2 * X events handling functions
4 * Copyright 1993 Alexandre Julliard
12 #include <X11/keysym.h>
14 #include <X11/Xresource.h>
15 #include <X11/Xutil.h>
16 #include <X11/Xatom.h>
22 #include "clipboard.h"
28 #include "registers.h"
35 typedef char *XPointer
;
39 #ifdef WHO_NEEDS_DIRTY_HACKS
41 /* Dirty hack to compile with Sun's OpenWindows */
42 typedef char *XPointer
;
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;
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 */
74 VK_HOME
, VK_LEFT
, VK_UP
, VK_RIGHT
, VK_DOWN
, VK_PRIOR
,
75 VK_NEXT
, VK_END
/* FF50 */
80 VK_SELECT
, VK_SNAPSHOT
, VK_EXECUTE
, VK_INSERT
, 0, 0, 0, 0, /* FF60 */
81 VK_CANCEL
, VK_HELP
, VK_CANCEL
, VK_MENU
/* FF68 */
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
,
110 0, VK_MENU
, VK_MENU
/* FFE8 */
117 unsigned long count
: 16;
118 unsigned long code
: 8;
119 unsigned long extended
: 1;
121 unsigned long reserved
: 2;
122 unsigned long context
: 1;
123 unsigned long previous
: 1;
124 unsigned long transition
: 1;
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"
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 /***********************************************************************
162 * Process an X event.
164 void EVENT_ProcessEvent( XEvent
*event
)
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
);
179 EVENT_key( (XKeyEvent
*)event
);
183 EVENT_ButtonPress( (XButtonEvent
*)event
);
187 EVENT_ButtonRelease( (XButtonEvent
*)event
);
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
);
205 EVENT_FocusIn( hwnd
, (XFocusChangeEvent
*)event
);
209 EVENT_FocusOut( hwnd
, (XFocusChangeEvent
*)event
);
213 EVENT_Expose( hwnd
, (XExposeEvent
*)event
);
216 case ConfigureNotify
:
217 EVENT_ConfigureNotify( hwnd
, (XConfigureEvent
*)event
);
220 case SelectionRequest
:
221 EVENT_SelectionRequest( hwnd
, (XSelectionRequestEvent
*)event
);
224 case SelectionNotify
:
225 EVENT_SelectionNotify( hwnd
, (XSelectionEvent
*)event
);
229 EVENT_SelectionClear( hwnd
, (XSelectionClearEvent
*) event
);
233 EVENT_ClientMessage( hwnd
, (XClientMessageEvent
*) event
);
237 EVENT_GraphicsExpose( hwnd
, (XGraphicsExposeEvent
*) event
);
243 dprintf_event(stddeb
, "Unprocessed event %s for hwnd %04x\n",
244 event_names
[event
->type
], hwnd
);
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
)
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
;
281 /***********************************************************************
284 static void EVENT_Expose( HWND hwnd
, XExposeEvent
*event
)
287 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
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
)
310 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
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 /***********************************************************************
328 * Handle a X key event
330 static void EVENT_key( XKeyEvent
*event
)
336 WORD xkey
, key_type
, key
;
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
);
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];
369 else if (key
>= 0xBE && key
<= 0xCD) /* function key */
371 vkey
= function_key
[key
- 0xBE];
374 else if (key
>= 0xE1 && key
<= 0xEA) /* modifier key */
375 vkey
= modifier_key
[key
- 0xE1];
376 else if (key
== 0xFF) /* DEL key */
379 else if (key_type
== 0) /* character key */
382 vkey
= toupper(key
); /* convert lower to uppercase */
387 if (event
->type
== KeyPress
)
389 if (!(KeyStateTable
[vkey
] & 0x80))
390 KeyStateTable
[vkey
] ^= 0x01;
391 KeyStateTable
[vkey
] |= 0x80;
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",
402 dprintf_key(stddeb
," KeyState=%X\n", KeyStateTable
[vkey
]);
403 hardware_event( KeyStateTable
[VK_MENU
] & 0x80 ? WM_SYSKEYDOWN
: WM_KEYDOWN
,
405 event
->x_root
- desktopX
, event
->y_root
- desktopY
,
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];
420 UINT sysKey
= KeyStateTable
[VK_MENU
];
422 KeyStateTable
[vkey
] &= ~0x80;
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",
432 dprintf_key(stddeb
," KeyState=%X\n", KeyStateTable
[vkey
]);
433 hardware_event( sysKey
& 0x80 ? WM_SYSKEYUP
: WM_KEYUP
,
435 event
->x_root
- desktopX
, event
->y_root
- desktopY
,
442 /***********************************************************************
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
,
453 /***********************************************************************
454 * EVENT_DummyMotionNotify
456 * Generate a dummy MotionNotify event. Used to force a WM_SETCURSOR message.
458 void EVENT_DummyMotionNotify(void)
461 int rootX
, rootY
, childX
, childY
;
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 /***********************************************************************
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
,
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
,
510 /**********************************************************************
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 /**********************************************************************
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())
549 /* A managed window; most of this code is shamelessly
550 * stolen from SetWindowPos - FIXME: outdated
555 RECT16 newWindowRect
, newClientRect
;
556 HRGN hrgnOldPos
, hrgnNewPos
;
558 if (!(wndPtr
= WIN_FindWndPtr( hwnd
)))
560 dprintf_event(stddeb
,"ConfigureNotify: invalid HWND %04x\n",hwnd
);
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
;
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
));
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
;
625 Window request
=event
->requestor
;
627 if(event
->target
== XA_STRING
)
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
;
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" );
700 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_CLOSE
, 0 );
704 /**********************************************************************
705 * SetCapture (USER.18)
707 HWND
SetCapture( HWND hwnd
)
710 HWND old_capture_wnd
= captureWnd
;
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
);
725 return old_capture_wnd
;
731 /**********************************************************************
732 * ReleaseCapture (USER.19)
734 void ReleaseCapture()
736 if (captureWnd
== 0) return;
737 XUngrabPointer( display
, CurrentTime
);
739 dprintf_win(stddeb
, "ReleaseCapture\n");
742 /**********************************************************************
743 * GetCapture (USER.236)
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)
766 void Mouse_Event( struct sigcontext_struct context
)
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 (?)
776 int rootX
, rootY
, childX
, childY
;
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
) );
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);
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
);