merges from authentic8

ulab-next
Jay Sorg 11 years ago
commit c1b7cbd657

@ -1,6 +1,5 @@
EXTRA_DIST = bootstrap COPYING design.txt faq-compile.txt faq-general.txt file-loc.txt install.txt prog_std.txt readme.txt EXTRA_DIST = bootstrap COPYING design.txt faq-compile.txt faq-general.txt file-loc.txt install.txt prog_std.txt readme.txt
if XRDP_NEUTRINORDP if XRDP_NEUTRINORDP
NEUTRINORDPDIR = neutrinordp NEUTRINORDPDIR = neutrinordp
else else

@ -416,6 +416,7 @@
#define RDP_ORDER_TRIBLT 14 #define RDP_ORDER_TRIBLT 14
#define RDP_ORDER_POLYLINE 22 #define RDP_ORDER_POLYLINE 22
#define RDP_ORDER_TEXT2 27 #define RDP_ORDER_TEXT2 27
#define RDP_ORDER_COMPOSITE 37 /* 0x25 */
#define RDP_ORDER_RAW_BMPCACHE 0 #define RDP_ORDER_RAW_BMPCACHE 0
#define RDP_ORDER_COLCACHE 1 #define RDP_ORDER_COLCACHE 1
@ -463,6 +464,10 @@
#define WM_BUTTON4DOWN 108 #define WM_BUTTON4DOWN 108
#define WM_BUTTON5UP 109 #define WM_BUTTON5UP 109
#define WM_BUTTON5DOWN 110 #define WM_BUTTON5DOWN 110
#define WM_BUTTON6UP 111
#define WM_BUTTON6DOWN 112
#define WM_BUTTON7UP 113
#define WM_BUTTON7DOWN 114
#define WM_INVALIDATE 200 #define WM_INVALIDATE 200
#define CB_ITEMCHANGE 300 #define CB_ITEMCHANGE 300
@ -561,5 +566,6 @@
#define XRDP_MAX_BITMAP_CACHE_ID 3 #define XRDP_MAX_BITMAP_CACHE_ID 3
#define XRDP_MAX_BITMAP_CACHE_IDX 2000 #define XRDP_MAX_BITMAP_CACHE_IDX 2000
#define XRDP_BITMAP_CACHE_ENTRIES 2048
#endif #endif

@ -628,6 +628,25 @@ libxrdp_orders_mem_blt(struct xrdp_session *session, int cache_id,
srcx, srcy, cache_idx, rect); srcx, srcy, cache_idx, rect);
} }
/******************************************************************************/
int DEFAULT_CC
libxrdp_orders_composite_blt(struct xrdp_session* session, int srcidx,
int srcformat, int srcwidth, int srcrepeat,
int* srctransform, int mskflags,
int mskidx, int mskformat, int mskwidth,
int mskrepeat, int op, int srcx, int srcy,
int mskx, int msky, int dstx, int dsty,
int width, int height, int dstformat,
struct xrdp_rect* rect)
{
return xrdp_orders_composite_blt((struct xrdp_orders*)session->orders,
srcidx, srcformat, srcwidth, srcrepeat,
srctransform, mskflags,
mskidx, mskformat, mskwidth, mskrepeat,
op, srcx, srcy, mskx, msky, dstx, dsty,
width, height, dstformat, rect);
}
/******************************************************************************/ /******************************************************************************/
int EXPORT_CC int EXPORT_CC
libxrdp_orders_text(struct xrdp_session *session, libxrdp_orders_text(struct xrdp_session *session,

@ -197,6 +197,28 @@ struct xrdp_orders_state
int text_y; int text_y;
int text_len; int text_len;
char* text_data; char* text_data;
int com_blt_srcidx; /* RDP_ORDER_COMPOSITE */ /* 2 */
int com_blt_srcformat; /* 2 */
int com_blt_srcwidth; /* 2 */
int com_blt_srcrepeat; /* 1 */
int com_blt_srctransform[10]; /* 40 */
int com_blt_mskflags; /* 1 */
int com_blt_mskidx; /* 2 */
int com_blt_mskformat; /* 2 */
int com_blt_mskwidth; /* 2 */
int com_blt_mskrepeat; /* 1 */
int com_blt_op; /* 1 */
int com_blt_srcx; /* 2 */
int com_blt_srcy; /* 2 */
int com_blt_mskx; /* 2 */
int com_blt_msky; /* 2 */
int com_blt_dstx; /* 2 */
int com_blt_dsty; /* 2 */
int com_blt_width; /* 2 */
int com_blt_height; /* 2 */
int com_blt_dstformat; /* 2 */
}; };
/* orders */ /* orders */
@ -212,6 +234,7 @@ struct xrdp_orders
int order_level; /* inc for every call to xrdp_orders_init */ int order_level; /* inc for every call to xrdp_orders_init */
struct xrdp_orders_state orders_state; struct xrdp_orders_state orders_state;
void* jpeg_han; void* jpeg_han;
int rfx_min_pixel;
}; };
#define PROTO_RDP_40 1 #define PROTO_RDP_40 1
@ -379,6 +402,15 @@ xrdp_orders_mem_blt(struct xrdp_orders* self, int cache_id,
int rop, int srcx, int srcy, int rop, int srcx, int srcy,
int cache_idx, struct xrdp_rect* rect); int cache_idx, struct xrdp_rect* rect);
int APP_CC int APP_CC
xrdp_orders_composite_blt(struct xrdp_orders* self, int srcidx,
int srcformat, int srcwidth,
int srcrepeat, int* srctransform, int mskflags,
int mskidx, int mskformat, int mskwidth,
int mskrepeat, int op, int srcx, int srcy,
int mskx, int msky, int dstx, int dsty,
int width, int height, int dstformat,
struct xrdp_rect* rect);
int APP_CC
xrdp_orders_text(struct xrdp_orders* self, xrdp_orders_text(struct xrdp_orders* self,
int font, int flags, int mixmode, int font, int flags, int mixmode,
int fg_color, int bg_color, int fg_color, int bg_color,

@ -40,13 +40,15 @@ struct xrdp_pen
int color; int color;
}; };
/* 2.2.2.2.1.2.5.1 Cache Glyph Data (TS_CACHE_GLYPH_DATA) */
struct xrdp_font_char struct xrdp_font_char
{ {
int offset; int offset; /* x */
int baseline; int baseline; /* y */
int width; int width; /* cx */
int height; int height; /* cy */
int incby; int incby;
int bpp;
char* data; char* data;
}; };
@ -128,6 +130,16 @@ libxrdp_orders_mem_blt(struct xrdp_session* session, int cache_id,
int rop, int srcx, int srcy, int rop, int srcx, int srcy,
int cache_idx, struct xrdp_rect* rect); int cache_idx, struct xrdp_rect* rect);
int DEFAULT_CC int DEFAULT_CC
libxrdp_orders_composite_blt(struct xrdp_session* session, int srcidx,
int srcformat, int srcwidth, int srcrepeat,
int* srctransform, int mskflags,
int mskidx, int mskformat, int mskwidth,
int mskrepeat, int op, int srcx, int srcy,
int mskx, int msky, int dstx, int dsty,
int width, int height, int dstformat,
struct xrdp_rect* rect);
int DEFAULT_CC
libxrdp_orders_text(struct xrdp_session* session, libxrdp_orders_text(struct xrdp_session* session,
int font, int flags, int mixmode, int font, int flags, int mixmode,
int fg_color, int bg_color, int fg_color, int bg_color,

@ -48,6 +48,11 @@ xrdp_orders_create(struct xrdp_session *session, struct xrdp_rdp *rdp_layer)
self->orders_state.clip_right = 1; /* silly rdp right clip */ self->orders_state.clip_right = 1; /* silly rdp right clip */
self->orders_state.clip_bottom = 1; /* silly rdp bottom clip */ self->orders_state.clip_bottom = 1; /* silly rdp bottom clip */
self->jpeg_han = xrdp_jpeg_init(); self->jpeg_han = xrdp_jpeg_init();
self->rfx_min_pixel = rdp_layer->client_info.rfx_min_pixel;
if (self->rfx_min_pixel == 0)
{
self->rfx_min_pixel = 64 * 32;
}
return self; return self;
} }
@ -1591,6 +1596,332 @@ xrdp_orders_mem_blt(struct xrdp_orders *self, int cache_id,
return 0; return 0;
} }
/*****************************************************************************/
/* returns error */
int APP_CC
xrdp_orders_composite_blt(struct xrdp_orders* self, int srcidx, int srcformat,
int srcwidth, int srcrepeat, int* srctransform,
int mskflags, int mskidx, int mskformat,
int mskwidth, int mskrepeat, int op,
int srcx, int srcy, int mskx, int msky,
int dstx, int dsty, int width, int height,
int dstformat,
struct xrdp_rect* rect)
{
int order_flags;
int vals[20];
int present;
char* present_ptr;
char* order_flags_ptr;
xrdp_orders_check(self, 80);
self->order_count++;
order_flags = RDP_ORDER_STANDARD;
if (self->orders_state.last_order != RDP_ORDER_COMPOSITE)
{
order_flags |= RDP_ORDER_CHANGE;
}
self->orders_state.last_order = RDP_ORDER_COMPOSITE;
if (rect != 0)
{
/* if clip is present, still check if its needed */
if (dstx < rect->left || dsty < rect->top ||
dstx + width > rect->right || dsty + height > rect->bottom)
{
order_flags |= RDP_ORDER_BOUNDS;
if (xrdp_orders_last_bounds(self, rect))
{
order_flags |= RDP_ORDER_LASTBOUNDS;
}
}
}
vals[0] = srcx;
vals[1] = self->orders_state.com_blt_srcx;
vals[2] = srcy;
vals[3] = self->orders_state.com_blt_srcy;
vals[4] = mskx;
vals[5] = self->orders_state.com_blt_mskx;
vals[6] = msky;
vals[7] = self->orders_state.com_blt_msky;
vals[8] = dstx;
vals[9] = self->orders_state.com_blt_dstx;
vals[10] = dsty;
vals[11] = self->orders_state.com_blt_dsty;
vals[12] = width;
vals[13] = self->orders_state.com_blt_width;
vals[14] = height;
vals[15] = self->orders_state.com_blt_height;
vals[16] = srcwidth;
vals[17] = self->orders_state.com_blt_srcwidth;
vals[18] = mskwidth;
vals[19] = self->orders_state.com_blt_mskwidth;
if (xrdp_orders_send_delta(self, vals, 20))
{
order_flags |= RDP_ORDER_DELTA;
}
/* order_flags, set later, 1 byte */
order_flags_ptr = self->out_s->p;
out_uint8s(self->out_s, 1);
if (order_flags & RDP_ORDER_CHANGE)
{
out_uint8(self->out_s, self->orders_state.last_order);
}
present = 0;
/* present, set later, 3 bytes */
present_ptr = self->out_s->p;
out_uint8s(self->out_s, 3);
if ((order_flags & RDP_ORDER_BOUNDS) &&
!(order_flags & RDP_ORDER_LASTBOUNDS))
{
xrdp_orders_out_bounds(self, rect);
}
if (srcidx != self->orders_state.com_blt_srcidx)
{
present |= 0x000001;
out_uint16_le(self->out_s, srcidx);
self->orders_state.com_blt_srcidx = srcidx;
}
if (srcformat != self->orders_state.com_blt_srcformat)
{
present |= 0x000002;
out_uint32_le(self->out_s, srcformat);
self->orders_state.com_blt_srcformat = srcformat;
}
if (srcwidth != self->orders_state.com_blt_srcwidth)
{
present |= 0x000004;
if (order_flags & RDP_ORDER_DELTA)
{
out_uint8(self->out_s, srcwidth - self->orders_state.com_blt_srcwidth);
}
else
{
out_uint16_le(self->out_s, srcwidth);
}
self->orders_state.com_blt_srcwidth = srcwidth;
}
if (srcrepeat != self->orders_state.com_blt_srcrepeat)
{
present |= 0x000008;
out_uint8(self->out_s, srcrepeat);
self->orders_state.com_blt_srcrepeat = srcrepeat;
}
if (srctransform != 0)
{
if (srctransform[0] != self->orders_state.com_blt_srctransform[0])
{
present |= 0x000010;
out_uint32_le(self->out_s, srctransform[0]);
self->orders_state.com_blt_srctransform[0] = srctransform[0];
}
if (g_memcmp(&(srctransform[1]),
&(self->orders_state.com_blt_srctransform[1]),
36) != 0)
{
present |= 0x000020;
out_uint32_le(self->out_s, srctransform[1]);
out_uint32_le(self->out_s, srctransform[2]);
out_uint32_le(self->out_s, srctransform[3]);
out_uint32_le(self->out_s, srctransform[4]);
out_uint32_le(self->out_s, srctransform[5]);
out_uint32_le(self->out_s, srctransform[6]);
out_uint32_le(self->out_s, srctransform[7]);
out_uint32_le(self->out_s, srctransform[8]);
out_uint32_le(self->out_s, srctransform[9]);
}
}
else
{
if (self->orders_state.com_blt_srctransform[0] != 0)
{
present |= 0x000010;
out_uint32_le(self->out_s, 0);
self->orders_state.com_blt_srctransform[0] = 0;
}
}
if (mskflags != self->orders_state.com_blt_mskflags)
{
present |= 0x000040;
out_uint8(self->out_s, mskflags);
self->orders_state.com_blt_mskflags = mskflags;
}
if (mskidx != self->orders_state.com_blt_mskidx)
{
present |= 0x000080;
out_uint16_le(self->out_s, mskidx);
self->orders_state.com_blt_mskidx = mskidx;
}
if (mskformat != self->orders_state.com_blt_mskformat)
{
present |= 0x000100;
out_uint32_le(self->out_s, mskformat);
self->orders_state.com_blt_mskformat = mskformat;
}
if (mskwidth != self->orders_state.com_blt_mskwidth)
{
present |= 0x000200;
if (order_flags & RDP_ORDER_DELTA)
{
out_uint8(self->out_s, mskwidth - self->orders_state.com_blt_mskwidth);
}
else
{
out_uint16_le(self->out_s, mskwidth);
}
self->orders_state.com_blt_mskwidth = mskwidth;
}
if (mskrepeat != self->orders_state.com_blt_mskrepeat)
{
present |= 0x000400;
out_uint8(self->out_s, mskrepeat);
self->orders_state.com_blt_mskrepeat = mskrepeat;
}
if (op != self->orders_state.com_blt_op)
{
present |= 0x000800;
out_uint8(self->out_s, op);
self->orders_state.com_blt_op = op;
}
if (srcx != self->orders_state.com_blt_srcx)
{
present |= 0x001000;
if (order_flags & RDP_ORDER_DELTA)
{
out_uint8(self->out_s, srcx - self->orders_state.com_blt_srcx);
}
else
{
out_uint16_le(self->out_s, srcx);
}
self->orders_state.com_blt_srcx = srcx;
}
if (srcy != self->orders_state.com_blt_srcy)
{
present |= 0x002000;
if (order_flags & RDP_ORDER_DELTA)
{
out_uint8(self->out_s, srcy - self->orders_state.com_blt_srcy);
}
else
{
out_uint16_le(self->out_s, srcy);
}
self->orders_state.com_blt_srcy = srcy;
}
if (mskx != self->orders_state.com_blt_mskx)
{
present |= 0x004000;
if (order_flags & RDP_ORDER_DELTA)
{
out_uint8(self->out_s, mskx - self->orders_state.com_blt_mskx);
}
else
{
out_uint16_le(self->out_s, mskx);
}
self->orders_state.com_blt_mskx = mskx;
}
if (msky != self->orders_state.com_blt_msky)
{
present |= 0x008000;
if (order_flags & RDP_ORDER_DELTA)
{
out_uint8(self->out_s, msky - self->orders_state.com_blt_msky);
}
else
{
out_uint16_le(self->out_s, msky);
}
self->orders_state.com_blt_msky = msky;
}
if (dstx != self->orders_state.com_blt_dstx)
{
present |= 0x010000;
if (order_flags & RDP_ORDER_DELTA)
{
out_uint8(self->out_s, dstx - self->orders_state.com_blt_dstx);
}
else
{
out_uint16_le(self->out_s, dstx);
}
self->orders_state.com_blt_dstx = dstx;
}
if (dsty != self->orders_state.com_blt_dsty)
{
present |= 0x020000;
if (order_flags & RDP_ORDER_DELTA)
{
out_uint8(self->out_s, dsty - self->orders_state.com_blt_dsty);
}
else
{
out_uint16_le(self->out_s, dsty);
}
self->orders_state.com_blt_dsty = dsty;
}
if (width != self->orders_state.com_blt_width)
{
present |= 0x040000;
if (order_flags & RDP_ORDER_DELTA)
{
out_uint8(self->out_s, width - self->orders_state.com_blt_width);
}
else
{
out_uint16_le(self->out_s, width);
}
self->orders_state.com_blt_width = width;
}
if (height != self->orders_state.com_blt_height)
{
present |= 0x080000;
if (order_flags & RDP_ORDER_DELTA)
{
out_uint8(self->out_s, height - self->orders_state.com_blt_height);
}
else
{
out_uint16_le(self->out_s, height);
}
self->orders_state.com_blt_height = height;
}
if (dstformat != self->orders_state.com_blt_dstformat)
{
present |= 0x100000;
out_uint32_le(self->out_s, dstformat);
self->orders_state.com_blt_dstformat = dstformat;
}
xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags,
present_ptr, present, 3);
return 0;
}
/*****************************************************************************/ /*****************************************************************************/
/* returns error */ /* returns error */
int APP_CC int APP_CC
@ -2017,15 +2348,25 @@ xrdp_orders_send_font(struct xrdp_orders *self,
int order_flags = 0; int order_flags = 0;
int datasize = 0; int datasize = 0;
int len = 0; int len = 0;
int flags;
datasize = FONT_DATASIZE(font_char); if (font_char->bpp == 8) /* alpha font */
{
datasize = ((font_char->width + 3) & ~3) * font_char->height;
flags = 8 | 0x4000;
}
else
{
datasize = FONT_DATASIZE(font_char);
flags = 8;
}
xrdp_orders_check(self, datasize + 18); xrdp_orders_check(self, datasize + 18);
self->order_count++; self->order_count++;
order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
out_uint8(self->out_s, order_flags); out_uint8(self->out_s, order_flags);
len = (datasize + 12) - 7; /* length after type minus 7 */ len = (datasize + 12) - 7; /* length after type minus 7 */
out_uint16_le(self->out_s, len); out_uint16_le(self->out_s, len);
out_uint16_le(self->out_s, 8); /* flags */ out_uint16_le(self->out_s, flags);
out_uint8(self->out_s, RDP_ORDER_FONTCACHE); /* type */ out_uint8(self->out_s, RDP_ORDER_FONTCACHE); /* type */
out_uint8(self->out_s, font_index); out_uint8(self->out_s, font_index);
out_uint8(self->out_s, 1); /* num of chars */ out_uint8(self->out_s, 1); /* num of chars */
@ -2268,7 +2609,9 @@ xrdp_orders_send_as_rfx(struct xrdp_orders *self,
return 0; return 0;
} }
if (width * height < 64) LLOGLN(10, ("width %d height %d rfx_min_pixel %d", width, height,
self->rfx_min_pixel));
if (width * height < self->rfx_min_pixel)
{ {
return 0; return 0;
} }

