diff --git a/inc/common/macro.h b/inc/common/macro.h
index c585059c7ad39800c1fde456f2f4a517eb57217f..ff1accded7f4f0f320713404dd4a457b2d10e226 100644
--- a/inc/common/macro.h
+++ b/inc/common/macro.h
@@ -174,3 +174,20 @@ typedef volatile enum {
 #define STR_NMATCH(str1, str2, n)       (! strncasecmp(str1, str2, n))
 
 #define sqlite3_column_chars BRACKETS_THAT(const char *) sqlite3_column_text
+
+#define GET_VA_COUNT(...)   PP_NARG_(__VA_ARGS__,PP_RSEQ_N())
+#define PP_NARG_(...)       PP_ARG_N(__VA_ARGS__)
+#define PP_ARG_N( _1, _2, _3, _4, _5, _6, _7, _8, _9,_10,   \
+                  _11,_12,_13,_14,_15,_16,_17,_18,_19,_20,  \
+                  _21,_22,_23,_24,_25,_26,_27,_28,_29,_30,  \
+                  _31,_32,_33,_34,_35,_36,_37,_38,_39,_40,  \
+                  _41,_42,_43,_44,_45,_46,_47,_48,_49,_50,  \
+                  _51,_52,_53,_54,_55,_56,_57,_58,_59,_60,  \
+                  _61,_62,_63,N,...) N
+#define PP_RSEQ_N() 63,62,61,60,                   \
+                    59,58,57,56,55,54,53,52,51,50, \
+                    49,48,47,46,45,44,43,42,41,40, \
+                    39,38,37,36,35,34,33,32,31,30, \
+                    29,28,27,26,25,24,23,22,21,20, \
+                    19,18,17,16,15,14,13,12,11,10, \
+                    9,8,7,6,5,4,3,2,1,0
diff --git a/inc/lektor/commands.h b/inc/lektor/commands.h
index 0b4ab432c1d205e24d65eb8784e79d8da33c14e4..37d6378f22af87e88a165eb33cdda9cc5545a315 100644
--- a/inc/lektor/commands.h
+++ b/inc/lektor/commands.h
@@ -18,37 +18,35 @@ bool command_currentsong(struct lkt_state *srv, size_t c);
 bool command_status     (struct lkt_state *srv, size_t c);
 
 /* Controlling playback */
-bool command_next    (volatile sqlite3 *db, struct lkt_win *win,                                   mpd_idle_flag *watch_mask_ptr);
-bool command_pause   (volatile sqlite3 *db, struct lkt_win *win,                                   mpd_idle_flag *watch_mask_ptr);
-bool command_previous(volatile sqlite3 *db, struct lkt_win *win,                                   mpd_idle_flag *watch_mask_ptr);
-bool command_play    (volatile sqlite3 *db, struct lkt_win *win, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr);
-bool command_stop    (volatile sqlite3 *db, struct lkt_win *win,                                   mpd_idle_flag *watch_mask_ptr);
+bool command_next    (struct lkt_state *srv,                                   mpd_idle_flag *watch_mask_ptr);
+bool command_pause   (struct lkt_state *srv,                                   mpd_idle_flag *watch_mask_ptr);
+bool command_previous(struct lkt_state *srv,                                   mpd_idle_flag *watch_mask_ptr);
+bool command_play    (struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr);
+bool command_stop    (struct lkt_state *srv,                                   mpd_idle_flag *watch_mask_ptr);
 
-bool command_set_pos(volatile sqlite3 *db, struct lkt_win *win, mpd_idle_flag *watch_mask_ptr, int index);
+bool command_set_pos(struct lkt_state *srv, mpd_idle_flag *watch_mask_ptr, int index);
 
 /* The queue */
