channels/rdpei: fix long press (multitouch right-click)
This commit is contained in:
parent
404f66820b
commit
3317592ecb
@ -26,9 +26,12 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <winpr/crt.h>
|
#include <winpr/crt.h>
|
||||||
|
#include <winpr/synch.h>
|
||||||
|
#include <winpr/thread.h>
|
||||||
#include <winpr/stream.h>
|
#include <winpr/stream.h>
|
||||||
#include <winpr/sysinfo.h>
|
#include <winpr/sysinfo.h>
|
||||||
#include <winpr/cmdline.h>
|
#include <winpr/cmdline.h>
|
||||||
|
#include <winpr/collections.h>
|
||||||
|
|
||||||
#include <freerdp/addin.h>
|
#include <freerdp/addin.h>
|
||||||
|
|
||||||
@ -92,9 +95,15 @@ struct _RDPEI_PLUGIN
|
|||||||
RDPINPUT_TOUCH_FRAME frame;
|
RDPINPUT_TOUCH_FRAME frame;
|
||||||
RDPINPUT_CONTACT_DATA contacts[MAX_CONTACTS];
|
RDPINPUT_CONTACT_DATA contacts[MAX_CONTACTS];
|
||||||
RDPINPUT_CONTACT_POINT* contactPoints;
|
RDPINPUT_CONTACT_POINT* contactPoints;
|
||||||
|
|
||||||
|
HANDLE mutex;
|
||||||
|
HANDLE event;
|
||||||
|
HANDLE thread;
|
||||||
};
|
};
|
||||||
typedef struct _RDPEI_PLUGIN RDPEI_PLUGIN;
|
typedef struct _RDPEI_PLUGIN RDPEI_PLUGIN;
|
||||||
|
|
||||||
|
int rdpei_send_frame(RdpeiClientContext* context);
|
||||||
|
|
||||||
const char* RDPEI_EVENTID_STRINGS[] =
|
const char* RDPEI_EVENTID_STRINGS[] =
|
||||||
{
|
{
|
||||||
"",
|
"",
|
||||||
@ -106,6 +115,67 @@ const char* RDPEI_EVENTID_STRINGS[] =
|
|||||||
"EVENTID_DISMISS_HOVERING_CONTACT"
|
"EVENTID_DISMISS_HOVERING_CONTACT"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int rdpei_add_frame(RdpeiClientContext* context)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
RDPINPUT_CONTACT_DATA* contact;
|
||||||
|
RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle;
|
||||||
|
|
||||||
|
rdpei->frame.contactCount = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < rdpei->maxTouchContacts; i++)
|
||||||
|
{
|
||||||
|
contact = (RDPINPUT_CONTACT_DATA*) &(rdpei->contactPoints[i].data);
|
||||||
|
|
||||||
|
if (rdpei->contactPoints[i].dirty)
|
||||||
|
{
|
||||||
|
CopyMemory(&(rdpei->contacts[rdpei->frame.contactCount]), contact, sizeof(RDPINPUT_CONTACT_DATA));
|
||||||
|
rdpei->contactPoints[i].dirty = FALSE;
|
||||||
|
rdpei->frame.contactCount++;
|
||||||
|
}
|
||||||
|
else if (rdpei->contactPoints[i].active)
|
||||||
|
{
|
||||||
|
if (contact->contactFlags & CONTACT_FLAG_DOWN)
|
||||||
|
{
|
||||||
|
contact->contactFlags = CONTACT_FLAG_UPDATE;
|
||||||
|
contact->contactFlags |= CONTACT_FLAG_INRANGE;
|
||||||
|
contact->contactFlags |= CONTACT_FLAG_INCONTACT;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMemory(&(rdpei->contacts[rdpei->frame.contactCount]), contact, sizeof(RDPINPUT_CONTACT_DATA));
|
||||||
|
rdpei->frame.contactCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void* rdpei_schedule_thread(void* arg)
|
||||||
|
{
|
||||||
|
DWORD status;
|
||||||
|
RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) arg;
|
||||||
|
RdpeiClientContext* context = (RdpeiClientContext*) rdpei->iface.pInterface;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
status = WaitForSingleObject(rdpei->event, 20);
|
||||||
|
|
||||||
|
WaitForSingleObject(rdpei->mutex, INFINITE);
|
||||||
|
|
||||||
|
rdpei_add_frame(context);
|
||||||
|
|
||||||
|
if (rdpei->frame.contactCount > 0)
|
||||||
|
rdpei_send_frame(context);
|
||||||
|
|
||||||
|
if (status == WAIT_OBJECT_0)
|
||||||
|
ResetEvent(rdpei->event);
|
||||||
|
|
||||||
|
ReleaseMutex(rdpei->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int rdpei_send_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s, UINT16 eventId, UINT32 pduLength)
|
int rdpei_send_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s, UINT16 eventId, UINT32 pduLength)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
@ -147,6 +217,13 @@ int rdpei_send_cs_ready_pdu(RDPEI_CHANNEL_CALLBACK* callback)
|
|||||||
|
|
||||||
Stream_SealLength(s);
|
Stream_SealLength(s);
|
||||||
|
|
||||||
|
if (!rdpei->thread)
|
||||||
|
{
|
||||||
|
rdpei->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||||
|
rdpei->event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||||
|
rdpei->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) rdpei_schedule_thread, (void*) rdpei, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
status = rdpei_send_pdu(callback, s, EVENTID_CS_READY, pduLength);
|
status = rdpei_send_pdu(callback, s, EVENTID_CS_READY, pduLength);
|
||||||
Stream_Free(s, TRUE);
|
Stream_Free(s, TRUE);
|
||||||
|
|
||||||
@ -180,7 +257,12 @@ int rdpei_write_touch_frame(wStream* s, RDPINPUT_TOUCH_FRAME* frame)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
rdpei_write_2byte_unsigned(s, frame->contactCount); /* contactCount (TWO_BYTE_UNSIGNED_INTEGER) */
|
rdpei_write_2byte_unsigned(s, frame->contactCount); /* contactCount (TWO_BYTE_UNSIGNED_INTEGER) */
|
||||||
rdpei_write_8byte_unsigned(s, frame->frameOffset); /* frameOffset (EIGHT_BYTE_UNSIGNED_INTEGER) */
|
|
||||||
|
/**
|
||||||
|
* the time offset from the previous frame (in microseconds).
|
||||||
|
* If this is the first frame being transmitted then this field MUST be set to zero.
|
||||||
|
*/
|
||||||
|
rdpei_write_8byte_unsigned(s, frame->frameOffset * 1000); /* frameOffset (EIGHT_BYTE_UNSIGNED_INTEGER) */
|
||||||
|
|
||||||
Stream_EnsureRemainingCapacity(s, frame->contactCount * 32);
|
Stream_EnsureRemainingCapacity(s, frame->contactCount * 32);
|
||||||
|
|
||||||
@ -248,8 +330,13 @@ int rdpei_send_touch_event_pdu(RDPEI_CHANNEL_CALLBACK* callback, RDPINPUT_TOUCH_
|
|||||||
s = Stream_New(NULL, pduLength);
|
s = Stream_New(NULL, pduLength);
|
||||||
Stream_Seek(s, RDPINPUT_HEADER_LENGTH);
|
Stream_Seek(s, RDPINPUT_HEADER_LENGTH);
|
||||||
|
|
||||||
rdpei_write_4byte_unsigned(s, frame->frameOffset); /* FOUR_BYTE_UNSIGNED_INTEGER */
|
/**
|
||||||
rdpei_write_2byte_unsigned(s, 1); /* TWO_BYTE_UNSIGNED_INTEGER */
|
* the time that has elapsed (in milliseconds) from when the oldest touch frame
|
||||||
|
* was generated to when it was encoded for transmission by the client.
|
||||||
|
*/
|
||||||
|
rdpei_write_4byte_unsigned(s, frame->frameOffset); /* encodeTime (FOUR_BYTE_UNSIGNED_INTEGER) */
|
||||||
|
|
||||||
|
rdpei_write_2byte_unsigned(s, 1); /* (frameCount) TWO_BYTE_UNSIGNED_INTEGER */
|
||||||
|
|
||||||
rdpei_write_touch_frame(s, frame);
|
rdpei_write_touch_frame(s, frame);
|
||||||
|
|
||||||
@ -443,15 +530,18 @@ int rdpei_send_frame(RdpeiClientContext* context)
|
|||||||
|
|
||||||
int rdpei_add_contact(RdpeiClientContext* context, RDPINPUT_CONTACT_DATA* contact)
|
int rdpei_add_contact(RdpeiClientContext* context, RDPINPUT_CONTACT_DATA* contact)
|
||||||
{
|
{
|
||||||
|
RDPINPUT_CONTACT_POINT* contactPoint;
|
||||||
RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle;
|
RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle;
|
||||||
|
|
||||||
if (rdpei->frame.contactCount < MAX_CONTACTS)
|
WaitForSingleObject(rdpei->mutex, INFINITE);
|
||||||
{
|
|
||||||
CopyMemory(&(rdpei->contacts[rdpei->frame.contactCount]), contact, sizeof(RDPINPUT_CONTACT_DATA));
|
|
||||||
rdpei->frame.contactCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
rdpei_send_frame(context);
|
contactPoint = (RDPINPUT_CONTACT_POINT*) &rdpei->contactPoints[contact->contactId];
|
||||||
|
CopyMemory(&(contactPoint->data), contact, sizeof(RDPINPUT_CONTACT_DATA));
|
||||||
|
contactPoint->dirty = TRUE;
|
||||||
|
|
||||||
|
SetEvent(rdpei->event);
|
||||||
|
|
||||||
|
ReleaseMutex(rdpei->mutex);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -88,11 +88,13 @@ struct _RDPINPUT_CONTACT_POINT
|
|||||||
{
|
{
|
||||||
int lastX;
|
int lastX;
|
||||||
int lastY;
|
int lastY;
|
||||||
|
BOOL dirty;
|
||||||
BOOL active;
|
BOOL active;
|
||||||
UINT32 state;
|
UINT32 state;
|
||||||
UINT32 flags;
|
UINT32 flags;
|
||||||
UINT32 contactId;
|
UINT32 contactId;
|
||||||
int externalId;
|
int externalId;
|
||||||
|
RDPINPUT_CONTACT_DATA data;
|
||||||
};
|
};
|
||||||
typedef struct _RDPINPUT_CONTACT_POINT RDPINPUT_CONTACT_POINT;
|
typedef struct _RDPINPUT_CONTACT_POINT RDPINPUT_CONTACT_POINT;
|
||||||
|
|
||||||
|
@ -341,17 +341,17 @@ int xf_input_touch_remote(xfInfo* xfi, XIDeviceEvent* event, int evtype)
|
|||||||
|
|
||||||
if (evtype == XI_TouchBegin)
|
if (evtype == XI_TouchBegin)
|
||||||
{
|
{
|
||||||
printf("TouchBegin: %d\n", touchId);
|
//printf("TouchBegin: %d\n", touchId);
|
||||||
contactId = rdpei->TouchBegin(rdpei, touchId, x, y);
|
contactId = rdpei->TouchBegin(rdpei, touchId, x, y);
|
||||||
}
|
}
|
||||||
else if (evtype == XI_TouchUpdate)
|
else if (evtype == XI_TouchUpdate)
|
||||||
{
|
{
|
||||||
printf("TouchUpdate: %d\n", touchId);
|
//printf("TouchUpdate: %d\n", touchId);
|
||||||
contactId = rdpei->TouchUpdate(rdpei, touchId, x, y);
|
contactId = rdpei->TouchUpdate(rdpei, touchId, x, y);
|
||||||
}
|
}
|
||||||
else if (evtype == XI_TouchEnd)
|
else if (evtype == XI_TouchEnd)
|
||||||
{
|
{
|
||||||
printf("TouchEnd: %d\n", touchId);
|
//printf("TouchEnd: %d\n", touchId);
|
||||||
contactId = rdpei->TouchEnd(rdpei, touchId, x, y);
|
contactId = rdpei->TouchEnd(rdpei, touchId, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user