2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2006 Sam Lantinga
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "SDL_config.h"
24 #include <sys/types.h>
28 #include "SDL_syswm.h"
29 #include "SDL_x11video.h"
30 #include "../../events/SDL_events_c.h"
32 extern int motion; /* the motion event id defined by an XInput function */
33 extern int button_pressed; /* the button_pressed event id defined by an XInput function */
34 extern int button_released; /* the button_released event id defined by an XInput function */
35 extern int proximity_in; /* the proximity in event defined by an XInput function */
36 extern int proximity_out; /* the proximity out event defined by an XInput function */
39 X11_DispatchEvent(_THIS)
41 SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
46 SDL_zero(xevent); /* valgrind fix. --ryan. */
47 XNextEvent(videodata->display, &xevent);
49 /* filter events catchs XIM events and sends them to the correct
51 if (XFilterEvent(&xevent, None) == True) {
53 printf("Filtered event type = %d display = %d window = %d\n",
54 xevent.type, xevent.xany.display, xevent.xany.window);
59 /* Send a SDL_SYSWMEVENT if the application wants them */
60 if (SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE) {
63 SDL_VERSION(&wmmsg.version);
64 wmmsg.subsystem = SDL_SYSWM_X11;
65 wmmsg.event.xevent = xevent;
66 SDL_SendSysWMEvent(&wmmsg);
70 if (videodata && videodata->windowlist) {
71 for (i = 0; i < videodata->numwindows; ++i) {
72 if ((videodata->windowlist[i] != NULL) &&
73 (videodata->windowlist[i]->window == xevent.xany.window)) {
74 data = videodata->windowlist[i];
83 printf("type = %d display = %d window = %d\n",
84 xevent.type, xevent.xany.display, xevent.xany.window);
86 switch (xevent.type) {
88 /* Gaining mouse coverage? */
91 printf("EnterNotify! (%d,%d)\n", xevent.xcrossing.x,
93 if (xevent.xcrossing.mode == NotifyGrab)
94 printf("Mode: NotifyGrab\n");
95 if (xevent.xcrossing.mode == NotifyUngrab)
96 printf("Mode: NotifyUngrab\n");
98 if ((xevent.xcrossing.mode != NotifyGrab) &&
99 (xevent.xcrossing.mode != NotifyUngrab)) {
100 XDeviceMotionEvent *move = (XDeviceMotionEvent *) & xevent;
101 SDL_SetMouseFocus(move->deviceid, data->windowID);
102 SDL_SendMouseMotion(move->deviceid, 0, move->x,
103 move->y, move->axis_data[2]);
108 /* Losing mouse coverage? */
111 printf("LeaveNotify! (%d,%d)\n", xevent.xcrossing.x,
113 if (xevent.xcrossing.mode == NotifyGrab)
114 printf("Mode: NotifyGrab\n");
115 if (xevent.xcrossing.mode == NotifyUngrab)
116 printf("Mode: NotifyUngrab\n");
118 if ((xevent.xcrossing.mode != NotifyGrab) &&
119 (xevent.xcrossing.mode != NotifyUngrab) &&
120 (xevent.xcrossing.detail != NotifyInferior)) {
121 XDeviceMotionEvent *move = (XDeviceMotionEvent *) & xevent;
122 SDL_SetMouseFocus(move->deviceid, 0);
127 /* Gaining input focus? */
130 printf("FocusIn!\n");
132 SDL_SetKeyboardFocus(videodata->keyboard, data->windowID);
133 #ifdef X_HAVE_UTF8_STRING
135 XSetICFocus(data->ic);
141 /* Losing input focus? */
144 printf("FocusOut!\n");
146 SDL_SetKeyboardFocus(videodata->keyboard, 0);
147 #ifdef X_HAVE_UTF8_STRING
149 XUnsetICFocus(data->ic);
155 /* Generated upon EnterWindow and FocusIn */
158 printf("KeymapNotify!\n");
161 X11_SetKeyboardState(SDL_Display, xevent.xkeymap.key_vector);
166 /* Has the keyboard layout changed? */
169 printf("MappingNotify!\n");
171 X11_UpdateKeymap(_this);
177 KeyCode keycode = xevent.xkey.keycode;
178 KeySym keysym = NoSymbol;
179 char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
183 printf("KeyPress (X11 keycode = 0x%X)\n", xevent.xkey.keycode);
185 SDL_SendKeyboardKey(videodata->keyboard, SDL_PRESSED,
186 videodata->key_layout[keycode]);
188 if (videodata->key_layout[keycode] == SDLK_UNKNOWN) {
189 int min_keycode, max_keycode;
190 XDisplayKeycodes(videodata->display, &min_keycode,
192 keysym = XKeycodeToKeysym(videodata->display, keycode, 0);
194 "The key you just pressed is not recognized by SDL. To help get this fixed, please report this to the SDL mailing list <sdl@libsdl.org> X11 KeyCode %d (%d), X11 KeySym 0x%X (%s).\n",
195 keycode, keycode - min_keycode, keysym,
196 XKeysymToString(keysym));
201 #ifdef X_HAVE_UTF8_STRING
203 Xutf8LookupString(data->ic, &xevent.xkey, text, sizeof(text),
207 XLookupString(&xevent.xkey, text, sizeof(text), &keysym, NULL);
210 printf("Sending text event %s\n", text);
211 SDL_SendKeyboardText(videodata->keyboard, text);
218 KeyCode keycode = xevent.xkey.keycode;
221 printf("KeyRelease (X11 keycode = 0x%X)\n", xevent.xkey.keycode);
223 SDL_SendKeyboardKey(videodata->keyboard, SDL_RELEASED,
224 videodata->key_layout[keycode]);
228 /* Have we been iconified? */
231 printf("UnmapNotify!\n");
233 SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_HIDDEN, 0, 0);
234 SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_MINIMIZED, 0,
239 /* Have we been restored? */
242 printf("MapNotify!\n");
244 SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_SHOWN, 0, 0);
245 SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_RESTORED, 0,
250 /* Have we been resized or moved? */
251 case ConfigureNotify:{
253 printf("ConfigureNotify! (resize: %dx%d)\n",
254 xevent.xconfigure.width, xevent.xconfigure.height);
256 SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_MOVED,
257 xevent.xconfigure.x, xevent.xconfigure.y);
258 SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_RESIZED,
259 xevent.xconfigure.width,
260 xevent.xconfigure.height);
264 /* Have we been requested to quit (or another client message?) */
266 if ((xevent.xclient.format == 32) &&
267 (xevent.xclient.data.l[0] == videodata->WM_DELETE_WINDOW)) {
269 SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_CLOSE, 0,
275 /* Do we need to refresh ourselves? */
278 printf("Expose (count = %d)\n", xevent.xexpose.count);
280 SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_EXPOSED, 0,
286 if (xevent.type == motion) { /* MotionNotify */
288 printf("X11 motion: %d,%d\n", xevent.xmotion.x,
291 XWindowAttributes attrib;
292 XGetWindowAttributes(videodata->display,
293 ((XAnyEvent *) & xevent)->window,
295 SDL_UpdateCoordinates(attrib.width, attrib.height);
296 XDeviceMotionEvent *move = (XDeviceMotionEvent *) & xevent;
297 SDL_SendMouseMotion(move->deviceid, 0, move->x,
298 move->y, move->axis_data[2]);
299 } else if (xevent.type == button_pressed) { /* ButtonPress */
300 XDeviceButtonPressedEvent *pressed =
301 (XDeviceButtonPressedEvent *) & xevent;
302 SDL_SendMouseButton(pressed->deviceid, SDL_PRESSED,
304 } else if (xevent.type == button_released) { /* ButtonRelease */
305 XDeviceButtonReleasedEvent *released =
306 (XDeviceButtonReleasedEvent *) & xevent;
307 SDL_SendMouseButton(released->deviceid, SDL_RELEASED,
309 } else if (xevent.type == proximity_in) {
310 XProximityNotifyEvent *proximity =
311 (XProximityNotifyEvent *) & xevent;
312 SDL_SendProximity(proximity->deviceid, proximity->x,
313 proximity->y, SDL_PROXIMITYIN);
314 } else if (xevent.type == proximity_out) {
315 XProximityNotifyEvent *proximity =
316 (XProximityNotifyEvent *) & xevent;
317 SDL_SendProximity(proximity->deviceid, proximity->x,
318 proximity->y, SDL_PROXIMITYOUT);
322 printf("Unhandled event %d\n", xevent.type);
330 /* Ack! XPending() actually performs a blocking read if no events available */
332 X11_Pending(Display * display)
334 /* Flush the display connection and look to see if events are queued */
336 if (XEventsQueued(display, QueuedAlready)) {
340 /* More drastic measures are required -- see if X is ready to talk */
342 static struct timeval zero_time; /* static == 0 */
346 x11_fd = ConnectionNumber(display);
348 FD_SET(x11_fd, &fdset);
349 if (select(x11_fd + 1, &fdset, NULL, NULL, &zero_time) == 1) {
350 return (XPending(display));
354 /* Oh well, nothing is ready .. */
359 X11_PumpEvents(_THIS)
361 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
363 /* Keep processing pending events */
364 while (X11_Pending(data->display)) {
365 X11_DispatchEvent(_this);
370 X11_SaveScreenSaver(Display * display, int *saved_timeout, BOOL * dpms)
372 int timeout, interval, prefer_blank, allow_exp;
373 XGetScreenSaver(display, &timeout, &interval, &prefer_blank, &allow_exp);
374 *saved_timeout = timeout;
376 #if SDL_VIDEO_DRIVER_X11_DPMS
377 if (SDL_X11_HAVE_DPMS) {
379 if (DPMSQueryExtension(display, &dummy, &dummy)) {
381 DPMSInfo(display, &state, dpms);
386 #endif /* SDL_VIDEO_DRIVER_X11_DPMS */
390 X11_DisableScreenSaver(Display * display)
392 int timeout, interval, prefer_blank, allow_exp;
393 XGetScreenSaver(display, &timeout, &interval, &prefer_blank, &allow_exp);
395 XSetScreenSaver(display, timeout, interval, prefer_blank, allow_exp);
397 #if SDL_VIDEO_DRIVER_X11_DPMS
398 if (SDL_X11_HAVE_DPMS) {
400 if (DPMSQueryExtension(display, &dummy, &dummy)) {
401 DPMSDisable(display);
404 #endif /* SDL_VIDEO_DRIVER_X11_DPMS */
408 X11_RestoreScreenSaver(Display * display, int saved_timeout, BOOL dpms)
410 int timeout, interval, prefer_blank, allow_exp;
411 XGetScreenSaver(display, &timeout, &interval, &prefer_blank, &allow_exp);
412 timeout = saved_timeout;
413 XSetScreenSaver(display, timeout, interval, prefer_blank, allow_exp);
415 #if SDL_VIDEO_DRIVER_X11_DPMS
416 if (SDL_X11_HAVE_DPMS) {
418 if (DPMSQueryExtension(display, &dummy, &dummy)) {
424 #endif /* SDL_VIDEO_DRIVER_X11_DPMS */
427 /* vi: set ts=4 sw=4 expandtab: */