src/video/x11/SDL_x11events.c
author Bob Pendleton <bob@pendleton.com>
Fri, 07 Mar 2008 23:57:15 +0000
changeset 2327 7b53a8401195
parent 2326 133562468ff2
child 2328 91e601d9df8b
permissions -rw-r--r--
In testdyngl.c the event type was being anded (&) with SDL_KEYDOWN and if the result was none zero the program was quiting. This is very weird because it was
working earlier this week.

I added some more trace code to SDL_x11events.c

In SDL_X11opengl.c I modified SDL_GL_GetSwapInterval() so that it returns a pretty good value even if you have the SGI swap extension instead of the MESA swap
extension. I just saved the value you set and return it too you.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2006 Sam Lantinga
     4 
     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.
     9 
    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.
    14 
    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
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 #include "SDL_config.h"
    23 
    24 #include <sys/types.h>
    25 #include <sys/time.h>
    26 #include <unistd.h>
    27 
    28 #include "SDL_syswm.h"
    29 #include "SDL_x11video.h"
    30 #include "../../events/SDL_events_c.h"
    31 
    32 static void
    33 X11_DispatchEvent(_THIS)
    34 {
    35     SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
    36     SDL_WindowData *data;
    37     XEvent xevent;
    38     int i;
    39 
    40     SDL_zero(xevent);           /* valgrind fix. --ryan. */
    41     XNextEvent(videodata->display, &xevent);
    42 
    43     /* filter events catchs XIM events and sends them to the correct
    44        handler */
    45     if (XFilterEvent(&xevent, None) == True) {
    46 #if 0
    47       printf("Filtered event type = %d display = %d window = %d\n", 
    48              xevent.type, xevent.xany.display, xevent.xany.window);
    49 #endif
    50         return;
    51     }
    52 
    53     /* Send a SDL_SYSWMEVENT if the application wants them */
    54     if (SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE) {
    55         SDL_SysWMmsg wmmsg;
    56 
    57         SDL_VERSION(&wmmsg.version);
    58         wmmsg.subsystem = SDL_SYSWM_X11;
    59         wmmsg.event.xevent = xevent;
    60         SDL_SendSysWMEvent(&wmmsg);
    61     }
    62 
    63     data = NULL;
    64     if (videodata && videodata->windowlist) {
    65         for (i = 0; i < videodata->numwindows; ++i) {
    66             if ((videodata->windowlist[i] != NULL) &&
    67                 (videodata->windowlist[i]->window == xevent.xany.window)) {
    68                 data = videodata->windowlist[i];
    69                 break;
    70             }
    71         }
    72     }
    73     if (!data) {
    74         return;
    75     }
    76 
    77 #if 0
    78       printf("type = %d display = %d window = %d\n", 
    79              xevent.type, xevent.xany.display, xevent.xany.window);
    80 #endif
    81     switch (xevent.type) {
    82 
    83         /* Gaining mouse coverage? */
    84     case EnterNotify:{
    85 #ifdef DEBUG_XEVENTS
    86             printf("EnterNotify! (%d,%d)\n", xevent.xcrossing.x,
    87                    xevent.xcrossing.y);
    88             if (xevent.xcrossing.mode == NotifyGrab)
    89                 printf("Mode: NotifyGrab\n");
    90             if (xevent.xcrossing.mode == NotifyUngrab)
    91                 printf("Mode: NotifyUngrab\n");
    92 #endif
    93             if ((xevent.xcrossing.mode != NotifyGrab) &&
    94                 (xevent.xcrossing.mode != NotifyUngrab)) {
    95                 SDL_SetMouseFocus(videodata->mouse, data->windowID);
    96                 SDL_SendMouseMotion(videodata->mouse, 0, xevent.xcrossing.x,
    97                                     xevent.xcrossing.y);
    98             }
    99         }
   100         break;
   101 
   102         /* Losing mouse coverage? */
   103     case LeaveNotify:{
   104 #ifdef DEBUG_XEVENTS
   105             printf("LeaveNotify! (%d,%d)\n", xevent.xcrossing.x,
   106                    xevent.xcrossing.y);
   107             if (xevent.xcrossing.mode == NotifyGrab)
   108                 printf("Mode: NotifyGrab\n");
   109             if (xevent.xcrossing.mode == NotifyUngrab)
   110                 printf("Mode: NotifyUngrab\n");
   111 #endif
   112             if ((xevent.xcrossing.mode != NotifyGrab) &&
   113                 (xevent.xcrossing.mode != NotifyUngrab) &&
   114                 (xevent.xcrossing.detail != NotifyInferior)) {
   115                 SDL_SendMouseMotion(videodata->mouse, 0,
   116                                     xevent.xcrossing.x, xevent.xcrossing.y);
   117                 SDL_SetMouseFocus(videodata->mouse, 0);
   118             }
   119         }
   120         break;
   121 
   122         /* Gaining input focus? */
   123     case FocusIn:{
   124 #ifdef DEBUG_XEVENTS
   125             printf("FocusIn!\n");
   126 #endif
   127             SDL_SetKeyboardFocus(videodata->keyboard, data->windowID);
   128 #ifdef X_HAVE_UTF8_STRING
   129             if (data->ic) {
   130                 XSetICFocus(data->ic);
   131             }
   132 #endif
   133         }
   134         break;
   135 
   136         /* Losing input focus? */
   137     case FocusOut:{
   138 #ifdef DEBUG_XEVENTS
   139             printf("FocusOut!\n");
   140 #endif
   141             SDL_SetKeyboardFocus(videodata->keyboard, 0);
   142 #ifdef X_HAVE_UTF8_STRING
   143             if (data->ic) {
   144                 XUnsetICFocus(data->ic);
   145             }
   146 #endif
   147         }
   148         break;
   149 
   150         /* Generated upon EnterWindow and FocusIn */
   151     case KeymapNotify:{
   152 #ifdef DEBUG_XEVENTS
   153             printf("KeymapNotify!\n");
   154 #endif
   155             /* FIXME:
   156                X11_SetKeyboardState(SDL_Display, xevent.xkeymap.key_vector);
   157              */
   158         }
   159         break;
   160 
   161         /* Has the keyboard layout changed? */
   162     case MappingNotify:{
   163 #ifdef DEBUG_XEVENTS
   164             printf("MappingNotify!\n");
   165 #endif
   166             X11_UpdateKeymap(_this);
   167         }
   168         break;
   169 
   170         /* Mouse motion? */
   171     case MotionNotify:{
   172 #ifdef DEBUG_MOTION
   173             printf("X11 motion: %d,%d\n", xevent.xmotion.x, xevent.xmotion.y);
   174 #endif
   175             SDL_SendMouseMotion(videodata->mouse, 0, xevent.xmotion.x,
   176                                 xevent.xmotion.y);
   177         }
   178         break;
   179 
   180         /* Mouse button press? */
   181     case ButtonPress:{
   182             SDL_SendMouseButton(videodata->mouse, SDL_PRESSED,
   183                                 xevent.xbutton.button);
   184         }
   185         break;
   186 
   187         /* Mouse button release? */
   188     case ButtonRelease:{
   189             SDL_SendMouseButton(videodata->mouse, SDL_RELEASED,
   190                                 xevent.xbutton.button);
   191         }
   192         break;
   193 
   194         /* Key press? */
   195     case KeyPress:{
   196             KeyCode keycode = xevent.xkey.keycode;
   197             KeySym keysym = NoSymbol;
   198             char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
   199             Status status = 0;
   200 
   201 #ifdef DEBUG_XEVENTS
   202             printf("KeyPress (X11 keycode = 0x%X)\n", xevent.xkey.keycode);
   203 #endif
   204             SDL_SendKeyboardKey(videodata->keyboard, SDL_PRESSED,
   205                                 videodata->key_layout[keycode]);
   206 #if 0
   207             if (videodata->key_layout[keycode] == SDLK_UNKNOWN) {
   208                 int min_keycode, max_keycode;
   209                 XDisplayKeycodes(videodata->display, &min_keycode,
   210                                  &max_keycode);
   211                 keysym = XKeycodeToKeysym(videodata->display, keycode, 0);
   212                 fprintf(stderr,
   213                         "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",
   214                         keycode, keycode - min_keycode, keysym,
   215                         XKeysymToString(keysym));
   216             }
   217 #endif
   218             /* */
   219             SDL_zero(text);
   220 #ifdef X_HAVE_UTF8_STRING
   221             if (data->ic) {
   222                 Xutf8LookupString(data->ic, &xevent.xkey, text, sizeof(text),
   223                                   &keysym, status);
   224             }
   225 #else
   226             XLookupString(&xevent.xkey, text, sizeof(text), &keysym, NULL);
   227 #endif
   228             if (*text) {
   229                 printf("Sending text event %s\n", text);
   230                 SDL_SendKeyboardText(videodata->keyboard, text);
   231             }
   232         }
   233         break;
   234 
   235         /* Key release? */
   236     case KeyRelease:{
   237             KeyCode keycode = xevent.xkey.keycode;
   238 
   239 #ifdef DEBUG_XEVENTS
   240             printf("KeyRelease (X11 keycode = 0x%X)\n", xevent.xkey.keycode);
   241 #endif
   242             SDL_SendKeyboardKey(videodata->keyboard, SDL_RELEASED,
   243                                 videodata->key_layout[keycode]);
   244         }
   245         break;
   246 
   247         /* Have we been iconified? */
   248     case UnmapNotify:{
   249 #ifdef DEBUG_XEVENTS
   250             printf("UnmapNotify!\n");
   251 #endif
   252             SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_HIDDEN, 0, 0);
   253             SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_MINIMIZED, 0,
   254                                 0);
   255         }
   256         break;
   257 
   258         /* Have we been restored? */
   259     case MapNotify:{
   260 #ifdef DEBUG_XEVENTS
   261             printf("MapNotify!\n");
   262 #endif
   263             SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_SHOWN, 0, 0);
   264             SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_RESTORED, 0,
   265                                 0);
   266         }
   267         break;
   268 
   269         /* Have we been resized or moved? */
   270     case ConfigureNotify:{
   271 #ifdef DEBUG_XEVENTS
   272             printf("ConfigureNotify! (resize: %dx%d)\n",
   273                    xevent.xconfigure.width, xevent.xconfigure.height);
   274 #endif
   275             SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_MOVED,
   276                                 xevent.xconfigure.x, xevent.xconfigure.y);
   277             SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_RESIZED,
   278                                 xevent.xconfigure.width,
   279                                 xevent.xconfigure.height);
   280         }
   281         break;
   282 
   283         /* Have we been requested to quit (or another client message?) */
   284     case ClientMessage:{
   285             if ((xevent.xclient.format == 32) &&
   286                 (xevent.xclient.data.l[0] == videodata->WM_DELETE_WINDOW)) {
   287 
   288                 SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_CLOSE, 0,
   289                                     0);
   290             }
   291         }
   292         break;
   293 
   294         /* Do we need to refresh ourselves? */
   295     case Expose:{
   296 #ifdef DEBUG_XEVENTS
   297             printf("Expose (count = %d)\n", xevent.xexpose.count);
   298 #endif
   299             SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_EXPOSED, 0,
   300                                 0);
   301         }
   302         break;
   303 
   304     default:{
   305 #ifdef DEBUG_XEVENTS
   306             printf("Unhandled event %d\n", xevent.type);
   307 #endif
   308         }
   309         break;
   310     }
   311 }
   312 
   313 /* Ack!  XPending() actually performs a blocking read if no events available */
   314 int
   315 X11_Pending(Display * display)
   316 {
   317     /* Flush the display connection and look to see if events are queued */
   318     XFlush(display);
   319     if (XEventsQueued(display, QueuedAlready)) {
   320         return (1);
   321     }
   322 
   323     /* More drastic measures are required -- see if X is ready to talk */
   324     {
   325         static struct timeval zero_time;        /* static == 0 */
   326         int x11_fd;
   327         fd_set fdset;
   328 
   329         x11_fd = ConnectionNumber(display);
   330         FD_ZERO(&fdset);
   331         FD_SET(x11_fd, &fdset);
   332         if (select(x11_fd + 1, &fdset, NULL, NULL, &zero_time) == 1) {
   333             return (XPending(display));
   334         }
   335     }
   336 
   337     /* Oh well, nothing is ready .. */
   338     return (0);
   339 }
   340 
   341 void
   342 X11_PumpEvents(_THIS)
   343 {
   344     SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
   345 
   346     /* Keep processing pending events */
   347     while (X11_Pending(data->display)) {
   348         X11_DispatchEvent(_this);
   349     }
   350 }
   351 
   352 void
   353 X11_SaveScreenSaver(Display * display, int *saved_timeout, BOOL * dpms)
   354 {
   355     int timeout, interval, prefer_blank, allow_exp;
   356     XGetScreenSaver(display, &timeout, &interval, &prefer_blank, &allow_exp);
   357     *saved_timeout = timeout;
   358 
   359 #if SDL_VIDEO_DRIVER_X11_DPMS
   360     if (SDL_X11_HAVE_DPMS) {
   361         int dummy;
   362         if (DPMSQueryExtension(display, &dummy, &dummy)) {
   363             CARD16 state;
   364             DPMSInfo(display, &state, dpms);
   365         }
   366     }
   367 #else
   368     *dpms = 0;
   369 #endif /* SDL_VIDEO_DRIVER_X11_DPMS */
   370 }
   371 
   372 void
   373 X11_DisableScreenSaver(Display * display)
   374 {
   375     int timeout, interval, prefer_blank, allow_exp;
   376     XGetScreenSaver(display, &timeout, &interval, &prefer_blank, &allow_exp);
   377     timeout = 0;
   378     XSetScreenSaver(display, timeout, interval, prefer_blank, allow_exp);
   379 
   380 #if SDL_VIDEO_DRIVER_X11_DPMS
   381     if (SDL_X11_HAVE_DPMS) {
   382         int dummy;
   383         if (DPMSQueryExtension(display, &dummy, &dummy)) {
   384             DPMSDisable(display);
   385         }
   386     }
   387 #endif /* SDL_VIDEO_DRIVER_X11_DPMS */
   388 }
   389 
   390 void
   391 X11_RestoreScreenSaver(Display * display, int saved_timeout, BOOL dpms)
   392 {
   393     int timeout, interval, prefer_blank, allow_exp;
   394     XGetScreenSaver(display, &timeout, &interval, &prefer_blank, &allow_exp);
   395     timeout = saved_timeout;
   396     XSetScreenSaver(display, timeout, interval, prefer_blank, allow_exp);
   397 
   398 #if SDL_VIDEO_DRIVER_X11_DPMS
   399     if (SDL_X11_HAVE_DPMS) {
   400         int dummy;
   401         if (DPMSQueryExtension(display, &dummy, &dummy)) {
   402             if (dpms) {
   403                 DPMSEnable(display);
   404             }
   405         }
   406     }
   407 #endif /* SDL_VIDEO_DRIVER_X11_DPMS */
   408 }
   409 
   410 /* vi: set ts=4 sw=4 expandtab: */