comparison src/video/win32/SDL_win32events.c @ 1895:c121d94672cb

SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.
author Sam Lantinga <slouken@libsdl.org>
date Mon, 10 Jul 2006 21:04:37 +0000
parents
children 83420da906a5
comparison
equal deleted inserted replaced
1894:c69cee13dd76 1895:c121d94672cb
1 /*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2006 Sam Lantinga
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 Sam Lantinga
20 slouken@libsdl.org
21 */
22 #include "SDL_config.h"
23
24 #include "SDL_win32video.h"
25 #include "SDL_version.h"
26 #include "SDL_syswm.h"
27 #include "SDL_vkeys.h"
28 #include "../../events/SDL_events_c.h"
29
30 /*#define WMMSG_DEBUG*/
31 #ifdef WMMSG_DEBUG
32 #include "wmmsg.h"
33 #endif
34
35 /* Masks for processing the windows KEYDOWN and KEYUP messages */
36 #define REPEATED_KEYMASK (1<<30)
37 #define EXTENDED_KEYMASK (1<<24)
38
39
40 static SDLKey
41 TranslateKey(WPARAM vkey)
42 {
43 SDLKey key;
44
45 /* FIXME: Assign vkey directly to key if in ASCII range */
46 switch (vkey) {
47 case VK_BACK:
48 key = SDLK_BACKSPACE;
49 break;
50 case VK_TAB:
51 key = SDLK_TAB;
52 break;
53 case VK_CLEAR:
54 key = SDLK_CLEAR;
55 break;
56 case VK_RETURN:
57 key = SDLK_RETURN;
58 break;
59 case VK_PAUSE:
60 key = SDLK_PAUSE;
61 break;
62 case VK_ESCAPE:
63 key = SDLK_ESCAPE;
64 break;
65 case VK_SPACE:
66 key = SDLK_SPACE;
67 break;
68 case VK_APOSTROPHE:
69 key = SDLK_QUOTE;
70 break;
71 case VK_COMMA:
72 key = SDLK_COMMA;
73 break;
74 case VK_MINUS:
75 key = SDLK_MINUS;
76 break;
77 case VK_PERIOD:
78 key = SDLK_PERIOD;
79 break;
80 case VK_SLASH:
81 key = SDLK_SLASH;
82 break;
83 case VK_0:
84 key = SDLK_0;
85 break;
86 case VK_1:
87 key = SDLK_1;
88 break;
89 case VK_2:
90 key = SDLK_2;
91 break;
92 case VK_3:
93 key = SDLK_3;
94 break;
95 case VK_4:
96 key = SDLK_4;
97 break;
98 case VK_5:
99 key = SDLK_5;
100 break;
101 case VK_6:
102 key = SDLK_6;
103 break;
104 case VK_7:
105 key = SDLK_7;
106 break;
107 case VK_8:
108 key = SDLK_8;
109 break;
110 case VK_9:
111 key = SDLK_9;
112 break;
113 case VK_SEMICOLON:
114 key = SDLK_SEMICOLON;
115 break;
116 case VK_EQUALS:
117 key = SDLK_EQUALS;
118 break;
119 case VK_LBRACKET:
120 key = SDLK_LEFTBRACKET;
121 break;
122 case VK_BACKSLASH:
123 key = SDLK_BACKSLASH;
124 break;
125 case VK_OEM_102:
126 key = SDLK_LESS;
127 break;
128 case VK_RBRACKET:
129 key = SDLK_RIGHTBRACKET;
130 break;
131 case VK_GRAVE:
132 key = SDLK_BACKQUOTE;
133 break;
134 case VK_BACKTICK:
135 key = SDLK_BACKQUOTE;
136 break;
137 case VK_A:
138 key = SDLK_a;
139 break;
140 case VK_B:
141 key = SDLK_b;
142 break;
143 case VK_C:
144 key = SDLK_c;
145 break;
146 case VK_D:
147 key = SDLK_d;
148 break;
149 case VK_E:
150 key = SDLK_e;
151 break;
152 case VK_F:
153 key = SDLK_f;
154 break;
155 case VK_G:
156 key = SDLK_g;
157 break;
158 case VK_H:
159 key = SDLK_h;
160 break;
161 case VK_I:
162 key = SDLK_i;
163 break;
164 case VK_J:
165 key = SDLK_j;
166 break;
167 case VK_K:
168 key = SDLK_k;
169 break;
170 case VK_L:
171 key = SDLK_l;
172 break;
173 case VK_M:
174 key = SDLK_m;
175 break;
176 case VK_N:
177 key = SDLK_n;
178 break;
179 case VK_O:
180 key = SDLK_o;
181 break;
182 case VK_P:
183 key = SDLK_p;
184 break;
185 case VK_Q:
186 key = SDLK_q;
187 break;
188 case VK_R:
189 key = SDLK_r;
190 break;
191 case VK_S:
192 key = SDLK_s;
193 break;
194 case VK_T:
195 key = SDLK_t;
196 break;
197 case VK_U:
198 key = SDLK_u;
199 break;
200 case VK_V:
201 key = SDLK_v;
202 break;
203 case VK_W:
204 key = SDLK_w;
205 break;
206 case VK_X:
207 key = SDLK_x;
208 break;
209 case VK_Y:
210 key = SDLK_y;
211 break;
212 case VK_Z:
213 key = SDLK_z;
214 break;
215 case VK_DELETE:
216 key = SDLK_DELETE;
217 break;
218 case VK_NUMPAD0:
219 key = SDLK_KP0;
220 break;
221 case VK_NUMPAD1:
222 key = SDLK_KP1;
223 break;
224 case VK_NUMPAD2:
225 key = SDLK_KP2;
226 break;
227 case VK_NUMPAD3:
228 key = SDLK_KP3;
229 break;
230 case VK_NUMPAD4:
231 key = SDLK_KP4;
232 break;
233 case VK_NUMPAD5:
234 key = SDLK_KP5;
235 break;
236 case VK_NUMPAD6:
237 key = SDLK_KP6;
238 break;
239 case VK_NUMPAD7:
240 key = SDLK_KP7;
241 break;
242 case VK_NUMPAD8:
243 key = SDLK_KP8;
244 break;
245 case VK_NUMPAD9:
246 key = SDLK_KP9;
247 break;
248 case VK_DECIMAL:
249 key = SDLK_KP_PERIOD;
250 break;
251 case VK_DIVIDE:
252 key = SDLK_KP_DIVIDE;
253 break;
254 case VK_MULTIPLY:
255 key = SDLK_KP_MULTIPLY;
256 break;
257 case VK_SUBTRACT:
258 key = SDLK_KP_MINUS;
259 break;
260 case VK_ADD:
261 key = SDLK_KP_PLUS;
262 break;
263 case VK_UP:
264 key = SDLK_UP;
265 break;
266 case VK_DOWN:
267 key = SDLK_DOWN;
268 break;
269 case VK_RIGHT:
270 key = SDLK_RIGHT;
271 break;
272 case VK_LEFT:
273 key = SDLK_LEFT;
274 break;
275 case VK_INSERT:
276 key = SDLK_INSERT;
277 break;
278 case VK_HOME:
279 key = SDLK_HOME;
280 break;
281 case VK_END:
282 key = SDLK_END;
283 break;
284 case VK_PRIOR:
285 key = SDLK_PAGEUP;
286 break;
287 case VK_NEXT:
288 key = SDLK_PAGEDOWN;
289 break;
290 case VK_F1:
291 key = SDLK_F1;
292 break;
293 case VK_F2:
294 key = SDLK_F2;
295 break;
296 case VK_F3:
297 key = SDLK_F3;
298 break;
299 case VK_F4:
300 key = SDLK_F4;
301 break;
302 case VK_F5:
303 key = SDLK_F5;
304 break;
305 case VK_F6:
306 key = SDLK_F6;
307 break;
308 case VK_F7:
309 key = SDLK_F7;
310 break;
311 case VK_F8:
312 key = SDLK_F8;
313 break;
314 case VK_F9:
315 key = SDLK_F9;
316 break;
317 case VK_F10:
318 key = SDLK_F10;
319 break;
320 case VK_F11:
321 key = SDLK_F11;
322 break;
323 case VK_F12:
324 key = SDLK_F12;
325 break;
326 case VK_F13:
327 key = SDLK_F13;
328 break;
329 case VK_F14:
330 key = SDLK_F14;
331 break;
332 case VK_F15:
333 key = SDLK_F15;
334 break;
335 case VK_NUMLOCK:
336 key = SDLK_NUMLOCK;
337 break;
338 case VK_CAPITAL:
339 key = SDLK_CAPSLOCK;
340 break;
341 case VK_SCROLL:
342 key = SDLK_SCROLLOCK;
343 break;
344 case VK_RSHIFT:
345 key = SDLK_RSHIFT;
346 break;
347 case VK_LSHIFT:
348 key = SDLK_LSHIFT;
349 break;
350 case VK_RCONTROL:
351 key = SDLK_RCTRL;
352 break;
353 case VK_LCONTROL:
354 key = SDLK_LCTRL;
355 break;
356 case VK_RMENU:
357 key = SDLK_RALT;
358 break;
359 case VK_LMENU:
360 key = SDLK_LALT;
361 break;
362 case VK_RWIN:
363 key = SDLK_RSUPER;
364 break;
365 case VK_LWIN:
366 key = SDLK_LSUPER;
367 break;
368 case VK_HELP:
369 key = SDLK_HELP;
370 break;
371 case VK_PRINT:
372 key = SDLK_PRINT;
373 break;
374 case VK_SNAPSHOT:
375 key = SDLK_PRINT;
376 break;
377 case VK_CANCEL:
378 key = SDLK_BREAK;
379 break;
380 case VK_APPS:
381 key = SDLK_MENU;
382 break;
383 default:
384 key = SDLK_UNKNOWN;
385 break;
386 }
387 return key;
388 }
389
390 LRESULT CALLBACK
391 WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
392 {
393 SDL_WindowData *data;
394
395 /* Get the window data for the window */
396 data = (SDL_WindowData *) GetProp(hwnd, TEXT("SDL_WindowData"));
397 if (!data) {
398 return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam);
399 }
400 #ifdef WMMSG_DEBUG
401 fprintf(stderr, "Received windows message: ");
402 if (msg > MAX_WMMSG) {
403 fprintf(stderr, "%d", msg);
404 } else {
405 fprintf(stderr, "%s", wmtab[msg]);
406 }
407 fprintf(stderr, " -- 0x%X, 0x%X\n", wParam, lParam);
408 #endif
409
410 /* Send a SDL_SYSWMEVENT if the application wants them */
411 if (SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE) {
412 SDL_SysWMmsg wmmsg;
413
414 SDL_VERSION(&wmmsg.version);
415 wmmsg.hwnd = hwnd;
416 wmmsg.msg = msg;
417 wmmsg.wParam = wParam;
418 wmmsg.lParam = lParam;
419 SDL_SendSysWMEvent(&wmmsg);
420 }
421
422 switch (msg) {
423
424 case WM_SHOWWINDOW:
425 {
426 if (wParam) {
427 SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_SHOWN, 0,
428 0);
429 } else {
430 SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_HIDDEN, 0,
431 0);
432 }
433 }
434 break;
435
436 case WM_ACTIVATE:
437 {
438 int index;
439 SDL_Keyboard *keyboard;
440 BOOL minimized;
441
442 minimized = HIWORD(wParam);
443 index = data->videodata->keyboard;
444 keyboard = SDL_GetKeyboard(index);
445 if (!minimized && (LOWORD(wParam) != WA_INACTIVE)) {
446 SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_SHOWN,
447 0, 0);
448 SDL_SendWindowEvent(data->windowID,
449 SDL_WINDOWEVENT_RESTORED, 0, 0);
450 if (IsZoomed(hwnd)) {
451 SDL_SendWindowEvent(data->windowID,
452 SDL_WINDOWEVENT_MAXIMIZED, 0, 0);
453 }
454 if (keyboard && keyboard->focus != data->windowID) {
455 SDL_SetKeyboardFocus(index, data->windowID);
456 }
457 /* FIXME: Update keyboard state */
458 } else {
459 if (keyboard && keyboard->focus == data->windowID) {
460 SDL_SetKeyboardFocus(index, 0);
461 }
462 if (minimized) {
463 SDL_SendWindowEvent(data->windowID,
464 SDL_WINDOWEVENT_MINIMIZED, 0, 0);
465 }
466 }
467 return (0);
468 }
469 break;
470
471 case WM_MOUSEMOVE:
472 {
473 int index;
474 SDL_Mouse *mouse;
475 int x, y;
476
477 index = data->videodata->mouse;
478 mouse = SDL_GetMouse(index);
479
480 if (mouse->focus != data->windowID) {
481 TRACKMOUSEEVENT tme;
482
483 tme.cbSize = sizeof(tme);
484 tme.dwFlags = TME_LEAVE;
485 tme.hwndTrack = hwnd;
486 TrackMouseEvent(&tme);
487
488 SDL_SetMouseFocus(index, data->windowID);
489 }
490
491 /* mouse has moved within the window */
492 x = LOWORD(lParam);
493 y = HIWORD(lParam);
494 if (mouse->relative_mode) {
495 int w, h;
496 POINT center;
497 SDL_GetWindowSize(data->windowID, &w, &h);
498 center.x = (w / 2);
499 center.y = (h / 2);
500 x -= center.x;
501 y -= center.y;
502 if (x || y) {
503 ClientToScreen(hwnd, &center);
504 SetCursorPos(center.x, center.y);
505 SDL_SendMouseMotion(index, 1, x, y);
506 }
507 } else {
508 SDL_SendMouseMotion(index, 0, x, y);
509 }
510 }
511 return (0);
512
513 case WM_MOUSELEAVE:
514 {
515 int index;
516 SDL_Mouse *mouse;
517
518 index = data->videodata->mouse;
519 mouse = SDL_GetMouse(index);
520
521 if (mouse->focus == data->windowID) {
522 SDL_SetMouseFocus(index, 0);
523 }
524 }
525 return (0);
526
527 case WM_LBUTTONDOWN:
528 case WM_LBUTTONUP:
529 case WM_MBUTTONDOWN:
530 case WM_MBUTTONUP:
531 case WM_RBUTTONDOWN:
532 case WM_RBUTTONUP:
533 {
534 int index;
535 SDL_Mouse *mouse;
536 Uint8 button, state;
537
538 /* DJM:
539 We want the SDL window to take focus so that
540 it acts like a normal windows "component"
541 (e.g. gains keyboard focus on a mouse click).
542 */
543 SetFocus(hwnd);
544
545 index = data->videodata->mouse;
546 mouse = SDL_GetMouse(index);
547
548 /* Figure out which button to use */
549 switch (msg) {
550 case WM_LBUTTONDOWN:
551 button = SDL_BUTTON_LEFT;
552 state = SDL_PRESSED;
553 break;
554 case WM_LBUTTONUP:
555 button = SDL_BUTTON_LEFT;
556 state = SDL_RELEASED;
557 break;
558 case WM_MBUTTONDOWN:
559 button = SDL_BUTTON_MIDDLE;
560 state = SDL_PRESSED;
561 break;
562 case WM_MBUTTONUP:
563 button = SDL_BUTTON_MIDDLE;
564 state = SDL_RELEASED;
565 break;
566 case WM_RBUTTONDOWN:
567 button = SDL_BUTTON_RIGHT;
568 state = SDL_PRESSED;
569 break;
570 case WM_RBUTTONUP:
571 button = SDL_BUTTON_RIGHT;
572 state = SDL_RELEASED;
573 break;
574 default:
575 /* Eh? Unknown button? */
576 return (0);
577 }
578 if (state == SDL_PRESSED) {
579 /* Grab mouse so we get up events */
580 if (++data->mouse_pressed > 0) {
581 SetCapture(hwnd);
582 }
583 } else {
584 /* Release mouse after all up events */
585 if (--data->mouse_pressed <= 0) {
586 ReleaseCapture();
587 data->mouse_pressed = 0;
588 }
589 }
590
591 if (!mouse->relative_mode) {
592 int x, y;
593 x = LOWORD(lParam);
594 y = HIWORD(lParam);
595 SDL_SendMouseMotion(index, 0, x, y);
596 }
597 SDL_SendMouseButton(index, state, button);
598 }
599 return (0);
600
601 case WM_MOUSEWHEEL:
602 {
603 int index;
604 int motion = (short) HIWORD(wParam);
605
606 index = data->videodata->mouse;
607 SDL_SendMouseWheel(index, motion);
608 }
609 return (0);
610
611 case WM_SYSKEYDOWN:
612 case WM_KEYDOWN:
613 {
614 int index;
615
616 /* Ignore repeated keys */
617 if (lParam & REPEATED_KEYMASK) {
618 return (0);
619 }
620
621 index = data->videodata->keyboard;
622 switch (wParam) {
623 case VK_CONTROL:
624 if (lParam & EXTENDED_KEYMASK)
625 wParam = VK_RCONTROL;
626 else
627 wParam = VK_LCONTROL;
628 break;
629 case VK_SHIFT:
630 /* EXTENDED trick doesn't work here */
631 {
632 Uint8 *state = SDL_GetKeyState(NULL);
633 if (state[SDLK_LSHIFT] == SDL_RELEASED
634 && (GetKeyState(VK_LSHIFT) & 0x8000)) {
635 wParam = VK_LSHIFT;
636 } else if (state[SDLK_RSHIFT] == SDL_RELEASED
637 && (GetKeyState(VK_RSHIFT) & 0x8000)) {
638 wParam = VK_RSHIFT;
639 } else {
640 /* Probably a key repeat */
641 return (0);
642 }
643 }
644 break;
645 case VK_MENU:
646 if (lParam & EXTENDED_KEYMASK)
647 wParam = VK_RMENU;
648 else
649 wParam = VK_LMENU;
650 break;
651 }
652 SDL_SendKeyboardKey(index, SDL_PRESSED, (Uint8) HIWORD(lParam),
653 TranslateKey(wParam));
654 }
655 return (0);
656
657 case WM_SYSKEYUP:
658 case WM_KEYUP:
659 {
660 int index;
661
662 index = data->videodata->keyboard;
663 switch (wParam) {
664 case VK_CONTROL:
665 if (lParam & EXTENDED_KEYMASK)
666 wParam = VK_RCONTROL;
667 else
668 wParam = VK_LCONTROL;
669 break;
670 case VK_SHIFT:
671 /* EXTENDED trick doesn't work here */
672 {
673 Uint8 *state = SDL_GetKeyState(NULL);
674 if (state[SDLK_LSHIFT] == SDL_PRESSED
675 && !(GetKeyState(VK_LSHIFT) & 0x8000)) {
676 wParam = VK_LSHIFT;
677 } else if (state[SDLK_RSHIFT] == SDL_PRESSED
678 && !(GetKeyState(VK_RSHIFT) & 0x8000)) {
679 wParam = VK_RSHIFT;
680 } else {
681 /* Probably a key repeat */
682 return (0);
683 }
684 }
685 break;
686 case VK_MENU:
687 if (lParam & EXTENDED_KEYMASK)
688 wParam = VK_RMENU;
689 else
690 wParam = VK_LMENU;
691 break;
692 }
693 /* Windows only reports keyup for print screen */
694 if (wParam == VK_SNAPSHOT
695 && SDL_GetKeyState(NULL)[SDLK_PRINT] == SDL_RELEASED) {
696 SDL_SendKeyboardKey(index, SDL_PRESSED,
697 (Uint8) HIWORD(lParam),
698 TranslateKey(wParam));
699 }
700 SDL_SendKeyboardKey(index, SDL_RELEASED, (Uint8) HIWORD(lParam),
701 TranslateKey(wParam));
702 }
703 return (0);
704
705 case WM_GETMINMAXINFO:
706 {
707 MINMAXINFO *info;
708 RECT size;
709 int x, y;
710 int w, h;
711 int style;
712
713 /* If we allow resizing, let the resize happen naturally */
714 if (SDL_GetWindowFlags(data->windowID) & SDL_WINDOW_RESIZABLE) {
715 return (0);
716 }
717
718 /* Get the current position of our window */
719 GetWindowRect(hwnd, &size);
720 x = size.left;
721 y = size.top;
722
723 /* Calculate current size of our window */
724 SDL_GetWindowSize(data->windowID, &w, &h);
725 size.top = 0;
726 size.left = 0;
727 size.bottom = h;
728 size.right = w;
729
730 /* DJM - according to the docs for GetMenu(), the
731 return value is undefined if hwnd is a child window.
732 Aparently it's too difficult for MS to check
733 inside their function, so I have to do it here.
734 */
735 style = GetWindowLong(hwnd, GWL_STYLE);
736 AdjustWindowRect(&size,
737 style,
738 style & WS_CHILDWINDOW ? FALSE : GetMenu(hwnd) !=
739 NULL);
740
741 w = size.right - size.left;
742 h = size.bottom - size.top;
743
744 /* Fix our size to the current size */
745 info = (MINMAXINFO *) lParam;
746 info->ptMaxSize.x = w;
747 info->ptMaxSize.y = h;
748 info->ptMaxPosition.x = x;
749 info->ptMaxPosition.y = y;
750 info->ptMinTrackSize.x = w;
751 info->ptMinTrackSize.y = h;
752 info->ptMaxTrackSize.x = w;
753 info->ptMaxTrackSize.y = h;
754 }
755 return (0);
756
757 case WM_WINDOWPOSCHANGED:
758 {
759 RECT rect;
760 int x, y;
761 int w, h;
762 Uint32 window_flags;
763
764 GetClientRect(hwnd, &rect);
765 ClientToScreen(hwnd, (LPPOINT) & rect);
766 ClientToScreen(hwnd, (LPPOINT) & rect + 1);
767
768 window_flags = SDL_GetWindowFlags(data->windowID);
769 if ((window_flags & SDL_WINDOW_INPUT_GRABBED) &&
770 (window_flags & SDL_WINDOW_INPUT_FOCUS)) {
771 ClipCursor(&rect);
772 }
773
774 x = rect.left;
775 y = rect.top;
776 SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_MOVED, x, y);
777
778 w = rect.right - rect.left;
779 h = rect.bottom - rect.top;
780 SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_RESIZED, w,
781 h);
782 }
783 break;
784
785 case WM_SETCURSOR:
786 {
787 /*
788 Uint16 hittest;
789
790 hittest = LOWORD(lParam);
791 if (hittest == HTCLIENT) {
792 SetCursor(SDL_hcursor);
793 return (TRUE);
794 }
795 */
796 }
797 break;
798
799 /* We are about to get palette focus! */
800 case WM_QUERYNEWPALETTE:
801 {
802 /*
803 WIN_RealizePalette(current_video);
804 return (TRUE);
805 */
806 }
807 break;
808
809 /* Another application changed the palette */
810 case WM_PALETTECHANGED:
811 {
812 /*
813 WIN_PaletteChanged(current_video, (HWND) wParam);
814 */
815 }
816 break;
817
818 /* We were occluded, refresh our display */
819 case WM_PAINT:
820 {
821 RECT rect;
822 if (GetUpdateRect(hwnd, &rect, FALSE)) {
823 ValidateRect(hwnd, &rect);
824 SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_EXPOSED,
825 0, 0);
826 }
827 }
828 return (0);
829
830 /* We'll do our own drawing, prevent flicker */
831 case WM_ERASEBKGND:
832 {
833 }
834 return (1);
835
836 case WM_SYSCOMMAND:
837 {
838 /* Don't start the screensaver or blank the monitor in fullscreen apps */
839 if ((wParam & 0xFFF0) == SC_SCREENSAVE ||
840 (wParam & 0xFFF0) == SC_MONITORPOWER) {
841 if (SDL_GetWindowFlags(data->windowID) &
842 SDL_WINDOW_FULLSCREEN) {
843 return (0);
844 }
845 }
846 }
847 break;
848
849 case WM_CLOSE:
850 {
851 SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_CLOSE, 0, 0);
852 }
853 return (0);
854 }
855 return CallWindowProc(data->wndproc, hwnd, msg, wParam, lParam);
856 }
857
858 void
859 WIN_PumpEvents(_THIS)
860 {
861 MSG msg;
862 while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
863 TranslateMessage(&msg);
864 DispatchMessage(&msg);
865 }
866 }
867
868 static int app_registered = 0;
869 LPTSTR SDL_Appname = NULL;
870 Uint32 SDL_Appstyle = 0;
871 HINSTANCE SDL_Instance = NULL;
872
873 /* Register the class for this application */
874 int
875 SDL_RegisterApp(char *name, Uint32 style, void *hInst)
876 {
877 WNDCLASS class;
878
879 /* Only do this once... */
880 if (app_registered) {
881 ++app_registered;
882 return (0);
883 }
884 if (!name && !SDL_Appname) {
885 name = "SDL_app";
886 SDL_Appstyle = (CS_BYTEALIGNCLIENT | CS_OWNDC);
887 SDL_Instance = hInst ? hInst : GetModuleHandle(NULL);
888 }
889
890 if (name) {
891 SDL_Appname = WIN_UTF8ToString(name);
892 SDL_Appstyle = style;
893 SDL_Instance = hInst ? hInst : GetModuleHandle(NULL);
894 }
895
896 /* Register the application class */
897 class.hCursor = NULL;
898 class.hIcon = LoadImage(SDL_Instance, SDL_Appname,
899 IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
900 class.lpszMenuName = NULL;
901 class.lpszClassName = SDL_Appname;
902 class.hbrBackground = NULL;
903 class.hInstance = SDL_Instance;
904 class.style = SDL_Appstyle;
905 class.lpfnWndProc = DefWindowProc;
906 class.cbWndExtra = 0;
907 class.cbClsExtra = 0;
908 if (!RegisterClass(&class)) {
909 SDL_SetError("Couldn't register application class");
910 return (-1);
911 }
912
913 app_registered = 1;
914 return (0);
915 }
916
917 /* Unregisters the windowclass registered in SDL_RegisterApp above. */
918 void
919 SDL_UnregisterApp()
920 {
921 WNDCLASS class;
922
923 /* SDL_RegisterApp might not have been called before */
924 if (!app_registered) {
925 return;
926 }
927 --app_registered;
928 if (app_registered == 0) {
929 /* Check for any registered window classes. */
930 if (GetClassInfo(SDL_Instance, SDL_Appname, &class)) {
931 UnregisterClass(SDL_Appname, SDL_Instance);
932 }
933 SDL_free(SDL_Appname);
934 SDL_Appname = NULL;
935 }
936 }
937
938 /* Sets an error message based on GetLastError() */
939 void
940 WIN_SetError(const char *prefix)
941 {
942 TCHAR buffer[1024];
943 char *message;
944
945 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
946 NULL,
947 GetLastError(), 0, buffer, SDL_arraysize(buffer), NULL);
948
949 message = WIN_StringToUTF8(buffer);
950 SDL_SetError("%s%s%s", prefix ? prefix : "", prefix ? ":" : "", message);
951 SDL_free(message);
952 }
953
954 /* vi: set ts=4 sw=4 expandtab: */