Click here to Skip to main content
15,896,475 members
Articles / Desktop Programming / X11

Programming Xlib with Mono Develop - Part 2: Athena widgets (proof of concept)

Rate me:
Please Sign up or sign in to vote.
4.89/5 (4 votes)
14 Sep 2013CPOL12 min read 30.7K   231   5  
How to call native Xt API from Mono Develop C# ending up in a very little Athena widget application.
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Collections.Generic;

using X11;

namespace Xt
{
	
	public enum XtValueMask : uint			{	};  // X11    32 Bit: 4 Bytes:          -2147483647 to 2147483647
	//public enum XtValueMask : ulong		{	};  // X11 64    Bit: 8 Bytes:                    0 to 18446744073709551615

	public struct Box
	{
	    public short x1, x2, y1, y2;
	}

	public struct Rectangle
	{
	    public short x, y, width, height;
	}

	public struct XRegion
	{
	    public int			size;
	    public int			numRects;
	    public Box[]		rects;
	    public Box			extents;
	}

	public struct XrmResourc
	{
		public TLong			xrm_name;				/* Resource name quark */
		public TLong			xrm_class;				/* Resource class quark */
		public TLong			xrm_type;				/* Resource representation type quark */
		public XCardinal		xrm_size;				/* Size in bytes of representation */
		public TChar			xrm_offset;				/* -offset-1 */
		public TLong			xrm_default_type;		/* Default representation type quark */
		public IntPtr			xrm_default_addr;		/* XtPointer: Default resource address */
	}
	
	public struct XtResource
	{
		public TChar[]			resource_name;			/* Resource name */
		public TChar[]			resource_class;			/* Resource class */
		public TChar[]			resource_type;			/* Representation type desired */
		public XCardinal		resource_size;			/* Size in bytes of representation */
		public XCardinal		resource_offset;		/* Offset from base to put resource value */
		public TChar[]			default_type;			/* representation type of specified default */
		public IntPtr			default_addr;			/* XtPointer: Address of default resource */
	}
	
	// Tested: O.K.
	public struct XtWidgetGeometry
	{
		public XtGeometryMask	request_mode;			/* Flag the fields, that matter. */
		public XPosition		x, y;
		public XDimension		width, height;
		public XDimension		border_width;
		public IntPtr			sibling;				/* Widget: */
		public TInt				stack_mode; 
	}
	
	[Flags]
	public enum XtGeometryMask : uint					/* Size is not unsigned long, as literature says (unsigned long fails for 64 bit)!!! */
	{
		CWX						= (1<<0),
		CWY						= (1<<1),
		CWWidth					= (1<<2),
		CWHeight				= (1<<3),
		CWBorderWidth			= (1<<4),
		CWSibling				= (1<<5),
		CWStackMode				= (1<<6)
	}
	
	public enum XtGeometryResult : int
	{
		XtGeometryYes,									/* The proposed change is acceptable to the child without modifications. */
														/* This means that the proposed changes are exactly what the child would prefer. */
		XtGeometryNo,									/* The child would prefer that no changes were made to its current geometry. */
														/* The parent can respect or ignore this response. */
		XtGeometryAlmost,								/* The child does not agree entirely with the proposed change. At least one field */
														/* of XtWidgetGeometry is different. The parent can respect or ignore this response. */
		XtGeometryDone 
	}

	public enum XtJustify
	{
	    XtJustifyLeft,									/* justify text to left side of button   */
	    XtJustifyCenter,								/* justify text in center of button      */
	    XtJustifyRight									/* justify text to right side of button  */
	}
	
	public enum XtGrabKind
	{
		XtGrabNone,
		XtGrabNonexclusive,
		XtGrabExclusive
	}
		
	public struct XtCallbackRec
	{
		public XtCallbackProc	callback;				/*	*/
		public IntPtr			closure;				/* XtPointer: */
	}
	
	public struct XtGrabRec
	{
	    public XtGrabRec[]		next;
	    public IntPtr			widget;					/* Widget: */
	    public TUint			exclusive;
	    public TUint			spring_loaded;
	}
	
	// Tested: O.K.
	/// <summary> Action map entry, containing logical action name and action procedure. </summary>
	public struct XtActionsRec
	{
		/// <summary> The logical action name. The C structure name is 'string'. </summary>
		/// <remarks> Define the action name including terminating NULL like: X11Utils.StringToSByteArray ("quitAction\0") </remarks>
		public TChar[]			str;
		
