OSDN Git Service

Revert "get rid of X11 function wrappers"
authorIvailo Monev <xakepa10@laimg.moc>
Sat, 4 May 2019 17:11:59 +0000 (17:11 +0000)
committerIvailo Monev <xakepa10@laimg.moc>
Sat, 4 May 2019 17:11:59 +0000 (17:11 +0000)
This reverts commit ebc49b34ffdf7d1061bfcd29f77be6dc8563cb74.

src/gui/kernel/kernel.cmake
src/gui/kernel/qguieventdispatcher_glib.cpp [new file with mode: 0644]
src/gui/kernel/qwidget_x11.cpp

index 8afc763..c9bc176 100644 (file)
@@ -94,6 +94,7 @@ if(WITH_X11 AND X11_FOUND)
         ${CMAKE_CURRENT_SOURCE_DIR}/kernel/qdesktopwidget_x11.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/kernel/qmotifdnd_x11.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/kernel/qwidget_x11.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/kernel/qwidgetcreate_x11.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/kernel/qx11embed_x11.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/kernel/qx11info_x11.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/kernel/qkeymapper_x11.cpp
diff --git a/src/gui/kernel/qguieventdispatcher_glib.cpp b/src/gui/kernel/qguieventdispatcher_glib.cpp
new file mode 100644 (file)
index 0000000..5b96462
--- /dev/null
@@ -0,0 +1,226 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qguieventdispatcher_glib_p.h"
+
+#include "qapplication.h"
+#include "qx11info_x11.h"
+
+#include "qt_x11_p.h"
+
+#include <glib.h>
+
+QT_BEGIN_NAMESPACE
+
+struct GX11EventSource
+{
+    GSource source;
+    GPollFD pollfd;
+    QEventLoop::ProcessEventsFlags flags;
+    QGuiEventDispatcherGlib *q;
+    QGuiEventDispatcherGlibPrivate *d;
+};
+
+class QGuiEventDispatcherGlibPrivate : public QEventDispatcherGlibPrivate
+{
+    Q_DECLARE_PUBLIC(QGuiEventDispatcherGlib)
+
+public:
+    QGuiEventDispatcherGlibPrivate();
+    GX11EventSource *x11EventSource;
+    QList<XEvent> queuedUserInputEvents;
+};
+
+static gboolean x11EventSourcePrepare(GSource *s, gint *timeout)
+{
+    if (timeout)
+        *timeout = -1;
+    GX11EventSource *source = reinterpret_cast<GX11EventSource *>(s);
+    return (XEventsQueued(qt_x11Data->display, QueuedAfterFlush)
+            || (!(source->flags & QEventLoop::ExcludeUserInputEvents)
+                && !source->d->queuedUserInputEvents.isEmpty()));
+}
+
+static gboolean x11EventSourceCheck(GSource *s)
+{
+    GX11EventSource *source = reinterpret_cast<GX11EventSource *>(s);
+    return (XEventsQueued(qt_x11Data->display, QueuedAfterFlush)
+            || (!(source->flags & QEventLoop::ExcludeUserInputEvents)
+                && !source->d->queuedUserInputEvents.isEmpty()));
+}
+
+static gboolean x11EventSourceDispatch(GSource *s, GSourceFunc callback, gpointer user_data)
+{
+    GX11EventSource *source = reinterpret_cast<GX11EventSource *>(s);
+
+    ulong marker = XNextRequest(qt_x11Data->display);
+    do {
+        XEvent event;
+        if (!(source->flags & QEventLoop::ExcludeUserInputEvents)
+            && !source->d->queuedUserInputEvents.isEmpty()) {
+            // process a pending user input event
+            event = source->d->queuedUserInputEvents.takeFirst();
+        } else if (XEventsQueued(qt_x11Data->display, QueuedAlready)) {
+            // process events from the X server
+            XNextEvent(qt_x11Data->display, &event);
+
+            if (source->flags & QEventLoop::ExcludeUserInputEvents) {
+                // queue user input events
+                switch (event.type) {
+                case ButtonPress:
+                case ButtonRelease:
+                case MotionNotify:
+                case XKeyPress:
+                case XKeyRelease:
+                case EnterNotify:
+                case LeaveNotify:
+                    source->d->queuedUserInputEvents.append(event);
+                    continue;
+
+                case ClientMessage:
+                    // only keep the wm_take_focus and
+                    // _qt_scrolldone protocols, queue all other
+                    // client messages
+                    if (event.xclient.format == 32) {
+                        if (event.xclient.message_type == ATOM(WM_PROTOCOLS) &&
+                            (Atom) event.xclient.data.l[0] == ATOM(WM_TAKE_FOCUS)) {
+                            break;
+                        } else if (event.xclient.message_type == ATOM(_QT_SCROLL_DONE)) {
+                            break;
+                        }
+                    }
+                    source->d->queuedUserInputEvents.append(event);
+                    continue;
+
+                default:
+                    break;
+                }
+            }
+        } else {
+            // no event to process
+            break;
+        }
+
+        // send through event filter
+        if (source->q->filterEvent(&event))
+            continue;
+
+        if (qApp->x11ProcessEvent(&event) == 1)
+            return true;
+
+        if (event.xany.serial >= marker)
+            goto out;
+    } while (XEventsQueued(qt_x11Data->display, QueuedAfterFlush));
+
+ out:
+
+    source->d->runTimersOnceWithNormalPriority();
+
+    if (callback)
+        callback(user_data);
+    return true;
+}
+
+static GSourceFuncs x11EventSourceFuncs = {
+    x11EventSourcePrepare,
+    x11EventSourceCheck,
+    x11EventSourceDispatch,
+    NULL,
+    NULL,
+    NULL
+};
+
+QGuiEventDispatcherGlibPrivate::QGuiEventDispatcherGlibPrivate()
+{
+    x11EventSource = reinterpret_cast<GX11EventSource *>(g_source_new(&x11EventSourceFuncs,
+                                                                      sizeof(GX11EventSource)));
+    g_source_set_can_recurse(&x11EventSource->source, true);
+
+    memset(&x11EventSource->pollfd, 0, sizeof(GPollFD));
+    x11EventSource->flags = QEventLoop::AllEvents;
+    x11EventSource->q = 0;
+    x11EventSource->d = 0;
+
+    g_source_attach(&x11EventSource->source, mainContext);
+}
+
+QGuiEventDispatcherGlib::QGuiEventDispatcherGlib(QObject *parent)
+    : QEventDispatcherGlib(*new QGuiEventDispatcherGlibPrivate, parent)
+{
+}
+
+QGuiEventDispatcherGlib::~QGuiEventDispatcherGlib()
+{
+    Q_D(QGuiEventDispatcherGlib);
+
+    g_source_remove_poll(&d->x11EventSource->source, &d->x11EventSource->pollfd);
+    g_source_destroy(&d->x11EventSource->source);
+    d->x11EventSource = 0;
+}
+
+bool QGuiEventDispatcherGlib::processEvents(QEventLoop::ProcessEventsFlags flags)
+{
+    Q_D(QGuiEventDispatcherGlib);
+    QEventLoop::ProcessEventsFlags saved_flags = d->x11EventSource->flags;
+    d->x11EventSource->flags = flags;
+    bool returnValue = QEventDispatcherGlib::processEvents(flags);
+    d->x11EventSource->flags = saved_flags;
+    return returnValue;
+}
+
+void QGuiEventDispatcherGlib::startingUp()
+{
+    Q_D(QGuiEventDispatcherGlib);
+    d->x11EventSource->pollfd.fd = XConnectionNumber(qt_x11Data->display);
+    d->x11EventSource->pollfd.events = G_IO_IN | G_IO_HUP | G_IO_ERR;
+    d->x11EventSource->q = this;
+    d->x11EventSource->d = d;
+    g_source_add_poll(&d->x11EventSource->source, &d->x11EventSource->pollfd);
+}
+
+void QGuiEventDispatcherGlib::flush()
+{
+    XFlush(qt_x11Data->display);
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qguieventdispatcher_glib_p.h"
index 1bdfd88..a9c301f 100644 (file)
@@ -199,6 +199,25 @@ const uint stdDesktopEventMask =                        // X event mask
            PropertyChangeMask
       );
 