-bool command_add    (volatile sqlite3 *db, struct lkt_win *win, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr,
-                     int priority);
-bool command_addid  (volatile sqlite3 *db, struct lkt_win *win, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr);
-bool command_del    (volatile sqlite3 *db, struct lkt_win *win, char *pos_range,                  mpd_idle_flag *watch_mask_ptr);
-bool command_delid  (volatile sqlite3 *db, struct lkt_win *win, char *id,                         mpd_idle_flag *watch_mask_ptr);
-bool command_clear  (volatile sqlite3 *db,                                                        mpd_idle_flag *watch_mask_ptr);
-bool command_crop   (volatile sqlite3 *db,                                                        mpd_idle_flag *watch_mask_ptr);
-bool command_move   (volatile sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX],                      mpd_idle_flag *watch_mask_ptr);
-bool command_shuffle(volatile sqlite3 *db,                                                        mpd_idle_flag *watch_mask_ptr);
-bool command_playid (volatile sqlite3 *db, struct lkt_win *win, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr);
-bool command_dump   (volatile sqlite3 *db,                      char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr);
+bool command_add    (struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr, int priority);
+bool command_addid  (struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr);
+bool command_delid  (struct lkt_state *srv, char *id,                         mpd_idle_flag *watch_mask_ptr);
+bool command_clear  (struct lkt_state *srv,                                   mpd_idle_flag *watch_mask_ptr);
+bool command_crop   (struct lkt_state *srv,                                   mpd_idle_flag *watch_mask_ptr);
+bool command_move   (struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX],                      mpd_idle_flag *watch_mask_ptr);
+bool command_shuffle(struct lkt_state *srv,                                   mpd_idle_flag *watch_mask_ptr);
+bool command_playid (struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr);
+bool command_dump   (struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr);
 
 bool command_queue_list(struct lkt_state *srv, size_t c, char *args[LKT_MESSAGE_ARGS_MAX]);
 
 /* The playlists */
-bool command_plt_create(volatile sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr);
-bool command_plt_remove(volatile sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr);
-bool command_plt_clear (volatile sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr);
-bool command_plt_rename(volatile sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr);
-bool command_plt_export(volatile sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr);
-bool command_plt_import(volatile sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr);
-bool command_plt_add   (volatile sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr);
+bool command_plt_create(struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr);
+bool command_plt_remove(struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr);
+bool command_plt_clear (struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr);
+bool command_plt_rename(struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr);
+bool command_plt_export(struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr);
+bool command_plt_import(struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr);
+bool command_plt_add   (struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr);
 
 /* The help */
 bool command_help(struct lkt_state *srv, size_t c);
diff --git a/inc/lektor/net.h b/inc/lektor/net.h
index 18a171b19b0bed4527e9ea2371194df10ac1e0eb..c17fc4657f682d1b737b57826bd5949bb72e7e28 100644
--- a/inc/lektor/net.h
+++ b/inc/lektor/net.h
@@ -97,7 +97,7 @@ void lkt_set_continuation(struct lkt_state *srv, size_t c, int i);
 
 /* Get the mask to watch for events for a given client, to be used with the `idle` command.
  * Return a pointer to the client's mask */
-int lkt_client_get_mask(struct lkt_state *srv, size_t c);
+int  lkt_client_get_mask(struct lkt_state *srv, size_t c);
 void lkt_client_add_mask(struct lkt_state *srv, size_t c, mpd_idle_flag add);
 void lkt_client_clear_mask(struct lkt_state *srv, size_t c);
 
diff --git a/inc/lektor/reg.h b/inc/lektor/reg.h
index a584e60eedccb9df3b478fa6ad23db54393ebd1c..e0428f910835f98c7a6c7f245d36a30c26936df2 100644
--- a/inc/lektor/reg.h
+++ b/inc/lektor/reg.h
@@ -3,6 +3,7 @@
 
 struct lkt_state;
 
+#include <common/macro.h>
 #include <stdarg.h>
 
 typedef int (*reg_func)(va_list *);
