channels/rdpei: implement client pdus

This commit is contained in:
Marc-André Moreau 2013-05-09 00:21:33 -04:00
parent e3a4d125cd
commit 335d13d65f
4 changed files with 195 additions and 14 deletions

View File

@ -32,6 +32,7 @@ BOOL rdpei_read_2byte_unsigned(wStream* s, UINT32* value)
if (Stream_GetRemainingLength(s) < 1)
return FALSE;
Stream_Read_UINT8(s, byte);
if (byte & 0x80)

View File

@ -23,5 +23,16 @@
#include <winpr/crt.h>
#include <winpr/stream.h>
BOOL rdpei_read_2byte_unsigned(wStream* s, UINT32* value);
BOOL rdpei_write_2byte_unsigned(wStream* s, UINT32 value);
BOOL rdpei_read_2byte_signed(wStream* s, INT32* value);
BOOL rdpei_write_2byte_signed(wStream* s, INT32 value);
BOOL rdpei_read_4byte_unsigned(wStream* s, UINT32* value);
BOOL rdpei_write_4byte_unsigned(wStream* s, UINT32 value);
BOOL rdpei_read_4byte_signed(wStream* s, INT32* value);
BOOL rdpei_write_4byte_signed(wStream* s, INT32 value);
BOOL rdpei_read_8byte_unsigned(wStream* s, UINT64* value);
BOOL rdpei_write_8byte_unsigned(wStream* s, UINT64 value);
#endif /* FREERDP_CHANNEL_RDPEI_CLIENT_COMMON_H */

View File

