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)
#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 */
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)
XRectangle clip;
xfInfo* xfi = ((xfContext*) context)->xfi;
+ WaitForSingleObject(xfi->mutex, INFINITE);
+
if (bounds != NULL)
{
clip.x = bounds->left;
{
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);
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)
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
+ WaitForSingleObject(xfi->mutex, INFINITE);
+
brush = &patblt->brush;
xf_set_rop3(xfi, gdi_rop3_code(patblt->bRop));
}
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,
}
XSetFunction(xfi->display, xfi->gc, GXcopy);
+
+ ReleaseMutex(xfi->mutex);
}
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);
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)
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);
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)
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);
}
XSetFunction(xfi->display, xfi->gc, GXcopy);
+
+ ReleaseMutex(xfi->mutex);
}
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);
XSetFunction(xfi->display, xfi->gc, GXcopy);
free(points);
+
+ ReleaseMutex(xfi->mutex);
}
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));
}
XSetFunction(xfi->display, xfi->gc, GXcopy);
+
+ ReleaseMutex(xfi->mutex);
}
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));
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)
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);
XSetFunction(xfi->display, xfi->gc, GXcopy);
free(points);
+
+ ReleaseMutex(xfi->mutex);
}
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);
XSetFunction(xfi->display, xfi->gc, GXcopy);
free(points);
+
+ ReleaseMutex(xfi->mutex);
}
void xf_gdi_ellipse_sc(rdpContext* context, ELLIPSE_SC_ORDER* ellipse_sc)
xfi = ((xfContext*) context)->xfi;
settings = xfi->instance->settings;
+
+ WaitForSingleObject(xfi->mutex, INFINITE);
+
switch (surface_frame_marker->frameAction)
{
case SURFACECMD_FRAMEACTION_BEGIN:
}
break;
}
+
+ ReleaseMutex(xfi->mutex);
}
static void xf_gdi_surface_update_frame(xfInfo* xfi, UINT16 tx, UINT16 ty, UINT16 width, UINT16 height)
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,
{
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);
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);
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);
}
}
{
printf("Unsupported codecID %d\n", surface_bits_command->codecID);
}
+
+ ReleaseMutex(xfi->mutex);
}
void xf_gdi_register_update_callbacks(rdpUpdate* update)
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);
}
((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)
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,
}
gdi_InvalidateRegion(xfi->hdc, bitmap->left, bitmap->top, width, height);
+
+ ReleaseMutex(xfi->mutex);
}
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;
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");
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)
{
{
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 */
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;
((xfPointer*) pointer)->cursor = XcursorImageLoadCursor(xfi->display, &ci);
free(ci.pixels);
+
+ ReleaseMutex(xfi->mutex);
#endif
}
#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
}
#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
}
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;
if (xfi->window != NULL && nullcursor != None)
XDefineCursor(xfi->display, xfi->window->handle, nullcursor);
+
+ ReleaseMutex(xfi->mutex);
#endif
}
#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
}
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);
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)
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)
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);
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)
gdi_InvalidateRegion(xfi->hdc, x, y, width, height);
}
+
+ ReleaseMutex(xfi->mutex);
}
/* Graphics Module */
height = (wnd->visibleOffsetY + wnd->windowHeight - 1) - ay;
}
+ WaitForSingleObject(xfi->mutex, INFINITE);
+
if (xfi->sw_gdi)
{
XPutImage(xfi->display, xfi->primary, window->gc, xfi->image,
ax, ay, width, height, x, y);
XFlush(xfi->display);
+
+ ReleaseMutex(xfi->mutex);
}
BOOL xf_IsWindowBorder(xfInfo* xfi, xfWindow* xfw, int x, int y)
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
{
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;
}
XFlush(xfi->display);
+
+ ReleaseMutex(xfi->mutex);
}
}
else
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);
}
}
xfi = ((xfContext*) context)->xfi;
settings = xfi->instance->settings;
+ WaitForSingleObject(xfi->mutex, INFINITE);
+
if (xfi->fullscreen != TRUE)
{
rdpGdi* gdi = context->gdi;
(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;
}
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);
}
}
xfi = ((xfContext*) context)->xfi;
settings = xfi->instance->settings;
+ WaitForSingleObject(xfi->mutex, INFINITE);
+
if (xfi->fullscreen != TRUE)
{
xfi->width = settings->DesktopWidth;
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)
BOOL xf_process_x_events(freerdp* instance)
{
+ BOOL status;
XEvent xevent;
+ int pending_status;
xfInfo* xfi = ((xfContext*) instance->context)->xfi;
- while (XPending(xfi->display))
+ status = TRUE;
+ pending_status = TRUE;
+
+ while (pending_status)
{
- memset(&xevent, 0, sizeof(xevent));
- XNextEvent(xfi->display, &xevent);
+ WaitForSingleObject(xfi->mutex, INFINITE);
- if (xf_event_process(instance, &xevent) != TRUE)
- return FALSE;
+ 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)
char* win_title;
int width, height;
- memset(&xevent, 0x00, sizeof(xevent));
+ ZeroMemory(&xevent, sizeof(xevent));
width = xfi->width;
height = xfi->height;
}
XFree(pfs);
- memset(&template, 0, sizeof(template));
+ ZeroMemory(&template, sizeof(template));
template.class = TrueColor;
template.screen = xfi->screen_number;
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);
return TRUE;
}
+ //if (!XInitThreads())
+ // printf("warning: XInitThreads() failure\n");
+
xfi->display = XOpenDisplay(NULL);
if (xfi->display == NULL)
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);
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)
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)
{
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));
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;
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);
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;
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);
+ xf_process_channel_event(channels, instance);
- 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);
+ }
+ }
+
+ 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* 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");
}
}
BOOL disconnect;
HCLRCONV clrconv;
Window parent_window;
+ HANDLE mutex;
HGDI_DC hdc;
BOOL sw_gdi;
*/
xfi->use_xshm = FALSE;
- xfi->display = XOpenDisplay(NULL);
+ if (!XInitThreads())
+ printf("warning: XInitThreads() failure\n");
- XInitThreads();
+ xfi->display = XOpenDisplay(NULL);
if (xfi->display == NULL)
{