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