libfreerdp-core: add true asynchronous input and update

This commit is contained in:
Marc-André Moreau 2013-02-06 21:57:49 -05:00
parent 593a9030d3
commit 2d38f99db0
7 changed files with 334 additions and 87 deletions

View File

@ -358,7 +358,7 @@ static BOOL xf_event_KeyRelease(xfInfo* xfi, XEvent* event, BOOL app)
if (XPending(xfi->display))
{
memset(&next_event, 0, sizeof(next_event));
ZeroMemory(&next_event, sizeof(next_event));
XPeekEvent(xfi->display, &next_event);
if (next_event.type == KeyPress)

View File

@ -33,7 +33,8 @@
#include "xf_gdi.h"
static UINT8 GDI_BS_HACHTED_PATTERNS[] = {
static UINT8 GDI_BS_HACHTED_PATTERNS[] =
{
0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, /* HS_HORIZONTAL */
0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, /* HS_VERTICAL */
0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F, /* HS_FDIAGONAL */
@ -262,33 +263,15 @@ Pixmap xf_mono_bitmap_new(xfInfo* xfi, int width, int height, BYTE* data)
return bitmap;
}
Pixmap xf_glyph_new(xfInfo* xfi, int width, int height, BYTE* data)
{
int scanline;
Pixmap bitmap;
XImage* image;
scanline = (width + 7) / 8;
bitmap = XCreatePixmap(xfi->display, xfi->drawable, width, height, 1);
image = XCreateImage(xfi->display, xfi->visual, 1,
ZPixmap, 0, (char*) data, width, height, 8, scanline);
image->byte_order = MSBFirst;
image->bitmap_bit_order = MSBFirst;
XInitImage(image);
XPutImage(xfi->display, bitmap, xfi->gc_mono, image, 0, 0, 0, 0, width, height);
XFree(image);
return bitmap;
}
void xf_gdi_palette_update(rdpContext* context, PALETTE_UPDATE* palette)
{
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
CopyMemory(xfi->clrconv->palette, palette, sizeof(rdpPalette));
ReleaseMutex(xfi->mutex);
}
void xf_gdi_set_bounds(rdpContext* context, rdpBounds* bounds)
@ -296,6 +279,8 @@ void xf_gdi_set_bounds(rdpContext* context, rdpBounds* bounds)
XRectangle clip;
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
if (bounds != NULL)
{
clip.x = bounds->left;
@ -308,12 +293,16 @@ void xf_gdi_set_bounds(rdpContext* context, rdpBounds* bounds)
{
XSetClipMask(xfi->display, xfi->gc, None);
}
ReleaseMutex(xfi->mutex);
}
void xf_gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt)
{
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_set_rop3(xfi, gdi_rop3_code(dstblt->bRop));
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
@ -331,7 +320,10 @@ void xf_gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt)
gdi_InvalidateRegion(xfi->hdc, dstblt->nLeftRect, dstblt->nTopRect, dstblt->nWidth, dstblt->nHeight);
}
XSetFunction(xfi->display, xfi->gc, GXcopy);
ReleaseMutex(xfi->mutex);
}
void xf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
@ -343,6 +335,8 @@ void xf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
brush = &patblt->brush;
xf_set_rop3(xfi, gdi_rop3_code(patblt->bRop));
@ -424,12 +418,16 @@ void xf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
}
XSetFunction(xfi->display, xfi->gc, GXcopy);
ReleaseMutex(xfi->mutex);
}
void xf_gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt)
{
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_set_rop3(xfi, gdi_rop3_code(scrblt->bRop));
XCopyArea(xfi->display, xfi->primary, xfi->drawing, xfi->gc, scrblt->nXSrc, scrblt->nYSrc,
@ -458,6 +456,8 @@ void xf_gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt)
}
XSetFunction(xfi->display, xfi->gc, GXcopy);
ReleaseMutex(xfi->mutex);
}
void xf_gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect)
@ -466,6 +466,8 @@ void xf_gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect)
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
color = freerdp_color_convert_var(opaque_rect->color, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);
XSetFunction(xfi->display, xfi->gc, GXcopy);
@ -487,6 +489,8 @@ void xf_gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect)
gdi_InvalidateRegion(xfi->hdc, opaque_rect->nLeftRect, opaque_rect->nTopRect,
opaque_rect->nWidth, opaque_rect->nHeight);
}
ReleaseMutex(xfi->mutex);
}
void xf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect)
@ -497,6 +501,8 @@ void xf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* mult
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
color = freerdp_color_convert_var(multi_opaque_rect->color, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);
XSetFunction(xfi->display, xfi->gc, GXcopy);
@ -522,6 +528,8 @@ void xf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* mult
gdi_InvalidateRegion(xfi->hdc, rectangle->left, rectangle->top, rectangle->width, rectangle->height);
}
}
ReleaseMutex(xfi->mutex);
}
void xf_gdi_draw_nine_grid(rdpContext* context, DRAW_NINE_GRID_ORDER* draw_nine_grid)
@ -535,6 +543,8 @@ void xf_gdi_line_to(rdpContext* context, LINE_TO_ORDER* line_to)
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_set_rop2(xfi, line_to->bRop2);
color = freerdp_color_convert_var(line_to->penColor, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);
@ -568,6 +578,8 @@ void xf_gdi_line_to(rdpContext* context, LINE_TO_ORDER* line_to)
}
XSetFunction(xfi->display, xfi->gc, GXcopy);
ReleaseMutex(xfi->mutex);
}
void xf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline)
@ -583,6 +595,8 @@ void xf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline)
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_set_rop2(xfi, polyline->bRop2);
color = freerdp_color_convert_var(polyline->penColor, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);
@ -631,6 +645,8 @@ void xf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline)
XSetFunction(xfi->display, xfi->gc, GXcopy);
free(points);
ReleaseMutex(xfi->mutex);
}
void xf_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt)
@ -638,6 +654,8 @@ void xf_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt)
xfBitmap* bitmap;
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
bitmap = (xfBitmap*) memblt->bitmap;
xf_set_rop3(xfi, gdi_rop3_code(memblt->bRop));
@ -658,6 +676,8 @@ void xf_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt)
}
XSetFunction(xfi->display, xfi->gc, GXcopy);
ReleaseMutex(xfi->mutex);
}
void xf_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
@ -670,6 +690,8 @@ void xf_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
brush = &mem3blt->brush;
bitmap = (xfBitmap*) mem3blt->bitmap;
xf_set_rop3(xfi, gdi_rop3_code(mem3blt->bRop));
@ -733,6 +755,8 @@ void xf_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
XFreePixmap(xfi->display, pattern);
XSetFunction(xfi->display, xfi->gc, GXcopy);
ReleaseMutex(xfi->mutex);
}
void xf_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)
@ -742,6 +766,8 @@ void xf_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)
UINT32 brush_color;
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_set_rop2(xfi, polygon_sc->bRop2);
brush_color = freerdp_color_convert_var(polygon_sc->brushColor, ((xfContext*)context)->settings->ColorDepth, xfi->bpp, xfi->clrconv);
@ -786,6 +812,8 @@ void xf_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)
XSetFunction(xfi->display, xfi->gc, GXcopy);
free(points);
ReleaseMutex(xfi->mutex);
}
void xf_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb)
@ -798,6 +826,8 @@ void xf_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb)
UINT32 backColor;
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
brush = &(polygon_cb->brush);
xf_set_rop2(xfi, polygon_cb->bRop2);
foreColor = freerdp_color_convert_var(polygon_cb->foreColor, ((xfContext*) context)->settings->ColorDepth, xfi->bpp, xfi->clrconv);
@ -889,6 +919,8 @@ void xf_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb)
XSetFunction(xfi->display, xfi->gc, GXcopy);
free(points);
ReleaseMutex(xfi->mutex);
}
void xf_gdi_ellipse_sc(rdpContext* context, ELLIPSE_SC_ORDER* ellipse_sc)
@ -908,6 +940,9 @@ void xf_gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surf
xfi = ((xfContext*) context)->xfi;
settings = xfi->instance->settings;
WaitForSingleObject(xfi->mutex, INFINITE);
switch (surface_frame_marker->frameAction)
{
case SURFACECMD_FRAMEACTION_BEGIN:
@ -938,6 +973,8 @@ void xf_gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surf
}
break;
}
ReleaseMutex(xfi->mutex);
}
static void xf_gdi_surface_update_frame(xfInfo* xfi, UINT16 tx, UINT16 ty, UINT16 width, UINT16 height)
@ -983,6 +1020,8 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
RFX_CONTEXT* rfx_context = (RFX_CONTEXT*) xfi->rfx_context;
NSC_CONTEXT* nsc_context = (NSC_CONTEXT*) xfi->nsc_context;
WaitForSingleObject(xfi->mutex, INFINITE);
if (surface_bits_command->codecID == RDP_CODEC_ID_REMOTEFX)
{
message = rfx_process_message(rfx_context,
@ -1024,6 +1063,7 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
{
nsc_process_message(nsc_context, surface_bits_command->bpp, surface_bits_command->width, surface_bits_command->height,
surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);
XSetFunction(xfi->display, xfi->gc, GXcopy);
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
@ -1053,7 +1093,7 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
/* Validate that the data received is large enough */
if( surface_bits_command->width * surface_bits_command->height * surface_bits_command->bpp / 8 <= surface_bits_command->bitmapDataLength )
if ((surface_bits_command->width * surface_bits_command->height * surface_bits_command->bpp / 8) <= (surface_bits_command->bitmapDataLength))
{
xfi->bmp_codec_none = (BYTE*) realloc(xfi->bmp_codec_none,
surface_bits_command->width * surface_bits_command->height * 4);
@ -1074,7 +1114,9 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
surface_bits_command->width, surface_bits_command->height);
XSetClipMask(xfi->display, xfi->gc, None);
} else {
}
else
{
printf("Invalid bitmap size - data is %d bytes for %dx%d\n update", surface_bits_command->bitmapDataLength, surface_bits_command->width, surface_bits_command->height);
}
}
@ -1082,6 +1124,8 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
{
printf("Unsupported codecID %d\n", surface_bits_command->codecID);
}
ReleaseMutex(xfi->mutex);
}
void xf_gdi_register_update_callbacks(rdpUpdate* update)

