1 /*
2 in_svgalib.c
3
4 (description)
5
6 Copyright (C) 1996-1997 Id Software, Inc.
7 Copyright (C) 1999-2000 Marcus Sundberg [mackan@stacken.kth.se]
8 Copyright (C) 1999,2000 contributors of the QuakeForge project
9 Please see the file "AUTHORS" for a list of contributors
10
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License
13 as published by the Free Software Foundation; either version 2
14 of the License, or (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19
20 See the GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to:
24
25 Free Software Foundation, Inc.
26 59 Temple Place - Suite 330
27 Boston, MA 02111-1307, USA
28
29 */
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
33
34 #ifdef HAVE_STRING_H
35 # include <string.h>
36 #endif
37 #ifdef HAVE_STRINGS_H
38 # include <strings.h>
39 #endif
40 #ifdef HAVE_UNISTD_H
41 # include <unistd.h>
42 #endif
43
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <vga.h>
47 #include <vgakeyboard.h>
48 #include <vgamouse.h>
49
50 #include "QF/cmd.h"
51 #include "QF/cvar.h"
52 #include "QF/input.h"
53 #include "QF/joystick.h"
54 #include "QF/keys.h"
55 #include "QF/mathlib.h"
56 #include "QF/qargs.h"
57 #include "QF/sys.h"
58
59 #include "compat.h"
60
61 static int UseKeyboard = 1;
62 static int UseMouse = 1;
63 static int in_svgalib_inited = 0;
64
65 static unsigned short scantokey[3][128];
66 static int mouse_buttons;
67 static int mouse_buttonstate;
68 static int mouse_oldbuttonstate;
69
70 static void IN_InitKeyboard (void);
71 static void IN_InitMouse (void);
72
73 #define ROTL(x,n) (((x)<<(n))|(x)>>(32-n))
74
75
76 static void
keyhandler(int scancode,int state)77 keyhandler (int scancode, int state)
78 {
79 int sc, ascii, key;
80 int press = state == KEY_EVENTPRESS;
81 unsigned long mask = ~1L;
82 static unsigned long shifts;
83
84 sc = scancode & 0x7f;
85 key = scantokey[0][sc];
86 if ((shifts & 0x0c)) {
87 ascii = scantokey[2][sc];
88 } else if (shifts & 3) {
89 ascii = scantokey[1][sc];
90 } else {
91 ascii = scantokey[0][sc];
92 }
93 if (ascii > 255)
94 ascii = 0;
95 switch (key) {
96 case QFK_RSHIFT:
97 shifts &= mask;
98 shifts |= press;
99 break;
100 case QFK_LSHIFT:
101 shifts &= ROTL(mask, 1);
102 shifts |= ROTL(press, 1);
103 break;
104 case QFK_RCTRL:
105 shifts &= ROTL(mask, 2);
106 shifts |= ROTL(press, 2);
107 break;
108 case QFK_LCTRL:
109 shifts &= ROTL(mask, 3);
110 shifts |= ROTL(press, 3);
111 break;
112 default:
113 break;
114 }
115 //Sys_MaskPrintf (SYS_VID, "%d %02x %02lx %04x %c\n", sc, press, shifts,
116 // key, ascii > 32 && ascii < 127 ? ascii : '#');
117 Key_Event (key, ascii, press);
118 }
119
120 static void
mousehandler(int buttonstate,int dx,int dy,int dz,int drx,int dry,int drz)121 mousehandler (int buttonstate, int dx, int dy, int dz, int drx, int dry,
122 int drz)
123 {
124 mouse_buttonstate = buttonstate;
125 in_mouse_x += dx;
126 in_mouse_y += dy;
127 if (drx > 0) {
128 Key_Event (QFM_WHEEL_UP, 0, 1);
129 Key_Event (QFM_WHEEL_UP, 0, 0);
130 } else if (drx < 0) {
131 Key_Event (QFM_WHEEL_DOWN, 0, 1);
132 Key_Event (QFM_WHEEL_DOWN, 0, 0);
133 }
134 }
135
136 void
IN_LL_Init(void)137 IN_LL_Init (void)
138 {
139 if (COM_CheckParm ("-nokbd"))
140 UseKeyboard = 0;
141 if (COM_CheckParm ("-nomouse"))
142 UseMouse = 0;
143
144 if (UseKeyboard)
145 IN_InitKeyboard ();
146 if (UseMouse)
147 IN_InitMouse ();
148
149 in_svgalib_inited = 1;
150 return;
151 }
152
153 void
IN_LL_Init_Cvars(void)154 IN_LL_Init_Cvars (void)
155 {
156 }
157
158 static void
IN_InitKeyboard(void)159 IN_InitKeyboard (void)
160 {
161 int i;
162
163 for (i = 0; i < 128; i++) {
164 scantokey[0][i] = ' ';
165 }
166
167 scantokey[0][1] = QFK_ESCAPE;
168 scantokey[0][2] = '1';
169 scantokey[0][3] = '2';
170 scantokey[0][4] = '3';
171 scantokey[0][5] = '4';
172 scantokey[0][6] = '5';
173 scantokey[0][7] = '6';
174 scantokey[0][8] = '7';
175 scantokey[0][9] = '8';
176 scantokey[0][10] = '9';
177 scantokey[0][11] = '0';
178 scantokey[0][12] = '-';
179 scantokey[0][13] = '=';
180 scantokey[0][14] = QFK_BACKSPACE;
181 scantokey[0][15] = QFK_TAB;
182 scantokey[0][16] = 'q';
183 scantokey[0][17] = 'w';
184 scantokey[0][18] = 'e';
185 scantokey[0][19] = 'r';
186 scantokey[0][20] = 't';
187 scantokey[0][21] = 'y';
188 scantokey[0][22] = 'u';
189 scantokey[0][23] = 'i';
190 scantokey[0][24] = 'o';
191 scantokey[0][25] = 'p';
192 scantokey[0][26] = '[';
193 scantokey[0][27] = ']';
194 scantokey[0][28] = QFK_RETURN;
195 scantokey[0][29] = QFK_LCTRL; /* left */
196 scantokey[0][30] = 'a';
197 scantokey[0][31] = 's';
198 scantokey[0][32] = 'd';
199 scantokey[0][33] = 'f';
200 scantokey[0][34] = 'g';
201 scantokey[0][35] = 'h';
202 scantokey[0][36] = 'j';
203 scantokey[0][37] = 'k';
204 scantokey[0][38] = 'l';
205 scantokey[0][39] = ';';
206 scantokey[0][40] = '\'';
207 scantokey[0][41] = '`';
208 scantokey[0][42] = QFK_LSHIFT; /* left */
209 scantokey[0][43] = '\\';
210 scantokey[0][44] = 'z';
211 scantokey[0][45] = 'x';
212 scantokey[0][46] = 'c';
213 scantokey[0][47] = 'v';
214 scantokey[0][48] = 'b';
215 scantokey[0][49] = 'n';
216 scantokey[0][50] = 'm';
217 scantokey[0][51] = ',';
218 scantokey[0][52] = '.';
219 scantokey[0][53] = '/';
220 scantokey[0][54] = QFK_RSHIFT; /* right */
221 scantokey[0][55] = QFK_KP_MULTIPLY;
222 scantokey[0][56] = QFK_LALT; /* left */
223 scantokey[0][57] = ' ';
224 scantokey[0][58] = QFK_CAPSLOCK;
225 scantokey[0][59] = QFK_F1;
226 scantokey[0][60] = QFK_F2;
227 scantokey[0][61] = QFK_F3;
228 scantokey[0][62] = QFK_F4;
229 scantokey[0][63] = QFK_F5;
230 scantokey[0][64] = QFK_F6;
231 scantokey[0][65] = QFK_F7;
232 scantokey[0][66] = QFK_F8;
233 scantokey[0][67] = QFK_F9;
234 scantokey[0][68] = QFK_F10;
235 scantokey[0][69] = QFK_NUMLOCK;
236 scantokey[0][70] = QFK_SCROLLOCK;
237 scantokey[0][71] = QFK_KP7;
238 scantokey[0][72] = QFK_KP8;
239 scantokey[0][73] = QFK_KP9;
240 scantokey[0][74] = QFK_KP_MINUS;
241 scantokey[0][75] = QFK_KP4;
242 scantokey[0][76] = QFK_KP5;
243 scantokey[0][77] = QFK_KP6;
244 scantokey[0][79] = QFK_KP1;
245 scantokey[0][78] = QFK_KP_PLUS;
246 scantokey[0][80] = QFK_KP2;
247 scantokey[0][81] = QFK_KP3;
248 scantokey[0][82] = QFK_KP0;
249 scantokey[0][83] = QFK_KP_PERIOD;
250 /* 84 to 86 not used */
251 scantokey[0][87] = QFK_F11;
252 scantokey[0][88] = QFK_F12;
253 /* 89 to 95 not used */
254 scantokey[0][96] = QFK_KP_ENTER; /* keypad enter */
255 scantokey[0][97] = QFK_RCTRL; /* right */
256 scantokey[0][98] = QFK_KP_DIVIDE;
257 scantokey[0][99] = QFK_PRINT; /* print screen */
258 scantokey[0][100] = QFK_RALT; /* right */
259
260 scantokey[0][101] = QFK_PAUSE; /* break */
261 scantokey[0][102] = QFK_HOME;
262 scantokey[0][103] = QFK_UP;
263 scantokey[0][104] = QFK_PAGEUP;
264 scantokey[0][105] = QFK_LEFT;
265 scantokey[0][106] = QFK_RIGHT;
266 scantokey[0][107] = QFK_END;
267 scantokey[0][108] = QFK_DOWN;
268 scantokey[0][109] = QFK_PAGEDOWN;
269 scantokey[0][110] = QFK_INSERT;
270 scantokey[0][111] = QFK_DELETE;
271 scantokey[0][119] = QFK_PAUSE;
272
273 memcpy (scantokey[1], scantokey[0], sizeof (scantokey[1]));
274 memcpy (scantokey[2], scantokey[0], sizeof (scantokey[2]));
275
276 scantokey[1][2] = '!';
277 scantokey[1][3] = '@';
278 scantokey[1][4] = '#';
279 scantokey[1][5] = '$';
280 scantokey[1][6] = '%';
281 scantokey[1][7] = '^';
282 scantokey[1][8] = '&';
283 scantokey[1][9] = '*';
284 scantokey[1][10] = '(';
285 scantokey[1][11] = ')';
286 scantokey[1][12] = '_';
287 scantokey[1][13] = '+';
288 scantokey[1][16] = 'Q';
289 scantokey[1][17] = 'W';
290 scantokey[1][18] = 'E';
291 scantokey[1][19] = 'R';
292 scantokey[1][20] = 'T';
293 scantokey[1][21] = 'Y';
294 scantokey[1][22] = 'U';
295 scantokey[1][23] = 'I';
296 scantokey[1][24] = 'O';
297 scantokey[1][25] = 'P';
298 scantokey[1][26] = '[';
299 scantokey[1][27] = ']';
300 scantokey[1][30] = 'A';
301 scantokey[1][31] = 'S';
302 scantokey[1][32] = 'D';
303 scantokey[1][33] = 'F';
304 scantokey[1][34] = 'G';
305 scantokey[1][35] = 'H';
306 scantokey[1][36] = 'J';
307 scantokey[1][37] = 'K';
308 scantokey[1][38] = 'L';
309 scantokey[1][39] = ':';
310 scantokey[1][40] = '"';
311 scantokey[1][41] = '~';
312 scantokey[1][43] = '|';
313 scantokey[1][44] = 'Z';
314 scantokey[1][45] = 'X';
315 scantokey[1][46] = 'C';
316 scantokey[1][47] = 'V';
317 scantokey[1][48] = 'B';
318 scantokey[1][49] = 'N';
319 scantokey[1][50] = 'M';
320 scantokey[1][51] = '<';
321 scantokey[1][52] = '>';
322 scantokey[1][53] = '?';
323
324 scantokey[2][7] = 30;
325 scantokey[2][12] = 31;
326 scantokey[2][16] = 'q' - 96;
327 scantokey[2][17] = 'w' - 96;
328 scantokey[2][18] = 'e' - 96;
329 scantokey[2][19] = 'r' - 96;
330 scantokey[2][20] = 't' - 96;
331 scantokey[2][21] = 'y' - 96;
332 scantokey[2][22] = 'u' - 96;
333 scantokey[2][23] = 'i' - 96;
334 scantokey[2][24] = 'o' - 96;
335 scantokey[2][25] = 'p' - 96;
336 scantokey[2][26] = 27;
337 scantokey[2][27] = 29;
338 scantokey[2][30] = 'a' - 96;
339 scantokey[2][31] = 's' - 96;
340 scantokey[2][32] = 'd' - 96;
341 scantokey[2][33] = 'f' - 96;
342 scantokey[2][34] = 'g' - 96;
343 scantokey[2][35] = 'h' - 96;
344 scantokey[2][36] = 'j' - 96;
345 scantokey[2][37] = 'k' - 96;
346 scantokey[2][38] = 'l' - 96;
347 scantokey[2][40] = 28;
348 scantokey[2][44] = 'z' - 96;
349 scantokey[2][45] = 'x' - 96;
350 scantokey[2][46] = 'c' - 96;
351 scantokey[2][47] = 'v' - 96;
352 scantokey[2][48] = 'b' - 96;
353 scantokey[2][49] = 'n' - 96;
354 scantokey[2][50] = 'm' - 96;
355
356 if (keyboard_init ()) {
357 Sys_Error ("keyboard_init() failed");
358 }
359 keyboard_seteventhandler (keyhandler);
360 }
361
362 static void
IN_InitMouse(void)363 IN_InitMouse (void)
364 {
365 int mtype;
366 int mouserate = MOUSE_DEFAULTSAMPLERATE;
367 const char *mousedev;
368
369 mouse_buttons = 3;
370
371 mtype = vga_getmousetype ();
372
373 mousedev = "/dev/mouse";
374 if (getenv ("MOUSEDEV"))
375 mousedev = getenv ("MOUSEDEV");
376 if (COM_CheckParm ("-mdev")) {
377 mousedev = com_argv[COM_CheckParm ("-mdev") + 1];
378 }
379
380 if (getenv ("MOUSERATE"))
381 mouserate = atoi (getenv ("MOUSERATE"));
382 if (COM_CheckParm ("-mrate")) {
383 mouserate = atoi (com_argv[COM_CheckParm ("-mrate") + 1]);
384 }
385 #if 0
386 Sys_MaskPrintf (SYS_VID, "Mouse: dev=%s,type=%s,speed=%d\n",
387 mousedev, mice[mtype].name, mouserate);
388 #endif
389 //FIXME: vga_init() opens the mouse automoatically
390 // closing it to ensure its opened how we want it
391 mouse_close();
392 if (mouse_init ((char *)mousedev, mtype, mouserate)) {
393 Sys_MaskPrintf (SYS_VID,
394 "No mouse found. Check your libvga.conf mouse settings"
395 " and that the mouse\n"
396 "device has appropriate permission settings.\n");
397 UseMouse = 0;
398 } else {
399 mouse_seteventhandler ((void *) mousehandler);
400 }
401 in_mouse_avail = 1;
402 }
403
404 void
IN_LL_Shutdown(void)405 IN_LL_Shutdown (void)
406 {
407 Sys_MaskPrintf (SYS_VID, "IN_LL_Shutdown\n");
408
409 if (UseMouse)
410 mouse_close ();
411 if (UseKeyboard)
412 keyboard_close ();
413 in_svgalib_inited = 0;
414 }
415
416
417 void
IN_LL_ProcessEvents(void)418 IN_LL_ProcessEvents (void)
419 {
420 if (!in_svgalib_inited)
421 return;
422
423 if (UseKeyboard) {
424 while ((keyboard_update ()));
425 }
426
427 if (UseMouse) {
428 /* Poll mouse values */
429 while (mouse_update ());
430
431 /* Perform button actions */
432 if ((mouse_buttonstate & MOUSE_LEFTBUTTON) &&
433 !(mouse_oldbuttonstate & MOUSE_LEFTBUTTON))
434 Key_Event (QFM_BUTTON1, 0, true);
435 else if (!(mouse_buttonstate & MOUSE_LEFTBUTTON) &&
436 (mouse_oldbuttonstate & MOUSE_LEFTBUTTON))
437 Key_Event (QFM_BUTTON1, 0, false);
438
439 if ((mouse_buttonstate & MOUSE_RIGHTBUTTON) &&
440 !(mouse_oldbuttonstate & MOUSE_RIGHTBUTTON))
441 Key_Event (QFM_BUTTON2, 0, true);
442 else if (!(mouse_buttonstate & MOUSE_RIGHTBUTTON) &&
443 (mouse_oldbuttonstate & MOUSE_RIGHTBUTTON))
444 Key_Event (QFM_BUTTON2, 0, false);
445
446 if ((mouse_buttonstate & MOUSE_MIDDLEBUTTON) &&
447 !(mouse_oldbuttonstate & MOUSE_MIDDLEBUTTON))
448 Key_Event (QFM_BUTTON3, 0, true);
449 else if (!(mouse_buttonstate & MOUSE_MIDDLEBUTTON) &&
450 (mouse_oldbuttonstate & MOUSE_MIDDLEBUTTON))
451 Key_Event (QFM_BUTTON3, 0, false);
452
453 mouse_oldbuttonstate = mouse_buttonstate;
454 }
455 }
456
457 void
IN_LL_Grab_Input(int grab)458 IN_LL_Grab_Input (int grab)
459 {
460 }
461
462 void
IN_LL_ClearStates(void)463 IN_LL_ClearStates (void)
464 {
465 }
466