CVS: rdesktop constants.h,1.45.2.3,1.45.2.4 ewmhints.c,1.10.2.8,1.10.2.9 proto.h,1.87.2.10,1.87.2.11 seamless.c,1.1.2.19,1.1.2.20 xproto.h,1.4.2.5,1.4.2.6 xwin.c,1.205.2.31,1.205.2.32

Pierre Ossman <[email protected]> Tue, 21 Mar 2006 06:42:28 -0800
Newsgroups gmane.network.rdesktop.cvs
Message-ID <[email protected]>
Update of /cvsroot/rdesktop/rdesktop
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14632

Modified Files:
      Tag: seamlessrdp-branch
	constants.h ewmhints.c proto.h seamless.c xproto.h xwin.c 
Log Message:
Support for window groups and modal windows.


Index: constants.h
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/constants.h,v
retrieving revision 1.45.2.3
retrieving revision 1.45.2.4
diff -C2 -d -r1.45.2.3 -r1.45.2.4
*** constants.h	17 Mar 2006 12:39:09 -0000	1.45.2.3
--- constants.h	21 Mar 2006 14:42:24 -0000	1.45.2.4
***************
*** 420,421 ****
--- 420,423 ----
  #define SEAMLESSRDP_MAXIMIZED 2
  #define SEAMLESSRDP_POSITION_TIMER 200000
+ 
+ #define SEAMLESSRDP_CREATE_MODAL	0x0001

Index: ewmhints.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/ewmhints.c,v
retrieving revision 1.10.2.8
retrieving revision 1.10.2.9
diff -C2 -d -r1.10.2.8 -r1.10.2.9
*** ewmhints.c	17 Mar 2006 15:16:52 -0000	1.10.2.8
--- ewmhints.c	21 Mar 2006 14:42:24 -0000	1.10.2.9
***************
*** 35,39 ****
  static Atom g_net_wm_state_maximized_vert_atom, g_net_wm_state_maximized_horz_atom,
  	g_net_wm_state_hidden_atom, g_net_wm_name_atom, g_utf8_string_atom,
! 	g_net_wm_state_skip_taskbar_atom, g_net_wm_state_skip_pager_atom;
  
  Atom g_net_wm_state_atom, g_net_wm_desktop_atom;
--- 35,39 ----
  static Atom g_net_wm_state_maximized_vert_atom, g_net_wm_state_maximized_horz_atom,
  	g_net_wm_state_hidden_atom, g_net_wm_name_atom, g_utf8_string_atom,
! 	g_net_wm_state_skip_taskbar_atom, g_net_wm_state_skip_pager_atom, g_net_wm_state_modal_atom;
  
  Atom g_net_wm_state_atom, g_net_wm_desktop_atom;
***************
*** 184,187 ****
--- 184,188 ----
  		XInternAtom(g_display, "_NET_WM_STATE_SKIP_TASKBAR", False);
  	g_net_wm_state_skip_pager_atom = XInternAtom(g_display, "_NET_WM_STATE_SKIP_PAGER", False);
+ 	g_net_wm_state_modal_atom = XInternAtom(g_display, "_NET_WM_STATE_MODAL", False);
  	g_net_wm_state_atom = XInternAtom(g_display, "_NET_WM_STATE", False);
  	g_net_wm_desktop_atom = XInternAtom(g_display, "_NET_WM_DESKTOP", False);
***************
*** 406,409 ****
--- 407,418 ----
  }
  
+ int
+ ewmh_set_window_modal(Window wnd)
+ {
+ 	if (ewmh_modify_state(wnd, 1, g_net_wm_state_modal_atom, 0) < 0)
+ 		return -1;
+ 	return 0;
+ }
+ 
  #endif /* MAKE_PROTO */
  

Index: proto.h
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/proto.h,v
retrieving revision 1.87.2.10
retrieving revision 1.87.2.11
diff -C2 -d -r1.87.2.10 -r1.87.2.11
*** proto.h	20 Mar 2006 12:36:14 -0000	1.87.2.10
--- proto.h	21 Mar 2006 14:42:24 -0000	1.87.2.11
***************
*** 275,279 ****
  void ui_seamless_begin(void);
  void ui_seamless_toggle(void);
