Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

keyboard_tty.cpp

Go to the documentation of this file.
00001 /*
00002         $Id: keyboard_tty.cpp,v 1.3 2001/03/13 21:43:01 sphair Exp $
00003 
00004         ------------------------------------------------------------------------
00005         ClanLib, the platform independent game SDK.
00006 
00007         This library is distributed under the GNU LIBRARY GENERAL PUBLIC LICENSE
00008         version 2. See COPYING for details.
00009 
00010         For a total list of contributers see CREDITS.
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   Keyboard
00066 ******************/
00067 
00068 CL_TTYKeyboard::CL_TTYKeyboard()
00069 {
00070         memset( &keymap, 0, sizeof(keymap) );
00071 
00072 //      CL_System_Generic::keep_alives.add(this);
00073 
00074         /* open the tty */
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         /* put tty into "straight through" mode. */
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         /* save old mode and set to mediumraw */
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         /* save old kd mode and set to graphics */
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 //      CL_System_Generic::keep_alives.del(this);
00132         restore();
00133 /*      why???
00134 #ifdef USE_FBDEV
00135         CL_Implementation_FBDev::clean_up();
00136 #endif
00137 */
00138 //      int num = buttons.get_num_items();
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         // Read keyboard data
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         //fetch the keycode
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 /*axis_num*/)
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 /*hat_num*/)
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 /*cursor_num*/)
00341 {
00342         return NULL;
00343 }
00344 
00345 /***************************
00346   CL_InputButton_TTYKeyboard
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

Generated at Wed Apr 4 19:54:01 2001 for ClanLib by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001