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
:
1657 ReplyMsg((struct Message
*)imsg
);
1661 int hborders
= iWin
->BorderLeft
+ iWin
->BorderRight
;
1662 int vborders
= iWin
->BorderTop
+ iWin
->BorderBottom
;
1664 /* set window limits according to window contents */
1667 data
->wd_MinMax
.MinWidth
+ hborders
,
1668 data
->wd_MinMax
.MinHeight
+ vborders
,
1669 data
->wd_MinMax
.MaxWidth
+ hborders
,
1670 data
->wd_MinMax
.MaxHeight
+ vborders
);
1673 if ((iWin
->GZZWidth
!= data
->wd_Width
)
1674 || (iWin
->GZZHeight
!= data
->wd_Height
))
1676 data
->wd_Width
= iWin
->GZZWidth
;
1677 data
->wd_Height
= iWin
->GZZHeight
;
1678 DoHideMethod(data
->wd_RootObject
);
1680 data
->wd_Flags
|= MUIWF_RESIZING
;
1681 RefreshWindow(oWin
, data
);
1685 case IDCMP_REFRESHWINDOW
:
1686 ReplyMsg((struct Message
*)imsg
);
1688 RefreshWindow(oWin
, data
);
1691 case IDCMP_CLOSEWINDOW
:
1692 ReplyMsg((struct Message
*)imsg
);
1694 set(oWin
, MUIA_Window_CloseRequest
, TRUE
);
1697 case IDCMP_MENUPICK
:
1698 ReplyMsg((struct Message
*)imsg
);
1703 if (MENUNUM(imsg
->Code
) != NOMENU
1704 && ITEMNUM(imsg
->Code
) != NOITEM
)
1706 struct MenuItem
*item
=
1707 ItemAddress(data
->wd_Menu
, imsg
->Code
);
1710 Object
*item_obj
= (Object
*) GTMENUITEM_USERDATA(item
);
1716 if (item
->Flags
& CHECKIT
)
1717 set(item_obj
, MUIA_Menuitem_Checked
,
1718 ! !(item
->Flags
& CHECKED
));
1720 set(item_obj
, MUIA_Menuitem_Trigger
, (IPTR
) item
);
1722 get(oWin
, MUIA_ApplicationObject
, &app
);
1723 get(item_obj
, MUIA_UserData
, &udata
);
1725 set(app
, MUIA_Application_MenuAction
, udata
);
1726 set(oWin
, MUIA_Window_MenuAction
, udata
);
1727 DoMethod(app
, MUIM_Application_ReturnID
, udata
);
1734 case IDCMP_IDCMPUPDATE
:
1735 is_handled
= FALSE
; /* forwardable to area event handlers */
1736 if (data
->wd_VertProp
|| data
->wd_HorizProp
)
1738 struct TagItem
*tag
;
1739 tag
= FindTagItem(GA_ID
, (struct TagItem
*)imsg
->IAddress
);
1742 /* If there's a propclass object connected to the prop
1743 gadget, the prop gadget's userdata will point to
1744 that propclass object. See classes/prop.c */
1746 if (data
->wd_VertProp
)
1748 if (tag
->ti_Data
== GADGETID(data
->wd_VertProp
))
1751 if (tag
->ti_Data
== GADGETID(data
->wd_UpButton
))
1754 (Object
*) ((struct Gadget
*)data
->
1755 wd_VertProp
)->UserData
;
1758 DoMethod(prop
, MUIM_Prop_Decrease
, 1);
1761 if (tag
->ti_Data
== GADGETID(data
->wd_DownButton
))
1764 (Object
*) ((struct Gadget
*)data
->
1765 wd_VertProp
)->UserData
;
1768 DoMethod(prop
, MUIM_Prop_Increase
, 1);
1773 if (data
->wd_HorizProp
)
1775 if (tag
->ti_Data
== GADGETID(data
->wd_HorizProp
))
1778 if (tag
->ti_Data
== GADGETID(data
->wd_LeftButton
))
1781 (Object
*) ((struct Gadget
*)data
->
1782 wd_HorizProp
)->UserData
;
1785 DoMethod(prop
, MUIM_Prop_Decrease
, 1);
1788 if (tag
->ti_Data
== GADGETID(data
->wd_RightButton
))
1791 (Object
*) ((struct Gadget
*)data
->
1792 wd_HorizProp
)->UserData
;
1795 DoMethod(prop
, MUIM_Prop_Increase
, 1);
1803 case IDCMP_INTUITICKS
:
1804 if (data
->wd_HelpTicker
)
1806 data
->wd_HelpTicker
--;
1808 if (data
->wd_HelpTicker
== 0)
1811 ObjectUnderPointer(data
, data
->wd_RootObject
,
1812 imsg
->MouseX
, imsg
->MouseY
,
1813 ShortHelpUnderPointerCheck
);
1815 if (underobj
!= data
->wd_HelpObject
)
1817 if (data
->wd_HelpObject
)
1819 DoMethod(data
->wd_HelpObject
, MUIM_DeleteBubble
,
1820 (IPTR
) data
->wd_HelpBubble
);
1822 data
->wd_HelpObject
= NULL
;
1823 data
->wd_HelpBubble
= NULL
;
1828 data
->wd_HelpBubble
=
1829 (APTR
) DoMethod(underobj
, MUIM_CreateBubble
,
1830 imsg
->MouseX
, imsg
->MouseY
, 0, 0);
1831 if (data
->wd_HelpBubble
)
1833 data
->wd_HelpObject
= underobj
;
1834 data
->wd_Flags
|= MUIWF_BUBBLEMODE
;
1839 if (data
->wd_Flags
& MUIWF_BUBBLEMODE
)
1841 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_LATER
;
1845 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_FIRST
;
1850 is_handled
= FALSE
; /* forwardable to area event handlers */
1853 case IDCMP_MOUSEBUTTONS
:
1854 DoMethod(oWin
, MUIM_Window_Snapshot
, 0);
1855 KillHelpBubble(data
, oWin
, TRUE
);
1860 case IDCMP_MOUSEMOVE
:
1861 KillHelpBubble(data
, oWin
, FALSE
);
1870 if (is_handled
&& !replied
)
1871 ReplyMsg((struct Message
*)imsg
);
1876 static ULONG
InvokeEventHandler(struct MUI_EventHandlerNode
*ehn
,
1877 struct IntuiMessage
*event
, ULONG muikey
)
1881 if (!(_flags(ehn
->ehn_Object
) & MADF_CANDRAW
))
1883 if (!(_flags(ehn
->ehn_Object
) & MADF_SHOWME
))
1887 && event
->Class
== IDCMP_MOUSEBUTTONS
1888 && event
->Code
== SELECTDOWN
1889 && (_flags(ehn
->ehn_Object
) & MADF_INVIRTUALGROUP
))
1892 Here we filter out SELECTDOWN messages if objects is in a virtual
1893 group but the click went out of the virtual group
1895 Object
*obj
= ehn
->ehn_Object
;
1896 Object
*parent
= obj
;
1897 Object
*wnd
= _win(obj
);
1899 while (get(parent
, MUIA_Parent
, &parent
))
1905 if (_flags(parent
) & MADF_ISVIRTUALGROUP
)
1907 if (event
->MouseX
< _mleft(parent
)
1908 || event
->MouseX
> _mright(parent
)
1909 || event
->MouseY
< _mtop(parent
)
1910 || event
->MouseY
> _mbottom(parent
))
1919 if (ehn
->ehn_Flags
& MUI_EHF_HANDLEINPUT
)
1921 DoMethod(ehn
->ehn_Object
, MUIM_HandleInput
, (IPTR
) event
, muikey
);
1928 (ehn
->ehn_Class
, ehn
->ehn_Object
, MUIM_HandleEvent
,
1929 (IPTR
) event
, muikey
);
1932 DoMethod(ehn
->ehn_Object
, MUIM_HandleEvent
, (IPTR
) event
,
1939 static void HandleRawkey(Object
*win
, struct MUI_WindowData
*data
,
1940 struct IntuiMessage
*event
)
1943 struct MUI_EventHandlerNode
*ehn
;
1944 struct IntuiMessage imsg_copy
;
1945 struct InputEvent ie
= { 0 };
1947 LONG muikey
= MUIKEY_NONE
;
1948 Object
*active_object
= NULL
;
1953 KillHelpBubble(data
, win
, BUBBLEHELP_TICKER_FIRST
);
1955 ie
.ie_NextEvent
= NULL
;
1956 ie
.ie_Class
= IECLASS_RAWKEY
;
1958 ie
.ie_Code
= event
->Code
;
1959 ie
.ie_Qualifier
= event
->Qualifier
;
1960 ie
.ie_EventAddress
= (APTR
) * (IPTR
*) event
->IAddress
;
1962 ie
.ie_TimeStamp
.Seconds
= event
->Seconds
;
1963 ie
.ie_TimeStamp
.Microseconds
= event
->Micros
;
1965 ie
.ie_TimeStamp
.tv_secs
= event
->Seconds
;
1966 ie
.ie_TimeStamp
.tv_micro
= event
->Micros
;
1969 set(win
, MUIA_Window_InputEvent
, (IPTR
) & ie
);
1971 /* get the vanilla key for control char */
1975 /* Remove the up prefix as convert key does not convert upkey event */
1976 msg_code
= event
->Code
;
1977 event
->Code
&= ~IECODE_UP_PREFIX
;
1978 key
= ConvertKey(event
);
1979 event
->Code
= msg_code
;
1983 deadkey
= *(ULONG
*) event
->IAddress
;
1984 imsg_copy
.IAddress
= &deadkey
;
1985 ReplyMsg((struct Message
*)event
);
1988 //bug("rawkey: code=%lx, qual=%lx\n", event->Code, event->Qualifier);
1990 /* check if imsg translates to predefined keystroke */
1992 struct InputEvent ievent
;
1993 BOOL matched
= FALSE
;
1995 ievent
.ie_NextEvent
= NULL
;
1996 ievent
.ie_Class
= IECLASS_RAWKEY
;
1997 ievent
.ie_SubClass
= 0;
1998 ievent
.ie_Code
= event
->Code
;
1999 ievent
.ie_Qualifier
= event
->Qualifier
;
2000 /* ie_EventAddress is not used by MatchIX. If needed, it should be
2001 * ensured that it is still a valid address because of the shallow
2002 * IntuiMessage copy currently done in _zune_window_message before
2003 * message is replied.
2005 ievent
.ie_EventAddress
= NULL
;
2006 //ievent.ie_EventAddress = (APTR *) *((ULONG *)(event->IAddress));
2008 for (muikey
= MUIKEY_COUNT
- 1; muikey
>= MUIKEY_PRESS
; muikey
--)
2010 if (muiGlobalInfo(win
)->mgi_Prefs
->muikeys
[muikey
].ix_well
!= 0
2012 &muiGlobalInfo(win
)->mgi_Prefs
->muikeys
[muikey
].ix
))
2021 if (muikey
== MUIKEY_PRESS
&& (event
->Code
& IECODE_UP_PREFIX
))
2022 muikey
= MUIKEY_RELEASE
;
2026 muikey
= MUIKEY_NONE
;
2028 } /* check if imsg translate to predefined keystroke */
2030 if ((muikey
!= MUIKEY_NONE
) && !(data
->wd_DisabledKeys
& (1 << muikey
)))
2032 D(bug("HandleRawkey: try MUIKEY %ld on window %0x08lx\n", muikey
,
2046 case MUIKEY_PAGEDOWN
:
2056 case MUIKEY_WORDLEFT
:
2058 case MUIKEY_WORDRIGHT
:
2060 case MUIKEY_LINESTART
:
2062 case MUIKEY_LINEEND
:
2064 case MUIKEY_GADGET_NEXT
:
2065 set(win
, MUIA_Window_ActiveObject
,
2066 MUIV_Window_ActiveObject_Next
);
2068 case MUIKEY_GADGET_PREV
:
2069 set(win
, MUIA_Window_ActiveObject
,
2070 MUIV_Window_ActiveObject_Prev
);
2072 case MUIKEY_GADGET_OFF
:
2073 set(win
, MUIA_Window_ActiveObject
,
2074 MUIV_Window_ActiveObject_None
);
2076 case MUIKEY_WINDOW_CLOSE
:
2077 set(win
, MUIA_Window_CloseRequest
, TRUE
);
2079 case MUIKEY_WINDOW_NEXT
:
2081 case MUIKEY_WINDOW_PREV
:
2092 active_object
= NULL
;
2093 if ((data
->wd_ActiveObject
!= NULL
)
2094 && (DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
2095 (IPTR
) data
->wd_ActiveObject
) != (IPTR
) NULL
))
2097 active_object
= data
->wd_ActiveObject
;
2098 get(active_object
, MUIA_Disabled
, &disabled
);
2101 data
->wd_ActiveObject
= NULL
;
2103 /* try ActiveObject */
2104 if ((active_object
!= NULL
) && !disabled
)
2108 ** Which method should be used for muikeys? MUIM_HandleInput or
2109 ** MUIM_HandleEvent. Also note that there is a flag MUI_EHF_ALWAYSKEYS
2110 ** which probably means that all keys events are requested??
2111 ** For now MUIM_HandleEvent is used as this is currently implemented
2112 ** in Area class ;) although I guess it should be MUIM_HandleInput as
2116 if (muikey
!= MUIKEY_NONE
)
2119 DoMethod(active_object
, MUIM_HandleEvent
, (IPTR
) event
,
2121 if (res
& MUI_EventHandlerRC_Eat
)
2125 D(bug("HandleRawkey: try active object (%08lx) handlers\n",
2128 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2130 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2132 if ((ehn
->ehn_Object
== active_object
)
2133 && ((ehn
->ehn_Events
& IDCMP_RAWKEY
)
2134 || (ehn
->ehn_Flags
& MUI_EHF_ALWAYSKEYS
)))
2136 D(bug("HandleRawkey: (active) invoking on %p (ehn=%p) "
2137 "event=%p muikey=%p\n",
2138 ehn
->ehn_Object
, ehn
, event
, muikey
));
2139 res
= InvokeEventHandler(ehn
, event
, muikey
);
2140 D(bug("HandleRawkey: (active) got res=%d\n", res
));
2141 if (res
& MUI_EventHandlerRC_Eat
)
2144 /* Leave the loop if a different object has been activated */
2145 if (active_object
!= data
->wd_ActiveObject
)
2150 // event not eaten by active object, try its parents
2151 // this is to implement popup key in Popstring
2152 if (active_object
== data
->wd_ActiveObject
)
2154 Object
*current_obj
= active_object
;
2156 D(bug("HandleRawkey: try active object parents handlers\n"));
2157 while (current_obj
!= NULL
)
2159 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
;
2162 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2164 if ((ehn
->ehn_Object
== current_obj
)
2165 && ((ehn
->ehn_Events
& IDCMP_RAWKEY
)
2166 || (ehn
->ehn_Flags
& MUI_EHF_ALWAYSKEYS
)))
2168 //D(bug("HandleRawkey: (active parents) invoking on "
2169 // "%p (ehn=%p) event=%p muikey=%p\n",
2170 // ehn->ehn_Object, ehn, event, muikey));
2171 res
= InvokeEventHandler(ehn
, event
, muikey
);
2172 //D(bug("HandleRawkey: (active parents) got res=%d\n",
2174 if (res
& MUI_EventHandlerRC_Eat
)
2177 /* Leave the loop if a different object has been
2179 if (active_object
!= data
->wd_ActiveObject
)
2183 current_obj
= (Object
*) XGET(current_obj
, MUIA_Parent
);
2188 D(bug("HandleRawkey: try default object handlers\n"));
2190 /* try DefaultObject */
2191 if (data
->wd_DefaultObject
!= NULL
)
2192 get(data
->wd_DefaultObject
, MUIA_Disabled
, &disabled
);
2194 if ((data
->wd_DefaultObject
!= NULL
) && !disabled
2195 && (active_object
!= data
->wd_DefaultObject
))
2197 /* No, we only should do this if the object actually has requested
2198 * this via RequestIDCMP()! */
2199 // if (muikey != MUIKEY_NONE
2200 // && (_flags(data->wd_DefaultObject) & MADF_CANDRAW))
2202 // DoMethod(data->wd_DefaultObject, MUIM_HandleInput, event, muikey);
2206 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2208 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2210 if ((ehn
->ehn_Object
== data
->wd_DefaultObject
)
2211 && ((ehn
->ehn_Events
& IDCMP_RAWKEY
)
2212 || (ehn
->ehn_Flags
& MUI_EHF_ALWAYSKEYS
)))
2214 //D(bug("HandleRawkey: (default) invoking on %p (ehn=%p) "
2215 //"event=%p muikey=%p\n",
2216 //ehn->ehn_Object, ehn, event, muikey));
2217 res
= InvokeEventHandler(ehn
, event
, muikey
);
2218 //D(bug("HandleRawkey: (default) got res=%d\n", res));
2219 if (res
& MUI_EventHandlerRC_Eat
)
2226 D(bug("HandleRawkey: try other handlers\n"));
2228 // try other handlers
2229 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2231 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2233 // skip Active and Default object as they have already been
2235 if (ehn
->ehn_Object
== data
->wd_ActiveObject
2236 || ehn
->ehn_Object
== data
->wd_DefaultObject
)
2239 if (ehn
->ehn_Events
& IDCMP_RAWKEY
)
2241 //D(bug("HandleRawkey: (others) invoking on %p (ehn=%p) "
2242 //"event=%p muikey=%p\n",
2243 //ehn->ehn_Object, ehn, event, muikey));
2244 res
= InvokeEventHandler(ehn
, event
, MUIKEY_NONE
);
2245 //D(bug("HandleRawkey: (others) got res=%d\n", res));
2246 if (res
& MUI_EventHandlerRC_Eat
)
2251 D(bug("HandleRawkey: try control chars handlers\n"));
2253 /* try Control Chars */
2254 //bug("ctrlchar, key='%c' code=0x%08lx\n", key, event->Code);
2257 for (mn
= data
->wd_CCList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2259 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2261 if (ehn
->ehn_Events
== key
)
2264 LONG muikey2
= ehn
->ehn_Flags
;
2266 get(ehn
->ehn_Object
, MUIA_Disabled
, &disabled
);
2270 //bug("control char\n");
2271 if (event
->Code
& IECODE_UP_PREFIX
)
2273 /* simulate a release */
2274 if (muikey2
== MUIKEY_PRESS
)
2275 muikey2
= MUIKEY_RELEASE
;
2280 if ((muikey2
!= MUIKEY_NONE
)
2281 && (_flags(ehn
->ehn_Object
) & MADF_CANDRAW
)
2282 && (_flags(ehn
->ehn_Object
) & MADF_SHOWME
))
2285 (ehn
->ehn_Class
, ehn
->ehn_Object
, MUIM_HandleEvent
,
2286 (IPTR
) NULL
, muikey2
);
2287 if (res
& MUI_EventHandlerRC_Eat
)
2295 /* forward non-keystroke events to event handlers */
2296 static void HandleInputEvent(Object
*win
, struct MUI_WindowData
*data
,
2297 struct IntuiMessage
*event
)
2300 struct MUI_EventHandlerNode
*ehn
;
2301 struct IntuiMessage imsg_copy
;
2303 ULONG mask
= event
->Class
;
2305 if (mask
!= IDCMP_IDCMPUPDATE
)
2308 imsg_copy
.IAddress
= NULL
; /* be sure to trap access to that */
2309 ReplyMsg((struct Message
*)event
);
2313 if (mask
== IDCMP_MOUSEMOVE
)
2315 struct Window
*iWin
;
2316 iWin
= event
->IDCMPWindow
;
2318 if (ContextMenuUnderPointer(data
, data
->wd_RootObject
,
2319 event
->MouseX
, event
->MouseY
))
2321 iWin
->Flags
|= WFLG_RMBTRAP
;
2323 else if (!data
->wd_NoMenus
)
2325 iWin
->Flags
&= ~WFLG_RMBTRAP
;
2329 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2331 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2333 if (ehn
->ehn_Events
& mask
)
2337 get(ehn
->ehn_Object
, MUIA_Disabled
, &disabled
);
2341 res
= InvokeEventHandler(ehn
, event
, MUIKEY_NONE
);
2342 if (res
& MUI_EventHandlerRC_Eat
)
2348 if (mask
== IDCMP_IDCMPUPDATE
)
2349 ReplyMsg((struct Message
*)event
);
2353 /* process window message; this does a ReplyMsg() to the message */
2354 /* Called from application.c */
2355 void _zune_window_message(struct IntuiMessage
*imsg
)
2357 struct Window
*iWin
;
2359 struct MUI_WindowData
*data
;
2362 iWin
= imsg
->IDCMPWindow
;
2363 oWin
= (Object
*) iWin
->UserData
;
2364 data
= muiWindowData(oWin
);
2366 if (data
->wd_DragObject
)
2368 if (!HandleDragging(oWin
, data
, imsg
))
2372 handled
= HandleWindowEvent(oWin
, data
, imsg
);
2375 if (IDCMP_RAWKEY
== imsg
->Class
)
2376 HandleRawkey(oWin
, data
, imsg
);
2377 else if (IDCMP_GADGETUP
== imsg
->Class
)
2380 if (ETI_MUI
== ((struct Gadget
*)imsg
->IAddress
)->GadgetID
)
2382 DoMethod(_app(oWin
), MUIM_Application_OpenConfigWindow
);
2385 if (ETI_Iconify
== ((struct Gadget
*)imsg
->IAddress
)->GadgetID
)
2387 set(_app(oWin
), MUIA_Application_Iconified
, TRUE
);
2392 HandleInputEvent(oWin
, data
, imsg
);
2397 /**************************************************************************/
2398 /**************************************************************************/
2400 /* code for setting MUIA_Window_RootObject */
2401 static void ChangeRootObject(struct MUI_WindowData
*data
, Object
*obj
,
2406 ASSERT_VALID_PTR(data
);
2407 ASSERT_VALID_PTR(obj
);
2409 oldRoot
= data
->wd_RootObject
;
2410 if (!(data
->wd_Flags
& MUIWF_OPENED
))
2414 if (data
->wd_ActiveObject
== oldRoot
)
2415 set(obj
, MUIA_Window_ActiveObject
,
2416 MUIV_Window_ActiveObject_None
);
2417 DoMethod(oldRoot
, MUIM_DisconnectParent
);
2420 data
->wd_RootObject
= newRoot
;
2423 /* if window is in App tree, inform child */
2424 if (muiNotifyData(obj
)->mnd_GlobalInfo
)
2425 DoMethod(newRoot
, MUIM_ConnectParent
, (IPTR
) obj
);
2430 // find the ObjNode containing a pointer to the given object
2431 // currently only used for cycle chain objects
2432 static struct ObjNode
*FindObjNode(struct MinList
*list
, Object
*obj
)
2434 struct ObjNode
*node
;
2436 ASSERT_VALID_PTR(list
);
2441 ASSERT_VALID_PTR(obj
);
2443 for (node
= (struct ObjNode
*)list
->mlh_Head
;
2444 node
->node
.mln_Succ
; node
= (struct ObjNode
*)node
->node
.mln_Succ
)
2446 if (node
->obj
== obj
)
2454 static Object
*GetFirstActiveObject(struct MUI_WindowData
*data
)
2456 ASSERT_VALID_PTR(data
);
2458 if (!IsListEmpty((struct List
*)&data
->wd_CycleChain
))
2459 return ((struct ObjNode
*)data
->wd_CycleChain
.mlh_Head
)->obj
;
2464 static Object
*GetLastActiveObject(struct MUI_WindowData
*data
)
2466 ASSERT_VALID_PTR(data
);
2468 if (!IsListEmpty((struct List
*)&data
->wd_CycleChain
))
2469 return ((struct ObjNode
*)data
->wd_CycleChain
.mlh_TailPred
)->obj
;
2474 typedef struct ObjNode
*objnode_iterator_t(struct ObjNode
*curr_node
);
2476 static objnode_iterator_t NextObjNodeIterator
;
2477 static objnode_iterator_t PrevObjNodeIterator
;
2479 static struct ObjNode
*NextObjNodeIterator(struct ObjNode
*curr_node
)
2481 if (curr_node
->node
.mln_Succ
->mln_Succ
)
2482 return (struct ObjNode
*)curr_node
->node
.mln_Succ
;
2487 static struct ObjNode
*PrevObjNodeIterator(struct ObjNode
*curr_node
)
2489 if (curr_node
->node
.mln_Pred
->mln_Pred
)
2490 return (struct ObjNode
*)curr_node
->node
.mln_Pred
;
2495 static Object
*GetPrevNextActiveObject(struct ObjNode
*old_activenode
,
2496 objnode_iterator_t node_iterator
)
2498 struct ObjNode
*curr_node
;
2499 struct ObjNode
*node
;
2502 ASSERT_VALID_PTR(old_activenode
);
2504 curr_node
= old_activenode
;
2510 node
= node_iterator(curr_node
);
2515 /* let's see if this object meets cycle requirements
2516 * (enabled & visible) */
2519 IPTR is_disabled
= 0;
2521 get(obj
, MUIA_Disabled
, &is_disabled
);
2523 if (!is_disabled
&& (_flags(obj
) & MADF_SHOWME
))
2537 /**************************************************************************
2538 Code for setting MUIA_Window_ActiveObject
2540 - remove focus drawing for current active object
2541 - find (if needed) the new active object
2542 - set data->wd_ActiveObject to the new object
2543 - draw focus around the new active object
2544 **************************************************************************/
2545 static void SetActiveObject(struct MUI_WindowData
*data
, Object
*obj
,
2548 struct ObjNode
*old_activenode
= NULL
;
2550 ASSERT_VALID_PTR(data
);
2551 ASSERT_VALID_PTR(obj
);
2553 D(bug("MUIC_Window:SetActiveObject(data, obj, %08lx) Active=%p\n",
2554 newval
, data
->wd_ActiveObject
));
2556 if ((data
->wd_ActiveObject
!= NULL
)
2557 && (DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
2558 (IPTR
) data
->wd_ActiveObject
) != (IPTR
) NULL
))
2560 if ((IPTR
) data
->wd_ActiveObject
!= newval
)
2563 FindObjNode(&data
->wd_CycleChain
, data
->wd_ActiveObject
);
2564 if ((data
->wd_Flags
& MUIWF_OBJECTGOACTIVESENT
)
2565 && (_flags(data
->wd_ActiveObject
) & MADF_SETUP
))
2567 D(bug("Deactivate=%p\n", data
->wd_ActiveObject
));
2568 DoMethod(data
->wd_ActiveObject
, MUIM_GoInactive
);
2573 data
->wd_ActiveObject
= NULL
;
2574 data
->wd_Flags
&= ~MUIWF_OBJECTGOACTIVESENT
;
2578 case MUIV_Window_ActiveObject_None
:
2581 case MUIV_Window_ActiveObject_Next
:
2582 if (old_activenode
!= NULL
)
2583 data
->wd_ActiveObject
= GetPrevNextActiveObject(old_activenode
,
2584 NextObjNodeIterator
);
2585 if (NULL
== data
->wd_ActiveObject
)
2586 data
->wd_ActiveObject
= GetFirstActiveObject(data
);
2589 case MUIV_Window_ActiveObject_Prev
:
2591 data
->wd_ActiveObject
= GetPrevNextActiveObject(old_activenode
,
2592 PrevObjNodeIterator
);
2593 if (NULL
== data
->wd_ActiveObject
)
2594 data
->wd_ActiveObject
= GetLastActiveObject(data
);
2598 data
->wd_ActiveObject
= (Object
*) newval
;
2603 if (data
->wd_ActiveObject
!= NULL
2604 && DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
2605 (IPTR
) data
->wd_ActiveObject
)
2606 && (_flags(data
->wd_ActiveObject
) & MADF_CANDRAW
))
2608 D(bug("Activate=%p\n", data
->wd_ActiveObject
));
2609 DoMethod(data
->wd_ActiveObject
, MUIM_GoActive
);
2610 data
->wd_Flags
|= MUIWF_OBJECTGOACTIVESENT
;
2615 static BOOL
InBox(struct IBox
*box
, WORD x
, WORD y
)
2617 return x
>= box
->Left
&& x
< box
->Left
+ box
->Width
2618 && y
>= box
->Top
&& y
< box
->Top
+ box
->Height
;
2623 * Pass on an AppMessage to all objects that it landed on.
2625 static void ForwardAppMessage(struct MUI_WindowData
*data
, Object
*child
,
2626 struct AppMessage
*appmsg
)
2628 WORD x
= appmsg
->am_MouseX
, y
= appmsg
->am_MouseY
;
2630 struct List
*children
= NULL
;
2632 ASSERT_VALID_PTR(data
);
2633 ASSERT_VALID_PTR(child
);
2635 set(child
, MUIA_AppMessage
, appmsg
);
2637 children
= (struct List
*)XGET(child
, MUIA_Group_ChildList
);
2639 if (children
!= NULL
)
2641 cstate
= (Object
*) children
->lh_Head
;
2642 while ((child
= NextObject(&cstate
)))
2644 if (InBox(&muiAreaData(child
)->mad_Box
, x
, y
))
2646 ForwardAppMessage(data
, child
, appmsg
);
2654 * calculate real dimensions from programmer requirements.
2655 * may be overridden by user settings if MUIA_Window_ID is set.
2657 /* MUIV_Window_Height_Screen and MUIV_Window_Height_Visible
2658 * are not handled yet, as their Width couterparts.
2660 static void WindowSelectDimensions(struct MUI_WindowData
*data
)
2662 if (!data
->wd_Width
)
2664 if (data
->wd_ReqWidth
> 0)
2665 data
->wd_Width
= data
->wd_ReqWidth
;
2666 else if (data
->wd_ReqWidth
== MUIV_Window_Width_Default
)
2667 data
->wd_Width
= data
->wd_MinMax
.DefWidth
;
2668 else if (_between(MUIV_Window_Width_MinMax(100),
2669 data
->wd_ReqWidth
, MUIV_Window_Width_MinMax(0)))
2671 data
->wd_Width
= data
->wd_MinMax
.MinWidth
2673 * (data
->wd_MinMax
.MaxWidth
- data
->wd_MinMax
.MinWidth
);
2675 else if (_between(MUIV_Window_Width_Screen(100),
2676 data
->wd_ReqWidth
, MUIV_Window_Width_Screen(0)))
2678 data
->wd_Width
= data
->wd_RenderInfo
.mri_ScreenWidth
2679 * (-(data
->wd_ReqWidth
+ 200)) / 100;
2681 else if (_between(MUIV_Window_Width_Visible(100),
2682 data
->wd_ReqWidth
, MUIV_Window_Width_Visible(0)))
2684 data
->wd_Width
= data
->wd_RenderInfo
.mri_ScreenWidth
2685 * (-(data
->wd_ReqWidth
+ 100)) / 100;
2688 if (data
->wd_ReqHeight
> 0)
2689 data
->wd_Height
= data
->wd_ReqHeight
;
2690 else if (data
->wd_ReqHeight
== MUIV_Window_Height_Default
)
2691 data
->wd_Height
= data
->wd_MinMax
.DefHeight
;
2692 else if (_between(MUIV_Window_Height_MinMax(100),
2693 data
->wd_ReqHeight
, MUIV_Window_Height_MinMax(0)))
2695 data
->wd_Height
= data
->wd_MinMax
.MinHeight
2696 - data
->wd_ReqHeight
2697 * (data
->wd_MinMax
.MaxHeight
- data
->wd_MinMax
.MinHeight
);
2699 else if (_between(MUIV_Window_Height_Screen(100),
2700 data
->wd_ReqHeight
, MUIV_Window_Height_Screen(0)))
2705 scr
= data
->wd_RenderInfo
.mri_Screen
;
2708 scr
->Height
- data
->wd_RenderInfo
.mri_BorderTop
-
2709 data
->wd_RenderInfo
.mri_BorderBottom
;
2711 /* This is new to Zune: If TopEdge Delta is requested
2712 * the screenheight doesn't cover the barlayer */
2713 if (data
->wd_Y
<= MUIV_Window_TopEdge_Delta(0))
2714 height
-= scr
->BarHeight
+ 1;
2716 data
->wd_Height
= height
* (-(data
->wd_ReqHeight
+ 200)) / 100;
2718 else if (_between(MUIV_Window_Height_Visible(100),
2719 data
->wd_ReqHeight
, MUIV_Window_Height_Visible(0)))
2721 data
->wd_Height
= data
->wd_RenderInfo
.mri_ScreenHeight
2722 * (-(data
->wd_ReqHeight
+ 100)) / 100;
2726 if (data
->wd_ReqWidth
== MUIV_Window_Width_Scaled
)
2727 data
->wd_Width
= data
->wd_Height
* data
->wd_MinMax
.MinWidth
2728 / data
->wd_MinMax
.MinHeight
;
2729 else if (data
->wd_ReqHeight
== MUIV_Window_Width_Scaled
)
2730 data
->wd_Height
= data
->wd_Width
* data
->wd_MinMax
.MinHeight
2731 / data
->wd_MinMax
.MinWidth
;
2733 data
->wd_Width
= CLAMP(data
->wd_Width
, data
->wd_MinMax
.MinWidth
,
2734 data
->wd_MinMax
.MaxWidth
);
2735 data
->wd_Height
= CLAMP(data
->wd_Height
, data
->wd_MinMax
.MinHeight
,
2736 data
->wd_MinMax
.MaxHeight
);
2740 /**************************************************************************
2742 **************************************************************************/
2743 IPTR
Window__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
2745 struct MUI_WindowData
*data
;
2746 struct TagItem
*tags
;
2747 struct TagItem
*tag
;
2749 obj
= (Object
*) DoSuperMethodA(cl
, obj
, (Msg
) msg
);
2753 /* Initial local instance data */
2754 data
= INST_DATA(cl
, obj
);
2756 data
->wd_MemoryPool
= CreatePool(0, 4096, 2048);
2757 if (NULL
== data
->wd_MemoryPool
)
2759 CoerceMethod(cl
, obj
, OM_DISPOSE
);
2763 data
->wd_RenderInfo
.mri_WindowObject
= obj
;
2765 NewList((struct List
*)&(data
->wd_EHList
));
2766 NewList((struct List
*)&(data
->wd_CCList
));
2767 NewList((struct List
*)&(data
->wd_CycleChain
));
2768 NewList((struct List
*)&(data
->wd_IDList
));
2770 data
->wd_CrtFlags
= WFLG_SIZEGADGET
| WFLG_DRAGBAR
| WFLG_DEPTHGADGET
2771 | WFLG_CLOSEGADGET
| WFLG_SIMPLE_REFRESH
2772 | WFLG_REPORTMOUSE
| WFLG_NEWLOOKMENUS
;
2773 data
->wd_ZoomGadget
= TRUE
;
2774 data
->wd_Events
= GetDefaultEvents();
2775 data
->wd_ActiveObject
= NULL
;
2777 data
->wd_ReqHeight
= MUIV_Window_Height_Default
;
2778 data
->wd_ReqWidth
= MUIV_Window_Width_Default
;
2779 data
->wd_RootObject
= NULL
;
2780 data
->wd_DefaultObject
= NULL
;
2782 /* alternate dimensions */
2783 /* no change in coordinates */
2784 data
->wd_AltDim
.Top
= MUIV_Window_AltTopEdge_NoChange
;
2785 data
->wd_AltDim
.Left
= MUIV_Window_AltLeftEdge_NoChange
;
2786 /* default to min size */
2787 data
->wd_AltDim
.Width
= MUIV_Window_AltWidth_MinMax(0);
2788 data
->wd_AltDim
.Height
= MUIV_Window_AltHeight_MinMax(0);
2789 data
->wd_X
= MUIV_Window_LeftEdge_Centered
;
2790 data
->wd_Y
= MUIV_Window_TopEdge_Centered
;
2791 data
->wd_DisabledKeys
= 0L;
2792 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_FIRST
;
2794 /* parse initial taglist */
2796 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
));)
2798 switch (tag
->ti_Tag
)
2800 case MUIA_Window_EraseArea
:
2801 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_ERASEAREA
);
2804 case MUIA_Window_ToolBox
:
2805 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_TOOLBOX
);
2808 case MUIA_Window_CloseGadget
:
2809 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
,
2813 case MUIA_Window_SizeGadget
:
2814 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
,
2818 case MUIA_Window_ZoomGadget
:
2819 data
->wd_ZoomGadget
= tag
->ti_Data
;
2822 case MUIA_Window_Backdrop
:
2823 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
,
2827 case MUIA_Window_Borderless
:
2828 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
,
2832 case MUIA_Window_DepthGadget
:
2833 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
,
2837 case MUIA_Window_DragBar
:
2838 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_DRAGBAR
);
2841 case MUIA_Window_SizeRight
:
2842 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
,
2846 case MUIA_Window_Height
:
2847 data
->wd_ReqHeight
= (LONG
) tag
->ti_Data
;
2850 case MUIA_Window_Width
:
2851 data
->wd_ReqWidth
= (LONG
) tag
->ti_Data
;
2854 case MUIA_Window_ID
:
2855 set(obj
, MUIA_Window_ID
, tag
->ti_Data
);
2858 case MUIA_Window_IsSubWindow
:
2859 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
2863 case MUIA_Window_Title
:
2864 set(obj
, MUIA_Window_Title
, tag
->ti_Data
);
2867 case MUIA_Window_ScreenTitle
:
2868 set(obj
, MUIA_Window_ScreenTitle
, tag
->ti_Data
);
2871 case MUIA_Window_Activate
:
2872 _handle_bool_tag(data
->wd_Flags
, !tag
->ti_Data
,
2873 MUIWF_DONTACTIVATE
);
2876 case MUIA_Window_DefaultObject
:
2877 set(obj
, MUIA_Window_DefaultObject
, tag
->ti_Data
);
2880 case MUIA_Window_Menustrip
:
2881 data
->wd_ChildMenustrip
= (Object
*) tag
->ti_Data
;
2884 case MUIA_Window_NoMenus
:
2885 data
->wd_NoMenus
= (BOOL
) tag
->ti_Data
;
2888 case MUIA_Window_RootObject
:
2891 CoerceMethod(cl
, obj
, OM_DISPOSE
);
2894 set(obj
, MUIA_Window_RootObject
, tag
->ti_Data
);
2897 case MUIA_Window_AltHeight
:
2898 data
->wd_AltDim
.Height
= (WORD
) tag
->ti_Data
;
2901 case MUIA_Window_AltWidth
:
2902 data
->wd_AltDim
.Width
= (WORD
) tag
->ti_Data
;
2905 case MUIA_Window_AltLeftEdge
:
2906 data
->wd_AltDim
.Left
= (WORD
) tag
->ti_Data
;
2909 case MUIA_Window_AltTopEdge
:
2910 data
->wd_AltDim
.Top
= (WORD
) tag
->ti_Data
;
2913 case MUIA_Window_AppWindow
:
2914 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
2918 case MUIA_Window_LeftEdge
:
2919 data
->wd_X
= tag
->ti_Data
;
2922 case MUIA_Window_TopEdge
:
2923 data
->wd_Y
= tag
->ti_Data
;
2926 case MUIA_Window_UseBottomBorderScroller
:
2927 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
2928 MUIWF_USEBOTTOMSCROLLER
);
2931 case MUIA_Window_UseRightBorderScroller
:
2932 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
2933 MUIWF_USERIGHTSCROLLER
);
2936 case MUIA_Window_DisableKeys
:
2937 data
->wd_DisabledKeys
= tag
->ti_Data
;
2940 case MUIA_Window_RefWindow
:
2941 data
->wd_RefWindow
= (Object
*) tag
->ti_Data
;
2944 case MUIA_Window_Screen
:
2945 data
->wd_UserScreen
= (struct Screen
*)tag
->ti_Data
;
2948 case MUIA_Window_PublicScreen
:
2949 data
->wd_UserPublicScreen
= (STRPTR
) tag
->ti_Data
;
2954 /* D(bug("muimaster.library/window.c: Window Object created at " */
2955 /* "0x%lx back=%lx\n", */
2956 /* obj,data->wd_Background)); */
2961 /**************************************************************************
2963 **************************************************************************/
2964 IPTR
Window__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
2966 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
2968 /* D(bug("Window_Dispose(%p)\n", obj)); */
2971 /* We no longer clear muiGlobalInfo() during disconnections, so
2972 this can cause problems (remove object which is already removed).
2973 Furthermore AFAIK it is not legal to dispose a window object
2974 which is still ocnnected to the application object, anyway. */
2976 if (muiGlobalInfo(obj
) && _app(obj
))
2978 /* D(bug(" Window_Dispose(%p) : calling app->OM_REMMEMBER\n", obj)); */
2979 DoMethod(_app(obj
), OM_REMMEMBER
, (IPTR
) obj
);
2983 if (data
->wd_RootObject
)
2984 MUI_DisposeObject(data
->wd_RootObject
);
2986 if (data
->wd_ChildMenustrip
)
2987 MUI_DisposeObject(data
->wd_ChildMenustrip
);
2990 FreeVec(data
->wd_Title
);
2992 if (data
->wd_ScreenTitle
)
2993 FreeVec(data
->wd_ScreenTitle
);
2995 DeletePool(data
->wd_MemoryPool
);
2997 /* D(bug(" Window_Dispose(%p) : calling supermethod\n", obj)); */
2998 return DoSuperMethodA(cl
, obj
, msg
);
3001 static ULONG
WindowOpen(struct IClass
*cl
, Object
*obj
);
3002 static ULONG
WindowClose(struct IClass
*cl
, Object
*obj
);
3004 /**************************************************************************
3006 **************************************************************************/
3007 IPTR
Window__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
3009 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3010 struct TagItem
*tags
= msg
->ops_AttrList
;
3011 struct TagItem
*tag
;
3013 while ((tag
= NextTagItem(&tags
)) != NULL
)
3015 switch (tag
->ti_Tag
)
3017 case MUIA_AppMessage
:
3018 ForwardAppMessage(data
, data
->wd_RootObject
,
3019 (struct AppMessage
*)tag
->ti_Data
);
3022 case MUIA_Window_Activate
:
3023 if (data
->wd_RenderInfo
.mri_Window
)
3025 if (tag
->ti_Data
&& !(data
->wd_Flags
& MUIWF_ACTIVE
))
3027 ActivateWindow(data
->wd_RenderInfo
.mri_Window
);
3028 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
3033 _handle_bool_tag(data
->wd_Flags
, !tag
->ti_Data
,
3034 MUIWF_DONTACTIVATE
);
3037 case MUIA_Window_ActiveObject
:
3038 /* D(bug("MUIA_Window_ActiveObject %ld (%p)\n", */
3039 /* tag->ti_Data, tag->ti_Data)); */
3040 SetActiveObject(data
, obj
, tag
->ti_Data
);
3043 case MUIA_Window_DefaultObject
:
3044 data
->wd_DefaultObject
= (APTR
) tag
->ti_Data
;
3047 case MUIA_Window_ID
:
3048 data
->wd_ID
= tag
->ti_Data
;
3051 case MUIA_Window_IsSubWindow
:
3052 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
3056 case MUIA_Window_Open
:
3059 if (data
->wd_Flags
& MUIWF_HIDDEN
)
3060 data
->wd_Flags
|= MUIWF_OPENONUNHIDE
;
3061 else if (!(data
->wd_Flags
& MUIWF_OPENED
))
3062 WindowOpen(cl
, obj
);
3065 DoMethod(obj
, MUIM_Window_ToFront
);
3066 set(obj
, MUIA_Window_Activate
, TRUE
);
3069 else if (data
->wd_Flags
& MUIWF_HIDDEN
)
3070 data
->wd_Flags
&= ~MUIWF_OPENONUNHIDE
;
3071 else if (data
->wd_Flags
& MUIWF_OPENED
)
3072 WindowClose(cl
, obj
);
3075 case MUIA_ShowMe
: /* PRIVATE *abuse* of the Area's ShowMe attr */
3080 if (data
->wd_Flags
& MUIWF_HIDDEN
)
3082 data
->wd_Flags
&= ~MUIWF_HIDDEN
;
3084 if (data
->wd_Flags
& MUIWF_OPENONUNHIDE
)
3086 data
->wd_Flags
&= ~MUIWF_OPENONUNHIDE
;
3087 set(obj
, MUIA_Window_Open
, TRUE
);
3095 if (data
->wd_Flags
& MUIWF_OPENED
)
3097 data
->wd_Flags
|= MUIWF_OPENONUNHIDE
;
3099 set(obj
, MUIA_Window_Open
, FALSE
);
3102 data
->wd_Flags
|= MUIWF_HIDDEN
;
3106 case MUIA_Window_RootObject
:
3107 ChangeRootObject(data
, obj
, (Object
*) tag
->ti_Data
);
3110 case MUIA_Window_Title
:
3112 FreeVec(data
->wd_Title
);
3113 data
->wd_Title
= StrDup((STRPTR
) tag
->ti_Data
);
3114 if (data
->wd_RenderInfo
.mri_Window
)
3115 SetWindowTitles(data
->wd_RenderInfo
.mri_Window
,
3116 data
->wd_Title
, (CONST_STRPTR
) ~ 0);
3119 case MUIA_Window_ScreenTitle
:
3120 if (data
->wd_ScreenTitle
)
3121 FreeVec(data
->wd_ScreenTitle
);
3122 data
->wd_ScreenTitle
= StrDup((STRPTR
) tag
->ti_Data
);
3123 if (data
->wd_RenderInfo
.mri_Window
)
3124 SetWindowTitles(data
->wd_RenderInfo
.mri_Window
,
3125 (CONST_STRPTR
) ~ 0, data
->wd_ScreenTitle
);
3128 case MUIA_Window_NoMenus
:
3129 data
->wd_NoMenus
= (BOOL
) tag
->ti_Data
;
3130 if (data
->wd_RenderInfo
.mri_Window
)
3132 if (data
->wd_NoMenus
)
3133 data
->wd_RenderInfo
.mri_Window
->Flags
|= WFLG_RMBTRAP
;
3135 data
->wd_RenderInfo
.mri_Window
->Flags
&= ~WFLG_RMBTRAP
;
3139 case MUIA_Window_UseBottomBorderScroller
:
3140 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
3141 MUIWF_USEBOTTOMSCROLLER
);
3144 case MUIA_Window_UseRightBorderScroller
:
3145 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
3146 MUIWF_USERIGHTSCROLLER
);
3149 case MUIA_Window_DisableKeys
:
3150 data
->wd_DisabledKeys
= tag
->ti_Data
;
3153 case MUIA_Window_RefWindow
:
3154 data
->wd_RefWindow
= (Object
*) tag
->ti_Data
;
3157 case MUIA_Window_LeftEdge
:
3158 data
->wd_X
= tag
->ti_Data
;
3161 case MUIA_Window_TopEdge
:
3162 data
->wd_Y
= tag
->ti_Data
;
3165 case MUIA_Window_Width
:
3166 data
->wd_ReqWidth
= (LONG
) tag
->ti_Data
;
3167 data
->wd_Width
= 0; /* otherwise windowselectdimensions()
3168 * ignores ReqWidth */
3171 case MUIA_Window_Height
:
3172 data
->wd_ReqHeight
= (LONG
) tag
->ti_Data
;
3173 data
->wd_Height
= 0;
3176 case MUIA_Window_Screen
:
3177 data
->wd_UserScreen
= (struct Screen
*)tag
->ti_Data
;
3180 case MUIA_Window_PublicScreen
:
3181 data
->wd_UserPublicScreen
= (STRPTR
) tag
->ti_Data
;
3184 case MUIA_Window_Sleep
:
3187 data
->wd_SleepCount
++;
3188 if (data
->wd_RenderInfo
.mri_Window
3189 && (data
->wd_SleepCount
== 1))
3192 (data
->wd_RenderInfo
.mri_Window
,
3193 WA_BusyPointer
, TRUE
,
3194 WA_PointerDelay
, TRUE
, TAG_DONE
);
3195 // FIXME: how to disable event handling?
3200 data
->wd_SleepCount
--;
3201 if (data
->wd_RenderInfo
.mri_Window
3202 && (data
->wd_SleepCount
== 0))
3204 SetWindowPointerA(data
->wd_RenderInfo
.mri_Window
, NULL
);
3212 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
3215 /**************************************************************************
3217 **************************************************************************/
3218 IPTR
Window__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
3220 #define STORE *(msg->opg_Storage)
3222 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3226 switch (msg
->opg_AttrID
)
3228 case MUIA_Window_Activate
:
3230 (data
->wd_Flags
& (MUIWF_ACTIVE
| MUIWF_OPENED
)) ==
3231 (MUIWF_ACTIVE
| MUIWF_OPENED
);
3234 case MUIA_Window_Window
:
3235 STORE
= (IPTR
) data
->wd_RenderInfo
.mri_Window
;
3238 case MUIA_Window_Screen
:
3239 STORE
= (IPTR
) data
->wd_RenderInfo
.mri_Screen
;
3242 case MUIA_Window_PublicScreen
:
3243 STORE
= (IPTR
) data
->wd_UserPublicScreen
;
3246 case MUIA_Window_ActiveObject
:
3247 if ((data
->wd_ActiveObject
!= NULL
)
3248 && (DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
3249 (IPTR
) data
->wd_ActiveObject
) != (IPTR
) NULL
))
3250 STORE
= (IPTR
) data
->wd_ActiveObject
;
3252 STORE
= (IPTR
) NULL
;
3255 case MUIA_Window_CloseRequest
:
3259 case MUIA_Window_DefaultObject
:
3260 STORE
= (IPTR
) data
->wd_DefaultObject
;
3263 case MUIA_Window_DisableKeys
:
3264 STORE
= data
->wd_DisabledKeys
;
3267 case MUIA_Window_Height
:
3268 STORE
= (IPTR
) data
->wd_Height
;
3271 case MUIA_Window_ID
:
3272 STORE
= data
->wd_ID
;
3275 case MUIA_Window_IsSubWindow
:
3276 STORE
= (data
->wd_Flags
& MUIWF_ISSUBWINDOW
) == MUIWF_ISSUBWINDOW
;
3279 case MUIA_Window_LeftEdge
:
3280 if (data
->wd_RenderInfo
.mri_Window
)
3281 STORE
= (IPTR
) data
->wd_RenderInfo
.mri_Window
->LeftEdge
;
3286 case MUIA_Window_Open
:
3287 STORE
= (data
->wd_Flags
& MUIWF_OPENED
) == MUIWF_OPENED
;
3290 case MUIA_Window_RootObject
:
3291 STORE
= (IPTR
) data
->wd_RootObject
;
3294 case MUIA_Window_ScreenTitle
:
3295 STORE
= (IPTR
) data
->wd_ScreenTitle
;
3298 case MUIA_Window_Title
:
3299 STORE
= (IPTR
) data
->wd_Title
;
3302 case MUIA_Window_TopEdge
:
3303 if (data
->wd_RenderInfo
.mri_Window
)
3304 STORE
= (IPTR
) data
->wd_RenderInfo
.mri_Window
->TopEdge
;
3309 case MUIA_Window_Width
:
3310 STORE
= (IPTR
) data
->wd_Width
;
3313 case MUIA_Window_Menustrip
:
3314 STORE
= (IPTR
) data
->wd_ChildMenustrip
;
3317 case MUIA_Window_Sleep
:
3318 STORE
= data
->wd_SleepCount
? TRUE
: FALSE
;
3330 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
3335 * MUIM_FindUData : tests if the MUIA_UserData of the object
3336 * contains the given <udata> and returns the object pointer in this case.
3338 IPTR
Window__MUIM_FindUData(struct IClass
*cl
, Object
*obj
,
3339 struct MUIP_FindUData
*msg
)
3341 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3343 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3346 if (data
->wd_RootObject
)
3347 return DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
3354 * MUIM_GetUData : This method tests if the MUIA_UserData of the object
3355 * contains the given <udata> and gets <attr> to <storage> for itself
3358 IPTR
Window__MUIM_GetUData(struct IClass
*cl
, Object
*obj
,
3359 struct MUIP_GetUData
*msg
)
3361 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3363 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3365 get(obj
, msg
->attr
, msg
->storage
);
3369 if (data
->wd_RootObject
)
3370 return DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
3377 * MUIM_SetUData : This method tests if the MUIA_UserData of the object
3378 * contains the given <udata> and sets <attr> to <val> for itself in this case.
3380 IPTR
Window__MUIM_SetUData(struct IClass
*cl
, Object
*obj
,
3381 struct MUIP_SetUData
*msg
)
3383 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3385 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3386 set(obj
, msg
->attr
, msg
->val
);
3388 if (data
->wd_RootObject
)
3389 DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
3396 * MUIM_SetUDataOnce : This method tests if the MUIA_UserData of the object
3397 * contains the given <udata> and sets <attr> to <val> for itself in this case.
3399 IPTR
Window__MUIM_SetUDataOnce(struct IClass
*cl
, Object
*obj
,
3400 struct MUIP_SetUDataOnce
*msg
)
3402 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3404 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3406 set(obj
, msg
->attr
, msg
->val
);
3410 if (data
->wd_RootObject
)
3411 return DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
3416 /**************************************************************************
3417 Called by Application (parent) object whenever this object is added.
3419 **************************************************************************/
3420 IPTR
Window__MUIM_ConnectParent(struct IClass
*cl
, Object
*obj
,
3421 struct MUIP_ConnectParent
*msg
)
3423 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3425 if (!DoSuperMethodA(cl
, obj
, (Msg
) msg
))
3428 if (data
->wd_RootObject
)
3429 DoMethod(data
->wd_RootObject
, MUIM_ConnectParent
, (IPTR
) obj
);
3431 if (data
->wd_ChildMenustrip
)
3432 DoMethod(data
->wd_ChildMenustrip
, MUIM_ConnectParent
, (IPTR
) obj
);
3438 /**************************************************************************
3439 called by parent object
3440 **************************************************************************/
3441 IPTR
Window__MUIM_DisconnectParent(struct IClass
*cl
, Object
*obj
,
3442 struct MUIP_DisconnectParent
*msg
)
3444 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3446 /* D(bug("Window_DisconnectParent(%p) : muiGlobalInfo=%p\n", */
3447 /* muiGlobalInfo(obj))); */
3448 if (muiGlobalInfo(obj
))
3450 /* Close the window before disconnecting all the childs */
3451 if ((data
->wd_Flags
& MUIWF_OPENED
))
3453 /* D(bug(" Window_DisconnectParent(%p) : closing window\n", */
3454 /* muiGlobalInfo(obj))); */
3455 set(obj
, MUIA_Window_Open
, FALSE
);
3457 if (data
->wd_ChildMenustrip
)
3458 DoMethod(data
->wd_ChildMenustrip
, MUIM_DisconnectParent
,
3461 if (data
->wd_RootObject
)
3462 DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
3464 /* D(bug(" Window_DisconnectParent(%p) : calling supermethod\n", */
3465 /* muiGlobalInfo(obj))); */
3466 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
3474 static void SetRootObjInnerSpacing(Object
*obj
,
3475 struct MUI_WindowData
*data
)
3477 UWORD wd_innerLeft
, wd_innerRight
, wd_innerTop
, wd_innerBottom
;
3479 if (data
->wd_CrtFlags
& WFLG_BORDERLESS
)
3488 wd_innerLeft
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_left
;
3489 wd_innerRight
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_right
;
3490 wd_innerTop
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_top
;
3491 wd_innerBottom
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_bottom
;
3494 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERLEFT
))
3496 muiAreaData(data
->wd_RootObject
)->mad_InnerLeft
= wd_innerLeft
;
3499 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERTOP
))
3501 muiAreaData(data
->wd_RootObject
)->mad_InnerTop
= wd_innerTop
;
3504 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERRIGHT
))
3506 muiAreaData(data
->wd_RootObject
)->mad_InnerRight
= wd_innerRight
;
3509 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERBOTTOM
))
3511 muiAreaData(data
->wd_RootObject
)->mad_InnerBottom
= wd_innerBottom
;
3516 * Called before window is opened or resized. It determines its bounds,
3517 * so you can call WindowSelectDimensions() to find the final dims.
3519 static void WindowMinMax(Object
*obj
, struct MUI_WindowData
*data
)
3521 SetRootObjInnerSpacing(obj
, data
);
3522 /* inquire about sizes */
3523 DoMethod(data
->wd_RootObject
, MUIM_AskMinMax
, (IPTR
) & data
->wd_MinMax
);
3524 /* D(bug("*** root minmax = %ld,%ld => %ld,%ld\n", */
3525 /* data->wd_MinMax.MinWidth, */
3526 /* data->wd_MinMax.MinHeight, */
3527 /* data->wd_MinMax.MaxWidth, data->wd_MinMax.MaxHeight)); */
3528 __area_finish_minmax(data
->wd_RootObject
, &data
->wd_MinMax
);
3529 /* D(bug("*** root minmax2 = %ld,%ld => %ld,%ld\n", */
3530 /* data->wd_MinMax.MinWidth, */
3531 /* data->wd_MinMax.MinHeight, */
3532 /* data->wd_MinMax.MaxWidth, data->wd_MinMax.MaxHeight)); */
3536 static void InstallBackbuffer(struct IClass
*cl
, Object
*obj
)
3538 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3540 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
3542 data
->wd_RenderInfo
.mri_BufferBM
=
3543 AllocBitMap(win
->Width
, win
->Height
, win
->RPort
->BitMap
->Depth
,
3544 0, win
->RPort
->BitMap
);
3546 if (data
->wd_RenderInfo
.mri_BufferBM
)
3548 /* D(bug("install_backbuffer : allocated bitmap %dx%dx%d " */
3549 /* "with friend %p\n", */
3550 /* win->Width, win->Height, win->RPort->BitMap->Depth, */
3551 /* win->RPort->BitMap)); */
3552 InitRastPort(&data
->wd_RenderInfo
.mri_BufferRP
);
3553 data
->wd_RenderInfo
.mri_BufferRP
.BitMap
=
3554 data
->wd_RenderInfo
.mri_BufferBM
;
3558 static void DeinstallBackbuffer(struct IClass
*cl
, Object
*obj
)
3560 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3562 if (data
->wd_RenderInfo
.mri_BufferBM
)
3564 DeinitRastPort(&data
->wd_RenderInfo
.mri_BufferRP
);
3565 FreeBitMap(data
->wd_RenderInfo
.mri_BufferBM
);
3566 data
->wd_RenderInfo
.mri_BufferBM
= NULL
;
3571 * Called after window is opened or resized.
3572 * An expose event is already queued, it will trigger
3573 * MUIM_Draw for us when going back to main loop.
3575 static void WindowShow(struct IClass
*cl
, Object
*obj
)
3577 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3578 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
3579 /* D(bug("WindowShow %s %d\n", __FILE__, __LINE__)); */
3581 _left(data
->wd_RootObject
) = win
->BorderLeft
;
3582 _top(data
->wd_RootObject
) = win
->BorderTop
;
3583 _width(data
->wd_RootObject
) = data
->wd_Width
;
3584 _height(data
->wd_RootObject
) = data
->wd_Height
;
3586 DoMethod(data
->wd_RootObject
, MUIM_Layout
);
3588 ShowRenderInfo(&data
->wd_RenderInfo
);
3589 /* D(bug("zune_imspec_show %s %d\n", __FILE__, __LINE__)); */
3590 zune_imspec_show(data
->wd_Background
, obj
);
3591 DoShowMethod(data
->wd_RootObject
);
3594 static ULONG
WindowOpen(struct IClass
*cl
, Object
*obj
)
3596 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3598 if (!data
->wd_RootObject
)
3601 if (!DoMethod(obj
, MUIM_Window_Setup
))
3604 /* I got display info, so calculate your display dependant data */
3605 if (!DoSetupMethod(data
->wd_RootObject
, &data
->wd_RenderInfo
))
3607 DoMethod(obj
, MUIM_Window_Cleanup
);
3611 /* inquire about sizes */
3612 WindowMinMax(obj
, data
);
3613 WindowSelectDimensions(data
);
3615 /* Decide which menustrip should be used */
3616 if (!data
->wd_ChildMenustrip
)
3617 get(_app(obj
), MUIA_Application_Menustrip
, &data
->wd_Menustrip
);
3619 data
->wd_Menustrip
= data
->wd_ChildMenustrip
;
3621 /* open window here ... */
3622 if (!DisplayWindow(obj
, data
))
3624 /* free display dependant data */
3625 data
->wd_Menustrip
= NULL
;
3626 DoMethod(data
->wd_RootObject
, MUIM_Cleanup
);
3627 DoMethod(obj
, MUIM_Window_Cleanup
);
3631 InstallBackbuffer(cl
, obj
);
3633 data
->wd_Flags
|= MUIWF_OPENED
;
3635 WindowShow(cl
, obj
);
3638 LONG left
, top
, width
, height
;
3640 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
3641 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
,
3642 width
= data
->wd_RenderInfo
.mri_Window
->Width
3643 - data
->wd_RenderInfo
.mri_Window
->BorderRight
- left
;
3644 height
= data
->wd_RenderInfo
.mri_Window
->Height
3645 - data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
3647 /* D(bug("zune_imspec_draw %s %d\n", __FILE__, __LINE__)); */
3648 // D(bug("%d:zune_imspec_draw(%p) l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
3649 // __LINE__, data->wd_Background, left, top, width,
3650 // height, left, top));
3652 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
3653 left
, top
, width
, height
, left
, top
, 0);
3656 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWOBJECT
);
3658 D(bug("MUIC_Window:windowOpen() ActiveObject=%p\n",
3659 data
->wd_ActiveObject
));
3660 if (data
->wd_OldActive
!= NULL
)
3662 set(obj
, MUIA_Window_ActiveObject
, data
->wd_OldActive
);
3668 /**************************************************************************/
3669 /**************************************************************************/
3671 static ULONG
WindowClose(struct IClass
*cl
, Object
*obj
)
3673 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3675 if (data
->wd_ActiveObject
!= NULL
)
3677 data
->wd_OldActive
= data
->wd_ActiveObject
;
3678 set(obj
, MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_None
);
3681 KillHelpBubble(data
, obj
, BUBBLEHELP_TICKER_FIRST
);
3683 /* remove from window */
3684 DoHideMethod(data
->wd_RootObject
);
3685 zune_imspec_hide(data
->wd_Background
);
3687 DeinstallBackbuffer(cl
, obj
);
3689 HideRenderInfo(&data
->wd_RenderInfo
);
3691 /* close here ... */
3692 UndisplayWindow(obj
, data
);
3694 data
->wd_Flags
&= ~MUIWF_OPENED
;
3695 data
->wd_Menustrip
= NULL
;
3697 /* free display dependant data */
3698 DoMethod(data
->wd_RootObject
, MUIM_Cleanup
);
3699 DoMethod(obj
, MUIM_Window_Cleanup
);
3703 /* calculate a new layout
3705 * see Group_ExitChange
3709 IPTR
Window__MUIM_RecalcDisplay(struct IClass
*cl
, Object
*obj
,
3710 struct MUIP_Window_RecalcDisplay
*msg
)
3712 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3713 LONG left
, top
, width
, height
;
3714 BOOL resized
, reshow
= FALSE
;
3715 Object
*current_obj
;
3717 if (!(data
->wd_Flags
& MUIWF_OPENED
))
3720 current_obj
= msg
->originator
;
3722 // typically originator is a group which has been added/removed a child
3723 // calculate minmax of current obj
3724 // if new minmax can accomodate current obj size, stop
3725 // else try with its parent
3726 // the resulting object will get a new layout
3727 // it currently produces some redundant AskMinMax but allows
3728 // to not always relayout the whole window
3730 D(bug("RecalcDisplay on %p\n", current_obj
));
3731 while (current_obj
!= NULL
)
3733 DoMethod(current_obj
, MUIM_AskMinMax
,
3734 (IPTR
) & muiAreaData(current_obj
)->mad_MinMax
);
3735 __area_finish_minmax(current_obj
,
3736 &muiAreaData(current_obj
)->mad_MinMax
);
3738 D(bug("size w = %d, h = %d\n", _width(current_obj
),
3739 _height(current_obj
)));
3740 D(bug("new w = %d-%d, h = %d-%d\n", _minwidth(current_obj
),
3741 _maxwidth(current_obj
), _minheight(current_obj
),
3742 _maxheight(current_obj
)));
3744 if (!_between(_minwidth(current_obj
), _width(current_obj
),
3745 _maxwidth(current_obj
))
3746 || !_between(_minheight(current_obj
), _height(current_obj
),
3747 _maxheight(current_obj
)))
3749 current_obj
= _parent(current_obj
);
3750 D(bug("RecalcDisplay, try parent %p\n", current_obj
));
3754 D(bug("found it\n"));
3760 current_obj
= data
->wd_RootObject
;
3762 WindowMinMax(obj
, data
);
3764 /* Important: current_obj could be hidden, like in an inactive page! */
3765 if (_flags(current_obj
) & MADF_CANDRAW
)
3771 DoHideMethod(current_obj
);
3773 /* resize window ? */
3774 WindowSelectDimensions(data
);
3775 resized
= WindowResize(data
);
3779 /* FIXME: Should we short circuit the following
3780 * if the window size didn't change?
3785 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
3786 _left(data
->wd_RootObject
) = win
->BorderLeft
;
3787 _top(data
->wd_RootObject
) = win
->BorderTop
;
3788 _width(data
->wd_RootObject
) = data
->wd_Width
;
3789 _height(data
->wd_RootObject
) = data
->wd_Height
;
3791 DoMethod(current_obj
, MUIM_Layout
);
3794 DoShowMethod(current_obj
);
3796 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_redraw
==
3797 WINDOW_REDRAW_WITHOUT_CLEAR
)
3800 MUI_Redraw(current_obj
, MADF_DRAWOBJECT
);
3804 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
3805 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
;
3806 width
= data
->wd_RenderInfo
.mri_Window
->Width
3807 - data
->wd_RenderInfo
.mri_Window
->BorderRight
- left
;
3808 height
= data
->wd_RenderInfo
.mri_Window
->Height
3809 - data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
3811 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
3812 left
, top
, width
, height
, left
, top
, 0);
3813 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWALL
);
3816 ActivateObject(data
);
3822 /**************************************************************************
3823 MUIM_AddEventHandler
3824 **************************************************************************/
3825 IPTR
Window__MUIM_AddEventHandler(struct IClass
*cl
, Object
*obj
,
3826 struct MUIP_Window_AddEventHandler
*msg
)
3828 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3830 //D(bug("muimaster.library/window.c: Add Eventhandler %p\n", msg->ehnode));
3832 msg
->ehnode
->ehn_Priority
= msg
->ehnode
->ehn_Priority
;
3833 EnqueueByPriAndAddress((struct List
*)&data
->wd_EHList
,
3834 (struct Node
*)msg
->ehnode
);
3835 ChangeEvents(data
, GetDefaultEvents());
3839 /**************************************************************************
3840 MUIM_RemEventHandler
3841 **************************************************************************/
3842 IPTR
Window__MUIM_RemEventHandler(struct IClass
*cl
, Object
*obj
,
3843 struct MUIP_Window_RemEventHandler
*msg
)
3845 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3847 //D(bug("muimaster.library/window.c: Rem Eventhandler %p\n", msg->ehnode));
3849 Remove((struct Node
*)msg
->ehnode
);
3850 ChangeEvents(data
, GetDefaultEvents());
3854 /**************************************************************************
3855 Note that this is MUIM_Window_Setup, not MUIM_Setup
3856 **************************************************************************/
3857 IPTR
Window__MUIM_Setup(struct IClass
*cl
, Object
*obj
, Msg msg
)
3859 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3861 if (!SetupRenderInfo(obj
, data
, &data
->wd_RenderInfo
))
3864 data
->wd_Background
=
3865 zune_imspec_setup(MUII_WindowBack
, &data
->wd_RenderInfo
);
3867 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_redraw
==
3868 WINDOW_REDRAW_WITH_CLEAR
)
3869 data
->wd_Flags
|= MUIWF_ERASEAREA
;
3874 /**************************************************************************
3876 **************************************************************************/
3877 IPTR
Window__MUIM_Cleanup(struct IClass
*cl
, Object
*obj
, Msg msg
)
3879 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3881 zune_imspec_cleanup(data
->wd_Background
);
3885 DeleteDragNDrop(data
->wd_dnd
);
3886 data
->wd_dnd
= NULL
;
3889 CleanupRenderInfo(obj
, data
, &data
->wd_RenderInfo
);
3894 /**************************************************************************
3895 This adds the the control char handler and also do the MUIA_CycleChain
3896 stuff. Orginal MUI does this in an other way.
3897 **************************************************************************/
3898 IPTR
Window__MUIM_AddControlCharHandler(struct IClass
*cl
, Object
*obj
,
3899 struct MUIP_Window_AddControlCharHandler
*msg
)
3901 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3902 struct ObjNode
*node
;
3904 if (msg
->ccnode
->ehn_Events
)
3906 msg
->ccnode
->ehn_Priority
= msg
->ccnode
->ehn_Priority
;
3907 Enqueue((struct List
*)&data
->wd_CCList
,
3908 (struct Node
*)msg
->ccnode
);
3910 /* Due to the lack of a better idea ... */
3911 if (muiAreaData(msg
->ccnode
->ehn_Object
)->mad_Flags
& MADF_CYCLECHAIN
)
3913 node
= AllocPooled(data
->wd_MemoryPool
, sizeof(struct ObjNode
));
3916 node
->obj
= msg
->ccnode
->ehn_Object
;
3917 AddTail((struct List
*)&data
->wd_CycleChain
,
3918 (struct Node
*)node
);
3924 /**************************************************************************
3925 MUIM_RemControlCharHandler
3926 **************************************************************************/
3927 IPTR
Window__MUIM_RemControlCharHandler(struct IClass
*cl
, Object
*obj
,
3928 struct MUIP_Window_RemControlCharHandler
*msg
)
3930 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3931 struct ObjNode
*node
=
3932 FindObjNode(&data
->wd_CycleChain
, msg
->ccnode
->ehn_Object
);
3934 if (msg
->ccnode
->ehn_Events
)
3935 Remove((struct Node
*)msg
->ccnode
);
3939 /* Remove from the chain list */
3940 Remove((struct Node
*)node
);
3941 FreePooled(data
->wd_MemoryPool
, node
, sizeof(struct ObjNode
));
3947 /**************************************************************************
3949 **************************************************************************/
3950 IPTR
Window__MUIM_DragObject(struct IClass
*cl
, Object
*obj
,
3951 struct MUIP_Window_DragObject
*msg
)
3953 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3956 struct DragNDrop
*dnd
;
3957 struct MUI_DragImage
*di
;
3958 struct BitMapNode
*bmn
;
3960 if (!(dnd
= CreateDragNDropA(NULL
)))
3964 (struct MUI_DragImage
*)DoMethod(msg
->obj
,
3965 MUIM_CreateDragImage
, -msg
->touchx
, -msg
->touchy
,
3968 DeleteDragNDrop(dnd
);
3973 DoMethod(msg
->obj
, MUIM_DeleteDragImage
, (IPTR
) di
);
3974 DeleteDragNDrop(dnd
);
3978 if (!(bmn
= CreateBitMapNodeA(TAGLIST(
3979 GUI_BitMap
, (IPTR
)di
->bm
,
3980 GUI_LeftOffset
, di
->touchx
,
3981 GUI_TopOffset
, di
->touchy
,
3982 GUI_Width
, di
->width
,
3983 GUI_Height
, di
->height
,
3984 GUI_SourceAlpha
, !!(di
->flags
& MUIF_DRAGIMAGE_SOURCEALPHA
)))))
3986 DoMethod(msg
->obj
, MUIM_DeleteDragImage
, (IPTR
) di
);
3987 DeleteDragNDrop(dnd
);
3991 AttachBitMapNode(dnd
, bmn
);
3993 if (!PrepareDragNDrop(dnd
, data
->wd_RenderInfo
.mri_Screen
))
3995 DoMethod(msg
->obj
, MUIM_DeleteDragImage
, (IPTR
) di
);
3996 DeleteDragNDrop(dnd
);
4000 muiAreaData(msg
->obj
)->mad_Flags
|= MADF_DRAGGING
;
4002 data
->wd_DragObject
= msg
->obj
;
4004 data
->wd_DragImage
= di
;
4010 /**************************************************************************
4012 **************************************************************************/
4013 IPTR
Window__MUIM_AllocGadgetID(struct IClass
*cl
, Object
*obj
,
4014 struct MUIP_Window_AllocGadgetID
*msg
)
4016 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4017 struct IDNode
*newnode
;
4019 newnode
= AllocPooled(data
->wd_MemoryPool
, sizeof(struct IDNode
));
4025 if (IsListEmpty((struct List
*)&data
->wd_IDList
))
4028 AddHead((struct List
*)&data
->wd_IDList
,
4029 (struct Node
*)&newnode
->node
);
4035 for (mn
= data
->wd_IDList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
4037 struct IDNode
*idn
= (struct IDNode
*)mn
;
4043 Insert((struct List
*)&data
->wd_IDList
,
4044 (struct Node
*)&newnode
->node
, (struct Node
*)mn
);
4051 /**************************************************************************
4053 **************************************************************************/
4054 IPTR
Window__MUIM_FreeGadgetID(struct IClass
*cl
, Object
*obj
,
4055 struct MUIP_Window_FreeGadgetID
*msg
)
4057 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4060 for (mn
= data
->wd_IDList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
4062 struct IDNode
*idn
= (struct IDNode
*)mn
;
4063 if (msg
->gadgetid
== idn
->id
)
4065 Remove((struct Node
*)idn
);
4066 FreePooled(data
->wd_MemoryPool
, idn
, sizeof(struct IDNode
));
4075 /**************************************************************************
4076 MUIM_Window_GetMenuCheck
4077 **************************************************************************/
4078 IPTR
Window__MUIM_GetMenuCheck(struct IClass
*cl
, Object
*obj
,
4079 struct MUIP_Window_GetMenuCheck
*msg
)
4082 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4084 Object
*strip
= data
->wd_ChildMenustrip
;
4086 strip
= data
->wd_Menustrip
;
4089 if (!(item
= (Object
*) DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
)))
4091 get(item
, MUIA_Menuitem_Checked
, &stat
);
4095 /**************************************************************************
4096 MUIM_Window_SetMenuCheck
4097 **************************************************************************/
4098 IPTR
Window__MUIM_SetMenuCheck(struct IClass
*cl
, Object
*obj
,
4099 struct MUIP_Window_SetMenuCheck
*msg
)
4101 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4103 Object
*strip
= data
->wd_ChildMenustrip
;
4105 strip
= data
->wd_Menustrip
;
4108 if (!(item
= (Object
*) DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
)))
4110 set(item
, MUIA_Menuitem_Checked
, msg
->stat
);
4114 /**************************************************************************
4115 MUIM_Window_GetMenuState
4116 **************************************************************************/
4117 IPTR
Window__MUIM_GetMenuState(struct IClass
*cl
, Object
*obj
,
4118 struct MUIP_Window_GetMenuState
*msg
)
4121 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4123 Object
*strip
= data
->wd_ChildMenustrip
;
4125 strip
= data
->wd_Menustrip
;
4128 if (!(item
= (Object
*) DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
)))
4130 get(item
, MUIA_Menuitem_Enabled
, &stat
);
4134 /**************************************************************************
4135 MUIM_Window_SetMenuState
4136 **************************************************************************/
4137 IPTR
Window__MUIM_SetMenuState(struct IClass
*cl
, Object
*obj
,
4138 struct MUIP_Window_SetMenuState
*msg
)
4140 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4142 Object
*strip
= data
->wd_ChildMenustrip
;
4144 strip
= data
->wd_Menustrip
;
4147 if (!(item
= (Object
*) DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
)))
4149 set(item
, MUIA_Menuitem_Enabled
, msg
->stat
);
4153 /**************************************************************************
4154 MUIM_Window_DrawBackground
4155 **************************************************************************/
4156 IPTR
Window__MUIM_DrawBackground(struct IClass
*cl
, Object
*obj
,
4157 struct MUIP_Window_DrawBackground
*msg
)
4159 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4160 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
4163 // D(bug("%d:zune_imspec_draw(%p) l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
4164 // __LINE__, data->wd_Background, msg->left, msg->top, msg->width,
4165 // msg->height, msg->xoffset, msg->yoffset));
4166 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
4167 msg
->left
, msg
->top
, msg
->width
, msg
->height
,
4168 msg
->xoffset
, msg
->yoffset
, 0);
4172 /**************************************************************************
4174 **************************************************************************/
4175 IPTR
Window__MUIM_ToFront(struct IClass
*cl
, Object
*obj
, Msg msg
)
4177 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4178 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
4181 WindowToFront(data
->wd_RenderInfo
.mri_Window
);
4185 /**************************************************************************
4187 **************************************************************************/
4188 IPTR
Window__MUIM_ToBack(struct IClass
*cl
, Object
*obj
, Msg msg
)
4190 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4191 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
4194 WindowToBack(data
->wd_RenderInfo
.mri_Window
);
4198 /**************************************************************************
4199 MUIM_Window_ScreenToBack
4200 **************************************************************************/
4201 IPTR
Window__MUIM_ScreenToBack(struct IClass
*cl
, Object
*obj
, Msg msg
)
4203 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4204 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
4207 ScreenToBack(data
->wd_RenderInfo
.mri_Screen
);
4211 /**************************************************************************
4212 MUIM_Window_ScreenToFront
4213 **************************************************************************/
4214 IPTR
Window__MUIM_ScreenToFront(struct IClass
*cl
, Object
*obj
, Msg msg
)
4216 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4217 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
4220 ScreenToFront(data
->wd_RenderInfo
.mri_Screen
);
4224 /**************************************************************************
4225 MUIM_Window_ActionIconify
4226 **************************************************************************/
4227 IPTR
Window__MUIM_ActionIconify(struct IClass
*cl
, Object
*obj
, Msg msg
)
4229 set(_app(obj
), MUIA_Application_Iconified
, TRUE
);
4235 /* Loads ENV: prefs, add a Window_ID chunk in the MUIW chunk, if no MUIW chunk
4236 * then create it at the same level as MUIC chunk, save prefs.
4237 * Do the same for ENVARC:
4238 * MUIW chunk layout:
4240 * 00 00 00 30 (chunk length for a single window, 0x30L big endian)
4243 * xx xx yy yy (X, Y)
4244 * ww ww hh hh (Width, Height)
4245 * ax ax ay ay (AltX, AltY)
4246 * aw aw ah ah (AltWidth, AltHeight)
4254 static void RememberWindowPosition(Object
*winobj
, ULONG id
)
4260 /* Loads ENV: prefs, remove our Window_ID chunk from the MUIW chunk,
4262 * Do the same for ENVARC:
4263 * This function shouldn't really be in window.c, but rather in a file dealing
4264 * with prefs file stuff.
4266 static void ForgetWindowPosition(Object
*winobj
, ULONG id
)
4272 /**************************************************************************
4273 MUIM_Window_Snapshot
4274 **************************************************************************/
4275 IPTR
Window__MUIM_Snapshot(struct IClass
*cl
, Object
*obj
,
4276 struct MUIP_Window_Snapshot
*msg
)
4278 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4279 struct windowpos winp
;
4282 winp
.id
= data
->wd_ID
;
4283 w
= data
->wd_RenderInfo
.mri_Window
;
4286 winp
.x1
= w
->LeftEdge
;
4287 winp
.y1
= w
->TopEdge
;
4288 winp
.w1
= w
->GZZWidth
;
4289 winp
.h1
= w
->GZZHeight
;
4293 winp
.h2
= 0; //to do save alt dims
4295 set(_app(obj
), MUIA_Application_SetWinPos
, &winp
);
4299 RememberWindowPosition(obj
, data
->wd_ID
);
4301 ForgetWindowPosition(obj
, data
->wd_ID
);
4305 /**************************************************************************
4306 MUIM_Window_UpdateMenu
4307 **************************************************************************/
4308 IPTR
Window__MUIM_UpdateMenu(struct IClass
*cl
, Object
*obj
, Msg msg
)
4310 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4312 struct Menu
*menu
= NULL
;
4313 struct NewMenu
*newmenu
= NULL
;
4314 APTR visinfo
= NULL
;
4315 struct Window
*win
= NULL
;
4317 if (data
->wd_Menustrip
) // only open windows can have a menustrip
4320 GetVisualInfoA(data
->wd_RenderInfo
.mri_Screen
, NULL
)))
4322 win
= data
->wd_RenderInfo
.mri_Window
;
4323 ClearMenuStrip(win
);
4326 FreeMenus(data
->wd_Menu
);
4327 data
->wd_Menu
= NULL
;
4330 get(data
->wd_Menustrip
, MUIA_Menuitem_NewMenu
, &newmenu
);
4333 if ((menu
= CreateMenusA(newmenu
, NULL
)))
4335 struct TagItem tags
[] = {
4336 {GTMN_NewLookMenus
, TRUE
},
4339 LayoutMenusA(menu
, visinfo
, tags
);
4340 data
->wd_Menu
= menu
;
4341 SetMenuStrip(win
, menu
);
4344 FreeVisualInfo(visinfo
);
4351 /**************************************************************************
4352 MUIM_Export : to export an object's "contents" to a dataspace object.
4353 **************************************************************************/
4354 static IPTR
Window__MUIM_Export(struct IClass
*cl
, Object
*obj
,
4355 struct MUIP_Export
*msg
)
4357 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4358 DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
4363 /**************************************************************************
4364 MUIM_Import : to import an object's "contents" from a dataspace object.
4365 **************************************************************************/
4366 static IPTR
Window__MUIM_Import(struct IClass
*cl
, Object
*obj
,
4367 struct MUIP_Import
*msg
)
4369 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4370 DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
4374 BOOPSI_DISPATCHER(IPTR
, Window_Dispatcher
, cl
, obj
, msg
)
4376 switch (msg
->MethodID
)
4379 return Window__OM_NEW(cl
, obj
, (struct opSet
*)msg
);
4381 return Window__OM_DISPOSE(cl
, obj
, msg
);
4383 return Window__OM_SET(cl
, obj
, (struct opSet
*)msg
);
4385 return Window__OM_GET(cl
, obj
, (struct opGet
*)msg
);
4386 case MUIM_FindUData
:
4387 return Window__MUIM_FindUData(cl
, obj
,
4388 (struct MUIP_FindUData
*)msg
);
4390 return Window__MUIM_GetUData(cl
, obj
, (struct MUIP_GetUData
*)msg
);
4392 return Window__MUIM_SetUData(cl
, obj
, (struct MUIP_SetUData
*)msg
);
4393 case MUIM_SetUDataOnce
:
4394 return Window__MUIM_SetUDataOnce(cl
, obj
,
4395 (struct MUIP_SetUDataOnce
*)msg
);
4396 case MUIM_Window_AddEventHandler
:
4397 return Window__MUIM_AddEventHandler(cl
, obj
, (APTR
) msg
);
4398 case MUIM_Window_RemEventHandler
:
4399 return Window__MUIM_RemEventHandler(cl
, obj
, (APTR
) msg
);
4400 case MUIM_ConnectParent
:
4401 return Window__MUIM_ConnectParent(cl
, obj
, (APTR
) msg
);
4402 case MUIM_DisconnectParent
:
4403 return Window__MUIM_DisconnectParent(cl
, obj
, (APTR
) msg
);
4404 case MUIM_Window_RecalcDisplay
:
4405 return Window__MUIM_RecalcDisplay(cl
, obj
, (APTR
) msg
);
4406 case MUIM_Window_Setup
:
4407 return Window__MUIM_Setup(cl
, obj
, (APTR
) msg
);
4408 case MUIM_Window_Cleanup
:
4409 return Window__MUIM_Cleanup(cl
, obj
, (APTR
) msg
);
4410 case MUIM_Window_AddControlCharHandler
:
4411 return Window__MUIM_AddControlCharHandler(cl
, obj
, (APTR
) msg
);
4412 case MUIM_Window_RemControlCharHandler
:
4413 return Window__MUIM_RemControlCharHandler(cl
, obj
, (APTR
) msg
);
4414 case MUIM_Window_DragObject
:
4415 return Window__MUIM_DragObject(cl
, obj
, (APTR
) msg
);
4416 case MUIM_Window_AllocGadgetID
:
4417 return Window__MUIM_AllocGadgetID(cl
, obj
, (APTR
) msg
);
4418 case MUIM_Window_FreeGadgetID
:
4419 return Window__MUIM_FreeGadgetID(cl
, obj
, (APTR
) msg
);
4420 case MUIM_Window_GetMenuCheck
:
4421 return Window__MUIM_GetMenuCheck(cl
, obj
, (APTR
) msg
);
4422 case MUIM_Window_SetMenuCheck
:
4423 return Window__MUIM_SetMenuCheck(cl
, obj
, (APTR
) msg
);
4424 case MUIM_Window_GetMenuState
:
4425 return Window__MUIM_GetMenuState(cl
, obj
, (APTR
) msg
);
4426 case MUIM_Window_SetMenuState
:
4427 return Window__MUIM_SetMenuState(cl
, obj
, (APTR
) msg
);
4428 case MUIM_Window_DrawBackground
:
4429 return Window__MUIM_DrawBackground(cl
, obj
, (APTR
) msg
);
4430 case MUIM_Window_ToFront
:
4431 return Window__MUIM_ToFront(cl
, obj
, (APTR
) msg
);
4432 case MUIM_Window_ToBack
:
4433 return Window__MUIM_ToBack(cl
, obj
, (APTR
) msg
);
4434 case MUIM_Window_ScreenToFront
:
4435 return Window__MUIM_ScreenToFront(cl
, obj
, (APTR
) msg
);
4436 case MUIM_Window_ScreenToBack
:
4437 return Window__MUIM_ScreenToBack(cl
, obj
, (APTR
) msg
);
4438 case MUIM_Window_ActionIconify
:
4439 return Window__MUIM_ActionIconify(cl
, obj
, (APTR
) msg
);
4440 case MUIM_Window_Snapshot
:
4441 return Window__MUIM_Snapshot(cl
, obj
, (APTR
) msg
);
4442 case MUIM_Window_UpdateMenu
:
4443 return Window__MUIM_UpdateMenu(cl
, obj
, (APTR
) msg
);
4445 return Window__MUIM_Export(cl
, obj
, (APTR
) msg
);
4447 return Window__MUIM_Import(cl
, obj
, (APTR
) msg
);
4450 return DoSuperMethodA(cl
, obj
, msg
);
4452 BOOPSI_DISPATCHER_END
4457 const struct __MUIBuiltinClass _MUI_Window_desc
=
4461 sizeof(struct MUI_WindowData
),
4462 (void *) Window_Dispatcher