Check for SYS/GL during library init. Reason is that
[AROS.git] / rom / intuition / intuition_misc.c
blobf8a70a5223edadca007a54e95b0624dd2c12d4f1
1 /*
2 Copyright © 1995-2015, The AROS Development Team. All rights reserved.
3 Copyright © 2001-2013, 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 <proto/oop.h>
15 #include <clib/macros.h>
16 #include <intuition/intuitionbase.h>
17 #include <intuition/gadgetclass.h>
18 #include <intuition/imageclass.h>
19 #include <intuition/windecorclass.h>
20 #include <intuition/scrdecorclass.h>
21 #include <intuition/preferences.h>
22 #include <intuition/extensions.h>
23 #include <graphics/layers.h>
24 #include <graphics/rpattr.h>
25 #include <graphics/gfxmacros.h>
26 #include <cybergraphx/cybergraphics.h>
27 #include <hidd/graphics.h>
29 #ifdef SKINS
30 # include "intuition_customize.h"
31 # include "intuition_extend.h"
32 # include "mosmisc.h"
33 #endif
35 #include "intuition_preferences.h"
36 #include "intuition_intern.h"
38 #include "boopsigadgets.h"
39 #include "showhide.h"
41 #include <string.h>
44 #undef DEBUG
45 #define DEBUG 0
46 # include <aros/debug.h>
48 ULONG addextragadget(struct Window *w,BOOL is_gzz,struct DrawInfo *dri,LONG relright,ULONG imagetype,ULONG gadgetid,ULONG gadgettype,struct IntuitionBase *IntuitionBase);
49 extern IPTR HookEntry();
51 /**********************************************************************************/
53 void SetDisplayDefaults(struct IntuitionBase * IntuitionBase)
55 struct IntIntuitionBase *_intuitionBase = GetPrivIBase(IntuitionBase);
56 struct GfxBase *GfxBase = _intuitionBase->GfxBase;
57 struct MonitorSpec *defmon;
58 BOOL done = FALSE;
60 D(bug("[Intuition] %s()\n", __PRETTY_FUNCTION__, defmon));
62 if (!_intuitionBase->ScreenModePrefs)
63 _intuitionBase->ScreenModePrefs = AllocMem(sizeof(struct IScreenModePrefs), MEMF_ANY);
65 _intuitionBase->ScreenModePrefs->smp_DisplayID = INVALID_ID;
66 _intuitionBase->ScreenModePrefs->smp_Control = 0;
68 if ((defmon = OpenMonitor(NULL, INVALID_ID)) != NULL)
70 OOP_Object *sync = (OOP_Object *)defmon->ms_Object, *drv = NULL;
72 D(bug("[Intuition] %s: default monitor @ 0x%p\n", __PRETTY_FUNCTION__, defmon));
74 if (sync)
76 OOP_AttrBase HiddSyncAttrBase = _intuitionBase->HiddSyncAttrBase;
77 struct Library *OOPBase = _intuitionBase->OOPBase;
79 D(bug("[Intuition] %s: monitor sync obj @ 0x%p\n", __PRETTY_FUNCTION__, sync));
81 OOP_GetAttr(sync, aHidd_Sync_GfxHidd, (IPTR *)&drv);
82 if (drv)
84 OOP_MethodID HiddGfxBase = _intuitionBase->ib_HiddGfxBase;
85 UBYTE depth;
87 HIDD_Gfx_NominalDimensions(drv,
88 &_intuitionBase->ScreenModePrefs->smp_Width,
89 &_intuitionBase->ScreenModePrefs->smp_Height,
90 &depth);
91 _intuitionBase->ScreenModePrefs->smp_Depth = depth;
92 done = TRUE;
95 CloseMonitor(defmon);
97 if (!done)
99 D(bug("[Intuition] %s: using system defaults..\n", __PRETTY_FUNCTION__));
101 _intuitionBase->ScreenModePrefs->smp_Width = GfxBase->NormalDisplayColumns;
102 _intuitionBase->ScreenModePrefs->smp_Height = GfxBase->NormalDisplayRows;
103 _intuitionBase->ScreenModePrefs->smp_Depth = AROS_NOMINAL_DEPTH;
107 void LoadDefaultPreferences(struct IntuitionBase * IntuitionBase)
109 struct IntIntuitionBase *_intuitionBase = GetPrivIBase(IntuitionBase);
110 # ifdef SKINS
111 static CONST UWORD DriPens2[NUMDRIPENS] = { 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1 , 1 , 0};
112 static CONST UWORD DriPens4[NUMDRIPENS] = { 1, 0, 1, 2, 1, 3, 1, 0, 2, 1, 2, 1 , 2 , 1};
113 # else
114 static CONST UWORD DriPens2[NUMDRIPENS] = { 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1};
115 static CONST UWORD DriPens4[NUMDRIPENS] = { 1, 0, 1, 2, 1, 3, 1, 0, 2, 1, 2, 1};
116 # endif /* SKINS */
118 /* Default IControl prefs are AROS addition. Keep while backporting. */
119 _intuitionBase->IControlPrefs.ic_TimeOut = 50;
120 _intuitionBase->IControlPrefs.ic_MetaDrag = IEQUALIFIER_LCOMMAND;
121 _intuitionBase->IControlPrefs.ic_Flags = ICF_3DMENUS |
122 ICF_OFFSCREENLAYERS |
123 ICF_AVOIDWINBORDERERASE |
124 ICF_MODEPROMOTE |
125 ICF_MENUSNAP |
126 ICF_STRGAD_FILTER |
127 ICF_COERCE_LACE;
128 _intuitionBase->IControlPrefs.ic_WBtoFront = 'N';
129 _intuitionBase->IControlPrefs.ic_FrontToBack = 'M';
130 _intuitionBase->IControlPrefs.ic_ReqTrue = 'V';
131 _intuitionBase->IControlPrefs.ic_ReqFalse = 'B';
135 * Mouse default.
137 _intuitionBase->DefaultPreferences.PointerTicks = 2;
139 CopyMem(&IntuitionDefaultPreferences,
140 &_intuitionBase->DefaultPreferences,
141 sizeof(struct Preferences));
142 CopyMem(&_intuitionBase->DefaultPreferences,
143 &_intuitionBase->ActivePreferences,
144 sizeof(struct Preferences));
146 CopyMem(DriPens2, _intuitionBase->DriPens2, sizeof(DriPens2));
147 CopyMem(DriPens4, _intuitionBase->DriPens4, sizeof(DriPens4));
148 CopyMem(DriPens4, _intuitionBase->DriPens8, sizeof(DriPens4));
151 /**********************************************************************************/
153 void CheckRectFill(struct RastPort *rp, WORD x1, WORD y1, WORD x2, WORD y2,
154 struct IntuitionBase * IntuitionBase)
156 struct IntIntuitionBase *_intuitionBase = GetPrivIBase(IntuitionBase);
157 struct GfxBase *GfxBase = _intuitionBase->GfxBase;
159 if ((x2 >= x1) && (y2 >= y1))
161 RectFill(rp, x1, y1, x2, y2);
165 /**********************************************************************************/
167 Object* CreateStdSysImage(WORD which, WORD preferred_height, struct Screen *scr,
168 struct DrawInfo *dri, struct IntuitionBase *IntuitionBase)
170 Object *im;
172 struct TagItem image_tags[] =
174 {SYSIA_Which , which },
175 {SYSIA_DrawInfo , (IPTR)dri },
176 {SYSIA_Size , scr->Flags & SCREENHIRES ?
177 SYSISIZE_MEDRES : SYSISIZE_LOWRES },
178 {TAG_DONE }
181 im = NewObjectA(NULL, SYSICLASS, image_tags);
182 if (im)
184 struct TagItem size_tags[] =
186 {IA_Width , 0 },
187 {IA_Height , preferred_height },
188 {TAG_DONE }
190 IPTR width, height;
192 GetAttr(IA_Width, im, &width);
193 GetAttr(IA_Height, im, &height);
195 size_tags[0].ti_Data = preferred_height * width / height;
197 SetAttrsA(im, size_tags);
200 return im;
203 /**********************************************************************************/
205 BOOL CreateWinSysGadgets(struct Window *w, struct IntuitionBase *IntuitionBase)
208 struct DrawInfo *dri;
209 BOOL is_gzz;
210 ULONG TitleHeight = w->BorderTop;
212 EnterFunc(bug("CreateWinSysGadgets(w=%p)\n", w));
214 is_gzz = (w->Flags & WFLG_GIMMEZEROZERO) ? TRUE : FALSE;
216 dri = GetScreenDrawInfo(w->WScreen);
217 if (dri)
219 LONG db_left, db_width, relright,ewidth; /* dragbar sizes */
220 BOOL sysgads_ok = TRUE;
223 db_left = 0;
224 db_width = 0; /* Georg Steger: was w->Width; */
226 /* Relright of rightmost button */
227 //relright = - (TitleHeight - 1);
229 relright = 1;
231 /* Now try to create the various gadgets */
233 if (w->Flags & WFLG_SIZEGADGET)
235 /* this code must not change the 'relright' variable */
236 WORD width = ((struct IntWindow *)w)->sizeimage_width;
237 WORD height = ((struct IntWindow *)w)->sizeimage_height;
239 struct TagItem size_tags[] =
241 {GA_Image , 0 },
242 {GA_RelRight , -width + 1 },
243 {GA_RelBottom , -height + 1 },
244 {GA_Width , width },
245 {GA_Height , height },
246 {GA_SysGadget , TRUE },
247 {GA_SysGType , GTYP_SIZING },
248 {GA_BottomBorder, TRUE },
249 {GA_RightBorder , TRUE },
250 {GA_GZZGadget , is_gzz },
251 {TAG_DONE }
254 struct TagItem image_tags[] =
256 {IA_Width , width },
257 {IA_Height , height },
258 {SYSIA_Which , SIZEIMAGE },
259 {SYSIA_DrawInfo , (IPTR)dri },
260 {SYSIA_Size , w->WScreen->Flags & SCREENHIRES ? SYSISIZE_MEDRES : SYSISIZE_LOWRES},
261 {TAG_DONE }
263 Object *im;
265 im = NewObjectA(NULL, SYSICLASS, image_tags);
266 if (!im)
268 sysgads_ok = FALSE;
270 else
272 size_tags[0].ti_Data = (IPTR)im;
274 SYSGAD(w, SIZEGAD) = NewObjectA(NULL, BUTTONGCLASS, size_tags);
276 if (!SYSGAD(w, SIZEGAD))
278 DisposeObject(im);
279 sysgads_ok = FALSE;
284 if (w->Flags & WFLG_DEPTHGADGET)
286 struct TagItem depth_tags[] =
288 {GA_Image , 0 },
289 //{GA_RelRight , relright },
290 {GA_Top , 0 },
291 #if SQUARE_WIN_GADGETS
292 {GA_Width , TitleHeight },
293 #endif
294 {GA_Height , TitleHeight },
295 {GA_SysGadget , TRUE },
296 {GA_SysGType , GTYP_WDEPTH },
297 {GA_TopBorder , TRUE },
298 {GA_GZZGadget , is_gzz },
299 {GA_RelVerify , TRUE },
300 {TAG_DONE }
302 Object *im;
304 im = CreateStdSysImage(DEPTHIMAGE, TitleHeight, w->WScreen, dri, IntuitionBase);
305 if (!im)
307 sysgads_ok = FALSE;
309 else
311 depth_tags[0].ti_Data = (IPTR)im;
313 SYSGAD(w, DEPTHGAD) = NewObjectA(NULL, BUTTONGCLASS, depth_tags);
315 if (!SYSGAD(w, DEPTHGAD))
317 DisposeObject(im);
318 sysgads_ok = FALSE;
320 else
322 IPTR width;
323 GetAttr(GA_Width, SYSGAD(w, DEPTHGAD), &width);
325 /*****/
327 relright -= width;
328 db_width -= width;
331 struct TagItem gadtags[] =
333 {GA_RelRight, relright },
334 /* {GA_Width , width }, */
335 {TAG_DONE }
338 SetAttrsA(SYSGAD(w, DEPTHGAD), gadtags);
345 /* RKRMs: window gets zoom gadget if WA_Zoom tag was used,
346 or if window has both a sizegadget and a depthgadget */
348 if ((w->Flags & WFLG_HASZOOM) ||
349 ((w->Flags & WFLG_SIZEGADGET) && (w->Flags & WFLG_DEPTHGADGET)))
351 struct TagItem zoom_tags[] =
353 {GA_Image , 0 },
354 //{GA_RelRight , relright },
355 {GA_Top , 0 },
356 #if SQUARE_WIN_GADGETS
357 {GA_Width , TitleHeight },
358 #endif
359 {GA_Height , TitleHeight },
360 {GA_SysGadget , TRUE },
361 {GA_SysGType , GTYP_WZOOM },
362 {GA_TopBorder , TRUE },
363 {GA_GZZGadget , is_gzz },
364 {GA_RelVerify , TRUE },
365 {TAG_DONE }
368 Object *im;
370 im = CreateStdSysImage(ZOOMIMAGE, TitleHeight, w->WScreen, dri, IntuitionBase);
371 if (!im)
373 sysgads_ok = FALSE;
375 else
377 zoom_tags[0].ti_Data = (IPTR)im;
379 SYSGAD(w, ZOOMGAD) = NewObjectA(NULL, BUTTONGCLASS, zoom_tags);
381 if (!SYSGAD(w, ZOOMGAD))
383 DisposeObject(im);
384 sysgads_ok = FALSE;
386 else
388 IPTR width;
389 GetAttr(GA_Width, SYSGAD(w, ZOOMGAD), &width);
391 relright -= width;
392 db_width -= width;
395 struct TagItem gadtags[] =
397 {GA_RelRight, relright},
398 {TAG_DONE }
402 SetAttrsA(SYSGAD(w, ZOOMGAD), gadtags);
408 if (((struct IntWindow *)(w))->extrabuttons & ETG_LOCK)
410 ewidth = addextragadget(w,is_gzz,dri,relright,LOCKIMAGE,((struct IntWindow *)w)->extrabuttonsid + ETD_Lock,LOCKGAD,IntuitionBase);
411 relright -= ewidth;
412 db_width -= ewidth;
415 if (((struct IntWindow *)(w))->extrabuttons & ETG_ICONIFY)
417 ewidth = addextragadget(w,is_gzz,dri,relright,ICONIFYIMAGE,((struct IntWindow *)w)->extrabuttonsid + ETD_Iconify,ICONIFYGAD,IntuitionBase);
418 relright -= ewidth;
419 db_width -= ewidth;
422 if (((struct IntWindow *)(w))->extrabuttons & ETG_JUMP)
424 ewidth = addextragadget(w,is_gzz,dri,relright,JUMPIMAGE,((struct IntWindow *)w)->extrabuttonsid + ETD_Jump,JUMPGAD,IntuitionBase);
425 relright -= ewidth;
426 db_width -= ewidth;
429 if (((struct IntWindow *)(w))->extrabuttons & ETG_SNAPSHOT)
431 ewidth = addextragadget(w,is_gzz,dri,relright,SNAPSHOTIMAGE,((struct IntWindow *)w)->extrabuttonsid + ETD_Snapshot,SNAPSHOTGAD,IntuitionBase);
432 relright -= ewidth;
433 db_width -= ewidth;
436 if (((struct IntWindow *)(w))->extrabuttons & ETG_MUI)
438 ewidth = addextragadget(w,is_gzz,dri,relright,MUIIMAGE,((struct IntWindow *)w)->extrabuttonsid + ETD_MUI,MUIGAD,IntuitionBase);
439 relright -= ewidth;
440 db_width -= ewidth;
443 if (((struct IntWindow *)(w))->extrabuttons & ETG_POPUP)
445 ewidth = addextragadget(w,is_gzz,dri,relright,POPUPIMAGE,((struct IntWindow *)w)->extrabuttonsid + ETD_PopUp,POPUPGAD,IntuitionBase);
446 relright -= ewidth;
447 db_width -= ewidth;
450 if (w->Flags & WFLG_CLOSEGADGET)
452 struct TagItem close_tags[] =
454 {GA_Image , 0 },
455 {GA_Left , 0 },
456 {GA_Top , 0 },
457 #if SQUARE_WIN_GADGETS
458 {GA_Width , TitleHeight },
459 #endif
460 {GA_Height , TitleHeight },
461 {GA_SysGadget , TRUE },
462 {GA_SysGType , GTYP_CLOSE },
463 {GA_TopBorder , TRUE },
464 {GA_GZZGadget , is_gzz },
465 {GA_RelVerify , TRUE },
466 {TAG_DONE }
468 Object *im;
470 im = CreateStdSysImage(CLOSEIMAGE, TitleHeight, w->WScreen, dri,IntuitionBase);
471 if (!im)
473 sysgads_ok = FALSE;
475 else
477 close_tags[0].ti_Data = (IPTR)im;
479 SYSGAD(w, CLOSEGAD) = NewObjectA(NULL, BUTTONGCLASS, close_tags);
481 if (!SYSGAD(w, CLOSEGAD))
483 DisposeObject(im);
484 sysgads_ok = FALSE;
486 else
488 IPTR width;
489 GetAttr(GA_Width, SYSGAD(w, CLOSEGAD), &width);
491 db_left += width;
492 db_width -= width;
497 if (w->Flags & WFLG_DRAGBAR)
500 struct TagItem dragbar_tags[] =
502 {GA_Left , 0/*db_left*/ },
503 {GA_Top , 0 },
504 {GA_RelWidth , 0/*db_width*/ },
505 {GA_Height , TitleHeight },
506 {GA_SysGadget , TRUE },
507 {GA_SysGType , GTYP_WDRAGGING },
508 {GA_TopBorder , TRUE },
509 {GA_GZZGadget , is_gzz },
510 {TAG_DONE }
512 SYSGAD(w, DRAGBAR) = NewObjectA(NULL, BUTTONGCLASS, dragbar_tags);
514 if (!SYSGAD(w, DRAGBAR))
515 sysgads_ok = FALSE;
520 D(bug("Dragbar: %p\n", SYSGAD(w, DRAGBAR ) ));
521 D(bug("Depthgad: %p\n", SYSGAD(w, DEPTHGAD) ));
522 D(bug("Zoomgad: %p\n", SYSGAD(w, ZOOMGAD ) ));
523 D(bug("Closegad: %p\n", SYSGAD(w, CLOSEGAD) ));
524 D(bug("Sizegad: %p\n", SYSGAD(w, SIZEGAD ) ));
526 /* Don't need drawinfo anymore */
527 FreeScreenDrawInfo(w->WScreen, dri);
529 if (sysgads_ok)
531 int i;
534 D(bug("Adding gadgets\n"));
535 for (i = NUM_SYSGADS; --i >= 0; )
537 if (SYSGAD(w, i))
539 struct wdpLayoutBorderGadgets msg;
541 msg.MethodID = WDM_LAYOUT_BORDERGADGETS;
542 msg.wdp_Window = w;
543 msg.wdp_Gadgets = (struct Gadget *)SYSGAD(w, i);
544 msg.wdp_Flags = WDF_LBG_SYSTEMGADGET | WDF_LBG_INITIAL;
545 msg.wdp_UserBuffer = ((struct IntWindow *)(w))->DecorUserBuffer;
546 msg.wdp_ExtraButtons = ((struct IntWindow *)w)->extrabuttons;
548 msg.wdp_TrueColor = (((struct IntScreen *)w->WScreen)->DInfo.dri_Flags & DRIF_DIRECTCOLOR) ? TRUE : FALSE;
549 msg.wdp_Dri = dri;
551 DoMethodA(((struct IntScreen *)(w->WScreen))->WinDecorObj, (Msg)&msg);
553 AddGadget(w, (struct Gadget *)SYSGAD(w, i), 0);
557 ReturnBool("CreateWinSysGadgets", TRUE);
559 } /* if (sysgads created) */
561 KillWinSysGadgets(w, IntuitionBase);
563 } /* if (got DrawInfo) */
564 ReturnBool("CreateWinSysGadgets", FALSE);
568 /**********************************************************************************/
570 VOID KillWinSysGadgets(struct Window *w, struct IntuitionBase *IntuitionBase)
572 /* Free system gadgets */
573 UWORD i;
575 for (i = 0; i < NUM_SYSGADS; i ++)
577 if (SYSGAD(w, i))
579 RemoveGadget( w, (struct Gadget *)SYSGAD(w, i));
580 DisposeObject((Object *)((struct Gadget *)SYSGAD(w, i))->GadgetRender);
581 DisposeObject( SYSGAD(w, i) );
586 /**********************************************************************************/
588 void CreateScreenBar(struct Screen *scr, struct IntuitionBase *IntuitionBase)
590 struct IntIntuitionBase *_intuitionBase = GetPrivIBase(IntuitionBase);
591 struct GfxBase *GfxBase = _intuitionBase->GfxBase;
592 struct LayersBase *LayersBase = _intuitionBase->LayersBase;
593 BOOL front = TRUE;
594 ULONG backdrop = LAYERBACKDROP;
595 WORD ypos = 0;
597 D(bug("[intuition] CreateScreenBar()\n"));
599 #ifdef SKINS
600 if ((scr->Flags & SCREENQUIET) || (GetPrivScreen(scr)->SpecialFlags & SF_InvisibleBar))
601 front = FALSE;
603 if (GetPrivScreen(scr)->SpecialFlags & SF_AppearingBar)
605 backdrop = 0;
606 ypos = - (scr->BarHeight + 1);
608 #else
609 if (scr->Flags & SCREENQUIET) front = FALSE;
610 #endif
611 D(bug("[intuition] CreateScreenBar: Got initial flags\n"));
613 if (!scr->BarLayer)
615 D(bug("[intuition] CreateScreenBar: No current BarLayer\n"));
616 if (front)
618 scr->BarLayer = CreateUpfrontHookLayer(&scr->LayerInfo,
619 scr->RastPort.BitMap,
621 ypos,
622 scr->Width - 1,
623 scr->BarHeight + ypos, /* 1 pixel heigher than scr->BarHeight */
624 LAYERSIMPLE | backdrop,
625 LAYERS_NOBACKFILL,
626 NULL);
628 else
630 scr->BarLayer = CreateBehindHookLayer(&scr->LayerInfo,
631 scr->RastPort.BitMap,
633 ypos,
634 scr->Width - 1,
635 scr->BarHeight + ypos, /* 1 pixel heigher than scr->BarHeight */
636 LAYERSIMPLE | backdrop,
637 LAYERS_NOBACKFILL,
638 NULL);
641 if (scr->BarLayer)
643 D(bug("[intuition] CreateScreenBar: Adding BarLayer @ %p\n", scr->BarLayer));
644 D(bug("[intuition] CreateScreenBar: Rastport @ %p, Font @ %p\n", scr->BarLayer->rp, ((struct IntScreen *)scr)->DInfo.dri_Font));
645 SetFont(scr->BarLayer->rp, ((struct IntScreen *)scr)->DInfo.dri_Font);
646 if (!(scr->Flags & SCREENQUIET)) {
647 D(bug("[intuition] CreateScreenBar: Rendering Bar ...\n"));
648 RenderScreenBar(scr, FALSE, IntuitionBase);
650 D(bug("[intuition] CreateScreenBar: ... done\n"));
652 else
654 D(bug("[intuition] CreateScreenBar: Failed to create BarLayer!!\n"));
657 else
659 D(bug("[intuition] CreateScreenBar: Screen already has BarLayer\n"));
663 /**********************************************************************************/
665 void KillScreenBar(struct Screen *scr, struct IntuitionBase *IntuitionBase)
667 struct IntIntuitionBase *_intuitionBase = GetPrivIBase(IntuitionBase);
668 struct LayersBase *LayersBase = _intuitionBase->LayersBase;
670 if (scr->BarLayer)
672 DeleteLayer(0, scr->BarLayer);
673 scr->BarLayer = FALSE;
678 /**********************************************************************************/
680 #ifdef SKINS
681 //RenderScreenBar moved to morphos/mosmisc.c
682 #endif
684 #ifndef SKINS
686 void RenderScreenBar(struct Screen *scr, BOOL refresh, struct IntuitionBase *IntuitionBase)
688 struct IntIntuitionBase *_intuitionBase = GetPrivIBase(IntuitionBase);
689 struct GfxBase *GfxBase = _intuitionBase->GfxBase;
690 struct LayersBase *LayersBase = _intuitionBase->LayersBase;
691 struct RastPort *rp;
693 D(bug("[intuition] RenderScreenBar()\n"));
695 if (scr->BarLayer)
697 #if USE_NEWDISPLAYBEEP
698 BOOL beeping;
699 #else
700 #define beeping 0
701 #endif
703 D(bug("[intuition] RenderScreenBar: BarLayer @ %p\n", scr->BarLayer));
705 rp = scr->BarLayer->rp;
707 D(bug("[intuition] RenderScreenBar: RastPort @ %p\n", rp));
708 /* must lock GadgetLock to avoid deadlocks with ObtainGIRPort
709 when calling refreshgadget inside layer update state */
710 LockLayerInfo(scr->BarLayer->LayerInfo);
711 LOCKGADGET(IntuitionBase)
712 LockLayer(0, scr->BarLayer);
714 D(bug("[intuition] RenderScreenBar: Layer locked\n"));
715 #if USE_NEWDISPLAYBEEP
716 beeping = (scr->Flags & BEEPING) && GetBitMapAttr(rp->BitMap, BMA_DEPTH) > 8;
717 #endif
719 if (refresh) BeginUpdate(scr->BarLayer);
722 struct sdpDrawScreenBar msg;
724 D(bug("[intuition] RenderScreenBar: Begin Refresh .. \n"));
726 msg.MethodID = SDM_DRAW_SCREENBAR;
727 msg.sdp_Layer = scr->BarLayer;
728 msg.sdp_RPort = rp;
729 msg.sdp_Flags = 0;
730 msg.sdp_Screen = scr;
731 msg.sdp_Dri = (struct DrawInfo *)&((struct IntScreen *)scr)->DInfo;
732 msg.sdp_UserBuffer = ((struct IntScreen *)(scr))->DecorUserBuffer;
733 msg.sdp_TrueColor = (((struct IntScreen *)(scr))->DInfo.dri_Flags & DRIF_DIRECTCOLOR) ? TRUE : FALSE;
735 D(bug("[intuition] RenderScreenBar: ScrDecorObj @ %p, DecorUserBuffer @ %p\n", ((struct IntScreen *)(scr))->ScrDecorObj, ((struct IntScreen *)(scr))->DecorUserBuffer));
736 DoMethodA(((struct IntScreen *)(scr))->ScrDecorObj, (Msg)&msg);
739 D(bug("[intuition] RenderScreenBar: Update gadgets .. \n"));
741 if (scr->FirstGadget)
743 RefreshBoopsiGadget(scr->FirstGadget, (struct Window *)scr, NULL, IntuitionBase);
746 if (refresh)
748 D(bug("[intuition] RenderScreenBar: End Refresh .. \n"));
749 scr->BarLayer->Flags &= ~LAYERREFRESH;
750 EndUpdate(scr->BarLayer, TRUE);
753 #if USE_NEWDISPLAYBEEP
754 if (beeping) {
755 /* FIXME: Shouldn't we 'beep' at this point? */
756 D(bug("[intuition] RenderScreenBar: Beep\n"));
758 #endif
760 D(bug("[intuition] RenderScreenBar: Unlock Layer ..\n"));
762 UnlockLayer(scr->BarLayer);
763 UNLOCKGADGET(IntuitionBase)
764 UnlockLayerInfo(scr->BarLayer->LayerInfo);
766 } /* if (scr->BarLayer) */
767 D(bug("[intuition] RenderScreenBar: Done \n"));
770 #endif
772 /**********************************************************************************/
774 void UpdateMouseCoords(struct Window *win)
776 WORD scrmousex = win->WScreen->MouseX;
777 WORD scrmousey = win->WScreen->MouseY;
779 win->MouseX = scrmousex - win->LeftEdge;
780 win->MouseY = scrmousey - win->TopEdge;
782 /* stegerg: AmigaOS sets this even if window is not GZZ
783 so we do the same as they are handy also for non-GZZ
784 windows */
786 win->GZZMouseX = scrmousex - (win->LeftEdge + win->BorderLeft);
787 win->GZZMouseY = scrmousey - (win->TopEdge + win->BorderTop);
790 /**********************************************************************************/
792 /* subtract rectangle b from rectangle b. resulting rectangles will be put into
793 destrectarray which must have place for at least 4 rectangles. Returns number
794 of resulting rectangles */
796 #if 0 /* use <clib/macros.h> MAX/MIN macros */
797 #undef MAX
798 #define MAX(a,b) (((a) > (b)) ? (a) : (b))
800 #undef MIN
801 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
802 #endif
804 WORD SubtractRectFromRect(struct Rectangle *a, struct Rectangle *b, struct Rectangle *destrectarray)
806 struct Rectangle intersect;
807 BOOL intersecting = FALSE;
808 WORD numrects = 0;
810 /* calc. intersection between a and b */
812 if (a->MinX <= b->MaxX)
814 if (a->MinY <= b->MaxY)
816 if (a->MaxX >= b->MinX)
818 if (a->MaxY >= b->MinY)
820 intersect.MinX = MAX(a->MinX, b->MinX);
821 intersect.MinY = MAX(a->MinY, b->MinY);
822 intersect.MaxX = MIN(a->MaxX, b->MaxX);
823 intersect.MaxY = MIN(a->MaxY, b->MaxY);
825 intersecting = TRUE;
831 if (!intersecting)
833 destrectarray[numrects++] = *a;
835 } /* not intersecting */
836 else
838 if (intersect.MinY > a->MinY) /* upper */
840 destrectarray->MinX = a->MinX;
841 destrectarray->MinY = a->MinY;
842 destrectarray->MaxX = a->MaxX;
843 destrectarray->MaxY = intersect.MinY - 1;
845 numrects++;
846 destrectarray++;
849 if (intersect.MaxY < a->MaxY) /* lower */
851 destrectarray->MinX = a->MinX;
852 destrectarray->MinY = intersect.MaxY + 1;
853 destrectarray->MaxX = a->MaxX;
854 destrectarray->MaxY = a->MaxY;
856 numrects++;
857 destrectarray++;
860 if (intersect.MinX > a->MinX) /* left */
862 destrectarray->MinX = a->MinX;
863 destrectarray->MinY = intersect.MinY;
864 destrectarray->MaxX = intersect.MinX - 1;
865 destrectarray->MaxY = intersect.MaxY;
867 numrects++;
868 destrectarray++;
871 if (intersect.MaxX < a->MaxX) /* right */
873 destrectarray->MinX = intersect.MaxX + 1;
874 destrectarray->MinY = intersect.MinY;
875 destrectarray->MaxX = a->MaxX;
876 destrectarray->MaxY = intersect.MaxY;
878 numrects++;
879 destrectarray++;
882 } /* intersecting */
884 return numrects;
888 ULONG addextragadget(struct Window *w,BOOL is_gzz,struct DrawInfo *dri,LONG relright,ULONG imagetype,ULONG gadgetid,ULONG gadgettype,struct IntuitionBase *IntuitionBase)
890 ULONG TitleHeight = w->BorderTop;
891 struct TagItem gadget_tags[] =
893 {GA_Image , 0 },
894 {GA_ToggleSelect, FALSE },
895 {GA_Top , 0 },
896 {GA_Height , TitleHeight },
897 {GA_TopBorder , TRUE },
898 {GA_GZZGadget , is_gzz },
899 {GA_ID , gadgetid },
900 {GA_RelVerify , TRUE },
901 {TAG_DONE }
904 Object *im;
906 if (gadgettype == LOCKGAD)
907 gadget_tags[1].ti_Data = TRUE;
909 im = CreateStdSysImage(imagetype, TitleHeight, w->WScreen, dri,IntuitionBase);
910 if (im)
912 gadget_tags[0].ti_Data = (IPTR)im;
914 SYSGAD(w, gadgettype) = NewObjectA(NULL, BUTTONGCLASS, gadget_tags);
916 if (!SYSGAD(w, gadgettype))
918 DisposeObject(im);
920 else
922 IPTR width;
923 GetAttr(GA_Width, SYSGAD(w, gadgettype), &width);
925 --width;
928 struct TagItem gadtags[] =
930 {GA_RelRight, relright - width },
931 {TAG_DONE }
934 SetAttrsA(SYSGAD(w, gadgettype), gadtags);
937 return width;
941 return 0;
945 /**********************************************************************************/
947 /* Use the FNV-1 hash function over the object's pointer.
948 * http://en.wikipedia.org/wiki/Fowler-Noll-Vo_hash_function
950 LONG CalcResourceHash(APTR resource)
952 const ULONG FNV1_32_Offset = 2166136261UL;
953 const ULONG FNV1_32_Prime = 16777619UL;
954 IPTR data = (IPTR)resource;
955 ULONG hash;
956 int i;
958 hash = FNV1_32_Offset;
959 for (i = 0; i < AROS_SIZEOFPTR; i++) {
960 hash *= FNV1_32_Prime;
961 hash ^= data & 0xff;
962 data >>= 8;
965 return hash & (RESOURCELIST_HASHSIZE-1);
968 /**********************************************************************************/
970 void AddResourceToList(APTR resource, UWORD resourcetype, struct IntuitionBase *IntuitionBase)
972 struct IntIntuitionBase *_intuitionBase = GetPrivIBase(IntuitionBase);
973 struct HashNode *hn = NULL;
974 LONG hash;
975 ULONG ilock;
977 switch(resourcetype)
979 case RESOURCE_WINDOW:
980 hn = &((struct IntWindow *)resource)->hashnode;
981 hn->type = RESOURCE_WINDOW;
982 break;
984 case RESOURCE_SCREEN:
985 hn = &((struct IntScreen *)resource)->hashnode;
986 hn->type = RESOURCE_SCREEN;
987 break;
989 default:
990 D(bug("AddResourceToList: Unknown resource type!!!\n"));
991 return;
994 hash = CalcResourceHash(resource);
996 hn->resource = resource;
998 ilock = LockIBase(0);
999 AddTail((struct List *)&_intuitionBase->ResourceList[hash], (struct Node *)hn);
1000 UnlockIBase(ilock);
1003 /**********************************************************************************/
1005 void RemoveResourceFromList(APTR resource, UWORD resourcetype, struct IntuitionBase *IntuitionBase)
1007 struct HashNode *hn = NULL;
1008 ULONG ilock;
1010 switch(resourcetype)
1012 case RESOURCE_WINDOW:
1013 hn = &((struct IntWindow *)resource)->hashnode;
1014 break;
1016 case RESOURCE_SCREEN:
1017 hn = &((struct IntScreen *)resource)->hashnode;
1018 break;
1020 default:
1021 D(bug("RemoveResourceFromList: Unknown resource type!!!\n"));
1022 return;
1025 if (hn->type != resourcetype)
1027 D(bug("RemoveResourceFromList: Panic. Resource Type mismatch!!!\n"));
1030 ilock = LockIBase(0);
1031 Remove((struct Node *)hn);
1032 UnlockIBase(ilock);
1035 /**********************************************************************************/
1037 BOOL ResourceExisting(APTR resource, UWORD resourcetype, struct IntuitionBase *IntuitionBase)
1039 struct IntIntuitionBase *_intuitionBase = GetPrivIBase(IntuitionBase);
1040 struct HashNode *hn = NULL;
1041 LONG hash;
1042 ULONG ilock;
1043 BOOL exists = FALSE;
1045 hash = CalcResourceHash(resource);
1047 ilock = LockIBase(0);
1048 ForeachNode(&_intuitionBase->ResourceList[hash], hn)
1050 if ((hn->resource == resource) && (hn->type == resourcetype))
1052 exists = TRUE;
1053 break;
1056 UnlockIBase(ilock);
1058 return exists;
1061 void FireScreenNotifyMessageCode(IPTR data, ULONG flag, ULONG code, struct IntuitionBase *IntuitionBase)
1063 struct IntIntuitionBase *_intuitionBase = GetPrivIBase(IntuitionBase);
1064 ObtainSemaphoreShared(&_intuitionBase->ScreenNotificationListLock);
1066 struct ScreenNotifyMessage *msg;
1067 struct ReplyPort *reply;
1069 struct IntScreenNotify *sn;
1070 struct Node *node;
1072 BOOL ignorescreen = FALSE;
1074 if (!IsListEmpty(&_intuitionBase->ScreenNotificationList))
1076 node = _intuitionBase->ScreenNotificationList.lh_Head;
1077 for (; node->ln_Succ; node = node->ln_Succ)
1079 sn = (struct IntScreenNotify *) node;
1080 if (flag & ( SNOTIFY_AFTER_OPENSCREEN | SNOTIFY_BEFORE_OPENSCREEN
1081 | SNOTIFY_AFTER_CLOSESCREEN | SNOTIFY_BEFORE_CLOSESCREEN
1082 | SNOTIFY_LOCKPUBSCREEN | SNOTIFY_UNLOCKPUBSCREEN
1083 | SNOTIFY_SCREENDEPTH | SNOTIFY_PUBSCREENSTATE ))
1086 * If sn->pubname is supplied, only notify for it
1087 * (data must be a screen, and it must be public)
1089 if (sn->pubname)
1091 D(bug("[intuition] FSNMC() sn->pubname is non-NULL... '%s'\n", sn->pubname));
1092 LockPubScreenList();
1093 if (!( (ResourceExisting((struct Screen*)data, RESOURCE_SCREEN, IntuitionBase))
1094 && (NULL != GetPrivScreen(data)->pubScrNode)
1095 && (NULL != GetPrivScreen(data)->pubScrNode->psn_Node.ln_Name)
1096 && (0 == strcmp(sn->pubname, (const char *)GetPrivScreen(data)->pubScrNode->psn_Node.ln_Name)) ))
1098 ignorescreen = TRUE;
1100 else
1102 D(bug("[intuition] FSNMC() IntScreen->pubScrNode->psn_Node.ln_Name is non-NULL... '%s'\n", GetPrivScreen(data)->pubScrNode->psn_Node.ln_Name));
1104 UnlockPubScreenList();
1106 D(bug("[intuition] FSNMC() ignorescreen = %s\n", ignorescreen ? "TRUE" : "FALSE"));
1109 if ((sn->flags & flag) && !ignorescreen)
1111 if (sn->port)
1113 msg = AllocMem(sizeof(struct ScreenNotifyMessage), MEMF_CLEAR);
1114 if (msg)
1116 msg->snm_Message.mn_Magic = MAGIC_SCREENNOTIFY;
1117 msg->snm_Message.mn_Version = SCREENNOTIFY_VERSION;
1118 msg->snm_Object = data;
1119 msg->snm_Class = flag;
1120 msg->snm_Code = code;
1121 msg->snm_UserData = sn->userdata;
1122 msg->snm_Message.mn_Length = sizeof(struct ScreenNotifyMessage);
1123 if (sn->flags & SNOTIFY_WAIT_REPLY)
1125 reply = (struct ReplyPort *)CreateMsgPort();
1126 if (reply)
1128 msg->snm_Message.mn_ReplyPort = (struct MsgPort *)reply;
1130 PutMsg((struct MsgPort *)sn->port, (struct Message *) msg);
1131 WaitPort((struct MsgPort *)reply);
1132 GetMsg((struct MsgPort *)reply);
1133 FreeMem((APTR) msg, sizeof(struct ScreenNotifyMessage));
1134 DeleteMsgPort((struct MsgPort *)reply);
1135 } else FreeMem((APTR) msg, sizeof(struct ScreenNotifyMessage));
1137 else
1139 msg->snm_Message.mn_ReplyPort = _intuitionBase->ScreenNotifyReplyPort;
1141 PutMsg(sn->port, (struct Message *) msg);
1146 else if (sn->sigtask)
1148 Signal(sn->sigtask, 1 << sn->sigbit);
1150 else if (sn->hook)
1152 struct ScreenNotifyMessage msg;
1153 msg.snm_Message.mn_Magic = MAGIC_SCREENNOTIFY;
1154 msg.snm_Message.mn_Version = SCREENNOTIFY_VERSION;
1155 msg.snm_Object = data;
1156 msg.snm_Class = flag;
1157 msg.snm_UserData = sn->userdata;
1158 msg.snm_Message.mn_Length = sizeof(struct ScreenNotifyMessage);
1160 CallHook(sn->hook, NULL, (Msg) &msg);
1165 ReleaseSemaphore(&_intuitionBase->ScreenNotificationListLock);
1168 void FireScreenNotifyMessage(IPTR data, ULONG flag, struct IntuitionBase *IntuitionBase)
1170 FireScreenNotifyMessageCode(data, flag, 0, IntuitionBase);
1173 /**********************************************************************************/
1175 AROS_UFH3(BOOL, DefaultWindowShapeFunc,
1176 AROS_UFHA(struct Hook *, hook, A0),
1177 AROS_UFHA(struct Layer *, lay, A2),
1178 AROS_UFHA(struct ShapeHookMsg *, msg, A1))
1180 AROS_USERFUNC_INIT
1182 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)hook->h_Data;
1183 struct IntIntuitionBase *_intuitionBase = GetPrivIBase(IntuitionBase);
1184 struct GfxBase *GfxBase = _intuitionBase->GfxBase;
1185 struct Window *win = (struct Window *)hook->h_SubEntry;
1186 struct Region *shape;
1187 struct wdpWindowShape shapemsg;
1189 shapemsg.MethodID = WDM_WINDOWSHAPE;
1190 shapemsg.wdp_TrueColor = (GetPrivScreen(win->WScreen)->DInfo.dri_Flags & DRIF_DIRECTCOLOR) ? TRUE : FALSE;
1191 shapemsg.wdp_Width = msg->NewBounds->MaxX - msg->NewBounds->MinX + 1;
1192 shapemsg.wdp_Height = msg->NewBounds->MaxY - msg->NewBounds->MinY + 1;
1193 shapemsg.wdp_Window = win;
1194 shapemsg.wdp_UserBuffer = IW(win)->DecorUserBuffer;
1196 shape = (struct Region *)DoMethodA(GetPrivScreen(win->WScreen)->WinDecorObj, (Msg)&shapemsg);
1198 if (IW(win)->OutlineShape) DisposeRegion(IW(win)->OutlineShape);
1199 IW(win)->OutlineShape = shape;
1200 IW(win)->CustomShape = FALSE;
1202 msg->NewShape = shape;
1203 return TRUE;
1205 AROS_USERFUNC_EXIT
1208 /**********************************************************************************/