X11: Scale cursor when SmartSizing is on
This commit is contained in:
parent
cba6181154
commit
f4f795f323
@ -226,13 +226,129 @@ static BOOL xf_Bitmap_SetSurface(rdpContext* context, rdpBitmap* bitmap, BOOL pr
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL _xf_Pointer_GetCursorForCurrentScale(rdpContext* context, const rdpPointer* pointer,
|
||||
Cursor* cursor)
|
||||
{
|
||||
#ifdef WITH_XCURSOR
|
||||
UINT32 CursorFormat;
|
||||
xfContext* xfc = (xfContext*)context;
|
||||
xfPointer* xpointer = (xfPointer*)pointer;
|
||||
XcursorImage ci;
|
||||
rdpSettings* settings;
|
||||
UINT32 xTargetSize;
|
||||
UINT32 yTargetSize;
|
||||
double xscale;
|
||||
double yscale;
|
||||
size_t size;
|
||||
int cursorIndex = -1;
|
||||
|
||||
if (!context || !pointer || !context->gdi)
|
||||
return FALSE;
|
||||
|
||||
settings = xfc->context.settings;
|
||||
|
||||
if (!settings)
|
||||
return FALSE;
|
||||
|
||||
xscale = (settings->SmartSizing ? xfc->scaledWidth / (double)settings->DesktopWidth : 1);
|
||||
yscale = (settings->SmartSizing ? xfc->scaledHeight / (double)settings->DesktopHeight : 1);
|
||||
xTargetSize = pointer->width * xscale;
|
||||
yTargetSize = pointer->height * yscale;
|
||||
|
||||
for (int i = 0; i < xpointer->nCursors; i++)
|
||||
{
|
||||
if (xpointer->cursorWidths[i] == xTargetSize && xpointer->cursorHeights[i] == yTargetSize)
|
||||
{
|
||||
cursorIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (cursorIndex == -1)
|
||||
{
|
||||
xf_lock_x11(xfc);
|
||||
|
||||
if (!xfc->invert)
|
||||
CursorFormat = (!xfc->big_endian) ? PIXEL_FORMAT_RGBA32 : PIXEL_FORMAT_ABGR32;
|
||||
else
|
||||
CursorFormat = (!xfc->big_endian) ? PIXEL_FORMAT_BGRA32 : PIXEL_FORMAT_ARGB32;
|
||||
|
||||
if (xpointer->nCursors == xpointer->mCursors)
|
||||
{
|
||||
xpointer->mCursors = (xpointer->mCursors == 0 ? 1 : xpointer->mCursors * 2);
|
||||
|
||||
if (!(xpointer->cursorWidths = (UINT32*)realloc(xpointer->cursorWidths,
|
||||
sizeof(UINT32) * xpointer->mCursors)))
|
||||
{
|
||||
xf_unlock_x11(xfc);
|
||||
return FALSE;
|
||||
}
|
||||
if (!(xpointer->cursorHeights = (UINT32*)realloc(xpointer->cursorHeights,
|
||||
sizeof(UINT32) * xpointer->mCursors)))
|
||||
{
|
||||
xf_unlock_x11(xfc);
|
||||
return FALSE;
|
||||
}
|
||||
if (!(xpointer->cursors =
|
||||
(Cursor*)realloc(xpointer->cursors, sizeof(Cursor) * xpointer->mCursors)))
|
||||
{
|
||||
xf_unlock_x11(xfc);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
ZeroMemory(&ci, sizeof(ci));
|
||||
ci.version = XCURSOR_IMAGE_VERSION;
|
||||
ci.size = sizeof(ci);
|
||||
ci.width = xTargetSize;
|
||||
ci.height = yTargetSize;
|
||||
ci.xhot = pointer->xPos * xscale;
|
||||
ci.yhot = pointer->yPos * yscale;
|
||||
size = ci.height * ci.width * GetBytesPerPixel(CursorFormat);
|
||||
|
||||
if (!(ci.pixels = (XcursorPixel*)_aligned_malloc(size, 16)))
|
||||
{
|
||||
xf_unlock_x11(xfc);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (xscale != 1 || yscale != 1)
|
||||
{
|
||||
if (!freerdp_image_scale((BYTE*)ci.pixels, CursorFormat, 0, 0, 0, ci.width, ci.height,
|
||||
(BYTE*)xpointer->cursorPixels, CursorFormat, 0, 0, 0,
|
||||
pointer->width, pointer->height))
|
||||
{
|
||||
_aligned_free(ci.pixels);
|
||||
xf_unlock_x11(xfc);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ci.pixels = xpointer->cursorPixels;
|
||||
}
|
||||
|
||||
cursorIndex = xpointer->nCursors;
|
||||
xpointer->cursorWidths[cursorIndex] = ci.width;
|
||||
xpointer->cursorHeights[cursorIndex] = ci.height;
|
||||
xpointer->cursors[cursorIndex] = XcursorImageLoadCursor(xfc->display, &ci);
|
||||
xpointer->nCursors += 1;
|
||||
if (xscale != 1 || yscale != 1)
|
||||
_aligned_free(ci.pixels);
|
||||
|
||||
xf_unlock_x11(xfc);
|
||||
}
|
||||
|
||||
cursor[0] = xpointer->cursors[cursorIndex];
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Pointer Class */
|
||||
static BOOL xf_Pointer_New(rdpContext* context, rdpPointer* pointer)
|
||||
{
|
||||
#ifdef WITH_XCURSOR
|
||||
UINT32 CursorFormat;
|
||||
size_t size;
|
||||
XcursorImage ci;
|
||||
xfContext* xfc = (xfContext*)context;
|
||||
xfPointer* xpointer = (xfPointer*)pointer;
|
||||
|
||||
@ -244,35 +360,25 @@ static BOOL xf_Pointer_New(rdpContext* context, rdpPointer* pointer)
|
||||
else
|
||||
CursorFormat = (!xfc->big_endian) ? PIXEL_FORMAT_BGRA32 : PIXEL_FORMAT_ARGB32;
|
||||
|
||||
xf_lock_x11(xfc);
|
||||
ZeroMemory(&ci, sizeof(ci));
|
||||
ci.version = XCURSOR_IMAGE_VERSION;
|
||||
ci.size = sizeof(ci);
|
||||
ci.width = pointer->width;
|
||||
ci.height = pointer->height;
|
||||
ci.xhot = pointer->xPos;
|
||||
ci.yhot = pointer->yPos;
|
||||
size = ci.height * ci.width * GetBytesPerPixel(CursorFormat);
|
||||
xpointer->nCursors = 0;
|
||||
xpointer->mCursors = 0;
|
||||
|
||||
if (!(ci.pixels = (XcursorPixel*)_aligned_malloc(size, 16)))
|
||||
{
|
||||
xf_unlock_x11(xfc);
|
||||
size = pointer->height * pointer->width * GetBytesPerPixel(CursorFormat);
|
||||
|
||||
if (!(xpointer->cursorPixels = (XcursorPixel*)_aligned_malloc(size, 16)))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!freerdp_image_copy_from_pointer_data(
|
||||
(BYTE*)ci.pixels, CursorFormat, 0, 0, 0, pointer->width, pointer->height,
|
||||
(BYTE*)xpointer->cursorPixels, CursorFormat, 0, 0, 0, pointer->width, pointer->height,
|
||||
pointer->xorMaskData, pointer->lengthXorMask, pointer->andMaskData,
|
||||
pointer->lengthAndMask, pointer->xorBpp, &context->gdi->palette))
|
||||
{
|
||||
_aligned_free(ci.pixels);
|
||||
xf_unlock_x11(xfc);
|
||||
_aligned_free(xpointer->cursorPixels);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
xpointer->cursor = XcursorImageLoadCursor(xfc->display, &ci);
|
||||
_aligned_free(ci.pixels);
|
||||
xf_unlock_x11(xfc);
|
||||
if (!_xf_Pointer_GetCursorForCurrentScale(context, pointer, &(xpointer->cursor)))
|
||||
return FALSE;
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
@ -281,10 +387,22 @@ static void xf_Pointer_Free(rdpContext* context, rdpPointer* pointer)
|
||||
{
|
||||
#ifdef WITH_XCURSOR
|
||||
xfContext* xfc = (xfContext*)context;
|
||||
xfPointer* xpointer = (xfPointer*)pointer;
|
||||
|
||||
xf_lock_x11(xfc);
|
||||
|
||||
if (((xfPointer*)pointer)->cursor)
|
||||
XFreeCursor(xfc->display, ((xfPointer*)pointer)->cursor);
|
||||
_aligned_free(xpointer->cursorPixels);
|
||||
free(xpointer->cursorWidths);
|
||||
free(xpointer->cursorHeights);
|
||||
|
||||
for (int i = 0; i < xpointer->nCursors; i++)
|
||||
{
|
||||
XFreeCursor(xfc->display, xpointer->cursors[i]);
|
||||
}
|
||||
|
||||
free(xpointer->cursors);
|
||||
xpointer->nCursors = 0;
|
||||
xpointer->mCursors = 0;
|
||||
|
||||
xf_unlock_x11(xfc);
|
||||
#endif
|
||||
@ -294,15 +412,18 @@ static BOOL xf_Pointer_Set(rdpContext* context, const rdpPointer* pointer)
|
||||
{
|
||||
#ifdef WITH_XCURSOR
|
||||
xfContext* xfc = (xfContext*)context;
|
||||
xf_lock_x11(xfc);
|
||||
xfc->pointer = (xfPointer*)pointer;
|
||||
|
||||
/* in RemoteApp mode, window can be null if none has had focus */
|
||||
|
||||
if (xfc->window)
|
||||
{
|
||||
if (!_xf_Pointer_GetCursorForCurrentScale(context, pointer, &(xfc->pointer->cursor)))
|
||||
return FALSE;
|
||||
xf_lock_x11(xfc);
|
||||
XDefineCursor(xfc->display, xfc->window->handle, xfc->pointer->cursor);
|
||||
|
||||
xf_unlock_x11(xfc);
|
||||
xf_unlock_x11(xfc);
|
||||
}
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -28,6 +28,10 @@
|
||||
|
||||
typedef struct xf_context xfContext;
|
||||
|
||||
#ifdef WITH_XCURSOR
|
||||
#include <X11/Xcursor/Xcursor.h>
|
||||
#endif
|
||||
|
||||
#include <freerdp/api.h>
|
||||
|
||||
#include "xf_window.h"
|
||||
@ -48,6 +52,14 @@ typedef struct xf_context xfContext;
|
||||
#include <freerdp/codec/progressive.h>
|
||||
#include <freerdp/codec/region.h>
|
||||
|
||||
#if !defined(XcursorUInt)
|
||||
typedef unsigned int XcursorUInt;
|
||||
#endif
|
||||
|
||||
#if !defined(XcursorPixel)
|
||||
typedef XcursorUInt XcursorPixel;
|
||||
#endif
|
||||
|
||||
struct xf_FullscreenMonitors
|
||||
{
|
||||
UINT32 top;
|
||||
@ -69,6 +81,12 @@ typedef struct xf_WorkArea xfWorkArea;
|
||||
struct xf_pointer
|
||||
{
|
||||
rdpPointer pointer;
|
||||
XcursorPixel* cursorPixels;
|
||||
UINT32 nCursors;
|
||||
UINT32 mCursors;
|
||||
UINT32* cursorWidths;
|
||||
UINT32* cursorHeights;
|
||||
Cursor* cursors;
|
||||
Cursor cursor;
|
||||
};
|
||||
typedef struct xf_pointer xfPointer;
|
||||
|
Loading…
Reference in New Issue
Block a user