4b4bbc5c964782a22f74559ff64c1428a6eadcb6
[profile/ivi/qtbase.git] / src / plugins / platforms / directfb / qdirectfbinput.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the plugins of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qdirectfbinput.h"
43 #include "qdirectfbconvenience.h"
44
45 #include <QThread>
46 #include <QDebug>
47 #include <QtGui/qwindowsysteminterface.h>
48 #include <QMouseEvent>
49 #include <QEvent>
50
51 #include <directfb.h>
52
53 QT_BEGIN_NAMESPACE
54
55 QDirectFbInput::QDirectFbInput(IDirectFB *dfb, IDirectFBDisplayLayer *dfbLayer)
56     : m_dfbInterface(dfb)
57     , m_dfbDisplayLayer(dfbLayer)
58     , m_shouldStop(false)
59 {
60     DFBResult ok = m_dfbInterface->CreateEventBuffer(m_dfbInterface, m_eventBuffer.outPtr());
61     if (ok != DFB_OK)
62         DirectFBError("Failed to initialise eventbuffer", ok);
63 }
64
65 void QDirectFbInput::run()
66 {
67     while (!m_shouldStop) {
68         if (m_eventBuffer->WaitForEvent(m_eventBuffer.data()) == DFB_OK)
69             handleEvents();
70     }
71 }
72
73 void QDirectFbInput::stopInputEventLoop()
74 {
75     m_shouldStop = true;
76     m_eventBuffer->WakeUp(m_eventBuffer.data());
77 }
78
79 void QDirectFbInput::addWindow(IDirectFBWindow *window, QWindow *platformWindow)
80 {
81     DFBResult res;
82     DFBWindowID id;
83
84     res = window->GetID(window, &id);
85     if (res != DFB_OK) {
86         DirectFBError("QDirectFbInput::addWindow", res);
87         return;
88     }
89
90     m_tlwMap.insert(id, platformWindow);
91     window->AttachEventBuffer(window, m_eventBuffer.data());
92 }
93
94 void QDirectFbInput::removeWindow(IDirectFBWindow *window)
95 {
96     DFBResult res;
97     DFBWindowID id;
98
99     res = window->GetID(window, &id);
100     if (res != DFB_OK) {
101         DirectFBError("QDirectFbInput::removeWindow", res);
102         return;
103     }
104
105     window->DetachEventBuffer(window, m_eventBuffer.data());
106     m_tlwMap.remove(id);
107 }
108
109 void QDirectFbInput::handleEvents()
110 {
111     DFBResult hasEvent = m_eventBuffer->HasEvent(m_eventBuffer.data());
112     while(hasEvent == DFB_OK){
113         DFBEvent event;
114         DFBResult ok = m_eventBuffer->GetEvent(m_eventBuffer.data(), &event);
115         if (ok != DFB_OK)
116             DirectFBError("Failed to get event",ok);
117         if (event.clazz == DFEC_WINDOW) {
118             switch (event.window.type) {
119             case DWET_BUTTONDOWN:
120             case DWET_BUTTONUP:
121             case DWET_MOTION:
122                 handleMouseEvents(event);
123                 break;
124             case DWET_WHEEL:
125                 handleWheelEvent(event);
126                 break;
127             case DWET_KEYDOWN:
128             case DWET_KEYUP:
129                 handleKeyEvents(event);
130                 break;
131             case DWET_ENTER:
132             case DWET_LEAVE:
133                 handleEnterLeaveEvents(event);
134                 break;
135             case DWET_GOTFOCUS:
136                 handleGotFocusEvent(event);
137                 break;
138             case DWET_CLOSE:
139                 handleCloseEvent(event);
140                 break;
141             case DWET_POSITION_SIZE:
142                 handleGeometryEvent(event);
143                 break;
144             default:
145                 break;
146             }
147
148         }
149
150         hasEvent = m_eventBuffer->HasEvent(m_eventBuffer.data());
151     }
152 }
153
154 void QDirectFbInput::handleMouseEvents(const DFBEvent &event)
155 {
156     QPoint p(event.window.x, event.window.y);
157     QPoint globalPos = globalPoint(event);
158     Qt::MouseButtons buttons = QDirectFbConvenience::mouseButtons(event.window.buttons);
159
160     QDirectFBPointer<IDirectFBDisplayLayer> layer(QDirectFbConvenience::dfbDisplayLayer());
161     QDirectFBPointer<IDirectFBWindow> window;
162     layer->GetWindow(layer.data(), event.window.window_id, window.outPtr());
163
164     long timestamp = (event.window.timestamp.tv_sec*1000) + (event.window.timestamp.tv_usec/1000);
165
166     QWindow *tlw = m_tlwMap.value(event.window.window_id);
167     QWindowSystemInterface::handleMouseEvent(tlw, timestamp, p, globalPos, buttons);
168 }
169
170 void QDirectFbInput::handleWheelEvent(const DFBEvent &event)
171 {
172     QPoint p(event.window.cx, event.window.cy);
173     QPoint globalPos = globalPoint(event);
174     long timestamp = (event.window.timestamp.tv_sec*1000) + (event.window.timestamp.tv_usec/1000);
175     QWindow *tlw = m_tlwMap.value(event.window.window_id);
176     QWindowSystemInterface::handleWheelEvent(tlw, timestamp, p, globalPos,
177                                           event.window.step*120,
178                                           Qt::Vertical);
179 }
180
181 void QDirectFbInput::handleKeyEvents(const DFBEvent &event)
182 {
183     QEvent::Type type = QDirectFbConvenience::eventType(event.window.type);
184     Qt::Key key = QDirectFbConvenience::keyMap()->value(event.window.key_symbol);
185     Qt::KeyboardModifiers modifiers = QDirectFbConvenience::keyboardModifiers(event.window.modifiers);
186
187     long timestamp = (event.window.timestamp.tv_sec*1000) + (event.window.timestamp.tv_usec/1000);
188
189     QChar character;
190     if (DFB_KEY_TYPE(event.window.key_symbol) == DIKT_UNICODE)
191         character = QChar(event.window.key_symbol);
192     QWindow *tlw = m_tlwMap.value(event.window.window_id);
193     QWindowSystemInterface::handleKeyEvent(tlw, timestamp, type, key, modifiers, character);
194 }
195
196 void QDirectFbInput::handleEnterLeaveEvents(const DFBEvent &event)
197 {
198     QWindow *tlw = m_tlwMap.value(event.window.window_id);
199     switch (event.window.type) {
200     case DWET_ENTER:
201         QWindowSystemInterface::handleEnterEvent(tlw);
202         break;
203     case DWET_LEAVE:
204         QWindowSystemInterface::handleLeaveEvent(tlw);
205         break;
206     default:
207         break;
208     }
209 }
210
211 void QDirectFbInput::handleGotFocusEvent(const DFBEvent &event)
212 {
213     QWindow *tlw = m_tlwMap.value(event.window.window_id);
214     QWindowSystemInterface::handleWindowActivated(tlw);
215 }
216
217 void QDirectFbInput::handleCloseEvent(const DFBEvent &event)
218 {
219     QWindow *tlw = m_tlwMap.value(event.window.window_id);
220     QWindowSystemInterface::handleCloseEvent(tlw);
221 }
222
223 void QDirectFbInput::handleGeometryEvent(const DFBEvent &event)
224 {
225     QWindow *tlw = m_tlwMap.value(event.window.window_id);
226     QRect rect(event.window.x, event.window.y, event.window.w, event.window.h);
227     QWindowSystemInterface::handleGeometryChange(tlw, rect);
228 }
229
230 inline QPoint QDirectFbInput::globalPoint(const DFBEvent &event) const
231 {
232     QDirectFBPointer<IDirectFBWindow> window;
233     m_dfbDisplayLayer->GetWindow(m_dfbDisplayLayer, event.window.window_id, window.outPtr());
234     int x,y;
235     window->GetPosition(window.data(), &x, &y);
236     return QPoint(event.window.cx +x, event.window.cy + y);
237 }
238
239 QT_END_NAMESPACE