! void ui_seamless_create_window(unsigned long id, unsigned long parent, unsigned long flags);
  void ui_seamless_destroy_window(unsigned long id, unsigned long flags);
  void ui_seamless_move_window(unsigned long id, int x, int y, int width, int height,
--- 275,280 ----
  void ui_seamless_begin(void);
  void ui_seamless_toggle(void);
! void ui_seamless_create_window(unsigned long id, unsigned long group, unsigned long parent,
! 			       unsigned long flags);
  void ui_seamless_destroy_window(unsigned long id, unsigned long flags);
  void ui_seamless_move_window(unsigned long id, int x, int y, int width, int height,

Index: seamless.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/Attic/seamless.c,v
retrieving revision 1.1.2.19
retrieving revision 1.1.2.20
diff -C2 -d -r1.1.2.19 -r1.1.2.20
*** seamless.c	20 Mar 2006 15:43:14 -0000	1.1.2.19
--- seamless.c	21 Mar 2006 14:42:24 -0000	1.1.2.20
***************
*** 83,88 ****
  	if (!strcmp("CREATE", tok1))
  	{
! 		unsigned long parent;
! 		if (!tok5)
  			return False;
  
--- 83,88 ----
  	if (!strcmp("CREATE", tok1))
  	{
! 		unsigned long group, parent;
! 		if (!tok6)
  			return False;
  
***************
*** 91,103 ****
  			return False;
  
! 		parent = strtoul(tok4, &endptr, 0);
  		if (*endptr)
  			return False;
  
! 		flags = strtoul(tok5, &endptr, 0);
  		if (*endptr)
  			return False;
  
! 		ui_seamless_create_window(id, parent, flags);
  	}
  	else if (!strcmp("DESTROY", tok1))
--- 91,107 ----
  			return False;
  
! 		group = strtoul(tok4, &endptr, 0);
  		if (*endptr)
  			return False;
  
! 		parent = strtoul(tok5, &endptr, 0);
  		if (*endptr)
  			return False;
  
! 		flags = strtoul(tok6, &endptr, 0);
! 		if (*endptr)
! 			return False;
! 
! 		ui_seamless_create_window(id, group, parent, flags);
  	}
  	else if (!strcmp("DESTROY", tok1))

Index: xproto.h
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/xproto.h,v
retrieving revision 1.4.2.5
retrieving revision 1.4.2.6
diff -C2 -d -r1.4.2.5 -r1.4.2.6
*** xproto.h	16 Mar 2006 08:41:53 -0000	1.4.2.5
--- xproto.h	21 Mar 2006 14:42:25 -0000	1.4.2.6
***************
*** 9,10 ****
--- 9,11 ----
  void ewmh_set_wm_name(Window wnd, const char *title);
  int ewmh_set_window_popup(Window wnd);
+ int ewmh_set_window_modal(Window wnd);

Index: xwin.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/xwin.c,v
retrieving revision 1.205.2.31
retrieving revision 1.205.2.32
diff -C2 -d -r1.205.2.31 -r1.205.2.32
*** xwin.c	20 Mar 2006 16:14:02 -0000	1.205.2.31
--- xwin.c	21 Mar 2006 14:42:25 -0000	1.205.2.32
***************
*** 29,32 ****
--- 29,35 ----
  #include "xproto.h"
  
+ /* We can't include Xproto.h because of conflicting defines for BOOL */
+ #define X_ConfigureWindow              12
+ 
  extern int g_width;
  extern int g_height;
***************
*** 51,54 ****
--- 54,63 ----
  
  /* SeamlessRDP support */
+ typedef struct _seamless_group
+ {
+ 	Window wnd;
+ 	unsigned long id;
+ 	unsigned int refcnt;
+ } seamless_group;
  typedef struct _seamless_window
  {
***************
*** 56,59 ****
--- 65,69 ----
  	unsigned long id;
  	unsigned long behind;
+ 	seamless_group *group;
  	int xoffset, yoffset;
  	int width, height;
***************
*** 305,308 ****
--- 315,324 ----
  		{
  			*prevnext = sw->next;
+ 			sw->group->refcnt--;
+ 			if (sw->group->refcnt == 0)
+ 			{
+ 				XDestroyWindow(g_display, sw->group->wnd);
+ 				xfree(sw->group);
+ 			}
  			xfree(sw);
  			return;
***************
*** 454,457 ****
--- 470,502 ----
  
  
+ static seamless_group *
+ sw_find_group(unsigned long id, BOOL dont_create)
+ {
+ 	seamless_window *sw;
+ 	seamless_group *sg;
+ 	XSetWindowAttributes attribs;
+ 
+ 	for (sw = g_seamless_windows; sw; sw = sw->next)
+ 	{
+ 		if (sw->group->id == id)
+ 			return sw->group;
+ 	}
+ 
+ 	if (dont_create)
+ 		return NULL;
+ 
+ 	sg = xmalloc(sizeof(seamless_group));
+ 
+ 	sg->wnd =
+ 		XCreateWindow(g_display, RootWindowOfScreen(g_screen), -1, -1, 1, 1, 0,
+ 			      CopyFromParent, CopyFromParent, CopyFromParent, 0, &attribs);
+ 
+ 	sg->id = id;
+ 	sg->refcnt = 0;
+ 
+ 	return sg;
+ }
+ 
+ 
  static void
  mwm_hide_decorations(Window wnd)
***************
*** 1451,1454 ****
--- 1496,1515 ----
  }
  
+ static XErrorHandler g_old_error_handler;
+ 
+ static int
+ error_handler(Display * dpy, XErrorEvent * eev)
+ {
+ 	if ((eev->error_code == BadMatch) && (eev->request_code == X_ConfigureWindow))
+ 	{
+ 		fprintf(stderr, "Got \"BadMatch\" when trying to restack windows.\n");
+ 		fprintf(stderr,
+ 			"This is most likely caused by a broken window manager (commonly KWin).\n");
+ 		return 0;
+ 	}
+ 
+ 	return g_old_error_handler(dpy, eev);
+ }
+ 
  BOOL
  ui_init(void)
***************
*** 1468,1471 ****
--- 1529,1534 ----
  	}
  
+ 	g_old_error_handler = XSetErrorHandler(error_handler);
+ 
  	g_xserver_be = (ImageByteOrder(g_display) == MSBFirst);
  	screen_num = DefaultScreen(g_display);
***************
*** 3223,3227 ****
  
  void
! ui_seamless_create_window(unsigned long id, unsigned long parent, unsigned long flags)
  {
  	Window wnd;
--- 3286,3291 ----
  
  void
! ui_seamless_create_window(unsigned long id, unsigned long group, unsigned long parent,
! 			  unsigned long flags)
  {
  	Window wnd;
***************
*** 3229,3232 ****
--- 3293,3297 ----
  	XClassHint *classhints;
  	XSizeHints *sizehints;
+ 	XWMHints *wmhints;
  	long input_mask;
  	seamless_window *sw, *sw_parent;
***************
*** 3268,3275 ****
  	}
  
! 	/* Handle popups without parents through some ewm hints */
  	if (parent == 0xFFFFFFFF)
  		ewmh_set_window_popup(wnd);
! 	/* Set WM_TRANSIENT_FOR, if necessary */
  	else if (parent != 0x00000000)
  	{
--- 3333,3345 ----
  	}
  
! 	/* Parent-less transient windows */
  	if (parent == 0xFFFFFFFF)
+ 	{
+ 		XSetTransientForHint(g_display, wnd, RootWindowOfScreen(g_screen));
+ 		/* Some buggy wm:s (kwin) do not handle the above, so fake it
+ 		   using some other hints. */
  		ewmh_set_window_popup(wnd);
! 	}
! 	/* Normal transient windows */
  	else if (parent != 0x00000000)
  	{
***************
*** 3281,3284 ****
--- 3351,3362 ----
  	}
  
+ 	if (flags & SEAMLESSRDP_CREATE_MODAL)
+ 	{
+ 		/* We do this to support buggy wm:s (*cough* metacity *cough*)
+ 		   somewhat at least */
+ 		if (parent == 0x00000000)
+ 			XSetTransientForHint(g_display, wnd, RootWindowOfScreen(g_screen));
+ 		ewmh_set_window_modal(wnd);
+ 	}
  
  	/* FIXME: Support for Input Context:s */
***************
*** 3298,3301 ****
--- 3376,3381 ----
  	sw->id = id;
  	sw->behind = 0;
+ 	sw->group = sw_find_group(group, False);
+ 	sw->group->refcnt++;
  	sw->xoffset = 0;
  	sw->yoffset = 0;
***************
*** 3314,3317 ****
--- 3394,3407 ----
  	sw->next = g_seamless_windows;
  	g_seamless_windows = sw;
+ 
+ 	/* WM_HINTS */
+ 	wmhints = XAllocWMHints();
+ 	if (wmhints)
+ 	{
+ 		wmhints->flags = WindowGroupHint;
+ 		wmhints->window_group = sw->group->wnd;
+ 		XSetWMHints(g_display, sw->wnd, wmhints);
+ 		XFree(wmhints);
+ 	}
  }
  
***************
*** 3473,3481 ****
  			{
  				XWMHints *hints;
! 				hints = XAllocWMHints();
! 				hints->flags = StateHint;
! 				hints->initial_state = IconicState;
! 				XSetWMHints(g_display, sw->wnd, hints);
! 				XFree(hints);
  				XMapWindow(g_display, sw->wnd);
  			}
--- 3563,3574 ----
  			{
  				XWMHints *hints;
! 				hints = XGetWMHints(g_display, sw->wnd);
! 				if (hints)
! 				{
! 					hints->flags |= StateHint;
! 					hints->initial_state = IconicState;
! 					XSetWMHints(g_display, sw->wnd, hints);
! 					XFree(hints);
! 				}
  				XMapWindow(g_display, sw->wnd);
  			}



-------------------------------------------------------
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