]> git.neil.brown.name Git - edlib.git/commitdiff
Add infrastructure to allow panes to get notifications from other panes.
authorNeilBrown <neil@brown.name>
Thu, 10 Dec 2015 06:00:28 +0000 (17:00 +1100)
committerNeilBrown <neil@brown.name>
Thu, 10 Dec 2015 06:47:33 +0000 (17:47 +1100)
Signed-off-by: NeilBrown <neil@brown.name>
core-pane.c
core.h

index a6df95074b14acb40a82cc9891c26d1630c66946..9c762dcd811583d1037ec79a4852a23cda528c25 100644 (file)
@@ -43,6 +43,8 @@ void pane_init(struct pane *p, struct pane *par, struct list_head *here)
        else
                INIT_LIST_HEAD(&p->siblings);
        INIT_LIST_HEAD(&p->children);
+       INIT_LIST_HEAD(&p->notifiers);
+       INIT_LIST_HEAD(&p->notifiees);
        p->x = p->y = p->z = 0;
        p->cx = p->cy = -1;
        p->h = p->w = 0;
@@ -155,6 +157,45 @@ void pane_refresh(struct pane *p)
        __pane_refresh(&ci);
 }
 
+void pane_add_notify(struct pane *target, struct pane *source, char *msg)
+{
+       struct notifier *n = malloc(sizeof(*n));
+
+       n->notifiee = target;
+       n->notification = strdup(msg);
+       list_add(&n->notifier_link, &source->notifiees);
+       list_add(&n->notifiee_link, &target->notifiers);
+}
+
+static void pane_drop_notifiers(struct pane *p)
+{
+       while (!list_empty(&p->notifiers)) {
+               struct notifier *n = list_first_entry(&p->notifiers,
+                                                     struct notifier,
+                                                     notifiee_link);
+               list_del_init(&n->notifiee_link);
+               list_del_init(&n->notifier_link);
+               free(n->notification);
+               free(n);
+       }
+}
+
+static void pane_notify_close(struct pane *p)
+{
+       while (!list_empty(&p->notifiees)) {
+               struct notifier *n = list_first_entry(&p->notifiers,
+                                                     struct notifier,
+                                                     notifiee_link);
+               list_del_init(&n->notifiee_link);
+               list_del_init(&n->notifier_link);
+               if (strcmp(n->notification, "Notify:Close") == 0)
+                       comm_call_pane(n->notifiee, n->notification, p,
+                                      0, NULL, NULL, 0);
+               free(n->notification);
+               free(n);
+       }
+}
+
 void pane_close(struct pane *p)
 {
        struct pane *c;
@@ -169,6 +210,8 @@ void pane_close(struct pane *p)
                p->parent->focus = NULL;
        }
        list_del_init(&p->siblings);
+       pane_drop_notifiers(p);
+       pane_notify_close(p);
        if (p->handle) {
                struct cmd_info ci = {0};
 
diff --git a/core.h b/core.h
index 4e3c8ce4f7d948500cab93c89b32647c2fc893ae..393343c69a1c192d29021c16566a0a5f54090e70 100644 (file)
--- a/core.h
+++ b/core.h
@@ -55,12 +55,20 @@ struct pane {
        void                    *data;
        struct mark             *pointer;
        struct attrset          *attrs;
+       struct list_head        notifiers, notifiees;
 };
 
 struct command {
        int     (*func)(const struct cmd_info *ci);
 };
 
+struct notifier {
+       struct pane             *notifiee;
+       char                    *notification;
+       struct list_head        notifier_link, notifiee_link;
+};
+void pane_add_notify(struct pane *target, struct pane *source, char *msg);
+
 /* this is ->data for a document pane.  Only core-doc and
  * individual document handlers can know about this.
  */
@@ -548,6 +556,25 @@ static inline int comm_call(struct command *comm, char *key, struct pane *focus,
        return comm->func(&ci);
 }
 
+static inline int comm_call_pane(struct pane *home, char *key, struct pane *focus,
+                                int numeric, struct mark *m, char *str, int extra)
+{
+       struct cmd_info ci = {0};
+       struct command *comm = home->handle;
+
+       if (!comm)
+               return -1;
+       ci.home = home;
+       ci.key = key;
+       ci.focus = focus;
+       ci.numeric = numeric;
+       ci.mark = m;
+       ci.str = str;
+       ci.extra = extra;
+       ci.comm = comm;
+       return comm->func(&ci);
+}
+
 static inline int comm_call7(struct command *comm, char *key,
                             struct pane *focus,
                             int numeric, struct mark *m, char *str,