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

keyboard_fbdev.cpp

Go to the documentation of this file.
00001 /*
00002         $Id: keyboard_fbdev.cpp,v 1.1 2001/03/06 15:09:20 mbn 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 #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   Keyboard
00068 ******************/
00069 
00070 CL_FBDevKeyboard::CL_FBDevKeyboard()
00071 {
00072         memset( &keymap, 0, sizeof(keymap) );
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_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         // Read keyboard data
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         //fetch the keycode
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 /*axis_num*/)
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 /*hat_num*/)
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 /*cursor_num*/)
00340 {
00341         return NULL;
00342 }
00343 
00344 /***************************
00345   CL_InputButton_FBDevKeyboard
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

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