home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume19 / Xod / part02 < prev    next >
Encoding:
Text File  |  1993-04-28  |  63.8 KB  |  2,168 lines

  1. Newsgroups: comp.sources.x
  2. From: rfs@se28.wg2.waii.com (Robert Starr)
  3. Subject: v19i019:  Xod - Octal dump for Xwindows, Part02/04
  4. Message-ID: <1993Mar9.211138.21863@sparky.imd.sterling.com>
  5. X-Md4-Signature: 78f4579231989a98cf0c7290c2ec53fc
  6. Date: Tue, 9 Mar 1993 21:11:38 GMT
  7. Approved: chris@sparky.imd.sterling.com
  8.  
  9. Submitted-by: rfs@se28.wg2.waii.com (Robert Starr)
  10. Posting-number: Volume 19, Issue 19
  11. Archive-name: Xod/part02
  12. Environment: X11R4 X11R5 gcc
  13.  
  14. ---- Cut Here and unpack ----
  15. #!/bin/sh
  16. # this is part 2 of a multipart archive
  17. # do not concatenate these parts, unpack them in order with /bin/sh
  18. # file ctw.c continued
  19. #
  20. CurArch=2
  21. if test ! -r s2_seq_.tmp
  22. then echo "Please unpack part 1 first!"
  23.      exit 1; fi
  24. ( read Scheck
  25.   if test "$Scheck" != $CurArch
  26.   then echo "Please unpack part $Scheck next!"
  27.        exit 1;
  28.   else exit 0; fi
  29. ) < s2_seq_.tmp || exit 1
  30. echo "x - Continuing file ctw.c"
  31. sed 's/^X//' << 'SHAR_EOF' >> ctw.c
  32. X        reason.len = 3;
  33. X        }
  34. X    else if (IsFunctionKey(keysym) || IsMiscFunctionKey(keysym) ||
  35. X        keysym == XK_Prior || keysym == XK_Next) {
  36. X        *rp++ = ESC;
  37. X        *rp++ = '[';
  38. X        if (cw->ctw.sun_function_keys) {
  39. X            sprintf(rp, "%dz", sunfuncvalue(keysym));
  40. X            }
  41. X        else {
  42. X            sprintf(rp, "%d~", funcvalue(keysym));
  43. X            }
  44. X        rp += strlen(rp);
  45. X        reason.len = rp - reply;
  46. X        }
  47. X    else if (nbytes > 0) {
  48. X        reason.ptr = buf;
  49. X        reason.len = nbytes;
  50. X        }
  51. X
  52. X    if (reason.len)
  53. X        XtCallCallbacks((Widget)w, XtNkbdCallback, (caddr_t) &reason);
  54. X}
  55. Xstatic void
  56. Xredisplay(Widget w, XExposeEvent *event) {
  57. X    exposed_region((CtwWidget)w, event->x, event->y, event->width, 
  58. X        event->height);
  59. X}
  60. X/**********************************************************************/
  61. X/*   Action routine to handle redrawing of window.              */
  62. X/**********************************************************************/
  63. Xstatic void 
  64. XCtwExpose(Widget w, XEvent *event, String *x, Cardinal *y) {
  65. X    CtwWidget    cw = (CtwWidget) w;
  66. X
  67. X    if (!XtIsRealized(w) /*|| need_resize*/)
  68. X        return;
  69. X    /***********************************************/
  70. X    /*   If  window  has  changed  size,  then we  */
  71. X    /*   need  to  resize  it.  Also  we  need to  */
  72. X    /*   clear  any  garbage  which may be at the  */
  73. X    /*   bottom or right edge of the window.       */
  74. X    /***********************************************/
  75. X    if (cw->ctw.win_height_allocated != cw->core.height ||
  76. X        cw->ctw.win_width_allocated != cw->core.width) {
  77. X/*        need_resize = TRUE;*/
  78. X        cw->ctw.win_height_allocated = cw->core.height;
  79. X        cw->ctw.win_width_allocated = cw->core.width;
  80. X        return;
  81. X        }
  82. X    redisplay(w, (XExposeEvent *)event);
  83. X}
  84. Xint
  85. Xctw_set_font(Widget w, char *font_name) {
  86. X    XFontStruct    *font;
  87. X    CtwWidget    cw = (CtwWidget) w;
  88. X    Display    *dpy = XtDisplay(cw);
  89. X    Arg    args[20];
  90. X    int    n;
  91. X        
  92. X    if ((font = XLoadQueryFont(dpy, font_name)) == NULL)
  93. X        return -1;
  94. X    cw->ctw.fontp = font;
  95. X    XSetFont(dpy, cw->ctw.gc, font->fid);
  96. X
  97. X    reset_font((CtwWidget)w, TRUE);
  98. X
  99. X    n = 0;
  100. X    XtSetArg(args[n], XtNwidthInc, cw->ctw.font_width); n++;
  101. X    XtSetArg(args[n], XtNheightInc, cw->ctw.font_height); n++;
  102. X    XtSetValues(XtParent(cw), args, n);
  103. X
  104. X    return 0;
  105. X}
  106. X/**********************************************************************/
  107. X/*   Common code to handle a change in the font.              */
  108. X/**********************************************************************/
  109. Xstatic int
  110. Xreset_font(CtwWidget w, int delete_flag) {
  111. X    w->ctw.font_height = w->ctw.fontp->ascent + w->ctw.fontp->descent;
  112. X    w->ctw.font_width = XTextWidth(w->ctw.fontp, "A", 1);
  113. X    return 0;
  114. X}
  115. X/**********************************************************************/
  116. X/*   Function to allocate color pixels.                      */
  117. X/**********************************************************************/
  118. Xstatic int
  119. Xsetup_x11_colors(Display *dpy) {
  120. X    static int first_time = TRUE;
  121. X    static int is_color;
  122. X
  123. X    Colormap    default_color_map;
  124. X    int    default_depth;
  125. X    XColor        exact_def;
  126. X    int        i;
  127. X    static char    *color_tbl[] = {
  128. X  "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white", 
  129. X  "dim gray", "red", "green", "yellow", "blue", "magenta", "cyan", "white", 
  130. X        NULL
  131. X        };
  132. X    static char    *mono_tbl[] = {
  133. X  "black", "gray80", "gray85", "gray90", "gray95", "gray96", "gray98", "white",
  134. X  "black", "gray80", "gray85", "gray90", "gray95", "gray96", "gray98", "white",
  135. X        NULL
  136. X        };
  137. X    char    **color_names = color_tbl;
  138. X
  139. X    if (!first_time)
  140. X        return is_color;
  141. X    first_time = FALSE;
  142. X    default_color_map = DefaultColormap(dpy, DefaultScreen(dpy));
  143. X    /***********************************************/
  144. X    /*   If  we've  got  a  mono-only screen then  */
  145. X    /*   set  up  the  flag  saying whether we're  */
  146. X    /*   running on mono or color screen.           */
  147. X    /***********************************************/
  148. X    default_depth = DefaultDepth(dpy, DefaultScreen(dpy));
  149. X    if (default_depth == 1 || getenv("CRMONO") != (char *) NULL) {
  150. X        color_names = mono_tbl;
  151. X        is_color = FALSE;
  152. X        }
  153. X    else
  154. X        is_color = TRUE;
  155. X
  156. X    for (i = 0; color_names[i]; i++) {
  157. X        if (!XParseColor(dpy, default_color_map, color_names[i], &exact_def)) {
  158. X            fprintf(stderr, "Color name %s not in database.\n",
  159. X                color_names[i]);
  160. X            exit(0);
  161. X            }
  162. X        if (!XAllocColor(dpy, default_color_map, &exact_def)) {
  163. X            fprintf(stderr, "Can't allocate color: %s -- all color cells allocated.\n",
  164. X                color_names[i]);
  165. X            exit(1);
  166. X            }
  167. X        x11_colors[i] = exact_def.pixel;
  168. X        }
  169. X    return is_color;
  170. X}
  171. X/**********************************************************************/
  172. X/*   Handle exposure events. Redraw appropriate sections of window.   */
  173. X/**********************************************************************/
  174. Xstatic void
  175. Xexposed_region(CtwWidget w, int x, int y, int width, int height) {
  176. X    int    start_row, start_col;
  177. X    int    end_row, end_col;
  178. X
  179. X    /***********************************************/
  180. X    /*   Convert     pixel     co-ordinates    to  */
  181. X    /*   character positions.               */
  182. X    /***********************************************/
  183. X    get_xy(w, &start_row, &start_col, x, y);
  184. X    get_xy(w, &end_row, &end_col, x + width, y + height);
  185. X
  186. X    update_region(w, start_row, start_col, end_row + 1, end_col + 1);
  187. X    /***********************************************/
  188. X    /*   Redraw cursor if we just obliterated it.  */
  189. X    /***********************************************/
  190. X    if (start_row <= w->ctw.y && w->ctw.y <= end_row + 1 &&
  191. X        start_col <= w->ctw.x && w->ctw.x <= end_col + 1)
  192. X            show_cursor(w);
  193. X}
  194. X/**********************************************************************/
  195. X/*   Function to allocate (or re-allocate) screen memory structure.   */
  196. X/**********************************************************************/
  197. Xstatic void
  198. Xalloc_screen(CtwWidget w, int clear_flag) {
  199. X    int    i, j, c;
  200. X    int    rows;
  201. X    ctw_callback_t    reason;
  202. X    vbyte_t    **old_lines = (vbyte_t **) NULL;
  203. X    vbyte_t    *old_memory = (vbyte_t *) NULL;
  204. X
  205. X    turn_off_cursor(w);
  206. X    /***********************************************/
  207. X    /*   Dont  do  anything if screen is the same  */
  208. X    /*   size.                       */
  209. X    /***********************************************/
  210. X    if (w->ctw.rows == w->ctw.old_rows && w->ctw.columns == w->ctw.old_columns)
  211. X        return;
  212. X
  213. X    /***********************************************/
  214. X    /*   Save  copy  of  old  screen  contents in  */
  215. X    /*   case   we   want  to  keep  as  much  as  */
  216. X    /*   possible.                       */
  217. X    /***********************************************/
  218. X    old_memory = w->ctw.memory;
  219. X    old_lines = w->ctw.lines;
  220. X
  221. X    rows = w->ctw.rows + w->ctw.max_lines;
  222. X    w->ctw.memory = (vbyte_t *) 
  223. X        chk_alloc(rows * w->ctw.columns * sizeof(vbyte_t));
  224. X    w->ctw.orig_lines = (vbyte_t **) chk_alloc(rows * sizeof(vbyte_t *));
  225. X    w->ctw.lines = w->ctw.orig_lines;
  226. X    for (i = 0; i < rows; i++) {
  227. X        w->ctw.lines[i] = &w->ctw.memory[i * w->ctw.columns];
  228. X        }
  229. X    /***********************************************/
  230. X    /*   Set  whole  screen  to  white  spaces on  */
  231. X    /*   black background.                   */
  232. X    /***********************************************/
  233. X    blank_line(w, w->ctw.lines[0]);
  234. X    for (i = 1; i < rows; i++)
  235. X        memcpy(w->ctw.lines[i], 
  236. X            w->ctw.lines[0], sizeof(vbyte_t) * w->ctw.columns);
  237. X    /***********************************************/
  238. X    /*   Keep cursor within bounds of the screen.  */
  239. X    /***********************************************/
  240. X    if (w->ctw.y >= w->ctw.rows)
  241. X        w->ctw.y = w->ctw.rows - 1;
  242. X    if (w->ctw.saved_y >= w->ctw.rows)
  243. X        w->ctw.saved_y = w->ctw.rows - 1;
  244. X    if (w->ctw.x >= w->ctw.columns)
  245. X        w->ctw.x = w->ctw.columns - 1;
  246. X    if (w->ctw.saved_x >= w->ctw.columns)
  247. X        w->ctw.saved_x = w->ctw.columns - 1;
  248. X
  249. X    /***********************************************/
  250. X    /*   If  we're  resizing the screen then copy  */
  251. X    /*   back  as  much  of  the  old  screen  as  */
  252. X    /*   possible.                       */
  253. X    /***********************************************/
  254. X    if (!clear_flag) {
  255. X        int    last_line;
  256. X        c = w->ctw.old_columns;
  257. X        if (w->ctw.columns < c)
  258. X            c = w->ctw.columns;
  259. X        if (w->ctw.rows < w->ctw.old_rows)
  260. X            last_line = w->ctw.top_line + w->ctw.rows;
  261. X        else
  262. X            last_line = w->ctw.top_line + w->ctw.old_rows;
  263. X        i = 0;
  264. X        while (i < last_line) {
  265. X            for (j = 0; j < c; j++)
  266. X                w->ctw.lines[i][j] = old_lines[i][j];
  267. X            i++;
  268. X            }
  269. X        }
  270. X    /***********************************************/
  271. X    /*   Save size in case we get a resize event.  */
  272. X    /***********************************************/
  273. X    w->ctw.old_rows = w->ctw.rows;
  274. X    w->ctw.old_columns = w->ctw.columns;
  275. X
  276. X    if (old_memory)
  277. X        chk_free((void *) old_memory);
  278. X    if (old_lines)
  279. X        chk_free((void *) old_lines);
  280. X    turn_on_cursor(w);
  281. X    /***********************************************/
  282. X    /*   Allow   owner   of  widget  to  see  the  */
  283. X    /*   resize event.                   */
  284. X    /***********************************************/
  285. X    reason.reason = CTW_RESIZE;
  286. X    XtCallCallbacks((Widget)w, XtNresizeCallback, (caddr_t) &reason);
  287. X}
  288. X/**********************************************************************/
  289. X/*   Function to display cursor at current position.              */
  290. X/**********************************************************************/
  291. Xstatic void
  292. Xshow_cursor(CtwWidget w) {
  293. X    vbyte_t    attr;
  294. X    int    y = w->ctw.top_line + w->ctw.y;
  295. X    int    x;
  296. X
  297. X    /***********************************************/
  298. X    /*   Dont do anything if cursor not visible.   */
  299. X    /***********************************************/
  300. X    if (w->ctw.cursor_visible == FALSE || 
  301. X        w->ctw.cursor_state == CURSOR_HIDDEN ||
  302. X        w->ctw.old_top_line >= 0)
  303. X        return;
  304. X    x = w->ctw.x >= w->ctw.columns ? w->ctw.columns - 1 : w->ctw.x;
  305. X    attr = w->ctw.lines[y][x];
  306. X    XDrawImageString(XtDisplay(w), XtWindow(w), w->ctw.cursor_gc, 
  307. X        x * w->ctw.font_width, 
  308. X        ROW_TO_PIXEL(w, w->ctw.y),
  309. X        &attr.vb_byte, 1);
  310. X    w->ctw.cursor_state = CURSOR_ON;
  311. X}
  312. X/**********************************************************************/
  313. X/*   Function to turn off cursor.                      */
  314. X/**********************************************************************/
  315. Xstatic void
  316. Xturn_off_cursor(CtwWidget w) {
  317. X    int    y = w->ctw.y;
  318. X    int    x;
  319. X
  320. X    if (w->ctw.cursor_state == CURSOR_OFF || w->ctw.cursor_state == CURSOR_HIDDEN)
  321. X        return;
  322. X    w->ctw.cursor_state = CURSOR_OFF;
  323. X    x = w->ctw.x >= w->ctw.columns ? w->ctw.columns - 1 : w->ctw.x;
  324. X    update_region(w, y, x, y+1, x+1);
  325. X}
  326. X/**********************************************************************/
  327. X/*   Function to toggle cursor.                          */
  328. X/**********************************************************************/
  329. Xstatic void
  330. Xtoggle_cursor(CtwWidget w) {
  331. X    if (w->ctw.cursor_state == CURSOR_OFF)
  332. X        turn_on_cursor(w);
  333. X    else
  334. X        turn_off_cursor(w);
  335. X}
  336. X/**********************************************************************/
  337. X/*   Function to turn on cursor.                      */
  338. X/**********************************************************************/
  339. Xstatic void
  340. Xturn_on_cursor(CtwWidget w) {
  341. X    if (w->ctw.cursor_state == CURSOR_ON || w->ctw.cursor_state == CURSOR_HIDDEN)
  342. X        return;
  343. X    w->ctw.cursor_state = CURSOR_ON;
  344. X    show_cursor(w);
  345. X}
  346. X/**********************************************************************/
  347. X/*   Routine  to  update  a  region of the screen. We get passed the  */
  348. X/*   co-ordinates as character positions (not pixels).              */
  349. X/**********************************************************************/
  350. Xstatic void
  351. Xupdate_region(CtwWidget w, int start_line, int start_col, int end_line,
  352. X    int end_col) {
  353. X    int    r;
  354. X    vbyte_t    *vp;
  355. X
  356. X    if (end_line > w->ctw.rows)
  357. X        end_line = w->ctw.rows;
  358. X    if (end_col > w->ctw.columns)
  359. X        end_col = w->ctw.columns;
  360. X    if (start_line < 0)
  361. X        r = 0;
  362. X    else
  363. X        r = start_line;
  364. X    for (; r < end_line; r++) {
  365. X        vp = w->ctw.lines[r + w->ctw.top_line] + start_col;
  366. X        print_string(w, r, start_col, end_col - start_col, vp);
  367. X        }
  368. X}
  369. X/**********************************************************************/
  370. X/*   Routine  to  draw  a  single  string at the specified position.  */
  371. X/*   Handles the changes in attributes.                      */
  372. X/**********************************************************************/
  373. Xstatic void
  374. Xprint_string(CtwWidget w, int row, int col, int len, vbyte_t *vp) {
  375. X    char    buf[80];
  376. X    char    *end_buf;
  377. X    char    *bp;
  378. X    Pixel    fg, bg;
  379. X    int    c;
  380. X    int    end_col = col + len;
  381. X
  382. X    for (c = col; c < end_col; ) {
  383. X        vbyte_t    attr;
  384. X        attr.vb_all = vp->vb_all;
  385. X        /***********************************************/
  386. X        /*   Draw  as  many consecutive characters as  */
  387. X        /*   we can until we hit a color change.       */
  388. X        /***********************************************/
  389. X        bp = buf;
  390. X        if (end_col - c > sizeof buf)
  391. X            end_buf = &buf[sizeof buf];
  392. X        else
  393. X            end_buf = &buf[end_col - c];
  394. X        while (bp < end_buf) {
  395. X            if (vp->vb_color != attr.vb_color ||
  396. X                vp->vb_attr != attr.vb_attr)
  397. X                break;
  398. X            *bp++ = vp->vb_byte;
  399. X            vp++;
  400. X            }
  401. X        if (attr.vb_attr & VB_SELECT) {
  402. X            fg = w->ctw.hilite_fg;
  403. X            bg = w->ctw.hilite_bg;
  404. X            }
  405. X        else {
  406. X            fg = x11_colors[GET_FG(attr.vb_color)];
  407. X            bg = x11_colors[GET_BG(attr.vb_color)];
  408. X            }
  409. X        /***********************************************/
  410. X        /*   Handle   line   drawing   by   doing  it  */
  411. X        /*   ourselves.                       */
  412. X        /***********************************************/
  413. X        len = bp - buf;
  414. X        if (attr.vb_attr & VB_LINE) {
  415. X            for (bp--; bp >= buf; bp--) {
  416. X                if (*bp >= 0x5f && *bp <= 0x7e)
  417. X                    *bp = *bp == 0x5f ? 0x7f : (*bp - 0x5f);
  418. X                }
  419. X            draw_line(w, row, c, buf, len, fg, bg, attr.vb_attr);
  420. X            }
  421. X        else {
  422. X            draw_string(w, row, c, buf, len, fg, bg, attr.vb_attr);
  423. X            }
  424. X        c += len;
  425. X        }
  426. X}
  427. X/**********************************************************************/
  428. X/*   Function to draw the line-drawing characters.              */
  429. X/**********************************************************************/
  430. Xstatic void
  431. Xdraw_line(CtwWidget w, int row, int col, unsigned char *str, int len,
  432. X     Pixel fg, Pixel bg, int attr) {
  433. X    if (w->ctw.line_fontp == (XFontStruct *) NULL) {
  434. X        draw_string(w, row, col, str, len, fg, bg, attr);
  435. X        return;
  436. X        }
  437. X
  438. X    XSetForeground(XtDisplay(w), w->ctw.line_gc, fg);
  439. X    XSetBackground(XtDisplay(w), w->ctw.line_gc, bg);
  440. X    XDrawImageString(XtDisplay(w), XtWindow(w), w->ctw.line_gc, 
  441. X        col * w->ctw.font_width, 
  442. X        ROW_TO_PIXEL(w, row),
  443. X        str, len);
  444. X}
  445. X/**********************************************************************/
  446. X/*   Public  function  to  draw  a  string  at the specified row/col  */
  447. X/*   with the specified foreground and background colors.          */
  448. X/**********************************************************************/
  449. Xstatic void
  450. Xdraw_string(CtwWidget w, int row, int col, char *str, int len,
  451. X     Pixel fg, Pixel bg, int attr) {
  452. X    int    x = col * w->ctw.font_width;
  453. X    int    y = ROW_TO_PIXEL(w, row);
  454. X    
  455. X    XSetForeground(XtDisplay(w), w->ctw.gc, fg);
  456. X    XSetBackground(XtDisplay(w), w->ctw.gc, bg);
  457. X    XDrawImageString(XtDisplay(w), XtWindow(w), w->ctw.gc, 
  458. X        x, y,
  459. X        str, len);
  460. X    if (attr & VB_BOLD) {
  461. X        XDrawString(XtDisplay(w), XtWindow(w), w->ctw.gc, 
  462. X            x + 1, y,
  463. X            str, len);
  464. X        }
  465. X    if (attr & VB_UNDERLINE) {
  466. X        XDrawLine(XtDisplay(w), XtWindow(w), w->ctw.gc,
  467. X            x, y,
  468. X            x + len * w->ctw.font_width, y);
  469. X        }
  470. X}
  471. X/**********************************************************************/
  472. X/*   Routine  to  convert  an (x,y) pixel co-ordinate to a character  */
  473. X/*   position.                                  */
  474. X/**********************************************************************/
  475. Xstatic void
  476. Xget_xy(CtwWidget w, int *row, int *col, int x, int y) {
  477. X    *row = y / w->ctw.font_height;
  478. X    *col = x / w->ctw.font_width;
  479. X    if (*row > w->ctw.rows)
  480. X        *row = w->ctw.rows;
  481. X    if (*col > w->ctw.columns)
  482. X        *col = w->ctw.columns;
  483. X}
  484. Xstatic int
  485. Xfuncvalue (int keycode) {
  486. X    switch (keycode) {
  487. X        case XK_F1:    return(11);
  488. X        case XK_F2:    return(12);
  489. X        case XK_F3:    return(13);
  490. X        case XK_F4:    return(14);
  491. X        case XK_F5:    return(15);
  492. X        case XK_F6:    return(17);
  493. X        case XK_F7:    return(18);
  494. X        case XK_F8:    return(19);
  495. X        case XK_F9:    return(20);
  496. X        case XK_F10:    return(21);
  497. X        case XK_F11:    return(23);
  498. X        case XK_F12:    return(24);
  499. X        case XK_F13:    return(25);
  500. X        case XK_F14:    return(26);
  501. X        case XK_F15:    return(28);
  502. X        case XK_Help:    return(28);
  503. X        case XK_F16:    return(29);
  504. X        case XK_Menu:    return(29);
  505. X        case XK_F17:    return(31);
  506. X        case XK_F18:    return(32);
  507. X        case XK_F19:    return(33);
  508. X        case XK_F20:    return(34);
  509. X
  510. X        case XK_Find :    return(1);
  511. X        case XK_Insert:    return(2);
  512. X        case XK_Delete:    return(3);
  513. X# if defined(DXK_Remove)
  514. X        case DXK_Remove: return(3);
  515. X# endif
  516. X        case XK_Select:    return(4);
  517. X        case XK_Prior:    return(5);
  518. X        case XK_Next:    return(6);
  519. X        default:    return(-1);
  520. X    }
  521. X}
  522. X
  523. X
  524. Xstatic int 
  525. Xsunfuncvalue (int keycode) {
  526. X      switch (keycode) {
  527. X        case XK_F1:    return(224);
  528. X        case XK_F2:    return(225);
  529. X        case XK_F3:    return(226);
  530. X        case XK_F4:    return(227);
  531. X        case XK_F5:    return(228);
  532. X        case XK_F6:    return(229);
  533. X        case XK_F7:    return(230);
  534. X        case XK_F8:    return(231);
  535. X        case XK_F9:    return(232);
  536. X        case XK_F10:    return(233);
  537. X        case XK_F11:    return(192);
  538. X        case XK_F12:    return(193);
  539. X        case XK_F13:    return(194);
  540. X        case XK_F14:    return(195);
  541. X        case XK_F15:    return(196);
  542. X        case XK_Help:    return(196);
  543. X        case XK_F16:    return(197);
  544. X        case XK_Menu:    return(197);
  545. X        case XK_F17:    return(198);
  546. X        case XK_F18:    return(199);
  547. X        case XK_F19:    return(200);
  548. X        case XK_F20:    return(201);
  549. X
  550. X        case XK_R1:    return(208);
  551. X        case XK_R2:    return(209);
  552. X        case XK_R3:    return(210);
  553. X        case XK_R4:    return(211);
  554. X        case XK_R5:    return(212);
  555. X        case XK_R6:    return(213);
  556. X        case XK_R7:    return(214);
  557. X        case XK_R8:    return(215);
  558. X        case XK_R9:    return(216);
  559. X        case XK_R10:    return(217);
  560. X        case XK_R11:    return(218);
  561. X        case XK_R12:    return(219);
  562. X        case XK_R13:    return(220);
  563. X        case XK_R14:    return(221);
  564. X        case XK_R15:    return(222);
  565. X  
  566. X        case XK_Find :    return(1);
  567. X        case XK_Insert:    return(2);
  568. X        case XK_Delete:    return(3);
  569. X# if defined(DXK_Remove)
  570. X        case DXK_Remove: return(3);
  571. X# endif
  572. X        case XK_Select:    return(4);
  573. X        case XK_Prior:    return(5);
  574. X        case XK_Next:    return(6);
  575. X        default:    return(-1);
  576. X    }
  577. X}
  578. X
  579. X/**********************************************************************/
  580. X/*   Function to reset the screen.                      */
  581. X/**********************************************************************/
  582. Xstatic void
  583. Xreset_screen(CtwWidget w) {
  584. X    w->ctw.x = w->ctw.y = 0;
  585. X    w->ctw.saved_x = w->ctw.saved_y = 0;
  586. X    w->ctw.flags[CTW_NEWLINE_GLITCH] = TRUE;
  587. X
  588. X    w->ctw.attr.vb_all = 0;
  589. X    w->ctw.attr.vb_color = FG(WHITE);
  590. X    w->ctw.old_color = FG(WHITE);
  591. X    w->ctw.char_set = 'B';
  592. X
  593. X    w->ctw.escp = (char *) NULL;
  594. X
  595. X    w->ctw.scroll_top = 0;
  596. X    w->ctw.scroll_bot = w->ctw.rows;
  597. X
  598. X    w->ctw.flags[CTW_AUTOWRAP] = TRUE;
  599. X    w->ctw.flags[CTW_AUTOLINEFEED] = FALSE;
  600. X    w->ctw.flags[CTW_APPL_KEYPAD]  = FALSE;
  601. X    w->ctw.flags[CTW_CURSOR_KEYPAD] = FALSE;
  602. X    w->ctw.flags[CTW_LITERAL_MODE] = FALSE;
  603. X}
  604. X# define    FLUSH_OUTPUT() \
  605. X        { \
  606. X        if (vp != start_vp) { \
  607. X            w->ctw.x = vp - vp_start; \
  608. X            update_region(w, w->ctw.y, start_vp - vp_start, \
  609. X                w->ctw.y + 1, w->ctw.x); \
  610. X            } \
  611. X        }
  612. X/**********************************************************************/
  613. X/*   Main public function for adding a string to the widget.          */
  614. X/**********************************************************************/
  615. Xvoid
  616. Xctw_add_string(CtwWidget w, char *str, int len) {
  617. X    if (w->ctw.flags[CTW_SLOW_MODE] == FALSE) {
  618. X        ctw_add_string2(w, str, len);
  619. X        return;
  620. X        }
  621. X    while (len-- > 0) {
  622. X        ctw_add_string2(w, str++, 1);
  623. X        XFlush(XtDisplay(w));
  624. X        usleep(20000);
  625. X        }
  626. X}
  627. X/**********************************************************************/
  628. X/*   Function  to  add  a  string  to  the  display.  Processes ANSI  */
  629. X/*   escape sequences.                              */
  630. X/**********************************************************************/
  631. Xstatic void
  632. Xctw_add_string2(CtwWidget w, char *str, int len) {
  633. X    ctw_callback_t    reason;
  634. X    int    x;
  635. X    vbyte_t    attr;
  636. X    static int nest_level = 0;
  637. X    char    *str_end = str + len;
  638. X    vbyte_t    *vp_start, *vp_end;
  639. X    vbyte_t    *start_vp, *vp;
  640. X    int    top_line = w->ctw.top_line;
  641. X    int    pc_charset = w->ctw.flags[CTW_PC_CHARSET];
  642. X
  643. X    if (nest_level++ == 0)
  644. X        turn_off_cursor(w);
  645. X
  646. X    /***********************************************/
  647. X    /*   Reframe   the   area  if  the  user  has  */
  648. X    /*   scrolled us.                   */
  649. X    /***********************************************/
  650. X    if (w->ctw.old_top_line >= 0) {
  651. X        ctw_callback_t reason;
  652. X        if (w->ctw.old_top_line != w->ctw.top_line) {
  653. X            w->ctw.top_line = w->ctw.old_top_line;
  654. X            update_region(w, 0, 0, 
  655. X                w->ctw.rows + 1, w->ctw.columns + 1);
  656. X            }
  657. X        w->ctw.old_top_line = -1;
  658. X        reason.reason = CTW_TOP_LINE;
  659. X        reason.top_line = w->ctw.top_line;
  660. X        XtCallCallbacks((Widget)w, XtNtopCallback, (caddr_t) &reason);
  661. X        }
  662. X    /***********************************************/
  663. X    /*   If  we  were in the middle of processing  */
  664. X    /*   an  escape  sequence  then carry on from  */
  665. X    /*   where we left off.                   */
  666. X    /***********************************************/
  667. X    if (w->ctw.escp)
  668. X        str = handle_escape(w, str, str_end);
  669. X
  670. X    attr = w->ctw.attr;
  671. Xstart_again:
  672. X    vp_start = w->ctw.lines[w->ctw.top_line + w->ctw.y];
  673. X    start_vp = vp = vp_start + w->ctw.x;
  674. X    vp_end = vp_start + w->ctw.columns;
  675. X    while (str < str_end) {
  676. X        if (parse_tbl[*str] == 0) {
  677. XDEFAULT:
  678. X              if (vp >= vp_end) {
  679. X                FLUSH_OUTPUT();
  680. X                w->ctw.x = 0;
  681. X                down_line(w, str);
  682. X                goto start_again;
  683. X                }
  684. X            attr.vb_byte = *str++;
  685. X            *vp = attr;
  686. X            if (pc_charset && pc_chars[attr.vb_byte]) {
  687. X                vp->vb_attr |= VB_LINE;
  688. X                vp->vb_byte = pc_chars[attr.vb_byte];
  689. X                }
  690. X
  691. X            if (++vp < vp_end)
  692. X                continue;
  693. X            FLUSH_OUTPUT();
  694. X            if (w->ctw.flags[CTW_AUTOWRAP]) {
  695. X                if (w->ctw.flags[CTW_NEWLINE_GLITCH])
  696. X                    continue;
  697. X                w->ctw.x = 0;
  698. X                down_line(w, str);
  699. X                goto start_again;
  700. X                }
  701. X            else
  702. X                vp--;
  703. X            continue;
  704. X            }
  705. X        switch (*str++) {
  706. X          case BEL:
  707. X            break;
  708. X          case '\b':
  709. X              FLUSH_OUTPUT();
  710. X              if (w->ctw.flags[CTW_LITERAL_MODE]) {
  711. X                ctw_add_string2(w, "<BS>", 4);
  712. X                goto start_again;
  713. X                }
  714. X            if (vp > vp_start) {
  715. X                start_vp = --vp;
  716. X                w->ctw.x = vp - vp_start;
  717. X                }
  718. X            break;
  719. X          case '\t':
  720. X              if (w->ctw.flags[CTW_LITERAL_MODE]) {
  721. X                  FLUSH_OUTPUT();
  722. X                ctw_add_string2(w, "<TAB>", 5);
  723. X                goto start_again;
  724. X                }
  725. X            x = vp - vp_start;
  726. X            if (w->ctw.flags[CTW_DESTRUCTIVE_TABS] == FALSE) {
  727. X                x = (x | 7) + 1;
  728. X                vp = vp_start + x;
  729. X                break;
  730. X                }
  731. X              attr.vb_byte = ' ';
  732. X            do {
  733. X                *vp++ = attr;
  734. X                }
  735. X            while (vp < vp_end && (++x & 7) != 0);
  736. X              break;
  737. X          case '\r':
  738. X              FLUSH_OUTPUT();
  739. X              if (w->ctw.flags[CTW_LITERAL_MODE]) {
  740. X                ctw_add_string2(w, "<CR>", 4);
  741. X                goto start_again;
  742. X                }
  743. X            w->ctw.x = 0;
  744. X            goto start_again;
  745. X          case '\n':
  746. X              FLUSH_OUTPUT();
  747. X            down_line(w, str);
  748. X            goto start_again;
  749. X          case 'n' & 0x1f:
  750. X              attr.vb_attr |= VB_LINE;
  751. X              break;
  752. X          case 'o' & 0x1f:
  753. X              attr.vb_attr &= ~VB_LINE;
  754. X              break;
  755. X          case XON:
  756. X              if (!w->ctw.flags[CTW_LITERAL_MODE])
  757. X                goto DEFAULT;
  758. X              FLUSH_OUTPUT();
  759. X            ctw_add_string2(w, "<XON>", 5);
  760. X            break;
  761. X          case XOFF:
  762. X              if (!w->ctw.flags[CTW_LITERAL_MODE])
  763. X                goto DEFAULT;
  764. X              FLUSH_OUTPUT();
  765. X            ctw_add_string2(w, "<XOFF>", 6);
  766. X            break;
  767. X          case ESC:
  768. X              str--;
  769. X              if (w->ctw.flags[CTW_LITERAL_MODE])
  770. X                goto DEFAULT;
  771. X              FLUSH_OUTPUT();
  772. X            w->ctw.escp = w->ctw.escbuf;
  773. X              str = handle_escape(w, str+1, str_end);
  774. X            attr = w->ctw.attr;
  775. X            goto start_again;
  776. X          case '\0':
  777. X            break;
  778. X          }
  779. X        }
  780. X    FLUSH_OUTPUT();
  781. X    w->ctw.attr = attr;
  782. X    if (w->ctw.num_exposures)
  783. X        wait_for_exposure(w);
  784. X
  785. X    if (--nest_level == 0)
  786. X        turn_on_cursor(w);
  787. X    /***********************************************/
  788. X    /*   If  top  line  changed then tell user so  */
  789. X    /*   he/she   can   update  a  scrollbar  for  */
  790. X    /*   instance.                       */
  791. X    /***********************************************/
  792. X    if (top_line != w->ctw.top_line) {
  793. X        reason.reason = CTW_TOP_LINE;
  794. X        reason.top_line = w->ctw.top_line;
  795. X        XtCallCallbacks((Widget)w, XtNtopCallback, (caddr_t) &reason);
  796. X        }
  797. X}
  798. X/**********************************************************************/
  799. X/*   Function  to  move  cursor  down  a  line,  possibly  forcing a  */
  800. X/*   scroll.  Also  look  ahead  for more new-lines to see if we can  */
  801. X/*   bit-blt more than a line at a time.                  */
  802. X/**********************************************************************/
  803. Xstatic void
  804. Xdown_line(CtwWidget w, char *str) {
  805. X    int    y = w->ctw.y;
  806. X    int    i;
  807. X    int    max_rows;
  808. X# if COLLECT_STATS
  809. X    ctw_stats.lines_scrolled++;
  810. X# endif
  811. X    if (y < w->ctw.scroll_bot-1) {
  812. X        w->ctw.y++;
  813. X        return;
  814. X        }
  815. X    /***********************************************/
  816. X    /*   Look  ahead  to  see  if  we  can scroll  */
  817. X    /*   more than one line.               */
  818. X    /***********************************************/
  819. X    i = 1;
  820. X    max_rows = w->ctw.scroll_bot - w->ctw.scroll_top;
  821. X    while (1) {
  822. X        switch (*str++) {
  823. X          case ESC:
  824. X              goto after_loop;
  825. X          case '\n':
  826. X              if (++i >= max_rows)
  827. X                goto after_loop;
  828. X            break;
  829. X          case '\0':
  830. X              goto after_loop;
  831. X          }
  832. X        }
  833. Xafter_loop:
  834. X
  835. X    /***********************************************/
  836. X    /*   If  we  have  a  hilited  selection then  */
  837. X    /*   adjust place where its displayed.           */
  838. X    /***********************************************/
  839. X    if (w->ctw.sel_string) {
  840. X        w->ctw.sel_start_y -= i;
  841. X        w->ctw.sel_cur_y -= i;
  842. X        if (w->ctw.sel_start_y < 0 ||
  843. X            w->ctw.sel_cur_y < 0) {
  844. X            w->ctw.sel_start_y -= -1;
  845. X            w->ctw.sel_cur_y -= -1;
  846. X            }
  847. X        }
  848. X
  849. X    w->ctw.y -= i-1;
  850. X    if (w->ctw.flags[CTW_SCROLLING_REGION] == FALSE &&
  851. X        w->ctw.top_line < w->ctw.max_lines - 1) {
  852. X        if (w->ctw.top_line + i > w->ctw.max_lines)
  853. X            w->ctw.top_line = w->ctw.max_lines;
  854. X        else
  855. X            w->ctw.top_line += i;
  856. X        delete_line(w, 0, i);
  857. X        }
  858. X    else {
  859. X# if COLLECT_STATS
  860. X        ctw_stats.lines_jumped += i;
  861. X        ctw_stats.scroll_ups++;
  862. X# endif
  863. X        scroll_up(w, i);
  864. X        }
  865. X}
  866. X/**********************************************************************/
  867. X/*   Scroll screen up number of lines. Called on '\n'.              */
  868. X/**********************************************************************/
  869. Xstatic void
  870. Xscroll_up(CtwWidget w, int num_lines) {
  871. X    int    j;
  872. X    vbyte_t    *vp;
  873. X    int    end;
  874. X    int    start_line;
  875. X    int    disp_start;
  876. X
  877. X    if (w->ctw.flags[CTW_SCROLLING_REGION]) {
  878. X        start_line = w->ctw.top_line + w->ctw.scroll_top;
  879. X        disp_start = w->ctw.scroll_top;
  880. X        end = w->ctw.top_line + w->ctw.scroll_bot;
  881. X        }
  882. X    else {
  883. X        start_line = 0;
  884. X        disp_start = 0;
  885. X        end = w->ctw.max_lines + w->ctw.rows;
  886. X        }
  887. X# if 0
  888. X    /***********************************************/
  889. X    /*   Blank  the  lines  at  the  top  of  the  */
  890. X    /*   screen  which  are  about  to be wrapped  */
  891. X    /*   around to the bottom.               */
  892. X    /***********************************************/
  893. X    for (j = 0; j < num_lines; j++) {
  894. X        blank_line(w, w->ctw.lines[start_line + j]);
  895. X        }
  896. X    rotate_mem(&w->ctw.lines[start_line],
  897. X        &w->ctw.lines[end - start_line],
  898. X        -num_lines * sizeof(vbyte_t *));
  899. X# else
  900. X    for (j = 0; j < num_lines; j++) {
  901. X        vp = w->ctw.lines[start_line];
  902. X        memcpy(&w->ctw.lines[start_line], 
  903. X            &w->ctw.lines[start_line+1],
  904. X            (end - start_line - 1) * sizeof(vbyte_t *));
  905. X        w->ctw.lines[end-1] = vp;
  906. X        blank_line(w, vp);
  907. X        }
  908. X# endif
  909. X    delete_line(w, disp_start, num_lines);
  910. X}
  911. X/**********************************************************************/
  912. X/*   Scroll screen up number of lines. Called on ESC[M              */
  913. X/**********************************************************************/
  914. Xstatic void
  915. Xscroll_up_local(CtwWidget w, int start_line, int num_lines) {
  916. X    int    j;
  917. X    vbyte_t    *vp;
  918. X    int    end;
  919. X    int    top = w->ctw.top_line;
  920. X
  921. X    
  922. X    if (w->ctw.flags[CTW_SCROLLING_REGION]) {
  923. X        end = w->ctw.scroll_bot;
  924. X        }
  925. X    else {
  926. X        end = w->ctw.rows;
  927. X        }
  928. X    if (num_lines > w->ctw.scroll_bot - w->ctw.scroll_top)
  929. X        num_lines = w->ctw.scroll_bot - w->ctw.scroll_top;
  930. X    for (j = 0; j < num_lines; j++) {
  931. X        vp = w->ctw.lines[top + start_line];
  932. X        memcpy(&w->ctw.lines[top + start_line], 
  933. X            &w->ctw.lines[top + start_line+1],
  934. X            (end - start_line - 1) * sizeof(vbyte_t *));
  935. X        w->ctw.lines[top + end-1] = vp;
  936. X        blank_line(w, vp);
  937. X        }
  938. X    delete_line(w, start_line, num_lines);
  939. X}
  940. X/**********************************************************************/
  941. X/*   Function to parse or continue parsing an escape sequence.          */
  942. X/**********************************************************************/
  943. Xstatic char *
  944. Xhandle_escape(CtwWidget w, char *str, char *str_end) {
  945. X    char    *cp = w->ctw.escp;
  946. X    char    *cpend = &w->ctw.escbuf[MAX_ESCBUF - 1];
  947. X
  948. X    while (str < str_end) {
  949. X        /***********************************************/
  950. X        /*   If sequence too large then just junk it.  */
  951. X        /***********************************************/
  952. X        if (cp >= cpend) {
  953. X            w->ctw.escp = (char *) NULL;
  954. X            send_str(w, "<ESC>", 5);
  955. X            send_str(w, w->ctw.escbuf, MAX_ESCBUF);
  956. X            return str;
  957. X            }
  958. X        *cp++ = *str++;
  959. X        switch(w->ctw.escbuf[0]) {
  960. X          case '[':
  961. X              if (!isalpha(str[-1]) && str[-1] != '@')
  962. X                continue;
  963. X            if (str[-1] == '-')
  964. X                continue;
  965. X            break;
  966. X          case ']':
  967. X              if (str[-1] == BEL)
  968. X                break;
  969. X            /***********************************************/
  970. X            /*   Check  for  shelltool  style icon/window  */
  971. X            /*   name escape                   */
  972. X            /***********************************************/
  973. X            if (cp < &w->ctw.escbuf[3])
  974. X                continue;
  975. X            if (str[-1] == '\\' && str[-2] == ESC)
  976. X                break;
  977. X            continue;
  978. X          case '(':
  979. X          case ')':
  980. X              if (cp > &w->ctw.escbuf[1])
  981. X                break;
  982. X            continue;
  983. X          case '7':
  984. X              w->ctw.saved_x = w->ctw.x;
  985. X              w->ctw.saved_y = w->ctw.y;
  986. X            w->ctw.escp = NULL;
  987. X              return str;
  988. X          case '8':
  989. X              w->ctw.x = w->ctw.saved_x;
  990. X              w->ctw.y = w->ctw.saved_y;
  991. X            w->ctw.escp = NULL;
  992. X              return str;
  993. X          case 'c':
  994. X              reset_screen(w);
  995. X            return str;
  996. X          case '<':
  997. X              return str;
  998. X          case '>':
  999. X              w->ctw.flags[CTW_APPL_KEYPAD] = FALSE;
  1000. X            w->ctw.escp = (char *) NULL;
  1001. X              return str;
  1002. X          case '=':
  1003. X              w->ctw.flags[CTW_APPL_KEYPAD] = TRUE;
  1004. X            w->ctw.escp = (char *) NULL;
  1005. X              return str;
  1006. X          case 'D':
  1007. X              do_index(w);
  1008. X              return str;
  1009. X          case 'M':
  1010. X              do_rev_index(w);
  1011. X              return str;
  1012. X          case 'Z':
  1013. X              send_input(w, "\033[?1;2c", 7);
  1014. X            w->ctw.escp = NULL;
  1015. X              return str;
  1016. X          default:
  1017. X              if (w->ctw.flags[CTW_ESC_LITERAL]) {
  1018. X                char    buf[1];
  1019. X                buf[0] = w->ctw.escbuf[0];
  1020. X                w->ctw.escp = NULL;
  1021. X                  send_str(w, buf, 1);
  1022. X                return str;
  1023. X                }
  1024. X              break;
  1025. X          }
  1026. X        *cp = '\0';
  1027. X        w->ctw.escp = NULL;
  1028. X        if (process_escape(w) == FALSE) {
  1029. X            send_str(w, "<ESC>", 5);
  1030. X            send_str(w, w->ctw.escbuf, cp - w->ctw.escbuf);
  1031. X            }
  1032. X        w->ctw.escp = NULL;
  1033. X        return str;
  1034. X        }
  1035. X    w->ctw.escp = cp;
  1036. X    return str;
  1037. X}
  1038. X/**********************************************************************/
  1039. X/*   Execute a compiled escape sequence.                  */
  1040. X/**********************************************************************/
  1041. Xstatic int
  1042. Xprocess_escape(CtwWidget w) {
  1043. X    int    args[MAX_ARGS];
  1044. X    int    arg1;
  1045. X    int    arg_no = 0;
  1046. X    int    n, i, y;
  1047. X    int    quest = FALSE;
  1048. X    int    esc_equ = FALSE;
  1049. X    int    isneg;
  1050. X    char    *cp;
  1051. X    char    buf[32];
  1052. X      vbyte_t space, attr;
  1053. X    ctw_callback_t    reason;
  1054. X
  1055. X    cp = w->ctw.escbuf;
  1056. X    switch (*cp++) {
  1057. X      case '[':
  1058. X          if (*cp == '?') {
  1059. X            cp++;
  1060. X              quest = TRUE;
  1061. X            }
  1062. X        break;
  1063. X      case ']':
  1064. X          do_text_parms((Widget) w, cp);
  1065. X        return TRUE;
  1066. X      case ')':
  1067. X          /***********************************************/
  1068. X          /*   Change character set.               */
  1069. X          /***********************************************/
  1070. X        switch (*cp) {
  1071. X          case '0':
  1072. X              w->ctw.attr.vb_attr &= ~VB_LINE;
  1073. X            break;
  1074. X          case 'B':
  1075. X          default:
  1076. X              w->ctw.attr.vb_attr |= VB_LINE;
  1077. X            break;
  1078. X          }
  1079. X          return TRUE;
  1080. X      case '(':
  1081. X          /***********************************************/
  1082. X          /*   Change character set.               */
  1083. X          /***********************************************/
  1084. X        switch (*cp) {
  1085. X          case '0':
  1086. X              w->ctw.attr.vb_attr |= VB_LINE;
  1087. X            break;
  1088. X          case 'B':
  1089. X          default:
  1090. X              w->ctw.attr.vb_attr &= ~VB_LINE;
  1091. X            break;
  1092. X          }
  1093. X          return TRUE;
  1094. X      default:
  1095. X          return FALSE;
  1096. X      }
  1097. X
  1098. X    /***********************************************/
  1099. X    /*   Handle ISC cursor size changes.           */
  1100. X    /***********************************************/
  1101. X    if (*cp == '=') {
  1102. X        cp++;
  1103. X        esc_equ = TRUE;
  1104. X        }
  1105. X    while (!isalpha(*cp) && *cp != '@') {
  1106. X        n = 0;
  1107. X        isneg = FALSE;
  1108. X        if (*cp == '-') {
  1109. X            cp++;
  1110. X            isneg = TRUE;
  1111. X            }
  1112. X        while (isdigit(*cp))
  1113. X            n = 10 * n + *cp++ - '0';
  1114. X        args[arg_no++] = isneg ? -n : n;
  1115. X        if (*cp != ';')
  1116. X            break;
  1117. X        cp++;
  1118. X        }
  1119. X    if (quest) {
  1120. X        return do_quest(w, *cp, arg_no, args);
  1121. X        }
  1122. X    if (esc_equ)
  1123. X        return do_escequ(w, *cp, arg_no, args);
  1124. X
  1125. X    if (arg_no > 0)
  1126. X        arg1 = args[0];
  1127. X    else
  1128. X        arg1 = 1;
  1129. X    switch (*cp) {
  1130. X      case '@': {
  1131. X        y = w->ctw.top_line + w->ctw.y;
  1132. X        space.vb_all = 0;
  1133. X        space.vb_byte = ' ';
  1134. X        space.vb_color = FG(WHITE) | BG(BLACK);
  1135. X          for (n = arg1; n-- > 0; ) {
  1136. X              for (i = w->ctw.columns - 1; i > w->ctw.x; i--) {
  1137. X                w->ctw.lines[y][i] = w->ctw.lines[y][i-1];
  1138. X                }
  1139. X            w->ctw.lines[y][w->ctw.x] = space;
  1140. X            }
  1141. X        update_region(w, w->ctw.y, w->ctw.x, w->ctw.y+1, w->ctw.columns);
  1142. X          break;
  1143. X        }
  1144. X      case 'A':
  1145. X          w->ctw.y -= arg1;
  1146. X        goto check_cursor;
  1147. X      case 'B':
  1148. X          w->ctw.y += arg1;
  1149. X        goto check_cursor;
  1150. X      case 'C':
  1151. X          w->ctw.x += arg1;
  1152. X        goto check_cursor;
  1153. X      case 'D':
  1154. X          w->ctw.x -= arg1;
  1155. X        goto check_cursor;
  1156. X      case 'H':
  1157. X          if (arg_no > 1)
  1158. X            w->ctw.x = args[1] - 1;
  1159. X        else
  1160. X            w->ctw.x = 0;
  1161. X        if (arg_no > 0)
  1162. X            w->ctw.y = args[0] - 1;
  1163. X        else {
  1164. X            w->ctw.x = 0;
  1165. X            w->ctw.y = 0;
  1166. X            }
  1167. Xcheck_cursor:
  1168. X        if (w->ctw.x < 0)
  1169. X            w->ctw.x = 0;
  1170. X        else if (w->ctw.x >= w->ctw.columns)
  1171. X            w->ctw.x = w->ctw.columns - 1;
  1172. X        if (w->ctw.y < w->ctw.scroll_top)
  1173. X            w->ctw.y = w->ctw.scroll_top;
  1174. X        else if (w->ctw.y >= w->ctw.scroll_bot)
  1175. X            w->ctw.y = w->ctw.scroll_bot - 1;
  1176. X        break;
  1177. X      case 'J':
  1178. X        if (arg_no == 0)
  1179. X            args[0] = 0;
  1180. X        switch (args[0]) {
  1181. X          case 0:
  1182. X              clear_to_eol(w);
  1183. X            clear_lines(w, w->ctw.y, w->ctw.rows - 1);
  1184. X              break;
  1185. X          case 1:
  1186. X              clear_from_beginning(w);
  1187. X            clear_lines(w, 0, w->ctw.y - 1);
  1188. X            break;
  1189. X          case 2:
  1190. X              clear_screen(w);
  1191. X            break;
  1192. X          }
  1193. X          break;
  1194. X      case 'K':
  1195. X          if (arg_no == 0)
  1196. X            args[0] = 0;
  1197. X        switch (args[0]) {
  1198. X          case 0:
  1199. X              clear_to_eol(w);
  1200. X            break;
  1201. X          case 1:
  1202. X              clear_from_beginning(w);
  1203. X            break;
  1204. X          case 2:
  1205. X              clear_from_beginning(w);
  1206. X            clear_to_eol(w);
  1207. X            break;
  1208. X          }
  1209. X          break;
  1210. X      case 'L':
  1211. X          if (w->ctw.y >= w->ctw.scroll_top && w->ctw.y < w->ctw.scroll_bot)
  1212. X              scroll_down(w, w->ctw.y, arg1);
  1213. X          break;
  1214. X      case 'M':
  1215. X          if (w->ctw.y >= w->ctw.scroll_top && w->ctw.y < w->ctw.scroll_bot)
  1216. X              scroll_up_local(w, w->ctw.y, arg1);
  1217. X          break;
  1218. X      case 'P': {
  1219. X        y = w->ctw.top_line + w->ctw.y;
  1220. X        space.vb_all = 0;
  1221. X        space.vb_byte = ' ';
  1222. X        space.vb_color = FG(WHITE) | BG(BLACK);
  1223. X
  1224. X          for (n = arg1; n-- > 0; ) {
  1225. X              for (i = w->ctw.x; i < w->ctw.columns - 1; i++) {
  1226. X                w->ctw.lines[y][i] = w->ctw.lines[y][i+1];
  1227. X                }
  1228. X            w->ctw.lines[y][i] = space;
  1229. X            }
  1230. X        update_region(w, w->ctw.y, w->ctw.x, w->ctw.y+1, w->ctw.columns);
  1231. X          break;
  1232. X        }
  1233. X      case 'S':
  1234. X          do_index(w);
  1235. X        break;
  1236. X      case 'T':
  1237. X          do_rev_index(w);
  1238. X        break;
  1239. X
  1240. X      case 'X':
  1241. X          /***********************************************/
  1242. X          /*   ISC  &  SCO  allow ESC[X have to erase a  */
  1243. X          /*   sequence of blanks.               */
  1244. X          /***********************************************/
  1245. X        if (w->ctw.flags[CTW_ISC_DRIVER] == FALSE && 
  1246. X            w->ctw.flags[CTW_SCO_DRIVER] == FALSE)
  1247. X                return FALSE;
  1248. X        attr = w->ctw.attr;
  1249. X        attr.vb_byte = ' ';
  1250. X        attr.vb_attr &= ~VB_LINE;
  1251. X        y = w->ctw.top_line + w->ctw.y;
  1252. X        for (i = 0; i < arg1; i++) {
  1253. X            if (w->ctw.x + i >= w->ctw.columns)
  1254. X                break;
  1255. X            w->ctw.lines[y][w->ctw.x + i] = attr;
  1256. X            }
  1257. X        update_region(w, w->ctw.y, w->ctw.x, w->ctw.y+1, w->ctw.x + arg1);
  1258. X        break;
  1259. X
  1260. X      case 'g':
  1261. X          if (w->ctw.flags[CTW_SCO_DRIVER] == FALSE)
  1262. X            return FALSE;
  1263. X        buf[0] = arg1;
  1264. X        send_str(w, buf, 1);
  1265. X          break;
  1266. X      case 'm':
  1267. X          if (arg_no == 0) {
  1268. X            arg_no = 1;
  1269. X            args[0] = 0;
  1270. X            }
  1271. X          for (i = 0; i < arg_no; i++) {
  1272. X            switch (args[i]) {
  1273. X              case 0: {
  1274. X                w->ctw.attr.vb_all = 0;
  1275. X                if (w->ctw.flags[CTW_COLOR_RESET] ||
  1276. X                    w->ctw.old_color == 0)
  1277. X                      w->ctw.attr.vb_color = FG(WHITE) | BG(0);
  1278. X                else
  1279. X                      w->ctw.attr.vb_color = w->ctw.old_color;
  1280. X                break;
  1281. X                }
  1282. X              case 1:
  1283. X                  w->ctw.attr.vb_attr |= VB_BOLD;
  1284. X                break;
  1285. X              case 4:
  1286. X                  w->ctw.attr.vb_attr |= VB_UNDERLINE;
  1287. X                break;
  1288. X              case 7: {
  1289. X                  w->ctw.old_color = w->ctw.attr.vb_color;
  1290. X                  w->ctw.attr.vb_color = 
  1291. X                    BG(GET_FG(w->ctw.attr.vb_color)) |
  1292. X                    FG(GET_BG(w->ctw.attr.vb_color));
  1293. X                break;
  1294. X                }
  1295. X              case 30: case 31: case 32: case 33:
  1296. X              case 34: case 35: case 36: case 37:
  1297. X                  w->ctw.attr.vb_color = 
  1298. X                    FG(args[i] - 30) | 
  1299. X                    BG(GET_BG(w->ctw.attr.vb_color));
  1300. X                  break;
  1301. X              case 40: case 41: case 42: case 43:
  1302. X              case 44: case 45: case 46: case 47:
  1303. X                  w->ctw.attr.vb_color = 
  1304. X                    BG(args[i] - 40) | 
  1305. X                    FG(GET_FG(w->ctw.attr.vb_color));
  1306. X                  break;
  1307. X              }
  1308. X            }
  1309. X          break;
  1310. X      case 'r':
  1311. X        w->ctw.scroll_top = 0;
  1312. X        w->ctw.scroll_bot = w->ctw.rows;
  1313. X        w->ctw.flags[CTW_SCROLLING_REGION] = FALSE;
  1314. X        if (arg_no >= 1) {
  1315. X            w->ctw.flags[CTW_SCROLLING_REGION] = TRUE;
  1316. X            w->ctw.scroll_top = args[0] ? args[0] - 1 : 0;
  1317. X            if (arg_no >= 2)
  1318. X                w->ctw.scroll_bot = args[1] ? args[1] : 0;
  1319. X            if (w->ctw.scroll_top < 0)
  1320. X                w->ctw.scroll_top = 0;
  1321. X            if (w->ctw.scroll_bot < w->ctw.scroll_top || 
  1322. X                w->ctw.scroll_bot > w->ctw.rows)
  1323. X                w->ctw.scroll_bot = w->ctw.rows;
  1324. X            /***********************************************/
  1325. X            /*   If  scrolling  region  to  entire window  */
  1326. X            /*   then turn flag off.               */
  1327. X            /***********************************************/
  1328. X            if (w->ctw.scroll_top == 0 &&
  1329. X                w->ctw.scroll_bot == w->ctw.rows)
  1330. X                w->ctw.flags[CTW_SCROLLING_REGION] = FALSE;
  1331. X            }
  1332. X        w->ctw.x = 0;
  1333. X        w->ctw.y = 0;
  1334. X          break;
  1335. X      case 't':
  1336. X          /***********************************************/
  1337. X          /*   Shelltool/cmdtool    compatable   escape  */
  1338. X          /*   sequences.                       */
  1339. X          /***********************************************/
  1340. X        switch (args[0]) {
  1341. X          case 1:
  1342. X              reason.reason = CTW_OPEN_WINDOW;
  1343. X              XtCallCallbacks((Widget)w, XtNapplCallback, (caddr_t) &reason);
  1344. X              break;
  1345. X          case 2:
  1346. X              reason.reason = CTW_CLOSE_WINDOW;
  1347. X              XtCallCallbacks((Widget)w, XtNapplCallback, (caddr_t) &reason);
  1348. X              break;
  1349. X          case 3:
  1350. X              reason.reason = CTW_MOVE_WINDOW;
  1351. X            reason.x = args[1];
  1352. X            reason.y = args[2];
  1353. X              XtCallCallbacks((Widget)w, XtNapplCallback, (caddr_t) &reason);
  1354. X            break;
  1355. X          case 4:
  1356. X              reason.reason = CTW_SIZE_WINDOW_PIXELS;
  1357. X            reason.height = args[1];
  1358. X            reason.width = args[2];
  1359. X              XtCallCallbacks((Widget)w, XtNapplCallback, (caddr_t) &reason);
  1360. X            break;
  1361. X          case 5:
  1362. X              reason.reason = CTW_FRONT_WINDOW;
  1363. X              XtCallCallbacks((Widget)w, XtNapplCallback, (caddr_t) &reason);
  1364. X              break;
  1365. X          case 6:
  1366. X              reason.reason = CTW_BACK_WINDOW;
  1367. X              XtCallCallbacks((Widget)w, XtNapplCallback, (caddr_t) &reason);
  1368. X              break;
  1369. X          case 8:
  1370. X              reason.reason = CTW_SIZE_WINDOW_CHARS;
  1371. X            reason.height = args[1];
  1372. X            reason.width = args[2];
  1373. X              XtCallCallbacks((Widget)w, XtNapplCallback, (caddr_t) &reason);
  1374. X            break;
  1375. X          }
  1376. X          break;
  1377. X      default:
  1378. X          return FALSE;
  1379. X      }
  1380. X    return TRUE;
  1381. X}
  1382. X/**********************************************************************/
  1383. X/*   Handle  Sun  compatable escape sequences where we have a string  */
  1384. X/*   to process.                              */
  1385. X/**********************************************************************/
  1386. Xstatic int
  1387. Xdo_text_parms(Widget w, char *str) {
  1388. X    Arg    args[20];
  1389. X    int    n;
  1390. X    int    type = atoi(str);
  1391. X    char    *cp;
  1392. X
  1393. X    /***********************************************/
  1394. X    /*   Check for Sun style shell tool sequence.  */
  1395. X    /***********************************************/
  1396. X    if (str[0] == 'l') {
  1397. X        type = 1;
  1398. X        str++;
  1399. X        str[strlen(str) - 2] = '\0';
  1400. X        }
  1401. X    else if (str[0] == 'L') {
  1402. X        type = 2;
  1403. X        str++;
  1404. X        str[strlen(str) - 2] = '\0';
  1405. X        }
  1406. X    else {
  1407. X        while (*str && *str != ';')
  1408. X            str++;
  1409. X            
  1410. X        if (*str++ == '\0')
  1411. X            return 0;
  1412. X        for (cp = str; *cp && *cp != BEL; )
  1413. X            cp++;
  1414. X        if (*cp == '\0')
  1415. X            return 0;
  1416. X        *cp = '\0';
  1417. X        }
  1418. X
  1419. X    /***********************************************/
  1420. X    /*   Find top level shell.               */
  1421. X    /***********************************************/
  1422. X    while (XtParent(w))
  1423. X        w = XtParent(w);
  1424. X
  1425. X    switch (type) {
  1426. X      case 0:
  1427. X          /***********************************************/
  1428. X          /*   Window Name and Title.               */
  1429. X          /***********************************************/
  1430. X        n = 0;
  1431. X        XtSetArg(args[n], XtNtitle, str); n++;
  1432. X        XtSetArg(args[n], XtNiconName, str); n++;
  1433. X        XtSetValues(w, args, n);
  1434. X        break;
  1435. X      case 1:
  1436. X          /***********************************************/
  1437. X          /*   Window name.                   */
  1438. X          /***********************************************/
  1439. X        n = 0;
  1440. X        XtSetArg(args[n], XtNtitle, str); n++;
  1441. X        XtSetValues(w, args, n);
  1442. X        break;
  1443. X      case 2:
  1444. X          /***********************************************/
  1445. X          /*   Window title.                   */
  1446. X          /***********************************************/
  1447. X        n = 0;
  1448. X        XtSetArg(args[n], XtNiconName, str); n++;
  1449. X        XtSetValues(w, args, n);
  1450. X        break;
  1451. X      case 46:
  1452. X          /***********************************************/
  1453. X          /*   Set log file name.                   */
  1454. X          /***********************************************/
  1455. X        break;
  1456. X      }
  1457. X    return 1;
  1458. X}
  1459. X/**********************************************************************/
  1460. X/*   Handle ESC ? escape sequences.                      */
  1461. X/**********************************************************************/
  1462. Xstatic int
  1463. Xdo_quest(CtwWidget w, int cmd, int arg_no, int *args) {
  1464. X    int    flag = TRUE;
  1465. X    int    r, c, h, width, num;
  1466. X
  1467. X    switch (cmd) {
  1468. X      case 'l':
  1469. X          flag = FALSE;
  1470. X        /* Fallthru.. */
  1471. X      case 'h':
  1472. X          switch (args[0]) {
  1473. X          case 1:
  1474. X              w->ctw.flags[CTW_CURSOR_KEYPAD] = flag;
  1475. X            return TRUE;
  1476. X          case 4:
  1477. X              w->ctw.flags[CTW_SMOOTH_SCROLL] = flag;
  1478. X            return TRUE;
  1479. X          case 7:
  1480. X              w->ctw.flags[CTW_AUTOWRAP] = flag;
  1481. X            return TRUE;
  1482. X          case 47:
  1483. X              /***********************************************/
  1484. X              /*   Alternate screen buffer.               */
  1485. X              /***********************************************/
  1486. X            return TRUE;
  1487. X          case 1962:
  1488. X              /***********************************************/
  1489. X              /*   My birthyear! Mouse report mode.           */
  1490. X              /***********************************************/
  1491. X            w->ctw.flags[CTW_APPL_MOUSE] = flag;
  1492. X            return TRUE;
  1493. X          }
  1494. X        break;
  1495. X      case 'S':
  1496. X          /***********************************************/
  1497. X          /*   Scroll a rectangular region.           */
  1498. X          /***********************************************/
  1499. X          if (arg_no != 5)
  1500. X            break;
  1501. X        r = args[0];
  1502. X        c = args[1];
  1503. X        h = args[2];
  1504. X        width = args[3];
  1505. X        num = args[4];
  1506. X        /***********************************************/
  1507. X        /*   Make sure arguments in range.           */
  1508. X        /***********************************************/
  1509. X        if (r < 0)
  1510. X            r = 0;
  1511. X        else if (r >= w->ctw.rows)
  1512. X            r = w->ctw.rows - 1;
  1513. X        if (c < 0)
  1514. X            c = 0;
  1515. X        else if (c >= w->ctw.columns)
  1516. X            c = w->ctw.columns - 1;
  1517. X        if (h <= 0)
  1518. X            h = 1;
  1519. X        else if (h >= w->ctw.rows - r)
  1520. X            h = w->ctw.rows - r;
  1521. X        if (width <= 0)
  1522. X            width = 1;
  1523. X        else if (width >= w->ctw.columns - width)
  1524. X            width = w->ctw.columns - width;
  1525. X        if (num < -h)
  1526. X            num = -h;
  1527. X        else if (num > h)
  1528. X            num = h;
  1529. X        scroll_rectangle(w, r, c, width, h, num);
  1530. X        return TRUE;
  1531. X      }
  1532. X    return FALSE;
  1533. X}
  1534. X/**********************************************************************/
  1535. X/*   Handle ISC's ESC[=... sequence.                      */
  1536. X/**********************************************************************/
  1537. Xstatic int
  1538. Xdo_escequ(CtwWidget w, int cmd, int arg_no, int *args) {
  1539. X    if (w->ctw.flags[CTW_ISC_DRIVER] == FALSE &&
  1540. X        w->ctw.flags[CTW_SCO_DRIVER] == FALSE) {
  1541. X        return FALSE;
  1542. X        }
  1543. X    switch (cmd) {
  1544. X      case 'C':
  1545. X          /***********************************************/
  1546. X          /*   Ignore cursor size changes for now.       */
  1547. X          /***********************************************/
  1548. X          return TRUE;
  1549. X      }
  1550. X    return FALSE;
  1551. X}
  1552. X/**********************************************************************/
  1553. X/*   Function  to  execute  the  Index  escape  sequences  (ESC D or  */
  1554. X/*   ESC[S).  Move  down  a  line  or  scroll screen if at bottom of  */
  1555. X/*   window.                                  */
  1556. X/**********************************************************************/
  1557. Xstatic void
  1558. Xdo_index(CtwWidget w) {
  1559. X    w->ctw.escp = NULL;
  1560. X    if (w->ctw.y >= w->ctw.scroll_bot-1)
  1561. X        scroll_up(w, 1);
  1562. X    else
  1563. X        w->ctw.y++;
  1564. X}
  1565. X/**********************************************************************/
  1566. X/*   Function  to  execute a Reverse Index escape sequence (ESC M or  */
  1567. X/*   ESC[T).  Move  up a line unless at top of region, in which case  */
  1568. X/*   scroll region down.                          */
  1569. X/**********************************************************************/
  1570. Xstatic void
  1571. Xdo_rev_index(CtwWidget w) {
  1572. X    w->ctw.escp = NULL;
  1573. X    if (w->ctw.y > w->ctw.scroll_top)
  1574. X        w->ctw.y--;
  1575. X    else
  1576. X        scroll_down(w, w->ctw.scroll_top, 1);
  1577. X}
  1578. Xstatic void
  1579. Xblank_line(CtwWidget w, vbyte_t *vp) {
  1580. X    int    i;
  1581. X    struct copy {
  1582. X        vbyte_t    array[80];
  1583. X        };
  1584. X    static struct copy blank;
  1585. X    static int first_time = TRUE;
  1586. X
  1587. X    if (first_time) {
  1588. X        for (i = 0; i < 80; i++) {
  1589. X            blank.array[i].vb_all = 0;
  1590. X            blank.array[i].vb_byte = ' ';
  1591. X            blank.array[i].vb_color = BG(0) | FG(7);
  1592. X            }
  1593. X        first_time = FALSE;
  1594. X        }
  1595. X
  1596. X    for (i = w->ctw.columns; i >= 80; i -= 80) {
  1597. X        *(struct copy *) vp = blank;
  1598. X        vp += 80;
  1599. X        }
  1600. X    while (i-- > 0) {
  1601. X        *vp++ = blank.array[0];
  1602. X        }
  1603. X}
  1604. X/**********************************************************************/
  1605. X/*   Do a fast delete line.                          */
  1606. X/**********************************************************************/
  1607. Xstatic void
  1608. Xdelete_line(CtwWidget w, int start_line, int num_lines) {
  1609. X    int    width, height;
  1610. X    int    src_x, src_y, dst_y;
  1611. X
  1612. X    width = w->ctw.font_width * w->ctw.columns;
  1613. X    height = w->ctw.font_height * (w->ctw.scroll_bot - start_line - num_lines);
  1614. X
  1615. X    src_x = 0;
  1616. X    src_y = w->ctw.font_height * (start_line + num_lines);
  1617. X    dst_y = w->ctw.font_height * start_line;
  1618. X    if (height) {
  1619. X        w->ctw.num_exposures++;
  1620. X        XCopyArea(XtDisplay(w), XtWindow(w), XtWindow(w), w->ctw.gc,
  1621. X            0, src_y, width, height,
  1622. X            0, dst_y);
  1623. X        }
  1624. X    XClearArea(XtDisplay(w), XtWindow(w),
  1625. X        0, dst_y + height, 
  1626. X        0, w->ctw.font_height * w->ctw.scroll_bot - (dst_y + height),
  1627. X        FALSE);
  1628. X}
  1629. X/**********************************************************************/
  1630. X/*   Do a fast insert line.                          */
  1631. X/**********************************************************************/
  1632. Xstatic void
  1633. Xinsert_line(CtwWidget w, int row, int bot, int nchunk) {
  1634. X    int    y, dst_y, height;
  1635. X
  1636. X    y = row * w->ctw.font_height;
  1637. X    dst_y = y + nchunk * w->ctw.font_height;
  1638. X    height = (bot - row - nchunk) * w->ctw.font_height;
  1639. X
  1640. X    if (height) {    
  1641. X        w->ctw.num_exposures++;
  1642. X        XCopyArea(XtDisplay(w), XtWindow(w), XtWindow(w), w->ctw.gc,
  1643. X            0, y, w->ctw.columns * w->ctw.font_width, height,
  1644. X            0, dst_y);
  1645. X        }
  1646. X
  1647. X    XClearArea(XtDisplay(w), XtWindow(w), 
  1648. X        0, y,
  1649. X        0, w->ctw.font_height * nchunk, False);
  1650. X
  1651. X}
  1652. X/**********************************************************************/
  1653. X/*   Wait  for  GraphicsExpose  or  NoExpose events to come in after  */
  1654. X/*   scrolling screen.                              */
  1655. X/**********************************************************************/
  1656. Xstatic void
  1657. Xwait_for_exposure(CtwWidget w) {
  1658. X    XEvent    ev;
  1659. X
  1660. X    while (w->ctw.num_exposures > 0) {
  1661. X        XWindowEvent(XtDisplay(w), XtWindow(w), ExposureMask, &ev);
  1662. X        switch (ev.type) {
  1663. X          case Expose:
  1664. X              exposed_region(w, ev.xexpose.x, ev.xexpose.y, 
  1665. X                ev.xexpose.width, ev.xexpose.height);
  1666. X            break;
  1667. X          case NoExpose:
  1668. X              break;
  1669. X            case GraphicsExpose:
  1670. X              exposed_region(w, ev.xgraphicsexpose.x, ev.xgraphicsexpose.y, 
  1671. X                ev.xgraphicsexpose.width, ev.xgraphicsexpose.height);
  1672. X            break;
  1673. X          }
  1674. X        w->ctw.num_exposures--;
  1675. X        }
  1676. X    w->ctw.num_exposures = 0;
  1677. X}
  1678. X/**********************************************************************/
  1679. X/*   Send input via the callback list to the owner.              */
  1680. X/**********************************************************************/
  1681. Xstatic void
  1682. Xsend_input(CtwWidget w, char *buf, int len) {
  1683. X    ctw_callback_t    reason;
  1684. X    reason.reason = CTW_INPUT;
  1685. X    reason.ptr = buf;
  1686. X    reason.len = len;
  1687. X
  1688. X    XtCallCallbacks((Widget)w, XtNkbdCallback, (caddr_t) &reason);
  1689. X}
  1690. Xstatic void
  1691. Xscroll_down(CtwWidget w, int start_line, int num_lines) {
  1692. X    int    i, j;
  1693. X    vbyte_t    *vp;
  1694. X    int    top = w->ctw.top_line;
  1695. X
  1696. X    if (num_lines > w->ctw.scroll_bot - w->ctw.scroll_top)
  1697. X        num_lines = w->ctw.scroll_bot - w->ctw.scroll_top;
  1698. X    for (j = 0; j < num_lines; j++) {
  1699. X        i = top + w->ctw.scroll_bot - 1;
  1700. X        vp = w->ctw.lines[i];
  1701. X        for (; i > top + start_line; i--) {
  1702. X            w->ctw.lines[i] = w->ctw.lines[i-1];
  1703. X            }
  1704. X        w->ctw.lines[top + start_line] = vp;
  1705. X        blank_line(w, vp);
  1706. X        }
  1707. X    insert_line(w, start_line, w->ctw.scroll_bot, num_lines);
  1708. X}
  1709. X/**********************************************************************/
  1710. X/*   Function to display a string internally.                  */
  1711. X/**********************************************************************/
  1712. Xstatic void
  1713. Xsend_str(CtwWidget w, char *buf, int len) {
  1714. X    vbyte_t    attr;
  1715. X    char    *escp = w->ctw.escp;
  1716. X
  1717. X    attr = w->ctw.attr;
  1718. X    w->ctw.attr.vb_color = FG(7) | BG(0);
  1719. X    ctw_add_string2(w, buf, len);
  1720. X    w->ctw.attr = attr;
  1721. X    w->ctw.escp = escp;
  1722. X}
  1723. X/**********************************************************************/
  1724. X/*   Clear to end of line.                          */
  1725. X/**********************************************************************/
  1726. Xstatic void
  1727. Xclear_to_eol(CtwWidget w) {
  1728. X    vbyte_t    space;
  1729. X    int    i;
  1730. X    int    y = w->ctw.top_line + w->ctw.y;
  1731. X
  1732. X    space.vb_all = 0;
  1733. X    space.vb_byte = ' ';
  1734. X    space.vb_color = FG(WHITE) | BG(BLACK);
  1735. X    for (i = w->ctw.x; i < w->ctw.columns; i++)
  1736. X        w->ctw.lines[y][i] = space;
  1737. X
  1738. X    XClearArea(XtDisplay(w), XtWindow(w), 
  1739. X        w->ctw.x * w->ctw.font_width,
  1740. X        w->ctw.y * w->ctw.font_height,
  1741. X        0, w->ctw.font_height,
  1742. X        False);
  1743. X
  1744. X}
  1745. X/**********************************************************************/
  1746. X/*   Clear from beginning of line to current character.              */
  1747. X/**********************************************************************/
  1748. Xstatic void
  1749. Xclear_from_beginning(CtwWidget w) {
  1750. X    vbyte_t    space;
  1751. X    int    i;
  1752. X    int    y = w->ctw.top_line + w->ctw.y;
  1753. X
  1754. X    space.vb_all = 0;
  1755. X    space.vb_byte = ' ';
  1756. X    space.vb_color = FG(WHITE) | BG(BLACK);
  1757. X    for (i = 0; i < w->ctw.x; i++)
  1758. X        w->ctw.lines[y][i] = space;
  1759. X
  1760. X    XClearArea(XtDisplay(w), XtWindow(w), 
  1761. X        0,
  1762. X        w->ctw.y * w->ctw.font_height,
  1763. X        w->ctw.x * w->ctw.font_width,
  1764. X        w->ctw.font_height,
  1765. X        False);
  1766. X}
  1767. X/**********************************************************************/
  1768. X/*   Clear entire screen.                          */
  1769. X/**********************************************************************/
  1770. Xstatic void
  1771. Xclear_screen(CtwWidget w) {
  1772. X    int    i;
  1773. X    int    y = w->ctw.top_line + w->ctw.y;
  1774. X
  1775. X    blank_line(w, w->ctw.lines[y]);
  1776. X    for (i = 1; i < w->ctw.rows; i++)
  1777. X        memcpy(w->ctw.lines[w->ctw.top_line + i], 
  1778. X            w->ctw.lines[y], sizeof(vbyte_t) * w->ctw.columns);
  1779. X
  1780. X    XClearWindow(XtDisplay(w), XtWindow(w));
  1781. X}
  1782. X/**********************************************************************/
  1783. X/*   Function  to  clear  a selected range of lines. Lines specified  */
  1784. X/*   relative to current window.                      */
  1785. X/**********************************************************************/
  1786. Xstatic void
  1787. Xclear_lines(CtwWidget w, int top, int bot) {
  1788. X    int    i;
  1789. X
  1790. X    if (top >= bot)
  1791. X        return;
  1792. X
  1793. X    top += w->ctw.top_line;
  1794. X    bot += w->ctw.top_line;
  1795. X        
  1796. X    for (i = top; i < bot; i++) {
  1797. X        blank_line(w, w->ctw.lines[i]);
  1798. X        }
  1799. X    XClearArea(XtDisplay(w), XtWindow(w),
  1800. X        0, top * w->ctw.font_height,
  1801. X        0, (bot - top) * w->ctw.font_height, FALSE);
  1802. X}
  1803. X/**********************************************************************/
  1804. X/*   Function  to  retrieve  current setting for the line at the top  */
  1805. X/*   of the screen.                              */
  1806. X/**********************************************************************/
  1807. Xint
  1808. Xctw_get_top_line(CtwWidget ctw) {
  1809. X    return ctw->ctw.top_line;
  1810. X}
  1811. X/**********************************************************************/
  1812. X/*   Function  to  retrieve  current setting for the line at the top  */
  1813. X/*   of the screen.                              */
  1814. X/**********************************************************************/
  1815. Xvoid
  1816. Xctw_set_top_line(CtwWidget ctw, int top_line) {
  1817. X    ctw_callback_t    reason;
  1818. X    int    old_top;
  1819. X    int    amt_to_scroll;
  1820. X
  1821. X    /***********************************************/
  1822. X    /*   Make sure value in range.               */
  1823. X    /***********************************************/
  1824. X    if (top_line < 0)
  1825. X        top_line = 0;
  1826. X    else if (top_line > ctw->ctw.max_lines)
  1827. X        top_line = ctw->ctw.max_lines;
  1828. X
  1829. X    /***********************************************/
  1830. X    /*   Save  the  top  line so that when we get  */
  1831. X    /*   some  more  data we put it where we left  */
  1832. X    /*   off and not where the user scrolled.      */
  1833. X    /***********************************************/
  1834. X    if (ctw->ctw.old_top_line < 0)
  1835. X        ctw->ctw.old_top_line = ctw->ctw.top_line;
  1836. X    if (top_line != ctw->ctw.top_line) {
  1837. X        old_top = ctw->ctw.top_line;
  1838. X        /***********************************************/
  1839. X        /*   Try  and  update window intelligently if  */
  1840. X        /*   we are scrolling a little up or down.     */
  1841. X        /***********************************************/
  1842. X        ctw->ctw.top_line = top_line;
  1843. X        if (top_line < old_top && top_line + ctw->ctw.rows > old_top) {
  1844. X            amt_to_scroll = old_top - top_line;
  1845. X            insert_line(ctw, 0, ctw->ctw.rows, amt_to_scroll);
  1846. X            update_region(ctw, 0, 0, 
  1847. X                amt_to_scroll + 1, ctw->ctw.columns + 1);
  1848. X            }
  1849. X        else if (top_line < old_top + ctw->ctw.rows) {
  1850. X            amt_to_scroll = top_line - old_top;
  1851. X            delete_line(ctw, 0, amt_to_scroll);
  1852. X            update_region(ctw, ctw->ctw.rows - amt_to_scroll, 0, 
  1853. X                ctw->ctw.rows, ctw->ctw.columns + 1);
  1854. X            }
  1855. X        else {
  1856. X            update_region(ctw, 0, 0, ctw->ctw.rows + 1, ctw->ctw.columns + 1);
  1857. X            }
  1858. X        if (ctw->ctw.num_exposures)
  1859. X            wait_for_exposure(ctw);
  1860. X        }
  1861. X    else
  1862. X        ctw->ctw.top_line = top_line;
  1863. X    /***********************************************/
  1864. X    /*   Let user affect a scrollbar.           */
  1865. X    /***********************************************/
  1866. X    reason.reason = CTW_TOP_LINE;
  1867. X    reason.top_line = ctw->ctw.top_line;
  1868. X    XtCallCallbacks((Widget)ctw, XtNtopCallback, (caddr_t) &reason);
  1869. X}
  1870. X/**********************************************************************/
  1871. X/*   Function to let user see current flags.                  */
  1872. X/**********************************************************************/
  1873. Xint
  1874. Xctw_get_attributes(CtwWidget w, int **ip, char ***strp) {
  1875. X    static char *attr_names[] = {
  1876. X    "Autowrap",
  1877. X    "Auto line feed",
  1878. X    "Application keypad",
  1879. X    "Application cursor",
  1880. X    "Application mouse",
  1881. X    "Color reset",
  1882. X    "Cut newlines",
  1883. X    "Destructive tabs",
  1884. X    "Erase black",
  1885. X    "Esc + literal",
  1886. X    "Font size",
  1887. X    "Literal mode",
  1888. X    "Newline glitch",
  1889. X    "PC char set",
  1890. X    "Reset",
  1891. X    "Scrolling region",
  1892. X    "Size",
  1893. X    "Slow mode",
  1894. X    "Smooth scroll",
  1895. X    "Sun keys",
  1896. X    "ISC driver",
  1897. X    "SCO driver",
  1898. X    (char *) NULL
  1899. X    };
  1900. X
  1901. X    w->ctw.flags[CTW_RESET] = FALSE;
  1902. X    w->ctw.flags[CTW_SUN_FUNCTION_KEYS] = w->ctw.sun_function_keys;
  1903. X    w->ctw.flags[CTW_FONT_SIZE] = (w->ctw.font_width << 16) | w->ctw.font_height;
  1904. X    w->ctw.flags[CTW_SIZE] = (w->ctw.columns << 16) | w->ctw.rows;
  1905. X    *ip = &w->ctw.flags[0];
  1906. X    *strp = attr_names;
  1907. X    return CTW_MAX_ATTR;
  1908. X}
  1909. X/**********************************************************************/
  1910. X/*   Function to set current attributes.                  */
  1911. X/**********************************************************************/
  1912. Xvoid
  1913. Xctw_set_attributes(CtwWidget w, int *ip) {
  1914. X    memcpy((char *) w->ctw.flags, (char *) ip, sizeof w->ctw.flags);
  1915. X    w->ctw.sun_function_keys = ip[CTW_SUN_FUNCTION_KEYS];
  1916. X
  1917. X    if (w->ctw.flags[CTW_ISC_DRIVER] || w->ctw.flags[CTW_SCO_DRIVER])
  1918. X        w->ctw.flags[CTW_PC_CHARSET] = TRUE;
  1919. X    else
  1920. X        w->ctw.flags[CTW_PC_CHARSET] = FALSE;
  1921. X
  1922. X    if (w->ctw.flags[CTW_RESET]) {
  1923. X        reset_screen(w);
  1924. X        }
  1925. X}
  1926. X
  1927. X/**********************************************************************/
  1928. X/*   Function  called  on  expiration  of timer to cause flashing to  */
  1929. X/*   occur.                                  */
  1930. X/**********************************************************************/
  1931. Xstatic void
  1932. Xcursor_flash_proc(XtPointer client_data, XtIntervalId *timer) {
  1933. X    CtwWidget    w = (CtwWidget) client_data;
  1934. X
  1935. X    /***********************************************/
  1936. X    /*   If we dont have focus, turn off timer.    */
  1937. X    /***********************************************/
  1938. X    w->ctw.cursor_timer = 0;
  1939. X    if (!w->ctw.have_focus) {
  1940. X        turn_on_cursor(w);
  1941. X        return;
  1942. X        }
  1943. X    if (w->ctw.flashrate) {
  1944. X        toggle_cursor(w);
  1945. X        w->ctw.cursor_timer = XtAppAddTimeOut(
  1946. X            XtWidgetToApplicationContext((Widget)w),
  1947. X            (long) w->ctw.flashrate, cursor_flash_proc, w);
  1948. X        }
  1949. X}
  1950. X/**********************************************************************/
  1951. X/*   Function to get the selection.                      */
  1952. X/**********************************************************************/
  1953. Xvoid
  1954. Xctw_get_selection(CtwWidget w) {
  1955. X    XtGetSelectionValue((Widget)w, XA_PRIMARY, XA_STRING, 
  1956. X        (XtSelectionCallbackProc)requestor_callback, 
  1957. X        NULL, w->ctw.timestamp);
  1958. X}
  1959. X/**********************************************************************/
  1960. X/*   Function  to  handle  the ESC[?r;c;w;h;numS scrolling rectangle  */
  1961. X/*   escape sequence.                              */
  1962. X/**********************************************************************/
  1963. Xstatic void
  1964. Xscroll_rectangle(CtwWidget ctw, int r, int c, int w, int h, int num) {
  1965. X    int    j, k;
  1966. X    vbyte_t    space;
  1967. X
  1968. X    space.vb_all = 0;
  1969. X    space.vb_byte = ' ';
  1970. X    space.vb_color = FG(GET_FG(ctw->ctw.attr.vb_color)) | BG(0);
  1971. X    if (num > 0) {
  1972. X        if (h != num)
  1973. X            XCopyArea(XtDisplay(ctw), XtWindow(ctw), XtWindow(ctw), ctw->ctw.gc,
  1974. X                c * ctw->ctw.font_width, 
  1975. X                (r + num) * ctw->ctw.font_height,
  1976. X                w * ctw->ctw.font_width,
  1977. X                (h - num) * ctw->ctw.font_height,
  1978. X                c * ctw->ctw.font_width, r * ctw->ctw.font_height);
  1979. X        XClearArea(XtDisplay(ctw), XtWindow(ctw),
  1980. X            c * ctw->ctw.font_width, 
  1981. X            (r + h - num) * ctw->ctw.font_height,
  1982. X            w * ctw->ctw.font_width, 
  1983. X            num * ctw->ctw.font_height, FALSE);
  1984. X        for (j = r; j < r + h - num; j++) {
  1985. X            memcpy(&ctw->ctw.lines[ctw->ctw.top_line + j][c],
  1986. X                &ctw->ctw.lines[ctw->ctw.top_line + j + num][c],
  1987. X                    w * sizeof(vbyte_t));
  1988. X            }
  1989. X        for ( ; j < r + h; j++) {
  1990. X            for (k = c; k < c + w; k++) {
  1991. X                ctw->ctw.lines[j][k] = space;
  1992. X                }
  1993. X            }
  1994. X        }
  1995. X    else {
  1996. X        num = -num;
  1997. X        if (h != num)
  1998. X            XCopyArea(XtDisplay(ctw), XtWindow(ctw), XtWindow(ctw), ctw->ctw.gc,
  1999. X                c * ctw->ctw.font_width, 
  2000. X                r * ctw->ctw.font_height,
  2001. X                w * ctw->ctw.font_width,
  2002. X                (h - num) * ctw->ctw.font_height,
  2003. X                c * ctw->ctw.font_width, (r + num) * ctw->ctw.font_height);
  2004. X        XClearArea(XtDisplay(ctw), XtWindow(ctw),
  2005. X            c * ctw->ctw.font_width, 
  2006. X            r * ctw->ctw.font_height,
  2007. X            w * ctw->ctw.font_width, 
  2008. X            num * ctw->ctw.font_height, FALSE);
  2009. X        for (j = r + h; j > r + num; j--) {
  2010. X            memcpy(&ctw->ctw.lines[ctw->ctw.top_line + j][c],
  2011. X                &ctw->ctw.lines[ctw->ctw.top_line + j - num][c],
  2012. X                    w * sizeof(vbyte_t));
  2013. X            }
  2014. X        for ( ; j >= r; j--) {
  2015. X            for (k = c; k < c + w; k++) {
  2016. X                ctw->ctw.lines[j][k] = space;
  2017. X                }
  2018. X            }
  2019. X        }
  2020. X}
  2021. X
  2022. SHAR_EOF
  2023. echo "File ctw.c is complete"
  2024. chmod 0644 ctw.c || echo "restore of ctw.c fails"
  2025. set `wc -c ctw.c`;Sum=$1
  2026. if test "$Sum" != "97005"
  2027. then echo original size 97005, current size $Sum;fi
  2028. echo "x - extracting ctw.h (Text)"
  2029. sed 's/^X//' << 'SHAR_EOF' > ctw.h &&
  2030. X/*#include <X11/copyright.h>*/
  2031. X
  2032. X/* $XConsortium: Template.h,v 1.4 89/07/21 01:41:49 kit Exp $ */
  2033. X
  2034. X#ifndef _Ctw_h
  2035. X#define _Ctw_h
  2036. X
  2037. X# if    defined(X11r3)
  2038. X#    define    XtPointer    void *
  2039. X# endif
  2040. X/****************************************************************
  2041. X *
  2042. X * Ctw widget
  2043. X *
  2044. X ****************************************************************/
  2045. X
  2046. X/* Resources:
  2047. X
  2048. X Name             Class        RepType        Default Value
  2049. X ----             -----        -------        -------------
  2050. X background         Background        Pixel        XtDefaultBackground
  2051. X border             BorderColor    Pixel        XtDefaultForeground
  2052. X borderWidth         BorderWidth    Dimension    1
  2053. X destroyCallback     Callback        Pointer        NULL
  2054. X height             Height        Dimension    0
  2055. X mappedWhenManaged   MappedWhenManaged    Boolean        True
  2056. X sensitive         Sensitive        Boolean        True
  2057. X width             Width        Dimension    0
  2058. X x             Position        Position    0
  2059. X y             Position        Position    0
  2060. X
  2061. XctwWidget:
  2062. X Name             Class        RepType        Default Value
  2063. X ----             -----        -------        -------------
  2064. X applCallback         ApplCallback    Callback    NULL
  2065. X font             Font        String        "fixed"
  2066. X cursorColor         CursorColor    Pixel        "red"
  2067. X rows             Rows        Integer        24
  2068. X columns         Columns        Integer        80
  2069. X kbdCallback         KbdCallback    Callback    NULL
  2070. X sunFunctionKeys     SunFunctionKeys    Boolean        false
  2071. X saveLines         SaveLines        Integer        512
  2072. X resizeCallback         ResizeCallback    Callback    NULL
  2073. X topCallback         TopCallback    Callback    NULL
  2074. X mouseCallback         MouseCallback    Callback    NULL
  2075. X geometry         Geometry        String        NULL
  2076. X flashrate         Flashrate        Integer        500
  2077. X font1             Font1        String        "5x8"
  2078. X font2             Font2        String        "6x9"
  2079. X font3             Font3        String        "6x10"
  2080. X font4             Font4        String        "6x13"
  2081. X font5             Font5        String        "7x13bold"
  2082. X font6             Font6        String        "8x13bold"
  2083. X hiliteBackground    HiliteBackground    String        "CadetBlue"
  2084. X hiliteForeground    HiliteForeground    String        "yellow"
  2085. X multiClickTime         MultiClickTime    Integer        250
  2086. X*/
  2087. X
  2088. X/**********************************************************************/
  2089. X/*   define  any  special  resource  names  here  that  are  not  in  */
  2090. X/*   <X11/StringDefs.h>                              */
  2091. X/**********************************************************************/
  2092. X
  2093. X#define    XtNapplCallback "applCallback"
  2094. X#define    XtNcursorColor    "cursorColor"
  2095. X#define    XtNrows "rows"
  2096. X#define    XtNcolumns "columns"
  2097. X#define    XtNkbdCallback "kbdCallback"
  2098. X#define    XtNsunFunctionKeys "sunFunctionKeys"
  2099. X#define    XtNsaveLines "saveLines"
  2100. X#define    XtNresizeCallback "resizeCallback"
  2101. X#define    XtNtopCallback "topCallback"
  2102. X#define    XtNmouseCallback "mouseCallback"
  2103. X/* #define    XtNgeometry "geometry" */
  2104. X#define    XtNflashrate "flashrate"
  2105. X#define XtNfont1 "font1"
  2106. X#define XtNfont2 "font2"
  2107. X#define XtNfont3 "font3"
  2108. X#define XtNfont4 "font4"
  2109. X#define XtNfont5 "font5"
  2110. X#define XtNfont6 "font6"
  2111. X#define    XtNhiliteBackground "hiliteBackground"
  2112. X#define    XtNhiliteForeground "hiliteForeground"
  2113. X#define    XtNmultiClickTime "multiClickTime"
  2114. X
  2115. X#define    XtCApplCallback "ApplCallback"
  2116. X#define    XtCCursorColor "CursorColor"
  2117. X#define    XtCRows "Rows"
  2118. X#define    XtCColumns "Columns"
  2119. X#define    XtCKbdCallback "KbdCallback"
  2120. X#define    XtCSunFunctionKeys "SunFunctionKeys"
  2121. X#define XtCSaveLines "SaveLines"
  2122. X#define    XtCResizeCallback "ResizeCallback"
  2123. X#define    XtCTopCallback "TopCallback"
  2124. X#define    XtCMouseCallback "MouseCallback"
  2125. X/* #define    XtCGeometry "Geometry" */
  2126. X#define    XtCFlashrate "Flashrate"
  2127. X#define XtCFont1 "Font1"
  2128. X#define XtCFont2 "Font2"
  2129. X#define XtCFont3 "Font3"
  2130. X#define XtCFont4 "Font4"
  2131. X#define XtCFont5 "Font5"
  2132. X#define XtCFont6 "Font6"
  2133. X#define    XtCHiliteBackground "HiliteBackground"
  2134. X#define    XtCHiliteForeground "HiliteForeground"
  2135. X#define    XtCMultiClickTime "MultiClickTime"
  2136. X
  2137. X/**********************************************************************/
  2138. X/*   declare specific CtwWidget class and instance datatypes          */
  2139. X/**********************************************************************/
  2140. X
  2141. Xtypedef struct _CtwClassRec*    CtwWidgetClass;
  2142. Xtypedef struct _CtwRec*        CtwWidget;
  2143. X
  2144. X/**********************************************************************/
  2145. X/*   declare the class constant                          */
  2146. X/**********************************************************************/
  2147. X
  2148. Xextern WidgetClass ctwWidgetClass;
  2149. X
  2150. X/**********************************************************************/
  2151. X/*   Declare a callback structure.                      */
  2152. X/**********************************************************************/
  2153. Xenum ctw_reasons {
  2154. X    CTW_INPUT,    /* Key or string input.    */
  2155. X    CTW_RESIZE,    /* Window was resized.  */
  2156. SHAR_EOF
  2157. echo "End of part 2"
  2158. echo "File ctw.h is continued in part 3"
  2159. echo "3" > s2_seq_.tmp
  2160. exit 0
  2161.  
  2162. exit 0 # Just in case...
  2163. -- 
  2164.   // chris@IMD.Sterling.COM            | Send comp.sources.x submissions to:
  2165. \X/  Amiga - The only way to fly!      |
  2166.  "It's intuitively obvious to the most |    sources-x@imd.sterling.com
  2167.   casual observer..."                  |
  2168.