		/// <summary> The pointer to a delegate of prototype XtActionProc. </summary>
		/// <remarks> Can be created like: Marshal.GetFunctionPointerForDelegate(new XtActionProc (QuitAction)) </remarks>
		public IntPtr		 	proc; // XtActionProc
		
		/// <summary> The initializing constructor to simplify creation of an XtActionsRec array. </summary>
		/// <param name="actionName"> The ogical action name. <see cref="TChar[]"/> </param>
		/// <param name="delegatePointer"> The pointer to a delegate of prototype XtActionProc. <see cref="System.IntPtr"/> </param>
		public XtActionsRec		(TChar[] actionName, IntPtr delegatePointer)
		{
			str				= actionName;
			proc			= delegatePointer;
		}
	}

	public struct XtEventRec
	{
	    public XtEventRec[]	next;
	    public EventMask		mask;
	    public XtEventHandler	proc;
	    public IntPtr			closure;				/* XtPointer: */
	    public TUint			selects;
	    public TUint			has_type_specifier;
	    public TUint			async;
	}

	public struct XtTMRec
	{
	    public IntPtr					translations;			/* XtTranslations: private to Translation Manager    */
	    public XtActionProc[]			proc_table;				/* XtBoundActions: procedure bindings for actions    */
	    public IntPtr					current_state;      	/* StatePtr: Translation Manager state ptr     */
	    public TUlong					lastEventTime;
	}

	public struct WidgetRec
	{
	}
	
	public delegate void     			XtProc					();
	public delegate void     			XtWidgetProc			(IntPtr widget);
	public delegate void     			XtWidgetClassProc		(IntPtr widget_class);
	public delegate void     			XtArgsProc				(IntPtr widget, Arg[] args, ref XCardinal num_args);
	
	// Tested: O.K.
	/// <summary> Declare the prototype of a callback procedure. </summary>
	/// <param name="widget"> The widget, that is source of the callback procedure. <see cref="System.IntPtr"/> </param>
	/// <param name="clientData"> Additional callback data from the client. <see cref="System.IntPtr"/> </param>
	/// <param name="callData"> Additional data defined for the call. <see cref="System.IntPtr"/> </param>
	public delegate void     			XtCallbackProc			(IntPtr widget, IntPtr clientData, IntPtr callData);

	public delegate void     			XtInitProc				(IntPtr request_widget, IntPtr new_widget, Arg[] args, ref XCardinal num_args);
	public delegate void     			XtExposeProc			(IntPtr widget, ref XEvent xevent, XRegion region);
	public delegate void     			XtAlmostProc			(IntPtr old_widget, IntPtr new_widget, ref XtWidgetGeometry request, ref XtWidgetGeometry reply);
	public delegate TBoolean			XtAcceptFocusProc		(IntPtr widget, IntPtr time_pointer);
	public delegate void     			XtStringProc			(IntPtr widget, TChar[] str);

	public delegate XtGeometryResult	XtGeometryHandler		(IntPtr widget, ref XtWidgetGeometry request, ref XtWidgetGeometry reply);
	
	public delegate void				XtEventHandler			(IntPtr widget, IntPtr clientData, ref XEvent xevent, ref TBoolean continue_to_dispatch_return);
	
	// Tested: O.K.
	/// <summary> Declare the prototype of an action procedure. </summary>
	/// <param name="widget"> The widget, that is source of the action procedure. <see cref="System.IntPtr"/> </param>
	/// <param name="xevent"> The event, that is invoked. <see cref="XEvent"/> </param>
	/// <param name="parameters"> Additional parameters (as String[]). <see cref="System.IntPtr"/> </param>
	/// <param name="num_params"> The number of additional parameters. <see cref="XCardinal"/> </param>
	public delegate void				XtActionProc			(IntPtr widget, ref XEvent xevent, IntPtr parameters, ref XCardinal num_params);
	
	public delegate void				XtRealizeProc			(IntPtr widget, ref XtValueMask mask, ref X11lib.XSetWindowAttributes attributes);
	public delegate TBoolean			XtChangeSensitiveFunc	(IntPtr widget);
	public delegate TBoolean			XtSetValuesFunc			(IntPtr old_widget, IntPtr request_widget, IntPtr new_widget, Arg[] args, ref XCardinal num_args);
	public delegate TBoolean			XtArgsFunc				(IntPtr widget, Arg[] args, ref XCardinal num_args);
	/// <summary> Emulate some functionality if X11/Object.h. </summary>
	public class XawObject : IDisposable
	{
		
