Merge branch 'master' of github.com:FreeRDP/FreeRDP

This commit is contained in:
Marc-André Moreau 2013-07-23 19:21:39 -04:00
commit e95e0e42ae
17 changed files with 938 additions and 215 deletions

View File

@ -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})

View File

@ -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;
}

View File

@ -44,6 +44,7 @@ extern "C" {
* Client Interface
*/
FREERDP_API int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints);
#ifdef __cplusplus

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -44,6 +44,7 @@
#ifdef WITH_XI
#include <X11/extensions/XInput2.h>
#include "xf_input.h"
#endif
#include "xf_input.h"

View File

@ -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);

View File

@ -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
View 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
)

View File

@ -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.

View File

@ -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)

View File

@ -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)

View File

@ -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);

View File

@ -40,7 +40,6 @@
struct _RFX_CONTEXT_PRIV
{
wQueue* TilePool;
wQueue* TileQueue;
BOOL UseThreads;
DWORD MinThreadCount;

View File

@ -2331,3 +2331,4 @@ int freerdp_set_param_double(rdpSettings* settings, int id, double param)
return 0;
}

View File

@ -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;
}