+
+/*
+  The qt_ functions below are implemented in qwidgetcreate_x11.cpp.
+*/
+
+Window qt_XCreateWindow(const QWidget *creator,
+                         Display *display, Window parent,
+                         int x, int y, uint w, uint h,
+                         int borderwidth, int depth,
+                         uint windowclass, Visual *visual,
+                         ulong valuemask, XSetWindowAttributes *attributes);
+Window qt_XCreateSimpleWindow(const QWidget *creator,
+                               Display *display, Window parent,
+                               int x, int y, uint w, uint h, int borderwidth,
+                               ulong border, ulong background);
+void qt_XDestroyWindow(const QWidget *destroyer,
+                        Display *display, Window window);
+
+
 static void qt_insert_sip(QWidget* scrolled_widget, int dx, int dy)
 {
     if (!scrolled_widget->isWindow() && !scrolled_widget->internalWinId())
@@ -595,23 +614,23 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO
         }
 #endif
         if (xinfo.defaultVisual() && xinfo.defaultColormap()) {
-            id = (WId)XCreateSimpleWindow(dpy, parentw,
-                                            safeRect.left(), safeRect.top(),
-                                            safeRect.width(), safeRect.height(),
-                                            0,
-                                            BlackPixel(dpy, xinfo.screen()),
-                                            WhitePixel(dpy, xinfo.screen()));
+            id = (WId)qt_XCreateSimpleWindow(q, dpy, parentw,
+                                             safeRect.left(), safeRect.top(),
+                                             safeRect.width(), safeRect.height(),
+                                             0,
+                                             BlackPixel(dpy, xinfo.screen()),
+                                             WhitePixel(dpy, xinfo.screen()));
         } else {
             wsa.background_pixel = WhitePixel(dpy, xinfo.screen());
             wsa.border_pixel = BlackPixel(dpy, xinfo.screen());
             wsa.colormap = xinfo.colormap();
-            id = (WId)XCreateWindow(dpy, parentw,
-                                    safeRect.left(), safeRect.top(),
-                                    safeRect.width(), safeRect.height(),
-                                    0, xinfo.depth(), InputOutput,
-                                    (Visual *) xinfo.visual(),
-                                    CWBackPixel|CWBorderPixel|CWColormap,
-                                    &wsa);
+            id = (WId)qt_XCreateWindow(q, dpy, parentw,
+                                       safeRect.left(), safeRect.top(),
+                                       safeRect.width(), safeRect.height(),
+                                       0, xinfo.depth(), InputOutput,
+                                       (Visual *) xinfo.visual(),
+                                       CWBackPixel|CWBorderPixel|CWColormap,
+                                       &wsa);
         }
 
         setWinId(id);                                // set widget id/handle + hd
@@ -846,7 +865,7 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO
         XShapeCombineRegion(qt_x11Data->display, q->internalWinId(), ShapeBounding, 0, 0,
                             extra->mask.handle(), ShapeSet);
     if (destroyw) {
-        XDestroyWindow(dpy, destroyw);
+        qt_XDestroyWindow(q, dpy, destroyw);
         if (QTLWExtra *topData = maybeTopData()) {
 #ifndef QT_NO_XSYNC
             if (topData->syncUpdateCounter)
@@ -1006,7 +1025,7 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
             if (isWindow())
                 qt_x11Data->dndEnable(this, false);
             if (destroyWindow)
-                XDestroyWindow(qt_x11Data->display, data->winid);
+                qt_XDestroyWindow(this, qt_x11Data->display, data->winid);
         }
         QT_TRY {
             d->setWinId(0);
@@ -1189,7 +1208,7 @@ void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f)
                 delete [] cmw;
             }
 
-            XDestroyWindow(qt_x11Data->display, old_winid);
+            qt_XDestroyWindow(q, qt_x11Data->display, old_winid);
         }
     }