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

  1. #ifndef lint
  2. static char SccsId[] = "%W%  %G%";
  3. #endif
  4.  
  5. /* Module:    csrctrl.c (Cursor Control)
  6.  * Purpose:    Manipulate the software cursor in response to mouse events
  7.  * Subroutine:    control_cursor()        returns: void
  8.  * Copyright:    1989 Smithsonian Astrophysical Observatory
  9.  *        You may do anything you like with this file except remove
  10.  *        this copyright.  The Smithsonian Astrophysical Observatory
  11.  *        makes no representations about the suitability of this
  12.  *        software for any purpose.  It is provided "as is" without
  13.  *        express or implied warranty.
  14.  * Modified:    {0} Michael VanHilst    initial version         4 June 1989
  15.  *        {1} MVH added arrow and text cursors          1 Jan 1991
  16.  *        {n} <who> -- <does what> -- <when>
  17.  */
  18.  
  19. #include <stdio.h>        /*  stderr, NULL, etc.  */
  20. #include <X11/Xlib.h>        /*  X window stuff  */
  21. #include <X11/Xutil.h>        /*  X window manager stuff  */
  22. #include "hfiles/constant.h"    /*  Define codes  */
  23. #include "hfiles/struct.h"    /*  Declare structure types  */
  24. #include "hfiles/extern.h"    /*  Extern main parameter structures  */
  25.  
  26. static unsigned int three_button_mask = Button1Mask|Button2Mask|Button3Mask;
  27.  
  28.  
  29. #ifdef ANSIC
  30. /*  Exported declarations must be centralized before ANSI C can be used  */
  31.  
  32. void control_cursor()
  33.  
  34. #else
  35.  
  36.   int request_delete_polygon_vertex(), start_size();
  37.   Bool statemotion_in_disp();        /* Function for XCheckIfEvent */
  38.   void grab_polygon_vertex(), draw_annuli(), point_region(), disp_dispbox();
  39.   void delete_annulus(), set_cursor_file_coords(), set_polygon_file_coords();
  40.   void make_new_annulus(), size_cursor(), report_cursor_info(), angle_cursor();
  41.   void move_annuli(), move_cursor(), size_annuli(), update_annuli_centers();
  42.   void save_textcursor();
  43. #ifdef IMTOOL
  44.   void note_trigger_key_position();
  45. #endif
  46.  
  47. #endif
  48.  
  49.  
  50. /*  Subroutine:    control_cursor
  51.  *  Purpose:    Respond to mouse commands
  52.  *  Note:    When not tracking, call on ButtonPress only.
  53.  *        When tracking priority set, enter on Press, Release, & Motion
  54.  */
  55. void control_cursor()
  56. {
  57.   static int oldmode = COP;        /* restore control mode when done */
  58.   static short originating_button;    /* the first determines the action */
  59.   static short cursor_has_moved=0;    /* position params may need updating */
  60.   int not_erased_yet = 1;        /* move-or-size-must-erase-old */
  61.  
  62.   if( control.event.type == ButtonPress ) {
  63.     /*  If mouse button pressed (and no others), start tracking  */
  64.     if( control.priority == 0 ) {
  65.       /*  Don't respond if control button is down  */
  66.       if( control.event.xbutton.state & ControlMask )
  67.     return;
  68.       /*  If not already tracking, set tracking mode  */
  69.       originating_button = control.event.xbutton.button;
  70.       if( cursor.type == COP_Point ) {
  71.     /*  For pointing cursor, this is a region command  */
  72.     point_region(&control.event.xbutton);
  73.     /*  Announce the coordinates  */
  74.     if( control.verbose )
  75.       report_cursor_info(&cursor);
  76. #ifdef IMTOOL
  77.     /*  Give this position over last imcur position for warping mouse  */
  78.     note_trigger_key_position(-1, -1);
  79. #endif
  80.     return;
  81.       } else {
  82.     if( (originating_button != Button1) && (cursor.type == COP_Text) ) {
  83.       save_textcursor(&control.event.xbutton);
  84.     } else {
  85.       if( originating_button == Button3 ) {
  86.         if( cursor.annuli )
  87.           delete_annulus(&cursor, &control.event);
  88.       } else {
  89.         if( cursor.type == COP_Polygon ) {
  90.           /*  Set up parameters for polygon tracking  */
  91.           grab_polygon_vertex(&cursor, &control.event,
  92.                   (originating_button == Button2) );
  93.           not_erased_yet = 0;
  94.         } else if( originating_button == Button2 ) {
  95.           if( (cursor.type == COP_Box) || (cursor.type == COP_Ellipse) )
  96.         cursor.ctrl.active_side = start_size(&cursor, &control.event);
  97.         }
  98.       }
  99.     }
  100.       }
  101.       /*  Store mode (in case called from other mode)  */
  102.       oldmode = control.mode;
  103.       control.mode = COP;
  104.       /*  Set mask for mouse tracking events  */
  105.       control.priority = ButtonPress | ButtonRelease | MotionNotify;
  106.     } else {
  107.       /*  Ignore additional buttons  */
  108.       control.completed = 1;
  109.       return;
  110.     }
  111.   } else if( control.event.type == ButtonRelease ) {
  112.     /*  If mouse button released (and no others are down), end tracking  */
  113.     /*  Which buttons were being held before?  */
  114.     int mask_of_released_button;    /*  State mask of event button  */
  115.     switch( control.event.xbutton.button ) {
  116.     case Button1:
  117.       mask_of_released_button = Button1Mask;
  118.       break;
  119.     case Button2:
  120.       mask_of_released_button = Button2Mask;
  121.       break;
  122.     case Button3:
  123.       mask_of_released_button = Button3Mask;
  124.       break;
  125.     default:
  126.       /*  Default case must fail test  */
  127.       mask_of_released_button = 7;
  128.     }
  129.     /*  If that was the last button, we are done  */
  130.     if( (control.event.xbutton.state & three_button_mask) ==
  131.         mask_of_released_button ) {
  132.       /*  Update cursor file coordinates  */
  133.       if( cursor.type == COP_Polygon ) {
  134.     /*  Update all polygon coordinates which have changed  */
  135.     set_polygon_file_coords(&cursor, &coord.disptofile);
  136.       } else {
  137.     if( cursor_has_moved ) {
  138.       cursor.win.X = (double)cursor.win.x + 0.5;
  139.       cursor.win.Y = (double)cursor.win.y + 0.5;
  140.       set_cursor_file_coords(&cursor, &coord.disptofile, 1);
  141.       if( cursor.annuli )
  142.         update_annuli_centers(&cursor);
  143.       cursor_has_moved = 0;
  144. #ifdef IMTOOL
  145.       /*  Give this position over last imcur position for warping mouse  */
  146.       note_trigger_key_position(-1, -1);
  147. #endif
  148.     } else {
  149.       /*  Else cursor was sized  */
  150.       set_cursor_file_coords (&cursor, &coord.disptofile, 0);
  151.       /*  If finished sizing an annulus, put it in the annulus list  */
  152.       if( cursor.annuli && (originating_button == Button2) ) {
  153.         make_new_annulus (&cursor);
  154.         if( !cursor.overwrites_image_data )
  155.           /*  Redraw all annuli in case we tracked across any  */
  156.           draw_annuli(&cursor, cursor.draw);
  157.       }
  158.     }
  159.       }
  160.       control.completed = 1;
  161.       /*  For point cursor, we never entered tracking mode.  end here  */
  162.       if( cursor.type != COP_Point ) {
  163.     if( control.verbose )
  164.       /*  Announce the coordinates  */
  165.       report_cursor_info (&cursor);
  166.     /*  Unset priority tracking mode  */
  167.     control.priority = 0;
  168.     control.mode = oldmode;
  169.     /*  If image altered by tracking, redraw the image (exc. poly del)  */
  170.     if( cursor.overwrites_image_data &&
  171.         ((originating_button != Button3) || (cursor.type != COP_Polygon)) )
  172.       disp_dispbox();
  173.       }
  174.     }
  175.     /*  Return on any release event  */
  176.     return;
  177.   } else if( control.event.type != MotionNotify )
  178.     return;
  179.   /*  Make sure this is a dispbox event event  */
  180.   if( control.event.xbutton.window != dispbox.ID )
  181.     return;
  182.   /*  Get only the most recent move  */
  183.   XSync(cursor.win.display, 0);
  184.   while( XCheckIfEvent(cursor.win.display, &control.event, statemotion_in_disp,
  185.                (char *)(&three_button_mask)) );
  186.   /*  Must be mouse moved - call relevant cursor activity  */
  187.   switch( originating_button ) {
  188.   case Button1:
  189.     /*  Move the cursor  */
  190.     if( cursor.annuli )
  191.       move_annuli(&cursor, control.event.xmotion.x, control.event.xmotion.y);
  192.     else
  193.       move_cursor(&cursor, &control.event, not_erased_yet);
  194.     cursor_has_moved = 1;
  195.     break;
  196.   case Button2:
  197.     /*  Resize the cursor  */
  198.     if( cursor.annuli )
  199.       size_annuli(&cursor, &control.event);
  200.     else
  201.       size_cursor(&cursor, &control.event, not_erased_yet);
  202.     break;
  203.   case Button3:
  204.     /*  Rotate the cursor or delete point  */
  205.     if( !cursor.annuli ) {
  206.       if( (cursor.type == COP_Box) ||
  207.       (cursor.type == COP_Ellipse) ||
  208.       (cursor.type == COP_Arrow) ) {
  209.     angle_cursor(&cursor, &control.event);
  210.       } else if( cursor.type == COP_Polygon ) {
  211.     /*  This is a delete point operation, redisplay if needed  */
  212.     if( request_delete_polygon_vertex(&cursor, &control.event) )
  213.       disp_dispbox();
  214.       }
  215.       /*  Else do nothing for now  */
  216.     }
  217.     break;
  218.   }
  219.   /*  Suppress the zoombox and everything else if not tracking  */
  220.   if( ((control.event.xbutton.state & (ShiftMask | LockMask)) ==0) ^
  221.       (control.tracking !=0) )
  222.     control.completed = 1;
  223. }
  224.