channels/rdpei: start implementing multitouch

This commit is contained in:
Marc-André Moreau 2013-05-08 23:18:42 -04:00
parent 99c821357d
commit e3a4d125cd
5 changed files with 708 additions and 3 deletions

View File

@ -1,7 +1,7 @@
# FreeRDP: A Remote Desktop Protocol Implementation # FreeRDP: A Remote Desktop Protocol Implementation
# FreeRDP cmake build script # FreeRDP cmake build script
# #
# Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com> # Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -19,7 +19,9 @@ define_channel_client("rdpei")
set(${MODULE_PREFIX}_SRCS set(${MODULE_PREFIX}_SRCS
rdpei_main.c rdpei_main.c
rdpei_main.h) rdpei_main.h
rdpei_common.c
rdpei_common.h)
include_directories(..) include_directories(..)

View File

@ -0,0 +1,590 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Input Virtual Channel Extension
*
* 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 <winpr/crt.h>
#include <winpr/stream.h>
#include "rdpei_common.h"
BOOL rdpei_read_2byte_unsigned(wStream* s, UINT32* value)
{
BYTE byte;
if (Stream_GetRemainingLength(s) < 1)
return FALSE;
Stream_Read_UINT8(s, byte);
if (byte & 0x80)
{
if (Stream_GetRemainingLength(s) < 1)
return FALSE;
*value = (byte & 0x7F) << 8;
Stream_Read_UINT8(s, byte);
*value |= byte;
}
else
{
*value = (byte & 0x7F);
}
return TRUE;
}
BOOL rdpei_write_2byte_unsigned(wStream* s, UINT32 value)
{
BYTE byte;
if (value > 0x7FFF)
return FALSE;
if (value >= 0x7F)
{
byte = ((value & 0x7F00) >> 8);
Stream_Write_UINT8(s, byte | 0x80);
byte = (value & 0xFF);
Stream_Write_UINT8(s, byte);
}
else
{
byte = (value & 0x7F);
Stream_Write_UINT8(s, byte);
}
return TRUE;
}
BOOL rdpei_read_2byte_signed(wStream* s, INT32* value)
{
BYTE byte;
BOOL negative;
if (Stream_GetRemainingLength(s) < 1)
return FALSE;
Stream_Read_UINT8(s, byte);
negative = (byte & 0x40) ? TRUE : FALSE;
*value = (byte & 0x3F);
if (byte & 0x80)
{
if (Stream_GetRemainingLength(s) < 1)
return FALSE;
Stream_Read_UINT8(s, byte);
*value = (*value << 8) | byte;
}
if (negative)
*value *= -1;
return TRUE;
}
BOOL rdpei_write_2byte_signed(wStream* s, INT32 value)
{
BYTE byte;
BOOL negative = FALSE;
if (value < 0)
{
negative = TRUE;
value *= -1;
}
if (value > 0x3FFF)
return FALSE;
if (value >= 0x3F)
{
byte = ((value & 0x3F00) >> 8);
if (negative)
byte |= 0x40;
Stream_Write_UINT8(s, byte | 0x80);
byte = (value & 0xFF);
Stream_Write_UINT8(s, byte);
}
else
{
byte = (value & 0x3F);
if (negative)
byte |= 0x40;
Stream_Write_UINT8(s, byte);
}
return TRUE;
}
BOOL rdpei_read_4byte_unsigned(wStream* s, UINT32* value)
{
BYTE byte;
BYTE count;
if (Stream_GetRemainingLength(s) < 1)
return FALSE;
Stream_Read_UINT8(s, byte);
count = (byte & 0xC0) >> 6;
if (Stream_GetRemainingLength(s) < count)
return FALSE;
switch (count)
{
case 0:
*value = (byte & 0x3F);
break;
case 1:
*value = (byte & 0x3F) << 8;
Stream_Read_UINT8(s, byte);
*value |= byte;
break;
case 2:
*value = (byte & 0x3F) << 16;
Stream_Read_UINT8(s, byte);
*value |= (byte << 8);
Stream_Read_UINT8(s, byte);
*value |= byte;
break;
case 3:
*value = (byte & 0x3F) << 24;
Stream_Read_UINT8(s, byte);
*value |= (byte << 16);
Stream_Read_UINT8(s, byte);
*value |= (byte << 8);
Stream_Read_UINT8(s, byte);
*value |= byte;
break;
default:
break;
}
return TRUE;
}
BOOL rdpei_write_4byte_unsigned(wStream* s, UINT32 value)
{
BYTE byte;
if (value <= 0x3F)
{
Stream_Write_UINT8(s, value);
}
else if (value <= 0x3FFF)
{
byte = (value >> 8) & 0x3F;
Stream_Write_UINT8(s, byte | 0x40);
byte = (value & 0xFF);
Stream_Write_UINT8(s, byte);
}
else if (value <= 0x3FFFFF)
{
byte = (value >> 16) & 0x3F;
Stream_Write_UINT8(s, byte | 0x80);
byte = (value >> 8) & 0xFF;
Stream_Write_UINT8(s, byte);
byte = (value & 0xFF);
Stream_Write_UINT8(s, byte);
}
else if (value <= 0x3FFFFF)
{
byte = (value >> 24) & 0x3F;
Stream_Write_UINT8(s, byte | 0xC0);
byte = (value >> 16) & 0xFF;
Stream_Write_UINT8(s, byte);
byte = (value >> 8) & 0xFF;
Stream_Write_UINT8(s, byte);
byte = (value & 0xFF);
Stream_Write_UINT8(s, byte);
}
else
{
return FALSE;
}
return TRUE;
}
BOOL rdpei_read_4byte_signed(wStream* s, INT32* value)
{
BYTE byte;
BYTE count;
BOOL negative;
if (Stream_GetRemainingLength(s) < 1)
return FALSE;
Stream_Read_UINT8(s, byte);
count = (byte & 0xC0) >> 6;
negative = (byte & 0x20);
if (Stream_GetRemainingLength(s) < count)
return FALSE;
switch (count)
{
case 0:
*value = (byte & 0x1F);
break;
case 1:
*value = (byte & 0x1F) << 8;
Stream_Read_UINT8(s, byte);
*value |= byte;
break;
case 2:
*value = (byte & 0x1F) << 16;
Stream_Read_UINT8(s, byte);
*value |= (byte << 8);
Stream_Read_UINT8(s, byte);
*value |= byte;
break;
case 3:
*value = (byte & 0x1F) << 24;
Stream_Read_UINT8(s, byte);
*value |= (byte << 16);
Stream_Read_UINT8(s, byte);
*value |= (byte << 8);
Stream_Read_UINT8(s, byte);
*value |= byte;
break;
default:
break;
}
if (negative)
*value *= -1;
return TRUE;
}
BOOL rdpei_write_4byte_signed(wStream* s, INT32 value)
{
BYTE byte;
BOOL negative = FALSE;
if (value < 0)
{
negative = TRUE;
value *= -1;
}
if (value <= 0x1F)
{
byte = value & 0x1F;
if (negative)
byte |= 0x20;
Stream_Write_UINT8(s, value);
}
else if (value <= 0x1FFF)
{
byte = (value >> 8) & 0x1F;
if (negative)
byte |= 0x20;
Stream_Write_UINT8(s, byte | 0x40);
byte = (value & 0xFF);
Stream_Write_UINT8(s, byte);
}
else if (value <= 0x1FFFFF)
{
byte = (value >> 16) & 0x1F;
if (negative)
byte |= 0x20;
Stream_Write_UINT8(s, byte | 0x80);
byte = (value >> 8) & 0xFF;
Stream_Write_UINT8(s, byte);
byte = (value & 0xFF);
Stream_Write_UINT8(s, byte);
}
else if (value <= 0x1FFFFF)
{
byte = (value >> 24) & 0x1F;
if (negative)
byte |= 0x20;
Stream_Write_UINT8(s, byte | 0xC0);
byte = (value >> 16) & 0xFF;
Stream_Write_UINT8(s, byte);
byte = (value >> 8) & 0xFF;
Stream_Write_UINT8(s, byte);
byte = (value & 0xFF);
Stream_Write_UINT8(s, byte);
}
else
{
return FALSE;
}
return TRUE;
}
BOOL rdpei_read_8byte_unsigned(wStream* s, UINT64* value)
{
BYTE byte;
BYTE count;
if (Stream_GetRemainingLength(s) < 1)
return FALSE;
Stream_Read_UINT8(s, byte);
count = (byte & 0xE0) >> 5;
if (Stream_GetRemainingLength(s) < count)
return FALSE;
switch (count)
{
case 0:
*value = (byte & 0x1F);
break;
case 1:
*value = (byte & 0x1F) << 8;
Stream_Read_UINT8(s, byte);
*value |= byte;
break;
case 2:
*value = (byte & 0x1F) << 16;
Stream_Read_UINT8(s, byte);
*value |= (byte << 8);
Stream_Read_UINT8(s, byte);
*value |= byte;
break;
case 3:
*value = (byte & 0x1F) << 24;
Stream_Read_UINT8(s, byte);
*value |= (byte << 16);
Stream_Read_UINT8(s, byte);
*value |= (byte << 8);
Stream_Read_UINT8(s, byte);
*value |= byte;
break;
case 4:
*value = (byte & 0x1F) << 32;
Stream_Read_UINT8(s, byte);
*value |= (byte << 24);
Stream_Read_UINT8(s, byte);
*value |= (byte << 16);
Stream_Read_UINT8(s, byte);
*value |= (byte << 8);
Stream_Read_UINT8(s, byte);
*value |= byte;
break;
case 5:
*value = (byte & 0x1F) << 40;
Stream_Read_UINT8(s, byte);
*value |= (byte << 32);
Stream_Read_UINT8(s, byte);
*value |= (byte << 24);
Stream_Read_UINT8(s, byte);
*value |= (byte << 16);
Stream_Read_UINT8(s, byte);
*value |= (byte << 8);
Stream_Read_UINT8(s, byte);
*value |= byte;
break;
case 6:
*value = (byte & 0x1F) << 48;
Stream_Read_UINT8(s, byte);
*value |= (byte << 40);
Stream_Read_UINT8(s, byte);
*value |= (byte << 32);
Stream_Read_UINT8(s, byte);
*value |= (byte << 24);
Stream_Read_UINT8(s, byte);
*value |= (byte << 16);
Stream_Read_UINT8(s, byte);
*value |= (byte << 8);
Stream_Read_UINT8(s, byte);
*value |= byte;
break;
case 7:
*value = (byte & 0x1F) << 56;
Stream_Read_UINT8(s, byte);
*value |= (byte << 48);
Stream_Read_UINT8(s, byte);
*value |= (byte << 40);
Stream_Read_UINT8(s, byte);
*value |= (byte << 32);
Stream_Read_UINT8(s, byte);
*value |= (byte << 24);
Stream_Read_UINT8(s, byte);
*value |= (byte << 16);
Stream_Read_UINT8(s, byte);
*value |= (byte << 8);
Stream_Read_UINT8(s, byte);
*value |= byte;
break;
default:
break;
}
return TRUE;
}
BOOL rdpei_write_8byte_unsigned(wStream* s, UINT64 value)
{
BYTE byte;
BYTE count;
if (value <= 0x1F)
{
count = 0;
byte = value & 0x1F;
Stream_Write_UINT8(s, byte | (count << 5));
}
else if (value <= 0x1FFF)
{
count = 1;
byte = (value >> 8) & 0x1F;
Stream_Write_UINT8(s, byte | (count << 5));
byte = (value & 0xFF);
Stream_Write_UINT8(s, byte);
}
else if (value <= 0x1FFFFF)
{
count = 2;
byte = (value >> 16) & 0x1F;
Stream_Write_UINT8(s, byte | (count << 5));
byte = (value >> 8) & 0xFF;
Stream_Write_UINT8(s, byte);
byte = (value & 0xFF);
Stream_Write_UINT8(s, byte);
}
else if (value <= 0x1FFFFF)
{
count = 3;
byte = (value >> 24) & 0x1F;
Stream_Write_UINT8(s, byte | (count << 5));
byte = (value >> 16) & 0xFF;
Stream_Write_UINT8(s, byte);
byte = (value >> 8) & 0xFF;
Stream_Write_UINT8(s, byte);
byte = (value & 0xFF);
Stream_Write_UINT8(s, byte);
}
else if (value <= 0x1FFFFFFF)
{
count = 4;
byte = (value >> 32) & 0x1F;
Stream_Write_UINT8(s, byte | (count << 5));
byte = (value >> 24) & 0x1F;
Stream_Write_UINT8(s, byte);
byte = (value >> 16) & 0xFF;
Stream_Write_UINT8(s, byte);
byte = (value >> 8) & 0xFF;
Stream_Write_UINT8(s, byte);
byte = (value & 0xFF);
Stream_Write_UINT8(s, byte);
}
else if (value <= 0x1FFFFFFFFF)
{
count = 5;
byte = (value >> 40) & 0x1F;
Stream_Write_UINT8(s, byte | (count << 5));
byte = (value >> 32) & 0x1F;
Stream_Write_UINT8(s, byte);
byte = (value >> 24) & 0x1F;
Stream_Write_UINT8(s, byte);
byte = (value >> 16) & 0xFF;
Stream_Write_UINT8(s, byte);
byte = (value >> 8) & 0xFF;
Stream_Write_UINT8(s, byte);
byte = (value & 0xFF);
Stream_Write_UINT8(s, byte);
}
else if (value <= 0x1FFFFFFFFFFF)
{
count = 6;
byte = (value >> 48) & 0x1F;
Stream_Write_UINT8(s, byte | (count << 5));
byte = (value >> 40) & 0x1F;
Stream_Write_UINT8(s, byte);
byte = (value >> 32) & 0x1F;
Stream_Write_UINT8(s, byte);
byte = (value >> 24) & 0x1F;
Stream_Write_UINT8(s, byte);
byte = (value >> 16) & 0xFF;
Stream_Write_UINT8(s, byte);
byte = (value >> 8) & 0xFF;
Stream_Write_UINT8(s, byte);
byte = (value & 0xFF);
Stream_Write_UINT8(s, byte);
}
else if (value <= 0x1FFFFFFFFFFFFF)
{
count = 7;
byte = (value >> 56) & 0x1F;
Stream_Write_UINT8(s, byte | (count << 5));
byte = (value >> 48) & 0x1F;
Stream_Write_UINT8(s, byte);
byte = (value >> 40) & 0x1F;
Stream_Write_UINT8(s, byte);
byte = (value >> 32) & 0x1F;
Stream_Write_UINT8(s, byte);
byte = (value >> 24) & 0x1F;
Stream_Write_UINT8(s, byte);
byte = (value >> 16) & 0xFF;
Stream_Write_UINT8(s, byte);
byte = (value >> 8) & 0xFF;
Stream_Write_UINT8(s, byte);
byte = (value & 0xFF);
Stream_Write_UINT8(s, byte);
}
else
{
return FALSE;
}
return TRUE;
}

