]> git.neil.brown.name Git - edlib.git/commitdiff
First step to plugable event loops.
authorNeilBrown <neil@brown.name>
Fri, 11 Dec 2015 06:15:32 +0000 (17:15 +1100)
committerNeilBrown <neil@brown.name>
Fri, 11 Dec 2015 06:15:32 +0000 (17:15 +1100)
attach libevent via an plugin command.

Signed-off-by: NeilBrown <neil@brown.name>
Makefile
core.h
display-ncurses.c
edlib.c
lib-libevent.c [new file with mode: 0644]

index 2256abca3538c73f651ca748d554d2a8beee17e9..57e3fe751736a78bed0ed31c24f75c1490fe2607 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@
 # May be distrubuted under terms of GPLv2 - see file:COPYING
 #
 
-LDLIBS= -levent -ldl
+LDLIBS= -ldl
 CPPFLAGS= -I.
 CFLAGS=-g -Wall -Werror -Wstrict-prototypes -Wextra -Wno-unused-parameter
 
@@ -16,7 +16,7 @@ SHOBJ = O/doc-text.o O/doc-dir.o \
        O/render-hex.o O/render-lines.o \
        O/render-format.o O/render-complete.o \
        O/lib-view.o O/lib-tile.o O/lib-popup.o O/lib-line-count.o O/lib-keymap.o \
-       O/lib-search.o O/lib-messageline.o O/lib-input.o \
+       O/lib-search.o O/lib-messageline.o O/lib-input.o O/lib-libevent.o \
        O/lang-python.o \
        O/mode-emacs.o \
        O/display-ncurses.o
@@ -28,6 +28,8 @@ INC-lang-python = -I/usr/include/python2.7
 LIBS-display-ncurses = -lncursesw
 INC-display-ncurses = -I/usr/include/ncursesw
 
+LIBS-lib-libevent = -levent
+
 SO = $(patsubst O/%.o,lib/edlib-%.so,$(SHOBJ))
 H = list.h core.h misc.h
 edlib: $(OBJ) lib/libedlib.so
diff --git a/core.h b/core.h
index a614608c17fbbfa9b15e36343dcf30e801b2d4c6..09577ef0434e3c41577f9f72183b7204999a0502 100644 (file)
--- a/core.h
+++ b/core.h
@@ -81,7 +81,6 @@ struct doc_data {
 
 struct editor {
        struct pane             root;
-       struct event_base       *base;
        struct doc              *docs;  /* document containing all documents */
        struct map              *commands;
 };
@@ -491,7 +490,7 @@ static inline int call3(char *key, struct pane *focus, int numeric, struct mark
 }
 
 static inline int call_home(struct pane *home, char *key, struct pane *focus,
-                           int numeric, struct mark *m)
+                           int numeric, struct mark *m, struct command *comm)
 {
        struct cmd_info ci = {0};
 
@@ -500,6 +499,7 @@ static inline int call_home(struct pane *home, char *key, struct pane *focus,
        ci.home = home;
        ci.numeric = numeric;
        ci.mark = m;
+       ci.comm2 = comm;
        return key_handle_focus(&ci);
 }
 
index 39fb2f2f8962f8494395578df1348f5ce02827e7..505a811dde1e7b20f5fd1fad9cf3009bed5f5bb2 100644 (file)
@@ -20,7 +20,6 @@
 #include <string.h>
 #include <locale.h>
 #include <ctype.h>
-#include <event.h>
 #include <signal.h>
 #include <sys/ioctl.h>
 
@@ -42,8 +41,6 @@ static void set_screen(SCREEN *scr)
        current_screen = scr;
 }
 
-static void input_handle(int fd, short ev, void *P);
-
 static void move_cursor(struct pane *p)
 {
        int ox;
@@ -62,13 +59,15 @@ static void move_cursor(struct pane *p)
        }
 }
 
