~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/plugins/mousedrivers/tslib/tslibmousehandler.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 
 
3
 Copyright (C) 2003, 2004, 2005 Texas Instruments, Inc.
 
4
 Copyright (C)       2004, 2005 Holger Hans Peter Freyther
 
5
 All rights reserved.
 
6
 
 
7
 Redistribution and use in source and binary forms, with or without
 
8
 modification, are permitted provided that the following conditions are met:
 
9
 
 
10
   Redistributions of source code must retain the above copyright notice,
 
11
   this list of conditions and the following disclaimer.
 
12
 
 
13
   Redistributions in binary form must reproduce the above copyright
 
14
   notice, this list of conditions and the following disclaimer in the
 
15
   documentation and/or other materials provided with the distribution.
 
16
 
 
17
   Neither the name Texas Instruments, Inc nor the names of its
 
18
   contributors may be used to endorse or promote products derived
 
19
   from this software without specific prior written permission.
 
20
 
 
21
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
22
 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
23
 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 
24
 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 
25
 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 
26
 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 
27
 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 
28
 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
29
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 
30
 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 
31
 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
32
 POSSIBILITY OF SUCH DAMAGE.
 
33
 
 
34
*/
 
35
 
 
36
#include "tslibmousehandler.h"
 
37
 
 
38
#include <QFile>
 
39
#include <QTextStream>
 
40
#include <QScreen>
 
41
#include <QSocketNotifier>
 
42
 
 
43
#ifdef QT_QWS_TSLIB
 
44
#include <tslib.h>
 
45
#endif
 
46
 
 
47
#include <string.h>
 
48
#include <errno.h>
 
49
#include <stdlib.h>
 
50
 
 
51
TSLibMouseHandler::TSLibMouseHandler()
 
52
    : m_raw(false), m_notify(0 )
 
53
#ifdef QT_QWS_TSLIB
 
54
    , m_ts( 0 )
 
55
#endif
 
56
{
 
57
    setObjectName( "TSLib Mouse Handler" );
 
58
    openTs();
 
59
}
 
60
 
 
61
TSLibMouseHandler::~TSLibMouseHandler()
 
62
{
 
63
    closeTs();
 
64
}
 
65
 
 
66
void TSLibMouseHandler::openTs()
 
67
{
 
68
#ifdef QT_QWS_TSLIB
 
69
    char *tsdevice;
 
70
 
 
71
    if( ( tsdevice = getenv( "TSLIB_TSDEVICE" ) ) != NULL ) {
 
72
        m_ts = ts_open( tsdevice, 1 );
 
73
    } else {
 
74
        m_ts = ts_open( "/dev/ts", 1 );
 
75
    }
 
76
 
 
77
    if (!m_ts) {
 
78
        qWarning( "Cannot open touchscreen (%s)", strerror( errno ) );
 
79
        return;
 
80
    }
 
81
 
 
82
    if (ts_config( m_ts )) {
 
83
        qWarning( "Cannot configure touchscreen (%s)", strerror( errno ) );
 
84
        return;
 
85
    }
 
86
 
 
87
 
 
88
    m_notify = new QSocketNotifier( ts_fd(m_ts), QSocketNotifier::Read, this );
 
89
    connect( m_notify, SIGNAL(activated(int)), this, SLOT(readMouseData()));
 
90
#endif
 
91
}
 
92
 
 
93
void TSLibMouseHandler::closeTs()
 
94
{
 
95
#ifdef QT_QWS_TSLIB
 
96
    if (m_ts)
 
97
        ts_close(m_ts);
 
98
    m_ts = 0;
 
99
#endif
 
100
 
 
101
    delete m_notify;
 
102
    m_notify = 0;
 
103
    m_raw = false;
 
104
}
 
105
 
 
106
void TSLibMouseHandler::clearCalibration()
 
107
{
 
108
    m_raw = true;
 
109
}
 
110
 
 
111
 
 
112
void TSLibMouseHandler::calibrate( QWSPointerCalibrationData *cd )
 
113
{
 
114
    QPoint dev_tl = cd->devPoints[ QWSPointerCalibrationData::TopLeft ];
 
115
    QPoint dev_br = cd->devPoints[ QWSPointerCalibrationData::BottomRight ];
 
116
    QPoint screen_tl = cd->screenPoints[ QWSPointerCalibrationData::TopLeft ];
 
117
    QPoint screen_br = cd->screenPoints[ QWSPointerCalibrationData::BottomRight ];
 
118
    int a, b, c, d, e, f, s;
 
119
 
 
120
    s = 1 << 16;
 
121
 
 
122
    a = s * (screen_tl.x() - screen_br.x() ) / (dev_tl.x() - dev_br.x());
 
123
    b = 0;
 
124
    c = s * screen_tl.x() - a * dev_tl.x();
 
125
 
 
126
    d = 0;
 
127
    e = s * (screen_tl.y() - screen_br.y() ) / (dev_tl.y() - dev_br.y());
 
128
    f = s * screen_tl.y() - e * dev_tl.y();
 
129
 
 
130
    QString calFile = "/etc/pointercal";
 
131
#ifndef QT_NO_TEXTSTREAM
 
132
    QFile file( calFile );
 
133
    if ( file.open( QFile::WriteOnly ) ) {
 
134
        QTextStream t( &file );
 
135
        t << a << " " << b << " " << c << " ";
 
136
        t << d << " " << e << " " << f << " " << s;
 
137
       file.flush(); closeTs();
 
138
       openTs();
 
139
    } else
 
140
#endif
 
141
    {
 
142
        qDebug( "Could not save calibration: %s", calFile.latin1() );
 
143
    }
 
144
}
 
