home *** CD-ROM | disk | FTP | other *** search
/ Encyclopedia of Graphics File Formats Companion / GFF_CD.ISO / software / unix / saoimage / sao1_07.tar / csrsave.c < prev    next >
C/C++ Source or Header  |  1991-01-03  |  10KB  |  326 lines

  1. #ifndef lint
  2. static char SccsId[] = "%W%  %G%";
  3. #endif
  4.  
  5. /* Module:    csrsave.c (Cursor Save)
  6.  * Purpose:    Make new copies of the cursor or replace the cursor by copying
  7.  * Subroutine:    get_new_cursor()        returns: struct cursorRec *
  8.  * Subroutine:    free_cursor()            returns: void
  9.  * Subroutine:    copy_cursor()            returns: struct cursorRec *
  10.  * Subroutine:    save_cursor_as_region()        returns: void
  11.  * Subroutine:    copy_region_to_cursor()        returns: void
  12.  * Subroutine:    match_region()            returns: int
  13.  * Copyright:    1989 Smithsonian Astrophysical Observatory
  14.  *        You may do anything you like with this file except remove
  15.  *        this copyright.  The Smithsonian Astrophysical Observatory
  16.  *        makes no representations about the suitability of this
  17.  *        software for any purpose.  It is provided "as is" without
  18.  *        express or implied warranty.
  19.  * Modified:    {0} Michael VanHilst    initial version          4 June 1989
  20.  *        {1} MVH support for Arrow cursor           1 Jan 1991
  21.  *        {n} <who> -- <does what> -- <when>
  22.  */
  23.  
  24. #include <stdio.h>        /* stderr, NULL, etc. */
  25. #include <X11/Xlib.h>        /* X window stuff */
  26. #include <X11/Xutil.h>        /* X window manager stuff */
  27. #include "hfiles/color.h"    /* cursor colors needed by Cursor.h */
  28. #include "hfiles/constant.h"    /* define codes */
  29. #include "hfiles/cursor.h"    /* define cursor parameter structures */
  30.  
  31. extern struct colorRec color;    /* need to know color.gcset */
  32.  
  33. #ifdef ANSIC
  34. /*  Exported declarations must be centralized before ANSI C can be used  */
  35.  
  36. struct cursorRec *get_new_cursor(    int point_cnt, int poly_cnt);
  37. void        free_cursor(        struct cursorRec *cursor);
  38. struct cursorRec *copy_cursor(        struct cursorRec *cursor);
  39. void        save_cursor_as_region(    struct cursorRec *cursor, int exclude);
  40. void        copy_region_to_cursor(    struct cursorRec *cursor,
  41.                     struct cursorRec *region);
  42. int        match_region(        struct cursorRec *cursor,
  43.                     struct cursorRec *region);
  44.  
  45. static struct cursorRec *copy_annulus(    struct cursorRec *annulus,
  46.                         int exclude);
  47.  
  48. #else
  49.  
  50.   char *calloc_errchk();
  51.   struct cursorRec *get_new_cursor();
  52.   double cursor_area();
  53.   void copy_polygon_region_to_cursor();
  54.   static struct cursorRec *copy_annulus();
  55.   struct cursorRec *copy_cursor();
  56.  
  57. #endif
  58.  
  59.  
  60. /*  Subroutine:    get_new_cursor()
  61.  *  Returns:    Returns space for cursor including points
  62.  *  Note:    Space is alloc'd as single chunk and can be freed en mass
  63.  */
  64. #ifdef ANSIC
  65. struct cursorRec *get_new_cursor ( int point_cnt, int poly_cnt )
  66. #else
  67. struct cursorRec *get_new_cursor ( point_cnt, poly_cnt )
  68.      int point_cnt;    /* i: number of drawing points needed */
  69.      int poly_cnt;    /* i: number of polygon vertex records needed */
  70. #endif
  71. {
  72.   struct cursorRec *cursor;
  73.   int size;
  74.  
  75.   /*  Convert segment count to point count (for Arrow Cursor)  */
  76.   if( point_cnt < 0 )
  77.     point_cnt *= -2;
  78.   /*  Don't take any chances on alignment, use multiples of 4  */
  79.   if( (size = point_cnt % 4) )
  80.     point_cnt += 4 - size;
  81.   size = sizeof(struct cursorRec) +
  82.     (point_cnt * sizeof(XPoint)) + (poly_cnt * sizeof(PolyPoint));
  83.   cursor = (struct cursorRec *)calloc_errchk(1, (unsigned int)size, "cursor");
  84.   if( point_cnt )
  85.     cursor->points = (XPoint *)&(cursor[1]);
  86.   if( poly_cnt )
  87.     cursor->poly = (PolyPoint *)&(cursor->points[point_cnt]);
  88.   /*  Set the default angle at 0.0 degrees, cos must be non-zero  */
  89.   cursor->rot.cos = -1.0;
  90.   return( cursor );
  91. }
  92.  
  93.  
  94. /*  Subroutine:    free_cursor
  95.  *  Purpose:    Free alloc'd cursor space
  96.  */
  97. #ifdef ANSIC
  98. void free_cursor ( struct cursorRec *cursor )
  99. #else
  100. void free_cursor ( cursor )
  101.      struct cursorRec *cursor;
  102. #endif
  103. {
  104.   free((char *)cursor);
  105. }
  106.  
  107.  
  108. /*  Subroutine:    copy_cursor
  109.  *  Returns:    A copy of the cursor in a newly allocated cursor record
  110.  */
  111. #ifdef ANSIC
  112. struct cursorRec *copy_cursor ( struct cursorRec *cursor )
  113. #else
  114. struct cursorRec *copy_cursor ( cursor )
  115.      struct cursorRec *cursor;
  116. #endif
  117. {
  118.   struct cursorRec *copy;
  119.   XPoint *points;
  120.   PolyPoint *poly;
  121.  
  122.   /*  Get a new cursor space  */
  123.   copy = get_new_cursor(cursor->point_cnt, cursor->poly_cnt);
  124.   points = copy->points;
  125.   poly = copy->poly;
  126.   /*  Copy the contents of cursor to copy  */
  127. #ifdef ANSIC
  128.   (void)memcpy((void *)copy, (void *)cursor, sizeof(struct cursorRec));
  129.   copy->points = points;
  130.   copy->poly = poly;
  131.   if( cursor->point_cnt > 0 )
  132.     (void)memcpy((void *)points, (void *)cursor->points,
  133.          cursor->point_cnt * sizeof(XPoint));
  134.   else if( cursor->point_cnt < 0 )
  135.     (void)memcpy((void *)points, (void *)cursor->points,
  136.          (size_t)(cursor->point_cnt * (-sizeof(XSegment))));
  137.   if( cursor->poly_cnt )
  138.     (void)memcpy((void *)poly, (void *)cursor->poly,
  139.          cursor->poly_cnt * sizeof(PolyPoint));
  140. #else
  141.   bcopy((char *)cursor, (char *)copy, sizeof(struct cursorRec));
  142.   copy->points = points;
  143.   copy->poly = poly;
  144.   if( cursor->point_cnt > 0 )
  145.     bcopy((char *)cursor->points, (char *)points,
  146.       cursor->point_cnt * sizeof(XPoint));
  147.   else if( cursor->point_cnt < 0 )
  148.     bcopy((char *)cursor->points, (char *)points,
  149.       -cursor->point_cnt * sizeof(XSegment));
  150.   if( cursor->poly_cnt )
  151.     bcopy((char *)cursor->poly, (char *)poly,
  152.       cursor->poly_cnt * sizeof(PolyPoint));
  153. #endif
  154.   /*  Rectangles are not included  */
  155.   copy->rectangles = NULL;
  156.   copy->rectangle_cnt = 0;
  157.   /*  Install cursor's area  */
  158.   copy->file.area = cursor_area(cursor, 0);
  159.   return( copy );
  160. }
  161.  
  162.  
  163. /*  Subroutine:    save_cursor_as_region
  164.  *  Purpose:    Copy the cursor onto a region of type include or exclude
  165.  */
  166. #ifdef ANSIC
  167. void save_cursor_as_region ( struct cursorRec *cursor, int exclude )
  168. #else
  169. void save_cursor_as_region ( cursor, exclude )
  170.      struct cursorRec *cursor;
  171.      int exclude;        /* i: include or exclude */
  172. #endif
  173. {
  174.   struct cursorRec *region;
  175.  
  176.   /*  Create and fill new cursor structure  */
  177.   region = copy_cursor(cursor);
  178.   /* set up regions drawing characteristics */
  179.   if( (region->exclude_region = exclude) )
  180.     region->draw = &color.gcset.excl;
  181.   else
  182.     region->draw = &color.gcset.incl;
  183.   region->overwrites_image_data = 1;
  184.   /*  Attach to cursor link list  */
  185.   if( cursor->next_region == 0 )
  186.     region->index = 1;
  187.   else
  188.     region->index = cursor->next_region->index + 1;
  189.   region->next_region = cursor->next_region;
  190.   cursor->next_region = region;
  191.   /*  Install annuli if any  */
  192.   if( cursor->annuli && (cursor->next_annulus != NULL) ) {
  193.     region->next_annulus = copy_annulus(cursor->next_annulus, exclude);
  194.   } else
  195.     region->next_annulus = NULL;
  196. }
  197.  
  198.  
  199. /*  Subroutine:    copy_annulus
  200.  *  Purpose:    Reconstruct annulus structure for copy
  201.  *  Returns:    Complete copy of the annulus chain given
  202.  *  Method:    Given an annulus chain, copy this link, add a copy of the
  203.  *        rest of the chain (by recursion) and return the copy
  204.  */
  205. #ifdef ANSIC
  206. static struct cursorRec *copy_annulus ( struct cursorRec *annulus,
  207.                         int exclude )
  208. #else
  209. static struct cursorRec *copy_annulus ( annulus, exclude )
  210.      struct cursorRec *annulus;
  211.      int exclude;
  212. #endif
  213. {
  214.   struct cursorRec *region;
  215.  
  216.   region = copy_cursor(annulus);
  217.   region->exclude_region = exclude;
  218.   if( annulus->next_annulus != NULL )
  219.     region->next_annulus = copy_annulus(annulus->next_annulus, exclude);
  220.   return( region );
  221. }
  222.  
  223.  
  224. /*  Subroutine:    copy_region_to_cursor
  225.  *  Purpose:    Copy region onto cursor
  226.  */
  227. #ifdef ANSIC
  228. void copy_region_to_cursor ( struct cursorRec *cursor,
  229.                  struct cursorRec *region )
  230. #else
  231. void copy_region_to_cursor ( cursor, region )
  232.      struct cursorRec *cursor;
  233.      struct cursorRec *region;
  234. #endif
  235. {
  236.   int overwrites;            /* cursor overwrites image data */
  237.   GCspec *draw;
  238.   XPoint *points;
  239.   struct cursorRec *next_region;
  240.  
  241.   /*  Save things which belong to the cursor and not a region  */
  242.   overwrites = cursor->overwrites_image_data;
  243.   draw = cursor->draw;
  244.   next_region = cursor->next_region;
  245.   points = cursor->points;
  246.   /*  Copy the contents of region to cursor  */
  247. #ifdef ANSIC
  248.   (void)memcpy((void *)cursor, (void *)region, sizeof(struct cursorRec));
  249.   if( region->point_cnt > 0 )
  250.     (void)memcpy((void *)points, (void *)region_points,
  251.          (size_t)region->point_cnt * sizeof(XPoint));
  252.   else if( region->point_cnt < 0 )
  253.     (void)memcpy((void *)points, (void *)region_points,
  254.          (size_t)(region->point_cnt * (-sizeof(XSegment)));
  255. #else
  256.   bcopy((char *)region, (char *)cursor, sizeof(struct cursorRec));
  257.   if( region->point_cnt > 0 )
  258.     bcopy((char *)region->points, (char *)points,
  259.       region->point_cnt * sizeof(XPoint));
  260.   else if( region->point_cnt < 0 )
  261.     bcopy((char *)region->points, (char *)points,
  262.       -region->point_cnt * sizeof(XSegment));
  263. #endif
  264.   if( region->annuli && (region->next_annulus != NULL) )
  265.     cursor->next_annulus = copy_annulus (region->next_annulus, 1);
  266.   /*  Restore things which were uniquely the cursor's  */
  267.   cursor->overwrites_image_data = overwrites;
  268.   cursor->draw = draw;
  269.   cursor->next_region = next_region;
  270.   cursor->points = points;
  271.   /*  Set up drawing for polygon or for other cursor types  */
  272.   if( cursor->type == COP_Polygon ) {
  273.     copy_polygon_region_to_cursor (region, cursor);
  274.   }
  275. }
  276.  
  277.  
  278. /*  Subroutine:    match_region
  279.  *  Purpose:    Compare a region with a cursor
  280.  *  Returns:    0 if perfect match, else 1
  281.  */
  282. #ifdef ANSIC
  283. int match_region ( struct cursorRec *cursor, struct cursorRec *region )
  284. #else
  285. int match_region ( cursor, region )
  286.      struct cursorRec *cursor, *region;
  287. #endif
  288. {
  289.   int i;
  290.  
  291.   if( (region != NULL) && (cursor != NULL) &&
  292.       (region->type == cursor->type) ) {
  293.     if( region->type == COP_Polygon ) {
  294.       if( region->poly_cnt == cursor->poly_cnt ) {
  295.     for( i=0; i<region->poly_cnt; i++ ) {
  296.       if( (region->points[i].x != cursor->points[i].x) ||
  297.           (region->points[i].y != cursor->points[i].y) )
  298.         return( 0 );
  299.     }
  300.     return( 1 );
  301.       }
  302.     } else if( region->annuli ) {
  303.       cursor = cursor->next_annulus;
  304.       region = region->next_annulus;
  305.       while( (cursor != NULL) && (region != NULL ) ) {
  306.     if( (region->win.X != cursor->win.X) ||
  307.         (region->win.Y != cursor->win.Y) ||
  308.         (region->win.rayX != cursor->win.rayX) ||
  309.         (region->win.rayY != cursor->win.rayY) )
  310.       return( 0 );
  311.     region = region->next_annulus;
  312.     cursor = cursor->next_annulus;
  313.       }
  314.       if( region == cursor )
  315.     return( 1 );
  316.     } else {
  317.       if( (region->win.X == cursor->win.X) &&
  318.       (region->win.Y == cursor->win.Y) &&
  319.       (region->win.rayX == cursor->win.rayX) &&
  320.       (region->win.rayY == cursor->win.rayY) )
  321.     return( 1 );
  322.     }
  323.   }
  324.   return( 0 );
  325. }
  326.