xfreerdp: stabilizing RemoteApp, fix window styles

This commit is contained in:
Marc-André Moreau 2011-08-30 14:21:16 -04:00
parent 81cac9c787
commit a9a06abcc3
9 changed files with 85 additions and 112 deletions

View File

@ -46,23 +46,23 @@ endif()
find_package(Xinerama)
if(XINERAMA_FOUND)
add_definitions(-DWITH_XINERAMA)
add_definitions(-DWITH_XINERAMA -DWITH_XEXT)
include_directories(${XINERAMA_INCLUDE_DIRS})
target_link_libraries(xfreerdp ${XINERAMA_LIBRARIES})
endif()
find_package(Xext)
if(Xext_FOUND)
if(XEXT_FOUND)
add_definitions(-DWITH_XEXT)
include_directories(${Xext_INCLUDE_DIRS})
target_link_libraries(xfreerdp ${Xext_LIBRARIES})
include_directories(${XEXT_INCLUDE_DIRS})
target_link_libraries(xfreerdp ${XEXT_LIBRARIES})
endif()
find_package(Xcursor)
if(Xcursor_FOUND)
add_definitions(-DWITH_XCURSOR)
include_directories(${Xcursor_INCLUDE_DIRS})
target_link_libraries(xfreerdp ${Xext_LIBRARIES})
target_link_libraries(xfreerdp ${Xcursor_LIBRARIES})
endif()
target_link_libraries(xfreerdp freerdp-core)

View File

@ -343,7 +343,7 @@ boolean xf_event_FocusIn(xfInfo* xfi, XEvent* event, boolean app)
if (xfi->mouse_active && (app != True))
XGrabKeyboard(xfi->display, xfi->window->handle, True, GrabModeAsync, GrabModeAsync, CurrentTime);
xf_rail_send_activate(xfi, event->xany.window, True);
//xf_rail_send_activate(xfi, event->xany.window, True);
xf_kbd_focus_in(xfi);
return True;
@ -359,7 +359,7 @@ boolean xf_event_FocusOut(xfInfo* xfi, XEvent* event, boolean app)
if (event->xfocus.mode == NotifyWhileGrabbed)
XUngrabKeyboard(xfi->display, CurrentTime);
xf_rail_send_activate(xfi, event->xany.window, False);
//xf_rail_send_activate(xfi, event->xany.window, False);
return True;
}

View File

@ -82,6 +82,7 @@ void xf_rail_CreateWindow(rdpRail* rail, rdpWindow* window)
window->windowId, window->ownerWindowId);
xfparent = NULL;
if (window->ownerWindowId != 0)
{
rdpWindow* p = NULL;
@ -89,7 +90,7 @@ void xf_rail_CreateWindow(rdpRail* rail, rdpWindow* window)
p = window_list_get_by_id(xfi->rail->list, window->ownerWindowId);
if (p != NULL)
xfparent = (xfWindow *)p->extra;
xfparent = (xfWindow *) p->extra;
}
xfw = xf_CreateWindow((xfInfo*) rail->extra, xfparent,
@ -165,6 +166,17 @@ void xf_rail_SetWindowRects(rdpRail* rail, rdpWindow* window)
xf_SetWindowRects(xfi, xfw, window->windowRects, window->numWindowRects);
}
void xf_rail_SetWindowVisibilityRects(rdpRail* rail, rdpWindow* window)
{
xfInfo* xfi;
xfWindow* xfw;
xfi = (xfInfo*) rail->extra;
xfw = (xfWindow*) window->extra;
xf_SetWindowVisibilityRects(xfi, xfw, window->windowRects, window->numWindowRects);
}
void xf_rail_DestroyWindow(rdpRail* rail, rdpWindow* window)
{
xfWindow* xfw;
@ -181,6 +193,7 @@ void xf_rail_register_callbacks(xfInfo* xfi, rdpRail* rail)
rail->SetWindowText = xf_rail_SetWindowText;
rail->SetWindowIcon = xf_rail_SetWindowIcon;
rail->SetWindowRects = xf_rail_SetWindowRects;
rail->SetWindowVisibilityRects = xf_rail_SetWindowVisibilityRects;
rail->DestroyWindow = xf_rail_DestroyWindow;
}

View File

