diff options
author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2010-06-10 00:13:48 -0700 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2010-06-10 00:13:48 -0700 |
commit | 0af12782c9643082ac6b1bfe540bc31d8ad93cac (patch) | |
tree | 94cc629981277a799662a6005ed1436de74b9ac3 | |
parent | afa730a1c9d6ba0f57ee6be60135d01b7c343952 (diff) |
Add initial Wayland app init code
Stolen from Wayland client code.
-rw-r--r-- | src/gui/kernel/qapplication.cpp | 4 | ||||
-rw-r--r-- | src/gui/kernel/qapplication_p.h | 4 | ||||
-rw-r--r-- | src/gui/kernel/qapplication_wayland.cpp | 465 | ||||
-rw-r--r-- | src/gui/kernel/qcursor_wayland.cpp | 7 | ||||
-rw-r--r-- | src/gui/kernel/qt_wayland_p.h | 31 |
5 files changed, 212 insertions, 299 deletions
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index c9a3e8b168..e8b684d3df 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -81,6 +81,10 @@ #include <private/qt_x11_p.h> #endif +#ifdef Q_WS_WAYLAND +#include <private/qt_wayland_p.h> +#endif + #if defined(Q_WS_X11) || defined(Q_WS_S60) #include "qinputcontextfactory.h" #endif diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index 570111a824..ed998ae581 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -303,9 +303,6 @@ public: static bool qws_apply_settings(); static QWidget *findWidget(const QObjectList&, const QPoint &, bool rec); #endif -#if defined(Q_WS_WAYLAND) - static QWidget *findWidget(const QObjectList&, const QPoint &, bool rec); -#endif static bool quitOnLastWindowClosed; static void emitLastWindowClosed(); #ifdef Q_WS_WINCE @@ -360,6 +357,7 @@ public: KB_Gnome = 16, KB_CDE = 32, KB_S60 = 64, + KB_Wayland = 128, KB_All = 0xffff }; diff --git a/src/gui/kernel/qapplication_wayland.cpp b/src/gui/kernel/qapplication_wayland.cpp index cf854c2ac3..de57aa5b43 100644 --- a/src/gui/kernel/qapplication_wayland.cpp +++ b/src/gui/kernel/qapplication_wayland.cpp @@ -3,6 +3,8 @@ ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) +** Copyright (C) 2010 Intel Corporation +** All rights reserved. ** ** This file is part of the QtGui module of the Qt Toolkit. ** @@ -64,11 +66,11 @@ #include "private/qcursor_p.h" #include "qsettings.h" #include "qdebug.h" +#include "qt_wayland_p.h" +#include <private/qgraphicssystemfactory_p.h> +#include "qguieventdispatcher_glib_p.h" #include "qeventdispatcher_wayland_p.h" -#if !defined(QT_NO_GLIB) -# include "qeventdispatcher_glib_wayland_p.h" -#endif - +#include "qeventdispatcher_glib_wayland_p.h" #include "private/qwidget_p.h" #include "private/qbackingstore_p.h" @@ -82,131 +84,217 @@ #include <locale.h> #include <errno.h> #include <fcntl.h> -#ifdef Q_OS_VXWORKS -# include <sys/times.h> -#else -# include <sys/time.h> -#endif #include <sys/stat.h> #include <sys/types.h> -#include <qvfbhdr.h> - -#ifndef QT_NO_QWS_MULTIPROCESS -#ifdef QT_NO_QSHM #include <sys/ipc.h> #include <sys/shm.h> -#ifndef Q_OS_DARWIN -# include <sys/sem.h> -#endif +#include <sys/sem.h> #include <sys/socket.h> -#endif -#endif QT_BEGIN_NAMESPACE QWidget *qt_button_down = 0; -WId qt_last_cursor = 0xffffffff; +static const char dri_device[] = "/dev/dri/card0"; +static const char socket_name[] = "\0wayland"; static QString appName; -int *qt_last_x = 0; -int *qt_last_y = 0; + +Q_GUI_EXPORT QWaylandData *qWayland = 0; void QApplicationPrivate::createEventDispatcher() { + Q_Q(QApplication); + + if (!QEventDispatcherGlib::versionSupported()) + qFatal("glib version not supported\n"); + + eventDispatcher = (q->type() != QApplication::Tty + ? new QGuiEventDispatcherGlib(q) + : new QEventDispatcherGlib(q)); } void QApplicationPrivate::initializeWidgetPaletteHash() { } -static void init_display() +static void +display_handle_device(void *data, + struct wl_compositor *compositor, + const char *device) { - // FIXME: Connect to Wayland server + struct QWaylandData *d = (struct QWaylandData *)data; - // Get display parameters - // Set paintdevice parameters - // XXX initial info sent from server - // Misc. initialization - - QColormap::initialize(); - QFont::initialize(); -#ifndef QT_NO_CURSOR - QCursorData::initialize(); -#endif + d->device_name = strdup(device); +} - qApp->setObjectName(appName); +static void +display_handle_acknowledge(void *data, + struct wl_compositor *compositor, + uint32_t key, uint32_t frame) +{ + struct QWaylandData *d = (struct QWaylandData *)data; - if (!QApplicationPrivate::sys_font) { -#ifdef QT_NO_FREETYPE - QFont f = QFont(QLatin1String("helvetica"), 10); -#else - QFont f = QFont(QLatin1String("DejaVu Sans"), 12); -#endif - QApplicationPrivate::setSystemFont(f); - } + return; } -void qt_init_display() +static void +display_handle_frame(void *data, + struct wl_compositor *compositor, + uint32_t frame, uint32_t timestamp) { - qt_is_gui_used = true; - init_display(); + struct QWaylandData *d = (struct QWaylandData *)data; + + return; } -static bool read_bool_env_var(const char *var, bool defaultvalue) +static const struct wl_compositor_listener compositor_listener = { + display_handle_device, + display_handle_acknowledge, + display_handle_frame, +}; + +static void +display_handle_geometry(void *data, + struct wl_output *output, + int32_t width, int32_t height) { - // returns true if env variable is set to non-zero - // returns false if env var is set to zero - // returns defaultvalue if env var not set - char *x = ::getenv(var); - return (x && *x) ? (strcmp(x,"0") != 0) : defaultvalue; + struct QWaylandData *d = (struct QWaylandData *)data; + + d->x = 0; + d->y = 0; + d->width = width; + d->height = height; } -static int read_int_env_var(const char *var, int defaultvalue) +static const struct wl_output_listener output_listener = { + display_handle_geometry, +}; + +static void +display_handle_global(struct wl_display *display, struct wl_object *object, + void *data) { - bool ok; - int r = qgetenv(var).toInt(&ok); - return ok ? r : defaultvalue; + struct QWaylandData *d = (struct QWaylandData *)data; + + if (wl_object_implements(object, "compositor", 1)) { + d->compositor = (struct wl_compositor *) object; + wl_compositor_add_listener(d->compositor, &compositor_listener, d); + } else if (wl_object_implements(object, "output", 1)) { + d->output = (struct wl_output *) object; + wl_output_add_listener(d->output, &output_listener, d); + } else if (wl_object_implements(object, "input_device", 1)) { + d->input_device =(struct wl_input_device *) object; + } } void qt_init(QApplicationPrivate *priv, int type) { -#ifdef QT_NO_QWS_MULTIPROCESS - if (type == QApplication::GuiClient) - type = QApplication::GuiServer; -#endif - if (type == QApplication::GuiServer) - qt_is_gui_used = false; //we'll turn it on in a second + PFNEGLGETTYPEDDISPLAYMESA get_typed_display_mesa; + EGLint major, minor, count; + EGLDisplay dpy; + EGLContext ctx; + EGLConfig config; + GOptionContext *context; + GError *error; + char *p; + int fd; + struct wl_display *d; + + static const EGLint config_attribs[] = { + EGL_SURFACE_TYPE, 0, + EGL_NO_SURFACE_CAPABLE_MESA, EGL_OPENGL_ES_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, + EGL_NONE + }; + + qWayland = new QWaylandData; + if (!qWayland) + qFatal("couldn't create Wayland connection, out of memory\n"); + + if (!qt_is_gui_used) + return; + + get_typed_display_mesa = + (PFNEGLGETTYPEDDISPLAYMESA)eglGetProcAddress("eglGetTypedDisplayMESA"); + if (!get_typed_display_mesa) + qFatal("failed to find MESA_get_typed_display extension\n"); + + fd = open(dri_device, O_RDWR); + if (fd < 0) { + qFatal("failed to open DRI device: %s\n", strerror(errno)); + return; + } - priv->inputContext = 0; + dpy = get_typed_display_mesa(EGL_DRM_DISPLAY_TYPE_MESA, (void *) fd); + if (!eglInitialize(dpy, &major, &minor)) { + close(fd); + qFatal("failed to initialize EGL\n"); + } - int flags = 0; - char *p; - int argc = priv->argc; - char **argv = priv->argv; - int j; + if (!eglChooseConfig(dpy, config_attribs, &config, 1, &count) || + count == 0) { + close(fd); + qFatal("failed to choose EGL config\n"); + } - // Set application name + eglBindAPI(EGL_OPENGL_ES_API); - if (argv && *argv) { //apparently, we allow people to pass 0 on the other platforms - p = strrchr(argv[0], '/'); - appName = QString::fromLocal8Bit(p ? p + 1 : argv[0]); + ctx = eglCreateContext(dpy, config, EGL_NO_CONTEXT, NULL); + if (ctx == NULL) { + close(fd); + qFatal("failed to create EGL context\n"); } - // Get command line params + if (!eglMakeCurrent(dpy, NULL, NULL, ctx)) { + close(fd); + qFatal("failed to make EGL context current\n"); + } - j = argc ? 1 : 0; - QString decoration; - for (int i=1; i<argc; i++) { - if (argv[i] && *argv[i] != '-') { - argv[j++] = argv[i]; - continue; - } + d = wl_display_create(socket_name, sizeof(socket_name)); + if (!d) { + close(fd); + qFatal("failed to create wayland display: %s\n", strerror(errno)); + return; } - if(j < priv->argc) { - priv->argv[j] = 0; - priv->argc = j; + + /* Set up listener so we'll catch all events. */ + if (!wl_display_add_global_listener(d, display_handle_global, qWayland)) { + close(fd); + wl_display_destroy(d); + qFatal("failed to add compositor listener\n"); } + + /* Process connection events. */ + wl_display_iterate(d, WL_DISPLAY_READABLE); + + qWayland->dri_fd = fd; + qWayland->display = d; + qWayland->dpy = dpy; + qWayland->ctx = ctx; + priv->inputContext = 0; + + // Set application name + + if (priv->argv && *priv->argv) { + p = strrchr(priv->argv[0], '/'); + appName = QString::fromLocal8Bit(p ? p + 1 : priv->argv[0]); + } + + QApplicationPrivate::graphics_system = + QGraphicsSystemFactory::create("opengl"); + QColormap::initialize(); + QFont::initialize(); + QCursorData::initialize(); + + if (!QApplicationPrivate::sys_font) { + // no font from settings or RESOURCE_MANAGER, provide a fallback + QFont f(QLatin1String("Sans Serif"), 9); + QApplicationPrivate::setSystemFont(f); + } + + qApp->setObjectName(appName); + } /***************************************************************************** @@ -216,9 +304,7 @@ void qt_init(QApplicationPrivate *priv, int type) void qt_cleanup() { QPixmapCache::clear(); -#ifndef QT_NO_CURSOR QCursorData::cleanup(); -#endif QFont::cleanup(); QColormap::cleanup(); } @@ -237,167 +323,6 @@ QString QApplicationPrivate::appName() const // get application name Platform specific QApplication members *****************************************************************************/ -#define NoValue 0x0000 -#define XValue 0x0001 -#define YValue 0x0002 -#define WidthValue 0x0004 -#define HeightValue 0x0008 -#define AllValues 0x000F -#define XNegative 0x0010 -#define YNegative 0x0020 - -/* Copyright notice for ReadInteger and parseGeometry - -Copyright (c) 1985, 1986, 1987 X Consortium - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of the X Consortium shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the X Consortium. - -*/ -/* - * XParseGeometry parses strings of the form - * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where - * width, height, xoffset, and yoffset are unsigned integers. - * Example: "=80x24+300-49" - * The equal sign is optional. - * It returns a bitmask that indicates which of the four values - * were actually found in the string. For each value found, - * the corresponding argument is updated; for each value - * not found, the corresponding argument is left unchanged. - */ - -static int -ReadInteger(char *string, char **NextString) -{ - register int Result = 0; - int Sign = 1; - - if (*string == '+') - string++; - else if (*string == '-') - { - string++; - Sign = -1; - } - for (; (*string >= '0') && (*string <= '9'); string++) - { - Result = (Result * 10) + (*string - '0'); - } - *NextString = string; - if (Sign >= 0) - return Result; - else - return -Result; -} - -static int parseGeometry(const char* string, - int* x, int* y, int* width, int* height) -{ - int mask = NoValue; - register char *strind; - unsigned int tempWidth=0, tempHeight=0; - int tempX=0, tempY=0; - char *nextCharacter; - - if (!string || (*string == '\0')) return mask; - if (*string == '=') - string++; /* ignore possible '=' at beg of geometry spec */ - - strind = const_cast<char *>(string); - if (*strind != '+' && *strind != '-' && *strind != 'x') { - tempWidth = ReadInteger(strind, &nextCharacter); - if (strind == nextCharacter) - return 0; - strind = nextCharacter; - mask |= WidthValue; - } - - if (*strind == 'x' || *strind == 'X') { - strind++; - tempHeight = ReadInteger(strind, &nextCharacter); - if (strind == nextCharacter) - return 0; - strind = nextCharacter; - mask |= HeightValue; - } - - if ((*strind == '+') || (*strind == '-')) { - if (*strind == '-') { - strind++; - tempX = -ReadInteger(strind, &nextCharacter); - if (strind == nextCharacter) - return 0; - strind = nextCharacter; - mask |= XNegative; - - } - else - { strind++; - tempX = ReadInteger(strind, &nextCharacter); - if (strind == nextCharacter) - return 0; - strind = nextCharacter; - } - mask |= XValue; - if ((*strind == '+') || (*strind == '-')) { - if (*strind == '-') { - strind++; - tempY = -ReadInteger(strind, &nextCharacter); - if (strind == nextCharacter) - return 0; - strind = nextCharacter; - mask |= YNegative; - - } - else - { - strind++; - tempY = ReadInteger(strind, &nextCharacter); - if (strind == nextCharacter) - return 0; - strind = nextCharacter; - } - mask |= YValue; - } - } - - /* If strind isn't at the end of the string then it's an invalid - geometry specification. */ - - if (*strind != '\0') return 0; - - if (mask & XValue) - *x = tempX; - if (mask & YValue) - *y = tempY; - if (mask & WidthValue) - *width = tempWidth; - if (mask & HeightValue) - *height = tempHeight; - return mask; -} - #ifdef QT3_SUPPORT void QApplication::setMainWidget(QWidget *mainWidget) { @@ -408,7 +333,6 @@ void QApplication::setMainWidget(QWidget *mainWidget) /***************************************************************************** QApplication cursor stack *****************************************************************************/ -#ifndef QT_NO_CURSOR void QApplication::setOverrideCursor(const QCursor &cursor) { } @@ -416,7 +340,6 @@ void QApplication::setOverrideCursor(const QCursor &cursor) void QApplication::restoreOverrideCursor() { } -#endif// QT_NO_CURSOR @@ -424,63 +347,25 @@ void QApplication::restoreOverrideCursor() Routines to find a Qt widget from a screen position *****************************************************************************/ -/*! - \internal -*/ -QWidget *QApplicationPrivate::findWidget(const QObjectList& list, - const QPoint &pos, bool rec) -{ - QWidget *w; - - for (int i = list.size()-1; i >= 0; --i) { - if (list.at(i)->isWidgetType()) { - w = static_cast<QWidget*>(list.at(i)); - if (w->isVisible() && !w->testAttribute(Qt::WA_TransparentForMouseEvents) && w->geometry().contains(pos) - && (!w->d_func()->extra || w->d_func()->extra->mask.isEmpty() || w->d_func()->extra->mask.contains(pos - w->geometry().topLeft()) )) { - if (!rec) - return w; - QWidget *c = w->childAt(w->mapFromParent(pos)); - return c ? c : w; - } - } - } - return 0; -} - - QWidget *QApplication::topLevelAt(const QPoint &pos) { - //### QWSDisplay::windowAt() is currently only implemented in the server process - //int winId = QPaintDevice::qwsDisplay()->windowAt(pos); - //if (winId !=0) - //return QWidget::find(winId); - -#if 1 - // fallback implementation for client processes -//### This is slightly wrong: we have no guarantee that the list is in -//### stacking order, so if the topmost window is transparent, we may -//### return the wrong widget - - QWidgetList list = topLevelWidgets(); - for (int i = list.size()-1; i >= 0; --i) { - QWidget *w = list[i]; - if (w != QApplication::desktop() && w->isVisible()) - return w; - } -#endif return 0; } void QApplication::beep() { + // don't beep } -void QApplication::alert(QWidget *, int) +void QApplication::alert(QWidget *widget, int msec) { + // notify wayland that this widget needs attention + // timeout the "alert" status after msec milliseconds } int QApplication::waylandProcessEvent(const struct wl_message *msg) { + // handle input and gui events here } bool QApplication::waylandEventFilter(struct wl_message *msg) diff --git a/src/gui/kernel/qcursor_wayland.cpp b/src/gui/kernel/qcursor_wayland.cpp index 92589960af..a3c8c14f5b 100644 --- a/src/gui/kernel/qcursor_wayland.cpp +++ b/src/gui/kernel/qcursor_wayland.cpp @@ -104,16 +104,11 @@ void QCursorData::update() #endif //QT_NO_CURSOR -extern int *qt_last_x,*qt_last_y; - QPoint QCursor::pos() { // This doesn't know about hotspots yet so we disable it //qt_accel_update_cursor(); - if (qt_last_x) - return QPoint(*qt_last_x, *qt_last_y); - else - return QPoint(); + return QPoint(); } void QCursor::setPos(int x, int y) diff --git a/src/gui/kernel/qt_wayland_p.h b/src/gui/kernel/qt_wayland_p.h new file mode 100644 index 0000000000..a95ba0063a --- /dev/null +++ b/src/gui/kernel/qt_wayland_p.h @@ -0,0 +1,31 @@ +#ifndef QT_WAYLAND_P_H +#define QT_WAYLAND_P_H + +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <glib.h> +#include <glib-object.h> +#include <wayland-client.h> +#include <wayland-util.h> + +// App global Wayland connection info + +struct QWaylandData { + int dri_fd; + struct wl_display *display; + struct wl_compositor *compositor; + struct wl_output *output; + struct wl_input_device *input_device; + char *device_name; + struct wl_list window_list; + EGLDisplay dpy; + EGLContext ctx; + int x; + int y; + int width; + int height; +}; + +extern QWaylandData *qWayland; + +#endif /* QT_WAYLAND_P_H */ |