View File

@ -0,0 +1,27 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Input Virtual Channel Extension
*
* 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 FREERDP_CHANNEL_RDPEI_CLIENT_COMMON_H
#define FREERDP_CHANNEL_RDPEI_CLIENT_COMMON_H
#include <winpr/crt.h>
#include <winpr/stream.h>
#endif /* FREERDP_CHANNEL_RDPEI_CLIENT_COMMON_H */

View File

@ -26,11 +26,12 @@
#include <string.h> #include <string.h>
#include <winpr/crt.h> #include <winpr/crt.h>
#include <winpr/stream.h>
#include <winpr/cmdline.h> #include <winpr/cmdline.h>
#include <freerdp/addin.h> #include <freerdp/addin.h>
#include <winpr/stream.h> #include "rdpei_common.h"
#include "rdpei_main.h" #include "rdpei_main.h"
@ -61,11 +62,83 @@ struct _RDPEI_PLUGIN
RDPEI_LISTENER_CALLBACK* listener_callback; RDPEI_LISTENER_CALLBACK* listener_callback;
}; };
const char* RDPEI_EVENTID_STRINGS[] =
{
"",
"EVENTID_SC_READY",
"EVENTID_CS_READY",
"EVENTID_TOUCH",
"EVENTID_SUSPEND_TOUCH",
"EVENTID_RESUME_TOUCH",
"EVENTID_DISMISS_HOVERING_CONTACT"
};
int rdpei_recv_sc_ready_pdu(wStream* s)
{
UINT32 protocolVersion;
Stream_Read_UINT32(s, protocolVersion); /* protocolVersion (4 bytes) */
if (protocolVersion != RDPINPUT_PROTOCOL_V1)
{
printf("Unknown [MS-RDPEI] protocolVersion: 0x%08X\n", protocolVersion);
return -1;
}
return 0;
}
int rdpei_recv_pdu(wStream* s)
{
UINT16 eventId;
UINT32 pduLength;
Stream_Read_UINT16(s, eventId); /* eventId (2 bytes) */
Stream_Read_UINT32(s, pduLength); /* pduLength (4 bytes) */
printf("rdpei_recv_pdu: eventId: %d (%s) length: %d\n",
eventId, RDPEI_EVENTID_STRINGS[eventId], pduLength);
switch (eventId)
{
case EVENTID_SC_READY:
rdpei_recv_sc_ready_pdu(s);
break;
case EVENTID_CS_READY:
break;
case EVENTID_TOUCH:
break;
case EVENTID_SUSPEND_TOUCH:
break;
case EVENTID_RESUME_TOUCH:
break;
case EVENTID_DISMISS_HOVERING_CONTACT:
break;
default:
break;
}
return 0;
}
static int rdpei_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, UINT32 cbSize, BYTE* pBuffer) static int rdpei_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, UINT32 cbSize, BYTE* pBuffer)
{ {
wStream* s;
int status = 0; 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);
Stream_Free(s, FALSE);
return status; return status;
} }

View File

@ -29,6 +29,19 @@
#include <freerdp/addin.h> #include <freerdp/addin.h>
#include <freerdp/utils/debug.h> #include <freerdp/utils/debug.h>
/* Protocol Version */
#define RDPINPUT_PROTOCOL_V1 0x00010000
/* Input Event Ids */
#define EVENTID_SC_READY 0x0001
#define EVENTID_CS_READY 0x0002
#define EVENTID_TOUCH 0x0003
#define EVENTID_SUSPEND_TOUCH 0x0004
#define EVENTID_RESUME_TOUCH 0x0005
#define EVENTID_DISMISS_HOVERING_CONTACT 0x0006
#ifdef WITH_DEBUG_DVC #ifdef WITH_DEBUG_DVC
#define DEBUG_DVC(fmt, ...) DEBUG_CLASS(DVC, fmt, ## __VA_ARGS__) #define DEBUG_DVC(fmt, ...) DEBUG_CLASS(DVC, fmt, ## __VA_ARGS__)
#else #else