Xlibe: an Xlib/X11 compatibility layer for Haiku

Everyone seems to be doing “progress threads” these days, so I figured I’d join the fun. And now I have something that seems uniquely suited to such a thread.

To begin with, there was a note I made in my last progress report, about the potentiality of writing an “Xlib compatibility layer”, that is, an implementation of the X11 APIs without an X11 server…

Some of you have already picked up on this (or seen my intermittent ramblings in IRC about it) and noticed the repository that has shown up in my GitHub account, now called “xlibe”. After only about two weeks and change of development, it already is quite sophisticated, and I expect it will continue to advance from here. More details in my next posts…

28 Likes

As of today, GTK now compiles (with some hacks) and displays windows. Proof:

image

Now, this is still quite early; pressing anything on the keyboard causes it to crash, clicking the mouse inside the window causes a hang, and you can clearly see strange redraw artifacts. Nonetheless, mouse-move events do work (buttons indicate they are being hovered over), and resizing the window behaves about as one would expect. But, well, considering I built GTK only yesterday, and had to work around one crash and fix two others in my own code before it would do this, I would say that is a pretty sizeable achievement already.

23 Likes

Before I detail more of “what works and what doesn’t”, let’s back up a bit.

Why write an Xlib/X11 compatibility layer at all, instead of native backends?

“Native” backends for toolkits are obviously preferable, allowing for tighter integration with the system; the Qt port takes this approach, and it is proof enough that such things are both feasible and desirable. However, Qt is kind of an exception in many ways; it is well-abstracted internally in a way most other toolkits are not, and it has a wide variety of supported platforms even before it was ported to Haiku.

Not all toolkits are like this; in fact, very few are. GTK has backends only for X11, (now) Wayland, Windows, and macOS. (The macOS backend was pretty poor for a long time; most users of GTK applications on macOS were stuck with using X11 via XQuartz, I seem to recall.) Other applications, like “AzPainter”, support X11 and only X11; or maybe they have support for Wayland, but not even a Windows or macOS port to speak of. Once software has been ported off of X11/Wayland, there is some hope that a native backend for a completely different architecture can be written, but oftentimes before that, the system will just make far too many assumptions about what it is running on to make rearchitecting it internally feasible.

So, even if writing a GTK backend for Haiku were feasible or doable, there is a separate, sizeable amount of Linux/etc. software that can really only be ported by bringing over X11 or Wayland. We could of course port a full X11 server and use that, as you can do on Windows or macOS, but considering the downsides of that approach and the flexibilities of the Haiku APIs, I realized that it was possible to re-implement the X11 APIs directly on top of the Haiku APIs (well, with some minor exceptions, of course), without an X11 server, and in fact provide a lot of the benefits that a “true” native backend would provide.

Why Xlib/X11 and not Wayland?

The Wayland APIs are very spartan and highly protocol-based; that is, there are more implementations of the protocol than just “libwayland”, making it basically impossible to write just one library for Wayland compatibility, but instead probably requiring a server implementation. While there are other X11 interface implementations besides Xlib (notably Xcb, which modern Xlib is based on), they are very rarely used, and in fact implementing an X11 server on top of Xlib is more than possible (Xnest, while very limited compared to Xephyr, is basically this, in fact), while implementing a Wayland server that runs on Wayland is experimental territory.

Further, I’m personally not so sure about Wayland as a system, anyway. It is only now, after over a decade of development, finally being used by default (after many, many years of support for it being theoretically available in toolkits, and tech demos showing it off.) Having looked into its design and implementation, I suspect a lot of its problems are actually design flaws; already it has been noted that the core protocol is so basic as to be functionally unusable (or at least unworkable) without piling on a large array of extensions.

X11, on the other hand, is a relatively stable target. It too has a lot of extensions, and it too has various oddities (what system wouldn’t after almost 40 years?), but it is well documented, well used (GTK+2 does not really support Wayland, for instance, meaning we’d be forever without it with just a Wayland compatibility layer, or be forced to use XWayland which sounds worse – a compatibility layer on top of a compatibility layer?)

While more Linux distributions are switching to Wayland, I don’t expect GTK et al. will drop their X11 code for quite a long time to come. If they eventually do, by then Wayland will be much more mature, and maybe a compatibility layer for it would also make sense. But that’s far off in the future, and not really worth considering at present.

Plus, by implementing Xlib, we have the potential to get xeyes and Motif! You know you want Motif applications, right? (Well, at least @3dEyes told me he wants one or two…)

