1 /* ELLE - Copyright 1982, 1987 by Ken Harrenstien, SRI International
2 * This software is quasi-public; it may be used freely with
3 * like software, but may NOT be sold or made part of licensed
4 * products without permission of the author.
7 /* EEFD Display control functions
14 /* EFUN: "New Window" */
15 /* Clear current window and set as requested.
16 * ^L - clear current window and redisplay it (default top)
17 * <arg>^L - select new window so that current line is
18 * the <arg>'th from top of window (0 = top line)
19 * ^U^L - clear current line and redisplay.
23 register struct window
*w
;
25 d_fixcur(); /* Ensure screen vars correct */
28 { if((n
= exp
) == 4 && exp_p
== 4 /* CTRL-U? */
29 && (i
= d_line(cur_dot
)) >= 0) /* On valid line? */
30 { d_lupd(w
, i
); /* Update it */
34 else /* No argument given */
35 { redp(RD_SCREEN
); /* Clear whole screen (later just window? */
39 n
= (ev_nwpct
*w
->w_ht
)/100; /* Set new window using % */
42 if (n
< 0) n
= 0; /* Ensure # is reasonable */
43 else if (n
>= w
->w_ht
)
45 d_fgoloff(-n
); /* Go up given # of lines */
46 w
->w_topldot
= e_dot(); /* Set new top-line dot */
47 e_gocur(); /* Move back to cur_dot */
48 redp(RD_FIXWIN
); /* Say to re-hack window */
53 /* EFUN: "Next Screen" */
60 /* EFUN: "Previous Screen" */
67 /* EFUN: "Other New Screen" (not EMACS) - from IMAGEN config */
73 if (exp_p
) /* With arg, back up */
78 redp(RD_WINDS
); /* Look at all windows */
80 #endif /*FX_OTHNSCREEN*/
84 /* EFUN: "Line to Window Border" (not EMACS) - from IMAGEN config */
88 /* With arg, means "to bottom" */
89 exp
= cur_win
->w_ht
- 1;
94 /* Just a "front end" for ^L */
98 #endif /*FX_LWINDBORD*/
101 /* EFUN: "Scroll Window Up" (not EMACS) - from IMAGEN config */
106 #endif /*FX_SCUPWIND*/
109 /* EFUN: "Scroll Window Down" (not EMACS) - from IMAGEN config */
114 #endif /*FX_SCDNWIND*/
118 /* EFUN: "Move to Window Top" (not EMACS) - from IMAGEN config */
127 /* EFUN: "Move to Window Bottom" (not EMACS) - from IMAGEN config */
137 #if FX_NSCREEN || FX_PSCREEN || FX_OTHNSCREEN
138 /* Move to new loc by N screenfuls.
139 * If moving downward, keep bottom 2 lines of current screen on top of next.
140 * If moving up, keep top 2 lines of current screen on bottom of next.
146 register struct window
*w
;
150 if((i
= w
->w_ht
- 2) <= 0) /* Just-in-case check */
154 d_fixcur(); /* Ensure window fixed up */
155 e_go(w
->w_topldot
); /* Start at top of screen */
158 /* Find where we are now, and make that the new top of window. */
159 if((newdot
= e_dot()) != e_blen()) /* If not at EOF, */
160 w
->w_topldot
= newdot
; /* set new top of window! */
161 else w
->w_topldot
= 0; /* Else let fix_wind select top. */
163 e_setcur(); /* Ensure cur_dot set to real loc */
165 redp(RD_WINRES
|RD_REDO
); /* HINT: just repaint screen */
167 redp(RD_FIXWIN
|RD_MOVE
);
170 #endif /*FX_NSCREEN || FX_PSCREEN || FX_OTHNSCREEN*/
172 #if FX_SCUPWIND || FX_SCDNWIND /* If want scroll-window function */
175 { register struct window
*w
= cur_win
;
179 d_fixcur(); /* Ensure screen vars for win all set up */
180 e_go(w
->w_topldot
); /* Go to top of current window */
181 d_fgoloff(n
); /* Move given # of display lines */
182 w
->w_topldot
= e_dot(); /* Set new top of window */
183 redp(RD_FIXWIN
); /* Say new window needs fixing up */
185 /* Now adjust position of current dot so it is still within window */
187 { /* Moving screen text "up" (win down) */
188 if (cur_dot
< w
->w_topldot
) /* See if scrolled off top */
189 e_setcur(); /* yes, make dot be win top */
191 else { /* Moving screen text "down" (win up) */
192 savdot
= cur_dot
; /* Save since must temporarily */
193 e_setcur(); /* set current dot within window, */
194 d_fixcur(); /* so screen can be fixed up. */
195 if (inwinp(w
, savdot
)) /* Now see if old dot in new win */
196 cur_dot
= savdot
; /* Yes, just restore it! */
197 else /* No, make it beg of bottom line. */
198 cur_dot
= scr
[w
->w_pos
+ w
->w_ht
- 1]->sl_boff
;
200 e_gocur(); /* Make current pos be cur_dot */
202 #endif /* FX_SC%%WIND */
204 #if FX_MVWTOP || FX_MVWBOT /* Guts for above two functions */
209 d_fixcur(); /* Ensure current win screen image fixed up */
210 e_gosetcur(top
? cur_win
->w_topldot
211 : scr
[cur_win
->w_pos
+ cur_win
->w_ht
- 1]->sl_boff
);
213 redp(RD_MOVE
); /* Should only be cursor adjustment */
217 /* Given a line and a position in that line, return the xpos.
218 * NOTE CAREFULLY that when line extends over several screen lines,
219 * the value returned is the screen X position even though it
220 * may be some lines down from the start of the logical line!
221 * Also note this won't work very well if tabs exist on the extra
222 * lines. This rtn should not be used for cursor positioning.
223 * Also note: d_ncols() will never return -1 meaning EOL because the
224 * setup guarantees there is no EOL within the range checked.
226 d_curind() /* Find current indentation */
231 { register int i
, col
;
235 savdot
= e_dot(); /* Save current position */
236 e_go(lin
); /* Go to line caller wants */
237 e_gobol(); /* Go to its beginning */
238 col
= 0; /* Start at left margin */
239 if((nchars
= lin
- e_dot()) > 0)
241 if(nchars
< (i
= scr_wd0
))
243 if((col
= d_ncols(i
, col
)) < 0) /* Hit edge of screen? */
244 col
= 0; /* Reset to left margin */
245 } while((nchars
-= i
) > 0);
246 e_go(savdot
); /* Restore current position */
250 /* ININDEX - How many positions in lin must we go to get to xpos?
251 * Returns -1 if can't be done. Assumes "lin" is at beginning of a line!
257 { register int col
, x
;
259 char tmp
[MAXLINE
+MAXCHAR
];
260 extern int sctreol
; /* From EEDISP */
262 if((x
= xpos
) <= 0) return(0);
263 if(x
>= MAXLINE
) return(-1); /* ?!? */
266 e_go(lin
); /* Assumes this is start of line */
267 col
= sctrin(tmp
, x
, 0); /* Translate from sb_getc input */
268 if((col
- x
) >= 0) /* Exact count-out or past it? */
269 { x
= e_dot() - lin
; /* Yup, win. */
270 if (sctreol
> 0) /* Did we hit (and include) EOL? */
271 #if FX_EOLMODE /* If so, back up over the EOL. */
272 x
-= eolcrlf(cur_buf
) ? 2 : 1;
277 else x
= -1; /* Nope, EOL or EOF hit too soon. */
283 * D_ ROUTINES - display-relative functions. Similar to E_, but
284 * a "line" is defined as one line of the screen rather than
285 * as a logical text line. Also, for efficiency reasons
286 * arguments are given saying how many lines to hack.
289 d_gopl() { return(d_goloff(-1)); }
290 d_gonl() { return(d_goloff( 1)); }
292 /* D_GOLOFF(i) - Go to beginning of a display line
293 * D_FGOLOFF(i) - ditto, but assumes screen image of window already fixed up.
294 * i - # of lines offset. Negative moves up, positive down.
295 * Zero arg goes to beginning of current display line.
296 * Side effects: screen image of window is fixed up at
297 * start of routine, but is NOT updated by the move to new location.
302 d_fgoloff(cnt
); /* Now can invoke fixed-up fast version */
308 char line
[MAXLINE
+MAXCHAR
];
311 /* Find current position in window, since can save time
312 * by using stuff already in fixed-up screen image.
314 if((y
= d_line(e_dot())) < 0) /* Get current Y position */
316 errbarf("Dot out of window");
319 top
= cur_win
->w_pos
; /* 1st line of window */
320 bot
= top
+ cur_win
->w_ht
; /* 1st line not in window */
321 l
.sl_boff
= scr
[y
]->sl_boff
;
322 l
.sl_nlin
= &line
[0];
325 if(cnt
> 0) goto down
;
327 /* Go upwards. This is hairy because we want to be clever about
328 * huge logical lines -- avoid going all the way back to BOL.
330 if((y
+cnt
) >= top
) /* Fits? */
331 goto onscr
; /* Hurray, hack it! */
332 cnt
+= y
- top
; /* Sigh, find # lines to skip */
334 l
.sl_boff
= scr
[y
]->sl_boff
;
337 /* Okay, here's the hairy part. Must go backwards from top
338 * line; if no EOL within scr_wid*cnt chars, then simply assume one is
343 return; /* Really should re-adjust stuff, but... */
345 /* Go downwards. Not too bad... */
347 if((y
+cnt
) <= bot
) /* Fits? */
348 goto onscr
; /* Hurray, hack it! */
349 cnt
-= bot
- y
; /* Sigh, find # lines can skip */
351 l
.sl_boff
= scr
[y
]->sl_boff
+ scr
[y
]->sl_len
;
353 && (l
.sl_cont
= scr
[y
-1]->sl_cont
))
354 l
.sl_line
= scr
[y
-1]->sl_line
;
359 } while(--cnt
> 0 && l
.sl_len
);
362 onscr
: if((y
+= cnt
) >= bot
)
364 e_go(scr
[y
]->sl_boff
+ scr
[y
]->sl_len
);
366 else e_go(scr
[y
]->sl_boff
);
369 /* D_FIXCUR() - Ensure current window is fixed up, with
370 * current location (not necessarily cur_dot)!
371 * Ensure cur_dot reflects real loc so that fix_wind will work,
372 * and always call fix_wind to ensure that screen image vars
373 * are set properly. Note any active redisplay flags must be carried
374 * on into window redisplay flags, so fix_wind will notice them.
377 { register struct window
*w
;
383 w
->w_redp
|= rd_type
&RDS_WINFLGS
;
384 fix_wind(w
); /* Always ensure window is set up! */
385 redp(w
->w_redp
); /* Add back new flags */
386 rd_type
&= ~RDS_DOFIX
; /* and flush fix-invoking ones */
387 cur_dot
= savedot
; /* Restore cur_dot, no longer hacked. */
390 d_backup(nlin
) /* Try to back up by nlin screen lines */
392 { register int cnt
, n
, c
;
395 if((cnt
= nlin
+1) <= 0) return;
399 eolstop
= 0; /* Not yet stopped at EOL */
400 do { if((c
= e_rgetc()) == EOF
)
406 { if((c
= e_rgetc()) == CR
)
424 if(eolcrlf(cur_buf
)) e_getc(); /* Skip back over CR */
426 e_getc(); /* Skip back over LF */
429 /* At this point, dot is guaranteed to be less than goal,
430 * which is the important thing for fix_wind, which can handle
431 * things okay if dot is off bottom of window.
433 return(1); /* Say always test result */