Bring back --with-sys-screenrc configure flag.
[screen-lua.git] / src / layout.c
blob6100b5ddb40bfb00fb1192a550ae94924b23ea49
1 /* Copyright (c) 2008, 2009
2 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
3 * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
4 * Micah Cowan (micah@cowan.name)
5 * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net)
6 * Copyright (c) 1993-2002, 2003, 2005, 2006, 2007
7 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
8 * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
9 * Copyright (c) 1987 Oliver Laumann
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3, or (at your option)
14 * any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program (see the file COPYING); if not, see
23 * http://www.gnu.org/licenses/, or contact Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
26 ****************************************************************
29 #include "config.h"
30 #include "screen.h"
31 #include "extern.h"
32 #include "layout.h"
34 extern struct display *display;
35 extern int captionalways;
37 struct layout *layouts;
38 struct layout *laytab[MAXLAY];
39 struct layout *layout_last, layout_last_marker;
40 struct layout *layout_attach = &layout_last_marker;
42 void
43 FreeLayoutCv(cv)
44 struct canvas *cv;
46 struct canvas *cnext, *c = cv;
47 for (; cv; cv = cnext)
49 if (cv->c_slperp)
51 FreeLayoutCv(cv->c_slperp);
52 free(cv->c_slperp);
53 cv->c_slperp = 0;
55 cnext = cv->c_slnext;
56 cv->c_slnext = 0;
57 if (cv != c)
58 free(cv);
62 struct layout *
63 CreateLayout(title, startat)
64 char *title;
65 int startat;
67 struct layout *lay;
68 int i;
70 if (startat >= MAXLAY || startat < 0)
71 startat = 0;
72 for (i = startat; ;)
74 if (!laytab[i])
75 break;
76 if (++i == MAXLAY)
77 i = 0;
78 if (i == startat)
80 Msg(0, "No more layouts\n");
81 return 0;
84 lay = (struct layout *)calloc(1, sizeof(*lay));
85 lay->lay_title = SaveStr(title);
86 lay->lay_autosave = 1;
87 lay->lay_number = i;
88 laytab[i] = lay;
89 lay->lay_next = layouts;
90 layouts = lay;
91 return lay;
94 void
95 SaveLayout(name, cv)
96 char *name;
97 struct canvas *cv;
99 struct layout *lay;
100 struct canvas *fcv;
101 for (lay = layouts; lay; lay = lay->lay_next)
102 if (!strcmp(lay->lay_title, name))
103 break;
104 if (lay)
105 FreeLayoutCv(&lay->lay_canvas);
106 else
107 lay = CreateLayout(name, 0);
108 if (!lay)
109 return;
110 fcv = D_forecv;
111 DupLayoutCv(cv, &lay->lay_canvas, 1);
112 lay->lay_forecv = D_forecv;
113 D_forecv = fcv;
114 D_layout = lay;
117 void
118 AutosaveLayout(lay)
119 struct layout *lay;
121 struct canvas *fcv;
122 if (!lay || !lay->lay_autosave)
123 return;
124 FreeLayoutCv(&lay->lay_canvas);
125 fcv = D_forecv;
126 DupLayoutCv(&D_canvas, &lay->lay_canvas, 1);
127 lay->lay_forecv = D_forecv;
128 D_forecv = fcv;
131 struct layout *
132 FindLayout(name)
133 char *name;
135 struct layout *lay;
136 char *s;
137 int i;
138 for (i = 0, s = name; *s >= '0' && *s <= '9'; s++)
139 i = i * 10 + (*s - '0');
140 if (!*s && s != name && i >= 0 && i < MAXLAY)
141 return laytab[i];
142 for (lay = layouts; lay; lay = lay->lay_next)
143 if (!strcmp(lay->lay_title, name))
144 break;
145 return lay;
148 void
149 LoadLayout(lay, cv)
150 struct layout *lay;
151 struct canvas *cv;
153 AutosaveLayout(D_layout);
154 if (!lay)
156 while (D_canvas.c_slperp)
157 FreeCanvas(D_canvas.c_slperp);
158 MakeDefaultCanvas();
159 SetCanvasWindow(D_forecv, 0);
160 D_layout = 0;
161 return;
163 while (D_canvas.c_slperp)
164 FreeCanvas(D_canvas.c_slperp);
165 D_cvlist = 0;
166 D_forecv = lay->lay_forecv;
167 DupLayoutCv(&lay->lay_canvas, &D_canvas, 0);
168 D_canvas.c_ye = D_height - 1 - ((D_canvas.c_slperp && D_canvas.c_slperp->c_slnext) || captionalways) - (D_has_hstatus == HSTATUS_LASTLINE);
169 ResizeCanvas(&D_canvas);
170 RecreateCanvasChain();
171 RethinkDisplayViewports();
172 PutWindowCv(&D_canvas);
173 ResizeLayersToCanvases();
174 D_layout = lay;
177 void
178 NewLayout(title, startat)
179 char *title;
180 int startat;
182 struct layout *lay;
183 struct canvas *fcv;
185 lay = CreateLayout(title, startat);
186 if (!lay)
187 return;
188 LoadLayout(0, &D_canvas);
189 fcv = D_forecv;
190 DupLayoutCv(&D_canvas, &lay->lay_canvas, 1);
191 lay->lay_forecv = D_forecv;
192 D_forecv = fcv;
193 D_layout = lay;
194 lay->lay_autosave = 1;
198 static char *
199 AddLayoutsInfo(buf, len, where)
200 char *buf;
201 int len;
202 int where;
204 char *s, *ss, *t;
205 struct layout *p, **pp;
206 int l;
208 s = ss = buf;
209 for (pp = laytab; pp < laytab + MAXLAY; pp++)
211 if (pp - laytab == where && ss == buf)
212 ss = s;
213 if ((p = *pp) == 0)
214 continue;
215 t = p->lay_title;
216 l = strlen(t);
217 if (l > 20)
218 l = 20;
219 if (s - buf + l > len - 24)
220 break;
221 if (s > buf)
223 *s++ = ' ';
224 *s++ = ' ';
226 sprintf(s, "%d", p->lay_number);
227 if (p->lay_number == where)
228 ss = s;
229 s += strlen(s);
230 if (display && p == D_layout)
231 *s++ = '*';
232 *s++ = ' ';
233 strncpy(s, t, l);
234 s += l;
236 *s = 0;
237 return ss;
240 void
241 ShowLayouts(where)
242 int where;
244 char buf[1024];
245 char *s, *ss;
247 if (!display)
248 return;
249 if (!layouts)
251 Msg(0, "No layouts defined\n");
252 return;
254 if (where == -1 && D_layout)
255 where = D_layout->lay_number;
256 ss = AddLayoutsInfo(buf, sizeof(buf), where);
257 s = buf + strlen(buf);
258 if (ss - buf > D_width / 2)
260 ss -= D_width / 2;
261 if (s - ss < D_width)
263 ss = s - D_width;
264 if (ss < buf)
265 ss = buf;
268 else
269 ss = buf;
270 Msg(0, "%s", ss);
273 void
274 RemoveLayout(lay)
275 struct layout *lay;
277 struct layout **layp = &layouts;
279 for (; *layp; layp = &(*layp)->lay_next)
281 if (*layp == lay)
283 *layp = lay->lay_next;
284 break;
287 laytab[lay->lay_number] = (struct layout *)0;
289 if (display && D_layout == lay)
290 D_layout = (struct layout *)0;
292 FreeLayoutCv(&lay->lay_canvas);
294 if (lay->lay_title)
295 free(lay->lay_title);
296 free(lay);
298 if (layouts)
299 LoadLayout((display && D_layout) ? D_layout : *layp ? *layp : layouts,
300 display ? &D_canvas : (struct canvas *)0);
301 Activate(0);
304 void
305 UpdateLayoutCanvas(cv, wi)
306 struct canvas *cv;
307 struct win *wi;
309 for (; cv; cv = cv->c_slnext)
311 if (cv->c_layer && Layer2Window(cv->c_layer) == wi)
313 /* A simplistic version of SetCanvasWindow(cv, 0) */
314 struct layer *l = cv->c_layer;
315 cv->c_layer = 0;
316 if (l->l_cvlist == 0 && (wi == 0 || l != wi->w_savelayer))
317 KillLayerChain(l);
318 l = &cv->c_blank;
319 l->l_data = 0;
320 if (l->l_cvlist != cv)
322 cv->c_lnext = l->l_cvlist;
323 l->l_cvlist = cv;
325 cv->c_layer = l;
326 /* Do not end here. Multiple canvases can have the same window */
329 if (cv->c_slperp)
330 UpdateLayoutCanvas(cv->c_slperp, wi);
335 static void
336 dump_canvas(cv, file)
337 struct canvas *cv;
338 FILE *file;
340 struct canvas *c;
341 for (c = cv->c_slperp; c && c->c_slnext; c = c->c_slnext)
343 fprintf(file, "split%s\n", c->c_slorient == SLICE_HORI ? " -v" : "");
346 for (c = cv->c_slperp; c; c = c->c_slnext)
348 if (c->c_slperp)
349 dump_canvas(c, file);
350 else
351 fprintf(file, "focus\n");
356 LayoutDumpCanvas(cv, filename)
357 struct canvas *cv;
358 char *filename;
360 FILE *file = secfopen(filename, "a");
361 if (!file)
362 return 0;
363 dump_canvas(cv, file);
364 fclose(file);
365 return 1;