Haskell wlroots bindings

Ah, oh well. I do think I’ll give jinja templating a try this weekend–hopefully that will speed certain parts up, somewhat.

Why not a Haskell templating library? I’d rather not touch Python if I can avoid it.

1 Like

That would no doubt be better for the project. Jinja is just what I’m familiar with and know that I can spin up a quick prototype with. I would definitely like to learn Template Haskell at some point, though!

In case you’re unaware, Template Haskell is something completely different — it’s not a general string templating library, but rather a full-blown macro system for Haskell. Undoubtedly it would be the most principled choice, but it adds a lot of complexity and I haven’t ever used it in the past.

Oh, gotcha. Good to know.

There are two places of interest here:

  • Automated conversion from C headers into some intermediate general format.

    People have been trying this forever and the outcome is inevitably trying to generalize C itself. The Vulkan XML directly embeds macros, C bitfields and types like <type>void</type> * const * because it’s a mess either way you do it.

    There are Haskell libraries that autogenerate from C headers, notably bindings-GLFW, but they have to stick to weird conventions out of necessity, like prepending garbage to names and exporting functions multiple times in different formats.

    The correct way to do this would be for each C library to ship an XML with all the function signatures, otherwise I think handrolling just does the job better.

  • Automated conversion from some intermediate general format into Haskell FFI modules.

    The generation here is the the easy part, you just get Data.ByteString.Builder and make a small program that writes files. I’ll inevitably make one like this just because every FFI import currently needs to be defined twice, safe and unsafe, and freetype2 is a rather large library without an XML file.

    However, I don’t think on a community level an opinionated templating library would be enough. You’d most probably want a holistic well-documented FFI experience, and aside from the community agreeing on the one true raw binding format, it would also include:

    • An extra library like storable-offset that is the only Haskell dependency needed to produce FFI bindings. If the generator is a boot library, this one would be too. Currently I think it would only need one type class for normal struct offsets and one for bitfield offsets.

    • Cabal support: FFI libraries as a new type of dependency. This would allow both proper user-side linking (instead of the current mess) and FFI dependency sharing between higher-level libraries.

    • Haddock support: a different way to render FFI functions. C structs are not Haskell datatypes, but I still want them to look accessible instead of being rendered as a bunch of instances. Same way foreign imports are not regular Haskell functions and I would want that to be clear.

    • Hackage support: showing FFI dependencies. Libraries with such dependencies should not be expected to work out of the box. Different languages could also use slightly different webpage styles (e.g. colors), but that would be the gravy on top.

    Sounds like an RFC, doesn’t it?

6 Likes

@bullishOnFunctional very kindly wrote some Jinja macros to generate the aforementioned Haskell types and instances for structs and enums. I’ve rewritten them in Haskell using ginger, and incorporated them into a custom Setup.hs. Now, any hsc file can make use of these macros! This should help development go a bit quicker for these bindings.

(If you want an example, see the new ServerCore.hsc.)

1 Like

Gah, I have been trying to not use this account where I have been clowning around a lot, but this project is simply too attractive to stay silent. I’d be glad to be of help.

First thing first, I think you guys need to take a look at wayland-protocol. IIRC, Most of wayland functionalities are implemented there. It is a streamlined protocol to access tons of wayland features, including potential future extensions. I think a few of wlroots’ features are also made callable via wayland-protocol as well.

The wayland protocol is fairly straightforward to implement, enough for me to generate a TH code to generate the bindings as well. I suggest to try this way first, because the c header part of the protocol can be volatile. Indeed, most of wlroots bindings should be written manually, but I believe you can still save some effort this way.

Another aspect is client-server separation of wayland, which imo is quite important. Since this might be quite long a story, I would talk about this later if needed.

2 Likes

I’m not sure which wayland-protocol you are referring too. I certainly can’t find a Haskell package of that name. The usual implementation of the Wayland protocol is libwayland, upon which wlroots builds — therefore, this is the implementation for which we are making bindings as part of this project.

The aforementioned macro system has been merged into master! Now development should go a bit faster, since it will be easier to write bindings to C structs.