@ -131,6 +131,10 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info)
{ {
client_info->max_bpp = g_atoi(value); client_info->max_bpp = g_atoi(value);
} }
else if (g_strcasecmp(item, "rfx_min_pixel") == 0)
{
client_info->rfx_min_pixel = g_atoi(value);
}
else if (g_strcasecmp(item, "new_cursors") == 0) else if (g_strcasecmp(item, "new_cursors") == 0)
{ {
client_info->pointer_flags = g_text2bool(value) == 0 ? 2 : 0; client_info->pointer_flags = g_text2bool(value) == 0 ? 2 : 0;
@ -595,6 +599,7 @@ xrdp_rdp_send_demand_active(struct xrdp_rdp *self)
int caps_size; int caps_size;
int codec_caps_count; int codec_caps_count;
int codec_caps_size; int codec_caps_size;
int flags;
char *caps_count_ptr; char *caps_count_ptr;
char *caps_size_ptr; char *caps_size_ptr;
char *caps_ptr; char *caps_ptr;
@ -688,38 +693,38 @@ xrdp_rdp_send_demand_active(struct xrdp_rdp *self)
out_uint16_le(s, 0x2f); /* Number of fonts */ out_uint16_le(s, 0x2f); /* Number of fonts */
out_uint16_le(s, 0x22); /* Capability flags */ out_uint16_le(s, 0x22); /* Capability flags */
/* caps */ /* caps */
out_uint8(s, 1); /* dest blt */ out_uint8(s, 1); /* NEG_DSTBLT_INDEX 0x00 0 */
out_uint8(s, 1); /* pat blt */ out_uint8(s, 1); /* NEG_PATBLT_INDEX 0x01 1 */
out_uint8(s, 1); /* screen blt */ out_uint8(s, 1); /* NEG_SCRBLT_INDEX 0x02 2 */
out_uint8(s, 1); /* mem blt */ out_uint8(s, 1); /* NEG_MEMBLT_INDEX 0x03 3 */
out_uint8(s, 0); /* tri blt */ out_uint8(s, 0); /* NEG_MEM3BLT_INDEX 0x04 4 */
out_uint8(s, 0); /* unused */ out_uint8(s, 0); /* NEG_ATEXTOUT_INDEX 0x05 5 */
out_uint8(s, 0); /* unused */ out_uint8(s, 0); /* NEG_AEXTTEXTOUT_INDEX 0x06 6 */
out_uint8(s, 0); /* nine grid */ out_uint8(s, 0); /* NEG_DRAWNINEGRID_INDEX 0x07 7 */
out_uint8(s, 1); /* line to */ out_uint8(s, 1); /* NEG_LINETO_INDEX 0x08 8 */
out_uint8(s, 0); /* multi nine grid */ out_uint8(s, 0); /* NEG_MULTI_DRAWNINEGRID_INDEX 0x09 9 */
out_uint8(s, 1); /* rect */ out_uint8(s, 1); /* NEG_OPAQUE_RECT_INDEX 0x0A 10 */
out_uint8(s, 0); /* desk save */ out_uint8(s, 0); /* NEG_SAVEBITMAP_INDEX 0x0B 11 */
out_uint8(s, 0); /* unused */ out_uint8(s, 0); /* NEG_WTEXTOUT_INDEX 0x0C 12 */
out_uint8(s, 0); /* unused */ out_uint8(s, 0); /* NEG_MEMBLT_V2_INDEX 0x0D 13 */
out_uint8(s, 0); /* unused */ out_uint8(s, 0); /* NEG_MEM3BLT_V2_INDEX 0x0E 14 */
out_uint8(s, 0); /* multi dest blt */ out_uint8(s, 0); /* NEG_MULTIDSTBLT_INDEX 0x0F 15 */
out_uint8(s, 0); /* multi pat blt */ out_uint8(s, 0); /* NEG_MULTIPATBLT_INDEX 0x10 16 */
out_uint8(s, 0); /* multi screen blt */ out_uint8(s, 0); /* NEG_MULTISCRBLT_INDEX 0x11 17 */
out_uint8(s, 1); /* multi rect */ out_uint8(s, 1); /* NEG_MULTIOPAQUERECT_INDEX 0x12 18 */
out_uint8(s, 0); /* fast index */ out_uint8(s, 0); /* NEG_FAST_INDEX_INDEX 0x13 19 */
out_uint8(s, 0); /* polygonSC ([MS-RDPEGDI], 2.2.2.2.1.1.2.16) */ out_uint8(s, 0); /* NEG_POLYGON_SC_INDEX 0x14 20 */
out_uint8(s, 0); /* polygonCB ([MS-RDPEGDI], 2.2.2.2.1.1.2.17) */ out_uint8(s, 0); /* NEG_POLYGON_CB_INDEX 0x15 21 */
out_uint8(s, 0); /* polyline */ out_uint8(s, 0); /* NEG_POLYLINE_INDEX 0x16 22 */
out_uint8(s, 0); /* unused */ out_uint8(s, 0); /* unused 0x17 23 */
out_uint8(s, 0); /* fast glyph */ out_uint8(s, 0); /* NEG_FAST_GLYPH_INDEX 0x18 24 */
out_uint8(s, 0); /* ellipse */ out_uint8(s, 0); /* NEG_ELLIPSE_SC_INDEX 0x19 25 */
out_uint8(s, 0); /* ellipse */ out_uint8(s, 0); /* NEG_ELLIPSE_CB_INDEX 0x1A 26 */
out_uint8(s, 0); /* ? */ out_uint8(s, 1); /* NEG_GLYPH_INDEX_INDEX 0x1B 27 */
out_uint8(s, 0); /* unused */ out_uint8(s, 0); /* NEG_GLYPH_WEXTTEXTOUT_INDEX 0x1C 28 */
out_uint8(s, 0); /* unused */ out_uint8(s, 0); /* NEG_GLYPH_WLONGTEXTOUT_INDEX 0x1D 29 */
out_uint8(s, 0); /* unused */ out_uint8(s, 0); /* NEG_GLYPH_WLONGEXTTEXTOUT_INDEX 0x1E 30 */
out_uint8(s, 0); /* unused */ out_uint8(s, 0); /* unused 0x1F 31 */
out_uint16_le(s, 0x6a1); out_uint16_le(s, 0x6a1);
/* declare support of bitmap cache rev3 */ /* declare support of bitmap cache rev3 */
out_uint16_le(s, XR_ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT); out_uint16_le(s, XR_ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT);
@ -782,18 +787,16 @@ xrdp_rdp_send_demand_active(struct xrdp_rdp *self)
caps_count++; caps_count++;
out_uint16_le(s, RDP_CAPSET_INPUT); /* 13(0xd) */ out_uint16_le(s, RDP_CAPSET_INPUT); /* 13(0xd) */
out_uint16_le(s, RDP_CAPLEN_INPUT); /* 88(0x58) */ out_uint16_le(s, RDP_CAPLEN_INPUT); /* 88(0x58) */
/* INPUT_FLAG_SCANCODES 0x0001
INPUT_FLAG_MOUSEX 0x0004
INPUT_FLAG_FASTPATH_INPUT 0x0008
INPUT_FLAG_FASTPATH_INPUT2 0x0020 */
flags = 0x0001 | 0x0004;
if (self->client_info.use_fast_path & 2) if (self->client_info.use_fast_path & 2)
{ flags |= 0x0008 | 0x0020;
/* INPUT_FLAG_SCANCODES 0x0001 out_uint16_le(s, flags);
INPUT_FLAG_FASTPATH_INPUT 0x0008 out_uint8s(s, 82);
INPUT_FLAG_FASTPATH_INPUT2 0x0020 */
out_uint8(s, 1 | 8 | 0x20);
}
else
{
out_uint8(s, 1);
}
out_uint8s(s, 83);
/* Remote Programs Capability Set */ /* Remote Programs Capability Set */
caps_count++; caps_count++;
@ -1410,15 +1413,16 @@ xrdp_rdp_process_data_input(struct xrdp_rdp *self, struct stream *s)
in_uint16_le(s, device_flags); in_uint16_le(s, device_flags);
in_sint16_le(s, param1); in_sint16_le(s, param1);
in_sint16_le(s, param2); in_sint16_le(s, param2);
DEBUG(("xrdp_rdp_process_data_input event %4.4x flags %4.4x param1 %d \ DEBUG(("xrdp_rdp_process_data_input event %4.4x flags %4.4x param1 %d "
param2 %d time %d", msg_type, device_flags, param1, param2, time)); "param2 %d time %d", msg_type, device_flags, param1, param2, time));
if (self->session->callback != 0) if (self->session->callback != 0)
{ {
/* msg_type can be /* msg_type can be
RDP_INPUT_SYNCHRONIZE - 0 RDP_INPUT_SYNCHRONIZE - 0
RDP_INPUT_SCANCODE - 4 RDP_INPUT_SCANCODE - 4
RDP_INPUT_MOUSE - 0x8001 */ RDP_INPUT_MOUSE - 0x8001
RDP_INPUT_MOUSEX - 0x8002 */
/* call to xrdp_wm.c : callback */ /* call to xrdp_wm.c : callback */
self->session->callback(self->session->id, msg_type, param1, param2, self->session->callback(self->session->id, msg_type, param1, param2,
device_flags, time); device_flags, time);

@ -61,5 +61,5 @@ xrdp_chansrv_LDFLAGS = \
xrdp_chansrv_LDADD = \ xrdp_chansrv_LDADD = \
-L/usr/X11R6/lib \ -L/usr/X11R6/lib \
$(top_builddir)/common/libcommon.la \ $(top_builddir)/common/libcommon.la \
-lX11 -lXfixes \ -lX11 -lXfixes -lXrandr \
$(EXTRA_LIBS) $(EXTRA_LIBS)

@ -72,16 +72,18 @@ tbus g_exec_mutex;
tbus g_exec_sem; tbus g_exec_sem;
int g_exec_pid = 0; int g_exec_pid = 0;
#define ARRAYSIZE(x) (sizeof(x)/sizeof(*(x)))
/* each time we create a DVC we need a unique DVC channel id */ /* each time we create a DVC we need a unique DVC channel id */
/* this variable gets bumped up once per DVC we create */ /* this variable gets bumped up once per DVC we create */
tui32 g_dvc_chan_id = 100; tui32 g_dvc_chan_id = 100;
struct timeout_obj struct timeout_obj
{ {
tui32 mstime; tui32 mstime;
void* data; void *data;
void (*callback)(void* data); void (*callback)(void *data);
struct timeout_obj* next; struct timeout_obj *next;
}; };
static struct timeout_obj *g_timeout_head = 0; static struct timeout_obj *g_timeout_head = 0;
@ -93,7 +95,7 @@ add_timeout(int msoffset, void (*callback)(void *data), void *data)
{ {
struct timeout_obj *tobj; struct timeout_obj *tobj;
tui32 now; tui32 now;
LOG(10, ("add_timeout:")); LOG(10, ("add_timeout:"));
now = g_time3(); now = g_time3();
tobj = g_malloc(sizeof(struct timeout_obj), 1); tobj = g_malloc(sizeof(struct timeout_obj), 1);
@ -372,6 +374,31 @@ send_channel_data(int chan_id, char *data, int size)
return 1; return 1;
} }
/*****************************************************************************/
/* returns error */
int APP_CC
send_rail_drawing_orders(char* data, int size)
{
LOGM((LOG_LEVEL_DEBUG, "chansrv::send_rail_drawing_orders: size %d", size));
struct stream* s;
int error;
s = trans_get_out_s(g_con_trans, 8192);
out_uint32_le(s, 0); /* version */
out_uint32_le(s, 8 + 8 + size); /* size */
out_uint32_le(s, 10); /* msg id */
out_uint32_le(s, 8 + size); /* size */
out_uint8a(s, data, size);
s_mark_end(s);
error = trans_force_write(g_con_trans);
if (error != 0)
{
return 1;
}
return 0;
}
/*****************************************************************************/ /*****************************************************************************/
/* returns error */ /* returns error */
static int APP_CC static int APP_CC
@ -1325,6 +1352,47 @@ read_ini(void)
return 0; return 0;
} }
/*****************************************************************************/
static char* APP_CC
get_log_path()
{
char* log_path = 0;
log_path = g_getenv("CHANSRV_LOG_PATH");
if (log_path == 0)
{
log_path = g_getenv("HOME");
}
return log_path;
}
/*****************************************************************************/
static unsigned int APP_CC
get_log_level(const char* level_str, unsigned int default_level)
{
static const char* levels[] = {
"LOG_LEVEL_ALWAYS",
"LOG_LEVEL_ERROR",
"LOG_LEVEL_WARNING",
"LOG_LEVEL_INFO",
"LOG_LEVEL_DEBUG"
};
unsigned int i;
if (level_str == NULL || level_str[0] == 0)
{
return default_level;
}
for (i = 0; i < ARRAYSIZE(levels); ++i)
{
if (g_strcasecmp(levels[i], level_str) == 0)
{
return i;
}
}
return default_level;
}
/*****************************************************************************/ /*****************************************************************************/
static int APP_CC static int APP_CC
run_exec(void) run_exec(void)
@ -1359,19 +1427,19 @@ main(int argc, char **argv)
tbus waiters[4]; tbus waiters[4];
int pid = 0; int pid = 0;
char text[256]; char text[256];
char *home_text; char* log_path;
char *display_text; char *display_text;
char log_file[256]; char log_file[256];
enum logReturns error; enum logReturns error;
struct log_config logconfig; struct log_config logconfig;
unsigned int log_level;
g_init("xrdp-chansrv"); /* os_calls */ g_init("xrdp-chansrv"); /* os_calls */
home_text = g_getenv("HOME"); log_path = get_log_path();
if (log_path == 0)
if (home_text == 0)
{ {
g_writeln("error reading HOME environment variable"); g_writeln("error reading CHANSRV_LOG_PATH and HOME environment variable");
g_deinit(); g_deinit();
return 1; return 1;
} }
@ -1379,10 +1447,12 @@ main(int argc, char **argv)
read_ini(); read_ini();
pid = g_getpid(); pid = g_getpid();
log_level = get_log_level(g_getenv("CHANSRV_LOG_LEVEL"), LOG_LEVEL_ERROR);
/* starting logging subsystem */ /* starting logging subsystem */
g_memset(&logconfig, 0, sizeof(struct log_config)); g_memset(&logconfig, 0, sizeof(struct log_config));
logconfig.program_name = "XRDP-Chansrv"; logconfig.program_name = "XRDP-Chansrv";
g_snprintf(log_file, 255, "%s/xrdp-chansrv.log", home_text); g_snprintf(log_file, 255, "%s/xrdp-chansrv.log", log_path);
g_writeln("chansrv::main: using log file [%s]", log_file); g_writeln("chansrv::main: using log file [%s]", log_file);
if (g_file_exist(log_file)) if (g_file_exist(log_file))
@ -1392,7 +1462,7 @@ main(int argc, char **argv)
logconfig.log_file = log_file; logconfig.log_file = log_file;
logconfig.fd = -1; logconfig.fd = -1;
logconfig.log_level = LOG_LEVEL_ERROR; logconfig.log_level = log_level;
logconfig.enable_syslog = 0; logconfig.enable_syslog = 0;
logconfig.syslog_level = 0; logconfig.syslog_level = 0;
error = log_start_from_param(&logconfig); error = log_start_from_param(&logconfig);

@ -58,6 +58,7 @@ int DEFAULT_CC
g_is_term(void); g_is_term(void);
int APP_CC send_channel_data(int chan_id, char *data, int size); int APP_CC send_channel_data(int chan_id, char *data, int size);
int APP_CC send_rail_drawing_orders(char* data, int size);
int APP_CC main_cleanup(void); int APP_CC main_cleanup(void);
int APP_CC add_timeout(int msoffset, void (*callback)(void* data), void* data); int APP_CC add_timeout(int msoffset, void (*callback)(void* data), void* data);
int APP_CC find_empty_slot_in_dvc_channels(); int APP_CC find_empty_slot_in_dvc_channels();

@ -277,6 +277,39 @@ static int g_num_formatIds = 0;
static int g_file_format_id = -1; static int g_file_format_id = -1;
static char g_last_atom_name[256] = "";
/*****************************************************************************/
static char* APP_CC
get_atom_text(Atom atom)
{
char* name;
int failed;
failed = 0;
/* sanity check */
if ((atom < 1) || (atom > 512))
{
failed = 1;
}
if (!failed)
{
name = XGetAtomName(g_display, atom);
if (name == 0)
{
failed = 1;
}
}
if (failed)
{
g_snprintf(g_last_atom_name, 255, "unknown atom 0x%8.8x", (int)atom);
return g_last_atom_name;
}
g_strncpy(g_last_atom_name, name, 255);
XFree(name);
return g_last_atom_name;
}
/*****************************************************************************/ /*****************************************************************************/
/* this is one way to get the current time from the x server */ /* this is one way to get the current time from the x server */
static Time APP_CC static Time APP_CC
@ -895,8 +928,8 @@ clipboard_provide_selection_c2s(XSelectionRequestEvent *req, Atom type)
g_clip_c2s.property = req->property; g_clip_c2s.property = req->property;
g_clip_c2s.window = req->requestor; g_clip_c2s.window = req->requestor;
log_debug("clipboard_provide_selection_c2s: start INCR property %s " log_debug("clipboard_provide_selection_c2s: start INCR property %s "
"type %s", XGetAtomName(g_display, req->property), "type %s", get_atom_text(req->property),
XGetAtomName(g_display, type)); get_atom_text(type));
val1[0] = g_clip_c2s.total_bytes; val1[0] = g_clip_c2s.total_bytes;
val1[1] = 0; val1[1] = 0;
XChangeProperty(g_display, req->requestor, req->property, XChangeProperty(g_display, req->requestor, req->property,
@ -1697,7 +1730,7 @@ clipboard_get_window_property(Window wnd, Atom prop, Atom *type, int *fmt,
Atom ltype; Atom ltype;
log_debug("clipboard_get_window_property:"); log_debug("clipboard_get_window_property:");
log_debug(" prop %d name %s", prop, XGetAtomName(g_display, prop)); log_debug(" prop %d name %s", prop, get_atom_text(prop));
lxdata = 0; lxdata = 0;
ltype = 0; ltype = 0;
XGetWindowProperty(g_display, wnd, prop, 0, 0, 0, XGetWindowProperty(g_display, wnd, prop, 0, 0, 0,
@ -1837,7 +1870,7 @@ clipboard_event_selection_notify(XEvent *xevent)
{ {
log_debug("clipboard_event_selection_notify: wnd %p prop %s", log_debug("clipboard_event_selection_notify: wnd %p prop %s",
lxevent->requestor, lxevent->requestor,
XGetAtomName(g_display, lxevent->property)); get_atom_text(lxevent->property));
rv = clipboard_get_window_property(lxevent->requestor, lxevent->property, rv = clipboard_get_window_property(lxevent->requestor, lxevent->property,
&type, &fmt, &type, &fmt,
&n_items, &data, &data_size); &n_items, &data, &data_size);
@ -1855,8 +1888,8 @@ clipboard_event_selection_notify(XEvent *xevent)
PropertyNotify */ PropertyNotify */
log_debug("clipboard_event_selection_notify: type is INCR " log_debug("clipboard_event_selection_notify: type is INCR "
"data_size %d property name %s type %s", data_size, "data_size %d property name %s type %s", data_size,
XGetAtomName(g_display, lxevent->property), get_atom_text(lxevent->property),
XGetAtomName(g_display, lxevent->type)); get_atom_text(lxevent->type));
g_clip_s2c.incr_in_progress = 1; g_clip_s2c.incr_in_progress = 1;
g_clip_s2c.property = lxevent->property; g_clip_s2c.property = lxevent->property;
g_clip_s2c.type = lxevent->target; g_clip_s2c.type = lxevent->target;
@ -1882,10 +1915,10 @@ clipboard_event_selection_notify(XEvent *xevent)
for (index = 0; index < n_items; index++) for (index = 0; index < n_items; index++)
{ {
atom = atoms[index]; atom = atoms[index];
log_debug("clipboard_event_selection_notify: %d %s %d", LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: %d %s %d",
atom, XGetAtomName(g_display, atom), XA_STRING); atom, get_atom_text(atom), XA_STRING));
log_debug("clipboard_event_selection_notify: 0x%x %s", log_debug("clipboard_event_selection_notify: 0x%x %s",
atom, XGetAtomName(g_display, atom)); atom, get_atom_text(atom));
if (atom == g_utf8_atom) if (atom == g_utf8_atom)
{ {
got_utf8 = 1; got_utf8 = 1;
@ -2091,7 +2124,6 @@ static int APP_CC
clipboard_event_selection_request(XEvent *xevent) clipboard_event_selection_request(XEvent *xevent)
{ {
XSelectionRequestEvent *lxev; XSelectionRequestEvent *lxev;
XEvent xev;
Atom atom_buf[10]; Atom atom_buf[10];
Atom type; Atom type;
int atom_count; int atom_count;
@ -2105,7 +2137,7 @@ clipboard_event_selection_request(XEvent *xevent)
log_debug("clipboard_event_selection_request: g_wnd %d, " log_debug("clipboard_event_selection_request: g_wnd %d, "
".requestor %d .owner %d .selection %d '%s' .target %d .property %d", ".requestor %d .owner %d .selection %d '%s' .target %d .property %d",
g_wnd, lxev->requestor, lxev->owner, lxev->selection, g_wnd, lxev->requestor, lxev->owner, lxev->selection,
XGetAtomName(g_display, lxev->selection), get_atom_text(lxev->selection),
lxev->target, lxev->property); lxev->target, lxev->property);
if (lxev->property == None) if (lxev->property == None)
@ -2164,8 +2196,7 @@ clipboard_event_selection_request(XEvent *xevent)
"g_multiple_atom"); "g_multiple_atom");
xdata = 0; xdata = 0;
if (clipboard_get_window_property(xev.xselection.requestor, if (clipboard_get_window_property(lxev->requestor, lxev->property,
xev.xselection.property,
&type, &fmt, &n_items, &xdata, &type, &fmt, &n_items, &xdata,
&xdata_size) == 0) &xdata_size) == 0)
{ {
@ -2235,9 +2266,9 @@ clipboard_event_selection_request(XEvent *xevent)
else else
{ {
log_debug("clipboard_event_selection_request: unknown " log_debug("clipboard_event_selection_request: unknown "
"target %s", XGetAtomName(g_display, lxev->target)); "target %s", get_atom_text(lxev->target));
log_error("clipboard_event_selection_request: unknown " LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_request: unknown "
"target %s", XGetAtomName(g_display, lxev->target)); "target %s", get_atom_text(lxev->target)));
} }
clipboard_refuse_selection(lxev); clipboard_refuse_selection(lxev);
@ -2293,7 +2324,7 @@ clipboard_event_property_notify(XEvent *xevent)
log_debug("clipboard_event_property_notify: PropertyNotify .window %d " log_debug("clipboard_event_property_notify: PropertyNotify .window %d "
".state %d .atom %d %s", xevent->xproperty.window, ".state %d .atom %d %s", xevent->xproperty.window,
xevent->xproperty.state, xevent->xproperty.atom, xevent->xproperty.state, xevent->xproperty.atom,
XGetAtomName(g_display, xevent->xproperty.atom)); get_atom_text(xevent->xproperty.atom));
if (g_clip_c2s.incr_in_progress && if (g_clip_c2s.incr_in_progress &&
(xevent->xproperty.window == g_clip_c2s.window) && (xevent->xproperty.window == g_clip_c2s.window) &&

File diff suppressed because it is too large Load Diff

@ -19,6 +19,7 @@
#ifndef _RAIL_H_ #ifndef _RAIL_H_
#define _RAIL_H_ #define _RAIL_H_
#include "../../common/rail.h"
#include "arch.h" #include "arch.h"
#include "parse.h" #include "parse.h"
@ -31,5 +32,6 @@ rail_data_in(struct stream* s, int chan_id, int chan_flags,
int length, int total_length); int length, int total_length);
int APP_CC int APP_CC
rail_xevent(void* xevent); rail_xevent(void* xevent);
int APP_CC rail_request_title(int window_id);
#endif #endif

@ -25,8 +25,10 @@
#include "clipboard.h" #include "clipboard.h"
#include "rail.h" #include "rail.h"
/*
#undef LOG_LEVEL #undef LOG_LEVEL
#define LOG_LEVEL 11 #define LOG_LEVEL 11
*/
extern int g_clip_up; /* in clipboard.c */ extern int g_clip_up; /* in clipboard.c */
@ -40,6 +42,9 @@ int g_screen_num = 0;
Window g_root_window = 0; Window g_root_window = 0;
Atom g_wm_delete_window_atom = 0; Atom g_wm_delete_window_atom = 0;
Atom g_wm_protocols_atom = 0; Atom g_wm_protocols_atom = 0;
Atom g_utf8_string = 0;
Atom g_net_wm_name = 0;
Atom g_wm_state = 0;
/*****************************************************************************/ /*****************************************************************************/
static int DEFAULT_CC static int DEFAULT_CC
@ -117,7 +122,10 @@ xcommon_init(void)
g_wm_delete_window_atom = XInternAtom(g_display, "WM_DELETE_WINDOW", 0); g_wm_delete_window_atom = XInternAtom(g_display, "WM_DELETE_WINDOW", 0);
g_wm_protocols_atom = XInternAtom(g_display, "WM_PROTOCOLS", 0); g_wm_protocols_atom = XInternAtom(g_display, "WM_PROTOCOLS", 0);
g_utf8_string = XInternAtom(g_display, "UTF8_STRING", 0);
g_net_wm_name = XInternAtom(g_display, "_NET_WM_NAME", 0);
g_wm_state = XInternAtom(g_display, "WM_STATE", 0);
return 0; return 0;
} }

@ -0,0 +1,102 @@
#!/bin/sh
#
# all directories can be read only except
# Read Write
# share/X11/xkb/compiled/
if test $# -lt 1
then
echo ""
echo "usage: clean_build_dir.sh <installation dir>"
echo ""
exit 1
fi
BASEDIR=$1
if ! test -d $BASEDIR
then
echo "error directory $BASEDIR does not exist"
exit 1
fi
if ! test -w $BASEDIR
then
echo "error directory $BASEDIR is not writable"
exit 1
fi
echo cleaning $BASEDIR
if ! test -x $BASEDIR/bin/X11rdp
then
echo "error $BASEDIR/bin/X11rdp does not exist"
fi
bin_check_file()
{
if [ "$1" = "X11rdp" ]
then
return 0
fi
if [ "$1" = "xkbcomp" ]
then
return 0
fi
rm -f $1
return 0
}
HOLDPATH=$PWD
cd $BASEDIR
# remove unused directories
rm -fr man/
rm -fr include/
rm -fr lib/python2.7/
rm -fr lib/pkgconfig/
rm -fr share/pkgconfig/
rm -fr share/gtk-doc
rm -fr share/doc
rm -fr share/man
rm -fr share/aclocal
rm -fr share/intltool
rm -fr share/util-macros
# remove development files
rm -f lib/*.a
rm -f lib/*.la
rm -f lib/xorg/modules/*.a
rm -f lib/xorg/modules/*.la
# remove symbols
#strip lib/*.so
#strip lib/xorg/modules/*.so
# remove hardware specific files
rm -f lib/dri/i915_dri.so
rm -f lib/dri/i965_dri.so
rm -f lib/dri/mach64_dri.so
rm -f lib/dri/mga_dri.so
rm -f lib/dri/r128_dri.so
rm -f lib/dri/r200_dri.so
rm -f lib/dri/r300_dri.so
rm -f lib/dri/r600_dri.so
rm -f lib/dri/radeon_dri.so
rm -f lib/dri/savage_dri.so
#strip lib/dri/swrast_dri.so
rm -f lib/dri/tdfx_dri.so
rm -f lib/dri/unichrome_dri.so
# remove extra bin tools
cd bin
for i in *
do
if ! test -d "$i"
then
bin_check_file $i
fi
done
cd ..
cd $HOLDPATH

@ -13,7 +13,7 @@ rdpPolylines.o rdpPolySegment.o rdpFillSpans.o rdpSetSpans.o \
rdpCopyPlane.o rdpPolyPoint.o rdpPolyArc.o rdpFillPolygon.o \ rdpCopyPlane.o rdpPolyPoint.o rdpPolyArc.o rdpFillPolygon.o \
rdpPolyFillArc.o rdpPolyText8.o rdpPolyText16.o \ rdpPolyFillArc.o rdpPolyText8.o rdpPolyText16.o \
rdpImageText8.o rdpImageText16.o rdpImageGlyphBlt.o rdpPolyGlyphBlt.o \ rdpImageText8.o rdpImageText16.o rdpImageGlyphBlt.o rdpPolyGlyphBlt.o \
rdpPushPixels.o rdpxv.o \ rdpPushPixels.o rdpxv.o rdpglyph.o rdpComposite.o \
miinitext.o \ miinitext.o \
fbcmap_mi.o fbcmap_mi.o
@ -43,7 +43,7 @@ LIBS = $(XSRCBASE)/dbe/.libs/libdbe.a \
LLIBS = -Wl,-rpath=$(LIBBASE) -lfreetype -lz -lm -lXfont -lXau \ LLIBS = -Wl,-rpath=$(LIBBASE) -lfreetype -lz -lm -lXfont -lXau \
-lXdmcp -lpixman-1 -lrt -ldl -lcrypto -lGL -lXdamage -lXdmcp -lpixman-1 -lrt -ldl -lcrypto -lGL -lXdamage
CFLAGS = -O2 -Wall -fno-strength-reduce \ CFLAGS = -g -O2 -Wall -fno-strength-reduce \
-I../../include \ -I../../include \
-I../../cfb \ -I../../cfb \
-I../../mfb \ -I../../mfb \

@ -95,6 +95,23 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define PixelDPI 100 #define PixelDPI 100
#define PixelToMM(_size) (((_size) * 254 + (PixelDPI) * 5) / ((PixelDPI) * 10)) #define PixelToMM(_size) (((_size) * 254 + (PixelDPI) * 5) / ((PixelDPI) * 10))
#define TAG_COMPOSITE 0
#define TAG_COPYAREA 1
#define TAG_POLYFILLRECT 2
#define TAG_PUTIMAGE 3
#define TAG_POLYRECTANGLE 4
#define TAG_COPYPLANE 5
#define TAG_POLYARC 6
#define TAG_FILLPOLYGON 7
#define TAG_POLYFILLARC 8
#define TAG_IMAGETEXT8 9
#define TAG_POLYTEXT8 10
#define TAG_POLYTEXT16 11
#define TAG_IMAGETEXT16 12
#define TAG_IMAGEGLYPHBLT 13
#define TAG_POLYGLYPHBLT 14
#define TAG_PUSHPIXELS 15
struct image_data struct image_data
{ {
int width; int width;
@ -118,7 +135,9 @@ struct _rdpScreenInfoRec
int height; int height;
int depth; int depth;
int bitsPerPixel; int bitsPerPixel;
int sizeInBytes; int sizeInBytes; /* size of current used frame buffer */
int sizeInBytesAlloc; /* size of current alloc frame buffer,
always >= sizeInBytes */
char* pfbMemory; char* pfbMemory;
Pixel blackPixel; Pixel blackPixel;
Pixel whitePixel; Pixel whitePixel;
@ -146,6 +165,8 @@ struct _rdpScreenInfoRec
CopyWindowProcPtr CopyWindow; CopyWindowProcPtr CopyWindow;
ClearToBackgroundProcPtr ClearToBackground; ClearToBackgroundProcPtr ClearToBackground;
ScreenWakeupHandlerProcPtr WakeupHandler; ScreenWakeupHandlerProcPtr WakeupHandler;
CreatePictureProcPtr CreatePicture;
DestroyPictureProcPtr DestroyPicture;
CompositeProcPtr Composite; CompositeProcPtr Composite;
GlyphsProcPtr Glyphs; GlyphsProcPtr Glyphs;
/* Backing store procedures */ /* Backing store procedures */
@ -202,6 +223,7 @@ typedef rdpWindowRec* rdpWindowPtr;
#define RDI_IMGLY 3 /* lossy */ #define RDI_IMGLY 3 /* lossy */
#define RDI_LINE 4 #define RDI_LINE 4
#define RDI_SCRBLT 5 #define RDI_SCRBLT 5
#define RDI_TEXT 6
struct urdp_draw_item_fill struct urdp_draw_item_fill
{ {
@ -238,17 +260,25 @@ struct urdp_draw_item_scrblt
int cy; int cy;
}; };
struct urdp_draw_item_text
{
int opcode;
int fg_color;
struct rdp_text* rtext; /* in rdpglyph.h */
};
union urdp_draw_item union urdp_draw_item
{ {
struct urdp_draw_item_fill fill; struct urdp_draw_item_fill fill;
struct urdp_draw_item_img img; struct urdp_draw_item_img img;
struct urdp_draw_item_line line; struct urdp_draw_item_line line;
struct urdp_draw_item_scrblt scrblt; struct urdp_draw_item_scrblt scrblt;
struct urdp_draw_item_text text;
}; };
struct rdp_draw_item struct rdp_draw_item
{ {
int type; int type; /* RDI_FILL, RDI_IMGLL, ... */
int flags; int flags;
struct rdp_draw_item* prev; struct rdp_draw_item* prev;
struct rdp_draw_item* next; struct rdp_draw_item* next;
@ -265,6 +295,11 @@ struct _rdpPixmapRec
int con_number; int con_number;
int is_dirty; int is_dirty;
int is_scratch; int is_scratch;
int is_alpha_dirty_not;
/* number of times used in a remote operation
if this gets above XRDP_USE_COUNT_THRESHOLD
then we force remote the pixmap */
int use_count;
int kind_width; int kind_width;
/* number of times used in a remote operation /* number of times used in a remote operation
if this gets above XRDP_USE_COUNT_THRESHOLD if this gets above XRDP_USE_COUNT_THRESHOLD
@ -335,6 +370,8 @@ void
hexdump(unsigned char *p, unsigned int len); hexdump(unsigned char *p, unsigned int len);
void void
RegionAroundSegs(RegionPtr reg, xSegment* segs, int nseg); RegionAroundSegs(RegionPtr reg, xSegment* segs, int nseg);
int
get_crc(char* data, int data_bytes);
/* rdpdraw.c */ /* rdpdraw.c */
Bool Bool
@ -363,6 +400,9 @@ int
draw_item_add_srcblt_region(rdpPixmapRec* priv, RegionPtr reg, draw_item_add_srcblt_region(rdpPixmapRec* priv, RegionPtr reg,
int srcx, int srcy, int dstx, int dsty, int srcx, int srcy, int dstx, int dsty,
int cx, int cy); int cx, int cy);
int
draw_item_add_text_region(rdpPixmapRec* priv, RegionPtr reg, int color,
int opcode, struct rdp_text* rtext);
PixmapPtr PixmapPtr
rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth, rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth,
@ -421,15 +461,19 @@ rdpDisplayCursor(ScreenPtr pScreen, CursorPtr pCursor);
void void
rdpRecolorCursor(ScreenPtr pScreen, CursorPtr pCursor, rdpRecolorCursor(ScreenPtr pScreen, CursorPtr pCursor,
Bool displayed); Bool displayed);
/* rdpglyph.c */
/* look in rdpglyph.h */
/* rdpComposite.c */
int
rdpCreatePicture(PicturePtr pPicture);
void
rdpDestroyPicture(PicturePtr pPicture);
void void
rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst,
INT16 yDst, CARD16 width, CARD16 height); INT16 yDst, CARD16 width, CARD16 height);
void
rdpGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc, INT16 ySrc, int nlists, GlyphListPtr lists,
GlyphPtr* glyphs);
/* rdpinput.c */ /* rdpinput.c */
int int
@ -516,6 +560,8 @@ rdpup_set_cursor_ex(short x, short y, char *cur_data, char *cur_mask, int bpp);
int int
rdpup_create_os_surface(int rdpindexd, int width, int height); rdpup_create_os_surface(int rdpindexd, int width, int height);
int int
rdpup_create_os_surface_bpp(int rdpindexd, int width, int height, int bpp);
int
rdpup_switch_os_surface(int rdpindex); rdpup_switch_os_surface(int rdpindex);
int int
rdpup_delete_os_surface(int rdpindex); rdpup_delete_os_surface(int rdpindex);
@ -532,7 +578,29 @@ rdpup_delete_window(WindowPtr pWindow, rdpWindowRec* priv);
int int
rdpup_check_dirty(PixmapPtr pDirtyPixmap, rdpPixmapRec* pDirtyPriv); rdpup_check_dirty(PixmapPtr pDirtyPixmap, rdpPixmapRec* pDirtyPriv);
int int
rdpup_check_alpha_dirty(PixmapPtr pDirtyPixmap, rdpPixmapRec* pDirtyPriv);
int
rdpup_check_dirty_screen(rdpPixmapRec* pDirtyPriv); rdpup_check_dirty_screen(rdpPixmapRec* pDirtyPriv);
int
rdpup_add_char(int font, int charactor, short x, short y, int cx, int cy,
char* bmpdata, int bmpdata_bytes);
int
rdpup_add_char_alpha(int font, int charactor, short x, short y, int cx, int cy,
char* bmpdata, int bmpdata_bytes);
int
rdpup_draw_text(int font, int flags, int mixmode,
short clip_left, short clip_top,
short clip_right, short clip_bottom,
short box_left, short box_top,
short box_right, short box_bottom, short x, short y,
char* data, int data_bytes);
int
rdpup_composite(short srcidx, int srcformat, short srcwidth, CARD8 srcrepeat,
PictTransform* srctransform, CARD8 mskflags,
short mskidx, int mskformat, short mskwidth, CARD8 mskrepeat,
CARD8 op, short srcx, short srcy, short mskx, short msky,
short dstx, short dsty, short width, short height,
int dstformat);
void void
rdpScheduleDeferredUpdate(void); rdpScheduleDeferredUpdate(void);
@ -603,6 +671,13 @@ struct stream
} }
#endif #endif
/******************************************************************************/
#define out_uint8(s, v) \
{ \
*((s)->p) = (unsigned char)((v) >> 0); \
(s)->p++; \
}
/******************************************************************************/ /******************************************************************************/
#define init_stream(s, v) \ #define init_stream(s, v) \
{ \ { \
@ -630,6 +705,13 @@ struct stream
out_uint8p((s), (v), (n)); \ out_uint8p((s), (v), (n)); \
} }
/******************************************************************************/
#define out_uint8s(s, n) do \
{ \
memset((s)->p, 0, (n)); \
(s)->p += (n); \
} while (0)
/******************************************************************************/ /******************************************************************************/
#if defined(B_ENDIAN) || defined(NEED_ALIGN) #if defined(B_ENDIAN) || defined(NEED_ALIGN)
#define out_uint32_le(s, v) \ #define out_uint32_le(s, v) \

@ -0,0 +1,835 @@
/*
Copyright 2012-2013 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "rdp.h"
#include "rdpdraw.h"
#define LDEBUG 0
#define LOG_LEVEL 1
#define LLOG(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0)
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */
extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */
extern DevPrivateKeyRec g_rdpWindowIndex; /* from rdpmain.c */
extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
extern int g_Bpp; /* from rdpmain.c */
extern ScreenPtr g_pScreen; /* from rdpmain.c */
extern Bool g_wrapPixmap; /* from rdpmain.c */
extern int g_can_do_pix_to_pix; /* from rdpmain.c */
extern int g_do_dirty_os; /* in rdpmain.c */
extern int g_do_glyph_cache; /* in rdpmain.c */
extern int g_doing_font; /* in rdpmain.c */
extern int g_do_composite; /* in rdpmain.c */
extern GCOps g_rdpGCOps; /* from rdpdraw.c */
extern int g_con_number; /* in rdpup.c */
extern int g_crc_seed; /* in rdpmisc.c */
extern int g_crc_table[]; /* in rdpmisc.c */
/******************************************************************************/
int
rdpCreatePicture(PicturePtr pPicture)
{
PictureScreenPtr ps;
int rv;
LLOGLN(10, ("rdpCreatePicture:"));
ps = GetPictureScreen(g_pScreen);
ps->CreatePicture = g_rdpScreen.CreatePicture;
rv = ps->CreatePicture(pPicture);
ps->CreatePicture = rdpCreatePicture;
return rv;
}
/******************************************************************************/
void
rdpDestroyPicture(PicturePtr pPicture)
{
PictureScreenPtr ps;
LLOGLN(10, ("rdpDestroyPicture:"));
ps = GetPictureScreen(g_pScreen);
ps->DestroyPicture = g_rdpScreen.DestroyPicture;
ps->DestroyPicture(pPicture);
ps->DestroyPicture = rdpDestroyPicture;
}
/******************************************************************************/
static int
print_format(PictFormatShort format)
{
switch (format)
{
case PIXMAN_a2r10g10b10:
LLOGLN(0, (" PIXMAN_x2r10g10b10"));
break;
case PIXMAN_x2r10g10b10:
LLOGLN(0, (" PIXMAN_x2r10g10b10"));
break;
case PIXMAN_a2b10g10r10:
LLOGLN(0, (" PIXMAN_a2b10g10r10"));
break;
case PIXMAN_x2b10g10r10:
LLOGLN(0, (" PIXMAN_x2b10g10r10"));
break;
case PIXMAN_a8r8g8b8:
LLOGLN(0, (" PIXMAN_a8r8g8b8"));
break;
case PIXMAN_x8r8g8b8:
LLOGLN(0, (" PIXMAN_x8r8g8b8"));
break;
case PIXMAN_a8b8g8r8:
LLOGLN(0, (" PIXMAN_a8b8g8r8"));
break;
case PIXMAN_x8b8g8r8:
LLOGLN(0, (" PIXMAN_x8b8g8r8"));
break;
case PIXMAN_b8g8r8a8:
LLOGLN(0, (" PIXMAN_b8g8r8a8"));
break;
case PIXMAN_b8g8r8x8:
LLOGLN(0, (" PIXMAN_b8g8r8x8"));
break;
/* 24bpp formats */
case PIXMAN_r8g8b8:
LLOGLN(0, (" PIXMAN_r8g8b8"));
break;
case PIXMAN_b8g8r8:
LLOGLN(0, (" PIXMAN_b8g8r8"));
break;
/* 16bpp formats */
case PIXMAN_r5g6b5:
LLOGLN(0, (" PIXMAN_r5g6b5"));
break;
case PIXMAN_b5g6r5:
LLOGLN(0, (" PIXMAN_b5g6r5"));
break;
case PIXMAN_a1r5g5b5:
LLOGLN(0, (" PIXMAN_a1r5g5b5"));
break;
case PIXMAN_x1r5g5b5:
LLOGLN(0, (" PIXMAN_x1r5g5b5"));
break;
case PIXMAN_a1b5g5r5:
LLOGLN(0, (" PIXMAN_a1b5g5r5"));
break;
case PIXMAN_x1b5g5r5:
LLOGLN(0, (" PIXMAN_x1b5g5r5"));
break;
case PIXMAN_a4r4g4b4:
LLOGLN(0, (" PIXMAN_a4r4g4b4"));
break;
case PIXMAN_x4r4g4b4:
LLOGLN(0, (" PIXMAN_x4r4g4b4"));
break;
case PIXMAN_a4b4g4r4:
LLOGLN(0, (" PIXMAN_a4b4g4r4"));
break;
case PIXMAN_x4b4g4r4:
LLOGLN(0, (" PIXMAN_x4b4g4r4"));
break;
/* 8bpp formats */
case PIXMAN_a8:
LLOGLN(0, (" PIXMAN_a8"));
break;
case PIXMAN_r3g3b2:
LLOGLN(0, (" PIXMAN_r3g3b2"));
break;
case PIXMAN_b2g3r3:
LLOGLN(0, (" PIXMAN_b2g3r3"));
break;
case PIXMAN_a2r2g2b2:
LLOGLN(0, (" PIXMAN_a2r2g2b2"));
break;
case PIXMAN_a2b2g2r2:
LLOGLN(0, (" PIXMAN_a2b2g2r2"));
break;
case PIXMAN_c8:
LLOGLN(0, (" PIXMAN_c8"));
break;
case PIXMAN_g8:
LLOGLN(0, (" PIXMAN_g8"));
break;
case PIXMAN_x4a4:
LLOGLN(0, (" PIXMAN_x4a4"));
break;
/* 4bpp formats */
case PIXMAN_a4:
LLOGLN(0, (" PIXMAN_a4"));
break;
case PIXMAN_r1g2b1:
LLOGLN(0, (" PIXMAN_r1g2b1"));
break;
case PIXMAN_b1g2r1:
LLOGLN(0, (" PIXMAN_b1g2r1"));
break;
case PIXMAN_a1r1g1b1:
LLOGLN(0, (" PIXMAN_a1r1g1b1"));
break;
case PIXMAN_a1b1g1r1:
LLOGLN(0, (" PIXMAN_a1b1g1r1"));
break;
case PIXMAN_c4:
LLOGLN(0, (" PIXMAN_c4"));
break;
case PIXMAN_g4:
LLOGLN(0, (" PIXMAN_g4"));
break;
/* 1bpp formats */
case PIXMAN_a1:
LLOGLN(0, (" PIXMAN_a1"));
break;
case PIXMAN_g1:
LLOGLN(0, (" PIXMAN_g1"));
break;
}
return 0;
}
/******************************************************************************/
static int
compsoite_print(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst,
INT16 yDst, CARD16 width, CARD16 height)
{
PixmapPtr pSrcPixmap;
PixmapPtr pDstPixmap;
rdpPixmapRec* pSrcPriv;
rdpPixmapRec* pDstPriv;
LLOGLN(0, ("compsoite_print: op %d xSrc %d ySrc %d xDst %d yDst %d "
"width %d height %d",
op, xSrc, ySrc, xDst, yDst, width, height));
if (pSrc != 0)
{
LLOGLN(0, (" src depth %d width %d height %d repeat %d repeatType %d "
"dither %d filter %d alphaMap %p componentAlpha %d", pSrc->pDrawable->depth,
pSrc->pDrawable->width, pSrc->pDrawable->height,
pSrc->repeat, pSrc->repeatType, pSrc->dither, pSrc->filter,
pSrc->alphaMap, pSrc->componentAlpha));
LLOGLN(0, (" transform %p", pSrc->transform));
LLOGLN(0, (" detail format red %d red mask %d green %d green mask %d "
"blue %d blue mask %d",
pSrc->pFormat->direct.red, pSrc->pFormat->direct.redMask,
pSrc->pFormat->direct.green, pSrc->pFormat->direct.greenMask,
pSrc->pFormat->direct.blue, pSrc->pFormat->direct.blueMask));
print_format(pSrc->format);
if (pSrc->pDrawable->type == DRAWABLE_PIXMAP)
{
pSrcPixmap = (PixmapPtr)(pSrc->pDrawable);
pSrcPriv = GETPIXPRIV(pSrcPixmap);
LLOGLN(0, (" DRAWABLE_PIXMAP pSrcPriv %p status %d", pSrcPriv, pSrcPriv->status));
}
else if (pSrc->pDrawable->type == DRAWABLE_WINDOW)
{
LLOGLN(0, (" DRAWABLE_WINDOW"));
}
else
{
LLOGLN(0, (" OTHER"));
}
}
if (pMask != 0)
{
LLOGLN(0, (" msk depth %d width %d height %d repeat %d repeatType %d",
pMask->pDrawable->depth,
pMask->pDrawable->width,
pMask->pDrawable->height, pMask->repeat, pMask->repeatType));
print_format(pMask->format);
}
if (pDst != 0)
{
LLOGLN(0, (" dst depth %d width %d height %d repeat %d repeatType %d "
"dither %d filter %d alphaMap %p", pDst->pDrawable->depth,
pDst->pDrawable->width, pDst->pDrawable->height,
pDst->repeat, pDst->repeatType, pDst->dither, pDst->filter,
pDst->alphaMap));
LLOGLN(0, (" transform %p", pDst->transform));
print_format(pDst->format);
if (pDst->pDrawable->type == DRAWABLE_PIXMAP)
{
pDstPixmap = (PixmapPtr)(pDst->pDrawable);
pDstPriv = GETPIXPRIV(pDstPixmap);
LLOGLN(0, (" DRAWABLE_PIXMAP pDstPriv %p status %d", pDstPriv, pDstPriv->status));
}
else if (pDst->pDrawable->type == DRAWABLE_WINDOW)
{
LLOGLN(0, (" DRAWABLE_WINDOW"));
}
else
{
LLOGLN(0, (" OTHER"));
}
}
return 0;
}
/******************************************************************************/
static int
src_alpha_needed(CARD8 op)
{
int rv;
rv = 0;
switch (op)
{
case 3: /* Over */
case 6: /* InReverse */
case 8: /* OutReverse */
case 9: /* Atop */
case 10: /* AtopReverse */
case 11: /* Xor */
case 13: /* Saturate */
case 17: /* DisjointOver */
case 18: /* DisjointOverReverse */
case 19: /* DisjointIn */
case 20: /* DisjointInReverse */
case 21: /* DisjointOut */
case 22: /* DisjointOutReverse */
case 23: /* DisjointAtop */
case 24: /* DisjointAtopReverse */
case 25: /* DisjointXor */
case 29: /* ConjointOver */
case 30: /* ConjointOverReverse */
case 31: /* ConjointIn */
case 32: /* ConjointInReverse */
case 33: /* ConjointOut */
case 34: /* ConjointOutReverse */
case 35: /* ConjointAtop */
case 36: /* ConjointAtopReverse */
case 37: /* ConjointXor */
rv = 1;
break;
}
return rv;
}
/******************************************************************************/
static int
dst_alpha_needed(CARD8 op)
{
int rv;
rv = 0;
switch (op)
{
case 4: /* OverReverse */
case 5: /* In */
case 7: /* Out */
case 9: /* Atop */
case 10: /* AtopReverse */
case 11: /* Xor */
case 13: /* Saturate */
case 17: /* DisjointOver */
case 18: /* DisjointOverReverse */
case 19: /* DisjointIn */
case 20: /* DisjointInReverse */
case 21: /* DisjointOut */
case 22: /* DisjointOutReverse */
case 23: /* DisjointAtop */
case 24: /* DisjointAtopReverse */
case 25: /* DisjointXor */
case 29: /* ConjointOver */
case 30: /* ConjointOverReverse */
case 31: /* ConjointIn */
case 32: /* ConjointInReverse */
case 33: /* ConjointOut */
case 34: /* ConjointOutReverse */
case 35: /* ConjointAtop */
case 36: /* ConjointAtopReverse */
case 37: /* ConjointXor */
rv = 1;
break;
}
return rv;
}
struct msk_info
{
int flags;
int idx;
int format;
int width;
int repeat;
};
static char g_com_fail_strings[][128] =
{
"OK",
"src not remotable",
"dst not remotable",
"msk not remotable"
};
/******************************************************************************/
/* returns boolean */
static int
check_drawables(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst,
INT16 yDst, CARD16 width, CARD16 height, struct msk_info* msk)
{
int rv;
int fail_reason;
PixmapPtr pSrcPixmap;
PixmapPtr pDstPixmap;
PixmapPtr pMskPixmap;
rdpPixmapRec* pSrcPriv;
rdpPixmapRec* pDstPriv;
rdpPixmapRec* pMskPriv;
fail_reason = 0;
pSrcPixmap = 0;
pDstPixmap = 0;
pMskPixmap = 0;
pSrcPriv = 0;
pDstPriv = 0;
pMskPriv = 0;
rv = 0;
if (pSrc != 0)
{
if (pSrc->pDrawable != 0)
{
if (pSrc->pDrawable->type == DRAWABLE_PIXMAP)
{
pSrcPixmap = (PixmapPtr)(pSrc->pDrawable);
pSrcPriv = GETPIXPRIV(pSrcPixmap);
if (xrdp_is_os(pSrcPixmap, pSrcPriv))
{
if (pDst != 0)
{
if (pDst->pDrawable != 0)
{
if (pDst->pDrawable->type == DRAWABLE_PIXMAP)
{
pDstPixmap = (PixmapPtr)(pDst->pDrawable);
pDstPriv = GETPIXPRIV(pDstPixmap);
if (xrdp_is_os(pDstPixmap, pDstPriv))
{
rv = 1;
}
else
{
fail_reason = 2;
}
}
}
}
}
else
{
fail_reason = 1;
}
}
}
}
if (rv)
{
if (pMask != 0)
{
#if 1
rv = 0;
if (pMask->pDrawable != 0)
{
if (pMask->pDrawable->type == DRAWABLE_PIXMAP)
{
pMskPixmap = (PixmapPtr)(pMask->pDrawable);
pMskPriv = GETPIXPRIV(pMskPixmap);
if (xrdp_is_os(pMskPixmap, pMskPriv))
{
rv = 1;
msk->flags = 1;
msk->idx = pMskPriv->rdpindex;
msk->format = pMask->format;
msk->width = pMask->pDrawable->width;
msk->repeat = pMask->repeatType;
}
else
{
fail_reason = 3;
}
}
}
#endif
}
}
if (rv == 0)
{
LLOGLN(10, ("check_drawables: can not remote [%s]", g_com_fail_strings[fail_reason]));
#if 0
compsoite_print(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
xDst, yDst, width, height);
#endif
}
else
{
LLOGLN(10, ("check_drawables: can remote [%s]", g_com_fail_strings[fail_reason]));
#if 0
compsoite_print(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
xDst, yDst, width, height);
#endif
}
return rv;
}
/******************************************************************************/
static int
rdpRemoteComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst,
INT16 yDst, CARD16 width, CARD16 height)
{
int ok_to_remote;
PixmapPtr pSrcPixmap;
PixmapPtr pMskPixmap;
PixmapPtr pDstPixmap;
rdpPixmapRec* pSrcPriv;
rdpPixmapRec* pMskPriv;
rdpPixmapRec* pDstPriv;
BoxRec box;
RegionRec reg1;
RegionRec reg2;
DrawablePtr p;
int j;
int num_clips;
struct msk_info msk;
LLOGLN(10, ("rdpRemoteComposite:"));
memset(&msk, 0, sizeof(msk));
ok_to_remote = check_drawables(op, pSrc, pMask, pDst, xSrc, ySrc,
xMask, yMask, xDst, yDst, width, height,
&msk);
if (!ok_to_remote)
{
return 1;
}
ValidatePicture(pSrc);
pSrcPixmap = (PixmapPtr)(pSrc->pDrawable);
pSrcPriv = GETPIXPRIV(pSrcPixmap);
rdpup_check_dirty(pSrcPixmap, pSrcPriv);
if (PIXMAN_FORMAT_A(pSrc->format) > 0)
{
if (src_alpha_needed(op))
{
rdpup_check_alpha_dirty(pSrcPixmap, pSrcPriv);
}
}
ValidatePicture(pDst);
pDstPixmap = (PixmapPtr)(pDst->pDrawable);
pDstPriv = GETPIXPRIV(pDstPixmap);
rdpup_check_dirty(pDstPixmap, pDstPriv);
if (PIXMAN_FORMAT_A(pDst->format) > 0)
{
if (dst_alpha_needed(op))
{
rdpup_check_alpha_dirty(pDstPixmap, pDstPriv);
}
}
if (pMask != 0)
{
ValidatePicture(pMask);
pMskPixmap = (PixmapPtr)(pMask->pDrawable);
pMskPriv = GETPIXPRIV(pMskPixmap);
rdpup_check_dirty(pMskPixmap, pMskPriv);
if (PIXMAN_FORMAT_A(msk.format) > 0)
{
rdpup_check_alpha_dirty(pMskPixmap, pMskPriv);
}
}
p = pDst->pDrawable;
rdpup_switch_os_surface(pDstPriv->rdpindex);
if (pDst->pCompositeClip != 0)
{
box.x1 = xDst;
box.y1 = yDst;
box.x2 = box.x1 + width;
box.y2 = box.y1 + height;
RegionInit(&reg1, &box, 0);
RegionInit(&reg2, NullBox, 0);
RegionCopy(&reg2, pDst->pCompositeClip);
RegionIntersect(&reg1, &reg1, &reg2);
RegionTranslate(&reg1, p->x, p->y);
num_clips = REGION_NUM_RECTS(&reg1);
if (num_clips > 0)
{
LLOGLN(10, ("num_clips %d", num_clips));
rdpup_begin_update();
for (j = num_clips - 1; j >= 0; j--)
{
box = REGION_RECTS(&reg1)[j];
rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
LLOGLN(10, ("pSrc->format 0x%x 0x%x 0x%x %d %d %d %d %d %d %d %d",
pSrc->format, msk.format, pDst->format, xSrc, ySrc,
xMask, yMask, xDst, yDst, width, height));
rdpup_composite(pSrcPriv->rdpindex, pSrc->format,
pSrc->pDrawable->width, pSrc->repeatType,
pSrc->transform, msk.flags, msk.idx, msk.format,
msk.width, msk.repeat, op, xSrc, ySrc,
xMask, yMask, xDst, yDst, width, height, pDst->format);
}
rdpup_reset_clip();
rdpup_end_update();
}
RegionUninit(&reg1);
RegionUninit(&reg2);
}
else
{
rdpup_begin_update();
rdpup_composite(pSrcPriv->rdpindex, pSrc->format,
pSrc->pDrawable->width, pSrc->repeatType,
pSrc->transform, msk.flags, msk.idx, msk.format,
msk.width, msk.repeat, op, xSrc, ySrc,
xMask, yMask, xDst, yDst, width, height, pDst->format);
rdpup_end_update();
}
rdpup_switch_os_surface(-1);
return 0;
}
/******************************************************************************/
static void
rdpCompositeOrg(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst,
INT16 yDst, CARD16 width, CARD16 height)
{
PictureScreenPtr ps;
ps = GetPictureScreen(g_pScreen);
ps->Composite = g_rdpScreen.Composite;
ps->Composite(op, pSrc, pMask, pDst, xSrc, ySrc,
xMask, yMask, xDst, yDst, width, height);
ps->Composite = rdpComposite;
}
/******************************************************************************/
/* it looks like all the antialias draws go through here
op is one of the following
#define PictOpMinimum 0
#define PictOpClear 0
#define PictOpSrc 1
#define PictOpDst 2
#define PictOpOver 3
#define PictOpOverReverse 4
#define PictOpIn 5
#define PictOpInReverse 6
#define PictOpOut 7
#define PictOpOutReverse 8
#define PictOpAtop 9
#define PictOpAtopReverse 10
#define PictOpXor 11
#define PictOpAdd 12
#define PictOpSaturate 13
#define PictOpMaximum 13
see for porter duff
http://www.svgopen.org/2005/papers/abstractsvgopen/
*/
void
rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst,
INT16 yDst, CARD16 width, CARD16 height)
{
BoxRec box;
RegionRec reg1;
RegionRec reg2;
DrawablePtr p;
int dirty_type;
int j;
int num_clips;
int post_process;
int reset_surface;
int got_id;
WindowPtr pDstWnd;
PixmapPtr pDstPixmap;
rdpPixmapRec* pDstPriv;
rdpPixmapRec* pDirtyPriv;
struct image_data id;
LLOGLN(10, ("rdpComposite:"));
if (g_doing_font == 2)
{
rdpCompositeOrg(op, pSrc, pMask, pDst, xSrc, ySrc,
xMask, yMask, xDst, yDst, width, height);
return;
}
#if 0
if (g_do_glyph_cache && g_do_alpha_glyphs)
{
if (pSrc->pDrawable->width == 1 &&
pSrc->pDrawable->height == 1)
{
if (pMask != 0)
{
/* TODO: here we can try to send it as a gylph */
}
}
}
#endif
/* try to remote the composite call */
if (g_do_composite &&
rdpRemoteComposite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
xDst, yDst, width, height) == 0)
{
rdpCompositeOrg(op, pSrc, pMask, pDst, xSrc, ySrc,
xMask, yMask, xDst, yDst, width, height);
return;
}
rdpCompositeOrg(op, pSrc, pMask, pDst, xSrc, ySrc,
xMask, yMask, xDst, yDst, width, height);
LLOGLN(10, ("rdpComposite: op %d %p %p %p w %d h %d", op, pSrc, pMask, pDst, width, height));
p = pDst->pDrawable;
pDstPriv = 0;
dirty_type = 0;
pDirtyPriv = 0;
post_process = 0;
reset_surface = 0;
got_id = 0;
if (p->type == DRAWABLE_PIXMAP)
{
pDstPixmap = (PixmapPtr)p;
pDstPriv = GETPIXPRIV(pDstPixmap);
if (XRDP_IS_OS(pDstPriv))
{
post_process = 1;
if (g_do_dirty_os)
{
LLOGLN(10, ("rdpComposite: gettig dirty"));
pDstPriv->is_dirty = 1;
dirty_type = g_doing_font ? RDI_IMGLL : RDI_IMGLY;
pDirtyPriv = pDstPriv;
}
else
{
rdpup_switch_os_surface(pDstPriv->rdpindex);
reset_surface = 1;
rdpup_get_pixmap_image_rect(pDstPixmap, &id);
got_id = 1;
LLOGLN(10, ("rdpComposite: offscreen"));
}
}
}
else
{
if (p->type == DRAWABLE_WINDOW)
{
pDstWnd = (WindowPtr)p;
if (pDstWnd->viewable)
{
post_process = 1;
rdpup_get_screen_image_rect(&id);
got_id = 1;
LLOGLN(10, ("rdpComposite: screen"));
}
}
}
if (!post_process)
{
return;
}
if (pDst->pCompositeClip != 0)
{
box.x1 = p->x + xDst;
box.y1 = p->y + yDst;
box.x2 = box.x1 + width;
box.y2 = box.y1 + height;
RegionInit(&reg1, &box, 0);
RegionInit(&reg2, NullBox, 0);
RegionCopy(&reg2, pDst->pCompositeClip);
RegionIntersect(&reg1, &reg1, &reg2);
if (dirty_type != 0)
{
draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, TAG_COMPOSITE);
}
else if (got_id)
{
num_clips = REGION_NUM_RECTS(&reg1);
if (num_clips > 0)
{
rdpup_begin_update();
for (j = num_clips - 1; j >= 0; j--)
{
box = REGION_RECTS(&reg1)[j];
rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
}
rdpup_end_update();
}
}
RegionUninit(&reg1);
RegionUninit(&reg2);
}
else
{
box.x1 = p->x + xDst;
box.y1 = p->y + yDst;
box.x2 = box.x1 + width;
box.y2 = box.y1 + height;
if (dirty_type != 0)
{
RegionInit(&reg1, &box, 0);
draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, TAG_COMPOSITE);
RegionUninit(&reg1);
}
else if (got_id)
{
rdpup_begin_update();
rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
rdpup_end_update();
}
}
if (reset_surface)
{
rdpup_switch_os_surface(-1);
}
}

@ -474,6 +474,8 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
} }
} }
LLOGLN(10, ("rdpCopyArea: fallback"));
/* do original call */ /* do original call */
rv = rdpCopyAreaOrg(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty); rv = rdpCopyAreaOrg(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
@ -557,7 +559,7 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
box.x2 = box.x1 + w; box.x2 = box.x1 + w;
box.y2 = box.y1 + h; box.y2 = box.y1 + h;
RegionInit(&reg1, &box, 0); RegionInit(&reg1, &box, 0);
draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, 1); draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, TAG_COPYAREA);
RegionUninit(&reg1); RegionUninit(&reg1);
} }
else if (got_id) else if (got_id)
@ -581,7 +583,7 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
box.y2 = box.y1 + h; box.y2 = box.y1 + h;
RegionInit(&box_reg, &box, 0); RegionInit(&box_reg, &box, 0);
RegionIntersect(&clip_reg, &clip_reg, &box_reg); RegionIntersect(&clip_reg, &clip_reg, &box_reg);
draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type, 1); draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type, TAG_COPYAREA);
RegionUninit(&box_reg); RegionUninit(&box_reg);
} }
else if (got_id) else if (got_id)

