[Gtk-sharp-list] Modified Gdk.Global glue bindings to expose some EWMH

Boyd Timothy boyd@timothy.ws
Fri, 09 Apr 2004 14:30:29 -0600


--=-Pd7TAz1qjral+Zeq05Zh
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

I've added _NET_ACTIVE_WINDOW now as well.  It was suggested that we
will have to make a #define in the glue code so we could provide the
functionality of these methods on other operating systems (like win32).

Does anyone else have any thoughts/concerns?

-Boyd
On Thu, 2004-04-08 at 16:54, Boyd Timothy wrote:
> Following Mike's recommendation to move the methods to properties, here
> is an updated patch to gdk/Global.custom
> 
> On Wed, 2004-04-07 at 23:45, Boyd Timothy wrote:
> > Attached is the patch to current CVS and a new windowmanager.c which
> > goes in the gtk-sharp/gdk/glue/ directory.
> > 
> > The new static properties/methods I added are:
> > 
> > Gdk.Global.ListSupportedWindowManagerHints () : Gdk.Atom []
> > Gdk.Global.NumberOfDesktops : int
> > Gdk.Global.CurrentDesktop: int
> > Gdk.Global.ListDesktopWorkareas () : Gdk.Rectangle []
> > 
> > These make it easy from C# to get these values without having to mess
> > with the crazy format of Gdk.Property.Get () or using gdk_property_get
> > () directly with P/Invoke from C#.
> > 
> > Anyhow, since I've never really posted any patches, I'm not sure what
> > the process is from here.  Mike, I assume you'll take it from here?
> > 
> > Thanks,
> > 
> > Boyd

--=-Pd7TAz1qjral+Zeq05Zh
Content-Disposition: attachment; filename=gtk-sharp.patch
Content-Type: text/plain; name=gtk-sharp.patch; charset=UTF-8
Content-Transfer-Encoding: 7bit

? gtk-sharp/gdk/glue/windowmanager.c
Index: gtk-sharp/gdk/Global.custom
===================================================================
RCS file: /mono/gtk-sharp/gdk/Global.custom,v
retrieving revision 1.1
diff -u -p -r1.1 Global.custom
--- gtk-sharp/gdk/Global.custom	12 Feb 2004 18:45:19 -0000	1.1
+++ gtk-sharp/gdk/Global.custom	9 Apr 2004 20:23:30 -0000
@@ -1,6 +1,7 @@
 // Global.custom - customizations to Gdk.Global
 //
 // Authors: Mike Kestner  <mkestner@ximian.com>
+//          Boyd Timothy  <btimothy@novell.com>
 //
 // Copyright (c) 2004 Novell, Inc.
 
@@ -34,3 +35,67 @@
 			return result;
 		}
 
+		[DllImport ("gdksharpglue")]
+		static extern IntPtr gtksharp_get_gdk_net_supported ();
+
+		public static Gdk.Atom[] SupportedWindowManagerHints {
+			get {
+				IntPtr raw_ret = gtksharp_get_gdk_net_supported ();
+				if (raw_ret == IntPtr.Zero)
+					return new Gdk.Atom [0];
+				GLib.List list = new GLib.List (raw_ret, typeof (Gdk.Atom));
+				Gdk.Atom[] atoms = new Gdk.Atom [list.Count];
+				for (int i = 0; i < list.Count; i++)
+					atoms [i] = list [i] as Gdk.Atom;
+
+				return atoms;
+			}
+		}
+
+		[DllImport ("gdksharpglue")]
+		static extern int gtksharp_get_gdk_net_number_of_desktops ();
+
+		public static int NumberOfDesktops {
+			get {
+				return gtksharp_get_gdk_net_number_of_desktops ();
+			}
+		}
+
+		[DllImport ("gdksharpglue")]
+		static extern int gtksharp_get_gdk_net_current_desktop ();
+
+		public static int CurrentDesktop {
+			get {
+				return gtksharp_get_gdk_net_current_desktop ();
+			}
+		}
+
+		[DllImport ("gdksharpglue")]
+		static extern uint gtksharp_get_gdk_net_active_window ();
+
+		public static Gdk.Window ActiveWindow {
+			get {
+				uint windowID = gtksharp_get_gdk_net_active_window ();
+				if (windowID == 0)
+					return Gdk.Global.DefaultRootWindow;
+				Gdk.Window window = Gdk.Window.ForeignNew (windowID);
+				return window;
+			}
+		}
+
+		[DllImport ("gdksharpglue")]
+		static extern IntPtr gtksharp_get_gdk_net_workarea ();
+
+		public static Gdk.Rectangle[] DesktopWorkareas {
+			get {
+				IntPtr raw_ret = gtksharp_get_gdk_net_workarea ();
+				if (raw_ret == IntPtr.Zero)
+					return new Gdk.Rectangle [0];
+				GLib.List list = new GLib.List (raw_ret, typeof (Gdk.Rectangle));
+				Gdk.Rectangle[] workareas = new Gdk.Rectangle [list.Count];
+				for (int i = 0; i < list.Count; i++)
+					workareas [i] = (Gdk.Rectangle) list [i];
+
+				return workareas;
+			}
+		}
Index: gtk-sharp/gdk/glue/Makefile.am
===================================================================
RCS file: /mono/gtk-sharp/gdk/glue/Makefile.am,v
retrieving revision 1.3
diff -u -p -r1.3 Makefile.am
--- gtk-sharp/gdk/glue/Makefile.am	31 Mar 2004 16:34:08 -0000	1.3
+++ gtk-sharp/gdk/glue/Makefile.am	9 Apr 2004 20:23:30 -0000
@@ -4,7 +4,8 @@ libgdksharpglue_la_SOURCES =	\
 	dragcontext.c		\
 	event.c			\
 	selection.c		\
