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

  1. #ifndef lint
  2. static char SccsId[] = "%W%  %G%";
  3. #endif
  4.  
  5. /*
  6.  * Module:    create.c (Make Box)
  7.  * Project:    PROS -- ROSAT RSDC
  8.  * Purpose:    Create a complete (unconnected) buttonbox in the given window
  9.  * Subroutines:    MakeButtonBox()            returns: ButtonBox
  10.  * Subroutines:    static btn_MakeWindows()    returns: void
  11.  * Subroutines:    btn_LabelButtons()        returns: void
  12.  * Subroutines:    SetTAEButtonLook()        returns: void
  13.  * Xlib calls:    XMakeSimpleWindow(), XSelectInput(), XMapSubwindows()
  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        21 March 1989
  21.  *        {1} Jay Travisano (STScI)  VMS,IMTOOL changes   10 Nov   1989
  22.  *        {n} <who> -- <does what> -- <when>
  23.  */
  24.  
  25. #include <stdio.h>    /* define stderr */
  26. #include <X11/Xlib.h>    /* define Xlib types and calls */
  27. #include "buttons.h"
  28.  
  29. /* 16x16 (2 bytes * 16) bitmaps with default corner patterns of border */
  30. #include "borders.h"        /* static BorderPatterns defBorders */
  31. #include "motf.h"
  32.  
  33. static int motf_look = 0;    /* if set, buttons harmonize better w/ motif */
  34.  
  35. #if VMS && IMTOOL
  36. extern void XZ_ast();
  37. extern int  XZ_efn;
  38. #endif
  39.  
  40. static GC def_gc = NULL;
  41. /*
  42.  * Subroutine:    MakeButtonBox
  43.  * Purpose:    Do everything necessary to make a new buttonbox
  44.  * Returns:    ButtonBox handle for the new buttonbox
  45.  * Called by:    Application program
  46.  * Uses:    btn_Alloc() in BtnAlloc.c
  47.  * Uses:    btn_CreateWindows(), btn_LabelButtons() below
  48.  * Xlib calls:    XCreateSimpleWindow(), XMapSubwindows()
  49.  * Xlib calls:    DefaultScreen, DefaultGC, DefaultVisual, DefaultDepth
  50.  * Post-state:    No buttons are in on state and no submenus are attached
  51.  * Method:    Make a subwindow exactly covering parent window.  Fill it with
  52.  *        subwindows as buttons, create drawing stuff for each button
  53.  * Note:    Buttonboxes must later be combined into menus and panels
  54.  * Note:    Call TouchButton to activate buttons and submenus when ready
  55.  */
  56. ButtonBox MakeButtonBox ( parent, gc, visual, background, geo, defs, borders )
  57.      BoxParent *parent;        /* i: Parent window info */
  58.      GC gc;            /* i: graphics context for drawing labels */
  59.      Visual *visual;        /* i: visual for XCreateImage() */
  60.      unsigned long background;    /* i: window background pixel value */
  61.      BoxGeometry *geo;        /* i: button arrangement and count info */
  62.      ButtonSpec defs[];        /* i: Button descriptors */
  63.      BorderPatterns *borders;    /* i: optional non-default border look */
  64. {
  65.   ButtonBox buttonbox;        /* o: handle for buttonbox record */
  66.   unsigned int width, height;    /* l: dimensions of parent window */
  67.   Display *display;        /* l: X server */
  68.   int screen;            /* l: screen number for default stuff */
  69.   int btn_wdth, btn_hght;    /* l: dimensions of all buttons */
  70.   int x, y;            /* l: coordinates of box in parent */
  71.   int i;            /* l: loop counter */
  72.   char *btn_Alloc();
  73.   static void btn_CreateWindows();
  74.   void btn_LabelButtons(), btn_Dimensions();
  75.  
  76.   /* allocate the space for the new record */
  77.   buttonbox = (ButtonBox)
  78.     btn_Alloc(1, sizeof(struct _ButtonBox), "Buttonbox");
  79.   /* put server connection display and screen details in the record */
  80.   display = parent->display;
  81.   buttonbox->display = display;
  82.   buttonbox->parentID = parent->wndwID;
  83.   screen = DefaultScreen(display);
  84.   if( gc == NULL ) {
  85.     /* use default buttonlib gc (create if not yet in existence */
  86.     if( def_gc == NULL ) {
  87.       def_gc = XCreateGC(display, parent->wndwID, 0, NULL);
  88.       XSetState(display, def_gc, 1, 0, GXcopy, 1);
  89.     }
  90.     gc = def_gc;
  91.   }
  92.   if( visual != (Visual *)0 )
  93.     buttonbox->visual = visual;
  94.   else
  95.     buttonbox->visual = DefaultVisual(display, screen);
  96.   /* get the basic box and button dimensions */
  97.   btn_Dimensions(parent, geo, &btn_wdth, &btn_hght, &x, &y, &width, &height);
  98.   /* create a buttonbox subwindow (it gets no events) */
  99.   buttonbox->wndwID =
  100.     XCreateSimpleWindow(display, parent->wndwID, x, y, width, height,
  101.             (unsigned int)0, (unsigned long)0, background);
  102.   buttonbox->parent_width = parent->width;
  103.   buttonbox->parent_height = parent->height;
  104.   i = geo->box_rows * geo->box_cols;
  105.   /* check counts */
  106.   if( geo->btn_cnt > i ) {
  107.     (void)fprintf(stderr, "WARNING: More labels than buttons: %s %d\n",
  108.           defs[0].feel->title, geo->btn_cnt);
  109.   geo->btn_cnt = i;
  110.   }
  111.   buttonbox->geometry = geo;
  112.   buttonbox->btn_cnt = geo->btn_cnt;
  113.   /* create space for the button records */
  114.   buttonbox->buttons = (ButtonRecord *)
  115.        btn_Alloc(buttonbox->btn_cnt, sizeof(ButtonRecord), "Buttons");
  116.   /* create space for a list of window id's (last one is this window) */
  117.   buttonbox->window_list = (Window *)
  118.        btn_Alloc(buttonbox->btn_cnt + 1, sizeof(Window *), "Button list");
  119.   buttonbox->window_list[buttonbox->btn_cnt] = buttonbox->wndwID;
  120.   buttonbox->window_count = buttonbox->btn_cnt + 1;
  121.   /* set pointers for user specified (and default) look and feel */
  122.   if( borders != NULL )
  123.     buttonbox->borders = borders;
  124.   else {
  125.     if( motf_look )
  126.       buttonbox->borders = &motfBorders;
  127.     else
  128.       buttonbox->borders = &defBorders;
  129.   }
  130.   for( i = 0; i < buttonbox->btn_cnt; i++ ) {
  131.     buttonbox->buttons[i].look = defs[i].look;
  132.     buttonbox->buttons[i].feel = defs[i].feel;
  133.   }
  134.   /* initially no mouse buttons are down */
  135.   buttonbox->down_btn = -1;
  136.   buttonbox->down_mouse_btn = -1;
  137.   buttonbox->mode_btn = -1;
  138.   buttonbox->co_mode_btn = -1;
  139.   /* create button subwindows and fill associated records */
  140.   btn_CreateWindows (buttonbox, gc, btn_wdth, btn_hght);
  141.   /* create XImage bitmaps for button visuals */
  142.   btn_LabelButtons(buttonbox, btn_wdth, btn_hght,
  143.            geo->off_inverse, geo->on_inverse);
  144.   /* make the buttons mapped (but not yet the box itself) */
  145.   XMapSubwindows(display, buttonbox->wndwID);
  146.   return( buttonbox );
  147. }
  148.  
  149. /*
  150.  * Subroutine:    btn_Dimensions
  151.  * Purpose:    Set six dimensions used to create box and its buttons
  152.  * Returns:    void
  153.  * Called by:    MakeButtonbox() above, ResizeBox() in ResizeBox.c
  154.  * Xlib calls:    none
  155.  * Post-state:    6 integer params are set
  156.  * Method:    Dimensions of buttons are to fill window area with full
  157.  *        arrangement.  Adjustment is made to center within excess, if
  158.  *        any.  X and Y position the box'x subset arrangement and
  159.  *        width and height are the subset's dimensions.
  160.  */
  161. void btn_Dimensions ( parent, geo, btn_wdth, btn_hght, x, y, width, height )
  162.      BoxParent *parent;            /* i: Parent window info */
  163.      BoxGeometry *geo;            /* i: arrangement and count info */
  164.      int *btn_wdth, *btn_hght;        /* o: dimensions of each buttons */
  165.      int *x, *y;            /* o: coordinates of box in parent */
  166.      unsigned int *width, *height;    /* o: dimensions of box subwindow */
  167. {
  168.   int xx, yy;
  169.   *btn_wdth = (int)((double)(parent->xwdth) / geo->parent_cols);
  170.   *btn_hght = (int)((double)(parent->yhght) / geo->parent_rows);
  171.   *width = geo->box_cols * *btn_wdth;
  172.   *height = geo->box_rows * *btn_hght;
  173.   /* offset centers buttons when fit is not perfect */
  174.   /* parent x + box x + 1/2 box's slop */
  175.   xx = parent->x + (int)(geo->box_col_x * (double)(parent->xwdth)) +
  176.     (((int)((double)(parent->xwdth) *
  177.         ((double)(geo->box_cols) / geo->parent_cols)) + 1 -
  178.       *width) / 2);
  179.   yy = parent->y + (int)(geo->box_row_y * (double)(parent->yhght)) +
  180.     (((int)((double)(parent->yhght) *
  181.       ((double)(geo->box_rows) / geo->parent_rows)) -
  182.       *height) / 2);
  183.   if( xx < 0 )
  184.     *x = 0;
  185.   else
  186.     *x = xx;
  187.   if( yy < 0 )
  188.     *y = 0;
  189.   else
  190.     *y = yy;
  191. }
  192.  
  193. /*
  194.  * Subroutine:    btn_CreateWindows
  195.  * Purpose:    Create a subwindow for each button and set its events
  196.  * Returns:    void
  197.  * Called by:    MakeButtonBox() above
  198.  * Xlib calls:    XCreateSimpleWindow(), XSelectInput()
  199.  * Pre-state:    surrounding window created for perfect fit
  200.  * Post-state:    Buttonbox has window and display filled for all buttons,
  201.  *        and window_list is filled.
  202.  * Method:    All buttons are the same size, and arranged according to
  203.  *        ButtonBox rows and cols specifications.
  204.  * Note:    Each button is a borderless window.
  205.  */
  206. static void btn_CreateWindows( buttonbox, gc, btn_wdth, btn_hght )
  207.      ButtonBox buttonbox;    /* i: handle of buttonbox record */
  208.      GC gc;            /* i: graphics context for drawing labels */
  209.      int btn_wdth, btn_hght;    /* i: dimensions of each buttons */
  210. {
  211.   int x, y;
  212.   int j, i;
  213.   int btn;
  214.   unsigned long background;
  215.   Display *display;
  216.   Window wndwID;
  217.   BoxGeometry *geo;
  218.  
  219.   btn = 0;
  220.   display = buttonbox->display;
  221.   wndwID = buttonbox->wndwID;
  222.   background = buttonbox->background;
  223.   geo = buttonbox->geometry;
  224.   for( j = 0; j < geo->box_rows; j++ ) {
  225.     for( i = 0; i < geo->box_cols; i++ ) {
  226.       x = btn_wdth * i;
  227.       y = btn_hght * j;
  228.       buttonbox->buttons[btn].display = display;
  229.       buttonbox->buttons[btn].gc = gc;
  230.       buttonbox->buttons[btn].wndwID =
  231.     XCreateSimpleWindow (display, wndwID, x, y, btn_wdth, btn_hght,
  232.                  (unsigned int)0, (unsigned long)0, background);
  233.       if( (buttonbox->buttons[btn].feel->nfunctions >0) &&
  234.       (buttonbox->buttons[btn].feel->function[0] != BTNNoOp) ) {
  235. #if VMS && IMTOOL
  236.     XSelectAsyncInput(display, buttonbox->buttons[btn].wndwID,
  237.               ButtonReleaseMask | ButtonPressMask |
  238.               EnterWindowMask | LeaveWindowMask | ExposureMask,
  239.               XZ_ast, XZ_efn);
  240. #endif
  241.     XSelectInput(display, buttonbox->buttons[btn].wndwID,
  242.              ButtonReleaseMask | ButtonPressMask |
  243.              EnterWindowMask | LeaveWindowMask | ExposureMask);
  244.       /* no_op buttons have no events, but are mapped */
  245.       } else {
  246. #if VMS && IMTOOL
  247.     XSelectAsyncInput(display, buttonbox->buttons[btn].wndwID,
  248.               ExposureMask | ButtonPressMask | ButtonReleaseMask,
  249.               XZ_ast, XZ_efn);
  250. #endif
  251.     XSelectInput(display, buttonbox->buttons[btn].wndwID,
  252.              ExposureMask | ButtonPressMask | ButtonReleaseMask);
  253.       }
  254.       /* put the window id in the buttonbox's check event list */
  255.       buttonbox->window_list[btn] = buttonbox->buttons[btn].wndwID;
  256.       if( ++btn >= buttonbox->btn_cnt )
  257.     return;
  258.     }
  259.   }
  260. }
  261.  
  262. /*
  263.  * Subroutine:    btn_LabelButtons
  264.  * Purpose:    Create XImages for all states of all buttons.
  265.  * Returns:    void
  266.  * Called by:    MakeButtonBox() above, ResizeBox() in ResizeBox.c
  267.  * Uses:    btn_Alloc() in BtnAlloc.c
  268.  * Uses:    btn_MakeBtdBitmap() in MakeBtnBdr.c
  269.  * Uses:    btn_MakeXImages() in MakeXImage.c
  270.  * Xlib calls:    none
  271.  * Post-state:    box record has XImages filled for all buttons
  272.  * Method:    Creates basic pattern for button minus label which is used as
  273.  *        the starting point for adding labels to make each button.
  274.  */
  275. void btn_LabelButtons ( buttonbox, btn_wdth, btn_hght, off, on )
  276.      ButtonBox buttonbox;    /* i: structure for boxed group of buttons */
  277.      int btn_wdth, btn_hght;    /* i: dimensions of each button */
  278.      int off, on;        /* i: flag set if off or on has invert bits */
  279. {
  280.   int byte_width;        /* l: width in bytes of the button bitmap */
  281.   int mapsz;            /* l: size of button bitmap in bytes */
  282.   int btn_cnt;            /* l: number of buttons specificied */
  283.   int i;            /* l: loop counter */
  284.   Visual *visual;        /* l: visual for XCreateImage() */
  285.   unsigned char *off_out;    /* l: filled bitmap with only border pattern */
  286.   unsigned char *off_in;    /* l: filled bitmap with only border pattern */
  287.   unsigned char *on_out;    /* l: filled bitmap with only border pattern */
  288.   unsigned char *on_in;        /* l: filled bitmap with only border pattern */
  289.   char *btn_Alloc();
  290.   void btn_MakeBdrBitmap(), btn_MakeXImages();
  291.  
  292.   /* calculate number of bytes in one line and in whole bitmap */
  293.   byte_width = (btn_wdth + 7) / 8;
  294.   mapsz = btn_hght * byte_width;
  295.   /* allocate space for patterns (initially empty) */
  296.   off_out = (unsigned char *)btn_Alloc(mapsz, sizeof(char), "button border");
  297.   off_in = (unsigned char *)btn_Alloc(mapsz, sizeof(char), "button border");
  298.   on_out = (unsigned char *)btn_Alloc(mapsz, sizeof(char), "button border");
  299.   on_in = (unsigned char *)btn_Alloc(mapsz, sizeof(char), "button border");
  300.   /* if border patterns were given, fill the border in */
  301.   if( buttonbox->borders != NULL ) {
  302.     btn_MakeBdrBitmap(off_out, btn_wdth, btn_hght, byte_width,
  303.               buttonbox->borders->off_out, off);
  304.     btn_MakeBdrBitmap(off_in, btn_wdth, btn_hght, byte_width,
  305.               buttonbox->borders->off_in, off);
  306.     btn_MakeBdrBitmap(on_out, btn_wdth, btn_hght, byte_width,
  307.               buttonbox->borders->on_out, on);
  308.     btn_MakeBdrBitmap(on_in, btn_wdth, btn_hght, byte_width,
  309.               buttonbox->borders->on_in, on);
  310.   }
  311.   visual = buttonbox->visual;
  312.   btn_cnt = buttonbox->btn_cnt;
  313.   for( i = 0; i < btn_cnt; i++ ) {
  314.     btn_MakeXImages(&(buttonbox->buttons[i]), btn_wdth, btn_hght, byte_width,
  315.             visual, off_out, off_in, on_out, on_in, mapsz,
  316.             off, on, motf_look);
  317.   }
  318.   /* free the patterns */
  319.   free((char *)off_out);
  320.   free((char *)off_in);
  321.   free((char *)on_out);
  322.   free((char *)on_in);
  323. }
  324.               
  325. /*
  326.  * Subroutine:    SetTAEButtonLook
  327.  * Purpose:    set flag prior to execution of any code to make buttons
  328.  *        look more like TAE (or monochrome motif) buttons
  329.  */
  330. void SetTAEButtonLook ( status )
  331.      int status;
  332. {
  333.   motf_look = status;
  334. }
  335.