CVS: rdesktop ewmhints.c,1.10,1.10.2.1 proto.h,1.87.2.3,1.87.2.4 xproto.h,1.4,1.4.2.1 xwin.c,1.205.2.7,1.205.2.8
Peter Ã
strand <[email protected]>
| Newsgroups | gmane.network.rdesktop.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/rdesktop/rdesktop
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27264
Modified Files:
Tag: seamlessrdp-branch
ewmhints.c proto.h xproto.h xwin.c
Log Message:
Implemented support for changing state normal/minimized/maximized via EWMH. Also, sending notifications to server when local state changes.
Index: ewmhints.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/ewmhints.c,v
retrieving revision 1.10
retrieving revision 1.10.2.1
diff -C2 -d -r1.10 -r1.10.2.1
*** ewmhints.c 12 Sep 2005 12:36:45 -0000 1.10
--- ewmhints.c 14 Mar 2006 13:56:50 -0000 1.10.2.1
***************
*** 25,29 ****
--- 25,36 ----
#include "rdesktop.h"
+ #define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
+ #define _NET_WM_STATE_ADD 1 /* add/set property */
+ #define _NET_WM_STATE_TOGGLE 2 /* toggle property */
+
extern Display *g_display;
+ static Atom g_net_wm_state_maximized_vert_atom, g_net_wm_state_maximized_horz_atom,
+ g_net_wm_state_hidden_atom;
+ Atom g_net_wm_state_atom;
/*
***************
*** 32,36 ****
*/
static int
! get_property_value(char *propname, long max_length,
unsigned long *nitems_return, unsigned char **prop_return)
{
--- 39,43 ----
*/
static int
! get_property_value(Window wnd, char *propname, long max_length,
unsigned long *nitems_return, unsigned char **prop_return)
{
***************
*** 48,52 ****
}
! result = XGetWindowProperty(g_display, DefaultRootWindow(g_display), property, 0, /* long_offset */
max_length, /* long_length */
False, /* delete */
--- 55,59 ----
}
! result = XGetWindowProperty(g_display, wnd, property, 0, /* long_offset */
max_length, /* long_length */
False, /* delete */
***************
*** 64,68 ****
if (actual_type_return == None || actual_format_return == 0)
{
! fprintf(stderr, "Root window is missing property %s\n", propname);
return (-1);
}
--- 71,75 ----
if (actual_type_return == None || actual_format_return == 0)
{
! fprintf(stderr, "Window is missing property %s\n", propname);
return (-1);
}
***************
*** 94,98 ****
int current_desktop;
! if (get_property_value("_NET_CURRENT_DESKTOP", 1, &nitems_return, &prop_return) < 0)
return (-1);
--- 101,107 ----
int current_desktop;
! if (get_property_value
! (DefaultRootWindow(g_display), "_NET_CURRENT_DESKTOP", 1, &nitems_return,
! &prop_return) < 0)
return (-1);
***************
*** 126,130 ****
const uint32 max_prop_length = 32 * 4; /* Max 32 desktops */
! if (get_property_value("_NET_WORKAREA", max_prop_length, &nitems_return, &prop_return) < 0)
return (-1);
--- 135,141 ----
const uint32 max_prop_length = 32 * 4; /* Max 32 desktops */
! if (get_property_value
! (DefaultRootWindow(g_display), "_NET_WORKAREA", max_prop_length, &nitems_return,
! &prop_return) < 0)
return (-1);
***************
*** 154,157 ****
--- 165,278 ----
+
+ void
+ ewmh_init()
+ {
+ g_net_wm_state_maximized_vert_atom =
+ XInternAtom(g_display, "_NET_WM_STATE_MAXIMIZED_VERT", False);
+ g_net_wm_state_maximized_horz_atom =
+ XInternAtom(g_display, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
+ g_net_wm_state_hidden_atom = XInternAtom(g_display, "_NET_WM_STATE_HIDDEN", False);
+ g_net_wm_state_atom = XInternAtom(g_display, "_NET_WM_STATE", False);
+ }
+
+
+ /*
+ Get the window state: normal/minimized/maximized.
+ */
+ #ifndef MAKE_PROTO
+ int
+ ewmh_get_window_state(Window w)
+ {
+ unsigned long nitems_return;
+ unsigned char *prop_return;
+ uint32 *return_words;
+ unsigned long item;
+ BOOL maximized_vert, maximized_horz, hidden;
+
+ maximized_vert = maximized_horz = hidden = False;
+
+ if (get_property_value(w, "_NET_WM_STATE", 64, &nitems_return, &prop_return) < 0)
+ return SEAMLESSRDP_NORMAL;
+
+ return_words = (uint32 *) prop_return;
+
+ for (item = 0; item < nitems_return; item++)
+ {
+ if (return_words[item] == g_net_wm_state_maximized_vert_atom)
+ maximized_vert = True;
+ if (return_words[item] == g_net_wm_state_maximized_horz_atom)
+ maximized_horz = True;
+ if (return_words[item] == g_net_wm_state_hidden_atom)
+ hidden = True;
+ }
+
+ XFree(prop_return);
+
+ if (maximized_vert && maximized_horz)
+ return SEAMLESSRDP_MAXIMIZED;
+ else if (hidden)
+ return SEAMLESSRDP_MINIMIZED;
+ else
+ return SEAMLESSRDP_NORMAL;
+ }
+
+ /*
+ Set the window state: normal/minimized/maximized.
+ Returns -1 on failure.
+ */
+ int
+ ewmh_change_state(Window wnd, int state)
+ {
+ Status status;
+ XEvent xevent;
+
+ /*
+ * Deal with the hidden atom
+ */
+ xevent.type = ClientMessage;
+ xevent.xclient.window = wnd;
+ xevent.xclient.message_type = g_net_wm_state_atom;
+ xevent.xclient.format = 32;
+ if (state == SEAMLESSRDP_MINIMIZED)
+ xevent.xclient.data.l[0] = _NET_WM_STATE_ADD;
+ else
+ xevent.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
+ xevent.xclient.data.l[1] = g_net_wm_state_hidden_atom;
+ xevent.xclient.data.l[2] = 0;
+ xevent.xclient.data.l[3] = 0;
+ xevent.xclient.data.l[4] = 0;
+ status = XSendEvent(g_display, DefaultRootWindow(g_display), False,
+ SubstructureNotifyMask | SubstructureRedirectMask, &xevent);
+ if (!status)
+ return -1;
+
+
+ /*
+ * Deal with the max atoms
+ */
+ xevent.type = ClientMessage;
+ xevent.xclient.window = wnd;
+ xevent.xclient.message_type = g_net_wm_state_atom;
+ xevent.xclient.format = 32;
+ if (state == SEAMLESSRDP_MAXIMIZED)
+ xevent.xclient.data.l[0] = _NET_WM_STATE_ADD;
+ else
+ xevent.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
+ xevent.xclient.data.l[1] = g_net_wm_state_maximized_vert_atom;
+ xevent.xclient.data.l[2] = g_net_wm_state_maximized_horz_atom;
+ xevent.xclient.data.l[3] = 0;
+ xevent.xclient.data.l[4] = 0;
+ status = XSendEvent(g_display, DefaultRootWindow(g_display), False,
+ SubstructureNotifyMask | SubstructureRedirectMask, &xevent);
+ if (!status)
+ return -1;
+
+ return 0;
+ }
+
+ #endif /* MAKE_PROTO */
+
+
#if 0
Index: proto.h
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/proto.h,v
retrieving revision 1.87.2.3
retrieving revision 1.87.2.4
diff -C2 -d -r1.87.2.3 -r1.87.2.4
*** proto.h 10 Mar 2006 12:44:32 -0000 1.87.2.3
--- proto.h 14 Mar 2006 13:56:50 -0000 1.87.2.4
***************
*** 68,71 ****
--- 68,72 ----
/* ewmhints.c */
int get_current_workarea(uint32 * x, uint32 * y, uint32 * width, uint32 * height);
+ void ewmh_init(void);
/* iso.c */
STREAM iso_init(int length);
***************
*** 284,287 ****
--- 285,289 ----
BOOL seamless_init(void);
void seamless_send_sync(void);
+ void seamless_send_state(unsigned long id, unsigned int state, unsigned long flags);
/* *INDENT-OFF* */
Index: xproto.h
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/xproto.h,v
retrieving revision 1.4
retrieving revision 1.4.2.1
diff -C2 -d -r1.4 -r1.4.2.1
*** xproto.h 9 Jul 2003 09:18:20 -0000 1.4
--- xproto.h 14 Mar 2006 13:56:50 -0000 1.4.2.1
***************
*** 3,4 ****
--- 3,6 ----
void xclip_handle_SelectionClear(void);
void xclip_handle_PropertyNotify(XPropertyEvent * xev);
+ int ewmh_get_window_state(Window w);
+ int ewmh_change_state(Window wnd, int state);
Index: xwin.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/xwin.c,v
retrieving revision 1.205.2.7
retrieving revision 1.205.2.8
diff -C2 -d -r1.205.2.7 -r1.205.2.8
*** xwin.c 10 Mar 2006 14:09:16 -0000 1.205.2.7
--- xwin.c 14 Mar 2006 13:56:50 -0000 1.205.2.8
***************
*** 57,60 ****
--- 57,61 ----
int xoffset, yoffset;
int width, height;
+ unsigned int state; /* normal/minimized/maximized */
struct _seamless_window *next;
} seamless_window;
***************
*** 84,87 ****
--- 85,89 ----
static HCURSOR g_null_cursor = NULL;
static Atom g_protocol_atom, g_kill_atom;
+ extern Atom g_net_wm_state_atom;
static BOOL g_focused;
static BOOL g_mouse_in_wnd;
***************
*** 1397,1400 ****
--- 1399,1403 ----
xclip_init();
+ ewmh_init();
if (g_seamless_rdp)
seamless_init();
***************
*** 1939,1942 ****
--- 1942,1961 ----
case PropertyNotify:
xclip_handle_PropertyNotify(&xevent.xproperty);
+ if (xevent.xproperty.window == g_wnd)
+ break;
+ if (xevent.xproperty.window == DefaultRootWindow(g_display))
+ break;
+
+ /* seamless */
+ sw = seamless_get_window_by_wnd(xevent.xproperty.window);
+ if (!sw)
+ break;
+
+ if ((xevent.xproperty.atom == g_net_wm_state_atom)
+ && (xevent.xproperty.state == PropertyNewValue))
+ {
+ sw->state = ewmh_get_window_state(sw->wnd);
+ seamless_send_state(sw->id, sw->state, 0);
+ }
break;
case MapNotify:
***************
*** 3038,3041 ****
--- 3057,3061 ----
get_input_mask(&input_mask);
+ input_mask |= PropertyChangeMask;
XSelectInput(g_display, wnd, input_mask);
***************
*** 3104,3107 ****
--- 3124,3132 ----
sw->height = MIN(MIN(height, height + y), g_height - sw->yoffset);
+ /* If we move the window in a maximized state, then KDE won't
+ accept restoration */
+ if (sw->state != SEAMLESSRDP_NORMAL)
+ return;
+
/* FIXME: Perhaps use ewmh_net_moveresize_window instead */
XMoveResizeWindow(g_display, sw->wnd, sw->xoffset, sw->yoffset, sw->width, sw->height);
***************
*** 3137,3147 ****
}
switch (state)
{
case SEAMLESSRDP_NORMAL:
case SEAMLESSRDP_MAXIMIZED:
! XMapWindow(g_display, sw->wnd);
break;
case SEAMLESSRDP_MINIMIZED:
XIconifyWindow(g_display, sw->wnd, DefaultScreen(g_display));
break;
--- 3162,3179 ----
}
+ sw->state = state;
+
switch (state)
{
case SEAMLESSRDP_NORMAL:
case SEAMLESSRDP_MAXIMIZED:
! ewmh_change_state(sw->wnd, state);
break;
case SEAMLESSRDP_MINIMIZED:
+ /* EWMH says: "if an Application asks to toggle _NET_WM_STATE_HIDDEN
+ the Window Manager should probably just ignore the request, since
+ _NET_WM_STATE_HIDDEN is a function of some other aspect of the window
+ such as minimization, rather than an independent state." Besides,
+ XIconifyWindow is easier. */
XIconifyWindow(g_display, sw->wnd, DefaultScreen(g_display));
break;
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642