Rabbit Remote Control 0.0.30
Loading...
Searching...
No Matches
ScreenXLib.cpp
1// Author: Kang Lin <kl222@126.com>
2
3#include <QLoggingCategory>
4#include "ScreenXLib.h"
5#include <X11/Xlib.h>
6#include <stdexcept>
7
8// xlib documents: https://www.x.org/releases/current/doc/libX11/libX11/libX11.html
9// X documents: https://www.x.org/releases/current/doc/index.html
10// X Window System Concepts: https://www.x.org/wiki/guide/concepts/
11// https://www.x.org
12
13Q_LOGGING_CATEGORY(LogScreen, "Screen")
14
15CScreen* CScreen::Instance()
16{
17 static CScreen* p = nullptr;
18 if(!p)
19 {
20 Display* dpy = NULL;
21 dpy = XOpenDisplay(NULL);/* Connect to a local display */
22 if(dpy)
23 {
24 if (strstr(ServerVendor(dpy), "X.Org")) {
25 int vendrel = VendorRelease(dpy);
26
27 QString version("X.Org version: ");
28 version += QString::number(vendrel / 10000000);
29 version += "." + QString::number((vendrel / 100000) % 100),
30 version += "." + QString::number((vendrel / 1000) % 100);
31 if (vendrel % 1000) {
32 version += "." + QString::number(vendrel % 1000);
33 }
34 qInfo(LogScreen) << version;
35 XCloseDisplay(dpy);
36 }
37 }
38 p = new CScreenXLib();
39 }
40 return p;
41}
42
43CScreenXLib::CScreenXLib(QObject *parent) : CScreen(parent)
44{
45 QString szErr;
46 Display* dsp = NULL;
47 dsp = XOpenDisplay(NULL);/* Connect to a local display */
48 if(NULL == dsp)
49 {
50 szErr = "Cannot connect to local display";
51 qCritical(LogScreen) << szErr;
52 throw std::runtime_error(szErr.toStdString().c_str());
53 }
54 do{
55 Visual* vis = DefaultVisual(dsp, DefaultScreen(dsp));
56 if (vis->c_class != TrueColor) {
57 szErr = "pseudocolour not supported";
58 qCritical(LogScreen) << szErr;
59 break;
60 }
61
62 m_pImage = XCreateImage(dsp, vis, DefaultDepth(dsp, DefaultScreen(dsp)),
63 ZPixmap, 0, 0, Width(), Height(),
64 BitmapPad(dsp), 0);
65 m_pImage->data = (char *)malloc(m_pImage->bytes_per_line * m_pImage->height);
66 if (m_pImage->data == NULL) {
67 szErr = "malloc() failed";
68 qCritical(LogScreen) << szErr;
69 }
70 } while(0);
71
72 XCloseDisplay(dsp);
73 if(!szErr.isEmpty())
74 throw std::runtime_error(szErr.toStdString().c_str());
75
76 m_Screen = QImage((uchar*)m_pImage->data, Width(), Height(), GetFormat(m_pImage));
77}
78
79CScreenXLib::~CScreenXLib()
80{
81 if(m_pImage)
82 XDestroyImage(m_pImage);
83}
84
85int CScreenXLib::Width()
86{
87 int w = 0;
88 Display* dsp = NULL;
89 dsp = XOpenDisplay(NULL);/* Connect to a local display */
90 if(NULL == dsp)
91 {
92 qCritical(LogScreen) << "Cannot connect to local display";
93 return 0;
94 }
95 w = DisplayWidth(dsp, DefaultScreen(dsp));
96 XCloseDisplay(dsp);
97 return w;
98}
99
100int CScreenXLib::Height()
101{
102 int h = 0;
103 Display* dsp = NULL;
104 dsp = XOpenDisplay(NULL);/* Connect to a local display */
105 if(NULL == dsp)
106 {
107 qCritical(LogScreen) << "Cannot connect to local display";
108 return 0;
109 }
110 h = DisplayHeight(dsp, DefaultScreen(dsp));
111 XCloseDisplay(dsp);
112 return h;
113}
114
115int CScreenXLib::VirtualTop()
116{
117 int n = 0;
118 return n;
119}
120
121int CScreenXLib::VirtualLeft()
122{
123 int n = 0;
124 return n;
125}
126
127int CScreenXLib::VirtualWidth()
128{
129 int n = 0;
130 return n;
131}
132
133int CScreenXLib::VirtualHeight()
134{
135 int n = 0;
136 return n;
137}
138
139int CScreenXLib::VisibleMonitorCount()
140{
141 int n = 0;
142 return n;
143}
144
145void myImageCleanupHandler(void *info)
146{
147 qDebug(LogScreen) << "void myImageCleanupHandler(void *info)";
148 XDestroyImage(static_cast<XImage*>(info));
149}
150
151QImage::Format CScreenXLib::GetFormat(XImage *img)
152{
153 switch(img->bits_per_pixel)
154 {
155 case 32:
156 return QImage::Format_ARGB32;
157 case 24:
158 return QImage::Format_RGB888;
159 default:
160 qCritical(LogScreen) << "Don't support format:" << img->bits_per_pixel;
161 return QImage::Format_Invalid;
162 }
163
164 return QImage::Format_Invalid;
165}
166
167QImage CScreenXLib::GetScreen(int index)
168{
169 Window desktop = 0;
170 Display* dsp = NULL;
171
172 int screen_width;
173 int screen_height;
174
175 dsp = XOpenDisplay(NULL);/* Connect to a local display */
176 if(NULL == dsp)
177 {
178 qCritical(LogScreen) << "Cannot connect to local display";
179 return m_Screen;
180 }
181 do{
182 desktop = DefaultRootWindow(dsp); // RootWindow(dsp,0);/* Refer to the root window */
183 if(0 == desktop)
184 {
185 qCritical(LogScreen) << "cannot get root window";
186 break;
187 }
188
189 /* Retrieve the width and the height of the screen */
190 screen_width = Width(); // DisplayWidth(dsp, 0);
191 screen_height = Height(); // DisplayHeight(dsp, 0);
192
193 XGetSubImage(dsp, desktop, 0, 0, Width(), Height(), AllPlanes, ZPixmap,
194 m_pImage, 0, 0);
195
196 /* Get the Image of the root window */
197// img = XGetImage(dsp, desktop, 0, 0, screen_width, screen_height, AllPlanes, ZPixmap);
198// m_Screen = QImage((uchar*)img->data,
199// img->width, img->height,
200// GetFormat(img),
201// myImageCleanupHandler, img);
202 }while(0);
203 XCloseDisplay(dsp);
204 return m_Screen;
205}
The CScreen class.
Definition Screen.h:14