Safer handling of Booleans.
[AROS.git] / workbench / libs / muimaster / mui_redraw.c
blobc7f1a0d595d32cb565cac25cc790cd0721da14bc
1 /*
2 Copyright © 2003-2012, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <string.h>
7 #include <clib/alib_protos.h>
8 #include <intuition/classusr.h>
9 #include <graphics/gfxmacros.h>
10 #include <cybergraphx/cybergraphics.h>
11 #include <proto/graphics.h>
12 #include <proto/intuition.h>
13 #include <proto/muimaster.h>
14 #include <proto/cybergraphics.h>
16 #include "muimaster_intern.h"
17 #include "mui.h"
18 #include "support.h"
20 #include "debug.h"
22 /*****************************************************************************
24 NAME */
25 AROS_LH2(VOID, MUI_Redraw,
27 /* SYNOPSIS */
28 AROS_LHA(Object *, obj, A0),
29 AROS_LHA(ULONG, flags, D0),
31 /* LOCATION */
32 struct Library *, MUIMasterBase, 17, MUIMaster)
34 /* FUNCTION
36 INPUTS
38 RESULT
40 NOTES
42 EXAMPLE
44 BUGS
46 SEE ALSO
48 INTERNALS
50 *****************************************************************************/
52 AROS_LIBFUNC_INIT
54 APTR clip = (APTR)-1;
55 IPTR disabled = 0;
57 if (!(_flags(obj) & MADF_CANDRAW)) return;
59 if (_flags(obj) & MADF_INVIRTUALGROUP)
61 Object *wnd = NULL;
62 Object *parent;
63 struct Region *region = NULL;
65 get(obj,MUIA_WindowObject,&wnd);
66 parent = obj;
68 while (get(parent,MUIA_Parent,&parent))
70 if (!parent) break;
71 if (parent == wnd) break;
73 if (_flags(parent) & MADF_ISVIRTUALGROUP)
75 struct Rectangle rect;
77 rect.MinX = _mleft(parent);
78 rect.MinY = _mtop(parent);
79 rect.MaxX = _mright(parent);
80 rect.MaxY = _mbottom(parent);
82 if (!region)
84 if ((region = NewRegion()))
86 OrRectRegion(region, &rect);
88 } else
90 AndRectRegion(region, &rect);
95 if (region)
97 clip = MUI_AddClipRegion(muiRenderInfo(obj),region);
100 } /* if object is in a virtual group */
102 if (1)
104 struct Region *region;
105 struct Rectangle *clip_rect;
106 struct Layer *l;
108 clip_rect = &muiRenderInfo(obj)->mri_ClipRect;
110 if (muiRenderInfo(obj)->mri_Window)
112 l = muiRenderInfo(obj)->mri_Window->WLayer;
114 else
116 l = muiRenderInfo(obj)->mri_RastPort->Layer;
119 if (l && (region = l->ClipRegion))
121 /* Maybe this should went to MUI_AddClipRegion() */
122 clip_rect->MinX = MAX(_left(obj),region->bounds.MinX);
123 clip_rect->MinY = MAX(_top(obj),region->bounds.MinY);
124 clip_rect->MaxX = MIN(_right(obj),region->bounds.MaxX);
125 clip_rect->MaxY = MIN(_bottom(obj),region->bounds.MaxY);
127 } else
129 clip_rect->MinX = _left(obj);
130 clip_rect->MinY = _top(obj);
131 clip_rect->MaxX = _right(obj);
132 clip_rect->MaxY = _bottom(obj);
136 _flags(obj) = (_flags(obj) & ~MADF_DRAWFLAGS) | (flags & MADF_DRAWFLAGS);
138 DoMethod(obj, MUIM_Draw, 0);
140 if (get(obj, MUIA_Disabled, &disabled))
142 #if 0
144 Commented out, because group children were drawn wrongly
145 when they have been disabled while window is open.
147 if (_parent(obj))
149 IPTR parentDisabled;
150 if (get(_parent(obj), MUIA_Disabled, &parentDisabled))
152 /* Let the parent draw the pattern... */
153 if (parentDisabled) disabled = FALSE;
156 #endif
158 if (disabled)
160 #ifdef __AROS__
161 #if 0
163 This aproach might be faster *provided* that the buffer is
164 allocated and filled *once* at startup of muimaster.library.
166 In reality, the WritePixelArray() call has quite a big
167 overhead, so you should only use this buffer if the gadget
168 completely fits inside, and fall back to allocating a new
169 buffer if the gadget is too big.
171 Perhaps a future optimization...
173 LONG width = 200;
174 LONG height = 100;
175 LONG *buffer = AllocVec(width * height * sizeof(LONG), MEMF_ANY);
176 LONG x, y;
178 memset(buffer, 0xAA, width * height * sizeof(LONG));
180 for (y = 0; y < _height(obj); y += height)
182 for (x = 0; x < _width(obj); x += width)
184 WritePixelArrayAlpha
186 buffer, 0, 0, width * sizeof(LONG),
187 _rp(obj), _left(obj) + x, _top(obj) + y,
188 x + width > _width(obj) ? _width(obj) - x : width,
189 y + height > _height(obj) ? _height(obj) - y : height,
190 0xffffffff
194 #else
195 LONG width = _width(obj);
196 LONG height = _height(obj);
197 LONG *buffer = NULL;
199 if (GetBitMapAttr(_rp(obj)->BitMap, BMA_DEPTH) >= 15)
201 buffer = AllocVec(width * sizeof(LONG), MEMF_ANY);
204 if (buffer != NULL)
206 memset(buffer, 0xAA, width * sizeof(LONG));
208 WritePixelArrayAlpha
210 buffer, 0, 0, 0,
211 _rp(obj), _left(obj), _top(obj), width, height,
212 0xffffffff
214 FreeVec(buffer);
215 } else
216 #endif
217 #endif
219 /* fallback */
220 const static UWORD pattern[] = { 0x8888, 0x2222, };
221 LONG fg = muiRenderInfo(obj)->mri_Pens[MPEN_SHADOW];
223 SetDrMd(_rp(obj), JAM1);
224 SetAPen(_rp(obj), fg);
225 SetAfPt(_rp(obj), pattern, 1);
226 RectFill(_rp(obj), _left(obj), _top(obj), _right(obj),
227 _bottom(obj));
228 SetAfPt(_rp(obj), NULL, 0);
231 } /* if (object is disabled) */
233 /* copy buffer to window */
234 if (muiRenderInfo(obj)->mri_BufferBM)
236 ClipBlit(&muiRenderInfo(obj)->mri_BufferRP, _left(obj), _top(obj),
237 muiRenderInfo(obj)->mri_Window->RPort, _left(obj), _top(obj),
238 _width(obj), _height(obj), 0xc0);
241 if (clip != (APTR)-1)
243 /* This call actually also frees the region */
244 MUI_RemoveClipRegion(muiRenderInfo(obj), clip);
247 AROS_LIBFUNC_EXIT
249 } /* MUIA_Redraw */