[comp.windows.x.motif] Toggle Button Woes

arm@sps.com (Annette Myjak) (09/13/90)

i'm at a bit of a loss to explain the following behavior for a toggle button.
if anyone could enlighten me, i'd be most appreciative.

i want to add a toggle button to a standard selection box dialog.  (the
documentation says i can add one child to the work area of a selection 
box dialog.)  

i usually use UIL, so i created my selection box in the usual UIL manner.
however, i have to add the toggle button AFTER the selection box is
created.  so i have a function that fetches the selection box from the UID
hierarchy and creates it, and then uses the standard (non UIL) stuff to
create the toggle button and add it to the selection box.  (ie, use
XtSetArg to put some resources and their values into an array, 
use XmCreateToggleButton with the parent being the selection box and
passing the argument array, use XtAddCallback to register a
XmNvalueChangedCallback, and XtManage my toggle button widget.)

so far so good.  the toggle button is there, and the procedure for the
XmNvalueChangedCallback is getting executed.  

now the strange stuff.  when i added the callback, i used:

XtAddCallback (toggle, XmNvalueChangedCallback, procedure, global_val);

where the global_val is just an integer constant to be used in the procedure
as a switch value.  (in this case, 71)

however, in my procedure, the value that's getting passed in is a 0 
instead of the number it's supposed to be (71).

so, like, what happened?

i have several toggle buttons on another form widget that also use this
same procedure for their XmNvalueChangedCallback's, and they all pass in
the proper constant values to use for the switch value.  (this other
widget with it's toggle buttons are completely defined in UIL).

for the selection box dialog, i finally used the value of the widget
passed to the procedure by the callback function as a switch value to
do what i needed to do.

in short, i managed to get something to work, but i still can't figure out
why the client_data that got passed to the procedure from the callback
is showing up as 0 instead of 71.

anybody got any clues?


thanks,

annette myjak
arm@sps.com

argv@turnpike.Eng.Sun.COM (Dan Heller) (09/14/90)

In article <270@sps.com> arm@sps.com (Annette Myjak) writes:
> i want to add a toggle button to a standard selection box dialog.  (the
> documentation says i can add one child to the work area of a selection 
> box dialog.)  

You don't neven need to go that far (altho it's technically correct).
I have found that simply creating a new widget with the dialog widget
as its parent works perfectly for me.  This should probably go under
more testing (lest I get some feedback fromk someone), but it seems
reasonable (my only hisitation is that the dialog is a bulletinboard
widget and therefore needs to be better educated about the new toggle
button.

Nevertheless, I use something like:
    dialog = XmCreateDialog(...);
    XtVaCreateManagedWidget("toggle", xmToggleButtonGadgetClass, dialog,
	/* resource values */
	NULL);
Notice the "parent" is the dialog shell.

Moving along (since that really wasn't your question).

> so far so good.  the toggle button is there, and the procedure for the
> XmNvalueChangedCallback is getting executed.  
> 
> now the strange stuff.  when i added the callback, i used:
> 
> XtAddCallback (toggle, XmNvalueChangedCallback, procedure, global_val);
                                                             ^^^^^^^^^^
Notice: you used a "global", so the value of the variable at the time
the function is called will be used -- not the time the *callback*
is actually performed. "I know", you might be saying.  However, since
you are saying that the client_data (2nd) parameter of the callback
routine is showing 0 (not 71), I suspect that the global variable has 
not been initialized to 71 (as you seem to think).  By passing the
value of the global rather than the address of the variable, you are
in fact passing a constant to that function.  This constant will never
change throughout the life of the application.

Rule of thumb -- *never* pass variables *as* callback_data.
Always use the -address- of the variable (global or otherwise).
In addition to not having the problem you describe above, you can
pass the address of any global value--data structure, or char or int.
The _address_ of the variable will always work as the client_data
parameter.  However, you must realize that the client_data should
be declared appropriately:

    void
    callback_func(widget, variable, call_data)
	Widget widget;
	int *variable;
	caddr_t call_data;

This is assuming your global variable is an int, of course.
You must dereference it accordingly in the routine.

Lastly -- I recognize that I might be mistaken about my analysis
of your problem.  If you can tell me that you are actually doing:

    XtAddCallback(widget, XmNvalueChangedCallback, func, 71);

and the client_data for "func" is indeed 0, then you have a problem :-)

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

arm@sps.com (Annette Myjak) (09/14/90)

In article <142439@sun.Eng.Sun.COM>, argv@turnpike.Eng.Sun.COM (Dan Heller) writes:

> 
> Lastly -- I recognize that I might be mistaken about my analysis
> of your problem.  If you can tell me that you are actually doing:
> 
>     XtAddCallback(widget, XmNvalueChangedCallback, func, 71);
> 
> and the client_data for "func" is indeed 0, then you have a problem :-)
> 
> --
> dan


i verified the data getting passed into the callback before i posted my 
sorrowful tale. i checked the global value just before the XtAddCallback 
statement, and it was set to 71 (in a #define in file included 5 files 
before my included utility file where this callback gets added :-) ).  
just to be sure, i did just what you indicated in the above XtAddCallback
line:  ie, i passed the integer 71.

the callback function says it's getting a 0 for the client_data.

does that mean i really have a problem :-(.

like the original post mentioned, i managed to find a work around, i just
want to know why this doesn't work for this toggle button, but works just
fine for 7 others on another dialog box.

annette
arm@sps.com