2 Copyright 1999, David Le Corfec.
3 Copyright 2002-2006, The AROS Development Team.
8 #include <exec/types.h>
9 #include <exec/memory.h>
13 #include <intuition/imageclass.h>
14 #include <intuition/icclass.h>
15 #include <intuition/gadgetclass.h>
16 #include <clib/alib_protos.h>
17 #include <graphics/gfxmacros.h>
18 #include <proto/exec.h>
19 #include <proto/intuition.h>
20 #include <proto/utility.h>
21 #include <proto/graphics.h>
22 #include <proto/commodities.h>
23 #include <proto/layers.h>
24 #include <proto/gadtools.h>
25 #include <proto/muimaster.h>
27 #define MUI_OBSOLETE /* for the obsolete menu stuff */
31 #include "classes/window.h"
32 #include "classes/area.h"
35 #include "dragndrop.h"
37 #include "muimaster_intern.h"
42 extern struct Library
*MUIMasterBase
;
44 static const int __version
= 1;
45 static const int __revision
= 1;
47 #define IM(x) ((struct Image*)(x))
48 #define G(x) ((struct Gadget*)(x))
49 #define GADGETID(x) (((struct Gadget*)(x))->GadgetID)
51 /* this is for the cycle list */
58 /* For the gadget ids */
65 struct MUI_ImageSpec_intern
;
69 struct MUI_RenderInfo wd_RenderInfo
;
70 struct MUI_MinMax wd_MinMax
;
71 struct IBox wd_AltDim
; /* zoomed dimensions */
72 BOOL wd_ZoomGadget
; /* enable/disable zoomgadget (altdim stuff) */
73 APTR wd_MemoryPool
; /* for nodes and stuff to deallocate at OM_DISPOSE */
74 struct MinList wd_CycleChain
; /* objects activated with tab */
75 struct MinList wd_EHList
; /* event handlers */
76 struct MinList wd_CCList
; /* control chars */
77 struct MinList wd_IDList
; /* gadget ids */
78 ULONG wd_Events
; /* events received */
79 ULONG wd_CrtFlags
; /* window creation flags, see below */
80 Object
*wd_ActiveObject
; /* the active object */
81 Object
*wd_OldActive
; /* active object before window was closed */
82 APTR wd_DefaultObject
;
85 STRPTR wd_ScreenTitle
;
86 LONG wd_Height
; /* Current dimensions */
90 LONG wd_ReqHeight
; /* given by programmer */
92 APTR wd_RootObject
; /* unique child */
93 ULONG wd_Flags
; /* various status flags */
94 struct MUI_ImageSpec_intern
*wd_Background
;
95 ULONG wd_DisabledKeys
;
96 BOOL wd_NoMenus
; /* MUIA_Window_NoMenus */
98 Object
*wd_DragObject
; /* the object which is being dragged */
99 struct Window
*wd_DropWindow
; /* the destination window, for faster access */
100 Object
*wd_DropObject
; /* the destination object */
101 struct DragNDrop
*wd_dnd
;
102 struct MUI_DragImage
*wd_DragImage
;
104 Object
*wd_Menustrip
; /* The menustrip object which is actually is used (either apps or windows or NULL) */
105 Object
* wd_ChildMenustrip
; /* If window has an own Menustrip */
106 struct Menu
*wd_Menu
; /* the intuition menustrip */
110 Object
*wd_DownButton
;
112 Object
*wd_HorizProp
;
113 Object
*wd_LeftButton
;
114 Object
*wd_RightButton
;
115 Object
*wd_RefWindow
;
117 Object
*wd_HelpObject
;
121 struct Screen
*wd_UserScreen
;
122 STRPTR wd_UserPublicScreen
;
123 LONG wd_XStore
; /*store MUIV_Window_LeftEdge_Centered Tags etc
124 because wd_X is overwritten by a value in CalcDimension
125 Popup windows work ok on AmiGG when main window is move
130 #ifndef WFLG_SIZEGADGET
132 #define WFLG_CLOSEGADGET (1<<0) /* has close gadget */
133 #define WFLG_SIZEGADGET (1<<1) /* has size gadget */
134 #define WFLG_BACKDROP (1<<2) /* is backdrop window */
135 #define WFLG_BORDERLESS (1<<3) /* has no borders */
136 #define WFLG_DEPTHGADGET (1<<4) /* has depth gadget */
137 #define WFLG_DRAGBAR (1<<5) /* is draggable */
138 #define WFLG_SIZEBRIGHT (1<<6) /* size gadget is in right border */
143 #define MUIWF_OPENED (1<<0) /* window currently opened */
144 #define MUIWF_HIDDEN (1<<1) /* window currently iconified */
145 #define MUIWF_ACTIVE (1<<2) /* window currently active */
146 #define MUIWF_RESIZING (1<<4) /* window currently resizing, for simple refresh */
147 #define MUIWF_DONTACTIVATE (1<<7) /* do not activate the window when opening */
148 #define MUIWF_USERIGHTSCROLLER (1<<8) /* window should have a right scroller */
149 #define MUIWF_USEBOTTOMSCROLLER (1<<9) /* window should have a bottom scroller */
150 #define MUIWF_ERASEAREA (1<<10) /* Erase area after a window resize */
151 #define MUIWF_ISAPPWINDOW (1<<11) /* Is an app window (user can drop icons on it) */
152 #define MUIWF_ISSUBWINDOW (1<<12) /* Dont get automatically disposed with app */
153 #define MUIWF_BUBBLEMODE (1<<13) /* Quick bubble mode. Bubbles appear quick when moving */
154 #define MUIWF_OPENONUNHIDE (1<<14) /* Open the window when unhiding */
155 #define MUIWF_SCREENLOCKED (1<<15) /* A pub screen was locked in SetupRenderInfo. Unlock it in CleanupRenderInfo! */
156 #define MUIWF_OBJECTGOACTIVESENT (1<<16) /* A MUIM_GoActive msg was sent to window's active object */
158 #define BUBBLEHELP_TICKER_FIRST 10
159 #define BUBBLEHELP_TICKER_LATER 3
166 struct MUI_NotifyData mnd
;
167 struct MUI_WindowData mwd
;
170 #define muiWindowData(obj) (&(((struct __dummyXFC3__ *)(obj))->mwd))
172 static ULONG
DoHalfshineGun(ULONG a
, ULONG b
)
174 ULONG val
= ((((a
)>>24) + 3 * ((b
)>>24)) / 4);
175 val
= val
+ (val
<<8) + (val
<<16) + (val
<<24);
179 static ULONG
DoHalfshadowGun(ULONG a
, ULONG b
)
181 ULONG val
= ((((a
)>>24) + 5 * ((b
)>>24)) / 6);
182 val
= val
+ (val
<<8) + (val
<<16) + (val
<<24);
186 static Object
*CreateSysimage(struct DrawInfo
*dri
, ULONG which
)
188 return NewObject(NULL
, "sysiclass",
189 SYSIA_DrawInfo
, (IPTR
)dri
,
194 static void EnqueueByPriAndAddress(struct List
*list
, struct Node
*node
)
196 struct Node
*scannode
;
198 /* Sort by priority and by node address, so that a
199 "remove - modify - enqueue" sequence will re-add
200 the node at the same place in the list it was
203 ForeachNode(list
, scannode
)
205 if (((struct Node
*)node
)->ln_Pri
> scannode
->ln_Pri
) break;
206 if (((struct Node
*)node
)->ln_Pri
== scannode
->ln_Pri
)
208 if ((IPTR
)node
> (IPTR
)scannode
) break;
212 Insert(list
, (struct Node
*)node
, scannode
->ln_Pred
);
216 static BOOL
SetupRenderInfo(Object
*obj
, struct MUI_WindowData
*data
, struct MUI_RenderInfo
*mri
)
218 ULONG rgbtable
[3 * 3];
222 screenmode
=muiGlobalInfo(obj
)->mgi_Prefs
->screenmodeid
;
224 if (screenmode
!= -1)
226 if (muiGlobalInfo(obj
)->mgi_Prefs
->screenaddress
)
227 data
->wd_UserScreen
=muiGlobalInfo(obj
)->mgi_Prefs
->screenaddress
;
229 data
->wd_UserScreen
= OpenScreenTags (
234 SA_DisplayID
,screenmode
,
236 SA_FullPalette
, TRUE
,
237 SA_LikeWorkbench
,TRUE
,
240 muiGlobalInfo(obj
)->mgi_Prefs
->screenaddress
=data
->wd_UserScreen
; // so screen is open only once
244 if (data
->wd_UserScreen
)
246 mri
->mri_Screen
= data
->wd_UserScreen
;
250 if (!(mri
->mri_Screen
= LockPubScreen(data
->wd_UserPublicScreen
)))
252 if (!(mri
->mri_Screen
= LockPubScreen(NULL
)))
258 data
->wd_Flags
|= MUIWF_SCREENLOCKED
;
261 if (!(mri
->mri_DrawInfo
= GetScreenDrawInfo(mri
->mri_Screen
)))
263 if (data
->wd_Flags
& MUIWF_SCREENLOCKED
)
265 UnlockPubScreen(NULL
,mri
->mri_Screen
);
266 data
->wd_Flags
&= ~MUIWF_SCREENLOCKED
;
271 mri
->mri_Colormap
= mri
->mri_Screen
->ViewPort
.ColorMap
;
272 mri
->mri_ScreenWidth
= mri
->mri_Screen
->Width
;
273 mri
->mri_ScreenHeight
= mri
->mri_Screen
->Height
;
275 if (mri
->mri_ScreenWidth
/ mri
->mri_ScreenHeight
< 2)
277 mri
->mri_Flags
|= MUIMRI_THINFRAMES
;
280 if (GetBitMapAttr(mri
->mri_Screen
->RastPort
.BitMap
, BMA_DEPTH
) >= 15)
282 mri
->mri_Flags
|= MUIMRI_TRUECOLOR
;
285 mri
->mri_PensStorage
[MPEN_SHINE
] = mri
->mri_DrawInfo
->dri_Pens
[SHINEPEN
];
286 mri
->mri_PensStorage
[MPEN_BACKGROUND
] = mri
->mri_DrawInfo
->dri_Pens
[BACKGROUNDPEN
];
287 mri
->mri_PensStorage
[MPEN_SHADOW
] = mri
->mri_DrawInfo
->dri_Pens
[SHADOWPEN
];
288 mri
->mri_PensStorage
[MPEN_TEXT
] = mri
->mri_DrawInfo
->dri_Pens
[TEXTPEN
];
289 mri
->mri_PensStorage
[MPEN_FILL
] = mri
->mri_DrawInfo
->dri_Pens
[FILLPEN
];
291 GetRGB32(mri
->mri_Colormap
, mri
->mri_DrawInfo
->dri_Pens
[SHINEPEN
], 1, rgbtable
);
292 GetRGB32(mri
->mri_Colormap
, mri
->mri_DrawInfo
->dri_Pens
[BACKGROUNDPEN
], 1, rgbtable
+3);
293 GetRGB32(mri
->mri_Colormap
, mri
->mri_DrawInfo
->dri_Pens
[SHADOWPEN
], 1, rgbtable
+6);
295 mri
->mri_PensStorage
[MPEN_HALFSHINE
] = ObtainBestPenA
298 DoHalfshineGun(rgbtable
[0], rgbtable
[3]),
299 DoHalfshineGun(rgbtable
[1], rgbtable
[4]),
300 DoHalfshineGun(rgbtable
[2], rgbtable
[5]), NULL
303 mri
->mri_PensStorage
[MPEN_HALFSHADOW
] = ObtainBestPenA
306 DoHalfshadowGun(rgbtable
[6], rgbtable
[3]),
307 DoHalfshadowGun(rgbtable
[7], rgbtable
[4]),
308 DoHalfshadowGun(rgbtable
[8], rgbtable
[5]), NULL
311 /* I'm really not sure that MUI does this for MPEN_MARK, but it seems mostly acceptable -dlc */
312 mri
->mri_PensStorage
[MPEN_MARK
] = ObtainBestPenA
314 mri
->mri_Colormap
, 0xf4f4f4f4, 0xb5b5b5b5, 0x8b8b8b8b, NULL
317 mri
->mri_Pens
= mri
->mri_PensStorage
;
319 for (i
= 0; i
< -MUIV_Font_NegCount
; i
++)
321 mri
->mri_Fonts
[i
] = NULL
;
324 if (data
->wd_Flags
& MUIWF_USEBOTTOMSCROLLER
)
326 mri
->mri_LeftImage
= CreateSysimage(mri
->mri_DrawInfo
, LEFTIMAGE
);
327 mri
->mri_RightImage
= CreateSysimage(mri
->mri_DrawInfo
, RIGHTIMAGE
);
331 mri
->mri_LeftImage
= mri
->mri_RightImage
= NULL
;
334 if (data
->wd_Flags
& MUIWF_USERIGHTSCROLLER
)
336 mri
->mri_UpImage
= CreateSysimage(mri
->mri_DrawInfo
, UPIMAGE
);
337 mri
->mri_DownImage
= CreateSysimage(mri
->mri_DrawInfo
, DOWNIMAGE
);
341 mri
->mri_UpImage
= mri
->mri_DownImage
= NULL
;
344 if ((data
->wd_Flags
& MUIWF_USEBOTTOMSCROLLER
) ||
345 (data
->wd_Flags
& MUIWF_USERIGHTSCROLLER
))
346 mri
->mri_SizeImage
= CreateSysimage(mri
->mri_DrawInfo
, SIZEIMAGE
);
348 mri
->mri_SizeImage
= NULL
;
350 if (data
->wd_CrtFlags
& WFLG_BORDERLESS
)
352 /* Infact borderless windows could also have borders (if they have a window title e.g. but
353 since they look ugly anywhy we ignore it for now */
354 mri
->mri_BorderLeft
= 0;
355 mri
->mri_BorderRight
= 0;
356 mri
->mri_BorderTop
= 0;
357 mri
->mri_BorderBottom
= 0;
361 mri
->mri_BorderLeft
= mri
->mri_Screen
->WBorLeft
;
362 mri
->mri_BorderTop
= mri
->mri_Screen
->WBorTop
+ mri
->mri_Screen
->Font
->ta_YSize
+ 1;
366 SYSIA_DrawInfo
, (IPTR
)mri
->mri_DrawInfo
,
367 SYSIA_Which
, SIZEIMAGE
,
372 GetAttr(IA_Height
,temp_obj
,&val
);
373 DisposeObject(temp_obj
);
374 mri
->mri_BorderBottom
= val
;
377 mri
->mri_BorderBottom
= mri
->mri_Screen
->WBorBottom
;
383 static void CleanupRenderInfo(struct MUI_WindowData
*data
, struct MUI_RenderInfo
*mri
)
387 if (mri
->mri_LeftImage
) {DisposeObject(mri
->mri_LeftImage
);mri
->mri_LeftImage
=NULL
;};
388 if (mri
->mri_RightImage
){DisposeObject(mri
->mri_RightImage
);mri
->mri_RightImage
=NULL
;};
389 if (mri
->mri_UpImage
) {DisposeObject(mri
->mri_UpImage
);mri
->mri_UpImage
=NULL
;};
390 if (mri
->mri_DownImage
) {DisposeObject(mri
->mri_DownImage
);mri
->mri_DownImage
=NULL
;};
391 if (mri
->mri_SizeImage
) {DisposeObject(mri
->mri_SizeImage
);mri
->mri_SizeImage
=NULL
;};
393 /* bug("CleanupRenderInfo\n"); */
394 for (i
= 0; i
< -MUIV_Font_NegCount
; i
++)
396 if (mri
->mri_Fonts
[i
])
398 /* bug("CleanupRenderInfo: closing font %p (%s/%d)\n", */
399 /* mri->mri_Fonts[i], mri->mri_Fonts[i]->tf_Message.mn_Node.ln_Name, */
400 /* mri->mri_Fonts[i]->tf_YSize); */
401 CloseFont(mri
->mri_Fonts
[i
]);
402 mri
->mri_Fonts
[i
] = NULL
;
405 ReleasePen(mri
->mri_Colormap
, mri
->mri_PensStorage
[MPEN_MARK
]);
406 ReleasePen(mri
->mri_Colormap
, mri
->mri_PensStorage
[MPEN_HALFSHADOW
]);
407 ReleasePen(mri
->mri_Colormap
, mri
->mri_PensStorage
[MPEN_HALFSHINE
]);
408 FreeScreenDrawInfo(mri
->mri_Screen
, mri
->mri_DrawInfo
);
409 mri
->mri_DrawInfo
= NULL
;
411 if (data
->wd_UserScreen
)
413 CloseScreen(mri
->mri_Screen
);
417 if (data
->wd_Flags
& MUIWF_SCREENLOCKED
)
419 UnlockPubScreen(NULL
, mri
->mri_Screen
);
420 data
->wd_Flags
&= ~MUIWF_SCREENLOCKED
;
422 mri
->mri_Screen
= NULL
;
425 static void ShowRenderInfo(struct MUI_RenderInfo
*mri
)
427 if (mri
->mri_BufferBM
)
429 mri
->mri_RastPort
= &mri
->mri_BufferRP
;
433 mri
->mri_RastPort
= mri
->mri_Window
->RPort
;
437 static void HideRenderInfo(struct MUI_RenderInfo
*mri
)
439 mri
->mri_RastPort
= NULL
;
442 static ULONG
GetDefaultEvents (void)
444 return IDCMP_NEWSIZE
| IDCMP_REFRESHWINDOW
445 | IDCMP_MOUSEBUTTONS
| IDCMP_MOUSEMOVE
| IDCMP_MENUPICK
446 | IDCMP_CLOSEWINDOW
| IDCMP_RAWKEY
| IDCMP_INTUITICKS
447 | IDCMP_ACTIVEWINDOW
| IDCMP_INACTIVEWINDOW
;
450 static void ChangeEvents (struct MUI_WindowData
*data
, ULONG new_events
)
453 struct MUI_EventHandlerNode
*ehn
;
454 ULONG old_events
= data
->wd_Events
;
456 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
458 ehn
= (struct MUI_EventHandlerNode
*)mn
;
459 new_events
|= ehn
->ehn_Events
;
462 /* sba: kill the IDCMP_VANILLAKEY flag. MUI doesn't do this but programs
463 ** which use this will behave different if they request for this flag
466 new_events
&= ~IDCMP_VANILLAKEY
;
468 data
->wd_Events
= new_events
;
469 if ((old_events
!= new_events
) && (data
->wd_Flags
& MUIWF_OPENED
))
471 ModifyIDCMP(data
->wd_RenderInfo
.mri_Window
, new_events
);
475 static void CalcWindowPosition(Object
*obj
, struct MUI_WindowData
*data
);
476 static void CreateWindowScrollbars(Object
*obj
, struct MUI_WindowData
*data
);
477 static void CalcAltDimensions(Object
*obj
, struct MUI_WindowData
*data
);
478 static void UndisplayWindow(Object
*obj
, struct MUI_WindowData
*data
);
479 static struct ObjNode
*FindObjNode(struct MinList
*list
, Object
*obj
);
481 static BOOL
DisplayWindow(Object
*obj
, struct MUI_WindowData
*data
)
484 ULONG flags
= data
->wd_CrtFlags
;
488 struct Menu
*menu
= NULL
;
489 struct NewMenu
*newmenu
= NULL
;
492 if (!(data
->wd_Flags
& MUIWF_DONTACTIVATE
))
494 flags
|= WFLG_ACTIVATE
;
499 data
->wd_MinMax
.MinHeight
== data
->wd_MinMax
.MaxHeight
500 && data
->wd_MinMax
.MinWidth
== data
->wd_MinMax
.MaxWidth
502 flags
&= ~WFLG_SIZEGADGET
;
504 if (!(flags
& WFLG_SIZEBRIGHT
))
505 flags
|= WFLG_SIZEBBOTTOM
;
507 CalcWindowPosition(obj
, data
);
509 if ((visinfo
= GetVisualInfoA(data
->wd_RenderInfo
.mri_Screen
,NULL
)))
511 if (data
->wd_Menustrip
)
513 get(data
->wd_Menustrip
,MUIA_Menuitem_NewMenu
,&newmenu
);
516 if ((menu
= CreateMenusA(newmenu
,NULL
)))
518 struct TagItem tags
[] =
520 { GTMN_NewLookMenus
, TRUE
},
521 { TAG_DONE
, (IPTR
)NULL
}
523 LayoutMenusA(menu
, visinfo
, tags
);
527 FreeVisualInfo(visinfo
);
530 CreateWindowScrollbars(obj
, data
);
531 CalcAltDimensions(obj
, data
);
532 altdims
= data
->wd_AltDim
;
533 /* hack to account for border size, as we only know the innersize and must give
536 altdims
.Width
+= data
->wd_RenderInfo
.mri_Screen
->WBorLeft
+ data
->wd_RenderInfo
.mri_Screen
->WBorRight
;
537 altdims
.Height
+= data
->wd_RenderInfo
.mri_Screen
->WBorTop
+ data
->wd_RenderInfo
.mri_Screen
->WBorBottom
+
538 data
->wd_RenderInfo
.mri_DrawInfo
->dri_Font
->tf_YSize
+ 1;
540 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_redraw
== WINDOW_REDRAW_WITHOUT_CLEAR
)
541 backfill
= WA_BackFill
;
543 backfill
= TAG_IGNORE
;
545 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_refresh
== WINDOW_REFRESH_SMART
)
546 flags
&= ~WFLG_SIMPLE_REFRESH
;
547 set(_app(obj
),MUIA_Application_SearchWinId
,data
->wd_ID
);
548 struct windowpos
*winp
=0;
549 get(_app(obj
),MUIA_Application_GetWinPos
,&winp
);
552 if (data
->wd_RenderInfo
.mri_ScreenWidth
> (data
->wd_X
+ data
->wd_Width
))
555 data
->wd_Width
=winp
->w1
;
557 if (data
->wd_RenderInfo
.mri_ScreenHeight
> (data
->wd_Y
+ data
->wd_Height
))
560 data
->wd_Height
=winp
->h1
;
569 WA_Left
, (IPTR
) data
->wd_X
,
570 WA_Top
, (IPTR
) data
->wd_Y
,
571 WA_Flags
, (IPTR
) flags
,
574 TAG_IGNORE
, (IPTR
) data
->wd_Title
,
575 data
->wd_ScreenTitle
?
577 TAG_IGNORE
, (IPTR
) data
->wd_ScreenTitle
,
578 WA_CustomScreen
, (IPTR
) data
->wd_RenderInfo
.mri_Screen
,
579 WA_InnerWidth
, (IPTR
) data
->wd_Width
,
580 WA_InnerHeight
, (IPTR
) data
->wd_Height
,
581 WA_AutoAdjust
, (IPTR
) TRUE
,
582 WA_NewLookMenus
, (IPTR
) TRUE
,
585 TAG_IGNORE
, (IPTR
) TRUE
,
586 WA_Gadgets
, (IPTR
) (data
->wd_VertProp
? data
->wd_VertProp
: data
->wd_HorizProp
),
587 data
->wd_ZoomGadget
?
589 TAG_IGNORE
, (IPTR
) &altdims
,
590 backfill
, (IPTR
) LAYERS_NOBACKFILL
,
596 int hborders
= win
->BorderLeft
+ win
->BorderRight
;
597 int vborders
= win
->BorderTop
+ win
->BorderBottom
;
599 /* recalc window size (which will hopefully equal our requested size) */
600 data
->wd_Width
= win
->GZZWidth
;
601 data
->wd_Height
= win
->GZZHeight
;
603 /* set window limits according to window contents */
606 win
, data
->wd_MinMax
.MinWidth
+ hborders
,
607 data
->wd_MinMax
.MinHeight
+ vborders
,
608 data
->wd_MinMax
.MaxWidth
+ hborders
,
609 data
->wd_MinMax
.MaxHeight
+ vborders
612 win
->UserData
= (char*)data
->wd_RenderInfo
.mri_WindowObject
;
613 win
->UserPort
= muiGlobalInfo(obj
)->mgi_WindowsPort
; /* Same port for all windows */
614 ModifyIDCMP(win
, data
->wd_Events
);
616 data
->wd_RenderInfo
.mri_Window
= win
;
617 data
->wd_RenderInfo
.mri_VertProp
= data
->wd_VertProp
;
618 data
->wd_RenderInfo
.mri_HorizProp
= data
->wd_HorizProp
;
619 SetDrMd(win
->RPort
,JAM1
); //text is draw wrong in toolbarclass if not set
623 data
->wd_Menu
= menu
;
624 SetMenuStrip(win
,menu
);
627 if (flags
& WFLG_ACTIVATE
)
629 data
->wd_Flags
|= MUIWF_ACTIVE
;
635 if (menu
) FreeMenus(menu
);
636 UndisplayWindow(obj
, data
);
642 static void UndisplayWindow(Object
*obj
, struct MUI_WindowData
*data
)
644 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
645 if ((data
->wd_XStore
>= 0) && (data
->wd_YStore
>= 0))
647 DoMethod(obj
,MUIM_Window_Snapshot
,0);
650 data
->wd_RenderInfo
.mri_Window
= NULL
;
651 data
->wd_RenderInfo
.mri_VertProp
= NULL
;
652 data
->wd_RenderInfo
.mri_HorizProp
= NULL
;
654 data
->wd_Flags
&= ~MUIWF_ACTIVE
;
658 /* store position and size */
659 if (data
->wd_XStore
>=0)
660 data
->wd_X
= win
->LeftEdge
;
662 data
->wd_X
= data
->wd_XStore
;
663 if (data
->wd_YStore
>=0)
664 data
->wd_Y
= win
->TopEdge
;
666 data
->wd_Y
= data
->wd_YStore
;
667 data
->wd_Width
= win
->GZZWidth
;
668 data
->wd_Height
= win
->GZZHeight
;
673 FreeMenus(data
->wd_Menu
);
674 data
->wd_Menu
= NULL
;
679 struct IntuiMessage
*msg
, *succ
;
681 /* remove all messages pending for this window */
685 msg
= (struct IntuiMessage
*)win
->UserPort
->mp_MsgList
.lh_Head
;
686 (succ
= (struct IntuiMessage
*)msg
->ExecMessage
.mn_Node
.ln_Succ
);
690 if (msg
->IDCMPWindow
== win
)
692 Remove((struct Node
*)msg
);
693 ReplyMsg((struct Message
*)msg
);
696 win
->UserPort
= NULL
;
701 /* D(bug("before CloseWindow\n")); */
703 /* D(bug("after CloseWindow\n")); */
706 #define DISPOSEGADGET(x) \
709 DoMethod(obj, MUIM_Window_FreeGadgetID, ((struct Gadget*)x)->GadgetID);\
714 DISPOSEGADGET(data
->wd_VertProp
);
715 DISPOSEGADGET(data
->wd_UpButton
);
716 DISPOSEGADGET(data
->wd_DownButton
);
717 DISPOSEGADGET(data
->wd_HorizProp
);
718 DISPOSEGADGET(data
->wd_LeftButton
);
719 DISPOSEGADGET(data
->wd_RightButton
);
724 /* Initialize data->wd_X and data->wd_Y for DisplayWindow */
725 /* FIXME 20030817: needs some fixing, seems not fully implemented */
726 static void CalcWindowPosition(Object
*obj
, struct MUI_WindowData
*data
)
728 data
->wd_XStore
= data
->wd_X
;
729 data
->wd_YStore
= data
->wd_Y
;
730 if (NULL
== data
->wd_RefWindow
)
732 /* The following calculations are not very correct, the size and dragbar
733 ** are ignored also the current overscan view */
734 if (data
->wd_X
== MUIV_Window_LeftEdge_Centered
)
736 data
->wd_X
= (data
->wd_RenderInfo
.mri_Screen
->Width
- data
->wd_Width
)/2;
738 else if (data
->wd_X
== MUIV_Window_LeftEdge_Moused
)
740 data
->wd_X
= data
->wd_RenderInfo
.mri_Screen
->MouseX
;
743 if (data
->wd_Y
== MUIV_Window_TopEdge_Centered
)
745 data
->wd_Y
= (data
->wd_RenderInfo
.mri_Screen
->Height
- data
->wd_Height
)/2;
747 else if (data
->wd_Y
== MUIV_Window_TopEdge_Moused
)
749 data
->wd_Y
= data
->wd_RenderInfo
.mri_Screen
->MouseY
;
751 else if (data
->wd_Y
<= MUIV_Window_TopEdge_Delta(0))
753 data
->wd_Y
= data
->wd_RenderInfo
.mri_Screen
->BarHeight
+ 1
754 + MUIV_Window_TopEdge_Delta(0) - data
->wd_Y
;
762 get(data
->wd_RefWindow
, MUIA_Window_Width
, &w
);
763 get(data
->wd_RefWindow
, MUIA_Window_LeftEdge
, &x
);
765 if (data
->wd_X
== MUIV_Window_LeftEdge_Centered
)
767 data
->wd_X
= x
+ (w
- data
->wd_Width
)/2;
774 get(data
->wd_RefWindow
, MUIA_Window_Height
, &h
);
775 get(data
->wd_RefWindow
, MUIA_Window_TopEdge
, &y
);
777 if (data
->wd_Y
== MUIV_Window_TopEdge_Centered
)
779 /* D(bug("y=%ld, h=%ld, wdh=%ld\n", y, h, data->wd_Height)); */
780 data
->wd_Y
= y
+ (h
- data
->wd_Height
)/2;
782 else if (data
->wd_Y
<= MUIV_Window_TopEdge_Delta(0))
784 /* ??? surely incorrect implementation */
785 data
->wd_Y
= y
+ 1 + MUIV_Window_TopEdge_Delta(0) - data
->wd_Y
;
794 /* Initialize data->wd_AltDim for DisplayWindow */
795 static void CalcAltDimensions(Object
*obj
, struct MUI_WindowData
*data
)
797 /* Calculate alternate (zoomed) dimensions.
799 if (data
->wd_AltDim
.Top
== MUIV_Window_AltTopEdge_NoChange
)
800 data
->wd_AltDim
.Top
= ~0;
801 else if (data
->wd_AltDim
.Top
== MUIV_Window_AltTopEdge_Centered
)
802 data
->wd_AltDim
.Top
= (data
->wd_RenderInfo
.mri_Screen
->Height
- data
->wd_Height
)/2;
803 else if (data
->wd_AltDim
.Top
== MUIV_Window_AltTopEdge_Moused
)
804 /* ? */ data
->wd_AltDim
.Top
= ~0;
806 if (data
->wd_AltDim
.Left
== MUIV_Window_AltLeftEdge_NoChange
)
807 data
->wd_AltDim
.Left
= ~0;
808 else if (data
->wd_AltDim
.Left
== MUIV_Window_AltLeftEdge_Centered
)
809 data
->wd_AltDim
.Left
= (data
->wd_RenderInfo
.mri_Screen
->Width
- data
->wd_Width
)/2;
810 else if (data
->wd_AltDim
.Left
== MUIV_Window_AltLeftEdge_Moused
)
811 /* ? */ data
->wd_AltDim
.Left
= ~0;
817 MUIV_Window_AltWidth_MinMax(100),
818 data
->wd_AltDim
.Width
,
819 MUIV_Window_AltWidth_MinMax(0)
823 data
->wd_AltDim
.Width
= data
->wd_MinMax
.MinWidth
824 - data
->wd_AltDim
.Width
825 * (data
->wd_MinMax
.MaxWidth
- data
->wd_MinMax
.MinWidth
);
831 MUIV_Window_AltWidth_Screen(100),
832 data
->wd_AltDim
.Width
,
833 MUIV_Window_AltWidth_Screen(0)
837 data
->wd_AltDim
.Width
= data
->wd_RenderInfo
.mri_ScreenWidth
838 * (- (data
->wd_AltDim
.Width
+ 200)) / 100;
844 MUIV_Window_AltWidth_Visible(100),
845 data
->wd_AltDim
.Width
,
846 MUIV_Window_AltWidth_Visible(0)
850 data
->wd_AltDim
.Width
= data
->wd_RenderInfo
.mri_ScreenWidth
851 * (- (data
->wd_AltDim
.Width
+ 100)) / 100;
858 MUIV_Window_AltHeight_MinMax(100),
859 data
->wd_AltDim
.Height
,
860 MUIV_Window_AltHeight_MinMax(0)
864 data
->wd_AltDim
.Height
= data
->wd_MinMax
.MinHeight
865 - data
->wd_AltDim
.Height
866 * (data
->wd_MinMax
.MaxHeight
- data
->wd_MinMax
.MinHeight
);
872 MUIV_Window_AltHeight_Screen(100),
873 data
->wd_AltDim
.Height
,
874 MUIV_Window_AltHeight_Screen(0)
878 data
->wd_AltDim
.Height
= data
->wd_RenderInfo
.mri_ScreenHeight
879 * (- (data
->wd_AltDim
.Height
+ 200)) / 100;
885 MUIV_Window_AltHeight_Visible(100),
886 data
->wd_AltDim
.Height
,
887 MUIV_Window_AltHeight_Visible(0)
891 data
->wd_AltDim
.Height
= data
->wd_RenderInfo
.mri_ScreenHeight
892 * (- (data
->wd_AltDim
.Height
+ 100)) / 100;
895 data
->wd_AltDim
.Width
= CLAMP
897 data
->wd_AltDim
.Width
, data
->wd_MinMax
.MinWidth
,
898 data
->wd_MinMax
.MaxWidth
900 data
->wd_AltDim
.Height
= CLAMP
902 data
->wd_AltDim
.Height
, data
->wd_MinMax
.MinHeight
,
903 data
->wd_MinMax
.MaxHeight
908 /* Create horiz/vert window scrollbars for DisplayWindow */
909 static void CreateWindowScrollbars(Object
*obj
, struct MUI_WindowData
*data
)
911 struct MUI_RenderInfo
*mri
= &data
->wd_RenderInfo
;
912 Object
*firstgad
= NULL
;
913 Object
*prevgad
= NULL
;
916 /* Create the right border scrollers now if requested */
917 if (data
->wd_Flags
& MUIWF_USERIGHTSCROLLER
)
921 voffset
= IM(mri
->mri_DownImage
)->Width
/ 4;
923 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
924 firstgad
= prevgad
= data
->wd_VertProp
= NewObject
928 GA_RelRight
, 1 - (IM(mri
->mri_UpImage
)->Width
- voffset
),
929 GA_Top
, mri
->mri_BorderTop
+ 2,
930 GA_Width
, IM(mri
->mri_UpImage
)->Width
- voffset
* 2,
931 GA_RelHeight
, - (mri
->mri_BorderTop
+ 2)
932 - IM(mri
->mri_UpImage
)->Height
933 - IM(mri
->mri_DownImage
)->Height
934 - IM(mri
->mri_SizeImage
)->Height
- 2,
935 GA_RightBorder
, TRUE
,
937 PGA_Borderless
, TRUE
,
939 PGA_Freedom
, FREEVERT
,
943 ICA_TARGET
, ICTARGET_IDCMP
,
947 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
948 prevgad
= data
->wd_UpButton
= NewObject
950 NULL
, "buttongclass",
952 GA_Image
, (IPTR
)mri
->mri_UpImage
,
953 GA_RelRight
, 1 - IM(mri
->mri_UpImage
)->Width
,
954 GA_RelBottom
, 1 - IM(mri
->mri_UpImage
)->Height
955 - IM(mri
->mri_DownImage
)->Height
956 - IM(mri
->mri_SizeImage
)->Height
,
957 GA_RightBorder
, TRUE
,
958 GA_Previous
, (IPTR
)prevgad
,
960 ICA_TARGET
, ICTARGET_IDCMP
,
964 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
965 prevgad
= data
->wd_DownButton
= NewObject
967 NULL
, "buttongclass",
969 GA_Image
, (IPTR
)mri
->mri_DownImage
,
970 GA_RelRight
, 1 - IM(mri
->mri_DownImage
)->Width
,
971 GA_RelBottom
, 1 - IM(mri
->mri_DownImage
)->Height
972 - IM(mri
->mri_SizeImage
)->Height
,
973 GA_RightBorder
, TRUE
,
974 GA_Previous
, (IPTR
)prevgad
,
976 ICA_TARGET
, ICTARGET_IDCMP
,
979 } // if (data->wd_Flags & MUIWF_USERIGHTSCROLLER)
981 /* Create the bottom border scrollers now if requested */
982 if (data
->wd_Flags
& MUIWF_USEBOTTOMSCROLLER
)
986 hoffset
= IM(mri
->mri_RightImage
)->Height
/ 4;
988 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
989 prevgad
= data
->wd_HorizProp
= NewObject
993 GA_RelBottom
, 1 - (IM(mri
->mri_LeftImage
)->Height
- hoffset
),
994 GA_Left
, mri
->mri_BorderLeft
,
995 GA_Height
, IM(mri
->mri_LeftImage
)->Height
997 GA_RelWidth
, - (mri
->mri_BorderLeft
)
998 - IM(mri
->mri_LeftImage
)->Width
999 - IM(mri
->mri_RightImage
)->Width
1000 - IM(mri
->mri_SizeImage
)->Width
1002 GA_BottomBorder
, TRUE
,
1004 prevgad
? GA_Previous
: TAG_IGNORE
, (IPTR
)prevgad
,
1005 PGA_Borderless
, TRUE
,
1007 PGA_Freedom
, FREEHORIZ
,
1011 ICA_TARGET
, ICTARGET_IDCMP
,
1015 if (!firstgad
) firstgad
= prevgad
;
1017 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1018 prevgad
= data
->wd_LeftButton
= NewObject
1020 NULL
, "buttongclass",
1022 GA_Image
, (IPTR
)mri
->mri_LeftImage
,
1023 GA_RelRight
, 1 - IM(mri
->mri_LeftImage
)->Width
1024 - IM(mri
->mri_RightImage
)->Width
1025 - IM(mri
->mri_SizeImage
)->Width
,
1026 GA_RelBottom
, 1 - IM(mri
->mri_LeftImage
)->Height
,
1027 GA_BottomBorder
, TRUE
,
1028 GA_Previous
, (IPTR
)prevgad
,
1030 ICA_TARGET
, ICTARGET_IDCMP
,
1034 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1035 prevgad
= data
->wd_RightButton
= NewObject
1037 NULL
, "buttongclass",
1039 GA_Image
, (IPTR
)mri
->mri_RightImage
,
1040 GA_RelRight
, 1 - IM(mri
->mri_RightImage
)->Width
1041 - IM(mri
->mri_SizeImage
)->Width
,
1042 GA_RelBottom
, 1 - IM(mri
->mri_RightImage
)->Height
,
1043 GA_BottomBorder
, TRUE
,
1044 GA_Previous
, (IPTR
)prevgad
,
1046 ICA_TARGET
, ICTARGET_IDCMP
,
1048 } // if (data->wd_Flags & MUIWF_USEBOTTOMSCROLLER)
1051 /* return FALSE only if no resize (dx=dy=0) occured */
1052 static BOOL
WindowResize (struct MUI_WindowData
*data
)
1054 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
1055 int hborders
= win
->BorderLeft
+ win
->BorderRight
;
1056 int vborders
= win
->BorderTop
+ win
->BorderBottom
;
1057 WORD dx
= data
->wd_Width
- win
->Width
+ hborders
;
1058 WORD dy
= data
->wd_Height
- win
->Height
+ vborders
;
1060 /* D(bug("_zune_window_resize : dx=%d, dy=%d\n", dx, dy)); */
1061 SizeWindow(win
, dx
, dy
);
1063 /* The following WindowLimits() call doesn't really work because SizeWindow() is async */
1066 win
, data
->wd_MinMax
.MinWidth
+ hborders
,
1067 data
->wd_MinMax
.MinHeight
+ vborders
,
1068 data
->wd_MinMax
.MaxWidth
+ hborders
,
1069 data
->wd_MinMax
.MaxHeight
+ vborders
1075 static void KillHelpBubble(struct MUI_WindowData
*data
, Object
*obj
, BOOL kill_bubblemode
)
1077 if (data
->wd_HelpObject
)
1079 DoMethod(data
->wd_HelpObject
, MUIM_DeleteBubble
, (IPTR
)data
->wd_HelpBubble
);
1080 data
->wd_HelpObject
= NULL
;
1081 data
->wd_HelpBubble
= NULL
;
1084 if (kill_bubblemode
) data
->wd_Flags
&= ~MUIWF_BUBBLEMODE
;
1086 if (data
->wd_Flags
& MUIWF_BUBBLEMODE
)
1088 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_LATER
;
1092 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_FIRST
;
1099 typedef BOOL (*UNDERCHECK_FUNC
)(Object
*obj
);
1101 static BOOL
ShortHelpUnderPointerCheck(Object
*obj
)
1103 return muiAreaData(obj
)->mad_ShortHelp
? TRUE
: FALSE
;
1106 static Object
*ObjectUnderPointer(struct MUI_WindowData
*data
, Object
*obj
,
1107 LONG x
, LONG y
, UNDERCHECK_FUNC func
)
1111 struct MinList
*ChildList
;
1113 if (!(muiAreaData(obj
)->mad_Flags
& MADF_CANDRAW
))
1116 if (!(x
>= _left(obj
) && x
<= _right(obj
)
1117 && y
>= _top(obj
) && y
<= _bottom(obj
)))
1122 if (get(obj
, MUIA_Group_ChildList
, (IPTR
*)&(ChildList
)))
1124 cstate
= (Object
*)ChildList
->mlh_Head
;
1125 while ((child
= NextObject(&cstate
)))
1129 if ((x
>= _left(child
) && x
<= _right(child
)
1131 y
>= _top(child
) && y
<= _bottom(child
))
1133 (ret
= ObjectUnderPointer(data
, child
, x
, y
, func
)))
1140 if (!(*func
)(obj
)) return NULL
;
1145 static BOOL
ContextMenuUnderPointer(struct MUI_WindowData
*data
, Object
*obj
, LONG x
, LONG y
)
1149 struct MinList
*ChildList
= 0;
1151 if (!(x
>= _left(obj
) && x
<= _right(obj
)
1152 && y
>= _top(obj
) && y
<= _bottom(obj
)))
1157 if (get(obj
, MUIA_Group_ChildList
, (IPTR
*)&(ChildList
)) && (ChildList
!= 0))
1160 cstate
= (Object
*)ChildList
->mlh_Head
;
1161 while ((child
= NextObject(&cstate
)))
1163 if ((x
>= _left(child
) && x
<= _right(child
)
1165 y
>= _top(child
) && y
<= _bottom(child
))
1167 (ContextMenuUnderPointer(data
,child
,x
,y
)))
1172 if (!(muiAreaData(obj
)->mad_Flags
& MADF_CANDRAW
))
1174 if (!(muiAreaData(obj
)->mad_ContextMenu
))
1182 static void ActivateObject (struct MUI_WindowData
*data
)
1184 //bug("Window::ActivateObject (dummy) %08lx\n", data->wd_ActiveObject);
1185 // if (FindObjNode(&data->wd_CycleChain, data->wd_ActiveObject))
1186 // DoMethod(data->wd_ActiveObject, MUIM_GoActive);
1188 // data->wd_ActiveObject = NULL;
1189 //activate better string gadgets.Fix from Georg S On ML List
1190 if (FindObjNode(&data
->wd_CycleChain
, data
->wd_ActiveObject
))
1192 if (!(data
->wd_Flags
& MUIWF_OBJECTGOACTIVESENT
))
1194 data
->wd_Flags
|= MUIWF_OBJECTGOACTIVESENT
;
1195 DoMethod(data
->wd_ActiveObject
, MUIM_GoActive
);
1199 data
->wd_ActiveObject
= NULL
;
1205 static void HandleInputEvent(Object
*win
, struct MUI_WindowData
*data
,
1206 struct IntuiMessage
*event
);
1208 /* handle intuimessage while an object is being dragged
1209 * (reply imsg before returning)
1211 void HandleDragging (Object
*oWin
, struct MUI_WindowData
*data
,
1212 struct IntuiMessage
*imsg
)
1214 struct Window
*iWin
;
1215 int finish_drag
= 0;
1217 iWin
= imsg
->IDCMPWindow
;
1219 if (imsg
->Class
== IDCMP_MOUSEMOVE
)
1221 struct Layer
*layer
;
1222 layer
= WhichLayer(&iWin
->WScreen
->LayerInfo
, iWin
->LeftEdge
+ imsg
->MouseX
, iWin
->TopEdge
+ imsg
->MouseY
);
1224 if (data
->wd_DropObject
)
1227 WORD mousex
= imsg
->MouseX
+ iWin
->LeftEdge
- data
->wd_DropWindow
->LeftEdge
;
1228 WORD mousey
= imsg
->MouseY
+ iWin
->TopEdge
- data
->wd_DropWindow
->TopEdge
;
1230 wnd
= _window(data
->wd_DropObject
);
1233 mousex
< _left(data
->wd_DropObject
)
1234 || mousex
> _right(data
->wd_DropObject
)
1235 || mousey
< _top(data
->wd_DropObject
)
1236 || mousey
> _bottom(data
->wd_DropObject
)
1237 || layer
!= wnd
->WLayer
1240 /* We have left the object */
1241 UndrawDragNDrop(data
->wd_dnd
);
1242 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
,(IPTR
)data
->wd_DragObject
);
1243 data
->wd_DropObject
= NULL
;
1245 } /* if (data->wd_DropObject) */
1247 if (!data
->wd_DropObject
)
1249 Object
*dest_wnd
= NULL
;
1251 /* Find out if app has an openend window at this position */
1256 struct MinList
*ChildList
;
1258 get(_app(oWin
), MUIA_Application_WindowList
, (IPTR
*)&(ChildList
));
1259 cstate
= (Object
*)ChildList
->mlh_Head
;
1260 while ((child
= NextObject(&cstate
)))
1263 get(child
, MUIA_Window_Window
,&wnd
);
1266 if (wnd
->WLayer
== layer
)
1268 data
->wd_DropWindow
= wnd
;
1278 get(dest_wnd
, MUIA_Window_RootObject
, (IPTR
*)&root
);
1285 data
->wd_DropObject
= (Object
*) DoMethod
1287 root
, MUIM_DragQueryExtended
,
1288 (IPTR
) data
->wd_DragObject
,
1289 imsg
->MouseX
+ iWin
->LeftEdge
- data
->wd_DropWindow
->LeftEdge
,
1290 imsg
->MouseY
+ iWin
->TopEdge
- data
->wd_DropWindow
->TopEdge
1295 UndrawDragNDrop(data
->wd_dnd
);
1296 DoMethod(data
->wd_DropObject
, MUIM_DragBegin
,(IPTR
)data
->wd_DragObject
);
1299 } /* if (dest_wnd) */
1300 } /* if (!data->wd_DropObject) */
1302 if (data
->wd_DropObject
)
1310 data
->wd_DropObject
, MUIM_DragReport
,
1311 (IPTR
) data
->wd_DragObject
,
1312 imsg
->MouseX
+ iWin
->LeftEdge
- data
->wd_DropWindow
->LeftEdge
,
1313 imsg
->MouseY
+ iWin
->TopEdge
- data
->wd_DropWindow
->TopEdge
,update
1317 case MUIV_DragReport_Abort
:
1318 UndrawDragNDrop(data
->wd_dnd
);
1319 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
,(IPTR
)data
->wd_DragObject
);
1320 data
->wd_DropObject
= NULL
;
1324 case MUIV_DragReport_Continue
: break;
1325 case MUIV_DragReport_Lock
: break; /* NYI */
1326 case MUIV_DragReport_Refresh
:
1327 UndrawDragNDrop(data
->wd_dnd
);
1332 } /* if (data->wd_DropObject) */
1333 DrawDragNDrop(data
->wd_dnd
, imsg
->MouseX
+ iWin
->LeftEdge
, imsg
->MouseY
+ iWin
->TopEdge
);
1334 } /* if (imsg->Class == IDCMP_MOUSEMOVE) */
1336 if (imsg
->Class
== IDCMP_MOUSEBUTTONS
)
1338 if ((imsg
->Code
== MENUDOWN
) || (imsg
->Code
== SELECTUP
))
1340 if (imsg
->Code
== SELECTUP
&& data
->wd_DropObject
)
1342 UndrawDragNDrop(data
->wd_dnd
);
1343 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
, (IPTR
)data
->wd_DragObject
);
1346 data
->wd_DropObject
, MUIM_DragDrop
, (IPTR
)data
->wd_DragObject
,
1347 imsg
->MouseX
+ iWin
->LeftEdge
- data
->wd_DropWindow
->LeftEdge
,
1348 imsg
->MouseY
+ iWin
->TopEdge
- data
->wd_DropWindow
->TopEdge
1350 data
->wd_DropObject
= NULL
;
1352 else if (imsg
->Code
== SELECTUP
)
1354 DoMethod(data
->wd_DragObject
, MUIM_UnknownDropDestination
, imsg
);
1360 if (imsg
->Class
== IDCMP_CLOSEWINDOW
)
1365 UndrawDragNDrop(data
->wd_dnd
);
1366 if (data
->wd_DropObject
)
1368 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
,(IPTR
)data
->wd_DragObject
);
1369 data
->wd_DropObject
= NULL
;
1371 DeleteDragNDrop(data
->wd_dnd
);
1372 DoMethod(data
->wd_DragObject
,MUIM_DeleteDragImage
, (IPTR
)data
->wd_DragImage
);
1373 muiAreaData(data
->wd_DragObject
)->mad_Flags
&= ~MADF_DRAGGING
;
1374 data
->wd_DragImage
= NULL
;
1375 data
->wd_DragObject
= NULL
;
1376 data
->wd_DropWindow
= NULL
;
1377 data
->wd_dnd
= NULL
;
1378 /* stop listening to IDCMP_MOUSEMOVE */
1379 ChangeEvents(data
, GetDefaultEvents());
1381 ReplyMsg((struct Message
*)imsg
);
1384 /* Reply to imsg if handled */
1385 BOOL
HandleWindowEvent (Object
*oWin
, struct MUI_WindowData
*data
,
1386 struct IntuiMessage
*imsg
)
1388 struct Window
*iWin
;
1389 BOOL is_handled
= TRUE
;
1390 BOOL replied
= FALSE
;
1392 iWin
= imsg
->IDCMPWindow
;
1393 switch (imsg
->Class
)
1395 case IDCMP_ACTIVEWINDOW
:
1396 data
->wd_Flags
|= MUIWF_ACTIVE
;
1397 if (data
->wd_OldActive
)
1398 set(oWin
, MUIA_Window_ActiveObject
, data
->wd_OldActive
);
1399 set(oWin
, MUIA_Window_Activate
, TRUE
);
1400 is_handled
= FALSE
; /* forwardable to area event handlers */
1403 case IDCMP_INACTIVEWINDOW
:
1404 KillHelpBubble(data
, oWin
, TRUE
);
1405 if (data
->wd_ActiveObject
)
1407 data
->wd_OldActive
= data
->wd_ActiveObject
;
1408 set(oWin
, MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_None
);
1410 data
->wd_Flags
&= ~MUIWF_ACTIVE
;
1411 set(oWin
, MUIA_Window_Activate
, FALSE
);
1412 is_handled
= FALSE
; /* forwardable to area event handlers */
1416 ReplyMsg((struct Message
*)imsg
);
1420 int hborders
= iWin
->BorderLeft
+ iWin
->BorderRight
;
1421 int vborders
= iWin
->BorderTop
+ iWin
->BorderBottom
;
1423 /* set window limits according to window contents */
1426 data
->wd_MinMax
.MinWidth
+ hborders
,
1427 data
->wd_MinMax
.MinHeight
+ vborders
,
1428 data
->wd_MinMax
.MaxWidth
+ hborders
,
1429 data
->wd_MinMax
.MaxHeight
+ vborders
1433 if ((iWin
->GZZWidth
!= data
->wd_Width
) || (iWin
->GZZHeight
!= data
->wd_Height
))
1435 data
->wd_Width
= iWin
->GZZWidth
;
1436 data
->wd_Height
= iWin
->GZZHeight
;
1437 DoHideMethod(data
->wd_RootObject
);
1439 if (1) // why only simple refresh? was: if (data->wd_RenderInfo.mri_Window->Flags & WFLG_SIMPLE_REFRESH)
1441 data
->wd_Flags
|= MUIWF_RESIZING
;
1445 _width(data
->wd_RootObject
) = data
->wd_Width
;
1446 _height(data
->wd_RootObject
) = data
->wd_Height
;
1447 DoMethod(data
->wd_RootObject
, MUIM_Layout
);
1448 DoShowMethod(data
->wd_RootObject
);
1450 LONG left
,top
,width
,height
;
1452 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
1453 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
,
1454 width
= data
->wd_RenderInfo
.mri_Window
->Width
1455 - data
->wd_RenderInfo
.mri_Window
->BorderRight
- left
;
1456 height
= data
->wd_RenderInfo
.mri_Window
->Height
1457 - data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
1459 // D(bug("%d:zune_imspec_draw(%p) l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
1460 // __LINE__, data->wd_Background, left, top, width,
1461 // height, left, top));
1462 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
1463 left
, top
, width
, height
, left
, top
, 0);
1465 if (muiGlobalInfo(oWin
)->mgi_Prefs
->window_redraw
== WINDOW_REDRAW_WITHOUT_CLEAR
)
1466 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWOBJECT
);
1468 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWALL
);
1469 // but should only draw focus without using MUIM_GoActive !
1470 ActivateObject(data
);
1475 case IDCMP_REFRESHWINDOW
:
1476 ReplyMsg((struct Message
*)imsg
);
1478 if (data
->wd_Flags
& MUIWF_RESIZING
)
1480 //LONG left,top,right,bottom;
1481 if (MUI_BeginRefresh(&data
->wd_RenderInfo
, 0))
1483 MUI_EndRefresh(&data
->wd_RenderInfo
, 0);
1485 RefreshWindowFrame(data
->wd_RenderInfo
.mri_Window
);
1487 data
->wd_Flags
&= ~MUIWF_RESIZING
;
1488 _width(data
->wd_RootObject
) = data
->wd_Width
;
1489 _height(data
->wd_RootObject
) = data
->wd_Height
;
1490 DoMethod(data
->wd_RootObject
, MUIM_Layout
);
1491 DoShowMethod(data
->wd_RootObject
);
1493 if (muiGlobalInfo(oWin
)->mgi_Prefs
->window_redraw
== WINDOW_REDRAW_WITH_CLEAR
)
1495 LONG left
,top
,width
,height
;
1497 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
1498 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
,
1499 width
= data
->wd_RenderInfo
.mri_Window
->Width
- data
->wd_RenderInfo
.mri_Window
->BorderRight
- left
;
1500 height
= data
->wd_RenderInfo
.mri_Window
->Height
- data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
1502 if(data
->wd_Flags
& MUIWF_ERASEAREA
)
1504 // D(bug("%d:zune_imspec_draw(%p) l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
1505 // __LINE__, data->wd_Background, left, top, width,
1506 // height, left, top));
1507 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
1508 left
, top
, width
, height
, left
, top
, 0);
1510 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWALL
);
1513 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWOBJECT
);
1514 // but should only draw focus without using MUIM_GoActive !
1515 ActivateObject(data
);
1519 if (MUI_BeginRefresh(&data
->wd_RenderInfo
, 0))
1521 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWALL
);
1522 // but should only draw focus without using MUIM_GoActive !
1523 ActivateObject(data
);
1524 MUI_EndRefresh(&data
->wd_RenderInfo
, 0);
1529 case IDCMP_CLOSEWINDOW
:
1530 ReplyMsg((struct Message
*)imsg
);
1532 set(oWin
, MUIA_Window_CloseRequest
, TRUE
);
1535 case IDCMP_MENUPICK
:
1536 ReplyMsg((struct Message
*)imsg
);
1541 if (MENUNUM(imsg
->Code
) != NOMENU
&& ITEMNUM(imsg
->Code
) != NOITEM
)
1543 struct MenuItem
*item
= ItemAddress(data
->wd_Menu
,imsg
->Code
);
1546 Object
*item_obj
= (Object
*)GTMENUITEM_USERDATA(item
);
1552 if (item
->Flags
& CHECKIT
)
1553 set(item_obj
, MUIA_Menuitem_Checked
, !!(item
->Flags
& CHECKED
));
1555 set(item_obj
, MUIA_Menuitem_Trigger
, (IPTR
)item
);
1557 get(oWin
, MUIA_ApplicationObject
, &app
);
1558 get(item_obj
, MUIA_UserData
, &udata
);
1560 set(app
, MUIA_Application_MenuAction
, udata
);
1561 set(oWin
, MUIA_Window_MenuAction
, udata
);
1562 DoMethod(app
, MUIM_Application_ReturnID
, udata
);
1569 case IDCMP_IDCMPUPDATE
:
1570 is_handled
= FALSE
; /* forwardable to area event handlers */
1571 if (data
->wd_VertProp
|| data
->wd_HorizProp
)
1573 struct TagItem
*tag
;
1574 tag
= FindTagItem(GA_ID
,(struct TagItem
*)imsg
->IAddress
);
1577 /* If there's a propclass object connected to the prop
1578 gadget, the prop gadget's userdata will point to
1579 that propclass object. See classes/prop.c */
1581 if (data
->wd_VertProp
)
1583 if (tag
->ti_Data
== GADGETID(data
->wd_VertProp
))
1586 if (tag
->ti_Data
== GADGETID(data
->wd_UpButton
))
1588 Object
*prop
= (Object
*)((struct Gadget
*)data
->wd_VertProp
)->UserData
;
1590 if (prop
) DoMethod(prop
, MUIM_Prop_Decrease
, 1);
1593 if (tag
->ti_Data
== GADGETID(data
->wd_DownButton
))
1595 Object
*prop
= (Object
*)((struct Gadget
*)data
->wd_VertProp
)->UserData
;
1597 if (prop
) DoMethod(prop
, MUIM_Prop_Increase
, 1);
1602 if (data
->wd_HorizProp
)
1604 if (tag
->ti_Data
== GADGETID(data
->wd_HorizProp
))
1607 if (tag
->ti_Data
== GADGETID(data
->wd_LeftButton
))
1609 Object
*prop
= (Object
*)((struct Gadget
*)data
->wd_HorizProp
)->UserData
;
1611 if (prop
) DoMethod(prop
, MUIM_Prop_Decrease
, 1);
1614 if (tag
->ti_Data
== GADGETID(data
->wd_RightButton
))
1616 Object
*prop
= (Object
*)((struct Gadget
*)data
->wd_HorizProp
)->UserData
;
1618 if (prop
) DoMethod(prop
, MUIM_Prop_Increase
, 1);
1626 case IDCMP_INTUITICKS
:
1627 if (data
->wd_HelpTicker
)
1629 data
->wd_HelpTicker
--;
1631 if (data
->wd_HelpTicker
== 0)
1633 Object
*underobj
= ObjectUnderPointer(data
, data
->wd_RootObject
, imsg
->MouseX
, imsg
->MouseY
,
1634 ShortHelpUnderPointerCheck
);
1636 if (underobj
!= data
->wd_HelpObject
)
1638 if (data
->wd_HelpObject
)
1640 DoMethod(data
->wd_HelpObject
, MUIM_DeleteBubble
, (IPTR
)data
->wd_HelpBubble
);
1642 data
->wd_HelpObject
= NULL
;
1643 data
->wd_HelpBubble
= NULL
;
1648 data
->wd_HelpBubble
= (APTR
)DoMethod(underobj
, MUIM_CreateBubble
,
1649 imsg
->MouseX
, imsg
->MouseY
,
1651 if (data
->wd_HelpBubble
)
1653 data
->wd_HelpObject
= underobj
;
1654 data
->wd_Flags
|= MUIWF_BUBBLEMODE
;
1659 if (data
->wd_Flags
& MUIWF_BUBBLEMODE
)
1661 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_LATER
;
1665 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_FIRST
;
1668 } /* if (data->wd_HelpTicker == 0) */
1670 } /* if (data->wd_HelpTicker) */
1672 is_handled
= FALSE
; /* forwardable to area event handlers */
1675 case IDCMP_MOUSEBUTTONS
:
1676 DoMethod(oWin
,MUIM_Window_Snapshot
,0);
1677 KillHelpBubble(data
, oWin
, TRUE
);
1682 case IDCMP_MOUSEMOVE
:
1683 KillHelpBubble(data
, oWin
, FALSE
);
1690 } /* switch (imsg->Class) */
1692 if (is_handled
&& !replied
)
1693 ReplyMsg((struct Message
*)imsg
);
1698 static ULONG
InvokeEventHandler (struct MUI_EventHandlerNode
*ehn
,
1699 struct IntuiMessage
*event
, ULONG muikey
)
1703 if (!(_flags(ehn
->ehn_Object
) & MADF_CANDRAW
)) return 0;
1704 if (!(_flags(ehn
->ehn_Object
) & MADF_SHOWME
)) return 0;
1709 && event
->Class
== IDCMP_MOUSEBUTTONS
1710 && event
->Code
== SELECTDOWN
1711 && (_flags(ehn
->ehn_Object
) & MADF_INVIRTUALGROUP
)
1715 Here we filter out SELECTDOWN messages if objects is in a virtual
1716 group but the click went out of the virtual group
1718 Object
*obj
= ehn
->ehn_Object
;
1719 Object
*parent
= obj
;
1720 Object
*wnd
= _win(obj
);
1722 while (get(parent
,MUIA_Parent
,(IPTR
*)&parent
))
1725 if (wnd
== parent
) break;
1726 if (_flags(parent
) & MADF_ISVIRTUALGROUP
)
1730 event
->MouseX
< _mleft(parent
)
1731 || event
->MouseX
> _mright(parent
)
1732 || event
->MouseY
< _mtop(parent
)
1733 || event
->MouseY
> _mbottom(parent
)
1743 if (ehn
->ehn_Flags
& MUI_EHF_HANDLEINPUT
)
1745 DoMethod(ehn
->ehn_Object
, MUIM_HandleInput
, (IPTR
)event
, muikey
);
1753 ehn
->ehn_Class
, ehn
->ehn_Object
, MUIM_HandleEvent
,
1757 res
= DoMethod(ehn
->ehn_Object
, MUIM_HandleEvent
, (IPTR
)event
, muikey
);
1762 static void HandleRawkey(Object
*win
, struct MUI_WindowData
*data
,
1763 struct IntuiMessage
*event
)
1766 struct MUI_EventHandlerNode
*ehn
;
1767 struct IntuiMessage imsg_copy
;
1768 struct InputEvent ie
= {0};
1770 LONG muikey
= MUIKEY_NONE
;
1771 Object
*active_object
= NULL
;
1776 KillHelpBubble(data
, win
, BUBBLEHELP_TICKER_FIRST
);
1778 ie
.ie_NextEvent
= NULL
;
1779 ie
.ie_Class
= IECLASS_RAWKEY
;
1781 ie
.ie_Code
= event
->Code
;
1782 ie
.ie_Qualifier
= event
->Qualifier
;
1783 ie
.ie_EventAddress
= (APTR
)*(ULONG
*)event
->IAddress
;
1784 ie
.ie_TimeStamp
.tv_secs
= event
->Seconds
;
1785 ie
.ie_TimeStamp
.tv_micro
= event
->Micros
;
1787 set(win
, MUIA_Window_InputEvent
, (IPTR
)&ie
);
1789 /* get the vanilla key for control char */
1792 /* Remove the up prefix as convert key does not convert a upkey event */
1793 msg_code
= event
->Code
;
1794 event
->Code
&= ~IECODE_UP_PREFIX
;
1795 key
= ConvertKey(event
);
1796 event
->Code
= msg_code
;
1800 deadkey
= *(ULONG
*)event
->IAddress
;
1801 imsg_copy
.IAddress
= &deadkey
;
1802 ReplyMsg((struct Message
*)event
);
1805 //bug("rawkey: code=%lx, qual=%lx\n", event->Code, event->Qualifier);
1807 /* check if imsg translate to predefined keystroke */
1809 struct InputEvent ievent
;
1810 BOOL matched
= FALSE
;
1812 ievent
.ie_NextEvent
= NULL
;
1813 ievent
.ie_Class
= IECLASS_RAWKEY
;
1814 ievent
.ie_SubClass
= 0;
1815 ievent
.ie_Code
= event
->Code
;
1816 ievent
.ie_Qualifier
= event
->Qualifier
;
1817 /* ie_EventAddress is not used by MatchIX. If needed, it should be
1818 * ensured that it is still a valid adress because of the shallow
1819 * IntuiMessage copy currently done in _zune_window_message before
1820 * message is replied.
1822 ievent
.ie_EventAddress
= NULL
;
1823 //ievent.ie_EventAddress = (APTR *) *((ULONG *)(event->IAddress));
1825 for (muikey
= MUIKEY_COUNT
- 1; muikey
>= MUIKEY_PRESS
; muikey
--)
1827 if (muiGlobalInfo(win
)->mgi_Prefs
->muikeys
[muikey
].ix_well
!= 0
1828 && MatchIX(&ievent
, &muiGlobalInfo(win
)->mgi_Prefs
->muikeys
[muikey
].ix
))
1837 if (muikey
== MUIKEY_PRESS
&& (event
->Code
& IECODE_UP_PREFIX
))
1838 muikey
= MUIKEY_RELEASE
;
1842 muikey
= MUIKEY_NONE
;
1844 } /* check if imsg translate to predefined keystroke */
1846 if ((muikey
!= MUIKEY_NONE
)
1847 && !(data
->wd_DisabledKeys
& (1<<muikey
)))
1849 D(bug("HandleRawkey: try MUIKEY %ld on window %0x08lx\n", muikey
, win
));
1852 case MUIKEY_PRESS
: break;
1853 case MUIKEY_TOGGLE
: break;
1854 case MUIKEY_UP
: break;
1855 case MUIKEY_DOWN
: break;
1856 case MUIKEY_PAGEUP
: break;
1857 case MUIKEY_PAGEDOWN
: break;
1858 case MUIKEY_TOP
: break;
1859 case MUIKEY_BOTTOM
: break;
1860 case MUIKEY_LEFT
: break;
1861 case MUIKEY_RIGHT
: break;
1862 case MUIKEY_WORDLEFT
: break;
1863 case MUIKEY_WORDRIGHT
: break;
1864 case MUIKEY_LINESTART
: break;
1865 case MUIKEY_LINEEND
: break;
1866 case MUIKEY_GADGET_NEXT
:
1867 set(win
, MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_Next
);
1869 case MUIKEY_GADGET_PREV
:
1870 set(win
, MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_Prev
);
1872 case MUIKEY_GADGET_OFF
:
1873 set(win
, MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_None
);
1875 case MUIKEY_WINDOW_CLOSE
:
1876 set(win
, MUIA_Window_CloseRequest
, TRUE
);
1878 case MUIKEY_WINDOW_NEXT
: break;
1879 case MUIKEY_WINDOW_PREV
: break;
1880 case MUIKEY_HELP
: break;
1881 case MUIKEY_POPUP
: break;
1886 active_object
= NULL
;
1887 if ((data
->wd_ActiveObject
!= NULL
)
1888 && (DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
1889 (IPTR
)data
->wd_ActiveObject
) != (IPTR
)NULL
))
1891 active_object
= data
->wd_ActiveObject
;
1892 get(active_object
, MUIA_Disabled
, &disabled
);
1895 data
->wd_ActiveObject
= NULL
;
1897 /* try ActiveObject */
1898 if ((active_object
!= NULL
) && !disabled
)
1902 ** Which method should be used for muikeys? MUIM_HandleInput or
1903 ** MUIM_HandleEvent. Also note that there is a flag MUI_EHF_ALWAYSKEYS
1904 ** which probably means that all keys events are requested??
1905 ** For now MUIM_HandleEvent is used as this is currently implemented
1906 ** in Area class ;) although I guess it should be MUIM_HandleInput as this
1910 if (muikey
!= MUIKEY_NONE
)
1912 res
= DoMethod(active_object
, MUIM_HandleEvent
, (IPTR
)event
, muikey
);
1913 if (res
& MUI_EventHandlerRC_Eat
) return;
1916 D(bug("HandleRawkey: try active object (%08lx) handlers\n", active_object
));
1918 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
1920 ehn
= (struct MUI_EventHandlerNode
*)mn
;
1922 if ((ehn
->ehn_Object
== active_object
)
1923 && ((ehn
->ehn_Events
& IDCMP_RAWKEY
)
1924 || (ehn
->ehn_Flags
& MUI_EHF_ALWAYSKEYS
)))
1926 D(bug("HandleRawkey: (active) invoking on %p (ehn=%p) event=%p muikey=%p\n",
1927 ehn
->ehn_Object
, ehn
, event
, muikey
));
1928 res
= InvokeEventHandler(ehn
, event
, muikey
);
1929 D(bug("HandleRawkey: (active) got res=%d\n", res
));
1930 if (res
& MUI_EventHandlerRC_Eat
)
1933 /* Leave the loop if a different object has been activated */
1934 if (active_object
!= data
->wd_ActiveObject
)
1937 } /* for (mn = data->wd_EHList.mlh_Head; mn->mln_Succ; mn = mn->mln_Succ) */
1939 // event not eaten by active object, try its parents
1940 // this is to implement popup key in Popstring
1941 if (active_object
== data
->wd_ActiveObject
)
1943 Object
*current_obj
= active_object
;
1945 D(bug("HandleRawkey: try active object parents handlers\n"));
1946 while (current_obj
!= NULL
)
1948 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
1950 ehn
= (struct MUI_EventHandlerNode
*)mn
;
1952 if ((ehn
->ehn_Object
== current_obj
)
1953 && ((ehn
->ehn_Events
& IDCMP_RAWKEY
)
1954 || (ehn
->ehn_Flags
& MUI_EHF_ALWAYSKEYS
)))
1956 //D(bug("HandleRawkey: (active parents) invoking on %p (ehn=%p) "
1957 //"event=%p muikey=%p\n",
1958 //ehn->ehn_Object, ehn, event, muikey));
1959 res
= InvokeEventHandler(ehn
, event
, muikey
);
1960 //D(bug("HandleRawkey: (active parents) got res=%d\n", res));
1961 if (res
& MUI_EventHandlerRC_Eat
)
1964 /* Leave the loop if a different object has been activated */
1965 if (active_object
!= data
->wd_ActiveObject
)
1969 current_obj
= (Object
*)XGET(current_obj
, MUIA_Parent
);
1970 } // while (current_obj != NULL)
1974 } /* if (active_object && !disabled) */
1976 D(bug("HandleRawkey: try default object handlers\n"));
1978 /* try DefaultObject */
1979 if (data
->wd_DefaultObject
!= NULL
)
1980 get(data
->wd_DefaultObject
, MUIA_Disabled
, &disabled
);
1982 if ((data
->wd_DefaultObject
!= NULL
) && !disabled
1983 && (active_object
!= data
->wd_DefaultObject
))
1985 /* No, we only should do this if the object actually has requested this via RequestIDCMP()! */
1986 // if (muikey != MUIKEY_NONE && (_flags(data->wd_DefaultObject) & MADF_CANDRAW))
1988 // DoMethod(data->wd_DefaultObject, MUIM_HandleInput, event, muikey);
1992 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
1994 ehn
= (struct MUI_EventHandlerNode
*)mn
;
1996 if ((ehn
->ehn_Object
== data
->wd_DefaultObject
)
1997 && ((ehn
->ehn_Events
& IDCMP_RAWKEY
)
1998 || (ehn
->ehn_Flags
& MUI_EHF_ALWAYSKEYS
)))
2000 //D(bug("HandleRawkey: (default) invoking on %p (ehn=%p) event=%p muikey=%p\n",
2001 //ehn->ehn_Object, ehn, event, muikey));
2002 res
= InvokeEventHandler(ehn
, event
, muikey
);
2003 //D(bug("HandleRawkey: (default) got res=%d\n", res));
2004 if (res
& MUI_EventHandlerRC_Eat
)
2009 } /* if ... default object */
2011 D(bug("HandleRawkey: try other handlers\n"));
2013 // try other handlers
2014 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2016 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2018 // skip Active and Default object as they have already been
2020 if (ehn
->ehn_Object
== data
->wd_ActiveObject
2021 || ehn
->ehn_Object
== data
->wd_DefaultObject
)
2024 if (ehn
->ehn_Events
& IDCMP_RAWKEY
)
2026 //D(bug("HandleRawkey: (others) invoking on %p (ehn=%p) event=%p muikey=%p\n",
2027 //ehn->ehn_Object, ehn, event, muikey));
2028 res
= InvokeEventHandler(ehn
, event
, MUIKEY_NONE
);
2029 //D(bug("HandleRawkey: (others) got res=%d\n", res));
2030 if (res
& MUI_EventHandlerRC_Eat
)
2033 } /* for (mn = data->wd_EHList.mlh_Head; mn->mln_Succ; mn = mn->mln_Succ) */
2035 D(bug("HandleRawkey: try control chars handlers\n"));
2037 /* try Control Chars */
2038 //bug("ctrlchar, key='%c' code=0x%08lx\n", key, event->Code);
2041 for (mn
= data
->wd_CCList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2043 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2045 if (ehn
->ehn_Events
== key
)
2048 LONG muikey2
= ehn
->ehn_Flags
;
2050 get(ehn
->ehn_Object
, MUIA_Disabled
, &disabled
);
2054 //bug("control char\n");
2055 if (event
->Code
& IECODE_UP_PREFIX
)
2057 /* simulate a release */
2058 if (muikey2
== MUIKEY_PRESS
)
2059 muikey2
= MUIKEY_RELEASE
;
2064 if ((muikey2
!= MUIKEY_NONE
)
2065 && (_flags(ehn
->ehn_Object
) & MADF_CANDRAW
)
2066 && (_flags(ehn
->ehn_Object
) & MADF_SHOWME
))
2070 ehn
->ehn_Class
, ehn
->ehn_Object
, MUIM_HandleEvent
,
2073 if (res
& MUI_EventHandlerRC_Eat
)
2078 } /* try control chars */
2081 /* forward non-keystroke events to event handlers */
2082 static void HandleInputEvent(Object
*win
, struct MUI_WindowData
*data
,
2083 struct IntuiMessage
*event
)
2086 struct MUI_EventHandlerNode
*ehn
;
2087 struct IntuiMessage imsg_copy
;
2089 ULONG mask
= event
->Class
;
2091 if (mask
!= IDCMP_IDCMPUPDATE
)
2094 imsg_copy
.IAddress
= NULL
; /* be sure to trap access to that */
2095 ReplyMsg((struct Message
*)event
);
2099 if (mask
== IDCMP_MOUSEMOVE
)
2101 struct Window
*iWin
;
2102 iWin
= event
->IDCMPWindow
;
2104 if (ContextMenuUnderPointer (data
, data
->wd_RootObject
,
2105 event
->MouseX
, event
->MouseY
))
2107 iWin
->Flags
|= WFLG_RMBTRAP
;
2109 else if (!data
->wd_NoMenus
)
2111 iWin
->Flags
&= ~WFLG_RMBTRAP
;
2115 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2117 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2119 if (ehn
->ehn_Events
& mask
)
2123 get(ehn
->ehn_Object
, MUIA_Disabled
, &disabled
);
2127 res
= InvokeEventHandler(ehn
, event
, MUIKEY_NONE
);
2128 if (res
& MUI_EventHandlerRC_Eat
)
2134 if (mask
== IDCMP_IDCMPUPDATE
)
2135 ReplyMsg((struct Message
*)event
);
2139 /* process window message, this does a ReplyMsg() to the message */
2140 /* Called from application.c */
2141 void _zune_window_message(struct IntuiMessage
*imsg
)
2143 struct Window
*iWin
;
2145 struct MUI_WindowData
*data
;
2148 iWin
= imsg
->IDCMPWindow
;
2149 oWin
= (Object
*)iWin
->UserData
;
2150 data
= muiWindowData(oWin
);
2152 if (data
->wd_DragObject
)
2154 HandleDragging(oWin
, data
, imsg
);
2158 handled
= HandleWindowEvent(oWin
, data
, imsg
);
2161 if (IDCMP_RAWKEY
== imsg
->Class
)
2162 HandleRawkey(oWin
, data
, imsg
);
2164 HandleInputEvent(oWin
, data
, imsg
);
2168 /******************************************************************************/
2169 /******************************************************************************/
2171 /* code for setting MUIA_Window_RootObject */
2172 static void ChangeRootObject (struct MUI_WindowData
*data
, Object
*obj
,
2177 ASSERT_VALID_PTR(data
);
2178 ASSERT_VALID_PTR(obj
);
2180 oldRoot
= data
->wd_RootObject
;
2181 if (!(data
->wd_Flags
& MUIWF_OPENED
))
2185 if (data
->wd_ActiveObject
== oldRoot
)
2186 set(obj
, MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_None
);
2187 DoMethod(oldRoot
, MUIM_DisconnectParent
);
2190 data
->wd_RootObject
= newRoot
;
2193 /* if window is in App tree, inform child */
2194 if (muiNotifyData(obj
)->mnd_GlobalInfo
)
2195 DoMethod(newRoot
, MUIM_ConnectParent
, (IPTR
)obj
);
2200 // find the ObjNode containing a pointer to the given object
2201 // currently only used for cycle chain objects
2202 static struct ObjNode
*FindObjNode(struct MinList
*list
, Object
*obj
)
2204 struct ObjNode
*node
;
2206 ASSERT_VALID_PTR(list
);
2211 ASSERT_VALID_PTR(obj
);
2213 for (node
= (struct ObjNode
*)list
->mlh_Head
;
2214 node
->node
.mln_Succ
;
2215 node
= (struct ObjNode
*)node
->node
.mln_Succ
)
2217 if (node
->obj
== obj
)
2225 static Object
*GetFirstActiveObject (struct MUI_WindowData
*data
)
2227 ASSERT_VALID_PTR(data
);
2229 if (!IsListEmpty((struct List
*)&data
->wd_CycleChain
))
2230 return ((struct ObjNode
*)data
->wd_CycleChain
.mlh_Head
)->obj
;
2235 static Object
*GetLastActiveObject (struct MUI_WindowData
*data
)
2237 ASSERT_VALID_PTR(data
);
2239 if (!IsListEmpty((struct List
*)&data
->wd_CycleChain
))
2240 return ((struct ObjNode
*)data
->wd_CycleChain
.mlh_TailPred
)->obj
;
2245 typedef struct ObjNode
*objnode_iterator_t(struct ObjNode
*curr_node
);
2247 static objnode_iterator_t NextObjNodeIterator
;
2248 static objnode_iterator_t PrevObjNodeIterator
;
2250 static struct ObjNode
*NextObjNodeIterator (struct ObjNode
*curr_node
)
2252 if (curr_node
->node
.mln_Succ
->mln_Succ
)
2253 return (struct ObjNode
*)curr_node
->node
.mln_Succ
;
2258 static struct ObjNode
*PrevObjNodeIterator (struct ObjNode
*curr_node
)
2260 if (curr_node
->node
.mln_Pred
->mln_Pred
)
2261 return (struct ObjNode
*)curr_node
->node
.mln_Pred
;
2266 static Object
*GetPrevNextActiveObject (struct ObjNode
*old_activenode
, objnode_iterator_t node_iterator
)
2268 struct ObjNode
*curr_node
;
2269 struct ObjNode
*node
;
2272 ASSERT_VALID_PTR(old_activenode
);
2274 curr_node
= old_activenode
;
2280 node
= node_iterator(curr_node
);
2285 /* let's see if this obj meets cycle requirements (enabled & visible) */
2290 get(obj
, MUIA_Disabled
, &is_disabled
);
2292 if (!is_disabled
&& (_flags(obj
) & MADF_SHOWME
))
2306 /**************************************************************************
2307 Code for setting MUIA_Window_ActiveObject
2309 - remove focus drawing for current active object
2310 - find (if needed) the new active object
2311 - set data->wd_ActiveObject to the new object
2312 - draw focus around the new active object
2313 **************************************************************************/
2314 static void SetActiveObject (struct MUI_WindowData
*data
, Object
*obj
, IPTR newval
)
2316 struct ObjNode
*old_activenode
= NULL
;
2318 ASSERT_VALID_PTR(data
);
2319 ASSERT_VALID_PTR(obj
);
2321 D(bug("MUIC_Window:SetActiveObject(data, obj, %08lx) Active=%p\n",
2322 newval
, data
->wd_ActiveObject
));
2324 if ((data
->wd_ActiveObject
!= NULL
)
2325 && (DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
2326 (IPTR
)data
->wd_ActiveObject
) != (IPTR
)NULL
))
2328 if ((IPTR
)data
->wd_ActiveObject
== newval
)
2330 old_activenode
= FindObjNode(&data
->wd_CycleChain
, data
->wd_ActiveObject
);
2331 //if (_flags(data->wd_ActiveObject) & MADF_CANDRAW)
2332 if (data
->wd_Flags
& MUIWF_OBJECTGOACTIVESENT
)
2334 DoMethod(data
->wd_ActiveObject
, MUIM_GoInactive
);
2338 data
->wd_ActiveObject
= NULL
;
2339 data
->wd_Flags
&= ~MUIWF_OBJECTGOACTIVESENT
;
2343 case MUIV_Window_ActiveObject_None
:
2346 case MUIV_Window_ActiveObject_Next
:
2347 if (old_activenode
!= NULL
)
2348 data
->wd_ActiveObject
= GetPrevNextActiveObject(old_activenode
,
2349 NextObjNodeIterator
);
2350 if (NULL
== data
->wd_ActiveObject
)
2351 data
->wd_ActiveObject
= GetFirstActiveObject(data
);
2354 case MUIV_Window_ActiveObject_Prev
:
2356 data
->wd_ActiveObject
= GetPrevNextActiveObject(old_activenode
,
2357 PrevObjNodeIterator
);
2358 if (NULL
== data
->wd_ActiveObject
)
2359 data
->wd_ActiveObject
= GetLastActiveObject(data
);
2363 data
->wd_ActiveObject
= (Object
*)newval
;
2367 if (data
->wd_ActiveObject
!= NULL
2368 && DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
2369 (IPTR
)data
->wd_ActiveObject
)
2370 && (_flags(data
->wd_ActiveObject
) & MADF_CANDRAW
))
2372 DoMethod(data
->wd_ActiveObject
, MUIM_GoActive
);
2373 data
->wd_Flags
|= MUIWF_OBJECTGOACTIVESENT
;
2379 * calculate real dimensions from programmer requirements.
2380 * may be overridden by user settings if MUIA_Window_ID is set.
2382 /* MUIV_Window_Height_Screen and MUIV_Window_Height_Visible
2383 * are not handled yet, as their Width couterparts.
2385 static void WindowSelectDimensions (struct MUI_WindowData
*data
)
2387 if (!data
->wd_Width
)
2389 if (data
->wd_ReqWidth
> 0) data
->wd_Width
= data
->wd_ReqWidth
;
2390 else if (data
->wd_ReqWidth
== MUIV_Window_Width_Default
)
2391 data
->wd_Width
= data
->wd_MinMax
.DefWidth
;
2392 else if (_between(MUIV_Window_Width_MinMax(100),
2394 MUIV_Window_Width_MinMax(0)))
2396 data
->wd_Width
= data
->wd_MinMax
.MinWidth
2398 * (data
->wd_MinMax
.MaxWidth
- data
->wd_MinMax
.MinWidth
);
2400 else if (_between(MUIV_Window_Width_Screen(100),
2402 MUIV_Window_Width_Screen(0)))
2404 data
->wd_Width
= data
->wd_RenderInfo
.mri_ScreenWidth
2405 * (- (data
->wd_ReqWidth
+ 200)) / 100;
2407 else if (_between(MUIV_Window_Width_Visible(100),
2409 MUIV_Window_Width_Visible(0)))
2411 data
->wd_Width
= data
->wd_RenderInfo
.mri_ScreenWidth
2412 * (- (data
->wd_ReqWidth
+ 100)) / 100;
2415 if (data
->wd_ReqHeight
> 0) data
->wd_Height
= data
->wd_ReqHeight
;
2416 else if (data
->wd_ReqHeight
== MUIV_Window_Height_Default
)
2417 data
->wd_Height
= data
->wd_MinMax
.DefHeight
;
2418 else if (_between(MUIV_Window_Height_MinMax(100),
2420 MUIV_Window_Height_MinMax(0)))
2422 data
->wd_Height
= data
->wd_MinMax
.MinHeight
2423 - data
->wd_ReqHeight
2424 * (data
->wd_MinMax
.MaxHeight
- data
->wd_MinMax
.MinHeight
);
2426 else if (_between(MUIV_Window_Height_Screen(100),
2428 MUIV_Window_Height_Screen(0)))
2433 scr
= data
->wd_RenderInfo
.mri_Screen
;
2435 height
= scr
->Height
- data
->wd_RenderInfo
.mri_BorderTop
- data
->wd_RenderInfo
.mri_BorderBottom
;
2437 /* This is new to Zune: If TopEdge Delta is requested
2438 * the screenheight doesn't cover the barlayer */
2439 if (data
->wd_Y
<= MUIV_Window_TopEdge_Delta(0))
2440 height
-= scr
->BarHeight
+ 1;
2442 data
->wd_Height
= height
* (- (data
->wd_ReqHeight
+ 200)) / 100;
2444 else if (_between(MUIV_Window_Height_Visible(100),
2446 MUIV_Window_Height_Visible(0)))
2448 data
->wd_Height
= data
->wd_RenderInfo
.mri_ScreenHeight
2449 * (- (data
->wd_ReqHeight
+ 100)) / 100;
2453 if (data
->wd_ReqWidth
== MUIV_Window_Width_Scaled
)
2454 data
->wd_Width
= data
->wd_Height
* data
->wd_MinMax
.MinWidth
2455 / data
->wd_MinMax
.MinHeight
;
2456 else if (data
->wd_ReqHeight
== MUIV_Window_Width_Scaled
)
2457 data
->wd_Height
= data
->wd_Width
* data
->wd_MinMax
.MinHeight
2458 / data
->wd_MinMax
.MinWidth
;
2460 data
->wd_Width
= CLAMP(data
->wd_Width
, data
->wd_MinMax
.MinWidth
,
2461 data
->wd_MinMax
.MaxWidth
);
2462 data
->wd_Height
= CLAMP(data
->wd_Height
, data
->wd_MinMax
.MinHeight
,
2463 data
->wd_MinMax
.MaxHeight
);
2467 /**************************************************************************
2469 **************************************************************************/
2470 IPTR
Window__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
2472 struct MUI_WindowData
*data
;
2473 struct TagItem
*tags
,*tag
;
2475 obj
= (Object
*)DoSuperMethodA(cl
, obj
, (Msg
)msg
);
2479 /* Initial local instance data */
2480 data
= INST_DATA(cl
, obj
);
2482 data
->wd_MemoryPool
= CreatePool(0, 4096, 2048);
2483 if (NULL
== data
->wd_MemoryPool
)
2485 CoerceMethod(cl
, obj
, OM_DISPOSE
);
2489 data
->wd_RenderInfo
.mri_WindowObject
= obj
;
2491 NewList((struct List
*)&(data
->wd_EHList
));
2492 NewList((struct List
*)&(data
->wd_CCList
));
2493 NewList((struct List
*)&(data
->wd_CycleChain
));
2494 NewList((struct List
*)&(data
->wd_IDList
));
2496 data
->wd_CrtFlags
= WFLG_SIZEGADGET
| WFLG_DRAGBAR
| WFLG_DEPTHGADGET
2497 | WFLG_CLOSEGADGET
| WFLG_SIMPLE_REFRESH
2498 | WFLG_REPORTMOUSE
| WFLG_NEWLOOKMENUS
;
2499 data
->wd_ZoomGadget
= TRUE
;
2500 data
->wd_Events
= GetDefaultEvents();
2501 data
->wd_ActiveObject
= NULL
;
2503 data
->wd_ReqHeight
= MUIV_Window_Height_Default
;
2504 data
->wd_ReqWidth
= MUIV_Window_Width_Default
;
2505 data
->wd_RootObject
= NULL
;
2506 data
->wd_DefaultObject
= NULL
;
2508 /* alternate dimensions */
2509 /* no change in coordinates */
2510 data
->wd_AltDim
.Top
= MUIV_Window_AltTopEdge_NoChange
;
2511 data
->wd_AltDim
.Left
= MUIV_Window_AltLeftEdge_NoChange
;
2512 /* default to min size */
2513 data
->wd_AltDim
.Width
= MUIV_Window_AltWidth_MinMax(0);
2514 data
->wd_AltDim
.Height
= MUIV_Window_AltHeight_MinMax(0);
2515 data
->wd_X
= MUIV_Window_LeftEdge_Centered
;
2516 data
->wd_Y
= MUIV_Window_TopEdge_Centered
;
2517 data
->wd_DisabledKeys
= 0L;
2518 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_FIRST
;
2520 /* parse initial taglist */
2522 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem((const struct TagItem
**)&tags
)); )
2524 switch (tag
->ti_Tag
)
2526 case MUIA_Window_EraseArea
:
2527 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_ERASEAREA
);
2530 case MUIA_Window_CloseGadget
:
2531 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_CLOSEGADGET
);
2534 case MUIA_Window_SizeGadget
:
2535 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_SIZEGADGET
);
2538 case MUIA_Window_ZoomGadget
:
2539 data
->wd_ZoomGadget
= tag
->ti_Data
;
2542 case MUIA_Window_Backdrop
:
2543 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_BACKDROP
);
2546 case MUIA_Window_Borderless
:
2547 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_BORDERLESS
);
2550 case MUIA_Window_DepthGadget
:
2551 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_DEPTHGADGET
);
2554 case MUIA_Window_DragBar
:
2555 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_DRAGBAR
);
2558 case MUIA_Window_SizeRight
:
2559 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_SIZEBRIGHT
);
2562 case MUIA_Window_Height
:
2563 data
->wd_ReqHeight
= (LONG
)tag
->ti_Data
;
2566 case MUIA_Window_Width
:
2567 data
->wd_ReqWidth
= (LONG
)tag
->ti_Data
;
2570 case MUIA_Window_ID
:
2571 set(obj
, MUIA_Window_ID
, tag
->ti_Data
);
2574 case MUIA_Window_IsSubWindow
:
2575 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_ISSUBWINDOW
);
2578 case MUIA_Window_Title
:
2579 set(obj
, MUIA_Window_Title
, tag
->ti_Data
);
2582 case MUIA_Window_ScreenTitle
:
2583 set(obj
, MUIA_Window_ScreenTitle
, tag
->ti_Data
);
2586 case MUIA_Window_Activate
:
2587 _handle_bool_tag(data
->wd_Flags
, !tag
->ti_Data
, MUIWF_DONTACTIVATE
);
2590 case MUIA_Window_DefaultObject
:
2591 set(obj
, MUIA_Window_DefaultObject
, tag
->ti_Data
);
2594 case MUIA_Window_Menustrip
:
2595 data
->wd_ChildMenustrip
= (Object
*)tag
->ti_Data
;
2598 case MUIA_Window_NoMenus
:
2599 data
->wd_NoMenus
= (BOOL
) tag
->ti_Data
;
2602 case MUIA_Window_RootObject
:
2605 CoerceMethod(cl
, obj
, OM_DISPOSE
);
2608 set(obj
, MUIA_Window_RootObject
, tag
->ti_Data
);
2611 case MUIA_Window_AltHeight
:
2612 data
->wd_AltDim
.Height
= (WORD
)tag
->ti_Data
;
2615 case MUIA_Window_AltWidth
:
2616 data
->wd_AltDim
.Width
= (WORD
)tag
->ti_Data
;
2619 case MUIA_Window_AltLeftEdge
:
2620 data
->wd_AltDim
.Left
= (WORD
)tag
->ti_Data
;
2623 case MUIA_Window_AltTopEdge
:
2624 data
->wd_AltDim
.Top
= (WORD
)tag
->ti_Data
;
2627 case MUIA_Window_AppWindow
:
2628 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_ISAPPWINDOW
);
2631 case MUIA_Window_LeftEdge
:
2632 data
->wd_X
= tag
->ti_Data
;
2635 case MUIA_Window_TopEdge
:
2636 data
->wd_Y
= tag
->ti_Data
;
2639 case MUIA_Window_UseBottomBorderScroller
:
2640 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_USEBOTTOMSCROLLER
);
2643 case MUIA_Window_UseRightBorderScroller
:
2644 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_USERIGHTSCROLLER
);
2647 case MUIA_Window_DisableKeys
:
2648 data
->wd_DisabledKeys
= tag
->ti_Data
;
2651 case MUIA_Window_RefWindow
:
2652 data
->wd_RefWindow
= (Object
*)tag
->ti_Data
;
2655 case MUIA_Window_Screen
:
2656 data
->wd_UserScreen
= (struct Screen
*)tag
->ti_Data
;
2659 case MUIA_Window_PublicScreen
:
2660 data
->wd_UserPublicScreen
= (STRPTR
)tag
->ti_Data
;
2665 /* D(bug("muimaster.library/window.c: Window Object created at 0x%lx back=%lx\n", */
2666 /* obj,data->wd_Background)); */
2671 /**************************************************************************
2673 **************************************************************************/
2674 IPTR
Window__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
2676 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
2678 /* D(bug("Window_Dispose(%p)\n", obj)); */
2680 #if 0 /* We no longer clear muiGlobalInfo() during disconnections, so
2681 this can cause problems (remove object which is already removed).
2682 Furthermore AFAIK it is not legal to dispose a window object
2683 which is still ocnnected to the application object, anyway. */
2685 if (muiGlobalInfo(obj
) && _app(obj
))
2687 /* D(bug(" Window_Dispose(%p) : calling app->OM_REMMEMBER\n", obj)); */
2688 DoMethod(_app(obj
), OM_REMMEMBER
, (IPTR
)obj
);
2692 if (data
->wd_RootObject
)
2693 MUI_DisposeObject(data
->wd_RootObject
);
2695 if (data
->wd_ChildMenustrip
)
2696 MUI_DisposeObject(data
->wd_ChildMenustrip
);
2698 if (data
->wd_Title
) FreeVec(data
->wd_Title
);
2699 if (data
->wd_ScreenTitle
)FreeVec(data
->wd_ScreenTitle
);
2701 DeletePool(data
->wd_MemoryPool
);
2703 /* D(bug(" Window_Dispose(%p) : calling supermethod\n", obj)); */
2704 return DoSuperMethodA(cl
, obj
, msg
);
2707 static ULONG
WindowOpen(struct IClass
*cl
, Object
*obj
);
2708 static ULONG
WindowClose(struct IClass
*cl
, Object
*obj
);
2710 /**************************************************************************
2712 **************************************************************************/
2713 IPTR
Window__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
2715 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
2716 struct TagItem
*tags
= msg
->ops_AttrList
;
2717 struct TagItem
*tag
;
2719 while ((tag
= NextTagItem((const struct TagItem
**)&tags
)) != NULL
)
2721 switch (tag
->ti_Tag
)
2723 case MUIA_Window_Activate
:
2724 if (data
->wd_RenderInfo
.mri_Window
)
2726 if (tag
->ti_Data
&& !(data
->wd_Flags
& MUIWF_ACTIVE
))
2728 ActivateWindow(data
->wd_RenderInfo
.mri_Window
);
2729 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_ACTIVE
);
2733 _handle_bool_tag(data
->wd_Flags
, !tag
->ti_Data
, MUIWF_DONTACTIVATE
);
2736 case MUIA_Window_ActiveObject
:
2737 /* D(bug("MUIA_Window_ActiveObject %ld (%p)\n", tag->ti_Data, tag->ti_Data)); */
2738 SetActiveObject(data
, obj
, tag
->ti_Data
);
2741 case MUIA_Window_DefaultObject
:
2742 data
->wd_DefaultObject
= (APTR
)tag
->ti_Data
;
2745 case MUIA_Window_ID
:
2746 data
->wd_ID
= tag
->ti_Data
;
2749 case MUIA_Window_IsSubWindow
:
2750 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_ISSUBWINDOW
);
2753 case MUIA_Window_Open
:
2756 if (data
->wd_Flags
& MUIWF_HIDDEN
)
2757 data
->wd_Flags
|= MUIWF_OPENONUNHIDE
;
2759 if (!(data
->wd_Flags
& MUIWF_OPENED
))
2760 WindowOpen(cl
, obj
);
2763 DoMethod(obj
, MUIM_Window_ToFront
);
2764 set(obj
, MUIA_Window_Activate
, TRUE
);
2768 if (data
->wd_Flags
& MUIWF_HIDDEN
)
2769 data
->wd_Flags
&= ~MUIWF_OPENONUNHIDE
;
2771 if (data
->wd_Flags
& MUIWF_OPENED
)
2772 WindowClose(cl
, obj
);
2775 case MUIA_ShowMe
: /* PRIVATE *abuse* of the Area's ShowMe attr */
2780 if (data
->wd_Flags
& MUIWF_HIDDEN
)
2782 data
->wd_Flags
&= ~MUIWF_HIDDEN
;
2784 if (data
->wd_Flags
& MUIWF_OPENONUNHIDE
)
2786 data
->wd_Flags
&= ~MUIWF_OPENONUNHIDE
;
2787 set(obj
, MUIA_Window_Open
, TRUE
);
2795 if (data
->wd_Flags
& MUIWF_OPENED
)
2797 data
->wd_Flags
|= MUIWF_OPENONUNHIDE
;
2799 set(obj
, MUIA_Window_Open
, FALSE
);
2802 data
->wd_Flags
|= MUIWF_HIDDEN
;
2806 case MUIA_Window_RootObject
:
2807 ChangeRootObject(data
, obj
, (Object
*)tag
->ti_Data
);
2810 case MUIA_Window_Title
:
2811 if (data
->wd_Title
) FreeVec(data
->wd_Title
);
2812 data
->wd_Title
= StrDup((STRPTR
)tag
->ti_Data
);
2813 if (data
->wd_RenderInfo
.mri_Window
)
2814 SetWindowTitles(data
->wd_RenderInfo
.mri_Window
,data
->wd_Title
, (CONST_STRPTR
)~0);
2817 case MUIA_Window_ScreenTitle
:
2818 if (data
->wd_ScreenTitle
) FreeVec(data
->wd_ScreenTitle
);
2819 data
->wd_ScreenTitle
= StrDup((STRPTR
)tag
->ti_Data
);
2820 if (data
->wd_RenderInfo
.mri_Window
)
2821 SetWindowTitles(data
->wd_RenderInfo
.mri_Window
,
2822 (CONST_STRPTR
)~0, data
->wd_ScreenTitle
);
2825 case MUIA_Window_NoMenus
:
2826 data
->wd_NoMenus
= (BOOL
) tag
->ti_Data
;
2827 if (data
->wd_RenderInfo
.mri_Window
)
2829 if (data
->wd_NoMenus
)
2830 data
->wd_RenderInfo
.mri_Window
->Flags
|= WFLG_RMBTRAP
;
2832 data
->wd_RenderInfo
.mri_Window
->Flags
&= ~WFLG_RMBTRAP
;
2837 case MUIA_Window_UseBottomBorderScroller
:
2838 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_USEBOTTOMSCROLLER
);
2841 case MUIA_Window_UseRightBorderScroller
:
2842 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_USERIGHTSCROLLER
);
2845 case MUIA_Window_DisableKeys
:
2846 data
->wd_DisabledKeys
= tag
->ti_Data
;
2849 case MUIA_Window_RefWindow
:
2850 data
->wd_RefWindow
= (Object
*)tag
->ti_Data
;
2853 #warning "TODO: obsolete hacked atribute - remove"
2854 #if defined(MUIA_Window_WandererBackdrop)
2855 case MUIA_Window_WandererBackdrop
:
2856 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_BACKDROP
);
2857 _handle_bool_tag(data
->wd_CrtFlags
, !tag
->ti_Data
, WFLG_DRAGBAR
);
2858 _handle_bool_tag(data
->wd_CrtFlags
, !tag
->ti_Data
, WFLG_SIZEGADGET
);
2859 _handle_bool_tag(data
->wd_CrtFlags
, !tag
->ti_Data
, WFLG_CLOSEGADGET
);
2860 _handle_bool_tag(data
->wd_CrtFlags
, !tag
->ti_Data
, WFLG_DEPTHGADGET
);
2861 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_BORDERLESS
);
2864 data
->wd_ReqWidth
= (LONG
)MUIV_Window_Width_Screen(100);
2865 /* won't take the barlayer into account */
2866 data
->wd_ReqHeight
= (LONG
)MUIV_Window_Height_Screen(100);
2868 data
->wd_Height
= 0;
2869 data
->wd_X
= (LONG
)0;
2870 /* place the window below the bar layer */
2871 data
->wd_Y
= (LONG
)MUIV_Window_TopEdge_Delta(0);
2876 case MUIA_Window_LeftEdge
:
2877 data
->wd_X
= tag
->ti_Data
;
2880 case MUIA_Window_TopEdge
:
2881 data
->wd_Y
= tag
->ti_Data
;
2884 case MUIA_Window_Width
:
2885 data
->wd_ReqWidth
= (LONG
)tag
->ti_Data
;
2886 data
->wd_Width
= 0; /* otherwise windowselectdimensions() ignores ReqWidth */
2889 case MUIA_Window_Height
:
2890 data
->wd_ReqWidth
= (LONG
)tag
->ti_Data
;
2891 data
->wd_Height
= 0;
2894 case MUIA_Window_Screen
:
2895 data
->wd_UserScreen
= (struct Screen
*)tag
->ti_Data
;
2898 case MUIA_Window_PublicScreen
:
2899 data
->wd_UserPublicScreen
= (STRPTR
)tag
->ti_Data
;
2906 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
2909 /**************************************************************************
2911 **************************************************************************/
2912 IPTR
Window__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
2914 #define STORE *(msg->opg_Storage)
2916 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
2920 switch(msg
->opg_AttrID
)
2922 case MUIA_Window_Activate
:
2923 STORE
= (data
->wd_Flags
& (MUIWF_ACTIVE
| MUIWF_OPENED
)) == (MUIWF_ACTIVE
| MUIWF_OPENED
);
2926 case MUIA_Window_Window
:
2927 STORE
= (IPTR
)data
->wd_RenderInfo
.mri_Window
;
2930 case MUIA_Window_Screen
:
2931 STORE
= (IPTR
)data
->wd_RenderInfo
.mri_Screen
;
2934 case MUIA_Window_PublicScreen
:
2935 STORE
= (IPTR
)data
->wd_UserPublicScreen
;
2938 case MUIA_Window_ActiveObject
:
2939 if ((data
->wd_ActiveObject
!= NULL
)
2940 && (DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
2941 (IPTR
)data
->wd_ActiveObject
) != (IPTR
)NULL
))
2942 STORE
= (IPTR
)data
->wd_ActiveObject
;
2947 case MUIA_Window_CloseRequest
:
2951 case MUIA_Window_DefaultObject
:
2952 STORE
= (IPTR
)data
->wd_DefaultObject
;
2955 case MUIA_Window_DisableKeys
:
2956 STORE
= data
->wd_DisabledKeys
;
2959 case MUIA_Window_Height
:
2960 STORE
= (IPTR
)data
->wd_Height
;
2963 case MUIA_Window_ID
:
2964 STORE
= data
->wd_ID
;
2967 case MUIA_Window_IsSubWindow
:
2968 STORE
= (data
->wd_Flags
& MUIWF_ISSUBWINDOW
) == MUIWF_ISSUBWINDOW
;
2971 case MUIA_Window_LeftEdge
:
2972 if (data
->wd_RenderInfo
.mri_Window
)
2973 STORE
= (IPTR
)data
->wd_RenderInfo
.mri_Window
->LeftEdge
;
2978 case MUIA_Window_Open
:
2979 STORE
= (data
->wd_Flags
& MUIWF_OPENED
) == MUIWF_OPENED
;
2982 case MUIA_Window_RootObject
:
2983 STORE
= (IPTR
)data
->wd_RootObject
;
2986 case MUIA_Window_ScreenTitle
:
2987 STORE
= (IPTR
)data
->wd_ScreenTitle
;
2990 case MUIA_Window_Title
:
2991 STORE
= (IPTR
)data
->wd_Title
;
2994 case MUIA_Window_TopEdge
:
2995 if (data
->wd_RenderInfo
.mri_Window
)
2996 STORE
= (IPTR
)data
->wd_RenderInfo
.mri_Window
->TopEdge
;
3001 case MUIA_Window_Width
:
3002 STORE
= (IPTR
)data
->wd_Width
;
3014 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
3019 * MUIM_FindUData : tests if the MUIA_UserData of the object
3020 * contains the given <udata> and returns the object pointer in this case.
3022 IPTR
Window__MUIM_FindUData(struct IClass
*cl
, Object
*obj
, struct MUIP_FindUData
*msg
)
3024 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3026 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3029 if (data
->wd_RootObject
)
3030 return DoMethodA(data
->wd_RootObject
, (Msg
)msg
);
3037 * MUIM_GetUData : This method tests if the MUIA_UserData of the object
3038 * contains the given <udata> and gets <attr> to <storage> for itself
3041 IPTR
Window__MUIM_GetUData(struct IClass
*cl
, Object
*obj
, struct MUIP_GetUData
*msg
)
3043 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3045 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3047 get(obj
, msg
->attr
, msg
->storage
);
3051 if (data
->wd_RootObject
)
3052 return DoMethodA(data
->wd_RootObject
, (Msg
)msg
);
3059 * MUIM_SetUData : This method tests if the MUIA_UserData of the object
3060 * contains the given <udata> and sets <attr> to <val> for itself in this case.
3062 IPTR
Window__MUIM_SetUData(struct IClass
*cl
, Object
*obj
, struct MUIP_SetUData
*msg
)
3064 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3066 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3067 set(obj
, msg
->attr
, msg
->val
);
3069 if (data
->wd_RootObject
)
3070 DoMethodA(data
->wd_RootObject
, (Msg
)msg
);
3077 * MUIM_SetUDataOnce : This method tests if the MUIA_UserData of the object
3078 * contains the given <udata> and sets <attr> to <val> for itself in this case.
3080 IPTR
Window__MUIM_SetUDataOnce(struct IClass
*cl
, Object
*obj
, struct MUIP_SetUDataOnce
*msg
)
3082 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3084 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3086 set(obj
, msg
->attr
, msg
->val
);
3090 if (data
->wd_RootObject
)
3091 return DoMethodA(data
->wd_RootObject
, (Msg
)msg
);
3096 /**************************************************************************
3097 Called by Application (parent) object whenever this object is added.
3099 **************************************************************************/
3100 IPTR
Window__MUIM_ConnectParent(struct IClass
*cl
, Object
*obj
,
3101 struct MUIP_ConnectParent
*msg
)
3103 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3105 if (!DoSuperMethodA(cl
,obj
,(Msg
)msg
)) return 0;
3107 if (data
->wd_RootObject
)
3108 DoMethod(data
->wd_RootObject
, MUIM_ConnectParent
, (IPTR
)obj
);
3110 if (data
->wd_ChildMenustrip
)
3111 DoMethod(data
->wd_ChildMenustrip
, MUIM_ConnectParent
, (IPTR
)obj
);
3117 /**************************************************************************
3118 called by parent object
3119 **************************************************************************/
3120 IPTR
Window__MUIM_DisconnectParent(struct IClass
*cl
, Object
*obj
, struct MUIP_DisconnectParent
*msg
)
3122 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3124 /* D(bug("Window_DisconnectParent(%p) : muiGlobalInfo=%p\n", muiGlobalInfo(obj))); */
3125 if (muiGlobalInfo(obj
))
3127 /* Close the window before disconnecting all the childs */
3128 if ((data
->wd_Flags
& MUIWF_OPENED
))
3130 /* D(bug(" Window_DisconnectParent(%p) : closing window\n", muiGlobalInfo(obj))); */
3131 set(obj
, MUIA_Window_Open
, FALSE
);
3133 if (data
->wd_ChildMenustrip
)
3134 DoMethod(data
->wd_ChildMenustrip
, MUIM_DisconnectParent
, (IPTR
)obj
);
3136 if (data
->wd_RootObject
)
3137 DoMethodA(data
->wd_RootObject
, (Msg
)msg
);
3139 /* D(bug(" Window_DisconnectParent(%p) : calling supermethod\n", muiGlobalInfo(obj))); */
3140 return DoSuperMethodA(cl
,obj
,(Msg
)msg
);
3148 static void SetRootObjInnerSpacing(Object
*obj
, struct MUI_WindowData
*data
)
3150 UWORD wd_innerLeft
, wd_innerRight
, wd_innerTop
, wd_innerBottom
;
3152 if (data
->wd_CrtFlags
& WFLG_BORDERLESS
)
3161 wd_innerLeft
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_left
;
3162 wd_innerRight
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_right
;
3163 wd_innerTop
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_top
;
3164 wd_innerBottom
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_bottom
;
3167 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERLEFT
))
3169 muiAreaData(data
->wd_RootObject
)->mad_InnerLeft
= wd_innerLeft
;
3172 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERTOP
))
3174 muiAreaData(data
->wd_RootObject
)->mad_InnerTop
= wd_innerTop
;
3177 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERRIGHT
))
3179 muiAreaData(data
->wd_RootObject
)->mad_InnerRight
= wd_innerRight
;
3182 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERBOTTOM
))
3184 muiAreaData(data
->wd_RootObject
)->mad_InnerBottom
= wd_innerBottom
;
3189 * Called before window is opened or resized. It determines its bounds,
3190 * so you can call WindowSelectDimensions() to find the final dims.
3192 static void WindowMinMax(Object
*obj
, struct MUI_WindowData
*data
)
3194 SetRootObjInnerSpacing(obj
, data
);
3195 /* inquire about sizes */
3196 DoMethod(data
->wd_RootObject
, MUIM_AskMinMax
, (IPTR
)&data
->wd_MinMax
);
3197 /* D(bug("*** root minmax = %ld,%ld => %ld,%ld\n", data->wd_MinMax.MinWidth, */
3198 /* data->wd_MinMax.MinHeight, */
3199 /* data->wd_MinMax.MaxWidth, data->wd_MinMax.MaxHeight)); */
3200 __area_finish_minmax(data
->wd_RootObject
, &data
->wd_MinMax
);
3201 /* D(bug("*** root minmax2 = %ld,%ld => %ld,%ld\n", data->wd_MinMax.MinWidth, */
3202 /* data->wd_MinMax.MinHeight, */
3203 /* data->wd_MinMax.MaxWidth, data->wd_MinMax.MaxHeight)); */
3207 static void InstallBackbuffer (struct IClass
*cl
, Object
*obj
)
3209 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3211 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
3213 data
->wd_RenderInfo
.mri_BufferBM
=
3214 AllocBitMap(win
->Width
, win
->Height
, win
->RPort
->BitMap
->Depth
,
3215 0, win
->RPort
->BitMap
);
3217 if (data
->wd_RenderInfo
.mri_BufferBM
)
3219 /* D(bug("install_backbuffer : allocated bitmap %dx%dx%d with friend %p\n", */
3220 /* win->Width, win->Height, win->RPort->BitMap->Depth, win->RPort->BitMap)); */
3221 InitRastPort(&data
->wd_RenderInfo
.mri_BufferRP
);
3222 data
->wd_RenderInfo
.mri_BufferRP
.BitMap
= data
->wd_RenderInfo
.mri_BufferBM
;
3226 static void DeinstallBackbuffer (struct IClass
*cl
, Object
*obj
)
3228 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3230 if (data
->wd_RenderInfo
.mri_BufferBM
)
3232 DeinitRastPort(&data
->wd_RenderInfo
.mri_BufferRP
);
3233 FreeBitMap(data
->wd_RenderInfo
.mri_BufferBM
);
3234 data
->wd_RenderInfo
.mri_BufferBM
= NULL
;
3239 * Called after window is opened or resized.
3240 * An expose event is already queued, it will trigger
3241 * MUIM_Draw for us when going back to main loop.
3243 static void WindowShow (struct IClass
*cl
, Object
*obj
)
3245 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3246 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
3247 /* D(bug("window_show %s %d\n", __FILE__, __LINE__)); */
3249 _left(data
->wd_RootObject
) = win
->BorderLeft
;
3250 _top(data
->wd_RootObject
) = win
->BorderTop
;
3251 _width(data
->wd_RootObject
) = data
->wd_Width
;
3252 _height(data
->wd_RootObject
) = data
->wd_Height
;
3254 DoMethod(data
->wd_RootObject
, MUIM_Layout
);
3256 ShowRenderInfo(&data
->wd_RenderInfo
);
3257 /* D(bug("zune_imspec_show %s %d\n", __FILE__, __LINE__)); */
3258 zune_imspec_show(data
->wd_Background
, obj
);
3259 DoShowMethod(data
->wd_RootObject
);
3262 static ULONG
WindowOpen(struct IClass
*cl
, Object
*obj
)
3264 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3266 if (!data
->wd_RootObject
)
3269 if (!DoMethod(obj
, MUIM_Window_Setup
))
3272 /* I got display info, so calculate your display dependant data */
3273 if (!DoSetupMethod(data
->wd_RootObject
, &data
->wd_RenderInfo
))
3275 DoMethod(obj
, MUIM_Window_Cleanup
);
3279 /* inquire about sizes */
3280 WindowMinMax(obj
,data
);
3281 WindowSelectDimensions(data
);
3283 /* Decide which menustrip should be used */
3284 if (!data
->wd_ChildMenustrip
)
3285 get(_app(obj
), MUIA_Application_Menustrip
, (IPTR
*)&data
->wd_Menustrip
);
3287 data
->wd_Menustrip
= data
->wd_ChildMenustrip
;
3289 /* open window here ... */
3290 if (!DisplayWindow(obj
,data
))
3292 /* free display dependant data */
3293 data
->wd_Menustrip
= NULL
;
3294 DoMethod(data
->wd_RootObject
, MUIM_Cleanup
);
3295 DoMethod(obj
, MUIM_Window_Cleanup
);
3299 InstallBackbuffer(cl
, obj
);
3301 data
->wd_Flags
|= MUIWF_OPENED
;
3303 WindowShow(cl
, obj
);
3306 LONG left
,top
,width
,height
;
3308 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
3309 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
,
3310 width
= data
->wd_RenderInfo
.mri_Window
->Width
3311 - data
->wd_RenderInfo
.mri_Window
->BorderRight
- left
;
3312 height
= data
->wd_RenderInfo
.mri_Window
->Height
3313 - data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
3315 /* D(bug("zune_imspec_draw %s %d\n", __FILE__, __LINE__)); */
3316 // D(bug("%d:zune_imspec_draw(%p) l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
3317 // __LINE__, data->wd_Background, left, top, width,
3318 // height, left, top));
3320 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
3321 left
, top
, width
, height
, left
, top
, 0);
3324 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWOBJECT
);
3326 D(bug("MUIC_Window:windowOpen() ActiveObject=%p\n", data
->wd_ActiveObject
));
3327 if (data
->wd_OldActive
!= NULL
)
3329 set(obj
, MUIA_Window_ActiveObject
, data
->wd_OldActive
);
3335 /******************************************************************************/
3336 /******************************************************************************/
3338 static ULONG
WindowClose(struct IClass
*cl
, Object
*obj
)
3340 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3342 if (data
->wd_ActiveObject
!= NULL
)
3344 data
->wd_OldActive
= data
->wd_ActiveObject
;
3345 set(obj
, MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_None
);
3348 KillHelpBubble(data
, obj
, BUBBLEHELP_TICKER_FIRST
);
3350 /* remove from window */
3351 DoHideMethod(data
->wd_RootObject
);
3352 zune_imspec_hide(data
->wd_Background
);
3354 DeinstallBackbuffer(cl
, obj
);
3356 HideRenderInfo(&data
->wd_RenderInfo
);
3358 /* close here ... */
3359 UndisplayWindow(obj
,data
);
3361 data
->wd_Flags
&= ~MUIWF_OPENED
;
3362 data
->wd_Menustrip
= NULL
;
3364 /* free display dependant data */
3365 DoMethod(data
->wd_RootObject
, MUIM_Cleanup
);
3366 DoMethod(obj
, MUIM_Window_Cleanup
);
3370 /* calculate a new layout
3372 * see Group_ExitChange
3376 IPTR
Window__MUIM_RecalcDisplay(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_RecalcDisplay
*msg
)
3378 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3379 LONG left
,top
,width
,height
;
3381 Object
*current_obj
;
3383 if (!(data
->wd_Flags
& MUIWF_OPENED
))
3386 current_obj
= msg
->originator
;
3388 // typically originator is a group which has been added/removed a child
3389 // calculate minmax of current obj
3390 // if new minmax can accomodate current obj size, stop
3391 // else try with its parent
3392 // the resulting object will get a new layout
3393 // it currently produces some redundant AskMinMax but allows
3394 // to not always relayout the whole window
3396 D(bug("RecalcDisplay on %p\n", current_obj
));
3397 while (current_obj
!= NULL
)
3399 DoMethod(current_obj
, MUIM_AskMinMax
, (IPTR
)&muiAreaData(current_obj
)->mad_MinMax
);
3400 __area_finish_minmax(current_obj
, &muiAreaData(current_obj
)->mad_MinMax
);
3402 D(bug("size w = %d, h = %d\n", _width(current_obj
), _height(current_obj
)));
3403 D(bug("new w = %d-%d, h = %d-%d\n", _minwidth(current_obj
), _maxwidth(current_obj
),
3404 _minheight(current_obj
), _maxheight(current_obj
)));
3406 if (!_between(_minwidth(current_obj
), _width(current_obj
), _maxwidth(current_obj
))
3407 || !_between(_minheight(current_obj
), _height(current_obj
), _maxheight(current_obj
)))
3409 current_obj
= _parent(current_obj
);
3410 D(bug("RecalcDisplay, try parent %p\n", current_obj
));
3414 D(bug("found it\n"));
3420 current_obj
= data
->wd_RootObject
;
3422 WindowMinMax(obj
, data
);
3423 DoHideMethod(current_obj
);
3424 /* resize window ? */
3425 WindowSelectDimensions(data
);
3426 resized
= WindowResize(data
);
3429 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
3430 _left(data
->wd_RootObject
) = win
->BorderLeft
;
3431 _top(data
->wd_RootObject
) = win
->BorderTop
;
3432 _width(data
->wd_RootObject
) = data
->wd_Width
;
3433 _height(data
->wd_RootObject
) = data
->wd_Height
;
3435 DoMethod(current_obj
, MUIM_Layout
);
3436 DoShowMethod(current_obj
);
3438 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_redraw
== WINDOW_REDRAW_WITHOUT_CLEAR
)
3439 MUI_Redraw(current_obj
, MADF_DRAWOBJECT
);
3442 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
3443 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
;
3444 width
= data
->wd_RenderInfo
.mri_Window
->Width
3445 - data
->wd_RenderInfo
.mri_Window
->BorderRight
- left
;
3446 height
= data
->wd_RenderInfo
.mri_Window
->Height
3447 - data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
3449 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
3450 left
, top
, width
, height
, left
, top
, 0);
3451 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWALL
);
3454 ActivateObject(data
);
3460 /**************************************************************************
3461 MUIM_AddEventHandler
3462 **************************************************************************/
3463 IPTR
Window__MUIM_AddEventHandler(struct IClass
*cl
, Object
*obj
,
3464 struct MUIP_Window_AddEventHandler
*msg
)
3466 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3468 //D(bug("muimaster.library/window.c: Add Eventhandler %p\n", msg->ehnode));
3471 #if !(AROS_FLAVOUR & AROS_FLAVOUR_BINCOMPAT)
3472 msg
->ehnode
->ehn_Node
.ln_Pri
= msg
->ehnode
->ehn_Priority
;
3474 msg
->ehnode
->ehn_Priority
= msg
->ehnode
->ehn_Priority
;
3477 EnqueueByPriAndAddress((struct List
*)&data
->wd_EHList
, (struct Node
*)msg
->ehnode
);
3478 ChangeEvents(data
, GetDefaultEvents());
3482 /**************************************************************************
3483 MUIM_RemEventHandler
3484 **************************************************************************/
3485 IPTR
Window__MUIM_RemEventHandler(struct IClass
*cl
, Object
*obj
,
3486 struct MUIP_Window_RemEventHandler
*msg
)
3488 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3490 //D(bug("muimaster.library/window.c: Rem Eventhandler %p\n", msg->ehnode));
3492 Remove((struct Node
*)msg
->ehnode
);
3493 ChangeEvents(data
, GetDefaultEvents());
3497 /**************************************************************************
3498 Note that this is MUIM_Window_Setup, not MUIM_Setup
3499 **************************************************************************/
3500 IPTR
Window__MUIM_Setup(struct IClass
*cl
, Object
*obj
, Msg msg
)
3502 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3504 if (!SetupRenderInfo(obj
, data
, &data
->wd_RenderInfo
))
3507 data
->wd_Background
= zune_imspec_setup(MUII_WindowBack
, &data
->wd_RenderInfo
);
3509 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_redraw
== WINDOW_REDRAW_WITH_CLEAR
)
3510 data
->wd_Flags
|= MUIWF_ERASEAREA
;
3515 /**************************************************************************
3517 **************************************************************************/
3518 IPTR
Window__MUIM_Cleanup(struct IClass
*cl
, Object
*obj
, Msg msg
)
3520 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3522 zune_imspec_cleanup(data
->wd_Background
);
3526 DeleteDragNDrop(data
->wd_dnd
);
3527 data
->wd_dnd
= NULL
;
3530 CleanupRenderInfo(data
, &data
->wd_RenderInfo
);
3535 /**************************************************************************
3536 This adds the the control char handler and also do the MUIA_CycleChain
3537 stuff. Orginal MUI does this in an other way.
3538 **************************************************************************/
3539 IPTR
Window__MUIM_AddControlCharHandler(struct IClass
*cl
, Object
*obj
,
3540 struct MUIP_Window_AddControlCharHandler
*msg
)
3542 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3543 struct ObjNode
*node
;
3545 if (msg
->ccnode
->ehn_Events
)
3548 #if !(AROS_FLAVOUR & AROS_FLAVOUR_BINCOMPAT)
3549 msg
->ccnode
->ehn_Node
.ln_Pri
= msg
->ccnode
->ehn_Priority
;
3551 msg
->ccnode
->ehn_Priority
= msg
->ccnode
->ehn_Priority
;
3554 Enqueue((struct List
*)&data
->wd_CCList
, (struct Node
*)msg
->ccnode
);
3556 /* Due to the lack of a better idea ... */
3557 if (muiAreaData(msg
->ccnode
->ehn_Object
)->mad_Flags
& MADF_CYCLECHAIN
)
3559 node
= AllocPooled(data
->wd_MemoryPool
, sizeof(struct ObjNode
));
3562 node
->obj
= msg
->ccnode
->ehn_Object
;
3563 AddTail((struct List
*)&data
->wd_CycleChain
,(struct Node
*)node
);
3569 /**************************************************************************
3570 MUIM_RemControlCharHandler
3571 **************************************************************************/
3572 IPTR
Window__MUIM_RemControlCharHandler(struct IClass
*cl
, Object
*obj
,
3573 struct MUIP_Window_RemControlCharHandler
*msg
)
3575 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3576 struct ObjNode
*node
= FindObjNode(&data
->wd_CycleChain
,msg
->ccnode
->ehn_Object
);
3578 if (msg
->ccnode
->ehn_Events
) Remove((struct Node
*)msg
->ccnode
);
3582 /* Remove from the chain list */
3583 Remove((struct Node
*)node
);
3584 FreePooled(data
->wd_MemoryPool
, node
, sizeof(struct ObjNode
));
3590 /**************************************************************************
3592 **************************************************************************/
3593 IPTR
Window__MUIM_DragObject(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_DragObject
*msg
)
3595 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3598 struct DragNDrop
*dnd
;
3599 struct MUI_DragImage
*di
;
3600 struct BitMapNode
*bmn
;
3602 if (!(dnd
= CreateDragNDropA(NULL
))) return 0;
3603 if (!(di
= (struct MUI_DragImage
*)DoMethod(msg
->obj
,MUIM_CreateDragImage
,-msg
->touchx
,-msg
->touchy
,msg
->flags
)))
3605 DeleteDragNDrop(dnd
);
3610 DoMethod(msg
->obj
,MUIM_DeleteDragImage
, (IPTR
)di
);
3611 DeleteDragNDrop(dnd
);
3615 if (!(bmn
= CreateBitMapNode(NULL
, /* dummy */
3617 GUI_LeftOffset
, di
->touchx
,
3618 GUI_TopOffset
, di
->touchy
,
3619 GUI_Width
, di
->width
,
3620 GUI_Height
, di
->height
,
3623 DoMethod(msg
->obj
, MUIM_DeleteDragImage
, (IPTR
)di
);
3624 DeleteDragNDrop(dnd
);
3628 AttachBitMapNode(dnd
,bmn
);
3630 if (!PrepareDragNDrop(dnd
, data
->wd_RenderInfo
.mri_Screen
))
3632 DoMethod(msg
->obj
,MUIM_DeleteDragImage
, (IPTR
)di
);
3633 DeleteDragNDrop(dnd
);
3637 muiAreaData(msg
->obj
)->mad_Flags
|= MADF_DRAGGING
;
3639 data
->wd_DragObject
= msg
->obj
;
3641 data
->wd_DragImage
= di
;
3647 /**************************************************************************
3649 **************************************************************************/
3650 IPTR
Window__MUIM_AllocGadgetID(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_AllocGadgetID
*msg
)
3652 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3653 struct IDNode
*newnode
;
3655 newnode
= AllocPooled(data
->wd_MemoryPool
, sizeof(struct IDNode
));
3661 if (IsListEmpty((struct List
*)&data
->wd_IDList
))
3664 AddHead((struct List
*)&data
->wd_IDList
, (struct Node
*)&newnode
->node
);
3670 for (mn
= data
->wd_IDList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
3672 struct IDNode
*idn
= (struct IDNode
*)mn
;
3678 Insert((struct List
*)&data
->wd_IDList
, (struct Node
*)&newnode
->node
, (struct Node
*)mn
);
3685 /**************************************************************************
3687 **************************************************************************/
3688 IPTR
Window__MUIM_FreeGadgetID(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_FreeGadgetID
*msg
)
3690 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3693 for (mn
= data
->wd_IDList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
3695 struct IDNode
*idn
= (struct IDNode
*)mn
;
3696 if (msg
->gadgetid
== idn
->id
)
3698 Remove((struct Node
*)idn
);
3699 FreePooled(data
->wd_MemoryPool
, idn
, sizeof(struct IDNode
));
3708 /**************************************************************************
3709 MUIM_Window_GetMenuCheck
3710 **************************************************************************/
3711 IPTR
Window__MUIM_GetMenuCheck(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_GetMenuCheck
*msg
)
3714 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3716 Object
*strip
= data
->wd_ChildMenustrip
;
3717 if (!strip
) strip
= data
->wd_Menustrip
;
3718 if (!strip
) return 0;
3719 if (!(item
= (Object
*)DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
))) return 0;
3720 get(item
,MUIA_Menuitem_Checked
, &stat
);
3724 /**************************************************************************
3725 MUIM_Window_SetMenuCheck
3726 **************************************************************************/
3727 IPTR
Window__MUIM_SetMenuCheck(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_SetMenuCheck
*msg
)
3729 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3731 Object
*strip
= data
->wd_ChildMenustrip
;
3732 if (!strip
) strip
= data
->wd_Menustrip
;
3733 if (!strip
) return 0;
3734 if (!(item
= (Object
*)DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
))) return 0;
3735 set(item
,MUIA_Menuitem_Checked
,msg
->stat
);
3739 /**************************************************************************
3740 MUIM_Window_GetMenuState
3741 **************************************************************************/
3742 IPTR
Window__MUIM_GetMenuState(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_GetMenuState
*msg
)
3745 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3747 Object
*strip
= data
->wd_ChildMenustrip
;
3748 if (!strip
) strip
= data
->wd_Menustrip
;
3749 if (!strip
) return 0;
3750 if (!(item
= (Object
*)DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
))) return 0;
3751 get(item
,MUIA_Menuitem_Enabled
, &stat
);
3755 /**************************************************************************
3756 MUIM_Window_SetMenuState
3757 **************************************************************************/
3758 IPTR
Window__MUIM_SetMenuState(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_SetMenuState
*msg
)
3760 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3762 Object
*strip
= data
->wd_ChildMenustrip
;
3763 if (!strip
) strip
= data
->wd_Menustrip
;
3764 if (!strip
) return 0;
3765 if (!(item
= (Object
*)DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
))) return 0;
3766 set(item
,MUIA_Menuitem_Enabled
,msg
->stat
);
3770 /**************************************************************************
3771 MUIM_Window_DrawBackground
3772 **************************************************************************/
3773 IPTR
Window__MUIM_DrawBackground(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_DrawBackground
*msg
)
3775 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3776 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
3779 // D(bug("%d:zune_imspec_draw(%p) l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
3780 // __LINE__, data->wd_Background, msg->left, msg->top, msg->width,
3781 // msg->height, msg->xoffset, msg->yoffset));
3782 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
3783 msg
->left
, msg
->top
, msg
->width
, msg
->height
,
3784 msg
->xoffset
, msg
->yoffset
, 0);
3788 /**************************************************************************
3790 **************************************************************************/
3791 IPTR
Window__MUIM_ToFront(struct IClass
*cl
, Object
*obj
, Msg msg
)
3793 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3794 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
3797 WindowToFront(data
->wd_RenderInfo
.mri_Window
);
3801 /**************************************************************************
3803 **************************************************************************/
3804 IPTR
Window__MUIM_ToBack(struct IClass
*cl
, Object
*obj
, Msg msg
)
3806 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3807 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
3810 WindowToBack(data
->wd_RenderInfo
.mri_Window
);
3814 /**************************************************************************
3815 MUIM_Window_ScreenToBack
3816 **************************************************************************/
3817 IPTR
Window__MUIM_ScreenToBack(struct IClass
*cl
, Object
*obj
, Msg msg
)
3819 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3820 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
3823 ScreenToBack(data
->wd_RenderInfo
.mri_Screen
);
3827 /**************************************************************************
3828 MUIM_Window_ScreenToFront
3829 **************************************************************************/
3830 IPTR
Window__MUIM_ScreenToFront(struct IClass
*cl
, Object
*obj
, Msg msg
)
3832 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3833 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
3836 ScreenToFront(data
->wd_RenderInfo
.mri_Screen
);
3840 /**************************************************************************
3841 MUIM_Window_ActionIconify
3842 **************************************************************************/
3843 IPTR
Window__MUIM_ActionIconify(struct IClass
*cl
, Object
*obj
, Msg msg
)
3845 set(_app(obj
), MUIA_Application_Iconified
, TRUE
);
3851 /* Loads ENV: prefs, add a Window_ID chunk in the MUIW chunk, if no MUIW chunk
3852 * then create it at the same level as MUIC chunk, save prefs.
3853 * Do the same for ENVARC:
3854 * MUIW chunk layout:
3856 * 00 00 00 30 (chunk length for a single window, 0x30L big endian)
3859 * xx xx yy yy (X, Y)
3860 * ww ww hh hh (Width, Height)
3861 * ax ax ay ay (AltX, AltY)
3862 * aw aw ah ah (AltWidth, AltHeight)
3870 static void RememberWindowPosition(Object
*winobj
, ULONG id
)
3876 /* Loads ENV: prefs, remove our Window_ID chunk from the MUIW chunk, save prefs.
3877 * Do the same for ENVARC:
3878 * This function shouldnt really be in window.c, but rather in a file dealing
3879 * with prefs file stuff.
3881 static void ForgetWindowPosition(Object
*winobj
, ULONG id
)
3887 /**************************************************************************
3888 MUIM_Window_Snapshot
3889 **************************************************************************/
3890 IPTR
Window__MUIM_Snapshot(struct IClass
*cl
, Object
*obj
, struct MUIP_Window_Snapshot
*msg
)
3892 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3893 struct windowpos winp
;
3895 winp
.id
= data
->wd_ID
;
3896 w
=data
->wd_RenderInfo
.mri_Window
;
3899 winp
.x1
= w
->LeftEdge
; winp
.y1
= w
->TopEdge
;
3900 winp
.w1
= w
->GZZWidth
; winp
.h1
= w
->GZZHeight
;
3901 winp
.x2
=0; winp
.x2
=0; winp
.w2
=0; winp
.h2
=0; //to do save alt dims
3903 set(_app(obj
),MUIA_Application_SetWinPos
,&winp
);
3907 RememberWindowPosition(obj
, data
->wd_ID
);
3909 ForgetWindowPosition(obj
, data
->wd_ID
);
3915 BOOPSI_DISPATCHER(IPTR
, Window_Dispatcher
, cl
, obj
, msg
)
3917 switch (msg
->MethodID
)
3919 case OM_NEW
: return Window__OM_NEW(cl
, obj
, (struct opSet
*) msg
);
3920 case OM_DISPOSE
: return Window__OM_DISPOSE(cl
, obj
, msg
);
3921 case OM_SET
: return Window__OM_SET(cl
, obj
, (struct opSet
*)msg
);
3922 case OM_GET
: return Window__OM_GET(cl
, obj
, (struct opGet
*)msg
);
3923 case MUIM_FindUData
: return Window__MUIM_FindUData(cl
, obj
, (struct MUIP_FindUData
*)msg
);
3924 case MUIM_GetUData
: return Window__MUIM_GetUData(cl
, obj
, (struct MUIP_GetUData
*)msg
);
3925 case MUIM_SetUData
: return Window__MUIM_SetUData(cl
, obj
, (struct MUIP_SetUData
*)msg
);
3926 case MUIM_SetUDataOnce
: return Window__MUIM_SetUDataOnce(cl
, obj
, (struct MUIP_SetUDataOnce
*)msg
);
3927 case MUIM_Window_AddEventHandler
: return Window__MUIM_AddEventHandler(cl
, obj
, (APTR
)msg
);
3928 case MUIM_Window_RemEventHandler
: return Window__MUIM_RemEventHandler(cl
, obj
, (APTR
)msg
);
3929 case MUIM_ConnectParent
: return Window__MUIM_ConnectParent(cl
, obj
, (APTR
)msg
);
3930 case MUIM_DisconnectParent
: return Window__MUIM_DisconnectParent(cl
, obj
, (APTR
)msg
);
3931 case MUIM_Window_RecalcDisplay
: return Window__MUIM_RecalcDisplay(cl
, obj
, (APTR
)msg
);
3932 case MUIM_Window_Setup
: return Window__MUIM_Setup(cl
, obj
, (APTR
)msg
);
3933 case MUIM_Window_Cleanup
: return Window__MUIM_Cleanup(cl
, obj
, (APTR
)msg
);
3934 case MUIM_Window_AddControlCharHandler
: return Window__MUIM_AddControlCharHandler(cl
, obj
, (APTR
)msg
);
3935 case MUIM_Window_RemControlCharHandler
: return Window__MUIM_RemControlCharHandler(cl
, obj
, (APTR
)msg
);
3936 case MUIM_Window_DragObject
: return Window__MUIM_DragObject(cl
, obj
, (APTR
)msg
);
3937 case MUIM_Window_AllocGadgetID
: return Window__MUIM_AllocGadgetID(cl
, obj
, (APTR
)msg
);
3938 case MUIM_Window_FreeGadgetID
: return Window__MUIM_FreeGadgetID(cl
, obj
, (APTR
)msg
);
3939 case MUIM_Window_GetMenuCheck
: return Window__MUIM_GetMenuCheck(cl
, obj
, (APTR
)msg
);
3940 case MUIM_Window_SetMenuCheck
: return Window__MUIM_SetMenuCheck(cl
, obj
, (APTR
)msg
);
3941 case MUIM_Window_GetMenuState
: return Window__MUIM_GetMenuState(cl
, obj
, (APTR
)msg
);
3942 case MUIM_Window_SetMenuState
: return Window__MUIM_SetMenuState(cl
, obj
, (APTR
)msg
);
3943 case MUIM_Window_DrawBackground
: return Window__MUIM_DrawBackground(cl
, obj
, (APTR
)msg
);
3944 case MUIM_Window_ToFront
: return Window__MUIM_ToFront(cl
, obj
, (APTR
)msg
);
3945 case MUIM_Window_ToBack
: return Window__MUIM_ToBack(cl
, obj
, (APTR
)msg
);
3946 case MUIM_Window_ScreenToFront
: return Window__MUIM_ScreenToFront(cl
, obj
, (APTR
)msg
);
3947 case MUIM_Window_ScreenToBack
: return Window__MUIM_ScreenToBack(cl
, obj
, (APTR
)msg
);
3948 case MUIM_Window_ActionIconify
: return Window__MUIM_ActionIconify(cl
, obj
, (APTR
)msg
);
3949 case MUIM_Window_Snapshot
: return Window__MUIM_Snapshot(cl
, obj
, (APTR
)msg
);
3952 return DoSuperMethodA(cl
, obj
, msg
);
3954 BOOPSI_DISPATCHER_END
3960 const struct __MUIBuiltinClass _MUI_Window_desc
= {
3963 sizeof(struct MUI_WindowData
),
3964 (void*)Window_Dispatcher