[comp.windows.x] How do I draw on a widget?

randy@umn-cs.CS.UMN.EDU (Randy Orrison) (12/16/88)

What kind of Widget should I use to draw on, and how do I do it?  I'm
currently trying to use a staticraster widget, and am getting the
display and window with the XtDisplay and XtWindow calls, but when I
call XDrawRectangle I get an X Error: parameter not a Pixmap or
Window.  The thing that bothers me is that this error does not occur
at the time of the XDrawRectangle call, but later.  I don't know when,
really.  I'm sure that this info is useful in some way:

| X Error: parameter not a Pixmap or Window
|   Request Major code 67 
|   Request Minor code
|   ResourceID 0x0
|   Error Serial #41
|   Current Serial #56

but it doesn't help me any.  Here's the code that creates the widget:

|   XtSetArg (arg[0], XtNheight, (XtArgVal) HEIGHT);
|   XtSetArg (arg[1], XtNwidth, (XtArgVal) WIDTH);
|   XtSetArg (arg[2], XtNsRimage, (XtArgVal) NULL);
|   fu = XtCreateManagedWidget ("box", XwsrasterWidgetClass,
|			        rgber, arg, 3);

and here's the code that trys to draw on it:

|void
|putbox (wid, x, y)
|   Widget	wid;
|   int		x, y;
|{
|   Window	drawwin = XtWindow (wid);
|   Display	*dpy	= XtDisplay (wid);
|   XGCValues	gcv;
|   GC		gc;
|
|   gcv.foreground = BlackPixel (dpy, DefaultScreen (dpy));
|   gcv.background = WhitePixel (dpy, DefaultScreen (dpy));
|   gc = XtGetGC (wid, (GCForeground | GCBackground), &gcv);
|
|   XDrawRectangle (dpy, drawwin, gc, x-2, y-2, 5, 5);
|}

The routine putbox is called with 'fu' from the bit of code above that
creates the widget.  What am I doing wrong?  Please take into account
that I have no idea what I'm doing anyway...

	Thanks for any and all help!

		-randy
--
Randy Orrison, Chemical Computer Thinking Battery  --  randy@cctb.mn.org
(aka randy@{ux.acss.umn.edu, umn-cs.uucp, umnacca.bitnet, halcdc.uucp})
Lie: A very poor substitute for the truth, but the only one discovered
to date.

randy@umn-cs.CS.UMN.EDU (Randy Orrison) (12/16/88)

In my previous article (<10461@umn-cs.CS.UMN.EDU>) I negelcted to
mention that I'm using X11r2 on a Sun, if it matters.

	Thanks again.

		-randy
--
Randy Orrison, Chemical Computer Thinking Battery  --  randy@cctb.mn.org
(aka randy@{ux.acss.umn.edu, umn-cs.uucp, umnacca.bitnet, halcdc.uucp})
Lie: A very poor substitute for the truth, but the only one discovered
to date.

kit@ATHENA.MIT.EDU (Chris D. Peterson) (12/17/88)

In reply to: randy@umn-cs.arpa (Randy Orrison) message of 16 December.

The most likely cause of your problem is that you are trying to draw in a 
widget that does not have a window associated with it.  Only widgets that
have been realized have real X windows associated with them.  A call to
XtIsRealized() may be appropriate.

When I just want a plain window to draw into I usually just instanciate
a core widget, class is widgetClass.  In order for this to work you must
understand X events.

References:		Xlib Manual Chapter 8 and Xt Manual Chapter 7.

Example:

NOTE: 	Rattled off here, has NOT been tested, but I hope you will get the
	general idea.


main(argc, argv)
int argc;
char ** argv;
{
	Widget foo, bar;
	Arg arglist[10];
	Cardinal num_args;
	static void DrawProc();

	bar = XtInitialize( NULL, "foo_bar", NULL, 0, &argc, argv);
	num_args = 0;
	XtSetArg(arglist[num_args], XtNwidth, 100); num_args++;
	XtSetArg(arglist[num_args], XtNheight, 100); num_args++;
	foo = XtCreateManagedWidget( "window", bar, widgetClass, arglist,
				    num_args);
	XtAddEventHandler(foo, ExposureMask, FALSE, DrawProc, NULL);
	XtRealizeWidget(bar);
	XtMainLoop();
}

static void
DrawProc(w, junk, event)
Widget w;
caddr_t junk;
XEvent *event;
{

/* Insert drawing code here, make sure to check the count in the
 * exposure structure, or you may draw the graphics multiple times 
 * on every exposure.
 */
}

						Chris D. Peterson     
						MIT X Consortium /
						Project Athena 

Net:	kit@athena.mit.edu		
Phone: (617) 253 - 1326			
USMail: MIT - Room E40-342C		
	77 Massachusetts Ave.		
	Cambridge, MA 02139		

rws@EXPO.LCS.MIT.EDU (Bob Scheifler) (12/17/88)

    What kind of Widget should I use to draw on, and how do I do it?

In the HP widget set, you can use the WorkSpace widget.

    The thing that bothers me is that this error does not occur
    at the time of the XDrawRectangle call, but later.

That's because of the asynchronous nature of X.  If you can
run your application with -synchronize, it would have happened
at the time of the call.