xfreerdp: added smart sizing, mt gesture fixes
- removed setting ScalingFactor - added settings SmartSizingWidth and SmartSizingHeight - changed option /smart-sizing to optionally support <width>x<height> - consolidated transformation of input event coordinates - rdp8 gfx ignored scaling and panning offsets: fixed - never resize window on panning/pinching - simplified keyboard multitouch gesture debugging emulation - disabled keyboard multitouch gesture emulation debug code via define
This commit is contained in:
parent
85297fb343
commit
25f66d2e6d
@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#ifdef WITH_XRENDER
|
#ifdef WITH_XRENDER
|
||||||
#include <X11/extensions/Xrender.h>
|
#include <X11/extensions/Xrender.h>
|
||||||
|
#include <math.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WITH_XI
|
#ifdef WITH_XI
|
||||||
@ -49,11 +50,6 @@
|
|||||||
#include <X11/extensions/XInput2.h>
|
#include <X11/extensions/XInput2.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WITH_XRENDER
|
|
||||||
#include <X11/extensions/Xrender.h>
|
|
||||||
#include <math.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <X11/XKBlib.h>
|
#include <X11/XKBlib.h>
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@ -107,38 +103,9 @@
|
|||||||
|
|
||||||
static const size_t password_size = 512;
|
static const size_t password_size = 512;
|
||||||
|
|
||||||
void xf_transform_window(xfContext* xfc)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
int w;
|
|
||||||
int h;
|
|
||||||
long supplied;
|
|
||||||
Atom hints_atom;
|
|
||||||
XSizeHints *size_hints = NULL;
|
|
||||||
hints_atom = XInternAtom(xfc->display, "WM_SIZE_HINTS", 1);
|
|
||||||
ret = XGetWMSizeHints(xfc->display, xfc->window->handle, size_hints, &supplied, hints_atom);
|
|
||||||
if (ret == 0)
|
|
||||||
size_hints = XAllocSizeHints();
|
|
||||||
w = (xfc->originalWidth * xfc->settings->ScalingFactor) + xfc->offset_x;
|
|
||||||
h = (xfc->originalHeight * xfc->settings->ScalingFactor) + xfc->offset_y;
|
|
||||||
if (w < 1)
|
|
||||||
w = 1;
|
|
||||||
if (h < 1)
|
|
||||||
h = 1;
|
|
||||||
if (size_hints)
|
|
||||||
{
|
|
||||||
size_hints->flags |= PMinSize | PMaxSize;
|
|
||||||
size_hints->min_width = size_hints->max_width = w;
|
|
||||||
size_hints->min_height = size_hints->max_height = h;
|
|
||||||
XSetWMNormalHints(xfc->display, xfc->window->handle, size_hints);
|
|
||||||
XResizeWindow(xfc->display, xfc->window->handle, w, h);
|
|
||||||
XFree(size_hints);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void xf_draw_screen_scaled(xfContext* xfc, int x, int y, int w, int h)
|
|
||||||
{
|
|
||||||
#ifdef WITH_XRENDER
|
#ifdef WITH_XRENDER
|
||||||
|
static void xf_draw_screen_scaled(xfContext* xfc, int x, int y, int w, int h)
|
||||||
|
{
|
||||||
XTransform transform;
|
XTransform transform;
|
||||||
Picture windowPicture;
|
Picture windowPicture;
|
||||||
Picture primaryPicture;
|
Picture primaryPicture;
|
||||||
@ -146,19 +113,53 @@ void xf_draw_screen_scaled(xfContext* xfc, int x, int y, int w, int h)
|
|||||||
XRenderPictFormat *picFormat;
|
XRenderPictFormat *picFormat;
|
||||||
double xScalingFactor;
|
double xScalingFactor;
|
||||||
double yScalingFactor;
|
double yScalingFactor;
|
||||||
|
int x2;
|
||||||
|
int y2;
|
||||||
|
|
||||||
if (xfc->currentWidth <= 0 || xfc->currentHeight <= 0) {
|
if (xfc->scaledWidth <= 0 || xfc->scaledHeight <= 0)
|
||||||
|
{
|
||||||
WLog_ERR(TAG, "the current window dimensions are invalid");
|
WLog_ERR(TAG, "the current window dimensions are invalid");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xfc->originalWidth <= 0 || xfc->originalHeight <= 0) {
|
if (xfc->width <= 0 || xfc->height <= 0)
|
||||||
WLog_ERR(TAG, "the original window dimensions are invalid");
|
{
|
||||||
|
WLog_ERR(TAG, "the window dimensions are invalid");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
xScalingFactor = xfc->originalWidth / (double)xfc->currentWidth;
|
if (!w || !h)
|
||||||
yScalingFactor = xfc->originalHeight / (double)xfc->currentHeight;
|
{
|
||||||
|
WLog_ERR(TAG, "invalid width and/or height specified");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
xScalingFactor = xfc->width / (double)xfc->scaledWidth;
|
||||||
|
yScalingFactor = xfc->height / (double)xfc->scaledHeight;
|
||||||
|
|
||||||
|
XSetFillStyle(xfc->display, xfc->gc, FillSolid);
|
||||||
|
XSetForeground(xfc->display, xfc->gc, 0);
|
||||||
|
|
||||||
|
/* Black out possible space between desktop and window borders */
|
||||||
|
{
|
||||||
|
XRectangle box1 = { 0, 0, xfc->window->width, xfc->window->height };
|
||||||
|
XRectangle box2 = { xfc->offset_x, xfc->offset_y, xfc->scaledWidth, xfc->scaledHeight };
|
||||||
|
Region reg1 = XCreateRegion();
|
||||||
|
Region reg2 = XCreateRegion();
|
||||||
|
|
||||||
|
XUnionRectWithRegion( &box1, reg1, reg1);
|
||||||
|
XUnionRectWithRegion( &box2, reg2, reg2);
|
||||||
|
|
||||||
|
if (XSubtractRegion(reg1, reg2, reg1) && !XEmptyRegion(reg1))
|
||||||
|
{
|
||||||
|
XSetRegion( xfc->display, xfc->gc, reg1);
|
||||||
|
XFillRectangle(xfc->display, xfc->window->handle, xfc->gc, 0, 0, xfc->window->width, xfc->window->height);
|
||||||
|
XSetClipMask(xfc->display, xfc->gc, None);
|
||||||
|
}
|
||||||
|
|
||||||
|
XDestroyRegion(reg1);
|
||||||
|
XDestroyRegion(reg2);
|
||||||
|
}
|
||||||
|
|
||||||
picFormat = XRenderFindStandardFormat(xfc->display, PictStandardRGB24);
|
picFormat = XRenderFindStandardFormat(xfc->display, PictStandardRGB24);
|
||||||
|
|
||||||
@ -178,22 +179,43 @@ void xf_draw_screen_scaled(xfContext* xfc, int x, int y, int w, int h)
|
|||||||
transform.matrix[2][1] = XDoubleToFixed(0.0);
|
transform.matrix[2][1] = XDoubleToFixed(0.0);
|
||||||
transform.matrix[2][2] = XDoubleToFixed(1.0);
|
transform.matrix[2][2] = XDoubleToFixed(1.0);
|
||||||
|
|
||||||
if ((w != 0) && (h != 0))
|
/* calculate and fix up scaled coordinates */
|
||||||
{
|
x2 = x + w;
|
||||||
int x2 = x + w;
|
y2 = y + h;
|
||||||
int y2 = y + h;
|
|
||||||
|
|
||||||
x = floor(x / xScalingFactor) - 1;
|
x = floor(x / xScalingFactor) - 1;
|
||||||
y = floor(y / yScalingFactor) - 1;
|
y = floor(y / yScalingFactor) - 1;
|
||||||
w = ceil(x2 / xScalingFactor) + 1 - x;
|
w = ceil(x2 / xScalingFactor) + 1 - x;
|
||||||
h = ceil(y2 / yScalingFactor) + 1 - y;
|
h = ceil(y2 / yScalingFactor) + 1 - y;
|
||||||
}
|
|
||||||
|
|
||||||
XRenderSetPictureTransform(xfc->display, primaryPicture, &transform);
|
XRenderSetPictureTransform(xfc->display, primaryPicture, &transform);
|
||||||
XRenderComposite(xfc->display, PictOpSrc, primaryPicture, 0, windowPicture, x, y, 0, 0, xfc->offset_x + x, xfc->offset_y + y, w, h);
|
XRenderComposite(xfc->display, PictOpSrc, primaryPicture, 0, windowPicture, x, y, 0, 0, xfc->offset_x + x, xfc->offset_y + y, w, h);
|
||||||
XRenderFreePicture(xfc->display, primaryPicture);
|
XRenderFreePicture(xfc->display, primaryPicture);
|
||||||
XRenderFreePicture(xfc->display, windowPicture);
|
XRenderFreePicture(xfc->display, windowPicture);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL xf_picture_transform_required(xfContext* xfc)
|
||||||
|
{
|
||||||
|
if (xfc->offset_x || xfc->offset_y ||
|
||||||
|
xfc->scaledWidth != xfc->width ||
|
||||||
|
xfc->scaledHeight != xfc->height)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void xf_draw_screen(xfContext* xfc, int x, int y, int w, int h)
|
||||||
|
{
|
||||||
|
#ifdef WITH_XRENDER
|
||||||
|
if (xf_picture_transform_required(xfc)) {
|
||||||
|
xf_draw_screen_scaled(xfc, x, y, w, h);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
XCopyArea(xfc->display, xfc->primary, xfc->window->handle, xfc->gc, x, y, w, h, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void xf_sw_begin_paint(rdpContext* context)
|
void xf_sw_begin_paint(rdpContext* context)
|
||||||
@ -232,14 +254,7 @@ void xf_sw_end_paint(rdpContext* context)
|
|||||||
|
|
||||||
XPutImage(xfc->display, xfc->primary, xfc->gc, xfc->image, x, y, x, y, w, h);
|
XPutImage(xfc->display, xfc->primary, xfc->gc, xfc->image, x, y, x, y, w, h);
|
||||||
|
|
||||||
if ((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y))
|
xf_draw_screen(xfc, x, y, w, h);
|
||||||
{
|
|
||||||
xf_draw_screen_scaled(xfc, x, y, w, h);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
XCopyArea(xfc->display, xfc->primary, xfc->window->handle, xfc->gc, x, y, w, h, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
xf_unlock_x11(xfc, FALSE);
|
xf_unlock_x11(xfc, FALSE);
|
||||||
}
|
}
|
||||||
@ -259,14 +274,7 @@ void xf_sw_end_paint(rdpContext* context)
|
|||||||
|
|
||||||
XPutImage(xfc->display, xfc->primary, xfc->gc, xfc->image, x, y, x, y, w, h);
|
XPutImage(xfc->display, xfc->primary, xfc->gc, xfc->image, x, y, x, y, w, h);
|
||||||
|
|
||||||
if ((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y))
|
xf_draw_screen(xfc, x, y, w, h);
|
||||||
{
|
|
||||||
xf_draw_screen_scaled(xfc, x, y, w, h);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
XCopyArea(xfc->display, xfc->primary, xfc->window->handle, xfc->gc, x, y, w, h, x, y);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XFlush(xfc->display);
|
XFlush(xfc->display);
|
||||||
@ -338,14 +346,7 @@ void xf_hw_end_paint(rdpContext* context)
|
|||||||
|
|
||||||
xf_lock_x11(xfc, FALSE);
|
xf_lock_x11(xfc, FALSE);
|
||||||
|
|
||||||
if ((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y))
|
xf_draw_screen(xfc, x, y, w, h);
|
||||||
{
|
|
||||||
xf_draw_screen_scaled(xfc, x, y, w, h);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
XCopyArea(xfc->display, xfc->primary, xfc->drawable, xfc->gc, x, y, w, h, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
xf_unlock_x11(xfc, FALSE);
|
xf_unlock_x11(xfc, FALSE);
|
||||||
}
|
}
|
||||||
@ -370,14 +371,7 @@ void xf_hw_end_paint(rdpContext* context)
|
|||||||
w = cinvalid[i].w;
|
w = cinvalid[i].w;
|
||||||
h = cinvalid[i].h;
|
h = cinvalid[i].h;
|
||||||
|
|
||||||
if ((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y))
|
xf_draw_screen(xfc, x, y, w, h);
|
||||||
{
|
|
||||||
xf_draw_screen_scaled(xfc, x, y, w, h);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
XCopyArea(xfc->display, xfc->primary, xfc->drawable, xfc->gc, x, y, w, h, x, y);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XFlush(xfc->display);
|
XFlush(xfc->display);
|
||||||
@ -500,6 +494,10 @@ void xf_create_window(xfContext* xfc)
|
|||||||
xfc->attribs.colormap = xfc->colormap;
|
xfc->attribs.colormap = xfc->colormap;
|
||||||
xfc->attribs.bit_gravity = NorthWestGravity;
|
xfc->attribs.bit_gravity = NorthWestGravity;
|
||||||
xfc->attribs.win_gravity = NorthWestGravity;
|
xfc->attribs.win_gravity = NorthWestGravity;
|
||||||
|
#ifdef WITH_XRENDER
|
||||||
|
xfc->offset_x = 0;
|
||||||
|
xfc->offset_y = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (xfc->settings->WindowTitle)
|
if (xfc->settings->WindowTitle)
|
||||||
{
|
{
|
||||||
@ -516,6 +514,30 @@ void xf_create_window(xfContext* xfc)
|
|||||||
sprintf(windowTitle, "FreeRDP: %s:%i", xfc->settings->ServerHostname, xfc->settings->ServerPort);
|
sprintf(windowTitle, "FreeRDP: %s:%i", xfc->settings->ServerHostname, xfc->settings->ServerPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_XRENDER
|
||||||
|
if (xfc->settings->SmartSizing)
|
||||||
|
{
|
||||||
|
if(xfc->fullscreen)
|
||||||
|
{
|
||||||
|
if (xfc->window)
|
||||||
|
{
|
||||||
|
xfc->settings->SmartSizingWidth = xfc->window->width;
|
||||||
|
xfc->settings->SmartSizingHeight = xfc->window->height;
|
||||||
|
}
|
||||||
|
width = WidthOfScreen(xfc->screen);
|
||||||
|
height = HeightOfScreen(xfc->screen);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (xfc->settings->SmartSizingWidth)
|
||||||
|
width = xfc->settings->SmartSizingWidth;
|
||||||
|
if (xfc->settings->SmartSizingHeight)
|
||||||
|
height = xfc->settings->SmartSizingHeight;
|
||||||
|
}
|
||||||
|
xfc->scaledWidth = width;
|
||||||
|
xfc->scaledHeight = height;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
xfc->window = xf_CreateDesktopWindow(xfc, windowTitle, width, height, xfc->settings->Decorations);
|
xfc->window = xf_CreateDesktopWindow(xfc, windowTitle, width, height, xfc->settings->Decorations);
|
||||||
|
|
||||||
free(windowTitle);
|
free(windowTitle);
|
||||||
@ -535,23 +557,16 @@ void xf_create_window(xfContext* xfc)
|
|||||||
|
|
||||||
void xf_toggle_fullscreen(xfContext* xfc)
|
void xf_toggle_fullscreen(xfContext* xfc)
|
||||||
{
|
{
|
||||||
Pixmap contents = 0;
|
|
||||||
WindowStateChangeEventArgs e;
|
WindowStateChangeEventArgs e;
|
||||||
|
|
||||||
xf_lock_x11(xfc, TRUE);
|
xf_lock_x11(xfc, TRUE);
|
||||||
|
|
||||||
contents = XCreatePixmap(xfc->display, xfc->window->handle, xfc->width, xfc->height, xfc->depth);
|
|
||||||
|
|
||||||
XCopyArea(xfc->display, xfc->primary, contents, xfc->gc, 0, 0, xfc->width, xfc->height, 0, 0);
|
|
||||||
XDestroyWindow(xfc->display, xfc->window->handle);
|
XDestroyWindow(xfc->display, xfc->window->handle);
|
||||||
|
|
||||||
xfc->fullscreen = (xfc->fullscreen) ? FALSE : TRUE;
|
xfc->fullscreen = (xfc->fullscreen) ? FALSE : TRUE;
|
||||||
|
|
||||||
xf_create_window(xfc);
|
xf_create_window(xfc);
|
||||||
|
|
||||||
XCopyArea(xfc->display, contents, xfc->primary, xfc->gc, 0, 0, xfc->width, xfc->height, 0, 0);
|
|
||||||
XFreePixmap(xfc->display, contents);
|
|
||||||
|
|
||||||
xf_unlock_x11(xfc, TRUE);
|
xf_unlock_x11(xfc, TRUE);
|
||||||
|
|
||||||
EventArgsInit(&e, "xfreerdp");
|
EventArgsInit(&e, "xfreerdp");
|
||||||
@ -988,16 +1003,16 @@ BOOL xf_post_connect(freerdp *instance)
|
|||||||
xfc->hdc = gdi_CreateDC(flags, xfc->bpp);
|
xfc->hdc = gdi_CreateDC(flags, xfc->bpp);
|
||||||
}
|
}
|
||||||
|
|
||||||
xfc->originalWidth = settings->DesktopWidth;
|
|
||||||
xfc->originalHeight = settings->DesktopHeight;
|
|
||||||
xfc->currentWidth = xfc->originalWidth;
|
|
||||||
xfc->currentHeight = xfc->originalHeight;
|
|
||||||
xfc->settings->ScalingFactor = 1.0;
|
|
||||||
xfc->offset_x = 0;
|
|
||||||
xfc->offset_y = 0;
|
|
||||||
xfc->width = settings->DesktopWidth;
|
xfc->width = settings->DesktopWidth;
|
||||||
xfc->height = settings->DesktopHeight;
|
xfc->height = settings->DesktopHeight;
|
||||||
|
|
||||||
|
#ifdef WITH_XRENDER
|
||||||
|
xfc->scaledWidth = xfc->width;
|
||||||
|
xfc->scaledHeight = xfc->height;
|
||||||
|
xfc->offset_x = 0;
|
||||||
|
xfc->offset_y = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (settings->RemoteApplicationMode)
|
if (settings->RemoteApplicationMode)
|
||||||
xfc->remote_app = TRUE;
|
xfc->remote_app = TRUE;
|
||||||
|
|
||||||
@ -1603,32 +1618,41 @@ void xf_TerminateEventHandler(rdpContext* context, TerminateEventArgs* e)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xf_ScalingFactorChangeEventHandler(rdpContext* context, ScalingFactorChangeEventArgs* e)
|
static void xf_ZoomingChangeEventHandler(rdpContext* context, ZoomingChangeEventArgs* e)
|
||||||
|
{
|
||||||
|
xfContext* xfc = (xfContext*) context;
|
||||||
|
int w = xfc->scaledWidth + e->dx;
|
||||||
|
int h = xfc->scaledHeight + e->dy;
|
||||||
|
|
||||||
|
if (e->dx == 0 && e->dy == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (w < 10)
|
||||||
|
w = 10;
|
||||||
|
|
||||||
|
if (h < 10)
|
||||||
|
h = 10;
|
||||||
|
|
||||||
|
if (w == xfc->scaledWidth && h == xfc->scaledHeight)
|
||||||
|
return;
|
||||||
|
|
||||||
|
xfc->scaledWidth = w;
|
||||||
|
xfc->scaledHeight = h;
|
||||||
|
|
||||||
|
xf_draw_screen(xfc, 0, 0, xfc->width, xfc->height);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void xf_PanningChangeEventHandler(rdpContext* context, PanningChangeEventArgs* e)
|
||||||
{
|
{
|
||||||
xfContext* xfc = (xfContext*) context;
|
xfContext* xfc = (xfContext*) context;
|
||||||
|
|
||||||
xfc->settings->ScalingFactor += e->ScalingFactor;
|
if (e->dx == 0 && e->dy == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
if (xfc->settings->ScalingFactor > 1.2)
|
xfc->offset_x += e->dx;
|
||||||
xfc->settings->ScalingFactor = 1.2;
|
xfc->offset_y += e->dy;
|
||||||
|
|
||||||
if (xfc->settings->ScalingFactor < 0.8)
|
xf_draw_screen(xfc, 0, 0, xfc->width, xfc->height);
|
||||||
xfc->settings->ScalingFactor = 0.8;
|
|
||||||
|
|
||||||
xfc->currentWidth = xfc->originalWidth * xfc->settings->ScalingFactor;
|
|
||||||
xfc->currentHeight = xfc->originalHeight * xfc->settings->ScalingFactor;
|
|
||||||
|
|
||||||
xf_transform_window(xfc);
|
|
||||||
|
|
||||||
{
|
|
||||||
ResizeWindowEventArgs ev;
|
|
||||||
EventArgsInit(&ev, "xfreerdp");
|
|
||||||
ev.width = (int) xfc->originalWidth * xfc->settings->ScalingFactor;
|
|
||||||
ev.height = (int) xfc->originalHeight * xfc->settings->ScalingFactor;
|
|
||||||
PubSub_OnResizeWindow(((rdpContext*) xfc)->pubSub, xfc, &ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
xf_draw_screen_scaled(xfc, 0, 0, xfc->originalWidth, xfc->originalHeight);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1705,7 +1729,8 @@ static int xfreerdp_client_new(freerdp* instance, rdpContext* context)
|
|||||||
xfc->settings = instance->context->settings;
|
xfc->settings = instance->context->settings;
|
||||||
|
|
||||||
PubSub_SubscribeTerminate(context->pubSub, (pTerminateEventHandler) xf_TerminateEventHandler);
|
PubSub_SubscribeTerminate(context->pubSub, (pTerminateEventHandler) xf_TerminateEventHandler);
|
||||||
PubSub_SubscribeScalingFactorChange(context->pubSub, (pScalingFactorChangeEventHandler) xf_ScalingFactorChangeEventHandler);
|
PubSub_SubscribeZoomingChange(context->pubSub, (pZoomingChangeEventHandler) xf_ZoomingChangeEventHandler);
|
||||||
|
PubSub_SubscribePanningChange(context->pubSub, (pPanningChangeEventHandler) xf_PanningChangeEventHandler);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -178,15 +178,42 @@ int xf_event_execute_action_script(xfContext* xfc, XEvent* event)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void xf_event_adjust_coordinates(xfContext* xfc, int* x, int *y)
|
||||||
|
{
|
||||||
|
if (!xfc->remote_app)
|
||||||
|
{
|
||||||
|
#ifdef WITH_XRENDER
|
||||||
|
if (xf_picture_transform_required(xfc))
|
||||||
|
{
|
||||||
|
double xScalingFactor = xfc->width / (double)xfc->scaledWidth;
|
||||||
|
double yScalingFactor = xfc->height / (double)xfc->scaledHeight;
|
||||||
|
*x = (int)((*x - xfc->offset_x) * xScalingFactor);
|
||||||
|
*y = (int)((*y - xfc->offset_y) * yScalingFactor);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
CLAMP_COORDINATES(*x, *y);
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL xf_event_Expose(xfContext* xfc, XEvent* event, BOOL app)
|
static BOOL xf_event_Expose(xfContext* xfc, XEvent* event, BOOL app)
|
||||||
{
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
int w, h;
|
int w, h;
|
||||||
|
|
||||||
|
if (!app && (xfc->settings->SmartSizing || xfc->settings->MultiTouchGestures))
|
||||||
|
{
|
||||||
|
x = 0;
|
||||||
|
y = 0;
|
||||||
|
w = xfc->width;
|
||||||
|
h = xfc->height;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
x = event->xexpose.x;
|
x = event->xexpose.x;
|
||||||
y = event->xexpose.y;
|
y = event->xexpose.y;
|
||||||
w = event->xexpose.width;
|
w = event->xexpose.width;
|
||||||
h = event->xexpose.height;
|
h = event->xexpose.height;
|
||||||
|
}
|
||||||
|
|
||||||
if (xfc->gfx)
|
if (xfc->gfx)
|
||||||
{
|
{
|
||||||
@ -196,14 +223,7 @@ static BOOL xf_event_Expose(xfContext* xfc, XEvent* event, BOOL app)
|
|||||||
|
|
||||||
if (!app)
|
if (!app)
|
||||||
{
|
{
|
||||||
if ((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y))
|
xf_draw_screen(xfc, x, y, w, h);
|
||||||
{
|
|
||||||
xf_draw_screen_scaled(xfc, x - xfc->offset_x, y - xfc->offset_y, w, h);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
XCopyArea(xfc->display, xfc->primary, xfc->window->handle, xfc->gc, x, y, w, h, x, y);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -251,13 +271,7 @@ BOOL xf_generic_MotionNotify(xfContext* xfc, int x, int y, int state, Window win
|
|||||||
x, y, &x, &y, &childWindow);
|
x, y, &x, &y, &childWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Take scaling in to consideration */
|
xf_event_adjust_coordinates(xfc, &x, &y);
|
||||||
if ( (xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y) )
|
|
||||||
{
|
|
||||||
x = (int)((x - xfc->offset_x) * (1.0 / xfc->settings->ScalingFactor) );
|
|
||||||
y = (int)((y - xfc->offset_y) * (1.0 / xfc->settings->ScalingFactor) );
|
|
||||||
}
|
|
||||||
CLAMP_COORDINATES(x,y);
|
|
||||||
|
|
||||||
input->MouseEvent(input, PTR_FLAGS_MOVE, x, y);
|
input->MouseEvent(input, PTR_FLAGS_MOVE, x, y);
|
||||||
|
|
||||||
@ -357,16 +371,8 @@ BOOL xf_generic_ButtonPress(xfContext* xfc, int x, int y, int button, Window win
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x)
|
xf_event_adjust_coordinates(xfc, &x, &y);
|
||||||
|| (xfc->offset_y))
|
|
||||||
{
|
|
||||||
x = (int) ((x - xfc->offset_x)
|
|
||||||
* (1.0 / xfc->settings->ScalingFactor));
|
|
||||||
y = (int) ((y - xfc->offset_y)
|
|
||||||
* (1.0 / xfc->settings->ScalingFactor));
|
|
||||||
}
|
|
||||||
|
|
||||||
CLAMP_COORDINATES(x,y);
|
|
||||||
if (extended)
|
if (extended)
|
||||||
input->ExtendedMouseEvent(input, flags, x, y);
|
input->ExtendedMouseEvent(input, flags, x, y);
|
||||||
else
|
else
|
||||||
@ -446,14 +452,7 @@ BOOL xf_generic_ButtonRelease(xfContext* xfc, int x, int y, int button, Window w
|
|||||||
x, y, &x, &y, &childWindow);
|
x, y, &x, &y, &childWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xf_event_adjust_coordinates(xfc, &x, &y);
|
||||||
if ((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y))
|
|
||||||
{
|
|
||||||
x = (int) ((x - xfc->offset_x) * (1.0 / xfc->settings->ScalingFactor));
|
|
||||||
y = (int) ((y - xfc->offset_y) * (1.0 / xfc->settings->ScalingFactor));
|
|
||||||
}
|
|
||||||
|
|
||||||
CLAMP_COORDINATES(x,y);
|
|
||||||
|
|
||||||
if (extended)
|
if (extended)
|
||||||
input->ExtendedMouseEvent(input, flags, x, y);
|
input->ExtendedMouseEvent(input, flags, x, y);
|
||||||
@ -641,7 +640,28 @@ static BOOL xf_event_ConfigureNotify(xfContext* xfc, XEvent* event, BOOL app)
|
|||||||
xfAppWindow* appWindow;
|
xfAppWindow* appWindow;
|
||||||
|
|
||||||
if (!app)
|
if (!app)
|
||||||
|
{
|
||||||
|
#ifdef WITH_XRENDER
|
||||||
|
if (xfc->settings->SmartSizing && event->xconfigure.window == xfc->window->handle)
|
||||||
|
{
|
||||||
|
if (xfc->window->width != event->xconfigure.width ||
|
||||||
|
xfc->window->height != event->xconfigure.height)
|
||||||
|
{
|
||||||
|
xfc->window->width = event->xconfigure.width;
|
||||||
|
xfc->window->height = event->xconfigure.height;
|
||||||
|
if (!xfc->fullscreen)
|
||||||
|
{
|
||||||
|
xfc->scaledWidth = xfc->window->width;
|
||||||
|
xfc->scaledHeight = xfc->window->height;
|
||||||
|
}
|
||||||
|
xfc->offset_x = 0;
|
||||||
|
xfc->offset_y = 0;
|
||||||
|
xf_draw_screen(xfc, 0, 0, xfc->width, xfc->height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
appWindow = xf_AppWindowFromX11Window(xfc, event->xany.window);
|
appWindow = xf_AppWindowFromX11Window(xfc, event->xany.window);
|
||||||
|
|
||||||
|
@ -31,6 +31,8 @@ void xf_event_action_script_free(xfContext* xfc);
|
|||||||
BOOL xf_event_process(freerdp* instance, XEvent* event);
|
BOOL xf_event_process(freerdp* instance, XEvent* event);
|
||||||
void xf_event_SendClientEvent(xfContext* xfc, xfWindow* window, Atom atom, unsigned int numArgs, ...);
|
void xf_event_SendClientEvent(xfContext* xfc, xfWindow* window, Atom atom, unsigned int numArgs, ...);
|
||||||
|
|
||||||
|
void xf_event_adjust_coordinates(xfContext* xfc, int* x, int *y);
|
||||||
|
|
||||||
BOOL xf_generic_MotionNotify(xfContext* xfc, int x, int y, int state, Window window, BOOL app);
|
BOOL xf_generic_MotionNotify(xfContext* xfc, int x, int y, int state, Window window, BOOL app);
|
||||||
BOOL xf_generic_ButtonPress(xfContext* xfc, int x, int y, int button, Window window, BOOL app);
|
BOOL xf_generic_ButtonPress(xfContext* xfc, int x, int y, int button, Window window, BOOL app);
|
||||||
BOOL xf_generic_ButtonRelease(xfContext* xfc, int x, int y, int button, Window window, BOOL app);
|
BOOL xf_generic_ButtonRelease(xfContext* xfc, int x, int y, int button, Window window, BOOL app);
|
||||||
|
@ -84,9 +84,21 @@ int xf_OutputUpdate(xfContext* xfc)
|
|||||||
surface->width, surface->height, surface->data, surface->format, surface->scanline, 0, 0, NULL);
|
surface->width, surface->height, surface->data, surface->format, surface->scanline, 0, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_XRENDER
|
||||||
|
if (xfc->settings->SmartSizing || xfc->settings->MultiTouchGestures)
|
||||||
|
{
|
||||||
|
XPutImage(xfc->display, xfc->primary, xfc->gc, surface->image,
|
||||||
|
extents->left, extents->top, extents->left, extents->top, width, height);
|
||||||
|
|
||||||
|
xf_draw_screen(xfc, extents->left, extents->top, width, height);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
XPutImage(xfc->display, xfc->drawable, xfc->gc, surface->image,
|
XPutImage(xfc->display, xfc->drawable, xfc->gc, surface->image,
|
||||||
extents->left, extents->top, extents->left, extents->top, width, height);
|
extents->left, extents->top, extents->left, extents->top, width, height);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
region16_clear(&(xfc->invalidRegion));
|
region16_clear(&(xfc->invalidRegion));
|
||||||
|
|
||||||
|
@ -276,13 +276,12 @@ void xf_input_detect_pan(xfContext* xfc)
|
|||||||
{
|
{
|
||||||
if (px_vector > PAN_THRESHOLD)
|
if (px_vector > PAN_THRESHOLD)
|
||||||
{
|
{
|
||||||
|
|
||||||
{
|
{
|
||||||
PanningChangeEventArgs e;
|
PanningChangeEventArgs e;
|
||||||
|
|
||||||
EventArgsInit(&e, "xfreerdp");
|
EventArgsInit(&e, "xfreerdp");
|
||||||
e.XPan = 5;
|
e.dx = 5;
|
||||||
e.YPan = 0;
|
e.dy = 0;
|
||||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,8 +297,8 @@ void xf_input_detect_pan(xfContext* xfc)
|
|||||||
PanningChangeEventArgs e;
|
PanningChangeEventArgs e;
|
||||||
|
|
||||||
EventArgsInit(&e, "xfreerdp");
|
EventArgsInit(&e, "xfreerdp");
|
||||||
e.XPan = -5;
|
e.dx = -5;
|
||||||
e.YPan = 0;
|
e.dy = 0;
|
||||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,8 +320,8 @@ void xf_input_detect_pan(xfContext* xfc)
|
|||||||
PanningChangeEventArgs e;
|
PanningChangeEventArgs e;
|
||||||
|
|
||||||
EventArgsInit(&e, "xfreerdp");
|
EventArgsInit(&e, "xfreerdp");
|
||||||
e.XPan = 0;
|
e.dx = 0;
|
||||||
e.YPan = 5;
|
e.dy = 5;
|
||||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -338,8 +337,8 @@ void xf_input_detect_pan(xfContext* xfc)
|
|||||||
PanningChangeEventArgs e;
|
PanningChangeEventArgs e;
|
||||||
|
|
||||||
EventArgsInit(&e, "xfreerdp");
|
EventArgsInit(&e, "xfreerdp");
|
||||||
e.XPan = 0;
|
e.dx = 0;
|
||||||
e.YPan = -5;
|
e.dy = -5;
|
||||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,7 +357,7 @@ void xf_input_detect_pinch(xfContext* xfc)
|
|||||||
double zoom;
|
double zoom;
|
||||||
|
|
||||||
double delta;
|
double delta;
|
||||||
ResizeWindowEventArgs e;
|
ZoomingChangeEventArgs e;
|
||||||
|
|
||||||
if (active_contacts != 2)
|
if (active_contacts != 2)
|
||||||
{
|
{
|
||||||
@ -400,21 +399,11 @@ void xf_input_detect_pinch(xfContext* xfc)
|
|||||||
|
|
||||||
if (z_vector > ZOOM_THRESHOLD)
|
if (z_vector > ZOOM_THRESHOLD)
|
||||||
{
|
{
|
||||||
xfc->settings->ScalingFactor -= 0.05;
|
|
||||||
|
|
||||||
if (xfc->settings->ScalingFactor < 0.8)
|
|
||||||
xfc->settings->ScalingFactor = 0.8;
|
|
||||||
|
|
||||||
EventArgsInit(&e, "xfreerdp");
|
EventArgsInit(&e, "xfreerdp");
|
||||||
e.width = (int) xfc->originalWidth * xfc->settings->ScalingFactor;
|
e.dx = e.dy = -10;
|
||||||
e.height = (int) xfc->originalHeight * xfc->settings->ScalingFactor;
|
PubSub_OnZoomingChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||||
|
|
||||||
xf_transform_window(xfc);
|
|
||||||
PubSub_OnResizeWindow(((rdpContext*) xfc)->pubSub, xfc, &e);
|
|
||||||
xf_draw_screen_scaled(xfc, 0, 0, xfc->originalWidth, xfc->originalHeight);
|
|
||||||
|
|
||||||
z_vector = 0;
|
z_vector = 0;
|
||||||
|
|
||||||
px_vector = 0;
|
px_vector = 0;
|
||||||
py_vector = 0;
|
py_vector = 0;
|
||||||
z_vector = 0;
|
z_vector = 0;
|
||||||
@ -422,21 +411,11 @@ void xf_input_detect_pinch(xfContext* xfc)
|
|||||||
|
|
||||||
if (z_vector < -ZOOM_THRESHOLD)
|
if (z_vector < -ZOOM_THRESHOLD)
|
||||||
{
|
{
|
||||||
xfc->settings->ScalingFactor += 0.05;
|
|
||||||
|
|
||||||
if (xfc->settings->ScalingFactor > 1.2)
|
|
||||||
xfc->settings->ScalingFactor = 1.2;
|
|
||||||
|
|
||||||
EventArgsInit(&e, "xfreerdp");
|
EventArgsInit(&e, "xfreerdp");
|
||||||
e.width = (int) xfc->originalWidth * xfc->settings->ScalingFactor;
|
e.dx = e.dy = 10;
|
||||||
e.height = (int) xfc->originalHeight * xfc->settings->ScalingFactor;
|
PubSub_OnZoomingChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||||
|
|
||||||
xf_transform_window(xfc);
|
|
||||||
PubSub_OnResizeWindow(((rdpContext*) xfc)->pubSub, xfc, &e);
|
|
||||||
xf_draw_screen_scaled(xfc, 0, 0, xfc->originalWidth, xfc->originalHeight);
|
|
||||||
|
|
||||||
z_vector = 0;
|
z_vector = 0;
|
||||||
|
|
||||||
px_vector = 0;
|
px_vector = 0;
|
||||||
py_vector = 0;
|
py_vector = 0;
|
||||||
z_vector = 0;
|
z_vector = 0;
|
||||||
@ -620,6 +599,8 @@ int xf_input_touch_remote(xfContext* xfc, XIDeviceEvent* event, int evtype)
|
|||||||
x = (int) event->event_x;
|
x = (int) event->event_x;
|
||||||
y = (int) event->event_y;
|
y = (int) event->event_y;
|
||||||
|
|
||||||
|
xf_event_adjust_coordinates(xfc, &x, &y);
|
||||||
|
|
||||||
if (evtype == XI_TouchBegin)
|
if (evtype == XI_TouchBegin)
|
||||||
{
|
{
|
||||||
WLog_DBG(TAG, "TouchBegin: %d", touchId);
|
WLog_DBG(TAG, "TouchBegin: %d", touchId);
|
||||||
|
@ -468,140 +468,80 @@ BOOL xf_keyboard_handle_special_keys(xfContext* xfc, KeySym keysym)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keysym == XK_period)
|
#if 0 /* set to 1 to enable multi touch gesture simulation via keyboard */
|
||||||
|
#ifdef WITH_XRENDER
|
||||||
|
if (!xfc->remote_app && xfc->settings->MultiTouchGestures)
|
||||||
{
|
{
|
||||||
if (mod.Ctrl && mod.Alt)
|
if (mod.Ctrl && mod.Alt)
|
||||||
{
|
{
|
||||||
/* Zoom In (scale larger) */
|
int pdx = 0;
|
||||||
|
int pdy = 0;
|
||||||
double s = xfc->settings->ScalingFactor;
|
int zdx = 0;
|
||||||
|
int zdy = 0;
|
||||||
s += 0.1;
|
|
||||||
|
|
||||||
if (s > 2.0)
|
|
||||||
s = 2.0;
|
|
||||||
|
|
||||||
xfc->settings->ScalingFactor = s;
|
|
||||||
|
|
||||||
xfc->currentWidth = xfc->originalWidth * s;
|
|
||||||
xfc->currentHeight = xfc->originalHeight * s;
|
|
||||||
|
|
||||||
xf_transform_window(xfc);
|
|
||||||
|
|
||||||
|
switch(keysym)
|
||||||
{
|
{
|
||||||
ResizeWindowEventArgs e;
|
case XK_0: /* Ctrl-Alt-0: Reset scaling and panning */
|
||||||
|
xfc->scaledWidth = xfc->width;
|
||||||
EventArgsInit(&e, "xfreerdp");
|
xfc->scaledHeight = xfc->height;
|
||||||
e.width = (int) xfc->originalWidth * xfc->settings->ScalingFactor;
|
xfc->offset_x = 0;
|
||||||
e.height = (int) xfc->originalHeight * xfc->settings->ScalingFactor;
|
xfc->offset_y = 0;
|
||||||
PubSub_OnResizeWindow(((rdpContext*) xfc)->pubSub, xfc, &e);
|
if (!xfc->fullscreen && (xfc->width != xfc->window->width ||
|
||||||
|
xfc->height != xfc->window->height))
|
||||||
|
{
|
||||||
|
xf_ResizeDesktopWindow(xfc, xfc->window, xfc->width, xfc->height);
|
||||||
}
|
}
|
||||||
|
xf_draw_screen(xfc, 0, 0, xfc->width, xfc->height);
|
||||||
xf_draw_screen_scaled(xfc, 0, 0, xfc->originalWidth, xfc->originalHeight);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
|
||||||
|
case XK_1: /* Ctrl-Alt-1: Zoom in */
|
||||||
|
zdx = zdy = 10;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XK_2: /* Ctrl-Alt-2: Zoom out */
|
||||||
|
zdx = zdy = -10;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XK_3: /* Ctrl-Alt-3: Pan left */
|
||||||
|
pdx = -10;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XK_4: /* Ctrl-Alt-4: Pan right */
|
||||||
|
pdx = 10;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XK_5: /* Ctrl-Alt-5: Pan up */
|
||||||
|
pdy = -10;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XK_6: /* Ctrl-Alt-6: Pan up */
|
||||||
|
pdy = 10;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keysym == XK_comma)
|
if (pdx != 0 || pdy != 0)
|
||||||
{
|
|
||||||
if (mod.Ctrl && mod.Alt)
|
|
||||||
{
|
|
||||||
/* Zoom Out (scale smaller) */
|
|
||||||
|
|
||||||
double s = xfc->settings->ScalingFactor;
|
|
||||||
|
|
||||||
s -= 0.1;
|
|
||||||
|
|
||||||
if (s < 0.5)
|
|
||||||
s = 0.5;
|
|
||||||
|
|
||||||
xfc->settings->ScalingFactor = s;
|
|
||||||
|
|
||||||
xfc->currentWidth = xfc->originalWidth * s;
|
|
||||||
xfc->currentHeight = xfc->originalHeight * s;
|
|
||||||
|
|
||||||
xf_transform_window(xfc);
|
|
||||||
|
|
||||||
{
|
|
||||||
ResizeWindowEventArgs e;
|
|
||||||
|
|
||||||
EventArgsInit(&e, "xfreerdp");
|
|
||||||
e.width = (int) xfc->originalWidth * xfc->settings->ScalingFactor;
|
|
||||||
e.height = (int) xfc->originalHeight * xfc->settings->ScalingFactor;
|
|
||||||
PubSub_OnResizeWindow(((rdpContext*) xfc)->pubSub, xfc, &e);
|
|
||||||
}
|
|
||||||
|
|
||||||
xf_draw_screen_scaled(xfc, 0, 0, xfc->originalWidth, xfc->originalHeight);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keysym == XK_KP_4)
|
|
||||||
{
|
|
||||||
if (mod.Ctrl && mod.Alt)
|
|
||||||
{
|
|
||||||
|
|
||||||
{
|
{
|
||||||
PanningChangeEventArgs e;
|
PanningChangeEventArgs e;
|
||||||
|
|
||||||
EventArgsInit(&e, "xfreerdp");
|
EventArgsInit(&e, "xfreerdp");
|
||||||
e.XPan = -5;
|
e.dx = pdx;
|
||||||
e.YPan = 0;
|
e.dy = pdy;
|
||||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (zdx != 0 || zdy != 0)
|
||||||
|
{
|
||||||
|
ZoomingChangeEventArgs e;
|
||||||
|
EventArgsInit(&e, "xfreerdp");
|
||||||
|
e.dx = zdx;
|
||||||
|
e.dy = zdy;
|
||||||
|
PubSub_OnZoomingChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keysym == XK_KP_6)
|
|
||||||
{
|
|
||||||
if (mod.Ctrl && mod.Alt)
|
|
||||||
{
|
|
||||||
|
|
||||||
{
|
|
||||||
PanningChangeEventArgs e;
|
|
||||||
|
|
||||||
EventArgsInit(&e, "xfreerdp");
|
|
||||||
e.XPan = 5;
|
|
||||||
e.YPan = 0;
|
|
||||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keysym == XK_KP_8)
|
|
||||||
{
|
|
||||||
if (mod.Ctrl && mod.Alt)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
PanningChangeEventArgs e;
|
|
||||||
|
|
||||||
EventArgsInit(&e, "xfreerdp");
|
|
||||||
e.XPan = 0;
|
|
||||||
e.YPan = -5;
|
|
||||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keysym == XK_KP_2)
|
|
||||||
{
|
|
||||||
if (mod.Ctrl && mod.Alt)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
PanningChangeEventArgs e;
|
|
||||||
|
|
||||||
EventArgsInit(&e, "xfreerdp");
|
|
||||||
e.XPan = 0;
|
|
||||||
e.YPan = 5;
|
|
||||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
#endif /* WITH_XRENDER defined */
|
||||||
|
#endif /* pinch/zoom/pan simulation */
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -412,11 +412,20 @@ void xf_ResizeDesktopWindow(xfContext* xfc, xfWindow* window, int width, int hei
|
|||||||
if (size_hints)
|
if (size_hints)
|
||||||
{
|
{
|
||||||
size_hints->flags = PMinSize | PMaxSize;
|
size_hints->flags = PMinSize | PMaxSize;
|
||||||
size_hints->min_width = size_hints->max_width = xfc->width;
|
|
||||||
size_hints->min_height = size_hints->max_height = xfc->height;
|
size_hints->min_width = size_hints->max_width = width;
|
||||||
|
size_hints->min_height = size_hints->max_height = height;
|
||||||
|
|
||||||
|
#ifdef WITH_XRENDER
|
||||||
|
if (xfc->settings->SmartSizing)
|
||||||
|
{
|
||||||
|
size_hints->min_width = size_hints->min_height = 1;
|
||||||
|
size_hints->max_width = size_hints->max_height = 16384;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
XSetWMNormalHints(xfc->display, window->handle, size_hints);
|
XSetWMNormalHints(xfc->display, window->handle, size_hints);
|
||||||
XResizeWindow(xfc->display, window->handle, xfc->width, xfc->height);
|
XResizeWindow(xfc->display, window->handle, width, height);
|
||||||
XFree(size_hints);
|
XFree(size_hints);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,15 +132,14 @@ struct xf_context
|
|||||||
UINT16 frame_x2;
|
UINT16 frame_x2;
|
||||||
UINT16 frame_y2;
|
UINT16 frame_y2;
|
||||||
|
|
||||||
int originalWidth;
|
|
||||||
int originalHeight;
|
|
||||||
int currentWidth;
|
|
||||||
int currentHeight;
|
|
||||||
int XInputOpcode;
|
int XInputOpcode;
|
||||||
BOOL enableScaling;
|
|
||||||
|
|
||||||
|
#ifdef WITH_XRENDER
|
||||||
|
int scaledWidth;
|
||||||
|
int scaledHeight;
|
||||||
int offset_x;
|
int offset_x;
|
||||||
int offset_y;
|
int offset_y;
|
||||||
|
#endif
|
||||||
|
|
||||||
BOOL focused;
|
BOOL focused;
|
||||||
BOOL use_xinput;
|
BOOL use_xinput;
|
||||||
@ -250,8 +249,8 @@ enum XF_EXIT_CODE
|
|||||||
void xf_lock_x11(xfContext* xfc, BOOL display);
|
void xf_lock_x11(xfContext* xfc, BOOL display);
|
||||||
void xf_unlock_x11(xfContext* xfc, BOOL display);
|
void xf_unlock_x11(xfContext* xfc, BOOL display);
|
||||||
|
|
||||||
void xf_draw_screen_scaled(xfContext* xfc, int x, int y, int w, int h);
|
BOOL xf_picture_transform_required(xfContext* xfc);
|
||||||
void xf_transform_window(xfContext* xfc);
|
void xf_draw_screen(xfContext* xfc, int x, int y, int w, int h);
|
||||||
|
|
||||||
FREERDP_API DWORD xf_exit_code_from_disconnect_reason(DWORD reason);
|
FREERDP_API DWORD xf_exit_code_from_disconnect_reason(DWORD reason);
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ COMMAND_LINE_ARGUMENT_A args[] =
|
|||||||
{ "monitor-list", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT, NULL, NULL, NULL, -1, NULL, "List detected monitors" },
|
{ "monitor-list", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT, NULL, NULL, NULL, -1, NULL, "List detected monitors" },
|
||||||
{ "t", COMMAND_LINE_VALUE_REQUIRED, "<title>", NULL, NULL, -1, "title", "Window title" },
|
{ "t", COMMAND_LINE_VALUE_REQUIRED, "<title>", NULL, NULL, -1, "title", "Window title" },
|
||||||
{ "decorations", COMMAND_LINE_VALUE_BOOL, NULL, NULL, BoolValueTrue, -1, NULL, "Window decorations" },
|
{ "decorations", COMMAND_LINE_VALUE_BOOL, NULL, NULL, BoolValueTrue, -1, NULL, "Window decorations" },
|
||||||
{ "smart-sizing", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Scale remote desktop to window size" },
|
{ "smart-sizing", COMMAND_LINE_VALUE_OPTIONAL, "<width>x<height>", NULL, NULL, -1, NULL, "Scale remote desktop to window size" },
|
||||||
{ "a", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, "addin", "Addin" },
|
{ "a", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, "addin", "Addin" },
|
||||||
{ "vc", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Static virtual channel" },
|
{ "vc", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Static virtual channel" },
|
||||||
{ "dvc", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Dynamic virtual channel" },
|
{ "dvc", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Dynamic virtual channel" },
|
||||||
@ -1344,7 +1344,19 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
|
|||||||
}
|
}
|
||||||
CommandLineSwitchCase(arg, "smart-sizing")
|
CommandLineSwitchCase(arg, "smart-sizing")
|
||||||
{
|
{
|
||||||
settings->SmartSizing = arg->Value ? TRUE : FALSE;
|
settings->SmartSizing = TRUE;
|
||||||
|
|
||||||
|
if (arg->Value)
|
||||||
|
{
|
||||||
|
str = _strdup(arg->Value);
|
||||||
|
if ((p = strchr(str, 'x')))
|
||||||
|
{
|
||||||
|
*p = '\0';
|
||||||
|
settings->SmartSizingWidth = atoi(str);
|
||||||
|
settings->SmartSizingHeight = atoi(&p[1]);
|
||||||
|
}
|
||||||
|
free(str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
CommandLineSwitchCase(arg, "bpp")
|
CommandLineSwitchCase(arg, "bpp")
|
||||||
{
|
{
|
||||||
|
@ -43,13 +43,14 @@ DEFINE_EVENT_BEGIN(ResizeWindow)
|
|||||||
DEFINE_EVENT_END(ResizeWindow)
|
DEFINE_EVENT_END(ResizeWindow)
|
||||||
|
|
||||||
DEFINE_EVENT_BEGIN(PanningChange)
|
DEFINE_EVENT_BEGIN(PanningChange)
|
||||||
int XPan;
|
int dx;
|
||||||
int YPan;
|
int dy;
|
||||||
DEFINE_EVENT_END(PanningChange)
|
DEFINE_EVENT_END(PanningChange)
|
||||||
|
|
||||||
DEFINE_EVENT_BEGIN(ScalingFactorChange)
|
DEFINE_EVENT_BEGIN(ZoomingChange)
|
||||||
double ScalingFactor;
|
int dx;
|
||||||
DEFINE_EVENT_END(ScalingFactorChange)
|
int dy;
|
||||||
|
DEFINE_EVENT_END(ZoomingChange)
|
||||||
|
|
||||||
DEFINE_EVENT_BEGIN(LocalResizeWindow)
|
DEFINE_EVENT_BEGIN(LocalResizeWindow)
|
||||||
int width;
|
int width;
|
||||||
|
@ -661,7 +661,8 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL;
|
|||||||
#define FreeRDP_SmartSizing 1551
|
#define FreeRDP_SmartSizing 1551
|
||||||
#define FreeRDP_XPan 1552
|
#define FreeRDP_XPan 1552
|
||||||
#define FreeRDP_YPan 1553
|
#define FreeRDP_YPan 1553
|
||||||
#define FreeRDP_ScalingFactor 1554
|
#define FreeRDP_SmartSizingWidth 1554
|
||||||
|
#define FreeRDP_SmartSizingHeight 1555
|
||||||
#define FreeRDP_SoftwareGdi 1601
|
#define FreeRDP_SoftwareGdi 1601
|
||||||
#define FreeRDP_LocalConnection 1602
|
#define FreeRDP_LocalConnection 1602
|
||||||
#define FreeRDP_AuthenticationOnly 1603
|
#define FreeRDP_AuthenticationOnly 1603
|
||||||
@ -1068,8 +1069,9 @@ struct rdp_settings
|
|||||||
ALIGN64 BOOL SmartSizing; /* 1551 */
|
ALIGN64 BOOL SmartSizing; /* 1551 */
|
||||||
ALIGN64 int XPan; /* 1552 */
|
ALIGN64 int XPan; /* 1552 */
|
||||||
ALIGN64 int YPan; /* 1553 */
|
ALIGN64 int YPan; /* 1553 */
|
||||||
ALIGN64 double ScalingFactor; /* 1554 */
|
ALIGN64 UINT32 SmartSizingWidth; /* 1554 */
|
||||||
UINT64 padding1601[1601 - 1555]; /* 1555 */
|
ALIGN64 UINT32 SmartSizingHeight; /* 1555 */
|
||||||
|
UINT64 padding1601[1601 - 1556]; /* 1556 */
|
||||||
|
|
||||||
/* Miscellaneous */
|
/* Miscellaneous */
|
||||||
ALIGN64 BOOL SoftwareGdi; /* 1601 */
|
ALIGN64 BOOL SoftwareGdi; /* 1601 */
|
||||||
@ -1453,9 +1455,6 @@ FREERDP_API int freerdp_set_param_uint64(rdpSettings* settings, int id, UINT64 p
|
|||||||
FREERDP_API char* freerdp_get_param_string(rdpSettings* settings, int id);
|
FREERDP_API char* freerdp_get_param_string(rdpSettings* settings, int id);
|
||||||
FREERDP_API int freerdp_set_param_string(rdpSettings* settings, int id, const char* param);
|
FREERDP_API int freerdp_set_param_string(rdpSettings* settings, int id, const char* param);
|
||||||
|
|
||||||
FREERDP_API double freerdp_get_param_double(rdpSettings* settings, int id);
|
|
||||||
FREERDP_API int freerdp_set_param_double(rdpSettings* settings, int id, double param);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1834,6 +1834,12 @@ UINT32 freerdp_get_param_uint32(rdpSettings* settings, int id)
|
|||||||
case FreeRDP_DynamicChannelArraySize:
|
case FreeRDP_DynamicChannelArraySize:
|
||||||
return settings->DynamicChannelArraySize;
|
return settings->DynamicChannelArraySize;
|
||||||
|
|
||||||
|
case FreeRDP_SmartSizingWidth:
|
||||||
|
return settings->SmartSizingWidth;
|
||||||
|
|
||||||
|
case FreeRDP_SmartSizingHeight:
|
||||||
|
return settings->SmartSizingHeight;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
WLog_ERR(TAG, "freerdp_get_param_uint32: unknown id: %d", id);
|
WLog_ERR(TAG, "freerdp_get_param_uint32: unknown id: %d", id);
|
||||||
return 0;
|
return 0;
|
||||||
@ -2587,35 +2593,3 @@ int freerdp_set_param_string(rdpSettings* settings, int id, const char* param)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
double freerdp_get_param_double(rdpSettings* settings, int id)
|
|
||||||
{
|
|
||||||
switch (id)
|
|
||||||
{
|
|
||||||
case FreeRDP_ScalingFactor:
|
|
||||||
return settings->ScalingFactor;
|
|
||||||
|
|
||||||
default:
|
|
||||||
WLog_ERR(TAG, "unknown id: %d", id);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int freerdp_set_param_double(rdpSettings* settings, int id, double param)
|
|
||||||
{
|
|
||||||
switch (id)
|
|
||||||
{
|
|
||||||
case FreeRDP_ScalingFactor:
|
|
||||||
settings->ScalingFactor = param;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Mark field as modified */
|
|
||||||
settings->SettingsModified[id] = 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -385,7 +385,7 @@ static wEventType FreeRDP_Events[] =
|
|||||||
DEFINE_EVENT_ENTRY(LocalResizeWindow)
|
DEFINE_EVENT_ENTRY(LocalResizeWindow)
|
||||||
DEFINE_EVENT_ENTRY(EmbedWindow)
|
DEFINE_EVENT_ENTRY(EmbedWindow)
|
||||||
DEFINE_EVENT_ENTRY(PanningChange)
|
DEFINE_EVENT_ENTRY(PanningChange)
|
||||||
DEFINE_EVENT_ENTRY(ScalingFactorChange)
|
DEFINE_EVENT_ENTRY(ZoomingChange)
|
||||||
DEFINE_EVENT_ENTRY(ErrorInfo)
|
DEFINE_EVENT_ENTRY(ErrorInfo)
|
||||||
DEFINE_EVENT_ENTRY(Terminate)
|
DEFINE_EVENT_ENTRY(Terminate)
|
||||||
DEFINE_EVENT_ENTRY(ConnectionResult)
|
DEFINE_EVENT_ENTRY(ConnectionResult)
|
||||||
|
Loading…
Reference in New Issue
Block a user