diff --git a/inc/lektor/commands.h b/inc/lektor/commands.h
index dae78100702bc29dd707a051f5a8bab8b611ce01..0b4ab432c1d205e24d65eb8784e79d8da33c14e4 100644
--- a/inc/lektor/commands.h
+++ b/inc/lektor/commands.h
@@ -2,7 +2,6 @@
 
 #include <common/common.h>
 #include <lektor/net.h>
-#include <lektor/window.h>
 #include <lektor/database.h>
 
 #include <stdbool.h>
diff --git a/inc/lektor/config.def b/inc/lektor/config.def
index fc0ba35475ef56cb60b14923504ddbc9bd6b09a4..001f44d3d611e4baa975dcac7b2532f0ff088b9a 100644
--- a/inc/lektor/config.def
+++ b/inc/lektor/config.def
@@ -11,8 +11,7 @@ value("kara_dir",       "/home/kara")
 value("db_path",        "/home/kara/kara.db")
 
 section("repo")
-value_opt("path",       "STATIC")
-value("load_function",  "load_repo_https")
+value("module",         "repo")
 value("name",           "Kurisu")
 value("url",            "https://kurisu.iiens.net")
 value("json",           "https://kurisu.iiens.net/api")
@@ -20,8 +19,7 @@ value("id_json",        "https://kurisu.iiens.net/api?id=%ld")
 value("id_kara",        "https://kurisu.iiens.net/download.php?id=%ld")
 
 section("player")
-value_opt("path",       "STATIC")
-value("load_function",  "load_sdl2")
+value("module",         "sdl2")
 value("autoclear",      "true")
 value("def_random",     "false")
 value("def_consume",    "false")
diff --git a/inc/lektor/module/module_sdl2.h b/inc/lektor/module/module_sdl2.h
deleted file mode 100644
index ae6c58fc8dbeb94c793c877566b7f20256b0f17b..0000000000000000000000000000000000000000
--- a/inc/lektor/module/module_sdl2.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#pragma once
-
-#include <stdbool.h>
-#include <sqlite3.h>
-#include <lektor/window.h>
-
-#if defined(_STATIC_MODULES)
-/* The only function with a setted filename */
-int load_sdl2(void *mod, struct lkt_state *srv, void *handle);
-#endif
-
-/* Below there are needed functions for a window module.
- * Names are not fixed but they follow a convention (to get a code easy
- * to read). They should not be used in lektor! They will be loaded into
- * the struct lkt_win by the module_set_function.
- */
-bool module_sdl2_new(struct lkt_win *const win);
-void module_sdl2_close(struct lkt_win *const win);
-void module_sdl2_free(struct lkt_win *const win);
-
-bool module_sdl2_toggle_pause(struct lkt_win *const win);
-bool module_sdl2_load_file(struct lkt_win *const win, const char *filepath);
-bool module_sdl2_set_volume(struct lkt_win *const win, int vol);
-
-bool module_sdl2_get_duration(struct lkt_win *const win, int *dur_sec);
-bool module_sdl2_get_elapsed(struct lkt_win *const win, int *elapsed_sec);
diff --git a/inc/lektor/module/mpv.h b/inc/lektor/module/mpv.h
index 2b412b6485dc872cba2fd00d586b3123594f0e18..48ed12ce2ca9db57a57db41cc72205c6a6a41a3d 100644
--- a/inc/lektor/module/mpv.h
+++ b/inc/lektor/module/mpv.h
@@ -1,10 +1,10 @@
 #pragma once
 
-#include <sqlite3.h>
 #include <mpv/client.h>
 #include <common/common.h>
 #include <common/queue.h>
-#include <lektor/window.h>
+#include <lektor/reg.h>
+#include <sqlite3.h>
 
 void lmpv_free(mpv_handle **ctx);
 mpv_handle *lmpv_new(unsigned long int wid, volatile sqlite3 *db);
