2 AHI - Hardware independent audio subsystem
3 Copyright (C) 2017 The AROS Dev Team
4 Copyright (C) 1996-2005 Martin Blom <martin@blom.org>
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
16 You should have received a copy of the GNU Library General Public
17 License along with this library; if not, write to the
18 Free Software Foundation, Inc., 59 Temple Place - Suite 330, Cambridge,
24 // Fix broken includes
27 #include <exec/memory.h>
28 #include <graphics/rpattr.h>
29 #include <intuition/gadgetclass.h>
30 #include <intuition/intuition.h>
31 #include <intuition/intuitionbase.h>
32 #include <libraries/gadtools.h>
33 #include <libraries/asl.h>
35 #include <clib/alib_protos.h>
36 #include <proto/exec.h>
37 #include <proto/dos.h>
38 #include <proto/gadtools.h>
39 #include <proto/graphics.h>
40 #include <proto/intuition.h>
41 #include <proto/utility.h>
43 #define __NOGLOBALIFACE__
44 #include <proto/ahi.h>
46 #undef __NOGLOBALIFACE__
47 #include <proto/ahi_sub.h>
60 #define min(a,b) (((a)<(b))?(a):(b))
61 #define max(a,b) (((a)>(b))?(a):(b))
63 struct AHIAudioModeRequesterExt
;
65 static void OpenInfoWindow( struct AHIAudioModeRequesterExt
* );
66 static void CloseInfoWindow( struct AHIAudioModeRequesterExt
* );
67 static void UpdateInfoWindow( struct AHIAudioModeRequesterExt
* );
70 /******************************************************************************
71 ** Audio mode requester ******************************************************
72 ******************************************************************************/
74 #define MY_IDCMPS (LISTVIEWIDCMP|SLIDERIDCMP|BUTTONIDCMP|IDCMP_SIZEVERIFY|IDCMP_NEWSIZE|IDCMP_REFRESHWINDOW|IDCMP_CLOSEWINDOW|IDCMP_MENUPICK|IDCMP_VANILLAKEY|IDCMP_RAWKEY)
75 #define MY_INFOIDCMPS (LISTVIEWIDCMP|IDCMP_REFRESHWINDOW|IDCMP_CLOSEWINDOW)
77 #define haveIDCMP 0x0001
78 #define lockwin 0x0002
79 #define freqgad 0x0004
80 #define ownIDCMP 0x0008
81 #define defaultmode 0x0010
83 static const struct TagItem reqboolmap
[] =
85 { AHIR_PrivateIDCMP
, haveIDCMP
},
86 { AHIR_SleepWindow
, lockwin
},
87 { AHIR_DoMixFreq
, freqgad
},
88 { AHIR_DoDefaultMode
, defaultmode
},
92 #define LASTMODEITEM 1
93 #define NEXTMODEITEM 2
94 #define PROPERTYITEM 3
99 /* Node for audio mode requester */
108 /* The attribues list */
118 /* AHIAudioModeRequester extension */
119 struct AHIAudioModeRequesterExt
121 struct AHIAudioModeRequester Req
;
124 struct Window
*SrcWindow
;
125 STRPTR PubScreenName
;
126 struct Screen
*Screen
;
128 struct Hook
*IntuiMsgFunc
;
129 struct TextAttr
*TextAttr
;
130 struct Locale
*Locale
;
134 struct TagItem
*FilterTags
;
135 struct Hook
*FilterFunc
;
137 // struct Screen *PubScreen;
138 struct Window
*Window
;
139 struct Window
*InfoWindow
;
142 struct Gadget
*Gadgets
;
143 struct Gadget
*InfoGadgets
;
144 struct Gadget
*InfoListViewGadget
;
145 struct Gadget
*listviewgadget
;
146 struct Gadget
*slidergadget
;
147 struct MinList
*list
;
148 struct MinList InfoList
;
150 struct Catalog
*Catalog
;
151 struct Attrnode AttrNodes
[ATTRNODES
];
155 static const struct TextAttr Topaz80
= { "topaz.font", 8, 0, 0, };
157 #define MINSLIDERWIDTH 40
160 #define CANCELBUTTON 2
164 #define FREQTEXT2 GetString(msgFreqFmt, req->Catalog) //"%lu Hz"
165 #define FREQLEN2 (5+3) // 5 digits + space + "Hz"
167 LONG
IndexToFrequency( struct Gadget
*gad
, WORD level
)
172 id
= ((struct AHIAudioModeRequesterExt
*)gad
->UserData
)->tempAudioID
;
174 if(id
!= AHI_DEFAULT_ID
)
176 AHI_GetAudioAttrs( id
, NULL
,
177 AHIDB_FrequencyArg
, level
,
178 AHIDB_Frequency
, (IPTR
)&freq
,
183 freq
= AHIBase
->ahib_Frequency
;
189 static void FillReqStruct(struct AHIAudioModeRequesterExt
*req
, struct TagItem
*tags
)
191 IPTR obsolete_userdata
;
193 // Check all known tags
194 req
->SrcWindow
=(struct Window
*)GetTagData(AHIR_Window
,(IPTR
)req
->SrcWindow
,tags
);
195 req
->PubScreenName
=(STRPTR
)GetTagData(AHIR_PubScreenName
,(IPTR
)req
->PubScreenName
,tags
);
196 req
->Screen
=(struct Screen
*)GetTagData(AHIR_Screen
,(IPTR
)req
->Screen
,tags
);
197 req
->IntuiMsgFunc
=(struct Hook
*)GetTagData(AHIR_IntuiMsgFunc
,(IPTR
)req
->IntuiMsgFunc
,tags
);
199 obsolete_userdata
= GetTagData( AHIR_ObsoleteUserData
, 0, tags
);
200 req
->Req
.ahiam_ObsoleteUserData
[ 0 ] = obsolete_userdata
>> 16;
201 req
->Req
.ahiam_ObsoleteUserData
[ 1 ] = obsolete_userdata
& 0xffff;
203 req
->Req
.ahiam_UserData
=(void *)GetTagData(AHIR_UserData
,(IPTR
)req
->Req
.ahiam_UserData
,tags
);
204 req
->TextAttr
=(struct TextAttr
*)GetTagData(AHIR_TextAttr
,(IPTR
)req
->TextAttr
,tags
);
205 req
->Locale
=(struct Locale
*)GetTagData(AHIR_Locale
,(IPTR
)req
->Locale
,tags
);
206 req
->TitleText
=(STRPTR
)GetTagData(AHIR_TitleText
,(IPTR
)req
->TitleText
,tags
);
207 req
->PositiveText
=(STRPTR
)GetTagData(AHIR_PositiveText
,(IPTR
)req
->PositiveText
,tags
);
208 req
->NegativeText
=(STRPTR
)GetTagData(AHIR_NegativeText
,(IPTR
)req
->NegativeText
,tags
);
209 req
->Req
.ahiam_LeftEdge
=GetTagData(AHIR_InitialLeftEdge
,req
->Req
.ahiam_LeftEdge
,tags
);
210 req
->Req
.ahiam_TopEdge
=GetTagData(AHIR_InitialTopEdge
,req
->Req
.ahiam_TopEdge
,tags
);
211 req
->Req
.ahiam_Width
=GetTagData(AHIR_InitialWidth
,req
->Req
.ahiam_Width
,tags
);
212 req
->Req
.ahiam_Height
=GetTagData(AHIR_InitialHeight
,req
->Req
.ahiam_Height
,tags
);
213 req
->Req
.ahiam_AudioID
=GetTagData(AHIR_InitialAudioID
,req
->Req
.ahiam_AudioID
,tags
);
214 req
->Req
.ahiam_MixFreq
=GetTagData(AHIR_InitialMixFreq
,req
->Req
.ahiam_MixFreq
,tags
);
215 req
->Req
.ahiam_InfoOpened
=GetTagData(AHIR_InitialInfoOpened
,req
->Req
.ahiam_InfoOpened
,tags
);
216 req
->Req
.ahiam_InfoLeftEdge
=GetTagData(AHIR_InitialInfoLeftEdge
,req
->Req
.ahiam_InfoLeftEdge
,tags
);
217 req
->Req
.ahiam_InfoTopEdge
=GetTagData(AHIR_InitialInfoTopEdge
,req
->Req
.ahiam_InfoTopEdge
,tags
);
218 // req->Req.ahiam_InfoWidth=GetTagData(AHIR_InitialInfoWidth,req->Req.ahiam_InfoWidth,tags);
219 // req->Req.ahiam_InfoHeight=GetTagData(AHIR_InitialInfoHeight,req->Req.ahiam_InfoHeight,tags);
220 req
->FilterTags
=(struct TagItem
*)GetTagData(AHIR_FilterTags
,(IPTR
)req
->FilterTags
,tags
);
221 req
->FilterFunc
=(struct Hook
*)GetTagData(AHIR_FilterFunc
,(IPTR
)req
->FilterFunc
,tags
);
222 req
->Flags
=PackBoolTags(req
->Flags
,tags
,(struct TagItem
*)reqboolmap
);
227 CalculateWindowSizePos( struct AHIAudioModeRequesterExt
* req
,
228 struct Screen
* screen
)
230 struct AslSemaphore
* asl_semaphore
= NULL
;
232 // Default position and size
238 #ifdef ASL_SEMAPHORE_NAME /* Don't break if no v45 includes found */
240 asl_semaphore
= (struct AslSemaphore
*) FindSemaphore( ASL_SEMAPHORE_NAME
);
242 if( asl_semaphore
!= NULL
)
244 ObtainSemaphore( (struct SignalSemaphore
*) asl_semaphore
);
248 if( asl_semaphore
!= NULL
)
250 if( asl_semaphore
->as_Version
>= 45 &&
251 asl_semaphore
->as_Size
> offsetof( struct AslSemaphore
,
252 as_RelativeHeight
) )
254 if( asl_semaphore
->as_SizePosition
& ASLOPTION_ASLOverrides
)
256 // Force default settings
257 req
->Req
.ahiam_LeftEdge
= -1;
258 req
->Req
.ahiam_TopEdge
= -1;
259 req
->Req
.ahiam_Width
= -1;
260 req
->Req
.ahiam_Height
= -1;
263 if( ( asl_semaphore
->as_SizePosition
& ASLSIZE_MASK
) ==
264 ASLSIZE_RelativeSize
)
266 // FIXME: Is it correct to use screen size only? The include file
267 // says something about parent window??
269 width
= (WORD
) ( (LONG
) screen
->Width
*
270 asl_semaphore
->as_RelativeWidth
/ 100 );
271 height
= (WORD
) ( (LONG
) screen
->Height
*
272 asl_semaphore
->as_RelativeHeight
/ 100 );
278 ReleaseSemaphore( (struct SignalSemaphore
*) asl_semaphore
);
279 asl_semaphore
= NULL
;
284 // Set default main window size
285 if( req
->Req
.ahiam_Width
== -1 )
286 req
->Req
.ahiam_Width
= width
;
288 if( req
->Req
.ahiam_Height
== -1 )
289 req
->Req
.ahiam_Height
= height
;
292 #ifdef ASL_SEMAPHORE_NAME /* Don't break if no v45 includes found */
293 if( asl_semaphore
!= NULL
)
295 switch( asl_semaphore
->as_SizePosition
& ASLPOS_MASK
)
297 case ASLPOS_CenterWindow
:
298 if( req
->SrcWindow
!= NULL
)
300 top
= ( req
->SrcWindow
->TopEdge
+
301 req
->SrcWindow
->Height
/ 2 -
302 req
->Req
.ahiam_Height
/ 2 );
303 left
= ( req
->SrcWindow
->LeftEdge
+
304 req
->SrcWindow
->Width
/ 2 -
305 req
->Req
.ahiam_Width
/ 2 );
310 // Fall through and use ASLPOS_CenterScreen instead
313 case ASLPOS_CenterScreen
:
314 top
= ( screen
->Height
/ 2 -
315 req
->Req
.ahiam_Height
/ 2 );
316 left
= ( screen
->Width
/ 2 -
317 req
->Req
.ahiam_Width
/ 2 );
320 case ASLPOS_WindowPosition
:
321 if( req
->SrcWindow
!= NULL
)
323 top
= ( req
->SrcWindow
->TopEdge
+
324 asl_semaphore
->as_RelativeTop
);
325 left
= ( req
->SrcWindow
->LeftEdge
+
326 asl_semaphore
->as_RelativeLeft
);
331 // Fall through and use ASLPOS_ScreenPosition instead
334 case ASLPOS_ScreenPosition
:
335 top
= asl_semaphore
->as_RelativeTop
;
336 left
= asl_semaphore
->as_RelativeLeft
;
339 case ASLPOS_CenterMouse
:
340 top
= ( screen
->MouseY
-
341 req
->Req
.ahiam_Height
/ 2 );
342 left
= ( screen
->MouseX
-
343 req
->Req
.ahiam_Width
/ 2 );
346 case ASLPOS_DefaultPosition
:
348 // Do nothing (use hardcoded defaults)
354 // Set default main window position
355 if( req
->Req
.ahiam_LeftEdge
== -1 )
356 req
->Req
.ahiam_LeftEdge
= left
;
358 if( req
->Req
.ahiam_TopEdge
== -1 )
359 req
->Req
.ahiam_TopEdge
= top
;
362 // Set default info window position (size is fixed)
363 if( req
->Req
.ahiam_InfoLeftEdge
== -1 )
364 req
->Req
.ahiam_InfoLeftEdge
= req
->Req
.ahiam_LeftEdge
+ 16;
366 if( req
->Req
.ahiam_InfoTopEdge
== -1 )
367 req
->Req
.ahiam_InfoTopEdge
= req
->Req
.ahiam_TopEdge
+ 25;
371 if( asl_semaphore
!= NULL
)
373 ReleaseSemaphore( (struct SignalSemaphore
*) asl_semaphore
);
378 ** Returns the ordinal number of the current audio id.
381 static LONG
GetSelected(struct AHIAudioModeRequesterExt
*req
)
383 struct IDnode
*idnode
;
386 for(idnode
=(struct IDnode
*)req
->list
->mlh_Head
;
387 idnode
->node
.ln_Succ
;
388 idnode
=(struct IDnode
*) idnode
->node
.ln_Succ
)
390 if(idnode
->ID
== req
->tempAudioID
)
395 if(idnode
->node
.ln_Succ
== NULL
)
398 req
->tempAudioID
=AHI_INVALID_ID
; // Crashed if this is not done! FIXIT!
404 ** Calculates what the current slider level shoud be and how many levels total
407 static void GetSliderAttrs(struct AHIAudioModeRequesterExt
*req
, LONG
*levels
, LONG
*level
)
412 AHI_GetAudioAttrs(req
->tempAudioID
, NULL
,
413 AHIDB_Frequencies
, (IPTR
)levels
,
414 AHIDB_IndexArg
, (req
->tempAudioID
== AHI_DEFAULT_ID
?
415 AHIBase
->ahib_Frequency
: req
->tempFrequency
),
416 AHIDB_Index
, (IPTR
)level
,
419 if(*level
>= *levels
)
422 AHI_GetAudioAttrs(req
->tempAudioID
, NULL
,
423 AHIDB_FrequencyArg
, *level
,
424 AHIDB_Frequency
, (IPTR
)&req
->tempFrequency
,
429 ** Updates the requester to the current frequency and if 'all'==TRUE, audio mode.
432 static void SetSelected(struct AHIAudioModeRequesterExt
*req
, BOOL all
)
434 LONG sliderlevels
,sliderlevel
,selected
;
435 BOOL disabled
= FALSE
;
436 ULONG top
= GTLV_Top
;
437 ULONG makevisible
= GTLV_MakeVisible
;
442 selected
=GetSelected(req
);
444 if( selected
== ~0 || GadToolsBase
->lib_Version
>= 39 )
451 makevisible
= TAG_IGNORE
;
454 GT_SetGadgetAttrs(req
->listviewgadget
, req
->Window
, NULL
,
456 makevisible
, selected
,
457 GTLV_Selected
, selected
,
462 GetSliderAttrs(req
,&sliderlevels
,&sliderlevel
);
464 if( sliderlevels
== 0 || req
->tempAudioID
== AHI_DEFAULT_ID
)
469 GT_SetGadgetAttrs(req
->slidergadget
, req
->Window
, NULL
,
470 GTSL_Max
, sliderlevels
-1,
471 GTSL_Level
, sliderlevel
,
472 GA_Disabled
, disabled
,
475 UpdateInfoWindow(req
);
480 ** Positions all gadgets in the requester.
483 static BOOL
LayOutReq (struct AHIAudioModeRequesterExt
*req
, const struct TextAttr
*TextAttr
)
488 struct TextAttr
*gadtextattr
;
489 struct TextFont
*font
;
490 LONG fontwidth
,buttonheight
,buttonwidth
,pixels
;
491 struct IntuiText intuitext
= {1,0,JAM1
,0,0,NULL
,NULL
,NULL
};
492 LONG sliderlevels
,sliderlevel
;
495 selected
=GetSelected(req
);
496 GetSliderAttrs(req
,&sliderlevels
,&sliderlevel
);
498 // Calculate gadget area
499 req
->gx
=req
->Window
->BorderLeft
+4;
500 req
->gy
=req
->Window
->BorderTop
+2;
501 req
->gw
=req
->Window
->Width
-req
->gx
-(req
->Window
->BorderRight
+4);
502 req
->gh
=req
->Window
->Height
-req
->gy
-(req
->Window
->BorderBottom
+2);
506 RemoveGList(req
->Window
,req
->Gadgets
,-1);
507 FreeGadgets(req
->Gadgets
);
508 SetAPen(req
->Window
->RPort
,0);
509 SetDrMd(req
->Window
->RPort
,JAM1
);
510 EraseRect(req
->Window
->RPort
, req
->Window
->BorderLeft
, req
->Window
->BorderTop
,
511 req
->Window
->Width
-req
->Window
->BorderRight
-1,req
->Window
->Height
-req
->Window
->BorderBottom
-1);
512 RefreshWindowFrame(req
->Window
);
515 if((gad
=CreateContext(&req
->Gadgets
)))
518 gadtextattr
=(struct TextAttr
*)TextAttr
;
520 gadtextattr
=req
->Window
->WScreen
->Font
;
522 if((font
=OpenFont(gadtextattr
)))
524 fontwidth
=font
->tf_XSize
;
530 buttonheight
=gadtextattr
->ta_YSize
+6;
531 intuitext
.ITextFont
=gadtextattr
;
532 intuitext
.IText
=req
->PositiveText
;
533 buttonwidth
=IntuiTextLength(&intuitext
);
534 intuitext
.IText
=req
->NegativeText
;
535 pixels
=IntuiTextLength(&intuitext
);
536 buttonwidth
=max(pixels
,buttonwidth
);
537 buttonwidth
+=4+fontwidth
;
539 // Create gadgets and check if they fit
540 // Do the two buttons fit?
541 if(2*buttonwidth
> req
->gw
)
543 ng
.ng_TextAttr
=gadtextattr
;
544 ng
.ng_VisualInfo
=req
->vi
;
547 ng
.ng_LeftEdge
=req
->gx
;
548 ng
.ng_TopEdge
=req
->gy
+req
->gh
-buttonheight
;
549 ng
.ng_Width
=buttonwidth
;
550 ng
.ng_Height
=buttonheight
;
551 ng
.ng_GadgetText
=req
->PositiveText
;
552 ng
.ng_GadgetID
=OKBUTTON
;
553 ng
.ng_Flags
=PLACETEXT_IN
;
554 gad
=CreateGadget(BUTTON_KIND
,gad
,&ng
,TAG_END
);
556 ng
.ng_LeftEdge
=req
->gx
+req
->gw
-ng
.ng_Width
;
557 ng
.ng_GadgetText
=req
->NegativeText
;
558 ng
.ng_GadgetID
=CANCELBUTTON
;
559 gad
=CreateGadget(BUTTON_KIND
,gad
,&ng
,TAG_END
);
561 if(req
->Flags
& freqgad
)
563 intuitext
.IText
= GetString(msgReqFrequency
, req
->Catalog
);
564 pixels
=IntuiTextLength(&intuitext
)+INTERWIDTH
;
565 if(pixels
+MINSLIDERWIDTH
+INTERWIDTH
+FREQLEN2
*fontwidth
> req
->gw
)
567 ng
.ng_Width
=req
->gw
-pixels
-INTERWIDTH
-FREQLEN2
*fontwidth
;
568 ng
.ng_LeftEdge
=req
->gx
+pixels
;
569 ng
.ng_TopEdge
-=2+buttonheight
;
570 ng
.ng_GadgetText
= GetString(msgReqFrequency
, req
->Catalog
);
571 ng
.ng_GadgetID
=FREQSLIDER
;
572 ng
.ng_Flags
=PLACETEXT_LEFT
;
573 gad
=CreateGadget(SLIDER_KIND
,gad
,&ng
,
575 GTSL_Max
,sliderlevels
-1,
576 GTSL_Level
,sliderlevel
,
577 GTSL_LevelFormat
, FREQTEXT2
,
578 GTSL_MaxLevelLen
,FREQLEN2
,
579 GTSL_LevelPlace
,PLACETEXT_RIGHT
,
580 GTSL_DispFunc
, m68k_IndexToFrequency
,
582 GA_Disabled
,!sliderlevels
|| (req
->tempAudioID
== AHI_DEFAULT_ID
),
584 req
->slidergadget
=gad
; // Save for HadleReq()...
587 if((ng
.ng_Height
=ng
.ng_TopEdge
-2-req
->gy
) < buttonheight
)
589 ng
.ng_LeftEdge
=req
->gx
;
590 ng
.ng_TopEdge
=req
->gy
;
592 ng
.ng_GadgetText
=NULL
,
593 ng
.ng_GadgetID
=LISTVIEW
;
594 ng
.ng_Flags
=PLACETEXT_ABOVE
;
595 gad
=CreateGadget(LISTVIEW_KIND
,gad
,&ng
,
596 GTLV_ScrollWidth
,(fontwidth
>8 ? fontwidth
*2 : 18),
597 GTLV_Labels
, req
->list
,
599 ((selected
== ~0) || (GadToolsBase
->lib_Version
>= 39) ? TAG_IGNORE
: GTLV_Top
),selected
,
600 (selected
== ~0 ? TAG_IGNORE
: GTLV_MakeVisible
),selected
,
601 GTLV_Selected
,selected
,
603 req
->listviewgadget
=gad
; // Save for HadleReq()...
611 AddGList(req
->Window
,req
->Gadgets
,~0,-1,NULL
);
612 RefreshGList(req
->Gadgets
,req
->Window
,NULL
,-1);
613 GT_RefreshWindow(req
->Window
,NULL
);
620 /* these functions close an Intuition window
621 * that shares a port with other Intuition
622 * windows or IPC customers.
624 * We are careful to set the UserPort to
625 * null before closing, and to free
626 * any messages that it might have been
630 /* remove and reply all IntuiMessages on a port that
631 * have been sent to a particular window
632 * (note that we don't rely on the ln_Succ pointer
633 * of a message after we have replied it)
635 static void StripIntuiMessagesAHI( struct MsgPort
*mp
, struct Window
*win
)
637 struct IntuiMessage
*msg
;
640 msg
= (struct IntuiMessage
*) mp
->mp_MsgList
.lh_Head
;
642 while((succ
= msg
->ExecMessage
.mn_Node
.ln_Succ
)) {
644 if( msg
->IDCMPWindow
== win
) {
646 /* Intuition is about to free this message.
647 * Make sure that we have politely sent it back.
649 Remove( (struct Node
*) msg
);
651 ReplyMsg( (struct Message
*) msg
);
654 msg
= (struct IntuiMessage
*) succ
;
658 static void CloseWindowSafely( struct Window
*win
)
660 /* we forbid here to keep out of race conditions with Intuition */
663 /* send back any messages for this window
664 * that have not yet been processed
666 StripIntuiMessagesAHI( win
->UserPort
, win
);
668 /* clear UserPort so Intuition will not free it */
669 win
->UserPort
= NULL
;
671 /* tell Intuition to stop sending more messages */
672 ModifyIDCMP( win
, 0L );
674 /* turn multitasking back on */
677 /* and really close the window */
681 static BOOL
HandleReq( struct AHIAudioModeRequesterExt
*req
)
683 // Returns FALSE if requester was cancelled
686 BOOL done
=FALSE
,rc
=TRUE
;
687 ULONG
class,sec
,oldsec
=0,micro
,oldmicro
=0;
688 IPTR oldid
=AHI_INVALID_ID
;
691 struct Gadget
*pgsel
;
692 struct IntuiMessage
*imsg
;
693 struct IDnode
*idnode
;
694 LONG sliderlevels
,sliderlevel
,i
,selected
;
695 struct MenuItem
*item
;
699 Wait(1L << req
->Window
->UserPort
->mp_SigBit
);
701 while ((imsg
=GT_GetIMsg(req
->Window
->UserPort
)) != NULL
)
704 if(imsg
->IDCMPWindow
== req
->InfoWindow
)
711 case IDCMP_CLOSEWINDOW
:
712 CloseInfoWindow(req
);
714 case IDCMP_REFRESHWINDOW
:
715 GT_BeginRefresh(req
->InfoWindow
);
716 GT_EndRefresh(req
->InfoWindow
,TRUE
);
719 continue; // Get next IntuiMessage
722 else if(imsg
->IDCMPWindow
!= req
->Window
) // Not my window!
724 if(req
->IntuiMsgFunc
)
725 CallHookPkt(req
->IntuiMsgFunc
,req
,imsg
);
726 // else what to do??? Reply and forget? FIXIT!
732 qual
=imsg
->Qualifier
;
735 pgsel
=(struct Gadget
*)imsg
->IAddress
; // pgsel illegal if not gadget
743 case 0x4c: // Cursor Up
744 selected
=GetSelected(req
);
749 idnode
=(struct IDnode
*)req
->list
->mlh_Head
;
750 for(i
=0;i
<selected
;i
++)
751 idnode
=(struct IDnode
*)idnode
->node
.ln_Succ
;
752 req
->tempAudioID
=idnode
->ID
;
753 SetSelected(req
,TRUE
);
755 case 0x4d: // Cursor Down
756 selected
=GetSelected(req
);
757 selected
++; // ~0 => 0
758 idnode
=(struct IDnode
*)req
->list
->mlh_Head
;
759 for(i
=0;i
<selected
;i
++)
760 if(idnode
->node
.ln_Succ
->ln_Succ
)
761 idnode
=(struct IDnode
*)idnode
->node
.ln_Succ
;
762 req
->tempAudioID
=idnode
->ID
;
763 SetSelected(req
,TRUE
);
765 case 0x4e: // Cursor Right
766 GetSliderAttrs(req
,&sliderlevels
,&sliderlevel
);
767 sliderlevel
+= (qual
& (IEQUALIFIER_LSHIFT
|IEQUALIFIER_RSHIFT
) ? 10 :1);
768 if(sliderlevel
>= sliderlevels
)
769 sliderlevel
=sliderlevels
-1;
770 AHI_GetAudioAttrs(req
->tempAudioID
, NULL
,
771 AHIDB_FrequencyArg
,sliderlevel
,
772 AHIDB_Frequency
, (IPTR
)&req
->tempFrequency
,
774 SetSelected(req
,FALSE
);
776 case 0x4f: // Cursor Left
777 GetSliderAttrs(req
,&sliderlevels
,&sliderlevel
);
778 sliderlevel
-= (qual
& (IEQUALIFIER_LSHIFT
|IEQUALIFIER_RSHIFT
) ? 10 :1);
781 AHI_GetAudioAttrs(req
->tempAudioID
, NULL
,
782 AHIDB_FrequencyArg
,sliderlevel
,
783 AHIDB_Frequency
, (IPTR
)&req
->tempFrequency
,
785 SetSelected(req
,FALSE
);
789 case IDCMP_GADGETUP
:
790 switch ( pgsel
->GadgetID
)
800 AHI_GetAudioAttrs(req
->tempAudioID
, NULL
,
801 AHIDB_FrequencyArg
,code
,
802 AHIDB_Frequency
, (IPTR
)&req
->tempFrequency
,
806 idnode
=(struct IDnode
*)req
->list
->mlh_Head
;
808 idnode
=(struct IDnode
*)idnode
->node
.ln_Succ
;
809 req
->tempAudioID
=idnode
->ID
;
810 SetSelected(req
,FALSE
);
811 // Test doubleclick and save timestamp
812 if( (oldid
== req
->tempAudioID
) && DoubleClick(oldsec
,oldmicro
,sec
,micro
))
816 oldid
=req
->tempAudioID
;
823 if(!(LayOutReq(req
,req
->TextAttr
)))
824 if(!(LayOutReq(req
,&Topaz80
)))
831 case IDCMP_CLOSEWINDOW
:
835 case IDCMP_REFRESHWINDOW
:
836 GT_BeginRefresh(req
->Window
);
837 GT_EndRefresh(req
->Window
,TRUE
);
839 case IDCMP_SIZEVERIFY
:
842 while((code
!= MENUNULL
) && !done
)
844 item
=ItemAddress(req
->Menu
, code
);
845 switch((IPTR
)GTMENUITEM_USERDATA(item
))
848 selected
=GetSelected(req
);
853 idnode
=(struct IDnode
*)req
->list
->mlh_Head
;
854 for(i
=0;i
<selected
;i
++)
855 idnode
=(struct IDnode
*)idnode
->node
.ln_Succ
;
856 req
->tempAudioID
=idnode
->ID
;
857 SetSelected(req
,TRUE
);
860 selected
=GetSelected(req
);
861 selected
++; // ~0 => 0
862 idnode
=(struct IDnode
*)req
->list
->mlh_Head
;
863 for(i
=0;i
<selected
;i
++)
864 if(idnode
->node
.ln_Succ
->ln_Succ
)
865 idnode
=(struct IDnode
*)idnode
->node
.ln_Succ
;
866 req
->tempAudioID
=idnode
->ID
;
867 SetSelected(req
,TRUE
);
873 req
->tempAudioID
=req
->Req
.ahiam_AudioID
;
874 req
->tempFrequency
=req
->Req
.ahiam_MixFreq
;
875 SetSelected(req
,TRUE
);
885 code
= item
->NextSelect
;
894 req
->Req
.ahiam_AudioID
= req
->tempAudioID
;
896 if(req
->tempAudioID
!= AHI_DEFAULT_ID
)
898 req
->Req
.ahiam_MixFreq
= req
->tempFrequency
;
902 req
->Req
.ahiam_MixFreq
= AHI_DEFAULT_FREQ
;
909 static void OpenInfoWindow( struct AHIAudioModeRequesterExt
*req
)
915 if(req
->InfoWindow
== NULL
)
917 req
->InfoWindow
=OpenWindowTags(NULL
,
918 WA_Left
, req
->Req
.ahiam_InfoLeftEdge
,
919 WA_Top
, req
->Req
.ahiam_InfoTopEdge
,
920 WA_Width
, req
->Req
.ahiam_InfoWidth
,
921 WA_Height
, req
->Req
.ahiam_InfoHeight
,
922 WA_Title
, GetString(msgReqInfoTitle
, req
->Catalog
),
923 WA_CustomScreen
, req
->Window
->WScreen
,
924 WA_PubScreenFallBack
, TRUE
,
926 WA_DepthGadget
, TRUE
,
927 WA_CloseGadget
, TRUE
,
929 WA_SimpleRefresh
, TRUE
,
932 WA_NewLookMenus
, TRUE
,
937 req
->InfoWindow
->UserPort
= req
->Window
->UserPort
;
938 ModifyIDCMP(req
->InfoWindow
, MY_INFOIDCMPS
);
940 if((gad
= CreateContext(&req
->InfoGadgets
)))
942 ng
.ng_TextAttr
= req
->TextAttr
;
943 ng
.ng_VisualInfo
= req
->vi
;
944 ng
.ng_LeftEdge
= req
->InfoWindow
->BorderLeft
+4;
945 ng
.ng_TopEdge
= req
->InfoWindow
->BorderTop
+2;
946 ng
.ng_Width
= req
->InfoWindow
->Width
947 - (req
->InfoWindow
->BorderLeft
+4)
948 - (req
->InfoWindow
->BorderRight
+4);
949 ng
.ng_Height
= req
->InfoWindow
->Height
950 - (req
->InfoWindow
->BorderTop
+2)
951 - (req
->InfoWindow
->BorderBottom
+2);
953 ng
.ng_GadgetText
= NULL
;
955 ng
.ng_Flags
= PLACETEXT_ABOVE
;
956 gad
= CreateGadget(LISTVIEW_KIND
, gad
, &ng
,
959 req
->InfoListViewGadget
= gad
;
963 AddGList(req
->InfoWindow
, req
->InfoGadgets
, ~0, -1, NULL
);
964 RefreshGList(req
->InfoGadgets
, req
->InfoWindow
, NULL
, -1);
965 GT_RefreshWindow(req
->InfoWindow
, NULL
);
966 UpdateInfoWindow(req
);
974 static void UpdateInfoWindow( struct AHIAudioModeRequesterExt
*req
)
976 LONG id
=0, bits
=0, stereo
=0, pan
=0, hifi
=0, channels
=0, minmix
=0, maxmix
=0,
977 record
=0, fullduplex
=0, multichannel
=0;
980 id
= req
->tempAudioID
;
981 if(id
== AHI_DEFAULT_ID
)
983 id
= AHIBase
->ahib_AudioMode
;
987 AHI_GetAudioAttrs(id
, NULL
,
988 AHIDB_MultiChannel
, (IPTR
)&multichannel
,
989 AHIDB_Stereo
, (IPTR
)&stereo
,
990 AHIDB_Panning
, (IPTR
)&pan
,
991 AHIDB_HiFi
, (IPTR
)&hifi
,
992 AHIDB_Record
, (IPTR
)&record
,
993 AHIDB_FullDuplex
, (IPTR
)&fullduplex
,
994 AHIDB_Bits
, (IPTR
)&bits
,
995 AHIDB_MaxChannels
, (IPTR
)&channels
,
996 AHIDB_MinMixFreq
, (IPTR
)&minmix
,
997 AHIDB_MaxMixFreq
, (IPTR
)&maxmix
,
1000 GT_SetGadgetAttrs(req
->InfoListViewGadget
, req
->InfoWindow
, NULL
,
1004 NewList((struct List
*) &req
->InfoList
);
1005 for(i
=0; i
<ATTRNODES
; i
++)
1007 req
->AttrNodes
[i
].node
.ln_Name
= req
->AttrNodes
[i
].text
;
1008 req
->AttrNodes
[i
].text
[0] = '\0';
1009 req
->AttrNodes
[i
].node
.ln_Type
= NT_USER
;
1010 req
->AttrNodes
[i
].node
.ln_Pri
= 0;
1014 AddTail((struct List
*) &req
->InfoList
,(struct Node
*) &req
->AttrNodes
[i
]);
1015 Sprintf(req
->AttrNodes
[i
++].text
, GetString(msgReqInfoAudioID
, req
->Catalog
),
1017 AddTail((struct List
*) &req
->InfoList
,(struct Node
*) &req
->AttrNodes
[i
]);
1018 Sprintf(req
->AttrNodes
[i
++].text
, GetString(msgReqInfoResolution
, req
->Catalog
),
1019 bits
, (IPTR
)GetString((multichannel
? msgReqInfoMultiChannel
: (stereo
?
1020 (pan
? msgReqInfoStereoPan
: msgReqInfoStereo
) :
1021 msgReqInfoMono
)), req
->Catalog
));
1022 AddTail((struct List
*) &req
->InfoList
,(struct Node
*) &req
->AttrNodes
[i
]);
1023 Sprintf(req
->AttrNodes
[i
++].text
, GetString(msgReqInfoChannels
, req
->Catalog
),
1025 AddTail((struct List
*) &req
->InfoList
,(struct Node
*) &req
->AttrNodes
[i
]);
1026 Sprintf(req
->AttrNodes
[i
++].text
, GetString(msgReqInfoMixrate
, req
->Catalog
),
1030 AddTail((struct List
*) &req
->InfoList
,(struct Node
*) &req
->AttrNodes
[i
]);
1031 Sprintf(req
->AttrNodes
[i
++].text
, GetString(msgReqInfoHiFi
, req
->Catalog
));
1035 AddTail((struct List
*) &req
->InfoList
,(struct Node
*) &req
->AttrNodes
[i
]);
1036 Sprintf(req
->AttrNodes
[i
++].text
, GetString(
1037 fullduplex
? msgReqInfoRecordFull
: msgReqInfoRecordHalf
, req
->Catalog
));
1040 GT_SetGadgetAttrs(req
->InfoListViewGadget
, req
->InfoWindow
, NULL
,
1041 GTLV_Labels
, &req
->InfoList
,
1046 static void CloseInfoWindow( struct AHIAudioModeRequesterExt
*req
)
1050 req
->Req
.ahiam_InfoOpened
= TRUE
;
1051 req
->Req
.ahiam_InfoLeftEdge
= req
->InfoWindow
->LeftEdge
;
1052 req
->Req
.ahiam_InfoTopEdge
= req
->InfoWindow
->TopEdge
;
1053 req
->Req
.ahiam_InfoWidth
= req
->InfoWindow
->Width
;
1054 req
->Req
.ahiam_InfoHeight
= req
->InfoWindow
->Height
;
1055 CloseWindowSafely(req
->InfoWindow
);
1056 req
->InfoWindow
= NULL
;
1061 req
->Req
.ahiam_InfoOpened
= FALSE
;
1065 FreeGadgets(req
->InfoGadgets
);
1066 req
->InfoGadgets
= NULL
;
1070 /******************************************************************************
1071 ** AHI_AllocAudioRequestA *****************************************************
1072 ******************************************************************************/
1074 /****** ahi.device/AHI_AllocAudioRequestA ***********************************
1077 * AHI_AllocAudioRequestA -- allocate an audio mode requester.
1078 * AHI_AllocAudioRequest -- varargs stub for AHI_AllocAudioRequestA()
1081 * requester = AHI_AllocAudioRequestA( tags );
1084 * struct AHIAudioModeRequester *AHI_AllocAudioRequestA(
1085 * struct TagItem * );
1087 * requester = AHI_AllocAudioRequest( tag1, ... );
1089 * struct AHIAudioModeRequester *AHI_AllocAudioRequest( Tag, ... );
1092 * Allocates an audio mode requester data structure.
1095 * tags - A pointer to an optional tag list specifying how to initialize
1096 * the data structure returned by this function. See the
1097 * documentation for AHI_AudioRequestA() for an explanation of how
1098 * to use the currently defined tags.
1101 * requester - An initialized requester data structure, or NULL on
1107 * The requester data structure is READ-ONLY and can only be modified
1113 * AHI_AudioRequestA(), AHI_FreeAudioRequest()
1115 ****************************************************************************
1119 struct AHIAudioModeRequester
*
1120 _AHI_AllocAudioRequestA( struct TagItem
* tags
,
1121 struct AHIBase
* AHIBase
)
1123 struct AHIAudioModeRequesterExt
*req
;
1125 if(AHIBase
->ahib_DebugLevel
>= AHI_DEBUG_LOW
)
1127 Debug_AllocAudioRequestA(tags
);
1130 if((req
=AllocVec(sizeof(struct AHIAudioModeRequesterExt
),MEMF_CLEAR
)))
1133 req
->Req
.ahiam_LeftEdge
= -1;
1134 req
->Req
.ahiam_TopEdge
= -1;
1135 req
->Req
.ahiam_Width
= -1;
1136 req
->Req
.ahiam_Height
= -1;
1138 req
->Req
.ahiam_AudioID
= AHI_INVALID_ID
;
1139 req
->Req
.ahiam_MixFreq
= AHIBase
->ahib_Frequency
;
1141 req
->Req
.ahiam_InfoLeftEdge
= -1;
1142 req
->Req
.ahiam_InfoTopEdge
= -1;
1143 req
->Req
.ahiam_InfoWidth
= 280;
1144 req
->Req
.ahiam_InfoHeight
= 112;
1146 req
->PubScreenName
= (STRPTR
) -1;
1148 FillReqStruct(req
,tags
);
1151 if(AHIBase
->ahib_DebugLevel
>= AHI_DEBUG_LOW
)
1153 KPrintF("=>0x%P\n", (IPTR
)req
);
1156 return (struct AHIAudioModeRequester
*) req
;
1160 /******************************************************************************
1161 ** AHI_AudioRequestA **********************************************************
1162 ******************************************************************************/
1164 /****** ahi.device/AHI_AudioRequestA ****************************************
1167 * AHI_AudioRequestA -- get an audio mode from user using an requester.
1168 * AHI_AudioRequest -- varargs stub for AHI_AudioRequestA()
1171 * success = AHI_AudioRequestA( requester, tags );
1174 * BOOL AHI_AudioRequestA( struct AHIAudioModeRequester *,
1175 * struct TagItem * );
1177 * result = AHI_AudioRequest( requester, tag1, ... );
1179 * BOOL AHI_AudioRequest( struct AHIAudioModeRequester *, Tag, ... );
1182 * Prompts the user for an audio mode, based on the modifying tags.
1183 * If the user cancels or the system aborts the request, FALSE is
1184 * returned, otherwise the requester's data structure reflects the
1187 * Note that tag values stay in effect for each use of the requester
1188 * until they are cleared or modified by passing the same tag with a
1192 * requester - Requester structure allocated with
1193 * AHI_AllocAudioRequestA(). If this parameter is NULL, this
1194 * function will always return FALSE with a dos.library/IoErr()
1195 * result of ERROR_NO_FREE_STORE.
1196 * tags - Pointer to an optional tag list which may be used to control
1197 * features of the requester.
1200 * Tags used for the requester (they look remarkable similar to the
1201 * screen mode requester in ASL, don't they? ;-) )
1203 * AHIR_Window (struct Window *) - Parent window of requester. If no
1204 * AHIR_Screen tag is specified, the window structure is used to
1205 * determine on which screen to open the requesting window.
1207 * AHIR_PubScreenName (STRPTR) - Name of a public screen to open on.
1208 * This overrides the screen used by AHIR_Window.
1210 * AHIR_Screen (struct Screen *) - Screen on which to open the
1211 * requester. This overrides the screen used by AHIR_Window or by
1212 * AHIR_PubScreenName.
1214 * AHIR_PrivateIDCMP (BOOL) - When set to TRUE, this tells AHI to
1215 * allocate a new IDCMP port for the requesting window. If not
1216 * specified or set to FALSE, and if AHIR_Window is provided, the
1217 * requesting window will share AHIR_Window's IDCMP port.
1219 * AHIR_IntuiMsgFunc (struct Hook *) - A function to call whenever an
1220 * unknown Intuition message arrives at the message port being used
1221 * by the requesting window. The function receives the following
1223 * A0 - (struct Hook *)
1224 * A1 - (struct IntuiMessage *)
1225 * A2 - (struct AHIAudioModeRequester *)
1227 * AHIR_SleepWindow (BOOL) - When set to TRUE, this tag will cause the
1228 * window specified by AHIR_Window to be "put to sleep". That is, a
1229 * busy pointer will be displayed in the parent window, and no
1230 * gadget or menu activity will be allowed. This is done by opening
1231 * an invisible Intuition Requester in the parent window.
1233 * AHIR_UserData (APTR) - A 32-bit value that is simply copied in the
1234 * ahiam_UserData field of the requester structure.
1236 * AHIR_TextAttr (struct TextAttr *) - Font to be used for the
1237 * requesting window's gadgets and menus. If this tag is not
1238 * provided or its value is NULL, the default font of the screen
1239 * on which the requesting window opens will be used. This font
1240 * must already be in memory as AHI calls OpenFont() and not
1243 * AHIR_Locale (struct Locale *) - Locale to use for the requesting
1244 * window. This determines the language used for the requester's
1245 * gadgets and menus. If this tag is not provided or its value is
1246 * NULL, the system's current default locale will be used.
1248 * AHIR_TitleText (STRPTR) - Title to use for the requesting window.
1249 * Default is no title.
1251 * AHIR_PositiveText (STRPTR) - Label of the positive gadget in the
1252 * requester. English default is "OK".
1254 * AHIR_NegativeText (STRPTR) - Label of the negative gadget in the
1255 * requester. English default is "Cancel".
1257 * AHIR_InitialLeftEdge (WORD) - Suggested left edge of requesting
1260 * AHIR_InitialTopEdge (WORD) - Suggested top edge of requesting
1263 * AHIR_InitialWidth (WORD) - Suggested width of requesting window.
1265 * AHIR_InitialHeight (WORD) - Suggested height of requesting window.
1267 * AHIR_InitialAudioID (IPTR) - Initial setting of the Mode list view
1268 * gadget (ahiam_AudioID). Default is ~0 (AHI_INVALID_ID), which
1269 * means that no mode will be selected.
1271 * AHIR_InitialMixFreq (ULONG) - Initial setting of the frequency
1272 * slider. Default is the lowest frequency supported.
1274 * AHIR_InitialInfoOpened (BOOL) - Whether to open the property
1275 * information window automatically. Default is FALSE.
1277 * AHIR_InitialInfoLeftEdge (WORD) - Initial left edge of information
1280 * AHIR_InitialInfoTopEdge (WORD) - Initial top edge of information
1283 * AHIR_DoMixFreq (BOOL) - Set this tag to TRUE to cause the requester
1284 * to display the frequency slider gadget. Default is FALSE.
1286 * AHIR_DoDefaultMode (BOOL) - Set this tag to TRUE to let the user
1287 * select the mode she has set in the preferences program. If she
1288 * selects this mode, ahiam_AudioID will be AHI_DEFAULT_ID and
1289 * ahiam_MixFreq will be AHI_DEFAULT_FREQ. Note that if you filter
1290 * the mode list (see below), you must also check the mode (with
1291 * AHI_BestAudioIDA()) before you use it since the user may change
1292 * the meaning of AHI_DEFAULT_MODE anytime, without your knowledge.
1293 * Default is FALSE. (V4)
1295 * AHIR_FilterFunc (struct Hook *) - A function to call for each mode
1296 * encountered. If the function returns TRUE, the mode is included
1297 * in the file list, otherwise it is rejected and not displayed. The
1298 * function receives the following parameters:
1299 * A0 - (struct Hook *)
1300 * A1 - (IPTR) mode id
1301 * A2 - (struct AHIAudioModeRequester *)
1303 * AHIR_FilterTags (struct TagItem *) - A pointer to a tag list used to
1304 * filter modes away, like AHIR_FilterFunc does. The tags are the
1305 * same as AHI_BestAudioIDA() takes as arguments. See that function
1306 * for an explanation of each tag.
1309 * result - FALSE if the user cancelled the requester or if something
1310 * prevented the requester from opening. If TRUE, values in the
1311 * requester structure will be set.
1313 * If the return value is FALSE, you can look at the result from the
1314 * dos.library/IoErr() function to determine whether the requester
1315 * was cancelled or simply failed to open. If dos.library/IoErr()
1316 * returns 0, then the requester was cancelled, any other value
1317 * indicates a failure to open. Current possible failure codes are
1318 * ERROR_NO_FREE_STORE which indicates there was not enough memory,
1319 * and ERROR_NO_MORE_ENTRIES which indicates no modes were available
1320 * (usually because the application filter hook filtered them all
1326 * The requester data structure is READ-ONLY and can only be modified
1329 * The mixing/recording frequencies that are presented to the user
1330 * may not be the only ones a driver supports, but just a selection.
1335 * AHI_AllocAudioRequestA(), AHI_FreeAudioRequest()
1337 ****************************************************************************
1342 _AHI_AudioRequestA( struct AHIAudioModeRequester
* req_in
,
1343 struct TagItem
* tags
,
1344 struct AHIBase
* AHIBase
)
1346 struct AHIAudioModeRequesterExt
*req
=(struct AHIAudioModeRequesterExt
*)req_in
;
1347 struct MinList list
;
1348 struct IDnode
*node
= NULL
, *node2
= NULL
;
1349 struct Screen
*pub_screen
= NULL
;
1350 struct Screen
*screen
= NULL
;
1351 IPTR id
=AHI_INVALID_ID
;
1353 struct Requester lockreq
;
1354 BOOL locksuxs
= FALSE
;
1357 if(AHIBase
->ahib_DebugLevel
>= AHI_DEBUG_LOW
)
1359 Debug_AudioRequestA(req_in
,tags
);
1366 SetIoErr( ERROR_REQUIRED_ARG_MISSING
);
1370 // Update requester structure
1371 FillReqStruct(req
,tags
);
1372 req
->tempAudioID
=req
->Req
.ahiam_AudioID
;
1373 req
->tempFrequency
=req
->Req
.ahiam_MixFreq
;
1377 req
->Catalog
= ExtOpenCatalog(req
->Locale
, NULL
);
1379 if(req
->PositiveText
== NULL
)
1380 req
->PositiveText
= GetString(msgReqOK
, req
->Catalog
);
1381 if(req
->NegativeText
== NULL
)
1382 req
->NegativeText
= GetString(msgReqCancel
, req
->Catalog
);
1385 // Scan audio database for modes and create list
1387 NewList((struct List
*)req
->list
);
1388 while(AHI_INVALID_ID
!= (id
=AHI_NextAudioID(id
)))
1392 if(!TestAudioID(id
,req
->FilterTags
))
1395 if(!CallHookPkt(req
->FilterFunc
,req
,(APTR
)id
))
1398 if((node
=AllocVec(sizeof(struct IDnode
),MEMF_ANY
)))
1400 node
->node
.ln_Type
=NT_USER
;
1401 node
->node
.ln_Pri
=0;
1402 node
->node
.ln_Name
=node
->name
;
1404 #ifndef __AMIGAOS4__
1405 Sprintf(node
->node
.ln_Name
, GetString(msgUnknown
, req
->Catalog
),id
);
1407 AHI_GetAudioAttrs(id
, NULL
,
1409 AHIDB_Name
, (IPTR
)node
->node
.ln_Name
,
1411 // Insert node alphabetically
1412 for(node2
=(struct IDnode
*)req
->list
->mlh_Head
;node2
->node
.ln_Succ
;node2
=(struct IDnode
*) node2
->node
.ln_Succ
)
1413 if(Stricmp(node
->node
.ln_Name
,node2
->node
.ln_Name
) < 0)
1415 Insert((struct List
*) req
->list
,(struct Node
*)node
,node2
->node
.ln_Pred
);
1419 // Add the users preferred mode
1421 if((req
->Flags
& defaultmode
) && (AHIBase
->ahib_AudioMode
!= AHI_INVALID_ID
)) do
1424 if(!TestAudioID(AHIBase
->ahib_AudioMode
,req
->FilterTags
))
1427 if(!CallHookPkt(req
->FilterFunc
,req
,(APTR
)AHIBase
->ahib_AudioMode
))
1430 if((node
=AllocVec(sizeof(struct IDnode
),MEMF_ANY
)))
1432 node
->node
.ln_Type
=NT_USER
;
1433 node
->node
.ln_Pri
=0;
1434 node
->node
.ln_Name
=node
->name
;
1435 node
->ID
= AHI_DEFAULT_ID
;
1436 Sprintf(node
->node
.ln_Name
, GetString(msgDefaultMode
, req
->Catalog
));
1437 AddTail((struct List
*) req
->list
, (struct Node
*)node
);
1441 if(NULL
== ((struct IDnode
*)req
->list
->mlh_Head
)->node
.ln_Succ
)
1443 // List is empty, no audio modes!
1444 // Return immediately (no nodes to free)
1445 SetIoErr(ERROR_NO_MORE_ENTRIES
);
1446 ExtCloseCatalog(req
->Catalog
);
1447 req
->Catalog
= FALSE
;
1455 screen
= req
->Screen
;
1457 else if(req
->PubScreenName
!= (STRPTR
) -1)
1459 pub_screen
= LockPubScreen( req
->PubScreenName
);
1460 screen
= pub_screen
;
1462 else if(req
->SrcWindow
)
1465 screen
= req
->SrcWindow
->WScreen
;
1468 if( screen
== NULL
)
1470 pub_screen
= LockPubScreen( NULL
);
1471 screen
= pub_screen
;
1474 CalculateWindowSizePos( req
, screen
);
1476 // Clear ownIDCMP flag
1477 req
->Flags
&= ~ownIDCMP
;
1479 if( req
->SrcWindow
!= NULL
)
1481 if(req
->Flags
& haveIDCMP
)
1482 req
->Flags
|= ownIDCMP
;
1485 zipcoords
[0]=req
->Req
.ahiam_LeftEdge
;
1486 zipcoords
[1]=req
->Req
.ahiam_TopEdge
;
1490 req
->Window
=OpenWindowTags(
1492 WA_Left
,req
->Req
.ahiam_LeftEdge
,
1493 WA_Top
,req
->Req
.ahiam_TopEdge
,
1494 WA_Width
,req
->Req
.ahiam_Width
,
1495 WA_Height
,req
->Req
.ahiam_Height
,
1499 WA_Title
, req
->TitleText
,
1500 ( pub_screen
!= NULL
? WA_PubScreen
: WA_CustomScreen
), screen
,
1501 WA_PubScreenFallBack
,TRUE
,
1503 WA_SizeBBottom
,TRUE
,
1505 WA_DepthGadget
,TRUE
,
1506 WA_CloseGadget
,TRUE
,
1508 WA_SimpleRefresh
,TRUE
,
1510 WA_IDCMP
,(req
->Flags
& ownIDCMP
? 0 : MY_IDCMPS
),
1511 WA_NewLookMenus
, TRUE
,
1514 if( pub_screen
!= NULL
)
1516 UnlockPubScreen( NULL
, pub_screen
);
1521 // Topaz80: "Frequency"+INTERWIDTH+MINSLIDERWIDTH+INTERWIDTH+"99999 Hz" gives...
1522 WORD min_width
= (req
->Window
->BorderLeft
+4)+
1523 strlen( GetString(msgReqFrequency
, req
->Catalog
))*8+
1524 INTERWIDTH
+MINSLIDERWIDTH
+INTERWIDTH
+
1526 (req
->Window
->BorderRight
+4);
1528 // Topaz80: 5 lines, freq & buttons gives...
1529 WORD min_height
= (req
->Window
->BorderTop
+2)+
1530 (5*8+6)+2+(8+6)+2+(8+6)+
1531 (req
->Window
->BorderBottom
+2);
1533 if( req
->Window
->Width
< min_width
||
1534 req
->Window
->Height
< min_height
)
1536 ChangeWindowBox( req
->Window
,
1537 req
->Window
->LeftEdge
,
1538 req
->Window
->TopEdge
,
1539 max( req
->Window
->Width
, min_width
),
1540 max( req
->Window
->Height
, min_height
) );
1544 WindowLimits( req
->Window
, min_width
, min_height
, 0, 0 );
1546 if((req
->vi
=GetVisualInfoA(req
->Window
->WScreen
, NULL
)))
1548 if(!(LayOutReq(req
,req
->TextAttr
)))
1549 if(!(LayOutReq(req
,&Topaz80
)))
1552 if(rc
) // Layout OK?
1554 struct NewMenu reqnewmenu
[] =
1556 { NM_TITLE
, NULL
, 0 ,0,0,(APTR
) 0, },
1557 { NM_ITEM
, NULL
, 0 ,0,0,(APTR
) LASTMODEITEM
, },
1558 { NM_ITEM
, NULL
, 0 ,0,0,(APTR
) NEXTMODEITEM
, },
1559 { NM_ITEM
, NM_BARLABEL
, 0 ,0,0,(APTR
) 0, },
1560 { NM_ITEM
, NULL
, 0 ,0,0,(APTR
) PROPERTYITEM
, },
1561 { NM_ITEM
, NULL
, 0 ,0,0,(APTR
) RESTOREITEM
, },
1562 { NM_ITEM
, NM_BARLABEL
, 0 ,0,0,(APTR
) 0, },
1563 { NM_ITEM
, NULL
, 0 ,0,0,(APTR
) OKITEM
, },
1564 { NM_ITEM
, NULL
, 0 ,0,0,(APTR
) CANCELITEM
, },
1565 { NM_END
, NULL
, 0 ,0,0,(APTR
) 0, },
1567 static const APTR strings
[] =
1572 msgMenuPropertyList
,
1578 struct NewMenu
*menuptr
;
1581 menuptr
= (struct NewMenu
*) &reqnewmenu
;
1582 stringptr
= (APTR
*) &strings
;
1584 while(menuptr
->nm_Type
!= NM_END
)
1586 if(menuptr
->nm_Label
== NULL
)
1588 menuptr
->nm_CommKey
= GetString(*stringptr
, req
->Catalog
);
1589 menuptr
->nm_Label
= menuptr
->nm_CommKey
+ 2;
1595 if(req
->Flags
& ownIDCMP
)
1597 req
->Window
->UserPort
=req
->SrcWindow
->UserPort
;
1598 ModifyIDCMP(req
->Window
,MY_IDCMPS
);
1601 if((req
->Flags
& lockwin
) && req
->SrcWindow
)
1603 InitRequester(&lockreq
);
1604 locksuxs
=Request(&lockreq
,req
->SrcWindow
);
1605 if(IntuitionBase
->LibNode
.lib_Version
>= 39)
1606 SetWindowPointer(req
->SrcWindow
,
1607 WA_BusyPointer
,TRUE
,
1612 if((req
->Menu
=CreateMenus(reqnewmenu
,
1613 GTMN_FullMenu
, TRUE
,
1614 GTMN_NewLookMenus
, TRUE
,
1617 if(LayoutMenus(req
->Menu
,req
->vi
, TAG_DONE
))
1619 if(SetMenuStrip(req
->Window
, req
->Menu
))
1621 if(req
->Req
.ahiam_InfoOpened
)
1623 OpenInfoWindow(req
);
1628 CloseInfoWindow(req
);
1629 ClearMenuStrip(req
->Window
);
1631 } // else LayoutMenus failed
1632 FreeMenus(req
->Menu
);
1634 } // else CreateMenus failed
1637 if((req
->Flags
& lockwin
) && req
->SrcWindow
)
1640 EndRequest(&lockreq
,req
->SrcWindow
);
1641 if(IntuitionBase
->LibNode
.lib_Version
>= 39)
1642 SetWindowPointer(req
->SrcWindow
,
1643 WA_BusyPointer
,FALSE
,
1647 req
->Req
.ahiam_LeftEdge
= req
->Window
->LeftEdge
;
1648 req
->Req
.ahiam_TopEdge
= req
->Window
->TopEdge
;
1649 req
->Req
.ahiam_Width
= req
->Window
->Width
;
1650 req
->Req
.ahiam_Height
= req
->Window
->Height
;
1651 } // else LayOutReq failed
1655 SetIoErr(ERROR_NO_FREE_STORE
);
1659 if(req
->Flags
& ownIDCMP
)
1660 CloseWindowSafely(req
->Window
);
1662 CloseWindow(req
->Window
);
1664 FreeVisualInfo(req
->vi
);
1666 FreeGadgets(req
->Gadgets
);
1672 SetIoErr(ERROR_NO_FREE_STORE
);
1676 ExtCloseCatalog(req
->Catalog
);
1677 req
->Catalog
= NULL
;
1678 req
->PositiveText
= req
->NegativeText
= NULL
;
1680 if(AHIBase
->ahib_DebugLevel
>= AHI_DEBUG_LOW
)
1682 KPrintF("=>%s\n", (IPTR
)(rc
? "TRUE" : "FALSE"));
1688 /******************************************************************************
1689 ** AHI_FreeAudioRequest *******************************************************
1690 ******************************************************************************/
1692 /****** ahi.device/AHI_FreeAudioRequest *************************************
1695 * AHI_FreeAudioRequest -- frees requester resources
1698 * AHI_FreeAudioRequest( requester );
1701 * void AHI_FreeAudioRequest( struct AHIAudioModeRequester * );
1704 * Frees any resources allocated by AHI_AllocAudioRequestA(). Once a
1705 * requester has been freed, it can no longer be used with other calls to
1706 * AHI_AudioRequestA().
1709 * requester - Requester obtained from AHI_AllocAudioRequestA(), or NULL
1710 * in which case this function does nothing.
1721 * AHI_AllocAudioRequestA()
1723 ****************************************************************************
1728 _AHI_FreeAudioRequest( struct AHIAudioModeRequester
* req
,
1729 struct AHIBase
* AHIBase
)
1732 if(AHIBase
->ahib_DebugLevel
>= AHI_DEBUG_LOW
)
1734 Debug_FreeAudioRequest(req
);