rev |
line source |
nuclear@25
|
1 /* SimplyGL window system module for Win32/WGL */
|
nuclear@25
|
2 /* link-with: -lopengl32 */
|
nuclear@25
|
3
|
nuclear@25
|
4 #include "config.h"
|
nuclear@25
|
5
|
nuclear@25
|
6 #ifdef USE_WSYS_MODULE_W32
|
nuclear@25
|
7
|
nuclear@25
|
8 #include <stdlib.h>
|
nuclear@25
|
9 #include <assert.h>
|
nuclear@25
|
10 #include <windows.h>
|
nuclear@25
|
11
|
nuclear@25
|
12 struct window {
|
nuclear@25
|
13 int id;
|
nuclear@25
|
14 HWND win;
|
nuclear@25
|
15 HDC dc;
|
nuclear@25
|
16 HGLRC ctx;
|
nuclear@25
|
17 int width, height;
|
nuclear@25
|
18 int redisp_pending;
|
nuclear@25
|
19
|
nuclear@25
|
20 struct window *next;
|
nuclear@25
|
21 };
|
nuclear@25
|
22
|
nuclear@25
|
23 static int init(void);
|
nuclear@25
|
24 static void shutdown(void);
|
nuclear@25
|
25
|
nuclear@25
|
26 /* video mode switching */
|
nuclear@25
|
27 static int set_vidmode(int xsz, int ysz);
|
nuclear@25
|
28 static int get_vidmode(int *xsz, int *ysz);
|
nuclear@25
|
29
|
nuclear@25
|
30 /* create/destroy windows */
|
nuclear@25
|
31 static int create_window(int xsz, int ysz, unsigned int flags);
|
nuclear@25
|
32 static void close_window(int id);
|
nuclear@25
|
33
|
nuclear@25
|
34 /* window management */
|
nuclear@25
|
35 static int set_active(int id);
|
nuclear@25
|
36 static struct window *find_window(int id);
|
nuclear@26
|
37 static struct window *find_window_handle(HWND wh);
|
nuclear@25
|
38 static int activate_window(struct window *win);
|
nuclear@25
|
39 static int set_title(const char *str);
|
nuclear@25
|
40 static void redisplay(void);
|
nuclear@25
|
41 static void swap_buffers(void);
|
nuclear@25
|
42
|
nuclear@25
|
43 static int get_modifiers(void);
|
nuclear@25
|
44
|
nuclear@25
|
45 /* event handling and friends */
|
nuclear@25
|
46 static void set_bits(long *mask, long bits);
|
nuclear@25
|
47 static void clear_bits(long *mask, long bits);
|
nuclear@25
|
48 static void set_event(int idx, int enable);
|
nuclear@25
|
49 static int process_events(void);
|
nuclear@25
|
50
|
nuclear@25
|
51 static LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
nuclear@25
|
52 static int mouse_button(unsigned int msg);
|
nuclear@26
|
53 static void calc_win_size(int w, int h, int *width, int *height, int *posx, int *posy);
|
nuclear@25
|
54
|
nuclear@25
|
55
|
nuclear@25
|
56 static struct wsys_module ws = {
|
nuclear@25
|
57 "win32", 0,
|
nuclear@25
|
58 init,
|
nuclear@25
|
59 shutdown,
|
nuclear@25
|
60 set_vidmode,
|
nuclear@25
|
61 get_vidmode,
|
nuclear@25
|
62 create_window,
|
nuclear@25
|
63 close_window,
|
nuclear@25
|
64 set_active,
|
nuclear@25
|
65 set_title,
|
nuclear@25
|
66 redisplay,
|
nuclear@25
|
67 swap_buffers,
|
nuclear@25
|
68 get_modifiers,
|
nuclear@25
|
69 set_event,
|
nuclear@25
|
70 process_events,
|
nuclear@25
|
71 0
|
nuclear@25
|
72 };
|
nuclear@25
|
73
|
nuclear@25
|
74 static struct window *winlist;
|
nuclear@25
|
75 static struct window *active_win, *prev_active;
|
nuclear@25
|
76 static int next_id = 1;
|
nuclear@25
|
77
|
nuclear@25
|
78 /* this is the only exported function, everything else should be static */
|
nuclear@25
|
79 void sgl_register_w32(void)
|
nuclear@25
|
80 {
|
nuclear@25
|
81 sgl_register_module(&ws);
|
nuclear@25
|
82 }
|
nuclear@25
|
83
|
nuclear@25
|
84
|
nuclear@25
|
85 static int init(void)
|
nuclear@25
|
86 {
|
nuclear@25
|
87 winlist = 0;
|
nuclear@25
|
88 active_win = prev_active = 0;
|
nuclear@25
|
89 return 0;
|
nuclear@25
|
90 }
|
nuclear@25
|
91
|
nuclear@25
|
92 static void shutdown(void)
|
nuclear@25
|
93 {
|
nuclear@25
|
94 /* TODO */
|
nuclear@25
|
95 }
|
nuclear@25
|
96
|
nuclear@25
|
97 static int set_vidmode(int xsz, int ysz)
|
nuclear@25
|
98 {
|
nuclear@25
|
99 DEVMODE dmode;
|
nuclear@25
|
100 memset(&dmode, 0, sizeof dmode);
|
nuclear@25
|
101 dmode.dmSize = sizeof dmode;
|
nuclear@25
|
102 /*dmode.dmBitsPerPel = 32;*/
|
nuclear@25
|
103 dmode.dmPelsWidth = xsz;
|
nuclear@25
|
104 dmode.dmPelsHeight = ysz;
|
nuclear@25
|
105 dmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
|
nuclear@25
|
106
|
nuclear@25
|
107 if(ChangeDisplaySettings(&dmode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) {
|
nuclear@25
|
108 sgl_log("failed to set video mode: %dx%d\n", xsz, ysz);
|
nuclear@25
|
109 return -1;
|
nuclear@25
|
110 }
|
nuclear@25
|
111 return 0;
|
nuclear@25
|
112 }
|
nuclear@25
|
113
|
nuclear@25
|
114 static int get_vidmode(int *xsz, int *ysz)
|
nuclear@25
|
115 {
|
nuclear@25
|
116 /* TODO */
|
nuclear@25
|
117 return 0;
|
nuclear@25
|
118 }
|
nuclear@25
|
119
|
nuclear@25
|
120 static int create_window(int xsz, int ysz, unsigned int flags)
|
nuclear@25
|
121 {
|
nuclear@25
|
122 WNDCLASS wclass;
|
nuclear@25
|
123 int win_width, win_height, win_x, win_y;
|
nuclear@25
|
124 unsigned int style;
|
nuclear@25
|
125 HINSTANCE pid;
|
nuclear@25
|
126 HWND win;
|
nuclear@25
|
127 PIXELFORMATDESCRIPTOR fmt;
|
nuclear@25
|
128 int pf_id;
|
nuclear@25
|
129 struct window *wnode;
|
nuclear@25
|
130 void (*func)();
|
nuclear@25
|
131
|
nuclear@25
|
132 if(!(wnode = malloc(sizeof *wnode))) {
|
nuclear@25
|
133 return -1;
|
nuclear@25
|
134 }
|
nuclear@25
|
135
|
nuclear@25
|
136 pid = GetModuleHandle(0);
|
nuclear@25
|
137
|
nuclear@25
|
138 memset(&wclass, 0, sizeof wclass);
|
nuclear@25
|
139 wclass.style = CS_VREDRAW | CS_HREDRAW | CS_OWNDC;
|
nuclear@25
|
140 wclass.lpfnWndProc = handle_events;
|
nuclear@25
|
141 wclass.hInstance = pid;
|
nuclear@25
|
142 wclass.lpszClassName = "simplygl";
|
nuclear@25
|
143
|
nuclear@25
|
144 if(!RegisterClass(&wclass)) {
|
nuclear@25
|
145 sgl_log("failed to register window class\n");
|
nuclear@25
|
146 return -1;
|
nuclear@25
|
147 }
|
nuclear@25
|
148
|
nuclear@25
|
149 calc_win_size(xsz, ysz, &win_width, &win_height, &win_x, &win_y);
|
nuclear@25
|
150
|
nuclear@25
|
151 style = WS_BORDER | WS_CAPTION | WS_MINIMIZEBOX | WS_POPUP | WS_SYSMENU | WS_VISIBLE;
|
nuclear@25
|
152
|
nuclear@25
|
153 if(!(win = CreateWindow("simplygl", "OpenGL/Win32", style, win_x, win_y, win_width, win_height, 0, 0, pid, 0))) {
|
nuclear@25
|
154 sgl_log("failed to create window\n");
|
nuclear@25
|
155 return -1;
|
nuclear@25
|
156 }
|
nuclear@25
|
157
|
nuclear@25
|
158 ShowWindow(win, SW_SHOW);
|
nuclear@25
|
159 SetForegroundWindow(win);
|
nuclear@25
|
160 SetActiveWindow(win);
|
nuclear@25
|
161
|
nuclear@25
|
162 wnode->win = win;
|
nuclear@25
|
163 wnode->dc = GetDC(win);
|
nuclear@25
|
164
|
nuclear@25
|
165 memset(&fmt, 0, sizeof fmt);
|
nuclear@25
|
166 fmt.nSize = sizeof fmt;
|
nuclear@25
|
167 fmt.nVersion = 1;
|
nuclear@25
|
168 fmt.cColorBits = PFD_TYPE_RGBA;
|
nuclear@25
|
169 fmt.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
|
nuclear@25
|
170
|
nuclear@25
|
171 if(flags & SGL_DOUBLE) {
|
nuclear@25
|
172 fmt.dwFlags |= PFD_DOUBLEBUFFER;
|
nuclear@25
|
173 }
|
nuclear@25
|
174 if(flags & SGL_DEPTH) {
|
nuclear@25
|
175 fmt.cDepthBits = 24;
|
nuclear@25
|
176 }
|
nuclear@25
|
177 if(flags & SGL_STENCIL) {
|
nuclear@25
|
178 fmt.cStencilBits = 8;
|
nuclear@25
|
179 }
|
nuclear@25
|
180 /* TODO: more... */
|
nuclear@25
|
181
|
nuclear@25
|
182 if(!(pf_id = ChoosePixelFormat(wnode->dc, &fmt))) {
|
nuclear@25
|
183 sgl_log("can't find requested pixel format\n");
|
nuclear@25
|
184 return -1;
|
nuclear@25
|
185 }
|
nuclear@25
|
186 if(!SetPixelFormat(wnode->dc, pf_id, &fmt)) {
|
nuclear@25
|
187 sgl_log("failed to set pixel format\n");
|
nuclear@25
|
188 return -1;
|
nuclear@25
|
189 }
|
nuclear@25
|
190 if(!(wnode->ctx = wglCreateContext(wnode->dc))) {
|
nuclear@25
|
191 sgl_log("failed to create OpenGL context\n");
|
nuclear@25
|
192 return -1;
|
nuclear@25
|
193 }
|
nuclear@25
|
194
|
nuclear@25
|
195 wnode->id = next_id++;
|
nuclear@25
|
196 wnode->width = xsz;
|
nuclear@25
|
197 wnode->height = ysz;
|
nuclear@25
|
198 wnode->redisp_pending = 1;
|
nuclear@25
|
199 wnode->next = winlist;
|
nuclear@25
|
200 winlist = wnode;
|
nuclear@25
|
201
|
nuclear@25
|
202 if(!active_win) {
|
nuclear@25
|
203 set_active(wnode->id);
|
nuclear@25
|
204 } else {
|
nuclear@25
|
205 activate_window(wnode);
|
nuclear@25
|
206 }
|
nuclear@25
|
207
|
nuclear@25
|
208 if((func = sgl_get_callback(SGL_CREATE))) {
|
nuclear@25
|
209 func(wnode->id);
|
nuclear@25
|
210 }
|
nuclear@25
|
211 if((func = sgl_get_callback(SGL_RESHAPE))) {
|
nuclear@25
|
212 func(xsz, ysz);
|
nuclear@25
|
213 }
|
nuclear@25
|
214 activate_window(prev_active);
|
nuclear@25
|
215 return wnode->id;
|
nuclear@25
|
216 }
|
nuclear@25
|
217
|
nuclear@25
|
218 static void close_window(int id)
|
nuclear@25
|
219 {
|
nuclear@25
|
220 struct window dummy, *win, *prev;
|
nuclear@25
|
221 sgl_close_callback_t close_func;
|
nuclear@25
|
222
|
nuclear@25
|
223 dummy.next = winlist;
|
nuclear@25
|
224
|
nuclear@25
|
225 prev = &dummy;
|
nuclear@25
|
226 win = prev->next;
|
nuclear@25
|
227
|
nuclear@25
|
228 while(win) {
|
nuclear@25
|
229 if(win->id == id) {
|
nuclear@25
|
230 if((close_func = sgl_get_callback(SGL_CLOSE))) {
|
nuclear@25
|
231 close_func(id);
|
nuclear@25
|
232 }
|
nuclear@25
|
233 wglDeleteContext(win->ctx);
|
nuclear@25
|
234 ReleaseDC(win->win, win->dc);
|
nuclear@25
|
235 DestroyWindow(win->win);
|
nuclear@25
|
236
|
nuclear@25
|
237 prev->next = win->next;
|
nuclear@25
|
238 free(win);
|
nuclear@25
|
239 return;
|
nuclear@25
|
240 }
|
nuclear@25
|
241 prev = win;
|
nuclear@25
|
242 win = win->next;
|
nuclear@25
|
243 }
|
nuclear@25
|
244 }
|
nuclear@25
|
245
|
nuclear@25
|
246 static int set_active(int id)
|
nuclear@25
|
247 {
|
nuclear@25
|
248 struct window *win = find_window(id);
|
nuclear@25
|
249 if(!win) {
|
nuclear@25
|
250 sgl_log("no such window: %d\n", id);
|
nuclear@25
|
251 return -1;
|
nuclear@25
|
252 }
|
nuclear@25
|
253 /* only the user calls this, so don't revert this selection */
|
nuclear@25
|
254 prev_active = win;
|
nuclear@25
|
255 return activate_window(win);
|
nuclear@25
|
256 }
|
nuclear@25
|
257
|
nuclear@25
|
258 static struct window *find_window(int id)
|
nuclear@25
|
259 {
|
nuclear@25
|
260 struct window *win = winlist;
|
nuclear@25
|
261
|
nuclear@25
|
262 while(win) {
|
nuclear@26
|
263 if(win->id == id) {
|
nuclear@26
|
264 return win;
|
nuclear@26
|
265 }
|
nuclear@26
|
266 win = win->next;
|
nuclear@26
|
267 }
|
nuclear@26
|
268 return 0;
|
nuclear@26
|
269 }
|
nuclear@26
|
270
|
nuclear@26
|
271 static struct window *find_window_handle(HWND wh)
|
nuclear@26
|
272 {
|
nuclear@26
|
273 struct window *win = winlist;
|
nuclear@26
|
274
|
nuclear@26
|
275 while(win) {
|
nuclear@26
|
276 if(win->win == wh) {
|
nuclear@25
|
277 return win;
|
nuclear@25
|
278 }
|
nuclear@25
|
279 win = win->next;
|
nuclear@25
|
280 }
|
nuclear@25
|
281 return 0;
|
nuclear@25
|
282 }
|
nuclear@25
|
283
|
nuclear@25
|
284 static int activate_window(struct window *win)
|
nuclear@25
|
285 {
|
nuclear@25
|
286 if(!wglMakeCurrent(win->dc, win->ctx)) {
|
nuclear@25
|
287 sgl_log("failed to activate window %d\n", (int)win->id);
|
nuclear@25
|
288 return -1;
|
nuclear@25
|
289 }
|
nuclear@25
|
290 active_win = win;
|
nuclear@25
|
291 return 0;
|
nuclear@25
|
292 }
|
nuclear@25
|
293
|
nuclear@25
|
294 static int set_title(const char *str)
|
nuclear@25
|
295 {
|
nuclear@25
|
296 SetWindowText(active_win->win, str);
|
nuclear@25
|
297 }
|
nuclear@25
|
298
|
nuclear@25
|
299 static void redisplay(void)
|
nuclear@25
|
300 {
|
nuclear@25
|
301 InvalidateRect(active_win->win, 0, 0);
|
nuclear@25
|
302 }
|
nuclear@25
|
303
|
nuclear@25
|
304 static void swap_buffers(void)
|
nuclear@25
|
305 {
|
nuclear@25
|
306 SwapBuffers(active_win->dc);
|
nuclear@25
|
307 }
|
nuclear@25
|
308
|
nuclear@25
|
309 static int get_modifiers(void)
|
nuclear@25
|
310 {
|
nuclear@25
|
311 return 0; /* TODO */
|
nuclear@25
|
312 }
|
nuclear@25
|
313
|
nuclear@25
|
314 static void set_event(int idx, int enable)
|
nuclear@25
|
315 {
|
nuclear@25
|
316 /* not needed */
|
nuclear@25
|
317 }
|
nuclear@25
|
318
|
nuclear@25
|
319 static int process_events(void)
|
nuclear@25
|
320 {
|
nuclear@25
|
321 int ret;
|
nuclear@25
|
322 MSG msg;
|
nuclear@25
|
323 sgl_idle_callback_t idle;
|
nuclear@25
|
324 sgl_display_callback_t disp;
|
nuclear@25
|
325
|
nuclear@25
|
326 idle = sgl_get_callback(SGL_IDLE);
|
nuclear@25
|
327
|
nuclear@25
|
328 prev_active = active_win;
|
nuclear@25
|
329
|
nuclear@25
|
330 if(!idle) {
|
nuclear@25
|
331 if(!GetMessage(&msg, 0, 0, 0)) {
|
nuclear@25
|
332 ret = -1;
|
nuclear@25
|
333 goto end;
|
nuclear@25
|
334 }
|
nuclear@25
|
335 } else {
|
nuclear@25
|
336 if(!PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
|
nuclear@25
|
337 ret = 0;
|
nuclear@25
|
338 goto end;
|
nuclear@25
|
339 }
|
nuclear@25
|
340 }
|
nuclear@25
|
341
|
nuclear@25
|
342 do {
|
nuclear@25
|
343 if(msg.message == WM_QUIT) {
|
nuclear@25
|
344 ret = -1;
|
nuclear@25
|
345 break;
|
nuclear@25
|
346 }
|
nuclear@25
|
347 TranslateMessage(&msg);
|
nuclear@25
|
348 DispatchMessage(&msg);
|
nuclear@25
|
349 } while(PeekMessage(&msg, 0, 0, 0, PM_REMOVE));
|
nuclear@25
|
350
|
nuclear@25
|
351 end:
|
nuclear@25
|
352 if(ret != -1 && idle) {
|
nuclear@25
|
353 idle();
|
nuclear@25
|
354 }
|
nuclear@25
|
355 activate_window(prev_active);
|
nuclear@25
|
356 return ret;
|
nuclear@25
|
357 }
|
nuclear@25
|
358
|
nuclear@25
|
359 static LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
nuclear@25
|
360 {
|
nuclear@25
|
361 static int state;
|
nuclear@25
|
362 struct window *win;
|
nuclear@25
|
363 void (*func)();
|
nuclear@25
|
364
|
nuclear@25
|
365 if((win = find_window_handle(hwnd))) {
|
nuclear@25
|
366 activate_window(win);
|
nuclear@25
|
367 } else {
|
nuclear@25
|
368 return DefWindowProc(hwnd, msg, wparam, lparam);
|
nuclear@25
|
369 }
|
nuclear@25
|
370
|
nuclear@25
|
371 switch(msg) {
|
nuclear@25
|
372 case WM_PAINT:
|
nuclear@25
|
373 if((func = sgl_get_callback(SGL_DISPLAY))) {
|
nuclear@25
|
374 func();
|
nuclear@25
|
375 }
|
nuclear@25
|
376 ValidateRect(hwnd, 0);
|
nuclear@25
|
377 break;
|
nuclear@25
|
378
|
nuclear@25
|
379 case WM_KEYDOWN:
|
nuclear@25
|
380 case WM_KEYUP:
|
nuclear@25
|
381 if((func = sgl_get_callback(SGL_KEYBOARD))) {
|
nuclear@25
|
382 func(MapVirtualKey(wparam, 2), msg == WM_KEYDOWN);
|
nuclear@25
|
383 }
|
nuclear@25
|
384 break;
|
nuclear@25
|
385
|
nuclear@25
|
386 case WM_LBUTTONDOWN:
|
nuclear@25
|
387 case WM_RBUTTONDOWN:
|
nuclear@25
|
388 case WM_MBUTTONDOWN:
|
nuclear@25
|
389 if(1) {
|
nuclear@25
|
390 state++;
|
nuclear@25
|
391 } else {
|
nuclear@25
|
392 case WM_LBUTTONUP:
|
nuclear@25
|
393 case WM_RBUTTONUP:
|
nuclear@25
|
394 case WM_MBUTTONUP:
|
nuclear@25
|
395 state--;
|
nuclear@25
|
396 }
|
nuclear@25
|
397 assert(state >= 0);
|
nuclear@25
|
398 if((func = sgl_get_callback(SGL_MOUSE))) {
|
nuclear@25
|
399 func(mouse_button(msg), state, LOWORD(lparam), HIWORD(lparam));
|
nuclear@25
|
400 }
|
nuclear@25
|
401 break;
|
nuclear@25
|
402
|
nuclear@25
|
403 case WM_MOUSEMOVE:
|
nuclear@25
|
404 if(state) {
|
nuclear@25
|
405 func = sgl_get_callback(SGL_MOTION);
|
nuclear@25
|
406 } else {
|
nuclear@25
|
407 func = sgl_get_callback(SGL_PASSIVE);
|
nuclear@25
|
408 }
|
nuclear@25
|
409 if(func) {
|
nuclear@25
|
410 func(LOWORD(lparam), HIWORD(lparam));
|
nuclear@25
|
411 }
|
nuclear@25
|
412 break;
|
nuclear@25
|
413
|
nuclear@25
|
414 default:
|
nuclear@25
|
415 return DefWindowProc(hwnd, msg, wparam, lparam);
|
nuclear@25
|
416 }
|
nuclear@25
|
417 return 0;
|
nuclear@25
|
418 }
|
nuclear@25
|
419
|
nuclear@25
|
420 static int mouse_button(unsigned int msg)
|
nuclear@25
|
421 {
|
nuclear@25
|
422 switch(msg) {
|
nuclear@25
|
423 case WM_LBUTTONDOWN:
|
nuclear@25
|
424 case WM_LBUTTONUP:
|
nuclear@25
|
425 return SGL_LEFT_BUTTON;
|
nuclear@25
|
426
|
nuclear@25
|
427 case WM_RBUTTONDOWN:
|
nuclear@25
|
428 case WM_RBUTTONUP:
|
nuclear@25
|
429 return SGL_RIGHT_BUTTON;
|
nuclear@25
|
430
|
nuclear@25
|
431 case WM_MBUTTONDOWN:
|
nuclear@25
|
432 case WM_MBUTTONUP:
|
nuclear@25
|
433 return SGL_MIDDLE_BUTTON;
|
nuclear@25
|
434
|
nuclear@25
|
435 default:
|
nuclear@25
|
436 break;
|
nuclear@25
|
437 }
|
nuclear@25
|
438 return -1;
|
nuclear@25
|
439 }
|
nuclear@25
|
440
|
nuclear@26
|
441 static void calc_win_size(int w, int h, int *width, int *height, int *posx, int *posy)
|
nuclear@26
|
442 {
|
nuclear@26
|
443 RECT rect;
|
nuclear@26
|
444 DEVMODE dmode;
|
nuclear@26
|
445 unsigned int style = WS_BORDER | WS_CAPTION | WS_MINIMIZEBOX | WS_POPUP | WS_SYSMENU | WS_VISIBLE;
|
nuclear@26
|
446
|
nuclear@26
|
447 rect.left = rect.top = 0;
|
nuclear@26
|
448 rect.right = w;
|
nuclear@26
|
449 rect.bottom = h;
|
nuclear@26
|
450
|
nuclear@26
|
451 AdjustWindowRect(&rect, style, 0);
|
nuclear@26
|
452
|
nuclear@26
|
453 *width = rect.right - rect.left;
|
nuclear@26
|
454 *height = rect.bottom - rect.top;
|
nuclear@26
|
455
|
nuclear@26
|
456 *posx = *posy = 0;
|
nuclear@26
|
457
|
nuclear@26
|
458 memset(&dmode, 0, sizeof dmode);
|
nuclear@26
|
459 dmode.dmSize = sizeof dmode;
|
nuclear@26
|
460
|
nuclear@26
|
461 if(EnumDisplaySettings(0, ENUM_CURRENT_SETTINGS, &dmode)) {
|
nuclear@26
|
462 int x, y;
|
nuclear@26
|
463
|
nuclear@26
|
464 x = (dmode.dmPelsWidth - *width) / 2;
|
nuclear@26
|
465 if(x > 0) {
|
nuclear@26
|
466 *posx = x;
|
nuclear@26
|
467 }
|
nuclear@26
|
468
|
nuclear@26
|
469 y = (dmode.dmPelsHeight - *height) / 2;
|
nuclear@26
|
470 if(y > 0) {
|
nuclear@26
|
471 *posy = y;
|
nuclear@26
|
472 }
|
nuclear@26
|
473 }
|
nuclear@26
|
474 }
|
nuclear@26
|
475
|
nuclear@25
|
476 #else
|
nuclear@25
|
477 int sgl_wsys_w32_silence_the_fucking_empty_file_warnings;
|
nuclear@25
|
478 #endif
|