View File

@ -46,6 +46,8 @@ void xf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap)
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
XSetFunction(xfi->display, xfi->gc, GXcopy);
pixmap = XCreatePixmap(xfi->display, xfi->drawable, bitmap->width, bitmap->height, xfi->depth);
@ -75,14 +77,20 @@ void xf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap)
}
((xfBitmap*) bitmap)->pixmap = pixmap;
ReleaseMutex(xfi->mutex);
}
void xf_Bitmap_Free(rdpContext* context, rdpBitmap* bitmap)
{
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
if (((xfBitmap*) bitmap)->pixmap != 0)
XFreePixmap(xfi->display, ((xfBitmap*) bitmap)->pixmap);
ReleaseMutex(xfi->mutex);
}
void xf_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap)
@ -94,6 +102,8 @@ void xf_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap)
width = bitmap->right - bitmap->left + 1;
height = bitmap->bottom - bitmap->top + 1;
WaitForSingleObject(xfi->mutex, INFINITE);
XSetFunction(xfi->display, xfi->gc, GXcopy);
image = XCreateImage(xfi->display, xfi->visual, xfi->depth,
@ -111,6 +121,8 @@ void xf_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap)
}
gdi_InvalidateRegion(xfi->hdc, bitmap->left, bitmap->top, width, height);
ReleaseMutex(xfi->mutex);
}
void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
@ -118,13 +130,15 @@ void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
BOOL compressed, int codec_id)
{
UINT16 size;
RFX_MESSAGE* msg;
BYTE* src;
BYTE* dst;
int yindex;
int xindex;
xfInfo* xfi;
BOOL status;
RFX_MESSAGE* msg;
xfi = ((xfContext*) context)->xfi;
size = width * height * (bpp + 7) / 8;
@ -138,10 +152,11 @@ void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
case RDP_CODEC_ID_NSCODEC:
printf("xf_Bitmap_Decompress: nsc not done\n");
break;
case RDP_CODEC_ID_REMOTEFX:
xfi = ((xfContext*)context)->xfi;
rfx_context_set_pixel_format(xfi->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8);
msg = rfx_process_message(xfi->rfx_context, data, length);
if (msg == NULL)
{
printf("xf_Bitmap_Decompress: rfx Decompression Failed\n");
@ -163,12 +178,14 @@ void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
rfx_message_free(xfi->rfx_context, msg);
}
break;
case RDP_CODEC_ID_JPEG:
if (!jpeg_decompress(data, bitmap->data, width, height, length, bpp))
{
printf("xf_Bitmap_Decompress: jpeg Decompression Failed\n");
}
break;
default:
if (compressed)
{
@ -195,10 +212,14 @@ void xf_Bitmap_SetSurface(rdpContext* context, rdpBitmap* bitmap, BOOL primary)
{
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
if (primary)
xfi->drawing = xfi->primary;
else
xfi->drawing = ((xfBitmap*) bitmap)->pixmap;
ReleaseMutex(xfi->mutex);
}
/* Pointer Class */
@ -209,7 +230,9 @@ void xf_Pointer_New(rdpContext* context, rdpPointer* pointer)
XcursorImage ci;
xfInfo* xfi = ((xfContext*) context)->xfi;
memset(&ci, 0, sizeof(ci));
WaitForSingleObject(xfi->mutex, INFINITE);
ZeroMemory(&ci, sizeof(ci));
ci.version = XCURSOR_IMAGE_VERSION;
ci.size = sizeof(ci);
ci.width = pointer->width;
@ -229,6 +252,8 @@ void xf_Pointer_New(rdpContext* context, rdpPointer* pointer)
((xfPointer*) pointer)->cursor = XcursorImageLoadCursor(xfi->display, &ci);
free(ci.pixels);
ReleaseMutex(xfi->mutex);
#endif
}
@ -237,8 +262,12 @@ void xf_Pointer_Free(rdpContext* context, rdpPointer* pointer)
#ifdef WITH_XCURSOR
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
if (((xfPointer*) pointer)->cursor != 0)
XFreeCursor(xfi->display, ((xfPointer*) pointer)->cursor);
ReleaseMutex(xfi->mutex);
#endif
}
@ -247,10 +276,14 @@ void xf_Pointer_Set(rdpContext* context, rdpPointer* pointer)
#ifdef WITH_XCURSOR
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
/* in RemoteApp mode, window can be null if none has had focus */
if (xfi->window != NULL)
XDefineCursor(xfi->display, xfi->window->handle, ((xfPointer*) pointer)->cursor);
ReleaseMutex(xfi->mutex);
#endif
}
@ -260,11 +293,13 @@ void xf_Pointer_SetNull(rdpContext* context)
xfInfo* xfi = ((xfContext*) context)->xfi;
static Cursor nullcursor = None;
WaitForSingleObject(xfi->mutex, INFINITE);
if (nullcursor == None)
{
XcursorImage ci;
XcursorPixel xp = 0;
memset(&ci, 0, sizeof(ci));
ZeroMemory(&ci, sizeof(ci));
ci.version = XCURSOR_IMAGE_VERSION;
ci.size = sizeof(ci);
ci.width = ci.height = 1;
@ -275,6 +310,8 @@ void xf_Pointer_SetNull(rdpContext* context)
if (xfi->window != NULL && nullcursor != None)
XDefineCursor(xfi->display, xfi->window->handle, nullcursor);
ReleaseMutex(xfi->mutex);
#endif
}
@ -283,8 +320,12 @@ void xf_Pointer_SetDefault(rdpContext* context)
#ifdef WITH_XCURSOR
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
if (xfi->window != NULL)
XUndefineCursor(xfi->display, xfi->window->handle);
ReleaseMutex(xfi->mutex);
#endif
}
@ -300,6 +341,8 @@ void xf_Glyph_New(rdpContext* context, rdpGlyph* glyph)
xf_glyph = (xfGlyph*) glyph;
xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
scanline = (glyph->cx + 7) / 8;
xf_glyph->pixmap = XCreatePixmap(xfi->display, xfi->drawing, glyph->cx, glyph->cy, 1);
@ -313,14 +356,20 @@ void xf_Glyph_New(rdpContext* context, rdpGlyph* glyph)
XInitImage(image);
XPutImage(xfi->display, xf_glyph->pixmap, xfi->gc_mono, image, 0, 0, 0, 0, glyph->cx, glyph->cy);
XFree(image);
ReleaseMutex(xfi->mutex);
}
void xf_Glyph_Free(rdpContext* context, rdpGlyph* glyph)
{
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
if (((xfGlyph*) glyph)->pixmap != 0)
XFreePixmap(xfi->display, ((xfGlyph*) glyph)->pixmap);
ReleaseMutex(xfi->mutex);
}
void xf_Glyph_Draw(rdpContext* context, rdpGlyph* glyph, int x, int y)
@ -330,10 +379,14 @@ void xf_Glyph_Draw(rdpContext* context, rdpGlyph* glyph, int x, int y)
xf_glyph = (xfGlyph*) glyph;
WaitForSingleObject(xfi->mutex, INFINITE);
XSetStipple(xfi->display, xfi->gc, xf_glyph->pixmap);
XSetTSOrigin(xfi->display, xfi->gc, x, y);
XFillRectangle(xfi->display, xfi->drawing, xfi->gc, x, y, glyph->cx, glyph->cy);
XSetStipple(xfi->display, xfi->gc, xfi->bitmap_mono);
ReleaseMutex(xfi->mutex);
}
void xf_Glyph_BeginDraw(rdpContext* context, int x, int y, int width, int height, UINT32 bgcolor, UINT32 fgcolor)
@ -349,6 +402,8 @@ void xf_Glyph_BeginDraw(rdpContext* context, int x, int y, int width, int height
freerdp_color_convert_var_bgr(fgcolor, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv):
freerdp_color_convert_var_rgb(fgcolor, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);
WaitForSingleObject(xfi->mutex, INFINITE);
XSetFunction(xfi->display, xfi->gc, GXcopy);
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
XSetForeground(xfi->display, xfi->gc, fgcolor);
@ -357,12 +412,16 @@ void xf_Glyph_BeginDraw(rdpContext* context, int x, int y, int width, int height
XSetForeground(xfi->display, xfi->gc, bgcolor);
XSetBackground(xfi->display, xfi->gc, fgcolor);
XSetFillStyle(xfi->display, xfi->gc, FillStippled);
ReleaseMutex(xfi->mutex);
}
void xf_Glyph_EndDraw(rdpContext* context, int x, int y, int width, int height, UINT32 bgcolor, UINT32 fgcolor)
{
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
if (xfi->drawing == xfi->primary)
{
if (xfi->remote_app != TRUE)
@ -372,6 +431,8 @@ void xf_Glyph_EndDraw(rdpContext* context, int x, int y, int width, int height,
gdi_InvalidateRegion(xfi->hdc, x, y, width, height);
}
ReleaseMutex(xfi->mutex);
}
/* Graphics Module */

View File

@ -873,6 +873,8 @@ void xf_UpdateWindowArea(xfInfo* xfi, xfWindow* window, int x, int y, int width,
height = (wnd->visibleOffsetY + wnd->windowHeight - 1) - ay;
}
WaitForSingleObject(xfi->mutex, INFINITE);
if (xfi->sw_gdi)
{
XPutImage(xfi->display, xfi->primary, window->gc, xfi->image,
@ -883,6 +885,8 @@ void xf_UpdateWindowArea(xfInfo* xfi, xfWindow* window, int x, int y, int width,
ax, ay, width, height, x, y);
XFlush(xfi->display);
ReleaseMutex(xfi->mutex);
}
BOOL xf_IsWindowBorder(xfInfo* xfi, xfWindow* xfw, int x, int y)

View File

@ -127,8 +127,12 @@ void xf_sw_end_paint(rdpContext* context)
w = gdi->primary->hdc->hwnd->invalid->w;
h = gdi->primary->hdc->hwnd->invalid->h;
WaitForSingleObject(xfi->mutex, INFINITE);
XPutImage(xfi->display, xfi->primary, xfi->gc, xfi->image, x, y, x, y, w, h);
XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, x, y, w, h, x, y);
ReleaseMutex(xfi->mutex);
}
else
{
@ -142,6 +146,8 @@ void xf_sw_end_paint(rdpContext* context)
ninvalid = gdi->primary->hdc->hwnd->ninvalid;
cinvalid = gdi->primary->hdc->hwnd->cinvalid;
WaitForSingleObject(xfi->mutex, INFINITE);
for (i = 0; i < ninvalid; i++)
{
x = cinvalid[i].x;
@ -154,6 +160,8 @@ void xf_sw_end_paint(rdpContext* context)
}
XFlush(xfi->display);
ReleaseMutex(xfi->mutex);
}
}
else
@ -166,7 +174,11 @@ void xf_sw_end_paint(rdpContext* context)
w = gdi->primary->hdc->hwnd->invalid->w;
h = gdi->primary->hdc->hwnd->invalid->h;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_rail_paint(xfi, context->rail, x, y, x + w - 1, y + h - 1);
ReleaseMutex(xfi->mutex);
}
}
@ -178,6 +190,8 @@ void xf_sw_desktop_resize(rdpContext* context)
xfi = ((xfContext*) context)->xfi;
settings = xfi->instance->settings;
WaitForSingleObject(xfi->mutex, INFINITE);
if (xfi->fullscreen != TRUE)
{
rdpGdi* gdi = context->gdi;
@ -191,12 +205,15 @@ void xf_sw_desktop_resize(rdpContext* context)
(char*) gdi->primary_buffer, gdi->width, gdi->height, xfi->scanline_pad, 0);
}
}
ReleaseMutex(xfi->mutex);
}
void xf_hw_begin_paint(rdpContext* context)
{
xfInfo* xfi;
xfi = ((xfContext*) context)->xfi;
xfi->hdc->hwnd->invalid->null = 1;
xfi->hdc->hwnd->ninvalid = 0;
}
@ -219,7 +236,11 @@ void xf_hw_end_paint(rdpContext* context)
w = xfi->hdc->hwnd->invalid->w;
h = xfi->hdc->hwnd->invalid->h;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_rail_paint(xfi, context->rail, x, y, x + w - 1, y + h - 1);
ReleaseMutex(xfi->mutex);
}
}
@ -232,6 +253,8 @@ void xf_hw_desktop_resize(rdpContext* context)
xfi = ((xfContext*) context)->xfi;
settings = xfi->instance->settings;
WaitForSingleObject(xfi->mutex, INFINITE);
if (xfi->fullscreen != TRUE)
{
xfi->width = settings->DesktopWidth;
@ -258,9 +281,10 @@ void xf_hw_desktop_resize(rdpContext* context)
XSetFunction(xfi->display, xfi->gc, GXcopy);
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
XSetForeground(xfi->display, xfi->gc, 0);
XFillRectangle(xfi->display, xfi->drawable, xfi->gc,
0, 0, xfi->width, xfi->height);
XFillRectangle(xfi->display, xfi->drawable, xfi->gc, 0, 0, xfi->width, xfi->height);
}
ReleaseMutex(xfi->mutex);
}
BOOL xf_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount)
@ -275,19 +299,35 @@ BOOL xf_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* w
BOOL xf_process_x_events(freerdp* instance)
{
BOOL status;
XEvent xevent;
int pending_status;
xfInfo* xfi = ((xfContext*) instance->context)->xfi;
while (XPending(xfi->display))
{
memset(&xevent, 0, sizeof(xevent));
XNextEvent(xfi->display, &xevent);
status = TRUE;
pending_status = TRUE;
if (xf_event_process(instance, &xevent) != TRUE)
return FALSE;
while (pending_status)
{
WaitForSingleObject(xfi->mutex, INFINITE);
pending_status = XPending(xfi->display);
ReleaseMutex(xfi->mutex);
if (pending_status)
{
ZeroMemory(&xevent, sizeof(xevent));
XNextEvent(xfi->display, &xevent);
status = xf_event_process(instance, &xevent);
if (!status)
return status;
}
}
return TRUE;
return status;
}
void xf_create_window(xfInfo* xfi)
@ -296,7 +336,7 @@ void xf_create_window(xfInfo* xfi)
char* win_title;
int width, height;
memset(&xevent, 0x00, sizeof(xevent));
ZeroMemory(&xevent, sizeof(xevent));
width = xfi->width;
height = xfi->height;
@ -384,7 +424,7 @@ BOOL xf_get_pixmap_info(xfInfo* xfi)
}
XFree(pfs);
memset(&template, 0, sizeof(template));
ZeroMemory(&template, sizeof(template));
template.class = TrueColor;
template.screen = xfi->screen_number;
@ -553,12 +593,12 @@ BOOL xf_pre_connect(freerdp* instance)
if (settings->AuthenticationOnly)
{
/* Check --authonly has a username and password. */
if (settings->Username == NULL )
if (settings->Username == NULL)
{
fprintf(stderr, "--authonly, but no -u username. Please provide one.\n");
exit(1);
}
if (settings->Password == NULL )
if (settings->Password == NULL)
{
fprintf(stderr, "--authonly, but no -p password. Please provide one.\n");
exit(1);
@ -568,6 +608,9 @@ BOOL xf_pre_connect(freerdp* instance)
return TRUE;
}
//if (!XInitThreads())
// printf("warning: XInitThreads() failure\n");
xfi->display = XOpenDisplay(NULL);
if (xfi->display == NULL)
@ -750,7 +793,7 @@ BOOL xf_post_connect(freerdp* instance)
xf_create_window(xfi);
memset(&gcv, 0, sizeof(gcv));
ZeroMemory(&gcv, sizeof(gcv));
xfi->modifier_map = XGetModifierMapping(xfi->display);
xfi->gc = XCreateGC(xfi->display, xfi->drawable, GCGraphicsExposures, &gcv);
@ -966,11 +1009,11 @@ void xf_window_free(xfInfo* xfi)
if (context != NULL)
{
cache_free(context->cache);
context->cache = NULL;
cache_free(context->cache);
context->cache = NULL;
rail_free(context->rail);
context->rail = NULL;
rail_free(context->rail);
context->rail = NULL;
}
if (xfi->rfx_context)
@ -1005,12 +1048,74 @@ void xf_free(xfInfo* xfi)
free(xfi);
}
void* xf_update_thread(void* arg)
{
wMessage message;
wMessageQueue* queue;
freerdp* instance = (freerdp*) arg;
queue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE);
while (MessageQueue_Wait(queue))
{
if (MessageQueue_Peek(queue, &message, TRUE))
{
if (!freerdp_message_queue_process_message(instance, FREERDP_UPDATE_MESSAGE_QUEUE, &message))
break;
}
}
return NULL;
}
void* xf_input_thread(void* arg)
{
int status;
xfInfo* xfi;
HANDLE event;
XEvent xevent;
freerdp* instance = (freerdp*) arg;
xfi = ((xfContext*) instance->context)->xfi;
event = CreateFileDescriptorEvent(NULL, TRUE, FALSE, xfi->xfds);
while (WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0)
{
WaitForSingleObject(xfi->mutex, INFINITE);
status = XPending(xfi->display);
ReleaseMutex(xfi->mutex);
if (status)
{
ZeroMemory(&xevent, sizeof(xevent));
WaitForSingleObject(xfi->mutex, INFINITE);
XNextEvent(xfi->display, &xevent);
status = xf_event_process(instance, &xevent);
ReleaseMutex(xfi->mutex);
if (!status)
break;
}
}
printf("Closed from X\n");
xfi->disconnect = TRUE;
return NULL;
}
/** Main loop for the rdp connection.
* It will be run from the thread's entry point (thread_func()).
* It initiates the connection, and will continue to run until the session ends,
* processing events as they are received.
* @param instance - pointer to the rdp_freerdp structure that contains the session's settings
* @return A code from the enum XF_EXIT_CODE (0 if successfull)
* @return A code from the enum XF_EXIT_CODE (0 if successful)
*/
int xfreerdp_run(freerdp* instance)
{
@ -1026,12 +1131,15 @@ int xfreerdp_run(freerdp* instance)
void* wfds[32];
fd_set rfds_set;
fd_set wfds_set;
int fd_update_event;
HANDLE update_event;
int fd_input_event;
HANDLE input_event;
int select_status;
BOOL async_update;
BOOL async_input;
HANDLE update_thread;
HANDLE input_thread;
rdpChannels* channels;
rdpSettings* settings;
struct timeval timeout;
ZeroMemory(rfds, sizeof(rfds));
@ -1056,19 +1164,26 @@ int xfreerdp_run(freerdp* instance)
xfi = ((xfContext*) instance->context)->xfi;
channels = instance->context->channels;
settings = instance->context->settings;
fd_update_event = -1;
update_event = freerdp_get_message_queue_event_handle(instance, FREERDP_UPDATE_MESSAGE_QUEUE);
async_update = settings->AsyncUpdate;
async_input = settings->AsyncInput;
if (update_event)
fd_update_event = GetEventFileDescriptor(update_event);
xfi->mutex = CreateMutex(NULL, FALSE, NULL);
fd_input_event = -1;
input_event = freerdp_get_message_queue_event_handle(instance, FREERDP_INPUT_MESSAGE_QUEUE);
if (async_update)
{
update_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_update_thread, instance, 0, NULL);
}
if (input_event)
if (async_input)
{
input_event = freerdp_get_message_queue_event_handle(instance, FREERDP_INPUT_MESSAGE_QUEUE);
fd_input_event = GetEventFileDescriptor(input_event);
input_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_input_thread, instance, 0, NULL);
}
while (!xfi->disconnect && !freerdp_shall_disconnect(instance))
{
rcount = 0;
@ -1080,24 +1195,27 @@ int xfreerdp_run(freerdp* instance)
ret = XF_EXIT_CONN_FAILED;
break;
}
if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount) != TRUE)
{
printf("Failed to get channel manager file descriptor\n");
ret = XF_EXIT_CONN_FAILED;
break;
}
if (xf_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
if (!async_input)
{
printf("Failed to get xfreerdp file descriptor\n");
ret = XF_EXIT_CONN_FAILED;
break;
if (xf_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
{
printf("Failed to get xfreerdp file descriptor\n");
ret = XF_EXIT_CONN_FAILED;
break;
}
}
if (fd_update_event > 0)
rfds[rcount++] = (void*) (long) fd_update_event;
if (fd_input_event > 0)
else
{
rfds[rcount++] = (void*) (long) fd_input_event;
}
max_fds = 0;
FD_ZERO(&rfds_set);
@ -1128,10 +1246,8 @@ int xfreerdp_run(freerdp* instance)
else if (select_status == -1)
{
/* these are not really errors */
if (!((errno == EAGAIN) ||
(errno == EWOULDBLOCK) ||
(errno == EINPROGRESS) ||
(errno == EINTR))) /* signal occurred */
if (!((errno == EAGAIN) || (errno == EWOULDBLOCK) ||
(errno == EINPROGRESS) || (errno == EINTR))) /* signal occurred */
{
printf("xfreerdp_run: select failed\n");
break;
@ -1143,46 +1259,66 @@ int xfreerdp_run(freerdp* instance)
printf("Failed to check FreeRDP file descriptor\n");
break;
}
if (xf_process_x_events(instance) != TRUE)
{
printf("Closed from X\n");
break;
}
if (freerdp_channels_check_fds(channels, instance) != TRUE)
{
printf("Failed to check channel manager file descriptor\n");
break;
}
xf_process_channel_event(channels, instance);
if (fd_update_event > 0)
freerdp_message_queue_process_pending_messages(instance, FREERDP_UPDATE_MESSAGE_QUEUE);
if (fd_input_event > 0)
if (!async_input)
{
if (xf_process_x_events(instance) != TRUE)
{
printf("Closed from X\n");
break;
}
}
else
{
freerdp_message_queue_process_pending_messages(instance, FREERDP_INPUT_MESSAGE_QUEUE);
}
}
FILE *fin = fopen("/tmp/tsmf.tid", "rt");
if(fin)
if (async_update)
{
wMessageQueue* update_queue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE);
MessageQueue_PostQuit(update_queue, 0);
WaitForSingleObject(update_thread, INFINITE);
CloseHandle(update_thread);
}
FILE* fin = fopen("/tmp/tsmf.tid", "rt");
if (fin)
{
FILE* fin1;
int thid = 0;
int timeout;
fscanf(fin, "%d", &thid);
fclose(fin);
pthread_kill((pthread_t) (size_t) thid, SIGUSR1);
FILE *fin1 = fopen("/tmp/tsmf.tid", "rt");
int timeout = 5;
fin1 = fopen("/tmp/tsmf.tid", "rt");
timeout = 5;
while (fin1)
{
fclose(fin1);
sleep(1);
timeout--;
if (timeout <= 0)
{
unlink("/tmp/tsmf.tid");
pthread_kill((pthread_t) (size_t) thid, SIGKILL);
break;
}
fin1 = fopen("/tmp/tsmf.tid", "rt");
}
}

View File

@ -114,6 +114,7 @@ struct xf_info
BOOL disconnect;
HCLRCONV clrconv;
Window parent_window;
HANDLE mutex;
HGDI_DC hdc;
BOOL sw_gdi;

View File

@ -194,9 +194,10 @@ xfInfo* xf_info_init()
*/
xfi->use_xshm = FALSE;
xfi->display = XOpenDisplay(NULL);
if (!XInitThreads())
printf("warning: XInitThreads() failure\n");
XInitThreads();
xfi->display = XOpenDisplay(NULL);
if (xfi->display == NULL)
{