rail: get client system parameters from xfreerdp

This commit is contained in:
Marc-André Moreau
2011-08-17 21:33:22 -04:00
parent 09980c8a7c
commit 48d3e65b08
9 changed files with 239 additions and 110 deletions

View File

@@ -47,18 +47,11 @@ static void on_free_rail_channel_event(RDP_EVENT* event)
}
static void rail_send_channel_event(void* rail_object, RAIL_CHANNEL_EVENT* event)
void rail_send_channel_event(void* rail_object, uint16 event_type, void* param)
{
railPlugin* plugin = (railPlugin*) rail_object;
RAIL_CHANNEL_EVENT* payload = NULL;
RDP_EVENT* out_event = NULL;
payload = xnew(RAIL_CHANNEL_EVENT);
memset(payload, 0, sizeof(RAIL_CHANNEL_EVENT));
memcpy(payload, event, sizeof(RAIL_CHANNEL_EVENT));
out_event = freerdp_event_new(RDP_EVENT_CLASS_RAIL, RDP_EVENT_TYPE_RAIL_CHANNEL, on_free_rail_channel_event, payload);
railPlugin* plugin = (railPlugin*) rail_object;
out_event = freerdp_event_new(RDP_EVENT_CLASS_RAIL, event_type, on_free_rail_channel_event, param);
svc_plugin_send_event((rdpSvcPlugin*) plugin, out_event);
}
@@ -67,10 +60,10 @@ static void rail_process_connect(rdpSvcPlugin* plugin)
railPlugin* rail = (railPlugin*) plugin;
rail->rail_event_sender.event_sender_object = rail;
rail->rail_event_sender.send_rail_vchannel_event = rail_send_channel_event;
rail->rail_event_sender.send_rail_channel_event = rail_send_channel_event;
rail->rail_data_sender.data_sender_object = rail;
rail->rail_data_sender.send_rail_vchannel_data = rail_send_channel_data;
rail->rail_data_sender.send_rail_channel_data = rail_send_channel_data;
rail->rail_order = rail_order_new();
rail->rail_order->plugin_data = (RDP_PLUGIN_DATA*)plugin->channel_entry_points.pExtendedData;
@@ -90,13 +83,47 @@ static void rail_process_receive(rdpSvcPlugin* plugin, STREAM* s)
stream_free(s);
}
void rail_recv_set_sysparams_event(rdpRailOrder* rail_order, RDP_EVENT* event)
{
RDP_PLUGIN_DATA* data;
/* Send System Parameters */
rail_send_client_sysparams_order(rail_order);
/* execute */
rail_order->exec.flags =
RAIL_EXEC_FLAG_EXPAND_WORKINGDIRECTORY |
RAIL_EXEC_FLAG_EXPAND_ARGUMENTS;
data = rail_order->plugin_data;
while (data && data->size > 0)
{
rail_string_to_unicode_string(rail_order, (char*)data->data[0], &rail_order->exec.exeOrFile);
rail_string_to_unicode_string(rail_order, (char*)data->data[1], &rail_order->exec.workingDir);
rail_string_to_unicode_string(rail_order, (char*)data->data[2], &rail_order->exec.arguments);
rail_send_client_exec_order(rail_order);
data = (RDP_PLUGIN_DATA*)(((void*)data) + data->size);
}
}
static void rail_process_event(rdpSvcPlugin* plugin, RDP_EVENT* event)
{
RAIL_CLIENT_EVENT* rail_ui_event = NULL;
railPlugin* rail = NULL;
rail = (railPlugin*) plugin;
rail = (railPlugin*)plugin;
rail_ui_event = (RAIL_CLIENT_EVENT*)event->user_data;
switch (event->event_type)
{
case RDP_EVENT_TYPE_RAIL_CLIENT_SET_SYSPARAMS:
rail_recv_set_sysparams_event(rail->rail_order, event);
break;
default:
break;
}
freerdp_event_free(event);
}

View File

@@ -26,19 +26,19 @@
#include <freerdp/utils/stream.h>
#include <freerdp/utils/svc_plugin.h>
typedef struct _RAIL_VCHANNEL_DATA_SENDER RAIL_VCHANNEL_DATA_SENDER;
typedef struct _RAIL_VCHANNEL_EVENT_SENDER RAIL_VCHANNEL_EVENT_SENDER;
typedef struct _RAIL_CHANNEL_DATA_SENDER RAIL_CHANNEL_DATA_SENDER;
typedef struct _RAIL_CHANNEL_EVENT_SENDER RAIL_CHANNEL_EVENT_SENDER;
struct _RAIL_VCHANNEL_DATA_SENDER
struct _RAIL_CHANNEL_DATA_SENDER
{
void* data_sender_object;
void (*send_rail_vchannel_data)(void* sender_object, void* data, size_t length);
void (*send_rail_channel_data)(void* sender_object, void* data, size_t length);
};
struct _RAIL_VCHANNEL_EVENT_SENDER
struct _RAIL_CHANNEL_EVENT_SENDER
{
void * event_sender_object;
void (*send_rail_vchannel_event)(void* ui_event_sender_object, RAIL_CHANNEL_EVENT* event);
void (*send_rail_channel_event)(void* ui_event_sender_object, uint16 event_type, void* param);
};
struct rdp_rail_order
@@ -60,20 +60,22 @@ struct rdp_rail_order
RAIL_LANGBAR_INFO_ORDER langbar_info;
RAIL_GET_APPID_REQ_ORDER get_appid_req;
RAIL_GET_APPID_RESP_ORDER get_appid_resp;
RAIL_VCHANNEL_DATA_SENDER* data_sender;
RAIL_VCHANNEL_EVENT_SENDER* event_sender;
RAIL_CHANNEL_DATA_SENDER* data_sender;
RAIL_CHANNEL_EVENT_SENDER* event_sender;
};
typedef struct rdp_rail_order rdpRailOrder;
struct rail_plugin
{
rdpSvcPlugin plugin;
RAIL_VCHANNEL_DATA_SENDER rail_data_sender;
RAIL_VCHANNEL_EVENT_SENDER rail_event_sender;
RAIL_CHANNEL_DATA_SENDER rail_data_sender;
RAIL_CHANNEL_EVENT_SENDER rail_event_sender;
rdpRailOrder* rail_order;
};
typedef struct rail_plugin railPlugin;
void rail_send_channel_event(void* rail_object, uint16 event_type, void* param);
#define WITH_DEBUG_RAIL 1
#ifdef WITH_DEBUG_RAIL

View File

