home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / x / volume16 / xfig-2.1.3 / part11 < prev    next >
Internet Message Format  |  1992-02-04  |  57KB

  1. Path: uunet!cis.ohio-state.edu!zaphod.mps.ohio-state.edu!mips!msi!dcmartin
  2. From: envbvs@bea.lbl.gov (Brian V. Smith)
  3. Newsgroups: comp.sources.x
  4. Subject: v16i016: Xfig 2.1.3, Part11/25
  5. Message-ID: <1992Feb4.145946.838@msi.com>
  6. Date: 4 Feb 92 14:59:46 GMT
  7. References: <csx-16i006-xfig-2.1.3@uunet.UU.NET>
  8. Sender: dcmartin@msi.com (David C. Martin - Moderator)
  9. Organization: Molecular Simulations, Inc.
  10. Lines: 2255
  11. Approved: dcmartin@msi.com
  12. Originator: dcmartin@fascet
  13.  
  14. Submitted-by: envbvs@bea.lbl.gov (Brian V. Smith)
  15. Posting-number: Volume 16, Issue 16
  16. Archive-name: xfig-2.1.3/part11
  17.  
  18. # This is a shell archive.  Remove anything before this line, then feed it
  19. # into a shell via "sh file" or similar.  To overwrite existing files,
  20. # type "sh file -c".
  21. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  22. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  23. # If this archive is complete, you will see the following message at the end:
  24. #        "End of archive 11 (of 25)."
  25. # Contents:  Examples/README d_text.c u_list.c u_undo.c
  26. # Wrapped by dcmartin@fascet on Tue Feb  4 06:42:29 1992
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'Examples/README' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'Examples/README'\"
  30. else
  31. echo shar: Extracting \"'Examples/README'\" \(301 characters\)
  32. sed "s/^X//" >'Examples/README' <<'END_OF_FILE'
  33. XThe figure files have been uuencoded so that they may be mailed
  34. Xto comp.sources.x without any problem with the ^A (control A)
  35. Xin the text objects.
  36. X
  37. XTo decode them, do the following (csh):
  38. X
  39. Xforeach file (*.uu)
  40. X   uudecode $file
  41. Xend
  42. X
  43. Xor the following (ksh):
  44. X
  45. Xfor file in *.uu
  46. Xdo
  47. X    uudecode $file
  48. Xdone
  49. END_OF_FILE
  50. if test 301 -ne `wc -c <'Examples/README'`; then
  51.     echo shar: \"'Examples/README'\" unpacked with wrong size!
  52. fi
  53. # end of 'Examples/README'
  54. fi
  55. if test -f 'd_text.c' -a "${1}" != "-c" ; then 
  56.   echo shar: Will not clobber existing file \"'d_text.c'\"
  57. else
  58. echo shar: Extracting \"'d_text.c'\" \(15677 characters\)
  59. sed "s/^X//" >'d_text.c' <<'END_OF_FILE'
  60. X/*
  61. X * FIG : Facility for Interactive Generation of figures
  62. X * Copyright (c) 1985 by Supoj Sutanthavibul
  63. X *
  64. X * "Permission to use, copy, modify, distribute, and sell this software and its
  65. X * documentation for any purpose is hereby granted without fee, provided that
  66. X * the above copyright notice appear in all copies and that both that
  67. X * copyright notice and this permission notice appear in supporting
  68. X * documentation, and that the name of M.I.T. not be used in advertising or
  69. X * publicity pertaining to distribution of the software without specific,
  70. X * written prior permission.  M.I.T. makes no representations about the
  71. X * suitability of this software for any purpose.  It is provided "as is"
  72. X * without express or implied warranty."
  73. X *
  74. X */
  75. X
  76. X#include "fig.h"
  77. X#include "resources.h"
  78. X#include "mode.h"
  79. X#include "object.h"
  80. X#include "paintop.h"
  81. X#include "u_create.h"
  82. X#include "u_fonts.h"
  83. X#include "u_list.h"
  84. X#include "u_search.h"
  85. X#include "w_canvas.h"
  86. X#include "w_drawprim.h"
  87. X#include "w_mousefun.h"
  88. X#include "w_setup.h"
  89. X
  90. Xextern PIX_FONT lookfont();
  91. X
  92. X#define CTRL_H    8
  93. X#define NL    10
  94. X#define CR    13
  95. X#define CTRL_X    24
  96. X#define SP    32
  97. X#define DEL    127
  98. X
  99. X#define            BUF_SIZE    400
  100. X
  101. Xchar        prefix[BUF_SIZE],    /* part of string left of mouse click */
  102. X        suffix[BUF_SIZE];    /* part to right of click */
  103. Xint        leng_prefix, leng_suffix;
  104. Xstatic int    char_ht, char_wid;
  105. Xstatic int    base_x, base_y;
  106. X
  107. Xstatic PR_SIZE    tsize;
  108. Xstatic PR_SIZE    ssize;
  109. X
  110. Xstatic int    work_psflag, work_font, work_fontsize, work_textjust;
  111. Xstatic        finish_n_start();
  112. Xstatic        init_text_input(), cancel_text_input();
  113. Xstatic        wrap_up();
  114. Xint        char_handler();
  115. Xstatic F_text  *new_text();
  116. X
  117. Xstatic int    cpy_n_char();
  118. Xstatic int    prefix_length();
  119. Xstatic int    initialize_char_handler();
  120. Xstatic int    terminate_char_handler();
  121. Xstatic int    erase_char_string();
  122. Xstatic int    draw_char_string();
  123. Xstatic int    turn_on_blinking_cursor();
  124. Xstatic int    turn_off_blinking_cursor();
  125. Xstatic int    move_blinking_cursor();
  126. X
  127. Xtext_drawing_selected()
  128. X{
  129. X    canvas_kbd_proc = null_proc;
  130. X    canvas_locmove_proc = null_proc;
  131. X    canvas_middlebut_proc = null_proc;
  132. X    canvas_leftbut_proc = init_text_input;
  133. X    canvas_rightbut_proc = null_proc;
  134. X    set_mousefun("posn cursor", "", "");
  135. X    set_cursor(pencil_cursor);
  136. X}
  137. X
  138. Xstatic
  139. Xfinish_n_start(x, y)
  140. X{
  141. X    wrap_up();
  142. X    init_text_input(x, y);
  143. X}
  144. X
  145. Xfinish_text_input()
  146. X{
  147. X    wrap_up();
  148. X    text_drawing_selected();
  149. X    draw_mousefun_canvas();
  150. X}
  151. X
  152. Xstatic
  153. Xcancel_text_input()
  154. X{
  155. X    erase_char_string();
  156. X    terminate_char_handler();
  157. X    if (cur_t != NULL) {
  158. X    draw_text(cur_t, PAINT);
  159. X    toggle_textmarker(cur_t);
  160. X    }
  161. X    text_drawing_selected();
  162. X    draw_mousefun_canvas();
  163. X    reset_action_on();
  164. X}
  165. X
  166. Xstatic
  167. Xnew_text_line()
  168. X{
  169. X    wrap_up();
  170. X    cur_y += (int) ((float) char_ht * cur_textstep);
  171. X    cur_x = base_x;
  172. X    init_text_input(cur_x, cur_y);
  173. X}
  174. X
  175. Xstatic
  176. Xwrap_up()
  177. X{
  178. X    PR_SIZE        size;
  179. X
  180. X    reset_action_on();
  181. X    erase_char_string();
  182. X    terminate_char_handler();
  183. X
  184. X    if (cur_t == NULL) {    /* a brand new text */
  185. X    if (leng_prefix == 0)
  186. X        return;
  187. X    cur_t = new_text();
  188. X    add_text(cur_t);
  189. X    } else {            /* existing text modified */
  190. X    strcat(prefix, suffix);
  191. X    leng_prefix += leng_suffix;
  192. X    if (leng_prefix == 0) {
  193. X        delete_text(cur_t);
  194. X        return;
  195. X    }
  196. X    if (!strcmp(cur_t->cstring, prefix)) {
  197. X        /* we didn't change anything */
  198. X        draw_text(cur_t, PAINT);
  199. X        toggle_textmarker(cur_t);
  200. X        return;
  201. X    }
  202. X    new_t = copy_text(cur_t);
  203. X    change_text(cur_t, new_t);
  204. X    if (strlen(new_t->cstring) >= leng_prefix) {
  205. X        strcpy(new_t->cstring, prefix);
  206. X    } else {        /* free old and allocate new */
  207. X        cfree(new_t->cstring);
  208. X        if ((new_t->cstring = new_string(leng_prefix + 1)) != NULL)
  209. X        strcpy(new_t->cstring, prefix);
  210. X    }
  211. X    size = pf_textwidth(new_t->font, psfont_text(new_t), new_t->size,
  212. X                leng_prefix, prefix);
  213. X    new_t->height = size.y;
  214. X    new_t->length = size.x; /* in pixels */
  215. X    cur_t = new_t;
  216. X    }
  217. X    draw_text(cur_t, PAINT);
  218. X    toggle_textmarker(cur_t);
  219. X}
  220. X
  221. Xstatic
  222. Xinit_text_input(x, y)
  223. X    int            x, y;
  224. X{
  225. X    int            basx;
  226. X
  227. X    cur_x = x;
  228. X    cur_y = y;
  229. X
  230. X    set_action_on();
  231. X    set_mousefun("reposn cursor", "finish text", "cancel");
  232. X    draw_mousefun_canvas();
  233. X    canvas_kbd_proc = char_handler;
  234. X    canvas_middlebut_proc = finish_text_input;
  235. X    canvas_leftbut_proc = finish_n_start;
  236. X    canvas_rightbut_proc = cancel_text_input;
  237. X
  238. X    /*
  239. X     * set working font info to current settings. This allows user to change
  240. X     * font settings while we are in the middle of accepting text without
  241. X     * affecting this text i.e. we don't allow the text to change midway
  242. X     * through
  243. X     */
  244. X
  245. X    work_fontsize = cur_fontsize;
  246. X    work_font = using_ps ? cur_ps_font : cur_latex_font;
  247. X    work_psflag = using_ps;
  248. X    work_textjust = cur_textjust;
  249. X
  250. X    /* load the X font and get its id for this font, size */
  251. X    canvas_font = lookfont(x_fontnum(work_psflag, work_font), work_fontsize);
  252. X    char_ht = char_height(canvas_font);
  253. X    char_wid = char_width(canvas_font);
  254. X
  255. X    if ((cur_t = text_search(cur_x, cur_y)) == NULL) {    /* new text input */
  256. X    leng_prefix = leng_suffix = 0;
  257. X    *suffix = 0;
  258. X    prefix[leng_prefix] = '\0';
  259. X    base_x = cur_x;
  260. X    base_y = cur_y;
  261. X    } else {            /* clicked on existing text */
  262. X    if (hidden_text(cur_t)) {
  263. X        put_msg("Can't edit hidden text");
  264. X        reset_action_on();
  265. X        text_drawing_selected();
  266. X        return;
  267. X    }
  268. X    toggle_textmarker(cur_t);
  269. X    draw_text(cur_t, ERASE);
  270. X    switch (cur_t->type) {
  271. X    case T_LEFT_JUSTIFIED:
  272. X        basx = cur_t->base_x;
  273. X        break;
  274. X    case T_CENTER_JUSTIFIED:
  275. X        basx = cur_t->base_x - cur_t->length / 2;
  276. X        break;
  277. X    case T_RIGHT_JUSTIFIED:
  278. X        basx = cur_t->base_x - cur_t->length;
  279. X        break;
  280. X    }
  281. X    leng_suffix = strlen(cur_t->cstring);
  282. X    /* leng_prefix is # of char in the text before the cursor */
  283. X    leng_prefix = prefix_length(cur_t->cstring, cur_x - basx);
  284. X    leng_suffix -= leng_prefix;
  285. X    cpy_n_char(prefix, cur_t->cstring, leng_prefix);
  286. X    strcpy(suffix, &cur_t->cstring[leng_prefix]);
  287. X    tsize = pf_textwidth(cur_t->font, psfont_text(cur_t), cur_t->size,
  288. X                 leng_prefix, prefix);
  289. X    ssize = pf_textwidth(cur_t->font, psfont_text(cur_t), cur_t->size,
  290. X                 leng_suffix, suffix);
  291. X    cur_x = base_x = basx;
  292. X    cur_y = base_y = cur_t->base_y;
  293. X    cur_x += tsize.x;
  294. X    work_font = cur_t->font;
  295. X    work_fontsize = cur_t->size;
  296. X    work_textjust = cur_t->type;
  297. X    }
  298. X    initialize_char_handler(canvas_win, finish_text_input,
  299. X                base_x, base_y);
  300. X    draw_char_string();
  301. X}
  302. X
  303. Xstatic
  304. XF_text           *
  305. Xnew_text()
  306. X{
  307. X    F_text       *text;
  308. X    PR_SIZE        size;
  309. X
  310. X    if ((text = create_text()) == NULL)
  311. X    return (NULL);
  312. X
  313. X    if ((text->cstring = new_string(leng_prefix + 1)) == NULL) {
  314. X    free((char *) text);
  315. X    return (NULL);
  316. X    }
  317. X    text->type = work_textjust;
  318. X    text->font = work_font;    /* put in current font number */
  319. X    text->size = work_fontsize; /* added 9/25/89 B.V.Smith */
  320. X    text->angle = cur_angle;
  321. X    text->flags = cur_textflags;
  322. X    text->color = cur_color;
  323. X    text->depth = 0;
  324. X    text->pen = 0;
  325. X    size = pf_textwidth(text->font, psfont_text(text), text->size,
  326. X            leng_prefix, prefix);
  327. X    text->length = size.x;    /* in pixels */
  328. X    text->height = size.y;    /* in pixels */
  329. X    text->base_x = base_x;
  330. X    text->base_y = base_y;
  331. X    strcpy(text->cstring, prefix);
  332. X    text->next = NULL;
  333. X    return (text);
  334. X}
  335. X
  336. Xstatic int
  337. Xcpy_n_char(dst, src, n)
  338. X    char       *dst, *src;
  339. X    int            n;
  340. X{
  341. X    /* src must be longer than n chars */
  342. X
  343. X    while (n--)
  344. X    *dst++ = *src++;
  345. X    *dst = '\0';
  346. X}
  347. X
  348. Xstatic int
  349. Xprefix_length(string, where_p)
  350. X    char       *string;
  351. X    int            where_p;
  352. X{
  353. X    /* c stands for character unit and p for pixel unit */
  354. X    int            l, len_c, len_p;
  355. X    int            char_wid, where_c;
  356. X    PR_SIZE        size;
  357. X
  358. X    if (canvas_font == NULL)
  359. X    fprintf(stderr, "xfig: Error, in prefix_length, canvas_font = NULL\n");
  360. X    len_c = strlen(string);
  361. X    size = pf_textwidth(cur_t->font, psfont_text(cur_t), cur_t->size,
  362. X            len_c, string);
  363. X    len_p = size.x;
  364. X    if (where_p >= len_p)
  365. X    return (len_c);        /* entire string is the prefix */
  366. X
  367. X    char_wid = char_width(canvas_font);
  368. X    where_c = where_p / char_wid;    /* estimated char position */
  369. X    size = pf_textwidth(cur_t->font, psfont_text(cur_t), cur_t->size,
  370. X            where_c, string);
  371. X    l = size.x;            /* actual length (pixels) of string of
  372. X                 * where_c chars */
  373. X    if (l < where_p) {
  374. X    do {            /* add the width of next char to l */
  375. X        l += (char_wid = char_advance(canvas_font, (unsigned char) string[where_c++]));
  376. X    } while (l < where_p);
  377. X    if (l - (char_wid >> 1) >= where_p)
  378. X        where_c--;
  379. X    } else if (l > where_p) {
  380. X    do {            /* subtract the width of last char from l */
  381. X        l -= (char_wid = char_advance(canvas_font, (unsigned char) string[--where_c]));
  382. X    } while (l > where_p);
  383. X    if (l + (char_wid >> 1) >= where_p)
  384. X        where_c++;
  385. X    }
  386. X    if (where_c < 0) {
  387. X    fprintf(stderr, "xfig file %s line %d: Error in prefix_length - adjusted\n", __FILE__, __LINE__);
  388. X    where_c = 0;
  389. X    }
  390. X    return (where_c);
  391. X}
  392. X
  393. X/*******************************************************************
  394. X
  395. X    char handling routines
  396. X
  397. X*******************************************************************/
  398. X
  399. X#define            BLINK_INTERVAL    700    /* milliseconds blink rate */
  400. X
  401. Xstatic PIXWIN    pw;
  402. Xstatic int    ch_height;
  403. Xstatic int    cbase_x, cbase_y;
  404. Xstatic float    rbase_x, rcur_x;
  405. Xstatic int    obase_x;
  406. X
  407. Xstatic        (*cr_proc) ();
  408. X
  409. Xstatic
  410. Xdraw_cursor(x, y)
  411. X    int            x, y;
  412. X{
  413. X    pw_vector(pw, x, y, x, y - ch_height, INV_PAINT, 1, RUBBER_LINE, 0.0,
  414. X          DEFAULT_COLOR);
  415. X}
  416. X
  417. Xstatic int
  418. Xinitialize_char_handler(p, cr, bx, by)
  419. X    PIXWIN        p;
  420. X    int            (*cr) ();
  421. X    int            bx, by;
  422. X{
  423. X    pw = p;
  424. X    cr_proc = cr;
  425. X    rbase_x = obase_x = cbase_x = bx;    /* keep real base so dont have
  426. X                     * roundoff */
  427. X    rcur_x = cur_x;
  428. X    cbase_y = by;
  429. X
  430. X    ch_height = char_height(canvas_font);
  431. X    turn_on_blinking_cursor(draw_cursor, draw_cursor,
  432. X                cur_x, cur_y, (long) BLINK_INTERVAL);
  433. X}
  434. X
  435. Xstatic int
  436. Xterminate_char_handler()
  437. X{
  438. X    turn_off_blinking_cursor();
  439. X    cr_proc = NULL;
  440. X}
  441. X
  442. X/*
  443. X * we use INV_PAINT below instead of ERASE and PAINT to avoid interactions
  444. X * with the cursor.  It means that we need to do a ERASE before we start the
  445. X * cursor and a PAINT after it is turned off.
  446. X */
  447. X
  448. Xstatic int
  449. Xerase_char_string()
  450. X{
  451. X    pw_text(pw, cbase_x, cbase_y, INV_PAINT, work_font, work_psflag,
  452. X        work_fontsize, prefix, DEFAULT_COLOR);
  453. X    if (leng_suffix)
  454. X    pw_text(pw, cur_x, cbase_y, INV_PAINT, work_font, work_psflag,
  455. X        work_fontsize, suffix, DEFAULT_COLOR);
  456. X}
  457. X
  458. Xstatic int
  459. Xdraw_char_string()
  460. X{
  461. X    pw_text(pw, cbase_x, cbase_y, INV_PAINT,
  462. X        work_font, work_psflag, work_fontsize, prefix, DEFAULT_COLOR);
  463. X    if (leng_suffix)
  464. X    pw_text(pw, cur_x, cbase_y, INV_PAINT,
  465. X          work_font, work_psflag, work_fontsize, suffix, DEFAULT_COLOR);
  466. X    move_blinking_cursor(cur_x, cur_y);
  467. X}
  468. X
  469. Xchar_handler(c)
  470. X    unsigned char   c;
  471. X{
  472. X    int            cwidth;
  473. X
  474. X    if (cr_proc == NULL)
  475. X    return;
  476. X
  477. X    if (c == CR || c == NL) {
  478. X    erase_char_string();
  479. X    /*
  480. X     * comment out the cr_proc() and un-comment the new_text-line() to
  481. X     * have new text automatically start after old
  482. X     */
  483. X    /* cr_proc(); */
  484. X    new_text_line();
  485. X    } else if (c == DEL || c == CTRL_H) {
  486. X    if (leng_prefix > 0) {
  487. X        /*
  488. X         * To increase efficiency you could remove the erase_char_string
  489. X         * from the next line and add the following in the switch below:
  490. X         * LEFT:            erase_suffix CENTER:    erase_prefix
  491. X         * erase_suffix RIGHT:    erase_prefix A similar thing would
  492. X         * need to be done for draw_char_string and for the other text
  493. X         * functions below.
  494. X         */
  495. X        erase_char_string();
  496. X        cwidth = char_advance(canvas_font, (unsigned char) prefix[leng_prefix - 1]);
  497. X        /* correct text/cursor posn for justification and zoom factor */
  498. X        switch (work_textjust) {
  499. X        case T_LEFT_JUSTIFIED:
  500. X        /* move the suffix to the left */
  501. X        rcur_x -= (float) (cwidth);
  502. X        break;
  503. X        case T_CENTER_JUSTIFIED:
  504. X        /* advance right by cwidth/2 */
  505. X        rbase_x += (float) (cwidth / 2.0);
  506. X        /* move suffix left by cwidth/2 */
  507. X        rcur_x -= (float) (cwidth / 2.0);
  508. X        break;
  509. X        case T_RIGHT_JUSTIFIED:
  510. X        /* move prefix to right */
  511. X        rbase_x += (float) (cwidth);
  512. X        break;
  513. X        }
  514. X        prefix[--leng_prefix] = '\0';
  515. X        cbase_x = rbase_x;    /* fix */
  516. X        cur_x = rcur_x;
  517. X        draw_char_string();
  518. X    }
  519. X    } else if (c == CTRL_X) {
  520. X    if (leng_prefix > 0) {
  521. X        erase_char_string();
  522. X        switch (work_textjust) {
  523. X        case T_CENTER_JUSTIFIED:
  524. X        while (leng_prefix--)    /* subtract char width/2 per char */
  525. X            rcur_x -= char_advance(canvas_font, (unsigned char) prefix[leng_prefix]) /
  526. X            2.0;
  527. X        cur_x = cbase_x = rbase_x = rcur_x;
  528. X        break;
  529. X        case T_RIGHT_JUSTIFIED:
  530. X        cbase_x = rbase_x = cur_x = rcur_x;
  531. X        break;
  532. X        case T_LEFT_JUSTIFIED:
  533. X        cur_x = rcur_x = cbase_x = rbase_x;
  534. X        break;
  535. X        }
  536. X        leng_prefix = 0;
  537. X        *prefix = '\0';
  538. X        draw_char_string();
  539. X    }
  540. X    } else if (c < SP) {
  541. X    put_msg("Invalid character ignored");
  542. X    } else if (leng_prefix + leng_suffix == BUF_SIZE) {
  543. X    put_msg("Text buffer is full, character is ignored");
  544. X    } else {            /* normal text character */
  545. X    erase_char_string();
  546. X    cwidth = char_advance(canvas_font, (unsigned char) c);
  547. X    /* correct text/cursor posn for justification and zoom factor */
  548. X    switch (work_textjust) {
  549. X    case T_LEFT_JUSTIFIED:
  550. X        /* move the suffix to the right */
  551. X        rcur_x += (float) (cwidth);
  552. X        break;
  553. X    case T_CENTER_JUSTIFIED:
  554. X        /* advance left by cwidth/2 */
  555. X        rbase_x -= (float) (cwidth / 2.0);
  556. X        /* move suffix right by cwidth/2 */
  557. X        rcur_x += (float) (cwidth / 2.0);
  558. X        break;
  559. X    case T_RIGHT_JUSTIFIED:
  560. X        /* move prefix to left */
  561. X        rbase_x -= (float) (cwidth);
  562. X        break;
  563. X    }
  564. X    prefix[leng_prefix++] = c;
  565. X    prefix[leng_prefix] = '\0';
  566. X    cbase_x = rbase_x;    /* fix */
  567. X    cur_x = rcur_x;
  568. X    draw_char_string();
  569. X    }
  570. X}
  571. X
  572. X/*******************************************************************
  573. X
  574. X    blinking cursor handling routines
  575. X
  576. X*******************************************************************/
  577. X
  578. Xstatic int    cursor_on, cursor_is_moving;
  579. Xstatic int    cursor_x, cursor_y;
  580. Xstatic int    (*erase) ();
  581. Xstatic int    (*draw) ();
  582. Xstatic XtTimerCallbackProc blink();
  583. Xstatic unsigned long blink_timer;
  584. Xstatic XtIntervalId blinkid;
  585. Xstatic int    stop_blinking = False;
  586. Xstatic int    cur_is_blinking = False;
  587. X
  588. Xstatic int
  589. Xturn_on_blinking_cursor(draw_cursor, erase_cursor, x, y, msec)
  590. X    int            (*draw_cursor) ();
  591. X    int            (*erase_cursor) ();
  592. X    int            x, y;
  593. X    unsigned long   msec;
  594. X{
  595. X    draw = draw_cursor;
  596. X    erase = erase_cursor;
  597. X    cursor_is_moving = 0;
  598. X    cursor_x = x;
  599. X    cursor_y = y;
  600. X    blink_timer = msec;
  601. X    draw(x, y);
  602. X    cursor_on = 1;
  603. X    if (!cur_is_blinking) {    /* if we are already blinking, don't request
  604. X                 * another */
  605. X    blinkid = XtAppAddTimeOut(tool_app, blink_timer, (XtTimerCallbackProc) blink,
  606. X                  (XtPointer) NULL);
  607. X    cur_is_blinking = True;
  608. X    }
  609. X    stop_blinking = False;
  610. X}
  611. X
  612. Xstatic int
  613. Xturn_off_blinking_cursor()
  614. X{
  615. X    if (cursor_on)
  616. X    erase(cursor_x, cursor_y);
  617. X    stop_blinking = True;
  618. X}
  619. X
  620. Xstatic        XtTimerCallbackProc
  621. Xblink(client_data, id)
  622. X#if XtSpecificationRelease >= 4
  623. X    XtPointer        client_data;
  624. X
  625. X#else
  626. X    caddr_t        client_data;
  627. X
  628. X#endif
  629. X    XtIntervalId   *id;
  630. X{
  631. X    if (!stop_blinking) {
  632. X    if (cursor_is_moving)
  633. X        return (0);
  634. X    if (cursor_on) {
  635. X        erase(cursor_x, cursor_y);
  636. X        cursor_on = 0;
  637. X    } else {
  638. X        draw(cursor_x, cursor_y);
  639. X        cursor_on = 1;
  640. X    }
  641. X    blinkid = XtAppAddTimeOut(tool_app, blink_timer, (XtTimerCallbackProc) blink,
  642. X                  (XtPointer) NULL);
  643. X    } else {
  644. X    stop_blinking = False;    /* signal that we've stopped */
  645. X    cur_is_blinking = False;
  646. X    }
  647. X    return (0);
  648. X}
  649. X
  650. Xstatic int
  651. Xmove_blinking_cursor(x, y)
  652. X    int            x, y;
  653. X{
  654. X    cursor_is_moving = 1;
  655. X    if (cursor_on)
  656. X    erase(cursor_x, cursor_y);
  657. X    cursor_x = x;
  658. X    cursor_y = y;
  659. X    draw(cursor_x, cursor_y);
  660. X    cursor_on = 1;
  661. X    cursor_is_moving = 0;
  662. X}
  663. END_OF_FILE
  664. if test 15677 -ne `wc -c <'d_text.c'`; then
  665.     echo shar: \"'d_text.c'\" unpacked with wrong size!
  666. fi
  667. # end of 'd_text.c'
  668. fi
  669. if test -f 'u_list.c' -a "${1}" != "-c" ; then 
  670.   echo shar: Will not clobber existing file \"'u_list.c'\"
  671. else
  672. echo shar: Extracting \"'u_list.c'\" \(18136 characters\)
  673. sed "s/^X//" >'u_list.c' <<'END_OF_FILE'
  674. X/*
  675. X * FIG : Facility for Interactive Generation of figures
  676. X * Copyright (c) 1985 by Supoj Sutanthavibul
  677. X *
  678. X * "Permission to use, copy, modify, distribute, and sell this software and its
  679. X * documentation for any purpose is hereby granted without fee, provided that
  680. X * the above copyright notice appear in all copies and that both that
  681. X * copyright notice and this permission notice appear in supporting
  682. X * documentation, and that the name of M.I.T. not be used in advertising or
  683. X * publicity pertaining to distribution of the software without specific,
  684. X * written prior permission.  M.I.T. makes no representations about the
  685. X * suitability of this software for any purpose.  It is provided "as is"
  686. X * without express or implied warranty."
  687. X *
  688. X */
  689. X
  690. X#include "fig.h"
  691. X#include "mode.h"
  692. X#include "object.h"
  693. X#include "resources.h"
  694. X#include "paintop.h"
  695. X#include "u_create.h"
  696. X#include "u_list.h"
  697. X#include "u_elastic.h"
  698. X#include "u_undo.h"
  699. X
  700. Xvoid
  701. Xlist_delete_arc(arc_list, arc)
  702. X    F_arc      **arc_list, *arc;
  703. X{
  704. X    F_arc       *a, *aa;
  705. X
  706. X    if (*arc_list == NULL)
  707. X    return;
  708. X    if (arc == NULL)
  709. X    return;
  710. X
  711. X    for (a = aa = *arc_list; aa != NULL; a = aa, aa = aa->next) {
  712. X    if (aa == arc) {
  713. X        if (aa == *arc_list)
  714. X        *arc_list = (*arc_list)->next;
  715. X        else
  716. X        a->next = aa->next;
  717. X        break;
  718. X    }
  719. X    }
  720. X    arc->next = NULL;
  721. X}
  722. X
  723. Xvoid
  724. Xlist_delete_ellipse(ellipse_list, ellipse)
  725. X    F_ellipse      **ellipse_list, *ellipse;
  726. X{
  727. X    F_ellipse       *q, *r;
  728. X
  729. X    if (*ellipse_list == NULL)
  730. X    return;
  731. X    if (ellipse == NULL)
  732. X    return;
  733. X
  734. X    for (q = r = *ellipse_list; r != NULL; q = r, r = r->next) {
  735. X    if (r == ellipse) {
  736. X        if (r == *ellipse_list)
  737. X        *ellipse_list = (*ellipse_list)->next;
  738. X        else
  739. X        q->next = r->next;
  740. X        break;
  741. X    }
  742. X    }
  743. X    ellipse->next = NULL;
  744. X}
  745. X
  746. Xvoid
  747. Xlist_delete_line(line_list, line)
  748. X    F_line       *line, **line_list;
  749. X{
  750. X    F_line       *q, *r;
  751. X
  752. X    if (*line_list == NULL)
  753. X    return;
  754. X    if (line == NULL)
  755. X    return;
  756. X
  757. X    for (q = r = *line_list; r != NULL; q = r, r = r->next) {
  758. X    if (r == line) {
  759. X        if (r == *line_list)
  760. X        *line_list = (*line_list)->next;
  761. X        else
  762. X        q->next = r->next;
  763. X        break;
  764. X    }
  765. X    }
  766. X    line->next = NULL;
  767. X}
  768. X
  769. Xvoid
  770. Xlist_delete_spline(spline_list, spline)
  771. X    F_spline      **spline_list, *spline;
  772. X{
  773. X    F_spline       *q, *r;
  774. X
  775. X    if (*spline_list == NULL)
  776. X    return;
  777. X    if (spline == NULL)
  778. X    return;
  779. X
  780. X    for (q = r = *spline_list; r != NULL; q = r, r = r->next) {
  781. X    if (r == spline) {
  782. X        if (r == *spline_list)
  783. X        *spline_list = (*spline_list)->next;
  784. X        else
  785. X        q->next = r->next;
  786. X        break;
  787. X    }
  788. X    }
  789. X    spline->next = NULL;
  790. X}
  791. X
  792. Xvoid
  793. Xlist_delete_text(text_list, text)
  794. X    F_text      **text_list, *text;
  795. X{
  796. X    F_text       *q, *r;
  797. X
  798. X    if (*text_list == NULL)
  799. X    return;
  800. X    if (text == NULL)
  801. X    return;
  802. X
  803. X    for (q = r = *text_list; r != NULL; q = r, r = r->next)
  804. X    if (r == text) {
  805. X        if (r == *text_list)
  806. X        *text_list = text->next;
  807. X        else
  808. X        q->next = text->next;
  809. X        break;
  810. X    }
  811. X    text->next = NULL;
  812. X}
  813. X
  814. Xvoid
  815. Xlist_delete_compound(list, compound)
  816. X    F_compound      **list, *compound;
  817. X{
  818. X    F_compound       *c, *cc;
  819. X
  820. X    if (*list == NULL)
  821. X    return;
  822. X    if (compound == NULL)
  823. X    return;
  824. X
  825. X    for (cc = c = *list; c != NULL; cc = c, c = c->next) {
  826. X    if (c == compound) {
  827. X        if (c == *list)
  828. X        *list = (*list)->next;
  829. X        else
  830. X        cc->next = c->next;
  831. X        break;
  832. X    }
  833. X    }
  834. X    compound->next = NULL;
  835. X}
  836. X
  837. Xvoid
  838. Xlist_add_arc(arc_list, a)
  839. X    F_arc      **arc_list, *a;
  840. X{
  841. X    F_arc       *aa;
  842. X
  843. X    a->next = NULL;
  844. X    if ((aa = last_arc(*arc_list)) == NULL)
  845. X    *arc_list = a;
  846. X    else
  847. X    aa->next = a;
  848. X}
  849. X
  850. Xvoid
  851. Xlist_add_ellipse(ellipse_list, e)
  852. X    F_ellipse      **ellipse_list, *e;
  853. X{
  854. X    F_ellipse       *ee;
  855. X
  856. X    e->next = NULL;
  857. X    if ((ee = last_ellipse(*ellipse_list)) == NULL)
  858. X    *ellipse_list = e;
  859. X    else
  860. X    ee->next = e;
  861. X}
  862. X
  863. Xvoid
  864. Xlist_add_line(line_list, l)
  865. X    F_line      **line_list, *l;
  866. X{
  867. X    F_line       *ll;
  868. X
  869. X    l->next = NULL;
  870. X    if ((ll = last_line(*line_list)) == NULL)
  871. X    *line_list = l;
  872. X    else
  873. X    ll->next = l;
  874. X}
  875. X
  876. Xvoid
  877. Xlist_add_spline(spline_list, s)
  878. X    F_spline      **spline_list, *s;
  879. X{
  880. X    F_spline       *ss;
  881. X
  882. X    s->next = NULL;
  883. X    if ((ss = last_spline(*spline_list)) == NULL)
  884. X    *spline_list = s;
  885. X    else
  886. X    ss->next = s;
  887. X}
  888. X
  889. Xvoid
  890. Xlist_add_text(text_list, t)
  891. X    F_text      **text_list, *t;
  892. X{
  893. X    F_text       *tt;
  894. X
  895. X    t->next = NULL;
  896. X    if ((tt = last_text(*text_list)) == NULL)
  897. X    *text_list = t;
  898. X    else
  899. X    tt->next = t;
  900. X}
  901. X
  902. Xvoid
  903. Xlist_add_compound(list, c)
  904. X    F_compound      **list, *c;
  905. X{
  906. X    F_compound       *cc;
  907. X
  908. X    c->next = NULL;
  909. X    if ((cc = last_compound(*list)) == NULL)
  910. X    *list = c;
  911. X    else
  912. X    cc->next = c;
  913. X}
  914. X
  915. Xvoid
  916. Xdelete_line(old_l)
  917. X    F_line       *old_l;
  918. X{
  919. X    list_delete_line(&objects.lines, old_l);
  920. X    clean_up();
  921. X    set_latestline(old_l);
  922. X    set_action_object(F_DELETE, O_POLYLINE);
  923. X    set_modifiedflag();
  924. X}
  925. X
  926. Xvoid
  927. Xdelete_arc(old_a)
  928. X    F_arc       *old_a;
  929. X{
  930. X    list_delete_arc(&objects.arcs, old_a);
  931. X    clean_up();
  932. X    set_latestarc(old_a);
  933. X    set_action_object(F_DELETE, O_ARC);
  934. X    set_modifiedflag();
  935. X}
  936. X
  937. Xvoid
  938. Xdelete_ellipse(old_e)
  939. X    F_ellipse       *old_e;
  940. X{
  941. X    list_delete_ellipse(&objects.ellipses, old_e);
  942. X    clean_up();
  943. X    set_latestellipse(old_e);
  944. X    set_action_object(F_DELETE, O_ELLIPSE);
  945. X    set_modifiedflag();
  946. X}
  947. X
  948. Xvoid
  949. Xdelete_text(old_t)
  950. X    F_text       *old_t;
  951. X{
  952. X    list_delete_text(&objects.texts, old_t);
  953. X    clean_up();
  954. X    set_latesttext(old_t);
  955. X    set_action_object(F_DELETE, O_TEXT);
  956. X    set_modifiedflag();
  957. X}
  958. X
  959. Xvoid
  960. Xdelete_spline(old_s)
  961. X    F_spline       *old_s;
  962. X{
  963. X    list_delete_spline(&objects.splines, old_s);
  964. X    clean_up();
  965. X    set_latestspline(old_s);
  966. X    set_action_object(F_DELETE, O_SPLINE);
  967. X    set_modifiedflag();
  968. X}
  969. X
  970. Xvoid
  971. Xdelete_compound(old_c)
  972. X    F_compound       *old_c;
  973. X{
  974. X    list_delete_compound(&objects.compounds, old_c);
  975. X    clean_up();
  976. X    set_latestcompound(old_c);
  977. X    set_action_object(F_DELETE, O_COMPOUND);
  978. X    set_modifiedflag();
  979. X}
  980. X
  981. Xvoid
  982. Xadd_line(new_l)
  983. X    F_line       *new_l;
  984. X{
  985. X    list_add_line(&objects.lines, new_l);
  986. X    clean_up();
  987. X    set_latestline(new_l);
  988. X    set_action_object(F_ADD, O_POLYLINE);
  989. X    set_modifiedflag();
  990. X}
  991. X
  992. Xvoid
  993. Xadd_arc(new_a)
  994. X    F_arc       *new_a;
  995. X{
  996. X    list_add_arc(&objects.arcs, new_a);
  997. X    clean_up();
  998. X    set_latestarc(new_a);
  999. X    set_action_object(F_ADD, O_ARC);
  1000. X    set_modifiedflag();
  1001. X}
  1002. X
  1003. Xvoid
  1004. Xadd_ellipse(new_e)
  1005. X    F_ellipse       *new_e;
  1006. X{
  1007. X    list_add_ellipse(&objects.ellipses, new_e);
  1008. X    clean_up();
  1009. X    set_latestellipse(new_e);
  1010. X    set_action_object(F_ADD, O_ELLIPSE);
  1011. X    set_modifiedflag();
  1012. X}
  1013. X
  1014. Xvoid
  1015. Xadd_text(new_t)
  1016. X    F_text       *new_t;
  1017. X{
  1018. X    list_add_text(&objects.texts, new_t);
  1019. X    clean_up();
  1020. X    set_latesttext(new_t);
  1021. X    set_action_object(F_ADD, O_TEXT);
  1022. X    set_modifiedflag();
  1023. X}
  1024. X
  1025. Xvoid
  1026. Xadd_spline(new_s)
  1027. X    F_spline       *new_s;
  1028. X{
  1029. X    list_add_spline(&objects.splines, new_s);
  1030. X    clean_up();
  1031. X    set_latestspline(new_s);
  1032. X    set_action_object(F_ADD, O_SPLINE);
  1033. X    set_modifiedflag();
  1034. X}
  1035. X
  1036. Xvoid
  1037. Xadd_compound(new_c)
  1038. X    F_compound       *new_c;
  1039. X{
  1040. X    list_add_compound(&objects.compounds, new_c);
  1041. X    clean_up();
  1042. X    set_latestcompound(new_c);
  1043. X    set_action_object(F_ADD, O_COMPOUND);
  1044. X    set_modifiedflag();
  1045. X}
  1046. X
  1047. X
  1048. Xvoid
  1049. Xchange_line(old_l, new_l)
  1050. X    F_line       *old_l, *new_l;
  1051. X{
  1052. X    list_delete_line(&objects.lines, old_l);
  1053. X    list_add_line(&objects.lines, new_l);
  1054. X    clean_up();
  1055. X    old_l->next = new_l;
  1056. X    set_latestline(old_l);
  1057. X    set_action_object(F_CHANGE, O_POLYLINE);
  1058. X    set_modifiedflag();
  1059. X}
  1060. X
  1061. Xvoid
  1062. Xchange_arc(old_a, new_a)
  1063. X    F_arc       *old_a, *new_a;
  1064. X{
  1065. X    list_delete_arc(&objects.arcs, old_a);
  1066. X    list_add_arc(&objects.arcs, new_a);
  1067. X    clean_up();
  1068. X    old_a->next = new_a;
  1069. X    set_latestarc(old_a);
  1070. X    set_action_object(F_CHANGE, O_ARC);
  1071. X    set_modifiedflag();
  1072. X}
  1073. X
  1074. Xvoid
  1075. Xchange_ellipse(old_e, new_e)
  1076. X    F_ellipse       *old_e, *new_e;
  1077. X{
  1078. X    list_delete_ellipse(&objects.ellipses, old_e);
  1079. X    list_add_ellipse(&objects.ellipses, new_e);
  1080. X    clean_up();
  1081. X    old_e->next = new_e;
  1082. X    set_latestellipse(old_e);
  1083. X    set_action_object(F_CHANGE, O_ELLIPSE);
  1084. X    set_modifiedflag();
  1085. X}
  1086. X
  1087. Xvoid
  1088. Xchange_text(old_t, new_t)
  1089. X    F_text       *old_t, *new_t;
  1090. X{
  1091. X    list_delete_text(&objects.texts, old_t);
  1092. X    list_add_text(&objects.texts, new_t);
  1093. X    clean_up();
  1094. X    old_t->next = new_t;
  1095. X    set_latesttext(old_t);
  1096. X    set_action_object(F_CHANGE, O_TEXT);
  1097. X    set_modifiedflag();
  1098. X}
  1099. X
  1100. Xvoid
  1101. Xchange_spline(old_s, new_s)
  1102. X    F_spline       *old_s, *new_s;
  1103. X{
  1104. X    list_delete_spline(&objects.splines, old_s);
  1105. X    list_add_spline(&objects.splines, new_s);
  1106. X    clean_up();
  1107. X    old_s->next = new_s;
  1108. X    set_latestspline(old_s);
  1109. X    set_action_object(F_CHANGE, O_SPLINE);
  1110. X    set_modifiedflag();
  1111. X}
  1112. X
  1113. Xvoid
  1114. Xchange_compound(old_c, new_c)
  1115. X    F_compound       *old_c, *new_c;
  1116. X{
  1117. X    list_delete_compound(&objects.compounds, old_c);
  1118. X    list_add_compound(&objects.compounds, new_c);
  1119. X    clean_up();
  1120. X    old_c->next = new_c;
  1121. X    set_latestcompound(old_c);
  1122. X    set_action_object(F_CHANGE, O_COMPOUND);
  1123. X    set_modifiedflag();
  1124. X}
  1125. X
  1126. Xtail(ob, tails)
  1127. X    F_compound       *ob, *tails;
  1128. X{
  1129. X    F_arc       *a;
  1130. X    F_compound       *c;
  1131. X    F_ellipse       *e;
  1132. X    F_line       *l;
  1133. X    F_spline       *s;
  1134. X    F_text       *t;
  1135. X
  1136. X    if (NULL != (a = ob->arcs))
  1137. X    for (; a->next != NULL; a = a->next);
  1138. X    if (NULL != (c = ob->compounds))
  1139. X    for (; c->next != NULL; c = c->next);
  1140. X    if (NULL != (e = ob->ellipses))
  1141. X    for (; e->next != NULL; e = e->next);
  1142. X    if (NULL != (l = ob->lines))
  1143. X    for (; l->next != NULL; l = l->next);
  1144. X    if (NULL != (s = ob->splines))
  1145. X    for (; s->next != NULL; s = s->next);
  1146. X    if (NULL != (t = ob->texts))
  1147. X    for (; t->next != NULL; t = t->next);
  1148. X
  1149. X    tails->arcs = a;
  1150. X    tails->compounds = c;
  1151. X    tails->ellipses = e;
  1152. X    tails->lines = l;
  1153. X    tails->splines = s;
  1154. X    tails->texts = t;
  1155. X}
  1156. X
  1157. X/*
  1158. X * Make pointers in tails point to the last element of each list of l1 and
  1159. X * Append the lists in l2 after those in l1. The tails pointers must be
  1160. X * defined prior to calling append.
  1161. X */
  1162. Xappend_objects(l1, l2, tails)
  1163. X    F_compound       *l1, *l2, *tails;
  1164. X{
  1165. X    if (tails->arcs)
  1166. X    tails->arcs->next = l2->arcs;
  1167. X    else
  1168. X    l1->arcs = l2->arcs;
  1169. X    if (tails->compounds)
  1170. X    tails->compounds->next = l2->compounds;
  1171. X    else
  1172. X    l1->compounds = l2->compounds;
  1173. X    if (tails->ellipses)
  1174. X    tails->ellipses->next = l2->ellipses;
  1175. X    else
  1176. X    l1->ellipses = l2->ellipses;
  1177. X    if (tails->lines)
  1178. X    tails->lines->next = l2->lines;
  1179. X    else
  1180. X    l1->lines = l2->lines;
  1181. X    if (tails->splines)
  1182. X    tails->splines->next = l2->splines;
  1183. X    else
  1184. X    l1->splines = l2->splines;
  1185. X    if (tails->texts)
  1186. X    tails->texts->next = l2->texts;
  1187. X    else
  1188. X    l1->texts = l2->texts;
  1189. X}
  1190. X
  1191. X/* Cut is the dual of append. */
  1192. X
  1193. Xcut_objects(objects, tails)
  1194. X    F_compound       *objects, *tails;
  1195. X{
  1196. X    if (tails->arcs)
  1197. X    tails->arcs->next = NULL;
  1198. X    else
  1199. X    objects->arcs = NULL;
  1200. X    if (tails->compounds)
  1201. X    tails->compounds->next = NULL;
  1202. X    else
  1203. X    objects->compounds = NULL;
  1204. X    if (tails->ellipses)
  1205. X    tails->ellipses->next = NULL;
  1206. X    else
  1207. X    objects->ellipses = NULL;
  1208. X    if (tails->lines)
  1209. X    tails->lines->next = NULL;
  1210. X    else
  1211. X    objects->lines = NULL;
  1212. X    if (tails->splines)
  1213. X    tails->splines->next = NULL;
  1214. X    else
  1215. X    objects->splines = NULL;
  1216. X    if (tails->texts)
  1217. X    tails->texts->next = NULL;
  1218. X    else
  1219. X    objects->texts = NULL;
  1220. X}
  1221. X
  1222. Xappend_point(x, y, point)
  1223. X    int            x, y;
  1224. X    F_point      **point;
  1225. X{
  1226. X    F_point       *p;
  1227. X
  1228. X    if ((p = create_point()) == NULL)
  1229. X    return;
  1230. X
  1231. X    p->x = x;
  1232. X    p->y = y;
  1233. X    p->next = NULL;
  1234. X    (*point)->next = p;
  1235. X    *point = p;
  1236. X}
  1237. X
  1238. Xnum_points(points)
  1239. X    F_point       *points;
  1240. X{
  1241. X    int            n;
  1242. X    F_point       *p;
  1243. X
  1244. X    for (p = points, n = 0; p != NULL; p = p->next, n++);
  1245. X    return (n);
  1246. X}
  1247. X
  1248. XF_text           *
  1249. Xlast_text(list)
  1250. X    F_text       *list;
  1251. X{
  1252. X    F_text       *tt;
  1253. X
  1254. X    if (list == NULL)
  1255. X    return NULL;
  1256. X
  1257. X    for (tt = list; tt->next != NULL; tt = tt->next);
  1258. X    return tt;
  1259. X}
  1260. X
  1261. XF_line           *
  1262. Xlast_line(list)
  1263. X    F_line       *list;
  1264. X{
  1265. X    F_line       *ll;
  1266. X
  1267. X    if (list == NULL)
  1268. X    return NULL;
  1269. X
  1270. X    for (ll = list; ll->next != NULL; ll = ll->next);
  1271. X    return ll;
  1272. X}
  1273. X
  1274. XF_spline       *
  1275. Xlast_spline(list)
  1276. X    F_spline       *list;
  1277. X{
  1278. X    F_spline       *ss;
  1279. X
  1280. X    if (list == NULL)
  1281. X    return NULL;
  1282. X
  1283. X    for (ss = list; ss->next != NULL; ss = ss->next);
  1284. X    return ss;
  1285. X}
  1286. X
  1287. XF_arc           *
  1288. Xlast_arc(list)
  1289. X    F_arc       *list;
  1290. X{
  1291. X    F_arc       *tt;
  1292. X
  1293. X    if (list == NULL)
  1294. X    return NULL;
  1295. X
  1296. X    for (tt = list; tt->next != NULL; tt = tt->next);
  1297. X    return tt;
  1298. X}
  1299. X
  1300. XF_ellipse      *
  1301. Xlast_ellipse(list)
  1302. X    F_ellipse       *list;
  1303. X{
  1304. X    F_ellipse       *tt;
  1305. X
  1306. X    if (list == NULL)
  1307. X    return NULL;
  1308. X
  1309. X    for (tt = list; tt->next != NULL; tt = tt->next);
  1310. X    return tt;
  1311. X}
  1312. X
  1313. XF_compound     *
  1314. Xlast_compound(list)
  1315. X    F_compound       *list;
  1316. X{
  1317. X    F_compound       *tt;
  1318. X
  1319. X    if (list == NULL)
  1320. X    return NULL;
  1321. X
  1322. X    for (tt = list; tt->next != NULL; tt = tt->next);
  1323. X    return tt;
  1324. X}
  1325. X
  1326. XF_point           *
  1327. Xlast_point(list)
  1328. X    F_point       *list;
  1329. X{
  1330. X    F_point       *tt;
  1331. X
  1332. X    if (list == NULL)
  1333. X    return NULL;
  1334. X
  1335. X    for (tt = list; tt->next != NULL; tt = tt->next);
  1336. X    return tt;
  1337. X}
  1338. X
  1339. XF_arc           *
  1340. Xprev_arc(list, arc)
  1341. X    F_arc       *list, *arc;
  1342. X{
  1343. X    F_arc       *csr;
  1344. X
  1345. X    if (list == arc)
  1346. X    return NULL;
  1347. X
  1348. X    for (csr = list; csr->next != arc; csr = csr->next);
  1349. X    return csr;
  1350. X}
  1351. X
  1352. XF_compound     *
  1353. Xprev_compound(list, compound)
  1354. X    F_compound       *list, *compound;
  1355. X{
  1356. X    F_compound       *csr;
  1357. X
  1358. X    if (list == compound)
  1359. X    return NULL;
  1360. X
  1361. X    for (csr = list; csr->next != compound; csr = csr->next);
  1362. X    return csr;
  1363. X}
  1364. X
  1365. XF_ellipse      *
  1366. Xprev_ellipse(list, ellipse)
  1367. X    F_ellipse       *list, *ellipse;
  1368. X{
  1369. X    F_ellipse       *csr;
  1370. X
  1371. X    if (list == ellipse)
  1372. X    return NULL;
  1373. X
  1374. X    for (csr = list; csr->next != ellipse; csr = csr->next);
  1375. X    return csr;
  1376. X}
  1377. X
  1378. XF_line           *
  1379. Xprev_line(list, line)
  1380. X    F_line       *list, *line;
  1381. X{
  1382. X    F_line       *csr;
  1383. X
  1384. X    if (list == line)
  1385. X    return NULL;
  1386. X
  1387. X    for (csr = list; csr->next != line; csr = csr->next);
  1388. X    return csr;
  1389. X}
  1390. X
  1391. XF_spline       *
  1392. Xprev_spline(list, spline)
  1393. X    F_spline       *list, *spline;
  1394. X{
  1395. X    F_spline       *csr;
  1396. X
  1397. X    if (list == spline)
  1398. X    return NULL;
  1399. X
  1400. X    for (csr = list; csr->next != spline; csr = csr->next);
  1401. X    return csr;
  1402. X}
  1403. X
  1404. XF_text           *
  1405. Xprev_text(list, text)
  1406. X    F_text       *list, *text;
  1407. X{
  1408. X    F_text       *csr;
  1409. X
  1410. X    if (list == text)
  1411. X    return NULL;
  1412. X
  1413. X    for (csr = list; csr->next != text; csr = csr->next);
  1414. X    return csr;
  1415. X}
  1416. X
  1417. XF_point           *
  1418. Xprev_point(list, point)
  1419. X    F_point       *list, *point;
  1420. X{
  1421. X    F_point       *csr;
  1422. X
  1423. X    if (list == point)
  1424. X    return NULL;
  1425. X
  1426. X    for (csr = list; csr->next != point; csr = csr->next);
  1427. X    return csr;
  1428. X}
  1429. X
  1430. Xint
  1431. Xobject_count(list)
  1432. X    F_compound       *list;
  1433. X{
  1434. X    register int    cnt;
  1435. X    F_arc       *a;
  1436. X    F_text       *t;
  1437. X    F_compound       *c;
  1438. X    F_ellipse       *e;
  1439. X    F_line       *l;
  1440. X    F_spline       *s;
  1441. X
  1442. X    cnt = 0;
  1443. X    for (a = list->arcs; a != NULL; a = a->next, cnt++);
  1444. X    for (t = list->texts; t != NULL; t = t->next, cnt++);
  1445. X    for (c = list->compounds; c != NULL; c = c->next, cnt++);
  1446. X    for (e = list->ellipses; e != NULL; e = e->next, cnt++);
  1447. X    for (l = list->lines; l != NULL; l = l->next, cnt++);
  1448. X    for (s = list->splines; s != NULL; s = s->next, cnt++);
  1449. X    return (cnt);
  1450. X}
  1451. X
  1452. Xset_tags(list, tag)
  1453. X    F_compound       *list;
  1454. X    int            tag;
  1455. X{
  1456. X    F_arc       *a;
  1457. X    F_text       *t;
  1458. X    F_compound       *c;
  1459. X    F_ellipse       *e;
  1460. X    F_line       *l;
  1461. X    F_spline       *s;
  1462. X
  1463. X    for (a = list->arcs; a != NULL; a = a->next) {
  1464. X    mask_toggle_arcmarker(a);
  1465. X    a->tagged = tag;
  1466. X    mask_toggle_arcmarker(a);
  1467. X    }
  1468. X    for (t = list->texts; t != NULL; t = t->next) {
  1469. X    mask_toggle_textmarker(t);
  1470. X    t->tagged = tag;
  1471. X    mask_toggle_textmarker(t);
  1472. X    }
  1473. X    for (c = list->compounds; c != NULL; c = c->next) {
  1474. X    mask_toggle_compoundmarker(c);
  1475. X    c->tagged = tag;
  1476. X    mask_toggle_compoundmarker(c);
  1477. X    }
  1478. X    for (e = list->ellipses; e != NULL; e = e->next) {
  1479. X    mask_toggle_ellipsemarker(e);
  1480. X    e->tagged = tag;
  1481. X    mask_toggle_ellipsemarker(e);
  1482. X    }
  1483. X    for (l = list->lines; l != NULL; l = l->next) {
  1484. X    mask_toggle_linemarker(l);
  1485. X    l->tagged = tag;
  1486. X    mask_toggle_linemarker(l);
  1487. X    }
  1488. X    for (s = list->splines; s != NULL; s = s->next) {
  1489. X    mask_toggle_splinemarker(s);
  1490. X    s->tagged = tag;
  1491. X    mask_toggle_splinemarker(s);
  1492. X    }
  1493. X}
  1494. X
  1495. Xvoid
  1496. Xget_links(llx, lly, urx, ury)
  1497. X    int            llx, lly, urx, ury;
  1498. X{
  1499. X    F_line       *l;
  1500. X    F_point       *a;
  1501. X    F_linkinfo       *j, *k;
  1502. X
  1503. X    j = NULL;
  1504. X    for (l = objects.lines; l != NULL; l = l->next)
  1505. X    if (l->type == T_POLYLINE) {
  1506. X        a = l->points;
  1507. X        if (point_on_perim(a, llx, lly, urx, ury)) {
  1508. X        if ((k = new_link(l, a, a->next)) == NULL)
  1509. X            return;
  1510. X        if (j == NULL)
  1511. X            cur_links = k;
  1512. X        else
  1513. X            j->next = k;
  1514. X        j = k;
  1515. X        if (k->prevpt != NULL)
  1516. X            k->two_pts = (k->prevpt->next == NULL);
  1517. X        continue;
  1518. X        }
  1519. X        if (a->next == NULL)/* single point, no need to check further */
  1520. X        continue;
  1521. X        a = last_point(l->points);
  1522. X        if (point_on_perim(a, llx, lly, urx, ury)) {
  1523. X        if ((k = new_link(l, a, prev_point(l->points, a))) == NULL)
  1524. X            return;
  1525. X        if (j == NULL)
  1526. X            cur_links = k;
  1527. X        else
  1528. X            j->next = k;
  1529. X        j = k;
  1530. X        if (k->prevpt != NULL)
  1531. X            k->two_pts = (prev_point(l->points, k->prevpt) == NULL);
  1532. X        continue;
  1533. X        }
  1534. X    }
  1535. X}
  1536. X
  1537. X#define LINK_TOL 3
  1538. X
  1539. Xint
  1540. Xpoint_on_perim(p, llx, lly, urx, ury)
  1541. X    F_point       *p;
  1542. X    int            llx, lly, urx, ury;
  1543. X{
  1544. X    return ((abs(p->x - llx) <= LINK_TOL && p->y >= lly - LINK_TOL
  1545. X         && p->y <= ury + LINK_TOL) ||
  1546. X        (abs(p->x - urx) <= LINK_TOL && p->y >= lly - LINK_TOL
  1547. X         && p->y <= ury + LINK_TOL) ||
  1548. X        (abs(p->y - lly) <= LINK_TOL && p->x >= llx - LINK_TOL
  1549. X         && p->x <= urx + LINK_TOL) ||
  1550. X        (abs(p->y - ury) <= LINK_TOL && p->x >= llx - LINK_TOL
  1551. X         && p->x <= urx + LINK_TOL));
  1552. X}
  1553. X
  1554. Xvoid
  1555. Xadjust_links(mode, links, dx, dy, cx, cy, sx, sy, copying)
  1556. X    int            mode;
  1557. X    F_linkinfo       *links;
  1558. X    int        dx, dy;        /* delta */
  1559. X    int        cx, cy;        /* center of scale - NOT USED YET */
  1560. X    float    sx, sy;        /* scale factor - NOT USED YET */
  1561. X    int            copying;
  1562. X{
  1563. X    F_linkinfo       *k;
  1564. X    F_line       *l;
  1565. X
  1566. X    if (mode != SMART_OFF)
  1567. X    for (k = links; k != NULL; k = k->next) {
  1568. X        if (copying) {
  1569. X        l = copy_line(k->line);
  1570. X        list_delete_line(&objects.lines, k->line);
  1571. X        list_add_line(&saved_objects.lines, k->line);
  1572. X        list_add_line(&objects.lines, l);
  1573. X        } else {
  1574. X        mask_toggle_linemarker(k->line);
  1575. X        draw_line(k->line, ERASE);
  1576. X        }
  1577. X        if (mode == SMART_SLIDE && k->prevpt != NULL) {
  1578. X        if (k->endpt->x == k->prevpt->x)
  1579. X            k->prevpt->x += dx;
  1580. X        else
  1581. X            k->prevpt->y += dy;
  1582. X        }
  1583. X        k->endpt->x += dx;
  1584. X        k->endpt->y += dy;
  1585. X        draw_line(k->line, PAINT);
  1586. X        mask_toggle_linemarker(k->line);
  1587. X    }
  1588. X}
  1589. END_OF_FILE
  1590. if test 18136 -ne `wc -c <'u_list.c'`; then
  1591.     echo shar: \"'u_list.c'\" unpacked with wrong size!
  1592. fi
  1593. # end of 'u_list.c'
  1594. fi
  1595. if test -f 'u_undo.c' -a "${1}" != "-c" ; then 
  1596.   echo shar: Will not clobber existing file \"'u_undo.c'\"
  1597. else
  1598. echo shar: Extracting \"'u_undo.c'\" \(16987 characters\)
  1599. sed "s/^X//" >'u_undo.c' <<'END_OF_FILE'
  1600. X/*
  1601. X * FIG : Facility for Interactive Generation of figures
  1602. X * Copyright (c) 1985 by Supoj Sutanthavibul
  1603. X *
  1604. X * "Permission to use, copy, modify, distribute, and sell this software and its
  1605. X * documentation for any purpose is hereby granted without fee, provided that
  1606. X * the above copyright notice appear in all copies and that both that
  1607. X * copyright notice and this permission notice appear in supporting
  1608. X * documentation, and that the name of M.I.T. not be used in advertising or
  1609. X * publicity pertaining to distribution of the software without specific,
  1610. X * written prior permission.  M.I.T. makes no representations about the
  1611. X * suitability of this software for any purpose.  It is provided "as is"
  1612. X * without express or implied warranty."
  1613. X *
  1614. X */
  1615. X
  1616. X/**************** IMPORTS ****************/
  1617. X
  1618. X#include "fig.h"
  1619. X#include "resources.h"
  1620. X#include "mode.h"
  1621. X#include "object.h"
  1622. X#include "paintop.h"
  1623. X#include "u_draw.h"
  1624. X#include "u_elastic.h"
  1625. X#include "u_list.h"
  1626. X#include "u_undo.h"
  1627. X
  1628. X/*************** EXPORTS *****************/
  1629. X
  1630. X/*
  1631. X * Object_tails *usually* points to the last object in each linked list in
  1632. X * objects.  The exceptions occur when multiple objects are added to a figure
  1633. X * (e.g. file read, break compound, undo delete region).  In these cases,
  1634. X * the added objects are appended to the object lists (and saved_objects is
  1635. X * set up to point to the new objects) but object_tails is not changed.
  1636. X * This speeds up a subsequent undo operation which need only set
  1637. X * all the "next" fields of objects pointed to by object_tails to NULL.
  1638. X */
  1639. X
  1640. XF_compound    saved_objects = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
  1641. XF_compound    object_tails = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
  1642. X
  1643. X/*************** LOCAL *****************/
  1644. X
  1645. Xstatic int    last_object;
  1646. Xstatic int    last_action = F_NULL;
  1647. Xstatic F_pos    last_position, new_position;
  1648. Xstatic int    last_arcpointnum;
  1649. Xstatic F_point *last_prev_point, *last_selected_point, *last_next_point;
  1650. Xstatic F_linkinfo *last_links;
  1651. Xstatic int    last_linkmode;
  1652. X
  1653. Xvoid
  1654. Xundo()
  1655. X{
  1656. X    switch (last_action) {
  1657. X    case F_ADD:
  1658. X    undo_add();
  1659. X    break;
  1660. X    case F_DELETE:
  1661. X    undo_delete();
  1662. X    break;
  1663. X    case F_MOVE:
  1664. X    undo_move();
  1665. X    break;
  1666. X    case F_CHANGE:
  1667. X    undo_change();
  1668. X    break;
  1669. X    case F_GLUE:
  1670. X    undo_glue();
  1671. X    break;
  1672. X    case F_BREAK:
  1673. X    undo_break();
  1674. X    break;
  1675. X    case F_LOAD:
  1676. X    undo_load();
  1677. X    break;
  1678. X    case F_SCALE:
  1679. X    undo_scale();
  1680. X    break;
  1681. X    case F_ADD_POINT:
  1682. X    undo_addpoint();
  1683. X    break;
  1684. X    case F_DELETE_POINT:
  1685. X    undo_deletepoint();
  1686. X    break;
  1687. X    case F_ADD_ARROW_HEAD:
  1688. X    undo_add_arrowhead();
  1689. X    break;
  1690. X    case F_DELETE_ARROW_HEAD:
  1691. X    undo_delete_arrowhead();
  1692. X    break;
  1693. X    case F_CONVERT:
  1694. X    undo_convert();
  1695. X    break;
  1696. X    default:
  1697. X    put_msg("Nothing to UNDO");
  1698. X    return;
  1699. X    }
  1700. X    put_msg("Undo complete");
  1701. X}
  1702. X
  1703. Xundo_addpoint()
  1704. X{
  1705. X    if (last_object == O_POLYLINE)
  1706. X    linepoint_deleting(saved_objects.lines, last_prev_point,
  1707. X               last_selected_point);
  1708. X    else
  1709. X    splinepoint_deleting(saved_objects.splines, last_prev_point,
  1710. X                 last_selected_point);
  1711. X}
  1712. X
  1713. Xundo_deletepoint()
  1714. X{
  1715. X    last_action = F_NULL;    /* to avoid doing a clean-up during adding */
  1716. X
  1717. X    if (last_object == O_POLYLINE)
  1718. X    linepoint_adding(saved_objects.lines, last_prev_point,
  1719. X             last_selected_point, last_next_point);
  1720. X    else
  1721. X    splinepoint_adding(saved_objects.splines, last_prev_point,
  1722. X               last_selected_point, last_next_point);
  1723. X    last_next_point = NULL;
  1724. X}
  1725. X
  1726. Xundo_break()
  1727. X{
  1728. X    cut_objects(&objects, &object_tails);
  1729. X    list_add_compound(&objects.compounds, saved_objects.compounds);
  1730. X    last_action = F_GLUE;
  1731. X    toggle_markers_in_compound(saved_objects.compounds);
  1732. X    mask_toggle_compoundmarker(saved_objects.compounds);
  1733. X}
  1734. X
  1735. Xundo_glue()
  1736. X{
  1737. X    list_delete_compound(&objects.compounds, saved_objects.compounds);
  1738. X    tail(&objects, &object_tails);
  1739. X    append_objects(&objects, saved_objects.compounds, &object_tails);
  1740. X    last_action = F_BREAK;
  1741. X    mask_toggle_compoundmarker(saved_objects.compounds);
  1742. X    toggle_markers_in_compound(saved_objects.compounds);
  1743. X    if (cur_mode != F_GLUE && cur_mode != F_BREAK)
  1744. X    set_tags(saved_objects.compounds, 0);
  1745. X}
  1746. X
  1747. Xundo_convert()
  1748. X{
  1749. X    switch (last_object) {
  1750. X    case O_POLYLINE:
  1751. X    spline_2_line(saved_objects.splines);
  1752. X    break;
  1753. X    case O_SPLINE:
  1754. X    line_2_spline(saved_objects.lines);
  1755. X    break;
  1756. X    }
  1757. X}
  1758. X
  1759. Xundo_add_arrowhead()
  1760. X{
  1761. X    switch (last_object) {
  1762. X    case O_POLYLINE:
  1763. X    delete_linearrow(saved_objects.lines,
  1764. X             last_prev_point, last_selected_point);
  1765. X    break;
  1766. X    case O_SPLINE:
  1767. X    delete_splinearrow(saved_objects.splines,
  1768. X               last_prev_point, last_selected_point);
  1769. X    break;
  1770. X    case O_ARC:
  1771. X    delete_arcarrow(saved_objects.arcs, last_arcpointnum);
  1772. X    break;
  1773. X    default:
  1774. X    return;
  1775. X    }
  1776. X    last_action = F_DELETE_ARROW_HEAD;
  1777. X}
  1778. X
  1779. Xundo_delete_arrowhead()
  1780. X{
  1781. X    switch (last_object) {
  1782. X    case O_POLYLINE:
  1783. X    add_linearrow(saved_objects.lines,
  1784. X              last_prev_point, last_selected_point);
  1785. X    break;
  1786. X    case O_SPLINE:
  1787. X    add_splinearrow(saved_objects.splines,
  1788. X            last_prev_point, last_selected_point);
  1789. X    break;
  1790. X    case O_ARC:
  1791. X    add_arcarrow(saved_objects.arcs, last_arcpointnum);
  1792. X    break;
  1793. X    default:
  1794. X    return;
  1795. X    }
  1796. X    last_action = F_ADD_ARROW_HEAD;
  1797. X}
  1798. X
  1799. X/*
  1800. X * saved_objects.xxxx contains a pointer to the original object,
  1801. X * saved_objects.xxxx->next points to the changed object.
  1802. X */
  1803. X
  1804. Xundo_change()
  1805. X{
  1806. X    last_action = F_NULL;    /* to avoid a clean-up during "unchange" */
  1807. X    switch (last_object) {
  1808. X    case O_POLYLINE:
  1809. X    new_l = saved_objects.lines;    /* the original */
  1810. X    old_l = saved_objects.lines->next;    /* the changed object */
  1811. X    change_line(old_l, new_l);
  1812. X    redisplay_lines(new_l, old_l);
  1813. X    break;
  1814. X    case O_ELLIPSE:
  1815. X    new_e = saved_objects.ellipses;
  1816. X    old_e = saved_objects.ellipses->next;
  1817. X    change_ellipse(old_e, new_e);
  1818. X    redisplay_ellipses(new_e, old_e);
  1819. X    break;
  1820. X    case O_TEXT:
  1821. X    new_t = saved_objects.texts;
  1822. X    old_t = saved_objects.texts->next;
  1823. X    change_text(old_t, new_t);
  1824. X    redisplay_texts(new_t, old_t);
  1825. X    break;
  1826. X    case O_SPLINE:
  1827. X    new_s = saved_objects.splines;
  1828. X    old_s = saved_objects.splines->next;
  1829. X    change_spline(old_s, new_s);
  1830. X    redisplay_splines(new_s, old_s);
  1831. X    break;
  1832. X    case O_ARC:
  1833. X    new_a = saved_objects.arcs;
  1834. X    old_a = saved_objects.arcs->next;
  1835. X    change_arc(old_a, new_a);
  1836. X    redisplay_arcs(new_a, old_a);
  1837. X    break;
  1838. X    case O_COMPOUND:
  1839. X    new_c = saved_objects.compounds;
  1840. X    old_c = saved_objects.compounds->next;
  1841. X    change_compound(old_c, new_c);
  1842. X    redisplay_compounds(new_c, old_c);
  1843. X    break;
  1844. X    }
  1845. X}
  1846. X
  1847. X/*
  1848. X * When a single object is created, it is appended to the appropriate list
  1849. X * in objects.    It is also placed in the appropriate list in saved_objects.
  1850. X *
  1851. X * When a number of objects are created (usually by reading them in from
  1852. X * a file or undoing a remove-all action), they are appended to the lists in
  1853. X * objects and also saved in saved_objects.  The pointers in object_tails
  1854. X * will be set to point to the last members of the lists in objects prior to
  1855. X * the appending.
  1856. X *
  1857. X * Note: The read operation will set the pointers in object_tails while the
  1858. X * remove-all operation will zero pointers in objects.
  1859. X */
  1860. X
  1861. Xundo_add()
  1862. X{
  1863. X    int            xmin, ymin, xmax, ymax;
  1864. X
  1865. X    switch (last_object) {
  1866. X    case O_POLYLINE:
  1867. X    list_delete_line(&objects.lines, saved_objects.lines);
  1868. X    redisplay_line(saved_objects.lines);
  1869. X    break;
  1870. X    case O_ELLIPSE:
  1871. X    list_delete_ellipse(&objects.ellipses, saved_objects.ellipses);
  1872. X    redisplay_ellipse(saved_objects.ellipses);
  1873. X    break;
  1874. X    case O_TEXT:
  1875. X    list_delete_text(&objects.texts, saved_objects.texts);
  1876. X    redisplay_text(saved_objects.texts);
  1877. X    break;
  1878. X    case O_SPLINE:
  1879. X    list_delete_spline(&objects.splines, saved_objects.splines);
  1880. X    redisplay_spline(saved_objects.splines);
  1881. X    break;
  1882. X    case O_ARC:
  1883. X    list_delete_arc(&objects.arcs, saved_objects.arcs);
  1884. X    redisplay_arc(saved_objects.arcs);
  1885. X    break;
  1886. X    case O_COMPOUND:
  1887. X    list_delete_compound(&objects.compounds, saved_objects.compounds);
  1888. X    redisplay_compound(saved_objects.compounds);
  1889. X    break;
  1890. X    case O_ALL_OBJECT:
  1891. X    cut_objects(&objects, &object_tails);
  1892. X    compound_bound(&saved_objects, &xmin, &ymin, &xmax, &ymax);
  1893. X    redisplay_zoomed_region(xmin, ymin, xmax, ymax);
  1894. X    break;
  1895. X    }
  1896. X    last_action = F_DELETE;
  1897. X}
  1898. X
  1899. Xundo_delete()
  1900. X{
  1901. X    int            xmin, ymin, xmax, ymax;
  1902. X
  1903. X    switch (last_object) {
  1904. X    case O_POLYLINE:
  1905. X    list_add_line(&objects.lines, saved_objects.lines);
  1906. X    redisplay_line(saved_objects.lines);
  1907. X    break;
  1908. X    case O_ELLIPSE:
  1909. X    list_add_ellipse(&objects.ellipses, saved_objects.ellipses);
  1910. X    redisplay_ellipse(saved_objects.ellipses);
  1911. X    break;
  1912. X    case O_TEXT:
  1913. X    list_add_text(&objects.texts, saved_objects.texts);
  1914. X    redisplay_text(saved_objects.texts);
  1915. X    break;
  1916. X    case O_SPLINE:
  1917. X    list_add_spline(&objects.splines, saved_objects.splines);
  1918. X    redisplay_spline(saved_objects.splines);
  1919. X    break;
  1920. X    case O_ARC:
  1921. X    list_add_arc(&objects.arcs, saved_objects.arcs);
  1922. X    redisplay_arc(saved_objects.arcs);
  1923. X    break;
  1924. X    case O_COMPOUND:
  1925. X    list_add_compound(&objects.compounds, saved_objects.compounds);
  1926. X    redisplay_compound(saved_objects.compounds);
  1927. X    break;
  1928. X    case O_ALL_OBJECT:
  1929. X    compound_bound(&saved_objects, &xmin, &ymin, &xmax, &ymax);
  1930. X    append_objects(&objects, &saved_objects, &object_tails);
  1931. X    redisplay_zoomed_region(xmin, ymin, xmax, ymax);
  1932. X    }
  1933. X    last_action = F_ADD;
  1934. X}
  1935. X
  1936. Xundo_move()
  1937. X{
  1938. X    int            dx, dy;
  1939. X    int            xmin1, ymin1, xmax1, ymax1;
  1940. X    int            xmin2, ymin2, xmax2, ymax2;
  1941. X
  1942. X    dx = last_position.x - new_position.x;
  1943. X    dy = last_position.y - new_position.y;
  1944. X    switch (last_object) {
  1945. X    case O_POLYLINE:
  1946. X    line_bound(saved_objects.lines, &xmin1, &ymin1, &xmax1, &ymax1);
  1947. X    translate_line(saved_objects.lines, dx, dy);
  1948. X    line_bound(saved_objects.lines, &xmin2, &ymin2, &xmax2, &ymax2);
  1949. X    adjust_links(last_linkmode, last_links, dx, dy, 0, 0, 1.0, 1.0, 0);
  1950. X    redisplay_regions(xmin1, ymin1, xmax1, ymax1,
  1951. X              xmin2, ymin2, xmax2, ymax2);
  1952. X    break;
  1953. X    case O_ELLIPSE:
  1954. X    ellipse_bound(saved_objects.ellipses, &xmin1, &ymin1, &xmax1, &ymax1);
  1955. X    translate_ellipse(saved_objects.ellipses, dx, dy);
  1956. X    ellipse_bound(saved_objects.ellipses, &xmin2, &ymin2, &xmax2, &ymax2);
  1957. X    redisplay_regions(xmin1, ymin1, xmax1, ymax1,
  1958. X              xmin2, ymin2, xmax2, ymax2);
  1959. X    break;
  1960. X    case O_TEXT:
  1961. X    text_bound(saved_objects.texts, &xmin1, &ymin1, &xmax1, &ymax1);
  1962. X    translate_text(saved_objects.texts, dx, dy);
  1963. X    text_bound(saved_objects.texts, &xmin2, &ymin2, &xmax2, &ymax2);
  1964. X    redisplay_regions(xmin1, ymin1, xmax1, ymax1,
  1965. X              xmin2, ymin2, xmax2, ymax2);
  1966. X    break;
  1967. X    case O_SPLINE:
  1968. X    spline_bound(saved_objects.splines, &xmin1, &ymin1, &xmax1, &ymax1);
  1969. X    translate_spline(saved_objects.splines, dx, dy);
  1970. X    spline_bound(saved_objects.splines, &xmin2, &ymin2, &xmax2, &ymax2);
  1971. X    redisplay_regions(xmin1, ymin1, xmax1, ymax1,
  1972. X              xmin2, ymin2, xmax2, ymax2);
  1973. X    break;
  1974. X    case O_ARC:
  1975. X    arc_bound(saved_objects.arcs, &xmin1, &ymin1, &xmax1, &ymax1);
  1976. X    translate_arc(saved_objects.arcs, dx, dy);
  1977. X    arc_bound(saved_objects.arcs, &xmin2, &ymin2, &xmax2, &ymax2);
  1978. X    redisplay_regions(xmin1, ymin1, xmax1, ymax1,
  1979. X              xmin2, ymin2, xmax2, ymax2);
  1980. X    break;
  1981. X    case O_COMPOUND:
  1982. X    compound_bound(saved_objects.compounds, &xmin1, &ymin1, &xmax1, &ymax1);
  1983. X    translate_compound(saved_objects.compounds, dx, dy);
  1984. X    compound_bound(saved_objects.compounds, &xmin2, &ymin2, &xmax2, &ymax2);
  1985. X    adjust_links(last_linkmode, last_links, dx, dy, 0, 0, 1.0, 1.0, 0);
  1986. X    redisplay_regions(xmin1, ymin1, xmax1, ymax1,
  1987. X              xmin2, ymin2, xmax2, ymax2);
  1988. X    break;
  1989. X    }
  1990. X    swap_newp_lastp();
  1991. X}
  1992. X
  1993. Xundo_load()
  1994. X{
  1995. X    F_compound        temp;
  1996. X    char        ctemp[128];
  1997. X
  1998. X    temp = objects;
  1999. X    objects = saved_objects;
  2000. X    saved_objects = temp;
  2001. X    strcpy(ctemp, cur_filename);
  2002. X    strcpy(cur_filename, save_filename);
  2003. X    strcpy(save_filename, ctemp);
  2004. X    redisplay_canvas();
  2005. X    set_modifiedflag();
  2006. X    last_action = F_LOAD;
  2007. X}
  2008. X
  2009. Xundo_scale()
  2010. X{
  2011. X    float        scalex, scaley;
  2012. X
  2013. X    mask_toggle_compoundmarker(saved_objects.compounds);
  2014. X    draw_compoundelements(saved_objects.compounds, ERASE);
  2015. X    scalex = ((float) (last_position.x - fix_x)) / (new_position.x - fix_x);
  2016. X    scaley = ((float) (last_position.y - fix_y)) / (new_position.y - fix_y);
  2017. X    scale_compound(saved_objects.compounds, scalex, scaley, fix_x, fix_y);
  2018. X    draw_compoundelements(saved_objects.compounds, PAINT);
  2019. X    mask_toggle_compoundmarker(saved_objects.compounds);
  2020. X    swap_newp_lastp();
  2021. X}
  2022. X
  2023. Xswap_newp_lastp()
  2024. X{
  2025. X    int            t;        /* swap new_position and last_position    */
  2026. X
  2027. X    t = new_position.x;
  2028. X    new_position.x = last_position.x;
  2029. X    last_position.x = t;
  2030. X    t = new_position.y;
  2031. X    new_position.y = last_position.y;
  2032. X    last_position.y = t;
  2033. X}
  2034. X
  2035. X/*
  2036. X * Clean_up should be called before committing a user's request. Clean_up
  2037. X * will attempt to free all the allocated memories which resulted from
  2038. X * delete/remove action.  It will set the last_action to F_NULL.  Thus this
  2039. X * routine should be before set_action_object(). if they are to be called in
  2040. X * the same routine.
  2041. X */
  2042. Xclean_up()
  2043. X{
  2044. X    if (last_action == F_CHANGE) {
  2045. X    switch (last_object) {
  2046. X    case O_ARC:
  2047. X        saved_objects.arcs->next = NULL;
  2048. X        free_arc(&saved_objects.arcs);
  2049. X        break;
  2050. X    case O_COMPOUND:
  2051. X        saved_objects.compounds->next = NULL;
  2052. X        free_compound(&saved_objects.compounds);
  2053. X        break;
  2054. X    case O_ELLIPSE:
  2055. X        saved_objects.ellipses->next = NULL;
  2056. X        free_ellipse(&saved_objects.ellipses);
  2057. X        break;
  2058. X    case O_POLYLINE:
  2059. X        saved_objects.lines->next = NULL;
  2060. X        free_line(&saved_objects.lines);
  2061. X        break;
  2062. X    case O_SPLINE:
  2063. X        saved_objects.splines->next = NULL;
  2064. X        free_spline(&saved_objects.splines);
  2065. X        break;
  2066. X    case O_TEXT:
  2067. X        saved_objects.texts->next = NULL;
  2068. X        free_text(&saved_objects.texts);
  2069. X        break;
  2070. X    }
  2071. X    } else if (last_action == F_DELETE) {
  2072. X    switch (last_object) {
  2073. X    case O_ARC:
  2074. X        free_arc(&saved_objects.arcs);
  2075. X        break;
  2076. X    case O_COMPOUND:
  2077. X        free_compound(&saved_objects.compounds);
  2078. X        break;
  2079. X    case O_ELLIPSE:
  2080. X        free_ellipse(&saved_objects.ellipses);
  2081. X        break;
  2082. X    case O_POLYLINE:
  2083. X        free_line(&saved_objects.lines);
  2084. X        break;
  2085. X    case O_SPLINE:
  2086. X        free_spline(&saved_objects.splines);
  2087. X        break;
  2088. X    case O_TEXT:
  2089. X        free_text(&saved_objects.texts);
  2090. X        break;
  2091. X    case O_ALL_OBJECT:
  2092. X        free_arc(&saved_objects.arcs);
  2093. X        free_compound(&saved_objects.compounds);
  2094. X        free_ellipse(&saved_objects.ellipses);
  2095. X        free_line(&saved_objects.lines);
  2096. X        free_spline(&saved_objects.splines);
  2097. X        free_text(&saved_objects.texts);
  2098. X        break;
  2099. X    }
  2100. X    } else if (last_action == F_DELETE_POINT) {
  2101. X    free((char *) last_selected_point);
  2102. X    last_prev_point = NULL;
  2103. X    last_selected_point = NULL;
  2104. X    last_next_point = NULL;
  2105. X    } else if (last_action == F_ADD_POINT) {
  2106. X    last_prev_point = NULL;
  2107. X    last_selected_point = NULL;
  2108. X    } else if (last_action == F_LOAD) {
  2109. X    free_arc(&saved_objects.arcs);
  2110. X    free_compound(&saved_objects.compounds);
  2111. X    free_ellipse(&saved_objects.ellipses);
  2112. X    free_line(&saved_objects.lines);
  2113. X    free_spline(&saved_objects.splines);
  2114. X    free_text(&saved_objects.texts);
  2115. X    } else if (last_action == F_GLUE) {
  2116. X    saved_objects.compounds = NULL;
  2117. X    } else if (last_action == F_BREAK) {
  2118. X    free((char *) saved_objects.compounds);
  2119. X    saved_objects.compounds = NULL;
  2120. X    } else if (last_action == F_ADD || last_action == F_MOVE) {
  2121. X    saved_objects.arcs = NULL;
  2122. X    saved_objects.compounds = NULL;
  2123. X    saved_objects.ellipses = NULL;
  2124. X    saved_objects.lines = NULL;
  2125. X    saved_objects.splines = NULL;
  2126. X    saved_objects.texts = NULL;
  2127. X    free_linkinfo(&last_links);
  2128. X    } else if (last_action == F_CONVERT) {
  2129. X    saved_objects.splines = NULL;
  2130. X    saved_objects.lines = NULL;
  2131. X    } else if (last_action == F_ADD_ARROW_HEAD ||
  2132. X           last_action == F_DELETE_ARROW_HEAD) {
  2133. X    saved_objects.splines = NULL;
  2134. X    saved_objects.lines = NULL;
  2135. X    saved_objects.arcs = NULL;
  2136. X    last_prev_point = NULL;
  2137. X    last_selected_point = NULL;
  2138. X    }
  2139. X    last_action = F_NULL;
  2140. X}
  2141. X
  2142. Xset_latestarc(arc)
  2143. X    F_arc       *arc;
  2144. X{
  2145. X    saved_objects.arcs = arc;
  2146. X}
  2147. X
  2148. Xset_latestobjects(objects)
  2149. X    F_compound       *objects;
  2150. X{
  2151. X    saved_objects = *objects;
  2152. X}
  2153. X
  2154. Xset_latestcompound(compound)
  2155. X    F_compound       *compound;
  2156. X{
  2157. X    saved_objects.compounds = compound;
  2158. X}
  2159. X
  2160. Xset_latestellipse(ellipse)
  2161. X    F_ellipse       *ellipse;
  2162. X{
  2163. X    saved_objects.ellipses = ellipse;
  2164. X}
  2165. X
  2166. Xset_latestline(line)
  2167. X    F_line       *line;
  2168. X{
  2169. X    saved_objects.lines = line;
  2170. X}
  2171. X
  2172. Xset_latestspline(spline)
  2173. X    F_spline       *spline;
  2174. X{
  2175. X    saved_objects.splines = spline;
  2176. X}
  2177. X
  2178. Xset_latesttext(text)
  2179. X    F_text       *text;
  2180. X{
  2181. X    saved_objects.texts = text;
  2182. X}
  2183. X
  2184. Xset_last_prevpoint(prev_point)
  2185. X    F_point       *prev_point;
  2186. X{
  2187. X    last_prev_point = prev_point;
  2188. X}
  2189. X
  2190. Xset_last_selectedpoint(selected_point)
  2191. X    F_point       *selected_point;
  2192. X{
  2193. X    last_selected_point = selected_point;
  2194. X}
  2195. X
  2196. Xset_last_nextpoint(next_point)
  2197. X    F_point       *next_point;
  2198. X{
  2199. X    last_next_point = next_point;
  2200. X}
  2201. X
  2202. Xset_last_arcpointnum(num)
  2203. X    int            num;
  2204. X{
  2205. X    last_arcpointnum = num;
  2206. X}
  2207. X
  2208. Xset_lastposition(x, y)
  2209. X    int            x, y;
  2210. X{
  2211. X    last_position.x = x;
  2212. X    last_position.y = y;
  2213. X}
  2214. X
  2215. Xset_newposition(x, y)
  2216. X    int            x, y;
  2217. X{
  2218. X    new_position.x = x;
  2219. X    new_position.y = y;
  2220. X}
  2221. X
  2222. Xset_action(action)
  2223. X    int            action;
  2224. X{
  2225. X    last_action = action;
  2226. X}
  2227. X
  2228. Xset_action_object(action, object)
  2229. X    int            action, object;
  2230. X{
  2231. X    last_action = action;
  2232. X    last_object = object;
  2233. X}
  2234. X
  2235. Xset_lastlinkinfo(mode, links)
  2236. X    int            mode;
  2237. X    F_linkinfo       *links;
  2238. X{
  2239. X    last_linkmode = mode;
  2240. X    last_links = links;
  2241. X}
  2242. END_OF_FILE
  2243. if test 16987 -ne `wc -c <'u_undo.c'`; then
  2244.     echo shar: \"'u_undo.c'\" unpacked with wrong size!
  2245. fi
  2246. # end of 'u_undo.c'
  2247. fi
  2248. echo shar: End of archive 11 \(of 25\).
  2249. cp /dev/null ark11isdone
  2250. MISSING=""
  2251. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ; do
  2252.     if test ! -f ark${I}isdone ; then
  2253.     MISSING="${MISSING} ${I}"
  2254.     fi
  2255. done
  2256. if test "${MISSING}" = "" ; then
  2257.     echo You have unpacked all 25 archives.
  2258.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2259. else
  2260.     echo You still need to unpack the following archives:
  2261.     echo "        " ${MISSING}
  2262. fi
  2263. ##  End of shell archive.
  2264. exit 0
  2265. -- 
  2266. Molecular Simulations, Inc.             mail: dcmartin@msi.com
  2267. 796 N. Pastoria Avenue                  uucp: uunet!dcmartin
  2268. Sunnyvale, California 94086             at&t: 408/522-9236
  2269.