2 Copyright 1999, David Le Corfec.
3 Copyright 2002-2014, 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>
17 #include <intuition/extensions.h>
19 #include <clib/alib_protos.h>
20 #include <graphics/gfxmacros.h>
21 #include <proto/exec.h>
22 #include <proto/intuition.h>
23 #include <proto/utility.h>
24 #include <proto/graphics.h>
25 #include <proto/commodities.h>
26 #include <proto/layers.h>
27 #include <proto/gadtools.h>
28 #include <proto/muimaster.h>
29 #include <proto/workbench.h>
31 #define MUI_OBSOLETE /* for the obsolete menu stuff */
35 #include "classes/window.h"
36 #include "classes/area.h"
38 #include "datatypescache.h"
40 #include "dragndrop.h"
42 #include "muimaster_intern.h"
47 extern struct Library
*MUIMasterBase
;
49 static const int __version
= 1;
50 static const int __revision
= 1;
52 #define IM(x) ((struct Image*)(x))
53 #define G(x) ((struct Gadget*)(x))
54 #define GADGETID(x) (((struct Gadget*)(x))->GadgetID)
56 /* this is for the cycle list */
63 /* For the gadget ids */
70 struct MUI_ImageSpec_intern
;
74 struct MUI_RenderInfo wd_RenderInfo
;
75 struct MUI_MinMax wd_MinMax
;
76 struct IBox wd_AltDim
; /* zoomed dimensions */
77 BOOL wd_ZoomGadget
; /* enable/disable zoomgadget (altdim stuff) */
78 APTR wd_MemoryPool
; /* for nodes and stuff to deallocate at
80 struct MinList wd_CycleChain
; /* objects activated with tab */
81 struct MinList wd_EHList
; /* event handlers */
82 struct MinList wd_CCList
; /* control chars */
83 struct MinList wd_IDList
; /* gadget ids */
84 ULONG wd_Events
; /* events received */
85 ULONG wd_CrtFlags
; /* window creation flags, see below */
86 Object
*wd_ActiveObject
; /* the active object */
87 Object
*wd_OldActive
; /* active object before window was closed */
88 APTR wd_DefaultObject
;
91 STRPTR wd_ScreenTitle
;
92 LONG wd_Height
; /* Current dimensions */
96 LONG wd_ReqHeight
; /* given by programmer */
98 APTR wd_RootObject
; /* unique child */
99 ULONG wd_Flags
; /* various status flags */
100 struct MUI_ImageSpec_intern
*wd_Background
;
101 ULONG wd_DisabledKeys
;
102 BOOL wd_NoMenus
; /* MUIA_Window_NoMenus */
104 Object
*wd_DragObject
; /* the object which is being dragged */
105 struct Window
*wd_DropWindow
; /* the destination window, for faster
107 Object
*wd_DropObject
; /* the destination object */
108 struct DragNDrop
*wd_dnd
;
109 struct MUI_DragImage
*wd_DragImage
;
110 struct AppWindow
*wd_AppWindow
;
112 Object
*wd_Menustrip
; /* The menustrip object which is actually
113 * used (either apps or windows or NULL) */
114 Object
*wd_ChildMenustrip
; /* If window has an own Menustrip */
115 struct Menu
*wd_Menu
; /* the intuition menustrip */
119 Object
*wd_DownButton
;
121 Object
*wd_HorizProp
;
122 Object
*wd_LeftButton
;
123 Object
*wd_RightButton
;
124 Object
*wd_RefWindow
;
126 Object
*wd_MUIGadget
;
128 Object
*wd_HelpObject
;
132 struct Screen
*wd_UserScreen
;
133 STRPTR wd_UserPublicScreen
;
134 LONG wd_XStore
; /* store MUIV_Window_LeftEdge_Centered Tags
135 * etc. because wd_X is overwritten by a
136 * value in CalcDimension. Popup windows work
137 * OK on AmiGG when main window is moved */
140 WORD wd_SleepCount
; /* MUIA_Window_Sleep nests */
143 #ifndef WFLG_SIZEGADGET
145 #define WFLG_CLOSEGADGET (1<<0) /* has close gadget */
146 #define WFLG_SIZEGADGET (1<<1) /* has size gadget */
147 #define WFLG_BACKDROP (1<<2) /* is backdrop window */
148 #define WFLG_BORDERLESS (1<<3) /* has no borders */
149 #define WFLG_DEPTHGADGET (1<<4) /* has depth gadget */
150 #define WFLG_DRAGBAR (1<<5) /* is draggable */
151 #define WFLG_SIZEBRIGHT (1<<6) /* size gadget is in right border */
156 #define MUIWF_OPENED (1<<0) /* window currently opened */
157 #define MUIWF_HIDDEN (1<<1) /* window currently iconified */
158 #define MUIWF_ACTIVE (1<<2) /* window currently active */
159 #define MUIWF_RESIZING (1<<4) /* window currently resizing */
160 #define MUIWF_DONTACTIVATE (1<<7) /* do not activate the window when
162 #define MUIWF_USERIGHTSCROLLER (1<<8) /* should have right scroller */
163 #define MUIWF_USEBOTTOMSCROLLER (1<<9) /* should have bottom scroller */
164 #define MUIWF_ERASEAREA (1<<10) /* Erase area after a window resize */
165 #define MUIWF_ISAPPWINDOW (1<<11) /* Is an AppWindow */
166 #define MUIWF_ISSUBWINDOW (1<<12) /* Don't get automatically disposed
168 #define MUIWF_BUBBLEMODE (1<<13) /* Quick bubble mode. Bubbles appear
169 * quick when moving */
170 #define MUIWF_OPENONUNHIDE (1<<14) /* Open the window when unhiding */
171 #define MUIWF_SCREENLOCKED (1<<15) /* A pub screen was locked in
172 * SetupRenderInfo. Unlock it in
173 * CleanupRenderInfo! */
174 #define MUIWF_OBJECTGOACTIVESENT (1<<16) /* A MUIM_GoActive msg was sent to
175 * window's active object */
176 #define MUIWF_TOOLBOX (1<<17) /* Window should be opened as
179 #define BUBBLEHELP_TICKER_FIRST 10
180 #define BUBBLEHELP_TICKER_LATER 3
184 struct MUI_NotifyData mnd
;
185 struct MUI_WindowData mwd
;
188 #define muiWindowData(obj) (&(((struct __dummyXFC3__ *)(obj))->mwd))
190 static void ActivateObject(struct MUI_WindowData
*data
);
191 static void HandleInputEvent(Object
*win
, struct MUI_WindowData
*data
,
192 struct IntuiMessage
*event
);
194 static ULONG
DoHalfshineGun(ULONG a
, ULONG b
)
196 ULONG val
= ((((a
) >> 24) + 3 * ((b
) >> 24)) / 4);
197 val
= val
+ (val
<< 8) + (val
<< 16) + (val
<< 24);
201 static ULONG
DoHalfshadowGun(ULONG a
, ULONG b
)
203 ULONG val
= ((((a
) >> 24) + 5 * ((b
) >> 24)) / 6);
204 val
= val
+ (val
<< 8) + (val
<< 16) + (val
<< 24);
208 static Object
*CreateSysimage(struct DrawInfo
*dri
, ULONG which
)
210 return NewObject(NULL
, "sysiclass",
211 SYSIA_DrawInfo
, (IPTR
) dri
, SYSIA_Which
, which
, TAG_DONE
);
214 static void EnqueueByPriAndAddress(struct List
*list
, struct Node
*node
)
216 struct Node
*scannode
;
218 /* Sort by priority and by node address, so that a
219 "remove - modify - enqueue" sequence will re-add
220 the node at the same place in the list it was
222 ForeachNode(list
, scannode
)
224 if (((struct Node
*)node
)->ln_Pri
> scannode
->ln_Pri
)
226 if (((struct Node
*)node
)->ln_Pri
== scannode
->ln_Pri
)
228 if ((IPTR
) node
> (IPTR
) scannode
)
233 Insert(list
, (struct Node
*)node
, scannode
->ln_Pred
);
236 static BOOL
InitCustomFrames(Object
*obj
, struct MUI_RenderInfo
*mri
)
240 for (i
= 0; i
< 16; i
++)
242 mri
->mri_FrameImage
[i
] = NULL
;
245 mri
->mri_FrameImage
[0] =
246 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
247 customframe_config_1
, mri
->mri_Screen
);
248 mri
->mri_FrameImage
[1] =
249 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
250 customframe_config_2
, mri
->mri_Screen
);
251 mri
->mri_FrameImage
[2] =
252 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
253 customframe_config_3
, mri
->mri_Screen
);
254 mri
->mri_FrameImage
[3] =
255 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
256 customframe_config_4
, mri
->mri_Screen
);
257 mri
->mri_FrameImage
[4] =
258 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
259 customframe_config_5
, mri
->mri_Screen
);
260 mri
->mri_FrameImage
[5] =
261 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
262 customframe_config_6
, mri
->mri_Screen
);
263 mri
->mri_FrameImage
[6] =
264 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
265 customframe_config_7
, mri
->mri_Screen
);
266 mri
->mri_FrameImage
[7] =
267 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
268 customframe_config_8
, mri
->mri_Screen
);
269 mri
->mri_FrameImage
[8] =
270 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
271 customframe_config_9
, mri
->mri_Screen
);
272 mri
->mri_FrameImage
[9] =
273 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
274 customframe_config_10
, mri
->mri_Screen
);
275 mri
->mri_FrameImage
[10] =
276 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
277 customframe_config_11
, mri
->mri_Screen
);
278 mri
->mri_FrameImage
[11] =
279 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
280 customframe_config_12
, mri
->mri_Screen
);
281 mri
->mri_FrameImage
[12] =
282 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
283 customframe_config_13
, mri
->mri_Screen
);
284 mri
->mri_FrameImage
[13] =
285 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
286 customframe_config_14
, mri
->mri_Screen
);
287 mri
->mri_FrameImage
[14] =
288 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
289 customframe_config_15
, mri
->mri_Screen
);
290 mri
->mri_FrameImage
[15] =
291 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
292 customframe_config_16
, mri
->mri_Screen
);
297 static void DisposeCustomFrames(struct MUI_RenderInfo
*mri
)
301 for (i
= 0; i
< 16; i
++)
303 dispose_custom_frame(mri
->mri_FrameImage
[i
]);
305 mri
->mri_FrameImage
[i
] = NULL
;
309 static BOOL
SetupRenderInfo(Object
*obj
, struct MUI_WindowData
*data
,
310 struct MUI_RenderInfo
*mri
)
312 ULONG rgbtable
[3 * 3];
317 /* TODO: Move this whole screen locking/opening stuff into the
318 * application class by creating methods for this purpose */
320 /* If no user screen has been specified try to open the application
322 if (!data
->wd_UserScreen
)
324 ULONG screenmodeid
= muiGlobalInfo(obj
)->mgi_Prefs
->screenmodeid
;
326 if (screenmodeid
!= ~0)
328 if (!muiGlobalInfo(obj
)->mgi_CustomScreen
)
330 muiGlobalInfo(obj
)->mgi_CustomScreen
= OpenScreenTags
332 SA_DisplayID
, screenmodeid
,
334 SA_FullPalette
, TRUE
, SA_LikeWorkbench
, TRUE
, TAG_DONE
);
335 /* It's fine if this fails as there is a fallback case below */
338 data
->wd_UserScreen
= muiGlobalInfo(obj
)->mgi_CustomScreen
;
341 if (data
->wd_UserScreen
)
343 mri
->mri_Screen
= data
->wd_UserScreen
;
347 if (data
->wd_UserPublicScreen
)
349 mri
->mri_Screen
= LockPubScreen(data
->wd_UserPublicScreen
);
351 else if (muiGlobalInfo(obj
)->mgi_Prefs
->publicscreen_name
352 && muiGlobalInfo(obj
)->mgi_Prefs
->publicscreen_name
[0])
355 LockPubScreen(muiGlobalInfo(obj
)->mgi_Prefs
->
357 // FIXME: open the public screen if necessary
360 if (mri
->mri_Screen
== NULL
)
362 mri
->mri_Screen
= LockPubScreen(NULL
);
363 if (mri
->mri_Screen
== NULL
)
369 // FIXME: is this the right place for this action?
371 && muiGlobalInfo(obj
)->mgi_Prefs
->publicscreen_pop_to_front
)
373 ScreenToFront(mri
->mri_Screen
);
376 data
->wd_Flags
|= MUIWF_SCREENLOCKED
;
379 if (!(mri
->mri_DrawInfo
= GetScreenDrawInfo(mri
->mri_Screen
)))
381 if (data
->wd_Flags
& MUIWF_SCREENLOCKED
)
383 UnlockPubScreen(NULL
, mri
->mri_Screen
);
384 data
->wd_Flags
&= ~MUIWF_SCREENLOCKED
;
389 if (!InitCustomFrames(obj
, mri
))
391 if (data
->wd_Flags
& MUIWF_SCREENLOCKED
)
393 UnlockPubScreen(NULL
, mri
->mri_Screen
);
394 data
->wd_Flags
&= ~MUIWF_SCREENLOCKED
;
399 mri
->mri_Colormap
= mri
->mri_Screen
->ViewPort
.ColorMap
;
400 mri
->mri_ScreenWidth
= mri
->mri_Screen
->Width
;
401 mri
->mri_ScreenHeight
= mri
->mri_Screen
->Height
;
403 if (mri
->mri_ScreenWidth
/ mri
->mri_ScreenHeight
< 2)
405 mri
->mri_Flags
|= MUIMRI_THINFRAMES
;
408 if (GetBitMapAttr(mri
->mri_Screen
->RastPort
.BitMap
, BMA_DEPTH
) >= 15)
410 mri
->mri_Flags
|= MUIMRI_TRUECOLOR
;
413 mri
->mri_PensStorage
[MPEN_SHINE
] =
414 mri
->mri_DrawInfo
->dri_Pens
[SHINEPEN
];
415 mri
->mri_PensStorage
[MPEN_BACKGROUND
] =
416 mri
->mri_DrawInfo
->dri_Pens
[BACKGROUNDPEN
];
417 mri
->mri_PensStorage
[MPEN_SHADOW
] =
418 mri
->mri_DrawInfo
->dri_Pens
[SHADOWPEN
];
419 mri
->mri_PensStorage
[MPEN_TEXT
] = mri
->mri_DrawInfo
->dri_Pens
[TEXTPEN
];
420 mri
->mri_PensStorage
[MPEN_FILL
] = mri
->mri_DrawInfo
->dri_Pens
[FILLPEN
];
422 GetRGB32(mri
->mri_Colormap
, mri
->mri_DrawInfo
->dri_Pens
[SHINEPEN
], 1,
424 GetRGB32(mri
->mri_Colormap
, mri
->mri_DrawInfo
->dri_Pens
[BACKGROUNDPEN
],
426 GetRGB32(mri
->mri_Colormap
, mri
->mri_DrawInfo
->dri_Pens
[SHADOWPEN
], 1,
429 mri
->mri_PensStorage
[MPEN_HALFSHINE
] = ObtainBestPenA
431 DoHalfshineGun(rgbtable
[0], rgbtable
[3]),
432 DoHalfshineGun(rgbtable
[1], rgbtable
[4]),
433 DoHalfshineGun(rgbtable
[2], rgbtable
[5]), NULL
);
435 mri
->mri_PensStorage
[MPEN_HALFSHADOW
] = ObtainBestPenA
437 DoHalfshadowGun(rgbtable
[6], rgbtable
[3]),
438 DoHalfshadowGun(rgbtable
[7], rgbtable
[4]),
439 DoHalfshadowGun(rgbtable
[8], rgbtable
[5]), NULL
);
441 /* I'm really not sure that MUI does this for MPEN_MARK, but it seems
442 * mostly acceptable -dlc */
443 mri
->mri_PensStorage
[MPEN_MARK
] = ObtainBestPenA
444 (mri
->mri_Colormap
, 0xf4f4f4f4, 0xb5b5b5b5, 0x8b8b8b8b, NULL
);
446 mri
->mri_Pens
= mri
->mri_PensStorage
;
448 for (i
= 0; i
< -MUIV_Font_NegCount
; i
++)
450 mri
->mri_Fonts
[i
] = NULL
;
453 if (data
->wd_Flags
& MUIWF_USEBOTTOMSCROLLER
)
455 mri
->mri_LeftImage
= CreateSysimage(mri
->mri_DrawInfo
, LEFTIMAGE
);
456 mri
->mri_RightImage
= CreateSysimage(mri
->mri_DrawInfo
, RIGHTIMAGE
);
460 mri
->mri_LeftImage
= mri
->mri_RightImage
= NULL
;
463 if (data
->wd_Flags
& MUIWF_USERIGHTSCROLLER
)
465 mri
->mri_UpImage
= CreateSysimage(mri
->mri_DrawInfo
, UPIMAGE
);
466 mri
->mri_DownImage
= CreateSysimage(mri
->mri_DrawInfo
, DOWNIMAGE
);
470 mri
->mri_UpImage
= mri
->mri_DownImage
= NULL
;
473 if ((data
->wd_Flags
& MUIWF_USEBOTTOMSCROLLER
) ||
474 (data
->wd_Flags
& MUIWF_USERIGHTSCROLLER
))
475 mri
->mri_SizeImage
= CreateSysimage(mri
->mri_DrawInfo
, SIZEIMAGE
);
477 mri
->mri_SizeImage
= NULL
;
479 if (data
->wd_CrtFlags
& WFLG_BORDERLESS
)
481 /* In fact borderless windows could also have borders (if they have
482 * a window title e.g. but since they look ugly anyway we ignore it
484 mri
->mri_BorderLeft
= 0;
485 mri
->mri_BorderRight
= 0;
486 mri
->mri_BorderTop
= 0;
487 mri
->mri_BorderBottom
= 0;
491 mri
->mri_BorderLeft
= mri
->mri_Screen
->WBorLeft
;
493 mri
->mri_Screen
->WBorTop
+ mri
->mri_Screen
->Font
->ta_YSize
+ 1;
495 NewObject(NULL
, "sysiclass", SYSIA_DrawInfo
,
496 (IPTR
) mri
->mri_DrawInfo
, SYSIA_Which
, SIZEIMAGE
, TAG_DONE
);
499 GetAttr(IA_Height
, temp_obj
, &val
);
500 DisposeObject(temp_obj
);
501 mri
->mri_BorderBottom
= val
;
504 mri
->mri_BorderBottom
= mri
->mri_Screen
->WBorBottom
;
510 static void CleanupRenderInfo(Object
*obj
, struct MUI_WindowData
*data
,
511 struct MUI_RenderInfo
*mri
)
515 DisposeCustomFrames(mri
);
517 if (mri
->mri_LeftImage
)
519 DisposeObject(mri
->mri_LeftImage
);
520 mri
->mri_LeftImage
= NULL
;
522 if (mri
->mri_RightImage
)
524 DisposeObject(mri
->mri_RightImage
);
525 mri
->mri_RightImage
= NULL
;
527 if (mri
->mri_UpImage
)
529 DisposeObject(mri
->mri_UpImage
);
530 mri
->mri_UpImage
= NULL
;
532 if (mri
->mri_DownImage
)
534 DisposeObject(mri
->mri_DownImage
);
535 mri
->mri_DownImage
= NULL
;
537 if (mri
->mri_SizeImage
)
539 DisposeObject(mri
->mri_SizeImage
);
540 mri
->mri_SizeImage
= NULL
;
543 /* bug("CleanupRenderInfo\n"); */
544 for (i
= 0; i
< -MUIV_Font_NegCount
; i
++)
546 if (mri
->mri_Fonts
[i
])
548 /* bug("CleanupRenderInfo: closing font %p (%s/%d)\n", */
549 /* mri->mri_Fonts[i], */
550 /* mri->mri_Fonts[i]->tf_Message.mn_Node.ln_Name, */
551 /* mri->mri_Fonts[i]->tf_YSize); */
552 CloseFont(mri
->mri_Fonts
[i
]);
553 mri
->mri_Fonts
[i
] = NULL
;
556 ReleasePen(mri
->mri_Colormap
, mri
->mri_PensStorage
[MPEN_MARK
]);
557 ReleasePen(mri
->mri_Colormap
, mri
->mri_PensStorage
[MPEN_HALFSHADOW
]);
558 ReleasePen(mri
->mri_Colormap
, mri
->mri_PensStorage
[MPEN_HALFSHINE
]);
559 FreeScreenDrawInfo(mri
->mri_Screen
, mri
->mri_DrawInfo
);
560 mri
->mri_DrawInfo
= NULL
;
562 /* If a custom screen has been opened by zune, close it as soon as zero
563 * windows are opened. See above for comments about refactorization. */
564 if (muiGlobalInfo(obj
)->mgi_CustomScreen
)
566 BOOL screenclose
= TRUE
;
567 Object
*_app
= _app(obj
);
570 struct List
*store
= NULL
;
571 get(_app
, MUIA_Application_WindowList
, &store
);
574 if (!IsListEmpty(store
))
580 /* If the window's user screen really was the custom screen,
581 * clear the reference */
582 if (data
->wd_UserScreen
== muiGlobalInfo(obj
)->mgi_CustomScreen
)
583 data
->wd_UserScreen
= NULL
;
585 CloseScreen(muiGlobalInfo(obj
)->mgi_CustomScreen
);
586 muiGlobalInfo(obj
)->mgi_CustomScreen
= NULL
;
590 if (data
->wd_Flags
& MUIWF_SCREENLOCKED
)
592 UnlockPubScreen(NULL
, mri
->mri_Screen
);
593 data
->wd_Flags
&= ~MUIWF_SCREENLOCKED
;
595 mri
->mri_Screen
= NULL
;
598 static void ShowRenderInfo(struct MUI_RenderInfo
*mri
)
600 if (mri
->mri_BufferBM
)
602 mri
->mri_RastPort
= &mri
->mri_BufferRP
;
606 mri
->mri_RastPort
= mri
->mri_Window
->RPort
;
610 static void HideRenderInfo(struct MUI_RenderInfo
*mri
)
612 mri
->mri_RastPort
= NULL
;
615 static ULONG
GetDefaultEvents(void)
617 return IDCMP_NEWSIZE
| IDCMP_CHANGEWINDOW
| IDCMP_REFRESHWINDOW
618 | IDCMP_MOUSEBUTTONS
| IDCMP_MOUSEMOVE
| IDCMP_MENUPICK
619 | IDCMP_CLOSEWINDOW
| IDCMP_RAWKEY
| IDCMP_INTUITICKS
620 | IDCMP_ACTIVEWINDOW
| IDCMP_INACTIVEWINDOW
| IDCMP_GADGETUP
;
623 static void ChangeEvents(struct MUI_WindowData
*data
, ULONG new_events
)
626 struct MUI_EventHandlerNode
*ehn
;
627 ULONG old_events
= data
->wd_Events
;
629 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
631 ehn
= (struct MUI_EventHandlerNode
*)mn
;
632 new_events
|= ehn
->ehn_Events
;
635 /* sba: kill the IDCMP_VANILLAKEY flag. MUI doesn't do this but programs
636 ** which use this will behave different if they request for this flag
639 new_events
&= ~IDCMP_VANILLAKEY
;
641 data
->wd_Events
= new_events
;
642 if ((old_events
!= new_events
) && (data
->wd_Flags
& MUIWF_OPENED
))
644 ModifyIDCMP(data
->wd_RenderInfo
.mri_Window
, new_events
);
648 static void CalcWindowPosition(Object
*obj
, struct MUI_WindowData
*data
);
649 static void CreateWindowScrollbars(Object
*obj
,
650 struct MUI_WindowData
*data
);
651 static void CalcAltDimensions(Object
*obj
, struct MUI_WindowData
*data
);
652 static void UndisplayWindow(Object
*obj
, struct MUI_WindowData
*data
);
653 static struct ObjNode
*FindObjNode(struct MinList
*list
, Object
*obj
);
655 static BOOL
DisplayWindow(Object
*obj
, struct MUI_WindowData
*data
)
658 ULONG flags
= data
->wd_CrtFlags
;
660 ULONG backfill
, buttons
;
662 struct Menu
*menu
= NULL
;
663 struct NewMenu
*newmenu
= NULL
;
668 if (!(data
->wd_Flags
& MUIWF_DONTACTIVATE
))
670 flags
|= WFLG_ACTIVATE
;
673 /* Toolboxes are handled differently on AmigaOS */
675 if (data
->wd_Flags
& MUIWF_TOOLBOX
)
676 flags
|= WFLG_TOOLBOX
;
679 if (data
->wd_MinMax
.MinHeight
== data
->wd_MinMax
.MaxHeight
680 && data
->wd_MinMax
.MinWidth
== data
->wd_MinMax
.MaxWidth
)
681 flags
&= ~WFLG_SIZEGADGET
;
683 if (!(flags
& WFLG_SIZEBRIGHT
))
684 flags
|= WFLG_SIZEBBOTTOM
;
686 CalcWindowPosition(obj
, data
);
688 if ((visinfo
= GetVisualInfoA(data
->wd_RenderInfo
.mri_Screen
, NULL
)))
690 if (data
->wd_Menustrip
)
692 get(data
->wd_Menustrip
, MUIA_Menuitem_NewMenu
, &newmenu
);
695 if ((menu
= CreateMenusA(newmenu
, NULL
)))
697 struct TagItem tags
[] = {
698 {GTMN_NewLookMenus
, TRUE
},
699 {TAG_DONE
, (IPTR
) NULL
}
701 LayoutMenusA(menu
, visinfo
, tags
);
705 FreeVisualInfo(visinfo
);
708 CreateWindowScrollbars(obj
, data
);
709 CalcAltDimensions(obj
, data
);
710 altdims
= data
->wd_AltDim
;
712 /* hack to account for border size, as we only know the innersize and
713 * must give the total size.
716 data
->wd_RenderInfo
.mri_Screen
->WBorLeft
+
717 data
->wd_RenderInfo
.mri_Screen
->WBorRight
;
719 data
->wd_RenderInfo
.mri_Screen
->WBorTop
+
720 data
->wd_RenderInfo
.mri_Screen
->WBorBottom
+
721 data
->wd_RenderInfo
.mri_DrawInfo
->dri_Font
->tf_YSize
+ 1;
723 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_redraw
==
724 WINDOW_REDRAW_WITHOUT_CLEAR
)
725 backfill
= WA_BackFill
;
727 backfill
= TAG_IGNORE
;
729 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_refresh
==
730 WINDOW_REFRESH_SMART
)
731 flags
&= ~WFLG_SIMPLE_REFRESH
;
732 set(_app(obj
), MUIA_Application_SearchWinId
, data
->wd_ID
);
733 struct windowpos
*winp
= 0;
734 get(_app(obj
), MUIA_Application_GetWinPos
, &winp
);
737 if (data
->wd_RenderInfo
.mri_ScreenWidth
>
738 (data
->wd_X
+ data
->wd_Width
))
740 data
->wd_X
= winp
->x1
;
741 data
->wd_Width
= winp
->w1
;
743 if (data
->wd_RenderInfo
.mri_ScreenHeight
>
744 (data
->wd_Y
+ data
->wd_Height
))
746 data
->wd_Y
= winp
->y1
;
747 data
->wd_Height
= winp
->h1
;
752 (data
->wd_VertProp
!=
753 NULL
) ? data
->wd_VertProp
: data
->wd_HorizProp
;
754 buttons
= muiGlobalInfo(obj
)->mgi_Prefs
->window_buttons
;
758 WA_Left
, (IPTR
) data
->wd_X
,
759 WA_Top
, (IPTR
) data
->wd_Y
,
760 WA_Flags
, (IPTR
) flags
,
763 TAG_IGNORE
, (IPTR
) data
->wd_Title
,
764 data
->wd_ScreenTitle
?
766 TAG_IGNORE
, (IPTR
) data
->wd_ScreenTitle
,
767 WA_CustomScreen
, (IPTR
) data
->wd_RenderInfo
.mri_Screen
,
768 WA_InnerWidth
, (IPTR
) data
->wd_Width
,
769 WA_InnerHeight
, (IPTR
) data
->wd_Height
,
770 WA_AutoAdjust
, (IPTR
) TRUE
, WA_NewLookMenus
, (IPTR
) TRUE
,
771 /* AmigaOS v4 extension */
773 WA_ToolBox
, (IPTR
) ! !(data
->wd_Flags
& MUIWF_TOOLBOX
),
775 /* MorphOS extensions */
776 #ifdef WA_ExtraGadget_MUI
778 (IPTR
) ((buttons
& MUIV_Window_Button_MUI
) != 0) ? TRUE
: FALSE
,
779 WA_ExtraGadget_PopUp
,
780 (IPTR
) ((buttons
& MUIV_Window_Button_Popup
) != 0) ? TRUE
: FALSE
,
781 WA_ExtraGadget_Snapshot
,
782 (IPTR
) ((buttons
& MUIV_Window_Button_Snapshot
) !=
783 0) ? TRUE
: FALSE
, WA_ExtraGadget_Iconify
,
784 (IPTR
) ((buttons
& MUIV_Window_Button_Iconify
) != 0) ? TRUE
: FALSE
,
788 TAG_IGNORE
, (IPTR
) TRUE
,
789 WA_Gadgets
, (IPTR
) gadgets
,
790 data
->wd_ZoomGadget
?
792 TAG_IGNORE
, (IPTR
) & altdims
,
793 backfill
, (IPTR
) LAYERS_NOBACKFILL
, TAG_DONE
);
798 int hborders
= win
->BorderLeft
+ win
->BorderRight
;
799 int vborders
= win
->BorderTop
+ win
->BorderBottom
;
801 /* recalc window size (which will hopefully equal our requested
803 data
->wd_Width
= win
->GZZWidth
;
804 data
->wd_Height
= win
->GZZHeight
;
806 /* set window limits according to window contents */
808 (win
, data
->wd_MinMax
.MinWidth
+ hborders
,
809 data
->wd_MinMax
.MinHeight
+ vborders
,
810 data
->wd_MinMax
.MaxWidth
+ hborders
,
811 data
->wd_MinMax
.MaxHeight
+ vborders
);
813 win
->UserData
= (BYTE
*) data
->wd_RenderInfo
.mri_WindowObject
;
814 win
->UserPort
= muiGlobalInfo(obj
)->mgi_WindowsPort
;
815 /* Same port for all windows */
816 ModifyIDCMP(win
, data
->wd_Events
);
818 data
->wd_RenderInfo
.mri_Window
= win
;
819 data
->wd_RenderInfo
.mri_VertProp
= data
->wd_VertProp
;
820 data
->wd_RenderInfo
.mri_HorizProp
= data
->wd_HorizProp
;
821 SetDrMd(win
->RPort
, JAM1
);
822 //text is drawn wrong in toolbarclass if not set
826 data
->wd_Menu
= menu
;
827 SetMenuStrip(win
, menu
);
830 if (flags
& WFLG_ACTIVATE
)
832 data
->wd_Flags
|= MUIWF_ACTIVE
;
835 if (data
->wd_Flags
& MUIWF_ISAPPWINDOW
)
837 data
->wd_AppWindow
= AddAppWindowA(0, (IPTR
) obj
, win
,
838 muiGlobalInfo(obj
)->mgi_AppPort
, NULL
);
846 UndisplayWindow(obj
, data
);
852 static void UndisplayWindow(Object
*obj
, struct MUI_WindowData
*data
)
854 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
856 ((muiGlobalInfo(obj
)->mgi_Prefs
->window_position
==
857 WINDOW_POSITION_REMEMBER_ON_EXIT
)
858 || (muiGlobalInfo(obj
)->mgi_Prefs
->window_position
==
859 WINDOW_POSITION_SAVE_ON_EXIT
));
861 if (((data
->wd_XStore
>= 0) && (data
->wd_YStore
>= 0)) || prefssnap
)
863 DoMethod(obj
, MUIM_Window_Snapshot
, 1);
866 data
->wd_RenderInfo
.mri_Window
= NULL
;
867 data
->wd_RenderInfo
.mri_VertProp
= NULL
;
868 data
->wd_RenderInfo
.mri_HorizProp
= NULL
;
870 data
->wd_Flags
&= ~MUIWF_ACTIVE
;
874 /* store position and size */
875 if (data
->wd_XStore
>= 0)
876 data
->wd_X
= win
->LeftEdge
;
878 data
->wd_X
= data
->wd_XStore
;
879 if (data
->wd_YStore
>= 0)
880 data
->wd_Y
= win
->TopEdge
;
882 data
->wd_Y
= data
->wd_YStore
;
883 data
->wd_Width
= win
->GZZWidth
;
884 data
->wd_Height
= win
->GZZHeight
;
889 FreeMenus(data
->wd_Menu
);
890 data
->wd_Menu
= NULL
;
895 struct IntuiMessage
*msg
, *succ
;
897 /* remove all messages pending for this window */
900 (struct IntuiMessage
*)win
->UserPort
->mp_MsgList
.lh_Head
;
902 (struct IntuiMessage
*)msg
->ExecMessage
.mn_Node
.
903 ln_Succ
); msg
= succ
)
905 if (msg
->IDCMPWindow
== win
)
907 Remove((struct Node
*)msg
);
908 ReplyMsg((struct Message
*)msg
);
911 win
->UserPort
= NULL
;
916 /* D(bug("before CloseWindow\n")); */
918 /* D(bug("after CloseWindow\n")); */
921 #define DISPOSEGADGET(x) \
924 DoMethod(obj, MUIM_Window_FreeGadgetID,\
925 ((struct Gadget*)x)->GadgetID);\
930 DISPOSEGADGET(data
->wd_VertProp
);
931 DISPOSEGADGET(data
->wd_UpButton
);
932 DISPOSEGADGET(data
->wd_DownButton
);
933 DISPOSEGADGET(data
->wd_HorizProp
);
934 DISPOSEGADGET(data
->wd_LeftButton
);
935 DISPOSEGADGET(data
->wd_RightButton
);
940 static VOID
RefreshWindow(Object
*oWin
, struct MUI_WindowData
*data
)
942 if (data
->wd_Flags
& MUIWF_RESIZING
)
944 //LONG left,top,right,bottom;
945 if (MUI_BeginRefresh(&data
->wd_RenderInfo
, 0))
947 MUI_EndRefresh(&data
->wd_RenderInfo
, 0);
949 RefreshWindowFrame(data
->wd_RenderInfo
.mri_Window
);
951 data
->wd_Flags
&= ~MUIWF_RESIZING
;
952 _width(data
->wd_RootObject
) = data
->wd_Width
;
953 _height(data
->wd_RootObject
) = data
->wd_Height
;
954 DoMethod(data
->wd_RootObject
, MUIM_Layout
);
955 DoShowMethod(data
->wd_RootObject
);
957 if (muiGlobalInfo(oWin
)->mgi_Prefs
->window_redraw
==
958 WINDOW_REDRAW_WITH_CLEAR
)
960 LONG left
, top
, width
, height
;
962 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
963 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
;
965 data
->wd_RenderInfo
.mri_Window
->Width
-
966 data
->wd_RenderInfo
.mri_Window
->BorderRight
- left
;
968 data
->wd_RenderInfo
.mri_Window
->Height
-
969 data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
971 if (data
->wd_Flags
& MUIWF_ERASEAREA
)
973 //D(bug("%d:zune_imspec_draw(%p) "
974 // "l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
975 // __LINE__, data->wd_Background, left, top, width,
976 // height, left, top));
977 zune_imspec_draw(data
->wd_Background
,
978 &data
->wd_RenderInfo
, left
, top
, width
, height
,
981 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWALL
);
984 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWOBJECT
);
985 // but should only draw focus without using MUIM_GoActive !
986 ActivateObject(data
);
990 if (MUI_BeginRefresh(&data
->wd_RenderInfo
, 0))
992 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWALL
);
993 // but should only draw focus without using MUIM_GoActive !
994 ActivateObject(data
);
995 MUI_EndRefresh(&data
->wd_RenderInfo
, 0);
1001 /* Initialize data->wd_X and data->wd_Y for DisplayWindow */
1002 /* FIXME 20030817: needs some fixing, seems not fully implemented */
1003 static void CalcWindowPosition(Object
*obj
, struct MUI_WindowData
*data
)
1005 data
->wd_XStore
= data
->wd_X
;
1006 data
->wd_YStore
= data
->wd_Y
;
1007 if (NULL
== data
->wd_RefWindow
)
1009 /* The following calculations are not very correct, the size and
1010 * dragbar are ignored also the current overscan view */
1011 if (data
->wd_X
== MUIV_Window_LeftEdge_Centered
)
1014 (data
->wd_RenderInfo
.mri_Screen
->ViewPort
.DWidth
-
1015 data
->wd_Width
) / 2 -
1016 data
->wd_RenderInfo
.mri_Screen
->LeftEdge
;
1018 else if (data
->wd_X
== MUIV_Window_LeftEdge_Moused
)
1020 data
->wd_X
= data
->wd_RenderInfo
.mri_Screen
->MouseX
;
1023 if (data
->wd_Y
== MUIV_Window_TopEdge_Centered
)
1026 (data
->wd_RenderInfo
.mri_Screen
->ViewPort
.DHeight
-
1027 data
->wd_Height
) / 2 -
1028 data
->wd_RenderInfo
.mri_Screen
->TopEdge
;
1030 else if (data
->wd_Y
== MUIV_Window_TopEdge_Moused
)
1032 data
->wd_Y
= data
->wd_RenderInfo
.mri_Screen
->MouseY
;
1034 else if (data
->wd_Y
<= MUIV_Window_TopEdge_Delta(0))
1036 data
->wd_Y
= data
->wd_RenderInfo
.mri_Screen
->BarHeight
+ 1
1037 + MUIV_Window_TopEdge_Delta(0) - data
->wd_Y
;
1045 get(data
->wd_RefWindow
, MUIA_Window_Width
, &w
);
1046 get(data
->wd_RefWindow
, MUIA_Window_LeftEdge
, &x
);
1048 if (data
->wd_X
== MUIV_Window_LeftEdge_Centered
)
1050 data
->wd_X
= x
+ (w
- data
->wd_Width
) / 2;
1057 get(data
->wd_RefWindow
, MUIA_Window_Height
, &h
);
1058 get(data
->wd_RefWindow
, MUIA_Window_TopEdge
, &y
);
1060 if (data
->wd_Y
== MUIV_Window_TopEdge_Centered
)
1062 /* D(bug("y=%ld, h=%ld, wdh=%ld\n", y, h, data->wd_Height)); */
1063 data
->wd_Y
= y
+ (h
- data
->wd_Height
) / 2;
1065 else if (data
->wd_Y
<= MUIV_Window_TopEdge_Delta(0))
1067 /* ??? surely incorrect implementation */
1068 data
->wd_Y
= y
+ 1 + MUIV_Window_TopEdge_Delta(0) - data
->wd_Y
;
1077 /* Initialize data->wd_AltDim for DisplayWindow */
1078 static void CalcAltDimensions(Object
*obj
, struct MUI_WindowData
*data
)
1080 /* Calculate alternate (zoomed) dimensions.
1082 if (data
->wd_AltDim
.Top
== MUIV_Window_AltTopEdge_NoChange
)
1083 data
->wd_AltDim
.Top
= ~0;
1084 else if (data
->wd_AltDim
.Top
== MUIV_Window_AltTopEdge_Centered
)
1085 data
->wd_AltDim
.Top
=
1086 (data
->wd_RenderInfo
.mri_Screen
->Height
- data
->wd_Height
) / 2;
1087 else if (data
->wd_AltDim
.Top
== MUIV_Window_AltTopEdge_Moused
)
1088 /* ? */ data
->wd_AltDim
.Top
= ~0;
1090 if (data
->wd_AltDim
.Left
== MUIV_Window_AltLeftEdge_NoChange
)
1091 data
->wd_AltDim
.Left
= ~0;
1092 else if (data
->wd_AltDim
.Left
== MUIV_Window_AltLeftEdge_Centered
)
1093 data
->wd_AltDim
.Left
=
1094 (data
->wd_RenderInfo
.mri_Screen
->Width
- data
->wd_Width
) / 2;
1095 else if (data
->wd_AltDim
.Left
== MUIV_Window_AltLeftEdge_Moused
)
1096 /* ? */ data
->wd_AltDim
.Left
= ~0;
1099 (MUIV_Window_AltWidth_MinMax(100),
1100 data
->wd_AltDim
.Width
, MUIV_Window_AltWidth_MinMax(0)))
1102 data
->wd_AltDim
.Width
= data
->wd_MinMax
.MinWidth
1103 - data
->wd_AltDim
.Width
1104 * (data
->wd_MinMax
.MaxWidth
- data
->wd_MinMax
.MinWidth
);
1108 (MUIV_Window_AltWidth_Screen(100),
1109 data
->wd_AltDim
.Width
, MUIV_Window_AltWidth_Screen(0)))
1111 data
->wd_AltDim
.Width
= data
->wd_RenderInfo
.mri_ScreenWidth
1112 * (-(data
->wd_AltDim
.Width
+ 200)) / 100;
1116 (MUIV_Window_AltWidth_Visible(100),
1117 data
->wd_AltDim
.Width
, MUIV_Window_AltWidth_Visible(0)))
1119 data
->wd_AltDim
.Width
= data
->wd_RenderInfo
.mri_ScreenWidth
1120 * (-(data
->wd_AltDim
.Width
+ 100)) / 100;
1124 (MUIV_Window_AltHeight_MinMax(100),
1125 data
->wd_AltDim
.Height
, MUIV_Window_AltHeight_MinMax(0)))
1127 data
->wd_AltDim
.Height
= data
->wd_MinMax
.MinHeight
1128 - data
->wd_AltDim
.Height
1129 * (data
->wd_MinMax
.MaxHeight
- data
->wd_MinMax
.MinHeight
);
1133 (MUIV_Window_AltHeight_Screen(100),
1134 data
->wd_AltDim
.Height
, MUIV_Window_AltHeight_Screen(0)))
1136 data
->wd_AltDim
.Height
= data
->wd_RenderInfo
.mri_ScreenHeight
1137 * (-(data
->wd_AltDim
.Height
+ 200)) / 100;
1141 (MUIV_Window_AltHeight_Visible(100),
1142 data
->wd_AltDim
.Height
, MUIV_Window_AltHeight_Visible(0)))
1144 data
->wd_AltDim
.Height
= data
->wd_RenderInfo
.mri_ScreenHeight
1145 * (-(data
->wd_AltDim
.Height
+ 100)) / 100;
1148 data
->wd_AltDim
.Width
= CLAMP
1149 (data
->wd_AltDim
.Width
, data
->wd_MinMax
.MinWidth
,
1150 data
->wd_MinMax
.MaxWidth
);
1151 data
->wd_AltDim
.Height
= CLAMP
1152 (data
->wd_AltDim
.Height
, data
->wd_MinMax
.MinHeight
,
1153 data
->wd_MinMax
.MaxHeight
);
1157 /* Create horiz/vert window scrollbars for DisplayWindow */
1158 static void CreateWindowScrollbars(Object
*obj
,
1159 struct MUI_WindowData
*data
)
1161 struct MUI_RenderInfo
*mri
= &data
->wd_RenderInfo
;
1162 Object
*firstgad
= NULL
;
1163 Object
*prevgad
= NULL
;
1166 /* Create the right border scrollers now if requested */
1167 if (data
->wd_Flags
& MUIWF_USERIGHTSCROLLER
)
1171 voffset
= IM(mri
->mri_DownImage
)->Width
/ 4;
1173 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1174 firstgad
= prevgad
= data
->wd_VertProp
= NewObject
1175 (NULL
, "propgclass",
1176 GA_RelRight
, 1 - (IM(mri
->mri_UpImage
)->Width
- voffset
),
1177 GA_Top
, mri
->mri_BorderTop
+ 2,
1178 GA_Width
, IM(mri
->mri_UpImage
)->Width
- voffset
* 2,
1179 GA_RelHeight
, -(mri
->mri_BorderTop
+ 2)
1180 - IM(mri
->mri_UpImage
)->Height
1181 - IM(mri
->mri_DownImage
)->Height
1182 - IM(mri
->mri_SizeImage
)->Height
- 2,
1183 GA_RightBorder
, TRUE
,
1185 PGA_Borderless
, TRUE
,
1187 PGA_Freedom
, FREEVERT
,
1190 PGA_Visible
, 1, ICA_TARGET
, ICTARGET_IDCMP
, TAG_DONE
);
1192 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1193 prevgad
= data
->wd_UpButton
= NewObject
1194 (NULL
, "buttongclass",
1195 GA_Image
, (IPTR
) mri
->mri_UpImage
,
1196 GA_RelRight
, 1 - IM(mri
->mri_UpImage
)->Width
,
1197 GA_RelBottom
, 1 - IM(mri
->mri_UpImage
)->Height
1198 - IM(mri
->mri_DownImage
)->Height
1199 - IM(mri
->mri_SizeImage
)->Height
,
1200 GA_RightBorder
, TRUE
,
1201 GA_Previous
, (IPTR
) prevgad
,
1202 GA_ID
, id
, ICA_TARGET
, ICTARGET_IDCMP
, TAG_DONE
);
1204 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1205 prevgad
= data
->wd_DownButton
= NewObject
1206 (NULL
, "buttongclass",
1207 GA_Image
, (IPTR
) mri
->mri_DownImage
,
1208 GA_RelRight
, 1 - IM(mri
->mri_DownImage
)->Width
,
1209 GA_RelBottom
, 1 - IM(mri
->mri_DownImage
)->Height
1210 - IM(mri
->mri_SizeImage
)->Height
,
1211 GA_RightBorder
, TRUE
,
1212 GA_Previous
, (IPTR
) prevgad
,
1213 GA_ID
, id
, ICA_TARGET
, ICTARGET_IDCMP
, TAG_DONE
);
1216 /* Create the bottom border scrollers now if requested */
1217 if (data
->wd_Flags
& MUIWF_USEBOTTOMSCROLLER
)
1221 hoffset
= IM(mri
->mri_RightImage
)->Height
/ 4;
1223 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1224 prevgad
= data
->wd_HorizProp
= NewObject
1225 (NULL
, "propgclass",
1226 GA_RelBottom
, 1 - (IM(mri
->mri_LeftImage
)->Height
- hoffset
),
1227 GA_Left
, mri
->mri_BorderLeft
,
1228 GA_Height
, IM(mri
->mri_LeftImage
)->Height
1230 GA_RelWidth
, -(mri
->mri_BorderLeft
)
1231 - IM(mri
->mri_LeftImage
)->Width
1232 - IM(mri
->mri_RightImage
)->Width
1233 - IM(mri
->mri_SizeImage
)->Width
1235 GA_BottomBorder
, TRUE
,
1237 prevgad
? GA_Previous
: TAG_IGNORE
, (IPTR
) prevgad
,
1238 PGA_Borderless
, TRUE
,
1240 PGA_Freedom
, FREEHORIZ
,
1243 PGA_Visible
, 1, ICA_TARGET
, ICTARGET_IDCMP
, TAG_DONE
);
1248 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1249 prevgad
= data
->wd_LeftButton
= NewObject
1250 (NULL
, "buttongclass",
1251 GA_Image
, (IPTR
) mri
->mri_LeftImage
,
1252 GA_RelRight
, 1 - IM(mri
->mri_LeftImage
)->Width
1253 - IM(mri
->mri_RightImage
)->Width
1254 - IM(mri
->mri_SizeImage
)->Width
,
1255 GA_RelBottom
, 1 - IM(mri
->mri_LeftImage
)->Height
,
1256 GA_BottomBorder
, TRUE
,
1257 GA_Previous
, (IPTR
) prevgad
,
1258 GA_ID
, id
, ICA_TARGET
, ICTARGET_IDCMP
, TAG_DONE
);
1260 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1261 prevgad
= data
->wd_RightButton
= NewObject
1262 (NULL
, "buttongclass",
1263 GA_Image
, (IPTR
) mri
->mri_RightImage
,
1264 GA_RelRight
, 1 - IM(mri
->mri_RightImage
)->Width
1265 - IM(mri
->mri_SizeImage
)->Width
,
1266 GA_RelBottom
, 1 - IM(mri
->mri_RightImage
)->Height
,
1267 GA_BottomBorder
, TRUE
,
1268 GA_Previous
, (IPTR
) prevgad
,
1269 GA_ID
, id
, ICA_TARGET
, ICTARGET_IDCMP
, TAG_DONE
);
1273 /* return FALSE only if no resize (dx=dy=0) occured */
1274 static BOOL
WindowResize(struct MUI_WindowData
*data
)
1276 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
1277 int hborders
= win
->BorderLeft
+ win
->BorderRight
;
1278 int vborders
= win
->BorderTop
+ win
->BorderBottom
;
1279 WORD dx
= data
->wd_Width
- win
->Width
+ hborders
;
1280 WORD dy
= data
->wd_Height
- win
->Height
+ vborders
;
1282 /* Temporarily disable window limits to let SizeWindow below work
1283 regardless of the previous limits */
1284 WindowLimits(win
, 1, 1, -1, -1);
1285 /* D(bug("_zune_window_resize : dx=%d, dy=%d\n", dx, dy)); */
1286 SizeWindow(win
, dx
, dy
);
1288 /* Set new window limits */
1290 (win
, data
->wd_MinMax
.MinWidth
+ hborders
,
1291 data
->wd_MinMax
.MinHeight
+ vborders
,
1292 data
->wd_MinMax
.MaxWidth
+ hborders
,
1293 data
->wd_MinMax
.MaxHeight
+ vborders
);
1298 static void KillHelpBubble(struct MUI_WindowData
*data
, Object
*obj
,
1299 BOOL kill_bubblemode
)
1301 if (data
->wd_HelpObject
)
1303 DoMethod(data
->wd_HelpObject
, MUIM_DeleteBubble
,
1304 (IPTR
) data
->wd_HelpBubble
);
1305 data
->wd_HelpObject
= NULL
;
1306 data
->wd_HelpBubble
= NULL
;
1309 if (kill_bubblemode
)
1310 data
->wd_Flags
&= ~MUIWF_BUBBLEMODE
;
1312 if (data
->wd_Flags
& MUIWF_BUBBLEMODE
)
1314 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_LATER
;
1318 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_FIRST
;
1325 typedef BOOL(*UNDERCHECK_FUNC
) (Object
*obj
);
1327 static BOOL
ShortHelpUnderPointerCheck(Object
*obj
)
1329 return muiAreaData(obj
)->mad_ShortHelp
? TRUE
: FALSE
;
1332 static Object
*ObjectUnderPointer(struct MUI_WindowData
*data
, Object
*obj
,
1333 LONG x
, LONG y
, UNDERCHECK_FUNC func
)
1337 struct MinList
*ChildList
= NULL
;
1339 if (!(muiAreaData(obj
)->mad_Flags
& MADF_CANDRAW
))
1342 if (!(x
>= _left(obj
) && x
<= _right(obj
)
1343 && y
>= _top(obj
) && y
<= _bottom(obj
)))
1348 if ((get(obj
, MUIA_Group_ChildList
, &(ChildList
)))
1349 && (ChildList
!= NULL
))
1351 cstate
= (Object
*) ChildList
->mlh_Head
;
1352 while ((child
= NextObject(&cstate
)))
1356 if ((x
>= _left(child
) && x
<= _right(child
)
1358 y
>= _top(child
) && y
<= _bottom(child
))
1359 && (ret
= ObjectUnderPointer(data
, child
, x
, y
, func
)))
1372 static BOOL
ContextMenuUnderPointer(struct MUI_WindowData
*data
,
1373 Object
*obj
, LONG x
, LONG y
)
1377 struct MinList
*ChildList
= NULL
;
1379 if (!(x
>= _left(obj
) && x
<= _right(obj
)
1380 && y
>= _top(obj
) && y
<= _bottom(obj
)))
1385 if ((get(obj
, MUIA_Group_ChildList
, &(ChildList
)))
1386 && (ChildList
!= NULL
))
1389 cstate
= (Object
*) ChildList
->mlh_Head
;
1390 while ((child
= NextObject(&cstate
)))
1392 if ((x
>= _left(child
) && x
<= _right(child
)
1394 y
>= _top(child
) && y
<= _bottom(child
))
1395 && (ContextMenuUnderPointer(data
, child
, x
, y
)))
1400 if (!(muiAreaData(obj
)->mad_Flags
& MADF_CANDRAW
))
1402 if (!(muiAreaData(obj
)->mad_ContextMenu
))
1410 static void ActivateObject(struct MUI_WindowData
*data
)
1412 //bug("Window::ActivateObject (dummy) %08lx\n", data->wd_ActiveObject);
1413 // if (FindObjNode(&data->wd_CycleChain, data->wd_ActiveObject))
1414 // DoMethod(data->wd_ActiveObject, MUIM_GoActive);
1416 // data->wd_ActiveObject = NULL;
1418 //activate better string gadgets.Fix from Georg S On ML List
1419 if (FindObjNode(&data
->wd_CycleChain
, data
->wd_ActiveObject
))
1421 if (!(data
->wd_Flags
& MUIWF_OBJECTGOACTIVESENT
))
1423 data
->wd_Flags
|= MUIWF_OBJECTGOACTIVESENT
;
1424 DoMethod(data
->wd_ActiveObject
, MUIM_GoActive
);
1428 data
->wd_ActiveObject
= NULL
;
1433 /* handle intuimessage while an object is being dragged
1434 * (reply imsg before returning)
1435 * Returns TRUE if finished dragging.
1437 static BOOL
HandleDragging(Object
*oWin
, struct MUI_WindowData
*data
,
1438 struct IntuiMessage
*imsg
)
1440 struct Window
*iWin
;
1441 BOOL finish_drag
= FALSE
;
1443 iWin
= imsg
->IDCMPWindow
;
1445 if (imsg
->Class
== IDCMP_MOUSEMOVE
)
1447 struct Layer
*layer
;
1449 LockLayerInfo(&iWin
->WScreen
->LayerInfo
);
1450 layer
= WhichLayer(&iWin
->WScreen
->LayerInfo
, iWin
->LeftEdge
+ imsg
->MouseX
,
1451 iWin
->TopEdge
+ imsg
->MouseY
);
1452 UnlockLayerInfo(&iWin
->WScreen
->LayerInfo
);
1454 if (data
->wd_DropObject
)
1458 imsg
->MouseX
+ iWin
->LeftEdge
-
1459 data
->wd_DropWindow
->LeftEdge
;
1461 imsg
->MouseY
+ iWin
->TopEdge
- data
->wd_DropWindow
->TopEdge
;
1463 wnd
= _window(data
->wd_DropObject
);
1464 if (mousex
< _left(data
->wd_DropObject
)
1465 || mousex
> _right(data
->wd_DropObject
)
1466 || mousey
< _top(data
->wd_DropObject
)
1467 || mousey
> _bottom(data
->wd_DropObject
)
1468 || layer
!= wnd
->WLayer
)
1470 /* We have left the object */
1471 UndrawDragNDrop(data
->wd_dnd
);
1472 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
,
1473 (IPTR
) data
->wd_DragObject
);
1474 data
->wd_DropObject
= NULL
;
1476 } /* if (data->wd_DropObject) */
1478 if (!data
->wd_DropObject
)
1480 Object
*dest_wnd
= NULL
;
1482 /* Find out if app has an open window at this position */
1487 struct MinList
*ChildList
= 0;
1489 get(_app(oWin
), MUIA_Application_WindowList
, &(ChildList
));
1490 cstate
= (Object
*) ChildList
->mlh_Head
;
1491 while ((child
= NextObject(&cstate
)))
1493 struct Window
*wnd
= NULL
;
1494 get(child
, MUIA_Window_Window
, &wnd
);
1498 if (wnd
->WLayer
== layer
)
1500 data
->wd_DropWindow
= wnd
;
1509 Object
*root
= NULL
;
1510 get(dest_wnd
, MUIA_Window_RootObject
, &root
);
1514 if ((data
->wd_DropObject
= (Object
*) DoMethod
1515 (root
, MUIM_DragQueryExtended
,
1516 (IPTR
) data
->wd_DragObject
,
1517 imsg
->MouseX
+ iWin
->LeftEdge
-
1518 data
->wd_DropWindow
->LeftEdge
,
1519 imsg
->MouseY
+ iWin
->TopEdge
-
1520 data
->wd_DropWindow
->TopEdge
)))
1522 UndrawDragNDrop(data
->wd_dnd
);
1523 DoMethod(data
->wd_DropObject
, MUIM_DragBegin
,
1524 (IPTR
) data
->wd_DragObject
);
1530 if (data
->wd_DropObject
)
1534 for (i
= 0; i
< 2; i
++)
1536 LONG res
= DoMethod(data
->wd_DropObject
, MUIM_DragReport
,
1537 (IPTR
) data
->wd_DragObject
,
1538 imsg
->MouseX
+ iWin
->LeftEdge
-
1539 data
->wd_DropWindow
->LeftEdge
,
1540 imsg
->MouseY
+ iWin
->TopEdge
-
1541 data
->wd_DropWindow
->TopEdge
, update
);
1544 case MUIV_DragReport_Abort
:
1545 UndrawDragNDrop(data
->wd_dnd
);
1546 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
,
1547 (IPTR
) data
->wd_DragObject
);
1548 data
->wd_DropObject
= NULL
;
1552 case MUIV_DragReport_Continue
:
1554 case MUIV_DragReport_Lock
:
1556 case MUIV_DragReport_Refresh
:
1557 UndrawDragNDrop(data
->wd_dnd
);
1563 DrawDragNDrop(data
->wd_dnd
, imsg
->MouseX
+ iWin
->LeftEdge
,
1564 imsg
->MouseY
+ iWin
->TopEdge
);
1567 if (imsg
->Class
== IDCMP_MOUSEBUTTONS
)
1569 if ((imsg
->Code
== MENUDOWN
) || (imsg
->Code
== SELECTUP
))
1571 UndrawDragNDrop(data
->wd_dnd
);
1572 if (imsg
->Code
== SELECTUP
&& data
->wd_DropObject
)
1574 DoMethod(data
->wd_DropObject
, MUIM_DragDrop
,
1575 (IPTR
) data
->wd_DragObject
,
1576 imsg
->MouseX
+ iWin
->LeftEdge
-
1577 data
->wd_DropWindow
->LeftEdge
,
1578 imsg
->MouseY
+ iWin
->TopEdge
-
1579 data
->wd_DropWindow
->TopEdge
);
1580 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
,
1581 (IPTR
) data
->wd_DragObject
);
1582 data
->wd_DropObject
= NULL
;
1584 else if (imsg
->Code
== SELECTUP
)
1586 DoMethod(data
->wd_DragObject
, MUIM_UnknownDropDestination
,
1593 if (imsg
->Class
== IDCMP_CLOSEWINDOW
)
1598 if (data
->wd_DropObject
)
1600 UndrawDragNDrop(data
->wd_dnd
);
1601 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
,
1602 (IPTR
) data
->wd_DragObject
);
1603 data
->wd_DropObject
= NULL
;
1605 DeleteDragNDrop(data
->wd_dnd
);
1606 DoMethod(data
->wd_DragObject
, MUIM_DeleteDragImage
,
1607 (IPTR
) data
->wd_DragImage
);
1608 muiAreaData(data
->wd_DragObject
)->mad_Flags
&= ~MADF_DRAGGING
;
1609 data
->wd_DragImage
= NULL
;
1610 data
->wd_DragObject
= NULL
;
1611 data
->wd_DropWindow
= NULL
;
1612 data
->wd_dnd
= NULL
;
1614 /* stop listening to IDCMP_MOUSEMOVE */
1615 ChangeEvents(data
, GetDefaultEvents());
1618 ReplyMsg((struct Message
*)imsg
);
1623 /* Reply to imsg if handled */
1624 BOOL
HandleWindowEvent(Object
*oWin
, struct MUI_WindowData
*data
,
1625 struct IntuiMessage
*imsg
)
1627 struct Window
*iWin
;
1628 BOOL is_handled
= TRUE
;
1629 BOOL replied
= FALSE
;
1631 iWin
= imsg
->IDCMPWindow
;
1632 switch (imsg
->Class
)
1634 case IDCMP_ACTIVEWINDOW
:
1635 data
->wd_Flags
|= MUIWF_ACTIVE
;
1636 if (data
->wd_OldActive
)
1637 set(oWin
, MUIA_Window_ActiveObject
, data
->wd_OldActive
);
1638 set(oWin
, MUIA_Window_Activate
, TRUE
);
1639 is_handled
= FALSE
; /* forwardable to area event handlers */
1642 case IDCMP_INACTIVEWINDOW
:
1643 KillHelpBubble(data
, oWin
, TRUE
);
1644 if (data
->wd_ActiveObject
)
1646 data
->wd_OldActive
= data
->wd_ActiveObject
;
1647 set(oWin
, MUIA_Window_ActiveObject
,
1648 MUIV_Window_ActiveObject_None
);
1650 data
->wd_Flags
&= ~MUIWF_ACTIVE
;
1651 set(oWin
, MUIA_Window_Activate
, FALSE
);
1652 is_handled
= FALSE
; /* forwardable to area event handlers */
1656 case IDCMP_CHANGEWINDOW
:
1658 int hborders
= iWin
->BorderLeft
+ iWin
->BorderRight
;
1659 int vborders
= iWin
->BorderTop
+ iWin
->BorderBottom
;
1661 /* set window limits according to window contents */
1664 data
->wd_MinMax
.MinWidth
+ hborders
,
1665 data
->wd_MinMax
.MinHeight
+ vborders
,
1666 data
->wd_MinMax
.MaxWidth
+ hborders
,
1667 data
->wd_MinMax
.MaxHeight
+ vborders
);
1670 if ((iWin
->GZZWidth
!= data
->wd_Width
)
1671 || (iWin
->GZZHeight
!= data
->wd_Height
))
1673 data
->wd_Width
= iWin
->GZZWidth
;
1674 data
->wd_Height
= iWin
->GZZHeight
;
1675 DoHideMethod(data
->wd_RootObject
);
1677 data
->wd_Flags
|= MUIWF_RESIZING
;
1678 RefreshWindow(oWin
, data
);
1680 is_handled
= FALSE
; /* forwardable to area event handlers */
1683 case IDCMP_REFRESHWINDOW
:
1684 ReplyMsg((struct Message
*)imsg
);
1686 RefreshWindow(oWin
, data
);
1689 case IDCMP_CLOSEWINDOW
:
1690 ReplyMsg((struct Message
*)imsg
);
1692 set(oWin
, MUIA_Window_CloseRequest
, TRUE
);
1695 case IDCMP_MENUPICK
:
1696 ReplyMsg((struct Message
*)imsg
);
1701 if (MENUNUM(imsg
->Code
) != NOMENU
1702 && ITEMNUM(imsg
->Code
) != NOITEM
)
1704 struct MenuItem
*item
=
1705 ItemAddress(data
->wd_Menu
, imsg
->Code
);
1708 Object
*item_obj
= (Object
*) GTMENUITEM_USERDATA(item
);
1714 if (item
->Flags
& CHECKIT
)
1715 set(item_obj
, MUIA_Menuitem_Checked
,
1716 ! !(item
->Flags
& CHECKED
));
1718 set(item_obj
, MUIA_Menuitem_Trigger
, (IPTR
) item
);
1720 get(oWin
, MUIA_ApplicationObject
, &app
);
1721 get(item_obj
, MUIA_UserData
, &udata
);
1723 set(app
, MUIA_Application_MenuAction
, udata
);
1724 set(oWin
, MUIA_Window_MenuAction
, udata
);
1725 DoMethod(app
, MUIM_Application_ReturnID
, udata
);
1732 case IDCMP_IDCMPUPDATE
:
1733 is_handled
= FALSE
; /* forwardable to area event handlers */
1734 if (data
->wd_VertProp
|| data
->wd_HorizProp
)
1736 struct TagItem
*tag
;
1737 tag
= FindTagItem(GA_ID
, (struct TagItem
*)imsg
->IAddress
);
1740 /* If there's a propclass object connected to the prop
1741 gadget, the prop gadget's userdata will point to
1742 that propclass object. See classes/prop.c */
1744 if (data
->wd_VertProp
)
1746 if (tag
->ti_Data
== GADGETID(data
->wd_VertProp
))
1749 if (tag
->ti_Data
== GADGETID(data
->wd_UpButton
))
1752 (Object
*) ((struct Gadget
*)data
->
1753 wd_VertProp
)->UserData
;
1756 DoMethod(prop
, MUIM_Prop_Decrease
, 1);
1759 if (tag
->ti_Data
== GADGETID(data
->wd_DownButton
))
1762 (Object
*) ((struct Gadget
*)data
->
1763 wd_VertProp
)->UserData
;
1766 DoMethod(prop
, MUIM_Prop_Increase
, 1);
1771 if (data
->wd_HorizProp
)
1773 if (tag
->ti_Data
== GADGETID(data
->wd_HorizProp
))
1776 if (tag
->ti_Data
== GADGETID(data
->wd_LeftButton
))
1779 (Object
*) ((struct Gadget
*)data
->
1780 wd_HorizProp
)->UserData
;
1783 DoMethod(prop
, MUIM_Prop_Decrease
, 1);
1786 if (tag
->ti_Data
== GADGETID(data
->wd_RightButton
))
1789 (Object
*) ((struct Gadget
*)data
->
1790 wd_HorizProp
)->UserData
;
1793 DoMethod(prop
, MUIM_Prop_Increase
, 1);
1801 case IDCMP_INTUITICKS
:
1802 if (data
->wd_HelpTicker
)
1804 data
->wd_HelpTicker
--;
1806 if (data
->wd_HelpTicker
== 0)
1809 ObjectUnderPointer(data
, data
->wd_RootObject
,
1810 imsg
->MouseX
, imsg
->MouseY
,
1811 ShortHelpUnderPointerCheck
);
1813 if (underobj
!= data
->wd_HelpObject
)
1815 if (data
->wd_HelpObject
)
1817 DoMethod(data
->wd_HelpObject
, MUIM_DeleteBubble
,
1818 (IPTR
) data
->wd_HelpBubble
);
1820 data
->wd_HelpObject
= NULL
;
1821 data
->wd_HelpBubble
= NULL
;
1826 data
->wd_HelpBubble
=
1827 (APTR
) DoMethod(underobj
, MUIM_CreateBubble
,
1828 imsg
->MouseX
, imsg
->MouseY
, 0, 0);
1829 if (data
->wd_HelpBubble
)
1831 data
->wd_HelpObject
= underobj
;
1832 data
->wd_Flags
|= MUIWF_BUBBLEMODE
;
1837 if (data
->wd_Flags
& MUIWF_BUBBLEMODE
)
1839 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_LATER
;
1843 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_FIRST
;
1848 is_handled
= FALSE
; /* forwardable to area event handlers */
1851 case IDCMP_MOUSEBUTTONS
:
1852 DoMethod(oWin
, MUIM_Window_Snapshot
, 0);
1853 KillHelpBubble(data
, oWin
, TRUE
);
1858 case IDCMP_MOUSEMOVE
:
1859 KillHelpBubble(data
, oWin
, FALSE
);
1868 if (is_handled
&& !replied
)
1869 ReplyMsg((struct Message
*)imsg
);
1874 static ULONG
InvokeEventHandler(struct MUI_EventHandlerNode
*ehn
,
1875 struct IntuiMessage
*event
, ULONG muikey
)
1879 if (!(_flags(ehn
->ehn_Object
) & MADF_CANDRAW
))
1881 if (!(_flags(ehn
->ehn_Object
) & MADF_SHOWME
))
1885 && event
->Class
== IDCMP_MOUSEBUTTONS
1886 && event
->Code
== SELECTDOWN
1887 && (_flags(ehn
->ehn_Object
) & MADF_INVIRTUALGROUP
))
1890 Here we filter out SELECTDOWN messages if objects is in a virtual
1891 group but the click went out of the virtual group
1893 Object
*obj
= ehn
->ehn_Object
;
1894 Object
*parent
= obj
;
1895 Object
*wnd
= _win(obj
);
1897 while (get(parent
, MUIA_Parent
, &parent
))
1903 if (_flags(parent
) & MADF_ISVIRTUALGROUP
)
1905 if (event
->MouseX
< _mleft(parent
)
1906 || event
->MouseX
> _mright(parent
)
1907 || event
->MouseY
< _mtop(parent
)
1908 || event
->MouseY
> _mbottom(parent
))
1917 if (ehn
->ehn_Flags
& MUI_EHF_HANDLEINPUT
)
1919 DoMethod(ehn
->ehn_Object
, MUIM_HandleInput
, (IPTR
) event
, muikey
);
1926 (ehn
->ehn_Class
, ehn
->ehn_Object
, MUIM_HandleEvent
,
1927 (IPTR
) event
, muikey
);
1930 DoMethod(ehn
->ehn_Object
, MUIM_HandleEvent
, (IPTR
) event
,
1937 static void HandleRawkey(Object
*win
, struct MUI_WindowData
*data
,
1938 struct IntuiMessage
*event
)
1941 struct MUI_EventHandlerNode
*ehn
;
1942 struct IntuiMessage imsg_copy
;
1943 struct InputEvent ie
= { 0 };
1945 LONG muikey
= MUIKEY_NONE
;
1946 Object
*active_object
= NULL
;
1951 KillHelpBubble(data
, win
, BUBBLEHELP_TICKER_FIRST
);
1953 ie
.ie_NextEvent
= NULL
;
1954 ie
.ie_Class
= IECLASS_RAWKEY
;
1956 ie
.ie_Code
= event
->Code
;
1957 ie
.ie_Qualifier
= event
->Qualifier
;
1958 ie
.ie_EventAddress
= (APTR
) * (IPTR
*) event
->IAddress
;
1960 ie
.ie_TimeStamp
.Seconds
= event
->Seconds
;
1961 ie
.ie_TimeStamp
.Microseconds
= event
->Micros
;
1963 ie
.ie_TimeStamp
.tv_secs
= event
->Seconds
;
1964 ie
.ie_TimeStamp
.tv_micro
= event
->Micros
;
1967 set(win
, MUIA_Window_InputEvent
, (IPTR
) & ie
);
1969 /* get the vanilla key for control char */
1973 /* Remove the up prefix as convert key does not convert upkey event */
1974 msg_code
= event
->Code
;
1975 event
->Code
&= ~IECODE_UP_PREFIX
;
1976 key
= ConvertKey(event
);
1977 event
->Code
= msg_code
;
1981 deadkey
= *(ULONG
*) event
->IAddress
;
1982 imsg_copy
.IAddress
= &deadkey
;
1983 ReplyMsg((struct Message
*)event
);
1986 //bug("rawkey: code=%lx, qual=%lx\n", event->Code, event->Qualifier);
1988 /* check if imsg translates to predefined keystroke */
1990 struct InputEvent ievent
;
1991 BOOL matched
= FALSE
;
1993 ievent
.ie_NextEvent
= NULL
;
1994 ievent
.ie_Class
= IECLASS_RAWKEY
;
1995 ievent
.ie_SubClass
= 0;
1996 ievent
.ie_Code
= event
->Code
;
1997 ievent
.ie_Qualifier
= event
->Qualifier
;
1998 /* ie_EventAddress is not used by MatchIX. If needed, it should be
1999 * ensured that it is still a valid address because of the shallow
2000 * IntuiMessage copy currently done in _zune_window_message before
2001 * message is replied.
2003 ievent
.ie_EventAddress
= NULL
;
2004 //ievent.ie_EventAddress = (APTR *) *((ULONG *)(event->IAddress));
2006 for (muikey
= MUIKEY_COUNT
- 1; muikey
>= MUIKEY_PRESS
; muikey
--)
2008 if (muiGlobalInfo(win
)->mgi_Prefs
->muikeys
[muikey
].ix_well
!= 0
2010 &muiGlobalInfo(win
)->mgi_Prefs
->muikeys
[muikey
].ix
))
2019 if (muikey
== MUIKEY_PRESS
&& (event
->Code
& IECODE_UP_PREFIX
))
2020 muikey
= MUIKEY_RELEASE
;
2024 muikey
= MUIKEY_NONE
;
2026 } /* check if imsg translate to predefined keystroke */
2028 if ((muikey
!= MUIKEY_NONE
) && !(data
->wd_DisabledKeys
& (1 << muikey
)))
2030 D(bug("HandleRawkey: try MUIKEY %ld on window %0x08lx\n", muikey
,
2044 case MUIKEY_PAGEDOWN
:
2054 case MUIKEY_WORDLEFT
:
2056 case MUIKEY_WORDRIGHT
:
2058 case MUIKEY_LINESTART
:
2060 case MUIKEY_LINEEND
:
2062 case MUIKEY_GADGET_NEXT
:
2063 set(win
, MUIA_Window_ActiveObject
,
2064 MUIV_Window_ActiveObject_Next
);
2066 case MUIKEY_GADGET_PREV
:
2067 set(win
, MUIA_Window_ActiveObject
,
2068 MUIV_Window_ActiveObject_Prev
);
2070 case MUIKEY_GADGET_OFF
:
2071 set(win
, MUIA_Window_ActiveObject
,
2072 MUIV_Window_ActiveObject_None
);
2074 case MUIKEY_WINDOW_CLOSE
:
2075 set(win
, MUIA_Window_CloseRequest
, TRUE
);
2077 case MUIKEY_WINDOW_NEXT
:
2079 case MUIKEY_WINDOW_PREV
:
2090 active_object
= NULL
;
2091 if ((data
->wd_ActiveObject
!= NULL
)
2092 && (DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
2093 (IPTR
) data
->wd_ActiveObject
) != (IPTR
) NULL
))
2095 active_object
= data
->wd_ActiveObject
;
2096 get(active_object
, MUIA_Disabled
, &disabled
);
2099 data
->wd_ActiveObject
= NULL
;
2101 /* try ActiveObject */
2102 if ((active_object
!= NULL
) && !disabled
)
2106 ** Which method should be used for muikeys? MUIM_HandleInput or
2107 ** MUIM_HandleEvent. Also note that there is a flag MUI_EHF_ALWAYSKEYS
2108 ** which probably means that all keys events are requested??
2109 ** For now MUIM_HandleEvent is used as this is currently implemented
2110 ** in Area class ;) although I guess it should be MUIM_HandleInput as
2114 if (muikey
!= MUIKEY_NONE
)
2117 DoMethod(active_object
, MUIM_HandleEvent
, (IPTR
) event
,
2119 if (res
& MUI_EventHandlerRC_Eat
)
2123 D(bug("HandleRawkey: try active object (%08lx) handlers\n",
2126 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2128 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2130 if ((ehn
->ehn_Object
== active_object
)
2131 && ((ehn
->ehn_Events
& IDCMP_RAWKEY
)
2132 || (ehn
->ehn_Flags
& MUI_EHF_ALWAYSKEYS
)))
2134 D(bug("HandleRawkey: (active) invoking on %p (ehn=%p) "
2135 "event=%p muikey=%p\n",
2136 ehn
->ehn_Object
, ehn
, event
, muikey
));
2137 res
= InvokeEventHandler(ehn
, event
, muikey
);
2138 D(bug("HandleRawkey: (active) got res=%d\n", res
));
2139 if (res
& MUI_EventHandlerRC_Eat
)
2142 /* Leave the loop if a different object has been activated */
2143 if (active_object
!= data
->wd_ActiveObject
)
2148 // event not eaten by active object, try its parents
2149 // this is to implement popup key in Popstring
2150 if (active_object
== data
->wd_ActiveObject
)
2152 Object
*current_obj
= active_object
;
2154 D(bug("HandleRawkey: try active object parents handlers\n"));
2155 while (current_obj
!= NULL
)
2157 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
;
2160 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2162 if ((ehn
->ehn_Object
== current_obj
)
2163 && ((ehn
->ehn_Events
& IDCMP_RAWKEY
)
2164 || (ehn
->ehn_Flags
& MUI_EHF_ALWAYSKEYS
)))
2166 //D(bug("HandleRawkey: (active parents) invoking on "
2167 // "%p (ehn=%p) event=%p muikey=%p\n",
2168 // ehn->ehn_Object, ehn, event, muikey));
2169 res
= InvokeEventHandler(ehn
, event
, muikey
);
2170 //D(bug("HandleRawkey: (active parents) got res=%d\n",
2172 if (res
& MUI_EventHandlerRC_Eat
)
2175 /* Leave the loop if a different object has been
2177 if (active_object
!= data
->wd_ActiveObject
)
2181 current_obj
= (Object
*) XGET(current_obj
, MUIA_Parent
);
2186 D(bug("HandleRawkey: try default object handlers\n"));
2188 /* try DefaultObject */
2189 if (data
->wd_DefaultObject
!= NULL
)
2190 get(data
->wd_DefaultObject
, MUIA_Disabled
, &disabled
);
2192 if ((data
->wd_DefaultObject
!= NULL
) && !disabled
2193 && (active_object
!= data
->wd_DefaultObject
))
2195 /* No, we only should do this if the object actually has requested
2196 * this via RequestIDCMP()! */
2197 // if (muikey != MUIKEY_NONE
2198 // && (_flags(data->wd_DefaultObject) & MADF_CANDRAW))
2200 // DoMethod(data->wd_DefaultObject, MUIM_HandleInput, event, muikey);
2204 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2206 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2208 if ((ehn
->ehn_Object
== data
->wd_DefaultObject
)
2209 && ((ehn
->ehn_Events
& IDCMP_RAWKEY
)
2210 || (ehn
->ehn_Flags
& MUI_EHF_ALWAYSKEYS
)))
2212 //D(bug("HandleRawkey: (default) invoking on %p (ehn=%p) "
2213 //"event=%p muikey=%p\n",
2214 //ehn->ehn_Object, ehn, event, muikey));
2215 res
= InvokeEventHandler(ehn
, event
, muikey
);
2216 //D(bug("HandleRawkey: (default) got res=%d\n", res));
2217 if (res
& MUI_EventHandlerRC_Eat
)
2224 D(bug("HandleRawkey: try other handlers\n"));
2226 // try other handlers
2227 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2229 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2231 // skip Active and Default object as they have already been
2233 if (ehn
->ehn_Object
== data
->wd_ActiveObject
2234 || ehn
->ehn_Object
== data
->wd_DefaultObject
)
2237 if (ehn
->ehn_Events
& IDCMP_RAWKEY
)
2239 //D(bug("HandleRawkey: (others) invoking on %p (ehn=%p) "
2240 //"event=%p muikey=%p\n",
2241 //ehn->ehn_Object, ehn, event, muikey));
2242 res
= InvokeEventHandler(ehn
, event
, MUIKEY_NONE
);
2243 //D(bug("HandleRawkey: (others) got res=%d\n", res));
2244 if (res
& MUI_EventHandlerRC_Eat
)
2249 D(bug("HandleRawkey: try control chars handlers\n"));
2251 /* try Control Chars */
2252 //bug("ctrlchar, key='%c' code=0x%08lx\n", key, event->Code);
2255 for (mn
= data
->wd_CCList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2257 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2259 if (ehn
->ehn_Events
== key
)
2262 LONG muikey2
= ehn
->ehn_Flags
;
2264 get(ehn
->ehn_Object
, MUIA_Disabled
, &disabled
);
2268 //bug("control char\n");
2269 if (event
->Code
& IECODE_UP_PREFIX
)
2271 /* simulate a release */
2272 if (muikey2
== MUIKEY_PRESS
)
2273 muikey2
= MUIKEY_RELEASE
;
2278 if ((muikey2
!= MUIKEY_NONE
)
2279 && (_flags(ehn
->ehn_Object
) & MADF_CANDRAW
)
2280 && (_flags(ehn
->ehn_Object
) & MADF_SHOWME
))
2283 (ehn
->ehn_Class
, ehn
->ehn_Object
, MUIM_HandleEvent
,
2284 (IPTR
) NULL
, muikey2
);
2285 if (res
& MUI_EventHandlerRC_Eat
)
2293 /* forward non-keystroke events to event handlers */
2294 static void HandleInputEvent(Object
*win
, struct MUI_WindowData
*data
,
2295 struct IntuiMessage
*event
)
2298 struct MUI_EventHandlerNode
*ehn
;
2299 struct IntuiMessage imsg_copy
;
2301 ULONG mask
= event
->Class
;
2303 if (mask
!= IDCMP_IDCMPUPDATE
)
2306 imsg_copy
.IAddress
= NULL
; /* be sure to trap access to that */
2307 ReplyMsg((struct Message
*)event
);
2311 if (mask
== IDCMP_MOUSEMOVE
)
2313 struct Window
*iWin
;
2314 iWin
= event
->IDCMPWindow
;
2316 if (ContextMenuUnderPointer(data
, data
->wd_RootObject
,
2317 event
->MouseX
, event
->MouseY
))
2319 iWin
->Flags
|= WFLG_RMBTRAP
;
2321 else if (!data
->wd_NoMenus
)
2323 iWin
->Flags
&= ~WFLG_RMBTRAP
;
2327 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2329 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2331 if (ehn
->ehn_Events
& mask
)
2335 get(ehn
->ehn_Object
, MUIA_Disabled
, &disabled
);
2339 res
= InvokeEventHandler(ehn
, event
, MUIKEY_NONE
);
2340 if (res
& MUI_EventHandlerRC_Eat
)
2346 if (mask
== IDCMP_IDCMPUPDATE
)
2347 ReplyMsg((struct Message
*)event
);
2351 /* process window message; this does a ReplyMsg() to the message */
2352 /* Called from application.c */
2353 void _zune_window_message(struct IntuiMessage
*imsg
)
2355 struct Window
*iWin
;
2357 struct MUI_WindowData
*data
;
2360 iWin
= imsg
->IDCMPWindow
;
2361 oWin
= (Object
*) iWin
->UserData
;
2362 data
= muiWindowData(oWin
);
2364 if (data
->wd_DragObject
)
2366 if (!HandleDragging(oWin
, data
, imsg
))
2370 handled
= HandleWindowEvent(oWin
, data
, imsg
);
2373 if (IDCMP_RAWKEY
== imsg
->Class
)
2374 HandleRawkey(oWin
, data
, imsg
);
2375 else if (IDCMP_GADGETUP
== imsg
->Class
)
2378 if (ETI_MUI
== ((struct Gadget
*)imsg
->IAddress
)->GadgetID
)
2380 DoMethod(_app(oWin
), MUIM_Application_OpenConfigWindow
);
2383 if (ETI_Iconify
== ((struct Gadget
*)imsg
->IAddress
)->GadgetID
)
2385 set(_app(oWin
), MUIA_Application_Iconified
, TRUE
);
2390 HandleInputEvent(oWin
, data
, imsg
);
2395 /**************************************************************************/
2396 /**************************************************************************/
2398 /* code for setting MUIA_Window_RootObject */
2399 static void ChangeRootObject(struct MUI_WindowData
*data
, Object
*obj
,
2404 ASSERT_VALID_PTR(data
);
2405 ASSERT_VALID_PTR(obj
);
2407 oldRoot
= data
->wd_RootObject
;
2408 if (!(data
->wd_Flags
& MUIWF_OPENED
))
2412 if (data
->wd_ActiveObject
== oldRoot
)
2413 set(obj
, MUIA_Window_ActiveObject
,
2414 MUIV_Window_ActiveObject_None
);
2415 DoMethod(oldRoot
, MUIM_DisconnectParent
);
2418 data
->wd_RootObject
= newRoot
;
2421 /* if window is in App tree, inform child */
2422 if (muiNotifyData(obj
)->mnd_GlobalInfo
)
2423 DoMethod(newRoot
, MUIM_ConnectParent
, (IPTR
) obj
);
2428 // find the ObjNode containing a pointer to the given object
2429 // currently only used for cycle chain objects
2430 static struct ObjNode
*FindObjNode(struct MinList
*list
, Object
*obj
)
2432 struct ObjNode
*node
;
2434 ASSERT_VALID_PTR(list
);
2439 ASSERT_VALID_PTR(obj
);
2441 for (node
= (struct ObjNode
*)list
->mlh_Head
;
2442 node
->node
.mln_Succ
; node
= (struct ObjNode
*)node
->node
.mln_Succ
)
2444 if (node
->obj
== obj
)
2452 static Object
*GetFirstActiveObject(struct MUI_WindowData
*data
)
2454 ASSERT_VALID_PTR(data
);
2456 if (!IsListEmpty((struct List
*)&data
->wd_CycleChain
))
2457 return ((struct ObjNode
*)data
->wd_CycleChain
.mlh_Head
)->obj
;
2462 static Object
*GetLastActiveObject(struct MUI_WindowData
*data
)
2464 ASSERT_VALID_PTR(data
);
2466 if (!IsListEmpty((struct List
*)&data
->wd_CycleChain
))
2467 return ((struct ObjNode
*)data
->wd_CycleChain
.mlh_TailPred
)->obj
;
2472 typedef struct ObjNode
*objnode_iterator_t(struct ObjNode
*curr_node
);
2474 static objnode_iterator_t NextObjNodeIterator
;
2475 static objnode_iterator_t PrevObjNodeIterator
;
2477 static struct ObjNode
*NextObjNodeIterator(struct ObjNode
*curr_node
)
2479 if (curr_node
->node
.mln_Succ
->mln_Succ
)
2480 return (struct ObjNode
*)curr_node
->node
.mln_Succ
;
2485 static struct ObjNode
*PrevObjNodeIterator(struct ObjNode
*curr_node
)
2487 if (curr_node
->node
.mln_Pred
->mln_Pred
)
2488 return (struct ObjNode
*)curr_node
->node
.mln_Pred
;
2493 static Object
*GetPrevNextActiveObject(struct ObjNode
*old_activenode
,
2494 objnode_iterator_t node_iterator
)
2496 struct ObjNode
*curr_node
;
2497 struct ObjNode
*node
;
2500 ASSERT_VALID_PTR(old_activenode
);
2502 curr_node
= old_activenode
;
2508 node
= node_iterator(curr_node
);
2513 /* let's see if this object meets cycle requirements
2514 * (enabled & visible) */
2517 IPTR is_disabled
= 0;
2519 get(obj
, MUIA_Disabled
, &is_disabled
);
2521 if (!is_disabled
&& (_flags(obj
) & MADF_SHOWME
))
2535 /**************************************************************************
2536 Code for setting MUIA_Window_ActiveObject
2538 - remove focus drawing for current active object
2539 - find (if needed) the new active object
2540 - set data->wd_ActiveObject to the new object
2541 - draw focus around the new active object
2542 **************************************************************************/
2543 static void SetActiveObject(struct MUI_WindowData
*data
, Object
*obj
,
2546 struct ObjNode
*old_activenode
= NULL
;
2548 ASSERT_VALID_PTR(data
);
2549 ASSERT_VALID_PTR(obj
);
2551 D(bug("MUIC_Window:SetActiveObject(data, obj, %08lx) Active=%p\n",
2552 newval
, data
->wd_ActiveObject
));
2554 if ((data
->wd_ActiveObject
!= NULL
)
2555 && (DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
2556 (IPTR
) data
->wd_ActiveObject
) != (IPTR
) NULL
))
2558 if ((IPTR
) data
->wd_ActiveObject
!= newval
)
2561 FindObjNode(&data
->wd_CycleChain
, data
->wd_ActiveObject
);
2562 if ((data
->wd_Flags
& MUIWF_OBJECTGOACTIVESENT
)
2563 && (_flags(data
->wd_ActiveObject
) & MADF_SETUP
))
2565 D(bug("Deactivate=%p\n", data
->wd_ActiveObject
));
2566 DoMethod(data
->wd_ActiveObject
, MUIM_GoInactive
);
2571 data
->wd_ActiveObject
= NULL
;
2572 data
->wd_Flags
&= ~MUIWF_OBJECTGOACTIVESENT
;
2576 case MUIV_Window_ActiveObject_None
:
2579 case MUIV_Window_ActiveObject_Next
:
2580 if (old_activenode
!= NULL
)
2581 data
->wd_ActiveObject
= GetPrevNextActiveObject(old_activenode
,
2582 NextObjNodeIterator
);
2583 if (NULL
== data
->wd_ActiveObject
)
2584 data
->wd_ActiveObject
= GetFirstActiveObject(data
);
2587 case MUIV_Window_ActiveObject_Prev
:
2589 data
->wd_ActiveObject
= GetPrevNextActiveObject(old_activenode
,
2590 PrevObjNodeIterator
);
2591 if (NULL
== data
->wd_ActiveObject
)
2592 data
->wd_ActiveObject
= GetLastActiveObject(data
);
2596 data
->wd_ActiveObject
= (Object
*) newval
;
2601 if (data
->wd_ActiveObject
!= NULL
2602 && DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
2603 (IPTR
) data
->wd_ActiveObject
)
2604 && (_flags(data
->wd_ActiveObject
) & MADF_CANDRAW
))
2606 D(bug("Activate=%p\n", data
->wd_ActiveObject
));
2607 DoMethod(data
->wd_ActiveObject
, MUIM_GoActive
);
2608 data
->wd_Flags
|= MUIWF_OBJECTGOACTIVESENT
;
2613 static BOOL
InBox(struct IBox
*box
, WORD x
, WORD y
)
2615 return x
>= box
->Left
&& x
< box
->Left
+ box
->Width
2616 && y
>= box
->Top
&& y
< box
->Top
+ box
->Height
;
2621 * Pass on an AppMessage to all objects that it landed on.
2623 static void ForwardAppMessage(struct MUI_WindowData
*data
, Object
*child
,
2624 struct AppMessage
*appmsg
)
2626 WORD x
= appmsg
->am_MouseX
, y
= appmsg
->am_MouseY
;
2628 struct List
*children
= NULL
;
2630 ASSERT_VALID_PTR(data
);
2631 ASSERT_VALID_PTR(child
);
2633 set(child
, MUIA_AppMessage
, appmsg
);
2635 children
= (struct List
*)XGET(child
, MUIA_Group_ChildList
);
2637 if (children
!= NULL
)
2639 cstate
= (Object
*) children
->lh_Head
;
2640 while ((child
= NextObject(&cstate
)))
2642 if (InBox(&muiAreaData(child
)->mad_Box
, x
, y
))
2644 ForwardAppMessage(data
, child
, appmsg
);
2652 * calculate real dimensions from programmer requirements.
2653 * may be overridden by user settings if MUIA_Window_ID is set.
2655 /* MUIV_Window_Height_Screen and MUIV_Window_Height_Visible
2656 * are not handled yet, as their Width couterparts.
2658 static void WindowSelectDimensions(struct MUI_WindowData
*data
)
2660 if (!data
->wd_Width
)
2662 if (data
->wd_ReqWidth
> 0)
2663 data
->wd_Width
= data
->wd_ReqWidth
;
2664 else if (data
->wd_ReqWidth
== MUIV_Window_Width_Default
)
2665 data
->wd_Width
= data
->wd_MinMax
.DefWidth
;
2666 else if (_between(MUIV_Window_Width_MinMax(100),
2667 data
->wd_ReqWidth
, MUIV_Window_Width_MinMax(0)))
2669 data
->wd_Width
= data
->wd_MinMax
.MinWidth
2671 * (data
->wd_MinMax
.MaxWidth
- data
->wd_MinMax
.MinWidth
);
2673 else if (_between(MUIV_Window_Width_Screen(100),
2674 data
->wd_ReqWidth
, MUIV_Window_Width_Screen(0)))
2676 data
->wd_Width
= data
->wd_RenderInfo
.mri_ScreenWidth
2677 * (-(data
->wd_ReqWidth
+ 200)) / 100;
2679 else if (_between(MUIV_Window_Width_Visible(100),
2680 data
->wd_ReqWidth
, MUIV_Window_Width_Visible(0)))
2682 data
->wd_Width
= data
->wd_RenderInfo
.mri_ScreenWidth
2683 * (-(data
->wd_ReqWidth
+ 100)) / 100;
2686 if (data
->wd_ReqHeight
> 0)
2687 data
->wd_Height
= data
->wd_ReqHeight
;
2688 else if (data
->wd_ReqHeight
== MUIV_Window_Height_Default
)
2689 data
->wd_Height
= data
->wd_MinMax
.DefHeight
;
2690 else if (_between(MUIV_Window_Height_MinMax(100),
2691 data
->wd_ReqHeight
, MUIV_Window_Height_MinMax(0)))
2693 data
->wd_Height
= data
->wd_MinMax
.MinHeight
2694 - data
->wd_ReqHeight
2695 * (data
->wd_MinMax
.MaxHeight
- data
->wd_MinMax
.MinHeight
);
2697 else if (_between(MUIV_Window_Height_Screen(100),
2698 data
->wd_ReqHeight
, MUIV_Window_Height_Screen(0)))
2703 scr
= data
->wd_RenderInfo
.mri_Screen
;
2706 scr
->Height
- data
->wd_RenderInfo
.mri_BorderTop
-
2707 data
->wd_RenderInfo
.mri_BorderBottom
;
2709 /* This is new to Zune: If TopEdge Delta is requested
2710 * the screenheight doesn't cover the barlayer */
2711 if (data
->wd_Y
<= MUIV_Window_TopEdge_Delta(0))
2712 height
-= scr
->BarHeight
+ 1;
2714 data
->wd_Height
= height
* (-(data
->wd_ReqHeight
+ 200)) / 100;
2716 else if (_between(MUIV_Window_Height_Visible(100),
2717 data
->wd_ReqHeight
, MUIV_Window_Height_Visible(0)))
2719 data
->wd_Height
= data
->wd_RenderInfo
.mri_ScreenHeight
2720 * (-(data
->wd_ReqHeight
+ 100)) / 100;
2724 if (data
->wd_ReqWidth
== MUIV_Window_Width_Scaled
)
2725 data
->wd_Width
= data
->wd_Height
* data
->wd_MinMax
.MinWidth
2726 / data
->wd_MinMax
.MinHeight
;
2727 else if (data
->wd_ReqHeight
== MUIV_Window_Width_Scaled
)
2728 data
->wd_Height
= data
->wd_Width
* data
->wd_MinMax
.MinHeight
2729 / data
->wd_MinMax
.MinWidth
;
2731 data
->wd_Width
= CLAMP(data
->wd_Width
, data
->wd_MinMax
.MinWidth
,
2732 data
->wd_MinMax
.MaxWidth
);
2733 data
->wd_Height
= CLAMP(data
->wd_Height
, data
->wd_MinMax
.MinHeight
,
2734 data
->wd_MinMax
.MaxHeight
);
2738 /**************************************************************************
2740 **************************************************************************/
2741 IPTR
Window__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
2743 struct MUI_WindowData
*data
;
2744 struct TagItem
*tags
;
2745 struct TagItem
*tag
;
2747 obj
= (Object
*) DoSuperMethodA(cl
, obj
, (Msg
) msg
);
2751 /* Initial local instance data */
2752 data
= INST_DATA(cl
, obj
);
2754 data
->wd_MemoryPool
= CreatePool(0, 4096, 2048);
2755 if (NULL
== data
->wd_MemoryPool
)
2757 CoerceMethod(cl
, obj
, OM_DISPOSE
);
2761 data
->wd_RenderInfo
.mri_WindowObject
= obj
;
2763 NewList((struct List
*)&(data
->wd_EHList
));
2764 NewList((struct List
*)&(data
->wd_CCList
));
2765 NewList((struct List
*)&(data
->wd_CycleChain
));
2766 NewList((struct List
*)&(data
->wd_IDList
));
2768 data
->wd_CrtFlags
= WFLG_SIZEGADGET
| WFLG_DRAGBAR
| WFLG_DEPTHGADGET
2769 | WFLG_CLOSEGADGET
| WFLG_SIMPLE_REFRESH
2770 | WFLG_REPORTMOUSE
| WFLG_NEWLOOKMENUS
;
2771 data
->wd_ZoomGadget
= TRUE
;
2772 data
->wd_Events
= GetDefaultEvents();
2773 data
->wd_ActiveObject
= NULL
;
2775 data
->wd_ReqHeight
= MUIV_Window_Height_Default
;
2776 data
->wd_ReqWidth
= MUIV_Window_Width_Default
;
2777 data
->wd_RootObject
= NULL
;
2778 data
->wd_DefaultObject
= NULL
;
2780 /* alternate dimensions */
2781 /* no change in coordinates */
2782 data
->wd_AltDim
.Top
= MUIV_Window_AltTopEdge_NoChange
;
2783 data
->wd_AltDim
.Left
= MUIV_Window_AltLeftEdge_NoChange
;
2784 /* default to min size */
2785 data
->wd_AltDim
.Width
= MUIV_Window_AltWidth_MinMax(0);
2786 data
->wd_AltDim
.Height
= MUIV_Window_AltHeight_MinMax(0);
2787 data
->wd_X
= MUIV_Window_LeftEdge_Centered
;
2788 data
->wd_Y
= MUIV_Window_TopEdge_Centered
;
2789 data
->wd_DisabledKeys
= 0L;
2790 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_FIRST
;
2792 /* parse initial taglist */
2794 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
));)
2796 switch (tag
->ti_Tag
)
2798 case MUIA_Window_EraseArea
:
2799 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_ERASEAREA
);
2802 case MUIA_Window_ToolBox
:
2803 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_TOOLBOX
);
2806 case MUIA_Window_CloseGadget
:
2807 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
,
2811 case MUIA_Window_SizeGadget
:
2812 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
,
2816 case MUIA_Window_ZoomGadget
:
2817 data
->wd_ZoomGadget
= tag
->ti_Data
;
2820 case MUIA_Window_Backdrop
:
2821 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
,
2825 case MUIA_Window_Borderless
:
2826 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
,
2830 case MUIA_Window_DepthGadget
:
2831 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
,
2835 case MUIA_Window_DragBar
:
2836 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_DRAGBAR
);
2839 case MUIA_Window_SizeRight
:
2840 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
,
2844 case MUIA_Window_Height
:
2845 data
->wd_ReqHeight
= (LONG
) tag
->ti_Data
;
2848 case MUIA_Window_Width
:
2849 data
->wd_ReqWidth
= (LONG
) tag
->ti_Data
;
2852 case MUIA_Window_ID
:
2853 set(obj
, MUIA_Window_ID
, tag
->ti_Data
);
2856 case MUIA_Window_IsSubWindow
:
2857 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
2861 case MUIA_Window_Title
:
2862 set(obj
, MUIA_Window_Title
, tag
->ti_Data
);
2865 case MUIA_Window_ScreenTitle
:
2866 set(obj
, MUIA_Window_ScreenTitle
, tag
->ti_Data
);
2869 case MUIA_Window_Activate
:
2870 _handle_bool_tag(data
->wd_Flags
, !tag
->ti_Data
,
2871 MUIWF_DONTACTIVATE
);
2874 case MUIA_Window_DefaultObject
:
2875 set(obj
, MUIA_Window_DefaultObject
, tag
->ti_Data
);
2878 case MUIA_Window_Menustrip
:
2879 data
->wd_ChildMenustrip
= (Object
*) tag
->ti_Data
;
2882 case MUIA_Window_NoMenus
:
2883 data
->wd_NoMenus
= (BOOL
) tag
->ti_Data
;
2886 case MUIA_Window_RootObject
:
2889 CoerceMethod(cl
, obj
, OM_DISPOSE
);
2892 set(obj
, MUIA_Window_RootObject
, tag
->ti_Data
);
2895 case MUIA_Window_AltHeight
:
2896 data
->wd_AltDim
.Height
= (WORD
) tag
->ti_Data
;
2899 case MUIA_Window_AltWidth
:
2900 data
->wd_AltDim
.Width
= (WORD
) tag
->ti_Data
;
2903 case MUIA_Window_AltLeftEdge
:
2904 data
->wd_AltDim
.Left
= (WORD
) tag
->ti_Data
;
2907 case MUIA_Window_AltTopEdge
:
2908 data
->wd_AltDim
.Top
= (WORD
) tag
->ti_Data
;
2911 case MUIA_Window_AppWindow
:
2912 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
2916 case MUIA_Window_LeftEdge
:
2917 data
->wd_X
= tag
->ti_Data
;
2920 case MUIA_Window_TopEdge
:
2921 data
->wd_Y
= tag
->ti_Data
;
2924 case MUIA_Window_UseBottomBorderScroller
:
2925 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
2926 MUIWF_USEBOTTOMSCROLLER
);
2929 case MUIA_Window_UseRightBorderScroller
:
2930 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
2931 MUIWF_USERIGHTSCROLLER
);
2934 case MUIA_Window_DisableKeys
:
2935 data
->wd_DisabledKeys
= tag
->ti_Data
;
2938 case MUIA_Window_RefWindow
:
2939 data
->wd_RefWindow
= (Object
*) tag
->ti_Data
;
2942 case MUIA_Window_Screen
:
2943 data
->wd_UserScreen
= (struct Screen
*)tag
->ti_Data
;
2946 case MUIA_Window_PublicScreen
:
2947 data
->wd_UserPublicScreen
= (STRPTR
) tag
->ti_Data
;
2952 /* D(bug("muimaster.library/window.c: Window Object created at " */
2953 /* "0x%lx back=%lx\n", */
2954 /* obj,data->wd_Background)); */
2959 /**************************************************************************
2961 **************************************************************************/
2962 IPTR
Window__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
2964 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
2966 /* D(bug("Window_Dispose(%p)\n", obj)); */
2969 /* We no longer clear muiGlobalInfo() during disconnections, so
2970 this can cause problems (remove object which is already removed).
2971 Furthermore AFAIK it is not legal to dispose a window object
2972 which is still ocnnected to the application object, anyway. */
2974 if (muiGlobalInfo(obj
) && _app(obj
))
2976 /* D(bug(" Window_Dispose(%p) : calling app->OM_REMMEMBER\n", obj)); */
2977 DoMethod(_app(obj
), OM_REMMEMBER
, (IPTR
) obj
);
2981 if (data
->wd_RootObject
)
2982 MUI_DisposeObject(data
->wd_RootObject
);
2984 if (data
->wd_ChildMenustrip
)
2985 MUI_DisposeObject(data
->wd_ChildMenustrip
);
2988 FreeVec(data
->wd_Title
);
2990 if (data
->wd_ScreenTitle
)
2991 FreeVec(data
->wd_ScreenTitle
);
2993 DeletePool(data
->wd_MemoryPool
);
2995 /* D(bug(" Window_Dispose(%p) : calling supermethod\n", obj)); */
2996 return DoSuperMethodA(cl
, obj
, msg
);
2999 static ULONG
WindowOpen(struct IClass
*cl
, Object
*obj
);
3000 static ULONG
WindowClose(struct IClass
*cl
, Object
*obj
);
3002 /**************************************************************************
3004 **************************************************************************/
3005 IPTR
Window__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
3007 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3008 struct TagItem
*tags
= msg
->ops_AttrList
;
3009 struct TagItem
*tag
;
3011 while ((tag
= NextTagItem(&tags
)) != NULL
)
3013 switch (tag
->ti_Tag
)
3015 case MUIA_AppMessage
:
3016 ForwardAppMessage(data
, data
->wd_RootObject
,
3017 (struct AppMessage
*)tag
->ti_Data
);
3020 case MUIA_Window_Activate
:
3021 if (data
->wd_RenderInfo
.mri_Window
)
3023 if (tag
->ti_Data
&& !(data
->wd_Flags
& MUIWF_ACTIVE
))
3025 ActivateWindow(data
->wd_RenderInfo
.mri_Window
);
3026 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
3031 _handle_bool_tag(data
->wd_Flags
, !tag
->ti_Data
,
3032 MUIWF_DONTACTIVATE
);
3035 case MUIA_Window_ActiveObject
:
3036 /* D(bug("MUIA_Window_ActiveObject %ld (%p)\n", */
3037 /* tag->ti_Data, tag->ti_Data)); */
3038 SetActiveObject(data
, obj
, tag
->ti_Data
);
3041 case MUIA_Window_DefaultObject
:
3042 data
->wd_DefaultObject
= (APTR
) tag
->ti_Data
;
3045 case MUIA_Window_ID
:
3046 data
->wd_ID
= tag
->ti_Data
;
3049 case MUIA_Window_IsSubWindow
:
3050 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
3054 case MUIA_Window_Open
:
3057 if (data
->wd_Flags
& MUIWF_HIDDEN
)
3058 data
->wd_Flags
|= MUIWF_OPENONUNHIDE
;
3059 else if (!(data
->wd_Flags
& MUIWF_OPENED
))
3060 WindowOpen(cl
, obj
);
3063 DoMethod(obj
, MUIM_Window_ToFront
);
3064 set(obj
, MUIA_Window_Activate
, TRUE
);
3067 else if (data
->wd_Flags
& MUIWF_HIDDEN
)
3068 data
->wd_Flags
&= ~MUIWF_OPENONUNHIDE
;
3069 else if (data
->wd_Flags
& MUIWF_OPENED
)
3070 WindowClose(cl
, obj
);
3073 case MUIA_ShowMe
: /* PRIVATE *abuse* of the Area's ShowMe attr */
3078 if (data
->wd_Flags
& MUIWF_HIDDEN
)
3080 data
->wd_Flags
&= ~MUIWF_HIDDEN
;
3082 if (data
->wd_Flags
& MUIWF_OPENONUNHIDE
)
3084 data
->wd_Flags
&= ~MUIWF_OPENONUNHIDE
;
3085 set(obj
, MUIA_Window_Open
, TRUE
);
3093 if (data
->wd_Flags
& MUIWF_OPENED
)
3095 data
->wd_Flags
|= MUIWF_OPENONUNHIDE
;
3097 set(obj
, MUIA_Window_Open
, FALSE
);
3100 data
->wd_Flags
|= MUIWF_HIDDEN
;
3104 case MUIA_Window_RootObject
:
3105 ChangeRootObject(data
, obj
, (Object
*) tag
->ti_Data
);
3108 case MUIA_Window_Title
:
3110 FreeVec(data
->wd_Title
);
3111 data
->wd_Title
= StrDup((STRPTR
) tag
->ti_Data
);
3112 if (data
->wd_RenderInfo
.mri_Window
)
3113 SetWindowTitles(data
->wd_RenderInfo
.mri_Window
,
3114 data
->wd_Title
, (CONST_STRPTR
) ~ 0);
3117 case MUIA_Window_ScreenTitle
:
3118 if (data
->wd_ScreenTitle
)
3119 FreeVec(data
->wd_ScreenTitle
);
3120 data
->wd_ScreenTitle
= StrDup((STRPTR
) tag
->ti_Data
);
3121 if (data
->wd_RenderInfo
.mri_Window
)
3122 SetWindowTitles(data
->wd_RenderInfo
.mri_Window
,
3123 (CONST_STRPTR
) ~ 0, data
->wd_ScreenTitle
);
3126 case MUIA_Window_NoMenus
:
3127 data
->wd_NoMenus
= (BOOL
) tag
->ti_Data
;
3128 if (data
->wd_RenderInfo
.mri_Window
)
3130 if (data
->wd_NoMenus
)
3131 data
->wd_RenderInfo
.mri_Window
->Flags
|= WFLG_RMBTRAP
;
3133 data
->wd_RenderInfo
.mri_Window
->Flags
&= ~WFLG_RMBTRAP
;
3137 case MUIA_Window_UseBottomBorderScroller
:
3138 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
3139 MUIWF_USEBOTTOMSCROLLER
);
3142 case MUIA_Window_UseRightBorderScroller
:
3143 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
3144 MUIWF_USERIGHTSCROLLER
);
3147 case MUIA_Window_DisableKeys
:
3148 data
->wd_DisabledKeys
= tag
->ti_Data
;
3151 case MUIA_Window_RefWindow
:
3152 data
->wd_RefWindow
= (Object
*) tag
->ti_Data
;
3155 case MUIA_Window_LeftEdge
:
3156 data
->wd_X
= tag
->ti_Data
;
3159 case MUIA_Window_TopEdge
:
3160 data
->wd_Y
= tag
->ti_Data
;
3163 case MUIA_Window_Width
:
3164 data
->wd_ReqWidth
= (LONG
) tag
->ti_Data
;
3165 data
->wd_Width
= 0; /* otherwise windowselectdimensions()
3166 * ignores ReqWidth */
3169 case MUIA_Window_Height
:
3170 data
->wd_ReqHeight
= (LONG
) tag
->ti_Data
;
3171 data
->wd_Height
= 0;
3174 case MUIA_Window_Screen
:
3175 data
->wd_UserScreen
= (struct Screen
*)tag
->ti_Data
;
3178 case MUIA_Window_PublicScreen
:
3179 data
->wd_UserPublicScreen
= (STRPTR
) tag
->ti_Data
;
3182 case MUIA_Window_Sleep
:
3185 data
->wd_SleepCount
++;
3186 if (data
->wd_RenderInfo
.mri_Window
3187 && (data
->wd_SleepCount
== 1))
3190 (data
->wd_RenderInfo
.mri_Window
,
3191 WA_BusyPointer
, TRUE
,
3192 WA_PointerDelay
, TRUE
, TAG_DONE
);
3193 // FIXME: how to disable event handling?
3198 data
->wd_SleepCount
--;
3199 if (data
->wd_RenderInfo
.mri_Window
3200 && (data
->wd_SleepCount
== 0))
3202 SetWindowPointerA(data
->wd_RenderInfo
.mri_Window
, NULL
);
3210 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
3213 /**************************************************************************
3215 **************************************************************************/
3216 IPTR
Window__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
3218 #define STORE *(msg->opg_Storage)
3220 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3224 switch (msg
->opg_AttrID
)
3226 case MUIA_Window_Activate
:
3228 (data
->wd_Flags
& (MUIWF_ACTIVE
| MUIWF_OPENED
)) ==
3229 (MUIWF_ACTIVE
| MUIWF_OPENED
);
3232 case MUIA_Window_Window
:
3233 STORE
= (IPTR
) data
->wd_RenderInfo
.mri_Window
;
3236 case MUIA_Window_Screen
:
3237 STORE
= (IPTR
) data
->wd_RenderInfo
.mri_Screen
;
3240 case MUIA_Window_PublicScreen
:
3241 STORE
= (IPTR
) data
->wd_UserPublicScreen
;
3244 case MUIA_Window_ActiveObject
:
3245 if ((data
->wd_ActiveObject
!= NULL
)
3246 && (DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
3247 (IPTR
) data
->wd_ActiveObject
) != (IPTR
) NULL
))
3248 STORE
= (IPTR
) data
->wd_ActiveObject
;
3250 STORE
= (IPTR
) NULL
;
3253 case MUIA_Window_CloseRequest
:
3257 case MUIA_Window_DefaultObject
:
3258 STORE
= (IPTR
) data
->wd_DefaultObject
;
3261 case MUIA_Window_DisableKeys
:
3262 STORE
= data
->wd_DisabledKeys
;
3265 case MUIA_Window_Height
:
3266 STORE
= (IPTR
) data
->wd_Height
;
3269 case MUIA_Window_ID
:
3270 STORE
= data
->wd_ID
;
3273 case MUIA_Window_IsSubWindow
:
3274 STORE
= (data
->wd_Flags
& MUIWF_ISSUBWINDOW
) == MUIWF_ISSUBWINDOW
;
3277 case MUIA_Window_LeftEdge
:
3278 if (data
->wd_RenderInfo
.mri_Window
)
3279 STORE
= (IPTR
) data
->wd_RenderInfo
.mri_Window
->LeftEdge
;
3284 case MUIA_Window_Open
:
3285 STORE
= (data
->wd_Flags
& MUIWF_OPENED
) == MUIWF_OPENED
;
3288 case MUIA_Window_RootObject
:
3289 STORE
= (IPTR
) data
->wd_RootObject
;
3292 case MUIA_Window_ScreenTitle
:
3293 STORE
= (IPTR
) data
->wd_ScreenTitle
;
3296 case MUIA_Window_Title
:
3297 STORE
= (IPTR
) data
->wd_Title
;
3300 case MUIA_Window_TopEdge
:
3301 if (data
->wd_RenderInfo
.mri_Window
)
3302 STORE
= (IPTR
) data
->wd_RenderInfo
.mri_Window
->TopEdge
;
3307 case MUIA_Window_Width
:
3308 STORE
= (IPTR
) data
->wd_Width
;
3311 case MUIA_Window_Menustrip
:
3312 STORE
= (IPTR
) data
->wd_ChildMenustrip
;
3315 case MUIA_Window_Sleep
:
3316 STORE
= data
->wd_SleepCount
? TRUE
: FALSE
;
3328 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
3333 * MUIM_FindUData : tests if the MUIA_UserData of the object
3334 * contains the given <udata> and returns the object pointer in this case.
3336 IPTR
Window__MUIM_FindUData(struct IClass
*cl
, Object
*obj
,
3337 struct MUIP_FindUData
*msg
)
3339 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3341 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3344 if (data
->wd_RootObject
)
3345 return DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
3352 * MUIM_GetUData : This method tests if the MUIA_UserData of the object
3353 * contains the given <udata> and gets <attr> to <storage> for itself
3356 IPTR
Window__MUIM_GetUData(struct IClass
*cl
, Object
*obj
,
3357 struct MUIP_GetUData
*msg
)
3359 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3361 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3363 get(obj
, msg
->attr
, msg
->storage
);
3367 if (data
->wd_RootObject
)
3368 return DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
3375 * MUIM_SetUData : This method tests if the MUIA_UserData of the object
3376 * contains the given <udata> and sets <attr> to <val> for itself in this case.
3378 IPTR
Window__MUIM_SetUData(struct IClass
*cl
, Object
*obj
,
3379 struct MUIP_SetUData
*msg
)
3381 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3383 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3384 set(obj
, msg
->attr
, msg
->val
);
3386 if (data
->wd_RootObject
)
3387 DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
3394 * MUIM_SetUDataOnce : This method tests if the MUIA_UserData of the object
3395 * contains the given <udata> and sets <attr> to <val> for itself in this case.
3397 IPTR
Window__MUIM_SetUDataOnce(struct IClass
*cl
, Object
*obj
,
3398 struct MUIP_SetUDataOnce
*msg
)
3400 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3402 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3404 set(obj
, msg
->attr
, msg
->val
);
3408 if (data
->wd_RootObject
)
3409 return DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
3414 /**************************************************************************
3415 Called by Application (parent) object whenever this object is added.
3417 **************************************************************************/
3418 IPTR
Window__MUIM_ConnectParent(struct IClass
*cl
, Object
*obj
,
3419 struct MUIP_ConnectParent
*msg
)
3421 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3423 if (!DoSuperMethodA(cl
, obj
, (Msg
) msg
))
3426 if (data
->wd_RootObject
)
3427 DoMethod(data
->wd_RootObject
, MUIM_ConnectParent
, (IPTR
) obj
);
3429 if (data
->wd_ChildMenustrip
)
3430 DoMethod(data
->wd_ChildMenustrip
, MUIM_ConnectParent
, (IPTR
) obj
);
3436 /**************************************************************************
3437 called by parent object
3438 **************************************************************************/
3439 IPTR
Window__MUIM_DisconnectParent(struct IClass
*cl
, Object
*obj
,
3440 struct MUIP_DisconnectParent
*msg
)
3442 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3444 /* D(bug("Window_DisconnectParent(%p) : muiGlobalInfo=%p\n", */
3445 /* muiGlobalInfo(obj))); */
3446 if (muiGlobalInfo(obj
))
3448 /* Close the window before disconnecting all the childs */
3449 if ((data
->wd_Flags
& MUIWF_OPENED
))
3451 /* D(bug(" Window_DisconnectParent(%p) : closing window\n", */
3452 /* muiGlobalInfo(obj))); */
3453 set(obj
, MUIA_Window_Open
, FALSE
);
3455 if (data
->wd_ChildMenustrip
)
3456 DoMethod(data
->wd_ChildMenustrip
, MUIM_DisconnectParent
,
3459 if (data
->wd_RootObject
)
3460 DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
3462 /* D(bug(" Window_DisconnectParent(%p) : calling supermethod\n", */
3463 /* muiGlobalInfo(obj))); */
3464 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
3472 static void SetRootObjInnerSpacing(Object
*obj
,
3473 struct MUI_WindowData
*data
)
3475 UWORD wd_innerLeft
, wd_innerRight
, wd_innerTop
, wd_innerBottom
;
3477 if (data
->wd_CrtFlags
& WFLG_BORDERLESS
)
3486 wd_innerLeft
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_left
;
3487 wd_innerRight
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_right
;
3488 wd_innerTop
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_top
;
3489 wd_innerBottom
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_bottom
;
3492 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERLEFT
))
3494 muiAreaData(data
->wd_RootObject
)->mad_InnerLeft
= wd_innerLeft
;
3497 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERTOP
))
3499 muiAreaData(data
->wd_RootObject
)->mad_InnerTop
= wd_innerTop
;
3502 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERRIGHT
))
3504 muiAreaData(data
->wd_RootObject
)->mad_InnerRight
= wd_innerRight
;
3507 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERBOTTOM
))
3509 muiAreaData(data
->wd_RootObject
)->mad_InnerBottom
= wd_innerBottom
;
3514 * Called before window is opened or resized. It determines its bounds,
3515 * so you can call WindowSelectDimensions() to find the final dims.
3517 static void WindowMinMax(Object
*obj
, struct MUI_WindowData
*data
)
3519 SetRootObjInnerSpacing(obj
, data
);
3520 /* inquire about sizes */
3521 DoMethod(data
->wd_RootObject
, MUIM_AskMinMax
, (IPTR
) & data
->wd_MinMax
);
3522 /* D(bug("*** root minmax = %ld,%ld => %ld,%ld\n", */
3523 /* data->wd_MinMax.MinWidth, */
3524 /* data->wd_MinMax.MinHeight, */
3525 /* data->wd_MinMax.MaxWidth, data->wd_MinMax.MaxHeight)); */
3526 __area_finish_minmax(data
->wd_RootObject
, &data
->wd_MinMax
);
3527 /* D(bug("*** root minmax2 = %ld,%ld => %ld,%ld\n", */
3528 /* data->wd_MinMax.MinWidth, */
3529 /* data->wd_MinMax.MinHeight, */
3530 /* data->wd_MinMax.MaxWidth, data->wd_MinMax.MaxHeight)); */
3534 static void InstallBackbuffer(struct IClass
*cl
, Object
*obj
)
3536 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3538 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
3540 data
->wd_RenderInfo
.mri_BufferBM
=
3541 AllocBitMap(win
->Width
, win
->Height
, win
->RPort
->BitMap
->Depth
,
3542 0, win
->RPort
->BitMap
);
3544 if (data
->wd_RenderInfo
.mri_BufferBM
)
3546 /* D(bug("install_backbuffer : allocated bitmap %dx%dx%d " */
3547 /* "with friend %p\n", */
3548 /* win->Width, win->Height, win->RPort->BitMap->Depth, */
3549 /* win->RPort->BitMap)); */
3550 InitRastPort(&data
->wd_RenderInfo
.mri_BufferRP
);
3551 data
->wd_RenderInfo
.mri_BufferRP
.BitMap
=
3552 data
->wd_RenderInfo
.mri_BufferBM
;
3556 static void DeinstallBackbuffer(struct IClass
*cl
, Object
*obj
)
3558 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3560 if (data
->wd_RenderInfo
.mri_BufferBM
)
3562 DeinitRastPort(&data
->wd_RenderInfo
.mri_BufferRP
);
3563 FreeBitMap(data
->wd_RenderInfo
.mri_BufferBM
);
3564 data
->wd_RenderInfo
.mri_BufferBM
= NULL
;
3569 * Called after window is opened or resized.
3570 * An expose event is already queued, it will trigger
3571 * MUIM_Draw for us when going back to main loop.
3573 static void WindowShow(struct IClass
*cl
, Object
*obj
)
3575 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3576 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
3577 /* D(bug("WindowShow %s %d\n", __FILE__, __LINE__)); */
3579 _left(data
->wd_RootObject
) = win
->BorderLeft
;
3580 _top(data
->wd_RootObject
) = win
->BorderTop
;
3581 _width(data
->wd_RootObject
) = data
->wd_Width
;
3582 _height(data
->wd_RootObject
) = data
->wd_Height
;
3584 DoMethod(data
->wd_RootObject
, MUIM_Layout
);
3586 ShowRenderInfo(&data
->wd_RenderInfo
);
3587 /* D(bug("zune_imspec_show %s %d\n", __FILE__, __LINE__)); */
3588 zune_imspec_show(data
->wd_Background
, obj
);
3589 DoShowMethod(data
->wd_RootObject
);
3592 static ULONG
WindowOpen(struct IClass
*cl
, Object
*obj
)
3594 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3596 if (!data
->wd_RootObject
)
3599 if (!DoMethod(obj
, MUIM_Window_Setup
))
3602 /* I got display info, so calculate your display dependant data */
3603 if (!DoSetupMethod(data
->wd_RootObject
, &data
->wd_RenderInfo
))
3605 DoMethod(obj
, MUIM_Window_Cleanup
);
3609 /* inquire about sizes */
3610 WindowMinMax(obj
, data
);
3611 WindowSelectDimensions(data
);
3613 /* Decide which menustrip should be used */
3614 if (!data
->wd_ChildMenustrip
)
3615 get(_app(obj
), MUIA_Application_Menustrip
, &data
->wd_Menustrip
);
3617 data
->wd_Menustrip
= data
->wd_ChildMenustrip
;
3619 /* open window here ... */
3620 if (!DisplayWindow(obj
, data
))
3622 /* free display dependant data */
3623 data
->wd_Menustrip
= NULL
;
3624 DoMethod(data
->wd_RootObject
, MUIM_Cleanup
);
3625 DoMethod(obj
, MUIM_Window_Cleanup
);
3629 InstallBackbuffer(cl
, obj
);
3631 data
->wd_Flags
|= MUIWF_OPENED
;
3633 WindowShow(cl
, obj
);
3636 LONG left
, top
, width
, height
;
3638 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
3639 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
,
3640 width
= data
->wd_RenderInfo
.mri_Window
->Width
3641 - data
->wd_RenderInfo
.mri_Window
->BorderRight
- left
;
3642 height
= data
->wd_RenderInfo
.mri_Window
->Height
3643 - data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
3645 /* D(bug("zune_imspec_draw %s %d\n", __FILE__, __LINE__)); */
3646 // D(bug("%d:zune_imspec_draw(%p) l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
3647 // __LINE__, data->wd_Background, left, top, width,
3648 // height, left, top));
3650 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
3651 left
, top
, width
, height
, left
, top
, 0);
3654 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWOBJECT
);
3656 D(bug("MUIC_Window:windowOpen() ActiveObject=%p\n",
3657 data
->wd_ActiveObject
));
3658 if (data
->wd_OldActive
!= NULL
)
3660 set(obj
, MUIA_Window_ActiveObject
, data
->wd_OldActive
);
3666 /**************************************************************************/
3667 /**************************************************************************/
3669 static ULONG
WindowClose(struct IClass
*cl
, Object
*obj
)
3671 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3673 if (data
->wd_ActiveObject
!= NULL
)
3675 data
->wd_OldActive
= data
->wd_ActiveObject
;
3676 set(obj
, MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_None
);
3679 KillHelpBubble(data
, obj
, BUBBLEHELP_TICKER_FIRST
);
3681 /* remove from window */
3682 DoHideMethod(data
->wd_RootObject
);
3683 zune_imspec_hide(data
->wd_Background
);
3685 DeinstallBackbuffer(cl
, obj
);
3687 HideRenderInfo(&data
->wd_RenderInfo
);
3689 /* close here ... */
3690 UndisplayWindow(obj
, data
);
3692 data
->wd_Flags
&= ~MUIWF_OPENED
;
3693 data
->wd_Menustrip
= NULL
;
3695 /* free display dependant data */
3696 DoMethod(data
->wd_RootObject
, MUIM_Cleanup
);
3697 DoMethod(obj
, MUIM_Window_Cleanup
);
3701 /* calculate a new layout
3703 * see Group_ExitChange
3707 IPTR
Window__MUIM_RecalcDisplay(struct IClass
*cl
, Object
*obj
,
3708 struct MUIP_Window_RecalcDisplay
*msg
)
3710 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3711 LONG left
, top
, width
, height
;
3712 BOOL resized
, reshow
= FALSE
;
3713 Object
*current_obj
;
3715 if (!(data
->wd_Flags
& MUIWF_OPENED
))
3718 current_obj
= msg
->originator
;
3720 // typically originator is a group which has been added/removed a child
3721 // calculate minmax of current obj
3722 // if new minmax can accomodate current obj size, stop
3723 // else try with its parent
3724 // the resulting object will get a new layout
3725 // it currently produces some redundant AskMinMax but allows
3726 // to not always relayout the whole window
3728 D(bug("RecalcDisplay on %p\n", current_obj
));
3729 while (current_obj
!= NULL
)
3731 DoMethod(current_obj
, MUIM_AskMinMax
,
3732 (IPTR
) & muiAreaData(current_obj
)->mad_MinMax
);
3733 __area_finish_minmax(current_obj
,
3734 &muiAreaData(current_obj
)->mad_MinMax
);
3736 D(bug("size w = %d, h = %d\n", _width(current_obj
),
3737 _height(current_obj
)));
3738 D(bug("new w = %d-%d, h = %d-%d\n", _minwidth(current_obj
),
3739 _maxwidth(current_obj
), _minheight(current_obj
),
3740 _maxheight(current_obj
)));
3742 if (!_between(_minwidth(current_obj
), _width(current_obj
),
3743 _maxwidth(current_obj
))
3744 || !_between(_minheight(current_obj
), _height(current_obj
),
3745 _maxheight(current_obj
)))
3747 current_obj
= _parent(current_obj
);
3748 D(bug("RecalcDisplay, try parent %p\n", current_obj
));
3752 D(bug("found it\n"));
3758 current_obj
= data
->wd_RootObject
;
3760 WindowMinMax(obj
, data
);
3762 /* Important: current_obj could be hidden, like in an inactive page! */
3763 if (_flags(current_obj
) & MADF_CANDRAW
)
3769 DoHideMethod(current_obj
);
3771 /* resize window ? */
3772 WindowSelectDimensions(data
);
3773 resized
= WindowResize(data
);
3777 /* FIXME: Should we short circuit the following
3778 * if the window size didn't change?
3783 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
3784 _left(data
->wd_RootObject
) = win
->BorderLeft
;
3785 _top(data
->wd_RootObject
) = win
->BorderTop
;
3786 _width(data
->wd_RootObject
) = data
->wd_Width
;
3787 _height(data
->wd_RootObject
) = data
->wd_Height
;
3789 DoMethod(current_obj
, MUIM_Layout
);
3792 DoShowMethod(current_obj
);
3794 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_redraw
==
3795 WINDOW_REDRAW_WITHOUT_CLEAR
)
3798 MUI_Redraw(current_obj
, MADF_DRAWOBJECT
);
3802 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
3803 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
;
3804 width
= data
->wd_RenderInfo
.mri_Window
->Width
3805 - data
->wd_RenderInfo
.mri_Window
->BorderRight
- left
;
3806 height
= data
->wd_RenderInfo
.mri_Window
->Height
3807 - data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
3809 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
3810 left
, top
, width
, height
, left
, top
, 0);
3811 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWALL
);
3814 ActivateObject(data
);
3820 /**************************************************************************
3821 MUIM_AddEventHandler
3822 **************************************************************************/
3823 IPTR
Window__MUIM_AddEventHandler(struct IClass
*cl
, Object
*obj
,
3824 struct MUIP_Window_AddEventHandler
*msg
)
3826 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3828 //D(bug("muimaster.library/window.c: Add Eventhandler %p\n", msg->ehnode));
3830 msg
->ehnode
->ehn_Priority
= msg
->ehnode
->ehn_Priority
;
3831 EnqueueByPriAndAddress((struct List
*)&data
->wd_EHList
,
3832 (struct Node
*)msg
->ehnode
);
3833 ChangeEvents(data
, GetDefaultEvents());
3837 /**************************************************************************
3838 MUIM_RemEventHandler
3839 **************************************************************************/
3840 IPTR
Window__MUIM_RemEventHandler(struct IClass
*cl
, Object
*obj
,
3841 struct MUIP_Window_RemEventHandler
*msg
)
3843 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3845 //D(bug("muimaster.library/window.c: Rem Eventhandler %p\n", msg->ehnode));
3847 Remove((struct Node
*)msg
->ehnode
);
3848 ChangeEvents(data
, GetDefaultEvents());
3852 /**************************************************************************
3853 Note that this is MUIM_Window_Setup, not MUIM_Setup
3854 **************************************************************************/
3855 IPTR
Window__MUIM_Setup(struct IClass
*cl
, Object
*obj
, Msg msg
)
3857 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3859 if (!SetupRenderInfo(obj
, data
, &data
->wd_RenderInfo
))
3862 data
->wd_Background
=
3863 zune_imspec_setup(MUII_WindowBack
, &data
->wd_RenderInfo
);
3865 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_redraw
==
3866 WINDOW_REDRAW_WITH_CLEAR
)
3867 data
->wd_Flags
|= MUIWF_ERASEAREA
;
3872 /**************************************************************************
3874 **************************************************************************/
3875 IPTR
Window__MUIM_Cleanup(struct IClass
*cl
, Object
*obj
, Msg msg
)
3877 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3879 zune_imspec_cleanup(data
->wd_Background
);
3883 DeleteDragNDrop(data
->wd_dnd
);
3884 data
->wd_dnd
= NULL
;
3887 CleanupRenderInfo(obj
, data
, &data
->wd_RenderInfo
);
3892 /**************************************************************************
3893 This adds the the control char handler and also do the MUIA_CycleChain
3894 stuff. Orginal MUI does this in an other way.
3895 **************************************************************************/
3896 IPTR
Window__MUIM_AddControlCharHandler(struct IClass
*cl
, Object
*obj
,
3897 struct MUIP_Window_AddControlCharHandler
*msg
)
3899 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3900 struct ObjNode
*node
;
3902 if (msg
->ccnode
->ehn_Events
)
3904 msg
->ccnode
->ehn_Priority
= msg
->ccnode
->ehn_Priority
;
3905 Enqueue((struct List
*)&data
->wd_CCList
,
3906 (struct Node
*)msg
->ccnode
);
3908 /* Due to the lack of a better idea ... */
3909 if (muiAreaData(msg
->ccnode
->ehn_Object
)->mad_Flags
& MADF_CYCLECHAIN
)
3911 node
= AllocPooled(data
->wd_MemoryPool
, sizeof(struct ObjNode
));
3914 node
->obj
= msg
->ccnode
->ehn_Object
;
3915 AddTail((struct List
*)&data
->wd_CycleChain
,
3916 (struct Node
*)node
);
3922 /**************************************************************************
3923 MUIM_RemControlCharHandler
3924 **************************************************************************/
3925 IPTR
Window__MUIM_RemControlCharHandler(struct IClass
*cl
, Object
*obj
,
3926 struct MUIP_Window_RemControlCharHandler
*msg
)
3928 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3929 struct ObjNode
*node
=
3930 FindObjNode(&data
->wd_CycleChain
, msg
->ccnode
->ehn_Object
);
3932 if (msg
->ccnode
->ehn_Events
)
3933 Remove((struct Node
*)msg
->ccnode
);
3937 /* Remove from the chain list */
3938 Remove((struct Node
*)node
);
3939 FreePooled(data
->wd_MemoryPool
, node
, sizeof(struct ObjNode
));
3945 /**************************************************************************
3947 **************************************************************************/
3948 IPTR
Window__MUIM_DragObject(struct IClass
*cl
, Object
*obj
,
3949 struct MUIP_Window_DragObject
*msg
)
3951 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3954 struct DragNDrop
*dnd
;
3955 struct MUI_DragImage
*di
;
3956 struct BitMapNode
*bmn
;
3958 if (!(dnd
= CreateDragNDropA(NULL
)))
3962 (struct MUI_DragImage
*)DoMethod(msg
->obj
,
3963 MUIM_CreateDragImage
, -msg
->touchx
, -msg
->touchy
,
3966 DeleteDragNDrop(dnd
);
3971 DoMethod(msg
->obj
, MUIM_DeleteDragImage
, (IPTR
) di
);
3972 DeleteDragNDrop(dnd
);
3976 if (!(bmn
= CreateBitMapNodeA(TAGLIST(
3977 GUI_BitMap
, (IPTR
)di
->bm
,
3978 GUI_LeftOffset
, di
->touchx
,
3979 GUI_TopOffset
, di
->touchy
,
3980 GUI_Width
, di
->width
,
3981 GUI_Height
, di
->height
,
3982 GUI_SourceAlpha
, !!(di
->flags
& MUIF_DRAGIMAGE_SOURCEALPHA
)))))
3984 DoMethod(msg
->obj
, MUIM_DeleteDragImage
, (IPTR
) di
);
3985 DeleteDragNDrop(dnd
);
3989 AttachBitMapNode(dnd
, bmn
);
3991 if (!PrepareDragNDrop(dnd
, data
->wd_RenderInfo
.mri_Screen
))
3993 DoMethod(msg
->obj
, MUIM_DeleteDragImage
, (IPTR
) di
);
3994 DeleteDragNDrop(dnd
);
3998 muiAreaData(msg
->obj
)->mad_Flags
|= MADF_DRAGGING
;
4000 data
->wd_DragObject
= msg
->obj
;
4002 data
->wd_DragImage
= di
;
4008 /**************************************************************************
4010 **************************************************************************/
4011 IPTR
Window__MUIM_AllocGadgetID(struct IClass
*cl
, Object
*obj
,
4012 struct MUIP_Window_AllocGadgetID
*msg
)
4014 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4015 struct IDNode
*newnode
;
4017 newnode
= AllocPooled(data
->wd_MemoryPool
, sizeof(struct IDNode
));
4023 if (IsListEmpty((struct List
*)&data
->wd_IDList
))
4026 AddHead((struct List
*)&data
->wd_IDList
,
4027 (struct Node
*)&newnode
->node
);
4033 for (mn
= data
->wd_IDList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
4035 struct IDNode
*idn
= (struct IDNode
*)mn
;
4041 Insert((struct List
*)&data
->wd_IDList
,
4042 (struct Node
*)&newnode
->node
, (struct Node
*)mn
);
4049 /**************************************************************************
4051 **************************************************************************/
4052 IPTR
Window__MUIM_FreeGadgetID(struct IClass
*cl
, Object
*obj
,
4053 struct MUIP_Window_FreeGadgetID
*msg
)
4055 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4058 for (mn
= data
->wd_IDList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
4060 struct IDNode
*idn
= (struct IDNode
*)mn
;
4061 if (msg
->gadgetid
== idn
->id
)
4063 Remove((struct Node
*)idn
);
4064 FreePooled(data
->wd_MemoryPool
, idn
, sizeof(struct IDNode
));
4073 /**************************************************************************
4074 MUIM_Window_GetMenuCheck
4075 **************************************************************************/
4076 IPTR
Window__MUIM_GetMenuCheck(struct IClass
*cl
, Object
*obj
,
4077 struct MUIP_Window_GetMenuCheck
*msg
)
4080 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4082 Object
*strip
= data
->wd_ChildMenustrip
;
4084 strip
= data
->wd_Menustrip
;
4087 if (!(item
= (Object
*) DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
)))
4089 get(item
, MUIA_Menuitem_Checked
, &stat
);
4093 /**************************************************************************
4094 MUIM_Window_SetMenuCheck
4095 **************************************************************************/
4096 IPTR
Window__MUIM_SetMenuCheck(struct IClass
*cl
, Object
*obj
,
4097 struct MUIP_Window_SetMenuCheck
*msg
)
4099 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4101 Object
*strip
= data
->wd_ChildMenustrip
;
4103 strip
= data
->wd_Menustrip
;
4106 if (!(item
= (Object
*) DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
)))
4108 set(item
, MUIA_Menuitem_Checked
, msg
->stat
);
4112 /**************************************************************************
4113 MUIM_Window_GetMenuState
4114 **************************************************************************/
4115 IPTR
Window__MUIM_GetMenuState(struct IClass
*cl
, Object
*obj
,
4116 struct MUIP_Window_GetMenuState
*msg
)
4119 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4121 Object
*strip
= data
->wd_ChildMenustrip
;
4123 strip
= data
->wd_Menustrip
;
4126 if (!(item
= (Object
*) DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
)))
4128 get(item
, MUIA_Menuitem_Enabled
, &stat
);
4132 /**************************************************************************
4133 MUIM_Window_SetMenuState
4134 **************************************************************************/
4135 IPTR
Window__MUIM_SetMenuState(struct IClass
*cl
, Object
*obj
,
4136 struct MUIP_Window_SetMenuState
*msg
)
4138 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4140 Object
*strip
= data
->wd_ChildMenustrip
;
4142 strip
= data
->wd_Menustrip
;
4145 if (!(item
= (Object
*) DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
)))
4147 set(item
, MUIA_Menuitem_Enabled
, msg
->stat
);
4151 /**************************************************************************
4152 MUIM_Window_DrawBackground
4153 **************************************************************************/
4154 IPTR
Window__MUIM_DrawBackground(struct IClass
*cl
, Object
*obj
,
4155 struct MUIP_Window_DrawBackground
*msg
)
4157 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4158 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
4161 // D(bug("%d:zune_imspec_draw(%p) l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
4162 // __LINE__, data->wd_Background, msg->left, msg->top, msg->width,
4163 // msg->height, msg->xoffset, msg->yoffset));
4164 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
4165 msg
->left
, msg
->top
, msg
->width
, msg
->height
,
4166 msg
->xoffset
, msg
->yoffset
, 0);
4170 /**************************************************************************
4172 **************************************************************************/
4173 IPTR
Window__MUIM_ToFront(struct IClass
*cl
, Object
*obj
, Msg msg
)
4175 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4176 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
4179 WindowToFront(data
->wd_RenderInfo
.mri_Window
);
4183 /**************************************************************************
4185 **************************************************************************/
4186 IPTR
Window__MUIM_ToBack(struct IClass
*cl
, Object
*obj
, Msg msg
)
4188 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4189 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
4192 WindowToBack(data
->wd_RenderInfo
.mri_Window
);
4196 /**************************************************************************
4197 MUIM_Window_ScreenToBack
4198 **************************************************************************/
4199 IPTR
Window__MUIM_ScreenToBack(struct IClass
*cl
, Object
*obj
, Msg msg
)
4201 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4202 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
4205 ScreenToBack(data
->wd_RenderInfo
.mri_Screen
);
4209 /**************************************************************************
4210 MUIM_Window_ScreenToFront
4211 **************************************************************************/
4212 IPTR
Window__MUIM_ScreenToFront(struct IClass
*cl
, Object
*obj
, Msg msg
)
4214 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4215 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
4218 ScreenToFront(data
->wd_RenderInfo
.mri_Screen
);
4222 /**************************************************************************
4223 MUIM_Window_ActionIconify
4224 **************************************************************************/
4225 IPTR
Window__MUIM_ActionIconify(struct IClass
*cl
, Object
*obj
, Msg msg
)
4227 set(_app(obj
), MUIA_Application_Iconified
, TRUE
);
4233 /* Loads ENV: prefs, add a Window_ID chunk in the MUIW chunk, if no MUIW chunk
4234 * then create it at the same level as MUIC chunk, save prefs.
4235 * Do the same for ENVARC:
4236 * MUIW chunk layout:
4238 * 00 00 00 30 (chunk length for a single window, 0x30L big endian)
4241 * xx xx yy yy (X, Y)
4242 * ww ww hh hh (Width, Height)
4243 * ax ax ay ay (AltX, AltY)
4244 * aw aw ah ah (AltWidth, AltHeight)
4252 static void RememberWindowPosition(Object
*winobj
, ULONG id
)
4258 /* Loads ENV: prefs, remove our Window_ID chunk from the MUIW chunk,
4260 * Do the same for ENVARC:
4261 * This function shouldn't really be in window.c, but rather in a file dealing
4262 * with prefs file stuff.
4264 static void ForgetWindowPosition(Object
*winobj
, ULONG id
)
4270 /**************************************************************************
4271 MUIM_Window_Snapshot
4272 **************************************************************************/
4273 IPTR
Window__MUIM_Snapshot(struct IClass
*cl
, Object
*obj
,
4274 struct MUIP_Window_Snapshot
*msg
)
4276 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4277 struct windowpos winp
;
4280 winp
.id
= data
->wd_ID
;
4281 w
= data
->wd_RenderInfo
.mri_Window
;
4284 winp
.x1
= w
->LeftEdge
;
4285 winp
.y1
= w
->TopEdge
;
4286 winp
.w1
= w
->GZZWidth
;
4287 winp
.h1
= w
->GZZHeight
;
4291 winp
.h2
= 0; //to do save alt dims
4293 set(_app(obj
), MUIA_Application_SetWinPos
, &winp
);
4297 RememberWindowPosition(obj
, data
->wd_ID
);
4299 ForgetWindowPosition(obj
, data
->wd_ID
);
4303 /**************************************************************************
4304 MUIM_Window_UpdateMenu
4305 **************************************************************************/
4306 IPTR
Window__MUIM_UpdateMenu(struct IClass
*cl
, Object
*obj
, Msg msg
)
4308 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4310 struct Menu
*menu
= NULL
;
4311 struct NewMenu
*newmenu
= NULL
;
4312 APTR visinfo
= NULL
;
4313 struct Window
*win
= NULL
;
4315 if (data
->wd_Menustrip
) // only open windows can have a menustrip
4318 GetVisualInfoA(data
->wd_RenderInfo
.mri_Screen
, NULL
)))
4320 win
= data
->wd_RenderInfo
.mri_Window
;
4321 ClearMenuStrip(win
);
4324 FreeMenus(data
->wd_Menu
);
4325 data
->wd_Menu
= NULL
;
4328 get(data
->wd_Menustrip
, MUIA_Menuitem_NewMenu
, &newmenu
);
4331 if ((menu
= CreateMenusA(newmenu
, NULL
)))
4333 struct TagItem tags
[] = {
4334 {GTMN_NewLookMenus
, TRUE
},
4337 LayoutMenusA(menu
, visinfo
, tags
);
4338 data
->wd_Menu
= menu
;
4339 SetMenuStrip(win
, menu
);
4342 FreeVisualInfo(visinfo
);
4349 /**************************************************************************
4350 MUIM_Export : to export an object's "contents" to a dataspace object.
4351 **************************************************************************/
4352 static IPTR
Window__MUIM_Export(struct IClass
*cl
, Object
*obj
,
4353 struct MUIP_Export
*msg
)
4355 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4356 DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
4361 /**************************************************************************
4362 MUIM_Import : to import an object's "contents" from a dataspace object.
4363 **************************************************************************/
4364 static IPTR
Window__MUIM_Import(struct IClass
*cl
, Object
*obj
,
4365 struct MUIP_Import
*msg
)
4367 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4368 DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
4372 BOOPSI_DISPATCHER(IPTR
, Window_Dispatcher
, cl
, obj
, msg
)
4374 switch (msg
->MethodID
)
4377 return Window__OM_NEW(cl
, obj
, (struct opSet
*)msg
);
4379 return Window__OM_DISPOSE(cl
, obj
, msg
);
4381 return Window__OM_SET(cl
, obj
, (struct opSet
*)msg
);
4383 return Window__OM_GET(cl
, obj
, (struct opGet
*)msg
);
4384 case MUIM_FindUData
:
4385 return Window__MUIM_FindUData(cl
, obj
,
4386 (struct MUIP_FindUData
*)msg
);
4388 return Window__MUIM_GetUData(cl
, obj
, (struct MUIP_GetUData
*)msg
);
4390 return Window__MUIM_SetUData(cl
, obj
, (struct MUIP_SetUData
*)msg
);
4391 case MUIM_SetUDataOnce
:
4392 return Window__MUIM_SetUDataOnce(cl
, obj
,
4393 (struct MUIP_SetUDataOnce
*)msg
);
4394 case MUIM_Window_AddEventHandler
:
4395 return Window__MUIM_AddEventHandler(cl
, obj
, (APTR
) msg
);
4396 case MUIM_Window_RemEventHandler
:
4397 return Window__MUIM_RemEventHandler(cl
, obj
, (APTR
) msg
);
4398 case MUIM_ConnectParent
:
4399 return Window__MUIM_ConnectParent(cl
, obj
, (APTR
) msg
);
4400 case MUIM_DisconnectParent
:
4401 return Window__MUIM_DisconnectParent(cl
, obj
, (APTR
) msg
);
4402 case MUIM_Window_RecalcDisplay
:
4403 return Window__MUIM_RecalcDisplay(cl
, obj
, (APTR
) msg
);
4404 case MUIM_Window_Setup
:
4405 return Window__MUIM_Setup(cl
, obj
, (APTR
) msg
);
4406 case MUIM_Window_Cleanup
:
4407 return Window__MUIM_Cleanup(cl
, obj
, (APTR
) msg
);
4408 case MUIM_Window_AddControlCharHandler
:
4409 return Window__MUIM_AddControlCharHandler(cl
, obj
, (APTR
) msg
);
4410 case MUIM_Window_RemControlCharHandler
:
4411 return Window__MUIM_RemControlCharHandler(cl
, obj
, (APTR
) msg
);
4412 case MUIM_Window_DragObject
:
4413 return Window__MUIM_DragObject(cl
, obj
, (APTR
) msg
);
4414 case MUIM_Window_AllocGadgetID
:
4415 return Window__MUIM_AllocGadgetID(cl
, obj
, (APTR
) msg
);
4416 case MUIM_Window_FreeGadgetID
:
4417 return Window__MUIM_FreeGadgetID(cl
, obj
, (APTR
) msg
);
4418 case MUIM_Window_GetMenuCheck
:
4419 return Window__MUIM_GetMenuCheck(cl
, obj
, (APTR
) msg
);
4420 case MUIM_Window_SetMenuCheck
:
4421 return Window__MUIM_SetMenuCheck(cl
, obj
, (APTR
) msg
);
4422 case MUIM_Window_GetMenuState
:
4423 return Window__MUIM_GetMenuState(cl
, obj
, (APTR
) msg
);
4424 case MUIM_Window_SetMenuState
:
4425 return Window__MUIM_SetMenuState(cl
, obj
, (APTR
) msg
);
4426 case MUIM_Window_DrawBackground
:
4427 return Window__MUIM_DrawBackground(cl
, obj
, (APTR
) msg
);
4428 case MUIM_Window_ToFront
:
4429 return Window__MUIM_ToFront(cl
, obj
, (APTR
) msg
);
4430 case MUIM_Window_ToBack
:
4431 return Window__MUIM_ToBack(cl
, obj
, (APTR
) msg
);
4432 case MUIM_Window_ScreenToFront
:
4433 return Window__MUIM_ScreenToFront(cl
, obj
, (APTR
) msg
);
4434 case MUIM_Window_ScreenToBack
:
4435 return Window__MUIM_ScreenToBack(cl
, obj
, (APTR
) msg
);
4436 case MUIM_Window_ActionIconify
:
4437 return Window__MUIM_ActionIconify(cl
, obj
, (APTR
) msg
);
4438 case MUIM_Window_Snapshot
:
4439 return Window__MUIM_Snapshot(cl
, obj
, (APTR
) msg
);
4440 case MUIM_Window_UpdateMenu
:
4441 return Window__MUIM_UpdateMenu(cl
, obj
, (APTR
) msg
);
4443 return Window__MUIM_Export(cl
, obj
, (APTR
) msg
);
4445 return Window__MUIM_Import(cl
, obj
, (APTR
) msg
);
4448 return DoSuperMethodA(cl
, obj
, msg
);
4450 BOOPSI_DISPATCHER_END
4455 const struct __MUIBuiltinClass _MUI_Window_desc
=
4459 sizeof(struct MUI_WindowData
),
4460 (void *) Window_Dispatcher