File indexing completed on 2024-11-10 04:56:42
0001 /* 0002 SPDX-FileCopyrightText: 2006 Lubos Lunak <l.lunak@kde.org> 0003 SPDX-FileCopyrightText: 2009 Lucas Murray <lmurray@undefinedfire.com> 0004 SPDX-FileCopyrightText: 2018 Vlad Zahorodnii <vlad.zahorodnii@kde.org> 0005 0006 SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "effect/effect.h" 0010 #include "effect/effecthandler.h" 0011 0012 #include <KConfigGroup> 0013 0014 #include <QMatrix4x4> 0015 #include <QVector3D> 0016 0017 namespace KWin 0018 { 0019 0020 void WindowPrePaintData::setTranslucent() 0021 { 0022 mask |= Effect::PAINT_WINDOW_TRANSLUCENT; 0023 mask &= ~Effect::PAINT_WINDOW_OPAQUE; 0024 opaque = QRegion(); // cannot clip, will be transparent 0025 } 0026 0027 void WindowPrePaintData::setTransformed() 0028 { 0029 mask |= Effect::PAINT_WINDOW_TRANSFORMED; 0030 } 0031 0032 class PaintDataPrivate 0033 { 0034 public: 0035 PaintDataPrivate() 0036 : scale(1., 1., 1.) 0037 , rotationAxis(0, 0, 1.) 0038 , rotationAngle(0.) 0039 { 0040 } 0041 QVector3D scale; 0042 QVector3D translation; 0043 0044 QVector3D rotationAxis; 0045 QVector3D rotationOrigin; 0046 qreal rotationAngle; 0047 }; 0048 0049 PaintData::PaintData() 0050 : d(std::make_unique<PaintDataPrivate>()) 0051 { 0052 } 0053 0054 PaintData::~PaintData() = default; 0055 0056 qreal PaintData::xScale() const 0057 { 0058 return d->scale.x(); 0059 } 0060 0061 qreal PaintData::yScale() const 0062 { 0063 return d->scale.y(); 0064 } 0065 0066 qreal PaintData::zScale() const 0067 { 0068 return d->scale.z(); 0069 } 0070 0071 void PaintData::setScale(const QVector2D &scale) 0072 { 0073 d->scale.setX(scale.x()); 0074 d->scale.setY(scale.y()); 0075 } 0076 0077 void PaintData::setScale(const QVector3D &scale) 0078 { 0079 d->scale = scale; 0080 } 0081 void PaintData::setXScale(qreal scale) 0082 { 0083 d->scale.setX(scale); 0084 } 0085 0086 void PaintData::setYScale(qreal scale) 0087 { 0088 d->scale.setY(scale); 0089 } 0090 0091 void PaintData::setZScale(qreal scale) 0092 { 0093 d->scale.setZ(scale); 0094 } 0095 0096 const QVector3D &PaintData::scale() const 0097 { 0098 return d->scale; 0099 } 0100 0101 void PaintData::setXTranslation(qreal translate) 0102 { 0103 d->translation.setX(translate); 0104 } 0105 0106 void PaintData::setYTranslation(qreal translate) 0107 { 0108 d->translation.setY(translate); 0109 } 0110 0111 void PaintData::setZTranslation(qreal translate) 0112 { 0113 d->translation.setZ(translate); 0114 } 0115 0116 void PaintData::translate(qreal x, qreal y, qreal z) 0117 { 0118 translate(QVector3D(x, y, z)); 0119 } 0120 0121 void PaintData::translate(const QVector3D &t) 0122 { 0123 d->translation += t; 0124 } 0125 0126 qreal PaintData::xTranslation() const 0127 { 0128 return d->translation.x(); 0129 } 0130 0131 qreal PaintData::yTranslation() const 0132 { 0133 return d->translation.y(); 0134 } 0135 0136 qreal PaintData::zTranslation() const 0137 { 0138 return d->translation.z(); 0139 } 0140 0141 const QVector3D &PaintData::translation() const 0142 { 0143 return d->translation; 0144 } 0145 0146 qreal PaintData::rotationAngle() const 0147 { 0148 return d->rotationAngle; 0149 } 0150 0151 QVector3D PaintData::rotationAxis() const 0152 { 0153 return d->rotationAxis; 0154 } 0155 0156 QVector3D PaintData::rotationOrigin() const 0157 { 0158 return d->rotationOrigin; 0159 } 0160 0161 void PaintData::setRotationAngle(qreal angle) 0162 { 0163 d->rotationAngle = angle; 0164 } 0165 0166 void PaintData::setRotationAxis(Qt::Axis axis) 0167 { 0168 switch (axis) { 0169 case Qt::XAxis: 0170 setRotationAxis(QVector3D(1, 0, 0)); 0171 break; 0172 case Qt::YAxis: 0173 setRotationAxis(QVector3D(0, 1, 0)); 0174 break; 0175 case Qt::ZAxis: 0176 setRotationAxis(QVector3D(0, 0, 1)); 0177 break; 0178 } 0179 } 0180 0181 void PaintData::setRotationAxis(const QVector3D &axis) 0182 { 0183 d->rotationAxis = axis; 0184 } 0185 0186 void PaintData::setRotationOrigin(const QVector3D &origin) 0187 { 0188 d->rotationOrigin = origin; 0189 } 0190 0191 QMatrix4x4 PaintData::toMatrix(qreal deviceScale) const 0192 { 0193 QMatrix4x4 ret; 0194 if (d->translation != QVector3D(0, 0, 0)) { 0195 ret.translate(d->translation * deviceScale); 0196 } 0197 if (d->scale != QVector3D(1, 1, 1)) { 0198 ret.scale(d->scale); 0199 } 0200 0201 if (d->rotationAngle != 0) { 0202 ret.translate(d->rotationOrigin * deviceScale); 0203 ret.rotate(d->rotationAngle, d->rotationAxis); 0204 ret.translate(-d->rotationOrigin * deviceScale); 0205 } 0206 0207 return ret; 0208 } 0209 0210 class WindowPaintDataPrivate 0211 { 0212 public: 0213 qreal opacity; 0214 qreal saturation; 0215 qreal brightness; 0216 int screen; 0217 qreal crossFadeProgress; 0218 QMatrix4x4 projectionMatrix; 0219 }; 0220 0221 WindowPaintData::WindowPaintData() 0222 : WindowPaintData(QMatrix4x4()) 0223 { 0224 } 0225 0226 WindowPaintData::WindowPaintData(const QMatrix4x4 &projectionMatrix) 0227 : PaintData() 0228 , d(std::make_unique<WindowPaintDataPrivate>()) 0229 { 0230 setProjectionMatrix(projectionMatrix); 0231 setOpacity(1.0); 0232 setSaturation(1.0); 0233 setBrightness(1.0); 0234 setScreen(0); 0235 setCrossFadeProgress(0.0); 0236 } 0237 0238 WindowPaintData::WindowPaintData(const WindowPaintData &other) 0239 : PaintData() 0240 , d(std::make_unique<WindowPaintDataPrivate>()) 0241 { 0242 setXScale(other.xScale()); 0243 setYScale(other.yScale()); 0244 setZScale(other.zScale()); 0245 translate(other.translation()); 0246 setRotationOrigin(other.rotationOrigin()); 0247 setRotationAxis(other.rotationAxis()); 0248 setRotationAngle(other.rotationAngle()); 0249 setOpacity(other.opacity()); 0250 setSaturation(other.saturation()); 0251 setBrightness(other.brightness()); 0252 setScreen(other.screen()); 0253 setCrossFadeProgress(other.crossFadeProgress()); 0254 setProjectionMatrix(other.projectionMatrix()); 0255 } 0256 0257 WindowPaintData::~WindowPaintData() = default; 0258 0259 qreal WindowPaintData::opacity() const 0260 { 0261 return d->opacity; 0262 } 0263 0264 qreal WindowPaintData::saturation() const 0265 { 0266 return d->saturation; 0267 } 0268 0269 qreal WindowPaintData::brightness() const 0270 { 0271 return d->brightness; 0272 } 0273 0274 int WindowPaintData::screen() const 0275 { 0276 return d->screen; 0277 } 0278 0279 void WindowPaintData::setOpacity(qreal opacity) 0280 { 0281 d->opacity = opacity; 0282 } 0283 0284 void WindowPaintData::setSaturation(qreal saturation) const 0285 { 0286 d->saturation = saturation; 0287 } 0288 0289 void WindowPaintData::setBrightness(qreal brightness) 0290 { 0291 d->brightness = brightness; 0292 } 0293 0294 void WindowPaintData::setScreen(int screen) const 0295 { 0296 d->screen = screen; 0297 } 0298 0299 qreal WindowPaintData::crossFadeProgress() const 0300 { 0301 return d->crossFadeProgress; 0302 } 0303 0304 void WindowPaintData::setCrossFadeProgress(qreal factor) 0305 { 0306 d->crossFadeProgress = std::clamp(factor, 0.0, 1.0); 0307 } 0308 0309 qreal WindowPaintData::multiplyOpacity(qreal factor) 0310 { 0311 d->opacity *= factor; 0312 return d->opacity; 0313 } 0314 0315 qreal WindowPaintData::multiplySaturation(qreal factor) 0316 { 0317 d->saturation *= factor; 0318 return d->saturation; 0319 } 0320 0321 qreal WindowPaintData::multiplyBrightness(qreal factor) 0322 { 0323 d->brightness *= factor; 0324 return d->brightness; 0325 } 0326 0327 void WindowPaintData::setProjectionMatrix(const QMatrix4x4 &matrix) 0328 { 0329 d->projectionMatrix = matrix; 0330 } 0331 0332 QMatrix4x4 WindowPaintData::projectionMatrix() const 0333 { 0334 return d->projectionMatrix; 0335 } 0336 0337 QMatrix4x4 &WindowPaintData::rprojectionMatrix() 0338 { 0339 return d->projectionMatrix; 0340 } 0341 0342 WindowPaintData &WindowPaintData::operator*=(qreal scale) 0343 { 0344 this->setXScale(this->xScale() * scale); 0345 this->setYScale(this->yScale() * scale); 0346 this->setZScale(this->zScale() * scale); 0347 return *this; 0348 } 0349 0350 WindowPaintData &WindowPaintData::operator*=(const QVector2D &scale) 0351 { 0352 this->setXScale(this->xScale() * scale.x()); 0353 this->setYScale(this->yScale() * scale.y()); 0354 return *this; 0355 } 0356 0357 WindowPaintData &WindowPaintData::operator*=(const QVector3D &scale) 0358 { 0359 this->setXScale(this->xScale() * scale.x()); 0360 this->setYScale(this->yScale() * scale.y()); 0361 this->setZScale(this->zScale() * scale.z()); 0362 return *this; 0363 } 0364 0365 WindowPaintData &WindowPaintData::operator+=(const QPointF &translation) 0366 { 0367 return this->operator+=(QVector3D(translation)); 0368 } 0369 0370 WindowPaintData &WindowPaintData::operator+=(const QPoint &translation) 0371 { 0372 return this->operator+=(QVector3D(translation)); 0373 } 0374 0375 WindowPaintData &WindowPaintData::operator+=(const QVector2D &translation) 0376 { 0377 return this->operator+=(QVector3D(translation)); 0378 } 0379 0380 WindowPaintData &WindowPaintData::operator+=(const QVector3D &translation) 0381 { 0382 translate(translation); 0383 return *this; 0384 } 0385 0386 Effect::Effect(QObject *parent) 0387 : QObject(parent) 0388 { 0389 } 0390 0391 Effect::~Effect() 0392 { 0393 } 0394 0395 void Effect::reconfigure(ReconfigureFlags) 0396 { 0397 } 0398 0399 void Effect::windowInputMouseEvent(QEvent *) 0400 { 0401 } 0402 0403 void Effect::grabbedKeyboardEvent(QKeyEvent *) 0404 { 0405 } 0406 0407 bool Effect::borderActivated(ElectricBorder) 0408 { 0409 return false; 0410 } 0411 0412 void Effect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) 0413 { 0414 effects->prePaintScreen(data, presentTime); 0415 } 0416 0417 void Effect::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const QRegion ®ion, Output *screen) 0418 { 0419 effects->paintScreen(renderTarget, viewport, mask, region, screen); 0420 } 0421 0422 void Effect::postPaintScreen() 0423 { 0424 effects->postPaintScreen(); 0425 } 0426 0427 void Effect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) 0428 { 0429 effects->prePaintWindow(w, data, presentTime); 0430 } 0431 0432 void Effect::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, QRegion region, WindowPaintData &data) 0433 { 0434 effects->paintWindow(renderTarget, viewport, w, mask, region, data); 0435 } 0436 0437 void Effect::postPaintWindow(EffectWindow *w) 0438 { 0439 effects->postPaintWindow(w); 0440 } 0441 0442 bool Effect::provides(Feature) 0443 { 0444 return false; 0445 } 0446 0447 bool Effect::isActive() const 0448 { 0449 return true; 0450 } 0451 0452 QString Effect::debug(const QString &) const 0453 { 0454 return QString(); 0455 } 0456 0457 void Effect::drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion ®ion, WindowPaintData &data) 0458 { 0459 effects->drawWindow(renderTarget, viewport, w, mask, region, data); 0460 } 0461 0462 void Effect::setPositionTransformations(WindowPaintData &data, QRect ®ion, EffectWindow *w, 0463 const QRect &r, Qt::AspectRatioMode aspect) 0464 { 0465 QSizeF size = w->size(); 0466 size.scale(r.size(), aspect); 0467 data.setXScale(size.width() / double(w->width())); 0468 data.setYScale(size.height() / double(w->height())); 0469 int width = int(w->width() * data.xScale()); 0470 int height = int(w->height() * data.yScale()); 0471 int x = r.x() + (r.width() - width) / 2; 0472 int y = r.y() + (r.height() - height) / 2; 0473 region = QRect(x, y, width, height); 0474 data.setXTranslation(x - w->x()); 0475 data.setYTranslation(y - w->y()); 0476 } 0477 0478 QPointF Effect::cursorPos() 0479 { 0480 return effects->cursorPos(); 0481 } 0482 0483 double Effect::animationTime(const KConfigGroup &cfg, const QString &key, int defaultTime) 0484 { 0485 int time = cfg.readEntry(key, 0); 0486 return time != 0 ? time : std::max(defaultTime * effects->animationTimeFactor(), 1.); 0487 } 0488 0489 double Effect::animationTime(int defaultTime) 0490 { 0491 // at least 1ms, otherwise 0ms times can break some things 0492 return std::max(defaultTime * effects->animationTimeFactor(), 1.); 0493 } 0494 0495 int Effect::requestedEffectChainPosition() const 0496 { 0497 return 0; 0498 } 0499 0500 bool Effect::touchDown(qint32 id, const QPointF &pos, std::chrono::microseconds time) 0501 { 0502 return false; 0503 } 0504 0505 bool Effect::touchMotion(qint32 id, const QPointF &pos, std::chrono::microseconds time) 0506 { 0507 return false; 0508 } 0509 0510 bool Effect::touchUp(qint32 id, std::chrono::microseconds time) 0511 { 0512 return false; 0513 } 0514 0515 bool Effect::perform(Feature feature, const QVariantList &arguments) 0516 { 0517 return false; 0518 } 0519 0520 bool Effect::tabletToolEvent(QTabletEvent *event) 0521 { 0522 return false; 0523 } 0524 0525 bool Effect::tabletToolButtonEvent(uint button, bool pressed, quint64 tabletToolId) 0526 { 0527 return false; 0528 } 0529 0530 bool Effect::tabletPadButtonEvent(uint button, bool pressed, void *tabletPadId) 0531 { 0532 return false; 0533 } 0534 0535 bool Effect::tabletPadStripEvent(int number, int position, bool isFinger, void *tabletPadId) 0536 { 0537 return false; 0538 } 0539 0540 bool Effect::tabletPadRingEvent(int number, int position, bool isFinger, void *tabletPadId) 0541 { 0542 return false; 0543 } 0544 0545 bool Effect::blocksDirectScanout() const 0546 { 0547 return true; 0548 } 0549 0550 EffectPluginFactory::EffectPluginFactory() 0551 { 0552 } 0553 0554 EffectPluginFactory::~EffectPluginFactory() 0555 { 0556 } 0557 0558 bool EffectPluginFactory::enabledByDefault() const 0559 { 0560 return true; 0561 } 0562 0563 bool EffectPluginFactory::isSupported() const 0564 { 0565 return true; 0566 } 0567 0568 } // namespace KWin 0569 0570 #include "moc_effect.cpp"