4 ** Copyright (C) 1993,94,95,96 Bernardo Innocenti
6 ** Handle Song Information panel.
9 #include <exec/nodes.h>
10 #include <intuition/intuition.h>
11 #include <intuition/gadgetclass.h>
12 #include <libraries/gadtools.h>
14 #include <proto/exec.h>
15 #include <proto/intuition.h>
16 #include <proto/gadtools.h>
17 #include <proto/xmodule.h>
19 #include "XModulePriv.h"
57 /* Local function Prototypes */
59 static void SongInfoPostOpen (void);
61 static void SongListClicked (struct WinUserData *wud);
62 static void SongNameClicked (struct WinUserData *wud);
63 static void AuthorNameClicked (struct WinUserData *wud);
64 static void TempoClicked (struct WinUserData *wud);
65 static void SpeedClicked (struct WinUserData *wud);
66 static void RestartClicked (struct WinUserData *wud);
67 static void NewSongClicked (struct WinUserData *wud);
68 static void OpenSongClicked (struct WinUserData *wud);
69 static void DelSongClicked (struct WinUserData *wud);
70 static void SaveSongClicked (struct WinUserData *wud);
72 static void SongInfoMiMergeSongs (void);
73 static void SongInfoMiJoinSongs (void);
74 static void SongInfoMiClearSong (void);
78 static struct NewMenu SongInfoNewMenu[] =
80 NM_TITLE, (STRPTR)MSG_SONG_MEN, NULL, 0, NULL, NULL,
81 NM_ITEM, (STRPTR)MSG_MERGE_SONGS_MEN, "M", 0, 0L, (APTR)SongInfoMiMergeSongs,
82 NM_ITEM, (STRPTR)MSG_JOIN_SONGS_MEN, "J", 0, 0L, (APTR)SongInfoMiJoinSongs,
83 NM_ITEM, (STRPTR)NM_BARLABEL, NULL, 0, 0L, NULL,
84 NM_ITEM, (STRPTR)MSG_CLEAR_MEN, "K", 0, 0L, (APTR)SongInfoMiClearSong,
85 NM_END, NULL, NULL, 0, 0L, NULL
90 static ULONG SongInfoArgs[] =
93 LISTVIEW_KIND, (ULONG)SongListClicked, 0, NULL, TAG_DONE,
95 BUTTON_KIND, (ULONG)NewSongClicked, MSG_UNDERSCORE_NEW_GAD, TAG_DONE,
96 BUTTON_KIND, (ULONG)OpenSongClicked, MSG_OPEN_GAD, TAG_DONE,
97 BUTTON_KIND, (ULONG)SaveSongClicked, MSG_SAVE_GAD, TAG_DONE,
98 BUTTON_KIND, (ULONG)DelSongClicked, MSG_DEL_GAD, TAG_DONE,
101 VGROUP_KIND, BBFT_RIDGE,
102 STRING_KIND, (ULONG)SongNameClicked, MSG_SONG_NAME_GAD, 31, TAG_DONE,
103 STRING_KIND, (ULONG)AuthorNameClicked, MSG_AUTHOR_NAME_GAD, 63, TAG_DONE,
105 HGROUP_KIND, BBFT_RIDGE,
107 INTEGER_KIND, (ULONG)TempoClicked, MSG_DEF_TEMPO_GAD, 3, TAG_DONE,
108 INTEGER_KIND, (ULONG)SpeedClicked, MSG_DEF_SPEED_GAD, 3, TAG_DONE,
109 INTEGER_KIND, (ULONG)RestartClicked, MSG_RESTART_GAD, 3, TAG_DONE,
112 NUMBER_KIND, MSG_LENGHT_GAD, 3, TAG_DONE,
113 NUMBER_KIND, MSG_NUM_PATTS_GAD, 3, TAG_DONE,
114 NUMBER_KIND, MSG_NUM_TRACKS_GAD, 3, TAG_DONE,
117 VGROUP_KIND, BBFT_RIDGE,
118 NUMBER_KIND, MSG_TOT_MOD_SIZE_GAD, 7, TAG_DONE,
119 NUMBER_KIND, MSG_TOT_INST_SIZE_GAD, 7, TAG_DONE,
126 XDEF LONG SongInfoWinTags[] =
128 XMWIN_NewMenu, (LONG)SongInfoNewMenu,
129 XMWIN_LayoutArgs, (LONG)SongInfoArgs,
130 XMWIN_GCount, SongInfo_CNT,
131 XMWIN_Title, MSG_SONGINFO_TITLE,
132 XMWIN_WindowFlags, WFLG_CLOSEGADGET,
133 XMWIN_IDCMPFlags, NUMBERIDCMP | STRINGIDCMP | LISTVIEWIDCMP | INTEGERIDCMP | BUTTONIDCMP | IDCMP_CLOSEWINDOW | IDCMP_REFRESHWINDOW | IDCMP_MENUPICK,
134 XMWIN_PostOpenFunc, (LONG)SongInfoPostOpen,
135 XMWIN_DropIconFunc, (LONG)ToolBoxDropIcon,
136 XMWIN_HelpNode, (LONG)"SongInfo",
142 static void SongInfoPostOpen (void)
144 UpdateSongInfoList();
150 /**********************/
151 /* SongInfo Functions */
152 /**********************/
155 GLOBALCALL void DetatchSongInfoList (void)
157 /* Detatches the SongInfo list from the listview gadget.
158 * Call UpdateSongInfoList() to re-attach it when you are done modifying it.
161 struct WinUserData *wud = WDescr[WID_SONGINFO].Wud;
164 GT_SetGadgetAttrs (wud->Gadgets[GD_SongList], wud->Win, NULL,
171 GLOBALCALL void UpdateSongInfoList (void)
173 /* Updates the SongInfo listview gadget */
175 struct WinUserData *wud = WDescr[WID_SONGINFO].Wud;
180 ObtainSemaphoreShared (&XModuleBase->xm_BaseLock);
182 /* Workaround for Pre-V39 ObtainSemaphoreShared() bug (see autodoc) */
184 /* Try to get the shared semaphore */
185 if (!AttemptSemaphoreShared (&XModuleBase->xm_BaseLock))
186 /* Check if we can get the exclusive version */
187 if (!AttemptSemaphore (&XModuleBase->xm_BaseLock))
188 /* Oh well, wait for the shared lock */
189 ObtainSemaphoreShared (&XModuleBase->xm_BaseLock);
190 #endif /* OS30_ONLY */
192 if (XModuleBase->xm_CurrentSong)
194 struct SongInfo *tmp = (struct SongInfo *)XModuleBase->xm_Songs.mlh_Head;
197 /* Find current song number */
199 while (tmp != XModuleBase->xm_CurrentSong)
201 tmp = (struct SongInfo *)tmp->Link.ln_Succ;
205 GT_SetGadgetAttrs (wud->Gadgets[GD_SongList], wud->Win, NULL,
206 GTLV_Labels, &XModuleBase->xm_Songs,
207 GTLV_Selected, songnum,
208 GTLV_MakeVisible, songnum,
212 ReleaseSemaphore (&XModuleBase->xm_BaseLock);
218 GLOBALCALL void UpdateSongInfo (void)
220 /* Update information on the current song */
222 struct WinUserData *wud = WDescr[WID_SONGINFO].Wud;
227 if (si = xmLockActiveSong (SM_SHARED))
230 GD_SongName, si->Title,
231 GD_AuthorName, si->Author,
232 GD_Tempo, si->GlobalTempo,
233 GD_Speed, si->GlobalSpeed,
234 GD_SongLength, si->Length,
235 GD_Patterns, si->NumPatterns,
236 GD_Tracks, si->MaxTracks,
237 GD_Restart, si->RestartPos,
238 GD_TotalSize, CalcSongSize (si),
239 GD_InstSize, CalcInstSize (si),
243 DB(millisecs = CalcSongTime (si));
244 DB(xmDisplayMessage (XMDMF_DEBUG, "Song Time: %02ld:%02ld", millisecs / 60000, (millisecs / 1000) % 60));
246 ReleaseSemaphore (&si->Lock);
255 /********************/
256 /* SongInfo Gadgets */
257 /********************/
260 static void SongListClicked (struct WinUserData *wud)
263 struct SongInfo *tmp;
265 ObtainSemaphoreShared (&XModuleBase->xm_BaseLock);
267 tmp = (struct SongInfo *)XModuleBase->xm_Songs.mlh_Head;
269 for (i = IntuiMsg.Code; (i > 0) && tmp ; i--)
270 tmp = (struct SongInfo *)tmp->Link.ln_Succ;
272 if (tmp) ObtainSemaphoreShared (&tmp->Lock);
273 ReleaseSemaphore (&XModuleBase->xm_BaseLock);
276 xmActivateSong (tmp);
277 ReleaseSemaphore (&tmp->Lock);
283 static void SongNameClicked (struct WinUserData *wud)
287 if (si = xmLockActiveSong(SM_EXCLUSIVE))
289 DetatchSongInfoList();
292 SNGA_Title, GetString (wud->Gadgets[GD_SongName]),
295 ReleaseSemaphore (&si->Lock);
297 UpdateSongInfoList();
303 static void AuthorNameClicked (struct WinUserData *wud)
307 if (si = xmLockActiveSong(SM_EXCLUSIVE))
310 SNGA_Author, GetString (wud->Gadgets[GD_AuthorName]),
313 ReleaseSemaphore (&si->Lock);
319 static void TempoClicked (struct WinUserData *wud)
323 if (si = xmLockActiveSong(SM_EXCLUSIVE))
326 SNGA_GlobalTempo, GetNumber (wud->Gadgets[GD_Tempo]),
328 GT_SetGadgetAttrs (wud->Gadgets[GD_Tempo], wud->Win, NULL,
329 GTIN_Number, si->GlobalTempo,
332 ReleaseSemaphore (&si->Lock);
338 static void RestartClicked (struct WinUserData *wud)
342 if (si = xmLockActiveSong(SM_EXCLUSIVE))
345 SNGA_RestartPos, GetNumber (wud->Gadgets[GD_Restart]),
347 GT_SetGadgetAttrs (wud->Gadgets[GD_Restart], wud->Win, NULL,
348 GTIN_Number, si->RestartPos,
351 ReleaseSemaphore (&si->Lock);
357 static void SpeedClicked (struct WinUserData *wud)
361 if (si = xmLockActiveSong(SM_EXCLUSIVE))
364 SNGA_GlobalSpeed, GetNumber (wud->Gadgets[GD_Speed]),
366 GT_SetGadgetAttrs (wud->Gadgets[GD_Speed], wud->Win, NULL,
367 GTIN_Number, si->GlobalSpeed,
370 ReleaseSemaphore (&si->Lock);
376 static void NewSongClicked (struct WinUserData *wud)
380 if (si = xmCreateSong (
381 SNGA_ReadyToUse, TRUE,
385 ReleaseSemaphore (&si->Lock); /* This is for XMSNG_AddToList */
392 static void OpenSongClicked (struct WinUserData *wud)
394 StartFileRequest (FREQ_LOADMOD, ToolBoxOpenModule);
399 static void DelSongClicked (struct WinUserData *wud)
401 if (ShowRequestArgs (MSG_DISCARD_CURRENT_SONG, MSG_YES_OR_NO, NULL))
405 if (si = xmLockActiveSong (SM_EXCLUSIVE))
408 if (!XModuleBase->xm_CurrentSong)
414 static void SaveSongClicked (struct WinUserData *wud)
420 if (si = xmLockActiveSong (SM_EXCLUSIVE))
422 LastErr = xmSaveModuleA (si, si->Path, NULL, NULL);
423 ReleaseSemaphore (&si->Lock);
435 static void SongInfoMiMergeSongs (void)
437 struct SongInfo *si1, *si2, *si3;
441 ObtainSemaphoreShared (&XModuleBase->xm_BaseLock);
443 if (si1 = XModuleBase->xm_CurrentSong)
445 si2 = (struct SongInfo *)si1->Link.ln_Succ;
447 if (si2->Link.ln_Succ)
449 /* Risking a deadlock?? Hmmm... No!
450 * Shared locks do not prevent other tasks from
451 * locking these two songs.
453 ObtainSemaphoreShared (&si1->Lock);
454 ObtainSemaphoreShared (&si2->Lock);
455 ReleaseSemaphore (&XModuleBase->xm_BaseLock);
457 si3 = MergeSongs (si1, si2);
459 ReleaseSemaphore (&si1->Lock);
460 ReleaseSemaphore (&si2->Lock);
462 if (si3) xmAddSongA (si3, si2, NULL);
466 ReleaseSemaphore (&XModuleBase->xm_BaseLock);
467 xmDisplayMessageA (XMDMF_ERROR | XMDMF_USECATALOG,
468 (APTR)MSG_MERGE_REQUIRES_TWO_SONGS, NULL);
473 ReleaseSemaphore (&XModuleBase->xm_BaseLock);
477 ReleaseSemaphore (&XModuleBase->xm_BaseLock);
483 static void SongInfoMiJoinSongs (void)
485 struct SongInfo *si1, *si2, *si3;
489 ObtainSemaphoreShared (&XModuleBase->xm_BaseLock);
491 if (si1 = XModuleBase->xm_CurrentSong)
493 si2 = (struct SongInfo *)si1->Link.ln_Succ;
495 if (si2->Link.ln_Succ)
497 /* Risking a deadlock?? Hmmm... No!
498 * Shared locks do not prevent other tasks from
499 * locking these two songs.
501 ObtainSemaphoreShared (&si1->Lock);
502 ObtainSemaphoreShared (&si2->Lock);
503 ReleaseSemaphore (&XModuleBase->xm_BaseLock);
505 si3 = JoinSongs (si1, si2);
507 ReleaseSemaphore (&si1->Lock);
508 ReleaseSemaphore (&si2->Lock);
510 xmAddSongA (si3, si2, NULL);
514 ReleaseSemaphore (&XModuleBase->xm_BaseLock);
515 xmDisplayMessageA (XMDMF_ERROR | XMDMF_USECATALOG,
516 (APTR)MSG_JOIN_REQUIRES_TWO_SONGS, NULL);
521 ReleaseSemaphore (&XModuleBase->xm_BaseLock);
530 static void SongInfoMiClearSong (void)
532 NewWindow (WID_CLEAR);