mirror of
https://github.com/FreeRDP/FreeRDP.git
synced 2024-12-12 03:06:34 +08:00
xfreerdp: add parent-child relationship for RAIL windows.
This commit is contained in:
parent
e5fb626d75
commit
6365db7be6
@ -458,7 +458,7 @@ boolean xf_event_process(freerdp* instance, XEvent* event)
|
||||
|
||||
#if 1
|
||||
if (event->type != MotionNotify)
|
||||
printf("X11 %s Event\n", X11_EVENT_STRINGS[event->type]);
|
||||
printf("X11 %s Event: wnd=0x%X\n", X11_EVENT_STRINGS[event->type], (uint32)event->xany.window);
|
||||
#endif
|
||||
|
||||
switch (event->type)
|
||||
|
@ -74,16 +74,37 @@ void xf_rail_CreateWindow(rdpRail* rail, rdpWindow* window)
|
||||
{
|
||||
xfInfo* xfi;
|
||||
xfWindow* xfw;
|
||||
xfWindow* xfparent;
|
||||
|
||||
xfi = (xfInfo*) rail->extra;
|
||||
|
||||
xfw = xf_CreateWindow((xfInfo*) rail->extra,
|
||||
printf("xf_rail_CreateWindow: wid=0x%X own_wid=0x%X\n",
|
||||
window->windowId, window->ownerWindowId);
|
||||
|
||||
|
||||
// When ownerWindowId is equal to 0, it means that
|
||||
// it is a main application window.
|
||||
// For main application windows screen window is parent. (0 in Win32)
|
||||
xfparent = NULL;
|
||||
if (window->ownerWindowId != 0)
|
||||
{
|
||||
rdpWindow* p = NULL;
|
||||
|
||||
p = window_list_get_by_id(xfi->rail->list, window->ownerWindowId);
|
||||
|
||||
if (p != NULL)
|
||||
xfparent = (xfWindow *)p->extra;
|
||||
}
|
||||
|
||||
xfw = xf_CreateWindow((xfInfo*) rail->extra, xfparent,
|
||||
window->windowOffsetX, window->windowOffsetY,
|
||||
window->windowWidth, window->windowHeight,
|
||||
window->windowId);
|
||||
|
||||
XStoreName(xfi->display, xfw->handle, window->title);
|
||||
|
||||
xf_SetWindowStyle(xfi, xfw, window->style, window->extendedStyle);
|
||||
|
||||
window->extra = (void*) xfw;
|
||||
window->extraId = (void*) xfw->handle;
|
||||
}
|
||||
@ -276,7 +297,7 @@ void xf_process_rail_server_minmaxinfo_event(xfInfo* xfi, rdpChanMan* chanman, R
|
||||
"maxWidth=%d maxHeight=%d maxPosX=%d maxPosY=%d "
|
||||
"minTrackWidth=%d minTrackHeight=%d maxTrackWidth=%d maxTrackHeight=%d\n",
|
||||
minmax->windowId, minmax->maxWidth, minmax->maxHeight,
|
||||
minmax->maxPosX, minmax->maxPosY,
|
||||
(sint16)minmax->maxPosX, (sint16)minmax->maxPosY,
|
||||
minmax->minTrackWidth, minmax->minTrackHeight,
|
||||
minmax->maxTrackWidth, minmax->maxTrackHeight);
|
||||
}
|
||||
@ -304,7 +325,7 @@ void xf_process_rail_server_localmovesize_event(xfInfo* xfi, rdpChanMan* chanman
|
||||
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], movesize->posX, movesize->posY);
|
||||
movetype_names[movesize->moveSizeType], (sint16)movesize->posX, (sint16)movesize->posY);
|
||||
}
|
||||
|
||||
void xf_process_rail_appid_resp_event(xfInfo* xfi, rdpChanMan* chanman, RDP_EVENT* event)
|
||||
|
@ -41,6 +41,9 @@ struct _PropMotifWmHints
|
||||
};
|
||||
typedef struct _PropMotifWmHints PropMotifWmHints;
|
||||
|
||||
void xf_RefrenceWindow(xfInfo* xfi, xfWindow* window);
|
||||
void xf_DerefrenceWindow(xfInfo* xfi, xfWindow* window);
|
||||
|
||||
void xf_SendClientMessage(xfInfo* xfi, xfWindow* window, Atom atom, long msg, long d1, long d2, long d3)
|
||||
{
|
||||
XEvent xevent;
|
||||
@ -159,6 +162,43 @@ void xf_SetWindowDecorations(xfInfo* xfi, xfWindow* window, boolean show)
|
||||
window->decorations = show;
|
||||
}
|
||||
|
||||
void xf_SetWindowStyle(xfInfo* xfi, xfWindow* window, uint32 style, uint32 ex_style)
|
||||
{
|
||||
Atom window_type;
|
||||
|
||||
window_type = xfi->_NET_WM_WINDOW_TYPE_NORMAL;
|
||||
|
||||
if (((style & WS_POPUP) !=0) ||
|
||||
((style & WS_DLGFRAME) != 0) ||
|
||||
((ex_style & WS_EX_DLGMODALFRAME) != 0)
|
||||
)
|
||||
{
|
||||
window_type = xfi->_NET_WM_WINDOW_TYPE_DIALOG;
|
||||
}
|
||||
else if ((ex_style & WS_EX_TOOLWINDOW) != 0)
|
||||
{
|
||||
window_type = xfi->_NET_WM_WINDOW_TYPE_UTILITY;
|
||||
}
|
||||
|
||||
XChangeProperty(xfi->display, window->handle, xfi->_NET_WM_WINDOW_TYPE,
|
||||
xfi->_NET_WM_WINDOW_TYPE, 32, PropModeReplace, (unsigned char*)&window_type, 1);
|
||||
}
|
||||
|
||||
void xf_SetWindowChildState(xfInfo* xfi, xfWindow* window)
|
||||
{
|
||||
Atom window_state[2];
|
||||
|
||||
if (window->parent != NULL)
|
||||
{
|
||||
window_state[0] = xfi->_NET_WM_STATE_SKIP_PAGER;
|
||||
window_state[1] = xfi->_NET_WM_STATE_SKIP_TASKBAR;
|
||||
|
||||
XChangeProperty(xfi->display, window->handle, xfi->_NET_WM_STATE,
|
||||
xfi->_NET_WM_STATE, 32, PropModeReplace, (unsigned char*)&window_state, 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
xfWindow* xf_CreateDesktopWindow(xfInfo* xfi, char* name, int width, int height)
|
||||
{
|
||||
xfWindow* window;
|
||||
@ -232,7 +272,7 @@ void xf_FixWindowCoordinates(int* x, int* y, int* width, int* height)
|
||||
|
||||
char rail_window_class[] = "RAIL:00000000";
|
||||
|
||||
xfWindow* xf_CreateWindow(xfInfo* xfi, int x, int y, int width, int height, uint32 id)
|
||||
xfWindow* xf_CreateWindow(xfInfo* xfi, xfWindow* parent, int x, int y, int width, int height, uint32 id)
|
||||
{
|
||||
xfWindow* window;
|
||||
|
||||
@ -254,18 +294,36 @@ xfWindow* xf_CreateWindow(xfInfo* xfi, int x, int y, int width, int height, uint
|
||||
{
|
||||
XGCValues gcv;
|
||||
int input_mask;
|
||||
XSizeHints* size_hints;
|
||||
XClassHint* class_hints;
|
||||
Window parent_handle;
|
||||
int lx;
|
||||
int ly;
|
||||
|
||||
window->ref_count = 0;
|
||||
window->decorations = False;
|
||||
window->fullscreen = False;
|
||||
window->parent = parent;
|
||||
|
||||
window->handle = XCreateWindow(xfi->display, RootWindowOfScreen(xfi->screen),
|
||||
x, y, window->width, window->height, 0, xfi->depth, InputOutput, xfi->visual,
|
||||
lx = x;
|
||||
ly = y;
|
||||
parent_handle = RootWindowOfScreen(xfi->screen);
|
||||
if (window->parent != NULL)
|
||||
{
|
||||
lx = x - window->parent->left;
|
||||
ly = y - window->parent->top;
|
||||
parent_handle = parent->handle;
|
||||
}
|
||||
|
||||
window->handle = XCreateWindow(xfi->display, parent_handle,
|
||||
lx, ly, window->width, window->height, 0, xfi->depth, InputOutput, xfi->visual,
|
||||
CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
|
||||
CWBorderPixel, &xfi->attribs);
|
||||
|
||||
xf_RefrenceWindow(xfi, window);
|
||||
xf_RefrenceWindow(xfi, window->parent);
|
||||
|
||||
xf_SetWindowDecorations(xfi, window, window->decorations);
|
||||
//xf_SetWindowChildState(xfi, window);
|
||||
|
||||
class_hints = XAllocClassHint();
|
||||
|
||||
@ -281,17 +339,6 @@ xfWindow* xf_CreateWindow(xfInfo* xfi, int x, int y, int width, int height, uint
|
||||
xfree(class);
|
||||
}
|
||||
|
||||
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 |
|
||||
@ -304,6 +351,10 @@ xfWindow* xf_CreateWindow(xfInfo* xfi, int x, int y, int width, int height, uint
|
||||
window->gc = XCreateGC(xfi->display, window->handle, GCGraphicsExposures, &gcv);
|
||||
window->surface = XCreatePixmap(xfi->display, window->handle, window->width, window->height, xfi->depth);
|
||||
|
||||
printf("xf_CreateWindow: h=0x%X p=0x%X x=%d y=%d w=%d h=%d\n", (uint32)window->handle,
|
||||
(window->parent != NULL) ? (uint32)window->parent->handle : 0,
|
||||
x, y, width, height);
|
||||
|
||||
xf_MoveWindow(xfi, window, x, y, width, height);
|
||||
}
|
||||
|
||||
@ -313,30 +364,32 @@ xfWindow* xf_CreateWindow(xfInfo* xfi, int x, int y, int width, int height, uint
|
||||
void xf_MoveWindow(xfInfo* xfi, xfWindow* window, int x, int y, int width, int height)
|
||||
{
|
||||
Pixmap surface;
|
||||
XSizeHints* size_hints;
|
||||
int lx = x;
|
||||
int ly = y;
|
||||
|
||||
if ((width * height) < 1)
|
||||
return;
|
||||
|
||||
xf_FixWindowCoordinates(&x, &y, &width, &height);
|
||||
printf("xf_MoveWindow: BEFORE correctness h=0x%X x=%d y=%d w=%d h=%d\n", (uint32)window->handle,
|
||||
x, y, width, height);
|
||||
|
||||
size_hints = XAllocSizeHints();
|
||||
xf_FixWindowCoordinates(&x, &y, &width, &height);
|
||||
|
||||
if (size_hints)
|
||||
{
|
||||
size_hints->flags = PMinSize | PMaxSize;
|
||||
size_hints->min_width = size_hints->max_width = width;
|
||||
size_hints->min_height = size_hints->max_height = height;
|
||||
XSetWMNormalHints(xfi->display, window->handle, size_hints);
|
||||
XFree(size_hints);
|
||||
}
|
||||
if (window->parent != NULL)
|
||||
{
|
||||
lx = x - window->parent->left;
|
||||
ly = y - window->parent->top;
|
||||
}
|
||||
|
||||
printf("xf_MoveWindow: AFTER correctness h=0x%X x=%d y=%d lx=%d ly=%d w=%d h=%d \n", (uint32)window->handle,
|
||||
x, y, lx, ly, width, height);
|
||||
|
||||
if (window->width == width && window->height == height)
|
||||
XMoveWindow(xfi->display, window->handle, x, y);
|
||||
XMoveWindow(xfi->display, window->handle, lx, ly);
|
||||
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, lx, ly, 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);
|
||||
@ -432,16 +485,42 @@ void xf_SetWindowVisibilityRects(xfInfo* xfi, xfWindow* window, RECTANGLE_16* re
|
||||
xfree(xrects);
|
||||
}
|
||||
|
||||
void xf_RefrenceWindow(xfInfo* xfi, xfWindow* window)
|
||||
{
|
||||
if (window == NULL) return;
|
||||
window->ref_count++;
|
||||
}
|
||||
|
||||
void xf_DerefrenceWindow(xfInfo* xfi, xfWindow* window)
|
||||
{
|
||||
if (window == NULL) return;
|
||||
|
||||
window->ref_count--;
|
||||
if (window->ref_count == 0)
|
||||
{
|
||||
printf("xf_DerefrenceWindow: destroying h=0x%X p=0x%X\n", (uint32)window->handle,
|
||||
(window->parent != NULL) ? (uint32)window->parent->handle : 0);
|
||||
|
||||
if (window->gc)
|
||||
XFreeGC(xfi->display, window->gc);
|
||||
if (window->surface)
|
||||
XFreePixmap(xfi->display, window->surface);
|
||||
if (window->handle)
|
||||
{
|
||||
XUnmapWindow(xfi->display, window->handle);
|
||||
XDestroyWindow(xfi->display, window->handle);
|
||||
}
|
||||
xfree(window);
|
||||
}
|
||||
}
|
||||
|
||||
void xf_DestroyWindow(xfInfo* xfi, xfWindow* window)
|
||||
{
|
||||
if (window->gc)
|
||||
XFreeGC(xfi->display, window->gc);
|
||||
if (window->surface)
|
||||
XFreePixmap(xfi->display, window->surface);
|
||||
if (window->handle)
|
||||
{
|
||||
XUnmapWindow(xfi->display, window->handle);
|
||||
XDestroyWindow(xfi->display, window->handle);
|
||||
}
|
||||
xfree(window);
|
||||
xfWindow* parent = window->parent;
|
||||
|
||||
printf("xf_DestroyWindow: h=0x%X p=0x%X\n", (uint32)window->handle,
|
||||
(window->parent != NULL) ? (uint32)window->parent->handle : 0);
|
||||
|
||||
xf_DerefrenceWindow(xfi, window);
|
||||
xf_DerefrenceWindow(xfi, parent);
|
||||
}
|
||||
|
@ -41,6 +41,8 @@ struct xf_window
|
||||
Pixmap surface;
|
||||
boolean fullscreen;
|
||||
boolean decorations;
|
||||
xfWindow* parent;
|
||||
size_t ref_count;
|
||||
};
|
||||
|
||||
void xf_ewmhints_init(xfInfo* xfi);
|
||||
@ -53,11 +55,12 @@ void xf_SetWindowDecorations(xfInfo* xfi, xfWindow* window, boolean show);
|
||||
|
||||
xfWindow* xf_CreateDesktopWindow(xfInfo* xfi, char* name, int width, int height);
|
||||
|
||||
xfWindow* xf_CreateWindow(xfInfo* xfi, int x, int y, int width, int height, uint32 id);
|
||||
xfWindow* xf_CreateWindow(xfInfo* xfi, xfWindow* parent, int x, int y, int width, int height, uint32 id);
|
||||
void xf_MoveWindow(xfInfo* xfi, xfWindow* window, int x, int y, int width, int height);
|
||||
void xf_ShowWindow(xfInfo* xfi, xfWindow* window, uint8 state);
|
||||
void xf_SetWindowIcon(xfInfo* xfi, xfWindow* window, rdpIcon* icon);
|
||||
void xf_SetWindowVisibilityRects(xfInfo* xfi, xfWindow* window, RECTANGLE_16* rects, int nrects);
|
||||
void xf_SetWindowStyle(xfInfo* xfi, xfWindow* window, uint32 style, uint32 ex_style);
|
||||
void xf_DestroyWindow(xfInfo* xfi, xfWindow* window);
|
||||
|
||||
#endif /* __XF_WINDOW_H */
|
||||
|
@ -266,6 +266,13 @@ boolean xf_pre_connect(freerdp* instance)
|
||||
xfi->_NET_WORKAREA = XInternAtom(xfi->display, "_NET_WORKAREA", False);
|
||||
xfi->_NET_WM_STATE = XInternAtom(xfi->display, "_NET_WM_STATE", False);
|
||||
xfi->_NET_WM_STATE_FULLSCREEN = XInternAtom(xfi->display, "_NET_WM_STATE_FULLSCREEN", False);
|
||||
xfi->_NET_WM_WINDOW_TYPE = XInternAtom(xfi->display, "_NET_WM_WINDOW_TYPE", False);
|
||||
|
||||
xfi->_NET_WM_WINDOW_TYPE_NORMAL = XInternAtom(xfi->display, "_NET_WM_WINDOW_TYPE_NORMAL", False);
|
||||
xfi->_NET_WM_WINDOW_TYPE_DIALOG = XInternAtom(xfi->display, "_NET_WM_WINDOW_TYPE_DIALOG", False);
|
||||
xfi->_NET_WM_WINDOW_TYPE_UTILITY = XInternAtom(xfi->display, "_NET_WM_WINDOW_TYPE_UTILITY", False);
|
||||
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);
|
||||
|
||||
xf_kbd_init(xfi);
|
||||
|
||||
|
@ -86,8 +86,16 @@ struct xf_info
|
||||
Atom _MOTIF_WM_HINTS;
|
||||
Atom _NET_CURRENT_DESKTOP;
|
||||
Atom _NET_WORKAREA;
|
||||
|
||||
Atom _NET_WM_STATE;
|
||||
Atom _NET_WM_STATE_FULLSCREEN;
|
||||
Atom _NET_WM_STATE_SKIP_TASKBAR;
|
||||
Atom _NET_WM_STATE_SKIP_PAGER;
|
||||
|
||||
Atom _NET_WM_WINDOW_TYPE;
|
||||
Atom _NET_WM_WINDOW_TYPE_NORMAL;
|
||||
Atom _NET_WM_WINDOW_TYPE_DIALOG;
|
||||
Atom _NET_WM_WINDOW_TYPE_UTILITY;
|
||||
};
|
||||
|
||||
void xf_toggle_fullscreen(xfInfo* xfi);
|
||||
|
Loading…
Reference in New Issue
Block a user