Fixing multitouch for Windows per e-mail from Florian Echtler dated 5/3/11 10:33 AM
[freeglut] / src / freeglut_main.c
index 3926b38..f73953d 100644 (file)
@@ -70,6 +70,12 @@ struct GXKeyList gxKeyList;
 #    define MIN(a,b) (((a)<(b)) ? (a) : (b))
 #endif
 
+#ifdef WM_TOUCH
+    typedef BOOL (*pGetTouchInputInfo)(HTOUCHINPUT,UINT,PTOUCHINPUT,int);
+    typedef BOOL (*pCloseTouchInputHandle)(HTOUCHINPUT);
+       static pGetTouchInputInfo fghGetTouchInputInfo = (pGetTouchInputInfo)0xDEADBEEF;
+       static pCloseTouchInputHandle fghCloseTouchInputHandle = (pCloseTouchInputHandle)0xDEADBEEF;
+#endif
 
 /*
  * TODO BEFORE THE STABLE RELEASE:
@@ -122,7 +128,8 @@ static void fghReshapeWindow ( SFG_Window *window, int width, int height )
 
         if ( window->Parent == NULL )
         {
-            if ( ! window->IsMenu && (window != fgStructure.GameModeWindow) )
+          if ( ! window->IsMenu && (window != fgStructure.GameModeWindow) &&
+              !( fgState.DisplayMode & GLUT_BORDERLESS ))
             {
                 w += GetSystemMetrics( SM_CXSIZEFRAME ) * 2;
                 h += GetSystemMetrics( SM_CYSIZEFRAME ) * 2 +
@@ -512,7 +519,7 @@ static void fghSleepForEvents( void )
 /*
  * Returns GLUT modifier mask for the state field of an X11 event.
  */
-static int fghGetXModifiers( int state )
+int fghGetXModifiers( int state )
 {
     int ret = 0;
 
@@ -1445,7 +1452,10 @@ void FGAPIENTRY glutMainLoopEvent( void )
             break;
 
         default:
-            fgWarning ("Unknown X event type: %d\n", event.type);
+            /* enter handling of Extension Events here */
+            #ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
+                fgHandleExtensionEvents( &event );
+            #endif
             break;
         }
     }
@@ -1918,6 +1928,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
             fgUpdateMenuHighlight( window->ActiveMenu );
             break;
         }
+        SetFocus(window->Window.Handle);
 
         fgState.Modifiers = fghGetWin32Modifiers( );
 
@@ -2444,6 +2455,52 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
         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 );