diff options
Diffstat (limited to 'src/plugins/platforms/openkode/qopenkodewindow.cpp')
-rw-r--r-- | src/plugins/platforms/openkode/qopenkodewindow.cpp | 316 |
1 files changed, 316 insertions, 0 deletions
diff --git a/src/plugins/platforms/openkode/qopenkodewindow.cpp b/src/plugins/platforms/openkode/qopenkodewindow.cpp new file mode 100644 index 0000000..32517c6 --- /dev/null +++ b/src/plugins/platforms/openkode/qopenkodewindow.cpp @@ -0,0 +1,316 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qopenkodewindow.h" +#include "qopenkodeintegration.h" +#include "../eglconvenience/qeglplatformcontext.h" +#include "../eglconvenience/qeglconvenience.h" + +#include <KD/kd.h> +#include <KD/NV_display.h> +#include <KD/kdplatform.h> +#ifdef KD_ATX_keyboard +#include "openkodekeytranslator.h" +#endif + +#include <EGL/egl.h> + +#include <QtGui/qwidget.h> +#include <QtGui/private/qwidget_p.h> +#include <QtGui/private/qapplication_p.h> + +#include <QtCore/qvector.h> +#include <QtCore/QDebug> + +QT_BEGIN_NAMESPACE + +void kdProcessMouseEvents( const KDEvent *event ) +{ + QOpenKODEWindow *window = static_cast<QOpenKODEWindow *>(event->userptr); + window->processMouseEvents(event); +} + +#ifdef KD_ATX_keyboard +void kdProcessKeyEvents( const KDEvent *event ) +{ + QOpenKODEWindow *window = static_cast<QOpenKODEWindow *>(event->userptr); + window->processKeyEvents(event); +} +#endif //KD_ATX_keyboard + +QOpenKODEWindow::QOpenKODEWindow(QWidget *tlw) + : QPlatformWindow(tlw), isFullScreen(false) +{ + if (tlw->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenVG) { + m_eglApi = EGL_OPENVG_API; + } else { + m_eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION); + m_eglContextAttrs.append(2); + + m_eglApi = EGL_OPENGL_ES_API; + } + eglBindAPI(m_eglApi); + + m_eglContextAttrs.append(EGL_NONE); + m_eglWindowAttrs.append(EGL_NONE); + + QList<QPlatformScreen *> screens = QApplicationPrivate::platformIntegration()->screens(); + //XXXX: jl figure out how to pick the correct screen. +// Q_ASSERT(screens.size() > tlw->d_func()->screenNumber); +// QOpenKODEScreen *screen = qobject_cast<QOpenKODEScreen *>(screens.at(tlw->d_func()->screenNumber)); + QOpenKODEScreen *screen = qobject_cast<QOpenKODEScreen *>(screens.at(0)); + if (!screen) { + qErrnoWarning("Could not make QOpenKODEWindow without a screen"); + } + + QPlatformWindowFormat format = tlw->platformWindowFormat(); + format.setRedBufferSize(5); + format.setGreenBufferSize(6); + format.setBlueBufferSize(5); + + m_eglConfig = q_configFromQPlatformWindowFormat(screen->eglDisplay(),format); + + m_kdWindow = kdCreateWindow(screen->eglDisplay(), + m_eglConfig, + this); + kdInstallCallback(kdProcessMouseEvents,KD_EVENT_INPUT_POINTER,this); +#ifdef KD_ATX_keyboard + kdInstallCallback(kdProcessKeyEvents, KD_EVENT_INPUT_KEY_ATX,this); +#endif //KD_ATX_keyboard + + if (!m_kdWindow) { + qErrnoWarning(kdGetError(), "Error creating native window"); + return; + } + + KDboolean exclusive(false); + if (kdSetWindowPropertybv(m_kdWindow,KD_WINDOWPROPERTY_DESKTOP_EXCLUSIVE_NV, &exclusive)) { + isFullScreen = true; + } + + if (isFullScreen) { + tlw->setGeometry(screen->geometry()); + screen->setFullScreen(isFullScreen); + }else { + const KDint windowSize[2] = { tlw->width(), tlw->height() }; + if (kdSetWindowPropertyiv(m_kdWindow, KD_WINDOWPROPERTY_SIZE, windowSize)) { + qErrnoWarning(kdGetError(), "Could not set native window size"); + } + KDboolean visibillity(false); + if (kdSetWindowPropertybv(m_kdWindow, KD_WINDOWPROPERTY_VISIBILITY, &visibillity)) { + qErrnoWarning(kdGetError(), "Could not set visibillity to false"); + } + + const KDint windowPos[2] = { tlw->x(), tlw->y() }; + if (kdSetWindowPropertyiv(m_kdWindow, KD_WINDOWPROPERTY_DESKTOP_OFFSET_NV, windowPos)) { + qErrnoWarning(kdGetError(), "Could not set native window position"); + return; + } + } + + + + + if (!isFullScreen || (isFullScreen && !QPlatformGLContext::defaultSharedContext())) { + if (kdRealizeWindow(m_kdWindow, &m_eglWindow)) { + qErrnoWarning(kdGetError(), "Could not realize native window"); + return; + } + + EGLSurface surface = eglCreateWindowSurface(screen->eglDisplay(),m_eglConfig,m_eglWindow,m_eglWindowAttrs.constData()); + m_platformGlContext = new QEGLPlatformContext(screen->eglDisplay(), m_eglConfig, + m_eglContextAttrs.data(), surface, m_eglApi); + m_platformGlContext->makeDefaultSaredContext(); + } else { + m_platformGlContext = static_cast<QEGLPlatformContext *>(QPlatformGLContext::defaultSharedContext()); + kdDestroyWindow(m_kdWindow); + m_kdWindow = 0; + } +} + + +QOpenKODEWindow::~QOpenKODEWindow() +{ + if (m_platformGlContext != QPlatformGLContext::defaultSharedContext()) { + delete m_platformGlContext; + } + if (m_kdWindow) + kdDestroyWindow(m_kdWindow); +} +void QOpenKODEWindow::setGeometry(const QRect &rect) +{ + if (isFullScreen) { + QList<QPlatformScreen *> screens = QApplicationPrivate::platformIntegration()->screens(); + QOpenKODEScreen *screen = qobject_cast<QOpenKODEScreen *>(screens.at(0)); + widget()->setGeometry(screen->geometry()); + return; + } + bool needToDeleteContext = false; + if (!isFullScreen) { + const QRect geo = geometry(); + if (geo.size() != rect.size()) { + const KDint windowSize[2] = { rect.width(), rect.height() }; + if (kdSetWindowPropertyiv(m_kdWindow, KD_WINDOWPROPERTY_SIZE, windowSize)) { + qErrnoWarning(kdGetError(), "Could not set native window size"); + //return; + } else { + needToDeleteContext = true; + } + } + + if (geo.topLeft() != rect.topLeft()) { + const KDint windowPos[2] = { rect.x(), rect.y() }; + if (kdSetWindowPropertyiv(m_kdWindow, KD_WINDOWPROPERTY_DESKTOP_OFFSET_NV, windowPos)) { + qErrnoWarning(kdGetError(), "Could not set native window position"); + //return; + } else { + needToDeleteContext = true; + } + } + } + + //need to recreate context + if (needToDeleteContext) { + qDebug() << "deleting context"; + delete m_platformGlContext; + + QList<QPlatformScreen *> screens = QApplicationPrivate::platformIntegration()->screens(); + QOpenKODEScreen *screen = qobject_cast<QOpenKODEScreen *>(screens.at(0)); + EGLSurface surface = eglCreateWindowSurface(screen->eglDisplay(),m_eglConfig,m_eglWindow,m_eglWindowAttrs.constData()); + m_platformGlContext = new QEGLPlatformContext(screen->eglDisplay(),m_eglConfig, + m_eglContextAttrs.data(),surface,m_eglApi); + } +} + +void QOpenKODEWindow::setVisible(bool visible) +{ + if (!m_kdWindow) + return; + KDboolean visibillity(visible); + if (kdSetWindowPropertybv(m_kdWindow, KD_WINDOWPROPERTY_VISIBILITY, &visibillity)) { + qErrnoWarning(kdGetError(), "Could not set visibillity property"); + } +} + +WId QOpenKODEWindow::winId() const +{ + static int i = 0; + return i++; +} + +QPlatformGLContext *QOpenKODEWindow::glContext() const +{ + return m_platformGlContext; +} + +void QOpenKODEWindow::raise() +{ + if (!m_kdWindow) + return; + KDboolean focus(true); + if (kdSetWindowPropertybv(m_kdWindow, KD_WINDOWPROPERTY_FOCUS, &focus)) { + qErrnoWarning(kdGetError(), "Could not set focus"); + } +} + +void QOpenKODEWindow::lower() +{ + if (!m_kdWindow) + return; + KDboolean focus(false); + if (kdSetWindowPropertybv(m_kdWindow, KD_WINDOWPROPERTY_FOCUS, &focus)) { + qErrnoWarning(kdGetError(), "Could not set focus"); + } +} + +void QOpenKODEWindow::processMouseEvents(const KDEvent *event) +{ + int x = event->data.inputpointer.x; + int y = event->data.inputpointer.y; + Qt::MouseButtons buttons; + switch(event->data.inputpointer.select) { + case 1: + buttons = Qt::LeftButton; + break; + default: + buttons = Qt::NoButton; + } + QPoint pos(x,y); + QWindowSystemInterface::handleMouseEvent(0,event->timestamp,pos,pos,buttons); +} + +void QOpenKODEWindow::processKeyEvents(const KDEvent *event) +{ +#ifdef KD_ATX_keyboard + //KD_KEY_PRESS_ATX 1 + QEvent::Type keyPressed = QEvent::KeyRelease; + if (event->data.keyboardInputKey.flags) + keyPressed = QEvent::KeyPress; +//KD_KEY_LOCATION_LEFT_ATX // dont care for now +//KD_KEY_LOCATION_RIGHT_ATX +//KD_KEY_LOCATION_NUMPAD_ATX + Qt::KeyboardModifiers mod = Qt::NoModifier; + int openkodeMods = event->data.keyboardInputKey.flags; + if (openkodeMods & KD_KEY_MODIFIER_SHIFT_ATX) + mod |= Qt::ShiftModifier; + if (openkodeMods & KD_KEY_MODIFIER_CTRL_ATX) + mod |= Qt::ControlModifier; + if (openkodeMods & KD_KEY_MODIFIER_ALT_ATX) + mod |= Qt::AltModifier; + if (openkodeMods & KD_KEY_MODIFIER_META_ATX) + mod |= Qt::MetaModifier; + + Qt::Key qtKey; + QChar keyText; + int key = event->data.keyboardInputKey.keycode; + if (key >= 0x20 && key <= 0x0ff){ // 8 bit printable Latin1 + qtKey = Qt::Key(key); + keyText = QChar(event->data.keyboardInputKeyChar.character); + if (!(mod & Qt::ShiftModifier)) + keyText = keyText.toLower(); + } else { + qtKey = keyTranslator(key); + } + QWindowSystemInterface::handleKeyEvent(0,event->timestamp,keyPressed,qtKey,mod,keyText); +#endif +} + +QT_END_NAMESPACE |