@ -41,9 +41,6 @@ struct _PropMotifWmHints
};
typedef struct _PropMotifWmHints PropMotifWmHints;
void xf_ReferenceWindow(xfInfo* xfi, xfWindow* window);
void xf_DereferenceWindow(xfInfo* xfi, xfWindow* window);
void xf_SendClientMessage(xfInfo* xfi, xfWindow* window, Atom atom, long msg, long d1, long d2, long d3)
{
XEvent xevent;
@ -162,43 +159,38 @@ void xf_SetWindowDecorations(xfInfo* xfi, xfWindow* window, boolean show)
window->decorations = show;
}
void xf_SetWindowUnlisted(xfInfo* xfi, xfWindow* window)
{
Atom window_state[2];
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,
XA_ATOM, 32, PropModeReplace, (uint8*) &window_state, 2);
}
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)
)
if ((style & WS_POPUP) || (style & WS_DLGFRAME) || (ex_style & WS_EX_DLGMODALFRAME))
{
window_type = xfi->_NET_WM_WINDOW_TYPE_DIALOG;
}
else if ((ex_style & WS_EX_TOOLWINDOW) != 0)
if (ex_style & WS_EX_TOOLWINDOW)
{
xf_SetWindowUnlisted(xfi, window);
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);
XA_ATOM, 32, PropModeReplace, (uint8*) &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;
@ -295,36 +287,19 @@ xfWindow* xf_CreateWindow(xfInfo* xfi, xfWindow* parent, int x, int y, int width
XGCValues gcv;
int input_mask;
XClassHint* class_hints;
Window parent_handle;
int lx;
int ly;
window->ref_count = 0;
window->decorations = False;
window->fullscreen = False;
window->parent = parent;
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,
window->handle = XCreateWindow(xfi->display, RootWindowOfScreen(xfi->screen),
x, y, window->width, window->height, 0, xfi->depth, InputOutput, xfi->visual,
CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
CWBorderPixel, &xfi->attribs);
xf_ReferenceWindow(xfi, window);
xf_ReferenceWindow(xfi, window->parent);
xf_SetWindowDecorations(xfi, window, window->decorations);
xf_SetWindowChildState(xfi, window);
xf_SetWindowUnlisted(xfi, window);
class_hints = XAllocClassHint();
@ -352,10 +327,6 @@ xfWindow* xf_CreateWindow(xfInfo* xfi, xfWindow* parent, int x, int y, int width
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);
}
@ -364,37 +335,19 @@ xfWindow* xf_CreateWindow(xfInfo* xfi, xfWindow* parent, int x, int y, int width
void xf_MoveWindow(xfInfo* xfi, xfWindow* window, int x, int y, int width, int height)
{
int lx, ly;
Pixmap surface;
if ((width * height) < 1)
return;
printf("xf_MoveWindow: BEFORE correctness h=0x%X x=%d y=%d w=%d h=%d\n",
(uint32) window->handle, x, y, width, height);
xf_FixWindowCoordinates(&x, &y, &width, &height);
if (window->parent != NULL)
{
lx = x - window->parent->left;
ly = y - window->parent->top;
}
else
{
lx = x;
ly = y;
}
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, lx, ly);
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, lx, ly, 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);
@ -490,42 +443,41 @@ void xf_SetWindowRects(xfInfo* xfi, xfWindow* window, RECTANGLE_16* rects, int n
xfree(xrects);
}
void xf_ReferenceWindow(xfInfo* xfi, xfWindow* window)
void xf_SetWindowVisibilityRects(xfInfo* xfi, xfWindow* window, RECTANGLE_16* rects, int nrects)
{
if (window == NULL) return;
window->ref_count++;
}
int i;
XRectangle* xrects;
void xf_DereferenceWindow(xfInfo* xfi, xfWindow* window)
{
if (window == NULL) return;
xrects = xmalloc(sizeof(XRectangle) * nrects);
window->ref_count--;
if (window->ref_count == 0)
for (i = 0; i < nrects; i++)
{
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);
xrects[i].x = rects[i].left;
xrects[i].y = rects[i].top;
xrects[i].width = rects[i].right - rects[i].left;
xrects[i].height = rects[i].bottom - rects[i].top;
}
#ifdef WITH_XEXT
XShapeCombineRectangles(xfi->display, window->handle, ShapeBounding, 0, 0, xrects, nrects, ShapeSet, 0);
#endif
xfree(xrects);
}
void xf_DestroyWindow(xfInfo* xfi, xfWindow* window)
{
xfWindow* parent = window->parent;
if (window->gc)
XFreeGC(xfi->display, window->gc);
printf("xf_DestroyWindow: h=0x%X p=0x%X\n", (uint32)window->handle,
(window->parent != NULL) ? (uint32)window->parent->handle : 0);
if (window->surface)
XFreePixmap(xfi->display, window->surface);
xf_DereferenceWindow(xfi, window);
xf_DereferenceWindow(xfi, parent);
if (window->handle)
{
XUnmapWindow(xfi->display, window->handle);
XDestroyWindow(xfi->display, window->handle);
}
xfree(window);
}