12 Likes

What about that GTK port that I saw screenshots of a while ago?

That was the work of @3dEyes (screenshots in this old thread) and it was an experiment that did not go as far as you might think. He commented about it on a ticket in HaikuPorts a few months ago:

In that same thread (where we were discussing XSDL, or the possibility even of writing an SDL backend for GTK, so that other obscure OSes could benefit too), I commented at the time that

I actually talked with one of the SDL developers about potentially trying to start some kind of campaign to collect funds for them to do such a port after these discussions, but that never materialized.

So, that is how we got where we are now: porting GTK directly is just not feasible or worth the time, the SDL backend idea was interesting but nothing much came of it, which leads us to: the only reasonable way to port GTK is to get X11 or Wayland. Seeing Tk have Xlib implementations outside of Linux, as well as seeing some other experiments about Xlib on top of SDL2, as well as the older “BeXlib” project from 2003 which I started this work off it, was enough for me to guess that a full enough version of Xlib-on-Haiku to run GTK on was at least theoretically possible, and so here we are.

8 Likes

As for where things are at now, besides GTK:

Tk starts and renders some things, but for some reason it places a “BackgroundElement” in front of everything else most of the time, so controls only show up if you get them to redraw partially instead of fully. I don’t really understand why this is happening; the exact same version of Tk works on SDL2Tk though, so I’m guessing this must somehow be a bug in Xlibe.

image

AzPainter on the other hand has much lighter usage of X11, and is almost fully working. It doesn’t support pen-pressure input yet (that needs XInput2 which I haven’t implemented compatibility for), but otherwise I think window modality is about the feature I know of that I still have yet to implement for it. (There are 3 ways of making windows modal in X11; I implemented two of them, but of course AzPainter uses the third.)

image

xclock starts, but it has some drawing glitches because it presumes drawing is not antialiased, whereas all drawing on Haiku actually is.

image

wxX11 compiles and starts but does not seem to draw correctly. It also rapidly runs into strange assertions and crashes. However, I’m not sure how well maintained wxX11 is; I didn’t compile it on Linux for comparison, so this may be not entirely unexpected behavior. (It does however seem to try to use some obscure X11 features I didn’t implement and didn’t plan on implementing. We already have wxQt in the repositories for porting wxWidgets applications and it works pretty well, so this was just for testing.)

image

Motif compiles and with two hacks (one to Motif, one two Xlibe) does start, but it has redraw glitches still, and most controls do not seem to respond to input.

Xterm compiles but does not start due to being unable to allocate PTYs (probably some incompatibility with our PTY layer. It seems to have a lot of ifdefs for various platforms, likely it would need some for Haiku.)

An old X11-only Fontforge build at least starts, but rapidly gets “stuck” and quits accepting input:

image

22 Likes

I fear the next time i blink you will post a full CDE-on-Haiku screenshot.

10 Likes

The main aim in this whole endeavor was mainly GTK, though. Indeed as previously mentioned, its internals are not very pretty; I would probably go so far as to call them downright ugly; in many ways it is the total antithesis of Haiku’s philosophies and designs for code. And the sheer amount of code it has is its own kind of ridiculous; when I was tracing through it last night to work around a crash caused by failing to load an image file, I wound up about 8-10 functions deep in a call stack just for loading an icon! (There were dozens of functions above that before the icon-loading code was invoked.)

But, well, plenty of major software relies heavily on GTK, including GIMP and Inkscape and Firefox, so this is an important thing to work on.

I would definitely go so far to say, though, that Xlib/X11, for all their problems (and for all I’ve made fun of them or loudly complained about them over the years, or even just in the past few weeks while working on this new compatibility layer), they are in at least some ways kind of fun to work with. (I’ve definitely had more than a bit of fun working on Xlibe so far, although some of that is due to the Haiku APIs being fun to work with.) The same cannot at all be said of GTK. I already dread opening a Debugger to delve into a GTK problem, and I’ve only just started working with GTK just in the past few days.

To put it more succinctly: GTK is just an absolute disaster of a library. Xlib is, by comparison, downright sane and reasonable. That isn’t even an exaggeration.

8 Likes

I made a few passes at Motif in order to get the “grunt work” out of the way (adding stubs, fixing minor bugs), but I don’t really have a lot of interest in it overall. But if @3dEyes wants to fix it and submit some PRs to me, I’ll take them. So you should watch out for him to post screenshots I suppose. :stuck_out_tongue:

