added new pointers

git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/rdesktop/trunk@1520 423420c4-83ab-492f-b58f-81f9feb106b5
This commit is contained in:
Jay Sorg 2009-10-25 21:36:17 +00:00
parent 6bc8c23da3
commit fdcd8d7591
5 changed files with 151 additions and 20 deletions

View File

@ -149,7 +149,8 @@ enum RDP_POINTER_PDU_TYPE
RDP_POINTER_SYSTEM = 1,
RDP_POINTER_MOVE = 3,
RDP_POINTER_COLOR = 6,
RDP_POINTER_CACHED = 7
RDP_POINTER_CACHED = 7,
RDP_POINTER_NEW = 8
};
enum RDP_SYSTEM_POINTER_TYPE
@ -244,6 +245,7 @@ enum RDP_INPUT_DEVICE
#define RDP_CAPSET_POINTER 8
#define RDP_CAPLEN_POINTER 0x08
#define RDP_CAPLEN_NEWPOINTER 0x0a
#define RDP_CAPSET_SHARE 9
#define RDP_CAPLEN_SHARE 0x08

View File

@ -144,6 +144,7 @@ void rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint1
uint16 param2);
void rdp_send_client_window_status(int status);
void process_colour_pointer_pdu(STREAM s);
void process_new_pointer_pdu(STREAM s);
void process_cached_pointer_pdu(STREAM s);
void process_system_pointer_pdu(STREAM s);
void process_bitmap_updates(STREAM s);
@ -249,7 +250,7 @@ void ui_destroy_bitmap(RD_HBITMAP bmp);
RD_HGLYPH ui_create_glyph(int width, int height, uint8 * data);
void ui_destroy_glyph(RD_HGLYPH glyph);
RD_HCURSOR ui_create_cursor(unsigned int x, unsigned int y, int width, int height, uint8 * andmask,
uint8 * xormask);
uint8 * xormask, int bpp);
void ui_set_cursor(RD_HCURSOR cursor);
void ui_destroy_cursor(RD_HCURSOR cursor);
void ui_set_null_cursor(void);

82
rdp.c
View File

@ -778,6 +778,18 @@ rdp_out_pointer_caps(STREAM s)
out_uint16_le(s, 20); /* Cache size */
}
/* Output new pointer capability set */
static void
rdp_out_newpointer_caps(STREAM s)
{
out_uint16_le(s, RDP_CAPSET_POINTER);
out_uint16_le(s, RDP_CAPLEN_NEWPOINTER);
out_uint16_le(s, 1); /* Colour pointer */
out_uint16_le(s, 20); /* Cache size */
out_uint16_le(s, 20); /* Cache size for new pointers */
}
/* Output share capability set */
static void
rdp_out_share_caps(STREAM s)
@ -855,12 +867,23 @@ rdp_send_confirm_active(void)
uint32 sec_flags = g_encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG;
uint16 caplen =
RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
RDP_CAPLEN_COLCACHE +
RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +
RDP_CAPLEN_SHARE +
RDP_CAPLEN_BRUSHCACHE + 0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */ +
4 /* w2k fix, sessionid */ ;
if (g_use_rdp5)
{
caplen += RDP_CAPLEN_BMPCACHE2;
caplen += RDP_CAPLEN_NEWPOINTER;
}
else
{
caplen += RDP_CAPLEN_BMPCACHE;
caplen += RDP_CAPLEN_POINTER;
}
s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE));
@ -879,11 +902,19 @@ rdp_send_confirm_active(void)
rdp_out_general_caps(s);
rdp_out_bitmap_caps(s);
rdp_out_order_caps(s);
g_use_rdp5 ? rdp_out_bmpcache2_caps(s) : rdp_out_bmpcache_caps(s);
if (g_use_rdp5)
{
rdp_out_bmpcache2_caps(s);
rdp_out_newpointer_caps(s);
}
else
{
rdp_out_bmpcache_caps(s);
rdp_out_pointer_caps(s);
}
rdp_out_colcache_caps(s);
rdp_out_activate_caps(s);
rdp_out_control_caps(s);
rdp_out_pointer_caps(s);
rdp_out_share_caps(s);
rdp_out_brushcache_caps(s);
@ -1022,11 +1053,13 @@ process_demand_active(STREAM s)
}
/* Process a colour pointer PDU */
void
process_colour_pointer_pdu(STREAM s)
static void
process_colour_pointer_common(STREAM s, int bpp)
{
uint16 x, y, width, height, cache_idx, masklen, datalen;
uint8 *mask, *data;
uint16 width, height, cache_idx, masklen, datalen;
sint16 x, y;
uint8 * mask;
uint8 * data;
RD_HCURSOR cursor;
in_uint16_le(s, cache_idx);
@ -1038,11 +1071,38 @@ process_colour_pointer_pdu(STREAM s)
in_uint16_le(s, datalen);
in_uint8p(s, data, datalen);
in_uint8p(s, mask, masklen);
cursor = ui_create_cursor(x, y, width, height, mask, data);
if ((width != 32) || (height != 32))
{
warning("process_colour_pointer_common: "
"width %d height %d\n", width, height);
}
/* sometimes x or y is out of bounds */
x = MAX(x, 0);
x = MIN(x, width - 1);
y = MAX(y, 0);
y = MIN(y, height - 1);
cursor = ui_create_cursor(x, y, width, height, mask, data, bpp);
ui_set_cursor(cursor);
cache_put_cursor(cache_idx, cursor);
}
/* Process a colour pointer PDU */
void
process_colour_pointer_pdu(STREAM s)
{
process_colour_pointer_common(s, 24);
}
/* Process a New Pointer PDU - these pointers have variable bit depth */
void
process_new_pointer_pdu(STREAM s)
{
int xor_bpp;
in_uint16_le(s, xor_bpp);
process_colour_pointer_common(s, xor_bpp);
}
/* Process a cached pointer PDU */
void
process_cached_pointer_pdu(STREAM s)
@ -1102,6 +1162,10 @@ process_pointer_pdu(STREAM s)
process_system_pointer_pdu(s);
break;
case RDP_POINTER_NEW:
process_new_pointer_pdu(s);
break;
default:
unimpl("Pointer message 0x%x\n", message_type);
}

