home *** CD-ROM | disk | FTP | other *** search
/ Encyclopedia of Graphics File Formats Companion / GFF_CD.ISO / software / unix / saoimage / sao1_07.tar / wndwmaus.c < prev   
C/C++ Source or Header  |  1990-04-20  |  10KB  |  300 lines

  1. #ifndef lint
  2. static char SccsId[] = "%W%  %G%";
  3. #endif
  4.  
  5. /* Module:    wndwmaus.c (Window Mouse)
  6.  * Purpose:    Set the mouse pointer icon for each window and mode
  7.  * Subroutine:  init_mousepointers()        returns: void
  8.  * Subroutine:    new_dispboxmouse()        returns: void
  9.  * Subroutine:    set_trigger_key_mouse()        returns: void
  10.  * Xlib calls:    DefaultScreen, DefaultRootWindow, DefaultColormap
  11.  * Xlib calls:    BlackPixel, WhitePixel, XQueryColors()
  12.  * Xlib calls:    XCreateBitmapFromData(), XCreatePixmapCursor(), XFreePixmap()
  13.  * Xlib calls:    XDefineCursor(), XSync(), XQueryPointer(), XWarpPointer()
  14.  * Copyright:    1989 Smithsonian Astrophysical Observatory
  15.  *        You may do anything you like with this file except remove
  16.  *        this copyright.  The Smithsonian Astrophysical Observatory
  17.  *        makes no representations about the suitability of this
  18.  *        software for any purpose.  It is provided "as is" without
  19.  *        express or implied warranty.
  20.  * Modified:    {0} Michael VanHilst    initial version        30 April 1989
  21.  *        {1} MVH icon for key to trigger IRAF write        16 Aug 1989
  22.  *              {2} MVH BSDonly strings.h compatability           19 Feb 1990
  23.  *        {n} <who> -- <does what> -- <when>
  24.  */
  25.  
  26. #include <stdio.h>            /* stderr, NULL, etc. */
  27.  
  28. #ifndef VMS
  29. #ifdef SYSV
  30. #include <string.h>        /* strlen, strcat, strcpy, strrchr */
  31. #else
  32. #include <strings.h>        /* strlen, strcat, strcpy, rindex */
  33. #endif
  34. #else
  35. #include <string.h>        /* strlen, strcat, strcpy, strrchr */
  36. #endif
  37.  
  38. #include <X11/Xlib.h>            /* X window stuff */
  39. #include <X11/Xutil.h>            /* window manager stuff */
  40. #include "hfiles/constant.h"        /* constants and codes */
  41. #include "hfiles/struct.h"        /* all struct record types */
  42. #include "hfiles/extern.h"        /* major declared structs */
  43.  
  44. #include "defs/mouse.def"        /* bitmaps for mouse cursors */
  45. extern Window root;
  46.  
  47. static Cursor pancursor;
  48. static Cursor cursorcursor;
  49. static Cursor colorcursor;
  50. static Cursor shuttlecursor;
  51. static Cursor missilecursor;
  52. #ifdef NOTUSED
  53. static Cursor plaincursor;
  54. #endif
  55. #ifdef IMTOOL
  56. static Cursor keycursor;
  57. #endif
  58.  
  59. /*
  60.  * Subroutine:    init_mousepointers
  61.  * Purpose:    Set up the various mouse pointer icons for all windows
  62.  */
  63. void init_mousepointers ( dispdisplay, auxdisplay )
  64.      Display *dispdisplay;    /* i: display for the dispbox */
  65.      Display *auxdisplay;    /* i: display for the auxiliary windows */
  66. {
  67.   static Cursor make_mouse_cursor();
  68.  
  69.   /* create special btnbox cursor for button menu window */
  70.   btnbox.attrs.cursor =
  71.     make_mouse_cursor(auxdisplay, button_bits, button_mask_bits,
  72.               button_width, button_height,
  73.               button_x_hot, button_y_hot);
  74.   btnbox.valuemask |= CWCursor;
  75.   /* create special missile cursor for magnifier window */
  76.   magnibox.attrs.cursor = 
  77.     make_mouse_cursor(auxdisplay, missile_bits, missile_mask_bits,
  78.               missile_width, missile_height,
  79.               missile_x_hot, missile_y_hot);
  80.   magnibox.valuemask |= CWCursor;
  81.   /* create special color graph manipulation cursor */
  82.   colorbox.attrs.cursor =
  83.     make_mouse_cursor(auxdisplay, cgraph_bits, cgraph_bits,
  84.               cgraph_width, cgraph_height,
  85.               cgraph_x_hot, cgraph_y_hot);
  86.   colorbox.valuemask |= CWCursor;
  87.   graphbox.attrs.cursor = colorbox.attrs.cursor;
  88.   graphbox.valuemask |= CWCursor;
  89.   /* create special pan and zoom cursor */
  90.   panbox.attrs.cursor =
  91.     make_mouse_cursor(auxdisplay, pan_bits, pan_mask_bits,
  92.               pan_width, pan_height, pan_x_hot, pan_y_hot);
  93.   panbox.valuemask |= CWCursor;
  94.   /* create selection of cursors for display window */
  95.   /* create special pan and zoom cursor */
  96.   if( dispdisplay == auxdisplay ) {
  97.     pancursor = panbox.attrs.cursor;
  98.   } else {
  99.     pancursor =
  100.       make_mouse_cursor(dispdisplay, pan_bits, pan_mask_bits,
  101.             pan_width, pan_height, pan_x_hot, pan_y_hot);
  102.   }
  103.   /* create special color manipulation cursor */
  104.   colorcursor =
  105.     make_mouse_cursor(dispdisplay, cgraph_bits, color_mask_bits,
  106.               cgraph_width, cgraph_height,
  107.               cgraph_x_hot, cgraph_y_hot);
  108.   /* create special cursor manipulation cursor */
  109.   cursorcursor =
  110.     make_mouse_cursor(dispdisplay, cursor_bits, cursor_mask_bits,
  111.               cursor_width, cursor_height,
  112.               cursor_x_hot, cursor_y_hot);
  113. #ifdef IMTOOL
  114.   /* create special key triggered cursor readback cursor for IRAF */
  115.   keycursor = 
  116.     make_mouse_cursor(dispdisplay, key_bits, key_mask_bits,
  117.               key_width, key_height, key_x_hot, key_y_hot);
  118. #endif
  119.   /* create special shuttle cursor */
  120.   shuttlecursor =
  121.     make_mouse_cursor(dispdisplay, shuttle_bits, shuttle_mask_bits,
  122.               shuttle_width, shuttle_height,
  123.               shuttle_x_hot, shuttle_y_hot);
  124.   /* install the appropriate cursor in dispbox */
  125.   switch( control.mode ) {
  126.   case VOP:  /* COLOR */
  127.     dispbox.attrs.cursor = colorcursor;
  128.     break;
  129.   case ZOP:  /* PAN */
  130.     dispbox.attrs.cursor = pancursor;
  131.     break;
  132.   case COP:  /* CURSOR */
  133.     dispbox.attrs.cursor = cursorcursor;
  134.     break;
  135.   case EOP:  /* ENV */
  136.   case SOP:  /* SCALE */
  137.   default:
  138.     dispbox.attrs.cursor = shuttlecursor;
  139.     break;
  140.   }
  141. }
  142.  
  143. /*
  144.  * Subroutine:    make_mouse_cursor
  145.  * Purpose:    Make Xlib calls to actually produce a mouse cursor
  146.  * Returns:    Cursor handle ready for use
  147.  * Xlib calls:    DefaultScreen, DefaultRootWindow, DefaultColormap
  148.  * Xlib calls:    BlackPixel, WhitePixel, XQueryColors()
  149.  * Xlib calls:    XCreateBitmapFromData(), XCreatePixmapCursor(), XFreePixmap()
  150.  * Note:    Uses black and white of display's root window's color map
  151.  */
  152. static Cursor make_mouse_cursor ( display, bits, mask_bits,
  153.                   width, height, x_hot, y_hot )
  154.      Display *display;
  155.      char *bits, *mask_bits;
  156.      unsigned int width, height;
  157.      unsigned int x_hot, y_hot;
  158. {
  159.   static XColor foreback[2];
  160.   static Display *display_base = NULL;
  161.   Cursor cursor;
  162.   Pixmap source, mask;
  163.  
  164.   /* renew basic params only if display is different */
  165.   if( display_base != display ) {
  166.     foreback[0].pixel = (unsigned long)color.hard.std_black;
  167.     foreback[1].pixel = (unsigned long)color.hard.std_white;
  168.     XQueryColors(display, color.colormap, foreback, 2);
  169.     display_base = display;
  170.   }
  171.   source = XCreateBitmapFromData(display, root, bits, width, height);
  172.   mask = XCreateBitmapFromData(display, root, mask_bits, width, height);
  173.   cursor = XCreatePixmapCursor
  174.     (display, source, mask, &foreback[0], &foreback[1], x_hot, y_hot);
  175.   XFreePixmap(display, source);
  176.   XFreePixmap(display, mask);
  177.   return( cursor );
  178. }
  179.  
  180. static short oldmode = -1;
  181.  
  182. #ifdef IMTOOL
  183. /* mouse positions saved for cursor interaction with IRAF */
  184. static int freeze_dispboxmouse = 0;
  185. static int trigger_x = -1;
  186. static int trigger_y;
  187. /*
  188.  * Subroutine:    note_trigger_key_position
  189.  * Purpose:    set the reference position for placing the cursor in next
  190.  *        trigger key from iraf
  191.  */
  192. void note_trigger_key_position ( x, y )
  193.      int x, y;
  194. {
  195.   trigger_x = x;
  196.   trigger_y = y;
  197. }
  198.     
  199. /*
  200.  * Subroutine:    set_trigger_key_mouse
  201.  * Purpose:    set special displaybox cursor to indicate cursor readback
  202.  *        trigger on any key is in effect
  203.  * Xlib calls:    XDefineCursor(), XSync(), XQueryPointer(), XWarpPointer()
  204.  */
  205. void set_trigger_key_mouse ( state )
  206.      int state;
  207. {
  208.   static int root_x, root_y = 0;
  209.   Window root_ret, child_ret;
  210.   int win_x, win_y;
  211.   int temp;
  212.   unsigned int mask;
  213.   void new_dispboxmouse(), raise_windows();
  214.  
  215.   if( (freeze_dispboxmouse = state) ) {
  216.     /* save current mouse position unless it is not on this screen */
  217.     if( XQueryPointer(dispbox.display, root, &root_ret, &child_ret,
  218.               &root_x, &root_y, &win_x, &win_y, &mask) == False )
  219.       root_y = 0;
  220.     /* change pointer appearance for this function */
  221.     XDefineCursor(dispbox.display, dispbox.ID, keycursor);
  222.     /* raise the main set of windows, before warp (but not the graphbox) */
  223.     temp = graphbox.active;
  224.     graphbox.active = 0;
  225.     raise_windows();
  226.     XSync(dispbox.display, 0);
  227.     graphbox.active = temp;
  228.     /* if pointer is not in display window, move it there */
  229.     if( child_ret != dispbox.ID ) {
  230.       /* if trigger not set, or cursor was moved more recently, use curpos */
  231.       if( trigger_x < 0 ) {
  232.     if( (cursor.win.x > 0) && (cursor.win.x < dispbox.width) &&
  233.         (cursor.win.y > 0) && (cursor.win.y < dispbox.height) )
  234.       XWarpPointer(dispbox.display, None, dispbox.ID, 0, 0, 0, 0,
  235.                cursor.win.x, cursor.win.y);
  236.     else
  237.       /* if cursor position wouldn't work, just center it */
  238.       XWarpPointer(dispbox.display, None, dispbox.ID, 0, 0, 0, 0,
  239.                dispbox.width / 2, dispbox.height / 2);
  240.       } else
  241.     /* return to last trigger position set by IRAF routines */
  242.     XWarpPointer(dispbox.display, None, dispbox.ID, 0, 0, 0, 0,
  243.              trigger_x, trigger_y);
  244.     } else
  245.       root_y = 0;
  246.     XSync(dispbox.display, 0);
  247.     oldmode = -1;
  248.   } else {
  249.     /* restore mouse position (NOW) if it was saved */
  250.     if( root_y > 0 ) {
  251.       XWarpPointer(dispbox.display, dispbox.ID, root, 0, 0, 0, 0,
  252.            root_x, root_y);
  253.       XSync(dispbox.display, 0);
  254.       root_y = 0;
  255.     }
  256.     new_dispboxmouse();
  257.   }
  258. }
  259. #endif   
  260.  
  261. /*
  262.  * Subroutine:    new_dispboxmouse
  263.  * Purpose:    Install dispbox mouse cursor appropriate for the  mode
  264.  * Xlib calls:    XDefineCursor()
  265.  * Note:    Does installation only if mode is actually different
  266.  */
  267. void new_dispboxmouse ( )
  268. {
  269.  
  270. #ifdef IMTOOL
  271.   if( freeze_dispboxmouse )
  272.     return;
  273. #endif
  274.   if( control.mode == oldmode )
  275.     return;
  276.   oldmode = control.mode;
  277.   switch( control.mode ) {
  278.   /* COLOR */
  279.   case VOP:
  280.     XDefineCursor(dispbox.display, dispbox.ID, colorcursor);
  281.     break;
  282.   /* PAN */
  283.   case ZOP:
  284.     XDefineCursor(dispbox.display, dispbox.ID, pancursor);
  285.     break;
  286.   /* CURSOR */
  287.   case COP:
  288.     XDefineCursor(dispbox.display, dispbox.ID, cursorcursor);
  289.     break;
  290.   /* ENV */
  291.   case EOP:
  292.     XDefineCursor(dispbox.display, dispbox.ID, shuttlecursor);
  293.     break;
  294.   /* SCALE */
  295.   case SOP:
  296.     XDefineCursor(dispbox.display, dispbox.ID, shuttlecursor);
  297.     break;
  298.   }
  299. }
  300.