@@ -46,6 +47,8 @@ struct lkt_module {
     static struct module_reg *as = reg;
 
 /* Call a function from a reg. */
+#define MOD_CALL(module, name, ...)     \
+    reg_call((module).reg, name, 1 + (GET_VA_COUNT(__VA_ARGS__)), (module).data, __VA_ARGS__)
 int reg_call(struct module_reg *reg, const char *name, int count, ...);
 
 /* Import a module, from a file (mod is a filepath) or from the __reg__ in the
diff --git a/src/commands.c b/src/commands.c
index 5b32c96822f13739745be2b82b5bbba58e135b72..6540ac09182b007f7e20798f12327910a453d43f 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -58,7 +58,7 @@ command_update(struct lkt_state *srv, size_t c, char *argv[LKT_MESSAGE_ARGS_MAX]
     RETURN_UNLESS(lkt_client_auth(srv, c, false), "Failed to authentificate user", false);
     srv->mpd_idle_events |= MPD_IDLE_UPDATE;
     srv->mpd_idle_events |= MPD_IDLE_DATABASE;
-    return ! repo_update(&srv->repo);
+    return ! repo_update(srv->repo_mod.data);
 }
 
 static inline void *
@@ -128,16 +128,14 @@ command_status(struct lkt_state *srv, size_t c)
 {
     struct lkt_message *out;
     struct lkt_queue_state queue_state;
-    struct lkt_win *win;
     int elapsed, duration, songid = 0;
     const char *play_state;
 
     RETURN_UNLESS(srv, "Invalid argument", false);
-    win = &srv->win;
     RETURN_UNLESS(database_queue_state(srv->db, &queue_state), "Can't determine playback status", false);
     database_queue_current_kara(srv->db, NULL, &songid);
-    win->get_elapsed(win, &elapsed);
-    win->get_duration(win, &duration);
+    MOD_CALL(srv->window_mod, "get_elapsed", &elapsed);
+    MOD_CALL(srv->window_mod, "get_duration", &duration);
 
     out = lkt_message_new();
     play_state = queue_state.current <= 0
@@ -164,41 +162,47 @@ command_status(struct lkt_state *srv, size_t c)
 }
 
 bool
-command_next(volatile sqlite3 *db, struct lkt_win *win, mpd_idle_flag *watch_mask_ptr)
+command_next(struct lkt_state *srv, mpd_idle_flag *watch_mask_ptr)
 {
     *watch_mask_ptr |= MPD_IDLE_PLAYER;
     char filepath[PATH_MAX];
-    return database_queue_next(db, filepath) && win->load_file(win, filepath);
+    if (!database_queue_next(srv->db, filepath))
+        return false;
+    return ! MOD_CALL(srv->window_mod, "load_file", filepath);
 }
 
 bool
-command_pause(volatile sqlite3 *db, struct lkt_win *win, mpd_idle_flag *watch_mask_ptr)
+command_pause(struct lkt_state *srv, mpd_idle_flag *watch_mask_ptr)
 {
     *watch_mask_ptr |= MPD_IDLE_PLAYER;
-    return database_queue_toggle_pause(db) && win->toggle_pause(win);
+    if (!database_queue_toggle_pause(srv->db))
+        return false;
+    return ! MOD_CALL(srv->window_mod, "toggle", 1);
 }
 
 bool
-command_previous(volatile sqlite3 *db, struct lkt_win *win, mpd_idle_flag *watch_mask_ptr)
+command_previous(struct lkt_state *srv, mpd_idle_flag *watch_mask_ptr)
 {
     *watch_mask_ptr |= MPD_IDLE_PLAYER;
     char filepath[PATH_MAX];
-    return database_queue_prev(db, filepath) && win->load_file(win, filepath);
+    if (!database_queue_prev(srv->db, filepath))
+        return false;
+    return ! MOD_CALL(srv->window_mod, "load_file", filepath);
 }
 
 static inline bool
-__play_that_file(volatile sqlite3 *db, struct lkt_win *win, int pos)
+__play_that_file(struct lkt_state *win, int pos)
 {
     char filepath[PATH_MAX];
     RETURN_UNLESS(pos, "Invalid argument", false);
-    RETURN_UNLESS(database_queue_play(db, (int) pos), "DB error", false);
-    RETURN_UNLESS(database_queue_get_current_file(db, filepath), "Can't get current kara", false);
-    RETURN_UNLESS(win->load_file(win, filepath), "Can't load file", false);
+    RETURN_UNLESS(database_queue_play(win->db, (int) pos), "DB error", false);
+    RETURN_UNLESS(database_queue_get_current_file(win->db, filepath), "Can't get current kara", false);
+    RETURN_IF(MOD_CALL(win->window_mod, "load_file", filepath), "Can't load file", false);
     return true;
 }
 
 bool
-command_play(volatile sqlite3 *db, struct lkt_win *win, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr)
+command_play(struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr)
 {
     *watch_mask_ptr |= MPD_IDLE_PLAYER;
     char *endptr, err;
@@ -211,22 +215,22 @@ command_play(volatile sqlite3 *db, struct lkt_win *win, char *args[LKT_MESSAGE_A
     }
 
     /* Do the actual job here. */
-    database_queue_stop(db);
-    RETURN_UNLESS(win->new (win), "Can't create window", false);
-    return __play_that_file(db, win, pos);
+    database_queue_stop(srv->db);
+    RETURN_UNLESS(MOD_CALL(srv->window_mod, "new", srv->queue, srv->db),
+                  "Can't create window", false);
+    return __play_that_file(srv, pos);
 }
 
 bool
