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/mmsinputlishandler.h"
00034 #include "mmsinput/mmsinputlisthread.h"
00035 #include "mmsconfig/mmsconfigdata.h"
00036 #include <cstring>
00037 #include <typeinfo>
00038 #include <sys/ioctl.h>
00039
00040 #include <linux/input.h>
00041
00042
00043 #if defined(__HAVE_FBDEV__) || defined(__HAVE_KMS__)
00044 MMSInputLISHandler::MMSInputLISHandler(MMS_INPUT_DEVICE device) :
00045 devcnt(0),
00046 ie_count(0),
00047 ie_read_pos(0),
00048 ie_write_pos(0) {
00049
00050 getDevices();
00051 for (int i = 0; i < this->devcnt; i++) {
00052 if(this->devices[i].type != MMSINPUTLISHANDLER_DEVTYPE_UNKNOWN) {
00053 MMSInputLISThread *lt = new MMSInputLISThread(this, &this->devices[i]);
00054 if (lt) {
00055 lt->start();
00056 }
00057 }
00058 }
00059 }
00060 #else
00061 MMSInputLISHandler::MMSInputLISHandler(MMS_INPUT_DEVICE device) {
00062 throw MMSError(0,(string)typeid(this).name() + " is empty. compile FBDEV or KMS support!");
00063 }
00064 #endif
00065
00066 MMSInputLISHandler::~MMSInputLISHandler() {
00067 }
00068
00069
00070 #define NUMBITS(x) ((((x)-1)/(sizeof(long)*8))+1)
00071 #define TSTBIT(bit, array) ((array[(bit)/(sizeof(long)*8)] >> ((bit)%(sizeof(long)*8))) & 1)
00072
00073 bool MMSInputLISHandler::checkDevice() {
00074
00075 MMSINPUTLISHANDLER_DEV *dev = &this->devices[this->devcnt];
00076
00077
00078 int fd;
00079 if ((fd = open(dev->name.c_str(), O_RDWR)) < 0)
00080 return false;
00081
00082
00083 if (ioctl(fd, EVIOCGRAB, 1)) {
00084 close(fd);
00085 return false;
00086 }
00087
00088
00089 char devdesc[256];
00090 memset(devdesc, 0, sizeof(devdesc));
00091 ioctl(fd, EVIOCGNAME(sizeof(devdesc)-1), devdesc);
00092 dev->desc = devdesc;
00093 dev->type = MMSINPUTLISHANDLER_DEVTYPE_UNKNOWN;
00094
00095
00096 unsigned int keys = 0;
00097 unsigned long ev_bit[NUMBITS(EV_MAX)];
00098 unsigned long key_bit[NUMBITS(KEY_MAX)];
00099 unsigned long abs_bit[NUMBITS(ABS_MAX)];
00100
00101
00102 ioctl(fd, EVIOCGBIT(0, sizeof(ev_bit)), ev_bit);
00103 if(TSTBIT(EV_KEY, ev_bit)) {
00104 ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bit)), key_bit);
00105 for(int i = KEY_Q; i < KEY_M; i++)
00106 if (TSTBIT(i, key_bit))
00107 keys++;
00108 if(keys > 20 || TSTBIT(KEY_ENTER, key_bit)) {
00109 dev->type = MMSINPUTLISHANDLER_DEVTYPE_KEYBOARD;
00110 } else {
00111 for(int i = KEY_OK; i < KEY_MAX; i++) {
00112 if(TSTBIT(i, key_bit)) {
00113 dev->type = MMSINPUTLISHANDLER_DEVTYPE_REMOTE;
00114 break;
00115 }
00116 }
00117 }
00118 }
00119
00120
00121 if(dev->type == MMSINPUTLISHANDLER_DEVTYPE_UNKNOWN) {
00122 if(ioctl(fd, EVIOCGBIT(EV_ABS, sizeof (abs_bit)), abs_bit) != -1) {
00123 if(TSTBIT(ABS_X, abs_bit) && TSTBIT(ABS_Y, abs_bit)) {
00124 if(TSTBIT(EV_KEY, ev_bit) && (TSTBIT(BTN_LEFT, key_bit) || TSTBIT(BTN_TOUCH, key_bit))) {
00125 dev->touch.haveBtnEvents = true;
00126 dev->type = MMSINPUTLISHANDLER_DEVTYPE_TOUCHSCREEN;
00127 } else if(TSTBIT(ABS_PRESSURE, abs_bit)) {
00128 dev->touch.haveBtnEvents = false;
00129 dev->type = MMSINPUTLISHANDLER_DEVTYPE_TOUCHSCREEN;
00130 }
00131 }
00132 }
00133
00134 if(dev->type == MMSINPUTLISHANDLER_DEVTYPE_TOUCHSCREEN) {
00135 struct input_absinfo abs;
00136 MMSConfigData config;
00137 MMSFBRectangle vRect = config.getVRect();
00138
00139
00140 if(vRect.w <= 0) {
00141 vRect = config.getGraphicsLayer().rect;
00142 }
00143
00144 dev->touch.rect = config.getTouchRect();
00145 dev->touch.swapX = config.getTouchSwapX();
00146 dev->touch.swapY = config.getTouchSwapY();
00147 dev->touch.swapXY = config.getTouchSwapXY();
00148
00149 if(dev->touch.rect.w) {
00150 dev->touch.xFactor = (float)vRect.w / (float)dev->touch.rect.w;
00151 } else if(ioctl(fd, EVIOCGABS(ABS_X), &abs) != -1) {
00152 if(dev->touch.swapXY) {
00153 dev->touch.yFactor = (float)vRect.h / (abs.maximum - abs.minimum);
00154 } else {
00155 dev->touch.xFactor = (float)vRect.w / (abs.maximum - abs.minimum);
00156 }
00157 } else {
00158 dev->touch.xFactor = 1.0;
00159 }
00160 if(dev->touch.rect.h) {
00161 dev->touch.yFactor = (float)vRect.h / (float)dev->touch.rect.h;
00162 } else if(ioctl(fd, EVIOCGABS(ABS_Y), &abs) != -1) {
00163 if(dev->touch.swapXY) {
00164 dev->touch.xFactor = (float)vRect.w / (abs.maximum - abs.minimum);
00165 } else {
00166 dev->touch.yFactor = (float)vRect.h / (abs.maximum - abs.minimum);
00167 }
00168 } else {
00169 dev->touch.yFactor = 1.0;
00170 }
00171 }
00172 }
00173
00174 printf("Found %s, type=%s (%s)\n",
00175 dev->name.c_str(),
00176 dev->type.c_str(),
00177 dev->desc.c_str());
00178
00179
00180 ioctl(fd, EVIOCGRAB, 0);
00181 close(fd);
00182
00183 return true;
00184 }
00185
00186 void MMSInputLISHandler::getDevices() {
00187 for (int i = 0; i < MMSINPUTLISHANDLER_MAX_DEVICES; i++) {
00188 this->devices[this->devcnt].name = "/dev/input/event" + iToStr(i);
00189 if (checkDevice())
00190 this->devcnt++;
00191 }
00192 }
00193
00194 bool MMSInputLISHandler::addEvent(MMSInputEvent *inputevent) {
00195 this->lock.lock();
00196
00197
00198 while(this->ie_count == (MMSINPUTLISHANDLER_EVENT_BUFFER_SIZE - 1)) {
00199 usleep(10000);
00200 }
00201
00202 this->ie_buffer[this->ie_write_pos] = *inputevent;
00203
00204
00205 this->ie_count++;
00206
00207
00208 this->ie_write_pos++;
00209 if(this->ie_write_pos >= MMSINPUTLISHANDLER_EVENT_BUFFER_SIZE)
00210 this->ie_write_pos = 0;
00211
00212 this->lock.unlock();
00213 return true;
00214 }
00215
00216 void MMSInputLISHandler::grabEvents(MMSInputEvent *inputevent) {
00217 #if defined(__HAVE_FBDEV__) || defined(__HAVE_KMS__)
00218
00219 while(this->ie_count == 0) {
00220 usleep(10000);
00221 }
00222
00223
00224 *inputevent = this->ie_buffer[this->ie_read_pos];
00225
00226
00227 this->ie_count--;
00228
00229
00230 this->ie_read_pos++;
00231 if (this->ie_read_pos >= MMSINPUTLISHANDLER_EVENT_BUFFER_SIZE)
00232 this->ie_read_pos = 0;
00233 #else
00234 throw MMSError(0,(string)typeid(this).name() + " is empty. compile FBDEV or KMS support!");
00235 #endif
00236 }
00237