7 Likes

I feel for you. First small tool I made was using GTK. I ended up with more swearing comments all across the code than I could think of. Switched then to FOX library and never looked back :smiley: . That said… if Xlib would be working then chances are FOX gets working too… O_O

Congratulations! Porting Motif through this compatibility layer is not recommended: if there is a way to crash or to behave mysteriously, Motif will find it. It has been well known as a torture test for X for decades, and going through a great deal of trouble to support Motif will not bring Haiku support for many significant applications.

As for Cairo (and by extension GTK), I recommend implementing the X Render Extension. The relevant documentation can be found at https://www.x.org/releases/X11R7.6/doc/renderproto/renderproto.txt, and Cairo is designed to take advantage of it whenever present. Its ubiquitousness throughout X servers has caused the non-XRender code paths in Cairo to rot, so there are certain to be many bugs there.

For GTK to work correctly, you will also need to implement the Extended Window Manager Hints, some non-standard Motif hints (they are not actually related to Motif anymore), and the ICCCM. I recommend starting with the ICCCM: It will introduce you to many concepts used in the other features mentioned here. You can find the documentation at Inter-Client Communication Conventions Manual. The X Session Management Library (www dot x dot org slash releases/X11R7.6/doc/libSM/SMlib.html) is also recommended.

GTK 4 also assumes the presence of the XInput 2 extension, which completely replaces the Core Input API. It is extremely convoluted and ugly, but it is required for GTK 4 to function, and is also recommended for running GTK 3.

Some extensions, especially the shaped window extension, can just be stubbed out, but I see you’ve already done that.

6 Likes

+1 person :slight_smile:

I socialized on AIX and Linux – I could happy with X forwarding.
I would really happy as Irix would be ported to a payable platform to use as server for alternative PC OSes.
I know maybe Haiku will be running earlier on Solaris machines than this dream above.
May some Irix enthusiasts discover some old/new platform to port Irix there. :open_mouth:

Oh, I’m no stranger to X, I’ve worked with it in a variety of ways before, so I know about the ICCCM and that sort of thing.

Like I said above, I don’t intend to do much more with Motif. It actually got surprisingly far already, though, but I did have to add some hacks to make it use ZPixmaps instead of XYBitmaps.

I was hoping to stave off implementing XRender and XInput2 for now, but indeed I’ll probably have to implement them eventually. I already implemented the write half of the Motif hints, and some of the EWM hints.

Yeah, we don’t really support shaped windows on Haiku anyway, so indeed I just stubbed that out.

2 Likes

I wonder how clients will talk to eachother though: for example, how will one one client query a property, or select for events, off a window of another client? Does Xlibe use some interprocess communication mechanism to make that work? Or is there an existing App Server API for that which I missed?

Thanks.

There are some properties you can query and some events you can watch for from windows from other applications, but largely I am probably just not going to support a lot of those features. If I really had to I could do some rather clever things with BMessage passing and scripting, but I suspect it will simply not be necessary.

Thanks for the clarification.

(If you’re unfamiliar with the scripting API’s introspection capabilities, you can play around with the hey command line tool or take a look at @X512’s rather neat TraverseApps tool. There also used to be “Clue” but I think it was never fully fixed to run on Haiku.)

It seems to be interesting indeed, I’ll look into adding support for it to Emacs.

Thanks!

Hi!
Interesting project, however one thing you have not mentionned and that would be possibly very useful is X forwarding, which would allow running apps on a Linux machine and showing their windows on Haiku. But I guess this needs an actual X server, and not just Xlib?

3 Likes

Yes. Some years ago I ran an X11 server on Windows, both for running some UI tool via cygwin, but also for X11 forwarding.

This is definitely an interesting project. And I agree, X11 support in toolkits is likely not going away soon. So X11 compatibility layers for different OS stay interesting. In the end also Waland is going a similar approach as well, XWayland will stay a while.

And while on any system it is always nicer to use native the UI backend, having the ability to use some legacy tools is beneficial. Not every small utility needs to be rewritten.

I’m personally looking forward to see git gui and gitk work with this :slight_smile:

1 Like

This is very exciting, but I can’t help to wish that this project won’t steal too much valuable development time of the Haiku core. I will prefer a more stable system instead of some 3rd party addition at any time. To be more fair, it will be much better if 3rd party additions will be handled via the community instead of paid development time.

4 Likes