add large cursor support, posix shm

This commit is contained in:
Jay Sorg
2022-07-14 01:46:38 -07:00
parent 544ead05e7
commit c250529e8e
14 changed files with 282 additions and 68 deletions
+4
View File
@@ -567,4 +567,8 @@
#define RDP_MPPC_FLUSH 0x80 #define RDP_MPPC_FLUSH 0x80
#define RDP_MPPC_DICT_SIZE 8192 /* RDP 4.0 | MS-RDPBCGR 3.1.8 */ #define RDP_MPPC_DICT_SIZE 8192 /* RDP 4.0 | MS-RDPBCGR 3.1.8 */
/* largePointerSupprtFlags (2.2.7.2.7) */
#define LARGE_POINTER_FLAG_96x96 0x00000001
#define LARGE_POINTER_FLAG_384x384 0x00000002
#endif /* MS_RDPBCGR_H */ #endif /* MS_RDPBCGR_H */
+32
View File
@@ -56,6 +56,7 @@
#if defined(HAVE_SYS_PRCTL_H) #if defined(HAVE_SYS_PRCTL_H)
#include <sys/prctl.h> #include <sys/prctl.h>
#endif #endif
#include <sys/mman.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netdb.h> #include <netdb.h>
@@ -2353,6 +2354,37 @@ nomem:
return NULL; return NULL;
} }
/*****************************************************************************/
int
g_file_map(int fd, int aread, int awrite, size_t length, void **addr)
{
int prot = 0;
void *laddr;
if (aread)
{
prot |= PROT_READ;
}
if (awrite)
{
prot |= PROT_WRITE;
}
laddr = mmap(NULL, length, prot, MAP_SHARED, fd, 0);
if (laddr == MAP_FAILED)
{
return 1;
}
*addr = laddr;
return 0;
}
/*****************************************************************************/
int
g_munmap(void *addr, size_t length)
{
return munmap(addr, length);
}
/*****************************************************************************/ /*****************************************************************************/
/* Converts a hex mask to a mode_t value */ /* Converts a hex mask to a mode_t value */
#if !defined(_WIN32) #if !defined(_WIN32)
+4
View File
@@ -221,6 +221,10 @@ int g_file_read(int fd, char *ptr, int len);
int g_file_write(int fd, const char *ptr, int len); int g_file_write(int fd, const char *ptr, int len);
int g_file_seek(int fd, int offset); int g_file_seek(int fd, int offset);
int g_file_lock(int fd, int start, int len); int g_file_lock(int fd, int start, int len);
int
g_file_map(int fd, int aread, int awrite, size_t length, void **addr);
int
g_munmap(void *addr, size_t length);
int g_file_duplicate_on(int fd, int target_fd); int g_file_duplicate_on(int fd, int target_fd);
int g_file_get_cloexec(int fd); int g_file_get_cloexec(int fd);
int g_file_set_cloexec(int fd, int status); int g_file_set_cloexec(int fd, int status);
+4 -1
View File
@@ -213,9 +213,12 @@ struct xrdp_client_info
* data */ * data */
unsigned int session_physical_width; /* in mm */ unsigned int session_physical_width; /* in mm */
unsigned int session_physical_height; /* in mm */ unsigned int session_physical_height; /* in mm */
int large_pointer_support_flags;
}; };
/* yyyymmdd of last incompatible change to xrdp_client_info */ /* yyyymmdd of last incompatible change to xrdp_client_info */
#define CLIENT_INFO_CURRENT_VERSION 20220428 /* also used for changes to all the xrdp installed headers */
#define CLIENT_INFO_CURRENT_VERSION 20230425
#endif #endif
+41 -36
View File
@@ -705,7 +705,8 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
/*****************************************************************************/ /*****************************************************************************/
int EXPORT_CC int EXPORT_CC
libxrdp_send_pointer(struct xrdp_session *session, int cache_idx, libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
char *data, char *mask, int x, int y, int bpp) char *data, char *mask, int x, int y, int bpp,
int width, int height)
{ {
struct stream *s; struct stream *s;
char *p; char *p;
@@ -714,12 +715,21 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
int i; int i;
int j; int j;
int data_bytes; int data_bytes;
int mask_bytes;
LOG_DEVEL(LOG_LEVEL_DEBUG, "sending cursor"); LOG_DEVEL(LOG_LEVEL_DEBUG, "sending cursor");
if (bpp == 0) if (bpp == 0)
{ {
bpp = 24; bpp = 24;
} }
if (width == 0)
{
width = 32;
}
if (height == 0)
{
height = 32;
}
/* error check */ /* error check */
if ((session->client_info->pointer_flags & 1) == 0) if ((session->client_info->pointer_flags & 1) == 0)
{ {
@@ -731,16 +741,17 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
} }
} }
if ((bpp != 16) && (bpp != 24) && (bpp != 32)) if ((bpp != 15) && (bpp != 16) && (bpp != 24) && (bpp != 32))
{ {
LOG(LOG_LEVEL_ERROR, LOG(LOG_LEVEL_ERROR,
"Send pointer: invalid bpp value. Expected 16 or 24 or 32, " "Send pointer: invalid bpp value. Expected 15, 16, 24 or 32, "
"received %d", bpp); "received %d", bpp);
return 1; return 1;
} }
make_stream(s); make_stream(s);
init_stream(s, 8192); data_bytes = width * height * ((bpp + 7) / 8);
mask_bytes = width * height / 8;
init_stream(s, data_bytes + mask_bytes + 8192);
if (session->client_info->use_fast_path & 1) /* fastpath output supported */ if (session->client_info->use_fast_path & 1) /* fastpath output supported */
{ {
LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_pointer: fastpath"); LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_pointer: fastpath");
@@ -751,13 +762,8 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
return 1; return 1;
} }
if ((session->client_info->pointer_flags & 1) == 0) if ((session->client_info->pointer_flags & 1) != 0)
{ {
data_bytes = 3072;
}
else
{
data_bytes = ((bpp + 7) / 8) * 32 * 32;
out_uint16_le(s, bpp); /* TS_FP_POINTERATTRIBUTE -> newPointerUpdateData.xorBpp */ out_uint16_le(s, bpp); /* TS_FP_POINTERATTRIBUTE -> newPointerUpdateData.xorBpp */
} }
} }
@@ -769,7 +775,6 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
{ {
out_uint16_le(s, RDP_POINTER_COLOR); out_uint16_le(s, RDP_POINTER_COLOR);
out_uint16_le(s, 0); /* pad */ out_uint16_le(s, 0); /* pad */
data_bytes = 3072;
LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPBCGR] TS_POINTER_PDU " LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPBCGR] TS_POINTER_PDU "
"messageType %d (TS_PTRMSGTYPE_COLOR), pad2Octets <ignored>", "messageType %d (TS_PTRMSGTYPE_COLOR), pad2Octets <ignored>",
RDP_POINTER_COLOR); RDP_POINTER_COLOR);
@@ -783,7 +788,6 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
RDP_POINTER_POINTER); RDP_POINTER_POINTER);
out_uint16_le(s, bpp); /* TS_POINTERATTRIBUTE -> xorBpp */ out_uint16_le(s, bpp); /* TS_POINTERATTRIBUTE -> xorBpp */
data_bytes = ((bpp + 7) / 8) * 32 * 32;
} }
} }
@@ -792,20 +796,21 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
out_uint16_le(s, cache_idx); /* cache_idx */ out_uint16_le(s, cache_idx); /* cache_idx */
out_uint16_le(s, x); /* hotSpot.xPos */ out_uint16_le(s, x); /* hotSpot.xPos */
out_uint16_le(s, y); /* hotSpot.yPos */ out_uint16_le(s, y); /* hotSpot.yPos */
out_uint16_le(s, 32); /* width */ out_uint16_le(s, width); /* width */
out_uint16_le(s, 32); /* height */ out_uint16_le(s, height); /* height */
out_uint16_le(s, 128); /* lengthAndMask */ out_uint16_le(s, mask_bytes); /* lengthAndMask */
out_uint16_le(s, data_bytes); /* lengthXorMask */ out_uint16_le(s, data_bytes); /* lengthXorMask */
/* xorMaskData */ /* xorMaskData */
switch (bpp) switch (bpp)
{ {
//case 15: /* coverity: this is logically dead code */ case 15:
/* fallthrough */
case 16: case 16:
p16 = (tui16 *) data; p16 = (tui16 *) data;
for (i = 0; i < 32; i++) for (i = 0; i < height; i++)
{ {
for (j = 0; j < 32; j++) for (j = 0; j < width; j++)
{ {
out_uint16_le(s, *p16); out_uint16_le(s, *p16);
p16++; p16++;
@@ -814,9 +819,9 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
break; break;
case 24: case 24:
p = data; p = data;
for (i = 0; i < 32; i++) for (i = 0; i < height; i++)
{ {
for (j = 0; j < 32; j++) for (j = 0; j < width; j++)
{ {
out_uint8(s, *p); out_uint8(s, *p);
p++; p++;
@@ -829,9 +834,9 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
break; break;
case 32: case 32:
p32 = (tui32 *) data; p32 = (tui32 *) data;
for (i = 0; i < 32; i++) for (i = 0; i < height; i++)
{ {
for (j = 0; j < 32; j++) for (j = 0; j < width; j++)
{ {
out_uint32_le(s, *p32); out_uint32_le(s, *p32);
p32++; p32++;
@@ -840,7 +845,7 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
break; break;
} }
out_uint8a(s, mask, 128); /* andMaskData */ out_uint8a(s, mask, mask_bytes); /* andMaskData */
out_uint8(s, 0); /* pad */ out_uint8(s, 0); /* pad */
s_mark_end(s); s_mark_end(s);
if (session->client_info->use_fast_path & 1) /* fastpath output supported */ if (session->client_info->use_fast_path & 1) /* fastpath output supported */
@@ -849,11 +854,11 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
{ {
LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_FP_COLORPOINTERATTRIBUTE " LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_FP_COLORPOINTERATTRIBUTE "
"cachedPointerUpdateData = { cacheIndex %d, " "cachedPointerUpdateData = { cacheIndex %d, "
"hotSpot.xPos %d, hotSpot.yPos %d, width 32, " "hotSpot.xPos %d, hotSpot.yPos %d, width %d, "
"height 32, lengthAndMask 128, lengthXorMask %d, " "height %d, lengthAndMask %d, lengthXorMask %d, "
"xorMaskData <omitted from log>, " "xorMaskData <omitted from log>, "
"andMaskData <omitted from log> }", "andMaskData <omitted from log> }",
cache_idx, x, y, data_bytes); cache_idx, x, y, width, height, mask_bytes, data_bytes);
if (xrdp_rdp_send_fastpath((struct xrdp_rdp *)session->rdp, s, if (xrdp_rdp_send_fastpath((struct xrdp_rdp *)session->rdp, s,
FASTPATH_UPDATETYPE_COLOR) != 0) FASTPATH_UPDATETYPE_COLOR) != 0)
{ {
@@ -867,11 +872,11 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_FP_POINTERATTRIBUTE " LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_FP_POINTERATTRIBUTE "
"newPointerUpdateData.xorBpp %d, " "newPointerUpdateData.xorBpp %d, "
"newPointerUpdateData.colorPtrAttr = { cacheIndex %d, " "newPointerUpdateData.colorPtrAttr = { cacheIndex %d, "
"hotSpot.xPos %d, hotSpot.yPos %d, width 32, " "hotSpot.xPos %d, hotSpot.yPos %d, width %d, "
"height 32, lengthAndMask 128, lengthXorMask %d, " "height %d, lengthAndMask %d, lengthXorMask %d, "
"xorMaskData <omitted from log>, " "xorMaskData <omitted from log>, "
"andMaskData <omitted from log> }", "andMaskData <omitted from log> }",
bpp, cache_idx, x, y, data_bytes); bpp, cache_idx, x, y, width, height, mask_bytes, data_bytes);
if (xrdp_rdp_send_fastpath((struct xrdp_rdp *)session->rdp, s, if (xrdp_rdp_send_fastpath((struct xrdp_rdp *)session->rdp, s,
FASTPATH_UPDATETYPE_POINTER) != 0) FASTPATH_UPDATETYPE_POINTER) != 0)
{ {
@@ -887,21 +892,21 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
{ {
LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_COLORPOINTERATTRIBUTE " LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_COLORPOINTERATTRIBUTE "
"cacheIndex %d, " "cacheIndex %d, "
"hotSpot.xPos %d, hotSpot.yPos %d, width 32, " "hotSpot.xPos %d, hotSpot.yPos %d, width %d, "
"height 32, lengthAndMask 128, lengthXorMask %d, " "height %d, lengthAndMask %d, lengthXorMask %d, "
"xorMaskData <omitted from log>, " "xorMaskData <omitted from log>, "
"andMaskData <omitted from log>", "andMaskData <omitted from log>",
cache_idx, x, y, data_bytes); cache_idx, x, y, width, height, mask_bytes, data_bytes);
} }
else else
{ {
LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_POINTERATTRIBUTE " LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_POINTERATTRIBUTE "
"xorBpp %d, colorPtrAttr = { cacheIndex %d, " "xorBpp %d, colorPtrAttr = { cacheIndex %d, "
"hotSpot.xPos %d, hotSpot.yPos %d, width 32, " "hotSpot.xPos %d, hotSpot.yPos %d, width %d, "
"height 32, lengthAndMask 128, lengthXorMask %d, " "height %d, lengthAndMask %d, lengthXorMask %d, "
"xorMaskData <omitted from log>, " "xorMaskData <omitted from log>, "
"andMaskData <omitted from log> }", "andMaskData <omitted from log> }",
bpp, cache_idx, x, y, data_bytes); bpp, cache_idx, x, y, width, height, mask_bytes, data_bytes);
} }
xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s, xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s,
RDP_DATA_PDU_POINTER); RDP_DATA_PDU_POINTER);
+2 -1
View File
@@ -122,7 +122,8 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
int bpp, char *data, int x, int y, int cx, int cy); int bpp, char *data, int x, int y, int cx, int cy);
int int
libxrdp_send_pointer(struct xrdp_session *session, int cache_idx, libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
char *data, char *mask, int x, int y, int bpp); char *data, char *mask, int x, int y, int bpp,
int width, int height);
int int
libxrdp_set_pointer(struct xrdp_session *session, int cache_idx); libxrdp_set_pointer(struct xrdp_session *session, int cache_idx);
int int
+63
View File
@@ -630,6 +630,18 @@ xrdp_caps_process_multifragmentupdate(struct xrdp_rdp *self, struct stream *s,
return 0; return 0;
} }
/*****************************************************************************/
static int
xrdp_caps_process_largepointer(struct xrdp_rdp *self, struct stream *s,
int len)
{
int largePointerSupportFlags;
in_uint16_le(s, largePointerSupportFlags);
self->client_info.large_pointer_support_flags = largePointerSupportFlags;
return 0;
}
/*****************************************************************************/ /*****************************************************************************/
static int static int
xrdp_caps_process_frame_ack(struct xrdp_rdp *self, struct stream *s, int len) xrdp_caps_process_frame_ack(struct xrdp_rdp *self, struct stream *s, int len)
@@ -846,6 +858,11 @@ xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
"capabilitySetType = CAPSSETTYPE_MULTIFRAGMENTUPDATE"); "capabilitySetType = CAPSSETTYPE_MULTIFRAGMENTUPDATE");
xrdp_caps_process_multifragmentupdate(self, s, len); xrdp_caps_process_multifragmentupdate(self, s, len);
break; break;
case CAPSETTYPE_LARGE_POINTER:
LOG_DEVEL(LOG_LEVEL_INFO, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
"capabilitySetType = CAPSETTYPE_LARGE_POINTER");
xrdp_caps_process_largepointer(self, s, len);
break;
case CAPSETTYPE_SURFACE_COMMANDS: case CAPSETTYPE_SURFACE_COMMANDS:
LOG_DEVEL(LOG_LEVEL_INFO, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET " LOG_DEVEL(LOG_LEVEL_INFO, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
"capabilitySetType = CAPSETTYPE_SURFACE_COMMANDS"); "capabilitySetType = CAPSETTYPE_SURFACE_COMMANDS");
@@ -881,6 +898,46 @@ xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
self->client_info.offscreen_cache_entries = 0; self->client_info.offscreen_cache_entries = 0;
} }
if (self->client_info.use_fast_path)
{
if ((self->client_info.large_pointer_support_flags & LARGE_POINTER_FLAG_96x96) &&
(self->client_info.max_fastpath_frag_bytes < 38055))
{
LOG(LOG_LEVEL_WARNING, "Client Capability: client requested "
"LARGE_POINTER_FLAG_96x96 but max_fastpath_frag_bytes(%d) is less then "
"the required size of 38055, 96x96 large cursor support disabled",
self->client_info.max_fastpath_frag_bytes);
self->client_info.large_pointer_support_flags &= ~LARGE_POINTER_FLAG_96x96;
}
if ((self->client_info.large_pointer_support_flags & LARGE_POINTER_FLAG_384x384) &&
(self->client_info.max_fastpath_frag_bytes < 608299))
{
LOG(LOG_LEVEL_WARNING, "Client Capability: client requested "
"LARGE_POINTER_FLAG_384x384 but max_fastpath_frag_bytes(%d) is less then "
"the required size of 608299, 384x384 large cursor support disabled",
self->client_info.max_fastpath_frag_bytes);
self->client_info.large_pointer_support_flags &= ~LARGE_POINTER_FLAG_384x384;
}
}
else
{
if (self->client_info.large_pointer_support_flags != 0)
{
LOG(LOG_LEVEL_WARNING, "Client Capability: client requested "
"large pointers but use_fast_path is false, "
"all large cursor support disabled");
self->client_info.large_pointer_support_flags = 0;
}
}
if (self->client_info.large_pointer_support_flags & LARGE_POINTER_FLAG_96x96)
{
LOG(LOG_LEVEL_INFO, "Client Capability: LARGE_POINTER_FLAG_96x96 supported");
}
if (self->client_info.large_pointer_support_flags & LARGE_POINTER_FLAG_384x384)
{
LOG(LOG_LEVEL_INFO, "Client Capability: LARGE_POINTER_FLAG_384x384 supported");
}
LOG_DEVEL(LOG_LEVEL_TRACE, "Completed processing received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU"); LOG_DEVEL(LOG_LEVEL_TRACE, "Completed processing received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU");
return 0; return 0;
} }
@@ -1225,6 +1282,12 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_send_demand_active: Server Capability " LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_send_demand_active: Server Capability "
"CAPSSETTYPE_MULTIFRAGMENTUPDATE = %d", max_request_size); "CAPSSETTYPE_MULTIFRAGMENTUPDATE = %d", max_request_size);
/* large pointer 96x96 */
caps_count++;
out_uint16_le(s, CAPSETTYPE_LARGE_POINTER);
out_uint16_le(s, CAPSETTYPE_LARGE_POINTER_LEN);
out_uint16_le(s, LARGE_POINTER_FLAG_96x96);
/* frame acks */ /* frame acks */
caps_count++; caps_count++;
out_uint16_le(s, CAPSTYPE_FRAME_ACKNOWLEDGE); out_uint16_le(s, CAPSTYPE_FRAME_ACKNOWLEDGE);
+7 -2
View File
@@ -149,10 +149,11 @@ int
xrdp_wm_pu(struct xrdp_wm *self, struct xrdp_bitmap *control); xrdp_wm_pu(struct xrdp_wm *self, struct xrdp_bitmap *control);
int int
xrdp_wm_send_pointer(struct xrdp_wm *self, int cache_idx, xrdp_wm_send_pointer(struct xrdp_wm *self, int cache_idx,
char *data, char *mask, int x, int y, int bpp); char *data, char *mask, int x, int y, int bpp,
int width, int height);
int int
xrdp_wm_pointer(struct xrdp_wm *self, char *data, char *mask, int x, int y, xrdp_wm_pointer(struct xrdp_wm *self, char *data, char *mask, int x, int y,
int bpp); int bpp, int width, int height);
int int
callback(intptr_t id, int msg, intptr_t param1, intptr_t param2, callback(intptr_t id, int msg, intptr_t param1, intptr_t param2,
intptr_t param3, intptr_t param4); intptr_t param3, intptr_t param4);
@@ -513,6 +514,10 @@ int
server_set_pointer_ex(struct xrdp_mod *mod, int x, int y, server_set_pointer_ex(struct xrdp_mod *mod, int x, int y,
char *data, char *mask, int bpp); char *data, char *mask, int bpp);
int int
server_set_pointer_large(struct xrdp_mod *mod, int x, int y,
char *data, char *mask, int bpp,
int width, int height);
int
server_palette(struct xrdp_mod *mod, int *palette); server_palette(struct xrdp_mod *mod, int *palette);
int int
server_msg(struct xrdp_mod *mod, const char *msg, int code); server_msg(struct xrdp_mod *mod, const char *msg, int code);
+17 -9
View File
@@ -619,10 +619,12 @@ xrdp_cache_add_pointer(struct xrdp_cache *self,
if (self->pointer_items[i].x == pointer_item->x && if (self->pointer_items[i].x == pointer_item->x &&
self->pointer_items[i].y == pointer_item->y && self->pointer_items[i].y == pointer_item->y &&
g_memcmp(self->pointer_items[i].data, g_memcmp(self->pointer_items[i].data,
pointer_item->data, 32 * 32 * 4) == 0 && pointer_item->data, 96 * 96 * 4) == 0 &&
g_memcmp(self->pointer_items[i].mask, g_memcmp(self->pointer_items[i].mask,
pointer_item->mask, 32 * 32 / 8) == 0 && pointer_item->mask, 96 * 96 / 8) == 0 &&
self->pointer_items[i].bpp == pointer_item->bpp) self->pointer_items[i].bpp == pointer_item->bpp &&
self->pointer_items[i].width == pointer_item->width &&
self->pointer_items[i].height == pointer_item->height)
{ {
self->pointer_items[i].stamp = self->pointer_stamp; self->pointer_items[i].stamp = self->pointer_stamp;
xrdp_wm_set_pointer(self->wm, i); xrdp_wm_set_pointer(self->wm, i);
@@ -648,17 +650,21 @@ xrdp_cache_add_pointer(struct xrdp_cache *self,
self->pointer_items[index].x = pointer_item->x; self->pointer_items[index].x = pointer_item->x;
self->pointer_items[index].y = pointer_item->y; self->pointer_items[index].y = pointer_item->y;
g_memcpy(self->pointer_items[index].data, g_memcpy(self->pointer_items[index].data,
pointer_item->data, 32 * 32 * 4); pointer_item->data, 96 * 96 * 4);
g_memcpy(self->pointer_items[index].mask, g_memcpy(self->pointer_items[index].mask,
pointer_item->mask, 32 * 32 / 8); pointer_item->mask, 96 * 96 / 8);
self->pointer_items[index].stamp = self->pointer_stamp; self->pointer_items[index].stamp = self->pointer_stamp;
self->pointer_items[index].bpp = pointer_item->bpp; self->pointer_items[index].bpp = pointer_item->bpp;
self->pointer_items[index].width = pointer_item->width;
self->pointer_items[index].height = pointer_item->height;
xrdp_wm_send_pointer(self->wm, index, xrdp_wm_send_pointer(self->wm, index,
self->pointer_items[index].data, self->pointer_items[index].data,
self->pointer_items[index].mask, self->pointer_items[index].mask,
self->pointer_items[index].x, self->pointer_items[index].x,
self->pointer_items[index].y, self->pointer_items[index].y,
self->pointer_items[index].bpp); self->pointer_items[index].bpp,
self->pointer_items[index].width,
self->pointer_items[index].height);
self->wm->current_pointer = index; self->wm->current_pointer = index;
LOG_DEVEL(LOG_LEVEL_TRACE, "adding pointer at %d", index); LOG_DEVEL(LOG_LEVEL_TRACE, "adding pointer at %d", index);
return index; return index;
@@ -680,9 +686,9 @@ xrdp_cache_add_pointer_static(struct xrdp_cache *self,
self->pointer_items[index].x = pointer_item->x; self->pointer_items[index].x = pointer_item->x;
self->pointer_items[index].y = pointer_item->y; self->pointer_items[index].y = pointer_item->y;
g_memcpy(self->pointer_items[index].data, g_memcpy(self->pointer_items[index].data,
pointer_item->data, 32 * 32 * 4); pointer_item->data, 96 * 96 * 4);
g_memcpy(self->pointer_items[index].mask, g_memcpy(self->pointer_items[index].mask,
pointer_item->mask, 32 * 32 / 8); pointer_item->mask, 96 * 96 / 8);
self->pointer_items[index].stamp = self->pointer_stamp; self->pointer_items[index].stamp = self->pointer_stamp;
self->pointer_items[index].bpp = pointer_item->bpp; self->pointer_items[index].bpp = pointer_item->bpp;
xrdp_wm_send_pointer(self->wm, index, xrdp_wm_send_pointer(self->wm, index,
@@ -690,7 +696,9 @@ xrdp_cache_add_pointer_static(struct xrdp_cache *self,
self->pointer_items[index].mask, self->pointer_items[index].mask,
self->pointer_items[index].x, self->pointer_items[index].x,
self->pointer_items[index].y, self->pointer_items[index].y,
self->pointer_items[index].bpp); self->pointer_items[index].bpp,
self->pointer_items[index].width,
self->pointer_items[index].height);
self->wm->current_pointer = index; self->wm->current_pointer = index;
LOG_DEVEL(LOG_LEVEL_TRACE, "adding pointer at %d", index); LOG_DEVEL(LOG_LEVEL_TRACE, "adding pointer at %d", index);
return index; return index;
+16 -2
View File
@@ -422,6 +422,7 @@ xrdp_mm_setup_mod1(struct xrdp_mm *self)
self->mod->server_composite = server_composite; self->mod->server_composite = server_composite;
self->mod->server_paint_rects = server_paint_rects; self->mod->server_paint_rects = server_paint_rects;
self->mod->server_session_info = server_session_info; self->mod->server_session_info = server_session_info;
self->mod->server_set_pointer_large = server_set_pointer_large;
self->mod->si = &(self->wm->session->si); self->mod->si = &(self->wm->session->si);
} }
} }
@@ -3463,7 +3464,7 @@ server_set_pointer(struct xrdp_mod *mod, int x, int y,
struct xrdp_wm *wm; struct xrdp_wm *wm;
wm = (struct xrdp_wm *)(mod->wm); wm = (struct xrdp_wm *)(mod->wm);
xrdp_wm_pointer(wm, data, mask, x, y, 0); xrdp_wm_pointer(wm, data, mask, x, y, 0, 32, 32);
return 0; return 0;
} }
@@ -3475,7 +3476,20 @@ server_set_pointer_ex(struct xrdp_mod *mod, int x, int y,
struct xrdp_wm *wm; struct xrdp_wm *wm;
wm = (struct xrdp_wm *)(mod->wm); wm = (struct xrdp_wm *)(mod->wm);
xrdp_wm_pointer(wm, data, mask, x, y, bpp); xrdp_wm_pointer(wm, data, mask, x, y, bpp, 32, 32);
return 0;
}
/*****************************************************************************/
int
server_set_pointer_large(struct xrdp_mod *mod, int x, int y,
char *data, char *mask, int bpp,
int width, int height)
{
struct xrdp_wm *wm;
wm = (struct xrdp_wm *)(mod->wm);
xrdp_wm_pointer(wm, data, mask, x, y, bpp, width, height);
return 0; return 0;
} }
+10 -3
View File
@@ -171,7 +171,10 @@ struct xrdp_mod
int flags, int frame_id); int flags, int frame_id);
int (*server_session_info)(struct xrdp_mod *v, const char *data, int (*server_session_info)(struct xrdp_mod *v, const char *data,
int data_bytes); int data_bytes);
tintptr server_dumby[100 - 46]; /* align, 100 minus the number of server int (*server_set_pointer_large)(struct xrdp_mod *v, int x, int y,
char *data, char *mask, int bpp,
int width, int height);
tintptr server_dumby[100 - 47]; /* align, 100 minus the number of server
functions above */ functions above */
/* common */ /* common */
tintptr handle; /* pointer to self as int */ tintptr handle; /* pointer to self as int */
@@ -242,9 +245,13 @@ struct xrdp_pointer_item
int stamp; int stamp;
int x; /* hotspot */ int x; /* hotspot */
int y; int y;
char data[32 * 32 * 4]; int pad0;
char mask[32 * 32 / 8]; char data[96 * 96 * 4];
char mask[96 * 96 / 8];
int bpp; int bpp;
int width;
int height;
int pad1;
}; };
struct xrdp_brush_item struct xrdp_brush_item
+16 -12
View File
@@ -199,23 +199,26 @@ xrdp_wm_get_pixel(char *data, int x, int y, int width, int bpp)
/*****************************************************************************/ /*****************************************************************************/
int int
xrdp_wm_pointer(struct xrdp_wm *self, char *data, char *mask, int x, int y, xrdp_wm_pointer(struct xrdp_wm *self, char *data, char *mask, int x, int y,
int bpp) int bpp, int width, int height)
{ {
int bytes; int bytes;
struct xrdp_pointer_item pointer_item; struct xrdp_pointer_item *pointer_item;
if (bpp == 0) if (bpp == 0)
{ {
bpp = 24; bpp = 24;
} }
bytes = ((bpp + 7) / 8) * 32 * 32; bytes = ((bpp + 7) / 8) * width * height;
g_memset(&pointer_item, 0, sizeof(struct xrdp_pointer_item)); pointer_item = g_new0(struct xrdp_pointer_item, 1);
pointer_item.x = x; pointer_item->x = x;
pointer_item.y = y; pointer_item->y = y;
pointer_item.bpp = bpp; pointer_item->bpp = bpp;
g_memcpy(pointer_item.data, data, bytes); pointer_item->width = width;
g_memcpy(pointer_item.mask, mask, 32 * 32 / 8); pointer_item->height = height;
self->screen->pointer = xrdp_cache_add_pointer(self->cache, &pointer_item); g_memcpy(pointer_item->data, data, bytes);
g_memcpy(pointer_item->mask, mask, width * height / 8);
self->screen->pointer = xrdp_cache_add_pointer(self->cache, pointer_item);
g_free(pointer_item);
return 0; return 0;
} }
@@ -334,10 +337,11 @@ xrdp_wm_load_pointer(struct xrdp_wm *self, char *file_name, char *data,
/*****************************************************************************/ /*****************************************************************************/
int int
xrdp_wm_send_pointer(struct xrdp_wm *self, int cache_idx, xrdp_wm_send_pointer(struct xrdp_wm *self, int cache_idx,
char *data, char *mask, int x, int y, int bpp) char *data, char *mask, int x, int y, int bpp,
int width, int height)
{ {
return libxrdp_send_pointer(self->session, cache_idx, data, mask, return libxrdp_send_pointer(self->session, cache_idx, data, mask,
x, y, bpp); x, y, bpp, width, height);
} }
/*****************************************************************************/ /*****************************************************************************/
+60
View File
@@ -1247,6 +1247,63 @@ process_server_paint_rect_shmem_ex(struct mod *amod, struct stream *s)
return rv; return rv;
} }
/******************************************************************************/
/* return error */
static int
process_server_set_pointer_shmfd(struct mod *amod, struct stream *s)
{
int rv;
int x;
int y;
int bpp;
int Bpp;
int width;
int height;
int fd;
int recv_bytes;
int shmembytes;
unsigned int num_fds;
void *shmemptr;
char *cur_data;
char *cur_mask;
char msg[4];
rv = 0;
in_sint16_le(s, x);
in_sint16_le(s, y);
in_uint16_le(s, bpp);
in_uint16_le(s, width);
in_uint16_le(s, height);
fd = -1;
num_fds = -1;
if (g_tcp_can_recv(amod->trans->sck, 5000) == 0)
{
return 1;
}
recv_bytes = g_sck_recv_fd_set(amod->trans->sck, msg, 4, &fd, 1, &num_fds);
LOG_DEVEL(LOG_LEVEL_DEBUG, "process_server_set_pointer_shmfd: "
"g_sck_recv_fd_set rv %d fd %d", recv_bytes, fd);
if (recv_bytes == 4)
{
if (num_fds == 1)
{
Bpp = (bpp == 0) ? 3 : (bpp + 7) / 8;
shmembytes = width * height * Bpp + width * height / 8;
if (g_file_map(fd, 1, 1, shmembytes, &shmemptr) == 0)
{
cur_data = (char *)shmemptr;
cur_mask = cur_data + width * height * Bpp;
rv = amod->server_set_pointer_large(amod, x, y,
cur_data, cur_mask,
bpp, width, height);
g_munmap(shmemptr, shmembytes);
}
g_file_close(fd);
}
}
return rv;
}
/******************************************************************************/ /******************************************************************************/
/* return error */ /* return error */
static int static int
@@ -1472,6 +1529,9 @@ lib_mod_process_orders(struct mod *mod, int type, struct stream *s)
case 61: /* server_paint_rect_shmem_ex */ case 61: /* server_paint_rect_shmem_ex */
rv = process_server_paint_rect_shmem_ex(mod, s); rv = process_server_paint_rect_shmem_ex(mod, s);
break; break;
case 63: /* server_set_pointer_shmfd */
rv = process_server_set_pointer_shmfd(mod, s);
break;
default: default:
LOG_DEVEL(LOG_LEVEL_WARNING, LOG_DEVEL(LOG_LEVEL_WARNING,
"lib_mod_process_orders: unknown order type %d", type); "lib_mod_process_orders: unknown order type %d", type);
+6 -2
View File
@@ -155,8 +155,12 @@ struct mod
int num_crects, short *crects, int num_crects, short *crects,
char *data, int width, int height, char *data, int width, int height,
int flags, int frame_id); int flags, int frame_id);
int (*server_session_info)(struct mod *v, const char *data,
tintptr server_dumby[100 - 45]; /* align, 100 minus the number of server int data_bytes);
int (*server_set_pointer_large)(struct mod *v, int x, int y,
char *data, char *mask, int bpp,
int width, int height);
tintptr server_dumby[100 - 47]; /* align, 100 minus the number of server
functions above */ functions above */
/* common */ /* common */
tintptr handle; /* pointer to self as long */ tintptr handle; /* pointer to self as long */