Blame client/X11/xf_graphics.c

Packit Service fa4841
/**
Packit Service fa4841
 * FreeRDP: A Remote Desktop Protocol Implementation
Packit Service fa4841
 * X11 Graphical Objects
Packit Service fa4841
 *
Packit Service fa4841
 * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
Packit Service fa4841
 * Copyright 2016 Thincast Technologies GmbH
Packit Service fa4841
 * Copyright 2016 Armin Novak <armin.novak@thincast.com>
Packit Service fa4841
 *
Packit Service fa4841
 * Licensed under the Apache License, Version 2.0 (the "License");
Packit Service fa4841
 * you may not use this file except in compliance with the License.
Packit Service fa4841
 * You may obtain a copy of the License at
Packit Service fa4841
 *
Packit Service fa4841
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit Service fa4841
 *
Packit Service fa4841
 * Unless required by applicable law or agreed to in writing, software
Packit Service fa4841
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit Service fa4841
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit Service fa4841
 * See the License for the specific language governing permissions and
Packit Service fa4841
 * limitations under the License.
Packit Service fa4841
 */
Packit Service fa4841
Packit Service fa4841
#ifdef HAVE_CONFIG_H
Packit Service fa4841
#include "config.h"
Packit Service fa4841
#endif
Packit Service fa4841
Packit Service fa4841
#include <X11/Xlib.h>
Packit Service fa4841
#include <X11/Xutil.h>
Packit Service fa4841
Packit Service fa4841
#ifdef WITH_XCURSOR
Packit Service fa4841
#include <X11/Xcursor/Xcursor.h>
Packit Service fa4841
#endif
Packit Service fa4841
Packit Service fa4841
#include <winpr/crt.h>
Packit Service fa4841
Packit Service fa4841
#include <freerdp/codec/bitmap.h>
Packit Service fa4841
#include <freerdp/codec/rfx.h>
Packit Service fa4841
Packit Service fa4841
#include "xf_graphics.h"
Packit Service fa4841
#include "xf_gdi.h"
Packit Service fa4841
Packit Service fa4841
#include <freerdp/log.h>
Packit Service fa4841
#define TAG CLIENT_TAG("x11")
Packit Service fa4841
Packit Service fa4841
BOOL xf_decode_color(xfContext* xfc, const UINT32 srcColor, XColor* color)
Packit Service fa4841
{
Packit Service fa4841
	rdpGdi* gdi;
Packit Service fa4841
	rdpSettings* settings;
Packit Service fa4841
	UINT32 SrcFormat;
Packit Service fa4841
	BYTE r, g, b, a;
Packit Service fa4841
Packit Service fa4841
	if (!xfc || !color)
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	gdi = xfc->context.gdi;
Packit Service fa4841
Packit Service fa4841
	if (!gdi)
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	settings = xfc->context.settings;
Packit Service fa4841
Packit Service fa4841
	if (!settings)
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	switch (settings->ColorDepth)
Packit Service fa4841
	{
Packit Service fa4841
		case 32:
Packit Service fa4841
		case 24:
Packit Service fa4841
			SrcFormat = PIXEL_FORMAT_BGR24;
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		case 16:
Packit Service fa4841
			SrcFormat = PIXEL_FORMAT_RGB16;
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		case 15:
Packit Service fa4841
			SrcFormat = PIXEL_FORMAT_RGB15;
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		case 8:
Packit Service fa4841
			SrcFormat = PIXEL_FORMAT_RGB8;
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		default:
Packit Service fa4841
			return FALSE;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	SplitColor(srcColor, SrcFormat, &r, &g, &b, &a, &gdi->palette);
Packit Service fa4841
	color->blue = (unsigned short)(b << 8);
Packit Service fa4841
	color->green = (unsigned short)(g << 8);
Packit Service fa4841
	color->red = (unsigned short)(r << 8);
Packit Service fa4841
	color->flags = DoRed | DoGreen | DoBlue;
Packit Service fa4841
Packit Service fa4841
	if (XAllocColor(xfc->display, xfc->colormap, color) == 0)
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
/* Bitmap Class */
Packit Service fa4841
static BOOL xf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap)
Packit Service fa4841
{
Packit Service fa4841
	BOOL rc = FALSE;
Packit Service fa4841
	UINT32 depth;
Packit Service fa4841
	BYTE* data;
Packit Service fa4841
	rdpGdi* gdi;
Packit Service fa4841
	xfBitmap* xbitmap = (xfBitmap*)bitmap;
Packit Service fa4841
	xfContext* xfc = (xfContext*)context;
Packit Service fa4841
Packit Service fa4841
	if (!context || !bitmap || !context->gdi)
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	gdi = context->gdi;
Packit Service fa4841
	xf_lock_x11(xfc);
Packit Service fa4841
	depth = GetBitsPerPixel(bitmap->format);
Packit Service fa4841
	xbitmap->pixmap =
Packit Service fa4841
	    XCreatePixmap(xfc->display, xfc->drawable, bitmap->width, bitmap->height, xfc->depth);
Packit Service fa4841
Packit Service fa4841
	if (!xbitmap->pixmap)
Packit Service fa4841
		goto unlock;
Packit Service fa4841
Packit Service fa4841
	if (bitmap->data)
Packit Service fa4841
	{
Packit Service fa4841
		XSetFunction(xfc->display, xfc->gc, GXcopy);
Packit Service fa4841
Packit Service fa4841
		if ((INT64)depth != xfc->depth)
Packit Service fa4841
		{
Packit Service fa4841
			if (!(data = _aligned_malloc(bitmap->width * bitmap->height * 4, 16)))
Packit Service fa4841
				goto unlock;
Packit Service fa4841
Packit Service fa4841
			if (!freerdp_image_copy(data, gdi->dstFormat, 0, 0, 0, bitmap->width, bitmap->height,
Packit Service fa4841
			                        bitmap->data, bitmap->format, 0, 0, 0, &context->gdi->palette,
Packit Service fa4841
			                        FREERDP_FLIP_NONE))
Packit Service fa4841
			{
Packit Service fa4841
				_aligned_free(data);
Packit Service fa4841
				goto unlock;
Packit Service fa4841
			}
Packit Service fa4841
Packit Service fa4841
			_aligned_free(bitmap->data);
Packit Service fa4841
			bitmap->data = data;
Packit Service fa4841
			bitmap->format = gdi->dstFormat;
Packit Service fa4841
		}
Packit Service fa4841
Packit Service fa4841
		xbitmap->image =
Packit Service fa4841
		    XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, (char*)bitmap->data,
Packit Service fa4841
		                 bitmap->width, bitmap->height, xfc->scanline_pad, 0);
Packit Service fa4841
Packit Service fa4841
		if (!xbitmap->image)
Packit Service fa4841
			goto unlock;
Packit Service fa4841
Packit Service fa4841
		xbitmap->image->byte_order = LSBFirst;
Packit Service fa4841
		xbitmap->image->bitmap_bit_order = LSBFirst;
Packit Service fa4841
		XPutImage(xfc->display, xbitmap->pixmap, xfc->gc, xbitmap->image, 0, 0, 0, 0, bitmap->width,
Packit Service fa4841
		          bitmap->height);
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	rc = TRUE;
Packit Service fa4841
unlock:
Packit Service fa4841
	xf_unlock_x11(xfc);
Packit Service fa4841
	return rc;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
static void xf_Bitmap_Free(rdpContext* context, rdpBitmap* bitmap)
Packit Service fa4841
{
Packit Service fa4841
	xfContext* xfc = (xfContext*)context;
Packit Service fa4841
	xfBitmap* xbitmap = (xfBitmap*)bitmap;
Packit Service fa4841
Packit Service fa4841
	if (!xfc || !xbitmap)
Packit Service fa4841
		return;
Packit Service fa4841
Packit Service fa4841
	xf_lock_x11(xfc);
Packit Service fa4841
Packit Service fa4841
	if (xbitmap->pixmap != 0)
Packit Service fa4841
	{
Packit Service fa4841
		XFreePixmap(xfc->display, xbitmap->pixmap);
Packit Service fa4841
		xbitmap->pixmap = 0;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	if (xbitmap->image)
Packit Service fa4841
	{
Packit Service fa4841
		xbitmap->image->data = NULL;
Packit Service fa4841
		XDestroyImage(xbitmap->image);
Packit Service fa4841
		xbitmap->image = NULL;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	xf_unlock_x11(xfc);
Packit Service fa4841
	_aligned_free(bitmap->data);
Packit Service fa4841
	free(xbitmap);
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
static BOOL xf_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap)
Packit Service fa4841
{
Packit Service fa4841
	int width, height;
Packit Service fa4841
	xfContext* xfc = (xfContext*)context;
Packit Service fa4841
	xfBitmap* xbitmap = (xfBitmap*)bitmap;
Packit Service fa4841
	BOOL ret;
Packit Service fa4841
Packit Service fa4841
	if (!context || !xbitmap)
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	width = bitmap->right - bitmap->left + 1;
Packit Service fa4841
	height = bitmap->bottom - bitmap->top + 1;
Packit Service fa4841
	xf_lock_x11(xfc);
Packit Service fa4841
	XSetFunction(xfc->display, xfc->gc, GXcopy);
Packit Service fa4841
	XPutImage(xfc->display, xfc->primary, xfc->gc, xbitmap->image, 0, 0, bitmap->left, bitmap->top,
Packit Service fa4841
	          width, height);
Packit Service fa4841
	ret = gdi_InvalidateRegion(xfc->hdc, bitmap->left, bitmap->top, width, height);
Packit Service fa4841
	xf_unlock_x11(xfc);
Packit Service fa4841
	return ret;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
static BOOL xf_Bitmap_SetSurface(rdpContext* context, rdpBitmap* bitmap, BOOL primary)
Packit Service fa4841
{
Packit Service fa4841
	xfContext* xfc = (xfContext*)context;
Packit Service fa4841
Packit Service fa4841
	if (!context || (!bitmap && !primary))
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	xf_lock_x11(xfc);
Packit Service fa4841
Packit Service fa4841
	if (primary)
Packit Service fa4841
		xfc->drawing = xfc->primary;
Packit Service fa4841
	else
Packit Service fa4841
		xfc->drawing = ((xfBitmap*)bitmap)->pixmap;
Packit Service fa4841
Packit Service fa4841
	xf_unlock_x11(xfc);
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
/* Pointer Class */
Packit Service fa4841
static BOOL xf_Pointer_New(rdpContext* context, rdpPointer* pointer)
Packit Service fa4841
{
Packit Service fa4841
#ifdef WITH_XCURSOR
Packit Service fa4841
	UINT32 CursorFormat;
Packit Service fa4841
	size_t size;
Packit Service fa4841
	XcursorImage ci;
Packit Service fa4841
	xfContext* xfc = (xfContext*)context;
Packit Service fa4841
	xfPointer* xpointer = (xfPointer*)pointer;
Packit Service fa4841
Packit Service fa4841
	if (!context || !pointer || !context->gdi)
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	if (!xfc->invert)
Packit Service fa4841
		CursorFormat = (!xfc->big_endian) ? PIXEL_FORMAT_RGBA32 : PIXEL_FORMAT_ABGR32;
Packit Service fa4841
	else
Packit Service fa4841
		CursorFormat = (!xfc->big_endian) ? PIXEL_FORMAT_BGRA32 : PIXEL_FORMAT_ARGB32;
Packit Service fa4841
Packit Service fa4841
	xf_lock_x11(xfc);
Packit Service fa4841
	ZeroMemory(&ci, sizeof(ci));
Packit Service fa4841
	ci.version = XCURSOR_IMAGE_VERSION;
Packit Service fa4841
	ci.size = sizeof(ci);
Packit Service fa4841
	ci.width = pointer->width;
Packit Service fa4841
	ci.height = pointer->height;
Packit Service fa4841
	ci.xhot = pointer->xPos;
Packit Service fa4841
	ci.yhot = pointer->yPos;
Packit Service fa4841
	size = ci.height * ci.width * GetBytesPerPixel(CursorFormat);
Packit Service fa4841
Packit Service fa4841
	if (!(ci.pixels = (XcursorPixel*)_aligned_malloc(size, 16)))
Packit Service fa4841
	{
Packit Service fa4841
		xf_unlock_x11(xfc);
Packit Service fa4841
		return FALSE;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	if (!freerdp_image_copy_from_pointer_data(
Packit Service fa4841
	        (BYTE*)ci.pixels, CursorFormat, 0, 0, 0, pointer->width, pointer->height,
Packit Service fa4841
	        pointer->xorMaskData, pointer->lengthXorMask, pointer->andMaskData,
Packit Service fa4841
	        pointer->lengthAndMask, pointer->xorBpp, &context->gdi->palette))
Packit Service fa4841
	{
Packit Service fa4841
		_aligned_free(ci.pixels);
Packit Service fa4841
		xf_unlock_x11(xfc);
Packit Service fa4841
		return FALSE;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	xpointer->cursor = XcursorImageLoadCursor(xfc->display, &ci);
Packit Service fa4841
	_aligned_free(ci.pixels);
Packit Service fa4841
	xf_unlock_x11(xfc);
Packit Service fa4841
#endif
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
static void xf_Pointer_Free(rdpContext* context, rdpPointer* pointer)
Packit Service fa4841
{
Packit Service fa4841
#ifdef WITH_XCURSOR
Packit Service fa4841
	xfContext* xfc = (xfContext*)context;
Packit Service fa4841
	xf_lock_x11(xfc);
Packit Service fa4841
Packit Service fa4841
	if (((xfPointer*)pointer)->cursor)
Packit Service fa4841
		XFreeCursor(xfc->display, ((xfPointer*)pointer)->cursor);
Packit Service fa4841
Packit Service fa4841
	xf_unlock_x11(xfc);
Packit Service fa4841
#endif
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
static BOOL xf_Pointer_Set(rdpContext* context, const rdpPointer* pointer)
Packit Service fa4841
{
Packit Service fa4841
#ifdef WITH_XCURSOR
Packit Service fa4841
	xfContext* xfc = (xfContext*)context;
Packit Service fa4841
	xf_lock_x11(xfc);
Packit Service fa4841
	xfc->pointer = (xfPointer*)pointer;
Packit Service fa4841
Packit Service fa4841
	/* in RemoteApp mode, window can be null if none has had focus */
Packit Service fa4841
Packit Service fa4841
	if (xfc->window)
Packit Service fa4841
		XDefineCursor(xfc->display, xfc->window->handle, xfc->pointer->cursor);
Packit Service fa4841
Packit Service fa4841
	xf_unlock_x11(xfc);
Packit Service fa4841
#endif
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
static BOOL xf_Pointer_SetNull(rdpContext* context)
Packit Service fa4841
{
Packit Service fa4841
#ifdef WITH_XCURSOR
Packit Service fa4841
	xfContext* xfc = (xfContext*)context;
Packit Service fa4841
	static Cursor nullcursor = None;
Packit Service fa4841
	xf_lock_x11(xfc);
Packit Service fa4841
Packit Service fa4841
	if (nullcursor == None)
Packit Service fa4841
	{
Packit Service fa4841
		XcursorImage ci;
Packit Service fa4841
		XcursorPixel xp = 0;
Packit Service fa4841
		ZeroMemory(&ci, sizeof(ci));
Packit Service fa4841
		ci.version = XCURSOR_IMAGE_VERSION;
Packit Service fa4841
		ci.size = sizeof(ci);
Packit Service fa4841
		ci.width = ci.height = 1;
Packit Service fa4841
		ci.xhot = ci.yhot = 0;
Packit Service fa4841
		ci.pixels = &xp;
Packit Service fa4841
		nullcursor = XcursorImageLoadCursor(xfc->display, &ci);
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	xfc->pointer = NULL;
Packit Service fa4841
Packit Service fa4841
	if ((xfc->window) && (nullcursor != None))
Packit Service fa4841
		XDefineCursor(xfc->display, xfc->window->handle, nullcursor);
Packit Service fa4841
Packit Service fa4841
	xf_unlock_x11(xfc);
Packit Service fa4841
#endif
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
static BOOL xf_Pointer_SetDefault(rdpContext* context)
Packit Service fa4841
{
Packit Service fa4841
#ifdef WITH_XCURSOR
Packit Service fa4841
	xfContext* xfc = (xfContext*)context;
Packit Service fa4841
	xf_lock_x11(xfc);
Packit Service fa4841
	xfc->pointer = NULL;
Packit Service fa4841
Packit Service fa4841
	if (xfc->window)
Packit Service fa4841
		XUndefineCursor(xfc->display, xfc->window->handle);
Packit Service fa4841
Packit Service fa4841
	xf_unlock_x11(xfc);
Packit Service fa4841
#endif
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
static BOOL xf_Pointer_SetPosition(rdpContext* context, UINT32 x, UINT32 y)
Packit Service fa4841
{
Packit Service fa4841
	xfContext* xfc = (xfContext*)context;
Packit Service fa4841
	XWindowAttributes current;
Packit Service fa4841
	XSetWindowAttributes tmp;
Packit Service fa4841
	BOOL ret = FALSE;
Packit Service fa4841
Packit Service fa4841
	if (!xfc->focused || !xfc->window)
Packit Service fa4841
		return TRUE;
Packit Service fa4841
Packit Service fa4841
	xf_lock_x11(xfc);
Packit Service fa4841
Packit Service fa4841
	if (XGetWindowAttributes(xfc->display, xfc->window->handle, &current) == 0)
Packit Service fa4841
		goto out;
Packit Service fa4841
Packit Service fa4841
	tmp.event_mask = (current.your_event_mask & ~(PointerMotionMask));
Packit Service fa4841
Packit Service fa4841
	if (XChangeWindowAttributes(xfc->display, xfc->window->handle, CWEventMask, &tmp) == 0)
Packit Service fa4841
		goto out;
Packit Service fa4841
Packit Service fa4841
	XWarpPointer(xfc->display, None, xfc->window->handle, 0, 0, 0, 0, x, y);
Packit Service fa4841
	tmp.event_mask = current.your_event_mask;
Packit Service fa4841
	XChangeWindowAttributes(xfc->display, xfc->window->handle, CWEventMask, &tmp);
Packit Service fa4841
	ret = TRUE;
Packit Service fa4841
out:
Packit Service fa4841
	xf_unlock_x11(xfc);
Packit Service fa4841
	return ret;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
/* Glyph Class */
Packit Service fa4841
static BOOL xf_Glyph_New(rdpContext* context, const rdpGlyph* glyph)
Packit Service fa4841
{
Packit Service fa4841
	int scanline;
Packit Service fa4841
	XImage* image;
Packit Service fa4841
	xfGlyph* xf_glyph;
Packit Service fa4841
	xf_glyph = (xfGlyph*)glyph;
Packit Service fa4841
	xfContext* xfc = (xfContext*)context;
Packit Service fa4841
	xf_lock_x11(xfc);
Packit Service fa4841
	scanline = (glyph->cx + 7) / 8;
Packit Service fa4841
	xf_glyph->pixmap = XCreatePixmap(xfc->display, xfc->drawing, glyph->cx, glyph->cy, 1);
Packit Service fa4841
	image = XCreateImage(xfc->display, xfc->visual, 1, ZPixmap, 0, (char*)glyph->aj, glyph->cx,
Packit Service fa4841
	                     glyph->cy, 8, scanline);
Packit Service fa4841
	image->byte_order = MSBFirst;
Packit Service fa4841
	image->bitmap_bit_order = MSBFirst;
Packit Service fa4841
	XInitImage(image);
Packit Service fa4841
	XPutImage(xfc->display, xf_glyph->pixmap, xfc->gc_mono, image, 0, 0, 0, 0, glyph->cx,
Packit Service fa4841
	          glyph->cy);
Packit Service fa4841
	image->data = NULL;
Packit Service fa4841
	XDestroyImage(image);
Packit Service fa4841
	xf_unlock_x11(xfc);
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
static void xf_Glyph_Free(rdpContext* context, rdpGlyph* glyph)
Packit Service fa4841
{
Packit Service fa4841
	xfContext* xfc = (xfContext*)context;
Packit Service fa4841
	xf_lock_x11(xfc);
Packit Service fa4841
Packit Service fa4841
	if (((xfGlyph*)glyph)->pixmap != 0)
Packit Service fa4841
		XFreePixmap(xfc->display, ((xfGlyph*)glyph)->pixmap);
Packit Service fa4841
Packit Service fa4841
	xf_unlock_x11(xfc);
Packit Service fa4841
	free(glyph->aj);
Packit Service fa4841
	free(glyph);
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
static BOOL xf_Glyph_Draw(rdpContext* context, const rdpGlyph* glyph, INT32 x, INT32 y, INT32 w,
Packit Service fa4841
                          INT32 h, INT32 sx, INT32 sy, BOOL fOpRedundant)
Packit Service fa4841
{
Packit Service fa4841
	xfGlyph* xf_glyph;
Packit Service fa4841
	xfContext* xfc = (xfContext*)context;
Packit Service fa4841
	xf_glyph = (xfGlyph*)glyph;
Packit Service fa4841
	xf_lock_x11(xfc);
Packit Service fa4841
Packit Service fa4841
	if (!fOpRedundant)
Packit Service fa4841
	{
Packit Service fa4841
		XSetFillStyle(xfc->display, xfc->gc, FillOpaqueStippled);
Packit Service fa4841
		XFillRectangle(xfc->display, xfc->drawable, xfc->gc, x, y, w, h);
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	XSetFillStyle(xfc->display, xfc->gc, FillStippled);
Packit Service fa4841
	XSetStipple(xfc->display, xfc->gc, xf_glyph->pixmap);
Packit Service fa4841
Packit Service fa4841
	if (sx || sy)
Packit Service fa4841
		WLog_ERR(TAG, "");
Packit Service fa4841
Packit Service fa4841
	// XSetClipOrigin(xfc->display, xfc->gc, sx, sy);
Packit Service fa4841
	XSetTSOrigin(xfc->display, xfc->gc, x, y);
Packit Service fa4841
	XFillRectangle(xfc->display, xfc->drawing, xfc->gc, x, y, w, h);
Packit Service fa4841
	xf_unlock_x11(xfc);
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
static BOOL xf_Glyph_BeginDraw(rdpContext* context, INT32 x, INT32 y, INT32 width, INT32 height,
Packit Service fa4841
                               UINT32 bgcolor, UINT32 fgcolor, BOOL fOpRedundant)
Packit Service fa4841
{
Packit Service fa4841
	xfContext* xfc = (xfContext*)context;
Packit Service fa4841
	XRectangle rect;
Packit Service fa4841
	XColor xbgcolor, xfgcolor;
Packit Service fa4841
Packit Service fa4841
	if (!xf_decode_color(xfc, bgcolor, &xbgcolor))
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	if (!xf_decode_color(xfc, fgcolor, &xfgcolor))
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	rect.x = x;
Packit Service fa4841
	rect.y = y;
Packit Service fa4841
	rect.width = width;
Packit Service fa4841
	rect.height = height;
Packit Service fa4841
	xf_lock_x11(xfc);
Packit Service fa4841
Packit Service fa4841
	if (!fOpRedundant)
Packit Service fa4841
	{
Packit Service fa4841
		XSetForeground(xfc->display, xfc->gc, xfgcolor.pixel);
Packit Service fa4841
		XSetBackground(xfc->display, xfc->gc, xfgcolor.pixel);
Packit Service fa4841
		XSetFillStyle(xfc->display, xfc->gc, FillOpaqueStippled);
Packit Service fa4841
		XFillRectangle(xfc->display, xfc->drawable, xfc->gc, x, y, width, height);
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	XSetForeground(xfc->display, xfc->gc, xbgcolor.pixel);
Packit Service fa4841
	XSetBackground(xfc->display, xfc->gc, xfgcolor.pixel);
Packit Service fa4841
	xf_unlock_x11(xfc);
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
static BOOL xf_Glyph_EndDraw(rdpContext* context, INT32 x, INT32 y, INT32 width, INT32 height,
Packit Service fa4841
                             UINT32 bgcolor, UINT32 fgcolor)
Packit Service fa4841
{
Packit Service fa4841
	xfContext* xfc = (xfContext*)context;
Packit Service fa4841
	BOOL ret = TRUE;
Packit Service fa4841
	XColor xfgcolor, xbgcolor;
Packit Service fa4841
Packit Service fa4841
	if (!xf_decode_color(xfc, bgcolor, &xbgcolor))
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	if (!xf_decode_color(xfc, fgcolor, &xfgcolor))
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	if (xfc->drawing == xfc->primary)
Packit Service fa4841
		ret = gdi_InvalidateRegion(xfc->hdc, x, y, width, height);
Packit Service fa4841
Packit Service fa4841
	return ret;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
/* Graphics Module */
Packit Service fa4841
BOOL xf_register_pointer(rdpGraphics* graphics)
Packit Service fa4841
{
Packit Service fa4841
	rdpPointer* pointer = NULL;
Packit Service fa4841
Packit Service fa4841
	if (!(pointer = (rdpPointer*)calloc(1, sizeof(rdpPointer))))
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	pointer->size = sizeof(xfPointer);
Packit Service fa4841
	pointer->New = xf_Pointer_New;
Packit Service fa4841
	pointer->Free = xf_Pointer_Free;
Packit Service fa4841
	pointer->Set = xf_Pointer_Set;
Packit Service fa4841
	pointer->SetNull = xf_Pointer_SetNull;
Packit Service fa4841
	pointer->SetDefault = xf_Pointer_SetDefault;
Packit Service fa4841
	pointer->SetPosition = xf_Pointer_SetPosition;
Packit Service fa4841
	graphics_register_pointer(graphics, pointer);
Packit Service fa4841
	free(pointer);
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
BOOL xf_register_graphics(rdpGraphics* graphics)
Packit Service fa4841
{
Packit Service fa4841
	rdpBitmap bitmap;
Packit Service fa4841
	rdpGlyph glyph;
Packit Service fa4841
Packit Service fa4841
	if (!graphics || !graphics->Bitmap_Prototype || !graphics->Glyph_Prototype)
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	bitmap = *graphics->Bitmap_Prototype;
Packit Service fa4841
	glyph = *graphics->Glyph_Prototype;
Packit Service fa4841
	bitmap.size = sizeof(xfBitmap);
Packit Service fa4841
	bitmap.New = xf_Bitmap_New;
Packit Service fa4841
	bitmap.Free = xf_Bitmap_Free;
Packit Service fa4841
	bitmap.Paint = xf_Bitmap_Paint;
Packit Service fa4841
	bitmap.SetSurface = xf_Bitmap_SetSurface;
Packit Service fa4841
	graphics_register_bitmap(graphics, &bitmap);
Packit Service fa4841
	glyph.size = sizeof(xfGlyph);
Packit Service fa4841
	glyph.New = xf_Glyph_New;
Packit Service fa4841
	glyph.Free = xf_Glyph_Free;
Packit Service fa4841
	glyph.Draw = xf_Glyph_Draw;
Packit Service fa4841
	glyph.BeginDraw = xf_Glyph_BeginDraw;
Packit Service fa4841
	glyph.EndDraw = xf_Glyph_EndDraw;
Packit Service fa4841
	graphics_register_glyph(graphics, &glyph);
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
UINT32 xf_get_local_color_format(xfContext* xfc, BOOL aligned)
Packit Service fa4841
{
Packit Service fa4841
	UINT32 DstFormat;
Packit Service fa4841
	BOOL invert = FALSE;
Packit Service fa4841
Packit Service fa4841
	if (!xfc)
Packit Service fa4841
		return 0;
Packit Service fa4841
Packit Service fa4841
	invert = xfc->invert;
Packit Service fa4841
Packit Service fa4841
	if (xfc->depth == 32)
Packit Service fa4841
		DstFormat = (!invert) ? PIXEL_FORMAT_RGBA32 : PIXEL_FORMAT_BGRA32;
Packit Service fa4841
	else if (xfc->depth == 24)
Packit Service fa4841
	{
Packit Service fa4841
		if (aligned)
Packit Service fa4841
			DstFormat = (!invert) ? PIXEL_FORMAT_RGBX32 : PIXEL_FORMAT_BGRX32;
Packit Service fa4841
		else
Packit Service fa4841
			DstFormat = (!invert) ? PIXEL_FORMAT_RGB24 : PIXEL_FORMAT_BGR24;
Packit Service fa4841
	}
Packit Service fa4841
	else if (xfc->depth == 16)
Packit Service fa4841
		DstFormat = PIXEL_FORMAT_RGB16;
Packit Service fa4841
	else if (xfc->depth == 15)
Packit Service fa4841
		DstFormat = PIXEL_FORMAT_RGB15;
Packit Service fa4841
	else
Packit Service fa4841
		DstFormat = (!invert) ? PIXEL_FORMAT_RGBX32 : PIXEL_FORMAT_BGRX32;
Packit Service fa4841
Packit Service fa4841
	return DstFormat;
Packit Service fa4841
}