Added kernel module for starting the usb stack at boot time. It's not activated thoug...
[cake.git] / rom / intuition / frameiclass.c
blob5441858e5a325766eefb9f77234f4109408196e7
1 /*
2 Copyright © 1995-2005, The AROS Development Team. All rights reserved.
3 Copyright © 2001-2003, The MorphOS Development Team. All Rights Reserved.
4 $Id$
5 */
7 #include <exec/types.h>
9 #include <dos/dos.h>
10 #include <dos/dosextens.h>
12 #include <intuition/intuition.h>
13 #include <intuition/intuitionbase.h>
14 #include <intuition/classes.h>
15 #include <intuition/classusr.h>
16 #include <intuition/imageclass.h>
17 #include <intuition/cghooks.h>
18 #include <intuition/icclass.h>
20 #include <graphics/gfxbase.h>
21 #include <graphics/gfxmacros.h>
23 #include <utility/tagitem.h>
24 #include <utility/hooks.h>
26 #include <clib/macros.h>
28 #include <proto/exec.h>
29 #include <proto/intuition.h>
30 #include <proto/graphics.h>
31 #include <proto/utility.h>
33 #ifndef __MORPHOS__
34 #include "intuition_intern.h"
35 #include <aros/asmcall.h>
36 #include <proto/alib.h>
37 #include "gadgets.h"
38 #endif /* !__MORPHOS__ */
40 #define DEBUG_IFRAME(x) ;
42 /****************************************************************************/
44 /* Some handy transparent base class object casting defines.
46 #define IM(o) ((struct Image *)o)
48 /****************************************************************************/
50 #undef IntuitionBase
51 #define IntuitionBase ((struct IntuitionBase *)(cl->cl_UserData))
53 /****************************************************************************/
55 /* This is utility function used by frameiclass to draw a simple
56 * bevel.
58 static void DrawFrame(Class * cl, struct RastPort *rport, UWORD shine, UWORD shadow,
59 WORD left, WORD top, WORD width, WORD height, BOOL thicken)
62 Here we attempt to render a bevel as quickly as possible using
63 as few system calls as possible. Note the ORDER of the rendering
64 and pen (or lack of) setting in important. This routine can be
65 useful alone as a basis for GadTools DrawBevelBox() perhaps, but
66 its real function is rendering the frameiclass components for the
67 various supported styles.
69 It should be futher noted, on the native Amiga chipset, rendering
70 bevels via serious of RectFill()'s is potentially as much as two
71 times faster. However, in the case of AROS the implementation
72 of the graphics drivers would ofcourse be the determining factor.
73 Just as on the native OS, 3rd party gfx boards would be a factor.
75 Additionally, if the frame metrics are changed here for whatever
76 reasons, you MUST also compensate the change in the frame class
77 render method, and framebox specifically the offset values.
80 DEBUG_IFRAME(dprintf("drawframe: width %ld height %ld\n",width,height));
82 height -= 1;
83 width -= 1;
85 /* Top/Left */
86 SetABPenDrMd(rport, shine, 0, JAM1);
87 Move(rport, left, top + height);
88 Draw(rport, left, top);
89 Draw(rport, left + width, top);
91 /* Bottom/Right */
92 SetAPen(rport, shadow);
93 Draw(rport, left + width, top + height);
94 Draw(rport, left + 1, top + height);
96 if (thicken)
98 if (FRAME_SIZE == 1)
100 /* Thicken Right Side */
101 Move(rport, left + width - 1, top + height - 1);
102 Draw(rport, left + width - 1, top + 1);
104 /* Thicken Left Side */
105 SetAPen(rport, shine);
106 Move(rport, left + 1, top + height - 1);
107 Draw(rport, left + 1, top + 1);
109 else if (FRAME_SIZE == 2)
111 /* Thicken Right Side */
112 Move(rport, left + width - 1, top + 1);
113 Draw(rport, left + width - 1, top + height - 1);
115 /* Thicken Bottom Side */
116 Draw(rport, left + 2, top + height - 1);
118 /* Thicken Left Side */
119 SetAPen(rport, shine);
121 Move(rport, left + 1, top + height - 1);
122 Draw(rport, left + 1, top + 1);
124 /* Thicken Top Side */
125 Draw(rport, left + width - 2, top + 1);
128 } /* if */
130 } /* DrawFrame */
132 /****************************************************************************/
134 /* frame attribute setting method */
135 static ULONG set_frameiclass(Class *cl, Object *o, struct opSet *msg)
137 struct FrameIData *fid = INST_DATA(cl, o);
139 struct TagItem *tstate = msg->ops_AttrList;
140 struct TagItem *tag;
141 ULONG retval = 0UL;
143 while ((tag = NextTagItem((const struct TagItem **)&tstate)))
145 switch(tag->ti_Tag)
147 case IA_Recessed:
148 fid->fid_Recessed = (BOOL)( tag->ti_Data ? TRUE : FALSE );
149 break;
151 case IA_EdgesOnly:
152 fid->fid_EdgesOnly = (BOOL)( tag->ti_Data ? TRUE : FALSE );
153 break;
155 case IA_FrameType:
157 Data values for IA_FrameType (recognized by FrameIClass)
159 FRAME_DEFAULT: The standard V37-type frame, which has
160 thin edges.
161 FRAME_BUTTON: Standard button gadget frames, having thicker
162 sides and edged corners.
163 FRAME_RIDGE: A ridge such as used by standard string gadgets.
164 You can recess the ridge to get a groove image.
165 FRAME_ICONDROPBOX: A broad ridge which is the standard imagery
166 for areas in AppWindows where icons may be dropped.
168 fid->fid_FrameType = (WORD)tag->ti_Data;
170 switch(fid->fid_FrameType)
172 case FRAME_DEFAULT:
173 fid->fid_HOffset = fid->fid_VOffset = 1;
174 break;
176 case FRAME_BUTTON:
177 DEBUG_IFRAME(dprintf("draw_frameiclass: FRAME_BUTTON\n"));
178 fid->fid_HOffset = 1;
179 fid->fid_VOffset = 1;
180 break;
182 case FRAME_RIDGE:
183 fid->fid_HOffset = 2;
184 fid->fid_VOffset = 2;
185 break;
187 case FRAME_ICONDROPBOX:
188 fid->fid_HOffset = 3;
189 fid->fid_VOffset = 3;
190 break;
192 } /* switch(fid->fid_FrameType) */
194 if (FRAME_SIZE > 0)
196 fid->fid_HOffset *= 2;
199 if (FRAME_SIZE == 2)
201 fid->fid_VOffset *= 2;
203 break;
205 } /* switch */
207 } /* while */
209 return(retval);
210 } /* set_frameiclass */
212 /****************************************************************************/
214 /* frame render method */
215 static IPTR draw_frameiclass(Class *cl, struct Image *im, struct impDraw *msg, WORD width, WORD height)
217 struct FrameIData *fid = INST_DATA(cl, (Object *)im);
220 Default pen array, this should be globally accessable from
221 all the boopsi objects, unless someone as a better idea...
223 UWORD default_pens[] =
225 1, /* detailPen */
226 0, /* blockPen */
227 1, /* textPen */
228 2, /* shinePen */
229 1, /* shadowPen */
230 3, /* hiFillPen */
231 1, /* hifilltextPen */
232 0, /* backgroundPen */
233 2 /* hilighttextPen */
235 ULONG retval;
237 DEBUG_IFRAME(dprintf("draw_frameiclass: width %ld height %ld\n",width,height));
239 /* we will check the rastport present */
240 if(msg->imp_RPort)
242 UWORD *pens = default_pens;
243 UWORD left, top;
244 UWORD shine, shadow;
245 BOOL selected;
246 struct RastPort *rp = msg->imp_RPort;
247 BYTE oldapen = rp->FgPen;
248 BYTE oldbpen = rp->BgPen;
249 BYTE olddrmd = rp->DrawMode;
251 /* set up our rendering pens */
252 if (msg->imp_DrInfo)
254 pens = msg->imp_DrInfo->dri_Pens;
257 Fall back to mono color bevels if depth is only 1 bitplane.
259 if (msg->imp_DrInfo->dri_Depth == 1)
261 shine = pens[SHADOWPEN];
263 else
265 shine = pens[SHINEPEN];
266 } /* if */
268 else
270 shine = pens[SHINEPEN];
271 } /* if */
273 shadow = pens[SHADOWPEN];
275 switch(msg->imp_State)
277 case IDS_SELECTED:
278 case IDS_INACTIVESELECTED:
279 selected = TRUE;
280 break;
282 default:
283 selected = FALSE;
284 break;
285 } /* switch */
288 I'm so clever :) We want to check if either of selected or
289 recessed is TRUE, and if so, swap the pens. However, if both
290 are true, they effectivly cancel each other out and we do
291 nothing. Rather than two compares against TRUE and an OR of the
292 results, plus the additional check to ignore the case where both
293 are TRUE, we will do an XOR of the bools and check the result.
294 This should prove most efficient too.
297 Recess|select| XOR'd result
298 ------|------|-------
299 0 | 0 | 0
300 ------|------|-------
301 0 | 1 | 1
302 ------|------|-------
303 1 | 0 | 1
304 ------|------|-------
305 1 | 1 | 0
306 ------|------|-------
309 if ( (fid->fid_Recessed ^ selected) != 0 )
311 /* swap pens */
312 UWORD tmp;
314 tmp = shine;
315 shine = shadow;
316 shadow = tmp;
317 } /* if */
319 left = im->LeftEdge + msg->imp_Offset.X;
320 top = im->TopEdge + msg->imp_Offset.Y;
322 DEBUG_IFRAME(dprintf("draw_frameiclass: type %ld height %ld\n",fid->fid_FrameType));
324 switch(fid->fid_FrameType)
326 case FRAME_DEFAULT:
327 DrawFrame(cl, rp, shine, shadow, left, top, width, height, FALSE);
328 break;
330 case FRAME_BUTTON:
331 DrawFrame(cl, rp, shine, shadow, left, top, width, height, TRUE);
332 break;
334 case FRAME_RIDGE:
335 /* render outer pen-inverted thick bevel */
336 DrawFrame(cl, rp, shine, shadow, left, top, width, height, TRUE);
338 /* render inner thick bevel */
339 DrawFrame(cl, rp, shadow, shine,
340 left + fid->fid_HOffset / 2, top + fid->fid_VOffset / 2,
341 width - fid->fid_HOffset, height - fid->fid_VOffset,
342 TRUE);
343 break;
345 case FRAME_ICONDROPBOX:
347 WORD hoffset = fid->fid_HOffset * 2 / 3;
348 WORD voffset = fid->fid_VOffset * 2 / 3;
350 /* render outer pen-inverted thick bevel */
351 DrawFrame(cl, rp, shine, shadow, left, top, width, height, TRUE);
353 /* render inner thick bevel */
354 DrawFrame(cl, rp, shadow, shine, left + hoffset, top + voffset,
355 width - hoffset * 2, height - voffset * 2, TRUE);
356 break;
359 } /* switch */
361 if(!fid->fid_EdgesOnly)
363 if(selected)
365 SetABPenDrMd(rp, pens[FILLPEN], pens[BACKGROUNDPEN], JAM1);
367 else
369 SetABPenDrMd(rp, pens[BACKGROUNDPEN], pens[BACKGROUNDPEN], JAM1);
370 } /* if */
372 RectFill(rp,
373 left + fid->fid_HOffset,
374 top + fid->fid_VOffset,
375 left + width - fid->fid_HOffset - 1,
376 top + height - fid->fid_VOffset - 1);
378 } /* if */
380 switch(msg->imp_State)
382 case IDS_DISABLED:
383 case IDS_INACTIVEDISABLED:
384 case IDS_SELECTEDDISABLED:
385 RenderDisabledPattern(rp,
386 msg->imp_DrInfo,
387 left,
388 top,
389 left + width - 1,
390 top + height - 1,
391 IntuitionBase);
392 break;
395 SetABPenDrMd(rp, oldapen, oldbpen, olddrmd);
397 retval = 1UL;
399 else
401 /* return failure */
402 retval = 0UL;
403 } /* if */
405 return retval;
406 } /* draw_frameiclass */
409 /****************************************************************************/
411 /* frameiclass framebox method */
412 IPTR FrameIClass__IM_FRAMEBOX(Class *cl, Object *o, struct impFrameBox *msg)
414 struct FrameIData *fid = INST_DATA(cl, o);
416 /* stegerg: the RKRM docs seem to be wrong. source box (around which
417 the frame goes) is imp_ContentsBox and dest box filled in by
418 this method is imp_FrameBox. */
420 DEBUG_IFRAME(dprintf("framebox_frameiclass: Contents Left %ld Top %ld Width %ld Height %ld\n",
421 msg->imp_ContentsBox->Left,
422 msg->imp_ContentsBox->Top,
423 msg->imp_ContentsBox->Width,
424 msg->imp_ContentsBox->Height));
426 DEBUG_IFRAME(dprintf("framebox_frameiclass: Flags 0x%lx\n",
427 msg->imp_FrameFlags));
429 if (msg->imp_FrameFlags & FRAMEF_SPECIFY)
431 msg->imp_FrameBox->Left = msg->imp_ContentsBox->Left +
432 (msg->imp_ContentsBox->Width - msg->imp_FrameBox->Width) / 2;
433 msg->imp_FrameBox->Top = msg->imp_ContentsBox->Top +
434 (msg->imp_ContentsBox->Height - msg->imp_FrameBox->Height) / 2;
436 else
438 msg->imp_FrameBox->Left = msg->imp_ContentsBox->Left - fid->fid_HOffset;
439 msg->imp_FrameBox->Top = msg->imp_ContentsBox->Top - fid->fid_VOffset;
440 msg->imp_FrameBox->Width = msg->imp_ContentsBox->Width + fid->fid_HOffset * 2;
441 msg->imp_FrameBox->Height = msg->imp_ContentsBox->Height + fid->fid_VOffset * 2;
442 } /* if */
444 DEBUG_IFRAME(dprintf("framebox_frameiclass: Left %ld Top %ld Width %ld Height %ld\n",
445 msg->imp_FrameBox->Left,
446 msg->imp_FrameBox->Top,
447 msg->imp_FrameBox->Width,
448 msg->imp_FrameBox->Height));
450 return (IPTR)1;
451 } /* framebox_frameiclass */
453 IPTR FrameIClass__OM_SET(Class *cl, Object *o, struct opSet *msg)
455 DEBUG_IFRAME(dprintf("dispatch_frameiclass: set\n"));
456 return DoSuperMethodA(cl, o, (Msg)msg) + (IPTR)set_frameiclass(cl, o, msg);
459 IPTR FrameIClass__OM_NEW(Class *cl, Object *o, struct opSet *msg)
461 DEBUG_IFRAME(dprintf("dispatch_frameiclass: new\n"));
463 o = (Object *)DoSuperMethodA(cl, o, (Msg)msg);
464 if (o)
466 struct FrameIData *fid = INST_DATA(cl, o);
468 /* set some defaults */
469 fid->fid_EdgesOnly = FALSE;
470 fid->fid_Recessed = FALSE;
471 fid->fid_FrameType = FRAME_DEFAULT;
472 fid->fid_HOffset = 1;
473 fid->fid_VOffset = 1;
475 /* Handle our special tags - overrides defaults */
476 set_frameiclass(cl, o, msg);
479 return (IPTR)o;
482 IPTR FrameIClass__IM_DRAWFRAME(Class *cl, struct Image *im, struct impDraw *msg)
484 DEBUG_IFRAME(dprintf("dispatch_frameiclass: drawframe Width %ld Height %ld\n", msg->imp_Dimensions.Width, msg->imp_Dimensions.Height));
485 return draw_frameiclass(cl, im, msg, msg->imp_Dimensions.Width, msg->imp_Dimensions.Height);
488 IPTR FrameIClass__IM_DRAW(Class *cl, struct Image *im, struct impDraw *msg)
490 DEBUG_IFRAME(dprintf("dispatch_frameiclass: draw Width %ld Height %ld\n",im->Width, im->Height));
491 return draw_frameiclass(cl, im, msg, im->Width, im->Height);