xfreerdp: start using X11-GDI implementation

This commit is contained in:
Marc-André Moreau 2011-08-26 14:48:51 -04:00
parent b0854dd817
commit 43bcfb4a3c
5 changed files with 195 additions and 2 deletions

View File

@ -17,6 +17,8 @@
* limitations under the License. * limitations under the License.
*/ */
#include <freerdp/utils/memory.h>
#include "xf_gdi.h" #include "xf_gdi.h"
static const uint8 xf_rop2_table[] = static const uint8 xf_rop2_table[] =
@ -186,14 +188,55 @@ boolean xf_set_rop3(xfInfo* xfi, int rop3)
return True; return True;
} }
void xf_bitmap_new(xfInfo* xfi, int width, int height, int bpp, uint8* data) Pixmap xf_bitmap_new(xfInfo* xfi, int width, int height, int bpp, uint8* data)
{ {
Pixmap bitmap;
uint8* cdata;
XImage* image;
bitmap = XCreatePixmap(xfi->display, xfi->window->handle, width, height, xfi->depth);
cdata = gdi_image_convert(data, NULL, width, height, bpp, xfi->bpp, xfi->clrconv);
image = XCreateImage(xfi->display, xfi->visual, xfi->depth,
ZPixmap, 0, (char *) cdata, width, height, xfi->scanline_pad, 0);
XPutImage(xfi->display, bitmap, xfi->gc, image, 0, 0, 0, 0, width, height);
XFree(image);
if (cdata != data)
xfree(cdata);
return bitmap;
} }
void xf_gdi_bitmap_update(rdpUpdate* update, BITMAP_UPDATE* bitmap) void xf_gdi_bitmap_update(rdpUpdate* update, BITMAP_UPDATE* bitmap)
{ {
int i;
int x, y;
int w, h;
uint8* data;
XImage* image;
BITMAP_DATA* bmp;
xfInfo* xfi = GET_XFI(update);
for (i = 0; i < bitmap->number; i++)
{
bmp = &bitmap->bitmaps[i];
data = gdi_image_convert(bmp->data, NULL, bmp->width, bmp->height, bmp->bpp, xfi->bpp, xfi->clrconv);
image = XCreateImage(xfi->display, xfi->visual, xfi->depth,
ZPixmap, 0, (char*) data, bmp->width, bmp->height, xfi->scanline_pad, 0);
x = bmp->left;
y = bmp->top;
w = bmp->right - bmp->left + 1;
h = bmp->bottom - bmp->top + 1;
XPutImage(xfi->display, xfi->primary, xfi->gc, image, 0, 0, x, y, w, h);
XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, x, y, w, h, x, y);
}
} }
void xf_gdi_palette_update(rdpUpdate* update, PALETTE_UPDATE* palette) void xf_gdi_palette_update(rdpUpdate* update, PALETTE_UPDATE* palette)
@ -203,12 +246,40 @@ void xf_gdi_palette_update(rdpUpdate* update, PALETTE_UPDATE* palette)
void xf_gdi_set_bounds(rdpUpdate* update, BOUNDS* bounds) void xf_gdi_set_bounds(rdpUpdate* update, BOUNDS* bounds)
{ {
XRectangle clip;
xfInfo* xfi = GET_XFI(update);
if (bounds != NULL)
{
clip.x = bounds->left;
clip.y = bounds->top;
clip.width = bounds->right - bounds->left + 1;
clip.height = bounds->bottom - bounds->top + 1;
XSetClipRectangles(xfi->display, xfi->gc, 0, 0, &clip, 1, YXBanded);
}
else
{
XSetClipMask(xfi->display, xfi->gc, None);
}
} }
void xf_gdi_dstblt(rdpUpdate* update, DSTBLT_ORDER* dstblt) void xf_gdi_dstblt(rdpUpdate* update, DSTBLT_ORDER* dstblt)
{ {
xfInfo* xfi = GET_XFI(update);
xf_set_rop3(xfi, gdi_rop3_code(dstblt->bRop));
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
XFillRectangle(xfi->display, xfi->drawing, xfi->gc,
dstblt->nLeftRect, dstblt->nTopRect,
dstblt->nWidth, dstblt->nHeight);
if (xfi->drawing == xfi->primary)
{
XFillRectangle(xfi->display, xfi->window->handle, xfi->gc,
dstblt->nLeftRect, dstblt->nTopRect,
dstblt->nWidth, dstblt->nHeight);
}
} }
void xf_gdi_patblt(rdpUpdate* update, PATBLT_ORDER* patblt) void xf_gdi_patblt(rdpUpdate* update, PATBLT_ORDER* patblt)
@ -218,17 +289,80 @@ void xf_gdi_patblt(rdpUpdate* update, PATBLT_ORDER* patblt)
void xf_gdi_scrblt(rdpUpdate* update, SCRBLT_ORDER* scrblt) void xf_gdi_scrblt(rdpUpdate* update, SCRBLT_ORDER* scrblt)
{ {
xfInfo* xfi = GET_XFI(update);
xf_set_rop3(xfi, gdi_rop3_code(scrblt->bRop));
XCopyArea(xfi->display, xfi->primary, xfi->drawing, xfi->gc, scrblt->nXSrc, scrblt->nYSrc,
scrblt->nWidth, scrblt->nHeight, scrblt->nLeftRect, scrblt->nTopRect);
if (xfi->drawing == xfi->primary)
{
if (xfi->unobscured)
{
XCopyArea(xfi->display, xfi->window->handle, xfi->window->handle, xfi->gc,
scrblt->nXSrc, scrblt->nYSrc, scrblt->nWidth, scrblt->nHeight,
scrblt->nLeftRect, scrblt->nTopRect);
}
else
{
XSetFunction(xfi->display, xfi->gc, GXcopy);
XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc,
scrblt->nLeftRect, scrblt->nTopRect, scrblt->nWidth, scrblt->nHeight,
scrblt->nLeftRect, scrblt->nTopRect);
}
}
} }
void xf_gdi_opaque_rect(rdpUpdate* update, OPAQUE_RECT_ORDER* opaque_rect) void xf_gdi_opaque_rect(rdpUpdate* update, OPAQUE_RECT_ORDER* opaque_rect)
{ {
uint32 color;
xfInfo* xfi = GET_XFI(update);
color = gdi_color_convert(opaque_rect->color, xfi->srcBpp, xfi->bpp, xfi->clrconv);
XSetFunction(xfi->display, xfi->gc, GXcopy);
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
XSetForeground(xfi->display, xfi->gc, color);
XFillRectangle(xfi->display, xfi->drawing, xfi->gc,
opaque_rect->nLeftRect, opaque_rect->nTopRect,
opaque_rect->nWidth, opaque_rect->nHeight);
if (xfi->drawing == xfi->primary)
{
XFillRectangle(xfi->display, xfi->window->handle, xfi->gc,
opaque_rect->nLeftRect, opaque_rect->nTopRect,
opaque_rect->nWidth, opaque_rect->nHeight);
}
} }
void xf_gdi_multi_opaque_rect(rdpUpdate* update, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect) void xf_gdi_multi_opaque_rect(rdpUpdate* update, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect)
{ {
int i;
uint32 color;
DELTA_RECT* rectangle;
xfInfo* xfi = GET_XFI(update);
color = gdi_color_convert(multi_opaque_rect->color, xfi->srcBpp, xfi->bpp, xfi->clrconv);
XSetFunction(xfi->display, xfi->gc, GXcopy);
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
XSetForeground(xfi->display, xfi->gc, color);
for (i = 1; i < multi_opaque_rect->numRectangles + 1; i++)
{
rectangle = &multi_opaque_rect->rectangles[i];
XFillRectangle(xfi->display, xfi->drawing, xfi->gc,
rectangle->left, rectangle->top,
rectangle->width, rectangle->height);
if (xfi->drawing == xfi->primary)
{
XFillRectangle(xfi->display, xfi->window->handle, xfi->gc,
rectangle->left, rectangle->top,
rectangle->width, rectangle->height);
}
}
} }
void xf_gdi_line_to(rdpUpdate* update, LINE_TO_ORDER* line_to) void xf_gdi_line_to(rdpUpdate* update, LINE_TO_ORDER* line_to)
@ -248,12 +382,28 @@ void xf_gdi_fast_index(rdpUpdate* update, FAST_INDEX_ORDER* fast_index)
void xf_gdi_create_offscreen_bitmap(rdpUpdate* update, CREATE_OFFSCREEN_BITMAP_ORDER* create_offscreen_bitmap) void xf_gdi_create_offscreen_bitmap(rdpUpdate* update, CREATE_OFFSCREEN_BITMAP_ORDER* create_offscreen_bitmap)
{ {
Pixmap surface;
xfInfo* xfi = GET_XFI(update);
surface = xf_bitmap_new(xfi, create_offscreen_bitmap->cx, create_offscreen_bitmap->cy, xfi->bpp, NULL);
offscreen_put(xfi->cache->offscreen, create_offscreen_bitmap->id, (void*) surface);
} }
void xf_gdi_switch_surface(rdpUpdate* update, SWITCH_SURFACE_ORDER* switch_surface) void xf_gdi_switch_surface(rdpUpdate* update, SWITCH_SURFACE_ORDER* switch_surface)
{ {
Pixmap surface;
xfInfo* xfi = GET_XFI(update);
if (switch_surface->bitmapId == SCREEN_BITMAP_SURFACE)
{
xfi->drawing = xfi->primary;
}
else
{
surface = (Pixmap) offscreen_get(xfi->cache->offscreen, switch_surface->bitmapId);
xfi->drawing = surface;
}
} }
void xf_gdi_cache_bitmap_v2(rdpUpdate* update, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2) void xf_gdi_cache_bitmap_v2(rdpUpdate* update, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2)

