2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
3 Copyright © 2001-2013, The MorphOS Development Team. All Rights Reserved.
7 #include <exec/types.h>
8 #include <exec/memory.h>
9 #include <proto/exec.h>
10 #include <proto/graphics.h>
11 #include <proto/layers.h>
12 #include <proto/intuition.h>
13 #include <proto/cybergraphics.h>
14 #include <clib/macros.h>
15 #include <intuition/intuitionbase.h>
16 #include <intuition/gadgetclass.h>
17 #include <intuition/imageclass.h>
18 #include <intuition/windecorclass.h>
19 #include <intuition/scrdecorclass.h>
20 #include <intuition/preferences.h>
21 #include <intuition/extensions.h>
22 #include <graphics/layers.h>
23 #include <graphics/rpattr.h>
24 #include <graphics/gfxmacros.h>
25 #include <cybergraphx/cybergraphics.h>
28 # include "intuition_customize.h"
29 # include "intuition_extend.h"
33 #include "intuition_preferences.h"
34 #include "intuition_intern.h"
36 #include "boopsigadgets.h"
44 # include <aros/debug.h>
46 ULONG
addextragadget(struct Window
*w
,BOOL is_gzz
,struct DrawInfo
*dri
,LONG relright
,ULONG imagetype
,ULONG gadgetid
,ULONG gadgettype
,struct IntuitionBase
*IntuitionBase
);
47 extern IPTR
HookEntry();
49 /**********************************************************************************/
51 void LoadDefaultPreferences(struct IntuitionBase
* IntuitionBase
)
54 static CONST UWORD DriPens2
[NUMDRIPENS
] = { 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1 , 1 , 0};
55 static CONST UWORD DriPens4
[NUMDRIPENS
] = { 1, 0, 1, 2, 1, 3, 1, 0, 2, 1, 2, 1 , 2 , 1};
57 static CONST UWORD DriPens2
[NUMDRIPENS
] = { 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1};
58 static CONST UWORD DriPens4
[NUMDRIPENS
] = { 1, 0, 1, 2, 1, 3, 1, 0, 2, 1, 2, 1};
61 GetPrivIBase(IntuitionBase
)->ScreenModePrefs
.smp_DisplayID
= INVALID_ID
;
62 GetPrivIBase(IntuitionBase
)->ScreenModePrefs
.smp_Width
= AROS_DEFAULT_WBWIDTH
;
64 GetPrivIBase(IntuitionBase
)->ScreenModePrefs
.smp_Height
= (GetPrivIBase(IntuitionBase
)->GfxBase
->DisplayFlags
& NTSC
) ? 200 : 256;
66 GetPrivIBase(IntuitionBase
)->ScreenModePrefs
.smp_Height
= AROS_DEFAULT_WBHEIGHT
;
68 GetPrivIBase(IntuitionBase
)->ScreenModePrefs
.smp_Depth
= AROS_DEFAULT_WBDEPTH
;
69 GetPrivIBase(IntuitionBase
)->ScreenModePrefs
.smp_Control
= 0;
71 /* Default IControl prefs are AROS addition. Keep while backporting. */
72 GetPrivIBase(IntuitionBase
)->IControlPrefs
.ic_TimeOut
= 50;
73 GetPrivIBase(IntuitionBase
)->IControlPrefs
.ic_MetaDrag
= IEQUALIFIER_LCOMMAND
;
74 GetPrivIBase(IntuitionBase
)->IControlPrefs
.ic_Flags
= ICF_3DMENUS
|
76 ICF_AVOIDWINBORDERERASE
|
81 GetPrivIBase(IntuitionBase
)->IControlPrefs
.ic_WBtoFront
= 'N';
82 GetPrivIBase(IntuitionBase
)->IControlPrefs
.ic_FrontToBack
= 'M';
83 GetPrivIBase(IntuitionBase
)->IControlPrefs
.ic_ReqTrue
= 'V';
84 GetPrivIBase(IntuitionBase
)->IControlPrefs
.ic_ReqFalse
= 'B';
90 GetPrivIBase(IntuitionBase
)->DefaultPreferences
.PointerTicks
= 2;
92 CopyMem(&IntuitionDefaultPreferences
,
93 &GetPrivIBase(IntuitionBase
)->DefaultPreferences
,
94 sizeof(struct Preferences
));
95 CopyMem(&GetPrivIBase(IntuitionBase
)->DefaultPreferences
,
96 &GetPrivIBase(IntuitionBase
)->ActivePreferences
,
97 sizeof(struct Preferences
));
99 CopyMem(DriPens2
, GetPrivIBase(IntuitionBase
)->DriPens2
, sizeof(DriPens2
));
100 CopyMem(DriPens4
, GetPrivIBase(IntuitionBase
)->DriPens4
, sizeof(DriPens4
));
101 CopyMem(DriPens4
, GetPrivIBase(IntuitionBase
)->DriPens8
, sizeof(DriPens4
));
104 /**********************************************************************************/
106 void CheckRectFill(struct RastPort
*rp
, WORD x1
, WORD y1
, WORD x2
, WORD y2
,
107 struct IntuitionBase
* IntuitionBase
)
109 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
111 if ((x2
>= x1
) && (y2
>= y1
))
113 RectFill(rp
, x1
, y1
, x2
, y2
);
117 /**********************************************************************************/
119 Object
* CreateStdSysImage(WORD which
, WORD preferred_height
, struct Screen
*scr
,
120 struct DrawInfo
*dri
, struct IntuitionBase
*IntuitionBase
)
124 struct TagItem image_tags
[] =
126 {SYSIA_Which
, which
},
127 {SYSIA_DrawInfo
, (IPTR
)dri
},
128 {SYSIA_Size
, scr
->Flags
& SCREENHIRES
?
129 SYSISIZE_MEDRES
: SYSISIZE_LOWRES
},
133 im
= NewObjectA(NULL
, SYSICLASS
, image_tags
);
136 struct TagItem size_tags
[] =
139 {IA_Height
, preferred_height
},
144 GetAttr(IA_Width
, im
, &width
);
145 GetAttr(IA_Height
, im
, &height
);
147 size_tags
[0].ti_Data
= preferred_height
* width
/ height
;
149 SetAttrsA(im
, size_tags
);
155 /**********************************************************************************/
157 BOOL
CreateWinSysGadgets(struct Window
*w
, struct IntuitionBase
*IntuitionBase
)
160 struct DrawInfo
*dri
;
162 ULONG TitleHeight
= w
->BorderTop
;
164 EnterFunc(bug("CreateWinSysGadgets(w=%p)\n", w
));
166 is_gzz
= (w
->Flags
& WFLG_GIMMEZEROZERO
) ? TRUE
: FALSE
;
168 dri
= GetScreenDrawInfo(w
->WScreen
);
171 LONG db_left
, db_width
, relright
,ewidth
; /* dragbar sizes */
172 BOOL sysgads_ok
= TRUE
;
176 db_width
= 0; /* Georg Steger: was w->Width; */
178 /* Relright of rightmost button */
179 //relright = - (TitleHeight - 1);
183 /* Now try to create the various gadgets */
185 if (w
->Flags
& WFLG_SIZEGADGET
)
187 /* this code must not change the 'relright' variable */
188 WORD width
= ((struct IntWindow
*)w
)->sizeimage_width
;
189 WORD height
= ((struct IntWindow
*)w
)->sizeimage_height
;
191 struct TagItem size_tags
[] =
194 {GA_RelRight
, -width
+ 1 },
195 {GA_RelBottom
, -height
+ 1 },
197 {GA_Height
, height
},
198 {GA_SysGadget
, TRUE
},
199 {GA_SysGType
, GTYP_SIZING
},
200 {GA_BottomBorder
, TRUE
},
201 {GA_RightBorder
, TRUE
},
202 {GA_GZZGadget
, is_gzz
},
206 struct TagItem image_tags
[] =
209 {IA_Height
, height
},
210 {SYSIA_Which
, SIZEIMAGE
},
211 {SYSIA_DrawInfo
, (IPTR
)dri
},
212 {SYSIA_Size
, w
->WScreen
->Flags
& SCREENHIRES
? SYSISIZE_MEDRES
: SYSISIZE_LOWRES
},
217 im
= NewObjectA(NULL
, SYSICLASS
, image_tags
);
224 size_tags
[0].ti_Data
= (IPTR
)im
;
226 SYSGAD(w
, SIZEGAD
) = NewObjectA(NULL
, BUTTONGCLASS
, size_tags
);
228 if (!SYSGAD(w
, SIZEGAD
))
236 if (w
->Flags
& WFLG_DEPTHGADGET
)
238 struct TagItem depth_tags
[] =
241 //{GA_RelRight , relright },
243 #if SQUARE_WIN_GADGETS
244 {GA_Width
, TitleHeight
},
246 {GA_Height
, TitleHeight
},
247 {GA_SysGadget
, TRUE
},
248 {GA_SysGType
, GTYP_WDEPTH
},
249 {GA_TopBorder
, TRUE
},
250 {GA_GZZGadget
, is_gzz
},
251 {GA_RelVerify
, TRUE
},
256 im
= CreateStdSysImage(DEPTHIMAGE
, TitleHeight
, w
->WScreen
, dri
, IntuitionBase
);
263 depth_tags
[0].ti_Data
= (IPTR
)im
;
265 SYSGAD(w
, DEPTHGAD
) = NewObjectA(NULL
, BUTTONGCLASS
, depth_tags
);
267 if (!SYSGAD(w
, DEPTHGAD
))
275 GetAttr(GA_Width
, SYSGAD(w
, DEPTHGAD
), &width
);
283 struct TagItem gadtags
[] =
285 {GA_RelRight
, relright
},
286 /* {GA_Width , width }, */
290 SetAttrsA(SYSGAD(w
, DEPTHGAD
), gadtags
);
297 /* RKRMs: window gets zoom gadget if WA_Zoom tag was used,
298 or if window has both a sizegadget and a depthgadget */
300 if ((w
->Flags
& WFLG_HASZOOM
) ||
301 ((w
->Flags
& WFLG_SIZEGADGET
) && (w
->Flags
& WFLG_DEPTHGADGET
)))
303 struct TagItem zoom_tags
[] =
306 //{GA_RelRight , relright },
308 #if SQUARE_WIN_GADGETS
309 {GA_Width
, TitleHeight
},
311 {GA_Height
, TitleHeight
},
312 {GA_SysGadget
, TRUE
},
313 {GA_SysGType
, GTYP_WZOOM
},
314 {GA_TopBorder
, TRUE
},
315 {GA_GZZGadget
, is_gzz
},
316 {GA_RelVerify
, TRUE
},
322 im
= CreateStdSysImage(ZOOMIMAGE
, TitleHeight
, w
->WScreen
, dri
, IntuitionBase
);
329 zoom_tags
[0].ti_Data
= (IPTR
)im
;
331 SYSGAD(w
, ZOOMGAD
) = NewObjectA(NULL
, BUTTONGCLASS
, zoom_tags
);
333 if (!SYSGAD(w
, ZOOMGAD
))
341 GetAttr(GA_Width
, SYSGAD(w
, ZOOMGAD
), &width
);
347 struct TagItem gadtags
[] =
349 {GA_RelRight
, relright
},
354 SetAttrsA(SYSGAD(w
, ZOOMGAD
), gadtags
);
360 if (((struct IntWindow
*)(w
))->extrabuttons
& ETG_LOCK
)
362 ewidth
= addextragadget(w
,is_gzz
,dri
,relright
,LOCKIMAGE
,((struct IntWindow
*)w
)->extrabuttonsid
+ ETD_Lock
,LOCKGAD
,IntuitionBase
);
367 if (((struct IntWindow
*)(w
))->extrabuttons
& ETG_ICONIFY
)
369 ewidth
= addextragadget(w
,is_gzz
,dri
,relright
,ICONIFYIMAGE
,((struct IntWindow
*)w
)->extrabuttonsid
+ ETD_Iconify
,ICONIFYGAD
,IntuitionBase
);
374 if (((struct IntWindow
*)(w
))->extrabuttons
& ETG_JUMP
)
376 ewidth
= addextragadget(w
,is_gzz
,dri
,relright
,JUMPIMAGE
,((struct IntWindow
*)w
)->extrabuttonsid
+ ETD_Jump
,JUMPGAD
,IntuitionBase
);
381 if (((struct IntWindow
*)(w
))->extrabuttons
& ETG_SNAPSHOT
)
383 ewidth
= addextragadget(w
,is_gzz
,dri
,relright
,SNAPSHOTIMAGE
,((struct IntWindow
*)w
)->extrabuttonsid
+ ETD_Snapshot
,SNAPSHOTGAD
,IntuitionBase
);
388 if (((struct IntWindow
*)(w
))->extrabuttons
& ETG_MUI
)
390 ewidth
= addextragadget(w
,is_gzz
,dri
,relright
,MUIIMAGE
,((struct IntWindow
*)w
)->extrabuttonsid
+ ETD_MUI
,MUIGAD
,IntuitionBase
);
395 if (((struct IntWindow
*)(w
))->extrabuttons
& ETG_POPUP
)
397 ewidth
= addextragadget(w
,is_gzz
,dri
,relright
,POPUPIMAGE
,((struct IntWindow
*)w
)->extrabuttonsid
+ ETD_PopUp
,POPUPGAD
,IntuitionBase
);
402 if (w
->Flags
& WFLG_CLOSEGADGET
)
404 struct TagItem close_tags
[] =
409 #if SQUARE_WIN_GADGETS
410 {GA_Width
, TitleHeight
},
412 {GA_Height
, TitleHeight
},
413 {GA_SysGadget
, TRUE
},
414 {GA_SysGType
, GTYP_CLOSE
},
415 {GA_TopBorder
, TRUE
},
416 {GA_GZZGadget
, is_gzz
},
417 {GA_RelVerify
, TRUE
},
422 im
= CreateStdSysImage(CLOSEIMAGE
, TitleHeight
, w
->WScreen
, dri
,IntuitionBase
);
429 close_tags
[0].ti_Data
= (IPTR
)im
;
431 SYSGAD(w
, CLOSEGAD
) = NewObjectA(NULL
, BUTTONGCLASS
, close_tags
);
433 if (!SYSGAD(w
, CLOSEGAD
))
441 GetAttr(GA_Width
, SYSGAD(w
, CLOSEGAD
), &width
);
449 if (w
->Flags
& WFLG_DRAGBAR
)
452 struct TagItem dragbar_tags
[] =
454 {GA_Left
, 0/*db_left*/ },
456 {GA_RelWidth
, 0/*db_width*/ },
457 {GA_Height
, TitleHeight
},
458 {GA_SysGadget
, TRUE
},
459 {GA_SysGType
, GTYP_WDRAGGING
},
460 {GA_TopBorder
, TRUE
},
461 {GA_GZZGadget
, is_gzz
},
464 SYSGAD(w
, DRAGBAR
) = NewObjectA(NULL
, BUTTONGCLASS
, dragbar_tags
);
466 if (!SYSGAD(w
, DRAGBAR
))
472 D(bug("Dragbar: %p\n", SYSGAD(w
, DRAGBAR
) ));
473 D(bug("Depthgad: %p\n", SYSGAD(w
, DEPTHGAD
) ));
474 D(bug("Zoomgad: %p\n", SYSGAD(w
, ZOOMGAD
) ));
475 D(bug("Closegad: %p\n", SYSGAD(w
, CLOSEGAD
) ));
476 D(bug("Sizegad: %p\n", SYSGAD(w
, SIZEGAD
) ));
478 /* Don't need drawinfo anymore */
479 FreeScreenDrawInfo(w
->WScreen
, dri
);
486 D(bug("Adding gadgets\n"));
487 for (i
= NUM_SYSGADS
; --i
>= 0; )
491 struct wdpLayoutBorderGadgets msg
;
493 msg
.MethodID
= WDM_LAYOUT_BORDERGADGETS
;
495 msg
.wdp_Gadgets
= (struct Gadget
*)SYSGAD(w
, i
);
496 msg
.wdp_Flags
= WDF_LBG_SYSTEMGADGET
| WDF_LBG_INITIAL
;
497 msg
.wdp_UserBuffer
= ((struct IntWindow
*)(w
))->DecorUserBuffer
;
498 msg
.wdp_ExtraButtons
= ((struct IntWindow
*)w
)->extrabuttons
;
500 msg
.wdp_TrueColor
= (((struct IntScreen
*)w
->WScreen
)->DInfo
.dri_Flags
& DRIF_DIRECTCOLOR
) ? TRUE
: FALSE
;
503 DoMethodA(((struct IntScreen
*)(w
->WScreen
))->WinDecorObj
, (Msg
)&msg
);
505 AddGadget(w
, (struct Gadget
*)SYSGAD(w
, i
), 0);
509 ReturnBool("CreateWinSysGadgets", TRUE
);
511 } /* if (sysgads created) */
513 KillWinSysGadgets(w
, IntuitionBase
);
515 } /* if (got DrawInfo) */
516 ReturnBool("CreateWinSysGadgets", FALSE
);
520 /**********************************************************************************/
522 VOID
KillWinSysGadgets(struct Window
*w
, struct IntuitionBase
*IntuitionBase
)
524 /* Free system gadgets */
527 for (i
= 0; i
< NUM_SYSGADS
; i
++)
531 RemoveGadget( w
, (struct Gadget
*)SYSGAD(w
, i
));
532 DisposeObject((Object
*)((struct Gadget
*)SYSGAD(w
, i
))->GadgetRender
);
533 DisposeObject( SYSGAD(w
, i
) );
538 /**********************************************************************************/
540 void CreateScreenBar(struct Screen
*scr
, struct IntuitionBase
*IntuitionBase
)
542 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
543 struct LayersBase
*LayersBase
= GetPrivIBase(IntuitionBase
)->LayersBase
;
545 ULONG backdrop
= LAYERBACKDROP
;
548 D(bug("[intuition] CreateScreenBar()\n"));
551 if ((scr
->Flags
& SCREENQUIET
) || (GetPrivScreen(scr
)->SpecialFlags
& SF_InvisibleBar
))
554 if (GetPrivScreen(scr
)->SpecialFlags
& SF_AppearingBar
)
557 ypos
= - (scr
->BarHeight
+ 1);
560 if (scr
->Flags
& SCREENQUIET
) front
= FALSE
;
562 D(bug("[intuition] CreateScreenBar: Got initial flags\n"));
566 D(bug("[intuition] CreateScreenBar: No current BarLayer\n"));
569 scr
->BarLayer
= CreateUpfrontHookLayer(&scr
->LayerInfo
,
570 scr
->RastPort
.BitMap
,
574 scr
->BarHeight
+ ypos
, /* 1 pixel heigher than scr->BarHeight */
575 LAYERSIMPLE
| backdrop
,
581 scr
->BarLayer
= CreateBehindHookLayer(&scr
->LayerInfo
,
582 scr
->RastPort
.BitMap
,
586 scr
->BarHeight
+ ypos
, /* 1 pixel heigher than scr->BarHeight */
587 LAYERSIMPLE
| backdrop
,
594 D(bug("[intuition] CreateScreenBar: Adding BarLayer @ %p\n", scr
->BarLayer
));
595 D(bug("[intuition] CreateScreenBar: Rastport @ %p, Font @ %p\n", scr
->BarLayer
->rp
, ((struct IntScreen
*)scr
)->DInfo
.dri_Font
));
596 SetFont(scr
->BarLayer
->rp
, ((struct IntScreen
*)scr
)->DInfo
.dri_Font
);
597 if (!(scr
->Flags
& SCREENQUIET
)) {
598 D(bug("[intuition] CreateScreenBar: Rendering Bar ...\n"));
599 RenderScreenBar(scr
, FALSE
, IntuitionBase
);
601 D(bug("[intuition] CreateScreenBar: ... done\n"));
605 D(bug("[intuition] CreateScreenBar: Failed to create BarLayer!!\n"));
610 D(bug("[intuition] CreateScreenBar: Screen already has BarLayer\n"));
614 /**********************************************************************************/
616 void KillScreenBar(struct Screen
*scr
, struct IntuitionBase
*IntuitionBase
)
618 struct LayersBase
*LayersBase
= GetPrivIBase(IntuitionBase
)->LayersBase
;
622 DeleteLayer(0, scr
->BarLayer
);
623 scr
->BarLayer
= FALSE
;
628 /**********************************************************************************/
631 //RenderScreenBar moved to morphos/mosmisc.c
636 void RenderScreenBar(struct Screen
*scr
, BOOL refresh
, struct IntuitionBase
*IntuitionBase
)
639 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
640 struct LayersBase
*LayersBase
= GetPrivIBase(IntuitionBase
)->LayersBase
;
643 D(bug("[intuition] RenderScreenBar()\n"));
647 #if USE_NEWDISPLAYBEEP
653 D(bug("[intuition] RenderScreenBar: BarLayer @ %p\n", scr
->BarLayer
));
655 rp
= scr
->BarLayer
->rp
;
657 D(bug("[intuition] RenderScreenBar: RastPort @ %p\n", rp
));
658 /* must lock GadgetLock to avoid deadlocks with ObtainGIRPort
659 when calling refreshgadget inside layer update state */
660 LockLayerInfo(scr
->BarLayer
->LayerInfo
);
661 LOCKGADGET(IntuitionBase
)
662 LockLayer(0, scr
->BarLayer
);
664 D(bug("[intuition] RenderScreenBar: Layer locked\n"));
665 #if USE_NEWDISPLAYBEEP
666 beeping
= (scr
->Flags
& BEEPING
) && GetBitMapAttr(rp
->BitMap
, BMA_DEPTH
) > 8;
669 if (refresh
) BeginUpdate(scr
->BarLayer
);
672 struct sdpDrawScreenBar msg
;
674 D(bug("[intuition] RenderScreenBar: Begin Refresh .. \n"));
676 msg
.MethodID
= SDM_DRAW_SCREENBAR
;
677 msg
.sdp_Layer
= scr
->BarLayer
;
680 msg
.sdp_Screen
= scr
;
681 msg
.sdp_Dri
= (struct DrawInfo
*)&((struct IntScreen
*)scr
)->DInfo
;
682 msg
.sdp_UserBuffer
= ((struct IntScreen
*)(scr
))->DecorUserBuffer
;
683 msg
.sdp_TrueColor
= (((struct IntScreen
*)(scr
))->DInfo
.dri_Flags
& DRIF_DIRECTCOLOR
) ? TRUE
: FALSE
;
685 D(bug("[intuition] RenderScreenBar: ScrDecorObj @ %p, DecorUserBuffer @ %p\n", ((struct IntScreen
*)(scr
))->ScrDecorObj
, ((struct IntScreen
*)(scr
))->DecorUserBuffer
));
686 DoMethodA(((struct IntScreen
*)(scr
))->ScrDecorObj
, (Msg
)&msg
);
689 D(bug("[intuition] RenderScreenBar: Update gadgets .. \n"));
691 if (scr
->FirstGadget
)
693 RefreshBoopsiGadget(scr
->FirstGadget
, (struct Window
*)scr
, NULL
, IntuitionBase
);
698 D(bug("[intuition] RenderScreenBar: End Refresh .. \n"));
699 scr
->BarLayer
->Flags
&= ~LAYERREFRESH
;
700 EndUpdate(scr
->BarLayer
, TRUE
);
703 #if USE_NEWDISPLAYBEEP
705 /* FIXME: Shouldn't we 'beep' at this point? */
706 D(bug("[intuition] RenderScreenBar: Beep\n"));
710 D(bug("[intuition] RenderScreenBar: Unlock Layer ..\n"));
712 UnlockLayer(scr
->BarLayer
);
713 UNLOCKGADGET(IntuitionBase
)
714 UnlockLayerInfo(scr
->BarLayer
->LayerInfo
);
716 } /* if (scr->BarLayer) */
717 D(bug("[intuition] RenderScreenBar: Done \n"));
722 /**********************************************************************************/
724 void UpdateMouseCoords(struct Window
*win
)
726 WORD scrmousex
= win
->WScreen
->MouseX
;
727 WORD scrmousey
= win
->WScreen
->MouseY
;
729 win
->MouseX
= scrmousex
- win
->LeftEdge
;
730 win
->MouseY
= scrmousey
- win
->TopEdge
;
732 /* stegerg: AmigaOS sets this even if window is not GZZ
733 so we do the same as they are handy also for non-GZZ
736 win
->GZZMouseX
= scrmousex
- (win
->LeftEdge
+ win
->BorderLeft
);
737 win
->GZZMouseY
= scrmousey
- (win
->TopEdge
+ win
->BorderTop
);
740 /**********************************************************************************/
742 /* subtract rectangle b from rectangle b. resulting rectangles will be put into
743 destrectarray which must have place for at least 4 rectangles. Returns number
744 of resulting rectangles */
746 #if 0 /* use <clib/macros.h> MAX/MIN macros */
748 #define MAX(a,b) (((a) > (b)) ? (a) : (b))
751 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
754 WORD
SubtractRectFromRect(struct Rectangle
*a
, struct Rectangle
*b
, struct Rectangle
*destrectarray
)
756 struct Rectangle intersect
;
757 BOOL intersecting
= FALSE
;
760 /* calc. intersection between a and b */
762 if (a
->MinX
<= b
->MaxX
)
764 if (a
->MinY
<= b
->MaxY
)
766 if (a
->MaxX
>= b
->MinX
)
768 if (a
->MaxY
>= b
->MinY
)
770 intersect
.MinX
= MAX(a
->MinX
, b
->MinX
);
771 intersect
.MinY
= MAX(a
->MinY
, b
->MinY
);
772 intersect
.MaxX
= MIN(a
->MaxX
, b
->MaxX
);
773 intersect
.MaxY
= MIN(a
->MaxY
, b
->MaxY
);
783 destrectarray
[numrects
++] = *a
;
785 } /* not intersecting */
788 if (intersect
.MinY
> a
->MinY
) /* upper */
790 destrectarray
->MinX
= a
->MinX
;
791 destrectarray
->MinY
= a
->MinY
;
792 destrectarray
->MaxX
= a
->MaxX
;
793 destrectarray
->MaxY
= intersect
.MinY
- 1;
799 if (intersect
.MaxY
< a
->MaxY
) /* lower */
801 destrectarray
->MinX
= a
->MinX
;
802 destrectarray
->MinY
= intersect
.MaxY
+ 1;
803 destrectarray
->MaxX
= a
->MaxX
;
804 destrectarray
->MaxY
= a
->MaxY
;
810 if (intersect
.MinX
> a
->MinX
) /* left */
812 destrectarray
->MinX
= a
->MinX
;
813 destrectarray
->MinY
= intersect
.MinY
;
814 destrectarray
->MaxX
= intersect
.MinX
- 1;
815 destrectarray
->MaxY
= intersect
.MaxY
;
821 if (intersect
.MaxX
< a
->MaxX
) /* right */
823 destrectarray
->MinX
= intersect
.MaxX
+ 1;
824 destrectarray
->MinY
= intersect
.MinY
;
825 destrectarray
->MaxX
= a
->MaxX
;
826 destrectarray
->MaxY
= intersect
.MaxY
;
838 ULONG
addextragadget(struct Window
*w
,BOOL is_gzz
,struct DrawInfo
*dri
,LONG relright
,ULONG imagetype
,ULONG gadgetid
,ULONG gadgettype
,struct IntuitionBase
*IntuitionBase
)
840 ULONG TitleHeight
= w
->BorderTop
;
841 struct TagItem gadget_tags
[] =
844 {GA_ToggleSelect
, FALSE
},
846 {GA_Height
, TitleHeight
},
847 {GA_TopBorder
, TRUE
},
848 {GA_GZZGadget
, is_gzz
},
850 {GA_RelVerify
, TRUE
},
856 if (gadgettype
== LOCKGAD
)
857 gadget_tags
[1].ti_Data
= TRUE
;
859 im
= CreateStdSysImage(imagetype
, TitleHeight
, w
->WScreen
, dri
,IntuitionBase
);
862 gadget_tags
[0].ti_Data
= (IPTR
)im
;
864 SYSGAD(w
, gadgettype
) = NewObjectA(NULL
, BUTTONGCLASS
, gadget_tags
);
866 if (!SYSGAD(w
, gadgettype
))
873 GetAttr(GA_Width
, SYSGAD(w
, gadgettype
), &width
);
878 struct TagItem gadtags
[] =
880 {GA_RelRight
, relright
- width
},
884 SetAttrsA(SYSGAD(w
, gadgettype
), gadtags
);
895 /**********************************************************************************/
897 /* Use the FNV-1 hash function over the object's pointer.
898 * http://en.wikipedia.org/wiki/Fowler-Noll-Vo_hash_function
900 LONG
CalcResourceHash(APTR resource
)
902 const ULONG FNV1_32_Offset
= 2166136261UL;
903 const ULONG FNV1_32_Prime
= 16777619UL;
904 IPTR data
= (IPTR
)resource
;
908 hash
= FNV1_32_Offset
;
909 for (i
= 0; i
< AROS_SIZEOFPTR
; i
++) {
910 hash
*= FNV1_32_Prime
;
915 return hash
& (RESOURCELIST_HASHSIZE
-1);
918 /**********************************************************************************/
920 void AddResourceToList(APTR resource
, UWORD resourcetype
, struct IntuitionBase
*IntuitionBase
)
922 struct HashNode
*hn
= NULL
;
928 case RESOURCE_WINDOW
:
929 hn
= &((struct IntWindow
*)resource
)->hashnode
;
930 hn
->type
= RESOURCE_WINDOW
;
933 case RESOURCE_SCREEN
:
934 hn
= &((struct IntScreen
*)resource
)->hashnode
;
935 hn
->type
= RESOURCE_SCREEN
;
939 D(bug("AddResourceToList: Unknown resource type!!!\n"));
943 hash
= CalcResourceHash(resource
);
945 hn
->resource
= resource
;
947 ilock
= LockIBase(0);
948 AddTail((struct List
*)&GetPrivIBase(IntuitionBase
)->ResourceList
[hash
], (struct Node
*)hn
);
952 /**********************************************************************************/
954 void RemoveResourceFromList(APTR resource
, UWORD resourcetype
, struct IntuitionBase
*IntuitionBase
)
956 struct HashNode
*hn
= NULL
;
961 case RESOURCE_WINDOW
:
962 hn
= &((struct IntWindow
*)resource
)->hashnode
;
965 case RESOURCE_SCREEN
:
966 hn
= &((struct IntScreen
*)resource
)->hashnode
;
970 D(bug("RemoveResourceFromList: Unknown resource type!!!\n"));
974 if (hn
->type
!= resourcetype
)
976 D(bug("RemoveResourceFromList: Panic. Resource Type mismatch!!!\n"));
979 ilock
= LockIBase(0);
980 Remove((struct Node
*)hn
);
984 /**********************************************************************************/
986 BOOL
ResourceExisting(APTR resource
, UWORD resourcetype
, struct IntuitionBase
*IntuitionBase
)
988 struct HashNode
*hn
= NULL
;
993 hash
= CalcResourceHash(resource
);
995 ilock
= LockIBase(0);
996 ForeachNode((struct List
*)&GetPrivIBase(IntuitionBase
)->ResourceList
[hash
], hn
)
998 if ((hn
->resource
== resource
) && (hn
->type
== resourcetype
))
1009 void FireScreenNotifyMessageCode(IPTR data
, ULONG flag
, ULONG code
, struct IntuitionBase
*IntuitionBase
)
1011 ObtainSemaphoreShared(&GetPrivIBase(IntuitionBase
)->ScreenNotificationListLock
);
1013 struct ScreenNotifyMessage
*msg
;
1014 struct ReplyPort
*reply
;
1016 struct IntScreenNotify
*sn
;
1019 BOOL ignorescreen
= FALSE
;
1021 if (!IsListEmpty(&GetPrivIBase(IntuitionBase
)->ScreenNotificationList
))
1023 node
= GetPrivIBase(IntuitionBase
)->ScreenNotificationList
.lh_Head
;
1024 for (; node
->ln_Succ
; node
= node
->ln_Succ
)
1026 sn
= (struct IntScreenNotify
*) node
;
1027 if (flag
& ( SNOTIFY_AFTER_OPENSCREEN
| SNOTIFY_BEFORE_OPENSCREEN
1028 | SNOTIFY_AFTER_CLOSESCREEN
| SNOTIFY_BEFORE_CLOSESCREEN
1029 | SNOTIFY_LOCKPUBSCREEN
| SNOTIFY_UNLOCKPUBSCREEN
1030 | SNOTIFY_SCREENDEPTH
| SNOTIFY_PUBSCREENSTATE
))
1033 * If sn->pubname is supplied, only notify for it
1034 * (data must be a screen, and it must be public)
1038 D(bug("[intuition] FSNMC() sn->pubname is non-NULL... '%s'\n", sn
->pubname
));
1039 LockPubScreenList();
1040 if (!( (ResourceExisting((struct Screen
*)data
, RESOURCE_SCREEN
, IntuitionBase
))
1041 && (NULL
!= GetPrivScreen(data
)->pubScrNode
)
1042 && (NULL
!= GetPrivScreen(data
)->pubScrNode
->psn_Node
.ln_Name
)
1043 && (0 == strcmp(sn
->pubname
, (const char *)GetPrivScreen(data
)->pubScrNode
->psn_Node
.ln_Name
)) ))
1045 ignorescreen
= TRUE
;
1049 D(bug("[intuition] FSNMC() IntScreen->pubScrNode->psn_Node.ln_Name is non-NULL... '%s'\n", GetPrivScreen(data
)->pubScrNode
->psn_Node
.ln_Name
));
1051 UnlockPubScreenList();
1053 D(bug("[intuition] FSNMC() ignorescreen = %s\n", ignorescreen
? "TRUE" : "FALSE"));
1056 if ((sn
->flags
& flag
) && !ignorescreen
)
1060 msg
= AllocMem(sizeof(struct ScreenNotifyMessage
), MEMF_CLEAR
);
1063 msg
->snm_Message
.mn_Magic
= MAGIC_SCREENNOTIFY
;
1064 msg
->snm_Message
.mn_Version
= SCREENNOTIFY_VERSION
;
1065 msg
->snm_Object
= data
;
1066 msg
->snm_Class
= flag
;
1067 msg
->snm_Code
= code
;
1068 msg
->snm_UserData
= sn
->userdata
;
1069 msg
->snm_Message
.mn_Length
= sizeof(struct ScreenNotifyMessage
);
1070 if (sn
->flags
& SNOTIFY_WAIT_REPLY
)
1072 reply
= (struct ReplyPort
*)CreateMsgPort();
1075 msg
->snm_Message
.mn_ReplyPort
= (struct MsgPort
*)reply
;
1077 PutMsg((struct MsgPort
*)sn
->port
, (struct Message
*) msg
);
1078 WaitPort((struct MsgPort
*)reply
);
1079 GetMsg((struct MsgPort
*)reply
);
1080 FreeMem((APTR
) msg
, sizeof(struct ScreenNotifyMessage
));
1081 DeleteMsgPort((struct MsgPort
*)reply
);
1082 } else FreeMem((APTR
) msg
, sizeof(struct ScreenNotifyMessage
));
1086 msg
->snm_Message
.mn_ReplyPort
= GetPrivIBase(IntuitionBase
)->ScreenNotifyReplyPort
;
1088 PutMsg(sn
->port
, (struct Message
*) msg
);
1093 else if (sn
->sigtask
)
1095 Signal(sn
->sigtask
, 1 << sn
->sigbit
);
1099 struct ScreenNotifyMessage msg
;
1100 msg
.snm_Message
.mn_Magic
= MAGIC_SCREENNOTIFY
;
1101 msg
.snm_Message
.mn_Version
= SCREENNOTIFY_VERSION
;
1102 msg
.snm_Object
= data
;
1103 msg
.snm_Class
= flag
;
1104 msg
.snm_UserData
= sn
->userdata
;
1105 msg
.snm_Message
.mn_Length
= sizeof(struct ScreenNotifyMessage
);
1107 CallHook(sn
->hook
, NULL
, (Msg
) &msg
);
1112 ReleaseSemaphore(&GetPrivIBase(IntuitionBase
)->ScreenNotificationListLock
);
1115 void FireScreenNotifyMessage(IPTR data
, ULONG flag
, struct IntuitionBase
*IntuitionBase
)
1117 FireScreenNotifyMessageCode(data
, flag
, 0, IntuitionBase
);
1120 /**********************************************************************************/
1122 AROS_UFH3(BOOL
, DefaultWindowShapeFunc
,
1123 AROS_UFHA(struct Hook
*, hook
, A0
),
1124 AROS_UFHA(struct Layer
*, lay
, A2
),
1125 AROS_UFHA(struct ShapeHookMsg
*, msg
, A1
))
1129 struct IntuitionBase
*IntuitionBase
= (struct IntuitionBase
*)hook
->h_Data
;
1130 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
1131 struct Window
*win
= (struct Window
*)hook
->h_SubEntry
;
1132 struct Region
*shape
;
1133 struct wdpWindowShape shapemsg
;
1135 shapemsg
.MethodID
= WDM_WINDOWSHAPE
;
1136 shapemsg
.wdp_TrueColor
= (GetPrivScreen(win
->WScreen
)->DInfo
.dri_Flags
& DRIF_DIRECTCOLOR
) ? TRUE
: FALSE
;
1137 shapemsg
.wdp_Width
= msg
->NewBounds
->MaxX
- msg
->NewBounds
->MinX
+ 1;
1138 shapemsg
.wdp_Height
= msg
->NewBounds
->MaxY
- msg
->NewBounds
->MinY
+ 1;
1139 shapemsg
.wdp_Window
= win
;
1140 shapemsg
.wdp_UserBuffer
= IW(win
)->DecorUserBuffer
;
1142 shape
= (struct Region
*)DoMethodA(GetPrivScreen(win
->WScreen
)->WinDecorObj
, (Msg
)&shapemsg
);
1144 if (IW(win
)->OutlineShape
) DisposeRegion(IW(win
)->OutlineShape
);
1145 IW(win
)->OutlineShape
= shape
;
1146 IW(win
)->CustomShape
= FALSE
;
1148 msg
->NewShape
= shape
;
1154 /**********************************************************************************/