1 /* 2 SDL - Simple DirectMedia Layer 3 Copyright (C) 1997-2012 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 (at) libsdl.org 21 */ 22 #include "SDL_config.h" 23 24 /* Handle the event stream, converting DGA events into SDL events */ 25 26 #include <stdio.h> 27 #include <X11/Xlib.h> 28 #include "../Xext/extensions/xf86dga.h" 29 30 #include "SDL_timer.h" 31 #include "../SDL_sysvideo.h" 32 #include "../../events/SDL_events_c.h" 33 #include "SDL_dgavideo.h" 34 #include "SDL_dgaevents_c.h" 35 36 /* get function pointers... */ 37 #include "../x11/SDL_x11dyn.h" 38 39 /* Heheh we're using X11 event code */ 40 extern int X11_Pending(Display *display); 41 extern void X11_InitKeymap(void); 42 extern SDLKey X11_TranslateKeycode(Display *display, KeyCode kc); 43 44 static int DGA_DispatchEvent(_THIS) 45 { 46 int posted; 47 SDL_NAME(XDGAEvent) xevent; 48 49 XNextEvent(DGA_Display, (XEvent *)&xevent); 50 51 posted = 0; 52 xevent.type -= DGA_event_base; 53 switch (xevent.type) { 54 55 /* Mouse motion? */ 56 case MotionNotify: { 57 if ( SDL_VideoSurface ) { 58 posted = SDL_PrivateMouseMotion(0, 1, 59 xevent.xmotion.dx, xevent.xmotion.dy); 60 } 61 } 62 break; 63 64 /* Mouse button press? */ 65 case ButtonPress: { 66 posted = SDL_PrivateMouseButton(SDL_PRESSED, 67 xevent.xbutton.button, 0, 0); 68 } 69 break; 70 71 /* Mouse button release? */ 72 case ButtonRelease: { 73 posted = SDL_PrivateMouseButton(SDL_RELEASED, 74 xevent.xbutton.button, 0, 0); 75 } 76 break; 77 78 /* Key press? */ 79 case KeyPress: { 80 SDL_keysym keysym; 81 KeyCode keycode; 82 XKeyEvent xkey; 83 84 SDL_NAME(XDGAKeyEventToXKeyEvent)(&xevent.xkey, &xkey); 85 keycode = xkey.keycode; 86 #ifdef DEBUG_XEVENTS 87 printf("KeyPress (X11 keycode = 0x%X)\n", xkey.keycode); 88 #endif 89 /* Get the translated SDL virtual keysym */ 90 keysym.scancode = keycode; 91 keysym.sym = X11_TranslateKeycode(DGA_Display, keycode); 92 keysym.mod = KMOD_NONE; 93 keysym.unicode = 0; 94 95 /* Look up the translated value for the key event */ 96 if ( SDL_TranslateUNICODE ) { 97 static XComposeStatus state; 98 char keybuf[32]; 99 100 if ( XLookupString(&xkey, keybuf, sizeof(keybuf), NULL, &state) ) { 101 /* 102 * FIXME: XLookupString() may yield more than one 103 * character, so we need a mechanism to allow for 104 * this (perhaps null keypress events with a 105 * unicode value) 106 */ 107 keysym.unicode = (Uint8)keybuf[0]; 108 } 109 } 110 posted = SDL_PrivateKeyboard(SDL_PRESSED, &keysym); 111 } 112 break; 113 114 /* Key release? */ 115 case KeyRelease: { 116 SDL_keysym keysym; 117 KeyCode keycode; 118 XKeyEvent xkey; 119 120 SDL_NAME(XDGAKeyEventToXKeyEvent)(&xevent.xkey, &xkey); 121 keycode = xkey.keycode; 122 #ifdef DEBUG_XEVENTS 123 printf("KeyRelease (X11 keycode = 0x%X)\n", xkey.keycode); 124 #endif 125 /* Get the translated SDL virtual keysym */ 126 keysym.scancode = keycode; 127 keysym.sym = X11_TranslateKeycode(DGA_Display, keycode); 128 keysym.mod = KMOD_NONE; 129 keysym.unicode = 0; 130 posted = SDL_PrivateKeyboard(SDL_RELEASED, &keysym); 131 } 132 break; 133 } 134 return(posted); 135 } 136 137 void DGA_PumpEvents(_THIS) 138 { 139 /* Keep processing pending events */ 140 LOCK_DISPLAY(); 141 142 /* Update activity every five seconds to prevent screensaver. --ryan. */ 143 if (!allow_screensaver) { 144 static Uint32 screensaverTicks; 145 Uint32 nowTicks = SDL_GetTicks(); 146 if ((nowTicks - screensaverTicks) > 5000) { 147 XResetScreenSaver(DGA_Display); 148 screensaverTicks = nowTicks; 149 } 150 } 151 152 while ( X11_Pending(DGA_Display) ) { 153 DGA_DispatchEvent(this); 154 } 155 156 UNLOCK_DISPLAY(); 157 } 158 159 void DGA_InitOSKeymap(_THIS) 160 { 161 X11_InitKeymap(); 162 } 163 164