diff options
Diffstat (limited to 'xrdp/xrdp_painter.c')
-rw-r--r-- | xrdp/xrdp_painter.c | 598 |
1 files changed, 289 insertions, 309 deletions
diff --git a/xrdp/xrdp_painter.c b/xrdp/xrdp_painter.c index f9e2630b..3800277c 100644 --- a/xrdp/xrdp_painter.c +++ b/xrdp/xrdp_painter.c @@ -132,7 +132,7 @@ int APP_CC xrdp_painter_set_clip(struct xrdp_painter* self, int x, int y, int cx, int cy) { - self->use_clip = 1; + self->use_clip = &self->clip; self->clip.left = x; self->clip.top = y; self->clip.right = x + cx; @@ -175,70 +175,69 @@ xrdp_painter_rop(int rop, int src, int dst) } /*****************************************************************************/ -/* fill in an area of the screen with one color */ int APP_CC -xrdp_painter_fill_rect(struct xrdp_painter* self, - struct xrdp_bitmap* bitmap, - int x, int y, int cx, int cy) +xrdp_painter_text_width(struct xrdp_painter* self, char* text) { - int i; - struct xrdp_region* region; - struct xrdp_rect rect; + int index; + int rv; + int len; + struct xrdp_font_char* font_item; - if (!check_bounds(bitmap, &x, &y, &cx, &cy)) + xrdp_painter_font_needed(self); + if (text == 0) { return 0; } - if (!xrdp_painter_clip_adj(self, &x, &y, &cx, &cy)) + rv = 0; + len = g_strlen(text); + for (index = 0; index < len; index++) { - return 0; + font_item = self->font->font_items + (unsigned char)text[index]; + rv = rv + font_item->incby; } + return rv; +} - /* todo data */ +/*****************************************************************************/ +int APP_CC +xrdp_painter_text_height(struct xrdp_painter* self, char* text) +{ + int index; + int rv; + int len; + struct xrdp_font_char* font_item; - if (bitmap->type == WND_TYPE_BITMAP) /* 0 */ + xrdp_painter_font_needed(self); + if (text == 0) { return 0; } - region = xrdp_region_create(self->wm); - xrdp_wm_get_vis_region(self->wm, bitmap, x, y, cx, cy, region, - self->clip_children); - i = 0; - while (xrdp_region_get_rect(region, i, &rect) == 0) + rv = 0; + len = g_strlen(text); + for (index = 0; index < len; index++) { - if (!ISRECTEMPTY(rect)) - { - DEBUG(("sending rect order %d %d %d %d\n\r", - rect.left, rect.top, - rect.right, rect.bottom)); - libxrdp_orders_rect(self->session, rect.left, rect.top, - rect.right - rect.left, - rect.bottom - rect.top, - self->fg_color, 0); - } - i++; + font_item = self->font->font_items + (unsigned char)text[index]; + rv = MAX(rv, font_item->height); } - xrdp_region_delete(region); - return 0; + return rv; } /*****************************************************************************/ -/* fill in an area of the screen with opcodes and patterns */ -/* todo, this needs work */ +/* fill in an area of the screen with one color */ int APP_CC -xrdp_painter_fill_rect2(struct xrdp_painter* self, - struct xrdp_bitmap* bitmap, - int x, int y, int cx, int cy) +xrdp_painter_fill_rect(struct xrdp_painter* self, + struct xrdp_bitmap* bitmap, + int x, int y, int cx, int cy) { - int i; - struct xrdp_region* region; + struct xrdp_rect clip_rect; + struct xrdp_rect draw_rect; struct xrdp_rect rect; + struct xrdp_region* region; + int k; + int dx; + int dy; - if (!check_bounds(bitmap, &x, &y, &cx, &cy)) - { - return 0; - } - if (!xrdp_painter_clip_adj(self, &x, &y, &cx, &cy)) + if (self == 0) { return 0; } @@ -249,193 +248,52 @@ xrdp_painter_fill_rect2(struct xrdp_painter* self, { return 0; } + xrdp_bitmap_get_screen_clip(bitmap, self, &clip_rect, &dx, &dy); region = xrdp_region_create(self->wm); xrdp_wm_get_vis_region(self->wm, bitmap, x, y, cx, cy, region, self->clip_children); - i = 0; - while (xrdp_region_get_rect(region, i, &rect) == 0) + x += dx; + y += dy; + if (self->mix_mode == 0 && self->rop == 0xcc) { - if (!ISRECTEMPTY(rect)) + k = 0; + while (xrdp_region_get_rect(region, k, &rect) == 0) { - DEBUG(("sending rect2 order %d %d %d %d\n\r", - rect.left, rect.top, - rect.right, rect.bottom)); - libxrdp_orders_pat_blt(self->session, rect.left, rect.top, - rect.right - rect.left, - rect.bottom - rect.top, - self->rop, self->bg_color, self->fg_color, - &self->brush, 0); + if (rect_intersect(&rect, &clip_rect, &draw_rect)) + { + libxrdp_orders_rect(self->session, x, y, cx, cy, + self->fg_color, &draw_rect); + } + k++; } - i++; } - xrdp_region_delete(region); - return 0; -} - -#define SSW 64 -#define SSH 60 - -/*****************************************************************************/ -int APP_CC -xrdp_painter_draw_bitmap(struct xrdp_painter* self, - struct xrdp_bitmap* bitmap, - struct xrdp_bitmap* to_draw, - int x, int y, int cx, int cy) -{ - int i; - int j; - int k; - int w; - int h; - int x1; - int y1; - int ok; - int srcx; - int srcy; - int bitmap_id; - int cache_id; - int cache_idx; - int palette_id; - struct xrdp_region* region; - struct xrdp_rect rect; - struct xrdp_rect rect1; - struct xrdp_rect rect2; - struct xrdp_bitmap* b; - - /* todo data */ - - if (bitmap->type == WND_TYPE_BITMAP) - { - return 0; - } - region = xrdp_region_create(self->wm); - xrdp_wm_get_vis_region(self->wm, bitmap, x, y, cx, cy, region, - self->clip_children); - b = bitmap; - while (b != 0) - { - x = x + b->left; - y = y + b->top; - b = b->parent; - } - if (self->wm->client_info->use_bitmap_cache) + else if (self->mix_mode == 0 && + ((self->rop & 0xf) == 0x0 || /* black */ + (self->rop & 0xf) == 0xf || /* white */ + (self->rop & 0xf) == 0x5)) /* DSTINVERT */ { - /*palette_id = xrdp_cache_add_palette(self->wm->cache, self->wm->palette);*/ - palette_id = 0; - j = 0; - while (j < to_draw->height) + k = 0; + while (xrdp_region_get_rect(region, k, &rect) == 0) { - i = 0; - while (i < to_draw->width) + if (rect_intersect(&rect, &clip_rect, &draw_rect)) { - x1 = x + i; - y1 = y + j; - w = MIN(SSW, to_draw->width - i); - h = MIN(SSH, to_draw->height - j); - b = xrdp_bitmap_create(w, h, self->wm->screen->bpp, 0, self->wm); -#ifdef USE_CRC - xrdp_bitmap_copy_box_with_crc(to_draw, b, i, j, w, h); -#else - xrdp_bitmap_copy_box(to_draw, b, i, j, w, h); -#endif - bitmap_id = xrdp_cache_add_bitmap(self->wm->cache, b); - cache_id = HIWORD(bitmap_id); - cache_idx = LOWORD(bitmap_id); - k = 0; - while (xrdp_region_get_rect(region, k, &rect) == 0) - { - if (!ISRECTEMPTY(rect)) - { - MAKERECT(rect1, x1, y1, w, h); - if (rect_intersect(&rect, &rect1, &rect2)) - { - ok = 1; - if (self->use_clip) - { - rect = self->clip; - RECTOFFSET(rect, x, y); - if (!rect_intersect(&rect2, &rect, &rect1)) - { - ok = 0; - } - } - else - { - rect1 = rect2; - } - if (ok) - { - rect1.right--; - rect1.bottom--; - /* check these so ms client don't crash */ - if (x1 + w >= self->wm->screen->width) - { - w = self->wm->screen->width - x1; - } - if (y1 + h >= self->wm->screen->height) - { - h = self->wm->screen->height - y1; - } - if (w > 0 && h > 0 && x1 + w > 0 && y1 + h > 0) - { - srcx = 0; - srcy = 0; - if (x1 < 0) - { - w = w + x1; - srcx = srcx - x1; - x1 = 0; - } - if (y1 < 0) - { - h = h + y1; - srcy = srcy - y1; - y1 = 0; - } - //g_printf("%d %d %d %d %d %d\n", x1, y1, w, h, srcx, srcy); - DEBUG(("sending memblt order \n\r\ - cache_id %d\n\r\ - palette_id %d\n\r\ - x %d\n\r\ - y %d\n\r\ - cx %d\n\r\ - cy %d\n\r\ - rop %d\n\r\ - srcx %d\n\r\ - srcy %d\n\r\ - cache_idx %d\n\r", - cache_id, palette_id, - x1, y1, w, h, self->rop, srcx, srcy, - cache_idx)); - libxrdp_orders_mem_blt(self->session, cache_id, palette_id, - x1, y1, w, h, self->rop, srcx, srcy, - cache_idx, &rect1); - } - } - } - } - k++; - } - i += SSW; + libxrdp_orders_dest_blt(self->session, x, y, cx, cy, + self->rop, &draw_rect); } - j += SSH; + k++; } } - else /* no bitmap cache */ + else { - /* make sure there is no waiting orders */ - libxrdp_orders_force_send(self->session); k = 0; while (xrdp_region_get_rect(region, k, &rect) == 0) { - x1 = rect.left; - y1 = rect.top; - w = rect.right - rect.left; - h = rect.bottom - rect.top; - b = xrdp_bitmap_create(w, h, self->wm->screen->bpp, 0, self->wm); - xrdp_bitmap_copy_box(to_draw, b, x1 - x, y1 - y, w, h); - xrdp_wm_send_bitmap(self->wm, b, x1, y1, w, h); - xrdp_bitmap_delete(b); + if (rect_intersect(&rect, &clip_rect, &draw_rect)) + { + libxrdp_orders_pat_blt(self->session, x, y, cx, cy, + self->rop, self->bg_color, self->fg_color, + &self->brush, &draw_rect); + } k++; } } @@ -445,54 +303,6 @@ xrdp_painter_draw_bitmap(struct xrdp_painter* self, /*****************************************************************************/ int APP_CC -xrdp_painter_text_width(struct xrdp_painter* self, char* text) -{ - int index; - int rv; - int len; - struct xrdp_font_char* font_item; - - xrdp_painter_font_needed(self); - if (text == 0) - { - return 0; - } - rv = 0; - len = g_strlen(text); - for (index = 0; index < len; index++) - { - font_item = self->font->font_items + (unsigned char)text[index]; - rv = rv + font_item->incby; - } - return rv; -} - -/*****************************************************************************/ -int APP_CC -xrdp_painter_text_height(struct xrdp_painter* self, char* text) -{ - int index; - int rv; - int len; - struct xrdp_font_char* font_item; - - xrdp_painter_font_needed(self); - if (text == 0) - { - return 0; - } - rv = 0; - len = g_strlen(text); - for (index = 0; index < len; index++) - { - font_item = self->font->font_items + (unsigned char)text[index]; - rv = MAX(rv, font_item->height); - } - return rv; -} - -/*****************************************************************************/ -int APP_CC xrdp_painter_draw_text(struct xrdp_painter* self, struct xrdp_bitmap* bitmap, int x, int y, char* text) @@ -508,15 +318,20 @@ xrdp_painter_draw_text(struct xrdp_painter* self, int index; int total_width; int total_height; + int dx; + int dy; char* data; struct xrdp_region* region; struct xrdp_rect rect; struct xrdp_rect clip_rect; struct xrdp_rect draw_rect; - struct xrdp_bitmap* b; struct xrdp_font* font; struct xrdp_font_char* font_item; + if (self == 0) + { + return 0; + } len = g_strlen(text); if (len < 1) { @@ -548,70 +363,103 @@ xrdp_painter_draw_text(struct xrdp_painter* self, total_width += k; total_height = MAX(total_height, font_item->height); } + xrdp_bitmap_get_screen_clip(bitmap, self, &clip_rect, &dx, &dy); region = xrdp_region_create(self->wm); xrdp_wm_get_vis_region(self->wm, bitmap, x, y, total_width, total_height, region, self->clip_children); - b = bitmap; - while (b != 0) + x += dx; + y += dy; + k = 0; + while (xrdp_region_get_rect(region, k, &rect) == 0) { - x = x + b->left; - y = y + b->top; - b = b->parent; + if (rect_intersect(&rect, &clip_rect, &draw_rect)) + { + x1 = x; + y1 = y + total_height; + draw_rect.right--; + draw_rect.bottom--; + flags = 0x03; /* 0x03 0x73; TEXT2_IMPLICIT_X and something else */ + libxrdp_orders_text(self->session, f, flags, 0, + font->color, 0, + x - 1, y - 1, x + total_width, y + total_height, + 0, 0, 0, 0, + x1, y1, data, len * 2, &draw_rect); + } + k++; } - if (self->use_clip) + xrdp_region_delete(region); + g_free(data); + return 0; +} + +/*****************************************************************************/ +int APP_CC +xrdp_painter_draw_text2(struct xrdp_painter* self, + struct xrdp_bitmap* bitmap, + int font, int flags, 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 x, int y, char* data, int data_len) +{ + struct xrdp_rect clip_rect; + struct xrdp_rect draw_rect; + struct xrdp_rect rect; + struct xrdp_region* region; + int k; + int dx; + int dy; + + if (self == 0) { - clip_rect = self->clip; + return 0; } - else + + /* todo data */ + + if (bitmap->type == WND_TYPE_BITMAP) { - MAKERECT(clip_rect, 0, 0, bitmap->width, bitmap->height); + return 0; } - b = bitmap; - while (b != 0) + xrdp_bitmap_get_screen_clip(bitmap, self, &clip_rect, &dx, &dy); + region = xrdp_region_create(self->wm); + if (box_right - box_left > 1) { - RECTOFFSET(clip_rect, b->left, b->top); - b = b->parent; + xrdp_wm_get_vis_region(self->wm, bitmap, box_left, box_top, + box_right - box_left, box_bottom - box_top, + region, self->clip_children); } + else + { + xrdp_wm_get_vis_region(self->wm, bitmap, clip_left, clip_top, + clip_right - clip_left, clip_bottom - clip_top, + region, self->clip_children); + } + clip_left += dx; + clip_top += dy; + clip_right += dx; + clip_bottom += dy; + box_left += dx; + box_top += dy; + box_right += dx; + box_bottom += dy; + x += dx; + y += dy; k = 0; while (xrdp_region_get_rect(region, k, &rect) == 0) { - if (!ISRECTEMPTY(rect)) + if (rect_intersect(&rect, &clip_rect, &draw_rect)) { - if (rect_intersect(&rect, &clip_rect, &draw_rect)) - { - x1 = x; - y1 = y + total_height; - draw_rect.right--; - draw_rect.bottom--; - flags = 0x03; /* 0x03 0x73; TEXT2_IMPLICIT_X and something else */ - DEBUG(("sending text order\n\r\ - font %d\n\r\ - flags %d\n\r\ - mixmode %d\n\r\ - color1 %d\n\r\ - color2 %d\n\r\ - clip box %d %d %d %d\n\r\ - box box %d %d %d %d\n\r\ - x %d\n\r\ - y %d\n\r\ - len %d\n\r\ - rect %d %d %d %d\n\r", - f, flags, 0, font->color, 0, x, y, - x + total_width, y + total_height, - 0, 0, 0, 0, x1, y1, len, - draw_rect.left, draw_rect.top, - draw_rect.right, draw_rect.bottom)); - libxrdp_orders_text(self->session, f, flags, 0, - font->color, 0, - x - 1, y - 1, x + total_width, y + total_height, - 0, 0, 0, 0, - x1, y1, data, len * 2, &draw_rect); - } + libxrdp_orders_text(self->session, font, flags, mixmode, + self->fg_color, self->bg_color, + clip_left, clip_top, clip_right, clip_bottom, + box_left, box_top, box_right, box_bottom, + x, y, data, data_len, &draw_rect); } k++; } xrdp_region_delete(region); - g_free(data); return 0; } @@ -623,6 +471,26 @@ xrdp_painter_copy(struct xrdp_painter* self, int x, int y, int cx, int cy, int srcx, int srcy) { + struct xrdp_rect clip_rect; + struct xrdp_rect draw_rect; + struct xrdp_rect rect1; + struct xrdp_rect rect2; + struct xrdp_region* region; + struct xrdp_bitmap* b; + int i; + int j; + int k; + int dx; + int dy; + int palette_id; + int bitmap_id; + int cache_id; + int cache_idx; + int walkx; + int walky; + int w; + int h; + if (self == 0 || src == 0 || dst == 0) { return 0; @@ -636,8 +504,120 @@ xrdp_painter_copy(struct xrdp_painter* self, } if (src == dst && src->wm->screen == src) { - libxrdp_orders_screen_blt(dst->wm->session, x, y, cx, cy, - srcx, srcy, self->rop, 0); + 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; + srcx += dx; + srcy += dy; + k = 0; + while (xrdp_region_get_rect(region, k, &rect1) == 0) + { + if (rect_intersect(&rect1, &clip_rect, &draw_rect)) + { + libxrdp_orders_screen_blt(self->session, x, y, cx, cy, + srcx, srcy, self->rop, &draw_rect); + } + k++; + } + xrdp_region_delete(region); + } + else if (src->data != 0) + /* todo, the non bitmap cache part is gone, it should be put back */ + { + 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; + palette_id = 0; + j = srcy; + while (j < src->height) + { + i = srcx; + while (i < src->width) + { + walkx = x + i; + walky = y + j; + w = MIN(64, src->width - i); + h = MIN(64, src->height - j); + b = xrdp_bitmap_create(w, h, self->wm->screen->bpp, 0, self->wm); + xrdp_bitmap_copy_box_with_crc(src, b, i, j, w, h); + bitmap_id = xrdp_cache_add_bitmap(self->wm->cache, b); + cache_id = HIWORD(bitmap_id); + cache_idx = LOWORD(bitmap_id); + k = 0; + while (xrdp_region_get_rect(region, k, &rect1) == 0) + { + if (rect_intersect(&rect1, &clip_rect, &rect2)) + { + MAKERECT(rect1, walkx, walky, w, h); + if (rect_intersect(&rect2, &rect1, &draw_rect)) + { + libxrdp_orders_mem_blt(self->session, cache_id, palette_id, + walkx, walky, w, h, self->rop, 0, 0, + cache_idx, &draw_rect); + } + } + k++; + } + i += 64; + } + j += 64; + } + xrdp_region_delete(region); + } + return 0; +} + +/*****************************************************************************/ +int APP_CC +xrdp_painter_line(struct xrdp_painter* self, + struct xrdp_bitmap* bitmap, + int x1, int y1, int x2, int y2) +{ + struct xrdp_rect clip_rect; + struct xrdp_rect draw_rect; + struct xrdp_rect rect; + struct xrdp_region* region; + int k; + int dx; + int dy; + + if (self == 0) + { + return 0; + } + + /* todo data */ + + if (bitmap->type == WND_TYPE_BITMAP) + { + return 0; + } + xrdp_bitmap_get_screen_clip(bitmap, self, &clip_rect, &dx, &dy); + region = xrdp_region_create(self->wm); + xrdp_wm_get_vis_region(self->wm, bitmap, MIN(x1, x2), MIN(y1, y2), + g_abs(x1 - x2) + 1, g_abs(y1 - y2) + 1, + region, self->clip_children); + x1 += dx; + y1 += dy; + x2 += dx; + y2 += dy; + k = 0; + while (xrdp_region_get_rect(region, k, &rect) == 0) + { + if (rect_intersect(&rect, &clip_rect, &draw_rect)) + { + libxrdp_orders_line(self->session, 0, x1, y1, x2, y2, + self->rop, self->bg_color, + &self->pen, &draw_rect); + } + k++; } + xrdp_region_delete(region); return 0; } |