Tested and debugged ToolTypes.
[AROS.git] / rom / intuition / intuition_misc.c
blobf65642a03867531f39885a4361de0c823f5ebf15
1 /*
2 Copyright 1995-2010, 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>
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>
27 #ifdef SKINS
28 # include "intuition_customize.h"
29 # include "intuition_extend.h"
30 # include "mosmisc.h"
31 #endif
33 #include "intuition_preferences.h"
34 #include "intuition_intern.h"
36 #include "boopsigadgets.h"
37 #include "showhide.h"
39 #include <string.h>
42 #undef DEBUG
43 #define DEBUG 0
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)
53 BYTE read_preferences = FALSE;
54 # ifdef SKINS
55 static CONST UWORD DriPens2[NUMDRIPENS] = { 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1 , 1 , 0};
56 static CONST UWORD DriPens4[NUMDRIPENS] = { 1, 0, 1, 2, 1, 3, 1, 0, 2, 1, 2, 1 , 2 , 1};
57 # else
58 static CONST UWORD DriPens2[NUMDRIPENS] = { 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1};
59 static CONST UWORD DriPens4[NUMDRIPENS] = { 1, 0, 1, 2, 1, 3, 1, 0, 2, 1, 2, 1};
60 # endif /* SKINS */
63 ** Load the intuition preferences from a file on the disk
64 ** Allocate storage for the preferences, even if it's just a copy
65 ** of the default preferences.
67 GetPrivIBase(IntuitionBase)->DefaultPreferences =
68 AllocMem(sizeof(struct Preferences), MEMF_CLEAR);
70 GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_DisplayID = INVALID_ID;
71 GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Width = AROS_DEFAULT_WBWIDTH;
72 #ifdef __mc68000
73 GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Height = (GfxBase->DisplayFlags & NTSC) ? 200 : 256;
74 #else
75 GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Height = AROS_DEFAULT_WBHEIGHT;
76 #endif
77 GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Depth = AROS_DEFAULT_WBDEPTH;
78 GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Control = 0;
80 GetPrivIBase(IntuitionBase)->IControlPrefs.ic_TimeOut = 50;
81 GetPrivIBase(IntuitionBase)->IControlPrefs.ic_MetaDrag = IEQUALIFIER_LCOMMAND;
82 GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags = ICF_3DMENUS |
83 ICF_OFFSCREENLAYERS |
84 ICF_AVOIDWINBORDERERASE |
85 ICF_MODEPROMOTE |
86 ICF_MENUSNAP |
87 ICF_STRGAD_FILTER |
88 ICF_COERCE_LACE;
89 GetPrivIBase(IntuitionBase)->IControlPrefs.ic_WBtoFront = 'N';
90 GetPrivIBase(IntuitionBase)->IControlPrefs.ic_FrontToBack = 'M';
91 GetPrivIBase(IntuitionBase)->IControlPrefs.ic_ReqTrue = 'V';
92 GetPrivIBase(IntuitionBase)->IControlPrefs.ic_ReqFalse = 'B';
96 * Mouse default.
98 GetPrivIBase(IntuitionBase)->DefaultPreferences->PointerTicks = 2;
100 /* FIXME: Try to load preferences from a file! */
103 /*******************************************************************
104 DOSBase = OpenLibrary("dos.library",0);
105 if (NULL != DOSBase)
107 if (NULL != (pref_file = Open("envarc:",MODE_OLDFILE)))
110 ** Read it and check whether the file was valid.
113 if (sizeof(struct Preferences) ==
114 Read(pref_file,
115 GetPrivIBase(IntuitionBase)->DefaultPreferences,
116 sizeof(struct Preferences)))
117 read_preferences = TRUE;
119 Close(pref_file);
121 CloseLibrary(DOSBase)
123 ****************************************************************/
125 if (FALSE == read_preferences)
128 ** no (valid) preferences file is available.
130 CopyMem(&IntuitionDefaultPreferences,
131 GetPrivIBase(IntuitionBase)->DefaultPreferences,
132 sizeof(struct Preferences));
137 ** Activate the preferences...
140 GetPrivIBase(IntuitionBase)->ActivePreferences =
141 AllocMem(sizeof(struct Preferences),
142 MEMF_CLEAR);
144 #if 1
145 CopyMem(GetPrivIBase(IntuitionBase)->DefaultPreferences,
146 GetPrivIBase(IntuitionBase)->ActivePreferences,
147 sizeof(struct Preferences));
148 #else
149 SetPrefs(GetPrivIBase(IntuitionBase)->DefaultPreferences,
150 sizeof(struct Preferences),
151 FALSE/*TRUE*/);
152 #endif
154 CopyMem(DriPens2, GetPrivIBase(IntuitionBase)->DriPens2, sizeof(DriPens2));
155 CopyMem(DriPens4, GetPrivIBase(IntuitionBase)->DriPens4, sizeof(DriPens4));
156 CopyMem(DriPens4, GetPrivIBase(IntuitionBase)->DriPens8, sizeof(DriPens4));
159 /**********************************************************************************/
161 void CheckRectFill(struct RastPort *rp, WORD x1, WORD y1, WORD x2, WORD y2,
162 struct IntuitionBase * IntuitionBase)
165 if ((x2 >= x1) && (y2 >= y1))
167 RectFill(rp, x1, y1, x2, y2);
171 /**********************************************************************************/
173 #define TITLEBAR_HEIGHT (w->BorderTop)
175 Object* CreateStdSysImage(WORD which, WORD preferred_height, struct Screen *scr, APTR buffer,
176 struct DrawInfo *dri, struct IntuitionBase *IntuitionBase)
178 Object *im;
180 struct TagItem image_tags[] =
182 {SYSIA_Which , which },
183 {SYSIA_DrawInfo , (IPTR)dri },
184 {SYSIA_Size , scr->Flags & SCREENHIRES ?
185 SYSISIZE_MEDRES : SYSISIZE_LOWRES },
186 {SYSIA_UserBuffer , (IPTR)buffer },
187 {TAG_DONE }
190 im = NewObjectA(NULL, SYSICLASS, image_tags);
191 if (im)
193 struct TagItem size_tags[] =
195 {IA_Width , 0 },
196 {IA_Height , preferred_height },
197 {TAG_DONE }
199 IPTR width, height;
201 GetAttr(IA_Width, im, &width);
202 GetAttr(IA_Height, im, &height);
204 size_tags[0].ti_Data = preferred_height * width / height;
206 SetAttrsA(im, size_tags);
209 return im;
212 /**********************************************************************************/
214 BOOL CreateWinSysGadgets(struct Window *w, struct IntuitionBase *IntuitionBase)
217 struct DrawInfo *dri;
218 BOOL is_gzz;
220 EnterFunc(bug("CreateWinSysGadgets(w=%p)\n", w));
222 is_gzz = (w->Flags & WFLG_GIMMEZEROZERO) ? TRUE : FALSE;
224 dri = GetScreenDrawInfo(w->WScreen);
225 if (dri)
227 LONG db_left, db_width, relright,ewidth; /* dragbar sizes */
228 BOOL sysgads_ok = TRUE;
231 db_left = 0;
232 db_width = 0; /* Georg Steger: was w->Width; */
234 /* Relright of rightmost button */
235 //relright = - (TITLEBAR_HEIGHT - 1);
237 relright = 1;
239 /* Now try to create the various gadgets */
241 if (w->Flags & WFLG_SIZEGADGET)
243 /* this code must not change the 'relright' variable */
244 WORD width = ((struct IntWindow *)w)->sizeimage_width;
245 WORD height = ((struct IntWindow *)w)->sizeimage_height;
247 struct TagItem size_tags[] =
249 {GA_Image , 0 },
250 {GA_RelRight , -width + 1 },
251 {GA_RelBottom , -height + 1 },
252 {GA_Width , width },
253 {GA_Height , height },
254 {GA_SysGadget , TRUE },
255 {GA_SysGType , GTYP_SIZING },
256 {GA_BottomBorder, TRUE },
257 {GA_RightBorder , TRUE },
258 {GA_GZZGadget , is_gzz },
259 {TAG_DONE }
262 struct TagItem image_tags[] =
264 {IA_Width , width },
265 {IA_Height , height },
266 {SYSIA_Which , SIZEIMAGE },
267 {SYSIA_DrawInfo , (IPTR)dri },
268 {SYSIA_UserBuffer, ((struct IntWindow *)(w))->DecorUserBuffer },
269 {SYSIA_Size , w->WScreen->Flags & SCREENHIRES ? SYSISIZE_MEDRES : SYSISIZE_LOWRES},
270 {TAG_DONE }
272 Object *im;
274 im = NewObjectA(NULL, SYSICLASS, image_tags);
275 if (!im)
277 sysgads_ok = FALSE;
279 else
281 size_tags[0].ti_Data = (IPTR)im;
283 SYSGAD(w, SIZEGAD) = NewObjectA(NULL, BUTTONGCLASS, size_tags);
285 if (!SYSGAD(w, SIZEGAD))
287 DisposeObject(im);
288 sysgads_ok = FALSE;
293 if (w->Flags & WFLG_DEPTHGADGET)
295 struct TagItem depth_tags[] =
297 {GA_Image , 0 },
298 //{GA_RelRight , relright },
299 {GA_Top , 0 },
300 #if SQUARE_WIN_GADGETS
301 {GA_Width , TITLEBAR_HEIGHT },
302 #endif
303 {GA_Height , TITLEBAR_HEIGHT },
304 {GA_SysGadget , TRUE },
305 {GA_SysGType , GTYP_WDEPTH },
306 {GA_TopBorder , TRUE },
307 {GA_GZZGadget , is_gzz },
308 {GA_RelVerify , TRUE },
309 {TAG_DONE }
311 Object *im;
313 im = CreateStdSysImage(DEPTHIMAGE, TITLEBAR_HEIGHT, w->WScreen, (APTR)((struct IntWindow *)(w))->DecorUserBuffer, dri, IntuitionBase);
314 if (!im)
316 sysgads_ok = FALSE;
318 else
320 depth_tags[0].ti_Data = (IPTR)im;
322 SYSGAD(w, DEPTHGAD) = NewObjectA(NULL, BUTTONGCLASS, depth_tags);
324 if (!SYSGAD(w, DEPTHGAD))
326 DisposeObject(im);
327 sysgads_ok = FALSE;
329 else
331 IPTR width;
332 GetAttr(GA_Width, SYSGAD(w, DEPTHGAD), &width);
334 /*****/
336 relright -= width;
337 db_width -= width;
340 struct TagItem gadtags[] =
342 {GA_RelRight, relright },
343 /* {GA_Width , width }, */
344 {TAG_DONE }
347 SetAttrsA(SYSGAD(w, DEPTHGAD), gadtags);
354 /* RKRMs: window gets zoom gadget if WA_Zoom tag was used,
355 or if window has both a sizegadget and a depthgadget */
357 if ((w->Flags & WFLG_HASZOOM) ||
358 ((w->Flags & WFLG_SIZEGADGET) && (w->Flags & WFLG_DEPTHGADGET)))
360 struct TagItem zoom_tags[] =
362 {GA_Image , 0 },
363 //{GA_RelRight , relright },
364 {GA_Top , 0 },
365 #if SQUARE_WIN_GADGETS
366 {GA_Width , TITLEBAR_HEIGHT },
367 #endif
368 {GA_Height , TITLEBAR_HEIGHT },
369 {GA_SysGadget , TRUE },
370 {GA_SysGType , GTYP_WZOOM },
371 {GA_TopBorder , TRUE },
372 {GA_GZZGadget , is_gzz },
373 {GA_RelVerify , TRUE },
374 {TAG_DONE }
377 Object *im;
379 im = CreateStdSysImage(ZOOMIMAGE, TITLEBAR_HEIGHT, w->WScreen, (APTR)((struct IntWindow *)(w))->DecorUserBuffer, dri, IntuitionBase);
380 if (!im)
382 sysgads_ok = FALSE;
384 else
386 zoom_tags[0].ti_Data = (IPTR)im;
388 SYSGAD(w, ZOOMGAD) = NewObjectA(NULL, BUTTONGCLASS, zoom_tags);
390 if (!SYSGAD(w, ZOOMGAD))
392 DisposeObject(im);
393 sysgads_ok = FALSE;
395 else
397 IPTR width;
398 GetAttr(GA_Width, SYSGAD(w, ZOOMGAD), &width);
400 relright -= width;
401 db_width -= width;
404 struct TagItem gadtags[] =
406 {GA_RelRight, relright},
407 {TAG_DONE }
411 SetAttrsA(SYSGAD(w, ZOOMGAD), gadtags);
417 if (((struct IntWindow *)(w))->extrabuttons & ETG_LOCK)
419 ewidth = addextragadget(w,is_gzz,dri,relright,LOCKIMAGE,((struct IntWindow *)w)->extrabuttonsid + ETD_Lock,LOCKGAD,IntuitionBase);
420 relright -= ewidth;
421 db_width -= ewidth;
424 if (((struct IntWindow *)(w))->extrabuttons & ETG_ICONIFY)
426 ewidth = addextragadget(w,is_gzz,dri,relright,ICONIFYIMAGE,((struct IntWindow *)w)->extrabuttonsid + ETD_Iconify,ICONIFYGAD,IntuitionBase);
427 relright -= ewidth;
428 db_width -= ewidth;
431 if (((struct IntWindow *)(w))->extrabuttons & ETG_JUMP)
433 ewidth = addextragadget(w,is_gzz,dri,relright,JUMPIMAGE,((struct IntWindow *)w)->extrabuttonsid + ETD_Jump,JUMPGAD,IntuitionBase);
434 relright -= ewidth;
435 db_width -= ewidth;
438 if (((struct IntWindow *)(w))->extrabuttons & ETG_SNAPSHOT)
440 ewidth = addextragadget(w,is_gzz,dri,relright,SNAPSHOTIMAGE,((struct IntWindow *)w)->extrabuttonsid + ETD_Snapshot,SNAPSHOTGAD,IntuitionBase);
441 relright -= ewidth;
442 db_width -= ewidth;
445 if (((struct IntWindow *)(w))->extrabuttons & ETG_MUI)
447 ewidth = addextragadget(w,is_gzz,dri,relright,MUIIMAGE,((struct IntWindow *)w)->extrabuttonsid + ETD_MUI,MUIGAD,IntuitionBase);
448 relright -= ewidth;
449 db_width -= ewidth;
452 if (((struct IntWindow *)(w))->extrabuttons & ETG_POPUP)
454 ewidth = addextragadget(w,is_gzz,dri,relright,POPUPIMAGE,((struct IntWindow *)w)->extrabuttonsid + ETD_PopUp,POPUPGAD,IntuitionBase);
455 relright -= ewidth;
456 db_width -= ewidth;
459 if (w->Flags & WFLG_CLOSEGADGET)
461 struct TagItem close_tags[] =
463 {GA_Image , 0 },
464 {GA_Left , 0 },
465 {GA_Top , 0 },
466 #if SQUARE_WIN_GADGETS
467 {GA_Width , TITLEBAR_HEIGHT },
468 #endif
469 {GA_Height , TITLEBAR_HEIGHT },
470 {GA_SysGadget , TRUE },
471 {GA_SysGType , GTYP_CLOSE },
472 {GA_TopBorder , TRUE },
473 {GA_GZZGadget , is_gzz },
474 {GA_RelVerify , TRUE },
475 {TAG_DONE }
477 Object *im;
479 im = CreateStdSysImage(CLOSEIMAGE, TITLEBAR_HEIGHT, w->WScreen, (APTR)((struct IntWindow *)(w))->DecorUserBuffer, dri,IntuitionBase);
480 if (!im)
482 sysgads_ok = FALSE;
484 else
486 close_tags[0].ti_Data = (IPTR)im;
488 SYSGAD(w, CLOSEGAD) = NewObjectA(NULL, BUTTONGCLASS, close_tags);
490 if (!SYSGAD(w, CLOSEGAD))
492 DisposeObject(im);
493 sysgads_ok = FALSE;
495 else
497 IPTR width;
498 GetAttr(GA_Width, SYSGAD(w, CLOSEGAD), &width);
500 db_left += width;
501 db_width -= width;
506 if (w->Flags & WFLG_DRAGBAR)
509 struct TagItem dragbar_tags[] =
511 {GA_Left , 0/*db_left*/ },
512 {GA_Top , 0 },
513 {GA_RelWidth , 0/*db_width*/ },
514 {GA_Height , TITLEBAR_HEIGHT },
515 {GA_SysGadget , TRUE },
516 {GA_SysGType , GTYP_WDRAGGING },
517 {GA_TopBorder , TRUE },
518 {GA_GZZGadget , is_gzz },
519 {TAG_DONE }
521 SYSGAD(w, DRAGBAR) = NewObjectA(NULL, BUTTONGCLASS, dragbar_tags);
523 if (!SYSGAD(w, DRAGBAR))
524 sysgads_ok = FALSE;
529 D(bug("Dragbar: %p\n", SYSGAD(w, DRAGBAR ) ));
530 D(bug("Depthgad: %p\n", SYSGAD(w, DEPTHGAD) ));
531 D(bug("Zoomgad: %p\n", SYSGAD(w, ZOOMGAD ) ));
532 D(bug("Closegad: %p\n", SYSGAD(w, CLOSEGAD) ));
533 D(bug("Sizegad: %p\n", SYSGAD(w, SIZEGAD ) ));
535 /* Don't need drawinfo anymore */
536 FreeScreenDrawInfo(w->WScreen, dri);
538 if (sysgads_ok)
540 int i;
543 D(bug("Adding gadgets\n"));
544 for (i = NUM_SYSGADS; --i >= 0; )
546 if (SYSGAD(w, i))
548 struct wdpLayoutBorderGadgets msg;
550 msg.MethodID = WDM_LAYOUT_BORDERGADGETS;
551 msg.wdp_Window = w;
552 msg.wdp_Gadgets = (struct Gadget *)SYSGAD(w, i);
553 msg.wdp_Flags = WDF_LBG_SYSTEMGADGET | WDF_LBG_INITIAL;
554 msg.wdp_UserBuffer = ((struct IntWindow *)(w))->DecorUserBuffer;
555 msg.wdp_ExtraButtons = ((struct IntWindow *)w)->extrabuttons;
557 msg.wdp_TrueColor = (((struct IntScreen *)w->WScreen)->DInfo.dri.dri_Flags & DRIF_DIRECTCOLOR);
558 msg.wdp_Dri = dri;
560 DoMethodA(((struct IntScreen *)(w->WScreen))->WinDecorObj, (Msg)&msg);
562 AddGadget(w, (struct Gadget *)SYSGAD(w, i), 0);
566 ReturnBool("CreateWinSysGadgets", TRUE);
568 } /* if (sysgads created) */
570 KillWinSysGadgets(w, IntuitionBase);
572 } /* if (got DrawInfo) */
573 ReturnBool("CreateWinSysGadgets", FALSE);
577 /**********************************************************************************/
579 VOID KillWinSysGadgets(struct Window *w, struct IntuitionBase *IntuitionBase)
581 /* Free system gadgets */
582 UWORD i;
584 for (i = 0; i < NUM_SYSGADS; i ++)
586 if (SYSGAD(w, i))
588 RemoveGadget( w, (struct Gadget *)SYSGAD(w, i));
589 DisposeObject((Object *)((struct Gadget *)SYSGAD(w, i))->GadgetRender);
590 DisposeObject( SYSGAD(w, i) );
595 /**********************************************************************************/
597 void CreateScreenBar(struct Screen *scr, struct IntuitionBase *IntuitionBase)
599 BOOL front = TRUE;
600 ULONG backdrop = LAYERBACKDROP;
601 WORD ypos = 0;
603 D(bug("[intuition] CreateScreenBar()\n"));
605 #ifdef SKINS
606 if (scr->Flags & SCREENQUIET || (GetPrivScreen(scr)->SpecialFlags & SF_InvisibleBar))
607 front = FALSE;
609 if (GetPrivScreen(scr)->SpecialFlags & SF_AppearingBar)
611 backdrop = 0;
612 ypos = - (scr->BarHeight + 1);
614 #else
615 if (scr->Flags & SCREENQUIET) front = FALSE;
616 #endif
617 D(bug("[intuition] CreateScreenBar: Got initial flags\n"));
619 if (!scr->BarLayer)
621 D(bug("[intuition] CreateScreenBar: No current BarLayer\n"));
622 if (front)
624 scr->BarLayer = CreateUpfrontHookLayer(&scr->LayerInfo,
625 scr->RastPort.BitMap,
627 ypos,
628 scr->Width - 1,
629 scr->BarHeight + ypos, /* 1 pixel heigher than scr->BarHeight */
630 LAYERSIMPLE | backdrop,
631 LAYERS_NOBACKFILL,
632 NULL);
634 else
636 scr->BarLayer = CreateBehindHookLayer(&scr->LayerInfo,
637 scr->RastPort.BitMap,
639 ypos,
640 scr->Width - 1,
641 scr->BarHeight + ypos, /* 1 pixel heigher than scr->BarHeight */
642 LAYERSIMPLE | backdrop,
643 LAYERS_NOBACKFILL,
644 NULL);
647 if (scr->BarLayer)
649 D(bug("[intuition] CreateScreenBar: Adding BarLayer @ %p\n", scr->BarLayer));
650 D(bug("[intuition] CreateScreenBar: Rastport @ %p, Font @ %p\n", scr->BarLayer->rp, ((struct IntScreen *)scr)->DInfo.dri.dri_Font));
651 SetFont(scr->BarLayer->rp, ((struct IntScreen *)scr)->DInfo.dri.dri_Font);
652 if (!(scr->Flags & SCREENQUIET)) {
653 D(bug("[intuition] CreateScreenBar: Rendering Bar ...\n"));
654 RenderScreenBar(scr, FALSE, IntuitionBase);
656 D(bug("[intuition] CreateScreenBar: ... done\n"));
658 else
660 D(bug("[intuition] CreateScreenBar: Failed to create BarLayer!!\n"));
663 else
665 D(bug("[intuition] CreateScreenBar: Screen already has BarLayer\n"));
669 /**********************************************************************************/
671 void KillScreenBar(struct Screen *scr, struct IntuitionBase *IntuitionBase)
673 if (scr->BarLayer)
675 DeleteLayer(0, scr->BarLayer);
676 scr->BarLayer = FALSE;
681 /**********************************************************************************/
683 #ifdef SKINS
684 //RenderScreenBar moved to morphos/mosmisc.c
685 #endif
687 #ifndef SKINS
689 void RenderScreenBar(struct Screen *scr, BOOL refresh, struct IntuitionBase *IntuitionBase)
692 struct DrawInfo *dri = &((struct IntScreen *)scr)->DInfo.dri;
693 struct RastPort *rp;
695 D(bug("[intuition] RenderScreenBar()\n"));
697 if (scr->BarLayer)
699 #if USE_NEWDISPLAYBEEP
700 BOOL beeping;
701 #else
702 #define beeping 0
703 #endif
705 D(bug("[intuition] RenderScreenBar: BarLayer @ %p\n", scr->BarLayer));
707 rp = scr->BarLayer->rp;
709 D(bug("[intuition] RenderScreenBar: RastPort @ %p\n", rp));
710 /* must lock GadgetLock to avoid deadlocks with ObtainGIRPort
711 when calling refreshgadget inside layer update state */
712 LockLayerInfo(scr->BarLayer->LayerInfo);
713 LOCKGADGET
714 LockLayer(0, scr->BarLayer);
716 D(bug("[intuition] RenderScreenBar: Layer locked\n"));
717 #if USE_NEWDISPLAYBEEP
718 beeping = (scr->Flags & BEEPING) && GetBitMapAttr(rp->BitMap, BMA_DEPTH) > 8;
719 #endif
721 if (refresh) BeginUpdate(scr->BarLayer);
724 struct sdpDrawScreenBar msg;
726 D(bug("[intuition] RenderScreenBar: Begin Refresh .. \n"));
728 msg.MethodID = SDM_DRAW_SCREENBAR;
729 msg.sdp_Layer = scr->BarLayer;
730 msg.sdp_RPort = rp;
731 msg.sdp_Flags = 0;
732 msg.sdp_Screen = scr;
733 msg.sdp_Dri = dri;
734 msg.sdp_UserBuffer = ((struct IntScreen *)(scr))->DecorUserBuffer;
735 msg.sdp_TrueColor = (((struct IntScreen *)(scr))->DInfo.dri.dri_Flags & DRIF_DIRECTCOLOR);
737 D(bug("[intuition] RenderScreenBar: ScrDecorObj @ %p, DecorUserBuffer @ %p\n", ((struct IntScreen *)(scr))->ScrDecorObj, ((struct IntScreen *)(scr))->DecorUserBuffer));
738 DoMethodA(((struct IntScreen *)(scr))->ScrDecorObj, (Msg)&msg);
741 D(bug("[intuition] RenderScreenBar: Update gadgets .. \n"));
743 if (scr->FirstGadget)
745 RefreshBoopsiGadget(scr->FirstGadget, (struct Window *)scr, NULL, IntuitionBase);
748 if (refresh)
750 D(bug("[intuition] RenderScreenBar: End Refresh .. \n"));
751 scr->BarLayer->Flags &= ~LAYERREFRESH;
752 EndUpdate(scr->BarLayer, TRUE);
755 D(bug("[intuition] RenderScreenBar: Unlock Layer ..\n"));
757 UnlockLayer(scr->BarLayer);
758 UNLOCKGADGET
759 UnlockLayerInfo(scr->BarLayer->LayerInfo);
761 } /* if (scr->BarLayer) */
762 D(bug("[intuition] RenderScreenBar: Done \n"));
765 #endif
767 /**********************************************************************************/
769 void UpdateMouseCoords(struct Window *win)
771 WORD scrmousex = win->WScreen->MouseX;
772 WORD scrmousey = win->WScreen->MouseY;
774 win->MouseX = scrmousex - win->LeftEdge;
775 win->MouseY = scrmousey - win->TopEdge;
777 /* stegerg: AmigaOS sets this even if window is not GZZ
778 so we do the same as they are handy also for non-GZZ
779 windows */
781 win->GZZMouseX = scrmousex - (win->LeftEdge + win->BorderLeft);
782 win->GZZMouseY = scrmousey - (win->TopEdge + win->BorderTop);
785 /**********************************************************************************/
787 /* subtract rectangle b from rectangle b. resulting rectangles will be put into
788 destrectarray which must have place for at least 4 rectangles. Returns number
789 of resulting rectangles */
791 #if 0 /* use <clib/macros.h> MAX/MIN macros */
792 #undef MAX
793 #define MAX(a,b) (((a) > (b)) ? (a) : (b))
795 #undef MIN
796 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
797 #endif
799 WORD SubtractRectFromRect(struct Rectangle *a, struct Rectangle *b, struct Rectangle *destrectarray)
801 struct Rectangle intersect;
802 BOOL intersecting = FALSE;
803 WORD numrects = 0;
805 /* calc. intersection between a and b */
807 if (a->MinX <= b->MaxX)
809 if (a->MinY <= b->MaxY)
811 if (a->MaxX >= b->MinX)
813 if (a->MaxY >= b->MinY)
815 intersect.MinX = MAX(a->MinX, b->MinX);
816 intersect.MinY = MAX(a->MinY, b->MinY);
817 intersect.MaxX = MIN(a->MaxX, b->MaxX);
818 intersect.MaxY = MIN(a->MaxY, b->MaxY);
820 intersecting = TRUE;
826 if (!intersecting)
828 destrectarray[numrects++] = *a;
830 } /* not intersecting */
831 else
833 if (intersect.MinY > a->MinY) /* upper */
835 destrectarray->MinX = a->MinX;
836 destrectarray->MinY = a->MinY;
837 destrectarray->MaxX = a->MaxX;
838 destrectarray->MaxY = intersect.MinY - 1;
840 numrects++;
841 destrectarray++;
844 if (intersect.MaxY < a->MaxY) /* lower */
846 destrectarray->MinX = a->MinX;
847 destrectarray->MinY = intersect.MaxY + 1;
848 destrectarray->MaxX = a->MaxX;
849 destrectarray->MaxY = a->MaxY;
851 numrects++;
852 destrectarray++;
855 if (intersect.MinX > a->MinX) /* left */
857 destrectarray->MinX = a->MinX;
858 destrectarray->MinY = intersect.MinY;
859 destrectarray->MaxX = intersect.MinX - 1;
860 destrectarray->MaxY = intersect.MaxY;
862 numrects++;
863 destrectarray++;
866 if (intersect.MaxX < a->MaxX) /* right */
868 destrectarray->MinX = intersect.MaxX + 1;
869 destrectarray->MinY = intersect.MinY;
870 destrectarray->MaxX = a->MaxX;
871 destrectarray->MaxY = intersect.MaxY;
873 numrects++;
874 destrectarray++;
877 } /* intersecting */
879 return numrects;
883 ULONG addextragadget(struct Window *w,BOOL is_gzz,struct DrawInfo *dri,LONG relright,ULONG imagetype,ULONG gadgetid,ULONG gadgettype,struct IntuitionBase *IntuitionBase)
885 struct TagItem gadget_tags[] =
887 {GA_Image , 0 },
888 {GA_ToggleSelect, FALSE },
889 {GA_Top , 0 },
890 {GA_Height , TITLEBAR_HEIGHT },
891 {GA_TopBorder , TRUE },
892 {GA_GZZGadget , is_gzz },
893 {GA_ID , gadgetid },
894 {GA_RelVerify , TRUE },
895 {TAG_DONE }
897 struct TagItem image_tags[] =
899 #ifdef SKINS
900 {TAG_IGNORE , 0 },
901 #else
902 {IA_Left , -1 },
903 #endif
904 {IA_Height , TITLEBAR_HEIGHT },
905 {SYSIA_Which , imagetype },
906 {SYSIA_DrawInfo , (IPTR)dri },
907 {SYSIA_Size , w->WScreen->Flags & SCREENHIRES ?
908 SYSISIZE_MEDRES : SYSISIZE_LOWRES },
909 {SYSIA_UserBuffer, ((struct IntWindow *)(w))->DecorUserBuffer },
911 {TAG_DONE }
913 Object *im;
915 if (gadgettype == LOCKGAD)
916 gadget_tags[1].ti_Data = TRUE;
918 im = NewObjectA(NULL, SYSICLASS, image_tags);
919 if (im)
921 gadget_tags[0].ti_Data = (IPTR)im;
923 SYSGAD(w, gadgettype) = NewObjectA(NULL, BUTTONGCLASS, gadget_tags);
925 if (!SYSGAD(w, gadgettype))
927 DisposeObject(im);
929 else
931 IPTR width;
932 GetAttr(GA_Width, SYSGAD(w, gadgettype), &width);
934 --width;
937 struct TagItem gadtags[] =
939 {GA_RelRight, relright - width },
940 {TAG_DONE }
943 SetAttrsA(SYSGAD(w, gadgettype), gadtags);
946 return width;
950 return 0;
954 /**********************************************************************************/
956 /* Use the FNV-1 hash function over the object's pointer.
957 * http://en.wikipedia.org/wiki/Fowler-Noll-Vo_hash_function
959 LONG CalcResourceHash(APTR resource)
961 const ULONG FNV1_32_Offset = 2166136261UL;
962 const ULONG FNV1_32_Prime = 16777619UL;
963 IPTR data = (IPTR)resource;
964 ULONG hash;
965 int i;
967 hash = FNV1_32_Offset;
968 for (i = 0; i < AROS_SIZEOFPTR; i++) {
969 hash *= FNV1_32_Prime;
970 hash ^= data & 0xff;
971 data >>= 8;
974 return hash & (RESOURCELIST_HASHSIZE-1);
977 /**********************************************************************************/
979 void AddResourceToList(APTR resource, UWORD resourcetype, struct IntuitionBase *IntuitionBase)
981 struct HashNode *hn = NULL;
982 LONG hash;
983 ULONG ilock;
985 switch(resourcetype)
987 case RESOURCE_WINDOW:
988 hn = &((struct IntWindow *)resource)->hashnode;
989 hn->type = RESOURCE_WINDOW;
990 break;
992 case RESOURCE_SCREEN:
993 hn = &((struct IntScreen *)resource)->hashnode;
994 hn->type = RESOURCE_SCREEN;
995 break;
997 default:
998 D(bug("AddResourceToList: Unknown resource type!!!\n"));
999 return;
1002 hash = CalcResourceHash(resource);
1004 hn->resource = resource;
1006 ilock = LockIBase(0);
1007 AddTail((struct List *)&GetPrivIBase(IntuitionBase)->ResourceList[hash], (struct Node *)hn);
1008 UnlockIBase(ilock);
1011 /**********************************************************************************/
1013 void RemoveResourceFromList(APTR resource, UWORD resourcetype, struct IntuitionBase *IntuitionBase)
1015 struct HashNode *hn = NULL;
1016 ULONG ilock;
1018 switch(resourcetype)
1020 case RESOURCE_WINDOW:
1021 hn = &((struct IntWindow *)resource)->hashnode;
1022 break;
1024 case RESOURCE_SCREEN:
1025 hn = &((struct IntScreen *)resource)->hashnode;
1026 break;
1028 default:
1029 D(bug("RemoveResourceFromList: Unknown resource type!!!\n"));
1030 return;
1033 if (hn->type != resourcetype)
1035 D(bug("RemoveResourceFromList: Panic. Resource Type mismatch!!!\n"));
1038 ilock = LockIBase(0);
1039 Remove((struct Node *)hn);
1040 UnlockIBase(ilock);
1043 /**********************************************************************************/
1045 BOOL ResourceExisting(APTR resource, UWORD resourcetype, struct IntuitionBase *IntuitionBase)
1047 struct HashNode *hn = NULL;
1048 LONG hash;
1049 ULONG ilock;
1050 BOOL exists = FALSE;
1052 hash = CalcResourceHash(resource);
1054 ilock = LockIBase(0);
1055 ForeachNode((struct List *)&GetPrivIBase(IntuitionBase)->ResourceList[hash], hn)
1057 if ((hn->resource == resource) && (hn->type == resourcetype))
1059 exists = TRUE;
1060 break;
1063 UnlockIBase(ilock);
1065 return exists;
1068 void FireScreenNotifyMessageCode(IPTR data, ULONG flag, ULONG code, struct IntuitionBase *IntuitionBase)
1070 ObtainSemaphoreShared(&GetPrivIBase(IntuitionBase)->ScreenNotificationListLock);
1072 struct ScreenNotifyMessage *msg;
1073 struct ReplyPort *reply;
1075 struct IntScreenNotify *sn;
1076 struct Node *node;
1078 if (!IsListEmpty(&GetPrivIBase(IntuitionBase)->ScreenNotificationList))
1080 node = GetPrivIBase(IntuitionBase)->ScreenNotificationList.lh_Head;
1081 for (; node->ln_Succ; node = node->ln_Succ)
1083 sn = (struct IntScreenNotify *) node;
1084 BOOL leavescreen = FALSE;
1085 if (flag & (SNOTIFY_AFTER_OPENSCREEN | SNOTIFY_BEFORE_OPENSCREEN | SNOTIFY_AFTER_CLOSESCREEN | SNOTIFY_BEFORE_CLOSESCREEN | SNOTIFY_LOCKPUBSCREEN | SNOTIFY_UNLOCKPUBSCREEN))
1088 if ((sn->flags & flag) && !leavescreen)
1090 if (sn->port)
1092 msg = AllocMem(sizeof(struct ScreenNotifyMessage), MEMF_CLEAR);
1093 if (msg)
1095 msg->snm_Message.mn_Magic = MAGIC_SCREENNOTIFY;
1096 msg->snm_Message.mn_Version = SCREENNOTIFY_VERSION;
1097 msg->snm_Object = data;
1098 msg->snm_Class = flag;
1099 msg->snm_Code = code;
1100 msg->snm_UserData = sn->userdata;
1101 msg->snm_Message.mn_Length = sizeof(struct ScreenNotifyMessage);
1102 if (sn->flags & SNOTIFY_WAIT_REPLY)
1104 reply = (struct ReplyPort *)CreateMsgPort();
1105 if (reply)
1107 msg->snm_Message.mn_ReplyPort = (struct MsgPort *)reply;
1109 PutMsg((struct MsgPort *)sn->port, (struct Message *) msg);
1110 WaitPort((struct MsgPort *)reply);
1111 GetMsg((struct MsgPort *)reply);
1112 FreeMem((APTR) msg, sizeof(struct ScreenNotifyMessage));
1113 DeleteMsgPort((struct MsgPort *)reply);
1114 } else FreeMem((APTR) msg, sizeof(struct ScreenNotifyMessage));
1116 else
1118 msg->snm_Message.mn_ReplyPort = GetPrivIBase(IntuitionBase)->ScreenNotifyReplyPort;
1120 PutMsg(sn->port, (struct Message *) msg);
1125 else if (sn->sigtask)
1127 Signal(sn->sigtask, 1 << sn->sigbit);
1129 else if (sn->hook)
1131 struct ScreenNotifyMessage msg;
1132 msg.snm_Message.mn_Magic = MAGIC_SCREENNOTIFY;
1133 msg.snm_Message.mn_Version = SCREENNOTIFY_VERSION;
1134 msg.snm_Object = data;
1135 msg.snm_Class = flag;
1136 msg.snm_UserData = sn->userdata;
1137 msg.snm_Message.mn_Length = sizeof(struct ScreenNotifyMessage);
1139 CallHook(sn->hook, NULL, (Msg) &msg);
1144 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->ScreenNotificationListLock);
1147 void FireScreenNotifyMessage(IPTR data, ULONG flag, struct IntuitionBase *IntuitionBase)
1149 FireScreenNotifyMessageCode(data, flag, 0, IntuitionBase);
1152 /**********************************************************************************/
1154 AROS_UFH3(struct Region *, DefaultWindowShapeFunc,
1155 AROS_UFHA(struct Hook *, hook, A0),
1156 AROS_UFHA(struct Layer *, lay, A2),
1157 AROS_UFHA(struct ShapeHookMsg *, msg, A1))
1159 AROS_USERFUNC_INIT
1161 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)hook->h_Data;
1162 struct Window *win = (struct Window *)hook->h_SubEntry;
1163 struct Region *shape;
1164 struct wdpWindowShape shapemsg;
1166 shapemsg.MethodID = WDM_WINDOWSHAPE;
1167 shapemsg.wdp_TrueColor = (GetPrivScreen(win->WScreen)->DInfo.dri.dri_Flags & DRIF_DIRECTCOLOR) ? TRUE : FALSE;
1168 shapemsg.wdp_Width = msg->NewBounds.MaxX - msg->NewBounds.MinX + 1;
1169 shapemsg.wdp_Height = msg->NewBounds.MaxY - msg->NewBounds.MinY + 1;
1170 shapemsg.wdp_Window = win;
1171 shapemsg.wdp_UserBuffer = IW(win)->DecorUserBuffer;
1173 shape = (struct Region *)DoMethodA(GetPrivScreen(win->WScreen)->WinDecorObj, (Msg)&shapemsg);
1175 if (IW(win)->OutlineShape) DisposeRegion(IW(win)->OutlineShape);
1176 IW(win)->OutlineShape = shape;
1177 IW(win)->CustomShape = FALSE;
1179 return shape;
1181 AROS_USERFUNC_EXIT
1184 /**********************************************************************************/