Commit 5bd049b3 authored by Marc-André Moreau's avatar Marc-André Moreau

RDP: fix race condition for region update

parent c2947377
......@@ -55,7 +55,7 @@
typedef void (*PThreadCleanupFunc)(void*);
/* Wrapper marcos to make the compiler happy on both signle/multi-threaded mode */
/* Wrapper macros to make the compiler happy on both signle/multi-threaded mode */
#ifdef HAVE_PTHREAD
#define IDLE_ADD gdk_threads_add_idle
#define TIMEOUT_ADD gdk_threads_add_timeout
......
......@@ -132,12 +132,42 @@ static void remmina_rdp_event_scale_area(RemminaProtocolWidget* gp, gint* x, gin
*h = sh;
}
void remmina_rdp_event_update_region(RemminaProtocolWidget* gp, RemminaPluginRdpUiObject* ui)
{
rfContext* rfi;
gint x, y, w, h;
x = ui->region.x;
y = ui->region.y;
w = ui->region.width;
h = ui->region.height;
rfi = GET_DATA(gp);
if (rfi->sw_gdi)
{
XPutImage(rfi->display, rfi->primary, rfi->gc, rfi->image, x, y, x, y, w, h);
XCopyArea(rfi->display, rfi->primary, rfi->rgb_surface, rfi->gc, x, y, w, h, x, y);
}
if (remmina_plugin_service->protocol_plugin_get_scale(gp))
remmina_rdp_event_scale_area(gp, &x, &y, &w, &h);
gtk_widget_queue_draw_area(rfi->drawing_area, x, y, w, h);
}
void remmina_rdp_event_update_rect(RemminaProtocolWidget* gp, gint x, gint y, gint w, gint h)
{
rfContext* rfi;
rfi = GET_DATA(gp);
if (rfi->sw_gdi)
{
XPutImage(rfi->display, rfi->primary, rfi->gc, rfi->image, x, y, x, y, w, h);
XCopyArea(rfi->display, rfi->primary, rfi->rgb_surface, rfi->gc, x, y, w, h, x, y);
}
if (remmina_plugin_service->protocol_plugin_get_scale(gp))
remmina_rdp_event_scale_area(gp, &x, &y, &w, &h);
......@@ -504,7 +534,7 @@ void remmina_rdp_event_uninit(RemminaProtocolWidget* gp)
}
while ((ui =(RemminaPluginRdpUiObject*) g_async_queue_try_pop(rfi->ui_queue)) != NULL)
{
rf_object_free (gp, ui);
rf_object_free(gp, ui);
}
if (rfi->gc)
......@@ -780,7 +810,7 @@ static void remmina_rdp_event_rfx(RemminaProtocolWidget* gp, RemminaPluginRdpUiO
XSetClipMask(rfi->display, rfi->gc, None);
}
static void remmina_rdp_event_nocodec(RemminaProtocolWidget* gp, RemminaPluginRdpUiObject *ui)
static void remmina_rdp_event_nocodec(RemminaProtocolWidget* gp, RemminaPluginRdpUiObject* ui)
{
XImage* image;
rfContext* rfi;
......@@ -817,6 +847,10 @@ gboolean remmina_rdp_event_queue_ui(RemminaProtocolWidget* gp)
{
switch (ui->type)
{
case REMMINA_RDP_UI_UPDATE_REGION:
remmina_rdp_event_update_region(gp, ui);
break;
case REMMINA_RDP_UI_CONNECTED:
remmina_rdp_event_connected(gp, ui);
break;
......
......@@ -205,6 +205,7 @@ void rf_sw_end_paint(rdpContext* context)
rdpGdi* gdi;
rfContext* rfi;
RemminaProtocolWidget* gp;
RemminaPluginRdpUiObject* ui;
gdi = context->gdi;
rfi = (rfContext*) context;
......@@ -218,11 +219,14 @@ void rf_sw_end_paint(rdpContext* context)
w = gdi->primary->hdc->hwnd->invalid->w;
h = gdi->primary->hdc->hwnd->invalid->h;
THREADS_ENTER
XPutImage(rfi->display, rfi->primary, rfi->gc, rfi->image, x, y, x, y, w, h);
XCopyArea(rfi->display, rfi->primary, rfi->rgb_surface, rfi->gc, x, y, w, h, x, y);
remmina_rdp_event_update_rect(gp, x, y, w, h);
THREADS_LEAVE
ui = g_new0(RemminaPluginRdpUiObject, 1);
ui->type = REMMINA_RDP_UI_UPDATE_REGION;
ui->region.x = x;
ui->region.y = y;
ui->region.width = w;
ui->region.height = h;
rf_queue_ui(rfi->protocol_widget, ui);
}
static void rf_sw_desktop_resize(rdpContext* context)
......
......@@ -164,7 +164,8 @@ typedef struct remmina_plugin_rdp_event RemminaPluginRdpEvent;
typedef enum
{
REMMINA_RDP_UI_CONNECTED = 0,
REMMINA_RDP_UI_UPDATE_REGION = 0,
REMMINA_RDP_UI_CONNECTED,
REMMINA_RDP_UI_RFX,
REMMINA_RDP_UI_NOCODEC
} RemminaPluginRdpUiType;
......@@ -174,6 +175,13 @@ struct remmina_plugin_rdp_ui_object
RemminaPluginRdpUiType type;
union
{
struct
{
gint x;
gint y;
gint width;
gint height;
} region;
struct
{
gint left;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment