2024-06-08 10:07:59 +02:00
# pragma once
/*
Implementations for :
- wl_compositor
- wl_surface
- wl_region
- wl_callback
*/
# include <memory>
# include <vector>
# include <cstdint>
# include "../WaylandProtocol.hpp"
# include "wayland.hpp"
# include "../../helpers/signal/Signal.hpp"
2024-06-19 16:20:06 +02:00
# include "../../helpers/math/Math.hpp"
2024-06-08 10:07:59 +02:00
# include "../types/Buffer.hpp"
# include "../types/SurfaceRole.hpp"
class CWLOutputResource ;
class CMonitor ;
class CWLSurface ;
class CWLSurfaceResource ;
class CWLSubsurfaceResource ;
class CViewportResource ;
2024-07-21 13:09:54 +02:00
class CDRMSyncobjSurfaceResource ;
2024-06-08 10:07:59 +02:00
class CWLCallbackResource {
public :
CWLCallbackResource ( SP < CWlCallback > resource_ ) ;
bool good ( ) ;
void send ( timespec * now ) ;
private :
SP < CWlCallback > resource ;
} ;
class CWLRegionResource {
public :
CWLRegionResource ( SP < CWlRegion > resource_ ) ;
static SP < CWLRegionResource > fromResource ( wl_resource * res ) ;
bool good ( ) ;
CRegion region ;
WP < CWLRegionResource > self ;
private :
SP < CWlRegion > resource ;
} ;
class CWLSurfaceResource {
public :
CWLSurfaceResource ( SP < CWlSurface > resource_ ) ;
~ CWLSurfaceResource ( ) ;
static SP < CWLSurfaceResource > fromResource ( wl_resource * res ) ;
bool good ( ) ;
wl_client * client ( ) ;
void enter ( SP < CMonitor > monitor ) ;
void leave ( SP < CMonitor > monitor ) ;
void sendPreferredTransform ( wl_output_transform t ) ;
void sendPreferredScale ( int32_t scale ) ;
void frame ( timespec * now ) ;
uint32_t id ( ) ;
void map ( ) ;
void unmap ( ) ;
void error ( int code , const std : : string & str ) ;
SP < CWlSurface > getResource ( ) ;
CBox extends ( ) ;
void resetRole ( ) ;
Vector2D sourceSize ( ) ;
struct {
2024-07-21 13:09:54 +02:00
CSignal precommit ;
2024-06-08 10:07:59 +02:00
CSignal commit ;
CSignal map ;
CSignal unmap ;
CSignal newSubsurface ;
CSignal destroy ;
} events ;
2024-07-21 13:09:54 +02:00
struct SState {
2024-07-31 21:47:26 +02:00
CRegion opaque , input = CBox { { } , { INT32_MAX , INT32_MAX } } , damage , bufferDamage = CBox { { } , { INT32_MAX , INT32_MAX } } /* initial damage */ ;
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL ;
int scale = 1 ;
SP < CHLBufferReference > buffer ; // buffer ref will be released once the buffer is no longer locked. For checking if a buffer is attached to this state, check texture.
SP < CTexture > texture ;
Vector2D offset ;
Vector2D size , bufferSize ;
2024-06-08 10:07:59 +02:00
struct {
bool hasDestination = false ;
bool hasSource = false ;
Vector2D destination ;
CBox source ;
} viewport ;
2024-07-21 13:09:54 +02:00
bool rejected = false ;
2024-06-08 10:07:59 +02:00
//
void reset ( ) {
damage . clear ( ) ;
bufferDamage . clear ( ) ;
transform = WL_OUTPUT_TRANSFORM_NORMAL ;
scale = 1 ;
offset = { } ;
size = { } ;
}
} current , pending ;
std : : vector < SP < CWLCallbackResource > > callbacks ;
WP < CWLSurfaceResource > self ;
WP < CWLSurface > hlSurface ;
std : : vector < WP < CMonitor > > enteredOutputs ;
bool mapped = false ;
std : : vector < WP < CWLSubsurfaceResource > > subsurfaces ;
2024-07-31 21:47:26 +02:00
SP < ISurfaceRole > role ;
2024-06-08 10:07:59 +02:00
WP < CViewportResource > viewportResource ;
2024-07-21 13:09:54 +02:00
WP < CDRMSyncobjSurfaceResource > syncobj ; // may not be present
2024-06-08 10:07:59 +02:00
void breadthfirst ( std : : function < void ( SP < CWLSurfaceResource > , const Vector2D & , void * ) > fn , void * data ) ;
CRegion accumulateCurrentBufferDamage ( ) ;
2024-07-21 13:09:54 +02:00
void presentFeedback ( timespec * when , CMonitor * pMonitor , bool needsExplicitSync = false ) ;
void lockPendingState ( ) ;
void unlockPendingState ( ) ;
2024-06-08 10:07:59 +02:00
// returns a pair: found surface (null if not found) and surface local coords.
// localCoords param is relative to 0,0 of this surface
std : : pair < SP < CWLSurfaceResource > , Vector2D > at ( const Vector2D & localCoords , bool allowsInput = false ) ;
private :
SP < CWlSurface > resource ;
wl_client * pClient = nullptr ;
2024-07-31 21:47:26 +02:00
// this is for cursor dumb copy. Due to our (and wayland's...) architecture,
// this stupid-ass hack is used
WP < IHLBuffer > lastBuffer ;
2024-07-21 13:09:54 +02:00
2024-07-31 21:47:26 +02:00
int stateLocks = 0 ;
void destroy ( ) ;
void releaseBuffers ( bool onlyCurrent = true ) ;
void dropPendingBuffer ( ) ;
void dropCurrentBuffer ( ) ;
void commitPendingState ( ) ;
void bfHelper ( std : : vector < SP < CWLSurfaceResource > > nodes , std : : function < void ( SP < CWLSurfaceResource > , const Vector2D & , void * ) > fn , void * data ) ;
void updateCursorShm ( ) ;
friend class CWLPointerResource ;
2024-06-08 10:07:59 +02:00
} ;
class CWLCompositorResource {
public :
CWLCompositorResource ( SP < CWlCompositor > resource_ ) ;
bool good ( ) ;
private :
SP < CWlCompositor > resource ;
} ;
class CWLCompositorProtocol : public IWaylandProtocol {
public :
CWLCompositorProtocol ( const wl_interface * iface , const int & ver , const std : : string & name ) ;
virtual void bindManager ( wl_client * client , void * data , uint32_t ver , uint32_t id ) ;
struct {
CSignal newSurface ; // SP<CWLSurfaceResource>
} events ;
private :
void destroyResource ( CWLCompositorResource * resource ) ;
void destroyResource ( CWLSurfaceResource * resource ) ;
void destroyResource ( CWLRegionResource * resource ) ;
//
std : : vector < SP < CWLCompositorResource > > m_vManagers ;
std : : vector < SP < CWLSurfaceResource > > m_vSurfaces ;
std : : vector < SP < CWLRegionResource > > m_vRegions ;
friend class CWLSurfaceResource ;
friend class CWLCompositorResource ;
friend class CWLRegionResource ;
friend class CWLCallbackResource ;
} ;
namespace PROTO {
inline UP < CWLCompositorProtocol > compositor ;
} ;