		public struct ObjectPart
		{
			public IntPtr				self;					/* Widget: pointer to widget itself */
			public IntPtr				widget_class;			/* WidgetClass: pointer to Widget's ClassRec */
			public IntPtr				parent;					/* parent widget */
			public XrmName				xrm_name;				/* widget resource name quarkified */
			public TBoolean				being_destroyed;		/* marked for destroy */
			public XtCallbackProc[]		destroy_callbacks;		/* who to call when widget destroyed */
			public IntPtr				constraints;			/* XtPointer: constraint record */
		}

		public struct ObjectRec
		{
			public ObjectPart object_part;
		}
		
		public struct ObjectClassPart
		{
			public IntPtr				superclass;				/* WidgetClass: pointer to superclass ClassRec */
			public TChar[]				class_name;				/* widget resource class name */
			public XCardinal			widget_size;			/* size in bytes of widget record */
			public XtProc				class_initialize;		/* class initialization proc */
			public XtWidgetClassProc	class_part_initialize;	/* dynamic initialization */
			public XtEnum				class_inited;			/* has class been initialized? */
			public XtInitProc			initialize;				/* initialize subclass fields */
			public XtArgsProc			initialize_hook;		/* notify that initialize called */
			public XtProc				obj1;					/* NULL */
			public IntPtr				obj2;					/* XtPointer: NULL */
			public XCardinal			obj3;					/* NULL */
			public XtResource[]			resources;				/* resources for subclass fields */
			public XCardinal			num_resources;			/* number of entries in resources */
			public XrmClass				xrm_class;				/* resource class quarkified */
			public TBoolean				obj4;					/* NULL */
			public XtEnum				obj5;					/* NULL */
			public TBoolean				obj6;					/* NULL */
			public TBoolean				obj7;					/* NULL */
			public XtWidgetProc			destroy;				/* free data for subclass pointers */
			public XtProc				obj8;					/* NULL */
			public XtProc				obj9;					/* NULL */
			public XtSetValuesFunc		set_values;				/* set subclass resource values */
			public XtArgsFunc			set_values_hook;		/* notify that set_values called */
			public XtProc				obj10;					/* NULL */
			public XtArgsProc			get_values_hook;		/* notify that get_values called */
			public XtProc				obj11;					/* NULL */
			public XtVersionType		version;				/* version of intrinsics used */
			public IntPtr				callback_private;		/* XtPointer: list of callback offsets */
			public TChar[]				obj12;					/* NULL */
			public XtProc				obj13;					/* NULL */
			public XtProc				obj14;					/* NULL */
			public IntPtr				extension;				/* XtPointer: pointer to extension record */
		}

		public struct ObjectClassRec
		{
			public ObjectClassPart		object_class;
		}
		
		public virtual void Dispose ()
		{
			;
		}
	}
	
	/// <summary> Emulate some functionality if X11/RextObj.h. </summary>
	public class XawRectObj : XawObject
	{

		public struct RectObjPart
		{
			public XPosition			x, y;					/* rectangle position */
			public XDimension			width, height;			/* rectangle dimensions */
			public XDimension			border_width;			/* rectangle border width */
			public TBoolean				managed;				/* is widget geometry managed? */
			public TBoolean				sensitive;				/* is widget sensitive to user events*/
			public TBoolean				ancestor_sensitive;		/* are all ancestors sensitive? */
		}
	
		public struct RectObjRec
		{
			public ObjectPart			object_part;
			public RectObjPart			rectobj_part;
		}

