[comp.windows.x.motif] trouble with structures and callbacks

baker@mprgate.mpr.ca (Sue Baker) (11/23/90)

i'm trying to pass a structure as client_data to a callback function,
and am achieving nothing but frustration.

i am working with text widgets making up a user entry screen, and
want to convert all of the user's responses to strings using 
multiple calls to XmTextGetString() when the user clicks on the 
"update" button.

the simple structure is like:

    struct widget_type{               /* more detail to be added */
        Widget widget_array[4]; };    /* to structure later */

then variable "text" is:
    struct widget_type text;

i then generate an array of text widgets in text.widget_array
i add a callback to my "update" button:

    XtAddCallback(update, XmNactivateCallback, get_text, text);

within the "get_text" function, i receive "text" as "textwidget" 
and i can access textwidget.widget_array[0] with no trouble, but 
i get a segmentation fault when i try to access any other element 
of textwidget.widget_array.

so, 
1) why can't i access my structure in this manner?
2) how can i make my structure accessible to my callback function?

thank you in advance for any help in this matter.
sue
baker@mprgate.mpr.ca

steve@mnetor.UUCP (Steve Rees) (11/23/90)

In article <2450@kiwi.mpr.ca> baker@mprgate.mpr.ca (Sue Baker) writes:
>    struct widget_type{               /* more detail to be added */
>        Widget widget_array[4]; };    /* to structure later */
>
>    struct widget_type text;
>
>    XtAddCallback(update, XmNactivateCallback, get_text, text);
>

Let me be the first (maybe not.. 8-) ) of dozens to suggest:

XtAddCallback(update, XmNactivateCallback, get_text, &text);

then,

void get_text( Widget w, struct widget_type *w_type, caddr_t call )
{ w_type->widget_array[i], etc. }
-- 
    Steve Rees
{uunet|utzoo}!mnetor!steve or (better) steve%mnetor.uucp@uunet.uu.net
Ma Bell: +1 416 475 8980  ext. 322
ISO-standard witty quote: "Quoth the raven, 'Eat my shorts!'" - Bart Simpson

argv@turnpike.Eng.Sun.COM (Dan Heller) (11/24/90)

In article <2450@kiwi.mpr.ca> baker@mprgate.mpr.ca (Sue Baker) writes:
> i'm trying to pass a structure as client_data to a callback function,
> and am achieving nothing but frustration.

That's because you're passing a whole structure rather than a
pointer to one.

>     struct widget_type{               /* more detail to be added */
>         Widget widget_array[4]; };    /* to structure later */
>     struct widget_type text;
>     XtAddCallback(update, XmNactivateCallback, get_text, text);

The arg "text" should be "&text".  e.g.:
      XtAddCallback(update, XmNactivateCallback, get_text, &text);

void
get_text(widget, text_data, cbs)
Widget widget;
widget_type *text_data;
XmAnyCallbackStruct *cbs;
{
    int i;
    char *p;

    /* print the text of the widget in array */
    for (i = 0; i < 4; i++) {
	p = XmTextGetString(text_data->widget_array[i]);
	printf("widget_array[%d] = %s\n", i, p);
	XtFree(p);
    }
}
--
dan
----------------------------------------------------
O'Reilly && Associates   argv@sun.com / argv@ora.com
Opinions expressed reflect those of the author only.

slh@wolf.cs.washington.edu (Scott Heyano) (11/24/90)

In article <2450@kiwi.mpr.ca> baker@mprgate.mpr.ca (Sue Baker) writes:
[stuff]
|
|    XtAddCallback(update, XmNactivateCallback, get_text, text);
|
|within the "get_text" function, i receive "text" as "textwidget" 
|and i can access textwidget.widget_array[0] with no trouble, but 
|i get a segmentation fault when i try to access any other element 
|of textwidget.widget_array.
	DAMNIT, you can only pass the POINTER TO THE STRUCTURE,
	NOT the actual structure.
	So only the first 32-bits are passed, in this case
	the first Widget in the array.
	So what you want is:
	    XtAddCallback(update, XmNactivateCallback, get_text, &text);
	and:
	    textwidget->widget_array[0]
|
|so, 
|1) why can't i access my structure in this manner?
|2) how can i make my structure accessible to my callback function?
|
|thank you in advance for any help in this matter.
|sue
|baker@mprgate.mpr.ca

kaleb@thyme.jpl.nasa.gov (Kaleb Keithley ) (11/24/90)

>In article <2450@kiwi.mpr.ca> baker@mprgate.mpr.ca (Sue Baker) writes:
>	DAMNIT, you can only pass the POINTER TO THE STRUCTURE,
>	NOT the actual structure.
>	So only the first 32-bits are passed, in this case

No, I don't think so.  K&R1 says you can.  Just because you might
not ordinarily want to.  Just because in this case it is definitely
wrong.  Doesn't make it *always* wrong.

erc@pai.UUCP (Eric Johnson) (11/25/90)

In article <13837@june.cs.washington.edu>, slh@wolf.cs.washington.edu (Scott Heyano) writes:
> In article <2450@kiwi.mpr.ca> baker@mprgate.mpr.ca (Sue Baker) writes:
> [stuff]
> |
> |    XtAddCallback(update, XmNactivateCallback, get_text, text);
> |

I'm sure evryone has suggested trying something like:

     XtAddCallback(update, XmNactivateCallback, get_text, &text);

That is, pass a pointer to text, not text itself.

> |within the "get_text" function, i receive "text" as "textwidget" 
> |and i can access textwidget.widget_array[0] with no trouble, but 
> |i get a segmentation fault when i try to access any other element 
> |of textwidget.widget_array.

> 	DAMNIT, you can only pass the POINTER TO THE STRUCTURE,


Hey now, let's be nice, please. Swearing at people for asking questions
will only convince people not to ask questions--it won't make them code any
better.

The vast majority of people programming Motif applications are new at it,
so they're bound to make mistakes. When they do, and ask a question about
it, let's all try to remember our first experiences with X and Motif.

Let's face it, X and Motif are tough to program. There are an awful lot of
concepts to master, some documented, some not. And, those things that are
documented are not always described in a clear, understandable manner.
In addition, we have different versions of both X and Motif that act in
slightly different ways, which only compounds an already tough 
problem.

None of us are perfect, and we all ask questions at one time or another.
I know *I* have made mistakes, and if I ask a question on the net,
I'd rather not be flamed about it.


> 	NOT the actual structure.
> 	So only the first 32-bits are passed, in this case
> 	the first Widget in the array.
> 	So what you want is:
> 	    XtAddCallback(update, XmNactivateCallback, get_text, &text);
> 	and:
> 	    textwidget->widget_array[0]
> |
> |thank you in advance for any help in this matter.
> |sue
> |baker@mprgate.mpr.ca

Have fun and dont get too excited about Moitf programming,
-Eric

-- 
Eric F. Johnson               phone: +1 612 894 0313    BTI: Industrial
Boulware Technologies, Inc.   fax:   +1 612 894 0316    automation systems
415 W. Travelers Trail        email: erc@pai.mn.org     and services
Burnsville, MN 55337 USA

nazgul@alphalpha.com (Kee Hinckley) (11/26/90)

> No, I don't think so.  K&R1 says you can.  Just because you might
> not ordinarily want to.  Just because in this case it is definitely
> wrong.  Doesn't make it *always* wrong.

True.  Although having a compiler which does prototyping would have
caught this one (assuming you turned on Xt prototypes and have R4
of course).