+DEF_CMD(input_handle);
+DEF_CMD(handle_winch);
+
 DEF_CMD(nc_misc)
 {
        struct pane *p = ci->home;
-       struct editor *ed = pane2ed(p);
 
        if (strcmp(ci->str, "exit") == 0)
-               event_base_loopbreak(ed->base);
+               call3("event:deactivate", p, 0, NULL);
        else if (strcmp(ci->str, "refresh") == 0) {
                clear();
                pane_damaged(p,  DAMAGED_SIZE);
@@ -158,12 +157,10 @@ DEF_CMD(ncurses_handle)
        return 0;
 }
 
-static void handle_winch(int sig, short ev, void *null);
 static struct pane *ncurses_init(struct editor *ed)
 {
        WINDOW *w = initscr();
        struct pane *p;
-       struct event *l;
        struct display_data *dd = malloc(sizeof(*dd));
 
        start_color();
@@ -184,18 +181,15 @@ static struct pane *ncurses_init(struct editor *ed)
 
        getmaxyx(stdscr, p->h, p->w); p->h-=1;
 
-       l = event_new(ed->base, 0, EV_READ|EV_PERSIST, input_handle, p);
-       event_add(l, NULL);
-       l = event_new(ed->base, SIGWINCH, EV_SIGNAL|EV_PERSIST,
-                     handle_winch, p);
-       event_add(l, NULL);
+       call_home(p, "event:read", p, 0, NULL, &input_handle);
+       call_home(p, "event:signal", p, SIGWINCH, NULL, &handle_winch);
        pane_damaged(p, DAMAGED_SIZE);
        return pane_attach(p, "input", NULL, NULL);
 }
 
-static void handle_winch(int sig, short ev, void *vpane)
+REDEF_CMD(handle_winch)
 {
-       struct pane *p = vpane;
+       struct pane *p = ci->home;
        struct winsize size;
        ioctl(1, TIOCGWINSZ, &size);
        resize_term(size.ws_row, size.ws_col);
@@ -203,6 +197,7 @@ static void handle_winch(int sig, short ev, void *vpane)
        clear();
        pane_damaged(p, DAMAGED_SIZE);
        pane_refresh(p);
+       return 1;
 }
 
 static void ncurses_clear(struct pane *p, int attr, int x, int y, int w, int h)
@@ -373,9 +368,9 @@ static void send_mouse(MEVENT *mev, struct pane *p)
                do_send_mouse(p, x, y, "MouseMove");
 }
 
-static void input_handle(int fd, short ev, void *P)
+REDEF_CMD(input_handle)
 {
-       struct pane *p = P;
+       struct pane *p = ci->home;
        wint_t c;
        int is_keycode;
 
@@ -388,6 +383,7 @@ static void input_handle(int fd, short ev, void *P)
                        send_key(is_keycode, c, p);
        }
        pane_refresh(p);
+       return 1;
 }
 
 DEF_CMD(display_ncurses)
diff --git a/edlib.c b/edlib.c
index c50cb7344c6b057cf40d163903d24661196c96d0..050166a86ee508a74d408fb4d0e0a95e16c1a955 100644 (file)
--- a/edlib.c
+++ b/edlib.c
@@ -10,7 +10,6 @@
 #include <stdlib.h>
 #include <locale.h>
 #include <fcntl.h>
-#include <event.h>
 #include <wchar.h>
 #include <dirent.h>
 #include <string.h>
@@ -52,7 +51,6 @@ DEF_CMD(take_pane)
 
 int main(int argc, char *argv[])
 {
-       struct event_base *base;
        struct pane *root, *global;
        struct pane *b, *p= NULL;
        struct cmd_info ci = {0};
@@ -63,13 +61,12 @@ int main(int argc, char *argv[])
        ed = pane2ed(vroot);
        setlocale(LC_ALL, "");
        setlocale(LC_CTYPE, "enUS.UTF-8");
-       base = event_base_new();
-       event_base_priority_init(base, 2);
-       ed->base = base;
 
        editor_load_module(ed, "lib-line-count");
        editor_load_module(ed, "lib-search");
+       editor_load_module(ed, "lib-libevent");
        editor_load_module(ed, "display-ncurses");
+       call3("libevent:activate", vroot, 0, NULL);
        ci.home = ci.focus = vroot;
        ci.key = "display-ncurses";
        cr.c = take_pane;
@@ -96,7 +93,7 @@ int main(int argc, char *argv[])
                key_handle(&ci);
 
                pane_refresh(&ed->root);
-               event_base_dispatch(base);
+               call3("event:run", vroot, 0, NULL);
        }
        pane_close(&ed->root);
        exit(0);
