Release 960521
[wine/multimedia.git] / windows / event.c
blobbe015bfe1ac2a332a1d5ad5bc8688ce370f80848
1 /*
2 * X events handling functions
3 *
4 * Copyright 1993 Alexandre Julliard
5 *
6 */
8 #include <ctype.h>
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <unistd.h>
12 #include <X11/keysym.h>
13 #include <X11/Xlib.h>
14 #include <X11/Xresource.h>
15 #include <X11/Xutil.h>
16 #include <X11/Xatom.h>
17 #include "windows.h"
18 #include "gdi.h"
19 #include "heap.h"
20 #include "win.h"
21 #include "class.h"
22 #include "clipboard.h"
23 #include "debugger.h"
24 #include "module.h"
25 #include "options.h"
26 #include "queue.h"
27 #include "winpos.h"
28 #include "registers.h"
29 #include "stddebug.h"
30 #include "debug.h"
33 #ifdef ndef
34 #ifndef FamilyAmoeba
35 typedef char *XPointer;
36 #endif
37 #endif
39 #ifdef WHO_NEEDS_DIRTY_HACKS
40 #ifdef sparc
41 /* Dirty hack to compile with Sun's OpenWindows */
42 typedef char *XPointer;
43 #endif
44 #endif
46 #define NB_BUTTONS 3 /* Windows can handle 3 buttons */
48 /* X context to associate a hwnd to an X window */
49 static XContext winContext = 0;
51 /* State variables */
52 BOOL MouseButtonsStates[NB_BUTTONS] = { FALSE, FALSE, FALSE };
53 BOOL AsyncMouseButtonsStates[NB_BUTTONS] = { FALSE, FALSE, FALSE };
54 BYTE KeyStateTable[256];
55 BYTE AsyncKeyStateTable[256];
58 WPARAM lastEventChar = 0; /* this will have to be changed once
59 * ToAscii starts working */
61 static HWND captureWnd = 0;
62 static BOOL InputEnabled = TRUE;
64 /* Keyboard translation tables */
65 static int special_key[] =
67 VK_BACK, VK_TAB, 0, VK_CLEAR, 0, VK_RETURN, 0, 0, /* FF08 */
68 0, 0, 0, VK_PAUSE, VK_SCROLL, 0, 0, 0, /* FF10 */
69 0, 0, 0, VK_ESCAPE /* FF18 */
72 static cursor_key[] =
74 VK_HOME, VK_LEFT, VK_UP, VK_RIGHT, VK_DOWN, VK_PRIOR,
75 VK_NEXT, VK_END /* FF50 */
78 static misc_key[] =
80 VK_SELECT, VK_SNAPSHOT, VK_EXECUTE, VK_INSERT, 0, 0, 0, 0, /* FF60 */
81 VK_CANCEL, VK_HELP, VK_CANCEL, VK_MENU /* FF68 */
84 static keypad_key[] =
86 VK_MENU, VK_NUMLOCK, /* FF7E */
87 0, 0, 0, 0, 0, 0, 0, 0, /* FF80 */
88 0, 0, 0, 0, 0, VK_RETURN, 0, 0, /* FF88 */
89 0, 0, 0, 0, 0, 0, 0, 0, /* FF90 */
90 0, 0, 0, 0, 0, 0, 0, 0, /* FF98 */
91 0, 0, 0, 0, 0, 0, 0, 0, /* FFA0 */
92 0, 0, VK_MULTIPLY, VK_ADD, VK_SEPARATOR, VK_SUBTRACT,
93 VK_DECIMAL, VK_DIVIDE, /* FFA8 */
94 VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, VK_NUMPAD4,
95 VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7, /* FFB0 */
96 VK_NUMPAD8, VK_NUMPAD9 /* FFB8 */
99 static function_key[] =
101 VK_F1, VK_F2, /* FFBE */
102 VK_F3, VK_F4, VK_F5, VK_F6, VK_F7, VK_F8, VK_F9, VK_F10, /* FFC0 */
103 VK_F11, VK_F12, VK_F13, VK_F14, VK_F15, VK_F16 /* FFC8 */
106 static modifier_key[] =
108 VK_SHIFT, VK_SHIFT, VK_CONTROL, VK_CONTROL, VK_CAPITAL,
109 0, 0, /* FFE1 */
110 0, VK_MENU, VK_MENU /* FFE8 */
113 typedef union
115 struct
117 unsigned long count : 16;
118 unsigned long code : 8;
119 unsigned long extended : 1;
120 unsigned long : 2;
121 unsigned long reserved : 2;
122 unsigned long context : 1;
123 unsigned long previous : 1;
124 unsigned long transition : 1;
125 } lp1;
126 unsigned long lp2;
127 } KEYLP;
129 static BOOL KeyDown = FALSE;
131 static const char *event_names[] =
133 "", "", "KeyPress", "KeyRelease", "ButtonPress", "ButtonRelease",
134 "MotionNotify", "EnterNotify", "LeaveNotify", "FocusIn", "FocusOut",
135 "KeymapNotify", "Expose", "GraphicsExpose", "NoExpose", "VisibilityNotify",
136 "CreateNotify", "DestroyNotify", "UnmapNotify", "MapNotify", "MapRequest",
137 "ReparentNotify", "ConfigureNotify", "ConfigureRequest", "GravityNotify",
138 "ResizeRequest", "CirculateNotify", "CirculateRequest", "PropertyNotify",
139 "SelectionClear", "SelectionRequest", "SelectionNotify", "ColormapNotify",
140 "ClientMessage", "MappingNotify"
143 /* Event handlers */
144 static void EVENT_key( XKeyEvent *event );
145 static void EVENT_ButtonPress( XButtonEvent *event );
146 static void EVENT_ButtonRelease( XButtonEvent *event );
147 static void EVENT_MotionNotify( XMotionEvent *event );
148 static void EVENT_FocusIn( HWND hwnd, XFocusChangeEvent *event );
149 static void EVENT_FocusOut( HWND hwnd, XFocusChangeEvent *event );
150 static void EVENT_Expose( HWND hwnd, XExposeEvent *event );
151 static void EVENT_GraphicsExpose( HWND hwnd, XGraphicsExposeEvent *event );
152 static void EVENT_ConfigureNotify( HWND hwnd, XConfigureEvent *event );
153 static void EVENT_SelectionRequest( HWND hwnd, XSelectionRequestEvent *event);
154 static void EVENT_SelectionNotify( HWND hwnd, XSelectionEvent *event);
155 static void EVENT_SelectionClear( HWND hwnd, XSelectionClearEvent *event);
156 static void EVENT_ClientMessage( HWND hwnd, XClientMessageEvent *event );
159 /***********************************************************************
160 * EVENT_ProcessEvent
162 * Process an X event.
164 void EVENT_ProcessEvent( XEvent *event )
166 HWND hwnd;
167 XPointer ptr;
169 XFindContext( display, ((XAnyEvent *)event)->window, winContext, &ptr );
170 hwnd = (HWND) (int)ptr;
172 dprintf_event(stddeb, "Got event %s for hwnd %04x\n",
173 event_names[event->type], hwnd );
175 switch(event->type)
177 case KeyPress:
178 case KeyRelease:
179 EVENT_key( (XKeyEvent*)event );
180 break;
182 case ButtonPress:
183 EVENT_ButtonPress( (XButtonEvent*)event );
184 break;
186 case ButtonRelease:
187 EVENT_ButtonRelease( (XButtonEvent*)event );
188 break;
190 case MotionNotify:
191 /* Wine between two fast machines across the overloaded campus
192 ethernet gets very boged down in MotionEvents. The following
193 simply finds the last motion event in the queue and drops
194 the rest. On a good link events are servered before they build
195 up so this doesn't take place. On a slow link this may cause
196 problems if the event order is important. I'm not yet seen
197 of any problems. Jon 7/6/96.
199 while (XCheckTypedWindowEvent(display, ((XAnyEvent *)event)->window,
200 MotionNotify, event));
201 EVENT_MotionNotify( (XMotionEvent*)event );
202 break;
204 case FocusIn:
205 EVENT_FocusIn( hwnd, (XFocusChangeEvent*)event );
206 break;
208 case FocusOut:
209 EVENT_FocusOut( hwnd, (XFocusChangeEvent*)event );
210 break;
212 case Expose:
213 EVENT_Expose( hwnd, (XExposeEvent*)event );
214 break;
216 case ConfigureNotify:
217 EVENT_ConfigureNotify( hwnd, (XConfigureEvent*)event );
218 break;
220 case SelectionRequest:
221 EVENT_SelectionRequest( hwnd, (XSelectionRequestEvent*)event );
222 break;
224 case SelectionNotify:
225 EVENT_SelectionNotify( hwnd, (XSelectionEvent*)event );
226 break;
228 case SelectionClear:
229 EVENT_SelectionClear( hwnd, (XSelectionClearEvent*) event );
230 break;
232 case ClientMessage:
233 EVENT_ClientMessage( hwnd, (XClientMessageEvent *) event );
234 break;
236 case GraphicsExpose:
237 EVENT_GraphicsExpose( hwnd, (XGraphicsExposeEvent *) event );
239 case NoExpose:
240 break;
242 default:
243 dprintf_event(stddeb, "Unprocessed event %s for hwnd %04x\n",
244 event_names[event->type], hwnd );
245 break;
250 /***********************************************************************
251 * EVENT_RegisterWindow
253 * Associate an X window to a HWND.
255 void EVENT_RegisterWindow( Window w, HWND hwnd )
257 if (!winContext) winContext = XUniqueContext();
258 XSaveContext( display, w, winContext, (XPointer)(int)hwnd );
262 /***********************************************************************
263 * EVENT_XStateToKeyState
265 * Translate a X event state (Button1Mask, ShiftMask, etc...) to
266 * a Windows key state (MK_SHIFT, MK_CONTROL, etc...)
268 static WORD EVENT_XStateToKeyState( int state )
270 int kstate = 0;
272 if (state & Button1Mask) kstate |= MK_LBUTTON;
273 if (state & Button2Mask) kstate |= MK_MBUTTON;
274 if (state & Button3Mask) kstate |= MK_RBUTTON;
275 if (state & ShiftMask) kstate |= MK_SHIFT;
276 if (state & ControlMask) kstate |= MK_CONTROL;
277 return kstate;
281 /***********************************************************************
282 * EVENT_Expose
284 static void EVENT_Expose( HWND hwnd, XExposeEvent *event )
286 RECT32 rect;
287 WND * wndPtr = WIN_FindWndPtr( hwnd );
288 if (!wndPtr) return;
290 /* Make position relative to client area instead of window */
291 rect.left = event->x - (wndPtr->rectClient.left - wndPtr->rectWindow.left);
292 rect.top = event->y - (wndPtr->rectClient.top - wndPtr->rectWindow.top);
293 rect.right = rect.left + event->width;
294 rect.bottom = rect.top + event->height;
296 RedrawWindow32( hwnd, &rect, 0,
297 RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE |
298 (event->count ? 0 : RDW_ERASENOW) );
302 /***********************************************************************
303 * EVENT_GraphicsExpose
304 * This is needed when scrolling area is partially obscured
305 * by non-Wine X window.
307 static void EVENT_GraphicsExpose( HWND hwnd, XGraphicsExposeEvent *event )
309 RECT16 rect;
310 WND * wndPtr = WIN_FindWndPtr( hwnd );
311 if (!wndPtr) return;
313 /* Make position relative to client area instead of window */
314 rect.left = event->x - (wndPtr->rectClient.left - wndPtr->rectWindow.left);
315 rect.top = event->y - (wndPtr->rectClient.top - wndPtr->rectWindow.top);
316 rect.right = rect.left + event->width;
317 rect.bottom = rect.top + event->height;
319 RedrawWindow16( hwnd, &rect, 0,
320 RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE |
321 (event->count ? 0 : RDW_ERASENOW) );
325 /***********************************************************************
326 * EVENT_key
328 * Handle a X key event
330 static void EVENT_key( XKeyEvent *event )
332 char Str[24];
333 XComposeStatus cs;
334 KeySym keysym;
335 WORD vkey = 0;
336 WORD xkey, key_type, key;
337 KEYLP keylp;
338 BOOL extended = FALSE;
340 int ascii_chars = XLookupString(event, Str, 1, &keysym, &cs);
342 Str[ascii_chars] = '\0';
343 dprintf_key(stddeb,"WM_KEY??? : keysym=%lX, ascii chars=%u / %X / '%s'\n",
344 keysym, ascii_chars, Str[0], Str);
346 /* Ctrl-Alt-Return enters the debugger */
347 if ((keysym == XK_Return) && (event->type == KeyPress) &&
348 (event->state & ControlMask) && (event->state & Mod1Mask))
349 DEBUG_EnterDebugger();
351 xkey = LOWORD(keysym);
352 key_type = HIBYTE(xkey);
353 key = LOBYTE(xkey);
354 dprintf_key(stddeb," key_type=%X, key=%X\n", key_type, key);
356 if (key_type == 0xFF) /* non-character key */
358 if (key >= 0x08 && key <= 0x1B) /* special key */
359 vkey = special_key[key - 0x08];
360 else if (key >= 0x50 && key <= 0x57) /* cursor key */
361 vkey = cursor_key[key - 0x50];
362 else if (key >= 0x60 && key <= 0x6B) /* miscellaneous key */
363 vkey = misc_key[key - 0x60];
364 else if (key >= 0x7E && key <= 0xB9) /* keypad key */
366 vkey = keypad_key[key - 0x7E];
367 extended = TRUE;
369 else if (key >= 0xBE && key <= 0xCD) /* function key */
371 vkey = function_key[key - 0xBE];
372 extended = TRUE;
374 else if (key >= 0xE1 && key <= 0xEA) /* modifier key */
375 vkey = modifier_key[key - 0xE1];
376 else if (key == 0xFF) /* DEL key */
377 vkey = VK_DELETE;
379 else if (key_type == 0) /* character key */
381 if ( isalnum(key) )
382 vkey = toupper(key); /* convert lower to uppercase */
383 else
384 vkey = 0xbe;
387 if (event->type == KeyPress)
389 if (!(KeyStateTable[vkey] & 0x80))
390 KeyStateTable[vkey] ^= 0x01;
391 KeyStateTable[vkey] |= 0x80;
392 keylp.lp1.count = 1;
393 keylp.lp1.code = LOBYTE(event->keycode) - 8;
394 keylp.lp1.extended = (extended ? 1 : 0);
395 keylp.lp1.reserved = (ascii_chars ? 1 : 0);
396 keylp.lp1.context = ( (event->state & Mod1Mask) ||
397 (KeyStateTable[VK_MENU] & 0x80)) ? 1 : 0;
398 keylp.lp1.previous = (KeyDown ? 0 : 1);
399 keylp.lp1.transition = 0;
400 dprintf_key(stddeb," wParam=%X, lParam=%lX\n",
401 vkey, keylp.lp2 );
402 dprintf_key(stddeb," KeyState=%X\n", KeyStateTable[vkey]);
403 hardware_event( KeyStateTable[VK_MENU] & 0x80 ? WM_SYSKEYDOWN : WM_KEYDOWN,
404 vkey, keylp.lp2,
405 event->x_root - desktopX, event->y_root - desktopY,
406 event->time, 0 );
407 KeyDown = TRUE;
409 /* Currently we use reserved field in the scan-code byte to
410 * make it possible for TranslateMessage to recognize character keys
411 * and get them from lastEventChar global variable.
413 * ToAscii should handle it.
416 if( ascii_chars ) lastEventChar = Str[0];
418 else
420 UINT sysKey = KeyStateTable[VK_MENU];
422 KeyStateTable[vkey] &= ~0x80;
423 keylp.lp1.count = 1;
424 keylp.lp1.code = LOBYTE(event->keycode) - 8;
425 keylp.lp1.extended = (extended ? 1 : 0);
426 keylp.lp1.reserved = 0;
427 keylp.lp1.context = (event->state & Mod1Mask ? 1 : 0);
428 keylp.lp1.previous = 1;
429 keylp.lp1.transition = 1;
430 dprintf_key(stddeb," wParam=%X, lParam=%lX\n",
431 vkey, keylp.lp2 );
432 dprintf_key(stddeb," KeyState=%X\n", KeyStateTable[vkey]);
433 hardware_event( sysKey & 0x80 ? WM_SYSKEYUP : WM_KEYUP,
434 vkey, keylp.lp2,
435 event->x_root - desktopX, event->y_root - desktopY,
436 event->time, 0 );
437 KeyDown = FALSE;
442 /***********************************************************************
443 * EVENT_MotionNotify
445 static void EVENT_MotionNotify( XMotionEvent *event )
447 hardware_event( WM_MOUSEMOVE, EVENT_XStateToKeyState( event->state ), 0L,
448 event->x_root - desktopX, event->y_root - desktopY,
449 event->time, 0 );
453 /***********************************************************************
454 * EVENT_DummyMotionNotify
456 * Generate a dummy MotionNotify event. Used to force a WM_SETCURSOR message.
458 void EVENT_DummyMotionNotify(void)
460 Window root, child;
461 int rootX, rootY, childX, childY;
462 unsigned int state;
464 if (XQueryPointer( display, rootWindow, &root, &child,
465 &rootX, &rootY, &childX, &childY, &state ))
467 hardware_event(WM_MOUSEMOVE, EVENT_XStateToKeyState( state ), 0L,
468 rootX - desktopX, rootY - desktopY, GetTickCount(), 0 );
473 /***********************************************************************
474 * EVENT_ButtonPress
476 static void EVENT_ButtonPress( XButtonEvent *event )
478 static WORD messages[NB_BUTTONS] =
479 { WM_LBUTTONDOWN, WM_MBUTTONDOWN, WM_RBUTTONDOWN };
480 int buttonNum = event->button - 1;
482 if (buttonNum >= NB_BUTTONS) return;
483 MouseButtonsStates[buttonNum] = 0x8000;
484 AsyncMouseButtonsStates[buttonNum] = 0x8000;
485 hardware_event( messages[buttonNum],
486 EVENT_XStateToKeyState( event->state ), 0L,
487 event->x_root - desktopX, event->y_root - desktopY,
488 event->time, 0 );
492 /***********************************************************************
493 * EVENT_ButtonRelease
495 static void EVENT_ButtonRelease( XButtonEvent *event )
497 static const WORD messages[NB_BUTTONS] =
498 { WM_LBUTTONUP, WM_MBUTTONUP, WM_RBUTTONUP };
499 int buttonNum = event->button - 1;
501 if (buttonNum >= NB_BUTTONS) return;
502 MouseButtonsStates[buttonNum] = FALSE;
503 hardware_event( messages[buttonNum],
504 EVENT_XStateToKeyState( event->state ), 0L,
505 event->x_root - desktopX, event->y_root - desktopY,
506 event->time, 0 );
510 /**********************************************************************
511 * EVENT_FocusIn
513 static void EVENT_FocusIn (HWND hwnd, XFocusChangeEvent *event )
515 if (event->detail == NotifyPointer) return;
516 if (hwnd != GetActiveWindow()) WINPOS_ChangeActiveWindow( hwnd, FALSE );
517 if ((hwnd != GetFocus()) && !IsChild( hwnd, GetFocus())) SetFocus( hwnd );
521 /**********************************************************************
522 * EVENT_FocusOut
524 * Note: only top-level override-redirect windows get FocusOut events.
526 static void EVENT_FocusOut( HWND hwnd, XFocusChangeEvent *event )
528 if (event->detail == NotifyPointer) return;
529 if (hwnd == GetActiveWindow()) WINPOS_ChangeActiveWindow( 0, FALSE );
530 if ((hwnd == GetFocus()) || IsChild( hwnd, GetFocus())) SetFocus( 0 );
534 /**********************************************************************
535 * EVENT_ConfigureNotify
537 * The ConfigureNotify event is only selected on the desktop window
538 * and on top-level windows when the -managed flag is used.
540 static void EVENT_ConfigureNotify( HWND hwnd, XConfigureEvent *event )
542 if (hwnd == GetDesktopWindow())
544 desktopX = event->x;
545 desktopY = event->y;
547 else
549 /* A managed window; most of this code is shamelessly
550 * stolen from SetWindowPos - FIXME: outdated
553 WND *wndPtr;
554 WINDOWPOS16 *winpos;
555 RECT16 newWindowRect, newClientRect;
556 HRGN hrgnOldPos, hrgnNewPos;
558 if (!(wndPtr = WIN_FindWndPtr( hwnd )))
560 dprintf_event(stddeb,"ConfigureNotify: invalid HWND %04x\n",hwnd);
561 return;
564 if (!(winpos = SEGPTR_NEW(WINDOWPOS16))) return;
566 /* Artificial messages - what is this for? */
567 SendMessage16(hwnd, WM_ENTERSIZEMOVE, 0, 0);
568 SendMessage16(hwnd, WM_EXITSIZEMOVE, 0, 0);
570 /* Fill WINDOWPOS struct */
571 winpos->flags = SWP_NOACTIVATE | SWP_NOZORDER;
572 winpos->hwnd = hwnd;
573 winpos->x = event->x;
574 winpos->y = event->y;
575 winpos->cx = event->width;
576 winpos->cy = event->height;
578 /* Check for unchanged attributes */
579 if(winpos->x == wndPtr->rectWindow.left &&
580 winpos->y == wndPtr->rectWindow.top)
581 winpos->flags |= SWP_NOMOVE;
582 if(winpos->cx == wndPtr->rectWindow.right - wndPtr->rectWindow.left &&
583 winpos->cy == wndPtr->rectWindow.bottom - wndPtr->rectWindow.top)
584 winpos->flags |= SWP_NOSIZE;
586 /* Send WM_WINDOWPOSCHANGING */
587 SendMessage16(hwnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)SEGPTR_GET(winpos));
589 /* Calculate new position and size */
590 newWindowRect.left = event->x;
591 newWindowRect.right = event->x + event->width;
592 newWindowRect.top = event->y;
593 newWindowRect.bottom = event->y + event->height;
595 WINPOS_SendNCCalcSize( winpos->hwnd, TRUE, &newWindowRect,
596 &wndPtr->rectWindow, &wndPtr->rectClient,
597 SEGPTR_GET(winpos), &newClientRect );
599 hrgnOldPos = CreateRectRgnIndirect16( &wndPtr->rectWindow );
600 hrgnNewPos = CreateRectRgnIndirect16( &newWindowRect );
601 CombineRgn( hrgnOldPos, hrgnOldPos, hrgnNewPos, RGN_DIFF );
603 /* Set new size and position */
604 wndPtr->rectWindow = newWindowRect;
605 wndPtr->rectClient = newClientRect;
606 SendMessage16( hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)SEGPTR_GET(winpos));
607 SEGPTR_FREE(winpos);
609 /* full window drag leaves unrepainted garbage without this */
610 RedrawWindow32( 0, NULL, hrgnOldPos, RDW_INVALIDATE |
611 RDW_ALLCHILDREN | RDW_ERASE | RDW_ERASENOW );
612 DeleteObject(hrgnOldPos);
613 DeleteObject(hrgnNewPos);
618 /***********************************************************************
619 * EVENT_SelectionRequest
621 static void EVENT_SelectionRequest( HWND hwnd, XSelectionRequestEvent *event )
623 XSelectionEvent result;
624 Atom rprop;
625 Window request=event->requestor;
626 rprop=None;
627 if(event->target == XA_STRING)
629 HANDLE hText;
630 LPSTR text;
631 rprop=event->property;
632 if(rprop == None)rprop=event->target;
633 if(event->selection!=XA_PRIMARY)rprop=None;
634 else if(!IsClipboardFormatAvailable(CF_TEXT))rprop=None;
635 else{
636 /* Don't worry if we can't open */
637 BOOL couldOpen=OpenClipboard(hwnd);
638 hText=GetClipboardData(CF_TEXT);
639 text=GlobalLock16(hText);
640 XChangeProperty(display,request,rprop,XA_STRING,
641 8,PropModeReplace,text,strlen(text));
642 GlobalUnlock16(hText);
643 /* close only if we opened before */
644 if(couldOpen)CloseClipboard();
647 if(rprop==None) dprintf_event(stddeb,"Request for %s ignored\n",
648 XGetAtomName(display,event->target));
649 result.type=SelectionNotify;
650 result.display=display;
651 result.requestor=request;
652 result.selection=event->selection;
653 result.property=rprop;
654 result.target=event->target;
655 result.time=event->time;
656 XSendEvent(display,event->requestor,False,NoEventMask,(XEvent*)&result);
660 /***********************************************************************
661 * EVENT_SelectionNotify
663 static void EVENT_SelectionNotify(HWND hwnd, XSelectionEvent *event)
665 if(event->selection!=XA_PRIMARY)return;
666 if(event->target!=XA_STRING)CLIPBOARD_ReadSelection(0,None);
667 CLIPBOARD_ReadSelection(event->requestor,event->property);
671 /***********************************************************************
672 * EVENT_SelectionClear
674 static void EVENT_SelectionClear(HWND hwnd, XSelectionClearEvent *event)
676 if(event->selection!=XA_PRIMARY)return;
677 CLIPBOARD_ReleaseSelection(hwnd);
681 /**********************************************************************
682 * EVENT_ClientMessage
684 static void EVENT_ClientMessage (HWND hwnd, XClientMessageEvent *event )
686 static Atom wmProtocols = None;
687 static Atom wmDeleteWindow = None;
689 if (wmProtocols == None)
690 wmProtocols = XInternAtom( display, "WM_PROTOCOLS", True );
691 if (wmDeleteWindow == None)
692 wmDeleteWindow = XInternAtom( display, "WM_DELETE_WINDOW", True );
694 if ((event->format != 32) || (event->message_type != wmProtocols) ||
695 (((Atom) event->data.l[0]) != wmDeleteWindow))
697 dprintf_event( stddeb, "unrecognized ClientMessage\n" );
698 return;
700 SendMessage16( hwnd, WM_SYSCOMMAND, SC_CLOSE, 0 );
704 /**********************************************************************
705 * SetCapture (USER.18)
707 HWND SetCapture( HWND hwnd )
709 Window win;
710 HWND old_capture_wnd = captureWnd;
712 if (!hwnd)
714 ReleaseCapture();
715 return old_capture_wnd;
717 if (!(win = WIN_GetXWindow( hwnd ))) return 0;
718 if (XGrabPointer(display, win, False,
719 ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
720 GrabModeAsync, GrabModeAsync,
721 None, None, CurrentTime ) == GrabSuccess)
723 dprintf_win(stddeb, "SetCapture: %04x\n", hwnd);
724 captureWnd = hwnd;
725 return old_capture_wnd;
727 else return 0;
731 /**********************************************************************
732 * ReleaseCapture (USER.19)
734 void ReleaseCapture()
736 if (captureWnd == 0) return;
737 XUngrabPointer( display, CurrentTime );
738 captureWnd = 0;
739 dprintf_win(stddeb, "ReleaseCapture\n");
742 /**********************************************************************
743 * GetCapture (USER.236)
745 HWND GetCapture()
747 return captureWnd;
751 /***********************************************************************
752 * GetMouseEventProc (USER.337)
754 FARPROC GetMouseEventProc(void)
756 HMODULE hmodule = GetModuleHandle("USER");
757 return MODULE_GetEntryPoint( hmodule,
758 MODULE_GetOrdinal( hmodule, "Mouse_Event" ) );
762 /***********************************************************************
763 * Mouse_Event (USER.299)
765 #ifndef WINELIB
766 void Mouse_Event( struct sigcontext_struct context )
768 /* Register values:
769 * AX = mouse event
770 * BX = horizontal displacement if AX & ME_MOVE
771 * CX = vertical displacement if AX & ME_MOVE
772 * DX = button state (?)
773 * SI = mouse event flags (?)
775 Window root, child;
776 int rootX, rootY, childX, childY;
777 unsigned int state;
779 if (AX_reg(&context) & ME_MOVE)
781 /* We have to actually move the cursor */
782 XWarpPointer( display, rootWindow, None, 0, 0, 0, 0,
783 (short)BX_reg(&context), (short)CX_reg(&context) );
784 return;
786 if (!XQueryPointer( display, rootWindow, &root, &child,
787 &rootX, &rootY, &childX, &childY, &state )) return;
788 if (AX_reg(&context) & ME_LDOWN)
789 hardware_event( WM_LBUTTONDOWN, EVENT_XStateToKeyState( state ), 0L,
790 rootX - desktopX, rootY - desktopY, GetTickCount(), 0);
791 if (AX_reg(&context) & ME_LUP)
792 hardware_event( WM_LBUTTONUP, EVENT_XStateToKeyState( state ), 0L,
793 rootX - desktopX, rootY - desktopY, GetTickCount(), 0);
794 if (AX_reg(&context) & ME_RDOWN)
795 hardware_event( WM_RBUTTONDOWN, EVENT_XStateToKeyState( state ), 0L,
796 rootX - desktopX, rootY - desktopY, GetTickCount(), 0);
797 if (AX_reg(&context) & ME_RUP)
798 hardware_event( WM_RBUTTONUP, EVENT_XStateToKeyState( state ), 0L,
799 rootX - desktopX, rootY - desktopY, GetTickCount(), 0);
801 #endif
804 /**********************************************************************
805 * EnableHardwareInput [USER.331]
807 BOOL EnableHardwareInput(BOOL bEnable)
809 BOOL bOldState = InputEnabled;
810 dprintf_event(stdnimp,"EMPTY STUB !!! EnableHardwareInput(%d);\n", bEnable);
811 InputEnabled = bEnable;
812 return (bOldState && !bEnable);