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