diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c index 9e206c2c..4985bbe2 100644 --- a/libxrdp/libxrdp.c +++ b/libxrdp/libxrdp.c @@ -758,10 +758,12 @@ libxrdp_orders_send_brush(struct xrdp_session* session, /*****************************************************************************/ int EXPORT_CC libxrdp_orders_send_create_os_surface(struct xrdp_session* session, int id, - int width, int height) + int width, int height, int num_del_list, + int* del_list) { return xrdp_orders_send_create_os_surface - ((struct xrdp_orders*)(session->orders), id, width, height); + ((struct xrdp_orders*)(session->orders), id, width, height, + num_del_list, del_list); } /*****************************************************************************/ diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h index 35a38190..99649a41 100644 --- a/libxrdp/libxrdp.h +++ b/libxrdp/libxrdp.h @@ -389,7 +389,8 @@ xrdp_orders_send_brush(struct xrdp_orders* self, int width, int height, int bpp, int type, int size, char* data, int cache_id); int APP_CC xrdp_orders_send_create_os_surface(struct xrdp_orders* self, int id, - int width, int height); + int width, int height, int num_del_list, + int* del_list); int APP_CC xrdp_orders_send_switch_os_surface(struct xrdp_orders* self, int id); diff --git a/libxrdp/libxrdpinc.h b/libxrdp/libxrdpinc.h index b7974b35..648eb1f6 100644 --- a/libxrdp/libxrdpinc.h +++ b/libxrdp/libxrdpinc.h @@ -178,7 +178,8 @@ libxrdp_orders_send_brush(struct xrdp_session* session, int size, char* data, int cache_id); int EXPORT_CC libxrdp_orders_send_create_os_surface(struct xrdp_session* session, int id, - int width, int height); + int width, int height, int num_del_list, + int* del_list); int EXPORT_CC libxrdp_orders_send_switch_os_surface(struct xrdp_session* session, int id); diff --git a/libxrdp/xrdp_orders.c b/libxrdp/xrdp_orders.c index 5acd42b0..4a36e112 100644 --- a/libxrdp/xrdp_orders.c +++ b/libxrdp/xrdp_orders.c @@ -1971,21 +1971,45 @@ xrdp_orders_send_brush(struct xrdp_orders* self, int width, int height, /* send an off screen bitmap entry */ int APP_CC xrdp_orders_send_create_os_surface(struct xrdp_orders* self, int id, - int width, int height) + int width, int height, int num_del_list, + int* del_list) { int order_flags; int cache_id; + int flags; + int index; + int bytes; - //g_writeln("xrdp_orders_send_create_os_surface:"); - xrdp_orders_check(self, 7); + bytes = 7; + if (num_del_list > 0) + { + bytes += 2; + bytes += num_del_list * 2; + } + xrdp_orders_check(self, bytes); self->order_count++; order_flags = RDP_ORDER_SECONDARY; order_flags |= 1 << 2; /* type RDP_ORDER_ALTSEC_CREATE_OFFSCR_BITMAP */ out_uint8(self->out_s, order_flags); cache_id = id & 0x7fff; - out_uint16_le(self->out_s, cache_id); + flags = cache_id; + if (num_del_list > 0) + { + flags |= 0x8000; + } + out_uint16_le(self->out_s, flags); out_uint16_le(self->out_s, width); out_uint16_le(self->out_s, height); + if (num_del_list > 0) + { + /* delete list */ + out_uint16_le(self->out_s, num_del_list); + for (index = 0; index < num_del_list; index++) + { + cache_id = del_list[index] & 0x7fff; + out_uint16_le(self->out_s, cache_id); + } + } return 0; } @@ -1997,7 +2021,6 @@ xrdp_orders_send_switch_os_surface(struct xrdp_orders* self, int id) int order_flags; int cache_id; - //g_writeln("xrdp_orders_send_switch_os_surface:"); xrdp_orders_check(self, 3); self->order_count++; order_flags = RDP_ORDER_SECONDARY; diff --git a/xorg/X11R7.6/rdp/rdpup.c b/xorg/X11R7.6/rdp/rdpup.c index fa2092e2..19a6e6d1 100644 --- a/xorg/X11R7.6/rdp/rdpup.c +++ b/xorg/X11R7.6/rdp/rdpup.c @@ -64,9 +64,6 @@ extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */ extern int g_use_uds; /* in rdpmain.c */ extern char g_uds_data[]; /* in rdpmain.c */ -extern int g_pixmap_byte_total; /* in rdpdraw.c */ -extern int g_pixmap_num_used; /* in rdpdraw.c */ - struct rdpup_os_bitmap { int used; @@ -79,8 +76,8 @@ static struct rdpup_os_bitmap* g_os_bitmaps = 0; static int g_max_os_bitmaps = 0; static int g_os_bitmap_stamp = 0; -int g_pixmap_byte_total = 0; -int g_pixmap_num_used = 0; +static int g_pixmap_byte_total = 0; +static int g_pixmap_num_used = 0; /* 0 GXclear, 0 @@ -121,6 +118,38 @@ static int g_rdp_opcodes[16] = 0xff /* GXset 0xf 1 */ }; +/*****************************************************************************/ +static int +rdpup_disconnect(void) +{ + int index; + + RemoveEnabledDevice(g_sck); + g_connected = 0; + g_tcp_close(g_sck); + g_sck = 0; + g_sck_closed = 1; + g_pixmap_byte_total = 0; + g_pixmap_num_used = 0; + if (g_max_os_bitmaps > 0) + { + for (index = 0; index < g_max_os_bitmaps; index++) + { + if (g_os_bitmaps[index].used) + { + if (g_os_bitmaps[index].priv != 0) + { + g_os_bitmaps[index].priv->status = 0; + } + } + } + } + g_max_os_bitmaps = 0; + g_free(g_os_bitmaps); + g_os_bitmaps = 0; + return 0; +} + /*****************************************************************************/ int rdpup_add_os_bitmap(PixmapPtr pixmap, rdpPixmapPtr priv) @@ -224,21 +253,13 @@ rdpup_send(char* data, int len) } else { - RemoveEnabledDevice(g_sck); - g_connected = 0; - g_tcp_close(g_sck); - g_sck = 0; - g_sck_closed = 1; + rdpup_disconnect(); return 1; } } else if (sent == 0) { - RemoveEnabledDevice(g_sck); - g_connected = 0; - g_tcp_close(g_sck); - g_sck = 0; - g_sck_closed = 1; + rdpup_disconnect(); return 1; } else @@ -338,25 +359,13 @@ rdpup_recv(char* data, int len) } else { - RemoveEnabledDevice(g_sck); - g_connected = 0; - g_tcp_close(g_sck); - g_sck = 0; - g_sck_closed = 1; - //g_pixmap_byte_total = 0; - //g_pixmap_num_used = 0; + rdpup_disconnect(); return 1; } } else if (rcvd == 0) { - RemoveEnabledDevice(g_sck); - g_connected = 0; - g_tcp_close(g_sck); - g_sck = 0; - g_sck_closed = 1; - //g_pixmap_byte_total = 0; - //g_pixmap_num_used = 0; + rdpup_disconnect(); return 1; } else @@ -638,6 +647,7 @@ param4 %d\n", msg, param1, param2, param3, param4)); if (g_rdpScreen.client_info.offscreen_cache_entries > 0) { g_max_os_bitmaps = g_rdpScreen.client_info.offscreen_cache_entries; + g_free(g_os_bitmaps); g_os_bitmaps = (struct rdpup_os_bitmap*) g_malloc(sizeof(struct rdpup_os_bitmap) * g_max_os_bitmaps, 1); } @@ -771,11 +781,7 @@ rdpup_check(void) { /* should maybe ask is user wants to allow here with timeout */ rdpLog("replacing connection, already got a connection\n"); - RemoveEnabledDevice(g_sck); - g_connected = 0; - g_tcp_close(g_sck); - g_sck = 0; - g_sck_closed = 1; + rdpup_disconnect(); } rdpLog("got a connection\n"); g_sck = new_sck; @@ -802,11 +808,7 @@ rdpup_check(void) if (g_sck != 0) { rdpLog("disconnecting session via user request\n"); - RemoveEnabledDevice(g_sck); - g_connected = 0; - g_tcp_close(g_sck); - g_sck = 0; - g_sck_closed = 1; + rdpup_disconnect(); } } } diff --git a/xrdp/xrdp_painter.c b/xrdp/xrdp_painter.c index 9cf9438d..ada8a65b 100644 --- a/xrdp/xrdp_painter.c +++ b/xrdp/xrdp_painter.c @@ -70,7 +70,7 @@ wm_painter_set_target(struct xrdp_painter* self) { libxrdp_orders_send_create_os_surface(self->session, surface_index, self->wm->target_surface->width, - self->wm->target_surface->height); + self->wm->target_surface->height, 0, 0); self->wm->target_surface->tab_stop = 1; } libxrdp_orders_send_switch_os_surface(self->session, surface_index);