		public struct RectObjClassPart
		{
			public IntPtr				superclass;				/* WidgetClass: pointer to superclass ClassRec */
			public TChar[]				class_name;				/* widget resource class name */
			public XCardinal			widget_size;			/* size in bytes of widget record */
			public XtProc				class_initialize;		/* class initialization proc */
			public XtWidgetClassProc	class_part_initialize;	/* dynamic initialization */
			public XtEnum				class_inited;			/* has class been initialized? */
			public XtInitProc			initialize;				/* initialize subclass fields */
			public XtArgsProc			initialize_hook;		/* notify that initialize called */
			public XtProc				rect1;					/* NULL */
			public IntPtr				rect2;					/* XtPointer: NULL */
			public XCardinal			rect3;					/* NULL */
			public XtResource[]			resources;				/* resources for subclass fields */
			public XCardinal			num_resources;			/* number of entries in resources */
			public XrmClass				xrm_class;				/* resource class quarkified */
			public TBoolean				rect4;					/* NULL */
			public XtEnum				rect5;					/* NULL */
			public TBoolean				rect6;					/* NULL */
			public TBoolean				rect7;					/* NULL */
			public XtWidgetProc			destroy;				/* free data for subclass pointers */
			public XtWidgetProc			resize;					/* geom manager changed widget size */
			public XtExposeProc			expose;					/* rediplay rectangle */
			public XtSetValuesFunc		set_values;				/* set subclass resource values */
			public XtArgsFunc			set_values_hook;		/* notify that set_values called */
			public XtAlmostProc			set_values_almost;		/* set values almost for geometry */
			public XtArgsProc			get_values_hook;		/* notify that get_values called */
			public XtProc				rect9;					/* NULL */
			public XtVersionType		version;				/* version of intrinsics used */
			public IntPtr				callback_private;		/* XtPointer: list of callback offsets */
			public String				rect10;					/* NULL */
			public XtGeometryHandler	query_geometry;			/* return preferred geometry */
			public XtProc				rect11;					/* NULL */
			public IntPtr				extension;				/* XtPointer: pointer to extension record */
		}

		public struct _RectObjClassRec
		{
			public RectObjClassPart rect_class;
		}
		
	}
	
	/// <summary> Emulate some functionality if X11/Core.h. </summary>
	public class XawCore : XawRectObj
	{

		public struct CorePart
		{
			IntPtr				self;					/* Widget: pointer to widget itself */
			IntPtr				widget_class;			/* IntPtr: pointer to Widget's ClassRec */
			IntPtr				parent;					/* parent widget */
			XrmName				xrm_name;				/* widget resource name quarkified */
			TBoolean			being_destroyed;		/* marked for destroy */
			XtCallbackRec[]		destroy_callbacks;		/* who to call when widget destroyed */
			IntPtr				constraints;			/* XtPointer: constraint record */
			XPosition			x, y;					/* window position */
			XDimension			width, height;			/* window dimensions */
			XDimension			border_width;			/* window border width */
			TBoolean			managed;				/* is widget geometry managed? */
			TBoolean			sensitive;				/* is widget sensitive to user events*/
			TBoolean			ancestor_sensitive;		/* are all ancestors sensitive? */
			XtEventRec[]		event_table;			/* private to event dispatcher */
			XtTMRec				tm;						/* translation management */
			IntPtr				accelerators;			/* XtTranslations: accelerator translations */
			TPixel				border_pixel;			/* window border pixel */
			IntPtr				border_pixmap;			/* window border pixmap or NULL */
			IntPtr[]			popup_list;				/* Widget[]: list of popups */
			XCardinal			num_popups;				/* how many popups */
			TChar[]				name;					/* widget resource name */
			IntPtr				screen_pointer;			/* window's screen */
			IntPtr				colormap;				/* colormap */
			IntPtr				window;					/* window ID */
			XCardinal			depth;					/* number of planes in window */
			TPixel				background_pixel;		/* window background pixel */
			IntPtr				background_pixmap;		/* window background pixmap or NULL */
			TBoolean			visible;				/* is window mapped and not occluded?*/
			TBoolean			mapped_when_managed;	/* map window if it's managed? */
		}

		public struct WidgetRec
		{
			CorePart core;
		}

