Add a new method for determining user inactivity.
Fix some bugs.
This commit is contained in:
parent
d1f4f80278
commit
e68da0a4cc
@ -11,7 +11,7 @@ find_package(Qt5Network REQUIRED)
|
|||||||
find_package(Qt5Widgets REQUIRED)
|
find_package(Qt5Widgets REQUIRED)
|
||||||
find_package(X11 REQUIRED)
|
find_package(X11 REQUIRED)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} -lXrender -lXdamage")
|
set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} -lXrender -lXdamage -lXss")
|
||||||
include_directories(${X11_INCLUDE_DIR})
|
include_directories(${X11_INCLUDE_DIR})
|
||||||
add_executable(${PROJECT_NAME} "main.cpp" "hgx11.h" "hgx11.cpp" "hgx11net.h" "hgx11net.cpp" "hgx11damage.h" "hgx11damage.cpp" "hgx11grab.h" "hgx11grab.cpp")
|
add_executable(${PROJECT_NAME} "main.cpp" "hgx11.h" "hgx11.cpp" "hgx11net.h" "hgx11net.cpp" "hgx11damage.h" "hgx11damage.cpp" "hgx11grab.h" "hgx11grab.cpp" "hgx11screensaver.h" "hgx11screensaver.cpp")
|
||||||
target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Network Qt5::Widgets ${X11_LIBRARIES})
|
target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Network Qt5::Widgets ${X11_LIBRARIES})
|
||||||
|
|||||||
@ -24,7 +24,12 @@ to start it run `systemctl --user enable hgx11.service`.
|
|||||||
|
|
||||||
## Info
|
## Info
|
||||||
|
|
||||||
The -i option can turn off the Hyperion LED's after configurable amount of time the X11 display has not changed.
|
The -i option can turn off the Hyperion LED's after a configurable amount of time.
|
||||||
|
|
||||||
|
The -j option determines how to know when to turn off the Hyperion LED's after user inactivity, 0 (Default) uses Xdamage which detects screen changes while 1 will use Xscreensaver, which detects user input (mouse / keyboard /etc).
|
||||||
|
Xdamage should be superior, the disadvantage is if you leave a window open with anything that changes (like a console with a blinking cursor), the LED's will stay on.
|
||||||
|
Xscreensaver has the disadvantage that if a program doesn't tell it there is activity (like if you play a video for example), the LED's will turn off.
|
||||||
|
Ideally there would be a way to determine if the screen is inactive if a video is not playing, maybe someone knows?
|
||||||
|
|
||||||
The -f option will skip grabbing frames, it can be used to limit the amount of images sent to hyperion. Since the images sent to hyperion is based on the amount of X11 display activity, if this option is set high and not much is going on, there may be a long delay between when images are sent to Hyperion, this option is useful if you're watching videos for example and want to reduce the CPU usage of the grabbing.
|
The -f option will skip grabbing frames, it can be used to limit the amount of images sent to hyperion. Since the images sent to hyperion is based on the amount of X11 display activity, if this option is set high and not much is going on, there may be a long delay between when images are sent to Hyperion, this option is useful if you're watching videos for example and want to reduce the CPU usage of the grabbing.
|
||||||
|
|
||||||
|
|||||||
59
hgx11.cpp
59
hgx11.cpp
@ -23,6 +23,8 @@ hgx11::hgx11(QHash<QString, QString> opts)
|
|||||||
frameskip = i.value().toUShort();
|
frameskip = i.value().toUShort();
|
||||||
} else if ((i.key() == "i" || i.key() == "inactive") && i.value().toInt()) {
|
} else if ((i.key() == "i" || i.key() == "inactive") && i.value().toInt()) {
|
||||||
_inactiveTime_m = (i.value().toInt() * 1000);
|
_inactiveTime_m = (i.value().toInt() * 1000);
|
||||||
|
} else if ((i.key() == "j" || i.key() == "inactivetype") && i.value().toInt() == 1) {
|
||||||
|
_inactiveXss_m = true;
|
||||||
} else if (i.key() == "r" || i.key() == "redadjust") {
|
} else if (i.key() == "r" || i.key() == "redadjust") {
|
||||||
redAdjust = _parseColorArr(i.value(), 1);
|
redAdjust = _parseColorArr(i.value(), 1);
|
||||||
} else if (i.key() == "g" || i.key() == "greenadjust") {
|
} else if (i.key() == "g" || i.key() == "greenadjust") {
|
||||||
@ -33,16 +35,24 @@ hgx11::hgx11(QHash<QString, QString> opts)
|
|||||||
temperature = _parseColorArr(i.value(), 1);
|
temperature = _parseColorArr(i.value(), 1);
|
||||||
} else if (i.key() == "d" || i.key() == "threshold") {
|
} else if (i.key() == "d" || i.key() == "threshold") {
|
||||||
threshold = _parseColorArr(i.value(), 0);
|
threshold = _parseColorArr(i.value(), 0);
|
||||||
}else if ((i.key() == "l" || i.key() == "transform") && _parseColorArr(i.value(), 0) != "") {
|
} else if ((i.key() == "l" || i.key() == "transform") && _parseColorArr(i.value(), 0) != "") {
|
||||||
transform = i.value();
|
transform = i.value();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_grabber_p = new hgx11grab(scale);
|
_display_p = XOpenDisplay(nullptr);
|
||||||
|
if(_display_p == nullptr){
|
||||||
|
qCritical() << "Failed to open X11 display";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_grabber_p = new hgx11grab(_display_p, scale);
|
||||||
_hclient_p = new hgx11net(addr, port);
|
_hclient_p = new hgx11net(addr, port);
|
||||||
|
|
||||||
_damage_p = new hgx11damage(frameskip);
|
_damage_p = new hgx11damage(frameskip);
|
||||||
|
if (_inactiveXss_m) {
|
||||||
|
_screensaver_p = new hgx11screensaver(_display_p);
|
||||||
|
_inactiveTimeXss_m = ulong(_inactiveTime_m);
|
||||||
|
}
|
||||||
|
|
||||||
_setImgSize();
|
_setImgSize();
|
||||||
_hclient_p->ledAdjustments(redAdjust, greenAdjust, blueAdjust, temperature, threshold, transform);
|
_hclient_p->ledAdjustments(redAdjust, greenAdjust, blueAdjust, temperature, threshold, transform);
|
||||||
@ -52,25 +62,44 @@ hgx11::hgx11(QHash<QString, QString> opts)
|
|||||||
connect(_damage_p, SIGNAL(damageDetected()), _grabber_p, SLOT(grabFrame()));
|
connect(_damage_p, SIGNAL(damageDetected()), _grabber_p, SLOT(grabFrame()));
|
||||||
connect(_grabber_p, SIGNAL(scaleChanged()), this, SLOT(_setImgSize()));
|
connect(_grabber_p, SIGNAL(scaleChanged()), this, SLOT(_setImgSize()));
|
||||||
connect(_grabber_p, SIGNAL(imageCreated()), this, SLOT(_sendImage()));
|
connect(_grabber_p, SIGNAL(imageCreated()), this, SLOT(_sendImage()));
|
||||||
|
_grabActive_m = true;
|
||||||
|
|
||||||
if (_inactiveTime_m) {
|
if (_inactiveTime_m) {
|
||||||
_timer_p = new QTimer(this);
|
_timer_p = new QTimer(this);
|
||||||
|
if (!_inactiveXss_m) {
|
||||||
connect(_timer_p, SIGNAL(timeout()), this, SLOT(_inActivity()));
|
connect(_timer_p, SIGNAL(timeout()), this, SLOT(_inActivity()));
|
||||||
_timer_p->start(_inactiveTime_m);
|
|
||||||
connect(_damage_p, SIGNAL(damageDetected()), this, SLOT(_activity()));
|
connect(_damage_p, SIGNAL(damageDetected()), this, SLOT(_activity()));
|
||||||
|
_timer_p->start(_inactiveTime_m);
|
||||||
|
} else {
|
||||||
|
connect(_timer_p, SIGNAL(timeout()), this, SLOT(_checkXss()));
|
||||||
|
_timer_p->start(1000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hgx11::~hgx11()
|
hgx11::~hgx11()
|
||||||
{
|
{
|
||||||
|
_timer_p->stop();
|
||||||
|
disconnect(_damage_p, SIGNAL(damageDetected()), _grabber_p, SLOT(grabFrame()));
|
||||||
|
disconnect(_grabber_p, SIGNAL(scaleChanged()), this, SLOT(_setImgSize()));
|
||||||
|
disconnect(_grabber_p, SIGNAL(imageCreated()), this, SLOT(_sendImage()));
|
||||||
|
if (!_inactiveXss_m) {
|
||||||
|
disconnect(_timer_p, SIGNAL(timeout()), this, SLOT(_inActivity()));
|
||||||
|
disconnect(_damage_p, SIGNAL(damageDetected()), this, SLOT(_activity()));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
disconnect(_timer_p, SIGNAL(timeout()), this, SLOT(_checkXss()));
|
||||||
|
delete _screensaver_p;
|
||||||
|
}
|
||||||
|
if (_display_p != nullptr) {
|
||||||
|
XCloseDisplay(_display_p);
|
||||||
|
}
|
||||||
delete _hclient_p;
|
delete _hclient_p;
|
||||||
_hclient_p = nullptr;
|
|
||||||
_damage_p->terminate();
|
_damage_p->terminate();
|
||||||
while (!_damage_p->isFinished()) {}
|
while (!_damage_p->isFinished()) {}
|
||||||
delete _damage_p;
|
delete _damage_p;
|
||||||
_damage_p = nullptr;
|
|
||||||
delete _grabber_p;
|
delete _grabber_p;
|
||||||
_grabber_p = nullptr;
|
delete _timer_p;
|
||||||
}
|
}
|
||||||
|
|
||||||
// private
|
// private
|
||||||
@ -124,3 +153,19 @@ void hgx11::_setImgSize()
|
|||||||
_hclient_p->imgCmdBuf.append(QString::number(_grabber_p->getDest_width()));
|
_hclient_p->imgCmdBuf.append(QString::number(_grabber_p->getDest_width()));
|
||||||
_hclient_p->imgCmdBuf.append(",\"imagedata\":\"");
|
_hclient_p->imgCmdBuf.append(",\"imagedata\":\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hgx11::_checkXss()
|
||||||
|
{
|
||||||
|
if (_screensaver_p->lastX11ActivitySeconds() < _inactiveTimeXss_m) {
|
||||||
|
if (!_grabActive_m) {
|
||||||
|
connect(_damage_p, SIGNAL(damageDetected()), _grabber_p, SLOT(grabFrame()));
|
||||||
|
_grabActive_m = true;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (_grabActive_m) {
|
||||||
|
disconnect(_damage_p, SIGNAL(damageDetected()), _grabber_p, SLOT(grabFrame()));
|
||||||
|
_grabActive_m = false;
|
||||||
|
_inActivity();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
9
hgx11.h
9
hgx11.h
@ -4,10 +4,11 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
#include "hgx11grab.h"
|
#include "hgx11grab.h"
|
||||||
#include "hgx11net.h"
|
#include "hgx11net.h"
|
||||||
#include "hgx11damage.h"
|
#include "hgx11damage.h"
|
||||||
|
#include "hgx11screensaver.h"
|
||||||
|
|
||||||
class hgx11 : public QObject
|
class hgx11 : public QObject
|
||||||
{
|
{
|
||||||
@ -17,12 +18,17 @@ public:
|
|||||||
~hgx11();
|
~hgx11();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Display *_display_p;
|
||||||
hgx11damage *_damage_p;
|
hgx11damage *_damage_p;
|
||||||
hgx11grab *_grabber_p;
|
hgx11grab *_grabber_p;
|
||||||
hgx11net *_hclient_p;
|
hgx11net *_hclient_p;
|
||||||
|
hgx11screensaver *_screensaver_p;
|
||||||
QTimer *_timer_p;
|
QTimer *_timer_p;
|
||||||
|
|
||||||
int _inactiveTime_m = 0;
|
int _inactiveTime_m = 0;
|
||||||
|
unsigned long _inactiveTimeXss_m = 0;
|
||||||
|
bool _inactiveXss_m = false;
|
||||||
|
bool _grabActive_m;
|
||||||
|
|
||||||
QString _parseColorArr(QString, bool);
|
QString _parseColorArr(QString, bool);
|
||||||
|
|
||||||
@ -31,6 +37,7 @@ private slots:
|
|||||||
void _inActivity();
|
void _inActivity();
|
||||||
void _activity();
|
void _activity();
|
||||||
void _setImgSize();
|
void _setImgSize();
|
||||||
|
void _checkXss();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // HGX11_H
|
#endif // HGX11_H
|
||||||
|
|||||||
@ -6,25 +6,26 @@ hgx11damage::hgx11damage(unsigned short frameSkip)
|
|||||||
{
|
{
|
||||||
_frameSkip_m = frameSkip;
|
_frameSkip_m = frameSkip;
|
||||||
_display_p = XOpenDisplay(nullptr);
|
_display_p = XOpenDisplay(nullptr);
|
||||||
if(!_display_p){
|
if(_display_p == nullptr){
|
||||||
qCritical() << "failed to open x display";
|
qCritical() << "Failed to open X11 display";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Window window = DefaultRootWindow(_display_p);
|
_damage_m = XDamageCreate(_display_p, DefaultRootWindow(_display_p), XDamageReportNonEmpty);
|
||||||
_damage_m = XDamageCreate(_display_p, window, XDamageReportNonEmpty);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hgx11damage::~hgx11damage()
|
hgx11damage::~hgx11damage()
|
||||||
{
|
{
|
||||||
_loop_m = false;
|
_loop_m = false;
|
||||||
|
if (_damage_m) {
|
||||||
|
XDamageDestroy(_display_p, _damage_m);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// protected
|
// protected
|
||||||
|
|
||||||
void hgx11damage::_monitor()
|
void hgx11damage::_monitor()
|
||||||
{
|
{
|
||||||
if(!_display_p){
|
if(_display_p == nullptr){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (_loop_m) {
|
while (_loop_m) {
|
||||||
|
|||||||
@ -2,39 +2,35 @@
|
|||||||
|
|
||||||
// public
|
// public
|
||||||
|
|
||||||
hgx11grab::hgx11grab(unsigned short scaleDivisor)
|
hgx11grab::hgx11grab(Display *display, unsigned short scaleDivisor)
|
||||||
{
|
{
|
||||||
_x11Display_p = XOpenDisplay(nullptr);
|
_display_p = display;
|
||||||
if (_x11Display_p == nullptr) {
|
|
||||||
qCritical() << "Failed to open X11 display.";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_window_m = DefaultRootWindow(_x11Display_p);
|
if (!XShmQueryExtension(_display_p)) {
|
||||||
|
|
||||||
if (!XShmQueryExtension(_x11Display_p)) {
|
|
||||||
qCritical() << "Xshm is: not available.";
|
qCritical() << "Xshm is: not available.";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dummy, pixmaps_supported;
|
int dummy, pixmaps_supported;
|
||||||
|
|
||||||
if (!XRenderQueryExtension(_x11Display_p, &dummy, &dummy)) {
|
if (!XRenderQueryExtension(_display_p, &dummy, &dummy)) {
|
||||||
qCritical() << "XRender is not available.";
|
qCritical() << "XRender is not available.";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!XShmQueryVersion(_x11Display_p, &dummy, &dummy, &pixmaps_supported)) {
|
if (!XShmQueryVersion(_display_p, &dummy, &dummy, &pixmaps_supported)) {
|
||||||
qCritical("Could not get x shared memory version.");
|
qCritical("Could not get x shared memory version.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _XShmPixmapAvailable = pixmaps_supported && XShmPixmapFormat(_x11Display_p) == ZPixmap;
|
bool _XShmPixmapAvailable = pixmaps_supported && XShmPixmapFormat(_display_p) == ZPixmap;
|
||||||
if (!_XShmPixmapAvailable) {
|
if (!_XShmPixmapAvailable) {
|
||||||
qCritical() << "XshmPixMap is: not available.";
|
qCritical() << "XshmPixMap is: not available.";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_window_m = DefaultRootWindow(_display_p);
|
||||||
|
|
||||||
if (!_getWinAttr()) {
|
if (!_getWinAttr()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -62,9 +58,8 @@ hgx11grab::hgx11grab(unsigned short scaleDivisor)
|
|||||||
|
|
||||||
hgx11grab::~hgx11grab()
|
hgx11grab::~hgx11grab()
|
||||||
{
|
{
|
||||||
if (_x11Display_p != nullptr) {
|
if (_display_p != nullptr) {
|
||||||
_freeResources();
|
_freeResources();
|
||||||
XCloseDisplay(_x11Display_p);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +77,7 @@ int hgx11grab::getDest_width() const
|
|||||||
|
|
||||||
bool hgx11grab::_getWinAttr()
|
bool hgx11grab::_getWinAttr()
|
||||||
{
|
{
|
||||||
if (XGetWindowAttributes(_x11Display_p, _window_m, &_windowAttr_m) == 0) {
|
if (XGetWindowAttributes(_display_p, _window_m, &_windowAttr_m) == 0) {
|
||||||
qWarning() << "Failed to obtain X11 window attributes.";
|
qWarning() << "Failed to obtain X11 window attributes.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -103,12 +98,12 @@ void hgx11grab::_freeResources()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
XDestroyImage(_xImage_p);
|
XDestroyImage(_xImage_p);
|
||||||
XShmDetach(_x11Display_p, &_shminfo_m);
|
XShmDetach(_display_p, &_shminfo_m);
|
||||||
shmdt(_shminfo_m.shmaddr);
|
shmdt(_shminfo_m.shmaddr);
|
||||||
shmctl(_shminfo_m.shmid, IPC_RMID, nullptr);
|
shmctl(_shminfo_m.shmid, IPC_RMID, nullptr);
|
||||||
XRenderFreePicture(_x11Display_p, _srcPicture_m);
|
XRenderFreePicture(_display_p, _srcPicture_m);
|
||||||
XRenderFreePicture(_x11Display_p, _dstPicture_m);
|
XRenderFreePicture(_display_p, _dstPicture_m);
|
||||||
XFreePixmap(_x11Display_p, _pixmap_m);
|
XFreePixmap(_display_p, _pixmap_m);
|
||||||
_freed_m = 1;
|
_freed_m = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +123,7 @@ void hgx11grab::grabFrame()
|
|||||||
|
|
||||||
_freed_m = 0;
|
_freed_m = 0;
|
||||||
_xImage_p = XShmCreateImage(
|
_xImage_p = XShmCreateImage(
|
||||||
_x11Display_p, _windowAttr_m.visual,
|
_display_p, _windowAttr_m.visual,
|
||||||
uint(_windowAttr_m.depth), ZPixmap, nullptr, &_shminfo_m,
|
uint(_windowAttr_m.depth), ZPixmap, nullptr, &_shminfo_m,
|
||||||
uint(_destWidth_m), uint(_destHeight_m)
|
uint(_destWidth_m), uint(_destHeight_m)
|
||||||
);
|
);
|
||||||
@ -138,20 +133,20 @@ void hgx11grab::grabFrame()
|
|||||||
_shminfo_m.shmaddr = _xImage_p->data;
|
_shminfo_m.shmaddr = _xImage_p->data;
|
||||||
_shminfo_m.readOnly = false;
|
_shminfo_m.readOnly = false;
|
||||||
|
|
||||||
XShmAttach(_x11Display_p, &_shminfo_m);
|
XShmAttach(_display_p, &_shminfo_m);
|
||||||
_pixmap_m = XShmCreatePixmap(_x11Display_p, _window_m, _xImage_p->data, &_shminfo_m, uint(_destWidth_m), uint(_destHeight_m), uint(_windowAttr_m.depth));
|
_pixmap_m = XShmCreatePixmap(_display_p, _window_m, _xImage_p->data, &_shminfo_m, uint(_destWidth_m), uint(_destHeight_m), uint(_windowAttr_m.depth));
|
||||||
|
|
||||||
_dstFormat_p = XRenderFindVisualFormat(_x11Display_p, _windowAttr_m.visual);
|
_dstFormat_p = XRenderFindVisualFormat(_display_p, _windowAttr_m.visual);
|
||||||
_srcFormat_p = XRenderFindVisualFormat(_x11Display_p, _windowAttr_m.visual);
|
_srcFormat_p = XRenderFindVisualFormat(_display_p, _windowAttr_m.visual);
|
||||||
|
|
||||||
_srcPicture_m = XRenderCreatePicture(_x11Display_p, _window_m, _srcFormat_p, CPRepeat, &_pictAttr_m);
|
_srcPicture_m = XRenderCreatePicture(_display_p, _window_m, _srcFormat_p, CPRepeat, &_pictAttr_m);
|
||||||
_dstPicture_m = XRenderCreatePicture(_x11Display_p, _pixmap_m, _dstFormat_p, CPRepeat, &_pictAttr_m);
|
_dstPicture_m = XRenderCreatePicture(_display_p, _pixmap_m, _dstFormat_p, CPRepeat, &_pictAttr_m);
|
||||||
|
|
||||||
XRenderSetPictureFilter(_x11Display_p, _srcPicture_m, FilterBilinear, nullptr, 0);
|
XRenderSetPictureFilter(_display_p, _srcPicture_m, FilterBilinear, nullptr, 0);
|
||||||
XRenderSetPictureTransform(_x11Display_p, _srcPicture_m, &_mTransform_m);
|
XRenderSetPictureTransform(_display_p, _srcPicture_m, &_mTransform_m);
|
||||||
|
|
||||||
XRenderComposite(
|
XRenderComposite(
|
||||||
_x11Display_p, // *dpy,
|
_display_p, // *dpy,
|
||||||
PictOpSrc, // op,
|
PictOpSrc, // op,
|
||||||
_srcPicture_m, // src
|
_srcPicture_m, // src
|
||||||
None, // mask
|
None, // mask
|
||||||
@ -166,16 +161,16 @@ void hgx11grab::grabFrame()
|
|||||||
uint(_destHeight_m) // height
|
uint(_destHeight_m) // height
|
||||||
);
|
);
|
||||||
|
|
||||||
XSync(_x11Display_p, false);
|
XSync(_display_p, false);
|
||||||
|
|
||||||
XShmGetImage(_x11Display_p, _pixmap_m, _xImage_p, 0, 0, 0xFFFFFFFF);
|
XShmGetImage(_display_p, _pixmap_m, _xImage_p, 0, 0, 0xFFFFFFFF);
|
||||||
|
|
||||||
if (_xImage_p == nullptr) {
|
if (_xImage_p == nullptr) {
|
||||||
qWarning() << "Failed to get image from X11 server.";
|
qWarning() << "Failed to get image from X11 server.";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage qimg = *new QImage(reinterpret_cast<const uchar *>(_xImage_p->data), _destWidth_m, _destHeight_m, _xImage_p->bytes_per_line, QImage::Format_ARGB32);
|
QImage qimg(reinterpret_cast<const uchar *>(_xImage_p->data), _destWidth_m, _destHeight_m, _xImage_p->bytes_per_line, QImage::Format_ARGB32);
|
||||||
qimg = qimg.convertToFormat(QImage::Format_RGB888);
|
qimg = qimg.convertToFormat(QImage::Format_RGB888);
|
||||||
imgdata_m = QByteArray::fromRawData(reinterpret_cast<const char *>(qimg.bits()), qimg.byteCount());
|
imgdata_m = QByteArray::fromRawData(reinterpret_cast<const char *>(qimg.bits()), qimg.byteCount());
|
||||||
|
|
||||||
|
|||||||
@ -14,14 +14,14 @@ class hgx11grab : public QObject
|
|||||||
public:
|
public:
|
||||||
QByteArray imgdata_m;
|
QByteArray imgdata_m;
|
||||||
|
|
||||||
hgx11grab(unsigned short);
|
hgx11grab(Display *, unsigned short);
|
||||||
~hgx11grab();
|
~hgx11grab();
|
||||||
|
|
||||||
int getDest_width() const;
|
int getDest_width() const;
|
||||||
int getDest_height() const;
|
int getDest_height() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Display *_x11Display_p;
|
Display *_display_p;
|
||||||
Window _window_m;
|
Window _window_m;
|
||||||
Picture _srcPicture_m;
|
Picture _srcPicture_m;
|
||||||
Picture _dstPicture_m;
|
Picture _dstPicture_m;
|
||||||
|
|||||||
@ -17,6 +17,7 @@ hgx11net::~hgx11net()
|
|||||||
while(_sock_p->waitForBytesWritten()) {}
|
while(_sock_p->waitForBytesWritten()) {}
|
||||||
_sock_p->disconnectFromHost();
|
_sock_p->disconnectFromHost();
|
||||||
}
|
}
|
||||||
|
delete _sock_p;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hgx11net::clearLeds()
|
void hgx11net::clearLeds()
|
||||||
|
|||||||
25
hgx11screensaver.cpp
Normal file
25
hgx11screensaver.cpp
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#include "hgx11screensaver.h"
|
||||||
|
|
||||||
|
// public
|
||||||
|
|
||||||
|
hgx11screensaver::hgx11screensaver(Display *display)
|
||||||
|
{
|
||||||
|
_display_p = display;
|
||||||
|
_window_m = DefaultRootWindow(_display_p);
|
||||||
|
_info_p = XScreenSaverAllocInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
hgx11screensaver::~hgx11screensaver()
|
||||||
|
{
|
||||||
|
XFree(_info_p);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long hgx11screensaver::lastX11ActivitySeconds()
|
||||||
|
{
|
||||||
|
if (!_info_p) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
XScreenSaverQueryInfo(_display_p, _window_m, _info_p);
|
||||||
|
return _info_p->idle;
|
||||||
|
}
|
||||||
|
|
||||||
24
hgx11screensaver.h
Normal file
24
hgx11screensaver.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef HGX11SCREENSAVER_H
|
||||||
|
#define HGX11SCREENSAVER_H
|
||||||
|
|
||||||
|
#include <QThread>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/extensions/scrnsaver.h>
|
||||||
|
|
||||||
|
class hgx11screensaver : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
hgx11screensaver(Display *);
|
||||||
|
~hgx11screensaver();
|
||||||
|
unsigned long lastX11ActivitySeconds();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Display *_display_p;
|
||||||
|
Window _window_m;
|
||||||
|
XScreenSaverInfo *_info_p;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // HGX11SCREENSAVER_H
|
||||||
7
main.cpp
7
main.cpp
@ -47,10 +47,15 @@ int main(int argc, char *argv[])
|
|||||||
);
|
);
|
||||||
parser.addOption(frameskip);
|
parser.addOption(frameskip);
|
||||||
QCommandLineOption inactiveTime(QStringList() << "i" << "inactive",
|
QCommandLineOption inactiveTime(QStringList() << "i" << "inactive",
|
||||||
QCoreApplication::translate("main", "How many seconds after the screen has not changed to turn off the LED's. Set to 0 to disable."),
|
QCoreApplication::translate("main", "How many seconds after the screen is inactive to turn off the LED's. Set to 0 to disable."),
|
||||||
QCoreApplication::translate("main", "seconds before turning off LEDs")
|
QCoreApplication::translate("main", "seconds before turning off LEDs")
|
||||||
);
|
);
|
||||||
parser.addOption(inactiveTime);
|
parser.addOption(inactiveTime);
|
||||||
|
QCommandLineOption inactiveType(QStringList() << "j" << "inactivetype",
|
||||||
|
QCoreApplication::translate("main", "If `i` or `inactive` is set, how to determine activity, using (1) Xscreensaver (based on amount of time since user input activity) or (0) Xdamage (based on amount of time since screen activity change)"),
|
||||||
|
QCoreApplication::translate("main", "1 to use Xscreensaver or 0 to use Xdamage for inactivity tracking")
|
||||||
|
);
|
||||||
|
parser.addOption(inactiveType);
|
||||||
QCommandLineOption redAdjust(QStringList() << "r" << "redadjust",
|
QCommandLineOption redAdjust(QStringList() << "r" << "redadjust",
|
||||||
QCoreApplication::translate("main", "Adjustment of the red color (requires 3 space seperated values between 0 and 255) (ex. \"255,10,0\")"),
|
QCoreApplication::translate("main", "Adjustment of the red color (requires 3 space seperated values between 0 and 255) (ex. \"255,10,0\")"),
|
||||||
QCoreApplication::translate("main", "adjusts red color of LEDs")
|
QCoreApplication::translate("main", "adjusts red color of LEDs")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user