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>
22 typedef char *XPointer
;
26 #define NB_BUTTONS 3 /* Windows can handle 3 buttons */
28 extern int desktopX
, desktopY
; /* misc/main.c */
30 extern void WINPOS_ChangeActiveWindow( HWND hwnd
, BOOL mouseMsg
); /*winpos.c*/
32 /* X context to associate a hwnd to an X window */
33 static XContext winContext
= 0;
36 BOOL MouseButtonsStates
[NB_BUTTONS
] = { FALSE
, FALSE
, FALSE
};
37 static WORD ALTKeyState
;
38 static HWND captureWnd
= 0;
39 Window winHasCursor
= 0;
41 /* Keyboard translation tables */
42 static int special_key
[] =
44 VK_BACK
, VK_TAB
, 0, VK_CLEAR
, 0, VK_RETURN
, 0, 0, /* FF08 */
45 0, 0, 0, VK_PAUSE
, VK_SCROLL
, 0, 0, 0, /* FF10 */
46 0, 0, 0, VK_ESCAPE
/* FF18 */
51 VK_HOME
, VK_LEFT
, VK_UP
, VK_RIGHT
, VK_DOWN
, VK_PRIOR
,
52 VK_NEXT
, VK_END
/* FF50 */
57 VK_SELECT
, VK_SNAPSHOT
, VK_EXECUTE
, VK_INSERT
, 0, 0, 0, 0, /* FF60 */
58 VK_CANCEL
, VK_HELP
, VK_CANCEL
, VK_MENU
/* FF68 */
63 VK_MENU
, VK_NUMLOCK
, /* FF7E */
64 0, 0, 0, 0, 0, 0, 0, 0, /* FF80 */
65 0, 0, 0, 0, 0, VK_RETURN
, 0, 0, /* FF88 */
66 0, 0, 0, 0, 0, 0, 0, 0, /* FF90 */
67 0, 0, 0, 0, 0, 0, 0, 0, /* FF98 */
68 0, 0, 0, 0, 0, 0, 0, 0, /* FFA0 */
69 0, 0, VK_MULTIPLY
, VK_ADD
, VK_SEPARATOR
, VK_SUBTRACT
,
70 VK_DECIMAL
, VK_DIVIDE
, /* FFA8 */
71 VK_NUMPAD0
, VK_NUMPAD1
, VK_NUMPAD2
, VK_NUMPAD3
, VK_NUMPAD4
,
72 VK_NUMPAD5
, VK_NUMPAD6
, VK_NUMPAD7
, /* FFB0 */
73 VK_NUMPAD8
, VK_NUMPAD9
/* FFB8 */
76 static function_key
[] =
78 VK_F1
, VK_F2
, /* FFBE */
79 VK_F3
, VK_F4
, VK_F5
, VK_F6
, VK_F7
, VK_F8
, VK_F9
, VK_F10
, /* FFC0 */
80 VK_F11
, VK_F12
, VK_F13
, VK_F14
, VK_F15
, VK_F16
/* FFC8 */
83 static modifier_key
[] =
85 VK_SHIFT
, VK_SHIFT
, VK_CONTROL
, VK_CONTROL
, VK_CAPITAL
,
87 0, VK_MENU
, VK_MENU
/* FFE8 */
94 unsigned long count
: 16;
95 unsigned long code
: 8;
96 unsigned long extended
: 1;
98 unsigned long context
: 1;
99 unsigned long previous
: 1;
100 unsigned long transition
: 1;
105 static BOOL KeyDown
= FALSE
;
109 static char *event_names
[] =
111 "", "", "KeyPress", "KeyRelease", "ButtonPress", "ButtonRelease",
112 "MotionNotify", "EnterNotify", "LeaveNotify", "FocusIn", "FocusOut",
113 "KeymapNotify", "Expose", "GraphicsExpose", "NoExpose", "VisibilityNotify",
114 "CreateNotify", "DestroyNotify", "UnmapNotify", "MapNotify", "MapRequest",
115 "ReparentNotify", "ConfigureNotify", "ConfigureRequest", "GravityNotify",
116 "ResizeRequest", "CirculateNotify", "CirculateRequest", "PropertyNotify",
117 "SelectionClear", "SelectionRequest", "SelectionNotify", "ColormapNotify",
118 "ClientMessage", "MappingNotify"
123 static void EVENT_key( HWND hwnd
, XKeyEvent
*event
);
124 static void EVENT_ButtonPress( XButtonEvent
*event
);
125 static void EVENT_ButtonRelease( XButtonEvent
*event
);
126 static void EVENT_MotionNotify( XMotionEvent
*event
);
127 static void EVENT_EnterNotify( XCrossingEvent
*event
);
128 static void EVENT_FocusOut( HWND hwnd
, XFocusChangeEvent
*event
);
129 static void EVENT_Expose( HWND hwnd
, XExposeEvent
*event
);
130 static void EVENT_ConfigureNotify( HWND hwnd
, XConfigureEvent
*event
);
133 /***********************************************************************
136 * Process an X event.
138 void EVENT_ProcessEvent( XEvent
*event
)
143 XFindContext( display
, ((XAnyEvent
*)event
)->window
, winContext
, &ptr
);
144 hwnd
= (HWND
) (int)ptr
;
147 printf( "Got event %s for hwnd %d\n", event_names
[event
->type
], hwnd
);
154 EVENT_key( hwnd
, (XKeyEvent
*)event
);
158 EVENT_ButtonPress( (XButtonEvent
*)event
);
162 EVENT_ButtonRelease( (XButtonEvent
*)event
);
166 EVENT_MotionNotify( (XMotionEvent
*)event
);
170 EVENT_EnterNotify( (XCrossingEvent
*)event
);
174 EVENT_FocusOut( hwnd
, (XFocusChangeEvent
*)event
);
178 EVENT_Expose( hwnd
, (XExposeEvent
*)event
);
181 case ConfigureNotify
:
182 EVENT_ConfigureNotify( hwnd
, (XConfigureEvent
*)event
);
187 printf( "Unprocessed event %s for hwnd %d\n",
188 event_names
[event
->type
], hwnd
);
195 /***********************************************************************
196 * EVENT_RegisterWindow
198 * Associate an X window to a HWND.
200 void EVENT_RegisterWindow( Window w
, HWND hwnd
)
202 if (!winContext
) winContext
= XUniqueContext();
203 XSaveContext( display
, w
, winContext
, (XPointer
)(int)hwnd
);
207 /***********************************************************************
208 * EVENT_XStateToKeyState
210 * Translate a X event state (Button1Mask, ShiftMask, etc...) to
211 * a Windows key state (MK_SHIFT, MK_CONTROL, etc...)
213 static WORD
EVENT_XStateToKeyState( int state
)
217 if (state
& Button1Mask
) kstate
|= MK_LBUTTON
;
218 if (state
& Button2Mask
) kstate
|= MK_MBUTTON
;
219 if (state
& Button3Mask
) kstate
|= MK_RBUTTON
;
220 if (state
& ShiftMask
) kstate
|= MK_SHIFT
;
221 if (state
& ControlMask
) kstate
|= MK_CONTROL
;
226 /***********************************************************************
229 static void EVENT_Expose( HWND hwnd
, XExposeEvent
*event
)
233 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
236 /* Make position relative to client area instead of window */
237 rect
.left
= event
->x
- (wndPtr
->rectClient
.left
- wndPtr
->rectWindow
.left
);
238 rect
.top
= event
->y
- (wndPtr
->rectClient
.top
- wndPtr
->rectWindow
.top
);
239 rect
.right
= rect
.left
+ event
->width
;
240 rect
.bottom
= rect
.top
+ event
->height
;
241 winHasCursor
= event
->window
;
243 flags
= RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
;
244 /* Erase desktop background synchronously */
245 if (event
->window
== rootWindow
) flags
|= RDW_ERASENOW
| RDW_NOCHILDREN
;
246 RedrawWindow( hwnd
, &rect
, 0, flags
);
250 /***********************************************************************
253 * Handle a X key event
255 static void EVENT_key( HWND hwnd
, XKeyEvent
*event
)
260 WORD xkey
, vkey
, key_type
, key
;
262 BOOL extended
= FALSE
;
264 int count
= XLookupString(event
, Str
, 1, &keysym
, &cs
);
267 printf("WM_KEY??? : keysym=%lX, count=%u / %X / '%s'\n",
268 keysym
, count
, Str
[0], Str
);
271 xkey
= LOWORD(keysym
);
272 key_type
= HIBYTE(xkey
);
275 printf(" key_type=%X, key=%X\n", key_type
, key
);
278 if (key_type
== 0xFF) /* non-character key */
280 if (key
>= 0x08 && key
<= 0x1B) /* special key */
281 vkey
= special_key
[key
- 0x08];
282 else if (key
>= 0x50 && key
<= 0x57) /* cursor key */
283 vkey
= cursor_key
[key
- 0x50];
284 else if (key
>= 0x60 && key
<= 0x6B) /* miscellaneous key */
285 vkey
= misc_key
[key
- 0x60];
286 else if (key
>= 0x7E && key
<= 0xB9) /* keypad key */
288 vkey
= keypad_key
[key
- 0x7E];
291 else if (key
>= 0xBE && key
<= 0xCD) /* function key */
293 vkey
= function_key
[key
- 0xBE];
296 else if (key
>= 0xE1 && key
<= 0xEA) /* modifier key */
297 vkey
= modifier_key
[key
- 0xE1];
298 else if (key
== 0xFF) /* DEL key */
301 else if (key_type
== 0) /* character key */
303 if (key
>= 0x61 && key
<= 0x7A)
304 vkey
= key
- 0x20; /* convert lower to uppercase */
309 if (event
->type
== KeyPress
)
311 if (vkey
== VK_MENU
) ALTKeyState
= TRUE
;
313 keylp
.lp1
.code
= LOBYTE(event
->keycode
);
314 keylp
.lp1
.extended
= (extended
? 1 : 0);
315 keylp
.lp1
.context
= (event
->state
& Mod1Mask
? 1 : 0);
316 keylp
.lp1
.previous
= (KeyDown
? 0 : 1);
317 keylp
.lp1
.transition
= 0;
319 printf(" wParam=%X, lParam=%lX\n", vkey
, keylp
.lp2
);
321 hardware_event( ALTKeyState
? WM_SYSKEYDOWN
: WM_KEYDOWN
,
323 event
->x_root
- desktopX
, event
->y_root
- desktopY
,
327 /* The key translation ought to take place in TranslateMessage().
328 * However, there is no way of passing the required information
329 * in a Windows message, so TranslateMessage does not currently
330 * do anything and the translation is done here.
332 if (count
== 1) /* key has an ASCII representation */
335 printf("WM_CHAR : wParam=%X\n", (WORD
)Str
[0] );
337 PostMessage( GetFocus(), WM_CHAR
, (WORD
)Str
[0], keylp
.lp2
);
342 if (vkey
== VK_MENU
) ALTKeyState
= FALSE
;
344 keylp
.lp1
.code
= LOBYTE(event
->keycode
);
345 keylp
.lp1
.extended
= (extended
? 1 : 0);
346 keylp
.lp1
.context
= (event
->state
& Mod1Mask
? 1 : 0);
347 keylp
.lp1
.previous
= 1;
348 keylp
.lp1
.transition
= 1;
350 printf(" wParam=%X, lParam=%lX\n", vkey
, keylp
.lp2
);
352 hardware_event( ((ALTKeyState
|| vkey
== VK_MENU
) ?
353 WM_SYSKEYUP
: WM_KEYUP
),
355 event
->x_root
- desktopX
, event
->y_root
- desktopY
,
362 /***********************************************************************
365 static void EVENT_MotionNotify( XMotionEvent
*event
)
367 hardware_event( WM_MOUSEMOVE
, EVENT_XStateToKeyState( event
->state
), 0L,
368 event
->x_root
- desktopX
, event
->y_root
- desktopY
,
373 /***********************************************************************
376 static void EVENT_ButtonPress( XButtonEvent
*event
)
378 static WORD messages
[NB_BUTTONS
] =
379 { WM_LBUTTONDOWN
, WM_MBUTTONDOWN
, WM_RBUTTONDOWN
};
380 int buttonNum
= event
->button
- 1;
382 if (buttonNum
>= NB_BUTTONS
) return;
383 MouseButtonsStates
[buttonNum
] = TRUE
;
384 winHasCursor
= event
->window
;
385 hardware_event( messages
[buttonNum
],
386 EVENT_XStateToKeyState( event
->state
), 0L,
387 event
->x_root
- desktopX
, event
->y_root
- desktopY
,
392 /***********************************************************************
393 * EVENT_ButtonRelease
395 static void EVENT_ButtonRelease( XButtonEvent
*event
)
397 static const WORD messages
[NB_BUTTONS
] =
398 { WM_LBUTTONUP
, WM_MBUTTONUP
, WM_RBUTTONUP
};
399 int buttonNum
= event
->button
- 1;
401 if (buttonNum
>= NB_BUTTONS
) return;
402 MouseButtonsStates
[buttonNum
] = FALSE
;
403 winHasCursor
= event
->window
;
404 hardware_event( messages
[buttonNum
],
405 EVENT_XStateToKeyState( event
->state
), 0L,
406 event
->x_root
- desktopX
, event
->y_root
- desktopY
,
411 /**********************************************************************
414 * Note: only top-level override-redirect windows get FocusOut events.
416 static void EVENT_FocusOut( HWND hwnd
, XFocusChangeEvent
*event
)
418 if (event
->detail
== NotifyPointer
) return;
419 if (hwnd
== GetActiveWindow()) WINPOS_ChangeActiveWindow( 0, FALSE
);
420 if ((hwnd
== GetFocus()) || IsChild( hwnd
, GetFocus())) SetFocus( 0 );
424 /**********************************************************************
427 static void EVENT_EnterNotify( XCrossingEvent
*event
)
429 if (captureWnd
!= 0) return;
430 winHasCursor
= event
->window
;
434 /**********************************************************************
435 * EVENT_ConfigureNotify
437 * The ConfigureNotify event is only selected on the desktop window.
439 static void EVENT_ConfigureNotify( HWND hwnd
, XConfigureEvent
*event
)
446 /**********************************************************************
447 * SetCapture (USER.18)
449 HWND
SetCapture(HWND wnd
)
452 HWND old_capture_wnd
= captureWnd
;
453 WND
*wnd_p
= WIN_FindWndPtr(wnd
);
457 rv
= XGrabPointer(display
, wnd_p
->window
, False
,
458 ButtonPressMask
| ButtonReleaseMask
| PointerMotionMask
,
459 GrabModeAsync
, GrabModeAsync
, None
, None
, CurrentTime
);
461 if (rv
== GrabSuccess
)
464 return old_capture_wnd
;
470 /**********************************************************************
471 * ReleaseCapture (USER.19)
473 void ReleaseCapture()
475 if (captureWnd
== 0) return;
476 XUngrabPointer( display
, CurrentTime
);
480 /**********************************************************************
481 * GetCapture (USER.236)