diff --git a/client/X11/xf_event.c b/client/X11/xf_event.c index 11bc57c9d..01f5230aa 100644 --- a/client/X11/xf_event.c +++ b/client/X11/xf_event.c @@ -421,15 +421,36 @@ boolean xf_event_LeaveNotify(xfInfo* xfi, XEvent* event, boolean app) boolean xf_event_ConfigureNotify(xfInfo* xfi, XEvent* event, boolean app) { - xfWindow* xfw; rdpWindow* window; - window = window_list_get_by_extra_id(xfi->rail->list, (void*) event->xany.window); + printf( "ConfigureNotify event: send_event=%d eventWindow=0x%X window=0x%X above=0x%X x=%d y=%d " + "width=%d height=%d override_redirect=%d\n", + event->xconfigure.send_event, + (uint32)event->xconfigure.event, + (uint32)event->xconfigure.window, + (uint32)event->xconfigure.above, + event->xconfigure.x, + event->xconfigure.y, + event->xconfigure.width, + event->xconfigure.height, + event->xconfigure.override_redirect); + + window = window_list_get_by_extra_id(xfi->rail->list, (void*) event->xconfigure.window); if (window != NULL) { + xfWindow* xfw; xfw = (xfWindow*) window->extra; + if (xfw->isLocalMoveSizeModeEnabled) + { + uint32 left = event->xconfigure.x; + uint32 top = event->xconfigure.y; + uint32 right = event->xconfigure.y + event->xconfigure.width - 1; + uint32 bottom = event->xconfigure.y + event->xconfigure.height - 1; + + xf_rail_send_windowmove(xfi, window->windowId, left, top, right, bottom); + } XPutImage(xfi->display, xfi->primary, xfw->gc, xfi->image, xfw->left, xfw->top, xfw->left, xfw->top, xfw->width, xfw->height); @@ -476,7 +497,7 @@ boolean xf_event_process(freerdp* instance, XEvent* event) app = True; } -#if 0 +#if 1 if (event->type != MotionNotify) printf("X11 %s Event: wnd=0x%X\n", X11_EVENT_STRINGS[event->type], (uint32)event->xany.window); #endif diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c index ecad1ab74..212c48a28 100644 --- a/client/X11/xf_rail.c +++ b/client/X11/xf_rail.c @@ -219,6 +219,22 @@ static void xf_send_rail_client_event(rdpChanMan* chanman, uint16 event_type, vo } } +void xf_rail_send_windowmove(xfInfo* xfi, uint32 windowId, uint32 left, uint32 top, uint32 right, uint32 bottom) +{ + rdpChanMan* chanman; + RAIL_WINDOW_MOVE_ORDER window_move; + + chanman = GET_CHANMAN(xfi->instance); + + window_move.windowId = windowId; + window_move.left = left; + window_move.top = top; + window_move.right = right; + window_move.bottom = bottom; + + xf_send_rail_client_event(chanman, RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE, &window_move); +} + void xf_rail_send_activate(xfInfo* xfi, Window xwindow, boolean enabled) { rdpChanMan* chanman; @@ -315,14 +331,26 @@ void xf_process_rail_server_sysparam_event(xfInfo* xfi, rdpChanMan* chanman, RDP void xf_process_rail_server_minmaxinfo_event(xfInfo* xfi, rdpChanMan* chanman, RDP_EVENT* event) { RAIL_MINMAXINFO_ORDER* minmax = (RAIL_MINMAXINFO_ORDER*)event->user_data; + rdpWindow* rail_window = NULL; - printf("Server Min Max Info PDU: windowId=0x%X " - "maxWidth=%d maxHeight=%d maxPosX=%d maxPosY=%d " - "minTrackWidth=%d minTrackHeight=%d maxTrackWidth=%d maxTrackHeight=%d\n", - minmax->windowId, minmax->maxWidth, minmax->maxHeight, - (sint16)minmax->maxPosX, (sint16)minmax->maxPosY, - minmax->minTrackWidth, minmax->minTrackHeight, - minmax->maxTrackWidth, minmax->maxTrackHeight); + rail_window = window_list_get_by_id(xfi->rail->list, minmax->windowId); + + if (rail_window != NULL) + { + xfWindow * window = NULL; + window = (xfWindow *) rail_window->extra; + + printf("Server Min Max Info PDU: windowId=0x%X " + "maxWidth=%d maxHeight=%d maxPosX=%d maxPosY=%d " + "minTrackWidth=%d minTrackHeight=%d maxTrackWidth=%d maxTrackHeight=%d\n", + minmax->windowId, minmax->maxWidth, minmax->maxHeight, + (sint16)minmax->maxPosX, (sint16)minmax->maxPosY, + minmax->minTrackWidth, minmax->minTrackHeight, + minmax->maxTrackWidth, minmax->maxTrackHeight); + + xf_SetWindowMinMaxInfo(xfi, window, minmax->maxWidth, minmax->maxHeight, minmax->maxPosX, minmax->maxPosY, + minmax->minTrackWidth, minmax->minTrackHeight, minmax->maxTrackWidth, minmax->maxTrackHeight); + } } const char* movetype_names[] = @@ -344,11 +372,27 @@ const char* movetype_names[] = void xf_process_rail_server_localmovesize_event(xfInfo* xfi, rdpChanMan* chanman, RDP_EVENT* event) { RAIL_LOCALMOVESIZE_ORDER* movesize = (RAIL_LOCALMOVESIZE_ORDER*) event->user_data; + rdpWindow* rail_window = NULL; + + rail_window = window_list_get_by_id(xfi->rail->list, movesize->windowId); + + if (rail_window != NULL) + { + xfWindow * window = NULL; + window = (xfWindow *) rail_window->extra; + + printf("Server Local MoveSize PDU: windowId=0x%X " + "isMoveSizeStart=%d moveSizeType=%s PosX=%d PosY=%d\n", + movesize->windowId, movesize->isMoveSizeStart, + movetype_names[movesize->moveSizeType], (sint16)movesize->posX, (sint16)movesize->posY); + + if (movesize->isMoveSizeStart) + xf_StartLocalMoveSize(xfi, window, movesize->moveSizeType, (int)movesize->posX, (int)movesize->posY); + else + xf_StopLocalMoveSize(xfi, window, movesize->moveSizeType, (int)movesize->posX, (int)movesize->posY); + + } - printf("Server Local MoveSize PDU: windowId=0x%X " - "isMoveSizeStart=%d moveSizeType=%s PosX=%d PosY=%d\n", - movesize->windowId, movesize->isMoveSizeStart, - movetype_names[movesize->moveSizeType], (sint16)movesize->posX, (sint16)movesize->posY); } void xf_process_rail_appid_resp_event(xfInfo* xfi, rdpChanMan* chanman, RDP_EVENT* event) diff --git a/client/X11/xf_rail.h b/client/X11/xf_rail.h index 58d91e6eb..be5ecee1b 100644 --- a/client/X11/xf_rail.h +++ b/client/X11/xf_rail.h @@ -30,6 +30,8 @@ void xf_rail_send_client_system_command(xfInfo* xfi, uint32 windowId, uint16 com void xf_rail_send_activate(xfInfo* xfi, Window xwindow, boolean enabled); +void xf_rail_send_windowmove(xfInfo* xfi, uint32 windowId, uint32 left, uint32 top, uint32 right, uint32 bottom); + void xf_process_rail_event(xfInfo* xfi, rdpChanMan* chanman, RDP_EVENT* event); #endif /* __XF_RAIL_H */ diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c index 28f9a45ee..4c1d7bf0b 100644 --- a/client/X11/xf_window.c +++ b/client/X11/xf_window.c @@ -20,6 +20,10 @@ #include #include +#include +#include + + #ifdef WITH_XEXT #include #endif @@ -292,6 +296,7 @@ xfWindow* xf_CreateWindow(xfInfo* xfi, xfWindow* parent, int x, int y, int width window->decorations = False; window->fullscreen = False; window->parent = parent; + window->isLocalMoveSizeModeEnabled = False; window->handle = XCreateWindow(xfi->display, RootWindowOfScreen(xfi->screen), x, y, window->width, window->height, 0, xfi->depth, InputOutput, xfi->visual, @@ -332,6 +337,156 @@ xfWindow* xf_CreateWindow(xfInfo* xfi, xfWindow* parent, int x, int y, int width return window; } +void xf_SetWindowMinMaxInfo(xfInfo* xfi, xfWindow* window, + int maxWidth, int maxHeight, + int maxPosX, int maxPosY, + int minTrackWidth, int minTrackHeight, + int maxTrackWidth, int maxTrackHeight) +{ + XSizeHints* size_hints; + + printf("xf_SetWindowMinMaxInfo: windowHandle=0x%X " + "maxWidth=%d maxHeight=%d maxPosX=%d maxPosY=%d " + "minTrackWidth=%d minTrackHeight=%d maxTrackWidth=%d maxTrackHeight=%d\n", + (uint32)window->handle, maxWidth, maxHeight, + (sint16)maxPosX, (sint16)maxPosY, + minTrackWidth, minTrackHeight, + maxTrackWidth, maxTrackHeight); + + size_hints = XAllocSizeHints(); + + if (size_hints) + { + size_hints->flags = PMinSize | PMaxSize | PResizeInc; + + size_hints->min_width = minTrackWidth; + size_hints->min_height = minTrackHeight; + + size_hints->max_width = maxTrackWidth; + size_hints->max_height = maxTrackHeight; + + // For speedup window drawing we need to select optimal value + // for sizing step. + size_hints->width_inc = size_hints->height_inc = 5; + + XSetWMNormalHints(xfi->display, window->handle, size_hints); + XFree(size_hints); + } + + +} + + +void SentMoveResizeEvent(xfInfo* xfi, xfWindow* window, int direction, int x_root, int y_root) +{ + // TODO: + // - how to receive movesize canceling event? + // - how to produce correct RAIL movesize finish? + // - how to receive move/size window coordinates in process of local move/size? + + XEvent event; + + event.xclient.type = ClientMessage; + event.xclient.window = window->handle; + event.xclient.message_type = xfi->_NET_WM_MOVERESIZE; + event.xclient.serial = 0; + event.xclient.display = xfi->display; + event.xclient.send_event = True; + event.xclient.format = 32; + event.xclient.data.l[0] = x_root; + event.xclient.data.l[1] = y_root; + event.xclient.data.l[2] = direction; + event.xclient.data.l[3] = 1; // BUTTON 1 + event.xclient.data.l[4] = 0; + + XUngrabPointer(xfi->display, CurrentTime); + XSendEvent(xfi->display, RootWindowOfScreen(xfi->screen), False, SubstructureNotifyMask, &event); +} + +#define XF_NET_WM_MOVERESIZE_SIZE_TOPLEFT 0 +#define XF_NET_WM_MOVERESIZE_SIZE_TOP 1 +#define XF_NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2 +#define XF_NET_WM_MOVERESIZE_SIZE_RIGHT 3 +#define XF_NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4 +#define XF_NET_WM_MOVERESIZE_SIZE_BOTTOM 5 +#define XF_NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6 +#define XF_NET_WM_MOVERESIZE_SIZE_LEFT 7 +#define XF_NET_WM_MOVERESIZE_MOVE 8 /* movement only */ +#define XF_NET_WM_MOVERESIZE_SIZE_KEYBOARD 9 /* size via keyboard */ +#define XF_NET_WM_MOVERESIZE_MOVE_KEYBOARD 10 /* move via keyboard */ +#define XF_NET_WM_MOVERESIZE_CANCEL 11 /* cancel operation */ + +void xf_StartLocalMoveSize(xfInfo* xfi, xfWindow* window, uint16 moveSizeType, int posX, int posY) +{ + struct + { + uint16 moveSizeType; + int direction; + } type2dir_table[] = + { + { RAIL_WMSZ_LEFT, XF_NET_WM_MOVERESIZE_SIZE_LEFT }, + { RAIL_WMSZ_RIGHT, XF_NET_WM_MOVERESIZE_SIZE_RIGHT }, + { RAIL_WMSZ_TOP, XF_NET_WM_MOVERESIZE_SIZE_TOP }, + { RAIL_WMSZ_TOPLEFT, XF_NET_WM_MOVERESIZE_SIZE_TOPLEFT }, + { RAIL_WMSZ_TOPRIGHT, XF_NET_WM_MOVERESIZE_SIZE_TOPRIGHT }, + { RAIL_WMSZ_BOTTOM, XF_NET_WM_MOVERESIZE_SIZE_BOTTOM }, + { RAIL_WMSZ_BOTTOMLEFT, XF_NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT }, + { RAIL_WMSZ_BOTTOMRIGHT, XF_NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT }, + { RAIL_WMSZ_MOVE, XF_NET_WM_MOVERESIZE_MOVE }, + { RAIL_WMSZ_KEYMOVE, XF_NET_WM_MOVERESIZE_MOVE_KEYBOARD }, + { RAIL_WMSZ_KEYSIZE, XF_NET_WM_MOVERESIZE_SIZE_KEYBOARD }, + }; + + int x_root = 0; + int y_root = 0; + int direction = -1; + int i = 0; + + + printf("xf_StartLocalMoveSize: window=0x%X moveSizeType=0x%X PosX=%d PosY=%d\n", + (uint32)window->handle, moveSizeType, posX, posY); + + window->isLocalMoveSizeModeEnabled = True; + x_root = posX; + y_root = posY; + + if (moveSizeType == RAIL_WMSZ_MOVE) + { + x_root += window->left; + y_root += window->top; + } + + for (i = 0; i < RAIL_ARRAY_SIZE(type2dir_table); i++) + { + if (type2dir_table[i].moveSizeType == moveSizeType) + { + direction = type2dir_table[i].direction; + break; + } + } + + if (direction == -1) + { + printf("xf_StartLocalMoveSize: unknown moveSizeType. (window=0x%X moveSizeType=0x%X)\n", + (uint32)window->handle, moveSizeType); + return; + } + + SentMoveResizeEvent(xfi, window, direction, x_root, y_root); +} + +void xf_StopLocalMoveSize(xfInfo* xfi, xfWindow* window, uint16 moveSizeType, int topLeftX, int topLeftY) +{ + window->isLocalMoveSizeModeEnabled = False; + printf("xf_StopLocalMoveSize: window=0x%X moveSizeType=0x%X PosX=%d PosY=%d\n", + (uint32)window->handle, moveSizeType, topLeftX, topLeftY); + + if (moveSizeType == RAIL_WMSZ_MOVE) + { + xf_MoveWindow(xfi, window, topLeftX, topLeftY, window->width, window->height); + } +} + void xf_MoveWindow(xfInfo* xfi, xfWindow* window, int x, int y, int width, int height) { Pixmap surface; @@ -339,14 +494,12 @@ void xf_MoveWindow(xfInfo* xfi, xfWindow* window, int x, int y, int width, int h if ((width * height) < 1) return; + if (window->isLocalMoveSizeModeEnabled) + return; + xf_FixWindowCoordinates(&x, &y, &width, &height); - if (window->width == width && window->height == height) - XMoveWindow(xfi->display, window->handle, x, y); - else if (window->left == x && window->top == y) - XResizeWindow(xfi->display, window->handle, width, height); - else - XMoveResizeWindow(xfi->display, window->handle, x, y, width, height); + XMoveResizeWindow(xfi->display, window->handle, x, y, width, height); surface = XCreatePixmap(xfi->display, window->handle, width, height, xfi->depth); XCopyArea(xfi->display, surface, window->surface, window->gc, 0, 0, window->width, window->height, 0, 0); @@ -458,7 +611,7 @@ void xf_SetWindowVisibilityRects(xfInfo* xfi, xfWindow* window, RECTANGLE_16* re } #ifdef WITH_XEXT - XShapeCombineRectangles(xfi->display, window->handle, ShapeBounding, 0, 0, xrects, nrects, ShapeSet, 0); + //XShapeCombineRectangles(xfi->display, window->handle, ShapeBounding, 0, 0, xrects, nrects, ShapeSet, 0); #endif xfree(xrects); diff --git a/client/X11/xf_window.h b/client/X11/xf_window.h index d9046d89d..70d5cbbed 100644 --- a/client/X11/xf_window.h +++ b/client/X11/xf_window.h @@ -43,6 +43,8 @@ struct xf_window boolean decorations; xfWindow* parent; size_t ref_count; + + boolean isLocalMoveSizeModeEnabled; }; void xf_ewmhints_init(xfInfo* xfi); @@ -65,4 +67,11 @@ void xf_SetWindowVisibilityRects(xfInfo* xfi, xfWindow* window, RECTANGLE_16* re void xf_SetWindowStyle(xfInfo* xfi, xfWindow* window, uint32 style, uint32 ex_style); void xf_DestroyWindow(xfInfo* xfi, xfWindow* window); +void xf_SetWindowMinMaxInfo(xfInfo* xfi, xfWindow* window, int maxWidth, int maxHeight, + int maxPosX, int maxPosY, int minTrackWidth, int minTrackHeight, int maxTrackWidth, int maxTrackHeight); + + +void xf_StartLocalMoveSize(xfInfo* xfi, xfWindow* window, uint16 moveSizeType, int posX, int posY); +void xf_StopLocalMoveSize(xfInfo* xfi, xfWindow* window, uint16 moveSizeType, int topLeftX, int topLeftY); + #endif /* __XF_WINDOW_H */ diff --git a/client/X11/xfreerdp.c b/client/X11/xfreerdp.c index 983da33ce..9762c42cc 100644 --- a/client/X11/xfreerdp.c +++ b/client/X11/xfreerdp.c @@ -290,6 +290,8 @@ boolean xf_pre_connect(freerdp* instance) xfi->_NET_WM_STATE_SKIP_TASKBAR = XInternAtom(xfi->display, "_NET_WM_STATE_SKIP_TASKBAR", False); xfi->_NET_WM_STATE_SKIP_PAGER = XInternAtom(xfi->display, "_NET_WM_STATE_SKIP_PAGER", False); + xfi->_NET_WM_MOVERESIZE = XInternAtom(xfi->display, "_NET_WM_MOVERESIZE", False); + xf_kbd_init(xfi); xfi->clrconv = (HCLRCONV) malloc(sizeof(CLRCONV)); @@ -306,7 +308,7 @@ boolean xf_pre_connect(freerdp* instance) xfi->depth = DefaultDepthOfScreen(xfi->screen); xfi->big_endian = (ImageByteOrder(xfi->display) == MSBFirst); - xfi->mouse_motion = True; + xfi->mouse_motion = settings->mouse_motion; xfi->complex_regions = True; xfi->decoration = settings->decorations; xfi->remote_app = settings->remote_app; diff --git a/client/X11/xfreerdp.h b/client/X11/xfreerdp.h index 887b3d07c..0b33b0aac 100644 --- a/client/X11/xfreerdp.h +++ b/client/X11/xfreerdp.h @@ -104,6 +104,8 @@ struct xf_info Atom _NET_WM_WINDOW_TYPE_NORMAL; Atom _NET_WM_WINDOW_TYPE_DIALOG; Atom _NET_WM_WINDOW_TYPE_UTILITY; + + Atom _NET_WM_MOVERESIZE; }; void xf_toggle_fullscreen(xfInfo* xfi); diff --git a/libfreerdp-core/fastpath.c b/libfreerdp-core/fastpath.c index 2275b57f1..2572e0397 100644 --- a/libfreerdp-core/fastpath.c +++ b/libfreerdp-core/fastpath.c @@ -113,7 +113,7 @@ static void fastpath_recv_orders(rdpFastPath* fastpath, STREAM* s) stream_read_uint16(s, numberOrders); /* numberOrders (2 bytes) */ - printf("numberOrders(FastPath):%d\n", numberOrders); + //printf("numberOrders(FastPath):%d\n", numberOrders); while (numberOrders > 0) { diff --git a/libfreerdp-core/settings.c b/libfreerdp-core/settings.c index ca900b014..18df81e78 100644 --- a/libfreerdp-core/settings.c +++ b/libfreerdp-core/settings.c @@ -147,6 +147,7 @@ rdpSettings* settings_new() settings->uniconv = freerdp_uniconv_new(); gethostname(settings->client_hostname, sizeof(settings->client_hostname) - 1); + settings->mouse_motion = False; } return settings; diff --git a/libfreerdp-rail/window.c b/libfreerdp-rail/window.c index 2723829cf..5202f8e89 100644 --- a/libfreerdp-rail/window.c +++ b/libfreerdp-rail/window.c @@ -141,6 +141,9 @@ void window_state_update(rdpWindow* window, WINDOW_ORDER_INFO* orderInfo, WINDOW printf("ownerWindowId:0x%08X\n", window->ownerWindowId); } + printf("window_state_update: windowId=0x%X ownerWindowId=0x%X\n", + window->windowId, window->ownerWindowId); + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_STYLE) { window->style = window_state->style; diff --git a/libfreerdp-utils/args.c b/libfreerdp-utils/args.c index b6ce38145..522543648 100644 --- a/libfreerdp-utils/args.c +++ b/libfreerdp-utils/args.c @@ -306,7 +306,7 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv, } else if (strcmp("-m", argv[index]) == 0) { - settings->mouse_motion = 0; + settings->mouse_motion = True; } else if (strcmp("--app", argv[index]) == 0) {