]> git.neil.brown.name Git - edlib.git/blob - core-pane.h
TODO: clean out done items.
[edlib.git] / core-pane.h
1 #include <unistd.h>
2
3 struct pane {
4         const char              *name; /* For easy discovery in gdb */
5         struct pane             *parent safe;
6         struct list_head        siblings;
7         struct list_head        children;
8         struct pane             *focus;
9         short                   x,y,z;
10         short                   h,w;
11         short                   cx, cy; /* cursor position */
12         short                   abs_z;
13
14         short                   damaged;
15         short                   alloc_size;
16         short                   consistency_checks;
17
18         int                     marks;
19         int                     refs;
20         /* timestamp is low bits of time in milliseconds when some
21          * command started.  This makes it easy to check when we
22          * have done too much work.
23          * 0 means nothing is running.
24          * 1 means time is exhausted
25          */
26         unsigned int            timestamp;
27
28         struct pane             *root safe;
29         struct command          *handle;
30         struct attrset          *attrs;
31         struct list_head        notifiers, notifiees;
32         union {
33                 struct doc      doc;
34 #ifdef PANE_DATA_TYPE
35                 PANE_DATA_TYPE  data[1];
36 #endif
37 #ifdef PANE_DATA_PTR_TYPE
38                 PANE_DATA_PTR_TYPE data safe;
39 #endif
40 #ifdef DOC_DATA_TYPE
41                 DOC_DATA_TYPE   doc_data[1];
42 #endif
43 #ifdef PANE_DATA_TYPE_2
44                 PANE_DATA_TYPE_2 data2[1];
45 #endif
46 #ifdef PANE_DATA_PTR_TYPE_2
47                 PANE_DATA_PTR_TYPE_2 data2 safe;
48 #endif
49 #ifdef PANE_DATA_TYPE_3
50                 PANE_DATA_TYPE_3 data3[1];
51 #endif
52 #ifdef PANE_DATA_PTR_TYPE_3
53                 PANE_DATA_PTR_TYPE_3 data3 safe;
54 #endif
55         };
56 };
57
58 bool pane_no_consistency(struct pane *p safe);
59 bool pane_too_long(struct pane *p safe, unsigned int msec);
60 void pane_set_time(struct pane *p safe);
61 static inline void pane_end_time(struct pane *p safe)
62 {
63         p->timestamp = 0;
64 }
65
66 static inline struct pane * safe pane_root(struct pane *p safe)
67 {
68         return p->root;
69 }
70
71 static inline void time_starts(struct pane *p safe)
72 {
73         pane_set_time(pane_root(p));
74         alarm(15);
75 }
76
77 static inline void time_ends(struct pane *p safe)
78 {
79         alarm(0);
80         pane_end_time(pane_root(p));
81 }
82
83 static inline bool times_up(struct pane *p safe)
84 {
85         return pane_too_long(pane_root(p), 15000);
86 }
87
88 static inline bool times_up_fast(struct pane *p safe)
89 {
90         return pane_root(p)->timestamp == 1;
91 }
92
93 static inline struct pane *safe pane_focus(struct pane *p safe)
94 {
95         struct pane *f;
96
97         while ((f = p->focus) != NULL)
98                 p = f;
99         return p;
100 }
101
102 static inline struct pane *pane_get(struct pane *p safe) safe
103 {
104         p->refs += 1;
105         return p;
106 }
107 static inline void pane_put(struct pane *p safe)
108 {
109         p->refs -= 1;
110         pane_free(p);
111 }
112
113 int do_comm_call(struct command *comm safe, const struct cmd_info *ci safe);
114 static inline int do_call_val(enum target_type type, struct pane *home,
115                               struct command *comm2a,
116                               const char *key safe, struct pane *focus safe,
117                               int num,  struct mark *m,  const char *str,
118                               int num2, struct mark *m2, const char *str2,
119                               int x, int y, struct command *comm2b)
120 {
121         struct cmd_info ci = {.key = key, .focus = focus, .home = focus,
122                               .num = num, .mark = m, .str = str,
123                               .num2 = num2, .mark2 = m2, .str2 = str2,
124                               .comm2 = comm2a ?: comm2b, .x = x, .y = y,
125                               .comm = safe_cast NULL};
126         int ret;
127
128         if ((type == TYPE_pane || type == TYPE_home) && !home)
129                 return 0;
130         if (type == TYPE_comm && !comm2a)
131                 return 0;
132         ASSERT(!comm2a || !comm2b || comm2a == comm2b || type == TYPE_comm);
133
134         switch(type) {
135         default:
136         case TYPE_home:
137                 if (home)
138                         ci.home = home;
139                 /* fall-through */
140         case TYPE_focus:
141                 ret = key_handle(&ci);
142                 break;
143         case TYPE_pane:
144                 ci.home = home;
145                 if (home->handle)
146                         ci.comm = home->handle;
147                 ret = do_comm_call(ci.comm, &ci);
148                 break;
149         case TYPE_comm:
150                 if (home)
151                         ci.home = home;
152                 ci.comm = comm2a;
153                 ci.comm2 = comm2b;
154                 ret = do_comm_call(ci.comm, &ci);
155                 break;
156         }
157         return ret;
158 }