/* ** $VER: XModule 3.9 (16.8.97) Copyright (C) 1993,94,95,96 Bernardo Innocenti ** ** This source code is provided "AS-IS", without warranties of any kind and ** it is subject to change without notice. All usage is at your own risk. ** No liability or responsibility is assumed by the author. ** ** Use 4 chars wide TABs to read this file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "XModulePriv.h" #include "Gui.h" /* Local functions prototypes */ static LONG GetShellArgs (void); static LONG GetWBArgs (void); static void DisposeArgs (void); static void HandleFrom (void); static void SetupHooks (void); static void Cleanup (LONG err); static LONG Setup (void); /* Memory pool for use by main program only */ XDEF void *Pool = NULL; /* Version tag */ XDEF const UBYTE Version[] = "$VER: " VSTR " " BUILDMODE " " XMODULECOPY; XDEF const UBYTE BaseName[] = BASENAME; XDEF const UBYTE PrgName[] = PRGNAME; /* Library bases */ XDEF struct IntuitionBase *IntuitionBase = NULL; XDEF struct GfxBase *GfxBase = NULL; XDEF struct Library *LayersBase = NULL; XDEF struct UtilityBase *UtilityBase = NULL; XDEF struct Library *GadToolsBase = NULL; XDEF struct Library *DiskfontBase = NULL; XDEF struct Library *AslBase = NULL; XDEF struct Library *IFFParseBase = NULL; XDEF struct Library *WorkbenchBase = NULL; XDEF struct Library *IconBase = NULL; XDEF struct ReqToolsBase *ReqToolsBase = NULL; XDEF struct Library *CxBase = NULL; XDEF struct Library *KeymapBase = NULL; XDEF struct XModuleBase *XModuleBase = NULL; /* This structure holds data to open required libraries automatically. */ struct OpenLibs { struct Library **Base; UBYTE *Name; LONG Version; }; #ifdef OS30_ONLY #define OSLIBVER 39 #else #define OSLIBVER 37 #endif /* !OS30_ONLY */ static const struct OpenLibs openlibs[] = { { (struct Library **)&IntuitionBase, "intuition.library", OSLIBVER }, { (struct Library **)&GfxBase, "graphics.library", OSLIBVER }, { (struct Library **)&LayersBase, "layers.library", OSLIBVER }, { (struct Library **)&UtilityBase, "utility.library", OSLIBVER }, { (struct Library **)&GadToolsBase, "gadtools.library", OSLIBVER }, { (struct Library **)&KeymapBase, "keymap.library", 37 }, { (struct Library **)&IFFParseBase, "iffparse.library", 37 }, { (struct Library **)&WorkbenchBase, "workbench.library", 37 }, { (struct Library **)&IconBase, "icon.library", 37 }, { (struct Library **)&DiskfontBase, "diskfont.library", 0 }, { NULL } }; /* Used for argument parsing. * NOTE: All fields must be 4 bytes long. */ static struct { STRPTR *From, PubScreen, PortName, Settings; LONG CxPopup; /* Set to TRUE by default. */ STRPTR CxPopKey; LONG *CxPriority, *IconX, *IconY; STRPTR IconName; } XMArgs; /* egcs doesn't like this: = { 0 }; */ static struct RDArgs *RDArgs = NULL; #define ARGS_TEMPLATE "FROM/M,PUBSCREEN/K,PORTNAME/K,SETTINGS/K,CX_POPUP/T,CX_POPKEY/K,CX_PRIORITY/K/N,ICONXPOS/K/N,ICONYPOS/K/N,ICONNAME/K" extern LONG STDARGS __main (void) /* XModule main entry point. Get arguments from CLI/Workbench, * setup environment, open required files and call main event * handling loop. */ { LONG err; DB(kprintf ("\n")); DB(kprintf ((STRPTR)(Version + 6))); DB(kprintf ("\n*** Starting debug session -- Good luck!\n\n")); if (!(err = Setup())) /* Setup environment */ err = HandleGui(); Cleanup (err); return err; } /* End main() */ static LONG GetShellArgs (void) /* Parse command line arguments */ { if (!(RDArgs = ReadArgs (ARGS_TEMPLATE, (LONG *)&XMArgs, NULL))) return IoErr(); return RETURN_OK; } /* End GetShellArgs() */ static LONG GetWBArgs (void) /* Parse Workbench arguments */ { struct DiskObject *dobj; STRPTR val; UWORD i; /* Get Multiselect args. * Create a NULL-terminated array of STRPTRs * in the same way ReadArgs() would have done. */ if (WBenchMsg->sm_NumArgs > 1) if (!(XMArgs.From = AllocVec (WBenchMsg->sm_NumArgs * sizeof (STRPTR), MEMF_CLEAR))) return RETURN_FAIL; for (i = 1; i < WBenchMsg->sm_NumArgs; i++) { UBYTE buf[PATHNAME_MAX]; if (NameFromLock (WBenchMsg->sm_ArgList[i].wa_Lock, buf, PATHNAME_MAX)) if (AddPart (buf, WBenchMsg->sm_ArgList[i].wa_Name, PATHNAME_MAX)) { if (XMArgs.From[i-1] = AllocVec (strlen (buf), MEMF_ANY)) strcpy (XMArgs.From[i-1], buf); else break; } } /* Get ToolTypes */ if (!(dobj = GetProgramIcon())) return RETURN_FAIL; if (val = FindToolType (dobj->do_ToolTypes, "PUBSCREEN")) if (XMArgs.PubScreen = AllocVec (strlen (val), MEMF_ANY)) strcpy (XMArgs.PubScreen, val); if (val = FindToolType (dobj->do_ToolTypes, "PORTNAME")) if (XMArgs.PortName = AllocVec (strlen (val), MEMF_ANY)) strcpy (XMArgs.PortName, val); if (val = FindToolType (dobj->do_ToolTypes, "SETTINGS")) if (XMArgs.Settings = AllocVec (strlen (val), MEMF_ANY)) strcpy (XMArgs.Settings, val); if (val = FindToolType (dobj->do_ToolTypes, "CX_POPUP")) XMArgs.CxPopup = MatchToolValue (val, "YES"); if (val = FindToolType (dobj->do_ToolTypes, "CX_POPKEY")) if (XMArgs.CxPopKey = AllocVec (strlen (val), MEMF_ANY)) strcpy (XMArgs.CxPopKey, val); if (val = FindToolType (dobj->do_ToolTypes, "CX_PRIORITY")) if (XMArgs.CxPriority = AllocVec (sizeof (LONG), MEMF_ANY)) StrToLong (val, XMArgs.CxPriority); if (val = FindToolType (dobj->do_ToolTypes, "ICONXPOS")) if (XMArgs.IconX = AllocVec (sizeof (LONG), MEMF_ANY)) StrToLong (val, XMArgs.IconX); if (val = FindToolType (dobj->do_ToolTypes, "ICONYPOS")) if (XMArgs.IconY = AllocVec (sizeof (LONG), MEMF_ANY)) StrToLong (val, XMArgs.IconY); if (val = FindToolType (dobj->do_ToolTypes, "ICONNAME")) if (XMArgs.IconName = AllocVec (strlen (val), MEMF_ANY)) strcpy (XMArgs.IconName, val); FreeDiskObject (dobj); return RETURN_OK; } /* End GetWBArgs() */ static void DisposeArgs (void) { if (RDArgs) { FreeArgs (RDArgs); RDArgs = NULL; } else /* Workbench */ { /* NULL is a valid parameter for FreeVec() */ FreeVec (XMArgs.IconName); FreeVec (XMArgs.IconY); FreeVec (XMArgs.IconX); FreeVec (XMArgs.CxPriority); FreeVec (XMArgs.CxPopKey); FreeVec (XMArgs.Settings); FreeVec (XMArgs.PortName); FreeVec (XMArgs.PubScreen); if (XMArgs.From) { STRPTR *tmp = XMArgs.From; while (*tmp) { FreeVec (*tmp); tmp++; } FreeVec (XMArgs.From); } } memset (&XMArgs, 0, sizeof (XMArgs)); } static void HandleFrom (void) { if (XMArgs.From) { STRPTR *name = XMArgs.From; struct AnchorPath *ap; LONG err; if (ap = AllocMem (sizeof (struct AnchorPath) + PATHNAME_MAX, MEMF_CLEAR)) { OpenProgressWindow (); ap->ap_BreakBits = SIGBREAKF_CTRL_C; ap->ap_Strlen = PATHNAME_MAX; while (*name) { err = MatchFirst (*name, ap); while (!err) { xmLoadModule (ap->ap_Buf, XMSNG_AddToList, TRUE, TAG_DONE); err = MatchNext (ap); } if (err != ERROR_NO_MORE_ENTRIES) { UBYTE buf[FAULT_MAX]; Fault (err, NULL, buf, FAULT_MAX); ShowMessage (MSG_ERR_LOAD, *name, buf); } MatchEnd (ap); name++; } CloseProgressWindow(); FreeMem (ap, sizeof (struct AnchorPath) + PATHNAME_MAX); } else LastErr = ERROR_NO_FREE_STORE; } } static void SetupHooks (void) { struct Library *XMHookBase; struct FileInfoBlock *fib; BPTR lock; UBYTE libpath[PATHNAME_MAX]; /* Built-in hooks */ AddXModuleHooks (); AddTrackerHooks (); if (fib = (struct FileInfoBlock *)AllocDosObject (DOS_FIB, NULL)) { if (lock = Lock (DEF_HOOKSDIR, ACCESS_READ)) if (Examine (lock, fib)) while (ExNext (lock, fib)) { strcpy (libpath, DEF_HOOKSDIR); AddPart (libpath, fib->fib_FileName, PATHNAME_MAX); if (XMHookBase = OpenLibrary (libpath, 0)) { #if defined(__SASC) #pragma libcall XMHookBase SetupXMHook 24 801 void SetupXMHook (struct XModuleBase *); #elif defined(__GNUC__) #define SetupXMHook(xmbase) \ LP1NR(0x24, SetupXMHook, struct XModuleBase *, xmbase, a0, \ , XMHookBase) #else #error Define SetupXMHook() library call for your compiler #endif SetupXMHook (XModuleBase); CloseLibrary (XMHookBase); } } FreeDosObject (DOS_FIB, fib); } /* Set default saver */ if (!IsListEmpty ((struct List *)&XModuleBase->xm_Savers)) XModuleBase->xm_DefaultSaver = (struct XMHook *)XModuleBase->xm_Savers.mlh_Head; } static LONG Setup (void) { LONG err; ULONG i; SetProgramName (PrgName); /* Initialize view lists */ NEWLIST (&WindowList); NEWLIST (&LogList); NEWLIST (&PatternsList); NEWLIST (&SequenceList); NEWLIST (&InstrList); /* Install graphics function replacements */ /* InstallGfxFunctions(); */ /* These are currently never used */ /* Initialize ScrInfo structure */ strcpy (ScrInfo.PubScreenName, BaseName); /* Initialize PubPort name */ strcpy (PubPortName, BaseName); /* Initialize PubPort name */ strcpy (IconName, PrgName); /* Open required libraries */ for (i = 0 ; openlibs[i].Base ; i++) if (!(*(openlibs[i].Base) = MyOpenLibrary (openlibs[i].Name, openlibs[i].Version))) if (openlibs[i].Version) return RETURN_FAIL; #ifndef OS30_ONLY if (UtilityBase->lib_Version >= 39) #endif /* !OS30_ONLY */ UniqueID = GetUniqueID(); /* Get ID for HelpGroup and other jobs */ /* Get startup arguments */ XMArgs.CxPopup = TRUE; if (WBenchMsg) err = GetWBArgs(); else err = GetShellArgs(); if (err) return err; SetupLocale(); /* Create XModule library */ if (err = MakeXModuleLibrary ()) return err; Pool = XModuleBase->xm_Pool; /* Try to load XModule preferences */ if (XMArgs.Settings) { if (LoadPrefs (XMArgs.Settings)) { UBYTE buf[FAULT_MAX]; Fault (IoErr(), NULL, buf, FAULT_MAX); ShowMessage (MSG_ERR_LOAD, XMArgs.Settings, buf); } } else { if (LoadPrefs ("PROGDIR:" PRGNAME ".prefs")) LoadPrefs ("ENV:" PRGNAME ".prefs"); } /* Use startup Arguments */ if (XMArgs.PubScreen) strncpy (ScrInfo.PubScreenName, XMArgs.PubScreen, 31); if (XMArgs.PortName) strncpy (PubPortName, XMArgs.PortName, 15); CxPopup = XMArgs.CxPopup; if (XMArgs.CxPopKey) strncpy (CxPopKey, XMArgs.CxPopKey, 31); if (XMArgs.CxPriority) CxPri = *XMArgs.CxPriority; if (XMArgs.IconX) IconX = *XMArgs.IconX; if (XMArgs.IconY) IconY = *XMArgs.IconY; if (XMArgs.IconName) strncpy (IconName, XMArgs.IconName, 15); /* Setup FileRequesters if LoadPrefs() hasn't already done it */ if (!AslBase && !ReqToolsBase) if (err = SetupRequesters()) return err; /* Setup App Message Port */ SetupApp(); /* Setup Rexx Host */ CreateRexxPort(); /* Setup Commodity object */ SetupCx(); /* Add internal hooks and load external ones */ SetupHooks(); /* Allocate a new SongInfo structure */ if (!XModuleBase->xm_CurrentSong) { struct SongInfo *si; if (si = xmCreateSong ( SNGA_ReadyToUse, TRUE, XMSNG_AddToList, -1, XMSNG_Active, TRUE, TAG_DONE)) ReleaseSemaphore (&si->Lock); else return ERROR_NO_FREE_STORE; } /* Open screen and ToolBox window */ if (CxPopup) if (err = SetupScreen()) return err; /* Load modules requested with Shell/Workbench startup arguments */ HandleFrom(); DisposeArgs(); return 0; } static void Cleanup (LONG err) /* Cleanup routine. Display error message, free all resources & exit */ { ULONG i; if (err > 100) PrintFault (err, PrgName); /* Free all allocated resources */ CleanupAudio(); DisposeArgs(); /* Just to be sure */ FreeFReq(); CloseDownScreen(); if (Pool) { FreeVecPooled (Pool, ScreenAttr.ta_Name); FreeVecPooled (Pool, WindowAttr.ta_Name); FreeVecPooled (Pool, ListAttr.ta_Name); FreeVecPooled (Pool, EditorAttr.ta_Name); } /* Dispose XModule library */ DisposeXModuleLibrary (); /* Remove AppIcons/AppWindows Port */ CleanupApp(); /* Remove Commodity Broker */ CleanupCx(); /* Remove ARexx port */ DeleteRexxPort(); CleanupLocale(); /* Close all libraries */ for (i = 0 ; openlibs[i].Base ; i++) /* starting with V36, NULL is a valid parameter for CloseLibrary(). */ CloseLibrary (*(openlibs[i].Base)); } /*!*/ /* Emergency patch: */ LONG SampleWinTags[1] = { 0 }; void UpdateSampleMenu (void) {}