add screen inversion through XF86VidModeSetGammaRamp or XRRSetCrtcGamma
use opengl invert effect as fallback REVIEW: 104371
This commit is contained in:
parent
1d00436ea4
commit
ab86f0e837
8 changed files with 95 additions and 10 deletions
|
@ -270,12 +270,12 @@ void EffectsHandlerImpl::postPaintWindow(EffectWindow* w)
|
||||||
// no special final code
|
// no special final code
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EffectsHandlerImpl::provides(Effect::Feature ef)
|
Effect *EffectsHandlerImpl::provides(Effect::Feature ef)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < loaded_effects.size(); ++i)
|
for (int i = 0; i < loaded_effects.size(); ++i)
|
||||||
if (loaded_effects.at(i).second->provides(ef))
|
if (loaded_effects.at(i).second->provides(ef))
|
||||||
return true;
|
return loaded_effects.at(i).second;
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EffectsHandlerImpl::drawWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
|
void EffectsHandlerImpl::drawWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
|
||||||
|
|
|
@ -57,7 +57,7 @@ public:
|
||||||
virtual void postPaintWindow(EffectWindow* w);
|
virtual void postPaintWindow(EffectWindow* w);
|
||||||
virtual void paintEffectFrame(EffectFrame* frame, QRegion region, double opacity, double frameOpacity);
|
virtual void paintEffectFrame(EffectFrame* frame, QRegion region, double opacity, double frameOpacity);
|
||||||
|
|
||||||
bool provides(Effect::Feature ef);
|
Effect *provides(Effect::Feature ef);
|
||||||
|
|
||||||
virtual void drawWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data);
|
virtual void drawWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data);
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ InvertEffect::InvertEffect()
|
||||||
KAction* a = (KAction*)actionCollection->addAction("Invert");
|
KAction* a = (KAction*)actionCollection->addAction("Invert");
|
||||||
a->setText(i18n("Toggle Invert Effect"));
|
a->setText(i18n("Toggle Invert Effect"));
|
||||||
a->setGlobalShortcut(KShortcut(Qt::CTRL + Qt::META + Qt::Key_I));
|
a->setGlobalShortcut(KShortcut(Qt::CTRL + Qt::META + Qt::Key_I));
|
||||||
connect(a, SIGNAL(triggered(bool)), this, SLOT(toggle()));
|
connect(a, SIGNAL(triggered(bool)), this, SLOT(toggleScreenInversion()));
|
||||||
|
|
||||||
KAction* b = (KAction*)actionCollection->addAction("InvertWindow");
|
KAction* b = (KAction*)actionCollection->addAction("InvertWindow");
|
||||||
b->setText(i18n("Toggle Invert Effect on Window"));
|
b->setText(i18n("Toggle Invert Effect on Window"));
|
||||||
|
@ -143,7 +143,7 @@ void InvertEffect::slotWindowClosed(EffectWindow* w)
|
||||||
m_windows.removeOne(w);
|
m_windows.removeOne(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InvertEffect::toggle()
|
void InvertEffect::toggleScreenInversion()
|
||||||
{
|
{
|
||||||
m_allWindows = !m_allWindows;
|
m_allWindows = !m_allWindows;
|
||||||
effects->addRepaintFull();
|
effects->addRepaintFull();
|
||||||
|
@ -163,6 +163,11 @@ bool InvertEffect::isActive() const
|
||||||
return m_valid && (m_allWindows || !m_windows.isEmpty());
|
return m_valid && (m_allWindows || !m_windows.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool InvertEffect::provides(Feature f)
|
||||||
|
{
|
||||||
|
return f == ScreenInversion;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
#include "invert.moc"
|
#include "invert.moc"
|
||||||
|
|
|
@ -45,11 +45,12 @@ public:
|
||||||
virtual void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time);
|
virtual void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time);
|
||||||
virtual void paintEffectFrame(KWin::EffectFrame* frame, QRegion region, double opacity, double frameOpacity);
|
virtual void paintEffectFrame(KWin::EffectFrame* frame, QRegion region, double opacity, double frameOpacity);
|
||||||
virtual bool isActive() const;
|
virtual bool isActive() const;
|
||||||
|
virtual bool provides(Feature);
|
||||||
|
|
||||||
static bool supported();
|
static bool supported();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void toggle();
|
void toggleScreenInversion();
|
||||||
void toggleWindow();
|
void toggleWindow();
|
||||||
void slotWindowClosed(KWin::EffectWindow *w);
|
void slotWindowClosed(KWin::EffectWindow *w);
|
||||||
|
|
||||||
|
|
|
@ -191,6 +191,7 @@ a->setText(i18n("Miscellaneous"));
|
||||||
DEF(I18N_NOOP("Kill Window"), Qt::CTRL + Qt::ALT + Qt::Key_Escape, slotKillWindow());
|
DEF(I18N_NOOP("Kill Window"), Qt::CTRL + Qt::ALT + Qt::Key_Escape, slotKillWindow());
|
||||||
DEF(I18N_NOOP("Block Global Shortcuts"), 0, slotDisableGlobalShortcuts());
|
DEF(I18N_NOOP("Block Global Shortcuts"), 0, slotDisableGlobalShortcuts());
|
||||||
DEF(I18N_NOOP("Suspend Compositing"), Qt::SHIFT + Qt::ALT + Qt::Key_F12, slotToggleCompositing());
|
DEF(I18N_NOOP("Suspend Compositing"), Qt::SHIFT + Qt::ALT + Qt::Key_F12, slotToggleCompositing());
|
||||||
|
DEF(I18N_NOOP("Invert Screen Colors"), 0, slotInvertScreen());
|
||||||
|
|
||||||
#undef DEF
|
#undef DEF
|
||||||
#undef DEF2
|
#undef DEF2
|
||||||
|
|
|
@ -320,8 +320,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Feature {
|
enum Feature {
|
||||||
Nothing = 0, Resize, GeometryTip,
|
Nothing = 0, Resize, GeometryTip, Outline, ScreenInversion
|
||||||
Outline
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -415,7 +414,7 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called on Transparent resizes.
|
* Called on Transparent resizes.
|
||||||
* return true if your effect substitutes the XOR rubberband
|
* return true if your effect substitutes questioned feature
|
||||||
*/
|
*/
|
||||||
virtual bool provides(Feature);
|
virtual bool provides(Feature);
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#include <KActivities/Info>
|
#include <KActivities/Info>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <X11/extensions/Xrandr.h>
|
||||||
|
#ifndef KWIN_NO_XF86VM
|
||||||
|
#include <X11/extensions/xf86vmode.h>
|
||||||
|
#endif
|
||||||
#include <fixx11h.h>
|
#include <fixx11h.h>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QSlider>
|
#include <QSlider>
|
||||||
|
@ -1615,6 +1619,80 @@ void Workspace::slotWindowResize()
|
||||||
performWindowOperation(active_client, Options::UnrestrictedResizeOp);
|
performWindowOperation(active_client, Options::UnrestrictedResizeOp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Workspace::slotInvertScreen()
|
||||||
|
{
|
||||||
|
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) {
|
||||||
|
kDebug(1212) << "inverting screen using XRRSetCrtcGamma";
|
||||||
|
const int half = gamma->size / 2 + 1;
|
||||||
|
unsigned short swap;
|
||||||
|
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
|
||||||
|
}
|
||||||
|
XRRSetCrtcGamma(display(), res->crtcs[j], gamma);
|
||||||
|
XRRFreeGamma(gamma);
|
||||||
|
succeeded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
XRRFreeScreenResources(res);
|
||||||
|
}
|
||||||
|
if (succeeded)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//BEGIN XF86VidMode inversion - only works if optionally libXxf86vm is linked
|
||||||
|
#ifndef KWIN_NO_XF86VM
|
||||||
|
int size = 0;
|
||||||
|
// TODO: this doesn't work with screen numbers in twinview - probably relevant only for multihead?
|
||||||
|
const int scrn = 0; // active_screen
|
||||||
|
if (XF86VidModeGetGammaRampSize(display(), scrn, &size)) {
|
||||||
|
unsigned short *red, *green, *blue;
|
||||||
|
red = new unsigned short[size];
|
||||||
|
green = new unsigned short[size];
|
||||||
|
blue = new unsigned short[size];
|
||||||
|
if (XF86VidModeGetGammaRamp(display(), scrn, size, red, green, blue)) {
|
||||||
|
kDebug(1212) << "inverting screen using XF86VidModeSetGammaRamp";
|
||||||
|
const int half = size / 2 + 1;
|
||||||
|
unsigned short swap;
|
||||||
|
for (int i = 0; i < half; ++i) {
|
||||||
|
swap = red[i]; red[i] = red[size - 1 - i]; red[size - 1 - i] = swap;
|
||||||
|
swap = green[i]; green[i] = green[size - 1 - i]; green[size - 1 - i] = swap;
|
||||||
|
swap = blue[i]; blue[i] = blue[size - 1 - i]; blue[size - 1 - i] = swap;
|
||||||
|
}
|
||||||
|
XF86VidModeSetGammaRamp(display(), scrn, size, red, green, blue);
|
||||||
|
succeeded = true;
|
||||||
|
}
|
||||||
|
delete [] red;
|
||||||
|
delete [] green;
|
||||||
|
delete [] blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (succeeded)
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//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)) {
|
||||||
|
kDebug(1212) << "inverting screen using Effect plugin";
|
||||||
|
QMetaObject::invokeMethod(inverter, "toggleScreenInversion", Qt::DirectConnection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!succeeded)
|
||||||
|
kDebug(1212) << "sorry - neither Xrandr, nor XF86VidModeSetGammaRamp worked and there's no inversion supplying effect plugin either";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#undef USABLE_ACTIVE_CLIENT
|
#undef USABLE_ACTIVE_CLIENT
|
||||||
|
|
||||||
void Client::setShortcut(const QString& _cut)
|
void Client::setShortcut(const QString& _cut)
|
||||||
|
|
|
@ -622,6 +622,7 @@ public slots:
|
||||||
void slotSetupWindowShortcut();
|
void slotSetupWindowShortcut();
|
||||||
void setupWindowShortcutDone(bool);
|
void setupWindowShortcutDone(bool);
|
||||||
void slotToggleCompositing();
|
void slotToggleCompositing();
|
||||||
|
void slotInvertScreen();
|
||||||
|
|
||||||
void updateClientArea();
|
void updateClientArea();
|
||||||
void suspendCompositing();
|
void suspendCompositing();
|
||||||
|
|
Loading…
Reference in a new issue