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;
65 static Atom wmProtocols = None;
66 static Atom wmDeleteWindow = None;
67 static Atom dndProtocol = None;
68 static Atom dndSelection = None;
70 static const char * const event_names[] =
72 "", "", "KeyPress", "KeyRelease", "ButtonPress", "ButtonRelease",
73 "MotionNotify", "EnterNotify", "LeaveNotify", "FocusIn", "FocusOut",
74 "KeymapNotify", "Expose", "GraphicsExpose", "NoExpose", "VisibilityNotify",
75 "CreateNotify", "DestroyNotify", "UnmapNotify", "MapNotify", "MapRequest",
76 "ReparentNotify", "ConfigureNotify", "ConfigureRequest", "GravityNotify",
77 "ResizeRequest", "CirculateNotify", "CirculateRequest", "PropertyNotify",
78 "SelectionClear", "SelectionRequest", "SelectionNotify", "ColormapNotify",
79 "ClientMessage", "MappingNotify"
83 static void EVENT_Key( XKeyEvent *event );
84 static void EVENT_ButtonPress( XButtonEvent *event );
85 static void EVENT_ButtonRelease( XButtonEvent *event );
86 static void EVENT_MotionNotify( XMotionEvent *event );
87 static void EVENT_FocusIn( HWND hwnd, XFocusChangeEvent *event );
88 static void EVENT_FocusOut( HWND hwnd, XFocusChangeEvent *event );
89 static void EVENT_Expose( WND *pWnd, XExposeEvent *event );
90 static void EVENT_GraphicsExpose( WND *pWnd, XGraphicsExposeEvent *event );
91 static void EVENT_ConfigureNotify( HWND hwnd, XConfigureEvent *event );
92 static void EVENT_SelectionRequest( WND *pWnd, XSelectionRequestEvent *event);
93 static void EVENT_SelectionNotify( XSelectionEvent *event);
94 static void EVENT_SelectionClear( WND *pWnd, XSelectionClearEvent *event);
95 static void EVENT_ClientMessage( WND *pWnd, XClientMessageEvent *event );
96 static void EVENT_MapNotify( HWND hwnd, XMapEvent *event );
98 /* Usable only with OLVWM - compile option perhaps?
99 static void EVENT_EnterNotify( WND *pWnd, XCrossingEvent *event );
102 extern void FOCUS_SetXFocus( HWND32 );
103 extern BOOL16 DRAG_QueryUpdate( HWND, SEGPTR, BOOL32 );
105 /***********************************************************************
108 * Process an X event.
110 void EVENT_ProcessEvent( XEvent *event )
114 if (XFindContext( display, event->xany.window, winContext,
115 (char **)&pWnd ) != 0)
116 return; /* Not for a registered window */
118 dprintf_event( stddeb, "Got event %s for hwnd %04x\n",
119 event_names[event->type], pWnd->hwndSelf );
126 EVENT_Key( (XKeyEvent*)event );
131 EVENT_ButtonPress( (XButtonEvent*)event );
136 EVENT_ButtonRelease( (XButtonEvent*)event );
140 /* Wine between two fast machines across the overloaded campus
141 ethernet gets very boged down in MotionEvents. The following
142 simply finds the last motion event in the queue and drops
143 the rest. On a good link events are servered before they build
144 up so this doesn't take place. On a slow link this may cause
145 problems if the event order is important. I'm not yet seen
146 of any problems. Jon 7/6/96.
150 while (XCheckTypedWindowEvent(display,((XAnyEvent *)event)->window,
151 MotionNotify, event));
152 EVENT_MotionNotify( (XMotionEvent*)event );
157 EVENT_FocusIn( pWnd->hwndSelf, (XFocusChangeEvent*)event );
161 EVENT_FocusOut( pWnd->hwndSelf, (XFocusChangeEvent*)event );
165 EVENT_Expose( pWnd, (XExposeEvent *)event );
169 EVENT_GraphicsExpose( pWnd, (XGraphicsExposeEvent *)event );
172 case ConfigureNotify:
173 EVENT_ConfigureNotify( pWnd->hwndSelf, (XConfigureEvent*)event );
176 case SelectionRequest:
177 EVENT_SelectionRequest( pWnd, (XSelectionRequestEvent *)event );
180 case SelectionNotify:
181 EVENT_SelectionNotify( (XSelectionEvent *)event );
185 EVENT_SelectionClear( pWnd, (XSelectionClearEvent*) event );
189 EVENT_ClientMessage( pWnd, (XClientMessageEvent *) event );
193 * EVENT_EnterNotify( pWnd, (XCrossingEvent *) event );
199 /* We get all these because of StructureNotifyMask. */
201 case CirculateNotify:
209 EVENT_MapNotify( pWnd->hwndSelf, (XMapEvent *)event );
213 dprintf_event(stddeb, "Unprocessed event %s for hwnd %04x\n",
214 event_names[event->type], pWnd->hwndSelf );
220 /***********************************************************************
221 * EVENT_RegisterWindow
223 * Associate an X window to a HWND.
225 void EVENT_RegisterWindow( WND *pWnd )
227 if (wmProtocols == None)
228 wmProtocols = XInternAtom( display, "WM_PROTOCOLS", True );
229 if (wmDeleteWindow == None)
230 wmDeleteWindow = XInternAtom( display, "WM_DELETE_WINDOW", True );
231 if( dndProtocol == None )
232 dndProtocol = XInternAtom( display, "DndProtocol" , False );
233 if( dndSelection == None )
234 dndSelection = XInternAtom( display, "DndSelection" , False );
236 XSetWMProtocols( display, pWnd->window, &wmDeleteWindow, 1 );
238 if (!winContext) winContext = XUniqueContext();
239 XSaveContext( display, pWnd->window, winContext, (char *)pWnd );
242 /***********************************************************************
243 * EVENT_DestroyWindow
245 void EVENT_DestroyWindow( WND *pWnd )
249 XDeleteContext( display, pWnd->window, winContext );
250 XDestroyWindow( display, pWnd->window );
251 while( XCheckWindowEvent(display, pWnd->window, NoEventMask, &xe) );
254 /***********************************************************************
257 * Wait for an X event, optionally sleeping until one arrives.
258 * Return TRUE if an event is pending, FALSE on timeout or error
259 * (for instance lost connection with the server).
261 BOOL32 EVENT_WaitXEvent( BOOL32 sleep, BOOL32 peek )
264 LONG maxWait = sleep ? TIMER_GetNextExpiration() : 0;
266 /* Wait for an event or a timeout. If maxWait is -1, we have no timeout;
267 * in this case, we fall through directly to the XNextEvent loop.
270 if ((maxWait != -1) && !XPending(display))
273 struct timeval timeout;
274 int fd = ConnectionNumber(display);
276 FD_ZERO( &read_set );
277 FD_SET( fd, &read_set );
279 timeout.tv_usec = (maxWait % 1000) * 1000;
280 timeout.tv_sec = maxWait / 1000;
283 sigsetjmp(env_wait_x, 1);
286 if (DDE_GetRemoteMessage()) {
287 while(DDE_GetRemoteMessage())
291 stop_wait_op = STOP_WAIT_X;
292 /* The code up to the next "stop_wait_op = CONT" must be reentrant */
293 if (select( fd+1, &read_set, NULL, NULL, &timeout ) != 1 &&
297 TIMER_ExpireTimers();
300 else stop_wait_op = CONT;
301 #else /* CONFIG_IPC */
302 if (select( fd+1, &read_set, NULL, NULL, &timeout ) != 1)
304 /* Timeout or error */
305 TIMER_ExpireTimers();
308 #endif /* CONFIG_IPC */
312 /* Process the event (and possibly others that occurred in the meantime) */
318 if (DDE_GetRemoteMessage())
320 while(DDE_GetRemoteMessage()) ;
323 #endif /* CONFIG_IPC */
325 XNextEvent( display, &event );
332 if (XFindContext( display, ((XAnyEvent *)&event)->window, winContext,
333 (char **)&pWnd ) || (event.type == NoExpose))
336 /* check for the "safe" hardware events */
338 if( event.type == MotionNotify ||
339 event.type == ButtonPress || event.type == ButtonRelease ||
340 event.type == KeyPress || event.type == KeyRelease ||
341 event.type == SelectionRequest || event.type == SelectionClear )
343 EVENT_ProcessEvent( &event );
348 if( (pQ = (MESSAGEQUEUE*)GlobalLock16(pWnd->hmemTaskQ)) )
350 pQ->flags |= QUEUE_FLAG_XEVENT;
351 PostEvent(pQ->hTask);
352 XPutBackEvent(display, &event);
357 EVENT_ProcessEvent( &event );
359 while (XPending( display ));
364 /***********************************************************************
367 * Synchronize with the X server. Should not be used too often.
369 void EVENT_Synchronize()
373 XSync( display, False );
374 while (XPending( display ))
376 XNextEvent( display, &event );
377 EVENT_ProcessEvent( &event );
382 /***********************************************************************
383 * EVENT_XStateToKeyState
385 * Translate a X event state (Button1Mask, ShiftMask, etc...) to
386 * a Windows key state (MK_SHIFT, MK_CONTROL, etc...)
388 static WORD EVENT_XStateToKeyState( int state )
392 if (state & Button1Mask) kstate |= MK_LBUTTON;
393 if (state & Button2Mask) kstate |= MK_MBUTTON;
394 if (state & Button3Mask) kstate |= MK_RBUTTON;
395 if (state & ShiftMask) kstate |= MK_SHIFT;
396 if (state & ControlMask) kstate |= MK_CONTROL;
401 /***********************************************************************
404 static void EVENT_Expose( WND *pWnd, XExposeEvent *event )
408 /* Make position relative to client area instead of window */
409 rect.left = event->x - (pWnd->rectClient.left - pWnd->rectWindow.left);
410 rect.top = event->y - (pWnd->rectClient.top - pWnd->rectWindow.top);
411 rect.right = rect.left + event->width;
412 rect.bottom = rect.top + event->height;
414 PAINT_RedrawWindow( pWnd->hwndSelf, &rect, 0,
415 RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE |
416 (event->count ? 0 : RDW_ERASENOW), 0 );
420 /***********************************************************************
421 * EVENT_GraphicsExpose
423 * This is needed when scrolling area is partially obscured
424 * by non-Wine X window.
426 static void EVENT_GraphicsExpose( WND *pWnd, XGraphicsExposeEvent *event )
430 /* Make position relative to client area instead of window */
431 rect.left = event->x - (pWnd->rectClient.left - pWnd->rectWindow.left);
432 rect.top = event->y - (pWnd->rectClient.top - pWnd->rectWindow.top);
433 rect.right = rect.left + event->width;
434 rect.bottom = rect.top + event->height;
436 PAINT_RedrawWindow( pWnd->hwndSelf, &rect, 0,
437 RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE |
438 (event->count ? 0 : RDW_ERASENOW), 0 );
442 /***********************************************************************
445 * Handle a X key event
447 static void EVENT_Key( XKeyEvent *event )
449 KEYBOARD_HandleEvent( event );
453 /***********************************************************************
456 static void EVENT_MotionNotify( XMotionEvent *event )
458 hardware_event( WM_MOUSEMOVE, EVENT_XStateToKeyState( event->state ), 0L,
459 event->x_root - desktopX, event->y_root - desktopY,
460 event->time - MSG_WineStartTicks, 0 );
464 /***********************************************************************
465 * EVENT_DummyMotionNotify
467 * Generate a dummy MotionNotify event. Used to force a WM_SETCURSOR message.
469 void EVENT_DummyMotionNotify(void)
472 int rootX, rootY, childX, childY;
475 if (XQueryPointer( display, rootWindow, &root, &child,
476 &rootX, &rootY, &childX, &childY, &state ))
478 hardware_event(WM_MOUSEMOVE, EVENT_XStateToKeyState( state ), 0L,
479 rootX - desktopX, rootY - desktopY, GetTickCount(), 0 );
484 /***********************************************************************
487 static void EVENT_ButtonPress( XButtonEvent *event )
489 static WORD messages[NB_BUTTONS] =
490 { WM_LBUTTONDOWN, WM_MBUTTONDOWN, WM_RBUTTONDOWN };
491 int buttonNum = event->button - 1;
493 if (buttonNum >= NB_BUTTONS) return;
494 MouseButtonsStates[buttonNum] = 0x8000;
495 AsyncMouseButtonsStates[buttonNum] = 0x8000;
496 hardware_event( messages[buttonNum],
497 EVENT_XStateToKeyState( event->state ), 0L,
498 event->x_root - desktopX, event->y_root - desktopY,
499 event->time - MSG_WineStartTicks, 0 );
503 /***********************************************************************
504 * EVENT_ButtonRelease
506 static void EVENT_ButtonRelease( XButtonEvent *event )
508 static const WORD messages[NB_BUTTONS] =
509 { WM_LBUTTONUP, WM_MBUTTONUP, WM_RBUTTONUP };
510 int buttonNum = event->button - 1;
512 if (buttonNum >= NB_BUTTONS) return;
513 MouseButtonsStates[buttonNum] = FALSE;
514 hardware_event( messages[buttonNum],
515 EVENT_XStateToKeyState( event->state ), 0L,
516 event->x_root - desktopX, event->y_root - desktopY,
517 event->time - MSG_WineStartTicks, 0 );
521 /**********************************************************************
524 static void EVENT_FocusIn (HWND hwnd, XFocusChangeEvent *event )
526 if (event->detail == NotifyPointer) return;
527 if (hwnd != GetActiveWindow32()) WINPOS_ChangeActiveWindow( hwnd, FALSE );
528 if ((hwnd != GetFocus32()) && !IsChild32( hwnd, GetFocus32()))
533 /**********************************************************************
536 * Note: only top-level override-redirect windows get FocusOut events.
538 static void EVENT_FocusOut( HWND hwnd, XFocusChangeEvent *event )
540 if (event->detail == NotifyPointer) return;
541 if (hwnd == GetActiveWindow32()) WINPOS_ChangeActiveWindow( 0, FALSE );
542 if ((hwnd == GetFocus32()) || IsChild32( hwnd, GetFocus32()))
547 /**********************************************************************
548 * EVENT_ConfigureNotify
550 * The ConfigureNotify event is only selected on the desktop window
551 * and on top-level windows when the -managed flag is used.
553 static void EVENT_ConfigureNotify( HWND hwnd, XConfigureEvent *event )
555 /* FIXME: with -desktop xxx we get this event _before_ desktop
556 * window structure is created. WIN_GetDesktop() check is a hack.
559 if ( !WIN_GetDesktop() || hwnd == GetDesktopWindow32())
568 RECT16 newWindowRect, newClientRect;
569 HRGN32 hrgnOldPos, hrgnNewPos;
571 if (!(wndPtr = WIN_FindWndPtr( hwnd )) ||
572 !(wndPtr->flags & WIN_MANAGED) )
575 if (!(winpos = SEGPTR_NEW(WINDOWPOS16))) return;
577 /* XTranslateCoordinates(display, event->window, rootWindow,
578 event->x, event->y, &event->x, &event->y, &child);
581 /* Fill WINDOWPOS struct */
582 winpos->flags = SWP_NOACTIVATE | SWP_NOZORDER;
584 winpos->x = event->x;
585 winpos->y = event->y;
586 winpos->cx = event->width;
587 winpos->cy = event->height;
589 /* Check for unchanged attributes */
590 if(winpos->x == wndPtr->rectWindow.left &&
591 winpos->y == wndPtr->rectWindow.top)
592 winpos->flags |= SWP_NOMOVE;
593 if(winpos->cx == wndPtr->rectWindow.right - wndPtr->rectWindow.left &&
594 winpos->cy == wndPtr->rectWindow.bottom - wndPtr->rectWindow.top)
595 winpos->flags |= SWP_NOSIZE;
597 /* Send WM_WINDOWPOSCHANGING */
598 SendMessage16(hwnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)SEGPTR_GET(winpos));
600 /* Calculate new position and size */
601 newWindowRect.left = event->x;
602 newWindowRect.right = event->x + event->width;
603 newWindowRect.top = event->y;
604 newWindowRect.bottom = event->y + event->height;
606 WINPOS_SendNCCalcSize( winpos->hwnd, TRUE, &newWindowRect,
607 &wndPtr->rectWindow, &wndPtr->rectClient,
608 SEGPTR_GET(winpos), &newClientRect );
610 hrgnOldPos = CreateRectRgnIndirect16( &wndPtr->rectWindow );
611 hrgnNewPos = CreateRectRgnIndirect16( &newWindowRect );
612 CombineRgn32( hrgnOldPos, hrgnOldPos, hrgnNewPos, RGN_DIFF );
614 /* Set new size and position */
615 wndPtr->rectWindow = newWindowRect;
616 wndPtr->rectClient = newClientRect;
617 SendMessage16( hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)SEGPTR_GET(winpos));
620 /* full window drag leaves unrepainted garbage without this */
621 PAINT_RedrawWindow( 0, NULL, hrgnOldPos, RDW_INVALIDATE |
622 RDW_ALLCHILDREN | RDW_ERASE | RDW_ERASENOW,
624 DeleteObject32(hrgnOldPos);
625 DeleteObject32(hrgnNewPos);
630 /***********************************************************************
631 * EVENT_SelectionRequest
633 static void EVENT_SelectionRequest( WND *pWnd, XSelectionRequestEvent *event )
635 XSelectionEvent result;
637 Window request = event->requestor;
639 if(event->target == XA_STRING)
645 rprop = event->property;
647 if(rprop == None) rprop = event->target;
649 if(event->selection!=XA_PRIMARY) rprop = None;
650 else if(!CLIPBOARD_IsPresent(CF_OEMTEXT)) rprop = None;
653 /* open to make sure that clipboard is available */
655 BOOL couldOpen = OpenClipboard( pWnd->hwndSelf );
658 hText = GetClipboardData(CF_TEXT);
659 text = GlobalLock16(hText);
660 size = GlobalSize16(hText);
662 /* remove carriage returns */
664 lpstr = (char*)xmalloc(size--);
665 for(i=0,j=0; i < size && text[i]; i++ )
667 if( text[i] == '\r' &&
668 (text[i+1] == '\n' || text[i+1] == '\0') ) continue;
669 lpstr[j++] = text[i];
673 XChangeProperty(display, request, rprop,
674 XA_STRING, 8, PropModeReplace,
678 /* close only if we opened before */
680 if(couldOpen) CloseClipboard();
685 dprintf_event(stddeb,"Request for %s ignored\n", XGetAtomName(display,event->target));
687 result.type=SelectionNotify;
688 result.display=display;
689 result.requestor=request;
690 result.selection=event->selection;
691 result.property=rprop;
692 result.target=event->target;
693 result.time=event->time;
694 XSendEvent(display,event->requestor,False,NoEventMask,(XEvent*)&result);
698 /***********************************************************************
699 * EVENT_SelectionNotify
701 static void EVENT_SelectionNotify( XSelectionEvent *event )
703 if (event->selection != XA_PRIMARY) return;
705 if (event->target != XA_STRING) CLIPBOARD_ReadSelection( 0, None );
706 else CLIPBOARD_ReadSelection( event->requestor, event->property );
708 dprintf_clipboard(stddeb,"\tSelectionNotify done!\n");
712 /***********************************************************************
713 * EVENT_SelectionClear
715 static void EVENT_SelectionClear( WND *pWnd, XSelectionClearEvent *event )
717 if (event->selection != XA_PRIMARY) return;
718 CLIPBOARD_ReleaseSelection( event->window, pWnd->hwndSelf );
722 /**********************************************************************
723 * EVENT_ClientMessage
725 static void EVENT_ClientMessage( WND *pWnd, XClientMessageEvent *event )
727 if (event->message_type != None && event->format == 32)
729 if ((event->message_type == wmProtocols) &&
730 (((Atom) event->data.l[0]) == wmDeleteWindow))
731 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_CLOSE, 0 );
732 else if ( event->message_type == dndProtocol &&
733 (event->data.l[0] == DndFile || event->data.l[0] == DndFiles) )
735 unsigned long data_length;
736 unsigned long aux_long;
737 unsigned char* p_data = NULL;
745 HGLOBAL16 hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, sizeof(DRAGINFO));
746 LPDRAGINFO lpDragInfo = (LPDRAGINFO) GlobalLock16(hDragInfo);
747 SEGPTR spDragInfo = (SEGPTR) WIN16_GlobalLock16(hDragInfo);
748 Window w_aux_root, w_aux_child;
751 if( !lpDragInfo || !spDragInfo ) return;
753 XQueryPointer( display, pWnd->window, &w_aux_root, &w_aux_child,
754 &x, &y, &u.pt_aux.x, &u.pt_aux.y, (unsigned int*)&aux_long);
756 lpDragInfo->hScope = pWnd->hwndSelf;
757 lpDragInfo->pt.x = (INT16)x; lpDragInfo->pt.y = (INT16)y;
759 /* find out drop point and drop window */
760 if( x < 0 || y < 0 ||
761 x > (pWnd->rectWindow.right - pWnd->rectWindow.left) ||
762 y > (pWnd->rectWindow.bottom - pWnd->rectWindow.top) )
763 { bAccept = pWnd->dwExStyle & WS_EX_ACCEPTFILES; x = y = 0; }
766 bAccept = DRAG_QueryUpdate( pWnd->hwndSelf, spDragInfo, TRUE );
767 x = lpDragInfo->pt.x; y = lpDragInfo->pt.y;
769 pDropWnd = WIN_FindWndPtr( lpDragInfo->hScope );
770 GlobalFree16( hDragInfo );
774 XGetWindowProperty( display, DefaultRootWindow(display),
775 dndSelection, 0, 65535, FALSE,
776 AnyPropertyType, &u.atom_aux, &u.pt_aux.y,
777 &data_length, &aux_long, &p_data);
779 if( !aux_long && p_data) /* don't bother if > 64K */
781 char *p = (char*) p_data;
785 while( *p ) /* calculate buffer size */
788 if((u.i = *p) != -1 )
789 u.i = DRIVE_FindDriveRoot( (const char **)&p_drop );
790 if( u.i == -1 ) *p = -1; /* mark as "bad" */
793 INT32 len = GetShortPathName32A( p, NULL, 0 );
794 if (len) aux_long += len + 1;
799 if( aux_long && aux_long < 65535 )
802 LPDROPFILESTRUCT lpDrop;
804 aux_long += sizeof(DROPFILESTRUCT) + 1;
805 hDrop = (HDROP16)GlobalAlloc16( GMEM_SHARE, aux_long );
806 lpDrop = (LPDROPFILESTRUCT) GlobalLock16( hDrop );
810 lpDrop->wSize = sizeof(DROPFILESTRUCT);
811 lpDrop->ptMousePos.x = (INT16)x;
812 lpDrop->ptMousePos.y = (INT16)y;
813 lpDrop->fInNonClientArea = (BOOL16)
814 ( x < (pDropWnd->rectClient.left - pDropWnd->rectWindow.left) ||
815 y < (pDropWnd->rectClient.top - pDropWnd->rectWindow.top) ||
816 x > (pDropWnd->rectClient.right - pDropWnd->rectWindow.left) ||
817 y > (pDropWnd->rectClient.bottom - pDropWnd->rectWindow.top) );
818 p_drop = ((char*)lpDrop) + sizeof(DROPFILESTRUCT);
822 if( *p != -1 ) /* use only "good" entries */
824 GetShortPathName32A( p, p_drop, 65535 );
825 p_drop += strlen( p_drop ) + 1;
830 PostMessage( pWnd->hwndSelf, WM_DROPFILES, (WPARAM16)hDrop, 0L );
834 if( p_data ) XFree(p_data);
836 } /* WS_EX_ACCEPTFILES */
839 dprintf_event( stddeb, "unrecognized ClientMessage\n" );
843 /**********************************************************************
846 * Install colormap when Wine window is focused in
847 * self-managed mode with private colormap
850 void EVENT_EnterNotify( WND *pWnd, XCrossingEvent *event )
852 if( !Options.managed && rootWindow == DefaultRootWindow(display) &&
853 (COLOR_GetSystemPaletteFlags() & COLOR_PRIVATE) && GetFocus32() )
854 XInstallColormap( display, COLOR_GetColormap() );
858 /**********************************************************************
861 void EVENT_MapNotify( HWND hWnd, XMapEvent *event )
863 HWND32 hwndFocus = GetFocus32();
865 if (hwndFocus && IsChild32( hWnd, hwndFocus ))
866 FOCUS_SetXFocus( (HWND32)hwndFocus );
871 /**********************************************************************
874 * We need this to be able to generate double click messages
875 * when menu code captures mouse in the window without CS_DBLCLK style.
877 HWND32 EVENT_Capture(HWND32 hwnd, INT16 ht)
880 HWND32 old_capture_wnd = captureWnd;
885 return old_capture_wnd;
887 if ((win = WIN_GetXWindow( hwnd )))
889 if (XGrabPointer(display, win, False,
890 ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
891 GrabModeAsync, GrabModeAsync,
892 None, None, CurrentTime ) == GrabSuccess)
894 dprintf_win(stddeb, "SetCapture: %04x\n", hwnd);
897 return old_capture_wnd;
903 /**********************************************************************
904 * EVENT_GetCaptureInfo
906 INT16 EVENT_GetCaptureInfo()
911 /**********************************************************************
912 * SetCapture16 (USER.18)
914 HWND16 SetCapture16( HWND16 hwnd )
916 return (HWND16)EVENT_Capture( hwnd, HTCLIENT );
920 /**********************************************************************
921 * SetCapture32 (USER32.463)
923 HWND32 SetCapture32( HWND32 hwnd )
925 return EVENT_Capture( hwnd, HTCLIENT );
929 /**********************************************************************
930 * ReleaseCapture (USER.19) (USER32.438)
932 void ReleaseCapture(void)
934 if (captureWnd == 0) return;
935 XUngrabPointer( display, CurrentTime );
937 dprintf_win(stddeb, "ReleaseCapture\n");
941 /**********************************************************************
942 * GetCapture16 (USER.236)
944 HWND16 GetCapture16(void)
946 return (HWND16)captureWnd;
950 /**********************************************************************
951 * GetCapture32 (USER32.207)
953 HWND32 GetCapture32(void)
959 /***********************************************************************
960 * GetMouseEventProc (USER.337)
962 FARPROC16 GetMouseEventProc(void)
964 HMODULE16 hmodule = GetModuleHandle("USER");
965 return MODULE_GetEntryPoint( hmodule,
966 MODULE_GetOrdinal( hmodule, "Mouse_Event" ) );
970 /***********************************************************************
971 * Mouse_Event (USER.299)
973 void Mouse_Event( CONTEXT *context )
977 * BX = horizontal displacement if AX & ME_MOVE
978 * CX = vertical displacement if AX & ME_MOVE
979 * DX = button state (?)
980 * SI = mouse event flags (?)
983 int rootX, rootY, childX, childY;
986 if (AX_reg(context) & ME_MOVE)
988 /* We have to actually move the cursor */
989 XWarpPointer( display, rootWindow, None, 0, 0, 0, 0,
990 (short)BX_reg(context), (short)CX_reg(context) );
993 if (!XQueryPointer( display, rootWindow, &root, &child,
994 &rootX, &rootY, &childX, &childY, &state )) return;
995 if (AX_reg(context) & ME_LDOWN)
996 hardware_event( WM_LBUTTONDOWN, EVENT_XStateToKeyState( state ), 0L,
997 rootX - desktopX, rootY - desktopY, GetTickCount(), 0);
998 if (AX_reg(context) & ME_LUP)
999 hardware_event( WM_LBUTTONUP, EVENT_XStateToKeyState( state ), 0L,
1000 rootX - desktopX, rootY - desktopY, GetTickCount(), 0);
1001 if (AX_reg(context) & ME_RDOWN)
1002 hardware_event( WM_RBUTTONDOWN, EVENT_XStateToKeyState( state ), 0L,
1003 rootX - desktopX, rootY - desktopY, GetTickCount(), 0);
1004 if (AX_reg(context) & ME_RUP)
1005 hardware_event( WM_RBUTTONUP, EVENT_XStateToKeyState( state ), 0L,
1006 rootX - desktopX, rootY - desktopY, GetTickCount(), 0);
1010 /**********************************************************************
1011 * EnableHardwareInput (USER.331)
1013 BOOL16 EnableHardwareInput(BOOL16 bEnable)
1015 BOOL16 bOldState = InputEnabled;
1016 dprintf_event(stdnimp,"EnableHardwareInput(%d);\n", bEnable);
1017 InputEnabled = bEnable;