Mercurial > sdl-ios-xcode
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, ¢er); | |
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: */ |