20#include <freerdp/config.h>
22#include <freerdp/gdi/gdi.h>
24#include "sdl_pointer.hpp"
25#include "sdl_freerdp.hpp"
26#include "sdl_touch.hpp"
27#include "sdl_utils.hpp"
31using sdlPointer =
struct
40static BOOL sdl_Pointer_New(rdpContext* context, rdpPointer* pointer)
42 auto ptr =
reinterpret_cast<sdlPointer*
>(pointer);
44 WINPR_ASSERT(context);
48 rdpGdi* gdi = context->gdi;
51 ptr->size = 4ull * pointer->width * pointer->height;
52 ptr->data = winpr_aligned_malloc(ptr->size, 16);
57 auto data =
static_cast<BYTE*
>(ptr->data);
58 if (!freerdp_image_copy_from_pointer_data(
59 data, gdi->dstFormat, 0, 0, 0, pointer->width, pointer->height, pointer->xorMaskData,
60 pointer->lengthXorMask, pointer->andMaskData, pointer->lengthAndMask, pointer->xorBpp,
61 &context->gdi->palette))
63 winpr_aligned_free(ptr->data);
71static void sdl_Pointer_Clear(sdlPointer* ptr)
74 SDL_FreeCursor(ptr->cursor);
75 SDL_FreeSurface(ptr->image);
76 ptr->cursor =
nullptr;
80static void sdl_Pointer_Free(rdpContext* context, rdpPointer* pointer)
82 auto ptr =
reinterpret_cast<sdlPointer*
>(pointer);
83 WINPR_UNUSED(context);
87 sdl_Pointer_Clear(ptr);
88 winpr_aligned_free(ptr->data);
93static BOOL sdl_Pointer_SetDefault(rdpContext* context)
95 WINPR_UNUSED(context);
97 return sdl_push_user_event(SDL_USEREVENT_POINTER_DEFAULT);
100static BOOL sdl_Pointer_Set(rdpContext* context, rdpPointer* pointer)
102 auto sdl = get_context(context);
104 return sdl_push_user_event(SDL_USEREVENT_POINTER_SET, pointer, sdl);
107BOOL sdl_Pointer_Set_Process(SDL_UserEvent* uptr)
118 auto sdl =
static_cast<SdlContext*
>(uptr->data2);
121 auto context = sdl->context();
122 auto ptr =
static_cast<sdlPointer*
>(uptr->data1);
125 rdpPointer* pointer = &ptr->pointer;
127 rdpGdi* gdi = context->gdi;
130 x =
static_cast<INT32
>(pointer->xPos);
131 y =
static_cast<INT32
>(pointer->yPos);
132 sw = w =
static_cast<INT32
>(pointer->width);
133 sh = h =
static_cast<INT32
>(pointer->height);
135 SDL_Window* window = SDL_GetMouseFocus();
137 return sdl_Pointer_SetDefault(context);
139 const Uint32
id = SDL_GetWindowID(window);
141 if (!sdl_scale_coordinates(sdl,
id, &x, &y, FALSE, FALSE) ||
142 !sdl_scale_coordinates(sdl,
id, &sw, &sh, FALSE, FALSE))
145 sdl_Pointer_Clear(ptr);
147 const DWORD bpp = FreeRDPGetBitsPerPixel(gdi->dstFormat);
149 SDL_CreateRGBSurfaceWithFormat(0, sw, sh,
static_cast<int>(bpp), sdl->sdl_pixel_format);
153 SDL_LockSurface(ptr->image);
154 auto pixels =
static_cast<BYTE*
>(ptr->image->pixels);
155 auto data =
static_cast<const BYTE*
>(ptr->data);
156 const BOOL rc = freerdp_image_scale(
157 pixels, gdi->dstFormat,
static_cast<UINT32
>(ptr->image->pitch), 0, 0,
158 static_cast<UINT32
>(ptr->image->w),
static_cast<UINT32
>(ptr->image->h), data,
159 gdi->dstFormat, 0, 0, 0,
static_cast<UINT32
>(w),
static_cast<UINT32
>(h));
160 SDL_UnlockSurface(ptr->image);
164 ptr->cursor = SDL_CreateColorCursor(ptr->image, x, y);
168 SDL_SetCursor(ptr->cursor);
169 SDL_ShowCursor(SDL_ENABLE);
173static BOOL sdl_Pointer_SetNull(rdpContext* context)
175 WINPR_UNUSED(context);
177 return sdl_push_user_event(SDL_USEREVENT_POINTER_NULL);
180static BOOL sdl_Pointer_SetPosition(rdpContext* context, UINT32 x, UINT32 y)
182 WINPR_UNUSED(context);
183 WINPR_ASSERT(context);
185 return sdl_push_user_event(SDL_USEREVENT_POINTER_POSITION, x, y);
188BOOL sdl_register_pointer(rdpGraphics* graphics)
190 const rdpPointer pointer = {
sizeof(sdlPointer),
195 sdl_Pointer_SetDefault,
196 sdl_Pointer_SetPosition,
208 graphics_register_pointer(graphics, &pointer);