Mercurial > sdl-ios-xcode
annotate src/video/x11/SDL_x11events.c @ 1176:dd2a8deeb26d
Date: Mon, 17 Oct 2005 20:09:03 -0400
From: Mark Schreiber <mark7@alumni.cmu.edu>
To: ryan@clutteredmind.org
Subject: [PATCH]SDL mprotect() crash fix
(I'm going to throw this patch your way at the suggestion of #SDL --
for some reason, I had some difficulty sending it to the main list
last time, and I go bonkers subscribing to send each email or
patch...)
Currently, when I run SDL applications as non-root using
SDL_VIDEODRIVER=dga, the fbdev fallback mprotect()s read/write the
proper size of mmapped /dev/fb0 (7.5MB), but on framebuffer release
mprotect()s read-only the range by the entire size of my video memory
(128MB), which causes a segfault:
#0 0x002a9a27 in ?? () from /lib/libc.so.6
#1 0x04a63eb6 in SDL_XDGAUnmapFramebuffer (screen=3D0) at XF86DGA2.c:978
#2 0x04a63efc in SDL_XDGACloseFramebuffer (dpy=3D0x9d3f008, screen=3D0)
at XF86DGA2.c:268
#3 0x04a68b57 in DGA_Available () at SDL_dgavideo.c:98
#4 0x04a53677 in SDL_VideoInit (driver_name=3D0xbfb0bfc7 "dga", flags=3D0)
at SDL_video.c:180
#5 0x04a2613f in SDL_InitSubSystem (flags=3D32) at SDL.c:74
#6 0x04a2617c in SDL_Init (flags=3D32) at SDL.c:166
#7 0x08049722 in main (argc=3D1, argv=3D0x0) at testwin.c:32
This is SDL 1.2.8 on Fedora Core 4, radeon driver for a Radeon 9250,
xorg-x11-6.8.2-37.
I've attached a one-line patch against SDL CVS that updates the size
of the framebuffer at framebuffer map time so that the mprotect() on
unmap will be the same size. I'm not sure if this is the best
approach (i.e. one might want to retain the original value), but it
does make my SDL applications work without segfaulting.
-- Best of luck, Mark Schreiber
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Sat, 19 Nov 2005 18:57:00 +0000 |
parents | 045f186426e1 |
children | 9867f3d86e44 |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
769
b8d311d90021
Updated copyright information for 2004 (Happy New Year!)
Sam Lantinga <slouken@libsdl.org>
parents:
496
diff
changeset
|
3 Copyright (C) 1997-2004 Sam Lantinga |
0 | 4 |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Library General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2 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 Library General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Library General Public | |
16 License along with this library; if not, write to the Free | |
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | |
19 Sam Lantinga | |
252
e8157fcb3114
Updated the source with the correct e-mail address
Sam Lantinga <slouken@libsdl.org>
parents:
161
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 /* Handle the event stream, converting X11 events into SDL events */ | |
29 | |
30 #include <stdio.h> | |
31 #include <stdlib.h> | |
32 #include <string.h> | |
33 #include <setjmp.h> | |
34 #include <X11/Xlib.h> | |
35 #include <X11/Xutil.h> | |
36 #include <X11/keysym.h> | |
37 #ifdef __SVR4 | |
38 #include <X11/Sunkeysym.h> | |
39 #endif | |
75
b0ae59d0f3ee
Added patches from FreeBSD ports
Sam Lantinga <slouken@lokigames.com>
parents:
14
diff
changeset
|
40 #include <sys/types.h> |
0 | 41 #include <sys/time.h> |
75
b0ae59d0f3ee
Added patches from FreeBSD ports
Sam Lantinga <slouken@lokigames.com>
parents:
14
diff
changeset
|
42 #include <unistd.h> |
0 | 43 |
44 #include "SDL.h" | |
45 #include "SDL_syswm.h" | |
46 #include "SDL_sysevents.h" | |
47 #include "SDL_sysvideo.h" | |
48 #include "SDL_events_c.h" | |
49 #include "SDL_x11video.h" | |
50 #include "SDL_x11dga_c.h" | |
51 #include "SDL_x11modes_c.h" | |
52 #include "SDL_x11image_c.h" | |
53 #include "SDL_x11gamma_c.h" | |
54 #include "SDL_x11wm_c.h" | |
55 #include "SDL_x11mouse_c.h" | |
56 #include "SDL_x11events_c.h" | |
57 | |
58 | |
14
c3e9d4a623c1
Fixed stuck keys when changing the video mode
Sam Lantinga <slouken@lokigames.com>
parents:
12
diff
changeset
|
59 /* Define this if you want to debug X11 events */ |
c3e9d4a623c1
Fixed stuck keys when changing the video mode
Sam Lantinga <slouken@lokigames.com>
parents:
12
diff
changeset
|
60 /*#define DEBUG_XEVENTS*/ |
c3e9d4a623c1
Fixed stuck keys when changing the video mode
Sam Lantinga <slouken@lokigames.com>
parents:
12
diff
changeset
|
61 |
0 | 62 /* The translation tables from an X11 keysym to a SDL keysym */ |
63 static SDLKey ODD_keymap[256]; | |
64 static SDLKey MISC_keymap[256]; | |
65 SDL_keysym *X11_TranslateKey(Display *display, XKeyEvent *xkey, KeyCode kc, | |
66 SDL_keysym *keysym); | |
67 | |
68 /* Check to see if this is a repeated key. | |
69 (idea shamelessly lifted from GII -- thanks guys! :) | |
70 */ | |
71 static int X11_KeyRepeat(Display *display, XEvent *event) | |
72 { | |
73 XEvent peekevent; | |
74 int repeated; | |
75 | |
76 repeated = 0; | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
1159
diff
changeset
|
77 if ( pXPending(display) ) { |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
1159
diff
changeset
|
78 pXPeekEvent(display, &peekevent); |
0 | 79 if ( (peekevent.type == KeyPress) && |
80 (peekevent.xkey.keycode == event->xkey.keycode) && | |
12
34d956b20f75
Fix key repeat detection on newer X servers
Sam Lantinga <slouken@lokigames.com>
parents:
8
diff
changeset
|
81 ((peekevent.xkey.time-event->xkey.time) < 2) ) { |
0 | 82 repeated = 1; |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
1159
diff
changeset
|
83 pXNextEvent(display, &peekevent); |
0 | 84 } |
85 } | |
86 return(repeated); | |
87 } | |
88 | |
89 /* Note: The X server buffers and accumulates mouse motion events, so | |
90 the motion event generated by the warp may not appear exactly as we | |
91 expect it to. We work around this (and improve performance) by only | |
92 warping the pointer when it reaches the edge, and then wait for it. | |
93 */ | |
94 #define MOUSE_FUDGE_FACTOR 8 | |
95 | |
96 static __inline__ int X11_WarpedMotion(_THIS, XEvent *xevent) | |
97 { | |
98 int w, h, i; | |
99 int deltax, deltay; | |
100 int posted; | |
101 | |
102 w = SDL_VideoSurface->w; | |
103 h = SDL_VideoSurface->h; | |
104 deltax = xevent->xmotion.x - mouse_last.x; | |
105 deltay = xevent->xmotion.y - mouse_last.y; | |
106 #ifdef DEBUG_MOTION | |
107 printf("Warped mouse motion: %d,%d\n", deltax, deltay); | |
108 #endif | |
109 mouse_last.x = xevent->xmotion.x; | |
110 mouse_last.y = xevent->xmotion.y; | |
111 posted = SDL_PrivateMouseMotion(0, 1, deltax, deltay); | |
112 | |
113 if ( (xevent->xmotion.x < MOUSE_FUDGE_FACTOR) || | |
114 (xevent->xmotion.x > (w-MOUSE_FUDGE_FACTOR)) || | |
115 (xevent->xmotion.y < MOUSE_FUDGE_FACTOR) || | |
116 (xevent->xmotion.y > (h-MOUSE_FUDGE_FACTOR)) ) { | |
117 /* Get the events that have accumulated */ | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
1159
diff
changeset
|
118 while ( pXCheckTypedEvent(SDL_Display, MotionNotify, xevent) ) { |
0 | 119 deltax = xevent->xmotion.x - mouse_last.x; |
120 deltay = xevent->xmotion.y - mouse_last.y; | |
121 #ifdef DEBUG_MOTION | |
122 printf("Extra mouse motion: %d,%d\n", deltax, deltay); | |
123 #endif | |
124 mouse_last.x = xevent->xmotion.x; | |
125 mouse_last.y = xevent->xmotion.y; | |
126 posted += SDL_PrivateMouseMotion(0, 1, deltax, deltay); | |
127 } | |
128 mouse_last.x = w/2; | |
129 mouse_last.y = h/2; | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
1159
diff
changeset
|
130 pXWarpPointer(SDL_Display, None, SDL_Window, 0, 0, 0, 0, |
0 | 131 mouse_last.x, mouse_last.y); |
132 for ( i=0; i<10; ++i ) { | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
1159
diff
changeset
|
133 pXMaskEvent(SDL_Display, PointerMotionMask, xevent); |
0 | 134 if ( (xevent->xmotion.x > |
135 (mouse_last.x-MOUSE_FUDGE_FACTOR)) && | |
136 (xevent->xmotion.x < | |
137 (mouse_last.x+MOUSE_FUDGE_FACTOR)) && | |
138 (xevent->xmotion.y > | |
139 (mouse_last.y-MOUSE_FUDGE_FACTOR)) && | |
140 (xevent->xmotion.y < | |
141 (mouse_last.y+MOUSE_FUDGE_FACTOR)) ) { | |
142 break; | |
143 } | |
144 #ifdef DEBUG_XEVENTS | |
145 printf("Lost mouse motion: %d,%d\n", xevent->xmotion.x, xevent->xmotion.y); | |
146 #endif | |
147 } | |
148 #ifdef DEBUG_XEVENTS | |
149 if ( i == 10 ) { | |
150 printf("Warning: didn't detect mouse warp motion\n"); | |
151 } | |
152 #endif | |
153 } | |
154 return(posted); | |
155 } | |
156 | |
157 static int X11_DispatchEvent(_THIS) | |
158 { | |
159 int posted; | |
160 XEvent xevent; | |
161 | |
1159 | 162 memset(&xevent, '\0', sizeof (XEvent)); /* valgrind fix. --ryan. */ |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
1159
diff
changeset
|
163 pXNextEvent(SDL_Display, &xevent); |
0 | 164 |
165 posted = 0; | |
166 switch (xevent.type) { | |
167 | |
168 /* Gaining mouse coverage? */ | |
169 case EnterNotify: { | |
170 #ifdef DEBUG_XEVENTS | |
82
2bddc38a9f5d
When the mouse is grabbed, send the application the motion associated with
Sam Lantinga <slouken@lokigames.com>
parents:
75
diff
changeset
|
171 printf("EnterNotify! (%d,%d)\n", xevent.xcrossing.x, xevent.xcrossing.y); |
0 | 172 if ( xevent.xcrossing.mode == NotifyGrab ) |
173 printf("Mode: NotifyGrab\n"); | |
174 if ( xevent.xcrossing.mode == NotifyUngrab ) | |
175 printf("Mode: NotifyUngrab\n"); | |
176 #endif | |
177 if ( (xevent.xcrossing.mode != NotifyGrab) && | |
178 (xevent.xcrossing.mode != NotifyUngrab) ) { | |
82
2bddc38a9f5d
When the mouse is grabbed, send the application the motion associated with
Sam Lantinga <slouken@lokigames.com>
parents:
75
diff
changeset
|
179 if ( this->input_grab == SDL_GRAB_OFF ) { |
2bddc38a9f5d
When the mouse is grabbed, send the application the motion associated with
Sam Lantinga <slouken@lokigames.com>
parents:
75
diff
changeset
|
180 posted = SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); |
2bddc38a9f5d
When the mouse is grabbed, send the application the motion associated with
Sam Lantinga <slouken@lokigames.com>
parents:
75
diff
changeset
|
181 } else { |
2bddc38a9f5d
When the mouse is grabbed, send the application the motion associated with
Sam Lantinga <slouken@lokigames.com>
parents:
75
diff
changeset
|
182 posted = SDL_PrivateMouseMotion(0, 0, |
2bddc38a9f5d
When the mouse is grabbed, send the application the motion associated with
Sam Lantinga <slouken@lokigames.com>
parents:
75
diff
changeset
|
183 xevent.xcrossing.x, |
2bddc38a9f5d
When the mouse is grabbed, send the application the motion associated with
Sam Lantinga <slouken@lokigames.com>
parents:
75
diff
changeset
|
184 xevent.xcrossing.y); |
2bddc38a9f5d
When the mouse is grabbed, send the application the motion associated with
Sam Lantinga <slouken@lokigames.com>
parents:
75
diff
changeset
|
185 } |
0 | 186 } |
187 } | |
188 break; | |
189 | |
190 /* Losing mouse coverage? */ | |
191 case LeaveNotify: { | |
192 #ifdef DEBUG_XEVENTS | |
82
2bddc38a9f5d
When the mouse is grabbed, send the application the motion associated with
Sam Lantinga <slouken@lokigames.com>
parents:
75
diff
changeset
|
193 printf("LeaveNotify! (%d,%d)\n", xevent.xcrossing.x, xevent.xcrossing.y); |
0 | 194 if ( xevent.xcrossing.mode == NotifyGrab ) |
195 printf("Mode: NotifyGrab\n"); | |
196 if ( xevent.xcrossing.mode == NotifyUngrab ) | |
197 printf("Mode: NotifyUngrab\n"); | |
198 #endif | |
199 if ( (xevent.xcrossing.mode != NotifyGrab) && | |
496
864a66f028d8
Don't be fooled by unclutter - the mouse isn't really leaving our window
Sam Lantinga <slouken@libsdl.org>
parents:
412
diff
changeset
|
200 (xevent.xcrossing.mode != NotifyUngrab) && |
864a66f028d8
Don't be fooled by unclutter - the mouse isn't really leaving our window
Sam Lantinga <slouken@libsdl.org>
parents:
412
diff
changeset
|
201 (xevent.xcrossing.detail != NotifyInferior) ) { |
82
2bddc38a9f5d
When the mouse is grabbed, send the application the motion associated with
Sam Lantinga <slouken@lokigames.com>
parents:
75
diff
changeset
|
202 if ( this->input_grab == SDL_GRAB_OFF ) { |
2bddc38a9f5d
When the mouse is grabbed, send the application the motion associated with
Sam Lantinga <slouken@lokigames.com>
parents:
75
diff
changeset
|
203 posted = SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); |
2bddc38a9f5d
When the mouse is grabbed, send the application the motion associated with
Sam Lantinga <slouken@lokigames.com>
parents:
75
diff
changeset
|
204 } else { |
2bddc38a9f5d
When the mouse is grabbed, send the application the motion associated with
Sam Lantinga <slouken@lokigames.com>
parents:
75
diff
changeset
|
205 posted = SDL_PrivateMouseMotion(0, 0, |
2bddc38a9f5d
When the mouse is grabbed, send the application the motion associated with
Sam Lantinga <slouken@lokigames.com>
parents:
75
diff
changeset
|
206 xevent.xcrossing.x, |
2bddc38a9f5d
When the mouse is grabbed, send the application the motion associated with
Sam Lantinga <slouken@lokigames.com>
parents:
75
diff
changeset
|
207 xevent.xcrossing.y); |
2bddc38a9f5d
When the mouse is grabbed, send the application the motion associated with
Sam Lantinga <slouken@lokigames.com>
parents:
75
diff
changeset
|
208 } |
0 | 209 } |
210 } | |
211 break; | |
212 | |
213 /* Gaining input focus? */ | |
214 case FocusIn: { | |
215 #ifdef DEBUG_XEVENTS | |
216 printf("FocusIn!\n"); | |
217 #endif | |
218 posted = SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS); | |
219 | |
220 /* Queue entry into fullscreen mode */ | |
221 switch_waiting = 0x01 | SDL_FULLSCREEN; | |
222 switch_time = SDL_GetTicks() + 1500; | |
223 } | |
224 break; | |
225 | |
226 /* Losing input focus? */ | |
227 case FocusOut: { | |
228 #ifdef DEBUG_XEVENTS | |
229 printf("FocusOut!\n"); | |
230 #endif | |
231 posted = SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS); | |
232 | |
233 /* Queue leaving fullscreen mode */ | |
234 switch_waiting = 0x01; | |
235 switch_time = SDL_GetTicks() + 200; | |
236 } | |
237 break; | |
238 | |
239 /* Generated upon EnterWindow and FocusIn */ | |
240 case KeymapNotify: { | |
14
c3e9d4a623c1
Fixed stuck keys when changing the video mode
Sam Lantinga <slouken@lokigames.com>
parents:
12
diff
changeset
|
241 #ifdef DEBUG_XEVENTS |
c3e9d4a623c1
Fixed stuck keys when changing the video mode
Sam Lantinga <slouken@lokigames.com>
parents:
12
diff
changeset
|
242 printf("KeymapNotify!\n"); |
c3e9d4a623c1
Fixed stuck keys when changing the video mode
Sam Lantinga <slouken@lokigames.com>
parents:
12
diff
changeset
|
243 #endif |
0 | 244 X11_SetKeyboardState(SDL_Display, xevent.xkeymap.key_vector); |
245 } | |
246 break; | |
247 | |
248 /* Mouse motion? */ | |
249 case MotionNotify: { | |
250 if ( SDL_VideoSurface ) { | |
251 if ( mouse_relative ) { | |
252 if ( using_dga & DGA_MOUSE ) { | |
253 #ifdef DEBUG_MOTION | |
254 printf("DGA motion: %d,%d\n", xevent.xmotion.x_root, xevent.xmotion.y_root); | |
255 #endif | |
256 posted = SDL_PrivateMouseMotion(0, 1, | |
257 xevent.xmotion.x_root, | |
258 xevent.xmotion.y_root); | |
259 } else { | |
260 posted = X11_WarpedMotion(this,&xevent); | |
261 } | |
262 } else { | |
82
2bddc38a9f5d
When the mouse is grabbed, send the application the motion associated with
Sam Lantinga <slouken@lokigames.com>
parents:
75
diff
changeset
|
263 #ifdef DEBUG_MOTION |
2bddc38a9f5d
When the mouse is grabbed, send the application the motion associated with
Sam Lantinga <slouken@lokigames.com>
parents:
75
diff
changeset
|
264 printf("X11 motion: %d,%d\n", xevent.xmotion.x, xevent.xmotion.y); |
2bddc38a9f5d
When the mouse is grabbed, send the application the motion associated with
Sam Lantinga <slouken@lokigames.com>
parents:
75
diff
changeset
|
265 #endif |
0 | 266 posted = SDL_PrivateMouseMotion(0, 0, |
267 xevent.xmotion.x, | |
268 xevent.xmotion.y); | |
269 } | |
270 } | |
271 } | |
272 break; | |
273 | |
274 /* Mouse button press? */ | |
275 case ButtonPress: { | |
276 posted = SDL_PrivateMouseButton(SDL_PRESSED, | |
277 xevent.xbutton.button, 0, 0); | |
278 } | |
279 break; | |
280 | |
281 /* Mouse button release? */ | |
282 case ButtonRelease: { | |
283 posted = SDL_PrivateMouseButton(SDL_RELEASED, | |
284 xevent.xbutton.button, 0, 0); | |
285 } | |
286 break; | |
287 | |
288 /* Key press? */ | |
289 case KeyPress: { | |
290 SDL_keysym keysym; | |
14
c3e9d4a623c1
Fixed stuck keys when changing the video mode
Sam Lantinga <slouken@lokigames.com>
parents:
12
diff
changeset
|
291 |
c3e9d4a623c1
Fixed stuck keys when changing the video mode
Sam Lantinga <slouken@lokigames.com>
parents:
12
diff
changeset
|
292 #ifdef DEBUG_XEVENTS |
c3e9d4a623c1
Fixed stuck keys when changing the video mode
Sam Lantinga <slouken@lokigames.com>
parents:
12
diff
changeset
|
293 printf("KeyPress (X11 keycode = 0x%X)\n", xevent.xkey.keycode); |
c3e9d4a623c1
Fixed stuck keys when changing the video mode
Sam Lantinga <slouken@lokigames.com>
parents:
12
diff
changeset
|
294 #endif |
0 | 295 posted = SDL_PrivateKeyboard(SDL_PRESSED, |
296 X11_TranslateKey(SDL_Display, &xevent.xkey, | |
297 xevent.xkey.keycode, | |
298 &keysym)); | |
299 } | |
300 break; | |
301 | |
302 /* Key release? */ | |
303 case KeyRelease: { | |
304 SDL_keysym keysym; | |
305 | |
14
c3e9d4a623c1
Fixed stuck keys when changing the video mode
Sam Lantinga <slouken@lokigames.com>
parents:
12
diff
changeset
|
306 #ifdef DEBUG_XEVENTS |
c3e9d4a623c1
Fixed stuck keys when changing the video mode
Sam Lantinga <slouken@lokigames.com>
parents:
12
diff
changeset
|
307 printf("KeyRelease (X11 keycode = 0x%X)\n", xevent.xkey.keycode); |
c3e9d4a623c1
Fixed stuck keys when changing the video mode
Sam Lantinga <slouken@lokigames.com>
parents:
12
diff
changeset
|
308 #endif |
0 | 309 /* Check to see if this is a repeated key */ |
310 if ( ! X11_KeyRepeat(SDL_Display, &xevent) ) { | |
311 posted = SDL_PrivateKeyboard(SDL_RELEASED, | |
312 X11_TranslateKey(SDL_Display, &xevent.xkey, | |
313 xevent.xkey.keycode, | |
314 &keysym)); | |
315 } | |
316 } | |
317 break; | |
318 | |
319 /* Have we been iconified? */ | |
320 case UnmapNotify: { | |
321 #ifdef DEBUG_XEVENTS | |
322 printf("UnmapNotify!\n"); | |
323 #endif | |
324 /* If we're active, make ourselves inactive */ | |
325 if ( SDL_GetAppState() & SDL_APPACTIVE ) { | |
326 /* Swap out the gamma before we go inactive */ | |
327 X11_SwapVidModeGamma(this); | |
328 | |
329 /* Send an internal deactivate event */ | |
330 posted = SDL_PrivateAppActive(0, | |
331 SDL_APPACTIVE|SDL_APPINPUTFOCUS); | |
332 } | |
333 } | |
334 break; | |
335 | |
336 /* Have we been restored? */ | |
337 case MapNotify: { | |
338 #ifdef DEBUG_XEVENTS | |
339 printf("MapNotify!\n"); | |
340 #endif | |
341 /* If we're not active, make ourselves active */ | |
342 if ( !(SDL_GetAppState() & SDL_APPACTIVE) ) { | |
343 /* Send an internal activate event */ | |
344 posted = SDL_PrivateAppActive(1, SDL_APPACTIVE); | |
345 | |
346 /* Now that we're active, swap the gamma back */ | |
347 X11_SwapVidModeGamma(this); | |
348 } | |
349 | |
350 if ( SDL_VideoSurface && | |
351 (SDL_VideoSurface->flags & SDL_FULLSCREEN) ) { | |
352 X11_EnterFullScreen(this); | |
353 } else { | |
354 X11_GrabInputNoLock(this, this->input_grab); | |
355 } | |
8
5574376c451d
Fixed relative motion checking after restore under X11
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
356 X11_CheckMouseModeNoLock(this); |
5574376c451d
Fixed relative motion checking after restore under X11
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
357 |
0 | 358 if ( SDL_VideoSurface ) { |
359 X11_RefreshDisplay(this); | |
360 } | |
361 } | |
362 break; | |
363 | |
364 /* Have we been resized or moved? */ | |
365 case ConfigureNotify: { | |
366 #ifdef DEBUG_XEVENTS | |
367 printf("ConfigureNotify! (resize: %dx%d)\n", xevent.xconfigure.width, xevent.xconfigure.height); | |
368 #endif | |
369 if ( SDL_VideoSurface ) { | |
370 if ((xevent.xconfigure.width != SDL_VideoSurface->w) || | |
371 (xevent.xconfigure.height != SDL_VideoSurface->h)) { | |
372 /* FIXME: Find a better fix for the bug with KDE 1.2 */ | |
373 if ( ! ((xevent.xconfigure.width == 32) && | |
374 (xevent.xconfigure.height == 32)) ) { | |
375 SDL_PrivateResize(xevent.xconfigure.width, | |
376 xevent.xconfigure.height); | |
377 } | |
378 } else { | |
379 /* OpenGL windows need to know about the change */ | |
380 if ( SDL_VideoSurface->flags & SDL_OPENGL ) { | |
381 SDL_PrivateExpose(); | |
382 } | |
383 } | |
384 } | |
385 } | |
386 break; | |
387 | |
388 /* Have we been requested to quit (or another client message?) */ | |
389 case ClientMessage: { | |
390 if ( (xevent.xclient.format == 32) && | |
391 (xevent.xclient.data.l[0] == WM_DELETE_WINDOW) ) | |
392 { | |
393 posted = SDL_PrivateQuit(); | |
394 } else | |
395 if ( SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE ) { | |
396 SDL_SysWMmsg wmmsg; | |
397 | |
398 SDL_VERSION(&wmmsg.version); | |
399 wmmsg.subsystem = SDL_SYSWM_X11; | |
400 wmmsg.event.xevent = xevent; | |
401 posted = SDL_PrivateSysWMEvent(&wmmsg); | |
402 } | |
403 } | |
404 break; | |
405 | |
406 /* Do we need to refresh ourselves? */ | |
407 case Expose: { | |
408 #ifdef DEBUG_XEVENTS | |
409 printf("Expose (count = %d)\n", xevent.xexpose.count); | |
410 #endif | |
411 if ( SDL_VideoSurface && (xevent.xexpose.count == 0) ) { | |
161
eb6b76a95f2d
An expose event is now sent when using XVideo output.
Sam Lantinga <slouken@libsdl.org>
parents:
111
diff
changeset
|
412 X11_RefreshDisplay(this); |
0 | 413 } |
414 } | |
415 break; | |
416 | |
417 default: { | |
418 #ifdef DEBUG_XEVENTS | |
419 printf("Unhandled event %d\n", xevent.type); | |
420 #endif | |
421 /* Only post the event if we're watching for it */ | |
422 if ( SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE ) { | |
423 SDL_SysWMmsg wmmsg; | |
424 | |
425 SDL_VERSION(&wmmsg.version); | |
426 wmmsg.subsystem = SDL_SYSWM_X11; | |
427 wmmsg.event.xevent = xevent; | |
428 posted = SDL_PrivateSysWMEvent(&wmmsg); | |
429 } | |
430 } | |
431 break; | |
432 } | |
433 return(posted); | |
434 } | |
435 | |
436 /* Ack! XPending() actually performs a blocking read if no events available */ | |
437 int X11_Pending(Display *display) | |
438 { | |
439 /* Flush the display connection and look to see if events are queued */ | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
1159
diff
changeset
|
440 pXFlush(display); |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
1159
diff
changeset
|
441 if ( pXEventsQueued(display, QueuedAlready) ) { |
0 | 442 return(1); |
443 } | |
444 | |
445 /* More drastic measures are required -- see if X is ready to talk */ | |
446 { | |
447 static struct timeval zero_time; /* static == 0 */ | |
448 int x11_fd; | |
449 fd_set fdset; | |
450 | |
451 x11_fd = ConnectionNumber(display); | |
452 FD_ZERO(&fdset); | |
453 FD_SET(x11_fd, &fdset); | |
454 if ( select(x11_fd+1, &fdset, NULL, NULL, &zero_time) == 1 ) { | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
1159
diff
changeset
|
455 return(pXPending(display)); |
0 | 456 } |
457 } | |
458 | |
459 /* Oh well, nothing is ready .. */ | |
460 return(0); | |
461 } | |
462 | |
463 void X11_PumpEvents(_THIS) | |
464 { | |
465 int pending; | |
466 | |
467 /* Keep processing pending events */ | |
468 pending = 0; | |
469 while ( X11_Pending(SDL_Display) ) { | |
470 X11_DispatchEvent(this); | |
471 ++pending; | |
472 } | |
473 if ( switch_waiting ) { | |
474 Uint32 now; | |
475 | |
476 now = SDL_GetTicks(); | |
477 if ( pending || !SDL_VideoSurface ) { | |
478 /* Try again later... */ | |
479 if ( switch_waiting & SDL_FULLSCREEN ) { | |
480 switch_time = now + 1500; | |
481 } else { | |
482 switch_time = now + 200; | |
483 } | |
484 } else if ( now >= switch_time ) { | |
485 Uint32 go_fullscreen; | |
486 | |
487 go_fullscreen = switch_waiting & SDL_FULLSCREEN; | |
488 switch_waiting = 0; | |
489 if ( SDL_VideoSurface->flags & SDL_FULLSCREEN ) { | |
490 if ( go_fullscreen ) { | |
491 X11_EnterFullScreen(this); | |
492 } else { | |
493 X11_LeaveFullScreen(this); | |
494 } | |
495 } | |
496 /* Handle focus in/out when grabbed */ | |
497 if ( go_fullscreen ) { | |
498 X11_GrabInputNoLock(this, this->input_grab); | |
499 } else { | |
500 X11_GrabInputNoLock(this, SDL_GRAB_OFF); | |
501 } | |
502 X11_CheckMouseModeNoLock(this); | |
503 } | |
504 } | |
505 } | |
506 | |
507 void X11_InitKeymap(void) | |
508 { | |
509 int i; | |
510 | |
511 /* Odd keys used in international keyboards */ | |
512 for ( i=0; i<SDL_TABLESIZE(ODD_keymap); ++i ) | |
513 ODD_keymap[i] = SDLK_UNKNOWN; | |
514 | |
515 #ifdef XK_dead_circumflex | |
516 /* These X keysyms have 0xFE as the high byte */ | |
517 ODD_keymap[XK_dead_circumflex&0xFF] = SDLK_CARET; | |
518 #endif | |
805
df1a3218b468
Date: Wed, 04 Feb 2004 13:51:56 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
519 #ifdef XK_ISO_Level3_Shift |
df1a3218b468
Date: Wed, 04 Feb 2004 13:51:56 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
520 ODD_keymap[XK_ISO_Level3_Shift&0xFF] = SDLK_MODE; /* "Alt Gr" key */ |
df1a3218b468
Date: Wed, 04 Feb 2004 13:51:56 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
521 #endif |
0 | 522 |
523 /* Map the miscellaneous keys */ | |
524 for ( i=0; i<SDL_TABLESIZE(MISC_keymap); ++i ) | |
525 MISC_keymap[i] = SDLK_UNKNOWN; | |
526 | |
527 /* These X keysyms have 0xFF as the high byte */ | |
528 MISC_keymap[XK_BackSpace&0xFF] = SDLK_BACKSPACE; | |
529 MISC_keymap[XK_Tab&0xFF] = SDLK_TAB; | |
530 MISC_keymap[XK_Clear&0xFF] = SDLK_CLEAR; | |
531 MISC_keymap[XK_Return&0xFF] = SDLK_RETURN; | |
532 MISC_keymap[XK_Pause&0xFF] = SDLK_PAUSE; | |
533 MISC_keymap[XK_Escape&0xFF] = SDLK_ESCAPE; | |
534 MISC_keymap[XK_Delete&0xFF] = SDLK_DELETE; | |
535 | |
536 MISC_keymap[XK_KP_0&0xFF] = SDLK_KP0; /* Keypad 0-9 */ | |
537 MISC_keymap[XK_KP_1&0xFF] = SDLK_KP1; | |
538 MISC_keymap[XK_KP_2&0xFF] = SDLK_KP2; | |
539 MISC_keymap[XK_KP_3&0xFF] = SDLK_KP3; | |
540 MISC_keymap[XK_KP_4&0xFF] = SDLK_KP4; | |
541 MISC_keymap[XK_KP_5&0xFF] = SDLK_KP5; | |
542 MISC_keymap[XK_KP_6&0xFF] = SDLK_KP6; | |
543 MISC_keymap[XK_KP_7&0xFF] = SDLK_KP7; | |
544 MISC_keymap[XK_KP_8&0xFF] = SDLK_KP8; | |
545 MISC_keymap[XK_KP_9&0xFF] = SDLK_KP9; | |
546 MISC_keymap[XK_KP_Insert&0xFF] = SDLK_KP0; | |
547 MISC_keymap[XK_KP_End&0xFF] = SDLK_KP1; | |
548 MISC_keymap[XK_KP_Down&0xFF] = SDLK_KP2; | |
549 MISC_keymap[XK_KP_Page_Down&0xFF] = SDLK_KP3; | |
550 MISC_keymap[XK_KP_Left&0xFF] = SDLK_KP4; | |
551 MISC_keymap[XK_KP_Begin&0xFF] = SDLK_KP5; | |
552 MISC_keymap[XK_KP_Right&0xFF] = SDLK_KP6; | |
553 MISC_keymap[XK_KP_Home&0xFF] = SDLK_KP7; | |
554 MISC_keymap[XK_KP_Up&0xFF] = SDLK_KP8; | |
555 MISC_keymap[XK_KP_Page_Up&0xFF] = SDLK_KP9; | |
556 MISC_keymap[XK_KP_Delete&0xFF] = SDLK_KP_PERIOD; | |
557 MISC_keymap[XK_KP_Decimal&0xFF] = SDLK_KP_PERIOD; | |
558 MISC_keymap[XK_KP_Divide&0xFF] = SDLK_KP_DIVIDE; | |
559 MISC_keymap[XK_KP_Multiply&0xFF] = SDLK_KP_MULTIPLY; | |
560 MISC_keymap[XK_KP_Subtract&0xFF] = SDLK_KP_MINUS; | |
561 MISC_keymap[XK_KP_Add&0xFF] = SDLK_KP_PLUS; | |
562 MISC_keymap[XK_KP_Enter&0xFF] = SDLK_KP_ENTER; | |
563 MISC_keymap[XK_KP_Equal&0xFF] = SDLK_KP_EQUALS; | |
564 | |
565 MISC_keymap[XK_Up&0xFF] = SDLK_UP; | |
566 MISC_keymap[XK_Down&0xFF] = SDLK_DOWN; | |
567 MISC_keymap[XK_Right&0xFF] = SDLK_RIGHT; | |
568 MISC_keymap[XK_Left&0xFF] = SDLK_LEFT; | |
569 MISC_keymap[XK_Insert&0xFF] = SDLK_INSERT; | |
570 MISC_keymap[XK_Home&0xFF] = SDLK_HOME; | |
571 MISC_keymap[XK_End&0xFF] = SDLK_END; | |
572 MISC_keymap[XK_Page_Up&0xFF] = SDLK_PAGEUP; | |
573 MISC_keymap[XK_Page_Down&0xFF] = SDLK_PAGEDOWN; | |
574 | |
575 MISC_keymap[XK_F1&0xFF] = SDLK_F1; | |
576 MISC_keymap[XK_F2&0xFF] = SDLK_F2; | |
577 MISC_keymap[XK_F3&0xFF] = SDLK_F3; | |
578 MISC_keymap[XK_F4&0xFF] = SDLK_F4; | |
579 MISC_keymap[XK_F5&0xFF] = SDLK_F5; | |
580 MISC_keymap[XK_F6&0xFF] = SDLK_F6; | |
581 MISC_keymap[XK_F7&0xFF] = SDLK_F7; | |
582 MISC_keymap[XK_F8&0xFF] = SDLK_F8; | |
583 MISC_keymap[XK_F9&0xFF] = SDLK_F9; | |
584 MISC_keymap[XK_F10&0xFF] = SDLK_F10; | |
585 MISC_keymap[XK_F11&0xFF] = SDLK_F11; | |
586 MISC_keymap[XK_F12&0xFF] = SDLK_F12; | |
587 MISC_keymap[XK_F13&0xFF] = SDLK_F13; | |
588 MISC_keymap[XK_F14&0xFF] = SDLK_F14; | |
589 MISC_keymap[XK_F15&0xFF] = SDLK_F15; | |
590 | |
591 MISC_keymap[XK_Num_Lock&0xFF] = SDLK_NUMLOCK; | |
592 MISC_keymap[XK_Caps_Lock&0xFF] = SDLK_CAPSLOCK; | |
593 MISC_keymap[XK_Scroll_Lock&0xFF] = SDLK_SCROLLOCK; | |
594 MISC_keymap[XK_Shift_R&0xFF] = SDLK_RSHIFT; | |
595 MISC_keymap[XK_Shift_L&0xFF] = SDLK_LSHIFT; | |
596 MISC_keymap[XK_Control_R&0xFF] = SDLK_RCTRL; | |
597 MISC_keymap[XK_Control_L&0xFF] = SDLK_LCTRL; | |
598 MISC_keymap[XK_Alt_R&0xFF] = SDLK_RALT; | |
599 MISC_keymap[XK_Alt_L&0xFF] = SDLK_LALT; | |
600 MISC_keymap[XK_Meta_R&0xFF] = SDLK_RMETA; | |
601 MISC_keymap[XK_Meta_L&0xFF] = SDLK_LMETA; | |
602 MISC_keymap[XK_Super_L&0xFF] = SDLK_LSUPER; /* Left "Windows" */ | |
603 MISC_keymap[XK_Super_R&0xFF] = SDLK_RSUPER; /* Right "Windows */ | |
604 MISC_keymap[XK_Mode_switch&0xFF] = SDLK_MODE; /* "Alt Gr" key */ | |
605 MISC_keymap[XK_Multi_key&0xFF] = SDLK_COMPOSE; /* Multi-key compose */ | |
606 | |
607 MISC_keymap[XK_Help&0xFF] = SDLK_HELP; | |
608 MISC_keymap[XK_Print&0xFF] = SDLK_PRINT; | |
609 MISC_keymap[XK_Sys_Req&0xFF] = SDLK_SYSREQ; | |
610 MISC_keymap[XK_Break&0xFF] = SDLK_BREAK; | |
611 MISC_keymap[XK_Menu&0xFF] = SDLK_MENU; | |
612 MISC_keymap[XK_Hyper_R&0xFF] = SDLK_MENU; /* Windows "Menu" key */ | |
613 } | |
614 | |
615 SDL_keysym *X11_TranslateKey(Display *display, XKeyEvent *xkey, KeyCode kc, | |
616 SDL_keysym *keysym) | |
617 { | |
618 KeySym xsym; | |
619 | |
620 /* Get the raw keyboard scancode */ | |
621 keysym->scancode = kc; | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
1159
diff
changeset
|
622 xsym = pXKeycodeToKeysym(display, kc, 0); |
0 | 623 #ifdef DEBUG_KEYS |
624 fprintf(stderr, "Translating key 0x%.4x (%d)\n", xsym, kc); | |
625 #endif | |
626 /* Get the translated SDL virtual keysym */ | |
627 keysym->sym = SDLK_UNKNOWN; | |
628 if ( xsym ) { | |
629 switch (xsym>>8) { | |
630 case 0x1005FF: | |
631 #ifdef SunXK_F36 | |
632 if ( xsym == SunXK_F36 ) | |
633 keysym->sym = SDLK_F11; | |
634 #endif | |
635 #ifdef SunXK_F37 | |
636 if ( xsym == SunXK_F37 ) | |
637 keysym->sym = SDLK_F12; | |
638 #endif | |
639 break; | |
640 case 0x00: /* Latin 1 */ | |
641 case 0x01: /* Latin 2 */ | |
642 case 0x02: /* Latin 3 */ | |
643 case 0x03: /* Latin 4 */ | |
644 case 0x04: /* Katakana */ | |
645 case 0x05: /* Arabic */ | |
646 case 0x06: /* Cyrillic */ | |
647 case 0x07: /* Greek */ | |
648 case 0x08: /* Technical */ | |
649 case 0x0A: /* Publishing */ | |
650 case 0x0C: /* Hebrew */ | |
651 case 0x0D: /* Thai */ | |
652 keysym->sym = (SDLKey)(xsym&0xFF); | |
653 /* Map capital letter syms to lowercase */ | |
654 if ((keysym->sym >= 'A')&&(keysym->sym <= 'Z')) | |
655 keysym->sym += ('a'-'A'); | |
656 break; | |
657 case 0xFE: | |
658 keysym->sym = ODD_keymap[xsym&0xFF]; | |
659 break; | |
660 case 0xFF: | |
661 keysym->sym = MISC_keymap[xsym&0xFF]; | |
662 break; | |
663 default: | |
664 fprintf(stderr, | |
665 "X11: Unknown xsym, sym = 0x%04x\n", | |
666 (unsigned int)xsym); | |
667 break; | |
668 } | |
669 } else { | |
670 /* X11 doesn't know how to translate the key! */ | |
671 switch (kc) { | |
672 /* Caution: | |
673 These keycodes are from the Microsoft Keyboard | |
674 */ | |
675 case 115: | |
676 keysym->sym = SDLK_LSUPER; | |
677 break; | |
678 case 116: | |
679 keysym->sym = SDLK_RSUPER; | |
680 break; | |
681 case 117: | |
682 keysym->sym = SDLK_MENU; | |
683 break; | |
684 default: | |
685 /* | |
686 * no point in an error message; happens for | |
687 * several keys when we get a keymap notify | |
688 */ | |
689 break; | |
690 } | |
691 } | |
692 keysym->mod = KMOD_NONE; | |
693 | |
694 /* If UNICODE is on, get the UNICODE value for the key */ | |
695 keysym->unicode = 0; | |
696 if ( SDL_TranslateUNICODE && xkey ) { | |
697 static XComposeStatus state; | |
698 /* Until we handle the IM protocol, use XLookupString() */ | |
699 unsigned char keybuf[32]; | |
700 | |
701 #define BROKEN_XFREE86_INTERNATIONAL_KBD | |
702 /* This appears to be a magical flag that is used with AltGr on | |
703 international keyboards to signal alternate key translations. | |
704 The flag doesn't show up when in fullscreen mode (?) | |
705 FIXME: Check to see if this code is safe for other servers. | |
706 */ | |
707 #ifdef BROKEN_XFREE86_INTERNATIONAL_KBD | |
708 /* Work around what appears to be a bug in XFree86 */ | |
709 if ( SDL_GetModState() & KMOD_MODE ) { | |
710 xkey->state |= (1<<13); | |
711 } | |
712 #endif | |
713 /* Look up the translated value for the key event */ | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
1159
diff
changeset
|
714 if ( pXLookupString(xkey, (char *)keybuf, sizeof(keybuf), |
0 | 715 NULL, &state) ) { |
716 /* | |
717 * FIXME,: XLookupString() may yield more than one | |
718 * character, so we need a mechanism to allow for | |
719 * this (perhaps generate null keypress events with | |
720 * a unicode value) | |
721 */ | |
722 keysym->unicode = keybuf[0]; | |
723 } | |
724 } | |
725 return(keysym); | |
726 } | |
727 | |
728 /* X11 modifier masks for various keys */ | |
729 static unsigned meta_l_mask, meta_r_mask, alt_l_mask, alt_r_mask; | |
730 static unsigned num_mask, mode_switch_mask; | |
731 | |
732 static void get_modifier_masks(Display *display) | |
733 { | |
734 static unsigned got_masks; | |
735 int i, j; | |
736 XModifierKeymap *xmods; | |
737 unsigned n; | |
738 | |
739 if(got_masks) | |
740 return; | |
741 | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
1159
diff
changeset
|
742 xmods = pXGetModifierMapping(display); |
0 | 743 n = xmods->max_keypermod; |
744 for(i = 3; i < 8; i++) { | |
745 for(j = 0; j < n; j++) { | |
746 KeyCode kc = xmods->modifiermap[i * n + j]; | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
1159
diff
changeset
|
747 KeySym ks = pXKeycodeToKeysym(display, kc, 0); |
0 | 748 unsigned mask = 1 << i; |
749 switch(ks) { | |
750 case XK_Num_Lock: | |
751 num_mask = mask; break; | |
752 case XK_Alt_L: | |
753 alt_l_mask = mask; break; | |
754 case XK_Alt_R: | |
755 alt_r_mask = mask; break; | |
756 case XK_Meta_L: | |
757 meta_l_mask = mask; break; | |
758 case XK_Meta_R: | |
759 meta_r_mask = mask; break; | |
760 case XK_Mode_switch: | |
761 mode_switch_mask = mask; break; | |
762 } | |
763 } | |
764 } | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
1159
diff
changeset
|
765 pXFreeModifiermap(xmods); |
0 | 766 got_masks = 1; |
767 } | |
768 | |
769 | |
770 /* | |
771 * This function is semi-official; it is not officially exported and should | |
772 * not be considered part of the SDL API, but may be used by client code | |
773 * that *really* needs it (including legacy code). | |
774 * It is slow, though, and should be avoided if possible. | |
775 * | |
776 * Note that it isn't completely accurate either; in particular, multi-key | |
777 * sequences (dead accents, compose key sequences) will not work since the | |
778 * state has been irrevocably lost. | |
779 */ | |
780 Uint16 X11_KeyToUnicode(SDLKey keysym, SDLMod modifiers) | |
781 { | |
782 struct SDL_VideoDevice *this = current_video; | |
783 char keybuf[32]; | |
784 int i; | |
785 KeySym xsym = 0; | |
786 XKeyEvent xkey; | |
787 Uint16 unicode; | |
788 | |
789 if ( !this || !SDL_Display ) { | |
790 return 0; | |
791 } | |
792 | |
793 memset(&xkey, 0, sizeof(xkey)); | |
794 xkey.display = SDL_Display; | |
795 | |
796 xsym = keysym; /* last resort if not found */ | |
797 for (i = 0; i < 256; ++i) { | |
798 if ( MISC_keymap[i] == keysym ) { | |
799 xsym = 0xFF00 | i; | |
800 break; | |
801 } else if ( ODD_keymap[i] == keysym ) { | |
802 xsym = 0xFE00 | i; | |
803 break; | |
804 } | |
805 } | |
806 | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
1159
diff
changeset
|
807 xkey.keycode = pXKeysymToKeycode(xkey.display, xsym); |
0 | 808 |
809 get_modifier_masks(SDL_Display); | |
810 if(modifiers & KMOD_SHIFT) | |
811 xkey.state |= ShiftMask; | |
812 if(modifiers & KMOD_CAPS) | |
813 xkey.state |= LockMask; | |
814 if(modifiers & KMOD_CTRL) | |
815 xkey.state |= ControlMask; | |
816 if(modifiers & KMOD_MODE) | |
817 xkey.state |= mode_switch_mask; | |
818 if(modifiers & KMOD_LALT) | |
819 xkey.state |= alt_l_mask; | |
820 if(modifiers & KMOD_RALT) | |
821 xkey.state |= alt_r_mask; | |
822 if(modifiers & KMOD_LMETA) | |
823 xkey.state |= meta_l_mask; | |
824 if(modifiers & KMOD_RMETA) | |
825 xkey.state |= meta_r_mask; | |
826 if(modifiers & KMOD_NUM) | |
827 xkey.state |= num_mask; | |
828 | |
829 unicode = 0; | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
1159
diff
changeset
|
830 if ( pXLookupString(&xkey, keybuf, sizeof(keybuf), NULL, NULL) ) |
0 | 831 unicode = (unsigned char)keybuf[0]; |
832 return(unicode); | |
833 } | |
834 | |
835 /* | |
836 * Called when focus is regained, to read the keyboard state and generate | |
837 * synthetic keypress/release events. | |
838 * key_vec is a bit vector of keycodes (256 bits) | |
839 */ | |
840 void X11_SetKeyboardState(Display *display, const char *key_vec) | |
841 { | |
842 char keys_return[32]; | |
412
ac59b067815b
Fix uninitialized variable warning
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
843 int i; |
0 | 844 KeyCode xcode[SDLK_LAST]; |
845 Uint8 new_kstate[SDLK_LAST]; | |
846 Uint8 *kstate = SDL_GetKeyState(NULL); | |
111
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
847 SDLMod modstate; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
848 Window junk_window; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
849 int x, y; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
850 unsigned int mask; |
0 | 851 |
852 /* The first time the window is mapped, we initialize key state */ | |
853 if ( ! key_vec ) { | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
1159
diff
changeset
|
854 pXQueryKeymap(display, keys_return); |
0 | 855 key_vec = keys_return; |
856 } | |
857 | |
111
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
858 /* Get the keyboard modifier state */ |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
859 modstate = 0; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
860 get_modifier_masks(display); |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
1159
diff
changeset
|
861 if ( pXQueryPointer(display, DefaultRootWindow(display), |
111
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
862 &junk_window, &junk_window, &x, &y, &x, &y, &mask) ) { |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
863 if ( mask & LockMask ) { |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
864 modstate |= KMOD_CAPS; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
865 } |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
866 if ( mask & mode_switch_mask ) { |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
867 modstate |= KMOD_MODE; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
868 } |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
869 if ( mask & num_mask ) { |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
870 modstate |= KMOD_NUM; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
871 } |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
872 } |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
873 |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
874 /* Zero the new keyboard state and generate it */ |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
875 memset(new_kstate, SDL_RELEASED, sizeof(new_kstate)); |
0 | 876 /* |
877 * An obvious optimisation is to check entire longwords at a time in | |
878 * both loops, but we can't be sure the arrays are aligned so it's not | |
879 * worth the extra complexity | |
880 */ | |
881 for(i = 0; i < 32; i++) { | |
882 int j; | |
883 if(!key_vec[i]) | |
884 continue; | |
885 for(j = 0; j < 8; j++) { | |
886 if(key_vec[i] & (1 << j)) { | |
887 SDL_keysym sk; | |
888 KeyCode kc = i << 3 | j; | |
889 X11_TranslateKey(display, NULL, kc, &sk); | |
111
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
890 new_kstate[sk.sym] = SDL_PRESSED; |
0 | 891 xcode[sk.sym] = kc; |
892 } | |
893 } | |
894 } | |
895 for(i = SDLK_FIRST+1; i < SDLK_LAST; i++) { | |
111
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
896 int state = new_kstate[i]; |
0 | 897 |
111
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
898 if ( state == SDL_PRESSED ) { |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
899 switch (i) { |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
900 case SDLK_LSHIFT: |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
901 modstate |= KMOD_LSHIFT; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
902 break; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
903 case SDLK_RSHIFT: |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
904 modstate |= KMOD_RSHIFT; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
905 break; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
906 case SDLK_LCTRL: |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
907 modstate |= KMOD_LCTRL; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
908 break; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
909 case SDLK_RCTRL: |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
910 modstate |= KMOD_RCTRL; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
911 break; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
912 case SDLK_LALT: |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
913 modstate |= KMOD_LALT; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
914 break; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
915 case SDLK_RALT: |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
916 modstate |= KMOD_RALT; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
917 break; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
918 case SDLK_LMETA: |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
919 modstate |= KMOD_LMETA; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
920 break; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
921 case SDLK_RMETA: |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
922 modstate |= KMOD_RMETA; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
923 break; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
924 default: |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
925 break; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
926 } |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
927 } |
412
ac59b067815b
Fix uninitialized variable warning
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
928 if ( kstate[i] != state ) { |
111
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
929 kstate[i] = state; |
0 | 930 } |
931 } | |
111
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
932 |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
933 /* Hack - set toggle key state */ |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
934 if ( modstate & KMOD_CAPS ) { |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
935 kstate[SDLK_CAPSLOCK] = SDL_PRESSED; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
936 } else { |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
937 kstate[SDLK_CAPSLOCK] = SDL_RELEASED; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
938 } |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
939 if ( modstate & KMOD_NUM ) { |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
940 kstate[SDLK_NUMLOCK] = SDL_PRESSED; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
941 } else { |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
942 kstate[SDLK_NUMLOCK] = SDL_RELEASED; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
943 } |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
944 |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
945 /* Set the final modifier state */ |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
946 SDL_SetModState(modstate); |
0 | 947 } |
948 | |
949 void X11_InitOSKeymap(_THIS) | |
950 { | |
951 X11_InitKeymap(); | |
952 } | |
953 |