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.