pci: don't do sanity check for missing pci bus, the check can misfire.
[minix.git] / commands / elle / eefd.c
blob8c169fbdb88063c9b671b99b1fca74a6a3fa3703
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.
5 */
7 /* EEFD Display control functions
8 */
10 #include "elle.h"
13 #if FX_NEWWIN
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.
21 f_newwin()
22 { register int i, n;
23 register struct window *w;
25 d_fixcur(); /* Ensure screen vars correct */
26 w = cur_win;
27 if (exp_p)
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 */
31 return;
34 else /* No argument given */
35 { redp(RD_SCREEN); /* Clear whole screen (later just window? */
36 #if IMAGEN
37 return;
38 #else
39 n = (ev_nwpct*w->w_ht)/100; /* Set new window using % */
40 #endif /*-IMAGEN*/
42 if (n < 0) n = 0; /* Ensure # is reasonable */
43 else if (n >= w->w_ht)
44 n = w->w_ht - 1;
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 */
50 #endif /*FX_NEWWIN*/
52 #if FX_NSCREEN
53 /* EFUN: "Next Screen" */
54 f_nscreen()
55 { d_screen( exp);
57 #endif /*FX_NSCREEN*/
59 #if FX_PSCREEN
60 /* EFUN: "Previous Screen" */
61 f_pscreen()
62 { d_screen(-exp);
64 #endif /*FX_PSCREEN*/
66 #if FX_OTHNSCREEN
67 /* EFUN: "Other New Screen" (not EMACS) - from IMAGEN config */
68 f_othnscreen()
70 if (! oth_win)
71 return;
72 f_othwind();
73 if (exp_p) /* With arg, back up */
74 d_screen(-1);
75 else
76 d_screen(1);
77 f_othwind();
78 redp(RD_WINDS); /* Look at all windows */
80 #endif /*FX_OTHNSCREEN*/
83 #if FX_LWINDBORD
84 /* EFUN: "Line to Window Border" (not EMACS) - from IMAGEN config */
85 f_lwindbord()
87 if (exp_p)
88 /* With arg, means "to bottom" */
89 exp = cur_win->w_ht - 1;
90 else
91 /* Else, to top */
92 exp = 0;
94 /* Just a "front end" for ^L */
95 exp_p = 1;
96 f_newwin();
98 #endif /*FX_LWINDBORD*/
100 #if FX_SCUPWIND
101 /* EFUN: "Scroll Window Up" (not EMACS) - from IMAGEN config */
102 f_scupwind()
104 scroll_win(exp);
106 #endif /*FX_SCUPWIND*/
108 #if FX_SCDNWIND
109 /* EFUN: "Scroll Window Down" (not EMACS) - from IMAGEN config */
110 f_scdnwind()
112 scroll_win(-exp);
114 #endif /*FX_SCDNWIND*/
117 #if FX_MVWTOP
118 /* EFUN: "Move to Window Top" (not EMACS) - from IMAGEN config */
119 f_mvwtop()
121 extern moveborder();
122 moveborder(1);
124 #endif /*FX_MVWTOP*/
126 #if FX_MVWBOT
127 /* EFUN: "Move to Window Bottom" (not EMACS) - from IMAGEN config */
128 f_mvwbot()
130 extern moveborder();
131 moveborder(0);
133 #endif /*FX_MVWBOT*/
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.
142 d_screen(rep)
143 int rep;
145 register int i;
146 register struct window *w;
147 chroff newdot;
149 w = cur_win;
150 if((i = w->w_ht - 2) <= 0) /* Just-in-case check */
151 i = 1;
152 if((i *= rep) == 0)
153 return;
154 d_fixcur(); /* Ensure window fixed up */
155 e_go(w->w_topldot); /* Start at top of screen */
156 d_fgoloff(i);
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 */
164 #if IMAGEN
165 redp(RD_WINRES|RD_REDO); /* HINT: just repaint screen */
166 #else
167 redp(RD_FIXWIN|RD_MOVE);
168 #endif /*-IMAGEN*/
170 #endif /*FX_NSCREEN || FX_PSCREEN || FX_OTHNSCREEN*/
172 #if FX_SCUPWIND || FX_SCDNWIND /* If want scroll-window function */
173 scroll_win(n)
174 register int n;
175 { register struct window *w = cur_win;
176 chroff savdot;
178 if (n == 0) return;
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 */
186 if (n > 0)
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 */
205 static
206 moveborder(top)
207 int top;
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 */
215 #endif /*FX_MVW%%%*/
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 */
227 { indtion(e_dot());
229 indtion(lin)
230 chroff lin;
231 { register int i, col;
232 chroff savdot;
233 chroff nchars;
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)
240 do {
241 if(nchars < (i = scr_wd0))
242 i = nchars;
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 */
247 return(col);
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!
254 inindex (lin, xpos)
255 chroff lin;
256 int xpos;
257 { register int col, x;
258 chroff savdot;
259 char tmp[MAXLINE+MAXCHAR];
260 extern int sctreol; /* From EEDISP */
262 if((x = xpos) <= 0) return(0);
263 if(x >= MAXLINE) return(-1); /* ?!? */
264 col = 0;
265 savdot = e_dot();
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;
273 #else
274 --x;
275 #endif
277 else x = -1; /* Nope, EOL or EOF hit too soon. */
278 e_go(savdot);
279 return(x);
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.
299 d_goloff(cnt)
300 int cnt;
301 { d_fixcur();
302 d_fgoloff(cnt); /* Now can invoke fixed-up fast version */
304 d_fgoloff(cnt)
305 register int cnt;
306 { register int y;
307 struct scr_line l;
308 char line[MAXLINE+MAXCHAR];
309 int top, bot;
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");
317 y = 0;
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];
323 l.sl_cont = 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 */
333 y = top;
334 l.sl_boff = scr[y]->sl_boff;
335 e_go(l.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
339 * seen.
341 cnt = -cnt;
342 d_backup(cnt);
343 return; /* Really should re-adjust stuff, but... */
345 /* Go downwards. Not too bad... */
346 down:
347 if((y+cnt) <= bot) /* Fits? */
348 goto onscr; /* Hurray, hack it! */
349 cnt -= bot - y; /* Sigh, find # lines can skip */
350 y = bot - 1;
351 l.sl_boff = scr[y]->sl_boff + scr[y]->sl_len;
352 if(y > top
353 && (l.sl_cont = scr[y-1]->sl_cont))
354 l.sl_line = scr[y-1]->sl_line;
355 e_go(l.sl_boff);
357 do {
358 fix_line(&l,&l);
359 } while(--cnt > 0 && l.sl_len);
360 return;
362 onscr: if((y += cnt) >= bot)
363 { --y;
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.
376 d_fixcur()
377 { register struct window *w;
378 chroff savedot;
380 w = cur_win;
381 savedot = cur_dot;
382 e_setcur();
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 */
391 int nlin;
392 { register int cnt, n, c;
393 int eolstop;
395 if((cnt = nlin+1) <= 0) return;
396 c = 0;
398 { n = scr_wid;
399 eolstop = 0; /* Not yet stopped at EOL */
400 do { if((c = e_rgetc()) == EOF)
401 return;
402 if(c == LF)
404 #if FX_EOLMODE
405 if(eolcrlf(cur_buf))
406 { if((c = e_rgetc()) == CR)
407 { eolstop++;
408 break;
410 if(c != EOF)
411 e_getc();
413 else
414 #endif
415 { eolstop++;
416 break;
419 } while(--n);
420 } while(--cnt);
421 if(eolstop)
423 #if FX_EOLMODE
424 if(eolcrlf(cur_buf)) e_getc(); /* Skip back over CR */
425 #endif
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 */