comparison src/video/win32/SDL_win32events.c @ 3566:07c8339c95c6

Fixed bug #905 Give the foreign window message proc more control over Windows events. This may need to be adjusted when we add the capability for the app to specify whether it wants SDL to handle input for the window or not.
author Sam Lantinga <slouken@libsdl.org>
date Tue, 15 Dec 2009 09:20:10 +0000
parents f43c8f688f77
children 64ce267332c6
comparison
equal deleted inserted replaced
3565:f43c8f688f77 3566:07c8339c95c6
99 WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 99 WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
100 { 100 {
101 SDL_WindowData *data; 101 SDL_WindowData *data;
102 RAWINPUT *raw; 102 RAWINPUT *raw;
103 PACKET packet; 103 PACKET packet;
104 LRESULT returnCode = -1;
104 105
105 /* Send a SDL_SYSWMEVENT if the application wants them */ 106 /* Send a SDL_SYSWMEVENT if the application wants them */
106 if (SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE) { 107 if (SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE) {
107 SDL_SysWMmsg wmmsg; 108 SDL_SysWMmsg wmmsg;
108 109
209 SDL_SendWindowEvent(data->windowID, 210 SDL_SendWindowEvent(data->windowID,
210 SDL_WINDOWEVENT_MINIMIZED, 0, 0); 211 SDL_WINDOWEVENT_MINIMIZED, 0, 0);
211 } 212 }
212 } 213 }
213 } 214 }
214 return (0); 215 returnCode = 0;
216 break;
215 217
216 /* WinCE has no RawInput, so we use the classic mouse events. 218 /* WinCE has no RawInput, so we use the classic mouse events.
217 In classic Win32 this is done by WM_INPUT 219 In classic Win32 this is done by WM_INPUT
218 */ 220 */
219 #ifdef _WIN32_WCE 221 #ifdef _WIN32_WCE
261 break; 263 break;
262 } 264 }
263 } 265 }
264 if (index < 0) { 266 if (index < 0) {
265 /* New mouse? Should we dynamically update mouse list? */ 267 /* New mouse? Should we dynamically update mouse list? */
266 return (0); 268 returnCode = 0;
269 break;
267 } 270 }
268 271
269 GetCursorPos(&point); 272 GetCursorPos(&point);
270 ScreenToClient(hwnd, &point); 273 ScreenToClient(hwnd, &point);
271 274
314 SDL_SendMouseWheel(index, 0, 317 SDL_SendMouseWheel(index, 0,
315 (short) raw->data.mouse.usButtonData); 318 (short) raw->data.mouse.usButtonData);
316 } 319 }
317 SDL_stack_free(lpb); 320 SDL_stack_free(lpb);
318 } 321 }
319 return (0); 322 returnCode = 0;
323 break;
320 #endif /* _WIN32_WCE */ 324 #endif /* _WIN32_WCE */
321 325
322 case WM_MOUSELEAVE: 326 case WM_MOUSELEAVE:
323 { 327 {
324 int i; 328 int i;
329 if (mouse->focus == data->windowID) { 333 if (mouse->focus == data->windowID) {
330 SDL_SetMouseFocus(i, 0); 334 SDL_SetMouseFocus(i, 0);
331 } 335 }
332 } 336 }
333 } 337 }
334 return (0); 338 returnCode = 0;
339 break;
335 340
336 case WM_SYSKEYDOWN: 341 case WM_SYSKEYDOWN:
337 case WM_KEYDOWN: 342 case WM_KEYDOWN:
338 { 343 {
339 int index; 344 int index;
340 345
341 /* Ignore repeated keys */ 346 /* Ignore repeated keys */
342 if (lParam & REPEATED_KEYMASK) { 347 if (lParam & REPEATED_KEYMASK) {
343 return (0); 348 returnCode = 0;
349 break;
344 } 350 }
345 351
346 index = data->videodata->keyboard; 352 index = data->videodata->keyboard;
347 wParam = RemapVKEY(wParam, lParam); 353 wParam = RemapVKEY(wParam, lParam);
348 switch (wParam) { 354 switch (wParam) {
362 } else if (state[SDL_SCANCODE_RSHIFT] == SDL_RELEASED 368 } else if (state[SDL_SCANCODE_RSHIFT] == SDL_RELEASED
363 && (GetKeyState(VK_RSHIFT) & 0x8000)) { 369 && (GetKeyState(VK_RSHIFT) & 0x8000)) {
364 wParam = VK_RSHIFT; 370 wParam = VK_RSHIFT;
365 } else { 371 } else {
366 /* Probably a key repeat */ 372 /* Probably a key repeat */
367 return (0); 373 wParam = 256;
368 } 374 }
369 } 375 }
370 break; 376 break;
371 case VK_MENU: 377 case VK_MENU:
372 if (lParam & EXTENDED_KEYMASK) 378 if (lParam & EXTENDED_KEYMASK)
382 if (wParam < 256) { 388 if (wParam < 256) {
383 SDL_SendKeyboardKey(index, SDL_PRESSED, 389 SDL_SendKeyboardKey(index, SDL_PRESSED,
384 data->videodata->key_layout[wParam]); 390 data->videodata->key_layout[wParam]);
385 } 391 }
386 } 392 }
387 return (0); 393 returnCode = 0;
394 break;
388 395
389 case WM_SYSKEYUP: 396 case WM_SYSKEYUP:
390 case WM_KEYUP: 397 case WM_KEYUP:
391 { 398 {
392 int index; 399 int index;
410 } else if (state[SDL_SCANCODE_RSHIFT] == SDL_PRESSED 417 } else if (state[SDL_SCANCODE_RSHIFT] == SDL_PRESSED
411 && !(GetKeyState(VK_RSHIFT) & 0x8000)) { 418 && !(GetKeyState(VK_RSHIFT) & 0x8000)) {
412 wParam = VK_RSHIFT; 419 wParam = VK_RSHIFT;
413 } else { 420 } else {
414 /* Probably a key repeat */ 421 /* Probably a key repeat */
415 return (0); 422 wParam = 256;
416 } 423 }
417 } 424 }
418 break; 425 break;
419 case VK_MENU: 426 case VK_MENU:
420 if (lParam & EXTENDED_KEYMASK) 427 if (lParam & EXTENDED_KEYMASK)
438 if (wParam < 256) { 445 if (wParam < 256) {
439 SDL_SendKeyboardKey(index, SDL_RELEASED, 446 SDL_SendKeyboardKey(index, SDL_RELEASED,
440 data->videodata->key_layout[wParam]); 447 data->videodata->key_layout[wParam]);
441 } 448 }
442 } 449 }
443 return (0); 450 returnCode = 0;
451 break;
444 452
445 case WM_CHAR: 453 case WM_CHAR:
446 { 454 {
447 char text[4]; 455 char text[4];
448 456
460 text[2] = 0x80 | (char) (wParam & 0x3F); 468 text[2] = 0x80 | (char) (wParam & 0x3F);
461 text[3] = '\0'; 469 text[3] = '\0';
462 } 470 }
463 SDL_SendKeyboardText(data->videodata->keyboard, text); 471 SDL_SendKeyboardText(data->videodata->keyboard, text);
464 } 472 }
465 return (0); 473 returnCode = 0;
474 break;
466 475
467 case WM_INPUTLANGCHANGE: 476 case WM_INPUTLANGCHANGE:
468 { 477 {
469 WIN_UpdateKeymap(data->videodata->keyboard); 478 WIN_UpdateKeymap(data->videodata->keyboard);
470 } 479 }
471 return (1); 480 returnCode = 1;
481 break;
472 482
473 case WM_GETMINMAXINFO: 483 case WM_GETMINMAXINFO:
474 { 484 {
475 MINMAXINFO *info; 485 MINMAXINFO *info;
476 RECT size; 486 RECT size;
479 int style; 489 int style;
480 BOOL menu; 490 BOOL menu;
481 491
482 /* If we allow resizing, let the resize happen naturally */ 492 /* If we allow resizing, let the resize happen naturally */
483 if (SDL_GetWindowFlags(data->windowID) & SDL_WINDOW_RESIZABLE) { 493 if (SDL_GetWindowFlags(data->windowID) & SDL_WINDOW_RESIZABLE) {
484 return (0); 494 returnCode = 0;
495 break;
485 } 496 }
486 497
487 /* Get the current position of our window */ 498 /* Get the current position of our window */
488 GetWindowRect(hwnd, &size); 499 GetWindowRect(hwnd, &size);
489 x = size.left; 500 x = size.left;
521 info->ptMinTrackSize.x = w; 532 info->ptMinTrackSize.x = w;
522 info->ptMinTrackSize.y = h; 533 info->ptMinTrackSize.y = h;
523 info->ptMaxTrackSize.x = w; 534 info->ptMaxTrackSize.x = w;
524 info->ptMaxTrackSize.y = h; 535 info->ptMaxTrackSize.y = h;
525 } 536 }
526 return (0); 537 returnCode = 0;
538 break;
527 539
528 case WM_WINDOWPOSCHANGED: 540 case WM_WINDOWPOSCHANGED:
529 { 541 {
530 RECT rect; 542 RECT rect;
531 int x, y; 543 int x, y;
566 static HCURSOR cursor; 578 static HCURSOR cursor;
567 if (!cursor) { 579 if (!cursor) {
568 cursor = LoadCursor(NULL, IDC_ARROW); 580 cursor = LoadCursor(NULL, IDC_ARROW);
569 } 581 }
570 SetCursor(cursor); 582 SetCursor(cursor);
571 return (TRUE); 583 returnCode = TRUE;
572 } 584 }
573 } 585 }
574 break; 586 break;
575 587
576 /* We are about to get palette focus! */ 588 /* We are about to get palette focus! */
577 case WM_QUERYNEWPALETTE: 589 case WM_QUERYNEWPALETTE:
578 { 590 {
579 /* 591 /*
580 WIN_RealizePalette(current_video); 592 WIN_RealizePalette(current_video);
581 return (TRUE); 593 returnCode = TRUE;
582 */ 594 */
583 } 595 }
584 break; 596 break;
585 597
586 /* Another application changed the palette */ 598 /* Another application changed the palette */
600 ValidateRect(hwnd, &rect); 612 ValidateRect(hwnd, &rect);
601 SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_EXPOSED, 613 SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_EXPOSED,
602 0, 0); 614 0, 0);
603 } 615 }
604 } 616 }
605 return (0); 617 returnCode = 0;
606 618 break;
607 /* If this isn't our window, we don't need to repaint the frame.
608 This fixes a reentrancy issue that can cause stack overflows with foreign windows.
609 3/21/09 Mason Wheeler */
610 case WM_NCPAINT:
611 {
612 if (SDL_GetWindowFlags(data->windowID) & SDL_WINDOW_FOREIGN) {
613 return (0);
614 }
615 break;
616 }
617 619
618 /* We'll do our own drawing, prevent flicker */ 620 /* We'll do our own drawing, prevent flicker */
619 case WM_ERASEBKGND: 621 case WM_ERASEBKGND:
620 { 622 {
621 } 623 }
635 637
636 case WM_CLOSE: 638 case WM_CLOSE:
637 { 639 {
638 SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_CLOSE, 0, 0); 640 SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_CLOSE, 0, 0);
639 } 641 }
640 return (0); 642 returnCode = 0;
641 } 643 break;
642 return CallWindowProc(data->wndproc, hwnd, msg, wParam, lParam); 644 }
645
646 /* If there's a window proc, assume it's going to handle messages */
647 if (data->wndproc) {
648 return CallWindowProc(data->wndproc, hwnd, msg, wParam, lParam);
649 } else if (returnCode >= 0) {
650 return returnCode;
651 } else {
652 return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam);
653 }
643 } 654 }
644 655
645 void 656 void
646 WIN_PumpEvents(_THIS) 657 WIN_PumpEvents(_THIS)
647 { 658 {