-	vmglueheaders.h
+	vmglueheaders.h		\
+	windowmanager.c
 
 # Adding a new glue file?
 # Please remember to update makefile.win32

--=-Pd7TAz1qjral+Zeq05Zh
Content-Disposition: attachment; filename=windowmanager.c
Content-Type: text/x-c; name=windowmanager.c; charset=UTF-8
Content-Transfer-Encoding: 7bit

/* windowmanager.c : Glue to access the extended window 
 * manager hints via the root window properties using
 * gdk_property_get ()
 *
 * This work is based on the specification found here:
 *	http://www.freedesktop.org/standards/wm-spec/
 *
 * Author: Boyd Timothy <btimothy@novell.com>
 *
 * Copyright (c) 2004 Novell, Inc.
 */

#include <gdk/gdkscreen.h>
#include <gdk/gdkwindow.h>
#include <gdk/gdkproperty.h>
#include <X11/Xlib.h>

GList * gtksharp_get_gdk_net_supported (void);
gint gtksharp_get_gdk_net_number_of_desktops (void);
gint gtksharp_get_gdk_net_current_desktop (void);
guint gtksharp_get_gdk_net_active_window (void);
GList * gtksharp_get_gdk_net_workarea (void);

GList * gtksharp_get_gdk_net_supported (void) {
	GdkAtom actual_property_type;
	int actual_format;
	int actual_length;
	long *data = NULL;
	GList *list = NULL;
	int i;

	if (!gdk_property_get (
			gdk_screen_get_root_window (gdk_screen_get_default ()),
			gdk_atom_intern ("_NET_SUPPORTED", FALSE),
			gdk_atom_intern ("ATOM", FALSE),
			0,
			G_MAXLONG,
			FALSE,
			&actual_property_type,
			&actual_format,
			&actual_length,
			(guchar **) &data)) {
		g_critical ("Unable to get _NET_SUPPORTED");
		gchar *actual_property_type_name = gdk_atom_name (actual_property_type);
		if (actual_property_type_name) {
			g_message ("actual_property_type: %s", actual_property_type_name);
			g_free (actual_property_type_name);
		}
		return NULL;
	}

	// Put all of the GdkAtoms into a GList to return
	for (i = 0; i < actual_length / sizeof (long); i ++) {
		list = g_list_append (list, (GdkAtom) data [i]);
	}

	g_free (data);
	return list;
}

gint gtksharp_get_gdk_net_number_of_desktops (void) {
	GdkAtom actual_property_type;
	int actual_format;
	int actual_length;
	long *data = NULL;
	gint num_of_desktops;

	if (!gdk_property_get (
			gdk_screen_get_root_window (gdk_screen_get_default ()),
			gdk_atom_intern ("_NET_NUMBER_OF_DESKTOPS", FALSE),
			gdk_atom_intern ("CARDINAL", FALSE),
			0,
			G_MAXLONG,
			FALSE,
			&actual_property_type,
			&actual_format,
			&actual_length,
			(guchar **) &data)) {
		g_critical ("Unable to get _NET_NUMBER_OF_DESKTOPS");
		gchar *actual_property_type_name = gdk_atom_name (actual_property_type);
		if (actual_property_type_name) {
			g_message ("actual_property_type: %s", actual_property_type_name);
			g_free (actual_property_type_name);
		}

		return -1;
	}

	num_of_desktops = (gint) data[0];
	g_free (data);

	return num_of_desktops;
}

