2 * X events handling functions
4 * Copyright 1993 Alexandre Julliard
7 static char Copyright
[] = "Copyright Alexandre Julliard, 1993";
10 #include <X11/Xresource.h>
11 #include <X11/Xutil.h>
19 typedef char *XPointer
;
22 #define NB_BUTTONS 3 /* Windows can handle 3 buttons */
24 extern Display
* display
;
26 extern void WINPOS_ChangeActiveWindow( HWND hwnd
, BOOL mouseMsg
); /*winpos.c*/
28 /* X context to associate a hwnd to an X window */
29 static XContext winContext
= 0;
32 static WORD ALTKeyState
;
33 static HWND captureWnd
= 0;
34 Window winHasCursor
= 0;
35 extern HWND hWndFocus
;
37 /* Keyboard translation tables */
38 static int special_key
[] =
40 VK_BACK
, VK_TAB
, 0, VK_CLEAR
, 0, VK_RETURN
, 0, 0, /* FF08 */
41 0, 0, 0, VK_PAUSE
, VK_SCROLL
, 0, 0, 0, /* FF10 */
42 0, 0, 0, VK_ESCAPE
/* FF18 */
47 VK_HOME
, VK_LEFT
, VK_UP
, VK_RIGHT
, VK_DOWN
, VK_PRIOR
,
48 VK_NEXT
, VK_END
/* FF50 */
53 VK_SELECT
, VK_SNAPSHOT
, VK_EXECUTE
, VK_INSERT
, 0, 0, 0, 0, /* FF60 */
54 VK_CANCEL
, VK_HELP
, VK_CANCEL
, VK_MENU
/* FF68 */
59 VK_MENU
, VK_NUMLOCK
, /* FF7E */
60 0, 0, 0, 0, 0, 0, 0, 0, /* FF80 */
61 0, 0, 0, 0, 0, VK_RETURN
, 0, 0, /* FF88 */
62 0, 0, 0, 0, 0, 0, 0, 0, /* FF90 */
63 0, 0, 0, 0, 0, 0, 0, 0, /* FF98 */
64 0, 0, 0, 0, 0, 0, 0, 0, /* FFA0 */
65 0, 0, VK_MULTIPLY
, VK_ADD
, VK_SEPARATOR
, VK_SUBTRACT
,
66 VK_DECIMAL
, VK_DIVIDE
, /* FFA8 */
67 VK_NUMPAD0
, VK_NUMPAD1
, VK_NUMPAD2
, VK_NUMPAD3
, VK_NUMPAD4
,
68 VK_NUMPAD5
, VK_NUMPAD6
, VK_NUMPAD7
, /* FFB0 */
69 VK_NUMPAD8
, VK_NUMPAD9
/* FFB8 */
72 static function_key
[] =
74 VK_F1
, VK_F2
, /* FFBE */
75 VK_F3
, VK_F4
, VK_F5
, VK_F6
, VK_F7
, VK_F8
, VK_F9
, VK_F10
, /* FFC0 */
76 VK_F11
, VK_F12
, VK_F13
, VK_F14
, VK_F15
, VK_F16
/* FFC8 */
79 static modifier_key
[] =
81 VK_SHIFT
, VK_SHIFT
, VK_CONTROL
, VK_CONTROL
, VK_CAPITAL
,
83 0, VK_MENU
, VK_MENU
/* FFE8 */
90 unsigned long count
: 16;
91 unsigned long code
: 8;
92 unsigned long extended
: 1;
94 unsigned long context
: 1;
95 unsigned long previous
: 1;
96 unsigned long transition
: 1;
101 static BOOL KeyDown
= FALSE
;
105 static char *event_names
[] =
107 "", "", "KeyPress", "KeyRelease", "ButtonPress", "ButtonRelease",
108 "MotionNotify", "EnterNotify", "LeaveNotify", "FocusIn", "FocusOut",
109 "KeymapNotify", "Expose", "GraphicsExpose", "NoExpose", "VisibilityNotify",
110 "CreateNotify", "DestroyNotify", "UnmapNotify", "MapNotify", "MapRequest",
111 "ReparentNotify", "ConfigureNotify", "ConfigureRequest", "GravityNotify",
112 "ResizeRequest", "CirculateNotify", "CirculateRequest", "PropertyNotify",
113 "SelectionClear", "SelectionRequest", "SelectionNotify", "ColormapNotify",
114 "ClientMessage", "MappingNotify"
119 static void EVENT_key( HWND hwnd
, XKeyEvent
*event
);
120 static void EVENT_ButtonPress( HWND hwnd
, XButtonEvent
*event
);
121 static void EVENT_ButtonRelease( HWND hwnd
, XButtonEvent
*event
);
122 static void EVENT_MotionNotify( HWND hwnd
, XMotionEvent
*event
);
123 static void EVENT_EnterNotify( HWND hwnd
, XCrossingEvent
*event
);
124 static void EVENT_FocusIn( HWND hwnd
, XFocusChangeEvent
*event
);
125 static void EVENT_FocusOut( HWND hwnd
, XFocusChangeEvent
*event
);
126 static void EVENT_Expose( HWND hwnd
, XExposeEvent
*event
);
129 /***********************************************************************
132 * Process an X event.
134 void EVENT_ProcessEvent( XEvent
*event
)
139 XFindContext( display
, ((XAnyEvent
*)event
)->window
, winContext
, &ptr
);
140 hwnd
= (HWND
) (int)ptr
;
143 printf( "Got event %s for hwnd %d\n", event_names
[event
->type
], hwnd
);
150 EVENT_key( hwnd
, (XKeyEvent
*)event
);
154 EVENT_ButtonPress( hwnd
, (XButtonEvent
*)event
);
158 EVENT_ButtonRelease( hwnd
, (XButtonEvent
*)event
);
162 EVENT_MotionNotify( hwnd
, (XMotionEvent
*)event
);
166 EVENT_EnterNotify( hwnd
, (XCrossingEvent
*)event
);
170 EVENT_FocusIn( hwnd
, (XFocusChangeEvent
*)event
);
174 EVENT_FocusOut( hwnd
, (XFocusChangeEvent
*)event
);
178 EVENT_Expose( hwnd
, (XExposeEvent
*)event
);
183 printf( "Unprocessed event %s for hwnd %d\n",
184 event_names
[event
->type
], hwnd
);
191 /***********************************************************************
192 * EVENT_RegisterWindow
194 * Associate an X window to a HWND.
196 void EVENT_RegisterWindow( Window w
, HWND hwnd
)
198 if (!winContext
) winContext
= XUniqueContext();
199 XSaveContext( display
, w
, winContext
, (XPointer
)(int)hwnd
);
203 /***********************************************************************
204 * EVENT_XStateToKeyState
206 * Translate a X event state (Button1Mask, ShiftMask, etc...) to
207 * a Windows key state (MK_SHIFT, MK_CONTROL, etc...)
209 static WORD
EVENT_XStateToKeyState( int state
)
213 if (state
& Button1Mask
) kstate
|= MK_LBUTTON
;
214 if (state
& Button2Mask
) kstate
|= MK_MBUTTON
;
215 if (state
& Button3Mask
) kstate
|= MK_RBUTTON
;
216 if (state
& ShiftMask
) kstate
|= MK_SHIFT
;
217 if (state
& ControlMask
) kstate
|= MK_CONTROL
;
222 /***********************************************************************
225 static void EVENT_Expose( HWND hwnd
, XExposeEvent
*event
)
228 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
230 /* Make position relative to client area instead of window */
231 rect
.left
= event
->x
- (wndPtr
->rectClient
.left
- wndPtr
->rectWindow
.left
);
232 rect
.top
= event
->y
- (wndPtr
->rectClient
.top
- wndPtr
->rectWindow
.top
);
233 rect
.right
= rect
.left
+ event
->width
;
234 rect
.bottom
= rect
.top
+ event
->height
;
235 winHasCursor
= event
->window
;
237 RedrawWindow( hwnd
, &rect
, 0,
238 RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
| RDW_NOCHILDREN
);
242 /***********************************************************************
245 * Handle a X key event
247 static void EVENT_key( HWND hwnd
, XKeyEvent
*event
)
252 WORD xkey
, vkey
, key_type
, key
;
254 BOOL extended
= FALSE
;
255 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
256 int count
= XLookupString(event
, Str
, 1, &keysym
, &cs
);
259 printf("WM_KEY??? : keysym=%lX, count=%u / %X / '%s'\n",
260 keysym
, count
, Str
[0], Str
);
263 if (wndPtr
->dwStyle
& WS_DISABLED
) {
264 if (event
->type
== KeyPress
) XBell(display
, 0);
269 xkey
= LOWORD(keysym
);
270 key_type
= HIBYTE(xkey
);
273 printf(" key_type=%X, key=%X\n", key_type
, key
);
276 /* Position must be relative to client area */
277 event
->x
-= wndPtr
->rectClient
.left
- wndPtr
->rectWindow
.left
;
278 event
->y
-= wndPtr
->rectClient
.top
- wndPtr
->rectWindow
.top
;
280 if (key_type
== 0xFF) /* non-character key */
282 if (key
>= 0x08 && key
<= 0x1B) /* special key */
283 vkey
= special_key
[key
- 0x08];
284 else if (key
>= 0x50 && key
<= 0x57) /* cursor key */
285 vkey
= cursor_key
[key
- 0x50];
286 else if (key
>= 0x60 && key
<= 0x6B) /* miscellaneous key */
287 vkey
= misc_key
[key
- 0x60];
288 else if (key
>= 0x7E && key
<= 0xB9) /* keypad key */
290 vkey
= keypad_key
[key
- 0x7E];
293 else if (key
>= 0xBE && key
<= 0xCD) /* function key */
295 vkey
= function_key
[key
- 0xBE];
298 else if (key
>= 0xE1 && key
<= 0xEA) /* modifier key */
299 vkey
= modifier_key
[key
- 0xE1];
300 else if (key
== 0xFF) /* DEL key */
303 else if (key_type
== 0) /* character key */
305 if (key
>= 0x61 && key
<= 0x7A)
306 vkey
= key
- 0x20; /* convert lower to uppercase */
311 if (event
->type
== KeyPress
)
313 if (vkey
== VK_MENU
) ALTKeyState
= TRUE
;
315 keylp
.lp1
.code
= LOBYTE(event
->keycode
);
316 keylp
.lp1
.extended
= (extended
? 1 : 0);
317 keylp
.lp1
.context
= (event
->state
& Mod1Mask
? 1 : 0);
318 keylp
.lp1
.previous
= (KeyDown
? 0 : 1);
319 keylp
.lp1
.transition
= 0;
321 printf(" wParam=%X, lParam=%lX\n", vkey
, keylp
.lp2
);
323 hardware_event( hwnd
, ALTKeyState
? WM_SYSKEYDOWN
: WM_KEYDOWN
,
325 event
->x_root
& 0xffff, event
->y_root
& 0xffff,
329 /* The key translation ought to take place in TranslateMessage().
330 * However, there is no way of passing the required information
331 * in a Windows message, so TranslateMessage does not currently
332 * do anything and the translation is done here.
334 if (count
== 1) /* key has an ASCII representation */
337 printf("WM_CHAR : wParam=%X\n", (WORD
)Str
[0] );
339 PostMessage( hwnd
, WM_CHAR
, (WORD
)Str
[0], keylp
.lp2
);
344 if (vkey
== VK_MENU
) ALTKeyState
= FALSE
;
346 keylp
.lp1
.code
= LOBYTE(event
->keycode
);
347 keylp
.lp1
.extended
= (extended
? 1 : 0);
348 keylp
.lp1
.context
= (event
->state
& Mod1Mask
? 1 : 0);
349 keylp
.lp1
.previous
= 1;
350 keylp
.lp1
.transition
= 1;
352 printf(" wParam=%X, lParam=%lX\n", vkey
, keylp
.lp2
);
354 hardware_event( hwnd
,
355 ((ALTKeyState
|| vkey
== VK_MENU
) ?
356 WM_SYSKEYUP
: WM_KEYUP
),
358 event
->x_root
& 0xffff, event
->y_root
& 0xffff,
365 /***********************************************************************
368 static void EVENT_MotionNotify( HWND hwnd
, XMotionEvent
*event
)
370 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
373 if (wndPtr
->dwStyle
& WS_DISABLED
) {
378 hardware_event( hwnd
, WM_MOUSEMOVE
,
379 EVENT_XStateToKeyState( event
->state
), 0L,
380 event
->x_root
& 0xffff, event
->y_root
& 0xffff,
385 /***********************************************************************
388 static void EVENT_ButtonPress( HWND hwnd
, XButtonEvent
*event
)
390 static WORD messages
[NB_BUTTONS
] =
391 { WM_LBUTTONDOWN
, WM_MBUTTONDOWN
, WM_RBUTTONDOWN
};
392 int buttonNum
= event
->button
- 1;
393 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
396 printf("couldn't find window\n");
399 if (wndPtr
->dwStyle
& WS_DISABLED
) {
406 if (buttonNum
>= NB_BUTTONS
) return;
407 winHasCursor
= event
->window
;
408 hardware_event( hwnd
, messages
[buttonNum
],
409 EVENT_XStateToKeyState( event
->state
), 0L,
410 event
->x_root
& 0xffff, event
->y_root
& 0xffff,
415 /***********************************************************************
416 * EVENT_ButtonRelease
418 static void EVENT_ButtonRelease( HWND hwnd
, XButtonEvent
*event
)
420 static const WORD messages
[NB_BUTTONS
] =
421 { WM_LBUTTONUP
, WM_MBUTTONUP
, WM_RBUTTONUP
};
422 int buttonNum
= event
->button
- 1;
423 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
426 if (wndPtr
->dwStyle
& WS_DISABLED
) {
431 if (buttonNum
>= NB_BUTTONS
) return;
432 winHasCursor
= event
->window
;
433 hardware_event( hwnd
, messages
[buttonNum
],
434 EVENT_XStateToKeyState( event
->state
), 0L,
435 event
->x_root
& 0xffff, event
->y_root
& 0xffff,
440 /**********************************************************************
443 static void EVENT_FocusIn( HWND hwnd
, XFocusChangeEvent
*event
)
446 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
449 if (wndPtr
->dwStyle
& WS_DISABLED
) {
454 PostMessage( hwnd
, WM_SETFOCUS
, hwnd
, 0 );
459 /**********************************************************************
462 static void EVENT_FocusOut( HWND hwnd
, XFocusChangeEvent
*event
)
464 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
467 if (hwnd
== GetActiveWindow()) WINPOS_ChangeActiveWindow( 0, FALSE
);
469 if (wndPtr
->dwStyle
& WS_DISABLED
) {
475 PostMessage( hwnd
, WM_KILLFOCUS
, hwnd
, 0 );
481 /**********************************************************************
484 static void EVENT_EnterNotify( HWND hwnd
, XCrossingEvent
*event
)
486 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
489 if (wndPtr
->dwStyle
& WS_DISABLED
) {
493 if (captureWnd
!= 0) return;
494 winHasCursor
= event
->window
;
495 /* Simulate a mouse motion to set the correct cursor */
496 hardware_event( hwnd
, WM_MOUSEMOVE
,
497 EVENT_XStateToKeyState( event
->state
), 0L,
498 event
->x_root
& 0xffff, event
->y_root
& 0xffff,
503 /**********************************************************************
504 * SetCapture (USER.18)
506 HWND
SetCapture(HWND wnd
)
509 HWND old_capture_wnd
= captureWnd
;
510 WND
*wnd_p
= WIN_FindWndPtr(wnd
);
514 rv
= XGrabPointer(display
, wnd_p
->window
, False
,
515 ButtonPressMask
| ButtonReleaseMask
| PointerMotionMask
,
516 GrabModeAsync
, GrabModeAsync
, None
, None
, CurrentTime
);
518 if (rv
== GrabSuccess
)
521 return old_capture_wnd
;
527 /**********************************************************************
528 * ReleaseCapture (USER.19)
530 void ReleaseCapture()
537 wnd_p
= WIN_FindWndPtr(captureWnd
);
541 XUngrabPointer( display
, CurrentTime
);
545 /**********************************************************************
546 * GetCapture (USER.236)