Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / workbench / libs / muimaster / classes / pendisplay.c
blobc3ffc9a8c77ffab62d12805605b3e6477c8ce12a
1 /*
2 Copyright © 2002-2003, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define MUIMASTER_YES_INLINE_STDARG
8 #include <stdio.h>
10 #include <graphics/gfx.h>
11 #include <graphics/view.h>
12 #include <graphics/gfxmacros.h>
13 #include <clib/alib_protos.h>
14 #include <proto/exec.h>
15 #include <proto/graphics.h>
16 #include <proto/utility.h>
17 #include <proto/intuition.h>
18 #include <proto/muimaster.h>
20 #include <string.h>
22 #include "mui.h"
23 #include "muimaster_intern.h"
24 #include "penspec.h"
25 #include "textengine.h"
26 #include "support.h"
27 #include "support_classes.h"
28 #include "pendisplay_private.h"
30 /* #define MYDEBUG 1 */
31 #include "debug.h"
33 extern struct Library *MUIMasterBase;
36 IPTR Pendisplay__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
38 struct Pendisplay_DATA *data;
39 const struct TagItem *tags;
40 struct TagItem *tag;
42 obj = (Object *)DoSuperMethodA(cl, obj, (Msg)msg);
43 if (!obj) return FALSE;
45 data = INST_DATA(cl, obj);
46 /* Format identifies need to be long enforced because of RawDoFmt() limits */
47 snprintf(data->penspec.ps_buf, sizeof(data->penspec.ps_buf), "%lc%ld", (LONG)PST_MUI, (LONG)MPEN_TEXT);
48 data->pen = -1;
50 /* parse initial taglist */
51 for (tags = msg->ops_AttrList; (tag = NextTagItem(&tags)); )
53 switch (tag->ti_Tag)
55 case MUIA_Pendisplay_Reference:
56 data->refobj = (Object *)tag->ti_Data;
57 DoMethod(data->refobj, MUIM_Notify, MUIA_Pendisplay_Spec, MUIV_EveryTime,
58 (IPTR)obj, 3, MUIM_Set, MUIA_Pendisplay_Spec, MUIV_TriggerValue);
59 break;
61 case MUIA_Pendisplay_RGBcolor:
63 struct MUI_RGBcolor *rgb = (struct MUI_RGBcolor *)tag->ti_Data;
64 snprintf(data->penspec.ps_buf, sizeof(data->penspec.ps_buf),
65 "%lc%08lx,%08lx,%08lx", (LONG)PST_RGB, rgb->red, rgb->green, rgb->blue);
67 break;
69 case MUIA_Pendisplay_Spec:
70 data->penspec = *(struct MUI_PenSpec *)tag->ti_Data;
71 break;
76 return (IPTR)obj;
79 IPTR Pendisplay__OM_DISPOSE(struct IClass *cl, Object *obj, Msg msg)
81 struct Pendisplay_DATA *data;
83 data = INST_DATA(cl, obj);
84 if (data->refobj)
86 /* hmm ... kill notify here? But refobj might already have been killed :-\ */
89 return DoSuperMethodA(cl, obj, msg);
92 IPTR Pendisplay__OM_SET(struct IClass *cl, Object *obj, struct opSet *msg)
94 struct Pendisplay_DATA *data;
95 const struct TagItem *tags;
96 struct TagItem *tag;
97 BOOL newcol = FALSE;
98 IPTR retval;
100 data = INST_DATA(cl, obj);
102 for (tags = msg->ops_AttrList; (tag = NextTagItem(&tags)); )
104 switch (tag->ti_Tag)
106 case MUIA_Pendisplay_Reference:
107 if (data->refobj)
109 DoMethod(data->refobj, MUIM_KillNotifyObj, MUIA_Pendisplay_Spec, (IPTR)obj);
112 data->refobj = (Object *)tag->ti_Data;
114 if (data->refobj)
116 DoMethod(data->refobj, MUIM_Notify, MUIA_Pendisplay_Spec, MUIV_EveryTime,
117 (IPTR)obj, 3, MUIM_Set, MUIA_Pendisplay_Spec, MUIV_TriggerValue);
119 newcol = TRUE;
120 break;
122 case MUIA_Pendisplay_RGBcolor:
124 struct MUI_RGBcolor *rgb = (struct MUI_RGBcolor *)tag->ti_Data;
126 snprintf(data->penspec.ps_buf, sizeof(data->penspec.ps_buf),
127 "%lc%08lx,%08lx,%08lx", (LONG)PST_RGB, rgb->red, rgb->green, rgb->blue);
129 newcol = TRUE;
130 break;
132 case MUIA_Pendisplay_Spec:
133 if (tag->ti_Data)
135 data->penspec = *(struct MUI_PenSpec *)tag->ti_Data;
136 newcol = TRUE;
138 break;
144 retval = DoSuperMethodA(cl, obj, (Msg)msg);
146 if (newcol && (_flags(obj) & MADF_SETUP))
148 if (data->pen != -1)
150 MUI_ReleasePen(muiRenderInfo(obj), data->pen);
151 data->pen = -1;
154 if (!data->refobj)
156 data->pen = MUI_ObtainPen(muiRenderInfo(obj), &data->penspec, 0);
159 MUI_Redraw(obj, MADF_DRAWUPDATE);
162 return retval;
165 IPTR Pendisplay__OM_GET(struct IClass *cl, Object * obj, struct opGet *msg)
167 struct Pendisplay_DATA *data = INST_DATA(cl, obj);
168 IPTR *store = msg->opg_Storage;
170 switch (msg->opg_AttrID)
172 case MUIA_Pendisplay_Pen:
173 *store = (IPTR)data->pen;
174 break;
176 case MUIA_Pendisplay_Reference:
177 *store = (IPTR)data->refobj;
178 break;
180 case MUIA_Pendisplay_RGBcolor:
182 #warning FIXME: MUIA_Pendisplay_RGBColor (only works for RGB pen specs)
183 struct MUI_PenSpec_intern intpenspec;
184 zune_pen_spec_to_intern(&data->penspec, &intpenspec);
186 switch(intpenspec.p_type)
188 case PST_MUI:
189 case PST_CMAP:
190 case PST_SYS:
191 break;
192 case PST_RGB:
193 data->rgb = intpenspec.p_rgb;
194 break;
197 *store = (IPTR)&data->rgb;
199 break;
201 case MUIA_Pendisplay_Spec:
202 *store = (IPTR)&data->penspec;
203 break;
205 default:
206 return DoSuperMethodA(cl, obj, (Msg)msg);
209 return TRUE;
212 IPTR Pendisplay__MUIM_Setup(struct IClass *cl, Object *obj, struct MUIP_Setup *msg)
214 struct Pendisplay_DATA *data = INST_DATA(cl,obj);
216 if (!(DoSuperMethodA(cl, obj, (Msg)msg))) return 0;
218 if (!data->refobj)
220 data->pen = MUI_ObtainPen(muiRenderInfo(obj), &data->penspec, 0);
223 return 1;
226 IPTR Pendisplay__MUIM_Cleanup(struct IClass *cl, Object *obj, struct MUIP_Cleanup *msg)
228 struct Pendisplay_DATA *data = INST_DATA(cl,obj);
230 if (data->pen != -1)
232 MUI_ReleasePen(muiRenderInfo(obj), data->pen);
233 data->pen = -1;
236 return DoSuperMethodA(cl, obj, (Msg)msg);
239 IPTR Pendisplay__MUIM_AskMinMax(struct IClass *cl, Object *obj, struct MUIP_AskMinMax *msg)
241 DoSuperMethodA(cl,obj,(Msg)msg);
243 msg->MinMaxInfo->MinWidth += 3;
244 msg->MinMaxInfo->MinHeight += 3;
245 msg->MinMaxInfo->DefWidth += 16;
246 msg->MinMaxInfo->DefHeight += 16;
247 msg->MinMaxInfo->MaxWidth = MUI_MAXMAX;
248 msg->MinMaxInfo->MaxHeight = MUI_MAXMAX;
250 return 0;
253 IPTR Pendisplay__MUIM_Draw(struct IClass *cl, Object *obj, struct MUIP_Draw *msg)
255 struct Pendisplay_DATA *data = INST_DATA(cl,obj);
256 LONG color;
258 DoSuperMethodA(cl,obj,(Msg)msg);
260 if (!(msg->flags & (MADF_DRAWOBJECT | MADF_DRAWUPDATE)))
261 return FALSE;
263 if (data->refobj)
265 IPTR val;
267 get(data->refobj, MUIA_Pendisplay_Pen, &val);
268 color = (LONG)val;
270 else
272 color = data->pen;
275 if (color == -1)
277 static UWORD pat[] = {0x1111,0x2222,0x4444,0x8888};
279 SetAfPt(_rp(obj), pat, 2);
280 SetABPenDrMd(_rp(obj), _pens(obj)[MPEN_SHADOW], _pens(obj)[MPEN_BACKGROUND],JAM2);
283 else
285 SetABPenDrMd(_rp(obj), MUIPEN(color), 0,JAM1);
288 RectFill(_rp(obj), _mleft(obj), _mtop(obj), _mright(obj), _mbottom(obj));
290 SetAfPt(_rp(obj), NULL, 0);
292 return 0;
295 IPTR Pendisplay__MUIM_Pendisplay_SetColormap(struct IClass *cl, Object *obj, struct MUIP_Pendisplay_SetColormap *msg)
297 struct MUI_PenSpec penspec;
299 snprintf(penspec.ps_buf, sizeof(penspec.ps_buf), "%lc%ld", (LONG)PST_CMAP, msg->colormap);
300 set(obj, MUIA_Pendisplay_Spec, (IPTR)&penspec);
302 return 0;
305 IPTR Pendisplay__MUIM_Pendisplay_SetRGB(struct IClass *cl, Object *obj, struct MUIP_Pendisplay_SetRGB *msg)
307 struct MUI_PenSpec penspec;
309 snprintf(penspec.ps_buf, sizeof(penspec.ps_buf), "%lc%08lx,%08lx,%08lx", (LONG)PST_RGB, msg->r, msg->g, msg->b);
310 set(obj, MUIA_Pendisplay_Spec, (IPTR)&penspec);
312 return 0;
315 IPTR Pendisplay__MUIM_Pendisplay_SetMUIPen(struct IClass *cl, Object *obj, struct MUIP_Pendisplay_SetMUIPen *msg)
317 struct MUI_PenSpec penspec;
319 snprintf(penspec.ps_buf, sizeof(penspec.ps_buf), "%lc%ld", (LONG)PST_MUI, msg->muipen);
320 set(obj, MUIA_Pendisplay_Spec, (IPTR)&penspec);
322 return 0;
325 IPTR Pendisplay__MUIM_DragQuery(struct IClass *cl, Object *obj, struct MUIP_DragQuery *msg)
327 STRPTR spec = NULL;
329 if (msg->obj == obj)
330 return MUIV_DragQuery_Refuse;
332 if (get(msg->obj, MUIA_Pendisplay_Spec, &spec))
333 return MUIV_DragQuery_Accept;
335 if (get(msg->obj, MUIA_Imagedisplay_Spec, &spec))
337 if ((NULL != spec) && (strlen(spec) > 2) && (spec[0] == '2') && (spec[1] == ':'))
338 return MUIV_DragQuery_Accept;
341 return MUIV_DragQuery_Refuse;
344 IPTR Pendisplay__MUIM_DragDrop(struct IClass *cl, Object *obj, struct MUIP_DragDrop *msg)
346 STRPTR spec;
348 if (get(msg->obj, MUIA_Pendisplay_Spec, &spec))
349 set(obj, MUIA_Pendisplay_Spec, spec);
350 else if (get(msg->obj, MUIA_Imagedisplay_Spec, &spec))
351 set(obj, MUIA_Pendisplay_Spec, spec+2);
352 return 0;
355 #if ZUNE_BUILTIN_PENDISPLAY
356 BOOPSI_DISPATCHER(IPTR, Pendisplay_Dispatcher, cl, obj, msg)
358 switch (msg->MethodID)
360 case OM_NEW: return Pendisplay__OM_NEW(cl, obj, (struct opSet *)msg);
361 case OM_DISPOSE: return Pendisplay__OM_DISPOSE(cl, obj, msg);
362 case OM_SET: return Pendisplay__OM_SET(cl, obj, (struct opSet *)msg);
363 case OM_GET: return Pendisplay__OM_GET(cl, obj, (struct opGet *)msg);
364 case MUIM_Setup: return Pendisplay__MUIM_Setup(cl, obj, (struct MUIP_Setup *)msg);
365 case MUIM_Cleanup: return Pendisplay__MUIM_Cleanup(cl, obj, (struct MUIP_Cleanup *)msg);
366 case MUIM_AskMinMax: return Pendisplay__MUIM_AskMinMax(cl, obj, (struct MUIP_AskMinMax*)msg);
367 case MUIM_Draw: return Pendisplay__MUIM_Draw(cl, obj, (struct MUIP_Draw*)msg);
368 case MUIM_Pendisplay_SetColormap: return Pendisplay__MUIM_Pendisplay_SetColormap(cl, obj, (struct MUIP_Pendisplay_SetColormap *)msg);
369 case MUIM_Pendisplay_SetMUIPen: return Pendisplay__MUIM_Pendisplay_SetMUIPen(cl, obj, (struct MUIP_Pendisplay_SetMUIPen *)msg);
370 case MUIM_Pendisplay_SetRGB: return Pendisplay__MUIM_Pendisplay_SetRGB(cl, obj, (struct MUIP_Pendisplay_SetRGB *)msg);
371 case MUIM_DragQuery: return Pendisplay__MUIM_DragQuery(cl, obj, (struct MUIP_DragQuery *)msg);
372 case MUIM_DragDrop: return Pendisplay__MUIM_DragDrop(cl, obj, (struct MUIP_DragDrop *)msg);
373 default: return DoSuperMethodA(cl, obj, msg);
376 BOOPSI_DISPATCHER_END
378 const struct __MUIBuiltinClass _MUI_Pendisplay_desc =
380 MUIC_Pendisplay,
381 MUIC_Area,
382 sizeof(struct Pendisplay_DATA),
383 (void*)Pendisplay_Dispatcher
385 #endif /* ZUNE_BUILTIN_PENDISPLAY */