/* ** Misc.c ** ** Copyright (C) 1993,94,95,96 Bernardo Innocenti ** ** Parts of this file are: ** ** Copyright © 1990-1993 by Olaf `Olsen' Barthel & MXM ** All Rights Reserved ** ** Miscellaneus useful functions */ #include #include #include #include #include #include #include "XModulePriv.h" #include "Gui.h" #if 0 /* --- This part has been removed --- */ /* Function pointers to Kickstart-sensitive RastPort query code */ ULONG (*ReadAPen)(struct RastPort *RPort); ULONG (*ReadBPen)(struct RastPort *RPort); ULONG (*ReadDrMd)(struct RastPort *RPort); /* Local function prototypes */ static ULONG OldGetAPen (struct RastPort *RPort); static ULONG OldGetBPen (struct RastPort *RPort); static ULONG OldGetDrMd (struct RastPort *RPort); static ULONG NewGetAPen (struct RastPort *RPort); static ULONG NewGetBPen (struct RastPort *RPort); static ULONG NewGetDrMd (struct RastPort *RPort); #endif /* --- This part has been removed --- */ GLOBALCALL struct DiskObject *GetProgramIcon (void) /* Get program associated icon. * This function will fail if we are not a son of Workbench. * The returned DiskObject must be freed by FreeDiskObject(). */ { struct DiskObject *dobj; BPTR olddir; if (!WBenchMsg) return NULL; olddir = CurrentDir (WBenchMsg->sm_ArgList->wa_Lock); dobj = GetDiskObject (WBenchMsg->sm_ArgList->wa_Name); CurrentDir (olddir); return dobj; } GLOBALCALL struct Library *MyOpenLibrary (CONST_STRPTR name, ULONG ver) { struct Library *lib; BPTR progdir = NULL; while (!(lib = OpenLibrary (name, ver))) { UBYTE path[PATHNAME_MAX]; /* Search the library file in "PROGDIR:"... */ strcpy (path, "PROGDIR:"); AddPart (path, name, PATHNAME_MAX); if (lib = OpenLibrary (path, ver)) break; strcpy (path, "PROGDIR:Libs"); AddPart (path, name, PATHNAME_MAX); if (lib = OpenLibrary (path, ver)) break; /* Tell the user we can't find this library anywhere... */ if (!ShowRequest (MSG_OPENLIB_FAIL, MSG_RETRY_OR_CANCEL, name, ver)) break; } if (progdir) UnLock (progdir); return lib; } GLOBALCALL void CantOpenLib (CONST_STRPTR name, LONG ver) /* Notify the user that a library didn't open */ { if (ver) ShowRequest (MSG_OPENLIB_VER_FAIL, MSG_CONTINUE, name, ver); else ShowRequest (MSG_OPENLIB_FAIL, MSG_CONTINUE, name); } GLOBALCALL void KillMsgPort (struct MsgPort *mp) /* Reply all pending messages and call DeletePort() */ { struct Message *msg; Forbid(); /* is this really useful? */ /* Reply all pending Messages */ while (msg = GetMsg (mp)) ReplyMsg (msg); DeleteMsgPort (mp); Permit(); } GLOBALCALL struct TextAttr *CopyTextAttrPooled (void *pool, const struct TextAttr *source, struct TextAttr *dest) /* Copy textattr structure over , allocating and copying * the ta_Name field. ->ta_Name if FreeVec()ed before * allocating the new one. * * Returns: if everything was ok, NULL for failure. */ { FreeVecPooled (pool, dest->ta_Name); memcpy (dest, source, sizeof (struct TextAttr)); if (dest->ta_Name = AllocVecPooled (pool, strlen (source->ta_Name) + 1)) { strcpy (dest->ta_Name, source->ta_Name); return dest; } return NULL; } GLOBALCALL UWORD CmpTextAttr (const struct TextAttr *ta1, const struct TextAttr *ta2) /* Compares two TextAttr structures and returns 0 if they refer to * the same font, a non-zero value otherwise. */ { if (ta1->ta_YSize == ta2->ta_YSize && ta1->ta_Style == ta2->ta_Style) { if (!ta1->ta_Name && !ta2->ta_Name) return 0; if (!ta1->ta_Name || !ta2->ta_Name) return 1; if (!strcmp (ta1->ta_Name, ta2->ta_Name)) return 0; } return 1; } /* More memory pools support */ #ifdef PORTABLE GLOBCALL void *AllocVecPooled (void *pool, ULONG size) { void *mem; size += 4; #ifdef OS30_ONLY if (mem = AllocPooled (pool, size)) #else if (mem = AsmAllocPooled (pool, size)) #endif *((ULONG *)mem)++ = size; return mem; } GLOBCALL void FreeVecPooled (void *pool, void *memory) { if (mem) { --(((ULONG *)mem); #ifdef OS30_ONLY FreePooled (pool, mem, *((ULONG *)mem)); #else AsmFreePooled (pool, mem, *((ULONG *)mem)); #endif } } GLOBCALL void *CAllocVecPooled (void *pool, ULONG size) { void *mem; size += 4; #ifdef OS30_ONLY if (mem = AllocPooled (pool, size)) #else if (mem = AsmAllocPooled (pool, size)) #endif { memset (mem, size, 0); *((ULONG *)mem)++ = size; } return mem; } #endif /* PORTABLE */ GLOBALCALL STRPTR DupStringPooled (void *pool, CONST_STRPTR source, STRPTR *dest) /* Allocates a buffer big enough to fit the string * using AllocVecPooled() and then copies the contents of * there. If the buffer pointed by is not NULL, * DupStringPooled() will first check to see if and * are identical, in which case no new buffer will be * allocated and the result will be FALSE. Otherwise, will * be deallocated and a new buffer will be allocated. Both and <*dest> * can be NULL. * * RESULT * Non-zero if has been reallocated, FALSE otherwise. */ { if (*dest) { if (source) { if (!(strcmp (*dest, source))) return NULL; } FreeVecPooled (pool, *dest); } if (source) { if (*dest = AllocVecPooled (pool, strlen (source) + 1)) strcpy (*dest, source); } return *dest; } GLOBALCALL void FilterName (STRPTR name) /* Finds and blanks out invalid characters in a string. * Will also strip blanks at the end. Passing NULL is safe. */ { UWORD i = 0; if (!name) return; while (name[i]) { if (name[i] < ' ' || (name[i] >'~' && name[i] < '¡')) name[i] = ' '; i++; } /* Kill blanks at the end of the string */ for (--i; i > 0 ; i--) if (name[i] == ' ') name[i] = '\0'; else break; } GLOBALCALL LONG PutIcon (CONST_STRPTR source, CONST_STRPTR dest) /* Add the icon to file */ { struct DiskObject *dobj; UBYTE buf[PATHNAME_MAX]; /* We do not alter existing icons */ if (dobj = GetDiskObject (dest)) { FreeDiskObject (dobj); return RETURN_WARN; } /* Get source icon */ strcpy (buf, "PROGDIR:Icons"); AddPart (buf, source, PATHNAME_MAX); if (!(dobj = GetDiskObject (buf))) { strcpy (buf, "ENV:Sys"); AddPart (buf, source, PATHNAME_MAX); if (!(dobj = GetDiskObject (buf))) { /* Get default project icon */ dobj = GetDefDiskObject (WBPROJECT); } } if (dobj) { dobj->do_CurrentX = dobj->do_CurrentY = NO_ICON_POSITION; if (!(dobj->do_DefaultTool[0])) { /* Get program path and store in icon's Default Tool */ BPTR progdir; dobj->do_DefaultTool = NULL; if (WBenchMsg) /* WB */ progdir = WBenchMsg->sm_ArgList->wa_Lock; else /* CLI */ progdir = GetProgramDir(); if (progdir) { if (NameFromLock (progdir, buf, PATHNAME_MAX)) { UBYTE progname[32]; if (WBenchMsg) /* WB */ strncpy (progname, WBenchMsg->sm_ArgList->wa_Name, 32); else /* CLI*/ GetProgramName (progname, 32); if(AddPart (buf, progname, PATHNAME_MAX)) dobj->do_DefaultTool = buf; } } } if (!dobj->do_DefaultTool) dobj->do_DefaultTool = BaseName; PutDiskObject (dest, dobj); FreeDiskObject (dobj); return RETURN_OK; } return RETURN_FAIL; } static ULONG MakeBackupName (STRPTR buf, CONST_STRPTR s, CONST_STRPTR tmpl, ULONG n) /* DESCRIPTION * Subfunction for BackupFile() - Constructs a file name for the backup. * is the template to build the backup name. * Each occurence of the '#' character in the template is replaced with * an ASCII decimal representation of . The '*' character is replaced * with the original filename . * * RESULT * The result is stored in . Returns TRUE if at least one occurrence * of the '#' wildcard has been replaced, otherwise returns FALSE. * * BUGS * Does not check for buffer overflow. * */ { BOOL wild_done = FALSE; BOOL num_done = FALSE; do { if ((*tmpl == '*') && (!wild_done)) { /* Copy file name */ s = FilePart (s); while (*buf++ = *s++); --buf; wild_done = TRUE; } else if (*tmpl == '#') { /* Insert backup number */ if (n > 9) *buf++ = (n / 10) + '0'; *buf++ = (n % 10) + '0'; num_done = TRUE; } else if (*tmpl == '\\') /* Handle escape character */ *buf++ = *++tmpl; else *buf++ = *tmpl; } while (*tmpl++); return num_done; } GLOBALCALL LONG BackupFile (CONST_STRPTR src, CONST_STRPTR template, ULONG versions) /* Creates backups of the given file */ { UBYTE buf[PATHNAME_MAX], oldbuf[PATHNAME_MAX]; ULONG i; BPTR lock, dir, olddir; if (!(lock = Lock (src, ACCESS_READ))) return IoErr(); /* CD to source directory: needed for relative paths */ dir = ParentDir (lock); olddir = CurrentDir (dir); if (!MakeBackupName (buf, src, template, 1)) { /* Simple backup */ DeleteFile (buf); } else { /* Delete oldest backup if exists */ MakeBackupName (buf, src, template, versions); DeleteFile (buf); /* Shift all others ahead... */ for (i = versions; i > 0; --i) { strcpy (oldbuf, buf); MakeBackupName (buf, src, template, i); Rename (buf, oldbuf); DB (kprintf ("Backup name is: %s\n", buf)); } } /* And finally move file to its backup location */ Rename (src, buf); /* Restore old current directory */ CurrentDir (olddir); UnLock (dir); UnLock (lock); return RETURN_OK; } #if 0 /* --- This part has been removed --- */ GLOBALCALL void InstallGfxFunctions (void) /* Install the correct routines to query * the rendering colours and drawing mode. */ { if(GfxBase->lib_Version >= 39) { ReadAPen = NewGetAPen; ReadBPen = NewGetBPen; ReadDrMd = NewGetDrMd; } else { ReadAPen = OldGetAPen; ReadBPen = OldGetBPen; ReadDrMd = OldGetDrMd; } } /* OldGetAPen(struct RastPort *RPort): * * Query the current primary rendering colour (old style). */ static ULONG OldGetAPen (struct RastPort *RPort) { return((ULONG)RPort->FgPen); } /* OldGetBPen(struct RastPort *RPort): * * Query the current seconary rendering colour (old style). */ static ULONG OldGetBPen (struct RastPort *RPort) { return((ULONG)RPort->BgPen); } /* OldGetDrMd(struct RastPort *RPort): * * Query the current drawing mode (old style). */ static ULONG OldGetDrMd (struct RastPort *RPort) { return((ULONG)RPort->DrawMode); } /* NewGetAPen(struct RastPort *RPort): * * Query the current primary rendering colour (new style). */ static ULONG NewGetAPen (struct RastPort *RPort) { return(GetAPen (RPort)); } /* NewGetBPen(struct RastPort *RPort): * * Query the current seconary rendering colour (new style). */ static ULONG NewGetBPen (struct RastPort *RPort) { return (GetBPen (RPort)); } /* NewGetDrMd(struct RastPort *RPort): * * Query the current drawing mode (new style). */ static ULONG NewGetDrMd (struct RastPort *RPort) { return(GetDrMd (RPort)); } #endif /* --- This part has been removed --- */