2 * X events handling functions
4 * Copyright 1993 Alexandre Julliard
7 static char Copyright
[] = "Copyright Alexandre Julliard, 1993";
12 #include <X11/Xresource.h>
13 #include <X11/Xutil.h>
21 typedef char *XPointer
;
24 #define NB_BUTTONS 3 /* Windows can handle 3 buttons */
26 extern int desktopX
, desktopY
; /* misc/main.c */
28 extern void WINPOS_ChangeActiveWindow( HWND hwnd
, BOOL mouseMsg
); /*winpos.c*/
30 /* X context to associate a hwnd to an X window */
31 static XContext winContext
= 0;
34 BOOL MouseButtonsStates
[NB_BUTTONS
] = { FALSE
, FALSE
, FALSE
};
35 static WORD ALTKeyState
;
36 static HWND captureWnd
= 0;
37 Window winHasCursor
= 0;
39 /* Keyboard translation tables */
40 static int special_key
[] =
42 VK_BACK
, VK_TAB
, 0, VK_CLEAR
, 0, VK_RETURN
, 0, 0, /* FF08 */
43 0, 0, 0, VK_PAUSE
, VK_SCROLL
, 0, 0, 0, /* FF10 */
44 0, 0, 0, VK_ESCAPE
/* FF18 */
49 VK_HOME
, VK_LEFT
, VK_UP
, VK_RIGHT
, VK_DOWN
, VK_PRIOR
,
50 VK_NEXT
, VK_END
/* FF50 */
55 VK_SELECT
, VK_SNAPSHOT
, VK_EXECUTE
, VK_INSERT
, 0, 0, 0, 0, /* FF60 */
56 VK_CANCEL
, VK_HELP
, VK_CANCEL
, VK_MENU
/* FF68 */
61 VK_MENU
, VK_NUMLOCK
, /* FF7E */
62 0, 0, 0, 0, 0, 0, 0, 0, /* FF80 */
63 0, 0, 0, 0, 0, VK_RETURN
, 0, 0, /* FF88 */
64 0, 0, 0, 0, 0, 0, 0, 0, /* FF90 */
65 0, 0, 0, 0, 0, 0, 0, 0, /* FF98 */
66 0, 0, 0, 0, 0, 0, 0, 0, /* FFA0 */
67 0, 0, VK_MULTIPLY
, VK_ADD
, VK_SEPARATOR
, VK_SUBTRACT
,
68 VK_DECIMAL
, VK_DIVIDE
, /* FFA8 */
69 VK_NUMPAD0
, VK_NUMPAD1
, VK_NUMPAD2
, VK_NUMPAD3
, VK_NUMPAD4
,
70 VK_NUMPAD5
, VK_NUMPAD6
, VK_NUMPAD7
, /* FFB0 */
71 VK_NUMPAD8
, VK_NUMPAD9
/* FFB8 */
74 static function_key
[] =
76 VK_F1
, VK_F2
, /* FFBE */
77 VK_F3
, VK_F4
, VK_F5
, VK_F6
, VK_F7
, VK_F8
, VK_F9
, VK_F10
, /* FFC0 */
78 VK_F11
, VK_F12
, VK_F13
, VK_F14
, VK_F15
, VK_F16
/* FFC8 */
81 static modifier_key
[] =
83 VK_SHIFT
, VK_SHIFT
, VK_CONTROL
, VK_CONTROL
, VK_CAPITAL
,
85 0, VK_MENU
, VK_MENU
/* FFE8 */
92 unsigned long count
: 16;
93 unsigned long code
: 8;
94 unsigned long extended
: 1;
96 unsigned long context
: 1;
97 unsigned long previous
: 1;
98 unsigned long transition
: 1;
103 static BOOL KeyDown
= FALSE
;
107 static char *event_names
[] =
109 "", "", "KeyPress", "KeyRelease", "ButtonPress", "ButtonRelease",
110 "MotionNotify", "EnterNotify", "LeaveNotify", "FocusIn", "FocusOut",
111 "KeymapNotify", "Expose", "GraphicsExpose", "NoExpose", "VisibilityNotify",
112 "CreateNotify", "DestroyNotify", "UnmapNotify", "MapNotify", "MapRequest",
113 "ReparentNotify", "ConfigureNotify", "ConfigureRequest", "GravityNotify",
114 "ResizeRequest", "CirculateNotify", "CirculateRequest", "PropertyNotify",
115 "SelectionClear", "SelectionRequest", "SelectionNotify", "ColormapNotify",
116 "ClientMessage", "MappingNotify"
121 static void EVENT_key( HWND hwnd
, XKeyEvent
*event
);
122 static void EVENT_ButtonPress( XButtonEvent
*event
);
123 static void EVENT_ButtonRelease( XButtonEvent
*event
);
124 static void EVENT_MotionNotify( XMotionEvent
*event
);
125 static void EVENT_EnterNotify( XCrossingEvent
*event
);
126 static void EVENT_FocusOut( HWND hwnd
, XFocusChangeEvent
*event
);
127 static void EVENT_Expose( HWND hwnd
, XExposeEvent
*event
);
128 static void EVENT_ConfigureNotify( HWND hwnd
, XConfigureEvent
*event
);
131 /***********************************************************************
134 * Process an X event.
136 void EVENT_ProcessEvent( XEvent
*event
)
141 XFindContext( display
, ((XAnyEvent
*)event
)->window
, winContext
, &ptr
);
142 hwnd
= (HWND
) (int)ptr
;
145 printf( "Got event %s for hwnd %d\n", event_names
[event
->type
], hwnd
);
152 EVENT_key( hwnd
, (XKeyEvent
*)event
);
156 EVENT_ButtonPress( (XButtonEvent
*)event
);
160 EVENT_ButtonRelease( (XButtonEvent
*)event
);
164 EVENT_MotionNotify( (XMotionEvent
*)event
);
168 EVENT_EnterNotify( (XCrossingEvent
*)event
);
172 EVENT_FocusOut( hwnd
, (XFocusChangeEvent
*)event
);
176 EVENT_Expose( hwnd
, (XExposeEvent
*)event
);
179 case ConfigureNotify
:
180 EVENT_ConfigureNotify( hwnd
, (XConfigureEvent
*)event
);
185 printf( "Unprocessed event %s for hwnd %d\n",
186 event_names
[event
->type
], hwnd
);
193 /***********************************************************************
194 * EVENT_RegisterWindow
196 * Associate an X window to a HWND.
198 void EVENT_RegisterWindow( Window w
, HWND hwnd
)
200 if (!winContext
) winContext
= XUniqueContext();
201 XSaveContext( display
, w
, winContext
, (XPointer
)(int)hwnd
);
205 /***********************************************************************
206 * EVENT_XStateToKeyState
208 * Translate a X event state (Button1Mask, ShiftMask, etc...) to
209 * a Windows key state (MK_SHIFT, MK_CONTROL, etc...)
211 static WORD
EVENT_XStateToKeyState( int state
)
215 if (state
& Button1Mask
) kstate
|= MK_LBUTTON
;
216 if (state
& Button2Mask
) kstate
|= MK_MBUTTON
;
217 if (state
& Button3Mask
) kstate
|= MK_RBUTTON
;
218 if (state
& ShiftMask
) kstate
|= MK_SHIFT
;
219 if (state
& ControlMask
) kstate
|= MK_CONTROL
;
224 /***********************************************************************
227 static void EVENT_Expose( HWND hwnd
, XExposeEvent
*event
)
231 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
234 /* Make position relative to client area instead of window */
235 rect
.left
= event
->x
- (wndPtr
->rectClient
.left
- wndPtr
->rectWindow
.left
);
236 rect
.top
= event
->y
- (wndPtr
->rectClient
.top
- wndPtr
->rectWindow
.top
);
237 rect
.right
= rect
.left
+ event
->width
;
238 rect
.bottom
= rect
.top
+ event
->height
;
239 winHasCursor
= event
->window
;
241 flags
= RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
;
242 /* Erase desktop background synchronously */
243 if (event
->window
== rootWindow
) flags
|= RDW_ERASENOW
| RDW_NOCHILDREN
;
244 RedrawWindow( hwnd
, &rect
, 0, flags
);
248 /***********************************************************************
251 * Handle a X key event
253 static void EVENT_key( HWND hwnd
, XKeyEvent
*event
)
258 WORD xkey
, vkey
, key_type
, key
;
260 BOOL extended
= FALSE
;
262 int count
= XLookupString(event
, Str
, 1, &keysym
, &cs
);
265 printf("WM_KEY??? : keysym=%lX, count=%u / %X / '%s'\n",
266 keysym
, count
, Str
[0], Str
);
269 xkey
= LOWORD(keysym
);
270 key_type
= HIBYTE(xkey
);
273 printf(" key_type=%X, key=%X\n", key_type
, key
);
276 if (key_type
== 0xFF) /* non-character key */
278 if (key
>= 0x08 && key
<= 0x1B) /* special key */
279 vkey
= special_key
[key
- 0x08];
280 else if (key
>= 0x50 && key
<= 0x57) /* cursor key */
281 vkey
= cursor_key
[key
- 0x50];
282 else if (key
>= 0x60 && key
<= 0x6B) /* miscellaneous key */
283 vkey
= misc_key
[key
- 0x60];
284 else if (key
>= 0x7E && key
<= 0xB9) /* keypad key */
286 vkey
= keypad_key
[key
- 0x7E];
289 else if (key
>= 0xBE && key
<= 0xCD) /* function key */
291 vkey
= function_key
[key
- 0xBE];
294 else if (key
>= 0xE1 && key
<= 0xEA) /* modifier key */
295 vkey
= modifier_key
[key
- 0xE1];
296 else if (key
== 0xFF) /* DEL key */
299 else if (key_type
== 0) /* character key */
301 if (key
>= 0x61 && key
<= 0x7A)
302 vkey
= key
- 0x20; /* convert lower to uppercase */
307 if (event
->type
== KeyPress
)
309 if (vkey
== VK_MENU
) ALTKeyState
= TRUE
;
311 keylp
.lp1
.code
= LOBYTE(event
->keycode
);
312 keylp
.lp1
.extended
= (extended
? 1 : 0);
313 keylp
.lp1
.context
= (event
->state
& Mod1Mask
? 1 : 0);
314 keylp
.lp1
.previous
= (KeyDown
? 0 : 1);
315 keylp
.lp1
.transition
= 0;
317 printf(" wParam=%X, lParam=%lX\n", vkey
, keylp
.lp2
);
319 hardware_event( ALTKeyState
? WM_SYSKEYDOWN
: WM_KEYDOWN
,
321 event
->x_root
- desktopX
, event
->y_root
- desktopY
,
325 /* The key translation ought to take place in TranslateMessage().
326 * However, there is no way of passing the required information
327 * in a Windows message, so TranslateMessage does not currently
328 * do anything and the translation is done here.
330 if (count
== 1) /* key has an ASCII representation */
333 printf("WM_CHAR : wParam=%X\n", (WORD
)Str
[0] );
335 PostMessage( hwnd
, WM_CHAR
, (WORD
)Str
[0], keylp
.lp2
);
340 if (vkey
== VK_MENU
) ALTKeyState
= FALSE
;
342 keylp
.lp1
.code
= LOBYTE(event
->keycode
);
343 keylp
.lp1
.extended
= (extended
? 1 : 0);
344 keylp
.lp1
.context
= (event
->state
& Mod1Mask
? 1 : 0);
345 keylp
.lp1
.previous
= 1;
346 keylp
.lp1
.transition
= 1;
348 printf(" wParam=%X, lParam=%lX\n", vkey
, keylp
.lp2
);
350 hardware_event( ((ALTKeyState
|| vkey
== VK_MENU
) ?
351 WM_SYSKEYUP
: WM_KEYUP
),
353 event
->x_root
- desktopX
, event
->y_root
- desktopY
,
360 /***********************************************************************
363 static void EVENT_MotionNotify( XMotionEvent
*event
)
365 hardware_event( WM_MOUSEMOVE
, EVENT_XStateToKeyState( event
->state
), 0L,
366 event
->x_root
- desktopX
, event
->y_root
- desktopY
,
371 /***********************************************************************
374 static void EVENT_ButtonPress( XButtonEvent
*event
)
376 static WORD messages
[NB_BUTTONS
] =
377 { WM_LBUTTONDOWN
, WM_MBUTTONDOWN
, WM_RBUTTONDOWN
};
378 int buttonNum
= event
->button
- 1;
380 if (buttonNum
>= NB_BUTTONS
) return;
381 MouseButtonsStates
[buttonNum
] = TRUE
;
382 winHasCursor
= event
->window
;
383 hardware_event( messages
[buttonNum
],
384 EVENT_XStateToKeyState( event
->state
), 0L,
385 event
->x_root
- desktopX
, event
->y_root
- desktopY
,
390 /***********************************************************************
391 * EVENT_ButtonRelease
393 static void EVENT_ButtonRelease( XButtonEvent
*event
)
395 static const WORD messages
[NB_BUTTONS
] =
396 { WM_LBUTTONUP
, WM_MBUTTONUP
, WM_RBUTTONUP
};
397 int buttonNum
= event
->button
- 1;
399 if (buttonNum
>= NB_BUTTONS
) return;
400 MouseButtonsStates
[buttonNum
] = FALSE
;
401 winHasCursor
= event
->window
;
402 hardware_event( messages
[buttonNum
],
403 EVENT_XStateToKeyState( event
->state
), 0L,
404 event
->x_root
- desktopX
, event
->y_root
- desktopY
,
409 /**********************************************************************
412 * Note: only top-level override-redirect windows get FocusOut events.
414 static void EVENT_FocusOut( HWND hwnd
, XFocusChangeEvent
*event
)
416 if (event
->detail
== NotifyPointer
) return;
417 if (hwnd
== GetActiveWindow()) WINPOS_ChangeActiveWindow( 0, FALSE
);
418 if ((hwnd
== GetFocus()) || IsChild( hwnd
, GetFocus())) SetFocus( 0 );
422 /**********************************************************************
425 static void EVENT_EnterNotify( XCrossingEvent
*event
)
427 if (captureWnd
!= 0) return;
428 winHasCursor
= event
->window
;
432 /**********************************************************************
433 * EVENT_ConfigureNotify
435 * The ConfigureNotify event is only selected on the desktop window.
437 static void EVENT_ConfigureNotify( HWND hwnd
, XConfigureEvent
*event
)
444 /**********************************************************************
445 * SetCapture (USER.18)
447 HWND
SetCapture(HWND wnd
)
450 HWND old_capture_wnd
= captureWnd
;
451 WND
*wnd_p
= WIN_FindWndPtr(wnd
);
455 rv
= XGrabPointer(display
, wnd_p
->window
, False
,
456 ButtonPressMask
| ButtonReleaseMask
| PointerMotionMask
,
457 GrabModeAsync
, GrabModeAsync
, None
, None
, CurrentTime
);
459 if (rv
== GrabSuccess
)
462 return old_capture_wnd
;
468 /**********************************************************************
469 * ReleaseCapture (USER.19)
471 void ReleaseCapture()
473 if (captureWnd
== 0) return;
474 XUngrabPointer( display
, CurrentTime
);
478 /**********************************************************************
479 * GetCapture (USER.236)