summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2010-06-10 00:13:48 -0700
committerJesse Barnes <jbarnes@virtuousgeek.org>2010-06-10 00:13:48 -0700
commit0af12782c9643082ac6b1bfe540bc31d8ad93cac (patch)
tree94cc629981277a799662a6005ed1436de74b9ac3
parentafa730a1c9d6ba0f57ee6be60135d01b7c343952 (diff)
Add initial Wayland app init code
Stolen from Wayland client code.
-rw-r--r--src/gui/kernel/qapplication.cpp4
-rw-r--r--src/gui/kernel/qapplication_p.h4
-rw-r--r--src/gui/kernel/qapplication_wayland.cpp465
-rw-r--r--src/gui/kernel/qcursor_wayland.cpp7
-rw-r--r--src/gui/kernel/qt_wayland_p.h31
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 */