Mercurial > sdl-ios-xcode
annotate src/video/x11/SDL_x11events.c @ 641:df178851293b
Date: 28 Jun 2003 22:42:52 +0100
From: Alan Swanson
Subject: Re: [SDL] New XFree 4.3 Video Mode Patch
I have a wee amendment that moves the qsort in set_best_resolution
to only occur after failing to find an exact match only. This would
make absolutely sure we get a user set mode.
While I've never had any problems for my normal resolutions (1280x1024,
1024x768, 800x600 & 640,480) while closely examining the output from
qsort I've noticed it doesn't seem to sort the modes fully. These is
one definite wrong at 1152x768 and a few that just look wrong to me.
From a program (attached) I made to examine this more easily. X has
sorted its mode list using the same method as ours (plus frequency),
and our user modes get inserted without any other movement.
On the patch I've made I've also changed cmpmodes to sort on vertical
resolution and then horizontal. Ie vertical is now most significant
bit.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 28 Jun 2003 21:52:26 +0000 |
parents | 864a66f028d8 |
children | b8d311d90021 |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
297
f6ffac90895c
Updated copyright information for 2002
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
3 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 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; | |
77 if ( XPending(display) ) { | |
78 XPeekEvent(display, &peekevent); | |
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; |
83 XNextEvent(display, &peekevent); | |
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 */ | |
118 while ( XCheckTypedEvent(SDL_Display, MotionNotify, xevent) ) { | |
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; | |
130 XWarpPointer(SDL_Display, None, SDL_Window, 0, 0, 0, 0, | |
131 mouse_last.x, mouse_last.y); | |
132 for ( i=0; i<10; ++i ) { | |
133 XMaskEvent(SDL_Display, PointerMotionMask, xevent); | |
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 | |
162 XNextEvent(SDL_Display, &xevent); | |
163 | |
164 posted = 0; | |
165 switch (xevent.type) { | |
166 | |
167 /* Gaining mouse coverage? */ | |
168 case EnterNotify: { | |
169 #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
|
170 printf("EnterNotify! (%d,%d)\n", xevent.xcrossing.x, xevent.xcrossing.y); |
0 | 171 if ( xevent.xcrossing.mode == NotifyGrab ) |
172 printf("Mode: NotifyGrab\n"); | |
173 if ( xevent.xcrossing.mode == NotifyUngrab ) | |
174 printf("Mode: NotifyUngrab\n"); | |
175 #endif | |
176 if ( (xevent.xcrossing.mode != NotifyGrab) && | |
177 (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
|
178 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
|
179 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
|
180 } else { |
2bddc38a9f5d
When the mouse is grabbed, send the application the motion associated with
Sam Lantinga <slouken@lokigames.com>
parents:
75
diff
changeset
|
181 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
|
182 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
|
183 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
|
184 } |
0 | 185 } |
186 } | |
187 break; | |
188 | |
189 /* Losing mouse coverage? */ | |
190 case LeaveNotify: { | |
191 #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
|
192 printf("LeaveNotify! (%d,%d)\n", xevent.xcrossing.x, xevent.xcrossing.y); |
0 | 193 if ( xevent.xcrossing.mode == NotifyGrab ) |
194 printf("Mode: NotifyGrab\n"); | |
195 if ( xevent.xcrossing.mode == NotifyUngrab ) | |
196 printf("Mode: NotifyUngrab\n"); | |
197 #endif | |
198 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
|
199 (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
|
200 (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
|
201 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
|
202 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
|
203 } else { |
2bddc38a9f5d
When the mouse is grabbed, send the application the motion associated with
Sam Lantinga <slouken@lokigames.com>
parents:
75
diff
changeset
|
204 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
|
205 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
|
206 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
|
207 } |
0 | 208 } |
209 } | |
210 break; | |
211 | |
212 /* Gaining input focus? */ | |
213 case FocusIn: { | |
214 #ifdef DEBUG_XEVENTS | |
215 printf("FocusIn!\n"); | |
216 #endif | |
217 posted = SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS); | |
218 | |
219 /* Queue entry into fullscreen mode */ | |
220 switch_waiting = 0x01 | SDL_FULLSCREEN; | |
221 switch_time = SDL_GetTicks() + 1500; | |
222 } | |
223 break; | |
224 | |
225 /* Losing input focus? */ | |
226 case FocusOut: { | |
227 #ifdef DEBUG_XEVENTS | |
228 printf("FocusOut!\n"); | |
229 #endif | |
230 posted = SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS); | |
231 | |
232 /* Queue leaving fullscreen mode */ | |
233 switch_waiting = 0x01; | |
234 switch_time = SDL_GetTicks() + 200; | |
235 } | |
236 break; | |
237 | |
238 /* Generated upon EnterWindow and FocusIn */ | |
239 case KeymapNotify: { | |
14
c3e9d4a623c1
Fixed stuck keys when changing the video mode
Sam Lantinga <slouken@lokigames.com>
parents:
12
diff
changeset
|
240 #ifdef DEBUG_XEVENTS |
c3e9d4a623c1
Fixed stuck keys when changing the video mode
Sam Lantinga <slouken@lokigames.com>
parents:
12
diff
changeset
|
241 printf("KeymapNotify!\n"); |
c3e9d4a623c1
Fixed stuck keys when changing the video mode
Sam Lantinga <slouken@lokigames.com>
parents:
12
diff
changeset
|
242 #endif |
0 | 243 X11_SetKeyboardState(SDL_Display, xevent.xkeymap.key_vector); |
244 } | |
245 break; | |
246 | |
247 /* Mouse motion? */ | |
248 case MotionNotify: { | |
249 if ( SDL_VideoSurface ) { | |
250 if ( mouse_relative ) { | |
251 if ( using_dga & DGA_MOUSE ) { | |
252 #ifdef DEBUG_MOTION | |
253 printf("DGA motion: %d,%d\n", xevent.xmotion.x_root, xevent.xmotion.y_root); | |
254 #endif | |
255 posted = SDL_PrivateMouseMotion(0, 1, | |
256 xevent.xmotion.x_root, | |
257 xevent.xmotion.y_root); | |
258 } else { | |
259 posted = X11_WarpedMotion(this,&xevent); | |
260 } | |
261 } else { | |
82
2bddc38a9f5d
When the mouse is grabbed, send the application the motion associated with
Sam Lantinga <slouken@lokigames.com>
parents:
75
diff
changeset
|
262 #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
|
263 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
|
264 #endif |
0 | 265 posted = SDL_PrivateMouseMotion(0, 0, |
266 xevent.xmotion.x, | |
267 xevent.xmotion.y); | |
268 } | |
269 } | |
270 } | |
271 break; | |
272 | |
273 /* Mouse button press? */ | |
274 case ButtonPress: { | |
275 posted = SDL_PrivateMouseButton(SDL_PRESSED, | |
276 xevent.xbutton.button, 0, 0); | |
277 } | |
278 break; | |
279 | |
280 /* Mouse button release? */ | |
281 case ButtonRelease: { | |
282 posted = SDL_PrivateMouseButton(SDL_RELEASED, | |
283 xevent.xbutton.button, 0, 0); | |
284 } | |
285 break; | |
286 | |
287 /* Key press? */ | |
288 case KeyPress: { | |
289 SDL_keysym keysym; | |
14
c3e9d4a623c1
Fixed stuck keys when changing the video mode
Sam Lantinga <slouken@lokigames.com>
parents:
12
diff
changeset
|
290 |
c3e9d4a623c1
Fixed stuck keys when changing the video mode
Sam Lantinga <slouken@lokigames.com>
parents:
12
diff
changeset
|
291 #ifdef DEBUG_XEVENTS |
c3e9d4a623c1
Fixed stuck keys when changing the video mode
Sam Lantinga <slouken@lokigames.com>
parents:
12
diff
changeset
|
292 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
|
293 #endif |
0 | 294 posted = SDL_PrivateKeyboard(SDL_PRESSED, |
295 X11_TranslateKey(SDL_Display, &xevent.xkey, | |
296 xevent.xkey.keycode, | |
297 &keysym)); | |
298 } | |
299 break; | |
300 | |
301 /* Key release? */ | |
302 case KeyRelease: { | |
303 SDL_keysym keysym; | |
304 | |
14
c3e9d4a623c1
Fixed stuck keys when changing the video mode
Sam Lantinga <slouken@lokigames.com>
parents:
12
diff
changeset
|
305 #ifdef DEBUG_XEVENTS |
c3e9d4a623c1
Fixed stuck keys when changing the video mode
Sam Lantinga <slouken@lokigames.com>
parents:
12
diff
changeset
|
306 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
|
307 #endif |
0 | 308 /* Check to see if this is a repeated key */ |
309 if ( ! X11_KeyRepeat(SDL_Display, &xevent) ) { | |
310 posted = SDL_PrivateKeyboard(SDL_RELEASED, | |
311 X11_TranslateKey(SDL_Display, &xevent.xkey, | |
312 xevent.xkey.keycode, | |
313 &keysym)); | |
314 } | |
315 } | |
316 break; | |
317 | |
318 /* Have we been iconified? */ | |
319 case UnmapNotify: { | |
320 #ifdef DEBUG_XEVENTS | |
321 printf("UnmapNotify!\n"); | |
322 #endif | |
323 /* If we're active, make ourselves inactive */ | |
324 if ( SDL_GetAppState() & SDL_APPACTIVE ) { | |
325 /* Swap out the gamma before we go inactive */ | |
326 X11_SwapVidModeGamma(this); | |
327 | |
328 /* Send an internal deactivate event */ | |
329 posted = SDL_PrivateAppActive(0, | |
330 SDL_APPACTIVE|SDL_APPINPUTFOCUS); | |
331 } | |
332 } | |
333 break; | |
334 | |
335 /* Have we been restored? */ | |
336 case MapNotify: { | |
337 #ifdef DEBUG_XEVENTS | |
338 printf("MapNotify!\n"); | |
339 #endif | |
340 /* If we're not active, make ourselves active */ | |
341 if ( !(SDL_GetAppState() & SDL_APPACTIVE) ) { | |
342 /* Send an internal activate event */ | |
343 posted = SDL_PrivateAppActive(1, SDL_APPACTIVE); | |
344 | |
345 /* Now that we're active, swap the gamma back */ | |
346 X11_SwapVidModeGamma(this); | |
347 } | |
348 | |
349 if ( SDL_VideoSurface && | |
350 (SDL_VideoSurface->flags & SDL_FULLSCREEN) ) { | |
351 X11_EnterFullScreen(this); | |
352 } else { | |
353 X11_GrabInputNoLock(this, this->input_grab); | |
354 } | |
8
5574376c451d
Fixed relative motion checking after restore under X11
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
355 X11_CheckMouseModeNoLock(this); |
5574376c451d
Fixed relative motion checking after restore under X11
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
356 |
0 | 357 if ( SDL_VideoSurface ) { |
358 X11_RefreshDisplay(this); | |
359 } | |
360 } | |
361 break; | |
362 | |
363 /* Have we been resized or moved? */ | |
364 case ConfigureNotify: { | |
365 #ifdef DEBUG_XEVENTS | |
366 printf("ConfigureNotify! (resize: %dx%d)\n", xevent.xconfigure.width, xevent.xconfigure.height); | |
367 #endif | |
368 if ( SDL_VideoSurface ) { | |
369 if ((xevent.xconfigure.width != SDL_VideoSurface->w) || | |
370 (xevent.xconfigure.height != SDL_VideoSurface->h)) { | |
371 /* FIXME: Find a better fix for the bug with KDE 1.2 */ | |
372 if ( ! ((xevent.xconfigure.width == 32) && | |
373 (xevent.xconfigure.height == 32)) ) { | |
374 SDL_PrivateResize(xevent.xconfigure.width, | |
375 xevent.xconfigure.height); | |
376 } | |
377 } else { | |
378 /* OpenGL windows need to know about the change */ | |
379 if ( SDL_VideoSurface->flags & SDL_OPENGL ) { | |
380 SDL_PrivateExpose(); | |
381 } | |
382 } | |
383 } | |
384 } | |
385 break; | |
386 | |
387 /* Have we been requested to quit (or another client message?) */ | |
388 case ClientMessage: { | |
389 if ( (xevent.xclient.format == 32) && | |
390 (xevent.xclient.data.l[0] == WM_DELETE_WINDOW) ) | |
391 { | |
392 posted = SDL_PrivateQuit(); | |
393 } else | |
394 if ( SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE ) { | |
395 SDL_SysWMmsg wmmsg; | |
396 | |
397 SDL_VERSION(&wmmsg.version); | |
398 wmmsg.subsystem = SDL_SYSWM_X11; | |
399 wmmsg.event.xevent = xevent; | |
400 posted = SDL_PrivateSysWMEvent(&wmmsg); | |
401 } | |
402 } | |
403 break; | |
404 | |
405 /* Do we need to refresh ourselves? */ | |
406 case Expose: { | |
407 #ifdef DEBUG_XEVENTS | |
408 printf("Expose (count = %d)\n", xevent.xexpose.count); | |
409 #endif | |
410 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
|
411 X11_RefreshDisplay(this); |
0 | 412 } |
413 } | |
414 break; | |
415 | |
416 default: { | |
417 #ifdef DEBUG_XEVENTS | |
418 printf("Unhandled event %d\n", xevent.type); | |
419 #endif | |
420 /* Only post the event if we're watching for it */ | |
421 if ( SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE ) { | |
422 SDL_SysWMmsg wmmsg; | |
423 | |
424 SDL_VERSION(&wmmsg.version); | |
425 wmmsg.subsystem = SDL_SYSWM_X11; | |
426 wmmsg.event.xevent = xevent; | |
427 posted = SDL_PrivateSysWMEvent(&wmmsg); | |
428 } | |
429 } | |
430 break; | |
431 } | |
432 return(posted); | |
433 } | |
434 | |
435 /* Ack! XPending() actually performs a blocking read if no events available */ | |
436 int X11_Pending(Display *display) | |
437 { | |
438 /* Flush the display connection and look to see if events are queued */ | |
439 XFlush(display); | |
440 if ( XEventsQueued(display, QueuedAlready) ) { | |
441 return(1); | |
442 } | |
443 | |
444 /* More drastic measures are required -- see if X is ready to talk */ | |
445 { | |
446 static struct timeval zero_time; /* static == 0 */ | |
447 int x11_fd; | |
448 fd_set fdset; | |
449 | |
450 x11_fd = ConnectionNumber(display); | |
451 FD_ZERO(&fdset); | |
452 FD_SET(x11_fd, &fdset); | |
453 if ( select(x11_fd+1, &fdset, NULL, NULL, &zero_time) == 1 ) { | |
454 return(XPending(display)); | |
455 } | |
456 } | |
457 | |
458 /* Oh well, nothing is ready .. */ | |
459 return(0); | |
460 } | |
461 | |
462 void X11_PumpEvents(_THIS) | |
463 { | |
464 int pending; | |
465 | |
466 /* Keep processing pending events */ | |
467 pending = 0; | |
468 while ( X11_Pending(SDL_Display) ) { | |
469 X11_DispatchEvent(this); | |
470 ++pending; | |
471 } | |
472 if ( switch_waiting ) { | |
473 Uint32 now; | |
474 | |
475 now = SDL_GetTicks(); | |
476 if ( pending || !SDL_VideoSurface ) { | |
477 /* Try again later... */ | |
478 if ( switch_waiting & SDL_FULLSCREEN ) { | |
479 switch_time = now + 1500; | |
480 } else { | |
481 switch_time = now + 200; | |
482 } | |
483 } else if ( now >= switch_time ) { | |
484 Uint32 go_fullscreen; | |
485 | |
486 go_fullscreen = switch_waiting & SDL_FULLSCREEN; | |
487 switch_waiting = 0; | |
488 if ( SDL_VideoSurface->flags & SDL_FULLSCREEN ) { | |
489 if ( go_fullscreen ) { | |
490 X11_EnterFullScreen(this); | |
491 } else { | |
492 X11_LeaveFullScreen(this); | |
493 } | |
494 } | |
495 /* Handle focus in/out when grabbed */ | |
496 if ( go_fullscreen ) { | |
497 X11_GrabInputNoLock(this, this->input_grab); | |
498 } else { | |
499 X11_GrabInputNoLock(this, SDL_GRAB_OFF); | |
500 } | |
501 X11_CheckMouseModeNoLock(this); | |
502 } | |
503 } | |
504 } | |
505 | |
506 void X11_InitKeymap(void) | |
507 { | |
508 int i; | |
509 | |
510 /* Odd keys used in international keyboards */ | |
511 for ( i=0; i<SDL_TABLESIZE(ODD_keymap); ++i ) | |
512 ODD_keymap[i] = SDLK_UNKNOWN; | |
513 | |
514 #ifdef XK_dead_circumflex | |
515 /* These X keysyms have 0xFE as the high byte */ | |
516 ODD_keymap[XK_dead_circumflex&0xFF] = SDLK_CARET; | |
517 #endif | |
518 | |
519 /* Map the miscellaneous keys */ | |
520 for ( i=0; i<SDL_TABLESIZE(MISC_keymap); ++i ) | |
521 MISC_keymap[i] = SDLK_UNKNOWN; | |
522 | |
523 /* These X keysyms have 0xFF as the high byte */ | |
524 MISC_keymap[XK_BackSpace&0xFF] = SDLK_BACKSPACE; | |
525 MISC_keymap[XK_Tab&0xFF] = SDLK_TAB; | |
526 MISC_keymap[XK_Clear&0xFF] = SDLK_CLEAR; | |
527 MISC_keymap[XK_Return&0xFF] = SDLK_RETURN; | |
528 MISC_keymap[XK_Pause&0xFF] = SDLK_PAUSE; | |
529 MISC_keymap[XK_Escape&0xFF] = SDLK_ESCAPE; | |
530 MISC_keymap[XK_Delete&0xFF] = SDLK_DELETE; | |
531 | |
532 MISC_keymap[XK_KP_0&0xFF] = SDLK_KP0; /* Keypad 0-9 */ | |
533 MISC_keymap[XK_KP_1&0xFF] = SDLK_KP1; | |
534 MISC_keymap[XK_KP_2&0xFF] = SDLK_KP2; | |
535 MISC_keymap[XK_KP_3&0xFF] = SDLK_KP3; | |
536 MISC_keymap[XK_KP_4&0xFF] = SDLK_KP4; | |
537 MISC_keymap[XK_KP_5&0xFF] = SDLK_KP5; | |
538 MISC_keymap[XK_KP_6&0xFF] = SDLK_KP6; | |
539 MISC_keymap[XK_KP_7&0xFF] = SDLK_KP7; | |
540 MISC_keymap[XK_KP_8&0xFF] = SDLK_KP8; | |
541 MISC_keymap[XK_KP_9&0xFF] = SDLK_KP9; | |
542 MISC_keymap[XK_KP_Insert&0xFF] = SDLK_KP0; | |
543 MISC_keymap[XK_KP_End&0xFF] = SDLK_KP1; | |
544 MISC_keymap[XK_KP_Down&0xFF] = SDLK_KP2; | |
545 MISC_keymap[XK_KP_Page_Down&0xFF] = SDLK_KP3; | |
546 MISC_keymap[XK_KP_Left&0xFF] = SDLK_KP4; | |
547 MISC_keymap[XK_KP_Begin&0xFF] = SDLK_KP5; | |
548 MISC_keymap[XK_KP_Right&0xFF] = SDLK_KP6; | |
549 MISC_keymap[XK_KP_Home&0xFF] = SDLK_KP7; | |
550 MISC_keymap[XK_KP_Up&0xFF] = SDLK_KP8; | |
551 MISC_keymap[XK_KP_Page_Up&0xFF] = SDLK_KP9; | |
552 MISC_keymap[XK_KP_Delete&0xFF] = SDLK_KP_PERIOD; | |
553 MISC_keymap[XK_KP_Decimal&0xFF] = SDLK_KP_PERIOD; | |
554 MISC_keymap[XK_KP_Divide&0xFF] = SDLK_KP_DIVIDE; | |
555 MISC_keymap[XK_KP_Multiply&0xFF] = SDLK_KP_MULTIPLY; | |
556 MISC_keymap[XK_KP_Subtract&0xFF] = SDLK_KP_MINUS; | |
557 MISC_keymap[XK_KP_Add&0xFF] = SDLK_KP_PLUS; | |
558 MISC_keymap[XK_KP_Enter&0xFF] = SDLK_KP_ENTER; | |
559 MISC_keymap[XK_KP_Equal&0xFF] = SDLK_KP_EQUALS; | |
560 | |
561 MISC_keymap[XK_Up&0xFF] = SDLK_UP; | |
562 MISC_keymap[XK_Down&0xFF] = SDLK_DOWN; | |
563 MISC_keymap[XK_Right&0xFF] = SDLK_RIGHT; | |
564 MISC_keymap[XK_Left&0xFF] = SDLK_LEFT; | |
565 MISC_keymap[XK_Insert&0xFF] = SDLK_INSERT; | |
566 MISC_keymap[XK_Home&0xFF] = SDLK_HOME; | |
567 MISC_keymap[XK_End&0xFF] = SDLK_END; | |
568 MISC_keymap[XK_Page_Up&0xFF] = SDLK_PAGEUP; | |
569 MISC_keymap[XK_Page_Down&0xFF] = SDLK_PAGEDOWN; | |
570 | |
571 MISC_keymap[XK_F1&0xFF] = SDLK_F1; | |
572 MISC_keymap[XK_F2&0xFF] = SDLK_F2; | |
573 MISC_keymap[XK_F3&0xFF] = SDLK_F3; | |
574 MISC_keymap[XK_F4&0xFF] = SDLK_F4; | |
575 MISC_keymap[XK_F5&0xFF] = SDLK_F5; | |
576 MISC_keymap[XK_F6&0xFF] = SDLK_F6; | |
577 MISC_keymap[XK_F7&0xFF] = SDLK_F7; | |
578 MISC_keymap[XK_F8&0xFF] = SDLK_F8; | |
579 MISC_keymap[XK_F9&0xFF] = SDLK_F9; | |
580 MISC_keymap[XK_F10&0xFF] = SDLK_F10; | |
581 MISC_keymap[XK_F11&0xFF] = SDLK_F11; | |
582 MISC_keymap[XK_F12&0xFF] = SDLK_F12; | |
583 MISC_keymap[XK_F13&0xFF] = SDLK_F13; | |
584 MISC_keymap[XK_F14&0xFF] = SDLK_F14; | |
585 MISC_keymap[XK_F15&0xFF] = SDLK_F15; | |
586 | |
587 MISC_keymap[XK_Num_Lock&0xFF] = SDLK_NUMLOCK; | |
588 MISC_keymap[XK_Caps_Lock&0xFF] = SDLK_CAPSLOCK; | |
589 MISC_keymap[XK_Scroll_Lock&0xFF] = SDLK_SCROLLOCK; | |
590 MISC_keymap[XK_Shift_R&0xFF] = SDLK_RSHIFT; | |
591 MISC_keymap[XK_Shift_L&0xFF] = SDLK_LSHIFT; | |
592 MISC_keymap[XK_Control_R&0xFF] = SDLK_RCTRL; | |
593 MISC_keymap[XK_Control_L&0xFF] = SDLK_LCTRL; | |
594 MISC_keymap[XK_Alt_R&0xFF] = SDLK_RALT; | |
595 MISC_keymap[XK_Alt_L&0xFF] = SDLK_LALT; | |
596 MISC_keymap[XK_Meta_R&0xFF] = SDLK_RMETA; | |
597 MISC_keymap[XK_Meta_L&0xFF] = SDLK_LMETA; | |
598 MISC_keymap[XK_Super_L&0xFF] = SDLK_LSUPER; /* Left "Windows" */ | |
599 MISC_keymap[XK_Super_R&0xFF] = SDLK_RSUPER; /* Right "Windows */ | |
600 MISC_keymap[XK_Mode_switch&0xFF] = SDLK_MODE; /* "Alt Gr" key */ | |
601 MISC_keymap[XK_Multi_key&0xFF] = SDLK_COMPOSE; /* Multi-key compose */ | |
602 | |
603 MISC_keymap[XK_Help&0xFF] = SDLK_HELP; | |
604 MISC_keymap[XK_Print&0xFF] = SDLK_PRINT; | |
605 MISC_keymap[XK_Sys_Req&0xFF] = SDLK_SYSREQ; | |
606 MISC_keymap[XK_Break&0xFF] = SDLK_BREAK; | |
607 MISC_keymap[XK_Menu&0xFF] = SDLK_MENU; | |
608 MISC_keymap[XK_Hyper_R&0xFF] = SDLK_MENU; /* Windows "Menu" key */ | |
609 } | |
610 | |
611 SDL_keysym *X11_TranslateKey(Display *display, XKeyEvent *xkey, KeyCode kc, | |
612 SDL_keysym *keysym) | |
613 { | |
614 KeySym xsym; | |
615 | |
616 /* Get the raw keyboard scancode */ | |
617 keysym->scancode = kc; | |
618 xsym = XKeycodeToKeysym(display, kc, 0); | |
619 #ifdef DEBUG_KEYS | |
620 fprintf(stderr, "Translating key 0x%.4x (%d)\n", xsym, kc); | |
621 #endif | |
622 /* Get the translated SDL virtual keysym */ | |
623 keysym->sym = SDLK_UNKNOWN; | |
624 if ( xsym ) { | |
625 switch (xsym>>8) { | |
626 case 0x1005FF: | |
627 #ifdef SunXK_F36 | |
628 if ( xsym == SunXK_F36 ) | |
629 keysym->sym = SDLK_F11; | |
630 #endif | |
631 #ifdef SunXK_F37 | |
632 if ( xsym == SunXK_F37 ) | |
633 keysym->sym = SDLK_F12; | |
634 #endif | |
635 break; | |
636 case 0x00: /* Latin 1 */ | |
637 case 0x01: /* Latin 2 */ | |
638 case 0x02: /* Latin 3 */ | |
639 case 0x03: /* Latin 4 */ | |
640 case 0x04: /* Katakana */ | |
641 case 0x05: /* Arabic */ | |
642 case 0x06: /* Cyrillic */ | |
643 case 0x07: /* Greek */ | |
644 case 0x08: /* Technical */ | |
645 case 0x0A: /* Publishing */ | |
646 case 0x0C: /* Hebrew */ | |
647 case 0x0D: /* Thai */ | |
648 keysym->sym = (SDLKey)(xsym&0xFF); | |
649 /* Map capital letter syms to lowercase */ | |
650 if ((keysym->sym >= 'A')&&(keysym->sym <= 'Z')) | |
651 keysym->sym += ('a'-'A'); | |
652 break; | |
653 case 0xFE: | |
654 keysym->sym = ODD_keymap[xsym&0xFF]; | |
655 break; | |
656 case 0xFF: | |
657 keysym->sym = MISC_keymap[xsym&0xFF]; | |
658 break; | |
659 default: | |
660 fprintf(stderr, | |
661 "X11: Unknown xsym, sym = 0x%04x\n", | |
662 (unsigned int)xsym); | |
663 break; | |
664 } | |
665 } else { | |
666 /* X11 doesn't know how to translate the key! */ | |
667 switch (kc) { | |
668 /* Caution: | |
669 These keycodes are from the Microsoft Keyboard | |
670 */ | |
671 case 115: | |
672 keysym->sym = SDLK_LSUPER; | |
673 break; | |
674 case 116: | |
675 keysym->sym = SDLK_RSUPER; | |
676 break; | |
677 case 117: | |
678 keysym->sym = SDLK_MENU; | |
679 break; | |
680 default: | |
681 /* | |
682 * no point in an error message; happens for | |
683 * several keys when we get a keymap notify | |
684 */ | |
685 break; | |
686 } | |
687 } | |
688 keysym->mod = KMOD_NONE; | |
689 | |
690 /* If UNICODE is on, get the UNICODE value for the key */ | |
691 keysym->unicode = 0; | |
692 if ( SDL_TranslateUNICODE && xkey ) { | |
693 static XComposeStatus state; | |
694 /* Until we handle the IM protocol, use XLookupString() */ | |
695 unsigned char keybuf[32]; | |
696 | |
697 #define BROKEN_XFREE86_INTERNATIONAL_KBD | |
698 /* This appears to be a magical flag that is used with AltGr on | |
699 international keyboards to signal alternate key translations. | |
700 The flag doesn't show up when in fullscreen mode (?) | |
701 FIXME: Check to see if this code is safe for other servers. | |
702 */ | |
703 #ifdef BROKEN_XFREE86_INTERNATIONAL_KBD | |
704 /* Work around what appears to be a bug in XFree86 */ | |
705 if ( SDL_GetModState() & KMOD_MODE ) { | |
706 xkey->state |= (1<<13); | |
707 } | |
708 #endif | |
709 /* Look up the translated value for the key event */ | |
710 if ( XLookupString(xkey, (char *)keybuf, sizeof(keybuf), | |
711 NULL, &state) ) { | |
712 /* | |
713 * FIXME,: XLookupString() may yield more than one | |
714 * character, so we need a mechanism to allow for | |
715 * this (perhaps generate null keypress events with | |
716 * a unicode value) | |
717 */ | |
718 keysym->unicode = keybuf[0]; | |
719 } | |
720 } | |
721 return(keysym); | |
722 } | |
723 | |
724 /* X11 modifier masks for various keys */ | |
725 static unsigned meta_l_mask, meta_r_mask, alt_l_mask, alt_r_mask; | |
726 static unsigned num_mask, mode_switch_mask; | |
727 | |
728 static void get_modifier_masks(Display *display) | |
729 { | |
730 static unsigned got_masks; | |
731 int i, j; | |
732 XModifierKeymap *xmods; | |
733 unsigned n; | |
734 | |
735 if(got_masks) | |
736 return; | |
737 | |
738 xmods = XGetModifierMapping(display); | |
739 n = xmods->max_keypermod; | |
740 for(i = 3; i < 8; i++) { | |
741 for(j = 0; j < n; j++) { | |
742 KeyCode kc = xmods->modifiermap[i * n + j]; | |
743 KeySym ks = XKeycodeToKeysym(display, kc, 0); | |
744 unsigned mask = 1 << i; | |
745 switch(ks) { | |
746 case XK_Num_Lock: | |
747 num_mask = mask; break; | |
748 case XK_Alt_L: | |
749 alt_l_mask = mask; break; | |
750 case XK_Alt_R: | |
751 alt_r_mask = mask; break; | |
752 case XK_Meta_L: | |
753 meta_l_mask = mask; break; | |
754 case XK_Meta_R: | |
755 meta_r_mask = mask; break; | |
756 case XK_Mode_switch: | |
757 mode_switch_mask = mask; break; | |
758 } | |
759 } | |
760 } | |
761 XFreeModifiermap(xmods); | |
762 got_masks = 1; | |
763 } | |
764 | |
765 | |
766 /* | |
767 * This function is semi-official; it is not officially exported and should | |
768 * not be considered part of the SDL API, but may be used by client code | |
769 * that *really* needs it (including legacy code). | |
770 * It is slow, though, and should be avoided if possible. | |
771 * | |
772 * Note that it isn't completely accurate either; in particular, multi-key | |
773 * sequences (dead accents, compose key sequences) will not work since the | |
774 * state has been irrevocably lost. | |
775 */ | |
776 Uint16 X11_KeyToUnicode(SDLKey keysym, SDLMod modifiers) | |
777 { | |
778 struct SDL_VideoDevice *this = current_video; | |
779 char keybuf[32]; | |
780 int i; | |
781 KeySym xsym = 0; | |
782 XKeyEvent xkey; | |
783 Uint16 unicode; | |
784 | |
785 if ( !this || !SDL_Display ) { | |
786 return 0; | |
787 } | |
788 | |
789 memset(&xkey, 0, sizeof(xkey)); | |
790 xkey.display = SDL_Display; | |
791 | |
792 xsym = keysym; /* last resort if not found */ | |
793 for (i = 0; i < 256; ++i) { | |
794 if ( MISC_keymap[i] == keysym ) { | |
795 xsym = 0xFF00 | i; | |
796 break; | |
797 } else if ( ODD_keymap[i] == keysym ) { | |
798 xsym = 0xFE00 | i; | |
799 break; | |
800 } | |
801 } | |
802 | |
803 xkey.keycode = XKeysymToKeycode(xkey.display, xsym); | |
804 | |
805 get_modifier_masks(SDL_Display); | |
806 if(modifiers & KMOD_SHIFT) | |
807 xkey.state |= ShiftMask; | |
808 if(modifiers & KMOD_CAPS) | |
809 xkey.state |= LockMask; | |
810 if(modifiers & KMOD_CTRL) | |
811 xkey.state |= ControlMask; | |
812 if(modifiers & KMOD_MODE) | |
813 xkey.state |= mode_switch_mask; | |
814 if(modifiers & KMOD_LALT) | |
815 xkey.state |= alt_l_mask; | |
816 if(modifiers & KMOD_RALT) | |
817 xkey.state |= alt_r_mask; | |
818 if(modifiers & KMOD_LMETA) | |
819 xkey.state |= meta_l_mask; | |
820 if(modifiers & KMOD_RMETA) | |
821 xkey.state |= meta_r_mask; | |
822 if(modifiers & KMOD_NUM) | |
823 xkey.state |= num_mask; | |
824 | |
825 unicode = 0; | |
826 if ( XLookupString(&xkey, keybuf, sizeof(keybuf), NULL, NULL) ) | |
827 unicode = (unsigned char)keybuf[0]; | |
828 return(unicode); | |
829 } | |
830 | |
831 /* | |
832 * Called when focus is regained, to read the keyboard state and generate | |
833 * synthetic keypress/release events. | |
834 * key_vec is a bit vector of keycodes (256 bits) | |
835 */ | |
836 void X11_SetKeyboardState(Display *display, const char *key_vec) | |
837 { | |
838 char keys_return[32]; | |
412
ac59b067815b
Fix uninitialized variable warning
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
839 int i; |
0 | 840 KeyCode xcode[SDLK_LAST]; |
841 Uint8 new_kstate[SDLK_LAST]; | |
842 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
|
843 SDLMod modstate; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
844 Window junk_window; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
845 int x, y; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
846 unsigned int mask; |
0 | 847 |
848 /* The first time the window is mapped, we initialize key state */ | |
849 if ( ! key_vec ) { | |
412
ac59b067815b
Fix uninitialized variable warning
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
850 XQueryKeymap(display, keys_return); |
0 | 851 key_vec = keys_return; |
852 } | |
853 | |
111
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
854 /* 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
|
855 modstate = 0; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
856 get_modifier_masks(display); |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
857 if ( XQueryPointer(display, DefaultRootWindow(display), |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
858 &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
|
859 if ( mask & LockMask ) { |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
860 modstate |= KMOD_CAPS; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
861 } |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
862 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
|
863 modstate |= KMOD_MODE; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
864 } |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
865 if ( mask & num_mask ) { |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
866 modstate |= KMOD_NUM; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
867 } |
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 |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
870 /* 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
|
871 memset(new_kstate, SDL_RELEASED, sizeof(new_kstate)); |
0 | 872 /* |
873 * An obvious optimisation is to check entire longwords at a time in | |
874 * both loops, but we can't be sure the arrays are aligned so it's not | |
875 * worth the extra complexity | |
876 */ | |
877 for(i = 0; i < 32; i++) { | |
878 int j; | |
879 if(!key_vec[i]) | |
880 continue; | |
881 for(j = 0; j < 8; j++) { | |
882 if(key_vec[i] & (1 << j)) { | |
883 SDL_keysym sk; | |
884 KeyCode kc = i << 3 | j; | |
885 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
|
886 new_kstate[sk.sym] = SDL_PRESSED; |
0 | 887 xcode[sk.sym] = kc; |
888 } | |
889 } | |
890 } | |
891 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
|
892 int state = new_kstate[i]; |
0 | 893 |
111
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
894 if ( state == SDL_PRESSED ) { |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
895 switch (i) { |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
896 case SDLK_LSHIFT: |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
897 modstate |= KMOD_LSHIFT; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
898 break; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
899 case SDLK_RSHIFT: |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
900 modstate |= KMOD_RSHIFT; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
901 break; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
902 case SDLK_LCTRL: |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
903 modstate |= KMOD_LCTRL; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
904 break; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
905 case SDLK_RCTRL: |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
906 modstate |= KMOD_RCTRL; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
907 break; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
908 case SDLK_LALT: |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
909 modstate |= KMOD_LALT; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
910 break; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
911 case SDLK_RALT: |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
912 modstate |= KMOD_RALT; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
913 break; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
914 case SDLK_LMETA: |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
915 modstate |= KMOD_LMETA; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
916 break; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
917 case SDLK_RMETA: |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
918 modstate |= KMOD_RMETA; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
919 break; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
920 default: |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
921 break; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
922 } |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
923 } |
412
ac59b067815b
Fix uninitialized variable warning
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
924 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
|
925 kstate[i] = state; |
0 | 926 } |
927 } | |
111
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
928 |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
929 /* 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
|
930 if ( modstate & KMOD_CAPS ) { |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
931 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
|
932 } else { |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
933 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
|
934 } |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
935 if ( modstate & KMOD_NUM ) { |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
936 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
|
937 } else { |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
938 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
|
939 } |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
940 |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
941 /* 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
|
942 SDL_SetModState(modstate); |
0 | 943 } |
944 | |
945 void X11_InitOSKeymap(_THIS) | |
946 { | |
947 X11_InitKeymap(); | |
948 } | |
949 |