Also, while I’m thinking about this, let me provide an update of which APIs have gotten some bindings so far, out of those I previously mentioned:

2 Likes

I’m trying to work my way towards wlr_seat, but I’m still fighting the xkbcommon library for wlr_keyboard. I have keyboard_group done iirc

2 Likes

Greetings, I’ve wanted to ask, whether taskboard will be available in near future? Even I don’t have much experience in Haskell in production, I would help with implementing some things, and in my opinion it will be super helpful for other developers like me. Or maybe it already exists, if so, I would appreciate if some of you will send a link

I don’t understand what you’re asking for here, sorry.

I meant, does board exists like Jira, Trello or GitHub Project for this project? Because, I don’t understand what’s going on here GitHub - bradrn/wlhs: Haskell bindings to wlroots (and libwayland). So that’s why I asked whether board will be available in the near future or it already exists?
English isn’t my native, so mistakes might occur

Not at the moment. Currently, wlhs is highly incomplete, so practically any new bindings you can write would be helpful!

Somehow, I seem to have suddenly lost the ability to build my own project:

$ cabal build
Resolving dependencies...
Error: cabal: Could not resolve dependencies:
[__0] next goal: wlhs-bindings (user goal)
[__0] rejecting: wlhs-bindings-0.1.0 (conflict: pkg-config package
wayland-server-any, not found in the pkg-config database)
[__0] fail (backjumping, conflict set: wlhs-bindings)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: wlhs-bindings

Cabal says that it can’t find wayland-server in the pkg-config database, even though it clearly does exist:

$ pkg-config --modversion wayland-server
1.22.0

Does anyone have any ideas?

Did you recently do a system update that updated pkg-config? This may be `pkgconf`-provided `pkg-config` does `--modversion` differently; dependency resolution fails mysteriously · Issue #8923 · haskell/cabal · GitHub, which is fixed in HEAD and should be in 3.10.3.

Oh, very interesting! But I doubt this is the issue… my pkgconf was last upgraded more than a month ago (December 7, according to pacman).

I’ve decided to repost this issue on /r/haskell in the hopes of getting any more responses: https://www.reddit.com/r/haskell/comments/19db56s/

Just had some useful discussion with @angerman on Reddit. This revealed the following useful information from cabal build -v3:

Searching for pkg-config in path.
Found pkg-config at /home/bradrn/Documents/wayland/wlhs/pkg-config
Running: /home/bradrn/Documents/wayland/wlhs/pkg-config --version
/home/bradrn/Documents/wayland/wlhs/pkg-config is version 2.1.0
Running: /home/bradrn/Documents/wayland/wlhs/pkg-config --variable pc_path pkg-config
[…omitted…]
Searching for pkg-config in path.
Found pkg-config at /home/bradrn/Documents/wayland/wlhs/pkg-config
Running: /home/bradrn/Documents/wayland/wlhs/pkg-config --version
/home/bradrn/Documents/wayland/wlhs/pkg-config is version 2.1.0
Running: /home/bradrn/Documents/wayland/wlhs/pkg-config --list-all
[…omitted…]
/home/bradrn/Documents/wayland/wlhs/pkg-config returned ExitFailure 141
/home/bradrn/Documents/wayland/wlhs/pkg-config returned ExitFailure 141
Failed to query pkg-config, Cabal will continue without solving for pkg-config
constraints: output of /home/bradrn/Documents/wayland/wlhs/pkg-config:
hGetContents: invalid argument (invalid byte sequence)

So this is weird: hGetContents is reporting an invalid byte sequence, of all things. As an experiment I made a wrapper script which teed the output of pkg-config to a file, then checked the encoding:

$ file pkg-config-out 
pkg-config-out: ISO-8859 text

So pkg-config is outputting text in ISO-8859… which, apparently, hGetContents can’t handle. Resetting the locale to C didn’t help, though.

Upon further investigating the pkg-config output, the following line sticks out to me:

vpl                            Intel® Video Processing Library - Accelerated video decode, encode, and frame processing capabilities o     n Intel® GPUs

Could the ® be the culprit here? What’s more, pacman logs show that libvpl was installed a week ago, so the timing is suspicious. But I don’t know, yet.