@ -168,7 +168,7 @@ rdpCopyPlane(DrawablePtr pSrc, DrawablePtr pDst,
box.x2 = box.x1 + w; box.x2 = box.x1 + w;
box.y2 = box.y1 + h; box.y2 = box.y1 + h;
RegionInit(&reg1, &box, 0); RegionInit(&reg1, &box, 0);
draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, 5); draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, TAG_COPYPLANE);
RegionUninit(&reg1); RegionUninit(&reg1);
} }
else if (got_id) else if (got_id)
@ -194,7 +194,7 @@ rdpCopyPlane(DrawablePtr pSrc, DrawablePtr pDst,
RegionInit(&reg2, NullBox, 0); RegionInit(&reg2, NullBox, 0);
RegionCopy(&reg2, &clip_reg); RegionCopy(&reg2, &clip_reg);
RegionIntersect(&reg1, &reg1, &reg2); RegionIntersect(&reg1, &reg1, &reg2);
draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, 5); draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, TAG_COPYPLANE);
RegionUninit(&reg1); RegionUninit(&reg1);
RegionUninit(&reg2); RegionUninit(&reg2);
} }

@ -203,7 +203,7 @@ rdpFillPolygon(DrawablePtr pDrawable, GCPtr pGC,
if (dirty_type != 0) if (dirty_type != 0)
{ {
RegionInit(&reg1, &box, 0); RegionInit(&reg1, &box, 0);
draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, 7); draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, TAG_FILLPOLYGON);
RegionUninit(&reg1); RegionUninit(&reg1);
} }
else if (got_id) else if (got_id)
@ -223,7 +223,7 @@ rdpFillPolygon(DrawablePtr pDrawable, GCPtr pGC,
{ {
if (dirty_type != 0) if (dirty_type != 0)
{ {
draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type, 7); draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type, TAG_FILLPOLYGON);
} }
else if (got_id) else if (got_id)
{ {

@ -169,7 +169,7 @@ rdpImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
if (dirty_type != 0) if (dirty_type != 0)
{ {
RegionInit(&reg1, &box, 0); RegionInit(&reg1, &box, 0);
draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, 13); draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, TAG_IMAGEGLYPHBLT);
RegionUninit(&reg1); RegionUninit(&reg1);
} }
else if (got_id) else if (got_id)
@ -189,7 +189,7 @@ rdpImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
{ {
if (dirty_type != 0) if (dirty_type != 0)
{ {
draw_item_add_img_region(pDirtyPriv, &reg, GXcopy, dirty_type, 13); draw_item_add_img_region(pDirtyPriv, &reg, GXcopy, dirty_type, TAG_IMAGEGLYPHBLT);
} }
else if (got_id) else if (got_id)
{ {

@ -167,7 +167,7 @@ rdpImageText16(DrawablePtr pDrawable, GCPtr pGC,
if (dirty_type != 0) if (dirty_type != 0)
{ {
RegionInit(&reg1, &box, 0); RegionInit(&reg1, &box, 0);
draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, 12); draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, TAG_IMAGETEXT16);
RegionUninit(&reg1); RegionUninit(&reg1);
} }
else if (got_id) else if (got_id)
@ -187,7 +187,7 @@ rdpImageText16(DrawablePtr pDrawable, GCPtr pGC,
{ {
if (dirty_type != 0) if (dirty_type != 0)
{ {
draw_item_add_img_region(pDirtyPriv, &reg, GXcopy, dirty_type, 12); draw_item_add_img_region(pDirtyPriv, &reg, GXcopy, dirty_type, TAG_IMAGETEXT16);
} }
else if (got_id) else if (got_id)
{ {

@ -167,7 +167,7 @@ rdpImageText8(DrawablePtr pDrawable, GCPtr pGC,
if (dirty_type != 0) if (dirty_type != 0)
{ {
RegionInit(&reg1, &box, 0); RegionInit(&reg1, &box, 0);
draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, 9); draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, TAG_IMAGETEXT8);
RegionUninit(&reg1); RegionUninit(&reg1);
} }
else if (got_id) else if (got_id)
@ -187,7 +187,7 @@ rdpImageText8(DrawablePtr pDrawable, GCPtr pGC,
{ {
if (dirty_type != 0) if (dirty_type != 0)
{ {
draw_item_add_img_region(pDirtyPriv, &reg, GXcopy, dirty_type, 9); draw_item_add_img_region(pDirtyPriv, &reg, GXcopy, dirty_type, TAG_IMAGETEXT8);
} }
else if (got_id) else if (got_id)
{ {

@ -185,7 +185,7 @@ rdpPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs)
{ {
if (dirty_type != 0) if (dirty_type != 0)
{ {
draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type, 6); draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type, TAG_POLYARC);
} }
else if (got_id) else if (got_id)
{ {
@ -217,7 +217,7 @@ rdpPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs)
{ {
if (dirty_type != 0) if (dirty_type != 0)
{ {
draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type, 6); draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type, TAG_POLYARC);
} }
else if (got_id) else if (got_id)
{ {

@ -185,7 +185,7 @@ rdpPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs)
{ {
if (dirty_type != 0) if (dirty_type != 0)
{ {
draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type, 8); draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type, TAG_POLYFILLARC);
} }
else if (got_id) else if (got_id)
{ {
@ -217,7 +217,7 @@ rdpPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs)
{ {
if (dirty_type != 0) if (dirty_type != 0)
{ {
draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type, 8); draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type, TAG_POLYFILLARC);
} }
else if (got_id) else if (got_id)
{ {

@ -196,7 +196,7 @@ rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
else else
{ {
draw_item_add_img_region(pDirtyPriv, fill_reg, GXcopy, draw_item_add_img_region(pDirtyPriv, fill_reg, GXcopy,
dirty_type, 2); dirty_type, TAG_POLYFILLRECT);
} }
} }
else if (got_id) else if (got_id)
@ -264,7 +264,7 @@ rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
{ {
LLOGLN(10, ("rdpPolyFillRect: 4")); LLOGLN(10, ("rdpPolyFillRect: 4"));
draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy,
dirty_type, 2); dirty_type, TAG_POLYFILLRECT);
} }
} }
else if (got_id) else if (got_id)

@ -169,7 +169,7 @@ rdpPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
if (dirty_type != 0) if (dirty_type != 0)
{ {
RegionInit(&reg1, &box, 0); RegionInit(&reg1, &box, 0);
draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, 14); draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, TAG_POLYGLYPHBLT);
RegionUninit(&reg1); RegionUninit(&reg1);
} }
else if (got_id) else if (got_id)
@ -189,7 +189,7 @@ rdpPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
{ {
if (dirty_type != 0) if (dirty_type != 0)
{ {
draw_item_add_img_region(pDirtyPriv, &reg, GXcopy, dirty_type, 14); draw_item_add_img_region(pDirtyPriv, &reg, GXcopy, dirty_type, TAG_POLYGLYPHBLT);
} }
else if (got_id) else if (got_id)
{ {

@ -221,7 +221,7 @@ rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects,
} }
else else
{ {
draw_item_add_img_region(pDirtyPriv, fill_reg, GXcopy, dirty_type, 4); draw_item_add_img_region(pDirtyPriv, fill_reg, GXcopy, dirty_type, TAG_POLYRECTANGLE);
} }
RegionDestroy(fill_reg); RegionDestroy(fill_reg);
@ -275,7 +275,7 @@ rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects,
} }
else else
{ {
draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type, 4); draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type, TAG_POLYRECTANGLE);
} }
} }
else if (got_id) else if (got_id)

@ -170,7 +170,7 @@ rdpPolyText16(DrawablePtr pDrawable, GCPtr pGC,
if (dirty_type != 0) if (dirty_type != 0)
{ {
RegionInit(&reg1, &box, 0); RegionInit(&reg1, &box, 0);
draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, 11); draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, TAG_POLYTEXT16);
RegionUninit(&reg1); RegionUninit(&reg1);
} }
else if (got_id) else if (got_id)
@ -190,7 +190,7 @@ rdpPolyText16(DrawablePtr pDrawable, GCPtr pGC,
{ {
if (dirty_type != 0) if (dirty_type != 0)
{ {
draw_item_add_img_region(pDirtyPriv, &reg, GXcopy, dirty_type, 11); draw_item_add_img_region(pDirtyPriv, &reg, GXcopy, dirty_type, TAG_POLYTEXT16);
} }
else if (got_id) else if (got_id)
{ {

@ -170,7 +170,7 @@ rdpPolyText8(DrawablePtr pDrawable, GCPtr pGC,
if (dirty_type != 0) if (dirty_type != 0)
{ {
RegionInit(&reg1, &box, 0); RegionInit(&reg1, &box, 0);
draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, 10); draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, TAG_POLYTEXT8);
RegionUninit(&reg1); RegionUninit(&reg1);
} }
else if (got_id) else if (got_id)
@ -190,7 +190,7 @@ rdpPolyText8(DrawablePtr pDrawable, GCPtr pGC,
{ {
if (dirty_type != 0) if (dirty_type != 0)
{ {
draw_item_add_img_region(pDirtyPriv, &reg, GXcopy, dirty_type, 10); draw_item_add_img_region(pDirtyPriv, &reg, GXcopy, dirty_type, TAG_POLYTEXT8);
} }
else if (got_id) else if (got_id)
{ {

@ -160,7 +160,7 @@ rdpPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst,
box.x2 = box.x1 + w; box.x2 = box.x1 + w;
box.y2 = box.y1 + h; box.y2 = box.y1 + h;
RegionInit(&reg1, &box, 0); RegionInit(&reg1, &box, 0);
draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, 15); draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, TAG_PUSHPIXELS);
RegionUninit(&reg1); RegionUninit(&reg1);
} }
else if (got_id) else if (got_id)
@ -185,7 +185,7 @@ rdpPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst,
if (dirty_type != 0) if (dirty_type != 0)
{ {
RegionInit(&reg1, &box, 0); RegionInit(&reg1, &box, 0);
draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type, 15); draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type, TAG_PUSHPIXELS);
RegionUninit(&reg1); RegionUninit(&reg1);
} }
else if (got_id) else if (got_id)

@ -163,7 +163,7 @@ rdpPutImage(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y,
box.x2 = box.x1 + w; box.x2 = box.x1 + w;
box.y2 = box.y1 + h; box.y2 = box.y1 + h;
RegionInit(&reg1, &box, 0); RegionInit(&reg1, &box, 0);
draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, 3); draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, TAG_PUTIMAGE);
RegionUninit(&reg1); RegionUninit(&reg1);
} }
else if (got_id) else if (got_id)
@ -185,7 +185,7 @@ rdpPutImage(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y,
RegionInit(&reg2, NullBox, 0); RegionInit(&reg2, NullBox, 0);
RegionCopy(&reg2, &clip_reg); RegionCopy(&reg2, &clip_reg);
RegionIntersect(&reg1, &reg1, &reg2); RegionIntersect(&reg1, &reg1, &reg2);
draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, 3); draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, TAG_PUTIMAGE);
RegionUninit(&reg1); RegionUninit(&reg1);
RegionUninit(&reg2); RegionUninit(&reg2);
} }

@ -45,6 +45,7 @@ Xserver drawing ops and funcs
#include "rdpImageGlyphBlt.h" #include "rdpImageGlyphBlt.h"
#include "rdpPolyGlyphBlt.h" #include "rdpPolyGlyphBlt.h"
#include "rdpPushPixels.h" #include "rdpPushPixels.h"
#include "rdpglyph.h"
#define LOG_LEVEL 1 #define LOG_LEVEL 1
#define LLOG(_level, _args) \ #define LLOG(_level, _args) \
@ -65,11 +66,10 @@ extern int g_do_dirty_os; /* in rdpmain.c */
extern int g_do_dirty_ons; /* in rdpmain.c */ extern int g_do_dirty_ons; /* in rdpmain.c */
extern rdpPixmapRec g_screenPriv; /* in rdpmain.c */ extern rdpPixmapRec g_screenPriv; /* in rdpmain.c */
extern int g_con_number; /* in rdpmain.c */ extern int g_con_number; /* in rdpmain.c */
extern int g_do_glyph_cache; /* in rdpmain.c */
ColormapPtr g_rdpInstalledColormap; ColormapPtr g_rdpInstalledColormap;
static int g_doing_font = 0;
GCFuncs g_rdpGCFuncs = GCFuncs g_rdpGCFuncs =
{ {
rdpValidateGC, rdpChangeGC, rdpCopyGC, rdpDestroyGC, rdpChangeClip, rdpValidateGC, rdpChangeGC, rdpCopyGC, rdpDestroyGC, rdpChangeClip,
@ -407,6 +407,8 @@ rdpCloseScreen(int i, ScreenPtr pScreen)
int int
draw_item_add(rdpPixmapRec *priv, struct rdp_draw_item *di) draw_item_add(rdpPixmapRec *priv, struct rdp_draw_item *di)
{ {
priv->is_alpha_dirty_not = 0;
if (priv->draw_item_tail == 0) if (priv->draw_item_tail == 0)
{ {
priv->draw_item_tail = di; priv->draw_item_tail = di;
@ -458,6 +460,11 @@ draw_item_remove(rdpPixmapRec *priv, struct rdp_draw_item *di)
g_free(di->u.line.segs); g_free(di->u.line.segs);
} }
} }
if (di->type == RDI_TEXT)
{
delete_rdp_text(di->u.text.rtext);
}
RegionDestroy(di->reg); RegionDestroy(di->reg);
g_free(di); g_free(di);
@ -511,6 +518,146 @@ remove_empties(rdpPixmapRec* priv)
return rv; return rv;
} }
/******************************************************************************/
int
region_get_pixel_count(RegionPtr reg)
{
int index;
int count;
int pixels;
int width;
int height;
BoxRec box;
pixels = 0;
count = REGION_NUM_RECTS(reg);
for (index = 0; index < count; index++)
{
box = REGION_RECTS(reg)[index];
width = box.x2 - box.x1;
height = box.y2 - box.y1;
pixels += width * height;
}
return pixels;
}
/******************************************************************************/
/* returns boolean */
int
region_in_region(RegionPtr reg_small, int sreg_pcount, RegionPtr reg_big)
{
int rv;
RegionRec reg;
rv = 0;
RegionInit(&reg, NullBox, 0);
RegionIntersect(&reg, reg_small, reg_big);
if (sreg_pcount == -1)
{
sreg_pcount = region_get_pixel_count(reg_small);
}
if (sreg_pcount == 0)
{
/* empty region not even in */
return 0;
}
if (region_get_pixel_count(&reg) == sreg_pcount)
{
rv = 1;
}
RegionUninit(&reg);
return rv;
}
/******************************************************************************/
static int
remove_empties(rdpPixmapRec* priv)
{
struct rdp_draw_item* di;
struct rdp_draw_item* di_prev;
int rv;
rv = 0;
/* remove draw items with empty regions */
di = priv->draw_item_head;
di_prev = 0;
while (di != 0)
{
if (!RegionNotEmpty(di->reg))
{
LLOGLN(10, ("remove_empties: removing empty item type %d", di->type));
draw_item_remove(priv, di);
di = di_prev == 0 ? priv->draw_item_head : di_prev->next;
rv++;
}
else
{
di_prev = di;
di = di->next;
}
}
return rv;
}
/******************************************************************************/
static int
dump_draw_list(rdpPixmapRec* priv)
{
struct rdp_draw_item* di;
int index;
int count;
BoxRec box;
LLOGLN(0, ("dump_draw_list:"));
di = priv->draw_item_head;
while (di != 0)
{
LLOGLN(0, (" type %d", di->type));
count = REGION_NUM_RECTS(di->reg);
if (count == 0)
{
LLOGLN(0, (" empty region"));
}
else
{
box = RegionExtents(di->reg)[0];
LLOGLN(0, (" region list follows extents x1 %d y1 %d x2 %d y2 %d",
box.x1, box.y1, box.x2, box.y2));
for (index = 0; index < count; index++)
{
box = REGION_RECTS(di->reg)[index];
LLOGLN(0, (" index %d x1 %d y1 %d x2 %d y2 %d",
index, box.x1, box.y1, box.x2, box.y2));
}
}
di = di->next;
}
return 0;
}
/******************************************************************************/
/* returns boolean */
static int
region_interect_at_all(RegionPtr reg_small, RegionPtr reg_big)
{
int rv;
RegionRec reg;
if (!RegionNotEmpty(reg_small))
{
return 0;
}
rv = 0;
RegionInit(&reg, NullBox, 0);
RegionIntersect(&reg, reg_big, reg_big);
if (RegionNotEmpty(&reg))
{
rv = 1;
}
RegionUninit(&reg);
return rv;
}
/******************************************************************************/ /******************************************************************************/
int int
draw_item_pack(PixmapPtr pix, rdpPixmapRec *priv) draw_item_pack(PixmapPtr pix, rdpPixmapRec *priv)
@ -552,6 +699,17 @@ draw_item_pack(PixmapPtr pix, rdpPixmapRec *priv)
while (di != 0) while (di != 0)
{ {
#if 0
if ((di_prev->type == RDI_IMGLL || di_prev->type == RDI_IMGLY) &&
(di->type == RDI_IMGLL || di->type == RDI_IMGLY))
{
LLOGLN(10, ("draw_item_pack: packing RDI_IMGLL and RDI_IMGLY"));
di_prev->type = RDI_IMGLY;
RegionUnion(di_prev->reg, di_prev->reg, di->reg);
draw_item_remove(priv, di);
di = di_prev->next;
}
#else
if ((di_prev->type == RDI_IMGLL) && (di->type == RDI_IMGLL)) if ((di_prev->type == RDI_IMGLL) && (di->type == RDI_IMGLL))
{ {
LLOGLN(10, ("draw_item_pack: packing RDI_IMGLL")); LLOGLN(10, ("draw_item_pack: packing RDI_IMGLL"));
@ -559,6 +717,7 @@ draw_item_pack(PixmapPtr pix, rdpPixmapRec *priv)
draw_item_remove(priv, di); draw_item_remove(priv, di);
di = di_prev->next; di = di_prev->next;
} }
#endif
else if ((di_prev->type == RDI_IMGLY) && (di->type == RDI_IMGLY)) else if ((di_prev->type == RDI_IMGLY) && (di->type == RDI_IMGLY))
{ {
LLOGLN(10, ("draw_item_pack: packing RDI_IMGLY")); LLOGLN(10, ("draw_item_pack: packing RDI_IMGLY"));
@ -577,6 +736,33 @@ draw_item_pack(PixmapPtr pix, rdpPixmapRec *priv)
remove_empties(priv); remove_empties(priv);
#endif #endif
#if 0
if (priv->draw_item_tail != 0)
{
if (priv->draw_item_tail->prev != 0)
{
di = priv->draw_item_tail;
while (di->prev != 0)
{
di_prev = di->prev;
while (di_prev != 0)
{
if ((di->type == RDI_TEXT) && (di_prev->type == RDI_IMGLY))
{
if (region_interect_at_all(di->reg, di_prev->reg))
{
di_prev->type = RDI_IMGLL;
}
}
di_prev = di_prev->prev;
}
di = di->prev;
}
}
}
remove_empties(priv);
#endif
#if 0 #if 0
/* subtract regions */ /* subtract regions */
if (priv->draw_item_tail != 0) if (priv->draw_item_tail != 0)
@ -598,8 +784,11 @@ draw_item_pack(PixmapPtr pix, rdpPixmapRec *priv)
while (di_prev != 0) while (di_prev != 0)
{ {
/* D = M - S */ if (region_in_region(di_prev->reg, -1, di->reg))
RegionSubtract(di_prev->reg, di_prev->reg, di->reg); {
/* empty region so this draw item will get removed below */
RegionEmpty(di_prev->reg);
}
di_prev = di_prev->prev; di_prev = di_prev->prev;
} }
} }
@ -723,6 +912,25 @@ draw_item_add_srcblt_region(rdpPixmapRec *priv, RegionPtr reg,
return 0; return 0;
} }
/******************************************************************************/
int
draw_item_add_text_region(rdpPixmapRec* priv, RegionPtr reg, int color,
int opcode, struct rdp_text* rtext)
{
struct rdp_draw_item* di;
LLOGLN(10, ("draw_item_add_text_region:"));
di = (struct rdp_draw_item*)g_malloc(sizeof(struct rdp_draw_item), 1);
di->type = RDI_TEXT;
di->u.text.fg_color = color;
di->u.text.opcode = opcode;
di->u.text.rtext = rtext;
di->reg = RegionCreate(NullBox, 0);
RegionCopy(di->reg, reg);
draw_item_add(priv, di);
return 0;
}
/******************************************************************************/ /******************************************************************************/
PixmapPtr PixmapPtr
rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth, rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth,
@ -746,6 +954,7 @@ rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth,
pScreen->ModifyPixmapHeader(rv, org_width, 0, 0, 0, 0, 0); pScreen->ModifyPixmapHeader(rv, org_width, 0, 0, 0, 0, 0);
if ((org_width == 0) && (height == 0)) if ((org_width == 0) && (height == 0))
{ {
LLOGLN(10, ("rdpCreatePixmap: setting is_scratch"));
priv->is_scratch = 1; priv->is_scratch = 1;
} }
return rv; return rv;
@ -808,13 +1017,12 @@ xrdp_is_os(PixmapPtr pix, rdpPixmapPtr priv)
(width > 0) && (height > 0) && (priv->kind_width > 0) && (width > 0) && (height > 0) && (priv->kind_width > 0) &&
(priv->is_scratch == 0) && (priv->use_count >= 0)) (priv->is_scratch == 0) && (priv->use_count >= 0))
{ {
LLOGLN(10, ("%d %d", priv->kind_width, pix->drawable.width)); width = (width + 3) & ~3;
priv->rdpindex = rdpup_add_os_bitmap(pix, priv); priv->rdpindex = rdpup_add_os_bitmap(pix, priv);
if (priv->rdpindex >= 0) if (priv->rdpindex >= 0)
{ {
priv->status = 1; priv->status = 1;
rdpup_create_os_surface(priv->rdpindex, rdpup_create_os_surface(priv->rdpindex, width, height);
priv->kind_width, height);
box.x1 = 0; box.x1 = 0;
box.y1 = 0; box.y1 = 0;
box.x2 = width; box.x2 = width;
@ -848,6 +1056,10 @@ xrdp_is_os(PixmapPtr pix, rdpPixmapPtr priv)
priv->use_count++; priv->use_count++;
return 1; return 1;
} }
else
{
LLOGLN(10, ("xrdp_is_os: rdpup_add_os_bitmap failed"));
}
} }
priv->use_count++; priv->use_count++;
return 0; return 0;
@ -896,6 +1108,10 @@ rdpDestroyWindow(WindowPtr pWindow)
if (g_use_rail) if (g_use_rail)
{ {
#ifdef XRDP_WM_RDPUP
LLOGLN(10, (" rdpup_delete_window"));
rdpup_delete_window(pWindow, priv);
#endif
} }
return rv; return rv;
@ -957,7 +1173,9 @@ rdpRealizeWindow(WindowPtr pWindow)
pWindow->drawable.x, pWindow->drawable.y, pWindow->drawable.x, pWindow->drawable.y,
pWindow->drawable.width, pWindow->drawable.height)); pWindow->drawable.width, pWindow->drawable.height));
priv->status = 1; priv->status = 1;
#ifdef XRDP_WM_RDPUP
rdpup_create_window(pWindow, priv); rdpup_create_window(pWindow, priv);
#endif
} }
} }
} }
@ -986,7 +1204,18 @@ rdpUnrealizeWindow(WindowPtr pWindow)
{ {
LLOGLN(10, ("rdpUnrealizeWindow:")); LLOGLN(10, ("rdpUnrealizeWindow:"));
priv->status = 0; priv->status = 0;
rdpup_delete_window(pWindow, priv); if (pWindow->overrideRedirect) {
#ifdef XRDP_WM_RDPUP
/*
* Popups are unmapped by X server, so probably
* they will be mapped again. Thereby we should
* just hide those popups instead of destroying
* them.
*/
LLOGLN(10, (" rdpup_show_window"));
rdpup_show_window(pWindow, priv, 0x0); /* 0x0 - do not show the window */
#endif
}
} }
} }
@ -1335,198 +1564,3 @@ rdpSaveScreen(ScreenPtr pScreen, int on)
{ {
return 1; return 1;
} }
/******************************************************************************/
/* it looks like all the antialias draws go through here */
void
rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst,
INT16 yDst, CARD16 width, CARD16 height)
{
BoxRec box;
PictureScreenPtr ps;
RegionRec reg1;
RegionRec reg2;
DrawablePtr p;
int dirty_type;
int j;
int num_clips;
int post_process;
int reset_surface;
int got_id;
WindowPtr pDstWnd;
PixmapPtr pDstPixmap;
rdpPixmapRec *pDstPriv;
rdpPixmapRec *pDirtyPriv;
struct image_data id;
LLOGLN(10, ("rdpComposite: op %d width %d height %d", op, width, height));
ps = GetPictureScreen(g_pScreen);
ps->Composite = g_rdpScreen.Composite;
ps->Composite(op, pSrc, pMask, pDst, xSrc, ySrc,
xMask, yMask, xDst, yDst, width, height);
ps->Composite = rdpComposite;
p = pDst->pDrawable;
dirty_type = 0;
pDirtyPriv = 0;
post_process = 0;
reset_surface = 0;
got_id = 0;
if (p->type == DRAWABLE_PIXMAP)
{
pDstPixmap = (PixmapPtr)p;
pDstPriv = GETPIXPRIV(pDstPixmap);
if (xrdp_is_os(pDstPixmap, pDstPriv))
{
post_process = 1;
if (g_do_dirty_os)
{
LLOGLN(10, ("rdpComposite: getting dirty"));
pDstPriv->is_dirty = 1;
dirty_type = g_doing_font ? RDI_IMGLL : RDI_IMGLY;
pDirtyPriv = pDstPriv;
}
else
{
rdpup_switch_os_surface(pDstPriv->rdpindex);
reset_surface = 1;
rdpup_get_pixmap_image_rect(pDstPixmap, &id);
got_id = 1;
LLOGLN(10, ("rdpComposite: offscreen"));
}
}
}
else
{
if (p->type == DRAWABLE_WINDOW)
{
pDstWnd = (WindowPtr)p;
if (pDstWnd->viewable)
{
post_process = 1;
if (g_do_dirty_ons)
{
LLOGLN(10, ("rdpComposite: getting dirty"));
g_screenPriv.is_dirty = 1;
pDirtyPriv = &g_screenPriv;
dirty_type = g_doing_font ? RDI_IMGLL : RDI_IMGLY;
}
else
{
rdpup_get_screen_image_rect(&id);
got_id = 1;
LLOGLN(10, ("rdpComposite: screen"));
}
}
}
}
if (!post_process)
{
return;
}
LLOGLN(10, ("rdpComposite: post_process"));
if (pDst->pCompositeClip != 0)
{
box.x1 = p->x + xDst;
box.y1 = p->y + yDst;
box.x2 = box.x1 + width;
box.y2 = box.y1 + height;
RegionInit(&reg1, &box, 0);
RegionInit(&reg2, NullBox, 0);
RegionCopy(&reg2, pDst->pCompositeClip);
RegionIntersect(&reg1, &reg1, &reg2);
if (dirty_type != 0)
{
draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, 0);
}
else if (got_id)
{
num_clips = REGION_NUM_RECTS(&reg1);
if (num_clips > 0)
{
rdpup_begin_update();
for (j = num_clips - 1; j >= 0; j--)
{
box = REGION_RECTS(&reg1)[j];
rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
}
rdpup_end_update();
}
}
RegionUninit(&reg1);
RegionUninit(&reg2);
}
else
{
box.x1 = p->x + xDst;
box.y1 = p->y + yDst;
box.x2 = box.x1 + width;
box.y2 = box.y1 + height;
if (dirty_type != 0)
{
RegionInit(&reg1, &box, 0);
draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, 0);
RegionUninit(&reg1);
}
else if (got_id)
{
rdpup_begin_update();
rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
rdpup_end_update();
}
}
if (reset_surface)
{
rdpup_switch_os_surface(-1);
}
}
/******************************************************************************/
void
rdpGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc, INT16 ySrc, int nlists, GlyphListPtr lists,
GlyphPtr *glyphs)
{
PictureScreenPtr ps;
int index;
LLOGLN(10, ("rdpGlyphs:"));
LLOGLN(10, ("rdpGlyphs: nlists %d len %d", nlists, lists->len));
rdpup_set_hints(1, 1);
g_doing_font = 1;
for (index = 0; index < lists->len; index++)
{
LLOGLN(10, (" index %d size %d refcnt %d width %d height %d",
index, (int)(glyphs[index]->size), (int)(glyphs[index]->refcnt),
glyphs[index]->info.width, glyphs[index]->info.height));
}
ps = GetPictureScreen(g_pScreen);
ps->Glyphs = g_rdpScreen.Glyphs;
ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc,
nlists, lists, glyphs);
ps->Glyphs = rdpGlyphs;
rdpup_set_hints(0, 1);
g_doing_font = 0;
LLOGLN(10, ("rdpGlyphs: out"));
}

