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 #include "mmsbase/mmseventsignup.h"
00035
00036 #ifndef __LIS_DEBUG__
00037 #undef MSG2OUT
00038 #define MSG2OUT(ident, msg...)
00039 #endif
00040
00041 MMSInputManager::MMSInputManager(string file, string name) {
00042 this->mapper = new MMSInputMapper(file, name);
00043 this->config = new MMSConfigData();
00044 this->buttonpress_window = NULL;
00045 this->button_pressed = false;
00046 clock_gettime(CLOCK_REALTIME,&this->lastinput);
00047
00048 MMSEventSignup *sign = new MMSEventSignup();
00049 sign->add("MMSINPUTEVENT");
00050 sign->getSignal()->connect(sigc::mem_fun(this, &MMSInputManager::onEvent));
00051 sign->executeSignup();
00052 }
00053
00054 MMSInputManager::~MMSInputManager() {
00055 this->threads.clear();
00056 this->subscriptions.clear();
00057 if(this->mapper) delete this->mapper;
00058 if(this->config) delete this->config;
00059 }
00060
00061 void MMSInputManager::handleInput(MMSInputEvent *inputevent) {
00062 MMSWindow *window=NULL;
00063
00064 this->mutex.lock();
00065
00066
00067 mmsfb->lock();
00068
00069 if (inputevent->type == MMSINPUTEVENTTYPE_KEYPRESS) {
00070
00071
00072 #ifdef __ENABLE_DEBUG__
00073
00074 if((inputevent->key==MMSKEY_SMALL_C)&&(this->lastkey==MMSKEY_CONTROL))
00075 exit(1);
00076 #endif
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 this->lastkey = inputevent->key;
00100
00101 this->mapper->mapkey(inputevent);
00102
00103 #if __ENABLE_LOG__ || __ENABLE_DEBUG__
00104 string symbol = mmskeys[inputevent->key];
00105 TRACEOUT("MMSINPUT", "KEY PRESS %d (MMSKEY_%s)", this->lastkey, symbol.c_str());
00106 if(lastkey != inputevent->key) {
00107 symbol = mmskeys[inputevent->key];
00108 TRACEOUT("MMSINPUT", " >MAPPED TO %d (MMSKEY_%s)", inputevent->key, symbol.c_str());
00109 }
00110 #endif
00111
00112 if((inputevent->key==MMSKEY_POWER)||(inputevent->key==MMSKEY_POWER2)) {
00113 if(config->getShutdown() == true) {
00114 DEBUGMSG("MMSINPUTMANAGER", "executing: %s", config->getShutdownCmd().c_str());
00115
00116 executeCmd(config->getShutdownCmd());
00117 sleep(30);
00118 }
00119 exit(0);
00120 }
00121
00122 window = this->windowmanager->getToplevelWindow();
00123
00124 if(window!=NULL) {
00125 if ((inputevent->key==MMSKEY_CURSOR_DOWN)||(inputevent->key==MMSKEY_CURSOR_UP)
00126 ||(inputevent->key==MMSKEY_CURSOR_LEFT)||(inputevent->key==MMSKEY_CURSOR_RIGHT)) {
00127
00128 window->handleInput(inputevent);
00129 memset(inputevent, 0, sizeof(MMSInputEvent));
00130 this->mutex.unlock();
00131 mmsfb->unlock();
00132 return;
00133 }
00134 }
00135
00136
00137 bool call_subscriptions = true;
00138 if (window) {
00139 bool modal = false;
00140 window->getModal(modal);
00141 if (modal)
00142 call_subscriptions = false;
00143 }
00144
00145 if (call_subscriptions) {
00146
00147 for(unsigned int i = 0; i < subscriptions.size();i++) {
00148 MMSKeySymbol key;
00149 if (subscriptions.at(i)->getKey(key)) {
00150 if (key == inputevent->key) {
00151 DEBUGMSG("MMSINPUTMANAGER", "found a subscription");
00152
00153 subscriptions.at(i)->callback.emit(subscriptions.at(i));
00154
00155 DEBUGMSG("MMSINPUTMANAGER", "returning from handle input");
00156 mmsfb->unlock();
00157 this->mutex.unlock();
00158 return;
00159 }
00160 }
00161 }
00162 }
00163
00164 if(window != NULL)
00165 window->handleInput(inputevent);
00166 memset(inputevent, 0, sizeof(MMSInputEvent));
00167 }
00168 else
00169 if (inputevent->type == MMSINPUTEVENTTYPE_KEYRELEASE) {
00170
00171 #if __ENABLE_LOG__ || __ENABLE_DEBUG__
00172 string symbol = mmskeys[inputevent->key];
00173 TRACEOUT("MMSINPUT", "KEY RELEASE %d (MMSKEY_%s)", this->lastkey, symbol.c_str());
00174 #endif
00175 MMSKeySymbol beforemap = inputevent->key;
00176 this->mapper->mapkey(inputevent);
00177 #if __ENABLE_LOG__ || __ENABLE_DEBUG__
00178 if(inputevent->key != beforemap) {
00179 symbol = mmskeys[inputevent->key];
00180 TRACEOUT("MMSINPUT", " >MAPPED TO %d (MMSKEY_%s)", inputevent->key, symbol.c_str());
00181 }
00182 #endif
00183
00184 window = this->windowmanager->getToplevelWindow();
00185
00186 if(window != NULL)
00187 window->handleInput(inputevent);
00188 memset(inputevent, 0, sizeof(MMSInputEvent));
00189 }
00190 else
00191 if (inputevent->type == MMSINPUTEVENTTYPE_BUTTONPRESS) {
00192 DEBUGMSG("MMSINPUTMANAGER", "MMSInputManager:handleInput: BUTTON PRESSED AT: %d,%d", inputevent->posx, inputevent->posy);
00193 MSG2OUT("MMSINPUTMANAGER", "MMSInputManager:handleInput: BUTTON PRESSED AT: %d,%d", inputevent->posx, inputevent->posy);
00194 struct timespec ts;
00195 clock_gettime(CLOCK_REALTIME,&ts);
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 }
00408
00409 void MMSInputManager::onEvent(_IMMSEvent *event) {
00410 string heading = event->getHeading();
00411
00412 MMSInputEvent inputevent;
00413 memset(&inputevent, 0, sizeof(MMSInputEvent));
00414
00415 if (heading == "MMSINPUTEVENT.KEYPRESS") {
00416 MMSKeyMap km;
00417 inputevent.type = MMSINPUTEVENTTYPE_KEYPRESS;
00418 inputevent.key = km[event->getData("key").c_str()];
00419 handleInput(&inputevent);
00420 }
00421 else
00422 if (heading == "MMSINPUTEVENT.KEYRELEASE") {
00423 MMSKeyMap km;
00424 inputevent.type = MMSINPUTEVENTTYPE_KEYRELEASE;
00425 inputevent.key = km[event->getData("key").c_str()];
00426 handleInput(&inputevent);
00427 }
00428 else {
00429 inputevent.posx = atoi(event->getData("posx").c_str());
00430 inputevent.posy = atoi(event->getData("posy").c_str());
00431 inputevent.dx = 0;
00432 inputevent.dy = 0;
00433 inputevent.absx = 0;
00434 inputevent.absy = 0;
00435
00436 if (heading == "MMSINPUTEVENT.BUTTONPRESS") {
00437 inputevent.type = MMSINPUTEVENTTYPE_BUTTONPRESS;
00438 handleInput(&inputevent);
00439 }
00440 else
00441 if (heading == "MMSINPUTEVENT.BUTTONRELEASE") {
00442 inputevent.type = MMSINPUTEVENTTYPE_BUTTONRELEASE;
00443 handleInput(&inputevent);
00444 }
00445 else
00446 if (heading == "MMSINPUTEVENT.AXISMOTION") {
00447 inputevent.type = MMSINPUTEVENTTYPE_AXISMOTION;
00448 handleInput(&inputevent);
00449 }
00450 }
00451 }