mirror of
https://github.com/FreeRDP/FreeRDP.git
synced 2024-12-04 15:23:32 +08:00
xfreerdp: start using X11-GDI implementation
This commit is contained in:
parent
b0854dd817
commit
43bcfb4a3c
@ -17,6 +17,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <freerdp/utils/memory.h>
|
||||
|
||||
#include "xf_gdi.h"
|
||||
|
||||
static const uint8 xf_rop2_table[] =
|
||||
@ -186,14 +188,55 @@ boolean xf_set_rop3(xfInfo* xfi, int rop3)
|
||||
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)
|
||||
{
|
||||
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)
|
||||
@ -203,12 +246,40 @@ void xf_gdi_palette_update(rdpUpdate* update, PALETTE_UPDATE* palette)
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
@ -218,17 +289,80 @@ void xf_gdi_patblt(rdpUpdate* update, PATBLT_ORDER* patblt)
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
@ -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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
|
@ -296,6 +296,14 @@ boolean xf_pre_connect(freerdp* instance)
|
||||
|
||||
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->screen_number = DefaultScreen(xfi->display);
|
||||
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 = 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)
|
||||
xfi->decoration = False;
|
||||
@ -427,6 +439,7 @@ boolean xf_post_connect(freerdp* instance)
|
||||
|
||||
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->drawing = xfi->primary;
|
||||
|
||||
XSetForeground(xfi->display, xfi->gc, BlackPixelOfScreen(xfi->screen));
|
||||
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();
|
||||
SET_CHANMAN(instance, chanman);
|
||||
|
||||
instance->settings->sw_gdi = False;
|
||||
|
||||
if (freerdp_parse_args(instance->settings, argc, argv,
|
||||
xf_process_plugin_args, chanman, xf_process_ui_args, NULL) < 0)
|
||||
return 1;
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <freerdp/chanman/chanman.h>
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
#include <freerdp/rail/rail.h>
|
||||
#include <freerdp/cache/cache.h>
|
||||
|
||||
typedef struct xf_info xfInfo;
|
||||
|
||||
@ -54,9 +55,11 @@ struct xf_info
|
||||
int depth;
|
||||
int width;
|
||||
int height;
|
||||
int srcBpp;
|
||||
Screen* screen;
|
||||
XImage* image;
|
||||
Pixmap primary;
|
||||
Pixmap drawing;
|
||||
Visual* visual;
|
||||
Display* display;
|
||||
Colormap colormap;
|
||||
@ -71,7 +74,9 @@ struct xf_info
|
||||
xfWorkArea workArea;
|
||||
int current_desktop;
|
||||
boolean remote_app;
|
||||
HCLRCONV clrconv;
|
||||
rdpRail* rail;
|
||||
rdpCache* cache;
|
||||
|
||||
boolean focused;
|
||||
boolean mouse_active;
|
||||
|
@ -176,6 +176,7 @@ struct rdp_settings
|
||||
{
|
||||
uint16 width;
|
||||
uint16 height;
|
||||
boolean sw_gdi;
|
||||
boolean workarea;
|
||||
boolean fullscreen;
|
||||
boolean decorations;
|
||||
|
@ -211,6 +211,28 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv,
|
||||
settings->fastpath_input = 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)
|
||||
{
|
||||
settings->rfx_codec = True;
|
||||
|
Loading…
Reference in New Issue
Block a user