xfreerdp: integrate corey's multitouch code
This commit is contained in:
parent
1b28ef5976
commit
91a55ae741
@ -30,6 +30,8 @@ set(${MODULE_PREFIX}_SRCS
|
||||
xf_tsmf.h
|
||||
xf_event.c
|
||||
xf_event.h
|
||||
xf_input.c
|
||||
xf_input.h
|
||||
xf_cliprdr.c
|
||||
xf_cliprdr.h
|
||||
xf_monitor.c
|
||||
@ -99,12 +101,17 @@ set(XI_FEATURE_TYPE "RECOMMENDED")
|
||||
set(XI_FEATURE_PURPOSE "input")
|
||||
set(XI_FEATURE_DESCRIPTION "X11 input extension")
|
||||
|
||||
set(XRENDER_FEATURE_TYPE "RECOMMENDED")
|
||||
set(XRENDER_FEATURE_PURPOSE "rendering")
|
||||
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})
|
||||
find_feature(Xext ${XEXT_FEATURE_TYPE} ${XEXT_FEATURE_PURPOSE} ${XEXT_FEATURE_DESCRIPTION})
|
||||
find_feature(Xcursor ${XCURSOR_FEATURE_TYPE} ${XCURSOR_FEATURE_PURPOSE} ${XCURSOR_FEATURE_DESCRIPTION})
|
||||
find_feature(Xv ${XV_FEATURE_TYPE} ${XV_FEATURE_PURPOSE} ${XV_FEATURE_DESCRIPTION})
|
||||
find_feature(Xi ${XI_FEATURE_TYPE} ${XI_FEATURE_PURPOSE} ${XI_FEATURE_DESCRIPTION})
|
||||
find_feature(Xrender ${XRENDER_FEATURE_TYPE} ${XRENDER_FEATURE_PURPOSE} ${XRENDER_FEATURE_DESCRIPTION})
|
||||
|
||||
if(WITH_XINERAMA)
|
||||
add_definitions(-DWITH_XINERAMA)
|
||||
@ -136,6 +143,12 @@ if(WITH_XI)
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XI_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if(WITH_XRENDER)
|
||||
add_definitions(-DWITH_XRENDER)
|
||||
include_directories(${XRENDER_INCLUDE_DIRS})
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XRENDER_LIBRARIES})
|
||||
endif()
|
||||
|
||||
include_directories(${CMAKE_SOURCE_DIR}/resources)
|
||||
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp-client)
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "xf_rail.h"
|
||||
#include "xf_window.h"
|
||||
#include "xf_cliprdr.h"
|
||||
#include "xf_input.h"
|
||||
|
||||
#include "xf_event.h"
|
||||
|
||||
@ -95,7 +96,15 @@ static BOOL xf_event_Expose(xfInfo* xfi, XEvent* event, BOOL app)
|
||||
|
||||
if (!app)
|
||||
{
|
||||
XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, x, y, w, h, x, y);
|
||||
if (xfi->scale != 1.0)
|
||||
{
|
||||
xf_draw_screen_scaled(xfi);
|
||||
}
|
||||
else
|
||||
{
|
||||
XCopyArea(xfi->display, xfi->primary,
|
||||
xfi->window->handle, xfi->gc, x, y, w, h, x, y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -151,6 +160,13 @@ static BOOL xf_event_MotionNotify(xfInfo* xfi, XEvent* event, BOOL app)
|
||||
x, y, &x, &y, &childWindow);
|
||||
}
|
||||
|
||||
if (xfi->scale != 1.0)
|
||||
{
|
||||
/* Take scaling in to consideration */
|
||||
x = (int) (x * (1.0 / xfi->scale));
|
||||
y = (int) (y * (1.0 / xfi->scale));
|
||||
}
|
||||
|
||||
input->MouseEvent(input, PTR_FLAGS_MOVE, x, y);
|
||||
|
||||
if (xfi->fullscreen)
|
||||
@ -254,6 +270,13 @@ static BOOL xf_event_ButtonPress(xfInfo* xfi, XEvent* event, BOOL app)
|
||||
x, y, &x, &y, &childWindow);
|
||||
}
|
||||
|
||||
if (xfi->scale != 1.0)
|
||||
{
|
||||
/* Take scaling in to consideration */
|
||||
x = (int) (x * (1.0 / xfi->scale));
|
||||
y = (int) (y * (1.0 / xfi->scale));
|
||||
}
|
||||
|
||||
if (extended)
|
||||
input->ExtendedMouseEvent(input, flags, x, y);
|
||||
else
|
||||
@ -337,6 +360,13 @@ static BOOL xf_event_ButtonRelease(xfInfo* xfi, XEvent* event, BOOL app)
|
||||
x, y, &x, &y, &childWindow);
|
||||
}
|
||||
|
||||
if (xfi->scale != 1.0)
|
||||
{
|
||||
/* Take scaling in to consideration */
|
||||
x = (int) (x * (1.0 / xfi->scale));
|
||||
y = (int) (y * (1.0 / xfi->scale));
|
||||
}
|
||||
|
||||
if (extended)
|
||||
input->ExtendedMouseEvent(input, flags, x, y);
|
||||
else
|
||||
@ -523,6 +553,15 @@ static BOOL xf_event_ConfigureNotify(xfInfo* xfi, XEvent* event, BOOL app)
|
||||
rdpWindow* window;
|
||||
rdpRail* rail = ((rdpContext*) xfi->context)->rail;
|
||||
|
||||
if (xfi->width != event->xconfigure.width)
|
||||
{
|
||||
xfi->scale = (double) event->xconfigure.width / (double) xfi->originalWidth;
|
||||
xfi->currentWidth = event->xconfigure.width;
|
||||
xfi->currentHeight = event->xconfigure.width;
|
||||
|
||||
xf_draw_screen_scaled(xfi);
|
||||
}
|
||||
|
||||
window = window_list_get_by_extra_id(rail->list, (void*) event->xconfigure.window);
|
||||
|
||||
if (window != NULL)
|
||||
@ -977,6 +1016,8 @@ BOOL xf_event_process(freerdp* instance, XEvent* event)
|
||||
break;
|
||||
}
|
||||
|
||||
xf_input_handle_event(xfi, event);
|
||||
|
||||
XSync(xfi->display, FALSE);
|
||||
|
||||
return status;
|
||||
|
308
client/X11/xf_input.c
Normal file
308
client/X11/xf_input.c
Normal file
@ -0,0 +1,308 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* X11 Input
|
||||
*
|
||||
* 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_XI
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "xf_input.h"
|
||||
|
||||
#ifdef WITH_XI
|
||||
|
||||
#define MAX_CONTACTS 2
|
||||
|
||||
typedef struct touch_contact
|
||||
{
|
||||
int id;
|
||||
int count;
|
||||
double pos_x;
|
||||
double pos_y;
|
||||
double last_x;
|
||||
double last_y;
|
||||
|
||||
} touchContact;
|
||||
|
||||
touchContact contacts[MAX_CONTACTS];
|
||||
|
||||
int active_contacts;
|
||||
XIDeviceEvent lastEvent;
|
||||
double firstDist = -1.0;
|
||||
double lastDist;
|
||||
double z_vector;
|
||||
int xinput_opcode;
|
||||
int scale_cnt;
|
||||
|
||||
int xf_input_init(xfInfo* xfi, Window window)
|
||||
{
|
||||
int i, j;
|
||||
int ndevices;
|
||||
int major = 2;
|
||||
int minor = 2;
|
||||
Status xstatus;
|
||||
XIEventMask evmask;
|
||||
XIDeviceInfo* info;
|
||||
int opcode, event, error;
|
||||
unsigned char mask[XIMaskLen(XI_LASTEVENT)];
|
||||
|
||||
active_contacts = 0;
|
||||
ZeroMemory(contacts, sizeof(touchContact) * MAX_CONTACTS);
|
||||
|
||||
if (!XQueryExtension(xfi->display, "XInputExtension", &opcode, &event, &error))
|
||||
{
|
||||
printf("XInput extension not available.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
xfi->XInputOpcode = opcode;
|
||||
|
||||
XIQueryVersion(xfi->display, &major, &minor);
|
||||
|
||||
if (major * 1000 + minor < 2002)
|
||||
{
|
||||
printf("Server does not support XI 2.2\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
info = XIQueryDevice(xfi->display, XIAllDevices, &ndevices);
|
||||
|
||||
for (i = 0; i < ndevices; i++)
|
||||
{
|
||||
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)
|
||||
continue;
|
||||
|
||||
//printf("%s %s touch device, supporting %d touches.\n",
|
||||
// dev->name, (t->mode == XIDirectTouch) ? "direct" : "dependent", t->num_touches);
|
||||
}
|
||||
}
|
||||
|
||||
evmask.mask = mask;
|
||||
evmask.mask_len = sizeof(mask);
|
||||
ZeroMemory(mask, sizeof(mask));
|
||||
evmask.deviceid = XIAllDevices;
|
||||
|
||||
XISetMask(mask, XI_TouchBegin);
|
||||
XISetMask(mask, XI_TouchUpdate);
|
||||
XISetMask(mask, XI_TouchEnd);
|
||||
|
||||
xstatus = XISelectEvents(xfi->display, window, &evmask, 1);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
BOOL xf_input_is_duplicate(XIDeviceEvent* event)
|
||||
{
|
||||
if ( (lastEvent.time == event->time) &&
|
||||
(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)
|
||||
{
|
||||
lastEvent.time = event->time;
|
||||
lastEvent.detail = event->detail;
|
||||
lastEvent.event_x = event->event_x;
|
||||
lastEvent.event_y = event->event_y;
|
||||
}
|
||||
|
||||
void xf_input_detect_pinch(xfInfo* xfi)
|
||||
{
|
||||
double dist;
|
||||
double zoom;
|
||||
double delta;
|
||||
|
||||
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));
|
||||
|
||||
/* if this is the first 2pt touch */
|
||||
if (firstDist <= 0)
|
||||
{
|
||||
firstDist = dist;
|
||||
lastDist = firstDist;
|
||||
scale_cnt = 0;
|
||||
z_vector = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
delta = lastDist - dist;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
xfi->scale -= 0.05;
|
||||
|
||||
if (xfi->scale < 0.5)
|
||||
xfi->scale = 0.5;
|
||||
|
||||
XResizeWindow(xfi->display, xfi->window->handle, xfi->originalWidth * xfi->scale, xfi->originalHeight * xfi->scale);
|
||||
IFCALL(xfi->client->OnResizeWindow, xfi->instance, xfi->originalWidth * xfi->scale, xfi->originalHeight * xfi->scale);
|
||||
|
||||
z_vector = 0;
|
||||
}
|
||||
|
||||
if (z_vector < -10)
|
||||
{
|
||||
xfi->scale += 0.05;
|
||||
|
||||
if (xfi->scale > 1.5)
|
||||
xfi->scale = 1.5;
|
||||
|
||||
XResizeWindow(xfi->display, xfi->window->handle, xfi->originalWidth * xfi->scale, xfi->originalHeight * xfi->scale);
|
||||
IFCALL(xfi->client->OnResizeWindow, xfi->instance, xfi->originalWidth * xfi->scale, xfi->originalHeight * xfi->scale);
|
||||
|
||||
z_vector = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int xf_input_handle_event(xfInfo* xfi, XEvent* event)
|
||||
{
|
||||
#ifdef WITH_XI
|
||||
XGenericEventCookie* cookie = &event->xcookie;
|
||||
|
||||
XGetEventData(xfi->display, cookie);
|
||||
|
||||
if ((cookie->type == GenericEvent) && (cookie->extension == xfi->XInputOpcode))
|
||||
{
|
||||
switch(cookie->evtype)
|
||||
{
|
||||
case XI_TouchBegin:
|
||||
if (xf_input_is_duplicate(cookie->data) == FALSE)
|
||||
xf_input_touch_begin(xfi, cookie->data);
|
||||
xf_input_save_last_event(cookie->data);
|
||||
break;
|
||||
|
||||
case XI_TouchUpdate:
|
||||
if (xf_input_is_duplicate(cookie->data) == FALSE)
|
||||
xf_input_touch_update(xfi, cookie->data);
|
||||
xf_input_save_last_event(cookie->data);
|
||||
break;
|
||||
|
||||
case XI_TouchEnd:
|
||||
if (xf_input_is_duplicate(cookie->data) == FALSE)
|
||||
xf_input_touch_end(xfi, cookie->data);
|
||||
xf_input_save_last_event(cookie->data);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("unhandled xi type= %d\n", cookie->evtype);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
XFreeEventData(xfi->display,cookie);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef WITH_XI
|
||||
void xf_input_touch_begin(xfInfo* xfi, XIDeviceEvent* event)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_CONTACTS; i++)
|
||||
{
|
||||
if (contacts[i].id == 0)
|
||||
{
|
||||
contacts[i].id = event->detail;
|
||||
contacts[i].count = 1;
|
||||
contacts[i].pos_x = event->event_x;
|
||||
contacts[i].pos_y = event->event_y;
|
||||
|
||||
active_contacts++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void xf_input_touch_update(xfInfo* xfi, XIDeviceEvent* event)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_CONTACTS; i++)
|
||||
{
|
||||
if (contacts[i].id == event->detail)
|
||||
{
|
||||
contacts[i].count++;
|
||||
contacts[i].last_x = contacts[i].pos_x;
|
||||
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(xfi);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void xf_input_touch_end(xfInfo* xfi, XIDeviceEvent* event)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_CONTACTS; i++)
|
||||
{
|
||||
if (contacts[i].id == event->detail)
|
||||
{
|
||||
contacts[i].id = 0;
|
||||
contacts[i].count = 0;
|
||||
//contacts[i].pos_x = (int)event->event_x;
|
||||
//contacts[i].pos_y = (int)event->event_y;
|
||||
|
||||
active_contacts--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
41
client/X11/xf_input.h
Normal file
41
client/X11/xf_input.h
Normal file
@ -0,0 +1,41 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* X11 Input
|
||||
*
|
||||
* 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __XF_INPUT_H
|
||||
#define __XF_INPUT_H
|
||||
|
||||
#include "xf_interface.h"
|
||||
#include "xfreerdp.h"
|
||||
|
||||
#ifdef WITH_XI
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#endif
|
||||
|
||||
int xf_input_init(xfInfo* xfi, Window win);
|
||||
int xf_input_handle_event(xfInfo* xfi, XEvent* event);
|
||||
|
||||
#ifdef WITH_XI
|
||||
|
||||
void xf_input_touch_begin(xfInfo* xfi, XIDeviceEvent* event);
|
||||
void xf_input_touch_update(xfInfo* xfi, XIDeviceEvent* event);
|
||||
void xf_input_touch_end(xfInfo* xfi, XIDeviceEvent* event);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
@ -32,6 +32,14 @@
|
||||
#include <X11/extensions/Xinerama.h>
|
||||
#endif
|
||||
|
||||
#ifdef WITH_XI
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#endif
|
||||
|
||||
#ifdef WITH_XRENDER
|
||||
#include <X11/extensions/Xrender.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -79,6 +87,35 @@
|
||||
static long xv_port = 0;
|
||||
static const size_t password_size = 512;
|
||||
|
||||
void xf_draw_screen_scaled(xfInfo* xfi)
|
||||
{
|
||||
XTransform transform;
|
||||
Picture windowPicture;
|
||||
Picture primaryPicture;
|
||||
XRenderPictureAttributes pa;
|
||||
XRenderPictFormat* picFormat;
|
||||
|
||||
picFormat = XRenderFindStandardFormat(xfi->display, PictStandardRGB24);
|
||||
pa.subwindow_mode = IncludeInferiors;
|
||||
primaryPicture = XRenderCreatePicture(xfi->display, xfi->primary, picFormat, CPSubwindowMode, &pa);
|
||||
windowPicture = XRenderCreatePicture(xfi->display, xfi->window->handle, picFormat, CPSubwindowMode, &pa);
|
||||
|
||||
transform.matrix[0][0] = XDoubleToFixed(1);
|
||||
transform.matrix[0][1] = XDoubleToFixed(0);
|
||||
transform.matrix[0][2] = XDoubleToFixed(0);
|
||||
|
||||
transform.matrix[1][0] = XDoubleToFixed(0);
|
||||
transform.matrix[1][1] = XDoubleToFixed(1);
|
||||
transform.matrix[1][2] = XDoubleToFixed(0);
|
||||
|
||||
transform.matrix[2][0] = XDoubleToFixed(0);
|
||||
transform.matrix[2][1] = XDoubleToFixed(0);
|
||||
transform.matrix[2][2] = XDoubleToFixed(xfi->scale);
|
||||
|
||||
XRenderSetPictureTransform(xfi->display, primaryPicture, &transform);
|
||||
XRenderComposite(xfi->display, PictOpSrc, primaryPicture, 0, windowPicture, 0, 0, 0, 0, 0, 0, xfi->currentWidth, xfi->currentHeight);
|
||||
}
|
||||
|
||||
void xf_context_new(freerdp* instance, rdpContext* context)
|
||||
{
|
||||
context->channels = freerdp_channels_new();
|
||||
@ -121,7 +158,15 @@ void xf_sw_end_paint(rdpContext* context)
|
||||
xf_lock_x11(xfi, FALSE);
|
||||
|
||||
XPutImage(xfi->display, xfi->primary, xfi->gc, xfi->image, x, y, x, y, w, h);
|
||||
XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, x, y, w, h, x, y);
|
||||
|
||||
if (xfi->scale != 1.0)
|
||||
{
|
||||
xf_draw_screen_scaled(xfi);
|
||||
}
|
||||
else
|
||||
{
|
||||
XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, x, y, w, h, x, y);
|
||||
}
|
||||
|
||||
xf_unlock_x11(xfi, FALSE);
|
||||
}
|
||||
@ -147,7 +192,15 @@ void xf_sw_end_paint(rdpContext* context)
|
||||
h = cinvalid[i].h;
|
||||
|
||||
XPutImage(xfi->display, xfi->primary, xfi->gc, xfi->image, x, y, x, y, w, h);
|
||||
XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, x, y, w, h, x, y);
|
||||
|
||||
if (xfi->scale != 1.0)
|
||||
{
|
||||
xf_draw_screen_scaled(xfi);
|
||||
}
|
||||
else
|
||||
{
|
||||
XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, x, y, w, h, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
XFlush(xfi->display);
|
||||
@ -231,7 +284,14 @@ void xf_hw_end_paint(rdpContext* context)
|
||||
|
||||
xf_lock_x11(xfi, FALSE);
|
||||
|
||||
XCopyArea(xfi->display, xfi->primary, xfi->drawable, xfi->gc, x, y, w, h, x, y);
|
||||
if (xfi->scale != 1.0)
|
||||
{
|
||||
xf_draw_screen_scaled(xfi);
|
||||
}
|
||||
else
|
||||
{
|
||||
XCopyArea(xfi->display, xfi->primary, xfi->drawable, xfi->gc, x, y, w, h, x, y);
|
||||
}
|
||||
|
||||
xf_unlock_x11(xfi, FALSE);
|
||||
}
|
||||
@ -256,7 +316,14 @@ void xf_hw_end_paint(rdpContext* context)
|
||||
w = cinvalid[i].w;
|
||||
h = cinvalid[i].h;
|
||||
|
||||
XCopyArea(xfi->display, xfi->primary, xfi->drawable, xfi->gc, x, y, w, h, x, y);
|
||||
if (xfi->scale != 1.0)
|
||||
{
|
||||
xf_draw_screen_scaled(xfi);
|
||||
}
|
||||
else
|
||||
{
|
||||
XCopyArea(xfi->display, xfi->primary, xfi->drawable, xfi->gc, x, y, w, h, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
XFlush(xfi->display);
|
||||
@ -768,6 +835,12 @@ BOOL xf_post_connect(freerdp* instance)
|
||||
}
|
||||
}
|
||||
|
||||
xfi->originalWidth = settings->DesktopWidth;
|
||||
xfi->originalHeight = settings->DesktopHeight;
|
||||
xfi->currentWidth = xfi->originalWidth;
|
||||
xfi->currentHeight = xfi->originalWidth;
|
||||
xfi->scale = 1.0;
|
||||
|
||||
xfi->width = settings->DesktopWidth;
|
||||
xfi->height = settings->DesktopHeight;
|
||||
|
||||
@ -1481,6 +1554,11 @@ rdpClient* freerdp_client_get_interface(cfInfo* cfi)
|
||||
return cfi->client;
|
||||
}
|
||||
|
||||
double freerdp_client_get_scale(xfInfo* xfi)
|
||||
{
|
||||
return xfi->scale;
|
||||
}
|
||||
|
||||
xfInfo* freerdp_client_new(int argc, char** argv)
|
||||
{
|
||||
int index;
|
||||
|
@ -55,6 +55,7 @@ FREERDP_API int freerdp_client_stop(cfInfo* cfi);
|
||||
FREERDP_API freerdp* freerdp_client_get_instance(cfInfo* cfi);
|
||||
FREERDP_API HANDLE freerdp_client_get_thread(cfInfo* cfi);
|
||||
FREERDP_API rdpClient* freerdp_client_get_interface(cfInfo* cfi);
|
||||
FREERDP_API double freerdp_client_get_scale(xfInfo* xfi);
|
||||
|
||||
FREERDP_API cfInfo* freerdp_client_new(int argc, char** argv);
|
||||
FREERDP_API void freerdp_client_free(cfInfo* cfi);
|
||||
|
@ -44,6 +44,7 @@
|
||||
|
||||
#ifdef WITH_XI
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#include "xf_input.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_DEBUG_X11
|
||||
@ -325,73 +326,6 @@ static void xf_SetWindowPID(xfInfo* xfi, xfWindow* window, pid_t pid)
|
||||
32, PropModeReplace, (unsigned char *)&pid, 1);
|
||||
}
|
||||
|
||||
int xf_input_init(xfInfo* xfi, Window window)
|
||||
{
|
||||
int i, j;
|
||||
int ndevices;
|
||||
int major = 2;
|
||||
int minor = 2;
|
||||
Status xstatus;
|
||||
XIEventMask evmask;
|
||||
XIDeviceInfo* info;
|
||||
int opcode, event, error;
|
||||
XIGrabModifiers mods = { 1 };
|
||||
unsigned char mask[XIMaskLen(XI_LASTEVENT)];
|
||||
|
||||
if (!XQueryExtension(xfi->display, "XInputExtension", &opcode, &event, &error))
|
||||
{
|
||||
printf("XInput extension not available.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
XIQueryVersion(xfi->display, &major, &minor);
|
||||
|
||||
if (major * 1000 + minor < 2002)
|
||||
{
|
||||
printf("Server does not support XI 2.2\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
info = XIQueryDevice(xfi->display, XIAllDevices, &ndevices);
|
||||
|
||||
for (i = 0; i < ndevices; i++)
|
||||
{
|
||||
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)
|
||||
continue;
|
||||
|
||||
printf("%s %s touch device, supporting %d touches.\n",
|
||||
dev->name, (t->mode == XIDirectTouch) ? "direct" : "dependent", t->num_touches);
|
||||
}
|
||||
}
|
||||
|
||||
evmask.mask = mask;
|
||||
evmask.mask_len = sizeof(mask);
|
||||
ZeroMemory(mask, sizeof(mask));
|
||||
evmask.deviceid = XIAllDevices;
|
||||
|
||||
XISetMask(mask, XI_TouchBegin);
|
||||
XISetMask(mask, XI_TouchUpdate);
|
||||
XISetMask(mask, XI_TouchEnd);
|
||||
|
||||
xstatus = XISelectEvents(xfi->display, window, &evmask, 1);
|
||||
//XIClearMask(mask, XI_TouchOwnership);
|
||||
|
||||
mods.modifiers = XIAnyModifier;
|
||||
|
||||
//XIGrabTouchBegin(xfi->display, XIAllMasterDevices, window, XINoOwnerEvents, &evmask, 1, &mods);
|
||||
|
||||
XSync(xfi->display, False);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
xfWindow* xf_CreateDesktopWindow(xfInfo* xfi, char* name, int width, int height, BOOL decorations)
|
||||
{
|
||||
xfWindow* window;
|
||||
|
@ -114,6 +114,13 @@ struct xf_info
|
||||
UINT16 frame_x2;
|
||||
UINT16 frame_y2;
|
||||
|
||||
double scale;
|
||||
int originalWidth;
|
||||
int originalHeight;
|
||||
int currentWidth;
|
||||
int currentHeight;
|
||||
int XInputOpcode;
|
||||
|
||||
BOOL focused;
|
||||
BOOL mouse_active;
|
||||
BOOL suppress_output;
|
||||
@ -204,6 +211,8 @@ enum XF_EXIT_CODE
|
||||
void xf_lock_x11(xfInfo* xfi, BOOL display);
|
||||
void xf_unlock_x11(xfInfo* xfi, BOOL display);
|
||||
|
||||
void xf_draw_screen_scaled(xfInfo* xfi);
|
||||
|
||||
DWORD xf_exit_code_from_disconnect_reason(DWORD reason);
|
||||
|
||||
#endif /* __XFREERDP_H */
|
||||
|
Loading…
Reference in New Issue
Block a user