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);