xfreerdp: remove backbuffer window in RemoteApp mode

This commit is contained in:
Marc-André Moreau 2011-08-18 01:16:49 -04:00
parent 2aa3d6f731
commit 3fa7d4a3d4
7 changed files with 116 additions and 74 deletions

View File

@ -29,18 +29,37 @@ void xf_send_mouse_motion_event(rdpInput* input, boolean down, uint32 button, ui
boolean xf_event_Expose(xfInfo* xfi, XEvent* event, boolean app) boolean xf_event_Expose(xfInfo* xfi, XEvent* event, boolean app)
{ {
int x; int x, y;
int y; int cx, cy;
int cx;
int cy;
if (event->xexpose.window == xfi->window->handle) if (app != True)
{ {
x = event->xexpose.x; x = event->xexpose.x;
y = event->xexpose.y; y = event->xexpose.y;
cx = event->xexpose.width; cx = event->xexpose.width;
cy = event->xexpose.height; cy = event->xexpose.height;
XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc_default, x, y, cx, cy, x, y); XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, x, y, cx, cy, x, y);
}
else
{
xfWindow* xfw;
rdpWindow* window;
window = window_list_get_by_extra_id(xfi->rail->list, (void*) event->xany.window);
if (window != NULL)
{
xfw = (xfWindow*) window->extra;
XPutImage(xfi->display, xfi->primary, xfw->gc, xfi->image,
window->windowOffsetX, window->windowOffsetY,
window->windowOffsetX, window->windowOffsetY,
window->windowWidth, window->windowHeight);
XCopyArea(xfi->display, xfi->primary, xfw->handle, xfw->gc,
window->windowOffsetX, window->windowOffsetY,
window->windowWidth, window->windowHeight, 0, 0);
}
} }
return True; return True;
@ -48,7 +67,7 @@ boolean xf_event_Expose(xfInfo* xfi, XEvent* event, boolean app)
boolean xf_event_VisibilityNotify(xfInfo* xfi, XEvent* event, boolean app) boolean xf_event_VisibilityNotify(xfInfo* xfi, XEvent* event, boolean app)
{ {
if (event->xvisibility.window == xfi->window->handle) if (app != True)
xfi->unobscured = event->xvisibility.state == VisibilityUnobscured; xfi->unobscured = event->xvisibility.state == VisibilityUnobscured;
return True; return True;
@ -60,7 +79,7 @@ boolean xf_event_MotionNotify(xfInfo* xfi, XEvent* event, boolean app)
input = xfi->instance->input; input = xfi->instance->input;
if (event->xmotion.window == xfi->window->handle) if (app != True)
{ {
if (xfi->mouse_motion != True) if (xfi->mouse_motion != True)
{ {
@ -69,10 +88,10 @@ boolean xf_event_MotionNotify(xfInfo* xfi, XEvent* event, boolean app)
} }
input->MouseEvent(input, PTR_FLAGS_MOVE, event->xmotion.x, event->xmotion.y); input->MouseEvent(input, PTR_FLAGS_MOVE, event->xmotion.x, event->xmotion.y);
}
if (xfi->fullscreen) if (xfi->fullscreen)
XSetInputFocus(xfi->display, xfi->window->handle, RevertToPointerRoot, CurrentTime); XSetInputFocus(xfi->display, xfi->window->handle, RevertToPointerRoot, CurrentTime);
}
return True; return True;
} }
@ -258,7 +277,7 @@ boolean xf_event_FocusIn(xfInfo* xfi, XEvent* event, boolean app)
xfi->focused = True; xfi->focused = True;
if (xfi->mouse_active) if (xfi->mouse_active && (app != True))
XGrabKeyboard(xfi->display, xfi->window->handle, True, GrabModeAsync, GrabModeAsync, CurrentTime); XGrabKeyboard(xfi->display, xfi->window->handle, True, GrabModeAsync, GrabModeAsync, CurrentTime);
xf_kbd_focus_in(xfi); xf_kbd_focus_in(xfi);
@ -309,13 +328,16 @@ boolean xf_event_ClientMessage(xfInfo* xfi, XEvent* event, boolean app)
boolean xf_event_EnterNotify(xfInfo* xfi, XEvent* event, boolean app) boolean xf_event_EnterNotify(xfInfo* xfi, XEvent* event, boolean app)
{ {
xfi->mouse_active = True; if (app != True)
{
xfi->mouse_active = True;
if (xfi->fullscreen) if (xfi->fullscreen)
XSetInputFocus(xfi->display, xfi->window->handle, RevertToPointerRoot, CurrentTime); XSetInputFocus(xfi->display, xfi->window->handle, RevertToPointerRoot, CurrentTime);
if (xfi->focused) if (xfi->focused)
XGrabKeyboard(xfi->display, xfi->window->handle, True, GrabModeAsync, GrabModeAsync, CurrentTime); XGrabKeyboard(xfi->display, xfi->window->handle, True, GrabModeAsync, GrabModeAsync, CurrentTime);
}
return True; return True;
} }
@ -328,14 +350,26 @@ boolean xf_event_LeaveNotify(xfInfo* xfi, XEvent* event, boolean app)
return True; return True;
} }
boolean xf_event_ConfigureNotify(xfInfo* xfi, XEvent* event, boolean app)
{
return True;
}
boolean xf_event_process(freerdp* instance, XEvent* event) boolean xf_event_process(freerdp* instance, XEvent* event)
{ {
boolean app = False; boolean app = False;
boolean status = True; boolean status = True;
xfInfo* xfi = GET_XFI(instance); xfInfo* xfi = GET_XFI(instance);
if (event->xany.window != xfi->window->handle) if (xfi->remote_app == True)
{
app = True; app = True;
}
else
{
if (event->xany.window != xfi->window->handle)
app = True;
}
switch (event->type) switch (event->type)
{ {
@ -390,6 +424,7 @@ boolean xf_event_process(freerdp* instance, XEvent* event)
break; break;
case ConfigureNotify: case ConfigureNotify:
status = xf_event_ConfigureNotify(xfi, event, app);
break; break;
case MapNotify: case MapNotify:

View File

@ -103,11 +103,14 @@ void xf_kbd_send_key(xfInfo* xfi, boolean down, uint8 keycode)
int xf_kbd_read_keyboard_state(xfInfo* xfi) int xf_kbd_read_keyboard_state(xfInfo* xfi)
{ {
int dummy; int dummy;
uint32 state;
Window wdummy; Window wdummy;
uint32 state = 0;
XQueryPointer(xfi->display, xfi->window->handle, if (xfi->remote_app != True)
{
XQueryPointer(xfi->display, xfi->window->handle,
&wdummy, &wdummy, &dummy, &dummy, &dummy, &dummy, &state); &wdummy, &wdummy, &dummy, &dummy, &dummy, &dummy, &state);
}
return state; return state;
} }

View File

@ -34,12 +34,14 @@ void xf_rail_paint(xfInfo* xfi, rdpRail* rail)
window = window_list_get_next(rail->list); window = window_list_get_next(rail->list);
xfw = (xfWindow*) window->extra; xfw = (xfWindow*) window->extra;
//printf("painting window 0x%08X\n", window->windowId); XPutImage(xfi->display, xfi->primary, xfw->gc, xfi->image,
XCopyArea(xfi->display, xfi->window->handle, xfw->handle, xfw->gc,
window->windowOffsetX, window->windowOffsetY, window->windowOffsetX, window->windowOffsetY,
window->windowWidth, window->windowHeight, window->windowOffsetX, window->windowOffsetY,
0, 0); window->windowWidth, window->windowHeight);
XCopyArea(xfi->display, xfi->primary, xfw->handle, xfw->gc,
window->windowOffsetX, window->windowOffsetY,
window->windowWidth, window->windowHeight, 0, 0);
XFlush(xfi->display); XFlush(xfi->display);
} }
@ -73,6 +75,8 @@ void xf_rail_MoveWindow(rdpRail* rail, rdpWindow* window)
window->windowOffsetX + xfi->workArea.x, window->windowOffsetX + xfi->workArea.x,
window->windowOffsetY + xfi->workArea.y, window->windowOffsetY + xfi->workArea.y,
window->windowWidth, window->windowHeight); window->windowWidth, window->windowHeight);
XFlush(xfi->display);
} }
void xf_rail_DestroyWindow(rdpRail* rail, rdpWindow* window) void xf_rail_DestroyWindow(rdpRail* rail, rdpWindow* window)

