diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c index b70feb00e..bf623f8a8 100644 --- a/client/X11/xf_rail.c +++ b/client/X11/xf_rail.c @@ -17,8 +17,45 @@ * limitations under the License. */ +#include +#include "xf_window.h" + #include "xf_rail.h" +void xf_rail_paint(xfInfo* xfi, rdpRail* rail) +{ + xfWindow* xfw; + rdpWindow* window; + window_list_rewind(rail->list); + + while (window_list_has_next(rail->list)) + { + window = window_list_get_next(rail->list); + xfw = (xfWindow*) window->extra; + + printf("painting window 0x%08X\n", window->windowId); + + XCopyArea(xfi->display, xfi->window->handle, xfw->handle, xfw->gc, + window->clientOffsetX, window->clientOffsetY, + window->windowWidth, window->windowHeight, 0, 0); + + XFlush(xfi->display); + } +} + +void xf_rail_CreateWindow(rdpRail* rail, rdpWindow* window) +{ + xfWindow* xfw; + xfw = xf_CreateWindow((xfInfo*) rail->extra, window->windowWidth, window->windowHeight, "RAIL"); + window->extra = (void*) xfw; +} + +void xf_rail_register_callbacks(xfInfo* xfi, rdpRail* rail) +{ + rail->extra = (void*) xfi; + rail->CreateWindow = xf_rail_CreateWindow; +} + void xf_process_rail_event(rdpChanMan* chanman, freerdp* instance) { diff --git a/client/X11/xf_rail.h b/client/X11/xf_rail.h index 83b70d57f..78bd407a3 100644 --- a/client/X11/xf_rail.h +++ b/client/X11/xf_rail.h @@ -22,6 +22,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); #endif /* __XF_RAIL_H */ diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c index ae607e97a..5c4b1ffd9 100644 --- a/client/X11/xf_window.c +++ b/client/X11/xf_window.c @@ -128,6 +128,71 @@ xfWindow* window_create(xfInfo* xfi, char* name) return window; } +xfWindow* xf_CreateWindow(xfInfo* xfi, int width, int height, char* name) +{ + xfWindow* window; + + window = (xfWindow*) xzalloc(sizeof(xfWindow)); + + window->width = width; + window->height = height; + + if (window != NULL) + { + XGCValues gcv; + int input_mask; + XSizeHints* size_hints; + XClassHint* class_hints; + + window->decorations = True; + window->fullscreen = False; + + window->handle = XCreateWindow(xfi->display, RootWindowOfScreen(xfi->screen), + 0, 0, window->width, window->height, 0, xfi->depth, InputOutput, xfi->visual, + CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap | + CWBorderPixel, &xfi->attribs); + + window_show_decorations(xfi, window, window->decorations); + + class_hints = XAllocClassHint(); + + if (class_hints != NULL) + { + if (name != NULL) + class_hints->res_name = name; + + class_hints->res_class = "freerdp"; + XSetClassHint(xfi->display, window->handle, class_hints); + XFree(class_hints); + } + + size_hints = XAllocSizeHints(); + + if (size_hints) + { + size_hints->flags = PMinSize | PMaxSize; + size_hints->min_width = size_hints->max_width = window->width; + size_hints->min_height = size_hints->max_height = window->height; + XSetWMNormalHints(xfi->display, window->handle, size_hints); + XFree(size_hints); + } + + input_mask = + KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | + VisibilityChangeMask | FocusChangeMask | StructureNotifyMask | + PointerMotionMask | ExposureMask; + + XSelectInput(xfi->display, window->handle, input_mask); + XMapWindow(xfi->display, window->handle); + + memset(&gcv, 0, sizeof(gcv)); + window->gc = XCreateGC(xfi->display, window->handle, GCGraphicsExposures, &gcv); + window->surface = XCreatePixmap(xfi->display, window->handle, window->width, window->height, xfi->depth); + } + + return window; +} + void window_destroy(xfInfo* xfi, xfWindow* window) { XDestroyWindow(xfi->display, window->handle); diff --git a/client/X11/xf_window.h b/client/X11/xf_window.h index b8e564a82..e3383f8f0 100644 --- a/client/X11/xf_window.h +++ b/client/X11/xf_window.h @@ -30,9 +30,11 @@ typedef struct xf_window xfWindow; struct xf_window { + GC gc; int width; int height; Window handle; + Pixmap surface; boolean fullscreen; boolean decorations; }; @@ -43,4 +45,6 @@ void window_show_decorations(xfInfo* xfi, xfWindow* window, boolean show); xfWindow* window_create(xfInfo* xfi, char* name); void window_destroy(xfInfo* xfi, xfWindow* window); +xfWindow* xf_CreateWindow(xfInfo* xfi, int width, int height, char* name); + #endif /* __XF_WINDOW_H */ diff --git a/client/X11/xfreerdp.c b/client/X11/xfreerdp.c index cdb827d70..feb4a75f7 100644 --- a/client/X11/xfreerdp.c +++ b/client/X11/xfreerdp.c @@ -74,6 +74,8 @@ void xf_end_paint(rdpUpdate* update) XPutImage(xfi->display, xfi->primary, xfi->gc_default, xfi->image, x, y, x, y, w, h); XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc_default, x, y, w, h, x, y); XFlush(xfi->display); + + xf_rail_paint(xfi, update->rail); } boolean xf_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount) @@ -313,6 +315,7 @@ boolean xf_post_connect(freerdp* instance) instance->update->rail = (void*) rail_new(); rail_register_update_callbacks((rdpRail*) instance->update->rail, instance->update); + xf_rail_register_callbacks(xfi, (rdpRail*) instance->update->rail); freerdp_chanman_post_connect(GET_CHANMAN(instance), instance); diff --git a/include/freerdp/rail/rail.h b/include/freerdp/rail/rail.h index 8e4ecd203..14528dc38 100644 --- a/include/freerdp/rail/rail.h +++ b/include/freerdp/rail/rail.h @@ -31,9 +31,13 @@ typedef struct rdp_rail rdpRail; #include #include +typedef void (*railCreateWindow)(rdpRail* rail, rdpWindow* window); + struct rdp_rail { + void* extra; rdpWindowList* list; + railCreateWindow CreateWindow; }; FREERDP_API void rail_register_update_callbacks(rdpRail* rail, rdpUpdate* update); diff --git a/include/freerdp/rail/window.h b/include/freerdp/rail/window.h index 626d88ee2..221e5833c 100644 --- a/include/freerdp/rail/window.h +++ b/include/freerdp/rail/window.h @@ -28,8 +28,11 @@ typedef struct rdp_window rdpWindow; +#include + struct rdp_window { + void* extra; rdpWindow* prev; rdpWindow* next; uint32 windowId; @@ -60,7 +63,7 @@ struct rdp_window FREERDP_API void window_state_update(rdpWindow* window, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state); -FREERDP_API rdpWindow* rail_CreateWindow(uint32 windowId); -FREERDP_API void rail_DestroyWindow(rdpWindow* window); +FREERDP_API void rail_CreateWindow(rdpRail* rail, rdpWindow* window); +FREERDP_API void rail_DestroyWindow(rdpRail* rail, rdpWindow* window); #endif /* __WINDOW_H */ diff --git a/include/freerdp/rail/window_list.h b/include/freerdp/rail/window_list.h index a964970ea..982c37ad1 100644 --- a/include/freerdp/rail/window_list.h +++ b/include/freerdp/rail/window_list.h @@ -25,21 +25,28 @@ #include #include -#include - typedef struct rdp_window_list rdpWindowList; +#include +#include + struct rdp_window_list { + rdpRail* rail; rdpWindow* head; rdpWindow* tail; + rdpWindow* iterator; }; +FREERDP_API void window_list_rewind(rdpWindowList* list); +FREERDP_API boolean window_list_has_next(rdpWindowList* list); +FREERDP_API rdpWindow* window_list_get_next(rdpWindowList* list); + FREERDP_API void window_list_create(rdpWindowList* list, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state); FREERDP_API void window_list_update(rdpWindowList* list, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state); FREERDP_API void window_list_delete(rdpWindowList* list, WINDOW_ORDER_INFO* orderInfo); -FREERDP_API rdpWindowList* window_list_new(); +FREERDP_API rdpWindowList* window_list_new(rdpRail* rail); FREERDP_API void window_list_free(rdpWindowList* list); #endif /* __WINDOW_LIST_H */ diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index e44795b7e..46cd98dd4 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -268,6 +268,7 @@ struct rdp_settings boolean remote_app; uint8 num_icon_caches; uint16 num_icon_cache_entries; + boolean rail_langbar_supported; boolean mouse_motion; }; diff --git a/libfreerdp-core/capabilities.c b/libfreerdp-core/capabilities.c index d6d83af98..3b2647317 100644 --- a/libfreerdp-core/capabilities.c +++ b/libfreerdp-core/capabilities.c @@ -1124,7 +1124,10 @@ void rdp_write_remote_programs_capability_set(STREAM* s, rdpSettings* settings) header = rdp_capability_set_start(s); - railSupportLevel = RAIL_LEVEL_SUPPORTED | RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED; + railSupportLevel = RAIL_LEVEL_SUPPORTED; + + if (settings->rail_langbar_supported) + railSupportLevel |= RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED; stream_write_uint32(s, railSupportLevel); /* railSupportLevel (4 bytes) */ diff --git a/libfreerdp-core/fastpath.c b/libfreerdp-core/fastpath.c index a96b94239..c06bab440 100644 --- a/libfreerdp-core/fastpath.c +++ b/libfreerdp-core/fastpath.c @@ -191,27 +191,27 @@ static void fastpath_recv_update(rdpFastPath* fastpath, uint8 updateCode, uint16 break; case FASTPATH_UPDATETYPE_PTR_NULL: - printf("FASTPATH_UPDATETYPE_PTR_NULL\n"); + //printf("FASTPATH_UPDATETYPE_PTR_NULL\n"); break; case FASTPATH_UPDATETYPE_PTR_DEFAULT: - printf("FASTPATH_UPDATETYPE_PTR_DEFAULT\n"); + //printf("FASTPATH_UPDATETYPE_PTR_DEFAULT\n"); break; case FASTPATH_UPDATETYPE_PTR_POSITION: - printf("FASTPATH_UPDATETYPE_PTR_POSITION\n"); + //printf("FASTPATH_UPDATETYPE_PTR_POSITION\n"); break; case FASTPATH_UPDATETYPE_COLOR: - printf("FASTPATH_UPDATETYPE_COLOR\n"); + //printf("FASTPATH_UPDATETYPE_COLOR\n"); break; case FASTPATH_UPDATETYPE_CACHED: - printf("FASTPATH_UPDATETYPE_CACHED\n"); + //printf("FASTPATH_UPDATETYPE_CACHED\n"); break; case FASTPATH_UPDATETYPE_POINTER: - printf("FASTPATH_UPDATETYPE_POINTER\n"); + //printf("FASTPATH_UPDATETYPE_POINTER\n"); break; default: diff --git a/libfreerdp-rail/rail.c b/libfreerdp-rail/rail.c index d8f35d11b..5fe1c197f 100644 --- a/libfreerdp-rail/rail.c +++ b/libfreerdp-rail/rail.c @@ -58,7 +58,7 @@ rdpRail* rail_new() if (rail != NULL) { - rail->list = window_list_new(); + rail->list = window_list_new(rail); } return rail; diff --git a/libfreerdp-rail/window.c b/libfreerdp-rail/window.c index 2a3574a27..c58358af3 100644 --- a/libfreerdp-rail/window.c +++ b/libfreerdp-rail/window.c @@ -103,21 +103,12 @@ void window_state_update(rdpWindow* window, WINDOW_ORDER_INFO* orderInfo, WINDOW } } -rdpWindow* rail_CreateWindow(uint32 windowId) +void rail_CreateWindow(rdpRail* rail, rdpWindow* window) { - rdpWindow* window; - - window = (rdpWindow*) xzalloc(sizeof(rdpWindow)); - - if (window != NULL) - { - window->windowId = windowId; - } - - return window; + IFCALL(rail->CreateWindow, rail, window); } -void rail_DestroyWindow(rdpWindow* window) +void rail_DestroyWindow(rdpRail* rail, rdpWindow* window) { if (window != NULL) { diff --git a/libfreerdp-rail/window_list.c b/libfreerdp-rail/window_list.c index af3c423dd..3941d46a3 100644 --- a/libfreerdp-rail/window_list.c +++ b/libfreerdp-rail/window_list.c @@ -22,6 +22,35 @@ #include +void window_list_rewind(rdpWindowList* list) +{ + list->iterator = list->head; +} + +boolean window_list_has_next(rdpWindowList* list) +{ + if (list->iterator != NULL) + { + if (list->iterator != NULL) + return True; + } + + return False; +} + +rdpWindow* window_list_get_next(rdpWindowList* list) +{ + rdpWindow* next = NULL; + + if (list->iterator != NULL) + { + next = list->iterator; + list->iterator = list->iterator->next; + } + + return next; +} + rdpWindow* window_list_get_by_id(rdpWindowList* list, uint32 windowId) { rdpWindow* window; @@ -46,7 +75,12 @@ void window_list_create(rdpWindowList* list, WINDOW_ORDER_INFO* orderInfo, WINDO { rdpWindow* window; - window = rail_CreateWindow(orderInfo->windowId); + window = (rdpWindow*) xzalloc(sizeof(rdpWindow)); + + if (window == NULL) + return; + + window->windowId = orderInfo->windowId; if (list->head == NULL) { @@ -64,6 +98,8 @@ void window_list_create(rdpWindowList* list, WINDOW_ORDER_INFO* orderInfo, WINDO window->windowId = orderInfo->windowId; window_state_update(window, orderInfo, window_state); + + rail_CreateWindow(list->rail, window); } void window_list_update(rdpWindowList* list, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state) @@ -111,10 +147,10 @@ void window_list_delete(rdpWindowList* list, WINDOW_ORDER_INFO* orderInfo) list->tail = prev; } - rail_DestroyWindow(window); + rail_DestroyWindow(list->rail, window); } -rdpWindowList* window_list_new() +rdpWindowList* window_list_new(rdpRail* rail) { rdpWindowList* list; @@ -124,6 +160,7 @@ rdpWindowList* window_list_new() { list->head = NULL; list->tail = NULL; + list->rail = rail; } return list; diff --git a/libfreerdp-utils/args.c b/libfreerdp-utils/args.c index 4673af4c2..b9fae60c4 100644 --- a/libfreerdp-utils/args.c +++ b/libfreerdp-utils/args.c @@ -196,6 +196,7 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv, else if (strcmp("--app", argv[index]) == 0) { settings->remote_app = True; + settings->rail_langbar_supported = True; } else if (strcmp("-x", argv[index]) == 0) {