X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2FCommon%2Ffreeglut_main.c;h=b1654a5275f43cff3e9edf7db05bcfaff668fb22;hb=1114cde95ebfcfedf5969b0484a0c94b8f79cb14;hp=2eed2d464d90d85d31c7fe78687d56448ababad5;hpb=d2f7ea29ea6d946f455f4363c3f058ff2bdfba35;p=freeglut diff --git a/src/Common/freeglut_main.c b/src/Common/freeglut_main.c index 2eed2d4..b1654a5 100644 --- a/src/Common/freeglut_main.c +++ b/src/Common/freeglut_main.c @@ -70,12 +70,12 @@ struct GXKeyList gxKeyList; # define MIN(a,b) (((a)<(b)) ? (a) : (b)) #endif -#ifdef WM_TOUCH - typedef BOOL (WINAPI *pGetTouchInputInfo)(HTOUCHINPUT,UINT,PTOUCHINPUT,int); - typedef BOOL (WINAPI *pCloseTouchInputHandle)(HTOUCHINPUT); - static pGetTouchInputInfo fghGetTouchInputInfo = (pGetTouchInputInfo)0xDEADBEEF; - static pCloseTouchInputHandle fghCloseTouchInputHandle = (pCloseTouchInputHandle)0xDEADBEEF; -#endif +extern void fgPlatformReshapeWindow ( SFG_Window *window, int width, int height ); +extern void fgPlatformDisplayWindow ( SFG_Window *window ); +extern void fgPlatformSleepForEvents( long msec ); +extern void fgPlatformProcessSingleEvent ( void ); +extern void fgPlatformMainLoopPreliminaryWork ( void ); + /* * TODO BEFORE THE STABLE RELEASE: @@ -95,65 +95,22 @@ struct GXKeyList gxKeyList; * callback is hooked, the viewport size is updated to * match the new window size. */ -static void fghReshapeWindow ( SFG_Window *window, int width, int height ) -{ - SFG_Window *current_window = fgStructure.CurrentWindow; - - freeglut_return_if_fail( window != NULL ); - #if TARGET_HOST_POSIX_X11 - +static void fgPlatformReshapeWindow ( SFG_Window *window, int width, int height ) +{ XResizeWindow( fgDisplay.Display, window->Window.Handle, width, height ); XFlush( fgDisplay.Display ); /* XXX Shouldn't need this */ +} +#endif -#elif TARGET_HOST_MS_WINDOWS && !defined(_WIN32_WCE) - { - RECT windowRect; - - /* - * For windowed mode, get the current position of the - * window and resize taking the size of the frame - * decorations into account. - */ +static void fghReshapeWindow ( SFG_Window *window, int width, int height ) +{ + SFG_Window *current_window = fgStructure.CurrentWindow; - /* "GetWindowRect" returns the pixel coordinates of the outside of the window */ - GetWindowRect( window->Window.Handle, &windowRect ); + freeglut_return_if_fail( window != NULL ); - /* Create rect in FreeGLUT format, (X,Y) topleft outside window, WxH of client area */ - windowRect.right = windowRect.left+width; - windowRect.bottom = windowRect.top+height; - - if (window->Parent == NULL) - /* get the window rect from this to feed to SetWindowPos, correct for window decorations */ - fghComputeWindowRectFromClientArea_QueryWindow(window,&windowRect,TRUE); - else - { - /* correct rect for position client area of parent window - * (SetWindowPos input for child windows is in coordinates - * relative to the parent's client area). - * Child windows don't have decoration, so no need to correct - * 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; - } - - /* Do the actual resizing */ - SetWindowPos( window->Window.Handle, - HWND_TOP, - windowRect.left, windowRect.top, - windowRect.right - windowRect.left, - windowRect.bottom- windowRect.top, - SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | - SWP_NOZORDER - ); - } -#endif + fgPlatformReshapeWindow ( window, width, height ); if( FETCH_WCB( *window, Reshape ) ) INVOKE_WCB( *window, Reshape, ( width, height ) ); @@ -180,7 +137,7 @@ static void fghReshapeWindow ( SFG_Window *window, int width, int height ) * Calls a window's redraw method. This is used when * a redraw is forced by the incoming window messages. */ -static void fghRedrawWindow ( SFG_Window *window ) +void fghRedrawWindow ( SFG_Window *window ) { SFG_Window *current_window = fgStructure.CurrentWindow; @@ -212,6 +169,13 @@ static void fghRedrawWindow ( SFG_Window *window ) /* * A static helper function to execute display callback for a window */ +#if TARGET_HOST_POSIX_X11 +static void fgPlatformDisplayWindow ( SFG_Window *window ) +{ + fghRedrawWindow ( window ) ; +} +#endif + static void fghcbDisplayWindow( SFG_Window *window, SFG_Enumerator *enumerator ) { @@ -219,16 +183,7 @@ static void fghcbDisplayWindow( SFG_Window *window, window->State.Visible ) { window->State.Redisplay = GL_FALSE; - -#if TARGET_HOST_POSIX_X11 - fghRedrawWindow ( window ) ; -#elif TARGET_HOST_MS_WINDOWS - - RedrawWindow( - window->Window.Handle, NULL, NULL, - RDW_NOERASE | RDW_INTERNALPAINT | RDW_INVALIDATE | RDW_UPDATENOW - ); -#endif + fgPlatformDisplayWindow ( window ); } fgEnumSubWindows( window, fghcbDisplayWindow, enumerator ); @@ -459,20 +414,10 @@ static long fghNextTimer( void ) * Does the magic required to relinquish the CPU until something interesting * happens. */ -static void fghSleepForEvents( void ) -{ - long msec; - - if( fgState.IdleCallback || fghHavePendingRedisplays( ) ) - return; - - msec = fghNextTimer( ); - /* XXX Use GLUT timers for joysticks... */ - /* XXX Dumb; forces granularity to .01sec */ - if( fghHaveJoystick( ) && ( msec > 10 ) ) - msec = 10; #if TARGET_HOST_POSIX_X11 +static void fgPlatformSleepForEvents( long msec ) +{ /* * Possibly due to aggressive use of XFlush() and friends, * it is possible to have our socket drained but still have @@ -501,16 +446,30 @@ static void fghSleepForEvents( void ) fgWarning ( "freeglut select() error: %d", errno ); #endif } -#elif TARGET_HOST_MS_WINDOWS - MsgWaitForMultipleObjects( 0, NULL, FALSE, msec, QS_ALLINPUT ); +} #endif + +static void fghSleepForEvents( void ) +{ + long msec; + + if( fgState.IdleCallback || fghHavePendingRedisplays( ) ) + return; + + msec = fghNextTimer( ); + /* XXX Use GLUT timers for joysticks... */ + /* XXX Dumb; forces granularity to .01sec */ + if( fghHaveJoystick( ) && ( msec > 10 ) ) + msec = 10; + + fgPlatformSleepForEvents ( msec ); } #if TARGET_HOST_POSIX_X11 /* * Returns GLUT modifier mask for the state field of an X11 event. */ -int fghGetXModifiers( int state ) +int fgPlatformGetModifiers( int state ) { int ret = 0; @@ -523,10 +482,8 @@ int fghGetXModifiers( int state ) return ret; } -#endif -#if TARGET_HOST_POSIX_X11 && _DEBUG static const char* fghTypeToString( int type ) { @@ -968,16 +925,9 @@ static void fghPrintEvent( XEvent *event ) } } -#endif - -/* -- INTERFACE FUNCTIONS -------------------------------------------------- */ -/* - * Executes a single iteration in the freeglut processing loop. - */ -void FGAPIENTRY glutMainLoopEvent( void ) +void fgPlatformProcessSingleEvent ( void ) { -#if TARGET_HOST_POSIX_X11 SFG_Window* window; XEvent event; @@ -1190,7 +1140,7 @@ void FGAPIENTRY glutMainLoopEvent( void ) * XXX track ButtonPress/ButtonRelease events in our own * XXX bit-mask? */ - fgState.Modifiers = fghGetXModifiers( event.xmotion.state ); + fgState.Modifiers = fgPlatformGetModifiers( event.xmotion.state ); if ( event.xmotion.state & ( Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask ) ) { INVOKE_WCB( *window, Motion, ( event.xmotion.x, event.xmotion.y ) ); @@ -1244,7 +1194,7 @@ void FGAPIENTRY glutMainLoopEvent( void ) ! FETCH_WCB( *window, MouseWheel ) ) break; - fgState.Modifiers = fghGetXModifiers( event.xbutton.state ); + fgState.Modifiers = fgPlatformGetModifiers( event.xbutton.state ); /* Finally execute the mouse or mouse wheel callback */ if( ( button < glutDeviceGet ( GLUT_NUM_MOUSE_BUTTONS ) ) || ( ! FETCH_WCB( *window, MouseWheel ) ) ) @@ -1359,7 +1309,7 @@ void FGAPIENTRY glutMainLoopEvent( void ) if( keyboard_cb ) { fgSetWindow( window ); - fgState.Modifiers = fghGetXModifiers( event.xkey.state ); + fgState.Modifiers = fgPlatformGetModifiers( event.xkey.state ); keyboard_cb( asciiCode[ 0 ], event.xkey.x, event.xkey.y ); @@ -1428,7 +1378,7 @@ void FGAPIENTRY glutMainLoopEvent( void ) if( special_cb && (special != -1) ) { fgSetWindow( window ); - fgState.Modifiers = fghGetXModifiers( event.xkey.state ); + fgState.Modifiers = fgPlatformGetModifiers( event.xkey.state ); special_cb( special, event.xkey.x, event.xkey.y ); fgState.Modifiers = INVALID_MODIFIERS; } @@ -1452,32 +1402,22 @@ void FGAPIENTRY glutMainLoopEvent( void ) break; } } +} -#elif TARGET_HOST_MS_WINDOWS - - MSG stMsg; - FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMainLoopEvent" ); - - while( PeekMessage( &stMsg, NULL, 0, 0, PM_NOREMOVE ) ) - { - if( GetMessage( &stMsg, NULL, 0, 0 ) == 0 ) - { - if( fgState.ActionOnWindowClose == GLUT_ACTION_EXIT ) - { - fgDeinitialize( ); - exit( 0 ); - } - else if( fgState.ActionOnWindowClose == GLUT_ACTION_GLUTMAINLOOP_RETURNS ) - fgState.ExecState = GLUT_EXEC_STATE_STOP; +static void fgPlatformMainLoopPreliminaryWork ( void ) +{ +} +#endif - return; - } +/* -- INTERFACE FUNCTIONS -------------------------------------------------- */ - TranslateMessage( &stMsg ); - DispatchMessage( &stMsg ); - } -#endif +/* + * Executes a single iteration in the freeglut processing loop. + */ +void FGAPIENTRY glutMainLoopEvent( void ) +{ + fgPlatformProcessSingleEvent (); if( fgState.Timers.First ) fghCheckTimers( ); @@ -1495,35 +1435,9 @@ void FGAPIENTRY glutMainLoop( void ) { int action; -#if TARGET_HOST_MS_WINDOWS - SFG_Window *window = (SFG_Window *)fgStructure.Windows.First ; -#endif - FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMainLoop" ); -#if TARGET_HOST_MS_WINDOWS - /* - * Processing before the main loop: If there is a window which is open and - * which has a visibility callback, call it. I know this is an ugly hack, - * but I'm not sure what else to do about it. Ideally we should leave - * something uninitialized in the create window code and initialize it in - * the main loop, and have that initialization create a "WM_ACTIVATE" - * message. Then we would put the visibility callback code in the - * "case WM_ACTIVATE" block below. - John Fay -- 10/24/02 - */ - while( window ) - { - if ( FETCH_WCB( *window, Visibility ) ) - { - SFG_Window *current_window = fgStructure.CurrentWindow ; - - INVOKE_WCB( *window, Visibility, ( window->State.Visible ) ); - fgSetWindow( current_window ); - } - - window = (SFG_Window *)window->Node.Next ; - } -#endif + fgPlatformMainLoopPreliminaryWork (); fgState.ExecState = GLUT_EXEC_STATE_RUNNING ; while( fgState.ExecState == GLUT_EXEC_STATE_RUNNING ) @@ -1580,932 +1494,5 @@ void FGAPIENTRY glutLeaveMainLoop( void ) } -#if TARGET_HOST_MS_WINDOWS -/* - * Determine a GLUT modifer mask based on MS-WINDOWS system info. - */ -static int fghGetWin32Modifiers (void) -{ - return - ( ( ( GetKeyState( VK_LSHIFT ) < 0 ) || - ( GetKeyState( VK_RSHIFT ) < 0 )) ? GLUT_ACTIVE_SHIFT : 0 ) | - ( ( ( GetKeyState( VK_LCONTROL ) < 0 ) || - ( GetKeyState( VK_RCONTROL ) < 0 )) ? GLUT_ACTIVE_CTRL : 0 ) | - ( ( ( GetKeyState( VK_LMENU ) < 0 ) || - ( GetKeyState( VK_RMENU ) < 0 )) ? GLUT_ACTIVE_ALT : 0 ); -} - -/* - * The window procedure for handling Win32 events - */ -LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, - LPARAM lParam ) -{ - static unsigned char lControl = 0, rControl = 0, lShift = 0, - rShift = 0, lAlt = 0, rAlt = 0; - - SFG_Window* window; - PAINTSTRUCT ps; - LRESULT lRet = 1; - - FREEGLUT_INTERNAL_ERROR_EXIT_IF_NOT_INITIALISED ( "Event Handler" ) ; - - window = fgWindowByHandle( hWnd ); - - if ( ( window == NULL ) && ( uMsg != WM_CREATE ) ) - return DefWindowProc( hWnd, uMsg, wParam, lParam ); - - /* printf ( "Window %3d message <%04x> %12d %12d\n", window?window->ID:0, - uMsg, wParam, lParam ); */ - - if ( window ) - { - /* 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 ) - ); - - lControl = 1; - } - - if ( !rControl && GetAsyncKeyState ( VK_RCONTROL ) ) - { - INVOKE_WCB ( *window, Special, - ( GLUT_KEY_CTRL_R, window->State.MouseX, window->State.MouseY ) - ); - - rControl = 1; - } - - if ( !lShift && GetAsyncKeyState ( VK_LSHIFT ) ) - { - INVOKE_WCB ( *window, Special, - ( GLUT_KEY_SHIFT_L, window->State.MouseX, window->State.MouseY ) - ); - - lShift = 1; - } - - if ( !rShift && GetAsyncKeyState ( VK_RSHIFT ) ) - { - INVOKE_WCB ( *window, Special, - ( GLUT_KEY_SHIFT_R, window->State.MouseX, window->State.MouseY ) - ); - - rShift = 1; - } - - if ( !lAlt && GetAsyncKeyState ( VK_LMENU ) ) - { - INVOKE_WCB ( *window, Special, - ( GLUT_KEY_ALT_L, window->State.MouseX, window->State.MouseY ) - ); - - lAlt = 1; - } - - if ( !rAlt && GetAsyncKeyState ( VK_RMENU ) ) - { - INVOKE_WCB ( *window, Special, - ( GLUT_KEY_ALT_R, window->State.MouseX, window->State.MouseY ) - ); - - rAlt = 1; - } - - /* 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 ) - ); - - lControl = 0; - } - - if ( rControl && !GetAsyncKeyState ( VK_RCONTROL ) ) - { - INVOKE_WCB ( *window, SpecialUp, - ( GLUT_KEY_CTRL_R, window->State.MouseX, window->State.MouseY ) - ); - - rControl = 0; - } - - if ( lShift && !GetAsyncKeyState ( VK_LSHIFT ) ) - { - INVOKE_WCB ( *window, SpecialUp, - ( GLUT_KEY_SHIFT_L, window->State.MouseX, window->State.MouseY ) - ); - - lShift = 0; - } - - if ( rShift && !GetAsyncKeyState ( VK_RSHIFT ) ) - { - INVOKE_WCB ( *window, SpecialUp, - ( GLUT_KEY_SHIFT_R, window->State.MouseX, window->State.MouseY ) - ); - - rShift = 0; - } - - if ( lAlt && !GetAsyncKeyState ( VK_LMENU ) ) - { - INVOKE_WCB ( *window, SpecialUp, - ( GLUT_KEY_ALT_L, window->State.MouseX, window->State.MouseY ) - ); - - lAlt = 0; - } - - if ( rAlt && !GetAsyncKeyState ( VK_RMENU ) ) - { - INVOKE_WCB ( *window, SpecialUp, - ( GLUT_KEY_ALT_R, window->State.MouseX, window->State.MouseY ) - ); - - rAlt = 0; - } - } - - switch( uMsg ) - { - case WM_CREATE: - /* The window structure is passed as the creation structure parameter... */ - window = (SFG_Window *) (((LPCREATESTRUCT) lParam)->lpCreateParams); - FREEGLUT_INTERNAL_ERROR_EXIT ( ( window != NULL ), "Cannot create window", - "fgWindowProc" ); - - window->Window.Handle = hWnd; - window->Window.Device = GetDC( hWnd ); - if( window->IsMenu ) - { - unsigned int current_DisplayMode = fgState.DisplayMode; - fgState.DisplayMode = GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH; -#if !defined(_WIN32_WCE) - fgSetupPixelFormat( window, GL_FALSE, PFD_MAIN_PLANE ); -#endif - fgState.DisplayMode = current_DisplayMode; - - if( fgStructure.MenuContext ) - wglMakeCurrent( window->Window.Device, - fgStructure.MenuContext->MContext - ); - else - { - fgStructure.MenuContext = - (SFG_MenuContext *)malloc( sizeof(SFG_MenuContext) ); - fgStructure.MenuContext->MContext = - wglCreateContext( window->Window.Device ); - } - - /* window->Window.Context = wglGetCurrentContext (); */ - window->Window.Context = wglCreateContext( window->Window.Device ); - } - else - { -#if !defined(_WIN32_WCE) - fgSetupPixelFormat( window, GL_FALSE, PFD_MAIN_PLANE ); -#endif - - if( ! fgState.UseCurrentContext ) - window->Window.Context = - wglCreateContext( window->Window.Device ); - else - { - window->Window.Context = wglGetCurrentContext( ); - if( ! window->Window.Context ) - window->Window.Context = - wglCreateContext( window->Window.Device ); - } - -#if !defined(_WIN32_WCE) - fgNewWGLCreateContext( window ); -#endif - } - - window->State.NeedToResize = GL_TRUE; - /* if we used CW_USEDEFAULT (thats a negative value) for the size - * of the window, query the window now for the size at which it - * was created. - */ - if( ( window->State.Width < 0 ) || ( window->State.Height < 0 ) ) - { - SFG_Window *current_window = fgStructure.CurrentWindow; - - fgSetWindow( window ); - window->State.Width = glutGet( GLUT_WINDOW_WIDTH ); - window->State.Height = glutGet( GLUT_WINDOW_HEIGHT ); - fgSetWindow( current_window ); - } - - ReleaseDC( window->Window.Handle, window->Window.Device ); - -#if defined(_WIN32_WCE) - /* Take over button handling */ - { - HINSTANCE dxDllLib=LoadLibrary(_T("gx.dll")); - if (dxDllLib) - { - GXGetDefaultKeys_=(GXGETDEFAULTKEYS)GetProcAddress(dxDllLib, _T("?GXGetDefaultKeys@@YA?AUGXKeyList@@H@Z")); - GXOpenInput_=(GXOPENINPUT)GetProcAddress(dxDllLib, _T("?GXOpenInput@@YAHXZ")); - } - - if(GXOpenInput_) - (*GXOpenInput_)(); - if(GXGetDefaultKeys_) - gxKeyList = (*GXGetDefaultKeys_)(GX_LANDSCAPEKEYS); - } - -#endif /* defined(_WIN32_WCE) */ - break; - - case WM_SIZE: - /* - * If the window is visible, then it is the user manually resizing it. - * If it is not, then it is the system sending us a dummy resize with - * zero dimensions on a "glutIconifyWindow" call. - */ - if( window->State.Visible ) - { - window->State.NeedToResize = GL_TRUE; -#if defined(_WIN32_WCE) - window->State.Width = HIWORD(lParam); - window->State.Height = LOWORD(lParam); -#else - window->State.Width = LOWORD(lParam); - window->State.Height = HIWORD(lParam); -#endif /* defined(_WIN32_WCE) */ - } - - break; - - case WM_SETFOCUS: -/* printf("WM_SETFOCUS: %p\n", window ); */ - lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); - INVOKE_WCB( *window, Entry, ( GLUT_ENTERED ) ); - 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 ); - - break; - -#if 0 - case WM_ACTIVATE: - if (LOWORD(wParam) != WA_INACTIVE) - { -/* printf("WM_ACTIVATE: fgSetCursor( %p, %d)\n", window, - window->State.Cursor ); */ - fgSetCursor( window, window->State.Cursor ); - } - - lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); - break; -#endif - - case WM_SETCURSOR: -/* printf ( "Cursor event %x %x %x %x\n", window, window->State.Cursor, lParam, wParam ) ; */ - if( LOWORD( lParam ) == HTCLIENT ) - fgSetCursor ( window, window->State.Cursor ) ; - else - lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); - break; - - case WM_SHOWWINDOW: - window->State.Visible = GL_TRUE; - window->State.Redisplay = GL_TRUE; - break; - - case WM_PAINT: - /* Turn on the visibility in case it was turned off somehow */ - window->State.Visible = GL_TRUE; - BeginPaint( hWnd, &ps ); - fghRedrawWindow( window ); - EndPaint( hWnd, &ps ); - break; - - case WM_CLOSE: - fgDestroyWindow ( window ); - if ( fgState.ActionOnWindowClose != GLUT_ACTION_CONTINUE_EXECUTION ) - PostQuitMessage(0); - break; - - case WM_DESTROY: - /* - * The window already got destroyed, so don't bother with it. - */ - return 0; - - case WM_MOUSEMOVE: - { -#if defined(_WIN32_WCE) - window->State.MouseX = 320-HIWORD( lParam ); - window->State.MouseY = LOWORD( lParam ); -#else - window->State.MouseX = LOWORD( lParam ); - window->State.MouseY = HIWORD( lParam ); -#endif /* defined(_WIN32_WCE) */ - /* Restrict to [-32768, 32767] to match X11 behaviour */ - /* See comment in "freeglut_developer" mailing list 10/4/04 */ - if ( window->State.MouseX > 32767 ) window->State.MouseX -= 65536; - if ( window->State.MouseY > 32767 ) window->State.MouseY -= 65536; - - if ( window->ActiveMenu ) - { - fgUpdateMenuHighlight( window->ActiveMenu ); - break; - } - SetFocus(window->Window.Handle); - - fgState.Modifiers = fghGetWin32Modifiers( ); - - if( ( wParam & MK_LBUTTON ) || - ( wParam & MK_MBUTTON ) || - ( wParam & MK_RBUTTON ) ) - INVOKE_WCB( *window, Motion, ( window->State.MouseX, - window->State.MouseY ) ); - else - INVOKE_WCB( *window, Passive, ( window->State.MouseX, - window->State.MouseY ) ); - - fgState.Modifiers = INVALID_MODIFIERS; - } - break; - - case WM_LBUTTONDOWN: - case WM_MBUTTONDOWN: - case WM_RBUTTONDOWN: - case WM_LBUTTONUP: - case WM_MBUTTONUP: - case WM_RBUTTONUP: - { - GLboolean pressed = GL_TRUE; - int button; - -#if defined(_WIN32_WCE) - window->State.MouseX = 320-HIWORD( lParam ); - window->State.MouseY = LOWORD( lParam ); -#else - window->State.MouseX = LOWORD( lParam ); - window->State.MouseY = HIWORD( lParam ); -#endif /* defined(_WIN32_WCE) */ - - /* Restrict to [-32768, 32767] to match X11 behaviour */ - /* See comment in "freeglut_developer" mailing list 10/4/04 */ - if ( window->State.MouseX > 32767 ) window->State.MouseX -= 65536; - if ( window->State.MouseY > 32767 ) window->State.MouseY -= 65536; - - switch( uMsg ) - { - case WM_LBUTTONDOWN: - pressed = GL_TRUE; - button = GLUT_LEFT_BUTTON; - break; - case WM_MBUTTONDOWN: - pressed = GL_TRUE; - button = GLUT_MIDDLE_BUTTON; - break; - case WM_RBUTTONDOWN: - pressed = GL_TRUE; - button = GLUT_RIGHT_BUTTON; - break; - case WM_LBUTTONUP: - pressed = GL_FALSE; - button = GLUT_LEFT_BUTTON; - break; - case WM_MBUTTONUP: - pressed = GL_FALSE; - button = GLUT_MIDDLE_BUTTON; - break; - case WM_RBUTTONUP: - pressed = GL_FALSE; - button = GLUT_RIGHT_BUTTON; - break; - default: - pressed = GL_FALSE; - button = -1; - break; - } - -#if !defined(_WIN32_WCE) - if( GetSystemMetrics( SM_SWAPBUTTON ) ) - { - if( button == GLUT_LEFT_BUTTON ) - button = GLUT_RIGHT_BUTTON; - else - if( button == GLUT_RIGHT_BUTTON ) - button = GLUT_LEFT_BUTTON; - } -#endif /* !defined(_WIN32_WCE) */ - - if( button == -1 ) - return DefWindowProc( hWnd, uMsg, lParam, wParam ); - - /* - * Do not execute the application's mouse callback if a menu - * is hooked to this button. In that case an appropriate - * private call should be generated. - */ - if( fgCheckActiveMenu( window, button, pressed, - window->State.MouseX, window->State.MouseY ) ) - break; - - /* Set capture so that the window captures all the mouse messages */ - /* - * XXX - Multiple button support: Under X11, the mouse is not released - * XXX - from the window until all buttons have been released, even if the - * XXX - user presses a button in another window. This will take more - * XXX - code changes than I am up to at the moment (10/5/04). The present - * XXX - is a 90 percent solution. - */ - if ( pressed == GL_TRUE ) - SetCapture ( window->Window.Handle ) ; - else - ReleaseCapture () ; - - if( ! FETCH_WCB( *window, Mouse ) ) - break; - - fgSetWindow( window ); - fgState.Modifiers = fghGetWin32Modifiers( ); - - INVOKE_WCB( - *window, Mouse, - ( button, - pressed ? GLUT_DOWN : GLUT_UP, - window->State.MouseX, - window->State.MouseY - ) - ); - - fgState.Modifiers = INVALID_MODIFIERS; - } - break; - - case 0x020a: - /* Should be WM_MOUSEWHEEL but my compiler doesn't recognize it */ - { - int wheel_number = LOWORD( wParam ); - short ticks = ( short )HIWORD( wParam ); - fgState.MouseWheelTicks += ticks; - - /* - * XXX Should use WHEEL_DELTA instead of 120 - */ - if ( abs ( fgState.MouseWheelTicks ) > 120 ) - { - int direction = ( fgState.MouseWheelTicks > 0 ) ? 1 : -1; - - if( ! FETCH_WCB( *window, MouseWheel ) && - ! FETCH_WCB( *window, Mouse ) ) - break; - - fgSetWindow( window ); - fgState.Modifiers = fghGetWin32Modifiers( ); - - /* - * XXX Should use WHEEL_DELTA instead of 120 - */ - while( abs ( fgState.MouseWheelTicks ) > 120 ) - { - if( FETCH_WCB( *window, MouseWheel ) ) - INVOKE_WCB( *window, MouseWheel, - ( wheel_number, - direction, - window->State.MouseX, - window->State.MouseY - ) - ); - else /* No mouse wheel, call the mouse button callback twice */ - { - /* - * Map wheel zero to button 3 and 4; +1 to 3, -1 to 4 - * " " one +1 to 5, -1 to 6, ... - * - * XXX The below assumes that you have no more than 3 mouse - * XXX buttons. Sorry. - */ - int button = wheel_number * 2 + 3; - if( direction < 0 ) - ++button; - INVOKE_WCB( *window, Mouse, - ( button, GLUT_DOWN, - window->State.MouseX, window->State.MouseY ) - ); - INVOKE_WCB( *window, Mouse, - ( button, GLUT_UP, - window->State.MouseX, window->State.MouseY ) - ); - } - - /* - * XXX Should use WHEEL_DELTA instead of 120 - */ - fgState.MouseWheelTicks -= 120 * direction; - } - - fgState.Modifiers = INVALID_MODIFIERS; - } - } - break ; - - case WM_SYSKEYDOWN: - case WM_KEYDOWN: - { - int keypress = -1; - POINT mouse_pos ; - - if( ( fgState.KeyRepeat==GLUT_KEY_REPEAT_OFF || window->State.IgnoreKeyRepeat==GL_TRUE ) && (HIWORD(lParam) & KF_REPEAT) ) - break; - - /* - * Remember the current modifiers state. This is done here in order - * to make sure the VK_DELETE keyboard callback is executed properly. - */ - fgState.Modifiers = fghGetWin32Modifiers( ); - - 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; - - switch( wParam ) - { - KEY( VK_F1, GLUT_KEY_F1 ); - KEY( VK_F2, GLUT_KEY_F2 ); - KEY( VK_F3, GLUT_KEY_F3 ); - KEY( VK_F4, GLUT_KEY_F4 ); - KEY( VK_F5, GLUT_KEY_F5 ); - KEY( VK_F6, GLUT_KEY_F6 ); - KEY( VK_F7, GLUT_KEY_F7 ); - KEY( VK_F8, GLUT_KEY_F8 ); - KEY( VK_F9, GLUT_KEY_F9 ); - KEY( VK_F10, GLUT_KEY_F10 ); - KEY( VK_F11, GLUT_KEY_F11 ); - KEY( VK_F12, GLUT_KEY_F12 ); - KEY( VK_PRIOR, GLUT_KEY_PAGE_UP ); - KEY( VK_NEXT, GLUT_KEY_PAGE_DOWN ); - KEY( VK_HOME, GLUT_KEY_HOME ); - KEY( VK_END, GLUT_KEY_END ); - KEY( VK_LEFT, GLUT_KEY_LEFT ); - KEY( VK_UP, GLUT_KEY_UP ); - KEY( VK_RIGHT, GLUT_KEY_RIGHT ); - KEY( VK_DOWN, GLUT_KEY_DOWN ); - KEY( VK_INSERT, GLUT_KEY_INSERT ); - KEY( VK_LCONTROL, GLUT_KEY_CTRL_L ); - KEY( VK_RCONTROL, GLUT_KEY_CTRL_R ); - KEY( VK_LSHIFT, GLUT_KEY_SHIFT_L ); - KEY( VK_RSHIFT, GLUT_KEY_SHIFT_R ); - KEY( VK_LMENU, GLUT_KEY_ALT_L ); - KEY( VK_RMENU, GLUT_KEY_ALT_R ); - - case VK_DELETE: - /* The delete key should be treated as an ASCII keypress: */ - INVOKE_WCB( *window, Keyboard, - ( 127, window->State.MouseX, window->State.MouseY ) - ); - } - -#if defined(_WIN32_WCE) - if(!(lParam & 0x40000000)) /* Prevent auto-repeat */ - { - if(wParam==(unsigned)gxKeyList.vkRight) - keypress = GLUT_KEY_RIGHT; - else if(wParam==(unsigned)gxKeyList.vkLeft) - keypress = GLUT_KEY_LEFT; - else if(wParam==(unsigned)gxKeyList.vkUp) - keypress = GLUT_KEY_UP; - else if(wParam==(unsigned)gxKeyList.vkDown) - keypress = GLUT_KEY_DOWN; - else if(wParam==(unsigned)gxKeyList.vkA) - keypress = GLUT_KEY_F1; - else if(wParam==(unsigned)gxKeyList.vkB) - keypress = GLUT_KEY_F2; - else if(wParam==(unsigned)gxKeyList.vkC) - keypress = GLUT_KEY_F3; - else if(wParam==(unsigned)gxKeyList.vkStart) - keypress = GLUT_KEY_F4; - } -#endif - - if( keypress != -1 ) - INVOKE_WCB( *window, Special, - ( keypress, - window->State.MouseX, window->State.MouseY ) - ); - - fgState.Modifiers = INVALID_MODIFIERS; - } - break; - - case WM_SYSKEYUP: - case WM_KEYUP: - { - int keypress = -1; - POINT mouse_pos; - - /* - * Remember the current modifiers state. This is done here in order - * to make sure the VK_DELETE keyboard callback is executed properly. - */ - fgState.Modifiers = fghGetWin32Modifiers( ); - - 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. - * "KEY(a,b)" was defined under "WM_KEYDOWN" - */ - - switch( wParam ) - { - KEY( VK_F1, GLUT_KEY_F1 ); - KEY( VK_F2, GLUT_KEY_F2 ); - KEY( VK_F3, GLUT_KEY_F3 ); - KEY( VK_F4, GLUT_KEY_F4 ); - KEY( VK_F5, GLUT_KEY_F5 ); - KEY( VK_F6, GLUT_KEY_F6 ); - KEY( VK_F7, GLUT_KEY_F7 ); - KEY( VK_F8, GLUT_KEY_F8 ); - KEY( VK_F9, GLUT_KEY_F9 ); - KEY( VK_F10, GLUT_KEY_F10 ); - KEY( VK_F11, GLUT_KEY_F11 ); - KEY( VK_F12, GLUT_KEY_F12 ); - KEY( VK_PRIOR, GLUT_KEY_PAGE_UP ); - KEY( VK_NEXT, GLUT_KEY_PAGE_DOWN ); - KEY( VK_HOME, GLUT_KEY_HOME ); - KEY( VK_END, GLUT_KEY_END ); - KEY( VK_LEFT, GLUT_KEY_LEFT ); - KEY( VK_UP, GLUT_KEY_UP ); - KEY( VK_RIGHT, GLUT_KEY_RIGHT ); - KEY( VK_DOWN, GLUT_KEY_DOWN ); - KEY( VK_INSERT, GLUT_KEY_INSERT ); - KEY( VK_LCONTROL, GLUT_KEY_CTRL_L ); - KEY( VK_RCONTROL, GLUT_KEY_CTRL_R ); - KEY( VK_LSHIFT, GLUT_KEY_SHIFT_L ); - KEY( VK_RSHIFT, GLUT_KEY_SHIFT_R ); - KEY( VK_LMENU, GLUT_KEY_ALT_L ); - KEY( VK_RMENU, GLUT_KEY_ALT_R ); - - case VK_DELETE: - /* The delete key should be treated as an ASCII keypress: */ - INVOKE_WCB( *window, KeyboardUp, - ( 127, window->State.MouseX, window->State.MouseY ) - ); - break; - - default: - { -#if !defined(_WIN32_WCE) - BYTE state[ 256 ]; - WORD code[ 2 ]; - - GetKeyboardState( state ); - - if( ToAscii( (UINT)wParam, 0, state, code, 0 ) == 1 ) - wParam=code[ 0 ]; - - INVOKE_WCB( *window, KeyboardUp, - ( (char)wParam, - window->State.MouseX, window->State.MouseY ) - ); -#endif /* !defined(_WIN32_WCE) */ - } - } - - if( keypress != -1 ) - INVOKE_WCB( *window, SpecialUp, - ( keypress, - window->State.MouseX, window->State.MouseY ) - ); - - fgState.Modifiers = INVALID_MODIFIERS; - } - break; - - case WM_SYSCHAR: - case WM_CHAR: - { - if( (fgState.KeyRepeat==GLUT_KEY_REPEAT_OFF || window->State.IgnoreKeyRepeat==GL_TRUE) && (HIWORD(lParam) & KF_REPEAT) ) - break; - - fgState.Modifiers = fghGetWin32Modifiers( ); - INVOKE_WCB( *window, Keyboard, - ( (char)wParam, - window->State.MouseX, window->State.MouseY ) - ); - fgState.Modifiers = INVALID_MODIFIERS; - } - break; - - case WM_CAPTURECHANGED: - /* User has finished resizing the window, force a redraw */ - INVOKE_WCB( *window, Display, ( ) ); - - /*lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); */ - break; - - /* Other messages that I have seen and which are not handled already */ - case WM_SETTEXT: /* 0x000c */ - lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); - /* Pass it on to "DefWindowProc" to set the window text */ - break; - - case WM_GETTEXT: /* 0x000d */ - /* Ideally we would copy the title of the window into "lParam" */ - /* strncpy ( (char *)lParam, "Window Title", wParam ); - lRet = ( wParam > 12 ) ? 12 : wParam; */ - /* the number of characters copied */ - lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); - break; - - case WM_GETTEXTLENGTH: /* 0x000e */ - /* Ideally we would get the length of the title of the window */ - lRet = 12; - /* the number of characters in "Window Title\0" (see above) */ - break; - - case WM_ERASEBKGND: /* 0x0014 */ - lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); - break; - -#if !defined(_WIN32_WCE) - case WM_SYNCPAINT: /* 0x0088 */ - /* Another window has moved, need to update this one */ - window->State.Redisplay = GL_TRUE; - lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); - /* Help screen says this message must be passed to "DefWindowProc" */ - break; - - case WM_NCPAINT: /* 0x0085 */ - /* Need to update the border of this window */ - lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); - /* Pass it on to "DefWindowProc" to repaint a standard border */ - break; - - case WM_SYSCOMMAND : /* 0x0112 */ - { - /* - * We have received a system command message. Try to act on it. - * The commands are passed in through the "wParam" parameter: - * The least significant digit seems to be which edge of the window - * is being used for a resize event: - * 4 3 5 - * 1 2 - * 7 6 8 - * Congratulations and thanks to Richard Rauch for figuring this out.. - */ - switch ( wParam & 0xfff0 ) - { - case SC_SIZE : - break ; - - case SC_MOVE : - break ; - - case SC_MINIMIZE : - /* User has clicked on the "-" to minimize the window */ - /* Turn off the visibility */ - window->State.Visible = GL_FALSE ; - - break ; - - case SC_MAXIMIZE : - break ; - - case SC_NEXTWINDOW : - break ; - - case SC_PREVWINDOW : - break ; - - case SC_CLOSE : - /* Followed very closely by a WM_CLOSE message */ - break ; - - case SC_VSCROLL : - break ; - - case SC_HSCROLL : - break ; - - case SC_MOUSEMENU : - break ; - - case SC_KEYMENU : - break ; - - case SC_ARRANGE : - break ; - - case SC_RESTORE : - break ; - - case SC_TASKLIST : - break ; - - case SC_SCREENSAVE : - break ; - - case SC_HOTKEY : - break ; - -#if(WINVER >= 0x0400) - case SC_DEFAULT : - break ; - - case SC_MONITORPOWER : - break ; - - case SC_CONTEXTHELP : - break ; -#endif /* WINVER >= 0x0400 */ - - default: -#if _DEBUG - fgWarning( "Unknown wParam type 0x%x", wParam ); -#endif - break; - } - } -#endif /* !defined(_WIN32_WCE) */ - - /* We need to pass the message on to the operating system as well */ - lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); - break; - -#ifdef WM_TOUCH - /* handle multi-touch messages */ - case WM_TOUCH: - { - unsigned int numInputs = (unsigned int)wParam; - unsigned int i = 0; - TOUCHINPUT* ti = (TOUCHINPUT*)malloc( sizeof(TOUCHINPUT)*numInputs); - - if (fghGetTouchInputInfo == (pGetTouchInputInfo)0xDEADBEEF) { - fghGetTouchInputInfo = (pGetTouchInputInfo)GetProcAddress(GetModuleHandle("user32"),"GetTouchInputInfo"); - fghCloseTouchInputHandle = (pCloseTouchInputHandle)GetProcAddress(GetModuleHandle("user32"),"CloseTouchInputHandle"); - } - - if (!fghGetTouchInputInfo) { - free( (void*)ti ); - break; - } - - if (fghGetTouchInputInfo( (HTOUCHINPUT)lParam, numInputs, ti, sizeof(TOUCHINPUT) )) { - /* Handle each contact point */ - for (i = 0; i < numInputs; ++i ) { - - POINT tp; - tp.x = TOUCH_COORD_TO_PIXEL(ti[i].x); - tp.y = TOUCH_COORD_TO_PIXEL(ti[i].y); - ScreenToClient( hWnd, &tp ); - - ti[i].dwID = ti[i].dwID * 2; - - if (ti[i].dwFlags & TOUCHEVENTF_DOWN) { - INVOKE_WCB( *window, MultiEntry, ( ti[i].dwID, GLUT_ENTERED ) ); - INVOKE_WCB( *window, MultiButton, ( ti[i].dwID, tp.x, tp.y, 0, GLUT_DOWN ) ); - } else if (ti[i].dwFlags & TOUCHEVENTF_MOVE) { - INVOKE_WCB( *window, MultiMotion, ( ti[i].dwID, tp.x, tp.y ) ); - } else if (ti[i].dwFlags & TOUCHEVENTF_UP) { - INVOKE_WCB( *window, MultiButton, ( ti[i].dwID, tp.x, tp.y, 0, GLUT_UP ) ); - INVOKE_WCB( *window, MultiEntry, ( ti[i].dwID, GLUT_LEFT ) ); - } - } - } - fghCloseTouchInputHandle((HTOUCHINPUT)lParam); - free( (void*)ti ); - lRet = 0; /*DefWindowProc( hWnd, uMsg, wParam, lParam );*/ - break; - } -#endif - default: - /* Handle unhandled messages */ - lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); - break; - } - - return lRet; -} -#endif /*** END OF FILE ***/