View File

@ -296,6 +296,14 @@ boolean xf_pre_connect(freerdp* instance)
xf_kbd_init(xfi); xf_kbd_init(xfi);
xfi->clrconv = (HCLRCONV) malloc(sizeof(CLRCONV));
xfi->clrconv->palette = NULL;
xfi->clrconv->alpha = 1;
xfi->clrconv->invert = 0;
xfi->clrconv->rgb555 = 0;
xfi->cache = cache_new(instance->settings);
xfi->xfds = ConnectionNumber(xfi->display); xfi->xfds = ConnectionNumber(xfi->display);
xfi->screen_number = DefaultScreen(xfi->display); xfi->screen_number = DefaultScreen(xfi->display);
xfi->screen = ScreenOfDisplay(xfi->display, xfi->screen_number); xfi->screen = ScreenOfDisplay(xfi->display, xfi->screen_number);
@ -385,7 +393,11 @@ boolean xf_post_connect(freerdp* instance)
gdi_init(instance, CLRCONV_ALPHA | CLRBUF_32BPP); gdi_init(instance, CLRCONV_ALPHA | CLRBUF_32BPP);
gdi = GET_GDI(instance->update); gdi = GET_GDI(instance->update);
//xf_gdi_register_update_callbacks(instance->update); if (instance->settings->sw_gdi != True)
{
xfi->srcBpp = instance->settings->color_depth;
xf_gdi_register_update_callbacks(instance->update);
}
if (xfi->fullscreen) if (xfi->fullscreen)
xfi->decoration = False; xfi->decoration = False;
@ -427,6 +439,7 @@ boolean xf_post_connect(freerdp* instance)
xfi->gc = XCreateGC(xfi->display, DefaultRootWindow(xfi->display), GCGraphicsExposures, &gcv); xfi->gc = XCreateGC(xfi->display, DefaultRootWindow(xfi->display), GCGraphicsExposures, &gcv);
xfi->primary = XCreatePixmap(xfi->display, DefaultRootWindow(xfi->display), xfi->width, xfi->height, xfi->depth); xfi->primary = XCreatePixmap(xfi->display, DefaultRootWindow(xfi->display), xfi->width, xfi->height, xfi->depth);
xfi->drawing = xfi->primary;
XSetForeground(xfi->display, xfi->gc, BlackPixelOfScreen(xfi->screen)); XSetForeground(xfi->display, xfi->gc, BlackPixelOfScreen(xfi->screen));
XFillRectangle(xfi->display, xfi->primary, xfi->gc, 0, 0, xfi->width, xfi->height); XFillRectangle(xfi->display, xfi->primary, xfi->gc, 0, 0, xfi->width, xfi->height);
@ -705,6 +718,8 @@ int main(int argc, char* argv[])
chanman = freerdp_chanman_new(); chanman = freerdp_chanman_new();
SET_CHANMAN(instance, chanman); SET_CHANMAN(instance, chanman);
instance->settings->sw_gdi = False;
if (freerdp_parse_args(instance->settings, argc, argv, if (freerdp_parse_args(instance->settings, argc, argv,
xf_process_plugin_args, chanman, xf_process_ui_args, NULL) < 0) xf_process_plugin_args, chanman, xf_process_ui_args, NULL) < 0)
return 1; return 1;

