2 Copyright 1995-2004, The AROS Development Team. All rights reserved.
3 Copyright 2001-2003, The MorphOS Development Team. All Rights Reserved.
7 #include <exec/memory.h>
8 #include <graphics/layers.h>
9 #include <graphics/gfx.h>
10 #include <intuition/intuition.h>
11 #include <intuition/imageclass.h>
12 #include <intuition/windecorclass.h>
13 #include <intuition/gadgetclass.h>
14 #include <intuition/extensions.h>
15 #include <utility/tagitem.h>
16 #include <proto/exec.h>
17 #include <proto/graphics.h>
18 #include <proto/utility.h>
19 #include <proto/intuition.h>
20 #include <proto/layers.h>
21 #include <exec/ports.h>
22 #include "intuition_intern.h"
23 #include "inputhandler.h"
24 #include "inputhandler_actions.h"
25 #include "boopsigadgets.h"
28 #include "transplayers.h"
29 #include "intuition_extend.h"
32 #ifndef DEBUG_OpenWindow
33 # define DEBUG_OpenWindow 0
40 # include <aros/debug.h>
42 struct OpenWindowActionMsg
44 struct IntuiActionMsg msg
;
45 struct Window
*window
;
46 struct BitMap
*bitmap
;
47 struct Hook
*backfillhook
;
49 struct Hook
*shapehook
;
50 struct Layer
*parentlayer
;
55 static VOID
int_openwindow(struct OpenWindowActionMsg
*msg
,
56 struct IntuitionBase
*IntuitionBase
);
58 /*****************************************************************************
62 AROS_LH1(struct Window
*, OpenWindow
,
65 AROS_LHA(struct NewWindow
*, newWindow
, A0
),
68 struct IntuitionBase
*, IntuitionBase
, 34, Intuition
)
71 Opens a new window with the characteristics specified in
75 newWindow - How you would like your new window.
78 A pointer to the new window or NULL if it couldn't be
79 opened. Reasons for this might be lack of memory or illegal
89 CloseWindow(), ModifyIDCMP()
93 *****************************************************************************/
96 AROS_LIBBASE_EXT_DECL(struct IntuitionBase
*,IntuitionBase
)
98 struct OpenWindowActionMsg msg
;
100 struct Window
*w
= NULL
, *helpgroupwindow
= NULL
, *parentwin
= NULL
;
101 struct TagItem
*tag
, *tagList
;
103 struct Hook
*backfillhook
= LAYERS_BACKFILL
, *shapehook
= NULL
;
104 struct Region
*shape
= NULL
;
105 struct IBox
*zoombox
= NULL
;
106 struct Image
*AmigaKey
= NULL
;
107 struct Image
*Checkmark
= NULL
;
108 struct Layer
*parentl
= NULL
;
110 struct SkinInfo
*skininfo
= NULL
;
111 BOOL hasskininfo
= FALSE
;
112 struct Region
*usertranspregion
= NULL
;
113 struct Hook
*usertransphook
= NULL
;
114 struct MsgPort
*userport
= NULL
;
116 STRPTR pubScreenName
= NULL
;
117 UBYTE
*screenTitle
= NULL
;
118 BOOL autoAdjust
= FALSE
, pubScreenFallBack
= FALSE
;
119 ULONG innerWidth
= ~0L;
120 ULONG innerHeight
= ~0L;
121 WORD mousequeue
= DEFAULTMOUSEQUEUE
;
122 WORD repeatqueue
= 3; /* stegerg: test on my Amiga suggests this */
125 ULONG extrabuttons
= 0, extrabuttonsid
= ETI_Dummy
;
127 ULONG windowvisible
= TRUE
;
128 BOOL driver_init_done
= FALSE
, have_helpgroup
= FALSE
;
129 BOOL do_setwindowpointer
= FALSE
;
131 ASSERT_VALID_PTR_ROMOK(newWindow
);
133 D(bug("OpenWindow (%p = { Left=%d Top=%d Width=%d Height=%d })\n"
135 , newWindow
->LeftEdge
141 FireScreenNotifyMessage((IPTR
) newWindow
, SNOTIFY_BEFORE_OPENWINDOW
, IntuitionBase
);
145 #define WFLG_PRIVATEFLAGS (WFLG_WINDOWREFRESH |\
146 WFLG_WINDOWTICKED | WFLG_VISITOR | \
150 /* WFLG_WBENCHWINDOW | \*/
151 /* this is used by WORKBENCH! */
152 /* WFLG_HASZOOM | \*/
153 /* do NOT filter this! how do you think apps could manage to get a zoom image with struct NewWindow? */
155 nw
.Flags
&= ~WFLG_PRIVATEFLAGS
;
157 if (newWindow
->Flags
& WFLG_NW_EXTENDED
)
159 tagList
= ((struct ExtNewWindow
*)newWindow
)->Extension
;
161 /* Sanitycheck the taglist pointer. Some Am*gaOS 1.3/2.x era
162 * apps have WFLG_NW_EXTENDED set with bogus Extension taglist
163 * pointer... (older CygnusED for example) - Piru
165 if (((ULONG
) tagList
& 1) || !TypeOfMem(tagList
))
176 DEBUG_OPENWINDOW(dprintf("OpenWindow: NewWindow 0x%lx TagList 0x%lx\n",
177 newWindow
, tagList
));
181 ASSERT_VALID_PTR_ROMOK(tagList
);
183 /* Look at WA_Flags first, since boolean tags override part of it
184 * even if they appear before it.
186 nw
.Flags
|= (GetTagData(WA_Flags
, nw
.Flags
, tagList
) & ~WFLG_PRIVATEFLAGS
);
188 while ((tag
= NextTagItem (&tagList
)))
190 /* ASSERT_VALID_PTR_ROMOK(tag); */
192 DEBUG_OPENWINDOW(dprintf("OpenWindow: Tag 0x%08lx 0x%08lx\n",
193 tag
->ti_Tag
, tag
->ti_Data
));
198 nw
.LeftEdge
= tag
->ti_Data
;
202 nw
.TopEdge
= tag
->ti_Data
;
206 nw
.Width
= tag
->ti_Data
;
210 nw
.Height
= tag
->ti_Data
;
214 nw
.IDCMPFlags
= tag
->ti_Data
;
218 nw
.MinWidth
= tag
->ti_Data
;
222 nw
.MinHeight
= tag
->ti_Data
;
226 nw
.MaxWidth
= tag
->ti_Data
;
230 nw
.MaxHeight
= tag
->ti_Data
;
234 nw
.FirstGadget
= (struct Gadget
*)(tag
->ti_Data
);
238 nw
.Title
= (UBYTE
*)(tag
->ti_Data
);
242 screenTitle
= (UBYTE
*)tag
->ti_Data
;
246 autoAdjust
= (tag
->ti_Data
!= 0);
250 innerWidth
= tag
->ti_Data
;
254 innerHeight
= tag
->ti_Data
;
257 #define MODIFY_FLAG(name) if (tag->ti_Data) \
258 nw.Flags |= (name); else nw.Flags &= ~(name)
259 #define MODIFY_MFLAG(name) if (tag->ti_Data) \
260 moreFlags |= (name); else moreFlags &= ~(name)
263 MODIFY_FLAG(WFLG_SIZEGADGET
);
267 MODIFY_FLAG(WFLG_DRAGBAR
);
271 MODIFY_FLAG(WFLG_DEPTHGADGET
);
275 MODIFY_FLAG(WFLG_CLOSEGADGET
);
279 MODIFY_FLAG(WFLG_BACKDROP
);
283 MODIFY_FLAG(WFLG_REPORTMOUSE
);
286 case WA_NoCareRefresh
:
287 MODIFY_FLAG(WFLG_NOCAREREFRESH
);
291 MODIFY_FLAG(WFLG_BORDERLESS
);
295 MODIFY_FLAG(WFLG_ACTIVATE
);
299 MODIFY_FLAG(WFLG_RMBTRAP
);
302 case WA_WBenchWindow
:
303 MODIFY_FLAG(WFLG_WBENCHWINDOW
);
307 MODIFY_FLAG(WFLG_SIZEBRIGHT
);
311 MODIFY_FLAG(WFLG_SIZEBBOTTOM
);
314 case WA_GimmeZeroZero
:
315 MODIFY_FLAG(WFLG_GIMMEZEROZERO
);
318 case WA_NewLookMenus
:
319 MODIFY_FLAG(WFLG_NEWLOOKMENUS
);
323 zoombox
= (struct IBox
*)tag
->ti_Data
;
324 DEBUG_OPENWINDOW(dprintf("OpenWindow: zoom %d %d %d %d\n",
325 zoombox
->Left
, zoombox
->Top
, zoombox
->Width
, zoombox
->Height
));
326 MODIFY_FLAG(WFLG_HASZOOM
);
330 if (nw
.DetailPen
== 0xFF)
331 nw
.DetailPen
= tag
->ti_Data
;
335 if (nw
.BlockPen
== 0xFF)
336 nw
.BlockPen
= tag
->ti_Data
;
339 case WA_CustomScreen
:
340 nw
.Screen
= (struct Screen
*)(tag
->ti_Data
);
341 nw
.Type
= CUSTOMSCREEN
;
345 nw
.Flags
|= WFLG_SUPER_BITMAP
;
346 nw
.BitMap
= (struct BitMap
*)(tag
->ti_Data
);
349 case WA_SimpleRefresh
:
351 nw
.Flags
|= WFLG_SIMPLE_REFRESH
;
354 case WA_SmartRefresh
:
356 nw
.Flags
|= WFLG_SMART_REFRESH
;
359 case WA_PubScreenFallBack
:
360 pubScreenFallBack
= (tag
->ti_Data
? TRUE
: FALSE
);
363 case WA_PubScreenName
:
364 //nw.Type = PUBLICSCREEN; //handled below!!
365 pubScreenName
= (STRPTR
)tag
->ti_Data
;
369 nw
.Type
= PUBLICSCREEN
;
370 nw
.Screen
= (struct Screen
*)tag
->ti_Data
;
374 backfillhook
= (struct Hook
*)tag
->ti_Data
;
378 mousequeue
= tag
->ti_Data
;
381 /* These two are not implemented in AmigaOS */
387 MODIFY_MFLAG(WMFLG_NOTIFYDEPTH
);
391 repeatqueue
= tag
->ti_Data
;
395 Checkmark
= (struct Image
*)tag
->ti_Data
;
399 AmigaKey
= (struct Image
*)tag
->ti_Data
;
403 helpgroup
= (ULONG
)tag
->ti_Data
;
404 have_helpgroup
= TRUE
;
407 case WA_HelpGroupWindow
:
408 helpgroupwindow
= (struct Window
*)tag
->ti_Data
;
412 MODIFY_MFLAG(WMFLG_MENUHELP
);
415 case WA_PointerDelay
:
416 MODIFY_MFLAG(WMFLG_POINTERDELAY
);
419 case WA_TabletMessages
:
420 MODIFY_MFLAG(WMFLG_TABLETMESSAGES
);
423 case WA_ExtraTitlebarGadgets
:
424 extrabuttons
= (ULONG
)tag
->ti_Data
;
427 case WA_ExtraGadgetsStartID
:
428 extrabuttonsid
= (ULONG
)tag
->ti_Data
;
431 case WA_ExtraGadget_Iconify
:
434 extrabuttons
|= ETG_ICONIFY
;
438 extrabuttons
&= ~ETG_ICONIFY
;
442 case WA_ExtraGadget_Lock
:
445 extrabuttons
|= ETG_LOCK
;
449 extrabuttons
&= ~ETG_LOCK
;
453 case WA_ExtraGadget_MUI
:
456 extrabuttons
|= ETG_MUI
;
460 extrabuttons
&= ~ETG_MUI
;
464 case WA_ExtraGadget_PopUp
:
467 extrabuttons
|= ETG_POPUP
;
471 extrabuttons
&= ~ETG_POPUP
;
475 case WA_ExtraGadget_Snapshot
:
478 extrabuttons
|= ETG_SNAPSHOT
;
482 extrabuttons
&= ~ETG_SNAPSHOT
;
486 case WA_ExtraGadget_Jump
:
489 extrabuttons
|= ETG_JUMP
;
493 extrabuttons
&= ~ETG_JUMP
;
499 skininfo
= (struct SkinInfo
*)tag
->ti_Data
;
503 case WA_TransparentRegion
:
504 usertranspregion
= (struct Region
*)tag
->ti_Data
;
505 usertransphook
= NULL
; //doesn't make sense
508 case WA_TransparentRegionHook
:
509 usertransphook
= (struct Hook
*)tag
->ti_Data
;
510 usertranspregion
= NULL
;
514 userport
= (struct MsgPort
*)tag
->ti_Data
;
518 MODIFY_MFLAG(WMFLG_IAMMUI
);
524 shape
= (struct Region
*)tag
->ti_Data
;
528 shapehook
= (struct Hook
*)tag
->ti_Data
;
533 parentwin
= ((struct Window
*)tag
->ti_Data
);
534 parentl
= parentwin
->WLayer
;
538 windowvisible
= (ULONG
)tag
->ti_Data
;
544 do_setwindowpointer
= TRUE
;
549 } /* while ((tag = NextTagItem (&tagList))) */
553 if (nw
.Flags
& WFLG_SIZEGADGET
)
555 if (!(nw
.Flags
& (WFLG_SIZEBRIGHT
| WFLG_SIZEBBOTTOM
)))
557 nw
.Flags
|= WFLG_SIZEBRIGHT
;
560 //jDc: tested behavior of intuition68k
561 nw
.Flags
|= WFLG_HASZOOM
;
565 nw
.Flags
&= ~(WFLG_SIZEBRIGHT
|WFLG_SIZEBBOTTOM
);
568 if (nw
.Flags
& WFLG_BORDERLESS
)
570 nw
.Flags
&= ~(WFLG_SIZEBRIGHT
|WFLG_SIZEBBOTTOM
|WFLG_SIZEGADGET
);
573 /* Find out on which Screen the window must open */
575 /* (cyfm 03/03/03 check for nw.Type == PUBLICSCREEN as well, some programs
576 * like TurboPrint GraphicPublisher specify {WA_PubScreen, NULL} and want
577 * to open on the default public screen that way
580 if (!nw
.Screen
&& (pubScreenName
|| (nw
.Type
== PUBLICSCREEN
)))
582 struct Screen
*pubs
= 0;
584 moreFlags
|= WMFLG_DO_UNLOCKPUBSCREEN
;
585 pubs
= LockPubScreen(pubScreenName
);
586 if (!pubs
&& pubScreenFallBack
)
588 nw
.Screen
= LockPubScreen(NULL
);
594 nw
.Type
= PUBLICSCREEN
;
595 if (nw
.Screen
) nw
.Flags
|= WFLG_VISITOR
;
598 if (!nw
.Screen
&& nw
.Type
== WBENCHSCREEN
)
600 nw
.Screen
= LockPubScreen("Workbench");
603 moreFlags
|= WMFLG_DO_UNLOCKPUBSCREEN
;
604 if (nw
.Screen
) nw
.Flags
|= WFLG_VISITOR
;
608 if (nw
.Screen
== NULL
)
611 w
= AllocMem (sizeof(struct IntWindow
), MEMF_CLEAR
);
613 DEBUG_OPENWINDOW(dprintf("OpenWindow: Window 0x%lx\n", w
));
615 /* nlorentz: For now, creating a rastport becomes the responsibility of
616 intui_OpenWindow(). This is because intui_OpenWindow() in
617 config/hidd/intuition_driver.c must call CreateUpfrontLayer(),
618 and that will create a rastport for the layer/window, and we don't
619 want two rastports pr. window.
620 Alternatively we may create a layers_driver.c driver for layers,
621 and then call CreateUpfrontLayer() here from openwindow.
622 For the Amiga window<-->X11 window stuff, the layers driver
623 would just allocate a layer struct, a rastport and
624 put the rasport into layer->RastPort, so we
625 could get it inside this routine and put it into
633 DEBUG_OPENWINDOW(dprintf("OpenWindow: Flags 0x%lx MoreFlags 0x%lx IDCMP 0x%lx\n",
634 nw
.Flags
, moreFlags
, nw
.IDCMPFlags
));
636 w
->WScreen
= nw
.Screen
;
641 w
->UserPort
= userport
;
642 ((struct IntWindow
*)w
)->specialflags
|= SPFLAG_USERPORT
;
646 if (!ModifyIDCMP (w
, nw
.IDCMPFlags
))
649 ((struct IntWindow
*)w
)->extrabuttons
= extrabuttons
;
650 ((struct IntWindow
*)w
)->extrabuttonsid
= extrabuttonsid
;
654 //w->FirstGadget = nw.FirstGadget;
656 w
->DetailPen
= (nw
.DetailPen
!= 0xFF) ? nw
.DetailPen
: w
->WScreen
->DetailPen
;
657 w
->BlockPen
= (nw
.BlockPen
!= 0xFF) ? nw
.BlockPen
: w
->WScreen
->BlockPen
;
661 w
->MoreFlags
= moreFlags
;
663 if (!(w
->Flags
& WFLG_BORDERLESS
))
665 w
->BorderLeft
= w
->WScreen
->WBorLeft
;
666 w
->BorderRight
= w
->WScreen
->WBorRight
;
668 w
->BorderTop
= w
->WScreen
->WBorBottom
;
670 w
->BorderTop
= w
->WScreen
->WBorTop
;
672 w
->BorderBottom
= w
->WScreen
->WBorBottom
;
675 if (nw
.Title
|| (w
->Flags
& (WFLG_DRAGBAR
| WFLG_CLOSEGADGET
| WFLG_DEPTHGADGET
)))
677 /* this is a hack. the correct way to "correct" (increase if necessary)
678 the w->Border??? items would be to check all GACT_???BORDER gadgets
679 (inclusive sysgadgets which are GACT_????BORDER gadgets as well) in
680 nw.FirstGadget (or WA_Gadgets tag) and all sysgadgets and then
681 make sure that each window border is big enough so that none of these
682 gadgets extends outside the window border area */
685 w
->BorderTop
= w
->WScreen
->WBorTop
;
687 /* Georg Steger: ??? font ??? */
688 if (w
->WScreen
->Font
)
689 w
->BorderTop
+= ((struct IntScreen
*)(w
->WScreen
))->DInfo
.dri
.dri_Font
->tf_YSize
+ 1;
691 w
->BorderTop
+= GfxBase
->DefaultFont
->tf_YSize
+ 1;
696 struct windowclassprefs
*wcprefs
;
697 struct IntDrawInfo
*dri
;
698 if ((dri
= (struct IntDrawInfo
*)GetScreenDrawInfo(w
->WScreen
)))
700 wcprefs
= (struct windowclassprefs
*)int_GetCustomPrefs(TYPE_WINDOWCLASS
,dri
,IntuitionBase
);
701 w
->BorderTop
+= wcprefs
->titlebarincrement
;
702 int_FreeCustomPrefs(TYPE_WINDOWCLASS
,dri
,IntuitionBase
);
709 /* look for GACT_???BORDER gadgets which increase the BorderSizes */
715 for(gad
= nw
.FirstGadget
; gad
; gad
= gad
->NextGadget
)
717 WORD gadx1
, gady1
, gadx2
, gady2
;
719 if (gad
->Activation
& GACT_LEFTBORDER
)
721 /* may never be GFLG_RELRIGHT / GFLG_RELWIDTH */
723 gadx2
= gad
->LeftEdge
+ gad
->Width
- 1;
724 if (gadx2
>= w
->BorderLeft
) w
->BorderLeft
= gadx2
/* + 1*/;
727 if (gad
->Activation
& GACT_TOPBORDER
)
729 /* may never be GFLG_RELBOTTOM / GFLG_RELHEIGHT */
731 gady2
= gad
->TopEdge
+ gad
->Height
- 1;
732 if (gady2
>= w
->BorderTop
) w
->BorderTop
= gady2
/* + 1*/;
735 if (gad
->Activation
& GACT_RIGHTBORDER
)
737 /* must be GFLG_RELRIGHT but never GFLG_RELWIDTH */
739 gadx1
= -gad
->LeftEdge
;
740 if (gadx1
>= w
->BorderRight
) w
->BorderRight
= gadx1
/* + 1*/;
743 if (gad
->Activation
& GACT_BOTTOMBORDER
)
745 /* must be GFLG_RELBOTTOM but never GFLG_RELHEIGHT */
747 gady1
= -gad
->TopEdge
;
748 if (gady1
>= w
->BorderBottom
) w
->BorderBottom
= gady1
/* + 1*/;
751 } /* for(gad = nw.FirstGadget; gad; gad = gad->NextGadget) */
753 } /* if (nw.FirstGadget) */
755 if (!(w
->Flags
& WFLG_SIZEBRIGHT
)) if (w
->BorderRight
> w
->WScreen
->WBorRight
)
757 w
->Flags
|= WFLG_SIZEBRIGHT
;
760 if (!(w
->Flags
& WFLG_SIZEBBOTTOM
)) if (w
->BorderBottom
> w
->WScreen
->WBorBottom
)
762 w
->Flags
|= WFLG_SIZEBBOTTOM
;
766 // if ((w->Flags & WFLG_SIZEGADGET) &&
767 // (w->Flags & (WFLG_SIZEBRIGHT | WFLG_SIZEBBOTTOM)))
769 IPTR sizewidth
= 16, sizeheight
= 16;
771 struct DrawInfo
*dri
;
773 if ((dri
= GetScreenDrawInfo(w
->WScreen
)))
775 struct TagItem imtags
[] =
777 {SYSIA_DrawInfo
, (STACKIPTR
)dri
},
778 {SYSIA_Which
, SIZEIMAGE
},
779 {SYSIA_Size
, w
->WScreen
->Flags
& SCREENHIRES
? SYSISIZE_MEDRES
: SYSISIZE_LOWRES
},
783 if ((im
= NewObjectA(NULL
, SYSICLASS
, imtags
)))
785 GetAttr(IA_Width
, (Object
*)im
, &sizewidth
);
786 GetAttr(IA_Height
, (Object
*)im
, &sizeheight
);
790 FreeScreenDrawInfo(w
->WScreen
, dri
);
793 if (w
->Flags
& WFLG_SIZEBRIGHT
)
795 if (w
->BorderRight
< sizewidth
) w
->BorderRight
= sizewidth
;
798 if (w
->Flags
& WFLG_SIZEBBOTTOM
)
800 if (w
->BorderBottom
< sizeheight
) w
->BorderBottom
= sizeheight
;
803 IW(w
)->sizeimage_width
= sizewidth
;
804 IW(w
)->sizeimage_height
= sizeheight
;
806 /* now increase window size if it's necessary */
811 IW(w
)->custombackfill
.h_Entry
= (HOOKFUNC
)HookEntry
;
812 IW(w
)->custombackfill
.h_SubEntry
= (HOOKFUNC
)GradientizeBackfillFunc
;
813 IW(w
)->custombackfill
.h_Data
= &IW(w
)->hd
;
814 IW(w
)->hd
.intuitionBase
= IntuitionBase
;
816 IW(w
)->usertranspregion
= usertranspregion
;
817 IW(w
)->usertransphook
= usertransphook
;
821 if (innerWidth
!= ~0L) nw
.Width
= innerWidth
+ w
->BorderLeft
+ w
->BorderRight
;
822 if (innerHeight
!= ~0L) nw
.Height
= innerHeight
+ w
->BorderTop
+ w
->BorderBottom
;
828 parentwidth
= parentwin
? parentwin
->Width
: w
->WScreen
->Width
;
829 parentheight
= parentwin
? parentwin
->Height
: w
->WScreen
->Height
;
831 w
->Width
= (nw
.Width
!= ~0) ? nw
.Width
: parentwidth
- nw
.LeftEdge
;
832 w
->Height
= (nw
.Height
!= ~0) ? nw
.Height
: parentheight
- nw
.TopEdge
;
837 if (w
->Width
> parentwidth
) w
->Width
= parentwidth
;
838 if (w
->Height
> parentheight
) w
->Height
= parentheight
;
840 if (nw
.LeftEdge
< 0) nw
.LeftEdge
= 0;
841 if (nw
.TopEdge
< 0) nw
.TopEdge
= 0;
843 if ((nw
.LeftEdge
+ w
->Width
) > parentwidth
)
844 nw
.LeftEdge
= parentwidth
- w
->Width
;
846 if ((nw
.TopEdge
+ w
->Height
) > parentheight
)
847 nw
.TopEdge
= parentheight
- w
->Height
;
850 w
->GZZWidth
= w
->Width
- w
->BorderLeft
- w
->BorderRight
;
851 w
->GZZHeight
= w
->Height
- w
->BorderTop
- w
->BorderBottom
;
854 if (nw
.LeftEdge
< 0 || nw
.TopEdge
< 0 ||
855 nw
.LeftEdge
+ w
->Width
> w
->WScreen
->Width
||
856 nw
.TopEdge
+ w
->Height
> w
->WScreen
->Height
)
859 if (NULL
== parentwin
)
861 w
->LeftEdge
= nw
.LeftEdge
;
862 w
->TopEdge
= nw
.TopEdge
;
866 w
->LeftEdge
= nw
.LeftEdge
+ parentwin
->LeftEdge
;
867 w
->TopEdge
= nw
.TopEdge
+ parentwin
->TopEdge
;
871 w
->RelLeftEdge
= nw
.LeftEdge
;
872 w
->RelTopEdge
= nw
.TopEdge
;
875 w
->MinWidth
= (nw
.MinWidth
!= 0) ? nw
.MinWidth
: w
->Width
;
876 w
->MinHeight
= (nw
.MinHeight
!= 0) ? nw
.MinHeight
: w
->Height
;
877 w
->MaxWidth
= (nw
.MaxWidth
!= 0) ? nw
.MaxWidth
: w
->Width
;
878 w
->MaxHeight
= (nw
.MaxHeight
!= 0) ? nw
.MaxHeight
: w
->Height
;
880 //jDc: tested behavior of intuition68k
881 if ((UWORD
)w
->MaxWidth
< w
->Width
) w
->MaxWidth
= w
->Width
;
882 if ((UWORD
)w
->MaxHeight
< w
->Height
) w
->MaxHeight
= w
->Height
;
884 /* check if maxwidth/height is not bigger than screen */
885 if (w
->MaxWidth
> w
->WScreen
->Width
) w
->MaxWidth
= w
->WScreen
->Width
;
886 if (w
->MaxHeight
> w
->WScreen
->Height
) w
->MaxHeight
= w
->WScreen
->Height
;
890 ((struct IntWindow
*)w
)->ZipLeftEdge
= zoombox
->Left
;
891 ((struct IntWindow
*)w
)->ZipTopEdge
= zoombox
->Top
;
892 ((struct IntWindow
*)w
)->ZipWidth
= zoombox
->Width
;
893 ((struct IntWindow
*)w
)->ZipHeight
= zoombox
->Height
;
897 ((struct IntWindow
*)w
)->ZipLeftEdge
= nw
.LeftEdge
;
898 ((struct IntWindow
*)w
)->ZipTopEdge
= nw
.TopEdge
;
899 ((struct IntWindow
*)w
)->ZipWidth
= (w
->Width
== w
->MinWidth
) ? w
->MaxWidth
: w
->MinWidth
;
900 ((struct IntWindow
*)w
)->ZipHeight
= (w
->Height
== w
->MinHeight
) ? w
->MaxHeight
: w
->MinHeight
;
903 DEBUG_OPENWINDOW(dprintf("OpenWindow: zip %d %d %d %d\n",
904 ((struct IntWindow
*)w
)->ZipLeftEdge
,
905 ((struct IntWindow
*)w
)->ZipTopEdge
,
906 ((struct IntWindow
*)w
)->ZipWidth
,
907 ((struct IntWindow
*)w
)->ZipHeight
));
910 IW(w
)->mousequeue
= mousequeue
;
911 IW(w
)->repeatqueue
= repeatqueue
;
913 /* Amiga and checkmark images for menus */
915 IW(w
)->Checkmark
= Checkmark
? Checkmark
:
916 ((struct IntScreen
*)(w
->WScreen
))->DInfo
.dri
.dri_CheckMark
;
918 IW(w
)->AmigaKey
= AmigaKey
? AmigaKey
:
919 ((struct IntScreen
*)(w
->WScreen
))->DInfo
.dri
.dri_AmigaKey
;
923 if (NULL
!= parentwin
)
925 if (parentwin
->firstchild
)
926 parentwin
->firstchild
->prevchild
= w
;
928 w
->nextchild
= parentwin
->firstchild
;
929 parentwin
->firstchild
= w
;
930 w
->parent
= parentwin
;
935 if (hasskininfo
) ((struct IntWindow
*)(w
))->specialflags
= SPFLAG_SKININFO
;
939 if ((w
->Flags
& WFLG_SIMPLE_REFRESH
) && (IS_DOCAREREFRESH(w
)) && (!(w
->Flags
& WFLG_BORDERLESS
))) IW(w
)->trashregion
= NewRegion();
944 if (!have_helpgroup
&& helpgroupwindow
)
946 if (IW(helpgroupwindow
)->helpflags
& HELPF_ISHELPGROUP
)
948 helpgroup
= IW(helpgroupwindow
)->helpgroup
;
949 have_helpgroup
= TRUE
;
955 IW(w
)->helpflags
|= HELPF_ISHELPGROUP
;
956 IW(w
)->helpgroup
= helpgroup
;
964 /* Use safe OpenFont.. - Piru
967 if (GetPrivScreen(w
->WScreen
)->SpecialFlags
& SF_SysFont
)
969 w
->IFont
= SafeReopenFont(IntuitionBase
, &GfxBase
->DefaultFont
);
973 w
->IFont
= SafeReopenFont(IntuitionBase
, &(GetPrivScreen(w
->WScreen
)->DInfo
.dri
.dri_Font
));
976 if (w
->IFont
== NULL
)
981 #warning: Really hacky way of re-opening GfxBase->DefaultFont
984 w
->IFont
= GfxBase
->DefaultFont
;
985 w
->IFont
->tf_Accessors
++;
990 /* jDc: intui68k waits before opening the window until
991 ** Move/SizeWindow actions are over (does it mean it's executed on
992 ** caller's context?).
996 if (!(FindTask(0) == ((struct IIHData
*)GetPrivIBase(IntuitionBase
)->InputHandler
->is_Data
)->InputDeviceTask
))
998 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->WindowLock
);
1003 msg
.bitmap
= nw
.BitMap
;
1004 //msg.backfillhook = backfillhook == LAYERS_BACKFILL ? &IW(w)->custombackfill : backfillhook;
1005 msg
.backfillhook
= backfillhook
;
1007 msg
.shapehook
= shapehook
;
1008 msg
.parentlayer
= parentl
;
1009 msg
.visible
= windowvisible
;
1011 DoSyncAction((APTR
)int_openwindow
, &msg
.msg
, IntuitionBase
);
1013 #ifdef USEWINDOWLOCK
1014 if (!(FindTask(0) == ((struct IIHData
*)GetPrivIBase(IntuitionBase
)->InputHandler
->is_Data
)->InputDeviceTask
))
1016 ReleaseSemaphore(&GetPrivIBase(IntuitionBase
)->WindowLock
);
1023 /* nlorentz: The driver has in some way or another allocated a rastport for us,
1024 which now is ready for us to use. */
1026 driver_init_done
= TRUE
;
1029 D(bug("called driver, rp=%p\n", rp
));
1031 /* The window RastPort always gets the font from GfxBase->DefaultFont, which
1032 is the system's default font. Usually topaz 8, but it can be changed with
1033 the Fonts prefs program to another fixed-sized font. */
1035 SetFont (rp
, w
->IFont
);
1037 D(bug("set fonts\n"));
1039 #warning Remove workaround!
1040 /* lbischoff: The following 4 Setxxx lines are a workaround for the InitRastPort
1041 problem (Bug #75 in docs/BUGS). They ensure that at least a window's rastport
1042 is initialized correctly. Remove them if they are not needed any longer!
1044 SetABPenDrMd (rp
, rp
->FgPen
, rp
->BgPen
, rp
->DrawMode
);
1045 SetWriteMask (rp
, rp
->Mask
);
1046 D(bug("set pens\n"));
1049 /* Send all GA_RelSpecial BOOPSI gadgets in the list the GM_LAYOUT msg */
1050 /*DoGMLayout(w->FirstGadget, w, NULL, -1, TRUE, IntuitionBase);
1052 if (NULL != w->FirstGadget)
1053 RefreshGadgets (w->FirstGadget, w, NULL);
1058 struct IntDrawInfo
*dri
= &((struct IntScreen
*)(w
->WScreen
))->DInfo
;
1059 struct wdpLayoutBorderGadgets msg
;
1061 msg
.MethodID
= WDM_LAYOUT_BORDERGADGETS
;
1063 msg
.wdp_Gadgets
= nw
.FirstGadget
;
1064 msg
.wdp_Flags
= WDF_LBG_INITIAL
| WDF_LBG_MULTIPLE
;
1066 LOCKSHARED_WINDECOR(dri
);
1067 DoMethodA(dri
->dri_WinDecorObj
, (Msg
)&msg
);
1068 UNLOCK_WINDECOR(dri
);
1070 AddGList(w
, nw
.FirstGadget
, -1, -1, NULL
);
1074 /* !!! This does double refreshing as the system gadgets also are refreshed
1075 in the above RfreshGadgets() call */
1076 if (nw
.Flags
& WFLG_ACTIVATE
)
1078 /* RefreshWindowFrame() will be called from within ActivateWindow().
1079 No point in doing double refreshing. */
1085 RefreshWindowFrame(w
);
1089 if (screenTitle
!= NULL
)
1090 SetWindowTitles (w
, (CONST_STRPTR
)~0L, screenTitle
);
1092 UpdateMouseCoords(w
);
1094 if (do_setwindowpointer
)
1096 //jDc: main for () loop destroys original taglist pointer, we need to get
1097 //it once again here!
1098 tagList
= (struct TagItem
*)((struct ExtNewWindow
*)newWindow
)->Extension
;
1099 SetWindowPointerA(w
, tagList
);
1109 ModifyIDCMP (w
, 0L);
1111 /* nlorentz: Freeing the rasport is now intui_CloseWindow()'s task.
1119 if (driver_init_done
)
1120 intui_CloseWindow(w
, IntuitionBase
);
1122 if (w
->IFont
) CloseFont(w
->IFont
);
1124 FreeMem (w
, sizeof(struct IntWindow
));
1129 if (nw
.Screen
&& (moreFlags
& WMFLG_DO_UNLOCKPUBSCREEN
))
1131 UnlockPubScreen(NULL
, nw
.Screen
);
1136 DEBUG_OPENWINDOW(dprintf("OpenWindow: Return 0x%lx\n", w
));
1138 FireScreenNotifyMessage((IPTR
) w
, SNOTIFY_AFTER_OPENWINDOW
, IntuitionBase
);
1140 ReturnPtr ("OpenWindow", struct Window
*, w
);
1146 /**********************************************************************************/
1148 static VOID
int_openwindow(struct OpenWindowActionMsg
*msg
,
1149 struct IntuitionBase
*IntuitionBase
)
1151 struct Window
* w
= msg
->window
;
1152 struct BitMap
* SuperBitMap
= msg
->bitmap
;
1153 struct Hook
* backfillhook
= msg
->backfillhook
;
1154 #ifdef CreateLayerTagList
1155 struct Region
* shape
= msg
->shape
;
1156 struct Hook
* shapehook
= msg
->shapehook
;
1157 struct Layer
* parent
= msg
->parentlayer
;
1158 BOOL visible
= msg
->visible
;
1162 BOOL installtransphook
= FALSE
;
1163 BOOL notransphook
= TRUE
;
1166 /* Create a layer for the window */
1167 LONG layerflags
= 0;
1169 EnterFunc(bug("int_OpenWindow(w=%p)\n", w
));
1171 D(bug("screen: %p\n", w
->WScreen
));
1172 D(bug("bitmap: %p\n", w
->WScreen
->RastPort
.BitMap
));
1174 /* Just insert some default values, should be taken from
1175 w->WScreen->WBorxxxx */
1177 /* Set the layer's flags according to the flags of the
1182 if (w
->Flags
& WFLG_SIMPLE_REFRESH
)
1184 layerflags
|= LAYERSIMPLE
;
1188 if (w
->Flags
& WFLG_SUPER_BITMAP
&& SuperBitMap
)
1190 layerflags
|= LAYERSUPER
;
1194 layerflags
|= LAYERSMART
;
1198 if (w
->Flags
& WFLG_BACKDROP
)
1200 layerflags
|= LAYERBACKDROP
;
1203 D(bug("Window dims: (%d, %d, %d, %d)\n",
1204 w
->LeftEdge
, w
->TopEdge
, w
->Width
, w
->Height
));
1207 //install transp layer hook!
1209 struct windowclassprefs
*wcprefs
= NULL
;
1211 wcprefs
= (struct windowclassprefs
*)int_GetCustomPrefs(TYPE_WINDOWCLASS
,&((struct IntScreen
*)(w
->WScreen
))->DInfo
,IntuitionBase
);
1212 if (wcprefs
->flags
& WINDOWCLASS_PREFS_ROUNDEDEDGES
&& (w
->Title
|| (w
->Flags
& (WFLG_DRAGBAR
| WFLG_CLOSEGADGET
| WFLG_DEPTHGADGET
))))
1214 IW(w
)->transpregion
= NewRegion();
1215 if (IW(w
)->transpregion
)
1217 installtransphook
= TRUE
; notransphook
= FALSE
;
1218 IW(w
)->specialflags
|= SPFLAG_TRANSPHOOK
;
1223 if (IW(w
)->usertransphook
)
1225 IW(w
)->transpregion
= NewRegion();
1226 if (IW(w
)->transpregion
)
1228 installtransphook
= TRUE
;
1229 IW(w
)->specialflags
|= SPFLAG_TRANSPHOOK
;
1232 else if (IW(w
)->usertranspregion
)
1234 IW(w
)->transpregion
= NewRegion();
1235 if (IW(w
)->transpregion
)
1237 installtransphook
= TRUE
;
1238 IW(w
)->specialflags
|= SPFLAG_TRANSPHOOK
;
1242 int_FreeCustomPrefs(TYPE_SYSICLASS
,&((struct IntScreen
*)(w
->WScreen
))->DInfo
,IntuitionBase
);
1246 // LockLayers(&w->WScreen->LayerInfo);
1248 /* A GimmeZeroZero window??? */
1249 if (w
->Flags
& WFLG_GIMMEZEROZERO
)
1252 A GimmeZeroZero window is to be created:
1253 - the outer window will be a simple refresh layer
1254 - the inner window will be a layer according to the flags
1255 What is the size of the inner/outer window supposed to be???
1256 I just make it that the outer window has the size of what is requested
1261 struct TagItem layertags
[] =
1263 {LA_BackfillHook
, (IPTR
)LAYERS_NOBACKFILL
},
1264 {SuperBitMap
? LA_SuperBitMap
: TAG_IGNORE
, (IPTR
)SuperBitMap
},
1265 {installtransphook
? LA_TransHook
: TAG_IGNORE
, notransphook
? (IPTR
)&((struct IntIntuitionBase
*)(IntuitionBase
))->notransphook
: (IPTR
)&((struct IntIntuitionBase
*)(IntuitionBase
))->transphook
},
1266 {installtransphook
? LA_TransRegion
: TAG_IGNORE
, (IPTR
)IW(w
)->transpregion
},
1267 {LA_WindowPtr
, (IPTR
)w
},
1273 /* First create outer window */
1274 struct Layer
* L
= CreateUpfrontLayerTagList(
1275 &w
->WScreen
->LayerInfo
1276 , w
->WScreen
->RastPort
.BitMap
1279 , w
->LeftEdge
+ w
->Width
- 1
1280 , w
->TopEdge
+ w
->Height
- 1
1281 , LAYERSIMPLE
| (layerflags
& LAYERBACKDROP
)
1282 , (struct TagItem
*)&layertags
);
1285 /* First create outer window */
1287 struct TagItem lay_tags
[] =
1289 {LA_Hook
, (IPTR
)LAYERS_NOBACKFILL
},
1290 {LA_Priority
, (layerflags
& LAYERBACKDROP
) ? BACKDROPPRIORITY
: UPFRONTPRIORITY
},
1291 {LA_SuperBitMap
, (IPTR
)NULL
},
1292 {LA_ChildOf
, (IPTR
)parent
},
1293 {LA_Visible
, (ULONG
)visible
},
1297 struct Layer
* L
= CreateLayerTagList(&w
->WScreen
->LayerInfo
,
1298 w
->WScreen
->RastPort
.BitMap
,
1301 w
->RelLeftEdge
+ w
->Width
- 1,
1302 w
->RelTopEdge
+ w
->Height
- 1,
1303 LAYERSIMPLE
| (layerflags
& LAYERBACKDROP
),
1307 /* Could the layer be created. Nothing bad happened so far, so simply leave */
1310 msg
->success
= FALSE
;
1311 // UnlockLayers(&w->WScreen->LayerInfo);
1312 ReturnVoid("intui_OpenWindow(No GimmeZeroZero layer)");
1315 D(bug("created outer GimmeZeroZero layer.\n"));
1317 /* install it as the BorderRPort */
1318 w
->BorderRPort
= L
->rp
;
1321 /* This layer belongs to a window */
1323 L
->Window
= (APTR
)w
;
1327 /* Now comes the inner window */
1328 layertags
[0].ti_Data
= (IPTR
)backfillhook
;
1329 w
->WLayer
= CreateUpfrontLayerTagList(
1330 &w
->WScreen
->LayerInfo
1331 , w
->WScreen
->RastPort
.BitMap
1332 , w
->LeftEdge
+ w
->BorderLeft
1333 , w
->TopEdge
+ w
->BorderTop
1334 , w
->LeftEdge
+ w
->BorderLeft
+ w
->GZZWidth
- 1
1335 , w
->TopEdge
+ w
->BorderTop
+ w
->GZZHeight
- 1
1337 , (struct TagItem
*)&layertags
);
1340 /* Now comes the inner window */
1343 struct TagItem lay_tags
[] =
1345 {LA_Hook
, (IPTR
)backfillhook
},
1346 {LA_Priority
, (layerflags
& LAYERBACKDROP
) ? BACKDROPPRIORITY
: UPFRONTPRIORITY
},
1347 {LA_Shape
, (IPTR
)shape
},
1348 {LA_ShapeHook
, (IPTR
)shapehook
},
1349 {LA_SuperBitMap
, (IPTR
)SuperBitMap
},
1350 {LA_ChildOf
, (IPTR
)parent
},
1351 {LA_Visible
, (ULONG
)visible
},
1355 w
->WLayer
= CreateLayerTagList(&w
->WScreen
->LayerInfo
,
1356 w
->WScreen
->RastPort
.BitMap
,
1357 w
->RelLeftEdge
+ w
->BorderLeft
,
1358 w
->RelTopEdge
+ w
->BorderTop
,
1359 w
->RelLeftEdge
+ w
->BorderLeft
+ w
->GZZWidth
- 1,
1360 w
->RelTopEdge
+ w
->BorderTop
+ w
->GZZHeight
- 1,
1368 /* could this layer be created? If not then delete the outer window and exit */
1369 if (NULL
== w
->WLayer
)
1372 msg
->success
= FALSE
;
1373 // UnlockLayers(&w->WScreen->LayerInfo);
1374 ReturnVoid("intui_OpenWindow(No window layer)");
1377 /* That should do it, I guess... */
1383 struct TagItem layertags
[] =
1385 {LA_BackfillHook
, (IPTR
)backfillhook
},
1386 {SuperBitMap
? LA_SuperBitMap
: TAG_IGNORE
, (IPTR
)SuperBitMap
},
1387 {installtransphook
? LA_TransHook
: TAG_IGNORE
, notransphook
? (IPTR
)&((struct IntIntuitionBase
*)(IntuitionBase
))->notransphook
: (IPTR
)&((struct IntIntuitionBase
*)(IntuitionBase
))->transphook
},
1388 {installtransphook
? LA_TransRegion
: TAG_IGNORE
, (IPTR
)IW(w
)->transpregion
},
1389 {LA_WindowPtr
, (IPTR
)w
},
1393 D(dprintf("CreateUpfontLayerTagList(taglist 0x%lx)\n",&layertags
));
1395 w
->WLayer
= CreateUpfrontLayerTagList( &w
->WScreen
->LayerInfo
,
1396 w
->WScreen
->RastPort
.BitMap
,
1399 w
->LeftEdge
+ w
->Width
- 1,
1400 w
->TopEdge
+ w
->Height
- 1,
1402 (struct TagItem
*)&layertags
);
1405 struct TagItem lay_tags
[] =
1407 {LA_Hook
, (IPTR
)backfillhook
},
1408 {LA_Priority
, (layerflags
& LAYERBACKDROP
) ? BACKDROPPRIORITY
: UPFRONTPRIORITY
},
1409 {LA_Shape
, (IPTR
)shape
},
1410 {LA_ShapeHook
, (IPTR
)shapehook
},
1411 {LA_SuperBitMap
, (IPTR
)SuperBitMap
},
1412 {LA_ChildOf
, (IPTR
)parent
},
1413 {LA_Visible
, (ULONG
)visible
},
1417 w
->WLayer
= CreateLayerTagList(&w
->WScreen
->LayerInfo
,
1418 w
->WScreen
->RastPort
.BitMap
,
1421 w
->RelLeftEdge
+ w
->Width
- 1,
1422 w
->RelTopEdge
+ w
->Height
- 1,
1428 /* Install the BorderRPort here! see GZZ window above */
1429 if (NULL
!= w
->WLayer
)
1432 I am installing a totally new RastPort here so window and frame can
1433 have different fonts etc.
1435 w
->BorderRPort
= AllocMem(sizeof(struct RastPort
), MEMF_ANY
);
1439 InitRastPort(w
->BorderRPort
);
1440 w
->BorderRPort
->Layer
= w
->WLayer
;
1441 w
->BorderRPort
->BitMap
= w
->WLayer
->rp
->BitMap
;
1445 /* no memory for RastPort! Simply close the window */
1446 intui_CloseWindow(w
, IntuitionBase
);
1447 msg
->success
= FALSE
;
1448 // UnlockLayers(&w->WScreen->LayerInfo);
1449 ReturnVoid("intui_OpenWindow(No BorderRPort)");
1454 D(bug("Layer created: %p\n", w
->WLayer
));
1455 D(bug("Window created: %p\n", w
));
1457 /* common code for GZZ and regular windows */
1462 if ((layerflags
& LAYERBACKDROP
) && (w
->WScreen
->Flags
& SHOWTITLE
))
1465 struct Layer
*blayer
;
1467 /* make sure the screen titlebar is in front of all user created */
1468 /* backdrop windows */
1470 blayer
= w
->WScreen
->BarLayer
;
1473 if (GetPrivScreen(w
->WScreen
)->SpecialFlags
& (SF_InvisibleBar
|SF_AppearingBar
)) blayer
= 0;
1476 if (blayer
) MoveLayerInFrontOf(blayer
,w
->WLayer
);
1478 D(bug("move screen bar layer in front of window backdrop layer\n"));
1480 /* backdrop window was created over screen barlayer, but it must be
1481 under the screen barlayer if screen has flag SHOWTITLE set */
1483 AROS_ATOMIC_AND(w
->WScreen
->Flags
, ~SHOWTITLE
);
1485 ShowTitle(w
->WScreen
, TRUE
);
1489 /* Layer gets pointer to the window */
1490 WLAYER(w
) = w
->WLayer
;
1492 CheckLayers(w
->WScreen
,IntuitionBase
);
1494 // UnlockLayers(&w->WScreen->LayerInfo);
1497 w
->WLayer
->Window
= (APTR
)w
;
1499 /* Window needs a rastport */
1500 w
->RPort
= w
->WLayer
->rp
;
1502 /* installation of the correct BorderRPort already happened above !! */
1504 if (CreateWinSysGadgets(w
, IntuitionBase
))
1508 lock
= LockIBase (0);
1510 /* insert new window into parent/descendant list
1512 ** before: parent win xyz
1516 ** descendant win abc
1518 ** after: parent win xyz
1525 ** descendant win abc
1530 struct Window
*parent
, *descendant_of_parent
;
1532 parent
= IntuitionBase
->ActiveWindow
;
1533 if (!parent
) parent
= w
->WScreen
->FirstWindow
;
1536 descendant_of_parent
= parent
->Descendant
;
1537 parent
->Descendant
= w
;
1538 if (descendant_of_parent
) descendant_of_parent
->Parent
= w
;
1542 descendant_of_parent
= NULL
;
1545 w
->Descendant
= descendant_of_parent
;
1550 w
->NextWindow
= w
->WScreen
->FirstWindow
;
1551 w
->WScreen
->FirstWindow
= w
;
1553 w
->WindowPort
= GetPrivIBase(IntuitionBase
)->IntuiReplyPort
;
1557 AddResourceToList(w
, RESOURCE_WINDOW
, IntuitionBase
);
1559 if (w
->Flags
& WFLG_ACTIVATE
)
1565 RefreshWindowFrame(w
);
1568 msg
->success
= TRUE
;
1569 ReturnVoid("int_openwindow");
1573 //int_closewindow(w, IntuitionBase);
1575 } /* if (layer created) */
1577 // UnlockLayers(&w->WScreen->LayerInfo);
1580 D(bug("int_openwindow(General failure)"));
1582 msg
->success
= FALSE
;
1583 ReturnVoid("int_openwindow");