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
00028
00029
00030
00031
00032
00033 #include "mmsinput/mmsinputmanager.h"
00034
00035 #ifndef __LIS_DEBUG__
00036 #undef MSG2OUT
00037 #define MSG2OUT(ident, msg...)
00038 #endif
00039
00040 MMSInputManager::MMSInputManager(string file, string name) {
00041 this->mapper = new MMSInputMapper(file, name);
00042 this->config = new MMSConfigData();
00043 this->buttonpress_window = NULL;
00044 this->button_pressed = false;
00045 clock_gettime(CLOCK_REALTIME,&this->lastinput);
00046 }
00047
00048 MMSInputManager::~MMSInputManager() {
00049 this->threads.clear();
00050 this->subscriptions.clear();
00051 if(this->mapper) delete this->mapper;
00052 if(this->config) delete this->config;
00053 }
00054
00055 void MMSInputManager::handleInput(MMSInputEvent *inputevent) {
00056 MMSWindow *window=NULL;
00057
00058 this->mutex.lock();
00059
00060
00061 mmsfb->lock();
00062
00063 if (inputevent->type == MMSINPUTEVENTTYPE_KEYPRESS) {
00064
00065
00066 #ifdef __ENABLE_DEBUG__
00067
00068 if((inputevent->key==MMSKEY_SMALL_C)&&(this->lastkey==MMSKEY_CONTROL))
00069 exit(1);
00070 #endif
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 this->lastkey = inputevent->key;
00094
00095 this->mapper->mapkey(inputevent);
00096
00097 #if __ENABLE_LOG__ || __ENABLE_DEBUG__
00098 string symbol = mmskeys[inputevent->key];
00099 TRACEOUT("MMSINPUT", "KEY PRESS %d (MMSKEY_%s)", this->lastkey, symbol.c_str());
00100 if(lastkey != inputevent->key) {
00101 symbol = mmskeys[inputevent->key];
00102 TRACEOUT("MMSINPUT", " >MAPPED TO %d (MMSKEY_%s)", inputevent->key, symbol.c_str());
00103 }
00104 #endif
00105
00106 if((inputevent->key==MMSKEY_POWER)||(inputevent->key==MMSKEY_POWER2)) {
00107 if(config->getShutdown() == true) {
00108 DEBUGMSG("MMSINPUTMANAGER", "executing: %s", config->getShutdownCmd().c_str());
00109
00110 executeCmd(config->getShutdownCmd());
00111 sleep(30);
00112 }
00113 exit(0);
00114 }
00115
00116 window = this->windowmanager->getToplevelWindow();
00117
00118 if(window!=NULL) {
00119 if ((inputevent->key==MMSKEY_CURSOR_DOWN)||(inputevent->key==MMSKEY_CURSOR_UP)
00120 ||(inputevent->key==MMSKEY_CURSOR_LEFT)||(inputevent->key==MMSKEY_CURSOR_RIGHT)) {
00121
00122 window->handleInput(inputevent);
00123 memset(inputevent, 0, sizeof(MMSInputEvent));
00124 this->mutex.unlock();
00125 mmsfb->unlock();
00126 return;
00127 }
00128 }
00129
00130
00131 bool call_subscriptions = true;
00132 if (window) {
00133 bool modal = false;
00134 window->getModal(modal);
00135 if (modal)
00136 call_subscriptions = false;
00137 }
00138
00139 if (call_subscriptions) {
00140
00141 for(unsigned int i = 0; i < subscriptions.size();i++) {
00142 MMSKeySymbol key;
00143 if (subscriptions.at(i)->getKey(key)) {
00144 if (key == inputevent->key) {
00145 DEBUGMSG("MMSINPUTMANAGER", "found a subscription");
00146
00147 subscriptions.at(i)->callback.emit(subscriptions.at(i));
00148
00149 DEBUGMSG("MMSINPUTMANAGER", "returning from handle input");
00150 mmsfb->unlock();
00151 this->mutex.unlock();
00152 return;
00153 }
00154 }
00155 }
00156 }
00157
00158 if(window != NULL)
00159 window->handleInput(inputevent);
00160 memset(inputevent, 0, sizeof(MMSInputEvent));
00161 }
00162 else
00163 if (inputevent->type == MMSINPUTEVENTTYPE_KEYRELEASE) {
00164
00165 #if __ENABLE_LOG__ || __ENABLE_DEBUG__
00166 string symbol = mmskeys[inputevent->key];
00167 TRACEOUT("MMSINPUT", "KEY RELEASE %d (MMSKEY_%s)", this->lastkey, symbol.c_str());
00168 #endif
00169 MMSKeySymbol beforemap = inputevent->key;
00170 this->mapper->mapkey(inputevent);
00171 #if __ENABLE_LOG__ || __ENABLE_DEBUG__
00172 if(inputevent->key != beforemap) {
00173 symbol = mmskeys[inputevent->key];
00174 TRACEOUT("MMSINPUT", " >MAPPED TO %d (MMSKEY_%s)", inputevent->key, symbol.c_str());
00175 }
00176 #endif
00177
00178 window = this->windowmanager->getToplevelWindow();
00179
00180 if(window != NULL)
00181 window->handleInput(inputevent);
00182 memset(inputevent, 0, sizeof(MMSInputEvent));
00183 }
00184 else
00185 if (inputevent->type == MMSINPUTEVENTTYPE_BUTTONPRESS) {
00186 DEBUGMSG("MMSINPUTMANAGER", "MMSInputManager:handleInput: BUTTON PRESSED AT: %d,%d", inputevent->posx, inputevent->posy);
00187 MSG2OUT("MMSINPUTMANAGER", "MMSInputManager:handleInput: BUTTON PRESSED AT: %d,%d", inputevent->posx, inputevent->posy);
00188 struct timespec ts;
00189 clock_gettime(CLOCK_REALTIME,&ts);
00190 int64_t diff = timespecDiff(&ts, &this->lastinput);
00191
00192
00193
00194
00195
00196 clock_gettime(CLOCK_REALTIME,&this->lastinput);
00197
00198 this->button_pressed = true;
00199 this->windowmanager->setPointerPosition(inputevent->posx, inputevent->posy, true);
00200
00201 this->oldx = inputevent->posx;
00202 this->oldy = inputevent->posy;
00203 window = this->windowmanager->getToplevelWindow();
00204 if (window) {
00205
00206 MMSFBRectangle rect = window->getGeometry();
00207
00208 if ((inputevent->posx - rect.x < 0)||(inputevent->posy - rect.y < 0)
00209 ||(inputevent->posx - rect.x - rect.w >= 0)||(inputevent->posy - rect.y - rect.h >= 0)) {
00210
00211 DEBUGMSG("MMSINPUTMANAGER", "MMSInputManager:handleInput: BUTTON PRESSED, NOT OVER THE WINDOW");
00212 MSG2OUT("MMSINPUTMANAGER", "MMSInputManager:handleInput: BUTTON PRESSED, NOT OVER THE WINDOW");
00213
00214 mmsfb->unlock();
00215 this->mutex.unlock();
00216 memset(inputevent, 0, sizeof(MMSInputEvent));
00217 return;
00218 }
00219 if(inputevent->posx < 0 || inputevent->posy<0) {
00220 inputevent->absx = this->oldx;
00221 inputevent->absy = this->oldy;
00222 } else {
00223 this->oldx = inputevent->posx;
00224 this->oldy = inputevent->posy;
00225 }
00226
00227
00228
00229 this->buttonpress_window = window;
00230
00231 inputevent->absx = inputevent->posx;
00232 inputevent->absy = inputevent->posy;
00233 inputevent->posx-= rect.x;
00234 inputevent->posy-= rect.y;
00235 inputevent->dx = 0;
00236 inputevent->dy = 0;
00237
00238 window->handleInput(inputevent);
00239 memset(inputevent, 0, sizeof(MMSInputEvent));
00240 }
00241 }
00242 else
00243 if (inputevent->type == MMSINPUTEVENTTYPE_BUTTONRELEASE) {
00244 DEBUGMSG("MMSINPUTMANAGER", "MMSInputManager:handleInput: BUTTON RELEASED AT: %d,%d", inputevent->posx, inputevent->posy);
00245
00246 this->button_pressed = false;
00247
00248 this->windowmanager->setPointerPosition(inputevent->posx, inputevent->posy, false);
00249
00250 window = this->windowmanager->getToplevelWindow();
00251 if (!window)
00252 window = this->buttonpress_window;
00253 if (window) {
00254
00255 MMSFBRectangle rect = window->getGeometry();
00256
00257 if ((window == this->buttonpress_window)
00258 || ((this->buttonpress_window)
00259 &&(inputevent->posx - rect.x >= 0)&&(inputevent->posy - rect.y >= 0)
00260 && (inputevent->posx - rect.x - rect.w < 0)&&(inputevent->posy - rect.y - rect.h < 0))) {
00261
00262
00263 if(inputevent->posx < 0 || inputevent->posy<0) {
00264 inputevent->absx = this->oldx;
00265 inputevent->absy = this->oldy;
00266 }
00267 inputevent->absx = inputevent->posx;
00268 inputevent->absy = inputevent->posy;
00269 inputevent->posx-= rect.x;
00270 inputevent->posy-= rect.y;
00271 inputevent->dx = inputevent->absx - this->oldx;
00272 inputevent->dy = inputevent->absy - this->oldy;
00273
00274 this->oldx = -1;
00275 this->oldy = -1;
00276
00277 if (window->handleInput(inputevent)) {
00278 this->buttonpress_window = NULL;
00279 memset(inputevent, 0, sizeof(MMSInputEvent));
00280 mmsfb->unlock();
00281 this->mutex.unlock();
00282 return;
00283 }
00284 }
00285 }
00286 this->buttonpress_window = NULL;
00287
00288
00289
00290 bool call_subscriptions = true;
00291 if (window) {
00292 bool modal = false;
00293 window->getModal(modal);
00294 if (modal)
00295 call_subscriptions = false;
00296 }
00297
00298 if (call_subscriptions) {
00299
00300 for(unsigned int i = 0; i < subscriptions.size();i++) {
00301 MMSFBRectangle pointer_area;
00302 if (subscriptions.at(i)->getPointerArea(pointer_area)) {
00303 if ((inputevent->posx >= pointer_area.x)&&(inputevent->posy >= pointer_area.y)
00304 &&(inputevent->posx < pointer_area.x + pointer_area.w)&&(inputevent->posy < pointer_area.y + pointer_area.h)) {
00305 DEBUGMSG("MMSINPUTMANAGER", "found a subscription");
00306
00307 subscriptions.at(i)->callback.emit(subscriptions.at(i));
00308
00309 DEBUGMSG("MMSINPUTMANAGER", "returning from handle input");
00310 memset(inputevent, 0, sizeof(MMSInputEvent));
00311 mmsfb->unlock();
00312 this->mutex.unlock();
00313 return;
00314 }
00315 }
00316 }
00317 }
00318
00319 }
00320 else
00321 if (inputevent->type == MMSINPUTEVENTTYPE_AXISMOTION) {
00322
00323
00324
00325
00326
00327
00328
00329
00330 this->windowmanager->setPointerPosition(inputevent->posx, inputevent->posy, this->button_pressed);
00331
00332
00333 window = this->windowmanager->getToplevelWindow();
00334 if (window) {
00335
00336 MMSFBRectangle rect = window->getGeometry();
00337
00338 if ((inputevent->posx - rect.x < 0)||(inputevent->posy - rect.y < 0)
00339 ||(inputevent->posx - rect.x - rect.w >= 0)||(inputevent->posy - rect.y - rect.h >= 0)) {
00340
00341 mmsfb->unlock();
00342 this->mutex.unlock();
00343 return;
00344 }
00345
00346 inputevent->absx = inputevent->posx;
00347 inputevent->absy = inputevent->posy;
00348 inputevent->posx-=rect.x;
00349 inputevent->posy-=rect.y;
00350 if(this->button_pressed) {
00351 inputevent->dx = inputevent->absx - this->oldx;
00352 inputevent->dy = inputevent->absy - this->oldy;
00353 } else {
00354 inputevent->dx = 0;
00355 inputevent->dy = 0;
00356 }
00357
00358 if(this->oldx == inputevent->absx && this->oldy == inputevent->absy) {
00359
00360 memset(inputevent, 0, sizeof(MMSInputEvent));
00361 mmsfb->unlock();
00362 this->mutex.unlock();
00363 return;
00364 }
00365
00366 fflush(stdout);
00367 this->oldx = inputevent->absx;
00368 this->oldy = inputevent->absy;
00369
00370
00371 window->handleInput(inputevent);
00372 memset(inputevent, 0, sizeof(MMSInputEvent));
00373 }
00374 }
00375
00376 mmsfb->unlock();
00377 this->mutex.unlock();
00378 }
00379
00380 void MMSInputManager::addDevice(MMS_INPUT_DEVICE device, int inputinterval) {
00381 MMSInputThread *thread = new MMSInputThread(this, device, inputinterval);
00382
00383 this->threads.push_back(thread);
00384
00385 }
00386
00387 void MMSInputManager::setWindowManager(IMMSWindowManager *wm) {
00388 this->windowmanager = wm;
00389
00390 }
00391
00392 void MMSInputManager::startListen() {
00393 for(unsigned int i=0; i<this->threads.size();i++) {
00394 this->threads.at(i)->start();
00395 }
00396 }
00397
00398 void MMSInputManager::stopListen() {
00399 for(unsigned int i=0; i<this->threads.size();i++) {
00400 this->threads.at(i)->cancel();
00401 }
00402 }
00403
00404
00405 void MMSInputManager::addSubscription(class MMSInputSubscription *sub) {
00406 this->subscriptions.push_back(sub);
00407 }