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);