-command_dump(volatile sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX],
-             mpd_idle_flag *watch_mask_ptr)
+command_dump(struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr)
 {
     RETURN_UNLESS(args[0], "Invalid argument", false);
     *watch_mask_ptr |= MPD_IDLE_PLAYLIST;
-    return database_queue_dump(db, args[0]);
+    return database_queue_dump(srv->db, args[0]);
 }
 
 bool
-command_playid(volatile sqlite3 *db, struct lkt_win *win, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr)
+command_playid(struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr)
 {
     *watch_mask_ptr |= MPD_IDLE_PLAYER;
     char *endptr, err;
@@ -239,34 +243,33 @@ command_playid(volatile sqlite3 *db, struct lkt_win *win, char *args[LKT_MESSAGE
     RETURN_IF(err, "STRTOL failed", false);
 
     /* Do the work. */
-    database_queue_stop(db);
-    RETURN_UNLESS(win->new (win), "Can't create window", false);
-    database_queue_seekid(db, (int) id, &pos);
-    return __play_that_file(db, win, pos);
+    database_queue_stop(srv->db);
+    RETURN_IF(MOD_CALL(srv->window_mod, "new", &srv->queue, srv->db),
+              "Can't create window", false);
+    database_queue_seekid(srv->db, (int) id, &pos);
+    return __play_that_file(srv, pos);
 }
 
 
 bool
-command_stop(volatile sqlite3 *db, struct lkt_win *win, mpd_idle_flag *watch_mask_ptr)
+command_stop(struct lkt_state *srv, mpd_idle_flag *watch_mask_ptr)
 {
-    RETURN_UNLESS(database_queue_stop(db), "DB error", false);
-    win->close(win);
+    RETURN_UNLESS(database_queue_stop(srv->db), "DB error", false);
+    MOD_CALL(srv->window_mod, "close", 1);
     *watch_mask_ptr |= MPD_IDLE_PLAYER;
     return true;
 }
 
 bool
-command_add(volatile sqlite3 *db, struct lkt_win *win,
-            char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr,
-            int priority)
+command_add(struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX],
+            mpd_idle_flag *watch_mask_ptr, int priority)
 {
     RETURN_UNLESS(args && args[0], "Invalid argument", false);
     *watch_mask_ptr |= MPD_IDLE_PLAYLIST;
     struct lkt_uri uri;
     int ret;        /* To be modified according to the command (insert or add) later (TODO) */
-    UNUSED(win);    /* No callbacks to the window for the moment */
     RETURN_UNLESS(lkt_uri_from(&uri, args[0]), "Failed to parse query", false);
-    ret = database_queue_add_uri(db, &uri, priority);
+    ret = database_queue_add_uri(srv->db, &uri, priority);
     lkt_uri_free(&uri);
     if (!ret)
         LOG_ERROR("COMMAND", "Failed to add with priority %d in queue", priority);
@@ -274,36 +277,35 @@ command_add(volatile sqlite3 *db, struct lkt_win *win,
 }
 
 bool
-command_addid(volatile sqlite3 *db, struct lkt_win *win,
-              char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr)
+command_addid(struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX],
+              mpd_idle_flag *watch_mask_ptr)
 {
-    UNUSED(win);
     RETURN_UNLESS(args, "Invalid argument", false);
     errno = 0;
     int i;
     struct lkt_uri uri = { .type = uri_id };
     for (i = 0; (uri.id = strtol(args[i], NULL, 0)) && ! errno; ++i)
-        errno |= database_queue_add_id(db, uri.id, 1);
+        errno |= database_queue_add_id(srv->db, uri.id, 1);
     *watch_mask_ptr |= MPD_IDLE_PLAYLIST;
     return ! errno;
 }
 
 inline bool
-command_clear(volatile sqlite3 *db, mpd_idle_flag *watch_mask_ptr)
+command_clear(struct lkt_state *srv, mpd_idle_flag *watch_mask_ptr)
 {
     *watch_mask_ptr |= MPD_IDLE_PLAYLIST;
-    return database_queue_clear(db);
+    return database_queue_clear(srv->db);
 }
 
 inline bool
-command_crop(volatile sqlite3 *db, mpd_idle_flag *watch_mask_ptr)
+command_crop(struct lkt_state *srv, mpd_idle_flag *watch_mask_ptr)
 {
     *watch_mask_ptr |= MPD_IDLE_PLAYLIST;
-    return database_queue_crop(db);
+    return database_queue_crop(srv->db);
 }
 
 bool
-command_delid(volatile sqlite3 *db, struct lkt_win *win, char *id_str, mpd_idle_flag *watch_mask_ptr)
+command_delid(struct lkt_state *srv, char *id_str, mpd_idle_flag *watch_mask_ptr)
 {
     long id;
     char *endptr = NULL, err = 0, filepath[PATH_MAX];
@@ -312,11 +314,11 @@ command_delid(volatile sqlite3 *db, struct lkt_win *win, char *id_str, mpd_idle_
     STRTOL(id, id_str, endptr, err);
     RETURN_IF(err, "STRTOL failed", false);
 
-    database_queue_current_kara(db, NULL, &uri);
+    database_queue_current_kara(srv->db, NULL, &uri);
 
     if (id == (long) uri) {
-        if (database_queue_skip_current(db, filepath)) {
-            if (!win->load_file(win, filepath)) {
+        if (database_queue_skip_current(srv->db, filepath)) {
+            if (MOD_CALL(srv->window_mod, "load_file", filepath)) {
                 LOG_ERROR("COMMAND", "Failed to skip current kara to delete id %ld", id);
                 return false;
             }
@@ -324,16 +326,16 @@ command_delid(volatile sqlite3 *db, struct lkt_win *win, char *id_str, mpd_idle_
 
         else {
             LOG_WARN("COMMAND", "Failed to skip current kara to delete id %ld, stop playback", id);
-            win->close(win);
+            MOD_CALL(srv->window_mod, "close", 1);
         }
     }
 
     *watch_mask_ptr |= MPD_IDLE_PLAYER;
-    return database_queue_del_id(db, id);
+    return database_queue_del_id(srv->db, id);
 }
 
 bool
-command_move(volatile sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr)
+command_move(struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr)
 {
     long from, to;
     char *endptr, err;
@@ -349,7 +351,7 @@ command_move(volatile sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_fl
     STRTOL(to, args[1], endptr, err);
     RETURN_IF(err, "STRTOL failed", false);
 
-    return database_queue_move(db, from, to);
+    return database_queue_move(srv->db, from, to);
 }
 
 bool
@@ -521,7 +523,6 @@ command_set_playback_option(struct lkt_state *srv, size_t c, enum lkt_playback_o
     UNUSED(c);
     long val;
     char *endptr, ret = false;
-    struct lkt_win *win = &srv->win;
 
     if (args == NULL || args[0] == NULL)
         val = 0;
@@ -552,7 +553,7 @@ command_set_playback_option(struct lkt_state *srv, size_t c, enum lkt_playback_o
     case lkt_playback_option_volume:
         ret = database_config_queue(srv->db, "volume", val);
         LOG_INFO("COMMAND", "Set volume to %ld", val);
-        ret &= win->set_volume(win, val);
+        ret &= ! MOD_CALL(srv->window_mod, "set_volume", val);
         srv->mpd_idle_events |= MPD_IDLE_MIXER;
         break;
     case lkt_playback_option_none:
@@ -567,17 +568,17 @@ command_set_playback_option(struct lkt_state *srv, size_t c, enum lkt_playback_o
 }
 
 bool
-command_set_pos(volatile sqlite3 *db, struct lkt_win *win, mpd_idle_flag *watch_mask_ptr, int index)
+command_set_pos(struct lkt_state *srv, mpd_idle_flag *watch_mask_ptr, int index)
 {
     char filepath[PATH_MAX];
     *watch_mask_ptr |= MPD_IDLE_PLAYER;
-    RETURN_UNLESS(database_queue_set_current_index(db, index), "Failed to set position in queue", false);
-    RETURN_UNLESS(database_queue_get_current_file(db, filepath), "Failed to get filename", false);
-    return win->load_file(win, filepath);
+    RETURN_UNLESS(database_queue_set_current_index(srv->db, index), "Failed to set position in queue", false);
+    RETURN_UNLESS(database_queue_get_current_file(srv->db, filepath), "Failed to get filename", false);
+    return ! MOD_CALL(srv->window_mod, "load_file", filepath);
 }
 
 bool
-command_plt_add(volatile sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr)
+command_plt_add(struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr)
 {
     RETURN_UNLESS(args && args[0], "Invalid argument", false);
 
@@ -585,7 +586,7 @@ command_plt_add(volatile sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle
     struct lkt_uri uri;
 
     if (args[1] == NULL)
-        ret = database_plt_create(db, args[0]);
+        ret = database_plt_create(srv->db, args[0]);
 
     else {
         if (!lkt_uri_from(&uri, args[1])) {
@@ -593,7 +594,7 @@ command_plt_add(volatile sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle
             goto end_plt_add_uri;
         }
 
-        else if (!database_plt_add_uri(db, args[0], &uri)) {
+        else if (!database_plt_add_uri(srv->db, args[0], &uri)) {
             LOG_ERROR("COMMAND", "Failed to add uri '%s' to playlist", args[1]);
             goto end_plt_add_uri;
         }
@@ -610,7 +611,7 @@ end_plt_add_uri:
 }
 
 bool
-command_plt_remove(volatile sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr)
+command_plt_remove(struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr)
 {
     RETURN_UNLESS(args && args[0], "Invalid argument", false);
     char *endptr, err;
@@ -618,64 +619,64 @@ command_plt_remove(volatile sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX], mpd_i
 
     if (args[1] == NULL) {
         *watch_mask_ptr |= MPD_IDLE_PLAYLIST;
-        return database_plt_remove(db, args[0]);
+        return database_plt_remove(srv->db, args[0]);
     }
 
     STRTOL(pos, args[1], endptr, err);
     RETURN_IF(err, "STRTOL failed", false);
     *watch_mask_ptr |= MPD_IDLE_PLAYLIST;
-    return database_plt_remove_pos(db, args[0], pos);
+    return database_plt_remove_pos(srv->db, args[0], pos);
 }
 
 bool
-command_plt_clear(volatile sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr)
+command_plt_clear(struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr)
 {
     RETURN_UNLESS(args && args[0], "Invalid argument", false);
-    RETURN_UNLESS(database_plt_clear(db, args[0]), "Failed to clear playlist", false);
+    RETURN_UNLESS(database_plt_clear(srv->db, args[0]), "Failed to clear playlist", false);
     *watch_mask_ptr |= MPD_IDLE_PLAYLIST;
     return true;
 }
 
 bool
-command_plt_rename(volatile sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr)
+command_plt_rename(struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr)
 {
     RETURN_UNLESS(args && args[0] && args[1], "Invalid argument", false);
-    RETURN_UNLESS(database_plt_rename(db, args[0], args[1]), "Failed to rename playlist", false);
+    RETURN_UNLESS(database_plt_rename(srv->db, args[0], args[1]), "Failed to rename playlist", false);
     *watch_mask_ptr |= MPD_IDLE_PLAYLIST;
     return true;
 }
 
 bool
-command_plt_export(volatile sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr)
+command_plt_export(struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr)
 {
     RETURN_UNLESS(args && args[0] && args[1], "Invalid argument", false);
-    RETURN_UNLESS(database_attach(db, args[0], args[1]), "Failed to attach database", false);
-    RETURN_UNLESS(database_plt_export(db, args[0]), "Failed to export playlist", false);
-    RETURN_UNLESS(database_detach(db, args[0]), "Failed to detach database", false);
+    RETURN_UNLESS(database_attach(srv->db, args[0], args[1]), "Failed to attach database", false);
+    RETURN_UNLESS(database_plt_export(srv->db, args[0]), "Failed to export playlist", false);
+    RETURN_UNLESS(database_detach(srv->db, args[0]), "Failed to detach database", false);
     LOG_INFO("COMMAND", "Exported playlist %s with path '%s'", args[0], args[1]);
     *watch_mask_ptr |= MPD_IDLE_PLAYLIST;
     return true;
 }
 
 bool
-command_plt_import(volatile sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr)
+command_plt_import(struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr)
 {
     RETURN_UNLESS(args && args[0] && args[1], "Invalid argument", false);
-    RETURN_UNLESS(database_attach(db, args[0], args[1]), "Failed to attach database", false);
-    RETURN_UNLESS(database_plt_import(db, args[0]), "Failed to import playlist", false);
-    RETURN_UNLESS(database_detach(db, args[0]), "Failed to detach playlist", false);
+    RETURN_UNLESS(database_attach(srv->db, args[0], args[1]), "Failed to attach database", false);
+    RETURN_UNLESS(database_plt_import(srv->db, args[0]), "Failed to import playlist", false);
+    RETURN_UNLESS(database_detach(srv->db, args[0]), "Failed to detach playlist", false);
     LOG_INFO("COMMAND", "Imported playlist %s with path '%s'", args[0], args[1]);
     *watch_mask_ptr |= MPD_IDLE_PLAYLIST;
     return true;
 }
 
 bool
-command_plt_add_uri(volatile sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr)
+command_plt_add_uri(struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr)
 {
     RETURN_UNLESS(args && args[0] && args[1], "Invalid argument", false);
     struct lkt_uri uri;
     RETURN_UNLESS(lkt_uri_from(&uri, args[1]), "Failed to parse uri", false);
-    bool ret = database_plt_add_uri(db, args[0], &uri);
+    bool ret = database_plt_add_uri(srv->db, args[0], &uri);
     lkt_uri_free(&uri);
     RETURN_UNLESS(ret, "Failed to add uri to plt", false);
     *watch_mask_ptr |= MPD_IDLE_PLAYLIST;
@@ -683,9 +684,9 @@ command_plt_add_uri(volatile sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX], mpd_
 }
 
 bool
-command_shuffle(volatile sqlite3 *db, mpd_idle_flag *watch_mask_ptr)
+command_shuffle(struct lkt_state *srv, mpd_idle_flag *watch_mask_ptr)
 {
-    RETURN_UNLESS(database_queue_shuffle(db), "Failed to shuffle", false);
+    RETURN_UNLESS(database_queue_shuffle(srv->db), "Failed to shuffle", false);
     *watch_mask_ptr |= MPD_IDLE_PLAYER;
     return true;
 }
diff --git a/src/main/server.c b/src/main/server.c
index 90687dd86b9c347e4ad7d36d882e6c933336d93e..3c5340738b3ce9f1f9fc24791a029566407c1cfe 100644
--- a/src/main/server.c
+++ b/src/main/server.c
@@ -122,9 +122,9 @@ normal_launch:
     reg_import("repo", &srv.repo_mod.reg, &srv.repo_mod.handle);
     free(module);
 
-    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);
+    srv.repo_mod.data = safe_zero_malloc(sizeof(struct lkt_repo));
+    MOD_CALL(srv.repo_mod, "new", &srv, srv.repo_mod.handle);
+    MOD_CALL(srv.window_mod, "new", &srv.queue, srv.db);
 
     /* Get ENV */
     /* Not working -> race condition with player module */