Release 960314
[wine/multimedia.git] / windows / event.c
blob203f75be269c701cf4ce6d56704c66c28479a4fb
1 /*
2 * X events handling functions
3 *
4 * Copyright 1993 Alexandre Julliard
5 *
6 */
8 #include <ctype.h>
9 #include <signal.h>
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <unistd.h>
13 #include <X11/keysym.h>
14 #include <X11/Xlib.h>
15 #include <X11/Xresource.h>
16 #include <X11/Xutil.h>
17 #include <X11/Xatom.h>
18 #include "gdi.h"
19 #include "windows.h"
20 #include "win.h"
21 #include "class.h"
22 #include "clipboard.h"
23 #include "options.h"
24 #include "queue.h"
25 #include "winpos.h"
26 #include "registers.h"
27 #include "stackframe.h"
28 #include "stddebug.h"
29 /* #define DEBUG_EVENT */
30 /* #define DEBUG_KEY */
31 #include "debug.h"
34 #ifdef ndef
35 #ifndef FamilyAmoeba
36 typedef char *XPointer;
37 #endif
38 #endif
40 #ifdef WHO_NEEDS_DIRTY_HACKS
41 #ifdef sparc
42 /* Dirty hack to compile with Sun's OpenWindows */
43 typedef char *XPointer;
44 #endif
45 #endif
47 #define NB_BUTTONS 3 /* Windows can handle 3 buttons */
49 /* X context to associate a hwnd to an X window */
50 static XContext winContext = 0;
52 /* State variables */
53 BOOL MouseButtonsStates[NB_BUTTONS] = { FALSE, FALSE, FALSE };
54 BOOL AsyncMouseButtonsStates[NB_BUTTONS] = { FALSE, FALSE, FALSE };
55 BYTE KeyStateTable[256];
56 BYTE AsyncKeyStateTable[256];
57 static WORD ALTKeyState;
58 static HWND captureWnd = 0;
59 static BOOL InputEnabled = TRUE;
61 /* Keyboard translation tables */
62 static int special_key[] =
64 VK_BACK, VK_TAB, 0, VK_CLEAR, 0, VK_RETURN, 0, 0, /* FF08 */
65 0, 0, 0, VK_PAUSE, VK_SCROLL, 0, 0, 0, /* FF10 */
66 0, 0, 0, VK_ESCAPE /* FF18 */
69 static cursor_key[] =
71 VK_HOME, VK_LEFT, VK_UP, VK_RIGHT, VK_DOWN, VK_PRIOR,
72 VK_NEXT, VK_END /* FF50 */
75 static misc_key[] =
77 VK_SELECT, VK_SNAPSHOT, VK_EXECUTE, VK_INSERT, 0, 0, 0, 0, /* FF60 */
78 VK_CANCEL, VK_HELP, VK_CANCEL, VK_MENU /* FF68 */
81 static keypad_key[] =
83 VK_MENU, VK_NUMLOCK, /* FF7E */
84 0, 0, 0, 0, 0, 0, 0, 0, /* FF80 */
85 0, 0, 0, 0, 0, VK_RETURN, 0, 0, /* FF88 */
86 0, 0, 0, 0, 0, 0, 0, 0, /* FF90 */
87 0, 0, 0, 0, 0, 0, 0, 0, /* FF98 */
88 0, 0, 0, 0, 0, 0, 0, 0, /* FFA0 */
89 0, 0, VK_MULTIPLY, VK_ADD, VK_SEPARATOR, VK_SUBTRACT,
90 VK_DECIMAL, VK_DIVIDE, /* FFA8 */
91 VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, VK_NUMPAD4,
92 VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7, /* FFB0 */
93 VK_NUMPAD8, VK_NUMPAD9 /* FFB8 */
96 static function_key[] =
98 VK_F1, VK_F2, /* FFBE */
99 VK_F3, VK_F4, VK_F5, VK_F6, VK_F7, VK_F8, VK_F9, VK_F10, /* FFC0 */
100 VK_F11, VK_F12, VK_F13, VK_F14, VK_F15, VK_F16 /* FFC8 */
103 static modifier_key[] =
105 VK_SHIFT, VK_SHIFT, VK_CONTROL, VK_CONTROL, VK_CAPITAL,
106 0, 0, /* FFE1 */
107 0, VK_MENU, VK_MENU /* FFE8 */
110 typedef union
112 struct
114 unsigned long count : 16;
115 unsigned long code : 8;
116 unsigned long extended : 1;
117 unsigned long : 4;
118 unsigned long context : 1;
119 unsigned long previous : 1;
120 unsigned long transition : 1;
121 } lp1;
122 unsigned long lp2;
123 } KEYLP;
125 static BOOL KeyDown = FALSE;
127 static const char *event_names[] =
129 "", "", "KeyPress", "KeyRelease", "ButtonPress", "ButtonRelease",
130 "MotionNotify", "EnterNotify", "LeaveNotify", "FocusIn", "FocusOut",
131 "KeymapNotify", "Expose", "GraphicsExpose", "NoExpose", "VisibilityNotify",
132 "CreateNotify", "DestroyNotify", "UnmapNotify", "MapNotify", "MapRequest",
133 "ReparentNotify", "ConfigureNotify", "ConfigureRequest", "GravityNotify",
134 "ResizeRequest", "CirculateNotify", "CirculateRequest", "PropertyNotify",
135 "SelectionClear", "SelectionRequest", "SelectionNotify", "ColormapNotify",
136 "ClientMessage", "MappingNotify"
139 /* Event handlers */
140 static void EVENT_key( XKeyEvent *event );
141 static void EVENT_ButtonPress( XButtonEvent *event );
142 static void EVENT_ButtonRelease( XButtonEvent *event );
143 static void EVENT_MotionNotify( XMotionEvent *event );
144 static void EVENT_FocusIn( HWND hwnd, XFocusChangeEvent *event );
145 static void EVENT_FocusOut( HWND hwnd, XFocusChangeEvent *event );
146 static void EVENT_Expose( HWND hwnd, XExposeEvent *event );
147 static void EVENT_ConfigureNotify( HWND hwnd, XConfigureEvent *event );
148 static void EVENT_SelectionRequest( HWND hwnd, XSelectionRequestEvent *event);
149 static void EVENT_SelectionNotify( HWND hwnd, XSelectionEvent *event);
150 static void EVENT_SelectionClear( HWND hwnd, XSelectionClearEvent *event);
151 static void EVENT_ClientMessage( HWND hwnd, XClientMessageEvent *event );
154 /***********************************************************************
155 * EVENT_ProcessEvent
157 * Process an X event.
159 void EVENT_ProcessEvent( XEvent *event )
161 HWND hwnd;
162 XPointer ptr;
164 XFindContext( display, ((XAnyEvent *)event)->window, winContext, &ptr );
165 hwnd = (HWND) (int)ptr;
167 dprintf_event(stddeb, "Got event %s for hwnd "NPFMT"\n",
168 event_names[event->type], hwnd );
170 switch(event->type)
172 case KeyPress:
173 case KeyRelease:
174 EVENT_key( (XKeyEvent*)event );
175 break;
177 case ButtonPress:
178 EVENT_ButtonPress( (XButtonEvent*)event );
179 break;
181 case ButtonRelease:
182 EVENT_ButtonRelease( (XButtonEvent*)event );
183 break;
185 case MotionNotify:
186 /* Wine between two fast machines across the overloaded campus
187 ethernet gets very boged down in MotionEvents. The following
188 simply finds the last motion event in the queue and drops
189 the rest. On a good link events are servered before they build
190 up so this doesn't take place. On a slow link this may cause
191 problems if the event order is important. I'm not yet seen
192 of any problems. Jon 7/6/96.
194 while (XCheckTypedWindowEvent(display, ((XAnyEvent *)event)->window,
195 MotionNotify, event));
196 EVENT_MotionNotify( (XMotionEvent*)event );
197 break;
199 case FocusIn:
200 EVENT_FocusIn( hwnd, (XFocusChangeEvent*)event );
201 break;
203 case FocusOut:
204 EVENT_FocusOut( hwnd, (XFocusChangeEvent*)event );
205 break;
207 case Expose:
208 EVENT_Expose( hwnd, (XExposeEvent*)event );
209 break;
211 case ConfigureNotify:
212 EVENT_ConfigureNotify( hwnd, (XConfigureEvent*)event );
213 break;
215 case SelectionRequest:
216 EVENT_SelectionRequest( hwnd, (XSelectionRequestEvent*)event );
217 break;
219 case SelectionNotify:
220 EVENT_SelectionNotify( hwnd, (XSelectionEvent*)event );
221 break;
223 case SelectionClear:
224 EVENT_SelectionClear( hwnd, (XSelectionClearEvent*) event );
225 break;
227 case ClientMessage:
228 EVENT_ClientMessage( hwnd, (XClientMessageEvent *) event );
229 break;
231 default:
232 dprintf_event(stddeb, "Unprocessed event %s for hwnd "NPFMT"\n",
233 event_names[event->type], hwnd );
234 break;
239 /***********************************************************************
240 * EVENT_RegisterWindow
242 * Associate an X window to a HWND.
244 void EVENT_RegisterWindow( Window w, HWND hwnd )
246 if (!winContext) winContext = XUniqueContext();
247 XSaveContext( display, w, winContext, (XPointer)(int)hwnd );
251 /***********************************************************************
252 * EVENT_XStateToKeyState
254 * Translate a X event state (Button1Mask, ShiftMask, etc...) to
255 * a Windows key state (MK_SHIFT, MK_CONTROL, etc...)
257 static WORD EVENT_XStateToKeyState( int state )
259 int kstate = 0;
261 if (state & Button1Mask) kstate |= MK_LBUTTON;
262 if (state & Button2Mask) kstate |= MK_MBUTTON;
263 if (state & Button3Mask) kstate |= MK_RBUTTON;
264 if (state & ShiftMask) kstate |= MK_SHIFT;
265 if (state & ControlMask) kstate |= MK_CONTROL;
266 return kstate;
270 /***********************************************************************
271 * EVENT_Expose
273 static void EVENT_Expose( HWND hwnd, XExposeEvent *event )
275 RECT rect;
276 WND * wndPtr = WIN_FindWndPtr( hwnd );
277 if (!wndPtr) return;
279 /* Make position relative to client area instead of window */
280 rect.left = event->x - (wndPtr->rectClient.left - wndPtr->rectWindow.left);
281 rect.top = event->y - (wndPtr->rectClient.top - wndPtr->rectWindow.top);
282 rect.right = rect.left + event->width;
283 rect.bottom = rect.top + event->height;
285 RedrawWindow( hwnd, &rect, 0,
286 RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE |
287 (event->count ? 0 : RDW_ERASENOW) );
291 /***********************************************************************
292 * EVENT_key
294 * Handle a X key event
296 static void EVENT_key( XKeyEvent *event )
298 char Str[24];
299 XComposeStatus cs;
300 KeySym keysym;
301 WORD vkey = 0;
302 WORD xkey, key_type, key;
303 KEYLP keylp;
304 BOOL extended = FALSE;
306 int count = XLookupString(event, Str, 1, &keysym, &cs);
307 Str[count] = '\0';
308 dprintf_key(stddeb,"WM_KEY??? : keysym=%lX, count=%u / %X / '%s'\n",
309 keysym, count, Str[0], Str);
311 /* Ctrl-Alt-Return enters the debugger */
312 if ((keysym == XK_Return) && (event->type == KeyPress) &&
313 (event->state & ControlMask) && (event->state & Mod1Mask))
314 kill( getpid(), SIGHUP );
316 xkey = LOWORD(keysym);
317 key_type = HIBYTE(xkey);
318 key = LOBYTE(xkey);
319 dprintf_key(stddeb," key_type=%X, key=%X\n", key_type, key);
321 if (key_type == 0xFF) /* non-character key */
323 if (key >= 0x08 && key <= 0x1B) /* special key */
324 vkey = special_key[key - 0x08];
325 else if (key >= 0x50 && key <= 0x57) /* cursor key */
326 vkey = cursor_key[key - 0x50];
327 else if (key >= 0x60 && key <= 0x6B) /* miscellaneous key */
328 vkey = misc_key[key - 0x60];
329 else if (key >= 0x7E && key <= 0xB9) /* keypad key */
331 vkey = keypad_key[key - 0x7E];
332 extended = TRUE;
334 else if (key >= 0xBE && key <= 0xCD) /* function key */
336 vkey = function_key[key - 0xBE];
337 extended = TRUE;
339 else if (key >= 0xE1 && key <= 0xEA) /* modifier key */
340 vkey = modifier_key[key - 0xE1];
341 else if (key == 0xFF) /* DEL key */
342 vkey = VK_DELETE;
344 else if (key_type == 0) /* character key */
346 if (isalnum(key))
347 vkey = toupper(key); /* convert lower to uppercase */
348 else
349 vkey = 0xbe;
352 if (event->type == KeyPress)
354 if (vkey == VK_MENU) ALTKeyState = TRUE;
355 if (!(KeyStateTable[vkey] & 0x0f))
356 KeyStateTable[vkey] ^= 0x80;
357 KeyStateTable[vkey] |= 0x01;
358 keylp.lp1.count = 1;
359 keylp.lp1.code = LOBYTE(event->keycode) - 8;
360 keylp.lp1.extended = (extended ? 1 : 0);
361 keylp.lp1.context = (event->state & Mod1Mask ? 1 : 0);
362 keylp.lp1.previous = (KeyDown ? 0 : 1);
363 keylp.lp1.transition = 0;
364 dprintf_key(stddeb," wParam=%X, lParam=%lX\n",
365 vkey, keylp.lp2 );
366 dprintf_key(stddeb," KeyState=%X\n", KeyStateTable[vkey]);
367 hardware_event( ALTKeyState ? WM_SYSKEYDOWN : WM_KEYDOWN,
368 vkey, keylp.lp2,
369 event->x_root - desktopX, event->y_root - desktopY,
370 event->time, 0 );
371 KeyDown = TRUE;
373 /* The key translation ought to take place in TranslateMessage().
374 * However, there is no way of passing the required information
375 * in a Windows message, so TranslateMessage does not currently
376 * do anything and the translation is done here.
378 if (count == 1) /* key has an ASCII representation */
380 dprintf_key(stddeb,"WM_CHAR : wParam=%X\n", (WORD)Str[0] );
381 PostMessage( GetFocus(), WM_CHAR, (WORD)(unsigned char)(Str[0]),
382 keylp.lp2 );
385 else
387 if (vkey == VK_MENU) ALTKeyState = FALSE;
388 KeyStateTable[vkey] &= 0xf0;
389 keylp.lp1.count = 1;
390 keylp.lp1.code = LOBYTE(event->keycode) - 8;
391 keylp.lp1.extended = (extended ? 1 : 0);
392 keylp.lp1.context = (event->state & Mod1Mask ? 1 : 0);
393 keylp.lp1.previous = 1;
394 keylp.lp1.transition = 1;
395 dprintf_key(stddeb," wParam=%X, lParam=%lX\n",
396 vkey, keylp.lp2 );
397 dprintf_key(stddeb," KeyState=%X\n", KeyStateTable[vkey]);
398 hardware_event( ((ALTKeyState || vkey == VK_MENU) ?
399 WM_SYSKEYUP : WM_KEYUP),
400 vkey, keylp.lp2,
401 event->x_root - desktopX, event->y_root - desktopY,
402 event->time, 0 );
403 KeyDown = FALSE;
408 /***********************************************************************
409 * EVENT_MotionNotify
411 static void EVENT_MotionNotify( XMotionEvent *event )
413 hardware_event( WM_MOUSEMOVE, EVENT_XStateToKeyState( event->state ), 0L,
414 event->x_root - desktopX, event->y_root - desktopY,
415 event->time, 0 );
419 /***********************************************************************
420 * EVENT_DummyMotionNotify
422 * Generate a dummy MotionNotify event. Used to force a WM_SETCURSOR message.
424 void EVENT_DummyMotionNotify(void)
426 Window root, child;
427 int rootX, rootY, childX, childY;
428 unsigned int state;
430 if (XQueryPointer( display, rootWindow, &root, &child,
431 &rootX, &rootY, &childX, &childY, &state ))
433 hardware_event(WM_MOUSEMOVE, EVENT_XStateToKeyState( state ), 0L,
434 rootX - desktopX, rootY - desktopY, GetTickCount(), 0 );
439 /***********************************************************************
440 * EVENT_ButtonPress
442 static void EVENT_ButtonPress( XButtonEvent *event )
444 static WORD messages[NB_BUTTONS] =
445 { WM_LBUTTONDOWN, WM_MBUTTONDOWN, WM_RBUTTONDOWN };
446 int buttonNum = event->button - 1;
448 if (buttonNum >= NB_BUTTONS) return;
449 MouseButtonsStates[buttonNum] = TRUE;
450 AsyncMouseButtonsStates[buttonNum] = TRUE;
451 hardware_event( messages[buttonNum],
452 EVENT_XStateToKeyState( event->state ), 0L,
453 event->x_root - desktopX, event->y_root - desktopY,
454 event->time, 0 );
458 /***********************************************************************
459 * EVENT_ButtonRelease
461 static void EVENT_ButtonRelease( XButtonEvent *event )
463 static const WORD messages[NB_BUTTONS] =
464 { WM_LBUTTONUP, WM_MBUTTONUP, WM_RBUTTONUP };
465 int buttonNum = event->button - 1;
467 if (buttonNum >= NB_BUTTONS) return;
468 MouseButtonsStates[buttonNum] = FALSE;
469 hardware_event( messages[buttonNum],
470 EVENT_XStateToKeyState( event->state ), 0L,
471 event->x_root - desktopX, event->y_root - desktopY,
472 event->time, 0 );
476 /**********************************************************************
477 * EVENT_FocusIn
479 static void EVENT_FocusIn (HWND hwnd, XFocusChangeEvent *event )
481 if (event->detail == NotifyPointer) return;
482 if (hwnd != GetActiveWindow()) WINPOS_ChangeActiveWindow( hwnd, FALSE );
483 if ((hwnd != GetFocus()) && ! IsChild( hwnd, GetFocus())) SetFocus( hwnd );
487 /**********************************************************************
488 * EVENT_FocusOut
490 * Note: only top-level override-redirect windows get FocusOut events.
492 static void EVENT_FocusOut( HWND hwnd, XFocusChangeEvent *event )
494 if (event->detail == NotifyPointer) return;
495 if (hwnd == GetActiveWindow()) WINPOS_ChangeActiveWindow( 0, FALSE );
496 if ((hwnd == GetFocus()) || IsChild( hwnd, GetFocus())) SetFocus( 0 );
500 /**********************************************************************
501 * EVENT_ConfigureNotify
503 * The ConfigureNotify event is only selected on the desktop window
504 * and on top-level windows when the -managed flag is used.
506 static void EVENT_ConfigureNotify( HWND hwnd, XConfigureEvent *event )
508 if (hwnd == GetDesktopWindow())
510 desktopX = event->x;
511 desktopY = event->y;
513 else
515 /* A managed window; most of this code is shamelessly
516 * stolen from SetWindowPos
519 WND *wndPtr;
520 WINDOWPOS winpos;
521 RECT newWindowRect, newClientRect;
523 if (!(wndPtr = WIN_FindWndPtr( hwnd )))
525 dprintf_event(stddeb, "ConfigureNotify: invalid HWND "NPFMT"\n", hwnd);
526 return;
529 /* Artificial messages */
530 SendMessage(hwnd, WM_ENTERSIZEMOVE, 0, 0);
531 SendMessage(hwnd, WM_EXITSIZEMOVE, 0, 0);
533 /* Fill WINDOWPOS struct */
534 winpos.flags = SWP_NOACTIVATE | SWP_NOZORDER;
535 winpos.hwnd = hwnd;
536 winpos.x = event->x;
537 winpos.y = event->y;
538 winpos.cx = event->width;
539 winpos.cy = event->height;
541 /* Check for unchanged attributes */
542 if(winpos.x == wndPtr->rectWindow.left &&
543 winpos.y == wndPtr->rectWindow.top)
544 winpos.flags |= SWP_NOMOVE;
545 if(winpos.cx == wndPtr->rectWindow.right - wndPtr->rectWindow.left &&
546 winpos.cy == wndPtr->rectWindow.bottom - wndPtr->rectWindow.top)
547 winpos.flags |= SWP_NOSIZE;
549 /* Send WM_WINDOWPOSCHANGING */
550 SendMessage(hwnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)MAKE_SEGPTR(&winpos));
552 /* Calculate new position and size */
553 newWindowRect.left = event->x;
554 newWindowRect.right = event->x + event->width;
555 newWindowRect.top = event->y;
556 newWindowRect.bottom = event->y + event->height;
558 WINPOS_SendNCCalcSize( winpos.hwnd, TRUE, &newWindowRect,
559 &wndPtr->rectWindow, &wndPtr->rectClient,
560 &winpos, &newClientRect );
562 /* Set new size and position */
563 wndPtr->rectWindow = newWindowRect;
564 wndPtr->rectClient = newClientRect;
565 SendMessage(hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)MAKE_SEGPTR(&winpos));
570 /***********************************************************************
571 * EVENT_SelectionRequest
573 static void EVENT_SelectionRequest( HWND hwnd, XSelectionRequestEvent *event )
575 XSelectionEvent result;
576 Atom rprop;
577 Window request=event->requestor;
578 rprop=None;
579 if(event->target == XA_STRING)
581 HANDLE hText;
582 LPSTR text;
583 rprop=event->property;
584 if(rprop == None)rprop=event->target;
585 if(event->selection!=XA_PRIMARY)rprop=None;
586 else if(!IsClipboardFormatAvailable(CF_TEXT))rprop=None;
587 else{
588 /* Don't worry if we can't open */
589 BOOL couldOpen=OpenClipboard(hwnd);
590 hText=GetClipboardData(CF_TEXT);
591 text=GlobalLock(hText);
592 XChangeProperty(display,request,rprop,XA_STRING,
593 8,PropModeReplace,text,strlen(text));
594 GlobalUnlock(hText);
595 /* close only if we opened before */
596 if(couldOpen)CloseClipboard();
599 if(rprop==None) dprintf_event(stddeb,"Request for %s ignored\n",
600 XGetAtomName(display,event->target));
601 result.type=SelectionNotify;
602 result.display=display;
603 result.requestor=request;
604 result.selection=event->selection;
605 result.property=rprop;
606 result.target=event->target;
607 result.time=event->time;
608 XSendEvent(display,event->requestor,False,NoEventMask,(XEvent*)&result);
612 /***********************************************************************
613 * EVENT_SelectionNotify
615 static void EVENT_SelectionNotify(HWND hwnd, XSelectionEvent *event)
617 if(event->selection!=XA_PRIMARY)return;
618 if(event->target!=XA_STRING)CLIPBOARD_ReadSelection(0,None);
619 CLIPBOARD_ReadSelection(event->requestor,event->property);
623 /***********************************************************************
624 * EVENT_SelectionClear
626 static void EVENT_SelectionClear(HWND hwnd, XSelectionClearEvent *event)
628 if(event->selection!=XA_PRIMARY)return;
629 CLIPBOARD_ReleaseSelection(hwnd);
633 /**********************************************************************
634 * EVENT_ClientMessage
636 static void EVENT_ClientMessage (HWND hwnd, XClientMessageEvent *event )
638 static Atom wmProtocols = None;
639 static Atom wmDeleteWindow = None;
641 if (wmProtocols == None)
642 wmProtocols = XInternAtom( display, "WM_PROTOCOLS", True );
643 if (wmDeleteWindow == None)
644 wmDeleteWindow = XInternAtom( display, "WM_DELETE_WINDOW", True );
646 if ((event->format != 32) || (event->message_type != wmProtocols) ||
647 (((Atom) event->data.l[0]) != wmDeleteWindow))
649 dprintf_event( stddeb, "unrecognized ClientMessage\n" );
650 return;
652 SendMessage( hwnd, WM_SYSCOMMAND, SC_CLOSE, 0 );
656 /**********************************************************************
657 * SetCapture (USER.18)
659 HWND SetCapture( HWND hwnd )
661 Window win;
662 HWND old_capture_wnd = captureWnd;
664 if (!hwnd)
666 ReleaseCapture();
667 return old_capture_wnd;
669 if (!(win = WIN_GetXWindow( hwnd ))) return 0;
670 if (XGrabPointer(display, win, False,
671 ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
672 GrabModeAsync, GrabModeAsync,
673 None, None, CurrentTime ) == GrabSuccess)
675 dprintf_win(stddeb, "SetCapture: "NPFMT"\n", hwnd);
676 captureWnd = hwnd;
677 return old_capture_wnd;
679 else return 0;
683 /**********************************************************************
684 * ReleaseCapture (USER.19)
686 void ReleaseCapture()
688 if (captureWnd == 0) return;
689 XUngrabPointer( display, CurrentTime );
690 captureWnd = 0;
691 dprintf_win(stddeb, "ReleaseCapture\n");
694 /**********************************************************************
695 * GetCapture (USER.236)
697 HWND GetCapture()
699 return captureWnd;
703 /***********************************************************************
704 * GetMouseEventProc (USER.337)
706 FARPROC GetMouseEventProc(void)
708 char name[] = "Mouse_Event";
709 return GetProcAddress( GetModuleHandle("USER"), MAKE_SEGPTR(name) );
713 /***********************************************************************
714 * Mouse_Event (USER.299)
716 #ifndef WINELIB
717 void Mouse_Event( struct sigcontext_struct context )
719 /* Register values:
720 * AX = mouse event
721 * BX = horizontal displacement if AX & ME_MOVE
722 * CX = vertical displacement if AX & ME_MOVE
723 * DX = button state (?)
724 * SI = mouse event flags (?)
726 Window root, child;
727 int rootX, rootY, childX, childY;
728 unsigned int state;
730 if (AX_reg(&context) & ME_MOVE)
732 /* We have to actually move the cursor */
733 XWarpPointer( display, rootWindow, None, 0, 0, 0, 0,
734 (short)BX_reg(&context), (short)CX_reg(&context) );
735 return;
737 if (!XQueryPointer( display, rootWindow, &root, &child,
738 &rootX, &rootY, &childX, &childY, &state )) return;
739 if (AX_reg(&context) & ME_LDOWN)
740 hardware_event( WM_LBUTTONDOWN, EVENT_XStateToKeyState( state ), 0L,
741 rootX - desktopX, rootY - desktopY, GetTickCount(), 0);
742 if (AX_reg(&context) & ME_LUP)
743 hardware_event( WM_LBUTTONUP, EVENT_XStateToKeyState( state ), 0L,
744 rootX - desktopX, rootY - desktopY, GetTickCount(), 0);
745 if (AX_reg(&context) & ME_RDOWN)
746 hardware_event( WM_RBUTTONDOWN, EVENT_XStateToKeyState( state ), 0L,
747 rootX - desktopX, rootY - desktopY, GetTickCount(), 0);
748 if (AX_reg(&context) & ME_RUP)
749 hardware_event( WM_RBUTTONUP, EVENT_XStateToKeyState( state ), 0L,
750 rootX - desktopX, rootY - desktopY, GetTickCount(), 0);
752 #endif
755 /**********************************************************************
756 * EnableHardwareInput [USER.331]
758 BOOL EnableHardwareInput(BOOL bEnable)
760 BOOL bOldState = InputEnabled;
761 dprintf_event(stdnimp,"EMPTY STUB !!! EnableHardwareInput(%d);\n", bEnable);
762 InputEnabled = bEnable;
763 return (bOldState && !bEnable);