diff --git a/lib-libevent.c b/lib-libevent.c
new file mode 100644 (file)
index 0000000..c1fac00
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright Neil Brown ©2015 <neil@brown.name>
+ * May be distributed under terms of GPLv2 - see file:COPYING
+ *
+ * libevent support for edlib.
+ *
+ * Register command "libevent:activate".
+ * When that is called, register:
+ *   "event:read"
+ *   "event:signal"
+ *   "event:run"
+ *   "event:deactivate"
+ *
+ * When "event:deactivate" is called, cause event:run to abort.
+ */
+
+
+#include <stdlib.h>
+#include <event.h>
+#include "core.h"
+
+static struct event_base *base;
+static struct list_head event_list;
+
+struct evt {
+       struct event *l;
+       struct pane *home;
+       struct command *comm;
+       struct list_head lst;
+};
+
+static void call_event(int thing, short sev, void *evv)
+{
+       struct evt *ev = evv;
+       struct cmd_info ci = {0};
+
+       ci.key = "callback:event";
+       ci.home = ci.focus = ev->home;
+       ci.comm = ev->comm;
+       ci.numeric = thing;
+       ev->comm->func(&ci);
+}
+
+DEF_CMD(libevent_read)
+{
+       struct evt *ev = malloc(sizeof(*ev));
+       ev->l = event_new(base, ci->numeric, EV_READ|EV_PERSIST,
+                         call_event, ev);
+       ev->home = ci->focus;
+       ev->comm = ci->comm2;
+       list_add(&ev->lst, &event_list);
+       event_add(ev->l, NULL);
+       return 1;
+}
+
+DEF_CMD(libevent_signal)
+{
+       struct evt *ev = malloc(sizeof(*ev));
+       ev->l = event_new(base, ci->numeric, EV_SIGNAL|EV_PERSIST,
+                         call_event, ev);
+       ev->home = ci->focus;
+       ev->comm = ci->comm2;
+       list_add(&ev->lst, &event_list);
+       event_add(ev->l, NULL);
+       return 1;
+}
+
+DEF_CMD(libevent_run)
+{
+       struct event_base *b = base;
+       event_base_dispatch(b);
+       while (!list_empty(&event_list)) {
+               struct evt *ev = list_first_entry(&event_list, struct evt, lst);
+               list_del(&ev->lst);
+               event_del(ev->l);
+               event_free(ev->l);
+       }
+       event_base_free(b);
+       return 1;
+}
+
+DEF_CMD(libevent_deactivate)
+{
+       event_base_loopbreak(base);
+       base = NULL;
+       return 1;
+}
+
+DEF_CMD(libevent_activate)
+{
+       if (base)
+               return 1;
+       base = event_base_new();
+       INIT_LIST_HEAD(&event_list);
+
+       call_comm("global-set-command", ci->focus, 0, NULL, "event:read",
+                 0, &libevent_read);
+       call_comm("global-set-command", ci->focus, 0, NULL, "event:signal",
+                 0, &libevent_signal);
+       call_comm("global-set-command", ci->focus, 0, NULL, "event:run",
+                 0, &libevent_run);
+       call_comm("global-set-command", ci->focus, 0, NULL, "event:deactivate",
+                 0, &libevent_deactivate);
+
+       return 1;
+}
+
+void edlib_init(struct editor *ed)
+{
+       call_comm("global-set-command", &ed->root, 0, NULL, "libevent:activate",
+                 0, &libevent_activate);
+}