Logo
  • Main Page
  • Related Pages
  • Modules
  • Classes
  • Files

mmsinputmanager.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2005-2007 Stefan Schwarzer, Jens Schneider,             *
00003  *                           Matthias Hardt, Guido Madaus                  *
00004  *                                                                         *
00005  *   Copyright (C) 2007-2008 BerLinux Solutions GbR                        *
00006  *                           Stefan Schwarzer & Guido Madaus               *
00007  *                                                                         *
00008  *   Copyright (C) 2009-2013 BerLinux Solutions GmbH                       *
00009  *                                                                         *
00010  *   Authors:                                                              *
00011  *      Stefan Schwarzer   <stefan.schwarzer@diskohq.org>,                 *
00012  *      Matthias Hardt     <matthias.hardt@diskohq.org>,                   *
00013  *      Jens Schneider     <jens.schneider@diskohq.org>,                   *
00014  *      Guido Madaus       <guido.madaus@diskohq.org>,                     *
00015  *      Patrick Helterhoff <patrick.helterhoff@diskohq.org>,               *
00016  *      René Bählkow       <rene.baehlkow@diskohq.org>                     *
00017  *                                                                         *
00018  *   This library is free software; you can redistribute it and/or         *
00019  *   modify it under the terms of the GNU Lesser General Public            *
00020  *   License version 2.1 as published by the Free Software Foundation.     *
00021  *                                                                         *
00022  *   This library is distributed in the hope that it will be useful,       *
00023  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00024  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00025  *   Lesser General Public License for more details.                       *
00026  *                                                                         *
00027  *   You should have received a copy of the GNU Lesser General Public      *
00028  *   License along with this library; if not, write to the                 *
00029  *   Free Software Foundation, Inc.,                                       *
00030  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
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     //lock mmsfb to ensure inputs are not interrupted by other threads
00067     mmsfb->lock();
00068 
00069     if (inputevent->type == MMSINPUTEVENTTYPE_KEYPRESS) {
00070         /* keyboard inputs */
00071 
00072 #ifdef __ENABLE_DEBUG__
00073         /* check crtl+c and exit */
00074         if((inputevent->key==MMSKEY_SMALL_C)&&(this->lastkey==MMSKEY_CONTROL))
00075             exit(1);
00076 #endif
00077 
00078 /*
00079 #ifdef ROTATE_180
00080         switch (inputevent->key) {
00081         case MMSKEY_CURSOR_LEFT:
00082             inputevent->key = MMSKEY_CURSOR_RIGHT;
00083             break;
00084         case MMSKEY_CURSOR_RIGHT:
00085             inputevent->key = MMSKEY_CURSOR_LEFT;
00086             break;
00087         case MMSKEY_CURSOR_UP:
00088             inputevent->key = MMSKEY_CURSOR_DOWN;
00089             break;
00090         case MMSKEY_CURSOR_DOWN:
00091             inputevent->key = MMSKEY_CURSOR_UP;
00092             break;
00093         default:
00094             break;
00095         }
00096 #endif
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                 /* ok execute input on window */
00128                 window->handleInput(inputevent);
00129                 memset(inputevent, 0, sizeof(MMSInputEvent));
00130                 this->mutex.unlock();
00131                 mmsfb->unlock();
00132                 return;
00133             }
00134         }
00135 
00136         // have to call subscriptions?
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             // go through subscriptions
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                         // ok i found one execute
00153                         subscriptions.at(i)->callback.emit(subscriptions.at(i));
00154                         // stop it only one key per subscription
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         /* keyboard inputs */
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             /* get the window rect and check if the pointer is in there */
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                 /* pointer is not over the window */
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             // save the pointer for release event
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 //      MSG2OUT("MMSINPUTMANAGER", "MMSInputManager:handleInput: BUTTON RELEASED AT: %d,%d", inputevent->posx, inputevent->posy);
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             /* get the window rect and check if the pointer is in there */
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                 /* call windows handleInput with normalized coordinates */
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         // have to call subscriptions?
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             // go through subscriptions
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                         // ok i found one execute
00307                         subscriptions.at(i)->callback.emit(subscriptions.at(i));
00308                         // stop it only one key per subscription
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         /*this->oldx = inputevent->absx;
00324         this->oldy = inputevent->absy;
00325         memset(inputevent, 0, sizeof(MMSInputEvent));
00326         return;
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             /* get the window rect and check if the pointer is in there */
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                 /* pointer is not over the window */
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             //printf("oldx = %d\n", this->oldx);
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 }

Generated by doxygen