home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume19 / xfig / part12 / u_undo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-27  |  17.2 KB  |  664 lines

  1. /*
  2.  * FIG : Facility for Interactive Generation of figures
  3.  * Copyright (c) 1985 by Supoj Sutanthavibul
  4.  *
  5.  * "Permission to use, copy, modify, distribute, and sell this software and its
  6.  * documentation for any purpose is hereby granted without fee, provided that
  7.  * the above copyright notice appear in all copies and that both the copyright
  8.  * notice and this permission notice appear in supporting documentation. 
  9.  * No representations are made about the suitability of this software for 
  10.  * any purpose.  It is provided "as is" without express or implied warranty."
  11.  */
  12.  
  13. /**************** IMPORTS ****************/
  14.  
  15. #include "fig.h"
  16. #include "resources.h"
  17. #include "mode.h"
  18. #include "object.h"
  19. #include "paintop.h"
  20. #include "u_draw.h"
  21. #include "u_elastic.h"
  22. #include "u_list.h"
  23. #include "u_undo.h"
  24. #include "w_setup.h"
  25.  
  26. /*************** EXPORTS *****************/
  27.  
  28. /*
  29.  * Object_tails *usually* points to the last object in each linked list in
  30.  * objects.  The exceptions occur when multiple objects are added to a figure
  31.  * (e.g. file read, break compound, undo delete region).  In these cases,
  32.  * the added objects are appended to the object lists (and saved_objects is
  33.  * set up to point to the new objects) but object_tails is not changed.
  34.  * This speeds up a subsequent undo operation which need only set
  35.  * all the "next" fields of objects pointed to by object_tails to NULL.
  36.  */
  37.  
  38. F_compound    saved_objects = {0, { 0, 0 }, { 0, 0 }, 
  39.                 NULL, NULL, NULL, NULL, NULL, NULL, NULL};
  40. F_compound    object_tails = {0, { 0, 0 }, { 0, 0 }, 
  41.                 NULL, NULL, NULL, NULL, NULL, NULL, NULL};
  42.  
  43. /*************** LOCAL *****************/
  44.  
  45. static int    last_object;
  46. static int    last_action = F_NULL;
  47. static F_pos    last_position, new_position;
  48. static int    last_arcpointnum;
  49. static F_point *last_prev_point, *last_selected_point, *last_next_point;
  50. static F_linkinfo *last_links;
  51. static int    last_linkmode;
  52.  
  53. void
  54. undo()
  55. {
  56.     switch (last_action) {
  57.     case F_ADD:
  58.     undo_add();
  59.     break;
  60.     case F_DELETE:
  61.     undo_delete();
  62.     break;
  63.     case F_MOVE:
  64.     undo_move();
  65.     break;
  66.     case F_CHANGE:
  67.     undo_change();
  68.     break;
  69.     case F_GLUE:
  70.     undo_glue();
  71.     break;
  72.     case F_BREAK:
  73.     undo_break();
  74.     break;
  75.     case F_LOAD:
  76.     undo_load();
  77.     break;
  78.     case F_SCALE:
  79.     undo_scale();
  80.     break;
  81.     case F_ADD_POINT:
  82.     undo_addpoint();
  83.     break;
  84.     case F_DELETE_POINT:
  85.     undo_deletepoint();
  86.     break;
  87.     case F_ADD_ARROW_HEAD:
  88.     undo_add_arrowhead();
  89.     break;
  90.     case F_DELETE_ARROW_HEAD:
  91.     undo_delete_arrowhead();
  92.     break;
  93.     case F_CONVERT:
  94.     undo_convert();
  95.     break;
  96.     default:
  97.     put_msg("Nothing to UNDO");
  98.     return;
  99.     }
  100.     put_msg("Undo complete");
  101. }
  102.  
  103. undo_addpoint()
  104. {
  105.     if (last_object == O_POLYLINE)
  106.     linepoint_deleting(saved_objects.lines, last_prev_point,
  107.                last_selected_point);
  108.     else
  109.     splinepoint_deleting(saved_objects.splines, last_prev_point,
  110.                  last_selected_point);
  111. }
  112.  
  113. undo_deletepoint()
  114. {
  115.     last_action = F_NULL;    /* to avoid doing a clean-up during adding */
  116.  
  117.     if (last_object == O_POLYLINE)
  118.     linepoint_adding(saved_objects.lines, last_prev_point,
  119.              last_selected_point, last_next_point);
  120.     else
  121.     splinepoint_adding(saved_objects.splines, last_prev_point,
  122.                last_selected_point, last_next_point);
  123.     last_next_point = NULL;
  124. }
  125.  
  126. undo_break()
  127. {
  128.     cut_objects(&objects, &object_tails);
  129.     list_add_compound(&objects.compounds, saved_objects.compounds);
  130.     last_action = F_GLUE;
  131.     toggle_markers_in_compound(saved_objects.compounds);
  132.     mask_toggle_compoundmarker(saved_objects.compounds);
  133. }
  134.  
  135. undo_glue()
  136. {
  137.     list_delete_compound(&objects.compounds, saved_objects.compounds);
  138.     tail(&objects, &object_tails);
  139.     append_objects(&objects, saved_objects.compounds, &object_tails);
  140.     last_action = F_BREAK;
  141.     mask_toggle_compoundmarker(saved_objects.compounds);
  142.     toggle_markers_in_compound(saved_objects.compounds);
  143.     if (cur_mode != F_GLUE && cur_mode != F_BREAK)
  144.     set_tags(saved_objects.compounds, 0);
  145. }
  146.  
  147. undo_convert()
  148. {
  149.     switch (last_object) {
  150.     case O_POLYLINE:
  151.     spline_2_line(saved_objects.splines);
  152.     break;
  153.     case O_SPLINE:
  154.     line_2_spline(saved_objects.lines);
  155.     break;
  156.     }
  157. }
  158.  
  159. undo_add_arrowhead()
  160. {
  161.     switch (last_object) {
  162.     case O_POLYLINE:
  163.     delete_linearrow(saved_objects.lines,
  164.              last_prev_point, last_selected_point);
  165.     break;
  166.     case O_SPLINE:
  167.     delete_splinearrow(saved_objects.splines,
  168.                last_prev_point, last_selected_point);
  169.     break;
  170.     case O_ARC:
  171.     delete_arcarrow(saved_objects.arcs, last_arcpointnum);
  172.     break;
  173.     default:
  174.     return;
  175.     }
  176.     last_action = F_DELETE_ARROW_HEAD;
  177. }
  178.  
  179. undo_delete_arrowhead()
  180. {
  181.     switch (last_object) {
  182.     case O_POLYLINE:
  183.     add_linearrow(saved_objects.lines,
  184.               last_prev_point, last_selected_point);
  185.     break;
  186.     case O_SPLINE:
  187.     add_splinearrow(saved_objects.splines,
  188.             last_prev_point, last_selected_point);
  189.     break;
  190.     case O_ARC:
  191.     add_arcarrow(saved_objects.arcs, last_arcpointnum);
  192.     break;
  193.     default:
  194.     return;
  195.     }
  196.     last_action = F_ADD_ARROW_HEAD;
  197. }
  198.  
  199. /*
  200.  * saved_objects.xxxx contains a pointer to the original object,
  201.  * saved_objects.xxxx->next points to the changed object.
  202.  */
  203.  
  204. undo_change()
  205. {
  206.     int            xmin, ymin, xmax, ymax;
  207.     F_compound        swp_comp;
  208.  
  209.     last_action = F_NULL;    /* to avoid a clean-up during "unchange" */
  210.     switch (last_object) {
  211.     case O_POLYLINE:
  212.     new_l = saved_objects.lines;    /* the original */
  213.     old_l = saved_objects.lines->next;    /* the changed object */
  214.     change_line(old_l, new_l);
  215.     redisplay_lines(new_l, old_l);
  216.     break;
  217.     case O_ELLIPSE:
  218.     new_e = saved_objects.ellipses;
  219.     old_e = saved_objects.ellipses->next;
  220.     change_ellipse(old_e, new_e);
  221.     redisplay_ellipses(new_e, old_e);
  222.     break;
  223.     case O_TEXT:
  224.     new_t = saved_objects.texts;
  225.     old_t = saved_objects.texts->next;
  226.     change_text(old_t, new_t);
  227.     redisplay_texts(new_t, old_t);
  228.     break;
  229.     case O_SPLINE:
  230.     new_s = saved_objects.splines;
  231.     old_s = saved_objects.splines->next;
  232.     change_spline(old_s, new_s);
  233.     redisplay_splines(new_s, old_s);
  234.     break;
  235.     case O_ARC:
  236.     new_a = saved_objects.arcs;
  237.     old_a = saved_objects.arcs->next;
  238.     change_arc(old_a, new_a);
  239.     redisplay_arcs(new_a, old_a);
  240.     break;
  241.     case O_COMPOUND:
  242.     new_c = saved_objects.compounds;
  243.     old_c = saved_objects.compounds->next;
  244.     change_compound(old_c, new_c);
  245.     redisplay_compounds(new_c, old_c);
  246.     break;
  247.     case O_ALL_OBJECT:
  248.     swp_comp = objects;
  249.     objects = saved_objects;
  250.     saved_objects = swp_comp;
  251.     new_c = &objects;
  252.     old_c = &saved_objects;
  253.     set_action_object(F_CHANGE, O_ALL_OBJECT);
  254.     set_modifiedflag();
  255.     redisplay_zoomed_region(0, 0, CANVAS_WD, CANVAS_HT);
  256.     break;
  257.     }
  258. }
  259.  
  260. /*
  261.  * When a single object is created, it is appended to the appropriate list
  262.  * in objects.    It is also placed in the appropriate list in saved_objects.
  263.  *
  264.  * When a number of objects are created (usually by reading them in from
  265.  * a file or undoing a remove-all action), they are appended to the lists in
  266.  * objects and also saved in saved_objects.  The pointers in object_tails
  267.  * will be set to point to the last members of the lists in objects prior to
  268.  * the appending.
  269.  *
  270.  * Note: The read operation will set the pointers in object_tails while the
  271.  * remove-all operation will zero pointers in objects.
  272.  */
  273.  
  274. undo_add()
  275. {
  276.     int            xmin, ymin, xmax, ymax;
  277.  
  278.     switch (last_object) {
  279.     case O_POLYLINE:
  280.     list_delete_line(&objects.lines, saved_objects.lines);
  281.     redisplay_line(saved_objects.lines);
  282.     break;
  283.     case O_ELLIPSE:
  284.     list_delete_ellipse(&objects.ellipses, saved_objects.ellipses);
  285.     redisplay_ellipse(saved_objects.ellipses);
  286.     break;
  287.     case O_TEXT:
  288.     list_delete_text(&objects.texts, saved_objects.texts);
  289.     redisplay_text(saved_objects.texts);
  290.     break;
  291.     case O_SPLINE:
  292.     list_delete_spline(&objects.splines, saved_objects.splines);
  293.     redisplay_spline(saved_objects.splines);
  294.     break;
  295.     case O_ARC:
  296.     list_delete_arc(&objects.arcs, saved_objects.arcs);
  297.     redisplay_arc(saved_objects.arcs);
  298.     break;
  299.     case O_COMPOUND:
  300.     list_delete_compound(&objects.compounds, saved_objects.compounds);
  301.     redisplay_compound(saved_objects.compounds);
  302.     break;
  303.     case O_ALL_OBJECT:
  304.     cut_objects(&objects, &object_tails);
  305.     compound_bound(&saved_objects, &xmin, &ymin, &xmax, &ymax);
  306.     redisplay_zoomed_region(xmin, ymin, xmax, ymax);
  307.     break;
  308.     }
  309.     last_action = F_DELETE;
  310. }
  311.  
  312. undo_delete()
  313. {
  314.     int            xmin, ymin, xmax, ymax;
  315.  
  316.     switch (last_object) {
  317.     case O_POLYLINE:
  318.     list_add_line(&objects.lines, saved_objects.lines);
  319.     redisplay_line(saved_objects.lines);
  320.     break;
  321.     case O_ELLIPSE:
  322.     list_add_ellipse(&objects.ellipses, saved_objects.ellipses);
  323.     redisplay_ellipse(saved_objects.ellipses);
  324.     break;
  325.     case O_TEXT:
  326.     list_add_text(&objects.texts, saved_objects.texts);
  327.     redisplay_text(saved_objects.texts);
  328.     break;
  329.     case O_SPLINE:
  330.     list_add_spline(&objects.splines, saved_objects.splines);
  331.     redisplay_spline(saved_objects.splines);
  332.     break;
  333.     case O_ARC:
  334.     list_add_arc(&objects.arcs, saved_objects.arcs);
  335.     redisplay_arc(saved_objects.arcs);
  336.     break;
  337.     case O_COMPOUND:
  338.     list_add_compound(&objects.compounds, saved_objects.compounds);
  339.     redisplay_compound(saved_objects.compounds);
  340.     break;
  341.     case O_ALL_OBJECT:
  342.     compound_bound(&saved_objects, &xmin, &ymin, &xmax, &ymax);
  343.     append_objects(&objects, &saved_objects, &object_tails);
  344.     redisplay_zoomed_region(xmin, ymin, xmax, ymax);
  345.     }
  346.     last_action = F_ADD;
  347. }
  348.  
  349. undo_move()
  350. {
  351.     int            dx, dy;
  352.     int            xmin1, ymin1, xmax1, ymax1;
  353.     int            xmin2, ymin2, xmax2, ymax2;
  354.     int            dum;
  355.  
  356.     dx = last_position.x - new_position.x;
  357.     dy = last_position.y - new_position.y;
  358.     switch (last_object) {
  359.     case O_POLYLINE:
  360.     line_bound(saved_objects.lines, &xmin1, &ymin1, &xmax1, &ymax1);
  361.     translate_line(saved_objects.lines, dx, dy);
  362.     line_bound(saved_objects.lines, &xmin2, &ymin2, &xmax2, &ymax2);
  363.     adjust_links(last_linkmode, last_links, dx, dy, 0, 0, 1.0, 1.0, 0);
  364.     redisplay_regions(xmin1, ymin1, xmax1, ymax1,
  365.               xmin2, ymin2, xmax2, ymax2);
  366.     break;
  367.     case O_ELLIPSE:
  368.     ellipse_bound(saved_objects.ellipses, &xmin1, &ymin1, &xmax1, &ymax1);
  369.     translate_ellipse(saved_objects.ellipses, dx, dy);
  370.     ellipse_bound(saved_objects.ellipses, &xmin2, &ymin2, &xmax2, &ymax2);
  371.     redisplay_regions(xmin1, ymin1, xmax1, ymax1,
  372.               xmin2, ymin2, xmax2, ymax2);
  373.     break;
  374.     case O_TEXT:
  375.     if (appres.textoutline) {
  376.         text_bound_both(saved_objects.texts, &xmin1, &ymin1, &xmax1, &ymax1,
  377.             &dum,&dum,&dum,&dum,&dum,&dum,&dum,&dum);
  378.         translate_text(saved_objects.texts, dx, dy);
  379.         text_bound_both(saved_objects.texts, &xmin2, &ymin2, &xmax2, &ymax2,
  380.             &dum,&dum,&dum,&dum,&dum,&dum,&dum,&dum);
  381.     } else {
  382.         text_bound(saved_objects.texts, &xmin1, &ymin1, &xmax1, &ymax1);
  383.         translate_text(saved_objects.texts, dx, dy);
  384.         text_bound(saved_objects.texts, &xmin2, &ymin2, &xmax2, &ymax2);
  385.     }
  386.     redisplay_regions(xmin1, ymin1, xmax1, ymax1,
  387.               xmin2, ymin2, xmax2, ymax2);
  388.     break;
  389.     case O_SPLINE:
  390.     spline_bound(saved_objects.splines, &xmin1, &ymin1, &xmax1, &ymax1);
  391.     translate_spline(saved_objects.splines, dx, dy);
  392.     spline_bound(saved_objects.splines, &xmin2, &ymin2, &xmax2, &ymax2);
  393.     redisplay_regions(xmin1, ymin1, xmax1, ymax1,
  394.               xmin2, ymin2, xmax2, ymax2);
  395.     break;
  396.     case O_ARC:
  397.     arc_bound(saved_objects.arcs, &xmin1, &ymin1, &xmax1, &ymax1);
  398.     translate_arc(saved_objects.arcs, dx, dy);
  399.     arc_bound(saved_objects.arcs, &xmin2, &ymin2, &xmax2, &ymax2);
  400.     redisplay_regions(xmin1, ymin1, xmax1, ymax1,
  401.               xmin2, ymin2, xmax2, ymax2);
  402.     break;
  403.     case O_COMPOUND:
  404.     compound_bound(saved_objects.compounds, &xmin1, &ymin1, &xmax1, &ymax1);
  405.     translate_compound(saved_objects.compounds, dx, dy);
  406.     compound_bound(saved_objects.compounds, &xmin2, &ymin2, &xmax2, &ymax2);
  407.     adjust_links(last_linkmode, last_links, dx, dy, 0, 0, 1.0, 1.0, 0);
  408.     redisplay_regions(xmin1, ymin1, xmax1, ymax1,
  409.               xmin2, ymin2, xmax2, ymax2);
  410.     break;
  411.     }
  412.     swap_newp_lastp();
  413. }
  414.  
  415. undo_load()
  416. {
  417.     F_compound        temp;
  418.     char        ctemp[128];
  419.  
  420.     temp = objects;
  421.     objects = saved_objects;
  422.     saved_objects = temp;
  423.     strcpy(ctemp, cur_filename);
  424.     update_cur_filename(save_filename);
  425.     strcpy(save_filename, ctemp);
  426.     redisplay_canvas();
  427.     set_modifiedflag();
  428.     last_action = F_LOAD;
  429. }
  430.  
  431. undo_scale()
  432. {
  433.     float        scalex, scaley;
  434.  
  435.     mask_toggle_compoundmarker(saved_objects.compounds);
  436.     draw_compoundelements(saved_objects.compounds, ERASE);
  437.     scalex = ((float) (last_position.x - fix_x)) / (new_position.x - fix_x);
  438.     scaley = ((float) (last_position.y - fix_y)) / (new_position.y - fix_y);
  439.     scale_compound(saved_objects.compounds, scalex, scaley, fix_x, fix_y);
  440.     draw_compoundelements(saved_objects.compounds, PAINT);
  441.     mask_toggle_compoundmarker(saved_objects.compounds);
  442.     swap_newp_lastp();
  443. }
  444.  
  445. swap_newp_lastp()
  446. {
  447.     int            t;        /* swap new_position and last_position    */
  448.  
  449.     t = new_position.x;
  450.     new_position.x = last_position.x;
  451.     last_position.x = t;
  452.     t = new_position.y;
  453.     new_position.y = last_position.y;
  454.     last_position.y = t;
  455. }
  456.  
  457. /*
  458.  * Clean_up should be called before committing a user's request. Clean_up
  459.  * will attempt to free all the allocated memories which resulted from
  460.  * delete/remove action.  It will set the last_action to F_NULL.  Thus this
  461.  * routine should be before set_action_object(). if they are to be called in
  462.  * the same routine.
  463.  */
  464. clean_up()
  465. {
  466.     if (last_action == F_CHANGE) {
  467.     switch (last_object) {
  468.     case O_ARC:
  469.         saved_objects.arcs->next = NULL;
  470.         free_arc(&saved_objects.arcs);
  471.         break;
  472.     case O_COMPOUND:
  473.         saved_objects.compounds->next = NULL;
  474.         free_compound(&saved_objects.compounds);
  475.         break;
  476.     case O_ELLIPSE:
  477.         saved_objects.ellipses->next = NULL;
  478.         free_ellipse(&saved_objects.ellipses);
  479.         break;
  480.     case O_POLYLINE:
  481.         saved_objects.lines->next = NULL;
  482.         free_line(&saved_objects.lines);
  483.         break;
  484.     case O_SPLINE:
  485.         saved_objects.splines->next = NULL;
  486.         free_spline(&saved_objects.splines);
  487.         break;
  488.     case O_TEXT:
  489.         saved_objects.texts->next = NULL;
  490.         free_text(&saved_objects.texts);
  491.         break;
  492.     }
  493.     } else if (last_action == F_DELETE) {
  494.     switch (last_object) {
  495.     case O_ARC:
  496.         free_arc(&saved_objects.arcs);
  497.         break;
  498.     case O_COMPOUND:
  499.         free_compound(&saved_objects.compounds);
  500.         break;
  501.     case O_ELLIPSE:
  502.         free_ellipse(&saved_objects.ellipses);
  503.         break;
  504.     case O_POLYLINE:
  505.         free_line(&saved_objects.lines);
  506.         break;
  507.     case O_SPLINE:
  508.         free_spline(&saved_objects.splines);
  509.         break;
  510.     case O_TEXT:
  511.         free_text(&saved_objects.texts);
  512.         break;
  513.     case O_ALL_OBJECT:
  514.         free_arc(&saved_objects.arcs);
  515.         free_compound(&saved_objects.compounds);
  516.         free_ellipse(&saved_objects.ellipses);
  517.         free_line(&saved_objects.lines);
  518.         free_spline(&saved_objects.splines);
  519.         free_text(&saved_objects.texts);
  520.         break;
  521.     }
  522.     } else if (last_action == F_DELETE_POINT) {
  523.     free((char *) last_selected_point);
  524.     last_prev_point = NULL;
  525.     last_selected_point = NULL;
  526.     last_next_point = NULL;
  527.     } else if (last_action == F_ADD_POINT) {
  528.     last_prev_point = NULL;
  529.     last_selected_point = NULL;
  530.     } else if (last_action == F_LOAD) {
  531.     free_arc(&saved_objects.arcs);
  532.     free_compound(&saved_objects.compounds);
  533.     free_ellipse(&saved_objects.ellipses);
  534.     free_line(&saved_objects.lines);
  535.     free_spline(&saved_objects.splines);
  536.     free_text(&saved_objects.texts);
  537.     } else if (last_action == F_GLUE) {
  538.     saved_objects.compounds = NULL;
  539.     } else if (last_action == F_BREAK) {
  540.     free((char *) saved_objects.compounds);
  541.     saved_objects.compounds = NULL;
  542.     } else if (last_action == F_ADD || last_action == F_MOVE) {
  543.     saved_objects.arcs = NULL;
  544.     saved_objects.compounds = NULL;
  545.     saved_objects.ellipses = NULL;
  546.     saved_objects.lines = NULL;
  547.     saved_objects.splines = NULL;
  548.     saved_objects.texts = NULL;
  549.     free_linkinfo(&last_links);
  550.     } else if (last_action == F_CONVERT) {
  551.     saved_objects.splines = NULL;
  552.     saved_objects.lines = NULL;
  553.     } else if (last_action == F_ADD_ARROW_HEAD ||
  554.            last_action == F_DELETE_ARROW_HEAD) {
  555.     saved_objects.splines = NULL;
  556.     saved_objects.lines = NULL;
  557.     saved_objects.arcs = NULL;
  558.     last_prev_point = NULL;
  559.     last_selected_point = NULL;
  560.     }
  561.     last_action = F_NULL;
  562. }
  563.  
  564. set_latestarc(arc)
  565.     F_arc       *arc;
  566. {
  567.     saved_objects.arcs = arc;
  568. }
  569.  
  570. set_latestobjects(objects)
  571.     F_compound       *objects;
  572. {
  573.     saved_objects = *objects;
  574. }
  575.  
  576. set_latestcompound(compound)
  577.     F_compound       *compound;
  578. {
  579.     saved_objects.compounds = compound;
  580. }
  581.  
  582. set_latestellipse(ellipse)
  583.     F_ellipse       *ellipse;
  584. {
  585.     saved_objects.ellipses = ellipse;
  586. }
  587.  
  588. set_latestline(line)
  589.     F_line       *line;
  590. {
  591.     saved_objects.lines = line;
  592. }
  593.  
  594. set_latestspline(spline)
  595.     F_spline       *spline;
  596. {
  597.     saved_objects.splines = spline;
  598. }
  599.  
  600. set_latesttext(text)
  601.     F_text       *text;
  602. {
  603.     saved_objects.texts = text;
  604. }
  605.  
  606. set_last_prevpoint(prev_point)
  607.     F_point       *prev_point;
  608. {
  609.     last_prev_point = prev_point;
  610. }
  611.  
  612. set_last_selectedpoint(selected_point)
  613.     F_point       *selected_point;
  614. {
  615.     last_selected_point = selected_point;
  616. }
  617.  
  618. set_last_nextpoint(next_point)
  619.     F_point       *next_point;
  620. {
  621.     last_next_point = next_point;
  622. }
  623.  
  624. set_last_arcpointnum(num)
  625.     int            num;
  626. {
  627.     last_arcpointnum = num;
  628. }
  629.  
  630. set_lastposition(x, y)
  631.     int            x, y;
  632. {
  633.     last_position.x = x;
  634.     last_position.y = y;
  635. }
  636.  
  637. set_newposition(x, y)
  638.     int            x, y;
  639. {
  640.     new_position.x = x;
  641.     new_position.y = y;
  642. }
  643.  
  644. set_action(action)
  645.     int            action;
  646. {
  647.     last_action = action;
  648. }
  649.  
  650. set_action_object(action, object)
  651.     int            action, object;
  652. {
  653.     last_action = action;
  654.     last_object = object;
  655. }
  656.  
  657. set_lastlinkinfo(mode, links)
  658.     int            mode;
  659.     F_linkinfo       *links;
  660. {
  661.     last_linkmode = mode;
  662.     last_links = links;
  663. }
  664.