- Update the pen in OM_SET before calling the supermethod. Otherwise,
[AROS.git] / workbench / libs / muimaster / classes / pendisplay.c
blob0d2485645d3a571ec9e1bcb2de8b10d5fc33bc5b
1 /*
2 Copyright © 2002-2015, 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 struct TagItem *tags;
40 struct TagItem *tag;
42 obj = (Object *) DoSuperMethodA(cl, obj, (Msg) msg);
43 if (!obj)
44 return FALSE;
46 data = INST_DATA(cl, obj);
48 /* Format identifiers need to be long enforced because of RawDoFmt()
49 * limits */
50 snprintf(data->penspec.ps_buf, sizeof(data->penspec.ps_buf), "%lc%d",
51 (int)PST_MUI, (int)MPEN_TEXT);
52 data->pen = -1;
54 /* parse initial taglist */
55 for (tags = msg->ops_AttrList; (tag = NextTagItem(&tags));)
57 switch (tag->ti_Tag)
59 case MUIA_Pendisplay_Reference:
60 data->refobj = (Object *) tag->ti_Data;
61 DoMethod(data->refobj, MUIM_Notify, MUIA_Pendisplay_Spec,
62 MUIV_EveryTime, (IPTR) obj, 3, MUIM_Set,
63 MUIA_Pendisplay_Spec, MUIV_TriggerValue);
64 break;
66 case MUIA_Pendisplay_RGBcolor:
68 struct MUI_RGBcolor *rgb =
69 (struct MUI_RGBcolor *)tag->ti_Data;
70 snprintf(data->penspec.ps_buf, sizeof(data->penspec.ps_buf),
71 "%lc%08x,%08x,%08x", (int)PST_RGB,
72 (unsigned int)rgb->red, (unsigned int)rgb->green,
73 (unsigned int)rgb->blue);
75 break;
77 case MUIA_Pendisplay_Spec:
78 data->penspec = *(struct MUI_PenSpec *)tag->ti_Data;
79 break;
84 return (IPTR) obj;
87 IPTR Pendisplay__OM_DISPOSE(struct IClass *cl, Object *obj, Msg msg)
89 struct Pendisplay_DATA *data;
91 data = INST_DATA(cl, obj);
92 if (data->refobj)
94 /* kill notify here? But refobj might already have been killed :-\ */
97 return DoSuperMethodA(cl, obj, msg);
100 IPTR Pendisplay__OM_SET(struct IClass *cl, Object *obj,
101 struct opSet *msg)
103 struct Pendisplay_DATA *data;
104 struct TagItem *tags;
105 struct TagItem *tag;
106 BOOL newcol = FALSE;
107 IPTR retval;
108 struct TagItem extra_tags[] = {{TAG_IGNORE, 0}, {TAG_IGNORE, 0},
109 {TAG_IGNORE, 0}, {TAG_MORE, (IPTR)msg->ops_AttrList}};
111 data = INST_DATA(cl, obj);
113 for (tags = msg->ops_AttrList; (tag = NextTagItem(&tags));)
115 switch (tag->ti_Tag)
117 case MUIA_Pendisplay_Reference:
118 if (data->refobj)
120 DoMethod(data->refobj, MUIM_KillNotifyObj,
121 MUIA_Pendisplay_Spec, (IPTR) obj);
124 data->refobj = (Object *) tag->ti_Data;
126 if (data->refobj)
128 DoMethod(data->refobj, MUIM_Notify, MUIA_Pendisplay_Spec,
129 MUIV_EveryTime, (IPTR) obj, 3, MUIM_Set,
130 MUIA_Pendisplay_Spec, MUIV_TriggerValue);
132 newcol = TRUE;
133 extra_tags[0].ti_Tag = MUIA_Pendisplay_Pen;
134 extra_tags[1].ti_Tag = MUIA_Pendisplay_RGBcolor;
135 extra_tags[2].ti_Tag = MUIA_Pendisplay_Spec;
136 break;
138 case MUIA_Pendisplay_RGBcolor:
140 struct MUI_RGBcolor *rgb =
141 (struct MUI_RGBcolor *)tag->ti_Data;
143 snprintf(data->penspec.ps_buf, sizeof(data->penspec.ps_buf),
144 "%lc%08x,%08x,%08x", (int)PST_RGB,
145 (unsigned int)rgb->red, (unsigned int)rgb->green,
146 (unsigned int)rgb->blue);
148 newcol = TRUE;
149 extra_tags[0].ti_Tag = MUIA_Pendisplay_Pen;
150 extra_tags[2].ti_Tag = MUIA_Pendisplay_Spec;
151 break;
153 case MUIA_Pendisplay_Spec:
154 if (tag->ti_Data)
156 data->penspec = *(struct MUI_PenSpec *)tag->ti_Data;
157 newcol = TRUE;
159 extra_tags[0].ti_Tag = MUIA_Pendisplay_Pen;
160 extra_tags[1].ti_Tag = MUIA_Pendisplay_RGBcolor;
161 break;
167 if (newcol && (_flags(obj) & MADF_SETUP))
169 if (data->pen != -1)
171 MUI_ReleasePen(muiRenderInfo(obj), data->pen);
172 data->pen = -1;
175 if (!data->refobj)
177 data->pen =
178 MUI_ObtainPen(muiRenderInfo(obj), &data->penspec, 0);
181 MUI_Redraw(obj, MADF_DRAWUPDATE);
183 if (data->pen != -1)
184 GetRGB32(muiRenderInfo(obj)->mri_Colormap, data->pen & 0xffff, 1,
185 (ULONG *)&data->rgb);
186 else
187 extra_tags[1].ti_Tag = TAG_IGNORE;
189 /* Prepare notification values for attributes affected by pen change */
190 extra_tags[0].ti_Data = data->pen & 0xffff;
191 extra_tags[1].ti_Data = (IPTR) &data->rgb;
192 extra_tags[2].ti_Data = (IPTR) &data->penspec;
193 msg->ops_AttrList = extra_tags;
196 retval = DoSuperMethodA(cl, obj, (Msg) msg);
198 return retval;
201 IPTR Pendisplay__OM_GET(struct IClass *cl, Object *obj,
202 struct opGet *msg)
204 struct Pendisplay_DATA *data = INST_DATA(cl, obj);
205 IPTR *store = msg->opg_Storage;
207 /* Redirect queries to the object we reference, if any */
208 if (data->refobj != NULL && msg->opg_AttrID != MUIA_Pendisplay_Reference)
209 return DoMethodA(data->refobj, (Msg) msg);
211 switch (msg->opg_AttrID)
213 case MUIA_Pendisplay_Pen:
214 *store = (IPTR) data->pen & 0xffff;
215 break;
217 case MUIA_Pendisplay_Reference:
218 *store = (IPTR) data->refobj;
219 break;
221 case MUIA_Pendisplay_RGBcolor:
223 struct MUI_PenSpec_intern intpenspec;
224 zune_pen_spec_to_intern(&data->penspec, &intpenspec);
226 switch (intpenspec.p_type)
228 case PST_MUI:
229 case PST_CMAP:
230 case PST_SYS:
231 GetRGB32(muiRenderInfo(obj)->mri_Colormap,
232 data->pen & 0xffff, 1, (ULONG *)&data->rgb);
233 break;
234 case PST_RGB:
235 data->rgb = intpenspec.p_rgb;
236 break;
239 if (data->pen != -1)
240 *store = (IPTR) &data->rgb;
241 else
242 return FALSE;
244 break;
246 case MUIA_Pendisplay_Spec:
247 *store = (IPTR) &data->penspec;
248 break;
250 default:
251 return DoSuperMethodA(cl, obj, (Msg) msg);
254 return TRUE;
257 IPTR Pendisplay__MUIM_Setup(struct IClass *cl, Object *obj,
258 struct MUIP_Setup *msg)
260 struct Pendisplay_DATA *data = INST_DATA(cl, obj);
262 if (!(DoSuperMethodA(cl, obj, (Msg) msg)))
263 return 0;
265 if (!data->refobj)
267 data->pen = MUI_ObtainPen(muiRenderInfo(obj), &data->penspec, 0);
270 return 1;
273 IPTR Pendisplay__MUIM_Cleanup(struct IClass *cl, Object *obj,
274 struct MUIP_Cleanup *msg)
276 struct Pendisplay_DATA *data = INST_DATA(cl, obj);
278 if (data->pen != -1)
280 MUI_ReleasePen(muiRenderInfo(obj), data->pen);
281 data->pen = -1;
284 return DoSuperMethodA(cl, obj, (Msg) msg);
287 IPTR Pendisplay__MUIM_AskMinMax(struct IClass *cl, Object *obj,
288 struct MUIP_AskMinMax *msg)
290 DoSuperMethodA(cl, obj, (Msg) msg);
292 msg->MinMaxInfo->MinWidth += 3;
293 msg->MinMaxInfo->MinHeight += 3;
294 msg->MinMaxInfo->DefWidth += 16;
295 msg->MinMaxInfo->DefHeight += 16;
296 msg->MinMaxInfo->MaxWidth = MUI_MAXMAX;
297 msg->MinMaxInfo->MaxHeight = MUI_MAXMAX;
299 return 0;
302 IPTR Pendisplay__MUIM_Draw(struct IClass *cl, Object *obj,
303 struct MUIP_Draw *msg)
305 struct Pendisplay_DATA *data = INST_DATA(cl, obj);
306 LONG color;
308 DoSuperMethodA(cl, obj, (Msg) msg);
310 if (!(msg->flags & (MADF_DRAWOBJECT | MADF_DRAWUPDATE)))
311 return FALSE;
313 if (data->refobj)
315 IPTR val = 0;
317 get(data->refobj, MUIA_Pendisplay_Pen, &val);
318 color = (LONG) val;
320 else
322 color = data->pen;
325 if (color == -1)
327 static UWORD pat[] = { 0x1111, 0x2222, 0x4444, 0x8888 };
329 SetAfPt(_rp(obj), pat, 2);
330 SetABPenDrMd(_rp(obj), _pens(obj)[MPEN_SHADOW],
331 _pens(obj)[MPEN_BACKGROUND], JAM2);
334 else
336 SetABPenDrMd(_rp(obj), MUIPEN(color), 0, JAM1);
339 RectFill(_rp(obj), _mleft(obj), _mtop(obj), _mright(obj),
340 _mbottom(obj));
342 SetAfPt(_rp(obj), NULL, 0);
344 return 0;
347 IPTR Pendisplay__MUIM_Pendisplay_SetColormap(struct IClass *cl,
348 Object *obj, struct MUIP_Pendisplay_SetColormap *msg)
350 struct MUI_PenSpec penspec;
352 snprintf(penspec.ps_buf, sizeof(penspec.ps_buf), "%lc%d", (int)PST_CMAP,
353 (int)msg->colormap);
354 set(obj, MUIA_Pendisplay_Spec, (IPTR) &penspec);
356 return 0;
359 IPTR Pendisplay__MUIM_Pendisplay_SetRGB(struct IClass *cl, Object *obj,
360 struct MUIP_Pendisplay_SetRGB *msg)
362 struct MUI_PenSpec penspec;
364 snprintf(penspec.ps_buf, sizeof(penspec.ps_buf), "%lc%08x,%08x,%08x",
365 (int)PST_RGB, (unsigned int)msg->r, (unsigned int)msg->g,
366 (unsigned int)msg->b);
367 set(obj, MUIA_Pendisplay_Spec, (IPTR) &penspec);
369 return 0;
372 IPTR Pendisplay__MUIM_Pendisplay_SetMUIPen(struct IClass *cl, Object *obj,
373 struct MUIP_Pendisplay_SetMUIPen *msg)
375 struct MUI_PenSpec penspec;
377 snprintf(penspec.ps_buf, sizeof(penspec.ps_buf), "%lc%d", (int)PST_MUI,
378 (int)msg->muipen);
379 set(obj, MUIA_Pendisplay_Spec, (IPTR) &penspec);
381 return 0;
384 IPTR Pendisplay__MUIM_DragQuery(struct IClass *cl, Object *obj,
385 struct MUIP_DragQuery *msg)
387 STRPTR spec = NULL;
389 if (msg->obj == obj)
390 return MUIV_DragQuery_Refuse;
392 if (get(msg->obj, MUIA_Pendisplay_Spec, &spec))
393 return MUIV_DragQuery_Accept;
395 if (get(msg->obj, MUIA_Imagedisplay_Spec, &spec))
397 if ((NULL != spec) && (strlen(spec) > 2) && (spec[0] == '2')
398 && (spec[1] == ':'))
399 return MUIV_DragQuery_Accept;
402 return MUIV_DragQuery_Refuse;
405 IPTR Pendisplay__MUIM_DragDrop(struct IClass *cl, Object *obj,
406 struct MUIP_DragDrop *msg)
408 STRPTR spec = NULL;
410 if (get(msg->obj, MUIA_Pendisplay_Spec, &spec))
411 set(obj, MUIA_Pendisplay_Spec, spec);
412 else if (get(msg->obj, MUIA_Imagedisplay_Spec, &spec))
413 set(obj, MUIA_Pendisplay_Spec, spec + 2);
414 return 0;
417 #if ZUNE_BUILTIN_PENDISPLAY
418 BOOPSI_DISPATCHER(IPTR, Pendisplay_Dispatcher, cl, obj, msg)
420 switch (msg->MethodID)
422 case OM_NEW:
423 return Pendisplay__OM_NEW(cl, obj, (struct opSet *)msg);
424 case OM_DISPOSE:
425 return Pendisplay__OM_DISPOSE(cl, obj, msg);
426 case OM_SET:
427 return Pendisplay__OM_SET(cl, obj, (struct opSet *)msg);
428 case OM_GET:
429 return Pendisplay__OM_GET(cl, obj, (struct opGet *)msg);
430 case MUIM_Setup:
431 return Pendisplay__MUIM_Setup(cl, obj, (struct MUIP_Setup *)msg);
432 case MUIM_Cleanup:
433 return Pendisplay__MUIM_Cleanup(cl, obj,
434 (struct MUIP_Cleanup *)msg);
435 case MUIM_AskMinMax:
436 return Pendisplay__MUIM_AskMinMax(cl, obj,
437 (struct MUIP_AskMinMax *)msg);
438 case MUIM_Draw:
439 return Pendisplay__MUIM_Draw(cl, obj, (struct MUIP_Draw *)msg);
440 case MUIM_Pendisplay_SetColormap:
441 return Pendisplay__MUIM_Pendisplay_SetColormap(cl, obj,
442 (struct MUIP_Pendisplay_SetColormap *)msg);
443 case MUIM_Pendisplay_SetMUIPen:
444 return Pendisplay__MUIM_Pendisplay_SetMUIPen(cl, obj,
445 (struct MUIP_Pendisplay_SetMUIPen *)msg);
446 case MUIM_Pendisplay_SetRGB:
447 return Pendisplay__MUIM_Pendisplay_SetRGB(cl, obj,
448 (struct MUIP_Pendisplay_SetRGB *)msg);
449 case MUIM_DragQuery:
450 return Pendisplay__MUIM_DragQuery(cl, obj,
451 (struct MUIP_DragQuery *)msg);
452 case MUIM_DragDrop:
453 return Pendisplay__MUIM_DragDrop(cl, obj,
454 (struct MUIP_DragDrop *)msg);
455 default:
456 return DoSuperMethodA(cl, obj, msg);
459 BOOPSI_DISPATCHER_END
461 const struct __MUIBuiltinClass _MUI_Pendisplay_desc =
463 MUIC_Pendisplay,
464 MUIC_Area,
465 sizeof(struct Pendisplay_DATA),
466 (void *) Pendisplay_Dispatcher
468 #endif /* ZUNE_BUILTIN_PENDISPLAY */