mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
xfreerdp-client: start trying to send multitouch events
This commit is contained in:
@@ -33,6 +33,11 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
MODULE freerdp
|
||||
MODULES freerdp-common freerdp-utils)
|
||||
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
MODULE winpr
|
||||
MODULES winpr-sysinfo)
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/stream.h>
|
||||
#include <winpr/sysinfo.h>
|
||||
#include <winpr/cmdline.h>
|
||||
|
||||
#include <freerdp/addin.h>
|
||||
@@ -35,14 +36,7 @@
|
||||
|
||||
#include "rdpei_main.h"
|
||||
|
||||
struct _RDPEI_LISTENER_CALLBACK
|
||||
{
|
||||
IWTSListenerCallback iface;
|
||||
|
||||
IWTSPlugin* plugin;
|
||||
IWTSVirtualChannelManager* channel_mgr;
|
||||
};
|
||||
typedef struct _RDPEI_LISTENER_CALLBACK RDPEI_LISTENER_CALLBACK;
|
||||
#define MAX_CONTACTS 512
|
||||
|
||||
struct _RDPEI_CHANNEL_CALLBACK
|
||||
{
|
||||
@@ -54,12 +48,28 @@ struct _RDPEI_CHANNEL_CALLBACK
|
||||
};
|
||||
typedef struct _RDPEI_CHANNEL_CALLBACK RDPEI_CHANNEL_CALLBACK;
|
||||
|
||||
struct _RDPEI_LISTENER_CALLBACK
|
||||
{
|
||||
IWTSListenerCallback iface;
|
||||
|
||||
IWTSPlugin* plugin;
|
||||
IWTSVirtualChannelManager* channel_mgr;
|
||||
RDPEI_CHANNEL_CALLBACK* channel_callback;
|
||||
};
|
||||
typedef struct _RDPEI_LISTENER_CALLBACK RDPEI_LISTENER_CALLBACK;
|
||||
|
||||
struct _RDPEI_PLUGIN
|
||||
{
|
||||
IWTSPlugin iface;
|
||||
|
||||
IWTSListener* listener;
|
||||
RDPEI_LISTENER_CALLBACK* listener_callback;
|
||||
|
||||
int version;
|
||||
UINT64 currentFrameTime;
|
||||
UINT64 previousFrameTime;
|
||||
RDPINPUT_TOUCH_FRAME frame;
|
||||
RDPINPUT_CONTACT_DATA contacts[MAX_CONTACTS];
|
||||
};
|
||||
typedef struct _RDPEI_PLUGIN RDPEI_PLUGIN;
|
||||
|
||||
@@ -164,29 +174,24 @@ int rdpei_write_touch_frame(wStream* s, RDPINPUT_TOUCH_FRAME* frame)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rdpei_send_touch_event_pdu(RDPEI_CHANNEL_CALLBACK* callback)
|
||||
int rdpei_send_touch_event_pdu(RDPEI_CHANNEL_CALLBACK* callback, RDPINPUT_TOUCH_FRAME* frame)
|
||||
{
|
||||
int status;
|
||||
wStream* s;
|
||||
UINT32 pduLength;
|
||||
UINT32 encodeTime;
|
||||
UINT16 frameCount;
|
||||
RDPINPUT_TOUCH_FRAME frame;
|
||||
RDPINPUT_CONTACT_DATA contact;
|
||||
|
||||
encodeTime = 123;
|
||||
encodeTime = 0;
|
||||
frameCount = 1;
|
||||
|
||||
frame.contactCount = 1;
|
||||
frame.contacts = &contact;
|
||||
|
||||
s = Stream_New(NULL, 512);
|
||||
Stream_Seek(s, RDPINPUT_HEADER_LENGTH);
|
||||
|
||||
rdpei_write_4byte_unsigned(s, encodeTime);
|
||||
rdpei_write_2byte_unsigned(s, frameCount);
|
||||
|
||||
rdpei_write_touch_frame(s, &frame);
|
||||
rdpei_write_touch_frame(s, frame);
|
||||
|
||||
Stream_SealLength(s);
|
||||
pduLength = Stream_Length(s);
|
||||
@@ -298,6 +303,7 @@ static int rdpei_on_new_channel_connection(IWTSListenerCallback* pListenerCallba
|
||||
callback->plugin = listener_callback->plugin;
|
||||
callback->channel_mgr = listener_callback->channel_mgr;
|
||||
callback->channel = pChannel;
|
||||
listener_callback->channel_callback = callback;
|
||||
|
||||
*ppCallback = (IWTSVirtualChannelCallback*) callback;
|
||||
|
||||
@@ -343,7 +349,53 @@ static int rdpei_plugin_terminated(IWTSPlugin* pPlugin)
|
||||
|
||||
int rdpei_get_version(RdpeiClientContext* context)
|
||||
{
|
||||
//RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle;
|
||||
RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle;
|
||||
return rdpei->version;
|
||||
}
|
||||
|
||||
int rdpei_begin_frame(RdpeiClientContext* context)
|
||||
{
|
||||
RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle;
|
||||
|
||||
rdpei->frame.contactCount = 0;
|
||||
rdpei->frame.frameOffset = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rdpei_end_frame(RdpeiClientContext* context)
|
||||
{
|
||||
RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle;
|
||||
RDPEI_CHANNEL_CALLBACK* callback = rdpei->listener_callback->channel_callback;
|
||||
|
||||
if (!rdpei->previousFrameTime && !rdpei->currentFrameTime)
|
||||
{
|
||||
rdpei->currentFrameTime = (UINT64) GetTickCount64();
|
||||
rdpei->frame.frameOffset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
rdpei->currentFrameTime = (UINT64) GetTickCount64();
|
||||
rdpei->frame.frameOffset = rdpei->currentFrameTime - rdpei->previousFrameTime;
|
||||
}
|
||||
|
||||
rdpei_send_touch_event_pdu(callback, &rdpei->frame);
|
||||
rdpei->previousFrameTime = rdpei->currentFrameTime;
|
||||
rdpei->frame.contactCount = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rdpei_add_contact(RdpeiClientContext* context, RDPINPUT_CONTACT_DATA* contact)
|
||||
{
|
||||
RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle;
|
||||
|
||||
if (rdpei->frame.contactCount < MAX_CONTACTS)
|
||||
{
|
||||
CopyMemory(&(rdpei->contacts[rdpei->frame.contactCount]), contact, sizeof(RDPINPUT_CONTACT_DATA));
|
||||
rdpei->frame.contactCount++;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -369,10 +421,18 @@ int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
|
||||
rdpei->iface.Disconnected = NULL;
|
||||
rdpei->iface.Terminated = rdpei_plugin_terminated;
|
||||
|
||||
rdpei->version = 1;
|
||||
rdpei->currentFrameTime = 0;
|
||||
rdpei->previousFrameTime = 0;
|
||||
rdpei->frame.contacts = (RDPINPUT_CONTACT_DATA*) rdpei->contacts;
|
||||
|
||||
context = (RdpeiClientContext*) malloc(sizeof(RdpeiClientContext));
|
||||
|
||||
context->handle = (void*) rdpei;
|
||||
context->GetVersion = rdpei_get_version;
|
||||
context->BeginFrame = rdpei_begin_frame;
|
||||
context->EndFrame = rdpei_end_frame;
|
||||
context->AddContact = rdpei_add_contact;
|
||||
|
||||
rdpei->iface.pInterface = (void*) context;
|
||||
|
||||
|
||||
@@ -33,41 +33,6 @@
|
||||
|
||||
#define RDPINPUT_HEADER_LENGTH 6
|
||||
|
||||
#define CONTACT_DATA_CONTACTRECT_PRESENT 0x0001
|
||||
#define CONTACT_DATA_ORIENTATION_PRESENT 0x0002
|
||||
#define CONTACT_DATA_PRESSURE_PRESENT 0x0004
|
||||
|
||||
#define CONTACT_FLAG_DOWN 0x0001
|
||||
#define CONTACT_FLAG_UPDATE 0x0002
|
||||
#define CONTACT_FLAG_UP 0x0004
|
||||
#define CONTACT_FLAG_INRANGE 0x0008
|
||||
#define CONTACT_FLAG_INCONTACT 0x0010
|
||||
#define CONTACT_FLAG_CANCELED 0x0020
|
||||
|
||||
struct _RDPINPUT_CONTACT_DATA
|
||||
{
|
||||
UINT32 contactId;
|
||||
UINT32 fieldsPresent;
|
||||
INT32 x;
|
||||
INT32 y;
|
||||
UINT32 contactFlags;
|
||||
INT32 contactRectLeft;
|
||||
INT32 contactRectTop;
|
||||
INT32 contactRectRight;
|
||||
INT32 contactRectBottom;
|
||||
UINT32 orientation;
|
||||
UINT32 pressure;
|
||||
};
|
||||
typedef struct _RDPINPUT_CONTACT_DATA RDPINPUT_CONTACT_DATA;
|
||||
|
||||
struct _RDPINPUT_TOUCH_FRAME
|
||||
{
|
||||
UINT32 contactCount;
|
||||
UINT64 frameOffset;
|
||||
RDPINPUT_CONTACT_DATA* contacts;
|
||||
};
|
||||
typedef struct _RDPINPUT_TOUCH_FRAME RDPINPUT_TOUCH_FRAME;
|
||||
|
||||
/* Protocol Version */
|
||||
|
||||
#define RDPINPUT_PROTOCOL_V1 0x00010000
|
||||
|
||||
@@ -32,6 +32,8 @@ set(${MODULE_PREFIX}_SRCS
|
||||
xf_event.h
|
||||
xf_input.c
|
||||
xf_input.h
|
||||
xf_channels.c
|
||||
xf_channels.h
|
||||
xf_cliprdr.c
|
||||
xf_cliprdr.h
|
||||
xf_monitor.c
|
||||
|
||||
46
client/X11/xf_channels.c
Normal file
46
client/X11/xf_channels.c
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* X11 Client Channels
|
||||
*
|
||||
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@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
|
||||
|
||||
#include "xf_channels.h"
|
||||
|
||||
#include "xf_interface.h"
|
||||
#include "xfreerdp.h"
|
||||
|
||||
int xf_on_channel_connected(freerdp* instance, const char* name, void* pInterface)
|
||||
{
|
||||
xfInfo* xfi = ((xfContext*) instance->context)->xfi;
|
||||
|
||||
printf("OnChannelConnected: %s\n", name);
|
||||
|
||||
if (strcmp(name, RDPEI_DVC_CHANNEL_NAME) == 0)
|
||||
{
|
||||
xfi->rdpei = (RdpeiClientContext*) pInterface;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xf_on_channel_disconnected(freerdp* instance, const char* name, void* pInterface)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
30
client/X11/xf_channels.h
Normal file
30
client/X11/xf_channels.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* X11 Client Channels
|
||||
*
|
||||
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@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_CHANNELS_H
|
||||
#define __XF_CHANNELS_H
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/client/channels.h>
|
||||
#include <freerdp/client/rdpei.h>
|
||||
|
||||
int xf_on_channel_connected(freerdp* instance, const char* name, void* pInterface);
|
||||
int xf_on_channel_disconnected(freerdp* instance, const char* name, void* pInterface);
|
||||
|
||||
#endif
|
||||
@@ -94,13 +94,13 @@ int xf_input_init(xfInfo* xfi, Window window)
|
||||
for (j = 0; j < dev->num_classes; j++)
|
||||
{
|
||||
XIAnyClassInfo* class = dev->classes[j];
|
||||
//XITouchClassInfo* t = (XITouchClassInfo*) class;
|
||||
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);
|
||||
printf("%s %s touch device, supporting %d touches.\n",
|
||||
dev->name, (t->mode == XIDirectTouch) ? "direct" : "dependent", t->num_touches);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,7 +257,7 @@ void xf_input_touch_end(xfInfo* xfi, XIDeviceEvent* event)
|
||||
//contacts[i].pos_y = (int)event->event_y;
|
||||
|
||||
active_contacts--;
|
||||
break;
|
||||
break;printf("TouchBegin\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -301,18 +301,50 @@ int xf_input_handle_event_local(xfInfo* xfi, XEvent* event)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xf_input_touch_begin_remote(xfInfo* xfi, XIDeviceEvent* event)
|
||||
char* xf_input_touch_state_string(DWORD flags)
|
||||
{
|
||||
return 0;
|
||||
if (flags & CONTACT_FLAG_DOWN)
|
||||
return "TouchBegin";
|
||||
else if (flags & CONTACT_FLAG_UPDATE)
|
||||
return "TouchUpdate";
|
||||
else if (flags & CONTACT_FLAG_UP)
|
||||
return "TouchEnd";
|
||||
else
|
||||
return "TouchUnknown";
|
||||
}
|
||||
|
||||
int xf_input_touch_update_remote(xfInfo* xfi, XIDeviceEvent* event)
|
||||
int xf_input_touch_remote(xfInfo* xfi, XIDeviceEvent* event, DWORD flags)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int x, y;
|
||||
int touchId;
|
||||
RDPINPUT_CONTACT_DATA contact;
|
||||
RdpeiClientContext* rdpei = xfi->rdpei;
|
||||
|
||||
if (!rdpei)
|
||||
return 0;
|
||||
|
||||
touchId = event->detail;
|
||||
x = (int) event->event_x;
|
||||
y = (int) event->event_y;
|
||||
ZeroMemory(&contact, sizeof(RDPINPUT_CONTACT_DATA));
|
||||
|
||||
if ((x < 0) || (y < 0))
|
||||
return 0;
|
||||
|
||||
printf("%s: id: %d x: %d y: %d\n",
|
||||
xf_input_touch_state_string(flags),
|
||||
touchId, x, y);
|
||||
|
||||
contact.contactId = touchId % 0xFF;
|
||||
contact.fieldsPresent = 0;
|
||||
contact.x = x;
|
||||
contact.y = y;
|
||||
contact.contactFlags = flags;
|
||||
|
||||
rdpei->BeginFrame(rdpei);
|
||||
rdpei->AddContact(rdpei, &contact);
|
||||
rdpei->EndFrame(rdpei);
|
||||
|
||||
int xf_input_touch_end_remote(xfInfo* xfi, XIDeviceEvent* event)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -327,15 +359,15 @@ int xf_input_handle_event_remote(xfInfo* xfi, XEvent* event)
|
||||
switch (cookie->evtype)
|
||||
{
|
||||
case XI_TouchBegin:
|
||||
xf_input_touch_begin_remote(xfi, cookie->data);
|
||||
xf_input_touch_remote(xfi, cookie->data, CONTACT_FLAG_DOWN);
|
||||
break;
|
||||
|
||||
case XI_TouchUpdate:
|
||||
xf_input_touch_update_remote(xfi, cookie->data);
|
||||
xf_input_touch_remote(xfi, cookie->data, CONTACT_FLAG_UPDATE);
|
||||
break;
|
||||
|
||||
case XI_TouchEnd:
|
||||
xf_input_touch_end_remote(xfi, cookie->data);
|
||||
xf_input_touch_remote(xfi, cookie->data, CONTACT_FLAG_UP);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -83,6 +83,7 @@
|
||||
#include "xf_monitor.h"
|
||||
#include "xf_graphics.h"
|
||||
#include "xf_keyboard.h"
|
||||
#include "xf_channels.h"
|
||||
|
||||
#include "xfreerdp.h"
|
||||
|
||||
@@ -653,17 +654,6 @@ int _xf_error_handler(Display* d, XErrorEvent* ev)
|
||||
return xf_error_handler(d, ev);
|
||||
}
|
||||
|
||||
int xf_on_channel_connected(freerdp* instance, const char* name, void* pInterface)
|
||||
{
|
||||
//printf("OnChannelConnected: %s\n", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xf_on_channel_disconnected(freerdp* instance, const char* name, void* pInterface)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback given to freerdp_connect() to process the pre-connect operations.
|
||||
* It will fill the rdp_freerdp structure (instance) with the appropriate options to use for the connection.
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include "xf_window.h"
|
||||
#include "xf_monitor.h"
|
||||
#include "xf_channels.h"
|
||||
|
||||
struct xf_WorkArea
|
||||
{
|
||||
@@ -162,6 +163,9 @@ struct xf_info
|
||||
Atom WM_STATE;
|
||||
Atom WM_PROTOCOLS;
|
||||
Atom WM_DELETE_WINDOW;
|
||||
|
||||
/* Channels */
|
||||
RdpeiClientContext* rdpei;
|
||||
};
|
||||
|
||||
void xf_create_window(xfInfo* xfi);
|
||||
|
||||
@@ -20,6 +20,41 @@
|
||||
#ifndef FREERDP_CHANNEL_CLIENT_RDPEI_H
|
||||
#define FREERDP_CHANNEL_CLIENT_RDPEI_H
|
||||
|
||||
#define CONTACT_DATA_CONTACTRECT_PRESENT 0x0001
|
||||
#define CONTACT_DATA_ORIENTATION_PRESENT 0x0002
|
||||
#define CONTACT_DATA_PRESSURE_PRESENT 0x0004
|
||||
|
||||
#define CONTACT_FLAG_DOWN 0x0001
|
||||
#define CONTACT_FLAG_UPDATE 0x0002
|
||||
#define CONTACT_FLAG_UP 0x0004
|
||||
#define CONTACT_FLAG_INRANGE 0x0008
|
||||
#define CONTACT_FLAG_INCONTACT 0x0010
|
||||
#define CONTACT_FLAG_CANCELED 0x0020
|
||||
|
||||
struct _RDPINPUT_CONTACT_DATA
|
||||
{
|
||||
UINT32 contactId;
|
||||
UINT32 fieldsPresent;
|
||||
INT32 x;
|
||||
INT32 y;
|
||||
UINT32 contactFlags;
|
||||
INT32 contactRectLeft;
|
||||
INT32 contactRectTop;
|
||||
INT32 contactRectRight;
|
||||
INT32 contactRectBottom;
|
||||
UINT32 orientation;
|
||||
UINT32 pressure;
|
||||
};
|
||||
typedef struct _RDPINPUT_CONTACT_DATA RDPINPUT_CONTACT_DATA;
|
||||
|
||||
struct _RDPINPUT_TOUCH_FRAME
|
||||
{
|
||||
UINT32 contactCount;
|
||||
UINT64 frameOffset;
|
||||
RDPINPUT_CONTACT_DATA* contacts;
|
||||
};
|
||||
typedef struct _RDPINPUT_TOUCH_FRAME RDPINPUT_TOUCH_FRAME;
|
||||
|
||||
/**
|
||||
* Client Interface
|
||||
*/
|
||||
@@ -29,6 +64,9 @@
|
||||
typedef struct _rdpei_client_context RdpeiClientContext;
|
||||
|
||||
typedef int (*pcRdpeiGetVersion)(RdpeiClientContext* context);
|
||||
typedef int (*pcRdpeiBeginFrame)(RdpeiClientContext* context);
|
||||
typedef int (*pcRdpeiEndFrame)(RdpeiClientContext* context);
|
||||
typedef int (*pcRdpeiAddContact)(RdpeiClientContext* context, RDPINPUT_CONTACT_DATA* contact);
|
||||
|
||||
struct _rdpei_client_context
|
||||
{
|
||||
@@ -36,6 +74,9 @@ struct _rdpei_client_context
|
||||
void* custom;
|
||||
|
||||
pcRdpeiGetVersion GetVersion;
|
||||
pcRdpeiBeginFrame BeginFrame;
|
||||
pcRdpeiEndFrame EndFrame;
|
||||
pcRdpeiAddContact AddContact;
|
||||
};
|
||||
|
||||
#endif /* FREERDP_CHANNEL_CLIENT_RDPEI_H */
|
||||
|
||||
Reference in New Issue
Block a user