@ -0,0 +1,860 @@
/*
Copyright 2012 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
http://msdn.microsoft.com/en-us/library/cc241863(v=prot.20).aspx
4.6.1 "d" Character
This topic has not yet been rated - Rate this topic
The following shows glyph image data (1 bpp format) for character
"d" extracted from a Cache Glyph (Revision 2) (section 2.2.2.2.1.2.6)
Secondary Drawing Order.
Glyph width = 5 pixels
Glyph height = 9 pixels
Glyph origin = (0, -9), marked with an "X" on the image grid
Bitmap = { 0x08, 0x08, 0x08, 0x78, 0x88, 0x88, 0x88, 0x88, 0x78 }
http://msdn.microsoft.com/en-us/library/cc241864(v=prot.20).aspx
4.6.2 "p" Character
This topic has not yet been rated - Rate this topic
The following shows glyph image data (1 bpp format) for character
"p" extracted from a Cache Glyph (Revision 2) (section 2.2.2.2.1.2.6)
Secondary Drawing Order.
Glyph width = 5 pixels
Glyph height = 8 pixels
Glyph origin = (0, -6), marked with an "X" on the image grid
Bitmap = { 0xF0, 0x88, 0x88, 0x88, 0x88, 0xF0, 0x80, 0x80 }
*/
#include "rdp.h"
#include "rdpdraw.h"
#include "rdpglyph.h"
extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
extern int g_do_dirty_os; /* in rdpmain.c */
extern int g_do_alpha_glyphs; /* in rdpmain.c */
extern int g_do_glyph_cache; /* in rdpmain.c */
extern int g_doing_font; /* in rdpmain.c */
extern ScreenPtr g_pScreen; /* in rdpmain.c */
extern rdpScreenInfoRec g_rdpScreen; /* in rdpmain.c */
#define LOG_LEVEL 1
#define LLOG(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0)
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
struct font_cache
{
int offset;
int baseline;
int width;
int height;
int crc;
int stamp;
};
static struct font_cache g_font_cache[12][256];
static int g_stamp = 0;
/*****************************************************************************/
static void
set_mono_pixel(char* data, int x, int y, int width, int pixel)
{
int start;
int shift;
width = (width + 7) / 8;
start = (y * width) + x / 8;
shift = x % 8;
if (pixel != 0)
{
data[start] = data[start] | (0x80 >> shift);
}
else
{
data[start] = data[start] & ~(0x80 >> shift);
}
}
/*****************************************************************************/
static int
lget_pixel(char* data, int x, int y, int depth, int stride_bytes)
{
int start;
int shift;
if (depth == 1)
{
start = (y * stride_bytes) + x / 8;
shift = x % 8;
return (data[start] & (0x01 << shift)) ? 0xff : 0;
}
else if (depth == 8)
{
return data[y * stride_bytes + x];
}
return 0;
}
/******************************************************************************/
static int
glyph_get_data(ScreenPtr pScreen, GlyphPtr glyph, struct rdp_font_char* rfd)
{
int i;
int j;
int src_xoff;
int src_yoff;
int src_stride_bytes;
int dst_stride_bytes;
int hh;
int ww;
int src_depth;
unsigned char pixel;
PicturePtr pPicture;
pixman_image_t *src;
uint32_t* pi32;
char* pi8;
pPicture = GlyphPicture(glyph)[pScreen->myNum];
if (pPicture == 0)
{
return 0;
}
src = image_from_pict(pPicture, FALSE, &src_xoff, &src_yoff);
if (src == 0)
{
return 0;
}
src_stride_bytes = pixman_image_get_stride(src);
if (g_do_alpha_glyphs)
{
dst_stride_bytes = (glyph->info.width + 3) & ~3;
rfd->bpp = 8;
}
else
{
dst_stride_bytes = (((glyph->info.width + 7) / 8) + 3) & ~3;
rfd->bpp = 1;
}
src_depth = pixman_image_get_depth(src);
ww = pixman_image_get_width(src);
hh = pixman_image_get_height(src);
if ((ww != glyph->info.width) || (hh != glyph->info.height) ||
((src_depth != 1) && (src_depth != 8)))
{
LLOGLN(0, ("glyph_get_data: bad glyph"));
free_pixman_pict(pPicture, src);
return 0;
}
rfd->data_bytes = glyph->info.height * dst_stride_bytes;
rfd->data = (char*)g_malloc(rfd->data_bytes, 1);
rfd->offset = -glyph->info.x;
rfd->baseline = -glyph->info.y;
rfd->width = glyph->info.width;
rfd->height = glyph->info.height;
pi32 = pixman_image_get_data(src);
pi8 = (char*)pi32;
for (j = 0; j < rfd->height; j++)
{
for (i = 0; i < rfd->width; i++)
{
pixel = lget_pixel(pi8, i, j, src_depth, src_stride_bytes);
if (g_do_alpha_glyphs)
{
rfd->data[j * dst_stride_bytes + i] = pixel;
}
else
{
if (pixel > 0x7f)
{
set_mono_pixel(rfd->data, i, j, rfd->width, 1);
}
else
{
set_mono_pixel(rfd->data, i, j, rfd->width, 0);
}
}
}
}
free_pixman_pict(pPicture, src);
return 0;
}
/******************************************************************************/
struct rdp_text*
create_rdp_text(ScreenPtr pScreen, int nlists, GlyphListPtr lists,
GlyphPtr* glyphs)
{
struct rdp_text* rv;
struct rdp_text* rtext;
struct rdp_text* last_rtext;
BoxRec box;
RegionRec reg1;
int n;
int lxoff;
int lyoff;
int count;
int lx;
int ly;
int font_index;
int max_height;
int min_height;
int force_new;
GlyphPtr glyph;
struct rdp_font_char* rfd;
LLOGLN(10, ("create_rdp_text: nlists %d", nlists));
max_height = 0;
min_height = 0x7fffffff;
lx = lists->xOff;
ly = lists->yOff;
lxoff = 0;
lyoff = 0;
force_new = 0;
rtext = (struct rdp_text*)g_malloc(sizeof(struct rdp_text), 1);
rtext->reg = RegionCreate(NullBox, 0);
rtext->flags = 3;
rtext->mixmode = 0;
rtext->x = lx;
rtext->y = ly;
rv = rtext;
last_rtext = rtext;
count = 0;
while (nlists--)
{
LLOGLN(10, ("lists->xOff %d lists->yOff %d", lists->xOff, lists->yOff));
if (count != 0)
{
lx += lists->xOff;
ly += lists->yOff;
force_new = 1;
}
count++;
n = lists->len;
lists++;
while (n--)
{
glyph = *glyphs++;
/* process glyph here */
if ((glyph->info.width > 0) && (glyph->info.height > 0))
{
if (force_new)
{
LLOGLN(10, ("create_rdp_text: too many chars"));
force_new = 0;
rtext = (struct rdp_text*)g_malloc(sizeof(struct rdp_text), 1);
rtext->reg = RegionCreate(NullBox, 0);
rtext->flags = 3;
rtext->mixmode = 0;
rtext->x = lx;
rtext->y = ly;
last_rtext->next = rtext;
last_rtext = rtext;
lxoff = 0;
lyoff = 0;
}
LLOGLN(10, ("x %d y %d width %d height %d xOff %d yOff %d "
"num_chars %d lxoff %d lyoff %d lx %d ly %d",
glyph->info.x, glyph->info.y,
glyph->info.width, glyph->info.height,
glyph->info.xOff, glyph->info.yOff, rtext->num_chars,
lxoff, lyoff, lx, ly));
rfd = (struct rdp_font_char*)g_malloc(sizeof(struct rdp_font_char), 1);
rtext->chars[rtext->num_chars] = rfd;
box.x1 = lx - glyph->info.x;
box.y1 = ly - glyph->info.y;
box.x2 = box.x1 + glyph->info.width;
box.y2 = box.y1 + glyph->info.height;
if (glyph->info.height > max_height)
{
max_height = glyph->info.height;
}
if (glyph->info.height < min_height)
{
min_height = glyph->info.height;
}
RegionInit(&reg1, &box, 0);
RegionUnion(rtext->reg, &reg1, rtext->reg);
RegionUninit(&reg1);
glyph_get_data(pScreen, glyph, rfd);
rfd->incby = lxoff;
lxoff = glyph->info.xOff;
lyoff = glyph->info.yOff;
rtext->num_chars++;
if (rtext->num_chars > 63)
{
force_new = 1;
}
}
else
{
lxoff += glyph->info.xOff;
lyoff += glyph->info.yOff;
}
lx += glyph->info.xOff;
ly += glyph->info.yOff;
}
}
if (max_height > 10)
{
font_index = 8;
}
else if (max_height < 7)
{
font_index = 6;
}
else
{
font_index = 7;
}
LLOGLN(10, ("create_rdp_text: min_height %d max_height %d font_index %d",
min_height, max_height, font_index));
rtext = rv;
while (rtext != 0)
{
rtext->font = font_index;
rtext = rtext->next;
}
return rv;
}
/******************************************************************************/
int
delete_rdp_text(struct rdp_text* rtext)
{
int index;
if (rtext == 0)
{
return 0;
}
for (index = 0; index < rtext->num_chars; index++)
{
if (rtext->chars[index] != 0)
{
g_free(rtext->chars[index]->data);
g_free(rtext->chars[index]);
}
}
RegionDestroy(rtext->reg);
delete_rdp_text(rtext->next);
g_free(rtext);
return 0;
}
/******************************************************************************/
static int
get_color(PicturePtr pPicture)
{
int src_xoff;
int src_yoff;
int rv;
uint32_t* pi32;
pixman_image_t *src;
src = image_from_pict(pPicture, FALSE, &src_xoff, &src_yoff);
if (src == 0)
{
return 0;
}
pi32 = pixman_image_get_data(src);
if (pi32 == 0)
{
return 0;
}
rv = *pi32;
LLOGLN(10, ("get_color: 0x%8.8x width %d height %d ", rv,
pixman_image_get_width(src),
pixman_image_get_height(src)));
free_pixman_pict(pPicture, src);
return rv;
}
/******************************************************************************/
static int
find_or_add_char(int font, struct rdp_font_char* rfd)
{
int crc;
int index;
int char_index;
int oldest;
crc = get_crc(rfd->data, rfd->data_bytes);
LLOGLN(10, ("find_or_add_char: crc 0x%8.8x", crc));
char_index = 0;
oldest = 0x7fffffff;
for (index = 0; index < 250; index++)
{
if ((g_font_cache[font][index].crc == crc) &&
(g_font_cache[font][index].width == rfd->width) &&
(g_font_cache[font][index].height == rfd->height) &&
(g_font_cache[font][index].offset == rfd->offset) &&
(g_font_cache[font][index].baseline == rfd->baseline))
{
g_stamp++;
g_font_cache[font][index].stamp = g_stamp;
LLOGLN(10, ("find_or_add_char: found char at %d %d", font, index));
return index;
}
if (g_font_cache[font][index].stamp < oldest)
{
oldest = g_font_cache[font][index].stamp;
char_index = index;
}
}
g_stamp++;
g_font_cache[font][char_index].stamp = g_stamp;
g_font_cache[font][char_index].crc = crc;
g_font_cache[font][char_index].width = rfd->width;
g_font_cache[font][char_index].height = rfd->height;
g_font_cache[font][char_index].offset = rfd->offset;
g_font_cache[font][char_index].baseline = rfd->baseline;
LLOGLN(10, ("find_or_add_char: adding char at %d %d", font, char_index));
if (rfd->bpp == 8)
{
rdpup_add_char_alpha(font, char_index, rfd->offset, rfd->baseline,
rfd->width, rfd->height,
rfd->data, rfd->data_bytes);
}
else
{
rdpup_add_char(font, char_index, rfd->offset, rfd->baseline,
rfd->width, rfd->height,
rfd->data, rfd->data_bytes);
}
return char_index;
}
/******************************************************************************/
int
rdp_text_chars_to_data(struct rdp_text* rtext)
{
int index;
int data_bytes;
int char_index;
struct rdp_font_char* rfd;
LLOGLN(10, ("rdp_text_chars_to_data: rtext->num_chars %d", rtext->num_chars));
data_bytes = 0;
for (index = 0; index < rtext->num_chars; index++)
{
rfd = rtext->chars[index];
if (rfd == 0)
{
LLOGLN(0, ("rdp_text_chars_to_data: error rfd is nil"));
continue;
}
char_index = find_or_add_char(rtext->font, rfd);
rtext->data[data_bytes] = char_index;
data_bytes++;
if (rfd->incby > 127)
{
rtext->data[data_bytes] = 0x80;
data_bytes++;
rtext->data[data_bytes] = (rfd->incby >> 0) & 0xff;
data_bytes++;
rtext->data[data_bytes] = (rfd->incby >> 8) & 0xff;
data_bytes++;
}
else
{
rtext->data[data_bytes] = rfd->incby;
data_bytes++;
}
}
rtext->data_bytes = data_bytes;
return 0;
}
/******************************************************************************/
/*
typedef struct _GlyphList {
INT16 xOff;
INT16 yOff;
CARD8 len;
PictFormatPtr format;
} GlyphListRec, *GlyphListPtr;
*/
/* see ghyphstr.h but the follow is not in there
typedef struct _XGlyphInfo {
unsigned short width;
unsigned short height;
short x;
short y;
short xOff;
short yOff;
} XGlyphInfo;
*/
static void
rdpGlyphu(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
int nlists, GlyphListPtr lists, GlyphPtr* glyphs,
BoxPtr extents)
{
BoxRec box;
RegionRec reg1;
RegionRec reg2;
DrawablePtr p;
int dirty_type;
int j;
int num_clips;
int post_process;
int reset_surface;
int got_id;
int fg_color;
WindowPtr pDstWnd;
PixmapPtr pDstPixmap;
rdpPixmapRec* pDstPriv;
rdpPixmapRec* pDirtyPriv;
struct image_data id;
struct rdp_text* rtext;
struct rdp_text* trtext;
LLOGLN(10, ("rdpGlyphu: xSrc %d ySrc %d", xSrc, ySrc));
p = pDst->pDrawable;
dirty_type = 0;
pDirtyPriv = 0;
post_process = 0;
reset_surface = 0;
got_id = 0;
if (p->type == DRAWABLE_PIXMAP)
{
pDstPixmap = (PixmapPtr)p;
pDstPriv = GETPIXPRIV(pDstPixmap);
if (XRDP_IS_OS(pDstPriv))
{
rdpup_check_dirty(pDstPixmap, pDstPriv);
post_process = 1;
if (g_do_dirty_os)
{
LLOGLN(10, ("rdpGlyphu: gettig dirty"));
pDstPriv->is_dirty = 1;
dirty_type = RDI_IMGLL;
pDirtyPriv = pDstPriv;
}
else
{
rdpup_switch_os_surface(pDstPriv->rdpindex);
reset_surface = 1;
rdpup_get_pixmap_image_rect(pDstPixmap, &id);
got_id = 1;
LLOGLN(10, ("rdpGlyphu: offscreen"));
}
}
}
else
{
if (p->type == DRAWABLE_WINDOW)
{
pDstWnd = (WindowPtr)p;
if (pDstWnd->viewable)
{
post_process = 1;
rdpup_get_screen_image_rect(&id);
got_id = 1;
LLOGLN(10, ("rdpGlyphu: screen"));
}
}
}
if (!post_process)
{
return;
}
rtext = create_rdp_text(pDst->pDrawable->pScreen, nlists, lists, glyphs);
if (rtext == 0)
{
LLOGLN(0, ("rdpGlyphu: create_rdp_text failed"));
return;
}
fg_color = get_color(pSrc);
LLOGLN(10, ("rdpGlyphu: pDst->clientClipType %d pCompositeClip %p",
pDst->clientClipType, pDst->pCompositeClip));
if (pDst->pCompositeClip != 0)
{
box.x1 = p->x + extents->x1;
box.y1 = p->y + extents->y1;
box.x2 = p->x + extents->x2;
box.y2 = p->y + extents->y2;
RegionInit(&reg1, &box, 0);
RegionInit(&reg2, NullBox, 0);
RegionCopy(&reg2, pDst->pCompositeClip);
RegionIntersect(&reg1, &reg1, &reg2);
if (dirty_type != 0)
{
LLOGLN(10, ("1"));
draw_item_add_text_region(pDirtyPriv, &reg1, fg_color, GXcopy, rtext);
rtext = 0;
}
else if (got_id)
{
num_clips = REGION_NUM_RECTS(&reg1);
if (num_clips > 0)
{
LLOGLN(10, (" num_clips %d", num_clips));
rdpup_begin_update();
rdpup_set_fgcolor(fg_color);
trtext = rtext;
while (trtext != 0)
{
rdp_text_chars_to_data(trtext);
for (j = num_clips - 1; j >= 0; j--)
{
box = REGION_RECTS(&reg1)[j];
LLOGLN(10, ("2"));
rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
LLOGLN(10, ("rdpGlyphu: rdpup_draw_text"));
box = RegionExtents(trtext->reg)[0];
rdpup_draw_text(trtext->font, trtext->flags, trtext->mixmode,
box.x1 + p->x, box.y1 + p->y,
box.x2 + p->x, box.y2 + p->y,
//box.x1 + p->x, box.y1 + p->y,
//box.x2 + p->x, box.y2 + p->y,
0, 0, 0, 0,
trtext->x + p->x, trtext->y + p->y,
trtext->data, trtext->data_bytes);
}
trtext = trtext->next;
}
rdpup_reset_clip();
rdpup_end_update();
}
}
RegionUninit(&reg1);
RegionUninit(&reg2);
}
else
{
box.x1 = p->x + extents->x1;
box.y1 = p->y + extents->y1;
box.x2 = p->x + extents->x2;
box.y2 = p->y + extents->y2;
if (dirty_type != 0)
{
RegionInit(&reg1, &box, 0);
LLOGLN(10, ("3"));
draw_item_add_text_region(pDirtyPriv, &reg1, fg_color, GXcopy, rtext);
rtext = 0;
RegionUninit(&reg1);
}
else if (got_id)
{
rdpup_begin_update();
LLOGLN(10, ("4"));
rdpup_set_fgcolor(fg_color);
trtext = rtext;
while (trtext != 0)
{
LLOGLN(10, ("rdpGlyphu: rdpup_draw_text"));
rdp_text_chars_to_data(trtext);
box = RegionExtents(trtext->reg)[0];
rdpup_draw_text(trtext->font, trtext->flags, trtext->mixmode,
box.x1 + p->x, box.y1 + p->y,
box.x2 + p->x, box.y2 + p->y,
//box.x1 + p->x, box.y1 + p->y,
//box.x2 + p->x, box.y2 + p->y,
0, 0, 0, 0,
trtext->x + p->x, trtext->y + p->y,
trtext->data, trtext->data_bytes);
trtext = trtext->next;
}
rdpup_end_update();
}
}
if (reset_surface)
{
rdpup_switch_os_surface(-1);
}
delete_rdp_text(rtext);
}
/******************************************************************************/
static void
GlyphExtents(int nlist, GlyphListPtr list, GlyphPtr* glyphs, BoxPtr extents)
{
int x1;
int x2;
int y1;
int y2;
int n;
int x;
int y;
GlyphPtr glyph;
x = 0;
y = 0;
extents->x1 = MAXSHORT;
extents->x2 = MINSHORT;
extents->y1 = MAXSHORT;
extents->y2 = MINSHORT;
while (nlist--)
{
x += list->xOff;
y += list->yOff;
n = list->len;
list++;
while (n--)
{
glyph = *glyphs++;
x1 = x - glyph->info.x;
if (x1 < MINSHORT)
{
x1 = MINSHORT;
}
y1 = y - glyph->info.y;
if (y1 < MINSHORT)
{
y1 = MINSHORT;
}
x2 = x1 + glyph->info.width;
if (x2 > MAXSHORT)
{
x2 = MAXSHORT;
}
y2 = y1 + glyph->info.height;
if (y2 > MAXSHORT)
{
y2 = MAXSHORT;
}
if (x1 < extents->x1)
{
extents->x1 = x1;
}
if (x2 > extents->x2)
{
extents->x2 = x2;
}
if (y1 < extents->y1)
{
extents->y1 = y1;
}
if (y2 > extents->y2)
{
extents->y2 = y2;
}
x += glyph->info.xOff;
y += glyph->info.yOff;
}
}
}
/******************************************************************************/
static void
rdpGlypht(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
int nlists, GlyphListPtr lists, GlyphPtr* glyphs)
{
BoxRec extents;
GlyphExtents(nlists, lists, glyphs, &extents);
if ((extents.x2 <= extents.x1) || (extents.y2 <= extents.y1))
{
return;
}
rdpGlyphu(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlists, lists,
glyphs, &extents);
}
/******************************************************************************/
/* make sure no glyph is too big */
/* returns boolean */
static int
rdpGlyphCheck(int nlist, GlyphListPtr list, GlyphPtr* glyphs)
{
int n;
GlyphPtr glyph;
while (nlist--)
{
n = list->len;
list++;
while (n--)
{
glyph = *glyphs++;
if ((glyph->info.width * glyph->info.height) > 8192)
{
LLOGLN(10, ("rdpGlyphCheck: too big"));
return 0;
}
}
}
return 1;
}
/******************************************************************************/
void
rdpGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc, INT16 ySrc, int nlists, GlyphListPtr lists,
GlyphPtr* glyphs)
{
PictureScreenPtr ps;
LLOGLN(10, ("rdpGlyphs: op %d xSrc %d ySrc %d maskFormat %p",
op, xSrc, ySrc, maskFormat));
if (g_do_glyph_cache && rdpGlyphCheck(nlists, lists, glyphs))
{
g_doing_font = 2;
rdpGlypht(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlists, lists, glyphs);
ps = GetPictureScreen(g_pScreen);
ps->Glyphs = g_rdpScreen.Glyphs;
ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc,
nlists, lists, glyphs);
ps->Glyphs = rdpGlyphs;
}
else
{
g_doing_font = 1;
rdpup_set_hints(1, 1);
ps = GetPictureScreen(g_pScreen);
ps->Glyphs = g_rdpScreen.Glyphs;
ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc,
nlists, lists, glyphs);
ps->Glyphs = rdpGlyphs;
rdpup_set_hints(0, 1);
}
g_doing_font = 0;
LLOGLN(10, ("rdpGlyphs: out"));
}
/******************************************************************************/
int
rdpGlyphInit(void)
{
memset(&g_font_cache, 0, sizeof(g_font_cache));
return 0;
}

