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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.