2 * X events handling functions
4 * Copyright 1993 Alexandre Julliard
7 static char Copyright
[] = "Copyright Alexandre Julliard, 1993";
17 #define NB_BUTTONS 3 /* Windows can handle 3 buttons */
19 extern Display
* display
;
21 extern void WINPOS_ChangeActiveWindow( HWND hwnd
, BOOL mouseMsg
); /*winpos.c*/
23 /* X context to associate a hwnd to an X window */
24 static XContext winContext
= 0;
27 static WORD ALTKeyState
;
28 static HWND captureWnd
= 0;
29 Window winHasCursor
= 0;
30 extern HWND hWndFocus
;
32 /* Keyboard translation tables */
33 static int special_key
[] =
35 VK_BACK
, VK_TAB
, 0, VK_CLEAR
, 0, VK_RETURN
, 0, 0, /* FF08 */
36 0, 0, 0, VK_PAUSE
, VK_SCROLL
, 0, 0, 0, /* FF10 */
37 0, 0, 0, VK_ESCAPE
/* FF18 */
42 VK_HOME
, VK_LEFT
, VK_UP
, VK_RIGHT
, VK_DOWN
, VK_PRIOR
,
43 VK_NEXT
, VK_END
/* FF50 */
48 VK_SELECT
, VK_SNAPSHOT
, VK_EXECUTE
, VK_INSERT
, 0, 0, 0, 0, /* FF60 */
49 VK_CANCEL
, VK_HELP
, VK_CANCEL
, VK_MENU
/* FF68 */
54 VK_MENU
, VK_NUMLOCK
, /* FF7E */
55 0, 0, 0, 0, 0, 0, 0, 0, /* FF80 */
56 0, 0, 0, 0, 0, VK_RETURN
, 0, 0, /* FF88 */
57 0, 0, 0, 0, 0, 0, 0, 0, /* FF90 */
58 0, 0, 0, 0, 0, 0, 0, 0, /* FF98 */
59 0, 0, 0, 0, 0, 0, 0, 0, /* FFA0 */
60 0, 0, VK_MULTIPLY
, VK_ADD
, VK_SEPARATOR
, VK_SUBTRACT
,
61 VK_DECIMAL
, VK_DIVIDE
, /* FFA8 */
62 VK_NUMPAD0
, VK_NUMPAD1
, VK_NUMPAD2
, VK_NUMPAD3
, VK_NUMPAD4
,
63 VK_NUMPAD5
, VK_NUMPAD6
, VK_NUMPAD7
, /* FFB0 */
64 VK_NUMPAD8
, VK_NUMPAD9
/* FFB8 */
67 static function_key
[] =
69 VK_F1
, VK_F2
, /* FFBE */
70 VK_F3
, VK_F4
, VK_F5
, VK_F6
, VK_F7
, VK_F8
, VK_F9
, VK_F10
, /* FFC0 */
71 VK_F11
, VK_F12
, VK_F13
, VK_F14
, VK_F15
, VK_F16
/* FFC8 */
74 static modifier_key
[] =
76 VK_SHIFT
, VK_SHIFT
, VK_CONTROL
, VK_CONTROL
, VK_CAPITAL
,
78 0, VK_MENU
, VK_MENU
/* FFE8 */
85 unsigned long count
: 16;
86 unsigned long code
: 8;
87 unsigned long extended
: 1;
89 unsigned long context
: 1;
90 unsigned long previous
: 1;
91 unsigned long transition
: 1;
96 static BOOL KeyDown
= FALSE
;
100 static char *event_names
[] =
102 "", "", "KeyPress", "KeyRelease", "ButtonPress", "ButtonRelease",
103 "MotionNotify", "EnterNotify", "LeaveNotify", "FocusIn", "FocusOut",
104 "KeymapNotify", "Expose", "GraphicsExpose", "NoExpose", "VisibilityNotify",
105 "CreateNotify", "DestroyNotify", "UnmapNotify", "MapNotify", "MapRequest",
106 "ReparentNotify", "ConfigureNotify", "ConfigureRequest", "GravityNotify",
107 "ResizeRequest", "CirculateNotify", "CirculateRequest", "PropertyNotify",
108 "SelectionClear", "SelectionRequest", "SelectionNotify", "ColormapNotify",
109 "ClientMessage", "MappingNotify"
114 static void EVENT_key( HWND hwnd
, XKeyEvent
*event
);
115 static void EVENT_ButtonPress( HWND hwnd
, XButtonEvent
*event
);
116 static void EVENT_ButtonRelease( HWND hwnd
, XButtonEvent
*event
);
117 static void EVENT_MotionNotify( HWND hwnd
, XMotionEvent
*event
);
118 static void EVENT_EnterNotify( HWND hwnd
, XCrossingEvent
*event
);
119 static void EVENT_FocusIn( HWND hwnd
, XFocusChangeEvent
*event
);
120 static void EVENT_FocusOut( HWND hwnd
, XFocusChangeEvent
*event
);
121 static void EVENT_Expose( HWND hwnd
, XExposeEvent
*event
);
124 /***********************************************************************
127 * Process an X event.
129 void EVENT_ProcessEvent( XEvent
*event
)
134 XFindContext( display
, ((XAnyEvent
*)event
)->window
, winContext
, &ptr
);
135 hwnd
= (HWND
) (int)ptr
;
138 printf( "Got event %s for hwnd %d\n", event_names
[event
->type
], hwnd
);
145 EVENT_key( hwnd
, (XKeyEvent
*)event
);
149 EVENT_ButtonPress( hwnd
, (XButtonEvent
*)event
);
153 EVENT_ButtonRelease( hwnd
, (XButtonEvent
*)event
);
157 EVENT_MotionNotify( hwnd
, (XMotionEvent
*)event
);
161 EVENT_EnterNotify( hwnd
, (XCrossingEvent
*)event
);
165 EVENT_FocusIn( hwnd
, (XFocusChangeEvent
*)event
);
169 EVENT_FocusOut( hwnd
, (XFocusChangeEvent
*)event
);
173 EVENT_Expose( hwnd
, (XExposeEvent
*)event
);
178 printf( "Unprocessed event %s for hwnd %d\n",
179 event_names
[event
->type
], hwnd
);
186 /***********************************************************************
187 * EVENT_RegisterWindow
189 * Associate an X window to a HWND.
191 void EVENT_RegisterWindow( Window w
, HWND hwnd
)
193 if (!winContext
) winContext
= XUniqueContext();
194 XSaveContext( display
, w
, winContext
, (XPointer
)(int)hwnd
);
198 /***********************************************************************
199 * EVENT_XStateToKeyState
201 * Translate a X event state (Button1Mask, ShiftMask, etc...) to
202 * a Windows key state (MK_SHIFT, MK_CONTROL, etc...)
204 static WORD
EVENT_XStateToKeyState( int state
)
208 if (state
& Button1Mask
) kstate
|= MK_LBUTTON
;
209 if (state
& Button2Mask
) kstate
|= MK_MBUTTON
;
210 if (state
& Button3Mask
) kstate
|= MK_RBUTTON
;
211 if (state
& ShiftMask
) kstate
|= MK_SHIFT
;
212 if (state
& ControlMask
) kstate
|= MK_CONTROL
;
217 /***********************************************************************
220 static void EVENT_Expose( HWND hwnd
, XExposeEvent
*event
)
223 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
225 /* Make position relative to client area instead of window */
226 rect
.left
= event
->x
- (wndPtr
->rectClient
.left
- wndPtr
->rectWindow
.left
);
227 rect
.top
= event
->y
- (wndPtr
->rectClient
.top
- wndPtr
->rectWindow
.top
);
228 rect
.right
= rect
.left
+ event
->width
;
229 rect
.bottom
= rect
.top
+ event
->height
;
230 winHasCursor
= event
->window
;
232 InvalidateRect( hwnd
, &rect
, TRUE
);
236 /***********************************************************************
239 * Handle a X key event
241 static void EVENT_key( HWND hwnd
, XKeyEvent
*event
)
246 WORD xkey
, vkey
, key_type
, key
;
248 BOOL extended
= FALSE
;
249 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
250 int count
= XLookupString(event
, Str
, 1, &keysym
, &cs
);
253 printf("WM_KEY??? : keysym=%lX, count=%u / %X / '%s'\n",
254 keysym
, count
, Str
[0], Str
);
257 if (wndPtr
->dwStyle
& WS_DISABLED
) {
258 if (event
->type
== KeyPress
) XBell(display
, 0);
263 xkey
= LOWORD(keysym
);
264 key_type
= HIBYTE(xkey
);
267 printf(" key_type=%X, key=%X\n", key_type
, key
);
270 /* Position must be relative to client area */
271 event
->x
-= wndPtr
->rectClient
.left
- wndPtr
->rectWindow
.left
;
272 event
->y
-= wndPtr
->rectClient
.top
- wndPtr
->rectWindow
.top
;
274 if (key_type
== 0xFF) /* non-character key */
276 if (key
>= 0x08 && key
<= 0x1B) /* special key */
277 vkey
= special_key
[key
- 0x08];
278 else if (key
>= 0x50 && key
<= 0x57) /* cursor key */
279 vkey
= cursor_key
[key
- 0x50];
280 else if (key
>= 0x60 && key
<= 0x6B) /* miscellaneous key */
281 vkey
= misc_key
[key
- 0x60];
282 else if (key
>= 0x7E && key
<= 0xB9) /* keypad key */
284 vkey
= keypad_key
[key
- 0x7E];
287 else if (key
>= 0xBE && key
<= 0xCD) /* function key */
289 vkey
= function_key
[key
- 0xBE];
292 else if (key
>= 0xE1 && key
<= 0xEA) /* modifier key */
293 vkey
= modifier_key
[key
- 0xE1];
294 else if (key
== 0xFF) /* DEL key */
297 else if (key_type
== 0) /* character key */
299 if (key
>= 0x61 && key
<= 0x7A)
300 vkey
= key
- 0x20; /* convert lower to uppercase */
305 if (event
->type
== KeyPress
)
307 if (vkey
== VK_MENU
) ALTKeyState
= TRUE
;
309 keylp
.lp1
.code
= LOBYTE(event
->keycode
);
310 keylp
.lp1
.extended
= (extended
? 1 : 0);
311 keylp
.lp1
.context
= (event
->state
& Mod1Mask
? 1 : 0);
312 keylp
.lp1
.previous
= (KeyDown
? 0 : 1);
313 keylp
.lp1
.transition
= 0;
315 printf(" wParam=%X, lParam=%lX\n", vkey
, keylp
.lp2
);
317 hardware_event( hwnd
, ALTKeyState
? WM_SYSKEYDOWN
: WM_KEYDOWN
,
319 event
->x_root
& 0xffff, event
->y_root
& 0xffff,
323 /* The key translation ought to take place in TranslateMessage().
324 * However, there is no way of passing the required information
325 * in a Windows message, so TranslateMessage does not currently
326 * do anything and the translation is done here.
328 if (count
== 1) /* key has an ASCII representation */
331 printf("WM_CHAR : wParam=%X\n", (WORD
)Str
[0] );
333 PostMessage( hwnd
, WM_CHAR
, (WORD
)Str
[0], keylp
.lp2
);
338 if (vkey
== VK_MENU
) ALTKeyState
= FALSE
;
340 keylp
.lp1
.code
= LOBYTE(event
->keycode
);
341 keylp
.lp1
.extended
= (extended
? 1 : 0);
342 keylp
.lp1
.context
= (event
->state
& Mod1Mask
? 1 : 0);
343 keylp
.lp1
.previous
= 1;
344 keylp
.lp1
.transition
= 1;
346 printf(" wParam=%X, lParam=%lX\n", vkey
, keylp
.lp2
);
348 hardware_event( hwnd
,
349 ((ALTKeyState
|| vkey
== VK_MENU
) ?
350 WM_SYSKEYUP
: WM_KEYUP
),
352 event
->x_root
& 0xffff, event
->y_root
& 0xffff,
359 /***********************************************************************
362 static void EVENT_MotionNotify( HWND hwnd
, XMotionEvent
*event
)
364 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
367 if (wndPtr
->dwStyle
& WS_DISABLED
) {
372 hardware_event( hwnd
, WM_MOUSEMOVE
,
373 EVENT_XStateToKeyState( event
->state
), 0L,
374 event
->x_root
& 0xffff, event
->y_root
& 0xffff,
379 /***********************************************************************
382 static void EVENT_ButtonPress( HWND hwnd
, XButtonEvent
*event
)
384 static WORD messages
[NB_BUTTONS
] =
385 { WM_LBUTTONDOWN
, WM_MBUTTONDOWN
, WM_RBUTTONDOWN
};
386 int buttonNum
= event
->button
- 1;
387 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
390 printf("couldn't find window\n");
393 if (wndPtr
->dwStyle
& WS_DISABLED
) {
400 if (buttonNum
>= NB_BUTTONS
) return;
401 winHasCursor
= event
->window
;
402 hardware_event( hwnd
, messages
[buttonNum
],
403 EVENT_XStateToKeyState( event
->state
), 0L,
404 event
->x_root
& 0xffff, event
->y_root
& 0xffff,
409 /***********************************************************************
410 * EVENT_ButtonRelease
412 static void EVENT_ButtonRelease( HWND hwnd
, XButtonEvent
*event
)
414 static const WORD messages
[NB_BUTTONS
] =
415 { WM_LBUTTONUP
, WM_MBUTTONUP
, WM_RBUTTONUP
};
416 int buttonNum
= event
->button
- 1;
417 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
420 if (wndPtr
->dwStyle
& WS_DISABLED
) {
425 if (buttonNum
>= NB_BUTTONS
) return;
426 winHasCursor
= event
->window
;
427 hardware_event( hwnd
, messages
[buttonNum
],
428 EVENT_XStateToKeyState( event
->state
), 0L,
429 event
->x_root
& 0xffff, event
->y_root
& 0xffff,
434 /**********************************************************************
437 static void EVENT_FocusIn( HWND hwnd
, XFocusChangeEvent
*event
)
440 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
443 if (wndPtr
->dwStyle
& WS_DISABLED
) {
448 PostMessage( hwnd
, WM_SETFOCUS
, hwnd
, 0 );
453 /**********************************************************************
456 static void EVENT_FocusOut( HWND hwnd
, XFocusChangeEvent
*event
)
458 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
461 if (hwnd
== GetActiveWindow()) WINPOS_ChangeActiveWindow( 0, FALSE
);
463 if (wndPtr
->dwStyle
& WS_DISABLED
) {
469 PostMessage( hwnd
, WM_KILLFOCUS
, hwnd
, 0 );
475 /**********************************************************************
478 static void EVENT_EnterNotify( HWND hwnd
, XCrossingEvent
*event
)
480 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
483 if (wndPtr
->dwStyle
& WS_DISABLED
) {
487 if (captureWnd
!= 0) return;
488 winHasCursor
= event
->window
;
489 /* Simulate a mouse motion to set the correct cursor */
490 hardware_event( hwnd
, WM_MOUSEMOVE
,
491 EVENT_XStateToKeyState( event
->state
), 0L,
492 event
->x_root
& 0xffff, event
->y_root
& 0xffff,
497 /**********************************************************************
498 * SetCapture (USER.18)
500 HWND
SetCapture(HWND wnd
)
503 HWND old_capture_wnd
= captureWnd
;
504 WND
*wnd_p
= WIN_FindWndPtr(wnd
);
508 rv
= XGrabPointer(display
, wnd_p
->window
, False
,
509 ButtonPressMask
| ButtonReleaseMask
| PointerMotionMask
,
510 GrabModeAsync
, GrabModeAsync
, None
, None
, CurrentTime
);
512 if (rv
== GrabSuccess
)
515 return old_capture_wnd
;
521 /**********************************************************************
522 * ReleaseCapture (USER.19)
524 void ReleaseCapture()
531 wnd_p
= WIN_FindWndPtr(captureWnd
);
535 XUngrabPointer( display
, CurrentTime
);
539 /**********************************************************************
540 * GetCapture (USER.236)