2 * Copyright Neil Brown ©2015-2023 <neil@brown.name>
3 * May be distributed under terms of GPLv2 - see file:COPYING
5 * Core elements include:
26 extern char edlib_version[];
28 #define VERSION "unreleased"
31 #define VERS_DATE "unreleased"
41 extern MEMPOOL_DECL(pane);
43 #ifndef PRIVATE_DOC_REF
49 struct generic_doc_ref {
54 void LOG(char *fmt, ...);
57 /* The 'editor' contains (by reference) everything else.
58 * This captures and documents the global states, and allows
59 * multiple "editors" in the one process, should that be valuable.
61 * Each document and contains a reference to the editor which is the root of the
67 int (*func)(const struct cmd_info *ci safe);
68 unsigned int refcnt; /* only if 'free' is not NULL */
69 unsigned int closed_ok:1;
70 void (*free)(struct command *c safe);
80 /* following errors are soft and don't create exceptions */
85 static inline struct command *safe command_get(struct command * safe c)
94 static inline void command_put(struct command *c)
96 if (c && c->free && --c->refcnt == 0)
101 struct pane *notifiee safe;
102 char *notification safe;
103 struct list_head notifier_link, notifiee_link;
106 void pane_add_notify(struct pane *target safe, struct pane *source safe,
107 const char *msg safe);
108 int do_pane_notify(struct pane *home, const char *notification safe,
110 int num, struct mark *m, const char *str,
111 int num2, struct mark *m2, const char *str2,
112 struct command *comm2);
113 void pane_drop_notifiers(struct pane *p safe, char *notification);
115 struct pane *editor_new(const char *comm_name);
116 void * safe memsave(struct pane *p safe, const char *buf, int len);
117 char *strsave(struct pane *p safe, const char *buf);
118 char *strnsave(struct pane *p safe, const char *buf, int len);
119 char * safe do_strconcat(struct pane *p, const char *s1 safe, ...);
120 #define strconcat(p, ...) do_strconcat(p, __VA_ARGS__, NULL)
121 bool edlib_testing(struct pane *p safe);
123 /* This is declared here so sparse knows it is global */
124 void edlib_init(struct pane *ed safe);
127 struct hlist_head marks;
128 struct tlist_head points;
130 struct tlist_head head;
132 } /* safe iff nviews > 0 */ *views;
134 struct mark *recent_points[8];
135 void (*refcnt)(struct mark *m safe, int cnt);
141 void doc_free(struct doc *d safe, struct pane *root safe);
142 extern struct map *doc_default_cmd safe;
144 #define CHAR_RET(_c) ((_c & 0x1FFFFF) | 0x200000)
146 #define is_eol(c) ({int _c = c; _c == '\n' || _c == '\v' || _c == '\f'; })
148 /* Points and Marks */
156 GRP_HEAD = 0, // tlist_head list head
157 GRP_MARK = 1, // tlist_head in mark.view
158 GRP_LIST = 2, // tlist_head in point.lists
161 #ifndef MARK_DATA_PTR
162 #define MARK_DATA_PTR void
166 struct hlist_node all;
167 struct tlist_head view;
168 struct attrset *attrs;
172 MARK_DATA_PTR *mdata;
173 void *mtype; /* can be used to validate
175 struct pane *owner safe; /* document pane which
179 #define MARK_FLAG_WATCHED 1
181 static inline bool mark_valid(struct mark *m)
183 /* When marks are freed, most fields including ->attrs are
184 * set to all 1's. The memory isn't released until an
187 return m && m->attrs != (void*)~0UL;
190 /* A point uses this for the mdata */
193 struct mark *pt safe;
194 struct tlist_head lists[];
197 struct mark *safe mark_dup(struct mark *m safe);
198 struct mark *safe mark_dup_view(struct mark *m safe);
199 void mark_free(struct mark *m);
200 void mark_watch(struct mark *m);
202 struct mark *mark_first(struct doc *d safe);
203 struct mark *mark_next(struct mark *m safe);
204 struct mark *mark_prev(struct mark *m safe);
205 void mark_reset(struct pane *p safe, struct mark *m safe, int end);
206 void mark_to_end(struct pane *p safe, struct mark *m safe, int end);
207 void doc_check_consistent(struct doc *d safe);
208 void mark_to_mark(struct mark *m safe, struct mark *target safe);
209 void mark_to_mark_noref(struct mark *m safe, struct mark *target safe);
210 wint_t do_doc_step(struct pane *p safe, struct mark *m,
211 int forward, int move);
212 void mark_step(struct mark *m safe, int forward);
213 void mark_step_sharesref(struct mark *m safe, int forward);
214 bool marks_validate(struct mark *m1 safe, struct mark *m2 safe);
216 static inline int mark_same(struct mark *m1 safe, struct mark *m2 safe)
218 struct generic_doc_ref *r1 = (void*)&m1->ref;
219 struct generic_doc_ref *r2 = (void*)&m2->ref;
221 /* Compile-time check that size of doc_ref is correct */
224 case (sizeof(struct doc_ref) == sizeof(struct generic_doc_ref)):
228 return r1->p == r2->p && r1->i == r2->i;
231 struct mark *mark_at_point(struct pane *p safe, struct mark *pm, int view);
232 struct mark *vmark_next(struct mark *m safe);
233 struct mark *vmark_prev(struct mark *m safe);
234 struct mark *vmark_matching(struct mark *m safe);
235 struct mark *vmark_first(struct pane *p safe, int view,
236 struct pane *owner safe);
237 struct mark *vmark_last(struct pane *p safe, int view, struct pane *owner safe);
238 struct mark *vmark_at_or_before(struct pane *p safe, struct mark *m safe,
239 int view, struct pane *owner);
240 struct mark *vmark_new(struct pane *p safe, int view, struct pane *owner);
241 static inline struct mark *mark_new(struct pane *p safe)
243 return vmark_new(p, MARK_UNGROUPED, NULL);
245 static inline struct mark *point_new(struct pane *p safe)
247 return vmark_new(p, MARK_POINT, NULL);
249 void mark_clip(struct mark *m safe, struct mark *start, struct mark *end,
251 void marks_clip(struct pane *p safe, struct mark *start, struct mark *end,
252 int view, struct pane *owner, bool tostart);
254 static inline int mark_ordered_or_same(struct mark *m1 safe,
255 struct mark *m2 safe)
257 return m1->seq < m2->seq || mark_same(m1, m2);
260 static inline int mark_ordered_not_same(struct mark *m1 safe,
261 struct mark *m2 safe)
263 return m1->seq < m2->seq && !mark_same(m1, m2);
266 static inline struct attrset **safe mark_attr(struct mark *m safe)
272 char *attr_find(struct attrset *set, const char *key safe);
273 bool attr_del(struct attrset **setp safe, const char *key safe);
274 void attr_del_all(struct attrset **setp safe, const char *key safe,
276 int attr_set_str(struct attrset **setp safe,
277 const char *key safe, const char *val);
278 int attr_set_str_key(struct attrset **setp safe, const char *key safe,
279 const char *val, int keynum);
280 char *attr_get_str(struct attrset *setp, const char *key safe, int keynum);
281 const char *attr_get_next_key(struct attrset *set, const char *key safe,
283 const char **valp safe);
284 int attr_find_int(struct attrset *set, const char *key safe);
285 int attr_set_int(struct attrset **setp safe, const char *key safe, int val);
286 void attr_trim(struct attrset **setp safe, int nkey);
287 struct attrset *attr_copy_tail(struct attrset *set, int nkey);
288 struct attrset *attr_copy(struct attrset *set);
289 struct attrset *attr_collect(struct attrset *set, unsigned int pos, int prefix);
290 void attr_free(struct attrset **setp safe);
298 #define CMD(_name) { \
299 .func = _name ## _func , \
305 #define CMD_CLOSED(_name) { \
306 .func = _name ## _func , \
312 #define CB(_name) {.func = _name ## _func , \
319 #define DEF_CMD(_name) \
320 static int _name ## _func(const struct cmd_info *ci safe); \
321 static struct command _name = CMD(_name); \
322 static int _name ## _func(const struct cmd_info *ci safe)
323 #define DEF_CMD_CLOSED(_name) \
324 static int _name ## _func(const struct cmd_info *ci safe); \
325 static struct command _name = CMD_CLOSED(_name); \
326 static int _name ## _func(const struct cmd_info *ci safe)
327 #define REDEF_CMD(_name) \
328 static int _name ## _func(const struct cmd_info *ci safe)
329 #define DEF_EXTERN_CMD(_name) \
330 static int _name ## _func(const struct cmd_info *ci safe); \
331 struct command _name = CMD(_name); \
332 static int _name ## _func(const struct cmd_info *ci safe)
333 #define DECL_EXTERN_CMD(_name) \
334 extern struct command _name;
335 #define DEF_CB(_name) \
336 static int _name ## _func(const struct cmd_info *ci safe); \
337 static struct command _name = CB(_name); \
338 static int _name ## _func(const struct cmd_info *ci safe)
339 #define REDEF_CB(_name) \
340 static int _name ## _func(const struct cmd_info *ci safe)
342 #define DEF_LOOKUP_CMD(_name, _map) \
343 static struct lookup_cmd _name = { \
344 .c.func = key_lookup_cmd_func, \
352 DECL_EXTERN_CMD(edlib_noop);
354 int key_lookup_cmd_func(const struct cmd_info *ci safe);
361 int key_pfx_func(const struct cmd_info *ci safe);
363 #define DEF_PFX_CMD(_name, _pfx) \
364 static struct pfx_cmd _name = { \
365 .c.func = key_pfx_func, \
369 .c.name = "prefix" #_pfx, \
373 #define ARRAY_SIZE(ra) (sizeof(ra) / sizeof(ra[0]))
375 /* Each event (above) is accompanied by a cmd_info structure.
376 * 'key' and 'home' are always present, others only if relevant.
377 * Num is present for 'key' and 'move'. INT_MAX/2 means no number was
378 * requested so is usually treated like '1'. Negative numbers are quite
380 * x,y are present for mouse events
381 * 'str' is inserted by 'replace' and sought by 'search'
382 * 'mark' is moved by 'move' and 'replace' deletes between point and mark.
385 const char *key safe;
386 struct pane *home safe, *focus safe;
388 int x,y; /* relative to focus */
389 const char *str, *str2;
390 struct mark *mark, *mark2;
391 struct command *comm safe;
392 struct command *comm2;
394 /* An array of 2 hashes, one for the prefix of the key - all
395 * chars to first '-' or ':'. One for the whole key.
400 #define NO_NUMERIC (INT_MAX/2)
401 #define RPT_NUM(ci) ((ci)->num == NO_NUMERIC ? 1 : \
402 (ci)->num == NO_NUMERIC + 1 ? 4 : \
403 (ci)->num == -NO_NUMERIC ? -1 : (ci)->num)
405 struct map *safe key_alloc(void);
406 void key_free(struct map *m safe);
407 int key_handle(const struct cmd_info *ci safe);
408 int key_lookup(struct map *m safe, const struct cmd_info *ci safe);
409 int key_lookup_prefix(struct map *m safe, const struct cmd_info *ci safe);
410 struct command *key_lookup_cmd(struct map *m safe, const char *c safe);
411 void key_add(struct map *map safe, const char *k safe, struct command *comm);
412 void key_add_range(struct map *map safe,
413 const char *first safe, const char *last safe,
414 struct command *comm);
415 #define key_add_prefix(map, prefix, comm) \
416 key_add_range(map, prefix, prefix "\xFF\xFF\xFF\xFF", comm)
417 void key_add_chain(struct map *map safe, struct map *chain);
419 static inline const char *safe ksuffix(const struct cmd_info *ci safe,
420 const char *prefix safe)
422 int l = strlen(prefix);
423 if (strncmp(ci->key, prefix, l) == 0)
428 /* DAMAGED_SIZE propagates down.
429 * If any flag is set on children, DAMAGED_CHILD is set.
431 #define BIT(n) (1 << (n))
433 DAMAGED_SIZE = BIT(0), /* Size has changed */
434 DAMAGED_SIZE_CHILD = BIT(1), /* a child has changed size */
435 DAMAGED_VIEW = BIT(2), /* content has moved */
436 DAMAGED_VIEW_CHILD = BIT(3), /* a child needs to adjust the view */
438 DAMAGED_REFRESH = BIT(4), /* Content has changed */
439 DAMAGED_CHILD = BIT(6), /* CONTENT in child */
441 DAMAGED_POSTORDER = BIT(7), /* Pane wants to be called again */
442 DAMAGED_POSTORDER_CHILD = BIT(8), /* Child pane wants to be called again */
444 DAMAGED_CLOSED = BIT(15),
445 DAMAGED_DEAD = BIT(14), /* Fully closed, but not freed yet */
446 DAMAGED_NOT_HANDLED = BIT(13), /* A for() loop is processing
447 * children, and this one
448 * hasn't been handled yet.
450 DAMAGED_DEBUG = BIT(12),
451 DAMAGED_NOINIT = BIT(11), /* Closing before pane_register
452 * had a chance to complete.
455 #define DAMAGED_NEED_CALL (DAMAGED_SIZE | DAMAGED_REFRESH)
457 struct xy {short x,y;};
458 struct pane * do_pane_register(struct pane *parent safe, short z,
459 struct command *handle safe, void *data,
461 #ifdef PANE_DATA_TYPE
462 #define pane_register(p,z,h) do_pane_register(p,z,h,NULL, sizeof(PANE_DATA_TYPE))
464 #ifdef PANE_DATA_PTR_TYPE
465 static inline struct pane *pane_register(struct pane *parent safe, short z,
466 struct command *handle safe,
467 PANE_DATA_PTR_TYPE data)
469 return do_pane_register(parent, z, handle, (void*)data, sizeof(data));
472 #ifdef PANE_DATA_VOID
473 #define pane_register(p,z,h) do_pane_register(p,z,h,NULL, 0)
476 #ifdef PANE_DATA_TYPE_2
477 #define pane_register_2(p,z,h) do_pane_register(p,z,h,NULL, sizeof(PANE_DATA_TYPE_2))
479 #ifdef PANE_DATA_PTR_TYPE_2
480 static inline struct pane *pane_register_2(struct pane *parent safe, short z,
481 struct command *handle safe,
482 PANE_DATA_PTR_TYPE_2 data)
484 return do_pane_register(parent, z, handle, (void*)data, sizeof(data));
487 #ifdef PANE_DATA_VOID_2
488 #define pane_register_2(p,z,h) do_pane_register(p,z,h,NULL, 0)
491 #ifdef PANE_DATA_TYPE_3
492 #define pane_register_3(p,z,h) do_pane_register(p,z,h,NULL, sizeof(PANE_DATA_TYPE_3))
494 #ifdef PANE_DATA_PTR_TYPE_3
495 static inline struct pane *pane_register_3(struct pane *parent safe, short z,
496 struct command *handle safe,
497 PANE_DATA_PTR_TYPE_3 data)
499 return do_pane_register(parent, z, handle, (void*)data, sizeof(data));
502 #ifdef PANE_DATA_VOID_3
503 #define pane_register_3(p,z,h) do_pane_register(p,z,h,NULL, 0)
506 void pane_update_handle(struct pane *p safe, struct command *handle safe);
510 struct pane *do_doc_register(struct pane *parent safe,
511 struct command *handle safe,
512 unsigned short data_size);
513 #define doc_register(p,h) do_doc_register(p, h, sizeof(DOC_DATA_TYPE))
516 void pane_reparent(struct pane *p safe, struct pane *newparent safe);
517 void pane_move_after(struct pane *p safe, struct pane *after);
518 void pane_subsume(struct pane *p safe, struct pane *parent safe);
519 void pane_close(struct pane *p safe);
520 bool pane_resize(struct pane *p safe, int x, int y, int w, int h);
521 void pane_take_focus(struct pane *p);
522 bool do_pane_has_focus(struct pane *p, struct pane *root);
523 #define pane_has_focus(...) VFUNC(pane_has_focus, __VA_ARGS__)
524 #define pane_has_focus1(p) do_pane_has_focus(p, NULL)
525 #define pane_has_focus2(p,r) do_pane_has_focus(p, r)
526 void pane_damaged(struct pane *p, int type);
527 void pane_clone_children(struct pane *from, struct pane *to);
528 struct pane *pane_my_child(struct pane *p, struct pane *c);
530 char *pane_attr_get(struct pane *p, const char *key safe);
531 char *pane_mark_attr(struct pane *p safe, struct mark *m safe,
532 const char *key safe);
533 struct xy pane_mapxy(struct pane *orig safe, struct pane *target safe,
534 short x, short y, bool clip);
536 struct xy pane_scale(struct pane *p safe);
538 static inline int pane_attr_get_int(struct pane *p safe, const char *key safe,
541 char *c = pane_attr_get(p, key);
546 rv = strtol(c, &end, 10);
547 if (end == c || !end || (*end && *end != ' '))
551 void pane_free(struct pane *p safe);
552 struct pane * safe pane_leaf(struct pane *p safe);
556 static inline wint_t doc_next(struct pane *p safe, struct mark *m)
558 return do_doc_step(p, m, 1, 1);
561 static inline wint_t doc_prev(struct pane *p safe, struct mark *m)
563 return do_doc_step(p, m, 0, 1);
566 static inline wint_t doc_following(struct pane *p safe, struct mark *m)
568 return do_doc_step(p, m, 1, 0);
571 static inline wint_t doc_prior(struct pane *p safe, struct mark *m)
573 return do_doc_step(p, m, 0, 0);
576 static inline wint_t doc_move(struct pane *p safe, struct mark *m, int n)
578 /* Move 'n' chars (backwards if negative) returning last character
582 while (n < 0 && (wc = doc_prev(p, m)) != WEOF)
584 while (n > 0 && (wc = doc_next(p, m)) != WEOF)
589 static inline wint_t doc_pending(struct pane *p safe, struct mark *m, int n)
591 /* n must be <0 or >0. Return the next char in that direction */
593 return doc_following(p, m);
595 return doc_prior(p, m);
599 #if defined(DOC_NEXT)
601 static inline wint_t DOC_NEXT_DECL(struct pane *p safe, struct mark *m safe, struct doc_ref *r safe, bool byte);
602 static inline wint_t DOC_PREV_DECL(struct pane *p safe, struct mark *m safe, struct doc_ref *r safe, bool byte);
604 static inline wint_t DOC_NEXT(struct pane *p safe, struct mark *m safe, struct doc_ref *r safe, bool byte);
605 static inline wint_t DOC_PREV(struct pane *p safe, struct mark *m safe, struct doc_ref *r safe, bool byte);
607 static inline int do_char_byte(const struct cmd_info *ci safe)
609 struct mark *m = ci->mark;
610 struct mark *end = ci->mark2;
611 struct pane *p = ci->home;
614 int forward = steps > 0;
616 int byte = strcmp(ci->key, "doc:byte") == 0;
620 if (end && mark_same(m, end))
622 if (end && (end->seq < m->seq) != (steps < 0))
623 /* Can never cross 'end' */
625 while (steps && ret != CHAR_RET(WEOF) && (!end || !mark_same(m, end))) {
627 mark_step_sharesref(m, forward);
629 mark_step(m, forward);
632 ret = DOC_NEXT(p, m, &m->ref, byte);
634 ret = DOC_PREV(p, m, &m->ref, byte);
635 steps -= forward*2 - 1;
638 return 1 + (forward ? ci->num - steps : steps - ci->num);
639 if (ret == WEOF || ci->num2 == 0)
640 return CHAR_RET(ret);
641 if (ci->num && (ci->num2 < 0) == forward)
642 return CHAR_RET(ret);
643 /* Want the 'next' char */
646 ret = DOC_NEXT(p, m, &r, byte);
648 ret = DOC_PREV(p, m, &r, byte);
649 return CHAR_RET(ret);
660 struct command *comm;
671 struct pane *do_call_pane(enum target_type type, struct pane *home,
672 struct command *comm2a,
673 const char *key safe, struct pane *focus safe,
674 int num, struct mark *m, const char *str,
675 int num2, struct mark *m2, const char *str2,
676 int x, int y, struct command *comm2b);
677 struct mark *do_call_mark(enum target_type type, struct pane *home,
678 struct command *comm2a,
679 const char *key safe, struct pane *focus safe,
680 int num, struct mark *m, const char *str,
681 int num2, struct mark *m2, const char *str2,
682 int x, int y, struct command *comm2b);
683 struct mark *do_call_mark2(enum target_type type, struct pane *home,
684 struct command *comm2a,
685 const char *key safe, struct pane *focus safe,
686 int num, struct mark *m, const char *str,
687 int num2, struct mark *m2, const char *str2,
688 int x, int y, struct command *comm2b);
689 struct command *do_call_comm(enum target_type type, struct pane *home,
690 struct command *comm2a,
691 const char *key safe, struct pane *focus safe,
692 int num, struct mark *m, const char *str,
693 int num2, struct mark *m2, const char *str2,
694 int x, int y, struct command *comm2b);
695 struct call_return do_call_all(enum target_type type, struct pane *home,
696 struct command *comm2a,
697 const char *key safe, struct pane *focus safe,
698 int num, struct mark *m, const char *str,
699 int num2, struct mark *m2, const char *str2,
700 int x, int y, struct command *comm2b);
701 char *do_call_str(enum target_type type, struct pane *home,
702 struct command *comm2a,
703 const char *key safe, struct pane *focus safe,
704 int num, struct mark *m, const char *str,
705 int num2, struct mark *m2, const char *str2,
706 int x, int y, struct command *comm2b);
707 struct call_return do_call_bytes(enum target_type type, struct pane *home,
708 struct command *comm2a,
709 const char *key safe, struct pane *focus safe,
710 int num, struct mark *m, const char *str,
711 int num2, struct mark *m2, const char *str2,
712 int x, int y, struct command *comm2b);
713 char *do_call_strsave(enum target_type type, struct pane *home,
714 struct command *comm2a,
715 const char *key safe, struct pane *focus safe,
716 int num, struct mark *m, const char *str,
717 int num2, struct mark *m2, const char *str2,
718 int x, int y, struct command *comm2b);
720 #define T_focus(_p, _c) _p
721 #define T_home(_p, _c) _p
722 #define T_pane(_p, _c) _p
723 #define T_comm(_p, _c) _c
725 #define CH(f,a,b) f(a,b)
727 #define _doCALL(...) VFUNC(CALL, __VA_ARGS__)
728 #define CALL15(ret, t_type, target, key, comm2a, focus, num, mark, str, \
729 num2, mark2, str2, x, y, comm2) \
730 do_call_##ret(TYPE_##t_type, CH(T_##t_type, target, comm2a), CH(T_##t_type,comm2,target), \
731 key, focus, num, mark, str, num2, mark2, str2, x, y, comm2)
732 #define CALL14(ret, t_type, target, key, comm2a, focus, num, mark, str, num2, mark2, str2, x, y) \
733 do_call_##ret(TYPE_##t_type, CH(T_##t_type, target, comm2a), CH(T_##t_type,comm2a,target), \
734 key, focus, num, mark, str, num2, mark2, str2, x, y, NULL)
735 #define CALL12(ret, t_type, target, key, comm2a, focus, num, mark, str, num2, mark2, str2) \
736 do_call_##ret(TYPE_##t_type, CH(T_##t_type, target, comm2a), CH(T_##t_type,comm2a,target), \
737 key, focus, num, mark, str, num2, mark2, str2, 0, 0, NULL)
738 #define CALL11(ret, t_type, target, key, comm2a, focus, num, mark, str, num2, mark2) \
739 do_call_##ret(TYPE_##t_type, CH(T_##t_type, target, comm2a), CH(T_##t_type,comm2a,target), \
740 key, focus, num, mark, str, num2, mark2, NULL, 0, 0, NULL)
741 #define CALL10(ret, t_type, target, key, comm2a, focus, num, mark, str, num2) \
742 do_call_##ret(TYPE_##t_type, CH(T_##t_type, target, comm2a), CH(T_##t_type,comm2a,target), \
743 key, focus, num, mark, str, num2, NULL, NULL, 0, 0, NULL)
744 #define CALL9(ret, t_type, target, key, comm2a, focus, num, mark, str) \
745 do_call_##ret(TYPE_##t_type, CH(T_##t_type, target, comm2a), CH(T_##t_type,comm2a,target), \
746 key, focus, num, mark, str, 0, NULL, NULL, 0, 0, NULL)
747 #define CALL8(ret, t_type, target, key, comm2a, focus, num, mark) \
748 do_call_##ret(TYPE_##t_type, CH(T_##t_type, target, comm2a), CH(T_##t_type,comm2a,target), \
749 key, focus, num, mark, NULL, 0, NULL, NULL, 0, 0, NULL)
750 #define CALL7(ret, t_type, target, key, comm2a, focus, num) \
751 do_call_##ret(TYPE_##t_type, CH(T_##t_type, target, comm2a), CH(T_##t_type,comm2a,target), \
752 key, focus, num, NULL, NULL, 0, NULL, NULL, 0, 0, NULL)
753 #define CALL6(ret, t_type, target, key, comm2a, focus) \
754 do_call_##ret(TYPE_##t_type, CH(T_##t_type,target, comm2a), CH(T_##t_type,comm2a,target), \
755 key, focus, 0, NULL, NULL, 0, NULL, NULL, 0, 0, NULL)
757 #define CALL(ret, t_type, target, key, ...) _doCALL(ret, t_type, target, key, NULL, __VA_ARGS__)
759 #define call(key, _focus, ...) CALL(val, focus, _focus, key, _focus, ##__VA_ARGS__)
760 /* comm_call() is only for callbacks
761 * home_comm_call must be used if the focus must be closed already.
763 #define comm_call(_comm, key, ...) CALL(val, comm, _comm, key, ##__VA_ARGS__)
764 #define home_comm_call(_home, _comm, key, ...) _doCALL(val, comm, _comm, key, _home, __VA_ARGS__)
766 #define comm_call_ret(_ret, _comm, key, ...) CALL(_ret, comm, _comm, key, ##__VA_ARGS__)
767 #define home_comm_call_ret(_ret, _comm, key, ...) _doCALL(_ret, comm, _comm, key, _home, ##__VA_ARGS__)
768 /* pane_call() is used when a very specific pane must be informed, rather than
769 * the first responder in a chain of panes. This mostly used for notifications,
770 * both generic notification, and special things like a child appearing or disappearing
771 * or the pane being closed.
773 #define pane_call(_pane, key, ...) CALL(val, pane, _pane, key, ##__VA_ARGS__)
774 #define pane_call_ret(_ret, _pane, key, ...) CALL(_ret, pane, _pane, key, ##__VA_ARGS__)
775 #define home_call(_home, key, ...) CALL(val, home, _home, key, ##__VA_ARGS__)
776 #define home_call_comm(_home, key, _focus, comm, ...) _doCALL(val, home, _home, key, comm, _focus, ##__VA_ARGS__)
777 #define home_call_ret(_ret, _home, key, ...) CALL(_ret, home, _home, key, ##__VA_ARGS__)
778 #define call_ret(_ret, key, _focus, ...) CALL(_ret, focus, _focus, key, _focus, ##__VA_ARGS__)
779 #define call_comm(key, _focus, comm, ...) _doCALL(val, focus, _focus, key, comm, _focus, ##__VA_ARGS__)
782 #define pane_notify(...) VFUNC(NOTIFY, __VA_ARGS__)
783 #define NOTIFY9(not, focus, num, m, str, num2, m2, str2, comm2) \
784 do_pane_notify(NULL, not, focus, num, m, str, num2, m2, str2, comm2)
785 #define NOTIFY8(not, focus, num, m, str, num2, m2, str2) \
786 do_pane_notify(NULL, not, focus, num, m, str, num2, m2, str2, NULL)
787 #define NOTIFY7(not, focus, num, m, str, num2, m2) \
788 do_pane_notify(NULL, not, focus, num, m, str, num2, m2, NULL, NULL)
789 #define NOTIFY6(not, focus, num, m, str, num2) \
790 do_pane_notify(NULL, not, focus, num, m, str, num2, NULL, NULL, NULL)
791 #define NOTIFY5(not, focus, num, m, str) \
792 do_pane_notify(NULL, not, focus, num, m, str, 0, NULL, NULL, NULL)
793 #define NOTIFY4(not, focus, num, m) \
794 do_pane_notify(NULL, not, focus, num, m, NULL, 0, NULL, NULL, NULL)
795 #define NOTIFY3(not, focus, num) \
796 do_pane_notify(NULL, not, focus, num, NULL, NULL, 0, NULL, NULL, NULL)
797 #define NOTIFY2(not, focus) \
798 do_pane_notify(NULL, not, focus, 0, NULL, NULL, 0, NULL, NULL, NULL)
800 #define home_pane_notify(...) VFUNC(HOMENOTIFY, __VA_ARGS__)
801 #define HOMENOTIFY10(home, not, focus, num, m, str, num2, m2, str2, comm2) \
802 do_pane_notify(home, not, focus, num, m, str, num2, m2, str2, comm2)
803 #define HOMENOTIFY9(home, not, focus, num, m, str, num2, m2, str2) \
804 do_pane_notify(home, not, focus, num, m, str, num2, m2, str2, NULL)
805 #define HOMENOTIFY8(home, not, focus, num, m, str, num2, m2) \
806 do_pane_notify(home, not, focus, num, m, str, num2, m2, NULL, NULL)
807 #define HOMENOTIFY7(home, not, focus, num, m, str, num2) \
808 do_pane_notify(home, not, focus, num, m, str, num2, NULL, NULL, NULL)
809 #define HOMENOTIFY6(home, not, focus, num, m, str) \
810 do_pane_notify(home, not, focus, num, m, str, 0, NULL, NULL, NULL)
811 #define HOMENOTIFY5(home, not, focus, num, m) \
812 do_pane_notify(home, not, focus, num, m, NULL, 0, NULL, NULL, NULL)
813 #define HOMENOTIFY4(home, not, focus, num) \
814 do_pane_notify(home, not, focus, num, NULL, NULL, 0, NULL, NULL, NULL)
815 #define HOMENOTIFY3(home, not, focus) \
816 do_pane_notify(home, not, focus, 0, NULL, NULL, 0, NULL, NULL, NULL)
818 #if !defined(PANE_DATA_TYPE) && !defined(DOC_DATA_TYPE) && !defined(PANE_DATA_PTR_TYPE)
819 /* If you define PANE_DATA_TYPEor DOC_DATA_TYPE, you need to include this yourself */
820 #include "core-pane.h"