|
|
1.1 root 1: #include <X/mit-copyright.h>
2:
3: /* Copyright Massachusetts Institute of Technology 1984, 1985 */
4:
5: /* util.c */
6:
7: #ifndef lint
8: static char *rcsid_util_c = "$Header: util.c,v 10.11 86/04/28 15:05:29 jg Exp $";
9: #endif lint
10:
11: #include <stdio.h>
12: #include <X/Xlib.h>
13: #include <errno.h>
14: #include <signal.h>
15:
16: #include "ptyx.h"
17:
18: extern errno;
19: extern debug;
20: #ifdef JUMPSCROLL
21: /*
22: * These routines are used for the jump scroll feature
23: */
24: FlushScroll(screen)
25: register Screen *screen;
26: {
27: register int height = screen->bot_marg - screen->top_marg + 1;
28: register int samount = screen->scroll_amt;
29: register int ramount = screen->refresh_amt;
30: register int scrolled = samount * screen->f_height;
31: register int refreshed = ramount * screen->f_height;
32: register int top = screen->top_marg * screen->f_height + screen->border;
33: int rtop;
34:
35: if(samount > 0) {
36: rtop = screen->bot_marg - ramount + 1;
37: } else {
38: rtop = screen->top_marg;
39: top -= scrolled;
40: ramount = -ramount;
41: refreshed = -refreshed;
42: }
43:
44: if (ramount != height) {
45:
46: if (screen->multiscroll && samount == 1 &&
47: screen->top_marg == 0 && screen->bot_marg == screen->max_row) {
48: if (screen->incopy < 0 && screen->scrolls == 0)
49: CopyWait (screen);
50: screen->scrolls++;
51: } else {
52: if (screen->incopy)
53: CopyWait (screen);
54: screen->incopy = -1;
55: }
56:
57: XMoveArea (screen->window,
58: screen->border, top + scrolled, screen->border, top,
59: screen->width, height * screen->f_height - refreshed);
60: }
61: screen->scroll_amt = 0;
62: screen->refresh_amt = 0;
63: XTileSet (screen->window, screen->border,
64: rtop * screen->f_height + screen->border,
65: screen->width, refreshed, screen->bgndtile);
66: ScrnRefresh(screen, rtop, 0, ramount, screen->max_col + 1);
67: }
68:
69: AddToRefresh(screen)
70: register Screen *screen;
71: {
72: register int amount = screen->refresh_amt;
73: register int row = screen->cur_row;
74:
75: if(amount == 0)
76: return(0);
77: if(amount > 0) {
78: register int bottom;
79:
80: if(row == (bottom = screen->bot_marg) - amount) {
81: screen->refresh_amt++;
82: return(1);
83: }
84: return(row >= bottom - amount + 1 && row <= bottom);
85: } else {
86: register int top;
87:
88: amount = -amount;
89: if(row == (top = screen->top_marg) + amount) {
90: screen->refresh_amt--;
91: return(1);
92: }
93: return(row <= top + amount - 1 && row >= top);
94: }
95: }
96: #endif JUMPSCROLL
97:
98: /*
99: * scrolls the screen by amount lines, erases bottom, doesn't alter
100: * cursor position (i.e. cursor moves down amount relative to text).
101: * All done within the scrolling region, of course.
102: * requires: amount > 0
103: */
104: Scroll (screen, amount)
105: register Screen *screen;
106: register int amount;
107: {
108: register int height = screen->bot_marg - screen->top_marg + 1;
109: register int covered;
110: register int border = screen->border;
111: register int top = screen->top_marg * screen->f_height + border;
112:
113: if (amount > height)
114: amount = height;
115: #ifdef JUMPSCROLL
116: if(screen->jumpscroll) {
117: if(screen->scroll_amt > 0) {
118: if(screen->refresh_amt + amount > height)
119: FlushScroll(screen);
120: screen->scroll_amt += amount;
121: screen->refresh_amt += amount;
122: } else {
123: if(screen->scroll_amt < 0)
124: FlushScroll(screen);
125: screen->scroll_amt = amount;
126: screen->refresh_amt = amount;
127: }
128: } else {
129: #endif JUMPSCROLL
130:
131: if (amount == height) {
132: ClearScreen(screen);
133: return;
134: }
135:
136: covered = amount * screen->f_height;
137:
138: if (screen->multiscroll
139: && amount==1
140: && screen->top_marg==0
141: && screen->bot_marg==screen->max_row) {
142: if (screen->incopy<0 && screen->scrolls==0)
143: CopyWait(screen);
144: screen->scrolls++;
145: } else {
146: if (screen->incopy)
147: CopyWait(screen);
148: screen->incopy = -1;
149: }
150:
151: XMoveArea(screen->window, border, top + covered, border, top,
152: screen->width, height * screen->f_height - covered);
153: XTileSet(screen->window, border,
154: (screen->bot_marg - amount + 1) * screen->f_height + border,
155: screen->width, covered, screen->bgndtile);
156: #ifdef JUMPSCROLL
157: }
158: #endif JUMPSCROLL
159:
160: ScrnDeleteLine(screen->buf, screen->bot_marg, screen->top_marg,
161: amount, screen->max_col + 1);
162: }
163:
164:
165: /*
166: * Reverse scrolls the screen by amount lines, erases top, doesn't alter
167: * cursor position (i.e. cursor moves up amount relative to text).
168: * All done within the scrolling region, of course.
169: * Requires: amount > 0
170: */
171: RevScroll(screen, amount)
172: register Screen *screen;
173: register int amount;
174: {
175: register int height = screen->bot_marg - screen->top_marg + 1;
176: register int border = screen->border;
177: register int top = screen->top_marg * screen->f_height + border;
178: register int covered;
179:
180: amount = (amount < height) ? amount : height;
181: #ifdef JUMPSCROLL
182: if(screen->jumpscroll) {
183: if(screen->scroll_amt < 0) {
184: if(-screen->refresh_amt + amount > height)
185: FlushScroll(screen);
186: screen->scroll_amt -= amount;
187: screen->refresh_amt -= amount;
188: } else {
189: if(screen->scroll_amt > 0)
190: FlushScroll(screen);
191: screen->scroll_amt = -amount;
192: screen->refresh_amt = -amount;
193: }
194: } else {
195: #endif JUMPSCROLL
196: covered = amount * screen->f_height;
197:
198: if (screen->incopy)
199: CopyWait (screen);
200: screen->incopy = -1;
201:
202: XMoveArea (screen->window,
203: border, top,
204: border, top + covered,
205: screen->width, height * screen->f_height - covered);
206: XTileSet (screen->window,
207: border, top,
208: screen->width, covered,
209: screen->bgndtile);
210:
211: #ifdef JUMPSCROLL
212: }
213: #endif JUMPSCROLL
214: ScrnInsertLine (screen->buf, screen->bot_marg, screen->top_marg,
215: amount, screen->max_col + 1);
216: }
217:
218: /*
219: * If cursor not in scrolling region, returns. Else,
220: * inserts n blank lines at the cursor's position. Lines above the
221: * bottom margin are lost.
222: */
223: InsertLine (screen, n)
224: register Screen *screen;
225: register int n;
226: {
227: register int height;
228: register int bottom = screen->bot_marg;
229:
230: if (screen->cur_row < screen->top_marg ||
231: screen->cur_row > screen->bot_marg) return;
232:
233: if (screen->cur_row + n - 1 > bottom) n = bottom - screen->cur_row + 1;
234: #ifdef JUMPSCROLL
235: if(screen->jumpscroll) {
236: if(screen->scroll_amt <= 0&&screen->cur_row <= -screen->refresh_amt) {
237: if(-screen->refresh_amt + n > height)
238: FlushScroll(screen);
239: screen->scroll_amt -= n;
240: screen->refresh_amt -= n;
241: } else if(screen->scroll_amt)
242: FlushScroll(screen);
243: }
244: if(!screen->scroll_amt) {
245: #endif JUMPSCROLL
246:
247:
248: height = n * screen->f_height;
249:
250: screen->do_wrap = 0;
251:
252: if (screen->incopy)
253: CopyWait (screen);
254: screen->incopy = -1;
255:
256: /*
257: * move stuff down.
258: * clear hole.
259: */
260: XMoveArea(screen->window,
261: screen->border, CursorY (screen),
262: screen->border, CursorY (screen) + height,
263: screen->width,
264: (bottom + 1 - screen->cur_row - n) * screen->f_height);
265: XTileSet(screen->window,
266: screen->border, CursorY (screen),
267: screen->width, height, screen->bgndtile);
268:
269: #ifdef JUMPSCROLL
270: }
271: #endif JUMPSCROLL
272: /* adjust screen->buf */
273: ScrnInsertLine(screen->buf, bottom, screen->cur_row, n,
274: screen->max_col + 1);
275: }
276:
277: /*
278: * If cursor not in scrolling region, returns. Else, deletes n lines
279: * at the cursor's position, lines added at bottom margin are blank.
280: */
281: DeleteLine(screen, n)
282: register Screen *screen;
283: register int n;
284: {
285: register int height;
286: register int bottom = screen->bot_marg;
287:
288: if (screen->cur_row < screen->top_marg
289: || screen->cur_row > screen->bot_marg)
290: return;
291:
292: if (screen->cur_row + n - 1 > bottom)
293: n = bottom - screen->cur_row + 1;
294: #ifdef JUMPSCROLL
295: if(screen->jumpscroll) {
296: if(screen->scroll_amt >= 0 && screen->cur_row == screen->top_marg) {
297: if(screen->refresh_amt + n > height)
298: FlushScroll(screen);
299: screen->scroll_amt += n;
300: screen->refresh_amt += n;
301: } else if(screen->scroll_amt)
302: FlushScroll(screen);
303: }
304: if(!screen->scroll_amt) {
305: #endif JUMPSCROLL
306:
307: height = n * screen->f_height;
308: screen->do_wrap = 0;
309:
310: if (screen->incopy)
311: CopyWait(screen);
312: screen->incopy = -1;
313:
314: /*
315: * move stuff up.
316: * clear bottom.
317: */
318: XMoveArea(screen->window,
319: screen->border, CursorY (screen) + height,
320: screen->border, CursorY (screen),
321: screen->width,
322: (bottom + 1 - screen->cur_row - n) * screen->f_height);
323: XTileSet(screen->window,
324: screen->border,
325: (bottom + 1 - n) * screen->f_height + screen->border,
326: screen->width, height, screen->bgndtile);
327:
328: #ifdef JUMPSCROLL
329: }
330: #endif JUMPSCROLL
331: /* adjust screen->buf */
332: ScrnDeleteLine(screen->buf, bottom, screen->cur_row, n,
333: screen->max_col + 1);
334: }
335:
336: /*
337: * Insert n blanks at the cursor's position, no wraparound.
338: */
339: InsertChar (screen, n)
340: register Screen *screen;
341: register int n;
342: {
343: register int width = n * screen->f_width;
344:
345: #ifdef JUMPSCROLL
346: if(!AddToRefresh(screen)) {
347: if(screen->scroll_amt)
348: FlushScroll(screen);
349: #endif JUMPSCROLL
350:
351: screen->do_wrap = 0;
352:
353: if (screen->incopy)
354: CopyWait (screen);
355: screen->incopy = -1;
356:
357: XMoveArea(screen->window,
358: CursorX (screen), CursorY (screen),
359: CursorX (screen) + width, CursorY (screen),
360: screen->width - (screen->cur_col + n) * screen->f_width,
361: screen->f_height);
362: XTileSet(screen->window,
363: CursorX (screen), CursorY (screen),
364: width, screen->f_height, screen->bgndtile);
365:
366: #ifdef JUMPSCROLL
367: }
368: #endif JUMPSCROLL
369: /* adjust screen->buf */
370: ScrnInsertChar(screen->buf, screen->cur_row, screen->cur_col, n,
371: screen->max_col + 1);
372: }
373:
374: /*
375: * Deletes n chars at the cursor's position, no wraparound.
376: */
377: DeleteChar (screen, n)
378: register Screen *screen;
379: register int n;
380: {
381: register int width;
382:
383: if (screen->cur_col + n > screen->max_col + 1)
384: n = screen->max_col + 1 - screen->cur_col;
385:
386: #ifdef JUMPSCROLL
387: if(!AddToRefresh(screen)) {
388: if(screen->scroll_amt)
389: FlushScroll(screen);
390: #endif JUMPSCROLL
391:
392: width = n * screen->f_width;
393:
394: screen->do_wrap = 0;
395:
396: if (screen->incopy)
397: CopyWait (screen);
398: screen->incopy = -1;
399:
400: XMoveArea(screen->window,
401: CursorX (screen) + width, CursorY (screen),
402: CursorX (screen), CursorY (screen),
403: screen->width - (screen->cur_col + n) * screen->f_width,
404: screen->f_height);
405: XTileSet (screen->window,
406: screen->border + screen->width - width, CursorY (screen),
407: width, screen->f_height, screen->bgndtile);
408:
409: #ifdef JUMPSCROLL
410: }
411: #endif JUMPSCROLL
412: /* adjust screen->buf */
413: ScrnDeleteChar (screen->buf, screen->cur_row, screen->cur_col, n,
414: screen->max_col + 1);
415:
416: }
417:
418: /*
419: * Clear from cursor position to beginning of display, inclusive.
420: */
421: ClearAbove (screen)
422: register Screen *screen;
423: {
424: #ifdef JUMPSCROLL
425: if(screen->scroll_amt)
426: FlushScroll(screen);
427: #endif JUMPSCROLL
428: ClearLeft(screen);
429:
430: XTileSet(screen->window, screen->border, 0,
431: screen->width, CursorY (screen), screen->bgndtile);
432: ClearBufRows(screen, 0, screen->cur_row - 1);
433: }
434:
435: /*
436: * Clear from cursor position to end of display, inclusive.
437: */
438: ClearBelow (screen)
439: register Screen *screen;
440: {
441: register int sy = CursorY (screen) + screen->f_height;
442:
443: #ifdef JUMPSCROLL
444: if(screen->scroll_amt)
445: FlushScroll(screen);
446: #endif JUMPSCROLL
447: ClearRight(screen);
448: XTileSet(screen->window, screen->border, sy,
449: screen->width, screen->height - sy + screen->border,
450: screen->bgndtile);
451: ClearBufRows(screen, screen->cur_row + 1, screen->max_row);
452: }
453:
454: /*
455: * Clear last part of cursor's line, inclusive.
456: */
457: ClearRight (screen)
458: register Screen *screen;
459: {
460: screen->do_wrap = 0;
461:
462: #ifdef JUMPSCROLL
463: if(!AddToRefresh(screen)) {
464: if(screen->scroll_amt)
465: FlushScroll(screen);
466: #endif JUMPSCROLL
467: XTileSet(screen->window,
468: CursorX (screen), CursorY (screen),
469: screen->width-screen->cur_col * screen->f_width,screen->f_height,
470: screen->bgndtile);
471: #ifdef JUMPSCROLL
472: }
473: #endif JUMPSCROLL
474: bzero((char *)(screen->buf [screen->cur_row] + screen->cur_col),
475: sizeof (short) * (screen->max_col - screen->cur_col + 1));
476: }
477:
478: /*
479: * Clear first part of cursor's line, inclusive.
480: */
481: ClearLeft (screen)
482: register Screen *screen;
483: {
484: screen->do_wrap = 0;
485:
486: #ifdef JUMPSCROLL
487: if(!AddToRefresh(screen)) {
488: if(screen->scroll_amt)
489: FlushScroll(screen);
490: #endif JUMPSCROLL
491:
492: XTileSet (screen->window,
493: screen->border, CursorY (screen),
494: (screen->cur_col + 1) * screen->f_width,
495: screen->f_height, screen->bgndtile);
496: #ifdef JUMPSCROLL
497: }
498: #endif JUMPSCROLL
499: bzero ((char *)screen->buf [screen->cur_row],
500: sizeof (short) * (screen->cur_col + 1));
501: }
502:
503: /*
504: * Erase the cursor's line.
505: */
506: ClearLine(screen)
507: register Screen *screen;
508: {
509: screen->do_wrap = 0;
510:
511: #ifdef JUMPSCROLL
512: if(!AddToRefresh(screen)) {
513: if(screen->scroll_amt)
514: FlushScroll(screen);
515: #endif JUMPSCROLL
516: XTileSet (screen->window,
517: screen->border, CursorY (screen),
518: screen->width, screen->f_height, screen->bgndtile);
519: #ifdef JUMPSCROLL
520: }
521: #endif JUMPSCROLL
522: bzero ((char *)screen->buf [screen->cur_row],
523: sizeof (short) * (screen->max_col + 1));
524: }
525:
526: ClearScreen(screen)
527: register Screen *screen;
528: {
529: screen->do_wrap = 0;
530:
531: #ifdef JUMPSCROLL
532: if(screen->scroll_amt)
533: FlushScroll(screen);
534: #endif JUMPSCROLL
535: XClear(screen->window);
536: ClearBufRows (screen, 0, screen->max_row);
537: }
538:
539: CopyWait(screen)
540: register Screen *screen;
541: {
542: XEvent reply;
543: XEvent *rep = &reply;
544:
545: while (1) {
546: XWindowEvent (screen->window, ExposeRegion|ExposeCopy, &reply);
547: switch (reply.type) {
548: case ExposeRegion:
549: if (((XExposeEvent *)rep)->detail == ExposeCopy &&
550: screen->incopy <= 0) {
551: screen->incopy = 1;
552: if (screen->scrolls > 0)
553: screen->scrolls--;
554: }
555: HandleExposure (screen, &reply);
556: break;
557: case ExposeCopy:
558: if (screen->incopy <= 0 && screen->scrolls > 0)
559: screen->scrolls--;
560: if (screen->scrolls == 0) {
561: screen->incopy = 0;
562: return;
563: }
564: screen->incopy = -1;
565: break;
566: }
567: }
568: }
569: /*
570: * This routine handles exposure events
571: */
572: HandleExposure (screen, reply)
573: register Screen *screen;
574: register XExposeEvent *reply;
575: {
576: int toprow, leftcol, nrows, ncols;
577: extern Terminal term; /* kludge */
578: XExposeRegionEvent event;
579:
580: toprow = (reply->y - screen->border) / screen->f_height;
581: leftcol = (reply->x - screen->border) / screen->f_width;
582: nrows = (reply->y + reply->height - 1 - screen->border) /
583: screen->f_height - toprow + 1;
584: ncols = (reply->x + reply->width - 1 - screen->border) /
585: screen->f_width - leftcol + 1;
586: toprow -= screen->scrolls;
587: if (toprow < 0) {
588: nrows += toprow;
589: toprow = 0;
590: }
591: if (toprow + nrows - 1 > screen->max_row)
592: nrows = screen->max_row - toprow + 1;
593: if (leftcol + ncols - 1 > screen->max_col)
594: ncols = screen->max_col - leftcol + 1;
595:
596: if (nrows > 0 && ncols > 0) {
597: if (screen->TekEmu && reply->detail != ExposeCopy)
598: /* Clear to avoid possible dangling cursor */
599: XTileSet (screen->window,
600: leftcol * screen->f_width + screen->border,
601: toprow * screen->f_height + screen->border,
602: ncols * screen->f_width,
603: nrows * screen->f_height,
604: screen->bgndtile);
605: ScrnRefresh (screen, toprow, leftcol, nrows, ncols);
606: /* only do the tek refresh on the last refresh event */
607: if (screen->TekEmu) {
608: XSync(0); /* make sure they are all here */
609: if (XPending() != 0) {
610: XPeekEvent(&event);
611: if (event.type != ExposeRegion) {
612: if (reply->detail != ExposeCopy)
613: TekRefresh(&term);
614: }
615: }
616: else {
617: if (reply->detail != ExposeCopy)
618: TekRefresh (&term);
619: }
620: }
621: if (screen->cur_row >= toprow &&
622: screen->cur_row < toprow + nrows &&
623: screen->cur_col >= leftcol &&
624: screen->cur_col < leftcol + ncols)
625: return (1);
626: }
627: return (0);
628: }
629:
630: Panic(s, a)
631: char *s;
632: {
633: fprintf(stderr, "PANIC! ");
634: fprintf(stderr, s, a);
635: fprintf(stderr, "\r\n");
636: fflush(stderr);
637: }
638:
639: Error ()
640: {
641: fprintf (stderr, "Error %d: ", errno);
642: perror ("");
643: Cleanup(66);
644: }
645:
646: /*
647: * cleanup by sending SIGHUP to client processes
648: */
649: Cleanup (code)
650: int code;
651: {
652: extern Terminal term;
653: register Screen *screen;
654: register long pgrp;
655: screen = &term.screen;
656: if (screen->pid > 1) {
657: pgrp = getpgrp(screen->pid);
658: if (pgrp > 1) killpg(pgrp, SIGHUP);
659: }
660: exit(code);
661: }
662:
663: /*
664: * sets the value of var to be arg in the Unix 4.2 BSD environment env.
665: * Var should end with '=' (bindings are of the form "var=value").
666: * This procedure assumes the memory for the first level of environ
667: * was allocated using malloc.
668: */
669: Setenv (var, value)
670: register char *var, *value;
671: {
672: extern char **environ;
673: register int index = 0;
674:
675: while (environ [index] != NULL) {
676: if (strncmp (environ [index], var, strlen (var)) == 0) {
677: /* found it */
678: environ [index] = (char *) malloc (strlen (var) + strlen (value));
679: strcpy (environ [index], var);
680: strcat (environ [index], value);
681: return;
682: }
683: index ++;
684: }
685:
686: if (debug) printf ("expanding env\n");
687: environ = (char **) realloc((char *)environ, sizeof(char *) * (index+2));
688: if (environ == NULL) {
689: fprintf (stderr, "Setenv: malloc out of memory\n");
690: exit (1);
691: }
692:
693: environ [index] = (char *) malloc (strlen (var) + strlen (value));
694: strcpy (environ [index], var);
695: strcat (environ [index], value);
696: environ [++index] = NULL;
697: }
698:
699: /*
700: * returns a pointer to the first occurrence of s2 in s1,
701: * or NULL if there are none.
702: */
703: char *strindex (s1, s2)
704: register char *s1, *s2;
705: {
706: register char *s3;
707: char *index();
708:
709: while ((s3=index(s1, *s2)) != NULL) {
710: if (strncmp(s3, s2, strlen(s2)) == 0)
711: return (s3);
712: s1 = ++s3;
713: }
714: return (NULL);
715: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.