Beispiel #1
0
void guac_rdp_gdi_opaquerect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect) {

    guac_client* client = ((rdp_freerdp_context*) context)->client;
    uint32 color = freerdp_color_convert_var(opaque_rect->color,
            context->instance->settings->color_depth, 32,
            ((rdp_freerdp_context*) context)->clrconv);

    const guac_layer* current_layer = ((rdp_guac_client_data*) client->data)->current_surface;

    rdp_guac_client_data* data = (rdp_guac_client_data*) client->data;
    pthread_mutex_lock(&(data->update_lock));

    int x = opaque_rect->nLeftRect;
    int y = opaque_rect->nTopRect;
    int w = opaque_rect->nWidth;
    int h = opaque_rect->nHeight;

    /* Clip operation to bounds */
    __guac_rdp_clip_rect(data, &x, &y, &w, &h);

    guac_protocol_send_rect(client->socket, current_layer, x, y, w, h);

    guac_protocol_send_cfill(client->socket,
            GUAC_COMP_OVER, current_layer,
            (color >> 16) & 0xFF,
            (color >> 8 ) & 0xFF,
            (color      ) & 0xFF,
            255);

    pthread_mutex_unlock(&(data->update_lock));

}
Beispiel #2
0
void xf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect)
{
	int i;
	UINT32 color;
	DELTA_RECT* rectangle;
	xfContext* context_ = (xfContext*) context;
	xfInfo* xfi = context_->xfi;

	color = freerdp_color_convert_var(multi_opaque_rect->color, context_->settings->ColorDepth, 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)
		{
			if (xfi->remote_app != TRUE)
			{
				XFillRectangle(xfi->display, xfi->drawable, xfi->gc,
					rectangle->left, rectangle->top, rectangle->width, rectangle->height);
			}

			gdi_InvalidateRegion(xfi->hdc, rectangle->left, rectangle->top, rectangle->width, rectangle->height);
		}
	}
}
Beispiel #3
0
void xf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect)
{
	Drawable dst;
	int i;
	uint32 color;
	DELTA_RECT* rectangle;
	xfInfo* xfi = ((xfContext*) context)->xfi;

	color = freerdp_color_convert_var(multi_opaque_rect->color, xfi->srcBpp, 32, xfi->clrconv);
	XSetFunction(xfi->display, xfi->gc, GXcopy);
	XSetFillStyle(xfi->display, xfi->gc, FillSolid);
	XSetForeground(xfi->display, xfi->gc, color);
	GET_DST(xfi, dst);
	for (i = 1; i < multi_opaque_rect->numRectangles + 1; i++)
	{
		rectangle = &multi_opaque_rect->rectangles[i];
		XFillRectangle(xfi->display, dst, xfi->gc,
				rectangle->left, rectangle->top,
				rectangle->width, rectangle->height);
		if (xfi->drawing == xfi->primary)
		{
			if (!xfi->remote_app && !xfi->skip_bs)
			{
				XFillRectangle(xfi->display, xfi->drawable, xfi->gc,
					rectangle->left, rectangle->top,
					rectangle->width, rectangle->height);
			}
			gdi_InvalidateRegion(xfi->hdc, rectangle->left, rectangle->top,
					rectangle->width, rectangle->height);
		}
	}
}
Beispiel #4
0
void xf_gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect)
{
	UINT32 color;
	xfContext* context_ = (xfContext*) context;
	xfInfo* xfi = context_->xfi;

	color = freerdp_color_convert_var(opaque_rect->color, context_->settings->ColorDepth, 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)
	{
		if (xfi->remote_app != TRUE)
		{
			XFillRectangle(xfi->display, xfi->drawable, xfi->gc,
				opaque_rect->nLeftRect, opaque_rect->nTopRect, opaque_rect->nWidth, opaque_rect->nHeight);
		}

		gdi_InvalidateRegion(xfi->hdc, opaque_rect->nLeftRect, opaque_rect->nTopRect,
				opaque_rect->nWidth, opaque_rect->nHeight);
	}
}
Beispiel #5
0
void guac_rdp_gdi_opaquerect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect) {

    guac_client* client = ((rdp_freerdp_context*) context)->client;
    UINT32 color = freerdp_color_convert_var(opaque_rect->color,
            context->instance->settings->ColorDepth, 32,
            ((rdp_freerdp_context*) context)->clrconv);

    const guac_layer* current_layer = ((rdp_guac_client_data*) client->data)->current_surface;

    rdp_guac_client_data* data = (rdp_guac_client_data*) client->data;
    pthread_mutex_lock(&(data->update_lock));

    guac_protocol_send_rect(client->socket, current_layer,
            opaque_rect->nLeftRect, opaque_rect->nTopRect,
            opaque_rect->nWidth, opaque_rect->nHeight);

    guac_protocol_send_cfill(client->socket,
            GUAC_COMP_OVER, current_layer,
            (color >> 16) & 0xFF,
            (color >> 8 ) & 0xFF,
            (color      ) & 0xFF,
            255);

    pthread_mutex_unlock(&(data->update_lock));

}
Beispiel #6
0
void xf_gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect)
{
	Drawable dst;
	uint32 color;
	xfInfo* xfi = ((xfContext*) context)->xfi;

	color = freerdp_color_convert_var(opaque_rect->color, xfi->srcBpp, 32, xfi->clrconv);
	XSetFunction(xfi->display, xfi->gc, GXcopy);
	XSetFillStyle(xfi->display, xfi->gc, FillSolid);
	XSetForeground(xfi->display, xfi->gc, color);
	GET_DST(xfi, dst);
	XFillRectangle(xfi->display, dst, xfi->gc,
			opaque_rect->nLeftRect, opaque_rect->nTopRect,
			opaque_rect->nWidth, opaque_rect->nHeight);
	if (xfi->drawing == xfi->primary)
	{
		if (!xfi->remote_app && !xfi->skip_bs)
		{
			XFillRectangle(xfi->display, xfi->drawable, xfi->gc,
					opaque_rect->nLeftRect, opaque_rect->nTopRect,
					opaque_rect->nWidth, opaque_rect->nHeight);
		}
		gdi_InvalidateRegion(xfi->hdc, opaque_rect->nLeftRect, opaque_rect->nTopRect,
				opaque_rect->nWidth, opaque_rect->nHeight);
	}
}
Beispiel #7
0
void xf_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)
{
    int i, npoints;
    XPoint* points;
    UINT32 brush_color;
    xfInfo* xfi = ((xfContext*) context)->xfi;

    xf_lock_x11(xfi, FALSE);

    xf_set_rop2(xfi, polygon_sc->bRop2);
    brush_color = freerdp_color_convert_var(polygon_sc->brushColor, ((xfContext*)context)->settings->ColorDepth, xfi->bpp, xfi->clrconv);

    npoints = polygon_sc->numPoints + 1;
    points = malloc(sizeof(XPoint) * npoints);

    points[0].x = polygon_sc->xStart;
    points[0].y = polygon_sc->yStart;

    for (i = 0; i < polygon_sc->numPoints; i++)
    {
        points[i + 1].x = polygon_sc->points[i].x;
        points[i + 1].y = polygon_sc->points[i].y;
    }

    switch (polygon_sc->fillMode)
    {
    case 1: /* alternate */
        XSetFillRule(xfi->display, xfi->gc, EvenOddRule);
        break;

    case 2: /* winding */
        XSetFillRule(xfi->display, xfi->gc, WindingRule);
        break;

    default:
        fprintf(stderr, "PolygonSC unknown fillMode: %d\n", polygon_sc->fillMode);
        break;
    }

    XSetFillStyle(xfi->display, xfi->gc, FillSolid);
    XSetForeground(xfi->display, xfi->gc, brush_color);

    XFillPolygon(xfi->display, xfi->drawing, xfi->gc,
                 points, npoints, Complex, CoordModePrevious);

    if (xfi->drawing == xfi->primary)
    {
        XFillPolygon(xfi->display, xfi->drawable, xfi->gc,
                     points, npoints, Complex, CoordModePrevious);
    }

    XSetFunction(xfi->display, xfi->gc, GXcopy);
    free(points);

    xf_unlock_x11(xfi, FALSE);
}
void guac_rdp_glyph_begindraw(rdpContext* context,
        int x, int y, int width, int height, uint32 fgcolor, uint32 bgcolor) {

    guac_client* client = ((rdp_freerdp_context*) context)->client;
    rdp_guac_client_data* guac_client_data =
        (rdp_guac_client_data*) client->data;

    /* Convert foreground color */
    fgcolor = freerdp_color_convert_var(fgcolor,
            context->instance->settings->color_depth, 32,
            ((rdp_freerdp_context*) context)->clrconv);

    /* Fill background with color if specified */
    if (width != 0 && height != 0) {

        /* Prepare for opaque glyphs */
        guac_client_data->glyph_surface = 
            guac_client_data->opaque_glyph_surface;

        /* Create cairo instance */
        guac_client_data->glyph_cairo = cairo_create(
            guac_client_data->glyph_surface);

        /* Convert background color */
        bgcolor = freerdp_color_convert_var(bgcolor,
                context->instance->settings->color_depth, 32,
                ((rdp_freerdp_context*) context)->clrconv);

        /* Fill background */
        cairo_rectangle(guac_client_data->glyph_cairo,
                x, y, width, height);

        cairo_set_source_rgb(guac_client_data->glyph_cairo,
                ((bgcolor & 0xFF0000) >> 16) / 255.0,
                ((bgcolor & 0x00FF00) >> 8 ) / 255.0,
                ( bgcolor & 0x0000FF       ) / 255.0);

        cairo_fill(guac_client_data->glyph_cairo);

    }
Beispiel #9
0
UINT32 guac_rdp_convert_color(rdpContext* context, UINT32 color) {

#ifdef HAVE_FREERDP_CONVERT_GDI_ORDER_COLOR
    UINT32* palette = ((rdp_freerdp_context*) context)->palette;

    /* Convert given color to ARGB32 */
    return freerdp_convert_gdi_order_color(color,
            guac_rdp_get_depth(context->instance), PIXEL_FORMAT_ARGB32,
            (BYTE*) palette);
#else
    CLRCONV* clrconv = ((rdp_freerdp_context*) context)->clrconv;

    /* Convert given color to ARGB32 */
    return freerdp_color_convert_var(color,
            guac_rdp_get_depth(context->instance), 32,
            clrconv);
#endif

}
Beispiel #10
0
void xf_gdi_line_to(rdpContext* context, LINE_TO_ORDER* line_to)
{
    UINT32 color;
    xfContext* context_ = (xfContext*) context;
    xfInfo* xfi = context_->xfi;

    xf_lock_x11(xfi, FALSE);

    xf_set_rop2(xfi, line_to->bRop2);
    color = freerdp_color_convert_var(line_to->penColor, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);

    XSetFillStyle(xfi->display, xfi->gc, FillSolid);
    XSetForeground(xfi->display, xfi->gc, color);

    XDrawLine(xfi->display, xfi->drawing, xfi->gc,
              line_to->nXStart, line_to->nYStart, line_to->nXEnd, line_to->nYEnd);

    if (xfi->drawing == xfi->primary)
    {
        int width, height;

        width = line_to->nXStart - line_to->nXEnd;
        height = line_to->nYStart - line_to->nYEnd;

        if (width < 0)
            width *= (-1);

        if (height < 0)
            height *= (-1);

        gdi_InvalidateRegion(xfi->hdc, line_to->nXStart, line_to->nYStart, width, height);

    }

    XSetFunction(xfi->display, xfi->gc, GXcopy);

    xf_unlock_x11(xfi, FALSE);
}
Beispiel #11
0
void xf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline)
{
	int i;
	int x, y;
	int x1, y1;
	int x2, y2;
	int npoints;
	UINT32 color;
	XPoint* points;
	int width, height;
	xfContext* context_ = (xfContext*) context;
	xfInfo* xfi = context_->xfi;

	xf_set_rop2(xfi, polyline->bRop2);
	color = freerdp_color_convert_var(polyline->penColor, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);

	XSetFillStyle(xfi->display, xfi->gc, FillSolid);
	XSetForeground(xfi->display, xfi->gc, color);

	npoints = polyline->numPoints + 1;
	points = malloc(sizeof(XPoint) * npoints);

	points[0].x = polyline->xStart;
	points[0].y = polyline->yStart;

	for (i = 0; i < polyline->numPoints; i++)
	{
		points[i + 1].x = polyline->points[i].x;
		points[i + 1].y = polyline->points[i].y;
	}

	XDrawLines(xfi->display, xfi->drawing, xfi->gc, points, npoints, CoordModePrevious);

	if (xfi->drawing == xfi->primary)
	{
		if (xfi->remote_app != TRUE)
			XDrawLines(xfi->display, xfi->drawable, xfi->gc, points, npoints, CoordModePrevious);

		x1 = points[0].x;
		y1 = points[0].y;

		for (i = 1; i < npoints; i++)
		{
			x2 = points[i].x + x1;
			y2 = points[i].y + y1;

			x = (x2 < x1) ? x2 : x1;
			width = (x2 > x1) ? x2 - x1 : x1 - x2;

			y = (y2 < y1) ? y2 : y1;
			height = (y2 > y1) ? y2 - y1 : y1 - y2;

			x1 = x2;
			y1 = y2;

			gdi_InvalidateRegion(xfi->hdc, x, y, width, height);
		}
	}

	XSetFunction(xfi->display, xfi->gc, GXcopy);
	free(points);
}
Beispiel #12
0
void xf_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb)
{
    int i, npoints;
    XPoint* points;
    Pixmap pattern;
    rdpBrush* brush;
    UINT32 foreColor;
    UINT32 backColor;
    xfInfo* xfi = ((xfContext*) context)->xfi;

    xf_lock_x11(xfi, FALSE);

    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);
    backColor = freerdp_color_convert_var(polygon_cb->backColor, ((xfContext*) context)->settings->ColorDepth, xfi->bpp, xfi->clrconv);

    npoints = polygon_cb->numPoints + 1;
    points = malloc(sizeof(XPoint) * npoints);

    points[0].x = polygon_cb->xStart;
    points[0].y = polygon_cb->yStart;

    for (i = 0; i < polygon_cb->numPoints; i++)
    {
        points[i + 1].x = polygon_cb->points[i].x;
        points[i + 1].y = polygon_cb->points[i].y;
    }

    switch (polygon_cb->fillMode)
    {
    case 1: /* alternate */
        XSetFillRule(xfi->display, xfi->gc, EvenOddRule);
        break;

    case 2: /* winding */
        XSetFillRule(xfi->display, xfi->gc, WindingRule);
        break;

    default:
        fprintf(stderr, "PolygonCB unknown fillMode: %d\n", polygon_cb->fillMode);
        break;
    }

    if (brush->style == GDI_BS_PATTERN)
    {
        if (brush->bpp > 1)
        {
            pattern = xf_brush_new(xfi, 8, 8, brush->bpp, brush->data);

            XSetFillStyle(xfi->display, xfi->gc, FillTiled);
            XSetTile(xfi->display, xfi->gc, pattern);
            XSetTSOrigin(xfi->display, xfi->gc, brush->x, brush->y);

            XFillPolygon(xfi->display, xfi->drawing, xfi->gc,
                         points, npoints, Complex, CoordModePrevious);

            if (xfi->drawing == xfi->primary)
            {
                XFillPolygon(xfi->display, xfi->drawable, xfi->gc,
                             points, npoints, Complex, CoordModePrevious);
            }

            XSetFillStyle(xfi->display, xfi->gc, FillSolid);
            XSetTSOrigin(xfi->display, xfi->gc, 0, 0);
            XFreePixmap(xfi->display, pattern);
        }
        else
        {
            pattern = xf_mono_bitmap_new(xfi, 8, 8, brush->data);

            XSetForeground(xfi->display, xfi->gc, backColor);
            XSetBackground(xfi->display, xfi->gc, foreColor);

            if (polygon_cb->backMode == BACKMODE_TRANSPARENT)
                XSetFillStyle(xfi->display, xfi->gc, FillStippled);
            else if (polygon_cb->backMode == BACKMODE_OPAQUE)
                XSetFillStyle(xfi->display, xfi->gc, FillOpaqueStippled);

            XSetStipple(xfi->display, xfi->gc, pattern);
            XSetTSOrigin(xfi->display, xfi->gc, brush->x, brush->y);

            XFillPolygon(xfi->display, xfi->drawing, xfi->gc,
                         points, npoints, Complex, CoordModePrevious);

            if (xfi->drawing == xfi->primary)
            {
                XFillPolygon(xfi->display, xfi->drawable, xfi->gc,
                             points, npoints, Complex, CoordModePrevious);
            }

            XSetFillStyle(xfi->display, xfi->gc, FillSolid);
            XSetTSOrigin(xfi->display, xfi->gc, 0, 0);
            XFreePixmap(xfi->display, pattern);
        }
    }
    else
    {
        fprintf(stderr, "PolygonCB unimplemented brush style:%d\n", brush->style);
    }

    XSetFunction(xfi->display, xfi->gc, GXcopy);
    free(points);

    xf_unlock_x11(xfi, FALSE);
}
Beispiel #13
0
void xf_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
{
    rdpBrush* brush;
    xfBitmap* bitmap;
    UINT32 foreColor;
    UINT32 backColor;
    Pixmap pattern = 0;
    xfContext* context_ = (xfContext*) context;
    xfInfo* xfi = context_->xfi;

    xf_lock_x11(xfi, FALSE);

    brush = &mem3blt->brush;
    bitmap = (xfBitmap*) mem3blt->bitmap;
    xf_set_rop3(xfi, gdi_rop3_code(mem3blt->bRop));
    foreColor = freerdp_color_convert_var(mem3blt->foreColor, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);
    backColor = freerdp_color_convert_var(mem3blt->backColor, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);

    if (brush->style == GDI_BS_PATTERN)
    {
        if (brush->bpp > 1)
        {
            pattern = xf_brush_new(xfi, 8, 8, brush->bpp, brush->data);

            XSetFillStyle(xfi->display, xfi->gc, FillTiled);
            XSetTile(xfi->display, xfi->gc, pattern);
            XSetTSOrigin(xfi->display, xfi->gc, brush->x, brush->y);
        }
        else
        {
            pattern = xf_mono_bitmap_new(xfi, 8, 8, brush->data);

            XSetForeground(xfi->display, xfi->gc, backColor);
            XSetBackground(xfi->display, xfi->gc, foreColor);
            XSetFillStyle(xfi->display, xfi->gc, FillOpaqueStippled);
            XSetStipple(xfi->display, xfi->gc, pattern);
            XSetTSOrigin(xfi->display, xfi->gc, brush->x, brush->y);
        }
    }
    else if (brush->style == GDI_BS_SOLID)
    {
        XSetFillStyle(xfi->display, xfi->gc, FillSolid);
        XSetForeground(xfi->display, xfi->gc, backColor);
        XSetBackground(xfi->display, xfi->gc, foreColor);

        XSetTSOrigin(xfi->display, xfi->gc, brush->x, brush->y);
    }
    else
    {
        fprintf(stderr, "Mem3Blt unimplemented brush style:%d\n", brush->style);
    }

    XCopyArea(xfi->display, bitmap->pixmap, xfi->drawing, xfi->gc,
              mem3blt->nXSrc, mem3blt->nYSrc, mem3blt->nWidth, mem3blt->nHeight,
              mem3blt->nLeftRect, mem3blt->nTopRect);

    if (xfi->drawing == xfi->primary)
    {
        gdi_InvalidateRegion(xfi->hdc, mem3blt->nLeftRect, mem3blt->nTopRect, mem3blt->nWidth, mem3blt->nHeight);
    }

    XSetFillStyle(xfi->display, xfi->gc, FillSolid);
    XSetTSOrigin(xfi->display, xfi->gc, 0, 0);

    if (pattern != 0)
        XFreePixmap(xfi->display, pattern);

    XSetFunction(xfi->display, xfi->gc, GXcopy);

    xf_unlock_x11(xfi, FALSE);
}
Beispiel #14
0
void xf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
{
    Pixmap pattern;
    rdpBrush* brush;
    UINT32 foreColor;
    UINT32 backColor;
    xfContext* context_ = (xfContext*) context;
    xfInfo* xfi = context_->xfi;

    xf_lock_x11(xfi, FALSE);

    brush = &patblt->brush;
    xf_set_rop3(xfi, gdi_rop3_code(patblt->bRop));

    foreColor = freerdp_color_convert_var(patblt->foreColor, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);
    backColor = freerdp_color_convert_var(patblt->backColor, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);

    if (brush->style == GDI_BS_SOLID)
    {
        XSetFillStyle(xfi->display, xfi->gc, FillSolid);
        XSetForeground(xfi->display, xfi->gc, foreColor);

        XFillRectangle(xfi->display, xfi->drawing, xfi->gc,
                       patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight);
    }
    else if (brush->style == GDI_BS_HATCHED)
    {
        pattern = xf_mono_bitmap_new(xfi, 8, 8, GDI_BS_HATCHED_PATTERNS + 8 * brush->hatch);

        XSetForeground(xfi->display, xfi->gc, backColor);
        XSetBackground(xfi->display, xfi->gc, foreColor);
        XSetFillStyle(xfi->display, xfi->gc, FillOpaqueStippled);
        XSetStipple(xfi->display, xfi->gc, pattern);
        XSetTSOrigin(xfi->display, xfi->gc, brush->x, brush->y);

        XFillRectangle(xfi->display, xfi->drawing, xfi->gc,
                       patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight);

        XFreePixmap(xfi->display, pattern);
    }
    else if (brush->style == GDI_BS_PATTERN)
    {
        if (brush->bpp > 1)
        {
            pattern = xf_brush_new(xfi, 8, 8, brush->bpp, brush->data);

            XSetFillStyle(xfi->display, xfi->gc, FillTiled);
            XSetTile(xfi->display, xfi->gc, pattern);
            XSetTSOrigin(xfi->display, xfi->gc, brush->x, brush->y);

            XFillRectangle(xfi->display, xfi->drawing, xfi->gc,
                           patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight);

            XSetTile(xfi->display, xfi->gc, xfi->primary);

            XFreePixmap(xfi->display, pattern);
        }
        else
        {
            pattern = xf_mono_bitmap_new(xfi, 8, 8, brush->data);

            XSetForeground(xfi->display, xfi->gc, backColor);
            XSetBackground(xfi->display, xfi->gc, foreColor);
            XSetFillStyle(xfi->display, xfi->gc, FillOpaqueStippled);
            XSetStipple(xfi->display, xfi->gc, pattern);
            XSetTSOrigin(xfi->display, xfi->gc, brush->x, brush->y);

            XFillRectangle(xfi->display, xfi->drawing, xfi->gc,
                           patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight);

            XFreePixmap(xfi->display, pattern);
        }
    }
    else
    {
        fprintf(stderr, "unimplemented brush style:%d\n", brush->style);
    }

    if (xfi->drawing == xfi->primary)
    {
        gdi_InvalidateRegion(xfi->hdc, patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight);
    }

    XSetFunction(xfi->display, xfi->gc, GXcopy);

    xf_unlock_x11(xfi, FALSE);
}