3#include <QLoggingCategory>
4#include "DisplayXLib.h"
7#include <X11/extensions/Xfixes.h>
18Q_DECLARE_LOGGING_CATEGORY(LogScreen)
20CDisplayXLib::CDisplayXLib() :
CDisplay(),
23 m_Format(QImage::Format_Invalid),
29CDisplayXLib::~CDisplayXLib()
41int CDisplayXLib::Width()
44 return DisplayWidth(m_pDisplay, DefaultScreen(m_pDisplay));
48int CDisplayXLib::Height()
51 return DisplayHeight(m_pDisplay, DefaultScreen(m_pDisplay));
55QImage::Format CDisplayXLib::GetFormat()
60QImage::Format CDisplayXLib::GetFormat(XImage* pImage)
62 switch(pImage->bits_per_pixel)
65 return QImage::Format_ARGB32;
67 return QImage::Format_RGB888;
69 qCritical(LogScreen) <<
"Don't support format:" << pImage->bits_per_pixel;
70 return QImage::Format_Invalid;
74int CDisplayXLib::Open()
79 m_pDisplay = XOpenDisplay(NULL);
86 if (strstr(ServerVendor(m_pDisplay),
"X.Org")) {
87 int vendrel = VendorRelease(m_pDisplay);
89 QString version(
"X.Org version: ");
90 version += QString::number(vendrel / 10000000);
91 version +=
"." + QString::number((vendrel / 100000) % 100),
92 version +=
"." + QString::number((vendrel / 1000) % 100);
94 version +=
"." + QString::number(vendrel % 1000);
96 qInfo(LogScreen) << version;
99 m_RootWindow = DefaultRootWindow(m_pDisplay);
100 if(0 == m_RootWindow)
102 qCritical(LogScreen) <<
"cannot get root window";
115 Visual* vis = DefaultVisual(m_pDisplay, DefaultScreen(m_pDisplay));
116 if (vis && vis->c_class == TrueColor) {
117 m_pImage = XCreateImage(m_pDisplay, vis,
118 DefaultDepth(m_pDisplay, DefaultScreen(m_pDisplay)),
119 ZPixmap, 0, 0, Width(), Height(),
120 BitmapPad(m_pDisplay), 0);
122 m_pImage->data = (
char *)malloc(m_pImage->bytes_per_line * m_pImage->height);
123 if (m_pImage->data) {
124 m_Format = GetFormat(m_pImage);
125 if(QImage::Format_Invalid != GetFormat()) {
126 m_Desktop = QImage((uchar*)m_pImage->data,
127 Width(), Height(), GetFormat());
132 if(!m_pImage->data || QImage::Format_Invalid == GetFormat()) {
133 DestroyImage(m_pImage);
142int CDisplayXLib::Close()
147 XCloseDisplay(m_pDisplay);
155 DestroyImage(m_pImage);
162int CDisplayXLib::GetScreenCount()
164 return ScreenCount(m_pDisplay);
167void CDisplayXLib::DestroyImage(
void *pImage)
169 qDebug(LogScreen) <<
"void DestroyImage(void *info)";
170 XDestroyImage(
static_cast<XImage*
>(pImage));
173QImage CDisplayXLib::GetDisplay(
int x,
int y,
int width,
int height)
175 if(!m_pDisplay || 0 == m_RootWindow)
182 XImage *pImage = XGetImage(m_pDisplay, m_RootWindow, x, y, width, height,
184 if(QImage::Format_Invalid == GetFormat())
185 m_Format = GetFormat(pImage);
186 if(QImage::Format_Invalid != GetFormat())
188 QImage img((uchar*)pImage->data,
189 pImage->width, pImage->height,
191 DestroyImage, pImage);
196 QImage cursor = GetCursor(pos, posHot);
198 && pos.x() >= x && (pos.x() + cursor.width()) <= width
199 && pos.y() >= y && (pos.y() + cursor.height()) <= height)
201 QPainter painter(&img);
202 painter.drawImage(pos, cursor);
209 DestroyImage(pImage);
214QImage CDisplayXLib::GetDisplay()
216 if(QImage::Format_Invalid != GetFormat()
217 && m_pDisplay && m_RootWindow && m_pImage)
219 XImage* pImg = XGetSubImage(m_pDisplay, m_RootWindow,
220 0, 0, Width(), Height(),
225 qCritical(LogScreen) <<
"Get desktop fail";
232 QImage cursor = GetCursor(pos, posHot);
235 if(m_Desktop.format() != cursor.format())
236 cursor = cursor.convertToFormat(m_Desktop.format());
237 QPainter painter(&m_Desktop);
238 painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
239 painter.drawImage(pos, cursor);
245QImage CDisplayXLib::GetCursor(QPoint &pos, QPoint &posHot)
249 XFixesCursorImage* ci;
250 XLockDisplay(m_pDisplay);
251 ci = XFixesGetCursorImage(m_pDisplay);
252 XUnlockDisplay(m_pDisplay);
256 pos = QPoint(ci->x, ci->y);
257 posHot = QPoint(ci->xhot, ci->yhot);
258 QImage img(ci->width, ci->height, QImage::Format_ARGB32);
260 unsigned char r = 0, g = 0, b = 0, a = 0;
261 unsigned short row = 0, col = 0, k = 0;
263 for(row = 0; row < ci->height; row++)
265 for(col = 0; col < ci->width; col++, k++)
267 a = (
unsigned char)((ci->pixels[k] >> 24) & 0xff);
268 r = (
unsigned char)((ci->pixels[k] >> 16) & 0xff);
269 g = (
unsigned char)((ci->pixels[k] >> 8) & 0xff);
270 b = (
unsigned char)((ci->pixels[k] >> 0) & 0xff);
272 QColor c(r, g, b, a);
273 img.setPixelColor(col, row, c);
281 pos = GetCursorPosition();
286QPoint CDisplayXLib::GetCursorPosition()
289 int win_x = 0, win_y = 0;
290 int root_x = 0, root_y = 0;
292 XLockDisplay(m_pDisplay);
294 if (!XQueryPointer(m_pDisplay, m_RootWindow, &root, &child, &root_x,
295 &root_y, &win_x, &win_y, &mask))
297 XUnlockDisplay(m_pDisplay);
301 XUnlockDisplay(m_pDisplay);
302 return QPoint(root_x, root_y);