1 /* 2 SDL - Simple DirectMedia Layer 3 Copyright (C) 1997-2012 Sam Lantinga 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with this library; if not, write to the Free Software 17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 19 Sam Lantinga 20 slouken (at) libsdl.org 21 */ 22 #include "SDL_config.h" 23 24 /* Handle the event stream, converting X11 events into SDL events */ 25 26 #include <vga.h> 27 #include <vgamouse.h> 28 #include <vgakeyboard.h> 29 #if defined(__LINUX__) 30 #include <linux/kd.h> 31 #include <linux/keyboard.h> 32 #elif defined(__FREEBSD__) 33 #include <sys/kbio.h> 34 #else 35 #error You must choose your operating system here 36 #endif 37 38 #include "../../events/SDL_sysevents.h" 39 #include "../../events/SDL_events_c.h" 40 #include "SDL_svgavideo.h" 41 #include "SDL_svgaevents_c.h" 42 43 /* The translation tables from a console scancode to a SDL keysym */ 44 #if defined(linux) 45 #define NUM_VGAKEYMAPS (1<<KG_CAPSSHIFT) 46 static Uint16 vga_keymap[NUM_VGAKEYMAPS][NR_KEYS]; 47 #elif defined(__FREEBSD__) 48 /* FIXME: Free the keymap when we shut down the video mode */ 49 static keymap_t *vga_keymap = NULL; 50 #else 51 #error You must choose your operating system here 52 #endif 53 static SDLKey keymap[128]; 54 static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym); 55 56 /* Ugh, we have to duplicate the kernel's keysym mapping code... 57 Oh, it's not so bad. :-) 58 59 FIXME: Add keyboard LED handling code 60 */ 61 #if defined(linux) 62 int SVGA_initkeymaps(int fd) 63 { 64 struct kbentry entry; 65 int map, i; 66 67 /* Load all the keysym mappings */ 68 for ( map=0; map<NUM_VGAKEYMAPS; ++map ) { 69 SDL_memset(vga_keymap[map], 0, NR_KEYS*sizeof(Uint16)); 70 for ( i=0; i<NR_KEYS; ++i ) { 71 entry.kb_table = map; 72 entry.kb_index = i; 73 if ( ioctl(fd, KDGKBENT, &entry) == 0 ) { 74 /* The "Enter" key is a special case */ 75 if ( entry.kb_value == K_ENTER ) { 76 entry.kb_value = K(KT_ASCII,13); 77 } 78 /* Handle numpad specially as well */ 79 if ( KTYP(entry.kb_value) == KT_PAD ) { 80 switch ( entry.kb_value ) { 81 case K_P0: 82 case K_P1: 83 case K_P2: 84 case K_P3: 85 case K_P4: 86 case K_P5: 87 case K_P6: 88 case K_P7: 89 case K_P8: 90 case K_P9: 91 vga_keymap[map][i]=entry.kb_value; 92 vga_keymap[map][i]+= '0'; 93 break; 94 case K_PPLUS: 95 vga_keymap[map][i]=K(KT_ASCII,'+'); 96 break; 97 case K_PMINUS: 98 vga_keymap[map][i]=K(KT_ASCII,'-'); 99 break; 100 case K_PSTAR: 101 vga_keymap[map][i]=K(KT_ASCII,'*'); 102 break; 103 case K_PSLASH: 104 vga_keymap[map][i]=K(KT_ASCII,'/'); 105 break; 106 case K_PENTER: 107 vga_keymap[map][i]=K(KT_ASCII,'\r'); 108 break; 109 case K_PCOMMA: 110 vga_keymap[map][i]=K(KT_ASCII,','); 111 break; 112 case K_PDOT: 113 vga_keymap[map][i]=K(KT_ASCII,'.'); 114 break; 115 default: 116 break; 117 } 118 } 119 /* Do the normal key translation */ 120 if ( (KTYP(entry.kb_value) == KT_LATIN) || 121 (KTYP(entry.kb_value) == KT_ASCII) || 122 (KTYP(entry.kb_value) == KT_LETTER) ) { 123 vga_keymap[map][i] = entry.kb_value; 124 } 125 } 126 } 127 } 128 return(0); 129 } 130 #elif defined(__FREEBSD__) 131 int SVGA_initkeymaps(int fd) 132 { 133 vga_keymap = SDL_malloc(sizeof(keymap_t)); 134 if ( ! vga_keymap ) { 135 SDL_OutOfMemory(); 136 return(-1); 137 } 138 if (ioctl(fd, GIO_KEYMAP, vga_keymap) == -1) { 139 SDL_free(vga_keymap); 140 vga_keymap = NULL; 141 SDL_SetError("Unable to get keyboard map"); 142 return(-1); 143 } 144 return(0); 145 } 146 #else 147 #error You must choose your operating system here 148 #endif 149 150 int posted = 0; 151 152 void SVGA_mousecallback(int button, int dx, int dy, 153 int u1,int u2,int u3, int u4) 154 { 155 if ( dx || dy ) { 156 posted += SDL_PrivateMouseMotion(0, 1, dx, dy); 157 } 158 if ( button & MOUSE_LEFTBUTTON ) { 159 if ( !(SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(1)) ) { 160 posted += SDL_PrivateMouseButton(SDL_PRESSED, 1, 0, 0); 161 } 162 } else { 163 if ( (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(1)) ) { 164 posted += SDL_PrivateMouseButton(SDL_RELEASED, 1, 0, 0); 165 } 166 } 167 if ( button & MOUSE_MIDDLEBUTTON ) { 168 if ( !(SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(2)) ) { 169 posted += SDL_PrivateMouseButton(SDL_PRESSED, 2, 0, 0); 170 } 171 } else { 172 if ( (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(2)) ) { 173 posted += SDL_PrivateMouseButton(SDL_RELEASED, 2, 0, 0); 174 } 175 } 176 if ( button & MOUSE_RIGHTBUTTON ) { 177 if ( !(SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(3)) ) { 178 posted += SDL_PrivateMouseButton(SDL_PRESSED, 3, 0, 0); 179 } 180 } else { 181 if ( (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(3)) ) { 182 posted += SDL_PrivateMouseButton(SDL_RELEASED, 3, 0, 0); 183 } 184 } 185 } 186 187 void SVGA_keyboardcallback(int scancode, int pressed) 188 { 189 SDL_keysym keysym; 190 191 if ( pressed ) { 192 posted += SDL_PrivateKeyboard(SDL_PRESSED, 193 TranslateKey(scancode, &keysym)); 194 } else { 195 posted += SDL_PrivateKeyboard(SDL_RELEASED, 196 TranslateKey(scancode, &keysym)); 197 } 198 } 199 200 void SVGA_PumpEvents(_THIS) 201 { 202 do { 203 posted = 0; 204 mouse_update(); 205 keyboard_update(); 206 } while ( posted ); 207 } 208 209 void SVGA_InitOSKeymap(_THIS) 210 { 211 int i; 212 213 /* Initialize the BeOS key translation table */ 214 for ( i=0; i<SDL_arraysize(keymap); ++i ) 215 keymap[i] = SDLK_UNKNOWN; 216 217 keymap[SCANCODE_ESCAPE] = SDLK_ESCAPE; 218 keymap[SCANCODE_1] = SDLK_1; 219 keymap[SCANCODE_2] = SDLK_2; 220 keymap[SCANCODE_3] = SDLK_3; 221 keymap[SCANCODE_4] = SDLK_4; 222 keymap[SCANCODE_5] = SDLK_5; 223 keymap[SCANCODE_6] = SDLK_6; 224 keymap[SCANCODE_7] = SDLK_7; 225 keymap[SCANCODE_8] = SDLK_8; 226 keymap[SCANCODE_9] = SDLK_9; 227 keymap[SCANCODE_0] = SDLK_0; 228 keymap[SCANCODE_MINUS] = SDLK_MINUS; 229 keymap[SCANCODE_EQUAL] = SDLK_EQUALS; 230 keymap[SCANCODE_BACKSPACE] = SDLK_BACKSPACE; 231 keymap[SCANCODE_TAB] = SDLK_TAB; 232 keymap[SCANCODE_Q] = SDLK_q; 233 keymap[SCANCODE_W] = SDLK_w; 234 keymap[SCANCODE_E] = SDLK_e; 235 keymap[SCANCODE_R] = SDLK_r; 236 keymap[SCANCODE_T] = SDLK_t; 237 keymap[SCANCODE_Y] = SDLK_y; 238 keymap[SCANCODE_U] = SDLK_u; 239 keymap[SCANCODE_I] = SDLK_i; 240 keymap[SCANCODE_O] = SDLK_o; 241 keymap[SCANCODE_P] = SDLK_p; 242 keymap[SCANCODE_BRACKET_LEFT] = SDLK_LEFTBRACKET; 243 keymap[SCANCODE_BRACKET_RIGHT] = SDLK_RIGHTBRACKET; 244 keymap[SCANCODE_ENTER] = SDLK_RETURN; 245 keymap[SCANCODE_LEFTCONTROL] = SDLK_LCTRL; 246 keymap[SCANCODE_A] = SDLK_a; 247 keymap[SCANCODE_S] = SDLK_s; 248 keymap[SCANCODE_D] = SDLK_d; 249 keymap[SCANCODE_F] = SDLK_f; 250 keymap[SCANCODE_G] = SDLK_g; 251 keymap[SCANCODE_H] = SDLK_h; 252 keymap[SCANCODE_J] = SDLK_j; 253 keymap[SCANCODE_K] = SDLK_k; 254 keymap[SCANCODE_L] = SDLK_l; 255 keymap[SCANCODE_SEMICOLON] = SDLK_SEMICOLON; 256 keymap[SCANCODE_APOSTROPHE] = SDLK_QUOTE; 257 keymap[SCANCODE_GRAVE] = SDLK_BACKQUOTE; 258 keymap[SCANCODE_LEFTSHIFT] = SDLK_LSHIFT; 259 keymap[SCANCODE_BACKSLASH] = SDLK_BACKSLASH; 260 keymap[SCANCODE_Z] = SDLK_z; 261 keymap[SCANCODE_X] = SDLK_x; 262 keymap[SCANCODE_C] = SDLK_c; 263 keymap[SCANCODE_V] = SDLK_v; 264 keymap[SCANCODE_B] = SDLK_b; 265 keymap[SCANCODE_N] = SDLK_n; 266 keymap[SCANCODE_M] = SDLK_m; 267 keymap[SCANCODE_COMMA] = SDLK_COMMA; 268 keymap[SCANCODE_PERIOD] = SDLK_PERIOD; 269 keymap[SCANCODE_SLASH] = SDLK_SLASH; 270 keymap[SCANCODE_RIGHTSHIFT] = SDLK_RSHIFT; 271 keymap[SCANCODE_KEYPADMULTIPLY] = SDLK_KP_MULTIPLY; 272 keymap[SCANCODE_LEFTALT] = SDLK_LALT; 273 keymap[SCANCODE_SPACE] = SDLK_SPACE; 274 keymap[SCANCODE_CAPSLOCK] = SDLK_CAPSLOCK; 275 keymap[SCANCODE_F1] = SDLK_F1; 276 keymap[SCANCODE_F2] = SDLK_F2; 277 keymap[SCANCODE_F3] = SDLK_F3; 278 keymap[SCANCODE_F4] = SDLK_F4; 279 keymap[SCANCODE_F5] = SDLK_F5; 280 keymap[SCANCODE_F6] = SDLK_F6; 281 keymap[SCANCODE_F7] = SDLK_F7; 282 keymap[SCANCODE_F8] = SDLK_F8; 283 keymap[SCANCODE_F9] = SDLK_F9; 284 keymap[SCANCODE_F10] = SDLK_F10; 285 keymap[SCANCODE_NUMLOCK] = SDLK_NUMLOCK; 286 keymap[SCANCODE_SCROLLLOCK] = SDLK_SCROLLOCK; 287 keymap[SCANCODE_KEYPAD7] = SDLK_KP7; 288 keymap[SCANCODE_CURSORUPLEFT] = SDLK_KP7; 289 keymap[SCANCODE_KEYPAD8] = SDLK_KP8; 290 keymap[SCANCODE_CURSORUP] = SDLK_KP8; 291 keymap[SCANCODE_KEYPAD9] = SDLK_KP9; 292 keymap[SCANCODE_CURSORUPRIGHT] = SDLK_KP9; 293 keymap[SCANCODE_KEYPADMINUS] = SDLK_KP_MINUS; 294 keymap[SCANCODE_KEYPAD4] = SDLK_KP4; 295 keymap[SCANCODE_CURSORLEFT] = SDLK_KP4; 296 keymap[SCANCODE_KEYPAD5] = SDLK_KP5; 297 keymap[SCANCODE_KEYPAD6] = SDLK_KP6; 298 keymap[SCANCODE_CURSORRIGHT] = SDLK_KP6; 299 keymap[SCANCODE_KEYPADPLUS] = SDLK_KP_PLUS; 300 keymap[SCANCODE_KEYPAD1] = SDLK_KP1; 301 keymap[SCANCODE_CURSORDOWNLEFT] = SDLK_KP1; 302 keymap[SCANCODE_KEYPAD2] = SDLK_KP2; 303 keymap[SCANCODE_CURSORDOWN] = SDLK_KP2; 304 keymap[SCANCODE_KEYPAD3] = SDLK_KP3; 305 keymap[SCANCODE_CURSORDOWNRIGHT] = SDLK_KP3; 306 keymap[SCANCODE_KEYPAD0] = SDLK_KP0; 307 keymap[SCANCODE_KEYPADPERIOD] = SDLK_KP_PERIOD; 308 keymap[SCANCODE_LESS] = SDLK_LESS; 309 keymap[SCANCODE_F11] = SDLK_F11; 310 keymap[SCANCODE_F12] = SDLK_F12; 311 keymap[SCANCODE_KEYPADENTER] = SDLK_KP_ENTER; 312 keymap[SCANCODE_RIGHTCONTROL] = SDLK_RCTRL; 313 keymap[SCANCODE_CONTROL] = SDLK_RCTRL; 314 keymap[SCANCODE_KEYPADDIVIDE] = SDLK_KP_DIVIDE; 315 keymap[SCANCODE_PRINTSCREEN] = SDLK_PRINT; 316 keymap[SCANCODE_RIGHTALT] = SDLK_RALT; 317 keymap[SCANCODE_BREAK] = SDLK_BREAK; 318 keymap[SCANCODE_BREAK_ALTERNATIVE] = SDLK_UNKNOWN; 319 keymap[SCANCODE_HOME] = SDLK_HOME; 320 keymap[SCANCODE_CURSORBLOCKUP] = SDLK_UP; 321 keymap[SCANCODE_PAGEUP] = SDLK_PAGEUP; 322 keymap[SCANCODE_CURSORBLOCKLEFT] = SDLK_LEFT; 323 keymap[SCANCODE_CURSORBLOCKRIGHT] = SDLK_RIGHT; 324 keymap[SCANCODE_END] = SDLK_END; 325 keymap[SCANCODE_CURSORBLOCKDOWN] = SDLK_DOWN; 326 keymap[SCANCODE_PAGEDOWN] = SDLK_PAGEDOWN; 327 keymap[SCANCODE_INSERT] = SDLK_INSERT; 328 keymap[SCANCODE_REMOVE] = SDLK_DELETE; 329 keymap[119] = SDLK_PAUSE; 330 keymap[SCANCODE_RIGHTWIN] = SDLK_RSUPER; 331 keymap[SCANCODE_LEFTWIN] = SDLK_LSUPER; 332 keymap[127] = SDLK_MENU; 333 } 334 335 #if defined(linux) 336 static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym) 337 { 338 /* Set the keysym information */ 339 keysym->scancode = scancode; 340 keysym->sym = keymap[scancode]; 341 keysym->mod = KMOD_NONE; 342 343 /* If UNICODE is on, get the UNICODE value for the key */ 344 keysym->unicode = 0; 345 if ( SDL_TranslateUNICODE ) { 346 int map; 347 SDLMod modstate; 348 349 modstate = SDL_GetModState(); 350 map = 0; 351 if ( modstate & KMOD_SHIFT ) { 352 map |= (1<<KG_SHIFT); 353 } 354 if ( modstate & KMOD_CTRL ) { 355 map |= (1<<KG_CTRL); 356 } 357 if ( modstate & KMOD_ALT ) { 358 map |= (1<<KG_ALT); 359 } 360 if ( modstate & KMOD_MODE ) { 361 map |= (1<<KG_ALTGR); 362 } 363 if ( KTYP(vga_keymap[map][scancode]) == KT_LETTER ) { 364 if ( modstate & KMOD_CAPS ) { 365 map ^= (1<<KG_SHIFT); 366 } 367 } 368 if ( KTYP(vga_keymap[map][scancode]) == KT_PAD ) { 369 if ( modstate & KMOD_NUM ) { 370 keysym->unicode=KVAL(vga_keymap[map][scancode]); 371 } 372 } else { 373 keysym->unicode = KVAL(vga_keymap[map][scancode]); 374 } 375 } 376 return(keysym); 377 } 378 #elif defined(__FREEBSD__) 379 static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym) 380 { 381 /* Set the keysym information */ 382 keysym->scancode = scancode; 383 keysym->sym = keymap[scancode]; 384 keysym->mod = KMOD_NONE; 385 386 /* If UNICODE is on, get the UNICODE value for the key */ 387 keysym->unicode = 0; 388 if ( SDL_TranslateUNICODE && vga_keymap ) { 389 int map; 390 SDLMod modstate; 391 392 modstate = SDL_GetModState(); 393 map = 0; 394 if ( modstate & KMOD_SHIFT ) { 395 map += 1; 396 } 397 if ( modstate & KMOD_CTRL ) { 398 map += 2; 399 } 400 if ( modstate & KMOD_ALT ) { 401 map += 4; 402 } 403 if ( !(vga_keymap->key[scancode].spcl & (0x80 >> map)) ) { 404 keysym->unicode = vga_keymap->key[scancode].map[map]; 405 } 406 407 } 408 return(keysym); 409 } 410 #else 411 #error You must choose your operating system here 412 #endif 413