@@ -14,6 +14,6 @@ mpv_handle *lmpv_prepare(volatile sqlite3 *db);
 int lmpv_set_volume(mpv_handle *ctx, int vol);
 int lmpv_load_file(mpv_handle *ctx, const char *file);
 int lmpv_toggle_pause(mpv_handle *ctx);
-int lmpv_handle(struct lkt_win *win, mpv_handle *ctx, struct queue *queue,
+int lmpv_handle(struct lkt_module *mod, mpv_handle *ctx, struct queue *queue,
                 volatile int *time_pos, volatile int *time_duration,
                 volatile int *state);
diff --git a/inc/lektor/net.h b/inc/lektor/net.h
index 0e69299543c0735b6485c3e316b5269bbd1ff603..18a171b19b0bed4527e9ea2371194df10ac1e0eb 100644
--- a/inc/lektor/net.h
+++ b/inc/lektor/net.h
@@ -4,8 +4,8 @@
 #include <common/queue.h>
 #include <lektor/mkv.h>
 #include <lektor/config.h>
-#include <lektor/window.h>
 #include <lektor/thread.h>
+#include <lektor/reg.h>
 #include <lektor/uri.h>
 
 #include <pthread.h>
@@ -82,12 +82,10 @@ struct lkt_state {
     mpd_idle_flag mpd_idle_events;
     pthread_mutex_t lock;
 
-    struct lkt_repo repo;
-    struct lkt_win win;
+    struct lkt_module window_mod;
+    struct lkt_module repo_mod;
 };
 
-void lkt_set_event_available(struct lkt_state *srv, enum lkt_event_type type);
-
 /* Send a message to the connected client. */
 void lkt_state_send(struct lkt_state *srv, size_t c, struct lkt_message *msg);
 
diff --git a/inc/lektor/reg.h b/inc/lektor/reg.h
index 1e43acb6958dff9dcd906f9e5e67a322636437ed..a584e60eedccb9df3b478fa6ad23db54393ebd1c 100644
--- a/inc/lektor/reg.h
+++ b/inc/lektor/reg.h
@@ -1,4 +1,5 @@
 #if ! defined(__REG_H__)
+#define __REG_H__
 
 struct lkt_state;
 
@@ -16,6 +17,13 @@ struct module_reg {
     };
 };
 
+/* A module */
+struct lkt_module {
+    struct module_reg *reg;
+    void *handle;
+    void *data;
+};
+
 #define REG_EXPORT_NAME     "__reg__"
 #define REG_BEGIN(reg)      struct module_reg reg[] = {
 #define REG_ADD(f)          { .name = #f,   .func = f    },
@@ -50,4 +58,4 @@ int reg_import(const char *mod, struct module_reg **ret, void **handle);
 /* Set the __reg__ pointer. */
 void reg_export(struct module_reg *reg);
 
-#endif
+#endif /* __REG_H__ */
diff --git a/inc/lektor/window.h b/inc/lektor/window.h
deleted file mode 100644
index 462f9fa7a5fc052fc896c6a7453d57307c6164a2..0000000000000000000000000000000000000000
--- a/inc/lektor/window.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#pragma once
-
-/* The window is a module */
-
-#include <common/common.h>
-#include <stdbool.h>
-#include <sqlite3.h>
-
-typedef void *lkt_win_element_t;    /* The real window struct, an opaque type   */
-struct lkt_state;                   /* Forward definition of the server         */
-
-/* The window with the selected correct functions, this is done because we may
-   need an SDL2, a X11 or a QT window, and may want to select the one to use at
-   run time. */
-struct lkt_win {
-    lkt_win_element_t window;           /* the opaque window type that depend on the module */
-    void *handle;                       /* the libdl handle                                 */
-    struct lkt_state *srv;              /* The server, must be set before the new call      */
-
-    /* Create and free the window */
-    bool (*new)(struct lkt_win *win);   /* Create a window or only the mpv context  */
-    void (*close)(struct lkt_win *win); /* Close the mpv context, not the window    */
-    void (*free)(struct lkt_win *win);  /* Entirelly liberate all the resources     */
-
-    /* Playback control */
-    bool (*toggle_pause)(struct lkt_win *win);
-    bool (*load_file)(struct lkt_win *win, const char *filepath);
-    bool (*set_volume)(struct lkt_win *win, int vol);
-
-    /* Get playback properties */
-    bool (*get_duration)(struct lkt_win *win, int *dur_sec);
-    bool (*get_elapsed)(struct lkt_win *win, int *elapsed_sec);
-
-    /* Handle loop event */
-    bool (*handle_events)(struct lkt_win *win, volatile sqlite3 *db,
-                          mpd_idle_flag *mpd_idle_events);
-};
diff --git a/meson_options.txt b/meson_options.txt
index ff8b1283e7c64efb6aed784e39ad250c1b6a3ad4..9791739bdcb0f6034c5d537074d5d3adb1d3e768 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -1,7 +1,4 @@
 option('static_modules', type: 'feature', value: 'enabled'
       , description: 'Build modules and link them statically with lektord')
