xfreerdp: start experimenting with multitouch
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 25 Apr 2013 21:00:43 +0000 (17:00 -0400)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 25 Apr 2013 21:00:43 +0000 (17:00 -0400)
client/X11/CMakeLists.txt
client/X11/xf_window.c
cmake/FindXi.cmake [new file with mode: 0644]

index 7d08ea6..2f833ed 100644 (file)
@@ -94,11 +94,16 @@ set(XV_FEATURE_TYPE "RECOMMENDED")
 set(XV_FEATURE_PURPOSE "video")
 set(XV_FEATURE_DESCRIPTION "X11 video extension")
 
+set(XI_FEATURE_TYPE "RECOMMENDED")
+set(XI_FEATURE_PURPOSE "input")
+set(XI_FEATURE_DESCRIPTION "X11 input extension")
+
 find_feature(XShm ${XSHM_FEATURE_TYPE} ${XSHM_FEATURE_PURPOSE} ${XSHM_FEATURE_DESCRIPTION})
 find_feature(Xinerama ${XINERAMA_FEATURE_TYPE} ${XINERAMA_FEATURE_PURPOSE} ${XINERAMA_FEATURE_DESCRIPTION})
 find_feature(Xext ${XEXT_FEATURE_TYPE} ${XEXT_FEATURE_PURPOSE} ${XEXT_FEATURE_DESCRIPTION})
 find_feature(Xcursor ${XCURSOR_FEATURE_TYPE} ${XCURSOR_FEATURE_PURPOSE} ${XCURSOR_FEATURE_DESCRIPTION})
 find_feature(Xv ${XV_FEATURE_TYPE} ${XV_FEATURE_PURPOSE} ${XV_FEATURE_DESCRIPTION})
+find_feature(Xi ${XI_FEATURE_TYPE} ${XI_FEATURE_PURPOSE} ${XI_FEATURE_DESCRIPTION})
 
 if(WITH_XINERAMA)
        add_definitions(-DWITH_XINERAMA)
@@ -124,6 +129,12 @@ if(WITH_XV)
        set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XV_LIBRARIES})
 endif()
 
+if(WITH_XI)
+       add_definitions(-DWITH_XI)
+       include_directories(${XI_INCLUDE_DIRS})
+       set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XI_LIBRARIES})
+endif()
+
 include_directories(${CMAKE_SOURCE_DIR}/resources)
 
 set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp-client)
index fd6631c..46f5507 100644 (file)
 #include <X11/extensions/shape.h>
 #endif
 
+#ifdef WITH_XI
+#include <X11/extensions/XInput2.h>
+#endif
+
 #ifdef WITH_DEBUG_X11
 #define DEBUG_X11(fmt, ...) DEBUG_CLASS(X11, fmt, ## __VA_ARGS__)
 #else
@@ -319,6 +323,73 @@ static void xf_SetWindowPID(xfInfo* xfi, xfWindow* window, pid_t pid)
                        32, PropModeReplace, (unsigned char *)&pid, 1);
 }
 
+int xf_input_init(xfInfo* xfi, Window window)
+{
+       int i, j;
+       int ndevices;
+       int major = 2;
+       int minor = 2;
+       Status xstatus;
+       XIEventMask evmask;
+       XIDeviceInfo* info;
+       int opcode, event, error;
+       XIGrabModifiers mods = { 1 };
+       unsigned char mask[XIMaskLen(XI_LASTEVENT)];
+
+       if (!XQueryExtension(xfi->display, "XInputExtension", &opcode, &event, &error))
+       {
+               printf("XInput extension not available.\n");
+               return -1;
+       }
+
+       XIQueryVersion(xfi->display, &major, &minor);
+
+       if (major * 1000 + minor < 2002)
+       {
+               printf("Server does not support XI 2.2\n");
+               return -1;
+       }
+
+       info = XIQueryDevice(xfi->display, XIAllDevices, &ndevices);
+
+       for (i = 0; i < ndevices; i++)
+       {
+               XIDeviceInfo* dev = &info[i];
+
+               for (j = 0; j < dev->num_classes; j++)
+               {
+                       XIAnyClassInfo* class = dev->classes[j];
+                       XITouchClassInfo* t = (XITouchClassInfo*) class;
+
+                       if (class->type != XITouchClass)
+                               continue;
+
+                       printf("%s %s touch device, supporting %d touches.\n",
+                               dev->name, (t->mode == XIDirectTouch) ? "direct" : "dependent", t->num_touches);
+               }
+       }
+
+       evmask.mask = mask;
+       evmask.mask_len = sizeof(mask);
+       ZeroMemory(mask, sizeof(mask));
+       evmask.deviceid = XIAllDevices;
+
+       XISetMask(mask, XI_TouchBegin);
+       XISetMask(mask, XI_TouchUpdate);
+       XISetMask(mask, XI_TouchEnd);
+
+       xstatus = XISelectEvents(xfi->display, window, &evmask, 1);
+       //XIClearMask(mask, XI_TouchOwnership);
+
+       mods.modifiers = XIAnyModifier;
+
+       //XIGrabTouchBegin(xfi->display, XIAllMasterDevices, window, XINoOwnerEvents, &evmask, 1, &mods);
+
+       XSync(xfi->display, False);
+
+       return -1;
+}
+
 xfWindow* xf_CreateDesktopWindow(xfInfo* xfi, char* name, int width, int height, BOOL decorations)
 {
        xfWindow* window;
@@ -403,6 +474,8 @@ xfWindow* xf_CreateDesktopWindow(xfInfo* xfi, char* name, int width, int height,
                XClearWindow(xfi->display, window->handle);
                XMapWindow(xfi->display, window->handle);
 
+               xf_input_init(xfi, window->handle);
+
                /*
                 * NOTE: This must be done here to handle reparenting the window, 
                 * so that we don't miss the event and hang waiting for the next one
diff --git a/cmake/FindXi.cmake b/cmake/FindXi.cmake
new file mode 100644 (file)
index 0000000..80bcdd6
--- /dev/null
@@ -0,0 +1,46 @@
+# - Find Xi
+# Find the Xi libraries
+#
+#  This module defines the following variables:
+#     XI_FOUND        - true if XI_INCLUDE_DIR & XI_LIBRARY are found
+#     XI_LIBRARIES    - Set when XI_LIBRARY is found
+#     XI_INCLUDE_DIRS - Set when XI_INCLUDE_DIR is found
+#
+#     XI_INCLUDE_DIR  - where to find XInput2.h, etc.
+#     XI_LIBRARY      - the Xi library
+#
+
+#=============================================================================
+# Copyright 2011 O.S. Systems Software Ltda.
+# Copyright 2011 Otavio Salvador <otavio@ossystems.com.br>
+# Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#=============================================================================
+
+find_path(XI_INCLUDE_DIR NAMES X11/extensions/XInput2.h
+          DOC "The Xi include directory")
+
+find_library(XI_LIBRARY NAMES Xi
+          DOC "The Xi library")
+
+include(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Xi DEFAULT_MSG XI_LIBRARY XI_INCLUDE_DIR)
+
+if(XI_FOUND)
+       set(XI_LIBRARIES ${XI_LIBRARY})
+       set(XI_INCLUDE_DIRS ${XI_INCLUDE_DIR})
+endif()
+
+mark_as_advanced(XI_INCLUDE_DIR XI_LIBRARY)
+