1 /* -*- mode: C; mode: fold; -*- */
2 /* Copyright (c) 1992, 1998 John E. Davis
3  * This file is part of JED editor library source.
4  *
5  * You may distribute this file under the terms the GNU General Public
6  * License.  See the file COPYING for more information.
7  */
8 #include "config.h"
9 #include "jed-feat.h"
10 
11 /*{{{ Include Files */
12 
13 #include <stdio.h>
14 #include <string.h>
15 
16 #include "buffer.h"
17 #include "window.h"
18 #include "screen.h"
19 #include "misc.h"
20 #include "ledit.h"
21 #include "sysdep.h"
22 #include "display.h"
23 #include "paste.h"
24 
25 /*}}}*/
26 
27 extern Window_Type *The_MiniWindow;
28 Window_Type *JWindow;
29 int Top_Window_Row = 2;
30 
create_window(int top,int rows,int col,int width)31 Window_Type *create_window(int top, int rows, int col, int width) /*{{{*/
32 {
33     Window_Type *w;
34 
35     if (NULL == (w = (Window_Type *) SLmalloc (sizeof(Window_Type))))
36       {
37 	  exit_error("create_window: malloc error.", 0);
38       }
39 
40    SLMEMSET ((char *) w, 0, sizeof (Window_Type));
41    if (top < 1) top = 1;
42    w->top = top;
43    if (rows < 1) rows = 1;
44    w->rows = rows;
45    if (width < 1) width = 1;
46    w->width = width;
47    w->column = col;
48 
49    return(w);
50 }
51 
52 /*}}}*/
window_buffer(Buffer * b)53 void window_buffer(Buffer *b) /*{{{*/
54 {
55    if (JWindow == NULL)
56      {
57 	JWindow = create_window(Top_Window_Row,
58 				Jed_Num_Screen_Rows - 2 - (Top_Window_Row - 1),
59 				1, Jed_Num_Screen_Cols);
60 	JWindow->next = JWindow;
61      }
62 
63    touch_window();
64 
65    JWindow->beg.line = JWindow->mark.line = b->line;
66    JWindow->beg.point = JWindow->mark.point = b->point;
67    JWindow->beg.n = JWindow->mark.n = b->linenum + b->nup;
68    JWindow->column = 1;
69    JWindow->buffer = b;
70    JWindow->trashed = 1;
71 }
72 
73 /*}}}*/
74 
75 #if JED_HAS_SUBPROCESSES
move_window_marks(int all)76 void move_window_marks (int all) /*{{{*/
77 {
78    Window_Type *w = JWindow;
79    if (w == NULL) return;
80    do
81      {
82 	if (w->buffer == CBuf)
83 	  {
84 	     w->mark.point = Point;
85 	     w->mark.line = CLine;
86 	     w->mark.n = LineNum + CBuf->nup;
87 	     if (all == 0) break;
88 	  }
89 	w = w->next;
90      }
91    while (w != JWindow);
92 }
93 
94 /*}}}*/
95 #endif
96 
other_window()97 int other_window() /*{{{*/
98 {
99    switch_to_buffer(JWindow->buffer);
100    /* CBuf->line = CLine;
101    CBuf->point = Point; */
102    JWindow->mark.point = Point;
103    JWindow->mark.line = CLine;
104    JWindow->mark.n = LineNum + CBuf->nup;
105    /* JWindow->buffer = CBuf; */
106 
107    JWindow = JWindow->next;
108    switch_to_buffer(JWindow->buffer);
109    /* CBuf = JWindow->buffer; */
110    Point = JWindow->mark.point;
111    CLine = JWindow->mark.line;
112    LineNum = JWindow->mark.n - CBuf->nup;
113    return(1);
114 }
115 
116 /*}}}*/
117 
split_window(void)118 int split_window (void) /*{{{*/
119 {
120    int n, top, width, row;
121    Window_Type *w, *neew;
122    Line *l, *cline;
123 
124     if (JWindow->rows < 5)
125       {
126 	  msg_error("Window too small.");
127 	  return(0);
128       }
129 
130    switch_to_buffer(JWindow->buffer);
131    n = JWindow->rows / 2;
132    top = JWindow->top + n + 1;
133    width = JWindow->width;
134    n = JWindow->rows - n - 1;
135    JWindow->rows = JWindow->rows / 2;
136 
137    if (NULL == (JWindow->beg.line = find_top()))
138      JWindow->beg.line = CLine;
139 
140    w = JWindow->next;
141    JWindow->next = neew = create_window(top, n, JWindow->column, width);
142 
143    neew->next = w;
144    neew->buffer = CBuf;
145    neew->mark.point = Point;
146    neew->mark.line = CLine;
147    neew->mark.n = LineNum + CBuf->nup;
148 
149    other_window();
150    touch_window();
151 
152 
153 #if JED_HAS_LINE_ATTRIBUTES
154    if (NULL == (cline = jed_find_non_hidden_line (CLine)))
155      cline = CLine;
156 #else
157    cline = CLine;
158 #endif
159 
160    l = find_top ();
161    if (l == NULL)
162      l = cline;
163 
164    JWindow->beg.line = cline;
165 
166    n = 0;
167    while (l != cline)
168      {
169 	l = l->next;
170 	n++;
171      }
172    JWindow->beg.n = LineNum + CBuf->nup - n;
173 
174    /* Try to leave Point on same line of display if possible */
175    if (-1 != (row = jed_find_line_on_screen (CLine)))
176      {
177 	row += 1;
178 
179 	w = JWindow;
180 	do
181 	  {
182 	     if ((JWindow->buffer == CBuf) && (JWindow->top <= row)
183 		 && (JWindow->top + JWindow->rows > row)) break;
184 	     other_window();
185 	  }
186 	while (w != JWindow);
187      }
188     return(1);
189 }
190 
191 /*}}}*/
one_window(void)192 int one_window (void) /*{{{*/
193 {
194    Window_Type *w, *next, *mini;
195    Buffer *b;
196    mini = NULL;
197    if (JWindow->top == Jed_Num_Screen_Rows) return(0);  /* mini-buffer */
198    w = JWindow->next;
199    b = JWindow->buffer;
200    while(w != JWindow)
201      {
202 	next = w->next;
203 	if (w != The_MiniWindow)
204 	  {
205 	     if (w->buffer != b) touch_window_hard (w, 0);
206 	     SLfree ((char *)w);
207 	  }
208 	else mini = w;
209 	w = next;
210      }
211    if (mini == NULL) mini = JWindow;
212    JWindow->next = mini;
213    mini->next = JWindow;
214    JWindow->top = Top_Window_Row;
215    JWindow->rows = Jed_Num_Screen_Rows - 2 - (Top_Window_Row - 1);
216    touch_window();
217    return(1);
218 }
219 
220 /*}}}*/
enlarge_window()221 int enlarge_window() /*{{{*/
222 {
223    Window_Type *w, *w1;
224    int min = 2;
225 
226    if (JWindow == The_MiniWindow) return(0);
227    /* if (IS_MINIBUFFER) return(0); */
228    if (JWindow == JWindow->next) return(0);
229    w = JWindow->next;
230    while(w->rows <= min) w = w->next;
231    if (w == JWindow) return(0);
232 
233    if (w->top < JWindow->top)
234      {
235 	w->rows -= 1;
236 	JWindow->rows += 1;
237 	do
238 	  {
239 	     w = w->next;
240 	     w->top -= 1;
241 	  }
242 	while (w != JWindow);
243      }
244    else
245      {
246 	JWindow->rows += 1;
247 	w1 = JWindow;
248 	while(w1 != w)
249 	  {
250 	     w1 = w1->next;
251 	     w1->top += 1;
252 	  }
253 	w->rows -= 1;
254      }
255    w = JWindow;
256    do
257      {
258 	touch_window();
259 	JWindow = JWindow->next;
260      }
261    while (w != JWindow);
262    return(1);
263 }
264 
265 /*}}}*/
adjust_windows(int height)266 static void adjust_windows(int height) /*{{{*/
267 {
268    Window_Type *w = JWindow;
269    int rows;
270 
271    do
272      {
273 	if (w->rows + w->top + 1 == Jed_Num_Screen_Rows)
274 	  {
275 	     rows = height - 1 - w->top;
276 	     if (rows > 1)
277 	       {
278 		  w->rows = rows;
279 		  return;
280 	       }
281 
282 	     while(JWindow->top != Top_Window_Row) other_window();
283 
284 	     one_window();
285 	     JWindow->rows = height - 2 - (Top_Window_Row - 1);
286 	     if (JWindow->rows < 1) JWindow->rows = 1;
287 	     return;
288 	  }
289 	w = w->next;
290      }
291    while (w != JWindow);
292    /* not reached! */
293 }
294 
295 /*}}}*/
296 
297 
jed_update_window_sizes(int height,int width)298 void jed_update_window_sizes (int height, int width) /*{{{*/
299 {
300    Window_Type *w;
301 
302    if (JWindow == NULL) return;
303 
304    if (height < 5) height = 5;
305    if (width < 5) width = 5;
306 
307    if (height != Jed_Num_Screen_Rows)
308      adjust_windows(height);
309 
310    w = JWindow;
311    do
312      {
313 	JWindow->trashed = 1;
314 	JWindow->width = width;
315 	JWindow = JWindow->next;
316      }
317    while (w != JWindow);
318 
319    if (The_MiniWindow != NULL)
320      {
321 	The_MiniWindow->top = height;
322 	The_MiniWindow->width = width;
323      }
324 }
325 
326 /*}}}*/
buffer_visible(Buffer * b)327 int buffer_visible(Buffer *b) /*{{{*/
328 {
329    Window_Type *w = JWindow;
330    int n = 0;
331    if (b == NULL) return 0;
332 
333    do
334      {
335 	if (w->buffer == b) n++;
336 	w = w->next;
337      }
338    while (w != JWindow);
339    return n;
340 }
341 
342 /*}}}*/
delete_window()343 int delete_window() /*{{{*/
344 {
345    Window_Type *tthis, *prev, *next;
346    int nr1;
347 
348    tthis = JWindow;
349    next = tthis->next;
350    if ((MiniBuffer_Active && ((tthis == The_MiniWindow) || (tthis == next->next)))
351        || (tthis == next)) return(0);
352 
353 
354 
355    nr1 = tthis->top + tthis->rows + 1;
356    if (nr1 != Jed_Num_Screen_Rows)
357      {
358 	while (JWindow->top != nr1) other_window();
359 	JWindow->top = tthis->top;
360      }
361    else
362      {
363 	while(JWindow->top + JWindow->rows + 1 != tthis->top) other_window();
364      }
365 
366    JWindow->rows += tthis->rows + 1;
367    touch_window();
368 
369    prev = next;
370    while(prev->next != tthis) prev = prev->next;
371    prev->next = next;
372 
373    SLfree ((char *)tthis);
374    return(1);
375 }
376 
377 /*}}}*/
378 
touch_screen_for_buffer(Buffer * b)379 void touch_screen_for_buffer(Buffer *b) /*{{{*/
380 {
381    Window_Type *w;
382 
383    w = JWindow;
384    do
385      {
386 	if (w->buffer == b)
387 	  {
388 	     touch_window_hard (w, 0);
389 	  }
390 	w = w->next;
391      }
392    while(w != JWindow);
393 }
394 
395 /*}}}*/
is_line_visible(int lnum)396 int is_line_visible (int lnum) /*{{{*/
397 {
398    int n = JWindow->rows;
399    Line *l, *beg = JWindow->beg.line;
400 
401    push_spot ();
402    goto_line (&lnum);
403    l = CLine;
404    pop_spot ();
405 
406 #if JED_HAS_LINE_ATTRIBUTES
407    if (l->flags & JED_LINE_HIDDEN) return 0;
408 #endif
409 
410    while (n && (beg != NULL))
411      {
412 	if (l == beg) return 1;
413 
414 #if JED_HAS_LINE_ATTRIBUTES
415 	if (0 == (beg->flags & JED_LINE_HIDDEN))
416 #endif
417 	  n--;
418 
419 	beg = beg->next;
420      }
421    return 0;
422 }
423 
424 /*}}}*/
425