kodi
WindowDecorator.h
1 /*
2  * Copyright (C) 2017-2018 Team Kodi
3  * This file is part of Kodi - https://kodi.tv
4  *
5  * SPDX-License-Identifier: GPL-2.0-or-later
6  * See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 #include "Connection.h"
12 #include "Registry.h"
13 #include "Seat.h"
14 #include "ShellSurface.h"
15 #include "Util.h"
16 #include "WindowDecorationHandler.h"
17 #include "threads/CriticalSection.h"
18 #include "utils/Geometry.h"
19 
20 #include "platform/posix/utils/SharedMemory.h"
21 
22 #include <array>
23 #include <memory>
24 #include <set>
25 
26 #include <wayland-client-protocol.hpp>
27 #include <wayland-cursor.hpp>
28 
29 namespace KODI
30 {
31 namespace WINDOWING
32 {
33 namespace WAYLAND
34 {
35 
36 enum SurfaceIndex
37 {
38  SURFACE_TOP = 0,
39  SURFACE_RIGHT,
40  SURFACE_BOTTOM,
41  SURFACE_LEFT,
42  SURFACE_COUNT
43 };
44 
64 {
65 public:
75  CWindowDecorator(IWindowDecorationHandler& handler, CConnection& connection, wayland::surface_t const& mainSurface);
76 
87  void SetState(CSizeInt size, int scale, IShellSurface::StateBitset state);
92  {
93  return m_mainSurfaceSize;
94  }
103  CSizeInt CalculateMainSurfaceSize(CSizeInt size, IShellSurface::StateBitset state) const;
108  CSizeInt CalculateFullSurfaceSize(CSizeInt mainSurfaceSize, IShellSurface::StateBitset state) const;
109 
110  bool IsDecorationActive() const;
111 
112  void AddSeat(CSeat* seat);
113  void RemoveSeat(CSeat* seat);
114 
115  struct Buffer
116  {
117  void* data{};
118  std::size_t dataSize{};
119  CSizeInt size{};
120  wayland::buffer_t wlBuffer;
121 
122  Buffer() noexcept {}
123 
124  Buffer(void* data, std::size_t dataSize, CSizeInt size, wayland::buffer_t&& buffer)
125  : data{data}, dataSize{dataSize}, size{size}, wlBuffer{std::move(buffer)}
126  {}
127 
128  std::uint32_t* RgbaBuffer()
129  {
130  return static_cast<std::uint32_t*> (data);
131  }
132  };
133 
134  struct Surface
135  {
136  wayland::surface_t wlSurface;
137  Buffer buffer;
138  CSizeInt size;
139  int scale{1};
140  };
141 
142 private:
143  CWindowDecorator(CWindowDecorator const& other) = delete;
144  CWindowDecorator& operator=(CWindowDecorator const& other) = delete;
145 
146  // IRawInputHandlerTouch
147  void OnTouchDown(CSeat* seat,
148  std::uint32_t serial,
149  std::uint32_t time,
150  const wayland::surface_t& surface,
151  std::int32_t id,
152  double x,
153  double y) override;
154  // IRawInputHandlerPointer
155  void OnPointerEnter(CSeat* seat,
156  std::uint32_t serial,
157  const wayland::surface_t& surface,
158  double surfaceX,
159  double surfaceY) override;
160  void OnPointerLeave(CSeat* seat,
161  std::uint32_t serial,
162  const wayland::surface_t& surface) override;
163  void OnPointerMotion(CSeat* seat, std::uint32_t time, double surfaceX, double surfaceY) override;
164  void OnPointerButton(CSeat* seat, std::uint32_t serial, std::uint32_t time, std::uint32_t button, wayland::pointer_button_state state) override;
165 
166  void Reset(bool reallocate);
167 
168  // These functions should not be called directly as they may leave internal
169  // structures in an inconsistent state when called individually - only call
170  // Reset().
171  void ResetButtons();
172  void ResetSurfaces();
173  void ResetShm();
174  void ReattachSubsurfaces();
175  void PositionButtons();
176  void AllocateBuffers();
177  void Repaint();
178  void CommitAllBuffers();
179 
180  bool StateHasWindowDecorations(IShellSurface::StateBitset state) const;
181 
182  Buffer GetBuffer(CSizeInt size);
183 
184  IWindowDecorationHandler& m_handler;
185 
186  CSizeInt m_mainSurfaceSize;
187  int m_scale{1};
188  IShellSurface::StateBitset m_windowState;
189 
190  CRegistry m_registry;
191  wayland::shm_t m_shm;
192  wayland::shm_pool_t m_shmPool;
193  wayland::compositor_t m_compositor;
194  wayland::subcompositor_t m_subcompositor;
195  wayland::surface_t m_mainSurface;
196 
197  std::unique_ptr<KODI::UTILS::POSIX::CSharedMemory> m_memory;
198  std::size_t m_memoryAllocatedSize{};
199 
200  struct BorderSurface
201  {
202  Surface surface;
203  wayland::subsurface_t subsurface;
204  CRectInt geometry;
206  CRectInt windowRect;
207  };
208  BorderSurface MakeBorderSurface();
209 
218  CCriticalSection m_mutex;
219 
220  std::array<BorderSurface, 4> m_borderSurfaces;
221 
222  std::set<wayland::buffer_t, WaylandCPtrCompare> m_pendingBuffers;
223  CCriticalSection m_pendingBuffersMutex;
224 
225  struct SeatState
226  {
227  CSeat* seat;
228  SurfaceIndex currentSurface{SURFACE_COUNT};
229  CPoint pointerPosition;
230 
231  std::uint32_t pointerEnterSerial{};
232  std::string cursorName;
233  wayland::surface_t cursor;
234 
235  explicit SeatState(CSeat* seat)
236  : seat{seat}
237  {}
238  };
239  std::map<std::uint32_t, SeatState> m_seats;
240 
241  struct Button
242  {
243  CRectInt position;
244  bool hovered{};
245  std::function<void(Surface&, CRectInt, bool /* hover */)> draw;
246  std::function<void()> onClick;
247  };
248  std::vector<Button> m_buttons;
249 
250  wayland::cursor_theme_t m_cursorTheme;
251  std::uint32_t m_buttonColor;
252 
253  void LoadCursorTheme();
254 
255  void UpdateSeatCursor(SeatState& seatState);
256  void UpdateButtonHoverState();
257  void HandleSeatClick(SeatState const& seatState, SurfaceIndex surface, std::uint32_t serial, std::uint32_t button, CPoint position);
258 };
259 
260 }
261 }
262 }
Paint decorations around windows with subcompositing.
Definition: WindowDecorator.h:63
void SetState(CSizeInt size, int scale, IShellSurface::StateBitset state)
Set decoration state and size by providing full surface size including decorations.
Definition: WindowDecorator.cpp:718
Handler for raw wl_touch events.
Definition: Seat.h:83
Handler for raw wl_pointer events.
Definition: Seat.h:58
Handle Wayland globals.
Definition: Registry.h:35
CRectInt GetWindowGeometry() const
Get full geometry of the window, including decorations if active.
Definition: WindowDecorator.cpp:870
Connection to Wayland compositor.
Definition: Connection.h:25
Definition: AudioDecoder.h:18
CSizeInt GetMainSurfaceSize() const
Get calculated size of main surface.
Definition: WindowDecorator.h:91
CSizeInt CalculateMainSurfaceSize(CSizeInt size, IShellSurface::StateBitset state) const
Calculate size of main surface given the size of the full area including decorations and a state...
Definition: WindowDecorator.cpp:690
CWindowDecorator(IWindowDecorationHandler &handler, CConnection &connection, wayland::surface_t const &mainSurface)
Construct window decorator.
Definition: WindowDecorator.cpp:416
Handle all events and requests related to one seat (including input and selection) ...
Definition: Seat.h:114
CSizeInt CalculateFullSurfaceSize(CSizeInt mainSurfaceSize, IShellSurface::StateBitset state) const
Calculate size of full surface including decorations given the size of the main surface and a state...
Definition: WindowDecorator.cpp:704
Handler for reacting to events originating in window decorations, such as moving the window by clicki...
Definition: WindowDecorationHandler.h:26