/**************************************************************** /* * /* HackBench - Part 4 of 4 - hbgad.c - Gadgets and Menus * /* * /* Copyright (C) 1987 by Bill Kinnersley * /* CS Dept, Washington State Univ, Pullman, WA 99164 * /* * /* Permission granted to redistribute this program * /* provided the copyright notice remains intact. * /* May not be used as part of any commercial product. * /* * /****************************************************************/ #include "hb.h" extern int drawobj(), clearobj(), openobj(), closeobj(), compobj(); extern char *rindex(); extern short debug; extern struct Window *wbWin, *curWin, *errWin; extern struct MyWBObject *lastObj; extern struct List wbObjs, selObjs, utilObjs; struct MsgPort *DOSPort, *IDCMPPort, *WBPort; long IDCMPBit, WBBit; extern void *IconBase; struct DosLibrary *DosBase; struct IntuitionBase *IntuitionBase; struct GfxBase *GfxBase; struct LayersBase *LayersBase; struct DosInfo *rnInfo; long sendpkt(); struct Remember *RememberKey=NULL; char *title = "HackBench release 1.0: "; char lastErr[60]; BPTR initialDir; BYTE sbuf[61], undoBuf[61]; struct StringInfo ren_si = { sbuf, undoBuf, 0, 60, 0, 0, 1, 60, 0, 0, NULL, 0, NULL }; struct Gadget ren_gad = { NULL, 1, 1, 500, 10, GADGHCOMP, STRINGCENTER | RELVERIFY, STRGADGET, NULL, NULL, NULL, 0, (APTR)&ren_si, GID_NAME, NULL }; struct NewWindow ren_nw = { 60, 100, 504, 11, 3, 1, NULL, ACTIVATE, &ren_gad, NULL, NULL, NULL, NULL, 0, 0, 0, 0, WBENCHSCREEN }; /* Used to generate menu items */ struct IntuiText gen_txt = {0, 1, JAM2, 5, 0, NULL, NULL, NULL}; USHORT dm_id[] = {0xfe7f, 0xfe7f, 0xfe7f, 0xce73, 0xf24f, 0xfc3f}; struct Image dm_img = {0, 0, 14, 6, 1, &dm_id[0], 1, 0, NULL}; struct Gadget dm_gad = { NULL, -15, -14, 15, 6, GADGIMAGE | GRELRIGHT | GRELBOTTOM, GADGIMMEDIATE | RIGHTBORDER, BOOLGADGET, (APTR)&dm_img, NULL, NULL, 0, NULL, GID_DOWNSCROLL, NULL }; USHORT up_id[] = {0xfc3f, 0xf24f, 0xce73, 0xfe7f, 0xfe7f, 0xfe7f}; struct Image up_img = {0, 0, 14, 6, 1, &up_id[0], 1, 0, NULL}; struct Gadget up_gad = { &dm_gad, -15, 10, 15, 6, GADGIMAGE | GRELRIGHT, GADGIMMEDIATE | RIGHTBORDER, BOOLGADGET, (APTR)&up_img, NULL, NULL, 0, NULL, GID_UPSCROLL, NULL }; USHORT rm_id[] = { 0xffff, 0xf9f0, 0xfe70, 0xff90,0x0000, 0xff90, 0xfe70, 0xf9f0}; struct Image rm_img = {0, 0, 12, 8, 1, &rm_id[0], 1, 0, NULL}; struct Gadget rm_gad = { &up_gad, -26, -8, 12, 8, GADGIMAGE | GRELRIGHT | GRELBOTTOM, GADGIMMEDIATE | BOTTOMBORDER, BOOLGADGET, (APTR)&rm_img, NULL, NULL, 0, NULL, GID_RIGHTSCROLL, NULL }; USHORT lm_id[] = { 0xffff, 0xf3f0, 0xcff0, 0x3ff0, 0x00000, 0x3ff0, 0xcff0, 0xf3f0}; struct Image lm_img = {0, 0, 12, 8, 1, &lm_id[0], 1, 0, NULL}; struct Gadget lm_gad = { &rm_gad, 2, -8, 12, 8, GADGIMAGE | GRELBOTTOM, GADGIMMEDIATE | BOTTOMBORDER, BOOLGADGET, (APTR)&lm_img, NULL, NULL, 0, NULL, GID_LEFTSCROLL, NULL }; struct Image knob_img1, knob_img2; struct PropInfo hs_knob = { FREEHORIZ | AUTOKNOB, 0, 0, MAXBODY, MAXBODY}; struct Gadget hs_gad = { &lm_gad, 13, -8, -40, 9, GADGIMAGE | GRELWIDTH | GRELBOTTOM, GADGIMMEDIATE | RELVERIFY | BOTTOMBORDER, PROPGADGET, (APTR)&knob_img1, NULL, NULL, 0, (APTR)&hs_knob, GID_HORIZSCROLL, NULL }; struct PropInfo vs_knob = {FREEVERT | AUTOKNOB, 0, 0, MAXBODY, MAXBODY}; struct Gadget vs_gad = { &hs_gad, -15, 16, 16,-31, GADGIMAGE | GRELHEIGHT | GRELRIGHT, GADGIMMEDIATE | RELVERIFY | RIGHTBORDER, PROPGADGET, (APTR)&knob_img2, NULL, NULL, 0, (APTR)&vs_knob, GID_VERTSCROLL, NULL }; struct NewWindow nw = { 0, 0, 640, 200, 0, 1, CLOSEWINDOW | GADGETUP | GADGETDOWN | MENUPICK | NEWSIZE | DISKINSERTED | DISKREMOVED | MOUSEBUTTONS | REFRESHWINDOW, SMART_REFRESH | REPORTMOUSE | BORDERLESS | ACTIVATE | BACKDROP | WBENCHWINDOW, NULL, NULL, "", NULL, NULL, 0, 0, 320, 186, WBENCHSCREEN }; /* Default disk icon */ USHORT disk_icon[] = { 0x0000, 0x0000, 0x3ffc, 0x3f00, 0x3ffc, 0x3fc0, 0x3ffc, 0x3ff0, 0x3ffc, 0x3ffc, 0x3fff, 0xfffc, 0x3fff, 0xfffc, 0x3fff, 0xfffc, 0x3fff, 0xfffc, 0x3fff, 0xfffc, 0x3fff, 0xfffc, 0x3fff, 0xfffc, 0x3fff, 0xfffc, 0x3fff, 0xfffc, 0x3fff, 0xfffc, 0x0000, 0x0000, 0xffff, 0xffc0, 0xc0ff, 0xfcf0, 0xc0ff, 0xfc3c, 0xc0ff, 0xfc0f, 0xc0ff, 0xfc03, 0xc0ff, 0xfc03, 0xc000, 0x0003, 0xc000, 0x0003, 0xc000, 0x0003, 0xc000, 0x0003, 0xc000, 0x0003, 0xc000, 0x0003, 0xc000, 0x0003, 0xc000, 0x0003, 0xc000, 0x0003, 0xffff, 0xffff }; struct Image disk_img = {0, 0, 32, 16, 2, &disk_icon[0], 3, 0, NULL}; USHORT zz_ptr[] = { 0x0000, 0x0000, 0x0008, 0x0000, 0x001c, 0x0000, 0x0026, 0x0000, 0x0013, 0x0060, 0x0009, 0x00f0, 0x0006, 0x01f8, 0x0000, 0x03fc, 0x0000, 0x07f8, 0x0000, 0x0fe0, 0x0070, 0x1ff0, 0x01f8, 0x3ff8, 0x030c, 0x7ffc, 0x03dc, 0xf3fc, 0x0bbc, 0x4bfc, 0x030c, 0x03fc, 0x51f8, 0x51f8, 0x00f0, 0x00f0, 0x2000, 0x2000, 0x2000, 0x2000, 0x0000, 0x0000, 0x0000, 0x0000 }; /*USHORT zz_ptr[] = { 0x0000, 0x0000, 0x0600, 0x0600, 0x0f40, 0x0f40, 0x3fe0, 0x3fe0, 0x7fe0, 0x7fe0, 0x61f0, 0x7ff0, 0x7bf8, 0x7ff8, 0xf7f8, 0xfff8, 0x61fc, 0x7ffc, 0x7f0c, 0x7ffc, 0x3fde, 0x3ffe, 0x7fbc, 0x7ffc, 0x3f0c, 0x3ffc, 0x1ff8, 0x1ff8, 0x07f0, 0x07f0, 0x01c0, 0x01c0, 0x0700, 0x0700, 0x0fc0, 0x0fc0, 0x0680, 0x0680, 0x0000, 0x0000, 0x00c0, 0x00c0, 0x00e0, 0x00e0, 0x0040, 0x0040, 0x0000, 0x0000, 0x0000, 0x0000 }; */ USHORT x_ptr[] = { 0x0000, 0x0000, 0x0600, 0x0000, 0x1f80, 0x0000, 0x3fc0, 0x0000, 0x6660, 0x0000, 0x6060, 0x0000, 0xf0f0, 0x0000, 0xf0f0, 0x0000, 0x6060, 0x0000, 0x6660, 0x0000, 0x3fc0, 0x0000, 0x1f80, 0x0000, 0x0600, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; /* Defaults if no Disk.info file is found */ struct DrawerData defDrDat = { {1, 13, 379, 123, -1, -1, NULL, WBENCHWINDOW | SIZEBRIGHT | SIZEBBOTTOM | SMART_REFRESH | WINDOWSIZING | WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE, NULL, NULL, "", NULL, NULL, 90, 40, -1, -1, WBENCHSCREEN}, 0, 0 }; struct DiskObject defDskObj = { 0, 1, { NULL, 575, 15, 32, 16, GADGIMAGE | GADGHBOX, RELVERIFY | GADGIMMEDIATE, BOOLGADGET, (APTR)&disk_img, NULL, NULL, 0, NULL, 17, NULL}, WBDISK, NULL, NULL, 575, 6, &defDrDat, NULL, 0 }; short menuSet = FALSE; long menuLoc = 30L; struct Menu *lastMenu = NULL, *menuStrip = NULL; char *benchNames[] = {"ParkBench", "Open", "Close", "Duplicate", "Rename", "Info", "Discard"}; char *diskNames[] = {"Disk", "Empty Trash", "Initialize"}; char *specNames[] = {"Special", "Cleanup", "Last Error", "Redraw", "Snapshot", "Version"}; char *debugNames[] = {"Debug", "Trace", "Wbobjs", "SelObjs", "UtilObjs", "Children", "Quit"}; makeMenu() { addMenu(benchNames, 6, BLACK_FILL); addMenu(diskNames, 2, BLACK_FILL); addMenu(specNames, 5, BLACK_FILL); addMenu(debugNames, 6, BLACK_FILL | ITEMENABLED); menuSet = TRUE; SetMenuStrip(wbWin, menuStrip); } addMenu (itemNames, numItems, flag) char *itemNames[]; short numItems; long flag; { short i; long l, height=0L, width=0L; struct Menu *menu; struct MenuItem *firstItem, *lastItem, *menuItem; struct IntuiText *menuText; menu = (struct Menu *) AllocRemember(&RememberKey, (long)sizeof(struct Menu), MEMF_CPC); menu->Flags = MENUENABLED; menu->MenuName = itemNames[0]; menu->Width = 10*strlen(itemNames[0]); menu->LeftEdge = menuLoc; menuLoc += (long)menu->Width + 30L; if (lastMenu) lastMenu->NextMenu = menu; else menuStrip = menu; lastMenu = menu; for (i=1; i<=numItems; i++) width = MAX(width, strlen(itemNames[i])); /*{l = strlen(itemNames[i+1]);if (l>width) width = l;}*/ width = 8L*width + 8L; lastItem = NULL; for (i=0; iNextItem = menuItem; else menu->FirstItem = menuItem; lastItem = menuItem; menuItem->TopEdge = 10L * i; menuItem->Height = 8L; menuItem->Flags = flag; menuItem->Width = width; menuItem->MutualExclude = (~(1L<IText = itemNames[i+1]; menuItem->ItemFill = (APTR)menuText; height += 10L; } menu->Height = height; } openAll() { struct Process *me; struct Screen *sc; struct RootNode *dlRoot; if (!(DosBase = (struct DosLibrary *) OpenLibrary(DOSNAME,33L))) closeAll("Requires V1.2 DOS Library"); if (!(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 33L))) closeAll("Requires V1.2 Graphics Library"); if (!(LayersBase = (struct LayersBase *) OpenLibrary("layers.library", 33L))) closeAll("Requires V1.2 Layers Library"); if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 33L))) closeAll("Requires V1.2 Intuition Library"); if (!(IconBase = OpenLibrary("icon.library", 31L))) closeAll("I give up, where's the icon library?\n"); /* Make sure the backdrop fills the screen */ for (sc=IntuitionBase->FirstScreen; sc; sc=sc->NextScreen) if (sc->Flags & WBENCHSCREEN) { nw.Height = sc->Height; nw.Width = sc->Width; break; } if (!(wbWin = OpenWindow(&nw))) closeAll("Couldn't open the backdrop window\n"); if (!(WBPort = CreatePort(NULL, NULL))) closeAll("Couldn't create the WB port\n"); WBBit = 1L << WBPort->mp_SigBit; IDCMPPort = wbWin->UserPort; IDCMPBit = 1L << wbWin->UserPort->mp_SigBit; me = (struct Process *)FindTask(NULL); initialDir = me->pr_CurrentDir; DOSPort = &me->pr_MsgPort; dlRoot = (struct RootNode *) DosBase->dl_Root; rnInfo = (struct DosInfo *) BADDR(dlRoot->rn_Info); NewList(&wbObjs); NewList(&selObjs); } doMenu(menuNum) USHORT menuNum; { if (menuNum==MENUNULL) return; switch ((long)menuNum) { case OPEN: doOpen(); OffMenu(wbWin, OPEN); OnMenu(wbWin, CLOZE); break; case CLOZE: doList(&selObjs, SEL, closeobj); clearSel(); break; case DUP: error("Not implemented"); break; case RENAME: ren(lastObj); break; case INFO: case DISCARD: case EMPTY: case INIT: case CLEANUP: error("Not implemented"); break; case ERROR: error(lastErr); break; case REDRAW: break; case SNAP: error("Not implemented"); break; case VERS: error(" (C) 1987 by Bill Kinnersley"); break; case TRACE: debug = ~debug; break; case WBOBJS: dumplist(&wbObjs, MAST); break; case SELOBJS: dumplist(&selObjs, SEL); break; case UTILOBJS: dumplist(&utilObjs, UTIL); break; case CHILDREN: if (!lastObj) error("No object selected"); else if (lastObj->wo_DrawerData) dumplist(&lastObj->wo_DrawerData->dd_Children, CHILD); break; case QUIT: closeAll(""); break; } } /* Rename an object */ ren(obj) struct MyWBObject *obj; { struct IntuiMessage *msg; struct IntuiMessage saveMsg; USHORT gid; char buf1[80], *buffer; struct Window *renWin; ULONG saveIDCMP; struct MsgPort *handid; long arg[1]; if (!obj) {error("No icon selected"); return;} if (!(buffer = AllocMem(50L, MEMF_CPC))) /* Must be aligned */ {printf("Couldn't allocate buffer"); return;} strcpy(sbuf, obj->wo_Name); strcpy(buf1, obj->wo_Name); if (!(renWin = OpenWindow(&ren_nw))) closeAll("Can't open rename window"); renWin->UserPort = IDCMPPort; saveIDCMP = wbWin->IDCMPFlags; ModifyIDCMP(renWin, ACTIVEWINDOW | GADGETUP); ActivateGadget(&ren_gad, renWin, NULL); curWin = renWin; error("Enter the new name"); for (;;) { WaitPort(IDCMPPort); while (msg = GetMsg(IDCMPPort)) { /*stc*/ saveMsg = *msg; ReplyMsg(msg); if (saveMsg.IDCMPWindow!=renWin) { /* If user clicks somewhere else, ignore him */ SetPointer(saveMsg.IDCMPWindow, zz_ptr, 19L, 16L, -7L, -8L); continue; } gid = ((struct Gadget *)saveMsg.IAddress)->GadgetID; switch (saveMsg.Class) { case GADGETUP: if (gid!=GID_NAME) break; if (obj->wo_Type==WBDISK) { if (strcmp(sbuf, obj->wo_Name)==0) goto rencln; cs2bs(buffer, sbuf); arg[0] = ((long)buffer)>>2; if (!(handid = DeviceProc(obj->wo_Name))) { printf("Couldn't get handler\n"); goto rencln; } if (!sendpkt(handid, ACTION_RENAME_DISK, arg, 1L)) { error("Couldn't rename the disk"); /* User probably cancelled a requester */ goto rencln; } } else { if (debug) printf("I should rename <%s> to <%s>\n", obj->wo_Name, sbuf); strcat(buf1, ".info"); strcat(sbuf, ".info"); if (debug) printf("and <%s> to <%s>\n", buf1, sbuf); if (rename(buf1, sbuf)==-1) {error("Can't rename"); goto rencln;} *rindex(buf1,'.') = 0; *rindex(sbuf,'.') = 0; rename(buf1, sbuf); /* Ignore error this time--if the real file does not exist, at least the .info has been renamed */ } goto renok; case GADGETDOWN: if (gid==GID_NAME) ClearPointer(renWin); break; default: SetPointer(curWin, zz_ptr, 19L, 16L, -7L, -8L); } } } renok: strcpy(obj->wo_Name, sbuf); obj->wo_NameXOffset = (obj->wo_Gadget.Width/2) - 4*strlen(sbuf); clearSel(); rencln: renWin->UserPort = NULL; CloseWindow(renWin); ModifyIDCMP(wbWin, saveIDCMP); FreeMem(buffer, 50L); ClearPointer(curWin = wbWin); } avail() { if (errWin) return; sprintf(title+25, "%ld free memory", AvailMem(MEMF_PUBLIC)); SetWindowTitles(curWin, -1L, title); } error(s) char *s; { strcpy(lastErr, s); DisplayBeep(wbWin->WScreen); SetWindowTitles(curWin, -1L, s); OnMenu(wbWin, ERROR); errWin = curWin; } closeAll(s) char *s; { struct MyWBObject *obj; struct MyDrawerData *dd; struct Region *reg; printf(s); if (debug) printf("Closing things\n"); while (obj = (struct MyWBObject *)RemHead(&wbObjs)) { if (debug) printf("Removing %lx <%s>\n", obj, obj->wo_Name); if (dd = obj->wo_DrawerData) { if (dd->dd_DrawerWin) { if (debug) printf(" (it was open)\n"); reg = InstallClipRegion(dd->dd_DrawerWin-> WLayer, NULL); DisposeRegion(reg); closeWinSafely(dd->dd_DrawerWin); } if (dd->dd_Lock) { if (debug) printf("Unlocking dd_Lock %lx\n", dd->dd_Lock); UnLock(dd->dd_Lock); } } if (obj->wo_Lock) { if (debug) printf("Unlocking wo_Lock %lx\n", obj->wo_Lock); UnLock(obj->wo_Lock); } FreeFreeList(&obj->wo_FreeList); FreeMem(obj, (long)sizeof(struct MyWBObject)); } if (menuSet) ClearMenuStrip(wbWin, menuStrip); FreeRemember(&RememberKey, TRUE); if (wbWin) CloseWindow(wbWin); if (WBPort) DeletePort(WBPort); if (IconBase) CloseLibrary(IconBase); CurrentDir(initialDir); exit(0); } closeWinSafely(win) struct Window *win; { /* This and the next courtesy Neil Katin */ Forbid(); stripIntuiMessages(win->UserPort, win); win->UserPort = NULL; ModifyIDCMP(win, 0L); win->MenuStrip = NULL; Permit(); CloseWindow(win); } stripIntuiMessages(mp, win) struct MsgPort *mp; struct Window *win; { struct IntuiMessage *msg, *succ; msg = (struct IntuiMessage *)mp->mp_MsgList.lh_Head; while (succ = (struct IntuiMessage *) msg->ExecMessage.mn_Node.ln_Succ) { if (msg->IDCMPWindow==win) { Remove(msg); ReplyMsg(msg); } msg = succ; } } long sendpkt(pid, action, args, nargs) struct MsgPort *pid; long action, args[], nargs; { struct StandardPacket *packet; long count, *pargs, res1, error; if (!(packet = ALLOC(StandardPacket))) {printf("Can't allocate packet\n"); return;} packet->sp_Msg.mn_Node.ln_Name = (char *) &(packet->sp_Pkt); packet->sp_Pkt.dp_Link = &(packet->sp_Msg); packet->sp_Pkt.dp_Port = DOSPort; packet->sp_Pkt.dp_Type = action; pargs = &(packet->sp_Pkt.dp_Arg1); for (count=0; countsp_Pkt.dp_Res1; FreeMem(packet, (long)sizeof(struct StandardPacket)); if (!res1) printf("DOS error: %ld action=%ld\n", packet->sp_Pkt.dp_Res2, packet->sp_Pkt.dp_Type); return res1; }