Show sane screen mode defaults if screenmode.prefs is missing or modeid isn't available.
[AROS.git] / workbench / prefs / screenmode / smproperties.c
blob7dd67b3453319ba7dfb17970c439651bc2f00cd7
1 /*
2 Copyright © 2003-2011, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define MUIMASTER_YES_INLINE_STDARG
7 #define DEBUG 0
9 #include <libraries/mui.h>
11 #include <proto/alib.h>
12 #include <proto/dos.h>
13 #include <proto/exec.h>
14 #include <proto/muimaster.h>
15 #include <proto/intuition.h>
16 #include <proto/graphics.h>
17 #include <proto/utility.h>
19 #include <zune/customclasses.h>
21 #include "locale.h"
23 #include "smproperties.h"
25 struct ScreenModeProperties_DATA
27 Object *depth, *def_width, *def_height;
29 Object *objWidth;
30 Object *objHeight;
31 Object *autoscroll;
33 ULONG DisplayID;
34 UWORD MinWidth, MinHeight;
35 UWORD MaxWidth, MaxHeight;
36 UWORD DefWidth, DefHeight;
37 UWORD DefDepth;
38 BOOL VariableDepth;
41 #define CheckMarkObject \
42 ImageObject, \
43 ImageButtonFrame, \
44 MUIA_InputMode , MUIV_InputMode_Toggle, \
45 MUIA_Image_Spec , MUII_CheckMark, \
46 MUIA_Image_FreeVert , TRUE, \
47 MUIA_Background , MUII_ButtonBack, \
48 MUIA_ShowSelState , FALSE
50 #define HLeft(obj...) \
51 (IPTR)(HGroup, (IPTR)GroupSpacing(0), Child, (IPTR)(obj), Child, (IPTR)HSpace(0), End)
53 #undef HCenter
54 #define HCenter(obj...) \
55 (HGroup, (IPTR)GroupSpacing(0), Child, (IPTR)HSpace(0), Child, (IPTR)(obj), Child, \
56 (IPTR)HSpace(0), End)
58 Object *ScreenModeProperties__OM_NEW(Class *CLASS, Object *self, struct opSet *message)
60 struct ScreenModeProperties_DATA *data;
61 Object *objWidth, *objHeight, *depth,
62 *def_width, *def_height;
64 Object *autoscroll;
66 ULONG id;
68 self = (Object *)DoSuperNewTags
70 CLASS, self, NULL,
71 MUIA_Group_Horiz, TRUE,
72 Child, (IPTR)ColGroup(4),
73 Child, (IPTR)Label1(__(MSG_WIDTH)),
74 Child, HLeft(objWidth = (Object *)StringObject,
75 StringFrame,
76 MUIA_String_Accept, (IPTR)"0123456789",
77 MUIA_String_MaxLen, 6,
78 MUIA_CycleChain, TRUE,
79 End),
80 Child, (IPTR)(def_width = (Object *)CheckMarkObject, MUIA_CycleChain, TRUE, End),
81 Child, (IPTR)Label1(__(MSG_DEFAULT)),
83 Child, (IPTR)Label1(__(MSG_HEIGHT)),
84 Child, HLeft(objHeight = (Object *)StringObject,
85 StringFrame,
86 MUIA_String_Accept, (IPTR)"0123456789",
87 MUIA_String_MaxLen, 6,
88 MUIA_CycleChain, TRUE,
89 End),
90 Child, HLeft(def_height = (Object *)CheckMarkObject, MUIA_CycleChain, TRUE, End),
91 Child, (IPTR)Label1(__(MSG_DEFAULT)),
93 Child, (IPTR)Label1(__(MSG_DEPTH)),
94 Child, HLeft(depth = (Object *)NumericbuttonObject, MUIA_CycleChain, TRUE, End),
95 Child, (IPTR)RectangleObject, End,
96 Child, (IPTR)RectangleObject, End,
98 Child, (IPTR)Label1(__(MSG_AUTOSCROLL)),
99 Child, HLeft(autoscroll = (Object *)CheckMarkObject, MUIA_CycleChain, TRUE, End),
100 Child, (IPTR)RectangleObject, End,
101 Child, (IPTR)RectangleObject, End,
103 End,
105 TAG_MORE, (IPTR)message->ops_AttrList
108 if (!self)
109 goto err;
111 D(bug("[smproperties] Created ScreenModeProperties object 0x%p\n", self));
112 data = INST_DATA(CLASS, self);
114 data->objWidth = objWidth;
115 data->objHeight = objHeight;
116 data->depth = depth;
117 data->def_width = def_width;
118 data->def_height = def_height;
119 data->autoscroll = autoscroll;
121 DoMethod
123 objWidth, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
124 (IPTR)self, 3,
125 MUIM_Set, MUIA_ScreenModeProperties_WidthString, MUIV_TriggerValue
128 DoMethod
130 objHeight, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
131 (IPTR)self, 3,
132 MUIM_Set, MUIA_ScreenModeProperties_HeightString, MUIV_TriggerValue
135 DoMethod
137 depth, MUIM_Notify, MUIA_Numeric_Value, MUIV_EveryTime,
138 (IPTR)self, 3,
139 MUIM_Set, MUIA_ScreenModeProperties_Depth, MUIV_TriggerValue
142 DoMethod
144 def_width, MUIM_Notify, MUIA_Selected, TRUE,
145 (IPTR)self, 3,
146 MUIM_Set, MUIA_ScreenModeProperties_Width, -1
149 DoMethod
151 def_width, MUIM_Notify, MUIA_Selected, MUIV_EveryTime,
152 (IPTR)objWidth, 3,
153 MUIM_Set, MUIA_Disabled, MUIV_TriggerValue
156 DoMethod
158 def_height, MUIM_Notify, MUIA_Selected, TRUE,
159 (IPTR)self, 3,
160 MUIM_Set, MUIA_ScreenModeProperties_Height, -1
163 DoMethod
165 def_height, MUIM_Notify, MUIA_Selected, MUIV_EveryTime,
166 (IPTR)objHeight, 3,
167 MUIM_Set, MUIA_Disabled, MUIV_TriggerValue
170 id = GetTagData(MUIA_ScreenModeProperties_DisplayID, INVALID_ID, message->ops_AttrList);
171 D(bug("[smproperties] Setting initial ModeID 0x%08lX\n", id));
172 set(self, MUIA_ScreenModeProperties_DisplayID, id);
174 return self;
176 err:
177 CoerceMethod(CLASS, self, OM_DISPOSE);
178 return NULL;
181 static inline UWORD AdjustWidth(UWORD width, struct ScreenModeProperties_DATA *data)
183 if (width < data->MinWidth)
184 width = data->MinWidth;
185 if (width > data->MaxWidth)
186 width = data->MaxWidth;
187 D(bug("[smproperties] Adjusted width = %lu\n", width));
188 return width;
191 static inline UWORD AdjustHeight(UWORD height, struct ScreenModeProperties_DATA *data)
193 if (height < data->MinHeight)
194 height = data->MinHeight;
195 if (height > data->MaxHeight)
196 height = data->MaxHeight;
197 D(bug("[smproperties] Adjusted height = %lu\n", height));
198 return height;
201 IPTR ScreenModeProperties__OM_SET(Class *CLASS, Object *self, struct opSet *message)
203 struct ScreenModeProperties_DATA *data = INST_DATA(CLASS, self);
204 struct TagItem *tags;
205 struct TagItem *tag;
206 ULONG id = INVALID_ID;
207 IPTR no_notify = TAG_IGNORE;
208 IPTR ret;
209 WORD depth;
210 LONG width, height;
212 DB2(bug("[smproperties] OM_SET called\n"));
213 for (tags = message->ops_AttrList; (tag = NextTagItem(&tags)); )
215 switch (tag->ti_Tag)
217 case MUIA_NoNotify:
218 no_notify = MUIA_NoNotify;
219 break;
221 case MUIA_ScreenModeProperties_DisplayID:
223 struct TagItem depth_tags[] =
225 { MUIA_NoNotify, TRUE },
226 { MUIA_Numeric_Min, 0 },
227 { MUIA_Numeric_Max, 0 },
228 { MUIA_Numeric_Default, 0 },
229 { MUIA_Disabled, FALSE},
230 { TAG_DONE, 0 }
233 struct DimensionInfo dim;
234 BOOL autoscroll;
235 ULONG tmpid;
237 tmpid = tag->ti_Data;
238 D(bug("[smproperties] Set DisplayID = 0x%08lx\n", tmpid));
240 if (!GetDisplayInfoData(NULL, (UBYTE *)&dim, sizeof(dim), DTAG_DIMS, tmpid))
242 tmpid = BestModeID(TAG_DONE);
243 nnset(data->def_width, MUIA_Selected, TRUE);
244 nnset(data->def_height, MUIA_Selected, TRUE);
246 if (GetDisplayInfoData(NULL, (UBYTE *)&dim, sizeof(dim), DTAG_DIMS, tmpid))
248 IPTR isdefault, val;
250 depth_tags[1].ti_Data = dim.MaxDepth > 8 ? dim.MaxDepth : 1;
251 depth_tags[2].ti_Data = dim.MaxDepth;
252 depth_tags[3].ti_Data = dim.MaxDepth;
254 id = tmpid;
255 data->DefWidth = dim.Nominal.MaxX - dim.Nominal.MinX + 1;
256 data->DefHeight = dim.Nominal.MaxY - dim.Nominal.MinY + 1;
257 data->DefDepth = depth_tags[3].ti_Data;
258 data->MinWidth = dim.MinRasterWidth;
259 data->MinHeight = dim.MinRasterHeight;
260 data->MaxWidth = dim.MaxRasterWidth;
261 data->MaxHeight = dim.MaxRasterHeight;
263 D(bug("[smproperties] Obtained DimensionsInfo:\n"));
264 D(bug("[smproperties] Minimum raster: %lux%lux1\n", dim.MinRasterWidth, dim.MinRasterHeight));
265 D(bug("[smproperties] Maximum raster: %lux%lux%lu\n", dim.MaxRasterWidth, dim.MaxRasterHeight, dim.MaxDepth));
266 D(bug("[smproperties] Display size: %lux%lu\n", data->DefWidth, data->DefHeight));
268 GetAttr(MUIA_Selected, data->def_width, &isdefault);
269 if (isdefault)
270 width = data->DefWidth;
271 else
273 GetAttr(MUIA_Numeric_Value, data->objWidth, &val);
274 width = AdjustWidth((LONG)val, data);
277 GetAttr(MUIA_Selected, data->def_height, &isdefault);
278 if (isdefault)
279 height = data->DefHeight;
280 else
282 GetAttr(MUIA_String_Integer, data->objHeight, &val);
283 height = AdjustHeight((LONG)val, data);
286 data->VariableDepth = TRUE;
287 GetAttr(MUIA_Numeric_Value, data->depth, &val);
288 /* Original AmigaOS screenmode prefs do not allow to change depth for CyberGFX
289 * screnmodes if it is high or true color screenmode. */
290 if (dim.MaxDepth > 8)
292 data->VariableDepth = FALSE;
293 depth_tags[3].ti_Tag = MUIA_Numeric_Value;
294 depth_tags[4].ti_Data = TRUE;
295 } else if (val > dim.MaxDepth) {
296 /* Make sure depth is always <= dim.MaxDepth */
297 depth_tags[3].ti_Tag = MUIA_Numeric_Value;
298 depth_tags[3].ti_Data = dim.MaxDepth;
302 /* Enable autoscroll if one of the maximum sizes is bigger than
303 the resolution. */
305 autoscroll = data->MaxWidth > data->DefWidth ||
306 data->MaxHeight > data->DefHeight;
308 data->DisplayID = id;
310 SetAttrs(self, MUIA_Disabled, id == INVALID_ID, TAG_DONE);
311 if (id == INVALID_ID)
313 nnset(data->def_width, MUIA_Selected, TRUE);
314 nnset(data->def_height, MUIA_Selected, TRUE);
315 depth_tags[4].ti_Tag = TAG_DONE;
317 else
319 IPTR isdefault;
320 GetAttr(MUIA_Selected, data->def_height, &isdefault);
321 SetAttrs(data->objHeight, MUIA_Disabled, isdefault, TAG_DONE);
322 GetAttr(MUIA_Selected, data->def_width, &isdefault);
323 SetAttrs(data->objWidth, MUIA_Disabled, isdefault, TAG_DONE);
326 SetAttrs(data->objWidth, MUIA_String_Integer, width, TAG_DONE);
327 SetAttrs(data->objHeight, MUIA_String_Integer, height, TAG_DONE);
328 SetAttrsA(data->depth, depth_tags);
330 SetAttrs(data->autoscroll, no_notify, TRUE,
331 MUIA_Disabled, !autoscroll,
332 MUIA_Selected, autoscroll,
333 TAG_DONE);
335 break;
338 case MUIA_ScreenModeProperties_WidthString:
339 D(bug("[smproperties] Set WidthString = %s\n", (CONST_STRPTR)tag->ti_Data));
340 StrToLong((CONST_STRPTR)tag->ti_Data, &width);
341 SetAttrs(self, MUIA_ScreenModeProperties_Width, width, TAG_DONE);
342 break;
344 case MUIA_ScreenModeProperties_Width:
345 width = tag->ti_Data;
347 D(bug("[smproperties] Set Width = %ld\n", width));
348 if (width == -1)
349 width = data->DefWidth;
350 else
351 width = AdjustWidth(width, data);
352 SetAttrs(data->objWidth, MUIA_NoNotify, TRUE, MUIA_String_Integer, width, TAG_DONE);
353 SetAttrs(data->def_width, MUIA_NoNotify, TRUE, MUIA_Selected, width == data->DefWidth, TAG_DONE);
354 SetAttrs(data->objWidth, MUIA_NoNotify, TRUE, MUIA_Disabled, width == data->DefWidth, TAG_DONE);
355 break;
357 case MUIA_ScreenModeProperties_HeightString:
358 D(bug("[smproperties] Set HeightString = %s\n", (CONST_STRPTR)tag->ti_Data));
359 StrToLong((CONST_STRPTR)tag->ti_Data, &height);
360 SetAttrs(self, MUIA_ScreenModeProperties_Height, height, TAG_DONE);
361 break;
363 case MUIA_ScreenModeProperties_Height:
364 height = tag->ti_Data;
366 D(bug("[smproperties] Set Height = %ld\n", height));
367 if (height == -1)
368 height = data->DefHeight;
369 else
370 height = AdjustHeight(height, data);
371 SetAttrs(data->objHeight, MUIA_NoNotify, TRUE, MUIA_String_Integer, height, TAG_DONE);
372 SetAttrs(data->def_height, MUIA_NoNotify, TRUE, MUIA_Selected, height == data->DefHeight, TAG_DONE);
373 SetAttrs(data->objHeight, MUIA_NoNotify, TRUE, MUIA_Disabled, height == data->DefHeight, TAG_DONE);
374 break;
376 case MUIA_ScreenModeProperties_Depth:
377 if (data->VariableDepth)
379 depth = tag->ti_Data;
381 D(bug("[smproperties] Set Depth = %ld\n", depth));
382 if (depth == -1)
383 depth = data->DefDepth;
384 SetAttrs(data->depth, no_notify, TRUE, MUIA_Numeric_Value, depth, TAG_DONE);
386 break;
388 case MUIA_ScreenModeProperties_Autoscroll:
390 D(bug("[smproperties] Set Autoscroll = %lu\n", tag->ti_Data));
391 if (id != INVALID_ID && !XGET(data->autoscroll, MUIA_Disabled))
392 SetAttrs(data->autoscroll, no_notify, TRUE, MUIA_Selected, tag->ti_Data != 0);
393 break;
397 DB2(bug("[smproperties] Calling OM_SET() on superclass\n"));
398 ret = DoSuperMethodA(CLASS, self, (Msg)message);
399 DB2(bug("[smproperties] OM_SET() on superclass returned %ld\n", ret));
400 return ret;
403 IPTR ScreenModeProperties__OM_GET(Class *CLASS, Object *self, struct opGet *message)
405 struct ScreenModeProperties_DATA *data = INST_DATA(CLASS, self);
407 switch (message->opg_AttrID)
409 case MUIA_ScreenModeProperties_DisplayID:
410 *message->opg_Storage = data->DisplayID;
411 break;
413 case MUIA_ScreenModeProperties_Width:
414 *message->opg_Storage = XGET(data->objWidth, MUIA_String_Integer);
415 break;
417 case MUIA_ScreenModeProperties_Height:
418 *message->opg_Storage = XGET(data->objHeight, MUIA_String_Integer);
419 break;
421 case MUIA_ScreenModeProperties_Depth:
422 *message->opg_Storage = XGET(data->depth, MUIA_Numeric_Value);
423 break;
425 case MUIA_ScreenModeProperties_Autoscroll:
426 *message->opg_Storage = XGET(data->autoscroll, MUIA_Selected);
427 break;
429 default:
430 return DoSuperMethodA(CLASS, self, (Msg)message);
433 return TRUE;
436 ZUNE_CUSTOMCLASS_3
438 ScreenModeProperties, NULL, MUIC_Group, NULL,
439 OM_NEW, struct opSet *,
440 OM_GET, struct opGet *,
441 OM_SET, struct opSet *