Qt 4.8
qopenkodewindow.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the plugins of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qopenkodewindow.h"
43 #include "qopenkodeintegration.h"
44 #include "../eglconvenience/qeglplatformcontext.h"
45 #include "../eglconvenience/qeglconvenience.h"
46 
47 #include <KD/kd.h>
48 #include <KD/NV_display.h>
49 #include <KD/kdplatform.h>
50 #ifdef KD_ATX_keyboard
51 #include "openkodekeytranslator.h"
52 #endif
53 
54 #include <EGL/egl.h>
55 
56 #include <QtGui/qwidget.h>
57 #include <QtGui/private/qwidget_p.h>
58 #include <QtGui/private/qapplication_p.h>
59 
60 #include <QtCore/qvector.h>
61 #include <QtCore/QDebug>
62 
64 
65 void kdProcessMouseEvents( const KDEvent *event )
66 {
67  QOpenKODEWindow *window = static_cast<QOpenKODEWindow *>(event->userptr);
68  window->processMouseEvents(event);
69 }
70 
71 #ifdef KD_ATX_keyboard
72 void kdProcessKeyEvents( const KDEvent *event )
73 {
74  QOpenKODEWindow *window = static_cast<QOpenKODEWindow *>(event->userptr);
75  window->processKeyEvents(event);
76 }
77 #endif //KD_ATX_keyboard
78 
80  : QPlatformWindow(tlw), isFullScreen(false)
81 {
82  if (tlw->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenVG) {
83  m_eglApi = EGL_OPENVG_API;
84  } else {
85  m_eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION);
87 
88  m_eglApi = EGL_OPENGL_ES_API;
89  }
90  eglBindAPI(m_eglApi);
91 
92  m_eglContextAttrs.append(EGL_NONE);
93  m_eglWindowAttrs.append(EGL_NONE);
94 
95  QList<QPlatformScreen *> screens = QApplicationPrivate::platformIntegration()->screens();
96  //XXXX: jl figure out how to pick the correct screen.
97 // Q_ASSERT(screens.size() > tlw->d_func()->screenNumber);
98 // QOpenKODEScreen *screen = qobject_cast<QOpenKODEScreen *>(screens.at(tlw->d_func()->screenNumber));
99  QOpenKODEScreen *screen = qobject_cast<QOpenKODEScreen *>(screens.at(0));
100  if (!screen) {
101  qErrnoWarning("Could not make QOpenKODEWindow without a screen");
102  }
103 
104  QPlatformWindowFormat format = tlw->platformWindowFormat();
105  format.setRedBufferSize(5);
106  format.setGreenBufferSize(6);
107  format.setBlueBufferSize(5);
108 
110 
111  m_kdWindow = kdCreateWindow(screen->eglDisplay(),
112  m_eglConfig,
113  this);
114  kdInstallCallback(kdProcessMouseEvents,KD_EVENT_INPUT_POINTER,this);
115 #ifdef KD_ATX_keyboard
116  kdInstallCallback(kdProcessKeyEvents, KD_EVENT_INPUT_KEY_ATX,this);
117 #endif //KD_ATX_keyboard
118 
119  if (!m_kdWindow) {
120  qErrnoWarning(kdGetError(), "Error creating native window");
121  return;
122  }
123 
124  KDboolean exclusive(false);
125  if (kdSetWindowPropertybv(m_kdWindow,KD_WINDOWPROPERTY_DESKTOP_EXCLUSIVE_NV, &exclusive)) {
126  isFullScreen = true;
127  }
128 
129  if (isFullScreen) {
130  tlw->setGeometry(screen->geometry());
131  screen->setFullScreen(isFullScreen);
132  }else {
133  const KDint windowSize[2] = { tlw->width(), tlw->height() };
134  if (kdSetWindowPropertyiv(m_kdWindow, KD_WINDOWPROPERTY_SIZE, windowSize)) {
135  qErrnoWarning(kdGetError(), "Could not set native window size");
136  }
137  KDboolean visibillity(false);
138  if (kdSetWindowPropertybv(m_kdWindow, KD_WINDOWPROPERTY_VISIBILITY, &visibillity)) {
139  qErrnoWarning(kdGetError(), "Could not set visibillity to false");
140  }
141 
142  const KDint windowPos[2] = { tlw->x(), tlw->y() };
143  if (kdSetWindowPropertyiv(m_kdWindow, KD_WINDOWPROPERTY_DESKTOP_OFFSET_NV, windowPos)) {
144  qErrnoWarning(kdGetError(), "Could not set native window position");
145  return;
146  }
147  }
148 
149 
150  QOpenKODEIntegration *integration = static_cast<QOpenKODEIntegration *>(QApplicationPrivate::platformIntegration());
151 
152  if (!isFullScreen || (isFullScreen && !integration->mainGLContext())) {
153  if (kdRealizeWindow(m_kdWindow, &m_eglWindow)) {
154  qErrnoWarning(kdGetError(), "Could not realize native window");
155  return;
156  }
157 
158  EGLSurface surface = eglCreateWindowSurface(screen->eglDisplay(),m_eglConfig,m_eglWindow,m_eglWindowAttrs.constData());
160  m_eglContextAttrs.data(), surface, m_eglApi);
161  integration->setMainGLContext(m_platformGLContext);
162  } else {
163  m_platformGlContext = integration->mainGLContext();
164  kdDestroyWindow(m_kdWindow);
165  m_kdWindow = 0;
166  }
167 }
168 
169 
171 {
172  if (m_platformGlContext != static_cast<QOpenKODEIntegration *>(QApplicationPrivate::platformIntegration())) {
173  delete m_platformGlContext;
174  }
175  if (m_kdWindow)
176  kdDestroyWindow(m_kdWindow);
177 }
179 {
180  if (isFullScreen) {
181  QList<QPlatformScreen *> screens = QApplicationPrivate::platformIntegration()->screens();
182  QOpenKODEScreen *screen = qobject_cast<QOpenKODEScreen *>(screens.at(0));
183  widget()->setGeometry(screen->geometry());
184  return;
185  }
186  bool needToDeleteContext = false;
187  if (!isFullScreen) {
188  const QRect geo = geometry();
189  if (geo.size() != rect.size()) {
190  const KDint windowSize[2] = { rect.width(), rect.height() };
191  if (kdSetWindowPropertyiv(m_kdWindow, KD_WINDOWPROPERTY_SIZE, windowSize)) {
192  qErrnoWarning(kdGetError(), "Could not set native window size");
193  //return;
194  } else {
195  needToDeleteContext = true;
196  }
197  }
198 
199  if (geo.topLeft() != rect.topLeft()) {
200  const KDint windowPos[2] = { rect.x(), rect.y() };
201  if (kdSetWindowPropertyiv(m_kdWindow, KD_WINDOWPROPERTY_DESKTOP_OFFSET_NV, windowPos)) {
202  qErrnoWarning(kdGetError(), "Could not set native window position");
203  //return;
204  } else {
205  needToDeleteContext = true;
206  }
207  }
208  }
209 
210  //need to recreate context
211  if (needToDeleteContext) {
212  delete m_platformGlContext;
213 
214  QList<QPlatformScreen *> screens = QApplicationPrivate::platformIntegration()->screens();
215  QOpenKODEScreen *screen = qobject_cast<QOpenKODEScreen *>(screens.at(0));
216  EGLSurface surface = eglCreateWindowSurface(screen->eglDisplay(),m_eglConfig,m_eglWindow,m_eglWindowAttrs.constData());
218  m_eglContextAttrs.data(),surface,m_eglApi);
219  }
220 }
221 
222 void QOpenKODEWindow::setVisible(bool visible)
223 {
224  if (!m_kdWindow)
225  return;
226  KDboolean visibillity(visible);
227  if (kdSetWindowPropertybv(m_kdWindow, KD_WINDOWPROPERTY_VISIBILITY, &visibillity)) {
228  qErrnoWarning(kdGetError(), "Could not set visibillity property");
229  }
230 }
231 
233 {
234  static int i = 0;
235  return i++;
236 }
237 
239 {
240  return m_platformGlContext;
241 }
242 
244 {
245  if (!m_kdWindow)
246  return;
247  KDboolean focus(true);
248  if (kdSetWindowPropertybv(m_kdWindow, KD_WINDOWPROPERTY_FOCUS, &focus)) {
249  qErrnoWarning(kdGetError(), "Could not set focus");
250  }
251 }
252 
254 {
255  if (!m_kdWindow)
256  return;
257  KDboolean focus(false);
258  if (kdSetWindowPropertybv(m_kdWindow, KD_WINDOWPROPERTY_FOCUS, &focus)) {
259  qErrnoWarning(kdGetError(), "Could not set focus");
260  }
261 }
262 
264 {
265  int x = event->data.inputpointer.x;
266  int y = event->data.inputpointer.y;
267  Qt::MouseButtons buttons;
268  switch(event->data.inputpointer.select) {
269  case 1:
270  buttons = Qt::LeftButton;
271  break;
272  default:
273  buttons = Qt::NoButton;
274  }
275  QPoint pos(x,y);
276  QWindowSystemInterface::handleMouseEvent(0,event->timestamp,pos,pos,buttons);
277 }
278 
280 {
281 #ifdef KD_ATX_keyboard
282  //KD_KEY_PRESS_ATX 1
283  QEvent::Type keyPressed = QEvent::KeyRelease;
284  if (event->data.keyboardInputKey.flags)
285  keyPressed = QEvent::KeyPress;
286 //KD_KEY_LOCATION_LEFT_ATX // don't care for now
287 //KD_KEY_LOCATION_RIGHT_ATX
288 //KD_KEY_LOCATION_NUMPAD_ATX
289  Qt::KeyboardModifiers mod = Qt::NoModifier;
290  int openkodeMods = event->data.keyboardInputKey.flags;
291  if (openkodeMods & KD_KEY_MODIFIER_SHIFT_ATX)
292  mod |= Qt::ShiftModifier;
293  if (openkodeMods & KD_KEY_MODIFIER_CTRL_ATX)
294  mod |= Qt::ControlModifier;
295  if (openkodeMods & KD_KEY_MODIFIER_ALT_ATX)
296  mod |= Qt::AltModifier;
297  if (openkodeMods & KD_KEY_MODIFIER_META_ATX)
298  mod |= Qt::MetaModifier;
299 
300  Qt::Key qtKey;
301  QChar keyText;
302  int key = event->data.keyboardInputKey.keycode;
303  if (key >= 0x20 && key <= 0x0ff){ // 8 bit printable Latin1
304  qtKey = Qt::Key(key);
305  keyText = QChar(event->data.keyboardInputKeyChar.character);
306  if (!(mod & Qt::ShiftModifier))
307  keyText = keyText.toLower();
308  } else {
309  qtKey = keyTranslator(key);
310  }
311  QWindowSystemInterface::handleKeyEvent(0,event->timestamp,keyPressed,qtKey,mod,keyText);
312 #endif
313 }
314 
T qobject_cast(QObject *object)
Definition: qobject.h:375
unsigned long WId
Definition: qwindowdefs.h:119
EGLConfig m_eglConfig
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
EventRef event
int width
the width of the widget excluding any window frame
Definition: qwidget.h:166
virtual QRect geometry() const
Returnes the current geometry of a window.
EGLConfig q_configFromQPlatformWindowFormat(EGLDisplay display, const QPlatformWindowFormat &format, bool highestPixelFormat, int surfaceType)
static Qt::MouseButtons buttons
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
void processMouseEvents(const KDEvent *event)
The QPlatformWindowFormat class specifies the display format of an OpenGL rendering context and if po...
static void handleKeyEvent(QWidget *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString &text=QString(), bool autorep=false, ushort count=1)
EGLNativeWindowType m_eglWindow
int width() const
Returns the width of the rectangle.
Definition: qrect.h:303
void setBlueBufferSize(int size)
Set the preferred blue buffer size to size.
void setGeometry(int x, int y, int w, int h)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qwidget.h:1017
int height() const
Returns the height of the rectangle.
Definition: qrect.h:306
The QPlatformWindow class provides an abstraction for top-level windows.
int x
the x coordinate of the widget relative to its parent including any window frame
Definition: qwidget.h:161
QRect geometry() const
Reimplement in subclass to return the pixel geometry of the screen.
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
void setVisible(bool visible)
Reimplemented in subclasses to show the surface if visible is true, and hide it if visible is false...
void lower()
Reimplement to be able to let Qt lower windows to the bottom of the desktop.
void raise()
Reimplement to be able to let Qt rais windows to the top of the desktop.
NSWindow * window
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
int height
the height of the widget excluding any window frame
Definition: qwidget.h:167
QSize size() const
Returns the size of the rectangle.
Definition: qrect.h:309
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
WId winId() const
Reimplement in subclasses to return a handle to the native window.
static void handleMouseEvent(QWidget *w, const QPoint &local, const QPoint &global, Qt::MouseButtons b)
tlw == 0 means that ev is in global coords only
void processKeyEvents(const KDEvent *event)
void append(const T &t)
Inserts value at the end of the vector.
Definition: qvector.h:573
QOpenKODEWindow(QWidget *tlw)
void setMainGLContext(QEGLPlatformContext *ctx)
Qt::Key keyTranslator(int key)
struct KDWindow * m_kdWindow
void setGeometry(const QRect &rect)
This function is called by Qt whenever a window is moved or the window is resized.
QPlatformGLContext * glContext() const
Reimplement to return the glContext associated with the window.
The QPlatformGLContext class provides an abstraction for native GL contexts.
Type
This enum type defines the valid event types in Qt.
Definition: qcoreevent.h:62
int y() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:255
int y
the y coordinate of the widget relative to its parent and including any window frame ...
Definition: qwidget.h:162
int x() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:252
int key
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
QVector< EGLint > m_eglContextAttrs
void setRedBufferSize(int size)
Set the preferred red buffer size to size.
QVector< EGLint > m_eglWindowAttrs
void kdProcessMouseEvents(const KDEvent *event)
T * data()
Returns a pointer to the data stored in the vector.
Definition: qvector.h:152
const T * constData() const
Returns a const pointer to the data stored in the vector.
Definition: qvector.h:154
static QString qtKey(CFStringRef cfkey)
void setFullScreen(bool fullscreen)
QChar toLower() const
Returns the lowercase equivalent if the character is uppercase or titlecase; otherwise returns the ch...
Definition: qchar.cpp:1239
void setGreenBufferSize(int size)
Set the preferred green buffer size to size.
The QList class is a template class that provides lists.
Definition: qdatastream.h:62
QEGLPlatformContext * m_platformGlContext
QWidget * widget() const
Returnes the widget which belongs to the QPlatformWindow.
void qErrnoWarning(const char *msg,...)
Definition: qglobal.cpp:2954
QPoint topLeft() const
Returns the position of the rectangle&#39;s top-left corner.
Definition: qrect.h:288
EGLDisplay eglDisplay()