145
 
 
146
void TSLibMouseHandler::suspend()
 
147
{
 
148
    m_notify->setEnabled( false );
 
149
}
 
150
 
 
151
void TSLibMouseHandler::resume()
 
152
{
 
153
    m_notify->setEnabled( true );
 
154
}
 
155
 
 
156
void TSLibMouseHandler::readMouseData()
 
157
{
 
158
#ifdef QT_QWS_TSLIB
 
159
    if(!qt_screen)
 
160
        return;
 
161
 
 
162
    /*
 
163
     * After clear Calibration
 
164
     * we're in raw mode and do some easy median
 
165
     * search.
 
166
     */
 
167
    if ( m_raw )
 
168
        return interpolateSample();
 
169
 
 
170
    static struct ts_sample sample;
 
171
    static int ret;
 
172
 
 
173
    /*
 
174
     * Ok. We need to see if we can read more than one event
 
175
     * We do this not to lose an update.
 
176
     */
 
177
    while ( true ) {
 
178
        if ((ret = ts_read(m_ts, &sample, 1)) != 1 )
 
179
            return;
 
180
 
 
181
 
 
182
        QPoint pos( sample.x, sample.y );
 
183
        mouseChanged( pos, sample.pressure != 0 ? 1 : 0 );
 
184
    }
 
185
#endif
 
186
}
 
187
 
 
188
 
 
189
/*
 
190
 * Lets take all down events and then sort them
 
191
 * and take the event in the middle.
 
192
 *
 
193
 * inspired by testutils.c
 
194
 */
 
195
void TSLibMouseHandler::interpolateSample() {
 
196
#ifdef QT_QWS_TSLIB
 
197
    static struct ts_sample samples[25];
 
198
    int index = 0;
 
199
    int ret;
 
200
 
 
201
    do {
 
202
        /* fill only the last sample again */
 
203
        if ( index >= 25 )
 
204
            index = 24;
 
205
 
 
206
        /* we're opened non-blocking */
 
207
        if((ret= ts_read_raw(m_ts, &samples[index], 1 ) ) !=  1 ) {
 
208
            /* no event yet, so try again */
 
209
            if (ret==-1 ) {
 
210
                index--;
 
211
                continue;
 
212
            }
 
213
        }
 
214
    }while (samples[index++].pressure != 0);
 
215
 
 
216
    /*
 
217
     * index is maximal 25  and we at least one sample
 
218
     */
 
219
    if( index >= 25 )
 
220
        index = 24;
 
221
    int x, y;
 
222
 
 
223
    /*
 
224
     * now let us use the median value
 
225
     * even index does not have an item in the middle
 
226
     * so let us take the average of n/2 and (n/2)-1 as the middle
 
227
     */
 
228
    int m = index/2;
 
229
    ::qsort(samples, index, sizeof(ts_sample), TSLibMouseHandler::sortByX);
 
230
    x = (index % 2 ) ? samples[m].x :
 
231
        ( samples[m-1].x + samples[m].x )/2;
 
232
 
 
233
    ::qsort(samples, index, sizeof(ts_sample), TSLibMouseHandler::sortByY);
 
234
    y = (index % 2 ) ? samples[m].y :
 
235
        ( samples[m-1].y + samples[m].y )/2;
 
236
 
 
237
    emit mouseChanged( QPoint(x, y), 1 );
 
238
    emit mouseChanged( QPoint(0, 0), 0 );
 
239
#endif
 
240
}
 
241
 
 
242
int TSLibMouseHandler::sortByX( const void* one, const void* two) {
 
243
    return reinterpret_cast<const struct ts_sample*>(one)->x -
 
244
        reinterpret_cast<const struct ts_sample*>(two)->x;
 
245
}
 
246
 
 
247
int TSLibMouseHandler::sortByY( const void* one, const void* two) {
 
248
    return reinterpret_cast<const struct ts_sample*>(one)->y -
 
249
        reinterpret_cast<const struct ts_sample*>(two)->y;
 
250
}
 
251
 
 
252
 
 
253