@@ -556,6 +556,7 @@ namespace gamescope
556556 uint32_t m_uAxisSource = WL_POINTER_AXIS_SOURCE_WHEEL ;
557557
558558 wl_surface *m_pCurrentCursorSurface = nullptr ;
559+ wl_surface *m_pCurrentTouchSurface = nullptr ;
559560
560561 std::optional<wl_fixed_t > m_ofPendingCursorX;
561562 std::optional<wl_fixed_t > m_ofPendingCursorY;
@@ -592,6 +593,15 @@ namespace gamescope
592593
593594 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 );
594595 static const zwp_relative_pointer_v1_listener s_RelativePointerListener;
596+
597+ 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 );
598+ void Wayland_Touch_Up ( wl_touch *pTouch, uint32_t uSerial, uint32_t uTime, int32_t nId );
599+ void Wayland_Touch_Motion ( wl_touch *pTouch, uint32_t uTime, int32_t nId, wl_fixed_t fX , wl_fixed_t fY );
600+ void Wayland_Touch_Frame ( wl_touch *pTouch );
601+ void Wayland_Touch_Cancel ( wl_touch *pTouch );
602+ void Wayland_Touch_Shape ( wl_touch *pTouch, int32_t nId, wl_fixed_t fMajor , wl_fixed_t fMinor );
603+ void Wayland_Touch_Orientation ( wl_touch *pTouch, int32_t nId, wl_fixed_t fOrientation );
604+ static const wl_touch_listener s_TouchListener;
595605 };
596606 const wl_registry_listener CWaylandInputThread::s_RegistryListener =
597607 {
@@ -629,6 +639,16 @@ namespace gamescope
629639 {
630640 .relative_motion = WAYLAND_USERDATA_TO_THIS ( CWaylandInputThread, Wayland_RelativePointer_RelativeMotion ),
631641 };
642+ const wl_touch_listener CWaylandInputThread::s_TouchListener =
643+ {
644+ .down = WAYLAND_USERDATA_TO_THIS ( CWaylandInputThread, Wayland_Touch_Down ),
645+ .up = WAYLAND_USERDATA_TO_THIS ( CWaylandInputThread, Wayland_Touch_Up ),
646+ .motion = WAYLAND_USERDATA_TO_THIS ( CWaylandInputThread, Wayland_Touch_Motion ),
647+ .frame = WAYLAND_USERDATA_TO_THIS ( CWaylandInputThread, Wayland_Touch_Frame ),
648+ .cancel = WAYLAND_USERDATA_TO_THIS ( CWaylandInputThread, Wayland_Touch_Cancel ),
649+ .shape = WAYLAND_USERDATA_TO_THIS ( CWaylandInputThread, Wayland_Touch_Shape ),
650+ .orientation = WAYLAND_USERDATA_TO_THIS ( CWaylandInputThread, Wayland_Touch_Orientation ),
651+ };
632652
633653 class CWaylandBackend : public CBaseBackend
634654 {
@@ -3024,6 +3044,20 @@ namespace gamescope
30243044 wl_keyboard_add_listener ( m_pKeyboard, &s_KeyboardListener, this );
30253045 }
30263046 }
3047+
3048+ if ( !!( uCapabilities & WL_SEAT_CAPABILITY_TOUCH ) != !!m_pTouch )
3049+ {
3050+ if ( m_pTouch )
3051+ {
3052+ wl_touch_release ( m_pTouch );
3053+ m_pTouch = nullptr ;
3054+ }
3055+ else
3056+ {
3057+ m_pTouch = wl_seat_get_touch ( m_pSeat );
3058+ wl_touch_add_listener ( m_pTouch, &s_TouchListener, this );
3059+ }
3060+ }
30273061 }
30283062
30293063 void CWaylandInputThread::Wayland_Seat_Name ( wl_seat *pSeat, const char *pName )
@@ -3250,6 +3284,78 @@ namespace gamescope
32503284 wlserver_unlock ();
32513285 }
32523286
3287+ // Touch
3288+
3289+ 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 )
3290+ {
3291+ if ( !IsGamescopeToplevel ( pSurface ) )
3292+ return ;
3293+
3294+ m_pCurrentTouchSurface = pSurface;
3295+
3296+ CWaylandPlane *pPlane = (CWaylandPlane *)wl_surface_get_user_data ( m_pCurrentTouchSurface );
3297+ if ( !pPlane )
3298+ return ;
3299+
3300+ auto oState = pPlane->GetCurrentState ();
3301+ if ( !oState )
3302+ return ;
3303+
3304+ uint32_t uScale = oState->uFractionalScale ;
3305+ double flX = ( wl_fixed_to_double ( fX ) * uScale / 120.0 + oState->nDestX ) / g_nOutputWidth;
3306+ double flY = ( wl_fixed_to_double ( fY ) * uScale / 120.0 + oState->nDestY ) / g_nOutputHeight;
3307+
3308+ wlserver_lock ();
3309+ wlserver_touchdown ( flX, flY, nId, ++m_uFakeTimestamp );
3310+ wlserver_unlock ();
3311+ }
3312+ void CWaylandInputThread::Wayland_Touch_Up ( wl_touch *pTouch, uint32_t uSerial, uint32_t uTime, int32_t nId )
3313+ {
3314+ wlserver_lock ();
3315+ wlserver_touchup ( nId, ++m_uFakeTimestamp );
3316+ wlserver_unlock ();
3317+ }
3318+ void CWaylandInputThread::Wayland_Touch_Motion ( wl_touch *pTouch, uint32_t uTime, int32_t nId, wl_fixed_t fX , wl_fixed_t fY )
3319+ {
3320+ if ( !m_pCurrentTouchSurface )
3321+ return ;
3322+
3323+ CWaylandPlane *pPlane = (CWaylandPlane *)wl_surface_get_user_data ( m_pCurrentTouchSurface );
3324+ if ( !pPlane )
3325+ return ;
3326+
3327+ auto oState = pPlane->GetCurrentState ();
3328+ if ( !oState )
3329+ return ;
3330+
3331+ uint32_t uScale = oState->uFractionalScale ;
3332+ double flX = ( wl_fixed_to_double ( fX ) * uScale / 120.0 + oState->nDestX ) / g_nOutputWidth;
3333+ double flY = ( wl_fixed_to_double ( fY ) * uScale / 120.0 + oState->nDestY ) / g_nOutputHeight;
3334+
3335+ wlserver_lock ();
3336+ wlserver_touchmotion ( flX, flY, nId, ++m_uFakeTimestamp );
3337+ wlserver_unlock ();
3338+ }
3339+ void CWaylandInputThread::Wayland_Touch_Frame ( wl_touch *pTouch )
3340+ {
3341+ }
3342+ void CWaylandInputThread::Wayland_Touch_Cancel ( wl_touch *pTouch )
3343+ {
3344+ wlserver_lock ();
3345+ std::set<uint32_t > touchIds = wlserver.touch_down_ids ;
3346+ for ( uint32_t nId : touchIds )
3347+ wlserver_touchup ( nId, ++m_uFakeTimestamp );
3348+ wlserver_unlock ();
3349+
3350+ m_pCurrentTouchSurface = nullptr ;
3351+ }
3352+ void CWaylandInputThread::Wayland_Touch_Shape ( wl_touch *pTouch, int32_t nId, wl_fixed_t fMajor , wl_fixed_t fMinor )
3353+ {
3354+ }
3355+ void CWaylandInputThread::Wayland_Touch_Orientation ( wl_touch *pTouch, int32_t nId, wl_fixed_t fOrientation )
3356+ {
3357+ }
3358+
32533359 // ///////////////////////
32543360 // Backend Instantiator
32553361 // ///////////////////////
0 commit comments