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