xorg: work on offscreen bitmaps

master
Jay Sorg 13 years ago
parent da658dc1b4
commit cc3754a2bd

@ -429,6 +429,7 @@
#define WND_TYPE_COMBO 7 #define WND_TYPE_COMBO 7
#define WND_TYPE_SPECIAL 8 #define WND_TYPE_SPECIAL 8
#define WND_TYPE_LISTBOX 9 #define WND_TYPE_LISTBOX 9
#define WND_TYPE_OFFSCREEN 10
/* button states */ /* button states */
#define BUTTON_STATE_UP 0 #define BUTTON_STATE_UP 0

@ -754,3 +754,20 @@ libxrdp_orders_send_brush(struct xrdp_session* session,
width, height, bpp, type, size, data, width, height, bpp, type, size, data,
cache_id); cache_id);
} }
/*****************************************************************************/
int EXPORT_CC
libxrdp_orders_send_create_os_surface(struct xrdp_session* session, int id,
int width, int height)
{
return xrdp_orders_send_create_os_surface
((struct xrdp_orders*)(session->orders), id, width, height);
}
/*****************************************************************************/
int EXPORT_CC
libxrdp_orders_send_switch_os_surface(struct xrdp_session* session, int id)
{
return xrdp_orders_send_switch_os_surface
((struct xrdp_orders*)(session->orders), id);
}

@ -176,5 +176,10 @@ int DEFAULT_CC
libxrdp_orders_send_brush(struct xrdp_session* session, libxrdp_orders_send_brush(struct xrdp_session* session,
int width, int height, int bpp, int type, int width, int height, int bpp, int type,
int size, char* data, int cache_id); int size, char* data, int cache_id);
int EXPORT_CC
libxrdp_orders_send_create_os_surface(struct xrdp_session* session, int id,
int width, int height);
int EXPORT_CC
libxrdp_orders_send_switch_os_surface(struct xrdp_session* session, int id);
#endif #endif

@ -1976,7 +1976,7 @@ xrdp_orders_send_create_os_surface(struct xrdp_orders* self, int id,
int order_flags; int order_flags;
int cache_id; int cache_id;
g_writeln("xrdp_orders_send_create_os_surface:"); //g_writeln("xrdp_orders_send_create_os_surface:");
xrdp_orders_check(self, 7); xrdp_orders_check(self, 7);
self->order_count++; self->order_count++;
order_flags = RDP_ORDER_SECONDARY; order_flags = RDP_ORDER_SECONDARY;
@ -1997,7 +1997,7 @@ xrdp_orders_send_switch_os_surface(struct xrdp_orders* self, int id)
int order_flags; int order_flags;
int cache_id; int cache_id;
g_writeln("xrdp_orders_send_switch_os_surface:"); //g_writeln("xrdp_orders_send_switch_os_surface:");
xrdp_orders_check(self, 3); xrdp_orders_check(self, 3);
self->order_count++; self->order_count++;
order_flags = RDP_ORDER_SECONDARY; order_flags = RDP_ORDER_SECONDARY;

@ -136,6 +136,7 @@ struct _rdpScreenInfoRec
ClearToBackgroundProcPtr ClearToBackground; ClearToBackgroundProcPtr ClearToBackground;
ScreenWakeupHandlerProcPtr WakeupHandler; ScreenWakeupHandlerProcPtr WakeupHandler;
CompositeProcPtr Composite; CompositeProcPtr Composite;
GlyphsProcPtr Glyphs;
/* Backing store procedures */ /* Backing store procedures */
RestoreAreasProcPtr RestoreAreas; RestoreAreasProcPtr RestoreAreas;
@ -292,6 +293,11 @@ 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 */
@ -378,6 +384,8 @@ rdpup_delete_os_surface(int rdpid);
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,
int rdpid, int srcx, int srcy); int rdpid, int srcx, int srcy);
void
rdpup_set_hints(int hints, int mask);
#if defined(X_BYTE_ORDER) #if defined(X_BYTE_ORDER)
# if X_BYTE_ORDER == X_LITTLE_ENDIAN # if X_BYTE_ORDER == X_LITTLE_ENDIAN

