aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2024-02-08 19:50:10 -0700
committerJosh Rahm <joshuarahm@gmail.com>2024-02-08 19:50:10 -0700
commit3e5cdf208606700b45acecf7c8a0b366a8caa106 (patch)
tree306272a3dde9b61cdb38f502493f895067af98c2 /src
downloadwetterhorn-3e5cdf208606700b45acecf7c8a0b366a8caa106.tar.gz
wetterhorn-3e5cdf208606700b45acecf7c8a0b366a8caa106.tar.bz2
wetterhorn-3e5cdf208606700b45acecf7c8a0b366a8caa106.zip
Initial commit for Project Wetterhorn.
Project Wetterhorn is an attempt to make a Wayland compositor inspired by XMonad. This project is different from other Wayland compositors in that one of its core tenets is dynamic reloading of as much code as possible. The architecture is going to be: - A harness, written in C, supplies the basic components to create a Wayland compositor. This will be modeled on tinywl, sway, dwl and others and use wlroots as its main abstraction to wayland. - A dynamic library, written in Haskell, will provide bindings for handling events and managing the windows. This dynamic library can be recompiled and reloaded at runtime, allowing the user to write their 'configuration' in Haskell, much as XMonad, but without needing to reboot the whole compositor. The boundaries of responsibilities between the harness and the plugin will be an evolving matter, depending on how important the dynamic reloading is for that specific responsibility and the need for raw performance. I chose this architecture as a compromise. With this architecture, dynamic loading is achieved without the need to define a whole protocol around controlling the window management, but this also gives the plugin the full ability to control the compositor because it is literally a part of it making anything possible in theory, which is a huge benefit.
Diffstat (limited to 'src')
-rw-r--r--src/Lib.hs6
-rw-r--r--src/Main.hs14
-rw-r--r--src/harness/main.c65
-rw-r--r--src/harness_adapter.c12
4 files changed, 97 insertions, 0 deletions
diff --git a/src/Lib.hs b/src/Lib.hs
new file mode 100644
index 0000000..d36ff27
--- /dev/null
+++ b/src/Lib.hs
@@ -0,0 +1,6 @@
+module Lib
+ ( someFunc
+ ) where
+
+someFunc :: IO ()
+someFunc = putStrLn "someFunc"
diff --git a/src/Main.hs b/src/Main.hs
new file mode 100644
index 0000000..c43ef13
--- /dev/null
+++ b/src/Main.hs
@@ -0,0 +1,14 @@
+module Main (main) where
+import Control.Monad.Writer (execWriter, MonadWriter (tell))
+
+foreign export ccall call_in :: IO ()
+call_in :: IO ()
+call_in = putStrLn $ execWriter $ do
+ tell "Yo,"
+ tell " This was "
+ tell "Called"
+ tell " From"
+ tell " C!!"
+
+main :: IO ()
+main = putStrLn "This should be dynamically linked!\n"
diff --git a/src/harness/main.c b/src/harness/main.c
new file mode 100644
index 0000000..6666e5e
--- /dev/null
+++ b/src/harness/main.c
@@ -0,0 +1,65 @@
+#include <stdio.h>
+
+#include <dlfcn.h>
+
+typedef void* dllib_t;
+
+dllib_t open_library(const char* library, int* err)
+{
+ dllib_t lib = dlopen(library, RTLD_LAZY);
+
+ if (!lib) {
+ fprintf(stderr, "Error opening shared library: %s\n", dlerror());
+ *err = 1;
+ }
+ *err = 0;
+ return lib;
+}
+
+void* getsym(dllib_t handle, char* sym, int* err)
+{
+ void* ret = dlsym(handle, sym);
+ if (!ret) {
+ fprintf(stderr, "Unable to read symbol '%s'\n", sym);
+ *err |= 1;
+ return NULL;
+ }
+ return ret;
+}
+
+void use_library(int argc, char** argv, dllib_t lib, int* err)
+{
+ *err = 0;
+
+ void (*init)(int* argc, char*** argv) = getsym(lib, "plugin_init", err);
+ void (*teardown)() = getsym(lib, "plugin_teardown", err);
+ void (*sym)() = getsym(lib, "call_in", err);
+
+ if (!sym) {
+ *err = 1;
+ fprintf(stderr, "Unable to find symbol call_in.\n");
+ return;
+ }
+
+ init(&argc, &argv);
+ sym();
+ teardown();
+}
+
+int main(int argc, char** argv)
+{
+ if (!argv[0] && !argv[1]) {
+ fprintf(stderr, "Missing argument.\n");
+ return 1;
+ }
+
+ int err = 0;
+ dllib_t lib = open_library(argv[1], &err);
+
+ if (err) {
+ return err;
+ }
+
+ use_library(argc, argv, lib, &err);
+ return 0;
+}
diff --git a/src/harness_adapter.c b/src/harness_adapter.c
new file mode 100644
index 0000000..9cd8118
--- /dev/null
+++ b/src/harness_adapter.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include "HsFFI.h"
+
+void plugin_init(int* argc, char*** argv)
+{
+ hs_init(argc, argv);
+}
+
+void plugin_teardown()
+{
+ hs_exit();
+}