Wayland cOMPositor written in C++ using Louvre.
at main 4.7 kB view raw
1/* ======================================================================== 2 * 3 * Filename: WOutput.cpp 4 * Description: W Compositor output class definitions 5 * GitHub Repo: https://github.com/diego-est/womp 6 * Author: Diego A. Estrada Rivera 7 * License: GPL-3.0 8 * 9 * ======================================================================== */ 10#include "WOutput.hpp" 11#include "WCompositor.hpp" 12#include "WSurface.hpp" 13#include "WTopBar.hpp" 14#include "global.hpp" 15#include "prelude.hpp" 16#include <LCompositor.h> 17#include <LCursor.h> 18#include <LDNDManager.h> 19#include <LLog.h> 20#include <LOpenGL.h> 21#include <LPainter.h> 22#include <LSeat.h> 23#include <LTexture.h> 24#include <LTextureView.h> 25#include <memory> 26 27WOutput::WOutput() noexcept 28{ 29} 30 31void WOutput::initializeGL() noexcept 32{ 33 wallpaperView = std::make_unique<LTextureView>( 34 nullptr, &G::compositor()->backgroundLayer); 35 36 /* 37 * TextureView's have a default nullptr translucent region, which means 38 * they are considered completely translucent by the scene. However, 39 * setting an empty LRegion (not nullptr) indicates to the scene that 40 * the view is completely opaque. 41 */ 42 let emptyRegion = LRegion(); 43 wallpaperView->setTranslucentRegion(&emptyRegion); 44 45 updateWallpaper(); 46 topBar = std::make_unique<WTopBar>(this); 47 G::scene()->handleInitializeGL(this); 48 repaint(); 49} 50 51void WOutput::moveGL() noexcept 52{ 53 wallpaperView->setPos(pos()); 54 topBar->update(); 55 G::scene()->handleMoveGL(this); 56 repaint(); 57} 58 59void WOutput::resizeGL() noexcept 60{ 61 updateWallpaper(); 62 topBar->update(); 63 G::scene()->handleResizeGL(this); 64 repaint(); 65} 66 67void WOutput::paintGL() noexcept 68{ 69 // check if HW cursor is supported 70 if (cursor()->hasHardwareSupport(this)) { 71 G::compositor()->softwareCursor.setTexture(nullptr); 72 } else { 73 G::compositor()->softwareCursor.setTexture(cursor()->texture()); 74 G::compositor()->softwareCursor.setPos(cursor()->rect().pos()); 75 G::compositor()->softwareCursor.setDstSize( 76 cursor()->rect().size()); 77 G::compositor()->softwareCursor.setVisible(cursor()->visible()); 78 } 79 topBar->update(); 80 G::scene()->handlePaintGL(this); 81} 82 83void WOutput::uninitializeGL() noexcept 84{ 85 /* 86 * set minimized output to nullptr to prevent the compositor from 87 * crashing when a surface is unminimized and 88 * WSurface::minimizeChanged() is triggered 89 */ 90 for (let surface : G::surfaces()) 91 if (surface->minimizedOutput == this) 92 surface->minimizedOutput = nullptr; 93 94 G::scene()->handleUninitializeGL(this); 95 96 if (wallpaperView->texture()) 97 delete wallpaperView->texture(); 98} 99 100void WOutput::updateWallpaper() const noexcept 101{ 102 if (wallpaperView->texture()) { 103 // if the current wallpaper size is equal to the output size 104 // then the output simply changed its scale 105 if (wallpaperView->texture()->sizeB() == sizeB()) { 106 wallpaperView->setBufferScale(scale()); 107 wallpaperView->setPos(pos()); 108 return; 109 } 110 111 delete wallpaperView->texture(); 112 } 113 114 // load the original wallpaper 115 let originalWallpaper = std::unique_ptr<LTexture>(LOpenGL::loadTexture( 116 "/home/Michorron/Media/Pictures/Wallpapers/bliss.jpg")); 117 118 if (originalWallpaper == nullptr) { 119 LLog::error("[louvre-example] Failed to load wallpaper."); 120 return; 121 } 122 123 let srcRect = calculateWallpaperRect(originalWallpaper->sizeB()); 124 125 // copy the srcRect of the originall wallpaper and scale it to match the 126 // output buffer size 127 wallpaperView->setTexture(originalWallpaper->copyB(sizeB(), srcRect)); 128 129 // set the buffer scale of the wallpaper view to match the output scale 130 wallpaperView->setBufferScale(scale()); 131 132 // delete the original wallpaper texture since we are using the scaled 133 // copy 134 wallpaperView->setPos(pos()); 135} 136 137void WOutput::damageRenderingTest() noexcept 138{ 139 painter()->clearScreen(); 140 G::scene()->handlePaintGL(this); 141 142 var damage = LRegion(); 143 damage.addRect(rect()); 144 setBufferDamage(damage); 145} 146fn WOutput::calculateWallpaperRect( 147 LSize const& originalWallpaperSize) const noexcept -> LRect 148{ 149 var srcRect = LRect(0); 150 151 let scaledWidth = 152 F32(size().w() * originalWallpaperSize.h()) / F32(size().h()); 153 154 // if the scaled width is greater than or equal to the output's width, 155 // we clip the texture's left and right sides. 156 if (scaledWidth >= originalWallpaperSize.w()) { 157 srcRect.setH(originalWallpaperSize.h()); 158 srcRect.setW((originalWallpaperSize.h() * size().w()) / 159 size().h()); 160 srcRect.setY((originalWallpaperSize.w() - srcRect.w()) / 2.0); 161 } else { // otherwise clip the texture's top and bottom sides 162 srcRect.setW(originalWallpaperSize.w()); 163 srcRect.setH(originalWallpaperSize.h() * size().h() / 164 size().w()); 165 srcRect.setY((originalWallpaperSize.h() - srcRect.h()) / 2.0); 166 } 167 168 return srcRect; 169}