1 #include <aros/debug.h>
2 #include <proto/alib.h>
3 #include <exec/types.h>
4 #include <exec/lists.h>
5 #include <aros/asmcall.h>
6 #include <utility/hooks.h>
7 #include <libraries/mui.h>
9 #define NO_INLINE_STDARG
11 #include <proto/exec.h>
12 #include <proto/intuition.h>
13 #include <proto/muimaster.h>
14 #include <proto/dos.h>
15 #include <proto/alib.h>
20 #include "fontlist_class.h"
25 struct MinList ScanDirTasks
;
27 typedef struct FontListData FontListData
;
29 struct ScanDirTaskInfo
39 AROS_UFH3(APTR
, flConstructFunc
,
40 AROS_UFHA(struct Hook
*, hook
, A0
),
41 AROS_UFHA(APTR
, pool
, A2
),
42 AROS_UFHA(struct MUIS_FontList_Entry
*, entry
, A1
))
46 struct MUIS_FontList_Entry
*new_entry
;
47 size_t len1
= strlen(entry
->FileName
) + 1;
48 size_t len2
= strlen(entry
->FamilyName
) + 1;
49 size_t len3
= strlen(entry
->StyleName
) + 1;
51 new_entry
= AllocPooled(pool
, sizeof(*entry
) + len1
+ len2
+ len3
);
54 STRPTR p
= (STRPTR
)(new_entry
+ 1);
55 new_entry
->FileName
= p
;
56 memcpy(p
, entry
->FileName
, len1
);
58 new_entry
->FamilyName
= p
;
59 memcpy(p
, entry
->FamilyName
, len2
);
61 new_entry
->StyleName
= p
;
62 memcpy(p
, entry
->StyleName
, len3
);
71 struct Hook flConstructHook
= {{NULL
, NULL
}, UFHN(flConstructFunc
) };
73 AROS_UFH3(void, flDestructFunc
,
74 AROS_UFHA(struct Hook
*, hook
, A0
),
75 AROS_UFHA(APTR
, pool
, A2
),
76 AROS_UFHA(struct MUIS_FontList_Entry
*, entry
, A1
))
80 size_t len1
= strlen(entry
->FileName
) + 1;
81 size_t len2
= strlen(entry
->FamilyName
) + 1;
82 size_t len3
= strlen(entry
->StyleName
) + 1;
84 FreePooled(pool
, entry
, sizeof(*entry
) + len1
+ len2
+ len3
);
90 struct Hook flDestructHook
= {{NULL
, NULL
}, UFHN(flDestructFunc
) };
92 AROS_UFH3(ULONG
, flDisplayFunc
,
93 AROS_UFHA(struct Hook
*, hook
, A0
),
94 AROS_UFHA(STRPTR
*, array
, A2
),
95 AROS_UFHA(struct MUIS_FontList_Entry
*, entry
, A1
))
99 array
[0] = entry
->FamilyName
;
100 array
[1] = entry
->StyleName
;
107 struct Hook flDisplayHook
= {{NULL
, NULL
}, UFHN(flDisplayFunc
) };
109 AROS_UFH3(LONG
, flCompareFunc
,
110 AROS_UFHA(struct Hook
*, hook
, A0
),
111 AROS_UFHA(struct MUIS_FontList_Entry
*, entry2
, A2
),
112 AROS_UFHA(struct MUIS_FontList_Entry
*, entry1
, A1
))
116 LONG ret
= strcmp(entry1
->FamilyName
, entry2
->FamilyName
);
118 ret
= strcmp(entry1
->StyleName
, entry2
->StyleName
);
125 struct Hook flCompareHook
= {{NULL
, NULL
}, UFHN(flCompareFunc
) };
128 IPTR
flNew(Class
*cl
, Object
*o
, struct opSet
*msg
)
131 struct TagItem tags
[8];
133 tags
[0].ti_Tag
= MUIA_Frame
;
134 tags
[0].ti_Data
= MUIV_Frame_InputList
;
135 tags
[1].ti_Tag
= MUIA_Background
;
136 tags
[1].ti_Data
= MUII_ListBack
;
137 tags
[2].ti_Tag
= MUIA_List_ConstructHook
;
138 tags
[2].ti_Data
= (IPTR
)&flConstructHook
;
139 tags
[3].ti_Tag
= MUIA_List_DestructHook
;
140 tags
[3].ti_Data
= (IPTR
)&flDestructHook
;
141 tags
[4].ti_Tag
= MUIA_List_DisplayHook
;
142 tags
[4].ti_Data
= (IPTR
)&flDisplayHook
;
143 tags
[4].ti_Tag
= MUIA_List_DisplayHook
;
144 tags
[4].ti_Data
= (IPTR
)&flDisplayHook
;
145 tags
[5].ti_Tag
= MUIA_List_CompareHook
;
146 tags
[5].ti_Data
= (IPTR
)&flCompareHook
;
147 tags
[6].ti_Tag
= MUIA_List_Format
;
148 tags
[6].ti_Data
= (IPTR
)",";
149 tags
[7].ti_Tag
= TAG_MORE
;
150 tags
[7].ti_Data
= (IPTR
)msg
->ops_AttrList
;
152 method
.MethodID
= OM_NEW
;
153 method
.ops_AttrList
= tags
;
154 method
.ops_GInfo
= NULL
;
156 o
= (Object
*)DoSuperMethodA(cl
, o
, (Msg
)&method
);
159 FontListData
*dat
= INST_DATA(cl
, o
);
160 NewList((struct List
*) &dat
->ScanDirTasks
);
163 DEBUG_FONTWINDOW(dprintf("FontList: created object 0x%lx.\n", o
));
169 IPTR
flDispose(Class
*cl
, Object
*o
, Msg msg
)
171 FontListData
*dat
= INST_DATA(cl
, o
);
172 struct ScanDirTaskInfo
*info
;
180 for (info
= (APTR
)dat
->ScanDirTasks
.mlh_Head
; info
->Node
.mln_Succ
; info
= (APTR
)info
->Node
.mln_Succ
)
183 Signal(&info
->Proc
->pr_Task
, SIGBREAKF_CTRL_C
);
188 Wait(SIGBREAKF_CTRL_F
);
192 return DoSuperMethodA(cl
, o
, msg
);
196 struct MUIP_FontList_AddDir
198 STACKED ULONG MethodID
;
199 STACKED STRPTR DirName
;
202 struct ScanDirTaskInfo
*_pass_info
;
204 struct Task
*_pass_parent
;
207 void ScanDirTask(void)
209 struct ScanDirTaskInfo
*info
= _pass_info
;
210 Object
*app
= _pass_app
;
211 struct Task
*parent
= _pass_parent
;
212 Object
*fl
= _pass_fl
;
214 struct ExAllControl
*eac
;
215 struct ExAllData
*ead
;
218 FT_Library ftlibrary
;
220 Signal(parent
, SIGBREAKF_CTRL_F
);
222 DEBUG_ADDDIR(dprintf("flScanDirTask: dir <%s>\n", info
->DirName
));
224 if (FT_Init_FreeType(&ftlibrary
) == 0)
226 DEBUG_ADDDIR(dprintf("flScanDirTask: ftlibrary 0x%x\n", ftlibrary
));
228 lock
= Lock(info
->DirName
, ACCESS_READ
);
231 DEBUG_ADDDIR(dprintf("flScanDirTask: lock 0x%lx\n", lock
));
233 olddir
= CurrentDir(lock
);
235 eac
= AllocDosObject(DOS_EXALLCONTROL
, NULL
);
238 DEBUG_ADDDIR(dprintf("flScanDirTask: eac 0x%lx\n", eac
));
240 eac
->eac_LastKey
= 0;
244 more
= ExAll(lock
, (struct ExAllData
*) info
->Buffer
, sizeof(info
->Buffer
), ED_NAME
, eac
);
246 DEBUG_ADDDIR(dprintf("flScanDirTask: more %d entries %d\n", more
, eac
->eac_Entries
));
249 if (!more
&& IoErr() != ERROR_NO_MORE_ENTRIES
)
251 DEBUG_ADDDIR(dprintf("flScanDirTask: err %d\n", IoErr()));
255 if (eac
->eac_Entries
== 0)
258 ead
= (APTR
)info
->Buffer
;
265 DEBUG_ADDDIR(dprintf("flScanDirTask: ead 0x%x name %x <%s>\n", ead
, ead
->ed_Name
, ead
->ed_Name
));
266 error
= FT_New_Face(ftlibrary
, ead
->ed_Name
, 0, &face
);
267 DEBUG_ADDDIR(dprintf("flScanDirTask: error %d\n", error
));
270 struct MUIS_FontList_Entry
*entry
;
271 size_t len1
, len2
, len3
;
273 DEBUG_ADDDIR(dprintf("flScanDirTask: family 0x <%s> style 0x%x <%s>\n", face
->family_name
, face
->family_name
, face
->style_name
, face
->style_name
));
275 strncpy(info
->NameBuf
, info
->DirName
, sizeof(info
->NameBuf
));
276 AddPart(info
->NameBuf
, ead
->ed_Name
, sizeof(info
->NameBuf
));
278 len1
= strlen(info
->NameBuf
) + 1;
279 len2
= strlen(face
->family_name
) + 1;
280 len3
= strlen(face
->style_name
) + 1;
282 entry
= AllocVec(sizeof(*entry
) + len1
+ len2
+ len3
, MEMF_PUBLIC
);
285 char *p
= (char *)(entry
+ 1);
287 memcpy(p
, info
->NameBuf
, len1
);
289 entry
->FamilyName
= p
;
290 memcpy(p
, face
->family_name
, len2
);
292 entry
->StyleName
= p
;
293 memcpy(p
, face
->style_name
, len3
);
295 if (!DoMethod(app
, MUIM_Application_PushMethod
,
296 fl
, 2, MUIM_FontList_AddEntry
, entry
))
309 DEBUG_ADDDIR(dprintf("flScanDirTask: done\n"));
311 FreeDosObject(DOS_EXALLCONTROL
, eac
);
318 FT_Done_FreeType(ftlibrary
);
324 Signal(parent
, SIGBREAKF_CTRL_F
);
328 ULONG
flAddDir(Class
*cl
, Object
*o
, struct MUIP_FontList_AddDir
*msg
)
330 FontListData
*dat
= INST_DATA(cl
, o
);
331 struct ScanDirTaskInfo
*info
;
332 int dirname_len
= strlen(msg
->DirName
) + 1;
334 info
= AllocVec(sizeof(*info
) + dirname_len
, MEMF_CLEAR
| MEMF_PUBLIC
);
337 info
->DirName
= (STRPTR
)(info
+ 1);
338 memcpy(info
->DirName
, msg
->DirName
, dirname_len
);
342 _pass_parent
= FindTask(NULL
);
345 info
->Proc
= CreateNewProcTags(
346 NP_Entry
, ScanDirTask
,
350 ADDTAIL((APTR
)&dat
->ScanDirTasks
, (APTR
)info
);
353 Wait(SIGBREAKF_CTRL_F
);
365 struct MUIP_FontList_AddEntry
367 STACKED ULONG MethodID
;
368 STACKED
struct MUIS_FontList_Entry
*Entry
;
371 ULONG
flAddEntry(Class
*cl
, Object
*o
, struct MUIP_FontList_AddEntry
*msg
)
373 DoMethod(o
, MUIM_List_InsertSingle
, msg
->Entry
, MUIV_List_Insert_Sorted
);
379 AROS_UFH3(ULONG
, FontListDispatch
,
380 AROS_UFHA(Class
*, cl
, A0
),
381 AROS_UFHA(Object
*, o
, A2
),
382 AROS_UFHA(Msg
, msg
, A1
))
388 switch (msg
->MethodID
)
391 ret
= flNew(cl
, o
, (struct opSet
*)msg
);
395 ret
= flDispose(cl
, o
, msg
);
398 case MUIM_FontList_AddDir
:
399 ret
= flAddDir(cl
, o
, (struct MUIP_FontList_AddDir
*)msg
);
402 case MUIM_FontList_AddEntry
:
403 ret
= flAddEntry(cl
, o
, (struct MUIP_FontList_AddEntry
*)msg
);
407 ret
= DoSuperMethodA(cl
, o
, msg
);
417 void CleanupFontListClass(void)
421 MUI_DeleteCustomClass(FontListClass
);
422 FontListClass
= NULL
;
426 int InitFontListClass(void)
428 FontListClass
= MUI_CreateCustomClass(NULL
, MUIC_List
, NULL
,
429 sizeof(FontListData
), UFHN(FontListDispatch
));
430 return FontListClass
!= NULL
;