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

Boyd Timothy boyd@timothy.ws
Wed, 07 Apr 2004 23:45:29 -0600


--=-mAneiKF6M2IMo9axWBu6
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

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

--=-mAneiKF6M2IMo9axWBu6
Content-Disposition: attachment; filename=gtk-sharp.patch
Content-Type: text/plain; name=gtk-sharp.patch; charset=
Content-Transfer-Encoding: 7bit

? gtk-sharp/gdk/Global.patch
? 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	8 Apr 2004 01:05:53 -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,50 @@
 			return result;
 		}
 
+		[DllImport ("gdksharpglue")]
+		static extern IntPtr gtksharp_get_gdk_net_supported ();
+
+		public static Gdk.Atom[] ListSupportedWindowManagerHints () {
+			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 IntPtr gtksharp_get_gdk_net_workarea ();
+
+		public static Gdk.Rectangle[] ListDesktopWorkareas () {
+			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	8 Apr 2004 01:05:53 -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

--=-mAneiKF6M2IMo9axWBu6
Content-Disposition: attachment; filename=windowmanager.c
Content-Type: text/x-c; name=windowmanager.c; charset=
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>

GList * gtksharp_get_gdk_net_supported (void);
gint gtksharp_get_gdk_net_number_of_desktops (void);
gint gtksharp_get_gdk_net_current_desktop (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;
}

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

--=-mAneiKF6M2IMo9axWBu6--