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

View File

@ -567,4 +567,8 @@
#define RDP_MPPC_FLUSH 0x80
#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 */

View File

@ -56,6 +56,7 @@
#if defined(HAVE_SYS_PRCTL_H)
#include <sys/prctl.h>
#endif
#include <sys/mman.h>
#include <dlfcn.h>
#include <arpa/inet.h>
#include <netdb.h>
@ -2353,6 +2354,37 @@ nomem:
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 */
#if !defined(_WIN32)

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_seek(int fd, int offset);
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_get_cloexec(int fd);
int g_file_set_cloexec(int fd, int status);

View File

@ -213,9 +213,12 @@ struct xrdp_client_info
* data */
unsigned int session_physical_width; /* in mm */
unsigned int session_physical_height; /* in mm */
int large_pointer_support_flags;
};
/* 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

View File

@ -705,7 +705,8 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
/*****************************************************************************/
int EXPORT_CC
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;
char *p;
@ -714,12 +715,21 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
int i;
int j;
int data_bytes;
int mask_bytes;
LOG_DEVEL(LOG_LEVEL_DEBUG, "sending cursor");
if (bpp == 0)
{
bpp = 24;
}
if (width == 0)
{
width = 32;
}
if (height == 0)
{
height = 32;
}
/* error check */
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,
"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);
return 1;
}
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 */
{
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;
}
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 */
}
}
@ -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, 0); /* pad */
data_bytes = 3072;
LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPBCGR] TS_POINTER_PDU "
"messageType %d (TS_PTRMSGTYPE_COLOR), pad2Octets <ignored>",
RDP_POINTER_COLOR);
@ -783,7 +788,6 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
RDP_POINTER_POINTER);
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, x); /* hotSpot.xPos */
out_uint16_le(s, y); /* hotSpot.yPos */
out_uint16_le(s, 32); /* width */
out_uint16_le(s, 32); /* height */
out_uint16_le(s, 128); /* lengthAndMask */
out_uint16_le(s, width); /* width */
out_uint16_le(s, height); /* height */
out_uint16_le(s, mask_bytes); /* lengthAndMask */
out_uint16_le(s, data_bytes); /* lengthXorMask */
/* xorMaskData */
switch (bpp)
{
//case 15: /* coverity: this is logically dead code */
case 15:
/* fallthrough */
case 16:
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);
p16++;
@ -814,9 +819,9 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
break;
case 24:
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);
p++;
@ -829,9 +834,9 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
break;
case 32:
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);
p32++;
@ -840,7 +845,7 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
break;
}
out_uint8a(s, mask, 128); /* andMaskData */
out_uint8a(s, mask, mask_bytes); /* andMaskData */
out_uint8(s, 0); /* pad */
s_mark_end(s);
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 "
"cachedPointerUpdateData = { cacheIndex %d, "
"hotSpot.xPos %d, hotSpot.yPos %d, width 32, "
"height 32, lengthAndMask 128, lengthXorMask %d, "
"hotSpot.xPos %d, hotSpot.yPos %d, width %d, "
"height %d, lengthAndMask %d, lengthXorMask %d, "
"xorMaskData <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,
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 "
"newPointerUpdateData.xorBpp %d, "
"newPointerUpdateData.colorPtrAttr = { cacheIndex %d, "
"hotSpot.xPos %d, hotSpot.yPos %d, width 32, "
"height 32, lengthAndMask 128, lengthXorMask %d, "
"hotSpot.xPos %d, hotSpot.yPos %d, width %d, "
"height %d, lengthAndMask %d, lengthXorMask %d, "
"xorMaskData <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,
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 "
"cacheIndex %d, "
"hotSpot.xPos %d, hotSpot.yPos %d, width 32, "
"height 32, lengthAndMask 128, lengthXorMask %d, "
"hotSpot.xPos %d, hotSpot.yPos %d, width %d, "
"height %d, lengthAndMask %d, lengthXorMask %d, "
"xorMaskData <omitted from log>, "
"andMaskData <omitted from log>",
cache_idx, x, y, data_bytes);
cache_idx, x, y, width, height, mask_bytes, data_bytes);
}
else
{
LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_POINTERATTRIBUTE "
"xorBpp %d, colorPtrAttr = { cacheIndex %d, "
"hotSpot.xPos %d, hotSpot.yPos %d, width 32, "
"height 32, lengthAndMask 128, lengthXorMask %d, "
"hotSpot.xPos %d, hotSpot.yPos %d, width %d, "
"height %d, lengthAndMask %d, lengthXorMask %d, "
"xorMaskData <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,
RDP_DATA_PDU_POINTER);

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
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
libxrdp_set_pointer(struct xrdp_session *session, int cache_idx);
int

View File

