Merge pull request #45 from llyzs/fastpath

Add FastPath Input/Output support.
This commit is contained in:
Marc-André Moreau
2011-08-16 04:43:55 -07:00
7 changed files with 177 additions and 20 deletions

View File

@@ -20,13 +20,6 @@
#ifndef __INPUT_API_H
#define __INPUT_API_H
/* Input Events */
#define INPUT_EVENT_SYNC 0x0000
#define INPUT_EVENT_SCANCODE 0x0004
#define INPUT_EVENT_UNICODE 0x0005
#define INPUT_EVENT_MOUSE 0x8001
#define INPUT_EVENT_MOUSEX 0x8002
/* keyboard Flags */
#define KBD_FLAGS_EXTENDED 0x0100
#define KBD_FLAGS_DOWN 0x4000

View File

@@ -22,6 +22,9 @@
#include <string.h>
#include <freerdp/utils/stream.h>
#include "orders.h"
#include "update.h"
#include "fastpath.h"
/**
@@ -129,23 +132,58 @@ static void fastpath_recv_update_surfcmds(rdpFastPath* fastpath, uint16 size, ST
}
}
static void fastpath_recv_orders(rdpFastPath* fastpath, STREAM* s)
{
rdpUpdate* update = fastpath->rdp->update;
uint16 numberOrders;
stream_read_uint16(s, numberOrders); /* numberOrders (2 bytes) */
printf("numberOrders(FastPath):%d\n", numberOrders);
while (numberOrders > 0)
{
update_recv_order(update, s);
numberOrders--;
}
}
static void fastpath_recv_update_common(rdpFastPath* fastpath, STREAM* s)
{
rdpUpdate* update = fastpath->rdp->update;
uint16 updateType;
stream_read_uint16(s, updateType); /* updateType (2 bytes) */
switch (updateType)
{
case UPDATE_TYPE_BITMAP:
update_read_bitmap(update, s, &update->bitmap_update);
IFCALL(update->Bitmap, update, &update->bitmap_update);
break;
case UPDATE_TYPE_PALETTE:
update_read_palette(update, s, &update->palette_update);
IFCALL(update->Palette, update, &update->palette_update);
break;
}
}
static void fastpath_recv_update(rdpFastPath* fastpath, uint8 updateCode, uint16 size, STREAM* s)
{
switch (updateCode)
{
case FASTPATH_UPDATETYPE_ORDERS:
printf("FASTPATH_UPDATETYPE_ORDERS\n");
fastpath_recv_orders(fastpath, s);
break;
case FASTPATH_UPDATETYPE_BITMAP:
printf("FASTPATH_UPDATETYPE_BITMAP\n");
break;
case FASTPATH_UPDATETYPE_PALETTE:
printf("FASTPATH_UPDATETYPE_PALETTE\n");
fastpath_recv_update_common(fastpath, s);
break;
case FASTPATH_UPDATETYPE_SYNCHRONIZE:
IFCALL(fastpath->rdp->update->Synchronize, fastpath->rdp->update);
break;
case FASTPATH_UPDATETYPE_SURFCMDS:
@@ -254,6 +292,34 @@ void fastpath_recv_updates(rdpFastPath* fastpath, STREAM* s)
IFCALL(update->EndPaint, update);
}
STREAM* fastpath_pdu_init(rdpFastPath* fastpath)
{
STREAM* s;
s = transport_send_stream_init(fastpath->rdp->transport, 127);
stream_seek(s, 2); /* fpInputHeader and length1 */
/* length2 is not necessary since input PDU should not exceed 127 bytes */
return s;
}
void fastpath_send_pdu(rdpFastPath* fastpath, STREAM* s, uint8 numberEvents)
{
int length;
length = stream_get_length(s);
if (length > 127)
{
printf("Maximum FastPath PDU length is 127\n");
return;
}
stream_set_pos(s, 0);
stream_write_uint8(s, (numberEvents << 2));
stream_write_uint8(s, length);
stream_set_pos(s, length);
transport_write(fastpath->rdp->transport, s);
}
rdpFastPath* fastpath_new(rdpRdp* rdp)
{
rdpFastPath* fastpath;

View File

@@ -82,6 +82,9 @@ struct rdp_fastpath
uint16 fastpath_read_header(rdpFastPath* fastpath, STREAM* s);
void fastpath_recv_updates(rdpFastPath* fastpath, STREAM* s);
STREAM* fastpath_pdu_init(rdpFastPath* fastpath);
void fastpath_send_pdu(rdpFastPath* fastpath, STREAM* s, uint8 numberEvents);
rdpFastPath* fastpath_new(rdpRdp* rdp);
void fastpath_free(rdpFastPath* fastpath);

View File

@@ -119,6 +119,62 @@ void input_send_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, ui
rdp_send_client_input_pdu(input->rdp, s);
}
STREAM* rdp_client_fastpath_input_pdu_init(rdpRdp* rdp, uint8 flags, uint8 code)
{
STREAM* s;
s = fastpath_pdu_init(rdp->fastpath);
stream_write_uint8(s, flags | (code << 5)); /* eventHeader */
return s;
}
void rdp_send_client_fastpath_input_pdu(rdpRdp* rdp, STREAM* s)
{
fastpath_send_pdu(rdp->fastpath, s, 1);
}
void input_send_fastpath_synchronize_event(rdpInput* input, uint32 flags)
{
STREAM* s;
/* The FastPath Synchronization eventFlags has identical values as SlowPath */
s = rdp_client_fastpath_input_pdu_init(input->rdp, (uint8)flags, FASTPATH_INPUT_EVENT_SYNC);
rdp_send_client_fastpath_input_pdu(input->rdp, s);
}
void input_send_fastpath_keyboard_event(rdpInput* input, uint16 flags, uint16 code)
{
STREAM* s;
uint8 eventFlags = 0;
eventFlags |= (flags & KBD_FLAGS_RELEASE) ? FASTPATH_INPUT_KBDFLAGS_RELEASE : 0;
eventFlags |= (flags & KBD_FLAGS_EXTENDED) ? FASTPATH_INPUT_KBDFLAGS_EXTENDED : 0;
s = rdp_client_fastpath_input_pdu_init(input->rdp, eventFlags, FASTPATH_INPUT_EVENT_SCANCODE);
stream_write_uint8(s, code); /* keyCode (1 byte) */
rdp_send_client_fastpath_input_pdu(input->rdp, s);
}
void input_send_fastpath_unicode_keyboard_event(rdpInput* input, uint16 code)
{
STREAM* s;
s = rdp_client_fastpath_input_pdu_init(input->rdp, 0, FASTPATH_INPUT_EVENT_UNICODE);
stream_write_uint16(s, code); /* unicodeCode (2 bytes) */
rdp_send_client_fastpath_input_pdu(input->rdp, s);
}
void input_send_fastpath_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y)
{
STREAM* s;
s = rdp_client_fastpath_input_pdu_init(input->rdp, 0, FASTPATH_INPUT_EVENT_MOUSE);
input_write_mouse_event(s, flags, x, y);
rdp_send_client_fastpath_input_pdu(input->rdp, s);
}
void input_send_fastpath_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y)
{
STREAM* s;
s = rdp_client_fastpath_input_pdu_init(input->rdp, 0, FASTPATH_INPUT_EVENT_MOUSEX);
input_write_extended_mouse_event(s, flags, x, y);
rdp_send_client_fastpath_input_pdu(input->rdp, s);
}
rdpInput* input_new(rdpRdp* rdp)
{
rdpInput* input;
@@ -128,11 +184,22 @@ rdpInput* input_new(rdpRdp* rdp)
if (input != NULL)
{
input->rdp = rdp;
input->SynchronizeEvent = input_send_synchronize_event;
input->KeyboardEvent = input_send_keyboard_event;
input->UnicodeKeyboardEvent = input_send_unicode_keyboard_event;
input->MouseEvent = input_send_mouse_event;
input->ExtendedMouseEvent = input_send_extended_mouse_event;
if (rdp->settings->fastpath_input)
{
input->SynchronizeEvent = input_send_fastpath_synchronize_event;
input->KeyboardEvent = input_send_fastpath_keyboard_event;
input->UnicodeKeyboardEvent = input_send_fastpath_unicode_keyboard_event;
input->MouseEvent = input_send_fastpath_mouse_event;
input->ExtendedMouseEvent = input_send_fastpath_extended_mouse_event;
}
else
{
input->SynchronizeEvent = input_send_synchronize_event;
input->KeyboardEvent = input_send_keyboard_event;
input->UnicodeKeyboardEvent = input_send_unicode_keyboard_event;
input->MouseEvent = input_send_mouse_event;
input->ExtendedMouseEvent = input_send_extended_mouse_event;
}
}
return input;

View File

@@ -21,12 +21,31 @@
#define __INPUT_H
#include "rdp.h"
#include "fastpath.h"
#include <freerdp/input.h>
#include <freerdp/freerdp.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/memory.h>
/* Input Events */
#define INPUT_EVENT_SYNC 0x0000
#define INPUT_EVENT_SCANCODE 0x0004
#define INPUT_EVENT_UNICODE 0x0005
#define INPUT_EVENT_MOUSE 0x8001
#define INPUT_EVENT_MOUSEX 0x8002
/* FastPath Input Events */
#define FASTPATH_INPUT_EVENT_SCANCODE 0x0
#define FASTPATH_INPUT_EVENT_MOUSE 0x1
#define FASTPATH_INPUT_EVENT_MOUSEX 0x2
#define FASTPATH_INPUT_EVENT_SYNC 0x3
#define FASTPATH_INPUT_EVENT_UNICODE 0x4
/* FastPath Keyboard Event Flags */
#define FASTPATH_INPUT_KBDFLAGS_RELEASE 0x01
#define FASTPATH_INPUT_KBDFLAGS_EXTENDED 0x02
#define RDP_CLIENT_INPUT_PDU_HEADER_LENGTH 4
void input_send_synchronize_event(rdpInput* input, uint32 flags);
@@ -35,6 +54,12 @@ void input_send_unicode_keyboard_event(rdpInput* input, uint16 code);
void input_send_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y);
void input_send_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y);
void input_send_fastpath_synchronize_event(rdpInput* input, uint32 flags);
void input_send_fastpath_keyboard_event(rdpInput* input, uint16 flags, uint16 code);
void input_send_fastpath_unicode_keyboard_event(rdpInput* input, uint16 code);
void input_send_fastpath_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y);
void input_send_fastpath_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y);
rdpInput* input_new(rdpRdp* rdp);
void input_free(rdpInput* input);

View File

@@ -109,6 +109,9 @@ rdpSettings* settings_new()
settings->num_icon_caches = 3;
settings->num_icon_cache_entries = 12;
settings->fastpath_input = True;
settings->fastpath_output = True;
settings->uniconv = freerdp_uniconv_new();
gethostname(settings->client_hostname, sizeof(settings->client_hostname) - 1);
}

View File

@@ -174,10 +174,10 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv,
{
settings->offscreen_bitmap_cache = 0;
}
else if (strcmp("-fastpath", argv[index]) == 0)
else if (strcmp("--no-fastpath", argv[index]) == 0)
{
settings->fastpath_input = True;
settings->fastpath_output = True;
settings->fastpath_input = False;
settings->fastpath_output = False;
}
else if (strcmp("--rfx", argv[index]) == 0)
{