320113f58d1ce00cbfe9e4d86b14e13767c59634
[profile/ivi/qtwayland.git] / src / plugins / platforms / wayland / gl_integration / xcomposite_egl / qwaylandxcompositeeglwindow.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the plugins of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qwaylandxcompositeeglwindow.h"
43 #include "qwaylandxcompositebuffer.h"
44
45 #include <QtPlatformSupport/private/qeglconvenience_p.h>
46 #include <QtPlatformSupport/private/qxlibeglintegration_p.h>
47
48 #include "wayland-xcomposite-client-protocol.h"
49
50 #include <X11/extensions/Xcomposite.h>
51 #include "qwaylandxcompositeeglintegration.h"
52 #include "windowmanager_integration/qwaylandwindowmanagerintegration.h"
53
54 #include <QtCore/QDebug>
55
56 QWaylandXCompositeEGLWindow::QWaylandXCompositeEGLWindow(QWindow *window, QWaylandXCompositeEGLIntegration *glxIntegration)
57     : QWaylandWindow(window)
58     , m_glxIntegration(glxIntegration)
59     , m_context(0)
60     , m_buffer(0)
61     , m_xWindow(0)
62     , m_config(q_configFromGLFormat(glxIntegration->eglDisplay(), window->format(), true))
63     , m_surface(0)
64     , m_waitingForSync(false)
65 {
66 }
67
68 QWaylandWindow::WindowType QWaylandXCompositeEGLWindow::windowType() const
69 {
70     //yeah. this type needs a new name
71     return QWaylandWindow::Egl;
72 }
73
74 void QWaylandXCompositeEGLWindow::setGeometry(const QRect &rect)
75 {
76     QWaylandWindow::setGeometry(rect);
77
78     if (m_surface) {
79         eglDestroySurface(m_glxIntegration->eglDisplay(), m_surface);
80         m_surface = 0;
81     }
82 }
83
84 EGLSurface QWaylandXCompositeEGLWindow::eglSurface() const
85 {
86     if (!m_surface)
87         const_cast<QWaylandXCompositeEGLWindow *>(this)->createEglSurface();
88     return m_surface;
89 }
90
91 void QWaylandXCompositeEGLWindow::createEglSurface()
92 {
93     QSize size(geometry().size());
94     if (size.isEmpty()) {
95         // QGLWidget wants a context for a window without geometry
96         size = QSize(1,1);
97     }
98
99     delete m_buffer;
100     //XFreePixmap deletes the glxPixmap as well
101     if (m_xWindow) {
102         XDestroyWindow(m_glxIntegration->xDisplay(), m_xWindow);
103     }
104
105     VisualID visualId = QXlibEglIntegration::getCompatibleVisualId(m_glxIntegration->xDisplay(), m_glxIntegration->eglDisplay(), m_config);
106
107     XVisualInfo visualInfoTemplate;
108     memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
109     visualInfoTemplate.visualid = visualId;
110
111     int matchingCount = 0;
112     XVisualInfo *visualInfo = XGetVisualInfo(m_glxIntegration->xDisplay(), VisualIDMask, &visualInfoTemplate, &matchingCount);
113
114     Colormap cmap = XCreateColormap(m_glxIntegration->xDisplay(),m_glxIntegration->rootWindow(),visualInfo->visual,AllocNone);
115
116     XSetWindowAttributes a;
117     a.colormap = cmap;
118     m_xWindow = XCreateWindow(m_glxIntegration->xDisplay(), m_glxIntegration->rootWindow(),0, 0, size.width(), size.height(),
119                              0, visualInfo->depth, InputOutput, visualInfo->visual,
120                              CWColormap, &a);
121
122     XCompositeRedirectWindow(m_glxIntegration->xDisplay(), m_xWindow, CompositeRedirectManual);
123     XMapWindow(m_glxIntegration->xDisplay(), m_xWindow);
124
125     m_surface = eglCreateWindowSurface(m_glxIntegration->eglDisplay(), m_config, m_xWindow,0);
126     if (m_surface == EGL_NO_SURFACE) {
127         qFatal("Could not make eglsurface");
128     }
129
130     XSync(m_glxIntegration->xDisplay(),False);
131     mBuffer = new QWaylandXCompositeBuffer(m_glxIntegration->waylandXComposite(),
132                                            (uint32_t)m_xWindow,
133                                            size,
134                                            m_glxIntegration->waylandDisplay()->argbVisual());
135     attach(m_buffer);
136     wl_display_sync_callback(m_glxIntegration->waylandDisplay()->wl_display(),
137                              QWaylandXCompositeEGLWindow::sync_function,
138                              this);
139
140     m_waitingForSync = true;
141     wl_display_sync(m_glxIntegration->waylandDisplay()->wl_display(),0);
142     m_glxIntegration->waylandDisplay()->flushRequests();
143     while (m_waitingForSync)
144         m_glxIntegration->waylandDisplay()->readEvents();
145 }
146
147 void QWaylandXCompositeEGLWindow::sync_function(void *data)
148 {
149     QWaylandXCompositeEGLWindow *that = static_cast<QWaylandXCompositeEGLWindow *>(data);
150     that->m_waitingForSync = false;
151 }
152
153 void QWaylandXCompositeEGLWindow::requestActivateWindow()
154 {
155 #ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT
156     mDisplay->windowManagerIntegration()->authenticateWithToken();
157 #endif
158
159     QWaylandWindow::requestActivateWindow();
160 }