[comp.windows.x] Novice question about using raw Xlib for drawing in a widget.

ssroy@phoenix.Princeton.EDU (Steve Scot Roy) (01/17/89)

Greetings ladies and gents, I am a novice Xt programmer and I have a
question about something that has got to be easy but doesn't seem to be
working the way I would think.

All I want to do is, given a widget, Core or Composite or whatever, fill
a rectangle in it with XFillRectangle.  At least, once I can do that I
can do what I really want to do.

I open a toplevel with XtInitialize, create a managed widget with
XtCreateManagedWidget, I set up translation table stuff so that it can
read mouse and key events and do the proper things when they happen, and
I realize the toplevel and dive into XtMainLoop.  All of this works with
no problem.

Getting Expose events and drawing into the window you get with
XtWindow(widget) doesn't seem to work, however.  Allow me to explain more
fully.

First, if I put the line "<Expose>: draw()\n" in my translation table
draw() does not end up being called even though "<Enter>: draw()\n"
does cause draw to be called.  What is the deal?

Second, in my translation table I say to call the routine draw() on
Enter events, and draw() is defined as follows:

void draw(w,event,params,n)
Widget w;
XEvent *event;
String *params;
Cardinal *n;
{
  XFillRectangle(XtDisplay(w),XtWindow(w),gc,10,10,100,100);
}

and in my main() I have

  gc = XtGetGC(toplevel,0L,&values);

When I run it it does not bomb and die, and when in the debugger it
does in fact go into the draw() routine, but nothing goes into the
window.  What am I missing?  Have I provided enough information here?
Sorry about such a stupid question, but the documentation I have doesn't
talk about this at all.  I get the impression that this is so easy once
you know how to do it that they don't bother documenting it or showing
examples of it.  Thanks in advance.

Steve Roy.
Princeton Program of Applied and Computational Mathematics.

swick@ATHENA.MIT.EDU (Ralph R. Swick) (01/17/89)

> First, if I put the line "<Expose>: draw()\n" in my translation table
> draw() does not end up being called even though "<Enter>: draw()\n"
> does cause draw to be called.  What is the deal?

I dunno.  The following patch to X11R3/examples/Xaw/xcommand.c seems
to do what you and I would expect.  Perhaps you can figure out what
you're missing from this.

*** X11R3/examples/Xaw/xcommand.c
--- /tmp/f.c
***************
*** 1,6 ****
--- 1,7 ----
  #include <stdio.h>
  #include <X11/Intrinsic.h>
  #include <X11/Command.h>
+ #include <X11/StringDefs.h>
  
  static XrmOptionDescRec options[] = {
  {"-label",	"*label",	XrmoptionSepArg,	NULL}
***************
*** 22,33 ****
--- 23,64 ----
      printf( "button was activated.\n" );
  }
  
+ void Exposed(w, event, params, param_count)
+     Widget w;
+     XEvent *event;
+     String *params;
+     Cardinal *param_count;
+ {
+     printf( "button was exposed.\n" );
+ }
  
+ void Draw(w, event, params, param_count)
+     Widget w;
+     XEvent *event;
+     String *params;
+     Cardinal *param_count;
+ {
+     static GC gc;
+     if (gc == NULL) {
+ 	XGCValues values;
+         Arg args[2];
+ 	XtSetArg( args[0], XtNforeground, &values.foreground );
+ 	XtSetArg( args[1], XtNbackground, &values.background );
+ 	XtGetValues( w, args, (Cardinal)2 );
+ 	gc = XtGetGC( w, GCForeground | GCBackground, &values );
+     }
+     XDrawPoint( XtDisplay(w), XtWindow(w), gc,
+ 	        event->xmotion.x, event->xmotion.y );
+ }
+ 
+ 
+ 
  void main(argc, argv)
      unsigned int argc;
      char **argv;
  {
      Widget toplevel;
+     Widget c;
      static XtCallbackRec callbacks[] = {
        { Activate, NULL },
        { NULL, NULL },
***************
*** 42,49 ****
--- 73,95 ----
  
      if (argc != 1) Syntax(argv[0]);
  
+     c =
      XtCreateManagedWidget( "command", commandWidgetClass, toplevel,
  			   args, XtNumber(args) );
+ 
+     {
+ 	static XtActionsRec actions[] = {
+ 	    { "expose", Exposed },
+ 	    { "draw",   Draw },
+ 	};
+ 	XtAddActions( actions, XtNumber(actions) );
+     }
+     XtOverrideTranslations( c,
+ 	XtParseTranslationTable(
+ 	    "<Expose>: expose() \n\
+ 	     <BtnMotion>: draw() "
+ 	)
+     );
      
      XtRealizeWidget(toplevel);
      XtMainLoop();