From: bruce@ais.com (Bruce C. Wright)
Newsgroups: gnu.gcc.help,comp.os.vms
Subject: Using GCC on VMS DECwindows/Motif
Date: 27 Jan 93 13:24:30 GMT
Organization: Applied Information Systems, Chapel Hill, NC

Has anyone successfully used Gnu CC under VMS to link to the DECwindows
Motif libraries?  The version I have (1.40) can't deal with the Motif
header files that DEC ships, because they use things like externalref
that are available in DEC's VAX C compiler but not in gcc.  So far
none of the obvious workarounds have worked (adding a line to the
source file like `#define externalref extern' will compile and build
but when it runs it gets the wrong values for some of the Motif constants
and fails -- apparently gcc's semantics for extern don't match VAX C's
semantics for externalref).  Some X11 .h files don't have the problem --
it's particularly (exclusively?) the Motif *.h files.  I can build
lots of things that don't use Motif but so far have had trouble getting
gcc to deal with the Motif widget class constants and similar things.

I'm sure I can solve this by building my own copy of X using gcc,
and possibly by editing _all_ of the X11 .h files to use more standard
C syntax :-(  but I'd rather not if there's a better (easier) way.
Below is a simple program to demonstrate the problem.  It needs to be
compiled and linked with:

	$ gcc /nocase test
	$ link test,xwin/opt

xwin.opt:
	sys$share:vaxcrtl	/share
	sys$share:decw$xlibshr	/share
	sys$share:decw$xmlibshr	/share

The error I get is:

	X Toolkit Error: XtCreateWidget requires non-NULL widget class

on the call to XtCreateManagedWidget.  I'd like to find a solution that
doesn't require making changes to DECwindows (like recompiling the X
libraries from the MIT distribution), making extensive editing changes
to the source files (I have lots of them, adding a short #ifdef at the
top of each is OK but lots of editing to the bodies of the files will be
a lot of trouble), or use VAX C (the machine this is for doesn't have a
license for it).

Thanks,

Bruce C. Wright

------------------------- cut here ---------------------------
/*
 * test1.c
 *
 *	A minimalist X program.
 */

#ifdef __GNUC__
/* #include <sys/types.h> */
#define externalref extern
#define NO_X_GBLS
#endif

#include <X11/StringDefs.h>
#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#include <X11/Xutil.h>
#include <Xm/Xm.h>
#include <Xm/DrawingA.h>

#define	START_CIRCLE	0
#define	FULL_CIRCLE	(64*360)

void resize ();
void redisplay ();

typedef struct	{
	int		depth, ncolors;
	GC		gc;
	Dimension 	width, height;
} image_data, *image_data_ptr;

unsigned long	iRedPixel;
unsigned long	iBluePixel;
unsigned long	iGreenPixel;
unsigned long	iYellowPixel;
unsigned long	iWhitePixel;
unsigned long	iBlackPixel;
unsigned long	iCyanPixel;
unsigned long	iMagentaPixel;

main (argc, argv)
	int	argc;
	char	*argv [];
{
	Widget		toplevel, canvas;
	image_data	data;

	toplevel = XtInitialize (argv [0], "Test", NULL, 0,
				&argc, argv);
	/*
	 */
/*	XtGetApplicationResources (toplevel, &data, resources,
				XtNumber (resources), NULL, 0);
	/*
	 * Create the widget to display.
	 */
	canvas = XtCreateManagedWidget ("canvas",
					xmDrawingAreaWidgetClass,
					toplevel, NULL, 0);
	printf ("Widget created\n");
	init_data (canvas, &data);
	printf ("Data initialized\n");
 	XtAddCallback (canvas, XmNexposeCallback, redisplay, &data);
	XtAddCallback (canvas, XmNresizeCallback, resize, &data);

	XtRealizeWidget (toplevel);
	printf ("Widget realized\n");

	iRedPixel = get_pixel (canvas, "red");
	iGreenPixel = get_pixel (canvas, "green");
	iBluePixel = get_pixel (canvas, "blue");
	iYellowPixel = get_pixel (canvas, "yellow");
	iWhitePixel = get_pixel (canvas, "white");
	iBlackPixel = get_pixel (canvas, "black");
	iCyanPixel = get_pixel (canvas, "cyan");
	iMagentaPixel = get_pixel (canvas, "magenta");

	printf ("get_pixel called\n");

	resize (canvas, &data, NULL);

	printf ("resize called\n");

	XtMainLoop ();

}

init_data (w, data)
	Widget		w;
	image_data	*data;
{
	Arg	wargs [2];

	/*
	 * Get the size of the drawing area.
	 */
	XtSetArg (wargs [0], XtNwidth,	&data->width);
	XtSetArg (wargs [1], XtNheight, &data->height);
	XtGetValues (w, wargs, 2);

	/*
	 * Find out how many colors we have to work with, and create
	 * a default, writeable, graphics context.
	 */
	data->ncolors = XDisplayCells (XtDisplay (w),
				       XDefaultScreen (XtDisplay (w)));
	data->gc = XCreateGC (XtDisplay (w),
				DefaultRootWindow (XtDisplay (w)),
				NULL, NULL);
}

get_pixel (w, colorname)
	Widget 	w;
	char	*colorname;
{
	Display *dpy	= XtDisplay (w);
	int	scr	= DefaultScreen (dpy);
	Colormap cmap	= DefaultColormap (dpy, scr);
	XColor	color, ignore;

	if (XAllocNamedColor (dpy, cmap, colorname, &color, &ignore))
		return (color.pixel);
	else
		{
		printf ("Warning: Couldn't allocate color %s\n", colorname);
		return (BlackPixel (dpy, scr));
		}
}	

void redisplay (w, data, call_data)
	Widget		w;
	image_data	*data;
	caddr_t		call_data;
{
	Display	*dpy	= XtDisplay (w);
	Window 	wnd	= XtWindow (w);
	/*
	 * Draw the data on the window.
	 */
	XSetForeground (dpy, data->gc, iRedPixel);
	XDrawLine (dpy, wnd, data->gc, 10, 10, 100, 100);

	XSetForeground (dpy, data->gc, iYellowPixel);
	XDrawRectangle (dpy, wnd, data->gc, 100, 100, 100, 100);	

	XSetForeground (dpy, data->gc, iGreenPixel);
	XDrawArc (dpy, wnd, data->gc, 110, 110, 100, 100,
				START_CIRCLE, FULL_CIRCLE);

	XSetForeground (dpy, data->gc, iCyanPixel);
	XFillRectangle (dpy, wnd, data->gc, 200, 200, 100, 100);

	XSetForeground (dpy, data->gc, iBluePixel);
	XFillArc (dpy, wnd, data->gc, 200, 200, 100, 100,
				START_CIRCLE, FULL_CIRCLE);
}

void resize (w, data, call_data)
	Widget		w;
	image_data	*data;
	caddr_t		call_data;
{
	Arg	wargs [10];
	/*
	 * Get the new window size
	 */
	XtSetArg (wargs [0], XtNwidth,	&data->width);
	XtSetArg (wargs [1], XtNheight, &data->height);
	XtGetValues (w, wargs, 2);
	/*
	 * Clear the window and generate an Expose event for
	 * the entire window.
	 */
	if (XtIsRealized (w))
		XClearArea (XtDisplay (w), XtWindow (w), 0, 0, 0, 0, TRUE);
}
------------------------- cut here ---------------------------