mirror of
https://github.com/FreeRDP/FreeRDP.git
synced 2024-12-05 07:43:58 +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.
|
* 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)
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user