revert between 56095 -> 55830 in arch
[AROS.git] / workbench / prefs / screenmode / smselector.c
blob6e267ee02f47b0da5c63939521c7ee9a2f38c750
1 /*
2 Copyright © 2003-2017, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define MUIMASTER_YES_INLINE_STDARG
7 #define DEBUG 0
9 #include <exec/rawfmt.h>
10 #include <libraries/mui.h>
11 #include <utility/hooks.h>
13 #include <proto/alib.h>
14 #include <proto/dos.h>
15 #include <proto/exec.h>
16 #include <proto/muimaster.h>
17 #include <proto/intuition.h>
18 #include <proto/graphics.h>
19 #include <proto/dos.h>
20 #include <proto/utility.h>
22 #include <zune/customclasses.h>
24 #include <string.h>
26 #include "locale.h"
28 #include "smselector.h"
30 struct ScreenModeSelector_DATA
32 Object *mode_list;
33 STRPTR *modes_array;
34 ULONG *ids_array;
37 #define HOOK(name) \
38 struct Hook
40 #define HOOKFUNC(name) IPTR name ## Func(struct Hook *hook, APTR obj, APTR msg)
42 AROS_UFH3(IPTR, SelectFunc,
43 AROS_UFHA(struct Hook *, hook, A0),
44 AROS_UFHA(APTR , obj , A2),
45 AROS_UFHA(APTR , msg , A1))
47 AROS_USERFUNC_INIT
49 struct ScreenModeSelector_DATA *data = INST_DATA(OCLASS(obj), obj);
51 /* Note: the value used to set MUIA_List_Active may not be an index */
52 return set(obj, MUIA_ScreenModeSelector_Active,
53 data->ids_array[XGET(obj, MUIA_List_Active)]);
55 AROS_USERFUNC_EXIT;
57 static struct Hook SelectHook = { .h_Entry = SelectFunc };
59 AROS_UFH3(IPTR, DisplayFunc,
60 AROS_UFHA(struct Hook *, hook, A0),
61 AROS_UFHA(CONST_STRPTR *, array, A2),
62 AROS_UFHA(STRPTR, entry, A1))
64 AROS_USERFUNC_INIT
66 if (entry)
68 ULONG *ids_array = hook->h_Data;
69 ULONG num = (ULONG)(IPTR)array[-1];
70 ULONG modeid = ids_array[num];
71 static char modeid_str[9];
73 RawDoFmt("%08lx", (RAWARG)&modeid, RAWFMTFUNC_STRING, modeid_str);
74 array[0] = modeid_str;
75 array[1] = entry;
77 else
79 array[0] = _(MSG_MODE_ID);
80 array[1] = _(MSG_DESCRIPTION);
82 return 0;
84 AROS_USERFUNC_EXIT
87 static struct Hook DisplayHook = { .h_Entry = DisplayFunc };
89 Object *ScreenModeSelector__OM_NEW(Class *CLASS, Object *self, struct opSet *message)
91 STRPTR *modes_array;
92 ULONG *ids_array;
93 ULONG id, num_modes, cur_mode;
94 Object *list;
96 struct DisplayInfo DisplayInfo;
97 struct DimensionInfo DimensionInfo;
98 struct NameInfo NameInfo;
99 APTR handle;
101 struct ScreenModeSelector_DATA *data;
103 num_modes = 0; id = INVALID_ID;
104 while ((id = NextDisplayInfo(id)) != INVALID_ID) num_modes++;
106 modes_array = AllocVec(sizeof(STRPTR) * (num_modes + 1), MEMF_CLEAR);
107 if (!modes_array)
108 goto err;
110 ids_array = AllocVec(sizeof(ULONG) * (num_modes + 1), MEMF_ANY);
111 if (!ids_array)
112 goto err;
114 ids_array[num_modes] = INVALID_ID;
116 cur_mode = 0;
117 while ((id = NextDisplayInfo(id)) != INVALID_ID)
119 if ((id & MONITOR_ID_MASK) == DEFAULT_MONITOR_ID)
120 continue;
122 if (!(handle = FindDisplayInfo(id)))
123 continue;
125 if (!GetDisplayInfoData(handle, (UBYTE *)&NameInfo, sizeof(struct NameInfo), DTAG_NAME, 0))
126 continue;
128 if (!GetDisplayInfoData(handle, (UBYTE *)&DisplayInfo, sizeof(struct DisplayInfo), DTAG_DISP, 0))
129 continue;
131 if (!(DisplayInfo.PropertyFlags & DIPF_IS_WB) || DisplayInfo.NotAvailable)
132 continue;
134 if (!GetDisplayInfoData(handle, (UBYTE *)&DimensionInfo, sizeof(struct DimensionInfo), DTAG_DIMS, 0))
135 continue;
137 modes_array[cur_mode] = AllocVec(sizeof(NameInfo.Name), MEMF_ANY);
138 if (!modes_array[cur_mode])
139 continue;
141 CopyMem(NameInfo.Name, modes_array[cur_mode], sizeof(NameInfo.Name));
142 ids_array[cur_mode] = id;
144 cur_mode++;
147 DisplayHook.h_Data = ids_array;
149 list = (Object *)ListObject,
150 InputListFrame,
151 MUIA_List_AutoVisible, (IPTR)TRUE,
152 MUIA_List_DisplayHook, (IPTR)&DisplayHook,
153 MUIA_List_Format, (IPTR)"BAR,",
154 MUIA_List_SourceArray, (IPTR)modes_array,
155 MUIA_List_Title, TRUE,
156 MUIA_CycleChain, TRUE,
157 End;
159 self = (Object *)DoSuperNewTags
161 CLASS, self, NULL,
162 MUIA_Listview_List, (IPTR)list,
163 TAG_MORE, (IPTR)message->ops_AttrList
166 if (!self)
167 goto err;
169 DoMethod(self, MUIM_Notify, MUIA_List_Active, MUIV_EveryTime,
170 (IPTR)self, 3, MUIM_CallHook, (IPTR)&SelectHook, MUIV_TriggerValue);
172 data = INST_DATA(CLASS, self);
173 data->mode_list = list;
174 data->modes_array = modes_array;
175 data->ids_array = ids_array;
177 return self;
179 err:
180 CoerceMethod(CLASS, self, OM_DISPOSE);
181 return NULL;
184 IPTR ScreenModeSelector__OM_DISPOSE(Class *CLASS, Object *self, Msg message)
186 struct ScreenModeSelector_DATA *data;
187 ULONG cur_mode;
189 data = INST_DATA(CLASS, self);
191 if (data->modes_array)
193 for (cur_mode = 0; data->modes_array[cur_mode]; cur_mode++)
194 FreeVec(data->modes_array[cur_mode]);
196 FreeVec(data->modes_array);
199 FreeVec(data->ids_array);
201 return DoSuperMethodA(CLASS, self, message);
205 IPTR ScreenModeSelector__OM_SET(Class *CLASS, Object *self, struct opSet *message)
207 struct ScreenModeSelector_DATA *data = INST_DATA(CLASS, self);
208 struct TagItem *tags;
209 struct TagItem *tag;
210 struct TagItem noforward_tags[] =
212 {MUIA_Group_Forward , FALSE },
213 {TAG_MORE , (IPTR)message->ops_AttrList }
215 struct opSet noforward_message = *message;
216 noforward_message.ops_AttrList = noforward_tags;
218 for (tags = message->ops_AttrList; (tag = NextTagItem(&tags)); )
220 switch (tag->ti_Tag)
222 case MUIA_ScreenModeSelector_Active:
224 int i;
226 D(bug("[smselector] Set Active ID 0x%08lX\n", tag->ti_Data));
229 i = 0;
230 data->ids_array[i] != tag->ti_Data && data->ids_array[i] != INVALID_ID;
234 if (data->ids_array[i] == INVALID_ID)
235 tag->ti_Data = INVALID_ID;
236 else
238 if (XGET(data->mode_list, MUIA_List_Active) != i)
240 D(bug("[smselector] Set active item %lu\n", i));
241 NNFSET(data->mode_list, MUIA_List_Active, i);
244 break;
249 return DoSuperMethodA(CLASS, self, (Msg)&noforward_message);
252 IPTR ScreenModeSelector__OM_GET(Class *CLASS, Object *self, struct opGet *message)
254 struct ScreenModeSelector_DATA *data = INST_DATA(CLASS, self);
256 switch (message->opg_AttrID)
258 case MUIA_ScreenModeSelector_Active:
259 *message->opg_Storage =
260 data->ids_array[XGET(data->mode_list, MUIA_List_Active)];
261 break;
262 default:
263 return DoSuperMethodA(CLASS, self, (Msg)message);
266 return TRUE;
270 ZUNE_CUSTOMCLASS_4
272 ScreenModeSelector, NULL, MUIC_Listview, NULL,
273 OM_NEW, struct opSet *,
274 OM_DISPOSE, Msg,
275 OM_GET, struct opGet *,
276 OM_SET, struct opSet *