3
rdp5.c
View File

@ -111,6 +111,9 @@ rdp5_process(STREAM s)
case 10: /* cached pointer */
process_cached_pointer_pdu(ts);
break;
case 11:
process_new_pointer_pdu(ts);
break;
default:
unimpl("RDP5 opcode %d\n", type);
}

79
xwin.c
View File

@ -2099,7 +2099,7 @@ ui_create_window(void)
/* create invisible 1x1 cursor to be used as null cursor */
if (g_null_cursor == NULL)
g_null_cursor = ui_create_cursor(0, 0, 1, 1, null_pointer_mask, null_pointer_data);
g_null_cursor = ui_create_cursor(0, 0, 1, 1, null_pointer_mask, null_pointer_data, 24);
if (g_seamless_rdp)
{
@ -2772,9 +2772,62 @@ ui_destroy_glyph(RD_HGLYPH glyph)
XFreePixmap(g_display, (Pixmap) glyph);
}
/* convert next pixel to 32 bpp */
static int
get_next_xor_pixel(uint8 * xormask, int bpp, int * k)
{
int rv = 0;
PixelColour pc;
uint8 * s8;
uint16 * s16;
switch (bpp)
{
case 1:
s8 = xormask + (*k) / 8;
rv = (*s8) & (0x80 >> ((*k) % 8));
rv = rv ? 0xffffff : 0;
(*k) += 1;
break;
case 8:
s8 = xormask + *k;
/* should use colour map */
rv = s8[0];
rv = rv ? 0xffffff : 0;
(*k) += 1;
break;
case 15:
s16 = (uint16 *) xormask;
SPLITCOLOUR15(s16[*k], pc);
rv = (pc.red << 16) | (pc.green << 8) | pc.blue;
(*k) += 1;
break;
case 16:
s16 = (uint16 *) xormask;
SPLITCOLOUR16(s16[*k], pc);
rv = (pc.red << 16) | (pc.green << 8) | pc.blue;
(*k) += 1;
break;
case 24:
s8 = xormask + *k;
rv = (s8[0] << 16) | (s8[1] << 8) | s8[2];
(*k) += 3;
break;
case 32:
s8 = xormask + *k;
rv = (s8[1] << 16) | (s8[2] << 8) | s8[3];
(*k) += 4;
break;
default:
error("unknown bpp in get_next_xor_pixel %d\n", bpp);
break;
}
return rv;
}
RD_HCURSOR
ui_create_cursor(unsigned int x, unsigned int y, int width, int height,
uint8 * andmask, uint8 * xormask)
uint8 * andmask, uint8 * xormask, int bpp)
{
RD_HGLYPH maskglyph, cursorglyph;
XColor bg, fg;
@ -2782,9 +2835,10 @@ ui_create_cursor(unsigned int x, unsigned int y, int width, int height,
uint8 *cursor, *pcursor;
uint8 *mask, *pmask;
uint8 nextbit;
int scanline, offset;
int i, j;
int scanline, offset, delta;
int i, j, k;
k = 0;
scanline = (width + 7) / 8;
offset = scanline * height;
@ -2793,11 +2847,19 @@ ui_create_cursor(unsigned int x, unsigned int y, int width, int height,
mask = (uint8 *) xmalloc(offset);
memset(mask, 0, offset);
if (bpp == 1)
{
offset = 0;
delta = scanline;
}
else
{
offset = scanline * height - scanline;
delta = -scanline;
}
/* approximate AND and XOR masks with a monochrome X pointer */
for (i = 0; i < height; i++)
{
offset -= scanline;
pcursor = &cursor[offset];
pmask = &mask[offset];
@ -2805,7 +2867,7 @@ ui_create_cursor(unsigned int x, unsigned int y, int width, int height,
{
for (nextbit = 0x80; nextbit != 0; nextbit >>= 1)
{
if (xormask[0] || xormask[1] || xormask[2])
if (get_next_xor_pixel(xormask, bpp, &k))
{
*pcursor |= (~(*andmask) & nextbit);
*pmask |= nextbit;
@ -2815,14 +2877,13 @@ ui_create_cursor(unsigned int x, unsigned int y, int width, int height,
*pcursor |= ((*andmask) & nextbit);
*pmask |= (~(*andmask) & nextbit);
}
xormask += 3;
}
andmask++;
pcursor++;
pmask++;
}
offset += delta;
}
fg.red = fg.blue = fg.green = 0xffff;