View File

@ -116,8 +116,6 @@ boolean window_GetWorkArea(xfInfo* xfi)
xfi->workArea.height = plong[xfi->current_desktop * 4 + 3]; xfi->workArea.height = plong[xfi->current_desktop * 4 + 3];
xfree(prop); xfree(prop);
printf("x:%d y:%d w:%d h:%d\n", xfi->workArea.x, xfi->workArea.y, xfi->workArea.width, xfi->workArea.height);
return True; return True;
} }
@ -148,7 +146,7 @@ void window_show_decorations(xfInfo* xfi, xfWindow* window, boolean show)
window->decorations = show; window->decorations = show;
} }
xfWindow* window_create(xfInfo* xfi, char* name) xfWindow* desktop_create(xfInfo* xfi, char* name)
{ {
xfWindow* window; xfWindow* window;
@ -272,6 +270,7 @@ xfWindow* xf_CreateWindow(xfInfo* xfi, int x, int y, int width, int height, char
void xf_MoveWindow(xfInfo* xfi, xfWindow* window, int x, int y, int width, int height) void xf_MoveWindow(xfInfo* xfi, xfWindow* window, int x, int y, int width, int height)
{ {
XSizeHints* size_hints;
XWindowChanges changes; XWindowChanges changes;
changes.x = x; changes.x = x;
@ -280,6 +279,22 @@ void xf_MoveWindow(xfInfo* xfi, xfWindow* window, int x, int y, int width, int h
changes.height = height; changes.height = height;
XConfigureWindow(xfi->display, window->handle, CWX | CWY | CWWidth | CWHeight, &changes); XConfigureWindow(xfi->display, window->handle, CWX | CWY | CWWidth | CWHeight, &changes);
window->width = width;
window->height = height;
XFreePixmap(xfi->display, window->surface);
window->surface = XCreatePixmap(xfi->display, window->handle, window->width, window->height, xfi->depth);
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);
}
} }
void xf_DestroyWindow(xfInfo* xfi, xfWindow* window) void xf_DestroyWindow(xfInfo* xfi, xfWindow* window)

View File

@ -45,7 +45,7 @@ boolean window_GetWorkArea(xfInfo* xfi);
void window_fullscreen(xfInfo* xfi, xfWindow* window, boolean fullscreen); void window_fullscreen(xfInfo* xfi, xfWindow* window, boolean fullscreen);
void window_show_decorations(xfInfo* xfi, xfWindow* window, boolean show); void window_show_decorations(xfInfo* xfi, xfWindow* window, boolean show);
xfWindow* window_create(xfInfo* xfi, char* name); xfWindow* desktop_create(xfInfo* xfi, char* name);
xfWindow* xf_CreateWindow(xfInfo* xfi, int x, int y, int width, int height, char* name); xfWindow* xf_CreateWindow(xfInfo* xfi, int x, int y, int width, int height, char* name);
void xf_MoveWindow(xfInfo* xfi, xfWindow* window, int x, int y, int width, int height); void xf_MoveWindow(xfInfo* xfi, xfWindow* window, int x, int y, int width, int height);

View File

@ -71,12 +71,16 @@ void xf_end_paint(rdpUpdate* update)
w = gdi->primary->hdc->hwnd->invalid->w; w = gdi->primary->hdc->hwnd->invalid->w;
h = gdi->primary->hdc->hwnd->invalid->h; h = gdi->primary->hdc->hwnd->invalid->h;
XPutImage(xfi->display, xfi->primary, xfi->gc_default, xfi->image, x, y, x, y, w, h); if (xfi->remote_app != True)
XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc_default, x, y, w, h, x, y); {
XFlush(xfi->display); XPutImage(xfi->display, xfi->primary, xfi->gc, xfi->image, x, y, x, y, w, h);
XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, x, y, w, h, x, y);
if (xfi->remote_app == True) XFlush(xfi->display);
}
else
{
xf_rail_paint(xfi, update->rail); xf_rail_paint(xfi, update->rail);
}
} }
boolean xf_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount) boolean xf_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount)
@ -283,39 +287,35 @@ boolean xf_post_connect(freerdp* instance)
xfi->attribs.override_redirect = xfi->fullscreen; xfi->attribs.override_redirect = xfi->fullscreen;
xfi->attribs.colormap = xfi->colormap; xfi->attribs.colormap = xfi->colormap;
xfi->window = window_create(xfi, "xfreerdp"); if (xfi->remote_app != True)
window_show_decorations(xfi, xfi->window, xfi->decoration);
window_fullscreen(xfi, xfi->window, xfi->fullscreen);
/* wait for VisibilityNotify */
do
{ {
XMaskEvent(xfi->display, VisibilityChangeMask, &xevent); xfi->window = desktop_create(xfi, "xfreerdp");
window_show_decorations(xfi, xfi->window, xfi->decoration);
window_fullscreen(xfi, xfi->window, xfi->fullscreen);
/* wait for VisibilityNotify */
do
{
XMaskEvent(xfi->display, VisibilityChangeMask, &xevent);
}
while (xevent.type != VisibilityNotify);
xfi->unobscured = (xevent.xvisibility.state == VisibilityUnobscured);
protocol_atom = XInternAtom(xfi->display, "WM_PROTOCOLS", True);
kill_atom = XInternAtom(xfi->display, "WM_DELETE_WINDOW", True);
XSetWMProtocols(xfi->display, xfi->window->handle, &kill_atom, 1);
} }
while (xevent.type != VisibilityNotify);
xfi->unobscured = (xevent.xvisibility.state == VisibilityUnobscured);
memset(&gcv, 0, sizeof(gcv)); memset(&gcv, 0, sizeof(gcv));
xfi->modifier_map = XGetModifierMapping(xfi->display);
protocol_atom = XInternAtom(xfi->display, "WM_PROTOCOLS", True); xfi->gc = XCreateGC(xfi->display, DefaultRootWindow(xfi->display), GCGraphicsExposures, &gcv);
kill_atom = XInternAtom(xfi->display, "WM_DELETE_WINDOW", True); xfi->primary = XCreatePixmap(xfi->display, DefaultRootWindow(xfi->display), xfi->width, xfi->height, xfi->depth);
XSetWMProtocols(xfi->display, xfi->window->handle, &kill_atom, 1);
if (!xfi->gc)
xfi->gc = XCreateGC(xfi->display, xfi->window->handle, GCGraphicsExposures, &gcv);
if (!xfi->primary)
xfi->primary = XCreatePixmap(xfi->display, xfi->window->handle, xfi->width, xfi->height, xfi->depth);
xfi->drawing = xfi->primary;
xfi->bitmap_mono = XCreatePixmap(xfi->display, xfi->window->handle, 8, 8, 1);
xfi->gc_mono = XCreateGC(xfi->display, xfi->bitmap_mono, GCGraphicsExposures, &gcv);
xfi->gc_default = XCreateGC(xfi->display, xfi->window->handle, GCGraphicsExposures, &gcv);
XSetForeground(xfi->display, xfi->gc, BlackPixelOfScreen(xfi->screen)); XSetForeground(xfi->display, xfi->gc, BlackPixelOfScreen(xfi->screen));
XFillRectangle(xfi->display, xfi->primary, xfi->gc, 0, 0, xfi->width, xfi->height); XFillRectangle(xfi->display, xfi->primary, xfi->gc, 0, 0, xfi->width, xfi->height);
xfi->modifier_map = XGetModifierMapping(xfi->display);
xfi->image = XCreateImage(xfi->display, xfi->visual, xfi->depth, ZPixmap, 0, xfi->image = XCreateImage(xfi->display, xfi->visual, xfi->depth, ZPixmap, 0,
(char*) gdi->primary_buffer, gdi->width, gdi->height, xfi->scanline_pad, 0); (char*) gdi->primary_buffer, gdi->width, gdi->height, xfi->scanline_pad, 0);
@ -399,16 +399,6 @@ void xf_window_free(xfInfo* xfi)
XFreeModifiermap(xfi->modifier_map); XFreeModifiermap(xfi->modifier_map);
xfi->modifier_map = 0; xfi->modifier_map = 0;
XFreeGC(xfi->display, xfi->gc_default);
xfi->gc_default = 0;
XFreeGC(xfi->display, xfi->gc_mono);
xfi->gc_mono = 0;
/* Note: valgrind reports this at lost no matter what */
XFreePixmap(xfi->display, xfi->bitmap_mono);
xfi->bitmap_mono = 0;
XFreeGC(xfi->display, xfi->gc); XFreeGC(xfi->display, xfi->gc);
xfi->gc = 0; xfi->gc = 0;

View File

@ -57,7 +57,6 @@ struct xf_info
Screen* screen; Screen* screen;
XImage* image; XImage* image;
Pixmap primary; Pixmap primary;
Drawable drawing;
Visual* visual; Visual* visual;
Display* display; Display* display;
Colormap colormap; Colormap colormap;
@ -74,10 +73,6 @@ struct xf_info
boolean remote_app; boolean remote_app;
rdpRail* rail; rdpRail* rail;
GC gc_mono;
GC gc_default;
Pixmap bitmap_mono;
boolean focused; boolean focused;
boolean mouse_active; boolean mouse_active;
boolean mouse_motion; boolean mouse_motion;