Mercurial > sdl-ios-xcode
annotate src/video/fbcon/SDL_fbevents.c @ 1348:40d0975c1769
Date: Mon, 6 Feb 2006 11:41:04 -0500
From: "mystml@adinet.com.uy"
Subject: [SDL] ALT-F4 using DirectX
My game isn't getting SDL_QUIT when I press ALT-F4 using the DirectX
driver; it does get SDL_QUIT when I press the red X in the window.
I tracked this down to DX5_HandleMessage() in SDL_dx5events.c;
WM_SYSKEYDOWN is being trapped and ignored which causes Windows not to post
a WM_CLOSE, hence no SDL_QUIT is being generated.
The relevant code is this :
/* The keyboard is handled via DirectInput */
case WM_SYSKEYUP:
case WM_SYSKEYDOWN:
case WM_KEYUP:
case WM_KEYDOWN: {
/* Ignore windows keyboard messages */;
}
return(0);
If I comment the WM_SYSKEYDOWN case, it falls through DefWindowProc() and
ALT-F4 starts working again.
I'm not sure about the best way to fix this. One option is handling ALT-F4
as a particular case somehow, but doesn't sound good. Another option would
be to handle WM_SYSKEYDOWN separately and breaking instead of returning 0,
so processing falls through and goes to DefWindowProc which does The Right
Thing (TM). This seems to be the minimal change that makes ALT-F4 work and
normal keyboard input continues to work.
Does this sound reasonable? Am I overlooking anything? Do I submit a patch?
--Gabriel
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Wed, 08 Feb 2006 17:19:43 +0000 |
parents | d02b552e5304 |
children | c71e05b4dc2e |
rev | line source |
---|---|
0 | 1 /* |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1241
diff
changeset
|
2 SDL - Simple DirectMedia Layer |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1241
diff
changeset
|
3 Copyright (C) 1997-2006 Sam Lantinga |
0 | 4 |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1241
diff
changeset
|
5 This library is free software; you can redistribute it and/or |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1241
diff
changeset
|
6 modify it under the terms of the GNU Lesser General Public |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1241
diff
changeset
|
7 License as published by the Free Software Foundation; either |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1241
diff
changeset
|
8 version 2.1 of the License, or (at your option) any later version. |
0 | 9 |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1241
diff
changeset
|
10 This library is distributed in the hope that it will be useful, |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1241
diff
changeset
|
11 but WITHOUT ANY WARRANTY; without even the implied warranty of |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1241
diff
changeset
|
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1241
diff
changeset
|
13 Lesser General Public License for more details. |
0 | 14 |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1241
diff
changeset
|
15 You should have received a copy of the GNU Lesser General Public |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1241
diff
changeset
|
16 License along with this library; if not, write to the Free Software |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1241
diff
changeset
|
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
0 | 18 |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1241
diff
changeset
|
19 Sam Lantinga |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1241
diff
changeset
|
20 slouken@libsdl.org |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1241
diff
changeset
|
21 */ |
0 | 22 |
23 /* Handle the event stream, converting console events into SDL events */ | |
24 | |
1338
604d73db6802
Removed uses of stdlib.h and string.h
Sam Lantinga <slouken@libsdl.org>
parents:
1336
diff
changeset
|
25 #include <stdio.h> |
0 | 26 #include <sys/types.h> |
27 #include <sys/time.h> | |
28 #include <sys/ioctl.h> | |
29 #include <unistd.h> | |
30 #include <fcntl.h> | |
31 #include <errno.h> | |
32 #include <limits.h> | |
33 | |
34 /* For parsing /proc */ | |
35 #include <dirent.h> | |
36 #include <ctype.h> | |
37 | |
38 #include <linux/vt.h> | |
39 #include <linux/kd.h> | |
40 #include <linux/keyboard.h> | |
41 | |
42 #include "SDL.h" | |
1338
604d73db6802
Removed uses of stdlib.h and string.h
Sam Lantinga <slouken@libsdl.org>
parents:
1336
diff
changeset
|
43 #include "SDL_stdlib.h" |
604d73db6802
Removed uses of stdlib.h and string.h
Sam Lantinga <slouken@libsdl.org>
parents:
1336
diff
changeset
|
44 #include "SDL_string.h" |
0 | 45 #include "SDL_mutex.h" |
46 #include "SDL_sysevents.h" | |
47 #include "SDL_sysvideo.h" | |
48 #include "SDL_events_c.h" | |
49 #include "SDL_fbvideo.h" | |
50 #include "SDL_fbevents_c.h" | |
51 #include "SDL_fbkeys.h" | |
52 | |
53 #include "SDL_fbelo.h" | |
54 | |
55 #ifndef GPM_NODE_FIFO | |
56 #define GPM_NODE_FIFO "/dev/gpmdata" | |
57 #endif | |
58 | |
59 | |
60 /* The translation tables from a console scancode to a SDL keysym */ | |
61 #define NUM_VGAKEYMAPS (1<<KG_CAPSSHIFT) | |
62 static Uint16 vga_keymap[NUM_VGAKEYMAPS][NR_KEYS]; | |
63 static SDLKey keymap[128]; | |
64 static Uint16 keymap_temp[128]; /* only used at startup */ | |
65 static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym); | |
66 | |
67 /* Ugh, we have to duplicate the kernel's keysym mapping code... | |
68 Oh, it's not so bad. :-) | |
69 | |
70 FIXME: Add keyboard LED handling code | |
71 */ | |
72 static void FB_vgainitkeymaps(int fd) | |
73 { | |
74 struct kbentry entry; | |
75 int map, i; | |
76 | |
77 /* Don't do anything if we are passed a closed keyboard */ | |
78 if ( fd < 0 ) { | |
79 return; | |
80 } | |
81 | |
82 /* Load all the keysym mappings */ | |
83 for ( map=0; map<NUM_VGAKEYMAPS; ++map ) { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1323
diff
changeset
|
84 SDL_memset(vga_keymap[map], 0, NR_KEYS*sizeof(Uint16)); |
0 | 85 for ( i=0; i<NR_KEYS; ++i ) { |
86 entry.kb_table = map; | |
87 entry.kb_index = i; | |
88 if ( ioctl(fd, KDGKBENT, &entry) == 0 ) { | |
89 /* fill keytemp. This replaces SDL_fbkeys.h */ | |
90 if ( (map == 0) && (i<128) ) { | |
91 keymap_temp[i] = entry.kb_value; | |
92 } | |
93 /* The "Enter" key is a special case */ | |
94 if ( entry.kb_value == K_ENTER ) { | |
95 entry.kb_value = K(KT_ASCII,13); | |
96 } | |
97 /* Handle numpad specially as well */ | |
98 if ( KTYP(entry.kb_value) == KT_PAD ) { | |
99 switch ( entry.kb_value ) { | |
100 case K_P0: | |
101 case K_P1: | |
102 case K_P2: | |
103 case K_P3: | |
104 case K_P4: | |
105 case K_P5: | |
106 case K_P6: | |
107 case K_P7: | |
108 case K_P8: | |
109 case K_P9: | |
110 vga_keymap[map][i]=entry.kb_value; | |
111 vga_keymap[map][i]+= '0'; | |
112 break; | |
113 case K_PPLUS: | |
114 vga_keymap[map][i]=K(KT_ASCII,'+'); | |
115 break; | |
116 case K_PMINUS: | |
117 vga_keymap[map][i]=K(KT_ASCII,'-'); | |
118 break; | |
119 case K_PSTAR: | |
120 vga_keymap[map][i]=K(KT_ASCII,'*'); | |
121 break; | |
122 case K_PSLASH: | |
123 vga_keymap[map][i]=K(KT_ASCII,'/'); | |
124 break; | |
125 case K_PENTER: | |
126 vga_keymap[map][i]=K(KT_ASCII,'\r'); | |
127 break; | |
128 case K_PCOMMA: | |
129 vga_keymap[map][i]=K(KT_ASCII,','); | |
130 break; | |
131 case K_PDOT: | |
132 vga_keymap[map][i]=K(KT_ASCII,'.'); | |
133 break; | |
134 default: | |
135 break; | |
136 } | |
137 } | |
138 /* Do the normal key translation */ | |
139 if ( (KTYP(entry.kb_value) == KT_LATIN) || | |
140 (KTYP(entry.kb_value) == KT_ASCII) || | |
141 (KTYP(entry.kb_value) == KT_LETTER) ) { | |
142 vga_keymap[map][i] = entry.kb_value; | |
143 } | |
144 } | |
145 } | |
146 } | |
147 } | |
148 | |
149 int FB_InGraphicsMode(_THIS) | |
150 { | |
151 return((keyboard_fd >= 0) && (saved_kbd_mode >= 0)); | |
152 } | |
153 | |
154 int FB_EnterGraphicsMode(_THIS) | |
155 { | |
156 struct termios keyboard_termios; | |
157 | |
158 /* Set medium-raw keyboard mode */ | |
159 if ( (keyboard_fd >= 0) && !FB_InGraphicsMode(this) ) { | |
160 | |
161 /* Switch to the correct virtual terminal */ | |
162 if ( current_vt > 0 ) { | |
163 struct vt_stat vtstate; | |
164 | |
165 if ( ioctl(keyboard_fd, VT_GETSTATE, &vtstate) == 0 ) { | |
166 saved_vt = vtstate.v_active; | |
167 } | |
168 if ( ioctl(keyboard_fd, VT_ACTIVATE, current_vt) == 0 ) { | |
169 ioctl(keyboard_fd, VT_WAITACTIVE, current_vt); | |
170 } | |
171 } | |
172 | |
173 /* Set the terminal input mode */ | |
174 if ( tcgetattr(keyboard_fd, &saved_kbd_termios) < 0 ) { | |
175 SDL_SetError("Unable to get terminal attributes"); | |
176 if ( keyboard_fd > 0 ) { | |
177 close(keyboard_fd); | |
178 } | |
179 keyboard_fd = -1; | |
180 return(-1); | |
181 } | |
182 if ( ioctl(keyboard_fd, KDGKBMODE, &saved_kbd_mode) < 0 ) { | |
183 SDL_SetError("Unable to get current keyboard mode"); | |
184 if ( keyboard_fd > 0 ) { | |
185 close(keyboard_fd); | |
186 } | |
187 keyboard_fd = -1; | |
188 return(-1); | |
189 } | |
190 keyboard_termios = saved_kbd_termios; | |
191 keyboard_termios.c_lflag &= ~(ICANON | ECHO | ISIG); | |
192 keyboard_termios.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON); | |
193 keyboard_termios.c_cc[VMIN] = 0; | |
194 keyboard_termios.c_cc[VTIME] = 0; | |
195 if (tcsetattr(keyboard_fd, TCSAFLUSH, &keyboard_termios) < 0) { | |
196 FB_CloseKeyboard(this); | |
197 SDL_SetError("Unable to set terminal attributes"); | |
198 return(-1); | |
199 } | |
200 /* This will fail if we aren't root or this isn't our tty */ | |
201 if ( ioctl(keyboard_fd, KDSKBMODE, K_MEDIUMRAW) < 0 ) { | |
202 FB_CloseKeyboard(this); | |
203 SDL_SetError("Unable to set keyboard in raw mode"); | |
204 return(-1); | |
205 } | |
206 if ( ioctl(keyboard_fd, KDSETMODE, KD_GRAPHICS) < 0 ) { | |
207 FB_CloseKeyboard(this); | |
208 SDL_SetError("Unable to set keyboard in graphics mode"); | |
209 return(-1); | |
210 } | |
211 } | |
212 return(keyboard_fd); | |
213 } | |
214 | |
215 void FB_LeaveGraphicsMode(_THIS) | |
216 { | |
217 if ( FB_InGraphicsMode(this) ) { | |
218 ioctl(keyboard_fd, KDSETMODE, KD_TEXT); | |
219 ioctl(keyboard_fd, KDSKBMODE, saved_kbd_mode); | |
220 tcsetattr(keyboard_fd, TCSAFLUSH, &saved_kbd_termios); | |
221 saved_kbd_mode = -1; | |
222 | |
223 /* Head back over to the original virtual terminal */ | |
224 if ( saved_vt > 0 ) { | |
225 ioctl(keyboard_fd, VT_ACTIVATE, saved_vt); | |
226 } | |
227 } | |
228 } | |
229 | |
230 void FB_CloseKeyboard(_THIS) | |
231 { | |
232 if ( keyboard_fd >= 0 ) { | |
233 FB_LeaveGraphicsMode(this); | |
234 if ( keyboard_fd > 0 ) { | |
235 close(keyboard_fd); | |
236 } | |
237 } | |
238 keyboard_fd = -1; | |
239 } | |
240 | |
241 int FB_OpenKeyboard(_THIS) | |
242 { | |
243 /* Open only if not already opened */ | |
244 if ( keyboard_fd < 0 ) { | |
91
e85e03f195b4
From: "Markus F.X.J. Oberhumer"
Sam Lantinga <slouken@lokigames.com>
parents:
69
diff
changeset
|
245 static const char * const tty0[] = { "/dev/tty0", "/dev/vc/0", NULL }; |
e85e03f195b4
From: "Markus F.X.J. Oberhumer"
Sam Lantinga <slouken@lokigames.com>
parents:
69
diff
changeset
|
246 static const char * const vcs[] = { "/dev/vc/%d", "/dev/tty%d", NULL }; |
0 | 247 int i, tty0_fd; |
248 | |
249 /* Try to query for a free virtual terminal */ | |
250 tty0_fd = -1; | |
251 for ( i=0; tty0[i] && (tty0_fd < 0); ++i ) { | |
252 tty0_fd = open(tty0[i], O_WRONLY, 0); | |
253 } | |
254 if ( tty0_fd < 0 ) { | |
255 tty0_fd = dup(0); /* Maybe stdin is a VT? */ | |
256 } | |
257 ioctl(tty0_fd, VT_OPENQRY, ¤t_vt); | |
258 close(tty0_fd); | |
259 if ( (geteuid() == 0) && (current_vt > 0) ) { | |
260 for ( i=0; vcs[i] && (keyboard_fd < 0); ++i ) { | |
261 char vtpath[12]; | |
262 | |
1338
604d73db6802
Removed uses of stdlib.h and string.h
Sam Lantinga <slouken@libsdl.org>
parents:
1336
diff
changeset
|
263 SDL_snprintf(vtpath, SDL_arraysize(vtpath), vcs[i], current_vt); |
0 | 264 keyboard_fd = open(vtpath, O_RDWR, 0); |
265 #ifdef DEBUG_KEYBOARD | |
266 fprintf(stderr, "vtpath = %s, fd = %d\n", | |
267 vtpath, keyboard_fd); | |
268 #endif /* DEBUG_KEYBOARD */ | |
269 | |
270 /* This needs to be our controlling tty | |
271 so that the kernel ioctl() calls work | |
272 */ | |
273 if ( keyboard_fd >= 0 ) { | |
274 tty0_fd = open("/dev/tty", O_RDWR, 0); | |
275 if ( tty0_fd >= 0 ) { | |
276 ioctl(tty0_fd, TIOCNOTTY, 0); | |
277 close(tty0_fd); | |
278 } | |
279 } | |
280 } | |
281 } | |
282 if ( keyboard_fd < 0 ) { | |
283 /* Last resort, maybe our tty is a usable VT */ | |
284 current_vt = 0; | |
285 keyboard_fd = open("/dev/tty", O_RDWR); | |
286 } | |
287 #ifdef DEBUG_KEYBOARD | |
288 fprintf(stderr, "Current VT: %d\n", current_vt); | |
289 #endif | |
290 saved_kbd_mode = -1; | |
291 | |
292 /* Make sure that our input is a console terminal */ | |
293 { int dummy; | |
294 if ( ioctl(keyboard_fd, KDGKBMODE, &dummy) < 0 ) { | |
295 close(keyboard_fd); | |
296 keyboard_fd = -1; | |
297 SDL_SetError("Unable to open a console terminal"); | |
298 } | |
299 } | |
300 | |
301 /* Set up keymap */ | |
302 FB_vgainitkeymaps(keyboard_fd); | |
303 } | |
304 return(keyboard_fd); | |
305 } | |
306 | |
307 static enum { | |
308 MOUSE_NONE = -1, | |
109
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
309 MOUSE_MSC, /* Note: GPM uses the MSC protocol */ |
0 | 310 MOUSE_PS2, |
311 MOUSE_IMPS2, | |
312 MOUSE_MS, | |
313 MOUSE_BM, | |
314 MOUSE_ELO, | |
1201
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
315 MOUSE_TSLIB, |
0 | 316 NUM_MOUSE_DRVS |
317 } mouse_drv = MOUSE_NONE; | |
318 | |
319 void FB_CloseMouse(_THIS) | |
320 { | |
1201
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
321 #ifdef HAVE_TSLIB |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
322 if (ts_dev != NULL) { |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
323 ts_close(ts_dev); |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
324 ts_dev = NULL; |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
325 mouse_fd = -1; |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
326 } |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
327 #endif /* HAVE_TSLIB */ |
0 | 328 if ( mouse_fd > 0 ) { |
329 close(mouse_fd); | |
330 } | |
331 mouse_fd = -1; | |
332 } | |
333 | |
334 /* Returns processes listed in /proc with the desired name */ | |
335 static int find_pid(DIR *proc, const char *wanted_name) | |
336 { | |
337 struct dirent *entry; | |
338 int pid; | |
339 | |
340 /* First scan proc for the gpm process */ | |
341 pid = 0; | |
342 while ( (pid == 0) && ((entry=readdir(proc)) != NULL) ) { | |
343 if ( isdigit(entry->d_name[0]) ) { | |
344 FILE *status; | |
345 char path[PATH_MAX]; | |
346 char name[PATH_MAX]; | |
347 | |
1338
604d73db6802
Removed uses of stdlib.h and string.h
Sam Lantinga <slouken@libsdl.org>
parents:
1336
diff
changeset
|
348 SDL_snprintf(path, SDL_arraysize(path), "/proc/%s/status", entry->d_name); |
0 | 349 status=fopen(path, "r"); |
350 if ( status ) { | |
351 name[0] = '\0'; | |
352 fscanf(status, "Name: %s", name); | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1323
diff
changeset
|
353 if ( SDL_strcmp(name, wanted_name) == 0 ) { |
1341
d02b552e5304
Configure dynamically generates SDL_config.h
Sam Lantinga <slouken@libsdl.org>
parents:
1338
diff
changeset
|
354 pid = SDL_atoi(entry->d_name); |
0 | 355 } |
356 fclose(status); | |
357 } | |
358 } | |
359 } | |
360 return pid; | |
361 } | |
362 | |
363 /* Returns true if /dev/gpmdata is being written to by gpm */ | |
364 static int gpm_available(void) | |
365 { | |
366 int available; | |
367 DIR *proc; | |
368 int pid; | |
369 int cmdline, len, arglen; | |
370 char path[PATH_MAX]; | |
371 char args[PATH_MAX], *arg; | |
372 | |
373 /* Don't bother looking if the fifo isn't there */ | |
374 if ( access(GPM_NODE_FIFO, F_OK) < 0 ) { | |
375 return(0); | |
376 } | |
377 | |
378 available = 0; | |
379 proc = opendir("/proc"); | |
380 if ( proc ) { | |
381 while ( (pid=find_pid(proc, "gpm")) > 0 ) { | |
1338
604d73db6802
Removed uses of stdlib.h and string.h
Sam Lantinga <slouken@libsdl.org>
parents:
1336
diff
changeset
|
382 SDL_snprintf(path, SDL_arraysize(path), "/proc/%d/cmdline", pid); |
0 | 383 cmdline = open(path, O_RDONLY, 0); |
384 if ( cmdline >= 0 ) { | |
385 len = read(cmdline, args, sizeof(args)); | |
386 arg = args; | |
387 while ( len > 0 ) { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1323
diff
changeset
|
388 if ( SDL_strcmp(arg, "-R") == 0 ) { |
0 | 389 available = 1; |
390 } | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1323
diff
changeset
|
391 arglen = SDL_strlen(arg)+1; |
0 | 392 len -= arglen; |
393 arg += arglen; | |
394 } | |
395 close(cmdline); | |
396 } | |
397 } | |
398 closedir(proc); | |
399 } | |
400 return available; | |
401 } | |
402 | |
59 | 403 |
404 /* rcg06112001 Set up IMPS/2 mode, if possible. This gives | |
405 * us access to the mousewheel, etc. Returns zero if | |
406 * writes to device failed, but you still need to query the | |
407 * device to see which mode it's actually in. | |
408 */ | |
409 static int set_imps2_mode(int fd) | |
410 { | |
411 /* If you wanted to control the mouse mode (and we do :) ) ... | |
412 Set IMPS/2 protocol: | |
413 {0xf3,200,0xf3,100,0xf3,80} | |
414 Reset mouse device: | |
415 {0xFF} | |
416 */ | |
417 Uint8 set_imps2[] = {0xf3, 200, 0xf3, 100, 0xf3, 80}; | |
418 Uint8 reset = 0xff; | |
419 fd_set fdset; | |
420 struct timeval tv; | |
421 int retval = 0; | |
422 | |
423 if ( write(fd, &set_imps2, sizeof(set_imps2)) == sizeof(set_imps2) ) { | |
424 if (write(fd, &reset, sizeof (reset)) == sizeof (reset) ) { | |
425 retval = 1; | |
426 } | |
427 } | |
428 | |
429 /* Get rid of any chatter from the above */ | |
430 FD_ZERO(&fdset); | |
431 FD_SET(fd, &fdset); | |
432 tv.tv_sec = 0; | |
433 tv.tv_usec = 0; | |
434 while ( select(fd+1, &fdset, 0, 0, &tv) > 0 ) { | |
435 char temp[32]; | |
436 read(fd, temp, sizeof(temp)); | |
437 } | |
438 | |
439 return retval; | |
440 } | |
441 | |
442 | |
0 | 443 /* Returns true if the mouse uses the IMPS/2 protocol */ |
444 static int detect_imps2(int fd) | |
445 { | |
446 int imps2; | |
447 | |
448 imps2 = 0; | |
59 | 449 |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1323
diff
changeset
|
450 if ( SDL_getenv("SDL_MOUSEDEV_IMPS2") ) { |
0 | 451 imps2 = 1; |
452 } | |
453 if ( ! imps2 ) { | |
59 | 454 Uint8 query_ps2 = 0xF2; |
0 | 455 fd_set fdset; |
456 struct timeval tv; | |
457 | |
458 /* Get rid of any mouse motion noise */ | |
459 FD_ZERO(&fdset); | |
460 FD_SET(fd, &fdset); | |
461 tv.tv_sec = 0; | |
462 tv.tv_usec = 0; | |
463 while ( select(fd+1, &fdset, 0, 0, &tv) > 0 ) { | |
464 char temp[32]; | |
465 read(fd, temp, sizeof(temp)); | |
466 } | |
467 | |
59 | 468 /* Query for the type of mouse protocol */ |
469 if ( write(fd, &query_ps2, sizeof (query_ps2)) == sizeof (query_ps2)) { | |
470 Uint8 ch = 0; | |
0 | 471 |
472 /* Get the mouse protocol response */ | |
473 do { | |
474 FD_ZERO(&fdset); | |
475 FD_SET(fd, &fdset); | |
476 tv.tv_sec = 1; | |
477 tv.tv_usec = 0; | |
478 if ( select(fd+1, &fdset, 0, 0, &tv) < 1 ) { | |
479 break; | |
480 } | |
59 | 481 } while ( (read(fd, &ch, sizeof (ch)) == sizeof (ch)) && |
0 | 482 ((ch == 0xFA) || (ch == 0xAA)) ); |
483 | |
484 /* Experimental values (Logitech wheelmouse) */ | |
485 #ifdef DEBUG_MOUSE | |
486 fprintf(stderr, "Last mouse mode: 0x%x\n", ch); | |
487 #endif | |
104
a746656b7599
Detect more types of IMPS/2 mouse
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
488 if ( (ch == 3) || (ch == 4) ) { |
0 | 489 imps2 = 1; |
490 } | |
491 } | |
492 } | |
493 return imps2; | |
494 } | |
495 | |
496 int FB_OpenMouse(_THIS) | |
497 { | |
69
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
498 int i; |
0 | 499 const char *mousedev; |
500 const char *mousedrv; | |
501 | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1323
diff
changeset
|
502 mousedrv = SDL_getenv("SDL_MOUSEDRV"); |
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1323
diff
changeset
|
503 mousedev = SDL_getenv("SDL_MOUSEDEV"); |
0 | 504 mouse_fd = -1; |
505 | |
1201
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
506 #ifdef HAVE_TSLIB |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1323
diff
changeset
|
507 if ((mousedrv != NULL) && (SDL_strcmp(mousedrv, "TSLIB") == 0)) { |
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1323
diff
changeset
|
508 if (mousedev == NULL) mousedev = SDL_getenv("TSLIB_TSDEVICE"); |
1201
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
509 if (mousedev != NULL) { |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
510 ts_dev = ts_open(mousedev, 1); |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
511 if ((ts_dev != NULL) && (ts_config(ts_dev) >= 0)) { |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
512 #ifdef DEBUG_MOUSE |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
513 fprintf(stderr, "Using tslib touchscreen\n"); |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
514 #endif |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
515 mouse_drv = MOUSE_TSLIB; |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
516 mouse_fd = ts_fd(ts_dev); |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
517 return mouse_fd; |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
518 } |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
519 } |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
520 mouse_drv = MOUSE_NONE; |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
521 return mouse_fd; |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
522 } |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
523 #endif /* HAVE_TSLIB */ |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
524 |
0 | 525 /* ELO TOUCHSCREEN SUPPORT */ |
526 | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1323
diff
changeset
|
527 if( (mousedrv != NULL) && (SDL_strcmp(mousedrv, "ELO") == 0) ) { |
0 | 528 mouse_fd = open(mousedev, O_RDWR); |
529 if ( mouse_fd >= 0 ) { | |
530 if(eloInitController(mouse_fd)) { | |
531 #ifdef DEBUG_MOUSE | |
532 fprintf(stderr, "Using ELO touchscreen\n"); | |
533 #endif | |
534 mouse_drv = MOUSE_ELO; | |
535 } | |
536 | |
537 } | |
538 else if ( mouse_fd < 0 ) { | |
539 mouse_drv = MOUSE_NONE; | |
540 } | |
541 | |
542 return(mouse_fd); | |
543 } | |
544 | |
545 /* STD MICE */ | |
546 | |
547 if ( mousedev == NULL ) { | |
69
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
548 /* FIXME someday... allow multiple mice in this driver */ |
91
e85e03f195b4
From: "Markus F.X.J. Oberhumer"
Sam Lantinga <slouken@lokigames.com>
parents:
69
diff
changeset
|
549 static const char * const ps2mice[] = { |
69
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
550 "/dev/input/mice", "/dev/usbmouse", "/dev/psaux", NULL |
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
551 }; |
0 | 552 /* First try to use GPM in repeater mode */ |
553 if ( mouse_fd < 0 ) { | |
554 if ( gpm_available() ) { | |
555 mouse_fd = open(GPM_NODE_FIFO, O_RDONLY, 0); | |
556 if ( mouse_fd >= 0 ) { | |
557 #ifdef DEBUG_MOUSE | |
558 fprintf(stderr, "Using GPM mouse\n"); | |
559 #endif | |
109
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
560 mouse_drv = MOUSE_MSC; |
0 | 561 } |
562 } | |
563 } | |
69
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
564 /* Now try to use a modern PS/2 mouse */ |
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
565 for ( i=0; (mouse_fd < 0) && ps2mice[i]; ++i ) { |
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
566 mouse_fd = open(ps2mice[i], O_RDWR, 0); |
59 | 567 if (mouse_fd < 0) { |
69
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
568 mouse_fd = open(ps2mice[i], O_RDONLY, 0); |
59 | 569 } |
570 if (mouse_fd >= 0) { | |
69
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
571 /* rcg06112001 Attempt to set IMPS/2 mode */ |
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
572 if ( i == 0 ) { |
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
573 set_imps2_mode(mouse_fd); |
59 | 574 } |
69
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
575 if (detect_imps2(mouse_fd)) { |
0 | 576 #ifdef DEBUG_MOUSE |
69
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
577 fprintf(stderr, "Using IMPS2 mouse\n"); |
0 | 578 #endif |
579 mouse_drv = MOUSE_IMPS2; | |
580 } else { | |
581 #ifdef DEBUG_MOUSE | |
69
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
582 fprintf(stderr, "Using PS2 mouse\n"); |
0 | 583 #endif |
584 mouse_drv = MOUSE_PS2; | |
585 } | |
586 } | |
587 } | |
588 /* Next try to use a PPC ADB port mouse */ | |
589 if ( mouse_fd < 0 ) { | |
590 mouse_fd = open("/dev/adbmouse", O_RDONLY, 0); | |
591 if ( mouse_fd >= 0 ) { | |
592 #ifdef DEBUG_MOUSE | |
593 fprintf(stderr, "Using ADB mouse\n"); | |
594 #endif | |
595 mouse_drv = MOUSE_BM; | |
596 } | |
597 } | |
598 } | |
599 /* Default to a serial Microsoft mouse */ | |
600 if ( mouse_fd < 0 ) { | |
601 if ( mousedev == NULL ) { | |
602 mousedev = "/dev/mouse"; | |
603 } | |
604 mouse_fd = open(mousedev, O_RDONLY, 0); | |
605 if ( mouse_fd >= 0 ) { | |
606 struct termios mouse_termios; | |
607 | |
608 /* Set the sampling speed to 1200 baud */ | |
609 tcgetattr(mouse_fd, &mouse_termios); | |
610 mouse_termios.c_iflag = IGNBRK | IGNPAR; | |
611 mouse_termios.c_oflag = 0; | |
612 mouse_termios.c_lflag = 0; | |
613 mouse_termios.c_line = 0; | |
614 mouse_termios.c_cc[VTIME] = 0; | |
615 mouse_termios.c_cc[VMIN] = 1; | |
616 mouse_termios.c_cflag = CREAD | CLOCAL | HUPCL; | |
617 mouse_termios.c_cflag |= CS8; | |
618 mouse_termios.c_cflag |= B1200; | |
619 tcsetattr(mouse_fd, TCSAFLUSH, &mouse_termios); | |
620 #ifdef DEBUG_MOUSE | |
621 fprintf(stderr, "Using Microsoft mouse on %s\n", mousedev); | |
622 #endif | |
623 mouse_drv = MOUSE_MS; | |
624 } | |
625 } | |
626 if ( mouse_fd < 0 ) { | |
627 mouse_drv = MOUSE_NONE; | |
628 } | |
629 return(mouse_fd); | |
630 } | |
631 | |
632 static int posted = 0; | |
633 | |
634 void FB_vgamousecallback(int button, int relative, int dx, int dy) | |
635 { | |
636 int button_1, button_3; | |
637 int button_state; | |
638 int state_changed; | |
639 int i; | |
640 Uint8 state; | |
641 | |
642 if ( dx || dy ) { | |
643 posted += SDL_PrivateMouseMotion(0, relative, dx, dy); | |
644 } | |
645 | |
646 /* Swap button 1 and 3 */ | |
647 button_1 = (button & 0x04) >> 2; | |
648 button_3 = (button & 0x01) << 2; | |
649 button &= ~0x05; | |
650 button |= (button_1|button_3); | |
651 | |
652 /* See what changed */ | |
653 button_state = SDL_GetMouseState(NULL, NULL); | |
654 state_changed = button_state ^ button; | |
655 for ( i=0; i<8; ++i ) { | |
656 if ( state_changed & (1<<i) ) { | |
657 if ( button & (1<<i) ) { | |
658 state = SDL_PRESSED; | |
659 } else { | |
660 state = SDL_RELEASED; | |
661 } | |
662 posted += SDL_PrivateMouseButton(state, i+1, 0, 0); | |
663 } | |
664 } | |
665 } | |
666 | |
1201
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
667 /* Handle input from tslib */ |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
668 #ifdef HAVE_TSLIB |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
669 static void handle_tslib(_THIS) |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
670 { |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
671 struct ts_sample sample; |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
672 int button; |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
673 |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
674 while (ts_read(ts_dev, &sample, 1) > 0) { |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
675 button = (sample.pressure > 0) ? 1 : 0; |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
676 button <<= 2; /* must report it as button 3 */ |
1323 | 677 FB_vgamousecallback(button, 0, sample.x, sample.y); |
1201
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
678 } |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
679 return; |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
680 } |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
681 #endif /* HAVE_TSLIB */ |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
682 |
109
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
683 /* For now, use MSC, PS/2, and MS protocols |
0 | 684 Driver adapted from the SVGAlib mouse driver code (taken from gpm, etc.) |
685 */ | |
686 static void handle_mouse(_THIS) | |
687 { | |
688 static int start = 0; | |
689 static unsigned char mousebuf[BUFSIZ]; | |
690 static int relative = 1; | |
691 | |
692 int i, nread; | |
693 int button = 0; | |
694 int dx = 0, dy = 0; | |
695 int packetsize = 0; | |
4
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
696 int realx, realy; |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
697 |
0 | 698 /* Figure out the mouse packet size */ |
699 switch (mouse_drv) { | |
700 case MOUSE_NONE: | |
701 /* Ack! */ | |
702 read(mouse_fd, mousebuf, BUFSIZ); | |
703 return; | |
109
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
704 case MOUSE_MSC: |
0 | 705 packetsize = 5; |
706 break; | |
707 case MOUSE_IMPS2: | |
708 packetsize = 4; | |
709 break; | |
710 case MOUSE_PS2: | |
711 case MOUSE_MS: | |
712 case MOUSE_BM: | |
713 packetsize = 3; | |
714 break; | |
715 case MOUSE_ELO: | |
1323 | 716 /* try to read the next packet */ |
717 if(eloReadPosition(this, mouse_fd, &dx, &dy, &button, &realx, &realy)) { | |
718 button = (button & 0x01) << 2; | |
719 FB_vgamousecallback(button, 0, dx, dy); | |
720 } | |
721 return; /* nothing left to do */ | |
1201
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
722 case MOUSE_TSLIB: |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
723 #ifdef HAVE_TSLIB |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
724 handle_tslib(this); |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
725 #endif |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
726 return; /* nothing left to do */ |
1323 | 727 default: |
0 | 728 /* Uh oh.. */ |
729 packetsize = 0; | |
730 break; | |
731 } | |
732 | |
4
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
733 /* Special handling for the quite sensitive ELO controller */ |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
734 if (mouse_drv == MOUSE_ELO) { |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
735 |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
736 } |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
737 |
0 | 738 /* Read as many packets as possible */ |
739 nread = read(mouse_fd, &mousebuf[start], BUFSIZ-start); | |
740 if ( nread < 0 ) { | |
741 return; | |
742 } | |
743 nread += start; | |
744 #ifdef DEBUG_MOUSE | |
745 fprintf(stderr, "Read %d bytes from mouse, start = %d\n", nread, start); | |
746 #endif | |
747 for ( i=0; i<(nread-(packetsize-1)); i += packetsize ) { | |
748 switch (mouse_drv) { | |
749 case MOUSE_NONE: | |
750 break; | |
109
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
751 case MOUSE_MSC: |
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
752 /* MSC protocol has 0x80 in high byte */ |
0 | 753 if ( (mousebuf[i] & 0xF8) != 0x80 ) { |
754 /* Go to next byte */ | |
755 i -= (packetsize-1); | |
756 continue; | |
757 } | |
758 /* Get current mouse state */ | |
759 button = (~mousebuf[i]) & 0x07; | |
760 dx = (signed char)(mousebuf[i+1]) + | |
761 (signed char)(mousebuf[i+3]); | |
762 dy = -((signed char)(mousebuf[i+2]) + | |
763 (signed char)(mousebuf[i+4])); | |
764 break; | |
765 case MOUSE_PS2: | |
766 /* PS/2 protocol has nothing in high byte */ | |
767 if ( (mousebuf[i] & 0xC0) != 0 ) { | |
768 /* Go to next byte */ | |
769 i -= (packetsize-1); | |
770 continue; | |
771 } | |
772 /* Get current mouse state */ | |
773 button = (mousebuf[i] & 0x04) >> 1 | /*Middle*/ | |
774 (mousebuf[i] & 0x02) >> 1 | /*Right*/ | |
775 (mousebuf[i] & 0x01) << 2; /*Left*/ | |
776 dx = (mousebuf[i] & 0x10) ? | |
777 mousebuf[i+1] - 256 : mousebuf[i+1]; | |
778 dy = (mousebuf[i] & 0x20) ? | |
779 -(mousebuf[i+2] - 256) : -mousebuf[i+2]; | |
780 break; | |
781 case MOUSE_IMPS2: | |
782 /* Get current mouse state */ | |
783 button = (mousebuf[i] & 0x04) >> 1 | /*Middle*/ | |
784 (mousebuf[i] & 0x02) >> 1 | /*Right*/ | |
785 (mousebuf[i] & 0x01) << 2 | /*Left*/ | |
786 (mousebuf[i] & 0x40) >> 3 | /* 4 */ | |
787 (mousebuf[i] & 0x80) >> 3; /* 5 */ | |
788 dx = (mousebuf[i] & 0x10) ? | |
789 mousebuf[i+1] - 256 : mousebuf[i+1]; | |
790 dy = (mousebuf[i] & 0x20) ? | |
791 -(mousebuf[i+2] - 256) : -mousebuf[i+2]; | |
792 switch (mousebuf[i+3]&0x0F) { | |
793 case 0x0E: /* DX = +1 */ | |
794 case 0x02: /* DX = -1 */ | |
795 break; | |
796 case 0x0F: /* DY = +1 (map button 4) */ | |
132
2604a7be65af
Added button-up with mouse-wheel on framebuffer console
Sam Lantinga <slouken@libsdl.org>
parents:
109
diff
changeset
|
797 FB_vgamousecallback(button | (1<<3), |
2604a7be65af
Added button-up with mouse-wheel on framebuffer console
Sam Lantinga <slouken@libsdl.org>
parents:
109
diff
changeset
|
798 1, 0, 0); |
0 | 799 break; |
800 case 0x01: /* DY = -1 (map button 5) */ | |
132
2604a7be65af
Added button-up with mouse-wheel on framebuffer console
Sam Lantinga <slouken@libsdl.org>
parents:
109
diff
changeset
|
801 FB_vgamousecallback(button | (1<<4), |
2604a7be65af
Added button-up with mouse-wheel on framebuffer console
Sam Lantinga <slouken@libsdl.org>
parents:
109
diff
changeset
|
802 1, 0, 0); |
0 | 803 break; |
804 } | |
805 break; | |
806 case MOUSE_MS: | |
807 /* Microsoft protocol has 0x40 in high byte */ | |
808 if ( (mousebuf[i] & 0x40) != 0x40 ) { | |
809 /* Go to next byte */ | |
810 i -= (packetsize-1); | |
811 continue; | |
812 } | |
813 /* Get current mouse state */ | |
814 button = ((mousebuf[i] & 0x20) >> 3) | | |
815 ((mousebuf[i] & 0x10) >> 4); | |
816 dx = (signed char)(((mousebuf[i] & 0x03) << 6) | | |
817 (mousebuf[i + 1] & 0x3F)); | |
818 dy = (signed char)(((mousebuf[i] & 0x0C) << 4) | | |
819 (mousebuf[i + 2] & 0x3F)); | |
820 break; | |
821 case MOUSE_BM: | |
822 /* BusMouse protocol has 0xF8 in high byte */ | |
823 if ( (mousebuf[i] & 0xF8) != 0x80 ) { | |
824 /* Go to next byte */ | |
825 i -= (packetsize-1); | |
826 continue; | |
827 } | |
828 /* Get current mouse state */ | |
829 button = (~mousebuf[i]) & 0x07; | |
830 dx = (signed char)mousebuf[i+1]; | |
831 dy = -(signed char)mousebuf[i+2]; | |
832 break; | |
1323 | 833 default: |
0 | 834 /* Uh oh.. */ |
835 dx = 0; | |
836 dy = 0; | |
837 break; | |
838 } | |
839 FB_vgamousecallback(button, relative, dx, dy); | |
840 } | |
841 if ( i < nread ) { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1323
diff
changeset
|
842 SDL_memcpy(mousebuf, &mousebuf[i], (nread-i)); |
0 | 843 start = (nread-i); |
844 } else { | |
845 start = 0; | |
846 } | |
847 return; | |
848 } | |
849 | |
109
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
850 /* Handle switching to another VC, returns when our VC is back. |
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
851 This isn't necessarily the best solution. For SDL 1.3 we need |
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
852 a way of notifying the application when we lose access to the |
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
853 video hardware and when we regain it. |
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
854 */ |
0 | 855 static void switch_vt(_THIS, unsigned short which) |
856 { | |
1241
4b2146866b82
Properly restore vidmode when switching back to SDL's virtual terminal with
Ryan C. Gordon <icculus@icculus.org>
parents:
1201
diff
changeset
|
857 struct fb_var_screeninfo vinfo; |
0 | 858 struct vt_stat vtstate; |
1022
3d4f1930ed02
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
859 unsigned short v_active; |
0 | 860 SDL_Surface *screen; |
861 __u16 saved_pal[3*256]; | |
862 Uint32 screen_arealen; | |
863 Uint8 *screen_contents; | |
864 | |
865 /* Figure out whether or not we're switching to a new console */ | |
866 if ( (ioctl(keyboard_fd, VT_GETSTATE, &vtstate) < 0) || | |
867 (which == vtstate.v_active) ) { | |
868 return; | |
869 } | |
1022
3d4f1930ed02
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
870 v_active = vtstate.v_active; |
0 | 871 |
872 /* Save the contents of the screen, and go to text mode */ | |
873 SDL_mutexP(hw_lock); | |
109
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
874 wait_idle(this); |
0 | 875 screen = SDL_VideoSurface; |
876 screen_arealen = (screen->h*screen->pitch); | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1323
diff
changeset
|
877 screen_contents = (Uint8 *)SDL_malloc(screen_arealen); |
0 | 878 if ( screen_contents ) { |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1323
diff
changeset
|
879 SDL_memcpy(screen_contents, screen->pixels, screen_arealen); |
0 | 880 } |
881 FB_SavePaletteTo(this, 256, saved_pal); | |
1241
4b2146866b82
Properly restore vidmode when switching back to SDL's virtual terminal with
Ryan C. Gordon <icculus@icculus.org>
parents:
1201
diff
changeset
|
882 ioctl(console_fd, FBIOGET_VSCREENINFO, &vinfo); |
0 | 883 ioctl(keyboard_fd, KDSETMODE, KD_TEXT); |
884 | |
885 /* New console, switch to it */ | |
886 if ( ioctl(keyboard_fd, VT_ACTIVATE, which) == 0 ) { | |
887 /* Wait for our console to be activated again */ | |
888 ioctl(keyboard_fd, VT_WAITACTIVE, which); | |
1022
3d4f1930ed02
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
889 while ( ioctl(keyboard_fd, VT_WAITACTIVE, v_active) < 0 ) { |
0 | 890 if ( (errno != EINTR) && (errno != EAGAIN) ) { |
891 /* Unknown VT error - cancel this */ | |
892 break; | |
893 } | |
894 SDL_Delay(500); | |
895 } | |
896 } | |
897 | |
898 /* Restore graphics mode and the contents of the screen */ | |
899 ioctl(keyboard_fd, KDSETMODE, KD_GRAPHICS); | |
1241
4b2146866b82
Properly restore vidmode when switching back to SDL's virtual terminal with
Ryan C. Gordon <icculus@icculus.org>
parents:
1201
diff
changeset
|
900 ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo); |
0 | 901 FB_RestorePaletteFrom(this, 256, saved_pal); |
902 if ( screen_contents ) { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1323
diff
changeset
|
903 SDL_memcpy(screen->pixels, screen_contents, screen_arealen); |
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1323
diff
changeset
|
904 SDL_free(screen_contents); |
0 | 905 } |
906 SDL_mutexV(hw_lock); | |
907 } | |
908 | |
909 static void handle_keyboard(_THIS) | |
910 { | |
911 unsigned char keybuf[BUFSIZ]; | |
912 int i, nread; | |
913 int pressed; | |
914 int scancode; | |
915 SDL_keysym keysym; | |
916 | |
917 nread = read(keyboard_fd, keybuf, BUFSIZ); | |
918 for ( i=0; i<nread; ++i ) { | |
919 scancode = keybuf[i] & 0x7F; | |
920 if ( keybuf[i] & 0x80 ) { | |
921 pressed = SDL_RELEASED; | |
922 } else { | |
923 pressed = SDL_PRESSED; | |
924 } | |
925 TranslateKey(scancode, &keysym); | |
926 /* Handle Alt-FN for vt switch */ | |
927 switch (keysym.sym) { | |
928 case SDLK_F1: | |
929 case SDLK_F2: | |
930 case SDLK_F3: | |
931 case SDLK_F4: | |
932 case SDLK_F5: | |
933 case SDLK_F6: | |
934 case SDLK_F7: | |
935 case SDLK_F8: | |
936 case SDLK_F9: | |
937 case SDLK_F10: | |
938 case SDLK_F11: | |
939 case SDLK_F12: | |
940 if ( SDL_GetModState() & KMOD_ALT ) { | |
109
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
941 if ( pressed ) { |
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
942 switch_vt(this, (keysym.sym-SDLK_F1)+1); |
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
943 } |
0 | 944 break; |
945 } | |
946 /* Fall through to normal processing */ | |
947 default: | |
948 posted += SDL_PrivateKeyboard(pressed, &keysym); | |
949 break; | |
950 } | |
951 } | |
952 } | |
953 | |
954 void FB_PumpEvents(_THIS) | |
955 { | |
956 fd_set fdset; | |
957 int max_fd; | |
958 static struct timeval zero; | |
959 | |
960 do { | |
961 posted = 0; | |
962 | |
963 FD_ZERO(&fdset); | |
964 max_fd = 0; | |
965 if ( keyboard_fd >= 0 ) { | |
966 FD_SET(keyboard_fd, &fdset); | |
967 if ( max_fd < keyboard_fd ) { | |
968 max_fd = keyboard_fd; | |
969 } | |
970 } | |
971 if ( mouse_fd >= 0 ) { | |
972 FD_SET(mouse_fd, &fdset); | |
973 if ( max_fd < mouse_fd ) { | |
974 max_fd = mouse_fd; | |
975 } | |
976 } | |
977 if ( select(max_fd+1, &fdset, NULL, NULL, &zero) > 0 ) { | |
978 if ( keyboard_fd >= 0 ) { | |
979 if ( FD_ISSET(keyboard_fd, &fdset) ) { | |
980 handle_keyboard(this); | |
981 } | |
982 } | |
983 if ( mouse_fd >= 0 ) { | |
984 if ( FD_ISSET(mouse_fd, &fdset) ) { | |
985 handle_mouse(this); | |
986 } | |
987 } | |
988 } | |
989 } while ( posted ); | |
990 } | |
991 | |
992 void FB_InitOSKeymap(_THIS) | |
993 { | |
994 int i; | |
995 | |
996 /* Initialize the Linux key translation table */ | |
997 | |
998 /* First get the ascii keys and others not well handled */ | |
999 for (i=0; i<SDL_TABLESIZE(keymap); ++i) { | |
1000 switch(i) { | |
1001 /* These aren't handled by the x86 kernel keymapping (?) */ | |
1002 case SCANCODE_PRINTSCREEN: | |
1003 keymap[i] = SDLK_PRINT; | |
1004 break; | |
1005 case SCANCODE_BREAK: | |
1006 keymap[i] = SDLK_BREAK; | |
1007 break; | |
1008 case SCANCODE_BREAK_ALTERNATIVE: | |
1009 keymap[i] = SDLK_PAUSE; | |
1010 break; | |
1011 case SCANCODE_LEFTSHIFT: | |
1012 keymap[i] = SDLK_LSHIFT; | |
1013 break; | |
1014 case SCANCODE_RIGHTSHIFT: | |
1015 keymap[i] = SDLK_RSHIFT; | |
1016 break; | |
1017 case SCANCODE_LEFTCONTROL: | |
1018 keymap[i] = SDLK_LCTRL; | |
1019 break; | |
1020 case SCANCODE_RIGHTCONTROL: | |
1021 keymap[i] = SDLK_RCTRL; | |
1022 break; | |
1023 case SCANCODE_RIGHTWIN: | |
1024 keymap[i] = SDLK_RSUPER; | |
1025 break; | |
1026 case SCANCODE_LEFTWIN: | |
1027 keymap[i] = SDLK_LSUPER; | |
1028 break; | |
1029 case 127: | |
1030 keymap[i] = SDLK_MENU; | |
1031 break; | |
1032 /* this should take care of all standard ascii keys */ | |
1033 default: | |
1034 keymap[i] = KVAL(vga_keymap[0][i]); | |
1035 break; | |
1036 } | |
1037 } | |
1038 for (i=0; i<SDL_TABLESIZE(keymap); ++i) { | |
1039 switch(keymap_temp[i]) { | |
1040 case K_F1: keymap[i] = SDLK_F1; break; | |
1041 case K_F2: keymap[i] = SDLK_F2; break; | |
1042 case K_F3: keymap[i] = SDLK_F3; break; | |
1043 case K_F4: keymap[i] = SDLK_F4; break; | |
1044 case K_F5: keymap[i] = SDLK_F5; break; | |
1045 case K_F6: keymap[i] = SDLK_F6; break; | |
1046 case K_F7: keymap[i] = SDLK_F7; break; | |
1047 case K_F8: keymap[i] = SDLK_F8; break; | |
1048 case K_F9: keymap[i] = SDLK_F9; break; | |
1049 case K_F10: keymap[i] = SDLK_F10; break; | |
1050 case K_F11: keymap[i] = SDLK_F11; break; | |
1051 case K_F12: keymap[i] = SDLK_F12; break; | |
1052 | |
1053 case K_DOWN: keymap[i] = SDLK_DOWN; break; | |
1054 case K_LEFT: keymap[i] = SDLK_LEFT; break; | |
1055 case K_RIGHT: keymap[i] = SDLK_RIGHT; break; | |
1056 case K_UP: keymap[i] = SDLK_UP; break; | |
1057 | |
1058 case K_P0: keymap[i] = SDLK_KP0; break; | |
1059 case K_P1: keymap[i] = SDLK_KP1; break; | |
1060 case K_P2: keymap[i] = SDLK_KP2; break; | |
1061 case K_P3: keymap[i] = SDLK_KP3; break; | |
1062 case K_P4: keymap[i] = SDLK_KP4; break; | |
1063 case K_P5: keymap[i] = SDLK_KP5; break; | |
1064 case K_P6: keymap[i] = SDLK_KP6; break; | |
1065 case K_P7: keymap[i] = SDLK_KP7; break; | |
1066 case K_P8: keymap[i] = SDLK_KP8; break; | |
1067 case K_P9: keymap[i] = SDLK_KP9; break; | |
1068 case K_PPLUS: keymap[i] = SDLK_KP_PLUS; break; | |
1069 case K_PMINUS: keymap[i] = SDLK_KP_MINUS; break; | |
1070 case K_PSTAR: keymap[i] = SDLK_KP_MULTIPLY; break; | |
1071 case K_PSLASH: keymap[i] = SDLK_KP_DIVIDE; break; | |
1072 case K_PENTER: keymap[i] = SDLK_KP_ENTER; break; | |
1073 case K_PDOT: keymap[i] = SDLK_KP_PERIOD; break; | |
1074 | |
1075 case K_SHIFT: if ( keymap[i] != SDLK_RSHIFT ) | |
1076 keymap[i] = SDLK_LSHIFT; | |
1077 break; | |
1078 case K_SHIFTL: keymap[i] = SDLK_LSHIFT; break; | |
1079 case K_SHIFTR: keymap[i] = SDLK_RSHIFT; break; | |
1080 case K_CTRL: if ( keymap[i] != SDLK_RCTRL ) | |
1081 keymap[i] = SDLK_LCTRL; | |
1082 break; | |
1083 case K_CTRLL: keymap[i] = SDLK_LCTRL; break; | |
1084 case K_CTRLR: keymap[i] = SDLK_RCTRL; break; | |
1085 case K_ALT: keymap[i] = SDLK_LALT; break; | |
1086 case K_ALTGR: keymap[i] = SDLK_RALT; break; | |
1087 | |
1088 case K_INSERT: keymap[i] = SDLK_INSERT; break; | |
1089 case K_REMOVE: keymap[i] = SDLK_DELETE; break; | |
1090 case K_PGUP: keymap[i] = SDLK_PAGEUP; break; | |
1091 case K_PGDN: keymap[i] = SDLK_PAGEDOWN; break; | |
1092 case K_FIND: keymap[i] = SDLK_HOME; break; | |
1093 case K_SELECT: keymap[i] = SDLK_END; break; | |
1094 | |
1095 case K_NUM: keymap[i] = SDLK_NUMLOCK; break; | |
1096 case K_CAPS: keymap[i] = SDLK_CAPSLOCK; break; | |
1097 | |
1098 case K_F13: keymap[i] = SDLK_PRINT; break; | |
1099 case K_HOLD: keymap[i] = SDLK_SCROLLOCK; break; | |
1100 case K_PAUSE: keymap[i] = SDLK_PAUSE; break; | |
1101 | |
1102 case 127: keymap[i] = SDLK_BACKSPACE; break; | |
1103 | |
1104 default: break; | |
1105 } | |
1106 } | |
1107 } | |
1108 | |
1109 static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym) | |
1110 { | |
1111 /* Set the keysym information */ | |
1112 keysym->scancode = scancode; | |
1113 keysym->sym = keymap[scancode]; | |
1114 keysym->mod = KMOD_NONE; | |
1115 | |
1116 /* If UNICODE is on, get the UNICODE value for the key */ | |
1117 keysym->unicode = 0; | |
1118 if ( SDL_TranslateUNICODE ) { | |
1119 int map; | |
1120 SDLMod modstate; | |
1121 | |
1122 modstate = SDL_GetModState(); | |
1123 map = 0; | |
1124 if ( modstate & KMOD_SHIFT ) { | |
1125 map |= (1<<KG_SHIFT); | |
1126 } | |
1127 if ( modstate & KMOD_CTRL ) { | |
1128 map |= (1<<KG_CTRL); | |
1129 } | |
1130 if ( modstate & KMOD_ALT ) { | |
1131 map |= (1<<KG_ALT); | |
1132 } | |
1133 if ( modstate & KMOD_MODE ) { | |
1134 map |= (1<<KG_ALTGR); | |
1135 } | |
1136 if ( KTYP(vga_keymap[map][scancode]) == KT_LETTER ) { | |
1137 if ( modstate & KMOD_CAPS ) { | |
1138 map ^= (1<<KG_SHIFT); | |
1139 } | |
1140 } | |
1141 if ( KTYP(vga_keymap[map][scancode]) == KT_PAD ) { | |
1142 if ( modstate & KMOD_NUM ) { | |
1143 keysym->unicode=KVAL(vga_keymap[map][scancode]); | |
1144 } | |
1145 } else { | |
1146 keysym->unicode = KVAL(vga_keymap[map][scancode]); | |
1147 } | |
1148 } | |
1149 return(keysym); | |
1150 } |