1: #include "parms.h" 2: #include "structs.h" 3: 4: #ifdef RCSIDENT 5: static char rcsid[] = "$Header: dsply.c,v 1.7.0.2 85/03/18 20:54:06 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 = "-- more %d%% --"; 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: 275: lines = 4; /* header eats 4 */ 276: wides = 0; /* start in col 1 */ 277: while (lines < nrows - 1 && dbuf -> outcount < dbuf -> d_head.textlen) 278: { 279: if (intflag) /* user abort? */ 280: { 281: intflag = 0; 282: return (-1); /* back to key processing */ 283: } 284: if (dbuf -> optr == dbuf -> olim) /* buffer is empty */ 285: { 286: x ((dbuf -> olim = read (io -> fidtxt, dbuf -> d_buf.txtbuf, BUFSIZE)) < 0, "dspnote: text read"); 287: dbuf -> optr = 0; 288: } 289: #ifdef ROTATE 290: if (Rotate) 291: { 292: register char cc; 293: cc = dbuf -> d_buf.txtbuf[dbuf -> optr]; 294: if ((cc >= 'a' && cc <= 'm') || (cc >= 'A' && cc <= 'M')) 295: cc += ROTATE; 296: else 297: if ((cc >= 'n' && cc <= 'z') || (cc >= 'N' && cc <= 'Z')) 298: cc -= ROTATE; 299: putc (cc, stdout); 300: } 301: else 302: #endif ROTATE 303: { 304: putc (dbuf -> d_buf.txtbuf[dbuf -> optr], stdout); 305: } 306: /* show the character */ 307: dbuf -> outcount++; 308: switch (dbuf -> d_buf.txtbuf[dbuf -> optr++]) /* some special chars */ 309: { 310: case '\n': /* next line */ 311: if (isinput ()) /* PLATO-brand erase-abort */ 312: goto exisho; 313: wides = 0; 314: lines++; 315: break; 316: 317: case '\014': /* force next page */ 318: lines = nrows; /* forces loop exit */ 319: break; 320: 321: case '\t': /* almost forgot tabs */ 322: wides += (8 - (wides % 8)); /* tab stops */ 323: break; 324: 325: case '\b': /* perverts using backspaces */ 326: wides--; 327: break; 328: 329: default: /* dull characters */ 330: wides++; 331: break; 332: } 333: if (wides >= ncols) /* test line overflow */ 334: { 335: lines++; 336: wides = 0; 337: } 338: } 339: exisho: /* typeahead exit */ 340: if (dbuf -> outcount < dbuf -> d_head.textlen) 341: { 342: at (0, 60); 343: printf (Continued, 344: (int) (dbuf -> outcount * 100L / (long) dbuf -> d_head.textlen)); 345: } 346: at (0, 1); /* grab command */ 347: #ifdef PROMPT 348: printf ("%s", PROMPT); 349: #endif 350: c = gchar (); /* grab command */ 351: printf ("\b \b"); 352: return c; /* so let caller handle it */ 353: }