@ -0,0 +1,64 @@
/*
Copyright 2012-2013 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __RDPGLYPH_H
#define __RDPGLYPH_H
struct rdp_font_char
{
int offset; /* x */
int baseline; /* y */
int width; /* cx */
int height; /* cy */
int incby;
int bpp;
char* data;
int data_bytes;
};
struct rdp_text
{
RegionPtr reg;
int font;
int x;
int y;
int flags;
int mixmode;
char data[256];
int data_bytes;
struct rdp_font_char* chars[256];
int num_chars;
struct rdp_text* next;
};
int
delete_rdp_text(struct rdp_text* rtext);
int
rdp_text_chars_to_data(struct rdp_text* rtext);
void
rdpGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
int nlists, GlyphListPtr lists, GlyphPtr* glyphs);
int
rdpGlyphInit(void);
#endif

@ -64,6 +64,7 @@ static int g_tab_down = 0;
/* this is toggled every time num lock key is released, not like the /* this is toggled every time num lock key is released, not like the
above *_down vars */ above *_down vars */
static int g_scroll_lock_down = 0; static int g_scroll_lock_down = 0;
static OsTimerPtr g_kbtimer = 0;
static OsTimerPtr g_timer = 0; static OsTimerPtr g_timer = 0;
static int g_x = 0; static int g_x = 0;
@ -326,11 +327,58 @@ rdpBell(int volume, DeviceIntPtr pDev, pointer ctrl, int cls)
ErrorF("rdpBell:\n"); ErrorF("rdpBell:\n");
} }
/******************************************************************************/
static CARD32
rdpInDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg)
{
//ErrorF("rdpInDeferredUpdateCallback:\n");
/* our keyboard device */
XkbSetRepeatKeys(g_keyboard, -1, AutoRepeatModeOff);
/* the main one for the server */
XkbSetRepeatKeys(inputInfo.keyboard, -1, AutoRepeatModeOff);
return 0;
}
/******************************************************************************/ /******************************************************************************/
void void
rdpChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl *ctrl) rdpChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
{ {
XkbControlsPtr ctrls;
ErrorF("rdpChangeKeyboardControl:\n"); ErrorF("rdpChangeKeyboardControl:\n");
ctrls = 0;
if (pDev != 0)
{
if (pDev->key != 0)
{
if (pDev->key->xkbInfo != 0)
{
if (pDev->key->xkbInfo->desc != 0)
{
if (pDev->key->xkbInfo->desc->ctrls != 0)
{
ctrls = pDev->key->xkbInfo->desc->ctrls;
}
}
}
}
}
if (ctrls != 0)
{
if (ctrls->enabled_ctrls & XkbRepeatKeysMask)
{
//ErrorF("rdpChangeKeyboardControl: autoRepeat on\n");
/* schedual to turn off the autorepeat after 100 ms so any app
* polling it will be happy it's on */
g_kbtimer = TimerSet(g_kbtimer, 0, 100, rdpInDeferredUpdateCallback, 0);\
}
else
{
//ErrorF("rdpChangeKeyboardControl: autoRepeat off\n");
}
}
} }
/******************************************************************************/ /******************************************************************************/
@ -419,9 +467,9 @@ rdpMouseCtrl(DeviceIntPtr pDevice, PtrCtrl *pCtrl)
int int
rdpMouseProc(DeviceIntPtr pDevice, int onoff) rdpMouseProc(DeviceIntPtr pDevice, int onoff)
{ {
BYTE map[6]; BYTE map[8];
DevicePtr pDev; DevicePtr pDev;
Atom btn_labels[6]; Atom btn_labels[8];
Atom axes_labels[2]; Atom axes_labels[2];
DEBUG_OUT_INPUT(("rdpMouseProc\n")); DEBUG_OUT_INPUT(("rdpMouseProc\n"));
@ -437,17 +485,21 @@ rdpMouseProc(DeviceIntPtr pDevice, int onoff)
map[3] = 3; map[3] = 3;
map[4] = 4; map[4] = 4;
map[5] = 5; map[5] = 5;
map[6] = 6;
map[7] = 7;
btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP); btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN); btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
InitPointerDeviceStruct(pDev, map, 5, btn_labels, rdpMouseCtrl, InitPointerDeviceStruct(pDev, map, 7, btn_labels, rdpMouseCtrl,
GetMotionHistorySize(), 2, axes_labels); GetMotionHistorySize(), 2, axes_labels);
break; break;
@ -961,9 +1013,13 @@ KbdAddEvent(int down, int param1, int param2, int param3, int param4)
if (x_scancode > 0) if (x_scancode > 0)
{ {
/* left or right shift */
if ((rdp_scancode == 42) || (rdp_scancode == 54))
{
g_shift_down = down ? x_scancode : 0;
}
rdpEnqueueKey(type, x_scancode); rdpEnqueueKey(type, x_scancode);
} }
break; break;
case 56: /* left - right alt button */ case 56: /* left - right alt button */
@ -977,6 +1033,7 @@ KbdAddEvent(int down, int param1, int param2, int param3, int param4)
x_scancode = 64; /* left alt button */ x_scancode = 64; /* left alt button */
} }
g_alt_down = down ? x_scancode : 0;
rdpEnqueueKey(type, x_scancode); rdpEnqueueKey(type, x_scancode);
break; break;
@ -1110,6 +1167,14 @@ KbdAddEvent(int down, int param1, int param2, int param3, int param4)
rdpEnqueueKey(type, 117); rdpEnqueueKey(type, 117);
break; break;
case 89: /* left meta */
rdpEnqueueKey(type, 156);
break;
case 90: /* right meta */
rdpEnqueueKey(type, 156);
break;
default: default:
x_scancode = rdp_scancode + MIN_KEY_CODE; x_scancode = rdp_scancode + MIN_KEY_CODE;

