Enable VFP unit as early as possible. This has to be so since e.g. gcc9 uses vfp...
[AROS.git] / rom / intuition / sysiclass.c
blobe62387bb6f4ab21ecadecdff41037d4ddeac217b
1 /*
2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
3 Copyright © 2001-2003, The MorphOS Development Team. All Rights Reserved.
4 $Id$
5 */
7 /**************************************************************************************************/
9 #include <exec/types.h>
11 #include <proto/intuition.h>
12 #include <proto/layers.h>
13 #include <intuition/classes.h>
14 #include <intuition/classusr.h>
15 #include <intuition/imageclass.h>
16 #include <intuition/windecorclass.h>
17 #include <intuition/scrdecorclass.h>
18 #include <intuition/intuition.h>
19 #include <intuition/intuitionbase.h>
20 #include <intuition/extensions.h>
21 #include <intuition/screens.h>
23 #include <proto/graphics.h>
24 #include <graphics/rastport.h>
26 #include <proto/utility.h>
27 #include <utility/tagitem.h>
29 #include <proto/alib.h>
31 #include <aros/asmcall.h>
32 #include "intuition_intern.h"
33 #ifdef __MORPHOS__
34 #include "intuition_extend.h"
35 #endif
37 #include "gadgets.h" /* Some handy rendering funtions */
39 #define INTDRI(dri) ((struct IntDrawInfo *)(dri))
41 #if 0
42 extern BYTE *ibPrefs;
43 extern BYTE *ibSnapshot;
44 extern BYTE *ibSnapshotSel;
45 extern BYTE *ibPopupSel;
46 extern BYTE *ibPopup;
47 extern BYTE *ibIconify;
48 extern BYTE *ibIconifySel;
49 extern BYTE *ibLock;
50 extern BYTE *ibLockSel;
51 extern VOID DrawIB(struct RastPort *rp,BYTE *ib,LONG cx,LONG cy,struct IntuitionBase *IntuitionBase);
52 extern void DrawJUMP(struct RastPort *rp,ULONG state,LONG cx,LONG cy,struct IntuitionBase *IntuitionBase);
53 #endif
55 #undef DEBUG
56 #define DEBUG 0
57 #include <aros/debug.h>
59 /**************************************************************************************************/
61 #define DEFSIZE_WIDTH 14
62 #define DEFSIZE_HEIGHT 14
64 /**************************************************************************************************/
66 /* Some handy transparent base class object casting defines.
68 #define IM(o) ((struct Image *)o)
70 static UWORD getbgpen(ULONG state, UWORD *pens);
71 static UWORD getbgpen_gt(ULONG state, UWORD *pens);
72 static void renderimageframe(struct RastPort *rp, ULONG which, ULONG state, UWORD *pens,
73 WORD left, WORD top, WORD width, WORD height,
74 struct IntuitionBase *IntuitionBase);
76 /**************************************************************************************************/
78 #define SYSIFLG_GADTOOLS 1
79 #define SYSIFLG_NOBORDER 2
81 /**************************************************************************************************/
83 /* Some handy drawing functions */
85 void draw_thick_line(Class *cl, struct RastPort *rport,
86 LONG x1, LONG y1, LONG x2, LONG y2,
87 UWORD thickness)
89 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
90 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
91 Move(rport, x1, y1);
92 Draw(rport, x2, y2);
93 /* Georg Steger */
94 Move(rport, x1 + 1, y1);
95 Draw(rport, x2 + 1, y2);
98 /**************************************************************************************************/
100 BOOL sysi_setnew(Class *cl, Object *obj, struct opSet *msg)
102 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
103 struct Library *UtilityBase = GetPrivIBase(IntuitionBase)->UtilityBase;
104 struct SysIData *data = INST_DATA(cl, obj);
105 struct TagItem *taglist, *tag;
106 struct TextFont *reffont = NULL;
107 int size = SYSISIZE_MEDRES;
108 BOOL unsupported = FALSE;
109 BOOL set_width = FALSE, set_height = FALSE;
111 taglist = msg->ops_AttrList;
112 while ((tag = NextTagItem(&taglist)))
114 switch(tag->ti_Tag)
116 case IA_Width:
117 set_width = TRUE;
118 break;
120 case IA_Height:
121 set_height = TRUE;
122 break;
124 case SYSIA_DrawInfo:
125 data->dri = (struct DrawInfo *)tag->ti_Data;
126 reffont = data->dri->dri_Font;
127 break;
129 case SYSIA_Which:
130 data->type = tag->ti_Data;
132 D(bug("SYSIA_Which type: %d\n", data->type));
134 switch (tag->ti_Data)
136 // FIXME: if IA_Width, IA_Height was not specified sysiclass should choose size depending on drawinfo (screen resolution)"
138 case LEFTIMAGE:
139 case UPIMAGE:
140 case RIGHTIMAGE:
141 case DOWNIMAGE:
142 case CHECKIMAGE:
143 case MXIMAGE:
144 case DEPTHIMAGE:
145 case SDEPTHIMAGE:
146 case ZOOMIMAGE:
147 case CLOSEIMAGE:
148 case SIZEIMAGE:
149 case MENUCHECK:
150 case AMIGAKEY:
151 case ICONIFYIMAGE:
152 case LOCKIMAGE:
153 case JUMPIMAGE:
154 case MUIIMAGE:
155 case POPUPIMAGE:
156 case SNAPSHOTIMAGE:
157 case SUBMENUIMAGE:
158 break;
160 default:
161 unsupported = TRUE;
162 break;
164 break;
166 case SYSIA_ReferenceFont:
167 if (tag->ti_Data) reffont = (struct TextFont *)tag->ti_Data;
168 break;
170 case SYSIA_Size:
171 size = tag->ti_Data;
172 break;
174 /* private tags */
176 case SYSIA_WithBorder:
177 if (!tag->ti_Data)
179 data->flags |= SYSIFLG_NOBORDER;
181 break;
183 case SYSIA_Style:
184 if (tag->ti_Data == SYSISTYLE_GADTOOLS)
186 data->flags |= SYSIFLG_GADTOOLS;
188 break;
190 } /* switch(tag->ti_Tag) */
192 } /* while ((tag = NextTagItem(&taglist))) */
194 D(bug("dri: %p, unsupported: %d version: %d\n", data->dri, unsupported, data->dri->dri_Version));
196 if ((!data->dri) || (unsupported) || (data->dri->dri_Version != DRI_VERSION))
197 return FALSE;
200 ULONG width = DEFSIZE_WIDTH, height = DEFSIZE_HEIGHT;
202 BOOL tc = (data->dri->dri_Flags & DRIF_DIRECTCOLOR) ? TRUE : FALSE;
204 if (data->type == SDEPTHIMAGE)
206 struct sdpGetDefSizeSysImage smsg;
208 smsg.MethodID = SDM_GETDEFSIZE_SYSIMAGE;
209 smsg.sdp_TrueColor = tc;
210 smsg.sdp_Which = data->type;
211 smsg.sdp_SysiSize = size;
212 smsg.sdp_ReferenceFont = reffont;
213 smsg.sdp_Width = &width;
214 smsg.sdp_Height = &height;
215 smsg.sdp_Flags = 0;
216 smsg.sdp_Dri = data->dri;
217 smsg.sdp_UserBuffer = 0;
219 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->ScrDecorObj, (Msg)&smsg);
222 else if ((data->type == AMIGAKEY) || (data->type == MENUCHECK) || (data->type == SUBMENUIMAGE))
224 struct mdpGetDefSizeSysImage mmsg;
226 mmsg.MethodID = MDM_GETDEFSIZE_SYSIMAGE;
227 mmsg.mdp_TrueColor = tc;
228 mmsg.mdp_Which = data->type;
229 mmsg.mdp_SysiSize = size;
230 mmsg.mdp_ReferenceFont = reffont;
231 mmsg.mdp_Width = &width;
232 mmsg.mdp_Height = &height;
233 mmsg.mdp_Flags = 0;
234 mmsg.mdp_Dri = data->dri;
235 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->MenuDecorObj, (Msg)&mmsg);
238 else
240 struct wdpGetDefSizeSysImage wmsg;
242 wmsg.MethodID = WDM_GETDEFSIZE_SYSIMAGE;
243 wmsg.wdp_TrueColor = tc;
244 wmsg.wdp_Which = data->type;
245 wmsg.wdp_SysiSize = size;
246 wmsg.wdp_ReferenceFont = reffont;
247 wmsg.wdp_Width = &width;
248 wmsg.wdp_Height = &height;
249 wmsg.wdp_Flags = 0;
250 wmsg.wdp_Dri = data->dri;
251 wmsg.wdp_UserBuffer = 0;
253 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->WinDecorObj, (Msg)&wmsg);
258 if (!set_width) IM(obj)->Width = width;
259 if (!set_height) IM(obj)->Height = height;
261 #ifdef WIN_GADGETS_KEEP_ASPECT
263 * AROS: This little tweak replaces CreateStdSysImage() function
264 * and keeps aspect rate of the image if only height is supplied.
265 * Currently only OpenScreen() relies on this.
267 if (set_height && (!set_width))
268 IM(obj)->Width = IM(obj)->Height * width / height;
269 #endif
272 return TRUE;
275 /**************************************************************************************************/
277 Object *SysIClass__OM_NEW(Class *cl, Class *rootcl, struct opSet *msg)
279 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
280 struct SysIData *data;
281 Object *obj;
283 D(bug("sysi_new()\n"));
284 obj = (Object *)DoSuperMethodA(cl, (Object *)rootcl, (Msg)msg);
285 if (!obj)
286 return NULL;
288 D(bug("sysi_new,: obj=%p\n", obj));
290 data = INST_DATA(cl, obj);
291 data->type = 0;
292 data->dri = NULL;
293 data->frame = NULL;
294 data->flags = 0;
296 if (!sysi_setnew(cl, obj, (struct opSet *)msg))
298 STACKULONG method = OM_DISPOSE;
299 CoerceMethodA(cl, obj, (Msg)&method);
300 return NULL;
303 D(bug("sysi_setnew called successfully\n"));
305 switch (data->type)
308 case CHECKIMAGE:
310 struct TagItem tags[] =
312 {IA_FrameType, FRAME_BUTTON },
313 {IA_EdgesOnly, FALSE },
314 {TAG_MORE }
317 tags[2].ti_Data = (IPTR)msg->ops_AttrList;
319 data->frame = NewObjectA(NULL, FRAMEICLASS, tags);
320 if (!data->frame)
322 STACKULONG method = OM_DISPOSE;
323 CoerceMethodA(cl, obj, (Msg)&method);
324 return NULL;
326 break;
329 /* Just to prevent it from reaching default: */
330 case MXIMAGE:
331 case LEFTIMAGE:
332 case UPIMAGE:
333 case RIGHTIMAGE:
334 case DOWNIMAGE:
336 case SDEPTHIMAGE:
337 case DEPTHIMAGE:
338 case ZOOMIMAGE:
339 case CLOSEIMAGE:
340 case SIZEIMAGE:
342 case MENUCHECK:
343 case AMIGAKEY:
344 case SUBMENUIMAGE:
345 case ICONIFYIMAGE:
346 case LOCKIMAGE:
347 case MUIIMAGE:
348 case POPUPIMAGE:
349 case SNAPSHOTIMAGE:
350 case JUMPIMAGE:
351 break;
353 default:
355 STACKULONG method = OM_DISPOSE;
357 CoerceMethodA(cl, obj, (Msg)&method);
359 return NULL;
362 return obj;
365 /**************************************************************************************************/
367 /* Georg Steger
369 #define HSPACING 3
370 #define VSPACING 3
371 /* Ralph Schmidt
372 * heuristics for smaller arrows used in apps
373 * like filer
375 #define HSPACING_MIDDLE 2
376 #define VSPACING_MIDDLE 2
377 #define HSPACING_SMALL 1
378 #define VSPACING_SMALL 1
380 IPTR SysIClass__IM_DRAW(Class *cl, Object *obj, struct impDraw *msg)
382 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
383 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
384 struct SysIData *data = INST_DATA(cl, obj);
385 struct RastPort *rport = msg->imp_RPort;
386 struct Window *win = NULL;
387 WORD left = IM(obj)->LeftEdge + msg->imp_Offset.X;
388 WORD top = IM(obj)->TopEdge + msg->imp_Offset.Y;
389 UWORD width = IM(obj)->Width;
390 UWORD height = IM(obj)->Height;
391 WORD right = left + width - 1;
392 WORD bottom = top + height - 1;
393 struct wdpDrawSysImage wdecormsg;
394 struct sdpDrawSysImage sdecormsg;
395 struct mdpDrawSysImage mdecormsg;
397 BOOL tc = (data->dri->dri_Flags & DRIF_DIRECTCOLOR) ? TRUE : FALSE;
399 if (rport) if (rport->Layer) win = (struct Window *) rport->Layer->Window;
401 wdecormsg.MethodID = WDM_DRAW_SYSIMAGE;
402 wdecormsg.wdp_TrueColor = tc;
403 wdecormsg.wdp_RPort = rport;
404 wdecormsg.wdp_X = left;
405 wdecormsg.wdp_Y = top;
406 wdecormsg.wdp_Width = width;
407 wdecormsg.wdp_Height = height;
408 wdecormsg.wdp_Which = data->type;
409 wdecormsg.wdp_State = msg->imp_State;
410 wdecormsg.wdp_Flags = 0;
411 wdecormsg.wdp_Dri = data->dri;
412 wdecormsg.wdp_UserBuffer = (win == NULL) ? 0 : ((struct IntWindow *)win)->DecorUserBuffer;
414 sdecormsg.MethodID = SDM_DRAW_SYSIMAGE;
415 sdecormsg.sdp_TrueColor = tc;
416 sdecormsg.sdp_RPort = rport;
417 sdecormsg.sdp_X = left;
418 sdecormsg.sdp_Y = top;
419 sdecormsg.sdp_Width = width;
420 sdecormsg.sdp_Height = height;
421 sdecormsg.sdp_Which = data->type;
422 sdecormsg.sdp_State = msg->imp_State;
423 sdecormsg.sdp_Flags = 0;
424 sdecormsg.sdp_Dri = data->dri;
425 sdecormsg.sdp_UserBuffer = GetPrivScreen(data->dri->dri_Screen)->DecorUserBuffer;
427 mdecormsg.MethodID = MDM_DRAW_SYSIMAGE;
428 mdecormsg.mdp_TrueColor = tc;
429 mdecormsg.mdp_RPort = rport;
430 mdecormsg.mdp_X = left;
431 mdecormsg.mdp_Y = top;
432 mdecormsg.mdp_Width = width;
433 mdecormsg.mdp_Height = height;
434 mdecormsg.mdp_Which = data->type;
435 mdecormsg.mdp_State = msg->imp_State;
436 mdecormsg.mdp_Flags = 0;
437 mdecormsg.mdp_Dri = data->dri;
438 mdecormsg.mdp_UserBuffer = GetPrivScreen(data->dri->dri_Screen)->DecorUserBuffer;
440 SetDrMd(rport, JAM1);
442 switch(data->type)
444 case CHECKIMAGE:
446 WORD h_spacing = width / 4;
447 WORD v_spacing = height / 4;
449 /* Draw frame */
450 DrawImageState(rport, data->frame,
451 msg->imp_Offset.X, msg->imp_Offset.Y,
452 IDS_NORMAL, data->dri);
454 /* Draw checkmark (only if image is in selected state) */
455 if (msg->imp_State == IDS_SELECTED)
457 left += h_spacing;
458 right -= h_spacing;
459 width -= h_spacing * 2;
460 top += v_spacing;
461 bottom -= v_spacing;
462 height -= v_spacing * 2;
464 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
465 draw_thick_line(cl, rport, left, top + height / 3 , left, bottom, 0);
466 draw_thick_line(cl, rport, left + 1, bottom, right - 1, top, 0);
468 break;
471 case MXIMAGE:
473 BOOL selected = FALSE;
474 WORD col1 = SHINEPEN;
475 WORD col2 = SHADOWPEN;
477 if ((msg->imp_State == IDS_SELECTED) || (msg->imp_State == IDS_INACTIVESELECTED))
479 col1 = SHADOWPEN;
480 col2 = SHINEPEN;
481 selected = TRUE;
484 SetAPen(rport, data->dri->dri_Pens[BACKGROUNDPEN]);
485 RectFill(rport, left, top, right, bottom);
487 #if 0
488 /* THICK MX IMAGE */
490 SetAPen(rport, data->dri->dri_Pens[col1]);
491 RectFill(rport, left + 2, top, right - 3, top + 1);
492 RectFill(rport, left + 1, top + 2, left + 2, top + 3);
493 RectFill(rport, left, top + 4, left + 1, bottom - 4);
494 RectFill(rport, left + 1, bottom - 3, left + 2, bottom - 2);
495 RectFill(rport, left + 2, bottom - 1, left + 2, bottom);
497 SetAPen(rport, data->dri->dri_Pens[col2]);
498 RectFill(rport, right - 2, top, right - 2, top + 1);
499 RectFill(rport, right - 2, top + 2, right - 1, top + 3);
500 RectFill(rport, right - 1, top + 4, right, bottom - 4);
501 RectFill(rport, right - 2, bottom - 3, right - 1, bottom - 2);
502 RectFill(rport, left + 3, bottom - 1, right - 2, bottom);
504 if (selected)
506 left += 4;
507 right -= 4;
508 width -= 8;
509 top += 4;
510 bottom -= 4;
511 height -= 8;
513 SetAPen(rport, data->dri->dri_Pens[FILLPEN]);
514 if ((width >= 3) && (height >= 3))
516 RectFill(rport, left + 1, top, right - 1, top);
517 RectFill(rport, left, top + 1, right, bottom - 1);
518 RectFill(rport, left + 1, bottom, right - 1, bottom);
520 else
522 RectFill(rport, left, top, right, bottom);
525 #else
526 /* THIN MX IMAGE */
528 SetAPen(rport, data->dri->dri_Pens[col1]);
529 RectFill(rport, left + 3, top, right - 3, top);
530 WritePixel(rport, left + 2, top + 1);
531 RectFill(rport, left + 1, top + 2, left + 1, top + 3);
532 RectFill(rport, left, top + 4, left, bottom - 4);
533 RectFill(rport, left + 1, bottom - 3, left + 1, bottom - 2);
534 WritePixel(rport, left + 2, bottom - 1);
536 SetAPen(rport, data->dri->dri_Pens[col2]);
537 WritePixel(rport, right - 2, top + 1);
538 RectFill(rport, right - 1, top + 2, right - 1, top + 3);
539 RectFill(rport, right, top + 4, right, bottom - 4);
540 RectFill(rport, right - 1, bottom - 3, right - 1, bottom - 2);
541 WritePixel(rport, right - 2, bottom - 1);
542 RectFill(rport, left + 3, bottom, right - 3, bottom);
544 if (selected)
546 left += 3;
547 right -= 3;
548 width -= 6;
549 top += 3;
550 bottom -= 3;
551 height -= 6;
553 SetAPen(rport, data->dri->dri_Pens[FILLPEN]);
554 if ((width >= 5) && (height >= 5))
556 RectFill(rport, left, top + 2, left, bottom - 2);
557 RectFill(rport, left + 1, top + 1, left + 1, bottom - 1);
558 RectFill(rport, left + 2, top, right - 2, bottom);
559 RectFill(rport, right - 1, top + 1, right - 1, bottom - 1);
560 RectFill(rport, right, top + 2, right, bottom - 2);
562 else
564 RectFill(rport, left, top, right, bottom);
568 #endif
569 break;
572 case LEFTIMAGE:
574 UWORD hspacing,vspacing;
575 WORD cy;
577 if (!(data->flags & (SYSIFLG_NOBORDER | SYSIFLG_GADTOOLS)))
579 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->WinDecorObj, (Msg)&wdecormsg);
580 break;
583 hspacing = HSPACING;
584 vspacing = VSPACING;
586 if (width <= 12)
588 hspacing = HSPACING_MIDDLE;
591 if (width <= 10)
593 hspacing = HSPACING_SMALL;
596 if (height <= 12)
598 vspacing = VSPACING_MIDDLE;
601 if (height <= 10)
603 vspacing = VSPACING_SMALL;
606 if (!(data->flags & SYSIFLG_NOBORDER))
608 renderimageframe(rport, LEFTIMAGE, msg->imp_State, data->dri->dri_Pens,
609 left, top, width, height, IntuitionBase);
610 left++;
611 top++;
612 right--;
613 bottom--;
614 width -= 2;
615 height -= 2;
617 if (data->flags & SYSIFLG_GADTOOLS)
619 SetAPen(rport, getbgpen_gt(msg->imp_State, data->dri->dri_Pens));
620 RectFill(rport, left, top, right, bottom);
624 if (data->flags & SYSIFLG_GADTOOLS)
626 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
628 cy = height / 2;
630 Move(rport, left + width - 1 - hspacing, top + vspacing + 1);
631 Draw(rport, left + hspacing, top + height - cy);
632 Move(rport, left + width - 1 - hspacing, top + vspacing);
633 Draw(rport, left + hspacing, top + height - cy - 1);
635 Move(rport, left + width - 1 - hspacing, top + height - 1- vspacing - 1);
636 Draw(rport, left + hspacing, top + cy - 1);
637 Move(rport, left + width - 1 - hspacing, top + height - 1 - vspacing);
638 Draw(rport, left + hspacing, top + cy);
640 else
642 WORD i;
644 SetAPen(rport, getbgpen(msg->imp_State, data->dri->dri_Pens));
646 RectFill(rport, left, top, right, bottom);
648 left += hspacing;
649 top += vspacing;
650 width -= hspacing * 2;
651 height -= vspacing * 2;
653 right = left + width - 1;
654 bottom = top + height - 1;
656 cy = (height + 1) / 2;
658 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
660 for(i = 0; i < cy; i++)
662 RectFill(rport, left + (cy - i - 1) * width / cy,
663 top + i,
664 right - i * width / cy / 2,
665 top + i);
666 RectFill(rport, left + (cy - i - 1) * width / cy,
667 bottom - i,
668 right - i * width / cy / 2,
669 bottom - i);
673 break;
676 case UPIMAGE:
678 UWORD hspacing,vspacing;
679 WORD cx;
681 if (!(data->flags & (SYSIFLG_NOBORDER | SYSIFLG_GADTOOLS)))
683 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->WinDecorObj, (Msg)&wdecormsg);
684 break;
687 hspacing = HSPACING;
688 vspacing = VSPACING;
690 if (width <= 12)
692 hspacing = HSPACING_MIDDLE;
695 if (width <= 10)
697 hspacing = HSPACING_SMALL;
700 if (height <= 12)
702 vspacing = VSPACING_MIDDLE;
705 if (height <= 10)
707 vspacing = VSPACING_SMALL;
710 if (!(data->flags & SYSIFLG_NOBORDER))
712 renderimageframe(rport, UPIMAGE, msg->imp_State, data->dri->dri_Pens,
713 left, top, width, height, IntuitionBase);
714 left++;
715 top++;
716 right--;
717 bottom--;
718 width -= 2;
719 height -= 2;
721 if (data->flags & SYSIFLG_GADTOOLS)
723 SetAPen(rport, getbgpen_gt(msg->imp_State, data->dri->dri_Pens));
724 RectFill(rport, left, top, right, bottom);
729 if (data->flags & SYSIFLG_GADTOOLS)
731 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
733 cx = width / 2;
735 Move(rport, left + hspacing + 1, top + height - 1 - vspacing);
736 Draw(rport, left + width - cx, top + vspacing);
737 Move(rport, left + hspacing, top + height - 1 - vspacing);
738 Draw(rport, left + width - cx - 1, top + vspacing);
740 Move(rport, left + width - 1 - hspacing - 1, top + height - 1 - vspacing);
741 Draw(rport, left + cx - 1, top + vspacing);
742 Move(rport, left + width - 1 - hspacing, top + height - 1 - vspacing);
743 Draw(rport, left + cx, top + vspacing);
745 else
747 WORD i;
749 SetAPen(rport, getbgpen(msg->imp_State, data->dri->dri_Pens));
751 RectFill(rport, left, top, right, bottom);
753 left += hspacing;
754 top += vspacing;
755 width -= hspacing * 2;
756 height -= vspacing * 2;
758 right = left + width - 1;
759 bottom = top + height - 1;
761 cx = (width + 1) / 2;
763 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
765 for(i = 0; i < cx; i++)
767 RectFill(rport, left + i,
768 top + (cx - i - 1) * height / cx,
769 left + i,
770 bottom - i * height / cx / 2);
771 RectFill(rport, right - i,
772 top + (cx - i - 1) * height / cx,
773 right - i,
774 bottom - i * height / cx / 2);
778 break;
781 case RIGHTIMAGE:
783 UWORD hspacing,vspacing;
784 WORD cy;
786 if (!(data->flags & (SYSIFLG_NOBORDER | SYSIFLG_GADTOOLS)))
788 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->WinDecorObj, (Msg)&wdecormsg);
789 break;
792 hspacing = HSPACING;
793 vspacing = VSPACING;
795 if (width <= 12)
797 hspacing = HSPACING_MIDDLE;
800 if (width <= 10)
802 hspacing = HSPACING_SMALL;
805 if (height <= 12)
807 vspacing = VSPACING_MIDDLE;
810 if (height <= 10)
812 vspacing = VSPACING_SMALL;
815 if (!(data->flags & SYSIFLG_NOBORDER))
817 renderimageframe(rport, RIGHTIMAGE, msg->imp_State, data->dri->dri_Pens,
818 left, top, width, height, IntuitionBase);
819 left++;
820 top++;
821 right--;
822 bottom--;
823 width -= 2;
824 height -= 2;
826 if (data->flags & SYSIFLG_GADTOOLS)
828 SetAPen(rport, getbgpen_gt(msg->imp_State, data->dri->dri_Pens));
829 RectFill(rport, left, top, right, bottom);
834 if (data->flags & SYSIFLG_GADTOOLS)
836 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
838 cy = height / 2;
840 Move(rport, left + hspacing, top + vspacing + 1);
841 Draw(rport, left + width - 1 - hspacing, top + height - cy);
842 Move(rport, left + hspacing, top + vspacing);
843 Draw(rport, left + width - 1 - hspacing, top + height - cy - 1);
845 Move(rport, left + hspacing, top + height - 1- vspacing - 1);
846 Draw(rport, left + width - 1 - hspacing, top + cy - 1);
847 Move(rport, left + hspacing, top + height - 1 - vspacing);
848 Draw(rport, left + width - 1 - hspacing, top + cy);
851 else
853 WORD i;
855 SetAPen(rport, getbgpen(msg->imp_State, data->dri->dri_Pens));
857 RectFill(rport, left, top, right, bottom);
859 left += hspacing;
860 top += vspacing;
861 width -= hspacing * 2;
862 height -= vspacing * 2;
864 right = left + width - 1;
865 bottom = top + height - 1;
867 cy = (height + 1) / 2;
869 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
871 for(i = 0; i < cy; i++)
873 RectFill(rport, left + i * width / cy / 2,
874 top + i,
875 right - (cy - i - 1) * width / cy,
876 top + i);
877 RectFill(rport, left + i * width / cy / 2,
878 bottom - i,
879 right - (cy - i - 1) * width / cy,
880 bottom - i);
884 break;
887 case DOWNIMAGE:
889 UWORD hspacing,vspacing;
890 WORD cx;
892 if (!(data->flags & (SYSIFLG_NOBORDER | SYSIFLG_GADTOOLS)))
894 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->WinDecorObj, (Msg)&wdecormsg);
895 break;
898 hspacing = HSPACING;
899 vspacing = VSPACING;
901 if (width <= 12)
903 hspacing = HSPACING_MIDDLE;
906 if (width <= 10)
908 hspacing = HSPACING_SMALL;
911 if (height <= 12)
913 vspacing = VSPACING_MIDDLE;
916 if (height <= 10)
918 vspacing = VSPACING_SMALL;
921 if (!(data->flags & SYSIFLG_NOBORDER))
923 renderimageframe(rport, DOWNIMAGE, msg->imp_State, data->dri->dri_Pens,
924 left, top, width, height, IntuitionBase);
925 left++;
926 top++;
927 right--;
928 bottom--;
929 width -= 2;
930 height -= 2;
932 if (data->flags & SYSIFLG_GADTOOLS)
934 SetAPen(rport, getbgpen_gt(msg->imp_State, data->dri->dri_Pens));
935 RectFill(rport, left, top, right, bottom);
939 if (data->flags & SYSIFLG_GADTOOLS)
941 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
943 cx = width / 2;
945 Move(rport, left + hspacing + 1, top + vspacing);
946 Draw(rport, left + width - cx, top + height - 1 - vspacing);
947 Move(rport, left + hspacing, top + vspacing);
948 Draw(rport, left + width - cx - 1, top + height - 1 - vspacing);
950 Move(rport, left + width - 1 - hspacing - 1, top + vspacing);
951 Draw(rport, left + cx - 1, top + height - 1 - vspacing);
952 Move(rport, left + width - 1 - hspacing, top + vspacing);
953 Draw(rport, left + cx, top + height - 1 - vspacing);
955 else
957 WORD i;
959 SetAPen(rport, getbgpen(msg->imp_State, data->dri->dri_Pens));
961 RectFill(rport, left, top, right, bottom);
963 left += hspacing;
964 top += vspacing;
965 width -= hspacing * 2;
966 height -= vspacing * 2;
968 right = left + width - 1;
969 bottom = top + height - 1;
971 cx = (width + 1) / 2;
973 SetAPen(rport, data->dri->dri_Pens[SHADOWPEN]);
975 for(i = 0; i < cx; i++)
977 RectFill(rport, left + i,
978 top + i * height / cx / 2,
979 left + i,
980 bottom - (cx - i - 1) * height / cx);
981 RectFill(rport, right - i,
982 top + i * height / cx / 2,
983 right - i,
984 bottom - (cx - i - 1) * height / cx);
989 break;
992 case CLOSEIMAGE:
993 case ZOOMIMAGE:
994 case DEPTHIMAGE:
995 case SIZEIMAGE:
997 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->WinDecorObj, (Msg)&wdecormsg);
998 break;
1001 case SDEPTHIMAGE:
1003 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->ScrDecorObj, (Msg)&sdecormsg);
1004 break;
1007 case MENUCHECK:
1009 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->MenuDecorObj, (Msg)&mdecormsg);
1010 break;
1013 case AMIGAKEY:
1015 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->MenuDecorObj, (Msg)&mdecormsg);
1016 break;
1019 case SUBMENUIMAGE:
1021 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->MenuDecorObj, (Msg)&mdecormsg);
1022 break;
1025 /* MUI and other non-std images */
1026 case MUIIMAGE:
1027 case SNAPSHOTIMAGE:
1028 case POPUPIMAGE:
1029 case ICONIFYIMAGE:
1030 case LOCKIMAGE:
1032 DoMethodA(((struct IntScreen *)(((struct IntDrawInfo *)data->dri)->dri_Screen))->WinDecorObj, (Msg)&wdecormsg);
1033 break;
1038 } /* switch (image type) */
1040 return (IPTR)0;
1043 IPTR SysIClass__OM_DISPOSE(Class *cl, Object *obj, Msg msg)
1045 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
1046 struct SysIData *data = INST_DATA(cl, obj);
1048 DisposeObject(data->frame);
1049 return DoSuperMethodA(cl, obj, msg);
1052 IPTR SysIClass__OM_SET(Class *cl, Object *obj, Msg msg)
1054 struct SysIData *data = INST_DATA(cl, obj);
1056 if (data->frame)
1057 DoMethodA((Object *)data->frame, msg);
1058 return DoSuperMethodA(cl, obj, msg);
1061 /**************************************************************************************************/
1063 static UWORD getbgpen(ULONG state, UWORD *pens)
1065 UWORD bg;
1067 switch (state)
1069 case IDS_NORMAL:
1070 case IDS_SELECTED:
1071 bg = pens[FILLPEN];
1072 break;
1074 default:
1075 bg = pens[BACKGROUNDPEN];
1076 break;
1079 return bg;
1082 /**************************************************************************************************/
1084 static UWORD getbgpen_gt(ULONG state, UWORD *pens)
1086 UWORD bg;
1088 switch (state)
1090 case IDS_SELECTED:
1091 case IDS_INACTIVESELECTED:
1092 bg = pens[FILLPEN];
1093 break;
1095 default:
1096 bg = pens[BACKGROUNDPEN];
1097 break;
1100 return bg;
1103 /**************************************************************************************************/
1105 static void renderimageframe(struct RastPort *rp, ULONG which, ULONG state, UWORD *pens,
1106 WORD left, WORD top, WORD width, WORD height,
1107 struct IntuitionBase *IntuitionBase)
1109 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1110 WORD right = left + width - 1;
1111 WORD bottom = top + height - 1;
1112 BOOL leftedgegodown = FALSE;
1113 BOOL topedgegoright = FALSE;
1115 switch(which)
1117 case CLOSEIMAGE:
1118 /* draw separator line at the right side */
1119 SetAPen(rp, pens[SHINEPEN]);
1120 RectFill(rp, right, top, right, bottom - 1);
1121 SetAPen(rp, pens[SHADOWPEN]);
1122 WritePixel(rp, right, bottom);
1124 right--;
1125 break;
1127 case ZOOMIMAGE:
1128 case DEPTHIMAGE:
1129 case SDEPTHIMAGE:
1130 /* draw separator line at the left side */
1131 SetAPen(rp, pens[SHINEPEN]);
1132 WritePixel(rp, left, top);
1133 SetAPen(rp, pens[SHADOWPEN]);
1134 RectFill(rp, left, top + 1, left, bottom);
1136 left++;
1137 break;
1139 case UPIMAGE:
1140 case DOWNIMAGE:
1141 leftedgegodown = TRUE;
1142 break;
1144 case LEFTIMAGE:
1145 case RIGHTIMAGE:
1146 topedgegoright = TRUE;
1147 break;
1150 if (left == 0) leftedgegodown = TRUE;
1151 if (top == 0) topedgegoright = TRUE;
1153 SetAPen(rp, pens[((state == IDS_SELECTED) || (state == IDS_INACTIVESELECTED)) ? SHADOWPEN : SHINEPEN]);
1155 /* left edge */
1156 RectFill(rp, left,
1157 top,
1158 left,
1159 bottom - (leftedgegodown ? 0 : 1));
1161 /* top edge */
1162 RectFill(rp, left + 1,
1163 top,
1164 right - (topedgegoright ? 0 : 1),
1165 top);
1167 SetAPen(rp, pens[((state == IDS_SELECTED) || (state == IDS_INACTIVESELECTED)) ? SHINEPEN : SHADOWPEN]);
1169 /* right edge */
1170 RectFill(rp, right,
1171 top + (topedgegoright ? 1 : 0),
1172 right,
1173 bottom);
1175 /* bottom edge */
1176 RectFill(rp, left + (leftedgegodown ? 1 : 0),
1177 bottom,
1178 right - 1,
1179 bottom);
1182 /**************************************************************************************************/