[comp.sources.x] v09i074: XtWrap -- R4 Xt-style varargs interface for R3 intrinsics, Part01/01

news@sun.Eng.Sun.COM (news) (10/08/90)

Submitted-by: ora!zipcode!argv (Dan Heller)
Posting-number: Volume 9, Issue 74
Archive-name: xtwrap/part01

The following shar contains XtWrap.c which should be compiled into
XtWrap.o and added to your default X11R3 Xt.a or whichever library
you want.  The functions included provide some of the X11R4 Xt varargs
functionality for those of you still using X11R3 intrinsics (probably
because you're using Motif 1.0).  This is going to extremely facilitate
your migration from Motif 1.0 to Motif 1.1 (in fact, all my programs
now compile for either one with the help of some #defines).

Not everything is supported -- just the most commonly used functions
(see the readme, which is included first here below).

Note: this code is based on my older WidgetWrap library that did
just about the same thing -- the major difference here is that
the routines have been modified to fit the new Xt-R4 API.

ps-- this is a hack; I'm sure the appropriate files from Xt-R4 can
be extracted and put into the R3 intrinsics if you really wanted
to do it right.

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then feed it
# into a shell via "sh file" or similar.  To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix@uunet.uu.net if you want that tool.
# If this archive is complete, you will see the following message at the end:
#		"End of shell archive."
# Contents:  README XtWrap.c XtWrap.h
# Wrapped by argv@zipcode on Sat Oct  6 21:28:41 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(2888 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XThis module was written by Dan Heller (Oct 6, 1990):
X<argv@sun.com>, <argv@uunet.uu.net>, <argv@zipcode.com>,
X<argv@ora.ora.com>, <argv@monet.berkeley.edu>
X
XXtWrap.c makes some of the varargs style Xt routines available to R3
X   intrinsics.  This is mostly used for Motif 1.0  This is package is
X   based on WidgetWrap also written by Dan Heller.
X
XWidgetWrap.c -- variable argument style programmer interfaces to widgets:
X
X   XtVaCreateManagedWidget(name, class, parent, varargs...);
X   XtVaCreateWidget(name, class, parent, varargs...);
X   XtVaCreatePopupShell(name, class, parent, varargs...);
X   XtVaSetValues(name, varargs);
X   XtVaGetValues(name, varargs);
X   GenericWidgetName(buf);
X
XThe purpose of this module is to allow the programmer to Create
Xwidgets and set/get widget attributes via a variable argument list
Xstyle of function call.  This eliminates the need for many local
Xvariables and bothersome XtSetArg() calls and so forth.  An example
Xof usage:
X
X   Widget foo;
X
X   foo = XtVaCreateManagedWidget("foo", labelWidgetClass, toplevel,
X	XtNlabel,	"Widget",
X	XtNforeground,	WhitePixelOfScreen(XtScreen(toplevel)),
X	XtNbackground,	BlackPixelOfScreen(XtScreen(toplevel)),
X        XtNborderWidth,	1,
X        NULL);
X
XAs you can see, the list must be NULL terminated.  You may pass up to
Xto MAXARGS argument pairs.  Increase this number in WidgetWrap.h if
Xnecessary.  There are special args availabel to the create/get/set
Xfunctions that are available:
X
X   XtNargList		takes _two_ parameters.
X
XThe XtNargList makes it possible to pass attributes to the create/get/set
Xcalls that are probably common to many widgets to be created or reset.
X
Xstatic Arg args[] = {
X    XtNforeground,	black,
X    XtNbackground,   white,
X    XtNwidth,	20,
X    XtNheight,	10,
X};
Xfoo = XtVaCreateManagedWidget("bar", widgetClass, toplevel,
X    XtNargList,	args, XtNumber(args),
X    NULL);
X
XMost large applications will create huge numbers of widgets that the
Xprogrammer has to think up unique names for.  What's more, as noted by
Xthe examples above, the names are constant strings which takes up memory.
XSo, if these routines get a NULL as the name of the widget, then a
Xwidget name is automatically generated.
X
XFinally, a note about varargs.  Note that there are many different
Ximplementations of varargs.  To maintain portability, it is important
Xto never return from a function that uses varargs without calling va_end().
Xva_start() and va_end() should always exist in the same block of {}'s.
XThere can be blocks between them, but va_end() shouldn't be in a block
Xinside of the va_start() stuff.  This is to allow support for weird
Ximplementations which define va_start() to something like:  ".... { "
X(pyramid computers for one).
X
XAlso, if you use varargs, never declare "known" arguments; extract them
Xfrom the vararg list later.  This is a bug in the R4 intrinsics that
Xshould eventually be fixed.
X
END_OF_FILE
if test 2888 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'XtWrap.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'XtWrap.c'\"
else
echo shar: Extracting \"'XtWrap.c'\" \(8661 characters\)
sed "s/^X//" >'XtWrap.c' <<'END_OF_FILE'
X/*
X * This module was written by Dan Heller (Oct 6, 1990):
X *	<argv@sun.com>, <argv@uunet.uu.net>, <argv@zipcode.com>,
X *	<argv@ora.ora.com>, <argv@monet.berkeley.edu>
X *
X * XtWrap.c makes some of the varargs style Xt routines available to R3
X *    intrinsics.  This is mostly used for Motif 1.0  This is package is
X *    based on WidgetWrap also written by Dan Heller.
X *
X * WidgetWrap.c -- variable argument style programmer interfaces to widgets:
X *    XtVaCreateManagedWidget(name, class, parent, varargs...);
X *    XtVaCreateWidget(name, class, parent, varargs...);
X *    XtVaCreatePopupShell(name, class, parent, varargs...);
X *    XtVaSetValues(name, varargs);
X *    XtVaGetValues(name, varargs);
X *    GenericWidgetName(buf);
X *
X * The purpose of this module is to allow the programmer to Create
X * widgets and set/get widget attributes via a variable argument list
X * style of function call.  This eliminates the need for many local
X * variables and bothersome XtSetArg() calls and so forth.  An example
X * of usage:
X *
X *    Widget foo;
X *
X *    foo = XtVaCreateManagedWidget("foo", labelWidgetClass, toplevel,
X *        XtNlabel,		"Widget",
X *	  XtNforeground,	WhitePixelOfScreen(XtScreen(toplevel)),
X *	  XtNbackground,	BlackPixelOfScreen(XtScreen(toplevel)),
X *        XtNborderWidth,	1,
X *        NULL);
X *
X * As you can see, the list must be NULL terminated.  You may pass up to
X * to MAXARGS argument pairs.  Increase this number in WidgetWrap.h if
X * necessary.  There are special args availabel to the create/get/set
X * functions that are available:
X *
X *    XtNargList		takes _two_ parameters.
X *
X * The XtNargList makes it possible to pass attributes to the create/get/set
X * calls that are probably common to many widgets to be created or reset.
X *
X * static Arg args[] = {
X *     XtNforeground,	black,
X *     XtNbackground,   white,
X *     XtNwidth,	20,
X *     XtNheight,	10,
X * };
X * foo = XtVaCreateManagedWidget("bar", widgetClass, toplevel,
X *     XtNargList,	args, XtNumber(args),
X *     NULL);
X *
X * Most large applications will create huge numbers of widgets that the
X * programmer has to think up unique names for.  What's more, as noted by
X * the examples above, the names are constant strings which takes up memory.
X * So, if these routines get a NULL as the name of the widget, then a
X * widget name is automatically generated.
X *
X * Finally, a note about varargs.  Note that there are many different
X * implementations of varargs.  To maintain portability, it is important
X * to never return from a function that uses varargs without calling va_end().
X * va_start() and va_end() should always exist in the same block of {}'s.
X * There can be blocks between them, but va_end() shouldn't be in a block
X * inside of the va_start() stuff.  This is to allow support for weird
X * implementations which define va_start() to something like:  ".... { "
X * (pyramid computers for one).
X *
X * Also, if you use varargs, never declare "known" arguments; extract them
X * from the vararg list later.  This is a bug in the R4 intrinsics that
X * should eventually be fixed.
X */
X#include <stdio.h>
X#include <X11/Intrinsic.h>
X#include <varargs.h>
X#include "XtWrap.h"
X
Xchar *
XGenericWidgetName(buf)
Xchar *buf;
X{
X    static int widget_count;
X
X    (void) sprintf(buf, "_widget.%d", widget_count++);
X    return buf;
X}
X
X/*
X * XtVaCreateWidget()
X *	Create a widget passing it's instance attributes and other parameters
X * as variable arguments.  This removes the need to build your own Arg[]
X * lists, etc...  Terminate argument list pairs with a NULL argument.
X */
X/* VARARGS */
XWidget
XXtVaCreateWidget(va_alist)
Xva_dcl
X{
X    va_list	var;
X    Arg		args[MAXARGS];
X    int		err = 0, nargs, i = 0;
X    String	argstr;
X    XtArgVal	argval;
X    char	*name, buf[32];
X    WidgetClass class;
X    Widget	parent;
X
X    va_start(var);
X
X    if (!(name = va_arg(var, char *)))
X	name = GenericWidgetName(buf);
X    class = va_arg(var, WidgetClass);
X    parent = va_arg(var, Widget);
X
X    while (argstr = va_arg(var, char *)) {
X	if (i == MAXARGS) {
X	    err++;
X	    break;
X	}
X	if (!strcmp(argstr, XtNargList)) {
X	    ArgList list = va_arg(var, ArgList);
X	    int numargs = va_arg(var, int);
X	    for (numargs--; i < MAXARGS && numargs >= 0; i++, numargs--)
X		XtSetArg(args[i], list[numargs].name, list[numargs].value);
X	    if (i == MAXARGS) {
X		err++;
X		break;
X	    }
X	} else {
X	    argval = va_arg(var, XtArgVal);
X	    XtSetArg(args[i], argstr, argval);
X	    ++i;
X	}
X    }
X    va_end(var);
X
X    if (err) {
X	char err[128];
X	sprintf(err, "%s: too many arguments: %d", name, i);
X	XtError(err); /* XtError *could* return */
X	return NULL;
X    }
X
X    return XtCreateWidget(name, class, parent, args, i);
X}
X
X/*
X * XtVaCreateManagedWidget()
X *	Create a widget passing it's instance attributes and other parameters
X * as variable arguments.  This removes the need to build your own Arg[]
X * lists, etc...  Terminate argument list pairs with a NULL argument.
X */
X/* VARARGS */
XWidget
XXtVaCreateManagedWidget(va_alist)
Xva_dcl
X{
X    va_list	var;
X    Arg		args[MAXARGS];
X    int		err = 0, nargs, i = 0;
X    String	argstr;
X    XtArgVal	argval;
X    char	*name, buf[32];
X    WidgetClass class;
X    Widget	parent, (*create_func)() = NULL;
X
X    va_start(var);
X
X    if (!(name = va_arg(var, char *)))
X	name = GenericWidgetName(buf);
X    class = va_arg(var, WidgetClass);
X    parent = va_arg(var, Widget);
X
X    while (argstr = va_arg(var, char *)) {
X	if (i == MAXARGS) {
X	    err++;
X	    break;
X	}
X	if (!strcmp(argstr, XtNargList)) {
X	    ArgList list = va_arg(var, ArgList);
X	    int numargs = va_arg(var, int);
X	    for (numargs--; i < MAXARGS && numargs >= 0; i++, numargs--)
X		XtSetArg(args[i], list[numargs].name, list[numargs].value);
X	    if (i == MAXARGS) {
X		err++;
X		break;
X	    }
X	} else {
X	    argval = va_arg(var, XtArgVal);
X	    XtSetArg(args[i], argstr, argval);
X	    ++i;
X	}
X    }
X    va_end(var);
X
X    if (err) {
X	char err[128];
X	sprintf(err, "%s: too many arguments: %d", name, i);
X	XtError(err); /* XtError *could* return */
X	return NULL;
X    }
X
X    return XtCreateManagedWidget(name, class, parent, args, i);
X}
X
XWidget
XXtVaCreatePopupShell(va_alist)
Xva_dcl
X{
X    va_list	var;
X    Arg		args[MAXARGS];
X    int		err = 0, nargs, i = 0;
X    String	argstr;
X    XtArgVal	argval;
X    char	*name, buf[32];
X    WidgetClass class;
X    Widget	parent;
X
X    va_start(var);
X
X    if (!(name = va_arg(var, char *)))
X	name = GenericWidgetName(buf);
X    class = va_arg(var, WidgetClass);
X    parent = va_arg(var, Widget);
X
X    while (argstr = va_arg(var, char *)) {
X	if (i == MAXARGS) {
X	    err++;
X	    break;
X	}
X	if (!strcmp(argstr, XtNargList)) {
X	    ArgList list = va_arg(var, ArgList);
X	    int numargs = va_arg(var, int);
X	    for (numargs--; i < MAXARGS && numargs >= 0; i++, numargs--)
X		XtSetArg(args[i], list[numargs].name, list[numargs].value);
X	    if (i == MAXARGS) {
X		err++;
X		break;
X	    }
X	} else {
X	    argval = va_arg(var, XtArgVal);
X	    XtSetArg(args[i], argstr, argval);
X	    ++i;
X	}
X    }
X    va_end(var);
X
X    if (err) {
X	char err[128];
X	sprintf(err, "%s: too many arguments: %d", name, i);
X	XtError(err); /* XtError *could* return */
X	return NULL;
X    }
X
X    return XtCreatePopupShell(name, class, parent, args, i);
X}
X
X/*VARARGS*/
Xvoid
XXtVaSetValues(va_alist)
Xva_dcl
X{
X    String   argstr;
X    Arg      args[MAXARGS];
X    XtArgVal argval;
X    int      i = 0;
X    va_list  var;
X    Widget   w;
X
X    va_start(var);
X
X    w = va_arg(var, Widget);
X
X    while (argstr = va_arg(var, char *)) {
X	if (i == MAXARGS) {
X	    fprintf(stderr, "Warning: increase MAXARGS! (%d)\n", i);
X	    XtSetValues(w, args, i);
X	    i = 0;
X	}
X	if (!strcmp(argstr, XtNargList)) {
X	    ArgList list = va_arg(var, ArgList);
X	    XtArgVal numargs = va_arg(var, Cardinal);
X	    XtSetValues(w, list, numargs);
X	} else {
X	    argval = va_arg(var, XtArgVal);
X	    XtSetArg(args[i], argstr, argval);
X	    ++i;
X	}
X    }
X    va_end(var);
X    if (i > 0)
X	XtSetValues(w, args, i);
X}
X
X/*VARARGS*/
Xvoid
XXtVaGetValues(va_alist)
Xva_dcl
X{
X    String   argstr;
X    Arg      args[MAXARGS];
X    XtArgVal argval;
X    int      i = 0;
X    va_list  var;
X    Widget   w;
X
X    va_start(var);
X
X    w = va_arg(var, Widget);
X
X    while (argstr = va_arg(var, char *)) {
X	argval = va_arg(var, XtArgVal);
X	if (i == MAXARGS) {
X	    fprintf(stderr, "Warning: increase MAXARGS! (%d)\n", i);
X	    XtGetValues(w, args, i);
X	    i = 0;
X	}
X	if (!strcmp(argstr, XtNargList)) {
X	    ArgList list = va_arg(var, ArgList);
X	    XtArgVal numargs = va_arg(var, Cardinal);
X	    XtGetValues(w, list, numargs);
X	} else
X	    XtSetArg(args[i], argstr, argval);
X        ++i;
X    }
X    va_end(var);
X    if (i > 0)
X	XtGetValues(w, args, i);
X}
END_OF_FILE
if test 8661 -ne `wc -c <'XtWrap.c'`; then
    echo shar: \"'XtWrap.c'\" unpacked with wrong size!
fi
# end of 'XtWrap.c'
fi
if test -f 'XtWrap.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'XtWrap.h'\"
else
echo shar: Extracting \"'XtWrap.h'\" \(521 characters\)
sed "s/^X//" >'XtWrap.h' <<'END_OF_FILE'
X/*
X * This module was written by Dan Heller (Oct 6, 1990):
X *	<argv@sun.com>, <argv@uunet.uu.net>, <argv@zipcode.com>,
X *	<argv@ora.ora.com>, <argv@monet.berkeley.edu>
X *
X * XtWrap.h -- header file for the XtWrap.c file.  This file should
X * be included by files that will link with that routine.
X */
X
X#define MAXARGS		50
X#define XtNargList	"Arglist"
X
Xextern char *GenericWidgetName();
Xextern void XtVaSetValues(), XtVaSetValues();
Xextern Widget
X    XtVaCreateManagedWidget(), XtVaCreateWidget(), XtVaCreatePopupShell();
END_OF_FILE
if test 521 -ne `wc -c <'XtWrap.h'`; then
    echo shar: \"'XtWrap.h'\" unpacked with wrong size!
fi
# end of 'XtWrap.h'
fi
echo shar: End of shell archive.
exit 0

dan
----------------------------------------------------
O'Reilly && Associates   argv@sun.com / argv@ora.com
Opinions expressed reflect those of the author only.