Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / workbench / libs / muimaster / support_classes.c
blob2a9a551618cc7d7b81f1670916624fe4becfef64
1 /*
2 Copyright © 2002-2003, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <string.h>
7 #include <stdio.h>
9 #include <intuition/classes.h>
10 #include <clib/alib_protos.h>
11 #include <proto/exec.h>
12 #include <proto/intuition.h>
13 #include <proto/utility.h>
14 #include <proto/muimaster.h>
17 #include "mui.h"
18 #include "support.h"
19 #include "support_classes.h"
20 #include "muimaster_intern.h"
22 /*#define MYDEBUG*/
23 #include "debug.h"
25 static const struct __MUIBuiltinClass * const builtins[] =
27 &_MUI_Notify_desc,
28 &_MUI_Family_desc,
29 &_MUI_Application_desc,
30 &_MUI_Window_desc,
31 &_MUI_Area_desc,
32 &_MUI_Rectangle_desc,
33 &_MUI_Group_desc,
34 &_MUI_Image_desc,
35 &_MUI_Configdata_desc,
36 &_MUI_Text_desc,
37 &_MUI_Numeric_desc,
38 &_MUI_Slider_desc,
39 &_MUI_String_desc,
40 ZUNE_BOOPSI_DESC
41 &_MUI_Prop_desc,
42 &_MUI_Scrollbar_desc,
43 &_MUI_Register_desc,
44 &_MUI_Menuitem_desc,
45 &_MUI_Menu_desc,
46 &_MUI_Menustrip_desc,
47 ZUNE_VIRTGROUP_DESC
48 ZUNE_SCROLLGROUP_DESC
49 &_MUI_Scrollbutton_desc,
50 &_MUI_Semaphore_desc,
51 &_MUI_Dataspace_desc,
52 &_MUI_Bitmap_desc,
53 &_MUI_Bodychunk_desc,
54 &_MUI_ChunkyImage_desc,
55 &_MUI_Cycle_desc,
56 &_MUI_Popstring_desc,
57 &_MUI_Listview_desc,
58 &_MUI_List_desc,
59 ZUNE_POPASL_DESC
60 &_MUI_Popobject_desc,
61 ZUNE_GAUGE_DESC
62 ZUNE_ABOUTMUI_DESC
63 ZUNE_SETTINGSGROUP_DESC
64 ZUNE_IMAGEADJUST_DESC
65 ZUNE_POPIMAGE_DESC
66 ZUNE_SCALE_DESC
67 ZUNE_RADIO_DESC
68 ZUNE_ICONLISTVIEW_DESC
69 ZUNE_BALANCE_DESC
70 ZUNE_COLORFIELD_DESC
71 ZUNE_COLORADJUST_DESC
72 ZUNE_IMAGEDISPLAY_DESC
73 ZUNE_PENDISPLAY_DESC
74 ZUNE_PENADJUST_DESC
75 ZUNE_POPPEN_DESC
76 &_MUI_Mccprefs_desc,
77 ZUNE_FRAMEDISPLAY_DESC
78 ZUNE_POPFRAME_DESC
79 ZUNE_FRAMEADJUST_DESC
80 ZUNE_VOLUMELIST_DESC
81 ZUNE_DIRLIST_DESC
82 ZUNE_NUMERICBUTTON_DESC
83 ZUNE_POPLIST_DESC
84 ZUNE_CRAWLING_DESC
85 ZUNE_POPSCREEN_DESC
86 ZUNE_LEVELMETER_DESC
87 ZUNE_KNOB_DESC
88 ZUNE_DTPIC_DESC
89 ZUNE_PALETTE_DESC
92 Class *ZUNE_GetExternalClass(ClassID classname, struct Library *MUIMasterBase)
94 struct Library *mcclib = NULL;
95 struct MUI_CustomClass *mcc = NULL ;
96 CONST_STRPTR const *pathptr;
97 TEXT s[255];
99 static CONST_STRPTR const searchpaths[] =
101 "Zune/%s",
102 "Classes/Zune/%s",
103 "MUI/%s",
104 NULL,
107 for (pathptr = searchpaths; *pathptr; pathptr++)
109 snprintf(s, 255, *pathptr, classname);
111 D(bug("Trying opening of %s\n",s));
113 if ((mcclib = OpenLibrary(s, 0)))
115 D(bug("Calling MCC Query. Librarybase at 0x%lx\n",mcclib));
117 mcc = MCC_Query(0);
118 if (!mcc) mcc = MCC_Query(1); /* MCP? */
120 if (mcc)
122 if (mcc->mcc_Class)
124 mcc->mcc_Module = mcclib;
125 D(bug("Successfully opened %s as external class\n",classname));
127 return mcc->mcc_Class;
131 CloseLibrary(mcclib);
135 D(bug("Failed to open external class %s\n",classname));
136 return NULL;
139 /**************************************************************************/
140 static Class *ZUNE_FindBuiltinClass(ClassID classid, struct Library *mb)
142 Class *cl = NULL, *cl2;
144 ForeachNode(&MUIMB(mb)->BuiltinClasses, cl2)
146 if (!strcmp(cl2->cl_ID, classid))
148 cl = cl2;
149 break;
153 return cl;
156 static Class *ZUNE_MakeBuiltinClass(ClassID classid, struct Library *MUIMasterBase)
158 int i;
159 Class *cl = NULL;
160 struct Library *mb = NULL;
162 D(bug("Makeing Builtinclass %s\n",classid));
164 for (i = 0; i < sizeof(builtins)/sizeof(builtins[0]); i++)
166 if (!strcmp(builtins[i]->name, classid))
168 Class *supercl;
169 ClassID superclid;
171 /* This may seem strange, but opening muimaster.library here is done in order to
172 increase muimaster.library's open count, so that it doesn't get expunged
173 while some of its internal classes are still in use.
174 We don't use muimaster.library directly but the name of the library
175 stored inside the base, because the library can be compiled also as
176 zunemaster.library */
178 mb = OpenLibrary(MUIMasterBase->lib_Node.ln_Name, 0);
180 /* It can't possibly fail, but well... */
181 if (!mb)
182 break;
184 if (strcmp(builtins[i]->supername, ROOTCLASS) == 0)
186 superclid = ROOTCLASS;
187 supercl = NULL;
189 else
191 superclid = NULL;
192 supercl = MUI_GetClass(builtins[i]->supername);
194 if (!supercl) break;
197 cl = MakeClass(builtins[i]->name, superclid, supercl, builtins[i]->datasize, 0);
198 if (cl)
200 #if defined(__MAXON__) || defined(__amigaos4__)
201 cl->cl_Dispatcher.h_Entry = builtins[i]->dispatcher;
202 #else
203 cl->cl_Dispatcher.h_Entry = (HOOKFUNC)metaDispatcher;
204 cl->cl_Dispatcher.h_SubEntry = builtins[i]->dispatcher;
205 #endif
206 /* Use this as a reference counter */
207 cl->cl_Dispatcher.h_Data = 0;
210 break;
214 if (!cl && mb)
215 CloseLibrary(mb);
217 return cl;
220 Class *ZUNE_GetBuiltinClass(ClassID classid, struct Library *mb)
222 Class *cl;
224 ObtainSemaphore(&MUIMB(MUIMasterBase)->ZuneSemaphore);
226 cl = ZUNE_FindBuiltinClass(classid, mb);
228 if (!cl)
230 cl = ZUNE_MakeBuiltinClass(classid, mb);
232 if (cl)
234 ZUNE_AddBuiltinClass(cl, mb);
236 /* Increase the reference counter */
237 cl->cl_Dispatcher.h_Data++;
241 ReleaseSemaphore(&MUIMB(MUIMasterBase)->ZuneSemaphore);
243 return cl;
247 * metaDispatcher - puts h_Data in A6 and calls real dispatcher
250 #ifdef __AROS__
251 AROS_UFH3(IPTR, metaDispatcher,
252 AROS_UFHA(struct IClass *, cl, A0),
253 AROS_UFHA(Object *, obj, A2),
254 AROS_UFHA(Msg , msg, A1))
256 AROS_USERFUNC_INIT
258 return AROS_UFC4(IPTR, cl->cl_Dispatcher.h_SubEntry,
259 AROS_UFPA(Class *, cl, A0),
260 AROS_UFPA(Object *, obj, A2),
261 AROS_UFPA(Msg , msg, A1),
262 AROS_UFPA(APTR , cl->cl_Dispatcher.h_Data, A6)
265 AROS_USERFUNC_EXIT
268 #else
269 #ifdef __SASC
270 __asm ULONG metaDispatcher(register __a0 struct IClass *cl, register __a2 Object *obj, register __a1 Msg msg)
272 __asm ULONG (*entry)(register __a0 struct IClass *cl, register __a2 Object *obj, register __a1 Msg msg) =
273 (__asm ULONG (*)(register __a0 struct IClass *, register __a2 Object *, register __a1 Msg))cl->cl_Dispatcher.h_SubEntry;
275 putreg(REG_A6,(long)cl->cl_Dispatcher.h_Data);
276 return entry(cl,obj,msg);
278 #endif
279 #endif