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

  1. #ifndef lint
  2. static char SccsId[] = "%W%  %G%";
  3. #endif
  4.  
  5. /*
  6.  * Module:    press.c (Push Button)
  7.  * Project:    PROS -- ROSAT RSDC
  8.  * Purpose:    Handle bookkeeping and visuals for pressing a button
  9.  * Subroutines:    btn_PushButton()            returns: int
  10.  * Subroutines:    btn_ReleaseButton()            returns: void
  11.  * Xlib calls:    XSync()
  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        31 March 1989
  19.  *        {n} <who> -- <does what> -- <when>
  20.  */
  21.  
  22. #include <stdio.h>    /* define stderr */
  23. #include <X11/Xlib.h>    /* needed for Buttons.h */
  24. #include "buttons.h"
  25.  
  26. /*
  27.  * Subroutine:    btn_PushButton
  28.  * Purpose:    Handle buttonbox behavior in response to a mouse button being
  29.  *        pressed while the mouse cursor is in a buttonbox button
  30.  *        (or as if that was the case)
  31.  * Returns:    1 if able to find button and button function, else 0
  32.  * Called by:    btn_Control() in EventCtrl.c
  33.  * Called by:    TouchButton() in RemoteCtrl.c
  34.  * Uses:    btn_PutImage(), btn_DrawButton() in DrawButton.c
  35.  * Uses:    btn_DelightButtons() in DrawButton.c
  36.  * Uses:    btn_ReplaceSubmenus(), btn_ReplaceCosubmenus() in MountBox.c
  37.  * Xlib calls:    XSync()
  38.  * Post-state:    Records updated, submenus replaced, buttons highlighted
  39.  * Method:    
  40.  * Note:    detail=(event.xbutton.button<<16)|(event.xbutton.state&0xffff)
  41.  * Note:    event filtering to select a response is detail&mask==reference
  42.  */
  43. int btn_PushButton ( buttonbox, btn, mouse_btn, state, mapping )
  44.      ButtonBox buttonbox;    /* i: box which contains this button */
  45.      int btn;            /* i: button identifying index */
  46.      int mouse_btn;        /* i: event.xbutton.button */
  47.      int state;            /* i: event.xbutton.state */
  48.      int mapping;        /* i: indicate whether to map submenus */
  49. {
  50.   ButtonRecord *button;        /* l: pointer to record of pressed button */
  51.   ButtonFeel *feel;        /* l: pointer to feel of pressed button */
  52.   int detail;            /* l: composite of mouse_btn and state */
  53.   int fnum;            /* l: index of accepting function mask/ref */
  54.   int type;            /* l: response type of button/function */
  55.   void btn_PutImage(), btn_DrawButton(), btn_DelightButtons();
  56.   void btn_ReplaceSubmenus(), btn_ReplaceCosubmenus();
  57.  
  58.   /* detail = (event.xbutton.button << 16) | (event.xbutton.state & 0xffff); */
  59.   detail = (mouse_btn << 16) | (state & 0xffff);
  60.   button = &buttonbox->buttons[btn];
  61.   feel = button->feel;
  62.   /* identify which button option it is */
  63.   for( fnum = 0; fnum < feel->nfunctions; ++fnum ) {
  64.     if( (detail & feel->mask[fnum]) == feel->reference[fnum] )
  65.       break;
  66.   }
  67.   /* if no option matches, ignore and return */
  68.   if( fnum >= feel->nfunctions )
  69.     return( 0 );
  70.   /* flag this as our mouse button */
  71.   buttonbox->down_btn = btn;
  72.   buttonbox->down_btn_func = fnum;
  73.   buttonbox->down_mouse_btn = mouse_btn;
  74.   /* what kind of button was it */
  75.   type = feel->function[fnum];
  76.   /* if selection is a BTNNoOp don't respond */
  77.   if( type == BTNNoOp )
  78.     return( 0 );
  79.   /* highlight this button (may be redone by toggle) */
  80.   button->highlight = 1;
  81.   switch( type ) {
  82.   case BTNMode:
  83.   /* if selection affects the prior mode status */
  84.     /* unhighlight previous selection if there is one */
  85.     if( buttonbox->mode_btn >= 0 ) {
  86.       buttonbox->buttons[buttonbox->mode_btn].selected = 0;
  87.       buttonbox->buttons[buttonbox->mode_btn].highlight = 0;
  88.       btn_PutImage (&buttonbox->buttons[buttonbox->mode_btn], OFF_OUT);
  89.       /* if this is the mode's button, blink but be highlighted */
  90.       if( buttonbox->mode_btn == btn ) {
  91.     button->highlight = 1;
  92.     if( buttonbox->mode_btn_func == fnum ) {
  93.       /* if this is the mode, don't change anything */
  94.       button->selected = 1;
  95.       if( button->occupied == 1 )
  96.         btn_PutImage(button, ON_IN);
  97.       else
  98.         btn_PutImage(button, ON_OUT);
  99.       XSync(buttonbox->display, 0);
  100.       /* no change in mode occurs, so return */
  101.       return( 1 );
  102.     }
  103.       }
  104.     }
  105.     /* indicate this selection */
  106.     button->selected = 1;
  107.     buttonbox->mode_btn = btn;
  108.     buttonbox->mode_btn_func = fnum;
  109.     break;
  110.   case BTNCoMode:
  111.   /* if selection affects the prior CoMode status */
  112.     /* unhighlight previous selection if there is one */
  113.     if( buttonbox->co_mode_btn >= 0 ) {
  114.       buttonbox->buttons[buttonbox->co_mode_btn].selected = 0;
  115.       buttonbox->buttons[buttonbox->co_mode_btn].highlight = 0;
  116.       btn_PutImage(&buttonbox->buttons[buttonbox->co_mode_btn], OFF_OUT);
  117.       /* if this is the CoMode's button, blink but be highlighted */
  118.       if( buttonbox->co_mode_btn == btn ) {
  119.     button->highlight = 1;
  120.     if( buttonbox->co_mode_func == fnum ) {
  121.       /* if this is the CoMode, don't change anything */
  122.       button->selected = 1;
  123.       if( button->occupied == 1 )
  124.         btn_PutImage(button, ON_IN);
  125.       else
  126.         btn_PutImage(button, ON_OUT);
  127.       XSync(buttonbox->display, 0);
  128.       return( 1 );
  129.     }
  130.       }
  131.     } else {
  132.       int co_btn;        /* l: current co-mode button */
  133.       int i;            /* l: loop counter */
  134.  
  135.       for( i = 0; i < buttonbox->co_menu_count; i++ ) {
  136.     /* look for the current CoMode button in other co_menus */
  137.     if( (co_btn = buttonbox->co_menu[i]->co_mode_btn) >= 0 ) {
  138.       /* if this was the previous choice, unset it */
  139.       buttonbox->co_menu[i]->buttons[co_btn].selected = 0;
  140.       buttonbox->co_menu[i]->buttons[co_btn].highlight = 0;
  141.       btn_PutImage(&buttonbox->co_menu[i]->buttons[co_btn], OFF_OUT);
  142.       buttonbox->co_menu[i]->co_mode_btn = -1;
  143.       buttonbox->co_menu[i]->co_mode_func = 0;
  144.       /* look no further */
  145.       break;
  146.     }
  147.       }
  148.     }
  149.     /* indicate this selection */
  150.     button->selected = 1;
  151.     buttonbox->co_mode_btn = btn;
  152.     buttonbox->co_mode_func = fnum;
  153.     break;
  154.   case BTNCoWhile:
  155.   /* if selection is a temporary and exclusive CoWhile */
  156.     /* dim all other highlighted buttons (until mouse button released) */
  157.     btn_DelightButtons(buttonbox);
  158.     break;
  159.   case BTNToggle:
  160.   /* toggle a Toggle button */
  161.     if( button->selected == 1 ) {
  162.       /* if highlighted, unhighlight */
  163.       button->selected = 0;
  164.       button->highlight = 0;
  165.     } else {
  166.       /* else highlight this button */
  167.       button->selected = 1;
  168.       button->highlight = 1;
  169.     }
  170.     break;
  171.   /* for BTNFlash, make button appear briefly in opposite highlighting */
  172.   case BTNFlash:
  173.     /* unhighlight (or higlight) this button, mindful of status */
  174.     if (button->selected == 1)
  175.       button->highlight = 0;
  176.     break;
  177.   case BTNOneShot:
  178.   case BTNWhile:
  179.   /* nothing more than highlighting for OneShot or While */
  180.   default:
  181.     break;
  182.   }
  183.   /* draw highlighted (or unhighlighted) button */
  184.   btn_DrawButton(button);
  185.   /* redraw buttons before any other processing */
  186.   XSync(buttonbox->display, 0);
  187.   if( type == BTNFlash ) {
  188.     /* unhighlight (or higlight) this button, mindful of status */
  189.     if( button->selected == 0 )
  190.       button->highlight = 0;
  191.     else
  192.       button->highlight = 1;
  193.     /* draw highlighted (or unhighlighted) button */
  194.     btn_DrawButton(button);
  195.     XSync(buttonbox->display, 0);
  196.   } else if( type == BTNMode ) {
  197.     /* install new submenu environment */
  198.     btn_ReplaceSubmenus(buttonbox, btn, fnum, mapping);
  199.   } else if( type == BTNCoMode ) {
  200.     /* install new cosubmenu environment */
  201.     btn_ReplaceCosubmenus(buttonbox, btn, fnum, mapping);
  202.   } else if( (type == BTNToggle) && (button->submenu_count[fnum] > 0) ) {
  203.     if( button->selected ) {
  204.       btn_ReplaceSubmenus(buttonbox, btn, fnum, mapping);
  205.     } else {
  206.       detail = button->submenu_count[fnum];
  207.       button->submenu_count[fnum] = 0;
  208.       btn_ReplaceSubmenus(buttonbox, btn, fnum, mapping);
  209.       button->submenu_count[fnum] = detail;
  210.     }
  211.   }
  212.   return( 1 );
  213. }
  214.  
  215. /*
  216.  * Subroutine:    btn_ReleaseButton
  217.  * Purpose:    Handle most of the buttonbox behavior in response to a mouse
  218.  *        button being released after being pressed
  219.  * Returns:    void
  220.  * Called by:    btn_Control() in EventCtrl.c
  221.  * Called by:    TouchButton() in RemoteCtrl.c
  222.  * Uses:    btn_PutImage(), btn_RelightButtons() in DrawButton.c
  223.  * Xlib calls:    XSync()
  224.  * Post-state:    Records updated, buttons rehighlighted
  225.  * Method:    
  226.  * Note:    Caller must redraw the released button
  227.  */
  228. void btn_ReleaseButton ( buttonbox, type, btn )
  229.      ButtonBox buttonbox;    /* i: box which contains this button */
  230.      int type;
  231.      int btn;            /* i: button identifying index */
  232. {
  233.   ButtonRecord *button;        /* l: pointer to record of pressed button */
  234.   void btn_PutImage(), btn_RelightButtons();
  235.  
  236.   /* indicate that our mouse button is no longer down */
  237.   buttonbox->down_btn = -1;
  238.   buttonbox->down_btn_func = -1;
  239.   buttonbox->down_mouse_btn = -1;
  240.   switch( type ) {
  241.   /* don't take any special action for mode, toggle, or NoOp */
  242.   case BTNNoOp:
  243.   case BTNFlash:
  244.   case BTNToggle:
  245.   case BTNMode:
  246.   case BTNCoMode:
  247.     return;
  248.   /* for a BTNCoWhile, rehighlight previous mode and report */
  249.   case BTNCoWhile:
  250.     /* unhighlight this button if it was not previously selected */
  251.     button = &buttonbox->buttons[btn];
  252.     if( button->selected == 0 ) {
  253.       button->highlight = 0;
  254.       if( button->occupied == 1 )
  255.     btn_PutImage(button, OFF_IN);
  256.       else
  257.     btn_PutImage(button, OFF_OUT);
  258.     }
  259.     /* highlight buttons that were earlier dimmed */
  260.     btn_RelightButtons (buttonbox);
  261.     /* draw everything correctly before returning */
  262.     XSync(buttonbox->display, 0);
  263.     break;
  264.   case BTNOneShot:
  265.   case BTNWhile:
  266.   default:
  267.     /* unhighlight this button, mindful of status */
  268.     if( buttonbox->buttons[btn].selected == 0 )
  269.       buttonbox->buttons[btn].highlight = 0;
  270.   }
  271. }
  272.