Move screen inversion through XRandr into X11 standalone platform
Summary: By moving the functionality into the Platform API we can also implement support on other platforms which support this in general (e.g. DRM once Roman's color adjustment patches landed). Reviewers: #kwin, #plasma Subscribers: plasma-devel Tags: #plasma Differential Revision: https://phabricator.kde.org/D7447
This commit is contained in:
parent
23ef40e638
commit
51561052ec
5 changed files with 64 additions and 48 deletions
11
platform.cpp
11
platform.cpp
|
@ -22,6 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "abstract_egl_backend.h"
|
||||
#include "composite.h"
|
||||
#include "cursor.h"
|
||||
#include "effects.h"
|
||||
#include "input.h"
|
||||
#include "overlaywindow.h"
|
||||
#include "outline.h"
|
||||
|
@ -487,4 +488,14 @@ Decoration::Renderer *Platform::createDecorationRenderer(Decoration::DecoratedCl
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void Platform::invertScreen()
|
||||
{
|
||||
if (effects) {
|
||||
if (Effect *inverter = static_cast<EffectsHandlerImpl*>(effects)->provides(Effect::ScreenInversion)) {
|
||||
qCDebug(KWIN_CORE) << "inverting screen using Effect plugin";
|
||||
QMetaObject::invokeMethod(inverter, "toggleScreenInversion", Qt::DirectConnection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -338,6 +338,12 @@ public:
|
|||
**/
|
||||
virtual Decoration::Renderer *createDecorationRenderer(Decoration::DecoratedClientImpl *client);
|
||||
|
||||
/**
|
||||
* Platform specific way to invert the screen.
|
||||
* Default implementation invokes the invert effect
|
||||
**/
|
||||
virtual void invertScreen();
|
||||
|
||||
public Q_SLOTS:
|
||||
void pointerMotion(const QPointF &position, quint32 time);
|
||||
void pointerButtonPressed(quint32 button, quint32 time);
|
||||
|
|
|
@ -29,6 +29,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#if HAVE_X11_XINPUT
|
||||
#include "xinputintegration.h"
|
||||
#endif
|
||||
#include "abstract_client.h"
|
||||
#include "eglonxbackend.h"
|
||||
#include "keyboard_input.h"
|
||||
#include "logging.h"
|
||||
|
@ -37,6 +38,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "options.h"
|
||||
#include "overlaywindow_x11.h"
|
||||
#include "non_composited_outline.h"
|
||||
#include "workspace.h"
|
||||
#include "x11_decoration_renderer.h"
|
||||
|
||||
#include <KConfigGroup>
|
||||
|
@ -356,4 +358,46 @@ Decoration::Renderer *X11StandalonePlatform::createDecorationRenderer(Decoration
|
|||
return renderer;
|
||||
}
|
||||
|
||||
void X11StandalonePlatform::invertScreen()
|
||||
{
|
||||
using namespace Xcb::RandR;
|
||||
bool succeeded = false;
|
||||
|
||||
if (Xcb::Extensions::self()->isRandrAvailable()) {
|
||||
const auto active_client = workspace()->activeClient();
|
||||
ScreenResources res((active_client && active_client->window() != XCB_WINDOW_NONE) ? active_client->window() : rootWindow());
|
||||
|
||||
if (!res.isNull()) {
|
||||
for (int j = 0; j < res->num_crtcs; ++j) {
|
||||
auto crtc = res.crtcs()[j];
|
||||
CrtcGamma gamma(crtc);
|
||||
if (gamma.isNull()) {
|
||||
continue;
|
||||
}
|
||||
if (gamma->size) {
|
||||
qCDebug(KWIN_CORE) << "inverting screen using xcb_randr_set_crtc_gamma";
|
||||
const int half = gamma->size / 2 + 1;
|
||||
|
||||
uint16_t *red = gamma.red();
|
||||
uint16_t *green = gamma.green();
|
||||
uint16_t *blue = gamma.blue();
|
||||
for (int i = 0; i < half; ++i) {
|
||||
auto invert = [&gamma, i](uint16_t *ramp) {
|
||||
qSwap(ramp[i], ramp[gamma->size - 1 - i]);
|
||||
};
|
||||
invert(red);
|
||||
invert(green);
|
||||
invert(blue);
|
||||
}
|
||||
xcb_randr_set_crtc_gamma(connection(), crtc, gamma->size, red, green, blue);
|
||||
succeeded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!succeeded) {
|
||||
Platform::invertScreen();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -62,6 +62,8 @@ public:
|
|||
OutlineVisual *createOutline(Outline *outline) override;
|
||||
Decoration::Renderer *createDecorationRenderer(Decoration::DecoratedClientImpl *client) override;
|
||||
|
||||
void invertScreen() override;
|
||||
|
||||
protected:
|
||||
void doHideCursor() override;
|
||||
void doShowCursor() override;
|
||||
|
|
|
@ -1705,54 +1705,7 @@ void Workspace::slotWindowResize()
|
|||
|
||||
void Workspace::slotInvertScreen()
|
||||
{
|
||||
using namespace Xcb::RandR;
|
||||
bool succeeded = false;
|
||||
|
||||
if (Xcb::Extensions::self()->isRandrAvailable()) {
|
||||
ScreenResources res((active_client && active_client->window() != XCB_WINDOW_NONE) ? active_client->window() : rootWindow());
|
||||
|
||||
if (!res.isNull()) {
|
||||
for (int j = 0; j < res->num_crtcs; ++j) {
|
||||
auto crtc = res.crtcs()[j];
|
||||
CrtcGamma gamma(crtc);
|
||||
if (gamma.isNull()) {
|
||||
continue;
|
||||
}
|
||||
if (gamma->size) {
|
||||
qCDebug(KWIN_CORE) << "inverting screen using xcb_randr_set_crtc_gamma";
|
||||
const int half = gamma->size / 2 + 1;
|
||||
|
||||
uint16_t *red = gamma.red();
|
||||
uint16_t *green = gamma.green();
|
||||
uint16_t *blue = gamma.blue();
|
||||
for (int i = 0; i < half; ++i) {
|
||||
auto invert = [&gamma, i](uint16_t *ramp) {
|
||||
qSwap(ramp[i], ramp[gamma->size - 1 - i]);
|
||||
};
|
||||
invert(red);
|
||||
invert(green);
|
||||
invert(blue);
|
||||
}
|
||||
xcb_randr_set_crtc_gamma(connection(), crtc, gamma->size, red, green, blue);
|
||||
succeeded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (succeeded)
|
||||
return;
|
||||
|
||||
//BEGIN effect plugin inversion - atm only works with OpenGL and has an overhead to it
|
||||
if (effects) {
|
||||
if (Effect *inverter = static_cast<EffectsHandlerImpl*>(effects)->provides(Effect::ScreenInversion)) {
|
||||
qCDebug(KWIN_CORE) << "inverting screen using Effect plugin";
|
||||
QMetaObject::invokeMethod(inverter, "toggleScreenInversion", Qt::DirectConnection);
|
||||
}
|
||||
}
|
||||
|
||||
if (!succeeded)
|
||||
qCDebug(KWIN_CORE) << "sorry - neither Xrandr, nor XF86VidModeSetGammaRamp worked and there's no inversion supplying effect plugin either";
|
||||
|
||||
kwinApp()->platform()->invertScreen();
|
||||
}
|
||||
|
||||
#undef USABLE_ACTIVE_CLIENT
|
||||
|
|
Loading…
Reference in a new issue