📄 qwsmouse_qws.cpp
字号:
int fd; fd = open( "/dev/psaux", O_RDWR | O_NDELAY ); if ( fd >= 0 ) { sub[nsub++] = new QAutoMouseSubHandler_intellimouse(fd); notify(fd); }#if !defined(QT_QWS_IPAQ) && !defined(QT_QWS_EBX) char fn[] = "/dev/ttyS?"; for (int ch='0'; ch<='3'; ch++) { fn[9] = ch; fd = open( fn, O_RDWR | O_NDELAY ); if ( fd >= 0 ) { //sub[nsub++] = new QAutoMouseSubHandler_intellimouse(fd); sub[nsub++] = new QAutoMouseSubHandler_mousesystems(fd); sub[nsub++] = new QAutoMouseSubHandler_ms(fd); notify(fd); } }#endif // ...}void QAutoMouseHandler::closeDevices(){ int pfd=-1; for (int i=0; i<nsub; i++) { sub[i]->closeIfNot(pfd); delete sub[i]; } notifiers.clear();}void QAutoMouseHandler::notify(int fd){ QSocketNotifier *mouseNotifier = new QSocketNotifier( fd, QSocketNotifier::Read, this ); connect(mouseNotifier, SIGNAL(activated(int)),this, SLOT(readMouseData(int))); notifiers.append( mouseNotifier );}void QAutoMouseHandler::readMouseData(int fd){ for (;;) { uchar buf[8]; int n = read(fd, buf, 8); if ( n<=0 ) break; for (int i=0; i<nsub; i++) { QAutoMouseSubHandler& h = *sub[i]; if ( h.file() == fd ) { h.appendData(buf,n); for (;;) { switch ( h.useData() ) { case QAutoMouseSubHandler::Button: sendEvent(h); case QAutoMouseSubHandler::Insufficient: goto breakbreak; case QAutoMouseSubHandler::Motion: break; } } breakbreak: ; } } } bool any_reliable=FALSE; for (int i=0; i<nsub; i++) { QAutoMouseSubHandler& h = *sub[i]; if ( h.motionPending() ) sendEvent(h); any_reliable = any_reliable || h.reliable(); } if ( any_reliable ) { // ... get rid of all unreliable ones? All bad ones? } else if ( retries < 2 ) { // Try again - maybe the mouse was being moved when we tried to init. closeDevices(); openDevices(); retries++; }}/* * Standard mouse driver */typedef struct { int bytesPerPacket;} MouseData;static const MouseData mouseData[] = { { 3 }, // dummy for auto protocal, correction made by add by YYD { 3 }, // MouseMan { 4 }, // intelliMouse { 3 }, // Microsoft { 0 }, // QVFBMouse, { 0 }, // TPanel, { 3 }, // BusMouse,};class QWSMouseHandlerPrivate : public QWSMouseHandler { Q_OBJECTpublic: QWSMouseHandlerPrivate( MouseProtocol protocol, QString mouseDev ); ~QWSMouseHandlerPrivate();private: static const int mouseBufSize = 128; int mouseFD; int mouseIdx; uchar mouseBuf[mouseBufSize]; MouseProtocol mouseProtocol; void handleMouseData();private slots: void readMouseData();private: int obstate;};void QWSMouseHandlerPrivate::readMouseData(){ int n; if ( BusMouse == mouseProtocol ) { // a workaround of linux busmouse driver interface. // It'll only read 3 bytes a time and return all other buffer zeroed, thus cause protocol errors for (;;) { if ( mouseBufSize - mouseIdx < 3 ) break; n = read( mouseFD, mouseBuf+mouseIdx, 3 ); if ( n != 3 ) break; mouseIdx += 3; } } else { do { n = read(mouseFD, mouseBuf+mouseIdx, mouseBufSize-mouseIdx ); if ( n > 0 ) mouseIdx += n; } while ( n > 0 ); } handleMouseData();}/**/void QWSMouseHandlerPrivate::handleMouseData(){ static const int accel_limit = 5; static const int accel = 2; int idx = 0; int bstate = 0; int dx = 0, dy = 0; bool sendEvent = false; int tdx = 0, tdy = 0; while ( mouseIdx-idx >= mouseData[mouseProtocol].bytesPerPacket ) { //qDebug( "Got mouse data" ); uchar *mb = mouseBuf+idx; bstate = 0; dx = 0; dy = 0; sendEvent = false; switch (mouseProtocol) { case MouseMan: case IntelliMouse: { if (mb[0] & 0x01) bstate |= Qt::LeftButton; if (mb[0] & 0x02) bstate |= Qt::RightButton; if (mb[0] & 0x04) bstate |= Qt::MidButton; int overflow = (mb[0]>>6 )& 0x03; if (mouseProtocol == MouseMan && overflow) { //### wheel events signalled with overflow bit, ignore for now } else { bool xs = mb[0] & 0x10; bool ys = mb[0] & 0x20; dx = xs ? mb[1]-256 : mb[1]; dy = ys ? mb[2]-256 : mb[2]; sendEvent = true; }#if 0 //debug if (mouseProtocol == MouseMan) printf("(%2d) %02x %02x %02x ", idx, mb[0], mb[1], mb[2]); else printf("(%2d) %02x %02x %02x %02x ",idx,mb[0],mb[1],mb[2],mb[3]); const char *b1 = (mb[0] & 0x01) ? "b1":" ";//left const char *b2 = (mb[0] & 0x02) ? "b2":" ";//right const char *b3 = (mb[0] & 0x04) ? "b3":" ";//mid if ( overflow ) printf( "Overflow%d %s %s %s (%4d,%4d)\n", overflow, b1, b2, b3, mousePos.x(), mousePos.y() ); else printf( "%s %s %s (%+3d,%+3d) (%4d,%4d)\n", b1, b2, b3, dx, dy, mousePos.x(), mousePos.y() );#endif break; } case Microsoft: if ( ((mb[0] & 0x20) >> 3) ) { bstate |= Qt::LeftButton; } if ( ((mb[0] & 0x10) >> 4) ) { bstate |= Qt::RightButton; } dx=(signed char)(((mb[0] & 0x03) << 6) | (mb[1] & 0x3f)); dy=-(signed char)(((mb[0] & 0x0c) << 4) | (mb[2] & 0x3f)); sendEvent=true; break; case BusMouse: if ( ((mb[0] & 0x4)) ) { bstate |= Qt::LeftButton; } if ( ((mb[0] & 0x01)) ) { bstate |= Qt::RightButton; } dx=(signed char)mb[1]; dy=(signed char)mb[2]; sendEvent=true; break; default: qWarning( "Unknown mouse protocol in QWSMouseHandlerPrivate" ); break; } if (sendEvent) { if ( QABS(dx) > accel_limit || QABS(dy) > accel_limit ) { dx *= accel; dy *= accel; } tdx += dx; tdy += dy; if ( bstate != obstate ) { mousePos += QPoint(tdx,-tdy); limitToScreen( mousePos ); emit mouseChanged(mousePos,bstate); sendEvent = FALSE; tdx = 0; tdy = 0; obstate = bstate; } } idx += mouseData[mouseProtocol].bytesPerPacket; } if ( sendEvent ) { mousePos += QPoint(tdx,-tdy); limitToScreen( mousePos ); emit mouseChanged(mousePos,bstate); } int surplus = mouseIdx - idx; for ( int i = 0; i < surplus; i++ ) mouseBuf[i] = mouseBuf[idx+i]; mouseIdx = surplus;}QWSMouseHandlerPrivate::QWSMouseHandlerPrivate( MouseProtocol protocol, QString mouseDev ){ mouseProtocol = protocol; if ( mouseDev.isEmpty() ) mouseDev = "/dev/mouse"; obstate = -1; mouseFD = -1; mouseFD = open( mouseDev.local8Bit(), O_RDWR | O_NDELAY); if ( mouseFD < 0 ) { mouseFD = open( mouseDev.local8Bit(), O_RDONLY | O_NDELAY); if ( mouseFD < 0 ) qDebug( "Cannot open %s (%s)", mouseDev.ascii(), strerror(errno)); } else { // Clear pending input tcflush(mouseFD,TCIFLUSH); bool ps2 = false; switch (mouseProtocol) { case MouseMan: ps2 = true; write(mouseFD,"",1); usleep(50000); write(mouseFD,"@EeI!",5); break; case IntelliMouse: {// ps2 = true; const unsigned char init1[] = { 243, 200, 243, 100, 243, 80 }; const unsigned char init2[] = { 246, 230, 244, 243, 100, 232, 3 }; write(mouseFD,init1,sizeof(init1)); usleep(50000); write(mouseFD,init2,sizeof(init2)); } break; case Microsoft: struct termios tty; tcgetattr(mouseFD, &tty); tty.c_iflag = IGNBRK | IGNPAR; tty.c_oflag = 0; tty.c_lflag = 0;#if !defined(_OS_FREEBSD_) tty.c_line = 0;#endif // _OS_FREEBSD_ tty.c_cc[VTIME] = 0; tty.c_cc[VMIN] = 1; tty.c_cflag = B1200 | CS7 | CREAD | CLOCAL | HUPCL; tcsetattr(mouseFD, TCSAFLUSH, &tty); /* set parameters */ break; case BusMouse: usleep(50000); break; default: qDebug("Unknown mouse protocol"); exit(1); } if (ps2) { char buf[] = { 246, 244 }; write(mouseFD,buf,1); write(mouseFD,buf+1,1); } usleep(50000); tcflush(mouseFD,TCIFLUSH); // ### doesn't seem to work. usleep(50000); tcflush(mouseFD,TCIFLUSH); // ### doesn't seem to work. char buf[100]; // busmouse driver will not read if bufsize < 3, YYD while (read(mouseFD, buf, 100) > 0) { } // eat unwanted replies mouseIdx = 0; QSocketNotifier *mouseNotifier; mouseNotifier = new QSocketNotifier( mouseFD, QSocketNotifier::Read, this ); connect(mouseNotifier, SIGNAL(activated(int)),this, SLOT(readMouseData())); }}QWSMouseHandlerPrivate::~QWSMouseHandlerPrivate(){ if (mouseFD >= 0) { tcflush(mouseFD,TCIFLUSH); // yyd. close(mouseFD); }}/* * */QCalibratedMouseHandler::QCalibratedMouseHandler() : samples(5), currSample(0), numSamples(0){ clearCalibration(); readCalibration();}void QCalibratedMouseHandler::getCalibration( QWSPointerCalibrationData *cd ){ QPoint screen_tl = cd->screenPoints[ QWSPointerCalibrationData::TopLeft ]; QPoint screen_br = cd->screenPoints[ QWSPointerCalibrationData::BottomRight ]; int tlx = ( s * screen_tl.x() - c ) / a; int tly = ( s * screen_tl.y() - f ) / e; cd->devPoints[ QWSPointerCalibrationData::TopLeft ] = QPoint(tlx,tly); cd->devPoints[ QWSPointerCalibrationData::BottomRight ] = QPoint( tlx - (s * (screen_tl.x() - screen_br.x() ) / a), tly - (s * (screen_tl.y() - screen_br.y() ) / e) );}void QCalibratedMouseHandler::clearCalibration(){ a = 1; b = 0; c = 0; d = 0; e = 1; f = 0; s = 1;}void QCalibratedMouseHandler::writeCalibration(){ QString calFile = "/etc/pointercal";#ifndef QT_NO_TEXTSTREAM QFile file( calFile ); if ( file.open( IO_WriteOnly ) ) { QTextStream t( &file ); t << a << " " << b << " " << c << " "; t << d << " " << e << " " << f << " " << s; } else#endif { qDebug( "Could not save calibration: %s", calFile.latin1() ); }}void QCalibratedMouseHandler::readCalibration(){ QString calFile = "/etc/pointercal";#ifndef QT_NO_TEXTSTREAM QFile file( calFile ); if ( file.open( IO_ReadOnly ) ) { QTextStream t( &file ); t >> a >> b >> c >> d >> e >> f >> s; } else#endif { qDebug( "Could not read calibration: %s", calFile.latin1() ); }}void QCalibratedMouseHandler::calibrate( QWSPointerCalibrationData *cd ){ QPoint dev_tl = cd->devPoints[ QWSPointerCalibrationData::TopLeft ]; QPoint dev_br = cd->devPoints[ QWSPointerCalibrationData::BottomRight ]; QPoint screen_tl = cd->screenPoints[ QWSPointerCalibrationData::TopLeft ]; QPoint screen_br = cd->screenPoints[ QWSPointerCalibrationData::BottomRight ]; s = 1 << 16; a = s * (screen_tl.x() - screen_br.x() ) / (dev_tl.x() - dev_br.x()); b = 0; c = s * screen_tl.x() - a * dev_tl.x(); d = 0; e = s * (screen_tl.y() - screen_br.y() ) / (dev_tl.y() - dev_br.y()); f = s * screen_tl.y() - e * dev_tl.y(); writeCalibration();}QPoint QCalibratedMouseHandler::transform( const QPoint &p ){ QPoint tp; tp.setX( (a * p.x() + b * p.y() + c) / s ); tp.setY( (d * p.x() + e * p.y() + f) / s ); return tp;}void QCalibratedMouseHandler::setFilterSize( int s ){ samples.resize( s ); numSamples = 0; currSample = 0;}bool QCalibratedMouseHandler::sendFiltered( const QPoint &p, int button ){ if ( !button ) { if ( numSamples >= samples.count() ) { emit mouseChanged( mousePos, 0 ); } currSample = 0; numSamples = 0; return TRUE; } bool sent = FALSE; samples[currSample] = p; numSamples++; if ( numSamples >= samples.count() ) { int maxd = 0; unsigned int ignore = 0; // throw away the "worst" sample for ( unsigned int i = 0; i < samples.count(); i++ ) { int d = ( mousePos - samples[i] ).manhattanLength(); if ( d > maxd ) { maxd = d; ignore = i; } } bool first = TRUE; QPoint pos; // average the rest for ( unsigned int i = 0; i < samples.count(); i++ ) { if ( ignore != i ) { if ( first ) { pos = samples[i]; first = FALSE; } else { pos += samples[i]; } } } pos /= (int)(samples.count() - 1); pos = transform( pos ); if ( pos != mousePos || numSamples == samples.count() ) { mousePos = pos; emit mouseChanged( mousePos, button ); sent = TRUE; } } currSample++; if ( currSample >= samples.count() ) currSample = 0; return sent;}/* * Handler for /dev/tpanel Linux kernel driver */class QVrTPanelHandlerPrivate : public QCalibratedMouseHandler { Q_OBJECTpublic: QVrTPanelHandlerPrivate(MouseProtocol, QString dev); ~QVrTPanelHandlerPrivate();private: int mouseFD; MouseProtocol mouseProtocol;private slots: void sendRelease(); void readMouseData();private: static const int mouseBufSize = 1280; QTimer *rtimer; int mouseIdx; uchar mouseBuf[mouseBufSize];};#ifndef QT_QWS_CASSIOPEIAQVrTPanelHandlerPrivate::QVrTPanelHandlerPrivate( MouseProtocol, QString ) : QCalibratedMouseHandler(){}#elseQVrTPanelHandlerPrivate::QVrTPanelHandlerPrivate( MouseProtocol, QString dev ) : QCalibratedMouseHandler(){ if ( dev.isEmpty() ) dev = "/dev/tpanel"; if ((mouseFD = open( dev, O_RDONLY)) < 0) { qFatal( "Cannot open %s (%s)", dev.latin1(), strerror(errno)); } else { sleep(1); } struct scanparam s; s.interval = 20000; s.settletime = 480; if ( ioctl(mouseFD, TPSETSCANPARM, &s) < 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -