diff --git a/CMakeLists.txt b/CMakeLists.txt index 18d575bb6..7d2c66e71 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,6 +58,11 @@ if(CMAKE_COMPILER_IS_GNUCC) endif() endif() +if(MSVC) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_X86_") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_X86_ -D_CRT_SECURE_NO_WARNINGS") +endif() + # Include files check_include_files(sys/param.h HAVE_SYS_PARAM_H) check_include_files(sys/socket.h HAVE_SYS_SOCKET_H) @@ -68,7 +73,7 @@ check_include_files(unistd.h HAVE_UNISTD_H) # Libraries that we have a hard dependency on find_package(OpenSSL REQUIRED) -if(!WINDOWS) +if(NOT WIN32) find_package(ZLIB REQUIRED) find_package(ALSA) find_package(PulseAudio) @@ -106,8 +111,13 @@ endif() # Sub-directories add_subdirectory(include) add_subdirectory(libfreerdp-utils) -add_subdirectory(libfreerdp-kbd) + +if(NOT WIN32) + add_subdirectory(libfreerdp-kbd) +endif() + add_subdirectory(libfreerdp-gdi) +add_subdirectory(libfreerdp-rail) add_subdirectory(libfreerdp-cache) add_subdirectory(libfreerdp-chanman) add_subdirectory(libfreerdp-core) diff --git a/channels/rdpsnd/rdpsnd_main.c b/channels/rdpsnd/rdpsnd_main.c index 4f2910aac..b35311d13 100644 --- a/channels/rdpsnd/rdpsnd_main.c +++ b/channels/rdpsnd/rdpsnd_main.c @@ -306,6 +306,7 @@ static void rdpsnd_process_message_wave_info(rdpsndPlugin* rdpsnd, STREAM* data_ DEBUG_SVC("waveDataSize %d wFormatNo %d", rdpsnd->waveDataSize, wFormatNo); + rdpsnd->close_timestamp = 0; if (!rdpsnd->is_open) { rdpsnd->current_format = wFormatNo; diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 9dff3a92b..002fff4e4 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -21,14 +21,16 @@ add_subdirectory(test) -# Build DirectFB Client -find_package(X11) -if(X11_FOUND) - add_subdirectory(X11) -endif() +if(NOT WIN32) + # Build X11 Client + find_package(X11) + if(X11_FOUND) + add_subdirectory(X11) + endif() -# Build DirectFB Client -find_package(DirectFB) -if(DIRECTFB_FOUND) - add_subdirectory(DirectFB) + # Build DirectFB Client + find_package(DirectFB) + if(DIRECTFB_FOUND) + add_subdirectory(DirectFB) + endif() endif() diff --git a/client/DirectFB/dfreerdp.c b/client/DirectFB/dfreerdp.c index ee23a671a..763519ec1 100644 --- a/client/DirectFB/dfreerdp.c +++ b/client/DirectFB/dfreerdp.c @@ -293,6 +293,7 @@ int dfreerdp_run(freerdp* instance) max_fds = 0; FD_ZERO(&rfds_set); + FD_ZERO(&wfds_set); for (i = 0; i < rcount; i++) { diff --git a/client/X11/CMakeLists.txt b/client/X11/CMakeLists.txt index b8ea2675d..610dcc9e1 100644 --- a/client/X11/CMakeLists.txt +++ b/client/X11/CMakeLists.txt @@ -20,6 +20,8 @@ include_directories(${X11_INCLUDE_DIRS}) add_executable(xfreerdp + xf_rail.c + xf_rail.h xf_event.c xf_event.h xf_keyboard.c @@ -32,6 +34,7 @@ add_executable(xfreerdp target_link_libraries(xfreerdp freerdp-core) target_link_libraries(xfreerdp freerdp-gdi) target_link_libraries(xfreerdp freerdp-kbd) +target_link_libraries(xfreerdp freerdp-rail) target_link_libraries(xfreerdp freerdp-chanman) target_link_libraries(xfreerdp freerdp-utils) target_link_libraries(xfreerdp ${X11_LIBRARIES}) diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c new file mode 100644 index 000000000..b70feb00e --- /dev/null +++ b/client/X11/xf_rail.c @@ -0,0 +1,25 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 RAIL + * + * Copyright 2011 Marc-Andre Moreau + * + * 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. + */ + +#include "xf_rail.h" + +void xf_process_rail_event(rdpChanMan* chanman, freerdp* instance) +{ + +} diff --git a/client/X11/xf_rail.h b/client/X11/xf_rail.h new file mode 100644 index 000000000..83b70d57f --- /dev/null +++ b/client/X11/xf_rail.h @@ -0,0 +1,27 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 RAIL + * + * Copyright 2011 Marc-Andre Moreau + * + * 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 __XF_RAIL_H +#define __XF_RAIL_H + +#include "xfreerdp.h" + +void xf_process_rail_event(rdpChanMan* chanman, freerdp* instance); + +#endif /* __XF_RAIL_H */ diff --git a/client/X11/xfreerdp.c b/client/X11/xfreerdp.c index 03a13ebe6..cdb827d70 100644 --- a/client/X11/xfreerdp.c +++ b/client/X11/xfreerdp.c @@ -32,6 +32,7 @@ #include #include +#include "xf_rail.h" #include "xf_event.h" #include "xfreerdp.h" @@ -310,6 +311,9 @@ boolean xf_post_connect(freerdp* instance) instance->update->BeginPaint = xf_begin_paint; instance->update->EndPaint = xf_end_paint; + instance->update->rail = (void*) rail_new(); + rail_register_update_callbacks((rdpRail*) instance->update->rail, instance->update); + freerdp_chanman_post_connect(GET_CHANMAN(instance), instance); return True; @@ -343,11 +347,6 @@ void xf_process_cb_sync_event(rdpChanMan* chanman, freerdp* instance) freerdp_chanman_send_event(chanman, event); } -void xf_process_rail_event(rdpChanMan* chanman, freerdp* instance) -{ - -} - void xf_process_channel_event(rdpChanMan* chanman, freerdp* instance) { FRDP_EVENT* event; @@ -451,6 +450,7 @@ int xfreerdp_run(freerdp* instance) max_fds = 0; FD_ZERO(&rfds_set); + FD_ZERO(&wfds_set); for (i = 0; i < rcount; i++) { diff --git a/client/X11/xfreerdp.h b/client/X11/xfreerdp.h index 54e9ca353..242049e6c 100644 --- a/client/X11/xfreerdp.h +++ b/client/X11/xfreerdp.h @@ -25,6 +25,7 @@ #include #include #include +#include typedef struct xf_info xfInfo; diff --git a/include/freerdp/freerdp.h b/include/freerdp/freerdp.h index 6334f902b..d14c6cac1 100644 --- a/include/freerdp/freerdp.h +++ b/include/freerdp/freerdp.h @@ -37,13 +37,13 @@ extern "C" { FREERDP_API boolean freerdp_global_init(); FREERDP_API void freerdp_global_finish(); -typedef boolean (*pcConnect)(freerdp* freerdp); -typedef boolean (*pcPreConnect)(freerdp* freerdp); -typedef boolean (*pcPostConnect)(freerdp* freerdp); -typedef boolean (*pcGetFileDescriptor)(freerdp* freerdp, void** rfds, int* rcount, void** wfds, int* wcount); -typedef boolean (*pcCheckFileDescriptor)(freerdp* freerdp); -typedef int (*pcSendChannelData)(freerdp* freerdp, int channelId, uint8* data, int size); -typedef int (*pcReceiveChannelData)(freerdp* freerdp, int channelId, uint8* data, int size, int flags, int total_size); +typedef boolean (*pcConnect)(freerdp* instance); +typedef boolean (*pcPreConnect)(freerdp* instance); +typedef boolean (*pcPostConnect)(freerdp* instance); +typedef boolean (*pcGetFileDescriptor)(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount); +typedef boolean (*pcCheckFileDescriptor)(freerdp* instance); +typedef int (*pcSendChannelData)(freerdp* instance, int channelId, uint8* data, int size); +typedef int (*pcReceiveChannelData)(freerdp* instance, int channelId, uint8* data, int size, int flags, int total_size); struct rdp_freerdp { diff --git a/include/freerdp/input.h b/include/freerdp/input.h index ec28db012..469cd1673 100644 --- a/include/freerdp/input.h +++ b/include/freerdp/input.h @@ -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 diff --git a/include/freerdp/rail.h b/include/freerdp/rail.h index 85bf5bd88..aa8792cee 100644 --- a/include/freerdp/rail.h +++ b/include/freerdp/rail.h @@ -18,8 +18,8 @@ * limitations under the License. */ -#ifndef __RAIL_H -#define __RAIL_H +#ifndef __RAIL_GLOBAL_H +#define __RAIL_GLOBAL_H #include @@ -325,5 +325,5 @@ typedef struct _RAIL_UI_EVENT } RAIL_UI_EVENT; -#endif /* __RAIL_H */ +#endif /* __RAIL_GLOBAL_H */ diff --git a/include/freerdp/rail/rail.h b/include/freerdp/rail/rail.h new file mode 100644 index 000000000..a5c1c7bf0 --- /dev/null +++ b/include/freerdp/rail/rail.h @@ -0,0 +1,43 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Remote Applications Integrated Locally (RAIL) + * + * Copyright 2011 Marc-Andre Moreau + * + * 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 __RAIL_H +#define __RAIL_H + +#include +#include +#include +#include + +typedef struct rdp_rail rdpRail; + +#include +#include + +struct rdp_rail +{ + rdpWindowList* list; +}; + +void rail_register_update_callbacks(rdpRail* rail, rdpUpdate* update); + +rdpRail* rail_new(); +void rail_free(rdpRail* rail); + +#endif /* __RAIL_H */ diff --git a/include/freerdp/rail/window.h b/include/freerdp/rail/window.h new file mode 100644 index 000000000..2778ff7a1 --- /dev/null +++ b/include/freerdp/rail/window.h @@ -0,0 +1,65 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RAIL Windows + * + * Copyright 2011 Marc-Andre Moreau + * + * 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 __WINDOW_H +#define __WINDOW_H + +#include +#include +#include +#include + +typedef struct rdp_window rdpWindow; + +struct rdp_window +{ + rdpWindow* prev; + rdpWindow* next; + uint32 windowId; + uint32 ownerWindowId; + uint32 style; + uint32 extendedStyle; + uint8 showState; + UNICODE_STRING titleInfo; + uint32 clientOffsetX; + uint32 clientOffsetY; + uint32 clientAreaWidth; + uint32 clientAreaHeight; + uint8 RPContent; + uint32 rootParentHandle; + uint32 windowOffsetX; + uint32 windowOffsetY; + uint32 windowClientDeltaX; + uint32 windowClientDeltaY; + uint32 windowWidth; + uint32 windowHeight; + uint16 numWindowRects; + RECTANGLE_16* windowRects; + uint32 visibleOffsetX; + uint32 visibleOffsetY; + uint16 numVisibilityRects; + RECTANGLE_16* visibilityRects; +}; + +void window_state_update(rdpWindow* window, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state); + +rdpWindow* rail_CreateWindow(uint32 windowId); +void rail_DestroyWindow(rdpWindow* window); + +#endif /* __WINDOW_H */ diff --git a/include/freerdp/rail/window_list.h b/include/freerdp/rail/window_list.h new file mode 100644 index 000000000..0d0311581 --- /dev/null +++ b/include/freerdp/rail/window_list.h @@ -0,0 +1,44 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RAIL Window List + * + * Copyright 2011 Marc-Andre Moreau + * + * 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 __WINDOW_LIST_H +#define __WINDOW_LIST_H + +#include +#include +#include + +#include + +typedef struct rdp_window_list rdpWindowList; + +struct rdp_window_list +{ + rdpWindow* head; + rdpWindow* tail; +}; + +void window_list_create(rdpWindowList* list, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state); +void window_list_update(rdpWindowList* list, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state); +void window_list_delete(rdpWindowList* list, WINDOW_ORDER_INFO* orderInfo); + +rdpWindowList* window_list_new(); +void window_list_free(rdpWindowList* list); + +#endif /* __WINDOW_LIST_H */ diff --git a/include/freerdp/update.h b/include/freerdp/update.h index 4744c20ef..0ab823efe 100644 --- a/include/freerdp/update.h +++ b/include/freerdp/update.h @@ -833,6 +833,40 @@ typedef struct _SURFACE_BITS_COMMAND SURFACE_BITS_COMMAND; #define SCREEN_BITMAP_SURFACE 0xFFFF +/* Window Order Header Flags */ +#define WINDOW_ORDER_TYPE_WINDOW 0x01000000 +#define WINDOW_ORDER_TYPE_NOTIFY 0x02000000 +#define WINDOW_ORDER_TYPE_DESKTOP 0x04000000 +#define WINDOW_ORDER_STATE_NEW 0x10000000 +#define WINDOW_ORDER_STATE_DELETED 0x20000000 +#define WINDOW_ORDER_FIELD_OWNER 0x00000002 +#define WINDOW_ORDER_FIELD_STYLE 0x00000008 +#define WINDOW_ORDER_FIELD_SHOW 0x00000010 +#define WINDOW_ORDER_FIELD_TITLE 0x00000004 +#define WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET 0x00004000 +#define WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE 0x00010000 +#define WINDOW_ORDER_FIELD_RP_CONTENT 0x00020000 +#define WINDOW_ORDER_FIELD_ROOT_PARENT 0x00040000 +#define WINDOW_ORDER_FIELD_WND_OFFSET 0x00000800 +#define WINDOW_ORDER_FIELD_WND_CLIENT_DELTA 0x00008000 +#define WINDOW_ORDER_FIELD_WND_SIZE 0x00000400 +#define WINDOW_ORDER_FIELD_WND_RECTS 0x00000100 +#define WINDOW_ORDER_FIELD_VIS_OFFSET 0x00001000 +#define WINDOW_ORDER_FIELD_VISIBILITY 0x00000200 +#define WINDOW_ORDER_FIELD_ICON_BIG 0x00002000 +#define WINDOW_ORDER_ICON 0x40000000 +#define WINDOW_ORDER_CACHED_ICON 0x80000000 +#define WINDOW_ORDER_FIELD_NOTIFY_VERSION 0x00000008 +#define WINDOW_ORDER_FIELD_NOTIFY_TIP 0x00000001 +#define WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP 0x00000002 +#define WINDOW_ORDER_FIELD_NOTIFY_STATE 0x00000004 +#define WINDOW_ORDER_FIELD_DESKTOP_NONE 0x00000001 +#define WINDOW_ORDER_FIELD_DESKTOP_HOOKED 0x00000002 +#define WINDOW_ORDER_FIELD_DESKTOP_ARC_COMPLETED 0x00000004 +#define WINDOW_ORDER_FIELD_DESKTOP_ARC_BEGAN 0x00000008 +#define WINDOW_ORDER_FIELD_DESKTOP_ZORDER 0x00000010 +#define WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND 0x00000020 + /* Update Interface */ typedef struct rdp_update rdpUpdate; @@ -888,12 +922,14 @@ typedef void (*pcDrawGdiPlusCacheFirst)(rdpUpdate* update, DRAW_GDIPLUS_CACHE_FI typedef void (*pcDrawGdiPlusCacheNext)(rdpUpdate* update, DRAW_GDIPLUS_CACHE_NEXT_ORDER* draw_gdiplus_cache_next); typedef void (*pcDrawGdiPlusCacheEnd)(rdpUpdate* update, DRAW_GDIPLUS_CACHE_END_ORDER* draw_gdiplus_cache_end); -typedef void (*pcWindowState)(rdpUpdate* update, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state); +typedef void (*pcWindowCreate)(rdpUpdate* update, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state); +typedef void (*pcWindowUpdate)(rdpUpdate* update, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state); typedef void (*pcWindowIcon)(rdpUpdate* update, WINDOW_ORDER_INFO* orderInfo, WINDOW_ICON_ORDER* window_icon); typedef void (*pcWindowCachedIcon)(rdpUpdate* update, WINDOW_ORDER_INFO* orderInfo, WINDOW_CACHED_ICON_ORDER* window_cached_icon); -typedef void (*pcWindowDeleted)(rdpUpdate* update, WINDOW_ORDER_INFO* orderInfo); -typedef void (*pcNotifyIconState)(rdpUpdate* update, WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notify_icon_state); -typedef void (*pcNotifyIconDeleted)(rdpUpdate* update, WINDOW_ORDER_INFO* orderInfo); +typedef void (*pcWindowDelete)(rdpUpdate* update, WINDOW_ORDER_INFO* orderInfo); +typedef void (*pcNotifyIconCreate)(rdpUpdate* update, WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notify_icon_state); +typedef void (*pcNotifyIconUpdate)(rdpUpdate* update, WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notify_icon_state); +typedef void (*pcNotifyIconDelete)(rdpUpdate* update, WINDOW_ORDER_INFO* orderInfo); typedef void (*pcMonitoredDesktop)(rdpUpdate* update, WINDOW_ORDER_INFO* orderInfo, MONITORED_DESKTOP_ORDER* monitored_desktop); typedef void (*pcNonMonitoredDesktop)(rdpUpdate* update, WINDOW_ORDER_INFO* orderInfo); @@ -903,6 +939,7 @@ struct rdp_update { void* rdp; void* gdi; + void* rail; void* param1; void* param2; @@ -958,12 +995,14 @@ struct rdp_update pcDrawGdiPlusCacheNext DrawGdiPlusCacheNext; pcDrawGdiPlusCacheEnd DrawGdiPlusCacheEnd; - pcWindowState WindowState; + pcWindowCreate WindowCreate; + pcWindowUpdate WindowUpdate; pcWindowIcon WindowIcon; pcWindowCachedIcon WindowCachedIcon; - pcWindowDeleted WindowDeleted; - pcNotifyIconState NotifyIconState; - pcNotifyIconDeleted NotifyIconDeleted; + pcWindowDelete WindowDelete; + pcNotifyIconCreate NotifyIconCreate; + pcNotifyIconUpdate NotifyIconUpdate; + pcNotifyIconDelete NotifyIconDelete; pcMonitoredDesktop MonitoredDesktop; pcNonMonitoredDesktop NonMonitoredDesktop; diff --git a/libfreerdp-chanman/libchanman.c b/libfreerdp-chanman/libchanman.c index d7eeca737..40e3117ad 100644 --- a/libfreerdp-chanman/libchanman.c +++ b/libfreerdp-chanman/libchanman.c @@ -67,6 +67,14 @@ struct chan_data PCHANNEL_OPEN_EVENT_FN open_event_proc; }; +struct sync_data +{ + void* data; + uint32 data_length; + void* user_data; + int index; +}; + typedef struct rdp_init_handle rdpInitHandle; struct rdp_init_handle { @@ -104,11 +112,8 @@ struct rdp_chan_man struct wait_obj* signal; /* used for sync write */ - freerdp_sem sync_data_sem; - void* sync_data; - uint32 sync_data_length; - void* sync_user_data; - int sync_index; + freerdp_mutex sync_data_mutex; + LIST* sync_data_list; /* used for sync event */ freerdp_sem event_sem; @@ -424,6 +429,7 @@ static uint32 FREERDP_CC MyVirtualChannelWrite(uint32 openHandle, void* pData, u { rdpChanMan* chan_man; struct chan_data* lchan; + struct sync_data* item; int index; chan_man = freerdp_chanman_find_by_open_handle(openHandle, &index); @@ -453,19 +459,24 @@ static uint32 FREERDP_CC MyVirtualChannelWrite(uint32 openHandle, void* pData, u DEBUG_CHANMAN("error not open"); return CHANNEL_RC_NOT_OPEN; } - freerdp_sem_wait(chan_man->sync_data_sem); /* lock chan_man->sync* vars */ + freerdp_mutex_lock(chan_man->sync_data_mutex); /* lock chan_man->sync* vars */ if (!chan_man->is_connected) { - freerdp_sem_signal(chan_man->sync_data_sem); + freerdp_mutex_unlock(chan_man->sync_data_mutex); DEBUG_CHANMAN("error not connected"); return CHANNEL_RC_NOT_CONNECTED; } - chan_man->sync_data = pData; - chan_man->sync_data_length = dataLength; - chan_man->sync_user_data = pUserData; - chan_man->sync_index = index; + item = xnew(struct sync_data); + item->data = pData; + item->data_length = dataLength; + item->user_data = pUserData; + item->index = index; + list_enqueue(chan_man->sync_data_list, item); + freerdp_mutex_unlock(chan_man->sync_data_mutex); + /* set the event */ wait_obj_set(chan_man->signal); + return CHANNEL_RC_OK; } @@ -544,7 +555,9 @@ rdpChanMan* freerdp_chanman_new(void) chan_man = xnew(rdpChanMan); - chan_man->sync_data_sem = freerdp_sem_new(1); + chan_man->sync_data_mutex = freerdp_mutex_new(); + chan_man->sync_data_list = list_new(); + chan_man->event_sem = freerdp_sem_new(1); chan_man->signal = wait_obj_new(); @@ -565,7 +578,9 @@ void freerdp_chanman_free(rdpChanMan * chan_man) rdpChanManList * list; rdpChanManList * prev; - freerdp_sem_free(chan_man->sync_data_sem); + freerdp_mutex_free(chan_man->sync_data_mutex); + list_free(chan_man->sync_data_list); + freerdp_sem_free(chan_man->event_sem); wait_obj_free(chan_man->signal); @@ -812,37 +827,30 @@ FREERDP_API int freerdp_chanman_send_event(rdpChanMan* chan_man, FRDP_EVENT* eve */ static void freerdp_chanman_process_sync(rdpChanMan* chan_man, freerdp* instance) { - void* ldata; - uint32 ldata_len; - void* luser_data; - int lindex; struct chan_data* lchan_data; struct rdp_chan* lrdp_chan; + struct sync_data* item; - if (chan_man->sync_data == NULL) - return; + while (chan_man->sync_data_list->head != NULL) + { + freerdp_mutex_lock(chan_man->sync_data_mutex); + item = (struct sync_data*)list_dequeue(chan_man->sync_data_list); + freerdp_mutex_unlock(chan_man->sync_data_mutex); - ldata = chan_man->sync_data; - ldata_len = chan_man->sync_data_length; - luser_data = chan_man->sync_user_data; - lindex = chan_man->sync_index; - chan_man->sync_data = NULL; - chan_man->sync_data_length = 0; - chan_man->sync_user_data = NULL; - chan_man->sync_index = 0; - freerdp_sem_signal(chan_man->sync_data_sem); /* release chan_man->sync* vars */ - lchan_data = chan_man->chans + lindex; - lrdp_chan = freerdp_chanman_find_rdp_chan_by_name(chan_man, instance->settings, - lchan_data->name, &lindex); - if (lrdp_chan != 0) - { - IFCALL(instance->SendChannelData, instance, lrdp_chan->chan_id, ldata, ldata_len); - } - if (lchan_data->open_event_proc != 0) - { - lchan_data->open_event_proc(lchan_data->open_handle, - CHANNEL_EVENT_WRITE_COMPLETE, - luser_data, sizeof(void *), sizeof(void *), 0); + lchan_data = chan_man->chans + item->index; + lrdp_chan = freerdp_chanman_find_rdp_chan_by_name(chan_man, instance->settings, + lchan_data->name, &item->index); + if (lrdp_chan != NULL) + { + IFCALL(instance->SendChannelData, instance, lrdp_chan->chan_id, item->data, item->data_length); + } + if (lchan_data->open_event_proc != 0) + { + lchan_data->open_event_proc(lchan_data->open_handle, + CHANNEL_EVENT_WRITE_COMPLETE, + item->user_data, sizeof(void *), sizeof(void *), 0); + } + xfree(item); } } diff --git a/libfreerdp-core/crypto.h b/libfreerdp-core/crypto.h index 5b3826351..ebff96289 100644 --- a/libfreerdp-core/crypto.h +++ b/libfreerdp-core/crypto.h @@ -20,6 +20,10 @@ #ifndef __CRYPTO_H #define __CRYPTO_H +#ifdef _WIN32 +#include +#endif + #include #include #include diff --git a/libfreerdp-core/fastpath.c b/libfreerdp-core/fastpath.c index 31d8f3f8c..a96b94239 100644 --- a/libfreerdp-core/fastpath.c +++ b/libfreerdp-core/fastpath.c @@ -22,6 +22,9 @@ #include #include +#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; diff --git a/libfreerdp-core/fastpath.h b/libfreerdp-core/fastpath.h index 20111e447..c1df080d6 100644 --- a/libfreerdp-core/fastpath.h +++ b/libfreerdp-core/fastpath.h @@ -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); diff --git a/libfreerdp-core/input.c b/libfreerdp-core/input.c index 72f6daefa..fca754f96 100644 --- a/libfreerdp-core/input.c +++ b/libfreerdp-core/input.c @@ -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; diff --git a/libfreerdp-core/input.h b/libfreerdp-core/input.h index da042f0c6..a61b0683c 100644 --- a/libfreerdp-core/input.h +++ b/libfreerdp-core/input.h @@ -21,12 +21,31 @@ #define __INPUT_H #include "rdp.h" +#include "fastpath.h" #include #include #include #include +/* 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); diff --git a/libfreerdp-core/settings.c b/libfreerdp-core/settings.c index f77d59656..c1d57be18 100644 --- a/libfreerdp-core/settings.c +++ b/libfreerdp-core/settings.c @@ -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); } diff --git a/libfreerdp-core/tcp.c b/libfreerdp-core/tcp.c index 2b8dc5516..8961bdd16 100644 --- a/libfreerdp-core/tcp.c +++ b/libfreerdp-core/tcp.c @@ -23,13 +23,16 @@ #include #include #include -#include #include #include #include #include #include +#ifndef _WIN32 +#include +#endif + #include #include #include diff --git a/libfreerdp-core/tls.h b/libfreerdp-core/tls.h index 94ab35be0..c777a6d84 100644 --- a/libfreerdp-core/tls.h +++ b/libfreerdp-core/tls.h @@ -20,11 +20,11 @@ #ifndef __TLS_H #define __TLS_H +#include "crypto.h" + #include #include -#include "crypto.h" - #include #include diff --git a/libfreerdp-core/window.c b/libfreerdp-core/window.c index 9f272bc8c..8ab01a33d 100644 --- a/libfreerdp-core/window.c +++ b/libfreerdp-core/window.c @@ -210,13 +210,17 @@ void update_recv_window_info_order(rdpUpdate* update, STREAM* s, WINDOW_ORDER_IN { DEBUG_WND("Window Deleted Order"); update_read_window_deleted_order(s, orderInfo); - IFCALL(update->WindowDeleted, update, orderInfo); + IFCALL(update->WindowDelete, update, orderInfo); } else { DEBUG_WND("Window State Order"); update_read_window_state_order(s, orderInfo, &update->window_state); - IFCALL(update->WindowState, update, orderInfo, &update->window_state); + + if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW) + IFCALL(update->WindowCreate, update, orderInfo, &update->window_state); + else + IFCALL(update->WindowUpdate, update, orderInfo, &update->window_state); } } @@ -253,15 +257,19 @@ void update_recv_notification_icon_info_order(rdpUpdate* update, STREAM* s, WIND if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_DELETED) { - DEBUG_WND("Deleted Notification Icon Deleted Order"); + DEBUG_WND("Delete Notification Icon Deleted Order"); update_read_notification_icon_deleted_order(s, orderInfo); - IFCALL(update->NotifyIconDeleted, update, orderInfo); + IFCALL(update->NotifyIconDelete, update, orderInfo); } else { DEBUG_WND("Notification Icon State Order"); update_read_notification_icon_state_order(s, orderInfo, &update->notify_icon_state); - IFCALL(update->NotifyIconState, update, orderInfo, &update->notify_icon_state); + + if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW) + IFCALL(update->NotifyIconCreate, update, orderInfo, &update->notify_icon_state); + else + IFCALL(update->NotifyIconUpdate, update, orderInfo, &update->notify_icon_state); } } diff --git a/libfreerdp-core/window.h b/libfreerdp-core/window.h index fee4f6d8f..3ee0dff97 100644 --- a/libfreerdp-core/window.h +++ b/libfreerdp-core/window.h @@ -25,40 +25,6 @@ #include -/* Window Order Header Flags */ -#define WINDOW_ORDER_TYPE_WINDOW 0x01000000 -#define WINDOW_ORDER_TYPE_NOTIFY 0x02000000 -#define WINDOW_ORDER_TYPE_DESKTOP 0x04000000 -#define WINDOW_ORDER_STATE_NEW 0x10000000 -#define WINDOW_ORDER_STATE_DELETED 0x20000000 -#define WINDOW_ORDER_FIELD_OWNER 0x00000002 -#define WINDOW_ORDER_FIELD_STYLE 0x00000008 -#define WINDOW_ORDER_FIELD_SHOW 0x00000010 -#define WINDOW_ORDER_FIELD_TITLE 0x00000004 -#define WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET 0x00004000 -#define WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE 0x00010000 -#define WINDOW_ORDER_FIELD_RP_CONTENT 0x00020000 -#define WINDOW_ORDER_FIELD_ROOT_PARENT 0x00040000 -#define WINDOW_ORDER_FIELD_WND_OFFSET 0x00000800 -#define WINDOW_ORDER_FIELD_WND_CLIENT_DELTA 0x00008000 -#define WINDOW_ORDER_FIELD_WND_SIZE 0x00000400 -#define WINDOW_ORDER_FIELD_WND_RECTS 0x00000100 -#define WINDOW_ORDER_FIELD_VIS_OFFSET 0x00001000 -#define WINDOW_ORDER_FIELD_VISIBILITY 0x00000200 -#define WINDOW_ORDER_FIELD_ICON_BIG 0x00002000 -#define WINDOW_ORDER_ICON 0x40000000 -#define WINDOW_ORDER_CACHED_ICON 0x80000000 -#define WINDOW_ORDER_FIELD_NOTIFY_VERSION 0x00000008 -#define WINDOW_ORDER_FIELD_NOTIFY_TIP 0x00000001 -#define WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP 0x00000002 -#define WINDOW_ORDER_FIELD_NOTIFY_STATE 0x00000004 -#define WINDOW_ORDER_FIELD_DESKTOP_NONE 0x00000001 -#define WINDOW_ORDER_FIELD_DESKTOP_HOOKED 0x00000002 -#define WINDOW_ORDER_FIELD_DESKTOP_ARC_COMPLETED 0x00000004 -#define WINDOW_ORDER_FIELD_DESKTOP_ARC_BEGAN 0x00000008 -#define WINDOW_ORDER_FIELD_DESKTOP_ZORDER 0x00000010 -#define WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND 0x00000020 - void update_recv_altsec_window_order(rdpUpdate* update, STREAM* s); #ifdef WITH_DEBUG_WND diff --git a/libfreerdp-rail/CMakeLists.txt b/libfreerdp-rail/CMakeLists.txt new file mode 100644 index 000000000..b4140fc8c --- /dev/null +++ b/libfreerdp-rail/CMakeLists.txt @@ -0,0 +1,29 @@ +# FreeRDP: A Remote Desktop Protocol Client +# libfreerdp-rail cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# 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. + +set(FREERDP_RAIL_SRCS + window_list.c + window.c + rail.c) + +add_library(freerdp-rail SHARED ${FREERDP_RAIL_SRCS}) + +set_target_properties(freerdp-rail PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION}) + +install(TARGETS freerdp-rail DESTINATION lib) diff --git a/libfreerdp-rail/rail.c b/libfreerdp-rail/rail.c new file mode 100644 index 000000000..d8f35d11b --- /dev/null +++ b/libfreerdp-rail/rail.c @@ -0,0 +1,73 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Remote Applications Integrated Locally (RAIL) + * + * Copyright 2011 Marc-Andre Moreau + * + * 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. + */ + +#include +#include + +#include + +static void rail_WindowCreate(rdpUpdate* update, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state) +{ + rdpRail* rail; + rail = (rdpRail*) update->rail; + window_list_create(rail->list, orderInfo, window_state); +} + +static void rail_WindowUpdate(rdpUpdate* update, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state) +{ + rdpRail* rail; + rail = (rdpRail*) update->rail; + window_list_update(rail->list, orderInfo, window_state); +} + +static void rail_WindowDelete(rdpUpdate* update, WINDOW_ORDER_INFO* orderInfo) +{ + rdpRail* rail; + rail = (rdpRail*) update->rail; + window_list_delete(rail->list, orderInfo); +} + +void rail_register_update_callbacks(rdpRail* rail, rdpUpdate* update) +{ + update->WindowCreate = rail_WindowCreate; + update->WindowUpdate = rail_WindowUpdate; + update->WindowDelete = rail_WindowDelete; +} + +rdpRail* rail_new() +{ + rdpRail* rail; + + rail = (rdpRail*) xzalloc(sizeof(rdpRail)); + + if (rail != NULL) + { + rail->list = window_list_new(); + } + + return rail; +} + +void rail_free(rdpRail* rail) +{ + if (rail != NULL) + { + xfree(rail); + } +} diff --git a/libfreerdp-rail/window.c b/libfreerdp-rail/window.c new file mode 100644 index 000000000..2a3574a27 --- /dev/null +++ b/libfreerdp-rail/window.c @@ -0,0 +1,126 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RAIL Windows + * + * Copyright 2011 Marc-Andre Moreau + * + * 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. + */ + +#include +#include + +#include + +void window_state_update(rdpWindow* window, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state) +{ + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_OWNER) + { + window->ownerWindowId = window_state->ownerWindowId; + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_STYLE) + { + window->style = window_state->style; + window->extendedStyle = window_state->extendedStyle; + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_SHOW) + { + window->showState = window_state->showState; + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TITLE) + { + window->clientOffsetX = window_state->clientOffsetX; + window->clientOffsetY = window_state->clientOffsetY; + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) + { + window->clientOffsetX = window_state->clientOffsetX; + window->clientOffsetY = window_state->clientOffsetY; + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE) + { + window->clientAreaWidth = window_state->clientAreaWidth; + window->clientAreaHeight = window_state->clientAreaHeight; + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT) + { + window->RPContent = window_state->RPContent; + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT) + { + window->rootParentHandle = window_state->rootParentHandle; + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) + { + window->windowOffsetX = window_state->windowOffsetX; + window->windowOffsetY = window_state->windowOffsetY; + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA) + { + window->windowClientDeltaX = window_state->windowClientDeltaX; + window->windowClientDeltaY = window_state->windowClientDeltaY; + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE) + { + window->windowWidth = window_state->windowWidth; + window->windowHeight = window_state->windowHeight; + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS) + { + + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET) + { + window->visibleOffsetX = window_state->visibleOffsetX; + window->visibleOffsetY = window_state->visibleOffsetY; + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY) + { + + } +} + +rdpWindow* rail_CreateWindow(uint32 windowId) +{ + rdpWindow* window; + + window = (rdpWindow*) xzalloc(sizeof(rdpWindow)); + + if (window != NULL) + { + window->windowId = windowId; + } + + return window; +} + +void rail_DestroyWindow(rdpWindow* window) +{ + if (window != NULL) + { + xfree(window); + } +} diff --git a/libfreerdp-rail/window_list.c b/libfreerdp-rail/window_list.c new file mode 100644 index 000000000..af3c423dd --- /dev/null +++ b/libfreerdp-rail/window_list.c @@ -0,0 +1,138 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RAIL Window List + * + * Copyright 2011 Marc-Andre Moreau + * + * 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. + */ + +#include +#include + +#include + +rdpWindow* window_list_get_by_id(rdpWindowList* list, uint32 windowId) +{ + rdpWindow* window; + + window = list->head; + + if (window == NULL) + return NULL; + + while (window->next != NULL) + { + if (window->windowId == windowId) + return window; + + window = window->next; + } + + return NULL; +} + +void window_list_create(rdpWindowList* list, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state) +{ + rdpWindow* window; + + window = rail_CreateWindow(orderInfo->windowId); + + if (list->head == NULL) + { + list->head = list->tail = window; + window->prev = NULL; + window->next = NULL; + } + else + { + window->prev = list->tail; + window->next = NULL; + list->tail = window; + } + + window->windowId = orderInfo->windowId; + + window_state_update(window, orderInfo, window_state); +} + +void window_list_update(rdpWindowList* list, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state) +{ + rdpWindow* window; + + window = window_list_get_by_id(list, orderInfo->windowId); + + if (window == NULL) + return; + + window_state_update(window, orderInfo, window_state); +} + +void window_list_delete(rdpWindowList* list, WINDOW_ORDER_INFO* orderInfo) +{ + rdpWindow* prev; + rdpWindow* next; + rdpWindow* window; + + window = window_list_get_by_id(list, orderInfo->windowId); + + if (window == NULL) + return; + + prev = window->prev; + next = window->next; + + if (prev != NULL) + prev->next = next; + + if (next != NULL) + next->prev = prev; + + if (list->head == list->tail) + { + list->head = list->tail = NULL; + } + else + { + if (list->head == window) + list->head = next; + + if (list->tail == window) + list->tail = prev; + } + + rail_DestroyWindow(window); +} + +rdpWindowList* window_list_new() +{ + rdpWindowList* list; + + list = (rdpWindowList*) xzalloc(sizeof(rdpWindowList)); + + if (list != NULL) + { + list->head = NULL; + list->tail = NULL; + } + + return list; +} + +void window_list_free(rdpWindowList* list) +{ + if (list != NULL) + { + xfree(list); + } +} diff --git a/libfreerdp-utils/args.c b/libfreerdp-utils/args.c index 01ad2a9eb..340ac461c 100644 --- a/libfreerdp-utils/args.c +++ b/libfreerdp-utils/args.c @@ -175,10 +175,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) { diff --git a/libfreerdp-utils/svc_plugin.c b/libfreerdp-utils/svc_plugin.c index fbd7d1557..66c1d92af 100644 --- a/libfreerdp-utils/svc_plugin.c +++ b/libfreerdp-utils/svc_plugin.c @@ -283,8 +283,9 @@ static void svc_plugin_process_connected(rdpSvcPlugin* plugin, void* pData, uint { uint32 error; - error = plugin->channel_entry_points.pVirtualChannelOpen(plugin->priv->init_handle, &plugin->priv->open_handle, - plugin->channel_def.name, svc_plugin_open_event); + error = plugin->channel_entry_points.pVirtualChannelOpen(plugin->priv->init_handle, + &plugin->priv->open_handle, plugin->channel_def.name, svc_plugin_open_event); + if (error != CHANNEL_RC_OK) { printf("svc_plugin_process_connected: open failed\n"); diff --git a/libfreerdp-utils/thread.c b/libfreerdp-utils/thread.c index 24eb82d25..0964b3ba4 100644 --- a/libfreerdp-utils/thread.c +++ b/libfreerdp-utils/thread.c @@ -26,6 +26,12 @@ #ifdef _WIN32 #include + +struct timespec +{ + uint64 tv_sec; + uint64 tv_nsec; +}; #endif freerdp_thread* freerdp_thread_new(void) @@ -61,17 +67,27 @@ void freerdp_thread_start(freerdp_thread* thread, void* func, void* arg) void freerdp_thread_stop(freerdp_thread* thread) { - struct timespec ts; - int i; + int i = 0; - wait_obj_set(thread->signals[0]); - i = 0; +#ifndef _WIN32 + struct timespec ts; ts.tv_sec = 0; ts.tv_nsec = 10000000; +#else + DWORD dwMilliseconds; + dwMilliseconds = 10000; +#endif + + wait_obj_set(thread->signals[0]); + while (thread->status > 0 && i < 1000) { i++; +#ifndef _WIN32 nanosleep(&ts, NULL); +#else + SleepEx(dwMilliseconds, 0); +#endif } for (i = 0; i < thread->num_signals; i++) diff --git a/libfreerdp-utils/wait_obj.c b/libfreerdp-utils/wait_obj.c index c28899a97..190192d16 100644 --- a/libfreerdp-utils/wait_obj.c +++ b/libfreerdp-utils/wait_obj.c @@ -133,7 +133,7 @@ void wait_obj_clear(struct wait_obj* obj) { #ifdef _WIN32 - ResetEvent(chan_man->chan_event); + ResetEvent(obj->event); #else int len; @@ -149,13 +149,15 @@ wait_obj_clear(struct wait_obj* obj) int wait_obj_select(struct wait_obj** listobj, int numobj, int timeout) { +#ifndef _WIN32 int max; - int rv; - int index; int sock; - struct timeval time; - struct timeval * ptime; + int index; +#endif fd_set fds; + int status; + struct timeval time; + struct timeval* ptime; ptime = 0; if (timeout >= 0) @@ -164,6 +166,8 @@ wait_obj_select(struct wait_obj** listobj, int numobj, int timeout) time.tv_usec = (timeout * 1000) % 1000000; ptime = &time; } + +#ifndef _WIN32 max = 0; FD_ZERO(&fds); if (listobj) @@ -172,14 +176,17 @@ wait_obj_select(struct wait_obj** listobj, int numobj, int timeout) { sock = listobj[index]->pipe_fd[0]; FD_SET(sock, &fds); + if (sock > max) - { max = sock; - } } } - rv = select(max + 1, &fds, 0, 0, ptime); - return rv; + status = select(max + 1, &fds, 0, 0, ptime); +#else + status = select(0, &fds, 0, 0, ptime); +#endif + + return status; } void wait_obj_get_fds(struct wait_obj* obj, void** fds, int* count)