Qt 4.8
qwaylanddisplay.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 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 "qwaylanddisplay.h"
43 
44 #include "qwaylandwindow.h"
45 #include "qwaylandscreen.h"
46 #include "qwaylandcursor.h"
47 #include "qwaylandinputdevice.h"
48 #include "qwaylandclipboard.h"
49 
50 #ifdef QT_WAYLAND_GL_SUPPORT
52 #endif
53 
54 #ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT
56 #endif
57 
58 #include <QtCore/QAbstractEventDispatcher>
59 #include <QtGui/QApplication>
60 #include <QtGui/private/qapplication_p.h>
61 
62 #include <unistd.h>
63 #include <fcntl.h>
64 #include <stdio.h>
65 #include <errno.h>
66 
67 struct wl_surface *QWaylandDisplay::createSurface(void *handle)
68 {
69  struct wl_surface * surface = wl_compositor_create_surface(mCompositor);
70  wl_surface_set_user_data(surface, handle);
71  return surface;
72 }
73 
74 struct wl_buffer *QWaylandDisplay::createShmBuffer(int fd,
75  int width, int height,
76  uint32_t stride,
77  struct wl_visual *visual)
78 {
79  return wl_shm_create_buffer(mShm, fd, width, height, stride, visual);
80 }
81 
82 struct wl_visual *QWaylandDisplay::rgbVisual()
83 {
84  return rgb_visual;
85 }
86 
87 struct wl_visual *QWaylandDisplay::argbVisual()
88 {
89  return argb_visual;
90 }
91 
93 {
95 }
96 
97 #ifdef QT_WAYLAND_GL_SUPPORT
98 QWaylandGLIntegration * QWaylandDisplay::eglIntegration()
99 {
100  return mEglIntegration;
101 }
102 #endif
103 
104 #ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT
105 QWaylandWindowManagerIntegration *QWaylandDisplay::windowManagerIntegration()
106 {
107  return mWindowManagerIntegration;
108 }
109 #endif
110 
112  uint32_t time, uint32_t edges,
113  struct wl_surface *surface,
114  int32_t width, int32_t height)
115 {
116  Q_UNUSED(data);
117  Q_UNUSED(shell);
118  Q_UNUSED(time);
119  Q_UNUSED(edges);
120  QWaylandWindow *ww = (QWaylandWindow *) wl_surface_get_user_data(surface);
121 
122  ww->configure(time, edges, 0, 0, width, height);
123 }
124 
125 const struct wl_shell_listener QWaylandDisplay::shellListener = {
127 };
128 
131 {
132  mDisplay = wl_display_connect(NULL);
133  if (mDisplay == NULL) {
134  qErrnoWarning(errno, "Failed to create display");
135  qFatal("No wayland connection available.");
136  }
137 
138  wl_display_add_global_listener(mDisplay, QWaylandDisplay::displayHandleGlobal, this);
139 
140 #ifdef QT_WAYLAND_GL_SUPPORT
141  mEglIntegration = QWaylandGLIntegration::createGLIntegration(this);
142 #endif
143 
144 #ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT
145  mWindowManagerIntegration = QWaylandWindowManagerIntegration::createIntegration(this);
146 #endif
147 
149 
150  qRegisterMetaType<uint32_t>("uint32_t");
151 
152 #ifdef QT_WAYLAND_GL_SUPPORT
153  mEglIntegration->initialize();
154 #endif
155 
157 
158  mFd = wl_display_get_fd(mDisplay, sourceUpdate, this);
159 
161  connect(mReadNotifier, SIGNAL(activated(int)), this, SLOT(readEvents()));
162 
163  waitForScreens();
164 }
165 
167 {
168  close(mFd);
169 #ifdef QT_WAYLAND_GL_SUPPORT
170  delete mEglIntegration;
171 #endif
172  wl_display_destroy(mDisplay);
173 }
174 
175 void QWaylandDisplay::createNewScreen(struct wl_output *output, QRect geometry)
176 {
177  QWaylandScreen *waylandScreen = new QWaylandScreen(this,output,geometry);
178  mScreens.append(waylandScreen);
179 }
180 
181 void QWaylandDisplay::syncCallback(wl_display_sync_func_t func, void *data)
182 {
183  wl_display_sync_callback(mDisplay, func, data);
184 }
185 
186 void QWaylandDisplay::frameCallback(wl_display_frame_func_t func, struct wl_surface *surface, void *data)
187 {
188  wl_display_frame_callback(mDisplay, surface, func, data);
189 }
190 
192 {
193  if (mSocketMask & WL_DISPLAY_WRITABLE)
194  wl_display_iterate(mDisplay, WL_DISPLAY_WRITABLE);
195 }
196 
198 {
199 // verify that there is still data on the socket
200  fd_set fds;
201  FD_ZERO(&fds);
202  FD_SET(mFd, &fds);
203  fd_set nds;
204  FD_ZERO(&nds);
205  fd_set rs = fds;
206  fd_set ws = nds;
207  fd_set es = nds;
208  timeval timeout;
209  timeout.tv_sec = 0;
210  timeout.tv_usec = 0;
211  int ret = ::select(mFd+1, &rs, &ws, &es, &timeout );
212 
213  if (ret <= 0) {
214  //qDebug("QWaylandDisplay::readEvents() No data... blocking avoided");
215  return;
216  }
217 
218  wl_display_iterate(mDisplay, WL_DISPLAY_READABLE);
219 }
220 
222 {
223  wl_display_iterate(mDisplay, WL_DISPLAY_READABLE);
224 }
225 
226 int QWaylandDisplay::sourceUpdate(uint32_t mask, void *data)
227 {
228  QWaylandDisplay *waylandDisplay = static_cast<QWaylandDisplay *>(data);
229  waylandDisplay->mSocketMask = mask;
230 
231  return 0;
232 }
233 
235  wl_output *output,
236  int32_t x, int32_t y,
237  int32_t physicalWidth,
238  int32_t physicalHeight,
239  int subpixel,
240  const char *make, const char *model)
241 {
242  QWaylandDisplay *waylandDisplay = static_cast<QWaylandDisplay *>(data);
243  QRect outputRect = QRect(x, y, physicalWidth, physicalHeight);
244  waylandDisplay->createNewScreen(output,outputRect);
245 }
246 
248  struct wl_output *wl_output,
249  uint32_t flags,
250  int width,
251  int height,
252  int refresh)
253 {
254  Q_UNUSED(data);
255  Q_UNUSED(wl_output);
256  Q_UNUSED(flags);
257  Q_UNUSED(width);
258  Q_UNUSED(height);
259  Q_UNUSED(refresh);
260 }
261 
262 const struct wl_output_listener QWaylandDisplay::outputListener = {
265 };
266 
267 const struct wl_compositor_listener QWaylandDisplay::compositorListener = {
269 };
270 
271 
273 {
274  flushRequests();
275  while (mScreens.isEmpty())
277 }
278 
280  uint32_t id,
281  const char *interface,
282  uint32_t version,
283  void *data)
284 {
285  Q_UNUSED(display);
286  QWaylandDisplay *that = static_cast<QWaylandDisplay *>(data);
287  that->displayHandleGlobal(id, QByteArray(interface), version);
288 }
289 
291  const QByteArray &interface,
292  uint32_t version)
293 {
294  Q_UNUSED(version);
295  if (interface == "wl_output") {
296  struct wl_output *output = wl_output_create(mDisplay, id, 1);
297  wl_output_add_listener(output, &outputListener, this);
298  } else if (interface == "wl_compositor") {
299  mCompositor = wl_compositor_create(mDisplay, id, 1);
300  wl_compositor_add_listener(mCompositor,
301  &compositorListener, this);
302  } else if (interface == "wl_shm") {
303  mShm = wl_shm_create(mDisplay, id, 1);
304  } else if (interface == "wl_shell"){
305  mShell = wl_shell_create(mDisplay, id, 1);
306  wl_shell_add_listener(mShell, &shellListener, this);
307  } else if (interface == "wl_input_device") {
308  QWaylandInputDevice *inputDevice =
309  new QWaylandInputDevice(mDisplay, id);
310  mInputDevices.append(inputDevice);
311  } else if (interface == "wl_selection_offer") {
312  QPlatformIntegration *plat = QApplicationPrivate::platformIntegration();
313  QWaylandClipboard *clipboard = static_cast<QWaylandClipboard *>(plat->clipboard());
314  clipboard->createSelectionOffer(id);
315  }
316 }
317 
319  struct wl_compositor *compositor,
320  uint32_t id, uint32_t token)
321 {
322  QWaylandDisplay *self = static_cast<QWaylandDisplay *>(data);
323 
324  switch (token) {
325  case WL_COMPOSITOR_VISUAL_ARGB32:
326  self->argb_visual = wl_visual_create(self->mDisplay, id, 1);
327  break;
328  case WL_COMPOSITOR_VISUAL_PREMULTIPLIED_ARGB32:
329  self->premultiplied_argb_visual =
330  wl_visual_create(self->mDisplay, id, 1);
331  break;
332  case WL_COMPOSITOR_VISUAL_XRGB32:
333  self->rgb_visual = wl_visual_create(self->mDisplay, id, 1);
334  break;
335  }
336 }
static QWaylandClipboard * clipboard
void createSelectionOffer(uint32_t id)
static QWaylandWindowManagerIntegration * createIntegration(QWaylandDisplay *waylandDisplay)
static void mode(void *data, struct wl_output *wl_output, uint32_t flags, int width, int height, int refresh)
static const struct wl_output_listener outputListener
void createNewScreen(struct wl_output *output, QRect geometry)
Q_CORE_EXPORT QTextStream & ws(QTextStream &s)
void configure(uint32_t time, uint32_t edges, int32_t x, int32_t y, int32_t width, int32_t height)
void displayHandleGlobal(uint32_t id, const QByteArray &interface, uint32_t version)
struct wl_shell * mShell
struct wl_visual * rgbVisual()
static QAbstractEventDispatcher * instance(QThread *thread=0)
Returns a pointer to the event dispatcher object for the specified thread.
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
static void handleVisual(void *data, struct wl_compositor *compositor, uint32_t id, uint32_t token)
struct wl_compositor * mCompositor
struct wl_visual * argbVisual()
#define SLOT(a)
Definition: qobjectdefs.h:226
static void outputHandleGeometry(void *data, struct wl_output *output, int32_t x, int32_t y, int32_t width, int32_t height, int subpixel, const char *make, const char *model)
int select(int, fd_set *, fd_set *, fd_set *, struct timeval *)
QList< QPlatformScreen * > mScreens
static const struct wl_shell_listener shellListener
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Definition: qlist.h:152
The QSocketNotifier class provides support for monitoring activity on a file descriptor.
#define SIGNAL(a)
Definition: qobjectdefs.h:227
virtual QPlatformClipboard * clipboard() const
Accessor for the platform integrations clipboard.
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
struct wl_visual * argbPremultipliedVisual()
Q_GUI_EXPORT EGLDisplay display()
Definition: qegl.cpp:589
void frameCallback(wl_display_frame_func_t func, struct wl_surface *surface, void *data)
static bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Creates a connection of the given type from the signal in the sender object to the method in the rece...
Definition: qobject.cpp:2580
struct wl_surface * createSurface(void *handle)
QList< QWaylandInputDevice * > mInputDevices
static const char * data(const QByteArray &arr)
static int sourceUpdate(uint32_t mask, void *data)
struct wl_shm * mShm
void syncCallback(wl_display_sync_func_t func, void *data)
The QPlatformIntegration class is the entry for WindowSystem specific functionality.
static QWaylandGLIntegration * createGLIntegration(QWaylandDisplay *waylandDisplay)
Q_CORE_EXPORT void qFatal(const char *,...)
struct wl_shell * wl_shell() const
struct wl_visual * argb_visual
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
struct wl_visual * premultiplied_argb_visual
static void shellHandleConfigure(void *data, struct wl_shell *shell, uint32_t time, uint32_t edges, struct wl_surface *surface, int32_t width, int32_t height)
QSocketNotifier * mReadNotifier
static const struct wl_compositor_listener compositorListener
struct wl_display * mDisplay
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
struct wl_buffer * createShmBuffer(int fd, int width, int height, uint32_t stride, struct wl_visual *visual)
int errno
void qErrnoWarning(const char *msg,...)
Definition: qglobal.cpp:2954
struct wl_display * wl_display() const
struct wl_visual * rgb_visual