Merge branch 'master' of github.com:FreeRDP/FreeRDP
This commit is contained in:
commit
e95e0e42ae
@ -2,6 +2,7 @@
|
||||
# FreeRDP X11 Client
|
||||
#
|
||||
# Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
# Copyright 2013 Corey Clayton <can.of.tuna@gmail.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@ -28,6 +29,8 @@ set(${MODULE_PREFIX}_SRCS
|
||||
xf_rail.h
|
||||
xf_tsmf.c
|
||||
xf_tsmf.h
|
||||
xf_input.c
|
||||
xf_input.h
|
||||
xf_event.c
|
||||
xf_event.h
|
||||
xf_input.c
|
||||
@ -101,11 +104,11 @@ set(XV_FEATURE_DESCRIPTION "X11 video extension")
|
||||
|
||||
set(XI_FEATURE_TYPE "RECOMMENDED")
|
||||
set(XI_FEATURE_PURPOSE "input")
|
||||
set(XI_FEATURE_DESCRIPTION "X11 input extension")
|
||||
set(XI_FEATURE_DESCRIPTION "X11 input extension")
|
||||
|
||||
set(XRENDER_FEATURE_TYPE "RECOMMENDED")
|
||||
set(XRENDER_FEATURE_PURPOSE "rendering")
|
||||
set(XRENDER_FEATURE_DESCRIPTION "X11 render extension")
|
||||
set(XRENDER_FEATURE_DESCRIPTION "X11 render extension")
|
||||
|
||||
find_feature(XShm ${XSHM_FEATURE_TYPE} ${XSHM_FEATURE_PURPOSE} ${XSHM_FEATURE_DESCRIPTION})
|
||||
find_feature(Xinerama ${XINERAMA_FEATURE_TYPE} ${XINERAMA_FEATURE_PURPOSE} ${XINERAMA_FEATURE_DESCRIPTION})
|
||||
|
@ -3,6 +3,7 @@
|
||||
* X11 Client Interface
|
||||
*
|
||||
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2013 Corey Clayton <can.of.tuna@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -24,6 +25,14 @@
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
#ifdef WITH_XRENDER
|
||||
#include <X11/extensions/Xrender.h>
|
||||
#endif
|
||||
|
||||
#ifdef WITH_XI
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#endif
|
||||
|
||||
#ifdef WITH_XCURSOR
|
||||
#include <X11/Xcursor/Xcursor.h>
|
||||
#endif
|
||||
@ -73,6 +82,7 @@
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/file.h>
|
||||
#include <winpr/print.h>
|
||||
|
||||
#include "xf_gdi.h"
|
||||
#include "xf_rail.h"
|
||||
@ -83,14 +93,51 @@
|
||||
#include "xf_monitor.h"
|
||||
#include "xf_graphics.h"
|
||||
#include "xf_keyboard.h"
|
||||
#include "xf_input.h"
|
||||
#include "xf_channels.h"
|
||||
|
||||
#include "xfreerdp.h"
|
||||
|
||||
static long xv_port = 0;
|
||||
static const size_t password_size = 512;
|
||||
|
||||
void xf_draw_screen_scaled(xfContext* xfc)
|
||||
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, BOOL scale)
|
||||
{
|
||||
#ifdef WITH_XRENDER
|
||||
XTransform transform;
|
||||
@ -98,6 +145,7 @@ void xf_draw_screen_scaled(xfContext* xfc)
|
||||
Picture primaryPicture;
|
||||
XRenderPictureAttributes pa;
|
||||
XRenderPictFormat* picFormat;
|
||||
XRectangle xr;
|
||||
|
||||
picFormat = XRenderFindStandardFormat(xfc->display, PictStandardRGB24);
|
||||
pa.subwindow_mode = IncludeInferiors;
|
||||
@ -114,11 +162,38 @@ void xf_draw_screen_scaled(xfContext* xfc)
|
||||
|
||||
transform.matrix[2][0] = XDoubleToFixed(0);
|
||||
transform.matrix[2][1] = XDoubleToFixed(0);
|
||||
transform.matrix[2][2] = XDoubleToFixed(xfc->scale);
|
||||
transform.matrix[2][2] = XDoubleToFixed(xfc->settings->ScalingFactor);
|
||||
|
||||
if( (w != 0) && (h != 0) )
|
||||
{
|
||||
|
||||
if(scale == TRUE)
|
||||
{
|
||||
xr.x = x * xfc->settings->ScalingFactor;
|
||||
xr.y = y * xfc->settings->ScalingFactor;
|
||||
xr.width = (w+1) * xfc->settings->ScalingFactor;
|
||||
xr.height = (h+1) * xfc->settings->ScalingFactor;
|
||||
}
|
||||
else
|
||||
{
|
||||
xr.x = x;
|
||||
xr.y = y;
|
||||
xr.width = w;
|
||||
xr.height = h;
|
||||
}
|
||||
|
||||
XRenderSetPictureClipRectangles(xfc->display, primaryPicture, 0, 0, &xr, 1);
|
||||
}
|
||||
|
||||
XRenderSetPictureTransform(xfc->display, primaryPicture, &transform);
|
||||
XRenderComposite(xfc->display, PictOpSrc, primaryPicture, 0, windowPicture, 0, 0, 0, 0, 0, 0, xfc->currentWidth, xfc->currentHeight);
|
||||
|
||||
XRenderComposite(xfc->display, PictOpSrc, primaryPicture, 0, windowPicture, 0, 0, 0, 0, xfc->offset_x, xfc->offset_y, xfc->currentWidth, xfc->currentHeight);
|
||||
|
||||
XRenderFreePicture(xfc->display, primaryPicture);
|
||||
XRenderFreePicture(xfc->display, windowPicture);
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void xf_sw_begin_paint(rdpContext* context)
|
||||
@ -153,9 +228,9 @@ void xf_sw_end_paint(rdpContext* context)
|
||||
|
||||
XPutImage(xfc->display, xfc->primary, xfc->gc, xfc->image, x, y, x, y, w, h);
|
||||
|
||||
if (xfc->scale != 1.0)
|
||||
if ( (xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y) )
|
||||
{
|
||||
xf_draw_screen_scaled(xfc);
|
||||
xf_draw_screen_scaled(xfc, x, y, w, h, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -184,12 +259,13 @@ void xf_sw_end_paint(rdpContext* context)
|
||||
y = cinvalid[i].y;
|
||||
w = cinvalid[i].w;
|
||||
h = cinvalid[i].h;
|
||||
|
||||
|
||||
//combine xfc->primary with xfc->image
|
||||
XPutImage(xfc->display, xfc->primary, xfc->gc, xfc->image, x, y, x, y, w, h);
|
||||
|
||||
if (xfc->scale != 1.0)
|
||||
if ( (xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y) )
|
||||
{
|
||||
xf_draw_screen_scaled(xfc);
|
||||
xf_draw_screen_scaled(xfc, x, y, w, h, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -271,12 +347,12 @@ void xf_hw_end_paint(rdpContext* context)
|
||||
y = xfc->hdc->hwnd->invalid->y;
|
||||
w = xfc->hdc->hwnd->invalid->w;
|
||||
h = xfc->hdc->hwnd->invalid->h;
|
||||
|
||||
|
||||
xf_lock_x11(xfc, FALSE);
|
||||
|
||||
if (xfc->scale != 1.0)
|
||||
if ( (xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y) )
|
||||
{
|
||||
xf_draw_screen_scaled(xfc);
|
||||
xf_draw_screen_scaled(xfc, x, y, w, h, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -305,10 +381,10 @@ void xf_hw_end_paint(rdpContext* context)
|
||||
y = cinvalid[i].y;
|
||||
w = cinvalid[i].w;
|
||||
h = cinvalid[i].h;
|
||||
|
||||
if (xfc->scale != 1.0)
|
||||
|
||||
if ( (xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y) )
|
||||
{
|
||||
xf_draw_screen_scaled(xfc);
|
||||
xf_draw_screen_scaled(xfc, x, y, w, h, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -832,7 +908,10 @@ BOOL xf_post_connect(freerdp* instance)
|
||||
xfc->originalHeight = settings->DesktopHeight;
|
||||
xfc->currentWidth = xfc->originalWidth;
|
||||
xfc->currentHeight = xfc->originalWidth;
|
||||
xfc->scale = 1.0;
|
||||
xfc->settings->ScalingFactor = 1.0;
|
||||
|
||||
xfc->offset_x = 0;
|
||||
xfc->offset_y = 0;
|
||||
|
||||
xfc->width = settings->DesktopWidth;
|
||||
xfc->height = settings->DesktopHeight;
|
||||
@ -1483,6 +1562,8 @@ void* xf_thread(void* param)
|
||||
gdi_free(instance);
|
||||
|
||||
ExitThread(exit_code);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DWORD xf_exit_code_from_disconnect_reason(DWORD reason)
|
||||
@ -1525,16 +1606,64 @@ void xf_TerminateEventHandler(rdpContext* context, TerminateEventArgs* e)
|
||||
|
||||
void xf_ParamChangeEventHandler(rdpContext* context, ParamChangeEventArgs* e)
|
||||
{
|
||||
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
|
||||
switch (e->id)
|
||||
{
|
||||
case FreeRDP_ScalingFactor:
|
||||
break;
|
||||
case FreeRDP_ScalingFactor:
|
||||
|
||||
default:
|
||||
break;
|
||||
xfc->currentWidth = xfc->originalWidth * xfc->settings->ScalingFactor;
|
||||
xfc->currentHeight = xfc->originalHeight * xfc->settings->ScalingFactor;
|
||||
|
||||
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, 0, 0, FALSE);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void xf_ScalingFactorChangeEventHandler(rdpContext* context, ScalingFactorChangeEventArgs* e)
|
||||
{
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
|
||||
xfc->settings->ScalingFactor += e->ScalingFactor;
|
||||
|
||||
if (xfc->settings->ScalingFactor > 1.2)
|
||||
xfc->settings->ScalingFactor = 1.2;
|
||||
if (xfc->settings->ScalingFactor < 0.8)
|
||||
xfc->settings->ScalingFactor = 0.8;
|
||||
|
||||
|
||||
xfc->currentWidth = xfc->originalWidth * xfc->settings->ScalingFactor;
|
||||
xfc->currentHeight = xfc->originalHeight * xfc->settings->ScalingFactor;
|
||||
|
||||
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, 0, 0, FALSE);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Client Interface
|
||||
*/
|
||||
@ -1588,28 +1717,6 @@ int xfreerdp_client_stop(rdpContext* context)
|
||||
return 0;
|
||||
}
|
||||
|
||||
double freerdp_client_get_scale(rdpContext* context)
|
||||
{
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
return xfc->scale;
|
||||
}
|
||||
|
||||
void freerdp_client_reset_scale(rdpContext* context)
|
||||
{
|
||||
ResizeWindowEventArgs e;
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
|
||||
xfc->scale = 1.0;
|
||||
XResizeWindow(xfc->display, xfc->window->handle, xfc->originalWidth * xfc->scale, xfc->originalHeight * xfc->scale);
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.width = (int) xfc->originalWidth * xfc->scale;
|
||||
e.height = (int) xfc->originalHeight * xfc->scale;
|
||||
PubSub_OnResizeWindow(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
|
||||
xf_draw_screen_scaled(xfc);
|
||||
}
|
||||
|
||||
int xfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
{
|
||||
xfContext* xfc;
|
||||
@ -1659,6 +1766,8 @@ int xfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
|
||||
PubSub_SubscribeTerminate(context->pubSub, (pTerminateEventHandler) xf_TerminateEventHandler);
|
||||
PubSub_SubscribeParamChange(context->pubSub, (pParamChangeEventHandler) xf_ParamChangeEventHandler);
|
||||
PubSub_SubscribeScalingFactorChange(context->pubSub, (pScalingFactorChangeEventHandler) xf_ScalingFactorChangeEventHandler);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ extern "C" {
|
||||
* Client Interface
|
||||
*/
|
||||
|
||||
|
||||
FREERDP_API int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "xf_input.h"
|
||||
|
||||
#include "xf_event.h"
|
||||
#include "xf_input.h"
|
||||
|
||||
const char* const X11_EVENT_STRINGS[] =
|
||||
{
|
||||
@ -88,39 +89,40 @@ static BOOL xf_event_Expose(xfContext* xfc, XEvent* event, BOOL app)
|
||||
{
|
||||
int x, y;
|
||||
int w, h;
|
||||
|
||||
|
||||
x = event->xexpose.x;
|
||||
y = event->xexpose.y;
|
||||
w = event->xexpose.width;
|
||||
h = event->xexpose.height;
|
||||
|
||||
|
||||
if (!app)
|
||||
{
|
||||
if (xfc->scale != 1.0)
|
||||
if ((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y))
|
||||
{
|
||||
xf_draw_screen_scaled(xfc);
|
||||
}
|
||||
else
|
||||
xf_draw_screen_scaled(xfc, x - xfc->offset_x,
|
||||
y - xfc->offset_y, w, h, FALSE);
|
||||
} else
|
||||
{
|
||||
XCopyArea(xfc->display, xfc->primary,
|
||||
xfc->window->handle, xfc->gc, x, y, w, h, x, y);
|
||||
xfc->window->handle, xfc->gc, x, y, w,
|
||||
h, x, y);
|
||||
}
|
||||
}
|
||||
else
|
||||
} else
|
||||
{
|
||||
xfWindow* xfw;
|
||||
rdpWindow* window;
|
||||
rdpRail* rail = ((rdpContext*) xfc)->rail;
|
||||
|
||||
window = window_list_get_by_extra_id(rail->list, (void*) event->xexpose.window);
|
||||
|
||||
if (window != NULL)
|
||||
|
||||
window = window_list_get_by_extra_id(rail->list,
|
||||
(void*) event->xexpose.window);
|
||||
|
||||
if (window != NULL )
|
||||
{
|
||||
xfw = (xfWindow*) window->extra;
|
||||
xf_UpdateWindowArea(xfc, xfw, x, y, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -156,12 +158,12 @@ BOOL xf_generic_MotionNotify(xfContext* xfc, int x, int y, int state, Window win
|
||||
RootWindowOfScreen(xfc->screen),
|
||||
x, y, &x, &y, &childWindow);
|
||||
}
|
||||
|
||||
if (xfc->scale != 1.0)
|
||||
|
||||
/* Take scaling in to consideration */
|
||||
if ( (xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y) )
|
||||
{
|
||||
/* Take scaling in to consideration */
|
||||
x = (int) (x * (1.0 / xfc->scale));
|
||||
y = (int) (y * (1.0 / xfc->scale));
|
||||
x = (int)((x - xfc->offset_x) * (1.0 / xfc->settings->ScalingFactor) );
|
||||
y = (int)((y - xfc->offset_y) * (1.0 / xfc->settings->ScalingFactor) );
|
||||
}
|
||||
|
||||
input->MouseEvent(input, PTR_FLAGS_MOVE, x, y);
|
||||
@ -260,13 +262,16 @@ BOOL xf_generic_ButtonPress(xfContext* xfc, int x, int y, int button, Window win
|
||||
XTranslateCoordinates(xfc->display, window,
|
||||
RootWindowOfScreen(xfc->screen),
|
||||
x, y, &x, &y, &childWindow);
|
||||
|
||||
}
|
||||
|
||||
if (xfc->scale != 1.0)
|
||||
if ((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x)
|
||||
|| (xfc->offset_y))
|
||||
{
|
||||
/* Take scaling in to consideration */
|
||||
x = (int) (x * (1.0 / xfc->scale));
|
||||
y = (int) (y * (1.0 / xfc->scale));
|
||||
x = (int) ((x - xfc->offset_x)
|
||||
* (1.0 / xfc->settings->ScalingFactor));
|
||||
y = (int) ((y - xfc->offset_y)
|
||||
* (1.0 / xfc->settings->ScalingFactor));
|
||||
}
|
||||
|
||||
if (extended)
|
||||
@ -350,11 +355,11 @@ BOOL xf_generic_ButtonRelease(xfContext* xfc, int x, int y, int button, Window w
|
||||
x, y, &x, &y, &childWindow);
|
||||
}
|
||||
|
||||
if (xfc->scale != 1.0)
|
||||
|
||||
if ((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y))
|
||||
{
|
||||
/* Take scaling in to consideration */
|
||||
x = (int) (x * (1.0 / xfc->scale));
|
||||
y = (int) (y * (1.0 / xfc->scale));
|
||||
x = (int) ((x - xfc->offset_x) * (1.0 / xfc->settings->ScalingFactor));
|
||||
y = (int) ((y - xfc->offset_y) * (1.0 / xfc->settings->ScalingFactor));
|
||||
}
|
||||
|
||||
if (extended)
|
||||
@ -552,15 +557,18 @@ static BOOL xf_event_ConfigureNotify(xfContext* xfc, XEvent* event, BOOL app)
|
||||
rdpWindow* window;
|
||||
rdpRail* rail = ((rdpContext*) xfc)->rail;
|
||||
|
||||
|
||||
/* This is for resizing the window by dragging the border
|
||||
|
||||
if (xfc->width != event->xconfigure.width)
|
||||
{
|
||||
xfc->scale = (double) event->xconfigure.width / (double) xfc->originalWidth;
|
||||
xfc->settings->ScalingFactor = (double) event->xconfigure.width / (double) xfc->originalWidth;
|
||||
xfc->currentWidth = event->xconfigure.width;
|
||||
xfc->currentHeight = event->xconfigure.width;
|
||||
|
||||
xf_draw_screen_scaled(xfc);
|
||||
}
|
||||
|
||||
*/
|
||||
window = window_list_get_by_extra_id(rail->list, (void*) event->xconfigure.window);
|
||||
|
||||
if (window != NULL)
|
||||
@ -578,6 +586,9 @@ static BOOL xf_event_ConfigureNotify(xfContext* xfc, XEvent* event, BOOL app)
|
||||
RootWindowOfScreen(xfc->screen),
|
||||
0, 0, &xfw->left, &xfw->top, &childWindow);
|
||||
|
||||
|
||||
|
||||
|
||||
xfw->width = event->xconfigure.width;
|
||||
xfw->height = event->xconfigure.height;
|
||||
xfw->right = xfw->left + xfw->width - 1;
|
||||
@ -936,7 +947,6 @@ BOOL xf_event_process(freerdp* instance, XEvent* event)
|
||||
case MotionNotify:
|
||||
status = xf_event_MotionNotify(xfc, event, xfc->remote_app);
|
||||
break;
|
||||
|
||||
case ButtonPress:
|
||||
status = xf_event_ButtonPress(xfc, event, xfc->remote_app);
|
||||
break;
|
||||
@ -1013,6 +1023,7 @@ BOOL xf_event_process(freerdp* instance, XEvent* event)
|
||||
case PropertyNotify:
|
||||
status = xf_event_PropertyNotify(xfc, event, xfc->remote_app);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
xf_input_handle_event(xfc, event);
|
||||
|
@ -28,13 +28,17 @@
|
||||
#include <math.h>
|
||||
|
||||
#include "xf_event.h"
|
||||
|
||||
#include "xf_input.h"
|
||||
|
||||
#ifdef WITH_XI
|
||||
|
||||
#define MAX_CONTACTS 2
|
||||
|
||||
#define PAN_THRESHOLD 50
|
||||
#define ZOOM_THRESHOLD 10
|
||||
|
||||
#define MIN_FINGER_DIST 5
|
||||
|
||||
typedef struct touch_contact
|
||||
{
|
||||
int id;
|
||||
@ -43,16 +47,21 @@ typedef struct touch_contact
|
||||
double pos_y;
|
||||
double last_x;
|
||||
double last_y;
|
||||
|
||||
|
||||
} touchContact;
|
||||
|
||||
touchContact contacts[MAX_CONTACTS];
|
||||
|
||||
int active_contacts;
|
||||
int lastEvType;
|
||||
XIDeviceEvent lastEvent;
|
||||
double firstDist = -1.0;
|
||||
double lastDist;
|
||||
|
||||
double z_vector;
|
||||
double px_vector;
|
||||
double py_vector;
|
||||
|
||||
int xinput_opcode;
|
||||
int scale_cnt;
|
||||
|
||||
@ -68,10 +77,11 @@ const char* xf_input_get_class_string(int class)
|
||||
return "XIScrollClass";
|
||||
else if (class == XITouchClass)
|
||||
return "XITouchClass";
|
||||
|
||||
|
||||
return "XIUnknownClass";
|
||||
}
|
||||
|
||||
|
||||
int xf_input_init(xfContext* xfc, Window window)
|
||||
{
|
||||
int i, j;
|
||||
@ -84,90 +94,94 @@ int xf_input_init(xfContext* xfc, Window window)
|
||||
XIEventMask evmasks[64];
|
||||
int opcode, event, error;
|
||||
BYTE masks[8][XIMaskLen(XI_LASTEVENT)];
|
||||
|
||||
|
||||
z_vector = 0;
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
|
||||
nmasks = 0;
|
||||
ndevices = 0;
|
||||
active_contacts = 0;
|
||||
ZeroMemory(contacts, sizeof(touchContact) * MAX_CONTACTS);
|
||||
|
||||
|
||||
if (!XQueryExtension(xfc->display, "XInputExtension", &opcode, &event, &error))
|
||||
{
|
||||
printf("XInput extension not available.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
xfc->XInputOpcode = opcode;
|
||||
|
||||
|
||||
XIQueryVersion(xfc->display, &major, &minor);
|
||||
|
||||
|
||||
if (major * 1000 + minor < 2002)
|
||||
{
|
||||
printf("Server does not support XI 2.2\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (xfc->settings->MultiTouchInput)
|
||||
xfc->use_xinput = TRUE;
|
||||
|
||||
|
||||
info = XIQueryDevice(xfc->display, XIAllDevices, &ndevices);
|
||||
|
||||
|
||||
for (i = 0; i < ndevices; i++)
|
||||
{
|
||||
BOOL touch = FALSE;
|
||||
XIDeviceInfo* dev = &info[i];
|
||||
|
||||
|
||||
for (j = 0; j < dev->num_classes; j++)
|
||||
{
|
||||
XIAnyClassInfo* class = dev->classes[j];
|
||||
XITouchClassInfo* t = (XITouchClassInfo*) class;
|
||||
|
||||
|
||||
if ((class->type == XITouchClass) && (t->mode == XIDirectTouch) &&
|
||||
(strcmp(dev->name, "Virtual core pointer") != 0))
|
||||
(strcmp(dev->name, "Virtual core pointer") != 0))
|
||||
{
|
||||
touch = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (j = 0; j < dev->num_classes; j++)
|
||||
{
|
||||
XIAnyClassInfo* class = dev->classes[j];
|
||||
XITouchClassInfo* t = (XITouchClassInfo*) class;
|
||||
|
||||
|
||||
if (xfc->settings->MultiTouchInput)
|
||||
{
|
||||
printf("%s (%d) \"%s\" id: %d\n",
|
||||
xf_input_get_class_string(class->type),
|
||||
class->type, dev->name, dev->deviceid);
|
||||
xf_input_get_class_string(class->type),
|
||||
class->type, dev->name, dev->deviceid);
|
||||
}
|
||||
|
||||
|
||||
evmasks[nmasks].mask = masks[nmasks];
|
||||
evmasks[nmasks].mask_len = sizeof(masks[0]);
|
||||
ZeroMemory(masks[nmasks], sizeof(masks[0]));
|
||||
evmasks[nmasks].deviceid = dev->deviceid;
|
||||
|
||||
|
||||
if ((class->type == XITouchClass) && (t->mode == XIDirectTouch) &&
|
||||
(strcmp(dev->name, "Virtual core pointer") != 0))
|
||||
(strcmp(dev->name, "Virtual core pointer") != 0))
|
||||
{
|
||||
if (xfc->settings->MultiTouchInput)
|
||||
{
|
||||
printf("%s %s touch device (id: %d, mode: %d), supporting %d touches.\n",
|
||||
dev->name, (t->mode == XIDirectTouch) ? "direct" : "dependent",
|
||||
dev->deviceid, t->mode, t->num_touches);
|
||||
dev->name, (t->mode == XIDirectTouch) ? "direct" : "dependent",
|
||||
dev->deviceid, t->mode, t->num_touches);
|
||||
}
|
||||
|
||||
|
||||
XISetMask(masks[nmasks], XI_TouchBegin);
|
||||
XISetMask(masks[nmasks], XI_TouchUpdate);
|
||||
XISetMask(masks[nmasks], XI_TouchEnd);
|
||||
nmasks++;
|
||||
}
|
||||
|
||||
|
||||
if (xfc->use_xinput)
|
||||
{
|
||||
if (!touch && (class->type == XIButtonClass) && strcmp(dev->name, "Virtual core pointer"))
|
||||
{
|
||||
printf("%s button device (id: %d, mode: %d)\n",
|
||||
dev->name,
|
||||
dev->deviceid, t->mode);
|
||||
dev->name,
|
||||
dev->deviceid, t->mode);
|
||||
XISetMask(masks[nmasks], XI_ButtonPress);
|
||||
XISetMask(masks[nmasks], XI_ButtonRelease);
|
||||
XISetMask(masks[nmasks], XI_Motion);
|
||||
@ -176,51 +190,181 @@ int xf_input_init(xfContext* xfc, Window window)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (nmasks > 0)
|
||||
xstatus = XISelectEvents(xfc->display, window, evmasks, nmasks);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL xf_input_is_duplicate(XIDeviceEvent* event)
|
||||
BOOL xf_input_is_duplicate(XGenericEventCookie* cookie)
|
||||
{
|
||||
XIDeviceEvent* event;
|
||||
|
||||
event = cookie->data;
|
||||
|
||||
|
||||
if ( (lastEvent.time == event->time) &&
|
||||
(lastEvent.detail == event->detail) &&
|
||||
(lastEvent.event_x == event->event_x) &&
|
||||
(lastEvent.event_y == event->event_y) )
|
||||
(lastEvType == cookie->evtype) &&
|
||||
(lastEvent.detail == event->detail) &&
|
||||
(lastEvent.event_x == event->event_x) &&
|
||||
(lastEvent.event_y == event->event_y) )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void xf_input_save_last_event(XIDeviceEvent* event)
|
||||
void xf_input_save_last_event(XGenericEventCookie* cookie)
|
||||
{
|
||||
XIDeviceEvent* event;
|
||||
|
||||
event = cookie->data;
|
||||
|
||||
lastEvType = cookie->evtype;
|
||||
|
||||
lastEvent.time = event->time;
|
||||
lastEvent.detail = event->detail;
|
||||
lastEvent.event_x = event->event_x;
|
||||
lastEvent.event_y = event->event_y;
|
||||
|
||||
}
|
||||
|
||||
void xf_input_detect_pan(xfContext* xfc)
|
||||
{
|
||||
double dx[2];
|
||||
double dy[2];
|
||||
|
||||
double px;
|
||||
double py;
|
||||
|
||||
double dist_x;
|
||||
double dist_y;
|
||||
|
||||
if (active_contacts != 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dx[0] = contacts[0].pos_x - contacts[0].last_x;
|
||||
dx[1] = contacts[1].pos_x - contacts[1].last_x;
|
||||
|
||||
dy[0] = contacts[0].pos_y - contacts[0].last_y;
|
||||
dy[1] = contacts[1].pos_y - contacts[1].last_y;
|
||||
|
||||
px = fabs(dx[0]) < fabs(dx[1]) ? dx[0] : dx[1];
|
||||
py = fabs(dy[0]) < fabs(dy[1]) ? dy[0] : dy[1];
|
||||
|
||||
px_vector += px;
|
||||
py_vector += py;
|
||||
|
||||
dist_x = fabs(contacts[0].pos_x - contacts[1].pos_x);
|
||||
dist_y = fabs(contacts[0].pos_y - contacts[1].pos_y);
|
||||
|
||||
|
||||
//only pan in x if dist_y is greater than something
|
||||
if(dist_y > MIN_FINGER_DIST)
|
||||
{
|
||||
|
||||
if(px_vector > PAN_THRESHOLD)
|
||||
{
|
||||
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.XPan = 5;
|
||||
e.YPan = 0;
|
||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
|
||||
px_vector = 0;
|
||||
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
z_vector = 0;
|
||||
}
|
||||
else if(px_vector < -PAN_THRESHOLD)
|
||||
{
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.XPan = -5;
|
||||
e.YPan = 0;
|
||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
|
||||
px_vector = 0;
|
||||
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
z_vector = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(dist_x > MIN_FINGER_DIST)
|
||||
{
|
||||
|
||||
if(py_vector > PAN_THRESHOLD)
|
||||
{
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.XPan = 0;
|
||||
e.YPan = 5;
|
||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
|
||||
py_vector = 0;
|
||||
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
z_vector = 0;
|
||||
}
|
||||
else if(py_vector < -PAN_THRESHOLD)
|
||||
{
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.XPan = 0;
|
||||
e.YPan = -5;
|
||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
|
||||
py_vector = 0;
|
||||
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
z_vector = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void xf_input_detect_pinch(xfContext* xfc)
|
||||
{
|
||||
double dist;
|
||||
double zoom;
|
||||
|
||||
double delta;
|
||||
ResizeWindowEventArgs e;
|
||||
|
||||
|
||||
if (active_contacts != 2)
|
||||
{
|
||||
firstDist = -1.0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* first calculate the distance */
|
||||
dist = sqrt(pow(contacts[1].pos_x - contacts[0].last_x, 2.0) +
|
||||
pow(contacts[1].pos_y - contacts[0].last_y, 2.0));
|
||||
|
||||
pow(contacts[1].pos_y - contacts[0].last_y, 2.0));
|
||||
|
||||
/* if this is the first 2pt touch */
|
||||
if (firstDist <= 0)
|
||||
{
|
||||
@ -228,50 +372,69 @@ void xf_input_detect_pinch(xfContext* xfc)
|
||||
lastDist = firstDist;
|
||||
scale_cnt = 0;
|
||||
z_vector = 0;
|
||||
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
z_vector = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
delta = lastDist - dist;
|
||||
|
||||
|
||||
if(delta > 1.0)
|
||||
delta = 1.0;
|
||||
if(delta < -1.0)
|
||||
delta = -1.0;
|
||||
|
||||
/* compare the current distance to the first one */
|
||||
zoom = (dist / firstDist);
|
||||
|
||||
|
||||
z_vector += delta;
|
||||
//printf("d: %.2f\n", delta);
|
||||
|
||||
|
||||
|
||||
lastDist = dist;
|
||||
|
||||
if (z_vector > 10)
|
||||
|
||||
if (z_vector > ZOOM_THRESHOLD)
|
||||
{
|
||||
xfc->scale -= 0.05;
|
||||
|
||||
if (xfc->scale < 0.5)
|
||||
xfc->scale = 0.5;
|
||||
|
||||
XResizeWindow(xfc->display, xfc->window->handle, xfc->originalWidth * xfc->scale, xfc->originalHeight * xfc->scale);
|
||||
|
||||
xfc->settings->ScalingFactor -= 0.05;
|
||||
|
||||
if (xfc->settings->ScalingFactor < 0.8)
|
||||
xfc->settings->ScalingFactor = 0.8;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.width = (int) xfc->originalWidth * xfc->scale;
|
||||
e.height = (int) xfc->originalHeight * xfc->scale;
|
||||
e.width = (int) xfc->originalWidth * xfc->settings->ScalingFactor;
|
||||
e.height = (int) xfc->originalHeight * xfc->settings->ScalingFactor;
|
||||
|
||||
xf_transform_window(xfc);
|
||||
PubSub_OnResizeWindow(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
|
||||
xf_draw_screen_scaled(xfc, 0, 0, 0, 0, FALSE);
|
||||
|
||||
z_vector = 0;
|
||||
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
z_vector = 0;
|
||||
}
|
||||
|
||||
if (z_vector < -10)
|
||||
|
||||
if (z_vector < -ZOOM_THRESHOLD)
|
||||
{
|
||||
xfc->scale += 0.05;
|
||||
|
||||
if (xfc->scale > 1.5)
|
||||
xfc->scale = 1.5;
|
||||
|
||||
XResizeWindow(xfc->display, xfc->window->handle, xfc->originalWidth * xfc->scale, xfc->originalHeight * xfc->scale);
|
||||
|
||||
xfc->settings->ScalingFactor += 0.05;
|
||||
|
||||
if (xfc->settings->ScalingFactor > 1.2)
|
||||
xfc->settings->ScalingFactor = 1.2;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.width = (int) xfc->originalWidth * xfc->scale;
|
||||
e.height = (int) xfc->originalHeight * xfc->scale;
|
||||
e.width = (int) xfc->originalWidth * xfc->settings->ScalingFactor;
|
||||
e.height = (int) xfc->originalHeight * xfc->settings->ScalingFactor;
|
||||
|
||||
xf_transform_window(xfc);
|
||||
PubSub_OnResizeWindow(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
|
||||
xf_draw_screen_scaled(xfc, 0, 0, 0, 0, FALSE);
|
||||
|
||||
z_vector = 0;
|
||||
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
z_vector = 0;
|
||||
}
|
||||
}
|
||||
@ -280,7 +443,9 @@ void xf_input_detect_pinch(xfContext* xfc)
|
||||
void xf_input_touch_begin(xfContext* xfc, XIDeviceEvent* event)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(active_contacts == MAX_CONTACTS)
|
||||
printf("Houston, we have a problem!\n\n");
|
||||
|
||||
for (i = 0; i < MAX_CONTACTS; i++)
|
||||
{
|
||||
if (contacts[i].id == 0)
|
||||
@ -289,7 +454,7 @@ void xf_input_touch_begin(xfContext* xfc, XIDeviceEvent* event)
|
||||
contacts[i].count = 1;
|
||||
contacts[i].pos_x = event->event_x;
|
||||
contacts[i].pos_y = event->event_y;
|
||||
|
||||
|
||||
active_contacts++;
|
||||
break;
|
||||
}
|
||||
@ -299,7 +464,6 @@ void xf_input_touch_begin(xfContext* xfc, XIDeviceEvent* event)
|
||||
void xf_input_touch_update(xfContext* xfc, XIDeviceEvent* event)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_CONTACTS; i++)
|
||||
{
|
||||
if (contacts[i].id == event->detail)
|
||||
@ -309,9 +473,10 @@ void xf_input_touch_update(xfContext* xfc, XIDeviceEvent* event)
|
||||
contacts[i].last_y = contacts[i].pos_y;
|
||||
contacts[i].pos_x = event->event_x;
|
||||
contacts[i].pos_y = event->event_y;
|
||||
|
||||
|
||||
xf_input_detect_pinch(xfc);
|
||||
|
||||
xf_input_detect_pan(xfc);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -320,7 +485,6 @@ void xf_input_touch_update(xfContext* xfc, XIDeviceEvent* event)
|
||||
void xf_input_touch_end(xfContext* xfc, XIDeviceEvent* event)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_CONTACTS; i++)
|
||||
{
|
||||
if (contacts[i].id == event->detail)
|
||||
@ -329,7 +493,7 @@ void xf_input_touch_end(xfContext* xfc, XIDeviceEvent* event)
|
||||
contacts[i].count = 0;
|
||||
//contacts[i].pos_x = (int)event->event_x;
|
||||
//contacts[i].pos_y = (int)event->event_y;
|
||||
|
||||
|
||||
active_contacts--;
|
||||
break;printf("TouchBegin\n");
|
||||
}
|
||||
@ -339,39 +503,39 @@ void xf_input_touch_end(xfContext* xfc, XIDeviceEvent* event)
|
||||
int xf_input_handle_event_local(xfContext* xfc, XEvent* event)
|
||||
{
|
||||
XGenericEventCookie* cookie = &event->xcookie;
|
||||
|
||||
|
||||
XGetEventData(xfc->display, cookie);
|
||||
|
||||
|
||||
if ((cookie->type == GenericEvent) && (cookie->extension == xfc->XInputOpcode))
|
||||
{
|
||||
switch (cookie->evtype)
|
||||
{
|
||||
case XI_TouchBegin:
|
||||
if (xf_input_is_duplicate(cookie->data) == FALSE)
|
||||
if (xf_input_is_duplicate(cookie) == FALSE)
|
||||
xf_input_touch_begin(xfc, cookie->data);
|
||||
xf_input_save_last_event(cookie->data);
|
||||
xf_input_save_last_event(cookie);
|
||||
break;
|
||||
|
||||
|
||||
case XI_TouchUpdate:
|
||||
if (xf_input_is_duplicate(cookie->data) == FALSE)
|
||||
if (xf_input_is_duplicate(cookie) == FALSE)
|
||||
xf_input_touch_update(xfc, cookie->data);
|
||||
xf_input_save_last_event(cookie->data);
|
||||
xf_input_save_last_event(cookie);
|
||||
break;
|
||||
|
||||
|
||||
case XI_TouchEnd:
|
||||
if (xf_input_is_duplicate(cookie->data) == FALSE)
|
||||
if (xf_input_is_duplicate(cookie) == FALSE)
|
||||
xf_input_touch_end(xfc, cookie->data);
|
||||
xf_input_save_last_event(cookie->data);
|
||||
xf_input_save_last_event(cookie);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
printf("unhandled xi type= %d\n", cookie->evtype);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
XFreeEventData(xfc->display,cookie);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -393,66 +557,66 @@ int xf_input_touch_remote(xfContext* xfc, XIDeviceEvent* event, int evtype)
|
||||
int touchId;
|
||||
int contactId;
|
||||
RdpeiClientContext* rdpei = xfc->rdpei;
|
||||
|
||||
|
||||
if (!rdpei)
|
||||
return 0;
|
||||
|
||||
|
||||
touchId = event->detail;
|
||||
x = (int) event->event_x;
|
||||
y = (int) event->event_y;
|
||||
|
||||
|
||||
if (evtype == XI_TouchBegin)
|
||||
{
|
||||
//printf("TouchBegin: %d\n", touchId);
|
||||
printf("TouchBegin: %d\n", touchId);
|
||||
contactId = rdpei->TouchBegin(rdpei, touchId, x, y);
|
||||
}
|
||||
else if (evtype == XI_TouchUpdate)
|
||||
{
|
||||
//printf("TouchUpdate: %d\n", touchId);
|
||||
printf("TouchUpdate: %d\n", touchId);
|
||||
contactId = rdpei->TouchUpdate(rdpei, touchId, x, y);
|
||||
}
|
||||
else if (evtype == XI_TouchEnd)
|
||||
{
|
||||
//printf("TouchEnd: %d\n", touchId);
|
||||
printf("TouchEnd: %d\n", touchId);
|
||||
contactId = rdpei->TouchEnd(rdpei, touchId, x, y);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xf_input_event(xfContext* xfc, XIDeviceEvent* event, int evtype)
|
||||
{
|
||||
|
||||
|
||||
switch (evtype)
|
||||
{
|
||||
case XI_ButtonPress:
|
||||
//printf("ButtonPress\n");
|
||||
|
||||
xf_generic_ButtonPress(xfc, (int) event->event_x, (int) event->event_y,
|
||||
event->detail, event->event, xfc->remote_app);
|
||||
event->detail, event->event, xfc->remote_app);
|
||||
break;
|
||||
|
||||
|
||||
case XI_ButtonRelease:
|
||||
//printf("ButtonRelease\n");
|
||||
|
||||
xf_generic_ButtonRelease(xfc, (int) event->event_x, (int) event->event_y,
|
||||
event->detail, event->event, xfc->remote_app);
|
||||
event->detail, event->event, xfc->remote_app);
|
||||
break;
|
||||
|
||||
|
||||
case XI_Motion:
|
||||
//printf("Motion\n");
|
||||
|
||||
xf_generic_MotionNotify(xfc, (int) event->event_x, (int) event->event_y,
|
||||
event->detail, event->event, xfc->remote_app);
|
||||
event->detail, event->event, xfc->remote_app);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xf_input_handle_event_remote(xfContext* xfc, XEvent* event)
|
||||
{
|
||||
XGenericEventCookie* cookie = &event->xcookie;
|
||||
|
||||
|
||||
XGetEventData(xfc->display, cookie);
|
||||
|
||||
|
||||
if ((cookie->type == GenericEvent) && (cookie->extension == xfc->XInputOpcode))
|
||||
{
|
||||
switch (cookie->evtype)
|
||||
@ -460,23 +624,23 @@ int xf_input_handle_event_remote(xfContext* xfc, XEvent* event)
|
||||
case XI_TouchBegin:
|
||||
xf_input_touch_remote(xfc, cookie->data, XI_TouchBegin);
|
||||
break;
|
||||
|
||||
|
||||
case XI_TouchUpdate:
|
||||
xf_input_touch_remote(xfc, cookie->data, XI_TouchUpdate);
|
||||
break;
|
||||
|
||||
|
||||
case XI_TouchEnd:
|
||||
xf_input_touch_remote(xfc, cookie->data, XI_TouchEnd);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
xf_input_event(xfc, cookie->data, cookie->evtype);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
XFreeEventData(xfc->display,cookie);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -495,10 +659,10 @@ void xf_process_rdpei_event(xfContext* xfc, wMessage* event)
|
||||
{
|
||||
case RdpeiChannel_ServerReady:
|
||||
break;
|
||||
|
||||
|
||||
case RdpeiChannel_SuspendTouch:
|
||||
break;
|
||||
|
||||
|
||||
case RdpeiChannel_ResumeTouch:
|
||||
break;
|
||||
}
|
||||
@ -507,14 +671,16 @@ void xf_process_rdpei_event(xfContext* xfc, wMessage* event)
|
||||
int xf_input_handle_event(xfContext* xfc, XEvent* event)
|
||||
{
|
||||
#ifdef WITH_XI
|
||||
if (xfc->settings->MultiTouchInput)
|
||||
//printf("m:%d g:%d\n", (xfc->settings->MultiTouchInput), (xfc->settings->MultiTouchGestures) );
|
||||
if (xfc->settings->MultiTouchInput)
|
||||
{
|
||||
return xf_input_handle_event_remote(xfc, event);
|
||||
}
|
||||
|
||||
if (xfc->enableScaling)
|
||||
|
||||
if (xfc->settings->MultiTouchGestures)
|
||||
return xf_input_handle_event_local(xfc, event);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -216,7 +216,160 @@ BOOL xf_kbd_handle_special_keys(xfContext* xfc, KeySym keysym)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (keysym == XK_period)
|
||||
{
|
||||
if ((xf_kbd_key_pressed(xfc, XK_Alt_L)
|
||||
|| xf_kbd_key_pressed(xfc, XK_Alt_R))
|
||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L)
|
||||
|| xf_kbd_key_pressed(xfc,
|
||||
XK_Control_R)))
|
||||
{
|
||||
//Zoom in (scale larger)
|
||||
double s = xfc->settings->ScalingFactor;
|
||||
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);
|
||||
|
||||
{
|
||||
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, 0, 0, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (keysym == XK_comma)
|
||||
{
|
||||
if ((xf_kbd_key_pressed(xfc, XK_Alt_L)
|
||||
|| xf_kbd_key_pressed(xfc, XK_Alt_R))
|
||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L)
|
||||
|| xf_kbd_key_pressed(xfc,
|
||||
XK_Control_R)))
|
||||
{
|
||||
//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, 0, 0, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (keysym == XK_KP_4)
|
||||
{
|
||||
if ((xf_kbd_key_pressed(xfc, XK_Alt_L)
|
||||
|| xf_kbd_key_pressed(xfc, XK_Alt_R))
|
||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L)
|
||||
|| xf_kbd_key_pressed(xfc,
|
||||
XK_Control_R)))
|
||||
{
|
||||
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.XPan = -5;
|
||||
e.YPan = 0;
|
||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (keysym == XK_KP_6)
|
||||
{
|
||||
if ((xf_kbd_key_pressed(xfc, XK_Alt_L)
|
||||
|| xf_kbd_key_pressed(xfc, XK_Alt_R))
|
||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L)
|
||||
|| xf_kbd_key_pressed(xfc,
|
||||
XK_Control_R)))
|
||||
{
|
||||
|
||||
{
|
||||
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 ((xf_kbd_key_pressed(xfc, XK_Alt_L)
|
||||
|| xf_kbd_key_pressed(xfc, XK_Alt_R))
|
||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L)
|
||||
|| xf_kbd_key_pressed(xfc,
|
||||
XK_Control_R)))
|
||||
{
|
||||
{
|
||||
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 ((xf_kbd_key_pressed(xfc, XK_Alt_L)
|
||||
|| xf_kbd_key_pressed(xfc, XK_Alt_R))
|
||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L)
|
||||
|| xf_kbd_key_pressed(xfc,
|
||||
XK_Control_R)))
|
||||
{
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.XPan = 0;
|
||||
e.YPan = 5;
|
||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,7 @@
|
||||
|
||||
#ifdef WITH_XI
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#include "xf_input.h"
|
||||
#endif
|
||||
|
||||
#include "xf_input.h"
|
||||
|
@ -106,7 +106,7 @@ struct xf_context
|
||||
UINT16 frame_x2;
|
||||
UINT16 frame_y2;
|
||||
|
||||
double scale;
|
||||
//double scale;
|
||||
int originalWidth;
|
||||
int originalHeight;
|
||||
int currentWidth;
|
||||
@ -114,6 +114,9 @@ struct xf_context
|
||||
int XInputOpcode;
|
||||
BOOL enableScaling;
|
||||
|
||||
int offset_x;
|
||||
int offset_y;
|
||||
|
||||
BOOL focused;
|
||||
BOOL use_xinput;
|
||||
BOOL mouse_active;
|
||||
@ -208,7 +211,8 @@ enum XF_EXIT_CODE
|
||||
void xf_lock_x11(xfContext* xfc, BOOL display);
|
||||
void xf_unlock_x11(xfContext* xfc, BOOL display);
|
||||
|
||||
void xf_draw_screen_scaled(xfContext* xfc);
|
||||
void xf_draw_screen_scaled(xfContext* xfc, int x, int y, int w, int h, BOOL scale);
|
||||
void xf_transform_window(xfContext* xfc);
|
||||
|
||||
DWORD xf_exit_code_from_disconnect_reason(DWORD reason);
|
||||
|
||||
|
@ -90,6 +90,7 @@ COMMAND_LINE_ARGUMENT_A args[] =
|
||||
{ "printer", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, NULL, "Redirect printer device" },
|
||||
{ "usb", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Redirect USB device" },
|
||||
{ "multitouch", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Redirect multitouch input" },
|
||||
{ "gestures", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Consume multitouch input locally" },
|
||||
{ "echo", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, "echo", "Echo channel" },
|
||||
{ "disp", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "Display control" },
|
||||
{ "fonts", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Smooth fonts (ClearType)" },
|
||||
@ -598,6 +599,11 @@ int freerdp_client_command_line_post_filter(void* context, COMMAND_LINE_ARGUMENT
|
||||
p[0] = "rdpei";
|
||||
freerdp_client_add_dynamic_channel(settings, count, p);
|
||||
}
|
||||
CommandLineSwitchCase(arg, "gestures")
|
||||
{
|
||||
printf("gestures\n");
|
||||
settings->MultiTouchGestures = TRUE;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "echo")
|
||||
{
|
||||
char* p[1];
|
||||
|
237
cmake/FindImageMagick.cmake
Normal file
237
cmake/FindImageMagick.cmake
Normal file
@ -0,0 +1,237 @@
|
||||
# - Find the ImageMagick binary suite.
|
||||
# This module will search for a set of ImageMagick tools specified
|
||||
# as components in the FIND_PACKAGE call. Typical components include,
|
||||
# but are not limited to (future versions of ImageMagick might have
|
||||
# additional components not listed here):
|
||||
#
|
||||
# animate
|
||||
# compare
|
||||
# composite
|
||||
# conjure
|
||||
# convert
|
||||
# display
|
||||
# identify
|
||||
# import
|
||||
# mogrify
|
||||
# montage
|
||||
# stream
|
||||
#
|
||||
# If no component is specified in the FIND_PACKAGE call, then it only
|
||||
# searches for the ImageMagick executable directory. This code defines
|
||||
# the following variables:
|
||||
#
|
||||
# ImageMagick_FOUND - TRUE if all components are found.
|
||||
# ImageMagick_EXECUTABLE_DIR - Full path to executables directory.
|
||||
# ImageMagick_<component>_FOUND - TRUE if <component> is found.
|
||||
# ImageMagick_<component>_EXECUTABLE - Full path to <component> executable.
|
||||
# ImageMagick_VERSION_STRING - the version of ImageMagick found
|
||||
# (since CMake 2.8.8)
|
||||
#
|
||||
# ImageMagick_VERSION_STRING will not work for old versions like 5.2.3.
|
||||
#
|
||||
# There are also components for the following ImageMagick APIs:
|
||||
#
|
||||
# Magick++
|
||||
# MagickWand
|
||||
# MagickCore
|
||||
#
|
||||
# For these components the following variables are set:
|
||||
#
|
||||
# ImageMagick_FOUND - TRUE if all components are found.
|
||||
# ImageMagick_INCLUDE_DIRS - Full paths to all include dirs.
|
||||
# ImageMagick_LIBRARIES - Full paths to all libraries.
|
||||
# ImageMagick_<component>_FOUND - TRUE if <component> is found.
|
||||
# ImageMagick_<component>_INCLUDE_DIRS - Full path to <component> include dirs.
|
||||
# ImageMagick_<component>_LIBRARIES - Full path to <component> libraries.
|
||||
#
|
||||
# Example Usages:
|
||||
# find_package(ImageMagick)
|
||||
# find_package(ImageMagick COMPONENTS convert)
|
||||
# find_package(ImageMagick COMPONENTS convert mogrify display)
|
||||
# find_package(ImageMagick COMPONENTS Magick++)
|
||||
# find_package(ImageMagick COMPONENTS Magick++ convert)
|
||||
#
|
||||
# Note that the standard FIND_PACKAGE features are supported
|
||||
# (i.e., QUIET, REQUIRED, etc.).
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2007-2009 Kitware, Inc.
|
||||
# Copyright 2007-2008 Miguel A. Figueroa-Villanueva <miguelf at ieee dot org>
|
||||
# Copyright 2012 Rolf Eike Beer <eike@sf-mail.de>
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# Helper functions
|
||||
#---------------------------------------------------------------------
|
||||
function(FIND_IMAGEMAGICK_API component header)
|
||||
set(ImageMagick_${component}_FOUND FALSE PARENT_SCOPE)
|
||||
|
||||
find_path(ImageMagick_${component}_INCLUDE_DIR
|
||||
NAMES ${header}
|
||||
PATHS
|
||||
${ImageMagick_INCLUDE_DIRS}
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]/include"
|
||||
PATH_SUFFIXES
|
||||
ImageMagick
|
||||
DOC "Path to the ImageMagick include dir."
|
||||
)
|
||||
find_library(ImageMagick_${component}_LIBRARY
|
||||
NAMES ${ARGN}
|
||||
PATHS
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]/lib"
|
||||
DOC "Path to the ImageMagick Magick++ library."
|
||||
)
|
||||
|
||||
if(ImageMagick_${component}_INCLUDE_DIR AND ImageMagick_${component}_LIBRARY)
|
||||
set(ImageMagick_${component}_FOUND TRUE PARENT_SCOPE)
|
||||
|
||||
list(APPEND ImageMagick_INCLUDE_DIRS
|
||||
${ImageMagick_${component}_INCLUDE_DIR}
|
||||
)
|
||||
list(REMOVE_DUPLICATES ImageMagick_INCLUDE_DIRS)
|
||||
set(ImageMagick_INCLUDE_DIRS ${ImageMagick_INCLUDE_DIRS} PARENT_SCOPE)
|
||||
|
||||
list(APPEND ImageMagick_LIBRARIES
|
||||
${ImageMagick_${component}_LIBRARY}
|
||||
)
|
||||
set(ImageMagick_LIBRARIES ${ImageMagick_LIBRARIES} PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(FIND_IMAGEMAGICK_EXE component)
|
||||
set(_IMAGEMAGICK_EXECUTABLE
|
||||
${ImageMagick_EXECUTABLE_DIR}/${component}${CMAKE_EXECUTABLE_SUFFIX})
|
||||
if(EXISTS ${_IMAGEMAGICK_EXECUTABLE})
|
||||
set(ImageMagick_${component}_EXECUTABLE
|
||||
${_IMAGEMAGICK_EXECUTABLE}
|
||||
PARENT_SCOPE
|
||||
)
|
||||
set(ImageMagick_${component}_FOUND TRUE PARENT_SCOPE)
|
||||
else()
|
||||
set(ImageMagick_${component}_FOUND FALSE PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# Start Actual Work
|
||||
#---------------------------------------------------------------------
|
||||
# Try to find a ImageMagick installation binary path.
|
||||
find_path(ImageMagick_EXECUTABLE_DIR
|
||||
NAMES mogrify${CMAKE_EXECUTABLE_SUFFIX}
|
||||
PATHS
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]"
|
||||
DOC "Path to the ImageMagick binary directory."
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
find_path(ImageMagick_EXECUTABLE_DIR
|
||||
NAMES mogrify${CMAKE_EXECUTABLE_SUFFIX}
|
||||
)
|
||||
|
||||
# Find each component. Search for all tools in same dir
|
||||
# <ImageMagick_EXECUTABLE_DIR>; otherwise they should be found
|
||||
# independently and not in a cohesive module such as this one.
|
||||
unset(ImageMagick_REQUIRED_VARS)
|
||||
unset(ImageMagick_DEFAULT_EXECUTABLES)
|
||||
foreach(component ${ImageMagick_FIND_COMPONENTS}
|
||||
# DEPRECATED: forced components for backward compatibility
|
||||
convert mogrify import montage composite
|
||||
)
|
||||
if(component STREQUAL "Magick++")
|
||||
FIND_IMAGEMAGICK_API(Magick++ Magick++.h
|
||||
Magick++ CORE_RL_Magick++_ Magick++-Q16 Magick++-Q8
|
||||
)
|
||||
list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_Magick++_LIBRARY)
|
||||
elseif(component STREQUAL "MagickWand")
|
||||
FIND_IMAGEMAGICK_API(MagickWand wand/MagickWand.h
|
||||
Wand MagickWand CORE_RL_wand_ MagickWand-Q16 MagickWand-Q8
|
||||
)
|
||||
list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_MagickWand_LIBRARY)
|
||||
elseif(component STREQUAL "MagickCore")
|
||||
FIND_IMAGEMAGICK_API(MagickCore magick/MagickCore.h
|
||||
Magick MagickCore CORE_RL_magick_ MagickCore-6 MagickCore-Q16 MagickCore-Q8
|
||||
)
|
||||
list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_MagickCore_LIBRARY)
|
||||
else()
|
||||
if(ImageMagick_EXECUTABLE_DIR)
|
||||
FIND_IMAGEMAGICK_EXE(${component})
|
||||
endif()
|
||||
|
||||
if(ImageMagick_FIND_COMPONENTS)
|
||||
list(FIND ImageMagick_FIND_COMPONENTS ${component} is_requested)
|
||||
if(is_requested GREATER -1)
|
||||
list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_${component}_EXECUTABLE)
|
||||
endif()
|
||||
elseif(ImageMagick_${component}_EXECUTABLE)
|
||||
# if no components were requested explicitly put all (default) executables
|
||||
# in the list
|
||||
list(APPEND ImageMagick_DEFAULT_EXECUTABLES ImageMagick_${component}_EXECUTABLE)
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(NOT ImageMagick_FIND_COMPONENTS AND NOT ImageMagick_DEFAULT_EXECUTABLES)
|
||||
# No components were requested, and none of the default components were
|
||||
# found. Just insert mogrify into the list of the default components to
|
||||
# find so FPHSA below has something to check
|
||||
list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_mogrify_EXECUTABLE)
|
||||
elseif(ImageMagick_DEFAULT_EXECUTABLES)
|
||||
list(APPEND ImageMagick_REQUIRED_VARS ${ImageMagick_DEFAULT_EXECUTABLES})
|
||||
endif()
|
||||
|
||||
set(ImageMagick_INCLUDE_DIRS ${ImageMagick_INCLUDE_DIRS})
|
||||
set(ImageMagick_LIBRARIES ${ImageMagick_LIBRARIES})
|
||||
|
||||
if(ImageMagick_mogrify_EXECUTABLE)
|
||||
execute_process(COMMAND ${ImageMagick_mogrify_EXECUTABLE} -version
|
||||
OUTPUT_VARIABLE imagemagick_version
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if(imagemagick_version MATCHES "^Version: ImageMagick [0-9]")
|
||||
string(REGEX REPLACE "^Version: ImageMagick ([-0-9\\.]+).*" "\\1" ImageMagick_VERSION_STRING "${imagemagick_version}")
|
||||
endif()
|
||||
unset(imagemagick_version)
|
||||
endif()
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# Standard Package Output
|
||||
#---------------------------------------------------------------------
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(ImageMagick
|
||||
REQUIRED_VARS ${ImageMagick_REQUIRED_VARS}
|
||||
VERSION_VAR ImageMagick_VERSION_STRING
|
||||
)
|
||||
# Maintain consistency with all other variables.
|
||||
set(ImageMagick_FOUND ${IMAGEMAGICK_FOUND})
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# DEPRECATED: Setting variables for backward compatibility.
|
||||
#---------------------------------------------------------------------
|
||||
set(IMAGEMAGICK_BINARY_PATH ${ImageMagick_EXECUTABLE_DIR}
|
||||
CACHE PATH "Path to the ImageMagick binary directory.")
|
||||
set(IMAGEMAGICK_CONVERT_EXECUTABLE ${ImageMagick_convert_EXECUTABLE}
|
||||
CACHE FILEPATH "Path to ImageMagick's convert executable.")
|
||||
set(IMAGEMAGICK_MOGRIFY_EXECUTABLE ${ImageMagick_mogrify_EXECUTABLE}
|
||||
CACHE FILEPATH "Path to ImageMagick's mogrify executable.")
|
||||
set(IMAGEMAGICK_IMPORT_EXECUTABLE ${ImageMagick_import_EXECUTABLE}
|
||||
CACHE FILEPATH "Path to ImageMagick's import executable.")
|
||||
set(IMAGEMAGICK_MONTAGE_EXECUTABLE ${ImageMagick_montage_EXECUTABLE}
|
||||
CACHE FILEPATH "Path to ImageMagick's montage executable.")
|
||||
set(IMAGEMAGICK_COMPOSITE_EXECUTABLE ${ImageMagick_composite_EXECUTABLE}
|
||||
CACHE FILEPATH "Path to ImageMagick's composite executable.")
|
||||
mark_as_advanced(
|
||||
IMAGEMAGICK_BINARY_PATH
|
||||
IMAGEMAGICK_CONVERT_EXECUTABLE
|
||||
IMAGEMAGICK_MOGRIFY_EXECUTABLE
|
||||
IMAGEMAGICK_IMPORT_EXECUTABLE
|
||||
IMAGEMAGICK_MONTAGE_EXECUTABLE
|
||||
IMAGEMAGICK_COMPOSITE_EXECUTABLE
|
||||
)
|
@ -14,6 +14,7 @@
|
||||
# Copyright 2011 O.S. Systems Software Ltda.
|
||||
# Copyright 2011 Otavio Salvador <otavio@ossystems.com.br>
|
||||
# Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
# Copyright 2013 Corey Clayton <can.of.tuna@gmail.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,13 +1,13 @@
|
||||
# - Find Xrender
|
||||
# Find the Xrender libraries
|
||||
# - Find XRender
|
||||
# Find the XRender libraries
|
||||
#
|
||||
# This module defines the following variables:
|
||||
# Xrender_FOUND - true if Xrender_INCLUDE_DIR & Xrender_LIBRARY are found
|
||||
# Xrender_LIBRARIES - Set when Xrender_LIBRARY is found
|
||||
# Xrender_INCLUDE_DIRS - Set when Xrender_INCLUDE_DIR is found
|
||||
# XRENDER_FOUND - true if XRENDER_INCLUDE_DIR & XRENDER_LIBRARY are found
|
||||
# XRENDER_LIBRARIES - Set when Xrender_LIBRARY is found
|
||||
# XRENDER_INCLUDE_DIRS - Set when Xrender_INCLUDE_DIR is found
|
||||
#
|
||||
# Xrender_INCLUDE_DIR - where to find Xrendernput2.h, etc.
|
||||
# Xrender_LIBRARY - the Xrender library
|
||||
# XRENDER_INCLUDE_DIR - where to find Xrender.h, etc.
|
||||
# XRENDER_LIBRARY - the Xrender library
|
||||
#
|
||||
|
||||
#=============================================================================
|
||||
@ -36,9 +36,10 @@ include(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Xrender DEFAULT_MSG XRENDER_LIBRARY XRENDER_INCLUDE_DIR)
|
||||
|
||||
if(XRENDER_FOUND)
|
||||
|
||||
set(XRENDER_LIBRARIES ${XRENDER_LIBRARY})
|
||||
set(XRENDER_INCLUDE_DIRS ${XRENDER_INCLUDE_DIR})
|
||||
|
||||
endif()
|
||||
|
||||
mark_as_advanced(XRENDER_INCLUDE_DIRS XRENDER_LIBRARIES)
|
||||
|
||||
mark_as_advanced(XRENDER_INCLUDE_DIR XRENDER_LIBRARY)
|
||||
|
@ -42,6 +42,15 @@ DEFINE_EVENT_BEGIN(ResizeWindow)
|
||||
int height;
|
||||
DEFINE_EVENT_END(ResizeWindow)
|
||||
|
||||
DEFINE_EVENT_BEGIN(PanningChange)
|
||||
int XPan;
|
||||
int YPan;
|
||||
DEFINE_EVENT_END(PanningChange)
|
||||
|
||||
DEFINE_EVENT_BEGIN(ScalingFactorChange)
|
||||
double ScalingFactor;
|
||||
DEFINE_EVENT_END(ScalingFactorChange)
|
||||
|
||||
DEFINE_EVENT_BEGIN(LocalResizeWindow)
|
||||
int width;
|
||||
int height;
|
||||
@ -52,15 +61,6 @@ DEFINE_EVENT_BEGIN(EmbedWindow)
|
||||
void* handle;
|
||||
DEFINE_EVENT_END(EmbedWindow)
|
||||
|
||||
DEFINE_EVENT_BEGIN(PanningChange)
|
||||
int XPan;
|
||||
int YPan;
|
||||
DEFINE_EVENT_END(PanningChange)
|
||||
|
||||
DEFINE_EVENT_BEGIN(ScalingFactorChange)
|
||||
double ScalingFactor;
|
||||
DEFINE_EVENT_END(ScalingFactorChange)
|
||||
|
||||
DEFINE_EVENT_BEGIN(ErrorInfo)
|
||||
UINT32 code;
|
||||
DEFINE_EVENT_END(ErrorInfo)
|
||||
|
@ -156,7 +156,6 @@ RFX_CONTEXT* rfx_context_new(void)
|
||||
ZeroMemory(context->priv, sizeof(RFX_CONTEXT_PRIV));
|
||||
|
||||
context->priv->TilePool = Queue_New(TRUE, -1, -1);
|
||||
context->priv->TileQueue = Queue_New(TRUE, -1, -1);
|
||||
|
||||
/*
|
||||
* align buffers to 16 byte boundary (needed for SSE/NEON instructions)
|
||||
@ -254,7 +253,6 @@ void rfx_context_free(RFX_CONTEXT* context)
|
||||
free(context->quants);
|
||||
|
||||
Queue_Free(context->priv->TilePool);
|
||||
Queue_Free(context->priv->TileQueue);
|
||||
|
||||
rfx_profiler_print(context);
|
||||
rfx_profiler_free(context);
|
||||
|
@ -40,7 +40,6 @@
|
||||
struct _RFX_CONTEXT_PRIV
|
||||
{
|
||||
wQueue* TilePool;
|
||||
wQueue* TileQueue;
|
||||
|
||||
BOOL UseThreads;
|
||||
DWORD MinThreadCount;
|
||||
|
@ -2331,3 +2331,4 @@ int freerdp_set_param_double(rdpSettings* settings, int id, double param)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -91,14 +91,24 @@ BOOL wf_mirror_driver_display_device_attach(wfInfo* wfi, DWORD mode)
|
||||
0, KEY_ALL_ACCESS | KEY_WOW64_64KEY, &hKey);
|
||||
|
||||
if (status != ERROR_SUCCESS)
|
||||
{
|
||||
printf("Error opening RegKey: status=%0X\n", status);
|
||||
if (status == ERROR_ACCESS_DENIED)
|
||||
printf("access denied. Do you have admin privleges?\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
dwSize = sizeof(DWORD);
|
||||
status = RegQueryValueEx(hKey, _T("Attach.ToDesktop"),
|
||||
NULL, &dwType, (BYTE*) &dwValue, &dwSize);
|
||||
|
||||
if (status != ERROR_SUCCESS)
|
||||
{
|
||||
printf("Error querying RegKey: status=%0X\n", status);
|
||||
if (status == ERROR_ACCESS_DENIED)
|
||||
printf("access denied. Do you have admin privleges?\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (dwValue ^ mode) //only if we want to change modes
|
||||
{
|
||||
@ -240,6 +250,28 @@ BOOL wf_mirror_driver_map_memory(wfInfo* wfi)
|
||||
if (wfi->driverDC == NULL)
|
||||
{
|
||||
_tprintf(_T("Could not create device driver context!\n"));
|
||||
|
||||
{
|
||||
LPVOID lpMsgBuf;
|
||||
DWORD dw = GetLastError();
|
||||
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
dw,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPTSTR) &lpMsgBuf,
|
||||
0, NULL );
|
||||
|
||||
// Display the error message and exit the process
|
||||
|
||||
_tprintf(_T("CreateDC failed on device [%s] with error %d: %s\n"), wfi->deviceName, dw, lpMsgBuf);
|
||||
|
||||
LocalFree(lpMsgBuf);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user