		public struct CoreClassPart
		{
			public IntPtr				superclass;				/* WidgetClass: pointer to superclass ClassRec */
			public TChar[]				class_name;				/* widget resource class name */
			public XCardinal			widget_size;			/* size in bytes of widget record */
			public XtProc				class_initialize;		/* class initialization proc */
			public XtWidgetClassProc	class_part_initialize;	/* dynamic initialization */
			public XtEnum				class_inited;			/* has class been initialized? */
			public XtInitProc			initialize;				/* initialize subclass fields */
			public XtArgsProc			initialize_hook;		/* notify that initialize called */
			public XtRealizeProc		realize;				/* XCreateWindow for widget */
			public XtActionsRec[]		actions;				/* widget semantics name to proc map */
			public XCardinal			num_actions;			/* number of entries in actions */
			public XtResource[]			resources;				/* resources for subclass fields */
			public XCardinal			num_resources;			/* number of entries in resources */
			public XrmClass				xrm_class;				/* resource class quarkified */
			public TBoolean				compress_motion;		/* compress MotionNotify for widget */
			public XtEnum				compress_exposure;		/* compress Expose events for widget*/
			public TBoolean				compress_enterleave;	/* compress enter and leave events */
			public TBoolean				visible_interest;		/* select for VisibilityNotify */
			public XtWidgetProc			destroy;				/* free data for subclass pointers */
			public XtWidgetProc			resize;					/* geom manager changed widget size */
			public XtExposeProc			expose;					/* rediplay window */
			public XtSetValuesFunc		set_values;				/* set subclass resource values */
			public XtArgsFunc			set_values_hook;		/* notify that set_values called */
			public XtAlmostProc			set_values_almost;		/* set_values got "Almost" geo reply */
			public XtArgsProc			get_values_hook;		/* notify that get_values called */
			public XtAcceptFocusProc	accept_focus;			/* assign input focus to widget */
			public XtVersionType		version;				/* version of intrinsics used */
			public IntPtr				callback_private;		/* XtPointer: list of callback offsets */
			public TChar[]				tm_table;				/* state machine */
			public XtGeometryHandler	query_geometry;			/* return preferred geometry */
			public XtStringProc			display_accelerator;	/* display your accelerator */
			public IntPtr				extension; 				/* XtPointer:		pointer to extension record */
		}

		public struct WidgetClassRec
		{
			CoreClassPart core_class;
		}
		
	}
	
	/// <summary> Emulate some functionality if X11/Xaw/Simple.h. </summary>
	public class XawSimple : XawCore
	{
		
		public struct SimplePart
		{
		    public IntPtr					cursor;
		    public IntPtr					insensitive_border;
		}
		
		public struct SimpleRec
		{
		    public CorePart			core;
		    public SimplePart		simple;
		}

		public struct SimpleClassPart
		{
		    public XtChangeSensitiveFunc	change_sensitive;
		}

		public struct SimpleClassRec
		{
    		public CoreClassPart			core_class;
    		public SimpleClassPart			simple_class;
		}

		public struct SimpleWidgetClass
		{
			public IntPtr superclass;
			public IntPtr class_name;
		}
		
	}
	
	/// <summary> Emulate some functionality if X11/Xaw/Label.h. </summary>
	public class XawLabel : XawSimple
	{
		
		public struct LabelClassPart
		{
		  	public IntPtr		 extension;			/* XtPointer:	*/
 		}

		public struct LabelClassRec
		{
			public CoreClassPart	core_class;
			public SimpleClassPart	simple_class;
			public LabelClassPart	label_class;
		}

		public struct LabelPart
		{
			public TPixel			foreground;
			public IntPtr			font;			/* XFontStruct */
			public TChar[]			label;
			public XtJustify		justify;
			public XDimension		internal_width;
			public XDimension		internal_height;
			public IntPtr			pixmap;
			public TBoolean			resize;
			public TUchar			encoding;
			public IntPtr			left_bitmap;	/* Pixmap */
			public IntPtr			normal_GC;
			public IntPtr			gray_GC;
			public IntPtr			stipple;
			public XPosition		label_x;
			public XPosition		label_y;
			public XDimension		label_width;
			public XDimension		label_height;
			public XDimension		label_len;
			public TInt				lbm_y;			/* where in label */
			public TUint			lbm_width;
			public TUint			lbm_height;		/* size of pixmap */
		}

		public struct LabelRec
		{
			CorePart	core;
			SimplePart	simple;
			LabelPart	label;
		}

	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Team Leader Celonis SA
Germany Germany
I am currently the CEO of Symbioworld GmbH and as such responsible for personnel management, information security, data protection and certifications. Furthermore, as a senior programmer, I am responsible for the automatic layout engine, the simulation (Activity Based Costing), the automatic creation of Word/RTF reports and the data transformation in complex migration projects.

The main focus of my work as a programmer is the development of Microsoft Azure Services using C# and Visual Studio.

Privately, I am interested in C++ and Linux in addition to C#. I like the approach of open source software and like to support OSS with own contributions.

Comments and Discussions