Merge pull request #76 from roman-b/rail

Rail Local Move/Size initial support.
This commit is contained in:
Marc-André Moreau 2011-09-02 07:55:08 -07:00
commit f6a3f636ec
11 changed files with 261 additions and 24 deletions

View File

@ -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

View File

@ -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)

View File

@ -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 */

View File

@ -20,6 +20,10 @@
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <freerdp/rail.h>
#include <freerdp/utils/rail.h>
#ifdef WITH_XEXT
#include <X11/extensions/shape.h>
#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);

View File

@ -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 */

View File

@ -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;

View File

@ -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);

View File

@ -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)
{

View File

@ -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;

View File

@ -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;

View File

@ -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)
{