home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 15 / AACD15.ISO / AACD / Programming / MultiDesktop / desk / bak / desk.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-03-27  |  25.7 KB  |  1,237 lines

  1. /* MultiDesktop-Library - Memory, Timer, Locale, Requester */
  2. #include "multidesktop.h"
  3.  
  4. BOOL            StrIsGreaterThan();
  5. BOOL            StrIsLessThan();
  6. UBYTE          *AllocMemory();
  7. UBYTE          *GetLStr();
  8. UBYTE          *FindID();
  9. void            Seconds2StarDate();
  10. struct Library *OpenDevLibrary();
  11. void            FreeMemory();
  12. void            FreeMemoryBlock();
  13. void            ErrorL();
  14. void            OldError();
  15. void            CloseDevLibrary();
  16. void            RemoveLib();
  17. extern ULONG    HookEntry();
  18. extern UBYTE    ToUpper();
  19.  
  20. extern struct MultiDesktopBase *MultiDesktopBase;
  21. extern struct ExecBase         *SysBase;
  22.  
  23. struct Catalog                 *Catalog;
  24. struct Library                 *LocaleBase;
  25. struct Library                 *UtilityBase;
  26. struct Library                 *TimerBase;
  27. struct Library                 *InputBase;
  28. struct Library                 *BattClockBase;
  29. struct Library                 *IntuitionBase;
  30. struct Library                 *DOSBase;
  31.  
  32. extern ULONG  SleepPointerSize;
  33. extern UBYTE *SleepPointerData;
  34. UBYTE        *ChipData;
  35.  
  36. struct IntuiText t1=
  37. {
  38.  AUTOFRONTPEN,
  39.  AUTOBACKPEN,
  40.  AUTODRAWMODE,
  41.  AUTOLEFTEDGE,
  42.  AUTOTOPEDGE,
  43.  NULL,
  44.  NULL,
  45.  NULL
  46. };
  47.  
  48. struct IntuiText t2=
  49. {
  50.  AUTOFRONTPEN,
  51.  AUTOBACKPEN,
  52.  AUTODRAWMODE,
  53.  AUTOLEFTEDGE,
  54.  AUTOTOPEDGE,
  55.  NULL,
  56.  "Abort!",
  57.  NULL
  58. };
  59.  
  60. /* ---- Library initialisieren */
  61. ULONG InitLib()
  62. {
  63.  MultiDesktopBase->IntLib=OpenLibrary("intuition.library",0L);
  64.  if(MultiDesktopBase->IntLib==NULL)
  65.   { RemoveLib(); exit(0); }
  66.  
  67.  IntuitionBase=MultiDesktopBase->IntLib;
  68.  if(IntuitionBase->lib_Version<37) {
  69.    OldError("This software requires AmigaDOS 2.0 (V37)!");
  70.    RemoveLib(); return(0); }
  71.  
  72.  MultiDesktopBase->GfxLib=OpenLibrary("graphics.library",37L);
  73.  if(MultiDesktopBase->GfxLib==NULL)
  74.   { OldError("Unable to open graphics.library V37!");
  75.     RemoveLib(); exit(0); }
  76.  
  77.  MultiDesktopBase->DosLib=OpenLibrary("dos.library",37L);
  78.  if(MultiDesktopBase->DosLib==NULL)
  79.   { OldError("Unable to open dos.library V37!");
  80.     RemoveLib(); exit(0); }
  81.  DOSBase=MultiDesktopBase->DosLib;
  82.  
  83.  MultiDesktopBase->DiskfontLib=OpenLibrary("diskfont.library",36L);
  84.  if(MultiDesktopBase->DiskfontLib==NULL)
  85.   { OldError("Unable to open diskfont.library V36!");
  86.     RemoveLib(); exit(0); }
  87.  
  88.  MultiDesktopBase->GadToolsLib=OpenLibrary("gadtools.library",37L);
  89.  if(MultiDesktopBase->GadToolsLib==NULL)
  90.   { OldError("Unable to open gadtools.library V37!");
  91.     RemoveLib(); exit(0); }
  92.  
  93.  MultiDesktopBase->IconLib=OpenLibrary("icon.library",37L);
  94.  if(MultiDesktopBase->IconLib==NULL)
  95.   { OldError("Unable to open icon.library V37!");
  96.     RemoveLib(); exit(0); }
  97.  
  98.  MultiDesktopBase->LayersLib=OpenLibrary("layers.library",37L);
  99.  if(MultiDesktopBase->LayersLib==NULL)
  100.   { OldError("Unable to open layers.library V37!");
  101.     RemoveLib(); exit(0); }
  102.  
  103.  MultiDesktopBase->WorkbenchLib=OpenLibrary("workbench.library",37L);
  104.  if(MultiDesktopBase->WorkbenchLib==NULL)
  105.   { OldError("Unable to open workbench.library V37!");
  106.     RemoveLib(); exit(0); }
  107.  
  108.  MultiDesktopBase->ExpansionLib=OpenLibrary("expansion.library",37L);
  109.  if(MultiDesktopBase->ExpansionLib==NULL)
  110.   { OldError("Unable to open expansion.library V37!");
  111.     RemoveLib(); exit(0); }
  112.  
  113.  MultiDesktopBase->UtilityLib=OpenLibrary("utility.library",37L);
  114.  if(MultiDesktopBase->UtilityLib==NULL)
  115.   { OldError("Unable to open utility.library V37!");
  116.     RemoveLib(); exit(0); }
  117.  UtilityBase=MultiDesktopBase->UtilityLib;
  118.  
  119.  MultiDesktopBase->KeymapLib=OpenLibrary("keymap.library",37L);
  120.  if(MultiDesktopBase->KeymapLib==NULL)
  121.   { OldError("Unable to open keymap.library V37!");
  122.     RemoveLib(); exit(0); }
  123.  
  124.  
  125.  MultiDesktopBase->VersionLib=OpenLibrary("version.library",0L);
  126.  MultiDesktopBase->LocaleLib=OpenLibrary("locale.library",38L);
  127.  if(MultiDesktopBase->LocaleLib!=NULL)
  128.   {
  129.    LocaleBase=MultiDesktopBase->LocaleLib;
  130.    MultiDesktopBase->Locale=OpenLocale(NULL);
  131.    if(MultiDesktopBase->Locale!=NULL)
  132.     {
  133.      MultiDesktopBase->Catalog=OpenCatalogA(MultiDesktopBase->Locale,
  134.                                             "multidesktop.catalog",
  135.                                             NULL);
  136.      Catalog=MultiDesktopBase->Catalog;
  137.     }
  138.   }
  139.  
  140.  MultiDesktopBase->TimerLib=OpenDevLibrary("timer.device",0);
  141.  if(MultiDesktopBase->TimerLib==NULL) {
  142.    OldError("Unable to open timer.device!");
  143.    RemoveLib(); return(0); }
  144.  
  145.  MultiDesktopBase->ConsoleLib=OpenDevLibrary("console.device",0);
  146.  if(MultiDesktopBase->ConsoleLib==NULL) {
  147.    OldError("Unable to open console.device!");
  148.    RemoveLib(); return(0); }
  149.  
  150.  MultiDesktopBase->InputLib=OpenDevLibrary("input.device",0);
  151.  if(MultiDesktopBase->InputLib==NULL) {
  152.    OldError("Unable to open input.device!");
  153.    RemoveLib(); return(0); }
  154.  
  155.  ChipData=AllocMem(SleepPointerSize,MEMF_CHIP|MEMF_PUBLIC);
  156.  if(ChipData!=NULL)
  157.    CopyMemQuick(&SleepPointerData,ChipData,SleepPointerSize);
  158.  
  159.  MultiDesktopBase->BattClockLib=OpenResource("battclock.resource",0);
  160.  BattClockBase=MultiDesktopBase->BattClockLib;
  161.  
  162.  TimerBase=MultiDesktopBase->TimerLib;
  163.  InputBase=MultiDesktopBase->InputLib;
  164.  
  165.  return(1L);
  166. }
  167.  
  168. /* ---- Library entfernen */
  169. void RemoveLib()
  170. {
  171.  if(ChipData) FreeMem(ChipData,SleepPointerSize);
  172.  if(MultiDesktopBase->TimerLib) CloseDevLibrary(MultiDesktopBase->TimerLib);
  173.  if(MultiDesktopBase->ConsoleLib) CloseDevLibrary(MultiDesktopBase->ConsoleLib);
  174.  if(MultiDesktopBase->InputLib) CloseDevLibrary(MultiDesktopBase->InputLib);
  175.  
  176.  if(MultiDesktopBase->Catalog) CloseCatalog(MultiDesktopBase->Catalog);
  177.  if(MultiDesktopBase->Locale) CloseLocale(MultiDesktopBase->Locale);
  178.  if(MultiDesktopBase->LocaleLib) CloseLibrary(MultiDesktopBase->LocaleLib);
  179.  if(MultiDesktopBase->VersionLib) CloseLibrary(MultiDesktopBase->VersionLib);
  180.  if(MultiDesktopBase->KeymapLib) CloseLibrary(MultiDesktopBase->KeymapLib);
  181.  if(MultiDesktopBase->ExpansionLib) CloseLibrary(MultiDesktopBase->ExpansionLib);
  182.  if(MultiDesktopBase->UtilityLib) CloseLibrary(MultiDesktopBase->UtilityLib);
  183.  if(MultiDesktopBase->WorkbenchLib) CloseLibrary(MultiDesktopBase->WorkbenchLib);
  184.  if(MultiDesktopBase->LayersLib) CloseLibrary(MultiDesktopBase->LayersLib);
  185.  if(MultiDesktopBase->IconLib) CloseLibrary(MultiDesktopBase->IconLib);
  186.  if(MultiDesktopBase->GadToolsLib) CloseLibrary(MultiDesktopBase->GadToolsLib);
  187.  if(MultiDesktopBase->DiskfontLib) CloseLibrary(MultiDesktopBase->DiskfontLib);
  188.  if(MultiDesktopBase->GfxLib) CloseLibrary(MultiDesktopBase->GfxLib);
  189.  if(MultiDesktopBase->IntLib) CloseLibrary(MultiDesktopBase->IntLib);
  190.  if(MultiDesktopBase->DosLib) CloseLibrary(MultiDesktopBase->DosLib);
  191. }
  192.  
  193. /* ---- Multi-Requester */
  194. LONG MultiRequest(titel,text,gads)
  195.  UBYTE *titel,*text,*gads;
  196. {
  197.  struct EasyStruct easy;
  198.  
  199.  easy.es_StructSize=sizeof(struct EasyStruct);
  200.  easy.es_Flags=0;
  201.  easy.es_Title=titel;
  202.  easy.es_TextFormat=text;
  203.  easy.es_GadgetFormat=gads;
  204.  return(EasyRequestArgs(NULL,&easy,0L,0L));
  205. }
  206.  
  207. /* ---- Fehler-Requester */
  208. LONG ErrorRequest(titel,text,gads)
  209.  UBYTE *titel,*text,*gads;
  210. {
  211.  if(titel==NULL) titel=GetLStr(1,"MultiDesktop - Error!");
  212.  if(gads==NULL) gads=GetLStr(2,"Okay");
  213.  return(MultiRequest(FindID(Catalog,titel),
  214.                      FindID(Catalog,text),
  215.                      FindID(Catalog,gads)));
  216. }
  217.  
  218. /* ---- Okay-Requester */
  219. void OkayRequest(text)
  220.  UBYTE *text;
  221. {
  222.  MultiRequest("MultiDesktop",text,GetLStr(2,"Okay"));
  223. }
  224.  
  225. /* ---- Einzeiliger Requester, Kickstart 1.1-kompatibel */
  226. void OldError(text)
  227.  UBYTE *text;
  228. {
  229.  struct IntuiText it;
  230.  
  231.  CopyMemQuick(&t1,&it,sizeof(struct IntuiText));
  232.  it.IText=text;
  233.  AutoRequest(NULL,&it,&t2,&t2,0L,0L,320,75);
  234. }
  235.  
  236. /* ---- Fehler-Requester */
  237. void ErrorL(num,text)
  238.  int    num;
  239.  UBYTE *text;
  240. {
  241.  if(text==NULL) text="Not enough memory!";
  242.  MultiRequest(GetLStr(1,"MultiDesktop - Error!"),GetLStr(num,text),GetLStr(2,"Okay"));
  243. }
  244.  
  245. /* ---- Stringadresse ermitteln */
  246. UBYTE *GetLStr(num,def)
  247.  LONG   num;
  248.  UBYTE *def;
  249. {
  250.  if(Catalog==NULL) return(def);
  251.  return(GetCatalogStr(Catalog,num,def));
  252. }
  253.  
  254. struct ProcSegment
  255. {
  256.  ULONG Length;
  257.  BPTR  Next;
  258.  UWORD OpCode;
  259.  VOID (* Address)();
  260. };
  261.  
  262. /* ---- Neuen Prozess erstellen */
  263. struct Task *CreateNewProcess(function,stack,name,pri)
  264.  VOID   (* function)();
  265.  ULONG  stack;
  266.  UBYTE *name;
  267.  BYTE   pri;
  268. {
  269.  struct Process *proc;
  270.  struct ProcSegment *Segment;
  271.  
  272.  Segment=AllocMem(sizeof(struct ProcSegment),MEMF_CLEAR|MEMF_PUBLIC);
  273.  if(Segment==NULL) return(NULL);
  274.  Segment->Length=sizeof(struct ProcSegment);
  275.  Segment->Next=NULL;
  276.  Segment->OpCode=0x4EF9;
  277.  Segment->Address=function;
  278.  Segment=(LONG)(&(Segment->Next)) >> 2;
  279.  
  280.  proc=CreateProc(name,pri,Segment,stack);
  281.  if(proc==NULL) return(NULL);
  282.  
  283.  return((struct Task *)((ULONG)proc-(ULONG)sizeof(struct Task)));
  284. }
  285.  
  286. void SleepPointer(win)
  287.  struct Window *win;
  288. {
  289.  if(ChipData) SetPointer(win,ChipData,22,16,-7,-7);
  290. }
  291.  
  292. /* ---- User initialisieren */
  293. struct MultiDesktopUser *InitDesktopUser(task)
  294.  struct Task *task;
  295. {
  296.  struct MultiDesktopUser *mu;
  297.  
  298.  Forbid();
  299.  if(task==NULL) task=SysBase->ThisTask;
  300.  mu=task->tc_UserData;
  301.  if(mu==NULL)
  302.   {
  303.    mu=AllocMem(MULTI_SIZE,MEMF_CLEAR|MEMF_PUBLIC);
  304.    if(mu!=NULL)
  305.     {
  306.      mu->UserCount=1;
  307.      mu->MagicID=MAGIC_ID;
  308.      mu->TimerPort=CreatePort(0L,0L);
  309.      if(mu->TimerPort!=NULL)
  310.       {
  311.        mu->TimerReq=CreateIORequest(mu->TimerPort,sizeof(struct timerequest));
  312.        if(mu->TimerReq!=NULL)
  313.         {
  314.          mu->TimerDev=OpenDevice("timer.device",UNIT_VBLANK,mu->TimerReq,0);
  315.          if(mu->TimerDev==0)
  316.           {
  317.            task->tc_UserData=mu;
  318.            Permit();
  319.            return(mu);
  320.           }
  321.          else
  322.            ErrorL(6,"Unable to open timer.device!");
  323.          DeleteIORequest(mu->TimerReq);
  324.         }
  325.        else
  326.          ErrorL(0,0);
  327.        DeletePort(mu->TimerPort);
  328.       }
  329.      else
  330.        ErrorL(5,"Unable to create port!");
  331.      FreeMem(mu,MULTI_SIZE);
  332.      mu=NULL;
  333.     }
  334.   }
  335.  else
  336.   {
  337.    if(mu->MagicID!=MAGIC_ID)
  338.     {
  339.      mu=NULL;
  340.      ErrorL(4,"Task->tc_UserData is already used by another program or\n"
  341.               "the structure is invalid! Try to start the program again\n"
  342.               "with 'Run' or from Workbench!");
  343.     }
  344.    else
  345.      mu->UserCount++;
  346.   }
  347.  Permit();
  348.  return(mu);
  349. }
  350.  
  351. /* ---- User entfernen */
  352. void TerminateDesktopUser(task)
  353.  struct Task *task;
  354. {
  355.  struct MultiDesktopUser *mu;
  356.  
  357.  Forbid();
  358.  if(task==NULL) task=SysBase->ThisTask;
  359.  mu=task->tc_UserData;
  360.  if(mu!=NULL)
  361.   {
  362.    mu->UserCount--;
  363.    if(mu->UserCount==0)
  364.     {
  365.      AbortIO(mu->TimerReq);
  366.      CloseDevice(mu->TimerReq);
  367.      DeleteIORequest(mu->TimerReq);
  368.      DeletePort(mu->TimerPort);
  369.      if(mu->Remember.FirstRemember) FreeMemory(&mu->Remember);
  370.      FreeMem(mu,MULTI_SIZE);
  371.      task->tc_UserData=NULL;
  372.     }
  373.   }
  374.  Permit();
  375. }
  376.  
  377. /* ---- Speicher belegen */
  378. UBYTE *GetMem(size,flags)
  379.  ULONG size,flags;
  380. {
  381.  struct MultiDesktopUser *mu;
  382.  
  383.  mu=SysBase->ThisTask->tc_UserData;
  384.  return(AllocMemory(&mu->Remember,size,flags));
  385. }
  386.  
  387. /* ---- Speicher freigeben */
  388. void DisposeMem(block)
  389.  UBYTE *block;
  390. {
  391.  struct MultiDesktopUser *mu;
  392.  
  393.  mu=SysBase->ThisTask->tc_UserData;
  394.  if(block)
  395.    FreeMemoryBlock(&mu->Remember,block);
  396. }
  397.  
  398. /* ---- Speicher belegen */
  399. UBYTE *AllocMemory(rem,size,flags)
  400.  struct MultiRemember *rem;
  401.  ULONG                 size,flags;
  402. {
  403.  struct MultiRememberEntry *mem;
  404.  
  405.  Forbid();
  406.  mem=AllocMem(size+12L,flags);
  407.  if(mem)
  408.   {
  409.    mem->PrevRemember=NULL;
  410.    mem->NextRemember=NULL;
  411.    mem->MemorySize=size+12L;
  412.  
  413.    if(rem->FirstRemember==NULL)
  414.     {
  415.      rem->FirstRemember=mem;
  416.      rem->LastRemember=mem;
  417.     }
  418.    else
  419.     {
  420.      mem->PrevRemember=rem->LastRemember;
  421.      rem->LastRemember->NextRemember=mem;
  422.      rem->LastRemember=mem;
  423.     }
  424.  
  425.    mem=(ULONG)mem+12L;
  426.   }
  427.  Permit();
  428.  return(mem);
  429. }
  430.  
  431. /* ---- Speicher mit bestimmten Alignment belegen */
  432. UBYTE *AllocAlignedMemory(rem,size,flags,align)
  433.  struct MultiRemember *rem;
  434.  ULONG                 size,flags,align;
  435. {
  436.  ULONG                      add;
  437.  struct MultiRememberEntry *mem;
  438.  
  439.  Forbid();
  440.  mem=AllocMem(size+align+12L,flags);
  441.  add=((ULONG)mem % align);
  442.  if(add!=0)
  443.   {
  444.    FreeMem(mem,size+align+12L);
  445.    mem=AllocAbs(size+12L,mem+add);
  446.   }
  447.  if(mem)
  448.   {
  449.    mem->PrevRemember=NULL;
  450.    mem->NextRemember=NULL;
  451.    mem->MemorySize=size+12L;
  452.  
  453.    if(rem->FirstRemember==NULL)
  454.     {
  455.      rem->FirstRemember=mem;
  456.      rem->LastRemember=mem;
  457.     }
  458.    else
  459.     {
  460.      mem->PrevRemember=rem->LastRemember;
  461.      rem->LastRemember->NextRemember=mem;
  462.      rem->LastRemember=mem;
  463.     }
  464.  
  465.    mem=(ULONG)mem+12L;
  466.   }
  467.  Permit();
  468.  return(mem);
  469. }
  470.  
  471. /* ---- Speicher freigeben */
  472. void FreeMemory(rem)
  473.  struct MultiRemember *rem;
  474. {
  475.  UBYTE                     *m;
  476.  ULONG                      s;
  477.  struct MultiRememberEntry *mem;
  478.  
  479.  Forbid();
  480.  mem=rem->FirstRemember;
  481.  while(mem!=NULL)
  482.   {
  483.    m=mem;
  484.    s=mem->MemorySize;
  485.    mem=mem->NextRemember;
  486.    FreeMem(m,s);
  487.   }
  488.  rem->FirstRemember=NULL;
  489.  rem->LastRemember=NULL;
  490.  Permit();
  491. }
  492.  
  493. /* ---- Speicherblock freigeben */
  494. void FreeMemoryBlock(rem,block)
  495.  struct MultiRemember      *rem;
  496.  UBYTE                     *block;
  497. {
  498.  struct MultiRememberEntry *mem;
  499.  
  500.  mem=(ULONG)block-12L;
  501.  
  502.  Forbid();
  503.  if(mem->PrevRemember)
  504.    mem->PrevRemember->NextRemember=mem->NextRemember;
  505.  if(mem->NextRemember)
  506.    mem->NextRemember->PrevRemember=mem->PrevRemember;
  507.  if(mem==rem->FirstRemember) rem->FirstRemember=mem->NextRemember;
  508.  if(mem==rem->LastRemember) rem->LastRemember=mem->PrevRemember;
  509.  Permit();
  510.  
  511.  FreeMem(mem,mem->MemorySize);
  512. }
  513.  
  514. /* ---- Text einer ID-Nummer ermitteln */
  515. UBYTE *FindID(cat,id)
  516.  struct Catalog *cat;
  517.  UBYTE           *id;
  518. {
  519.  UBYTE         num[200];
  520.  REGISTER BOOL hasNum;
  521.  ULONG         catID;
  522.  register int  i;
  523.  
  524.  if(id==NULL) return(NULL);
  525.  
  526.  hasNum=FALSE;
  527.  i=0;
  528.  while(id[i]!=0x00)
  529.   {
  530.    if(id[i]!=':')
  531.      num[i]=id[i];
  532.    else
  533.     {
  534.      num[i]=0x00;
  535.      hasNum=TRUE;
  536.      break;
  537.     }
  538.    i++;
  539.   }
  540.  
  541.  if(!hasNum)
  542.    return(id);
  543.  
  544.  catID=atol(&num);
  545.  if(catID==0)
  546.    return(id);
  547.  
  548.  return(GetCatalogStr(cat,catID,&id[i+1]));
  549. }
  550.  
  551. /* ---- Asynchroner Programmstart */
  552. void ASyncRun(name)
  553.  UBYTE *name;
  554. {
  555.  struct TagItem              tag[5];
  556.  register struct FileHandle *con;
  557.  
  558.  con=Open("CON:10/20/620/150/MultiDesktop/AUTO/WAIT/CLOSE",MODE_NEWFILE);
  559.  if(con!=NULL)
  560.   {
  561.    tag[0].ti_Tag=SYS_Input;
  562.    tag[0].ti_Data=NULL;
  563.    tag[1].ti_Tag=SYS_Output;
  564.    tag[1].ti_Data=con;
  565.    tag[2].ti_Tag=SYS_Asynch;
  566.    tag[2].ti_Data=TRUE;
  567.    tag[3].ti_Tag=SYS_UserShell;
  568.    tag[3].ti_Data=TRUE;
  569.    tag[4].ti_Tag=TAG_DONE;
  570.    SystemTagList(name,&tag);
  571.   }
  572.  else
  573.    ErrorL(3,"Unable to open AutoCon-window!");
  574. }
  575.  
  576. /* ---- Synchroner Programmstart */
  577. void SyncRun(name)
  578.  UBYTE *name;
  579. {
  580.  struct TagItem tag[3];
  581.  
  582.  tag[0].ti_Tag=SYS_Input;
  583.  tag[0].ti_Data=Input();
  584.  tag[1].ti_Tag=SYS_Output;
  585.  tag[1].ti_Data=Output();
  586.  tag[2].ti_Tag=TAG_DONE;
  587.  SystemTagList(name,&tag);
  588. }
  589.  
  590. /* ---- Node suchen */
  591. struct Node *FindNode(list,num)
  592.  struct List *list;
  593.  ULONG        num;
  594. {
  595.  register struct Node *node;
  596.  register ULONG        i;
  597.  
  598.  i=0;
  599.  for(node=list->lh_Head;node!=&list->lh_Tail;node=node->ln_Succ)
  600.   {
  601.    if(i==num) return(node);
  602.    i++;
  603.   }
  604.  return(NULL);
  605. }
  606.  
  607. /* ---- Nodes zählen */
  608. struct Node *CountNodes(list)
  609.  struct List *list;
  610. {
  611.  register struct Node *node;
  612.  register ULONG        i;
  613.  
  614.  i=0;
  615.  for(node=list->lh_Head;node!=&list->lh_Tail;node=node->ln_Succ)
  616.    i++;
  617.  return(i);
  618. }
  619.  
  620. /*
  621.    Stringvergleich für Sortierung:
  622.    =>  TRUE,  wenn String A > B
  623. */
  624. BOOL StrIsGreaterThan(a,b)
  625.  UBYTE *a,*b;
  626. {
  627.  register int l1,l2,l,i;
  628.  
  629.  l1=strlen(a);
  630.  l2=strlen(b);
  631.  
  632.  if(l1>l2) l=l2; else l=l1;
  633.  
  634.  for(i=0;i<l;i++)
  635.   {
  636.    if(ToUpper(a[i]) > ToUpper(b[i]))
  637.      return(TRUE);
  638.    else if(ToUpper(b[i]) > ToUpper(a[i]))
  639.      return(FALSE);
  640.   }
  641.  if(l1>l2) return(TRUE);
  642.  return(FALSE);
  643. }
  644.  
  645. /*
  646.    Stringvergleich für Sortierung:
  647.    =>  TRUE,  wenn String A < B
  648. */
  649. BOOL StrIsLessThan(a,b)
  650.  UBYTE *a,*b;
  651. {
  652.  register int l1,l2,l,i;
  653.  
  654.  l1=strlen(a);
  655.  l2=strlen(b);
  656.  
  657.  if(l1>l2) l=l2; else l=l1;
  658.  
  659.  for(i=0;i<l;i++)
  660.   {
  661.    if(ToUpper(a[i]) > ToUpper(b[i]))
  662.      return(FALSE);
  663.    else if(ToUpper(b[i]) > ToUpper(a[i]))
  664.      return(TRUE);
  665.   }
  666.  if(l1>l2) return(TRUE);
  667.  return(FALSE);
  668. }
  669.  
  670. /* ---- Sortiert einfügen */
  671. void InsertSort(list,node,place)
  672.  struct List *list;
  673.  struct Node *node;
  674.  UBYTE        place;
  675. {
  676.  BOOL         okay;
  677.  struct Node *old,*prev;
  678.  BOOL         sort;
  679.  
  680.  if(place==SORT_DESCENDING) sort=TRUE; else sort=FALSE;
  681.  prev=NULL; okay=FALSE;
  682.  for(old=list->lh_Head;old!=&list->lh_Tail;old=old->ln_Succ)
  683.   {
  684.    if((StrIsGreaterThan(node->ln_Name,old->ln_Name))==sort)
  685.     {
  686.      okay=TRUE;
  687.      if(prev==NULL)
  688.        AddHead(list,node);
  689.      else
  690.        Insert(list,node,prev);
  691.      break;
  692.     }
  693.    prev=old;
  694.   }
  695.  if(okay==FALSE) AddTail(list,node);
  696. }
  697.  
  698. /* ---- QuickSort-Hauptteil (Aufsteigend sortieren) */
  699. void QuickSortMainA(array,start,end)
  700.  struct Node  **array;
  701.  long           start,end;
  702. {
  703.  struct Node *help;
  704.  UBYTE       *vge;
  705.  long         i,j;
  706.  
  707.  vge=array[(start+end)/2]->ln_Name;
  708.  i=start;
  709.  j=end;
  710.  do
  711.   {
  712.    while((StrIsLessThan(array[i]->ln_Name,vge))) i++;
  713.    while((StrIsGreaterThan(array[j]->ln_Name,vge))) j--;
  714.  
  715.    if(i<=j)
  716.     {
  717.      help=array[i];
  718.      array[i]=array[j];
  719.      array[j]=help;
  720.      i++;
  721.      j--;
  722.     }
  723.   } while(i<=j);
  724.  
  725.  if(j>start) QuickSortMainA(array,start,j);
  726.  if(end>i) QuickSortMainA(array,i,end);
  727. }
  728.  
  729. /* ---- QuickSort-Hauptteil (Absteigend sortieren) */
  730. void QuickSortMainD(array,start,end)
  731.  struct Node  *array[];
  732.  long          start,end;
  733. {
  734.  struct Node *help;
  735.  UBYTE       *vge;
  736.  long         i,j;
  737.  
  738.  vge=array[(start+end)/2]->ln_Name;
  739.  i=start;
  740.  j=end;
  741.  do
  742.   {
  743.    while((StrIsGreaterThan(array[i]->ln_Name,vge))) i++;
  744.    while((StrIsLessThan(array[j]->ln_Name,vge))) j--;
  745.  
  746.    if(i<=j)
  747.     {
  748.      help=array[i];
  749.      array[i]=array[j];
  750.      array[j]=help;
  751.      i++;
  752.      j--;
  753.     }
  754.  
  755.   } while(i<=j);
  756.  if(j>start) QuickSortMainD(array,start,j);
  757.  if(end>i) QuickSortMainD(array,i,end);
  758. }
  759.  
  760. /* ---- Liste sortieren */
  761. BOOL SortList(list,place)
  762.  struct List *list;
  763.  UBYTE        place;
  764. {
  765.  REGISTER ULONG        i,count;
  766.  REGISTER ULONG       *array;
  767.  register struct Node *node;
  768.  
  769.  count=CountNodes(list);
  770.  if(count<2) return;
  771.  
  772.  array=AllocVec((count*4)+8,MEMF_ANY);
  773.  if(array)
  774.   {
  775.    for(node=list->lh_Head,i=0;node!=&list->lh_Tail;node=node->ln_Succ,i++)
  776.      array[i]=node;
  777.    NewList(list);
  778.  
  779.    if(place==SORT_DESCENDING)
  780.      QuickSortMainD(array,0,count-1);
  781.    else
  782.      QuickSortMainA(array,0,count-1);
  783.  
  784.    for(i=0;i<count;i++)
  785.      AddTail(list,array[i]);
  786.    FreeVec(array);
  787.   }
  788.  else
  789.   { ErrorL(0,0); return(FALSE); }
  790.  return(TRUE);
  791. }
  792.  
  793. /* ---- Listen zusammenfügen */
  794. void ConcatList(list,list2)
  795.  struct List *list,*list2;
  796. {
  797.  register struct Node *node,*succ;
  798.  
  799.  if(list==NULL) return;
  800.  if(list2==NULL) return;
  801.  
  802.  node=list2->lh_Head;
  803.  while(node!=&list2->lh_Tail)
  804.   {
  805.    succ=node->ln_Succ;
  806.    AddTail(list,node);
  807.    node=succ;
  808.   }
  809.  NewList(list2);
  810. }
  811.  
  812. /* ---- Liste duplizieren */
  813. struct List *DupList(list,size)
  814.  struct List *list;
  815. {
  816.  REGISTER ULONG        name;
  817.  register long         size2;
  818.  register struct Node *node;
  819.  register struct Node *xn;
  820.  register struct List *xl;
  821.  
  822.  if(list==NULL) return;
  823.  
  824.  size += (size % 4);
  825.  xl=GetMem(sizeof(struct List),MEMF_CLEAR|MEMF_PUBLIC);
  826.  if(xl==NULL) return(NULL);
  827.  NewList(xl);
  828.  
  829.  for(node=list->lh_Head;node!=&list->lh_Tail;node=node->ln_Succ)
  830.   {
  831.    size2=size;
  832.    if(node->ln_Name) size2+=strlen(node->ln_Name)+1;
  833.    xn=GetMem(size2,MEMF_PUBLIC);
  834.    if(xn!=NULL)
  835.     {
  836.      CopyMemQuick(node,xn,size);
  837.      if(node->ln_Name)
  838.       {
  839.        name=(ULONG)xn+(ULONG)size;
  840.        strcpy(name,node->ln_Name);
  841.        xn->ln_Name=name;
  842.       }
  843.      AddTail(xl,xn);
  844.     }
  845.   }
  846.  
  847.  return(xl);
  848. }
  849.  
  850. /* ---- Liste freigeben */
  851. void FreeList(list)
  852.  struct List *list;
  853. {
  854.  struct Node *node,*succ;
  855.  
  856.  if(list==NULL) return;
  857.  
  858.  node=list->lh_Head;
  859.  while(node!=&list->lh_Tail)
  860.   {
  861.    succ=node->ln_Succ;
  862.    DisposeMem(node);
  863.    node=succ;
  864.   }
  865.  DisposeMem(list);
  866. }
  867.  
  868. /* ---- Listen zusammenfügen mit Kopieren der Quellliste */
  869. void CopyConcatList(list,list2)
  870.  struct List *list,*list2;
  871. {
  872.  register struct List *list3;
  873.  
  874.  if(list==NULL) return;
  875.  if(list2==NULL) return;
  876.  
  877.  list3=DupList(list2);
  878.  if(list3)
  879.   {
  880.    ConcatList(list,list3);
  881.    DisposeMem(list3);
  882.   }
  883. }
  884.  
  885. /* ---- Hook-Entry-Prozedur */
  886. #asm
  887. H_SUBENTRY:   EQU 12
  888.  
  889.    public _HookEntry
  890. _HookEntry:
  891.    movem.l d0-d7/a0-a6,-(sp)
  892.    move.l a1,-(sp)
  893.    move.l a2,-(sp)
  894.    move.l a0,-(sp)
  895.  
  896.    move.l H_SUBENTRY(a0),a0
  897.    jsr (a0)
  898.  
  899.    lea 12(sp),sp
  900.    movem.l (sp)+,d0-d7/a0-a6
  901.    rts
  902. #endasm
  903.  
  904. /* ---- Hook initialisieren */
  905. void InitHook(hook,proc,data)
  906.  struct Hook *hook;
  907.  ULONG        (*proc)();
  908.  ULONG       *data;
  909. {
  910.  hook->h_MinNode.mln_Succ=NULL;
  911.  hook->h_MinNode.mln_Pred=NULL;
  912.  hook->h_Entry=HookEntry;
  913.  hook->h_SubEntry=proc;
  914.  hook->h_Data=data;
  915. }
  916.  
  917. /* ---- ID-Nummer ermitteln */
  918. ULONG GetTextID(id)
  919.  UBYTE *id;
  920. {
  921.  UBYTE         num[200];
  922.  REGISTER BOOL hasNum;
  923.  register int  i;
  924.  
  925.  if(id==NULL) return(NULL);
  926.  
  927.  hasNum=FALSE;
  928.  i=0;
  929.  while(id[i]!=0x00)
  930.   {
  931.    if(id[i]!=':')
  932.      num[i]=id[i];
  933.    else
  934.     {
  935.      num[i]=0x00;
  936.      hasNum=TRUE;
  937.      break;
  938.     }
  939.    i++;
  940.   }
  941.  
  942.  if(!hasNum)
  943.    return(0);
  944.  
  945.  return(atol(num));
  946. }
  947.  
  948. /* ---- Device als Library öffnen */
  949. struct Library *OpenDevLibrary(name,version)
  950.  UBYTE *name;
  951.  LONG   version;
  952. {
  953.  struct Library *lib;
  954.  
  955.  Forbid();
  956.  lib=FindName(&SysBase->DeviceList,name);
  957.  if(lib)
  958.   {
  959.    if(lib->lib_Version<version)
  960.      lib=NULL;
  961.    else
  962.      lib->lib_OpenCnt++;
  963.   }
  964.  Permit();
  965.  return(lib);
  966. }
  967.  
  968. /* ---- Mit OpenDevLibrary() geöffnetes Device schließen */
  969. void CloseDevLibrary(lib)
  970.  struct Library *lib;
  971. {
  972.  Forbid();
  973.  lib->lib_OpenCnt--;
  974.  Permit();
  975. }
  976.  
  977. /* ---- Sekunden in MultiTime umwandeln */
  978. void Seconds2Time(secs,mt)
  979.  ULONG             secs;
  980.  struct MultiTime *mt;
  981. {
  982.  struct ClockData cd;
  983.  
  984.  Amiga2Date(secs,&cd);
  985.  mt->Day=cd.mday;
  986.  mt->Month=cd.month;
  987.  mt->Year=cd.year;
  988.  mt->WDay=cd.wday;
  989.  mt->Second=cd.sec;
  990.  mt->Minute=cd.min;
  991.  mt->Hour=cd.hour;
  992.  mt->SecondsSince1978=secs;
  993.  Seconds2StarDate(secs,mt);
  994. }
  995.  
  996. /* ---- MultiTime in Sekunden umwandeln */
  997. ULONG Time2Seconds(mt)
  998.  struct MultiTime *mt;
  999. {
  1000.  struct ClockData cd;
  1001.  
  1002.  cd.mday=mt->Day;
  1003.  cd.month=mt->Month;
  1004.  cd.year=mt->Year;
  1005.  cd.wday=mt->WDay;
  1006.  cd.sec=mt->Second;
  1007.  cd.min=mt->Minute;
  1008.  cd.hour=mt->Hour;
  1009.  return(Date2Amiga(&cd));
  1010. }
  1011.  
  1012. #define SECONDS_PER_STARDATE 32400L   /* 9 Stunden */
  1013. #define STARDATE_1978        (((((12*365)+3)*24)*60*60)/SECONDS_PER_STARDATE)
  1014.  
  1015. /* ---- Sekunden in Sternzeit umwandeln */
  1016. void Seconds2StarDate(secs,mt)
  1017.  ULONG             secs;
  1018.  struct MultiTime *mt;
  1019. {
  1020.  ULONG a;
  1021.  FLOAT b;
  1022.  
  1023.  mt->StarDate[0]=(secs / SECONDS_PER_STARDATE) + STARDATE_1978;
  1024.  a=secs % SECONDS_PER_STARDATE;
  1025.  b=(FLOAT)a*(100000.0/(FLOAT)SECONDS_PER_STARDATE);
  1026.  mt->StarDate[1]=(ULONG)b/10L;
  1027. }
  1028.  
  1029. /* ---- Sekunden in Sternzeit umwandeln */
  1030. ULONG StarDate2Seconds(mt)
  1031.  struct MultiTime *mt;
  1032. {
  1033.  ULONG a;
  1034.  FLOAT b;
  1035.  
  1036.  b=(FLOAT)mt->StarDate[1]*10.0;
  1037.  a=(ULONG)(b*((FLOAT)SECONDS_PER_STARDATE/100000.0));
  1038.  return(a+(mt->StarDate[0]-STARDATE_1978)*SECONDS_PER_STARDATE);
  1039. }
  1040.  
  1041. /* ---- Datum und Uhrzeit ermitteln */
  1042. void GetTime(mt)
  1043.  struct MultiTime *mt;
  1044. {
  1045.  struct timeval tv;
  1046.  
  1047.  GetSysTime(&tv);
  1048.  Seconds2Time(tv.tv_secs,mt);
  1049. }
  1050.  
  1051. /* ---- Datum und Uhrzeit setzen */
  1052. void SetTime(mt)
  1053.  struct MultiTime *mt;
  1054. {
  1055.  struct MultiDesktopUser *mu;
  1056.  struct timerequest      *tr;
  1057.  struct timeval           tv;
  1058.  
  1059.  mu=SysBase->ThisTask->tc_UserData;
  1060.  tr=mu->TimerReq;
  1061.  AbortIO(tr);
  1062.  tr->tr_time.tv_secs=Time2Seconds(mt);
  1063.  tr->tr_time.tv_micro=0;
  1064.  tr->tr_node.io_Command=TR_SETSYSTIME;
  1065.  DoIO(tr);
  1066. }
  1067.  
  1068. /* ---- BattClock: Datum und Uhrzeit ermitteln */
  1069. void GetBattClockTime(mt)
  1070.  struct MultiTime *mt;
  1071. {
  1072.  if(BattClockBase)
  1073.    Seconds2Time(ReadBattClock(),mt);
  1074. }
  1075.  
  1076. /* ---- BattClock: Datum und Uhrzeit setzen */
  1077. void SetBattClockTime(mt)
  1078.  struct MultiTime *mt;
  1079. {
  1080.  if(BattClockBase)
  1081.    WriteBattClock(Time2Seconds(mt));
  1082. }
  1083.  
  1084. /* ---- Uhrzeiten addieren */
  1085. void AddTimes(source,dest)
  1086.  struct MultiTime *source,*dest;
  1087. {
  1088.  struct timeval t1,t2;
  1089.  
  1090.  t1.tv_secs=Time2Seconds(source);
  1091.  t1.tv_micro=0;
  1092.  t2.tv_secs=Time2Seconds(dest);
  1093.  t2.tv_micro=0;
  1094.  AddTime(&t2,&t1);
  1095.  Seconds2Time(t2.tv_secs,&dest);
  1096. }
  1097.  
  1098. /* ---- Uhrzeiten subtrahieren */
  1099. void SubTimes(source,dest)
  1100.  struct MultiTime *source,*dest;
  1101. {
  1102.  struct timeval t1,t2;
  1103.  
  1104.  t1.tv_secs=Time2Seconds(source);
  1105.  t1.tv_micro=0;
  1106.  t2.tv_secs=Time2Seconds(dest);
  1107.  t2.tv_micro=0;
  1108.  SubTime(&t2,&t1);
  1109.  Seconds2Time(t2.tv_secs,&dest);
  1110. }
  1111.  
  1112. /* ---- Uhrzeiten subtrahieren */
  1113. int CompareTimes(mt1,mt2)
  1114.  struct MultiTime *mt1,*mt2;
  1115. {
  1116.  struct timeval t1,t2;
  1117.  
  1118.  t1.tv_secs=Time2Seconds(mt1);
  1119.  t1.tv_micro=0;
  1120.  t2.tv_secs=Time2Seconds(mt2);
  1121.  t2.tv_micro=0;
  1122.  return(CmpTime(&t2,&t1));
  1123. }
  1124.  
  1125. /* ---- Warten */
  1126. void WaitTime(ticks)
  1127.  ULONG ticks;
  1128. {
  1129.  struct timerequest      *tr;
  1130.  struct MultiDesktopUser *mu;
  1131.  
  1132.  mu=SysBase->ThisTask->tc_UserData;
  1133.  tr=mu->TimerReq;
  1134.  AbortIO(tr);
  1135.  tr->tr_time.tv_secs=ticks / 50;
  1136.  tr->tr_time.tv_micro=(ticks % 50)*20000;
  1137.  tr->tr_node.io_Command=TR_ADDREQUEST;
  1138.  DoIO(tr);
  1139. }
  1140.  
  1141. /* ---- Alarm setzen */
  1142. void SetAlarm(ticks)
  1143.  ULONG ticks;
  1144. {
  1145.  struct timerequest      *tr;
  1146.  struct MultiDesktopUser *mu;
  1147.  
  1148.  mu=SysBase->ThisTask->tc_UserData;
  1149.  tr=mu->TimerReq;
  1150.  AbortIO(tr);
  1151.  tr->tr_time.tv_secs=ticks / 50;
  1152.  tr->tr_time.tv_micro=(ticks % 50)*20000;
  1153.  tr->tr_node.io_Command=TR_ADDREQUEST;
  1154.  SendIO(tr);
  1155. }
  1156.  
  1157. /* ---- Alarm testen */
  1158. BOOL CheckAlarm()
  1159. {
  1160.  struct timerequest      *tr;
  1161.  struct MultiDesktopUser *mu;
  1162.  
  1163.  mu=SysBase->ThisTask->tc_UserData;
  1164.  tr=CheckIO(mu->TimerReq);
  1165.  if(tr!=NULL) return(TRUE);
  1166.  return(FALSE);
  1167. }
  1168.  
  1169. /* ---- Alarm abwarten */
  1170. void WaitAlarm()
  1171. {
  1172.  struct MultiDesktopUser *mu;
  1173.  
  1174.  mu=SysBase->ThisTask->tc_UserData;
  1175.  WaitIO(mu->TimerReq);
  1176. }
  1177.  
  1178. /* ---- Alarm testen */
  1179. void AbortAlarm()
  1180. {
  1181.  struct MultiDesktopUser *mu;
  1182.  
  1183.  mu=SysBase->ThisTask->tc_UserData;
  1184.  AbortIO(mu->TimerReq);
  1185. }
  1186.  
  1187. /* ---- MultiTime-Struktur initialisieren */
  1188. void InitTime(mt,day,month,year,h,m,s)
  1189.  struct MultiTime *mt;
  1190.  UBYTE             day,month;
  1191.  UWORD             year;
  1192.  UBYTE             h,m,s;
  1193. {
  1194.  ULONG sec;
  1195.  
  1196.  mt->Day=day;
  1197.  mt->Month=month;
  1198.  mt->Year=year;
  1199.  mt->Hour=h;
  1200.  mt->Minute=m;
  1201.  mt->Second=s;
  1202.  sec=Time2Seconds(mt);
  1203.  sec=sec/(60*60*24);
  1204.  mt->WDay=(sec % 7);
  1205. }
  1206.  
  1207. /* ---- Speicher ermitteln */
  1208. ULONG AvailChipMem()
  1209. {
  1210.  return(AvailMem(MEMF_CHIP|MEMF_PUBLIC));
  1211. }
  1212.  
  1213. /* ---- Speicher ermitteln */
  1214. ULONG AvailFastMem()
  1215. {
  1216.  return(AvailMem(MEMF_FAST|MEMF_PUBLIC));
  1217. }
  1218.  
  1219. /* ---- Speicher ermitteln */
  1220. ULONG AvailVMem()
  1221. {
  1222.  return(AvailMem(MEMF_ANY)-AvailMem(MEMF_PUBLIC));
  1223. }
  1224.  
  1225. /* ---- Speicher ermitteln */
  1226. ULONG AvailPublicMem()
  1227. {
  1228.  return(AvailMem(MEMF_PUBLIC));
  1229. }
  1230.  
  1231. /* ---- Speicher ermitteln */
  1232. ULONG AvailMemory()
  1233. {
  1234.  return(AvailMem(MEMF_TOTAL));
  1235. }
  1236.  
  1237.