1: #include "parms.h" 2: #include "structs.h" 3: 4: #ifdef RCSIDENT 5: static char rcsid[] = "$Header: dsply.c,v 1.7.0.4 86/10/12 20:20:17 notes Rel $"; 6: #endif RCSIDENT 7: 8: 9: /* 10: * dspnote(io,note) struct io_f *io; struct note_f *note; 11: * 12: * displays a completely formatted note on the screen. It calls 13: * gettrec to get the text of the note. 14: * 15: * dspresp(io,note,resp,phys,logical) is a little trickier. 16: * 17: * it prints out the response to <note> from response form <resp> 18: * (at index of <resp> of <phys>). <logical> is the logical number 19: * of the note and is displayed. 20: * 21: * Original coding: Rob Kolstad Winter 1980 22: * Modified: Ray Essick December 1981 23: * - reordered display so went top to bottom, left to right 24: * - to facilitate use on dumb terminals (or tty's) 25: */ 26: 27: static char *Anon = "Anonymous"; 28: static char *Fromnews = "(From News system)"; 29: static char *Continued = "-- %2d%% [%ld/%ld] --"; 30: 31: 32: dspnote (io, note, notenum) 33: struct io_f *io; 34: struct note_f *note; 35: { 36: int c, /* character temp */ 37: Rotate; /* whether rotated */ 38: long where; /* for seeking */ 39: struct dsply_f dispbuf; 40: long pagecnt[PAGESAV + 1]; 41: int pagesout; 42: 43: 44: Rotate = 0; /* default non-rotated */ 45: io -> nnotread++; /* bump count of notes read */ 46: pagesout = 0; 47: pagecnt[pagesout] = 0; 48: 49: if (note -> n_addr.addr == 0) 50: dispbuf.d_head.textlen = 0; /* empty text */ 51: else 52: { 53: x (lseek (io -> fidtxt, note -> n_addr.addr, 0) != note -> n_addr.addr, 54: "dsply: bad note seek"); 55: dispbuf.d_head = note -> n_addr; /* get header info */ 56: } 57: 58: dispbuf.outcount = dispbuf.optr = dispbuf.olim = 0; /* fix buffer */ 59: do /* always show the first page */ 60: /* display loop */ 61: { 62: erase (); /* write header crap */ 63: at (1, 1); 64: if (notenum != 0) 65: { 66: if (dispbuf.outcount) /* nth page */ 67: printf ("[Continued] "); 68: printf ("Note %d", notenum); 69: } 70: center (io -> descr.d_title, NNLEN, 1, 40 - NNLEN / 2); 71: if (note -> n_nresp > 0) 72: { 73: at (1, 67); 74: printf ("%d response", note -> n_nresp); 75: if (note -> n_nresp > 1) 76: printf ("s"); 77: } 78: at (2, 1); 79: printf ("%s", note -> n_auth.aname); 80: center (note -> ntitle, TITLEN, 2, 40 - TITLEN / 2); 81: at (2, 59); 82: prdate (¬e -> n_date); 83: if (strcmp (Authsystem, note -> n_auth.asystem) && strcmp (Anon, note -> n_auth.aname)) 84: { 85: at (3, 1); 86: printf ("(at %s)", note -> n_auth.asystem); /* print system name if not local */ 87: } 88: if (note -> n_stat & DIRMES) 89: center (io -> descr.d_drmes, DMLEN, 3, 40 - DMLEN / 2); 90: else 91: if (note -> n_stat & ORPHND) 92: { 93: at (3, 29); 94: printf ("-- (Foster Parent) --"); 95: } 96: else 97: if (note -> n_stat & WRITONLY) 98: { 99: at (3, 31); 100: printf ("-- (Write Only) --"); 101: } 102: if (note -> n_stat & FRMNEWS) 103: { 104: at (3, 59); 105: printf ("%s", Fromnews); 106: } 107: if (dispbuf.d_head.textlen == 0) 108: { 109: c = (-1); 110: break; /* header is it for empties */ 111: } 112: at (4, 1); 113: putc ('\n', stdout); /* make sure soft-tabs work */ 114: c = showit (io, &dispbuf, Rotate); 115: switch (c) 116: { 117: case ' ': /* wants the next page */ 118: if (pagesout < PAGESAV) 119: pagecnt[++pagesout] = dispbuf.outcount; 120: /* save new start */ 121: break; 122: 123: case '-': /* go back to previous */ 124: case '\b': /* backspace has same function */ 125: if (pagesout-- == 0) 126: return c; /* pass the buck */ 127: goto replot; /* else fall into replot */ 128: 129: #ifdef ROTATE 130: case 'R': /* rot-13 the text */ 131: Rotate = !Rotate; /* toggle */ 132: /* and fall into re-plot */ 133: #endif ROTATE 134: replot: /* nasty goto label */ 135: case 'r': 136: case '\014': /* control-L too */ 137: dispbuf.optr = dispbuf.olim = 0; 138: dispbuf.outcount = pagecnt[pagesout]; 139: where = dispbuf.d_head.addr + dispbuf.outcount; 140: x (lseek (io -> fidtxt, where, 0) < 0, "dspnote: bad seek"); 141: break; /* are all set now */ 142: 143: 144: default: /* pass the buck */ 145: return c; 146: } 147: } while (dispbuf.outcount < dispbuf.d_head.textlen); 148: 149: return c; /* didn't field a command */ 150: } 151: 152: /* 153: * Code to print the header and manage the paging of a response 154: * It calls the "showit" routine to print pages of text 155: */ 156: 157: dspresp (io, note, resp, phys, logical, notenum) 158: struct io_f *io; 159: struct note_f *note; 160: struct resp_f *resp; 161: { 162: int c; 163: int Rotate; /* whether rotated */ 164: struct dsply_f dispbuf; 165: 166: long where, 167: pagecnt[PAGESAV + 1]; /* stack for backing up */ 168: int pagesout; 169: 170: Rotate = 0; /* default non-rotated */ 171: io -> nrspread++; /* bump count or responses read */ 172: pagesout = 0; 173: pagecnt[pagesout] = 0; 174: 175: 176: if (resp -> r_addr[phys].addr == 0) 177: dispbuf.d_head.textlen = 0; /* so can get a header */ 178: else 179: { 180: x (lseek (io -> fidtxt, resp -> r_addr[phys].addr, 0) != resp -> r_addr[phys].addr, 181: "dspresp: bad resp seek"); 182: dispbuf.d_head = resp -> r_addr[phys]; /* get header info */ 183: } 184: 185: dispbuf.outcount = dispbuf.optr = dispbuf.olim = 0; /* fix buffer */ 186: do /* always make 1 pass */ 187: { 188: erase (); /* paint the header */ 189: at (1, 1); 190: if (dispbuf.outcount) /* nth page */ 191: printf ("[Continued] "); 192: printf ("Note %d", notenum); 193: center (io -> descr.d_title, NNLEN, 1, 40 - NNLEN / 2); 194: at (2, 1); 195: printf ("%s", resp -> r_auth[phys].aname); 196: at (2, 31); 197: printf ("Response %2d of %2d", logical, note -> n_nresp); 198: at (2, 59); 199: prdate (&resp -> r_when[phys]); 200: if (strcmp (Authsystem, resp -> r_auth[phys].asystem) != 0 && strcmp (Anon, resp -> r_auth[phys].aname) != 0) 201: { 202: at (3, 1); 203: printf ("(at %s)", resp -> r_auth[phys].asystem);/* print sys name if not here */ 204: } 205: if (resp -> r_stat[phys] & DIRMES) 206: center (io -> descr.d_drmes, DMLEN, 3, 40 - DMLEN / 2); 207: if (resp -> r_stat[phys] & FRMNEWS) 208: { 209: at (3, 59); 210: printf ("%s", Fromnews); 211: } 212: if (dispbuf.d_head.textlen == 0) 213: { 214: c = (-1); 215: break; /* header is all for empties */ 216: } 217: at (4, 1); 218: putc ('\n', stdout); /* make sure soft-tabs work */ 219: c = showit (io, &dispbuf, Rotate); 220: switch (c) 221: { 222: case ' ': /* wants the next page */ 223: if (pagesout < PAGESAV) 224: pagecnt[++pagesout] = dispbuf.outcount; 225: /* save new start */ 226: break; 227: 228: case '-': /* go back to previous */ 229: case '\b': /* backspace does the same thing */ 230: if (pagesout-- == 0) 231: return c; /* pass the buck */ 232: goto replot; /* else fall into replot */ 233: 234: #ifdef ROTATE 235: case 'R': /* rot-13 the text */ 236: Rotate = !Rotate; /* toggle */ 237: /* and fall into re-plot */ 238: #endif ROTATE 239: replot: /* nasty goto label */ 240: case 'r': 241: case '\014': /* control-L too */ 242: dispbuf.optr = dispbuf.olim = 0; 243: dispbuf.outcount = pagecnt[pagesout]; 244: where = dispbuf.d_head.addr + dispbuf.outcount; 245: x (lseek (io -> fidtxt, where, 0) < 0, "dspnote: bad seek"); 246: break; /* are all set now */ 247: 248: 249: default: /* pass the buck */ 250: return c; 251: } 252: } while (dispbuf.outcount < dispbuf.d_head.textlen); 253: 254: return c; /* didn't field a command */ 255: } 256: /* 257: * showit 258: * 259: * accepts a pointer to a dsply_f and dumps text until runs out 260: * or the screen is filled. 261: * Counts things like lines, columns, and also prints a "more" line 262: * 263: * Ray Essick June 15, 1982 264: */ 265: 266: showit (io, dbuf, Rotate) 267: struct io_f *io; 268: struct dsply_f *dbuf; 269: int Rotate; 270: { 271: int lines, 272: wides; /* screen fill stuff */ 273: int c; 274: int onechar; 275: 276: lines = 4; /* header eats 4 */ 277: wides = 0; /* start in col 1 */ 278: while (lines < nrows - 1 && dbuf -> outcount < dbuf -> d_head.textlen) 279: { 280: if (intflag) /* user abort? */ 281: { 282: intflag = 0; 283: return (-1); /* back to key processing */ 284: } 285: if (dbuf -> optr == dbuf -> olim) /* buffer is empty */ 286: { 287: x ((dbuf -> olim = read (io -> fidtxt, dbuf -> d_buf.txtbuf, BUFSIZE)) < 0, "dspnote: text read"); 288: dbuf -> optr = 0; 289: } 290: #ifdef ROTATE 291: if (Rotate) 292: { 293: register char cc; 294: cc = dbuf -> d_buf.txtbuf[dbuf -> optr]; 295: if ((cc >= 'a' && cc <= 'm') || (cc >= 'A' && cc <= 'M')) 296: cc += ROTATE; 297: else 298: if ((cc >= 'n' && cc <= 'z') || (cc >= 'N' && cc <= 'Z')) 299: cc -= ROTATE; 300: onechar = cc; 301: } 302: else 303: #endif ROTATE 304: { 305: onechar = dbuf -> d_buf.txtbuf[dbuf -> optr]; 306: } 307: /* show the character */ 308: dbuf -> optr++; /* advance ptr */ 309: dbuf -> outcount++; 310: /* 311: * look at the output character and do any massaging 312: */ 313: if (onechar != '\014') /* suppress ^l */ 314: putc (onechar, stdout); 315: switch (onechar) /* some special chars */ 316: { 317: case '\n': /* next line */ 318: if (isinput ()) /* PLATO-brand erase-abort */ 319: goto exisho; 320: wides = 0; 321: lines++; 322: break; 323: 324: case '\014': /* force next page */ 325: lines = nrows; /* forces loop exit */ 326: break; 327: 328: case '\t': /* almost forgot tabs */ 329: wides += (8 - (wides % 8)); /* tab stops */ 330: break; 331: 332: case '\b': /* perverts using backspaces */ 333: wides--; 334: break; 335: 336: default: /* dull characters */ 337: wides++; 338: break; 339: } 340: if (wides >= ncols) /* test line overflow */ 341: { 342: lines++; 343: wides = 0; 344: } 345: } 346: exisho: /* typeahead exit */ 347: if (dbuf -> outcount < dbuf -> d_head.textlen) 348: { 349: at (0, 52); 350: printf (Continued, 351: (int) ((long) (dbuf -> outcount * 100L) 352: / (long) dbuf -> d_head.textlen), 353: (long) dbuf -> outcount, (long) dbuf -> d_head.textlen); 354: } 355: at (0, 1); /* grab command */ 356: #ifdef PROMPT 357: printf ("%s", PROMPT); 358: #endif 359: c = gchar (); /* grab command */ 360: printf ("\b \b"); 361: return c; /* so let caller handle it */ 362: }