home *** CD-ROM | disk | FTP | other *** search
/ Network PC / Network PC.iso / amiga utilities / disk utilities / backup / backup_restore / backup_src_v3.20.lha / ByteCount.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-28  |  13.1 KB  |  545 lines

  1. // ByteCount.c
  2. // 15 Jun 1996 16:24:42
  3.  
  4. #ifndef    BACKUP_INCLUDE
  5. #include "IncludeAll.c"
  6. #endif
  7. #include "Backup.h"
  8. #include "FileSelect.h"
  9. #include "ByteCount.h"
  10. #include "Backup_proto.h"
  11. #include "BackupStrings.h"
  12.  
  13.  
  14. static BOOL inROM(APTR addr);
  15. static short SetupBCRequest(ULONG BCScaleX, ULONG BCScaleY, UWORD BCOffX, UWORD BCOffY);
  16. static void DisplayByteCount(struct BCInfo *BCount);
  17. static int BC_IDCMPHandler(void);
  18. static void __interrupt HandleBCGadgetCallback(struct Hook *hook, struct Gadget *Gad, ULONG *Code);
  19. static void HandleBCGadget(struct Gadget *gad, USHORT code);
  20. static ULONG __saveds __asm BCHookDisplay(register __a0 struct Hook *theHook,
  21.         register __a1 object,
  22.         register __a2 struct BCInfo *BCount);
  23.  
  24.  
  25. #define    BC_THRESHOLD    10
  26.  
  27.  
  28. // aus Backup.c
  29. extern struct DiskFlags __far *Disks;
  30. extern struct BackupOptions myOptions;    // Einstellungen für die aktuelle Sicherung
  31. extern struct TextFont *ScreenFont;
  32.  
  33. // aus NextFile.c
  34. extern BOOL NextFileAbort;        // Abbruch-Flag für NextFile
  35.  
  36. // aus Backup_Window.c
  37. extern APTR vi;                // VisualInfo
  38. extern struct Screen *WBScreen;
  39.  
  40. // aus FileSelect.c
  41. extern struct Window *activeWindow;    // das gerade aktive Backup-Window
  42. extern BOOL HelpActive;            // Online-Hilfe ist aktiv
  43. extern BOOL GadgetHelp;            // V39-GadgetHelp ist verfügbar
  44. extern ULONG BackupHelpGroup;        // Help Group
  45.  
  46.  
  47. static struct Window *BCWin;
  48.  
  49. static BOOL BCStop;            // Stopflag für Byte-Count
  50.  
  51. static struct Window         *ByteCountWnd = NULL;
  52. static struct Gadget         *ByteCountGList = NULL;
  53. static struct Gadget         *ByteCountGadgets[ByteCount_CNT];
  54. static UWORD                  ByteCountWidth = 211;
  55. static UWORD                  ByteCountHeight = 84;
  56.  
  57. static struct BInputHandler *BCInput = NULL;
  58.  
  59. static struct GadgetShort *BCGadgetShort;    // Tabelle für Tasten-Kürzel
  60.  
  61. static MINLIST(BCResourceList);
  62.  
  63. static struct Hook BCGadgetShortHook =
  64.     {
  65.     { NULL },
  66.     HookEntry,
  67.     (ULONG (*)()) HandleBCGadgetCallback,
  68.     NULL,
  69.     };
  70.  
  71.  
  72. static UWORD ByteCountGTypes[] = {
  73.     BUTTON_KIND,
  74.     BUTTON_KIND,
  75.     TEXT_KIND,
  76.     TEXT_KIND,
  77.     TEXT_KIND,
  78.     TEXT_KIND,
  79.     TEXT_KIND,
  80.     NUMBER_KIND,
  81.     NUMBER_KIND
  82. };
  83.  
  84. static struct NewGadget ByteCountNGad[] = {
  85.       8,  60,  69, 17,   (UBYTE *) MSG_BCOK_GAD, NULL, GD_BCOkGadget, PLACETEXT_IN, NULL, NULL,
  86.     135,  60,  69, 17, (UBYTE *) MSG_BCSTOP_GAD, NULL, GD_StopGadget, PLACETEXT_IN, NULL, NULL,
  87.      11,   5, 173, 16,                     NULL, NULL, GD_BytesTextGadget, 0, NULL, NULL,
  88.     129,  22,  75, 16,                     NULL, NULL, GD_FilesTextGadget, 0, NULL, NULL,
  89.     129,  39,  75, 16,                     NULL, NULL, GD_DisksTxtGadget, 0, NULL, NULL,
  90.       5,  39,  58, 16,                     NULL, NULL, GD_OnGadget, 0, NULL, NULL,
  91.       5,  22,  58, 16,                     NULL, NULL, GD_InGadget, 0, NULL, NULL,
  92.      66,  22,  59, 16,                     NULL, NULL, GD_FilesGadget, 0, NULL, NULL,
  93.      66,  39,  59, 16,                     NULL, NULL, GD_DisksGadget, 0, NULL, NULL
  94. };
  95.  
  96. static ULONG ByteCountGTags[] = {
  97.     (GT_Underscore), '_', (TAG_DONE),
  98.     (GT_Underscore), '_', (TAG_DONE),
  99.     GTTX_Justification, GTJ_LEFT, GTTX_Clipped, TRUE, (TAG_DONE),
  100.     GTTX_Justification, GTJ_LEFT, GTTX_Clipped, TRUE, (TAG_DONE),
  101.     GTTX_Justification, GTJ_LEFT, GTTX_Clipped, TRUE, (TAG_DONE),
  102.     GTTX_Justification, GTJ_RIGHT, GTTX_Clipped, TRUE, (TAG_DONE),
  103.     GTTX_Justification, GTJ_RIGHT, GTTX_Clipped, TRUE, (TAG_DONE),
  104.     GTNM_Justification, GTJ_RIGHT, GTNM_Clipped, TRUE, GTNM_Format, (ULONG) "%8ld",
  105.         (GTNM_Number), 171, (TAG_DONE),
  106.     GTNM_Justification, GTJ_RIGHT, GTNM_Clipped, TRUE, GTNM_Format, (ULONG) "%8ld",
  107.         (GTNM_Number), 17, (TAG_DONE)
  108. };
  109.  
  110.  
  111. // Prüfung, ob <addr> im ROM liegt
  112. static BOOL inROM(APTR addr)
  113. {
  114.     return (BOOL)(addr >= (APTR) 0xf80000 && addr <= (APTR) 0xffffff);
  115. }
  116.  
  117.  
  118. static short SetupBCRequest(ULONG BCScaleX, ULONG BCScaleY, UWORD BCOffX, UWORD BCOffY)
  119. {
  120.     struct Gadget    *g;
  121.  
  122.     CreateGadgetShort(&BCGadgetShort);
  123.  
  124.     g = CreateGadgetList(&ByteCountGList, ByteCount_CNT,
  125.             WBScreen->Font,
  126.             ByteCountGTypes,
  127.             ByteCountNGad,
  128.             ByteCountGadgets,
  129.             ByteCountGTags,
  130.             BCGadgetShort,
  131.             &BCResourceList,
  132.             BCScaleX, BCScaleY,
  133.             BCOffX, BCOffY
  134.             );
  135.     if (NULL == g)
  136.         {
  137.         alarm(GetString(MSG_CREATEGAD_FAILED), __FUNC__);
  138.         return 2;
  139.         }
  140.  
  141.     return 0;
  142. }
  143.  
  144.  
  145. void GetByteCount(struct Window *Parent, struct BackupOptions *Opt,
  146.     unsigned long *ByteCntPtr, unsigned long *FileCntPtr)
  147. {
  148.     struct NewWindow NewBCWindow;
  149.     struct BCInfo BCount;
  150.     struct Hook BCDHook;
  151.     ULONG BCScaleX, BCScaleY;
  152.     UWORD BCOffX, BCOffY;
  153.  
  154.     ASSERT_VALID0(Parent);
  155.     ASSERT_VALID(Opt);
  156.     ASSERT_VALID0(ByteCntPtr);
  157.     ASSERT_VALID0(FileCntPtr);
  158.  
  159.     BCDHook.h_Entry = HookEntry;
  160.     BCDHook.h_SubEntry = (unsigned long (* )()) BCHookDisplay;
  161.     BCDHook.h_Data  = NULL;
  162.  
  163.     if (Parent)
  164.         {
  165.         CalcGadgetScale(WBScreen, ScreenFont, &BCScaleX, &BCScaleY, &BCOffX, &BCOffY, 8, 11);
  166.  
  167.         SetupBCRequest(BCScaleX, BCScaleY, BCOffX, BCOffY);
  168.  
  169.         NewBCWindow.Width = ByteCountWidth * BCScaleX/65535 + BCOffX + Parent->WScreen->WBorRight;
  170.         NewBCWindow.Height = ByteCountHeight * BCScaleY/65535 + BCOffY + Parent->WScreen->WBorBottom;
  171.  
  172.         CenterWindow(Parent, &NewBCWindow);
  173.  
  174.         BCWin = OpenWindowTags(NULL,
  175.                 WA_Left,    NewBCWindow.LeftEdge,
  176.                 WA_Top,        NewBCWindow.TopEdge,
  177.                 WA_Width,    NewBCWindow.Width,
  178.                 WA_Height,    NewBCWindow.Height,
  179.                 WA_IDCMP,    BUTTONIDCMP | TEXTIDCMP | NUMBERIDCMP | IDCMP_GADGETDOWN | 
  180.                         IDCMP_CLOSEWINDOW | IDCMP_ACTIVEWINDOW | IDCMP_MENUHELP | 
  181.                         IDCMP_RAWKEY | IDCMP_GADGETHELP | 
  182.                         IDCMP_REFRESHWINDOW | IDCMP_VANILLAKEY,
  183.                 WA_Flags,    WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_SMART_REFRESH | WFLG_ACTIVATE,
  184.                 WA_Gadgets,    ByteCountGList,
  185.                 WA_Title,    GetString(MSG_BC_WINDOWTITLE),
  186.                 WA_PubScreen,    Parent->WScreen,
  187.                 WA_AutoAdjust,    TRUE,
  188.                 WA_HelpGroup,    BackupHelpGroup,
  189.                 WA_MenuHelp,    TRUE,
  190.                 WA_NewLookMenus, TRUE,
  191.                 TAG_END);
  192.         if (NULL == BCWin)
  193.             {
  194.             alarm("%s: %s", __FUNC__, GetString(MSG_CANNOT_OPEN_WINDOW), "BCWin");
  195.             return;
  196.             }
  197.  
  198.         WindowBusy(Parent, TRUE);
  199.         GT_RefreshWindow(BCWin, NULL );
  200.  
  201.         BCInput = AddBInputHandler(1 << BCWin->UserPort->mp_SigBit, BC_IDCMPHandler);
  202.         }
  203.  
  204.     if (BCWin)
  205.         {
  206.         GT_SetGadgetAttrs(ByteCountGadgets[GDX_BCOkGadget],
  207.             BCWin, NULL,
  208.             GA_Disabled, TRUE,
  209.             TAG_END);
  210.         GT_SetGadgetAttrs(ByteCountGadgets[GDX_StopGadget],
  211.             BCWin, NULL,
  212.             GA_Disabled, FALSE,
  213.             TAG_END);
  214.  
  215.         GT_SetGadgetAttrs(ByteCountGadgets[GDX_BytesTextGadget],
  216.             BCWin, NULL,
  217.             GTTX_Text, GetString(MSG_BC_BYTECOUNT1),
  218.             TAG_END);
  219.         GT_SetGadgetAttrs(ByteCountGadgets[GDX_FilesTextGadget],
  220.             BCWin, NULL,
  221.             GTTX_Text, GetString(MSG_BC_FILECOUNT2),
  222.             TAG_END);
  223.         GT_SetGadgetAttrs(ByteCountGadgets[GDX_DisksTxtGadget],
  224.             BCWin, NULL,
  225.             GTTX_Text, GetString(MSG_BC_DISKCOUNT2),
  226.             TAG_END);
  227.  
  228.         GT_SetGadgetAttrs(ByteCountGadgets[GDX_OnGadget],
  229.             BCWin, NULL,
  230.             GTTX_Text, GetString(MSG_BC_ON_GAD),
  231.             TAG_END);
  232.         GT_SetGadgetAttrs(ByteCountGadgets[GDX_InGadget],
  233.             BCWin, NULL,
  234.             GTTX_Text, GetString(MSG_BC_IN_GAD),
  235.             TAG_END);
  236.         }
  237.  
  238.     DoByteCount(Opt, &BCount, &BCDHook, BC_THRESHOLD);
  239.  
  240.     if (!BCStop && BCWin)
  241.         {
  242.         GT_SetGadgetAttrs(ByteCountGadgets[GDX_BCOkGadget],
  243.             BCWin, NULL,
  244.             GA_Disabled, FALSE,
  245.             TAG_END);
  246.         GT_SetGadgetAttrs(ByteCountGadgets[GDX_StopGadget],
  247.             BCWin, NULL,
  248.             GA_Disabled, TRUE,
  249.             TAG_END);
  250.         }
  251.  
  252.     while (BCWin)
  253.         eingabe(0l);
  254.  
  255.     EndByteCount();
  256.  
  257.     if (Parent)
  258.         WindowBusy(Parent, FALSE);
  259.  
  260.     if (ByteCntPtr)
  261.         *ByteCntPtr = BCount.bci_ByteCount;
  262.     if (FileCntPtr)
  263.         *FileCntPtr = BCount.bci_FileCount;
  264. }
  265.  
  266.  
  267. void EndByteCount(void)
  268. {
  269.     NextFileAbort = BCStop = TRUE;    // ByteCount anhalten
  270.  
  271.     RemBInputHandler(&BCInput);
  272.  
  273.     SafeCloseWindow(&BCWin);
  274.  
  275.     if (ByteCountGList)
  276.         {
  277.         FreeGadgets( ByteCountGList );
  278.         ByteCountGList = NULL;
  279.         }
  280.  
  281.     FreeBResources(&BCResourceList);
  282.     DestroyGadgetShort(&BCGadgetShort);
  283. }
  284.  
  285.  
  286. static void DisplayByteCount(struct BCInfo *BCount)
  287. {
  288.     static unsigned long LastDisks=0;
  289.     unsigned long DiskSize, DiskCount;
  290.     static char BCString[60], OldBCString[60];
  291.  
  292.     ASSERT_VALID(BCount);
  293.  
  294.     // Platz für die Directory-Einträge reservieren
  295.     DiskSize = Disks[myOptions.bo_FirstUnit].DrvDat.BlockSize * Disks[myOptions.bo_FirstUnit].DrvDat.NumHeads
  296.         * Disks[myOptions.bo_FirstUnit].DrvDat.NumCyls * Disks[myOptions.bo_FirstUnit].DrvDat.NumSecs;
  297.  
  298.     DiskCount = ceildiv((BCount->bci_ByteCount / 100) * BCount->bci_Ratio
  299.          + BCount->bci_FileCount * (sizeof(struct DirEntry) + 35), DiskSize);
  300.  
  301.     KMBytes(BCString, BCount->bci_ByteCount);
  302.     strcat(BCString, GetString(MSG_BC_BYTECOUNT1));
  303.     if (0 != strcmp(BCString, OldBCString))
  304.         {
  305.         GT_SetGadgetAttrs(ByteCountGadgets[GDX_BytesTextGadget],
  306.             BCWin, NULL,
  307.             GTTX_Text, BCString,
  308.             TAG_END);
  309.         strcpy(OldBCString, BCString);
  310.         }
  311.  
  312.     // zur Beschleunigung nur alle <bci_Threshold> Files update!
  313.     if (BCS_Final == BCount->bci_Status || 0 == BCount->bci_FileCount % BCount->bci_Threshold)
  314.         {
  315.         if (1 == BCount->bci_FileCount)
  316.             {
  317.             GT_SetGadgetAttrs(ByteCountGadgets[GDX_FilesTextGadget],
  318.                 BCWin, NULL,
  319.                 GTTX_Text, GetString(MSG_BC_FILECOUNT1),
  320.                 TAG_END);
  321.             }
  322.         else if (2 == BCount->bci_FileCount)
  323.             {
  324.             GT_SetGadgetAttrs(ByteCountGadgets[GDX_FilesTextGadget],
  325.                 BCWin, NULL,
  326.                 GTTX_Text, GetString(MSG_BC_FILECOUNT2),
  327.                 TAG_END);
  328.             }
  329.  
  330.         GT_SetGadgetAttrs(ByteCountGadgets[GDX_FilesGadget],
  331.             BCWin, NULL,
  332.             GTNM_Number, BCount->bci_FileCount,
  333.             TAG_END);
  334.         }
  335.  
  336.     if (BCS_Final == BCount->bci_Status || DiskCount != LastDisks)
  337.         {
  338.         if (1 == DiskCount)
  339.             {
  340.             GT_SetGadgetAttrs(ByteCountGadgets[GDX_DisksTxtGadget],
  341.                 BCWin, NULL,
  342.                 GTTX_Text, GetString(MSG_BC_DISKCOUNT1),
  343.                 TAG_END);
  344.             }
  345.         else if (2 == DiskCount)
  346.             {
  347.             GT_SetGadgetAttrs(ByteCountGadgets[GDX_DisksTxtGadget],
  348.                 BCWin, NULL,
  349.                 GTTX_Text, GetString(MSG_BC_DISKCOUNT2),
  350.                 TAG_END);
  351.             }
  352.  
  353.         GT_SetGadgetAttrs(ByteCountGadgets[GDX_DisksGadget],
  354.             BCWin, NULL,
  355.             GTNM_Number, DiskCount,
  356.             TAG_END);
  357.         }
  358.     LastDisks = DiskCount;
  359. }
  360.  
  361.  
  362. static int BC_IDCMPHandler(void)
  363. {
  364.     struct IntuiMessage *msg;
  365.  
  366.     while (BCWin && (msg = GT_GetIMsg(BCWin->UserPort)) )
  367.         {
  368.         ULONG class;
  369.         USHORT code;
  370.         APTR Address;
  371.  
  372.         class = msg->Class;
  373.         code = msg->Code;
  374.         Address = msg->IAddress;
  375.  
  376.         GT_ReplyIMsg(msg);
  377.  
  378.         switch (class)
  379.             {
  380.         case IDCMP_ACTIVEWINDOW:
  381.             activeWindow = BCWin;
  382.             SetHelpPointer(activeWindow, HelpActive);
  383.             break;
  384.  
  385.         case IDCMP_GADGETHELP:
  386.             if (Address == NULL)
  387.                 {
  388.                 // Nicht über unserem Window
  389.                 }
  390.             else if (Address == (APTR) BCWin)
  391.                 {
  392.                 // über unserem Window
  393.                 CallHelp(HELPID_BCWINDOW, TRUE);
  394.                 }
  395.             else
  396.                 CallHelp(((struct Gadget *) Address)->GadgetID, TRUE);
  397.             break;
  398.  
  399.         case IDCMP_MENUHELP:
  400.             break;
  401.  
  402.         case IDCMP_GADGETUP:
  403.             HandleBCGadget((struct Gadget *) Address, code);
  404.             break;
  405.  
  406.         case IDCMP_MENUPICK:
  407.             break;
  408.  
  409.         case IDCMP_RAWKEY:
  410.             if (GADCODE_HELP == code)
  411.                 ToggleHelp();
  412.             break;
  413.  
  414.         case IDCMP_VANILLAKEY:
  415.             HandleGadgetShort(BCGadgetShort, BCWin, code, &BCGadgetShortHook);
  416.             break;
  417.  
  418.         case IDCMP_REFRESHWINDOW:
  419.             // This handling is REQUIRED with GadTools.
  420.             GT_BeginRefresh(BCWin);
  421.             GT_EndRefresh(BCWin, TRUE);
  422.             break;
  423.             }
  424.         }
  425.     return 0;
  426. }
  427.  
  428.  
  429. static void __interrupt HandleBCGadgetCallback(struct Hook *hook, struct Gadget *Gad, ULONG *Code)
  430. {
  431.     HandleBCGadget(Gad, (USHORT) *Code);
  432. }
  433.  
  434.  
  435. static void HandleBCGadget(struct Gadget *gad, USHORT code)
  436. {
  437.     switch (gad->GadgetID)
  438.         {
  439.     case GD_StopGadget:
  440.         EndByteCount();
  441.         break;
  442.  
  443.     case GD_BCOkGadget:
  444.         EndByteCount();
  445.         break;
  446.         }
  447. }
  448.  
  449.  
  450. void DoByteCount(struct BackupOptions *Opt, struct BCInfo *BCount, struct Hook *BCDisplayHook, short Threshold)
  451. {
  452.     static struct FileInfoBlock __aligned fib;
  453.     struct NextFileInfo Info;
  454.  
  455.     BCount->bci_ByteCount = 0;
  456.     BCount->bci_FileCount = 0;
  457.     BCount->bci_Threshold = Threshold;
  458.  
  459.     switch (Opt->bo_Compress)
  460.         {
  461.     case 0:
  462.         BCount->bci_Ratio = 100l;
  463.         break;
  464.     case 1:
  465.         BCount->bci_Ratio = 66l;
  466.         break;
  467.     case 2:
  468.         BCount->bci_Ratio = GetCompressionRatio(Opt->XPKPackerName);
  469.         break;
  470.         }
  471.  
  472.     SetupNextFileInfo(&Info, Opt, NULL);
  473.     Info.nfi_TellSkips = FALSE;
  474.  
  475.     BCount->bci_Status = BCS_Counting;
  476.  
  477.     BCStop = FALSE;
  478.     while (!BCStop && NextFile(&Info, &fib))
  479.         {
  480.         if (LONG_MIN == fib.fib_DirEntryType)
  481.             {
  482.             // Device (Partition)
  483.             char pName[FNSIZE];
  484.             struct DosEnvec *env;
  485.             size_t fSize = 0;
  486.  
  487.             stccpy(pName, fib.fib_FileName, sizeof(pName));
  488.             if (':' == pName[strlen(pName)-1])
  489.                 pName[strlen(pName)-1] = '\0';
  490.  
  491.             // Partition in der DosList suchen um die Größe zu bestimmen!
  492.             env = myFindDosEntry(pName, LDF_DEVICES | LDF_READ);
  493.             if (env)
  494.                 {
  495.                 fSize = (1 + env->de_HighCyl - env->de_LowCyl)
  496.                     * env->de_Surfaces * env->de_BlocksPerTrack
  497.                     * (env->de_SizeBlock << 2);    // Größe in Bytes
  498.                 }
  499.             else
  500.                 {
  501.                 // Partition nicht gefunden!
  502.                 alarm(GetString(MSG_PARTITION_NOTFOUND), fib.fib_FileName);
  503.                 }
  504.  
  505.             BCount->bci_FileCount++;
  506.             BCount->bci_ByteCount += fSize;
  507.             }
  508.         else if (fib.fib_DirEntryType < 0)
  509.             {
  510.             BCount->bci_FileCount++;
  511.             BCount->bci_ByteCount += fib.fib_Size;
  512.             }
  513.  
  514.         if (BCDisplayHook)
  515.             CallHookA(BCDisplayHook, (Object *) BCount, NULL);
  516.         }
  517.  
  518.     BCount->bci_Status = BCS_Final;
  519.  
  520.     if (BCDisplayHook && !BCStop)
  521.         CallHookA(BCDisplayHook, (Object *) BCount, NULL);
  522.  
  523.     CleanupNextFileInfo(&Info);
  524. }
  525.  
  526.  
  527. static ULONG __saveds __asm BCHookDisplay(register __a0 struct Hook *theHook,
  528.         register __a1 object,
  529.         register __a2 struct BCInfo *BCount)
  530. {
  531.     if (BCWin)
  532.         {
  533.         if (!BCStop)
  534.             DisplayByteCount(BCount);
  535.  
  536.         if (BCS_Final != BCount->bci_Status)
  537.             {
  538.             // Testen auf Stop
  539.             chkinput();
  540.             }
  541.         }
  542.  
  543.     return 0L;
  544. }
  545.