[client,sdl] encapsulate c++ context

to properly initialize c++ us a heap allocated wrapper class
This commit is contained in:
Armin Novak 2023-05-31 11:44:27 +02:00 committed by Martin Fleisz
parent b1ae467ae2
commit a0fd9cf957
13 changed files with 259 additions and 258 deletions

View File

@ -31,7 +31,7 @@
void sdl_OnChannelConnectedEventHandler(void* context, const ChannelConnectedEventArgs* e) void sdl_OnChannelConnectedEventHandler(void* context, const ChannelConnectedEventArgs* e)
{ {
auto sdl = reinterpret_cast<sdlContext*>(context); auto sdl = get_context(context);
WINPR_ASSERT(sdl); WINPR_ASSERT(sdl);
WINPR_ASSERT(e); WINPR_ASSERT(e);
@ -48,9 +48,8 @@ void sdl_OnChannelConnectedEventHandler(void* context, const ChannelConnectedEve
else if (strcmp(e->name, DISP_DVC_CHANNEL_NAME) == 0) else if (strcmp(e->name, DISP_DVC_CHANNEL_NAME) == 0)
{ {
auto disp = reinterpret_cast<DispClientContext*>(e->pInterface); auto disp = reinterpret_cast<DispClientContext*>(e->pInterface);
WINPR_ASSERT(sdl->disp);
WINPR_ASSERT(disp); WINPR_ASSERT(disp);
sdl->disp->init(disp); sdl->disp.init(disp);
} }
else else
freerdp_client_OnChannelConnectedEventHandler(context, e); freerdp_client_OnChannelConnectedEventHandler(context, e);
@ -58,7 +57,7 @@ void sdl_OnChannelConnectedEventHandler(void* context, const ChannelConnectedEve
void sdl_OnChannelDisconnectedEventHandler(void* context, const ChannelDisconnectedEventArgs* e) void sdl_OnChannelDisconnectedEventHandler(void* context, const ChannelDisconnectedEventArgs* e)
{ {
auto sdl = reinterpret_cast<sdlContext*>(context); auto sdl = get_context(context);
WINPR_ASSERT(sdl); WINPR_ASSERT(sdl);
WINPR_ASSERT(e); WINPR_ASSERT(e);
@ -77,8 +76,7 @@ void sdl_OnChannelDisconnectedEventHandler(void* context, const ChannelDisconnec
{ {
auto disp = reinterpret_cast<DispClientContext*>(e->pInterface); auto disp = reinterpret_cast<DispClientContext*>(e->pInterface);
WINPR_ASSERT(disp); WINPR_ASSERT(disp);
WINPR_ASSERT(sdl->disp); sdl->disp.uninit(disp);
sdl->disp->uninit(disp);
} }
else else
freerdp_client_OnChannelDisconnectedEventHandler(context, e); freerdp_client_OnChannelDisconnectedEventHandler(context, e);

View File

@ -37,7 +37,7 @@
BOOL sdlDispContext::settings_changed() BOOL sdlDispContext::settings_changed()
{ {
auto settings = _sdl->common.context.settings; auto settings = _sdl->context()->settings;
WINPR_ASSERT(settings); WINPR_ASSERT(settings);
if (_lastSentWidth != _targetWidth) if (_lastSentWidth != _targetWidth)
@ -65,7 +65,7 @@ BOOL sdlDispContext::update_last_sent()
{ {
WINPR_ASSERT(_sdl); WINPR_ASSERT(_sdl);
auto settings = _sdl->common.context.settings; auto settings = _sdl->context()->settings;
WINPR_ASSERT(settings); WINPR_ASSERT(settings);
_lastSentWidth = _targetWidth; _lastSentWidth = _targetWidth;
@ -80,7 +80,7 @@ BOOL sdlDispContext::update_last_sent()
BOOL sdlDispContext::sendResize() BOOL sdlDispContext::sendResize()
{ {
DISPLAY_CONTROL_MONITOR_LAYOUT layout = {}; DISPLAY_CONTROL_MONITOR_LAYOUT layout = {};
auto settings = _sdl->common.context.settings; auto settings = _sdl->context()->settings;
if (!settings) if (!settings)
return FALSE; return FALSE;
@ -130,29 +130,26 @@ BOOL sdlDispContext::set_window_resizable()
return TRUE; return TRUE;
} }
static BOOL sdl_disp_check_context(void* context, sdlContext** ppsdl, sdlDispContext** ppsdlDisp, static BOOL sdl_disp_check_context(void* context, SdlContext** ppsdl, sdlDispContext** ppsdlDisp,
rdpSettings** ppSettings) rdpSettings** ppSettings)
{ {
if (!context) if (!context)
return FALSE; return FALSE;
auto sdl = static_cast<sdlContext*>(context); auto sdl = get_context(context);
if (!(sdl->disp)) if (!sdl->context()->settings)
return FALSE;
if (!sdl->common.context.settings)
return FALSE; return FALSE;
*ppsdl = sdl; *ppsdl = sdl;
*ppsdlDisp = sdl->disp.get(); *ppsdlDisp = &sdl->disp;
*ppSettings = sdl->common.context.settings; *ppSettings = sdl->context()->settings;
return TRUE; return TRUE;
} }
void sdlDispContext::OnActivated(void* context, const ActivatedEventArgs* e) void sdlDispContext::OnActivated(void* context, const ActivatedEventArgs* e)
{ {
sdlContext* sdl = nullptr; SdlContext* sdl = nullptr;
sdlDispContext* sdlDisp = nullptr; sdlDispContext* sdlDisp = nullptr;
rdpSettings* settings = nullptr; rdpSettings* settings = nullptr;
@ -174,7 +171,7 @@ void sdlDispContext::OnActivated(void* context, const ActivatedEventArgs* e)
void sdlDispContext::OnGraphicsReset(void* context, const GraphicsResetEventArgs* e) void sdlDispContext::OnGraphicsReset(void* context, const GraphicsResetEventArgs* e)
{ {
sdlContext* sdl = nullptr; SdlContext* sdl = nullptr;
sdlDispContext* sdlDisp = nullptr; sdlDispContext* sdlDisp = nullptr;
rdpSettings* settings = nullptr; rdpSettings* settings = nullptr;
@ -193,7 +190,7 @@ void sdlDispContext::OnGraphicsReset(void* context, const GraphicsResetEventArgs
void sdlDispContext::OnTimer(void* context, const TimerEventArgs* e) void sdlDispContext::OnTimer(void* context, const TimerEventArgs* e)
{ {
sdlContext* sdl = nullptr; SdlContext* sdl = nullptr;
sdlDispContext* sdlDisp = nullptr; sdlDispContext* sdlDisp = nullptr;
rdpSettings* settings = nullptr; rdpSettings* settings = nullptr;
@ -214,7 +211,7 @@ UINT sdlDispContext::sendLayout(const rdpMonitor* monitors, size_t nmonitors)
WINPR_ASSERT(monitors); WINPR_ASSERT(monitors);
WINPR_ASSERT(nmonitors > 0); WINPR_ASSERT(nmonitors > 0);
auto settings = _sdl->common.context.settings; auto settings = _sdl->context()->settings;
WINPR_ASSERT(settings); WINPR_ASSERT(settings);
std::vector<DISPLAY_CONTROL_MONITOR_LAYOUT> layouts; std::vector<DISPLAY_CONTROL_MONITOR_LAYOUT> layouts;
@ -303,14 +300,14 @@ BOOL sdlDispContext::handle_window_event(const SDL_WindowEvent* ev)
{ {
case SDL_WINDOWEVENT_HIDDEN: case SDL_WINDOWEVENT_HIDDEN:
case SDL_WINDOWEVENT_MINIMIZED: case SDL_WINDOWEVENT_MINIMIZED:
gdi_send_suppress_output(_sdl->common.context.gdi, TRUE); gdi_send_suppress_output(_sdl->context()->gdi, TRUE);
return TRUE; return TRUE;
case SDL_WINDOWEVENT_EXPOSED: case SDL_WINDOWEVENT_EXPOSED:
case SDL_WINDOWEVENT_SHOWN: case SDL_WINDOWEVENT_SHOWN:
case SDL_WINDOWEVENT_MAXIMIZED: case SDL_WINDOWEVENT_MAXIMIZED:
case SDL_WINDOWEVENT_RESTORED: case SDL_WINDOWEVENT_RESTORED:
gdi_send_suppress_output(_sdl->common.context.gdi, FALSE); gdi_send_suppress_output(_sdl->context()->gdi, FALSE);
return TRUE; return TRUE;
case SDL_WINDOWEVENT_RESIZED: case SDL_WINDOWEVENT_RESIZED:
@ -321,18 +318,15 @@ BOOL sdlDispContext::handle_window_event(const SDL_WindowEvent* ev)
case SDL_WINDOWEVENT_LEAVE: case SDL_WINDOWEVENT_LEAVE:
WINPR_ASSERT(_sdl); WINPR_ASSERT(_sdl);
WINPR_ASSERT(_sdl->input); _sdl->input.keyboard_grab(ev->windowID, SDL_FALSE);
_sdl->input->keyboard_grab(ev->windowID, SDL_FALSE);
return TRUE; return TRUE;
case SDL_WINDOWEVENT_ENTER: case SDL_WINDOWEVENT_ENTER:
WINPR_ASSERT(_sdl); WINPR_ASSERT(_sdl);
WINPR_ASSERT(_sdl->input); _sdl->input.keyboard_grab(ev->windowID, SDL_TRUE);
_sdl->input->keyboard_grab(ev->windowID, SDL_TRUE); return _sdl->input.keyboard_focus_in();
return _sdl->input->keyboard_focus_in();
case SDL_WINDOWEVENT_FOCUS_GAINED: case SDL_WINDOWEVENT_FOCUS_GAINED:
case SDL_WINDOWEVENT_TAKE_FOCUS: case SDL_WINDOWEVENT_TAKE_FOCUS:
WINPR_ASSERT(_sdl->input); return _sdl->input.keyboard_focus_in();
return _sdl->input->keyboard_focus_in();
default: default:
return TRUE; return TRUE;
@ -353,7 +347,7 @@ UINT sdlDispContext::DisplayControlCaps(DispClientContext* disp, UINT32 maxNumMo
UINT sdlDispContext::DisplayControlCaps(UINT32 maxNumMonitors, UINT32 maxMonitorAreaFactorA, UINT sdlDispContext::DisplayControlCaps(UINT32 maxNumMonitors, UINT32 maxMonitorAreaFactorA,
UINT32 maxMonitorAreaFactorB) UINT32 maxMonitorAreaFactorB)
{ {
auto settings = _sdl->common.context.settings; auto settings = _sdl->context()->settings;
WINPR_ASSERT(settings); WINPR_ASSERT(settings);
WLog_DBG(TAG, WLog_DBG(TAG,
@ -374,7 +368,7 @@ BOOL sdlDispContext::init(DispClientContext* disp)
if (!disp) if (!disp)
return FALSE; return FALSE;
auto settings = _sdl->common.context.settings; auto settings = _sdl->context()->settings;
if (!settings) if (!settings)
return FALSE; return FALSE;
@ -401,14 +395,14 @@ BOOL sdlDispContext::uninit(DispClientContext* disp)
return TRUE; return TRUE;
} }
sdlDispContext::sdlDispContext(sdlContext* sdl) : _sdl(sdl) sdlDispContext::sdlDispContext(SdlContext* sdl) : _sdl(sdl)
{ {
WINPR_ASSERT(_sdl); WINPR_ASSERT(_sdl);
WINPR_ASSERT(_sdl->common.context.settings); WINPR_ASSERT(_sdl->context()->settings);
WINPR_ASSERT(_sdl->common.context.pubSub); WINPR_ASSERT(_sdl->context()->pubSub);
auto settings = _sdl->common.context.settings; auto settings = _sdl->context()->settings;
auto pubSub = _sdl->common.context.pubSub; auto pubSub = _sdl->context()->pubSub;
_lastSentWidth = _targetWidth = settings->DesktopWidth; _lastSentWidth = _targetWidth = settings->DesktopWidth;
_lastSentHeight = _targetHeight = settings->DesktopHeight; _lastSentHeight = _targetHeight = settings->DesktopHeight;
@ -419,7 +413,7 @@ sdlDispContext::sdlDispContext(sdlContext* sdl) : _sdl(sdl)
sdlDispContext::~sdlDispContext() sdlDispContext::~sdlDispContext()
{ {
wPubSub* pubSub = _sdl->common.context.pubSub; wPubSub* pubSub = _sdl->context()->pubSub;
WINPR_ASSERT(pubSub); WINPR_ASSERT(pubSub);
PubSub_UnsubscribeActivated(pubSub, sdlDispContext::OnActivated); PubSub_UnsubscribeActivated(pubSub, sdlDispContext::OnActivated);

View File

@ -28,7 +28,7 @@ class sdlDispContext
{ {
public: public:
sdlDispContext(sdlContext* sdl); sdlDispContext(SdlContext* sdl);
~sdlDispContext(); ~sdlDispContext();
BOOL init(DispClientContext* disp); BOOL init(DispClientContext* disp);
@ -58,7 +58,7 @@ class sdlDispContext
static void OnTimer(void* context, const TimerEventArgs* e); static void OnTimer(void* context, const TimerEventArgs* e);
private: private:
sdlContext* _sdl = nullptr; SdlContext* _sdl = nullptr;
DispClientContext* _disp = nullptr; DispClientContext* _disp = nullptr;
int _eventBase = -1; int _eventBase = -1;
int _errorBase = -1; int _errorBase = -1;

View File

@ -274,11 +274,11 @@ static int error_info_to_error(freerdp* instance, DWORD* pcode)
static BOOL sdl_begin_paint(rdpContext* context) static BOOL sdl_begin_paint(rdpContext* context)
{ {
rdpGdi* gdi; rdpGdi* gdi;
auto sdl = reinterpret_cast<sdlContext*>(context); auto sdl = get_context(context);
WINPR_ASSERT(sdl); WINPR_ASSERT(sdl);
HANDLE handles[] = { sdl->update_complete->handle(), freerdp_abort_event(context) }; HANDLE handles[] = { sdl->update_complete.handle(), freerdp_abort_event(context) };
const DWORD status = WaitForMultipleObjects(ARRAYSIZE(handles), handles, FALSE, INFINITE); const DWORD status = WaitForMultipleObjects(ARRAYSIZE(handles), handles, FALSE, INFINITE);
switch (status) switch (status)
{ {
@ -287,7 +287,7 @@ static BOOL sdl_begin_paint(rdpContext* context)
default: default:
return FALSE; return FALSE;
} }
sdl->update_complete->clear(); sdl->update_complete.clear();
gdi = context->gdi; gdi = context->gdi;
WINPR_ASSERT(gdi); WINPR_ASSERT(gdi);
@ -301,33 +301,33 @@ static BOOL sdl_begin_paint(rdpContext* context)
return TRUE; return TRUE;
} }
static BOOL sdl_redraw(sdlContext* sdl) static BOOL sdl_redraw(SdlContext* sdl)
{ {
WINPR_ASSERT(sdl); WINPR_ASSERT(sdl);
rdpGdi* gdi = sdl->common.context.gdi; auto gdi = sdl->context()->gdi;
return gdi_send_suppress_output(gdi, FALSE); return gdi_send_suppress_output(gdi, FALSE);
} }
class SdlEventUpdateTriggerGuard class SdlEventUpdateTriggerGuard
{ {
private: private:
sdlContext* _sdl; SdlContext* _sdl;
public: public:
SdlEventUpdateTriggerGuard(sdlContext* sdl) : _sdl(sdl) SdlEventUpdateTriggerGuard(SdlContext* sdl) : _sdl(sdl)
{ {
} }
~SdlEventUpdateTriggerGuard() ~SdlEventUpdateTriggerGuard()
{ {
_sdl->update_complete->set(); _sdl->update_complete.set();
} }
}; };
static BOOL sdl_end_paint_process(rdpContext* context) static BOOL sdl_end_paint_process(rdpContext* context)
{ {
rdpGdi* gdi; rdpGdi* gdi;
auto sdl = reinterpret_cast<sdlContext*>(context); auto sdl = get_context(context);
WINPR_ASSERT(context); WINPR_ASSERT(context);
@ -349,32 +349,31 @@ static BOOL sdl_end_paint_process(rdpContext* context)
return TRUE; return TRUE;
// TODO: Support multiple windows // TODO: Support multiple windows
for (size_t x = 0; x < sdl->windowCount; x++) for (auto& window : sdl->windows)
{ {
sdl_window_t* window = &sdl->windows[x]; SDL_Surface* screen = SDL_GetWindowSurface(window.window);
SDL_Surface* screen = SDL_GetWindowSurface(window->window);
int w, h; int w, h;
SDL_GetWindowSize(window->window, &w, &h); SDL_GetWindowSize(window.window, &w, &h);
window->offset_x = 0; window.offset_x = 0;
window->offset_y = 0; window.offset_y = 0;
if (!freerdp_settings_get_bool(context->settings, FreeRDP_SmartSizing)) if (!freerdp_settings_get_bool(context->settings, FreeRDP_SmartSizing))
{ {
if (gdi->width < w) if (gdi->width < w)
{ {
window->offset_x = (w - gdi->width) / 2; window.offset_x = (w - gdi->width) / 2;
} }
if (gdi->height < h) if (gdi->height < h)
{ {
window->offset_y = (h - gdi->height) / 2; window.offset_y = (h - gdi->height) / 2;
} }
for (INT32 i = 0; i < ninvalid; i++) for (INT32 i = 0; i < ninvalid; i++)
{ {
const GDI_RGN* rgn = &cinvalid[i]; const GDI_RGN* rgn = &cinvalid[i];
const SDL_Rect srcRect = { rgn->x, rgn->y, rgn->w, rgn->h }; const SDL_Rect srcRect = { rgn->x, rgn->y, rgn->w, rgn->h };
SDL_Rect dstRect = { window->offset_x + rgn->x, window->offset_y + rgn->y, rgn->w, SDL_Rect dstRect = { window.offset_x + rgn->x, window.offset_y + rgn->y, rgn->w,
rgn->h }; rgn->h };
SDL_SetClipRect(sdl->primary.get(), &srcRect); SDL_SetClipRect(sdl->primary.get(), &srcRect);
SDL_SetClipRect(screen, &dstRect); SDL_SetClipRect(screen, &dstRect);
@ -383,7 +382,7 @@ static BOOL sdl_end_paint_process(rdpContext* context)
} }
else else
{ {
const Uint32 id = SDL_GetWindowID(window->window); auto id = SDL_GetWindowID(window.window);
for (INT32 i = 0; i < ninvalid; i++) for (INT32 i = 0; i < ninvalid; i++)
{ {
const GDI_RGN* rgn = &cinvalid[i]; const GDI_RGN* rgn = &cinvalid[i];
@ -396,7 +395,7 @@ static BOOL sdl_end_paint_process(rdpContext* context)
SDL_BlitScaled(sdl->primary.get(), &srcRect, screen, &dstRect); SDL_BlitScaled(sdl->primary.get(), &srcRect, screen, &dstRect);
} }
} }
SDL_UpdateWindowSurface(window->window); SDL_UpdateWindowSurface(window.window);
} }
return TRUE; return TRUE;
@ -408,16 +407,16 @@ static BOOL sdl_end_paint_process(rdpContext* context)
*/ */
static BOOL sdl_end_paint(rdpContext* context) static BOOL sdl_end_paint(rdpContext* context)
{ {
auto sdl = reinterpret_cast<sdlContext*>(context); auto sdl = get_context(context);
WINPR_ASSERT(sdl); WINPR_ASSERT(sdl);
std::lock_guard<CriticalSection> lock(*sdl->critical); std::lock_guard<CriticalSection> lock(sdl->critical);
const BOOL rc = sdl_push_user_event(SDL_USEREVENT_UPDATE, context); const BOOL rc = sdl_push_user_event(SDL_USEREVENT_UPDATE, context);
return rc; return rc;
} }
static void sdl_destroy_primary(sdlContext* sdl) static void sdl_destroy_primary(SdlContext* sdl)
{ {
if (!sdl) if (!sdl)
return; return;
@ -426,13 +425,13 @@ static void sdl_destroy_primary(sdlContext* sdl)
} }
/* Create a SDL surface from the GDI buffer */ /* Create a SDL surface from the GDI buffer */
static BOOL sdl_create_primary(sdlContext* sdl) static BOOL sdl_create_primary(SdlContext* sdl)
{ {
rdpGdi* gdi; rdpGdi* gdi;
WINPR_ASSERT(sdl); WINPR_ASSERT(sdl);
gdi = sdl->common.context.gdi; gdi = sdl->context()->gdi;
WINPR_ASSERT(gdi); WINPR_ASSERT(gdi);
sdl_destroy_primary(sdl); sdl_destroy_primary(sdl);
@ -458,7 +457,7 @@ static BOOL sdl_desktop_resize(rdpContext* context)
{ {
rdpGdi* gdi; rdpGdi* gdi;
rdpSettings* settings; rdpSettings* settings;
auto sdl = reinterpret_cast<sdlContext*>(context); auto sdl = get_context(context);
WINPR_ASSERT(context); WINPR_ASSERT(context);
@ -480,13 +479,12 @@ static BOOL sdl_play_sound(rdpContext* context, const PLAY_SOUND_UPDATE* play_so
return TRUE; return TRUE;
} }
static BOOL sdl_wait_for_init(sdlContext* sdl) static BOOL sdl_wait_for_init(SdlContext* sdl)
{ {
WINPR_ASSERT(sdl); WINPR_ASSERT(sdl);
WINPR_ASSERT(sdl->initialize); sdl->initialize.set();
sdl->initialize->set();
HANDLE handles[] = { sdl->initialized->handle(), freerdp_abort_event(&sdl->common.context) }; HANDLE handles[] = { sdl->initialized.handle(), freerdp_abort_event(sdl->context()) };
const DWORD rc = WaitForMultipleObjects(ARRAYSIZE(handles), handles, FALSE, INFINITE); const DWORD rc = WaitForMultipleObjects(ARRAYSIZE(handles), handles, FALSE, INFINITE);
switch (rc) switch (rc)
@ -505,7 +503,7 @@ static BOOL sdl_pre_connect(freerdp* instance)
WINPR_ASSERT(instance); WINPR_ASSERT(instance);
WINPR_ASSERT(instance->context); WINPR_ASSERT(instance->context);
auto sdl = reinterpret_cast<sdlContext*>(instance->context); auto sdl = get_context(instance->context);
sdl->highDpi = TRUE; // If High DPI is available, we want unscaled data, RDP can scale itself. sdl->highDpi = TRUE; // If High DPI is available, we want unscaled data, RDP can scale itself.
auto settings = instance->context->settings; auto settings = instance->context->settings;
@ -592,44 +590,36 @@ static const char* sdl_window_get_title(rdpSettings* settings)
return freerdp_settings_get_string(settings, FreeRDP_WindowTitle); return freerdp_settings_get_string(settings, FreeRDP_WindowTitle);
} }
static void sdl_cleanup_sdl(sdlContext* sdl) static void sdl_cleanup_sdl(SdlContext* sdl)
{ {
const sdl_window_t empty = {};
if (!sdl) if (!sdl)
return; return;
for (size_t x = 0; x < sdl->windowCount; x++) for (auto& window : sdl->windows)
{ SDL_DestroyWindow(window.window);
sdl_window_t* window = &sdl->windows[x];
SDL_DestroyWindow(window->window);
*window = empty;
}
sdl_destroy_primary(sdl); sdl_destroy_primary(sdl);
sdl->windowCount = 0; sdl->windows.clear();
SDL_Quit(); SDL_Quit();
} }
static BOOL sdl_create_windows(sdlContext* sdl) static BOOL sdl_create_windows(SdlContext* sdl)
{ {
WINPR_ASSERT(sdl); WINPR_ASSERT(sdl);
const char* title = sdl_window_get_title(sdl->common.context.settings); auto title = sdl_window_get_title(sdl->context()->settings);
BOOL rc = FALSE; BOOL rc = FALSE;
// TODO: Multimonitor setup // TODO: Multimonitor setup
sdl->windowCount = 1; const size_t windowCount = 1;
const UINT32 w = const UINT32 w = freerdp_settings_get_uint32(sdl->context()->settings, FreeRDP_DesktopWidth);
freerdp_settings_get_uint32(sdl->common.context.settings, FreeRDP_DesktopWidth); const UINT32 h = freerdp_settings_get_uint32(sdl->context()->settings, FreeRDP_DesktopHeight);
const UINT32 h =
freerdp_settings_get_uint32(sdl->common.context.settings, FreeRDP_DesktopHeight);
sdl_window_t* window = nullptr; for (size_t x = 0; x < windowCount; x++)
for (size_t x = 0; x < sdl->windowCount; x++)
{ {
sdl_window_t window = {};
Uint32 flags = SDL_WINDOW_SHOWN; Uint32 flags = SDL_WINDOW_SHOWN;
if (sdl->highDpi) if (sdl->highDpi)
@ -639,32 +629,31 @@ static BOOL sdl_create_windows(sdlContext* sdl)
#endif #endif
} }
if (sdl->common.context.settings->Fullscreen || sdl->common.context.settings->UseMultimon) if (sdl->context()->settings->Fullscreen || sdl->context()->settings->UseMultimon)
flags |= SDL_WINDOW_FULLSCREEN; flags |= SDL_WINDOW_FULLSCREEN;
window = &sdl->windows[x]; window.window = SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
static_cast<int>(w), static_cast<int>(h), flags);
window->window = SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, if (!window.window)
static_cast<int>(w), static_cast<int>(h), flags);
if (!window->window)
goto fail; goto fail;
sdl->windows.push_back(window);
} }
rc = TRUE; rc = TRUE;
fail: fail:
sdl->windows_created->set(); sdl->windows_created.set();
return rc; return rc;
} }
static BOOL sdl_wait_create_windows(sdlContext* sdl) static BOOL sdl_wait_create_windows(SdlContext* sdl)
{ {
std::lock_guard<CriticalSection> lock(*sdl->critical); std::lock_guard<CriticalSection> lock(sdl->critical);
sdl->windows_created->clear(); sdl->windows_created.clear();
if (!sdl_push_user_event(SDL_USEREVENT_CREATE_WINDOWS, sdl)) if (!sdl_push_user_event(SDL_USEREVENT_CREATE_WINDOWS, sdl))
return FALSE; return FALSE;
HANDLE handles[] = { sdl->initialized->handle(), freerdp_abort_event(&sdl->common.context) }; HANDLE handles[] = { sdl->initialized.handle(), freerdp_abort_event(sdl->context()) };
const DWORD rc = WaitForMultipleObjects(ARRAYSIZE(handles), handles, FALSE, INFINITE); const DWORD rc = WaitForMultipleObjects(ARRAYSIZE(handles), handles, FALSE, INFINITE);
switch (rc) switch (rc)
@ -676,12 +665,12 @@ static BOOL sdl_wait_create_windows(sdlContext* sdl)
} }
} }
static int sdl_run(sdlContext* sdl) static int sdl_run(SdlContext* sdl)
{ {
int rc = -1; int rc = -1;
WINPR_ASSERT(sdl); WINPR_ASSERT(sdl);
HANDLE handles[] = { sdl->initialize->handle(), freerdp_abort_event(&sdl->common.context) }; HANDLE handles[] = { sdl->initialize.handle(), freerdp_abort_event(sdl->context()) };
const DWORD status = WaitForMultipleObjects(ARRAYSIZE(handles), handles, FALSE, INFINITE); const DWORD status = WaitForMultipleObjects(ARRAYSIZE(handles), handles, FALSE, INFINITE);
switch (status) switch (status)
{ {
@ -692,30 +681,28 @@ static int sdl_run(sdlContext* sdl)
} }
SDL_Init(SDL_INIT_VIDEO); SDL_Init(SDL_INIT_VIDEO);
sdl->initialized->set(); sdl->initialized.set();
while (!freerdp_shall_disconnect_context(&sdl->common.context)) while (!freerdp_shall_disconnect_context(sdl->context()))
{ {
SDL_Event windowEvent = { 0 }; SDL_Event windowEvent = { 0 };
while (!freerdp_shall_disconnect_context(&sdl->common.context) && while (!freerdp_shall_disconnect_context(sdl->context()) && SDL_WaitEvent(&windowEvent))
SDL_WaitEvent(&windowEvent))
{ {
#if defined(WITH_DEBUG_SDL_EVENTS) #if defined(WITH_DEBUG_SDL_EVENTS)
SDL_Log("got event %s [0x%08" PRIx32 "]", sdl_event_type_str(windowEvent.type), SDL_Log("got event %s [0x%08" PRIx32 "]", sdl_event_type_str(windowEvent.type),
windowEvent.type); windowEvent.type);
#endif #endif
std::lock_guard<CriticalSection> lock(*sdl->critical); std::lock_guard<CriticalSection> lock(sdl->critical);
switch (windowEvent.type) switch (windowEvent.type)
{ {
case SDL_QUIT: case SDL_QUIT:
freerdp_abort_connect_context(&sdl->common.context); freerdp_abort_connect_context(sdl->context());
break; break;
case SDL_KEYDOWN: case SDL_KEYDOWN:
case SDL_KEYUP: case SDL_KEYUP:
{ {
const SDL_KeyboardEvent* ev = &windowEvent.key; const SDL_KeyboardEvent* ev = &windowEvent.key;
WINPR_ASSERT(sdl->input); sdl->input.keyboard_handle_event(ev);
sdl->input->keyboard_handle_event(ev);
} }
break; break;
case SDL_KEYMAPCHANGED: case SDL_KEYMAPCHANGED:
@ -763,16 +750,14 @@ static int sdl_run(sdlContext* sdl)
case SDL_DISPLAYEVENT: case SDL_DISPLAYEVENT:
{ {
const SDL_DisplayEvent* ev = &windowEvent.display; const SDL_DisplayEvent* ev = &windowEvent.display;
if (sdl->disp) sdl->disp.handle_display_event(ev);
sdl->disp->handle_display_event(ev);
} }
break; break;
#endif #endif
case SDL_WINDOWEVENT: case SDL_WINDOWEVENT:
{ {
const SDL_WindowEvent* ev = &windowEvent.window; const SDL_WindowEvent* ev = &windowEvent.window;
if (sdl->disp) sdl->disp.handle_window_event(ev);
sdl->disp->handle_window_event(ev);
} }
break; break;
@ -793,7 +778,7 @@ static int sdl_run(sdlContext* sdl)
break; break;
case SDL_USEREVENT_CREATE_WINDOWS: case SDL_USEREVENT_CREATE_WINDOWS:
{ {
auto ctx = static_cast<sdlContext*>(windowEvent.user.data1); auto ctx = static_cast<SdlContext*>(windowEvent.user.data1);
sdl_create_windows(ctx); sdl_create_windows(ctx);
} }
break; break;
@ -861,7 +846,6 @@ static int sdl_run(sdlContext* sdl)
rc = 1; rc = 1;
fail:
sdl_cleanup_sdl(sdl); sdl_cleanup_sdl(sdl);
return rc; return rc;
} }
@ -881,7 +865,7 @@ static BOOL sdl_post_connect(freerdp* instance)
auto context = instance->context; auto context = instance->context;
WINPR_ASSERT(context); WINPR_ASSERT(context);
auto sdl = reinterpret_cast<sdlContext*>(context); auto sdl = get_context(context);
if (freerdp_settings_get_bool(context->settings, FreeRDP_AuthenticationOnly)) if (freerdp_settings_get_bool(context->settings, FreeRDP_AuthenticationOnly))
{ {
@ -906,14 +890,6 @@ static BOOL sdl_post_connect(freerdp* instance)
if (!sdl_create_primary(sdl)) if (!sdl_create_primary(sdl))
return FALSE; return FALSE;
sdl->disp = std::make_unique<sdlDispContext>(sdl);
if (!sdl->disp)
return FALSE;
sdl->input = std::make_unique<sdlInput>(sdl);
if (!sdl->input)
return FALSE;
if (!sdl_register_pointer(instance->context->graphics)) if (!sdl_register_pointer(instance->context->graphics))
return FALSE; return FALSE;
@ -942,7 +918,7 @@ static void sdl_post_disconnect(freerdp* instance)
if (!instance->context) if (!instance->context)
return; return;
auto context = reinterpret_cast<sdlContext*>(instance->context); auto context = get_context(instance->context);
PubSub_UnsubscribeChannelConnected(instance->context->pubSub, PubSub_UnsubscribeChannelConnected(instance->context->pubSub,
sdl_OnChannelConnectedEventHandler); sdl_OnChannelConnectedEventHandler);
PubSub_UnsubscribeChannelDisconnected(instance->context->pubSub, PubSub_UnsubscribeChannelDisconnected(instance->context->pubSub,
@ -959,18 +935,13 @@ static void sdl_post_final_disconnect(freerdp* instance)
if (!instance->context) if (!instance->context)
return; return;
auto context = reinterpret_cast<sdlContext*>(instance->context);
context->disp.reset();
context->input.reset();
} }
/* RDP main loop. /* RDP main loop.
* Connects RDP, loops while running and handles event and dispatch, cleans up * Connects RDP, loops while running and handles event and dispatch, cleans up
* after the connection ends. */ * after the connection ends. */
static DWORD WINAPI sdl_client_thread_proc(void* arg) static DWORD WINAPI sdl_client_thread_proc(SdlContext* sdl)
{ {
auto sdl = static_cast<sdlContext*>(arg);
DWORD nCount; DWORD nCount;
DWORD status; DWORD status;
int exit_code = SDL_EXIT_SUCCESS; int exit_code = SDL_EXIT_SUCCESS;
@ -978,12 +949,12 @@ static DWORD WINAPI sdl_client_thread_proc(void* arg)
WINPR_ASSERT(sdl); WINPR_ASSERT(sdl);
freerdp* instance = sdl->common.context.instance; auto instance = sdl->context()->instance;
WINPR_ASSERT(instance); WINPR_ASSERT(instance);
BOOL rc = freerdp_connect(instance); BOOL rc = freerdp_connect(instance);
rdpContext* context = &sdl->common.context; rdpContext* context = sdl->context();
rdpSettings* settings = context->settings; rdpSettings* settings = context->settings;
WINPR_ASSERT(settings); WINPR_ASSERT(settings);
@ -1026,12 +997,11 @@ static DWORD WINAPI sdl_client_thread_proc(void* arg)
*/ */
if (freerdp_focus_required(instance)) if (freerdp_focus_required(instance))
{ {
sdlContext* ctx = reinterpret_cast<sdlContext*>(context); auto ctx = get_context(context);
WINPR_ASSERT(ctx); WINPR_ASSERT(ctx);
WINPR_ASSERT(ctx->input); if (!ctx->input.keyboard_focus_in())
if (!ctx->input->keyboard_focus_in())
break; break;
if (!ctx->input->keyboard_focus_in()) if (!ctx->input.keyboard_focus_in())
break; break;
} }
@ -1143,7 +1113,7 @@ static int sdl_logon_error_info(freerdp* instance, UINT32 data, UINT32 type)
if (!instance || !instance->context) if (!instance || !instance->context)
return -1; return -1;
auto sdl = reinterpret_cast<sdlContext*>(instance->context); auto sdl = get_context(instance->context);
WLog_Print(sdl->log, WLOG_INFO, "Logon Error Info %s [%s]", str_data, str_type); WLog_Print(sdl->log, WLOG_INFO, "Logon Error Info %s [%s]", str_data, str_type);
return 1; return 1;
@ -1151,12 +1121,14 @@ static int sdl_logon_error_info(freerdp* instance, UINT32 data, UINT32 type)
static BOOL sdl_client_new(freerdp* instance, rdpContext* context) static BOOL sdl_client_new(freerdp* instance, rdpContext* context)
{ {
auto sdl = reinterpret_cast<sdlContext*>(context); auto sdl = reinterpret_cast<sdl_rdp_context*>(context);
if (!instance || !context) if (!instance || !context)
return FALSE; return FALSE;
sdl->log = WLog_Get(SDL_TAG); sdl->sdl = new SdlContext(context);
if (!sdl->sdl)
return FALSE;
instance->PreConnect = sdl_pre_connect; instance->PreConnect = sdl_pre_connect;
instance->PostConnect = sdl_post_connect; instance->PostConnect = sdl_post_connect;
@ -1173,31 +1145,22 @@ static BOOL sdl_client_new(freerdp* instance, rdpContext* context)
#endif #endif
/* TODO: Client display set up */ /* TODO: Client display set up */
sdl->critical = std::make_unique<CriticalSection>(); return TRUE;
sdl->initialize = std::make_unique<WinPREvent>();
sdl->initialized = std::make_unique<WinPREvent>();
sdl->update_complete = std::make_unique<WinPREvent>(true);
sdl->windows_created = std::make_unique<WinPREvent>();
return sdl->initialize && sdl->initialized && sdl->update_complete && sdl->windows_created;
} }
static void sdl_client_free(freerdp* instance, rdpContext* context) static void sdl_client_free(freerdp* instance, rdpContext* context)
{ {
auto sdl = reinterpret_cast<sdlContext*>(instance->context); auto sdl = reinterpret_cast<sdl_rdp_context*>(context);
if (!context) if (!context)
return; return;
sdl->initialize.reset(); delete sdl->sdl;
sdl->initialized.reset();
sdl->update_complete.reset();
sdl->windows_created.reset();
sdl->critical.reset();
} }
static int sdl_client_start(rdpContext* context) static int sdl_client_start(rdpContext* context)
{ {
auto sdl = reinterpret_cast<sdlContext*>(context); auto sdl = get_context(context);
WINPR_ASSERT(sdl); WINPR_ASSERT(sdl);
sdl->thread = std::thread(sdl_client_thread_proc, sdl); sdl->thread = std::thread(sdl_client_thread_proc, sdl);
@ -1206,7 +1169,7 @@ static int sdl_client_start(rdpContext* context)
static int sdl_client_stop(rdpContext* context) static int sdl_client_stop(rdpContext* context)
{ {
auto sdl = reinterpret_cast<sdlContext*>(context); auto sdl = get_context(context);
WINPR_ASSERT(sdl); WINPR_ASSERT(sdl);
/* We do not want to use freerdp_abort_connect_context here. /* We do not want to use freerdp_abort_connect_context here.
@ -1228,7 +1191,7 @@ static int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints)
pEntryPoints->Size = sizeof(RDP_CLIENT_ENTRY_POINTS_V1); pEntryPoints->Size = sizeof(RDP_CLIENT_ENTRY_POINTS_V1);
pEntryPoints->GlobalInit = sdl_client_global_init; pEntryPoints->GlobalInit = sdl_client_global_init;
pEntryPoints->GlobalUninit = sdl_client_global_uninit; pEntryPoints->GlobalUninit = sdl_client_global_uninit;
pEntryPoints->ContextSize = sizeof(sdlContext); pEntryPoints->ContextSize = sizeof(sdl_rdp_context);
pEntryPoints->ClientNew = sdl_client_new; pEntryPoints->ClientNew = sdl_client_new;
pEntryPoints->ClientFree = sdl_client_free; pEntryPoints->ClientFree = sdl_client_free;
pEntryPoints->ClientStart = sdl_client_start; pEntryPoints->ClientStart = sdl_client_start;
@ -1236,7 +1199,7 @@ static int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints)
return 0; return 0;
} }
static void context_free(sdlContext* sdl) static void context_free(sdl_rdp_context* sdl)
{ {
if (sdl) if (sdl)
freerdp_client_context_free(&sdl->common.context); freerdp_client_context_free(&sdl->common.context);
@ -1246,20 +1209,20 @@ int main(int argc, char* argv[])
{ {
int rc = -1; int rc = -1;
int status; int status;
rdpContext* context = nullptr;
RDP_CLIENT_ENTRY_POINTS clientEntryPoints = {}; RDP_CLIENT_ENTRY_POINTS clientEntryPoints = {};
freerdp_client_warn_experimental(argc, argv); freerdp_client_warn_experimental(argc, argv);
RdpClientEntry(&clientEntryPoints); RdpClientEntry(&clientEntryPoints);
std::unique_ptr<sdlContext, void (*)(sdlContext*)> sdl( std::unique_ptr<sdl_rdp_context, void (*)(sdl_rdp_context*)> sdl_rdp(
reinterpret_cast<sdlContext*>(freerdp_client_context_new(&clientEntryPoints)), reinterpret_cast<sdl_rdp_context*>(freerdp_client_context_new(&clientEntryPoints)),
context_free); context_free);
if (!sdl) if (!sdl_rdp)
return -1; return -1;
auto sdl = sdl_rdp->sdl;
rdpSettings* settings = sdl->common.context.settings; auto settings = sdl->context()->settings;
WINPR_ASSERT(settings); WINPR_ASSERT(settings);
status = freerdp_client_settings_parse_command_line(settings, argc, argv, FALSE); status = freerdp_client_settings_parse_command_line(settings, argc, argv, FALSE);
@ -1267,11 +1230,11 @@ int main(int argc, char* argv[])
{ {
rc = freerdp_client_settings_command_line_status_print(settings, status, argc, argv); rc = freerdp_client_settings_command_line_status_print(settings, status, argc, argv);
if (settings->ListMonitors) if (settings->ListMonitors)
sdl_list_monitors(sdl.get()); sdl_list_monitors(sdl);
return rc; return rc;
} }
context = &sdl->common.context; auto context = sdl->context();
WINPR_ASSERT(context); WINPR_ASSERT(context);
if (!stream_dump_register_handlers(context, CONNECTION_STATE_MCS_CREATE_REQUEST, FALSE)) if (!stream_dump_register_handlers(context, CONNECTION_STATE_MCS_CREATE_REQUEST, FALSE))
@ -1280,7 +1243,7 @@ int main(int argc, char* argv[])
if (freerdp_client_start(context) != 0) if (freerdp_client_start(context) != 0)
return -1; return -1;
rc = sdl_run(sdl.get()); rc = sdl_run(sdl);
if (freerdp_client_stop(context) != 0) if (freerdp_client_stop(context) != 0)
return -1; return -1;
@ -1290,35 +1253,49 @@ int main(int argc, char* argv[])
return rc; return rc;
} }
BOOL sdl_context::update_fullscreen(BOOL enter) BOOL SdlContext::update_fullscreen(BOOL enter)
{ {
std::lock_guard<CriticalSection> lock(*critical); std::lock_guard<CriticalSection> lock(critical);
for (uint32_t x = 0; x < windowCount; x++) for (const auto& window : windows)
{ {
sdl_window_t* window = &windows[x]; if (!sdl_push_user_event(SDL_USEREVENT_WINDOW_FULLSCREEN, window.window, enter))
if (!sdl_push_user_event(SDL_USEREVENT_WINDOW_FULLSCREEN, window->window, enter))
return FALSE; return FALSE;
} }
fullscreen = enter; fullscreen = enter;
return TRUE; return TRUE;
} }
BOOL sdl_context::update_resizeable(BOOL enable) BOOL SdlContext::update_resizeable(BOOL enable)
{ {
std::lock_guard<CriticalSection> lock(*critical); std::lock_guard<CriticalSection> lock(critical);
const rdpSettings* settings = common.context.settings; const auto settings = context()->settings;
const BOOL dyn = freerdp_settings_get_bool(settings, FreeRDP_DynamicResolutionUpdate); const BOOL dyn = freerdp_settings_get_bool(settings, FreeRDP_DynamicResolutionUpdate);
const BOOL smart = freerdp_settings_get_bool(settings, FreeRDP_SmartSizing); const BOOL smart = freerdp_settings_get_bool(settings, FreeRDP_SmartSizing);
BOOL use = (dyn && enable) || smart; BOOL use = (dyn && enable) || smart;
for (uint32_t x = 0; x < windowCount; x++) for (const auto& window : windows)
{ {
sdl_window_t* window = &windows[x]; if (!sdl_push_user_event(SDL_USEREVENT_WINDOW_RESIZEABLE, window.window, use))
if (!sdl_push_user_event(SDL_USEREVENT_WINDOW_RESIZEABLE, window->window, use))
return FALSE; return FALSE;
} }
resizeable = use; resizeable = use;
return TRUE; return TRUE;
} }
SdlContext::SdlContext(rdpContext* context)
: _context(context), log(WLog_Get(SDL_TAG)), update_complete(true), disp(this), input(this),
primary(nullptr, SDL_FreeSurface), primary_format(nullptr, SDL_FreeFormat)
{
}
rdpContext* SdlContext::context() const
{
return _context;
}
rdpClientContext* SdlContext::common() const
{
return reinterpret_cast<rdpClientContext*>(_context);
}

View File

@ -21,6 +21,7 @@
#include <memory> #include <memory>
#include <thread> #include <thread>
#include <vector>
#include <freerdp/freerdp.h> #include <freerdp/freerdp.h>
#include <freerdp/client/rdpei.h> #include <freerdp/client/rdpei.h>
@ -46,38 +47,46 @@ typedef struct
using SDLSurfacePtr = std::unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)>; using SDLSurfacePtr = std::unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)>;
using SDLPixelFormatPtr = std::unique_ptr<SDL_PixelFormat, decltype(&SDL_FreeFormat)>; using SDLPixelFormatPtr = std::unique_ptr<SDL_PixelFormat, decltype(&SDL_FreeFormat)>;
struct sdl_context class SdlContext
{ {
rdpClientContext common; public:
SdlContext(rdpContext* context);
private:
rdpContext* _context;
public:
wLog* log;
/* SDL */ /* SDL */
BOOL fullscreen; bool fullscreen = false;
BOOL resizeable; bool resizeable = false;
BOOL grab_mouse; bool grab_mouse = false;
BOOL grab_kbd; bool grab_kbd = false;
BOOL highDpi; bool highDpi = false;
size_t windowCount; std::vector<sdl_window_t> windows;
sdl_window_t windows[16];
std::unique_ptr<CriticalSection> critical; CriticalSection critical;
std::thread thread; std::thread thread;
std::unique_ptr<WinPREvent> initialize; WinPREvent initialize;
std::unique_ptr<WinPREvent> initialized; WinPREvent initialized;
std::unique_ptr<WinPREvent> update_complete; WinPREvent update_complete;
std::unique_ptr<WinPREvent> windows_created; WinPREvent windows_created;
int exit_code; int exit_code = -1;
sdlDispContext disp;
sdlInput input;
SDLSurfacePtr primary; SDLSurfacePtr primary;
SDLPixelFormatPtr primary_format; SDLPixelFormatPtr primary_format;
std::unique_ptr<sdlDispContext> disp; Uint32 sdl_pixel_format = 0;
std::unique_ptr<sdlInput> input;
Uint32 sdl_pixel_format;
wLog* log;
public:
BOOL update_resizeable(BOOL enable); BOOL update_resizeable(BOOL enable);
BOOL update_fullscreen(BOOL enter); BOOL update_fullscreen(BOOL enter);
rdpContext* context() const;
rdpClientContext* common() const;
}; };

View File

@ -311,12 +311,12 @@ static UINT32 sdl_get_kbd_flags(void)
BOOL sdlInput::keyboard_sync_state() BOOL sdlInput::keyboard_sync_state()
{ {
const UINT32 syncFlags = sdl_get_kbd_flags(); const UINT32 syncFlags = sdl_get_kbd_flags();
return freerdp_input_send_synchronize_event(_sdl->common.context.input, syncFlags); return freerdp_input_send_synchronize_event(_sdl->context()->input, syncFlags);
} }
BOOL sdlInput::keyboard_focus_in() BOOL sdlInput::keyboard_focus_in()
{ {
auto input = _sdl->common.context.input; auto input = _sdl->context()->input;
WINPR_ASSERT(input); WINPR_ASSERT(input);
auto syncFlags = sdl_get_kbd_flags(); auto syncFlags = sdl_get_kbd_flags();
@ -454,7 +454,7 @@ BOOL sdlInput::keyboard_handle_event(const SDL_KeyboardEvent* ev)
break; break;
} }
} }
return freerdp_input_send_keyboard_event_ex(_sdl->common.context.input, ev->type == SDL_KEYDOWN, return freerdp_input_send_keyboard_event_ex(_sdl->context()->input, ev->type == SDL_KEYDOWN,
ev->repeat, rdp_scancode); ev->repeat, rdp_scancode);
} }
@ -489,7 +489,7 @@ BOOL sdlInput::mouse_grab(Uint32 windowID, SDL_bool enable)
#endif #endif
} }
sdlInput::sdlInput(sdlContext* sdl) : _sdl(sdl) sdlInput::sdlInput(SdlContext* sdl) : _sdl(sdl)
{ {
WINPR_ASSERT(_sdl); WINPR_ASSERT(_sdl);
} }

View File

@ -28,7 +28,7 @@
class sdlInput class sdlInput
{ {
public: public:
sdlInput(sdlContext* sdl); sdlInput(SdlContext* sdl);
~sdlInput(); ~sdlInput();
BOOL keyboard_sync_state(); BOOL keyboard_sync_state();
@ -45,5 +45,5 @@ class sdlInput
UINT32 imeConvMode); UINT32 imeConvMode);
private: private:
sdlContext* _sdl; SdlContext* _sdl;
}; };

View File

@ -55,7 +55,7 @@ typedef struct
/* See MSDN Section on Multiple Display Monitors: http://msdn.microsoft.com/en-us/library/dd145071 /* See MSDN Section on Multiple Display Monitors: http://msdn.microsoft.com/en-us/library/dd145071
*/ */
int sdl_list_monitors(sdlContext* sdl) int sdl_list_monitors(SdlContext* sdl)
{ {
SDL_Init(SDL_INIT_VIDEO); SDL_Init(SDL_INIT_VIDEO);
const int nmonitors = SDL_GetNumVideoDisplays(); const int nmonitors = SDL_GetNumVideoDisplays();
@ -77,14 +77,14 @@ int sdl_list_monitors(sdlContext* sdl)
return 0; return 0;
} }
static BOOL sdl_is_monitor_id_active(sdlContext* sdl, UINT32 id) static BOOL sdl_is_monitor_id_active(SdlContext* sdl, UINT32 id)
{ {
UINT32 index; UINT32 index;
const rdpSettings* settings; const rdpSettings* settings;
WINPR_ASSERT(sdl); WINPR_ASSERT(sdl);
settings = sdl->common.context.settings; settings = sdl->context()->settings;
WINPR_ASSERT(settings); WINPR_ASSERT(settings);
if (!settings->NumMonitorIds) if (!settings->NumMonitorIds)
@ -99,13 +99,13 @@ static BOOL sdl_is_monitor_id_active(sdlContext* sdl, UINT32 id)
return FALSE; return FALSE;
} }
static BOOL sdl_apply_max_size(sdlContext* sdl, UINT32* pMaxWidth, UINT32* pMaxHeight) static BOOL sdl_apply_max_size(SdlContext* sdl, UINT32* pMaxWidth, UINT32* pMaxHeight)
{ {
WINPR_ASSERT(sdl); WINPR_ASSERT(sdl);
WINPR_ASSERT(pMaxWidth); WINPR_ASSERT(pMaxWidth);
WINPR_ASSERT(pMaxHeight); WINPR_ASSERT(pMaxHeight);
rdpSettings* settings = sdl->common.context.settings; auto settings = sdl->context()->settings;
WINPR_ASSERT(settings); WINPR_ASSERT(settings);
*pMaxWidth = 0; *pMaxWidth = 0;
@ -168,11 +168,11 @@ static UINT32 sdl_orientaion_to_rdp(SDL_DisplayOrientation orientation)
} }
#endif #endif
static BOOL sdl_apply_display_properties(sdlContext* sdl) static BOOL sdl_apply_display_properties(SdlContext* sdl)
{ {
WINPR_ASSERT(sdl); WINPR_ASSERT(sdl);
rdpSettings* settings = sdl->common.context.settings; rdpSettings* settings = sdl->context()->settings;
WINPR_ASSERT(settings); WINPR_ASSERT(settings);
const UINT32 numIds = freerdp_settings_get_uint32(settings, FreeRDP_NumMonitorIds); const UINT32 numIds = freerdp_settings_get_uint32(settings, FreeRDP_NumMonitorIds);
@ -251,13 +251,13 @@ static BOOL sdl_apply_display_properties(sdlContext* sdl)
return TRUE; return TRUE;
} }
static BOOL sdl_detect_single_window(sdlContext* sdl, UINT32* pMaxWidth, UINT32* pMaxHeight) static BOOL sdl_detect_single_window(SdlContext* sdl, UINT32* pMaxWidth, UINT32* pMaxHeight)
{ {
WINPR_ASSERT(sdl); WINPR_ASSERT(sdl);
WINPR_ASSERT(pMaxWidth); WINPR_ASSERT(pMaxWidth);
WINPR_ASSERT(pMaxHeight); WINPR_ASSERT(pMaxHeight);
rdpSettings* settings = sdl->common.context.settings; rdpSettings* settings = sdl->context()->settings;
WINPR_ASSERT(settings); WINPR_ASSERT(settings);
if ((!settings->UseMultimon && !settings->SpanMonitors) || if ((!settings->UseMultimon && !settings->SpanMonitors) ||
@ -268,7 +268,7 @@ static BOOL sdl_detect_single_window(sdlContext* sdl, UINT32* pMaxWidth, UINT32*
if (!settings->NumMonitorIds) if (!settings->NumMonitorIds)
{ {
const size_t id = const size_t id =
(sdl->windowCount > 0) ? SDL_GetWindowDisplayIndex(sdl->windows[0].window) : 0; (sdl->windows.size() > 0) ? SDL_GetWindowDisplayIndex(sdl->windows[0].window) : 0;
if (!freerdp_settings_set_pointer_len(settings, FreeRDP_MonitorIds, &id, 1)) if (!freerdp_settings_set_pointer_len(settings, FreeRDP_MonitorIds, &id, 1))
return FALSE; return FALSE;
} }
@ -290,13 +290,13 @@ static BOOL sdl_detect_single_window(sdlContext* sdl, UINT32* pMaxWidth, UINT32*
return TRUE; return TRUE;
} }
BOOL sdl_detect_monitors(sdlContext* sdl, UINT32* pMaxWidth, UINT32* pMaxHeight) BOOL sdl_detect_monitors(SdlContext* sdl, UINT32* pMaxWidth, UINT32* pMaxHeight)
{ {
WINPR_ASSERT(sdl); WINPR_ASSERT(sdl);
WINPR_ASSERT(pMaxWidth); WINPR_ASSERT(pMaxWidth);
WINPR_ASSERT(pMaxHeight); WINPR_ASSERT(pMaxHeight);
rdpSettings* settings = sdl->common.context.settings; rdpSettings* settings = sdl->context()->settings;
WINPR_ASSERT(settings); WINPR_ASSERT(settings);
const int numDisplays = SDL_GetNumVideoDisplays(); const int numDisplays = SDL_GetNumVideoDisplays();

View File

@ -24,5 +24,5 @@
#include "sdl_types.hpp" #include "sdl_types.hpp"
int sdl_list_monitors(sdlContext* sdl); int sdl_list_monitors(SdlContext* sdl);
BOOL sdl_detect_monitors(sdlContext* sdl, UINT32* pWidth, UINT32* pHeight); BOOL sdl_detect_monitors(SdlContext* sdl, UINT32* pWidth, UINT32* pHeight);

View File

@ -100,7 +100,7 @@ static BOOL sdl_Pointer_SetDefault(rdpContext* context)
static BOOL sdl_Pointer_Set(rdpContext* context, rdpPointer* pointer) static BOOL sdl_Pointer_Set(rdpContext* context, rdpPointer* pointer)
{ {
auto sdl = reinterpret_cast<sdlContext*>(context); auto sdl = get_context(context);
return sdl_push_user_event(SDL_USEREVENT_POINTER_SET, pointer, sdl); return sdl_push_user_event(SDL_USEREVENT_POINTER_SET, pointer, sdl);
} }
@ -111,10 +111,10 @@ BOOL sdl_Pointer_Set_Process(SDL_UserEvent* uptr)
WINPR_ASSERT(uptr); WINPR_ASSERT(uptr);
auto sdl = static_cast<sdlContext*>(uptr->data2); auto sdl = static_cast<SdlContext*>(uptr->data2);
WINPR_ASSERT(sdl); WINPR_ASSERT(sdl);
rdpContext* context = &sdl->common.context; auto context = sdl->context();
auto ptr = static_cast<sdlPointer*>(uptr->data1); auto ptr = static_cast<sdlPointer*>(uptr->data1);
WINPR_ASSERT(ptr); WINPR_ASSERT(ptr);
@ -175,7 +175,7 @@ static BOOL sdl_Pointer_SetNull(rdpContext* context)
static BOOL sdl_Pointer_SetPosition(rdpContext* context, UINT32 x, UINT32 y) static BOOL sdl_Pointer_SetPosition(rdpContext* context, UINT32 x, UINT32 y)
{ {
auto sdl = reinterpret_cast<sdlContext*>(context); auto sdl = get_context(context);
WINPR_ASSERT(sdl); WINPR_ASSERT(sdl);
return sdl_push_user_event(SDL_USEREVENT_POINTER_POSITION, x, y); return sdl_push_user_event(SDL_USEREVENT_POINTER_POSITION, x, y);

View File

@ -32,20 +32,20 @@
#define TAG CLIENT_TAG("SDL.touch") #define TAG CLIENT_TAG("SDL.touch")
BOOL sdl_scale_coordinates(sdlContext* sdl, Uint32 windowId, INT32* px, INT32* py, BOOL sdl_scale_coordinates(SdlContext* sdl, Uint32 windowId, INT32* px, INT32* py,
BOOL fromLocalToRDP, BOOL applyOffset) BOOL fromLocalToRDP, BOOL applyOffset)
{ {
rdpGdi* gdi; rdpGdi* gdi;
double sx = 1.0; double sx = 1.0;
double sy = 1.0; double sy = 1.0;
if (!sdl || !px || !py || !sdl->common.context.gdi) if (!sdl || !px || !py || !sdl->context()->gdi)
return FALSE; return FALSE;
WINPR_ASSERT(sdl->common.context.gdi); WINPR_ASSERT(sdl->context()->gdi);
WINPR_ASSERT(sdl->common.context.settings); WINPR_ASSERT(sdl->context()->settings);
gdi = sdl->common.context.gdi; gdi = sdl->context()->gdi;
// TODO: Make this multimonitor ready! // TODO: Make this multimonitor ready!
// TODO: Need to find the primary monitor, get the scale // TODO: Need to find the primary monitor, get the scale
@ -54,25 +54,24 @@ BOOL sdl_scale_coordinates(sdlContext* sdl, Uint32 windowId, INT32* px, INT32* p
int offset_x = 0; int offset_x = 0;
int offset_y = 0; int offset_y = 0;
for (size_t x = 0; x < sdl->windowCount; x++) for (const auto& window : sdl->windows)
{ {
int w, h; int w, h;
const sdl_window_t* window = &sdl->windows[x]; const Uint32 id = SDL_GetWindowID(window.window);
const Uint32 id = SDL_GetWindowID(window->window);
if (id != windowId) if (id != windowId)
{ {
continue; continue;
} }
SDL_GetWindowSize(window->window, &w, &h); SDL_GetWindowSize(window.window, &w, &h);
sx = w / static_cast<double>(gdi->width); sx = w / static_cast<double>(gdi->width);
sy = h / static_cast<double>(gdi->height); sy = h / static_cast<double>(gdi->height);
offset_x = window->offset_x; offset_x = window.offset_x;
offset_y = window->offset_y; offset_y = window.offset_y;
break; break;
} }
if (sdl->common.context.settings->SmartSizing) if (sdl->context()->settings->SmartSizing)
{ {
if (!fromLocalToRDP) if (!fromLocalToRDP)
{ {
@ -94,7 +93,7 @@ BOOL sdl_scale_coordinates(sdlContext* sdl, Uint32 windowId, INT32* px, INT32* p
return TRUE; return TRUE;
} }
static BOOL sdl_get_touch_scaled(sdlContext* sdl, const SDL_TouchFingerEvent* ev, INT32* px, static BOOL sdl_get_touch_scaled(SdlContext* sdl, const SDL_TouchFingerEvent* ev, INT32* px,
INT32* py, BOOL local) INT32* py, BOOL local)
{ {
Uint32 windowID; Uint32 windowID;
@ -124,7 +123,7 @@ static BOOL sdl_get_touch_scaled(sdlContext* sdl, const SDL_TouchFingerEvent* ev
return sdl_scale_coordinates(sdl, windowID, px, py, local, TRUE); return sdl_scale_coordinates(sdl, windowID, px, py, local, TRUE);
} }
static BOOL send_mouse_wheel(sdlContext* sdl, UINT16 flags, INT32 avalue) static BOOL send_mouse_wheel(SdlContext* sdl, UINT16 flags, INT32 avalue)
{ {
WINPR_ASSERT(sdl); WINPR_ASSERT(sdl);
if (avalue < 0) if (avalue < 0)
@ -140,7 +139,7 @@ static BOOL send_mouse_wheel(sdlContext* sdl, UINT16 flags, INT32 avalue)
/* Convert negative values to 9bit twos complement */ /* Convert negative values to 9bit twos complement */
if (flags & PTR_FLAGS_WHEEL_NEGATIVE) if (flags & PTR_FLAGS_WHEEL_NEGATIVE)
cflags = (flags & 0xFF00) | (0x100 - cval); cflags = (flags & 0xFF00) | (0x100 - cval);
if (!freerdp_client_send_wheel_event(&sdl->common, cflags)) if (!freerdp_client_send_wheel_event(sdl->common(), cflags))
return FALSE; return FALSE;
avalue -= cval; avalue -= cval;
@ -158,7 +157,7 @@ static UINT32 sdl_scale_pressure(const float pressure)
return static_cast<UINT32>(val); return static_cast<UINT32>(val);
} }
BOOL sdl_handle_touch_up(sdlContext* sdl, const SDL_TouchFingerEvent* ev) BOOL sdl_handle_touch_up(SdlContext* sdl, const SDL_TouchFingerEvent* ev)
{ {
WINPR_ASSERT(sdl); WINPR_ASSERT(sdl);
WINPR_ASSERT(ev); WINPR_ASSERT(ev);
@ -166,12 +165,12 @@ BOOL sdl_handle_touch_up(sdlContext* sdl, const SDL_TouchFingerEvent* ev)
INT32 x, y; INT32 x, y;
if (!sdl_get_touch_scaled(sdl, ev, &x, &y, TRUE)) if (!sdl_get_touch_scaled(sdl, ev, &x, &y, TRUE))
return FALSE; return FALSE;
return freerdp_client_handle_touch(&sdl->common, FREERDP_TOUCH_UP | FREERDP_TOUCH_HAS_PRESSURE, return freerdp_client_handle_touch(sdl->common(), FREERDP_TOUCH_UP | FREERDP_TOUCH_HAS_PRESSURE,
static_cast<INT32>(ev->fingerId), static_cast<INT32>(ev->fingerId),
sdl_scale_pressure(ev->pressure), x, y); sdl_scale_pressure(ev->pressure), x, y);
} }
BOOL sdl_handle_touch_down(sdlContext* sdl, const SDL_TouchFingerEvent* ev) BOOL sdl_handle_touch_down(SdlContext* sdl, const SDL_TouchFingerEvent* ev)
{ {
WINPR_ASSERT(sdl); WINPR_ASSERT(sdl);
WINPR_ASSERT(ev); WINPR_ASSERT(ev);
@ -180,11 +179,11 @@ BOOL sdl_handle_touch_down(sdlContext* sdl, const SDL_TouchFingerEvent* ev)
if (!sdl_get_touch_scaled(sdl, ev, &x, &y, TRUE)) if (!sdl_get_touch_scaled(sdl, ev, &x, &y, TRUE))
return FALSE; return FALSE;
return freerdp_client_handle_touch( return freerdp_client_handle_touch(
&sdl->common, FREERDP_TOUCH_DOWN | FREERDP_TOUCH_HAS_PRESSURE, sdl->common(), FREERDP_TOUCH_DOWN | FREERDP_TOUCH_HAS_PRESSURE,
static_cast<INT32>(ev->fingerId), sdl_scale_pressure(ev->pressure), x, y); static_cast<INT32>(ev->fingerId), sdl_scale_pressure(ev->pressure), x, y);
} }
BOOL sdl_handle_touch_motion(sdlContext* sdl, const SDL_TouchFingerEvent* ev) BOOL sdl_handle_touch_motion(SdlContext* sdl, const SDL_TouchFingerEvent* ev)
{ {
WINPR_ASSERT(sdl); WINPR_ASSERT(sdl);
WINPR_ASSERT(ev); WINPR_ASSERT(ev);
@ -193,24 +192,24 @@ BOOL sdl_handle_touch_motion(sdlContext* sdl, const SDL_TouchFingerEvent* ev)
if (!sdl_get_touch_scaled(sdl, ev, &x, &y, TRUE)) if (!sdl_get_touch_scaled(sdl, ev, &x, &y, TRUE))
return FALSE; return FALSE;
return freerdp_client_handle_touch( return freerdp_client_handle_touch(
&sdl->common, FREERDP_TOUCH_MOTION | FREERDP_TOUCH_HAS_PRESSURE, sdl->common(), FREERDP_TOUCH_MOTION | FREERDP_TOUCH_HAS_PRESSURE,
static_cast<INT32>(ev->fingerId), sdl_scale_pressure(ev->pressure), x, y); static_cast<INT32>(ev->fingerId), sdl_scale_pressure(ev->pressure), x, y);
} }
BOOL sdl_handle_mouse_motion(sdlContext* sdl, const SDL_MouseMotionEvent* ev) BOOL sdl_handle_mouse_motion(SdlContext* sdl, const SDL_MouseMotionEvent* ev)
{ {
WINPR_ASSERT(sdl); WINPR_ASSERT(sdl);
WINPR_ASSERT(ev); WINPR_ASSERT(ev);
const BOOL relative = const BOOL relative =
freerdp_settings_get_bool(sdl->common.context.settings, FreeRDP_MouseUseRelativeMove); freerdp_settings_get_bool(sdl->context()->settings, FreeRDP_MouseUseRelativeMove);
INT32 x = relative ? ev->xrel : ev->x; INT32 x = relative ? ev->xrel : ev->x;
INT32 y = relative ? ev->yrel : ev->y; INT32 y = relative ? ev->yrel : ev->y;
sdl_scale_coordinates(sdl, ev->windowID, &x, &y, TRUE, TRUE); sdl_scale_coordinates(sdl, ev->windowID, &x, &y, TRUE, TRUE);
return freerdp_client_send_button_event(&sdl->common, relative, PTR_FLAGS_MOVE, x, y); return freerdp_client_send_button_event(sdl->common(), relative, PTR_FLAGS_MOVE, x, y);
} }
BOOL sdl_handle_mouse_wheel(sdlContext* sdl, const SDL_MouseWheelEvent* ev) BOOL sdl_handle_mouse_wheel(SdlContext* sdl, const SDL_MouseWheelEvent* ev)
{ {
WINPR_ASSERT(sdl); WINPR_ASSERT(sdl);
WINPR_ASSERT(ev); WINPR_ASSERT(ev);
@ -234,7 +233,7 @@ BOOL sdl_handle_mouse_wheel(sdlContext* sdl, const SDL_MouseWheelEvent* ev)
return TRUE; return TRUE;
} }
BOOL sdl_handle_mouse_button(sdlContext* sdl, const SDL_MouseButtonEvent* ev) BOOL sdl_handle_mouse_button(SdlContext* sdl, const SDL_MouseButtonEvent* ev)
{ {
UINT16 flags = 0; UINT16 flags = 0;
UINT16 xflags = 0; UINT16 xflags = 0;
@ -273,9 +272,9 @@ BOOL sdl_handle_mouse_button(sdlContext* sdl, const SDL_MouseButtonEvent* ev)
INT32 y = ev->y; INT32 y = ev->y;
sdl_scale_coordinates(sdl, ev->windowID, &x, &y, TRUE, TRUE); sdl_scale_coordinates(sdl, ev->windowID, &x, &y, TRUE, TRUE);
if ((flags & (~PTR_FLAGS_DOWN)) != 0) if ((flags & (~PTR_FLAGS_DOWN)) != 0)
return freerdp_client_send_button_event(&sdl->common, FALSE, flags, x, y); return freerdp_client_send_button_event(sdl->common(), FALSE, flags, x, y);
else if ((xflags & (~PTR_XFLAGS_DOWN)) != 0) else if ((xflags & (~PTR_XFLAGS_DOWN)) != 0)
return freerdp_client_send_extended_button_event(&sdl->common, FALSE, xflags, x, y); return freerdp_client_send_extended_button_event(sdl->common(), FALSE, xflags, x, y);
else else
return FALSE; return FALSE;
} }

View File

@ -24,13 +24,13 @@
#include <SDL.h> #include <SDL.h>
#include "sdl_types.hpp" #include "sdl_types.hpp"
BOOL sdl_scale_coordinates(sdlContext* sdl, Uint32 windowId, INT32* px, INT32* py, BOOL sdl_scale_coordinates(SdlContext* sdl, Uint32 windowId, INT32* px, INT32* py,
BOOL fromLocalToRDP, BOOL applyOffset); BOOL fromLocalToRDP, BOOL applyOffset);
BOOL sdl_handle_mouse_motion(sdlContext* sdl, const SDL_MouseMotionEvent* ev); BOOL sdl_handle_mouse_motion(SdlContext* sdl, const SDL_MouseMotionEvent* ev);
BOOL sdl_handle_mouse_wheel(sdlContext* sdl, const SDL_MouseWheelEvent* ev); BOOL sdl_handle_mouse_wheel(SdlContext* sdl, const SDL_MouseWheelEvent* ev);
BOOL sdl_handle_mouse_button(sdlContext* sdl, const SDL_MouseButtonEvent* ev); BOOL sdl_handle_mouse_button(SdlContext* sdl, const SDL_MouseButtonEvent* ev);
BOOL sdl_handle_touch_down(sdlContext* sdl, const SDL_TouchFingerEvent* ev); BOOL sdl_handle_touch_down(SdlContext* sdl, const SDL_TouchFingerEvent* ev);
BOOL sdl_handle_touch_up(sdlContext* sdl, const SDL_TouchFingerEvent* ev); BOOL sdl_handle_touch_up(SdlContext* sdl, const SDL_TouchFingerEvent* ev);
BOOL sdl_handle_touch_motion(sdlContext* sdl, const SDL_TouchFingerEvent* ev); BOOL sdl_handle_touch_motion(SdlContext* sdl, const SDL_TouchFingerEvent* ev);

View File

@ -19,4 +19,28 @@
#pragma once #pragma once
typedef struct sdl_context sdlContext; #include <freerdp/freerdp.h>
class SdlContext;
typedef struct
{
rdpClientContext common;
SdlContext* sdl;
} sdl_rdp_context;
static inline SdlContext* get_context(void* ctx)
{
if (!ctx)
return nullptr;
auto sdl = static_cast<sdl_rdp_context*>(ctx);
return sdl->sdl;
}
static inline SdlContext* get_context(rdpContext* ctx)
{
if (!ctx)
return nullptr;
auto sdl = reinterpret_cast<sdl_rdp_context*>(ctx);
return sdl->sdl;
}