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

  1. #ifndef lint
  2. static char SccsId[] = "%W%  %G%";
  3. #endif
  4.  
  5. /* Module:    dispblnk.c (Display Blink)
  6.  * Purpose:    Switch between stored displays
  7.  * Subroutine:    save_blink()        returns: void
  8.  * Subroutine:    free_blink()        returns: void
  9.  * Subroutine:    clear_blink()        returns: void
  10.  * Subroutine:    unset_blink()        returns: void
  11.  * Subroutine:    control_blink()        returns: void
  12.  * Copyright:    1989 Smithsonian Astrophysical Observatory
  13.  *        You may do anything you like with this file except remove
  14.  *        this copyright.  The Smithsonian Astrophysical Observatory
  15.  *        makes no representations about the suitability of this
  16.  *        software for any purpose.  It is provided "as is" without
  17.  *        express or implied warranty.
  18.  * Modified:    {0} Michael VanHilst    initial version          26 May 1989
  19.  *        {n} <who> -- <does what> -- <when>
  20.  */
  21.  
  22. #include <stdio.h>        /* get stderr, NULL */
  23. #include <X11/Xlib.h>        /* get X types and constants */
  24. #include <X11/Xutil.h>        /* X window manager stuff */
  25. #include "hfiles/struct.h"    /* declare structure types */
  26. #include "hfiles/extern.h"    /* extern main ximage parameter structures */
  27. #include "hfiles/constant.h"    /* define SOP */
  28.  
  29. #define MetaMask Mod1Mask
  30.  
  31. static struct {
  32.   char *buf;
  33.   Pixmap pixmap;
  34.   int depth;
  35.   int bufsz;
  36.   int byte_width;
  37. } blink[4] = { { 0 }, { 0 }, { 0 }, { 0 } };
  38. static int current_index = 0;
  39.  
  40. /*
  41.  * Subroutine:    save_blink
  42.  * Purpose:    Save the current display in a blink buffer
  43.  */
  44. void save_blink ( button )
  45.      int button;
  46. {
  47.   int bufsz, index;
  48.   GC gc, set_gc();
  49.   char *calloc_errchk();
  50.  
  51.   if( blink[0].buf == NULL ) {
  52.     blink[0].buf = dispbox.image.data;
  53.     blink[0].depth = dispbox.image.depth;
  54.     blink[0].byte_width = dispbox.image.bytes_per_line;
  55.   }
  56.   if( blink[0].depth == 1 )
  57.     bufsz = ((dispbox.xwidth + 7) / 8) * dispbox.yheight * sizeof(short);
  58.   else
  59.     bufsz = dispbox.xwidth * dispbox.yheight;
  60.   if( button == Button1 )
  61.     index = 1;
  62.   else if( button == Button2 )
  63.     index = 2;
  64.   else
  65.     index = 3;
  66.   if( blink[index].bufsz != bufsz ) {
  67.     if( blink[index].buf != NULL ) {
  68.       free((char *)blink[index].buf);
  69.       blink[index].buf = NULL;
  70.     }
  71.     if( blink[index].pixmap != NULL ) {
  72.       XFreePixmap (dispbox.display, blink[index].pixmap);
  73.       blink[index].pixmap = NULL;
  74.     }
  75.     blink[index].depth = blink[0].depth;
  76.     if( (blink[index].pixmap =
  77.      XCreatePixmap(dispbox.display, dispbox.ID, dispbox.xwidth,
  78.                dispbox.yheight, blink[index].depth)) == NULL )
  79.       blink[index].buf = calloc_errchk(bufsz, 1, "blink");
  80.     blink[index].bufsz = bufsz;
  81.   }
  82.   if( blink[index].pixmap != NULL ) {
  83.     gc = set_gc(&(color.gcset.disp));
  84.     if( blink[index].depth == 1 )
  85.       XCopyPlane(dispbox.display, dispbox.ID, blink[index].pixmap, gc,
  86.          dispbox.xzero, dispbox.yzero,
  87.          dispbox.xwidth, dispbox.yheight, 0, 0, 1);
  88.     else
  89.       XCopyArea(dispbox.display, dispbox.ID, blink[index].pixmap, gc,
  90.         dispbox.xzero, dispbox.yzero,
  91.         dispbox.xwidth, dispbox.yheight, 0, 0);
  92.   } else {
  93.     bcopy((char *)dispbox.image.data, blink[index].buf, bufsz);
  94.     blink[index].depth = dispbox.image.depth;
  95.     blink[index].byte_width = dispbox.image.bytes_per_line;
  96.   }
  97. }
  98.  
  99. /*
  100.  * Subroutine:    free_blink
  101.  * Purpose:    When dispbox changes size, dump all current buffers
  102.  */
  103. void free_blink ( )
  104. {
  105.   int i;
  106.   void clear_blink();
  107.  
  108.   clear_blink();
  109.   for( i=1; i<4; i++ ) {
  110.     if( blink[i].buf != NULL ) {
  111.       free((char *)blink[i].buf);
  112.       blink[i].buf = NULL;
  113.     }
  114.     if( blink[i].pixmap != NULL ) {
  115.       XFreePixmap (dispbox.display, blink[i].pixmap);
  116.       blink[i].pixmap = NULL;
  117.     }
  118.     blink[i].bufsz = 0;
  119.   }
  120. }
  121.  
  122. /*
  123.  * Subroutine:    clear_blink
  124.  * Purpose:    Reset basic blink parameters when color arrangements change
  125.  */
  126. void clear_blink ( )
  127. {
  128.   if( (blink[0].buf != NULL) && (current_index != 0) ) {
  129.     dispbox.image.depth = blink[0].depth;
  130.     dispbox.image.bytes_per_line = blink[0].byte_width;
  131.     dispbox.image.data = blink[0].buf;
  132.   }
  133.   current_index = 0;
  134.   blink[0].buf = NULL;
  135. }
  136.  
  137. /*
  138.  * Subroutine:    unset_blink
  139.  * Purpose:    Indicate that display no longer holds a blinking image
  140.  *        Use when display is redrawn by regular display update routine
  141.  */
  142. void unset_blink ( )
  143. {
  144.   current_index = 0;
  145. }
  146.  
  147. /*
  148.  * Subroutine:    display_blink
  149.  */
  150. static int display_blink ( index )
  151.      int index;
  152. {
  153.   GC gc, set_gc();
  154.   void disp_dispbox();
  155.  
  156.   if( blink[index].pixmap != NULL ) {
  157.     gc = set_gc(&(color.gcset.disp));
  158.     if( blink[index].depth == 1 )
  159.       XCopyPlane(dispbox.display, blink[index].pixmap, dispbox.ID, gc, 0, 0,
  160.          dispbox.xwidth, dispbox.yheight,
  161.          dispbox.xzero, dispbox.yzero, 1);
  162.     else
  163.       XCopyArea(dispbox.display, blink[index].pixmap, dispbox.ID, gc, 0, 0,
  164.         dispbox.xwidth, dispbox.yheight, dispbox.xzero, dispbox.yzero);
  165.   } else if( blink[index].buf != NULL ) {
  166.     dispbox.image.data = blink[index].buf;
  167.     dispbox.image.depth = blink[index].depth;
  168.     dispbox.image.bytes_per_line = blink[index].byte_width;
  169.     disp_dispbox();
  170.   } else
  171.     return( 0 );
  172.   current_index = index;
  173.   XSync (dispbox.display, 0);
  174.   return( 1 );
  175. }
  176.  
  177. /*
  178.  * Subroutine:    control_blink
  179.  * Purpose:    Control blinking of stored displays
  180.  * For each new button press, put it on top of stack and display its buffer
  181.  * For each button release, if it is on top of stack, release it and display
  182.  *  one below, else just release it
  183.  */
  184. void control_blink ()
  185. {
  186.   static int oldmode;
  187.   static int buttons = 0;
  188.   static int btnstack[4];
  189.   int i;
  190.   static int display_blink();
  191.  
  192.   if( control.event.type == ButtonPress ) {
  193.     /* don't respond if it's with a meta key (window resize) */
  194.     if( control.event.xbutton.state & (ControlMask | MetaMask) )
  195.       return;
  196.     if( ++buttons == 1 ) {
  197.       /* store mode (may be called from other mode) */
  198.       oldmode = control.mode;
  199.       control.mode = SOP;
  200.       /* events to send through here in any case */
  201.       control.priority = ButtonPressMask | ButtonReleaseMask;
  202.     }
  203.     btnstack[buttons] = control.event.xbutton.button;
  204.   } else if( control.event.type == ButtonRelease ) {
  205.     /* don't respond if we weren't doing anything */
  206.     if( buttons <= 0 )
  207.       return;
  208.     if( buttons == 1 ) {
  209.       /* unset tracking priority */
  210.       control.mode =  oldmode;
  211.       control.priority = 0;
  212.     }
  213.     if( btnstack[buttons] != control.event.xbutton.button ) {
  214.       /* button other than top one released, lower the stack */
  215.       for( i = 1;
  216.        (i <= buttons) && (btnstack[i] != control.event.xbutton.button);
  217.        i++ );
  218.       while( i<buttons ) {
  219.     btnstack[i] = btnstack[i+1];
  220.     ++i;
  221.       }
  222.       --buttons;
  223.       return;
  224.     } else {
  225.       --buttons;
  226.     }
  227.   } else {
  228.     /* not our kind of event */
  229.     return;
  230.   }
  231.   /* which buffer is indicated? */
  232.   switch( btnstack[buttons] ) {
  233.   case Button1:
  234.     i = 1;
  235.     break;
  236.   case Button2:
  237.     i = 2;
  238.     break;
  239.   case Button3:
  240.     i = 3;
  241.     break;
  242.   default:
  243.     i = 0;
  244.     break;
  245.   }
  246.   /* display the selected buffer */
  247.   if( display_blink(i) == 0 )
  248.     (void)fprintf(stderr, "WARNING: Frame[%d] is empty\n", buttons);
  249. }
  250.