@@ -114,7 +114,7 @@ void rail_send_pdu(rdpRailOrder* rail_order, STREAM* s, uint16 orderType)
printf("Sending %s PDU, length:%d\n",
RAIL_ORDER_TYPE_STRINGS[((orderType & 0xF0) >> 3) + (orderType & 0x0F)], orderLength);
rail_order->data_sender->send_rail_vchannel_data(rail_order->data_sender->data_sender_object, s->data, orderLength);
rail_order->data_sender->send_rail_channel_data(rail_order->data_sender->data_sender_object, s->data, orderLength);
}
void rail_write_high_contrast(STREAM* s, HIGH_CONTRAST* high_contrast)
@@ -142,9 +142,22 @@ void rail_read_server_exec_result_order(STREAM* s, RAIL_EXEC_RESULT_ORDER* exec_
void rail_read_server_sysparam_order(STREAM* s, RAIL_SYSPARAM_ORDER* sysparam)
{
uint8 body;
stream_read_uint32(s, sysparam->systemParam); /* systemParam (4 bytes) */
stream_read_uint32(s, sysparam->param); /* systemParam (4 bytes) */
stream_read_uint8(s, body); /* body (1 byte) */
sysparam->value = (body != 0) ? True : False;
switch (sysparam->param)
{
case SPI_SET_SCREEN_SAVE_ACTIVE:
sysparam->set_screen_save_active = (body != 0) ? True : False;
break;
case SPI_SET_SCREEN_SAVE_SECURE:
sysparam->set_screen_save_secure = (body != 0) ? True : False;
break;
default:
break;
}
}
void rail_read_server_minmaxinfo_order(STREAM* s, RAIL_MINMAXINFO_ORDER* minmaxinfo)
@@ -210,22 +223,40 @@ void rail_write_client_exec_order(STREAM* s, RAIL_EXEC_ORDER* exec)
void rail_write_client_sysparam_order(STREAM* s, RAIL_SYSPARAM_ORDER* sysparam)
{
uint8 body;
stream_write_uint32(s, sysparam->systemParam); /* systemParam (4 bytes) */
stream_write_uint32(s, sysparam->param); /* systemParam (4 bytes) */
switch (sysparam->systemParam)
switch (sysparam->param)
{
case SPI_SET_DRAG_FULL_WINDOWS:
body = sysparam->dragFullWindows;
stream_write_uint8(s, body);
break;
case SPI_SET_KEYBOARD_CUES:
body = sysparam->keyboardCues;
stream_write_uint8(s, body);
break;
case SPI_SET_KEYBOARD_PREF:
body = sysparam->keyboardPref;
stream_write_uint8(s, body);
break;
case SPI_SET_MOUSE_BUTTON_SWAP:
body = sysparam->value;
body = sysparam->mouseButtonSwap;
stream_write_uint8(s, body);
break;
case SPI_SET_WORK_AREA:
rail_write_rectangle_16(s, &sysparam->workArea);
break;
case SPI_DISPLAY_CHANGE:
rail_write_rectangle_16(s, &sysparam->displayChange);
break;
case SPI_TASKBAR_POS:
rail_write_rectangle_16(s, &sysparam->rectangle);
rail_write_rectangle_16(s, &sysparam->taskbarPos);
break;
case SPI_SET_HIGH_CONTRAST:
@@ -285,8 +316,6 @@ void rail_write_langbar_info_order(STREAM* s, RAIL_LANGBAR_INFO_ORDER* langbar_i
void rail_recv_handshake_order(rdpRailOrder* rail_order, STREAM* s)
{
RDP_PLUGIN_DATA* data;
rail_read_handshake_order(s, &rail_order->handshake);
rail_order->handshake.buildNumber = 0x00001DB0;
@@ -297,59 +326,39 @@ void rail_recv_handshake_order(rdpRailOrder* rail_order, STREAM* s)
/* sysparam update */
rail_order->sysparam.systemParam = SPI_SET_HIGH_CONTRAST;
rail_order->sysparam.params = 0;
rail_order->sysparam.params |= SPI_SET_HIGH_CONTRAST;
rail_order->sysparam.highContrast.colorScheme.string = NULL;
rail_order->sysparam.highContrast.colorScheme.length = 0;
rail_order->sysparam.highContrast.flags = 0x7E;
rail_send_client_sysparam_order(rail_order);
rail_order->sysparam.systemParam = SPI_TASKBAR_POS;
rail_order->sysparam.rectangle.left = 0;
rail_order->sysparam.rectangle.top = 0;
rail_order->sysparam.rectangle.right = 1024;
rail_order->sysparam.rectangle.bottom = 29;
rail_send_client_sysparam_order(rail_order);
rail_order->sysparam.params |= SPI_TASKBAR_POS;
rail_order->sysparam.taskbarPos.left = 0;
rail_order->sysparam.taskbarPos.top = 0;
rail_order->sysparam.taskbarPos.right = 1024;
rail_order->sysparam.taskbarPos.bottom = 29;
rail_order->sysparam.systemParam = SPI_SET_MOUSE_BUTTON_SWAP;
rail_order->sysparam.value = False;
rail_send_client_sysparam_order(rail_order);
rail_order->sysparam.params |= SPI_SET_MOUSE_BUTTON_SWAP;
rail_order->sysparam.mouseButtonSwap = False;
rail_order->sysparam.systemParam = SPI_SET_KEYBOARD_PREF;
rail_order->sysparam.value = False;
rail_send_client_sysparam_order(rail_order);
rail_order->sysparam.params |= SPI_SET_KEYBOARD_PREF;
rail_order->sysparam.keyboardPref = False;
rail_order->sysparam.systemParam = SPI_SET_DRAG_FULL_WINDOWS;
rail_order->sysparam.value = True;
rail_send_client_sysparam_order(rail_order);
rail_order->sysparam.params |= SPI_SET_DRAG_FULL_WINDOWS;
rail_order->sysparam.dragFullWindows = True;
rail_order->sysparam.systemParam = SPI_SET_KEYBOARD_CUES;
rail_order->sysparam.value = False;
rail_send_client_sysparam_order(rail_order);
rail_order->sysparam.params |= SPI_SET_KEYBOARD_CUES;
rail_order->sysparam.keyboardCues = False;
rail_order->sysparam.systemParam = SPI_SET_WORK_AREA;
rail_order->sysparam.rectangle.left = 0;
rail_order->sysparam.rectangle.top = 0;
rail_order->sysparam.rectangle.right = 1024;
rail_order->sysparam.rectangle.bottom = 768;
rail_send_client_sysparam_order(rail_order);
rail_order->sysparam.params |= SPI_SET_WORK_AREA;
rail_order->sysparam.workArea.left = 0;
rail_order->sysparam.workArea.top = 0;
rail_order->sysparam.workArea.right = 1024;
rail_order->sysparam.workArea.bottom = 768;
/* execute */
rail_order->exec.flags =
RAIL_EXEC_FLAG_EXPAND_WORKINGDIRECTORY |
RAIL_EXEC_FLAG_EXPAND_ARGUMENTS;
data = rail_order->plugin_data;
while (data && data->size > 0)
{
rail_string_to_unicode_string(rail_order, (char*)data->data[0], &rail_order->exec.exeOrFile);
rail_string_to_unicode_string(rail_order, (char*)data->data[1], &rail_order->exec.workingDir);
rail_string_to_unicode_string(rail_order, (char*)data->data[2], &rail_order->exec.arguments);
rail_send_client_exec_order(rail_order);
data = (RDP_PLUGIN_DATA*)(((void*)data) + data->size);
}
rail_send_channel_event(rail_order->event_sender->event_sender_object,
RDP_EVENT_TYPE_RAIL_CHANNEL_GET_SYSPARAMS, (void*) &rail_order->sysparam);
}
void rail_order_recv(rdpRailOrder* rail_order, STREAM* s)
@@ -435,7 +444,7 @@ void rail_send_client_sysparam_order(rdpRailOrder* rail_order)
length = RAIL_SYSPARAM_ORDER_LENGTH;
switch (rail_order->sysparam.systemParam)
switch (rail_order->sysparam.param)
{
case SPI_SET_DRAG_FULL_WINDOWS:
case SPI_SET_KEYBOARD_CUES:
@@ -460,6 +469,51 @@ void rail_send_client_sysparam_order(rdpRailOrder* rail_order)
rail_send_pdu(rail_order, s, RAIL_ORDER_TYPE_SYSPARAM);
}
void rail_send_client_sysparams_order(rdpRailOrder* rail_order)
{
if (rail_order->sysparam.params & SPI_SET_HIGH_CONTRAST)
{
rail_order->sysparam.param = SPI_SET_HIGH_CONTRAST;
rail_send_client_sysparam_order(rail_order);
}
if (rail_order->sysparam.params & SPI_TASKBAR_POS)
{
rail_order->sysparam.param = SPI_TASKBAR_POS;
rail_send_client_sysparam_order(rail_order);
}
if (rail_order->sysparam.params & SPI_SET_MOUSE_BUTTON_SWAP)
{
rail_order->sysparam.param = SPI_SET_MOUSE_BUTTON_SWAP;
rail_send_client_sysparam_order(rail_order);
}
if (rail_order->sysparam.params & SPI_SET_KEYBOARD_PREF)
{
rail_order->sysparam.param = SPI_SET_KEYBOARD_PREF;
rail_send_client_sysparam_order(rail_order);
}
if (rail_order->sysparam.params & SPI_SET_DRAG_FULL_WINDOWS)
{
rail_order->sysparam.param = SPI_SET_DRAG_FULL_WINDOWS;
rail_send_client_sysparam_order(rail_order);
}
if (rail_order->sysparam.params & SPI_SET_KEYBOARD_CUES)
{
rail_order->sysparam.param = SPI_SET_KEYBOARD_CUES;
rail_send_client_sysparam_order(rail_order);
}
if (rail_order->sysparam.params & SPI_SET_WORK_AREA)
{
rail_order->sysparam.param = SPI_SET_WORK_AREA;
rail_send_client_sysparam_order(rail_order);
}
}
void rail_send_client_activate_order(rdpRailOrder* rail_order)
{
STREAM* s;

View File

@@ -54,6 +54,8 @@
#define RAIL_GET_APPID_REQ_ORDER_LENGTH 4 /* fixed */
#define RAIL_LANGBAR_INFO_ORDER_LENGTH 4 /* fixed */
void rail_string_to_unicode_string(rdpRailOrder* rail_order, char* string, UNICODE_STRING* unicode_string);
void rail_read_handshake_order(STREAM* s, RAIL_HANDSHAKE_ORDER* handshake);
void rail_read_server_exec_result_order(STREAM* s, RAIL_EXEC_RESULT_ORDER* exec_result);
void rail_read_server_sysparam_order(STREAM* s, RAIL_SYSPARAM_ORDER* sysparam);
@@ -80,6 +82,7 @@ void rail_send_handshake_order(rdpRailOrder* rail_order);
void rail_send_client_status_order(rdpRailOrder* rail_order);
void rail_send_client_exec_order(rdpRailOrder* rail_order);
void rail_send_client_sysparam_order(rdpRailOrder* rail_order);
void rail_send_client_sysparams_order(rdpRailOrder* rail_order);
void rail_send_client_activate_order(rdpRailOrder* rail_order);
void rail_send_client_sysmenu_order(rdpRailOrder* rail_order);
void rail_send_client_syscommand_order(rdpRailOrder* rail_order);

View File

@@ -17,6 +17,7 @@
* limitations under the License.
*/
#include <freerdp/utils/event.h>
#include <freerdp/rail/rail.h>
#include "xf_window.h"
@@ -62,7 +63,43 @@ void xf_rail_register_callbacks(xfInfo* xfi, rdpRail* rail)
rail->CreateWindow = xf_rail_CreateWindow;
}
void xf_process_rail_event(rdpChanMan* chanman, freerdp* instance)
void xf_process_rail_get_sysparams_event(xfInfo* xfi, rdpChanMan* chanman, RDP_EVENT* event)
{
printf("xf_process_rail_event");
RDP_EVENT* new_event;
RAIL_SYSPARAM_ORDER* sysparam;
sysparam = (RAIL_SYSPARAM_ORDER*) event->user_data;
sysparam->workArea.left = xfi->workArea.x;
sysparam->workArea.top = xfi->workArea.y;
sysparam->workArea.right = xfi->workArea.x + xfi->workArea.width;
sysparam->workArea.bottom = xfi->workArea.y + xfi->workArea.height;
sysparam->displayChange.left = xfi->workArea.x;
sysparam->displayChange.top = xfi->workArea.y;
sysparam->displayChange.right = xfi->workArea.x + xfi->workArea.width;
sysparam->displayChange.bottom = xfi->workArea.y + xfi->workArea.height;
sysparam->taskbarPos.left = 0;
sysparam->taskbarPos.top = 0;
sysparam->taskbarPos.right = 0;
sysparam->taskbarPos.bottom = 0;
new_event = freerdp_event_new(RDP_EVENT_CLASS_RAIL,
RDP_EVENT_TYPE_RAIL_CLIENT_SET_SYSPARAMS, NULL, (void*) sysparam);
freerdp_chanman_send_event(chanman, new_event);
}
void xf_process_rail_event(xfInfo* xfi, rdpChanMan* chanman, RDP_EVENT* event)
{
switch (event->event_type)
{
case RDP_EVENT_TYPE_RAIL_CHANNEL_GET_SYSPARAMS:
xf_process_rail_get_sysparams_event(xfi, chanman, event);
break;
default:
break;
}
}

View File

@@ -23,7 +23,8 @@
#include "xfreerdp.h"
void xf_rail_paint(xfInfo* xfi, rdpRail* rail);
void xf_process_rail_event(rdpChanMan* chanman, freerdp* instance);
void xf_rail_register_callbacks(xfInfo* xfi, rdpRail* rail);
void xf_process_rail_event(xfInfo* xfi, rdpChanMan* chanman, RDP_EVENT* event);
#endif /* __XF_RAIL_H */

View File

@@ -355,7 +355,7 @@ void xf_process_cb_sync_event(rdpChanMan* chanman, freerdp* instance)
event = freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, RDP_EVENT_TYPE_CB_FORMAT_LIST, NULL, NULL);
format_list_event = (RDP_CB_FORMAT_LIST_EVENT*)event;
format_list_event = (RDP_CB_FORMAT_LIST_EVENT*) event;
format_list_event->num_formats = 0;
freerdp_chanman_send_event(chanman, event);
@@ -363,21 +363,31 @@ void xf_process_cb_sync_event(rdpChanMan* chanman, freerdp* instance)
void xf_process_channel_event(rdpChanMan* chanman, freerdp* instance)
{
xfInfo* xfi;
RDP_EVENT* event;
xfi = GET_XFI(instance);
event = freerdp_chanman_pop_event(chanman);
if (event)
{
switch (event->event_class)
{
case RDP_EVENT_CLASS_RAIL:
xf_process_rail_event(xfi, chanman, event);
break;
default:
break;
}
switch (event->event_type)
{
case RDP_EVENT_TYPE_CB_SYNC:
xf_process_cb_sync_event(chanman, instance);
break;
case RDP_EVENT_TYPE_RAIL_CHANNEL:
xf_process_rail_event(chanman, instance);
break;
default:
printf("xf_process_channel_event: unknown event type %d\n", event->event_type);
break;
}
freerdp_event_free(event);

View File

@@ -192,10 +192,18 @@ typedef struct _RAIL_EXEC_RESULT_ORDER RAIL_EXEC_RESULT_ORDER;
struct _RAIL_SYSPARAM_ORDER
{
uint32 systemParam;
boolean value;
RECTANGLE_16 rectangle;
uint32 param;
uint32 params;
boolean dragFullWindows;
boolean keyboardCues;
boolean keyboardPref;
boolean mouseButtonSwap;
RECTANGLE_16 workArea;
RECTANGLE_16 displayChange;
RECTANGLE_16 taskbarPos;
HIGH_CONTRAST highContrast;
boolean set_screen_save_active;
boolean set_screen_save_secure;
};
typedef struct _RAIL_SYSPARAM_ORDER RAIL_SYSPARAM_ORDER;
@@ -305,25 +313,9 @@ enum RDP_RAIL_PDU_TYPE
enum RDP_EVENT_TYPE_RAIL
{
RDP_EVENT_TYPE_RAIL_CLIENT = 1,
RDP_EVENT_TYPE_RAIL_CHANNEL
RDP_EVENT_TYPE_RAIL_CHANNEL_GET_SYSPARAMS = 1,
RDP_EVENT_TYPE_RAIL_CLIENT_SET_SYSPARAMS = 2
};
/* RAIL Common structures */
struct _RAIL_CHANNEL_EVENT
{
uint32 id;
void* param;
};
typedef struct _RAIL_CHANNEL_EVENT RAIL_CHANNEL_EVENT;
struct _RAIL_CLIENT_EVENT
{
uint32 id;
void* param;
};
typedef struct _RAIL_CLIENT_EVENT RAIL_CLIENT_EVENT;
#endif /* __RAIL_GLOBAL_H */

View File

@@ -56,10 +56,10 @@ static RDP_EVENT* freerdp_tsmf_event_new(uint16 event_type)
switch (event_type)
{
case RDP_EVENT_TYPE_TSMF_VIDEO_FRAME:
event = (RDP_EVENT*)xnew(RDP_VIDEO_FRAME_EVENT);
event = (RDP_EVENT*) xnew(RDP_VIDEO_FRAME_EVENT);
break;
case RDP_EVENT_TYPE_TSMF_REDRAW:
event = (RDP_EVENT*)xnew(RDP_REDRAW_EVENT);
event = (RDP_EVENT*) xnew(RDP_REDRAW_EVENT);
break;
}
@@ -68,7 +68,9 @@ static RDP_EVENT* freerdp_tsmf_event_new(uint16 event_type)
static RDP_EVENT* freerdp_rail_event_new(uint16 event_type)
{
return xnew(RDP_EVENT);
RDP_EVENT* event = NULL;
event = xnew(RDP_EVENT);
return event;
}
RDP_EVENT* freerdp_event_new(uint16 event_class, uint16 event_type,
@@ -91,6 +93,7 @@ RDP_EVENT* freerdp_event_new(uint16 event_class, uint16 event_type,
event = freerdp_rail_event_new(event_type);
break;
}
if (event != NULL)
{
event->event_class = event_class;