@ -630,6 +630,18 @@ xrdp_caps_process_multifragmentupdate(struct xrdp_rdp *self, struct stream *s,
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
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");
xrdp_caps_process_multifragmentupdate(self, s, len);
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:
LOG_DEVEL(LOG_LEVEL_INFO, "Received [MS-RDPBCGR] TS_CONFIRM_ACTIVE_PDU - TS_CAPS_SET "
"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;
}
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");
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 "
"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 */
caps_count++;
out_uint16_le(s, CAPSTYPE_FRAME_ACKNOWLEDGE);

View File

@ -149,10 +149,11 @@ int
xrdp_wm_pu(struct xrdp_wm *self, struct xrdp_bitmap *control);
int
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
xrdp_wm_pointer(struct xrdp_wm *self, char *data, char *mask, int x, int y,
int bpp);
int bpp, int width, int height);
int
callback(intptr_t id, int msg, intptr_t param1, intptr_t param2,
intptr_t param3, intptr_t param4);
@ -513,6 +514,10 @@ int
server_set_pointer_ex(struct xrdp_mod *mod, int x, int y,
char *data, char *mask, int bpp);
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);
int
server_msg(struct xrdp_mod *mod, const char *msg, int code);

View File

@ -619,10 +619,12 @@ xrdp_cache_add_pointer(struct xrdp_cache *self,
if (self->pointer_items[i].x == pointer_item->x &&
self->pointer_items[i].y == pointer_item->y &&
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,
pointer_item->mask, 32 * 32 / 8) == 0 &&
self->pointer_items[i].bpp == pointer_item->bpp)
pointer_item->mask, 96 * 96 / 8) == 0 &&
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;
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].y = pointer_item->y;
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,
pointer_item->mask, 32 * 32 / 8);
pointer_item->mask, 96 * 96 / 8);
self->pointer_items[index].stamp = self->pointer_stamp;
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,
self->pointer_items[index].data,
self->pointer_items[index].mask,
self->pointer_items[index].x,
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;
LOG_DEVEL(LOG_LEVEL_TRACE, "adding pointer at %d", 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].y = pointer_item->y;
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,
pointer_item->mask, 32 * 32 / 8);
pointer_item->mask, 96 * 96 / 8);
self->pointer_items[index].stamp = self->pointer_stamp;
self->pointer_items[index].bpp = pointer_item->bpp;
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].x,
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;
LOG_DEVEL(LOG_LEVEL_TRACE, "adding pointer at %d", index);
return index;

View File

@ -422,6 +422,7 @@ xrdp_mm_setup_mod1(struct xrdp_mm *self)
self->mod->server_composite = server_composite;
self->mod->server_paint_rects = server_paint_rects;
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);
}
}
@ -3463,7 +3464,7 @@ server_set_pointer(struct xrdp_mod *mod, int x, int y,
struct xrdp_wm *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;
}
@ -3475,7 +3476,20 @@ server_set_pointer_ex(struct xrdp_mod *mod, int x, int y,
struct xrdp_wm *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;
}

View File

@ -171,7 +171,10 @@ struct xrdp_mod
int flags, int frame_id);
int (*server_session_info)(struct xrdp_mod *v, const char *data,
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 */
/* common */
tintptr handle; /* pointer to self as int */
@ -242,9 +245,13 @@ struct xrdp_pointer_item
int stamp;
int x; /* hotspot */
int y;
char data[32 * 32 * 4];
char mask[32 * 32 / 8];
int pad0;
char data[96 * 96 * 4];
char mask[96 * 96 / 8];
int bpp;
int width;
int height;
int pad1;
};
struct xrdp_brush_item

View File

@ -199,23 +199,26 @@ xrdp_wm_get_pixel(char *data, int x, int y, int width, int bpp)
/*****************************************************************************/
int
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;
struct xrdp_pointer_item pointer_item;
struct xrdp_pointer_item *pointer_item;
if (bpp == 0)
{
bpp = 24;
}
bytes = ((bpp + 7) / 8) * 32 * 32;
g_memset(&pointer_item, 0, sizeof(struct xrdp_pointer_item));
pointer_item.x = x;
pointer_item.y = y;
pointer_item.bpp = bpp;
g_memcpy(pointer_item.data, data, bytes);
g_memcpy(pointer_item.mask, mask, 32 * 32 / 8);
self->screen->pointer = xrdp_cache_add_pointer(self->cache, &pointer_item);
bytes = ((bpp + 7) / 8) * width * height;
pointer_item = g_new0(struct xrdp_pointer_item, 1);
pointer_item->x = x;
pointer_item->y = y;
pointer_item->bpp = bpp;
pointer_item->width = width;
pointer_item->height = height;
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;
}
@ -334,10 +337,11 @@ xrdp_wm_load_pointer(struct xrdp_wm *self, char *file_name, char *data,
/*****************************************************************************/
int
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,
x, y, bpp);
x, y, bpp, width, height);
}
/*****************************************************************************/

View File

@ -1247,6 +1247,63 @@ process_server_paint_rect_shmem_ex(struct mod *amod, struct stream *s)
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 */
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 */
rv = process_server_paint_rect_shmem_ex(mod, s);
break;
case 63: /* server_set_pointer_shmfd */
rv = process_server_set_pointer_shmfd(mod, s);
break;
default:
LOG_DEVEL(LOG_LEVEL_WARNING,
"lib_mod_process_orders: unknown order type %d", type);

View File

@ -155,8 +155,12 @@ struct mod
int num_crects, short *crects,
char *data, int width, int height,
int flags, int frame_id);
tintptr server_dumby[100 - 45]; /* align, 100 minus the number of server
int (*server_session_info)(struct mod *v, const char *data,
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 */
/* common */
tintptr handle; /* pointer to self as long */