@ -24,6 +24,7 @@ Sets up the functions
#include "rdp.h" #include "rdp.h"
#include "rdprandr.h" #include "rdprandr.h"
#include "rdpglyph.h"
#if 1 #if 1
#define DEBUG_OUT(arg) #define DEBUG_OUT(arg)
@ -46,7 +47,10 @@ DeviceIntPtr g_keyboard = 0;
int g_can_do_pix_to_pix = 0; int g_can_do_pix_to_pix = 0;
int g_do_dirty_os = 1; /* delay remoting off screen bitmaps */ int g_do_dirty_os = 1; /* delay remoting off screen bitmaps */
int g_do_dirty_ons = 1; /* delay remoting screen */ int g_do_dirty_ons = 0; /* delay remoting screen */
int g_do_glyph_cache = 0; /* rdpup.c may set this */
int g_do_alpha_glyphs = 1;
int g_do_composite = 0; /* rdpup.c may set this */
Bool g_wrapWindow = 1; Bool g_wrapWindow = 1;
Bool g_wrapPixmap = 1; Bool g_wrapPixmap = 1;
@ -60,6 +64,7 @@ int g_use_rail = 0;
int g_con_number = 0; /* increments for each connection */ int g_con_number = 0; /* increments for each connection */
WindowPtr g_invalidate_window = 0; WindowPtr g_invalidate_window = 0;
int g_doing_font = 0;
/* if true, use a unix domain socket instead of a tcp socket */ /* if true, use a unix domain socket instead of a tcp socket */
int g_use_uds = 0; int g_use_uds = 0;
@ -273,7 +278,8 @@ rdpScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
g_rdpScreen.sizeInBytes = g_rdpScreen.sizeInBytes =
(g_rdpScreen.paddedWidthInBytes * g_rdpScreen.height); (g_rdpScreen.paddedWidthInBytes * g_rdpScreen.height);
ErrorF("buffer size %d\n", g_rdpScreen.sizeInBytes); ErrorF("buffer size %d\n", g_rdpScreen.sizeInBytes);
g_rdpScreen.pfbMemory = (char *)g_malloc(2048 * 2048 * 4, 1); g_rdpScreen.pfbMemory = (char *)g_malloc(g_rdpScreen.sizeInBytes, 1);
g_rdpScreen.sizeInBytesAlloc = g_rdpScreen.sizeInBytes;
} }
if (g_rdpScreen.pfbMemory == 0) if (g_rdpScreen.pfbMemory == 0)
@ -397,6 +403,8 @@ rdpScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
if (ps) if (ps)
{ {
g_rdpScreen.CreatePicture = ps->CreatePicture;
g_rdpScreen.DestroyPicture = ps->DestroyPicture;
g_rdpScreen.Composite = ps->Composite; g_rdpScreen.Composite = ps->Composite;
g_rdpScreen.Glyphs = ps->Glyphs; g_rdpScreen.Glyphs = ps->Glyphs;
@ -410,6 +418,8 @@ rdpScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
if (ps) if (ps)
{ {
ps->CreatePicture = rdpCreatePicture;
ps->DestroyPicture = rdpDestroyPicture;
ps->Composite = rdpComposite; ps->Composite = rdpComposite;
ps->Glyphs = rdpGlyphs; ps->Glyphs = rdpGlyphs;
} }
@ -529,6 +539,8 @@ rdpScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
} }
rdpGlyphInit();
//rdpXvInit(pScreen); //rdpXvInit(pScreen);
ErrorF("rdpScreenInit: ret %d\n", ret); ErrorF("rdpScreenInit: ret %d\n", ret);

@ -27,6 +27,59 @@ the rest
Bool noFontCacheExtension = 1; Bool noFontCacheExtension = 1;
static int g_crc_seed = 0xffffffff;
static int g_crc_table[256] =
{
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
#define CRC_START(in_crc) (in_crc) = g_crc_seed
#define CRC_PASS(in_pixel, in_crc) \
(in_crc) = g_crc_table[((in_crc) ^ (in_pixel)) & 0xff] ^ ((in_crc) >> 8)
#define CRC_END(in_crc) (in_crc) = ((in_crc) ^ g_crc_seed)
/******************************************************************************/ /******************************************************************************/
/* print a time-stamped message to the log file (stderr). */ /* print a time-stamped message to the log file (stderr). */
void void
@ -599,3 +652,19 @@ RegionAroundSegs(RegionPtr reg, xSegment *segs, int nseg)
index++; index++;
} }
} }
/******************************************************************************/
int
get_crc(char* data, int data_bytes)
{
int crc;
int index;
CRC_START(crc);
for (index = 0; index < data_bytes; index++)
{
CRC_PASS(data[index], crc);
}
CRC_END(crc);
return crc;
}

@ -156,6 +156,13 @@ rdpRRScreenSetSize(ScreenPtr pScreen, CARD16 width, CARD16 height,
ErrorF(" resizing screenPixmap [%p] to %dx%d, currently at %dx%d\n", ErrorF(" resizing screenPixmap [%p] to %dx%d, currently at %dx%d\n",
(void *)screenPixmap, width, height, (void *)screenPixmap, width, height,
screenPixmap->drawable.width, screenPixmap->drawable.height); screenPixmap->drawable.width, screenPixmap->drawable.height);
if (g_rdpScreen.sizeInBytes > g_rdpScreen.sizeInBytesAlloc)
{
g_free(g_rdpScreen.pfbMemory);
g_rdpScreen.pfbMemory = (char*)g_malloc(g_rdpScreen.sizeInBytes, 1);
g_rdpScreen.sizeInBytesAlloc = g_rdpScreen.sizeInBytes;
ErrorF("new buffer size %d\n", g_rdpScreen.sizeInBytes);
}
pScreen->ModifyPixmapHeader(screenPixmap, width, height, pScreen->ModifyPixmapHeader(screenPixmap, width, height,
g_rdpScreen.depth, g_rdpScreen.bitsPerPixel, g_rdpScreen.depth, g_rdpScreen.bitsPerPixel,
g_rdpScreen.paddedWidthInBytes, g_rdpScreen.paddedWidthInBytes,

@ -21,6 +21,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h" #include "rdp.h"
#include "xrdp_rail.h" #include "xrdp_rail.h"
#include "rdpglyph.h"
#include <signal.h> #include <signal.h>
#include <sys/ipc.h> #include <sys/ipc.h>
@ -67,8 +68,10 @@ extern ScreenPtr g_pScreen; /* from rdpmain.c */
extern int g_Bpp; /* from rdpmain.c */ extern int g_Bpp; /* from rdpmain.c */
extern int g_Bpp_mask; /* from rdpmain.c */ extern int g_Bpp_mask; /* from rdpmain.c */
extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */ extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */
extern int g_do_glyph_cache; /* from rdpmain.c */
extern int g_can_do_pix_to_pix; /* from rdpmain.c */ extern int g_can_do_pix_to_pix; /* from rdpmain.c */
extern int g_use_rail; /* from rdpmain.c */ extern int g_use_rail; /* from rdpmain.c */
extern int g_do_composite; /* from rdpmain.c */
/* true is to use unix domain socket */ /* true is to use unix domain socket */
extern int g_use_uds; /* in rdpmain.c */ extern int g_use_uds; /* in rdpmain.c */
@ -189,6 +192,7 @@ rdpup_disconnect(void)
{ {
int index; int index;
LLOGLN(0, ("rdpup_disconnect:"));
if (g_do_kill_disconnected) if (g_do_kill_disconnected)
{ {
if (!g_disconnect_scheduled) if (!g_disconnect_scheduled)
@ -229,6 +233,8 @@ rdpup_disconnect(void)
g_free(g_os_bitmaps); g_free(g_os_bitmaps);
g_os_bitmaps = 0; g_os_bitmaps = 0;
g_use_rail = 0; g_use_rail = 0;
g_do_glyph_cache = 0;
g_do_composite = 0;
return 0; return 0;
} }
@ -471,12 +477,14 @@ rdpup_send(char *data, int len)
} }
else else
{ {
LLOGLN(0, ("rdpup_send: g_tcp_send failed(returned -1)"));
rdpup_disconnect(); rdpup_disconnect();
return 1; return 1;
} }
} }
else if (sent == 0) else if (sent == 0)
{ {
LLOGLN(0, ("rdpup_send: g_tcp_send failed(returned zero)"));
rdpup_disconnect(); rdpup_disconnect();
return 1; return 1;
} }
@ -527,6 +535,9 @@ rdpup_send_msg(struct stream *s)
static int static int
rdpup_send_pending(void) rdpup_send_pending(void)
{ {
int rv;
rv = 0;
if (g_connected && g_begin) if (g_connected && g_begin)
{ {
LLOGLN(10, ("end %d", g_count)); LLOGLN(10, ("end %d", g_count));
@ -534,12 +545,16 @@ rdpup_send_pending(void)
out_uint16_le(g_out_s, 4); out_uint16_le(g_out_s, 4);
g_count++; g_count++;
s_mark_end(g_out_s); s_mark_end(g_out_s);
rdpup_send_msg(g_out_s); if (rdpup_send_msg(g_out_s) != 0)
{
LLOGLN(0, ("rdpup_send_pending: rdpup_send_msg failed"));
rv = 1;
}
} }
g_count = 0; g_count = 0;
g_begin = 0; g_begin = 0;
return 0; return rv;
} }
/******************************************************************************/ /******************************************************************************/
@ -603,12 +618,14 @@ rdpup_recv(char *data, int len)
} }
else else
{ {
LLOGLN(0, ("rdpup_recv: g_tcp_recv failed(returned -1)"));
rdpup_disconnect(); rdpup_disconnect();
return 1; return 1;
} }
} }
else if (rcvd == 0) else if (rcvd == 0)
{ {
LLOGLN(0, ("rdpup_recv: g_tcp_recv failed(returned 0)"));
rdpup_disconnect(); rdpup_disconnect();
return 1; return 1;
} }
@ -872,6 +889,14 @@ rdpup_send_rail(void)
return 0; return 0;
} }
#define XR_BUTTON1 1
#define XR_BUTTON2 2
#define XR_BUTTON3 4
#define XR_BUTTON4 8
#define XR_BUTTON5 16
#define XR_BUTTON6 32
#define XR_BUTTON7 64
/******************************************************************************/ /******************************************************************************/
static int static int
rdpup_process_msg(struct stream *s) rdpup_process_msg(struct stream *s)
@ -920,44 +945,74 @@ rdpup_process_msg(struct stream *s)
g_cursor_y = l_bound_by(param2, 0, g_rdpScreen.height - 2); g_cursor_y = l_bound_by(param2, 0, g_rdpScreen.height - 2);
PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y);
break; break;
case 101: case 101: /* left button up */
g_button_mask = g_button_mask & (~1); g_button_mask = g_button_mask & (~XR_BUTTON1);
PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y);
break; break;
case 102: case 102: /* left button down */
g_button_mask = g_button_mask | 1; g_cursor_x = l_bound_by(param1, 0, g_rdpScreen.width - 2);
g_cursor_y = l_bound_by(param2, 0, g_rdpScreen.height - 2);
g_button_mask = g_button_mask | XR_BUTTON1;
PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y);
break; break;
case 103: case 103: /* right button up */
g_button_mask = g_button_mask & (~4); g_button_mask = g_button_mask & (~XR_BUTTON3);
PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y);
break; break;
case 104: case 104: /* right button down */
g_button_mask = g_button_mask | 4; g_cursor_x = l_bound_by(param1, 0, g_rdpScreen.width - 2);
g_cursor_y = l_bound_by(param2, 0, g_rdpScreen.height - 2);
g_button_mask = g_button_mask | XR_BUTTON3;
PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y);
break; break;
case 105: case 105: /* middle button down */
g_button_mask = g_button_mask & (~2); g_button_mask = g_button_mask & (~XR_BUTTON2);
PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y);
break; break;
case 106: case 106: /* middle button up */
g_button_mask = g_button_mask | 2; g_cursor_x = l_bound_by(param1, 0, g_rdpScreen.width - 2);
g_cursor_y = l_bound_by(param2, 0, g_rdpScreen.height - 2);
g_button_mask = g_button_mask | XR_BUTTON2;
PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y);
break; break;
case 107: case 107: /* button 4 up */
g_button_mask = g_button_mask & (~8); g_button_mask = g_button_mask & (~XR_BUTTON4);
PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y);
break; break;
case 108: case 108: /* button 4 down */
g_button_mask = g_button_mask | 8; g_cursor_x = l_bound_by(param1, 0, g_rdpScreen.width - 2);
g_cursor_y = l_bound_by(param2, 0, g_rdpScreen.height - 2);
g_button_mask = g_button_mask | XR_BUTTON4;
PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y);
break; break;
case 109: case 109: /* button 5 up */
g_button_mask = g_button_mask & (~16); g_button_mask = g_button_mask & (~XR_BUTTON5);
PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y);
break; break;
case 110: case 110: /* button 5 down */
g_button_mask = g_button_mask | 16; g_cursor_x = l_bound_by(param1, 0, g_rdpScreen.width - 2);
g_cursor_y = l_bound_by(param2, 0, g_rdpScreen.height - 2);
g_button_mask = g_button_mask | XR_BUTTON5;
PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y);
break;
case 111: /* button 6 up */
g_button_mask = g_button_mask & (~XR_BUTTON6);
PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y);
break;
case 112: /* button 6 down */
g_cursor_x = l_bound_by(param1, 0, g_rdpScreen.width - 2);
g_cursor_y = l_bound_by(param2, 0, g_rdpScreen.height - 2);
g_button_mask = g_button_mask | XR_BUTTON6;
PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y);
break;
case 113: /* button 7 up */
g_button_mask = g_button_mask & (~XR_BUTTON7);
PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y);
break;
case 114: /* button 7 down */
g_cursor_x = l_bound_by(param1, 0, g_rdpScreen.width - 2);
g_cursor_y = l_bound_by(param2, 0, g_rdpScreen.height - 2);
g_button_mask = g_button_mask | XR_BUTTON7;
PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y); PtrAddEvent(g_button_mask, g_cursor_x, g_cursor_y);
break; break;
case 200: case 200:
@ -1008,8 +1063,27 @@ rdpup_process_msg(struct stream *s)
if (g_rdpScreen.client_info.rail_support_level > 0) if (g_rdpScreen.client_info.rail_support_level > 0)
{ {
g_use_rail = 1; g_use_rail = 1;
#ifdef XRDP_WM_RDPUP
rdpup_send_rail(); rdpup_send_rail();
#endif
}
if (g_rdpScreen.client_info.orders[0x1b]) /* 27 NEG_GLYPH_INDEX_INDEX */
{
g_do_glyph_cache = 1;
}
if (g_rdpScreen.client_info.order_flags_ex & 0x100)
{
g_do_composite = 1;
}
if (g_do_glyph_cache)
{
LLOGLN(0, (" using glyph cache"));
} }
if (g_do_composite)
{
LLOGLN(0, (" using client composite"));
}
LLOGLN(10, ("order_flags_ex 0x%x", g_rdpScreen.client_info.order_flags_ex));
if (g_rdpScreen.client_info.offscreen_cache_entries == 2000) if (g_rdpScreen.client_info.offscreen_cache_entries == 2000)
{ {
LLOGLN(0, (" client can do offscreen to offscreen blits")); LLOGLN(0, (" client can do offscreen to offscreen blits"));
@ -1254,6 +1328,7 @@ rdpup_check(void)
g_sck_closed = 0; g_sck_closed = 0;
g_begin = 0; g_begin = 0;
g_con_number++; g_con_number++;
rdpGlyphInit();
AddEnabledDevice(g_sck); AddEnabledDevice(g_sck);
if (g_dis_timer != 0) if (g_dis_timer != 0)
@ -1341,6 +1416,9 @@ rdpup_end_update(void)
int int
rdpup_pre_check(int in_size) rdpup_pre_check(int in_size)
{ {
int rv;
rv = 0;
if (!g_begin) if (!g_begin)
{ {
rdpup_begin_update(); rdpup_begin_update();
@ -1349,13 +1427,17 @@ rdpup_pre_check(int in_size)
if ((g_out_s->p - g_out_s->data) > (g_out_s->size - (in_size + 20))) if ((g_out_s->p - g_out_s->data) > (g_out_s->size - (in_size + 20)))
{ {
s_mark_end(g_out_s); s_mark_end(g_out_s);
rdpup_send_msg(g_out_s); if (rdpup_send_msg(g_out_s) != 0)
{
LLOGLN(0, ("rdpup_pre_check: rdpup_send_msg failed"));
rv = 1;
}
g_count = 0; g_count = 0;
init_stream(g_out_s, 0); init_stream(g_out_s, 0);
s_push_layer(g_out_s, iso_hdr, 8); s_push_layer(g_out_s, iso_hdr, 8);
} }
return 0; return rv;
} }
/******************************************************************************/ /******************************************************************************/
@ -1579,6 +1661,25 @@ convert_pixels(void *src, void *dst, int num_pixels)
return 0; return 0;
} }
/******************************************************************************/
int
alpha_pixels(void* src, void* dst, int num_pixels)
{
unsigned int* src32;
unsigned char* dst8;
int index;
src32 = (unsigned int*)src;
dst8 = (unsigned char*)dst;
for (index = 0; index < num_pixels; index++)
{
*dst8 = (*src32) >> 24;
dst8++;
src32++;
}
return 0;
}
/******************************************************************************/ /******************************************************************************/
int int
rdpup_set_fgcolor(int fgcolor) rdpup_set_fgcolor(int fgcolor)
@ -1750,6 +1851,26 @@ rdpup_create_os_surface(int rdpindex, int width, int height)
return 0; return 0;
} }
/******************************************************************************/
int
rdpup_create_os_surface_bpp(int rdpindex, int width, int height, int bpp)
{
LLOGLN(10, ("rdpup_create_os_surface_bpp:"));
if (g_connected)
{
LLOGLN(10, (" width %d height %d bpp %d", width, height, bpp));
rdpup_pre_check(13);
out_uint16_le(g_out_s, 31);
out_uint16_le(g_out_s, 13);
g_count++;
out_uint32_le(g_out_s, rdpindex);
out_uint16_le(g_out_s, width);
out_uint16_le(g_out_s, height);
out_uint8(g_out_s, bpp);
}
return 0;
}
/******************************************************************************/ /******************************************************************************/
int int
rdpup_switch_os_surface(int rdpindex) rdpup_switch_os_surface(int rdpindex)
@ -2023,7 +2144,7 @@ rdpup_send_area(struct image_data *id, int x, int y, int w, int h)
} }
ly = y; ly = y;
while (ly < y + h) while ((ly < y + h) && g_connected)
{ {
lx = x; lx = x;
@ -2074,6 +2195,103 @@ rdpup_send_area(struct image_data *id, int x, int y, int w, int h)
} }
} }
/******************************************************************************/
/* split the bitmap up into 64 x 64 pixel areas */
void
rdpup_send_alpha_area(struct image_data* id, int x, int y, int w, int h)
{
char* s;
int i;
int lx;
int ly;
int lh;
int lw;
int size;
struct image_data lid;
LLOGLN(10, ("rdpup_send_alpha_area: id %p x %d y %d w %d h %d",
id, x, y, w, h));
if (id == 0)
{
rdpup_get_screen_image_rect(&lid);
id = &lid;
}
if (x >= id->width)
{
return;
}
if (y >= id->height)
{
return;
}
if (x < 0)
{
w += x;
x = 0;
}
if (y < 0)
{
h += y;
y = 0;
}
if (w <= 0)
{
return;
}
if (h <= 0)
{
return;
}
if (x + w > id->width)
{
w = id->width - x;
}
if (y + h > id->height)
{
h = id->height - y;
}
LLOGLN(10, ("%d", w * h));
if (g_connected && g_begin)
{
LLOGLN(10, (" rdpup_send_area"));
ly = y;
while ((ly < y + h) && g_connected)
{
lx = x;
while ((lx < x + w) && g_connected)
{
lw = MIN(64, (x + w) - lx);
lh = MIN(64, (y + h) - ly);
size = lw * lh + 25;
rdpup_pre_check(size);
out_uint16_le(g_out_s, 32); /* server_paint_rect_bpp */
out_uint16_le(g_out_s, size);
g_count++;
out_uint16_le(g_out_s, lx);
out_uint16_le(g_out_s, ly);
out_uint16_le(g_out_s, lw);
out_uint16_le(g_out_s, lh);
out_uint32_le(g_out_s, lw * lh);
for (i = 0; i < lh; i++)
{
s = (id->pixels +
((ly + i) * id->lineBytes) + (lx * g_Bpp));
alpha_pixels(s, g_out_s->p, lw);
g_out_s->p += lw;
}
out_uint16_le(g_out_s, lw);
out_uint16_le(g_out_s, lh);
out_uint16_le(g_out_s, 0);
out_uint16_le(g_out_s, 0);
out_uint8(g_out_s, 8);
lx += 64;
}
ly += 64;
}
}
}
/******************************************************************************/ /******************************************************************************/
void void
rdpup_paint_rect_os(int x, int y, int cx, int cy, rdpup_paint_rect_os(int x, int y, int cx, int cy,
@ -2165,7 +2383,7 @@ rdpup_create_window(WindowPtr pWindow, rdpWindowRec *priv)
out_uint32_le(g_out_s, style); /* style */ out_uint32_le(g_out_s, style); /* style */
out_uint32_le(g_out_s, ext_style); /* extended_style */ out_uint32_le(g_out_s, ext_style); /* extended_style */
flags |= WINDOW_ORDER_FIELD_STYLE; flags |= WINDOW_ORDER_FIELD_STYLE;
out_uint32_le(g_out_s, 0); /* show_state */ out_uint32_le(g_out_s, 0x05); /* show_state */
flags |= WINDOW_ORDER_FIELD_SHOW; flags |= WINDOW_ORDER_FIELD_SHOW;
out_uint16_le(g_out_s, title_bytes); /* title_info */ out_uint16_le(g_out_s, title_bytes); /* title_info */
out_uint8a(g_out_s, title, title_bytes); out_uint8a(g_out_s, title, title_bytes);
@ -2235,6 +2453,27 @@ rdpup_delete_window(WindowPtr pWindow, rdpWindowRec *priv)
} }
} }
/******************************************************************************/
void
rdpup_show_window(WindowPtr pWindow, rdpWindowRec* priv, int showState)
{
LLOGLN(10, ("rdpup_show_window: id 0x%8.8x state 0x%x", pWindow->drawable.id,
showState));
if (g_connected)
{
int flags = WINDOW_ORDER_TYPE_WINDOW;
rdpup_pre_check(16);
out_uint16_le(g_out_s, 27);
out_uint16_le(g_out_s, 16);
g_count++;
out_uint32_le(g_out_s, pWindow->drawable.id);
flags |= WINDOW_ORDER_FIELD_SHOW;
out_uint32_le(g_out_s, flags);
out_uint32_le(g_out_s, showState);
}
}
/******************************************************************************/ /******************************************************************************/
int int
rdpup_check_dirty(PixmapPtr pDirtyPixmap, rdpPixmapRec *pDirtyPriv) rdpup_check_dirty(PixmapPtr pDirtyPixmap, rdpPixmapRec *pDirtyPriv)
@ -2247,6 +2486,8 @@ rdpup_check_dirty(PixmapPtr pDirtyPixmap, rdpPixmapRec *pDirtyPriv)
xSegment *seg; xSegment *seg;
struct image_data id; struct image_data id;
struct rdp_draw_item *di; struct rdp_draw_item *di;
struct rdp_text* rtext;
struct rdp_text* trtext;
if (pDirtyPriv == 0) if (pDirtyPriv == 0)
{ {
@ -2349,6 +2590,37 @@ rdpup_check_dirty(PixmapPtr pDirtyPixmap, rdpPixmapRec *pDirtyPriv)
case RDI_SCRBLT: case RDI_SCRBLT:
LLOGLN(10, (" RDI_SCRBLT")); LLOGLN(10, (" RDI_SCRBLT"));
break; break;
case RDI_TEXT:
LLOGLN(10, (" RDI_TEXT"));
num_clips = REGION_NUM_RECTS(di->reg);
if (num_clips > 0)
{
LLOGLN(10, (" num_clips %d", num_clips));
rdpup_set_fgcolor(di->u.text.fg_color);
rdpup_set_opcode(di->u.text.opcode);
rtext = di->u.text.rtext;
trtext = rtext;
while (trtext != 0)
{
rdp_text_chars_to_data(trtext);
for (clip_index = num_clips - 1; clip_index >= 0; clip_index--)
{
box = REGION_RECTS(di->reg)[clip_index];
rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
LLOGLN(10, (" %d %d %d %d", box.x1, box.y1, box.x2, box.y2));
box = RegionExtents(trtext->reg)[0];
rdpup_draw_text(trtext->font, trtext->flags, trtext->mixmode,
box.x1, box.y1, box.x2, box.y2,
//box.x1, box.y1, box.x2, box.y2,
0, 0, 0, 0,
trtext->x, trtext->y, trtext->data, trtext->data_bytes);
}
trtext = trtext->next;
}
}
rdpup_reset_clip();
rdpup_set_opcode(GXcopy);
break;
} }
di = di->next; di = di->next;
@ -2484,3 +2756,171 @@ rdpup_check_dirty_screen(rdpPixmapRec *pDirtyPriv)
pDirtyPriv->is_dirty = 0; pDirtyPriv->is_dirty = 0;
return 0; return 0;
} }
/******************************************************************************/
int
rdpup_check_alpha_dirty(PixmapPtr pDirtyPixmap, rdpPixmapRec* pDirtyPriv)
{
struct image_data id;
LLOGLN(10, ("rdpup_check_alpha_dirty: width %d height %d",
pDirtyPixmap->drawable.width, pDirtyPixmap->drawable.height));
if (pDirtyPriv == 0)
{
return 0;
}
LLOGLN(10, ("rdpup_check_alpha_dirty: is_alpha_dirty_not %d",
pDirtyPriv->is_alpha_dirty_not));
if (pDirtyPriv->is_alpha_dirty_not)
{
return 0;
}
pDirtyPriv->is_alpha_dirty_not = 1;
rdpup_switch_os_surface(pDirtyPriv->rdpindex);
rdpup_get_pixmap_image_rect(pDirtyPixmap, &id);
rdpup_begin_update();
rdpup_send_alpha_area(&id, 0, 0, pDirtyPixmap->drawable.width,
pDirtyPixmap->drawable.height);
rdpup_end_update();
rdpup_switch_os_surface(-1);
return 0;
}
/******************************************************************************/
int
rdpup_add_char(int font, int charactor, short x, short y, int cx, int cy,
char* bmpdata, int bmpdata_bytes)
{
if (g_connected)
{
LLOGLN(10, (" rdpup_add_char"));
rdpup_pre_check(18 + bmpdata_bytes);
out_uint16_le(g_out_s, 28); /* add char */
out_uint16_le(g_out_s, 18 + bmpdata_bytes); /* size */
g_count++;
out_uint16_le(g_out_s, font);
out_uint16_le(g_out_s, charactor);
out_uint16_le(g_out_s, x);
out_uint16_le(g_out_s, y);
out_uint16_le(g_out_s, cx);
out_uint16_le(g_out_s, cy);
out_uint16_le(g_out_s, bmpdata_bytes);
out_uint8a(g_out_s, bmpdata, bmpdata_bytes);
}
return 0;
}
/******************************************************************************/
int
rdpup_add_char_alpha(int font, int charactor, short x, short y, int cx, int cy,
char* bmpdata, int bmpdata_bytes)
{
if (g_connected)
{
LLOGLN(10, (" rdpup_add_char_alpha"));
rdpup_pre_check(18 + bmpdata_bytes);
out_uint16_le(g_out_s, 29); /* add char alpha */
out_uint16_le(g_out_s, 18 + bmpdata_bytes); /* size */
g_count++;
out_uint16_le(g_out_s, font);
out_uint16_le(g_out_s, charactor);
out_uint16_le(g_out_s, x);
out_uint16_le(g_out_s, y);
out_uint16_le(g_out_s, cx);
out_uint16_le(g_out_s, cy);
out_uint16_le(g_out_s, bmpdata_bytes);
out_uint8a(g_out_s, bmpdata, bmpdata_bytes);
}
return 0;
}
/******************************************************************************/
int
rdpup_draw_text(int font, int flags, int mixmode,
short clip_left, short clip_top,
short clip_right, short clip_bottom,
short box_left, short box_top,
short box_right, short box_bottom, short x, short y,
char* data, int data_bytes)
{
if (g_connected)
{
LLOGLN(10, (" rdpup_draw_text"));
rdpup_pre_check(32 + data_bytes);
out_uint16_le(g_out_s, 30); /* draw text */
out_uint16_le(g_out_s, 32 + data_bytes); /* size */
g_count++;
out_uint16_le(g_out_s, font);
out_uint16_le(g_out_s, flags);
out_uint16_le(g_out_s, mixmode);
out_uint16_le(g_out_s, clip_left);
out_uint16_le(g_out_s, clip_top);
out_uint16_le(g_out_s, clip_right);
out_uint16_le(g_out_s, clip_bottom);
out_uint16_le(g_out_s, box_left);
out_uint16_le(g_out_s, box_top);
out_uint16_le(g_out_s, box_right);
out_uint16_le(g_out_s, box_bottom);
out_uint16_le(g_out_s, x);
out_uint16_le(g_out_s, y);
out_uint16_le(g_out_s, data_bytes);
out_uint8a(g_out_s, data, data_bytes);
}
return 0;
}
/******************************************************************************/
int
rdpup_composite(short srcidx, int srcformat, short srcwidth, CARD8 srcrepeat,
PictTransform* srctransform, CARD8 mskflags,
short mskidx, int mskformat, short mskwidth, CARD8 mskrepeat,
CARD8 op, short srcx, short srcy, short mskx, short msky,
short dstx, short dsty, short width, short height,
int dstformat)
{
if (g_connected)
{
LLOGLN(10, (" rdpup_composite"));
rdpup_pre_check(84);
out_uint16_le(g_out_s, 33);
out_uint16_le(g_out_s, 84); /* size */
g_count++;
out_uint16_le(g_out_s, srcidx);
out_uint32_le(g_out_s, srcformat);
out_uint16_le(g_out_s, srcwidth);
out_uint8(g_out_s, srcrepeat);
if (srctransform == 0)
{
out_uint8s(g_out_s, 10 * 4);
}
else
{
out_uint32_le(g_out_s, 1);
out_uint32_le(g_out_s, srctransform->matrix[0][0]);
out_uint32_le(g_out_s, srctransform->matrix[0][1]);
out_uint32_le(g_out_s, srctransform->matrix[0][2]);
out_uint32_le(g_out_s, srctransform->matrix[1][0]);
out_uint32_le(g_out_s, srctransform->matrix[1][1]);
out_uint32_le(g_out_s, srctransform->matrix[1][2]);
out_uint32_le(g_out_s, srctransform->matrix[2][0]);
out_uint32_le(g_out_s, srctransform->matrix[2][1]);
out_uint32_le(g_out_s, srctransform->matrix[2][2]);
}
out_uint8(g_out_s, mskflags);
out_uint16_le(g_out_s, mskidx);
out_uint32_le(g_out_s, mskformat);
out_uint16_le(g_out_s, mskwidth);
out_uint8(g_out_s, mskrepeat);
out_uint8(g_out_s, op);
out_uint16_le(g_out_s, srcx);
out_uint16_le(g_out_s, srcy);
out_uint16_le(g_out_s, mskx);
out_uint16_le(g_out_s, msky);
out_uint16_le(g_out_s, dstx);
out_uint16_le(g_out_s, dsty);
out_uint16_le(g_out_s, width);
out_uint16_le(g_out_s, height);
out_uint32_le(g_out_s, dstformat);
}
return 0;
}

