home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************
- /* *
- /* HackBench - Part 2 of 4 - hbicon.c - Icon Routines *
- /* *
- /* 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 struct DosInfo *rnInfo;
- extern struct MsgPort *IDCMPPort, WBPort;
- extern long IDCMPBit, WBBit;
-
- extern USHORT x_ptr[];
- extern struct Gadget
- vs_gad, hs_gad, ren_gad, up_gad, dm_gad, lm_gad, rm_gad;
- extern struct PropInfo hs_knob, vs_knob;
-
- extern struct Rectangle rect;
- extern char *type[], *title;
- extern short wbFlags, toolsRunning;
- extern struct List selObjs, wbObjs, utilObjs;
- extern int drawobj(), clearobj(), compobj(), openobj(), closeobj();
- extern char *rindex();
-
- struct MyWBObject *lastObj, *hitObj, *hitWinObj, *findObj(), *makeWbObj();
- struct Window *wbWin, *oldWin, *curWin, *hitWin, *errWin;
- struct IntuiMessage saveMsg;
- struct Layer_Info *li;
-
- ULONG downSecs, downMicros, upSecs, upMicros;
- short oldX, oldY, dblclik, debug=FALSE;
- char buf1[61], buf2[61];
-
- struct DeviceList *vol();
- BPTR getlock();
- long tooSoon();
-
- main() {
- struct Message *msg;
- struct WBStartup *wbmsg;
- long mask;
- BPTR seg;
-
- openAll();
- curWin = wbWin; /* Current window is the backdrop */
- li = &wbWin->WScreen->LayerInfo;
-
- findDisks();
- makeMenu();
- OnMenu(wbWin, REDRAW); OnMenu(wbWin, VERS);
-
- avail();
-
- while (1) { /* We have two ports to monitor at once */
- mask = Wait(IDCMPBit | WBBit);
- if (mask & WBBit) while (msg = GetMsg(WBPort)) {
- /* Unload the tool that just exited */
- wbmsg = (struct WBStartup *)msg;
- if (debug) printf("Unloading\n");
- if (seg = wbmsg->sm_Segment) UnLoadSeg(seg);
- FreeMem(wbmsg->sm_ArgList,
- wbmsg->sm_NumArgs*(long)sizeof(struct WBArg));
- FreeMem(msg, (long)sizeof(struct WBStartup));
- toolsRunning--;
- }
- if (mask & IDCMPBit) while (msg = GetMsg(IDCMPPort))
- doIDCMP(msg);
- }
- }
-
- doIDCMP(msg) struct IntuiMessage *msg; {
- struct MyWBObject *obj;
- struct DeviceList *diDev, *ptr;
- char diskName[31];
- struct Node *node;
-
- /*stc*/ saveMsg = *msg;
- ReplyMsg(msg);
- curWin = oldWin = saveMsg.IDCMPWindow;
- switch (saveMsg.Class) {
- case CLOSEWINDOW :
- obj = (struct MyWBObject *)oldWin->UserData;
- closeobj(obj);
- clearSel();
- avail();
- break;
- case MENUPICK: doMenu(saveMsg.Code); break;
- case MOUSEBUTTONS:
- switch(saveMsg.Code) {
- case SELECTDOWN: doSelDown(); break;
- case SELECTUP: doSelUp(); break;
- }
- break;
- case GADGETUP: doGadUp(); break;
- case GADGETDOWN: doGadDown(); break;
- case DISKINSERTED:
- /*Delay(10L);*/ /* May be necessary */
- /* Scan the Device List for a Volume that does not
- appear on the Master List of WBObjects */
- diDev = (struct DeviceList *) BADDR(rnInfo->di_DevInfo);
- for (ptr=diDev; ptr; ptr=(struct DeviceList *)
- BADDR(ptr->dl_Next)) if (ptr->dl_Type==DLT_VOLUME) {
- bs2cs(diskName, ptr->dl_Name);
- if (!FindName(&wbObjs, diskName)) break;
- }
- if (!ptr) break;
- instDisk(diskName); /* Make a new disk object */
- refresh(wbWin);
- break;
- case DISKREMOVED:
- Delay(10L); /* This does seem to be necessary */
- /* For each disk object, check to see if it's still
- on the Device List */
- diDev = (struct DeviceList *) BADDR(rnInfo->di_DevInfo);
- for (node=wbObjs.lh_Head; node->ln_Succ; node=node->ln_Succ) {
- obj = (struct MyWBObject *)node;
- if (obj->wo_Type!=WBDISK) continue;
- for (ptr=diDev; ptr; ptr=(struct DeviceList *)
- BADDR(ptr->dl_Next)) if (ptr->dl_Type==DLT_VOLUME) {
- bs2cs(diskName, ptr->dl_Name);
- if (strcmp(diskName, obj->wo_Name)==0) break;
- }
- if (ptr) continue;
- clearobj(obj); /* Not found--get rid of it */
- deleteobj(obj);
- break;
- }
- refresh(wbWin);
- break;
- case REFRESHWINDOW:
- if (debug)
- printf("Window %lx is SIMPLY REFRESHING!\n", curWin);
- BeginRefresh(curWin);
- refresh(curWin);
- EndRefresh(curWin, TRUE);
- break;
- case NEWSIZE:
- reclip(curWin);
- resize(curWin);
- break;
- }
- }
-
- clearSel() { /* Purge the Select List */
- struct Node *node;
-
- doList(&selObjs, SEL, drawobj, NORM);
- while (node = RemHead(&selObjs)) node->ln_Succ = NULL;
- /* So we can tell later whether a given object
- is still on the List */
- lastObj = NULL;
- OffMenu(wbWin, OPEN); OffMenu(wbWin, CLOZE);
- OffMenu(wbWin, DUP); OffMenu(wbWin, RENAME);
- OffMenu(wbWin, INFO); OffMenu(wbWin, INIT);
- OffMenu(wbWin, SNAP); OffMenu(wbWin, DISCARD);
- }
-
- doOpen() {
- struct Node *node;
- struct MyWBObject *obj;
-
- /* If there's a tool or project on the Select List, run it.
- Otherwise, just open everybody on the List */
- for (node=selObjs.lh_Head; node->ln_Succ; node=node->ln_Succ) {
- obj = OBJ(node,SEL);
- if (obj->wo_Type==WBTOOL || obj->wo_Type==WBPROJECT)
- {run(obj); return;}
- }
- doList(&selObjs, SEL, openobj);
- }
-
- /* doSelDown does three things:
- Detects and handles double clicks
- Accumulates the extended selection list
- Toggles menu items
- */
- doSelDown() {
- struct MyWBObject *obj;
- struct Node *node;
-
- if (errWin) {SetWindowTitles(errWin,-1L,title); errWin=NULL;}
- if (obj = findObj(saveMsg.MouseX, saveMsg.MouseY, curWin)) {
- /* Hit an icon */
- if (dblclik = ((obj==lastObj) && DoubleClick(downSecs,
- downMicros, saveMsg.Seconds, saveMsg.Micros))) {
- /* Double click */
- if (debug) printf("Double click\n");
- saveMsg.Seconds -= 20L; /* To prevent triple clicks */
- doOpen();
- OffMenu(wbWin, OPEN); OnMenu(wbWin, CLOZE);
- avail();
- }
-
- else { /* Single click so far */
- if (debug) printf("Single click\n");
- SetPointer(oldWin, x_ptr, 12L, 12L, -6L, -6L);
- if (saveMsg.Qualifier & SHIFT) {
- /* Extended selection rules out some operations */
- OffMenu(wbWin, DUP); OffMenu(wbWin, RENAME);
- OffMenu(wbWin, INFO);
- }
- else {
- doList(&selObjs, SEL, drawobj, NORM);
- while (node = RemHead(&selObjs))
- node->ln_Succ = node->ln_Pred = NULL;
- OnMenu(wbWin, DUP); OnMenu(wbWin, RENAME);
- OnMenu(wbWin, INFO);
- }
- OnMenu(wbWin, SNAP);
- if (!obj->wo_SelectNode.ln_Succ) /* Not yet selected */
- AddHead(&selObjs, &obj->wo_SelectNode);
- /* Exec gets confused if a node is in the same list twice */
- drawobj(obj, HIGH); /* Highlight it */
- /* Did I hit an open drawer? */
- if (obj->wo_DrawerData
- && obj->wo_DrawerData->dd_DrawerWin)
- {OnMenu(wbWin, CLOZE); OffMenu(wbWin, OPEN);}
- /* Either a closed drawer or a tool */
- /* Tools can always be opened */
- else {OnMenu(wbWin, OPEN); OffMenu(wbWin, CLOZE);}
-
- lastObj = obj; oldX = saveMsg.MouseX; oldY = saveMsg.MouseY;
- downSecs = saveMsg.Seconds; downMicros = saveMsg.Micros;
- }
- }
- else clearSel(); /* Didn't hit an icon */
- }
-
- doSelUp() {
- struct Layer *layer;
- struct Window *w;
- short dx, dy;
- BPTR lock, lock2;
- struct MyDrawerData *dd;
-
- if (dblclik) {dblclik = FALSE; return;}
- ClearPointer(oldWin);
- if (!lastObj) return;
- curWin = oldWin;
- upSecs = saveMsg.Seconds; upMicros = saveMsg.Micros;
-
- /* Selectup msg is sent back to the window where selectdown occurred,
- (oldWin), so we have to search the layers for the real window */
-
- layer = WhichLayer(li, (long)(saveMsg.MouseX + oldWin->LeftEdge),
- (long)(saveMsg.MouseY + oldWin->TopEdge));
- for (hitWin=wbWin->WScreen->FirstWindow; hitWin;
- hitWin=hitWin->NextWindow)
- if (hitWin->WLayer==layer) break;
- if (!hitWin) return; /* Shouldn't happen */
-
- if (!(hitWin->Flags & WBENCHWINDOW))
- {error("That's somebody else's window"); return;}
- if (hitWin!=wbWin) if (lastObj->wo_Type==WBDISK)
- {error("Disks can't be moved into windows"); return;}
- if (lastObj->wo_Type==WBGARBAGE)
- if (hitWin!=lastObj->wo_IconWin)
- {error("A trashcan must stay in its own window"); return;}
- if (lastObj->wo_Type==WBDRAWER)
- if (hitWin==lastObj->wo_DrawerData->dd_DrawerWin)
- /* You tried to move an icon into its own open window, dodo */
- {error("Hey, that's me!"); return;}
-
- hitWinObj = (struct MyWBObject *)hitWin->UserData;
- /* hitWinObj may be NULL if hitWin is the backdrop */
- dx = saveMsg.MouseX + oldWin->LeftEdge - hitWin->LeftEdge;
- dy = saveMsg.MouseY + oldWin->TopEdge - hitWin->TopEdge;
- hitObj = findObj(dx, dy, hitWin);
- if (debug) printf("SelUp hitObj=%lx hitWin=%lx\n", hitObj, hitWin);
-
- if ((!hitObj) || (hitObj==lastObj))
- {moveObj(&selObjs, SEL, dx - oldX, dy - oldY); return;}
-
- /* So from here on we must have hit a new icon */
- if (debug) printf("Hit <%s>, a %s\n",
- hitObj->wo_Name, type[hitObj->wo_Type]);
-
- switch (hitObj->wo_Type) {
- case WBDISK: if (lastObj->wo_Type==WBDISK)
- {error("DiskCopy not implemented"); return;}
- if (lastObj->wo_Type==WBGARBAGE)
- {error("A trashcan must stay in its own window"); return;}
- if (hitObj==lastObj->wo_Parent) break;
- lock = getlock(lastObj);
- if (vol(lock)==vol(hitObj->wo_Lock)) {
- /* On same disk--just rename */
- strcpy(buf1, lastObj->wo_Name); strcpy(buf2, lastObj->wo_Name);
- if (debug) printf("Renaming %lx <%s> to %lx <:%s>\n",
- lock, lastObj->wo_Name, hitObj->wo_Lock, lastObj->wo_Name);
- strcat(buf1, ".info"); strcat(buf2, ".info");
- renBoth(lock, buf1, hitObj->wo_Lock, buf2);
- break;
- }
- /* Otherwise copy to another disk--not implemented */
- if (debug) printf("I should copy %lx <%s> to %lx <%s:>\n",
- lock, lastObj->wo_Name, hitObj->wo_Lock, hitObj->wo_Name);
- return;
-
- case WBDRAWER:
- case WBGARBAGE: /* Hit a drawer icon */
- if (hitObj==lastObj->wo_Parent) break;
- if (lastObj->wo_Type==WBDISK) if (hitWin!=wbWin)
- {error("Can't move a disk into a drawer"); return;}
- if (lastObj->wo_Type==WBGARBAGE)
- {error("A trashcan must stay in its own window"); return;}
-
- strcpy(buf1, lastObj->wo_Name); strcpy(buf2, hitObj->wo_Name);
- strcat(buf2, "/"); strcat(buf2, lastObj->wo_Name);
- lock = getlock(lastObj); lock2 = getlock(hitObj);
- if (debug) printf("Renaming %lx <%s> to %lx <%s>\n",
- lock, buf1, lock2, buf2);
- strcat(buf1, ".info"); strcat(buf2, ".info");
- renBoth(lock, buf1, lock2, buf2);
- break;
- default: /* Just let the icons overlap */
- moveObj(&selObjs, SEL, dx-oldX, dy-oldY);
- return;
- }
- goAway();
- doResize();
- }
-
- goAway() { /* Do move from one window to another */
- struct MyDrawerData *dd;
- struct Window *w;
-
- mark(lastObj->wo_IconWin);
- clearobj(lastObj);
- Remove(&lastObj->wo_Siblings);
- lastObj->wo_Siblings.ln_Succ = NULL;
- dd = hitObj->wo_DrawerData;
- if (w=dd->dd_DrawerWin) { /* Destination window open */
- AddHead(&dd->dd_Children, &lastObj->wo_Siblings);
- lastObj->wo_Parent = hitObj;
- lastObj->wo_IconWin = w;
- mark(w);
- Remove(lastObj); AddTail(&wbObjs, lastObj);
- /* Rearrange, so that refresh() draws it last (on top) */
- }
- else deleteobj(lastObj);
- }
-
- moveObj(list, off, x, y)
- struct List *list; long off; short x, y; {
- struct Node *node;
- struct MyWBObject *obj, *iconWinObj;
- struct Window *w;
- struct MyDrawerData *dd;
- char *p;
- BPTR lock, lock2;
-
- mark(hitWin);
- hitWinObj = (struct MyWBObject *)hitWin->UserData;
-
- if (tooSoon()) return; /* If selup too soon, ignore */
- doList(list, off, clearobj);
- for (node=list->lh_Head; node->ln_Succ; node=node->ln_Succ) {
- obj = OBJ(node,off);
- if (debug)
- printf("moveObj: %lx (%d %d) by (%d %d) from %lx to %lx\n",
- obj, obj->wo_Gadget.LeftEdge, obj->wo_Gadget.TopEdge,
- x, y, obj->wo_IconWin, hitWin);
- iconWinObj = (struct MyWBObject *)obj->wo_IconWin->UserData;
- mark(obj->wo_IconWin);
- if (obj->wo_IconWin!=hitWin) { /* Changing windows */
- /* Adjust the virtual coordinates */
- if (obj->wo_IconWin!=wbWin) {
- dd = iconWinObj->wo_DrawerData;
- obj->wo_CurrentX -= dd->dd_CurrentX;
- obj->wo_CurrentY -= dd->dd_CurrentY;
- }
- if (hitWin!=wbWin) {
- dd = hitWinObj->wo_DrawerData;
- obj->wo_CurrentX += dd->dd_CurrentX;
- obj->wo_CurrentY += dd->dd_CurrentY;
- }
- if (hitWin==wbWin) { /* To the backdrop */
- /* A backdrop icon needs its very own lock,
- in case its parent's drawer is later closed */
- obj->wo_Lock = DupLock(obj->wo_Parent->
- wo_DrawerData->dd_Lock);
- if (debug) printf("Duplicate lock: <%s> %lx\n",
- obj->wo_Name, obj->wo_Lock);
- }
-
- else if (hitWinObj==obj->wo_Parent) {
- /* Into the open drawer of my parent */
- if (debug) printf("Oh Lawdy, I'se home--home at las'!\n");
- /* I don't need my lock any more */
- if (obj->wo_Lock) { /* Coming from the backdrop */
- if (debug) printf("Unlocking <%s>: %lx\n",
- obj->wo_Name, obj->wo_Lock);
- UnLock(obj->wo_Lock);
- obj->wo_Lock = NULL;
- }
- }
-
- else { /* Into some other open drawer */
- lock = getlock(obj);
- lock2 = hitWinObj->wo_DrawerData->dd_Lock;
- if (vol(lock)==vol(lock2)) {
- strcpy(buf1, obj->wo_Name); strcpy(buf2, obj->wo_Name);
- if (debug) printf("Renaming %lx <%s> to %lx <%s>\n",
- lock, buf1, lock2, buf2);
- strcat(buf1, ".info"); strcat(buf2, ".info");
- renBoth(lock, buf1, lock2, buf2);
- }
- else {
- bs2cs(buf2, vol(lock2)->dl_Name);
- if (debug) printf("I should copy %lx <%s> to %lx <%s/%s> on <%s:>\n",
- lock, obj->wo_Name, lock2,
- hitWinObj->wo_Name, obj->wo_Name, buf2);
- }
- Remove(&obj->wo_Siblings);
- AddHead(&dd->dd_Children, &obj->wo_Siblings);
- obj->wo_Parent = hitWinObj;
- }
- obj->wo_IconWin = hitWin;
- }
- obj->wo_CurrentX += x;
- obj->wo_CurrentY += y;
- Remove(obj); AddTail(&wbObjs, obj);
- /* So that refresh() draws it last (on top) */
- }
- doList(list, off, drawobj, HIGH);
- doResize();
- }
-
- mark(w) struct Window *w; { /* Mark window for later resizing */
- if (w!=wbWin)
- ((struct MyWBObject *)w->UserData)->wo_Flags |= RESIZE;
- else wbFlags |= RESIZE;
- }
-
- doResize() {
- struct Node *node;
- struct MyWBObject *obj;
- struct Window *w;
-
- for (node=wbObjs.lh_Head; node->ln_Succ; node=node->ln_Succ) {
- obj = (struct MyWBObject *)node;
- if (obj->wo_Flags & RESIZE) {
- w = obj->wo_DrawerData->dd_DrawerWin;
- resize(w);
- refresh(w);
- obj->wo_Flags &= ~RESIZE;
- }
- }
- if (wbFlags & RESIZE) {
- /* It might be worth having a fake object whose drawer is
- the backdrop, but all we really need is the Flags field */
- refresh(wbWin);
- wbFlags &= ~RESIZE;
- }
- }
-
- doGadDown () {
- USHORT gid;
- struct MyDrawerData *dd;
- short shift;
- long pos;
-
- gid = ((struct Gadget *)saveMsg.IAddress)->GadgetID;
- dd = ((struct MyWBObject *)oldWin->UserData)->wo_DrawerData;
- shift = saveMsg.Qualifier & SHIFT;
- lastObj = NULL;
-
- switch (gid) {
- case GID_VERTSCROLL: case GID_HORIZSCROLL: return;
- case GID_LEFTSCROLL: pos = (ULONG)dd->dd_HorizProp.HorizPot;
- dd->dd_CurrentX -= shift ? 1 : 20;
- break;
- case GID_RIGHTSCROLL: pos = (ULONG)dd->dd_HorizProp.HorizPot;
- dd->dd_CurrentX += shift ? 1 : 20;
- break;
- case GID_UPSCROLL: pos = (ULONG)dd->dd_VertProp.VertPot;
- dd->dd_CurrentY -= shift ? 1 : 10;
- break;
- case GID_DOWNSCROLL: pos = (ULONG)dd->dd_VertProp.VertPot;
- dd->dd_CurrentY += shift ? 1 : 10;
- break;
- }
- resize(oldWin);
- SetRast(oldWin->RPort, 0L);
- refresh(oldWin);
- }
-
- doGadUp() {
- USHORT gid;
- struct MyDrawerData *dd;
- long pos;
-
- gid = ((struct Gadget *)saveMsg.IAddress)->GadgetID;
- dd = ((struct MyWBObject *)oldWin->UserData)->wo_DrawerData;
-
- switch (gid) {
- case GID_HORIZSCROLL: /* I don't understand this either */
- pos = (ULONG)dd->dd_HorizProp.HorizPot;
- dd->dd_CurrentX = dd->dd_MinX + (pos *
- (MAX(dd->dd_CurrentX, dd->dd_MaxX - (oldWin->Width-14L))
- - MIN(dd->dd_CurrentX, dd->dd_MinX)) ) / MAXBODY;
- break;
- case GID_VERTSCROLL:
- pos = (ULONG)dd->dd_VertProp.VertPot;
- dd->dd_CurrentY = dd->dd_MinY + (pos *
- (MAX(dd->dd_CurrentY,dd->dd_MaxY-(oldWin->Height-YOFF-9L))
- - MIN(dd->dd_CurrentY, dd->dd_MinY)) ) / MAXBODY;
- break;
- }
- resize(oldWin);
- SetRast(oldWin->RPort, 0L);
- refresh(oldWin);
- }
-
- /* Recalculate the size of a window's virtual coord system */
- resize(w) struct Window *w; {
- struct Node *node;
- struct MyWBObject *obj;
- struct MyDrawerData *dd;
- long effH, effW, total, left, right, pot, body;
-
- obj = (struct MyWBObject *)w->UserData;
- dd = obj->wo_DrawerData;
- dd->dd_MinX = dd->dd_MinY = 10000;
- dd->dd_MaxX = dd->dd_MaxY = -10000;
-
- /* For each icon living in the window.. */
- for (node=dd->dd_Children.lh_Head; node->ln_Succ;
- node=node->ln_Succ) {
- obj = OBJ(node,CHILD);
- if (obj->wo_IconWin!=w) continue;
-
- /* Each icon contains two pieces..a title and an image */
- /* Take the MIN of the left edges.. */
- dd->dd_MinX = MIN(dd->dd_MinX,
- obj->wo_CurrentX + obj->wo_NameXOffset);
-
- /* and the MAX of the right edges */
- right = MAX(obj->wo_Gadget.Width,
- obj->wo_NameXOffset + 8*strlen(obj->wo_Name));
- dd->dd_MaxX = MAX(dd->dd_MaxX, obj->wo_CurrentX + right);
-
- /* Likewise top and bottom edges */
- dd->dd_MinY = MIN(dd->dd_MinY, obj->wo_CurrentY);
- dd->dd_MaxY = MAX(dd->dd_MaxY, obj->wo_CurrentY +
- obj->wo_Gadget.Height + 10L);
- }
-
- /* Now recalculate the horizontal extent... */
- /* total: Total size of virtual coord system */
- /* left: Size undisplayed to left */
- /* right: Size undisplayed to right */
-
- effW = w->Width-14L;
- total = MAX(dd->dd_CurrentX + effW, dd->dd_MaxX)
- - MIN(dd->dd_CurrentX, dd->dd_MinX);
- left = MAX(dd->dd_CurrentX - dd->dd_MinX, 0L);
- right = total - left - effW;
- if ((left + right)==0L) pot = 0L;
- else pot = (MAXBODY * left) / (left + right);
- body = (MAXBODY * effW) / total;
- ModifyProp(&dd->dd_HorizScroll, w, NULL, FREEHORIZ | AUTOKNOB,
- pot, MAXBODY, body, MAXBODY);
-
- /* and the vertical extent */
- effH = w->Height-YOFF-9L;
- total = MAX(dd->dd_CurrentY + effH, dd->dd_MaxY)
- - MIN(dd->dd_CurrentY, dd->dd_MinY);
- left = MAX(dd->dd_CurrentY - dd->dd_MinY, 0L);
- right = total - left - effH;
-
- if ((left + right)==0L) pot = 0L;
- else pot = (MAXBODY * left) / (left + right);
- body = (MAXBODY * effH) / total;
- ModifyProp(&dd->dd_VertScroll, w, NULL, FREEVERT | AUTOKNOB,
- MAXBODY, pot, MAXBODY, body);
- }
-
- /* Must do this each time a window's size is changed */
- /* To prevent drawing over the borders */
- reclip(w) struct Window *w; {
- struct Region *reg, *oldreg;
-
- reg = NewRegion();
- rect.MaxX = w->Width - 19;
- rect.MaxY = w->Height - 11;
- OrRectRegion(reg, &rect);
- oldreg = InstallClipRegion(w->WLayer, reg);
- if (oldreg) DisposeRegion(oldreg);
- }
-
- BPTR getlock(obj) struct MyWBObject *obj; {
- BPTR lock;
- char name[31];
-
- /* Either the obj's own Lock, or the Lock of the drawer it's in,
- or manufacture a new one */
- lock = obj->wo_Lock;
- if (!lock) if (obj->wo_Parent)
- lock = obj->wo_Parent->wo_DrawerData->dd_Lock;
- if (!lock) { /* Presumably a disk */
- if (debug) printf("%lx <%s> (a %s) needs a new lock\n",
- obj, obj->wo_Name, type[obj->wo_Type]);
- strcpy(name, obj->wo_Name);
- strcat(name,":");
- lock = obj->wo_Lock = Lock(name, ACCESS_READ);
- /* Maybe user refused to reinsert disk */
- if (!lock) printf("Can't lock <%s>\n", name);
- if (debug) printf("getlock: new lock: %lx\n",lock);
- }
- return lock;
- }
-
- struct DeviceList *vol(lock) BPTR lock; {
- struct FileLock *fl;
-
- /* Return the Volume corresponding to a given Lock */
- if (!lock) {printf("vol: Null lock\n"); return NULL;}
- fl = (struct FileLock *)BADDR(lock);
- return (struct DeviceList *)BADDR(fl->fl_Volume);
- }
-
- /* Convert a BSTR to a C string */
- bs2cs(buf, bstr) char *buf; BPTR bstr; {
- char *p;
-
- p = (char *)BADDR(bstr);
- strncpy(buf, p+1, *p);
- buf[*p] = 0;
- }
-
- /* C string to BSTR - (buf must be Long Aligned) */
- cs2bs(buf, s) char *buf, *s; {
- strcpy(buf+1, s);
- *buf = strlen(s);
- }
-
- renpkt(l1, n1, l2, n2) BPTR l1, l2; char *n1, *n2; {
- long arg[4], res;
- struct DeviceList *dl1, *dl2;
- char *buf1, *buf2;
- struct MsgPort *handid;
-
- if (debug) printf("Renpkt: <%s> to <%s>\n", n1, n2);
- if (!l1 || !l2) {printf("renpkt error: null lock\n"); return;}
- if ((dl1=vol(l1)) != (dl2=vol(l2)))
- {printf("renpkt error: different volumes\n"); return;}
- handid = ((struct FileLock *)BADDR(l1))->fl_Task;
- /* Must be long aligned: */
- buf1 = AllocMem(31L, MEMF_CPC); buf2 = AllocMem(31L, MEMF_CPC);
- cs2bs(buf1, n1); cs2bs(buf2, n2);
- arg[0] = l1; arg[2] = l2;
- arg[1] = ((long)buf1)>>2; arg[3] = ((long)buf2)>>2;
- if (!sendpkt(handid, ACTION_RENAME_OBJECT, arg, 4L))
- printf("Rename failed\n");
- FreeMem(buf1, 31L); FreeMem(buf2, 31L);
- }
-
- renBoth(l1, n1, l2, n2) BPTR l1, l2; char *n1, *n2; {
- /* Rename both the file and its .info file */
- renpkt(l1, n1, l2, n2);
- *rindex(n1,'.') = 0; *rindex(n2,'.') = 0;
- renpkt(l1, n1, l2, n2);
- }
-
- long tooSoon() {
- long dt;
-
- dt = upSecs - downSecs;
- if (dt>1) return FALSE;
- dt = upMicros - downMicros + 1000000L*dt;
- return (dt<200000L);
- /* Two-tenths of a sec between selup and seldown
- is too soon to count as a drag operation */
- }
-