@ -73,7 +73,130 @@ const char* RDPEI_EVENTID_STRINGS[] =
"EVENTID_DISMISS_HOVERING_CONTACT"
};
int rdpei_recv_sc_ready_pdu(wStream* s)
int rdpei_send_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s, UINT16 eventId, UINT32 pduLength)
{
int status;
Stream_SetPosition(s, 0);
Stream_Write_UINT16(s, eventId); /* eventId (2 bytes) */
Stream_Write_UINT32(s, pduLength); /* pduLength (4 bytes) */
Stream_SetPosition(s, Stream_Length(s));
printf("rdpei_send_pdu: eventId: %d (%s) length: %d\n",
eventId, RDPEI_EVENTID_STRINGS[eventId], pduLength);
status = callback->channel->Write(callback->channel,
Stream_Length(s), Stream_Buffer(s), NULL);
return status;
}
int rdpei_send_cs_ready_pdu(RDPEI_CHANNEL_CALLBACK* callback)
{
int status;
wStream* s;
UINT32 flags;
UINT32 pduLength;
UINT16 maxTouchContacts;
flags = 0;
flags |= READY_FLAGS_SHOW_TOUCH_VISUALS;
//flags |= READY_FLAGS_DISABLE_TIMESTAMP_INJECTION;
maxTouchContacts = 10;
pduLength = RDPINPUT_HEADER_LENGTH + 10;
s = Stream_New(NULL, pduLength);
Stream_Seek(s, RDPINPUT_HEADER_LENGTH);
Stream_Write_UINT32(s, flags); /* flags (4 bytes) */
Stream_Write_UINT32(s, RDPINPUT_PROTOCOL_V1); /* protocolVersion (4 bytes) */
Stream_Write_UINT16(s, maxTouchContacts); /* maxTouchContacts (2 bytes) */
Stream_SealLength(s);
status = rdpei_send_pdu(callback, s, EVENTID_CS_READY, pduLength);
Stream_Free(s, TRUE);
return status;
}
int rdpei_write_touch_frame(wStream* s, RDPINPUT_TOUCH_FRAME* frame)
{
int index;
RDPINPUT_CONTACT_DATA* contact;
rdpei_write_2byte_unsigned(s, frame->contactCount);
rdpei_write_8byte_unsigned(s, frame->frameOffset);
Stream_EnsureRemainingCapacity(s, frame->contactCount * 32);
for (index = 0; index < frame->contactCount; index++)
{
contact = &frame->contacts[index];
Stream_Write_UINT8(s, contact->contactId);
rdpei_write_2byte_unsigned(s, contact->fieldsPresent);
rdpei_write_4byte_signed(s, contact->x);
rdpei_write_4byte_signed(s, contact->y);
rdpei_write_4byte_unsigned(s, contact->contactFlags);
if (contact->fieldsPresent & CONTACT_DATA_CONTACTRECT_PRESENT)
{
rdpei_write_2byte_signed(s, contact->contactRectLeft);
rdpei_write_2byte_signed(s, contact->contactRectTop);
rdpei_write_2byte_signed(s, contact->contactRectRight);
rdpei_write_2byte_signed(s, contact->contactRectBottom);
}
if (contact->fieldsPresent & CONTACT_DATA_ORIENTATION_PRESENT)
{
rdpei_write_4byte_unsigned(s, contact->orientation);
}
if (contact->fieldsPresent & CONTACT_DATA_PRESSURE_PRESENT)
{
rdpei_write_4byte_unsigned(s, contact->pressure);
}
}
return 0;
}
int rdpei_send_touch_event_pdu(RDPEI_CHANNEL_CALLBACK* callback)
{
int status;
wStream* s;
UINT32 pduLength;
UINT32 encodeTime;
UINT16 frameCount;
RDPINPUT_TOUCH_FRAME frame;
RDPINPUT_CONTACT_DATA contact;
encodeTime = 123;
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);
Stream_SealLength(s);
pduLength = Stream_Length(s);
status = rdpei_send_pdu(callback, s, EVENTID_TOUCH, pduLength);
Stream_Free(s, TRUE);
return status;
}
int rdpei_recv_sc_ready_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s)
{
UINT32 protocolVersion;
@ -88,7 +211,17 @@ int rdpei_recv_sc_ready_pdu(wStream* s)
return 0;
}
int rdpei_recv_pdu(wStream* s)
int rdpei_recv_suspend_touch_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s)
{
return 0;
}
int rdpei_recv_resume_touch_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s)
{
return 0;
}
int rdpei_recv_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s)
{
UINT16 eventId;
UINT32 pduLength;
@ -102,22 +235,16 @@ int rdpei_recv_pdu(wStream* s)
switch (eventId)
{
case EVENTID_SC_READY:
rdpei_recv_sc_ready_pdu(s);
break;
case EVENTID_CS_READY:
break;
case EVENTID_TOUCH:
rdpei_recv_sc_ready_pdu(callback, s);
rdpei_send_cs_ready_pdu(callback);
break;
case EVENTID_SUSPEND_TOUCH:
rdpei_recv_suspend_touch_pdu(callback, s);
break;
case EVENTID_RESUME_TOUCH:
break;
case EVENTID_DISMISS_HOVERING_CONTACT:
rdpei_recv_resume_touch_pdu(callback, s);
break;
default:
@ -131,11 +258,11 @@ static int rdpei_on_data_received(IWTSVirtualChannelCallback* pChannelCallback,
{
wStream* s;
int status = 0;
//RDPEI_CHANNEL_CALLBACK* callback = (RDPEI_CHANNEL_CALLBACK*) pChannelCallback;
RDPEI_CHANNEL_CALLBACK* callback = (RDPEI_CHANNEL_CALLBACK*) pChannelCallback;
s = Stream_New(pBuffer, cbSize);
status = rdpei_recv_pdu(s);
status = rdpei_recv_pdu(callback, s);
Stream_Free(s, FALSE);

View File

@ -29,10 +29,52 @@
#include <freerdp/addin.h>
#include <freerdp/utils/debug.h>
#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
/* Client Ready Flags */
#define READY_FLAGS_SHOW_TOUCH_VISUALS 0x00000001
#define READY_FLAGS_DISABLE_TIMESTAMP_INJECTION 0x00000002
/* Input Event Ids */
#define EVENTID_SC_READY 0x0001