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

  1. #ifndef lint
  2. static char SccsId[] = "%W%  %G%";
  3. #endif
  4.  
  5. /* Module:    rgnctrl.c (Region Control)
  6.  * Purpose:    Respond to region commands from various sources
  7.  * Subroutine:    point_region()        returns: void
  8.  * Subroutine:    ascii_region()        returns: void
  9.  * Subroutine:    select_region()        returns: void
  10.  * Copyright:    1989 Smithsonian Astrophysical Observatory
  11.  *        You may do anything you like with this file except remove
  12.  *        this copyright.  The Smithsonian Astrophysical Observatory
  13.  *        makes no representations about the suitability of this
  14.  *        software for any purpose.  It is provided "as is" without
  15.  *        express or implied warranty.
  16.  * Modified:    {0} Michael VanHilst    initial version          26 May 1989
  17.  *        {n} <who> -- <does what> -- <when>
  18.  */
  19.  
  20. #include <stdio.h>        /*  Define stderr, NULL */
  21. #include <X11/Xlib.h>        /*  X window stuff */
  22. #include <X11/Xutil.h>        /*  X window manager stuff, visuals */
  23. #include <X11/keysym.h>
  24. #include <X11/keysymdef.h>
  25. #include "hfiles/constant.h"    /*  Define codes */
  26. #include "hfiles/struct.h"    /*  Declare structure types */
  27. #include "hfiles/extern.h"    /*  Extern main parameter structures  */
  28.  
  29. struct cursorRec *cycle_region = 0;
  30.  
  31.  
  32. #ifdef ANSIC
  33.  
  34. void        point_region(        XButtonEvent *xbutton);
  35. void        ascii_region(        XKeyEvent *xkey, KeySym keysym);
  36. static void    cycle_regions();
  37. static void    reset_regions();
  38.  
  39. #else
  40.  
  41.   struct cursorRec *region_indicated_by_pointer();
  42.   int match_region();
  43.   void unsave_region(), set_cursor_file_coords(), disp_dispbox();
  44.   void save_cursor_as_region(), disp_region(), unsave_region();
  45.   void enable_annuli_button(), delete_annuli(), erase_cursor();
  46.   void copy_region_to_cursor(), disp_cursor(), d_transform(), draw_magnifier();
  47.   void label_region_cycle_magnifier(), touch_submenu_button();
  48.   void set_submenu_toggle(), enable_ortho_button();
  49.   void toggle_region_labeling(), toggle_region_visibility();
  50.   void write_regions(), read_regions(), free_cursor();
  51.   static void cycle_regions(), reset_regions();
  52.  
  53. #endif
  54.  
  55.  
  56. /*  Subroutine:    point_region
  57.  *  Purpose:    Respond to a mouse activated request for a point region
  58.  *  Note:    In cursor point mode the mouse buttons map directly:
  59.  *   left - save for include, middle - save for exclude, right - delete
  60.  */
  61. #ifdef ANSIC
  62. void point_region ( XButtonEvent *xbutton )
  63. #else
  64. void point_region ( xbutton )
  65.      XButtonEvent *xbutton;
  66. #endif
  67. {
  68.   struct cursorRec *region;
  69.  
  70.   /*  Right button is a delete request in point cursor mode  */
  71.   if( xbutton->button == Button3 ) {
  72.     /*  See if mouse indicates a region to delete  */
  73.     region = region_indicated_by_pointer(&cursor, xbutton->x, xbutton->y, 1);
  74.     if( region != NULL ) {
  75.       unsave_region(&cursor, region);
  76.       disp_dispbox();
  77.     }
  78.   } else if( (xbutton->button == Button1) || (xbutton->button == Button2) ) {
  79.     cursor.win.x = xbutton->x;
  80.     cursor.win.y = xbutton->y;
  81.     cursor.win.X = (double)cursor.win.x + 0.5;
  82.     cursor.win.Y = (double)cursor.win.y + 0.5;
  83.     /*  Force file coordinates into agreement with window coordinates  */
  84.     set_cursor_file_coords(&cursor, &coord.disptofile, 1);
  85.     /*  Save cursor as a region  */
  86.     if( xbutton->button == Button1 )
  87.       save_cursor_as_region(&cursor, 0);
  88.     else
  89.       save_cursor_as_region(&cursor, 1);
  90.     cursor.index = cursor.next_region->index;
  91.     disp_region(cursor.next_region);
  92.   }
  93. }
  94.  
  95.  
  96. /*  Subroutine:    ascii_region
  97.  *  Purpose:    Keyboard control of regions
  98.  */
  99. #ifdef ANSIC
  100. void ascii_region ( XKeyEvent *xkey, KeySym keysym )
  101. #else
  102. void ascii_region ( xkey, keysym )
  103.      XKeyEvent *xkey;
  104.      KeySym keysym;
  105. #endif
  106. {
  107.   int exclude;
  108.   struct cursorRec *region;
  109.  
  110.   if( cursor.type == COP_Point ) {
  111.     cursor.win.x = xkey->x;
  112.     cursor.win.y = xkey->y;
  113.     cursor.win.X = (double)cursor.win.x + 0.5;
  114.     cursor.win.Y = (double)cursor.win.y + 0.5;
  115.   }
  116.   /*  Initialize values used or switched in overlapping functions  */
  117.   region = cursor.next_region;
  118.   exclude = 0;
  119.   switch( keysym ) {
  120.   case XK_E:
  121.   case XK_e:
  122.     exclude = 1;
  123.   case XK_S:
  124.   case XK_s:
  125.     /*  Force file coordinates into agreement with window coordinates  */
  126.     set_cursor_file_coords(&cursor, &coord.disptofile, 0);
  127.     set_cursor_file_coords(&cursor, &coord.disptofile, 1);
  128.     save_cursor_as_region(&cursor, exclude);
  129.     disp_region(cursor.next_region);
  130.     break;
  131.   case XK_D:
  132.   case XK_d:
  133.     region = region_indicated_by_pointer(&cursor, xkey->x, xkey->y, 0);
  134.   case XK_Delete:
  135.     if( region != NULL ) {
  136.       unsave_region(&cursor, region);
  137.       disp_dispbox();
  138.     }
  139.     break;
  140.   default:
  141.     break;
  142.   }
  143. }
  144.  
  145.  
  146. /*  Subroutine:    select_region
  147.  *  Purpose:    Act on commands from the region button panel
  148.  */
  149. void select_region ( )
  150. {
  151.   switch( control.response[1] ) {
  152.   /*  This case comes up when the main menu button is pressed */
  153.   case 0:
  154.     break;
  155.   case ROP_Cycle:
  156.     cycle_regions();
  157.     break;
  158.   case ROP_Label:
  159.     toggle_region_labeling();
  160.     break;
  161.   case ROP_Omit:
  162.     if( match_region(&cursor, cycle_region) ) {
  163.       unsave_region(&cursor, cycle_region);
  164.       /*  Redisplay without the omitted region  */ 
  165.       disp_dispbox();
  166.     }
  167.     break;
  168.   case ROP_View:
  169.     toggle_region_visibility();
  170.     break;
  171.   case ROP_Reset:
  172.     reset_regions();
  173.     break;
  174.   case ROP_Write:
  175.     write_regions(&cursor, &img, img.file_type);
  176.     break;
  177.   case ROP_Read:
  178.     read_regions();
  179.     break;
  180.   default:
  181.     break;
  182.   }
  183. }
  184.  
  185.  
  186. /* Subroutine:    cycle_regions
  187.  * Purpose:    Cylce cursor through saved regions
  188.  */
  189. static void cycle_regions()
  190. {
  191.   float bufx, bufy;
  192.   int annuli_disabled, annuli_on;
  193.  
  194.   /*  There must be saved regions through which to cycle  */
  195.   if( cursor.next_region == NULL ) {
  196.     (void)fprintf(stderr, "Warning: no saved regions.\n");
  197.     return;
  198.   }
  199.   /*  Determine if annuli button is currently disabled or on  */
  200.   annuli_on = 0;
  201.   if( (cursor.type != COP_Point) && (cursor.type != COP_Polygon) ) {
  202.     annuli_disabled = 0;
  203.     if( cursor.annuli )
  204.       annuli_on = 1;
  205.   } else
  206.     annuli_disabled = 1;
  207.   /*  Erase the cursor while we still know it  */
  208.   if( cursor.overwrites_image_data ) {
  209.     /*  Redraw image and any saved cursors, but not the cursor  */
  210.     if( cursor.next_annulus != NULL )
  211.       delete_annuli (&cursor, 0);
  212.     cursor.annuli = 0;
  213.     cursor.point_cnt = 0;
  214.     cursor.rectangle_cnt = 0;
  215.     disp_dispbox();
  216.   } else {
  217.     if( cursor.next_annulus != NULL )
  218.       /*  Delete_annuli does an erase cursor  */
  219.       delete_annuli(&cursor, 0);
  220.     else
  221.       erase_cursor(&cursor);
  222.   }
  223.   /*  Get next region in cycle  */
  224.   if( cycle_region == NULL )
  225.     cycle_region = cursor.next_region;
  226.   else
  227.     cycle_region = cycle_region->next_region;
  228.   /*  If at end of list, go back to head of list  */
  229.   if( cycle_region == NULL )
  230.     cycle_region = cursor.next_region;
  231.   /*  Make cursor be a copy of this region  */
  232.   copy_region_to_cursor(&cursor, cycle_region);
  233.   /*  If this is a text cursor, set the editor info for this string  */
  234.   if( cursor.type == COP_Text )
  235.     reload_textcursor();
  236.   if( cursor.type != COP_Point )
  237.     /*  Draw the cursor  */
  238.     disp_cursor(&cursor);
  239.   /*  Show exact region position in magnifier  */
  240.   d_transform(&coord.disptobuf, cursor.win.X, cursor.win.Y, &bufx, &bufy);
  241.   draw_magnifier((double)bufx, (double)bufy);
  242.   /*  Label what we just drew  */
  243.   label_region_cycle_magnifier (cycle_region, 1);
  244.   /*  Make sure cursor buttons are correct  */
  245.   touch_submenu_button(COP, cursor.type);
  246.   if( (cursor.type == COP_Box) ||
  247.       (cursor.type == COP_Circle) ||
  248.       (cursor.type == COP_Ellipse) ) {
  249.     if( annuli_disabled )
  250.       enable_annuli_button(1);
  251.     if( annuli_on != cursor.annuli )
  252.       set_submenu_toggle(COP, COP_Annuli, cursor.annuli);
  253.     if( cursor.type == COP_Circle )
  254.       enable_ortho_button(0);
  255.     else
  256.       enable_ortho_button(1);
  257.   } else if( !annuli_disabled ) {
  258.     enable_annuli_button(0);
  259.     enable_ortho_button(0);
  260.   }
  261. }
  262.  
  263.  
  264. /*  Subroutine:    reset_regions
  265.  *  Purpose:    Reset all save cursor areas
  266.  */
  267. static void reset_regions()
  268. {
  269.   struct cursorRec *region, *next, *annulus;
  270.  
  271.   if( (next = cursor.next_region) != NULL ) {
  272.     while( next != NULL ) {
  273.       region = next;
  274.       next = next->next_region;
  275.       /*  Free deleted region and any annuli it might have  */
  276.       do {
  277.     annulus = region->next_annulus;
  278.     free_cursor(region);
  279.     region = annulus;
  280.       } while( region != NULL );
  281.     }
  282.     /*  Reset cycle pointer  */
  283.     cycle_region = NULL;
  284.     cursor.next_region = NULL;
  285.     /*  Redisplay image without the regions  */
  286.     disp_dispbox();
  287.   }
  288. }
  289.