~ubuntu-branches/ubuntu/trusty/libavg/trusty-proposed

« back to all changes in this revision

Viewing changes to src/player/LibMTDevInputDevice.cpp

  • Committer: Package Import Robot
  • Author(s): OXullo Intersecans
  • Date: 2011-12-06 22:44:56 UTC
  • mfrom: (1.1.6)
  • Revision ID: package-import@ubuntu.com-20111206224456-qc7250z3ya1vi8s9
Tags: 1.7.0-0ubuntu1
* New upstream release (LP: #899183)
* Remove patches 0002-libav-0.7.patch, 0003-fglrx-segfault-on-startup.patch
  now merged to upstream
* Remove unnecessary .la files
* Update debian/watch file
* Fix debian/copyright dep-5 compliancy
* Update standards to version 3.9.2
* Add man pages for avg_checktouch, avg_checkvsync, avg_showsvg
* Minor debian/rules enhancement
* Add librsvg2-dev, libgdk-pixbuf2.0-dev to Build-Depends
* Proper transition to dh_python2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
//  libavg - Media Playback Engine. 
 
3
//  Copyright (C) 2003-2011 Ulrich von Zadow
 
4
//
 
5
//  This library is free software; you can redistribute it and/or
 
6
//  modify it under the terms of the GNU Lesser General Public
 
7
//  License as published by the Free Software Foundation; either
 
8
//  version 2 of the License, or (at your option) any later version.
 
9
//
 
10
//  This library is distributed in the hope that it will be useful,
 
11
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
//  Lesser General Public License for more details.
 
14
//
 
15
//  You should have received a copy of the GNU Lesser General Public
 
16
//  License along with this library; if not, write to the Free Software
 
17
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
18
//
 
19
//  Current versions can be found at www.libavg.de
 
20
//
 
21
 
 
22
#include "LibMTDevInputDevice.h"
 
23
 
 
24
#include "TouchEvent.h"
 
25
#include "Player.h"
 
26
#include "AVGNode.h"
 
27
#include "TouchStatus.h"
 
28
 
 
29
#include "../base/Logger.h"
 
30
#include "../base/Point.h"
 
31
#include "../base/ObjectCounter.h"
 
32
#include "../base/Exception.h"
 
33
#include "../base/OSHelper.h"
 
34
 
 
35
#include <linux/input.h>
 
36
#include <fcntl.h>
 
37
#include <sys/types.h>
 
38
#include <sys/stat.h>
 
39
 
 
40
extern "C" {
 
41
#include <mtdev.h>
 
42
#include <mtdev-mapping.h>
 
43
}
 
44
 
 
45
using namespace std;
 
46
 
 
47
namespace avg {
 
48
 
 
49
LibMTDevInputDevice::LibMTDevInputDevice()
 
50
    : m_LastID(0),
 
51
      m_pMTDevice(0)
 
52
{
 
53
}
 
54
 
 
55
LibMTDevInputDevice::~LibMTDevInputDevice()
 
56
{
 
57
    if (m_pMTDevice) {
 
58
        mtdev_close(m_pMTDevice);
 
59
        delete m_pMTDevice;
 
60
    }
 
61
}
 
62
 
 
63
void LibMTDevInputDevice::start()
 
64
 
65
    string sDevice("/dev/input/event3");
 
66
    getEnv("AVG_LINUX_MULTITOUCH_DEVICE", sDevice);
 
67
    m_DeviceFD = ::open(sDevice.c_str(), O_RDONLY | O_NONBLOCK);
 
68
    if (m_DeviceFD == -1) {
 
69
        throw Exception(AVG_ERR_MT_INIT, 
 
70
                string("Linux multitouch event source: Could not open device file '")+
 
71
                sDevice+"'. "+strerror(errno)+".");
 
72
    }
 
73
    m_pMTDevice = new mtdev;
 
74
    int err = mtdev_open(m_pMTDevice, m_DeviceFD);
 
75
    if (err == -1) {
 
76
        throw Exception(AVG_ERR_MT_INIT, 
 
77
                string("Linux multitouch event source: Could not open mtdev '")+
 
78
                sDevice+"'. "+strerror(errno)+".");
 
79
    }
 
80
    input_absinfo* pAbsInfo;
 
81
    pAbsInfo = &(m_pMTDevice->caps.abs[MTDEV_POSITION_X]);
 
82
    m_Dimensions.tl.x = pAbsInfo->minimum;
 
83
    m_Dimensions.br.x = pAbsInfo->maximum;
 
84
    pAbsInfo = &(m_pMTDevice->caps.abs[MTDEV_POSITION_Y]);
 
85
    m_Dimensions.tl.y = pAbsInfo->minimum;
 
86
    m_Dimensions.br.y = pAbsInfo->maximum;
 
87
 
 
88
    MultitouchInputDevice::start();
 
89
    AVG_TRACE(Logger::CONFIG, "Linux MTDev Multitouch event source created.");
 
90
}
 
91
 
 
92
std::vector<EventPtr> LibMTDevInputDevice::pollEvents()
 
93
{
 
94
    struct input_event event;
 
95
    static int curSlot = 0;
 
96
 
 
97
    set<int> changedIDs;
 
98
    while (mtdev_get(m_pMTDevice, m_DeviceFD, &event, 1) > 0) {
 
99
        if (event.type == EV_SYN && event.code == SYN_REPORT) {
 
100
//            cerr << ">> SYN_REPORT" << endl;
 
101
            processEvents(changedIDs);
 
102
            changedIDs.clear();
 
103
        } else if (event.type == EV_ABS && event.code == ABS_MT_SLOT) {
 
104
//            cerr << ">> slot " << event.value << endl;
 
105
            curSlot = event.value;
 
106
        } else {
 
107
            TouchData* pTouch;
 
108
            switch (event.code) {
 
109
                case ABS_MT_TRACKING_ID:
 
110
//                    cerr << ">> ABS_MT_TRACKING_ID: " << event.value << endl;
 
111
                    pTouch = &(m_Slots[curSlot]);
 
112
                    if (event.value == -1) {
 
113
                        TouchStatusPtr pTouchStatus = getTouchStatus(pTouch->id);
 
114
//                        cerr << "up " << pTouch->id << endl;
 
115
                        if (pTouchStatus) {
 
116
//                            cerr << "  --> remove" << endl;
 
117
                            TouchEventPtr pOldEvent = pTouchStatus->getLastEvent();
 
118
                            TouchEventPtr pUpEvent =
 
119
                                    boost::dynamic_pointer_cast<TouchEvent>(
 
120
                                    pOldEvent->cloneAs(Event::CURSORUP));
 
121
                            pTouchStatus->pushEvent(pUpEvent);
 
122
                            removeTouchStatus(pTouch->id);
 
123
                        }
 
124
                        pTouch->id = -1;
 
125
                    } else {
 
126
                        pTouch->id = event.value;
 
127
                        changedIDs.insert(curSlot);
 
128
                    }
 
129
                    break;
 
130
                case ABS_MT_POSITION_X:
 
131
//                    cerr << ">> ABS_MT_POSITION_X: " << event.value << endl;
 
132
                    pTouch = &(m_Slots[curSlot]);
 
133
                    pTouch->pos.x = event.value;
 
134
                    changedIDs.insert(curSlot);
 
135
                    break;
 
136
                case ABS_MT_POSITION_Y:
 
137
//                    cerr << ">> ABS_MT_POSITION_Y: " << event.value << endl;
 
138
                    pTouch = &(m_Slots[curSlot]);
 
139
                    pTouch->pos.y = event.value;
 
140
                    changedIDs.insert(curSlot);
 
141
                    break;
 
142
                default:
 
143
                    break;
 
144
            }
 
145
        }
 
146
    }
 
147
 
 
148
    return MultitouchInputDevice::pollEvents();
 
149
}
 
150
 
 
151
void LibMTDevInputDevice::processEvents(const set<int>& changedIDs)
 
152
{
 
153
    for (set<int>::iterator it = changedIDs.begin(); it != changedIDs.end(); ++it) {
 
154
        map<int, TouchData>::iterator it2 = m_Slots.find(*it);
 
155
        if (it2 != m_Slots.end()) {
 
156
            const TouchData& touch = it2->second;
 
157
//            cerr << "slot: " << *it << ", id: " << touch.id << ", pos: " << touch.pos
 
158
//                    << endl;
 
159
//            AVG_ASSERT(touch.pos.x != 0);
 
160
            if (touch.id != -1) {
 
161
                TouchStatusPtr pTouchStatus = getTouchStatus(touch.id);
 
162
                if (!pTouchStatus) {
 
163
                    // Down
 
164
                    m_LastID++;
 
165
                    TouchEventPtr pEvent = createEvent(m_LastID, Event::CURSORDOWN,
 
166
                            touch.pos);
 
167
//                    cerr << "down <" << touch.id << "> --> [" << m_LastID << "]" << endl;
 
168
                    addTouchStatus((long)touch.id, pEvent);
 
169
                } else {
 
170
//                    cerr << "move <" << touch.id << "> --> " << touch.pos << endl;
 
171
                    // Move
 
172
                    TouchEventPtr pEvent = createEvent(0, Event::CURSORMOTION, touch.pos);
 
173
                    pTouchStatus->pushEvent(pEvent);
 
174
                }
 
175
            }
 
176
        }
 
177
    }
 
178
}
 
179
 
 
180
TouchEventPtr LibMTDevInputDevice::createEvent(int id, Event::Type type, IntPoint pos)
 
181
{
 
182
    DPoint size = getWindowSize();
 
183
    DPoint normPos = DPoint(double(pos.x-m_Dimensions.tl.x)/m_Dimensions.width(),
 
184
            double(pos.y-m_Dimensions.tl.y)/m_Dimensions.height());
 
185
    IntPoint screenPos(int(normPos.x*size.x+0.5), int(normPos.y*size.y+0.5));
 
186
    return TouchEventPtr(new TouchEvent(id, type, screenPos, Event::TOUCH));
 
187
}
 
188
 
 
189
}