diff options
author | Jay Sorg <jay.sorg@gmail.com> | 2012-05-17 18:48:28 -0700 |
---|---|---|
committer | Jay Sorg <jay.sorg@gmail.com> | 2012-05-17 18:48:28 -0700 |
commit | cc3754a2bdd6801179751d45f1df3b5816e189fc (patch) | |
tree | 21403a46563d5d5ea12e099e708c59213510718e /xrdp | |
parent | da658dc1b4147c3d928ed2e13bef26280d64cd03 (diff) | |
download | xrdp-proprietary-cc3754a2bdd6801179751d45f1df3b5816e189fc.tar.gz xrdp-proprietary-cc3754a2bdd6801179751d45f1df3b5816e189fc.zip |
xorg: work on offscreen bitmaps
Diffstat (limited to 'xrdp')
-rw-r--r-- | xrdp/xrdp.h | 15 | ||||
-rw-r--r-- | xrdp/xrdp_cache.c | 4 | ||||
-rw-r--r-- | xrdp/xrdp_mm.c | 138 | ||||
-rw-r--r-- | xrdp/xrdp_painter.c | 185 | ||||
-rw-r--r-- | xrdp/xrdp_types.h | 13 | ||||
-rw-r--r-- | xrdp/xrdp_wm.c | 2 |
6 files changed, 314 insertions, 43 deletions
diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h index 14be3767..e295408c 100644 --- a/xrdp/xrdp.h +++ b/xrdp/xrdp.h @@ -64,7 +64,8 @@ int APP_CC xrdp_cache_reset(struct xrdp_cache* self, struct xrdp_client_info* client_info); int APP_CC -xrdp_cache_add_bitmap(struct xrdp_cache* self, struct xrdp_bitmap* bitmap); +xrdp_cache_add_bitmap(struct xrdp_cache* self, struct xrdp_bitmap* bitmap, + int hints); int APP_CC xrdp_cache_add_palette(struct xrdp_cache* self, int* palette); int APP_CC @@ -422,3 +423,15 @@ int DEFAULT_CC server_send_to_channel(struct xrdp_mod* mod, int channel_id, char* data, int data_len, int total_data_len, int flags); +int DEFAULT_CC +server_create_os_surface(struct xrdp_mod* mod, int id, + int width, int height); +int DEFAULT_CC +server_switch_os_surface(struct xrdp_mod* mod, int id); +int DEFAULT_CC +server_delete_os_surface(struct xrdp_mod* mod, int id); +int DEFAULT_CC +server_paint_rect_os(struct xrdp_mod* mod, int x, int y, int cx, int cy, + int id, int srcx, int srcy); +int DEFAULT_CC +server_set_hints(struct xrdp_mod* mod, int hints, int mask); diff --git a/xrdp/xrdp_cache.c b/xrdp/xrdp_cache.c index 88180491..a63a8210 100644 --- a/xrdp/xrdp_cache.c +++ b/xrdp/xrdp_cache.c @@ -73,6 +73,7 @@ xrdp_cache_delete(struct xrdp_cache* self) g_free(self->char_items[i][j].font_item.data); } } + /* free all the off screen bitmaps */ for (i = 0; i < 2000; i++) { xrdp_bitmap_delete(self->os_bitmap_items[i].bitmap); @@ -131,7 +132,8 @@ xrdp_cache_reset(struct xrdp_cache* self, /*****************************************************************************/ /* returns cache id */ int APP_CC -xrdp_cache_add_bitmap(struct xrdp_cache* self, struct xrdp_bitmap* bitmap) +xrdp_cache_add_bitmap(struct xrdp_cache* self, struct xrdp_bitmap* bitmap, + int hints) { int i = 0; int j = 0; diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index a41208eb..f0ecc249 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -351,6 +351,11 @@ xrdp_mm_setup_mod1(struct xrdp_mm* self) self->mod->server_query_channel = server_query_channel; self->mod->server_get_channel_id = server_get_channel_id; self->mod->server_send_to_channel = server_send_to_channel; + self->mod->server_create_os_surface = server_create_os_surface; + self->mod->server_switch_os_surface = server_switch_os_surface; + self->mod->server_delete_os_surface = server_delete_os_surface; + self->mod->server_paint_rect_os = server_paint_rect_os; + self->mod->server_set_hints = server_set_hints; } } /* id self->mod is null, there must be a problem */ @@ -1223,7 +1228,7 @@ server_fill_rect(struct xrdp_mod* mod, int x, int y, int cx, int cy) return 0; } wm = (struct xrdp_wm*)(mod->wm); - xrdp_painter_fill_rect(p, wm->screen, x, y, cx, cy); + xrdp_painter_fill_rect(p, wm->target_surface, x, y, cx, cy); return 0; } @@ -1242,7 +1247,7 @@ server_screen_blt(struct xrdp_mod* mod, int x, int y, int cx, int cy, } wm = (struct xrdp_wm*)(mod->wm); p->rop = 0xcc; - xrdp_painter_copy(p, wm->screen, wm->screen, x, y, cx, cy, srcx, srcy); + xrdp_painter_copy(p, wm->screen, wm->target_surface, x, y, cx, cy, srcx, srcy); return 0; } @@ -1262,7 +1267,7 @@ server_paint_rect(struct xrdp_mod* mod, int x, int y, int cx, int cy, } wm = (struct xrdp_wm*)(mod->wm); b = xrdp_bitmap_create_with_data(width, height, wm->screen->bpp, data, wm); - xrdp_painter_copy(p, b, wm->screen, x, y, cx, cy, srcx, srcy); + xrdp_painter_copy(p, b, wm->target_surface, x, y, cx, cy, srcx, srcy); xrdp_bitmap_delete(b); return 0; } @@ -1453,7 +1458,7 @@ server_draw_line(struct xrdp_mod* mod, int x1, int y1, int x2, int y2) return 0; } wm = (struct xrdp_wm*)(mod->wm); - return xrdp_painter_line(p, wm->screen, x1, y1, x2, y2); + return xrdp_painter_line(p, wm->target_surface, x1, y1, x2, y2); } /*****************************************************************************/ @@ -1492,7 +1497,7 @@ server_draw_text(struct xrdp_mod* mod, int font, return 0; } wm = (struct xrdp_wm*)(mod->wm); - return xrdp_painter_draw_text2(p, wm->screen, font, flags, + return xrdp_painter_draw_text2(p, wm->target_surface, font, flags, mixmode, clip_left, clip_top, clip_right, clip_bottom, box_left, box_top, @@ -1586,3 +1591,126 @@ server_send_to_channel(struct xrdp_mod* mod, int channel_id, return libxrdp_send_to_channel(wm->session, channel_id, data, data_len, total_data_len, flags); } + +/*****************************************************************************/ +int DEFAULT_CC +server_create_os_surface(struct xrdp_mod* mod, int id, + int width, int height) +{ + struct xrdp_wm* wm; + struct xrdp_bitmap* bitmap; + int index; + + //g_writeln("server_create_os_surface: id 0x%x, width %d height %d", + // id, width, height); + wm = (struct xrdp_wm*)(mod->wm); + bitmap = xrdp_bitmap_create(width, height, wm->screen->bpp, + WND_TYPE_OFFSCREEN, wm); + bitmap->id = id; + index = xrdp_cache_add_os_bitmap(wm->cache, bitmap, id); + if (index < 0) + { + g_writeln("server_create_os_surface: xrdp_cache_add_os_bitmap failed"); + return 1; + } + bitmap->item_index = index; + return 0; +} + +/*****************************************************************************/ +int DEFAULT_CC +server_switch_os_surface(struct xrdp_mod* mod, int id) +{ + struct xrdp_wm* wm; + struct xrdp_os_bitmap_item* bi; + + //g_writeln("server_switch_os_surface: id 0x%x", id); + wm = (struct xrdp_wm*)(mod->wm); + if (id == -1) + { + //g_writeln("server_switch_os_surface: setting target_surface to screen"); + wm->target_surface = wm->screen; + return 0; + } + bi = xrdp_cache_get_os_bitmap(wm->cache, id); + if (bi != 0) + { + //g_writeln("server_switch_os_surface: setting target_surface to rdpid %d", id); + wm->target_surface = bi->bitmap; + } + else + { + g_writeln("server_switch_os_surface: error finding id 0x%x", id); + } + return 0; +} + +/*****************************************************************************/ +int DEFAULT_CC +server_delete_os_surface(struct xrdp_mod* mod, int id) +{ + struct xrdp_wm* wm; + + //g_writeln("server_delete_os_surface: id 0x%x", id); + wm = (struct xrdp_wm*)(mod->wm); + if (wm->target_surface->type == WND_TYPE_OFFSCREEN) + { + if (wm->target_surface->id == id) + { + g_writeln("server_delete_os_surface: setting target_surface to screen"); + wm->target_surface = wm->screen; + } + } + xrdp_cache_remove_os_bitmap(wm->cache, id); + return 0; +} + +/*****************************************************************************/ +int DEFAULT_CC +server_paint_rect_os(struct xrdp_mod* mod, int x, int y, int cx, int cy, + int id, int srcx, int srcy) +{ + struct xrdp_wm* wm; + struct xrdp_bitmap* b; + 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); + bi = xrdp_cache_get_os_bitmap(wm->cache, id); + if (bi != 0) + { + b = bi->bitmap; + xrdp_painter_copy(p, b, wm->target_surface, x, y, cx, cy, srcx, srcy); + } + else + { + g_writeln("server_paint_rect_os: error finding id 0x%x", id); + } + return 0; +} + +/*****************************************************************************/ +int DEFAULT_CC +server_set_hints(struct xrdp_mod* mod, int hints, int mask) +{ + struct xrdp_wm* wm; + + wm = (struct xrdp_wm*)(mod->wm); + if (mask & 1) + { + if (hints & 1) + { + wm->hints |= 1; + } + else + { + wm->hints &= ~1; + } + } + return 0; +} diff --git a/xrdp/xrdp_painter.c b/xrdp/xrdp_painter.c index 38644ae1..117d68a4 100644 --- a/xrdp/xrdp_painter.c +++ b/xrdp/xrdp_painter.c @@ -14,7 +14,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 + Copyright (C) Jay Sorg 2004-2012 painter, gc @@ -51,11 +51,42 @@ xrdp_painter_delete(struct xrdp_painter* self) int APP_CC xrdp_painter_begin_update(struct xrdp_painter* self) { + int surface_index; + if (self == 0) { return 0; } libxrdp_orders_init(self->session); + + if (self->wm->target_surface->type == WND_TYPE_SCREEN) + { + if (self->wm->current_surface_index != 0xffff) + { + libxrdp_orders_send_switch_os_surface(self->session, 0xffff); + self->wm->current_surface_index = 0xffff; + } + } + else if (self->wm->target_surface->type == WND_TYPE_OFFSCREEN) + { + surface_index = self->wm->target_surface->item_index; + if (surface_index != self->wm->current_surface_index) + { + if (self->wm->target_surface->tab_stop == 0) /* tab_stop is hack */ + { + libxrdp_orders_send_create_os_surface(self->session, surface_index, + self->wm->target_surface->width, + self->wm->target_surface->height); + self->wm->target_surface->tab_stop = 1; + } + libxrdp_orders_send_switch_os_surface(self->session, surface_index); + self->wm->current_surface_index = surface_index; + } + } + else + { + g_writeln("xrdp_painter_begin_update: bad target_surface"); + } return 0; } @@ -271,7 +302,7 @@ xrdp_painter_setup_brush(struct xrdp_painter* self, /* 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, + struct xrdp_bitmap* dst, int x, int y, int cx, int cy) { struct xrdp_rect clip_rect; @@ -291,14 +322,21 @@ xrdp_painter_fill_rect(struct xrdp_painter* self, /* todo data */ - if (bitmap->type == WND_TYPE_BITMAP) /* 0 */ + if (dst->type == WND_TYPE_BITMAP) /* 0 */ { return 0; } - xrdp_bitmap_get_screen_clip(bitmap, self, &clip_rect, &dx, &dy); + xrdp_bitmap_get_screen_clip(dst, 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); + if (dst->type != WND_TYPE_OFFSCREEN) + { + xrdp_wm_get_vis_region(self->wm, dst, x, y, cx, cy, region, + self->clip_children); + } + else + { + xrdp_region_add_rect(region, &clip_rect); + } x += dx; y += dy; if (self->mix_mode == 0 && self->rop == 0xcc) @@ -372,7 +410,7 @@ xrdp_painter_fill_rect(struct xrdp_painter* self, /*****************************************************************************/ int APP_CC xrdp_painter_draw_text(struct xrdp_painter* self, - struct xrdp_bitmap* bitmap, + struct xrdp_bitmap* dst, int x, int y, const char* text) { int i; @@ -409,7 +447,7 @@ xrdp_painter_draw_text(struct xrdp_painter* self, /* todo data */ - if (bitmap->type == 0) + if (dst->type == 0) { return 0; } @@ -439,10 +477,17 @@ 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); + xrdp_bitmap_get_screen_clip(dst, 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); + if (dst->type != WND_TYPE_OFFSCREEN) + { + xrdp_wm_get_vis_region(self->wm, dst, x, y, total_width, total_height, + region, self->clip_children); + } + else + { + xrdp_region_add_rect(region, &clip_rect); + } x += dx; y += dy; k = 0; @@ -470,7 +515,7 @@ xrdp_painter_draw_text(struct xrdp_painter* self, /*****************************************************************************/ int APP_CC xrdp_painter_draw_text2(struct xrdp_painter* self, - struct xrdp_bitmap* bitmap, + struct xrdp_bitmap* dst, int font, int flags, int mixmode, int clip_left, int clip_top, int clip_right, int clip_bottom, @@ -493,24 +538,32 @@ xrdp_painter_draw_text2(struct xrdp_painter* self, /* todo data */ - if (bitmap->type == WND_TYPE_BITMAP) + if (dst->type == WND_TYPE_BITMAP) { return 0; } - xrdp_bitmap_get_screen_clip(bitmap, self, &clip_rect, &dx, &dy); + xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy); region = xrdp_region_create(self->wm); - if (box_right - box_left > 1) + if (dst->type != WND_TYPE_OFFSCREEN) { - xrdp_wm_get_vis_region(self->wm, bitmap, box_left, box_top, - box_right - box_left, box_bottom - box_top, - region, self->clip_children); + if (box_right - box_left > 1) + { + xrdp_wm_get_vis_region(self->wm, dst, box_left, box_top, + box_right - box_left, box_bottom - box_top, + region, self->clip_children); + } + else + { + xrdp_wm_get_vis_region(self->wm, dst, clip_left, clip_top, + clip_right - clip_left, clip_bottom - clip_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); + xrdp_region_add_rect(region, &clip_rect); } + clip_left += dx; clip_top += dy; clip_right += dx; @@ -577,12 +630,19 @@ xrdp_painter_copy(struct xrdp_painter* self, { return 0; } - if (src == dst && src->wm->screen == src) + if (src->type == WND_TYPE_SCREEN) { 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); + if (dst->type != WND_TYPE_OFFSCREEN) + { + xrdp_wm_get_vis_region(self->wm, dst, x, y, cx, cy, + region, self->clip_children); + } + else + { + xrdp_region_add_rect(region, &clip_rect); + } x += dx; y += dy; srcx += dx; @@ -599,13 +659,61 @@ xrdp_painter_copy(struct xrdp_painter* self, } xrdp_region_delete(region); } + else if (src->type == WND_TYPE_OFFSCREEN) + { + //g_writeln("xrdp_painter_copy: todo"); + + xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy); + region = xrdp_region_create(self->wm); + if (dst->type != WND_TYPE_OFFSCREEN) + { + g_writeln("off screen to screen"); + xrdp_wm_get_vis_region(self->wm, dst, x, y, cx, cy, + region, self->clip_children); + } + else + { + g_writeln("off screen to off screen"); + xrdp_region_add_rect(region, &clip_rect); + } + x += dx; + y += dy; + + palette_id = 0; + cache_id = 255; // todo + cache_idx = src->item_index; // todo + + k = 0; + while (xrdp_region_get_rect(region, k, &rect1) == 0) + { + if (rect_intersect(&rect1, &clip_rect, &rect2)) + { + MAKERECT(rect1, x, y, cx, cy); + if (rect_intersect(&rect2, &rect1, &draw_rect)) + { + libxrdp_orders_mem_blt(self->session, cache_id, palette_id, + x, y, cx, cy, self->rop, srcx, srcy, + cache_idx, &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); + if (dst->type != WND_TYPE_OFFSCREEN) + { + xrdp_wm_get_vis_region(self->wm, dst, x, y, cx, cy, + region, self->clip_children); + } + else + { + xrdp_region_add_rect(region, &clip_rect); + } x += dx; y += dy; palette_id = 0; @@ -615,11 +723,11 @@ xrdp_painter_copy(struct xrdp_painter* self, i = srcx; while (i < (srcx + cx)) { - w = MIN(64, (srcx + cx) - i); - h = MIN(64, (srcy + cy) - j); + w = MIN(64, ((srcx + cx) - i)); + h = MIN(64, ((srcy + cy) - 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); + bitmap_id = xrdp_cache_add_bitmap(self->wm->cache, b, self->wm->hints); cache_id = HIWORD(bitmap_id); cache_idx = LOWORD(bitmap_id); dstx = (x + i) - srcx; @@ -651,7 +759,7 @@ xrdp_painter_copy(struct xrdp_painter* self, /*****************************************************************************/ int APP_CC xrdp_painter_line(struct xrdp_painter* self, - struct xrdp_bitmap* bitmap, + struct xrdp_bitmap* dst, int x1, int y1, int x2, int y2) { struct xrdp_rect clip_rect; @@ -670,15 +778,22 @@ xrdp_painter_line(struct xrdp_painter* self, /* todo data */ - if (bitmap->type == WND_TYPE_BITMAP) + if (dst->type == WND_TYPE_BITMAP) { return 0; } - xrdp_bitmap_get_screen_clip(bitmap, self, &clip_rect, &dx, &dy); + xrdp_bitmap_get_screen_clip(dst, 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); + if (dst->type != WND_TYPE_OFFSCREEN) + { + xrdp_wm_get_vis_region(self->wm, dst, MIN(x1, x2), MIN(y1, y2), + g_abs(x1 - x2) + 1, g_abs(y1 - y2) + 1, + region, self->clip_children); + } + else + { + xrdp_region_add_rect(region, &clip_rect); + } x1 += dx; y1 += dy; x2 += dx; diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h index 3c5decf6..73bb066c 100644 --- a/xrdp/xrdp_types.h +++ b/xrdp/xrdp_types.h @@ -80,7 +80,15 @@ struct xrdp_mod char* data, int data_len, int total_data_len, int flags); int (*server_bell_trigger)(struct xrdp_mod* v); - long server_dumby[100 - 25]; /* align, 100 minus the number of server + int (*server_create_os_surface)(struct xrdp_mod* v, int id, + int width, int height); + int (*server_switch_os_surface)(struct xrdp_mod* v, int id); + int (*server_delete_os_surface)(struct xrdp_mod* v, int id); + int (*server_paint_rect_os)(struct xrdp_mod* mod, int x, int y, + int cx, int cy, + int id, int srcx, int srcy); + int (*server_set_hints)(struct xrdp_mod* mod, int hints, int mask); + long server_dumby[100 - 30]; /* align, 100 minus the number of server functions above */ /* common */ long handle; /* pointer to self as int */ @@ -274,6 +282,9 @@ struct xrdp_wm struct xrdp_font* default_font; struct xrdp_keymap keymap; int hide_log_window; + struct xrdp_bitmap* target_surface; /* either screen or os surface */ + int current_surface_index; + int hints; }; /* rdp process */ diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c index 7d15c3d0..3f9d3c6e 100644 --- a/xrdp/xrdp_wm.c +++ b/xrdp/xrdp_wm.c @@ -56,6 +56,8 @@ xrdp_wm_create(struct xrdp_process* owner, /* this will use built in keymap or load from file */ get_keymaps(self->session->client_info->keylayout, &(self->keymap)); xrdp_wm_set_login_mode(self, 0); + self->target_surface = self->screen; + self->current_surface_index = 0xffff; /* screen */ return self; } |