-
 option('module_sdl', type: 'feature', value: 'enabled', description: 'Build the sdl module')
-option('module_x11', type: 'feature', value: 'enabled', description: 'Build the x11 module')
-
 option('static_liblektor', type: 'boolean', value: true, description: 'Link the liblektor statically')
diff --git a/src/main/server.c b/src/main/server.c
index 02a9023594212187e0236b070c244a4fb4e15074..90687dd86b9c347e4ad7d36d882e6c933336d93e 100644
--- a/src/main/server.c
+++ b/src/main/server.c
@@ -19,6 +19,9 @@
 #include <pthread.h>
 
 REG_DECLARE(repo_reg)
+#if defined (_STATIC_MODULES) && (_STATIC_SDL2)
+REG_DECLARE(sdl2_reg)
+#endif
 
 int
 main(int argc, char *argv[])
@@ -26,6 +29,9 @@ main(int argc, char *argv[])
     REG_BEGIN(server_reg)
     REG_ADD(load_repo_https)
     REG_REGISTER("repo", repo_reg)
+#if defined (_STATIC_MODULES) && (_STATIC_SDL2)
+    REG_REGISTER("sdl2", sdl2_reg)
+#endif
     REG_END()
 
     char exe[PATH_MAX];
@@ -111,15 +117,14 @@ normal_launch:
 
     lkt_queue_make_available(&srv.queue, lkt_event_prop);
     char *module = safe_malloc(sizeof(char) * PATH_MAX);
-    struct module_reg *player_mod, *repo_mod;
-    void *player_handle, *repo_handle;
     database_config_get_text(srv.db, "player", "module", module, PATH_MAX);
-    reg_import(module, &player_mod, &player_handle);
-    reg_import("repo", &repo_mod, &repo_handle);
+    reg_import(module, &srv.window_mod.reg, &srv.window_mod.handle);
+    reg_import("repo", &srv.repo_mod.reg, &srv.repo_mod.handle);
     free(module);
 
-    void *handle = NULL;
-    reg_call(server_reg, "load_repo_https", 3, &srv.repo, &srv, handle);
+    srv.repo_reg.data = safe_zero_malloc(sizeof(struct lkt_repo));
+    reg_call(srv.repo_mod.reg, "load_repo_https", 3, srv.repo_reg.data, &srv, handle);
+    reg_call(srv.window_mod.reg, "new", 3, &srv.player_mod.data, &srv.queue, srv.db);
 
     /* Get ENV */
     /* Not working -> race condition with player module */
diff --git a/src/module/module_sdl2.c b/src/module/module_sdl2.c
index 0e5a2b623589369329184fe0c278beaa968718e2..775f1b696525e5bfc9bbde65bb40575abbf6dcaf 100644
--- a/src/module/module_sdl2.c
+++ b/src/module/module_sdl2.c
@@ -2,12 +2,12 @@
 
 #include <common/common.h>
 #include <common/queue.h>