@ -68,8 +68,15 @@ extern int g_Bpp; /* from rdpmain.c */
extern ScreenPtr g_pScreen; /* from rdpmain.c */ extern ScreenPtr g_pScreen; /* from rdpmain.c */
extern Bool g_wrapPixmap; /* from rdpmain.c */ extern Bool g_wrapPixmap; /* from rdpmain.c */
extern int g_con_number; /* in rdpup.c */
extern int g_connected; /* in rdpup.c */
ColormapPtr g_rdpInstalledColormap; ColormapPtr g_rdpInstalledColormap;
static int g_pixmap_rdpid = 1;
int g_pixmap_byte_total = 0;
int g_pixmap_num_used = 0;
GCFuncs g_rdpGCFuncs = GCFuncs g_rdpGCFuncs =
{ {
rdpValidateGC, rdpChangeGC, rdpCopyGC, rdpDestroyGC, rdpChangeClip, rdpValidateGC, rdpChangeGC, rdpCopyGC, rdpDestroyGC, rdpChangeClip,
@ -395,14 +402,29 @@ rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth,
int org_width; int org_width;
org_width = width; org_width = width;
/* width must be a multiple of 4 in rdp */
width = (width + 3) & ~3; width = (width + 3) & ~3;
LLOGLN(10, ("rdpCreatePixmap: width %d org_width %d", width, org_width)); LLOGLN(10, ("rdpCreatePixmap: width %d org_width %d", width, org_width));
pScreen->CreatePixmap = g_rdpScreen.CreatePixmap; pScreen->CreatePixmap = g_rdpScreen.CreatePixmap;
rv = pScreen->CreatePixmap(pScreen, width, height, depth, usage_hint); rv = pScreen->CreatePixmap(pScreen, width, height, depth, usage_hint);
priv = GETPIXPRIV(rv); priv = GETPIXPRIV(rv);
priv->status = 1; if ((g_rdpScreen.client_info.offscreen_support_level > 0) &&
pScreen->CreatePixmap = rdpCreatePixmap; (rv->drawable.depth == g_rdpScreen.depth) &&
(org_width > 1) && (height > 1) && g_connected)
{
priv->allocBytes = width * height * 4;
g_pixmap_byte_total += priv->allocBytes;
g_pixmap_num_used++;
priv->status = 1;
priv->rdpid = g_pixmap_rdpid;
g_pixmap_rdpid++;
priv->con_number = g_con_number;
rdpup_create_os_surface(priv->rdpid, width, height);
LLOGLN(0, ("rdpCreatePixmap: g_pixmap_byte_total %d g_pixmap_num_used %d",
g_pixmap_byte_total, g_pixmap_num_used));
}
pScreen->ModifyPixmapHeader(rv, org_width, 0, 0, 0, 0, 0); pScreen->ModifyPixmapHeader(rv, org_width, 0, 0, 0, 0, 0);
pScreen->CreatePixmap = rdpCreatePixmap;
return rv; return rv;
} }
@ -414,9 +436,22 @@ rdpDestroyPixmap(PixmapPtr pPixmap)
ScreenPtr pScreen; ScreenPtr pScreen;
rdpPixmapRec* priv; rdpPixmapRec* priv;
//ErrorF("rdpDestroyPixmap:\n"); LLOGLN(10, ("rdpDestroyPixmap:"));
priv = GETPIXPRIV(pPixmap); priv = GETPIXPRIV(pPixmap);
//ErrorF(" refcnt %d\n", pPixmap->refcnt); LLOGLN(10, ("status %d refcnt %d", priv->status, pPixmap->refcnt));
if (pPixmap->refcnt < 2)
{
if (XRDP_IS_OS(priv) && g_connected)
{
g_pixmap_byte_total -= priv->allocBytes;
g_pixmap_num_used--;
LLOGLN(0, ("rdpDestroyPixmap: id 0x%x "
"rdpid 0x%x g_pixmap_byte_total %d g_pixmap_num_used %d",
pPixmap->drawable.id, priv->rdpid,
g_pixmap_byte_total, g_pixmap_num_used));
rdpup_delete_os_surface(priv->rdpid);
}
}
pScreen = pPixmap->drawable.pScreen; pScreen = pPixmap->drawable.pScreen;
pScreen->DestroyPixmap = g_rdpScreen.DestroyPixmap; pScreen->DestroyPixmap = g_rdpScreen.DestroyPixmap;
rv = pScreen->DestroyPixmap(pPixmap); rv = pScreen->DestroyPixmap(pPixmap);
@ -691,51 +726,119 @@ rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
DrawablePtr p; DrawablePtr p;
int j; int j;
int num_clips; int num_clips;
int got_id;
WindowPtr pDstWnd;
PixmapPtr pDstPixmap;
rdpPixmapRec* pDstPriv;
struct image_data id;
DEBUG_OUT_OPS(("in rdpComposite\n")); LLOGLN(10, ("rdpComposite:"));
ps = GetPictureScreen(g_pScreen); ps = GetPictureScreen(g_pScreen);
ps->Composite = g_rdpScreen.Composite; ps->Composite = g_rdpScreen.Composite;
ps->Composite(op, pSrc, pMask, pDst, xSrc, ySrc, ps->Composite(op, pSrc, pMask, pDst, xSrc, ySrc,
xMask, yMask, xDst, yDst, width, height); xMask, yMask, xDst, yDst, width, height);
ps->Composite = rdpComposite;
p = pDst->pDrawable; p = pDst->pDrawable;
if (p->type == DRAWABLE_WINDOW)
got_id = 0;
if (p->type == DRAWABLE_PIXMAP)
{ {
if (pDst->clientClipType == CT_REGION) pDstPixmap = (PixmapPtr)p;
pDstPriv = GETPIXPRIV(pDstPixmap);
if (XRDP_IS_OS(pDstPriv))
{ {
box.x1 = p->x + xDst; rdpup_switch_os_surface(pDstPriv->rdpid);
box.y1 = p->y + yDst; rdpup_get_pixmap_image_rect(pDstPixmap, &id);
box.x2 = box.x1 + width; got_id = 1;
box.y2 = box.y1 + height; }
RegionInit(&reg1, &box, 0); }
RegionInit(&reg2, NullBox, 0); else
RegionCopy(&reg2, pDst->clientClip); {
RegionTranslate(&reg2, p->x + pDst->clipOrigin.x, if (p->type == DRAWABLE_WINDOW)
p->y + pDst->clipOrigin.y); {
RegionIntersect(&reg1, &reg1, &reg2); pDstWnd = (WindowPtr)p;
num_clips = REGION_NUM_RECTS(&reg1); if (pDstWnd->viewable)
if (num_clips > 0)
{ {
rdpup_begin_update(); rdpup_get_screen_image_rect(&id);
for (j = num_clips - 1; j >= 0; j--) got_id = 1;
{
box = REGION_RECTS(&reg1)[j];
rdpup_send_area(0, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
}
rdpup_end_update();
} }
RegionUninit(&reg1);
RegionUninit(&reg2);
} }
else }
if (!got_id)
{
return;
}
if (pDst->clientClipType == CT_REGION)
{
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->clientClip);
RegionTranslate(&reg2, p->x + pDst->clipOrigin.x,
p->y + pDst->clipOrigin.y);
RegionIntersect(&reg1, &reg1, &reg2);
num_clips = REGION_NUM_RECTS(&reg1);
if (num_clips > 0)
{ {
box.x1 = p->x + xDst;
box.y1 = p->y + yDst;
box.x2 = box.x1 + width;
box.y2 = box.y1 + height;
rdpup_begin_update(); rdpup_begin_update();
rdpup_send_area(0, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); 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(); rdpup_end_update();
} }
RegionUninit(&reg1);
RegionUninit(&reg2);
} }
ps->Composite = rdpComposite; else
{
box.x1 = p->x + xDst;
box.y1 = p->y + yDst;
box.x2 = box.x1 + width;
box.y2 = box.y1 + height;
rdpup_begin_update();
rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
rdpup_end_update();
}
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));
if (g_rdpScreen.client_info.jpeg)
{
rdpup_set_hints(1, 1);
}
for (index = 0; index < lists->len; index++)
{
LLOGLN(10, (" index %d size %d refcnt %d width %d height %d",
index, glyphs[index]->size, 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;
if (g_rdpScreen.client_info.jpeg)
{
rdpup_set_hints(0, 1);
}
LLOGLN(10, ("rdpGlyphs: out"));
} }

@ -361,6 +361,8 @@ rdpScreenInit(int index, ScreenPtr pScreen, int argc, char** argv)
if (ps) if (ps)
{ {
g_rdpScreen.Composite = ps->Composite; g_rdpScreen.Composite = ps->Composite;
g_rdpScreen.Glyphs = ps->Glyphs;
} }
pScreen->blackPixel = g_rdpScreen.blackPixel; pScreen->blackPixel = g_rdpScreen.blackPixel;
pScreen->whitePixel = g_rdpScreen.whitePixel; pScreen->whitePixel = g_rdpScreen.whitePixel;
@ -370,6 +372,7 @@ rdpScreenInit(int index, ScreenPtr pScreen, int argc, char** argv)
if (ps) if (ps)
{ {
ps->Composite = rdpComposite; ps->Composite = rdpComposite;
ps->Glyphs = rdpGlyphs;
} }
pScreen->SaveScreen = rdpSaveScreen; pScreen->SaveScreen = rdpSaveScreen;
/* GC procedures */ /* GC procedures */

@ -38,7 +38,8 @@ int g_con_number = 0; /* increments for each connection */
static int g_listen_sck = 0; static int g_listen_sck = 0;
static int g_sck = 0; static int g_sck = 0;
static int g_sck_closed = 0; static int g_sck_closed = 0;
static int g_connected = 0;
int g_connected = 0;
static int g_dis_listen_sck = 0; static int g_dis_listen_sck = 0;
//static int g_dis_sck = 0; //static int g_dis_sck = 0;
@ -65,6 +66,9 @@ extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */
extern int g_use_uds; /* in rdpmain.c */ extern int g_use_uds; /* in rdpmain.c */
extern char g_uds_data[]; /* in rdpmain.c */ extern char g_uds_data[]; /* in rdpmain.c */
extern int g_pixmap_byte_total; /* in rdpdraw.c */
extern int g_pixmap_num_used; /* in rdpdraw.c */
/* /*
0 GXclear, 0 0 GXclear, 0
1 GXnor, DPon 1 GXnor, DPon
@ -189,6 +193,7 @@ rdpup_send_pending(void)
{ {
DEBUG_OUT_UP(("end %d\n", g_count)); DEBUG_OUT_UP(("end %d\n", g_count));
out_uint16_le(g_out_s, 2); out_uint16_le(g_out_s, 2);
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); rdpup_send_msg(g_out_s);
@ -202,16 +207,7 @@ rdpup_send_pending(void)
static CARD32 static CARD32
rdpDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg) rdpDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg)
{ {
if (g_connected && g_begin) rdpup_send_pending();
{
DEBUG_OUT_UP(("end %d\n", g_count));
out_uint16_le(g_out_s, 2);
g_count++;
s_mark_end(g_out_s);
rdpup_send_msg(g_out_s);
}
g_count = 0;
g_begin = 0;
g_scheduled = 0; g_scheduled = 0;
return 0; return 0;
} }
@ -254,6 +250,8 @@ rdpup_recv(char* data, int len)
g_tcp_close(g_sck); g_tcp_close(g_sck);
g_sck = 0; g_sck = 0;
g_sck_closed = 1; g_sck_closed = 1;
g_pixmap_byte_total = 0;
g_pixmap_num_used = 0;
return 1; return 1;
} }
} }
@ -264,6 +262,8 @@ rdpup_recv(char* data, int len)
g_tcp_close(g_sck); g_tcp_close(g_sck);
g_sck = 0; g_sck = 0;
g_sck_closed = 1; g_sck_closed = 1;
g_pixmap_byte_total = 0;
g_pixmap_num_used = 0;
return 1; return 1;
} }
else else
@ -568,7 +568,7 @@ rdpup_get_pixmap_image_rect(PixmapPtr pPixmap, struct image_data* id)
id->height = pPixmap->drawable.height; id->height = pPixmap->drawable.height;
id->bpp = g_rdpScreen.rdp_bpp; id->bpp = g_rdpScreen.rdp_bpp;
id->Bpp = g_rdpScreen.rdp_Bpp; id->Bpp = g_rdpScreen.rdp_Bpp;
id->lineBytes = id->width * id->Bpp; id->lineBytes = pPixmap->devKind;
id->pixels = (char*)(pPixmap->devPrivate.ptr); id->pixels = (char*)(pPixmap->devPrivate.ptr);
} }
@ -1087,11 +1087,13 @@ rdpup_set_cursor(short x, short y, char* cur_data, char* cur_mask)
int int
rdpup_create_os_surface(int rdpid, int width, int height) rdpup_create_os_surface(int rdpid, int width, int height)
{ {
LLOGLN(10, ("rdpup_create_os_surface:"));
if (g_connected) if (g_connected)
{ {
DEBUG_OUT_UP((" rdpup_create_os_surface\n")); DEBUG_OUT_UP((" rdpup_create_os_surface\n"));
rdpup_pre_check(10); rdpup_pre_check(12);
out_uint16_le(g_out_s, 20); out_uint16_le(g_out_s, 20);
out_uint16_le(g_out_s, 12);
g_count++; g_count++;
out_uint32_le(g_out_s, rdpid); out_uint32_le(g_out_s, rdpid);
out_uint16_le(g_out_s, width); out_uint16_le(g_out_s, width);
@ -1112,15 +1114,19 @@ rdpup_switch_os_surface(int rdpid)
return 0; return 0;
} }
g_rdpid = rdpid; g_rdpid = rdpid;
rdpup_send_pending(); rdpup_send_pending(); // TODO: do we need this ?
LLOGLN(0, ("rdpup_switch_os_surface: rdpid %d", rdpid)); // the protocol allows switch the surface anytime
LLOGLN(10, ("rdpup_switch_os_surface: rdpid %d", rdpid));
/* switch surface */ /* switch surface */
out_uint16_le(g_out_s, 21); out_uint16_le(g_out_s, 21);
out_uint16_le(g_out_s, 8);
out_uint32_le(g_out_s, rdpid); out_uint32_le(g_out_s, rdpid);
/* begin update */ /* begin update */
out_uint16_le(g_out_s, 1); out_uint16_le(g_out_s, 1);
out_uint16_le(g_out_s, 4);
g_begin = 1; g_begin = 1;
g_count = 2; g_count = 2;
@ -1132,15 +1138,17 @@ rdpup_switch_os_surface(int rdpid)
int int
rdpup_delete_os_surface(int rdpid) rdpup_delete_os_surface(int rdpid)
{ {
LLOGLN(10, ("rdpup_delete_os_surface: rdpid %d", rdpid));
if (g_connected) if (g_connected)
{ {
DEBUG_OUT_UP((" rdpup_delete_os_surface\n")); LLOGLN(10, ("rdpup_delete_os_surface: rdpid %d", rdpid));
//if (g_current_surface == rdpid) //if (g_current_surface == rdpid)
//{ //{
// g_current_surface = -1; // g_current_surface = -1;
//} //}
rdpup_pre_check(6); rdpup_pre_check(8);
out_uint16_le(g_out_s, 22); out_uint16_le(g_out_s, 22);
out_uint16_le(g_out_s, 8);
g_count++; g_count++;
out_uint32_le(g_out_s, rdpid); out_uint32_le(g_out_s, rdpid);
} }
@ -1149,7 +1157,7 @@ rdpup_delete_os_surface(int rdpid)
/******************************************************************************/ /******************************************************************************/
static int static int
get_single_color(int x, int y, int w, int h) get_single_color(struct image_data* id, int x, int y, int w, int h)
{ {
int rv; int rv;
int i; int i;
@ -1165,8 +1173,8 @@ get_single_color(int x, int y, int w, int h)
{ {
for (i = 0; i < h; i++) for (i = 0; i < h; i++)
{ {
i8 = (unsigned char*)(g_rdpScreen.pfbMemory + i8 = (unsigned char*)(id->pixels +
((y + i) * g_rdpScreen.paddedWidthInBytes) + (x * g_Bpp)); ((y + i) * id->lineBytes) + (x * g_Bpp));
if (i == 0) if (i == 0)
{ {
p = *i8; p = *i8;
@ -1185,8 +1193,8 @@ get_single_color(int x, int y, int w, int h)
{ {
for (i = 0; i < h; i++) for (i = 0; i < h; i++)
{ {
i16 = (unsigned short*)(g_rdpScreen.pfbMemory + i16 = (unsigned short*)(id->pixels +
((y + i) * g_rdpScreen.paddedWidthInBytes) + (x * g_Bpp)); ((y + i) * id->lineBytes) + (x * g_Bpp));
if (i == 0) if (i == 0)
{ {
p = *i16; p = *i16;
@ -1205,8 +1213,8 @@ get_single_color(int x, int y, int w, int h)
{ {
for (i = 0; i < h; i++) for (i = 0; i < h; i++)
{ {
i32 = (unsigned int*)(g_rdpScreen.pfbMemory + i32 = (unsigned int*)(id->pixels +
((y + i) * g_rdpScreen.paddedWidthInBytes) + (x * g_Bpp)); ((y + i) * id->lineBytes) + (x * g_Bpp));
if (i == 0) if (i == 0)
{ {
p = *i32; p = *i32;
@ -1237,12 +1245,20 @@ rdpup_send_area(struct image_data* id, int x, int y, int w, int h)
int lh; int lh;
int lw; int lw;
int size; int size;
struct image_data lid;
LLOGLN(10, ("rdpup_send_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 >= g_rdpScreen.width) if (x >= id->width)
{ {
return; return;
} }
if (y >= g_rdpScreen.height) if (y >= id->height)
{ {
return; return;
} }
@ -1264,13 +1280,13 @@ rdpup_send_area(struct image_data* id, int x, int y, int w, int h)
{ {
return; return;
} }
if (x + w > g_rdpScreen.width) if (x + w > id->width)
{ {
w = g_rdpScreen.width - x; w = id->width - x;
} }
if (y + h > g_rdpScreen.height) if (y + h > id->height)
{ {
h = g_rdpScreen.height - y; h = id->height - y;
} }
DEBUG_OUT_UP(("%d\n", w * h)); DEBUG_OUT_UP(("%d\n", w * h));
if (g_connected && g_begin) if (g_connected && g_begin)
@ -1284,7 +1300,7 @@ rdpup_send_area(struct image_data* id, int x, int y, int w, int h)
{ {
lw = MIN(64, (x + w) - lx); lw = MIN(64, (x + w) - lx);
lh = MIN(64, (y + h) - ly); lh = MIN(64, (y + h) - ly);
single_color = get_single_color(lx, ly, lw, lh); single_color = get_single_color(id, lx, ly, lw, lh);
if (single_color != -1) if (single_color != -1)
{ {
DEBUG_OUT_UP(("%d sending single color\n", g_count)); DEBUG_OUT_UP(("%d sending single color\n", g_count));
@ -1293,7 +1309,7 @@ rdpup_send_area(struct image_data* id, int x, int y, int w, int h)
} }
else else
{ {
size = lw * lh * g_rdpScreen.rdp_Bpp + 24; size = lw * lh * id->Bpp + 24;
rdpup_pre_check(size); rdpup_pre_check(size);
out_uint16_le(g_out_s, 5); out_uint16_le(g_out_s, 5);
out_uint16_le(g_out_s, size); out_uint16_le(g_out_s, size);
@ -1302,13 +1318,13 @@ rdpup_send_area(struct image_data* id, int x, int y, int w, int h)
out_uint16_le(g_out_s, ly); out_uint16_le(g_out_s, ly);
out_uint16_le(g_out_s, lw); out_uint16_le(g_out_s, lw);
out_uint16_le(g_out_s, lh); out_uint16_le(g_out_s, lh);
out_uint32_le(g_out_s, lw * lh * g_rdpScreen.rdp_Bpp); out_uint32_le(g_out_s, lw * lh * id->Bpp);
for (i = 0; i < lh; i++) for (i = 0; i < lh; i++)
{ {
s = (g_rdpScreen.pfbMemory + s = (id->pixels +
((ly + i) * g_rdpScreen.paddedWidthInBytes) + (lx * g_Bpp)); ((ly + i) * id->lineBytes) + (lx * g_Bpp));
convert_pixels(s, g_out_s->p, lw); convert_pixels(s, g_out_s->p, lw);
g_out_s->p += lw * g_rdpScreen.rdp_Bpp; g_out_s->p += lw * id->Bpp;
} }
out_uint16_le(g_out_s, lw); out_uint16_le(g_out_s, lw);
out_uint16_le(g_out_s, lh); out_uint16_le(g_out_s, lh);
@ -1329,8 +1345,9 @@ rdpup_paint_rect_os(int x, int y, int cx, int cy,
{ {
if (g_connected) if (g_connected)
{ {
rdpup_pre_check(18); rdpup_pre_check(20);
out_uint16_le(g_out_s, 23); out_uint16_le(g_out_s, 23);
out_uint16_le(g_out_s, 20);
g_count++; g_count++;
out_uint16_le(g_out_s, x); out_uint16_le(g_out_s, x);
out_uint16_le(g_out_s, y); out_uint16_le(g_out_s, y);
@ -1341,3 +1358,17 @@ rdpup_paint_rect_os(int x, int y, int cx, int cy,
out_uint16_le(g_out_s, srcy); out_uint16_le(g_out_s, srcy);
} }
} }
/******************************************************************************/
void
rdpup_set_hints(int hints, int mask)
{
if (g_connected)
{
rdpup_pre_check(6);
out_uint16_le(g_out_s, 24);
g_count++;
out_uint32_le(g_out_s, hints);
out_uint32_le(g_out_s, mask);
}
}

@ -64,7 +64,8 @@ int APP_CC
xrdp_cache_reset(struct xrdp_cache* self, xrdp_cache_reset(struct xrdp_cache* self,
struct xrdp_client_info* client_info); struct xrdp_client_info* client_info);
int APP_CC 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 int APP_CC
xrdp_cache_add_palette(struct xrdp_cache* self, int* palette); xrdp_cache_add_palette(struct xrdp_cache* self, int* palette);
int APP_CC int APP_CC
@ -422,3 +423,15 @@ int DEFAULT_CC
server_send_to_channel(struct xrdp_mod* mod, int channel_id, server_send_to_channel(struct xrdp_mod* mod, int channel_id,
char* data, int data_len, char* data, int data_len,
int total_data_len, int flags); 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);

@ -73,6 +73,7 @@ xrdp_cache_delete(struct xrdp_cache* self)
g_free(self->char_items[i][j].font_item.data); g_free(self->char_items[i][j].font_item.data);
} }
} }
/* free all the off screen bitmaps */
for (i = 0; i < 2000; i++) for (i = 0; i < 2000; i++)
{ {
xrdp_bitmap_delete(self->os_bitmap_items[i].bitmap); xrdp_bitmap_delete(self->os_bitmap_items[i].bitmap);
@ -131,7 +132,8 @@ xrdp_cache_reset(struct xrdp_cache* self,
/*****************************************************************************/ /*****************************************************************************/
/* returns cache id */ /* returns cache id */
int APP_CC 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 i = 0;
int j = 0; int j = 0;

@ -351,6 +351,11 @@ xrdp_mm_setup_mod1(struct xrdp_mm* self)
self->mod->server_query_channel = server_query_channel; self->mod->server_query_channel = server_query_channel;
self->mod->server_get_channel_id = server_get_channel_id; self->mod->server_get_channel_id = server_get_channel_id;
self->mod->server_send_to_channel = server_send_to_channel; 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 */ /* 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; return 0;
} }
wm = (struct xrdp_wm*)(mod->wm); 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; 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); wm = (struct xrdp_wm*)(mod->wm);
p->rop = 0xcc; 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; 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); wm = (struct xrdp_wm*)(mod->wm);
b = xrdp_bitmap_create_with_data(width, height, wm->screen->bpp, data, 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); xrdp_bitmap_delete(b);
return 0; return 0;
} }
@ -1453,7 +1458,7 @@ server_draw_line(struct xrdp_mod* mod, int x1, int y1, int x2, int y2)
return 0; return 0;
} }
wm = (struct xrdp_wm*)(mod->wm); 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; return 0;
} }
wm = (struct xrdp_wm*)(mod->wm); 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, mixmode, clip_left, clip_top,
clip_right, clip_bottom, clip_right, clip_bottom,
box_left, box_top, 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, return libxrdp_send_to_channel(wm->session, channel_id, data, data_len,
total_data_len, flags); 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;
}

@ -14,7 +14,7 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
xrdp: A Remote Desktop Protocol server. xrdp: A Remote Desktop Protocol server.
Copyright (C) Jay Sorg 2004-2010 Copyright (C) Jay Sorg 2004-2012
painter, gc painter, gc
@ -51,11 +51,42 @@ xrdp_painter_delete(struct xrdp_painter* self)
int APP_CC int APP_CC
xrdp_painter_begin_update(struct xrdp_painter* self) xrdp_painter_begin_update(struct xrdp_painter* self)
{ {
int surface_index;
if (self == 0) if (self == 0)
{ {
return 0; return 0;
} }
libxrdp_orders_init(self->session); 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; return 0;
} }
@ -271,7 +302,7 @@ xrdp_painter_setup_brush(struct xrdp_painter* self,
/* fill in an area of the screen with one color */ /* fill in an area of the screen with one color */
int APP_CC int APP_CC
xrdp_painter_fill_rect(struct xrdp_painter* self, xrdp_painter_fill_rect(struct xrdp_painter* self,
struct xrdp_bitmap* bitmap, struct xrdp_bitmap* dst,
int x, int y, int cx, int cy) int x, int y, int cx, int cy)
{ {
struct xrdp_rect clip_rect; struct xrdp_rect clip_rect;
@ -291,14 +322,21 @@ xrdp_painter_fill_rect(struct xrdp_painter* self,
/* todo data */ /* todo data */
if (bitmap->type == WND_TYPE_BITMAP) /* 0 */ if (dst->type == WND_TYPE_BITMAP) /* 0 */
{ {
return 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); region = xrdp_region_create(self->wm);
xrdp_wm_get_vis_region(self->wm, bitmap, x, y, cx, cy, region, if (dst->type != WND_TYPE_OFFSCREEN)
self->clip_children); {
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; x += dx;
y += dy; y += dy;
if (self->mix_mode == 0 && self->rop == 0xcc) if (self->mix_mode == 0 && self->rop == 0xcc)
@ -372,7 +410,7 @@ xrdp_painter_fill_rect(struct xrdp_painter* self,
/*****************************************************************************/ /*****************************************************************************/
int APP_CC int APP_CC
xrdp_painter_draw_text(struct xrdp_painter* self, xrdp_painter_draw_text(struct xrdp_painter* self,
struct xrdp_bitmap* bitmap, struct xrdp_bitmap* dst,
int x, int y, const char* text) int x, int y, const char* text)
{ {
int i; int i;
@ -409,7 +447,7 @@ xrdp_painter_draw_text(struct xrdp_painter* self,
/* todo data */ /* todo data */
if (bitmap->type == 0) if (dst->type == 0)
{ {
return 0; return 0;
} }
@ -439,10 +477,17 @@ xrdp_painter_draw_text(struct xrdp_painter* self,
total_width += k; total_width += k;
total_height = MAX(total_height, font_item->height); 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); region = xrdp_region_create(self->wm);
xrdp_wm_get_vis_region(self->wm, bitmap, x, y, total_width, total_height, if (dst->type != WND_TYPE_OFFSCREEN)
region, self->clip_children); {
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; x += dx;
y += dy; y += dy;
k = 0; k = 0;
@ -470,7 +515,7 @@ xrdp_painter_draw_text(struct xrdp_painter* self,
/*****************************************************************************/ /*****************************************************************************/
int APP_CC int APP_CC
xrdp_painter_draw_text2(struct xrdp_painter* self, xrdp_painter_draw_text2(struct xrdp_painter* self,
struct xrdp_bitmap* bitmap, struct xrdp_bitmap* dst,
int font, int flags, int mixmode, int font, int flags, int mixmode,
int clip_left, int clip_top, int clip_left, int clip_top,
int clip_right, int clip_bottom, int clip_right, int clip_bottom,
@ -493,24 +538,32 @@ xrdp_painter_draw_text2(struct xrdp_painter* self,
/* todo data */ /* todo data */
if (bitmap->type == WND_TYPE_BITMAP) if (dst->type == WND_TYPE_BITMAP)
{ {
return 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); 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, if (box_right - box_left > 1)
box_right - box_left, box_bottom - box_top, {
region, self->clip_children); 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 else
{ {
xrdp_wm_get_vis_region(self->wm, bitmap, clip_left, clip_top, xrdp_region_add_rect(region, &clip_rect);
clip_right - clip_left, clip_bottom - clip_top,
region, self->clip_children);
} }
clip_left += dx; clip_left += dx;
clip_top += dy; clip_top += dy;
clip_right += dx; clip_right += dx;
@ -577,12 +630,19 @@ xrdp_painter_copy(struct xrdp_painter* self,
{ {
return 0; 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); xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy);
region = xrdp_region_create(self->wm); region = xrdp_region_create(self->wm);
xrdp_wm_get_vis_region(self->wm, dst, x, y, cx, cy, if (dst->type != WND_TYPE_OFFSCREEN)
region, self->clip_children); {
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; x += dx;
y += dy; y += dy;
srcx += dx; srcx += dx;
@ -599,13 +659,61 @@ xrdp_painter_copy(struct xrdp_painter* self,
} }
xrdp_region_delete(region); 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) else if (src->data != 0)
/* todo, the non bitmap cache part is gone, it should be put back */ /* todo, the non bitmap cache part is gone, it should be put back */
{ {
xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy); xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy);
region = xrdp_region_create(self->wm); region = xrdp_region_create(self->wm);
xrdp_wm_get_vis_region(self->wm, dst, x, y, cx, cy, if (dst->type != WND_TYPE_OFFSCREEN)
region, self->clip_children); {
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; x += dx;
y += dy; y += dy;
palette_id = 0; palette_id = 0;
@ -615,11 +723,11 @@ xrdp_painter_copy(struct xrdp_painter* self,
i = srcx; i = srcx;
while (i < (srcx + cx)) while (i < (srcx + cx))
{ {
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, self->wm->screen->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); bitmap_id = xrdp_cache_add_bitmap(self->wm->cache, b, self->wm->hints);
cache_id = HIWORD(bitmap_id); cache_id = HIWORD(bitmap_id);
cache_idx = LOWORD(bitmap_id); cache_idx = LOWORD(bitmap_id);
dstx = (x + i) - srcx; dstx = (x + i) - srcx;
@ -651,7 +759,7 @@ xrdp_painter_copy(struct xrdp_painter* self,
/*****************************************************************************/ /*****************************************************************************/
int APP_CC int APP_CC
xrdp_painter_line(struct xrdp_painter* self, xrdp_painter_line(struct xrdp_painter* self,
struct xrdp_bitmap* bitmap, struct xrdp_bitmap* dst,
int x1, int y1, int x2, int y2) int x1, int y1, int x2, int y2)
{ {
struct xrdp_rect clip_rect; struct xrdp_rect clip_rect;
@ -670,15 +778,22 @@ xrdp_painter_line(struct xrdp_painter* self,
/* todo data */ /* todo data */
if (bitmap->type == WND_TYPE_BITMAP) if (dst->type == WND_TYPE_BITMAP)
{ {
return 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); region = xrdp_region_create(self->wm);
xrdp_wm_get_vis_region(self->wm, bitmap, MIN(x1, x2), MIN(y1, y2), if (dst->type != WND_TYPE_OFFSCREEN)
g_abs(x1 - x2) + 1, g_abs(y1 - y2) + 1, {
region, self->clip_children); 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; x1 += dx;
y1 += dy; y1 += dy;
x2 += dx; x2 += dx;

@ -80,7 +80,15 @@ struct xrdp_mod
char* data, int data_len, char* data, int data_len,
int total_data_len, int flags); int total_data_len, int flags);
int (*server_bell_trigger)(struct xrdp_mod* v); 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 */ functions above */
/* common */ /* common */
long handle; /* pointer to self as int */ long handle; /* pointer to self as int */
@ -274,6 +282,9 @@ struct xrdp_wm
struct xrdp_font* default_font; struct xrdp_font* default_font;
struct xrdp_keymap keymap; struct xrdp_keymap keymap;
int hide_log_window; int hide_log_window;
struct xrdp_bitmap* target_surface; /* either screen or os surface */
int current_surface_index;
int hints;
}; };
/* rdp process */ /* rdp process */

@ -56,6 +56,8 @@ xrdp_wm_create(struct xrdp_process* owner,
/* this will use built in keymap or load from file */ /* this will use built in keymap or load from file */
get_keymaps(self->session->client_info->keylayout, &(self->keymap)); get_keymaps(self->session->client_info->keylayout, &(self->keymap));
xrdp_wm_set_login_mode(self, 0); xrdp_wm_set_login_mode(self, 0);
self->target_surface = self->screen;
self->current_surface_index = 0xffff; /* screen */
return self; return self;
} }

@ -377,6 +377,9 @@ lib_mod_process_orders(struct mod* mod, int type, struct stream* s)
int y1; int y1;
int x2; int x2;
int y2; int y2;
int rdpid;
int hints;
int mask;
int width; int width;
int height; int height;
int fgcolor; int fgcolor;
@ -462,6 +465,36 @@ lib_mod_process_orders(struct mod* mod, int type, struct stream* s)
in_uint8a(s, cur_mask, 32 * (32 / 8)); in_uint8a(s, cur_mask, 32 * (32 / 8));
rv = mod->server_set_cursor(mod, x, y, cur_data, cur_mask); rv = mod->server_set_cursor(mod, x, y, cur_data, cur_mask);
break; break;
case 20:
in_uint32_le(s, rdpid);
in_uint16_le(s, width);
in_uint16_le(s, height);
rv = mod->server_create_os_surface(mod, rdpid, width, height);
break;
case 21:
in_uint32_le(s, rdpid);
rv = mod->server_switch_os_surface(mod, rdpid);
break;
case 22:
in_uint32_le(s, rdpid);
rv = mod->server_delete_os_surface(mod, rdpid);
break;
case 23: /* server_paint_rect_os */
in_sint16_le(s, x);
in_sint16_le(s, y);
in_uint16_le(s, cx);
in_uint16_le(s, cy);
in_uint32_le(s, rdpid);
in_sint16_le(s, srcx);
in_sint16_le(s, srcy);
rv = mod->server_paint_rect_os(mod, x, y, cx, cy,
rdpid, srcx, srcy);
break;
case 24: /* server_set_hints */
in_uint32_le(s, hints);
in_uint32_le(s, mask);
rv = mod->server_set_hints(mod, hints, mask);
break;
default: default:
g_writeln("lib_mod_process_orders: unknown order type %d", type); g_writeln("lib_mod_process_orders: unknown order type %d", type);
rv = 0; rv = 0;

@ -88,7 +88,15 @@ struct mod
char* data, int data_len, char* data, int data_len,
int total_data_len, int flags); int total_data_len, int flags);
int (*server_bell_trigger)(struct mod* v); int (*server_bell_trigger)(struct mod* v);
tbus server_dumby[100 - 25]; /* align, 100 minus the number of server int (*server_create_os_surface)(struct mod* v, int id,
int width, int height);
int (*server_switch_os_surface)(struct mod* v, int id);
int (*server_delete_os_surface)(struct mod* v, int id);
int (*server_paint_rect_os)(struct mod* v, int x, int y,
int cx, int cy,
int id, int srcx, int srcy);
int (*server_set_hints)(struct mod* v, int hints, int mask);
tbus server_dumby[100 - 30]; /* 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