Minor fixes to comments.
[AROS.git] / rom / intuition / intuition_misc.c
blob847cf960a8084c7abcc6cfcf5baa1d2fe707a15f
1 /*
2 Copyright 1995-2012, 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 #ifdef __mc68000
54 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
55 #endif
56 BYTE read_preferences = FALSE;
57 # ifdef SKINS
58 static CONST UWORD DriPens2[NUMDRIPENS] = { 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1 , 1 , 0};
59 static CONST UWORD DriPens4[NUMDRIPENS] = { 1, 0, 1, 2, 1, 3, 1, 0, 2, 1, 2, 1 , 2 , 1};
60 # else
61 static CONST UWORD DriPens2[NUMDRIPENS] = { 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1};
62 static CONST UWORD DriPens4[NUMDRIPENS] = { 1, 0, 1, 2, 1, 3, 1, 0, 2, 1, 2, 1};
63 # endif /* SKINS */
66 ** Load the intuition preferences from a file on the disk
67 ** Allocate storage for the preferences, even if it's just a copy
68 ** of the default preferences.
70 GetPrivIBase(IntuitionBase)->DefaultPreferences =
71 AllocMem(sizeof(struct Preferences), MEMF_CLEAR);
73 GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_DisplayID = INVALID_ID;
74 GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Width = AROS_DEFAULT_WBWIDTH;
75 #ifdef __mc68000
76 GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Height = (GfxBase->DisplayFlags & NTSC) ? 200 : 256;
77 #else
78 GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Height = AROS_DEFAULT_WBHEIGHT;
79 #endif
80 GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Depth = AROS_DEFAULT_WBDEPTH;
81 GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Control = 0;
83 GetPrivIBase(IntuitionBase)->IControlPrefs.ic_TimeOut = 50;
84 GetPrivIBase(IntuitionBase)->IControlPrefs.ic_MetaDrag = IEQUALIFIER_LCOMMAND;
85 GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags = ICF_3DMENUS |
86 ICF_OFFSCREENLAYERS |
87 ICF_AVOIDWINBORDERERASE |
88 ICF_MODEPROMOTE |
89 ICF_MENUSNAP |
90 ICF_STRGAD_FILTER |
91 ICF_COERCE_LACE;
92 GetPrivIBase(IntuitionBase)->IControlPrefs.ic_WBtoFront = 'N';
93 GetPrivIBase(IntuitionBase)->IControlPrefs.ic_FrontToBack = 'M';
94 GetPrivIBase(IntuitionBase)->IControlPrefs.ic_ReqTrue = 'V';
95 GetPrivIBase(IntuitionBase)->IControlPrefs.ic_ReqFalse = 'B';
99 * Mouse default.
101 GetPrivIBase(IntuitionBase)->DefaultPreferences->PointerTicks = 2;
103 /* FIXME: Try to load preferences from a file! */
106 /*******************************************************************
107 DOSBase = OpenLibrary("dos.library",0);
108 if (NULL != DOSBase)
110 if (NULL != (pref_file = Open("envarc:",MODE_OLDFILE)))
113 ** Read it and check whether the file was valid.
116 if (sizeof(struct Preferences) ==
117 Read(pref_file,
118 GetPrivIBase(IntuitionBase)->DefaultPreferences,
119 sizeof(struct Preferences)))
120 read_preferences = TRUE;
122 Close(pref_file);
124 CloseLibrary(DOSBase)
126 ****************************************************************/
128 if (FALSE == read_preferences)
131 ** no (valid) preferences file is available.
133 CopyMem(&IntuitionDefaultPreferences,
134 GetPrivIBase(IntuitionBase)->DefaultPreferences,
135 sizeof(struct Preferences));
140 ** Activate the preferences...
143 GetPrivIBase(IntuitionBase)->ActivePreferences =
144 AllocMem(sizeof(struct Preferences),
145 MEMF_CLEAR);
147 #if 1
148 CopyMem(GetPrivIBase(IntuitionBase)->DefaultPreferences,
149 GetPrivIBase(IntuitionBase)->ActivePreferences,
150 sizeof(struct Preferences));
151 #else
152 SetPrefs(GetPrivIBase(IntuitionBase)->DefaultPreferences,
153 sizeof(struct Preferences),
154 FALSE/*TRUE*/);
155 #endif
157 CopyMem(DriPens2, GetPrivIBase(IntuitionBase)->DriPens2, sizeof(DriPens2));
158 CopyMem(DriPens4, GetPrivIBase(IntuitionBase)->DriPens4, sizeof(DriPens4));
159 CopyMem(DriPens4, GetPrivIBase(IntuitionBase)->DriPens8, sizeof(DriPens4));
162 /**********************************************************************************/
164 void CheckRectFill(struct RastPort *rp, WORD x1, WORD y1, WORD x2, WORD y2,
165 struct IntuitionBase * IntuitionBase)
167 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
169 if ((x2 >= x1) && (y2 >= y1))
171 RectFill(rp, x1, y1, x2, y2);
175 /**********************************************************************************/
177 Object* CreateStdSysImage(WORD which, WORD preferred_height, struct Screen *scr, APTR buffer,
178 struct DrawInfo *dri, struct IntuitionBase *IntuitionBase)
180 Object *im;
182 struct TagItem image_tags[] =
184 {SYSIA_Which , which },
185 {SYSIA_DrawInfo , (IPTR)dri },
186 {SYSIA_Size , scr->Flags & SCREENHIRES ?
187 SYSISIZE_MEDRES : SYSISIZE_LOWRES },
188 {SYSIA_UserBuffer , (IPTR)buffer },
189 {TAG_DONE }
192 im = NewObjectA(NULL, SYSICLASS, image_tags);
193 if (im)
195 struct TagItem size_tags[] =
197 {IA_Width , 0 },
198 {IA_Height , preferred_height },
199 {TAG_DONE }
201 IPTR width, height;
203 GetAttr(IA_Width, im, &width);
204 GetAttr(IA_Height, im, &height);
206 size_tags[0].ti_Data = preferred_height * width / height;
208 SetAttrsA(im, size_tags);
211 return im;
214 /**********************************************************************************/
216 BOOL CreateWinSysGadgets(struct Window *w, struct IntuitionBase *IntuitionBase)
219 struct DrawInfo *dri;
220 BOOL is_gzz;
221 ULONG TitleHeight = w->BorderTop;
223 EnterFunc(bug("CreateWinSysGadgets(w=%p)\n", w));
225 is_gzz = (w->Flags & WFLG_GIMMEZEROZERO) ? TRUE : FALSE;
227 dri = GetScreenDrawInfo(w->WScreen);
228 if (dri)
230 LONG db_left, db_width, relright,ewidth; /* dragbar sizes */
231 BOOL sysgads_ok = TRUE;
234 db_left = 0;
235 db_width = 0; /* Georg Steger: was w->Width; */
237 /* Relright of rightmost button */
238 //relright = - (TitleHeight - 1);
240 relright = 1;
242 /* Now try to create the various gadgets */
244 if (w->Flags & WFLG_SIZEGADGET)
246 /* this code must not change the 'relright' variable */
247 WORD width = ((struct IntWindow *)w)->sizeimage_width;
248 WORD height = ((struct IntWindow *)w)->sizeimage_height;
250 struct TagItem size_tags[] =
252 {GA_Image , 0 },
253 {GA_RelRight , -width + 1 },
254 {GA_RelBottom , -height + 1 },
255 {GA_Width , width },
256 {GA_Height , height },
257 {GA_SysGadget , TRUE },
258 {GA_SysGType , GTYP_SIZING },
259 {GA_BottomBorder, TRUE },
260 {GA_RightBorder , TRUE },
261 {GA_GZZGadget , is_gzz },
262 {TAG_DONE }
265 struct TagItem image_tags[] =
267 {IA_Width , width },
268 {IA_Height , height },
269 {SYSIA_Which , SIZEIMAGE },
270 {SYSIA_DrawInfo , (IPTR)dri },
271 {SYSIA_UserBuffer, ((struct IntWindow *)(w))->DecorUserBuffer },
272 {SYSIA_Size , w->WScreen->Flags & SCREENHIRES ? SYSISIZE_MEDRES : SYSISIZE_LOWRES},
273 {TAG_DONE }
275 Object *im;
277 im = NewObjectA(NULL, SYSICLASS, image_tags);
278 if (!im)
280 sysgads_ok = FALSE;
282 else
284 size_tags[0].ti_Data = (IPTR)im;
286 SYSGAD(w, SIZEGAD) = NewObjectA(NULL, BUTTONGCLASS, size_tags);
288 if (!SYSGAD(w, SIZEGAD))
290 DisposeObject(im);
291 sysgads_ok = FALSE;
296 if (w->Flags & WFLG_DEPTHGADGET)
298 struct TagItem depth_tags[] =
300 {GA_Image , 0 },
301 //{GA_RelRight , relright },
302 {GA_Top , 0 },
303 #if SQUARE_WIN_GADGETS
304 {GA_Width , TitleHeight },
305 #endif
306 {GA_Height , TitleHeight },
307 {GA_SysGadget , TRUE },
308 {GA_SysGType , GTYP_WDEPTH },
309 {GA_TopBorder , TRUE },
310 {GA_GZZGadget , is_gzz },
311 {GA_RelVerify , TRUE },
312 {TAG_DONE }
314 Object *im;
316 im = CreateStdSysImage(DEPTHIMAGE, TitleHeight, w->WScreen, (APTR)((struct IntWindow *)(w))->DecorUserBuffer, dri, IntuitionBase);
317 if (!im)
319 sysgads_ok = FALSE;
321 else
323 depth_tags[0].ti_Data = (IPTR)im;
325 SYSGAD(w, DEPTHGAD) = NewObjectA(NULL, BUTTONGCLASS, depth_tags);
327 if (!SYSGAD(w, DEPTHGAD))
329 DisposeObject(im);
330 sysgads_ok = FALSE;
332 else
334 IPTR width;
335 GetAttr(GA_Width, SYSGAD(w, DEPTHGAD), &width);
337 /*****/
339 relright -= width;
340 db_width -= width;
343 struct TagItem gadtags[] =
345 {GA_RelRight, relright },
346 /* {GA_Width , width }, */
347 {TAG_DONE }
350 SetAttrsA(SYSGAD(w, DEPTHGAD), gadtags);
357 /* RKRMs: window gets zoom gadget if WA_Zoom tag was used,
358 or if window has both a sizegadget and a depthgadget */
360 if ((w->Flags & WFLG_HASZOOM) ||
361 ((w->Flags & WFLG_SIZEGADGET) && (w->Flags & WFLG_DEPTHGADGET)))
363 struct TagItem zoom_tags[] =
365 {GA_Image , 0 },
366 //{GA_RelRight , relright },
367 {GA_Top , 0 },
368 #if SQUARE_WIN_GADGETS
369 {GA_Width , TitleHeight },
370 #endif
371 {GA_Height , TitleHeight },
372 {GA_SysGadget , TRUE },
373 {GA_SysGType , GTYP_WZOOM },
374 {GA_TopBorder , TRUE },
375 {GA_GZZGadget , is_gzz },
376 {GA_RelVerify , TRUE },
377 {TAG_DONE }
380 Object *im;
382 im = CreateStdSysImage(ZOOMIMAGE, TitleHeight, w->WScreen, (APTR)((struct IntWindow *)(w))->DecorUserBuffer, dri, IntuitionBase);
383 if (!im)
385 sysgads_ok = FALSE;
387 else
389 zoom_tags[0].ti_Data = (IPTR)im;
391 SYSGAD(w, ZOOMGAD) = NewObjectA(NULL, BUTTONGCLASS, zoom_tags);
393 if (!SYSGAD(w, ZOOMGAD))
395 DisposeObject(im);
396 sysgads_ok = FALSE;
398 else
400 IPTR width;
401 GetAttr(GA_Width, SYSGAD(w, ZOOMGAD), &width);
403 relright -= width;
404 db_width -= width;
407 struct TagItem gadtags[] =
409 {GA_RelRight, relright},
410 {TAG_DONE }
414 SetAttrsA(SYSGAD(w, ZOOMGAD), gadtags);
420 if (((struct IntWindow *)(w))->extrabuttons & ETG_LOCK)
422 ewidth = addextragadget(w,is_gzz,dri,relright,LOCKIMAGE,((struct IntWindow *)w)->extrabuttonsid + ETD_Lock,LOCKGAD,IntuitionBase);
423 relright -= ewidth;
424 db_width -= ewidth;
427 if (((struct IntWindow *)(w))->extrabuttons & ETG_ICONIFY)
429 ewidth = addextragadget(w,is_gzz,dri,relright,ICONIFYIMAGE,((struct IntWindow *)w)->extrabuttonsid + ETD_Iconify,ICONIFYGAD,IntuitionBase);
430 relright -= ewidth;
431 db_width -= ewidth;
434 if (((struct IntWindow *)(w))->extrabuttons & ETG_JUMP)
436 ewidth = addextragadget(w,is_gzz,dri,relright,JUMPIMAGE,((struct IntWindow *)w)->extrabuttonsid + ETD_Jump,JUMPGAD,IntuitionBase);
437 relright -= ewidth;
438 db_width -= ewidth;
441 if (((struct IntWindow *)(w))->extrabuttons & ETG_SNAPSHOT)
443 ewidth = addextragadget(w,is_gzz,dri,relright,SNAPSHOTIMAGE,((struct IntWindow *)w)->extrabuttonsid + ETD_Snapshot,SNAPSHOTGAD,IntuitionBase);
444 relright -= ewidth;
445 db_width -= ewidth;
448 if (((struct IntWindow *)(w))->extrabuttons & ETG_MUI)
450 ewidth = addextragadget(w,is_gzz,dri,relright,MUIIMAGE,((struct IntWindow *)w)->extrabuttonsid + ETD_MUI,MUIGAD,IntuitionBase);
451 relright -= ewidth;
452 db_width -= ewidth;
455 if (((struct IntWindow *)(w))->extrabuttons & ETG_POPUP)
457 ewidth = addextragadget(w,is_gzz,dri,relright,POPUPIMAGE,((struct IntWindow *)w)->extrabuttonsid + ETD_PopUp,POPUPGAD,IntuitionBase);
458 relright -= ewidth;
459 db_width -= ewidth;
462 if (w->Flags & WFLG_CLOSEGADGET)
464 struct TagItem close_tags[] =
466 {GA_Image , 0 },
467 {GA_Left , 0 },
468 {GA_Top , 0 },
469 #if SQUARE_WIN_GADGETS
470 {GA_Width , TitleHeight },
471 #endif
472 {GA_Height , TitleHeight },
473 {GA_SysGadget , TRUE },
474 {GA_SysGType , GTYP_CLOSE },
475 {GA_TopBorder , TRUE },
476 {GA_GZZGadget , is_gzz },
477 {GA_RelVerify , TRUE },
478 {TAG_DONE }
480 Object *im;
482 im = CreateStdSysImage(CLOSEIMAGE, TitleHeight, w->WScreen, (APTR)((struct IntWindow *)(w))->DecorUserBuffer, dri,IntuitionBase);
483 if (!im)
485 sysgads_ok = FALSE;
487 else
489 close_tags[0].ti_Data = (IPTR)im;
491 SYSGAD(w, CLOSEGAD) = NewObjectA(NULL, BUTTONGCLASS, close_tags);
493 if (!SYSGAD(w, CLOSEGAD))
495 DisposeObject(im);
496 sysgads_ok = FALSE;
498 else
500 IPTR width;
501 GetAttr(GA_Width, SYSGAD(w, CLOSEGAD), &width);
503 db_left += width;
504 db_width -= width;
509 if (w->Flags & WFLG_DRAGBAR)
512 struct TagItem dragbar_tags[] =
514 {GA_Left , 0/*db_left*/ },
515 {GA_Top , 0 },
516 {GA_RelWidth , 0/*db_width*/ },
517 {GA_Height , TitleHeight },
518 {GA_SysGadget , TRUE },
519 {GA_SysGType , GTYP_WDRAGGING },
520 {GA_TopBorder , TRUE },
521 {GA_GZZGadget , is_gzz },
522 {TAG_DONE }
524 SYSGAD(w, DRAGBAR) = NewObjectA(NULL, BUTTONGCLASS, dragbar_tags);
526 if (!SYSGAD(w, DRAGBAR))
527 sysgads_ok = FALSE;
532 D(bug("Dragbar: %p\n", SYSGAD(w, DRAGBAR ) ));
533 D(bug("Depthgad: %p\n", SYSGAD(w, DEPTHGAD) ));
534 D(bug("Zoomgad: %p\n", SYSGAD(w, ZOOMGAD ) ));
535 D(bug("Closegad: %p\n", SYSGAD(w, CLOSEGAD) ));
536 D(bug("Sizegad: %p\n", SYSGAD(w, SIZEGAD ) ));
538 /* Don't need drawinfo anymore */
539 FreeScreenDrawInfo(w->WScreen, dri);
541 if (sysgads_ok)
543 int i;
546 D(bug("Adding gadgets\n"));
547 for (i = NUM_SYSGADS; --i >= 0; )
549 if (SYSGAD(w, i))
551 struct wdpLayoutBorderGadgets msg;
553 msg.MethodID = WDM_LAYOUT_BORDERGADGETS;
554 msg.wdp_Window = w;
555 msg.wdp_Gadgets = (struct Gadget *)SYSGAD(w, i);
556 msg.wdp_Flags = WDF_LBG_SYSTEMGADGET | WDF_LBG_INITIAL;
557 msg.wdp_UserBuffer = ((struct IntWindow *)(w))->DecorUserBuffer;
558 msg.wdp_ExtraButtons = ((struct IntWindow *)w)->extrabuttons;
560 msg.wdp_TrueColor = (((struct IntScreen *)w->WScreen)->DInfo.dri.dri_Flags & DRIF_DIRECTCOLOR);
561 msg.wdp_Dri = dri;
563 DoMethodA(((struct IntScreen *)(w->WScreen))->WinDecorObj, (Msg)&msg);
565 AddGadget(w, (struct Gadget *)SYSGAD(w, i), 0);
569 ReturnBool("CreateWinSysGadgets", TRUE);
571 } /* if (sysgads created) */
573 KillWinSysGadgets(w, IntuitionBase);
575 } /* if (got DrawInfo) */
576 ReturnBool("CreateWinSysGadgets", FALSE);
580 /**********************************************************************************/
582 VOID KillWinSysGadgets(struct Window *w, struct IntuitionBase *IntuitionBase)
584 /* Free system gadgets */
585 UWORD i;
587 for (i = 0; i < NUM_SYSGADS; i ++)
589 if (SYSGAD(w, i))
591 RemoveGadget( w, (struct Gadget *)SYSGAD(w, i));
592 DisposeObject((Object *)((struct Gadget *)SYSGAD(w, i))->GadgetRender);
593 DisposeObject( SYSGAD(w, i) );
598 /**********************************************************************************/
600 void CreateScreenBar(struct Screen *scr, struct IntuitionBase *IntuitionBase)
602 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
603 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
604 BOOL front = TRUE;
605 ULONG backdrop = LAYERBACKDROP;
606 WORD ypos = 0;
608 D(bug("[intuition] CreateScreenBar()\n"));
610 #ifdef SKINS
611 if (scr->Flags & SCREENQUIET || (GetPrivScreen(scr)->SpecialFlags & SF_InvisibleBar))
612 front = FALSE;
614 if (GetPrivScreen(scr)->SpecialFlags & SF_AppearingBar)
616 backdrop = 0;
617 ypos = - (scr->BarHeight + 1);
619 #else
620 if (scr->Flags & SCREENQUIET) front = FALSE;
621 #endif
622 D(bug("[intuition] CreateScreenBar: Got initial flags\n"));
624 if (!scr->BarLayer)
626 D(bug("[intuition] CreateScreenBar: No current BarLayer\n"));
627 if (front)
629 scr->BarLayer = CreateUpfrontHookLayer(&scr->LayerInfo,
630 scr->RastPort.BitMap,
632 ypos,
633 scr->Width - 1,
634 scr->BarHeight + ypos, /* 1 pixel heigher than scr->BarHeight */
635 LAYERSIMPLE | backdrop,
636 LAYERS_NOBACKFILL,
637 NULL);
639 else
641 scr->BarLayer = CreateBehindHookLayer(&scr->LayerInfo,
642 scr->RastPort.BitMap,
644 ypos,
645 scr->Width - 1,
646 scr->BarHeight + ypos, /* 1 pixel heigher than scr->BarHeight */
647 LAYERSIMPLE | backdrop,
648 LAYERS_NOBACKFILL,
649 NULL);
652 if (scr->BarLayer)
654 D(bug("[intuition] CreateScreenBar: Adding BarLayer @ %p\n", scr->BarLayer));
655 D(bug("[intuition] CreateScreenBar: Rastport @ %p, Font @ %p\n", scr->BarLayer->rp, ((struct IntScreen *)scr)->DInfo.dri.dri_Font));
656 SetFont(scr->BarLayer->rp, ((struct IntScreen *)scr)->DInfo.dri.dri_Font);
657 if (!(scr->Flags & SCREENQUIET)) {
658 D(bug("[intuition] CreateScreenBar: Rendering Bar ...\n"));
659 RenderScreenBar(scr, FALSE, IntuitionBase);
661 D(bug("[intuition] CreateScreenBar: ... done\n"));
663 else
665 D(bug("[intuition] CreateScreenBar: Failed to create BarLayer!!\n"));
668 else
670 D(bug("[intuition] CreateScreenBar: Screen already has BarLayer\n"));
674 /**********************************************************************************/
676 void KillScreenBar(struct Screen *scr, struct IntuitionBase *IntuitionBase)
678 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
680 if (scr->BarLayer)
682 DeleteLayer(0, scr->BarLayer);
683 scr->BarLayer = FALSE;
688 /**********************************************************************************/
690 #ifdef SKINS
691 //RenderScreenBar moved to morphos/mosmisc.c
692 #endif
694 #ifndef SKINS
696 void RenderScreenBar(struct Screen *scr, BOOL refresh, struct IntuitionBase *IntuitionBase)
699 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
700 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
701 struct DrawInfo *dri = &((struct IntScreen *)scr)->DInfo.dri;
702 struct RastPort *rp;
704 D(bug("[intuition] RenderScreenBar()\n"));
706 if (scr->BarLayer)
708 #if USE_NEWDISPLAYBEEP
709 BOOL beeping;
710 #else
711 #define beeping 0
712 #endif
714 D(bug("[intuition] RenderScreenBar: BarLayer @ %p\n", scr->BarLayer));
716 rp = scr->BarLayer->rp;
718 D(bug("[intuition] RenderScreenBar: RastPort @ %p\n", rp));
719 /* must lock GadgetLock to avoid deadlocks with ObtainGIRPort
720 when calling refreshgadget inside layer update state */
721 LockLayerInfo(scr->BarLayer->LayerInfo);
722 LOCKGADGET(IntuitionBase)
723 LockLayer(0, scr->BarLayer);
725 D(bug("[intuition] RenderScreenBar: Layer locked\n"));
726 #if USE_NEWDISPLAYBEEP
727 beeping = (scr->Flags & BEEPING) && GetBitMapAttr(rp->BitMap, BMA_DEPTH) > 8;
728 #endif
730 if (refresh) BeginUpdate(scr->BarLayer);
733 struct sdpDrawScreenBar msg;
735 D(bug("[intuition] RenderScreenBar: Begin Refresh .. \n"));
737 msg.MethodID = SDM_DRAW_SCREENBAR;
738 msg.sdp_Layer = scr->BarLayer;
739 msg.sdp_RPort = rp;
740 msg.sdp_Flags = 0;
741 msg.sdp_Screen = scr;
742 msg.sdp_Dri = dri;
743 msg.sdp_UserBuffer = ((struct IntScreen *)(scr))->DecorUserBuffer;
744 msg.sdp_TrueColor = (((struct IntScreen *)(scr))->DInfo.dri.dri_Flags & DRIF_DIRECTCOLOR);
746 D(bug("[intuition] RenderScreenBar: ScrDecorObj @ %p, DecorUserBuffer @ %p\n", ((struct IntScreen *)(scr))->ScrDecorObj, ((struct IntScreen *)(scr))->DecorUserBuffer));
747 DoMethodA(((struct IntScreen *)(scr))->ScrDecorObj, (Msg)&msg);
750 D(bug("[intuition] RenderScreenBar: Update gadgets .. \n"));
752 if (scr->FirstGadget)
754 RefreshBoopsiGadget(scr->FirstGadget, (struct Window *)scr, NULL, IntuitionBase);
757 if (refresh)
759 D(bug("[intuition] RenderScreenBar: End Refresh .. \n"));
760 scr->BarLayer->Flags &= ~LAYERREFRESH;
761 EndUpdate(scr->BarLayer, TRUE);
764 #if USE_NEWDISPLAYBEEP
765 if (beeping) {
766 /* FIXME: Shouldn't we 'beep' at this point? */
767 D(bug("[intuition] RenderScreenBar: Beep\n"));
769 #endif
771 D(bug("[intuition] RenderScreenBar: Unlock Layer ..\n"));
773 UnlockLayer(scr->BarLayer);
774 UNLOCKGADGET(IntuitionBase)
775 UnlockLayerInfo(scr->BarLayer->LayerInfo);
777 } /* if (scr->BarLayer) */
778 D(bug("[intuition] RenderScreenBar: Done \n"));
781 #endif
783 /**********************************************************************************/
785 void UpdateMouseCoords(struct Window *win)
787 WORD scrmousex = win->WScreen->MouseX;
788 WORD scrmousey = win->WScreen->MouseY;
790 win->MouseX = scrmousex - win->LeftEdge;
791 win->MouseY = scrmousey - win->TopEdge;
793 /* stegerg: AmigaOS sets this even if window is not GZZ
794 so we do the same as they are handy also for non-GZZ
795 windows */
797 win->GZZMouseX = scrmousex - (win->LeftEdge + win->BorderLeft);
798 win->GZZMouseY = scrmousey - (win->TopEdge + win->BorderTop);
801 /**********************************************************************************/
803 /* subtract rectangle b from rectangle b. resulting rectangles will be put into
804 destrectarray which must have place for at least 4 rectangles. Returns number
805 of resulting rectangles */
807 #if 0 /* use <clib/macros.h> MAX/MIN macros */
808 #undef MAX
809 #define MAX(a,b) (((a) > (b)) ? (a) : (b))
811 #undef MIN
812 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
813 #endif
815 WORD SubtractRectFromRect(struct Rectangle *a, struct Rectangle *b, struct Rectangle *destrectarray)
817 struct Rectangle intersect;
818 BOOL intersecting = FALSE;
819 WORD numrects = 0;
821 /* calc. intersection between a and b */
823 if (a->MinX <= b->MaxX)
825 if (a->MinY <= b->MaxY)
827 if (a->MaxX >= b->MinX)
829 if (a->MaxY >= b->MinY)
831 intersect.MinX = MAX(a->MinX, b->MinX);
832 intersect.MinY = MAX(a->MinY, b->MinY);
833 intersect.MaxX = MIN(a->MaxX, b->MaxX);
834 intersect.MaxY = MIN(a->MaxY, b->MaxY);
836 intersecting = TRUE;
842 if (!intersecting)
844 destrectarray[numrects++] = *a;
846 } /* not intersecting */
847 else
849 if (intersect.MinY > a->MinY) /* upper */
851 destrectarray->MinX = a->MinX;
852 destrectarray->MinY = a->MinY;
853 destrectarray->MaxX = a->MaxX;
854 destrectarray->MaxY = intersect.MinY - 1;
856 numrects++;
857 destrectarray++;
860 if (intersect.MaxY < a->MaxY) /* lower */
862 destrectarray->MinX = a->MinX;
863 destrectarray->MinY = intersect.MaxY + 1;
864 destrectarray->MaxX = a->MaxX;
865 destrectarray->MaxY = a->MaxY;
867 numrects++;
868 destrectarray++;
871 if (intersect.MinX > a->MinX) /* left */
873 destrectarray->MinX = a->MinX;
874 destrectarray->MinY = intersect.MinY;
875 destrectarray->MaxX = intersect.MinX - 1;
876 destrectarray->MaxY = intersect.MaxY;
878 numrects++;
879 destrectarray++;
882 if (intersect.MaxX < a->MaxX) /* right */
884 destrectarray->MinX = intersect.MaxX + 1;
885 destrectarray->MinY = intersect.MinY;
886 destrectarray->MaxX = a->MaxX;
887 destrectarray->MaxY = intersect.MaxY;
889 numrects++;
890 destrectarray++;
893 } /* intersecting */
895 return numrects;
899 ULONG addextragadget(struct Window *w,BOOL is_gzz,struct DrawInfo *dri,LONG relright,ULONG imagetype,ULONG gadgetid,ULONG gadgettype,struct IntuitionBase *IntuitionBase)
901 ULONG TitleHeight = w->BorderTop;
902 struct TagItem gadget_tags[] =
904 {GA_Image , 0 },
905 {GA_ToggleSelect, FALSE },
906 {GA_Top , 0 },
907 {GA_Height , TitleHeight },
908 {GA_TopBorder , TRUE },
909 {GA_GZZGadget , is_gzz },
910 {GA_ID , gadgetid },
911 {GA_RelVerify , TRUE },
912 {TAG_DONE }
915 Object *im;
917 if (gadgettype == LOCKGAD)
918 gadget_tags[1].ti_Data = TRUE;
920 im = CreateStdSysImage(imagetype, TitleHeight, w->WScreen, (APTR)((struct IntWindow *)(w))->DecorUserBuffer, dri,IntuitionBase);
921 if (im)
923 gadget_tags[0].ti_Data = (IPTR)im;
925 SYSGAD(w, gadgettype) = NewObjectA(NULL, BUTTONGCLASS, gadget_tags);
927 if (!SYSGAD(w, gadgettype))
929 DisposeObject(im);
931 else
933 IPTR width;
934 GetAttr(GA_Width, SYSGAD(w, gadgettype), &width);
936 --width;
939 struct TagItem gadtags[] =
941 {GA_RelRight, relright - width },
942 {TAG_DONE }
945 SetAttrsA(SYSGAD(w, gadgettype), gadtags);
948 return width;
952 return 0;
956 /**********************************************************************************/
958 /* Use the FNV-1 hash function over the object's pointer.
959 * http://en.wikipedia.org/wiki/Fowler-Noll-Vo_hash_function
961 LONG CalcResourceHash(APTR resource)
963 const ULONG FNV1_32_Offset = 2166136261UL;
964 const ULONG FNV1_32_Prime = 16777619UL;
965 IPTR data = (IPTR)resource;
966 ULONG hash;
967 int i;
969 hash = FNV1_32_Offset;
970 for (i = 0; i < AROS_SIZEOFPTR; i++) {
971 hash *= FNV1_32_Prime;
972 hash ^= data & 0xff;
973 data >>= 8;
976 return hash & (RESOURCELIST_HASHSIZE-1);
979 /**********************************************************************************/
981 void AddResourceToList(APTR resource, UWORD resourcetype, struct IntuitionBase *IntuitionBase)
983 struct HashNode *hn = NULL;
984 LONG hash;
985 ULONG ilock;
987 switch(resourcetype)
989 case RESOURCE_WINDOW:
990 hn = &((struct IntWindow *)resource)->hashnode;
991 hn->type = RESOURCE_WINDOW;
992 break;
994 case RESOURCE_SCREEN:
995 hn = &((struct IntScreen *)resource)->hashnode;
996 hn->type = RESOURCE_SCREEN;
997 break;
999 default:
1000 D(bug("AddResourceToList: Unknown resource type!!!\n"));
1001 return;
1004 hash = CalcResourceHash(resource);
1006 hn->resource = resource;
1008 ilock = LockIBase(0);
1009 AddTail((struct List *)&GetPrivIBase(IntuitionBase)->ResourceList[hash], (struct Node *)hn);
1010 UnlockIBase(ilock);
1013 /**********************************************************************************/
1015 void RemoveResourceFromList(APTR resource, UWORD resourcetype, struct IntuitionBase *IntuitionBase)
1017 struct HashNode *hn = NULL;
1018 ULONG ilock;
1020 switch(resourcetype)
1022 case RESOURCE_WINDOW:
1023 hn = &((struct IntWindow *)resource)->hashnode;
1024 break;
1026 case RESOURCE_SCREEN:
1027 hn = &((struct IntScreen *)resource)->hashnode;
1028 break;
1030 default:
1031 D(bug("RemoveResourceFromList: Unknown resource type!!!\n"));
1032 return;
1035 if (hn->type != resourcetype)
1037 D(bug("RemoveResourceFromList: Panic. Resource Type mismatch!!!\n"));
1040 ilock = LockIBase(0);
1041 Remove((struct Node *)hn);
1042 UnlockIBase(ilock);
1045 /**********************************************************************************/
1047 BOOL ResourceExisting(APTR resource, UWORD resourcetype, struct IntuitionBase *IntuitionBase)
1049 struct HashNode *hn = NULL;
1050 LONG hash;
1051 ULONG ilock;
1052 BOOL exists = FALSE;
1054 hash = CalcResourceHash(resource);
1056 ilock = LockIBase(0);
1057 ForeachNode((struct List *)&GetPrivIBase(IntuitionBase)->ResourceList[hash], hn)
1059 if ((hn->resource == resource) && (hn->type == resourcetype))
1061 exists = TRUE;
1062 break;
1065 UnlockIBase(ilock);
1067 return exists;
1070 void FireScreenNotifyMessageCode(IPTR data, ULONG flag, ULONG code, struct IntuitionBase *IntuitionBase)
1072 ObtainSemaphoreShared(&GetPrivIBase(IntuitionBase)->ScreenNotificationListLock);
1074 struct ScreenNotifyMessage *msg;
1075 struct ReplyPort *reply;
1077 struct IntScreenNotify *sn;
1078 struct Node *node;
1080 BOOL ignorescreen = FALSE;
1082 if (!IsListEmpty(&GetPrivIBase(IntuitionBase)->ScreenNotificationList))
1084 node = GetPrivIBase(IntuitionBase)->ScreenNotificationList.lh_Head;
1085 for (; node->ln_Succ; node = node->ln_Succ)
1087 sn = (struct IntScreenNotify *) node;
1088 if (flag & ( SNOTIFY_AFTER_OPENSCREEN | SNOTIFY_BEFORE_OPENSCREEN
1089 | SNOTIFY_AFTER_CLOSESCREEN | SNOTIFY_BEFORE_CLOSESCREEN
1090 | SNOTIFY_LOCKPUBSCREEN | SNOTIFY_UNLOCKPUBSCREEN
1091 | SNOTIFY_SCREENDEPTH | SNOTIFY_PUBSCREENSTATE ))
1094 * If sn->pubname is supplied, only notify for it
1095 * (data must be a screen, and it must be public)
1097 if (sn->pubname)
1099 D(bug("[intuition] FSNMC() sn->pubname is non-NULL... '%s'\n", sn->pubname));
1100 LockPubScreenList();
1101 if (!( (ResourceExisting((struct Screen*)data, RESOURCE_SCREEN, IntuitionBase))
1102 && (NULL != GetPrivScreen(data)->pubScrNode)
1103 && (NULL != GetPrivScreen(data)->pubScrNode->psn_Node.ln_Name)
1104 && (0 == strcmp(sn->pubname, (const char *)GetPrivScreen(data)->pubScrNode->psn_Node.ln_Name)) ))
1106 ignorescreen = TRUE;
1108 else
1110 D(bug("[intuition] FSNMC() IntScreen->pubScrNode->psn_Node.ln_Name is non-NULL... '%s'\n", GetPrivScreen(data)->pubScrNode->psn_Node.ln_Name));
1112 UnlockPubScreenList();
1114 D(bug("[intuition] FSNMC() ignorescreen = %s\n", ignorescreen ? "TRUE" : "FALSE"));
1117 if ((sn->flags & flag) && !ignorescreen)
1119 if (sn->port)
1121 msg = AllocMem(sizeof(struct ScreenNotifyMessage), MEMF_CLEAR);
1122 if (msg)
1124 msg->snm_Message.mn_Magic = MAGIC_SCREENNOTIFY;
1125 msg->snm_Message.mn_Version = SCREENNOTIFY_VERSION;
1126 msg->snm_Object = data;
1127 msg->snm_Class = flag;
1128 msg->snm_Code = code;
1129 msg->snm_UserData = sn->userdata;
1130 msg->snm_Message.mn_Length = sizeof(struct ScreenNotifyMessage);
1131 if (sn->flags & SNOTIFY_WAIT_REPLY)
1133 reply = (struct ReplyPort *)CreateMsgPort();
1134 if (reply)
1136 msg->snm_Message.mn_ReplyPort = (struct MsgPort *)reply;
1138 PutMsg((struct MsgPort *)sn->port, (struct Message *) msg);
1139 WaitPort((struct MsgPort *)reply);
1140 GetMsg((struct MsgPort *)reply);
1141 FreeMem((APTR) msg, sizeof(struct ScreenNotifyMessage));
1142 DeleteMsgPort((struct MsgPort *)reply);
1143 } else FreeMem((APTR) msg, sizeof(struct ScreenNotifyMessage));
1145 else
1147 msg->snm_Message.mn_ReplyPort = GetPrivIBase(IntuitionBase)->ScreenNotifyReplyPort;
1149 PutMsg(sn->port, (struct Message *) msg);
1154 else if (sn->sigtask)
1156 Signal(sn->sigtask, 1 << sn->sigbit);
1158 else if (sn->hook)
1160 struct ScreenNotifyMessage msg;
1161 msg.snm_Message.mn_Magic = MAGIC_SCREENNOTIFY;
1162 msg.snm_Message.mn_Version = SCREENNOTIFY_VERSION;
1163 msg.snm_Object = data;
1164 msg.snm_Class = flag;
1165 msg.snm_UserData = sn->userdata;
1166 msg.snm_Message.mn_Length = sizeof(struct ScreenNotifyMessage);
1168 CallHook(sn->hook, NULL, (Msg) &msg);
1173 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->ScreenNotificationListLock);
1176 void FireScreenNotifyMessage(IPTR data, ULONG flag, struct IntuitionBase *IntuitionBase)
1178 FireScreenNotifyMessageCode(data, flag, 0, IntuitionBase);
1181 /**********************************************************************************/
1183 AROS_UFH3(BOOL, DefaultWindowShapeFunc,
1184 AROS_UFHA(struct Hook *, hook, A0),
1185 AROS_UFHA(struct Layer *, lay, A2),
1186 AROS_UFHA(struct ShapeHookMsg *, msg, A1))
1188 AROS_USERFUNC_INIT
1190 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)hook->h_Data;
1191 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1192 struct Window *win = (struct Window *)hook->h_SubEntry;
1193 struct Region *shape;
1194 struct wdpWindowShape shapemsg;
1196 shapemsg.MethodID = WDM_WINDOWSHAPE;
1197 shapemsg.wdp_TrueColor = (GetPrivScreen(win->WScreen)->DInfo.dri.dri_Flags & DRIF_DIRECTCOLOR) ? TRUE : FALSE;
1198 shapemsg.wdp_Width = msg->NewBounds->MaxX - msg->NewBounds->MinX + 1;
1199 shapemsg.wdp_Height = msg->NewBounds->MaxY - msg->NewBounds->MinY + 1;
1200 shapemsg.wdp_Window = win;
1201 shapemsg.wdp_UserBuffer = IW(win)->DecorUserBuffer;
1203 shape = (struct Region *)DoMethodA(GetPrivScreen(win->WScreen)->WinDecorObj, (Msg)&shapemsg);
1205 if (IW(win)->OutlineShape) DisposeRegion(IW(win)->OutlineShape);
1206 IW(win)->OutlineShape = shape;
1207 IW(win)->CustomShape = FALSE;
1209 msg->NewShape = shape;
1210 return TRUE;
1212 AROS_USERFUNC_EXIT
1215 /**********************************************************************************/