📄 qwsmouse_qws.cpp
字号:
sub[nsub++] = new QAutoMouseSubHandler_mousesystems(fd);
sub[nsub++] = new QAutoMouseSubHandler_ms(fd);
notify(fd);
}
}
#endif
// ...
}
void QAutoMouseHandlerPrivate::closeDevices()
{
int pfd=-1;
for (int i=0; i<nsub; i++) {
sub[i]->closeIfNot(pfd);
delete sub[i];
}
notifiers.clear();
}
void QAutoMouseHandlerPrivate::notify(int fd)
{
QSocketNotifier *mouseNotifier
= new QSocketNotifier( fd, QSocketNotifier::Read, this );
connect(mouseNotifier, SIGNAL(activated(int)),this, SLOT(readMouseData(int)));
notifiers.append( mouseNotifier );
}
void QAutoMouseHandlerPrivate::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++;
}
}
#endif //QT_NO_QWS_MOUSE_AUTO
#ifndef QT_NO_QWS_MOUSE_MANUAL
/*
* 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,
};
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 ) {
#if 0 // debug
qDebug( "Got mouse data" );
#endif
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 );
mouseChanged(mousePos,bstate);
sendEvent = FALSE;
tdx = 0;
tdy = 0;
obstate = bstate;
}
}
idx += mouseData[mouseProtocol].bytesPerPacket;
}
if ( sendEvent ) {
mousePos += QPoint(tdx,-tdy);
limitToScreen( mousePos );
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;
#if !defined(Q_OS_FREEBSD) && !defined(Q_OS_SOLARIS)
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);
}
}
#endif //QT_NO_QWS_MOUSE_MANUAL
#ifndef QT_NO_QWS_MOUSE_CALIBRATED
/*
*
*/
QCalibratedMouseHandler::QCalibratedMouseHandler()
: samples(5), currSample(0), numSamples(0)
{
clearCalibration();
readCalibration();
}
/*!
\internal
*/
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() )
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;
mouseChanged( mousePos, button );
sent = TRUE;
}
}
currSample++;
if ( currSample >= samples.count() )
currSample = 0;
return sent;
}
#endif //QT_NO_QWS_MOUSE_CALIBRATED
#ifdef QT_QWS_CASSIOPEIA
QVrTPanelHandlerPrivate::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
|| fcntl(mouseFD, F_SETFL, O_NONBLOCK) < 0 )
qWarning("Error initializing touch panel.");
QSocketNotifier *mouseNotifier;
mouseNotifier = new QSocketNotifier( mouseFD, QSocketNotifier::Read,
this );
connect(mouseNotifier, SIGNAL(activated(int)),this, SLOT(readMouseData()));
rtimer = new QTimer( this );
connect( rtimer, SIGNAL(timeout()), this, SLOT(sendRelease()));
mouseIdx = 0;
setFilterSize( 3 );
printf("\033[?25l"); fflush(stdout); // VT100 cursor off
}
QVrTPanelHandlerPrivate::~QVrTPanelHandlerPrivate()
{
if (mouseFD >= 0)
close(mouseFD);
}
void QVrTPanelHandlerPrivate::sendRelease()
{
sendFiltered( mousePos, 0 );
}
void QVrTPanelHandlerPrivate::readMouseData()
{
if(!qt_screen)
return;
static bool pressed = FALSE;
int n;
do {
n = read(mouseFD, mouseBuf+mouseIdx, mouseBufSize-mouseIdx );
if ( n > 0 )
mouseIdx += n;
} while ( n > 0 && mouseIdx < mouseBufSize );
int idx = 0;
while ( mouseIdx-idx >= (int)sizeof( short ) * 6 ) {
uchar *mb = mouseBuf+idx;
ushort *data = (ushort *) mb;
if ( data[0] & 0x8000 ) {
if ( data[5] > 750 ) {
QPoint t(data[3]-data[4],data[2]-data[1]);
if ( sendFiltered( t, Qt::LeftButton ) )
pressed = TRUE;
if ( pressed )
rtimer->start( 200, TRUE ); // release unreliable
}
} else if ( pressed ) {
rtimer->start( 50, TRUE );
pressed = FALSE;
}
idx += sizeof( ushort ) * 6;
}
int surplus = mouseIdx - idx;
for ( int i = 0; i < surplus; i++ )
mouseBuf[i] = mouseBuf[idx+i];
mouseIdx = surplus;
}
#endif //QT_QWS_CASSIOPEIA
#if defined(QT_QWS_IPAQ) || defined(QT_QWS_EBX)
QTPanelHandlerPrivate::QTPanelHandlerPrivate( MouseProtocol, QString )
: samples(QT_QWS_TP_SAMPLE_SIZE), currSample(0), numSamples(0)
{
#if defined(QT_QWS_IPAQ)
# ifdef QT_QWS_IPAQ_RAW
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -