Adding multitouch capability per e-mail from Florian Echtler dated 3/17/11 12:07 PM
authorJohn F. Fay <johnffay@nettally.com>
Fri, 18 Mar 2011 02:59:22 +0000 (02:59 +0000)
committerJohn F. Fay <johnffay@nettally.com>
Fri, 18 Mar 2011 02:59:22 +0000 (02:59 +0000)
git-svn-id: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@905 7f0cb862-5218-0410-a997-914c9d46530a

configure.ac
include/GL/freeglut_ext.h
src/Makefile.am
src/freeglut_callbacks.c
src/freeglut_ext.c
src/freeglut_internal.h
src/freeglut_main.c
src/freeglut_window.c

index 408dd93..0eecd11 100644 (file)
@@ -31,6 +31,7 @@ else
   GL_LIBS="-lGL -lXext -lX11"
   AC_CHECK_LIB([Xxf86vm], [XF86VidModeSwitchToMode])
   AC_CHECK_LIB([Xrandr], [XRRQueryExtension])
+  AC_CHECK_LIB([Xi], [XISelectEvents])
   LIBXI=-lXi
   VERSION_INFO="-version-info 12:0:9"
   EXPORT_FLAGS=
@@ -50,6 +51,7 @@ AC_HEADER_TIME
 AC_CHECK_HEADERS([X11/extensions/xf86vmode.h], [], [], [#include <X11/Xlib.h>])
 AC_CHECK_HEADERS([X11/extensions/Xrandr.h])
 AC_CHECK_HEADERS([X11/extensions/XI.h X11/extensions/XInput.h])
+AC_CHECK_HEADERS([X11/extensions/XInput2.h])
 CPPFLAGS="$save_CPPFLAGS"
 
 # Checks for library functions.
index 52367a6..c0fddbf 100644 (file)
@@ -173,6 +173,17 @@ typedef void (*GLUTproc)();
 FGAPI GLUTproc FGAPIENTRY glutGetProcAddress( const char *procName );
 
 /*
+ * Multi-touch/multi-pointer extensions
+ */
+
+#define GLUT_HAS_MULTI 1
+
+FGAPI void FGAPIENTRY glutMultiEntryFunc( void (* callback)( int, int ) );
+FGAPI void FGAPIENTRY glutMultiButtonFunc( void (* callback)( int, int, int, int, int ) );
+FGAPI void FGAPIENTRY glutMultiMotionFunc( void (* callback)( int, int, int ) );
+FGAPI void FGAPIENTRY glutMultiPassiveFunc( void (* callback)( int, int, int ) );
+
+/*
  * Joystick functions, see freeglut_joystick.c
  */
 /* USE OF THESE FUNCTIONS IS DEPRECATED !!!!! */
index 5b0b00f..7e68570 100644 (file)
@@ -38,7 +38,8 @@ lib@LIBRARY@_la_SOURCES = freeglut_callbacks.c \
                         freeglut_structure.c \
                         freeglut_teapot.c \
                         freeglut_videoresize.c \
-                        freeglut_window.c
+                        freeglut_window.c \
+                        freeglut_xinput.c
 
 #
 # Additional linker flags
index 4f6ad86..a40f7da 100644 (file)
@@ -373,4 +373,40 @@ void FGAPIENTRY glutTabletButtonFunc( void (* callback)( int, int, int, int ) )
     SET_CALLBACK( TabletButton );
 }
 
+/*
+ * Sets the multi-pointer entry callback for the current window
+ */
+void FGAPIENTRY glutMultiEntryFunc( void (* callback)(int, int ) )
+{
+    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMultiEntryFunc" );
+    SET_CALLBACK( MultiEntry );
+}
+
+/*
+ * Sets the multi-pointer button callback for the current window
+ */
+void FGAPIENTRY glutMultiButtonFunc( void (* callback)(int, int, int, int, int ) )
+{
+    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMultiButtonFunc" );
+    SET_CALLBACK( MultiButton );
+}
+
+/*
+ * Sets the multi-pointer motion callback for the current window
+ */
+void FGAPIENTRY glutMultiMotionFunc( void (* callback)(int, int, int ) )
+{
+    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMultiMotionFunc" );
+    SET_CALLBACK( MultiMotion );
+}
+
+/*
+ * Sets the multi-pointer passive motion callback for the current window
+ */
+void FGAPIENTRY glutMultiPassiveFunc( void (* callback)(int, int, int ) )
+{
+    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMultiPassiveFunc" );
+    SET_CALLBACK( MultiPassive );
+}
+
 /*** END OF FILE ***/
index 9470dd7..927cb4e 100644 (file)
@@ -85,6 +85,10 @@ static GLUTproc fghGetGLUTProcAddress( const char* procName )
     CHECK_NAME(glutReshapeFunc);
     CHECK_NAME(glutKeyboardFunc);
     CHECK_NAME(glutMouseFunc);
+    CHECK_NAME(glutMultiEntryFunc);
+    CHECK_NAME(glutMultiMotionFunc);
+    CHECK_NAME(glutMultiButtonFunc);
+    CHECK_NAME(glutMultiPassiveFunc);
     CHECK_NAME(glutMotionFunc);
     CHECK_NAME(glutPassiveMotionFunc);
     CHECK_NAME(glutEntryFunc);
index f7634df..6faef9d 100644 (file)
@@ -238,6 +238,11 @@ typedef void (* FGCBTabletMotion  )( int, int );
 typedef void (* FGCBTabletButton  )( int, int, int, int );
 typedef void (* FGCBDestroy       )( void );
 
+typedef void (* FGCBMultiEntry   )( int, int );
+typedef void (* FGCBMultiButton  )( int, int, int, int, int );
+typedef void (* FGCBMultiMotion  )( int, int, int );
+typedef void (* FGCBMultiPassive )( int, int, int );
+
 /* The global callbacks type definitions */
 typedef void (* FGCBIdle          )( void );
 typedef void (* FGCBTimer         )( int );
@@ -587,6 +592,12 @@ enum
     CB_Joystick,
     CB_Destroy,
 
+    /* MPX-related */
+    CB_MultiEntry,
+    CB_MultiButton,
+    CB_MultiMotion,
+    CB_MultiPassive,
+
     /* Presently ignored */
     CB_Select,
     CB_OverlayDisplay,
@@ -970,6 +981,13 @@ void fgWarning( const char *fmt, ... );
  */
 #if TARGET_HOST_POSIX_X11
 int fgHintPresent(Window window, Atom property, Atom hint);
+
+/* Handler for X extension Events */
+#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
+  void fgHandleExtensionEvents( XEvent * ev );
+  void fgRegisterDevices( Display* dpy, Window* win );
+#endif
+
 #endif
 
 SFG_Proc fghGetProcAddress( const char *procName );
index 3926b38..9002d1c 100644 (file)
@@ -512,7 +512,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 +1445,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;
         }
     }
@@ -2444,6 +2447,41 @@ 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 (GetTouchInputInfo( (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 ) );
+                               }
+                       }
+               }
+               CloseTouchInputHandle((HTOUCHINPUT)lParam);
+               free( (void*)ti );
+               lRet = 0; /*DefWindowProc( hWnd, uMsg, wParam, lParam );*/
+               break;
+       }
+#endif
     default:
         /* Handle unhandled messages */
         lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
index fc9fc55..4f5c9bc 100644 (file)
@@ -1120,6 +1120,11 @@ void fgOpenWindow( SFG_Window* window, const char* title,
         window->Window.Context
     );
 
+    /* register extension events _before_ window is mapped */
+    #ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
+       fgRegisterDevices( fgDisplay.Display, &(window->Window.Handle) );
+    #endif
+
     XMapWindow( fgDisplay.Display, window->Window.Handle );
 
     XFree(visualInfo);
@@ -1286,6 +1291,10 @@ void fgOpenWindow( SFG_Window* window, const char* title,
 /*  SetWindowPos(window->Window.Handle, NULL, 0, 0, 0, 0,
      SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); */
 
+    /* Enable multitouch: additional flag TWF_FINETOUCH, TWF_WANTPALM */
+    #ifdef WM_TOUCH
+       RegisterTouchWindow( window->Window.Handle, TWF_FINETOUCH | TWF_WANTPALM );
+    #endif
 
 #if defined(_WIN32_WCE)
     ShowWindow( window->Window.Handle, SW_SHOW );