Thursday, May 02, 2013

Programming Xlib with Mono Develop - Part 1: Low-level (proof of concept)

Introduction

This article shows how to access Xlib/X11 API from C# using Mono Develop. A lot of API calls are ready-to-use defined and tested and some challenges are mastered, e.g., transparent bitmap display or modal dialog.

Background

A lot of little helpful Unix/Linux tools are, still today, coded in C/C++ against Xlib/X11. A migration to C# can simplify the maintenance and offer new opportunities. But developers tend to stick to their inherent development environment. On the one hand a change from the GUI development environment Xlib/X11 to GTK or Qt has many advantages, like rapid prototyping or ready-to-use high-level GUI elements. On the othrer hand it requires to leave old habits, to refuse problem-optimized solutions implemented with low-level API and to loose control over some beloved GUI implementation details. Further more programmers see GUI toolkits come and go in rapid succession, esecially on Windows platforms, and are careful with radical changes.

Those, who are willing to change from an old-fashioned language/IDE like C/GCC to a modern one like C#/Mono Develop, might be afraid of the effort or imponderables of switching the GUI development environment simultaneously. But to change the language and to stick to the approved GUI development environment is possible.

If a programmer don't want to miss the control over the bits and bobs of his GUI, if he relies on the speed and zero overhead costs or if he just has fun or feels comfortable coding against the Xlib/X11, he will find some helpful information to communicate from C# to Xlib/X11 and vice versa provided with this little sample application. 

Using the code

The sample application was written with Mono Develop 2.4.1 for Mono 2.8.1 on OPEN SUSE 11.3 Linux 32 bit EN and GNOME desktop. Neither the port to any older nor to any newer version should be a problem. The sample application's solution consists of two projects (the complete sources are provided for download):

X11Wrapper defines the function prototypes, structures and types for Xlib/X11 calls  to the libX11.so
X11 contains the sample application based on a very lightweight widget set - called "Roma Widget Set" (Xrw)
Since C# doesn't support type declarations like

#typedef unsigned long Pixel;

the specific X11 type names can not be emulated. The compromise i found was to define enumerations like

public enum TChar : sbyte {};

but there are no automatic casts and all cast operation must be specified explicitly, like

TChar c1 = (TChar)'a';

Nevertheless, to avoid type mismatch during development some of those types, that might confuse through same names for different value ranges or different names for same value ranges - like long (in C/C++) which is int (in C#) for 32 bit -, are defined as enumeration.
The sample application is also tested with Mono Develop 3.0.6 for Mono 3.0.4 on OPEN SUSE 12.3 Linux 64 bit DE and GNOME desktop, IceWM, TWM und Xfce.

The only difference between the 32 bit and the 64 bit solution is the definition of some types:

public enum TLong : int            {};  // X11    32 Bit: 4 Bytes:                    0 to 65535
//public enum TLong : long        {};  // X11 64    Bit: 8 Bytes: -9223372036854775807 to 9223372036854775807
public enum TUlong : uint        {};  // X11    32 Bit: 4 Bytes:          -2147483647 to 2147483647
//public enum TUlong : ulong        {};  // X11 64    Bit: 8 Bytes:                    0 to 18446744073709551615
public enum TPixel : uint        {};  // X11    32 Bit: 4 Bytes:          -2147483647 to 2147483647
//public enum TPixel : ulong        {};  // X11 64    Bit: 8 Bytes:                    0 to 18446744073709551615
public enum XtArgVal : int        {};  // X11    32 Bit: 4 Bytes:                    0 to 65535
//public enum XtArgVal : long        {};  // X11 64    Bit: 8 Bytes: -9223372036854775807 to 9223372036854775807
public enum XtVersionType : uint    {};  // X11    32 Bit: 4 Bytes:          -2147483647 to 2147483647
//public enum XtVersionType : ulong    {};  // X11 64    Bit: 8 Bytes:                    0 to 18446744073709551615


Read more: Codeproject
QR: Inline image 1