X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fmswin%2Ffg_main_mswin.c;h=92f653e0d32e3caabc7d73dbc5d48b230233709c;hb=473ed0eb3ac4d8252717a06ea9de2bc062edee03;hp=7f33ac180db598133adcbe9a38e55a954eb82497;hpb=3b8c74a07a7e9de271191dca77ff475d50499c04;p=freeglut diff --git a/src/mswin/fg_main_mswin.c b/src/mswin/fg_main_mswin.c index 7f33ac1..92f653e 100644 --- a/src/mswin/fg_main_mswin.c +++ b/src/mswin/fg_main_mswin.c @@ -170,27 +170,25 @@ static int fgPlatformGetModifiers (void) ( GetKeyState( VK_RMENU ) < 0 )) ? GLUT_ACTIVE_ALT : 0 ); } -static void fghKeyPress(SFG_Window *window, GLboolean keydown, WPARAM wParam, LPARAM lParam) +static LRESULT fghWindowProcKeyPress(SFG_Window *window, UINT uMsg, GLboolean keydown, WPARAM wParam, LPARAM lParam) { static unsigned char lControl = 0, lShift = 0, lAlt = 0, rControl = 0, rShift = 0, rAlt = 0; int keypress = -1; - POINT mouse_pos ; /* if keydown, check for repeat */ + /* If repeat is globally switched off, it cannot be switched back on per window. + * But if it is globally switched on, it can be switched off per window. This matches + * GLUT's behavior on X11, but not Nate Robbins' win32 GLUT, as he didn't implement the + * global state switch. + */ if( keydown && ( fgState.KeyRepeat==GLUT_KEY_REPEAT_OFF || window->State.IgnoreKeyRepeat==GL_TRUE ) && (HIWORD(lParam) & KF_REPEAT) ) - return; + return 1; /* Remember the current modifiers state so user can query it from their callback */ fgState.Modifiers = fgPlatformGetModifiers( ); - /* Get mouse position roughly at time of keypress */ - GetCursorPos( &mouse_pos ); - ScreenToClient( window->Window.Handle, &mouse_pos ); - window->State.MouseX = mouse_pos.x; - window->State.MouseY = mouse_pos.y; - /* Convert the Win32 keystroke codes to GLUTtish way */ # define KEY(a,b) case a: keypress = b; break; @@ -315,6 +313,43 @@ static void fghKeyPress(SFG_Window *window, GLboolean keydown, WPARAM wParam, LP ); fgState.Modifiers = INVALID_MODIFIERS; + + /* SYSKEY events should be sent to default window proc for system to handle them */ + if (uMsg==WM_SYSKEYDOWN || uMsg==WM_SYSKEYUP) + return DefWindowProc( window->Window.Handle, uMsg, wParam, lParam ); + else + return 1; +} + +void fghWindowUnderCursor(SFG_Window *window, SFG_Window **child_window) +{ + /* Check if the current window that the mouse is over is a child window + * of the window the message was sent to. + */ + if (window && window->Children.First) + { + POINT mouse_pos; + SFG_WindowHandleType hwnd; + SFG_Window* temp_window; + + /* Get mouse position at time of message */ + DWORD mouse_pos_Dword = GetMessagePos(); + mouse_pos.x = GET_X_LPARAM(mouse_pos_Dword); + mouse_pos.y = GET_Y_LPARAM(mouse_pos_Dword); + ScreenToClient( window->Window.Handle, &mouse_pos ); + + hwnd = ChildWindowFromPoint(window->Window.Handle, mouse_pos); + if (hwnd && hwnd!=window->Window.Handle) /* can be NULL if mouse outside parent by the time we get here, or can be same as parent if we didn't find a child */ + { + temp_window = fgWindowByHandle(hwnd); + if (temp_window) /* Verify we got a FreeGLUT window */ + { + *child_window = temp_window; + /* ChildWindowFromPoint only searches immediate children, so search again to see if actually in grandchild or further descendant */ + fghWindowUnderCursor(temp_window,child_window); + } + } + } } /* @@ -341,22 +376,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR * we make sure that we process callbacks on the child window instead. * This mirrors how GLUT does things. */ - if (window && window->Children.First) - { - POINT mouse_pos; - SFG_WindowHandleType hwnd; - SFG_Window* temp_window; - - GetCursorPos( &mouse_pos ); - ScreenToClient( window->Window.Handle, &mouse_pos ); - hwnd = ChildWindowFromPoint(window->Window.Handle, mouse_pos); - if (hwnd) /* can be NULL if mouse outside parent by the time we get here */ - { - temp_window = fgWindowByHandle(hwnd); - if (temp_window && temp_window->Parent) /* Verify we got a child window */ - child_window = temp_window; - } - } + fghWindowUnderCursor(window, &child_window); switch( uMsg ) { @@ -503,20 +523,8 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); - if (child_window) - { - /* If we're dealing with a child window, make sure it has input focus instead, set it here. */ - SetFocus(child_window->Window.Handle); - SetActiveWindow( child_window->Window.Handle ); - INVOKE_WCB( *child_window, Entry, ( GLUT_ENTERED ) ); - UpdateWindow ( child_window->Window.Handle ); - } - else - { - SetActiveWindow( window->Window.Handle ); - INVOKE_WCB( *window, Entry, ( GLUT_ENTERED ) ); - } - /* Always request update on main window to be safe */ + SetActiveWindow( window->Window.Handle ); + INVOKE_WCB( *window, Entry, ( GLUT_ENTERED ) ); UpdateWindow ( hWnd ); break; @@ -536,6 +544,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR #if 0 case WM_ACTIVATE: + //printf("WM_ACTIVATE: %x %d %d\n",lParam, HIWORD(wParam), LOWORD(wParam)); if (LOWORD(wParam) != WA_INACTIVE) { /* printf("WM_ACTIVATE: fgSetCursor( %p, %d)\n", window, @@ -730,8 +739,11 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR { int wheel_number = LOWORD( wParam ); short ticks = ( short )HIWORD( wParam ); - fgState.MouseWheelTicks += ticks; + if (child_window) + window = child_window; + + fgState.MouseWheelTicks += ticks; if ( abs ( fgState.MouseWheelTicks ) >= WHEEL_DELTA ) { int direction = ( fgState.MouseWheelTicks > 0 ) ? 1 : -1; @@ -785,16 +797,12 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR case WM_SYSKEYDOWN: case WM_KEYDOWN: - if (child_window) - window = child_window; - fghKeyPress(window,GL_TRUE,wParam,lParam); + lRet = fghWindowProcKeyPress(child_window?child_window:window,uMsg,GL_TRUE,wParam,lParam); break; case WM_SYSKEYUP: case WM_KEYUP: - if (child_window) - window = child_window; - fghKeyPress(window,GL_FALSE,wParam,lParam); + lRet = fghWindowProcKeyPress(child_window?child_window:window,uMsg,GL_FALSE,wParam,lParam); break; case WM_SYSCHAR: