2 * X events handling functions
4 * Copyright 1993 Alexandre Julliard
14 #include <sys/types.h>
16 #include <X11/keysym.h>
18 #include <X11/Xresource.h>
19 #include <X11/Xutil.h>
20 #include <X11/Xatom.h>
29 #include "clipboard.h"
44 #define NB_BUTTONS 3 /* Windows can handle 3 buttons */
46 #define DndNotDnd -1 /* OffiX drag&drop */
58 /* X context to associate a hwnd to an X window */
59 static XContext winContext = 0;
61 static INT16 captureHT = HTCLIENT;
62 static HWND32 captureWnd = 0;
63 static BOOL32 InputEnabled = TRUE;
64 static BOOL32 SwappedButtons = FALSE;
66 static Atom wmProtocols = None;
67 static Atom wmDeleteWindow = None;
68 static Atom dndProtocol = None;
69 static Atom dndSelection = None;
71 static const char * const event_names[] =
73 "", "", "KeyPress", "KeyRelease", "ButtonPress", "ButtonRelease",
74 "MotionNotify", "EnterNotify", "LeaveNotify", "FocusIn", "FocusOut",
75 "KeymapNotify", "Expose", "GraphicsExpose", "NoExpose", "VisibilityNotify",
76 "CreateNotify", "DestroyNotify", "UnmapNotify", "MapNotify", "MapRequest",
77 "ReparentNotify", "ConfigureNotify", "ConfigureRequest", "GravityNotify",
78 "ResizeRequest", "CirculateNotify", "CirculateRequest", "PropertyNotify",
79 "SelectionClear", "SelectionRequest", "SelectionNotify", "ColormapNotify",
80 "ClientMessage", "MappingNotify"
84 static void EVENT_Key( XKeyEvent *event );
85 static void EVENT_ButtonPress( XButtonEvent *event );
86 static void EVENT_ButtonRelease( XButtonEvent *event );
87 static void EVENT_MotionNotify( XMotionEvent *event );
88 static void EVENT_FocusIn( HWND32 hwnd, XFocusChangeEvent *event );
89 static void EVENT_FocusOut( HWND32 hwnd, XFocusChangeEvent *event );
90 static void EVENT_Expose( WND *pWnd, XExposeEvent *event );
91 static void EVENT_GraphicsExpose( WND *pWnd, XGraphicsExposeEvent *event );
92 static void EVENT_ConfigureNotify( HWND32 hwnd, XConfigureEvent *event );
93 static void EVENT_SelectionRequest( WND *pWnd, XSelectionRequestEvent *event);
94 static void EVENT_SelectionNotify( XSelectionEvent *event);
95 static void EVENT_SelectionClear( WND *pWnd, XSelectionClearEvent *event);
96 static void EVENT_ClientMessage( WND *pWnd, XClientMessageEvent *event );
97 static void EVENT_MapNotify( HWND32 hwnd, XMapEvent *event );
99 /* Usable only with OLVWM - compile option perhaps?
100 static void EVENT_EnterNotify( WND *pWnd, XCrossingEvent *event );
103 extern void FOCUS_SetXFocus( HWND32 );
104 extern BOOL16 DRAG_QueryUpdate( HWND16, SEGPTR, BOOL32 );
106 /***********************************************************************
109 * Process an X event.
111 void EVENT_ProcessEvent( XEvent *event )
115 if (XFindContext( display, event->xany.window, winContext,
116 (char **)&pWnd ) != 0)
117 return; /* Not for a registered window */
119 dprintf_event( stddeb, "Got event %s for hwnd %04x\n",
120 event_names[event->type], pWnd->hwndSelf );
127 EVENT_Key( (XKeyEvent*)event );
132 EVENT_ButtonPress( (XButtonEvent*)event );
137 EVENT_ButtonRelease( (XButtonEvent*)event );
141 /* Wine between two fast machines across the overloaded campus
142 ethernet gets very boged down in MotionEvents. The following
143 simply finds the last motion event in the queue and drops
144 the rest. On a good link events are servered before they build
145 up so this doesn't take place. On a slow link this may cause
146 problems if the event order is important. I'm not yet seen
147 of any problems. Jon 7/6/96.
151 while (XCheckTypedWindowEvent(display,((XAnyEvent *)event)->window,
152 MotionNotify, event));
153 EVENT_MotionNotify( (XMotionEvent*)event );
158 EVENT_FocusIn( pWnd->hwndSelf, (XFocusChangeEvent*)event );
162 EVENT_FocusOut( pWnd->hwndSelf, (XFocusChangeEvent*)event );
166 EVENT_Expose( pWnd, (XExposeEvent *)event );
170 EVENT_GraphicsExpose( pWnd, (XGraphicsExposeEvent *)event );
173 case ConfigureNotify:
174 EVENT_ConfigureNotify( pWnd->hwndSelf, (XConfigureEvent*)event );
177 case SelectionRequest:
178 EVENT_SelectionRequest( pWnd, (XSelectionRequestEvent *)event );
181 case SelectionNotify:
182 EVENT_SelectionNotify( (XSelectionEvent *)event );
186 EVENT_SelectionClear( pWnd, (XSelectionClearEvent*) event );
190 EVENT_ClientMessage( pWnd, (XClientMessageEvent *) event );
194 * EVENT_EnterNotify( pWnd, (XCrossingEvent *) event );
200 /* We get all these because of StructureNotifyMask. */
202 case CirculateNotify:
210 EVENT_MapNotify( pWnd->hwndSelf, (XMapEvent *)event );
214 dprintf_event(stddeb, "Unprocessed event %s for hwnd %04x\n",
215 event_names[event->type], pWnd->hwndSelf );
221 /***********************************************************************
222 * EVENT_RegisterWindow
224 * Associate an X window to a HWND.
226 void EVENT_RegisterWindow( WND *pWnd )
228 if (wmProtocols == None)
229 wmProtocols = XInternAtom( display, "WM_PROTOCOLS", True );
230 if (wmDeleteWindow == None)
231 wmDeleteWindow = XInternAtom( display, "WM_DELETE_WINDOW", True );
232 if( dndProtocol == None )
233 dndProtocol = XInternAtom( display, "DndProtocol" , False );
234 if( dndSelection == None )
235 dndSelection = XInternAtom( display, "DndSelection" , False );
237 XSetWMProtocols( display, pWnd->window, &wmDeleteWindow, 1 );
239 if (!winContext) winContext = XUniqueContext();
240 XSaveContext( display, pWnd->window, winContext, (char *)pWnd );
243 /***********************************************************************
244 * EVENT_DestroyWindow
246 void EVENT_DestroyWindow( WND *pWnd )
250 XDeleteContext( display, pWnd->window, winContext );
251 XDestroyWindow( display, pWnd->window );
252 while( XCheckWindowEvent(display, pWnd->window, NoEventMask, &xe) );
255 /***********************************************************************
258 * Wait for an X event, optionally sleeping until one arrives.
259 * Return TRUE if an event is pending, FALSE on timeout or error
260 * (for instance lost connection with the server).
262 BOOL32 EVENT_WaitXEvent( BOOL32 sleep, BOOL32 peek )
265 LONG maxWait = sleep ? TIMER_GetNextExpiration() : 0;
267 /* Wait for an event or a timeout. If maxWait is -1, we have no timeout;
268 * in this case, we fall through directly to the XNextEvent loop.
271 if ((maxWait != -1) && !XPending(display))
274 struct timeval timeout;
275 int fd = ConnectionNumber(display);
277 FD_ZERO( &read_set );
278 FD_SET( fd, &read_set );
280 timeout.tv_usec = (maxWait % 1000) * 1000;
281 timeout.tv_sec = maxWait / 1000;
284 sigsetjmp(env_wait_x, 1);
287 if (DDE_GetRemoteMessage()) {
288 while(DDE_GetRemoteMessage())
292 stop_wait_op = STOP_WAIT_X;
293 /* The code up to the next "stop_wait_op = CONT" must be reentrant */
294 if (select( fd+1, &read_set, NULL, NULL, &timeout ) != 1 &&
298 TIMER_ExpireTimers();
301 else stop_wait_op = CONT;
302 #else /* CONFIG_IPC */
303 if (select( fd+1, &read_set, NULL, NULL, &timeout ) != 1)
305 /* Timeout or error */
306 TIMER_ExpireTimers();
309 #endif /* CONFIG_IPC */
313 /* Process the event (and possibly others that occurred in the meantime) */
319 if (DDE_GetRemoteMessage())
321 while(DDE_GetRemoteMessage()) ;
324 #endif /* CONFIG_IPC */
326 XNextEvent( display, &event );
333 if (XFindContext( display, ((XAnyEvent *)&event)->window, winContext,
334 (char **)&pWnd ) || (event.type == NoExpose))
337 /* Check only for those events which can be processed
340 if( event.type == MotionNotify ||
341 event.type == ButtonPress || event.type == ButtonRelease ||
342 event.type == KeyPress || event.type == KeyRelease ||
343 event.type == SelectionRequest || event.type == SelectionClear )
345 EVENT_ProcessEvent( &event );
350 if( (pQ = (MESSAGEQUEUE*)GlobalLock16(pWnd->hmemTaskQ)) )
352 pQ->flags |= QUEUE_FLAG_XEVENT;
353 PostEvent(pQ->hTask);
354 XPutBackEvent(display, &event);
359 EVENT_ProcessEvent( &event );
361 while (XPending( display ));
366 /***********************************************************************
369 * Synchronize with the X server. Should not be used too often.
371 void EVENT_Synchronize()
375 XSync( display, False );
376 while (XPending( display ))
378 XNextEvent( display, &event );
379 EVENT_ProcessEvent( &event );
384 /***********************************************************************
385 * EVENT_XStateToKeyState
387 * Translate a X event state (Button1Mask, ShiftMask, etc...) to
388 * a Windows key state (MK_SHIFT, MK_CONTROL, etc...)
390 static WORD EVENT_XStateToKeyState( int state )
394 if (state & Button1Mask) kstate |= MK_LBUTTON;
395 if (state & Button2Mask) kstate |= MK_MBUTTON;
396 if (state & Button3Mask) kstate |= MK_RBUTTON;
397 if (state & ShiftMask) kstate |= MK_SHIFT;
398 if (state & ControlMask) kstate |= MK_CONTROL;
403 /***********************************************************************
406 static void EVENT_Expose( WND *pWnd, XExposeEvent *event )
410 /* Make position relative to client area instead of window */
411 rect.left = event->x - (pWnd->rectClient.left - pWnd->rectWindow.left);
412 rect.top = event->y - (pWnd->rectClient.top - pWnd->rectWindow.top);
413 rect.right = rect.left + event->width;
414 rect.bottom = rect.top + event->height;
416 PAINT_RedrawWindow( pWnd->hwndSelf, &rect, 0,
417 RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE |
418 (event->count ? 0 : RDW_ERASENOW), 0 );
422 /***********************************************************************
423 * EVENT_GraphicsExpose
425 * This is needed when scrolling area is partially obscured
426 * by non-Wine X window.
428 static void EVENT_GraphicsExpose( WND *pWnd, XGraphicsExposeEvent *event )
432 /* Make position relative to client area instead of window */
433 rect.left = event->x - (pWnd->rectClient.left - pWnd->rectWindow.left);
434 rect.top = event->y - (pWnd->rectClient.top - pWnd->rectWindow.top);
435 rect.right = rect.left + event->width;
436 rect.bottom = rect.top + event->height;
438 PAINT_RedrawWindow( pWnd->hwndSelf, &rect, 0,
439 RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE |
440 (event->count ? 0 : RDW_ERASENOW), 0 );
444 /***********************************************************************
447 * Handle a X key event
449 static void EVENT_Key( XKeyEvent *event )
451 KEYBOARD_HandleEvent( event );
455 /***********************************************************************
458 static void EVENT_MotionNotify( XMotionEvent *event )
460 hardware_event( WM_MOUSEMOVE, EVENT_XStateToKeyState( event->state ), 0L,
461 event->x_root - desktopX, event->y_root - desktopY,
462 event->time - MSG_WineStartTicks, 0 );
466 /***********************************************************************
467 * EVENT_DummyMotionNotify
469 * Generate a dummy MotionNotify event. Used to force a WM_SETCURSOR message.
471 void EVENT_DummyMotionNotify(void)
474 int rootX, rootY, childX, childY;
477 if (XQueryPointer( display, rootWindow, &root, &child,
478 &rootX, &rootY, &childX, &childY, &state ))
480 hardware_event(WM_MOUSEMOVE, EVENT_XStateToKeyState( state ), 0L,
481 rootX - desktopX, rootY - desktopY, GetTickCount(), 0 );
486 /***********************************************************************
489 static void EVENT_ButtonPress( XButtonEvent *event )
491 static WORD messages[NB_BUTTONS] =
492 { WM_LBUTTONDOWN, WM_MBUTTONDOWN, WM_RBUTTONDOWN };
493 int buttonNum = event->button - 1;
495 if (buttonNum >= NB_BUTTONS) return;
496 if (SwappedButtons) buttonNum = NB_BUTTONS - 1 - buttonNum;
497 MouseButtonsStates[buttonNum] = 0x8000;
498 AsyncMouseButtonsStates[buttonNum] = 0x8000;
499 hardware_event( messages[buttonNum],
500 EVENT_XStateToKeyState( event->state ), 0L,
501 event->x_root - desktopX, event->y_root - desktopY,
502 event->time - MSG_WineStartTicks, 0 );
506 /***********************************************************************
507 * EVENT_ButtonRelease
509 static void EVENT_ButtonRelease( XButtonEvent *event )
511 static const WORD messages[NB_BUTTONS] =
512 { WM_LBUTTONUP, WM_MBUTTONUP, WM_RBUTTONUP };
513 int buttonNum = event->button - 1;
515 if (buttonNum >= NB_BUTTONS) return;
516 if (SwappedButtons) buttonNum = NB_BUTTONS - 1 - buttonNum;
517 MouseButtonsStates[buttonNum] = FALSE;
518 hardware_event( messages[buttonNum],
519 EVENT_XStateToKeyState( event->state ), 0L,
520 event->x_root - desktopX, event->y_root - desktopY,
521 event->time - MSG_WineStartTicks, 0 );
525 /**********************************************************************
528 static void EVENT_FocusIn( HWND32 hwnd, XFocusChangeEvent *event )
530 if (event->detail == NotifyPointer) return;
531 if (hwnd != GetActiveWindow32()) WINPOS_ChangeActiveWindow( hwnd, FALSE );
532 if ((hwnd != GetFocus32()) && !IsChild32( hwnd, GetFocus32()))
537 /**********************************************************************
540 * Note: only top-level override-redirect windows get FocusOut events.
542 static void EVENT_FocusOut( HWND32 hwnd, XFocusChangeEvent *event )
544 if (event->detail == NotifyPointer) return;
545 if (hwnd == GetActiveWindow32()) WINPOS_ChangeActiveWindow( 0, FALSE );
546 if ((hwnd == GetFocus32()) || IsChild32( hwnd, GetFocus32()))
550 /**********************************************************************
553 BOOL32 EVENT_CheckFocus(void)
559 XGetInputFocus(display, &xW, &state);
561 XFindContext(display, xW, winContext, (char **)&pWnd) )
566 /**********************************************************************
567 * EVENT_ConfigureNotify
569 * The ConfigureNotify event is only selected on the desktop window
570 * and on top-level windows when the -managed flag is used.
572 static void EVENT_ConfigureNotify( HWND32 hwnd, XConfigureEvent *event )
574 /* FIXME: with -desktop xxx we get this event _before_ desktop
575 * window structure is created. WIN_GetDesktop() check is a hack.
578 if ( !WIN_GetDesktop() || hwnd == GetDesktopWindow32())
587 RECT16 newWindowRect, newClientRect;
588 HRGN32 hrgnOldPos, hrgnNewPos;
590 if (!(wndPtr = WIN_FindWndPtr( hwnd )) ||
591 !(wndPtr->flags & WIN_MANAGED) )
594 if (!(winpos = SEGPTR_NEW(WINDOWPOS16))) return;
596 /* Fill WINDOWPOS struct */
597 winpos->flags = SWP_NOACTIVATE | SWP_NOZORDER;
599 winpos->x = event->x;
600 winpos->y = event->y;
601 winpos->cx = event->width;
602 winpos->cy = event->height;
604 /* Check for unchanged attributes */
605 if(winpos->x == wndPtr->rectWindow.left &&
606 winpos->y == wndPtr->rectWindow.top)
607 winpos->flags |= SWP_NOMOVE;
608 if(winpos->cx == wndPtr->rectWindow.right - wndPtr->rectWindow.left &&
609 winpos->cy == wndPtr->rectWindow.bottom - wndPtr->rectWindow.top)
610 winpos->flags |= SWP_NOSIZE;
612 /* Send WM_WINDOWPOSCHANGING */
613 SendMessage16(hwnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)SEGPTR_GET(winpos));
615 /* Calculate new position and size */
616 newWindowRect.left = event->x;
617 newWindowRect.right = event->x + event->width;
618 newWindowRect.top = event->y;
619 newWindowRect.bottom = event->y + event->height;
621 WINPOS_SendNCCalcSize( winpos->hwnd, TRUE, &newWindowRect,
622 &wndPtr->rectWindow, &wndPtr->rectClient,
623 SEGPTR_GET(winpos), &newClientRect );
625 hrgnOldPos = CreateRectRgnIndirect16( &wndPtr->rectWindow );
626 hrgnNewPos = CreateRectRgnIndirect16( &newWindowRect );
627 CombineRgn32( hrgnOldPos, hrgnOldPos, hrgnNewPos, RGN_DIFF );
629 /* Set new size and position */
630 wndPtr->rectWindow = newWindowRect;
631 wndPtr->rectClient = newClientRect;
632 SendMessage16( hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)SEGPTR_GET(winpos));
635 /* full window drag leaves unrepainted garbage without this */
636 PAINT_RedrawWindow( 0, NULL, hrgnOldPos, RDW_INVALIDATE |
637 RDW_ALLCHILDREN | RDW_ERASE | RDW_ERASENOW,
639 DeleteObject32(hrgnOldPos);
640 DeleteObject32(hrgnNewPos);
645 /***********************************************************************
646 * EVENT_SelectionRequest
648 static void EVENT_SelectionRequest( WND *pWnd, XSelectionRequestEvent *event )
650 XSelectionEvent result;
652 Window request = event->requestor;
654 if(event->target == XA_STRING)
660 rprop = event->property;
662 if(rprop == None) rprop = event->target;
664 if(event->selection!=XA_PRIMARY) rprop = None;
665 else if(!CLIPBOARD_IsPresent(CF_OEMTEXT)) rprop = None;
668 /* open to make sure that clipboard is available */
670 BOOL32 couldOpen = OpenClipboard32( pWnd->hwndSelf );
673 hText = GetClipboardData16(CF_TEXT);
674 text = GlobalLock16(hText);
675 size = GlobalSize16(hText);
677 /* remove carriage returns */
679 lpstr = (char*)xmalloc(size--);
680 for(i=0,j=0; i < size && text[i]; i++ )
682 if( text[i] == '\r' &&
683 (text[i+1] == '\n' || text[i+1] == '\0') ) continue;
684 lpstr[j++] = text[i];
688 XChangeProperty(display, request, rprop,
689 XA_STRING, 8, PropModeReplace,
693 /* close only if we opened before */
695 if(couldOpen) CloseClipboard32();
700 dprintf_event(stddeb,"Request for %s ignored\n", XGetAtomName(display,event->target));
702 result.type=SelectionNotify;
703 result.display=display;
704 result.requestor=request;
705 result.selection=event->selection;
706 result.property=rprop;
707 result.target=event->target;
708 result.time=event->time;
709 XSendEvent(display,event->requestor,False,NoEventMask,(XEvent*)&result);
713 /***********************************************************************
714 * EVENT_SelectionNotify
716 static void EVENT_SelectionNotify( XSelectionEvent *event )
718 if (event->selection != XA_PRIMARY) return;
720 if (event->target != XA_STRING) CLIPBOARD_ReadSelection( 0, None );
721 else CLIPBOARD_ReadSelection( event->requestor, event->property );
723 dprintf_clipboard(stddeb,"\tSelectionNotify done!\n");
727 /***********************************************************************
728 * EVENT_SelectionClear
730 static void EVENT_SelectionClear( WND *pWnd, XSelectionClearEvent *event )
732 if (event->selection != XA_PRIMARY) return;
733 CLIPBOARD_ReleaseSelection( event->window, pWnd->hwndSelf );
737 /**********************************************************************
738 * EVENT_ClientMessage
740 static void EVENT_ClientMessage( WND *pWnd, XClientMessageEvent *event )
742 if (event->message_type != None && event->format == 32)
744 if ((event->message_type == wmProtocols) &&
745 (((Atom) event->data.l[0]) == wmDeleteWindow))
746 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_CLOSE, 0 );
747 else if ( event->message_type == dndProtocol &&
748 (event->data.l[0] == DndFile || event->data.l[0] == DndFiles) )
750 unsigned long data_length;
751 unsigned long aux_long;
752 unsigned char* p_data = NULL;
760 HGLOBAL16 hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, sizeof(DRAGINFO));
761 LPDRAGINFO lpDragInfo = (LPDRAGINFO) GlobalLock16(hDragInfo);
762 SEGPTR spDragInfo = (SEGPTR) WIN16_GlobalLock16(hDragInfo);
763 Window w_aux_root, w_aux_child;
766 if( !lpDragInfo || !spDragInfo ) return;
768 XQueryPointer( display, pWnd->window, &w_aux_root, &w_aux_child,
769 &x, &y, &u.pt_aux.x, &u.pt_aux.y, (unsigned int*)&aux_long);
771 lpDragInfo->hScope = pWnd->hwndSelf;
772 lpDragInfo->pt.x = (INT16)x; lpDragInfo->pt.y = (INT16)y;
774 /* find out drop point and drop window */
775 if( x < 0 || y < 0 ||
776 x > (pWnd->rectWindow.right - pWnd->rectWindow.left) ||
777 y > (pWnd->rectWindow.bottom - pWnd->rectWindow.top) )
778 { bAccept = pWnd->dwExStyle & WS_EX_ACCEPTFILES; x = y = 0; }
781 bAccept = DRAG_QueryUpdate( pWnd->hwndSelf, spDragInfo, TRUE );
782 x = lpDragInfo->pt.x; y = lpDragInfo->pt.y;
784 pDropWnd = WIN_FindWndPtr( lpDragInfo->hScope );
785 GlobalFree16( hDragInfo );
789 XGetWindowProperty( display, DefaultRootWindow(display),
790 dndSelection, 0, 65535, FALSE,
791 AnyPropertyType, &u.atom_aux, &u.pt_aux.y,
792 &data_length, &aux_long, &p_data);
794 if( !aux_long && p_data) /* don't bother if > 64K */
796 char *p = (char*) p_data;
800 while( *p ) /* calculate buffer size */
803 if((u.i = *p) != -1 )
804 u.i = DRIVE_FindDriveRoot( (const char **)&p_drop );
805 if( u.i == -1 ) *p = -1; /* mark as "bad" */
808 INT32 len = GetShortPathName32A( p, NULL, 0 );
809 if (len) aux_long += len + 1;
814 if( aux_long && aux_long < 65535 )
817 LPDROPFILESTRUCT lpDrop;
819 aux_long += sizeof(DROPFILESTRUCT) + 1;
820 hDrop = (HDROP16)GlobalAlloc16( GMEM_SHARE, aux_long );
821 lpDrop = (LPDROPFILESTRUCT) GlobalLock16( hDrop );
825 lpDrop->wSize = sizeof(DROPFILESTRUCT);
826 lpDrop->ptMousePos.x = (INT16)x;
827 lpDrop->ptMousePos.y = (INT16)y;
828 lpDrop->fInNonClientArea = (BOOL16)
829 ( x < (pDropWnd->rectClient.left - pDropWnd->rectWindow.left) ||
830 y < (pDropWnd->rectClient.top - pDropWnd->rectWindow.top) ||
831 x > (pDropWnd->rectClient.right - pDropWnd->rectWindow.left) ||
832 y > (pDropWnd->rectClient.bottom - pDropWnd->rectWindow.top) );
833 p_drop = ((char*)lpDrop) + sizeof(DROPFILESTRUCT);
837 if( *p != -1 ) /* use only "good" entries */
839 GetShortPathName32A( p, p_drop, 65535 );
840 p_drop += strlen( p_drop ) + 1;
845 PostMessage16( pWnd->hwndSelf, WM_DROPFILES,
846 (WPARAM16)hDrop, 0L );
850 if( p_data ) XFree(p_data);
852 } /* WS_EX_ACCEPTFILES */
855 dprintf_event( stddeb, "unrecognized ClientMessage\n" );
859 /**********************************************************************
862 * Install colormap when Wine window is focused in
863 * self-managed mode with private colormap
866 void EVENT_EnterNotify( WND *pWnd, XCrossingEvent *event )
868 if( !Options.managed && rootWindow == DefaultRootWindow(display) &&
869 (COLOR_GetSystemPaletteFlags() & COLOR_PRIVATE) && GetFocus32() )
870 XInstallColormap( display, COLOR_GetColormap() );
874 /**********************************************************************
877 void EVENT_MapNotify( HWND32 hWnd, XMapEvent *event )
879 HWND32 hwndFocus = GetFocus32();
881 if (hwndFocus && IsChild32( hWnd, hwndFocus ))
882 FOCUS_SetXFocus( (HWND32)hwndFocus );
887 /**********************************************************************
890 * We need this to be able to generate double click messages
891 * when menu code captures mouse in the window without CS_DBLCLK style.
893 HWND32 EVENT_Capture(HWND32 hwnd, INT16 ht)
896 HWND32 capturePrev = captureWnd;
900 XUngrabPointer(display, CurrentTime );
901 captureWnd = NULL; captureHT = 0;
903 else if ((win = WIN_GetXWindow( hwnd )))
905 WND* wndPtr = WIN_FindWndPtr( hwnd );
908 (XGrabPointer(display, win, False,
909 ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
910 GrabModeAsync, GrabModeAsync,
911 None, None, CurrentTime ) == GrabSuccess) )
913 dprintf_win(stddeb, "SetCapture(0x%04x)\n", hwnd );
919 if( capturePrev && capturePrev != captureWnd )
921 WND* wndPtr = WIN_FindWndPtr( capturePrev );
922 if( wndPtr && (wndPtr->flags & WIN_ISWIN32) )
923 SendMessage32A( capturePrev, WM_CAPTURECHANGED, 0L, hwnd);
928 /**********************************************************************
929 * EVENT_GetCaptureInfo
931 INT16 EVENT_GetCaptureInfo()
936 /**********************************************************************
937 * SetCapture16 (USER.18)
939 HWND16 SetCapture16( HWND16 hwnd )
941 return (HWND16)EVENT_Capture( hwnd, HTCLIENT );
945 /**********************************************************************
946 * SetCapture32 (USER32.463)
948 HWND32 SetCapture32( HWND32 hwnd )
950 return EVENT_Capture( hwnd, HTCLIENT );
954 /**********************************************************************
955 * ReleaseCapture (USER.19) (USER32.438)
957 void ReleaseCapture(void)
959 dprintf_win(stddeb, "ReleaseCapture() [%04x]\n", captureWnd );
960 if( captureWnd ) EVENT_Capture( 0, 0 );
964 /**********************************************************************
965 * GetCapture16 (USER.236)
967 HWND16 GetCapture16(void)
973 /**********************************************************************
974 * GetCapture32 (USER32.207)
976 HWND32 GetCapture32(void)
982 /***********************************************************************
983 * GetMouseEventProc (USER.337)
985 FARPROC16 GetMouseEventProc(void)
987 HMODULE16 hmodule = GetModuleHandle16("USER");
988 return MODULE_GetEntryPoint( hmodule,
989 MODULE_GetOrdinal( hmodule, "Mouse_Event" ) );
993 /***********************************************************************
994 * Mouse_Event (USER.299)
996 void Mouse_Event( CONTEXT *context )
1000 * BX = horizontal displacement if AX & ME_MOVE
1001 * CX = vertical displacement if AX & ME_MOVE
1002 * DX = button state (?)
1003 * SI = mouse event flags (?)
1006 int rootX, rootY, childX, childY;
1009 if (AX_reg(context) & ME_MOVE)
1011 /* We have to actually move the cursor */
1012 XWarpPointer( display, rootWindow, None, 0, 0, 0, 0,
1013 (short)BX_reg(context), (short)CX_reg(context) );
1016 if (!XQueryPointer( display, rootWindow, &root, &child,
1017 &rootX, &rootY, &childX, &childY, &state )) return;
1018 if (AX_reg(context) & ME_LDOWN)
1019 hardware_event( WM_LBUTTONDOWN, EVENT_XStateToKeyState( state ), 0L,
1020 rootX - desktopX, rootY - desktopY, GetTickCount(), 0);
1021 if (AX_reg(context) & ME_LUP)
1022 hardware_event( WM_LBUTTONUP, EVENT_XStateToKeyState( state ), 0L,
1023 rootX - desktopX, rootY - desktopY, GetTickCount(), 0);
1024 if (AX_reg(context) & ME_RDOWN)
1025 hardware_event( WM_RBUTTONDOWN, EVENT_XStateToKeyState( state ), 0L,
1026 rootX - desktopX, rootY - desktopY, GetTickCount(), 0);
1027 if (AX_reg(context) & ME_RUP)
1028 hardware_event( WM_RBUTTONUP, EVENT_XStateToKeyState( state ), 0L,
1029 rootX - desktopX, rootY - desktopY, GetTickCount(), 0);
1033 /**********************************************************************
1034 * EnableHardwareInput (USER.331)
1036 BOOL16 EnableHardwareInput(BOOL16 bEnable)
1038 BOOL16 bOldState = InputEnabled;
1039 dprintf_event(stdnimp,"EnableHardwareInput(%d);\n", bEnable);
1040 InputEnabled = bEnable;
1045 /***********************************************************************
1046 * SwapMouseButton16 (USER.186)
1048 BOOL16 SwapMouseButton16( BOOL16 fSwap )
1050 BOOL16 ret = SwappedButtons;
1051 SwappedButtons = fSwap;
1056 /***********************************************************************
1057 * SwapMouseButton32 (USER32.536)
1059 BOOL32 SwapMouseButton32( BOOL32 fSwap )
1061 BOOL32 ret = SwappedButtons;
1062 SwappedButtons = fSwap;