Mercurial > sdl-ios-xcode
annotate src/video/x11/SDL_x11events.c @ 934:af585d6efec8
Date: Thu, 17 Jun 2004 11:38:51 -0700 (PDT)
From: Eric Wing <ewing2121@yahoo.com>
Subject: New OS X patch (was Re: [SDL] Bug with inverted mouse coordinates in
I have a new patch for OS X I would like to submit.
First, it appears no further action has been taken on
my fix from Apple on the OpenGL windowed mode mouse
inversion problem. The fix would reunify the code, and
no longer require case checking for which version of
the OS you are running. This is probably a good fix
because the behavior with the old code could change
again with future versions of the OS, so those fixes
are included in this new patch.
But in addition, when I was at Apple, I asked them
about the ability to distinguish between the modifier
keys on the left and right sides of the keyboard (e.g.
Left Shift, Right Shift, Left/Right Alt, L/R Cmd, L/R
Ctrl). They told me that starting with Panther, the OS
began supporting this feature. This has always been a
source of annoyance for me when bringing a program
that comes from Windows or Linux to OS X when the
keybindings happened to need distinguishable left-side
and right-side keys. So the rest of the patch I am
submitting contains new code to support this feature
on Panther (and presumably later versions of the OS).
So after removing the OS version checks for the mouse
inversion problem, I reused the OS version checks to
activate the Left/Right detection of modifier keys. If
you are running Panther (or above), the new code will
attempt to distinguish between sides. For the older
OS's, the code path reverts to the original code.
I've tested with Panther on a G4 Cube, G5 dual
processor, and Powerbook Rev C. The Cube and G5
keyboards demonstrated the ability to distinguish
between sides. The Powerbook seems to only have
left-side keys, but the patch was still able to handle
it by producing the same results as before the patch.
I also wanted to test a non-Apple keyboard.
Unfortunately, I don't have any PC USB keyboards.
However, I was able to borrow a Sun Microsystems USB
keyboard, so I tried that out on the G5, and I got the
correct behavior for left and right sides. I'm
expecting that if it worked with a Sun keyboard, most
other keyboards should work with no problems.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Fri, 20 Aug 2004 22:35:23 +0000 |
parents | df1a3218b468 |
children | 787b8d2c23e4 |
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; | |
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 | |
805
df1a3218b468
Date: Wed, 04 Feb 2004 13:51:56 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
518 #ifdef XK_ISO_Level3_Shift |
df1a3218b468
Date: Wed, 04 Feb 2004 13:51:56 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
519 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
|
520 #endif |
0 | 521 |
522 /* Map the miscellaneous keys */ | |
523 for ( i=0; i<SDL_TABLESIZE(MISC_keymap); ++i ) | |
524 MISC_keymap[i] = SDLK_UNKNOWN; | |
525 | |
526 /* These X keysyms have 0xFF as the high byte */ | |
527 MISC_keymap[XK_BackSpace&0xFF] = SDLK_BACKSPACE; | |
528 MISC_keymap[XK_Tab&0xFF] = SDLK_TAB; | |
529 MISC_keymap[XK_Clear&0xFF] = SDLK_CLEAR; | |
530 MISC_keymap[XK_Return&0xFF] = SDLK_RETURN; | |
531 MISC_keymap[XK_Pause&0xFF] = SDLK_PAUSE; | |
532 MISC_keymap[XK_Escape&0xFF] = SDLK_ESCAPE; | |
533 MISC_keymap[XK_Delete&0xFF] = SDLK_DELETE; | |
534 | |
535 MISC_keymap[XK_KP_0&0xFF] = SDLK_KP0; /* Keypad 0-9 */ | |
536 MISC_keymap[XK_KP_1&0xFF] = SDLK_KP1; | |
537 MISC_keymap[XK_KP_2&0xFF] = SDLK_KP2; | |
538 MISC_keymap[XK_KP_3&0xFF] = SDLK_KP3; | |
539 MISC_keymap[XK_KP_4&0xFF] = SDLK_KP4; | |
540 MISC_keymap[XK_KP_5&0xFF] = SDLK_KP5; | |
541 MISC_keymap[XK_KP_6&0xFF] = SDLK_KP6; | |
542 MISC_keymap[XK_KP_7&0xFF] = SDLK_KP7; | |
543 MISC_keymap[XK_KP_8&0xFF] = SDLK_KP8; | |
544 MISC_keymap[XK_KP_9&0xFF] = SDLK_KP9; | |
545 MISC_keymap[XK_KP_Insert&0xFF] = SDLK_KP0; | |
546 MISC_keymap[XK_KP_End&0xFF] = SDLK_KP1; | |
547 MISC_keymap[XK_KP_Down&0xFF] = SDLK_KP2; | |
548 MISC_keymap[XK_KP_Page_Down&0xFF] = SDLK_KP3; | |
549 MISC_keymap[XK_KP_Left&0xFF] = SDLK_KP4; | |
550 MISC_keymap[XK_KP_Begin&0xFF] = SDLK_KP5; | |
551 MISC_keymap[XK_KP_Right&0xFF] = SDLK_KP6; | |
552 MISC_keymap[XK_KP_Home&0xFF] = SDLK_KP7; | |
553 MISC_keymap[XK_KP_Up&0xFF] = SDLK_KP8; | |
554 MISC_keymap[XK_KP_Page_Up&0xFF] = SDLK_KP9; | |
555 MISC_keymap[XK_KP_Delete&0xFF] = SDLK_KP_PERIOD; | |
556 MISC_keymap[XK_KP_Decimal&0xFF] = SDLK_KP_PERIOD; | |
557 MISC_keymap[XK_KP_Divide&0xFF] = SDLK_KP_DIVIDE; | |
558 MISC_keymap[XK_KP_Multiply&0xFF] = SDLK_KP_MULTIPLY; | |
559 MISC_keymap[XK_KP_Subtract&0xFF] = SDLK_KP_MINUS; | |
560 MISC_keymap[XK_KP_Add&0xFF] = SDLK_KP_PLUS; | |
561 MISC_keymap[XK_KP_Enter&0xFF] = SDLK_KP_ENTER; | |
562 MISC_keymap[XK_KP_Equal&0xFF] = SDLK_KP_EQUALS; | |
563 | |
564 MISC_keymap[XK_Up&0xFF] = SDLK_UP; | |
565 MISC_keymap[XK_Down&0xFF] = SDLK_DOWN; | |
566 MISC_keymap[XK_Right&0xFF] = SDLK_RIGHT; | |
567 MISC_keymap[XK_Left&0xFF] = SDLK_LEFT; | |
568 MISC_keymap[XK_Insert&0xFF] = SDLK_INSERT; | |
569 MISC_keymap[XK_Home&0xFF] = SDLK_HOME; | |
570 MISC_keymap[XK_End&0xFF] = SDLK_END; | |
571 MISC_keymap[XK_Page_Up&0xFF] = SDLK_PAGEUP; | |
572 MISC_keymap[XK_Page_Down&0xFF] = SDLK_PAGEDOWN; | |
573 | |
574 MISC_keymap[XK_F1&0xFF] = SDLK_F1; | |
575 MISC_keymap[XK_F2&0xFF] = SDLK_F2; | |
576 MISC_keymap[XK_F3&0xFF] = SDLK_F3; | |
577 MISC_keymap[XK_F4&0xFF] = SDLK_F4; | |
578 MISC_keymap[XK_F5&0xFF] = SDLK_F5; | |
579 MISC_keymap[XK_F6&0xFF] = SDLK_F6; | |
580 MISC_keymap[XK_F7&0xFF] = SDLK_F7; | |
581 MISC_keymap[XK_F8&0xFF] = SDLK_F8; | |
582 MISC_keymap[XK_F9&0xFF] = SDLK_F9; | |
583 MISC_keymap[XK_F10&0xFF] = SDLK_F10; | |
584 MISC_keymap[XK_F11&0xFF] = SDLK_F11; | |
585 MISC_keymap[XK_F12&0xFF] = SDLK_F12; | |
586 MISC_keymap[XK_F13&0xFF] = SDLK_F13; | |
587 MISC_keymap[XK_F14&0xFF] = SDLK_F14; | |
588 MISC_keymap[XK_F15&0xFF] = SDLK_F15; | |
589 | |
590 MISC_keymap[XK_Num_Lock&0xFF] = SDLK_NUMLOCK; | |
591 MISC_keymap[XK_Caps_Lock&0xFF] = SDLK_CAPSLOCK; | |
592 MISC_keymap[XK_Scroll_Lock&0xFF] = SDLK_SCROLLOCK; | |
593 MISC_keymap[XK_Shift_R&0xFF] = SDLK_RSHIFT; | |
594 MISC_keymap[XK_Shift_L&0xFF] = SDLK_LSHIFT; | |
595 MISC_keymap[XK_Control_R&0xFF] = SDLK_RCTRL; | |
596 MISC_keymap[XK_Control_L&0xFF] = SDLK_LCTRL; | |
597 MISC_keymap[XK_Alt_R&0xFF] = SDLK_RALT; | |
598 MISC_keymap[XK_Alt_L&0xFF] = SDLK_LALT; | |
599 MISC_keymap[XK_Meta_R&0xFF] = SDLK_RMETA; | |
600 MISC_keymap[XK_Meta_L&0xFF] = SDLK_LMETA; | |
601 MISC_keymap[XK_Super_L&0xFF] = SDLK_LSUPER; /* Left "Windows" */ | |
602 MISC_keymap[XK_Super_R&0xFF] = SDLK_RSUPER; /* Right "Windows */ | |
603 MISC_keymap[XK_Mode_switch&0xFF] = SDLK_MODE; /* "Alt Gr" key */ | |
604 MISC_keymap[XK_Multi_key&0xFF] = SDLK_COMPOSE; /* Multi-key compose */ | |
605 | |
606 MISC_keymap[XK_Help&0xFF] = SDLK_HELP; | |
607 MISC_keymap[XK_Print&0xFF] = SDLK_PRINT; | |
608 MISC_keymap[XK_Sys_Req&0xFF] = SDLK_SYSREQ; | |
609 MISC_keymap[XK_Break&0xFF] = SDLK_BREAK; | |
610 MISC_keymap[XK_Menu&0xFF] = SDLK_MENU; | |
611 MISC_keymap[XK_Hyper_R&0xFF] = SDLK_MENU; /* Windows "Menu" key */ | |
612 } | |
613 | |
614 SDL_keysym *X11_TranslateKey(Display *display, XKeyEvent *xkey, KeyCode kc, | |
615 SDL_keysym *keysym) | |
616 { | |
617 KeySym xsym; | |
618 | |
619 /* Get the raw keyboard scancode */ | |
620 keysym->scancode = kc; | |
621 xsym = XKeycodeToKeysym(display, kc, 0); | |
622 #ifdef DEBUG_KEYS | |
623 fprintf(stderr, "Translating key 0x%.4x (%d)\n", xsym, kc); | |
624 #endif | |
625 /* Get the translated SDL virtual keysym */ | |
626 keysym->sym = SDLK_UNKNOWN; | |
627 if ( xsym ) { | |
628 switch (xsym>>8) { | |
629 case 0x1005FF: | |
630 #ifdef SunXK_F36 | |
631 if ( xsym == SunXK_F36 ) | |
632 keysym->sym = SDLK_F11; | |
633 #endif | |
634 #ifdef SunXK_F37 | |
635 if ( xsym == SunXK_F37 ) | |
636 keysym->sym = SDLK_F12; | |
637 #endif | |
638 break; | |
639 case 0x00: /* Latin 1 */ | |
640 case 0x01: /* Latin 2 */ | |
641 case 0x02: /* Latin 3 */ | |
642 case 0x03: /* Latin 4 */ | |
643 case 0x04: /* Katakana */ | |
644 case 0x05: /* Arabic */ | |
645 case 0x06: /* Cyrillic */ | |
646 case 0x07: /* Greek */ | |
647 case 0x08: /* Technical */ | |
648 case 0x0A: /* Publishing */ | |
649 case 0x0C: /* Hebrew */ | |
650 case 0x0D: /* Thai */ | |
651 keysym->sym = (SDLKey)(xsym&0xFF); | |
652 /* Map capital letter syms to lowercase */ | |
653 if ((keysym->sym >= 'A')&&(keysym->sym <= 'Z')) | |
654 keysym->sym += ('a'-'A'); | |
655 break; | |
656 case 0xFE: | |
657 keysym->sym = ODD_keymap[xsym&0xFF]; | |
658 break; | |
659 case 0xFF: | |
660 keysym->sym = MISC_keymap[xsym&0xFF]; | |
661 break; | |
662 default: | |
663 fprintf(stderr, | |
664 "X11: Unknown xsym, sym = 0x%04x\n", | |
665 (unsigned int)xsym); | |
666 break; | |
667 } | |
668 } else { | |
669 /* X11 doesn't know how to translate the key! */ | |
670 switch (kc) { | |
671 /* Caution: | |
672 These keycodes are from the Microsoft Keyboard | |
673 */ | |
674 case 115: | |
675 keysym->sym = SDLK_LSUPER; | |
676 break; | |
677 case 116: | |
678 keysym->sym = SDLK_RSUPER; | |
679 break; | |
680 case 117: | |
681 keysym->sym = SDLK_MENU; | |
682 break; | |
683 default: | |
684 /* | |
685 * no point in an error message; happens for | |
686 * several keys when we get a keymap notify | |
687 */ | |
688 break; | |
689 } | |
690 } | |
691 keysym->mod = KMOD_NONE; | |
692 | |
693 /* If UNICODE is on, get the UNICODE value for the key */ | |
694 keysym->unicode = 0; | |
695 if ( SDL_TranslateUNICODE && xkey ) { | |
696 static XComposeStatus state; | |
697 /* Until we handle the IM protocol, use XLookupString() */ | |
698 unsigned char keybuf[32]; | |
699 | |
700 #define BROKEN_XFREE86_INTERNATIONAL_KBD | |
701 /* This appears to be a magical flag that is used with AltGr on | |
702 international keyboards to signal alternate key translations. | |
703 The flag doesn't show up when in fullscreen mode (?) | |
704 FIXME: Check to see if this code is safe for other servers. | |
705 */ | |
706 #ifdef BROKEN_XFREE86_INTERNATIONAL_KBD | |
707 /* Work around what appears to be a bug in XFree86 */ | |
708 if ( SDL_GetModState() & KMOD_MODE ) { | |
709 xkey->state |= (1<<13); | |
710 } | |
711 #endif | |
712 /* Look up the translated value for the key event */ | |
713 if ( XLookupString(xkey, (char *)keybuf, sizeof(keybuf), | |
714 NULL, &state) ) { | |
715 /* | |
716 * FIXME,: XLookupString() may yield more than one | |
717 * character, so we need a mechanism to allow for | |
718 * this (perhaps generate null keypress events with | |
719 * a unicode value) | |
720 */ | |
721 keysym->unicode = keybuf[0]; | |
722 } | |
723 } | |
724 return(keysym); | |
725 } | |
726 | |
727 /* X11 modifier masks for various keys */ | |
728 static unsigned meta_l_mask, meta_r_mask, alt_l_mask, alt_r_mask; | |
729 static unsigned num_mask, mode_switch_mask; | |
730 | |
731 static void get_modifier_masks(Display *display) | |
732 { | |
733 static unsigned got_masks; | |
734 int i, j; | |
735 XModifierKeymap *xmods; | |
736 unsigned n; | |
737 | |
738 if(got_masks) | |
739 return; | |
740 | |
741 xmods = XGetModifierMapping(display); | |
742 n = xmods->max_keypermod; | |
743 for(i = 3; i < 8; i++) { | |
744 for(j = 0; j < n; j++) { | |
745 KeyCode kc = xmods->modifiermap[i * n + j]; | |
746 KeySym ks = XKeycodeToKeysym(display, kc, 0); | |
747 unsigned mask = 1 << i; | |
748 switch(ks) { | |
749 case XK_Num_Lock: | |
750 num_mask = mask; break; | |
751 case XK_Alt_L: | |
752 alt_l_mask = mask; break; | |
753 case XK_Alt_R: | |
754 alt_r_mask = mask; break; | |
755 case XK_Meta_L: | |
756 meta_l_mask = mask; break; | |
757 case XK_Meta_R: | |
758 meta_r_mask = mask; break; | |
759 case XK_Mode_switch: | |
760 mode_switch_mask = mask; break; | |
761 } | |
762 } | |
763 } | |
764 XFreeModifiermap(xmods); | |
765 got_masks = 1; | |
766 } | |
767 | |
768 | |
769 /* | |
770 * This function is semi-official; it is not officially exported and should | |
771 * not be considered part of the SDL API, but may be used by client code | |
772 * that *really* needs it (including legacy code). | |
773 * It is slow, though, and should be avoided if possible. | |
774 * | |
775 * Note that it isn't completely accurate either; in particular, multi-key | |
776 * sequences (dead accents, compose key sequences) will not work since the | |
777 * state has been irrevocably lost. | |
778 */ | |
779 Uint16 X11_KeyToUnicode(SDLKey keysym, SDLMod modifiers) | |
780 { | |
781 struct SDL_VideoDevice *this = current_video; | |
782 char keybuf[32]; | |
783 int i; | |
784 KeySym xsym = 0; | |
785 XKeyEvent xkey; | |
786 Uint16 unicode; | |
787 | |
788 if ( !this || !SDL_Display ) { | |
789 return 0; | |
790 } | |
791 | |
792 memset(&xkey, 0, sizeof(xkey)); | |
793 xkey.display = SDL_Display; | |
794 | |
795 xsym = keysym; /* last resort if not found */ | |
796 for (i = 0; i < 256; ++i) { | |
797 if ( MISC_keymap[i] == keysym ) { | |
798 xsym = 0xFF00 | i; | |
799 break; | |
800 } else if ( ODD_keymap[i] == keysym ) { | |
801 xsym = 0xFE00 | i; | |
802 break; | |
803 } | |
804 } | |
805 | |
806 xkey.keycode = XKeysymToKeycode(xkey.display, xsym); | |
807 | |
808 get_modifier_masks(SDL_Display); | |
809 if(modifiers & KMOD_SHIFT) | |
810 xkey.state |= ShiftMask; | |
811 if(modifiers & KMOD_CAPS) | |
812 xkey.state |= LockMask; | |
813 if(modifiers & KMOD_CTRL) | |
814 xkey.state |= ControlMask; | |
815 if(modifiers & KMOD_MODE) | |
816 xkey.state |= mode_switch_mask; | |
817 if(modifiers & KMOD_LALT) | |
818 xkey.state |= alt_l_mask; | |
819 if(modifiers & KMOD_RALT) | |
820 xkey.state |= alt_r_mask; | |
821 if(modifiers & KMOD_LMETA) | |
822 xkey.state |= meta_l_mask; | |
823 if(modifiers & KMOD_RMETA) | |
824 xkey.state |= meta_r_mask; | |
825 if(modifiers & KMOD_NUM) | |
826 xkey.state |= num_mask; | |
827 | |
828 unicode = 0; | |
829 if ( XLookupString(&xkey, keybuf, sizeof(keybuf), NULL, NULL) ) | |
830 unicode = (unsigned char)keybuf[0]; | |
831 return(unicode); | |
832 } | |
833 | |
834 /* | |
835 * Called when focus is regained, to read the keyboard state and generate | |
836 * synthetic keypress/release events. | |
837 * key_vec is a bit vector of keycodes (256 bits) | |
838 */ | |
839 void X11_SetKeyboardState(Display *display, const char *key_vec) | |
840 { | |
841 char keys_return[32]; | |
412
ac59b067815b
Fix uninitialized variable warning
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
842 int i; |
0 | 843 KeyCode xcode[SDLK_LAST]; |
844 Uint8 new_kstate[SDLK_LAST]; | |
845 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
|
846 SDLMod modstate; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
847 Window junk_window; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
848 int x, y; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
849 unsigned int mask; |
0 | 850 |
851 /* The first time the window is mapped, we initialize key state */ | |
852 if ( ! key_vec ) { | |
412
ac59b067815b
Fix uninitialized variable warning
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
853 XQueryKeymap(display, keys_return); |
0 | 854 key_vec = keys_return; |
855 } | |
856 | |
111
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
857 /* 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
|
858 modstate = 0; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
859 get_modifier_masks(display); |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
860 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
|
861 &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
|
862 if ( mask & LockMask ) { |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
863 modstate |= KMOD_CAPS; |
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 & mode_switch_mask ) { |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
866 modstate |= KMOD_MODE; |
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 if ( mask & num_mask ) { |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
869 modstate |= KMOD_NUM; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
870 } |
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 /* 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
|
874 memset(new_kstate, SDL_RELEASED, sizeof(new_kstate)); |
0 | 875 /* |
876 * An obvious optimisation is to check entire longwords at a time in | |
877 * both loops, but we can't be sure the arrays are aligned so it's not | |
878 * worth the extra complexity | |
879 */ | |
880 for(i = 0; i < 32; i++) { | |
881 int j; | |
882 if(!key_vec[i]) | |
883 continue; | |
884 for(j = 0; j < 8; j++) { | |
885 if(key_vec[i] & (1 << j)) { | |
886 SDL_keysym sk; | |
887 KeyCode kc = i << 3 | j; | |
888 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
|
889 new_kstate[sk.sym] = SDL_PRESSED; |
0 | 890 xcode[sk.sym] = kc; |
891 } | |
892 } | |
893 } | |
894 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
|
895 int state = new_kstate[i]; |
0 | 896 |
111
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
897 if ( state == SDL_PRESSED ) { |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
898 switch (i) { |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
899 case SDLK_LSHIFT: |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
900 modstate |= KMOD_LSHIFT; |
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_RSHIFT: |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
903 modstate |= KMOD_RSHIFT; |
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_LCTRL: |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
906 modstate |= KMOD_LCTRL; |
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_RCTRL: |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
909 modstate |= KMOD_RCTRL; |
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_LALT: |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
912 modstate |= KMOD_LALT; |
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_RALT: |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
915 modstate |= KMOD_RALT; |
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_LMETA: |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
918 modstate |= KMOD_LMETA; |
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 case SDLK_RMETA: |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
921 modstate |= KMOD_RMETA; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
922 break; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
923 default: |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
924 break; |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
925 } |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
926 } |
412
ac59b067815b
Fix uninitialized variable warning
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
927 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
|
928 kstate[i] = state; |
0 | 929 } |
930 } | |
111
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
931 |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
932 /* 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
|
933 if ( modstate & KMOD_CAPS ) { |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
934 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
|
935 } else { |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
936 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
|
937 } |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
938 if ( modstate & KMOD_NUM ) { |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
939 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
|
940 } else { |
53e3d8ba4321
Now gets correct keyboard state when starting up on X11
Sam Lantinga <slouken@lokigames.com>
parents:
88
diff
changeset
|
941 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
|
942 } |
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 /* 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
|
945 SDL_SetModState(modstate); |
0 | 946 } |
947 | |
948 void X11_InitOSKeymap(_THIS) | |
949 { | |
950 X11_InitKeymap(); | |
951 } | |
952 |