-#include <lektor/module/module_sdl2.h>
 #include <lektor/module/mpv.h>
 #include <lektor/thread.h>
 #include <lektor/reg.h>
 #include <lektor/net.h>
 
+#include <sqlite3.h>
 #include <sched.h>
 #include <assert.h>
 #include <string.h>
@@ -43,8 +43,19 @@ struct module_sdl2_window {
 
     /* Things from the server */
     struct queue *queue;
+    volatile sqlite3 *db;
 };
 
+/* Function definitions */
+bool module_sdl2_get_elapsed(struct module_sdl2_window *, int *);
+bool module_sdl2_get_duration(struct module_sdl2_window *, int *);
+bool module_sdl2_set_volume(struct module_sdl2_window *, int);
+bool module_sdl2_load_file(struct module_sdl2_window *, const char *);
+bool module_sdl2_toggle_pause(struct module_sdl2_window *);
+void module_sdl2_free(struct module_sdl2_window *);
+void module_sdl2_close(struct module_sdl2_window *);
+bool module_sdl2_new(struct module_sdl2_window **, struct queue *, volatile sqlite3 *);
+
 /* Private functions. */
 
 static inline void *
@@ -101,17 +112,134 @@ init_mpv_gl__(mpv_handle *mpv, mpv_render_context **mpv_gl,
     return 0;
 }
 