gint gtksharp_get_gdk_net_current_desktop (void) {
	GdkAtom actual_property_type;
	int actual_format;
	int actual_length;
	long *data = NULL;
	gint current_desktop;

	if (!gdk_property_get (
			gdk_screen_get_root_window (gdk_screen_get_default ()),
			gdk_atom_intern ("_NET_CURRENT_DESKTOP", FALSE),
			gdk_atom_intern ("CARDINAL", FALSE),
			0,
			G_MAXLONG,
			FALSE,
			&actual_property_type,
			&actual_format,
			&actual_length,
			(guchar **) &data)) {
		g_critical ("Unable to get _NET_CURRENT_DESKTOP");
		gchar *actual_property_type_name = gdk_atom_name (actual_property_type);
		if (actual_property_type_name) {
			g_message ("actual_property_type: %s", actual_property_type_name);
			g_free (actual_property_type_name);
		}
		return -1;
	}

	current_desktop = (gint) data[0];
	g_free (data);

	return current_desktop;
}

guint gtksharp_get_gdk_net_active_window (void) {
	GdkAtom actual_property_type;
	int actual_format;
	int actual_length;
	long *data = NULL;
	guint windowID = 0;

	if (!gdk_property_get (
		gdk_screen_get_root_window (gdk_screen_get_default ()),	// GdkWindow * window,
		gdk_atom_intern ("_NET_ACTIVE_WINDOW", FALSE),		// GdkAtom property,
		gdk_atom_intern ("WINDOW", FALSE),			// GdkAtom type,
		0,							// gulong offset,
		G_MAXLONG,						// gulong length,
		FALSE,							// gint pdelete,
		&actual_property_type,					// GdkAtom * actual_property_type,
		&actual_format,						// gint * actual_format,
		&actual_length,						// gint * actual_length,
		(guchar **) &data)) {					// guchar ** data);
			g_critical ("Unable to get _NET_ACTIVE_WINDOW");
			gchar *actualPropertyTypeName = gdk_atom_name (actual_property_type);
			if (actualPropertyTypeName) {
				g_message ("actual_property_type: %s", actualPropertyTypeName);
				g_free(actualPropertyTypeName);
			}
			return -1;
	}

	windowID = (gint) data [0];
	g_free (data);

	return windowID;
}

GList * gtksharp_get_gdk_net_workarea (void) {
	GdkAtom actual_property_type;
	int actual_format;
	int actual_length;
	long *data = NULL;	
	int i = 0;
	GList *list = NULL;

	if (!gdk_property_get (
		gdk_screen_get_root_window (gdk_screen_get_default ()),	// GdkWindow * window,
		gdk_atom_intern ("_NET_WORKAREA", FALSE),		// GdkAtom property,
		gdk_atom_intern ("CARDINAL", FALSE),			// GdkAtom type,
		0,							// gulong offset,
		G_MAXLONG,						// gulong length,
		FALSE,							// gint pdelete,
		&actual_property_type,					// GdkAtom * actual_property_type,
		&actual_format,						// gint * actual_format,
		&actual_length,						// gint * actual_length,
		(guchar **) &data)) {					// guchar ** data);
			g_critical ("Unable to get _NET_WORKAREA");
			gchar *actualPropertyTypeName = gdk_atom_name (actual_property_type);
			if (actualPropertyTypeName) {
				g_message ("actual_property_type: %s", actualPropertyTypeName);
				g_free(actualPropertyTypeName);
			}
			return FALSE;
	}

	for (i = 0; i < actual_length / sizeof (long); i += 4) {
		GdkRectangle *rectangle = g_malloc(sizeof (GdkRectangle));
		rectangle->x		= (int) data [i];
		rectangle->y		= (int) data [i + 1];
		rectangle->width	= (int) data [i + 2];
		rectangle->height	= (int) data [i + 3];
		list = g_list_append (list, rectangle);
	}


	if (data != NULL)
		g_free(data);

	return list;
}

--=-Pd7TAz1qjral+Zeq05Zh--