2 AHI - Hardware independent audio subsystem
3 Copyright (C) 1996-2005 Martin Blom <martin@blom.org>
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330, Cambridge,
23 // Fix broken includes
26 #include <exec/memory.h>
27 #include <graphics/rpattr.h>
28 #include <intuition/gadgetclass.h>
29 #include <intuition/intuition.h>
30 #include <intuition/intuitionbase.h>
31 #include <libraries/gadtools.h>
32 #include <libraries/asl.h>
34 #include <clib/alib_protos.h>
35 #include <proto/exec.h>
36 #include <proto/dos.h>
37 #include <proto/gadtools.h>
38 #include <proto/graphics.h>
39 #include <proto/intuition.h>
40 #include <proto/utility.h>
42 #define __NOGLOBALIFACE__
43 #include <proto/ahi.h>
45 #undef __NOGLOBALIFACE__
46 #include <proto/ahi_sub.h>
59 #define min(a,b) (((a)<(b))?(a):(b))
60 #define max(a,b) (((a)>(b))?(a):(b))
62 struct AHIAudioModeRequesterExt
;
64 static void OpenInfoWindow( struct AHIAudioModeRequesterExt
* );
65 static void CloseInfoWindow( struct AHIAudioModeRequesterExt
* );
66 static void UpdateInfoWindow( struct AHIAudioModeRequesterExt
* );
69 /******************************************************************************
70 ** Audio mode requester ******************************************************
71 ******************************************************************************/
73 #define MY_IDCMPS (LISTVIEWIDCMP|SLIDERIDCMP|BUTTONIDCMP|IDCMP_SIZEVERIFY|IDCMP_NEWSIZE|IDCMP_REFRESHWINDOW|IDCMP_CLOSEWINDOW|IDCMP_MENUPICK|IDCMP_VANILLAKEY|IDCMP_RAWKEY)
74 #define MY_INFOIDCMPS (LISTVIEWIDCMP|IDCMP_REFRESHWINDOW|IDCMP_CLOSEWINDOW)
76 #define haveIDCMP 0x0001
77 #define lockwin 0x0002
78 #define freqgad 0x0004
79 #define ownIDCMP 0x0008
80 #define defaultmode 0x0010
82 static const struct TagItem reqboolmap
[] =
84 { AHIR_PrivateIDCMP
, haveIDCMP
},
85 { AHIR_SleepWindow
, lockwin
},
86 { AHIR_DoMixFreq
, freqgad
},
87 { AHIR_DoDefaultMode
, defaultmode
},
91 #define LASTMODEITEM 1
92 #define NEXTMODEITEM 2
93 #define PROPERTYITEM 3
98 /* Node for audio mode requester */
107 /* The attribues list */
117 /* AHIAudioModeRequester extension */
118 struct AHIAudioModeRequesterExt
120 struct AHIAudioModeRequester Req
;
123 struct Window
*SrcWindow
;
124 STRPTR PubScreenName
;
125 struct Screen
*Screen
;
127 struct Hook
*IntuiMsgFunc
;
128 struct TextAttr
*TextAttr
;
129 struct Locale
*Locale
;
133 struct TagItem
*FilterTags
;
134 struct Hook
*FilterFunc
;
136 // struct Screen *PubScreen;
137 struct Window
*Window
;
138 struct Window
*InfoWindow
;
141 struct Gadget
*Gadgets
;
142 struct Gadget
*InfoGadgets
;
143 struct Gadget
*InfoListViewGadget
;
144 struct Gadget
*listviewgadget
;
145 struct Gadget
*slidergadget
;
146 struct MinList
*list
;
147 struct MinList InfoList
;
149 struct Catalog
*Catalog
;
150 struct Attrnode AttrNodes
[ATTRNODES
];
154 static const struct TextAttr Topaz80
= { "topaz.font", 8, 0, 0, };
156 #define MINSLIDERWIDTH 40
159 #define CANCELBUTTON 2
163 #define FREQTEXT2 GetString(msgFreqFmt, req->Catalog) //"%lu Hz"
164 #define FREQLEN2 (5+3) // 5 digits + space + "Hz"
166 LONG
IndexToFrequency( struct Gadget
*gad
, WORD level
)
171 id
= ((struct AHIAudioModeRequesterExt
*)gad
->UserData
)->tempAudioID
;
173 if(id
!= AHI_DEFAULT_ID
)
175 AHI_GetAudioAttrs( id
, NULL
,
176 AHIDB_FrequencyArg
, level
,
177 AHIDB_Frequency
, (IPTR
)&freq
,
182 freq
= AHIBase
->ahib_Frequency
;
188 static void FillReqStruct(struct AHIAudioModeRequesterExt
*req
, struct TagItem
*tags
)
190 ULONG obsolete_userdata
;
192 // Check all known tags
193 req
->SrcWindow
=(struct Window
*)GetTagData(AHIR_Window
,(IPTR
)req
->SrcWindow
,tags
);
194 req
->PubScreenName
=(STRPTR
)GetTagData(AHIR_PubScreenName
,(IPTR
)req
->PubScreenName
,tags
);
195 req
->Screen
=(struct Screen
*)GetTagData(AHIR_Screen
,(IPTR
)req
->Screen
,tags
);
196 req
->IntuiMsgFunc
=(struct Hook
*)GetTagData(AHIR_IntuiMsgFunc
,(IPTR
)req
->IntuiMsgFunc
,tags
);
198 obsolete_userdata
= GetTagData( AHIR_ObsoleteUserData
, 0, tags
);
199 req
->Req
.ahiam_ObsoleteUserData
[ 0 ] = obsolete_userdata
>> 16;
200 req
->Req
.ahiam_ObsoleteUserData
[ 1 ] = obsolete_userdata
& 0xffff;
202 req
->Req
.ahiam_UserData
=(void *)GetTagData(AHIR_UserData
,(IPTR
)req
->Req
.ahiam_UserData
,tags
);
203 req
->TextAttr
=(struct TextAttr
*)GetTagData(AHIR_TextAttr
,(IPTR
)req
->TextAttr
,tags
);
204 req
->Locale
=(struct Locale
*)GetTagData(AHIR_Locale
,(IPTR
)req
->Locale
,tags
);
205 req
->TitleText
=(STRPTR
)GetTagData(AHIR_TitleText
,(IPTR
)req
->TitleText
,tags
);
206 req
->PositiveText
=(STRPTR
)GetTagData(AHIR_PositiveText
,(IPTR
)req
->PositiveText
,tags
);
207 req
->NegativeText
=(STRPTR
)GetTagData(AHIR_NegativeText
,(IPTR
)req
->NegativeText
,tags
);
208 req
->Req
.ahiam_LeftEdge
=GetTagData(AHIR_InitialLeftEdge
,req
->Req
.ahiam_LeftEdge
,tags
);
209 req
->Req
.ahiam_TopEdge
=GetTagData(AHIR_InitialTopEdge
,req
->Req
.ahiam_TopEdge
,tags
);
210 req
->Req
.ahiam_Width
=GetTagData(AHIR_InitialWidth
,req
->Req
.ahiam_Width
,tags
);
211 req
->Req
.ahiam_Height
=GetTagData(AHIR_InitialHeight
,req
->Req
.ahiam_Height
,tags
);
212 req
->Req
.ahiam_AudioID
=GetTagData(AHIR_InitialAudioID
,req
->Req
.ahiam_AudioID
,tags
);
213 req
->Req
.ahiam_MixFreq
=GetTagData(AHIR_InitialMixFreq
,req
->Req
.ahiam_MixFreq
,tags
);
214 req
->Req
.ahiam_InfoOpened
=GetTagData(AHIR_InitialInfoOpened
,req
->Req
.ahiam_InfoOpened
,tags
);
215 req
->Req
.ahiam_InfoLeftEdge
=GetTagData(AHIR_InitialInfoLeftEdge
,req
->Req
.ahiam_InfoLeftEdge
,tags
);
216 req
->Req
.ahiam_InfoTopEdge
=GetTagData(AHIR_InitialInfoTopEdge
,req
->Req
.ahiam_InfoTopEdge
,tags
);
217 // req->Req.ahiam_InfoWidth=GetTagData(AHIR_InitialInfoWidth,req->Req.ahiam_InfoWidth,tags);
218 // req->Req.ahiam_InfoHeight=GetTagData(AHIR_InitialInfoHeight,req->Req.ahiam_InfoHeight,tags);
219 req
->FilterTags
=(struct TagItem
*)GetTagData(AHIR_FilterTags
,(IPTR
)req
->FilterTags
,tags
);
220 req
->FilterFunc
=(struct Hook
*)GetTagData(AHIR_FilterFunc
,(IPTR
)req
->FilterFunc
,tags
);
221 req
->Flags
=PackBoolTags(req
->Flags
,tags
,(struct TagItem
*)reqboolmap
);
226 CalculateWindowSizePos( struct AHIAudioModeRequesterExt
* req
,
227 struct Screen
* screen
)
229 struct AslSemaphore
* asl_semaphore
= NULL
;
231 // Default position and size
237 #ifdef ASL_SEMAPHORE_NAME /* Don't break if no v45 includes found */
239 asl_semaphore
= (struct AslSemaphore
*) FindSemaphore( ASL_SEMAPHORE_NAME
);
241 if( asl_semaphore
!= NULL
)
243 ObtainSemaphore( (struct SignalSemaphore
*) asl_semaphore
);
247 if( asl_semaphore
!= NULL
)
249 if( asl_semaphore
->as_Version
>= 45 &&
250 asl_semaphore
->as_Size
> offsetof( struct AslSemaphore
,
251 as_RelativeHeight
) )
253 if( asl_semaphore
->as_SizePosition
& ASLOPTION_ASLOverrides
)
255 // Force default settings
256 req
->Req
.ahiam_LeftEdge
= -1;
257 req
->Req
.ahiam_TopEdge
= -1;
258 req
->Req
.ahiam_Width
= -1;
259 req
->Req
.ahiam_Height
= -1;
262 if( ( asl_semaphore
->as_SizePosition
& ASLSIZE_MASK
) ==
263 ASLSIZE_RelativeSize
)
265 // FIXME: Is it correct to use screen size only? The include file
266 // says something about parent window??
268 width
= (WORD
) ( (LONG
) screen
->Width
*
269 asl_semaphore
->as_RelativeWidth
/ 100 );
270 height
= (WORD
) ( (LONG
) screen
->Height
*
271 asl_semaphore
->as_RelativeHeight
/ 100 );
277 ReleaseSemaphore( (struct SignalSemaphore
*) asl_semaphore
);
278 asl_semaphore
= NULL
;
283 // Set default main window size
284 if( req
->Req
.ahiam_Width
== -1 )
285 req
->Req
.ahiam_Width
= width
;
287 if( req
->Req
.ahiam_Height
== -1 )
288 req
->Req
.ahiam_Height
= height
;
291 #ifdef ASL_SEMAPHORE_NAME /* Don't break if no v45 includes found */
292 if( asl_semaphore
!= NULL
)
294 switch( asl_semaphore
->as_SizePosition
& ASLPOS_MASK
)
296 case ASLPOS_CenterWindow
:
297 if( req
->SrcWindow
!= NULL
)
299 top
= ( req
->SrcWindow
->TopEdge
+
300 req
->SrcWindow
->Height
/ 2 -
301 req
->Req
.ahiam_Height
/ 2 );
302 left
= ( req
->SrcWindow
->LeftEdge
+
303 req
->SrcWindow
->Width
/ 2 -
304 req
->Req
.ahiam_Width
/ 2 );
309 // Fall through and use ASLPOS_CenterScreen instead
312 case ASLPOS_CenterScreen
:
313 top
= ( screen
->Height
/ 2 -
314 req
->Req
.ahiam_Height
/ 2 );
315 left
= ( screen
->Width
/ 2 -
316 req
->Req
.ahiam_Width
/ 2 );
319 case ASLPOS_WindowPosition
:
320 if( req
->SrcWindow
!= NULL
)
322 top
= ( req
->SrcWindow
->TopEdge
+
323 asl_semaphore
->as_RelativeTop
);
324 left
= ( req
->SrcWindow
->LeftEdge
+
325 asl_semaphore
->as_RelativeLeft
);
330 // Fall through and use ASLPOS_ScreenPosition instead
333 case ASLPOS_ScreenPosition
:
334 top
= asl_semaphore
->as_RelativeTop
;
335 left
= asl_semaphore
->as_RelativeLeft
;
338 case ASLPOS_CenterMouse
:
339 top
= ( screen
->MouseY
-
340 req
->Req
.ahiam_Height
/ 2 );
341 left
= ( screen
->MouseX
-
342 req
->Req
.ahiam_Width
/ 2 );
345 case ASLPOS_DefaultPosition
:
347 // Do nothing (use hardcoded defaults)
353 // Set default main window position
354 if( req
->Req
.ahiam_LeftEdge
== -1 )
355 req
->Req
.ahiam_LeftEdge
= left
;
357 if( req
->Req
.ahiam_TopEdge
== -1 )
358 req
->Req
.ahiam_TopEdge
= top
;
361 // Set default info window position (size is fixed)
362 if( req
->Req
.ahiam_InfoLeftEdge
== -1 )
363 req
->Req
.ahiam_InfoLeftEdge
= req
->Req
.ahiam_LeftEdge
+ 16;
365 if( req
->Req
.ahiam_InfoTopEdge
== -1 )
366 req
->Req
.ahiam_InfoTopEdge
= req
->Req
.ahiam_TopEdge
+ 25;
370 if( asl_semaphore
!= NULL
)
372 ReleaseSemaphore( (struct SignalSemaphore
*) asl_semaphore
);
377 ** Returns the ordinal number of the current audio id.
380 static LONG
GetSelected(struct AHIAudioModeRequesterExt
*req
)
382 struct IDnode
*idnode
;
385 for(idnode
=(struct IDnode
*)req
->list
->mlh_Head
;
386 idnode
->node
.ln_Succ
;
387 idnode
=(struct IDnode
*) idnode
->node
.ln_Succ
)
389 if(idnode
->ID
== req
->tempAudioID
)
394 if(idnode
->node
.ln_Succ
== NULL
)
397 req
->tempAudioID
=AHI_INVALID_ID
; // Crashed if this is not done! FIXIT!
403 ** Calculates what the current slider level shoud be and how many levels total
406 static void GetSliderAttrs(struct AHIAudioModeRequesterExt
*req
, LONG
*levels
, LONG
*level
)
411 AHI_GetAudioAttrs(req
->tempAudioID
, NULL
,
412 AHIDB_Frequencies
, (IPTR
)levels
,
413 AHIDB_IndexArg
, (req
->tempAudioID
== AHI_DEFAULT_ID
?
414 AHIBase
->ahib_Frequency
: req
->tempFrequency
),
415 AHIDB_Index
, (IPTR
)level
,
418 if(*level
>= *levels
)
421 AHI_GetAudioAttrs(req
->tempAudioID
, NULL
,
422 AHIDB_FrequencyArg
, *level
,
423 AHIDB_Frequency
, (IPTR
)&req
->tempFrequency
,
428 ** Updates the requester to the current frequency and if 'all'==TRUE, audio mode.
431 static void SetSelected(struct AHIAudioModeRequesterExt
*req
, BOOL all
)
433 LONG sliderlevels
,sliderlevel
,selected
;
434 BOOL disabled
= FALSE
;
435 ULONG top
= GTLV_Top
;
436 ULONG makevisible
= GTLV_MakeVisible
;
441 selected
=GetSelected(req
);
443 if( selected
== ~0 || GadToolsBase
->lib_Version
>= 39 )
450 makevisible
= TAG_IGNORE
;
453 GT_SetGadgetAttrs(req
->listviewgadget
, req
->Window
, NULL
,
455 makevisible
, selected
,
456 GTLV_Selected
, selected
,
461 GetSliderAttrs(req
,&sliderlevels
,&sliderlevel
);
463 if( sliderlevels
== 0 || req
->tempAudioID
== AHI_DEFAULT_ID
)
468 GT_SetGadgetAttrs(req
->slidergadget
, req
->Window
, NULL
,
469 GTSL_Max
, sliderlevels
-1,
470 GTSL_Level
, sliderlevel
,
471 GA_Disabled
, disabled
,
474 UpdateInfoWindow(req
);
479 ** Positions all gadgets in the requester.
482 static BOOL
LayOutReq (struct AHIAudioModeRequesterExt
*req
, const struct TextAttr
*TextAttr
)
487 struct TextAttr
*gadtextattr
;
488 struct TextFont
*font
;
489 LONG fontwidth
,buttonheight
,buttonwidth
,pixels
;
490 struct IntuiText intuitext
= {1,0,JAM1
,0,0,NULL
,NULL
,NULL
};
491 LONG sliderlevels
,sliderlevel
;
494 selected
=GetSelected(req
);
495 GetSliderAttrs(req
,&sliderlevels
,&sliderlevel
);
497 // Calculate gadget area
498 req
->gx
=req
->Window
->BorderLeft
+4;
499 req
->gy
=req
->Window
->BorderTop
+2;
500 req
->gw
=req
->Window
->Width
-req
->gx
-(req
->Window
->BorderRight
+4);
501 req
->gh
=req
->Window
->Height
-req
->gy
-(req
->Window
->BorderBottom
+2);
505 RemoveGList(req
->Window
,req
->Gadgets
,-1);
506 FreeGadgets(req
->Gadgets
);
507 SetAPen(req
->Window
->RPort
,0);
508 SetDrMd(req
->Window
->RPort
,JAM1
);
509 EraseRect(req
->Window
->RPort
, req
->Window
->BorderLeft
, req
->Window
->BorderTop
,
510 req
->Window
->Width
-req
->Window
->BorderRight
-1,req
->Window
->Height
-req
->Window
->BorderBottom
-1);
511 RefreshWindowFrame(req
->Window
);
514 if((gad
=CreateContext(&req
->Gadgets
)))
517 gadtextattr
=(struct TextAttr
*)TextAttr
;
519 gadtextattr
=req
->Window
->WScreen
->Font
;
521 if((font
=OpenFont(gadtextattr
)))
523 fontwidth
=font
->tf_XSize
;
529 buttonheight
=gadtextattr
->ta_YSize
+6;
530 intuitext
.ITextFont
=gadtextattr
;
531 intuitext
.IText
=req
->PositiveText
;
532 buttonwidth
=IntuiTextLength(&intuitext
);
533 intuitext
.IText
=req
->NegativeText
;
534 pixels
=IntuiTextLength(&intuitext
);
535 buttonwidth
=max(pixels
,buttonwidth
);
536 buttonwidth
+=4+fontwidth
;
538 // Create gadgets and check if they fit
539 // Do the two buttons fit?
540 if(2*buttonwidth
> req
->gw
)
542 ng
.ng_TextAttr
=gadtextattr
;
543 ng
.ng_VisualInfo
=req
->vi
;
546 ng
.ng_LeftEdge
=req
->gx
;
547 ng
.ng_TopEdge
=req
->gy
+req
->gh
-buttonheight
;
548 ng
.ng_Width
=buttonwidth
;
549 ng
.ng_Height
=buttonheight
;
550 ng
.ng_GadgetText
=req
->PositiveText
;
551 ng
.ng_GadgetID
=OKBUTTON
;
552 ng
.ng_Flags
=PLACETEXT_IN
;
553 gad
=CreateGadget(BUTTON_KIND
,gad
,&ng
,TAG_END
);
555 ng
.ng_LeftEdge
=req
->gx
+req
->gw
-ng
.ng_Width
;
556 ng
.ng_GadgetText
=req
->NegativeText
;
557 ng
.ng_GadgetID
=CANCELBUTTON
;
558 gad
=CreateGadget(BUTTON_KIND
,gad
,&ng
,TAG_END
);
560 if(req
->Flags
& freqgad
)
562 intuitext
.IText
= GetString(msgReqFrequency
, req
->Catalog
);
563 pixels
=IntuiTextLength(&intuitext
)+INTERWIDTH
;
564 if(pixels
+MINSLIDERWIDTH
+INTERWIDTH
+FREQLEN2
*fontwidth
> req
->gw
)
566 ng
.ng_Width
=req
->gw
-pixels
-INTERWIDTH
-FREQLEN2
*fontwidth
;
567 ng
.ng_LeftEdge
=req
->gx
+pixels
;
568 ng
.ng_TopEdge
-=2+buttonheight
;
569 ng
.ng_GadgetText
= GetString(msgReqFrequency
, req
->Catalog
);
570 ng
.ng_GadgetID
=FREQSLIDER
;
571 ng
.ng_Flags
=PLACETEXT_LEFT
;
572 gad
=CreateGadget(SLIDER_KIND
,gad
,&ng
,
574 GTSL_Max
,sliderlevels
-1,
575 GTSL_Level
,sliderlevel
,
576 GTSL_LevelFormat
, FREQTEXT2
,
577 GTSL_MaxLevelLen
,FREQLEN2
,
578 GTSL_LevelPlace
,PLACETEXT_RIGHT
,
579 GTSL_DispFunc
, m68k_IndexToFrequency
,
581 GA_Disabled
,!sliderlevels
|| (req
->tempAudioID
== AHI_DEFAULT_ID
),
583 req
->slidergadget
=gad
; // Save for HadleReq()...
586 if((ng
.ng_Height
=ng
.ng_TopEdge
-2-req
->gy
) < buttonheight
)
588 ng
.ng_LeftEdge
=req
->gx
;
589 ng
.ng_TopEdge
=req
->gy
;
591 ng
.ng_GadgetText
=NULL
,
592 ng
.ng_GadgetID
=LISTVIEW
;
593 ng
.ng_Flags
=PLACETEXT_ABOVE
;
594 gad
=CreateGadget(LISTVIEW_KIND
,gad
,&ng
,
595 GTLV_ScrollWidth
,(fontwidth
>8 ? fontwidth
*2 : 18),
596 GTLV_Labels
, req
->list
,
598 ((selected
== ~0) || (GadToolsBase
->lib_Version
>= 39) ? TAG_IGNORE
: GTLV_Top
),selected
,
599 (selected
== ~0 ? TAG_IGNORE
: GTLV_MakeVisible
),selected
,
600 GTLV_Selected
,selected
,
602 req
->listviewgadget
=gad
; // Save for HadleReq()...
610 AddGList(req
->Window
,req
->Gadgets
,~0,-1,NULL
);
611 RefreshGList(req
->Gadgets
,req
->Window
,NULL
,-1);
612 GT_RefreshWindow(req
->Window
,NULL
);
619 /* these functions close an Intuition window
620 * that shares a port with other Intuition
621 * windows or IPC customers.
623 * We are careful to set the UserPort to
624 * null before closing, and to free
625 * any messages that it might have been
629 /* remove and reply all IntuiMessages on a port that
630 * have been sent to a particular window
631 * (note that we don't rely on the ln_Succ pointer
632 * of a message after we have replied it)
634 static void StripIntuiMessagesAHI( struct MsgPort
*mp
, struct Window
*win
)
636 struct IntuiMessage
*msg
;
639 msg
= (struct IntuiMessage
*) mp
->mp_MsgList
.lh_Head
;
641 while((succ
= msg
->ExecMessage
.mn_Node
.ln_Succ
)) {
643 if( msg
->IDCMPWindow
== win
) {
645 /* Intuition is about to free this message.
646 * Make sure that we have politely sent it back.
648 Remove( (struct Node
*) msg
);
650 ReplyMsg( (struct Message
*) msg
);
653 msg
= (struct IntuiMessage
*) succ
;
657 static void CloseWindowSafely( struct Window
*win
)
659 /* we forbid here to keep out of race conditions with Intuition */
662 /* send back any messages for this window
663 * that have not yet been processed
665 StripIntuiMessagesAHI( win
->UserPort
, win
);
667 /* clear UserPort so Intuition will not free it */
668 win
->UserPort
= NULL
;
670 /* tell Intuition to stop sending more messages */
671 ModifyIDCMP( win
, 0L );
673 /* turn multitasking back on */
676 /* and really close the window */
680 static BOOL
HandleReq( struct AHIAudioModeRequesterExt
*req
)
682 // Returns FALSE if requester was cancelled
685 BOOL done
=FALSE
,rc
=TRUE
;
686 ULONG
class,sec
,oldsec
=0,micro
,oldmicro
=0,oldid
=AHI_INVALID_ID
;
689 struct Gadget
*pgsel
;
690 struct IntuiMessage
*imsg
;
691 struct IDnode
*idnode
;
692 LONG sliderlevels
,sliderlevel
,i
,selected
;
693 struct MenuItem
*item
;
697 Wait(1L << req
->Window
->UserPort
->mp_SigBit
);
699 while ((imsg
=GT_GetIMsg(req
->Window
->UserPort
)) != NULL
)
702 if(imsg
->IDCMPWindow
== req
->InfoWindow
)
709 case IDCMP_CLOSEWINDOW
:
710 CloseInfoWindow(req
);
712 case IDCMP_REFRESHWINDOW
:
713 GT_BeginRefresh(req
->InfoWindow
);
714 GT_EndRefresh(req
->InfoWindow
,TRUE
);
717 continue; // Get next IntuiMessage
720 else if(imsg
->IDCMPWindow
!= req
->Window
) // Not my window!
722 if(req
->IntuiMsgFunc
)
723 CallHookPkt(req
->IntuiMsgFunc
,req
,imsg
);
724 // else what to do??? Reply and forget? FIXIT!
730 qual
=imsg
->Qualifier
;
733 pgsel
=(struct Gadget
*)imsg
->IAddress
; // pgsel illegal if not gadget
741 case 0x4c: // Cursor Up
742 selected
=GetSelected(req
);
747 idnode
=(struct IDnode
*)req
->list
->mlh_Head
;
748 for(i
=0;i
<selected
;i
++)
749 idnode
=(struct IDnode
*)idnode
->node
.ln_Succ
;
750 req
->tempAudioID
=idnode
->ID
;
751 SetSelected(req
,TRUE
);
753 case 0x4d: // Cursor Down
754 selected
=GetSelected(req
);
755 selected
++; // ~0 => 0
756 idnode
=(struct IDnode
*)req
->list
->mlh_Head
;
757 for(i
=0;i
<selected
;i
++)
758 if(idnode
->node
.ln_Succ
->ln_Succ
)
759 idnode
=(struct IDnode
*)idnode
->node
.ln_Succ
;
760 req
->tempAudioID
=idnode
->ID
;
761 SetSelected(req
,TRUE
);
763 case 0x4e: // Cursor Right
764 GetSliderAttrs(req
,&sliderlevels
,&sliderlevel
);
765 sliderlevel
+= (qual
& (IEQUALIFIER_LSHIFT
|IEQUALIFIER_RSHIFT
) ? 10 :1);
766 if(sliderlevel
>= sliderlevels
)
767 sliderlevel
=sliderlevels
-1;
768 AHI_GetAudioAttrs(req
->tempAudioID
, NULL
,
769 AHIDB_FrequencyArg
,sliderlevel
,
770 AHIDB_Frequency
, (IPTR
)&req
->tempFrequency
,
772 SetSelected(req
,FALSE
);
774 case 0x4f: // Cursor Left
775 GetSliderAttrs(req
,&sliderlevels
,&sliderlevel
);
776 sliderlevel
-= (qual
& (IEQUALIFIER_LSHIFT
|IEQUALIFIER_RSHIFT
) ? 10 :1);
779 AHI_GetAudioAttrs(req
->tempAudioID
, NULL
,
780 AHIDB_FrequencyArg
,sliderlevel
,
781 AHIDB_Frequency
, (IPTR
)&req
->tempFrequency
,
783 SetSelected(req
,FALSE
);
787 case IDCMP_GADGETUP
:
788 switch ( pgsel
->GadgetID
)
798 AHI_GetAudioAttrs(req
->tempAudioID
, NULL
,
799 AHIDB_FrequencyArg
,code
,
800 AHIDB_Frequency
, (IPTR
)&req
->tempFrequency
,
804 idnode
=(struct IDnode
*)req
->list
->mlh_Head
;
806 idnode
=(struct IDnode
*)idnode
->node
.ln_Succ
;
807 req
->tempAudioID
=idnode
->ID
;
808 SetSelected(req
,FALSE
);
809 // Test doubleclick and save timestamp
810 if( (oldid
== req
->tempAudioID
) && DoubleClick(oldsec
,oldmicro
,sec
,micro
))
814 oldid
=req
->tempAudioID
;
821 if(!(LayOutReq(req
,req
->TextAttr
)))
822 if(!(LayOutReq(req
,&Topaz80
)))
829 case IDCMP_CLOSEWINDOW
:
833 case IDCMP_REFRESHWINDOW
:
834 GT_BeginRefresh(req
->Window
);
835 GT_EndRefresh(req
->Window
,TRUE
);
837 case IDCMP_SIZEVERIFY
:
840 while((code
!= MENUNULL
) && !done
)
842 item
=ItemAddress(req
->Menu
, code
);
843 switch((IPTR
)GTMENUITEM_USERDATA(item
))
846 selected
=GetSelected(req
);
851 idnode
=(struct IDnode
*)req
->list
->mlh_Head
;
852 for(i
=0;i
<selected
;i
++)
853 idnode
=(struct IDnode
*)idnode
->node
.ln_Succ
;
854 req
->tempAudioID
=idnode
->ID
;
855 SetSelected(req
,TRUE
);
858 selected
=GetSelected(req
);
859 selected
++; // ~0 => 0
860 idnode
=(struct IDnode
*)req
->list
->mlh_Head
;
861 for(i
=0;i
<selected
;i
++)
862 if(idnode
->node
.ln_Succ
->ln_Succ
)
863 idnode
=(struct IDnode
*)idnode
->node
.ln_Succ
;
864 req
->tempAudioID
=idnode
->ID
;
865 SetSelected(req
,TRUE
);
871 req
->tempAudioID
=req
->Req
.ahiam_AudioID
;
872 req
->tempFrequency
=req
->Req
.ahiam_MixFreq
;
873 SetSelected(req
,TRUE
);
883 code
= item
->NextSelect
;
892 req
->Req
.ahiam_AudioID
= req
->tempAudioID
;
894 if(req
->tempAudioID
!= AHI_DEFAULT_ID
)
896 req
->Req
.ahiam_MixFreq
= req
->tempFrequency
;
900 req
->Req
.ahiam_MixFreq
= AHI_DEFAULT_FREQ
;
907 static void OpenInfoWindow( struct AHIAudioModeRequesterExt
*req
)
913 if(req
->InfoWindow
== NULL
)
915 req
->InfoWindow
=OpenWindowTags(NULL
,
916 WA_Left
, req
->Req
.ahiam_InfoLeftEdge
,
917 WA_Top
, req
->Req
.ahiam_InfoTopEdge
,
918 WA_Width
, req
->Req
.ahiam_InfoWidth
,
919 WA_Height
, req
->Req
.ahiam_InfoHeight
,
920 WA_Title
, GetString(msgReqInfoTitle
, req
->Catalog
),
921 WA_CustomScreen
, req
->Window
->WScreen
,
922 WA_PubScreenFallBack
, TRUE
,
924 WA_DepthGadget
, TRUE
,
925 WA_CloseGadget
, TRUE
,
927 WA_SimpleRefresh
, TRUE
,
930 WA_NewLookMenus
, TRUE
,
935 req
->InfoWindow
->UserPort
= req
->Window
->UserPort
;
936 ModifyIDCMP(req
->InfoWindow
, MY_INFOIDCMPS
);
938 if((gad
= CreateContext(&req
->InfoGadgets
)))
940 ng
.ng_TextAttr
= req
->TextAttr
;
941 ng
.ng_VisualInfo
= req
->vi
;
942 ng
.ng_LeftEdge
= req
->InfoWindow
->BorderLeft
+4;
943 ng
.ng_TopEdge
= req
->InfoWindow
->BorderTop
+2;
944 ng
.ng_Width
= req
->InfoWindow
->Width
945 - (req
->InfoWindow
->BorderLeft
+4)
946 - (req
->InfoWindow
->BorderRight
+4);
947 ng
.ng_Height
= req
->InfoWindow
->Height
948 - (req
->InfoWindow
->BorderTop
+2)
949 - (req
->InfoWindow
->BorderBottom
+2);
951 ng
.ng_GadgetText
= NULL
;
953 ng
.ng_Flags
= PLACETEXT_ABOVE
;
954 gad
= CreateGadget(LISTVIEW_KIND
, gad
, &ng
,
957 req
->InfoListViewGadget
= gad
;
961 AddGList(req
->InfoWindow
, req
->InfoGadgets
, ~0, -1, NULL
);
962 RefreshGList(req
->InfoGadgets
, req
->InfoWindow
, NULL
, -1);
963 GT_RefreshWindow(req
->InfoWindow
, NULL
);
964 UpdateInfoWindow(req
);
972 static void UpdateInfoWindow( struct AHIAudioModeRequesterExt
*req
)
974 LONG id
=0, bits
=0, stereo
=0, pan
=0, hifi
=0, channels
=0, minmix
=0, maxmix
=0,
975 record
=0, fullduplex
=0, multichannel
=0;
978 id
= req
->tempAudioID
;
979 if(id
== AHI_DEFAULT_ID
)
981 id
= AHIBase
->ahib_AudioMode
;
985 AHI_GetAudioAttrs(id
, NULL
,
986 AHIDB_MultiChannel
, (IPTR
)&multichannel
,
987 AHIDB_Stereo
, (IPTR
)&stereo
,
988 AHIDB_Panning
, (IPTR
)&pan
,
989 AHIDB_HiFi
, (IPTR
)&hifi
,
990 AHIDB_Record
, (IPTR
)&record
,
991 AHIDB_FullDuplex
, (IPTR
)&fullduplex
,
992 AHIDB_Bits
, (IPTR
)&bits
,
993 AHIDB_MaxChannels
, (IPTR
)&channels
,
994 AHIDB_MinMixFreq
, (IPTR
)&minmix
,
995 AHIDB_MaxMixFreq
, (IPTR
)&maxmix
,
998 GT_SetGadgetAttrs(req
->InfoListViewGadget
, req
->InfoWindow
, NULL
,
1002 NewList((struct List
*) &req
->InfoList
);
1003 for(i
=0; i
<ATTRNODES
; i
++)
1005 req
->AttrNodes
[i
].node
.ln_Name
= req
->AttrNodes
[i
].text
;
1006 req
->AttrNodes
[i
].text
[0] = '\0';
1007 req
->AttrNodes
[i
].node
.ln_Type
= NT_USER
;
1008 req
->AttrNodes
[i
].node
.ln_Pri
= 0;
1012 AddTail((struct List
*) &req
->InfoList
,(struct Node
*) &req
->AttrNodes
[i
]);
1013 Sprintf(req
->AttrNodes
[i
++].text
, GetString(msgReqInfoAudioID
, req
->Catalog
),
1015 AddTail((struct List
*) &req
->InfoList
,(struct Node
*) &req
->AttrNodes
[i
]);
1016 Sprintf(req
->AttrNodes
[i
++].text
, GetString(msgReqInfoResolution
, req
->Catalog
),
1017 bits
, (IPTR
)GetString((multichannel
? msgReqInfoMultiChannel
: (stereo
?
1018 (pan
? msgReqInfoStereoPan
: msgReqInfoStereo
) :
1019 msgReqInfoMono
)), req
->Catalog
));
1020 AddTail((struct List
*) &req
->InfoList
,(struct Node
*) &req
->AttrNodes
[i
]);
1021 Sprintf(req
->AttrNodes
[i
++].text
, GetString(msgReqInfoChannels
, req
->Catalog
),
1023 AddTail((struct List
*) &req
->InfoList
,(struct Node
*) &req
->AttrNodes
[i
]);
1024 Sprintf(req
->AttrNodes
[i
++].text
, GetString(msgReqInfoMixrate
, req
->Catalog
),
1028 AddTail((struct List
*) &req
->InfoList
,(struct Node
*) &req
->AttrNodes
[i
]);
1029 Sprintf(req
->AttrNodes
[i
++].text
, GetString(msgReqInfoHiFi
, req
->Catalog
));
1033 AddTail((struct List
*) &req
->InfoList
,(struct Node
*) &req
->AttrNodes
[i
]);
1034 Sprintf(req
->AttrNodes
[i
++].text
, GetString(
1035 fullduplex
? msgReqInfoRecordFull
: msgReqInfoRecordHalf
, req
->Catalog
));
1038 GT_SetGadgetAttrs(req
->InfoListViewGadget
, req
->InfoWindow
, NULL
,
1039 GTLV_Labels
, &req
->InfoList
,
1044 static void CloseInfoWindow( struct AHIAudioModeRequesterExt
*req
)
1048 req
->Req
.ahiam_InfoOpened
= TRUE
;
1049 req
->Req
.ahiam_InfoLeftEdge
= req
->InfoWindow
->LeftEdge
;
1050 req
->Req
.ahiam_InfoTopEdge
= req
->InfoWindow
->TopEdge
;
1051 req
->Req
.ahiam_InfoWidth
= req
->InfoWindow
->Width
;
1052 req
->Req
.ahiam_InfoHeight
= req
->InfoWindow
->Height
;
1053 CloseWindowSafely(req
->InfoWindow
);
1054 req
->InfoWindow
= NULL
;
1059 req
->Req
.ahiam_InfoOpened
= FALSE
;
1063 FreeGadgets(req
->InfoGadgets
);
1064 req
->InfoGadgets
= NULL
;
1068 /******************************************************************************
1069 ** AHI_AllocAudioRequestA *****************************************************
1070 ******************************************************************************/
1072 /****** ahi.device/AHI_AllocAudioRequestA ***********************************
1075 * AHI_AllocAudioRequestA -- allocate an audio mode requester.
1076 * AHI_AllocAudioRequest -- varargs stub for AHI_AllocAudioRequestA()
1079 * requester = AHI_AllocAudioRequestA( tags );
1082 * struct AHIAudioModeRequester *AHI_AllocAudioRequestA(
1083 * struct TagItem * );
1085 * requester = AHI_AllocAudioRequest( tag1, ... );
1087 * struct AHIAudioModeRequester *AHI_AllocAudioRequest( Tag, ... );
1090 * Allocates an audio mode requester data structure.
1093 * tags - A pointer to an optional tag list specifying how to initialize
1094 * the data structure returned by this function. See the
1095 * documentation for AHI_AudioRequestA() for an explanation of how
1096 * to use the currently defined tags.
1099 * requester - An initialized requester data structure, or NULL on
1105 * The requester data structure is READ-ONLY and can only be modified
1111 * AHI_AudioRequestA(), AHI_FreeAudioRequest()
1113 ****************************************************************************
1117 struct AHIAudioModeRequester
*
1118 _AHI_AllocAudioRequestA( struct TagItem
* tags
,
1119 struct AHIBase
* AHIBase
)
1121 struct AHIAudioModeRequesterExt
*req
;
1123 if(AHIBase
->ahib_DebugLevel
>= AHI_DEBUG_LOW
)
1125 Debug_AllocAudioRequestA(tags
);
1128 if((req
=AllocVec(sizeof(struct AHIAudioModeRequesterExt
),MEMF_CLEAR
)))
1131 req
->Req
.ahiam_LeftEdge
= -1;
1132 req
->Req
.ahiam_TopEdge
= -1;
1133 req
->Req
.ahiam_Width
= -1;
1134 req
->Req
.ahiam_Height
= -1;
1136 req
->Req
.ahiam_AudioID
= AHI_INVALID_ID
;
1137 req
->Req
.ahiam_MixFreq
= AHIBase
->ahib_Frequency
;
1139 req
->Req
.ahiam_InfoLeftEdge
= -1;
1140 req
->Req
.ahiam_InfoTopEdge
= -1;
1141 req
->Req
.ahiam_InfoWidth
= 280;
1142 req
->Req
.ahiam_InfoHeight
= 112;
1144 req
->PubScreenName
= (STRPTR
) -1;
1146 FillReqStruct(req
,tags
);
1149 if(AHIBase
->ahib_DebugLevel
>= AHI_DEBUG_LOW
)
1151 KPrintF("=>0x%P\n", (IPTR
)req
);
1154 return (struct AHIAudioModeRequester
*) req
;
1158 /******************************************************************************
1159 ** AHI_AudioRequestA **********************************************************
1160 ******************************************************************************/
1162 /****** ahi.device/AHI_AudioRequestA ****************************************
1165 * AHI_AudioRequestA -- get an audio mode from user using an requester.
1166 * AHI_AudioRequest -- varargs stub for AHI_AudioRequestA()
1169 * success = AHI_AudioRequestA( requester, tags );
1172 * BOOL AHI_AudioRequestA( struct AHIAudioModeRequester *,
1173 * struct TagItem * );
1175 * result = AHI_AudioRequest( requester, tag1, ... );
1177 * BOOL AHI_AudioRequest( struct AHIAudioModeRequester *, Tag, ... );
1180 * Prompts the user for an audio mode, based on the modifying tags.
1181 * If the user cancels or the system aborts the request, FALSE is
1182 * returned, otherwise the requester's data structure reflects the
1185 * Note that tag values stay in effect for each use of the requester
1186 * until they are cleared or modified by passing the same tag with a
1190 * requester - Requester structure allocated with
1191 * AHI_AllocAudioRequestA(). If this parameter is NULL, this
1192 * function will always return FALSE with a dos.library/IoErr()
1193 * result of ERROR_NO_FREE_STORE.
1194 * tags - Pointer to an optional tag list which may be used to control
1195 * features of the requester.
1198 * Tags used for the requester (they look remarkable similar to the
1199 * screen mode requester in ASL, don't they? ;-) )
1201 * AHIR_Window (struct Window *) - Parent window of requester. If no
1202 * AHIR_Screen tag is specified, the window structure is used to
1203 * determine on which screen to open the requesting window.
1205 * AHIR_PubScreenName (STRPTR) - Name of a public screen to open on.
1206 * This overrides the screen used by AHIR_Window.
1208 * AHIR_Screen (struct Screen *) - Screen on which to open the
1209 * requester. This overrides the screen used by AHIR_Window or by
1210 * AHIR_PubScreenName.
1212 * AHIR_PrivateIDCMP (BOOL) - When set to TRUE, this tells AHI to
1213 * allocate a new IDCMP port for the requesting window. If not
1214 * specified or set to FALSE, and if AHIR_Window is provided, the
1215 * requesting window will share AHIR_Window's IDCMP port.
1217 * AHIR_IntuiMsgFunc (struct Hook *) - A function to call whenever an
1218 * unknown Intuition message arrives at the message port being used
1219 * by the requesting window. The function receives the following
1221 * A0 - (struct Hook *)
1222 * A1 - (struct IntuiMessage *)
1223 * A2 - (struct AHIAudioModeRequester *)
1225 * AHIR_SleepWindow (BOOL) - When set to TRUE, this tag will cause the
1226 * window specified by AHIR_Window to be "put to sleep". That is, a
1227 * busy pointer will be displayed in the parent window, and no
1228 * gadget or menu activity will be allowed. This is done by opening
1229 * an invisible Intuition Requester in the parent window.
1231 * AHIR_UserData (APTR) - A 32-bit value that is simply copied in the
1232 * ahiam_UserData field of the requester structure.
1234 * AHIR_TextAttr (struct TextAttr *) - Font to be used for the
1235 * requesting window's gadgets and menus. If this tag is not
1236 * provided or its value is NULL, the default font of the screen
1237 * on which the requesting window opens will be used. This font
1238 * must already be in memory as AHI calls OpenFont() and not
1241 * AHIR_Locale (struct Locale *) - Locale to use for the requesting
1242 * window. This determines the language used for the requester's
1243 * gadgets and menus. If this tag is not provided or its value is
1244 * NULL, the system's current default locale will be used.
1246 * AHIR_TitleText (STRPTR) - Title to use for the requesting window.
1247 * Default is no title.
1249 * AHIR_PositiveText (STRPTR) - Label of the positive gadget in the
1250 * requester. English default is "OK".
1252 * AHIR_NegativeText (STRPTR) - Label of the negative gadget in the
1253 * requester. English default is "Cancel".
1255 * AHIR_InitialLeftEdge (WORD) - Suggested left edge of requesting
1258 * AHIR_InitialTopEdge (WORD) - Suggested top edge of requesting
1261 * AHIR_InitialWidth (WORD) - Suggested width of requesting window.
1263 * AHIR_InitialHeight (WORD) - Suggested height of requesting window.
1265 * AHIR_InitialAudioID (ULONG) - Initial setting of the Mode list view
1266 * gadget (ahiam_AudioID). Default is ~0 (AHI_INVALID_ID), which
1267 * means that no mode will be selected.
1269 * AHIR_InitialMixFreq (ULONG) - Initial setting of the frequency
1270 * slider. Default is the lowest frequency supported.
1272 * AHIR_InitialInfoOpened (BOOL) - Whether to open the property
1273 * information window automatically. Default is FALSE.
1275 * AHIR_InitialInfoLeftEdge (WORD) - Initial left edge of information
1278 * AHIR_InitialInfoTopEdge (WORD) - Initial top edge of information
1281 * AHIR_DoMixFreq (BOOL) - Set this tag to TRUE to cause the requester
1282 * to display the frequency slider gadget. Default is FALSE.
1284 * AHIR_DoDefaultMode (BOOL) - Set this tag to TRUE to let the user
1285 * select the mode she has set in the preferences program. If she
1286 * selects this mode, ahiam_AudioID will be AHI_DEFAULT_ID and
1287 * ahiam_MixFreq will be AHI_DEFAULT_FREQ. Note that if you filter
1288 * the mode list (see below), you must also check the mode (with
1289 * AHI_BestAudioIDA()) before you use it since the user may change
1290 * the meaning of AHI_DEFAULT_MODE anytime, without your knowledge.
1291 * Default is FALSE. (V4)
1293 * AHIR_FilterFunc (struct Hook *) - A function to call for each mode
1294 * encountered. If the function returns TRUE, the mode is included
1295 * in the file list, otherwise it is rejected and not displayed. The
1296 * function receives the following parameters:
1297 * A0 - (struct Hook *)
1298 * A1 - (ULONG) mode id
1299 * A2 - (struct AHIAudioModeRequester *)
1301 * AHIR_FilterTags (struct TagItem *) - A pointer to a tag list used to
1302 * filter modes away, like AHIR_FilterFunc does. The tags are the
1303 * same as AHI_BestAudioIDA() takes as arguments. See that function
1304 * for an explanation of each tag.
1307 * result - FALSE if the user cancelled the requester or if something
1308 * prevented the requester from opening. If TRUE, values in the
1309 * requester structure will be set.
1311 * If the return value is FALSE, you can look at the result from the
1312 * dos.library/IoErr() function to determine whether the requester
1313 * was cancelled or simply failed to open. If dos.library/IoErr()
1314 * returns 0, then the requester was cancelled, any other value
1315 * indicates a failure to open. Current possible failure codes are
1316 * ERROR_NO_FREE_STORE which indicates there was not enough memory,
1317 * and ERROR_NO_MORE_ENTRIES which indicates no modes were available
1318 * (usually because the application filter hook filtered them all
1324 * The requester data structure is READ-ONLY and can only be modified
1327 * The mixing/recording frequencies that are presented to the user
1328 * may not be the only ones a driver supports, but just a selection.
1333 * AHI_AllocAudioRequestA(), AHI_FreeAudioRequest()
1335 ****************************************************************************
1340 _AHI_AudioRequestA( struct AHIAudioModeRequester
* req_in
,
1341 struct TagItem
* tags
,
1342 struct AHIBase
* AHIBase
)
1344 struct AHIAudioModeRequesterExt
*req
=(struct AHIAudioModeRequesterExt
*)req_in
;
1345 struct MinList list
;
1346 struct IDnode
*node
= NULL
, *node2
= NULL
;
1347 struct Screen
*pub_screen
= NULL
;
1348 struct Screen
*screen
= NULL
;
1349 ULONG id
=AHI_INVALID_ID
;
1351 struct Requester lockreq
;
1352 BOOL locksuxs
= FALSE
;
1355 if(AHIBase
->ahib_DebugLevel
>= AHI_DEBUG_LOW
)
1357 Debug_AudioRequestA(req_in
,tags
);
1364 SetIoErr( ERROR_REQUIRED_ARG_MISSING
);
1368 // Update requester structure
1369 FillReqStruct(req
,tags
);
1370 req
->tempAudioID
=req
->Req
.ahiam_AudioID
;
1371 req
->tempFrequency
=req
->Req
.ahiam_MixFreq
;
1375 req
->Catalog
= ExtOpenCatalog(req
->Locale
, NULL
);
1377 if(req
->PositiveText
== NULL
)
1378 req
->PositiveText
= GetString(msgReqOK
, req
->Catalog
);
1379 if(req
->NegativeText
== NULL
)
1380 req
->NegativeText
= GetString(msgReqCancel
, req
->Catalog
);
1383 // Scan audio database for modes and create list
1385 NewList((struct List
*)req
->list
);
1386 while(AHI_INVALID_ID
!= (id
=AHI_NextAudioID(id
)))
1390 if(!TestAudioID(id
,req
->FilterTags
))
1393 if(!CallHookPkt(req
->FilterFunc
,req
,(APTR
)id
))
1396 if((node
=AllocVec(sizeof(struct IDnode
),MEMF_ANY
)))
1398 node
->node
.ln_Type
=NT_USER
;
1399 node
->node
.ln_Pri
=0;
1400 node
->node
.ln_Name
=node
->name
;
1402 #ifndef __AMIGAOS4__
1403 Sprintf(node
->node
.ln_Name
, GetString(msgUnknown
, req
->Catalog
),id
);
1405 AHI_GetAudioAttrs(id
, NULL
,
1407 AHIDB_Name
, (IPTR
)node
->node
.ln_Name
,
1409 // Insert node alphabetically
1410 for(node2
=(struct IDnode
*)req
->list
->mlh_Head
;node2
->node
.ln_Succ
;node2
=(struct IDnode
*) node2
->node
.ln_Succ
)
1411 if(Stricmp(node
->node
.ln_Name
,node2
->node
.ln_Name
) < 0)
1413 Insert((struct List
*) req
->list
,(struct Node
*)node
,node2
->node
.ln_Pred
);
1417 // Add the users preferred mode
1419 if((req
->Flags
& defaultmode
) && (AHIBase
->ahib_AudioMode
!= AHI_INVALID_ID
)) do
1422 if(!TestAudioID(AHIBase
->ahib_AudioMode
,req
->FilterTags
))
1425 if(!CallHookPkt(req
->FilterFunc
,req
,(APTR
)AHIBase
->ahib_AudioMode
))
1428 if((node
=AllocVec(sizeof(struct IDnode
),MEMF_ANY
)))
1430 node
->node
.ln_Type
=NT_USER
;
1431 node
->node
.ln_Pri
=0;
1432 node
->node
.ln_Name
=node
->name
;
1433 node
->ID
= AHI_DEFAULT_ID
;
1434 Sprintf(node
->node
.ln_Name
, GetString(msgDefaultMode
, req
->Catalog
));
1435 AddTail((struct List
*) req
->list
, (struct Node
*)node
);
1439 if(NULL
== ((struct IDnode
*)req
->list
->mlh_Head
)->node
.ln_Succ
)
1441 // List is empty, no audio modes!
1442 // Return immediately (no nodes to free)
1443 SetIoErr(ERROR_NO_MORE_ENTRIES
);
1444 ExtCloseCatalog(req
->Catalog
);
1445 req
->Catalog
= FALSE
;
1453 screen
= req
->Screen
;
1455 else if(req
->PubScreenName
!= (STRPTR
) -1)
1457 pub_screen
= LockPubScreen( req
->PubScreenName
);
1458 screen
= pub_screen
;
1460 else if(req
->SrcWindow
)
1463 screen
= req
->SrcWindow
->WScreen
;
1466 if( screen
== NULL
)
1468 pub_screen
= LockPubScreen( NULL
);
1469 screen
= pub_screen
;
1472 CalculateWindowSizePos( req
, screen
);
1474 // Clear ownIDCMP flag
1475 req
->Flags
&= ~ownIDCMP
;
1477 if( req
->SrcWindow
!= NULL
)
1479 if(req
->Flags
& haveIDCMP
)
1480 req
->Flags
|= ownIDCMP
;
1483 zipcoords
[0]=req
->Req
.ahiam_LeftEdge
;
1484 zipcoords
[1]=req
->Req
.ahiam_TopEdge
;
1488 req
->Window
=OpenWindowTags(
1490 WA_Left
,req
->Req
.ahiam_LeftEdge
,
1491 WA_Top
,req
->Req
.ahiam_TopEdge
,
1492 WA_Width
,req
->Req
.ahiam_Width
,
1493 WA_Height
,req
->Req
.ahiam_Height
,
1497 WA_Title
, req
->TitleText
,
1498 ( pub_screen
!= NULL
? WA_PubScreen
: WA_CustomScreen
), screen
,
1499 WA_PubScreenFallBack
,TRUE
,
1501 WA_SizeBBottom
,TRUE
,
1503 WA_DepthGadget
,TRUE
,
1504 WA_CloseGadget
,TRUE
,
1506 WA_SimpleRefresh
,TRUE
,
1508 WA_IDCMP
,(req
->Flags
& ownIDCMP
? 0 : MY_IDCMPS
),
1509 WA_NewLookMenus
, TRUE
,
1512 if( pub_screen
!= NULL
)
1514 UnlockPubScreen( NULL
, pub_screen
);
1519 // Topaz80: "Frequency"+INTERWIDTH+MINSLIDERWIDTH+INTERWIDTH+"99999 Hz" gives...
1520 WORD min_width
= (req
->Window
->BorderLeft
+4)+
1521 strlen( GetString(msgReqFrequency
, req
->Catalog
))*8+
1522 INTERWIDTH
+MINSLIDERWIDTH
+INTERWIDTH
+
1524 (req
->Window
->BorderRight
+4);
1526 // Topaz80: 5 lines, freq & buttons gives...
1527 WORD min_height
= (req
->Window
->BorderTop
+2)+
1528 (5*8+6)+2+(8+6)+2+(8+6)+
1529 (req
->Window
->BorderBottom
+2);
1531 if( req
->Window
->Width
< min_width
||
1532 req
->Window
->Height
< min_height
)
1534 ChangeWindowBox( req
->Window
,
1535 req
->Window
->LeftEdge
,
1536 req
->Window
->TopEdge
,
1537 max( req
->Window
->Width
, min_width
),
1538 max( req
->Window
->Height
, min_height
) );
1542 WindowLimits( req
->Window
, min_width
, min_height
, 0, 0 );
1544 if((req
->vi
=GetVisualInfoA(req
->Window
->WScreen
, NULL
)))
1546 if(!(LayOutReq(req
,req
->TextAttr
)))
1547 if(!(LayOutReq(req
,&Topaz80
)))
1550 if(rc
) // Layout OK?
1552 struct NewMenu reqnewmenu
[] =
1554 { NM_TITLE
, NULL
, 0 ,0,0,(APTR
) 0, },
1555 { NM_ITEM
, NULL
, 0 ,0,0,(APTR
) LASTMODEITEM
, },
1556 { NM_ITEM
, NULL
, 0 ,0,0,(APTR
) NEXTMODEITEM
, },
1557 { NM_ITEM
, NM_BARLABEL
, 0 ,0,0,(APTR
) 0, },
1558 { NM_ITEM
, NULL
, 0 ,0,0,(APTR
) PROPERTYITEM
, },
1559 { NM_ITEM
, NULL
, 0 ,0,0,(APTR
) RESTOREITEM
, },
1560 { NM_ITEM
, NM_BARLABEL
, 0 ,0,0,(APTR
) 0, },
1561 { NM_ITEM
, NULL
, 0 ,0,0,(APTR
) OKITEM
, },
1562 { NM_ITEM
, NULL
, 0 ,0,0,(APTR
) CANCELITEM
, },
1563 { NM_END
, NULL
, 0 ,0,0,(APTR
) 0, },
1565 static const APTR strings
[] =
1570 msgMenuPropertyList
,
1576 struct NewMenu
*menuptr
;
1579 menuptr
= (struct NewMenu
*) &reqnewmenu
;
1580 stringptr
= (APTR
*) &strings
;
1582 while(menuptr
->nm_Type
!= NM_END
)
1584 if(menuptr
->nm_Label
== NULL
)
1586 menuptr
->nm_CommKey
= GetString(*stringptr
, req
->Catalog
);
1587 menuptr
->nm_Label
= menuptr
->nm_CommKey
+ 2;
1593 if(req
->Flags
& ownIDCMP
)
1595 req
->Window
->UserPort
=req
->SrcWindow
->UserPort
;
1596 ModifyIDCMP(req
->Window
,MY_IDCMPS
);
1599 if((req
->Flags
& lockwin
) && req
->SrcWindow
)
1601 InitRequester(&lockreq
);
1602 locksuxs
=Request(&lockreq
,req
->SrcWindow
);
1603 if(IntuitionBase
->LibNode
.lib_Version
>= 39)
1604 SetWindowPointer(req
->SrcWindow
,
1605 WA_BusyPointer
,TRUE
,
1610 if((req
->Menu
=CreateMenus(reqnewmenu
,
1611 GTMN_FullMenu
, TRUE
,
1612 GTMN_NewLookMenus
, TRUE
,
1615 if(LayoutMenus(req
->Menu
,req
->vi
, TAG_DONE
))
1617 if(SetMenuStrip(req
->Window
, req
->Menu
))
1619 if(req
->Req
.ahiam_InfoOpened
)
1621 OpenInfoWindow(req
);
1626 CloseInfoWindow(req
);
1627 ClearMenuStrip(req
->Window
);
1629 } // else LayoutMenus failed
1630 FreeMenus(req
->Menu
);
1632 } // else CreateMenus failed
1635 if((req
->Flags
& lockwin
) && req
->SrcWindow
)
1638 EndRequest(&lockreq
,req
->SrcWindow
);
1639 if(IntuitionBase
->LibNode
.lib_Version
>= 39)
1640 SetWindowPointer(req
->SrcWindow
,
1641 WA_BusyPointer
,FALSE
,
1645 req
->Req
.ahiam_LeftEdge
= req
->Window
->LeftEdge
;
1646 req
->Req
.ahiam_TopEdge
= req
->Window
->TopEdge
;
1647 req
->Req
.ahiam_Width
= req
->Window
->Width
;
1648 req
->Req
.ahiam_Height
= req
->Window
->Height
;
1649 } // else LayOutReq failed
1653 SetIoErr(ERROR_NO_FREE_STORE
);
1657 if(req
->Flags
& ownIDCMP
)
1658 CloseWindowSafely(req
->Window
);
1660 CloseWindow(req
->Window
);
1662 FreeVisualInfo(req
->vi
);
1664 FreeGadgets(req
->Gadgets
);
1670 SetIoErr(ERROR_NO_FREE_STORE
);
1674 ExtCloseCatalog(req
->Catalog
);
1675 req
->Catalog
= NULL
;
1676 req
->PositiveText
= req
->NegativeText
= NULL
;
1678 if(AHIBase
->ahib_DebugLevel
>= AHI_DEBUG_LOW
)
1680 KPrintF("=>%s\n", (IPTR
)(rc
? "TRUE" : "FALSE"));
1686 /******************************************************************************
1687 ** AHI_FreeAudioRequest *******************************************************
1688 ******************************************************************************/
1690 /****** ahi.device/AHI_FreeAudioRequest *************************************
1693 * AHI_FreeAudioRequest -- frees requester resources
1696 * AHI_FreeAudioRequest( requester );
1699 * void AHI_FreeAudioRequest( struct AHIAudioModeRequester * );
1702 * Frees any resources allocated by AHI_AllocAudioRequestA(). Once a
1703 * requester has been freed, it can no longer be used with other calls to
1704 * AHI_AudioRequestA().
1707 * requester - Requester obtained from AHI_AllocAudioRequestA(), or NULL
1708 * in which case this function does nothing.
1719 * AHI_AllocAudioRequestA()
1721 ****************************************************************************
1726 _AHI_FreeAudioRequest( struct AHIAudioModeRequester
* req
,
1727 struct AHIBase
* AHIBase
)
1730 if(AHIBase
->ahib_DebugLevel
>= AHI_DEBUG_LOW
)
1732 Debug_FreeAudioRequest(req
);