View File

@ -26,6 +26,7 @@
#include <freerdp/chanman/chanman.h> #include <freerdp/chanman/chanman.h>
#include <freerdp/gdi/gdi.h> #include <freerdp/gdi/gdi.h>
#include <freerdp/rail/rail.h> #include <freerdp/rail/rail.h>
#include <freerdp/cache/cache.h>
typedef struct xf_info xfInfo; typedef struct xf_info xfInfo;
@ -54,9 +55,11 @@ struct xf_info
int depth; int depth;
int width; int width;
int height; int height;
int srcBpp;
Screen* screen; Screen* screen;
XImage* image; XImage* image;
Pixmap primary; Pixmap primary;
Pixmap drawing;
Visual* visual; Visual* visual;
Display* display; Display* display;
Colormap colormap; Colormap colormap;
@ -71,7 +74,9 @@ struct xf_info
xfWorkArea workArea; xfWorkArea workArea;
int current_desktop; int current_desktop;
boolean remote_app; boolean remote_app;
HCLRCONV clrconv;
rdpRail* rail; rdpRail* rail;
rdpCache* cache;
boolean focused; boolean focused;
boolean mouse_active; boolean mouse_active;

View File

@ -176,6 +176,7 @@ struct rdp_settings
{ {
uint16 width; uint16 width;
uint16 height; uint16 height;
boolean sw_gdi;
boolean workarea; boolean workarea;
boolean fullscreen; boolean fullscreen;
boolean decorations; boolean decorations;

View File

@ -211,6 +211,28 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv,
settings->fastpath_input = False; settings->fastpath_input = False;
settings->fastpath_output = False; settings->fastpath_output = False;
} }
else if (strcmp("--gdi", argv[index]) == 0)
{
index++;
if (index == argc)
{
printf("missing GDI backend\n");
return -1;
}
if (strncmp("sw", argv[index], 1) == 0) /* software */
{
settings->sw_gdi = True;
}
else if (strncmp("hw", argv[index], 1) == 0) /* hardware */
{
settings->sw_gdi = False;
}
else
{
printf("unknown GDI backend\n");
return -1;
}
}
else if (strcmp("--rfx", argv[index]) == 0) else if (strcmp("--rfx", argv[index]) == 0)
{ {
settings->rfx_codec = True; settings->rfx_codec = True;