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