From: NeilBrown Date: Thu, 10 Dec 2015 06:00:28 +0000 (+1100) Subject: Add infrastructure to allow panes to get notifications from other panes. X-Git-Tag: lca2016~70 X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=0f40bcce783354a927ae28193a42d73722d20389;p=edlib.git Add infrastructure to allow panes to get notifications from other panes. Signed-off-by: NeilBrown --- diff --git a/core-pane.c b/core-pane.c index a6df9507..9c762dcd 100644 --- a/core-pane.c +++ b/core-pane.c @@ -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 4e3c8ce4..393343c6 100644 --- 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,