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-2012 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 
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     //lock mmsfb to ensure inputs are not interrupted by other threads
00061     mmsfb->lock();
00062 
00063     if (inputevent->type == MMSINPUTEVENTTYPE_KEYPRESS) {
00064         /* keyboard inputs */
00065 
00066 #ifdef __ENABLE_DEBUG__
00067         /* check crtl+c and exit */
00068         if((inputevent->key==MMSKEY_SMALL_C)&&(this->lastkey==MMSKEY_CONTROL))
00069             exit(1);
00070 #endif
00071 
00072 /*
00073 #ifdef ROTATE_180
00074         switch (inputevent->key) {
00075         case MMSKEY_CURSOR_LEFT:
00076             inputevent->key = MMSKEY_CURSOR_RIGHT;
00077             break;
00078         case MMSKEY_CURSOR_RIGHT:
00079             inputevent->key = MMSKEY_CURSOR_LEFT;
00080             break;
00081         case MMSKEY_CURSOR_UP:
00082             inputevent->key = MMSKEY_CURSOR_DOWN;
00083             break;
00084         case MMSKEY_CURSOR_DOWN:
00085             inputevent->key = MMSKEY_CURSOR_UP;
00086             break;
00087         default:
00088             break;
00089         }
00090 #endif
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                 /* ok execute input on window */
00122                 window->handleInput(inputevent);
00123                 memset(inputevent, 0, sizeof(MMSInputEvent));
00124                 this->mutex.unlock();
00125                 mmsfb->unlock();
00126                 return;
00127             }
00128         }
00129 
00130         // have to call subscriptions?
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             // go through subscriptions
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                         // ok i found one execute
00147                         subscriptions.at(i)->callback.emit(subscriptions.at(i));
00148                         // stop it only one key per subscription
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         /* keyboard inputs */
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         //printf("diff %ld\n",diff);
00192         /*if(diff < 130000000) {
00193             memset(inputevent, 0, sizeof(MMSInputEvent));
00194             return;
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             /* 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 }

Generated by doxygen