add large cursor support, posix shm
This commit is contained in:
parent
544ead05e7
commit
c250529e8e
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
60
xup/xup.c
60
xup/xup.c
@ -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);
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user