home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / cdrom / compactplayer / source / mainwindow.c < prev    next >
C/C++ Source or Header  |  1995-12-28  |  20KB  |  904 lines

  1. #include "sysheaders.h"
  2. #include "cdpanel.h"
  3. #include "CompactPlayer.h"
  4.  
  5. /********************************************************
  6.  * Main GUI
  7.  */
  8.  
  9. #define CDPanelObject   NewObject( CDPanelClass, NULL /* ) open parentheses annoy */
  10.  
  11. struct Gadget *GList[GG_MAX];
  12.  
  13. struct Screen *Scr;
  14. struct DrawInfo *Dri;
  15. struct Window *Win;
  16. struct Menu *MyMenuStrip;
  17. APTR VisInfo;
  18. Object *WinObj;
  19. struct Gadget *MainLayout;
  20. STRPTR Screen;
  21.  
  22. static UWORD chip forwardData[26] =
  23. {
  24.     /* Plane 0 */
  25.     0x0000,0x0000,0x0000,0x0000,0x0410,0x0000,0x0618,0x0000,
  26.     0x071C,0x0000,0x079E,0x0000,0x07DF,0x0000,0x079E,0x0000,
  27.     0x071C,0x0000,0x0618,0x0000,0x0410,0x0000,0x0000,0x0000,
  28.     0x0000,0x0000
  29. };
  30.  
  31. static struct Image ForwardButton =
  32. {
  33.     0, 0,      /* LeftEdge, TopEdge */
  34.     20, 13, 1,  /* Width, Height, Depth */
  35.     forwardData,    /* ImageData */
  36.     0x0001, 0x0000, /* PlanePick, PlaneOnOff */
  37.     NULL        /* NextImage */
  38. };
  39.  
  40. static UWORD chip playData[26] =
  41. {
  42.     /* Plane 0 */
  43.     0x0000,0x0000,0x0000,0x0000,0x1003,0xDE00,0x1C03,0xDE00,
  44.     0x1F03,0xDE00,0x1FC3,0xDE00,0x1FF3,0xDE00,0x1FC3,0xDE00,
  45.     0x1F03,0xDE00,0x1C03,0xDE00,0x1003,0xDE00,0x0000,0x0000,
  46.     0x0000,0x0000
  47. };
  48.  
  49. static struct Image PlayButton =
  50. {
  51.     0, 0,      /* LeftEdge, TopEdge */
  52.     26, 13, 1,  /* Width, Height, Depth */
  53.     playData,   /* ImageData */
  54.     0x0001, 0x0000, /* PlanePick, PlaneOnOff */
  55.     NULL        /* NextImage */
  56. };
  57.  
  58. static UWORD chip rewindData[26] =
  59. {
  60.     /* Plane 0 */
  61.     0x0000,0x0000,0x0000,0x0000,0x0082,0x0000,0x0186,0x0000,
  62.     0x038E,0x0000,0x079E,0x0000,0x0FBE,0x0000,0x079E,0x0000,
  63.     0x038E,0x0000,0x0186,0x0000,0x0082,0x0000,0x0000,0x0000,
  64.     0x0000,0x0000
  65. };
  66.  
  67. static struct Image RewindButton =
  68. {
  69.     0, 0,      /* LeftEdge, TopEdge */
  70.     20, 13, 1,  /* Width, Height, Depth */
  71.     rewindData, /* ImageData */
  72.     0x0001, 0x0000, /* PlanePick, PlaneOnOff */
  73.     NULL        /* NextImage */
  74. };
  75.  
  76. static UWORD chip stopData[26] =
  77. {
  78.     /* Plane 0 */
  79.     0x0000,0x0000,0x0000,0x0000,0x1FF0,0x2000,0x1FF0,0x7000,
  80.     0x1FF0,0xF800,0x1FF1,0xFC00,0x1FF3,0xFE00,0x1FF0,0x0000,
  81.     0x1FF3,0xFE00,0x1FF3,0xFE00,0x1FF3,0xFE00,0x0000,0x0000,
  82.     0x0000,0x0000
  83. };
  84.  
  85. static struct Image StopButton =
  86. {
  87.     0, 0,      /* LeftEdge, TopEdge */
  88.     26, 13, 1,  /* Width, Height, Depth */
  89.     stopData,   /* ImageData */
  90.     0x0001, 0x0000, /* PlanePick, PlaneOnOff */
  91.     NULL        /* NextImage */
  92. };
  93.  
  94. typedef enum { M_SelDev = 1, M_EditTitles, M_Iconify, M_Quit } MenuIDs;
  95.  
  96. struct NewMenu CompactMenu[] =
  97. {
  98.     NM_TITLE,   MENU_PROJECT,    NULL, 0, 0, NULL,
  99.     NM_ITEM,    MENU_DEVICE,    NULL,  0, 0, (APTR)M_SelDev,
  100.     NM_ITEM,    MENU_TITLES,    NULL,  0, 0, (APTR)M_EditTitles,
  101.     NM_ITEM,    NM_BARLABEL,    NULL, 0, 0, NULL,
  102.     NM_ITEM,    MENU_ICONIFY,    NULL,  0, 0, (APTR)M_Iconify,
  103.     NM_ITEM,    MENU_QUIT,        NULL,  0, 0, (APTR)M_Quit,
  104.     NM_END,     NULL,           NULL, 0, 0, NULL
  105. };
  106.  
  107. struct TextAttr CompactAttr = { NULL, 0, FS_NORMAL, FPF_PROPORTIONAL };
  108. struct TextAttr PanelAttr = { NULL, 0, FS_NORMAL, 0L };
  109. struct TextFont *CompactFont;
  110. struct TextFont *PanelFont;
  111. struct TextFont *ScreenFont;
  112.  
  113. struct List dummyList;
  114.  
  115. /* handler functions for the buttons, since I want to act on them from
  116.  * rawkey messages too. Gadgets don't support rawkey command keys (as of yet
  117.  * anyway) because it is generally a bad practise to bind a rawkey to a gadget. */
  118. static void
  119. SeekCD(ULONG id)
  120. {
  121.   /* notifications from the rewind/fast forward buttons */
  122.     ULONG status;
  123.     static struct timeval tv1, tv2, tv3;
  124.  
  125.     GetSysTime(&tv1);
  126.     tv3 = tv1;
  127.     SubTime(&tv3, &tv2);
  128.  
  129.     GetAttr(CDPANEL_Status, GList[G_Panel], &status);
  130.  
  131.     if ((status == CDP_PLAYING || status == CDP_SEEKING)
  132.         && (tv3.tv_secs || tv3.tv_micro >= 190000))
  133.     {
  134.         tv2 = tv1;                     /* only seek four times per second */
  135.         switch (id)
  136.          {
  137.          case G_Backward:
  138.              CD_Seek(-2);
  139.              break;
  140.  
  141.          case G_Forward:
  142.              CD_Seek(2);
  143.              break;
  144.          }
  145.         if (status == CDP_PLAYING)
  146.             SetGadgetAttrs(GList[G_Panel], Win, NULL, CDPANEL_Status, CDP_SEEKING, TAG_END);
  147.     }
  148. }
  149.  
  150. static void
  151. PlayCD(void)
  152. {
  153.     ULONG status;
  154.  
  155.     GetAttr(CDPANEL_Status, GList[G_Panel], &status);
  156.  
  157.     if (status == CDP_PLAYING || status == CDP_SEEKING)
  158.     {
  159.         SetGadgetAttrs(GList[G_Panel], Win, NULL, CDPANEL_Status, CDP_PAUSED, TAG_END);
  160.         CD_PauseResume(0x00);
  161.     }
  162.     else if (status == CDP_PAUSED)
  163.     {
  164.         SetGadgetAttrs(GList[G_Panel], Win, NULL, CDPANEL_Status, CDP_PLAYING, TAG_END);
  165.         CD_PauseResume(0x01);
  166.     }
  167.     else if (status == CDP_STOPPED)
  168.     {
  169.         ULONG track;
  170.  
  171.         SetGadgetAttrs(GList[G_Panel], Win, NULL, CDPANEL_Status, CDP_PLAYING, TAG_END);
  172.         GetAttr(LISTBROWSER_Selected, GList[G_List], &track);
  173.         if (track++ > 100)
  174.             track = 1;
  175.         CD_Play(track);
  176.         AbortIO(TimerIO);
  177.     }
  178.     else if (status == CDP_EJECTED || status == CDP_EMPTY)
  179.     {
  180.         CD_Eject(0x00);
  181.         Delay(20);                     /* give it a chance to settle. I really hate these kind of things */
  182.         if (Tracks = CD_ReadTOC())
  183.             CD_Play(1);
  184.     }
  185. }
  186.  
  187. static void
  188. StopCD(void)
  189. {
  190.     ULONG status;
  191.  
  192.     GetAttr(CDPANEL_Status, GList[G_Panel], &status);
  193.  
  194.     JustStarted = FALSE;
  195.  
  196.     if (status == CDP_STOPPED || status == CDP_EMPTY || status == CDP_EJECTED)
  197.     {
  198.         SetGadgetAttrs(GList[G_Panel], Win, NULL, CDPANEL_Status, CDP_EJECTED, TAG_END);
  199.         CD_Eject(0x01);
  200.     }
  201.     else
  202.     {
  203.         SetGadgetAttrs(GList[G_List], Win, NULL, LISTBROWSER_Selected, ~0, TAG_END);
  204.         SetGadgetAttrs(GList[G_Panel], Win, NULL, CDPANEL_Status, CDP_STOPPED, TAG_END);
  205.         CD_Stop();
  206.         AbortIO(TimerIO);
  207.     }
  208. }
  209.  
  210. static void
  211. SelectCD(LONG dir)
  212. {
  213.     LONG track;
  214.     ULONG status;
  215.  
  216.     GetAttr(CDPANEL_Track,  GList[G_Panel], (ULONG *) & track);
  217.     GetAttr(CDPANEL_Status, GList[G_Panel], &status);
  218.  
  219.     if (dir > 0)
  220.     {
  221.          if (track < 100)
  222.          {
  223.              track++;
  224.              if (track > Tracks)
  225.                  track = Tracks;
  226.          }
  227.          else
  228.              track = 1;
  229.     }
  230.     else
  231.     {
  232.         if (track > 100)
  233.             track = Tracks;
  234.         track--;
  235.         if (track < 1)
  236.             track = 1;
  237.     }
  238.     SetGadgetAttrs(GList[G_List], Win, NULL, LISTBROWSER_Selected, track-1, LISTBROWSER_MakeVisible, track-1, TAG_END);
  239.     SetGadgetAttrs(GList[G_Panel], Win, NULL, CDPANEL_Track, track, TAG_END);
  240.  
  241.     if (status == CDP_PLAYING || status == CDP_SEEKING)
  242.     {
  243.          CD_Play(track);
  244.          AbortIO(TimerIO);
  245.     }
  246. }
  247.  
  248. static struct Hook IDCMPHook;
  249.  
  250. static ULONG __asm __saveds
  251. IDCMPHookFunc(register __a0 struct Hook * hook, register __a2 Object * WinObj, register __a1 struct IntuiMessage *msg)
  252. {
  253.     /* this function is hooked from windowclass to grab some IDCMP messages */
  254.  
  255.     switch (msg->Class)
  256.     {
  257.     case IDCMP_IDCMPUPDATE:
  258.     {
  259.         ULONG id = GetTagData(GA_ID, 0, msg->IAddress);
  260.  
  261.         if (FindTagItem(GA_Selected, msg->IAddress) && (id == G_Backward || id == G_Forward))
  262.         {
  263.             SeekCD(id);
  264.         }
  265.         break;
  266.     }
  267.  
  268.     case IDCMP_RAWKEY:
  269.         switch (msg->Code)
  270.         {
  271.         case 0x43:  /* enter */
  272.         case 0x44:  /* return */
  273.             if (!(msg->Qualifier & IEQUALIFIER_REPEAT))
  274.             {
  275.                 DoGadgetMethod(GList[G_Stop], Win, NULL, GM_KEYACTIVE, NULL, msg, (ULONG)'\n' );
  276.                 StopCD();
  277.             }
  278.             break;
  279.         case 0xc3:
  280.         case 0xc4:
  281.             DoGadgetMethod(GList[G_Stop], Win, NULL, GM_KEYINACTIVE, NULL, msg, (ULONG)'\n', 0 );
  282.             break;
  283.  
  284.         case 0x40:  /* space */
  285.             if (!(msg->Qualifier & IEQUALIFIER_REPEAT))
  286.             {
  287.                 DoGadgetMethod(GList[G_Play], Win, NULL, GM_KEYACTIVE, NULL, msg, (ULONG)' ' );
  288.                 PlayCD();
  289.             }
  290.             break;
  291.         case 0xc0:
  292.             DoGadgetMethod(GList[G_Play], Win, NULL, GM_KEYINACTIVE, NULL, msg, (ULONG)' ', 0 );
  293.             break;
  294.  
  295.         case 0x4f:  /* cursor left */
  296.             DoGadgetMethod(GList[G_Backward], Win, NULL, GM_KEYACTIVE, NULL, msg, (ULONG)'<' );
  297.             SeekCD(G_Backward);
  298.             break;
  299.  
  300.         case 0xcf:  /* cursor left (keyup)*/
  301.             SetGadgetAttrs(GList[G_Panel], Win, NULL, CDPANEL_Status, CDP_PLAYING, TAG_END);
  302.             DoGadgetMethod(GList[G_Backward], Win, NULL, GM_KEYINACTIVE, NULL, msg, (ULONG)'>', 0 );
  303.             break;
  304.  
  305.         case 0x4e:  /* cursor right */
  306.             DoGadgetMethod(GList[G_Forward], Win, NULL, GM_KEYACTIVE, NULL, msg, (ULONG)'>' );
  307.             SeekCD(G_Forward);
  308.             break;
  309.  
  310.         case 0xce:  /* cursor right (keyup) */
  311.             SetGadgetAttrs(GList[G_Panel], Win, NULL, CDPANEL_Status, CDP_PLAYING, TAG_END);
  312.             DoGadgetMethod(GList[G_Forward], Win, NULL, GM_KEYINACTIVE, NULL, msg, (ULONG)'>', 0 );
  313.             break;
  314.  
  315.         case 0x4c:  /* cursor up */
  316.             SelectCD(-1);
  317.             break;
  318.  
  319.         case 0x4d:  /* cursor down */
  320.             SelectCD(+1);
  321.             break;
  322.  
  323.         case 0x45|0x80: /* escape up */
  324.             done = TRUE;
  325.             break;
  326.             
  327.         case 0x01:
  328.         case 0x1d:
  329.             CD_Play(1);
  330.             break;
  331.             
  332.         case 0x02:
  333.         case 0x1e:
  334.             CD_Play(2);
  335.             break;
  336.             
  337.         case 0x03:
  338.         case 0x1f:
  339.             CD_Play(3);
  340.             break;
  341.             
  342.         case 0x04:
  343.         case 0x2d:
  344.             CD_Play(4);
  345.             break;
  346.             
  347.         case 0x05:
  348.         case 0x2e:
  349.             CD_Play(5);
  350.             break;
  351.             
  352.         case 0x06:
  353.         case 0x2f:
  354.             CD_Play(6);
  355.             break;
  356.             
  357.         case 0x07:
  358.         case 0x3d:
  359.             CD_Play(7);
  360.             break;
  361.             
  362.         case 0x08:
  363.         case 0x3e:
  364.             CD_Play(8);
  365.             break;
  366.             
  367.         case 0x09:
  368.         case 0x3f:
  369.             CD_Play(9);
  370.             break;
  371.             
  372.         case 0x0a:
  373.         case 0x0f:
  374.             CD_Play(10);
  375.             break;
  376.         }
  377.         break;
  378.     }
  379.     return 0;
  380. }
  381.  
  382. struct Gadget *
  383. CreateMainLayout( void )
  384. {
  385.     struct Image *i;
  386.  
  387.     SetAttrs( GList[G_Panel], 
  388.             CDPANEL_NoBorder, FALSE, 
  389.             TAG_END );
  390.  
  391.     return HGroupObject, Offset(1,1,1,1), Spacing(1),
  392.         GA_TextAttr, & CompactAttr,
  393.         GA_DrawInfo, Dri,
  394.         LAYOUT_DeferLayout, TRUE,
  395.         LAYOUT_AddChild, VGroupObject, Spacing(1),
  396.  
  397.             /* Layout hierarchies are so hard to explain.. we have the
  398.              * window split to the status panel side and the listview side,
  399.              * with four buttons below the status panel. */
  400.  
  401.             StartMember, GList[G_Panel],
  402.                 CHILD_NoDispose, TRUE,
  403.                 CHILD_CacheDomain, FALSE,
  404.  
  405.             StartHGroup,
  406.                 LAYOUT_SpaceInner, FALSE,
  407.  
  408.                 StartMember, GList[G_Backward] = ButtonObject,
  409.                     GA_Image, i = & RewindButton,
  410.                     GA_RelVerify, TRUE,
  411.                     GA_ID, G_Backward,
  412.                     ICA_TARGET, ICTARGET_IDCMP,
  413.                     BUTTON_FillPen, Dri->dri_Pens[BACKGROUNDPEN],
  414.                     CLASSACT_CommKey, "<",
  415.                     End,
  416.                     CHILD_MinWidth, i->Width,
  417.                     CHILD_WeightMinimum, TRUE,
  418.  
  419.                 StartMember, GList[G_Play] = ButtonObject,
  420.                     GA_Image, i = & PlayButton,
  421.                     GA_RelVerify, TRUE,
  422.                     GA_ID, G_Play,
  423.                     BUTTON_FillPen, Dri->dri_Pens[BACKGROUNDPEN],
  424.                     End,
  425.                     CHILD_MinWidth, i->Width,
  426.                     CHILD_WeightMinimum, TRUE,
  427.  
  428.                 StartMember, GList[G_Forward] = ButtonObject,
  429.                     GA_Image, i = & ForwardButton,
  430.                     GA_RelVerify, TRUE,
  431.                     GA_ID, G_Forward,
  432.                     ICA_TARGET, ICTARGET_IDCMP,
  433.                     BUTTON_FillPen, Dri->dri_Pens[BACKGROUNDPEN],
  434.                     CLASSACT_CommKey, ">",
  435.                     End,
  436.                     CHILD_MinWidth, i->Width,
  437.                     CHILD_WeightMinimum, TRUE,
  438.  
  439.                 StartMember, GList[G_Stop] = ButtonObject,
  440.                     GA_Image, i = & StopButton,
  441.                     GA_RelVerify, TRUE,
  442.                     GA_ID, G_Stop,
  443.                     BUTTON_FillPen, Dri->dri_Pens[BACKGROUNDPEN],
  444.                     End,
  445.                     CHILD_MinWidth, i->Width,
  446.                     CHILD_WeightMinimum, TRUE,
  447.                 End,
  448.                 CHILD_WeightedHeight, 0,
  449.             End,
  450.             CHILD_WeightedWidth, 0,
  451.  
  452.         StartVGroup, Spacing(1),
  453.  
  454.             /* This is the listview group, with two buttons above it */
  455.  
  456.             StartHGroup, Spacing(1),
  457.                 LAYOUT_EvenSize, TRUE,
  458.  
  459.                 StartMember, GList[G_Titles] = ButtonObject,
  460.                     GA_Text, GS(B_TITLES),
  461.                     GA_TextAttr, & CompactAttr,
  462.                     GA_RelVerify, TRUE,
  463.                     GA_ID, G_Titles,
  464.                     End,
  465.  
  466.                 StartMember, GList[G_Program] = ButtonObject,
  467.                     GA_Text, GS(B_PROGR),
  468.                     GA_TextAttr, & CompactAttr,
  469.                     GA_RelVerify, TRUE,
  470.                     GA_ID, G_Program,
  471.                     End,
  472.                 End,
  473.                 /* force the button smaller than it tells is the minimum size.
  474.                  * This gets rid of a few pixels that aren't needed, to really
  475.                  * minimize the layout.. It's called _Compact_Player, after all.
  476.                  */
  477.                 CHILD_WeightedHeight, 0,
  478.  
  479.             StartMember, GList[G_List] = ListBrowserObject,
  480.                 LISTBROWSER_Labels, TrackList ? TrackList : &dummyList,
  481.                 LISTBROWSER_VerticalProp, FALSE,
  482.                 LISTBROWSER_ShowSelected, TRUE,
  483.                 GA_ReadOnly, TrackList ? FALSE : TRUE,
  484.                 GA_TextAttr, & CompactAttr,
  485.                 GA_RelVerify, TRUE,
  486.                 GA_ID, G_List,
  487.                 End,
  488.             End,
  489.         End;
  490. }
  491.  
  492. struct Gadget *
  493. CreateZippedLayout( void )
  494. {
  495.     memset(&GList[G_Backward], 0, (ULONG)&GList[GG_MAX1]-(ULONG)&GList[G_Backward]);
  496.  
  497.     /* By sharing the status panel gadget between the zoomed and normal layouts,
  498.      * we retain the play graph of the gadget. This is allowed by V41 layout.gadget,
  499.      * which has the NoDispose attribute for suppressing automatic child dispose.
  500.      */
  501.  
  502.     SetAttrs( GList[G_Panel], 
  503.             CDPANEL_NoBorder, TRUE, 
  504.             TAG_END );
  505.  
  506.     return HGroupObject,
  507.         GA_DrawInfo, Dri,
  508.         LAYOUT_DeferLayout, TRUE,
  509.         LAYOUT_FixedHoriz, FALSE,
  510.         LAYOUT_FixedVert, FALSE,
  511.  
  512.         StartMember, GList[G_Panel],
  513.             CHILD_NoDispose, TRUE,
  514.                CHILD_CacheDomain, FALSE,
  515.  
  516.         End;
  517. }
  518.  
  519. struct Window *
  520. OpenMainWindow(ULONG X, ULONG Y)
  521. {
  522.     if (!ButtonBase)                   /* force it open */
  523.         return NULL;
  524.  
  525.     if (Win)
  526.         return Win;
  527.  
  528.     NewList(&dummyList);
  529.  
  530.     if (!(Scr = LockPubScreen(Screen)))
  531.         Scr = LockPubScreen(NULL);
  532.  
  533.     if (Scr)
  534.     {
  535.         ScreenFont = OpenFont(Scr->Font);
  536.  
  537.         if (!CompactAttr.ta_Name)
  538.         {
  539.             CompactAttr = *Scr->Font;
  540.         }
  541.         if (!PanelAttr.ta_Name)
  542.         {
  543.             PanelAttr.ta_Name = GfxBase->DefaultFont->tf_Message.mn_Node.ln_Name;
  544.             PanelAttr.ta_YSize = GfxBase->DefaultFont->tf_YSize;
  545.         }
  546.  
  547.         if ((CompactFont = OpenDiskFont(&CompactAttr)) && (PanelFont = OpenDiskFont(&PanelAttr)))
  548.         {
  549.             if ((Dri = GetScreenDrawInfo(Scr)) && (VisInfo = GetVisualInfo(Scr, TAG_END)))
  550.             {
  551.                 if ((MyMenuStrip = CreateMenus(CompactMenu, TAG_END)) &&
  552.                     LayoutMenus(MyMenuStrip, VisInfo, GTMN_NewLookMenus, TRUE, TAG_END))
  553.                 {
  554.                     struct IBox ZoomSize;
  555.  
  556.                     GList[G_Panel] = CDPanelObject, CDPANEL_Status, CDP_EMPTY, GA_TextAttr, &PanelAttr, End;
  557.  
  558.                     MainLayout = CreateZippedLayout();
  559.  
  560.                     LayoutLimits(MainLayout, (struct LayoutLimits *) & ZoomSize, NULL, Scr);
  561.                     ZoomSize.Top = -1;
  562.                     ZoomSize.Left = -1;
  563.                     ZoomSize.Width += Scr->WBorLeft + Scr->WBorRight + 2;
  564.                     ZoomSize.Height += Scr->WBorTop + ScreenFont->tf_YSize + 1 + Scr->WBorBottom + 2;
  565.  
  566.                     DisposeObject(MainLayout);
  567.  
  568.                     MainLayout = CreateMainLayout();
  569.  
  570.                     if (MainLayout)
  571.                     {
  572.                         struct DiskObject *icon = NULL;
  573.  
  574.                         IDCMPHook.h_Entry = (HOOKFUNC) IDCMPHookFunc;
  575.                         IDCMPHook.h_SubEntry = NULL;
  576.                         IDCMPHook.h_Data = NULL;
  577.  
  578.                         if (_WBenchMsg)
  579.                             icon = GetDiskObject(_WBenchMsg->sm_ArgList->wa_Name);
  580.                         if (!icon)
  581.                             icon = GetDiskObject("PROGDIR:CompactPlayer");
  582.  
  583.                         if (icon)
  584.                         {
  585.                             icon->do_CurrentY = icon->do_CurrentX = NO_ICON_POSITION;
  586.                         }
  587.  
  588.                         if (WinObj = WindowObject,
  589.                                 WA_DepthGadget,        TRUE,
  590.                                 WA_DragBar,            TRUE,
  591.                                 WA_CloseGadget,        TRUE,
  592.                                 WA_Activate,        TRUE,
  593.                                 LayoutBase->cl_Lib.lib_Version >= 41 ?
  594.                             WA_Zoom : TAG_IGNORE,    &ZoomSize,    /* V41 layout.gadget knows CHILD_NoDispose */
  595.                                 WA_Top,                Y,
  596.                                 WA_Left,            X,
  597.                                 WA_PubScreen,        Scr,
  598.                                 WA_Title,            GS(COMPACTPLAYER),
  599.                                 WA_ScreenTitle,        GS(TITLE_COPYRIGHT),
  600.                                 WA_AutoAdjust,        TRUE,
  601.                                 WINDOW_Layout,        MainLayout,
  602.                                 WINDOW_IDCMPHook,    &IDCMPHook,
  603.                                 WINDOW_IDCMPHookBits, IDCMP_IDCMPUPDATE | IDCMP_RAWKEY,
  604.                                 WA_IDCMP,            IDCMP_IDCMPUPDATE | IDCMP_RAWKEY,
  605.                                 WINDOW_MenuStrip,    MyMenuStrip,
  606.                                 WINDOW_AppPort,        AppPort,
  607.                                 WINDOW_SharedPort,    WinPort,
  608.                                 WINDOW_Icon,        icon, /* windowclass will free this */
  609.                                 WINDOW_IconifyGadget, TRUE,
  610.                                 TAG_END)
  611.                             )
  612.                         {
  613.                             Win = CA_OpenWindow(WinObj);
  614.  
  615.                             return Win;
  616.                         }
  617.                         DisposeObject(MainLayout);
  618.                         MainLayout = NULL;
  619.                     }
  620.                     ErrorMsg(GS(GUI_FAIL));
  621.                     
  622.                     DisposeObject( GList[G_Panel] );
  623.                 }
  624.             }
  625.         }
  626.         else
  627.             ErrorMsg(GS(FONTS_FAIL));
  628.     }
  629.     return NULL;
  630. }
  631.  
  632. void
  633. CloseMainWindow(void)
  634. {
  635.     if (TrackList)
  636.     {
  637.         SetGadgetAttrs(GList[G_List], Win, NULL, LISTBROWSER_Labels, ~0, TAG_END);
  638.         FreeBrowserNodes(TrackList);
  639.         TrackList = NULL;
  640.     }
  641.     if (WinObj)
  642.     {
  643.         DisposeObject(WinObj);
  644.         DisposeObject(GList[G_Panel]);
  645.         MainLayout = NULL;
  646.         WinObj = NULL;
  647.         Win = NULL;
  648.         memset(&GList[G_Panel], 0, (ULONG)&GList[GG_MAX1]-(ULONG)&GList[G_Panel]);
  649.     }
  650.     if (MyMenuStrip)
  651.     {
  652.         FreeMenus(MyMenuStrip);
  653.         MyMenuStrip = NULL;
  654.     }
  655.     if (VisInfo)
  656.     {
  657.         FreeVisualInfo(VisInfo);
  658.         VisInfo = NULL;
  659.     }
  660.     if (Dri)
  661.     {
  662.         FreeScreenDrawInfo(Scr, Dri);
  663.         Dri = NULL;
  664.     }
  665.     if (Scr)
  666.     {
  667.         UnlockPubScreen(0, Scr);
  668.         Scr = NULL;
  669.     }
  670.     if (CompactFont)
  671.     {
  672.         CloseFont(CompactFont);
  673.         CompactFont = NULL;
  674.     }
  675.     if (PanelFont)
  676.     {
  677.         CloseFont(PanelFont);
  678.         PanelFont = NULL;
  679.     }
  680.     if (ScreenFont)
  681.     {
  682.         CloseFont(ScreenFont);
  683.         ScreenFont = NULL;
  684.     }
  685. }
  686.  
  687. void
  688. Iconify(void)
  689. {
  690.     CA_Iconify( WinObj );
  691.     CA_CloseWindow( ListWinObj );
  692.     CA_CloseWindow( ConfWinObj );
  693.     Win = ListWin = ConfWin = NULL;
  694.  
  695.     SetAttrs(WinObj, WA_PubScreen, NULL, TAG_END);
  696.     SetAttrs(ListWinObj, WA_PubScreen, NULL, TAG_END);
  697.     SetAttrs(ConfWinObj, WA_PubScreen, NULL, TAG_END);
  698.  
  699.     UnlockPubScreen( NULL, Scr );
  700. }
  701.  
  702. void
  703. UnIconify(void)
  704. {
  705.     if (!(Scr = LockPubScreen(Screen)))
  706.         Scr = LockPubScreen(NULL);
  707.  
  708.     SetAttrs(WinObj, WA_PubScreen, Scr, TAG_END);
  709.     SetAttrs(ListWinObj, WA_PubScreen, Scr, TAG_END);
  710.     SetAttrs(ConfWinObj, WA_PubScreen, Scr, TAG_END);
  711.  
  712.     Win     = CA_OpenWindow( WinObj );
  713.     ListWin = CA_OpenWindow( ListWinObj );
  714.     ConfWin = CA_OpenWindow( ConfWinObj );
  715. }
  716.  
  717. void
  718. MainWindowIDCMP()
  719. {
  720.     ULONG result;
  721.     UWORD code;
  722.     BOOL iconify = FALSE;
  723.  
  724.     while ((result = CA_HandleInput(WinObj, &code)) != WMHI_LASTMSG)
  725.     {
  726.         /* Windowclass translates key events to GADGETUPs on its own */
  727.  
  728.         switch (result & WMHI_CLASSMASK)
  729.         {
  730.          case WMHI_CLOSEWINDOW:
  731.              done = TRUE;
  732.              break;
  733.  
  734.          case WMHI_GADGETUP:
  735.             switch (result & WMHI_GADGETMASK)
  736.              {
  737.              case G_Backward:
  738.                  {
  739.                      ULONG status;
  740.  
  741.                      /* only do this if not playing. During playing do a continous
  742.                       * seek by listening to the IDCMP messages */
  743.  
  744.                      GetAttr(CDPANEL_Status, GList[G_Panel], &status);
  745.  
  746.                      if (status == CDP_STOPPED)
  747.                      {
  748.                         SelectCD(-1);
  749.                      }
  750.                      else
  751.                      {
  752.                         static struct timeval lasttime;
  753.                         struct timeval tv1, tv2;
  754.                         
  755.                         if (status == CDP_SEEKING)
  756.                             SetGadgetAttrs(GList[G_Panel], Win, NULL, CDPANEL_Status, CDP_PLAYING, TAG_END);
  757.                          
  758.                          GetSysTime(&tv1);
  759.                          tv2 = tv1;
  760.                          SubTime(&tv2, &lasttime);
  761.                          lasttime = tv1;
  762.                          
  763.                          if (tv2.tv_secs == 0 && tv2.tv_micro <= 900000)
  764.                              SelectCD(-1);    /* doubleclick */
  765.                      }
  766.                  }
  767.                  break;
  768.  
  769.              case G_Play:
  770.                  PlayCD(); /* see earlier in this file */
  771.                  break;
  772.  
  773.              case G_Forward:
  774.                  {
  775.                      ULONG status;
  776.  
  777.                      /* As with G_Backward */
  778.  
  779.                      GetAttr(CDPANEL_Status, GList[G_Panel], &status);
  780.  
  781.                      if (status == CDP_STOPPED)
  782.                      {
  783.                         SelectCD(+1);
  784.                      }
  785.                      else
  786.                      {
  787.                         static struct timeval lasttime;
  788.                         struct timeval tv1, tv2;
  789.                         
  790.                         if (status == CDP_SEEKING)
  791.                             SetGadgetAttrs(GList[G_Panel], Win, NULL, CDPANEL_Status, CDP_PLAYING, TAG_END);
  792.                          
  793.                          GetSysTime(&tv1);
  794.                          tv2 = tv1;
  795.                          SubTime(&tv2, &lasttime);
  796.                          lasttime = tv1;
  797.                          
  798.                          if (tv2.tv_secs == 0 && tv2.tv_micro <= 900000)
  799.                              SelectCD(+1);    /* doubleclick */
  800.                      }
  801.                  }
  802.                  break;
  803.  
  804.              case G_Stop:
  805.                  StopCD(); /* see earlier */
  806.                  break;
  807.  
  808.              case G_Titles:
  809.                  {
  810.                      ULONG status;
  811.  
  812.                      /* open up the list list editor */
  813.  
  814.                      OpenListWindow(Win->LeftEdge + Win->Width, Win->TopEdge);
  815.  
  816.                      GetAttr(CDPANEL_Status, GList[G_Panel], &status);
  817.  
  818.                      if (status != CDP_EJECTED && status != CDP_EMPTY)
  819.                      {
  820.                          UpdateTitleEditor();
  821.                      }
  822.                  }
  823.                  break;
  824.  
  825.              case G_Program:
  826.                 /* program editor unimplemented */
  827.                  break;
  828.  
  829.              case G_List:
  830.                 /* user selected a track in the listview, jump to it and play */
  831.                  CD_Play(code + 1);
  832.                  AbortIO(TimerIO);
  833.                  break;
  834.              }
  835.             break;
  836.  
  837.         case WMHI_MENUPICK:
  838.             code = result & WMHI_MENUMASK;
  839.             while (code != MENUNULL)
  840.             {
  841.                 struct MenuItem *mi = ItemAddress( MyMenuStrip, code );
  842.                 switch ((ULONG)GTMENUITEM_USERDATA( mi ))
  843.                 {
  844.                 case M_SelDev:
  845.                     OpenConfWindow(Win->LeftEdge, Win->TopEdge);
  846.                     break;
  847.  
  848.                 case M_EditTitles:
  849.                     {
  850.                         ULONG status;
  851.  
  852.                         OpenListWindow(Win->LeftEdge + Win->Width, Win->TopEdge);
  853.  
  854.                         GetAttr(CDPANEL_Status, GList[G_Panel], &status);
  855.  
  856.                         if (status != CDP_EJECTED && status != CDP_EMPTY)
  857.                         {
  858.                             UpdateTitleEditor();
  859.                         }
  860.                     }
  861.                     break;
  862.  
  863.                 case M_Iconify:
  864.                     iconify = TRUE;
  865.                     break;
  866.  
  867.                 case M_Quit:
  868.                     done = TRUE;
  869.                     break;
  870.                 }
  871.                 code = mi->NextSelect;
  872.             }
  873.             break;
  874.  
  875.         case WMHI_NEWSIZE:
  876.             if (result & WMF_ZIPWINDOW)
  877.             {
  878.                 struct Gadget *l;
  879.                 if (result & WMF_ZOOMED)
  880.                     l = CreateZippedLayout();
  881.                 else
  882.                     l = CreateMainLayout();
  883.                 if (l)
  884.                 {
  885.                     SetAttrs( WinObj, WINDOW_Layout, MainLayout = l, TAG_END );
  886.                 }
  887.             }
  888.             break;
  889.  
  890.         case WMHI_UNICONIFY:
  891.             UnIconify();
  892.             break;
  893.  
  894.         case WMHI_ICONIFY:
  895.             iconify = TRUE;
  896.             break;
  897.         }
  898.     }
  899.     if (iconify)
  900.     {
  901.         Iconify();
  902.     }
  903. }
  904.