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"
29 #include <SDL_mouse.h>
31 using sdlPointer =
struct
40 static 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);
70 static void sdl_Pointer_Clear(sdlPointer* ptr)
73 SDL_FreeCursor(ptr->cursor);
74 SDL_FreeSurface(ptr->image);
75 ptr->cursor =
nullptr;
79 static void sdl_Pointer_Free(rdpContext* context, rdpPointer* pointer)
81 auto ptr =
reinterpret_cast<sdlPointer*
>(pointer);
82 WINPR_UNUSED(context);
86 sdl_Pointer_Clear(ptr);
87 winpr_aligned_free(ptr->data);
92 static BOOL sdl_Pointer_SetDefault(rdpContext* context)
94 WINPR_UNUSED(context);
96 return sdl_push_user_event(SDL_USEREVENT_POINTER_DEFAULT);
99 static BOOL sdl_Pointer_Set(rdpContext* context, rdpPointer* pointer)
101 auto sdl = get_context(context);
103 return sdl_push_user_event(SDL_USEREVENT_POINTER_SET, pointer, sdl);
106 BOOL sdl_Pointer_Set_Process(SDL_UserEvent* uptr)
117 auto sdl =
static_cast<SdlContext*
>(uptr->data2);
120 auto context = sdl->context();
121 auto ptr =
static_cast<sdlPointer*
>(uptr->data1);
124 rdpPointer* pointer = &ptr->pointer;
126 rdpGdi* gdi = context->gdi;
129 x =
static_cast<INT32
>(pointer->xPos);
130 y =
static_cast<INT32
>(pointer->yPos);
131 sw = w =
static_cast<INT32
>(pointer->width);
132 sh = h =
static_cast<INT32
>(pointer->height);
134 SDL_Window* window = SDL_GetMouseFocus();
136 return sdl_Pointer_SetDefault(context);
138 const Uint32
id = SDL_GetWindowID(window);
140 if (!sdl_scale_coordinates(sdl,
id, &x, &y, FALSE, FALSE) ||
141 !sdl_scale_coordinates(sdl,
id, &sw, &sh, FALSE, FALSE))
144 sdl_Pointer_Clear(ptr);
146 const DWORD bpp = FreeRDPGetBitsPerPixel(gdi->dstFormat);
148 SDL_CreateRGBSurfaceWithFormat(0, sw, sh,
static_cast<int>(bpp), sdl->sdl_pixel_format);
152 SDL_LockSurface(ptr->image);
153 auto pixels =
static_cast<BYTE*
>(ptr->image->pixels);
154 auto data =
static_cast<const BYTE*
>(ptr->data);
155 const BOOL rc = freerdp_image_scale(
156 pixels, gdi->dstFormat,
static_cast<UINT32
>(ptr->image->pitch), 0, 0,
157 static_cast<UINT32
>(ptr->image->w),
static_cast<UINT32
>(ptr->image->h), data,
158 gdi->dstFormat, 0, 0, 0,
static_cast<UINT32
>(w),
static_cast<UINT32
>(h));
159 SDL_UnlockSurface(ptr->image);
163 ptr->cursor = SDL_CreateColorCursor(ptr->image, x, y);
167 SDL_SetCursor(ptr->cursor);
168 SDL_ShowCursor(SDL_ENABLE);
172 static BOOL sdl_Pointer_SetNull(rdpContext* context)
174 WINPR_UNUSED(context);
176 return sdl_push_user_event(SDL_USEREVENT_POINTER_NULL);
179 static BOOL sdl_Pointer_SetPosition(rdpContext* context, UINT32 x, UINT32 y)
181 WINPR_UNUSED(context);
182 WINPR_ASSERT(context);
184 return sdl_push_user_event(SDL_USEREVENT_POINTER_POSITION, x, y);
187 BOOL sdl_register_pointer(rdpGraphics* graphics)
189 const rdpPointer pointer = {
sizeof(sdlPointer),
194 sdl_Pointer_SetDefault,
195 sdl_Pointer_SetPosition,
207 graphics_register_pointer(graphics, &pointer);