/* * DiskSpeed v3.0 * by * Michael Sinz * * Copyright (c) 1989 by MKSoft Development * * MKSoft Development * 163 Appledore Drive * Downingtown, PA 19335 * * Yes, this is yet another disk speed testing program, but with a few * differences. It was designed to give the most accurate results of the * true disk performance in the system. For this reason many of * DiskSpeed's results may look either lower or higher than current disk * performance tests. * * This program was thrown together in a few hours because I needed more * accurate and consistent results for disk performance as seen from the * application's standpoint. This program has now served its purpose and * I am now giving it to the rest of the Amiga world to play with as long * as all of the files remain together in unmodified form. (That is, the * files DiskSpeed, DiskSpeed.info, DiskSpeed.c, DiskSpeedWindow.c, * DiskSpeedWindow.h, MakeBoxes.c, MakeBoxes.h, StandardGadgets.c, * StandardGadgets.h, RenderInfo.c, RenderInfo.h, DiskSpeed.doc, and * MakeFile) * * Version 2.0 of this program added a few features and cleaned up the * user interface. I hope you like this... * * Version 3.0 of this program added the performance stress and cleaned up * some parts of the older code. (Fix to RenderInfo.c) * ****************************************************************************** * * * Reading legal mush can turn your brain into guacamole! * * * * So here is some of that legal mush: * * * * Permission is hereby granted to distribute this program's source * * executable, and documentation for non-commercial purposes, so long as the * * copyright notices are not removed from the sources, executable or * * documentation. This program may not be distributed for a profit without * * the express written consent of the author Michael Sinz. * * * * This program is not in the public domain. * * * * Fred Fish is expressly granted permission to distribute this program's * * source and executable as part of the "Fred Fish freely redistributable * * Amiga software library." * * * * Permission is expressly granted for this program and it's source to be * * distributed as part of the Amicus Amiga software disks, and the * * First Amiga User Group's Hot Mix disks. * * * ****************************************************************************** * * This is the window opening and definition code... */ #include #include #include #include #include #include #include #include #include #include "RenderInfo.h" #include "StandardGadgets.h" #include "MakeBoxes.h" #include "DiskSpeedWindow.h" extern struct Custom __far custom; #define WINDOWTEXT_SIZE 60 static char DiskSpeedTitle[14]="DiskSpeed 3.1"; static char WindowText[WINDOWTEXT_SIZE]="DiskSpeed 3.1 - Copyright (c) 1989,90 by MKSoft Development"; static char CPUstressTask[26]="DiskSpeed CPU Stress Task"; static char Dashes[10]="---------"; static char fontnam[11]="topaz.font"; static struct TextAttr TOPAZ80={fontnam,TOPAZ_EIGHTY,0,0}; #define TEXT_BUFFER_SIZE 1000L #define NUM_COP_INS 12000 #define WINDOW_WIDTH 531 #define WINDOW_HEIGHT 177 #define REQ_X_SIZE 518 #define REQ_Y_SIZE 152 #define BOX_OUT 0 #define BOX_IN 1 struct BoxType { SHORT x1,y1; SHORT x2,y2; SHORT type; }; struct Text_Info { SHORT x,y; char *text; }; struct Gadget_Info { SHORT x,y; SHORT size; SHORT flags; USHORT ID; char *text; }; struct Result_Info { SHORT x,y; }; static struct BoxType BoxTypes[NUM_BOXES]= { {0,0, WINDOW_WIDTH-1,WINDOW_HEIGHT-1, BOX_OUT}, {70,20, 249,31, BOX_IN}, {70,37, 524,48, BOX_IN}, {16,55, 516,102, BOX_IN}, {16,106, 265,154, BOX_IN}, {274,106, 373,154, BOX_IN}, {143,68, 226,98, BOX_IN}, {236,68, 319,98, BOX_IN}, {329,68, 412,98, BOX_IN}, {422,68, 505,98, BOX_IN}, {171,110, 254,150, BOX_IN}, {282,127, 365,137, BOX_IN} }; static struct Text_Info TextInfo[NUM_TEXT]= { {8,22, "Device:"}, {8,39, "Comment"}, {265,22, "Test Intensity:"}, {24,59, "Buffer Size"}, {24,70, "Bytes/s Create"}, {24,80, "Bytes/s Write"}, {24,90, "Bytes/s Read"}, {197,59, "512"}, {282,59, "4096"}, {367,59, "32768"}, {452,59, "262144"}, {24,112, "Files/s Create"}, {24,122, "Files/s Open/Close"}, {24,132, "Files/s Scan"}, {24,142, "Files/s Delete"}, {288,118, "Seek/Read"}, {8,162, "Performance Stress:"}, {185,162, "DMA Contention"}, {368,162, "CPU Contention"} }; static struct Gadget_Info GadgetInfo[NUM_GADGETS]= { {387,19, 41, GADGIMMEDIATE|TOGGLESELECT, GADGET_HIGH, "High"}, {435,19, 41, GADGIMMEDIATE|TOGGLESELECT, GADGET_MED, "Med"}, {483,19, 41, GADGIMMEDIATE|TOGGLESELECT, GADGET_LOW, "Low"}, {391,107, 116, RELVERIFY, GADGET_START, "Start Test"}, {391,124, 116, RELVERIFY, GADGET_SAVE, "Save Results"}, {391,141, 116, RELVERIFY, GADGET_PRINT, "Print Results"}, {300,159, 41, TOGGLESELECT, GADGET_DMA, "DMA"}, {483,159, 41, TOGGLESELECT, GADGET_CPU, "CPU"} }; static struct Result_Info ResultInfo[NUM_RESULTS]= { {149,70}, {149,80}, {149,90}, {242,70}, {242,80}, {242,90}, {335,70}, {335,80}, {335,90}, {428,70}, {428,80}, {428,90}, {177,112}, {177,122}, {177,132}, {177,142}, {288,129} }; /* * This define is for the Write_Results routine... */ #define MYCAT(z,y,x) for (y=x;*y;*z++=*y++) #define MYCATNEWLINE(x) *x++='\n' #define MYCATTAB(x) *x++='\t' #define MYCATSPACE(x) *x++=' ' /* * This routine builds a string of the results and then writes it to * the file passed... */ VOID Write_Results(struct MyWindow *MyWindow,BPTR TheFile) { register char *t; register char *h; register char *Buffer; register struct Gadget *gad; register short flag=FALSE; if (t=Buffer=AllocMem(TEXT_BUFFER_SIZE,MEMF_PUBLIC|MEMF_CLEAR)) { /* Title and device name */ MYCATNEWLINE(t); MYCAT(t,h,WindowText); MYCATNEWLINE(t); MYCATNEWLINE(t); MYCAT(t,h,TextInfo[0].text); MYCATTAB(t); MYCAT(t,h,MyWindow->DeviceName); MYCATNEWLINE(t); MYCATNEWLINE(t); if (MyWindow->Comment[0]) { MYCAT(t,h,TextInfo[1].text); MYCATTAB(t); MYCAT(t,h,MyWindow->Comment); MYCATNEWLINE(t); MYCATNEWLINE(t); } /* Tell of the test intensity... */ MYCAT(t,h,TextInfo[2].text); MYCATSPACE(t); switch(MyWindow->TestFlag) { case GADGET_HIGH: MYCAT(t,h,GadgetInfo[0].text); break; case GADGET_MED: MYCAT(t,h,GadgetInfo[1].text); MYCATSPACE(t); break; case GADGET_LOW: MYCAT(t,h,GadgetInfo[2].text); MYCATSPACE(t); break; } /* Show the DMA and CPU settings... */ MYCATSPACE(t); MYCATSPACE(t); MYCAT(t,h,TextInfo[16].text); gad=MyWindow->Window->FirstGadget; while (gad) { if (gad->Flags & SELECTED) { if (GADGET_DMA==gad->GadgetID) { MYCATSPACE(t); if (flag) { *t++='&'; MYCATSPACE(t); } MYCAT(t,h,TextInfo[17].text); flag=TRUE; } else if (GADGET_CPU==gad->GadgetID) { MYCATSPACE(t); if (flag) { *t++='&'; MYCATSPACE(t); } MYCAT(t,h,TextInfo[18].text); flag=TRUE; } } gad=gad->NextGadget; } if (!flag) MYCAT(t,h," None"); MYCATNEWLINE(t); MYCATNEWLINE(t); /* File Create */ MYCAT(t,h,MyWindow->MyResults[RESULTS_CREATE].text); MYCATSPACE(t); MYCAT(t,h,TextInfo[11].text); MYCATNEWLINE(t); /* File Open/Close */ MYCAT(t,h,MyWindow->MyResults[RESULTS_OPEN_CLOSE].text); MYCATSPACE(t); MYCAT(t,h,TextInfo[12].text); MYCATNEWLINE(t); /* File Scan */ MYCAT(t,h,MyWindow->MyResults[RESULTS_DIR_SCAN].text); MYCATSPACE(t); MYCAT(t,h,TextInfo[13].text); MYCATNEWLINE(t); /* File Delete */ MYCAT(t,h,MyWindow->MyResults[RESULTS_DELETE].text); MYCATSPACE(t); MYCAT(t,h,TextInfo[14].text); MYCATNEWLINE(t); MYCATNEWLINE(t); /* Seek and Read */ MYCAT(t,h,MyWindow->MyResults[RESULTS_SEEK_READ].text); MYCATSPACE(t); MYCAT(t,h,TextInfo[15].text); MYCATNEWLINE(t); MYCATNEWLINE(t); /* Titles... */ MYCAT(t,h,TextInfo[3].text); MYCATTAB(t); MYCAT(t,h,TextInfo[7].text); MYCATTAB(t); MYCATTAB(t); MYCAT(t,h,TextInfo[8].text); MYCATTAB(t); MYCATTAB(t); MYCAT(t,h,TextInfo[9].text); MYCATTAB(t); MYCATTAB(t); MYCAT(t,h,TextInfo[10].text); MYCATNEWLINE(t); /* Dash it all... :-) */ MYCAT(t,h,Dashes); MYCATTAB(t); MYCAT(t,h,Dashes); MYCATTAB(t); MYCAT(t,h,Dashes); MYCATTAB(t); MYCAT(t,h,Dashes); MYCATTAB(t); MYCAT(t,h,Dashes); MYCATNEWLINE(t); /* Create Speed */ MYCAT(t,h,TextInfo[4].text); MYCATTAB(t); MYCAT(t,h,MyWindow->MyResults[RESULTS_512_CREATE].text); MYCATTAB(t); MYCAT(t,h,MyWindow->MyResults[RESULTS_4096_CREATE].text); MYCATTAB(t); MYCAT(t,h,MyWindow->MyResults[RESULTS_32768_CREATE].text); MYCATTAB(t); MYCAT(t,h,MyWindow->MyResults[RESULTS_262144_CREATE].text); MYCATNEWLINE(t); /* Write Speed */ MYCAT(t,h,TextInfo[5].text); MYCATTAB(t); MYCAT(t,h,MyWindow->MyResults[RESULTS_512_WRITE].text); MYCATTAB(t); MYCAT(t,h,MyWindow->MyResults[RESULTS_4096_WRITE].text); MYCATTAB(t); MYCAT(t,h,MyWindow->MyResults[RESULTS_32768_WRITE].text); MYCATTAB(t); MYCAT(t,h,MyWindow->MyResults[RESULTS_262144_WRITE].text); MYCATNEWLINE(t); /* Read Speed */ MYCAT(t,h,TextInfo[6].text); MYCATTAB(t); MYCAT(t,h,MyWindow->MyResults[RESULTS_512_READ].text); MYCATTAB(t); MYCAT(t,h,MyWindow->MyResults[RESULTS_4096_READ].text); MYCATTAB(t); MYCAT(t,h,MyWindow->MyResults[RESULTS_32768_READ].text); MYCATTAB(t); MYCAT(t,h,MyWindow->MyResults[RESULTS_262144_READ].text); MYCATNEWLINE(t); MYCATNEWLINE(t); MYCATNEWLINE(t); /* Now, all we have to do is write the sucker... */ Write(TheFile,Buffer,t-Buffer); FreeMem(Buffer,TEXT_BUFFER_SIZE); } } VOID __saveds CPU_Stress_Code(VOID) { char test1[WINDOWTEXT_SIZE]; char test2[WINDOWTEXT_SIZE]; for(;;) { strcpy(test1,WindowText); strcpy(test2,test1); } } VOID CreateCopper(struct MyWindow *MyWin) { register SHORT loop; register SHORT colour; register struct ViewPort *vp; register struct UCopList *ucop; register ULONG mask; vp=ViewPortAddress(MyWin->Window); colour=GetRGB4(vp->ColorMap,0); if (ucop=AllocMem(sizeof(struct UCopList),MEMF_PUBLIC|MEMF_CLEAR)) { MyWin->DMAstress=ucop; CINIT(ucop,NUM_COP_INS+2); CWAIT(ucop,12,0); mask=0x04044004; for (loop=0;loop> 28); CMOVE(ucop,custom.color[0],colour); } CEND(ucop); Forbid(); vp->UCopIns=ucop; Permit(); RethinkDisplay(); } } VOID Stress_On(struct MyWindow *MyWin) { register struct Gadget *gad; gad=MyWin->Window->FirstGadget; while (gad) { if (gad->Flags & SELECTED) { if (GADGET_DMA==gad->GadgetID) { CreateCopper(MyWin); } else if (GADGET_CPU==gad->GadgetID) { MyWin->CPUstress=CreateTask(CPUstressTask,0L,CPU_Stress_Code,1000L); } } gad=gad->NextGadget; } } VOID Stress_Off(struct MyWindow *MyWin) { if (MyWin->CPUstress) { Forbid(); /* This is a work-around for a bug in EXEC... */ RemTask(MyWin->CPUstress); /* RemTask in 1.3 and earlier */ Permit(); /* has a problem of reusing memory after free */ MyWin->CPUstress=NULL; } if (MyWin->DMAstress) { FreeVPortCopLists(ViewPortAddress(MyWin->Window)); RemakeDisplay(); MyWin->DMAstress=NULL; } } VOID CloseMyWindow(struct MyWindow *MyWin) { if (MyWin) { if (MyWin->Window) { if (MyWin->DragGadget) RemDragGadget(MyWin->DragGadget); if (MyWin->FrontBackGadget) RemFrontBackGadget(MyWin->FrontBackGadget); if (MyWin->CloseGadget) RemCloseGadget(MyWin->CloseGadget); CloseWindow(MyWin->Window); } FreeMem(MyWin,sizeof(struct MyWindow)); } } struct MyWindow *OpenMyWindow(struct RenderInfo *ri) { register SHORT loop; register struct MyWindow *MyWin; register struct Border *MyBorder; register struct IntuiText *itext; register struct Gadget *gad; struct NewWindow nw; if (MyWin=AllocMem(sizeof(struct MyWindow),MEMF_PUBLIC|MEMF_CLEAR)) { /* First, set up the requester structures... */ MyWin->Req.LeftEdge=7; MyWin->Req.TopEdge=19; MyWin->Req.Width=REQ_X_SIZE; MyWin->Req.Height=REQ_Y_SIZE; MyWin->Req.BackFill=ri->BackPen; MyWin->Req.ReqGadget=&(MyWin->ReqGadget); MyWin->ReqGadget.Width=REQ_X_SIZE; MyWin->ReqGadget.Height=REQ_Y_SIZE; MyWin->ReqGadget.Flags=GADGHIMAGE; MyWin->ReqGadget.Activation=RELVERIFY; MyWin->ReqGadget.GadgetType=BOOLGADGET|REQGADGET; MyWin->ReqGadget.GadgetRender=(APTR)&(MyWin->ReqBorders[0]); MyWin->ReqGadget.SelectRender=(APTR)&(MyWin->ReqBorders[2]); MyWin->ReqGadget.GadgetText=&(MyWin->ReqIText); MyWin->ReqGadget.GadgetID=GADGET_REQ; MyWin->ReqBorders[0].NextBorder=&(MyWin->ReqBorders[1]); MyWin->ReqBorders[2].NextBorder=&(MyWin->ReqBorders[3]); MyWin->ReqBorders[0].XY=MyWin->ReqBorders[2].XY=MyWin->ReqVector1; MyWin->ReqBorders[1].XY=MyWin->ReqBorders[3].XY=MyWin->ReqVector2; for (loop=0;loop<4;loop++) { MyWin->ReqBorders[loop].Count=8; MyWin->ReqBorders[loop].DrawMode=JAM1; } MyWin->ReqBorders[0].FrontPen=MyWin->ReqBorders[3].FrontPen=ri->Highlight; MyWin->ReqBorders[1].FrontPen=MyWin->ReqBorders[2].FrontPen=ri->Shadow; FillTopLeftDouble_Border(&(MyWin->ReqBorders[0]),REQ_X_SIZE,REQ_Y_SIZE); FillBottomRightDouble_Border(&(MyWin->ReqBorders[1]),REQ_X_SIZE,REQ_Y_SIZE); MyWin->ReqIText.FrontPen=ri->TextPen; MyWin->ReqIText.DrawMode=JAM1; MyWin->ReqIText.TopEdge=(REQ_Y_SIZE>>1)-8; MyWin->ReqIText.ITextFont=&TOPAZ80; /* Now for the window gadgets... */ gad=&(MyWin->Detail); gad->Flags=GADGHNONE; gad->GadgetType=BOOLGADGET; nw.LeftEdge=20; nw.TopEdge=11; nw.Width=WINDOW_WIDTH; nw.Height=WINDOW_HEIGHT; nw.DetailPen=-1; nw.BlockPen=-1; nw.IDCMPFlags=GADGETDOWN|GADGETUP|CLOSEWINDOW|ACTIVEWINDOW; nw.Flags=SIMPLE_REFRESH|BORDERLESS|ACTIVATE|NOCAREREFRESH|RMBTRAP; nw.FirstGadget=gad; nw.CheckMark=NULL; nw.Title=NULL; nw.Type=WBENCHSCREEN; MyBorder=NULL; for (loop=0;loop<(NUM_BOXES*2);loop++) { MyWin->Details[loop].Border.NextBorder=MyBorder; MyBorder=&(MyWin->Details[loop].Border); MyBorder->XY=MyWin->Details[loop].Vectors; MyBorder->FrontPen=ri->Highlight; MyBorder->DrawMode=JAM1; MyBorder->Count=5; } gad->GadgetRender=(APTR)MyBorder; for (loop=0;loopDetails[loop*2].Border.LeftEdge=BoxTypes[loop].x1; MyWin->Details[loop*2].Border.TopEdge=BoxTypes[loop].y1; FillTopLeft_Border(&(MyWin->Details[loop*2].Border), BoxTypes[loop].x2-BoxTypes[loop].x1+1, BoxTypes[loop].y2-BoxTypes[loop].y1+1); if (BOX_IN==BoxTypes[loop].type) MyWin->Details[loop*2].Border.FrontPen=ri->Shadow; MyWin->Details[loop*2+1].Border.LeftEdge=BoxTypes[loop].x1; MyWin->Details[loop*2+1].Border.TopEdge=BoxTypes[loop].y1; FillBottomRight_Border(&(MyWin->Details[loop*2+1].Border), BoxTypes[loop].x2-BoxTypes[loop].x1+1, BoxTypes[loop].y2-BoxTypes[loop].y1+1); if (BOX_OUT==BoxTypes[loop].type) MyWin->Details[loop*2+1].Border.FrontPen=ri->Shadow; } itext=NULL; for (loop=NUM_RESULTS-1;loop>=0;loop--) { MyWin->MyResults[loop].IntuiText.NextText=itext; itext=&(MyWin->MyResults[loop].IntuiText); itext->FrontPen=ri->TextPen; itext->BackPen=ri->BackPen; itext->DrawMode=JAM2; itext->LeftEdge=ResultInfo[loop].x; itext->TopEdge=ResultInfo[loop].y; itext->ITextFont=&TOPAZ80; itext->IText=MyWin->MyResults[loop].text; } for (loop=0;loopTextDetails[loop].NextText=itext; itext=&(MyWin->TextDetails[loop]); itext->FrontPen=ri->TextPen; itext->DrawMode=JAM1; itext->LeftEdge=TextInfo[loop].x; itext->TopEdge=TextInfo[loop].y; itext->ITextFont=&TOPAZ80; itext->IText=TextInfo[loop].text; } gad->GadgetText=itext; for (loop=0;loopNextGadget=&(MyWin->MyGadgets[loop].Gadget); gad=gad->NextGadget; gad->LeftEdge=GadgetInfo[loop].x; gad->TopEdge=GadgetInfo[loop].y; gad->Width=GadgetInfo[loop].size; gad->Height=14; gad->Flags=GADGHIMAGE; gad->Activation=GadgetInfo[loop].flags; gad->GadgetType=BOOLGADGET; gad->GadgetRender=(APTR)&(MyWin->MyGadgets[loop].Borders[0]); gad->SelectRender=(APTR)&(MyWin->MyGadgets[loop].Borders[2]); gad->GadgetText=&(MyWin->MyGadgets[loop].IntuiText); gad->GadgetID=GadgetInfo[loop].ID; if (GadgetInfo[loop].ID==GADGET_MED) { gad->Flags|=SELECTED; MyWin->TestFlag=GadgetInfo[loop].ID; } MyWin->MyGadgets[loop].Borders[0].NextBorder=&(MyWin->MyGadgets[loop].Borders[1]); MyWin->MyGadgets[loop].Borders[2].NextBorder=&(MyWin->MyGadgets[loop].Borders[3]); MyWin->MyGadgets[loop].Borders[0].DrawMode=JAM1; MyWin->MyGadgets[loop].Borders[1].DrawMode=JAM1; MyWin->MyGadgets[loop].Borders[2].DrawMode=JAM1; MyWin->MyGadgets[loop].Borders[3].DrawMode=JAM1; MyWin->MyGadgets[loop].Borders[0].FrontPen=ri->Highlight; MyWin->MyGadgets[loop].Borders[1].FrontPen=ri->Shadow; MyWin->MyGadgets[loop].Borders[2].FrontPen=ri->Shadow; MyWin->MyGadgets[loop].Borders[3].FrontPen=ri->Highlight; MyWin->MyGadgets[loop].Borders[0].XY=MyWin->MyGadgets[loop].Vectors1; MyWin->MyGadgets[loop].Borders[1].XY=MyWin->MyGadgets[loop].Vectors2; MyWin->MyGadgets[loop].Borders[2].XY=MyWin->MyGadgets[loop].Vectors1; MyWin->MyGadgets[loop].Borders[3].XY=MyWin->MyGadgets[loop].Vectors2; MyWin->MyGadgets[loop].Borders[0].Count=8; MyWin->MyGadgets[loop].Borders[1].Count=8; MyWin->MyGadgets[loop].Borders[2].Count=8; MyWin->MyGadgets[loop].Borders[3].Count=8; FillTopLeftDouble_Border(&(MyWin->MyGadgets[loop].Borders[0]),GadgetInfo[loop].size,14); FillBottomRightDouble_Border(&(MyWin->MyGadgets[loop].Borders[1]),GadgetInfo[loop].size,14); MyWin->MyGadgets[loop].IntuiText.TopEdge=3; MyWin->MyGadgets[loop].IntuiText.FrontPen=ri->TextPen; MyWin->MyGadgets[loop].IntuiText.DrawMode=JAM1; MyWin->MyGadgets[loop].IntuiText.ITextFont=&TOPAZ80; MyWin->MyGadgets[loop].IntuiText.IText=GadgetInfo[loop].text; MyWin->MyGadgets[loop].IntuiText.LeftEdge= (GadgetInfo[loop].size-IntuiTextLength(&(MyWin->MyGadgets[loop].IntuiText))) >> 1; } gad->NextGadget=&(MyWin->DeviceGadget); gad=gad->NextGadget; gad->LeftEdge=72; gad->TopEdge=22; gad->Width=176; gad->Height=9; gad->Activation=RELVERIFY; gad->GadgetType=STRGADGET; gad->SpecialInfo=(APTR)&(MyWin->DeviceGadgetInfo); gad->GadgetID=GADGET_STRING; gad->UserData=(APTR)&(MyWin->CommentGadget); MyWin->DeviceGadgetInfo.Buffer=MyWin->DeviceName; MyWin->DeviceGadgetInfo.MaxChars=32; gad->NextGadget=&(MyWin->CommentGadget); gad=gad->NextGadget; gad->LeftEdge=72; gad->TopEdge=39; gad->Width=451; gad->Height=9; gad->Activation=RELVERIFY; gad->GadgetType=STRGADGET; gad->SpecialInfo=(APTR)&(MyWin->CommentGadgetInfo); gad->GadgetID=GADGET_STRING; gad->UserData=(APTR)&(MyWin->DeviceGadget); MyWin->CommentGadgetInfo.Buffer=MyWin->Comment; MyWin->CommentGadgetInfo.MaxChars=80; gad->NextGadget=&(MyWin->Background); gad=gad->NextGadget; gad->Flags=GADGHNONE|GADGIMAGE; gad->GadgetType=BOOLGADGET; gad->GadgetRender=(APTR)&(MyWin->Image_Background); MyWin->Image_Background.Width=WINDOW_WIDTH; MyWin->Image_Background.Height=WINDOW_HEIGHT; MyWin->Image_Background.PlaneOnOff=ri->BackPen; loop=FALSE; if (MyWin->Window=OpenWindow(&nw)) if (MyWin->CloseGadget=AddCloseGadget(MyWin->Window,ri,7,3)) if (MyWin->FrontBackGadget=AddFrontBackGadget(MyWin->Window,ri,473,3)) if (MyWin->DragGadget=AddDragGadget(MyWin->Window,ri,DiskSpeedTitle,33,3,438)) { loop=TRUE; } if (!loop) { CloseMyWindow(MyWin); MyWin=NULL; } else SetWindowTitles(MyWin->Window,(UBYTE *)-1L,WindowText); } return(MyWin); }