Send back our local positions upon changes, but only after a small timeout.
git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/branches/seamlessrdp-branch/rdesktop@1156 423420c4-83ab-492f-b58f-81f9feb106b5
This commit is contained in:
parent
d54d68dccc
commit
2e7aa4b8b4
@ -418,3 +418,4 @@ enum RDP_INPUT_DEVICE
|
|||||||
#define SEAMLESSRDP_NORMAL 0
|
#define SEAMLESSRDP_NORMAL 0
|
||||||
#define SEAMLESSRDP_MINIMIZED 1
|
#define SEAMLESSRDP_MINIMIZED 1
|
||||||
#define SEAMLESSRDP_MAXIMIZED 2
|
#define SEAMLESSRDP_MAXIMIZED 2
|
||||||
|
#define SEAMLESSRDP_POSITION_TIMER 200000
|
||||||
|
3
proto.h
3
proto.h
@ -288,6 +288,9 @@ BOOL lspci_init(void);
|
|||||||
BOOL seamless_init(void);
|
BOOL seamless_init(void);
|
||||||
void seamless_send_sync(void);
|
void seamless_send_sync(void);
|
||||||
void seamless_send_state(unsigned long id, unsigned int state, unsigned long flags);
|
void seamless_send_state(unsigned long id, unsigned int state, unsigned long flags);
|
||||||
|
void seamless_send_position(unsigned long id, int x, int y, int width, int height,
|
||||||
|
unsigned long flags);
|
||||||
|
void seamless_select_timeout(struct timeval *tv);
|
||||||
void seamless_send_zchange(unsigned long id, unsigned long below, unsigned long flags);
|
void seamless_send_zchange(unsigned long id, unsigned long below, unsigned long flags);
|
||||||
void seamless_send_focus(unsigned long id, unsigned long flags);
|
void seamless_send_focus(unsigned long id, unsigned long flags);
|
||||||
|
|
||||||
|
16
rdesktop.h
16
rdesktop.h
@ -67,6 +67,22 @@
|
|||||||
#define MAX(x,y) (((x) > (y)) ? (x) : (y))
|
#define MAX(x,y) (((x) > (y)) ? (x) : (y))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* timeval macros */
|
||||||
|
#ifndef timerisset
|
||||||
|
#define timerisset(tvp)\
|
||||||
|
((tvp)->tv_sec || (tvp)->tv_usec)
|
||||||
|
#endif
|
||||||
|
#ifndef timercmp
|
||||||
|
#define timercmp(tvp, uvp, cmp)\
|
||||||
|
((tvp)->tv_sec cmp (uvp)->tv_sec ||\
|
||||||
|
(tvp)->tv_sec == (uvp)->tv_sec &&\
|
||||||
|
(tvp)->tv_usec cmp (uvp)->tv_usec)
|
||||||
|
#endif
|
||||||
|
#ifndef timerclear
|
||||||
|
#define timerclear(tvp)\
|
||||||
|
((tvp)->tv_sec = (tvp)->tv_usec = 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* If configure does not define the endianess, try
|
/* If configure does not define the endianess, try
|
||||||
to find it out */
|
to find it out */
|
||||||
#if !defined(L_ENDIAN) && !defined(B_ENDIAN)
|
#if !defined(L_ENDIAN) && !defined(B_ENDIAN)
|
||||||
|
24
seamless.c
24
seamless.c
@ -339,6 +339,30 @@ seamless_send_state(unsigned long id, unsigned int state, unsigned long flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
seamless_send_position(unsigned long id, int x, int y, int width, int height, unsigned long flags)
|
||||||
|
{
|
||||||
|
seamless_send("POSITION,0x%08lx,%d,%d,%d,%d,0x%lx\n", id, x, y, width, height, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Update select timeout */
|
||||||
|
void
|
||||||
|
seamless_select_timeout(struct timeval *tv)
|
||||||
|
{
|
||||||
|
struct timeval ourtimeout = { 0, SEAMLESSRDP_POSITION_TIMER };
|
||||||
|
|
||||||
|
if (g_seamless_rdp)
|
||||||
|
{
|
||||||
|
if (timercmp(&ourtimeout, tv, <))
|
||||||
|
{
|
||||||
|
tv->tv_sec = ourtimeout.tv_sec;
|
||||||
|
tv->tv_usec = ourtimeout.tv_usec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
seamless_send_zchange(unsigned long id, unsigned long below, unsigned long flags)
|
seamless_send_zchange(unsigned long id, unsigned long below, unsigned long flags)
|
||||||
{
|
{
|
||||||
|
87
xwin.c
87
xwin.c
@ -60,6 +60,7 @@ typedef struct _seamless_window
|
|||||||
int width, height;
|
int width, height;
|
||||||
int state; /* normal/minimized/maximized. */
|
int state; /* normal/minimized/maximized. */
|
||||||
unsigned int desktop;
|
unsigned int desktop;
|
||||||
|
struct timeval *position_timer;
|
||||||
struct _seamless_window *next;
|
struct _seamless_window *next;
|
||||||
} seamless_window;
|
} seamless_window;
|
||||||
static seamless_window *g_seamless_windows = NULL;
|
static seamless_window *g_seamless_windows = NULL;
|
||||||
@ -325,6 +326,45 @@ seamless_all_to_desktop(Window wnd, unsigned int desktop)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Send our position */
|
||||||
|
static void
|
||||||
|
seamless_update_position(seamless_window * sw)
|
||||||
|
{
|
||||||
|
XWindowAttributes wa;
|
||||||
|
int x, y;
|
||||||
|
Window child_return;
|
||||||
|
|
||||||
|
XGetWindowAttributes(g_display, sw->wnd, &wa);
|
||||||
|
XTranslateCoordinates(g_display, sw->wnd, wa.root,
|
||||||
|
-wa.border_width, -wa.border_width, &x, &y, &child_return);
|
||||||
|
|
||||||
|
seamless_send_position(sw->id, x, y, wa.width, wa.height, 0);
|
||||||
|
sw->xoffset = x;
|
||||||
|
sw->yoffset = y;
|
||||||
|
sw->width = wa.width;
|
||||||
|
sw->height = wa.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Check if it's time to send our position */
|
||||||
|
static void
|
||||||
|
seamless_check_timers()
|
||||||
|
{
|
||||||
|
seamless_window *sw;
|
||||||
|
struct timeval now;
|
||||||
|
|
||||||
|
gettimeofday(&now, NULL);
|
||||||
|
for (sw = g_seamless_windows; sw; sw = sw->next)
|
||||||
|
{
|
||||||
|
if (timerisset(sw->position_timer) && timercmp(sw->position_timer, &now, <))
|
||||||
|
{
|
||||||
|
timerclear(sw->position_timer);
|
||||||
|
seamless_update_position(sw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
seamless_restack_window(seamless_window * sw, unsigned long behind)
|
seamless_restack_window(seamless_window * sw, unsigned long behind)
|
||||||
{
|
{
|
||||||
@ -2085,12 +2125,31 @@ xwin_process_events(void)
|
|||||||
rdp_send_client_window_status(0);
|
rdp_send_client_window_status(0);
|
||||||
break;
|
break;
|
||||||
case ConfigureNotify:
|
case ConfigureNotify:
|
||||||
/* seamless */
|
if (!g_seamless_active)
|
||||||
sw = seamless_get_window_by_wnd(xevent.xconfigure.window);
|
|
||||||
if (!sw)
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
sw = seamless_get_window_by_wnd(xevent.xconfigure.window);
|
||||||
|
if (!sw)
|
||||||
|
{
|
||||||
|
error("ConfigureNotify for unknown window 0x%lx\n",
|
||||||
|
xevent.xconfigure.window);
|
||||||
|
}
|
||||||
|
|
||||||
|
gettimeofday(sw->position_timer, NULL);
|
||||||
|
if (sw->position_timer->tv_usec + SEAMLESSRDP_POSITION_TIMER >=
|
||||||
|
1000000)
|
||||||
|
{
|
||||||
|
sw->position_timer->tv_usec +=
|
||||||
|
SEAMLESSRDP_POSITION_TIMER - 1000000;
|
||||||
|
sw->position_timer->tv_sec += 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sw->position_timer->tv_usec += SEAMLESSRDP_POSITION_TIMER;
|
||||||
|
}
|
||||||
|
|
||||||
ui_seamless_handle_restack(sw);
|
ui_seamless_handle_restack(sw);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Keep going */
|
/* Keep going */
|
||||||
@ -2114,6 +2173,9 @@ ui_select(int rdp_socket)
|
|||||||
/* User quit */
|
/* User quit */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (g_seamless_active)
|
||||||
|
seamless_check_timers();
|
||||||
|
|
||||||
FD_ZERO(&rfds);
|
FD_ZERO(&rfds);
|
||||||
FD_ZERO(&wfds);
|
FD_ZERO(&wfds);
|
||||||
FD_SET(rdp_socket, &rfds);
|
FD_SET(rdp_socket, &rfds);
|
||||||
@ -2133,6 +2195,7 @@ ui_select(int rdp_socket)
|
|||||||
|
|
||||||
/* add redirection handles */
|
/* add redirection handles */
|
||||||
rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout);
|
rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout);
|
||||||
|
seamless_select_timeout(&tv);
|
||||||
|
|
||||||
n++;
|
n++;
|
||||||
|
|
||||||
@ -3216,7 +3279,7 @@ ui_seamless_create_window(unsigned long id, unsigned long parent, unsigned long
|
|||||||
serverside, instead of terminating rdesktop */
|
serverside, instead of terminating rdesktop */
|
||||||
XSetWMProtocols(g_display, wnd, &g_kill_atom, 1);
|
XSetWMProtocols(g_display, wnd, &g_kill_atom, 1);
|
||||||
|
|
||||||
sw = malloc(sizeof(seamless_window));
|
sw = xmalloc(sizeof(seamless_window));
|
||||||
sw->wnd = wnd;
|
sw->wnd = wnd;
|
||||||
sw->id = id;
|
sw->id = id;
|
||||||
sw->parent = parent;
|
sw->parent = parent;
|
||||||
@ -3227,6 +3290,8 @@ ui_seamless_create_window(unsigned long id, unsigned long parent, unsigned long
|
|||||||
sw->height = 0;
|
sw->height = 0;
|
||||||
sw->state = SEAMLESSRDP_NOTYETMAPPED;
|
sw->state = SEAMLESSRDP_NOTYETMAPPED;
|
||||||
sw->desktop = 0;
|
sw->desktop = 0;
|
||||||
|
sw->position_timer = xmalloc(sizeof(struct timeval));
|
||||||
|
timerclear(sw->position_timer);
|
||||||
sw->next = g_seamless_windows;
|
sw->next = g_seamless_windows;
|
||||||
g_seamless_windows = sw;
|
g_seamless_windows = sw;
|
||||||
}
|
}
|
||||||
@ -3271,16 +3336,10 @@ ui_seamless_move_window(unsigned long id, int x, int y, int width, int height, u
|
|||||||
/* X11 windows must be at least 1x1 */
|
/* X11 windows must be at least 1x1 */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* About MAX and MIN: Windows allows moving a window outside
|
sw->xoffset = x;
|
||||||
the desktop. This happens, for example, when maximizing an
|
sw->yoffset = y;
|
||||||
application. In this case, the position is set to something
|
sw->width = width;
|
||||||
like -4,-4,1288,1032. Many WMs does not allow windows
|
sw->height = height;
|
||||||
outside the desktop, however. Therefore, clip the window
|
|
||||||
ourselves. */
|
|
||||||
sw->xoffset = MAX(0, x);
|
|
||||||
sw->yoffset = MAX(0, y);
|
|
||||||
sw->width = MIN(MIN(width, width + x), g_width - sw->xoffset);
|
|
||||||
sw->height = MIN(MIN(height, height + y), g_height - sw->yoffset);
|
|
||||||
|
|
||||||
/* If we move the window in a maximized state, then KDE won't
|
/* If we move the window in a maximized state, then KDE won't
|
||||||
accept restoration */
|
accept restoration */
|
||||||
|
Loading…
Reference in New Issue
Block a user