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