📄 qwsmouse_qws.cpp
字号:
/****************************************************************************** $Id: qt/src/kernel/qwsmouse_qws.cpp 2.3.2 edited 2001-10-14 $**** Implementation of Qt/Embedded mouse drivers**** Created : 991025**** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.**** This file is part of the kernel module of the Qt GUI Toolkit.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition** licenses for Qt/Embedded may use this file in accordance with the** Qt Embedded Commercial License Agreement provided with the Software.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for** information about Qt Commercial License Agreements.** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#include "qwindowsystem_qws.h"#include "qsocketnotifier.h"#include "qwsevent_qws.h"#include "qwscommand_qws.h"#include "qwsutils_qws.h"#include "qwsmouse_qws.h"#include <qapplication.h>#include <qpointarray.h>#include <qtimer.h>#include <qfile.h>#include <qtextstream.h>#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <sys/ioctl.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <errno.h>#include <termios.h>#include <qgfx_qws.h>#if !defined(_OS_QNX6_)#ifdef QT_QWS_PSION#undef QT_QWS_IPAQ#endif#ifdef QT_QWS_CASSIOPEIA#include <linux/tpanel.h>#endif#if defined(QT_QWS_IPAQ)#define QT_QWS_IPAQ_RAWtypedef struct { unsigned short pressure; unsigned short x; unsigned short y; unsigned short pad;} TS_EVENT;#elif defined(QT_QWS_EBX)#define QT_QWS_EBX_RAW#ifndef QT_QWS_CUSTOMtypedef struct { unsigned short pressure; unsigned short x; unsigned short y; unsigned short pad;} TS_EVENT;#elsetypedef struct { long y; long x; long pressure; long long millisecs;} TS_EVENT;#define QT_QWS_TP_SAMPLE_SIZE 5#define QT_QWS_TP_PRESSURE_THRESHOLD 500#define QT_QWS_TP_MOVE_LIMIT 50#endif#endif#ifndef QT_QWS_TP_SAMPLE_SIZE#define QT_QWS_TP_SAMPLE_SIZE 5#endif#ifndef QT_QWS_TP_PRESSURE_THRESHOLD#define QT_QWS_TP_PRESSURE_THRESHOLD 1#endif#ifndef QT_QWS_TP_MOVE_LIMIT#define QT_QWS_TP_MOVE_LIMIT 100#endif//#define QWS_CUSTOMTOUCHPANEL/*! \class QWSMouseHandler qwsmouse_qws.h \brief Mouse driver/handler for Qt/Embedded The mouse driver/handler handles events from system devices and generates mouse events. A QWSMouseHandler will usually open some system device in its constructor, create a QSocketNotifier on that opened device and when it receives data, it will call mouseChanged() to send the event to Qt/Embedded for relaying to clients.*//*! Constructs a mouse handler. This becomes the primary mouse handler. Note that once created, mouse handlers are controlled by the system and should not be deleted.*/QWSMouseHandler::QWSMouseHandler(){ QWSServer::setMouseHandler(this);}/*! Destructs the mouse handler. You should not invoked this directly.*/QWSMouseHandler::~QWSMouseHandler(){}/*! \fn void mouseChanged(const QPoint& pos, int bstate); This signal is emited by the mouse handler to signal that the mouse is now at position \a pos and the mouse buttons are now in the state \a bstate.*/enum MouseProtocol { Unknown = -1, Auto = 0, MouseMan, IntelliMouse, Microsoft, QVFBMouse, TPanel, BusMouse, FirstAuto = MouseMan, LastAuto = Microsoft };static void limitToScreen( QPoint &pt ){ static int w = -1; static int h; if ( w < 0 ) { w = qt_screen->deviceWidth(); h = qt_screen->deviceHeight(); } pt.setX( QMIN( w-1, QMAX( 0, pt.x() ))); pt.setY( QMIN( h-1, QMAX( 0, pt.y() )));}static QPoint &mousePos = QWSServer::mousePosition;typedef struct { char *name; MouseProtocol id;} MouseConfig;static const MouseConfig mouseConfig[] = { { "Auto", Auto }, { "MouseMan", MouseMan }, { "IntelliMouse", IntelliMouse }, { "Microsoft", Microsoft }, { "QVFbMouse", QVFBMouse }, { "TPanel", TPanel }, { "BusMouse", BusMouse }, { 0, Unknown }};/* * Automatic-detection mouse driver */class QAutoMouseSubHandler {protected: enum { max_buf=32 }; int fd; uchar buffer[max_buf]; int nbuf; QPoint motion; int bstate; int goodness; int badness; virtual int tryData()=0;public: QAutoMouseSubHandler(int f) : fd(f) { nbuf = bstate = goodness = badness = 0; } int file() const { return fd; } void closeIfNot(int& f) { if ( fd != f ) { f = fd; close(fd); } } void worse(int by=1) { badness+=by; } bool reliable() const { return goodness >= 5 && badness < 50; } int buttonState() const { return bstate; } bool motionPending() const { return motion!=QPoint(0,0); } QPoint takeMotion() { QPoint r=motion; motion=QPoint(0,0); return r; } void appendData(uchar* data, int length) { memcpy(buffer+nbuf, data, length); nbuf += length; } enum UsageResult { Insufficient, Motion, Button }; UsageResult useData() { int pbstate = bstate; int n = tryData(); if ( n > 0 ) { if ( n<nbuf ) memcpy( buffer, buffer+n, nbuf-n ); nbuf -= n; return pbstate == bstate ? Motion : Button; } return Insufficient; }};class QAutoMouseSubHandler_intellimouse : public QAutoMouseSubHandler { int packetsize;public: QAutoMouseSubHandler_intellimouse(int f) : QAutoMouseSubHandler(f) { init(); } void init() { int n; uchar reply[20]; tcflush(fd,TCIOFLUSH); static const uchar initseq[] = { 243, 200, 243, 100, 243, 80 }; static const uchar query[] = { 0xf2 }; if (write(fd, initseq, sizeof(initseq))!=sizeof(initseq)) { badness = 100; return; } usleep(10000); tcflush(fd,TCIOFLUSH); if (write(fd, query, sizeof(query))!=sizeof(query)) { badness = 100; return; } usleep(10000); n = read(fd, reply, 20); if ( n > 0 ) { goodness = 10; switch ( reply[n-1] ) { case 3: case 4: packetsize = 4; break; default: packetsize = 3; } } else { badness = 100; } } int tryData() { if ( nbuf >= packetsize ) { //int overflow = (buffer[0]>>6 )& 0x03; if ( /*overflow ||*/ !(buffer[0] & 8) ) { badness++; return 1; } else { motion += QPoint((buffer[0] & 0x10) ? buffer[1]-256 : buffer[1], (buffer[0] & 0x20) ? 256-buffer[2] : -buffer[2]); int nbstate = buffer[0] & 0x7; if ( motion.x() || motion.y() || bstate != nbstate ) { bstate = nbstate; goodness++; } else { badness++; return 1; } } return packetsize; } return 0; }};class QAutoMouseSubHandler_serial : public QAutoMouseSubHandler {public: QAutoMouseSubHandler_serial(int f) : QAutoMouseSubHandler(f) { initSerial(); }protected: void setflags(int f) { termios tty; tcgetattr(fd, &tty); tty.c_iflag = IGNBRK | IGNPAR; tty.c_oflag = 0; tty.c_lflag = 0; tty.c_cflag = f | CREAD | CLOCAL | HUPCL;#if !defined(_OS_FREEBSD_) tty.c_line = 0;#endif tty.c_cc[VTIME] = 0; tty.c_cc[VMIN] = 1; tcsetattr(fd, TCSANOW, &tty); }private: void initSerial() { int speed[4] = { B9600, B4800, B2400, B1200 }; for (int n = 0; n < 4; n++) { setflags(CSTOPB | speed[n]); write(fd, "*q", 2); usleep(10000); } }};class QAutoMouseSubHandler_mousesystems : public QAutoMouseSubHandler_serial {public: // ##### This driver has not been tested QAutoMouseSubHandler_mousesystems(int f) : QAutoMouseSubHandler_serial(f) { init(); } void init() { setflags(B1200|CS8|CSTOPB); // 60Hz if (write(fd, "R", 1)!=1) { badness = 100; return; } tcflush(fd,TCIOFLUSH); } int tryData() { if ( nbuf >= 5 ) { if ( (buffer[0] & 0xf8) != 0x80 ) { badness++; return 1; } motion += QPoint((signed char)buffer[1] + (signed char)buffer[3], -(signed char)buffer[2] + (signed char)buffer[4]); int t = ~buffer[0]; int nbstate = ((t&3) << 1) | ((t&4) >> 2); if ( motion.x() || motion.y() || bstate != nbstate ) { bstate = nbstate; goodness++; } else { badness++; return 1; } return 5; } return 0; }};class QAutoMouseSubHandler_ms : public QAutoMouseSubHandler_serial { int mman;public: QAutoMouseSubHandler_ms(int f) : QAutoMouseSubHandler_serial(f) { mman=0; init(); } void init() { setflags(B1200|CS7); // 60Hz if (write(fd, "R", 1)!=1) { badness = 100; return; } tcflush(fd,TCIOFLUSH); } int tryData() { if ( !(buffer[0] & 0x40) ) { if ( buffer[0] == 0x20 && (bstate & Qt::MidButton) ) { mman=1; // mouseman extension } return 1; } int extra = mman&&(bstate & Qt::MidButton); if ( nbuf >= 3+extra ) { int nbstate = 0; if ( buffer[0] == 0x40 && !bstate && !buffer[1] && !buffer[2] ) { nbstate = Qt::MidButton; } else { nbstate = ((buffer[0] & 0x20) >> 5) | ((buffer[0] & 0x10) >> 3); if ( extra && buffer[3] == 0x20 ) nbstate = Qt::MidButton; } if ( buffer[1] & 0x40 ) { badness++; return 1; } else { motion += QPoint((signed char)((buffer[0]&0x3)<<6) |(signed char)(buffer[1]&0x3f), (signed char)((buffer[0]&0xc)<<4) |(signed char)(buffer[2]&0x3f)); if ( motion.x() || motion.y() || bstate != nbstate ) { bstate = nbstate; goodness++; } else { badness++; return 1; } return 3+extra; } } return 0; }};/*QAutoMouseHandler::UsageResult QAutoMouseHandler::useDev(Dev& d){ if ( d.nbuf >= mouseData[d.protocol].bytesPerPacket ) { uchar *mb = d.buf; int bstate = 0; int dx = 0; int dy = 0; switch (mouseProtocol) { case MouseMan: case IntelliMouse: { bstate = mb[0] & 0x7; // assuming Qt::*Button order 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]; } 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)); break; } } }*/class QAutoMouseHandler : public QWSMouseHandler { Q_OBJECTpublic: QAutoMouseHandler(); ~QAutoMouseHandler();private: enum { max_dev=32 }; QAutoMouseSubHandler *sub[max_dev]; QList<QSocketNotifier> notifiers; int nsub; int retries;private slots: void readMouseData(int);private: void openDevices(); void closeDevices(); void notify(int fd); bool sendEvent(QAutoMouseSubHandler& h) { if ( h.reliable() ) { mousePos += h.takeMotion(); limitToScreen( mousePos );/*qDebug("%d,%d %c%c%c",mousePos.x(),mousePos.y(),(h.buttonState()&Qt::LeftButton)?'L':'.',(h.buttonState()&Qt::MidButton)?'M':'.',(h.buttonState()&Qt::RightButton)?'R':'.');*/ emit mouseChanged(mousePos,h.buttonState()); return TRUE; } else { h.takeMotion(); if ( h.buttonState() & (Qt::RightButton|Qt::MidButton) ) { // Strange for the user to press right or middle without // a moving mouse! h.worse(); } return FALSE; } }};QAutoMouseHandler::QAutoMouseHandler(){ notifiers.setAutoDelete( TRUE ); retries = 0; openDevices();}QAutoMouseHandler::~QAutoMouseHandler(){ closeDevices();}void QAutoMouseHandler::openDevices(){ nsub=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -