Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions src/Backends/WaylandBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,7 @@ namespace gamescope
uint32_t m_uAxisSource = WL_POINTER_AXIS_SOURCE_WHEEL;

wl_surface *m_pCurrentCursorSurface = nullptr;
wl_surface *m_pCurrentTouchSurface = nullptr;

std::optional<wl_fixed_t> m_ofPendingCursorX;
std::optional<wl_fixed_t> m_ofPendingCursorY;
Expand Down Expand Up @@ -592,6 +593,15 @@ namespace gamescope

void Wayland_RelativePointer_RelativeMotion( zwp_relative_pointer_v1 *pRelativePointer, uint32_t uTimeHi, uint32_t uTimeLo, wl_fixed_t fDx, wl_fixed_t fDy, wl_fixed_t fDxUnaccel, wl_fixed_t fDyUnaccel );
static const zwp_relative_pointer_v1_listener s_RelativePointerListener;

void Wayland_Touch_Down( wl_touch *pTouch, uint32_t uSerial, uint32_t uTime, wl_surface *pSurface, int32_t nId, wl_fixed_t fX, wl_fixed_t fY );
void Wayland_Touch_Up( wl_touch *pTouch, uint32_t uSerial, uint32_t uTime, int32_t nId );
void Wayland_Touch_Motion( wl_touch *pTouch, uint32_t uTime, int32_t nId, wl_fixed_t fX, wl_fixed_t fY );
void Wayland_Touch_Frame( wl_touch *pTouch );
void Wayland_Touch_Cancel( wl_touch *pTouch );
void Wayland_Touch_Shape( wl_touch *pTouch, int32_t nId, wl_fixed_t fMajor, wl_fixed_t fMinor );
void Wayland_Touch_Orientation( wl_touch *pTouch, int32_t nId, wl_fixed_t fOrientation );
static const wl_touch_listener s_TouchListener;
};
const wl_registry_listener CWaylandInputThread::s_RegistryListener =
{
Expand Down Expand Up @@ -629,6 +639,16 @@ namespace gamescope
{
.relative_motion = WAYLAND_USERDATA_TO_THIS( CWaylandInputThread, Wayland_RelativePointer_RelativeMotion ),
};
const wl_touch_listener CWaylandInputThread::s_TouchListener =
{
.down = WAYLAND_USERDATA_TO_THIS( CWaylandInputThread, Wayland_Touch_Down ),
.up = WAYLAND_USERDATA_TO_THIS( CWaylandInputThread, Wayland_Touch_Up ),
.motion = WAYLAND_USERDATA_TO_THIS( CWaylandInputThread, Wayland_Touch_Motion ),
.frame = WAYLAND_USERDATA_TO_THIS( CWaylandInputThread, Wayland_Touch_Frame ),
.cancel = WAYLAND_USERDATA_TO_THIS( CWaylandInputThread, Wayland_Touch_Cancel ),
.shape = WAYLAND_USERDATA_TO_THIS( CWaylandInputThread, Wayland_Touch_Shape ),
.orientation = WAYLAND_USERDATA_TO_THIS( CWaylandInputThread, Wayland_Touch_Orientation ),
};

class CWaylandBackend : public CBaseBackend
{
Expand Down Expand Up @@ -3024,6 +3044,20 @@ namespace gamescope
wl_keyboard_add_listener( m_pKeyboard, &s_KeyboardListener, this );
}
}

if ( !!( uCapabilities & WL_SEAT_CAPABILITY_TOUCH ) != !!m_pTouch )
{
if ( m_pTouch )
{
wl_touch_release( m_pTouch );
m_pTouch = nullptr;
}
else
{
m_pTouch = wl_seat_get_touch( m_pSeat );
wl_touch_add_listener( m_pTouch, &s_TouchListener, this );
}
}
}

void CWaylandInputThread::Wayland_Seat_Name( wl_seat *pSeat, const char *pName )
Expand Down Expand Up @@ -3250,6 +3284,78 @@ namespace gamescope
wlserver_unlock();
}

// Touch

void CWaylandInputThread::Wayland_Touch_Down( wl_touch *pTouch, uint32_t uSerial, uint32_t uTime, wl_surface *pSurface, int32_t nId, wl_fixed_t fX, wl_fixed_t fY )
{
if ( !IsGamescopeToplevel( pSurface ) )
return;

m_pCurrentTouchSurface = pSurface;

CWaylandPlane *pPlane = (CWaylandPlane *)wl_surface_get_user_data( m_pCurrentTouchSurface );
if ( !pPlane )
return;

auto oState = pPlane->GetCurrentState();
if ( !oState )
return;

uint32_t uScale = oState->uFractionalScale;
double flX = ( wl_fixed_to_double( fX ) * uScale / 120.0 + oState->nDestX ) / g_nOutputWidth;
double flY = ( wl_fixed_to_double( fY ) * uScale / 120.0 + oState->nDestY ) / g_nOutputHeight;

wlserver_lock();
wlserver_touchdown( flX, flY, nId, ++m_uFakeTimestamp );
wlserver_unlock();
}
void CWaylandInputThread::Wayland_Touch_Up( wl_touch *pTouch, uint32_t uSerial, uint32_t uTime, int32_t nId )
{
wlserver_lock();
wlserver_touchup( nId, ++m_uFakeTimestamp );
wlserver_unlock();
}
void CWaylandInputThread::Wayland_Touch_Motion( wl_touch *pTouch, uint32_t uTime, int32_t nId, wl_fixed_t fX, wl_fixed_t fY )
{
if ( !m_pCurrentTouchSurface )
return;

CWaylandPlane *pPlane = (CWaylandPlane *)wl_surface_get_user_data( m_pCurrentTouchSurface );
if ( !pPlane )
return;

auto oState = pPlane->GetCurrentState();
if ( !oState )
return;

uint32_t uScale = oState->uFractionalScale;
double flX = ( wl_fixed_to_double( fX ) * uScale / 120.0 + oState->nDestX ) / g_nOutputWidth;
double flY = ( wl_fixed_to_double( fY ) * uScale / 120.0 + oState->nDestY ) / g_nOutputHeight;

wlserver_lock();
wlserver_touchmotion( flX, flY, nId, ++m_uFakeTimestamp );
wlserver_unlock();
}
void CWaylandInputThread::Wayland_Touch_Frame( wl_touch *pTouch )
{
}
void CWaylandInputThread::Wayland_Touch_Cancel( wl_touch *pTouch )
{
wlserver_lock();
std::set<uint32_t> touchIds = wlserver.touch_down_ids;
for ( uint32_t nId : touchIds )
wlserver_touchup( nId, ++m_uFakeTimestamp );
wlserver_unlock();

m_pCurrentTouchSurface = nullptr;
}
void CWaylandInputThread::Wayland_Touch_Shape( wl_touch *pTouch, int32_t nId, wl_fixed_t fMajor, wl_fixed_t fMinor )
{
}
void CWaylandInputThread::Wayland_Touch_Orientation( wl_touch *pTouch, int32_t nId, wl_fixed_t fOrientation )
{
}

/////////////////////////
// Backend Instantiator
/////////////////////////
Expand Down