2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
9 /*****************************************************************************************/
11 #include <proto/exec.h>
12 #include <proto/dos.h>
13 #include <proto/intuition.h>
14 #include <proto/graphics.h>
15 #include <proto/utility.h>
16 #include <proto/diskfont.h>
17 #include <exec/memory.h>
18 #include <exec/initializers.h>
19 #include <intuition/imageclass.h>
25 #include <clib/macros.h>
27 #include "asl_intern.h"
28 #include "fontreqsupport.h"
29 #include "fontreqhooks.h"
36 #include <aros/debug.h>
38 /*****************************************************************************************/
40 static WORD
FOCompareFontNodes(struct IntFontReq
*iforeq
, struct Node
*node1
,
41 struct Node
*node2
, struct AslBase_intern
*AslBase
)
43 return Stricmp(node1
->ln_Name
, node2
->ln_Name
);
46 /*****************************************************************************************/
48 static WORD
FOCompareSizeNodes(struct IntFontReq
*iforeq
, struct Node
*node1
,
49 struct Node
*node2
, struct AslBase_intern
*AslBase
)
51 return ((LONG
)node1
->ln_Name
) - ((LONG
)node2
->ln_Name
);
54 /*****************************************************************************************/
56 static int AVFCompare(struct AvailFonts
*one
, struct AvailFonts
*two
)
58 int retval
= strcmp(one
->af_Attr
.ta_Name
, two
->af_Attr
.ta_Name
);
60 if (!retval
) retval
= ((int)one
->af_Attr
.ta_YSize
) -
61 ((int)two
->af_Attr
.ta_YSize
);
66 /*****************************************************************************************/
68 static void SortAvailFonts(struct AvailFontsHeader
*afh
, struct AslBase_intern
*AslBase
)
70 struct AvailFonts
*avf
;
73 avf
= (struct AvailFonts
*)&afh
[1];
74 numentries
= afh
->afh_NumEntries
;
75 if (numentries
< 2) return;
80 (int (*)(const void *, const void *))AVFCompare
);
83 /*****************************************************************************************/
85 LONG
FOGetFonts(struct LayoutData
*ld
, struct AslBase_intern
*AslBase
)
87 struct FOUserData
*udata
= (struct FOUserData
*)ld
->ld_UserData
;
88 struct IntFontReq
*iforeq
= (struct IntFontReq
*)ld
->ld_IntReq
;
89 struct AvailFonts
*avf
;
90 ULONG afshortage
, afsize
= 100;
93 FOFreeFonts(ld
, AslBase
);
97 udata
->AFH
= (struct AvailFontsHeader
*)AllocVec(afsize
, MEMF_ANY
);
100 afshortage
= AvailFonts((STRPTR
)udata
->AFH
, afsize
, AFF_MEMORY
| AFF_DISK
);
105 afsize
+= afshortage
;
109 } while (udata
->AFH
&& afshortage
);
111 if (!udata
->AFH
) return ERROR_NO_FREE_STORE
;
113 SortAvailFonts(udata
->AFH
, AslBase
);
115 avf
= (struct AvailFonts
*)&udata
->AFH
[1];
117 for(i
= 0; i
< udata
->AFH
->afh_NumEntries
;)
119 struct AvailFonts
*avf_start
= avf
;
120 struct ASLLVFontReqNode
*fontnode
;
124 while (i2
< udata
->AFH
->afh_NumEntries
- 1)
127 if (strcmp(avf_start
->af_Attr
.ta_Name
, avf
->af_Attr
.ta_Name
)) break;
131 i
+= num_sizes
; avf
= avf_start
+ num_sizes
;
133 if (iforeq
->ifo_Flags
& FOF_FIXEDWIDTHONLY
)
135 if (avf_start
->af_Attr
.ta_Flags
& FPF_PROPORTIONAL
) continue;
138 if (iforeq
->ifo_FilterFunc
)
144 REG_A4
= (ULONG
)iforeq
->ifo_IntReq
.ir_BasePtr
; /* Compatability */
145 REG_A0
= (ULONG
)iforeq
->ifo_FilterFunc
;
146 REG_A2
= (ULONG
)ld
->ld_Req
;
147 REG_A1
= (ULONG
)&avf_start
->af_Attr
;
148 ret
= (*MyEmulHandle
->EmulCallDirect68k
)(iforeq
->ifo_FilterFunc
->h_Entry
);
153 if (!(CallHookPkt(iforeq
->ifo_FilterFunc
, ld
->ld_Req
, &avf_start
->af_Attr
))) continue;
157 if (iforeq
->ifo_HookFunc
&& (iforeq
->ifo_Flags
& FOF_FILTERFUNC
))
162 UWORD
*funcptr
= iforeq
->ifo_HookFunc
;
163 ULONG
*p
= (ULONG
*)REG_A7
- 3;
165 p
[0] = (ULONG
)FOF_FILTERFUNC
;
166 p
[1] = (ULONG
)&avf_start
->af_Attr
;
167 p
[2] = (ULONG
)ld
->ld_Req
;
170 if (*funcptr
>= (UWORD
)0xFF00)
173 REG_A4
= (ULONG
)iforeq
->ifo_IntReq
.ir_BasePtr
; /* Compatability */
175 ret
= (ULONG
)(*MyEmulHandle
->EmulCallDirect68k
)(funcptr
);
177 if (*funcptr
>= (UWORD
)0xFF00)
185 if (!(iforeq
->ifo_HookFunc(FOF_FILTERFUNC
,
187 (struct FontRequester
*)ld
->ld_Req
))) continue;
191 fontnode
= MyAllocVecPooled(ld
->ld_IntReq
->ir_MemPool
,
192 sizeof(*fontnode
) + sizeof(struct Node
) * num_sizes
,
201 sp
= strchr(avf_start
->af_Attr
.ta_Name
, '.');
204 len
= (IPTR
)sp
- (IPTR
)avf_start
->af_Attr
.ta_Name
- 1;;
208 /* Paranoia: Should never happen */
209 len
= strlen(avf_start
->af_Attr
.ta_Name
);
212 strncpy(fontnode
->Name
, avf_start
->af_Attr
.ta_Name
, len
+ 1);
213 fontnode
->node
.ln_Name
= fontnode
->Name
;
214 fontnode
->TAttr
= avf_start
->af_Attr
;
215 fontnode
->TAttr
.ta_Name
= fontnode
->Name
;
217 fontnode
->NumSizes
= num_sizes
;
219 NEWLIST(&fontnode
->SizeList
);
221 for(i2
= 0; i2
< num_sizes
; i2
++, avf_start
++)
223 UWORD size
= avf_start
->af_Attr
.ta_YSize
;
225 if (size
== prevsize
) continue;
227 if ((size
< iforeq
->ifo_MinHeight
) ||
228 (size
> iforeq
->ifo_MaxHeight
)) continue;
230 fontnode
->SizeNode
[i2
].ln_Name
= (char *)(IPTR
)size
;
231 SortInNode(iforeq
, &fontnode
->SizeList
, &fontnode
->SizeNode
[i2
], (APTR
)FOCompareSizeNodes
, AslBase
);
236 SortInNode(iforeq
, &udata
->NameListviewList
, &fontnode
->node
, (APTR
)FOCompareFontNodes
, AslBase
);
240 } /* for(i = 0; i < udata->AFH->afh_NumEntries; ) */
242 if (udata
->NameListview
)
244 struct TagItem set_tags
[] =
246 {ASLLV_Labels
, (IPTR
)&udata
->NameListviewList
},
252 SetGadgetAttrsA((struct Gadget
*)udata
->NameListview
, ld
->ld_Window
, NULL
, set_tags
);
254 GetAttr(STRINGA_TextVal
, udata
->NameString
, (IPTR
*)&fontname
);
255 GetAttr(STRINGA_LongVal
, udata
->SizeString
, (IPTR
*)&fontsize
);
257 FORestore(ld
, fontname
, fontsize
, AslBase
);
261 return IsListEmpty(&udata
->NameListviewList
) ? ERROR_NO_MORE_ENTRIES
: 0;
265 /*****************************************************************************************/
267 void FOFreeFonts(struct LayoutData
*ld
, struct AslBase_intern
*AslBase
)
269 struct FOUserData
*udata
= (struct FOUserData
*)ld
->ld_UserData
;
270 struct ASLVFontReqNode
*node
, *succ
;
271 struct TagItem set_tags
[] =
277 udata
->ActiveFont
= NULL
;
279 if (udata
->NameListview
) SetGadgetAttrsA((struct Gadget
*)udata
->NameListview
, ld
->ld_Window
, NULL
, set_tags
);
280 if (udata
->SizeListview
) SetGadgetAttrsA((struct Gadget
*)udata
->SizeListview
, ld
->ld_Window
, NULL
, set_tags
);
282 ForeachNodeSafe(&udata
->NameListviewList
, node
, succ
)
284 MyFreeVecPooled(node
, AslBase
);
287 NEWLIST(&udata
->NameListviewList
);
296 /*****************************************************************************************/
298 VOID
FOUpdatePreview(struct LayoutData
*ld
, struct AslBase_intern
*AslBase
)
300 struct FOUserData
*udata
= (struct FOUserData
*)ld
->ld_UserData
;
301 struct IntReq
*intreq
= ld
->ld_IntReq
;
302 struct IntFontReq
*iforeq
= (struct IntFontReq
*)ld
->ld_IntReq
;
304 struct TextFont
*font
;
308 GetAttr(STRINGA_LongVal
, udata
->SizeString
, &val
);
309 ta
.ta_YSize
= (WORD
)val
;
313 GetAttr(STRINGA_TextVal
, udata
->NameString
, (IPTR
*)&name
);
314 if ((name
= VecPooledCloneString(name
, ".font", intreq
->ir_MemPool
, AslBase
)))
316 UBYTE style
= FS_NORMAL
;
317 UBYTE apen
= iforeq
->ifo_FrontPen
;
318 UBYTE bpen
= iforeq
->ifo_BackPen
;
322 if (iforeq
->ifo_Flags
& FOF_DOSTYLE
)
324 style
= FOGetStyle(ld
, AslBase
);
327 if (iforeq
->ifo_Flags
& FOF_DOFRONTPEN
)
329 apen
= FOGetFGColor(ld
, AslBase
);
332 if (iforeq
->ifo_Flags
& FOF_DOBACKPEN
)
334 bpen
= FOGetBGColor(ld
, AslBase
);
337 font
= OpenDiskFont(&ta
);
339 struct TagItem settags
[] =
341 {ASLFP_Font
, (IPTR
)font
},
342 {ASLFP_Style
, style
},
343 {ASLFP_APen
, apen
},
344 {ASLFP_BPen
, bpen
},
348 SetGadgetAttrsA((struct Gadget
*)udata
->Preview
, ld
->ld_Window
, NULL
, settags
);
351 if (udata
->PreviewFont
) CloseFont(udata
->PreviewFont
);
352 udata
->PreviewFont
= font
;
354 MyFreeVecPooled(name
, AslBase
);
358 /*****************************************************************************************/
360 struct ASLLVFontReqNode
*FOGetActiveFont(struct LayoutData
*ld
, struct AslBase_intern
*AslBase
)
362 struct FOUserData
*udata
= (struct FOUserData
*)ld
->ld_UserData
;
365 GetAttr(ASLLV_Active
, udata
->NameListview
, &active
);
367 return (struct ASLLVFontReqNode
*)FindListNode(&udata
->NameListviewList
, active
);
370 /*****************************************************************************************/
372 void FOChangeActiveFont(struct LayoutData
*ld
, WORD delta
, UWORD quali
, BOOL jump
, struct AslBase_intern
*AslBase
)
374 struct FOUserData
*udata
= (struct FOUserData
*)ld
->ld_UserData
;
375 IPTR active
, total
, visible
, size
;
377 GetAttr(ASLLV_Active
, udata
->NameListview
, &active
);
378 GetAttr(ASLLV_Total
, udata
->NameListview
, &total
);
379 GetAttr(ASLLV_Visible
, udata
->NameListview
, &visible
);
380 GetAttr(STRINGA_LongVal
, udata
->SizeString
, &size
);
384 if (quali
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
))
386 delta
*= (visible
- 1);
388 else if (quali
& (IEQUALIFIER_LALT
| IEQUALIFIER_RALT
| IEQUALIFIER_CONTROL
))
394 /* try to jump to first item which matches text in name string gadget,
395 but only if text in string gadget mismatches actual active
396 item's text (in this case move normally = one step)) */
398 struct ASLLVFontReqNode
*node
;
399 UBYTE buffer
[MAXFONTNAME
+ 2];
404 GetAttr(STRINGA_TextVal
, udata
->NameString
, (IPTR
*)&val
);
407 len
= strlen(buffer
);
411 if (((LONG
)active
) >= 0)
413 if ((node
= (struct ASLLVFontReqNode
*)FindListNode(&udata
->NameListviewList
, (WORD
)active
)))
415 if (stricmp(node
->node
.ln_Name
, buffer
) == 0) dojump
= FALSE
;
422 ForeachNode(&udata
->NameListviewList
, node
)
424 if (Strnicmp((CONST_STRPTR
)node
->node
.ln_Name
, (CONST_STRPTR
)buffer
, len
) == 0)
440 if (((LONG
)active
) < 0) active
= 0;
441 if (active
>= total
) active
= total
- 1;
443 FOActivateFont(ld
, active
, (LONG
)size
, AslBase
);
447 /*****************************************************************************************/
449 void FOChangeActiveSize(struct LayoutData
*ld
, WORD delta
, UWORD quali
, struct AslBase_intern
*AslBase
)
451 struct FOUserData
*udata
= (struct FOUserData
*)ld
->ld_UserData
;
452 IPTR active
, total
, visible
;
454 GetAttr(ASLLV_Active
, udata
->SizeListview
, &active
);
455 GetAttr(ASLLV_Total
, udata
->SizeListview
, &total
);
456 GetAttr(ASLLV_Visible
, udata
->SizeListview
, &visible
);
460 if (quali
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
))
462 delta
*= (visible
- 1);
464 else if (quali
& (IEQUALIFIER_LALT
| IEQUALIFIER_RALT
| IEQUALIFIER_CONTROL
))
471 if (((LONG
)active
) < 0) active
= 0;
472 if (active
>= total
) active
= total
- 1;
474 FOActivateSize(ld
, active
, AslBase
);
478 /*****************************************************************************************/
480 void FOActivateFont(struct LayoutData
*ld
, WORD which
, LONG size
, struct AslBase_intern
*AslBase
)
482 struct FOUserData
*udata
= (struct FOUserData
*)ld
->ld_UserData
;
483 // struct IntFontReq *iforeq = (struct IntFontReq *)ld->ld_IntReq;
484 struct ASLLVFontReqNode
*fontnode
;
486 struct TagItem name_tags
[] =
489 {ASLLV_MakeVisible
, 0 },
492 struct TagItem size_tags
[] =
495 {ASLLV_Active
, (IPTR
)-1 },
496 {ASLLV_MakeVisible
, 0 },
499 WORD sizelvindex
= 0;
501 fontnode
= (struct ASLLVFontReqNode
*)FindListNode(&udata
->NameListviewList
, which
);
502 udata
->ActiveFont
= fontnode
;
506 SetGadgetAttrsA((struct Gadget
*)udata
->SizeListview
, ld
->ld_Window
, NULL
, size_tags
);
508 name_tags
[0].ti_Data
= (IPTR
)-1;
509 name_tags
[1].ti_Tag
= TAG_IGNORE
;
510 SetGadgetAttrsA((struct Gadget
*)udata
->NameListview
, ld
->ld_Window
, NULL
, name_tags
);
514 name_tags
[0].ti_Data
= name_tags
[1].ti_Data
= which
;
515 SetGadgetAttrsA((struct Gadget
*)udata
->NameListview
, ld
->ld_Window
, NULL
, name_tags
);
517 size_tags
[0].ti_Data
= (IPTR
)&fontnode
->SizeList
;
518 ForeachNode(&fontnode
->SizeList
, node
)
520 MARK_UNSELECTED(node
);
521 if ((LONG
)node
->ln_Name
== size
)
523 size_tags
[1].ti_Data
= size_tags
[2].ti_Data
= sizelvindex
;
527 SetGadgetAttrsA((struct Gadget
*)udata
->SizeListview
, ld
->ld_Window
, NULL
, size_tags
);
529 FOSetFontString(fontnode
->node
.ln_Name
, ld
, AslBase
);
532 FOUpdatePreview(ld
, AslBase
);
535 /*****************************************************************************************/
537 void FOActivateSize(struct LayoutData
*ld
, WORD which
, struct AslBase_intern
*AslBase
)
539 struct FOUserData
*udata
= (struct FOUserData
*)ld
->ld_UserData
;
540 // struct IntFontReq *iforeq = (struct IntFontReq *)ld->ld_IntReq;
542 struct TagItem size_tags
[] =
545 {ASLLV_MakeVisible
, 0 },
549 if (!udata
->ActiveFont
) return;
553 node
= FindListNode(&udata
->ActiveFont
->SizeList
, which
);
561 ForeachNode(&udata
->ActiveFont
->SizeList
, node
)
563 if ((LONG
)node
->ln_Name
== size
)
571 if (!found
) node
= NULL
;
574 size_tags
[0].ti_Data
= node
? which
: -1;
575 size_tags
[1].ti_Data
= node
? which
: 0;
577 SetGadgetAttrsA((struct Gadget
*)udata
->SizeListview
, ld
->ld_Window
, NULL
, size_tags
);
579 if (node
) FOSetSizeString((LONG
)node
->ln_Name
, ld
, AslBase
);
581 FOUpdatePreview(ld
, AslBase
);
584 /*****************************************************************************************/
586 void FORestore(struct LayoutData
*ld
, STRPTR fontname
, LONG fontsize
, struct AslBase_intern
*AslBase
)
588 struct FOUserData
*udata
= (struct FOUserData
*)ld
->ld_UserData
;
589 struct IntFontReq
*iforeq
= (struct IntFontReq
*)ld
->ld_IntReq
;
590 struct ASLLVFontReqNode
*fontnode
;
591 struct TagItem set_tags
[] =
596 UBYTE initialfontname
[MAXFONTNAME
+ 2];
600 strncpy(initialfontname
, fontname
, MAXFONTNAME
+ 1);
601 if ((sp
= strchr(initialfontname
, '.'))) *sp
= '\0';
603 FOSetSizeString(fontsize
, ld
, AslBase
);
605 SetGadgetAttrsA((struct Gadget
*)udata
->SizeListview
, ld
->ld_Window
, NULL
, set_tags
);
607 ForeachNode(&udata
->NameListviewList
, fontnode
)
609 if (stricmp(fontnode
->node
.ln_Name
, initialfontname
) == 0) break;
613 if (iforeq
->ifo_Flags
& FOF_DODRAWMODE
)
615 FOSetDrawMode(ld
, iforeq
->ifo_DrawMode
, AslBase
);
618 if (iforeq
->ifo_Flags
& FOF_DOSTYLE
)
620 FOSetStyle(ld
, iforeq
->ifo_TextAttr
.ta_Style
, AslBase
);
623 if (iforeq
->ifo_Flags
& FOF_DOFRONTPEN
)
625 FOSetFGColor(ld
, iforeq
->ifo_FrontPen
, AslBase
);
628 if (iforeq
->ifo_Flags
& FOF_DOBACKPEN
)
630 FOSetBGColor(ld
, iforeq
->ifo_BackPen
, AslBase
);
633 FOActivateFont(ld
, i
, fontsize
, AslBase
);
636 /*****************************************************************************************/
638 void FOSetFontString(STRPTR name
, struct LayoutData
*ld
, struct AslBase_intern
*AslBase
)
640 struct FOUserData
*udata
= (struct FOUserData
*)ld
->ld_UserData
;
641 struct TagItem set_tags
[] =
643 {STRINGA_TextVal
, (IPTR
)name
},
647 SetGadgetAttrsA((struct Gadget
*)udata
->NameString
, ld
->ld_Window
, NULL
, set_tags
);
650 /*****************************************************************************************/
652 void FOSetSizeString(LONG size
, struct LayoutData
*ld
, struct AslBase_intern
*AslBase
)
654 struct FOUserData
*udata
= (struct FOUserData
*)ld
->ld_UserData
;
655 struct TagItem set_tags
[] =
657 {STRINGA_LongVal
, (IPTR
)size
},
661 SetGadgetAttrsA((struct Gadget
*)udata
->SizeString
, ld
->ld_Window
, NULL
, set_tags
);
664 /*****************************************************************************************/
666 LONG
FOGetDrawMode(struct LayoutData
*ld
, struct AslBase_intern
*AslBase
)
668 struct FOUserData
*udata
= (struct FOUserData
*)ld
->ld_UserData
;
671 ASSERT(udata
->DrawModeGadget
);
673 GetAttr(ASLCY_Active
, udata
->DrawModeGadget
, &active
);
678 /*****************************************************************************************/
680 void FOSetDrawMode(struct LayoutData
*ld
, UWORD id
, struct AslBase_intern
*AslBase
)
682 struct FOUserData
*udata
= (struct FOUserData
*)ld
->ld_UserData
;
683 struct TagItem set_tags
[] =
685 {ASLCY_Active
, id
},
689 ASSERT(udata
->DrawModeGadget
);
691 SetGadgetAttrsA((struct Gadget
*)udata
->DrawModeGadget
, ld
->ld_Window
, NULL
, set_tags
);
695 /*****************************************************************************************/
697 UBYTE
FOGetStyle(struct LayoutData
*ld
, struct AslBase_intern
*AslBase
)
699 struct FOUserData
*udata
= (struct FOUserData
*)ld
->ld_UserData
;
702 ASSERT(udata
->StyleGadget
);
704 GetAttr(ASLFS_Style
, udata
->StyleGadget
, &style
);
709 /*****************************************************************************************/
711 void FOSetStyle(struct LayoutData
*ld
, UBYTE style
, struct AslBase_intern
*AslBase
)
713 struct FOUserData
*udata
= (struct FOUserData
*)ld
->ld_UserData
;
714 struct TagItem set_tags
[] =
716 {ASLFS_Style
, style
},
720 ASSERT(udata
->StyleGadget
);
722 SetGadgetAttrsA((struct Gadget
*)udata
->StyleGadget
, ld
->ld_Window
, NULL
, set_tags
);
726 /*****************************************************************************************/
728 UBYTE
FOGetFGColor(struct LayoutData
*ld
, struct AslBase_intern
*AslBase
)
730 struct FOUserData
*udata
= (struct FOUserData
*)ld
->ld_UserData
;
733 ASSERT(udata
->FGColorGadget
);
735 GetAttr(ASLCP_Color
, udata
->FGColorGadget
, &color
);
740 /*****************************************************************************************/
742 void FOSetFGColor(struct LayoutData
*ld
, UBYTE color
, struct AslBase_intern
*AslBase
)
744 struct FOUserData
*udata
= (struct FOUserData
*)ld
->ld_UserData
;
745 struct TagItem set_tags
[] =
747 {ASLCP_Color
, color
},
751 ASSERT(udata
->FGColorGadget
);
753 SetGadgetAttrsA((struct Gadget
*)udata
->FGColorGadget
, ld
->ld_Window
, NULL
, set_tags
);
757 /*****************************************************************************************/
759 UBYTE
FOGetBGColor(struct LayoutData
*ld
, struct AslBase_intern
*AslBase
)
761 struct FOUserData
*udata
= (struct FOUserData
*)ld
->ld_UserData
;
764 ASSERT(udata
->BGColorGadget
);
766 GetAttr(ASLCP_Color
, udata
->BGColorGadget
, &color
);
771 /*****************************************************************************************/
773 void FOSetBGColor(struct LayoutData
*ld
, UBYTE color
, struct AslBase_intern
*AslBase
)
775 struct FOUserData
*udata
= (struct FOUserData
*)ld
->ld_UserData
;
776 struct TagItem set_tags
[] =
778 {ASLCP_Color
, color
},
782 ASSERT(udata
->BGColorGadget
);
784 SetGadgetAttrsA((struct Gadget
*)udata
->BGColorGadget
, ld
->ld_Window
, NULL
, set_tags
);
788 /*****************************************************************************************/