All pastes #1283042 Raw Edit

Someone

public text v1 · immutable
#1283042 ·published 2008-12-11 22:27 UTC
rendered paste body
diff --git a/dlls/winex11.drv/wintab.c b/dlls/winex11.drv/wintab.c
index c997c7c..5ac1e0b 100644
--- a/dlls/winex11.drv/wintab.c
+++ b/dlls/winex11.drv/wintab.c
@@ -265,6 +265,7 @@ static int           proximity_in_type;
 static int           proximity_out_type;
 
 static HWND          hwndTabletDefault;
+static HWND          gActiveOwner;
 static WTPACKET      gMsgPacket;
 static DWORD         gSerial;
 
@@ -859,7 +860,9 @@ static void motion_event( HWND hwnd, XEvent *event )
 
     memset(&gMsgPacket,0,sizeof(WTPACKET));
 
-    TRACE("Received tablet motion event (%p); device id %d, cursor num %d\n",hwnd, (int) motion->deviceid, curnum);
+    TRACE("Received tablet motion event: "
+        "hwnd=%p, motion->deviceid=%d, cursornum=%d, gActiveOwner=%p\n",
+        hwnd, (int)motion->deviceid, curnum, gActiveOwner);
 
     /* Set cursor to inverted if cursor is the eraser */
     gMsgPacket.pkStatus = (cursor->TYPE  == CSR_TYPE_ERASER ? TPS_INVERT:0);
@@ -875,7 +878,8 @@ static void motion_event( HWND hwnd, XEvent *event )
                                            * (gMsgPacket.pkStatus & TPS_INVERT?-1:1));
     gMsgPacket.pkNormalPressure = motion->axis_data[2];
     gMsgPacket.pkButtons = get_button_state(curnum);
-    SendMessageW(hwndTabletDefault,WT_PACKET,gMsgPacket.pkSerialNumber,(LPARAM)hwnd);
+    SendMessageW(hwndTabletDefault, WT_PACKET, gMsgPacket.pkSerialNumber,
+        (LPARAM)gActiveOwner);
 }
 
 static void button_event( HWND hwnd, XEvent *event )
@@ -888,7 +892,9 @@ static void button_event( HWND hwnd, XEvent *event )
 
     memset(&gMsgPacket,0,sizeof(WTPACKET));
 
-    TRACE("Received tablet button %s event\n", (event->type == button_press_type)?"press":"release");
+    TRACE("Received tablet button %s event, hwnd=%p, gActiveOwner=%p\n",
+        (event->type == button_press_type)? "press":"release",
+        hwnd, gActiveOwner);
 
     /* Set cursor to inverted if cursor is the eraser */
     gMsgPacket.pkStatus = (cursor->TYPE == CSR_TYPE_ERASER ? TPS_INVERT:0);
@@ -904,7 +910,8 @@ static void button_event( HWND hwnd, XEvent *event )
                                            * (gMsgPacket.pkStatus & TPS_INVERT?-1:1));
     gMsgPacket.pkNormalPressure = button->axis_data[2];
     gMsgPacket.pkButtons = get_button_state(curnum);
-    SendMessageW(hwndTabletDefault,WT_PACKET,gMsgPacket.pkSerialNumber,(LPARAM)hwnd);
+    SendMessageW(hwndTabletDefault, WT_PACKET, gMsgPacket.pkSerialNumber,
+        (LPARAM)gActiveOwner);
 }
 
 static void key_event( HWND hwnd, XEvent *event )
@@ -922,7 +929,8 @@ static void proximity_event( HWND hwnd, XEvent *event )
     int curnum = cursor_from_device(proximity->deviceid, &cursor);
     LPARAM proximity_info;
 
-    TRACE("hwnd=%p\n", hwnd);
+    TRACE("hwnd=%p, event->type=%s, gActiveOwner=%p\n",
+        (event->type == proximity_out_type)? "out":"in", hwnd, gActiveOwner);
 
     if (curnum < 0)
         return;
@@ -953,7 +961,50 @@ static void proximity_event( HWND hwnd, XEvent *event )
      */
     proximity_info = MAKELPARAM((event->type == proximity_in_type),
                      (event->type == proximity_in_type) || (event->type == proximity_out_type));
-    SendMessageW(hwndTabletDefault, WT_PROXIMITY, (WPARAM)hwnd, proximity_info);
+    SendMessageW(hwndTabletDefault, WT_PROXIMITY, (WPARAM)gActiveOwner,
+        proximity_info);
+}
+
+
+/* time in milliseconds */
+#define X11_WINDOW_CREATION_DELAY 500
+#define MAX_X11_WINDOW_CREATION_WAIT_TIME 5000
+
+/* Guaranteed closest x11 window for your hwnd */
+static Window X11DRV_get_x11_window_from_hwnd(HWND hwnd)
+{
+    Window win;
+    DWORD time_start, current_time, time_waited;
+        
+    time_start = GetTickCount();
+
+    /* try to loop until the x11 window is created */
+    for (;;)
+    {
+        if ((win = X11DRV_get_whole_window(hwnd))                            ||
+            (win = X11DRV_get_whole_window(GetAncestor(hwnd, GA_PARENT)))    ||
+            (win = X11DRV_get_whole_window(GetAncestor(hwnd, GA_ROOTOWNER))) ||
+            (win = X11DRV_get_whole_window(GetAncestor(hwnd, GA_ROOT)))      ||
+            (time_waited >= MAX_X11_WINDOW_CREATION_WAIT_TIME))
+        {
+            break;
+        }
+ 
+        Sleep(X11_WINDOW_CREATION_DELAY);
+        time_current = GetTickCount();
+
+        /* check for overflow, 49.7 days issue */
+        if (time_current <= time_start)
+        {
+            DWORD diff_to_max = DWORD_MAX - time_start;
+            
+            time_waited = diff_to_max + time_current;
+        }
+        else
+            time_waited = time_current - time_start;
+    }
+
+    return win;
 }
 
 /***********************************************************************
@@ -969,11 +1020,18 @@ int X11DRV_AttachEventQueueToTablet(HWND hOwner)
     XDeviceInfo     *target = NULL;
     XDevice         *the_device;
     XEventClass     event_list[7];
-    Window          win = X11DRV_get_whole_window( hOwner );
+    Window          win = X11DRV_get_x11_window_from_hwnd(hOwner);
+
+    TRACE("Creating context for window hOwner=%p, win=%lx, %i cursors\n",
+        hOwner, win, gNumCursors);
 
-    if (!win) return 0;
+    if (!win)
+    {
+        ERR("Failed to hoook x11 window events. Wintab is disabled.\n");
+        return 0;
+    }
 
-    TRACE("Creating context for window %p (%lx)  %i cursors\n", hOwner, win, gNumCursors);
+    gActiveOwner = hOwner;
 
     wine_tsx11_lock();
     devices = pXListInputDevices(data->display, &num_devices);