@ -1,11 +1,20 @@
EXTRA_DIST = xrdp.ini ad24b.bmp ad256.bmp xrdp24b.bmp xrdp256.bmp sans-10.fv1 cursor0.cur cursor1.cur xrdp.h xrdp_types.h EXTRA_DIST = xrdp.ini ad24b.bmp ad256.bmp xrdp24b.bmp xrdp256.bmp sans-10.fv1 cursor0.cur cursor1.cur xrdp.h xrdp_types.h
EXTRA_INCLUDES =
EXTRA_LIBS =
EXTRA_FLAGS =
if XRDP_DEBUG if XRDP_DEBUG
EXTRA_DEFINES = -DXRDP_DEBUG EXTRA_DEFINES = -DXRDP_DEBUG
else else
EXTRA_DEFINES = -DXRDP_NODEBUG EXTRA_DEFINES = -DXRDP_NODEBUG
endif endif
if GOT_PREFIX
EXTRA_INCLUDES += -I$(prefix)/include
EXTRA_FLAGS += -L$(prefix)/lib -Wl,-rpath -Wl,$(prefix)/lib
endif
AM_CFLAGS = \ AM_CFLAGS = \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \ -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
-DXRDP_SBIN_PATH=\"${sbindir}\" \ -DXRDP_SBIN_PATH=\"${sbindir}\" \
@ -17,7 +26,8 @@ AM_CFLAGS = \
INCLUDES = \ INCLUDES = \
-I$(top_builddir) \ -I$(top_builddir) \
-I$(top_srcdir)/common \ -I$(top_srcdir)/common \
-I$(top_srcdir)/libxrdp -I$(top_srcdir)/libxrdp \
$(EXTRA_INCLUDES)
sbin_PROGRAMS = \ sbin_PROGRAMS = \
xrdp xrdp
@ -41,6 +51,9 @@ xrdp_LDADD = \
$(top_builddir)/common/libcommon.la \ $(top_builddir)/common/libcommon.la \
$(top_builddir)/libxrdp/libxrdp.la $(top_builddir)/libxrdp/libxrdp.la
xrdp_LDFLAGS = \
$(EXTRA_FLAGS)
xrdpsysconfdir=$(sysconfdir)/xrdp xrdpsysconfdir=$(sysconfdir)/xrdp
xrdpsysconf_DATA = \ xrdpsysconf_DATA = \

@ -283,6 +283,20 @@ xrdp_painter_copy(struct xrdp_painter* self,
int x, int y, int cx, int cy, int x, int y, int cx, int cy,
int srcx, int srcy); int srcx, int srcy);
int APP_CC int APP_CC
xrdp_painter_composite(struct xrdp_painter* self,
struct xrdp_bitmap* src,
int srcformat,
int srcwidth,
int srcrepeat,
struct xrdp_bitmap* dst,
int* srctransform,
int mskflags,
struct xrdp_bitmap* msk,
int mskformat, int mskwidth, int mskrepeat, int op,
int srcx, int srcy, int mskx, int msky,
int dstx, int dsty, int width, int height,
int dstformat);
int APP_CC
xrdp_painter_line(struct xrdp_painter* self, xrdp_painter_line(struct xrdp_painter* self,
struct xrdp_bitmap* bitmap, struct xrdp_bitmap* bitmap,
int x1, int y1, int x2, int y2); int x1, int y1, int x2, int y2);
@ -374,6 +388,16 @@ int DEFAULT_CC
server_paint_rect(struct xrdp_mod* mod, int x, int y, int cx, int cy, server_paint_rect(struct xrdp_mod* mod, int x, int y, int cx, int cy,
char* data, int width, int height, int srcx, int srcy); char* data, int width, int height, int srcx, int srcy);
int DEFAULT_CC int DEFAULT_CC
server_paint_rect_bpp(struct xrdp_mod* mod, int x, int y, int cx, int cy,
char* data, int width, int height, int srcx, int srcy,
int bpp);
int DEFAULT_CC
server_composite(struct xrdp_mod* mod, int srcidx, int srcformat, int srcwidth,
int srcrepeat, int* srctransform, int mskflags, int mskidx,
int mskformat, int mskwidth, int mskrepeat, int op,
int srcx, int srcy, int mskx, int msky,
int dstx, int dsty, int width, int height, int dstformat);
int DEFAULT_CC
server_set_pointer(struct xrdp_mod* mod, int x, int y, server_set_pointer(struct xrdp_mod* mod, int x, int y,
char* data, char* mask); char* data, char* mask);
int DEFAULT_CC int DEFAULT_CC
@ -434,6 +458,9 @@ int DEFAULT_CC
server_create_os_surface(struct xrdp_mod* mod, int id, server_create_os_surface(struct xrdp_mod* mod, int id,
int width, int height); int width, int height);
int DEFAULT_CC int DEFAULT_CC
server_create_os_surface_bpp(struct xrdp_mod* mod, int id,
int width, int height, int bpp);
int DEFAULT_CC
server_switch_os_surface(struct xrdp_mod* mod, int id); server_switch_os_surface(struct xrdp_mod* mod, int id);
int DEFAULT_CC int DEFAULT_CC
server_delete_os_surface(struct xrdp_mod* mod, int id); server_delete_os_surface(struct xrdp_mod* mod, int id);
@ -468,3 +495,7 @@ int DEFAULT_CC
server_monitored_desktop(struct xrdp_mod* mod, server_monitored_desktop(struct xrdp_mod* mod,
struct rail_monitored_desktop_order* mdo, struct rail_monitored_desktop_order* mdo,
int flags); int flags);
int DEFAULT_CC
server_add_char_alpha(struct xrdp_mod* mod, int font, int charactor,
int offset, int baseline,
int width, int height, char* data);

