Merge pull request #553 from jsorg71/libpainter
add libpainter for drawing when client does not have minimum orders
This commit is contained in:
commit
25e5243ecf
@ -148,6 +148,8 @@ struct xrdp_client_info
|
||||
|
||||
int client_os_major;
|
||||
int client_os_minor;
|
||||
|
||||
int no_orders_supported;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -495,6 +495,40 @@
|
||||
#define XR_ORDERFLAGS_EX_ALTSEC_FRAME_MARKER_SUPPORT 0x0004
|
||||
#define XR_ORDERFLAGS_EX_OFFSCREEN_COMPOSITE_SUPPORT 0x0100
|
||||
|
||||
/* orders negotiation indexes */
|
||||
#define TS_NEG_DSTBLT_INDEX 0x00
|
||||
#define TS_NEG_PATBLT_INDEX 0x01
|
||||
#define TS_NEG_SCRBLT_INDEX 0x02
|
||||
#define TS_NEG_MEMBLT_INDEX 0x03
|
||||
#define TS_NEG_MEM3BLT_INDEX 0x04
|
||||
/* 0x05 */
|
||||
/* 0x06 */
|
||||
#define TS_NEG_DRAWNINEGRID_INDEX 0x07
|
||||
#define TS_NEG_LINETO_INDEX 0x08
|
||||
#define TS_NEG_MULTI_DRAWNINEGRID_INDEX 0x09
|
||||
/* 0x0A */
|
||||
#define TS_NEG_SAVEBITMAP_INDEX 0x0B
|
||||
/* 0x0C */
|
||||
/* 0x0D */
|
||||
/* 0x0E */
|
||||
#define TS_NEG_MULTIDSTBLT_INDEX 0x0F
|
||||
#define TS_NEG_MULTIPATBLT_INDEX 0x10
|
||||
#define TS_NEG_MULTISCRBLT_INDEX 0x11
|
||||
#define TS_NEG_MULTIOPAQUERECT_INDEX 0x12
|
||||
#define TS_NEG_FAST_INDEX_INDEX 0x13
|
||||
#define TS_NEG_POLYGON_SC_INDEX 0x14
|
||||
#define TS_NEG_POLYGON_CB_INDEX 0x15
|
||||
#define TS_NEG_POLYLINE_INDEX 0x16
|
||||
/* 0x17 */
|
||||
#define TS_NEG_FAST_GLYPH_INDEX 0x18
|
||||
#define TS_NEG_ELLIPSE_SC_INDEX 0x19
|
||||
#define TS_NEG_ELLIPSE_CB_INDEX 0x1A
|
||||
#define TS_NEG_INDEX_INDEX 0x1B
|
||||
/* 0x1C */
|
||||
/* 0x1D */
|
||||
/* 0x1E */
|
||||
/* 0x1F */
|
||||
|
||||
/* drawable types */
|
||||
#define WND_TYPE_BITMAP 0
|
||||
#define WND_TYPE_WND 1
|
||||
|
@ -119,6 +119,11 @@ AC_ARG_ENABLE(pixman, AS_HELP_STRING([--enable-pixman],
|
||||
[Use pixman library (default: no)]),
|
||||
[], [enable_pixman=no])
|
||||
AM_CONDITIONAL(XRDP_PIXMAN, [test x$enable_pixman = xyes])
|
||||
AM_CONDITIONAL(XRDP_PAINTER, [test x$enable_painter = xyes])
|
||||
AC_ARG_ENABLE(painter, AS_HELP_STRING([--enable-painter],
|
||||
[Use painter library (default: no)]),
|
||||
[], [enable_painter=no])
|
||||
AM_CONDITIONAL(XRDP_PAINTER, [test x$enable_painter = xyes])
|
||||
|
||||
# Check if -ldl is needed to use dlopen()
|
||||
DLOPEN_LIBS=
|
||||
|
@ -159,6 +159,15 @@ xrdp_caps_process_order(struct xrdp_rdp *self, struct stream *s,
|
||||
DEBUG(("desktop cache size %d", i));
|
||||
in_uint8s(s, 4); /* Unknown */
|
||||
in_uint8s(s, 4); /* Unknown */
|
||||
|
||||
/* check if libpainter should be used for drawing, instead of orders */
|
||||
if (!(order_caps[TS_NEG_DSTBLT_INDEX] && order_caps[TS_NEG_PATBLT_INDEX] &&
|
||||
order_caps[TS_NEG_SCRBLT_INDEX] && order_caps[TS_NEG_MEMBLT_INDEX]))
|
||||
{
|
||||
g_writeln("xrdp_caps_process_order: not enough orders supported by client, using painter.");
|
||||
self->client_info.no_orders_supported = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -682,6 +691,17 @@ xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
|
||||
s->p = p + len + 4;
|
||||
}
|
||||
|
||||
if (self->client_info.no_orders_supported &&
|
||||
(self->client_info.offscreen_support_level != 0))
|
||||
{
|
||||
g_writeln("xrdp_caps_process_confirm_active: not enough orders "
|
||||
"supported by client, client wants off screen bitmap but "
|
||||
"offscreen bitmaps disabled");
|
||||
self->client_info.offscreen_support_level = 0;
|
||||
self->client_info.offscreen_cache_size = 0;
|
||||
self->client_info.offscreen_cache_entries = 0;
|
||||
}
|
||||
|
||||
DEBUG(("out xrdp_caps_process_confirm_active"));
|
||||
return 0;
|
||||
}
|
||||
|
@ -33,6 +33,12 @@ AM_CPPFLAGS += $(PIXMAN_CFLAGS)
|
||||
XRDP_EXTRA_LIBS += $(PIXMAN_LIBS)
|
||||
endif
|
||||
|
||||
if XRDP_PAINTER
|
||||
AM_CPPFLAGS += -DXRDP_PAINTER
|
||||
AM_CPPFLAGS += -I$(top_srcdir)/libpainter/include
|
||||
XRDP_EXTRA_LIBS += $(top_srcdir)/libpainter/src/.libs/libpainter.a
|
||||
endif
|
||||
|
||||
sbin_PROGRAMS = \
|
||||
xrdp
|
||||
|
||||
|
@ -123,6 +123,14 @@ xrdp_bitmap_create(int width, int height, int bpp,
|
||||
self->data = (char *)g_malloc(width * height * Bpp, 0);
|
||||
}
|
||||
|
||||
#if defined(XRDP_PAINTER)
|
||||
if (self->type == WND_TYPE_SCREEN) /* noorders */
|
||||
{
|
||||
LLOGLN(0, ("xrdp_bitmap_create: noorders"));
|
||||
self->data = (char *) g_malloc(width * height * Bpp, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (self->type != WND_TYPE_BITMAP)
|
||||
{
|
||||
self->child_list = list_create();
|
||||
|
@ -20,17 +20,152 @@
|
||||
|
||||
#include "xrdp.h"
|
||||
|
||||
#if defined(XRDP_PAINTER)
|
||||
#include <painter.h> /* libpainter */
|
||||
#endif
|
||||
|
||||
#define LLOG_LEVEL 1
|
||||
#define LLOGLN(_level, _args) \
|
||||
do \
|
||||
{ \
|
||||
if (_level < LLOG_LEVEL) \
|
||||
{ \
|
||||
g_write("xrdp:xrdp_painter [%10.10u]: ", g_time3()); \
|
||||
g_writeln _args ; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#if defined(XRDP_PAINTER)
|
||||
|
||||
/*****************************************************************************/
|
||||
static int APP_CC
|
||||
xrdp_painter_add_dirty_rect(struct xrdp_painter *self, int x, int y,
|
||||
int cx, int cy, struct xrdp_rect *clip_rect)
|
||||
{
|
||||
int x2;
|
||||
int y2;
|
||||
struct xrdp_rect rect;
|
||||
|
||||
if (clip_rect != 0)
|
||||
{
|
||||
x2 = x + cx;
|
||||
y2 = y + cy;
|
||||
x = MAX(x, clip_rect->left);
|
||||
y = MAX(y, clip_rect->top);
|
||||
x2 = MIN(x2, clip_rect->right);
|
||||
y2 = MIN(y2, clip_rect->bottom);
|
||||
cx = x2 - x;
|
||||
cy = y2 - y;
|
||||
}
|
||||
if (cx < 1 || cy < 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
rect.left = x;
|
||||
rect.top = y;
|
||||
rect.right = x + cx;
|
||||
rect.bottom = y + cy;
|
||||
xrdp_region_add_rect(self->dirty_region, &rect);
|
||||
LLOGLN(10, ("xrdp_painter_add_dirty_rect: x %d y %d cx %d cy %d",
|
||||
x, y, cx, cy));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
xrdp_painter_send_dirty(struct xrdp_painter *self)
|
||||
{
|
||||
int cx;
|
||||
int cy;
|
||||
int bpp;
|
||||
int Bpp;
|
||||
int index;
|
||||
int jndex;
|
||||
int error;
|
||||
char *ldata;
|
||||
char *src;
|
||||
char *dst;
|
||||
struct xrdp_rect rect;
|
||||
|
||||
LLOGLN(10, ("xrdp_painter_send_dirty:"));
|
||||
|
||||
bpp = self->wm->screen->bpp;
|
||||
Bpp = (bpp + 7) / 8;
|
||||
if (Bpp == 3)
|
||||
{
|
||||
Bpp = 4;
|
||||
}
|
||||
|
||||
jndex = 0;
|
||||
error = xrdp_region_get_rect(self->dirty_region, jndex, &rect);
|
||||
while (error == 0)
|
||||
{
|
||||
cx = rect.right - rect.left;
|
||||
cy = rect.bottom - rect.top;
|
||||
ldata = (char *)g_malloc(cx * cy * Bpp, 0);
|
||||
if (ldata == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
src = self->wm->screen->data;
|
||||
src += self->wm->screen->line_size * rect.top;
|
||||
src += rect.left * Bpp;
|
||||
dst = ldata;
|
||||
for (index = 0; index < cy; index++)
|
||||
{
|
||||
g_memcpy(dst, src, cx * Bpp);
|
||||
src += self->wm->screen->line_size;
|
||||
dst += cx * Bpp;
|
||||
}
|
||||
LLOGLN(10, ("xrdp_painter_send_dirty: x %d y %d cx %d cy %d",
|
||||
rect.left, rect.top, cx, cy));
|
||||
libxrdp_send_bitmap(self->session, cx, cy, bpp,
|
||||
ldata, rect.left, rect.top, cx, cy);
|
||||
g_free(ldata);
|
||||
|
||||
jndex++;
|
||||
error = xrdp_region_get_rect(self->dirty_region, jndex, &rect);
|
||||
}
|
||||
|
||||
xrdp_region_delete(self->dirty_region);
|
||||
self->dirty_region = xrdp_region_create(self->wm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
struct xrdp_painter *APP_CC
|
||||
xrdp_painter_create(struct xrdp_wm *wm, struct xrdp_session *session)
|
||||
{
|
||||
struct xrdp_painter *self;
|
||||
|
||||
LLOGLN(10, ("xrdp_painter_create:"));
|
||||
self = (struct xrdp_painter *)g_malloc(sizeof(struct xrdp_painter), 1);
|
||||
self->wm = wm;
|
||||
self->session = session;
|
||||
self->rop = 0xcc; /* copy will use 0xcc*/
|
||||
self->rop = 0xcc; /* copy will use 0xcc */
|
||||
self->clip_children = 1;
|
||||
|
||||
|
||||
if (self->session->client_info->no_orders_supported)
|
||||
{
|
||||
#if defined(XRDP_PAINTER)
|
||||
if (painter_create(&(self->painter)) != PT_ERROR_NONE)
|
||||
{
|
||||
self->painter = 0;
|
||||
LLOGLN(0, ("xrdp_painter_create: painter_create failed"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LLOGLN(10, ("xrdp_painter_create: painter_create success"));
|
||||
}
|
||||
self->dirty_region = xrdp_region_create(wm);
|
||||
#endif
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@ -38,11 +173,17 @@ xrdp_painter_create(struct xrdp_wm *wm, struct xrdp_session *session)
|
||||
void APP_CC
|
||||
xrdp_painter_delete(struct xrdp_painter *self)
|
||||
{
|
||||
LLOGLN(10, ("xrdp_painter_delete:"));
|
||||
if (self == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(XRDP_PAINTER)
|
||||
painter_delete(self->painter);
|
||||
xrdp_region_delete(self->dirty_region);
|
||||
#endif
|
||||
|
||||
g_free(self);
|
||||
}
|
||||
|
||||
@ -54,6 +195,13 @@ wm_painter_set_target(struct xrdp_painter *self)
|
||||
int index;
|
||||
struct list *del_list;
|
||||
|
||||
LLOGLN(10, ("wm_painter_set_target:"));
|
||||
|
||||
if (self->painter != 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (self->wm->target_surface->type == WND_TYPE_SCREEN)
|
||||
{
|
||||
if (self->wm->current_surface_index != 0xffff)
|
||||
@ -97,11 +245,19 @@ wm_painter_set_target(struct xrdp_painter *self)
|
||||
int APP_CC
|
||||
xrdp_painter_begin_update(struct xrdp_painter *self)
|
||||
{
|
||||
LLOGLN(10, ("xrdp_painter_begin_update:"));
|
||||
if (self == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
self->begin_end_level++;
|
||||
|
||||
if (self->painter != 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
libxrdp_orders_init(self->session);
|
||||
wm_painter_set_target(self);
|
||||
return 0;
|
||||
@ -111,11 +267,25 @@ xrdp_painter_begin_update(struct xrdp_painter *self)
|
||||
int APP_CC
|
||||
xrdp_painter_end_update(struct xrdp_painter *self)
|
||||
{
|
||||
LLOGLN(10, ("xrdp_painter_end_update:"));
|
||||
if (self == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
self->begin_end_level--;
|
||||
|
||||
if (self->painter != 0)
|
||||
{
|
||||
#if defined(XRDP_PAINTER)
|
||||
if (self->begin_end_level == 0)
|
||||
{
|
||||
xrdp_painter_send_dirty(self);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
libxrdp_orders_send(self->session);
|
||||
return 0;
|
||||
}
|
||||
@ -270,6 +440,7 @@ xrdp_painter_text_width(struct xrdp_painter *self, const char *text)
|
||||
struct xrdp_font_char *font_item;
|
||||
twchar *wstr;
|
||||
|
||||
LLOGLN(10, ("xrdp_painter_text_width:"));
|
||||
xrdp_painter_font_needed(self);
|
||||
|
||||
if (self->font == 0)
|
||||
@ -307,6 +478,7 @@ xrdp_painter_text_height(struct xrdp_painter *self, const char *text)
|
||||
struct xrdp_font_char *font_item;
|
||||
twchar *wstr;
|
||||
|
||||
LLOGLN(10, ("xrdp_painter_text_height:"));
|
||||
xrdp_painter_font_needed(self);
|
||||
|
||||
if (self->font == 0)
|
||||
@ -342,6 +514,13 @@ xrdp_painter_setup_brush(struct xrdp_painter *self,
|
||||
{
|
||||
int cache_id;
|
||||
|
||||
LLOGLN(10, ("xrdp_painter_setup_brush:"));
|
||||
|
||||
if (self->painter != 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
g_memcpy(out_brush, in_brush, sizeof(struct xrdp_brush));
|
||||
|
||||
if (in_brush->style == 3)
|
||||
@ -358,6 +537,38 @@ xrdp_painter_setup_brush(struct xrdp_painter *self,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(XRDP_PAINTER)
|
||||
|
||||
/*****************************************************************************/
|
||||
static int APP_CC
|
||||
get_pt_format(struct xrdp_painter *self)
|
||||
{
|
||||
switch (self->wm->screen->bpp)
|
||||
{
|
||||
case 8:
|
||||
return PT_FORMAT_r3g3b2;
|
||||
case 15:
|
||||
return PT_FORMAT_a1r5g5b5;
|
||||
case 16:
|
||||
return PT_FORMAT_r5g6b5;
|
||||
}
|
||||
return PT_FORMAT_a8r8g8b8;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
get_rgb_from_rdp_color(struct xrdp_painter *self, int rdp_color)
|
||||
{
|
||||
if (self->wm->screen->bpp < 24)
|
||||
{
|
||||
return rdp_color;
|
||||
}
|
||||
/* well, this is really BGR2RGB */
|
||||
return XR_RGB2BGR(rdp_color);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/* fill in an area of the screen with one color */
|
||||
int APP_CC
|
||||
@ -375,11 +586,120 @@ xrdp_painter_fill_rect(struct xrdp_painter *self,
|
||||
int dy;
|
||||
int rop;
|
||||
|
||||
LLOGLN(10, ("xrdp_painter_fill_rect:"));
|
||||
|
||||
if (self == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
dx = 0;
|
||||
dy = 0;
|
||||
|
||||
if (self->painter != 0)
|
||||
{
|
||||
#if defined(XRDP_PAINTER)
|
||||
struct painter_bitmap dst_pb;
|
||||
struct xrdp_bitmap *ldst;
|
||||
struct painter_bitmap pat;
|
||||
|
||||
LLOGLN(10, ("xrdp_painter_fill_rect: dst->type %d", dst->type));
|
||||
if (dst->type != WND_TYPE_OFFSCREEN)
|
||||
{
|
||||
LLOGLN(10, ("xrdp_painter_fill_rect: using painter"));
|
||||
|
||||
ldst = self->wm->screen;
|
||||
|
||||
g_memset(&dst_pb, 0, sizeof(dst_pb));
|
||||
dst_pb.format = get_pt_format(self);
|
||||
dst_pb.width = ldst->width;
|
||||
dst_pb.stride_bytes = ldst->line_size;
|
||||
dst_pb.height = ldst->height;
|
||||
dst_pb.data = ldst->data;
|
||||
|
||||
LLOGLN(10, ("xrdp_painter_fill_rect: ldst->width %d ldst->height %d "
|
||||
"dst->data %p self->fg_color %d",
|
||||
ldst->width, ldst->height, ldst->data, self->fg_color));
|
||||
|
||||
xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy);
|
||||
region = xrdp_region_create(self->wm);
|
||||
xrdp_wm_get_vis_region(self->wm, dst, x, y, cx, cy, region,
|
||||
self->clip_children);
|
||||
x += dx;
|
||||
y += dy;
|
||||
|
||||
rop = self->rop;
|
||||
switch (self->rop)
|
||||
{
|
||||
case 0x5a:
|
||||
rop = PT_ROP_DSx;
|
||||
break;
|
||||
case 0xf0:
|
||||
rop = PT_ROP_S;
|
||||
break;
|
||||
case 0xfb:
|
||||
rop = PT_ROP_D;
|
||||
break;
|
||||
case 0xc0:
|
||||
rop = PT_ROP_DSa;
|
||||
break;
|
||||
}
|
||||
painter_set_rop(self->painter, rop);
|
||||
|
||||
if (self->mix_mode == 0)
|
||||
{
|
||||
painter_set_pattern_mode(self->painter, PT_PATTERN_MODE_OPAQUE);
|
||||
painter_set_fgcolor(self->painter, get_rgb_from_rdp_color(self, self->fg_color));
|
||||
k = 0;
|
||||
while (xrdp_region_get_rect(region, k, &rect) == 0)
|
||||
{
|
||||
if (rect_intersect(&rect, &clip_rect, &draw_rect))
|
||||
{
|
||||
painter_set_clip(self->painter,
|
||||
draw_rect.left, draw_rect.top,
|
||||
draw_rect.right - draw_rect.left,
|
||||
draw_rect.bottom - draw_rect.top);
|
||||
painter_fill_rect(self->painter, &dst_pb, x, y, cx, cy);
|
||||
xrdp_painter_add_dirty_rect(self, x, y, cx, cy, &draw_rect);
|
||||
}
|
||||
k++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
painter_set_pattern_mode(self->painter, PT_PATTERN_MODE_OPAQUE);
|
||||
painter_set_fgcolor(self->painter, get_rgb_from_rdp_color(self, self->fg_color));
|
||||
painter_set_bgcolor(self->painter, get_rgb_from_rdp_color(self, self->bg_color));
|
||||
painter_set_pattern_origin(self->painter, self->brush.x_origin, self->brush.y_origin);
|
||||
g_memset(&pat, 0, sizeof(pat));
|
||||
pat.format = PT_FORMAT_c1;
|
||||
pat.width = 8;
|
||||
pat.stride_bytes = 1;
|
||||
pat.height = 8;
|
||||
pat.data = self->brush.pattern;
|
||||
k = 0;
|
||||
while (xrdp_region_get_rect(region, k, &rect) == 0)
|
||||
{
|
||||
if (rect_intersect(&rect, &clip_rect, &draw_rect))
|
||||
{
|
||||
painter_set_clip(self->painter,
|
||||
draw_rect.left, draw_rect.top,
|
||||
draw_rect.right - draw_rect.left,
|
||||
draw_rect.bottom - draw_rect.top);
|
||||
painter_fill_pattern(self->painter, &dst_pb, &pat,
|
||||
x, y, x, y, cx, cy);
|
||||
xrdp_painter_add_dirty_rect(self, x, y, cx, cy, &draw_rect);
|
||||
}
|
||||
k++;
|
||||
}
|
||||
}
|
||||
painter_clear_clip(self->painter);
|
||||
xrdp_region_delete(region);
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* todo data */
|
||||
|
||||
if (dst->type == WND_TYPE_BITMAP) /* 0 */
|
||||
@ -508,11 +828,14 @@ xrdp_painter_draw_text(struct xrdp_painter *self,
|
||||
struct xrdp_font_char *font_item;
|
||||
twchar *wstr;
|
||||
|
||||
LLOGLN(10, ("xrdp_painter_draw_text:"));
|
||||
|
||||
if (self == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
len = g_mbstowcs(0, text, 0);
|
||||
|
||||
if (len < 1)
|
||||
@ -534,6 +857,88 @@ xrdp_painter_draw_text(struct xrdp_painter *self,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (self->painter != 0)
|
||||
{
|
||||
#if defined(XRDP_PAINTER)
|
||||
struct painter_bitmap pat;
|
||||
struct painter_bitmap dst_pb;
|
||||
struct xrdp_bitmap *ldst;
|
||||
|
||||
if (dst->type != WND_TYPE_OFFSCREEN)
|
||||
{
|
||||
ldst = self->wm->screen;
|
||||
/* convert to wide char */
|
||||
wstr = (twchar *)g_malloc((len + 2) * sizeof(twchar), 0);
|
||||
g_mbstowcs(wstr, text, len + 1);
|
||||
font = self->font;
|
||||
total_width = 0;
|
||||
total_height = 0;
|
||||
for (index = 0; index < len; index++)
|
||||
{
|
||||
font_item = font->font_items + wstr[index];
|
||||
k = font_item->incby;
|
||||
total_width += k;
|
||||
total_height = MAX(total_height, font_item->height);
|
||||
}
|
||||
xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy);
|
||||
region = xrdp_region_create(self->wm);
|
||||
xrdp_wm_get_vis_region(self->wm, dst, x, y,
|
||||
total_width, total_height,
|
||||
region, self->clip_children);
|
||||
x += dx;
|
||||
y += dy;
|
||||
g_memset(&dst_pb, 0, sizeof(dst_pb));
|
||||
dst_pb.format = get_pt_format(self);
|
||||
dst_pb.width = ldst->width;
|
||||
dst_pb.stride_bytes = ldst->line_size;
|
||||
dst_pb.height = ldst->height;
|
||||
dst_pb.data = ldst->data;
|
||||
painter_set_rop(self->painter, PT_ROP_S);
|
||||
painter_set_pattern_origin(self->painter, 0, 0);
|
||||
painter_set_pattern_mode(self->painter, PT_PATTERN_MODE_NORMAL);
|
||||
painter_set_fgcolor(self->painter,
|
||||
get_rgb_from_rdp_color(self, self->fg_color));
|
||||
k = 0;
|
||||
while (xrdp_region_get_rect(region, k, &rect) == 0)
|
||||
{
|
||||
if (rect_intersect(&rect, &clip_rect, &draw_rect))
|
||||
{
|
||||
painter_set_clip(self->painter,
|
||||
draw_rect.left, draw_rect.top,
|
||||
draw_rect.right - draw_rect.left,
|
||||
draw_rect.bottom - draw_rect.top);
|
||||
for (index = 0; index < len; index++)
|
||||
{
|
||||
font_item = font->font_items + wstr[index];
|
||||
g_memset(&pat, 0, sizeof(pat));
|
||||
pat.format = PT_FORMAT_c1;
|
||||
pat.width = font_item->width;
|
||||
pat.stride_bytes = (font_item->width + 7) / 8;
|
||||
pat.height = font_item->height;
|
||||
pat.data = font_item->data;
|
||||
x1 = x + font_item->offset;
|
||||
y1 = y + (font_item->height + font_item->baseline);
|
||||
painter_fill_pattern(self->painter, &dst_pb, &pat,
|
||||
0, 0, x1, y1,
|
||||
font_item->width,
|
||||
font_item->height);
|
||||
xrdp_painter_add_dirty_rect(self, x, y,
|
||||
font_item->width,
|
||||
font_item->height,
|
||||
&draw_rect);
|
||||
x += font_item->incby;
|
||||
}
|
||||
}
|
||||
k++;
|
||||
}
|
||||
painter_clear_clip(self->painter);
|
||||
xrdp_region_delete(region);
|
||||
g_free(wstr);
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* convert to wide char */
|
||||
wstr = (twchar *)g_malloc((len + 2) * sizeof(twchar), 0);
|
||||
g_mbstowcs(wstr, text, len + 1);
|
||||
@ -616,11 +1021,18 @@ xrdp_painter_draw_text2(struct xrdp_painter *self,
|
||||
int dx;
|
||||
int dy;
|
||||
|
||||
LLOGLN(0, ("xrdp_painter_draw_text2:"));
|
||||
|
||||
if (self == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (self->painter != 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* todo data */
|
||||
|
||||
if (dst->type == WND_TYPE_BITMAP)
|
||||
@ -711,11 +1123,76 @@ xrdp_painter_copy(struct xrdp_painter *self,
|
||||
int index;
|
||||
struct list *del_list;
|
||||
|
||||
LLOGLN(10, ("xrdp_painter_copy:"));
|
||||
|
||||
if (self == 0 || src == 0 || dst == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (self->painter != 0)
|
||||
{
|
||||
#if defined(XRDP_PAINTER)
|
||||
struct painter_bitmap src_pb;
|
||||
struct painter_bitmap dst_pb;
|
||||
struct xrdp_bitmap *ldst;
|
||||
|
||||
LLOGLN(10, ("xrdp_painter_copy: src->type %d dst->type %d", src->type, dst->type));
|
||||
LLOGLN(10, ("xrdp_painter_copy: self->rop 0x%2.2x", self->rop));
|
||||
|
||||
if (dst->type != WND_TYPE_OFFSCREEN)
|
||||
{
|
||||
LLOGLN(10, ("xrdp_painter_copy: using painter"));
|
||||
ldst = self->wm->screen;
|
||||
|
||||
g_memset(&dst_pb, 0, sizeof(dst_pb));
|
||||
dst_pb.format = get_pt_format(self);
|
||||
dst_pb.width = ldst->width;
|
||||
dst_pb.stride_bytes = ldst->line_size;
|
||||
dst_pb.height = ldst->height;
|
||||
dst_pb.data = ldst->data;
|
||||
|
||||
g_memset(&src_pb, 0, sizeof(src_pb));
|
||||
src_pb.format = get_pt_format(self);
|
||||
src_pb.width = src->width;
|
||||
src_pb.stride_bytes = src->line_size;
|
||||
src_pb.height = src->height;
|
||||
src_pb.data = src->data;
|
||||
|
||||
xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy);
|
||||
region = xrdp_region_create(self->wm);
|
||||
xrdp_wm_get_vis_region(self->wm, dst, x, y, cx, cy, region,
|
||||
self->clip_children);
|
||||
x += dx;
|
||||
y += dy;
|
||||
k = 0;
|
||||
|
||||
painter_set_rop(self->painter, self->rop);
|
||||
while (xrdp_region_get_rect(region, k, &rect1) == 0)
|
||||
{
|
||||
if (rect_intersect(&rect1, &clip_rect, &draw_rect))
|
||||
{
|
||||
painter_set_clip(self->painter,
|
||||
draw_rect.left, draw_rect.top,
|
||||
draw_rect.right - draw_rect.left,
|
||||
draw_rect.bottom - draw_rect.top);
|
||||
LLOGLN(10, (" x %d y %d cx %d cy %d srcx %d srcy %d",
|
||||
x, y, cx, cy, srcx, srcy));
|
||||
painter_copy(self->painter, &dst_pb, x, y, cx, cy,
|
||||
&src_pb, srcx, srcy);
|
||||
xrdp_painter_add_dirty_rect(self, x, y, cx, cy,
|
||||
&draw_rect);
|
||||
}
|
||||
k++;
|
||||
}
|
||||
painter_clear_clip(self->painter);
|
||||
xrdp_region_delete(region);
|
||||
}
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* todo data */
|
||||
|
||||
if (dst->type == WND_TYPE_BITMAP)
|
||||
@ -848,7 +1325,7 @@ xrdp_painter_copy(struct xrdp_painter *self,
|
||||
while (i < (srcx + cx))
|
||||
{
|
||||
w = MIN(64, ((srcx + cx) - i));
|
||||
h = MIN(63, ((srcy + cy) - j));
|
||||
h = MIN(64, ((srcy + cy) - j));
|
||||
b = xrdp_bitmap_create(w, h, src->bpp, 0, self->wm);
|
||||
#if 1
|
||||
xrdp_bitmap_copy_box_with_crc(src, b, i, j, w, h);
|
||||
@ -883,7 +1360,7 @@ xrdp_painter_copy(struct xrdp_painter *self,
|
||||
i += 64;
|
||||
}
|
||||
|
||||
j += 63;
|
||||
j += 64;
|
||||
}
|
||||
|
||||
xrdp_region_delete(region);
|
||||
@ -918,11 +1395,18 @@ xrdp_painter_composite(struct xrdp_painter* self,
|
||||
int cache_srcidx;
|
||||
int cache_mskidx;
|
||||
|
||||
LLOGLN(0, ("xrdp_painter_composite:"));
|
||||
|
||||
if (self == 0 || src == 0 || dst == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (self->painter != 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* todo data */
|
||||
|
||||
if (dst->type == WND_TYPE_BITMAP)
|
||||
@ -985,10 +1469,75 @@ xrdp_painter_line(struct xrdp_painter *self,
|
||||
int dy;
|
||||
int rop;
|
||||
|
||||
LLOGLN(10, ("xrdp_painter_line:"));
|
||||
if (self == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (self->painter != 0)
|
||||
{
|
||||
#if defined(XRDP_PAINTER)
|
||||
int x;
|
||||
int y;
|
||||
int cx;
|
||||
int cy;
|
||||
struct painter_bitmap dst_pb;
|
||||
struct xrdp_bitmap *ldst;
|
||||
|
||||
LLOGLN(10, ("xrdp_painter_line: dst->type %d", dst->type));
|
||||
LLOGLN(10, ("xrdp_painter_line: self->rop 0x%2.2x", self->rop));
|
||||
|
||||
if (dst->type != WND_TYPE_OFFSCREEN)
|
||||
{
|
||||
LLOGLN(10, ("xrdp_painter_line: using painter"));
|
||||
ldst = self->wm->screen;
|
||||
|
||||
g_memset(&dst_pb, 0, sizeof(dst_pb));
|
||||
dst_pb.format = get_pt_format(self);
|
||||
dst_pb.width = ldst->width;
|
||||
dst_pb.stride_bytes = ldst->line_size;
|
||||
dst_pb.height = ldst->height;
|
||||
dst_pb.data = ldst->data;
|
||||
|
||||
xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy);
|
||||
region = xrdp_region_create(self->wm);
|
||||
x = MIN(x1, x2);
|
||||
y = MIN(y1, y2);
|
||||
cx = g_abs(x1 - x2) + 1;
|
||||
cy = g_abs(y1 - y2) + 1;
|
||||
xrdp_wm_get_vis_region(self->wm, dst, x, y, cx, cy,
|
||||
region, self->clip_children);
|
||||
x1 += dx;
|
||||
y1 += dy;
|
||||
x2 += dx;
|
||||
y2 += dy;
|
||||
k = 0;
|
||||
rop = self->rop;
|
||||
|
||||
painter_set_rop(self->painter, rop);
|
||||
painter_set_fgcolor(self->painter, self->pen.color);
|
||||
while (xrdp_region_get_rect(region, k, &rect) == 0)
|
||||
{
|
||||
if (rect_intersect(&rect, &clip_rect, &draw_rect))
|
||||
{
|
||||
painter_set_clip(self->painter,
|
||||
draw_rect.left, draw_rect.top,
|
||||
draw_rect.right - draw_rect.left,
|
||||
draw_rect.bottom - draw_rect.top);
|
||||
painter_line(self->painter, &dst_pb, x1, y1, x2, x2,
|
||||
self->pen.width, 0);
|
||||
xrdp_painter_add_dirty_rect(self, x, y, cx, cy,
|
||||
&draw_rect);
|
||||
}
|
||||
k++;
|
||||
}
|
||||
painter_clear_clip(self->painter);
|
||||
xrdp_region_delete(region);
|
||||
}
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* todo data */
|
||||
|
||||
|
@ -429,6 +429,9 @@ struct xrdp_painter
|
||||
struct xrdp_session* session;
|
||||
struct xrdp_wm* wm; /* owner */
|
||||
struct xrdp_font* font;
|
||||
void *painter;
|
||||
struct xrdp_region *dirty_region;
|
||||
int begin_end_level;
|
||||
};
|
||||
|
||||
/* window or bitmap */
|
||||
|
@ -834,44 +834,6 @@ xrdp_wm_xor_pat(struct xrdp_wm *self, int x, int y, int cx, int cy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* this don't are about nothing, just copy the bits */
|
||||
/* no clipping rects, no windows in the way, nothing */
|
||||
static int APP_CC
|
||||
xrdp_wm_bitblt(struct xrdp_wm *self,
|
||||
struct xrdp_bitmap *dst, int dx, int dy,
|
||||
struct xrdp_bitmap *src, int sx, int sy,
|
||||
int sw, int sh, int rop)
|
||||
{
|
||||
// int i;
|
||||
// int line_size;
|
||||
// int Bpp;
|
||||
// char* s;
|
||||
// char* d;
|
||||
|
||||
// if (sw <= 0 || sh <= 0)
|
||||
// return 0;
|
||||
if (self->screen == dst && self->screen == src)
|
||||
{
|
||||
/* send a screen blt */
|
||||
// Bpp = (dst->bpp + 7) / 8;
|
||||
// line_size = sw * Bpp;
|
||||
// s = src->data + (sy * src->width + sx) * Bpp;
|
||||
// d = dst->data + (dy * dst->width + dx) * Bpp;
|
||||
// for (i = 0; i < sh; i++)
|
||||
// {
|
||||
// //g_memcpy(d, s, line_size);
|
||||
// s += src->width * Bpp;
|
||||
// d += dst->width * Bpp;
|
||||
// }
|
||||
libxrdp_orders_init(self->session);
|
||||
libxrdp_orders_screen_blt(self->session, dx, dy, sw, sh, sx, sy, rop, 0);
|
||||
libxrdp_orders_send(self->session);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* return true if rect is totally exposed going in reverse z order */
|
||||
/* from wnd up */
|
||||
@ -935,6 +897,7 @@ xrdp_wm_move_window(struct xrdp_wm *self, struct xrdp_bitmap *wnd,
|
||||
|
||||
MAKERECT(rect1, wnd->left, wnd->top, wnd->width, wnd->height);
|
||||
|
||||
self->painter->clip_children = 0;
|
||||
if (xrdp_wm_is_rect_vis(self, wnd, &rect1))
|
||||
{
|
||||
rect2 = rect1;
|
||||
@ -942,10 +905,13 @@ xrdp_wm_move_window(struct xrdp_wm *self, struct xrdp_bitmap *wnd,
|
||||
|
||||
if (xrdp_wm_is_rect_vis(self, wnd, &rect2))
|
||||
{
|
||||
/* if both src and dst are unobscured, we can do a bitblt move */
|
||||
xrdp_wm_bitblt(self, self->screen, wnd->left + dx, wnd->top + dy,
|
||||
self->screen, wnd->left, wnd->top,
|
||||
wnd->width, wnd->height, 0xcc);
|
||||
xrdp_painter_begin_update(self->painter);
|
||||
xrdp_painter_copy(self->painter, self->screen, self->screen,
|
||||
wnd->left + dx, wnd->top + dy,
|
||||
wnd->width, wnd->height,
|
||||
wnd->left, wnd->top);
|
||||
xrdp_painter_end_update(self->painter);
|
||||
|
||||
wnd->left += dx;
|
||||
wnd->top += dy;
|
||||
r = xrdp_region_create(self);
|
||||
@ -960,9 +926,11 @@ xrdp_wm_move_window(struct xrdp_wm *self, struct xrdp_bitmap *wnd,
|
||||
}
|
||||
|
||||
xrdp_region_delete(r);
|
||||
self->painter->clip_children = 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
self->painter->clip_children = 1;
|
||||
|
||||
wnd->left += dx;
|
||||
wnd->top += dy;
|
||||
@ -971,6 +939,7 @@ xrdp_wm_move_window(struct xrdp_wm *self, struct xrdp_bitmap *wnd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
static int APP_CC
|
||||
xrdp_wm_undraw_dragging_box(struct xrdp_wm *self, int do_begin_end)
|
||||
|
Loading…
Reference in New Issue
Block a user