View File

@ -52,6 +52,7 @@ boolean xf_GetWorkArea(xfInfo* xfi);
void xf_SetWindowFullscreen(xfInfo* xfi, xfWindow* window, boolean fullscreen);
void xf_SetWindowDecorations(xfInfo* xfi, xfWindow* window, boolean show);
void xf_SetWindowUnlisted(xfInfo* xfi, xfWindow* window);
xfWindow* xf_CreateDesktopWindow(xfInfo* xfi, char* name, int width, int height);
@ -60,6 +61,7 @@ void xf_MoveWindow(xfInfo* xfi, xfWindow* window, int x, int y, int width, int h
void xf_ShowWindow(xfInfo* xfi, xfWindow* window, uint8 state);
void xf_SetWindowIcon(xfInfo* xfi, xfWindow* window, rdpIcon* icon);
void xf_SetWindowRects(xfInfo* xfi, xfWindow* window, RECTANGLE_16* rects, int nrects);
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);

View File

@ -310,7 +310,7 @@ boolean xf_pre_connect(freerdp* instance)
xfi->depth = DefaultDepthOfScreen(xfi->screen);
xfi->big_endian = (ImageByteOrder(xfi->display) == MSBFirst);
xfi->mouse_motion = False;
xfi->mouse_motion = True;
xfi->complex_regions = True;
xfi->decoration = settings->decorations;
xfi->remote_app = settings->remote_app;

View File

@ -28,22 +28,22 @@
# limitations under the License.
#=============================================================================
find_path(Xext_INCLUDE_DIR NAMES Xext.h
find_path(XEXT_INCLUDE_DIR NAMES Xext.h
PATH_SUFFIXES X11/extensions
DOC "The Xext include directory"
)
find_library(Xext_LIBRARY NAMES Xext
find_library(XEXT_LIBRARY NAMES Xext
DOC "The Xext library"
)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Xext DEFAULT_MSG Xext_LIBRARY Xext_INCLUDE_DIR)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(XEXT DEFAULT_MSG XEXT_LIBRARY XEXT_INCLUDE_DIR)
if(Xext_FOUND)
set( Xext_LIBRARIES ${Xext_LIBRARY} )
set( Xext_INCLUDE_DIRS ${Xext_INCLUDE_DIR} )
if(XEXT_FOUND)
set( XEXT_LIBRARIES ${XEXT_LIBRARY} )
set( XEXT_INCLUDE_DIRS ${XEXT_INCLUDE_DIR} )
endif()
mark_as_advanced(Xext_INCLUDE_DIR Xext_LIBRARY)
mark_as_advanced(XEXT_INCLUDE_DIR XEXT_LIBRARY)

View File

@ -40,6 +40,7 @@ typedef void (*railShowWindow)(rdpRail* rail, rdpWindow* window, uint8 state);
typedef void (*railSetWindowText)(rdpRail* rail, rdpWindow* window);
typedef void (*railSetWindowIcon)(rdpRail* rail, rdpWindow* window, rdpIcon* icon);
typedef void (*railSetWindowRects)(rdpRail* rail, rdpWindow* window);
typedef void (*railSetWindowVisibilityRects)(rdpRail* rail, rdpWindow* window);
struct rdp_rail
{
@ -56,6 +57,7 @@ struct rdp_rail
railSetWindowText SetWindowText;
railSetWindowIcon SetWindowIcon;
railSetWindowRects SetWindowRects;
railSetWindowVisibilityRects SetWindowVisibilityRects;
};
FREERDP_API void rail_register_update_callbacks(rdpRail* rail, rdpUpdate* update);

View File

@ -284,6 +284,10 @@ void rail_CreateWindow(rdpRail* rail, rdpWindow* window)
{
IFCALL(rail->SetWindowRects, rail, window);
}
if (window->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
{
IFCALL(rail->SetWindowVisibilityRects, rail, window);
}
}
void rail_UpdateWindow(rdpRail* rail, rdpWindow* window)
@ -356,7 +360,7 @@ void rail_UpdateWindow(rdpRail* rail, rdpWindow* window)
if (window->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
{
IFCALL(rail->SetWindowVisibilityRects, rail, window);
}
}