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 <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/thread.h>
|
||||
#include <winpr/stream.h>
|
||||
#include <winpr/sysinfo.h>
|
||||
#include <winpr/cmdline.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
#include <freerdp/addin.h>
|
||||
|
||||
@ -92,9 +95,15 @@ struct _RDPEI_PLUGIN
|
||||
RDPINPUT_TOUCH_FRAME frame;
|
||||
RDPINPUT_CONTACT_DATA contacts[MAX_CONTACTS];
|
||||
RDPINPUT_CONTACT_POINT* contactPoints;
|
||||
|
||||
HANDLE mutex;
|
||||
HANDLE event;
|
||||
HANDLE thread;
|
||||
};
|
||||
typedef struct _RDPEI_PLUGIN RDPEI_PLUGIN;
|
||||
|
||||
int rdpei_send_frame(RdpeiClientContext* context);
|
||||
|
||||
const char* RDPEI_EVENTID_STRINGS[] =
|
||||
{
|
||||
"",
|
||||
@ -106,6 +115,67 @@ const char* RDPEI_EVENTID_STRINGS[] =
|
||||
"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 status;
|
||||
@ -147,6 +217,13 @@ int rdpei_send_cs_ready_pdu(RDPEI_CHANNEL_CALLBACK* callback)
|
||||
|
||||
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);
|
||||
Stream_Free(s, TRUE);
|
||||
|
||||
@ -180,7 +257,12 @@ int rdpei_write_touch_frame(wStream* s, RDPINPUT_TOUCH_FRAME* frame)
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
@ -248,8 +330,13 @@ int rdpei_send_touch_event_pdu(RDPEI_CHANNEL_CALLBACK* callback, RDPINPUT_TOUCH_
|
||||
s = Stream_New(NULL, pduLength);
|
||||
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);
|
||||
|
||||
@ -443,15 +530,18 @@ int rdpei_send_frame(RdpeiClientContext* context)
|
||||
|
||||
int rdpei_add_contact(RdpeiClientContext* context, RDPINPUT_CONTACT_DATA* contact)
|
||||
{
|
||||
RDPINPUT_CONTACT_POINT* contactPoint;
|
||||
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++;
|
||||
}
|
||||
WaitForSingleObject(rdpei->mutex, INFINITE);
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -88,11 +88,13 @@ struct _RDPINPUT_CONTACT_POINT
|
||||
{
|
||||
int lastX;
|
||||
int lastY;
|
||||
BOOL dirty;
|
||||
BOOL active;
|
||||
UINT32 state;
|
||||
UINT32 flags;
|
||||
UINT32 contactId;
|
||||
int externalId;
|
||||
RDPINPUT_CONTACT_DATA data;
|
||||
};
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user