[comp.sys.amiga.programmer] Me and Gadtools again...

kent@swrinde.nde.swri.edu (Kent D. Polk) (01/11/91)

Ok, here is a representation of a program that I am really having
trouble with. This program exhibits the same problem as the real one:
When the gadget window is removed so it can be redrawn, CloseWindow
hits low memory.

Warning: This will probably take your machine with it :^(

Compiled with Aztec 5.0d :
CFLAGS=-f8 -c2 -wonu
LFLAGS=+q

.c.o:
   cc $(CFLAGS) -o $@ $*.c

play: play.o
   ln $(LFLAGS) -o play play.o -lm8 -lc +l amiga.lib

If you can figure out what I am doing to get CloseWindow so confused, I sure
appreciate your response.

Kent Polk: Southwest Research Institute (512) 522-2882
Internet : kent@swrinde.nde.swri.edu
UUCP     : $ {cs.utexas.edu, gatech!petro, sun!texsun}!swrinde!kent

-------------------------------------  cut here  ------------------------------
#!/bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #!/bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	play.c
# This archive created: Thu Jan 10 17:07:03 1991
export PATH; PATH=/bin:$PATH
echo shar: extracting "'play.c'" '(7257 characters)'
if test -f 'play.c'
then
	echo shar: over-writing existing file "'play.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'play.c'
X/* Program	: play.c
X *	Purpose	: Play waveforms.
X * kdp		:
X * Thu 10-Jan-91 16:58:04
X *------------------------------------------------------------------------------
X * Generic Filter Exported functions:
X *		int OpenFilter	(int argc, char *argv[])
X *		int InitFilter	(struct event_header *e_h, int reinit)
X *		int DoFilter	(struct event *buf, long size, long flags)
X *		ControlFilter	()
X *		CloseFilter		()
X *------------------------------------------------------------------------------
X * ts=3
X */
X#include <functions.h>
X#include <clib/exec_protos.h>
X#include <clib/graphics_protos.h>
X#include <clib/intuition_protos.h>
X#include <clib/gadtools_protos.h>
X#include <graphics/gfxbase.h>
X#include <intuition/intuition.h>
X#include <intuition/gadgetclass.h>
X#include <libraries/gadtools.h>
X
X#define MAXCHANNELS 16
X
X/* Gadget defines of our choosing, to be used as GadgetID's: */
X#define AUDIOCHANS	4
X#define NUMGADS		4
X#define HEIGHT			256
X#define NOONE			MAXCHANNELS
X
X/* Starting values for the gadgets	*/
X#define STCHN OFF
X#define STVOL 63
X#define STDUR 2000
X#define STREP 1
X
X/* Forward References */
Xstruct Gadget *CreateAllGadgets(struct Gadget **, void *, UWORD, UWORD);
X
X/*****************  Window/Gadget Stuff  ******************/
Xstruct GfxBase *GfxBase					= NULL;
Xstruct IntuitionBase *IntuitionBase = NULL;
Xstruct Library *GadToolsBase			= NULL;
Xstruct Screen *mysc						= NULL;
Xstruct Gadget *glist						= NULL;
Xstruct Window *mywin						= NULL;
Xstruct TextAttr *SysDefTattr			= NULL;
Xvoid *vi										= NULL;
X
XUWORD topborder;
Xint numch			= 1;
Xint w_HEIGHT		= HEIGHT;
Xint opened			= 0;
X
Xenum Gads {CHAN, VOL, DUR, REPT};
XSTRPTR GadLabels[]	=
X	{"Chn:      ", "Vol:      ", "Dur:      ", "Rep:      ", NULL};
X
Xenum Chans {CHAN1, CHAN2, CHAN3, CHAN4, OFF};
XSTRPTR ChanLabels[]	= {"1", "2", "3", "4", "Off", NULL};
X
X/* Range for the sliders */
XWORD SliderMin[]	= { 0, 0, 127, 1};
XWORD SliderMax[]	= { 0, 63, 8000, 20};
XWORD SliderLevel[]= { STCHN, STVOL, STDUR, STREP};
X
X/* Current Gadget values	*/
XULONG GadVal [MAXCHANNELS] [NUMGADS];
X
X
X/******************************/
XCloseFilter()
X{
X	closeinit();
X	if (vi)				FreeVisualInfo(vi);
X	if (GadToolsBase)	CloseLibrary(GadToolsBase);
X	if (mysc)			UnlockPubScreen(NULL, mysc);
X	if (IntuitionBase)CloseLibrary(IntuitionBase);
X	if (GfxBase)		CloseLibrary(GfxBase);
X}
X
X/**********  Exported Filter Functions  *********/
X/* int OpenFilter	(int argc, char *argv[]) */
Xmain(int argc, char *argv[])
X{
X	register int i;
X
X	if (!(GfxBase=(struct GfxBase *) OpenLibrary("graphics.library", 36L))) {
X		puts("Requires V36 graphics.library");
X		return(FALSE);
X	}
X	if (!(IntuitionBase = (struct IntuitionBase *)
X	  OpenLibrary("intuition.library", 36L))) {
X		puts("Requires V36 intuition.library");
X		return(FALSE);
X	}
X	if (!(GadToolsBase = OpenLibrary("gadtools.library", 36L))) {
X		puts("Requires V36 gadtools.library");
X		return(FALSE);
X	}
X	if (!(mysc = LockPubScreen(NULL))) {
X		puts("Couldn't lock default public screen");
X		return(FALSE);
X	}
X	if (!(vi = GetVisualInfo(mysc, TAG_DONE))) {
X		puts("GetVisualInfo() failed");
X		return(FALSE);
X	}
X	topborder = mysc->WBorTop + (mysc->Font->ta_YSize + 1);
X	SysDefTattr = GfxBase->DefaultFont;
X	SysDefTattr->ta_Style = 0;
X	SysDefTattr->ta_Flags = 0;
X
X	for (i=0;i<MAXCHANNELS;i++) {
X		GadVal [i][CHAN]	= STCHN;
X		GadVal [i][VOL]	= STVOL;
X		GadVal [i][DUR]	= STDUR;
X		GadVal [i][REPT]	= STREP;
X	}
X	
X	MakeWindow();
X	while (numch< 5) {
X		ControlFilter();
X	}
X	CloseFilter();
X}
X
X
X/******************************/
XControlFilter ()
X{
X	struct IntuiMessage *imsg;
X	struct Gadget *gad;
X	ULONG imsgClass;
X	UWORD imsgCode;
X
X	Wait (1 << mywin->UserPort->mp_SigBit);
X	while (imsg = GT_GetIMsg(mywin->UserPort)) {
X		imsgClass = imsg->Class;
X		imsgCode = imsg->Code;
X
X		/*  Presuming a gadget, of course, but no harm... */
X		gad = (struct Gadget *)imsg->IAddress;
X
X		/*  Use the toolkit message-replying function here... */
X		GT_ReplyIMsg(imsg);
X		switch (imsgClass) {
X			case GADGETUP:
X				GadVal[(gad->GadgetID/MAXCHANNELS)]
X						[(gad->GadgetID%MAXCHANNELS)] = imsgCode;
X				break;
X			case MOUSEMOVE:
X				GadVal[(gad->GadgetID/MAXCHANNELS)]
X						[(gad->GadgetID%MAXCHANNELS)] = imsgCode;
X				break;
X			case CLOSEWINDOW:
X				numch++;
X				if (numch < 5) MakeWindow();
X				break;
X		}
X	}
X}
X
X
X/******************************/
Xint MakeWindow()
X{
X	int scale_height	= 0;
X
X	if (opened) closeinit();
X	opened = TRUE;
X
X	/***  Calculate how many plots/control sets in the window ***/
X	/* For this example, numch had better be less than 5 :^)	*/
X	if	(numch<=1) scale_height = 0;
X	else if (numch<= 2) scale_height = 1;
X	else if (numch<= 4) scale_height = 2;
X	else if (numch<= 8) scale_height = 3;
X	else if (numch<=16) scale_height = 4;
X	w_HEIGHT	= HEIGHT>>scale_height;
X
X	if (!CreateAllGadgets(&glist, vi, topborder, numch)) {
X		puts("CreateAllGadgets() failed");
X		return (FALSE);
X	}
X
X	/***  Create the Gadget Window ***/
X	if (!(mywin = OpenWindowTags(NULL,
X		WA_Left, 0,
X		WA_Width, 190,
X		WA_InnerHeight, w_HEIGHT * numch,
X
X		WA_DragBar, TRUE,
X		WA_Activate, TRUE,
X		WA_DepthGadget, TRUE,
X		WA_CloseGadget, TRUE,
X		WA_SmartRefresh, TRUE, /* WA_PubScreenFallBack, TRUE, */
X
X		WA_IDCMP, CLOSEWINDOW|SLIDERIDCMP|CYCLEIDCMP,
X		WA_Title, "Play",
X		TAG_DONE)))
X	{
X		puts("OpenWindow() failed");
X		return (FALSE);
X	}
X
X/* Add gadgets, refresh them, and call the toolkit refresh */
X	AddGList(mywin, glist, ((UWORD) -1), ((UWORD) -1), NULL);
X	RefreshGList(glist, mywin, NULL, ((UWORD) -1));
X	GT_RefreshWindow(mywin, NULL);
X
X	return (TRUE);
X}
X
X
X/******************************/
Xstruct Gadget *CreateAllGadgets(
X	struct Gadget **glistptr, void *vi, UWORD topborder, UWORD num)
X/* Here is where all the initialization and creation of toolkit gadgets
X * take place.  This function requires a pointer to a NULL-initialized
X * gadget list pointer.  It returns a pointer to the last created gadget,
X * which can be checked for success/failure.
X */
X{
X	register int i, j;
X	struct NewGadget ng;
X	struct Gadget *gad = NULL;
X
X	/* We obligingly perform the following operation, required of
X	any program that uses the toolkit.  It gives the toolkit a
X	place to stuff context data: */
X
X	gad = CreateContext(glistptr);
X
X	ng.ng_VisualInfo	= vi;
X	ng.ng_LeftEdge		= 85;
X	ng.ng_Height		= 11;
X	ng.ng_Width			= 100;
X	ng.ng_Flags			= PLACETEXT_LEFT;
X	ng.ng_TextAttr		= &SysDefTattr;
X
X	for (j=0;j<num;j++) {
X		ng.ng_TopEdge = topborder + w_HEIGHT*j + 5*j +1;
X		ng.ng_GadgetText	= GadLabels[0];
X		ng.ng_GadgetID		= j * MAXCHANNELS;
X		gad = CreateGadget(CYCLE_KIND, gad, &ng,
X			GTCY_Labels, ChanLabels,
X			GTCY_Active, GadVal [j][CHAN],
X			TAG_DONE);
X
X		for (i=1;i<NUMGADS;i++) {
X				ng.ng_TopEdge		= ng.ng_TopEdge + 12;
X				ng.ng_GadgetText	= GadLabels[i];
X				ng.ng_GadgetID		= j * MAXCHANNELS + i;
X				gad = CreateGadget(SLIDER_KIND, gad, &ng,
X					GTSL_Min, SliderMin[i],
X					GTSL_Max, SliderMax[i],
X					GTSL_Level, GadVal [j][i],
X					GTSL_LevelFormat, "%4ld",
X					GTSL_MaxLevelLen, 4,
X					TAG_DONE);
X		}
X	}
X	return(gad);
X}
X
X
X/******************************/
Xcloseinit()
X{
X	if (glist) {
X		puts("Freeing glist");
X		FreeGadgets(glist);
X		glist = NULL;
X	}
X	if (mywin) {
X		puts("Closing window");
X		CloseWindow(mywin);		/* Here is where I see evidence of my problems	*/
X		puts("Done Closing window");
X		mywin = NULL;
X	}
X}
SHAR_EOF
if test 7257 -ne "`wc -c 'play.c'`"
then
	echo shar: error transmitting "'play.c'" '(should have been 7257 characters)'
fi
#	End of shell archive
exit 0

peter@cbmvax.commodore.com (Peter Cherna) (01/12/91)

In article <677@swrinde.nde.swri.edu> kent@swrinde.nde.swri.edu (Kent D. Polk) writes:
>
>Ok, here is a representation of a program that I am really having
>trouble with. This program exhibits the same problem as the real one:
>When the gadget window is removed so it can be redrawn, CloseWindow
>hits low memory.
>
>If you can figure out what I am doing to get CloseWindow so confused, I sure
>appreciate your response.

You're freeing gadgets that are still on the window's gadget list.
Either close the window first, or else remove the gadgets from the
window before you free them.

>Kent Polk: Southwest Research Institute (512) 522-2882
>Internet : kent@swrinde.nde.swri.edu
>UUCP     : $ {cs.utexas.edu, gatech!petro, sun!texsun}!swrinde!kent

     Peter
--
     Peter Cherna, Software Engineer, Commodore-Amiga, Inc.
     {uunet|rutgers}!cbmvax!peter    peter@cbmvax.commodore.com
My opinions do not necessarily represent the opinions of my employer.
"Oh, PIN-compatible!  I thought you wanted me to make it IN-compatible!"