Qt 4.8
qxlibwindowsurface.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the plugins of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qxlibwindowsurface.h"
43 #include "qxlibintegration.h"
44 
45 #include <QtCore/qdebug.h>
46 #include <QWindowSystemInterface>
47 
48 #include "qxlibwindow.h"
49 #include "qxlibscreen.h"
50 #include "qxlibdisplay.h"
51 
52 #include "qpainter.h"
53 
54 # include <sys/ipc.h>
55 # include <sys/shm.h>
56 # include <X11/extensions/XShm.h>
57 
59 
60 
62  QXlibShmImageInfo(Display *xdisplay) : image(0), display(xdisplay) {}
64 
65  void destroy();
66 
67  XShmSegmentInfo shminfo;
68  XImage *image;
70 };
71 
72 
73 #ifndef DONT_USE_MIT_SHM
75 {
76  XShmDetach (display, &shminfo);
77  XDestroyImage (image);
78  shmdt (shminfo.shmaddr);
79  shmctl (shminfo.shmid, IPC_RMID, 0);
80 }
81 #endif
82 
83 void QXlibWindowSurface::resizeShmImage(int width, int height)
84 {
86  QXlibWindow *win = static_cast<QXlibWindow*>(window()->platformWindow());
87 
88 #ifdef DONT_USE_MIT_SHM
89  shm_img = QImage(width, height, win->format());
90 #else
91 
92  if (image_info)
93  image_info->destroy();
94  else
95  image_info = new QXlibShmImageInfo(screen->display()->nativeDisplay());
96 
97  XImage *image = XShmCreateImage (screen->display()->nativeDisplay(), win->visual(), win->depth(), ZPixmap, 0,
98  &image_info->shminfo, width, height);
99 
100 
101  image_info->shminfo.shmid = shmget (IPC_PRIVATE,
102  image->bytes_per_line * image->height, IPC_CREAT|0700);
103 
104  image_info->shminfo.shmaddr = image->data = (char*)shmat (image_info->shminfo.shmid, 0, 0);
105  image_info->shminfo.readOnly = False;
106 
107  image_info->image = image;
108 
109  Status shm_attach_status = XShmAttach(screen->display()->nativeDisplay(), &image_info->shminfo);
110 
111  Q_ASSERT(shm_attach_status == True);
112 
113  shm_img = QImage( (uchar*) image->data, image->width, image->height, image->bytes_per_line, win->format() );
114 #endif
115  painted = false;
116 }
117 
118 
120 {
121  if (shm_img.size() != s)
122  resizeShmImage(s.width(), s.height());
123 }
124 
126 {
127  return shm_img.size();
128 }
129 
131  : QWindowSurface(window),
132  painted(false), image_info(0)
133 {
134  xw = static_cast<QXlibWindow*>(window->platformWindow());
135 // qDebug() << "QTestLiteWindowSurface::QTestLiteWindowSurface:" << xw->window;
136 }
137 
139 {
140  delete image_info;
141 }
142 
144 {
145  return &shm_img;
146 }
147 
148 
150 {
151  Q_UNUSED(widget);
152  Q_UNUSED(region);
153  Q_UNUSED(offset);
154 
155  if (!painted)
156  return;
157 
159  GC gc = xw->graphicsContext();
160  Window window = xw->xWindow();
161 #ifdef DONT_USE_MIT_SHM
162  // just convert the image every time...
163  if (!shm_img.isNull()) {
164  QXlibWindow *win = static_cast<QXlibWindow*>(window()->platformWindow());
165 
166  QImage image = shm_img;
167  //img.convertToFormat(
168  XImage *xi = XCreateImage(screen->display(), win->visual(), win->depth(), ZPixmap,
169  0, (char *) image.scanLine(0), image.width(), image.height(),
170  32, image.bytesPerLine());
171 
172  int x = 0;
173  int y = 0;
174 
175  /*int r =*/ XPutImage(screen->display(), window, gc, xi, 0, 0, x, y, image.width(), image.height());
176 
177  xi->data = 0; // QImage owns these bits
178  XDestroyImage(xi);
179  }
180 #else
181  // Use MIT_SHM
182  if (image_info && image_info->image) {
183  //qDebug() << "Here we go" << image_info->image->width << image_info->image->height;
184  int x = 0;
185  int y = 0;
186 
187  // We could set send_event to true, and then use the ShmCompletion to synchronize,
188  // but let's do like Qt/11 and just use XSync
189  XShmPutImage (screen->display()->nativeDisplay(), window, gc, image_info->image, 0, 0,
190  x, y, image_info->image->width, image_info->image->height,
191  /*send_event*/ False);
192 
193  screen->display()->sync();
194  }
195 #endif
196 }
197 
198 // from qwindowsurface.cpp
199 extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset);
200 
201 bool QXlibWindowSurface::scroll(const QRegion &area, int dx, int dy)
202 {
203  if (shm_img.isNull())
204  return false;
205 
206  const QVector<QRect> rects = area.rects();
207  for (int i = 0; i < rects.size(); ++i)
208  qt_scrollRectInImage(shm_img, rects.at(i), QPoint(dx, dy));
209 
210  return true;
211 }
212 
213 
215 {
216  Q_UNUSED(region);
217  resizeBuffer(size());
218 
219  if (shm_img.hasAlphaChannel()) {
220  QPainter p(&shm_img);
222  const QVector<QRect> rects = region.rects();
223  const QColor blank = Qt::transparent;
224  for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) {
225  p.fillRect(*it, blank);
226  }
227  }
228 }
229 
231 {
232  Q_UNUSED(region);
233  painted = true; //there is content in the buffer
234 }
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
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
void resizeShmImage(int width, int height)
QPointer< QWidget > widget
uint depth() const
Definition: qxlibwindow.h:125
QRect rect(const QWidget *widget) const
Returns the rectangle for widget in the coordinates of this window surface.
#define it(className, varName)
Window xWindow() const
void endPaint(const QRegion &region)
This function is called after painting onto the surface has ended, with the region in which the paint...
bool isNull() const
Returns true if it is a null image, otherwise returns false.
Definition: qimage.cpp:1542
Display * nativeDisplay() const
QXlibWindowSurface(QWidget *window)
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
virtual QPoint offset(const QWidget *widget) const
Returns the offset of widget in the coordinates of this window surface.
bool hasAlphaChannel() const
Returns true if the image has a format that respects the alpha channel, otherwise returns false...
Definition: qimage.cpp:6495
Visual * visual() const
Definition: qxlibwindow.h:127
int bytesPerLine() const
Returns the number of bytes per image scanline.
Definition: qimage.cpp:1812
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the vector...
Definition: qvector.h:250
XShmSegmentInfo shminfo
static QXlibScreen * testLiteScreenForWidget(QWidget *widget)
unsigned char uchar
Definition: qglobal.h:994
NSWindow * window
int width() const
Returns the width.
Definition: qsize.h:126
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
void beginPaint(const QRegion &region)
This function is called before painting onto the surface begins, with the region in which the paintin...
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
QXlibShmImageInfo(Display *xdisplay)
The QRegion class specifies a clip region for a painter.
Definition: qregion.h:68
QXlibShmImageInfo * image_info
void flush(QWidget *widget, const QRegion &region, const QPoint &offset)
Flushes the given region from the specified widget onto the screen.
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
GC graphicsContext() const
struct _XDisplay Display
Definition: qwindowdefs.h:115
int width() const
Returns the width of the image.
Definition: qimage.cpp:1557
void setCompositionMode(CompositionMode mode)
Sets the composition mode to the given mode.
Definition: qpainter.cpp:2422
iterator begin()
Returns an STL-style iterator pointing to the first item in the vector.
Definition: qvector.h:247
QPaintDevice * paintDevice()
Implement this function to return the appropriate paint device.
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
QVector< QRect > rects() const
Returns an array of non-overlapping rectangles that make up the region.
Definition: qregion.cpp:4412
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
int height() const
Returns the height of the image.
Definition: qimage.cpp:1572
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...
struct _XGC * GC
Definition: qwindowdefs.h:117
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
QImage::Format format() const
Definition: qxlibwindow.h:126
QXlibDisplay * display() const
#define Status
Definition: qcursor_x11.cpp:59
#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
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137
void sync() const
QWidget * window() const
Returns a pointer to the top-level window associated with this surface.
uchar * scanLine(int)
Returns a pointer to the pixel data at the scanline with index i.
Definition: qimage.cpp:1886
void fillRect(const QRectF &, const QBrush &)
Fills the given rectangle with the brush specified.
Definition: qpainter.cpp:7420
static int area(const QSize &s)
Definition: qicon.cpp:155
void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset)