Change copyrights from Nokia to Digia
[profile/ivi/qtwayland.git] / src / plugins / platforms / wayland / gl_integration / xcomposite_glx / qwaylandxcompositeglxwindow.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 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 "qwaylandxcompositeglxwindow.h"
43 #include "qwaylandxcompositebuffer.h"
44
45 #include <QtCore/QDebug>
46
47 #include "wayland-xcomposite-client-protocol.h"
48 #include <QtGui/QRegion>
49
50 #include <X11/extensions/Xcomposite.h>
51
52 QWaylandXCompositeGLXWindow::QWaylandXCompositeGLXWindow(QWindow *window, QWaylandXCompositeGLXIntegration *glxIntegration)
53     : QWaylandWindow(window)
54     , m_glxIntegration(glxIntegration)
55     , m_xWindow(0)
56     , m_config(qglx_findConfig(glxIntegration->xDisplay(), glxIntegration->screen(), window->format(), GLX_WINDOW_BIT | GLX_PIXMAP_BIT))
57     , m_buffer(0)
58     , m_syncCallback(0)
59 {
60 }
61
62 QWaylandWindow::WindowType QWaylandXCompositeGLXWindow::windowType() const
63 {
64     //yeah. this type needs a new name
65     return QWaylandWindow::Egl;
66 }
67
68 void QWaylandXCompositeGLXWindow::setGeometry(const QRect &rect)
69 {
70     QWaylandWindow::setGeometry(rect);
71
72     if (m_xWindow) {
73         delete m_buffer;
74
75         XDestroyWindow(m_glxIntegration->xDisplay(), m_xWindow);
76         m_xWindow = 0;
77     }
78 }
79
80 Window QWaylandXCompositeGLXWindow::xWindow() const
81 {
82     if (!m_xWindow)
83         const_cast<QWaylandXCompositeGLXWindow *>(this)->createSurface();
84
85     return m_xWindow;
86 }
87
88 void QWaylandXCompositeGLXWindow::waitForSync()
89 {
90     if (!m_syncCallback) {
91         struct wl_display *dpy = m_glxIntegration->waylandDisplay()->wl_display();
92         m_syncCallback = wl_display_sync(dpy);
93         wl_callback_add_listener(m_syncCallback, &sync_callback_listener, this);
94     }
95     m_glxIntegration->waylandDisplay()->flushRequests();
96     while (m_syncCallback)
97         m_glxIntegration->waylandDisplay()->readEvents();
98 }
99
100 const struct wl_callback_listener QWaylandXCompositeGLXWindow::sync_callback_listener = {
101     QWaylandXCompositeGLXWindow::sync_function
102 };
103
104 void QWaylandXCompositeGLXWindow::createSurface()
105 {
106     QSize size(geometry().size());
107     if (size.isEmpty()) {
108         //QGLWidget wants a context for a window without geometry
109         size = QSize(1,1);
110     }
111
112     if (!m_glxIntegration->xDisplay()) {
113         qWarning("XCompositeGLXWindow: X display still null?!");
114         return;
115     }
116
117     XVisualInfo *visualInfo = glXGetVisualFromFBConfig(m_glxIntegration->xDisplay(), m_config);
118     Colormap cmap = XCreateColormap(m_glxIntegration->xDisplay(), m_glxIntegration->rootWindow(),
119             visualInfo->visual, AllocNone);
120
121     XSetWindowAttributes a;
122     a.background_pixel = WhitePixel(m_glxIntegration->xDisplay(), m_glxIntegration->screen());
123     a.border_pixel = BlackPixel(m_glxIntegration->xDisplay(), m_glxIntegration->screen());
124     a.colormap = cmap;
125     m_xWindow = XCreateWindow(m_glxIntegration->xDisplay(), m_glxIntegration->rootWindow(),0, 0, size.width(), size.height(),
126                               0, visualInfo->depth, InputOutput, visualInfo->visual,
127                               CWBackPixel|CWBorderPixel|CWColormap, &a);
128
129     XCompositeRedirectWindow(m_glxIntegration->xDisplay(), m_xWindow, CompositeRedirectManual);
130     XMapWindow(m_glxIntegration->xDisplay(), m_xWindow);
131
132     XSync(m_glxIntegration->xDisplay(), False);
133     m_buffer = new QWaylandXCompositeBuffer(m_glxIntegration->waylandXComposite(),
134                                             (uint32_t)m_xWindow,
135                                             size);
136     attach(m_buffer);
137     waitForSync();
138 }
139
140 void QWaylandXCompositeGLXWindow::sync_function(void *data, struct wl_callback *callback, uint32_t time)
141 {
142     Q_UNUSED(time);
143     QWaylandXCompositeGLXWindow *that = static_cast<QWaylandXCompositeGLXWindow *>(data);
144     if (that->m_syncCallback != callback)
145         return;
146     that->m_syncCallback = 0;
147     wl_callback_destroy(callback);
148 }