+/* va_list version of functions. */
+
+int
+mod_new(va_list *va)
+{
+    va_list copy;
+    va_copy(copy, *va);
+    void **win_void = va_arg(copy, void **);
+    struct module_sdl2_window **win = (struct module_sdl2_window **) win_void;
+    struct queue *queue  = va_arg(copy, struct queue *);
+    volatile sqlite3 *db = va_arg(copy, volatile sqlite3 *);
+    bool ret = module_sdl2_new(win, queue, db);
+    va_end(copy);
+    return ! ret;
+}
+
+int
+mod_close(va_list *va)
+{
+    va_list copy;
+    va_copy(copy, *va);
+    struct module_sdl2_window *win = va_arg(copy, void *);
+    module_sdl2_close(win);
+    va_end(copy);
+    return 0;
+}
+
+int
+mod_free(va_list *va)
+{
+    va_list copy;
+    va_copy(copy, *va);
+    struct module_sdl2_window *win = va_arg(copy, void *);
+    module_sdl2_free(win);
+    va_end(copy);
+    return 0;
+}
+
+int
+mod_toggle_pause(va_list *va)
+{
+    va_list copy;
+    va_copy(copy, *va);
+    struct module_sdl2_window *win = va_arg(copy, void *);
+    bool ret = module_sdl2_toggle_pause(win);
+    va_end(copy);
+    return ! ret;
+}
+
+int
+mod_load_file(va_list *va)
+{
+    va_list copy;
+    va_copy(copy, *va);
+    struct module_sdl2_window *win = va_arg(copy, void *);
+    const char *file = va_arg(copy, const char *);
+    bool ret = module_sdl2_load_file(win, file);
+    va_end(copy);
+    return ! ret;
+}
+
+int
+mod_set_volume(va_list *va)
+{
+    va_list copy;
+    va_copy(copy, *va);
+    struct module_sdl2_window *win = va_arg(copy, void *);
+    int volume = va_arg(copy, int);
+    bool ret = module_sdl2_set_volume(win, volume);
+    va_end(copy);
+    return ! ret;
+}
+
+int
+mod_get_duration(va_list *va)
+{
+    va_list copy;
+    va_copy(copy, *va);
+    struct module_sdl2_window *win = va_arg(copy, void *);
+    int *duration = va_arg(copy, int *);
+    bool ret = module_sdl2_get_duration(win, duration);
+    va_end(copy);
+    return ! ret;
+}
+
+int
+mod_get_elapsed(va_list *va)
+{
+    va_list copy;
+    va_copy(copy, *va);
+    struct module_sdl2_window *win = va_arg(copy, void *);
+    int *elapsed = va_arg(copy, int *);
+    bool ret = module_sdl2_get_elapsed(win, elapsed);
+    va_end(copy);
+    return ! ret;
+}
+
+/* The module stuff */
+
+REG_BEGIN(sdl2_reg)
+REG_ADD_NAMED("new",          mod_new)
+REG_ADD_NAMED("free",         mod_free)
+REG_ADD_NAMED("close",        mod_close)
+REG_ADD_NAMED("toggle",       mod_toggle_pause)
+REG_ADD_NAMED("load",         mod_load_file)
+REG_ADD_NAMED("set_volume",   mod_set_volume)
+REG_ADD_NAMED("get_duration", mod_get_duration)
+REG_ADD_NAMED("get_elapsed",  mod_get_elapsed)
+REG_END()
+REG_EXPORT(sdl2_reg)
+
+/* Function implementation */
+
 static void *
 sdl_thread__(struct poller_thread_arg *arg)
 {
-    volatile struct lkt_win *const win       = arg->args;
-    volatile struct module_sdl2_window *sdl2 = win->window;
+    struct module_sdl2_window *sdl2 = arg->args;
     SDL_Event event;
     uint64_t flags;
     int w, h, redraw = 0;
     bool ctrl = false;
     const Uint8 *state;
     free(arg);
+    struct lkt_module module = {
+        .handle = NULL,
+        .reg = sdl2_reg,
+        .data = sdl2,
+    };
 
     /* Init the SDL window
        Yeah, SDL you sucks */
@@ -129,7 +257,7 @@ sdl_thread__(struct poller_thread_arg *arg)
 
     /* Init mpv here */
 
-    RETURN_IF(init_mpv__((mpv_handle **) & sdl2->mpv, win->srv->db),
+    RETURN_IF(init_mpv__((mpv_handle **) & sdl2->mpv, sdl2->db),
               "Failed to init mpv", false);
 
     mpv_render_param params[] = {
@@ -169,8 +297,8 @@ loop:
 
     case SDL_WINDOWEVENT:
         if (event.window.event == SDL_WINDOWEVENT_EXPOSED) {
-            lkt_queue_make_available(&win->srv->queue, lkt_event_play);
-            lkt_queue_make_available(&win->srv->queue, lkt_event_prop);
+            lkt_queue_make_available(sdl2->queue, lkt_event_play);
+            lkt_queue_make_available(sdl2->queue, lkt_event_prop);
             redraw = 1;
         }
         break;
@@ -227,10 +355,10 @@ loop:
                 redraw = 1;
         }
 
-        if (event.type == wakeup_on_mpv_events)
-            lmpv_handle((struct lkt_win *) win, (mpv_handle *) sdl2->mpv,
-                        sdl2->queue, &sdl2->mpv_time_pos, &sdl2->mpv_duration,
-                        &sdl2->state);
+        if (event.type == wakeup_on_mpv_events) {
+            lmpv_handle(&module, (mpv_handle *) sdl2->mpv, sdl2->queue,
+                        &sdl2->mpv_time_pos, &sdl2->mpv_duration, &sdl2->state);
+        }
     }
 
     if (redraw) {
@@ -263,211 +391,93 @@ end:
     return NULL;
 }
 
-/* Exported functions */
-
 bool
-module_sdl2_new(struct lkt_win *const win)
+module_sdl2_new(struct module_sdl2_window **win, struct queue *queue,
+                volatile sqlite3 *db)
 {
     RETURN_UNLESS(win, "Invalid arguments", false);
     struct poller_thread_arg *arg;
 
-    if (win->window == NULL) {
-        win->window = calloc(1, sizeof(struct module_sdl2_window));
-        RETURN_UNLESS(win->window, "Out of memory", false);
-        memset(win->window, 0, sizeof(struct module_sdl2_window));
+    if (*win == NULL) {
+        *win = calloc(1, sizeof(struct module_sdl2_window));
+        RETURN_UNLESS(*win, "Out of memory", false);
+        memset(*win, 0, sizeof(struct module_sdl2_window));
 
-        /* Yeah, this is how it is done. */
-        struct module_sdl2_window *sdl2 = win->window;
-        sdl2->queue = &win->srv->queue;
+        (*win)->queue = queue;
+        (*win)->db    = db;
 
         /* Start the SDL thread */
         arg = malloc(sizeof(struct poller_thread_arg));
         RETURN_UNLESS(arg, "Out of memory", false);
-        arg->args = win;
-        RETURN_IF(poller_new(&((struct module_sdl2_window *)win->window)->self,
-                             sdl_thread__, arg),
+        arg->args = *win;
+        RETURN_IF(poller_new(&(*win)->self, sdl_thread__, arg),
                   "Failed to launch the SDL thread", false);
     }
 
     /* Finish */
-    SDL_SetWindowTitle((SDL_Window *) ((struct module_sdl2_window *)
-                                       win->window)->window, "Lektord");
+    SDL_SetWindowTitle((SDL_Window *) (*win)->window, "Lektord");
     SDL_DisableScreenSaver();
-    ((struct module_sdl2_window *) win->window)->launched = 1;
+    (*win)->launched = 1;
     return true;
 }
 
 void
-module_sdl2_close(struct lkt_win *const win)
+module_sdl2_close(struct module_sdl2_window *win)
 {
     RETURN_UNLESS(win && win->window, "Invalid arguments", NOTHING);
-    struct module_sdl2_window *sdl2 = win->window;
-    sdl2->mpv_time_pos = (sdl2->mpv_duration = 0);
-    RETURN_UNLESS(sdl2->mpv, "Missing mpv ctx", NOTHING);
+    win->mpv_time_pos = win->mpv_duration = 0;
+    RETURN_UNLESS(win->mpv, "Missing mpv ctx", NOTHING);
     static const char *cmd[] = { "stop", NULL };
-    mpv_command_async((mpv_handle *) sdl2->mpv, 0, cmd);
+    mpv_command_async((mpv_handle *) win->mpv, 0, cmd);
     /* TODO: make the SDL window background be black. */
 }
 
 void
-module_sdl2_free(struct lkt_win *const win)
+module_sdl2_free(struct module_sdl2_window *win)
 {
-    RETURN_UNLESS(win && win->window, "Invalid arguments", NOTHING);
-    struct module_sdl2_window *sdl2 = win->window;
-    sdl2->launched = 2;
-    while (sdl2->launched)
+    RETURN_UNLESS(win, "Invalid arguments", NOTHING);
+    win->launched = 2;
+    while (win->launched)
         sched_yield();
-    poller_join(&sdl2->self, NULL);
+    poller_join(&win->self, NULL);
 }
 
 bool
-module_sdl2_toggle_pause(struct lkt_win *const win)
+module_sdl2_toggle_pause(struct module_sdl2_window *win)
 {
-    RETURN_UNLESS(win && win->window, "Invalid arguments", false);
-    return ! lmpv_toggle_pause((mpv_handle *) ((struct module_sdl2_window *)
-                               win->window)->mpv);
+    RETURN_UNLESS(win, "Invalid arguments", false);
+    return ! lmpv_toggle_pause((mpv_handle *) win->mpv);
 }
 
 bool
-module_sdl2_load_file(struct lkt_win *const win, const char *filepath)
+module_sdl2_load_file(struct module_sdl2_window *win, const char *filepath)
 {
-    RETURN_UNLESS(win && win->window, "Invalid arguments", false);
-    struct module_sdl2_window *sdl2 = win->window;
-    bool ret = ! lmpv_load_file((mpv_handle *) sdl2->mpv, filepath);
-    sdl2->mpv_duration = 0;
-    sdl2->mpv_time_pos = 0;
+    RETURN_UNLESS(win, "Invalid arguments", false);
+    bool ret = ! lmpv_load_file((mpv_handle *) win->mpv, filepath);
+    win->mpv_duration = 0;
+    win->mpv_time_pos = 0;
     return ret;
 }
 
 bool
-module_sdl2_set_volume(struct lkt_win *const win, int vol)
+module_sdl2_set_volume(struct module_sdl2_window *win, int vol)
 {
     RETURN_UNLESS(win && win->window, "Invalid arguments", false);
-    return ! lmpv_set_volume((mpv_handle *)
-                             ((struct module_sdl2_window *) win->window)->mpv,
-                             vol);
+    return ! lmpv_set_volume((mpv_handle *) win->mpv, vol);
 }
 
 bool
-module_sdl2_get_duration(struct lkt_win *const win, int *dur_sec)
+module_sdl2_get_duration(struct module_sdl2_window *win, int *dur_sec)
 {
-    RETURN_UNLESS(win && win->window, "Invalid arguments", false);
-    *dur_sec = ((struct module_sdl2_window *) win->window)->mpv_duration;
+    RETURN_UNLESS(win, "Invalid arguments", false);
+    *dur_sec = win->mpv_duration;
     return true;
 }
 
 bool
-module_sdl2_get_elapsed(struct lkt_win *const win, int *elapsed_sec)
+module_sdl2_get_elapsed(struct module_sdl2_window *win, int *elapsed_sec)
 {
-    RETURN_UNLESS(win && win->window, "Invalid arguments", false);
-    *elapsed_sec = ((struct module_sdl2_window *) win->window)->mpv_time_pos;
+    RETURN_UNLESS(win, "Invalid arguments", false);
+    *elapsed_sec = win->mpv_time_pos;
     return true;
 }
-
-/* va_list version of functions. */
-
-int
-mod_new(va_list *va)
-{
-    va_list copy;
-    va_copy(copy, *va);
-    struct lkt_win *win = va_arg(copy, struct lkt_win *);
-    bool ret = module_sdl2_new(win);
-    va_end(copy);
-    return ! ret;
-}
-
-int
-mod_close(va_list *va)
-{
-    va_list copy;
-    va_copy(copy, *va);
-    struct lkt_win *win = va_arg(copy, struct lkt_win *);
-    module_sdl2_close(win);
-    va_end(copy);
-    return 0;
-}
-
-int
-mod_free(va_list *va)
-{
-    va_list copy;
-    va_copy(copy, *va);
-    struct lkt_win *win = va_arg(copy, struct lkt_win *);
-    module_sdl2_free(win);
-    va_end(copy);
-    return 0;
-}
-
-int
-mod_toggle_pause(va_list *va)
-{
-    va_list copy;
-    va_copy(copy, *va);
-    struct lkt_win *win = va_arg(copy, struct lkt_win *);
-    bool ret = module_sdl2_toggle_pause(win);
-    va_end(copy);
-    return ! ret;
-}
-
-int
-mod_load_file(va_list *va)
-{
-    va_list copy;
-    va_copy(copy, *va);
-    struct lkt_win *win = va_arg(copy, struct lkt_win *);
-    const char *file    = va_arg(copy, const char *);
-    bool ret = module_sdl2_load_file(win, file);
-    va_end(copy);
-    return ! ret;
-}
-
-int
-mod_set_volume(va_list *va)
-{
-    va_list copy;
-    va_copy(copy, *va);
-    struct lkt_win *win = va_arg(copy, struct lkt_win *);
-    int volume          = va_arg(copy, int);
-    bool ret = module_sdl2_set_volume(win, volume);
-    va_end(copy);
-    return ! ret;
-}
-
-int
-mod_get_duration(va_list *va)
-{
-    va_list copy;
-    va_copy(copy, *va);
-    struct lkt_win *win = va_arg(copy, struct lkt_win *);
-    int *duration       = va_arg(copy, int *);
-    bool ret = module_sdl2_get_duration(win, duration);
-    va_end(copy);
-    return ! ret;
-}
-
-int
-mod_get_elapsed(va_list *va)
-{
-    va_list copy;
-    va_copy(copy, *va);
-    struct lkt_win *win = va_arg(copy, struct lkt_win *);
-    int *elapsed        = va_arg(copy, int *);
-    bool ret = module_sdl2_get_elapsed(win, elapsed);
-    va_end(copy);
-    return ! ret;
-}
-
-/* The module stuff */
-
-REG_BEGIN(sdl2_reg)
-REG_ADD_NAMED("new",          mod_new)
-REG_ADD_NAMED("free",         mod_free)
-REG_ADD_NAMED("close",        mod_close)
-REG_ADD_NAMED("toggle",       mod_toggle_pause)
-REG_ADD_NAMED("load",         mod_load_file)
-REG_ADD_NAMED("set_volume",   mod_set_volume)
-REG_ADD_NAMED("get_duration", mod_get_duration)
-REG_ADD_NAMED("get_elapsed",  mod_get_elapsed)
-REG_END()
-REG_EXPORT(sdl2_reg)
diff --git a/src/module/mpv.c b/src/module/mpv.c
index eb0b901484c0956859f55e8c443a663fe1998405..b52c75ee7bb6793ed841635810f83b4a1831f8d3 100644
--- a/src/module/mpv.c
+++ b/src/module/mpv.c
@@ -150,14 +150,14 @@ lmpv_toggle_pause(mpv_handle *ctx)
 }
 
 int
-lmpv_handle(struct lkt_win *win, mpv_handle *ctx, struct queue *queue,
+lmpv_handle(struct lkt_module *mod, mpv_handle *ctx, struct queue *queue,
             volatile int *time_pos, volatile int *time_duration,
             volatile int *state)
 {
     size_t ao_volume;
     mpv_event *event = NULL;
     mpv_event_property *prop;
-    RETURN_UNLESS(ctx && win, "Invalid argument", 1);
+    RETURN_UNLESS(ctx, "Invalid argument", 1);
 
 loop:
     event = mpv_wait_event(ctx, 0);
@@ -177,7 +177,7 @@ loop:
         *time_pos = (*time_duration = 0);
         *state = STATE_STOP;
         lkt_queue_send(queue, lkt_event_play_toggle, LKT_PLAY_STOP);
-        win->close(win);
+        reg_call(mod->reg, "close", 1, mod->data);
         return 1;
 
     case MPV_EVENT_NONE:
diff --git a/src/module/repo.c b/src/module/repo.c
index aa9dace4e90068156672f897bd34226e8e638a87..dba9a1b954a1d8c57efee8a87f7890be893fe79d 100644
--- a/src/module/repo.c
+++ b/src/module/repo.c
@@ -96,7 +96,7 @@ load_repo_https(va_list *va)
 {
     va_list copy;
     va_copy(copy, *va);
-    struct lkt_repo *repo = va_arg(copy, struct lkt_repo *);
+    struct lkt_repo *repo = va_arg(copy, void *);
     struct lkt_state *srv = va_arg(copy, struct lkt_state *);
     int ret = repo_new(repo, srv);
     va_end(copy);
diff --git a/src/net/listen.c b/src/net/listen.c
index fa05cfe7a0d1a275ead32fcdbd1e5c66f4aba598..cc0411972673598c353704ec8a14c6c2d26725ba 100644
--- a/src/net/listen.c
+++ b/src/net/listen.c
@@ -50,12 +50,6 @@ struct lkt_client {
     int continuation;
 };
 
-void
-lkt_set_event_available(struct lkt_state *srv, enum lkt_event_type type)
-{
-    lkt_queue_make_available(&srv->queue, type);
-}
-
 static inline bool
 lkt_close_client(struct lkt_state *srv, size_t c)
 {