X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fmswin%2Ffg_main_mswin.c;h=a9f85528cba616ddc73b46a2ae671996075315e2;hb=637e1260edb9068591665330c32407549ca36535;hp=0f7f4ae913f804de1b6831b78a7b2202dd4c300e;hpb=7cb04a52ca8a17ec1ee7197378a34f5b3e063a9c;p=freeglut diff --git a/src/mswin/fg_main_mswin.c b/src/mswin/fg_main_mswin.c index 0f7f4ae..a9f8552 100644 --- a/src/mswin/fg_main_mswin.c +++ b/src/mswin/fg_main_mswin.c @@ -35,6 +35,8 @@ extern void fgNewWGLCreateContext( SFG_Window* window ); extern GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly, unsigned char layer_type ); +extern void fgPlatformCheckMenuDeactivate(); + #ifdef WM_TOUCH typedef BOOL (WINAPI *pGetTouchInputInfo)(HTOUCHINPUT,UINT,PTOUCHINPUT,int); typedef BOOL (WINAPI *pCloseTouchInputHandle)(HTOUCHINPUT); @@ -61,8 +63,8 @@ struct GXKeyList gxKeyList; * and the window rect from the client area given the style of the window * (or a valid window pointer from which the style can be queried). */ -extern void fghComputeWindowRectFromClientArea_QueryWindow( const SFG_Window *window, RECT *clientRect, BOOL posIsOutside ); -extern RECT fghGetClientArea ( const SFG_Window *window, BOOL wantPosOutside ); +extern void fghComputeWindowRectFromClientArea_QueryWindow( RECT *clientRect, const SFG_Window *window, BOOL posIsOutside ); +extern void fghGetClientArea ( RECT *clientRect, const SFG_Window *window, BOOL wantPosOutside ); void fgPlatformReshapeWindow ( SFG_Window *window, int width, int height ) @@ -84,7 +86,7 @@ void fgPlatformReshapeWindow ( SFG_Window *window, int width, int height ) if (window->Parent == NULL) /* get the window rect from this to feed to SetWindowPos, correct for window decorations */ - fghComputeWindowRectFromClientArea_QueryWindow(window,&windowRect,TRUE); + fghComputeWindowRectFromClientArea_QueryWindow(&windowRect,window,TRUE); else { /* correct rect for position client area of parent window @@ -94,11 +96,8 @@ void fgPlatformReshapeWindow ( SFG_Window *window, int width, int height ) * for them. */ RECT parentRect; - parentRect = fghGetClientArea( window->Parent, FALSE ); - windowRect.left -= parentRect.left; - windowRect.right -= parentRect.left; - windowRect.top -= parentRect.top; - windowRect.bottom -= parentRect.top; + fghGetClientArea( &parentRect, window->Parent, FALSE ); + OffsetRect(&windowRect,-parentRect.left,-parentRect.top); } /* Do the actual resizing */ @@ -225,7 +224,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, static unsigned char lControl = 0, rControl = 0, lShift = 0, rShift = 0, lAlt = 0, rAlt = 0; - SFG_Window* window; + SFG_Window *window, *child_window = NULL; PAINTSTRUCT ps; LRESULT lRet = 1; @@ -239,15 +238,39 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, /* printf ( "Window %3d message <%04x> %12d %12d\n", window?window->ID:0, uMsg, wParam, lParam ); */ + /* Some events only sent to main window. Check if the current window that + * the mouse is over is a child window. Below when handling some messages, + * 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->Parent) /* Verify we got a child window */ + child_window = temp_window; + } + } + if ( window ) { + SFG_Window* temp_window = child_window?child_window:window; + fgState.Modifiers = fgPlatformGetModifiers( ); /* Checking for CTRL, ALT, and SHIFT key positions: Key Down! */ if ( !lControl && GetAsyncKeyState ( VK_LCONTROL ) ) { - INVOKE_WCB ( *window, Special, - ( GLUT_KEY_CTRL_L, window->State.MouseX, window->State.MouseY ) + INVOKE_WCB ( *temp_window, Special, + ( GLUT_KEY_CTRL_L, temp_window->State.MouseX, temp_window->State.MouseY ) ); lControl = 1; @@ -255,8 +278,8 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, if ( !rControl && GetAsyncKeyState ( VK_RCONTROL ) ) { - INVOKE_WCB ( *window, Special, - ( GLUT_KEY_CTRL_R, window->State.MouseX, window->State.MouseY ) + INVOKE_WCB ( *temp_window, Special, + ( GLUT_KEY_CTRL_R, temp_window->State.MouseX, temp_window->State.MouseY ) ); rControl = 1; @@ -264,8 +287,8 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, if ( !lShift && GetAsyncKeyState ( VK_LSHIFT ) ) { - INVOKE_WCB ( *window, Special, - ( GLUT_KEY_SHIFT_L, window->State.MouseX, window->State.MouseY ) + INVOKE_WCB ( *temp_window, Special, + ( GLUT_KEY_SHIFT_L, temp_window->State.MouseX, temp_window->State.MouseY ) ); lShift = 1; @@ -273,8 +296,8 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, if ( !rShift && GetAsyncKeyState ( VK_RSHIFT ) ) { - INVOKE_WCB ( *window, Special, - ( GLUT_KEY_SHIFT_R, window->State.MouseX, window->State.MouseY ) + INVOKE_WCB ( *temp_window, Special, + ( GLUT_KEY_SHIFT_R, temp_window->State.MouseX, temp_window->State.MouseY ) ); rShift = 1; @@ -282,8 +305,8 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, if ( !lAlt && GetAsyncKeyState ( VK_LMENU ) ) { - INVOKE_WCB ( *window, Special, - ( GLUT_KEY_ALT_L, window->State.MouseX, window->State.MouseY ) + INVOKE_WCB ( *temp_window, Special, + ( GLUT_KEY_ALT_L, temp_window->State.MouseX, temp_window->State.MouseY ) ); lAlt = 1; @@ -291,8 +314,8 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, if ( !rAlt && GetAsyncKeyState ( VK_RMENU ) ) { - INVOKE_WCB ( *window, Special, - ( GLUT_KEY_ALT_R, window->State.MouseX, window->State.MouseY ) + INVOKE_WCB ( *temp_window, Special, + ( GLUT_KEY_ALT_R, temp_window->State.MouseX, temp_window->State.MouseY ) ); rAlt = 1; @@ -301,8 +324,8 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, /* Checking for CTRL, ALT, and SHIFT key positions: Key Up! */ if ( lControl && !GetAsyncKeyState ( VK_LCONTROL ) ) { - INVOKE_WCB ( *window, SpecialUp, - ( GLUT_KEY_CTRL_L, window->State.MouseX, window->State.MouseY ) + INVOKE_WCB ( *temp_window, SpecialUp, + ( GLUT_KEY_CTRL_L, temp_window->State.MouseX, temp_window->State.MouseY ) ); lControl = 0; @@ -310,8 +333,8 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, if ( rControl && !GetAsyncKeyState ( VK_RCONTROL ) ) { - INVOKE_WCB ( *window, SpecialUp, - ( GLUT_KEY_CTRL_R, window->State.MouseX, window->State.MouseY ) + INVOKE_WCB ( *temp_window, SpecialUp, + ( GLUT_KEY_CTRL_R, temp_window->State.MouseX, temp_window->State.MouseY ) ); rControl = 0; @@ -319,8 +342,8 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, if ( lShift && !GetAsyncKeyState ( VK_LSHIFT ) ) { - INVOKE_WCB ( *window, SpecialUp, - ( GLUT_KEY_SHIFT_L, window->State.MouseX, window->State.MouseY ) + INVOKE_WCB ( *temp_window, SpecialUp, + ( GLUT_KEY_SHIFT_L, temp_window->State.MouseX, temp_window->State.MouseY ) ); lShift = 0; @@ -328,8 +351,8 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, if ( rShift && !GetAsyncKeyState ( VK_RSHIFT ) ) { - INVOKE_WCB ( *window, SpecialUp, - ( GLUT_KEY_SHIFT_R, window->State.MouseX, window->State.MouseY ) + INVOKE_WCB ( *temp_window, SpecialUp, + ( GLUT_KEY_SHIFT_R, temp_window->State.MouseX, temp_window->State.MouseY ) ); rShift = 0; @@ -337,8 +360,8 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, if ( lAlt && !GetAsyncKeyState ( VK_LMENU ) ) { - INVOKE_WCB ( *window, SpecialUp, - ( GLUT_KEY_ALT_L, window->State.MouseX, window->State.MouseY ) + INVOKE_WCB ( *temp_window, SpecialUp, + ( GLUT_KEY_ALT_L, temp_window->State.MouseX, temp_window->State.MouseY ) ); lAlt = 0; @@ -346,8 +369,8 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, if ( rAlt && !GetAsyncKeyState ( VK_RMENU ) ) { - INVOKE_WCB ( *window, SpecialUp, - ( GLUT_KEY_ALT_R, window->State.MouseX, window->State.MouseY ) + INVOKE_WCB ( *temp_window, SpecialUp, + ( GLUT_KEY_ALT_R, temp_window->State.MouseX, temp_window->State.MouseY ) ); rAlt = 0; @@ -470,21 +493,38 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, case WM_SETFOCUS: /* printf("WM_SETFOCUS: %p\n", window ); */ + lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); - INVOKE_WCB( *window, Entry, ( GLUT_ENTERED ) ); - UpdateWindow ( hWnd ); + if (child_window) + { + /* If child should have 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 */ + UpdateWindow ( hWnd ); + break; case WM_KILLFOCUS: -/* printf("WM_KILLFOCUS: %p\n", window ); */ - lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); - INVOKE_WCB( *window, Entry, ( GLUT_LEFT ) ); - - if( window->IsMenu && - window->ActiveMenu && window->ActiveMenu->IsActive ) - fgUpdateMenuHighlight( window->ActiveMenu ); + { + SFG_Window* saved_window = fgStructure.CurrentWindow; +/* printf("WM_KILLFOCUS: %p\n", window ); */ + lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); + INVOKE_WCB( *window, Entry, ( GLUT_LEFT ) ); + fgSetWindow(saved_window); + /* Check if there are any open menus that need to be closed */ + fgPlatformCheckMenuDeactivate(); + } break; #if 0 @@ -516,6 +556,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, case WM_PAINT: /* Turn on the visibility in case it was turned off somehow */ window->State.Visible = GL_TRUE; + InvalidateRect( hWnd, NULL, GL_FALSE ); /* Make sure whole window is repainted. Bit of a hack, but a safe on from what google turns up... */ BeginPaint( hWnd, &ps ); fghRedrawWindow( window ); EndPaint( hWnd, &ps ); @@ -552,7 +593,6 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, fgUpdateMenuHighlight( window->ActiveMenu ); break; } - SetFocus(window->Window.Handle); fgState.Modifiers = fgPlatformGetModifiers( ); @@ -679,8 +719,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, } break; - case 0x020a: - /* Should be WM_MOUSEWHEEL but my compiler doesn't recognize it */ + case WM_MOUSEWHEEL: { int wheel_number = LOWORD( wParam ); short ticks = ( short )HIWORD( wParam ); @@ -689,7 +728,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, /* * XXX Should use WHEEL_DELTA instead of 120 */ - if ( abs ( fgState.MouseWheelTicks ) > 120 ) + if ( abs ( fgState.MouseWheelTicks ) >= 120 ) { int direction = ( fgState.MouseWheelTicks > 0 ) ? 1 : -1; @@ -703,7 +742,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, /* * XXX Should use WHEEL_DELTA instead of 120 */ - while( abs ( fgState.MouseWheelTicks ) > 120 ) + while( abs ( fgState.MouseWheelTicks ) >= 120 ) { if( FETCH_WCB( *window, MouseWheel ) ) INVOKE_WCB( *window, MouseWheel, @@ -752,6 +791,9 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, int keypress = -1; POINT mouse_pos ; + if (child_window) + window = child_window; + if( ( fgState.KeyRepeat==GLUT_KEY_REPEAT_OFF || window->State.IgnoreKeyRepeat==GL_TRUE ) && (HIWORD(lParam) & KF_REPEAT) ) break; @@ -794,6 +836,12 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, KEY( VK_DOWN, GLUT_KEY_DOWN ); KEY( VK_INSERT, GLUT_KEY_INSERT ); + case VK_LCONTROL: case VK_RCONTROL: case VK_CONTROL: + case VK_LSHIFT: case VK_RSHIFT: case VK_SHIFT: + case VK_LMENU: case VK_RMENU: case VK_MENU: + /* These keypresses and releases are handled earlier in the function */ + break; + case VK_DELETE: /* The delete key should be treated as an ASCII keypress: */ INVOKE_WCB( *window, Keyboard, @@ -839,6 +887,9 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, int keypress = -1; POINT mouse_pos; + if (child_window) + window = child_window; + /* * Remember the current modifiers state. This is done here in order * to make sure the VK_DELETE keyboard callback is executed properly. @@ -880,6 +931,12 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, KEY( VK_DOWN, GLUT_KEY_DOWN ); KEY( VK_INSERT, GLUT_KEY_INSERT ); + case VK_LCONTROL: case VK_RCONTROL: case VK_CONTROL: + case VK_LSHIFT: case VK_RSHIFT: case VK_SHIFT: + case VK_LMENU: case VK_RMENU: case VK_MENU: + /* These keypresses and releases are handled earlier in the function */ + break; + case VK_DELETE: /* The delete key should be treated as an ASCII keypress: */ INVOKE_WCB( *window, KeyboardUp, @@ -919,6 +976,9 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, case WM_SYSCHAR: case WM_CHAR: { + if (child_window) + window = child_window; + if( (fgState.KeyRepeat==GLUT_KEY_REPEAT_OFF || window->State.IgnoreKeyRepeat==GL_TRUE) && (HIWORD(lParam) & KF_REPEAT) ) break;