Port invert screen from XLib xrandr to xcb randr

With this we can drop the linking to xrandr in KWin core.
icc-effect-5.14.5
Martin Gräßlin 2013-08-01 10:26:39 +02:00
parent becb5c2dc1
commit c16c0c3753
3 changed files with 52 additions and 15 deletions

View File

@ -236,7 +236,6 @@ set(kwin_KDE_LIBS
set(kwin_XLIB_LIBS
${X11_X11_LIB}
${X11_Xcursor_LIB}
${X11_Xrandr_LIB}
)
set(kwin_XCB_LIBS

View File

@ -1840,30 +1840,38 @@ void Workspace::slotWindowResize()
void Workspace::slotInvertScreen()
{
using namespace Xcb::RandR;
bool succeeded = false;
//BEGIN Xrandr inversion - does atm NOT work with the nvidia blob
XRRScreenResources *res = XRRGetScreenResources(display(), active_client ? active_client->window() : rootWindow());
if (res) {
for (int j = 0; j < res->ncrtc; ++j) {
XRRCrtcGamma *gamma = XRRGetCrtcGamma(display(), res->crtcs[j]);
if (gamma && gamma->size) {
ScreenResources res(active_client ? 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) {
kDebug(1212) << "inverting screen using XRRSetCrtcGamma";
const int half = gamma->size / 2 + 1;
unsigned short swap;
uint16_t *red = gamma.red();
uint16_t *green = gamma.green();
uint16_t *blue = gamma.blue();
for (int i = 0; i < half; ++i) {
#define INVERT(_C_) swap = gamma->_C_[i]; gamma->_C_[i] = gamma->_C_[gamma->size - 1 - i]; gamma->_C_[gamma->size - 1 - i] = swap
INVERT(red);
INVERT(green);
INVERT(blue);
#undef INVERT
auto invert = [&gamma, i](uint16_t *ramp) {
qSwap(ramp[i], ramp[gamma->size - 1 - i]);
};
invert(red);
invert(green);
invert(blue);
}
XRRSetCrtcGamma(display(), res->crtcs[j], gamma);
XRRFreeGamma(gamma);
xcb_randr_set_crtc_gamma(connection(), crtc, gamma->size, red, green, blue);
succeeded = true;
}
}
XRRFreeScreenResources(res);
}
if (succeeded)
return;

View File

@ -238,6 +238,36 @@ public:
namespace RandR
{
typedef Wrapper<xcb_randr_get_screen_info_reply_t, xcb_randr_get_screen_info_cookie_t, &xcb_randr_get_screen_info_reply, &xcb_randr_get_screen_info_unchecked> ScreenInfo;
class ScreenResources : public Wrapper<xcb_randr_get_screen_resources_reply_t, xcb_randr_get_screen_resources_cookie_t, &xcb_randr_get_screen_resources_reply, &xcb_randr_get_screen_resources_unchecked>
{
public:
explicit ScreenResources(WindowId window) : Wrapper<xcb_randr_get_screen_resources_reply_t, xcb_randr_get_screen_resources_cookie_t, &xcb_randr_get_screen_resources_reply, &xcb_randr_get_screen_resources_unchecked>(window) {}
inline xcb_randr_crtc_t *crtcs() {
if (isNull()) {
return nullptr;
}
return xcb_randr_get_screen_resources_crtcs(data());
}
};
class CrtcGamma : public Wrapper<xcb_randr_get_crtc_gamma_reply_t, xcb_randr_get_crtc_gamma_cookie_t, &xcb_randr_get_crtc_gamma_reply, &xcb_randr_get_crtc_gamma_unchecked>
{
public:
explicit CrtcGamma(xcb_randr_crtc_t c) : Wrapper<xcb_randr_get_crtc_gamma_reply_t, xcb_randr_get_crtc_gamma_cookie_t, &xcb_randr_get_crtc_gamma_reply, &xcb_randr_get_crtc_gamma_unchecked>(c) {}
inline uint16_t *red() {
return xcb_randr_get_crtc_gamma_red(data());
}
inline uint16_t *green() {
return xcb_randr_get_crtc_gamma_green(data());
}
inline uint16_t *blue() {
return xcb_randr_get_crtc_gamma_blue(data());
}
};
}
class ExtensionData