00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "Core/precomp.h"
00016
00017 #ifndef USE_TTY_INPUT
00018 #ifdef USE_SVGALIB
00019 #define USE_TTY_INPUT
00020 #else
00021 #ifdef USE_FBDEV
00022 #define USE_TTY_INPUT
00023 #endif
00024 #endif
00025 #endif
00026
00027 #ifdef USE_TTY_INPUT
00028
00029 #include <stdlib.h>
00030 #include <stdio.h>
00031 #include <string.h>
00032 #include <iostream>
00033 #include <unistd.h>
00034
00035 #include <fcntl.h>
00036 #include <sys/ioctl.h>
00037 #include <sys/stat.h>
00038
00039 #ifdef HAVE_SYS_KD_H
00040 #include <sys/kd.h>
00041 #else
00042 #include <linux/kd.h>
00043 #endif
00044 #ifdef HAVE_SYS_VT_H
00045 #include <sys/vt.h>
00046 #else
00047 #include <linux/vt.h>
00048 #endif
00049 #include <linux/tty.h>
00050 #include <linux/keyboard.h>
00051
00052 #include "keyboard_fbdev.h"
00053
00054 #include <API/Core/System/error.h>
00055 #include <Display/Input/FBDev/keyboard_fbdev.h>
00056 #include <Core/System/Unix/implementation_fbdev.h>
00057 #include <API/Display/Input/inputaxis.h>
00058 #include <Display/Input/FBDev/keyboard_fbdev.h>
00059 #include <API/Display/Input/inputbutton.h>
00060 #include <Display/Input/FBDev/keyboard_fbdev.h>
00061 #include <API/Display/Input/inputcursor.h>
00062 #include <API/Display/Input/inputhat.h>
00063
00064 #include "Core/System/Generic/string_asm.h"
00065
00066
00067
00068
00069
00070 CL_FBDevKeyboard::CL_FBDevKeyboard()
00071 {
00072 memset( &keymap, 0, sizeof(keymap) );
00073
00074
00075 fd = open("/dev/tty", O_RDWR | O_NONBLOCK);
00076
00077 if (fd < 0)
00078 {
00079 throw CL_Error("Couldn't open /dev/tty.");
00080 }
00081
00082
00083 struct termios newterm;
00084
00085 if (tcgetattr(fd, &old_termios) < 0)
00086 {
00087 perror("tcgetattr failed");
00088 }
00089
00090 memcpy ( &newterm, &old_termios, sizeof(termios) );
00091
00092 newterm.c_lflag &= ~(ICANON | ECHO | ISIG);
00093 newterm.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON);
00094 newterm.c_iflag |= IGNBRK;
00095 newterm.c_cc[VMIN] = 0;
00096 newterm.c_cc[VTIME] = 0;
00097
00098 if (tcsetattr(fd, TCSANOW, &newterm) < 0)
00099 {
00100 perror("tcsetattr failed");
00101 }
00102
00103
00104 if (ioctl(fd, KDGKBMODE, &old_mode) < 0)
00105 {
00106 perror("Couldn't get keyboard mode");
00107 old_mode = K_XLATE;
00108 }
00109 if (ioctl(fd, KDSKBMODE, K_MEDIUMRAW) < 0)
00110 {
00111 perror("Couldn't set keyboard mode to K_MEDIUMRAW");
00112 }
00113
00114
00115 if (ioctl(fd, KDGETMODE, &old_kd) < 0)
00116 {
00117 perror("Couldn't get kd mode");
00118 old_kd = KD_TEXT;
00119 }
00120 if (ioctl(fd, KDSETMODE, KD_GRAPHICS) < 0)
00121 {
00122 perror("Couldn't set kd mode to KD_GRAPHICS");
00123 }
00124
00125 buttons = new CL_InputButton_FBDevKeyboard*[CL_NUM_KEYS];
00126 for (int i=0; i<CL_NUM_KEYS; i++) buttons[i] = NULL;
00127 }
00128
00129 CL_FBDevKeyboard::~CL_FBDevKeyboard()
00130 {
00131 restore();
00132 #ifdef USE_FBDEV
00133 CL_Implementation_FBDev::clean_up();
00134 #endif
00135
00136 for (int i=0; i<CL_NUM_KEYS; i++) delete buttons[i];
00137 delete[] buttons;
00138 }
00139
00140 void CL_FBDevKeyboard::restore()
00141 {
00142 if (fd>=0)
00143 {
00144 ioctl(fd, KDSKBMODE, old_mode);
00145 ioctl(fd, KDSETMODE, old_kd);
00146 if (tcsetattr(fd, TCSANOW, &old_termios) < 0)
00147 {
00148 cerr << "Could not restore old terminal input settings! Please run 'reset'!" << endl;
00149 perror( "System error message" );
00150 }
00151 close(fd);
00152 }
00153 }
00154
00155 void CL_FBDevKeyboard::keep_alive()
00156 {
00157 int readlen;
00158 unsigned char buf[256];
00159
00160
00161 while ((readlen = read(fd, buf, 256)) > 0)
00162 {
00163 for (int i = 0; i < readlen; i++)
00164 {
00165 handle_code( buf[i] );
00166 }
00167 }
00168
00169 return;
00170 }
00171
00172 void CL_FBDevKeyboard::handle_code(char code)
00173 {
00174 bool keydown;
00175 kbentry entry;
00176
00177 if (code & 0x80)
00178 {
00179 code &= 0x7f;
00180 keydown = false;
00181 } else
00182 {
00183 keydown = true;
00184 }
00185
00186
00187 entry.kb_table = 0;
00188 entry.kb_index = code;
00189 ioctl(fd,KDGKBENT,&entry);
00190
00191 CL_Key key;
00192 key.id = translate(entry.kb_value);
00193 key.ascii = -1;
00194 key.state = keydown ? CL_Key::Pressed : CL_Key::Released;
00195
00196 if (keydown) CL_Input::chain_button_press.on_button_press(this, key);
00197 else CL_Input::chain_button_release.on_button_release(this, key);
00198
00199 keymap[translate(entry.kb_value)] = keydown;
00200 }
00201
00202 char CL_FBDevKeyboard::translate(int kb_value)
00203 {
00204 switch (kb_value)
00205 {
00206 case K_F1: return CL_KEY_F1;
00207 case K_F2: return CL_KEY_F2;
00208 case K_F3: return CL_KEY_F3;
00209 case K_F4: return CL_KEY_F4;
00210 case K_F5: return CL_KEY_F5;
00211 case K_F6: return CL_KEY_F6;
00212 case K_F7: return CL_KEY_F7;
00213 case K_F8: return CL_KEY_F8;
00214 case K_F9: return CL_KEY_F9;
00215 case K_F10: return CL_KEY_F10;
00216 case K_F11: return CL_KEY_F11;
00217 case K_F12: return CL_KEY_F12;
00218
00219 case 2816+'a': return CL_KEY_A;
00220 case 2816+'b': return CL_KEY_B;
00221 case 2816+'c': return CL_KEY_C;
00222 case 2816+'d': return CL_KEY_D;
00223 case 2816+'e': return CL_KEY_E;
00224 case 2816+'f': return CL_KEY_F;
00225 case 2816+'g': return CL_KEY_G;
00226 case 2816+'h': return CL_KEY_H;
00227 case 2816+'i': return CL_KEY_I;
00228 case 2816+'j': return CL_KEY_J;
00229 case 2816+'k': return CL_KEY_K;
00230 case 2816+'l': return CL_KEY_L;
00231 case 2816+'m': return CL_KEY_M;
00232 case 2816+'n': return CL_KEY_N;
00233 case 2816+'o': return CL_KEY_O;
00234 case 2816+'p': return CL_KEY_P;
00235 case 2816+'q': return CL_KEY_Q;
00236 case 2816+'r': return CL_KEY_R;
00237 case 2816+'s': return CL_KEY_S;
00238 case 2816+'t': return CL_KEY_T;
00239 case 2816+'u': return CL_KEY_U;
00240 case 2816+'v': return CL_KEY_V;
00241 case 2816+'w': return CL_KEY_W;
00242 case 2816+'x': return CL_KEY_X;
00243 case 2816+'y': return CL_KEY_Y;
00244 case 2816+'z': return CL_KEY_Z;
00245
00246 case 48: return CL_KEY_0;
00247 case 49: return CL_KEY_1;
00248 case 50: return CL_KEY_2;
00249 case 51: return CL_KEY_3;
00250 case 52: return CL_KEY_4;
00251 case 53: return CL_KEY_5;
00252 case 54: return CL_KEY_6;
00253 case 55: return CL_KEY_7;
00254 case 56: return CL_KEY_8;
00255 case 57: return CL_KEY_9;
00256
00257 case 27: return CL_KEY_ESCAPE;
00258 case K_LEFT: return CL_KEY_LEFT;
00259 case K_RIGHT: return CL_KEY_RIGHT;
00260 case K_UP: return CL_KEY_UP;
00261 case K_DOWN: return CL_KEY_DOWN;
00262 case K_ENTER: return CL_KEY_ENTER;
00263
00264 case K_CTRLL: return CL_KEY_LCTRL;
00265 case K_CTRLR: return CL_KEY_RCTRL;
00266 case K_SHIFTL: return CL_KEY_LSHIFT;
00267 case K_SHIFTR: return CL_KEY_RSHIFT;
00268 case K_ALT: return CL_KEY_ALT;
00269 case K_ALTGR: return CL_KEY_ALTGR;
00270 case 9: return CL_KEY_TAB;
00271 case 32: return CL_KEY_SPACE;
00272 case 127: return CL_KEY_BACKSPACE;
00273 case K_INSERT: return CL_KEY_INSERT;
00274 case K_REMOVE: return CL_KEY_DELETE;
00275 case K_FIND: return CL_KEY_HOME;
00276 case K_SELECT: return CL_KEY_END;
00277 case K_PGUP: return CL_KEY_PAGEUP;
00278 case K_PGDN: return CL_KEY_PAGEDOWN;
00279 case K_CAPS: return CL_KEY_CAPSLOCK;
00280 case K_NUM: return CL_KEY_NUMLOCK;
00281 case K_HOLD: return CL_KEY_SCRLOCK;
00282 case 28: return CL_KEY_PRINT;
00283 case K(1,29): return CL_KEY_PAUSE;
00284 case K_PSLASH: return CL_KEY_KP_DIV;
00285 case K_PSTAR: return CL_KEY_KP_MULT;
00286 case K_PMINUS: return CL_KEY_KP_MINUS;
00287 case K_PPLUS: return CL_KEY_KP_PLUS;
00288 case K_PENTER: return CL_KEY_KP_ENTER;
00289 }
00290
00291 return CL_KEY_NONE_OF_THE_ABOVE;
00292 }
00293
00294 char *CL_FBDevKeyboard::get_name() const
00295 {
00296 return "FBDev keyboard";
00297 }
00298
00299 int CL_FBDevKeyboard::get_num_buttons() const
00300 {
00301 return CL_NUM_KEYS;
00302 }
00303
00304 CL_InputButton *CL_FBDevKeyboard::get_button(int button_num)
00305 {
00306 if (button_num < 0 || button_num >= CL_NUM_KEYS) return NULL;
00307
00308 if (buttons[button_num] == NULL)
00309 buttons[button_num] = new CL_InputButton_FBDevKeyboard(button_num, keymap);
00310
00311 return buttons[button_num];
00312 }
00313
00314 int CL_FBDevKeyboard::get_num_axes() const
00315 {
00316 return 0;
00317 }
00318
00319 CL_InputAxis *CL_FBDevKeyboard::get_axis(int )
00320 {
00321 return NULL;
00322 }
00323
00324 int CL_FBDevKeyboard::get_num_hats() const
00325 {
00326 return 0;
00327 }
00328
00329 CL_InputHat *CL_FBDevKeyboard::get_hat(int )
00330 {
00331 return NULL;
00332 }
00333
00334 int CL_FBDevKeyboard::get_num_cursors() const
00335 {
00336 return 0;
00337 }
00338
00339 CL_InputCursor *CL_FBDevKeyboard::get_cursor(int )
00340 {
00341 return NULL;
00342 }
00343
00344
00345
00346
00347
00348 CL_InputButton_FBDevKeyboard::CL_InputButton_FBDevKeyboard(
00349 int _key, char *_keymap)
00350 {
00351 key = _key;
00352 keymap = _keymap;
00353 }
00354
00355 bool CL_InputButton_FBDevKeyboard::is_pressed()
00356 {
00357 return keymap[key];
00358 }
00359
00360 #endif