00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "ArExport.h"
00028 #include "ariaOSDef.h"
00029 #include "ArKeyHandler.h"
00030 #include "ArLog.h"
00031
00032 #ifdef WIN32
00033 #include <conio.h>
00034 #else // if not win32
00035 #include <stdio.h>
00036 #endif
00037
00038 #include "ArRobot.h"
00039 #include "ariaInternal.h"
00040
00047 ArKeyHandler::ArKeyHandler(bool blocking, bool addAriaExitCB) :
00048 myAriaExitCB(this, &ArKeyHandler::restore)
00049 {
00050 myAriaExitCB.setName("ArKeyHandlerExit");
00051 if (addAriaExitCB)
00052 Aria::addExitCallback(&myAriaExitCB);
00053 takeKeys(blocking);
00054 }
00055
00056 ArKeyHandler::~ArKeyHandler()
00057 {
00058 restore();
00059 }
00060
00061 void ArKeyHandler::takeKeys(bool blocking)
00062 {
00063 myBlocking = blocking;
00064 #ifndef WIN32
00065 struct termios newTermios;
00066
00067 tcgetattr(fileno(stdin), &myOriginalTermios);
00068
00069 tcgetattr(fileno(stdin), &newTermios);
00070
00071 newTermios.c_cc[VTIME] = 0;
00072 if (myBlocking)
00073 newTermios.c_cc[VMIN] = 1;
00074 else
00075 newTermios.c_cc[VMIN] = 0;
00076 newTermios.c_lflag &= (~ECHO & ~ICANON);
00077 tcsetattr(fileno(stdin), TCSANOW, &newTermios);
00078
00079 #endif
00080 myRestored = false;
00081 }
00082
00083 void ArKeyHandler::restore(void)
00084 {
00085 #ifndef WIN32
00086 tcsetattr(fileno(stdin), TCSANOW, &myOriginalTermios);
00087
00088 #endif
00089 myRestored = true;
00090 }
00091
00103 bool ArKeyHandler::addKeyHandler(int keyToHandle, ArFunctor *functor)
00104 {
00105 if (myMap.find(keyToHandle) != myMap.end())
00106 {
00107 ArLog::log(ArLog::Normal, "There is already a key to handle '%c' which is number %d 0x%x", keyToHandle, keyToHandle, keyToHandle);
00108 return false;
00109 }
00110
00111
00112 myMap[keyToHandle] = functor;
00113
00114 return true;
00115 }
00116
00125 bool ArKeyHandler::remKeyHandler(int keyToHandle)
00126 {
00127 if (myMap.find(keyToHandle) == myMap.end())
00128 {
00129
00130 return false;
00131 }
00132 ArLog::log(ArLog::Verbose, "keyhandler %p removed key '%c' number '%d'",
00133 this, keyToHandle, keyToHandle);
00134 myMap.erase(keyToHandle);
00135 return true;
00136 }
00137
00145 bool ArKeyHandler::remKeyHandler(ArFunctor *functor)
00146 {
00147 std::map<int, ArFunctor *>::iterator it;
00148 std::list<std::map<int, ArFunctor *>::iterator> iters;
00149 std::list<std::map<int, ArFunctor *>::iterator>::iterator iterIter;
00150
00151 for (it = myMap.begin(); it != myMap.end(); ++it)
00152 {
00153 if (it->second == functor)
00154 {
00155 iters.push_front(it);
00156 }
00157 }
00158 if (iters.size() > 0)
00159 {
00160 while((iterIter = iters.begin()) != iters.end())
00161 {
00162 myMap.erase((*iterIter));
00163 iters.pop_front();
00164 }
00165 ArLog::log(ArLog::Verbose, "keyhandler %p removed functor %p", this,
00166 functor);
00167 return true;
00168 }
00169 return false;
00170 }
00171
00172 void ArKeyHandler::checkKeys(void)
00173 {
00174 int key;
00175 std::map<int, ArFunctor *>::iterator it;
00176
00177 if (myRestored)
00178 return;
00179
00180
00181 while (!myRestored && (key = getKey()) != -1)
00182 {
00183
00184 if ((it = myMap.find(key)) != myMap.end())
00185 {
00186
00187 it->second->invoke();
00188 }
00189 }
00190 }
00191
00192 #ifndef WIN32
00193
00194 int ArKeyHandler::getKey(void)
00195 {
00196
00197
00198
00199
00200
00201 int key;
00202 int k[5] = {-1, -1, -1, -1, -1};
00203
00204 key = getchar();
00205 switch(key)
00206 {
00207 case -1:
00208 case 0:
00209 return -1;
00210
00211
00212 case ' ': return SPACE;
00213 case '\t': return TAB;
00214 case 10: return ENTER;
00215 case 8: return BACKSPACE;
00216 case 127: return BACKSPACE;
00217
00218 case 27:
00219 key = getchar();
00220 switch(key)
00221 {
00222 case -1: return ESCAPE;
00223 case 79:
00224 key = getchar();
00225 switch(key)
00226 {
00227 case 80: return F1;
00228 case 81: return F2;
00229 case 82: return F3;
00230 case 83: return F4;
00231 case 70: return END;
00232 case 72: return HOME;
00233 default: return key;
00234 }
00235 case '[':
00236
00237
00238
00239
00240
00241 for(short i = 0; key != -1 && key != 27 && i < 5; i++)
00242 {
00243 k[i] = key = getchar();
00244
00245 }
00246 ungetc(key, stdin);
00247
00248 switch(k[0])
00249 {
00250 case 65: return UP;
00251 case 66: return DOWN;
00252 case 67: return RIGHT;
00253 case 68: return LEFT;
00254
00255 case 51: return DEL;
00256 case 53: return PAGEUP;
00257 case 54: return PAGEDOWN;
00258
00259 case 50:
00260 switch(k[1])
00261 {
00262 case 126: return INSERT;
00263 case 48: return F9;
00264 case 49: return F10;
00265 case 51: return F11;
00266 case 52: return F12;
00267 }
00268 return k[1];
00269
00270
00271 case 49:
00272 switch(k[1])
00273 {
00274 case 53: return F5;
00275 case 55: return F6;
00276 case 56: return F7;
00277 case 57: return F8;
00278 }
00279 return k[1];
00280 default: return -1;
00281 }
00282 default: return -1;
00283 }
00284
00285 default: return key;
00286 }
00287 }
00288
00289 #if 0
00290
00291
00292 int ArKeyHandler::getKey(void)
00293 {
00294 char key;
00295
00296 key = getchar();
00297 if (key == -1 || key == 0)
00298 return -1;
00299
00300 if (key == 27)
00301 {
00302 key = getchar();
00303 if (key == '[')
00304 {
00305 key = getchar();
00306 if (key == 'A')
00307 return UP;
00308 else if (key == 'B')
00309 return DOWN;
00310 else if (key == 'C')
00311 return RIGHT;
00312 else if (key == 'D')
00313 return LEFT;
00314 else
00315 return getKey();
00316 }
00317 else if (key == -1)
00318 return ESCAPE;
00319 else if (key == 79)
00320 {
00321 key = getchar();
00322 if (key == 'P')
00323 return F1;
00324 else if (key == 'Q')
00325 return F2;
00326 else if (key == 'R')
00327 return F3;
00328 else if (key == 'S')
00329 return F4;
00330 else
00331 return getKey();
00332 }
00333 }
00334 else if (key == ' ')
00335 return SPACE;
00336 else if (key == '\t')
00337 return TAB;
00338 else if (key == 10)
00339 return ENTER;
00340 else if (key == 8 || key == 127)
00341 return BACKSPACE;
00342 return key;
00343 }
00344 #endif
00345
00346
00347 #else
00348
00349 int ArKeyHandler::getKey(void)
00350 {
00351 int key;
00352
00353 if (!myBlocking && !kbhit())
00354 return -1;
00355
00356 key = _getch();
00357 if (key == 224)
00358 {
00359 key = _getch();
00360 if (key == 'H')
00361 return UP;
00362 else if (key == 'P')
00363 return DOWN;
00364 else if (key == 'K')
00365 return LEFT;
00366 else if (key == 'M')
00367 return RIGHT;
00368 else
00369 return getKey();
00370 }
00371 else if (key == 0)
00372 {
00373 key = _getch();
00374 if (key == ';')
00375 return F1;
00376 else if (key == '<')
00377 return F2;
00378 else if (key == '=')
00379 return F3;
00380 else if (key == '>')
00381 return F4;
00382 else if (key == 'H')
00383 return UP;
00384 else if (key == 'P')
00385 return DOWN;
00386 else if (key == 'K')
00387 return LEFT;
00388 else if (key == 'M')
00389 return RIGHT;
00390 else
00391 return getKey();
00392 }
00393 else if (key == ' ')
00394 return SPACE;
00395 else if (key == '\t')
00396 return TAB;
00397 else if (key == 13)
00398 return ENTER;
00399 else if (key == 8)
00400 return BACKSPACE;
00401 else if (key == 27)
00402 return ESCAPE;
00403
00404 return key;
00405
00406 }
00407
00408 #endif
00409