use struct timeval to obtain the cputime. disable display atm until the code is corre...
[AROS.git] / rom / intuition / intuition_misc.c
blob326ed201ec29221abe975acc25faf26998687094
1 /*
2 Copyright © 1995-2013, 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 <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 SKINS
54 static CONST UWORD DriPens2[NUMDRIPENS] = { 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1 , 1 , 0};
55 static CONST UWORD DriPens4[NUMDRIPENS] = { 1, 0, 1, 2, 1, 3, 1, 0, 2, 1, 2, 1 , 2 , 1};
56 # else
57 static CONST UWORD DriPens2[NUMDRIPENS] = { 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1};
58 static CONST UWORD DriPens4[NUMDRIPENS] = { 1, 0, 1, 2, 1, 3, 1, 0, 2, 1, 2, 1};
59 # endif /* SKINS */
61 GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_DisplayID = INVALID_ID;
62 GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Width = AROS_DEFAULT_WBWIDTH;
63 #ifdef __mc68000
64 GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Height = (GetPrivIBase(IntuitionBase)->GfxBase->DisplayFlags & NTSC) ? 200 : 256;
65 #else
66 GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Height = AROS_DEFAULT_WBHEIGHT;
67 #endif
68 GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Depth = AROS_DEFAULT_WBDEPTH;
69 GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Control = 0;
71 /* Default IControl prefs are AROS addition. Keep while backporting. */
72 GetPrivIBase(IntuitionBase)->IControlPrefs.ic_TimeOut = 50;
73 GetPrivIBase(IntuitionBase)->IControlPrefs.ic_MetaDrag = IEQUALIFIER_LCOMMAND;
74 GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags = ICF_3DMENUS |
75 ICF_OFFSCREENLAYERS |
76 ICF_AVOIDWINBORDERERASE |
77 ICF_MODEPROMOTE |
78 ICF_MENUSNAP |
79 ICF_STRGAD_FILTER |
80 ICF_COERCE_LACE;
81 GetPrivIBase(IntuitionBase)->IControlPrefs.ic_WBtoFront = 'N';
82 GetPrivIBase(IntuitionBase)->IControlPrefs.ic_FrontToBack = 'M';
83 GetPrivIBase(IntuitionBase)->IControlPrefs.ic_ReqTrue = 'V';
84 GetPrivIBase(IntuitionBase)->IControlPrefs.ic_ReqFalse = 'B';
88 * Mouse default.
90 GetPrivIBase(IntuitionBase)->DefaultPreferences.PointerTicks = 2;
92 CopyMem(&IntuitionDefaultPreferences,
93 &GetPrivIBase(IntuitionBase)->DefaultPreferences,
94 sizeof(struct Preferences));
95 CopyMem(&GetPrivIBase(IntuitionBase)->DefaultPreferences,
96 &GetPrivIBase(IntuitionBase)->ActivePreferences,
97 sizeof(struct Preferences));
99 CopyMem(DriPens2, GetPrivIBase(IntuitionBase)->DriPens2, sizeof(DriPens2));
100 CopyMem(DriPens4, GetPrivIBase(IntuitionBase)->DriPens4, sizeof(DriPens4));
101 CopyMem(DriPens4, GetPrivIBase(IntuitionBase)->DriPens8, sizeof(DriPens4));
104 /**********************************************************************************/
106 void CheckRectFill(struct RastPort *rp, WORD x1, WORD y1, WORD x2, WORD y2,
107 struct IntuitionBase * IntuitionBase)
109 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
111 if ((x2 >= x1) && (y2 >= y1))
113 RectFill(rp, x1, y1, x2, y2);
117 /**********************************************************************************/
119 Object* CreateStdSysImage(WORD which, WORD preferred_height, struct Screen *scr,
120 struct DrawInfo *dri, struct IntuitionBase *IntuitionBase)
122 Object *im;
124 struct TagItem image_tags[] =
126 {SYSIA_Which , which },
127 {SYSIA_DrawInfo , (IPTR)dri },
128 {SYSIA_Size , scr->Flags & SCREENHIRES ?
129 SYSISIZE_MEDRES : SYSISIZE_LOWRES },
130 {TAG_DONE }
133 im = NewObjectA(NULL, SYSICLASS, image_tags);
134 if (im)
136 struct TagItem size_tags[] =
138 {IA_Width , 0 },
139 {IA_Height , preferred_height },
140 {TAG_DONE }
142 IPTR width, height;
144 GetAttr(IA_Width, im, &width);
145 GetAttr(IA_Height, im, &height);
147 size_tags[0].ti_Data = preferred_height * width / height;
149 SetAttrsA(im, size_tags);
152 return im;
155 /**********************************************************************************/
157 BOOL CreateWinSysGadgets(struct Window *w, struct IntuitionBase *IntuitionBase)
160 struct DrawInfo *dri;
161 BOOL is_gzz;
162 ULONG TitleHeight = w->BorderTop;
164 EnterFunc(bug("CreateWinSysGadgets(w=%p)\n", w));
166 is_gzz = (w->Flags & WFLG_GIMMEZEROZERO) ? TRUE : FALSE;
168 dri = GetScreenDrawInfo(w->WScreen);
169 if (dri)
171 LONG db_left, db_width, relright,ewidth; /* dragbar sizes */
172 BOOL sysgads_ok = TRUE;
175 db_left = 0;
176 db_width = 0; /* Georg Steger: was w->Width; */
178 /* Relright of rightmost button */
179 //relright = - (TitleHeight - 1);
181 relright = 1;
183 /* Now try to create the various gadgets */
185 if (w->Flags & WFLG_SIZEGADGET)
187 /* this code must not change the 'relright' variable */
188 WORD width = ((struct IntWindow *)w)->sizeimage_width;
189 WORD height = ((struct IntWindow *)w)->sizeimage_height;
191 struct TagItem size_tags[] =
193 {GA_Image , 0 },
194 {GA_RelRight , -width + 1 },
195 {GA_RelBottom , -height + 1 },
196 {GA_Width , width },
197 {GA_Height , height },
198 {GA_SysGadget , TRUE },
199 {GA_SysGType , GTYP_SIZING },
200 {GA_BottomBorder, TRUE },
201 {GA_RightBorder , TRUE },
202 {GA_GZZGadget , is_gzz },
203 {TAG_DONE }
206 struct TagItem image_tags[] =
208 {IA_Width , width },
209 {IA_Height , height },
210 {SYSIA_Which , SIZEIMAGE },
211 {SYSIA_DrawInfo , (IPTR)dri },
212 {SYSIA_Size , w->WScreen->Flags & SCREENHIRES ? SYSISIZE_MEDRES : SYSISIZE_LOWRES},
213 {TAG_DONE }
215 Object *im;
217 im = NewObjectA(NULL, SYSICLASS, image_tags);
218 if (!im)
220 sysgads_ok = FALSE;
222 else
224 size_tags[0].ti_Data = (IPTR)im;
226 SYSGAD(w, SIZEGAD) = NewObjectA(NULL, BUTTONGCLASS, size_tags);
228 if (!SYSGAD(w, SIZEGAD))
230 DisposeObject(im);
231 sysgads_ok = FALSE;
236 if (w->Flags & WFLG_DEPTHGADGET)
238 struct TagItem depth_tags[] =
240 {GA_Image , 0 },
241 //{GA_RelRight , relright },
242 {GA_Top , 0 },
243 #if SQUARE_WIN_GADGETS
244 {GA_Width , TitleHeight },
245 #endif
246 {GA_Height , TitleHeight },
247 {GA_SysGadget , TRUE },
248 {GA_SysGType , GTYP_WDEPTH },
249 {GA_TopBorder , TRUE },
250 {GA_GZZGadget , is_gzz },
251 {GA_RelVerify , TRUE },
252 {TAG_DONE }
254 Object *im;
256 im = CreateStdSysImage(DEPTHIMAGE, TitleHeight, w->WScreen, dri, IntuitionBase);
257 if (!im)
259 sysgads_ok = FALSE;
261 else
263 depth_tags[0].ti_Data = (IPTR)im;
265 SYSGAD(w, DEPTHGAD) = NewObjectA(NULL, BUTTONGCLASS, depth_tags);
267 if (!SYSGAD(w, DEPTHGAD))
269 DisposeObject(im);
270 sysgads_ok = FALSE;
272 else
274 IPTR width;
275 GetAttr(GA_Width, SYSGAD(w, DEPTHGAD), &width);
277 /*****/
279 relright -= width;
280 db_width -= width;
283 struct TagItem gadtags[] =
285 {GA_RelRight, relright },
286 /* {GA_Width , width }, */
287 {TAG_DONE }
290 SetAttrsA(SYSGAD(w, DEPTHGAD), gadtags);
297 /* RKRMs: window gets zoom gadget if WA_Zoom tag was used,
298 or if window has both a sizegadget and a depthgadget */
300 if ((w->Flags & WFLG_HASZOOM) ||
301 ((w->Flags & WFLG_SIZEGADGET) && (w->Flags & WFLG_DEPTHGADGET)))
303 struct TagItem zoom_tags[] =
305 {GA_Image , 0 },
306 //{GA_RelRight , relright },
307 {GA_Top , 0 },
308 #if SQUARE_WIN_GADGETS
309 {GA_Width , TitleHeight },
310 #endif
311 {GA_Height , TitleHeight },
312 {GA_SysGadget , TRUE },
313 {GA_SysGType , GTYP_WZOOM },
314 {GA_TopBorder , TRUE },
315 {GA_GZZGadget , is_gzz },
316 {GA_RelVerify , TRUE },
317 {TAG_DONE }
320 Object *im;
322 im = CreateStdSysImage(ZOOMIMAGE, TitleHeight, w->WScreen, dri, IntuitionBase);
323 if (!im)
325 sysgads_ok = FALSE;
327 else
329 zoom_tags[0].ti_Data = (IPTR)im;
331 SYSGAD(w, ZOOMGAD) = NewObjectA(NULL, BUTTONGCLASS, zoom_tags);
333 if (!SYSGAD(w, ZOOMGAD))
335 DisposeObject(im);
336 sysgads_ok = FALSE;
338 else
340 IPTR width;
341 GetAttr(GA_Width, SYSGAD(w, ZOOMGAD), &width);
343 relright -= width;
344 db_width -= width;
347 struct TagItem gadtags[] =
349 {GA_RelRight, relright},
350 {TAG_DONE }
354 SetAttrsA(SYSGAD(w, ZOOMGAD), gadtags);
360 if (((struct IntWindow *)(w))->extrabuttons & ETG_LOCK)
362 ewidth = addextragadget(w,is_gzz,dri,relright,LOCKIMAGE,((struct IntWindow *)w)->extrabuttonsid + ETD_Lock,LOCKGAD,IntuitionBase);
363 relright -= ewidth;
364 db_width -= ewidth;
367 if (((struct IntWindow *)(w))->extrabuttons & ETG_ICONIFY)
369 ewidth = addextragadget(w,is_gzz,dri,relright,ICONIFYIMAGE,((struct IntWindow *)w)->extrabuttonsid + ETD_Iconify,ICONIFYGAD,IntuitionBase);
370 relright -= ewidth;
371 db_width -= ewidth;
374 if (((struct IntWindow *)(w))->extrabuttons & ETG_JUMP)
376 ewidth = addextragadget(w,is_gzz,dri,relright,JUMPIMAGE,((struct IntWindow *)w)->extrabuttonsid + ETD_Jump,JUMPGAD,IntuitionBase);
377 relright -= ewidth;
378 db_width -= ewidth;
381 if (((struct IntWindow *)(w))->extrabuttons & ETG_SNAPSHOT)
383 ewidth = addextragadget(w,is_gzz,dri,relright,SNAPSHOTIMAGE,((struct IntWindow *)w)->extrabuttonsid + ETD_Snapshot,SNAPSHOTGAD,IntuitionBase);
384 relright -= ewidth;
385 db_width -= ewidth;
388 if (((struct IntWindow *)(w))->extrabuttons & ETG_MUI)
390 ewidth = addextragadget(w,is_gzz,dri,relright,MUIIMAGE,((struct IntWindow *)w)->extrabuttonsid + ETD_MUI,MUIGAD,IntuitionBase);
391 relright -= ewidth;
392 db_width -= ewidth;
395 if (((struct IntWindow *)(w))->extrabuttons & ETG_POPUP)
397 ewidth = addextragadget(w,is_gzz,dri,relright,POPUPIMAGE,((struct IntWindow *)w)->extrabuttonsid + ETD_PopUp,POPUPGAD,IntuitionBase);
398 relright -= ewidth;
399 db_width -= ewidth;
402 if (w->Flags & WFLG_CLOSEGADGET)
404 struct TagItem close_tags[] =
406 {GA_Image , 0 },
407 {GA_Left , 0 },
408 {GA_Top , 0 },
409 #if SQUARE_WIN_GADGETS
410 {GA_Width , TitleHeight },
411 #endif
412 {GA_Height , TitleHeight },
413 {GA_SysGadget , TRUE },
414 {GA_SysGType , GTYP_CLOSE },
415 {GA_TopBorder , TRUE },
416 {GA_GZZGadget , is_gzz },
417 {GA_RelVerify , TRUE },
418 {TAG_DONE }
420 Object *im;
422 im = CreateStdSysImage(CLOSEIMAGE, TitleHeight, w->WScreen, dri,IntuitionBase);
423 if (!im)
425 sysgads_ok = FALSE;
427 else
429 close_tags[0].ti_Data = (IPTR)im;
431 SYSGAD(w, CLOSEGAD) = NewObjectA(NULL, BUTTONGCLASS, close_tags);
433 if (!SYSGAD(w, CLOSEGAD))
435 DisposeObject(im);
436 sysgads_ok = FALSE;
438 else
440 IPTR width;
441 GetAttr(GA_Width, SYSGAD(w, CLOSEGAD), &width);
443 db_left += width;
444 db_width -= width;
449 if (w->Flags & WFLG_DRAGBAR)
452 struct TagItem dragbar_tags[] =
454 {GA_Left , 0/*db_left*/ },
455 {GA_Top , 0 },
456 {GA_RelWidth , 0/*db_width*/ },
457 {GA_Height , TitleHeight },
458 {GA_SysGadget , TRUE },
459 {GA_SysGType , GTYP_WDRAGGING },
460 {GA_TopBorder , TRUE },
461 {GA_GZZGadget , is_gzz },
462 {TAG_DONE }
464 SYSGAD(w, DRAGBAR) = NewObjectA(NULL, BUTTONGCLASS, dragbar_tags);
466 if (!SYSGAD(w, DRAGBAR))
467 sysgads_ok = FALSE;
472 D(bug("Dragbar: %p\n", SYSGAD(w, DRAGBAR ) ));
473 D(bug("Depthgad: %p\n", SYSGAD(w, DEPTHGAD) ));
474 D(bug("Zoomgad: %p\n", SYSGAD(w, ZOOMGAD ) ));
475 D(bug("Closegad: %p\n", SYSGAD(w, CLOSEGAD) ));
476 D(bug("Sizegad: %p\n", SYSGAD(w, SIZEGAD ) ));
478 /* Don't need drawinfo anymore */
479 FreeScreenDrawInfo(w->WScreen, dri);
481 if (sysgads_ok)
483 int i;
486 D(bug("Adding gadgets\n"));
487 for (i = NUM_SYSGADS; --i >= 0; )
489 if (SYSGAD(w, i))
491 struct wdpLayoutBorderGadgets msg;
493 msg.MethodID = WDM_LAYOUT_BORDERGADGETS;
494 msg.wdp_Window = w;
495 msg.wdp_Gadgets = (struct Gadget *)SYSGAD(w, i);
496 msg.wdp_Flags = WDF_LBG_SYSTEMGADGET | WDF_LBG_INITIAL;
497 msg.wdp_UserBuffer = ((struct IntWindow *)(w))->DecorUserBuffer;
498 msg.wdp_ExtraButtons = ((struct IntWindow *)w)->extrabuttons;
500 msg.wdp_TrueColor = (((struct IntScreen *)w->WScreen)->DInfo.dri_Flags & DRIF_DIRECTCOLOR) ? TRUE : FALSE;
501 msg.wdp_Dri = dri;
503 DoMethodA(((struct IntScreen *)(w->WScreen))->WinDecorObj, (Msg)&msg);
505 AddGadget(w, (struct Gadget *)SYSGAD(w, i), 0);
509 ReturnBool("CreateWinSysGadgets", TRUE);
511 } /* if (sysgads created) */
513 KillWinSysGadgets(w, IntuitionBase);
515 } /* if (got DrawInfo) */
516 ReturnBool("CreateWinSysGadgets", FALSE);
520 /**********************************************************************************/
522 VOID KillWinSysGadgets(struct Window *w, struct IntuitionBase *IntuitionBase)
524 /* Free system gadgets */
525 UWORD i;
527 for (i = 0; i < NUM_SYSGADS; i ++)
529 if (SYSGAD(w, i))
531 RemoveGadget( w, (struct Gadget *)SYSGAD(w, i));
532 DisposeObject((Object *)((struct Gadget *)SYSGAD(w, i))->GadgetRender);
533 DisposeObject( SYSGAD(w, i) );
538 /**********************************************************************************/
540 void CreateScreenBar(struct Screen *scr, struct IntuitionBase *IntuitionBase)
542 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
543 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
544 BOOL front = TRUE;
545 ULONG backdrop = LAYERBACKDROP;
546 WORD ypos = 0;
548 D(bug("[intuition] CreateScreenBar()\n"));
550 #ifdef SKINS
551 if ((scr->Flags & SCREENQUIET) || (GetPrivScreen(scr)->SpecialFlags & SF_InvisibleBar))
552 front = FALSE;
554 if (GetPrivScreen(scr)->SpecialFlags & SF_AppearingBar)
556 backdrop = 0;
557 ypos = - (scr->BarHeight + 1);
559 #else
560 if (scr->Flags & SCREENQUIET) front = FALSE;
561 #endif
562 D(bug("[intuition] CreateScreenBar: Got initial flags\n"));
564 if (!scr->BarLayer)
566 D(bug("[intuition] CreateScreenBar: No current BarLayer\n"));
567 if (front)
569 scr->BarLayer = CreateUpfrontHookLayer(&scr->LayerInfo,
570 scr->RastPort.BitMap,
572 ypos,
573 scr->Width - 1,
574 scr->BarHeight + ypos, /* 1 pixel heigher than scr->BarHeight */
575 LAYERSIMPLE | backdrop,
576 LAYERS_NOBACKFILL,
577 NULL);
579 else
581 scr->BarLayer = CreateBehindHookLayer(&scr->LayerInfo,
582 scr->RastPort.BitMap,
584 ypos,
585 scr->Width - 1,
586 scr->BarHeight + ypos, /* 1 pixel heigher than scr->BarHeight */
587 LAYERSIMPLE | backdrop,
588 LAYERS_NOBACKFILL,
589 NULL);
592 if (scr->BarLayer)
594 D(bug("[intuition] CreateScreenBar: Adding BarLayer @ %p\n", scr->BarLayer));
595 D(bug("[intuition] CreateScreenBar: Rastport @ %p, Font @ %p\n", scr->BarLayer->rp, ((struct IntScreen *)scr)->DInfo.dri_Font));
596 SetFont(scr->BarLayer->rp, ((struct IntScreen *)scr)->DInfo.dri_Font);
597 if (!(scr->Flags & SCREENQUIET)) {
598 D(bug("[intuition] CreateScreenBar: Rendering Bar ...\n"));
599 RenderScreenBar(scr, FALSE, IntuitionBase);
601 D(bug("[intuition] CreateScreenBar: ... done\n"));
603 else
605 D(bug("[intuition] CreateScreenBar: Failed to create BarLayer!!\n"));
608 else
610 D(bug("[intuition] CreateScreenBar: Screen already has BarLayer\n"));
614 /**********************************************************************************/
616 void KillScreenBar(struct Screen *scr, struct IntuitionBase *IntuitionBase)
618 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
620 if (scr->BarLayer)
622 DeleteLayer(0, scr->BarLayer);
623 scr->BarLayer = FALSE;
628 /**********************************************************************************/
630 #ifdef SKINS
631 //RenderScreenBar moved to morphos/mosmisc.c
632 #endif
634 #ifndef SKINS
636 void RenderScreenBar(struct Screen *scr, BOOL refresh, struct IntuitionBase *IntuitionBase)
639 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
640 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
641 struct RastPort *rp;
643 D(bug("[intuition] RenderScreenBar()\n"));
645 if (scr->BarLayer)
647 #if USE_NEWDISPLAYBEEP
648 BOOL beeping;
649 #else
650 #define beeping 0
651 #endif
653 D(bug("[intuition] RenderScreenBar: BarLayer @ %p\n", scr->BarLayer));
655 rp = scr->BarLayer->rp;
657 D(bug("[intuition] RenderScreenBar: RastPort @ %p\n", rp));
658 /* must lock GadgetLock to avoid deadlocks with ObtainGIRPort
659 when calling refreshgadget inside layer update state */
660 LockLayerInfo(scr->BarLayer->LayerInfo);
661 LOCKGADGET(IntuitionBase)
662 LockLayer(0, scr->BarLayer);
664 D(bug("[intuition] RenderScreenBar: Layer locked\n"));
665 #if USE_NEWDISPLAYBEEP
666 beeping = (scr->Flags & BEEPING) && GetBitMapAttr(rp->BitMap, BMA_DEPTH) > 8;
667 #endif
669 if (refresh) BeginUpdate(scr->BarLayer);
672 struct sdpDrawScreenBar msg;
674 D(bug("[intuition] RenderScreenBar: Begin Refresh .. \n"));
676 msg.MethodID = SDM_DRAW_SCREENBAR;
677 msg.sdp_Layer = scr->BarLayer;
678 msg.sdp_RPort = rp;
679 msg.sdp_Flags = 0;
680 msg.sdp_Screen = scr;
681 msg.sdp_Dri = (struct DrawInfo *)&((struct IntScreen *)scr)->DInfo;
682 msg.sdp_UserBuffer = ((struct IntScreen *)(scr))->DecorUserBuffer;
683 msg.sdp_TrueColor = (((struct IntScreen *)(scr))->DInfo.dri_Flags & DRIF_DIRECTCOLOR) ? TRUE : FALSE;
685 D(bug("[intuition] RenderScreenBar: ScrDecorObj @ %p, DecorUserBuffer @ %p\n", ((struct IntScreen *)(scr))->ScrDecorObj, ((struct IntScreen *)(scr))->DecorUserBuffer));
686 DoMethodA(((struct IntScreen *)(scr))->ScrDecorObj, (Msg)&msg);
689 D(bug("[intuition] RenderScreenBar: Update gadgets .. \n"));
691 if (scr->FirstGadget)
693 RefreshBoopsiGadget(scr->FirstGadget, (struct Window *)scr, NULL, IntuitionBase);
696 if (refresh)
698 D(bug("[intuition] RenderScreenBar: End Refresh .. \n"));
699 scr->BarLayer->Flags &= ~LAYERREFRESH;
700 EndUpdate(scr->BarLayer, TRUE);
703 #if USE_NEWDISPLAYBEEP
704 if (beeping) {
705 /* FIXME: Shouldn't we 'beep' at this point? */
706 D(bug("[intuition] RenderScreenBar: Beep\n"));
708 #endif
710 D(bug("[intuition] RenderScreenBar: Unlock Layer ..\n"));
712 UnlockLayer(scr->BarLayer);
713 UNLOCKGADGET(IntuitionBase)
714 UnlockLayerInfo(scr->BarLayer->LayerInfo);
716 } /* if (scr->BarLayer) */
717 D(bug("[intuition] RenderScreenBar: Done \n"));
720 #endif
722 /**********************************************************************************/
724 void UpdateMouseCoords(struct Window *win)
726 WORD scrmousex = win->WScreen->MouseX;
727 WORD scrmousey = win->WScreen->MouseY;
729 win->MouseX = scrmousex - win->LeftEdge;
730 win->MouseY = scrmousey - win->TopEdge;
732 /* stegerg: AmigaOS sets this even if window is not GZZ
733 so we do the same as they are handy also for non-GZZ
734 windows */
736 win->GZZMouseX = scrmousex - (win->LeftEdge + win->BorderLeft);
737 win->GZZMouseY = scrmousey - (win->TopEdge + win->BorderTop);
740 /**********************************************************************************/
742 /* subtract rectangle b from rectangle b. resulting rectangles will be put into
743 destrectarray which must have place for at least 4 rectangles. Returns number
744 of resulting rectangles */
746 #if 0 /* use <clib/macros.h> MAX/MIN macros */
747 #undef MAX
748 #define MAX(a,b) (((a) > (b)) ? (a) : (b))
750 #undef MIN
751 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
752 #endif
754 WORD SubtractRectFromRect(struct Rectangle *a, struct Rectangle *b, struct Rectangle *destrectarray)
756 struct Rectangle intersect;
757 BOOL intersecting = FALSE;
758 WORD numrects = 0;
760 /* calc. intersection between a and b */
762 if (a->MinX <= b->MaxX)
764 if (a->MinY <= b->MaxY)
766 if (a->MaxX >= b->MinX)
768 if (a->MaxY >= b->MinY)
770 intersect.MinX = MAX(a->MinX, b->MinX);
771 intersect.MinY = MAX(a->MinY, b->MinY);
772 intersect.MaxX = MIN(a->MaxX, b->MaxX);
773 intersect.MaxY = MIN(a->MaxY, b->MaxY);
775 intersecting = TRUE;
781 if (!intersecting)
783 destrectarray[numrects++] = *a;
785 } /* not intersecting */
786 else
788 if (intersect.MinY > a->MinY) /* upper */
790 destrectarray->MinX = a->MinX;
791 destrectarray->MinY = a->MinY;
792 destrectarray->MaxX = a->MaxX;
793 destrectarray->MaxY = intersect.MinY - 1;
795 numrects++;
796 destrectarray++;
799 if (intersect.MaxY < a->MaxY) /* lower */
801 destrectarray->MinX = a->MinX;
802 destrectarray->MinY = intersect.MaxY + 1;
803 destrectarray->MaxX = a->MaxX;
804 destrectarray->MaxY = a->MaxY;
806 numrects++;
807 destrectarray++;
810 if (intersect.MinX > a->MinX) /* left */
812 destrectarray->MinX = a->MinX;
813 destrectarray->MinY = intersect.MinY;
814 destrectarray->MaxX = intersect.MinX - 1;
815 destrectarray->MaxY = intersect.MaxY;
817 numrects++;
818 destrectarray++;
821 if (intersect.MaxX < a->MaxX) /* right */
823 destrectarray->MinX = intersect.MaxX + 1;
824 destrectarray->MinY = intersect.MinY;
825 destrectarray->MaxX = a->MaxX;
826 destrectarray->MaxY = intersect.MaxY;
828 numrects++;
829 destrectarray++;
832 } /* intersecting */
834 return numrects;
838 ULONG addextragadget(struct Window *w,BOOL is_gzz,struct DrawInfo *dri,LONG relright,ULONG imagetype,ULONG gadgetid,ULONG gadgettype,struct IntuitionBase *IntuitionBase)
840 ULONG TitleHeight = w->BorderTop;
841 struct TagItem gadget_tags[] =
843 {GA_Image , 0 },
844 {GA_ToggleSelect, FALSE },
845 {GA_Top , 0 },
846 {GA_Height , TitleHeight },
847 {GA_TopBorder , TRUE },
848 {GA_GZZGadget , is_gzz },
849 {GA_ID , gadgetid },
850 {GA_RelVerify , TRUE },
851 {TAG_DONE }
854 Object *im;
856 if (gadgettype == LOCKGAD)
857 gadget_tags[1].ti_Data = TRUE;
859 im = CreateStdSysImage(imagetype, TitleHeight, w->WScreen, dri,IntuitionBase);
860 if (im)
862 gadget_tags[0].ti_Data = (IPTR)im;
864 SYSGAD(w, gadgettype) = NewObjectA(NULL, BUTTONGCLASS, gadget_tags);
866 if (!SYSGAD(w, gadgettype))
868 DisposeObject(im);
870 else
872 IPTR width;
873 GetAttr(GA_Width, SYSGAD(w, gadgettype), &width);
875 --width;
878 struct TagItem gadtags[] =
880 {GA_RelRight, relright - width },
881 {TAG_DONE }
884 SetAttrsA(SYSGAD(w, gadgettype), gadtags);
887 return width;
891 return 0;
895 /**********************************************************************************/
897 /* Use the FNV-1 hash function over the object's pointer.
898 * http://en.wikipedia.org/wiki/Fowler-Noll-Vo_hash_function
900 LONG CalcResourceHash(APTR resource)
902 const ULONG FNV1_32_Offset = 2166136261UL;
903 const ULONG FNV1_32_Prime = 16777619UL;
904 IPTR data = (IPTR)resource;
905 ULONG hash;
906 int i;
908 hash = FNV1_32_Offset;
909 for (i = 0; i < AROS_SIZEOFPTR; i++) {
910 hash *= FNV1_32_Prime;
911 hash ^= data & 0xff;
912 data >>= 8;
915 return hash & (RESOURCELIST_HASHSIZE-1);
918 /**********************************************************************************/
920 void AddResourceToList(APTR resource, UWORD resourcetype, struct IntuitionBase *IntuitionBase)
922 struct HashNode *hn = NULL;
923 LONG hash;
924 ULONG ilock;
926 switch(resourcetype)
928 case RESOURCE_WINDOW:
929 hn = &((struct IntWindow *)resource)->hashnode;
930 hn->type = RESOURCE_WINDOW;
931 break;
933 case RESOURCE_SCREEN:
934 hn = &((struct IntScreen *)resource)->hashnode;
935 hn->type = RESOURCE_SCREEN;
936 break;
938 default:
939 D(bug("AddResourceToList: Unknown resource type!!!\n"));
940 return;
943 hash = CalcResourceHash(resource);
945 hn->resource = resource;
947 ilock = LockIBase(0);
948 AddTail((struct List *)&GetPrivIBase(IntuitionBase)->ResourceList[hash], (struct Node *)hn);
949 UnlockIBase(ilock);
952 /**********************************************************************************/
954 void RemoveResourceFromList(APTR resource, UWORD resourcetype, struct IntuitionBase *IntuitionBase)
956 struct HashNode *hn = NULL;
957 ULONG ilock;
959 switch(resourcetype)
961 case RESOURCE_WINDOW:
962 hn = &((struct IntWindow *)resource)->hashnode;
963 break;
965 case RESOURCE_SCREEN:
966 hn = &((struct IntScreen *)resource)->hashnode;
967 break;
969 default:
970 D(bug("RemoveResourceFromList: Unknown resource type!!!\n"));
971 return;
974 if (hn->type != resourcetype)
976 D(bug("RemoveResourceFromList: Panic. Resource Type mismatch!!!\n"));
979 ilock = LockIBase(0);
980 Remove((struct Node *)hn);
981 UnlockIBase(ilock);
984 /**********************************************************************************/
986 BOOL ResourceExisting(APTR resource, UWORD resourcetype, struct IntuitionBase *IntuitionBase)
988 struct HashNode *hn = NULL;
989 LONG hash;
990 ULONG ilock;
991 BOOL exists = FALSE;
993 hash = CalcResourceHash(resource);
995 ilock = LockIBase(0);
996 ForeachNode((struct List *)&GetPrivIBase(IntuitionBase)->ResourceList[hash], hn)
998 if ((hn->resource == resource) && (hn->type == resourcetype))
1000 exists = TRUE;
1001 break;
1004 UnlockIBase(ilock);
1006 return exists;
1009 void FireScreenNotifyMessageCode(IPTR data, ULONG flag, ULONG code, struct IntuitionBase *IntuitionBase)
1011 ObtainSemaphoreShared(&GetPrivIBase(IntuitionBase)->ScreenNotificationListLock);
1013 struct ScreenNotifyMessage *msg;
1014 struct ReplyPort *reply;
1016 struct IntScreenNotify *sn;
1017 struct Node *node;
1019 BOOL ignorescreen = FALSE;
1021 if (!IsListEmpty(&GetPrivIBase(IntuitionBase)->ScreenNotificationList))
1023 node = GetPrivIBase(IntuitionBase)->ScreenNotificationList.lh_Head;
1024 for (; node->ln_Succ; node = node->ln_Succ)
1026 sn = (struct IntScreenNotify *) node;
1027 if (flag & ( SNOTIFY_AFTER_OPENSCREEN | SNOTIFY_BEFORE_OPENSCREEN
1028 | SNOTIFY_AFTER_CLOSESCREEN | SNOTIFY_BEFORE_CLOSESCREEN
1029 | SNOTIFY_LOCKPUBSCREEN | SNOTIFY_UNLOCKPUBSCREEN
1030 | SNOTIFY_SCREENDEPTH | SNOTIFY_PUBSCREENSTATE ))
1033 * If sn->pubname is supplied, only notify for it
1034 * (data must be a screen, and it must be public)
1036 if (sn->pubname)
1038 D(bug("[intuition] FSNMC() sn->pubname is non-NULL... '%s'\n", sn->pubname));
1039 LockPubScreenList();
1040 if (!( (ResourceExisting((struct Screen*)data, RESOURCE_SCREEN, IntuitionBase))
1041 && (NULL != GetPrivScreen(data)->pubScrNode)
1042 && (NULL != GetPrivScreen(data)->pubScrNode->psn_Node.ln_Name)
1043 && (0 == strcmp(sn->pubname, (const char *)GetPrivScreen(data)->pubScrNode->psn_Node.ln_Name)) ))
1045 ignorescreen = TRUE;
1047 else
1049 D(bug("[intuition] FSNMC() IntScreen->pubScrNode->psn_Node.ln_Name is non-NULL... '%s'\n", GetPrivScreen(data)->pubScrNode->psn_Node.ln_Name));
1051 UnlockPubScreenList();
1053 D(bug("[intuition] FSNMC() ignorescreen = %s\n", ignorescreen ? "TRUE" : "FALSE"));
1056 if ((sn->flags & flag) && !ignorescreen)
1058 if (sn->port)
1060 msg = AllocMem(sizeof(struct ScreenNotifyMessage), MEMF_CLEAR);
1061 if (msg)
1063 msg->snm_Message.mn_Magic = MAGIC_SCREENNOTIFY;
1064 msg->snm_Message.mn_Version = SCREENNOTIFY_VERSION;
1065 msg->snm_Object = data;
1066 msg->snm_Class = flag;
1067 msg->snm_Code = code;
1068 msg->snm_UserData = sn->userdata;
1069 msg->snm_Message.mn_Length = sizeof(struct ScreenNotifyMessage);
1070 if (sn->flags & SNOTIFY_WAIT_REPLY)
1072 reply = (struct ReplyPort *)CreateMsgPort();
1073 if (reply)
1075 msg->snm_Message.mn_ReplyPort = (struct MsgPort *)reply;
1077 PutMsg((struct MsgPort *)sn->port, (struct Message *) msg);
1078 WaitPort((struct MsgPort *)reply);
1079 GetMsg((struct MsgPort *)reply);
1080 FreeMem((APTR) msg, sizeof(struct ScreenNotifyMessage));
1081 DeleteMsgPort((struct MsgPort *)reply);
1082 } else FreeMem((APTR) msg, sizeof(struct ScreenNotifyMessage));
1084 else
1086 msg->snm_Message.mn_ReplyPort = GetPrivIBase(IntuitionBase)->ScreenNotifyReplyPort;
1088 PutMsg(sn->port, (struct Message *) msg);
1093 else if (sn->sigtask)
1095 Signal(sn->sigtask, 1 << sn->sigbit);
1097 else if (sn->hook)
1099 struct ScreenNotifyMessage msg;
1100 msg.snm_Message.mn_Magic = MAGIC_SCREENNOTIFY;
1101 msg.snm_Message.mn_Version = SCREENNOTIFY_VERSION;
1102 msg.snm_Object = data;
1103 msg.snm_Class = flag;
1104 msg.snm_UserData = sn->userdata;
1105 msg.snm_Message.mn_Length = sizeof(struct ScreenNotifyMessage);
1107 CallHook(sn->hook, NULL, (Msg) &msg);
1112 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->ScreenNotificationListLock);
1115 void FireScreenNotifyMessage(IPTR data, ULONG flag, struct IntuitionBase *IntuitionBase)
1117 FireScreenNotifyMessageCode(data, flag, 0, IntuitionBase);
1120 /**********************************************************************************/
1122 AROS_UFH3(BOOL, DefaultWindowShapeFunc,
1123 AROS_UFHA(struct Hook *, hook, A0),
1124 AROS_UFHA(struct Layer *, lay, A2),
1125 AROS_UFHA(struct ShapeHookMsg *, msg, A1))
1127 AROS_USERFUNC_INIT
1129 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)hook->h_Data;
1130 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1131 struct Window *win = (struct Window *)hook->h_SubEntry;
1132 struct Region *shape;
1133 struct wdpWindowShape shapemsg;
1135 shapemsg.MethodID = WDM_WINDOWSHAPE;
1136 shapemsg.wdp_TrueColor = (GetPrivScreen(win->WScreen)->DInfo.dri_Flags & DRIF_DIRECTCOLOR) ? TRUE : FALSE;
1137 shapemsg.wdp_Width = msg->NewBounds->MaxX - msg->NewBounds->MinX + 1;
1138 shapemsg.wdp_Height = msg->NewBounds->MaxY - msg->NewBounds->MinY + 1;
1139 shapemsg.wdp_Window = win;
1140 shapemsg.wdp_UserBuffer = IW(win)->DecorUserBuffer;
1142 shape = (struct Region *)DoMethodA(GetPrivScreen(win->WScreen)->WinDecorObj, (Msg)&shapemsg);
1144 if (IW(win)->OutlineShape) DisposeRegion(IW(win)->OutlineShape);
1145 IW(win)->OutlineShape = shape;
1146 IW(win)->CustomShape = FALSE;
1148 msg->NewShape = shape;
1149 return TRUE;
1151 AROS_USERFUNC_EXIT
1154 /**********************************************************************************/