@ -21,6 +21,18 @@
#include "xrdp.h" #include "xrdp.h"
#include "log.h" #include "log.h"
#define LLOG_LEVEL 1
#define LLOGLN(_level, _args) \
do \
{ \
if (_level < LLOG_LEVEL) \
{ \
g_write("xrdp:xrdp_cache [%10.10u]: ", g_time3()); \
g_writeln _args ; \
} \
} \
while (0)
/*****************************************************************************/ /*****************************************************************************/
struct xrdp_cache *APP_CC struct xrdp_cache *APP_CC
xrdp_cache_create(struct xrdp_wm *owner, xrdp_cache_create(struct xrdp_wm *owner,
@ -53,7 +65,8 @@ xrdp_cache_create(struct xrdp_wm *owner,
self->bitmap_cache_version = client_info->bitmap_cache_version; self->bitmap_cache_version = client_info->bitmap_cache_version;
self->pointer_cache_entries = client_info->pointer_cache_entries; self->pointer_cache_entries = client_info->pointer_cache_entries;
self->xrdp_os_del_list = list_create(); self->xrdp_os_del_list = list_create();
LLOGLN(10, ("xrdp_cache_create: 0 %d 1 %d 2 %d",
self->cache1_entries, self->cache2_entries, self->cache3_entries));
return self; return self;
} }
@ -72,7 +85,7 @@ xrdp_cache_delete(struct xrdp_cache *self)
/* free all the cached bitmaps */ /* free all the cached bitmaps */
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
{ {
for (j = 0; j < 2000; j++) for (j = 0; j < XRDP_BITMAP_CACHE_ENTRIES; j++)
{ {
xrdp_bitmap_delete(self->bitmap_items[i][j].bitmap); xrdp_bitmap_delete(self->bitmap_items[i][j].bitmap);
} }
@ -111,7 +124,7 @@ xrdp_cache_reset(struct xrdp_cache *self,
/* free all the cached bitmaps */ /* free all the cached bitmaps */
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
{ {
for (j = 0; j < 2000; j++) for (j = 0; j < XRDP_BITMAP_CACHE_ENTRIES; j++)
{ {
xrdp_bitmap_delete(self->bitmap_items[i][j].bitmap); xrdp_bitmap_delete(self->bitmap_items[i][j].bitmap);
} }
@ -192,7 +205,7 @@ xrdp_cache_add_bitmap(struct xrdp_cache *self, struct xrdp_bitmap *bitmap,
#endif #endif
{ {
self->bitmap_items[i][j].stamp = self->bitmap_stamp; self->bitmap_items[i][j].stamp = self->bitmap_stamp;
DEBUG(("found bitmap at %d %d", i, j)); LLOGLN(10, ("found bitmap at %d %d", i, j));
xrdp_bitmap_delete(bitmap); xrdp_bitmap_delete(bitmap);
return MAKELONG(j, i); return MAKELONG(j, i);
} }
@ -211,7 +224,7 @@ xrdp_cache_add_bitmap(struct xrdp_cache *self, struct xrdp_bitmap *bitmap,
#endif #endif
{ {
self->bitmap_items[i][j].stamp = self->bitmap_stamp; self->bitmap_items[i][j].stamp = self->bitmap_stamp;
DEBUG(("found bitmap at %d %d", i, j)); LLOGLN(10, ("found bitmap at %d %d", i, j));
xrdp_bitmap_delete(bitmap); xrdp_bitmap_delete(bitmap);
return MAKELONG(j, i); return MAKELONG(j, i);
} }
@ -230,7 +243,7 @@ xrdp_cache_add_bitmap(struct xrdp_cache *self, struct xrdp_bitmap *bitmap,
#endif #endif
{ {
self->bitmap_items[i][j].stamp = self->bitmap_stamp; self->bitmap_items[i][j].stamp = self->bitmap_stamp;
DEBUG(("found bitmap at %d %d", i, j)); LLOGLN(10, ("found bitmap at %d %d", i, j));
xrdp_bitmap_delete(bitmap); xrdp_bitmap_delete(bitmap);
return MAKELONG(j, i); return MAKELONG(j, i);
} }
@ -238,7 +251,7 @@ xrdp_cache_add_bitmap(struct xrdp_cache *self, struct xrdp_bitmap *bitmap,
} }
else else
{ {
log_message(LOG_LEVEL_ERROR,"error in xrdp_cache_add_bitmap, too big(%d)", bmp_size); log_message(LOG_LEVEL_ERROR,"error in xrdp_cache_add_bitmap, too big(%d) bpp %d", bmp_size, bitmap->bpp);
} }
/* look for oldest */ /* look for oldest */
@ -289,7 +302,8 @@ xrdp_cache_add_bitmap(struct xrdp_cache *self, struct xrdp_bitmap *bitmap,
} }
} }
DEBUG(("adding bitmap at %d %d", cache_id, cache_idx)); LLOGLN(10, ("adding bitmap at %d %d ptr %p", cache_id, cache_idx,
self->bitmap_items[cache_id][cache_idx].bitmap));
/* set, send bitmap and return */ /* set, send bitmap and return */
xrdp_bitmap_delete(self->bitmap_items[cache_id][cache_idx].bitmap); xrdp_bitmap_delete(self->bitmap_items[cache_id][cache_idx].bitmap);
self->bitmap_items[cache_id][cache_idx].bitmap = bitmap; self->bitmap_items[cache_id][cache_idx].bitmap = bitmap;

@ -413,6 +413,10 @@ xrdp_mm_setup_mod1(struct xrdp_mm *self)
self->mod->server_notify_new_update = server_notify_new_update; self->mod->server_notify_new_update = server_notify_new_update;
self->mod->server_notify_delete = server_notify_delete; self->mod->server_notify_delete = server_notify_delete;
self->mod->server_monitored_desktop = server_monitored_desktop; self->mod->server_monitored_desktop = server_monitored_desktop;
self->mod->server_add_char_alpha = server_add_char_alpha;
self->mod->server_create_os_surface_bpp = server_create_os_surface_bpp;
self->mod->server_paint_rect_bpp = server_paint_rect_bpp;
self->mod->server_composite = server_composite;
} }
} }
@ -675,6 +679,265 @@ xrdp_mm_trans_process_channel_data(struct xrdp_mm *self, struct trans *trans)
return rv; return rv;
} }
/*****************************************************************************/
/* returns error
process rail create window order */
static int APP_CC
xrdp_mm_process_rail_create_window(struct xrdp_mm* self, struct stream* s)
{
int flags;
int window_id;
int title_bytes;
int index;
int bytes;
int rv;
struct rail_window_state_order rwso;
g_memset(&rwso, 0, sizeof(rwso));
in_uint32_le(s, window_id);
g_writeln("xrdp_mm_process_rail_create_window: 0x%8.8x", window_id);
in_uint32_le(s, rwso.owner_window_id);
in_uint32_le(s, rwso.style);
in_uint32_le(s, rwso.extended_style);
in_uint32_le(s, rwso.show_state);
in_uint16_le(s, title_bytes);
if (title_bytes > 0)
{
rwso.title_info = g_malloc(title_bytes + 1, 0);
in_uint8a(s, rwso.title_info, title_bytes);
rwso.title_info[title_bytes] = 0;
}
in_uint32_le(s, rwso.client_offset_x);
in_uint32_le(s, rwso.client_offset_y);
in_uint32_le(s, rwso.client_area_width);
in_uint32_le(s, rwso.client_area_height);
in_uint32_le(s, rwso.rp_content);
in_uint32_le(s, rwso.root_parent_handle);
in_uint32_le(s, rwso.window_offset_x);
in_uint32_le(s, rwso.window_offset_y);
in_uint32_le(s, rwso.window_client_delta_x);
in_uint32_le(s, rwso.window_client_delta_y);
in_uint32_le(s, rwso.window_width);
in_uint32_le(s, rwso.window_height);
in_uint16_le(s, rwso.num_window_rects);
if (rwso.num_window_rects > 0)
{
bytes = sizeof(struct rail_window_rect) * rwso.num_window_rects;
rwso.window_rects = (struct rail_window_rect*)g_malloc(bytes, 0);
for (index = 0; index < rwso.num_window_rects; index++)
{
in_uint16_le(s, rwso.window_rects[index].left);
in_uint16_le(s, rwso.window_rects[index].top);
in_uint16_le(s, rwso.window_rects[index].right);
in_uint16_le(s, rwso.window_rects[index].bottom);
}
}
in_uint32_le(s, rwso.visible_offset_x);
in_uint32_le(s, rwso.visible_offset_y);
in_uint16_le(s, rwso.num_visibility_rects);
if (rwso.num_visibility_rects > 0)
{
bytes = sizeof(struct rail_window_rect) * rwso.num_visibility_rects;
rwso.visibility_rects = (struct rail_window_rect*)g_malloc(bytes, 0);
for (index = 0; index < rwso.num_visibility_rects; index++)
{
in_uint16_le(s, rwso.visibility_rects[index].left);
in_uint16_le(s, rwso.visibility_rects[index].top);
in_uint16_le(s, rwso.visibility_rects[index].right);
in_uint16_le(s, rwso.visibility_rects[index].bottom);
}
}
in_uint32_le(s, flags);
rv = libxrdp_orders_init(self->wm->session);
rv = libxrdp_window_new_update(self->wm->session, window_id, &rwso, flags);
rv = libxrdp_orders_send(self->wm->session);
g_free(rwso.title_info);
g_free(rwso.window_rects);
g_free(rwso.visibility_rects);
return rv;
}
/*****************************************************************************/
/* returns error
process rail configure window order */
static int APP_CC
xrdp_mm_process_rail_configure_window(struct xrdp_mm* self, struct stream* s)
{
int flags;
int window_id;
int index;
int bytes;
int rv;
struct rail_window_state_order rwso;
g_memset(&rwso, 0, sizeof(rwso));
in_uint32_le(s, window_id);
g_writeln("xrdp_mm_process_rail_configure_window: 0x%8.8x", window_id);
in_uint32_le(s, rwso.client_offset_x);
in_uint32_le(s, rwso.client_offset_y);
in_uint32_le(s, rwso.client_area_width);
in_uint32_le(s, rwso.client_area_height);
in_uint32_le(s, rwso.rp_content);
in_uint32_le(s, rwso.root_parent_handle);
in_uint32_le(s, rwso.window_offset_x);
in_uint32_le(s, rwso.window_offset_y);
in_uint32_le(s, rwso.window_client_delta_x);
in_uint32_le(s, rwso.window_client_delta_y);
in_uint32_le(s, rwso.window_width);
in_uint32_le(s, rwso.window_height);
in_uint16_le(s, rwso.num_window_rects);
if (rwso.num_window_rects > 0)
{
bytes = sizeof(struct rail_window_rect) * rwso.num_window_rects;
rwso.window_rects = (struct rail_window_rect*)g_malloc(bytes, 0);
for (index = 0; index < rwso.num_window_rects; index++)
{
in_uint16_le(s, rwso.window_rects[index].left);
in_uint16_le(s, rwso.window_rects[index].top);
in_uint16_le(s, rwso.window_rects[index].right);
in_uint16_le(s, rwso.window_rects[index].bottom);
}
}
in_uint32_le(s, rwso.visible_offset_x);
in_uint32_le(s, rwso.visible_offset_y);
in_uint16_le(s, rwso.num_visibility_rects);
if (rwso.num_visibility_rects > 0)
{
bytes = sizeof(struct rail_window_rect) * rwso.num_visibility_rects;
rwso.visibility_rects = (struct rail_window_rect*)g_malloc(bytes, 0);
for (index = 0; index < rwso.num_visibility_rects; index++)
{
in_uint16_le(s, rwso.visibility_rects[index].left);
in_uint16_le(s, rwso.visibility_rects[index].top);
in_uint16_le(s, rwso.visibility_rects[index].right);
in_uint16_le(s, rwso.visibility_rects[index].bottom);
}
}
in_uint32_le(s, flags);
rv = libxrdp_orders_init(self->wm->session);
rv = libxrdp_window_new_update(self->wm->session, window_id, &rwso, flags);
rv = libxrdp_orders_send(self->wm->session);
g_free(rwso.window_rects);
g_free(rwso.visibility_rects);
return rv;
}
/*****************************************************************************/
/* returns error
process rail destroy window order */
static int APP_CC
xrdp_mm_process_rail_destroy_window(struct xrdp_mm* self, struct stream* s)
{
int window_id;
int rv;
in_uint32_le(s, window_id);
g_writeln("xrdp_mm_process_rail_destroy_window 0x%8.8x", window_id);
rv = libxrdp_orders_init(self->wm->session);
rv = libxrdp_window_delete(self->wm->session, window_id);
rv = libxrdp_orders_send(self->wm->session);
return rv;
}
/*****************************************************************************/
/* returns error
process rail update window (show state) order */
static int APP_CC
xrdp_mm_process_rail_show_window(struct xrdp_mm* self, struct stream* s)
{
int window_id;
int rv;
int flags;
struct rail_window_state_order rwso;
g_memset(&rwso, 0, sizeof(rwso));
in_uint32_le(s, window_id);
in_uint32_le(s, flags);
in_uint32_le(s, rwso.show_state);
g_writeln("xrdp_mm_process_rail_show_window 0x%8.8x %x", window_id,
rwso.show_state);
rv = libxrdp_orders_init(self->wm->session);
rv = libxrdp_window_new_update(self->wm->session, window_id, &rwso, flags);
rv = libxrdp_orders_send(self->wm->session);
return rv;
}
/*****************************************************************************/
/* returns error
process rail update window (title) order */
static int APP_CC
xrdp_mm_process_rail_update_window_text(struct xrdp_mm* self, struct stream* s)
{
int size;
int flags;
int rv = 0;
int window_id;
struct rail_window_state_order rwso;
g_writeln("xrdp_mm_process_rail_update_window_text:");
in_uint32_le(s, window_id);
in_uint32_le(s, flags);
g_writeln(" update window title info: 0x%8.8x", window_id);
g_memset(&rwso, 0, sizeof(rwso));
in_uint32_le(s, size); /* title size */
rwso.title_info = g_malloc(size + 1, 0);
in_uint8a(s, rwso.title_info, size);
rwso.title_info[size] = 0;
g_writeln(" set window title %s size %d 0x%8.8x", rwso.title_info, size, flags);
rv = libxrdp_orders_init(self->wm->session);
rv = libxrdp_window_new_update(self->wm->session, window_id, &rwso, flags);
rv = libxrdp_orders_send(self->wm->session);
g_writeln(" set window title %s %d", rwso.title_info, rv);
g_free(rwso.title_info);
return rv;
}
/*****************************************************************************/
/* returns error
process alternate secondary drawing orders for rail channel */
static int APP_CC
xrdp_mm_process_rail_drawing_orders(struct xrdp_mm* self, struct trans* trans)
{
struct stream* s;
int order_type;
int rv = 0;
s = trans_get_in_s(trans);
if (s == 0)
{
return 1;
}
in_uint32_le(s, order_type);
switch(order_type)
{
case 2: /* create_window */
xrdp_mm_process_rail_create_window(self, s);
break;
case 4: /* destroy_window */
xrdp_mm_process_rail_destroy_window(self, s);
break;
case 6: /* show_window */
rv = xrdp_mm_process_rail_show_window(self, s);
break;
case 8: /* update title info */
rv = xrdp_mm_process_rail_update_window_text(self, s);
break;
default:
break;
}
return rv;
}
/*****************************************************************************/ /*****************************************************************************/
/* returns error /* returns error
process a message for the channel handler */ process a message for the channel handler */
@ -708,6 +971,9 @@ xrdp_mm_chan_process_msg(struct xrdp_mm *self, struct trans *trans,
case 8: /* channel data */ case 8: /* channel data */
rv = xrdp_mm_trans_process_channel_data(self, trans); rv = xrdp_mm_trans_process_channel_data(self, trans);
break; break;
case 10: /* rail alternate secondary drawing orders */
rv = xrdp_mm_process_rail_drawing_orders(self, trans);
break;
default: default:
log_message(LOG_LEVEL_ERROR,"xrdp_mm_chan_process_msg: unknown id %d", id); log_message(LOG_LEVEL_ERROR,"xrdp_mm_chan_process_msg: unknown id %d", id);
break; break;
@ -793,7 +1059,7 @@ xrdp_mm_connect_chansrv(struct xrdp_mm *self, char *ip, char *port)
self->usechansrv = 1; self->usechansrv = 1;
/* connect channel redir */ /* connect channel redir */
if ((ip == 0) || (g_strcmp(ip, "127.0.0.1") == 0) || (ip[0] == 0)) if ((g_strcmp(ip, "127.0.0.1") == 0) || (ip[0] == 0))
{ {
/* unix socket */ /* unix socket */
self->chan_trans = trans_create(TRANS_MODE_UNIX, 8192, 8192); self->chan_trans = trans_create(TRANS_MODE_UNIX, 8192, 8192);
@ -1797,6 +2063,79 @@ server_paint_rect(struct xrdp_mod *mod, int x, int y, int cx, int cy,
return 0; return 0;
} }
/*****************************************************************************/
int DEFAULT_CC
server_paint_rect_bpp(struct xrdp_mod* mod, int x, int y, int cx, int cy,
char* data, int width, int height, int srcx, int srcy,
int bpp)
{
struct xrdp_wm* wm;
struct xrdp_bitmap* b;
struct xrdp_painter* p;
p = (struct xrdp_painter*)(mod->painter);
if (p == 0)
{
return 0;
}
wm = (struct xrdp_wm*)(mod->wm);
b = xrdp_bitmap_create_with_data(width, height, bpp, data, wm);
xrdp_painter_copy(p, b, wm->target_surface, x, y, cx, cy, srcx, srcy);
xrdp_bitmap_delete(b);
return 0;
}
/*****************************************************************************/
int DEFAULT_CC
server_composite(struct xrdp_mod* mod, int srcidx, int srcformat,
int srcwidth, int srcrepeat, int* srctransform,
int mskflags, int mskidx, int mskformat, int mskwidth,
int mskrepeat, int op, int srcx, int srcy,
int mskx, int msky, int dstx, int dsty,
int width, int height, int dstformat)
{
struct xrdp_wm* wm;
struct xrdp_bitmap* b;
struct xrdp_bitmap* msk;
struct xrdp_painter* p;
struct xrdp_os_bitmap_item* bi;
p = (struct xrdp_painter*)(mod->painter);
if (p == 0)
{
return 0;
}
wm = (struct xrdp_wm*)(mod->wm);
b = 0;
msk = 0;
bi = xrdp_cache_get_os_bitmap(wm->cache, srcidx);
if (bi != 0)
{
b = bi->bitmap;
}
if (mskflags & 1)
{
bi = xrdp_cache_get_os_bitmap(wm->cache, mskidx);
if (bi != 0)
{
msk = bi->bitmap;
}
}
if (b != 0)
{
xrdp_painter_composite(p, b, srcformat, srcwidth, srcrepeat,
wm->target_surface, srctransform,
mskflags, msk, mskformat, mskwidth, mskrepeat,
op, srcx, srcy, mskx, msky, dstx, dsty,
width, height, dstformat);
}
else
{
g_writeln("server_composite: error finding id %d or %d", srcidx, mskidx);
}
return 0;
}
/*****************************************************************************/ /*****************************************************************************/
int DEFAULT_CC int DEFAULT_CC
server_set_pointer(struct xrdp_mod *mod, int x, int y, server_set_pointer(struct xrdp_mod *mod, int x, int y,
@ -2033,6 +2372,7 @@ server_add_char(struct xrdp_mod *mod, int font, int charactor,
fi.height = height; fi.height = height;
fi.incby = 0; fi.incby = 0;
fi.data = data; fi.data = data;
fi.bpp = 1;
return libxrdp_orders_send_font(((struct xrdp_wm *)mod->wm)->session, return libxrdp_orders_send_font(((struct xrdp_wm *)mod->wm)->session,
&fi, font, charactor); &fi, font, charactor);
} }
@ -2411,6 +2751,29 @@ server_create_os_surface(struct xrdp_mod *mod, int rdpindex,
return 0; return 0;
} }
/*****************************************************************************/
int DEFAULT_CC
server_create_os_surface_bpp(struct xrdp_mod* mod, int rdpindex,
int width, int height, int bpp)
{
struct xrdp_wm* wm;
struct xrdp_bitmap* bitmap;
int error;
wm = (struct xrdp_wm*)(mod->wm);
bitmap = xrdp_bitmap_create(width, height, bpp,
WND_TYPE_OFFSCREEN, wm);
error = xrdp_cache_add_os_bitmap(wm->cache, bitmap, rdpindex);
if (error != 0)
{
g_writeln("server_create_os_surface_bpp: xrdp_cache_add_os_bitmap failed");
return 1;
}
bitmap->item_index = rdpindex;
bitmap->id = rdpindex;
return 0;
}
/*****************************************************************************/ /*****************************************************************************/
int DEFAULT_CC int DEFAULT_CC
server_switch_os_surface(struct xrdp_mod *mod, int rdpindex) server_switch_os_surface(struct xrdp_mod *mod, int rdpindex)
@ -2630,3 +2993,23 @@ server_monitored_desktop(struct xrdp_mod *mod,
wm = (struct xrdp_wm *)(mod->wm); wm = (struct xrdp_wm *)(mod->wm);
return libxrdp_monitored_desktop(wm->session, mdo, flags); return libxrdp_monitored_desktop(wm->session, mdo, flags);
} }
/*****************************************************************************/
int DEFAULT_CC
server_add_char_alpha(struct xrdp_mod* mod, int font, int charactor,
int offset, int baseline,
int width, int height, char* data)
{
struct xrdp_font_char fi;
fi.offset = offset;
fi.baseline = baseline;
fi.width = width;
fi.height = height;
fi.incby = 0;
fi.data = data;
fi.bpp = 8;
return libxrdp_orders_send_font(((struct xrdp_wm*)mod->wm)->session,
&fi, font, charactor);
}

@ -849,7 +849,7 @@ xrdp_painter_copy(struct xrdp_painter *self,
{ {
w = MIN(64, ((srcx + cx) - i)); w = MIN(64, ((srcx + cx) - i));
h = MIN(64, ((srcy + cy) - j)); h = MIN(64, ((srcy + cy) - j));
b = xrdp_bitmap_create(w, h, self->wm->screen->bpp, 0, self->wm); b = xrdp_bitmap_create(w, h, src->bpp, 0, self->wm);
xrdp_bitmap_copy_box_with_crc(src, b, i, j, w, h); xrdp_bitmap_copy_box_with_crc(src, b, i, j, w, h);
bitmap_id = xrdp_cache_add_bitmap(self->wm->cache, b, self->wm->hints); bitmap_id = xrdp_cache_add_bitmap(self->wm->cache, b, self->wm->hints);
cache_id = HIWORD(bitmap_id); cache_id = HIWORD(bitmap_id);
@ -887,6 +887,86 @@ xrdp_painter_copy(struct xrdp_painter *self,
return 0; return 0;
} }
/*****************************************************************************/
int APP_CC
xrdp_painter_composite(struct xrdp_painter* self,
struct xrdp_bitmap* src,
int srcformat,
int srcwidth,
int srcrepeat,
struct xrdp_bitmap* dst,
int* srctransform,
int mskflags,
struct xrdp_bitmap* msk,
int mskformat, int mskwidth, int mskrepeat, int op,
int srcx, int srcy, int mskx, int msky,
int dstx, int dsty, int width, int height, int dstformat)
{
struct xrdp_rect clip_rect;
struct xrdp_rect draw_rect;
struct xrdp_rect rect1;
struct xrdp_rect rect2;
struct xrdp_region* region;
int k;
int dx;
int dy;
int palette_id;
int cache_srcidx;
int cache_mskidx;
if (self == 0 || src == 0 || dst == 0)
{
return 0;
}
/* todo data */
if (dst->type == WND_TYPE_BITMAP)
{
return 0;
}
if (src->type == WND_TYPE_OFFSCREEN)
{
xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy);
region = xrdp_region_create(self->wm);
xrdp_region_add_rect(region, &clip_rect);
dstx += dx;
dsty += dy;
palette_id = 0;
cache_srcidx = src->item_index;
cache_mskidx = -1;
if (mskflags & 1)
{
if (msk != 0)
{
cache_mskidx = msk->item_index; // todo
}
}
k = 0;
while (xrdp_region_get_rect(region, k, &rect1) == 0)
{
if (rect_intersect(&rect1, &clip_rect, &rect2))
{
MAKERECT(rect1, dstx, dsty, width, height);
if (rect_intersect(&rect2, &rect1, &draw_rect))
{
libxrdp_orders_composite_blt(self->session, cache_srcidx, srcformat, srcwidth,
srcrepeat, srctransform, mskflags, cache_mskidx,
mskformat, mskwidth, mskrepeat, op, srcx, srcy,
mskx, msky, dstx, dsty, width, height, dstformat,
&draw_rect);
}
}
k++;
}
xrdp_region_delete(region);
}
return 0;
}
/*****************************************************************************/ /*****************************************************************************/
int APP_CC int APP_CC
xrdp_painter_line(struct xrdp_painter *self, xrdp_painter_line(struct xrdp_painter *self,

@ -22,6 +22,7 @@
#define LOG_WINDOW_CHAR_PER_LINE 60 #define LOG_WINDOW_CHAR_PER_LINE 60
#include "xrdp_rail.h" #include "xrdp_rail.h"
#include "xrdp_constants.h"
#define MAX_NR_CHANNELS 16 #define MAX_NR_CHANNELS 16
#define MAX_CHANNEL_NAME 16 #define MAX_CHANNEL_NAME 16
@ -51,8 +52,10 @@ struct xrdp_mod
int (*server_screen_blt)(struct xrdp_mod* v, int x, int y, int cx, int cy, int (*server_screen_blt)(struct xrdp_mod* v, int x, int y, int cx, int cy,
int srcx, int srcy); int srcx, int srcy);
int (*server_paint_rect)(struct xrdp_mod* v, int x, int y, int cx, int cy, int (*server_paint_rect)(struct xrdp_mod* v, int x, int y, int cx, int cy,
char* data, int width, int height, int srcx, int srcy); char* data, int width, int height,
int (*server_set_pointer)(struct xrdp_mod* v, int x, int y, char* data, char* mask); int srcx, int srcy);
int (*server_set_pointer)(struct xrdp_mod* v, int x, int y,
char* data, char* mask);
int (*server_palette)(struct xrdp_mod* v, int* palette); int (*server_palette)(struct xrdp_mod* v, int* palette);
int (*server_msg)(struct xrdp_mod* v, char* msg, int code); int (*server_msg)(struct xrdp_mod* v, char* msg, int code);
int (*server_is_term)(struct xrdp_mod* v); int (*server_is_term)(struct xrdp_mod* v);
@ -117,8 +120,23 @@ struct xrdp_mod
int flags); int flags);
int (*server_set_pointer_ex)(struct xrdp_mod* v, int x, int y, char* data, int (*server_set_pointer_ex)(struct xrdp_mod* v, int x, int y, char* data,
char* mask, int bpp); char* mask, int bpp);
int (*server_add_char_alpha)(struct xrdp_mod* mod, int font, int charactor,
int offset, int baseline,
int width, int height, char* data);
long server_dumby[100 - 38]; /* align, 100 minus the number of server int (*server_create_os_surface_bpp)(struct xrdp_mod* v, int rdpindex,
int width, int height, int bpp);
int (*server_paint_rect_bpp)(struct xrdp_mod* v, int x, int y, int cx, int cy,
char* data, int width, int height,
int srcx, int srcy, int bpp);
int (*server_composite)(struct xrdp_mod* v, int srcidx, int srcformat,
int srcwidth, int srcrepeat, int* srctransform,
int mskflags, int mskidx, int mskformat,
int mskwidth, int mskrepeat, int op,
int srcx, int srcy, int mskx, int msky,
int dstx, int dsty, int width, int height,
int dstformat);
long server_dumby[100 - 42]; /* align, 100 minus the number of server
functions above */ functions above */
/* common */ /* common */
long handle; /* pointer to self as int */ long handle; /* pointer to self as int */
@ -185,6 +203,9 @@ struct xrdp_brush_item
char pattern[8]; char pattern[8];
}; };
/* moved to xrdp_constants.h
#define XRDP_BITMAP_CACHE_ENTRIES 2048 */
/* differnce caches */ /* differnce caches */
struct xrdp_cache struct xrdp_cache
{ {

@ -401,7 +401,7 @@ xrdp_wm_load_static_colors_plus(struct xrdp_wm *self, char *autorun_name)
if (g_strcasecmp(val, "black") == 0) if (g_strcasecmp(val, "black") == 0)
{ {
val = (char *)list_get_item(values, index); val = (char *)list_get_item(values, index);
self->black = HCOLOR(self->screen->bpp, xrdp_wm_htoi(val)); self->black = HCOLOR(self->screen->bpp,xrdp_wm_htoi(val));
} }
else if (g_strcasecmp(val, "grey") == 0) else if (g_strcasecmp(val, "grey") == 0)
{ {
@ -1221,6 +1221,22 @@ xrdp_wm_mouse_click(struct xrdp_wm *self, int x, int y, int but, int down)
self->mm->mod->mod_event(self->mm->mod, WM_BUTTON5UP, self->mm->mod->mod_event(self->mm->mod, WM_BUTTON5UP,
self->mouse_x, self->mouse_y, 0, 0); self->mouse_x, self->mouse_y, 0, 0);
} }
if (but == 6 && down)
{
self->mm->mod->mod_event(self->mm->mod, WM_BUTTON6DOWN, x, y, 0, 0);
}
else if (but == 6 && !down)
{
self->mm->mod->mod_event(self->mm->mod, WM_BUTTON6UP, x, y, 0, 0);
}
if (but == 7 && down)
{
self->mm->mod->mod_event(self->mm->mod, WM_BUTTON7DOWN, x, y, 0, 0);
}
else if (but == 7 && !down)
{
self->mm->mod->mod_event(self->mm->mod, WM_BUTTON7UP, x, y, 0, 0);
}
} }
} }
} }
@ -1528,18 +1544,48 @@ xrdp_wm_process_input_mouse(struct xrdp_wm *self, int device_flags,
} }
} }
if (device_flags == MOUSE_FLAG_BUTTON4 || /* 0x0280 */ if (device_flags & 0x200) /* PTRFLAGS_WHEEL */
device_flags == 0x0278)
{ {
xrdp_wm_mouse_click(self, 0, 0, 4, 0); if (device_flags & 0x100) /* PTRFLAGS_WHEEL_NEGATIVE */
{
xrdp_wm_mouse_click(self, 0, 0, 5, 0);
}
else
{
xrdp_wm_mouse_click(self, 0, 0, 4, 0);
}
} }
if (device_flags == MOUSE_FLAG_BUTTON5 || /* 0x0380 */ return 0;
device_flags == 0x0388) }
/*****************************************************************************/
static int APP_CC
xrdp_wm_process_input_mousex(struct xrdp_wm* self, int device_flags,
int x, int y)
{
if (device_flags & 0x8000) /* PTRXFLAGS_DOWN */
{ {
xrdp_wm_mouse_click(self, 0, 0, 5, 0); if (device_flags & 0x0001) /* PTRXFLAGS_BUTTON1 */
{
xrdp_wm_mouse_click(self, x, y, 6, 1);
}
else if (device_flags & 0x0002) /* PTRXFLAGS_BUTTON2 */
{
xrdp_wm_mouse_click(self, x, y, 7, 1);
}
}
else
{
if (device_flags & 0x0001) /* PTRXFLAGS_BUTTON1 */
{
xrdp_wm_mouse_click(self, x, y, 6, 0);
}
else if (device_flags & 0x0002) /* PTRXFLAGS_BUTTON2 */
{
xrdp_wm_mouse_click(self, x, y, 7, 0);
}
} }
return 0; return 0;
} }
@ -1616,6 +1662,9 @@ callback(long id, int msg, long param1, long param2, long param3, long param4)
case 0x8001: /* RDP_INPUT_MOUSE */ case 0x8001: /* RDP_INPUT_MOUSE */
rv = xrdp_wm_process_input_mouse(wm, param3, param1, param2); rv = xrdp_wm_process_input_mouse(wm, param3, param1, param2);
break; break;
case 0x8002: /* RDP_INPUT_MOUSEX (INPUT_EVENT_MOUSEX) */
rv = xrdp_wm_process_input_mousex(wm, param3, param1, param2);
break;
case 0x4444: /* invalidate, this is not from RDP_DATA_PDU_INPUT */ case 0x4444: /* invalidate, this is not from RDP_DATA_PDU_INPUT */
/* like the rest, its from RDP_PDU_DATA with code 33 */ /* like the rest, its from RDP_PDU_DATA with code 33 */
/* its the rdp client asking for a screen update */ /* its the rdp client asking for a screen update */

@ -23,6 +23,12 @@
#include <sys/ipc.h> #include <sys/ipc.h>
#include <sys/shm.h> #include <sys/shm.h>
#define LOG_LEVEL 1
#define LLOG(_level, _args) \
do { if (_level < LOG_LEVEL) { g_write _args ; } } while (0)
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0)
/******************************************************************************/ /******************************************************************************/
/* returns error */ /* returns error */
int DEFAULT_CC int DEFAULT_CC
@ -476,6 +482,25 @@ process_server_window_new_update(struct mod *mod, struct stream *s)
return rv; return rv;
} }
/******************************************************************************/
/* return error */
static int APP_CC
process_server_window_show(struct mod* mod, struct stream* s)
{
int window_id;
int rv;
int flags;
struct rail_window_state_order rwso;
g_memset(&rwso, 0, sizeof(rwso));
in_uint32_le(s, window_id);
in_uint32_le(s, flags);
in_uint32_le(s, rwso.show_state);
mod->server_window_new_update(mod, window_id, &rwso, flags);
rv = 0;
return rv;
}
/******************************************************************************/ /******************************************************************************/
/* return error */ /* return error */
static int APP_CC static int APP_CC
@ -553,12 +578,17 @@ lib_mod_process_orders(struct mod *mod, int type, struct stream *s)
int cy; int cy;
int srcx; int srcx;
int srcy; int srcy;
int mskx;
int msky;
int dstx;
int dsty;
int len_bmpdata; int len_bmpdata;
int style; int style;
int x1; int x1;
int y1; int y1;
int x2; int x2;
int y2; int y2;
int bpp;
int rdpid; int rdpid;
int hints; int hints;
int mask; int mask;
@ -571,6 +601,29 @@ lib_mod_process_orders(struct mod *mod, int type, struct stream *s)
int shmem_id; int shmem_id;
int shmem_offset; int shmem_offset;
int frame_id; int frame_id;
int charactor;
int font;
int mixmode;
int clip_left;
int clip_top;
int clip_right;
int clip_bottom;
int box_left;
int box_top;
int box_right;
int box_bottom;
int srcrepeat;
int srcidx;
int srcformat;
int srcwidth;
int mskflags;
int mskidx;
int mskformat;
int mskwidth;
int mskrepeat;
int dstformat;
int op;
int transform[10];
char *bmpdata; char *bmpdata;
char cur_data[32 * (32 * 3)]; char cur_data[32 * (32 * 3)];
char cur_mask[32 * (32 / 8)]; char cur_mask[32 * (32 / 8)];
@ -693,6 +746,101 @@ lib_mod_process_orders(struct mod *mod, int type, struct stream *s)
case 26: /* server_window_delete */ case 26: /* server_window_delete */
rv = process_server_window_delete(mod, s); rv = process_server_window_delete(mod, s);
break; break;
case 27: /* server_window_new_update - show */
rv = process_server_window_show(mod, s);
break;
case 28: /* server_add_char */
in_uint16_le(s, font);
in_uint16_le(s, charactor);
in_sint16_le(s, x);
in_sint16_le(s, y);
in_uint16_le(s, cx);
in_uint16_le(s, cy);
in_uint16_le(s, len_bmpdata);
in_uint8p(s, bmpdata, len_bmpdata);
rv = mod->server_add_char(mod, font, charactor, x, y, cx, cy, bmpdata);
break;
case 29: /* server_add_char_alpha */
in_uint16_le(s, font);
in_uint16_le(s, charactor);
in_sint16_le(s, x);
in_sint16_le(s, y);
in_uint16_le(s, cx);
in_uint16_le(s, cy);
in_uint16_le(s, len_bmpdata);
in_uint8p(s, bmpdata, len_bmpdata);
rv = mod->server_add_char_alpha(mod, font, charactor, x, y, cx, cy, bmpdata);
break;
case 30: /* server_draw_text */
in_uint16_le(s, font);
in_uint16_le(s, flags);
in_uint16_le(s, mixmode);
in_sint16_le(s, clip_left);
in_sint16_le(s, clip_top);
in_sint16_le(s, clip_right);
in_sint16_le(s, clip_bottom);
in_sint16_le(s, box_left);
in_sint16_le(s, box_top);
in_sint16_le(s, box_right);
in_sint16_le(s, box_bottom);
in_sint16_le(s, x);
in_sint16_le(s, y);
in_uint16_le(s, len_bmpdata);
in_uint8p(s, bmpdata, len_bmpdata);
rv = mod->server_draw_text(mod, font, flags, mixmode, clip_left, clip_top,
clip_right, clip_bottom, box_left, box_top,
box_right, box_bottom, x, y, bmpdata, len_bmpdata);
break;
case 31: /* server_create_os_surface_bpp */
in_uint32_le(s, rdpid);
in_uint16_le(s, width);
in_uint16_le(s, height);
in_uint8(s, bpp);
rv = mod->server_create_os_surface_bpp(mod, rdpid, width, height, bpp);
break;
case 32: /* server_paint_rect_bpp */
in_sint16_le(s, x);
in_sint16_le(s, y);
in_uint16_le(s, cx);
in_uint16_le(s, cy);
in_uint32_le(s, len_bmpdata);
in_uint8p(s, bmpdata, len_bmpdata);
in_uint16_le(s, width);
in_uint16_le(s, height);
in_sint16_le(s, srcx);
in_sint16_le(s, srcy);
in_uint8(s, bpp);
rv = mod->server_paint_rect_bpp(mod, x, y, cx, cy,
bmpdata, width, height,
srcx, srcy, bpp);
break;
case 33:
in_uint16_le(s, srcidx);
in_uint32_le(s, srcformat);
in_uint16_le(s, srcwidth);
in_uint8(s, srcrepeat);
g_memcpy(transform, s->p, 40);
in_uint8s(s, 40);
in_uint8(s, mskflags);
in_uint16_le(s, mskidx);
in_uint32_le(s, mskformat);
in_uint16_le(s, mskwidth);
in_uint8(s, mskrepeat);
in_uint8(s, op);
in_sint16_le(s, srcx);
in_sint16_le(s, srcy);
in_sint16_le(s, mskx);
in_sint16_le(s, msky);
in_sint16_le(s, dstx);
in_sint16_le(s, dsty);
in_uint16_le(s, width);
in_uint16_le(s, height);
in_uint32_le(s, dstformat);
rv = mod->server_composite(mod, srcidx, srcformat, srcwidth, srcrepeat,
transform, mskflags, mskidx, mskformat,
mskwidth, mskrepeat, op, srcx, srcy, mskx, msky,
dstx, dsty, width, height, dstformat);
break;
case 51: /* server_set_pointer_ex */ case 51: /* server_set_pointer_ex */
rv = process_server_set_pointer_ex(mod, s); rv = process_server_set_pointer_ex(mod, s);
break; break;

@ -53,7 +53,8 @@ struct mod
int (*server_screen_blt)(struct mod* v, int x, int y, int cx, int cy, int (*server_screen_blt)(struct mod* v, int x, int y, int cx, int cy,
int srcx, int srcy); int srcx, int srcy);
int (*server_paint_rect)(struct mod* v, int x, int y, int cx, int cy, int (*server_paint_rect)(struct mod* v, int x, int y, int cx, int cy,
char* data, int width, int height, int srcx, int srcy); char* data, int width, int height,
int srcx, int srcy);
int (*server_set_cursor)(struct mod* v, int x, int y, char* data, char* mask); int (*server_set_cursor)(struct mod* v, int x, int y, char* data, char* mask);
int (*server_palette)(struct mod* v, int* palette); int (*server_palette)(struct mod* v, int* palette);
int (*server_msg)(struct mod* v, char* msg, int code); int (*server_msg)(struct mod* v, char* msg, int code);
@ -119,8 +120,21 @@ struct mod
int flags); int flags);
int (*server_set_cursor_ex)(struct mod* v, int x, int y, char* data, int (*server_set_cursor_ex)(struct mod* v, int x, int y, char* data,
char* mask, int bpp); char* mask, int bpp);
int (*server_add_char_alpha)(struct mod* v, int font, int charactor,
int offset, int baseline,
int width, int height, char* data);
int (*server_create_os_surface_bpp)(struct mod* v, int rdpindex,
int width, int height, int bpp);
int (*server_paint_rect_bpp)(struct mod* v, int x, int y, int cx, int cy,
char* data, int width, int height,
int srcx, int srcy, int bpp);
int (*server_composite)(struct mod* v, int srcidx, int srcformat, int srcwidth,
int srcrepeat, int* srctransform, int mskflags, int mskidx,
int mskformat, int mskwidth, int mskrepeat, int op,
int srcx, int srcy, int mskx, int msky,
int dstx, int dsty, int width, int height, int dstformat);
tbus server_dumby[100 - 38]; /* align, 100 minus the number of server tbus server_dumby[100 - 42]; /* align, 100 minus the number of server
functions above */ functions above */
/* common */ /* common */
tbus handle; /* pointer to self as long */ tbus handle; /* pointer to self as long */

Loading…
Cancel
Save