Exemplo n.º 1
0
void xf_Glyph_EndDraw(rdpContext* context, int x, int y, int width, int height, uint32 bgcolor, uint32 fgcolor)
{
	xfInfo* xfi = ((xfContext*) context)->xfi;

	if (xfi->drawing == xfi->primary)
	{
		if (xfi->remote_app != true)
		{
			XCopyArea(xfi->display, xfi->primary, xfi->drawable, xfi->gc, x, y, width, height, x, y);
		}

		gdi_InvalidateRegion(xfi->hdc, x, y, width, height);
	}
}
Exemplo n.º 2
0
static BOOL xf_gdi_surface_update_frame(xfContext* xfc, UINT16 tx, UINT16 ty,
                                        UINT16 width, UINT16 height)
{
	BOOL ret = TRUE;

	if (!xfc->remote_app)
	{
		if (xfc->frame_begin)
		{
			if (xfc->frame_x2 > xfc->frame_x1 && xfc->frame_y2 > xfc->frame_y1)
			{
				xfc->frame_x1 = MIN(xfc->frame_x1, tx);
				xfc->frame_y1 = MIN(xfc->frame_y1, ty);
				xfc->frame_x2 = MAX(xfc->frame_x2, tx + width);
				xfc->frame_y2 = MAX(xfc->frame_y2, ty + height);
			}
			else
			{
				xfc->frame_x1 = tx;
				xfc->frame_y1 = ty;
				xfc->frame_x2 = tx + width;
				xfc->frame_y2 = ty + height;
			}
		}
		else
		{
			ret = gdi_InvalidateRegion(xfc->hdc, tx, ty, width, height);
		}
	}
	else
	{
		ret = gdi_InvalidateRegion(xfc->hdc, tx, ty, width, height);
	}

	return ret;
}
Exemplo n.º 3
0
static UINT gdi_OutputUpdate(rdpGdi* gdi, gdiGfxSurface* surface)
{
	UINT32 nXDst, nYDst;
	UINT32 nXSrc, nYSrc;
	UINT16 width, height;
	UINT32 surfaceX, surfaceY;
	RECTANGLE_16 surfaceRect;
	const RECTANGLE_16* rects;
	UINT32 i, nbRects;
	rdpUpdate* update = gdi->context->update;
	surfaceX = surface->outputOriginX;
	surfaceY = surface->outputOriginY;
	surfaceRect.left = 0;
	surfaceRect.top = 0;
	surfaceRect.right = surface->width;
	surfaceRect.bottom = surface->height;
	region16_intersect_rect(&(surface->invalidRegion),
	                        &(surface->invalidRegion), &surfaceRect);

	if (!(rects = region16_rects(&surface->invalidRegion, &nbRects)) || !nbRects)
                return CHANNEL_RC_OK;

	update->BeginPaint(gdi->context);

	for (i = 0; i < nbRects; i++)
	{
		nXSrc = rects[i].left;
		nYSrc = rects[i].top;
		nXDst = surfaceX + nXSrc;
		nYDst = surfaceY + nYSrc;
		width = rects[i].right - rects[i].left;
		height = rects[i].bottom - rects[i].top;

		if (!freerdp_image_copy(gdi->primary_buffer, gdi->primary->hdc->format,
		                        gdi->stride,
		                        nXDst, nYDst, width, height,
		                        surface->data, surface->format,
		                        surface->scanline, nXSrc, nYSrc, NULL, FREERDP_FLIP_NONE))
			return CHANNEL_RC_NULL_DATA;

		gdi_InvalidateRegion(gdi->primary->hdc, nXDst, nYDst, width, height);
	}

	update->EndPaint(gdi->context);

	region16_clear(&(surface->invalidRegion));
	return CHANNEL_RC_OK;
}
Exemplo n.º 4
0
int PatBlt_16bpp(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, int rop)
{
	if (gdi_ClipCoords(hdc, &nXLeft, &nYLeft, &nWidth, &nHeight, NULL, NULL) == 0)
		return 0;
	
	gdi_InvalidateRegion(hdc, nXLeft, nYLeft, nWidth, nHeight);

	switch (rop)
	{
		case GDI_PATCOPY:
			return BitBlt_PATCOPY_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
			break;

		case GDI_PATINVERT:
			return BitBlt_PATINVERT_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
			break;
			
		case GDI_DSTINVERT:
			return BitBlt_DSTINVERT_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
			break;

		case GDI_BLACKNESS:
			return BitBlt_BLACKNESS_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
			break;

		case GDI_WHITENESS:
			return BitBlt_WHITENESS_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
			break;

		case GDI_DPa:
			return BitBlt_DPa_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
			break;

		case GDI_PDxn:
			return BitBlt_PDxn_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
			break;

		default:
			break;
	}
	
	printf("PatBlt: unknown rop: 0x%08X\n", rop);

	return 1;
}
Exemplo n.º 5
0
static BOOL xf_Glyph_EndDraw(rdpContext* context, UINT32 x, UINT32 y,
                             UINT32 width, UINT32 height,
                             UINT32 bgcolor, UINT32 fgcolor)
{
	xfContext* xfc = (xfContext*) context;
	BOOL ret = TRUE;

	if (!xf_decode_color(context->gdi, bgcolor, &bgcolor, NULL))
		return FALSE;

	if (!xf_decode_color(context->gdi, fgcolor, &fgcolor, NULL))
		return FALSE;

	if (xfc->drawing == xfc->primary)
		ret = gdi_InvalidateRegion(xfc->hdc, x, y, width, height);

	return ret;
}
Exemplo n.º 6
0
void wf_invalidate_region(wfContext* wfc, UINT32 x, UINT32 y, UINT32 width,
                          UINT32 height)
{
	RECT rect;
	rdpGdi* gdi = wfc->context.gdi;
	wfc->update_rect.left = x + wfc->offset_x;
	wfc->update_rect.top = y + wfc->offset_y;
	wfc->update_rect.right = wfc->update_rect.left + width;
	wfc->update_rect.bottom = wfc->update_rect.top + height;
	wf_scale_rect(wfc, &(wfc->update_rect));
	InvalidateRect(wfc->hwnd, &(wfc->update_rect), FALSE);
	rect.left = x;
	rect.right = width;
	rect.top = y;
	rect.bottom = height;
	wf_scale_rect(wfc, &rect);
	gdi_InvalidateRegion(gdi->primary->hdc, rect.left, rect.top, rect.right,
	                     rect.bottom);
}
Exemplo n.º 7
0
static UINT gdi_OutputUpdate(rdpGdi* gdi, gdiGfxSurface* surface)
{
	UINT32 nXDst, nYDst;
	UINT32 nXSrc, nYSrc;
	UINT16 width, height;
	UINT32 surfaceX, surfaceY;
	RECTANGLE_16 surfaceRect;
	const RECTANGLE_16* extents;
	rdpUpdate* update = gdi->context->update;
	surfaceX = surface->outputOriginX;
	surfaceY = surface->outputOriginY;
	surfaceRect.left = 0;
	surfaceRect.top = 0;
	surfaceRect.right = surface->width;
	surfaceRect.bottom = surface->height;
	region16_intersect_rect(&(surface->invalidRegion),
	                        &(surface->invalidRegion), &surfaceRect);

	if (!region16_is_empty(&(surface->invalidRegion)))
	{
		extents = region16_extents(&(surface->invalidRegion));
		nXSrc = extents->left;
		nYSrc = extents->top;
		nXDst = surfaceX + extents->left;
		nYDst = surfaceY + extents->top;
		width = extents->right - extents->left;
		height = extents->bottom - extents->top;
		update->BeginPaint(gdi->context);

		if (!freerdp_image_copy(gdi->primary_buffer, gdi->primary->hdc->format,
		                        gdi->stride,
		                        nXDst, nYDst, width, height,
		                        surface->data, surface->format,
		                        surface->scanline, nXSrc, nYSrc, NULL, FREERDP_FLIP_NONE))
			return CHANNEL_RC_NULL_DATA;

		gdi_InvalidateRegion(gdi->primary->hdc, nXDst, nYDst, width, height);
		update->EndPaint(gdi->context);
	}

	region16_clear(&(surface->invalidRegion));
	return CHANNEL_RC_OK;
}
Exemplo n.º 8
0
void xf_gdi_line_to(rdpContext* context, LINE_TO_ORDER* line_to)
{
	UINT32 color;
	xfContext* xfc = (xfContext*) context;

	xf_lock_x11(xfc, FALSE);

	xf_set_rop2(xfc, line_to->bRop2);
	color = freerdp_convert_gdi_order_color(line_to->penColor, context->settings->ColorDepth, xfc->format, xfc->palette);
	color = xf_gdi_get_color(xfc, color);

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

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

	if (xfc->drawing == xfc->primary)
	{
		if (!xfc->remote_app)
		{
			XDrawLine(xfc->display, xfc->drawable, xfc->gc,
					line_to->nXStart, line_to->nYStart, line_to->nXEnd, line_to->nYEnd);
		}
		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(xfc->hdc, line_to->nXStart, line_to->nYStart, width, height);

	}

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

	xf_unlock_x11(xfc, FALSE);
}
Exemplo n.º 9
0
void wf_invalidate_region(wfContext* wfc, int x, int y, int width, int height)
{
	RECT rect;

	wfc->update_rect.left = x + wfc->offset_x;
	wfc->update_rect.top = y + wfc->offset_y;
	wfc->update_rect.right = wfc->update_rect.left + width;
	wfc->update_rect.bottom = wfc->update_rect.top + height;

	wf_scale_rect(wfc, &(wfc->update_rect));
	InvalidateRect(wfc->hwnd, &(wfc->update_rect), FALSE);

	rect.left = x;
	rect.right = width;
	rect.top = y;
	rect.bottom = height;
	wf_scale_rect(wfc, &rect);
	gdi_InvalidateRegion(wfc->hdc, rect.left, rect.top, rect.right, rect.bottom);
}
Exemplo n.º 10
0
static BOOL xf_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap)
{
	XImage* image;
	int width, height;
	xfContext* xfc = (xfContext*) context;
	BOOL ret = TRUE;
	width = bitmap->right - bitmap->left + 1;
	height = bitmap->bottom - bitmap->top + 1;
	xf_lock_x11(xfc, FALSE);
	XSetFunction(xfc->display, xfc->gc, GXcopy);
	image = XCreateImage(xfc->display, xfc->visual, xfc->depth,
	                     ZPixmap, 0, (char*) bitmap->data, bitmap->width, bitmap->height,
	                     xfc->scanline_pad, 0);
	XPutImage(xfc->display, xfc->primary, xfc->gc,
	          image, 0, 0, bitmap->left, bitmap->top, width, height);
	XFree(image);
	ret = gdi_InvalidateRegion(xfc->hdc, bitmap->left, bitmap->top, width, height);
	xf_unlock_x11(xfc, FALSE);
	return TRUE;
}
Exemplo n.º 11
0
void xf_gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt)
{
    xfInfo* xfi = ((xfContext*) context)->xfi;

    xf_lock_x11(xfi, FALSE);

    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)
    {
        gdi_InvalidateRegion(xfi->hdc, scrblt->nLeftRect, scrblt->nTopRect, scrblt->nWidth, scrblt->nHeight);
    }

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

    xf_unlock_x11(xfi, FALSE);
}
Exemplo n.º 12
0
static BOOL xf_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap)
{
	int width, height;
	xfContext* xfc = (xfContext*) context;
	xfBitmap* xbitmap = (xfBitmap*)bitmap;
	BOOL ret;

	if (!context || !xbitmap)
		return FALSE;

	width = bitmap->right - bitmap->left + 1;
	height = bitmap->bottom - bitmap->top + 1;
	xf_lock_x11(xfc, FALSE);
	XSetFunction(xfc->display, xfc->gc, GXcopy);
	XPutImage(xfc->display, xfc->primary, xfc->gc,
	          xbitmap->image, 0, 0, bitmap->left, bitmap->top, width, height);
	ret = gdi_InvalidateRegion(xfc->hdc, bitmap->left, bitmap->top, width, height);
	xf_unlock_x11(xfc, FALSE);
	return ret;
}
Exemplo n.º 13
0
void xf_gdi_line_to(rdpContext* context, LINE_TO_ORDER* line_to)
{
	UINT32 color;
	xfContext* context_ = (xfContext*) context;
	xfInfo* xfi = context_->xfi;

	xf_set_rop2(xfi, line_to->bRop2);
	color = freerdp_color_convert_rgb(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;

		if (xfi->remote_app != TRUE)
		{
			XDrawLine(xfi->display, xfi->drawable, xfi->gc,
				line_to->nXStart, line_to->nYStart, line_to->nXEnd, line_to->nYEnd);
		}

		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);
}
Exemplo n.º 14
0
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)
	{
		if (xfi->remote_app != True)
		{
			XFillRectangle(xfi->display, xfi->drawable, xfi->gc,
				dstblt->nLeftRect, dstblt->nTopRect, dstblt->nWidth, dstblt->nHeight);
		}

		gdi_InvalidateRegion(xfi->hdc, dstblt->nLeftRect, dstblt->nTopRect, dstblt->nWidth, dstblt->nHeight);
	}
}
Exemplo n.º 15
0
void xf_gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt)
{
    xfInfo* xfi = ((xfContext*) context)->xfi;

    xf_lock_x11(xfi, FALSE);

    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)
    {
        gdi_InvalidateRegion(xfi->hdc, dstblt->nLeftRect, dstblt->nTopRect, dstblt->nWidth, dstblt->nHeight);
    }

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

    xf_unlock_x11(xfi, FALSE);
}
Exemplo n.º 16
0
static BOOL xf_gdi_surface_frame_marker(rdpContext* context,
                                        const SURFACE_FRAME_MARKER* surface_frame_marker)
{
	rdpSettings* settings;
	xfContext* xfc = (xfContext*) context;
	BOOL ret = TRUE;
	settings = xfc->context.settings;
	xf_lock_x11(xfc, FALSE);

	switch (surface_frame_marker->frameAction)
	{
		case SURFACECMD_FRAMEACTION_BEGIN:
			xfc->frame_begin = TRUE;
			xfc->frame_x1 = 0;
			xfc->frame_y1 = 0;
			xfc->frame_x2 = 0;
			xfc->frame_y2 = 0;
			break;

		case SURFACECMD_FRAMEACTION_END:
			xfc->frame_begin = FALSE;

			if ((xfc->frame_x2 > xfc->frame_x1) && (xfc->frame_y2 > xfc->frame_y1))
				ret = gdi_InvalidateRegion(xfc->hdc, xfc->frame_x1, xfc->frame_y1,
				                           xfc->frame_x2 - xfc->frame_x1, xfc->frame_y2 - xfc->frame_y1);

			if (settings->FrameAcknowledge > 0)
			{
				IFCALL(xfc->context.update->SurfaceFrameAcknowledge, context,
				       surface_frame_marker->frameId);
			}

			break;
	}

	xf_unlock_x11(xfc, FALSE);
	return ret;
}
Exemplo n.º 17
0
void xf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect)
{
	int i;
	UINT32 color;
	DELTA_RECT* rectangle;
	xfContext* xfc = (xfContext*) context;

	xf_lock_x11(xfc, FALSE);

	color = freerdp_convert_gdi_order_color(multi_opaque_rect->color, context->settings->ColorDepth, xfc->format, xfc->palette);
	color = xf_gdi_get_color(xfc, color);

	XSetFunction(xfc->display, xfc->gc, GXcopy);
	XSetFillStyle(xfc->display, xfc->gc, FillSolid);
	XSetForeground(xfc->display, xfc->gc, color);

	for (i = 1; i < multi_opaque_rect->numRectangles + 1; i++)
	{
		rectangle = &multi_opaque_rect->rectangles[i];

		XFillRectangle(xfc->display, xfc->drawing, xfc->gc,
				rectangle->left, rectangle->top,
				rectangle->width, rectangle->height);

		if (xfc->drawing == xfc->primary)
		{
			if (!xfc->remote_app)
			{
				XFillRectangle(xfc->display, xfc->drawable, xfc->gc,
						rectangle->left, rectangle->top,
						rectangle->width, rectangle->height);
			}
			gdi_InvalidateRegion(xfc->hdc, rectangle->left, rectangle->top, rectangle->width, rectangle->height);
		}
	}

	xf_unlock_x11(xfc, FALSE);
}
Exemplo n.º 18
0
void xf_gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker)
{
	xfInfo* xfi;
	rdpSettings* settings;

	xfi = ((xfContext*) context)->xfi;
	settings = xfi->instance->settings;
	switch (surface_frame_marker->frameAction)
	{
		case SURFACECMD_FRAMEACTION_BEGIN:
			xfi->frame_begin = TRUE;
			xfi->frame_x1 = 0;
			xfi->frame_y1 = 0;
			xfi->frame_x2 = 0;
			xfi->frame_y2 = 0;
			break;

		case SURFACECMD_FRAMEACTION_END:
			xfi->frame_begin = FALSE;
			if (xfi->frame_x2 > xfi->frame_x1 && xfi->frame_y2 > xfi->frame_y1)
			{
				XSetFunction(xfi->display, xfi->gc, GXcopy);
				XSetFillStyle(xfi->display, xfi->gc, FillSolid);

				XCopyArea(xfi->display, xfi->primary, xfi->drawable, xfi->gc,
					xfi->frame_x1, xfi->frame_y1,
					xfi->frame_x2 - xfi->frame_x1, xfi->frame_y2 - xfi->frame_y1,
					xfi->frame_x1, xfi->frame_y1);
				gdi_InvalidateRegion(xfi->hdc, xfi->frame_x1, xfi->frame_y1,
					xfi->frame_x2 - xfi->frame_x1, xfi->frame_y2 - xfi->frame_y1);
			}
			if (settings->FrameAcknowledge > 0)
			{
				IFCALL(xfi->instance->update->SurfaceFrameAcknowledge, context, surface_frame_marker->frameId);
			}
			break;
	}
}
Exemplo n.º 19
0
BOOL PatBlt_16bpp(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, DWORD rop)
{
	if (!gdi_ClipCoords(hdc, &nXLeft, &nYLeft, &nWidth, &nHeight, NULL, NULL))
		return TRUE;
	
	if (!gdi_InvalidateRegion(hdc, nXLeft, nYLeft, nWidth, nHeight))
		return FALSE;

	switch (rop)
	{
		case GDI_PATCOPY:
			return BitBlt_PATCOPY_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);

		case GDI_PATINVERT:
			return BitBlt_PATINVERT_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);

		case GDI_DSTINVERT:
			return BitBlt_DSTINVERT_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);

		case GDI_BLACKNESS:
			return BitBlt_BLACKNESS_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);

		case GDI_WHITENESS:
			return BitBlt_WHITENESS_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);

		case GDI_DPa:
			return BitBlt_DPa_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);

		case GDI_PDxn:
			return BitBlt_PDxn_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);

		default:
			break;
	}
	
	WLog_ERR(TAG,  "PatBlt: unknown rop: 0x%08X", rop);
	return FALSE;
}
Exemplo n.º 20
0
void xf_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt)
{
    xfBitmap* bitmap;
    xfInfo* xfi = ((xfContext*) context)->xfi;

    xf_lock_x11(xfi, FALSE);

    bitmap = (xfBitmap*) memblt->bitmap;
    xf_set_rop3(xfi, gdi_rop3_code(memblt->bRop));

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

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

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

    xf_unlock_x11(xfi, FALSE);
}
Exemplo n.º 21
0
void xf_gdi_line_to(rdpUpdate* update, LINE_TO_ORDER* line_to)
{
	uint32 color;
	xfInfo* xfi = ((xfContext*) update->context)->xfi;

	xf_set_rop2(xfi, line_to->bRop2);
	color = freerdp_color_convert(line_to->penColor, xfi->srcBpp, 32, 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)
	{
		if (xfi->remote_app != True)
		{
			int width, height;

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

			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);
}
Exemplo n.º 22
0
void xf_gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt)
{
	Drawable dst;
	xfInfo* xfi = ((xfContext*) context)->xfi;

	xf_set_rop3(xfi, gdi_rop3_code(dstblt->bRop));
	GET_DST(xfi, dst);
	XSetFillStyle(xfi->display, xfi->gc, FillSolid);
	XFillRectangle(xfi->display, dst, xfi->gc,
			dstblt->nLeftRect, dstblt->nTopRect,
			dstblt->nWidth, dstblt->nHeight);
	if (xfi->drawing == xfi->primary)
	{
		if (!xfi->remote_app && !xfi->skip_bs)
		{
			XFillRectangle(xfi->display, xfi->drawable, xfi->gc,
					dstblt->nLeftRect, dstblt->nTopRect,
					dstblt->nWidth, dstblt->nHeight);
		}
		gdi_InvalidateRegion(xfi->hdc, dstblt->nLeftRect, dstblt->nTopRect,
				dstblt->nWidth, dstblt->nHeight);
	}
	XSetFunction(xfi->display, xfi->gc, GXcopy);
}
Exemplo n.º 23
0
void xf_gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker)
{
    xfInfo* xfi;
    rdpSettings* settings;

    xfi = ((xfContext*) context)->xfi;
    settings = xfi->instance->settings;

    xf_lock_x11(xfi, FALSE);

    switch (surface_frame_marker->frameAction)
    {
    case SURFACECMD_FRAMEACTION_BEGIN:
        xfi->frame_begin = TRUE;
        xfi->frame_x1 = 0;
        xfi->frame_y1 = 0;
        xfi->frame_x2 = 0;
        xfi->frame_y2 = 0;
        break;

    case SURFACECMD_FRAMEACTION_END:
        xfi->frame_begin = FALSE;
        if ((xfi->frame_x2 > xfi->frame_x1) && (xfi->frame_y2 > xfi->frame_y1))
        {
            gdi_InvalidateRegion(xfi->hdc, xfi->frame_x1, xfi->frame_y1,
                                 xfi->frame_x2 - xfi->frame_x1, xfi->frame_y2 - xfi->frame_y1);
        }
        if (settings->FrameAcknowledge > 0)
        {
            IFCALL(xfi->instance->update->SurfaceFrameAcknowledge, context, surface_frame_marker->frameId);
        }
        break;
    }

    xf_unlock_x11(xfi, FALSE);
}
Exemplo n.º 24
0
static BOOL xf_gdi_dstblt(rdpContext* context, const DSTBLT_ORDER* dstblt)
{
	xfContext* xfc = (xfContext*) context;
	BOOL ret = FALSE;
	xf_lock_x11(xfc, FALSE);

	if (!xf_set_rop3(xfc, gdi_rop3_code(dstblt->bRop)))
		goto fail;

	XSetFillStyle(xfc->display, xfc->gc, FillSolid);
	XFillRectangle(xfc->display, xfc->drawing, xfc->gc,
	               dstblt->nLeftRect, dstblt->nTopRect,
	               dstblt->nWidth, dstblt->nHeight);
	ret = TRUE;

	if (xfc->drawing == xfc->primary)
		ret = gdi_InvalidateRegion(xfc->hdc, dstblt->nLeftRect, dstblt->nTopRect,
		                           dstblt->nWidth, dstblt->nHeight);

fail:
	XSetFunction(xfc->display, xfc->gc, GXcopy);
	xf_unlock_x11(xfc, FALSE);
	return ret;
}
Exemplo n.º 25
0
void xf_gdi_memblt(rdpUpdate* update, MEMBLT_ORDER* memblt)
{
	xfBitmap* bitmap;
	xfInfo* xfi = GET_XFI(update);

	bitmap = (xfBitmap*) memblt->bitmap;
	xf_set_rop3(xfi, gdi_rop3_code(memblt->bRop));

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

	if (xfi->drawing == xfi->primary)
	{
		if (xfi->remote_app != True)
		{
			XCopyArea(xfi->display, bitmap->pixmap, xfi->drawable, xfi->gc,
				memblt->nXSrc, memblt->nYSrc, memblt->nWidth, memblt->nHeight,
				memblt->nLeftRect, memblt->nTopRect);
		}

		gdi_InvalidateRegion(xfi->hdc, memblt->nLeftRect, memblt->nTopRect, memblt->nWidth, memblt->nHeight);
	}
}
Exemplo n.º 26
0
Arquivo: gdi.c Projeto: AMV007/FreeRDP
static void gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate)
{
	int status;
	int nXDst;
	int nYDst;
	int nXSrc;
	int nYSrc;
	int nWidth;
	int nHeight;
	int nSrcStep;
	int nDstStep;
	UINT32 index;
	BYTE* pSrcData;
	BYTE* pDstData;
	UINT32 SrcSize;
	BOOL compressed;
	UINT32 SrcFormat;
	UINT32 bitsPerPixel;
	BITMAP_DATA* bitmap;
	rdpGdi* gdi = context->gdi;
	rdpCodecs* codecs = context->codecs;

	for (index = 0; index < bitmapUpdate->number; index++)
	{
		bitmap = &(bitmapUpdate->rectangles[index]);

		nXSrc = 0;
		nYSrc = 0;

		nXDst = bitmap->destLeft;
		nYDst = bitmap->destTop;

		nWidth = bitmap->width;
		nHeight = bitmap->height;

		pSrcData = bitmap->bitmapDataStream;
		SrcSize = bitmap->bitmapLength;

		compressed = bitmap->compressed;
		bitsPerPixel = bitmap->bitsPerPixel;

		if (gdi->bitmap_size < (nWidth * nHeight * 4))
		{
			gdi->bitmap_size = nWidth * nHeight * 4;
			gdi->bitmap_buffer = (BYTE*) _aligned_realloc(gdi->bitmap_buffer, gdi->bitmap_size, 16);

			if (!gdi->bitmap_buffer)
				return;
		}

		if (compressed)
		{
			pDstData = gdi->bitmap_buffer;

			if (bitsPerPixel < 32)
			{
				freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_INTERLEAVED);

				status = interleaved_decompress(codecs->interleaved, pSrcData, SrcSize, bitsPerPixel,
						&pDstData, gdi->format, -1, 0, 0, nWidth, nHeight, gdi->palette);
			}
			else
			{
				freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_PLANAR);

				status = planar_decompress(codecs->planar, pSrcData, SrcSize, &pDstData,
						gdi->format, -1, 0, 0, nWidth, nHeight, TRUE);
			}

			if (status < 0)
			{
				WLog_ERR(TAG, "bitmap decompression failure");
				return;
			}

			pSrcData = gdi->bitmap_buffer;
		}
		else
		{
			pDstData = gdi->bitmap_buffer;
			SrcFormat = gdi_get_pixel_format(bitsPerPixel, TRUE);

			status = freerdp_image_copy(pDstData, gdi->format, -1, 0, 0,
						nWidth, nHeight, pSrcData, SrcFormat, -1, 0, 0, gdi->palette);

			pSrcData = gdi->bitmap_buffer;
		}

		nSrcStep = nWidth * gdi->bytesPerPixel;

		pDstData = gdi->primary_buffer;
		nDstStep = gdi->width * gdi->bytesPerPixel;

		nWidth = bitmap->destRight - bitmap->destLeft + 1; /* clip width */
		nHeight = bitmap->destBottom - bitmap->destTop + 1; /* clip height */

		status = freerdp_image_copy(pDstData, gdi->format, nDstStep, nXDst, nYDst,
				nWidth, nHeight, pSrcData, gdi->format, nSrcStep, nXSrc, nYSrc, gdi->palette);

		gdi_InvalidateRegion(gdi->primary->hdc, nXDst, nYDst, nWidth, nHeight);
	}
}
Exemplo n.º 27
0
int BitBlt_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, int rop)
{
	if (hdcSrc != NULL)
	{
		if (gdi_ClipCoords(hdcDest, &nXDest, &nYDest, &nWidth, &nHeight, &nXSrc, &nYSrc) == 0)
			return 0;
	}
	else
	{
		if (gdi_ClipCoords(hdcDest, &nXDest, &nYDest, &nWidth, &nHeight, NULL, NULL) == 0)
			return 0;
	}
	
	gdi_InvalidateRegion(hdcDest, nXDest, nYDest, nWidth, nHeight);
	
	switch (rop)
	{
		case GDI_BLACKNESS:
			return BitBlt_BLACKNESS_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight);
			break;

		case GDI_WHITENESS:
			return BitBlt_WHITENESS_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight);
			break;

		case GDI_SRCCOPY:
			return BitBlt_SRCCOPY_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
			break;

		case GDI_SPna:
			return BitBlt_SPna_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
			break;

		case GDI_DSna:
			return BitBlt_DSna_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
			break;

		case GDI_DSPDxax:
			return BitBlt_DSPDxax_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
			break;
			
		case GDI_NOTSRCCOPY:
			return BitBlt_NOTSRCCOPY_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
			break;

		case GDI_DSTINVERT:
			return BitBlt_DSTINVERT_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight);
			break;

		case GDI_SRCERASE:
			return BitBlt_SRCERASE_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
			break;

		case GDI_NOTSRCERASE:
			return BitBlt_NOTSRCERASE_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
			break;

		case GDI_SRCINVERT:
			return BitBlt_SRCINVERT_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
			break;

		case GDI_SRCAND:
			return BitBlt_SRCAND_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
			break;

		case GDI_SRCPAINT:
			return BitBlt_SRCPAINT_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
			break;

		case GDI_MERGECOPY:
			return BitBlt_MERGECOPY_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
			break;

		case GDI_MERGEPAINT:
			return BitBlt_MERGEPAINT_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
			break;

		case GDI_PATCOPY:
			return BitBlt_PATCOPY_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight);
			break;

		case GDI_PATINVERT:
			return BitBlt_PATINVERT_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight);
			break;

		case GDI_PATPAINT:
			return BitBlt_PATPAINT_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
			break;
	}
	
	printf("BitBlt: unknown rop: 0x%08X\n", rop);
	return 1;
}
Exemplo n.º 28
0
BOOL gdi_FillRect(HGDI_DC hdc, const HGDI_RECT rect, HGDI_BRUSH hbr)
{
	UINT32 x, y;
	UINT32 color, dstColor;
	BOOL monochrome = FALSE;
	UINT32 nXDest, nYDest;
	UINT32 nWidth, nHeight;
	const BYTE* srcp;
	DWORD formatSize;
	gdi_RectToCRgn(rect, &nXDest, &nYDest, &nWidth, &nHeight);

	if (!hdc || !hbr)
		return FALSE;

	if (!gdi_ClipCoords(hdc, &nXDest, &nYDest, &nWidth, &nHeight, NULL, NULL))
		return TRUE;

	switch (hbr->style)
	{
		case GDI_BS_SOLID:
			color = hbr->color;

			for (x = 0; x < nWidth; x++)
			{
				BYTE* dstp = gdi_get_bitmap_pointer(hdc, nXDest + x,
				                                    nYDest);

				if (dstp)
					WriteColor(dstp, hdc->format, color);
			}

			srcp = gdi_get_bitmap_pointer(hdc, nXDest, nYDest);
			formatSize = GetBytesPerPixel(hdc->format);

			for (y = 1; y < nHeight; y++)
			{
				BYTE* dstp = gdi_get_bitmap_pointer(hdc, nXDest, nYDest + y);
				memcpy(dstp, srcp, nWidth * formatSize);
			}

			break;

		case GDI_BS_HATCHED:
		case GDI_BS_PATTERN:
			monochrome = (hbr->pattern->format == PIXEL_FORMAT_MONO);
			formatSize = GetBytesPerPixel(hbr->pattern->format);

			for (y = 0; y < nHeight; y++)
			{
				for (x = 0; x < nWidth; x++)
				{
					const UINT32 yOffset = ((nYDest + y) * hbr->pattern->width %
					                        hbr->pattern->height) * formatSize;
					const UINT32 xOffset = ((nXDest + x) % hbr->pattern->width) * formatSize;
					const BYTE* patp = &hbr->pattern->data[yOffset + xOffset];
					BYTE* dstp = gdi_get_bitmap_pointer(hdc, nXDest + x,
					                                    nYDest + y);

					if (!patp)
						return FALSE;

					if (monochrome)
					{
						if (*patp == 0)
							dstColor = hdc->bkColor;
						else
							dstColor = hdc->textColor;
					}
					else
					{
						dstColor = ReadColor(patp, hbr->pattern->format);
						dstColor = ConvertColor(dstColor, hbr->pattern->format, hdc->format, NULL);
					}

					if (dstp)
						WriteColor(dstp, hdc->format, dstColor);
				}
			}

			break;

		default:
			break;
	}

	if (!gdi_InvalidateRegion(hdc, nXDest, nYDest, nWidth, nHeight))
		return FALSE;

	return TRUE;
}
Exemplo n.º 29
0
void xf_gdi_surface_bits(rdpUpdate* update, SURFACE_BITS_COMMAND* surface_bits_command)
{
	int i, tx, ty;
	XImage* image;
	RFX_MESSAGE* message;
	xfInfo* xfi = GET_XFI(update);
	RFX_CONTEXT* context = (RFX_CONTEXT*) xfi->rfx_context;
	NSC_CONTEXT* ncontext = (NSC_CONTEXT*) xfi->nsc_context;

	if (surface_bits_command->codecID == CODEC_ID_REMOTEFX)
	{
		message = rfx_process_message(context, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);

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

		XSetClipRectangles(xfi->display, xfi->gc,
				surface_bits_command->destLeft, surface_bits_command->destTop,
				(XRectangle*) message->rects, message->num_rects, YXBanded);

		/* Draw the tiles to primary surface, each is 64x64. */
		for (i = 0; i < message->num_tiles; i++)
		{
			image = XCreateImage(xfi->display, xfi->visual, 24, ZPixmap, 0,
				(char*) message->tiles[i]->data, 64, 64, 32, 0);

			tx = message->tiles[i]->x + surface_bits_command->destLeft;
			ty = message->tiles[i]->y + surface_bits_command->destTop;

			XPutImage(xfi->display, xfi->primary, xfi->gc, image, 0, 0, tx, ty, 64, 64);
			XFree(image);
		}

		/* Copy the updated region from backstore to the window. */
		for (i = 0; i < message->num_rects; i++)
		{
			tx = message->rects[i].x + surface_bits_command->destLeft;
			ty = message->rects[i].y + surface_bits_command->destTop;

			if (xfi->remote_app != True)
			{
				XCopyArea(xfi->display, xfi->primary, xfi->drawable, xfi->gc,
						tx, ty, message->rects[i].width, message->rects[i].height, tx, ty);
			}

			gdi_InvalidateRegion(xfi->hdc, tx, ty, message->rects[i].width, message->rects[i].height);
		}

		XSetClipMask(xfi->display, xfi->gc, None);
		rfx_message_free(context, message);
	}
	else if (surface_bits_command->codecID == CODEC_ID_NSCODEC)
	{
		ncontext->width = surface_bits_command->width;
		ncontext->height = surface_bits_command->height;
		nsc_process_message(ncontext, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);
		XSetFunction(xfi->display, xfi->gc, GXcopy);
		XSetFillStyle(xfi->display, xfi->gc, FillSolid);

		xfi->bmp_codec_nsc = (uint8*) xrealloc(xfi->bmp_codec_nsc,
				surface_bits_command->width * surface_bits_command->height * 4);

		freerdp_image_flip(ncontext->bmpdata, xfi->bmp_codec_nsc,
				surface_bits_command->width, surface_bits_command->height, 32);

		image = XCreateImage(xfi->display, xfi->visual, 24, ZPixmap, 0,
			(char*) xfi->bmp_codec_nsc, surface_bits_command->width, surface_bits_command->height, 32, 0);

		XPutImage(xfi->display, xfi->primary, xfi->gc, image, 0, 0,
				surface_bits_command->destLeft, surface_bits_command->destTop,
				surface_bits_command->width, surface_bits_command->height);

		if (xfi->remote_app != True)
		{
			XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc,
				surface_bits_command->destLeft, surface_bits_command->destTop,
				surface_bits_command->width, surface_bits_command->height,
				surface_bits_command->destLeft, surface_bits_command->destTop);
		}

		gdi_InvalidateRegion(xfi->hdc, surface_bits_command->destLeft, surface_bits_command->destTop,
				surface_bits_command->width, surface_bits_command->height);

		XSetClipMask(xfi->display, xfi->gc, None);
		nsc_context_destroy(ncontext);
	}
	else if (surface_bits_command->codecID == CODEC_ID_NONE)
	{
		XSetFunction(xfi->display, xfi->gc, GXcopy);
		XSetFillStyle(xfi->display, xfi->gc, FillSolid);

		xfi->bmp_codec_none = (uint8*) xrealloc(xfi->bmp_codec_none,
				surface_bits_command->width * surface_bits_command->height * 4);

		freerdp_image_flip(surface_bits_command->bitmapData, xfi->bmp_codec_none,
				surface_bits_command->width, surface_bits_command->height, 32);

		image = XCreateImage(xfi->display, xfi->visual, 24, ZPixmap, 0,
			(char*) xfi->bmp_codec_none, surface_bits_command->width, surface_bits_command->height, 32, 0);

		XPutImage(xfi->display, xfi->primary, xfi->gc, image, 0, 0,
				surface_bits_command->destLeft, surface_bits_command->destTop,
				surface_bits_command->width, surface_bits_command->height);

		if (xfi->remote_app != True)
		{
			XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc,
				surface_bits_command->destLeft, surface_bits_command->destTop,
				surface_bits_command->width, surface_bits_command->height,
				surface_bits_command->destLeft, surface_bits_command->destTop);
		}

		gdi_InvalidateRegion(xfi->hdc, surface_bits_command->destLeft, surface_bits_command->destTop,
				surface_bits_command->width, surface_bits_command->height);

		XSetClipMask(xfi->display, xfi->gc, None);
	}
	else
	{
		printf("Unsupported codecID %d\n", surface_bits_command->codecID);
	}
}
Exemplo n.º 30
0
void xf_gdi_fast_index(rdpUpdate* update, FAST_INDEX_ORDER* fast_index)
{
	int i, j;
	int x, y;
	int w, h;
	Pixmap bmp;
	Pixmap* bmps;
	uint32 fgcolor;
	uint32 bgcolor;
	GLYPH_DATA* glyph;
	GLYPH_DATA** glyphs;
	GLYPH_FRAGMENT* fragment;
	xfInfo* xfi = GET_XFI(update);

	fgcolor = freerdp_color_convert(fast_index->foreColor, xfi->srcBpp, 32, xfi->clrconv);
	bgcolor = freerdp_color_convert(fast_index->backColor, xfi->srcBpp, 32, xfi->clrconv);

	XSetFunction(xfi->display, xfi->gc, GXcopy);
	XSetForeground(xfi->display, xfi->gc, bgcolor);
	XSetBackground(xfi->display, xfi->gc, fgcolor);

	if (fast_index->opaqueRect)
	{
		XSetFillStyle(xfi->display, xfi->gc, FillSolid);

		x = fast_index->opLeft;
		y = fast_index->opTop;
		w = fast_index->opRight - fast_index->opLeft + 1;
		h = fast_index->opBottom - fast_index->opTop + 1;

		XFillRectangle(xfi->display, xfi->drawing, xfi->gc, x, y, w, h);

		if (xfi->drawing == xfi->primary)
		{
			if (xfi->remote_app != True)
			{
				XFillRectangle(xfi->display, xfi->drawable, xfi->gc, x, y, w, h);
			}

			gdi_InvalidateRegion(xfi->hdc, x, y, w, h);
		}
	}

	x = fast_index->bkLeft;
	y = fast_index->y;

	XSetFillStyle(xfi->display, xfi->gc, FillStippled);

	for (i = 0; i < fast_index->nfragments; i++)
	{
		fragment = &fast_index->fragments[i];

		if (fragment->operation == GLYPH_FRAGMENT_USE)
		{
			fragment->indices = (GLYPH_FRAGMENT_INDEX*) glyph_fragment_get(xfi->cache->glyph,
							fragment->index, &fragment->nindices, (void**) &bmps);

			glyphs = (GLYPH_DATA**) xmalloc(sizeof(GLYPH_DATA*) * fragment->nindices);

			for (j = 0; j < fragment->nindices; j++)
			{
				glyphs[j] = glyph_get(xfi->cache->glyph, fast_index->cacheId, fragment->indices[j].index, (void**) &bmps[j]);
			}
		}
		else
		{
			bmps = (Pixmap*) xmalloc(sizeof(Pixmap*) * fragment->nindices);
			glyphs = (GLYPH_DATA**) xmalloc(sizeof(GLYPH_DATA*) * fragment->nindices);

			for (j = 0; j < fragment->nindices; j++)
			{
				glyphs[j] = glyph_get(xfi->cache->glyph, fast_index->cacheId, fragment->indices[j].index, (void**) &bmps[j]);
			}
		}

		for (j = 0; j < fragment->nindices; j++)
		{
			bmp = bmps[j];
			glyph = glyphs[j];

			XSetStipple(xfi->display, xfi->gc, bmp);
			XSetTSOrigin(xfi->display, xfi->gc, glyph->x + x, glyph->y + y);
			XFillRectangle(xfi->display, xfi->drawing, xfi->gc, glyph->x + x, glyph->y + y, glyph->cx, glyph->cy);
			XSetStipple(xfi->display, xfi->gc, xfi->bitmap_mono);

			if ((j + 1) < fragment->nindices)
			{
				if (!(fast_index->flAccel & SO_CHAR_INC_EQUAL_BM_BASE))
				{
					if (fast_index->flAccel & SO_VERTICAL)
					{
						y += fragment->indices[j + 1].delta;
					}
					else
					{
						x += fragment->indices[j + 1].delta;
					}
				}
				else
				{
					x += glyph->cx;
				}
			}
		}

		if (fragment->operation == GLYPH_FRAGMENT_ADD)
		{
			glyph_fragment_put(xfi->cache->glyph, fragment->index,
					fragment->nindices, (void*) fragment->indices, (void*) bmps);
		}
	}

	if (xfi->drawing == xfi->primary)
	{
		if (xfi->remote_app != True)
		{
			XCopyArea(xfi->display, xfi->primary, xfi->drawable, xfi->gc,
				fast_index->bkLeft, fast_index->bkTop,
				fast_index->bkRight - fast_index->bkLeft + 1,
				fast_index->bkBottom - fast_index->bkTop + 1,
				fast_index->bkLeft, fast_index->bkTop);
		}

		gdi_InvalidateRegion(xfi->hdc, fast_index->bkLeft, fast_index->bkTop,
				fast_index->bkRight - fast_index->bkLeft + 1,
				fast_index->bkBottom - fast_index->bkTop + 1);
	}
}