Mercurial > sdl-ios-xcode
annotate src/video/fbcon/SDL_fbevents.c @ 4157:baf615f9f2a0 SDL-1.2
Date: Thu, 16 Oct 2008 20:27:34 +0400
From: "Ilya Kasnacheev" <ilya.kasnacheev@gmail.com>
To: sdl@lists.libsdl.org
Subject: [SDL] SDL for Windows CE: a few GAPI patches
Hi *!
I've just ported a POWDER roguelike ( http://www.zincland.com/powder/ ) to
Windows CE (PDAs, Windows Mobile/Pocket PC). To do that, I had to get libsdl
working. Thanks for the awesome project files, it built without a hitch.
Nevertheless, I've found quite a few bugs in Windows CE (GAPI) SDL
implementation, which I've solved and now present as a serie of patches.
I'll try carefully annotate them. Please annotate them so I can work
toward accepting
them into the main source tree since without them SDL isn't really working on
Windows CE (I wonder why nobody fixed them before, btw: why isn't SDL popular as
a way to develop Windows CE games? Where are no ports?)
These changes can't be considered flawless, but they can be considered working
because I've yet to hear complains about things I fixed and POWDER build for
Windows CE is now considered stable.
Note: my comments start with !!, delete them before applying.
diff -bru SDL-1.2.13/src/video/gapi/SDL_gapivideo.c
SDL-1.2.13-new/src/video/gapi/SDL_gapivideo.c
--- SDL-1.2.13/src/video/gapi/SDL_gapivideo.c 2007-12-31
07:48:00.000000000 +0300
+++ SDL-1.2.13-new/src/video/gapi/SDL_gapivideo.c 2008-10-16
20:02:11.000000000 +0400
@@ -643,6 +643,7 @@
}
gapi->userOrientation = SDL_ORIENTATION_UP;
+ gapi->systemOrientation = SDL_ORIENTATION_UP;
video->flags = SDL_FULLSCREEN; /* Clear flags, GAPI supports
fullscreen only */
/* GAPI or VGA? */
@@ -661,18 +662,21 @@
}
/* detect user landscape mode */
- if( (width > height) && (GetSystemMetrics(SM_CXSCREEN) <
GetSystemMetrics(SM_CYSCREEN)))
+ if( (width > height) && (gapi->gxProperties.cxWidth <
gapi->gxProperties.cyHeight))
gapi->userOrientation = SDL_ORIENTATION_RIGHT;
+ if(GetSystemMetrics(SM_CYSCREEN) < GetSystemMetrics(SM_CXSCREEN))
+ gapi->systemOrientation = SDL_ORIENTATION_RIGHT;
+
/* shall we apply hires fix? for example when we do not use
hires resource */
gapi->hiresFix = 0;
- if( gapi->userOrientation == SDL_ORIENTATION_RIGHT )
+ if( gapi->systemOrientation == gapi->userOrientation )
{
- if( (width > GetSystemMetrics(SM_CYSCREEN)) || (height
> GetSystemMetrics(SM_CXSCREEN)))
+ if( (width > GetSystemMetrics(SM_CXSCREEN)) || (height
> GetSystemMetrics(SM_CYSCREEN)))
gapi->hiresFix = 1;
} else
- if( (width > GetSystemMetrics(SM_CXSCREEN)) || (height
> GetSystemMetrics(SM_CYSCREEN)))
- if( !((width == GetSystemMetrics(SM_CYSCREEN))
&& (height == GetSystemMetrics(SM_CXSCREEN)))) // user portrait,
device landscape
+ if( (width > GetSystemMetrics(SM_CYSCREEN)) || (height
> GetSystemMetrics(SM_CXSCREEN)))
+// if( !((width == gapi->gxProperties.cyHeight)
&& (height == gapi->gxProperties.cxWidth))) // user portrait, device
landscape
gapi->hiresFix = 1;
switch( gapi->userOrientation )
!! It used to query system metrics which return dimensions according to screen
!! orientation, which can really be portrait, left landscape or right landscape.
!! This is presumably incorrect because we couldn't care less about user mode
!! dimensions - all we want are the GAPI framebuffer dimensions, which
only match
!! user dimensions in one of possible orientations.
!! There's a fair dose of cargo cult programming involved in this fix, but it
!! used to work only in one orientation (portrait for PDAs, where frame-buffer
!! have same orientation as user screen), and now it works on all orientations.
@@ -742,21 +746,30 @@
WIN_FlushMessageQueue();
/* Open GAPI display */
- if( !gapi->useVga && this->hidden->useGXOpenDisplay )
+ if( !gapi->useVga && this->hidden->useGXOpenDisplay &&
!this->hidden->alreadyGXOpened )
+ {
+ this->hidden->alreadyGXOpened = 1;
if( !gapi->gxFunc.GXOpenDisplay(SDL_Window, GX_FULLSCREEN) )
{
SDL_SetError("Couldn't initialize GAPI");
return(NULL);
}
+ }
#if REPORT_VIDEO_INFO
printf("Video properties:\n");
printf("display bpp: %d\n", gapi->gxProperties.cBPP);
printf("display width: %d\n", gapi->gxProperties.cxWidth);
printf("display height: %d\n", gapi->gxProperties.cyHeight);
+ printf("system display width: %d\n", GetSystemMetrics(SM_CXSCREEN));
+ printf("system display height: %d\n", GetSystemMetrics(SM_CYSCREEN));
printf("x pitch: %d\n", gapi->gxProperties.cbxPitch);
printf("y pitch: %d\n", gapi->gxProperties.cbyPitch);
printf("gapi flags: 0x%x\n", gapi->gxProperties.ffFormat);
+ printf("user orientation: %d\n", gapi->userOrientation);
+ printf("system orientation: %d\n", gapi->userOrientation);
+ printf("gapi orientation: %d\n", gapi->gapiOrientation);
+
if( !gapi->useVga && this->hidden->useGXOpenDisplay && gapi->needUpdate)
{
!! Previous version used to call gapi->gxFunc.GXOpenDisplay each time the video
!! mode would be changed. You shouldn't, because this call has a
meaning "Lock the
!! GAPI framebuffer, designate it as busy", so the second call will fail (it is
!! already locked/busy).
!! Testing might not find that because most programs set up the video mode only
!! once, but POWDER does this once in a while, so it crashed when in
320x240 mode
!! (640x480 mode doesn't use that code, it worked fine).
diff -bru SDL-1.2.13/src/video/gapi/SDL_gapivideo.h
SDL-1.2.13-new/src/video/gapi/SDL_gapivideo.h
--- SDL-1.2.13/src/video/gapi/SDL_gapivideo.h 2007-12-31
07:48:00.000000000 +0300
+++ SDL-1.2.13-new/src/video/gapi/SDL_gapivideo.h 2008-10-16
20:02:11.000000000 +0400
@@ -132,12 +132,17 @@
#define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */
int SDL_nummodes[NUM_MODELISTS];
SDL_Rect **SDL_modelist[NUM_MODELISTS];
+ // The orientation of the video mode user wants to get
+ // Probably restricted to UP and RIGHT
enum SDL_ScreenOrientation userOrientation;
int invert;
char hiresFix; // using hires mode without defining hires resource
// --------------
int useGXOpenDisplay; /* use GXOpenDispplay */
+ int alreadyGXOpened;
int w, h;
+ // The orientation of GAPI framebuffer.
+ // Never changes on the same device.
enum SDL_ScreenOrientation gapiOrientation;
void *buffer; // may be 8, 16, 24, 32 bpp
@@ -153,6 +158,10 @@
int startOffset; // in bytes
int useVga;
int suspended; // do not pu anything into video memory
+ // The orientation of the system, as defined by SM_CXSCREEN
and SM_CYSCREEN
+ // User can change it by using 'screen layout' in system options
+ // Restricted to UP or RIGHT
+ enum SDL_ScreenOrientation systemOrientation;
};
!! This is a flag variable, see the previous comment
!! And yet another orientation: now we have to keep three of them in mind.
diff -bru SDL-1.2.13/src/video/wincommon/SDL_sysevents.c
SDL-1.2.13-new/src/video/wincommon/SDL_sysevents.c
--- SDL-1.2.13/src/video/wincommon/SDL_sysevents.c 2007-12-31
07:48:02.000000000 +0300
+++ SDL-1.2.13-new/src/video/wincommon/SDL_sysevents.c 2008-10-16
20:02:12.000000000 +0400
@@ -160,10 +160,22 @@
#endif */
}
break;
+ // FIXME: Older version used just SDL_VideoSurface->(w, h)
+ // w and h are "clipped" while x and y are "raw", which caused
+ // x in former and y in latter case to be clipped in a
wrong direction,
+ // thus offsetting the coordinate on 2 x clip pixels
+ // (like, 128 for 640 -> 512 clipping).
+ // We will now try to extract and use raw values.
+ // The way to do that RIGHT is do
(orientation-dependent) clipping before
+ // doing this transform, but it's hardly possible.
+
+ // SEE SDL_mouse.c /ClipOffset to understand these calculations.
case SDL_ORIENTATION_RIGHT:
if (!SDL_VideoSurface)
break;
- rotatedX = SDL_VideoSurface->w - *y;
+ rotatedX = (2 *
((SDL_VideoSurface->offset%SDL_VideoSurface->pitch)/
+ SDL_VideoSurface->format->BytesPerPixel))
+ + SDL_VideoSurface->w - *y;
rotatedY = *x;
*x = rotatedX;
*y = rotatedY;
@@ -172,7 +184,8 @@
if (!SDL_VideoSurface)
break;
rotatedX = *y;
- rotatedY = SDL_VideoSurface->h - *x;
+ rotatedY = (2 *
(SDL_VideoSurface->offset/SDL_VideoSurface->pitch))
+ + SDL_VideoSurface->h - *x;
*x = rotatedX;
*y = rotatedY;
break;
!! That's the trickest part, hence the long comment.
!! GAPI would really support only 320x240 or 640x480 mode, if application
!! requested the different screen size (as POWDER did, wishing
256x192), then SDL
!! is going to grab the first mode that fits the requested, and pad the screen
!! with black bars (as they do with wide-screen films).
!! It would also get, say, 240x320 mode, and to turn it into 256x192 it would
!! need to rotate mouse clicks.
!! It worked, but one bug slipped through: it would receive mouse clicks
!! unpadded, then rotate them, and then pad the black bars. The
problem is: rotate
!! is done by GAPI driver while padding is done by SDL core. SDL core
doesn't know
!! anything about rotating, so it would pad one of dimensions incorrectly.
I understand that some of my claims (or code) might seem unbacked, but you can
always grab the POWDER binary, compile your own libsdl with one or more of
those fixes turned off, and see how weird it would misbehave. I can even supply
you with those custom builds of libsdl if you don't want to set up the build
environment for windows ce, you'll just need a PDA or a smartphone with it.
I plan to take care of SDL on Windows CE as long as I maintain the POWDER port.
POWDER is good for that because it:
Employs both padded (with centered image, black bars) and unpadded
(image occupies full screen) graphics; initializes video more than
once; uses both 320x240 and 640x480 video; uses both stylus and
buttons.
There's still a list of unresolved issues which I'm planning to fix:
1) Arrow buttons on PDA return weird scancodes compared to PC, this
caused the game to misbehave before I've fixed that. You can see it on
those diagrams:
http://wrar.name/upload/powder-htc.png
http://wrar.name/upload/powder-pda.png
2) SDL (or underlying windows) doesn't care to rotate arrow presses
when we're in a low-res GAPI mode, but it will rotate them in VGA mode
(because of different screen orientations, the same arrow buttons can
suddently mean different directions). Solution: we should stick to
GAPI user orientation (the orientation the program supposedly wants)
and rotate the keys on our own.
_______________________________________________
SDL mailing list
SDL@lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Fri, 07 Nov 2008 04:15:36 +0000 |
parents | 15ae67aa6b4b |
children | c121d94672cb a1b03ba2fcd0 |
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 */ |
1402
d910939febfa
Use consistent identifiers for the various platforms we support.
Sam Lantinga <slouken@libsdl.org>
parents:
1379
diff
changeset
|
22 #include "SDL_config.h" |
0 | 23 |
24 /* Handle the event stream, converting console events into SDL events */ | |
25 | |
1338
604d73db6802
Removed uses of stdlib.h and string.h
Sam Lantinga <slouken@libsdl.org>
parents:
1336
diff
changeset
|
26 #include <stdio.h> |
0 | 27 #include <sys/types.h> |
28 #include <sys/time.h> | |
29 #include <sys/ioctl.h> | |
30 #include <unistd.h> | |
31 #include <fcntl.h> | |
32 #include <errno.h> | |
33 #include <limits.h> | |
34 | |
35 /* For parsing /proc */ | |
36 #include <dirent.h> | |
37 #include <ctype.h> | |
38 | |
39 #include <linux/vt.h> | |
40 #include <linux/kd.h> | |
41 #include <linux/keyboard.h> | |
42 | |
1359
1e4ba2e063b4
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
1358
diff
changeset
|
43 #include "SDL_timer.h" |
0 | 44 #include "SDL_mutex.h" |
1361
19418e4422cb
New configure-based build system. Still work in progress, but much improved
Sam Lantinga <slouken@libsdl.org>
parents:
1359
diff
changeset
|
45 #include "../SDL_sysvideo.h" |
19418e4422cb
New configure-based build system. Still work in progress, but much improved
Sam Lantinga <slouken@libsdl.org>
parents:
1359
diff
changeset
|
46 #include "../../events/SDL_sysevents.h" |
19418e4422cb
New configure-based build system. Still work in progress, but much improved
Sam Lantinga <slouken@libsdl.org>
parents:
1359
diff
changeset
|
47 #include "../../events/SDL_events_c.h" |
0 | 48 #include "SDL_fbvideo.h" |
49 #include "SDL_fbevents_c.h" | |
50 #include "SDL_fbkeys.h" | |
51 | |
52 #include "SDL_fbelo.h" | |
53 | |
54 #ifndef GPM_NODE_FIFO | |
55 #define GPM_NODE_FIFO "/dev/gpmdata" | |
56 #endif | |
57 | |
1778
e28233f37f8c
Fixed detection of current vt when not running as root.
Sam Lantinga <slouken@libsdl.org>
parents:
1776
diff
changeset
|
58 /*#define DEBUG_KEYBOARD*/ |
1772 | 59 /*#define DEBUG_MOUSE*/ |
0 | 60 |
61 /* The translation tables from a console scancode to a SDL keysym */ | |
62 #define NUM_VGAKEYMAPS (1<<KG_CAPSSHIFT) | |
63 static Uint16 vga_keymap[NUM_VGAKEYMAPS][NR_KEYS]; | |
64 static SDLKey keymap[128]; | |
65 static Uint16 keymap_temp[128]; /* only used at startup */ | |
66 static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym); | |
67 | |
68 /* Ugh, we have to duplicate the kernel's keysym mapping code... | |
69 Oh, it's not so bad. :-) | |
70 | |
71 FIXME: Add keyboard LED handling code | |
72 */ | |
73 static void FB_vgainitkeymaps(int fd) | |
74 { | |
75 struct kbentry entry; | |
76 int map, i; | |
77 | |
78 /* Don't do anything if we are passed a closed keyboard */ | |
79 if ( fd < 0 ) { | |
80 return; | |
81 } | |
82 | |
83 /* Load all the keysym mappings */ | |
84 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
|
85 SDL_memset(vga_keymap[map], 0, NR_KEYS*sizeof(Uint16)); |
0 | 86 for ( i=0; i<NR_KEYS; ++i ) { |
87 entry.kb_table = map; | |
88 entry.kb_index = i; | |
89 if ( ioctl(fd, KDGKBENT, &entry) == 0 ) { | |
90 /* fill keytemp. This replaces SDL_fbkeys.h */ | |
91 if ( (map == 0) && (i<128) ) { | |
92 keymap_temp[i] = entry.kb_value; | |
93 } | |
94 /* The "Enter" key is a special case */ | |
95 if ( entry.kb_value == K_ENTER ) { | |
96 entry.kb_value = K(KT_ASCII,13); | |
97 } | |
98 /* Handle numpad specially as well */ | |
99 if ( KTYP(entry.kb_value) == KT_PAD ) { | |
100 switch ( entry.kb_value ) { | |
101 case K_P0: | |
102 case K_P1: | |
103 case K_P2: | |
104 case K_P3: | |
105 case K_P4: | |
106 case K_P5: | |
107 case K_P6: | |
108 case K_P7: | |
109 case K_P8: | |
110 case K_P9: | |
111 vga_keymap[map][i]=entry.kb_value; | |
112 vga_keymap[map][i]+= '0'; | |
113 break; | |
114 case K_PPLUS: | |
115 vga_keymap[map][i]=K(KT_ASCII,'+'); | |
116 break; | |
117 case K_PMINUS: | |
118 vga_keymap[map][i]=K(KT_ASCII,'-'); | |
119 break; | |
120 case K_PSTAR: | |
121 vga_keymap[map][i]=K(KT_ASCII,'*'); | |
122 break; | |
123 case K_PSLASH: | |
124 vga_keymap[map][i]=K(KT_ASCII,'/'); | |
125 break; | |
126 case K_PENTER: | |
127 vga_keymap[map][i]=K(KT_ASCII,'\r'); | |
128 break; | |
129 case K_PCOMMA: | |
130 vga_keymap[map][i]=K(KT_ASCII,','); | |
131 break; | |
132 case K_PDOT: | |
133 vga_keymap[map][i]=K(KT_ASCII,'.'); | |
134 break; | |
135 default: | |
136 break; | |
137 } | |
138 } | |
139 /* Do the normal key translation */ | |
140 if ( (KTYP(entry.kb_value) == KT_LATIN) || | |
141 (KTYP(entry.kb_value) == KT_ASCII) || | |
142 (KTYP(entry.kb_value) == KT_LETTER) ) { | |
143 vga_keymap[map][i] = entry.kb_value; | |
144 } | |
145 } | |
146 } | |
147 } | |
148 } | |
149 | |
150 int FB_InGraphicsMode(_THIS) | |
151 { | |
152 return((keyboard_fd >= 0) && (saved_kbd_mode >= 0)); | |
153 } | |
154 | |
155 int FB_EnterGraphicsMode(_THIS) | |
156 { | |
157 struct termios keyboard_termios; | |
158 | |
159 /* Set medium-raw keyboard mode */ | |
160 if ( (keyboard_fd >= 0) && !FB_InGraphicsMode(this) ) { | |
161 | |
162 /* Switch to the correct virtual terminal */ | |
163 if ( current_vt > 0 ) { | |
164 struct vt_stat vtstate; | |
165 | |
166 if ( ioctl(keyboard_fd, VT_GETSTATE, &vtstate) == 0 ) { | |
167 saved_vt = vtstate.v_active; | |
168 } | |
169 if ( ioctl(keyboard_fd, VT_ACTIVATE, current_vt) == 0 ) { | |
170 ioctl(keyboard_fd, VT_WAITACTIVE, current_vt); | |
171 } | |
172 } | |
173 | |
174 /* Set the terminal input mode */ | |
175 if ( tcgetattr(keyboard_fd, &saved_kbd_termios) < 0 ) { | |
176 SDL_SetError("Unable to get terminal attributes"); | |
177 if ( keyboard_fd > 0 ) { | |
178 close(keyboard_fd); | |
179 } | |
180 keyboard_fd = -1; | |
181 return(-1); | |
182 } | |
183 if ( ioctl(keyboard_fd, KDGKBMODE, &saved_kbd_mode) < 0 ) { | |
184 SDL_SetError("Unable to get current keyboard mode"); | |
185 if ( keyboard_fd > 0 ) { | |
186 close(keyboard_fd); | |
187 } | |
188 keyboard_fd = -1; | |
189 return(-1); | |
190 } | |
191 keyboard_termios = saved_kbd_termios; | |
192 keyboard_termios.c_lflag &= ~(ICANON | ECHO | ISIG); | |
193 keyboard_termios.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON); | |
194 keyboard_termios.c_cc[VMIN] = 0; | |
195 keyboard_termios.c_cc[VTIME] = 0; | |
196 if (tcsetattr(keyboard_fd, TCSAFLUSH, &keyboard_termios) < 0) { | |
197 FB_CloseKeyboard(this); | |
198 SDL_SetError("Unable to set terminal attributes"); | |
199 return(-1); | |
200 } | |
201 /* This will fail if we aren't root or this isn't our tty */ | |
202 if ( ioctl(keyboard_fd, KDSKBMODE, K_MEDIUMRAW) < 0 ) { | |
203 FB_CloseKeyboard(this); | |
204 SDL_SetError("Unable to set keyboard in raw mode"); | |
205 return(-1); | |
206 } | |
207 if ( ioctl(keyboard_fd, KDSETMODE, KD_GRAPHICS) < 0 ) { | |
208 FB_CloseKeyboard(this); | |
209 SDL_SetError("Unable to set keyboard in graphics mode"); | |
210 return(-1); | |
211 } | |
1780 | 212 /* Prevent switching the virtual terminal */ |
213 ioctl(keyboard_fd, VT_LOCKSWITCH, 1); | |
0 | 214 } |
215 return(keyboard_fd); | |
216 } | |
217 | |
218 void FB_LeaveGraphicsMode(_THIS) | |
219 { | |
220 if ( FB_InGraphicsMode(this) ) { | |
221 ioctl(keyboard_fd, KDSETMODE, KD_TEXT); | |
222 ioctl(keyboard_fd, KDSKBMODE, saved_kbd_mode); | |
223 tcsetattr(keyboard_fd, TCSAFLUSH, &saved_kbd_termios); | |
224 saved_kbd_mode = -1; | |
225 | |
226 /* Head back over to the original virtual terminal */ | |
1780 | 227 ioctl(keyboard_fd, VT_UNLOCKSWITCH, 1); |
0 | 228 if ( saved_vt > 0 ) { |
229 ioctl(keyboard_fd, VT_ACTIVATE, saved_vt); | |
230 } | |
231 } | |
232 } | |
233 | |
234 void FB_CloseKeyboard(_THIS) | |
235 { | |
236 if ( keyboard_fd >= 0 ) { | |
237 FB_LeaveGraphicsMode(this); | |
238 if ( keyboard_fd > 0 ) { | |
239 close(keyboard_fd); | |
240 } | |
241 } | |
242 keyboard_fd = -1; | |
243 } | |
244 | |
245 int FB_OpenKeyboard(_THIS) | |
246 { | |
247 /* Open only if not already opened */ | |
248 if ( keyboard_fd < 0 ) { | |
91
e85e03f195b4
From: "Markus F.X.J. Oberhumer"
Sam Lantinga <slouken@lokigames.com>
parents:
69
diff
changeset
|
249 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
|
250 static const char * const vcs[] = { "/dev/vc/%d", "/dev/tty%d", NULL }; |
0 | 251 int i, tty0_fd; |
252 | |
253 /* Try to query for a free virtual terminal */ | |
254 tty0_fd = -1; | |
255 for ( i=0; tty0[i] && (tty0_fd < 0); ++i ) { | |
256 tty0_fd = open(tty0[i], O_WRONLY, 0); | |
257 } | |
258 if ( tty0_fd < 0 ) { | |
259 tty0_fd = dup(0); /* Maybe stdin is a VT? */ | |
260 } | |
261 ioctl(tty0_fd, VT_OPENQRY, ¤t_vt); | |
262 close(tty0_fd); | |
263 if ( (geteuid() == 0) && (current_vt > 0) ) { | |
264 for ( i=0; vcs[i] && (keyboard_fd < 0); ++i ) { | |
265 char vtpath[12]; | |
266 | |
1338
604d73db6802
Removed uses of stdlib.h and string.h
Sam Lantinga <slouken@libsdl.org>
parents:
1336
diff
changeset
|
267 SDL_snprintf(vtpath, SDL_arraysize(vtpath), vcs[i], current_vt); |
0 | 268 keyboard_fd = open(vtpath, O_RDWR, 0); |
269 #ifdef DEBUG_KEYBOARD | |
270 fprintf(stderr, "vtpath = %s, fd = %d\n", | |
271 vtpath, keyboard_fd); | |
272 #endif /* DEBUG_KEYBOARD */ | |
273 | |
274 /* This needs to be our controlling tty | |
275 so that the kernel ioctl() calls work | |
276 */ | |
277 if ( keyboard_fd >= 0 ) { | |
278 tty0_fd = open("/dev/tty", O_RDWR, 0); | |
279 if ( tty0_fd >= 0 ) { | |
280 ioctl(tty0_fd, TIOCNOTTY, 0); | |
281 close(tty0_fd); | |
282 } | |
283 } | |
284 } | |
285 } | |
286 if ( keyboard_fd < 0 ) { | |
287 /* Last resort, maybe our tty is a usable VT */ | |
1778
e28233f37f8c
Fixed detection of current vt when not running as root.
Sam Lantinga <slouken@libsdl.org>
parents:
1776
diff
changeset
|
288 struct vt_stat vtstate; |
e28233f37f8c
Fixed detection of current vt when not running as root.
Sam Lantinga <slouken@libsdl.org>
parents:
1776
diff
changeset
|
289 |
0 | 290 keyboard_fd = open("/dev/tty", O_RDWR); |
1778
e28233f37f8c
Fixed detection of current vt when not running as root.
Sam Lantinga <slouken@libsdl.org>
parents:
1776
diff
changeset
|
291 |
e28233f37f8c
Fixed detection of current vt when not running as root.
Sam Lantinga <slouken@libsdl.org>
parents:
1776
diff
changeset
|
292 if ( ioctl(keyboard_fd, VT_GETSTATE, &vtstate) == 0 ) { |
e28233f37f8c
Fixed detection of current vt when not running as root.
Sam Lantinga <slouken@libsdl.org>
parents:
1776
diff
changeset
|
293 current_vt = vtstate.v_active; |
e28233f37f8c
Fixed detection of current vt when not running as root.
Sam Lantinga <slouken@libsdl.org>
parents:
1776
diff
changeset
|
294 } else { |
e28233f37f8c
Fixed detection of current vt when not running as root.
Sam Lantinga <slouken@libsdl.org>
parents:
1776
diff
changeset
|
295 current_vt = 0; |
e28233f37f8c
Fixed detection of current vt when not running as root.
Sam Lantinga <slouken@libsdl.org>
parents:
1776
diff
changeset
|
296 } |
0 | 297 } |
298 #ifdef DEBUG_KEYBOARD | |
299 fprintf(stderr, "Current VT: %d\n", current_vt); | |
300 #endif | |
301 saved_kbd_mode = -1; | |
302 | |
303 /* Make sure that our input is a console terminal */ | |
304 { int dummy; | |
305 if ( ioctl(keyboard_fd, KDGKBMODE, &dummy) < 0 ) { | |
306 close(keyboard_fd); | |
307 keyboard_fd = -1; | |
308 SDL_SetError("Unable to open a console terminal"); | |
309 } | |
310 } | |
311 | |
312 /* Set up keymap */ | |
313 FB_vgainitkeymaps(keyboard_fd); | |
314 } | |
315 return(keyboard_fd); | |
316 } | |
317 | |
318 static enum { | |
319 MOUSE_NONE = -1, | |
109
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
320 MOUSE_MSC, /* Note: GPM uses the MSC protocol */ |
0 | 321 MOUSE_PS2, |
322 MOUSE_IMPS2, | |
323 MOUSE_MS, | |
324 MOUSE_BM, | |
325 MOUSE_ELO, | |
1201
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
326 MOUSE_TSLIB, |
0 | 327 NUM_MOUSE_DRVS |
328 } mouse_drv = MOUSE_NONE; | |
329 | |
330 void FB_CloseMouse(_THIS) | |
331 { | |
1361
19418e4422cb
New configure-based build system. Still work in progress, but much improved
Sam Lantinga <slouken@libsdl.org>
parents:
1359
diff
changeset
|
332 #if SDL_INPUT_TSLIB |
1201
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
333 if (ts_dev != NULL) { |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
334 ts_close(ts_dev); |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
335 ts_dev = NULL; |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
336 mouse_fd = -1; |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
337 } |
1361
19418e4422cb
New configure-based build system. Still work in progress, but much improved
Sam Lantinga <slouken@libsdl.org>
parents:
1359
diff
changeset
|
338 #endif /* SDL_INPUT_TSLIB */ |
0 | 339 if ( mouse_fd > 0 ) { |
340 close(mouse_fd); | |
341 } | |
342 mouse_fd = -1; | |
343 } | |
344 | |
345 /* Returns processes listed in /proc with the desired name */ | |
346 static int find_pid(DIR *proc, const char *wanted_name) | |
347 { | |
348 struct dirent *entry; | |
349 int pid; | |
350 | |
351 /* First scan proc for the gpm process */ | |
352 pid = 0; | |
353 while ( (pid == 0) && ((entry=readdir(proc)) != NULL) ) { | |
354 if ( isdigit(entry->d_name[0]) ) { | |
355 FILE *status; | |
356 char path[PATH_MAX]; | |
357 char name[PATH_MAX]; | |
358 | |
1338
604d73db6802
Removed uses of stdlib.h and string.h
Sam Lantinga <slouken@libsdl.org>
parents:
1336
diff
changeset
|
359 SDL_snprintf(path, SDL_arraysize(path), "/proc/%s/status", entry->d_name); |
0 | 360 status=fopen(path, "r"); |
361 if ( status ) { | |
362 name[0] = '\0'; | |
363 fscanf(status, "Name: %s", name); | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1323
diff
changeset
|
364 if ( SDL_strcmp(name, wanted_name) == 0 ) { |
1341
d02b552e5304
Configure dynamically generates SDL_config.h
Sam Lantinga <slouken@libsdl.org>
parents:
1338
diff
changeset
|
365 pid = SDL_atoi(entry->d_name); |
0 | 366 } |
367 fclose(status); | |
368 } | |
369 } | |
370 } | |
371 return pid; | |
372 } | |
373 | |
374 /* Returns true if /dev/gpmdata is being written to by gpm */ | |
1772 | 375 static int gpm_available(char *proto, size_t protolen) |
0 | 376 { |
377 int available; | |
378 DIR *proc; | |
379 int pid; | |
380 int cmdline, len, arglen; | |
381 char path[PATH_MAX]; | |
382 char args[PATH_MAX], *arg; | |
383 | |
384 /* Don't bother looking if the fifo isn't there */ | |
1772 | 385 #ifdef DEBUG_MOUSE |
386 fprintf(stderr,"testing gpm\n"); | |
387 #endif | |
0 | 388 if ( access(GPM_NODE_FIFO, F_OK) < 0 ) { |
389 return(0); | |
390 } | |
391 | |
392 available = 0; | |
393 proc = opendir("/proc"); | |
394 if ( proc ) { | |
1772 | 395 char raw_proto[10] = { '\0' }; |
396 char repeat_proto[10] = { '\0' }; | |
397 while ( !available && (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
|
398 SDL_snprintf(path, SDL_arraysize(path), "/proc/%d/cmdline", pid); |
0 | 399 cmdline = open(path, O_RDONLY, 0); |
400 if ( cmdline >= 0 ) { | |
401 len = read(cmdline, args, sizeof(args)); | |
402 arg = args; | |
403 while ( len > 0 ) { | |
1772 | 404 arglen = SDL_strlen(arg)+1; |
405 #ifdef DEBUG_MOUSE | |
406 fprintf(stderr,"gpm arg %s len %d\n",arg,arglen); | |
407 #endif | |
408 if ( SDL_strcmp(arg, "-t") == 0) { | |
409 /* protocol string, keep it for later */ | |
410 char *t, *s; | |
411 t = arg + arglen; | |
412 s = SDL_strchr(t, ' '); | |
413 if (s) *s = 0; | |
1776
ed39aa7383ea
SDL_strncpy doesn't exist
Sam Lantinga <slouken@libsdl.org>
parents:
1772
diff
changeset
|
414 SDL_strlcpy(raw_proto, t, SDL_arraysize(raw_proto)); |
1772 | 415 if (s) *s = ' '; |
416 } | |
417 if ( SDL_strncmp(arg, "-R", 2) == 0 ) { | |
418 char *t, *s; | |
0 | 419 available = 1; |
1772 | 420 t = arg + 2; |
421 s = SDL_strchr(t, ' '); | |
422 if (s) *s = 0; | |
1776
ed39aa7383ea
SDL_strncpy doesn't exist
Sam Lantinga <slouken@libsdl.org>
parents:
1772
diff
changeset
|
423 SDL_strlcpy(repeat_proto, t, SDL_arraysize(repeat_proto)); |
1772 | 424 if (s) *s = ' '; |
0 | 425 } |
426 len -= arglen; | |
427 arg += arglen; | |
428 } | |
429 close(cmdline); | |
430 } | |
431 } | |
432 closedir(proc); | |
1772 | 433 |
434 if ( available ) { | |
435 if ( SDL_strcmp(repeat_proto, "raw") == 0 ) { | |
436 SDL_strlcpy(proto, raw_proto, protolen); | |
437 } else if ( *repeat_proto ) { | |
438 SDL_strlcpy(proto, repeat_proto, protolen); | |
439 } else { | |
440 SDL_strlcpy(proto, "msc", protolen); | |
441 } | |
442 } | |
0 | 443 } |
444 return available; | |
445 } | |
446 | |
59 | 447 |
448 /* rcg06112001 Set up IMPS/2 mode, if possible. This gives | |
449 * us access to the mousewheel, etc. Returns zero if | |
450 * writes to device failed, but you still need to query the | |
451 * device to see which mode it's actually in. | |
452 */ | |
453 static int set_imps2_mode(int fd) | |
454 { | |
455 /* If you wanted to control the mouse mode (and we do :) ) ... | |
456 Set IMPS/2 protocol: | |
457 {0xf3,200,0xf3,100,0xf3,80} | |
458 Reset mouse device: | |
459 {0xFF} | |
460 */ | |
461 Uint8 set_imps2[] = {0xf3, 200, 0xf3, 100, 0xf3, 80}; | |
1780 | 462 /*Uint8 reset = 0xff;*/ |
59 | 463 fd_set fdset; |
464 struct timeval tv; | |
465 int retval = 0; | |
466 | |
467 if ( write(fd, &set_imps2, sizeof(set_imps2)) == sizeof(set_imps2) ) { | |
1584 | 468 /* Don't reset it, that'll clear IMPS/2 mode on some mice |
59 | 469 if (write(fd, &reset, sizeof (reset)) == sizeof (reset) ) { |
470 retval = 1; | |
471 } | |
1584 | 472 */ |
59 | 473 } |
474 | |
475 /* Get rid of any chatter from the above */ | |
476 FD_ZERO(&fdset); | |
477 FD_SET(fd, &fdset); | |
478 tv.tv_sec = 0; | |
479 tv.tv_usec = 0; | |
480 while ( select(fd+1, &fdset, 0, 0, &tv) > 0 ) { | |
481 char temp[32]; | |
482 read(fd, temp, sizeof(temp)); | |
483 } | |
484 | |
485 return retval; | |
486 } | |
487 | |
488 | |
0 | 489 /* Returns true if the mouse uses the IMPS/2 protocol */ |
490 static int detect_imps2(int fd) | |
491 { | |
492 int imps2; | |
493 | |
494 imps2 = 0; | |
59 | 495 |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1323
diff
changeset
|
496 if ( SDL_getenv("SDL_MOUSEDEV_IMPS2") ) { |
0 | 497 imps2 = 1; |
498 } | |
499 if ( ! imps2 ) { | |
59 | 500 Uint8 query_ps2 = 0xF2; |
0 | 501 fd_set fdset; |
502 struct timeval tv; | |
503 | |
504 /* Get rid of any mouse motion noise */ | |
505 FD_ZERO(&fdset); | |
506 FD_SET(fd, &fdset); | |
507 tv.tv_sec = 0; | |
508 tv.tv_usec = 0; | |
509 while ( select(fd+1, &fdset, 0, 0, &tv) > 0 ) { | |
510 char temp[32]; | |
511 read(fd, temp, sizeof(temp)); | |
512 } | |
513 | |
59 | 514 /* Query for the type of mouse protocol */ |
515 if ( write(fd, &query_ps2, sizeof (query_ps2)) == sizeof (query_ps2)) { | |
516 Uint8 ch = 0; | |
0 | 517 |
518 /* Get the mouse protocol response */ | |
519 do { | |
520 FD_ZERO(&fdset); | |
521 FD_SET(fd, &fdset); | |
522 tv.tv_sec = 1; | |
523 tv.tv_usec = 0; | |
524 if ( select(fd+1, &fdset, 0, 0, &tv) < 1 ) { | |
525 break; | |
526 } | |
59 | 527 } while ( (read(fd, &ch, sizeof (ch)) == sizeof (ch)) && |
0 | 528 ((ch == 0xFA) || (ch == 0xAA)) ); |
529 | |
530 /* Experimental values (Logitech wheelmouse) */ | |
531 #ifdef DEBUG_MOUSE | |
532 fprintf(stderr, "Last mouse mode: 0x%x\n", ch); | |
533 #endif | |
104
a746656b7599
Detect more types of IMPS/2 mouse
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
534 if ( (ch == 3) || (ch == 4) ) { |
0 | 535 imps2 = 1; |
536 } | |
537 } | |
538 } | |
539 return imps2; | |
540 } | |
541 | |
542 int FB_OpenMouse(_THIS) | |
543 { | |
69
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
544 int i; |
0 | 545 const char *mousedev; |
546 const char *mousedrv; | |
547 | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1323
diff
changeset
|
548 mousedrv = SDL_getenv("SDL_MOUSEDRV"); |
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1323
diff
changeset
|
549 mousedev = SDL_getenv("SDL_MOUSEDEV"); |
0 | 550 mouse_fd = -1; |
551 | |
1361
19418e4422cb
New configure-based build system. Still work in progress, but much improved
Sam Lantinga <slouken@libsdl.org>
parents:
1359
diff
changeset
|
552 #if SDL_INPUT_TSLIB |
1585
980d2a0dc2a3
Date: Tue, 4 Mar 2003 15:05:31 -0800
Sam Lantinga <slouken@libsdl.org>
parents:
1584
diff
changeset
|
553 if ( mousedrv && (SDL_strcmp(mousedrv, "TSLIB") == 0) ) { |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1323
diff
changeset
|
554 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
|
555 if (mousedev != NULL) { |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
556 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
|
557 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
|
558 #ifdef DEBUG_MOUSE |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
559 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
|
560 #endif |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
561 mouse_drv = MOUSE_TSLIB; |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
562 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
|
563 return mouse_fd; |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
564 } |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
565 } |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
566 mouse_drv = MOUSE_NONE; |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
567 return mouse_fd; |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
568 } |
1361
19418e4422cb
New configure-based build system. Still work in progress, but much improved
Sam Lantinga <slouken@libsdl.org>
parents:
1359
diff
changeset
|
569 #endif /* SDL_INPUT_TSLIB */ |
1201
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
570 |
0 | 571 /* ELO TOUCHSCREEN SUPPORT */ |
572 | |
1585
980d2a0dc2a3
Date: Tue, 4 Mar 2003 15:05:31 -0800
Sam Lantinga <slouken@libsdl.org>
parents:
1584
diff
changeset
|
573 if ( mousedrv && (SDL_strcmp(mousedrv, "ELO") == 0) ) { |
0 | 574 mouse_fd = open(mousedev, O_RDWR); |
575 if ( mouse_fd >= 0 ) { | |
576 if(eloInitController(mouse_fd)) { | |
577 #ifdef DEBUG_MOUSE | |
578 fprintf(stderr, "Using ELO touchscreen\n"); | |
579 #endif | |
580 mouse_drv = MOUSE_ELO; | |
581 } | |
582 | |
583 } | |
584 else if ( mouse_fd < 0 ) { | |
585 mouse_drv = MOUSE_NONE; | |
586 } | |
587 | |
588 return(mouse_fd); | |
589 } | |
590 | |
591 /* STD MICE */ | |
592 | |
593 if ( mousedev == NULL ) { | |
69
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
594 /* FIXME someday... allow multiple mice in this driver */ |
1584 | 595 static const char *ps2mice[] = { |
69
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
596 "/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
|
597 }; |
0 | 598 /* First try to use GPM in repeater mode */ |
599 if ( mouse_fd < 0 ) { | |
1772 | 600 char proto[10]; |
601 if ( gpm_available(proto, SDL_arraysize(proto)) ) { | |
0 | 602 mouse_fd = open(GPM_NODE_FIFO, O_RDONLY, 0); |
603 if ( mouse_fd >= 0 ) { | |
1772 | 604 if ( SDL_strcmp(proto, "msc") == 0 ) { |
605 mouse_drv = MOUSE_MSC; | |
606 } else if ( SDL_strcmp(proto, "ps2") == 0 ) { | |
607 mouse_drv = MOUSE_PS2; | |
608 } else if ( SDL_strcmp(proto, "imps2") == 0 ) { | |
609 mouse_drv = MOUSE_IMPS2; | |
610 } else if ( SDL_strcmp(proto, "ms") == 0 || | |
611 SDL_strcmp(proto, "bare") == 0 ) { | |
612 mouse_drv = MOUSE_MS; | |
613 } else if ( SDL_strcmp(proto, "bm") == 0 ) { | |
614 mouse_drv = MOUSE_BM; | |
615 } else { | |
616 /* Unknown protocol... */ | |
0 | 617 #ifdef DEBUG_MOUSE |
1772 | 618 fprintf(stderr, "GPM mouse using unknown protocol = %s\n", proto); |
0 | 619 #endif |
1772 | 620 close(mouse_fd); |
621 mouse_fd = -1; | |
622 } | |
0 | 623 } |
1772 | 624 #ifdef DEBUG_MOUSE |
625 if ( mouse_fd >= 0 ) { | |
626 fprintf(stderr, "Using GPM mouse, protocol = %s\n", proto); | |
627 } | |
628 #endif /* DEBUG_MOUSE */ | |
0 | 629 } |
630 } | |
69
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
631 /* 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
|
632 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
|
633 mouse_fd = open(ps2mice[i], O_RDWR, 0); |
59 | 634 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
|
635 mouse_fd = open(ps2mice[i], O_RDONLY, 0); |
59 | 636 } |
637 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
|
638 /* rcg06112001 Attempt to set IMPS/2 mode */ |
1584 | 639 set_imps2_mode(mouse_fd); |
69
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
640 if (detect_imps2(mouse_fd)) { |
0 | 641 #ifdef DEBUG_MOUSE |
69
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
642 fprintf(stderr, "Using IMPS2 mouse\n"); |
0 | 643 #endif |
644 mouse_drv = MOUSE_IMPS2; | |
645 } else { | |
646 #ifdef DEBUG_MOUSE | |
69
280ff3af2ecc
Added /dev/usbmouse to the list of mice to check
Sam Lantinga <slouken@lokigames.com>
parents:
60
diff
changeset
|
647 fprintf(stderr, "Using PS2 mouse\n"); |
0 | 648 #endif |
649 mouse_drv = MOUSE_PS2; | |
650 } | |
651 } | |
652 } | |
653 /* Next try to use a PPC ADB port mouse */ | |
654 if ( mouse_fd < 0 ) { | |
655 mouse_fd = open("/dev/adbmouse", O_RDONLY, 0); | |
656 if ( mouse_fd >= 0 ) { | |
657 #ifdef DEBUG_MOUSE | |
658 fprintf(stderr, "Using ADB mouse\n"); | |
659 #endif | |
660 mouse_drv = MOUSE_BM; | |
661 } | |
662 } | |
663 } | |
664 /* Default to a serial Microsoft mouse */ | |
665 if ( mouse_fd < 0 ) { | |
666 if ( mousedev == NULL ) { | |
667 mousedev = "/dev/mouse"; | |
668 } | |
669 mouse_fd = open(mousedev, O_RDONLY, 0); | |
670 if ( mouse_fd >= 0 ) { | |
671 struct termios mouse_termios; | |
672 | |
673 /* Set the sampling speed to 1200 baud */ | |
674 tcgetattr(mouse_fd, &mouse_termios); | |
675 mouse_termios.c_iflag = IGNBRK | IGNPAR; | |
676 mouse_termios.c_oflag = 0; | |
677 mouse_termios.c_lflag = 0; | |
678 mouse_termios.c_line = 0; | |
679 mouse_termios.c_cc[VTIME] = 0; | |
680 mouse_termios.c_cc[VMIN] = 1; | |
681 mouse_termios.c_cflag = CREAD | CLOCAL | HUPCL; | |
682 mouse_termios.c_cflag |= CS8; | |
683 mouse_termios.c_cflag |= B1200; | |
684 tcsetattr(mouse_fd, TCSAFLUSH, &mouse_termios); | |
1585
980d2a0dc2a3
Date: Tue, 4 Mar 2003 15:05:31 -0800
Sam Lantinga <slouken@libsdl.org>
parents:
1584
diff
changeset
|
685 if ( mousedrv && (SDL_strcmp(mousedrv, "PS2") == 0) ) { |
0 | 686 #ifdef DEBUG_MOUSE |
1585
980d2a0dc2a3
Date: Tue, 4 Mar 2003 15:05:31 -0800
Sam Lantinga <slouken@libsdl.org>
parents:
1584
diff
changeset
|
687 fprintf(stderr, "Using (user specified) PS2 mouse on %s\n", mousedev); |
0 | 688 #endif |
1585
980d2a0dc2a3
Date: Tue, 4 Mar 2003 15:05:31 -0800
Sam Lantinga <slouken@libsdl.org>
parents:
1584
diff
changeset
|
689 mouse_drv = MOUSE_PS2; |
980d2a0dc2a3
Date: Tue, 4 Mar 2003 15:05:31 -0800
Sam Lantinga <slouken@libsdl.org>
parents:
1584
diff
changeset
|
690 } else { |
980d2a0dc2a3
Date: Tue, 4 Mar 2003 15:05:31 -0800
Sam Lantinga <slouken@libsdl.org>
parents:
1584
diff
changeset
|
691 #ifdef DEBUG_MOUSE |
980d2a0dc2a3
Date: Tue, 4 Mar 2003 15:05:31 -0800
Sam Lantinga <slouken@libsdl.org>
parents:
1584
diff
changeset
|
692 fprintf(stderr, "Using (default) MS mouse on %s\n", mousedev); |
980d2a0dc2a3
Date: Tue, 4 Mar 2003 15:05:31 -0800
Sam Lantinga <slouken@libsdl.org>
parents:
1584
diff
changeset
|
693 #endif |
980d2a0dc2a3
Date: Tue, 4 Mar 2003 15:05:31 -0800
Sam Lantinga <slouken@libsdl.org>
parents:
1584
diff
changeset
|
694 mouse_drv = MOUSE_MS; |
980d2a0dc2a3
Date: Tue, 4 Mar 2003 15:05:31 -0800
Sam Lantinga <slouken@libsdl.org>
parents:
1584
diff
changeset
|
695 } |
0 | 696 } |
697 } | |
698 if ( mouse_fd < 0 ) { | |
699 mouse_drv = MOUSE_NONE; | |
700 } | |
701 return(mouse_fd); | |
702 } | |
703 | |
704 static int posted = 0; | |
705 | |
706 void FB_vgamousecallback(int button, int relative, int dx, int dy) | |
707 { | |
708 int button_1, button_3; | |
709 int button_state; | |
710 int state_changed; | |
711 int i; | |
712 Uint8 state; | |
713 | |
714 if ( dx || dy ) { | |
715 posted += SDL_PrivateMouseMotion(0, relative, dx, dy); | |
716 } | |
717 | |
718 /* Swap button 1 and 3 */ | |
719 button_1 = (button & 0x04) >> 2; | |
720 button_3 = (button & 0x01) << 2; | |
721 button &= ~0x05; | |
722 button |= (button_1|button_3); | |
723 | |
724 /* See what changed */ | |
725 button_state = SDL_GetMouseState(NULL, NULL); | |
726 state_changed = button_state ^ button; | |
727 for ( i=0; i<8; ++i ) { | |
728 if ( state_changed & (1<<i) ) { | |
729 if ( button & (1<<i) ) { | |
730 state = SDL_PRESSED; | |
731 } else { | |
732 state = SDL_RELEASED; | |
733 } | |
734 posted += SDL_PrivateMouseButton(state, i+1, 0, 0); | |
735 } | |
736 } | |
737 } | |
738 | |
1201
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
739 /* Handle input from tslib */ |
1361
19418e4422cb
New configure-based build system. Still work in progress, but much improved
Sam Lantinga <slouken@libsdl.org>
parents:
1359
diff
changeset
|
740 #if SDL_INPUT_TSLIB |
1201
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
741 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
|
742 { |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
743 struct ts_sample sample; |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
744 int button; |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
745 |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
746 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
|
747 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
|
748 button <<= 2; /* must report it as button 3 */ |
1323 | 749 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
|
750 } |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
751 return; |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
752 } |
1361
19418e4422cb
New configure-based build system. Still work in progress, but much improved
Sam Lantinga <slouken@libsdl.org>
parents:
1359
diff
changeset
|
753 #endif /* SDL_INPUT_TSLIB */ |
1201
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
754 |
109
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
755 /* For now, use MSC, PS/2, and MS protocols |
0 | 756 Driver adapted from the SVGAlib mouse driver code (taken from gpm, etc.) |
757 */ | |
758 static void handle_mouse(_THIS) | |
759 { | |
760 static int start = 0; | |
761 static unsigned char mousebuf[BUFSIZ]; | |
762 static int relative = 1; | |
763 | |
764 int i, nread; | |
765 int button = 0; | |
766 int dx = 0, dy = 0; | |
767 int packetsize = 0; | |
4
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
768 int realx, realy; |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
769 |
0 | 770 /* Figure out the mouse packet size */ |
771 switch (mouse_drv) { | |
772 case MOUSE_NONE: | |
773 /* Ack! */ | |
774 read(mouse_fd, mousebuf, BUFSIZ); | |
775 return; | |
109
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
776 case MOUSE_MSC: |
0 | 777 packetsize = 5; |
778 break; | |
779 case MOUSE_IMPS2: | |
780 packetsize = 4; | |
781 break; | |
782 case MOUSE_PS2: | |
783 case MOUSE_MS: | |
784 case MOUSE_BM: | |
785 packetsize = 3; | |
786 break; | |
787 case MOUSE_ELO: | |
1323 | 788 /* try to read the next packet */ |
789 if(eloReadPosition(this, mouse_fd, &dx, &dy, &button, &realx, &realy)) { | |
790 button = (button & 0x01) << 2; | |
791 FB_vgamousecallback(button, 0, dx, dy); | |
792 } | |
793 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
|
794 case MOUSE_TSLIB: |
1361
19418e4422cb
New configure-based build system. Still work in progress, but much improved
Sam Lantinga <slouken@libsdl.org>
parents:
1359
diff
changeset
|
795 #if SDL_INPUT_TSLIB |
1201
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
796 handle_tslib(this); |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
797 #endif |
718d00094f82
Date: Sat, 10 Dec 2005 18:29:41 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
1022
diff
changeset
|
798 return; /* nothing left to do */ |
1323 | 799 default: |
0 | 800 /* Uh oh.. */ |
801 packetsize = 0; | |
802 break; | |
803 } | |
804 | |
4
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
805 /* 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
|
806 if (mouse_drv == MOUSE_ELO) { |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
807 |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
808 } |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
809 |
0 | 810 /* Read as many packets as possible */ |
811 nread = read(mouse_fd, &mousebuf[start], BUFSIZ-start); | |
812 if ( nread < 0 ) { | |
813 return; | |
814 } | |
815 nread += start; | |
816 #ifdef DEBUG_MOUSE | |
817 fprintf(stderr, "Read %d bytes from mouse, start = %d\n", nread, start); | |
818 #endif | |
819 for ( i=0; i<(nread-(packetsize-1)); i += packetsize ) { | |
820 switch (mouse_drv) { | |
821 case MOUSE_NONE: | |
822 break; | |
109
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
823 case MOUSE_MSC: |
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
824 /* MSC protocol has 0x80 in high byte */ |
0 | 825 if ( (mousebuf[i] & 0xF8) != 0x80 ) { |
826 /* Go to next byte */ | |
827 i -= (packetsize-1); | |
828 continue; | |
829 } | |
830 /* Get current mouse state */ | |
831 button = (~mousebuf[i]) & 0x07; | |
832 dx = (signed char)(mousebuf[i+1]) + | |
833 (signed char)(mousebuf[i+3]); | |
834 dy = -((signed char)(mousebuf[i+2]) + | |
835 (signed char)(mousebuf[i+4])); | |
836 break; | |
837 case MOUSE_PS2: | |
838 /* PS/2 protocol has nothing in high byte */ | |
839 if ( (mousebuf[i] & 0xC0) != 0 ) { | |
840 /* Go to next byte */ | |
841 i -= (packetsize-1); | |
842 continue; | |
843 } | |
844 /* Get current mouse state */ | |
845 button = (mousebuf[i] & 0x04) >> 1 | /*Middle*/ | |
846 (mousebuf[i] & 0x02) >> 1 | /*Right*/ | |
847 (mousebuf[i] & 0x01) << 2; /*Left*/ | |
848 dx = (mousebuf[i] & 0x10) ? | |
849 mousebuf[i+1] - 256 : mousebuf[i+1]; | |
850 dy = (mousebuf[i] & 0x20) ? | |
851 -(mousebuf[i+2] - 256) : -mousebuf[i+2]; | |
852 break; | |
853 case MOUSE_IMPS2: | |
854 /* Get current mouse state */ | |
855 button = (mousebuf[i] & 0x04) >> 1 | /*Middle*/ | |
856 (mousebuf[i] & 0x02) >> 1 | /*Right*/ | |
857 (mousebuf[i] & 0x01) << 2 | /*Left*/ | |
858 (mousebuf[i] & 0x40) >> 3 | /* 4 */ | |
859 (mousebuf[i] & 0x80) >> 3; /* 5 */ | |
860 dx = (mousebuf[i] & 0x10) ? | |
861 mousebuf[i+1] - 256 : mousebuf[i+1]; | |
862 dy = (mousebuf[i] & 0x20) ? | |
863 -(mousebuf[i+2] - 256) : -mousebuf[i+2]; | |
864 switch (mousebuf[i+3]&0x0F) { | |
865 case 0x0E: /* DX = +1 */ | |
866 case 0x02: /* DX = -1 */ | |
867 break; | |
868 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
|
869 FB_vgamousecallback(button | (1<<3), |
2604a7be65af
Added button-up with mouse-wheel on framebuffer console
Sam Lantinga <slouken@libsdl.org>
parents:
109
diff
changeset
|
870 1, 0, 0); |
0 | 871 break; |
872 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
|
873 FB_vgamousecallback(button | (1<<4), |
2604a7be65af
Added button-up with mouse-wheel on framebuffer console
Sam Lantinga <slouken@libsdl.org>
parents:
109
diff
changeset
|
874 1, 0, 0); |
0 | 875 break; |
876 } | |
877 break; | |
878 case MOUSE_MS: | |
879 /* Microsoft protocol has 0x40 in high byte */ | |
880 if ( (mousebuf[i] & 0x40) != 0x40 ) { | |
881 /* Go to next byte */ | |
882 i -= (packetsize-1); | |
883 continue; | |
884 } | |
885 /* Get current mouse state */ | |
886 button = ((mousebuf[i] & 0x20) >> 3) | | |
887 ((mousebuf[i] & 0x10) >> 4); | |
888 dx = (signed char)(((mousebuf[i] & 0x03) << 6) | | |
889 (mousebuf[i + 1] & 0x3F)); | |
890 dy = (signed char)(((mousebuf[i] & 0x0C) << 4) | | |
891 (mousebuf[i + 2] & 0x3F)); | |
892 break; | |
893 case MOUSE_BM: | |
894 /* BusMouse protocol has 0xF8 in high byte */ | |
895 if ( (mousebuf[i] & 0xF8) != 0x80 ) { | |
896 /* Go to next byte */ | |
897 i -= (packetsize-1); | |
898 continue; | |
899 } | |
900 /* Get current mouse state */ | |
901 button = (~mousebuf[i]) & 0x07; | |
902 dx = (signed char)mousebuf[i+1]; | |
903 dy = -(signed char)mousebuf[i+2]; | |
904 break; | |
1323 | 905 default: |
0 | 906 /* Uh oh.. */ |
907 dx = 0; | |
908 dy = 0; | |
909 break; | |
910 } | |
911 FB_vgamousecallback(button, relative, dx, dy); | |
912 } | |
913 if ( i < nread ) { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1323
diff
changeset
|
914 SDL_memcpy(mousebuf, &mousebuf[i], (nread-i)); |
0 | 915 start = (nread-i); |
916 } else { | |
917 start = 0; | |
918 } | |
919 return; | |
920 } | |
921 | |
1780 | 922 /* Handle switching to another VC, returns when our VC is back */ |
923 static void switch_vt_prep(_THIS) | |
924 { | |
925 SDL_Surface *screen = SDL_VideoSurface; | |
926 | |
927 SDL_PrivateAppActive(0, (SDL_APPACTIVE|SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS)); | |
928 | |
929 /* Save the contents of the screen, and go to text mode */ | |
930 wait_idle(this); | |
931 screen_arealen = ((screen->h + (2*this->offset_y)) * screen->pitch); | |
932 screen_contents = (Uint8 *)SDL_malloc(screen_arealen); | |
933 if ( screen_contents ) { | |
934 SDL_memcpy(screen_contents, screen->pixels, screen_arealen); | |
935 } | |
936 FB_SavePaletteTo(this, 256, screen_palette); | |
937 ioctl(console_fd, FBIOGET_VSCREENINFO, &screen_vinfo); | |
938 ioctl(keyboard_fd, KDSETMODE, KD_TEXT); | |
939 ioctl(keyboard_fd, VT_UNLOCKSWITCH, 1); | |
940 } | |
941 static void switch_vt_done(_THIS) | |
942 { | |
943 SDL_Surface *screen = SDL_VideoSurface; | |
944 | |
945 /* Restore graphics mode and the contents of the screen */ | |
946 ioctl(keyboard_fd, VT_LOCKSWITCH, 1); | |
947 ioctl(keyboard_fd, KDSETMODE, KD_GRAPHICS); | |
948 ioctl(console_fd, FBIOPUT_VSCREENINFO, &screen_vinfo); | |
949 FB_RestorePaletteFrom(this, 256, screen_palette); | |
950 if ( screen_contents ) { | |
951 SDL_memcpy(screen->pixels, screen_contents, screen_arealen); | |
952 SDL_free(screen_contents); | |
953 screen_contents = NULL; | |
954 } | |
955 | |
1781
d8030f368b84
Get updates to the shadow surface while switched away
Sam Lantinga <slouken@libsdl.org>
parents:
1780
diff
changeset
|
956 /* Get updates to the shadow surface while switched away */ |
d8030f368b84
Get updates to the shadow surface while switched away
Sam Lantinga <slouken@libsdl.org>
parents:
1780
diff
changeset
|
957 if ( SDL_ShadowSurface ) { |
d8030f368b84
Get updates to the shadow surface while switched away
Sam Lantinga <slouken@libsdl.org>
parents:
1780
diff
changeset
|
958 SDL_UpdateRect(SDL_ShadowSurface, 0, 0, 0, 0); |
d8030f368b84
Get updates to the shadow surface while switched away
Sam Lantinga <slouken@libsdl.org>
parents:
1780
diff
changeset
|
959 } |
d8030f368b84
Get updates to the shadow surface while switched away
Sam Lantinga <slouken@libsdl.org>
parents:
1780
diff
changeset
|
960 |
1780 | 961 SDL_PrivateAppActive(1, (SDL_APPACTIVE|SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS)); |
962 } | |
0 | 963 static void switch_vt(_THIS, unsigned short which) |
964 { | |
965 struct vt_stat vtstate; | |
966 | |
967 /* Figure out whether or not we're switching to a new console */ | |
968 if ( (ioctl(keyboard_fd, VT_GETSTATE, &vtstate) < 0) || | |
969 (which == vtstate.v_active) ) { | |
970 return; | |
971 } | |
972 | |
973 /* New console, switch to it */ | |
1780 | 974 SDL_mutexP(hw_lock); |
975 switch_vt_prep(this); | |
0 | 976 if ( ioctl(keyboard_fd, VT_ACTIVATE, which) == 0 ) { |
977 ioctl(keyboard_fd, VT_WAITACTIVE, which); | |
1780 | 978 switched_away = 1; |
1585
980d2a0dc2a3
Date: Tue, 4 Mar 2003 15:05:31 -0800
Sam Lantinga <slouken@libsdl.org>
parents:
1584
diff
changeset
|
979 } else { |
1780 | 980 switch_vt_done(this); |
0 | 981 } |
982 SDL_mutexV(hw_lock); | |
983 } | |
984 | |
985 static void handle_keyboard(_THIS) | |
986 { | |
987 unsigned char keybuf[BUFSIZ]; | |
988 int i, nread; | |
989 int pressed; | |
990 int scancode; | |
991 SDL_keysym keysym; | |
992 | |
993 nread = read(keyboard_fd, keybuf, BUFSIZ); | |
994 for ( i=0; i<nread; ++i ) { | |
995 scancode = keybuf[i] & 0x7F; | |
996 if ( keybuf[i] & 0x80 ) { | |
997 pressed = SDL_RELEASED; | |
998 } else { | |
999 pressed = SDL_PRESSED; | |
1000 } | |
1001 TranslateKey(scancode, &keysym); | |
1582 | 1002 /* Handle Ctrl-Alt-FN for vt switch */ |
0 | 1003 switch (keysym.sym) { |
1004 case SDLK_F1: | |
1005 case SDLK_F2: | |
1006 case SDLK_F3: | |
1007 case SDLK_F4: | |
1008 case SDLK_F5: | |
1009 case SDLK_F6: | |
1010 case SDLK_F7: | |
1011 case SDLK_F8: | |
1012 case SDLK_F9: | |
1013 case SDLK_F10: | |
1014 case SDLK_F11: | |
1015 case SDLK_F12: | |
1582 | 1016 if ( (SDL_GetModState() & KMOD_CTRL) && |
1017 (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
|
1018 if ( pressed ) { |
5a9c36a45db1
Fixed switching away from the SDL at the framebuffer console
Sam Lantinga <slouken@lokigames.com>
parents:
104
diff
changeset
|
1019 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
|
1020 } |
0 | 1021 break; |
1022 } | |
1023 /* Fall through to normal processing */ | |
1024 default: | |
1025 posted += SDL_PrivateKeyboard(pressed, &keysym); | |
1026 break; | |
1027 } | |
1028 } | |
1029 } | |
1030 | |
1031 void FB_PumpEvents(_THIS) | |
1032 { | |
1033 fd_set fdset; | |
1034 int max_fd; | |
1035 static struct timeval zero; | |
1036 | |
1037 do { | |
1780 | 1038 if ( switched_away ) { |
1039 struct vt_stat vtstate; | |
1040 | |
1041 SDL_mutexP(hw_lock); | |
1042 if ( (ioctl(keyboard_fd, VT_GETSTATE, &vtstate) == 0) && | |
1043 vtstate.v_active == current_vt ) { | |
1044 switched_away = 0; | |
1045 switch_vt_done(this); | |
1046 } | |
1047 SDL_mutexV(hw_lock); | |
1048 } | |
1049 | |
0 | 1050 posted = 0; |
1051 | |
1052 FD_ZERO(&fdset); | |
1053 max_fd = 0; | |
1054 if ( keyboard_fd >= 0 ) { | |
1055 FD_SET(keyboard_fd, &fdset); | |
1056 if ( max_fd < keyboard_fd ) { | |
1057 max_fd = keyboard_fd; | |
1058 } | |
1059 } | |
1060 if ( mouse_fd >= 0 ) { | |
1061 FD_SET(mouse_fd, &fdset); | |
1062 if ( max_fd < mouse_fd ) { | |
1063 max_fd = mouse_fd; | |
1064 } | |
1065 } | |
1066 if ( select(max_fd+1, &fdset, NULL, NULL, &zero) > 0 ) { | |
1067 if ( keyboard_fd >= 0 ) { | |
1068 if ( FD_ISSET(keyboard_fd, &fdset) ) { | |
1069 handle_keyboard(this); | |
1070 } | |
1071 } | |
1072 if ( mouse_fd >= 0 ) { | |
1073 if ( FD_ISSET(mouse_fd, &fdset) ) { | |
1074 handle_mouse(this); | |
1075 } | |
1076 } | |
1077 } | |
1078 } while ( posted ); | |
1079 } | |
1080 | |
1081 void FB_InitOSKeymap(_THIS) | |
1082 { | |
1083 int i; | |
1084 | |
1085 /* Initialize the Linux key translation table */ | |
1086 | |
1087 /* First get the ascii keys and others not well handled */ | |
1379
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
1088 for (i=0; i<SDL_arraysize(keymap); ++i) { |
0 | 1089 switch(i) { |
1090 /* These aren't handled by the x86 kernel keymapping (?) */ | |
1091 case SCANCODE_PRINTSCREEN: | |
1092 keymap[i] = SDLK_PRINT; | |
1093 break; | |
1094 case SCANCODE_BREAK: | |
1095 keymap[i] = SDLK_BREAK; | |
1096 break; | |
1097 case SCANCODE_BREAK_ALTERNATIVE: | |
1098 keymap[i] = SDLK_PAUSE; | |
1099 break; | |
1100 case SCANCODE_LEFTSHIFT: | |
1101 keymap[i] = SDLK_LSHIFT; | |
1102 break; | |
1103 case SCANCODE_RIGHTSHIFT: | |
1104 keymap[i] = SDLK_RSHIFT; | |
1105 break; | |
1106 case SCANCODE_LEFTCONTROL: | |
1107 keymap[i] = SDLK_LCTRL; | |
1108 break; | |
1109 case SCANCODE_RIGHTCONTROL: | |
1110 keymap[i] = SDLK_RCTRL; | |
1111 break; | |
1112 case SCANCODE_RIGHTWIN: | |
1113 keymap[i] = SDLK_RSUPER; | |
1114 break; | |
1115 case SCANCODE_LEFTWIN: | |
1116 keymap[i] = SDLK_LSUPER; | |
1117 break; | |
1787 | 1118 case SCANCODE_LEFTALT: |
1119 keymap[i] = SDLK_LALT; | |
1120 break; | |
1121 case SCANCODE_RIGHTALT: | |
1122 keymap[i] = SDLK_RALT; | |
1123 break; | |
0 | 1124 case 127: |
1125 keymap[i] = SDLK_MENU; | |
1126 break; | |
1127 /* this should take care of all standard ascii keys */ | |
1128 default: | |
1129 keymap[i] = KVAL(vga_keymap[0][i]); | |
1130 break; | |
1131 } | |
1132 } | |
1379
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
1133 for (i=0; i<SDL_arraysize(keymap); ++i) { |
0 | 1134 switch(keymap_temp[i]) { |
1135 case K_F1: keymap[i] = SDLK_F1; break; | |
1136 case K_F2: keymap[i] = SDLK_F2; break; | |
1137 case K_F3: keymap[i] = SDLK_F3; break; | |
1138 case K_F4: keymap[i] = SDLK_F4; break; | |
1139 case K_F5: keymap[i] = SDLK_F5; break; | |
1140 case K_F6: keymap[i] = SDLK_F6; break; | |
1141 case K_F7: keymap[i] = SDLK_F7; break; | |
1142 case K_F8: keymap[i] = SDLK_F8; break; | |
1143 case K_F9: keymap[i] = SDLK_F9; break; | |
1144 case K_F10: keymap[i] = SDLK_F10; break; | |
1145 case K_F11: keymap[i] = SDLK_F11; break; | |
1146 case K_F12: keymap[i] = SDLK_F12; break; | |
1147 | |
1148 case K_DOWN: keymap[i] = SDLK_DOWN; break; | |
1149 case K_LEFT: keymap[i] = SDLK_LEFT; break; | |
1150 case K_RIGHT: keymap[i] = SDLK_RIGHT; break; | |
1151 case K_UP: keymap[i] = SDLK_UP; break; | |
1152 | |
1153 case K_P0: keymap[i] = SDLK_KP0; break; | |
1154 case K_P1: keymap[i] = SDLK_KP1; break; | |
1155 case K_P2: keymap[i] = SDLK_KP2; break; | |
1156 case K_P3: keymap[i] = SDLK_KP3; break; | |
1157 case K_P4: keymap[i] = SDLK_KP4; break; | |
1158 case K_P5: keymap[i] = SDLK_KP5; break; | |
1159 case K_P6: keymap[i] = SDLK_KP6; break; | |
1160 case K_P7: keymap[i] = SDLK_KP7; break; | |
1161 case K_P8: keymap[i] = SDLK_KP8; break; | |
1162 case K_P9: keymap[i] = SDLK_KP9; break; | |
1163 case K_PPLUS: keymap[i] = SDLK_KP_PLUS; break; | |
1164 case K_PMINUS: keymap[i] = SDLK_KP_MINUS; break; | |
1165 case K_PSTAR: keymap[i] = SDLK_KP_MULTIPLY; break; | |
1166 case K_PSLASH: keymap[i] = SDLK_KP_DIVIDE; break; | |
1167 case K_PENTER: keymap[i] = SDLK_KP_ENTER; break; | |
1168 case K_PDOT: keymap[i] = SDLK_KP_PERIOD; break; | |
1169 | |
1170 case K_SHIFT: if ( keymap[i] != SDLK_RSHIFT ) | |
1171 keymap[i] = SDLK_LSHIFT; | |
1172 break; | |
1173 case K_SHIFTL: keymap[i] = SDLK_LSHIFT; break; | |
1174 case K_SHIFTR: keymap[i] = SDLK_RSHIFT; break; | |
1175 case K_CTRL: if ( keymap[i] != SDLK_RCTRL ) | |
1176 keymap[i] = SDLK_LCTRL; | |
1177 break; | |
1178 case K_CTRLL: keymap[i] = SDLK_LCTRL; break; | |
1179 case K_CTRLR: keymap[i] = SDLK_RCTRL; break; | |
1180 case K_ALT: keymap[i] = SDLK_LALT; break; | |
1181 case K_ALTGR: keymap[i] = SDLK_RALT; break; | |
1182 | |
1183 case K_INSERT: keymap[i] = SDLK_INSERT; break; | |
1184 case K_REMOVE: keymap[i] = SDLK_DELETE; break; | |
1185 case K_PGUP: keymap[i] = SDLK_PAGEUP; break; | |
1186 case K_PGDN: keymap[i] = SDLK_PAGEDOWN; break; | |
1187 case K_FIND: keymap[i] = SDLK_HOME; break; | |
1188 case K_SELECT: keymap[i] = SDLK_END; break; | |
1189 | |
1190 case K_NUM: keymap[i] = SDLK_NUMLOCK; break; | |
1191 case K_CAPS: keymap[i] = SDLK_CAPSLOCK; break; | |
1192 | |
1193 case K_F13: keymap[i] = SDLK_PRINT; break; | |
1194 case K_HOLD: keymap[i] = SDLK_SCROLLOCK; break; | |
1195 case K_PAUSE: keymap[i] = SDLK_PAUSE; break; | |
1196 | |
1197 case 127: keymap[i] = SDLK_BACKSPACE; break; | |
1198 | |
1199 default: break; | |
1200 } | |
1201 } | |
1202 } | |
1203 | |
1204 static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym) | |
1205 { | |
1206 /* Set the keysym information */ | |
1207 keysym->scancode = scancode; | |
1208 keysym->sym = keymap[scancode]; | |
1209 keysym->mod = KMOD_NONE; | |
1210 | |
1211 /* If UNICODE is on, get the UNICODE value for the key */ | |
1212 keysym->unicode = 0; | |
1213 if ( SDL_TranslateUNICODE ) { | |
1214 int map; | |
1215 SDLMod modstate; | |
1216 | |
1217 modstate = SDL_GetModState(); | |
1218 map = 0; | |
1219 if ( modstate & KMOD_SHIFT ) { | |
1220 map |= (1<<KG_SHIFT); | |
1221 } | |
1222 if ( modstate & KMOD_CTRL ) { | |
1223 map |= (1<<KG_CTRL); | |
1224 } | |
1787 | 1225 if ( modstate & KMOD_LALT ) { |
0 | 1226 map |= (1<<KG_ALT); |
1227 } | |
1787 | 1228 if ( modstate & KMOD_RALT ) { |
0 | 1229 map |= (1<<KG_ALTGR); |
1230 } | |
1231 if ( KTYP(vga_keymap[map][scancode]) == KT_LETTER ) { | |
1232 if ( modstate & KMOD_CAPS ) { | |
1233 map ^= (1<<KG_SHIFT); | |
1234 } | |
1235 } | |
1236 if ( KTYP(vga_keymap[map][scancode]) == KT_PAD ) { | |
1237 if ( modstate & KMOD_NUM ) { | |
1238 keysym->unicode=KVAL(vga_keymap[map][scancode]); | |
1239 } | |
1240 } else { | |
1241 keysym->unicode = KVAL(vga_keymap[map][scancode]); | |
1242 } | |
1243 } | |
1244 return(keysym); | |
1245 } |