Qt 4.8
qxlibstatic.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 "qxlibstatic.h"
43 #include "qxlibscreen.h"
44 #include "qxlibdisplay.h"
45 
46 #include <qplatformdefs.h>
47 
48 #include <QtGui/private/qapplication_p.h>
49 #include <QtCore/QBuffer>
50 #include <QtCore/QLibrary>
51 
52 #include <QDebug>
53 
54 static const char * x11_atomnames = {
55  // window-manager <-> client protocols
56  "WM_PROTOCOLS\0"
57  "WM_DELETE_WINDOW\0"
58  "WM_TAKE_FOCUS\0"
59  "_NET_WM_PING\0"
60  "_NET_WM_CONTEXT_HELP\0"
61  "_NET_WM_SYNC_REQUEST\0"
62  "_NET_WM_SYNC_REQUEST_COUNTER\0"
63 
64  // ICCCM window state
65  "WM_STATE\0"
66  "WM_CHANGE_STATE\0"
67 
68  // Session management
69  "WM_CLIENT_LEADER\0"
70  "WM_WINDOW_ROLE\0"
71  "SM_CLIENT_ID\0"
72 
73  // Clipboard
74  "CLIPBOARD\0"
75  "INCR\0"
76  "TARGETS\0"
77  "MULTIPLE\0"
78  "TIMESTAMP\0"
79  "SAVE_TARGETS\0"
80  "CLIP_TEMPORARY\0"
81  "_QT_SELECTION\0"
82  "_QT_CLIPBOARD_SENTINEL\0"
83  "_QT_SELECTION_SENTINEL\0"
84  "CLIPBOARD_MANAGER\0"
85 
86  "RESOURCE_MANAGER\0"
87 
88  "_XSETROOT_ID\0"
89 
90  "_QT_SCROLL_DONE\0"
91  "_QT_INPUT_ENCODING\0"
92 
93  "_MOTIF_WM_HINTS\0"
94 
95  "DTWM_IS_RUNNING\0"
96  "ENLIGHTENMENT_DESKTOP\0"
97  "_DT_SAVE_MODE\0"
98  "_SGI_DESKS_MANAGER\0"
99 
100  // EWMH (aka NETWM)
101  "_NET_SUPPORTED\0"
102  "_NET_VIRTUAL_ROOTS\0"
103  "_NET_WORKAREA\0"
104 
105  "_NET_MOVERESIZE_WINDOW\0"
106  "_NET_WM_MOVERESIZE\0"
107 
108  "_NET_WM_NAME\0"
109  "_NET_WM_ICON_NAME\0"
110  "_NET_WM_ICON\0"
111 
112  "_NET_WM_PID\0"
113 
114  "_NET_WM_WINDOW_OPACITY\0"
115 
116  "_NET_WM_STATE\0"
117  "_NET_WM_STATE_ABOVE\0"
118  "_NET_WM_STATE_BELOW\0"
119  "_NET_WM_STATE_FULLSCREEN\0"
120  "_NET_WM_STATE_MAXIMIZED_HORZ\0"
121  "_NET_WM_STATE_MAXIMIZED_VERT\0"
122  "_NET_WM_STATE_MODAL\0"
123  "_NET_WM_STATE_STAYS_ON_TOP\0"
124  "_NET_WM_STATE_DEMANDS_ATTENTION\0"
125 
126  "_NET_WM_USER_TIME\0"
127  "_NET_WM_USER_TIME_WINDOW\0"
128  "_NET_WM_FULL_PLACEMENT\0"
129 
130  "_NET_WM_WINDOW_TYPE\0"
131  "_NET_WM_WINDOW_TYPE_DESKTOP\0"
132  "_NET_WM_WINDOW_TYPE_DOCK\0"
133  "_NET_WM_WINDOW_TYPE_TOOLBAR\0"
134  "_NET_WM_WINDOW_TYPE_MENU\0"
135  "_NET_WM_WINDOW_TYPE_UTILITY\0"
136  "_NET_WM_WINDOW_TYPE_SPLASH\0"
137  "_NET_WM_WINDOW_TYPE_DIALOG\0"
138  "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU\0"
139  "_NET_WM_WINDOW_TYPE_POPUP_MENU\0"
140  "_NET_WM_WINDOW_TYPE_TOOLTIP\0"
141  "_NET_WM_WINDOW_TYPE_NOTIFICATION\0"
142  "_NET_WM_WINDOW_TYPE_COMBO\0"
143  "_NET_WM_WINDOW_TYPE_DND\0"
144  "_NET_WM_WINDOW_TYPE_NORMAL\0"
145  "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE\0"
146 
147  "_KDE_NET_WM_FRAME_STRUT\0"
148 
149  "_NET_STARTUP_INFO\0"
150  "_NET_STARTUP_INFO_BEGIN\0"
151 
152  "_NET_SUPPORTING_WM_CHECK\0"
153 
154  "_NET_WM_CM_S0\0"
155 
156  "_NET_SYSTEM_TRAY_VISUAL\0"
157 
158  "_NET_ACTIVE_WINDOW\0"
159 
160  // Property formats
161  "COMPOUND_TEXT\0"
162  "TEXT\0"
163  "UTF8_STRING\0"
164 
165  // xdnd
166  "XdndEnter\0"
167  "XdndPosition\0"
168  "XdndStatus\0"
169  "XdndLeave\0"
170  "XdndDrop\0"
171  "XdndFinished\0"
172  "XdndTypeList\0"
173  "XdndActionList\0"
174 
175  "XdndSelection\0"
176 
177  "XdndAware\0"
178  "XdndProxy\0"
179 
180  "XdndActionCopy\0"
181  "XdndActionLink\0"
182  "XdndActionMove\0"
183  "XdndActionPrivate\0"
184 
185  // Motif DND
186  "_MOTIF_DRAG_AND_DROP_MESSAGE\0"
187  "_MOTIF_DRAG_INITIATOR_INFO\0"
188  "_MOTIF_DRAG_RECEIVER_INFO\0"
189  "_MOTIF_DRAG_WINDOW\0"
190  "_MOTIF_DRAG_TARGETS\0"
191 
192  "XmTRANSFER_SUCCESS\0"
193  "XmTRANSFER_FAILURE\0"
194 
195  // Xkb
196  "_XKB_RULES_NAMES\0"
197 
198  // XEMBED
199  "_XEMBED\0"
200  "_XEMBED_INFO\0"
201 
202  // Wacom old. (before version 0.10)
203  "Wacom Stylus\0"
204  "Wacom Cursor\0"
205  "Wacom Eraser\0"
206 
207  // Tablet
208  "STYLUS\0"
209  "ERASER\0"
210 };
211 
224 static void* qt_load_library_runtime(const char *library, int vernum,
225  int highestVernum, const char *symbol)
226 {
227  QList<int> versions;
228  // we try to load in the following order:
229  // explicit version -> the default one -> (from the highest (highestVernum) to the lowest (vernum) )
230  if (vernum != -1)
231  versions << vernum;
232  versions << -1;
233  if (vernum != -1) {
234  for(int i = highestVernum; i > vernum; --i)
235  versions << i;
236  }
237  Q_FOREACH(int version, versions) {
238  QLatin1String libName(library);
239  QLibrary xfixesLib(libName, version);
240  void *ptr = xfixesLib.resolve(symbol);
241  if (ptr)
242  return ptr;
243  }
244  return 0;
245 }
246 
247 # define XFIXES_LOAD_RUNTIME(vernum, symbol, symbol_type) \
248  (symbol_type)qt_load_library_runtime("libXfixes", vernum, 4, #symbol);
249 # define XFIXES_LOAD_V1(symbol) \
250  XFIXES_LOAD_RUNTIME(1, symbol, Ptr##symbol)
251 # define XFIXES_LOAD_V2(symbol) \
252  XFIXES_LOAD_RUNTIME(2, symbol, Ptr##symbol)
253 
254 
256 {
257 public:
259  : use_xfixes(false)
260  , xfixes_major(0)
261  , xfixes_eventbase(0)
262  , xfixes_errorbase(0)
263  {
264  QXlibScreen *screen = qobject_cast<QXlibScreen *> (QApplicationPrivate::platformIntegration()->screens().at(0));
265  Q_ASSERT(screen);
266 
267  initializeAllAtoms(screen);
268  initializeSupportedAtoms(screen);
269 
270  resolveXFixes(screen);
271  }
272 
274  {
275  if (!m_supportedAtoms)
276  return false;
277 
278  bool supported = false;
279  int i = 0;
280  while (m_supportedAtoms[i] != 0) {
281  if (m_supportedAtoms[i++] == atom) {
282  supported = true;
283  break;
284  }
285  }
286 
287  return supported;
288  }
289 
291  {
292  return m_allAtoms[atom];
293  }
294 
295  bool useXFixes() const { return use_xfixes; }
296 
297  int xFixesEventBase() const {return xfixes_eventbase; }
298 
300  {
302  }
303 
305  {
307  if (xi->depth == 24)
308  format = QImage::Format_RGB32;
309  else if (xi->depth == 16)
310  format = QImage::Format_RGB16;
311 
312  QImage image = QImage((uchar *)xi->data, xi->width, xi->height, xi->bytes_per_line, format).copy();
313 
314  // we may have to swap the byte order
315  if ((QSysInfo::ByteOrder == QSysInfo::LittleEndian && xi->byte_order == MSBFirst)
316  || (QSysInfo::ByteOrder == QSysInfo::BigEndian && xi->byte_order == LSBFirst))
317  {
318  for (int i=0; i < image.height(); i++) {
319  if (xi->depth == 16) {
320  ushort *p = (ushort*)image.scanLine(i);
321  ushort *end = p + image.width();
322  while (p < end) {
323  *p = ((*p << 8) & 0xff00) | ((*p >> 8) & 0x00ff);
324  p++;
325  }
326  } else {
327  uint *p = (uint*)image.scanLine(i);
328  uint *end = p + image.width();
329  while (p < end) {
330  *p = ((*p << 24) & 0xff000000) | ((*p << 8) & 0x00ff0000)
331  | ((*p >> 8) & 0x0000ff00) | ((*p >> 24) & 0x000000ff);
332  p++;
333  }
334  }
335  }
336  }
337 
338  // fix-up alpha channel
339  if (format == QImage::Format_RGB32) {
340  QRgb *p = (QRgb *)image.bits();
341  for (int y = 0; y < xi->height; ++y) {
342  for (int x = 0; x < xi->width; ++x)
343  p[x] |= 0xff000000;
344  p += xi->bytes_per_line / 4;
345  }
346  }
347 
348  return image;
349  }
350 
351 
352 private:
353 
355  const char *names[QXlibStatic::NAtoms];
356  const char *ptr = x11_atomnames;
357 
358  int i = 0;
359  while (*ptr) {
360  names[i++] = ptr;
361  while (*ptr)
362  ++ptr;
363  ++ptr;
364  }
365 
367 
368  QByteArray settings_atom_name("_QT_SETTINGS_TIMESTAMP_");
369  settings_atom_name += XDisplayName(qPrintable(screen->display()->displayName()));
370  names[i++] = settings_atom_name;
371 
373  #if 0//defined(XlibSpecificationRelease) && (XlibSpecificationRelease >= 6)
374  XInternAtoms(screen->display(), (char **)names, i, False, m_allAtoms);
375  #else
376  for (i = 0; i < QXlibStatic::NAtoms; ++i)
377  m_allAtoms[i] = XInternAtom(screen->display()->nativeDisplay(), (char *)names[i], False);
378  #endif
379  }
380 
382  {
383  Atom type;
384  int format;
385  long offset = 0;
386  unsigned long nitems, after;
387  unsigned char *data = 0;
388 
389  int e = XGetWindowProperty(screen->display()->nativeDisplay(), screen->rootWindow(),
390  this->atom(QXlibStatic::_NET_SUPPORTED), 0, 0,
391  False, XA_ATOM, &type, &format, &nitems, &after, &data);
392  if (data)
393  XFree(data);
394 
395  if (e == Success && type == XA_ATOM && format == 32) {
396  QBuffer ts;
398 
399  while (after > 0) {
400  XGetWindowProperty(screen->display()->nativeDisplay(), screen->rootWindow(),
401  this->atom(QXlibStatic::_NET_SUPPORTED), offset, 1024,
402  False, XA_ATOM, &type, &format, &nitems, &after, &data);
403 
404  if (type == XA_ATOM && format == 32) {
405  ts.write(reinterpret_cast<char *>(data), nitems * sizeof(long));
406  offset += nitems;
407  } else
408  after = 0;
409  if (data)
410  XFree(data);
411  }
412 
413  // compute nitems
414  QByteArray buffer(ts.buffer());
415  nitems = buffer.size() / sizeof(Atom);
416  m_supportedAtoms = new Atom[nitems + 1];
417  Atom *a = (Atom *) buffer.data();
418  uint i;
419  for (i = 0; i < nitems; i++)
420  m_supportedAtoms[i] = a[i];
421  m_supportedAtoms[nitems] = 0;
422 
423  }
424  }
425 
427  {
428 #ifndef QT_NO_XFIXES
429  // See if Xfixes is supported on the connected display
430  if (XQueryExtension(screen->display()->nativeDisplay(), "XFIXES", &xfixes_major,
432  ptrXFixesQueryExtension = XFIXES_LOAD_V1(XFixesQueryExtension);
433  ptrXFixesQueryVersion = XFIXES_LOAD_V1(XFixesQueryVersion);
434  ptrXFixesSetCursorName = XFIXES_LOAD_V2(XFixesSetCursorName);
435  ptrXFixesSelectSelectionInput = XFIXES_LOAD_V2(XFixesSelectSelectionInput);
436 
439  &xfixes_errorbase)) {
440  // Xfixes is supported.
441  // Note: the XFixes protocol version is negotiated using QueryVersion.
442  // We supply the highest version we support, the X server replies with
443  // the highest version it supports, but no higher than the version we
444  // asked for. The version sent back is the protocol version the X server
445  // will use to talk us. If this call is removed, the behavior of the
446  // X server when it receives an XFixes request is undefined.
447  int major = 3;
448  int minor = 0;
449  ptrXFixesQueryVersion(screen->display()->nativeDisplay(), &major, &minor);
450  use_xfixes = (major >= 1);
451  xfixes_major = major;
452  }
453  }
454 #endif // QT_NO_XFIXES
455 
456  }
457 
460 
461 #ifndef QT_NO_XFIXES
466 #endif
467 
472 
473 };
474 Q_GLOBAL_STATIC(QTestLiteStaticInfoPrivate, qTestLiteStaticInfoPrivate);
475 
476 
478 {
479  return qTestLiteStaticInfoPrivate()->atom(atom);
480 }
481 
483 {
484  return qTestLiteStaticInfoPrivate()->isSupportedByWM(atom);
485 }
486 
488 {
489  return qTestLiteStaticInfoPrivate()->useXFixes();
490 }
491 
493 {
494  return qTestLiteStaticInfoPrivate()->xFixesEventBase();
495 }
496 
497 #ifndef QT_NO_XFIXES
499 {
500  qDebug() << qTestLiteStaticInfoPrivate()->useXFixes();
501  if (!qTestLiteStaticInfoPrivate()->useXFixes())
502  return 0;
503 
504  return qTestLiteStaticInfoPrivate()->xFixesSelectSelectionInput();
505 }
506 
508 {
509  return qTestLiteStaticInfoPrivate()->qimageFromXImage(xi);
510 }
511 #endif //QT_NO_XFIXES
T qobject_cast(QObject *object)
Definition: qobject.h:375
void resolveXFixes(QXlibScreen *screen)
static bool isSupportedByWM(Atom atom)
Format
The following image formats are available in Qt.
Definition: qimage.h:91
unsigned int QRgb
Definition: qrgb.h:53
QImage copy(const QRect &rect=QRect()) const
Returns a sub-area of the image as a new image.
Definition: qimage.cpp:1410
int type
Definition: qmetatype.cpp:239
Status(* PtrXFixesQueryVersion)(Display *, int *, int *)
Definition: qt_x11_p.h:209
Window rootWindow()
bool open(OpenMode openMode)
Reimplemented Function
Definition: qbuffer.cpp:338
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
Display * nativeDisplay() const
QString displayName() const
bool isSupportedByWM(Atom atom)
Q_GLOBAL_STATIC(QTestLiteStaticInfoPrivate, qTestLiteStaticInfoPrivate)
long ASN1_INTEGER_get ASN1_INTEGER * a
void * resolve(const char *symbol)
Returns the address of the exported symbol symbol.
Definition: qlibrary.cpp:1155
The QBuffer class provides a QIODevice interface for a QByteArray.
Definition: qbuffer.h:57
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
PtrXFixesSelectSelectionInput xFixesSelectSelectionInput() const
Q_CORE_EXPORT void qDebug(const char *,...)
unsigned char uchar
Definition: qglobal.h:994
void initializeAllAtoms(QXlibScreen *screen)
PtrXFixesQueryVersion ptrXFixesQueryVersion
QByteArray & buffer()
Returns a reference to the QBuffer&#39;s internal buffer.
Definition: qbuffer.cpp:271
Bool(* PtrXFixesQueryExtension)(Display *, int *, int *)
Definition: qt_x11_p.h:208
Atom m_allAtoms[QXlibStatic::NAtoms]
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
static const char * data(const QByteArray &arr)
unsigned int uint
Definition: qglobal.h:996
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal...
Definition: qstring.h:654
PtrXFixesQueryExtension ptrXFixesQueryExtension
static void * qt_load_library_runtime(const char *library, int vernum, int highestVernum, const char *symbol)
Try to resolve a symbol from library with the version specified by vernum.
const T * ptr(const T &t)
#define XFIXES_LOAD_V2(symbol)
static const char * x11_atomnames
Definition: qxlibstatic.cpp:54
static Atom atom(X11Atom atom)
uchar * bits()
Returns a pointer to the first pixel data.
Definition: qimage.cpp:1946
int width() const
Returns the width of the image.
Definition: qimage.cpp:1557
Atom atom(QXlibStatic::X11Atom atom)
void(* PtrXFixesSelectSelectionInput)(Display *dpy, Window win, Atom selection, unsigned long eventMask)
Definition: qt_x11_p.h:211
unsigned short ushort
Definition: qglobal.h:995
QImage qimageFromXImage(XImage *xi)
static bool useXFixes()
void(* PtrXFixesSetCursorName)(Display *dpy, Cursor cursor, const char *name)
Definition: qt_x11_p.h:210
int height() const
Returns the height of the image.
Definition: qimage.cpp:1572
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
static int xFixesEventBase()
static QImage qimageFromXImage(XImage *xi)
#define Q_FOREACH(variable, container)
Same as foreach(variable, container).
Definition: qglobal.h:2435
PtrXFixesSetCursorName ptrXFixesSetCursorName
static PtrXFixesSelectSelectionInput xFixesSelectSelectionInput()
qint64 write(const char *data, qint64 len)
Writes at most maxSize bytes of data from data to the device.
Definition: qiodevice.cpp:1342
static const KeyPair *const end
QXlibDisplay * display() const
#define qPrintable(string)
Definition: qglobal.h:1750
PtrXFixesSelectSelectionInput ptrXFixesSelectSelectionInput
uchar * scanLine(int)
Returns a pointer to the pixel data at the scanline with index i.
Definition: qimage.cpp:1886
The QLibrary class loads shared libraries at runtime.
Definition: qlibrary.h:62
#define XFIXES_LOAD_V1(symbol)
void initializeSupportedAtoms(QXlibScreen *screen)