Qt 4.8
qpixmap_x11.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 QtGui module 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 // Uncomment the next line to enable the MIT Shared Memory extension
43 //
44 // WARNING: This has some problems:
45 //
46 // 1. Consumes a 800x600 pixmap
47 // 2. Qt does not handle the ShmCompletion message, so you will
48 // get strange effects if you xForm() repeatedly.
49 //
50 // #define QT_MITSHM
51 
52 #if defined(Q_OS_WIN32) && defined(QT_MITSHM)
53 #undef QT_MITSHM
54 #endif
55 
56 #include "qplatformdefs.h"
57 
58 #include "qdebug.h"
59 #include "qiodevice.h"
60 #include "qpixmap_x11_p.h"
61 #include "qbitmap.h"
62 #include "qcolormap.h"
63 #include "qimage.h"
64 #include "qmatrix.h"
65 #include "qapplication.h"
66 #include <private/qpaintengine_x11_p.h>
67 #include <private/qt_x11_p.h>
68 #include "qx11info_x11.h"
69 #include <private/qdrawhelper_p.h>
70 #include <private/qimage_p.h>
71 #include <private/qimagepixmapcleanuphooks_p.h>
72 
73 #include <stdlib.h>
74 
75 #if defined(Q_CC_MIPS)
76 # define for if(0){}else for
77 #endif
78 
80 
82 {
83  QPixmapData *data =
84  new QX11PixmapData(image.depth() == 1
87 
88  data->fromImage(image, Qt::AutoColor);
89 
90  return QPixmap(data);
91 }
92 
94 {
95  if (pixmap.isNull())
96  return QPixmap();
97 
98  if (QPixmap(pixmap).data_ptr()->classId() == QPixmapData::X11Class)
99  return pixmap;
100 
101  return qt_toX11Pixmap(pixmap.toImage());
102 }
103 
104 // For thread-safety:
105 // image->data does not belong to X11, so we must free it ourselves.
106 
107 inline static void qSafeXDestroyImage(XImage *x)
108 {
109  if (x->data) {
110  free(x->data);
111  x->data = 0;
112  }
113  XDestroyImage(x);
114 }
115 
117 {
118  if (!x11_mask)
119  return QBitmap();
120  QPixmap::x11SetDefaultScreen(screen);
121  QBitmap bm(w, h);
122  GC gc = XCreateGC(X11->display, bm.handle(), 0, 0);
123  XCopyArea(X11->display, x11_mask, bm.handle(), gc, 0, 0,
124  bm.data->width(), bm.data->height(), 0, 0);
125  XFreeGC(X11->display, gc);
126  return bm;
127 }
128 
130 {
131  if (bitmap.isNull())
132  return 0;
133  QBitmap bm = bitmap;
134  bm.x11SetScreen(screen);
135 
136  Pixmap mask = XCreatePixmap(X11->display, RootWindow(X11->display, screen),
137  bm.data->width(), bm.data->height(), 1);
138  GC gc = XCreateGC(X11->display, mask, 0, 0);
139  XCopyArea(X11->display, bm.handle(), mask, gc, 0, 0,
140  bm.data->width(), bm.data->height(), 0, 0);
141  XFreeGC(X11->display, gc);
142  return mask;
143 }
144 
145 
146 /*****************************************************************************
147  MIT Shared Memory Extension support: makes xForm noticeably (~20%) faster.
148  *****************************************************************************/
149 
150 #if defined(QT_MITSHM)
151 
152 static bool xshminit = false;
153 static XShmSegmentInfo xshminfo;
154 static XImage *xshmimg = 0;
155 static Pixmap xshmpm = 0;
156 
157 static void qt_cleanup_mitshm()
158 {
159  if (xshmimg == 0)
160  return;
161  Display *dpy = QX11Info::appDisplay();
162  if (xshmpm) {
163  XFreePixmap(dpy, xshmpm);
164  xshmpm = 0;
165  }
166  XShmDetach(dpy, &xshminfo); xshmimg->data = 0;
167  qSafeXDestroyImage(xshmimg); xshmimg = 0;
168  shmdt(xshminfo.shmaddr);
169  shmctl(xshminfo.shmid, IPC_RMID, 0);
170 }
171 
172 static bool qt_create_mitshm_buffer(const QPaintDevice* dev, int w, int h)
173 {
174  static int major, minor;
175  static Bool pixmaps_ok;
176  Display *dpy = dev->data->xinfo->display();
177  int dd = dev->x11Depth();
178  Visual *vis = (Visual*)dev->x11Visual();
179 
180  if (xshminit) {
181  qt_cleanup_mitshm();
182  } else {
183  if (!XShmQueryVersion(dpy, &major, &minor, &pixmaps_ok))
184  return false; // MIT Shm not supported
185  qAddPostRoutine(qt_cleanup_mitshm);
186  xshminit = true;
187  }
188 
189  xshmimg = XShmCreateImage(dpy, vis, dd, ZPixmap, 0, &xshminfo, w, h);
190  if (!xshmimg)
191  return false;
192 
193  bool ok;
194  xshminfo.shmid = shmget(IPC_PRIVATE,
195  xshmimg->bytes_per_line * xshmimg->height,
196  IPC_CREAT | 0700);
197  ok = xshminfo.shmid != -1;
198  if (ok) {
199  xshmimg->data = (char*)shmat(xshminfo.shmid, 0, 0);
200  xshminfo.shmaddr = xshmimg->data;
201  ok = (xshminfo.shmaddr != (char*)-1);
202  }
203  xshminfo.readOnly = false;
204  if (ok)
205  ok = XShmAttach(dpy, &xshminfo);
206  if (!ok) {
207  qSafeXDestroyImage(xshmimg);
208  xshmimg = 0;
209  if (xshminfo.shmaddr)
210  shmdt(xshminfo.shmaddr);
211  if (xshminfo.shmid != -1)
212  shmctl(xshminfo.shmid, IPC_RMID, 0);
213  return false;
214  }
215  if (pixmaps_ok)
216  xshmpm = XShmCreatePixmap(dpy, DefaultRootWindow(dpy), xshmimg->data,
217  &xshminfo, w, h, dd);
218 
219  return true;
220 }
221 
222 #else
223 
224 // If extern, need a dummy.
225 //
226 // static bool qt_create_mitshm_buffer(QPaintDevice*, int, int)
227 // {
228 // return false;
229 // }
230 
231 #endif // QT_MITSHM
232 
233 
234 /*****************************************************************************
235  Internal functions
236  *****************************************************************************/
237 
238 extern const uchar *qt_get_bitflip_array(); // defined in qimage.cpp
239 
240 // Returns position of highest bit set or -1 if none
241 static int highest_bit(uint v)
242 {
243  int i;
244  uint b = (uint)1 << 31;
245  for (i=31; ((b & v) == 0) && i>=0; i--)
246  b >>= 1;
247  return i;
248 }
249 
250 // Returns position of lowest set bit in 'v' as an integer (0-31), or -1
251 static int lowest_bit(uint v)
252 {
253  int i;
254  ulong lb;
255  lb = 1;
256  for (i=0; ((v & lb) == 0) && i<32; i++, lb<<=1) {}
257  return i==32 ? -1 : i;
258 }
259 
260 // Counts the number of bits set in 'v'
261 static uint n_bits(uint v)
262 {
263  int i = 0;
264  while (v) {
265  v = v & (v - 1);
266  i++;
267  }
268  return i;
269 }
270 
271 static uint *red_scale_table = 0;
273 static uint *blue_scale_table = 0;
274 
275 static void cleanup_scale_tables()
276 {
277  delete[] red_scale_table;
278  delete[] green_scale_table;
279  delete[] blue_scale_table;
280 }
281 
282 /*
283  Could do smart bitshifting, but the "obvious" algorithm only works for
284  nBits >= 4. This is more robust.
285 */
286 static void build_scale_table(uint **table, uint nBits)
287 {
288  if (nBits > 7) {
289  qWarning("build_scale_table: internal error, nBits = %i", nBits);
290  return;
291  }
292  if (!*table) {
293  static bool firstTable = true;
294  if (firstTable) {
296  firstTable = false;
297  }
298  *table = new uint[256];
299  }
300  int maxVal = (1 << nBits) - 1;
301  int valShift = 8 - nBits;
302  int i;
303  for(i = 0 ; i < maxVal + 1 ; i++)
304  (*table)[i << valShift] = i*255/maxVal;
305 }
306 
307 static int defaultScreen = -1;
308 
309 /*****************************************************************************
310  QPixmap member functions
311  *****************************************************************************/
312 
315 
317  : QPixmapData(type, X11Class), gl_surface(0), hd(0),
319  share_mode(QPixmap::ImplicitlyShared), pengine(0)
320 {
321 }
322 
324 {
325  return new QX11PixmapData(pixelType());
326 }
327 
329 {
330  setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1));
331 
332  w = width;
333  h = height;
334  is_null = (w <= 0 || h <= 0);
335 
336  if (defaultScreen >= 0 && defaultScreen != xinfo.screen()) {
337  QX11InfoData* xd = xinfo.getX11Data(true);
338  xd->screen = defaultScreen;
339  xd->depth = QX11Info::appDepth(xd->screen);
340  xd->cells = QX11Info::appCells(xd->screen);
343  xd->visual = (Visual *)QX11Info::appVisual(xd->screen);
345  xinfo.setX11Data(xd);
346  }
347 
348  int dd = xinfo.depth();
349 
352 
353  bool make_null = w <= 0 || h <= 0; // create null pixmap
354  d = (pixelType() == BitmapType ? 1 : dd);
355  if (make_null || d == 0) {
356  w = 0;
357  h = 0;
358  is_null = true;
359  hd = 0;
360  picture = 0;
361  d = 0;
362  if (!make_null)
363  qWarning("QPixmap: Invalid pixmap parameters");
364  return;
365  }
366  hd = (Qt::HANDLE)XCreatePixmap(X11->display,
367  RootWindow(X11->display, xinfo.screen()),
368  w, h, d);
369 #ifndef QT_NO_XRENDER
370  if (X11->use_xrender) {
371  XRenderPictFormat *format = d == 1
372  ? XRenderFindStandardFormat(X11->display, PictStandardA1)
373  : XRenderFindVisualFormat(X11->display, (Visual *)xinfo.visual());
374  picture = XRenderCreatePicture(X11->display, hd, format, 0, 0);
375  }
376 #endif // QT_NO_XRENDER
377 }
378 
380 {
381  bool hasAlpha() const {
382  if (checked)
383  return has;
384  // Will implicitly also check format and return quickly for opaque types...
385  checked = true;
386  has = image->isNull() ? false : const_cast<QImage *>(image)->data_ptr()->checkForAlphaPixels();
387  return has;
388  }
389 
390  bool hasXRenderAndAlpha() const {
391  if (!X11->use_xrender)
392  return false;
393  return hasAlpha();
394  }
395 
396  QX11AlphaDetector(const QImage *i, Qt::ImageConversionFlags flags)
397  : image(i), checked(false), has(false)
398  {
399  if (flags & Qt::NoOpaqueDetection) {
400  checked = true;
401  has = image->hasAlphaChannel();
402  }
403  }
404 
405  const QImage *image;
406  mutable bool checked;
407  mutable bool has;
408 };
409 
411  Qt::ImageConversionFlags flags)
412 {
413  setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1));
414 
415  w = img.width();
416  h = img.height();
417  d = img.depth();
418  is_null = (w <= 0 || h <= 0);
419 
420  if (is_null) {
421  w = h = 0;
422  return;
423  }
424 
425  if (defaultScreen >= 0 && defaultScreen != xinfo.screen()) {
426  QX11InfoData* xd = xinfo.getX11Data(true);
427  xd->screen = defaultScreen;
428  xd->depth = QX11Info::appDepth(xd->screen);
429  xd->cells = QX11Info::appCells(xd->screen);
432  xd->visual = (Visual *)QX11Info::appVisual(xd->screen);
434  xinfo.setX11Data(xd);
435  }
436 
437  if (pixelType() == BitmapType) {
438  bitmapFromImage(img);
439  return;
440  }
441 
442  if (uint(w) >= 32768 || uint(h) >= 32768) {
443  w = h = 0;
444  is_null = true;
445  return;
446  }
447 
448  QX11AlphaDetector alphaCheck(&img, flags);
449  int dd = alphaCheck.hasXRenderAndAlpha() ? 32 : xinfo.depth();
450 
453 
454  QImage image = img;
455 
456  // must be monochrome
457  if (dd == 1 || (flags & Qt::ColorMode_Mask) == Qt::MonoOnly) {
458  if (d != 1) {
459  // dither
460  image = image.convertToFormat(QImage::Format_MonoLSB, flags);
461  d = 1;
462  }
463  } else { // can be both
464  bool conv8 = false;
465  if (d > 8 && dd <= 8) { // convert to 8 bit
466  if ((flags & Qt::DitherMode_Mask) == Qt::AutoDither)
467  flags = (flags & ~Qt::DitherMode_Mask)
469  conv8 = true;
470  } else if ((flags & Qt::ColorMode_Mask) == Qt::ColorOnly) {
471  conv8 = (d == 1); // native depth wanted
472  } else if (d == 1) {
473  if (image.colorCount() == 2) {
474  QRgb c0 = image.color(0); // Auto: convert to best
475  QRgb c1 = image.color(1);
476  conv8 = qMin(c0,c1) != qRgb(0,0,0) || qMax(c0,c1) != qRgb(255,255,255);
477  } else {
478  // eg. 1-color monochrome images (they do exist).
479  conv8 = true;
480  }
481  }
482  if (conv8) {
483  image = image.convertToFormat(QImage::Format_Indexed8, flags);
484  d = 8;
485  }
486  }
487 
488  if (d == 1 || d == 16 || d == 24) {
489  image = image.convertToFormat(QImage::Format_RGB32, flags);
490  fromImage(image, Qt::AutoColor);
491  return;
492  }
493 
494  Display *dpy = X11->display;
495  Visual *visual = (Visual *)xinfo.visual();
496  XImage *xi = 0;
497  bool trucol = (visual->c_class >= TrueColor);
498  int nbytes = image.byteCount();
499  uchar *newbits= 0;
500 
501 #ifndef QT_NO_XRENDER
502  if (alphaCheck.hasXRenderAndAlpha()) {
503  const QImage &cimage = image;
504 
505  d = 32;
506 
507  if (QX11Info::appDepth() != d) {
508  if (xinfo.x11data) {
509  xinfo.x11data->depth = d;
510  } else {
511  QX11InfoData *xd = xinfo.getX11Data(true);
512  xd->screen = QX11Info::appScreen();
513  xd->depth = d;
514  xd->cells = QX11Info::appCells();
517  xd->visual = (Visual *)QX11Info::appVisual();
519  xinfo.setX11Data(xd);
520  }
521  }
522 
523  hd = (Qt::HANDLE)XCreatePixmap(dpy, RootWindow(dpy, xinfo.screen()),
524  w, h, d);
525  picture = XRenderCreatePicture(X11->display, hd,
526  XRenderFindStandardFormat(X11->display, PictStandardARGB32), 0, 0);
527 
528  xi = XCreateImage(dpy, visual, d, ZPixmap, 0, 0, w, h, 32, 0);
529  Q_CHECK_PTR(xi);
530  newbits = (uchar *)malloc(xi->bytes_per_line*h);
531  Q_CHECK_PTR(newbits);
532  xi->data = (char *)newbits;
533 
534  switch(cimage.format()) {
536  QVector<QRgb> colorTable = cimage.colorTable();
537  uint *xidata = (uint *)xi->data;
538  for (int y = 0; y < h; ++y) {
539  const uchar *p = cimage.scanLine(y);
540  for (int x = 0; x < w; ++x) {
541  const QRgb rgb = colorTable[p[x]];
542  const int a = qAlpha(rgb);
543  if (a == 0xff)
544  *xidata = rgb;
545  else
546  // RENDER expects premultiplied alpha
547  *xidata = qRgba(qt_div_255(qRed(rgb) * a),
548  qt_div_255(qGreen(rgb) * a),
549  qt_div_255(qBlue(rgb) * a),
550  a);
551  ++xidata;
552  }
553  }
554  }
555  break;
556  case QImage::Format_RGB32: {
557  uint *xidata = (uint *)xi->data;
558  for (int y = 0; y < h; ++y) {
559  const QRgb *p = (const QRgb *) cimage.scanLine(y);
560  for (int x = 0; x < w; ++x)
561  *xidata++ = p[x] | 0xff000000;
562  }
563  }
564  break;
565  case QImage::Format_ARGB32: {
566  uint *xidata = (uint *)xi->data;
567  for (int y = 0; y < h; ++y) {
568  const QRgb *p = (const QRgb *) cimage.scanLine(y);
569  for (int x = 0; x < w; ++x) {
570  const QRgb rgb = p[x];
571  const int a = qAlpha(rgb);
572  if (a == 0xff)
573  *xidata = rgb;
574  else
575  // RENDER expects premultiplied alpha
576  *xidata = qRgba(qt_div_255(qRed(rgb) * a),
577  qt_div_255(qGreen(rgb) * a),
578  qt_div_255(qBlue(rgb) * a),
579  a);
580  ++xidata;
581  }
582  }
583 
584  }
585  break;
587  uint *xidata = (uint *)xi->data;
588  for (int y = 0; y < h; ++y) {
589  const QRgb *p = (const QRgb *) cimage.scanLine(y);
590  memcpy(xidata, p, w*sizeof(QRgb));
591  xidata += w;
592  }
593  }
594  break;
595  default:
596  Q_ASSERT(false);
597  }
598 
599  if ((xi->byte_order == MSBFirst) != (QSysInfo::ByteOrder == QSysInfo::BigEndian)) {
600  uint *xidata = (uint *)xi->data;
601  uint *xiend = xidata + w*h;
602  while (xidata < xiend) {
603  *xidata = (*xidata >> 24)
604  | ((*xidata >> 8) & 0xff00)
605  | ((*xidata << 8) & 0xff0000)
606  | (*xidata << 24);
607  ++xidata;
608  }
609  }
610 
611  GC gc = XCreateGC(dpy, hd, 0, 0);
612  XPutImage(dpy, hd, gc, xi, 0, 0, 0, 0, w, h);
613  XFreeGC(dpy, gc);
614 
615  qSafeXDestroyImage(xi);
616 
617  return;
618  }
619 #endif // QT_NO_XRENDER
620 
621  if (trucol) { // truecolor display
623  image = image.convertToFormat(QImage::Format_ARGB32);
624 
625  const QImage &cimage = image;
626  QRgb pix[256]; // pixel translation table
627  const bool d8 = (d == 8);
628  const uint red_mask = (uint)visual->red_mask;
629  const uint green_mask = (uint)visual->green_mask;
630  const uint blue_mask = (uint)visual->blue_mask;
631  const int red_shift = highest_bit(red_mask) - 7;
632  const int green_shift = highest_bit(green_mask) - 7;
633  const int blue_shift = highest_bit(blue_mask) - 7;
634  const uint rbits = highest_bit(red_mask) - lowest_bit(red_mask) + 1;
635  const uint gbits = highest_bit(green_mask) - lowest_bit(green_mask) + 1;
636  const uint bbits = highest_bit(blue_mask) - lowest_bit(blue_mask) + 1;
637 
638  if (d8) { // setup pixel translation
639  QVector<QRgb> ctable = cimage.colorTable();
640  for (int i=0; i < cimage.colorCount(); i++) {
641  int r = qRed (ctable[i]);
642  int g = qGreen(ctable[i]);
643  int b = qBlue (ctable[i]);
644  r = red_shift > 0 ? r << red_shift : r >> -red_shift;
645  g = green_shift > 0 ? g << green_shift : g >> -green_shift;
646  b = blue_shift > 0 ? b << blue_shift : b >> -blue_shift;
647  pix[i] = (b & blue_mask) | (g & green_mask) | (r & red_mask)
648  | ~(blue_mask | green_mask | red_mask);
649  }
650  }
651 
652  xi = XCreateImage(dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0);
653  Q_CHECK_PTR(xi);
654  newbits = (uchar *)malloc(xi->bytes_per_line*h);
655  Q_CHECK_PTR(newbits);
656  if (!newbits) // no memory
657  return;
658  int bppc = xi->bits_per_pixel;
659 
660  bool contig_bits = n_bits(red_mask) == rbits &&
661  n_bits(green_mask) == gbits &&
662  n_bits(blue_mask) == bbits;
663  bool dither_tc =
664  // Want it?
665  (flags & Qt::Dither_Mask) != Qt::ThresholdDither &&
666  (flags & Qt::DitherMode_Mask) != Qt::AvoidDither &&
667  // Need it?
668  bppc < 24 && !d8 &&
669  // Can do it? (Contiguous bits?)
670  contig_bits;
671 
672  static bool init=false;
673  static int D[16][16];
674  if (dither_tc && !init) {
675  // I also contributed this code to XV - WWA.
676  /*
677  The dither matrix, D, is obtained with this formula:
678 
679  D2 = [0 2]
680  [3 1]
681 
682 
683  D2*n = [4*Dn 4*Dn+2*Un]
684  [4*Dn+3*Un 4*Dn+1*Un]
685  */
686  int n,i,j;
687  init=1;
688 
689  /* Set D2 */
690  D[0][0]=0;
691  D[1][0]=2;
692  D[0][1]=3;
693  D[1][1]=1;
694 
695  /* Expand using recursive definition given above */
696  for (n=2; n<16; n*=2) {
697  for (i=0; i<n; i++) {
698  for (j=0; j<n; j++) {
699  D[i][j]*=4;
700  D[i+n][j]=D[i][j]+2;
701  D[i][j+n]=D[i][j]+3;
702  D[i+n][j+n]=D[i][j]+1;
703  }
704  }
705  }
706  init=true;
707  }
708 
709  enum { BPP8,
710  BPP16_565, BPP16_555,
711  BPP16_MSB, BPP16_LSB,
712  BPP24_888,
713  BPP24_MSB, BPP24_LSB,
714  BPP32_8888,
715  BPP32_MSB, BPP32_LSB
716  } mode = BPP8;
717 
718  bool same_msb_lsb = (xi->byte_order == MSBFirst) == (QSysInfo::ByteOrder == QSysInfo::BigEndian);
719 
720  if(bppc == 8) // 8 bit
721  mode = BPP8;
722  else if(bppc == 16) { // 16 bit MSB/LSB
723  if(red_shift == 8 && green_shift == 3 && blue_shift == -3 && !d8 && same_msb_lsb)
724  mode = BPP16_565;
725  else if(red_shift == 7 && green_shift == 2 && blue_shift == -3 && !d8 && same_msb_lsb)
726  mode = BPP16_555;
727  else
728  mode = (xi->byte_order == LSBFirst) ? BPP16_LSB : BPP16_MSB;
729  } else if(bppc == 24) { // 24 bit MSB/LSB
730  if (red_shift == 16 && green_shift == 8 && blue_shift == 0 && !d8 && same_msb_lsb)
731  mode = BPP24_888;
732  else
733  mode = (xi->byte_order == LSBFirst) ? BPP24_LSB : BPP24_MSB;
734  } else if(bppc == 32) { // 32 bit MSB/LSB
735  if(red_shift == 16 && green_shift == 8 && blue_shift == 0 && !d8 && same_msb_lsb)
736  mode = BPP32_8888;
737  else
738  mode = (xi->byte_order == LSBFirst) ? BPP32_LSB : BPP32_MSB;
739  } else
740  qFatal("Logic error 3");
741 
742 #define GET_PIXEL \
743  uint pixel; \
744  if (d8) pixel = pix[*src++]; \
745  else { \
746  int r = qRed (*p); \
747  int g = qGreen(*p); \
748  int b = qBlue (*p++); \
749  r = red_shift > 0 \
750  ? r << red_shift : r >> -red_shift; \
751  g = green_shift > 0 \
752  ? g << green_shift : g >> -green_shift; \
753  b = blue_shift > 0 \
754  ? b << blue_shift : b >> -blue_shift; \
755  pixel = (r & red_mask)|(g & green_mask) | (b & blue_mask) \
756  | ~(blue_mask | green_mask | red_mask); \
757  }
758 
759 #define GET_PIXEL_DITHER_TC \
760  int r = qRed (*p); \
761  int g = qGreen(*p); \
762  int b = qBlue (*p++); \
763  const int thres = D[x%16][y%16]; \
764  if (r <= (255-(1<<(8-rbits))) && ((r<<rbits) & 255) \
765  > thres) \
766  r += (1<<(8-rbits)); \
767  if (g <= (255-(1<<(8-gbits))) && ((g<<gbits) & 255) \
768  > thres) \
769  g += (1<<(8-gbits)); \
770  if (b <= (255-(1<<(8-bbits))) && ((b<<bbits) & 255) \
771  > thres) \
772  b += (1<<(8-bbits)); \
773  r = red_shift > 0 \
774  ? r << red_shift : r >> -red_shift; \
775  g = green_shift > 0 \
776  ? g << green_shift : g >> -green_shift; \
777  b = blue_shift > 0 \
778  ? b << blue_shift : b >> -blue_shift; \
779  uint pixel = (r & red_mask)|(g & green_mask) | (b & blue_mask);
780 
781 // again, optimized case
782 // can't be optimized that much :(
783 #define GET_PIXEL_DITHER_TC_OPT(red_shift,green_shift,blue_shift,red_mask,green_mask,blue_mask, \
784  rbits,gbits,bbits) \
785  const int thres = D[x%16][y%16]; \
786  int r = qRed (*p); \
787  if (r <= (255-(1<<(8-rbits))) && ((r<<rbits) & 255) \
788  > thres) \
789  r += (1<<(8-rbits)); \
790  int g = qGreen(*p); \
791  if (g <= (255-(1<<(8-gbits))) && ((g<<gbits) & 255) \
792  > thres) \
793  g += (1<<(8-gbits)); \
794  int b = qBlue (*p++); \
795  if (b <= (255-(1<<(8-bbits))) && ((b<<bbits) & 255) \
796  > thres) \
797  b += (1<<(8-bbits)); \
798  uint pixel = ((r red_shift) & red_mask) \
799  | ((g green_shift) & green_mask) \
800  | ((b blue_shift) & blue_mask);
801 
802 #define CYCLE(body) \
803  for (int y=0; y<h; y++) { \
804  const uchar* src = cimage.scanLine(y); \
805  uchar* dst = newbits + xi->bytes_per_line*y; \
806  const QRgb* p = (const QRgb *)src; \
807  body \
808  }
809 
810  if (dither_tc) {
811  switch (mode) {
812  case BPP16_565:
813  CYCLE(
814  quint16* dst16 = (quint16*)dst;
815  for (int x=0; x<w; x++) {
816  GET_PIXEL_DITHER_TC_OPT(<<8,<<3,>>3,0xf800,0x7e0,0x1f,5,6,5)
817  *dst16++ = pixel;
818  }
819  )
820  break;
821  case BPP16_555:
822  CYCLE(
823  quint16* dst16 = (quint16*)dst;
824  for (int x=0; x<w; x++) {
825  GET_PIXEL_DITHER_TC_OPT(<<7,<<2,>>3,0x7c00,0x3e0,0x1f,5,5,5)
826  *dst16++ = pixel;
827  }
828  )
829  break;
830  case BPP16_MSB: // 16 bit MSB
831  CYCLE(
832  for (int x=0; x<w; x++) {
834  *dst++ = (pixel >> 8);
835  *dst++ = pixel;
836  }
837  )
838  break;
839  case BPP16_LSB: // 16 bit LSB
840  CYCLE(
841  for (int x=0; x<w; x++) {
843  *dst++ = pixel;
844  *dst++ = pixel >> 8;
845  }
846  )
847  break;
848  default:
849  qFatal("Logic error");
850  }
851  } else {
852  switch (mode) {
853  case BPP8: // 8 bit
854  CYCLE(
855  Q_UNUSED(p);
856  for (int x=0; x<w; x++)
857  *dst++ = pix[*src++];
858  )
859  break;
860  case BPP16_565:
861  CYCLE(
862  quint16* dst16 = (quint16*)dst;
863  for (int x = 0; x < w; x++) {
864  *dst16++ = ((*p >> 8) & 0xf800)
865  | ((*p >> 5) & 0x7e0)
866  | ((*p >> 3) & 0x1f);
867  ++p;
868  }
869  )
870  break;
871  case BPP16_555:
872  CYCLE(
873  quint16* dst16 = (quint16*)dst;
874  for (int x=0; x<w; x++) {
875  *dst16++ = ((*p >> 9) & 0x7c00)
876  | ((*p >> 6) & 0x3e0)
877  | ((*p >> 3) & 0x1f);
878  ++p;
879  }
880  )
881  break;
882  case BPP16_MSB: // 16 bit MSB
883  CYCLE(
884  for (int x=0; x<w; x++) {
885  GET_PIXEL
886  *dst++ = (pixel >> 8);
887  *dst++ = pixel;
888  }
889  )
890  break;
891  case BPP16_LSB: // 16 bit LSB
892  CYCLE(
893  for (int x=0; x<w; x++) {
894  GET_PIXEL
895  *dst++ = pixel;
896  *dst++ = pixel >> 8;
897  }
898  )
899  break;
900  case BPP24_888:
901  CYCLE(
902  if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
903  for (int x=0; x<w; x++) {
904  *dst++ = qRed (*p);
905  *dst++ = qGreen(*p);
906  *dst++ = qBlue (*p++);
907  }
908  } else {
909  for (int x=0; x<w; x++) {
910  *dst++ = qBlue (*p);
911  *dst++ = qGreen(*p);
912  *dst++ = qRed (*p++);
913  }
914  }
915  )
916  break;
917  case BPP24_MSB: // 24 bit MSB
918  CYCLE(
919  for (int x=0; x<w; x++) {
920  GET_PIXEL
921  *dst++ = pixel >> 16;
922  *dst++ = pixel >> 8;
923  *dst++ = pixel;
924  }
925  )
926  break;
927  case BPP24_LSB: // 24 bit LSB
928  CYCLE(
929  for (int x=0; x<w; x++) {
930  GET_PIXEL
931  *dst++ = pixel;
932  *dst++ = pixel >> 8;
933  *dst++ = pixel >> 16;
934  }
935  )
936  break;
937  case BPP32_8888:
938  CYCLE(
939  memcpy(dst, p, w * 4);
940  )
941  break;
942  case BPP32_MSB: // 32 bit MSB
943  CYCLE(
944  for (int x=0; x<w; x++) {
945  GET_PIXEL
946  *dst++ = pixel >> 24;
947  *dst++ = pixel >> 16;
948  *dst++ = pixel >> 8;
949  *dst++ = pixel;
950  }
951  )
952  break;
953  case BPP32_LSB: // 32 bit LSB
954  CYCLE(
955  for (int x=0; x<w; x++) {
956  GET_PIXEL
957  *dst++ = pixel;
958  *dst++ = pixel >> 8;
959  *dst++ = pixel >> 16;
960  *dst++ = pixel >> 24;
961  }
962  )
963  break;
964  default:
965  qFatal("Logic error 2");
966  }
967  }
968  xi->data = (char *)newbits;
969  }
970 
971  if (d == 8 && !trucol) { // 8 bit pixmap
972  int pop[256]; // pixel popularity
973 
974  if (image.colorCount() == 0)
975  image.setColorCount(1);
976 
977  const QImage &cimage = image;
978  memset(pop, 0, sizeof(int)*256); // reset popularity array
979  for (int i = 0; i < h; i++) { // for each scanline...
980  const uchar* p = cimage.scanLine(i);
981  const uchar *end = p + w;
982  while (p < end) // compute popularity
983  pop[*p++]++;
984  }
985 
986  newbits = (uchar *)malloc(nbytes); // copy image into newbits
987  Q_CHECK_PTR(newbits);
988  if (!newbits) // no memory
989  return;
990  uchar* p = newbits;
991  memcpy(p, cimage.bits(), nbytes); // copy image data into newbits
992 
993  /*
994  * The code below picks the most important colors. It is based on the
995  * diversity algorithm, implemented in XV 3.10. XV is (C) by John Bradley.
996  */
997 
998  struct PIX { // pixel sort element
999  uchar r,g,b,n; // color + pad
1000  int use; // popularity
1001  int index; // index in colormap
1002  int mindist;
1003  };
1004  int ncols = 0;
1005  for (int i=0; i< cimage.colorCount(); i++) { // compute number of colors
1006  if (pop[i] > 0)
1007  ncols++;
1008  }
1009  for (int i = cimage.colorCount(); i < 256; i++) // ignore out-of-range pixels
1010  pop[i] = 0;
1011 
1012  // works since we make sure above to have at least
1013  // one color in the image
1014  if (ncols == 0)
1015  ncols = 1;
1016 
1017  PIX pixarr[256]; // pixel array
1018  PIX pixarr_sorted[256]; // pixel array (sorted)
1019  memset(pixarr, 0, ncols*sizeof(PIX));
1020  PIX *px = &pixarr[0];
1021  int maxpop = 0;
1022  int maxpix = 0;
1023  uint j = 0;
1024  QVector<QRgb> ctable = cimage.colorTable();
1025  for (int i = 0; i < 256; i++) { // init pixel array
1026  if (pop[i] > 0) {
1027  px->r = qRed (ctable[i]);
1028  px->g = qGreen(ctable[i]);
1029  px->b = qBlue (ctable[i]);
1030  px->n = 0;
1031  px->use = pop[i];
1032  if (pop[i] > maxpop) { // select most popular entry
1033  maxpop = pop[i];
1034  maxpix = j;
1035  }
1036  px->index = i;
1037  px->mindist = 1000000;
1038  px++;
1039  j++;
1040  }
1041  }
1042  pixarr_sorted[0] = pixarr[maxpix];
1043  pixarr[maxpix].use = 0;
1044 
1045  for (int i = 1; i < ncols; i++) { // sort pixels
1046  int minpix = -1, mindist = -1;
1047  px = &pixarr_sorted[i-1];
1048  int r = px->r;
1049  int g = px->g;
1050  int b = px->b;
1051  int dist;
1052  if ((i & 1) || i<10) { // sort on max distance
1053  for (int j=0; j<ncols; j++) {
1054  px = &pixarr[j];
1055  if (px->use) {
1056  dist = (px->r - r)*(px->r - r) +
1057  (px->g - g)*(px->g - g) +
1058  (px->b - b)*(px->b - b);
1059  if (px->mindist > dist)
1060  px->mindist = dist;
1061  if (px->mindist > mindist) {
1062  mindist = px->mindist;
1063  minpix = j;
1064  }
1065  }
1066  }
1067  } else { // sort on max popularity
1068  for (int j=0; j<ncols; j++) {
1069  px = &pixarr[j];
1070  if (px->use) {
1071  dist = (px->r - r)*(px->r - r) +
1072  (px->g - g)*(px->g - g) +
1073  (px->b - b)*(px->b - b);
1074  if (px->mindist > dist)
1075  px->mindist = dist;
1076  if (px->use > mindist) {
1077  mindist = px->use;
1078  minpix = j;
1079  }
1080  }
1081  }
1082  }
1083  pixarr_sorted[i] = pixarr[minpix];
1084  pixarr[minpix].use = 0;
1085  }
1086 
1088  uint pix[256]; // pixel translation table
1089  px = &pixarr_sorted[0];
1090  for (int i = 0; i < ncols; i++) { // allocate colors
1091  QColor c(px->r, px->g, px->b);
1092  pix[px->index] = cmap.pixel(c);
1093  px++;
1094  }
1095 
1096  p = newbits;
1097  for (int i = 0; i < nbytes; i++) { // translate pixels
1098  *p = pix[*p];
1099  p++;
1100  }
1101  }
1102 
1103  if (!xi) { // X image not created
1104  xi = XCreateImage(dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0);
1105  if (xi->bits_per_pixel == 16) { // convert 8 bpp ==> 16 bpp
1106  ushort *p2;
1107  int p2inc = xi->bytes_per_line/sizeof(ushort);
1108  ushort *newerbits = (ushort *)malloc(xi->bytes_per_line * h);
1109  Q_CHECK_PTR(newerbits);
1110  if (!newerbits) // no memory
1111  return;
1112  uchar* p = newbits;
1113  for (int y = 0; y < h; y++) { // OOPS: Do right byte order!!
1114  p2 = newerbits + p2inc*y;
1115  for (int x = 0; x < w; x++)
1116  *p2++ = *p++;
1117  }
1118  free(newbits);
1119  newbits = (uchar *)newerbits;
1120  } else if (xi->bits_per_pixel != 8) {
1121  qWarning("QPixmap::fromImage: Display not supported "
1122  "(bpp=%d)", xi->bits_per_pixel);
1123  }
1124  xi->data = (char *)newbits;
1125  }
1126 
1127  hd = (Qt::HANDLE)XCreatePixmap(X11->display,
1128  RootWindow(X11->display, xinfo.screen()),
1129  w, h, dd);
1130 
1131  GC gc = XCreateGC(dpy, hd, 0, 0);
1132  XPutImage(dpy, hd, gc, xi, 0, 0, 0, 0, w, h);
1133  XFreeGC(dpy, gc);
1134 
1135  qSafeXDestroyImage(xi);
1136  d = dd;
1137 
1138 #ifndef QT_NO_XRENDER
1139  if (X11->use_xrender) {
1140  XRenderPictFormat *format = d == 1
1141  ? XRenderFindStandardFormat(X11->display, PictStandardA1)
1142  : XRenderFindVisualFormat(X11->display, (Visual *)xinfo.visual());
1143  picture = XRenderCreatePicture(X11->display, hd, format, 0, 0);
1144  }
1145 #endif
1146 
1147  if (alphaCheck.hasAlpha()) {
1148  QBitmap m = QBitmap::fromImage(image.createAlphaMask(flags));
1149  setMask(m);
1150  }
1151 }
1152 
1154 {
1156  const QRgb c0 = QColor(Qt::black).rgb();
1157  const QRgb c1 = QColor(Qt::white).rgb();
1158  if (img.color(0) == c0 && img.color(1) == c1) {
1159  img.invertPixels();
1160  img.setColor(0, c1);
1161  img.setColor(1, c0);
1162  }
1163 
1164  char *bits;
1165  uchar *tmp_bits;
1166  int w = img.width();
1167  int h = img.height();
1168  int bpl = (w + 7) / 8;
1169  int ibpl = img.bytesPerLine();
1170  if (bpl != ibpl) {
1171  tmp_bits = new uchar[bpl*h];
1172  bits = (char *)tmp_bits;
1173  uchar *p, *b;
1174  int y;
1175  b = tmp_bits;
1176  p = img.scanLine(0);
1177  for (y = 0; y < h; y++) {
1178  memcpy(b, p, bpl);
1179  b += bpl;
1180  p += ibpl;
1181  }
1182  } else {
1183  bits = (char *)img.bits();
1184  tmp_bits = 0;
1185  }
1186  Qt::HANDLE hd = (Qt::HANDLE)XCreateBitmapFromData(X11->display,
1188  bits, w, h);
1189  if (tmp_bits) // Avoid purify complaint
1190  delete [] tmp_bits;
1191  return hd;
1192 }
1193 
1195 {
1196  w = image.width();
1197  h = image.height();
1198  d = 1;
1199  is_null = (w <= 0 || h <= 0);
1200  hd = createBitmapFromImage(image);
1201 #ifndef QT_NO_XRENDER
1202  if (X11->use_xrender)
1203  picture = XRenderCreatePicture(X11->display, hd,
1204  XRenderFindStandardFormat(X11->display, PictStandardA1), 0, 0);
1205 #endif // QT_NO_XRENDER
1206 }
1207 
1208 void QX11PixmapData::fill(const QColor &fillColor)
1209 {
1210  if (fillColor.alpha() != 255) {
1211 #ifndef QT_NO_XRENDER
1212  if (X11->use_xrender) {
1213  if (!picture || d != 32)
1214  convertToARGB32(/*preserveContents = */false);
1215 
1216  ::Picture src = X11->getSolidFill(xinfo.screen(), fillColor);
1217  XRenderComposite(X11->display, PictOpSrc, src, 0, picture,
1218  0, 0, width(), height(),
1219  0, 0, width(), height());
1220  } else
1221 #endif
1222  {
1224  im.fill(PREMUL(fillColor.rgba()));
1225  release();
1227  }
1228  return;
1229  }
1230 
1231  GC gc = XCreateGC(X11->display, hd, 0, 0);
1232  if (depth() == 1) {
1233  XSetForeground(X11->display, gc, qGray(fillColor.rgb()) > 127 ? 0 : 1);
1234  } else if (X11->use_xrender && d >= 24) {
1235  XSetForeground(X11->display, gc, fillColor.rgba());
1236  } else {
1237  XSetForeground(X11->display, gc,
1238  QColormap::instance(xinfo.screen()).pixel(fillColor));
1239  }
1240  XFillRectangle(X11->display, hd, gc, 0, 0, width(), height());
1241  XFreeGC(X11->display, gc);
1242 }
1243 
1245 {
1246  // Cleanup hooks have to be called before the handles are freed
1247  if (is_cached) {
1249  is_cached = false;
1250  }
1251 
1252  release();
1253 }
1254 
1256 {
1257  delete pengine;
1258  pengine = 0;
1259 
1260  if (!X11) {
1261  // At this point, the X server will already have freed our resources,
1262  // so there is nothing to do.
1263  return;
1264  }
1265 
1266  if (x11_mask) {
1267 #ifndef QT_NO_XRENDER
1268  if (mask_picture)
1269  XRenderFreePicture(X11->display, mask_picture);
1270  mask_picture = 0;
1271 #endif
1272  XFreePixmap(X11->display, x11_mask);
1273  x11_mask = 0;
1274  }
1275 
1276  if (hd) {
1277 #ifndef QT_NO_XRENDER
1278  if (picture) {
1279  XRenderFreePicture(X11->display, picture);
1280  picture = 0;
1281  }
1282 #endif // QT_NO_XRENDER
1283 
1284  if (hd2) {
1285  XFreePixmap(xinfo.display(), hd2);
1286  hd2 = 0;
1287  }
1288  if (!(flags & Readonly))
1289  XFreePixmap(xinfo.display(), hd);
1290  hd = 0;
1291  }
1292 }
1293 
1295 {
1296  if (!hasAlphaChannel()) {
1297  QPixmap pm(w, h);
1298  pm.fill(Qt::white);
1299  return pm;
1300  }
1301  QImage im(toImage());
1303 }
1304 
1306 {
1307  QImage image(toImage());
1308  image.setAlphaChannel(alpha.toImage());
1309  release();
1311 }
1312 
1313 
1315 {
1316  QBitmap mask;
1317 #ifndef QT_NO_XRENDER
1318  if (picture && d == 32) {
1319  // #### slow - there must be a better way..
1320  mask = QBitmap::fromImage(toImage().createAlphaMask());
1321  } else
1322 #endif
1323  if (d == 1) {
1324  QX11PixmapData *that = const_cast<QX11PixmapData*>(this);
1325  mask = QPixmap(that);
1326  } else {
1327  mask = mask_to_bitmap(xinfo.screen());
1328  }
1329  return mask;
1330 }
1331 
1353 void QX11PixmapData::setMask(const QBitmap &newmask)
1354 {
1355  if (newmask.isNull()) { // clear mask
1356 #ifndef QT_NO_XRENDER
1357  if (picture && d == 32) {
1358  QX11PixmapData newData(pixelType());
1359  newData.resize(w, h);
1360  newData.fill(Qt::black);
1361  XRenderComposite(X11->display, PictOpOver,
1362  picture, 0, newData.picture,
1363  0, 0, 0, 0, 0, 0, w, h);
1364  release();
1365  *this = newData;
1366  // the new QX11PixmapData object isn't referenced yet, so
1367  // ref it
1368  ref.ref();
1369 
1370  // the below is to make sure the QX11PixmapData destructor
1371  // doesn't delete our newly created render picture
1372  newData.hd = 0;
1373  newData.x11_mask = 0;
1374  newData.picture = 0;
1375  newData.mask_picture = 0;
1376  newData.hd2 = 0;
1377  } else
1378 #endif
1379  if (x11_mask) {
1380 #ifndef QT_NO_XRENDER
1381  if (picture) {
1382  XRenderPictureAttributes attrs;
1383  attrs.alpha_map = 0;
1384  XRenderChangePicture(X11->display, picture, CPAlphaMap,
1385  &attrs);
1386  }
1387  if (mask_picture)
1388  XRenderFreePicture(X11->display, mask_picture);
1389  mask_picture = 0;
1390 #endif
1391  XFreePixmap(X11->display, x11_mask);
1392  x11_mask = 0;
1393  }
1394  return;
1395  }
1396 
1397 #ifndef QT_NO_XRENDER
1398  if (picture && d == 32) {
1399  XRenderComposite(X11->display, PictOpSrc,
1400  picture, newmask.x11PictureHandle(),
1401  picture, 0, 0, 0, 0, 0, 0, w, h);
1402  } else
1403 #endif
1404  if (depth() == 1) {
1405  XGCValues vals;
1406  vals.function = GXand;
1407  GC gc = XCreateGC(X11->display, hd, GCFunction, &vals);
1408  XCopyArea(X11->display, newmask.handle(), hd, gc, 0, 0,
1409  width(), height(), 0, 0);
1410  XFreeGC(X11->display, gc);
1411  } else {
1412  // ##### should or the masks together
1413  if (x11_mask) {
1414  XFreePixmap(X11->display, x11_mask);
1415 #ifndef QT_NO_XRENDER
1416  if (mask_picture)
1417  XRenderFreePicture(X11->display, mask_picture);
1418 #endif
1419  }
1421 #ifndef QT_NO_XRENDER
1422  if (picture) {
1423  mask_picture = XRenderCreatePicture(X11->display, x11_mask,
1424  XRenderFindStandardFormat(X11->display, PictStandardA1), 0, 0);
1425  XRenderPictureAttributes attrs;
1426  attrs.alpha_map = mask_picture;
1427  XRenderChangePicture(X11->display, picture, CPAlphaMap, &attrs);
1428  }
1429 #endif
1430  }
1431 }
1432 
1434 {
1435  switch (metric) {
1437  return w;
1439  return h;
1441  return 1 << d;
1443  return d;
1444  case QPaintDevice::PdmWidthMM: {
1445  const int screen = xinfo.screen();
1446  const int mm = DisplayWidthMM(X11->display, screen) * w
1447  / DisplayWidth(X11->display, screen);
1448  return mm;
1449  }
1451  const int screen = xinfo.screen();
1452  const int mm = (DisplayHeightMM(X11->display, screen) * h)
1453  / DisplayHeight(X11->display, screen);
1454  return mm;
1455  }
1456  case QPaintDevice::PdmDpiX:
1458  return QX11Info::appDpiX(xinfo.screen());
1459  case QPaintDevice::PdmDpiY:
1461  return QX11Info::appDpiY(xinfo.screen());
1462  default:
1463  qWarning("QX11PixmapData::metric(): Invalid metric");
1464  return 0;
1465  }
1466 }
1467 
1469 {
1470  XImage *xi;
1471 };
1472 
1474 {
1475  XImage *xi = xiWrapper.xi;
1476 
1477  // ARGB32_Premultiplied
1478  if (picture && depth() == 32)
1479  return true;
1480 
1481  Visual *visual = (Visual *)xinfo.visual();
1482 
1483  // RGB32
1484  if (depth() == 24 && xi->bits_per_pixel == 32 && visual->red_mask == 0xff0000
1485  && visual->green_mask == 0xff00 && visual->blue_mask == 0xff)
1486  return true;
1487 
1488  // RGB16
1489  if (depth() == 16 && xi->bits_per_pixel == 16 && visual->red_mask == 0xf800
1490  && visual->green_mask == 0x7e0 && visual->blue_mask == 0x1f)
1491  return true;
1492 
1493  return false;
1494 }
1495 
1497 {
1498  XImage *xi = xiWrapper.xi;
1499 
1501  if (depth() == 24)
1502  format = QImage::Format_RGB32;
1503  else if (depth() == 16)
1504  format = QImage::Format_RGB16;
1505 
1506  QImage image((uchar *)xi->data, xi->width, xi->height, xi->bytes_per_line, format);
1507  // take ownership
1508  image.data_ptr()->own_data = true;
1509  xi->data = 0;
1510 
1511  // we may have to swap the byte order
1512  if ((QSysInfo::ByteOrder == QSysInfo::LittleEndian && xi->byte_order == MSBFirst)
1513  || (QSysInfo::ByteOrder == QSysInfo::BigEndian && xi->byte_order == LSBFirst))
1514  {
1515  for (int i=0; i < image.height(); i++) {
1516  if (depth() == 16) {
1517  ushort *p = (ushort*)image.scanLine(i);
1518  ushort *end = p + image.width();
1519  while (p < end) {
1520  *p = ((*p << 8) & 0xff00) | ((*p >> 8) & 0x00ff);
1521  p++;
1522  }
1523  } else {
1524  uint *p = (uint*)image.scanLine(i);
1525  uint *end = p + image.width();
1526  while (p < end) {
1527  *p = ((*p << 24) & 0xff000000) | ((*p << 8) & 0x00ff0000)
1528  | ((*p >> 8) & 0x0000ff00) | ((*p >> 24) & 0x000000ff);
1529  p++;
1530  }
1531  }
1532  }
1533  }
1534 
1535  // fix-up alpha channel
1536  if (format == QImage::Format_RGB32) {
1537  QRgb *p = (QRgb *)image.bits();
1538  for (int y = 0; y < xi->height; ++y) {
1539  for (int x = 0; x < xi->width; ++x)
1540  p[x] |= 0xff000000;
1541  p += xi->bytes_per_line / 4;
1542  }
1543  }
1544 
1545  XDestroyImage(xi);
1546  return image;
1547 }
1548 
1550 {
1551  QXImageWrapper xiWrapper;
1552  xiWrapper.xi = XGetImage(X11->display, hd, rect.x(), rect.y(), rect.width(), rect.height(),
1553  AllPlanes, (depth() == 1) ? XYPixmap : ZPixmap);
1554 
1555  Q_CHECK_PTR(xiWrapper.xi);
1556  if (!xiWrapper.xi)
1557  return QImage();
1558 
1559  if (!x11_mask && canTakeQImageFromXImage(xiWrapper))
1560  return takeQImageFromXImage(xiWrapper);
1561 
1562  QImage image = toImage(xiWrapper, rect);
1563  qSafeXDestroyImage(xiWrapper.xi);
1564  return image;
1565 }
1566 
1583 {
1584  return toImage(QRect(0, 0, w, h));
1585 }
1586 
1587 QImage QX11PixmapData::toImage(const QXImageWrapper &xiWrapper, const QRect &rect) const
1588 {
1589  XImage *xi = xiWrapper.xi;
1590 
1591  int d = depth();
1592  Visual *visual = (Visual *)xinfo.visual();
1593  bool trucol = (visual->c_class >= TrueColor) && d > 1;
1594 
1596  if (d > 1 && d <= 8) {
1597  d = 8;
1598  format = QImage::Format_Indexed8;
1599  }
1600  // we could run into the situation where d == 8 AND trucol is true, which can
1601  // cause problems when converting to and from images. in this case, always treat
1602  // the depth as 32...
1603  if (d > 8 || trucol) {
1604  d = 32;
1605  format = QImage::Format_RGB32;
1606  }
1607 
1608  if (d == 1 && xi->bitmap_bit_order == LSBFirst)
1609  format = QImage::Format_MonoLSB;
1610  if (x11_mask && format == QImage::Format_RGB32)
1611  format = QImage::Format_ARGB32;
1612 
1613  QImage image(xi->width, xi->height, format);
1614  if (image.isNull()) // could not create image
1615  return image;
1616 
1617  QImage alpha;
1618  if (x11_mask) {
1619  if (rect.contains(QRect(0, 0, w, h)))
1620  alpha = mask().toImage();
1621  else
1622  alpha = mask().toImage().copy(rect);
1623  }
1624  bool ale = alpha.format() == QImage::Format_MonoLSB;
1625 
1626  if (trucol) { // truecolor
1627  const uint red_mask = (uint)visual->red_mask;
1628  const uint green_mask = (uint)visual->green_mask;
1629  const uint blue_mask = (uint)visual->blue_mask;
1630  const int red_shift = highest_bit(red_mask) - 7;
1631  const int green_shift = highest_bit(green_mask) - 7;
1632  const int blue_shift = highest_bit(blue_mask) - 7;
1633 
1634  const uint red_bits = n_bits(red_mask);
1635  const uint green_bits = n_bits(green_mask);
1636  const uint blue_bits = n_bits(blue_mask);
1637 
1638  static uint red_table_bits = 0;
1639  static uint green_table_bits = 0;
1640  static uint blue_table_bits = 0;
1641 
1642  if (red_bits < 8 && red_table_bits != red_bits) {
1643  build_scale_table(&red_scale_table, red_bits);
1644  red_table_bits = red_bits;
1645  }
1646  if (blue_bits < 8 && blue_table_bits != blue_bits) {
1647  build_scale_table(&blue_scale_table, blue_bits);
1648  blue_table_bits = blue_bits;
1649  }
1650  if (green_bits < 8 && green_table_bits != green_bits) {
1651  build_scale_table(&green_scale_table, green_bits);
1652  green_table_bits = green_bits;
1653  }
1654 
1655  int r, g, b;
1656 
1657  QRgb *dst;
1658  uchar *src;
1659  uint pixel;
1660  int bppc = xi->bits_per_pixel;
1661 
1662  if (bppc > 8 && xi->byte_order == LSBFirst)
1663  bppc++;
1664 
1665  for (int y = 0; y < xi->height; ++y) {
1666  uchar* asrc = x11_mask ? alpha.scanLine(y) : 0;
1667  dst = (QRgb *)image.scanLine(y);
1668  src = (uchar *)xi->data + xi->bytes_per_line*y;
1669  for (int x = 0; x < xi->width; x++) {
1670  switch (bppc) {
1671  case 8:
1672  pixel = *src++;
1673  break;
1674  case 16: // 16 bit MSB
1675  pixel = src[1] | (uint)src[0] << 8;
1676  src += 2;
1677  break;
1678  case 17: // 16 bit LSB
1679  pixel = src[0] | (uint)src[1] << 8;
1680  src += 2;
1681  break;
1682  case 24: // 24 bit MSB
1683  pixel = src[2] | (uint)src[1] << 8 | (uint)src[0] << 16;
1684  src += 3;
1685  break;
1686  case 25: // 24 bit LSB
1687  pixel = src[0] | (uint)src[1] << 8 | (uint)src[2] << 16;
1688  src += 3;
1689  break;
1690  case 32: // 32 bit MSB
1691  pixel = src[3] | (uint)src[2] << 8 | (uint)src[1] << 16 | (uint)src[0] << 24;
1692  src += 4;
1693  break;
1694  case 33: // 32 bit LSB
1695  pixel = src[0] | (uint)src[1] << 8 | (uint)src[2] << 16 | (uint)src[3] << 24;
1696  src += 4;
1697  break;
1698  default: // should not really happen
1699  x = xi->width; // leave loop
1700  y = xi->height;
1701  pixel = 0; // eliminate compiler warning
1702  qWarning("QPixmap::convertToImage: Invalid depth %d", bppc);
1703  }
1704  if (red_shift > 0)
1705  r = (pixel & red_mask) >> red_shift;
1706  else
1707  r = (pixel & red_mask) << -red_shift;
1708  if (green_shift > 0)
1709  g = (pixel & green_mask) >> green_shift;
1710  else
1711  g = (pixel & green_mask) << -green_shift;
1712  if (blue_shift > 0)
1713  b = (pixel & blue_mask) >> blue_shift;
1714  else
1715  b = (pixel & blue_mask) << -blue_shift;
1716 
1717  if (red_bits < 8)
1718  r = red_scale_table[r];
1719  if (green_bits < 8)
1720  g = green_scale_table[g];
1721  if (blue_bits < 8)
1722  b = blue_scale_table[b];
1723 
1724  if (x11_mask) {
1725  if (ale) {
1726  *dst++ = (asrc[x >> 3] & (1 << (x & 7))) ? qRgba(r, g, b, 0xff) : 0;
1727  } else {
1728  *dst++ = (asrc[x >> 3] & (0x80 >> (x & 7))) ? qRgba(r, g, b, 0xff) : 0;
1729  }
1730  } else {
1731  *dst++ = qRgb(r, g, b);
1732  }
1733  }
1734  }
1735  } else if (xi->bits_per_pixel == d) { // compatible depth
1736  char *xidata = xi->data; // copy each scanline
1737  int bpl = qMin(image.bytesPerLine(),xi->bytes_per_line);
1738  for (int y=0; y<xi->height; y++) {
1739  memcpy(image.scanLine(y), xidata, bpl);
1740  xidata += xi->bytes_per_line;
1741  }
1742  } else {
1743  /* Typically 2 or 4 bits display depth */
1744  qWarning("QPixmap::convertToImage: Display not supported (bpp=%d)",
1745  xi->bits_per_pixel);
1746  return QImage();
1747  }
1748 
1749  if (d == 1) { // bitmap
1750  image.setColorCount(2);
1751  image.setColor(0, qRgb(255,255,255));
1752  image.setColor(1, qRgb(0,0,0));
1753  } else if (!trucol) { // pixmap with colormap
1754  register uchar *p;
1755  uchar *end;
1756  uchar use[256]; // pixel-in-use table
1757  uchar pix[256]; // pixel translation table
1758  int ncols, bpl;
1759  memset(use, 0, 256);
1760  memset(pix, 0, 256);
1761  bpl = image.bytesPerLine();
1762 
1763  if (x11_mask) { // which pixels are used?
1764  for (int i = 0; i < xi->height; i++) {
1765  uchar* asrc = alpha.scanLine(i);
1766  p = image.scanLine(i);
1767  if (ale) {
1768  for (int x = 0; x < xi->width; x++) {
1769  if (asrc[x >> 3] & (1 << (x & 7)))
1770  use[*p] = 1;
1771  ++p;
1772  }
1773  } else {
1774  for (int x = 0; x < xi->width; x++) {
1775  if (asrc[x >> 3] & (0x80 >> (x & 7)))
1776  use[*p] = 1;
1777  ++p;
1778  }
1779  }
1780  }
1781  } else {
1782  for (int i = 0; i < xi->height; i++) {
1783  p = image.scanLine(i);
1784  end = p + bpl;
1785  while (p < end)
1786  use[*p++] = 1;
1787  }
1788  }
1789  ncols = 0;
1790  for (int i = 0; i < 256; i++) { // build translation table
1791  if (use[i])
1792  pix[i] = ncols++;
1793  }
1794  for (int i = 0; i < xi->height; i++) { // translate pixels
1795  p = image.scanLine(i);
1796  end = p + bpl;
1797  while (p < end) {
1798  *p = pix[*p];
1799  p++;
1800  }
1801  }
1802  if (x11_mask) {
1803  int trans;
1804  if (ncols < 256) {
1805  trans = ncols++;
1806  image.setColorCount(ncols); // create color table
1807  image.setColor(trans, 0x00000000);
1808  } else {
1809  image.setColorCount(ncols); // create color table
1810  // oh dear... no spare "transparent" pixel.
1811  // use first pixel in image (as good as any).
1812  trans = image.scanLine(0)[0];
1813  }
1814  for (int i = 0; i < xi->height; i++) {
1815  uchar* asrc = alpha.scanLine(i);
1816  p = image.scanLine(i);
1817  if (ale) {
1818  for (int x = 0; x < xi->width; x++) {
1819  if (!(asrc[x >> 3] & (1 << (x & 7))))
1820  *p = trans;
1821  ++p;
1822  }
1823  } else {
1824  for (int x = 0; x < xi->width; x++) {
1825  if (!(asrc[x >> 3] & (1 << (7 -(x & 7)))))
1826  *p = trans;
1827  ++p;
1828  }
1829  }
1830  }
1831  } else {
1832  image.setColorCount(ncols); // create color table
1833  }
1834  QVector<QColor> colors = QColormap::instance(xinfo.screen()).colormap();
1835  int j = 0;
1836  for (int i=0; i<colors.size(); i++) { // translate pixels
1837  if (use[i])
1838  image.setColor(j++, 0xff000000 | colors.at(i).rgb());
1839  }
1840  }
1841 
1842  return image;
1843 }
1844 
1864  Qt::TransformationMode mode ) const
1865 {
1866  if (mode == Qt::SmoothTransformation || transform.type() >= QTransform::TxProject) {
1867  QImage image = toImage();
1868  return QPixmap::fromImage(image.transformed(transform, mode));
1869  }
1870 
1871  uint w = 0;
1872  uint h = 0; // size of target pixmap
1873  uint ws, hs; // size of source pixmap
1874  uchar *dptr; // data in target pixmap
1875  uint dbpl, dbytes; // bytes per line/bytes total
1876  uchar *sptr; // data in original pixmap
1877  int sbpl; // bytes per line in original
1878  int bpp; // bits per pixel
1879  bool depth1 = depth() == 1;
1880  Display *dpy = X11->display;
1881 
1882  ws = width();
1883  hs = height();
1884 
1885  QTransform mat(transform.m11(), transform.m12(), transform.m13(),
1886  transform.m21(), transform.m22(), transform.m23(),
1887  0., 0., 1);
1888  bool complex_xform = false;
1889  qreal scaledWidth;
1890  qreal scaledHeight;
1891 
1892  if (mat.type() <= QTransform::TxScale) {
1893  scaledHeight = qAbs(mat.m22()) * hs + 0.9999;
1894  scaledWidth = qAbs(mat.m11()) * ws + 0.9999;
1895  h = qAbs(int(scaledHeight));
1896  w = qAbs(int(scaledWidth));
1897  } else { // rotation or shearing
1898  QPolygonF a(QRectF(0, 0, ws, hs));
1899  a = mat.map(a);
1900  QRect r = a.boundingRect().toAlignedRect();
1901  w = r.width();
1902  h = r.height();
1903  scaledWidth = w;
1904  scaledHeight = h;
1905  complex_xform = true;
1906  }
1907  mat = QPixmap::trueMatrix(mat, ws, hs); // true matrix
1908 
1909  bool invertible;
1910  mat = mat.inverted(&invertible); // invert matrix
1911 
1912  if (h == 0 || w == 0 || !invertible
1913  || qAbs(scaledWidth) >= 32768 || qAbs(scaledHeight) >= 32768 )
1914  // error, return null pixmap
1915  return QPixmap();
1916 
1917 #if defined(QT_MITSHM)
1918  static bool try_once = true;
1919  if (try_once) {
1920  try_once = false;
1921  if (!xshminit)
1922  qt_create_mitshm_buffer(this, 800, 600);
1923  }
1924 
1925  bool use_mitshm = xshmimg && !depth1 &&
1926  xshmimg->width >= w && xshmimg->height >= h;
1927 #endif
1928  XImage *xi = XGetImage(X11->display, handle(), 0, 0, ws, hs, AllPlanes,
1929  depth1 ? XYPixmap : ZPixmap);
1930 
1931  if (!xi)
1932  return QPixmap();
1933 
1934  sbpl = xi->bytes_per_line;
1935  sptr = (uchar *)xi->data;
1936  bpp = xi->bits_per_pixel;
1937 
1938  if (depth1)
1939  dbpl = (w+7)/8;
1940  else
1941  dbpl = ((w*bpp+31)/32)*4;
1942  dbytes = dbpl*h;
1943 
1944 #if defined(QT_MITSHM)
1945  if (use_mitshm) {
1946  dptr = (uchar *)xshmimg->data;
1947  uchar fillbyte = bpp == 8 ? white.pixel() : 0xff;
1948  for (int y=0; y<h; y++)
1949  memset(dptr + y*xshmimg->bytes_per_line, fillbyte, dbpl);
1950  } else {
1951 #endif
1952  dptr = (uchar *)malloc(dbytes); // create buffer for bits
1953  Q_CHECK_PTR(dptr);
1954  if (depth1) // fill with zeros
1955  memset(dptr, 0, dbytes);
1956  else if (bpp == 8) // fill with background color
1957  memset(dptr, WhitePixel(X11->display, xinfo.screen()), dbytes);
1958  else
1959  memset(dptr, 0, dbytes);
1960 #if defined(QT_MITSHM)
1961  }
1962 #endif
1963 
1964  // #define QT_DEBUG_XIMAGE
1965 #if defined(QT_DEBUG_XIMAGE)
1966  qDebug("----IMAGE--INFO--------------");
1967  qDebug("width............. %d", xi->width);
1968  qDebug("height............ %d", xi->height);
1969  qDebug("xoffset........... %d", xi->xoffset);
1970  qDebug("format............ %d", xi->format);
1971  qDebug("byte order........ %d", xi->byte_order);
1972  qDebug("bitmap unit....... %d", xi->bitmap_unit);
1973  qDebug("bitmap bit order.. %d", xi->bitmap_bit_order);
1974  qDebug("depth............. %d", xi->depth);
1975  qDebug("bytes per line.... %d", xi->bytes_per_line);
1976  qDebug("bits per pixel.... %d", xi->bits_per_pixel);
1977 #endif
1978 
1979  int type;
1980  if (xi->bitmap_bit_order == MSBFirst)
1981  type = QT_XFORM_TYPE_MSBFIRST;
1982  else
1983  type = QT_XFORM_TYPE_LSBFIRST;
1984  int xbpl, p_inc;
1985  if (depth1) {
1986  xbpl = (w+7)/8;
1987  p_inc = dbpl - xbpl;
1988  } else {
1989  xbpl = (w*bpp)/8;
1990  p_inc = dbpl - xbpl;
1991 #if defined(QT_MITSHM)
1992  if (use_mitshm)
1993  p_inc = xshmimg->bytes_per_line - xbpl;
1994 #endif
1995  }
1996 
1997  if (!qt_xForm_helper(mat, xi->xoffset, type, bpp, dptr, xbpl, p_inc, h, sptr, sbpl, ws, hs)){
1998  qWarning("QPixmap::transform: display not supported (bpp=%d)",bpp);
1999  QPixmap pm;
2000  return pm;
2001  }
2002 
2003  qSafeXDestroyImage(xi);
2004 
2005  if (depth1) { // mono bitmap
2006  QBitmap bm = QBitmap::fromData(QSize(w, h), dptr,
2007  BitmapBitOrder(X11->display) == MSBFirst
2010  free(dptr);
2011  return bm;
2012  } else { // color pixmap
2014  QPixmap pm(x11Data);
2016  x11Data->xinfo = xinfo;
2017  x11Data->d = d;
2018  x11Data->w = w;
2019  x11Data->h = h;
2020  x11Data->is_null = (w <= 0 || h <= 0);
2021  x11Data->hd = (Qt::HANDLE)XCreatePixmap(X11->display,
2022  RootWindow(X11->display, xinfo.screen()),
2023  w, h, d);
2024  x11Data->setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1));
2025 
2026 #ifndef QT_NO_XRENDER
2027  if (X11->use_xrender) {
2028  XRenderPictFormat *format = x11Data->d == 32
2029  ? XRenderFindStandardFormat(X11->display, PictStandardARGB32)
2030  : XRenderFindVisualFormat(X11->display, (Visual *) x11Data->xinfo.visual());
2031  x11Data->picture = XRenderCreatePicture(X11->display, x11Data->hd, format, 0, 0);
2032  }
2033 #endif // QT_NO_XRENDER
2034 
2035  GC gc = XCreateGC(X11->display, x11Data->hd, 0, 0);
2036 #if defined(QT_MITSHM)
2037  if (use_mitshm) {
2038  XCopyArea(dpy, xshmpm, x11Data->hd, gc, 0, 0, w, h, 0, 0);
2039  } else
2040 #endif
2041  {
2042  xi = XCreateImage(dpy, (Visual*)x11Data->xinfo.visual(),
2043  x11Data->d,
2044  ZPixmap, 0, (char *)dptr, w, h, 32, 0);
2045  XPutImage(dpy, pm.handle(), gc, xi, 0, 0, 0, 0, w, h);
2046  qSafeXDestroyImage(xi);
2047  }
2048  XFreeGC(X11->display, gc);
2049 
2050  if (x11_mask) { // xform mask, too
2051  pm.setMask(mask_to_bitmap(xinfo.screen()).transformed(transform));
2052  } else if (d != 32 && complex_xform) { // need a mask!
2053  QBitmap mask(ws, hs);
2054  mask.fill(Qt::color1);
2055  pm.setMask(mask.transformed(transform));
2056  }
2057  return pm;
2058  }
2059 }
2060 
2061 int QPixmap::x11SetDefaultScreen(int screen)
2062 {
2063  int old = defaultScreen;
2064  defaultScreen = screen;
2065  return old;
2066 }
2067 
2068 void QPixmap::x11SetScreen(int screen)
2069 {
2070  if (paintingActive()) {
2071  qWarning("QPixmap::x11SetScreen(): Cannot change screens during painting");
2072  return;
2073  }
2074 
2075  if (isNull())
2076  return;
2077 
2078  if (data->classId() != QPixmapData::X11Class)
2079  return;
2080 
2081  if (screen < 0)
2082  screen = QX11Info::appScreen();
2083 
2084  QX11PixmapData *x11Data = static_cast<QX11PixmapData*>(data.data());
2085  if (screen == x11Data->xinfo.screen())
2086  return; // nothing to do
2087 
2088  if (isNull()) {
2089  QX11InfoData* xd = x11Data->xinfo.getX11Data(true);
2090  xd->screen = screen;
2091  xd->depth = QX11Info::appDepth(screen);
2092  xd->cells = QX11Info::appCells(screen);
2093  xd->colormap = QX11Info::appColormap(screen);
2095  xd->visual = (Visual *)QX11Info::appVisual(screen);
2097  x11Data->xinfo.setX11Data(xd);
2098  return;
2099  }
2100 #if 0
2101  qDebug("QPixmap::x11SetScreen for %p from %d to %d. Size is %d/%d", x11Data, x11Data->xinfo.screen(), screen, width(), height());
2102 #endif
2103 
2104  x11SetDefaultScreen(screen);
2105  *this = qt_toX11Pixmap(toImage());
2106 }
2107 
2108 QPixmap QPixmap::grabWindow(WId window, int x, int y, int w, int h)
2109 {
2110  if (w == 0 || h == 0)
2111  return QPixmap();
2112 
2113  Display *dpy = X11->display;
2114  XWindowAttributes window_attr;
2115  if (!XGetWindowAttributes(dpy, window, &window_attr))
2116  return QPixmap();
2117 
2118  if (w < 0)
2119  w = window_attr.width - x;
2120  if (h < 0)
2121  h = window_attr.height - y;
2122 
2123  // determine the screen
2124  int scr;
2125  for (scr = 0; scr < ScreenCount(dpy); ++scr) {
2126  if (window_attr.root == RootWindow(dpy, scr)) // found it
2127  break;
2128  }
2129  if (scr >= ScreenCount(dpy)) // sanity check
2130  return QPixmap();
2131 
2132 
2133  // get the depth of the root window
2134  XWindowAttributes root_attr;
2135  if (!XGetWindowAttributes(dpy, window_attr.root, &root_attr))
2136  return QPixmap();
2137 
2138  if (window_attr.depth == root_attr.depth) {
2139  // if the depth of the specified window and the root window are the
2140  // same, grab pixels from the root window (so that we get the any
2141  // overlapping windows and window manager frames)
2142 
2143  // map x and y to the root window
2144  WId unused;
2145  if (!XTranslateCoordinates(dpy, window, window_attr.root, x, y,
2146  &x, &y, &unused))
2147  return QPixmap();
2148 
2149  window = window_attr.root;
2150  window_attr = root_attr;
2151  }
2152 
2154 
2155  void qt_x11_getX11InfoForWindow(QX11Info * xinfo, const XWindowAttributes &a);
2156  qt_x11_getX11InfoForWindow(&data->xinfo,window_attr);
2157 
2158  data->resize(w, h);
2159 
2160  QPixmap pm(data);
2161 
2163  pm.x11SetScreen(scr);
2164 
2165  GC gc = XCreateGC(dpy, pm.handle(), 0, 0);
2166  XSetSubwindowMode(dpy, gc, IncludeInferiors);
2167  XCopyArea(dpy, window, pm.handle(), gc, x, y, w, h, 0, 0);
2168  XFreeGC(dpy, gc);
2169 
2170  return pm;
2171 }
2172 
2174 {
2175  return d == 32;
2176 }
2177 
2178 const QX11Info &QPixmap::x11Info() const
2179 {
2180  if (data && data->classId() == QPixmapData::X11Class)
2181  return static_cast<QX11PixmapData*>(data.data())->xinfo;
2182  else {
2183  static QX11Info nullX11Info;
2184  return nullX11Info;
2185  }
2186 }
2187 
2188 #if !defined(QT_NO_XRENDER)
2189 static XRenderPictFormat *qt_renderformat_for_depth(const QX11Info &xinfo, int depth)
2190 {
2191  if (depth == 1)
2192  return XRenderFindStandardFormat(X11->display, PictStandardA1);
2193  else if (depth == 32)
2194  return XRenderFindStandardFormat(X11->display, PictStandardARGB32);
2195  else
2196  return XRenderFindVisualFormat(X11->display, (Visual *)xinfo.visual());
2197 }
2198 #endif
2199 
2201 {
2202  QX11PixmapData *that = const_cast<QX11PixmapData*>(this);
2203 
2204  if ((flags & Readonly) && share_mode == QPixmap::ImplicitlyShared) {
2205  // if someone wants to draw onto us, copy the shared contents
2206  // and turn it into a fully fledged QPixmap
2207  ::Pixmap hd_copy = XCreatePixmap(X11->display, RootWindow(X11->display, xinfo.screen()),
2208  w, h, d);
2209 #if !defined(QT_NO_XRENDER)
2210  XRenderPictFormat *format = qt_renderformat_for_depth(xinfo, d);
2211  ::Picture picture_copy = XRenderCreatePicture(X11->display, hd_copy, format, 0, 0);
2212 
2213  if (picture && d == 32) {
2214  XRenderComposite(X11->display, PictOpSrc, picture, 0, picture_copy,
2215  0, 0, 0, 0, 0, 0, w, h);
2216  XRenderFreePicture(X11->display, picture);
2217  that->picture = picture_copy;
2218  } else
2219 #endif
2220  {
2221  GC gc = XCreateGC(X11->display, hd_copy, 0, 0);
2222  XCopyArea(X11->display, hd, hd_copy, gc, 0, 0, w, h, 0, 0);
2223  XFreeGC(X11->display, gc);
2224  }
2225  that->hd = hd_copy;
2227  }
2228 
2229  if (!that->pengine)
2230  that->pengine = new QX11PaintEngine;
2231  return that->pengine;
2232 }
2233 
2234 Qt::HANDLE QPixmap::x11PictureHandle() const
2235 {
2236 #ifndef QT_NO_XRENDER
2237  if (data && data->classId() == QPixmapData::X11Class)
2238  return static_cast<const QX11PixmapData*>(data.data())->picture;
2239  else
2240  return 0;
2241 #else
2242  return 0;
2243 #endif // QT_NO_XRENDER
2244 }
2245 
2247 {
2248 #ifndef QT_NO_XRENDER
2249  if (d == QX11Info::appDepth() || !X11->use_xrender)
2250  return hd;
2251  if (!hd2) {
2252  hd2 = XCreatePixmap(xinfo.display(), hd, w, h, QX11Info::appDepth());
2253  XRenderPictFormat *format = XRenderFindVisualFormat(xinfo.display(),
2254  (Visual*) xinfo.visual());
2255  Picture pic = XRenderCreatePicture(xinfo.display(), hd2, format, 0, 0);
2256  XRenderComposite(xinfo.display(), PictOpSrc, picture,
2257  XNone, pic, 0, 0, 0, 0, 0, 0, w, h);
2258  XRenderFreePicture(xinfo.display(), pic);
2259  }
2260  return hd2;
2261 #else
2262  return hd;
2263 #endif
2264 }
2265 
2266 void QX11PixmapData::copy(const QPixmapData *data, const QRect &rect)
2267 {
2268  if (data->pixelType() == BitmapType) {
2269  fromImage(data->toImage().copy(rect), Qt::AutoColor);
2270  return;
2271  }
2272 
2273  const QX11PixmapData *x11Data = static_cast<const QX11PixmapData*>(data);
2274 
2275  setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1));
2276 
2277  flags &= ~Uninitialized;
2278  xinfo = x11Data->xinfo;
2279  d = x11Data->d;
2280  w = rect.width();
2281  h = rect.height();
2282  is_null = (w <= 0 || h <= 0);
2283  hd = (Qt::HANDLE)XCreatePixmap(X11->display,
2284  RootWindow(X11->display, x11Data->xinfo.screen()),
2285  w, h, d);
2286 #ifndef QT_NO_XRENDER
2287  if (X11->use_xrender) {
2288  XRenderPictFormat *format = d == 32
2289  ? XRenderFindStandardFormat(X11->display, PictStandardARGB32)
2290  : XRenderFindVisualFormat(X11->display, (Visual *)xinfo.visual());
2291  picture = XRenderCreatePicture(X11->display, hd, format, 0, 0);
2292  }
2293 #endif // QT_NO_XRENDER
2294  if (x11Data->x11_mask) {
2295  x11_mask = XCreatePixmap(X11->display, hd, w, h, 1);
2296 #ifndef QT_NO_XRENDER
2297  if (X11->use_xrender) {
2298  mask_picture = XRenderCreatePicture(X11->display, x11_mask,
2299  XRenderFindStandardFormat(X11->display, PictStandardA1), 0, 0);
2300  XRenderPictureAttributes attrs;
2301  attrs.alpha_map = x11Data->mask_picture;
2302  XRenderChangePicture(X11->display, x11Data->picture, CPAlphaMap, &attrs);
2303  }
2304 #endif
2305  }
2306 
2307 #if !defined(QT_NO_XRENDER)
2308  if (x11Data->picture && x11Data->d == 32) {
2309  XRenderComposite(X11->display, PictOpSrc,
2310  x11Data->picture, 0, picture,
2311  rect.x(), rect.y(), 0, 0, 0, 0, w, h);
2312  } else
2313 #endif
2314  {
2315  GC gc = XCreateGC(X11->display, hd, 0, 0);
2316  XCopyArea(X11->display, x11Data->hd, hd, gc,
2317  rect.x(), rect.y(), w, h, 0, 0);
2318  if (x11Data->x11_mask) {
2319  GC monogc = XCreateGC(X11->display, x11_mask, 0, 0);
2320  XCopyArea(X11->display, x11Data->x11_mask, x11_mask, monogc,
2321  rect.x(), rect.y(), w, h, 0, 0);
2322  XFreeGC(X11->display, monogc);
2323  }
2324  XFreeGC(X11->display, gc);
2325  }
2326 }
2327 
2328 bool QX11PixmapData::scroll(int dx, int dy, const QRect &rect)
2329 {
2330  GC gc = XCreateGC(X11->display, hd, 0, 0);
2331  XCopyArea(X11->display, hd, hd, gc,
2332  rect.left(), rect.top(), rect.width(), rect.height(),
2333  rect.left() + dx, rect.top() + dy);
2334  XFreeGC(X11->display, gc);
2335  return true;
2336 }
2337 
2338 #if !defined(QT_NO_XRENDER)
2339 void QX11PixmapData::convertToARGB32(bool preserveContents)
2340 {
2341  if (!X11->use_xrender)
2342  return;
2343 
2344  // Q_ASSERT(count == 1);
2345  if ((flags & Readonly) && share_mode == QPixmap::ExplicitlyShared)
2346  return;
2347 
2348  Pixmap pm = XCreatePixmap(X11->display, RootWindow(X11->display, xinfo.screen()),
2349  w, h, 32);
2350  Picture p = XRenderCreatePicture(X11->display, pm,
2351  XRenderFindStandardFormat(X11->display, PictStandardARGB32), 0, 0);
2352  if (picture) {
2353  if (preserveContents)
2354  XRenderComposite(X11->display, PictOpSrc, picture, 0, p, 0, 0, 0, 0, 0, 0, w, h);
2355  if (!(flags & Readonly))
2356  XRenderFreePicture(X11->display, picture);
2357  }
2358  if (hd && !(flags & Readonly))
2359  XFreePixmap(X11->display, hd);
2360  if (x11_mask) {
2361  XFreePixmap(X11->display, x11_mask);
2362  if (mask_picture)
2363  XRenderFreePicture(X11->display, mask_picture);
2364  x11_mask = 0;
2365  mask_picture = 0;
2366  }
2367  hd = pm;
2368  picture = p;
2369  d = 32;
2370 }
2371 #endif
2372 
2373 QPixmap QPixmap::fromX11Pixmap(Qt::HANDLE pixmap, QPixmap::ShareMode mode)
2374 {
2375  Window root;
2376  int x;
2377  int y;
2378  uint width;
2379  uint height;
2380  uint border_width;
2381  uint depth;
2382  XWindowAttributes win_attribs;
2383  int num_screens = ScreenCount(X11->display);
2384  int screen = 0;
2385 
2386  XGetGeometry(X11->display, pixmap, &root, &x, &y, &width, &height, &border_width, &depth);
2387  XGetWindowAttributes(X11->display, root, &win_attribs);
2388 
2389  for (; screen < num_screens; ++screen) {
2390  if (win_attribs.screen == ScreenOfDisplay(X11->display, screen))
2391  break;
2392  }
2393 
2395  data->setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1));
2397  data->share_mode = mode;
2398  data->w = width;
2399  data->h = height;
2400  data->is_null = (width <= 0 || height <= 0);
2401  data->d = depth;
2402  data->hd = pixmap;
2403 
2404  if (defaultScreen >= 0 && defaultScreen != screen) {
2405  QX11InfoData* xd = data->xinfo.getX11Data(true);
2406  xd->screen = defaultScreen;
2407  xd->depth = QX11Info::appDepth(xd->screen);
2408  xd->cells = QX11Info::appCells(xd->screen);
2411  xd->visual = (Visual *)QX11Info::appVisual(xd->screen);
2413  data->xinfo.setX11Data(xd);
2414  }
2415 
2416 #ifndef QT_NO_XRENDER
2417  if (X11->use_xrender) {
2418  XRenderPictFormat *format = qt_renderformat_for_depth(data->xinfo, depth);
2419  data->picture = XRenderCreatePicture(X11->display, data->hd, format, 0, 0);
2420  }
2421 #endif // QT_NO_XRENDER
2422 
2423  return QPixmap(data);
2424 }
2425 
2426 
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition: qcolor.h:67
QRect toAlignedRect() const
Returns a QRect based on the values of this rectangle that is the smallest possible integer rectangle...
Definition: qrect.cpp:2817
int depth() const
Returns the color depth (bits per pixel) of the X display.
DataPtr & data_ptr()
Definition: qpixmap.h:297
static Qt::HANDLE createBitmapFromImage(const QImage &image)
QImage toImage() const
Converts the pixmap to a QImage.
Definition: qpixmap.cpp:542
static QPixmap fromImage(const QImage &image, Qt::ImageConversionFlags flags=Qt::AutoColor)
Converts the given image to a pixmap using the specified flags to control the conversion.
Definition: qpixmap.cpp:2197
Format
The following image formats are available in Qt.
Definition: qimage.h:91
static QColormap instance(int screen=-1)
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
unsigned long WId
Definition: qwindowdefs.h:119
void setColor(int i, QRgb c)
Sets the color at the given index in the color table, to the given to colorValue. ...
Definition: qimage.cpp:1850
double qreal
Definition: qglobal.h:1193
unsigned char c[8]
Definition: qnumeric_p.h:62
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
static QMatrix trueMatrix(const QMatrix &m, int w, int h)
This convenience function loads the matrix m into a QTransform and calls the overloaded function with...
Definition: qpixmap.cpp:584
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
Q_CORE_EXPORT QTextStream & ws(QTextStream &s)
int width() const
Returns the width of the pixmap.
Definition: qpixmap.cpp:630
static int defaultScreen
static int appScreen()
Returns the number of the screen where the application is being displayed.
Qt::HANDLE picture
QX11PaintEngine * pengine
void qAddPostRoutine(QtCleanUpFunction p)
Qt::HANDLE hd
Q_GUI_EXPORT_INLINE int qAlpha(QRgb rgb)
Definition: qrgb.h:66
friend class QBitmap
static int appDepth(int screen=-1)
Returns the color depth (bits per pixel) used by the application on the given screen.
QPixmap qt_toX11Pixmap(const QImage &image)
Definition: qpixmap_x11.cpp:81
void setMask(const QBitmap &)
Sets a mask bitmap.
Definition: qpixmap.cpp:822
static bool appDefaultVisual(int screen=-1)
Returns true if the application has a default visual on the given screen; otherwise returns false...
#define Q_GUI_EXPORT
Definition: qglobal.h:1450
bool isNull() const
Returns true if it is a null image, otherwise returns false.
Definition: qimage.cpp:1542
qreal m21() const
Returns the horizontal shearing factor.
Definition: qtransform.h:249
void fill(uint pixel)
Fills the entire image with the given pixelValue.
Definition: qimage.cpp:2032
static Qt::HANDLE appRootWindow(int screen=-1)
Returns a handle for the applications root window on the given screen.
QBitmap mask_to_bitmap(int screen) const
static QBitmap fromData(const QSize &size, const uchar *bits, QImage::Format monoFormat=QImage::Format_MonoLSB)
Constructs a bitmap with the given size, and sets the contents to the bits supplied.
Definition: qbitmap.cpp:318
static int highest_bit(uint v)
qreal m22() const
Returns the vertical scaling factor.
Definition: qtransform.h:253
int width() const
static QColor cmap[256]
Definition: qgl_mac.mm:760
int left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:240
int byteCount() const
Returns the number of bytes occupied by the image data.
Definition: qimage.cpp:1800
int width() const
Returns the width of the rectangle.
Definition: qrect.h:303
QPixmapData * createCompatiblePixmapData() const
const QImage * image
const uchar * qt_get_bitflip_array()
Definition: qimage.cpp:765
Qt::HANDLE handle() const
Returns the pixmap&#39;s handle to the device context.
Definition: qpixmap.cpp:1299
int bytesPerLine() const
Returns the number of bytes per image scanline.
Definition: qimage.cpp:1812
long ASN1_INTEGER_get ASN1_INTEGER * a
QPixmap::ShareMode share_mode
static void qSafeXDestroyImage(XImage *x)
QX11AlphaDetector(const QImage *i, Qt::ImageConversionFlags flags)
bool ref()
Atomically increments the value of this QAtomicInt.
static int lowest_bit(uint v)
void resize(int width, int height)
int height() const
Returns the height of the rectangle.
Definition: qrect.h:306
QBasicAtomicInt qt_pixmap_serial
Q_DECL_CONSTEXPR T qAbs(const T &t)
Definition: qglobal.h:1201
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
QRectF boundingRect() const
Returns the bounding rectangle of the polygon, or QRectF(0,0,0,0) if the polygon is empty...
Definition: qpolygon.cpp:742
TransformationType type() const
Returns the transformation type of this matrix.
#define Q_BASIC_ATOMIC_INITIALIZER(a)
Definition: qbasicatomic.h:218
QBitmap transformed(const QMatrix &) const
This convenience function converts the matrix to a QTransform and calls the overloaded function...
Definition: qbitmap.cpp:356
#define X11
Definition: qt_x11_p.h:724
void fromImage(const QImage &image, Qt::ImageConversionFlags flags)
void setAlphaChannel(const QPixmap &alphaChannel)
static void executePixmapDataDestructionHooks(QPixmapData *)
QX11InfoData * x11data
Definition: qx11info_x11.h:105
Qt::HANDLE mask_picture
Format format() const
Returns the format of the image.
Definition: qimage.cpp:2305
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
Q_GUI_EXPORT_INLINE int qRed(QRgb rgb)
Definition: qrgb.h:57
static uint n_bits(uint v)
#define PIX(x, y)
Q_CORE_EXPORT void qDebug(const char *,...)
friend class QX11PaintEngine
PixelType pixelType() const
qreal m12() const
Returns the vertical shearing factor.
Definition: qtransform.h:241
QX11InfoData * getX11Data(bool def=false) const
for(int ii=mo->methodOffset();ii< mo->methodCount();++ii)
unsigned char uchar
Definition: qglobal.h:994
The QBitmap class provides monochrome (1-bit depth) pixmaps.
Definition: qbitmap.h:55
QPaintEngine * paintEngine() const
NSWindow * window
virtual QImage toImage() const =0
void setColorCount(int)
Resizes the color table to contain colorCount entries.
Definition: qimage.cpp:2275
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
Q_GUI_EXPORT_INLINE QRgb qRgba(int r, int g, int b, int a)
Definition: qrgb.h:72
The QRectF class defines a rectangle in the plane using floating point precision. ...
Definition: qrect.h:511
int metric(QPaintDevice::PaintDeviceMetric metric) const
static Qt::HANDLE bitmap_to_mask(const QBitmap &, int screen)
static uint * blue_scale_table
Qt::HANDLE handle() const
Definition: qpixmap_x11_p.h:95
bool scroll(int dx, int dy, const QRect &rect)
Q_STATIC_INLINE_FUNCTION uint PREMUL(uint x)
#define D(arg)
static bool init
virtual void fromImage(const QImage &image, Qt::ImageConversionFlags flags)=0
static int appDpiX(int screen=-1)
Returns the horizontal resolution of the given screen in terms of the number of dots per inch...
The QPolygonF class provides a vector of points using floating point precision.
Definition: qpolygon.h:134
TransformationMode
Definition: qnamespace.h:1510
unsigned short quint16
Definition: qglobal.h:936
Q_CORE_EXPORT void qWarning(const char *,...)
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
void convertToARGB32(bool preserveContents=true)
static bool appDefaultColormap(int screen=-1)
Returns true if the application has a default color map on the given screen; otherwise returns false...
static const char * data(const QByteArray &arr)
unsigned int uint
Definition: qglobal.h:996
QPixmap transformed(const QTransform &transform, Qt::TransformationMode mode) const
Returns a copy of the pixmap that is transformed using the given transformation matrix and transforma...
#define CYCLE(body)
QImage createAlphaMask(Qt::ImageConversionFlags flags=Qt::AutoColor) const
Builds and returns a 1-bpp mask from the alpha buffer in this image.
Definition: qimage.cpp:4720
#define QT_XFORM_TYPE_MSBFIRST
static uint * green_scale_table
ClassId classId() const
int depth() const
Returns the depth of the image.
Definition: qimage.cpp:1620
void * HANDLE
Definition: qnamespace.h:1671
unsigned long ulong
Definition: qglobal.h:997
static XRenderPictFormat * qt_renderformat_for_depth(const QX11Info &xinfo, int depth)
void * visual() const
Returns the current visual.
QImage transformed(const QMatrix &matrix, Qt::TransformationMode mode=Qt::FastTransformation) const
Returns a copy of the image that is transformed using the given transformation matrix and transformat...
Definition: qimage.cpp:4698
static Qt::HANDLE appColormap(int screen=-1)
Returns a handle for the application&#39;s color map on the given screen.
void copy(const QPixmapData *data, const QRect &rect)
The QPaintEngine class provides an abstract definition of how QPainter draws to a given device on a g...
Definition: qpaintengine.h:90
PixelType type
Q_GUI_EXPORT_INLINE int qBlue(QRgb rgb)
Definition: qrgb.h:63
#define QT_XFORM_TYPE_LSBFIRST
Visual * visual
Definition: qt_x11_p.h:318
uint pixel(const QColor &color) const
QImage alphaChannel() const
Returns the alpha channel of the image as a new grayscale QImage in which each pixel&#39;s red...
Definition: qimage.cpp:6430
bool contains(const QPoint &p, bool proper=false) const
Returns true if the given point is inside or on the edge of the rectangle, otherwise returns false...
Definition: qrect.cpp:1101
DataPtr & data_ptr()
Definition: qimage.h:346
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
QPixmap alphaChannel() const
#define rgb(r, g, b)
Definition: qcolor_p.cpp:130
int Q_GUI_EXPORT qt_x11_preferred_pixmap_depth
void fill(const QColor &fillColor=Qt::white)
Fills the pixmap with the given color.
Definition: qpixmap.cpp:1080
unsigned long Picture
Q_GUI_EXPORT_INLINE int qGray(int r, int g, int b)
Definition: qrgb.h:75
uchar * bits()
Returns a pointer to the first pixel data.
Definition: qimage.cpp:1946
Q_CORE_EXPORT void qFatal(const char *,...)
static uint * red_scale_table
#define Q_CHECK_PTR(p)
Definition: qglobal.h:1853
struct _XDisplay Display
Definition: qwindowdefs.h:115
int top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:243
int width() const
Returns the width of the image.
Definition: qimage.cpp:1557
QImage toImage() const
Converts the pixmap to a QImage.
The QX11Info class provides information about the X display configuration.
Definition: qx11info_x11.h:63
QImage convertToFormat(Format f, Qt::ImageConversionFlags flags=Qt::AutoColor) const Q_REQUIRED_RESULT
Returns a copy of the image in the given format.
Definition: qimage.cpp:3966
int depth() const
QBitmap mask() const
#define GET_PIXEL_DITHER_TC_OPT(red_shift, green_shift, blue_shift, red_mask, green_mask, blue_mask, rbits, gbits, bbits)
Qt::HANDLE x11_mask
void setMask(const QBitmap &mask)
Sets a mask bitmap.
void fill(const QColor &color)
ushort alpha
Returns the alpha color component of this color.
Definition: qcolor.h:242
int y() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:255
bool hasAlphaChannel() const
int colorCount() const
Returns the size of the color table for the image.
Definition: qimage.cpp:1656
static void * appVisual(int screen=-1)
Returns the current visual used by the application on the given screen.
uint own_data
Definition: qimage_p.h:94
unsigned short ushort
Definition: qglobal.h:995
void qt_x11_getX11InfoForWindow(QX11Info *xinfo, const XWindowAttributes &a)
void * data_ptr(const QTransform &t)
Definition: qpainter_p.h:81
Colormap colormap
Definition: qt_x11_p.h:317
int x() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:252
Q_GUI_EXPORT_INLINE QRgb qRgb(int r, int g, int b)
Definition: qrgb.h:69
QAtomicInt ref
qreal m23() const
Returns the vertical projection factor.
Definition: qtransform.h:257
bool qt_xForm_helper(const QTransform &trueMat, int xoffset, int type, int depth, uchar *dptr, int dbpl, int p_inc, int dHeight, const uchar *sptr, int sbpl, int sWidth, int sHeight)
Definition: qimage.cpp:6100
if(void) toggleToolbarShown
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
int fetchAndAddRelaxed(int valueToAdd)
Definition: qnamespace.h:54
int height() const
Returns the height of the image.
Definition: qimage.cpp:1572
QImage takeQImageFromXImage(const QXImageWrapper &xi) const
quint16 index
The QPixmap class is an off-screen image representation that can be used as a paint device...
Definition: qpixmap.h:71
Q_GUI_EXPORT_INLINE int qGreen(QRgb rgb)
Definition: qrgb.h:60
static void build_scale_table(uint **table, uint nBits)
Q_STATIC_INLINE_FUNCTION int qt_div_255(int x)
#define GET_PIXEL_DITHER_TC
struct _XGC * GC
Definition: qwindowdefs.h:117
int height() const
Returns the height of the pixmap.
Definition: qpixmap.cpp:645
static QBitmap fromImage(const QImage &image, Qt::ImageConversionFlags flags=Qt::AutoColor)
Returns a copy of the given image converted to a bitmap using the specified image conversion flags...
Definition: qbitmap.cpp:281
int height() const
bool isNull() const
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
T * data()
Returns a pointer to the data stored in the vector.
Definition: qvector.h:152
static QPixmap grabWindow(WId, int x=0, int y=0, int w=-1, int h=-1)
Creates and returns a pixmap constructed by grabbing the contents of the given window restricted by Q...
void invertPixels(InvertMode=InvertRgb)
Inverts all pixel values in the image.
Definition: qimage.cpp:2179
void setX11Data(const QX11InfoData *)
Makes a shallow copy of the X11-specific data d and assigns it to this class.
qreal m13() const
Returns the horizontal projection factor.
Definition: qtransform.h:245
QRgb rgba() const
Returns the RGB value of the color, including its alpha.
Definition: qcolor.cpp:1019
void setAlphaChannel(const QImage &alphaChannel)
Sets the alpha channel of this image to the given alphaChannel.
Definition: qimage.cpp:6329
void bitmapFromImage(const QImage &image)
bool defaultColormap
Definition: qt_x11_p.h:319
bool isNull() const
Returns true if this is a null pixmap; otherwise returns false.
Definition: qpixmap.cpp:615
void setSerialNumber(int serNo)
friend class QPixmap
static const KeyPair *const end
bool hasXRenderAndAlpha() const
bool canTakeQImageFromXImage(const QXImageWrapper &xi) const
static int appCells(int screen=-1)
Returns the number of cells used by the application on the given screen.
bool hasAlpha() const
Qt::HANDLE hd2
#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
#define GET_PIXEL
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137
Qt::HANDLE x11ConvertToDefaultDepth()
QVector< QRgb > colorTable() const
Returns a list of the colors contained in the image&#39;s color table, or an empty list if the image does...
Definition: qimage.cpp:1770
QRgb color(int i) const
Returns the color in the color table at index i.
Definition: qimage.cpp:1829
QRgb rgb() const
Returns the RGB value of the color.
Definition: qcolor.cpp:1051
static Display * display()
Returns the default display for the application.
uchar * scanLine(int)
Returns a pointer to the pixel data at the scanline with index i.
Definition: qimage.cpp:1886
qreal m11() const
Returns the horizontal scaling factor.
Definition: qtransform.h:237
static void cleanup_scale_tables()
int screen() const
Returns the number of the screen currently in use.
bool defaultVisual
Definition: qt_x11_p.h:320
The QTransform class specifies 2D transformations of a coordinate system.
Definition: qtransform.h:65
QX11PixmapData(PixelType type)
static int appDpiY(int screen=-1)
Returns the vertical resolution of the given screen in terms of the number of dots per inch...