dan@salt.uucp (Dan Williams) (03/10/89)
I am working in X11r3 on a sun and I am building a widget subclass of an athena box widget. I added a callback list for button press events and that worked so well that I wanted to add another call back that would do the client procedures for redrawing my graphics and be initiated from the expose procedure in the widget. I copied what I did for the button press callback list and attempted to add the second callback. The widget subclass gave me no errors but when I attempt to do an XtPopup of my root I get the infamous "Segmentation fault" error and everything bombs out. What am I doing wrong ? The following is a shar file containing a tstmain.c and 3 diff files that give the difference of my widget BaarsBox from the Template widget code under X11/lib/Xaw/ Template.c Template.h and TemplateP.h and a Makefile for the set. Run patch and compile the set to see it "run" then produce educated analysis on where I fouled up. _______________________________________________________________ #The following is a shar file delete all above this line before running #through sh echo x - tstmain.c sed 's/^X//' >tstmain.c <<'*-*-END-of-tstmain.c-*-*' X/* SCCS ID %W% %G% */ X#include <stdio.h> X#include <X11/Cardinals.h> X#include <X11/Xlib.h> X#include <X11/Intrinsic.h> X#include <X11/Shell.h> X#include <X11/StringDefs.h> X#include "BaarsBox.h" X#include <X11/Shell.h> X XWidget root_widget; /* global toplevel shell. */ Xstatic int next_window_num = 1; /* private variable to set the window num */ X Xvoid my_button3_hit (w,widget_winid,eventptr) X Widget w; X caddr_t widget_winid; /* passes parent of window */ X caddr_t eventptr; /* unused */ X{ X fprintf (stderr,"got a button 3 hit\n"); X return; X} X Xvoid expose_graphics (w,windata,call_data) X Widget w; X caddr_t windata; /* passes data with window */ X caddr_t call_data; /* unused */ X{ X printf ("doing expose_graphics routine\n"); X return; X} X Xint make_window (toplevel,xloc,yloc,xsiz,ysiz) X Widget toplevel; X long xloc,yloc,xsiz,ysiz; X{ X Dimension win_height,win_width; X int i; X Widget pop_shell,viewpane; X XtCallbackRec callbacks [2]; X XtCallbackRec morecallbacks [2]; X Arg carg[10]; X char widget_name[20]; X XtCallbackStatus stat; X int win_data; X X win_data = next_window_num++; /* setup window data */ X i = 0; X XtSetArg( carg[i], XtNx,(Position)xloc ) ; i++; X XtSetArg( carg[i], XtNy,(Position)yloc ) ; i++; X sprintf(widget_name,"popshell%d\0",win_data); X pop_shell = XtCreatePopupShell(widget_name,applicationShellWidgetClass, X toplevel, carg, i); X i = 0; X win_height = (Dimension) (ysiz); X win_width = (Dimension) (xsiz); X XtSetArg(carg[i],XtNheight, win_height ); i++; X XtSetArg(carg[i],XtNwidth, win_width ); i++; X viewpane = X XtCreateWidget("VIEWPANE",baarsBoxWidgetClass,pop_shell,carg,i); X XtManageChild(viewpane); X /* add a call back for button 3 hits */ X XtAddCallback(viewpane,XtNbaarsBoxCallback,(XtCallbackProc)my_button3_hit, X (caddr_t)win_data); X X/* if this next call is commented out then this program runs */ X X XtAddCallback(viewpane,XtNboxExposeCallback, X (XtCallbackProc)expose_graphics,(caddr_t)win_data); /* */ X X stat = XtHasCallbacks(viewpane,XtNboxExposeCallback); X switch (stat) { X case XtCallbackNoList : X fprintf (stderr,"Nolist"); X break; X case XtCallbackHasSome : X fprintf (stderr,"HasSome\n"); X break; X case XtCallbackHasNone : X fprintf (stderr,"HasNone\n"); X break; X } X /* Now pop up the widget */ X X/* here is where the error manifests itself */ X X XtPopup(pop_shell,XtGrabNone); X return(win_data); X} X X XrmOptionDescRec options[] = { X {"-label","*button.label",XrmoptionSepArg,NULL} X }; X Xmain (argc, argv) X int argc; X char *argv []; X{ X X root_widget = XtInitialize("main","DEMO",options,XtNumber(options), X &argc,argv); X X make_window(root_widget, (long)300, (long)300, X (long)500, (long)500); X X XtMainLoop(); X} *-*-END-of-tstmain.c-*-* echo x - diff.c2 sed 's/^X//' >diff.c2 <<'*-*-END-of-diff.c2-*-*' X2c2,3 X< /* $XConsortium: BaarsBox.c,v 1.2 88/10/25 17:40:25 swick Exp $ */ X--- X> X> /* $XConsortium: Template.c,v 1.2 88/10/25 17:40:25 swick Exp $ */ X5,6d5 X< X< #include <stdio.h> X9,10c8 X< #include <X11/XawMisc.h> X< #include "BaarsBoxP.h" X--- X> #include "TemplateP.h" X12,21d9 X< /* #DEFINES */ X< #define offset(field) XtOffset(BaarsBoxWidget, BaarsBox.field) X< X< /* TYPEDEFS */ X< X< struct EventData { X< XEvent *oldEvent; X< int count; X< }; X< X22a11 X> #define offset(field) XtOffset(TemplateWidget, template.field) X24,28c13,14 X< { XtNbaarsBoxCallback, XtCCallback, XtRCallback, sizeof(caddr_t), X< offset(baarsbox_callback), XtRCallback, NULL }, X< { XtNboxExposeCallback, XtCCallback, XtRCallback, sizeof(caddr_t), X< offset(boxexpose_callback), XtRCallback, NULL }, X< }; X--- X> { XtNtemplateResource, XtCTemplateResource, XtRTemplateResource, sizeof(char*), X> offset(resource), XtRString, "default" }, X29a16 X> }; X31,32c18 X< /* superclass definition */ X< #define superclass (&boxClassRec) X--- X> static void TemplateAction(/* Widget, XEvent*, String*, Cardinal* */); X34,44d19 X< X< /* GLOBALS */ X< X< X< /* EXTERNS */ X< extern void GotButton3Hit(/* Widget, XEvent*, String*, Cardinal* */); X< X< static void Initialize(); X< static void Realize(); X< static void Expose_proc(); X< static void ExtractPosition(); X47,48c22,23 X< /* {name, procedure}, */ X< {"GotButton3Hit", GotButton3Hit}, X--- X> /* {name, procedure}, */ X> {"template", TemplateAction}, X50,52d24 X< static char defaultTranslations[] = X< /* event, procedure */ X< "<Btn3Down>: GotButton3Hit()"; X53a26,28 X> static char translations[] = X> "<Key>: template() \n\ X> "; X55,60c30,34 X< BaarsBoxClassRec baarsBoxClassRec = { X< /* core fields */ X< { X< /* superclass */ (WidgetClass) &boxClassRec, X< /* class_name */ "BaarsBox", X< /* widget_size */ sizeof(BaarsBoxRec), X--- X> TemplateClassRec templateClassRec = { X> { /* core fields */ X> /* superclass */ (WidgetClass) &widgetClassRec, X> /* class_name */ "Template", X> /* widget_size */ sizeof(TemplateRec), X64c38 X< /* initialize */ Initialize, X--- X> /* initialize */ NULL, X66c40 X< /* realize function */ Realize, X--- X> /* realize */ XtInheritRealize, X78c52 X< /* expose */ Expose_proc, X--- X> /* expose */ NULL, X86c60 X< /* tm_table */ defaultTranslations, X--- X> /* tm_table */ translations, X90,99d63 X< },{ X< /* composite_class fields */ X< /* geometry_manager */ XtInheritGeometryManager, X< /* change_managed */ XtInheritChangeManaged, X< /* insert_child */ XtInheritInsertChild, X< /* delete_child */ XtInheritDeleteChild, X< /* extension */ NULL X< },{ X< /* Box class fields */ X< /* empty */ 0, X101,104c65,66 X< X< /* BaarsBox fields */ X< { X< /* empty */ 0, X--- X> { /* template fields */ X> /* empty */ 0 X108,224c70 X< WidgetClass baarsBoxWidgetClass = (WidgetClass)&baarsBoxClassRec; X< X< /* FUNCTIONS */ X< X< X< static void Initialize(request,new) X< Widget request, new; X< { X< BaarsBoxWidget newbbw = (BaarsBoxWidget)new; X< BaarsBoxWidget rw = (BaarsBoxWidget)request; X< XtCallbackStatus stat; X< X< fprintf (stderr,"In the Initialize\n"); X< X< X< } X< X< static void Realize(widget, value_mask, attributes) X< Widget widget;/* ARGSUSED */ X< XtValueMask *value_mask; X< XSetWindowAttributes *attributes; X< { X< *value_mask |= CWBitGravity; X< attributes->bit_gravity = NorthWestGravity; X< XtCreateWindow(widget, (unsigned int)CopyFromParent, X< (Visual *)CopyFromParent, *value_mask, attributes); X< XSelectInput(XtDisplay(widget),XtWindow(widget), ButtonPressMask | X< ButtonReleaseMask | ButtonMotionMask | X< PointerMotionHintMask | ExposureMask); X< } X< X< static void Expose_proc(widget,event,region) X< Widget widget; X< XEvent event; X< Region region; X< { X< fprintf (stderr,"Got an Expose call\n"); X< X< XtCallCallbacks(widget,XtNboxExposeCallback,(caddr_t)0); X< /* */ X< } X< X< static Boolean CompareEvents( oldEvent, newEvent ) X< XEvent *oldEvent, *newEvent; X< { X< #define Check(field) if (newEvent->field != oldEvent->field) return False; X< X< Check(xany.display); X< Check(xany.type); X< Check(xany.window); X< X< switch( newEvent->type ) { X< case MotionNotify: X< Check(xmotion.state); break; X< case ButtonPress: X< case ButtonRelease: X< Check(xbutton.state); X< Check(xbutton.button); break; X< case KeyPress: X< case KeyRelease: X< Check(xkey.state); X< Check(xkey.keycode); break; X< case EnterNotify: X< case LeaveNotify: X< Check(xcrossing.mode); X< Check(xcrossing.detail); X< Check(xcrossing.state); break; X< } X< #undef Check X< X< return True; X< } X< X< static Boolean PeekNotifyEvent( dpy, event, args ) X< Display *dpy; X< XEvent *event; X< char *args; X< { X< struct EventData *eventData = (struct EventData*)args; X< X< return ((++eventData->count == QLength(dpy)) /* since PeekIf blocks */ X< || CompareEvents(event, eventData->oldEvent)); X< } X< X< static Boolean LookAhead( w, event ) X< Widget w; X< XEvent *event; X< { X< XEvent newEvent; X< struct EventData eventData; X< X< if (QLength(XtDisplay(w)) == 0) return False; X< X< eventData.count = 0; X< eventData.oldEvent = event; X< X< XPeekIfEvent(XtDisplay(w), &newEvent, PeekNotifyEvent, (char*)&eventData); X< X< if (CompareEvents(event, &newEvent)) X< return True; X< else X< return False; X< } X< X< void GotButton3Hit (gw, event, params, num_params ) X< Widget gw; X< XEvent *event; X< String *params; /* unused */ X< Cardinal *num_params; /* unused */ X< { X< BaarsBoxWidget w = (BaarsBoxWidget) gw; X< Position x, y; X< X< if (LookAhead(gw, event)) return; X< XtCallCallbacks(w, XtNbaarsBoxCallback, (caddr_t)event); X< X< } X--- X> WidgetClass templateWidgetClass = (WidgetClass)&templateClassRec; *-*-END-of-diff.c2-*-* echo x - diff.h2 sed 's/^X//' >diff.h2 <<'*-*-END-of-diff.h2-*-*' X1,2d0 X< /* SCCS ID "@(#)BaarsBox.h 1.1 11/17/88" */ X< X5c3 X< /* $XConsortium: BaarsBox.h,v 1.2 88/10/25 17:22:09 swick Exp $ */ X--- X> /* $XConsortium: Template.h,v 1.2 88/10/25 17:22:09 swick Exp $ */ X8,9c6,7 X< #ifndef BaarsBox_h X< #define BaarsBox_h X--- X> #ifndef _Template_h X> #define _Template_h X11,12d8 X< #include <X11/Box.h> X< X15c11 X< * BaarsBox widget X--- X> * Template widget X26,27d21 X< baarsBoxCallback Callback Pointer NULL X< boxExposeCallback Callback Pointer NULL X40,41c34 X< #define XtNbaarsBoxCallback "baarsBoxCallback" X< #define XtCBaarsBoxCallback "BaarsBoxCallback" X--- X> #define XtNtemplateResource "templateResource" X43,44c36 X< #define XtNboxExposeCallback "boxExoseCallback" X< #define XtCBoxExposeCallback "BoxExposeCallback" X--- X> #define XtCTemplateResource "TemplateResource" X46c38 X< /* declare specific BaarsBoxWidget class and instance datatypes */ X--- X> /* declare specific TemplateWidget class and instance datatypes */ X48,49c40,41 X< typedef struct _BaarsBoxClassRec* BaarsBoxWidgetClass; X< typedef struct _BaarsBoxRec* BaarsBoxWidget; X--- X> typedef struct _TemplateClassRec* TemplateWidgetClass; X> typedef struct _TemplateRec* TemplateWidget; X53c45 X< extern WidgetClass baarsBoxWidgetClass; X--- X> extern WidgetClass templateWidgetClass; X55c47 X< #endif BaarsBox_h X--- X> #endif _Template_h *-*-END-of-diff.h2-*-* echo x - diffP.h2 sed 's/^X//' >diffP.h2 <<'*-*-END-of-diffP.h2-*-*' X1,2d0 X< /* SCCS ID "@(#)BaarsBoxP.h 1.1 11/17/88" */ X< X5c3 X< /* $XConsortium: BaarsBoxP.h,v 1.2 88/10/25 17:37:59 swick Exp $ */ X--- X> /* $XConsortium: TemplateP.h,v 1.2 88/10/25 17:37:59 swick Exp $ */ X8,9c6,7 X< #ifndef BaarsBoxP_h X< #define BaarsBoxP_h X--- X> #ifndef _TemplateP_h X> #define _TemplateP_h X11,12c9 X< #include "BaarsBox.h" X< X--- X> #include "Template.h" X14c11 X< #include <X11/BoxP.h> X--- X> #include <X11/CoreP.h> X17d13 X< /* no unique types */ X19,22c15 X< typedef struct X< { X< int make_compiler_happy; X< } BaarsBoxClassPart; X--- X> #define XtRTemplateResource "TemplateResource" X24,30c17,19 X< typedef struct _BaarsBoxClassRec X< { X< CoreClassPart core_class; X< CompositeClassPart composite_class; X< BoxClassPart box_class; X< BaarsBoxClassPart baarsbox_class; X< } BaarsBoxClassRec; X--- X> typedef struct { X> int empty; X> } TemplateClassPart; X32c21,24 X< extern BaarsBoxClassRec baarsBoxClassRec; X--- X> typedef struct _TemplateClassRec { X> CoreClassPart core_class; X> TemplateClassPart template_class; X> } TemplateClassRec; X34,40c26 X< typedef struct X< { X< /* resources */ X< XtCallbackList baarsbox_callback; X< XtCallbackList boxexpose_callback; X< /* private state */ X< } BaarsBoxPart; X--- X> extern TemplateClassRec templateClassRec; X42,46c28,32 X< typedef struct _BaarsBoxRec X< { X< CorePart core; X< BaarsBoxPart BaarsBox; X< } BaarsBoxRec; X--- X> typedef struct { X> /* resources */ X> char* resource; X> /* private state */ X> } TemplatePart; X48c34,39 X< #endif BaarsBoxP_h X--- X> typedef struct _TemplateRec { X> CorePart core; X> TemplatePart template; X> } TemplateRec; X> X> #endif _TemplateP_h *-*-END-of-diffP.h2-*-* echo x - Makefile sed 's/^X//' >Makefile <<'*-*-END-of-Makefile-*-*' X# Dan's personal makefile for his test and development area X# XCC = /bin/cc XINC_DIR = /usr/xbaars/include XTEST_INC_DIR = /u1/dan/X/VIEW XLIBS = -lXaw -lXmu -lXt -lX11 -lm XEWO_DIR = /usr/xbaars/src/ewo/ XMENU_DIR = /usr/xbaars/src/xmenu/ XCFLAGS = -g XCC = cc XLIBS = -lXaw -lXmu -lXt -lX11 -lm X X X############################################################################# Xall : tst X Xtst : tstmain.o BaarsBox.o X $(CC) tstmain.o BaarsBox.o -o tst $(CFLAGS) $(LIBS) X Xclean : X rm -f *.o core tst X Xtstmain.o : tstmain.c X $(CC) -c $(CFLAGS) $*.c X XBaarsBox.o : BaarsBox.c BaarsBox.h BaarsBoxP.h X $(CC) -c $(CFLAGS) $*.c X *-*-END-of-Makefile-*-* exit
kit@ATHENA.MIT.EDU (Chris D. Peterson) (03/11/89)
> I get the infamous "Segmentation fault" error and everything bombs out. > What am I doing wrong ? Saber C to the rescue... In your Private header file the definition for the instance record for you widget is: typedef struct _BaarsBoxRec { CorePart core; BaarsBoxPart BaarsBox; } BaarsBoxRec; It should be: typedef struct _BaarsBoxRec { CorePart core; CompositePart composite; BoxPart box; BaarsBoxPart BaarsBox; } BaarsBoxRec; Since you are leaving out some of the fields the XtOffset() macro gets confused and when you specify a resource (In this case a callback list with XtAddCallback) it scribbles all over your instance record. In your case it was setting the number of children to some garbage value, and thus running off the end of an array, causing a seg. fault. Chris D. Peterson MIT X Consortium / Project Athena Net: kit@athena.mit.edu Phone: (617) 253 - 1326 USMail: MIT - Room E40-321 77 Massachusetts Ave. Cambridge, MA 02139