Qt 4.8
qwindowsurface_qws.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 #include "qwindowsurface_qws_p.h"
43 #include <qwidget.h>
44 #include <qscreen_qws.h>
45 #include <qwsmanager_qws.h>
46 #include <qapplication.h>
47 #include <qwsdisplay_qws.h>
48 #include <qrgb.h>
49 #include <qpaintengine.h>
50 #include <qdesktopwidget.h>
51 #include <private/qapplication_p.h>
52 #include <private/qwsdisplay_qws_p.h>
53 #include <private/qwidget_p.h>
54 #include <private/qwsmanager_p.h>
55 #include <private/qwslock_p.h>
56 #include <private/qbackingstore_p.h>
57 #include <stdio.h>
58 
60 
61 #ifdef Q_BACKINGSTORE_SUBSURFACES
62 
63 typedef QMap<int, QWSWindowSurface*> SurfaceMap;
64 Q_GLOBAL_STATIC(SurfaceMap, winIdToSurfaceMap);
65 
66 QWSWindowSurface* qt_findWindowSurface(int winId)
67 {
68  return winIdToSurfaceMap()->value(winId);
69 }
70 
71 static void qt_insertWindowSurface(int winId, QWSWindowSurface *surface)
72 {
73  if (!surface)
74  winIdToSurfaceMap()->remove(winId);
75  else
76  winIdToSurfaceMap()->insert(winId, surface);
77 }
78 
79 #endif // Q_BACKINGSTORE_SUBSURFACES
80 
81 inline bool isWidgetOpaque(const QWidget *w)
82 {
83  return w->d_func()->isOpaque && !w->testAttribute(Qt::WA_TranslucentBackground);
84 }
85 
86 static inline QScreen *getScreen(const QWidget *w)
87 {
88  const QList<QScreen*> subScreens = qt_screen->subScreens();
89  if (subScreens.isEmpty())
90  return qt_screen;
91 
92  const int screen = QApplication::desktop()->screenNumber(w);
93 
94  return qt_screen->subScreens().at(screen < 0 ? 0 : screen);
95 }
96 
98 {
99  switch (format) {
101  return 0;
102 #ifndef QT_NO_DEBUG
103  case QImage::Format_Mono:
105  qFatal("QWSWindowSurface: Invalid backingstore format: %i",
106  int(format));
107 #endif
109  return 1;
113  return 4;
118  return 2;
124  return 3;
125  default:
126 #ifndef QT_NO_DEBUG
127  qFatal("QWSWindowSurface: Invalid backingstore format: %i",
128  int(format));
129 #endif
130  return 0;
131  }
132 }
133 
134 static inline int nextMulOf4(int n)
135 {
136  return ((n + 3) & 0xfffffffc);
137 }
138 
139 static inline void setImageMetrics(QImage &img, QWidget *window) {
140  QScreen *myScreen = getScreen(window);
141  if (myScreen) {
142  int dpmx = myScreen->width()*1000 / myScreen->physicalWidth();
143  int dpmy = myScreen->height()*1000 / myScreen->physicalHeight();
144  img.setDotsPerMeterX(dpmx);
145  img.setDotsPerMeterY(dpmy);
146  }
147 }
148 
150 {
151 
152  QWidget *win = window();
153  if (win) {
154  win->d_func()->invalidateBuffer(win->rect());
155 #ifndef QT_NO_QWS_MANAGER
156  QTLWExtra *topextra = win->d_func()->extra->topextra;
157  QWSManager *manager = topextra->qwsManager;
158  if (manager)
159  manager->d_func()->dirtyRegion(QDecoration::All,
161 #endif
162  }
163 }
164 
166  : flags(0),
167 #ifdef QT_QWS_CLIENTBLIT
168  directId(-1),
169 #endif
170  winId(0)
171 {
172 }
173 
175 {
176  winId = id;
177 }
178 
180 {
181  // XXX: the widget winId may change during the lifetime of the widget!!!
182 
183  const QWidget *win = window();
184  if (win && win->isWindow())
185  return win->internalWinId();
186 
187 #ifdef Q_BACKINGSTORE_SUBSURFACES
188  if (!d_ptr->winId) {
189  QWSWindowSurface *that = const_cast<QWSWindowSurface*>(this);
191  const int id = display->takeId();
192  qt_insertWindowSurface(id, that);
193  that->d_ptr->winId = id;
194 
195  if (win)
196  display->nameRegion(id, win->objectName(), win->windowTitle());
197  else
198  display->nameRegion(id, QString(), QString());
199 
200  display->setAltitude(id, 1, true); // XXX
201  }
202 #endif
203 
204  return d_ptr->winId;
205 }
206 
208 {
209  d_ptr->winId = id;
210 }
211 
437  : QWindowSurface(0), d_ptr(new QWSWindowSurfacePrivate)
438 {
439 }
440 
446 {
447 }
448 
450 {
451 #ifdef Q_BACKINGSTORE_SUBSURFACES
452  if (d_ptr->winId)
453  winIdToSurfaceMap()->remove(d_ptr->winId);
454 #endif
455 
456  delete d_ptr;
457 }
458 
465 {
466  const QWidget *w = window();
467  if (!w)
468  return QPoint();
469  return w->geometry().topLeft() - w->frameGeometry().topLeft();
470 }
471 
473 {
474  lock();
475 }
476 
478 {
479  unlock();
480 }
481 
482 // XXX: documentation!!!
484 {
485  return QByteArray();
486 }
487 
489 {
490  return QByteArray();
491 }
492 
494 {
495  Q_UNUSED(state);
496 }
497 
499 {
500  Q_UNUSED(state);
501 }
502 
503 bool QWSWindowSurface::lock(int timeout)
504 {
505  Q_UNUSED(timeout);
506  return true;
507 }
508 
510 {
511 }
512 
513 #ifdef QT_QWS_CLIENTBLIT
514 
515 const QRegion QWSWindowSurface::directRegion() const
516 {
517  return d_ptr->direct;
518 }
519 
521 int QWSWindowSurface::directRegionId() const
522 {
523  return d_ptr->directId;
524 }
525 
527 void QWSWindowSurface::setDirectRegion(const QRegion &r, int id)
528 {
529  d_ptr->direct = r;
530  d_ptr->directId = id;
531 }
532 #endif
533 
540 {
541  return d_ptr->clip;
542 }
543 
551 {
552  if (clip == d_ptr->clip)
553  return;
554 
555  QRegion expose = (clip - d_ptr->clip);
556  d_ptr->clip = clip;
557 
558  if (expose.isEmpty() || clip.isEmpty())
559  return; // No repaint or flush required.
560 
561  QWidget *win = window();
562  if (!win)
563  return;
564 
565  if (isBuffered()) {
566  // No repaint required. Flush exposed area via the backing store.
567  win->d_func()->syncBackingStore(expose);
568  return;
569  }
570 
571 #ifndef QT_NO_QWS_MANAGER
572  // Invalidate exposed decoration area.
573  if (win && win->isWindow()) {
574  QTLWExtra *topextra = win->d_func()->extra->topextra;
575  if (QWSManager *manager = topextra->qwsManager) {
576  QRegion decorationExpose(manager->region());
577  decorationExpose.translate(-win->geometry().topLeft());
578  decorationExpose &= expose;
579  if (!decorationExpose.isEmpty()) {
580  expose -= decorationExpose;
581  manager->d_func()->dirtyRegion(QDecoration::All, QDecoration::Normal, decorationExpose);
582  }
583  }
584  }
585 #endif
586 
587  // Invalidate exposed widget area.
588  win->d_func()->invalidateBuffer(expose);
589 }
590 
596 QWSWindowSurface::SurfaceFlags QWSWindowSurface::surfaceFlags() const
597 {
598  return d_ptr->flags;
599 }
600 
607 void QWSWindowSurface::setSurfaceFlags(SurfaceFlags flags)
608 {
609  d_ptr->flags = flags;
610 }
611 
613 {
614  QRegion mask = rect;
615 
616  const QWidget *win = window();
617  if (win) {
618 #ifndef QT_NO_QWS_MANAGER
619  if (win->isWindow()) {
620  QTLWExtra *topextra = win->d_func()->extra->topextra;
621  QWSManager *manager = topextra->qwsManager;
622 
623  if (manager) {
624  // The frame geometry is the bounding rect of manager->region,
625  // which could be too much, so we need to clip.
626  mask &= (manager->region() + win->geometry());
627  }
628  }
629 #endif
630 
631  const QRegion winMask = win->mask();
632  if (!winMask.isEmpty())
633  mask &= winMask.translated(win->geometry().topLeft());
634  }
635 
636  setGeometry(rect, mask);
637 }
638 
640 {
641  if (rect == geometry()) // XXX: && mask == prevMask
642  return;
643 
644  const bool isResize = rect.size() != geometry().size();
645  const bool needsRepaint = isResize || !isBuffered();
646 
648 
649  const QRegion region = mask & rect;
650  QWidget *win = window();
651  // Only request regions for widgets visible on the screen.
652  // (Added the !win check for compatibility reasons, because
653  // there was no "if (win)" check before).
654  const bool requestQWSRegion = !win || !win->testAttribute(Qt::WA_DontShowOnScreen);
655  if (requestQWSRegion)
657 
658  if (needsRepaint)
660 
661  if (!requestQWSRegion) {
662  // We didn't request a region, hence we won't get a QWSRegionEvent::Allocation
663  // event back from the server so we set the clip directly. We have to
664  // do this after the invalidateBuffer() call above, as it might trigger a
665  // backing store sync, resulting in too many update requests.
666  setClipRegion(region);
667  }
668 }
669 
670 static inline void flushUpdate(QWidget *widget, const QRegion &region,
671  const QPoint &offset)
672 {
673 #ifdef QT_NO_PAINT_DEBUG
674  Q_UNUSED(widget);
675  Q_UNUSED(region);
676  Q_UNUSED(offset);
677 #else
678  static int delay = -1;
679 
680  if (delay == -1)
681  delay = qgetenv("QT_FLUSH_UPDATE").toInt() * 10;
682 
683  if (delay == 0)
684  return;
685 
686  static QWSYellowSurface surface(true);
687  surface.setDelay(delay);
688  surface.flush(widget, region, offset);
689 #endif // QT_NO_PAINT_DEBUG
690 }
691 
693  const QPoint &offset)
694 {
695  const QWidget *win = window();
696  if (!win)
697  return;
698 
699 #ifndef QT_NO_GRAPHICSVIEW
700  QWExtra *extra = win->d_func()->extra;
701  if (extra && extra->proxyWidget)
702  return;
703 #endif //QT_NO_GRAPHICSVIEW
704 
705  Q_UNUSED(offset);
706 
707  const bool opaque = isOpaque();
708 #ifdef QT_QWS_DISABLE_FLUSHCLIPPING
709  QRegion toFlush = region;
710 #else
711  QRegion toFlush = region & d_ptr->clip;
712 #endif
713 
714  if (!toFlush.isEmpty()) {
715  flushUpdate(widget, toFlush, QPoint(0, 0));
716  QPoint globalZero = win->mapToGlobal(QPoint(0, 0));
717  toFlush.translate(globalZero);
718 
719 #ifdef QT_QWS_CLIENTBLIT
720  bool needRepaint = true;
721  if (opaque) {
722  QScreen* widgetScreen = getScreen(widget);
723  if (widgetScreen->supportsBlitInClients()) {
724 
726  if(directRegion().intersected(toFlush) == toFlush) {
727  QPoint translate = -globalZero + painterOffset() + geometry().topLeft();
728  QRegion flushRegion = toFlush.translated(translate);
729  widgetScreen->blit(image(), geometry().topLeft(), flushRegion);
730  widgetScreen->setDirty(toFlush.boundingRect());
731  needRepaint = false;
732  }
734  }
735  }
736 
737  if(needRepaint)
738 #endif
739  win->qwsDisplay()->repaintRegion(winId(), win->windowFlags(), opaque, toFlush);
740  }
741 }
742 
758 {
759  QWindowSurface::setGeometry(geometry().translated(offset));
760  return isBuffered();
761 }
762 
779 {
780  const QRegion oldGeometry = geometry();
781  QWindowSurface::setGeometry(geometry().translated(offset));
782  return oldGeometry + newClip;
783 }
784 
786 {
787 }
788 
789 bool QWSMemorySurface::lock(int timeout)
790 {
791  Q_UNUSED(timeout);
792 #ifndef QT_NO_QWS_MULTIPROCESS
793  if (memlock && !memlock->lock(QWSLock::BackingStore))
794  return false;
795 #endif
796 #ifndef QT_NO_THREAD
797  threadLock.lock();
798 #endif
799  return true;
800 }
801 
803 {
804 #ifndef QT_NO_THREAD
805  threadLock.unlock();
806 #endif
807 #ifndef QT_NO_QWS_MULTIPROCESS
808  if (memlock)
809  memlock->unlock(QWSLock::BackingStore);
810 #endif
811 }
812 
814  : QWSWindowSurface()
816  , memlock(0)
817 #endif
818 {
820 }
821 
823  : QWSWindowSurface(w)
824 {
825  SurfaceFlags flags = Buffered;
826  if (isWidgetOpaque(w))
827  flags |= Opaque;
828  setSurfaceFlags(flags);
829 
830 #ifndef QT_NO_QWS_MULTIPROCESS
832 #endif
833 }
834 
836 {
837 #ifndef QT_NO_QWS_MULTIPROCESS
839  delete memlock;
840 #endif
841 }
842 
843 
846 {
847  QScreen *screen = getScreen(widget);
848  const int depth = screen->depth();
849  const bool opaque = isWidgetOpaque(widget);
850 
851  if (!opaque) {
852  if (depth <= 12)
854  else if (depth <= 15)
856  else if (depth <= 16)
858  else if (depth <= 18)
860  else
862  }
863 
864  QImage::Format format = screen->pixelFormat();
865  if (format > QImage::Format_Indexed8) // ### assumes all new image formats supports a QPainter
866  return format;
867 
868  if (depth <= 12)
869  return QImage::Format_RGB444;
870  else if (depth <= 15)
871  return QImage::Format_RGB555;
872  else if (depth <= 16)
873  return QImage::Format_RGB16;
874  else if (depth <= 18)
875  return QImage::Format_RGB666;
876  else if (depth <= 24)
877  return QImage::Format_RGB888;
878  else
880 }
881 
882 #ifndef QT_NO_QWS_MULTIPROCESS
884 {
885  if (memlock && memlock->id() == lockId)
886  return;
888  delete memlock;
889  memlock = (lockId == -1 ? 0 : new QWSLock(lockId));
890 }
891 #endif // QT_NO_QWS_MULTIPROCESS
892 
894 {
895  if (img.isNull())
896  return true;
897 
898  const QWidget *win = window();
899  if (preferredImageFormat(win) != img.format())
900  return false;
901 
902  if (isOpaque() != isWidgetOpaque(win)) // XXX: use QWidgetPrivate::isOpaque()
903  return false;
904 
905  return true;
906 }
907 
908 // ### copied from qwindowsurface_raster.cpp -- should be cross-platform
910 {
911  if (!isWidgetOpaque(window())) {
912  QPainter p(&img);
914  const QVector<QRect> rects = rgn.rects();
915  const QColor blank = Qt::transparent;
916  for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) {
917  QRect r = *it;
918 #ifdef Q_BACKINGSTORE_SUBSURFACES
920 #endif
921  p.fillRect(r, blank);
922  }
923  }
925 }
926 
927 // from qwindowsurface.cpp
928 extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset);
929 
930 bool QWSMemorySurface::scroll(const QRegion &area, int dx, int dy)
931 {
932  const QVector<QRect> rects = area.rects();
933  for (int i = 0; i < rects.size(); ++i)
934  qt_scrollRectInImage(img, rects.at(i), QPoint(dx, dy));
935 
936  return true;
937 }
938 
940 {
941  const QWidget *w = window();
942  if (!w)
943  return QPoint();
944 
945  if (w->mask().isEmpty())
947 
948  const QRegion region = w->mask()
949  & w->frameGeometry().translated(-w->geometry().topLeft());
950  return -region.boundingRect().topLeft();
951 }
952 
954  : QWSMemorySurface(), mem(0), memsize(0)
955 {
956 }
957 
959  : QWSMemorySurface(w), mem(0), memsize(0)
960 {
961 }
962 
964 {
965  if (memsize)
966  delete[] mem;
967 }
968 
970 {
971  QSize size = rect.size();
972 
973  QWidget *win = window();
974  if (win && !win->mask().isEmpty()) {
975  const QRegion region = win->mask()
976  & rect.translated(-win->geometry().topLeft());
977  size = region.boundingRect().size();
978  }
979 
980  uchar *deleteLater = 0;
981 
982  if (img.size() != size) {
983  if (size.isEmpty()) {
984  if (memsize) {
985  // In case of a Hide event we need to delete the memory after sending the
986  // event to the server in order to let the server animate the event.
987  deleteLater = mem;
988  memsize = 0;
989  }
990  mem = 0;
991  img = QImage();
992  } else {
994  const int bpl = nextMulOf4(bytesPerPixel(format) * size.width());
995  const int imagesize = bpl * size.height();
996  if (memsize < imagesize) {
997  delete[] mem;
998  memsize = imagesize;
999  mem = new uchar[memsize];
1000  }
1001  img = QImage(mem, size.width(), size.height(), bpl, format);
1002  setImageMetrics(img, win);
1003  }
1004  }
1005 
1007 
1008  delete[] deleteLater;
1009 }
1010 
1012 {
1013  QByteArray array(sizeof(uchar*) + 3 * sizeof(int) + sizeof(SurfaceFlags), Qt::Uninitialized);
1014 
1015  char *ptr = array.data();
1016 
1017  *reinterpret_cast<uchar**>(ptr) = mem;
1018  ptr += sizeof(uchar*);
1019 
1020  reinterpret_cast<int*>(ptr)[0] = img.width();
1021  reinterpret_cast<int*>(ptr)[1] = img.height();
1022  ptr += 2 * sizeof(int);
1023 
1024  *reinterpret_cast<int *>(ptr) = img.format();
1025  ptr += sizeof(int);
1026 
1027  *reinterpret_cast<SurfaceFlags*>(ptr) = surfaceFlags();
1028 
1029  return array;
1030 }
1031 
1033 {
1034  if (memsize) {
1035  delete[] mem;
1036  memsize = 0;
1037  }
1038 
1039  int width;
1040  int height;
1042  SurfaceFlags flags;
1043 
1044  const char *ptr = data.constData();
1045 
1046  mem = *reinterpret_cast<uchar* const*>(ptr);
1047  ptr += sizeof(uchar*);
1048 
1049  width = reinterpret_cast<const int*>(ptr)[0];
1050  height = reinterpret_cast<const int*>(ptr)[1];
1051  ptr += 2 * sizeof(int);
1052 
1053  format = QImage::Format(*reinterpret_cast<const int*>(ptr));
1054  ptr += sizeof(int);
1055 
1056  flags = *reinterpret_cast<const SurfaceFlags*>(ptr);
1057 
1058  const int bpl = nextMulOf4(bytesPerPixel(format) * width);
1059  QWSMemorySurface::img = QImage(mem, width, height, bpl, format);
1060  setSurfaceFlags(flags);
1061 }
1062 
1064 {
1065  if (memsize) {
1066  delete[] mem;
1067  memsize = 0;
1068  }
1069  mem = 0;
1070  img = QImage();
1071 }
1072 
1073 #ifndef QT_NO_QWS_MULTIPROCESS
1074 
1076  : QWSMemorySurface()
1077 {
1078 }
1079 
1081  : QWSMemorySurface(widget)
1082 {
1083 }
1084 
1086 {
1087  // mem.detach() is done automatically by ~QSharedMemory
1088 }
1089 
1091 {
1092  if (mem.id() == memId)
1093  return true;
1094 
1095  mem.detach();
1096 
1097  if (memId != -1 && !mem.attach(memId)) {
1098 #ifndef QT_NO_DEBUG
1099  perror("QWSSharedMemSurface: attaching to shared memory");
1100  qCritical("QWSSharedMemSurface: Error attaching to shared memory 0x%x", memId);
1101 #endif
1102  return false;
1103  }
1104 
1105  return true;
1106 }
1107 
1108 #ifdef QT_QWS_CLIENTBLIT
1109 void QWSSharedMemSurface::setDirectRegion(const QRegion &r, int id)
1110 {
1111  QWSMemorySurface::setDirectRegion(r, id);
1112  if (mem.address())
1113  *(uint *)mem.address() = id;
1114 }
1115 
1116 const QRegion QWSSharedMemSurface::directRegion() const
1117 {
1118  if (mem.address() && *(uint *)mem.address() == uint(directRegionId()))
1119  return QWSMemorySurface::directRegion();
1120  return QRegion();
1121 }
1122 #endif
1123 
1125 {
1126  int memId;
1127  int width;
1128  int height;
1129  int lockId;
1131  SurfaceFlags flags;
1132 
1133  const int *ptr = reinterpret_cast<const int*>(data.constData());
1134 
1135  memId = ptr[0];
1136  width = ptr[1];
1137  height = ptr[2];
1138  lockId = ptr[3];
1139  format = QImage::Format(ptr[4]);
1140  flags = SurfaceFlags(ptr[5]);
1141 
1142  setSurfaceFlags(flags);
1143  setMemory(memId);
1144  setLock(lockId);
1145 
1146 #ifdef QT_QWS_CLIENTBLIT
1147  uchar *base = static_cast<uchar*>(mem.address()) + sizeof(uint);
1148 #else
1149  uchar *base = static_cast<uchar*>(mem.address());
1150 #endif
1151  const int bpl = nextMulOf4(bytesPerPixel(format) * width);
1152  QWSMemorySurface::img = QImage(base, width, height, bpl, format);
1153 }
1154 
1156 {
1157  const QSize size = rect.size();
1158  if (img.size() != size) {
1159  if (size.isEmpty()) {
1160  mem.detach();
1161  img = QImage();
1162  } else {
1163  QWidget *win = window();
1165  const int bpl = nextMulOf4(bytesPerPixel(format) * size.width());
1166 #ifdef QT_QWS_CLIENTBLIT
1167  const int imagesize = bpl * size.height() + sizeof(uint);
1168 #else
1169  const int imagesize = bpl * size.height();
1170 #endif
1171  if (mem.size() < imagesize) {
1172  mem.detach();
1173  if (!mem.create(imagesize)) {
1174  perror("QWSSharedMemSurface::setGeometry allocating shared memory");
1175  qFatal("Error creating shared memory of size %d", imagesize);
1176  }
1177  }
1178 #ifdef QT_QWS_CLIENTBLIT
1179  *((uint *)mem.address()) = 0;
1180  uchar *base = static_cast<uchar*>(mem.address()) + sizeof(uint);
1181 #else
1182  uchar *base = static_cast<uchar*>(mem.address());
1183 #endif
1184  img = QImage(base, size.width(), size.height(), bpl, format);
1185  setImageMetrics(img, win);
1186  }
1187  }
1188 
1190 }
1191 
1193 {
1194  QByteArray array(6 * sizeof(int), Qt::Uninitialized);
1195 
1196  int *ptr = reinterpret_cast<int*>(array.data());
1197 
1198  ptr[0] = mem.id();
1199  ptr[1] = img.width();
1200  ptr[2] = img.height();
1201  ptr[3] = (memlock ? memlock->id() : -1);
1202  ptr[4] = int(img.format());
1203  ptr[5] = int(surfaceFlags());
1204 
1205  return array;
1206 }
1207 
1209 {
1210  mem.detach();
1211  img = QImage();
1212 }
1213 
1214 #endif // QT_NO_QWS_MULTIPROCESS
1215 
1216 #ifndef QT_NO_PAINTONSCREEN
1217 
1219  : QWSMemorySurface(w)
1220 {
1223 }
1224 
1226  : QWSMemorySurface()
1227 {
1229 }
1230 
1232 {
1233  screen = s;
1234  uchar *base = screen->base();
1236 
1237  if (format == QImage::Format_Invalid || format == QImage::Format_Indexed8) {
1238  //### currently we have no paint engine for indexed image formats
1239  qFatal("QWSOnScreenSurface::attachToScreen(): screen depth %d "
1240  "not implemented", screen->depth());
1241  return;
1242  }
1244  screen->linestep(), format );
1245 }
1246 
1248 {
1249 }
1250 
1252 {
1254 }
1255 
1257 {
1258  const QWidget *win = window();
1259  if (screen != getScreen(win))
1260  return false;
1261  if (img.isNull())
1262  return false;
1263  return QScreen::isWidgetPaintOnScreen(win);
1264 }
1265 
1267 {
1268  QByteArray array(sizeof(int), Qt::Uninitialized);
1269 
1270  int *ptr = reinterpret_cast<int*>(array.data());
1271  ptr[0] = QApplication::desktop()->screenNumber(window());
1272  return array;
1273 }
1274 
1276 {
1277  const int *ptr = reinterpret_cast<const int*>(data.constData());
1278  const int screenNo = ptr[0];
1279 
1281  if (screenNo > 0)
1282  screen = qt_screen->subScreens().at(screenNo);
1283  attachToScreen(screen);
1284 }
1285 
1286 #endif // QT_NO_PAINTONSCREEN
1287 
1288 #ifndef QT_NO_PAINT_DEBUG
1289 
1291  : QWSWindowSurface(), delay(10)
1292 {
1293  if (isClient) {
1294  setWinId(QWidget::qwsDisplay()->takeId());
1296  QLatin1String("Debug flush paint"),
1297  QLatin1String("Silly yellow thing"));
1298  QWidget::qwsDisplay()->setAltitude(winId(), 1, true);
1299  }
1301 }
1302 
1304 {
1305 }
1306 
1308 {
1309  QByteArray array(2 * sizeof(int), Qt::Uninitialized);
1310 
1311  int *ptr = reinterpret_cast<int*>(array.data());
1312  ptr[0] = surfaceSize.width();
1313  ptr[1] = surfaceSize.height();
1314 
1315  return array;
1316 }
1317 
1319 {
1320  const int *ptr = reinterpret_cast<const int*>(data.constData());
1321 
1322  const int width = ptr[0];
1323  const int height = ptr[1];
1324 
1325  img = QImage(width, height, QImage::Format_ARGB32);
1326  img.fill(qRgba(255,255,31,127));
1327 }
1328 
1330  const QPoint &offset)
1331 {
1332  Q_UNUSED(offset);
1333 
1335  QRegion rgn = region;
1336 
1337  if (widget)
1338  rgn.translate(widget->mapToGlobal(QPoint(0, 0)));
1339 
1340  surfaceSize = region.boundingRect().size();
1341 
1342  const int id = winId();
1343  display->requestRegion(id, key(), permanentState(), rgn);
1344  display->setAltitude(id, 1, true);
1345  display->repaintRegion(id, 0, false, rgn);
1346 
1347  ::usleep(500 * delay);
1348  display->requestRegion(id, key(), permanentState(), QRegion());
1349  ::usleep(500 * delay);
1350 }
1351 
1352 #endif // QT_NO_PAINT_DEBUG
1353 
1354 #ifndef QT_NO_DIRECTPAINTER
1355 
1356 static inline QScreen *getPrimaryScreen()
1357 {
1358  QScreen *screen = QScreen::instance();
1359  if (!screen->base()) {
1360  QList<QScreen*> subScreens = screen->subScreens();
1361  if (subScreens.size() < 1)
1362  return 0;
1363  screen = subScreens.at(0);
1364  }
1365  return screen;
1366 }
1367 
1370  : QWSWindowSurface(), flushingRegionEvents(false), doLocking(false)
1371 {
1374 
1375  if (isClient) {
1376  setWinId(QWidget::qwsDisplay()->takeId());
1378  QLatin1String("QDirectPainter reserved space"),
1379  QLatin1String("reserved"));
1380  } else {
1381  setWinId(0);
1382  }
1384  if (!_screen->base()) {
1385  QList<QScreen*> subScreens = _screen->subScreens();
1386  if (subScreens.size() < 1)
1387  _screen = 0;
1388  else
1389  _screen = subScreens.at(0);
1390  }
1391 }
1392 
1394 {
1395  if (winId() && QWSDisplay::instance()) // make sure not in QApplication destructor
1397 }
1398 
1400 {
1401  const int id = winId();
1402  QWidget::qwsDisplay()->requestRegion(id, key(), permanentState(), region);
1403 #ifndef QT_NO_QWS_MULTIPROCESS
1404  if (synchronous)
1406 #endif
1407 }
1408 
1410 {
1411  QWSDisplay::instance()->repaintRegion(winId(), 0, true, r);
1412 }
1413 
1415 {
1416  QByteArray res;
1417  if (isRegionReserved())
1418  res.append( 'r');
1419  return res;
1420 }
1421 
1423 {
1424  if (ba.size() > 0 && ba.at(0) == 'r')
1425  setReserved();
1427 }
1428 
1430 {
1432 #ifndef QT_NO_QWS_MULTIPROCESS
1433  if (!synchronous) {
1434  flushingRegionEvents = true;
1436  flushingRegionEvents = false;
1437  }
1438 #endif
1439 }
1440 
1442 {
1443 #ifndef QT_NO_QWS_MULTIPROCESS
1444  if (synchronous)
1445  return false;
1446 
1448 #else
1449  return false;
1450 #endif
1451 }
1452 
1454 {
1455 #ifndef QT_NO_THREAD
1456  threadLock.lock();
1457 #endif
1458  Q_UNUSED(timeout);
1459  if (doLocking)
1460  QWSDisplay::grab(true);
1461  return true;
1462 }
1463 
1465 {
1466  if (doLocking)
1468 #ifndef QT_NO_THREAD
1469  threadLock.unlock();
1470 #endif
1471 }
1472 
1473 #endif // QT_NO_DIRECTPAINTER
1474 
Q_GUI_EXPORT QScreen * qt_screen
Definition: qscreen_qws.cpp:69
The QPainter class performs low-level painting on widgets and other paint devices.
Definition: qpainter.h:86
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition: qcolor.h:67
void nameRegion(int winId, const QString &n, const QString &c)
QRect geometry() const
Returns the currently allocated area on the screen.
The QWSWindowSurface class provides the drawing area for top-level windows in Qt for Embedded Linux...
The QWSDisplay class provides a display for QWS; it is an internal class.
Format
The following image formats are available in Qt.
Definition: qimage.h:91
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
int height() const
Returns the logical height of the framebuffer in pixels.
Definition: qscreen_qws.h:228
bool isWidgetOpaque(const QWidget *w)
bool create(int size)
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
void lock()
Locks the mutex.
Definition: qmutex.cpp:151
const QRegion clipRegion() const
Returns the region currently visible on the screen.
QPointer< QWidget > widget
void beginPaint(const QRegion &)
This function is called before painting onto the surface begins, with the region in which the paintin...
char * data()
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:429
void setAltitude(int winId, int altitude, bool fixed=false)
int physicalHeight() const
Returns the physical height of the screen in millimeters.
Definition: qscreen_qws.h:291
static QWSDisplay * qwsDisplay()
QWSYellowSurface(bool isClient=false)
QRect rect(const QWidget *widget) const
Returns the rectangle for widget in the coordinates of this window surface.
#define it(className, varName)
void setGeometry(const QRect &rect)
Sets the currently allocated area to be the given rect.
bool isWindow() const
Returns true if the widget is an independent window, otherwise returns false.
Definition: qwidget.h:945
void repaintRegion(int winId, int windowFlags, bool opaque, QRegion)
QByteArray & append(char c)
Appends the character ch to this byte array.
static QScreen * getScreen(const QWidget *w)
bool isNull() const
Returns true if it is a null image, otherwise returns false.
Definition: qimage.cpp:1542
void * address() const
void fill(uint pixel)
Fills the entire image with the given pixelValue.
Definition: qimage.cpp:2032
bool isValid() const
Implement this function to return true if the surface is a valid surface for the given top-level wind...
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
bool hasPendingRegionEvents() const
virtual QByteArray permanentState() const
Implement this function to return the data required for creating a server-side representation of the ...
QString key() const
Implement this function to return a string that uniquely identifies the class of this surface...
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
QRect frameGeometry
geometry of the widget relative to its parent including any window frame
Definition: qwidget.h:159
static int bytesPerPixel(QImage::Format format)
void setPermanentState(const QByteArray &data)
Implement this function to attach a server-side surface instance to the corresponding client side ins...
QRect translated(int dx, int dy) const
Returns a copy of the rectangle that is translated dx along the x axis and dy along the y axis...
Definition: qrect.h:328
virtual void setGeometry(const QRect &rect)
Sets the currently allocated area to be the given rect.
virtual QPoint offset(const QWidget *widget) const
Returns the offset of widget in the coordinates of this window surface.
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
QByteArray permanentState() const
Implement this function to return the data required for creating a server-side representation of the ...
void flush(QWidget *widget, const QRegion &region, const QPoint &offset)
Flushes the given region from the specified widget onto the screen.
virtual void beginPaint(const QRegion &)
This function is called before painting onto the surface begins, with the region in which the paintin...
QRect boundingRect() const
Returns the bounding rectangle of this region.
Definition: qregion.cpp:4363
void setGeometry(const QRect &rect)
Sets the currently allocated area to be the given rect.
void attachToScreen(const QScreen *screen)
bool isBuffered() const
Returns true if the QWSWindowSurface::Buffered is set; otherwise returns false.
void setSurfaceFlags(SurfaceFlags type)
Sets the surface flags describing the contents of this surface, to be the given flags.
static int nextMulOf4(int n)
The QString class provides a Unicode character string.
Definition: qstring.h:83
QWSWindowSurface::SurfaceFlags flags
void setPermanentState(const QByteArray &data)
Implement this function to attach a server-side surface instance to the corresponding client side ins...
virtual bool lock(int timeout=-1)
virtual void setDirty(const QRect &)
Marks the given rectangle as dirty.
static const uint base
Definition: qurl.cpp:268
virtual void setTransientState(const QByteArray &state)
Format format() const
Returns the format of the image.
Definition: qimage.cpp:2305
QWSWindowSurfacePrivate * d_ptr
void destroyRegion(int winId)
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Definition: qlist.h:152
virtual void releaseSurface()
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the vector...
Definition: qvector.h:250
virtual void releaseSurface()
virtual void blit(const QImage &img, const QPoint &topLeft, const QRegion &region)
Copies the given region in the given image to the point specified by topLeft using device coordinates...
QByteArray permanentState() const
Implement this function to return the data required for creating a server-side representation of the ...
bool isValid() const
Implement this function to return true if the surface is a valid surface for the given top-level wind...
void waitForRegionAck(int winId)
QGraphicsProxyWidget * proxyWidget
Definition: qwidget_p.h:251
unsigned char uchar
Definition: qglobal.h:994
int width() const
Returns the logical width of the framebuffer in pixels.
Definition: qscreen_qws.h:227
NSWindow * window
int width() const
Returns the width.
Definition: qsize.h:126
void requestRegion(int winId, const QString &surfacekey, const QByteArray &surfaceData, const QRegion &region)
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
QString key() const
Implement this function to return a string that uniquely identifies the class of this surface...
void setPermanentState(const QByteArray &)
Implement this function to attach a server-side surface instance to the corresponding client side ins...
void setDelay(int msec)
Q_GUI_EXPORT_INLINE QRgb qRgba(int r, int g, int b, int a)
Definition: qrgb.h:72
int linestep() const
Returns the length of each scanline of the framebuffer in bytes.
Definition: qscreen_qws.h:232
Q_GUI_EXPORT EGLDisplay display()
Definition: qegl.cpp:589
void setPermanentState(const QByteArray &data)
Implement this function to attach a server-side surface instance to the corresponding client side ins...
void setRegion(const QRegion &region)
QByteArray permanentState() const
Implement this function to return the data required for creating a server-side representation of the ...
virtual bool move(const QPoint &offset)
Move the surface with the given offset.
bool testAttribute(Qt::WidgetAttribute) const
Returns true if attribute attribute is set on this widget; otherwise returns false.
Definition: qwidget.h:1041
bool scroll(const QRegion &area, int dx, int dy)
Scrolls the given area dx pixels to the right and dy downward; both dx and dy may be negative...
bool isEmpty() const
Returns true if the region is empty; otherwise returns false.
Definition: qregion.cpp:4098
QPoint painterOffset() const
Returns the offset to be used when painting.
#define Q_GLOBAL_STATIC(TYPE, NAME)
Declares a global static variable with the given type and name.
Definition: qglobal.h:1968
QSize size() const
Returns the size of the rectangle.
Definition: qrect.h:309
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
void waitForRegionEvents(int winId, bool ungrabDisplay)
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
QString windowTitle
the window title (caption)
Definition: qwidget.h:198
static QScreen * instance()
Returns a pointer to the application&#39;s QScreen instance.
Definition: qscreen_qws.h:201
The QRegion class specifies a clip region for a painter.
Definition: qregion.h:68
const T * ptr(const T &t)
void setDotsPerMeterY(int)
Sets the number of pixels that fit vertically in a physical meter, to y.
Definition: qimage.cpp:5667
QImage::Format preferredImageFormat(const QWidget *widget) const
static void grab()
static QWSLock * getClientLock()
bool attach(int id)
QByteArray permanentState() const
Implement this function to return the data required for creating a server-side representation of the ...
bool lock(int timeout=-1)
QPoint painterOffset() const
Returns the offset to be used when painting.
void unlock()
Unlocks the mutex.
Definition: qmutex.cpp:296
QRegion mask() const
Returns the mask currently set on a widget.
Definition: qwidget.cpp:10058
The QWindowSurface class provides the drawing area for top-level windows.
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
virtual void endPaint(const QRegion &)
This function is called after painting onto the surface has ended, with the region in which the paint...
QSize size() const
Returns the size of the image, i.
Definition: qimage.cpp:1587
static QDesktopWidget * desktop()
Returns the desktop widget (also called the root window).
SurfaceFlags surfaceFlags() const
Returns the surface flags describing the contents of this surface.
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
uchar * base() const
Returns a pointer to the beginning of the framebuffer.
Definition: qscreen_qws.h:235
Q_CORE_EXPORT void qFatal(const char *,...)
virtual QPoint painterOffset() const
Returns the offset to be used when painting.
int width() const
Returns the width of the image.
Definition: qimage.cpp:1557
virtual QString key() const =0
Implement this function to return a string that uniquely identifies the class of this surface...
static void setImageMetrics(QImage &img, QWidget *window)
QImage::Format pixelFormat() const
Returns the pixel format of the screen, or QImage::Format_Invalid if the pixel format is not a suppor...
void setCompositionMode(CompositionMode mode)
Sets the composition mode to the given mode.
Definition: qpainter.cpp:2422
void setDotsPerMeterX(int)
Sets the number of pixels that fit horizontally in a physical meter, to x.
Definition: qimage.cpp:5645
iterator begin()
Returns an STL-style iterator pointing to the first item in the vector.
Definition: qvector.h:247
QRect rect
the internal geometry of the widget excluding any window frame
Definition: qwidget.h:168
void setClipRegion(const QRegion &)
Sets the region currently visible on the screen to be the given clip region.
bool isOpaque() const
Returns true if the QWSWindowSurface::Opaque is set; otherwise returns false.
int toInt(bool *ok=0, int base=10) const
Returns the byte array converted to an int using base base, which is 10 by default and must be betwee...
void flush(QWidget *, const QRegion &, const QPoint &)
Flushes the given region from the specified widget onto the screen.
virtual QList< QScreen * > subScreens() const
Definition: qscreen_qws.h:283
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
bool isRegionReserved() const
Returns true if the QWSWindowSurface::RegionReserved is set; otherwise returns false.
QVector< QRect > rects() const
Returns an array of non-overlapping rectangles that make up the region.
Definition: qregion.cpp:4412
int size() const
Returns the number of items in the list.
Definition: qlist.h:137
QString objectName() const
int height() const
Returns the height.
Definition: qsize.h:129
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
QByteArray permanentState() const
Implement this function to return the data required for creating a server-side representation of the ...
SurfaceFlag
This enum describes the behavior of the region reserved by this QDirectPainter object.
static QScreen * getPrimaryScreen()
int height() const
Returns the height of the image.
Definition: qimage.cpp:1572
The QScreen class is a base class for screen drivers in Qt for Embedded Linux.
Definition: qscreen_qws.h:191
WId internalWinId() const
Returns the window system identifier of the widget, or 0 if the widget is not created yet...
Definition: qwidget.h:244
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
void setLock(int lockId)
virtual void flush(QWidget *widget, const QRegion &region, const QPoint &offset)
Flushes the given region from the specified widget onto the screen.
void translate(int dx, int dy)
Translates (moves) the region dx along the X axis and dy along the Y axis.
Definition: qregion.cpp:4116
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
int screenNumber(const QWidget *widget=0) const
QRegion translated(int dx, int dy) const
Returns a copy of the region that is translated dx along the x axis and dy along the y axis...
Definition: qregion.cpp:743
virtual void setPermanentState(const QByteArray &state)
Implement this function to attach a server-side surface instance to the corresponding client side ins...
static QWSDisplay * instance()
static void flushUpdate(QWidget *widget, const QRegion &region, const QPoint &offset)
void beginPaint(const QRegion &rgn)
This function is called before painting onto the surface begins, with the region in which the paintin...
Qt::WindowFlags windowFlags() const
Window flags are a combination of a type (e.
Definition: qwidget.h:939
int id() const
Definition: qwslock_p.h:78
static void ungrab()
void setPermanentState(const QByteArray &data)
Implement this function to attach a server-side surface instance to the corresponding client side ins...
bool isEmpty() const
Returns true if either of the width and height is less than or equal to 0; otherwise returns false...
Definition: qsize.h:120
void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset)
#define QT_NO_QWS_MULTIPROCESS
char at(int i) const
Returns the character at index position i in the byte array.
Definition: qbytearray.h:413
void translate(int dx, int dy)
Moves the rectangle dx along the x axis and dy along the y axis, relative to the current position...
Definition: qrect.h:312
static bool isWidgetPaintOnScreen(const QWidget *w)
virtual QImage image() const =0
Implement this function to return an image of the top-level window.
int physicalWidth() const
Returns the physical width of the screen in millimeters.
Definition: qscreen_qws.h:290
#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
QWSDirectPainterSurface(bool isClient=false, QDirectPainter::SurfaceFlag flags=QDirectPainter::NonReserved)
QRect geometry
the geometry of the widget relative to its parent and excluding the window frame
Definition: qwidget.h:158
QWSWindowSurface()
Constructs an empty surface.
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137
QPoint mapToGlobal(const QPoint &) const
Translates the widget coordinate pos to global screen coordinates.
QWidget * window() const
Returns a pointer to the top-level window associated with this surface.
virtual void setGeometry(const QRect &rect)
Sets the currently allocated area to be the given rect.
The QMap class is a template class that provides a skip-list-based dictionary.
Definition: qdatastream.h:67
Q_CORE_EXPORT void qCritical(const char *,...)
void fillRect(const QRectF &, const QBrush &)
Fills the given rectangle with the brush specified.
Definition: qpainter.cpp:7420
int depth() const
Returns the depth of the framebuffer, in bits per pixel.
Definition: qscreen_qws.h:229
The QList class is a template class that provides lists.
Definition: qdatastream.h:62
static int area(const QSize &s)
Definition: qicon.cpp:155
QPoint topLeft() const
Returns the position of the rectangle&#39;s top-left corner.
Definition: qrect.h:288
virtual QByteArray transientState() const