home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume3 / WidgetWrap / part01 / WidgetWrap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-04-21  |  6.8 KB  |  241 lines

  1. /*
  2.  * WidgetWrap.c -- variable argument style programmer interfaces to widgets:
  3.  *    WidgetCreate(name, class, parent, varargs...);
  4.  *    WidgetSet(name, varargs);
  5.  *    WidgetGet(name, varargs);
  6.  *    GenericWidgetName(buf);
  7.  *
  8.  * This module was written by Dan Heller <island!argv@sun.com> or
  9.  * <dheller@ucbcory.berkeley.edu>.
  10.  *
  11.  * The purpose of this module is to allow the programmer to Create
  12.  * widgets and set/get widget attributes via a variable argument list
  13.  * style of function call.  This eliminates the need for many local
  14.  * variables and bothersome XtSetArg() calls and so forth.  An example
  15.  * of usage:
  16.  *
  17.  *    Widget foo;
  18.  *
  19.  *    foo = WidgetCreate("foo", labelWidgetClass, toplevel,
  20.  *        XtNlabel,        "Widget",
  21.  *      XtNforeground,    WhitePixelOfScreen(XtScreen(toplevel)),
  22.  *      XtNbackground,    BlackPixelOfScreen(XtScreen(toplevel)),
  23.  *        XtNborderWidth,    1,
  24.  *        NULL);
  25.  *
  26.  * As you can see, the list must be NULL terminated.  You may pass up to
  27.  * to MAXARGS argument pairs.  Increase this number in WidgetWrap.h if
  28.  * necessary.  There are special args availabel to the create/get/set
  29.  * functions that are available:
  30.  *
  31.  *    XtNmanaged        pass "False" to create a non-managed widget.
  32.  *    XtNargList        takes _two_ parameters.
  33.  *    XtNpopupShell        pass "True" to create a PopupShellWidget.
  34.  *    XtNapplicShell        pass "True" to create an applicationShellWidget
  35.  *
  36.  * The XtNargList makes it possible to pass attributes to the create/get/set
  37.  * calls that are probably common to many widgets to be created or reset.
  38.  *
  39.  * static Arg args[] = {
  40.  *     XtNforeground,    black,
  41.  *     XtNbackground,   white,
  42.  *     XtNwidth,    20,
  43.  *     XtNheight,    10,
  44.  * };
  45.  * foo = WidgetCreate("bar", widgetClass, toplevel,
  46.  *     XtNargList,    args, XtNumber(args),
  47.  *     NULL);
  48.  *
  49.  * Most large applciations will create huge numbers of widgets which the
  50.  * programmer has to think up unique names for all of them.  What's more,
  51.  * typically, as noted by the examples above, the names are constant strings
  52.  * which takes up memory, disk spaces, etc...  So, if WidgetCreate() gets
  53.  * NULL as the name of the widget, then a widget name will be created
  54.  * automatically.  Since most of the time, user's don't care what the name
  55.  * of a widget is, this capability is available.
  56.  *
  57.  * Finally, a note about varargs.  Note that there are many different
  58.  * implementations of varargs.  To maintain portability, it is important
  59.  * to never return from a function that uses varargs without calling va_end().
  60.  * va_start() and va_end() should always exist in the same block of {}'s.
  61.  * There can be blocks between them, but va_end() shouldn't be in a block
  62.  * inside of the va_start() stuff.  This is to allow support for weird
  63.  * implementations which define va_start() to something like:  ".... { "
  64.  * (pyramid computers for one).
  65.  * Also, if you use varargs, never declare "known" arguments; extract them
  66.  * from the vararg list later.
  67.  */
  68. #include <stdio.h>
  69. #include <X11/Intrinsic.h>
  70. #include <varargs.h>
  71. #include "WidgetWrap.h"
  72.  
  73. char *
  74. GenericWidgetName(buf)
  75. char *buf;
  76. {
  77.     static int widget_count;
  78.  
  79.     (void) sprintf(buf, "_widget.%d", widget_count++);
  80.     return buf;
  81. }
  82.  
  83. /*
  84.  * WidgetCreate()
  85.  *    Create a widget passing it's instance attributes and other parameters
  86.  * as variable arguments.  This removes the need to build your own Arg[]
  87.  * lists, etc...  Terminate argument list pairs with a NULL argument.
  88.  */
  89. /* VARARGS */
  90. Widget
  91. WidgetCreate(va_alist)
  92. va_dcl
  93. {
  94.     va_list    var;
  95.     Arg        args[MAXARGS];
  96.     int        err = 0, nargs, i = 0, managed = 1;
  97.     String    argstr;
  98.     XtArgVal    argval;
  99.     char    *name, buf[32];
  100.     WidgetClass class;
  101.     Widget    parent, (*create_func)() = NULL;
  102.  
  103.     va_start(var);
  104.  
  105.     if (!(name = va_arg(var, char *)))
  106.     name = GenericWidgetName(buf);
  107.     class = va_arg(var, WidgetClass);
  108.     parent = va_arg(var, Widget);
  109.  
  110.     while (argstr = va_arg(var, char *)) {
  111.     if (i == MAXARGS) {
  112.         fprintf(stderr, "WidgetCreate: too many arguments: %d\n", i);
  113.         err++;
  114.         break;
  115.     }
  116.     if (!strcmp(argstr, XtNargList)) {
  117.         ArgList list = va_arg(var, ArgList);
  118.         int numargs = va_arg(var, int);
  119.         for (numargs--; i < MAXARGS && numargs >= 0; i++, numargs--)
  120.         XtSetArg(args[i], list[numargs].name, list[numargs].value);
  121.         if (i == MAXARGS) {
  122.         fprintf(stderr, "WidgetCreate: too many arguments: %d\n", i);
  123.         err++;
  124.         break;
  125.         }
  126.     } else if (!strcmp(argstr, XtNmanaged))
  127.         managed = va_arg(var, int);
  128.     else if (!strcmp(argstr, XtNpopupShell)) {
  129.         if (va_arg(var, int))
  130.         create_func = XtCreatePopupShell;
  131.     } else if (!strcmp(argstr, XtNapplicShell)) {
  132.         if (va_arg(var, int))
  133.         create_func = XtCreateApplicationShell;
  134.     } else {
  135.         argval = va_arg(var, XtArgVal);
  136.         XtSetArg(args[i], argstr, argval);
  137.         ++i;
  138.     }
  139.     }
  140.     va_end(var);
  141.  
  142.     if (err)
  143.     return NULL;
  144.  
  145.     if (create_func == XtCreateApplicationShell)
  146.     return XtCreateApplicationShell(name, class, args, i);
  147.  
  148.     if (!create_func)
  149.     create_func = managed? XtCreateManagedWidget : XtCreateWidget;
  150.     return (create_func)(name, class, parent, args, i);
  151. }
  152.  
  153. /*
  154.  * WidgetSet()
  155.  *    Once a widget has been created, you may use this routine to
  156.  * add or change a varaible number of attributes on it.
  157.  */
  158. /*VARARGS*/
  159. void
  160. WidgetSet(va_alist)
  161. va_dcl
  162. {
  163.     String   argstr;
  164.     Arg      args[MAXARGS];
  165.     XtArgVal argval;
  166.     int      i = 0, managed = -1;
  167.     va_list  var;
  168.     Widget   w;
  169.  
  170.     va_start(var);
  171.  
  172.     w = va_arg(var, Widget);
  173.  
  174.     while (argstr = va_arg(var, char *)) {
  175.     if (i == MAXARGS) {
  176.         fprintf(stderr, "Warning: increase MAXARGS! (%d)\n", i);
  177.         XtSetValues(w, args, i);
  178.         i = 0;
  179.     }
  180.     if (!strcmp(argstr, XtNmanaged))
  181.         managed = va_arg(var, int);
  182.     else if (!strcmp(argstr, XtNargList)) {
  183.         ArgList list = va_arg(var, ArgList);
  184.         XtArgVal numargs = va_arg(var, Cardinal);
  185.         XtSetValues(w, list, numargs);
  186.     } else {
  187.         argval = va_arg(var, XtArgVal);
  188.         XtSetArg(args[i], argstr, argval);
  189.         ++i;
  190.     }
  191.     }
  192.     va_end(var);
  193.     if (i > 0)
  194.     XtSetValues(w, args, i);
  195.     if (managed > -1)
  196.     if (managed == True)
  197.         XtManageChild(w);
  198.     else
  199.         XtUnmanageChild(w);
  200. }
  201.  
  202. /*
  203.  * WidgetGet()
  204.  *     Get the values of a widget via an interface identical to WidgetSet
  205.  */
  206. /*VARARGS*/
  207. void
  208. WidgetGet(va_alist)
  209. va_dcl
  210. {
  211.     String   argstr;
  212.     Arg      args[MAXARGS];
  213.     XtArgVal argval;
  214.     int      i = 0;
  215.     va_list  var;
  216.     Widget   w;
  217.  
  218.     va_start(var);
  219.  
  220.     w = va_arg(var, Widget);
  221.  
  222.     while (argstr = va_arg(var, char *)) {
  223.     argval = va_arg(var, XtArgVal);
  224.     if (i == MAXARGS) {
  225.         fprintf(stderr, "Warning: increase MAXARGS! (%d)\n", i);
  226.         XtGetValues(w, args, i);
  227.         i = 0;
  228.     }
  229.     if (!strcmp(argstr, XtNargList)) {
  230.         ArgList list = va_arg(var, ArgList);
  231.         XtArgVal numargs = va_arg(var, Cardinal);
  232.         XtGetValues(w, list, numargs);
  233.     } else
  234.         XtSetArg(args[i], argstr, argval);
  235.         ++i;
  236.     }
  237.     va_end(var);
  238.     if (i > 0)
  239.     XtGetValues(w, args, i);
  240. }
  241.