2 Copyright © 1999, David Le Corfec.
3 Copyright © 2002-2015, 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 app's or window's or NULL) */
114 Object
*wd_ChildMenustrip
; /* If window has its 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 */
141 struct IClass
*wd_Class
;
144 #ifndef WFLG_SIZEGADGET
146 #define WFLG_CLOSEGADGET (1<<0) /* has close gadget */
147 #define WFLG_SIZEGADGET (1<<1) /* has size gadget */
148 #define WFLG_BACKDROP (1<<2) /* is backdrop window */
149 #define WFLG_BORDERLESS (1<<3) /* has no borders */
150 #define WFLG_DEPTHGADGET (1<<4) /* has depth gadget */
151 #define WFLG_DRAGBAR (1<<5) /* is draggable */
152 #define WFLG_SIZEBRIGHT (1<<6) /* size gadget is in right border */
157 #define MUIWF_OPENED (1<<0) /* window currently opened */
158 #define MUIWF_HIDDEN (1<<1) /* window currently iconified */
159 #define MUIWF_ACTIVE (1<<2) /* window currently active */
160 #define MUIWF_RESIZING (1<<4) /* window currently resizing */
161 #define MUIWF_DONTACTIVATE (1<<7) /* do not activate the window when
163 #define MUIWF_USERIGHTSCROLLER (1<<8) /* should have right scroller */
164 #define MUIWF_USEBOTTOMSCROLLER (1<<9) /* should have bottom scroller */
165 #define MUIWF_ERASEAREA (1<<10) /* Erase area after a window resize */
166 #define MUIWF_ISAPPWINDOW (1<<11) /* Is an AppWindow */
167 #define MUIWF_ISSUBWINDOW (1<<12) /* Don't get automatically disposed
169 #define MUIWF_BUBBLEMODE (1<<13) /* Quick bubble mode. Bubbles appear
170 * quick when moving */
171 #define MUIWF_OPENONUNHIDE (1<<14) /* Open the window when unhiding */
172 #define MUIWF_SCREENLOCKED (1<<15) /* A pub screen was locked in
173 * SetupRenderInfo. Unlock it in
174 * CleanupRenderInfo! */
175 #define MUIWF_OBJECTGOACTIVESENT (1<<16) /* A MUIM_GoActive msg was sent to
176 * window's active object */
177 #define MUIWF_TOOLBOX (1<<17) /* Window should be opened as
180 #define BUBBLEHELP_TICKER_FIRST 10
181 #define BUBBLEHELP_TICKER_LATER 3
185 struct MUI_NotifyData mnd
;
186 struct MUI_WindowData mwd
;
189 #define muiWindowData(obj) (&(((struct __dummyXFC3__ *)(obj))->mwd))
191 static void ActivateObject(struct MUI_WindowData
*data
);
192 static void HandleInputEvent(Object
*win
, struct MUI_WindowData
*data
,
193 struct IntuiMessage
*event
);
195 static ULONG
DoHalfshineGun(ULONG a
, ULONG b
)
197 ULONG val
= ((((a
) >> 24) + 3 * ((b
) >> 24)) / 4);
198 val
= val
+ (val
<< 8) + (val
<< 16) + (val
<< 24);
202 static ULONG
DoHalfshadowGun(ULONG a
, ULONG b
)
204 ULONG val
= ((((a
) >> 24) + 5 * ((b
) >> 24)) / 6);
205 val
= val
+ (val
<< 8) + (val
<< 16) + (val
<< 24);
209 static Object
*CreateSysimage(struct DrawInfo
*dri
, ULONG which
)
211 return NewObject(NULL
, "sysiclass",
212 SYSIA_DrawInfo
, (IPTR
) dri
, SYSIA_Which
, which
, TAG_DONE
);
215 static void EnqueueByPriAndAddress(struct List
*list
, struct Node
*node
)
217 struct Node
*scannode
;
219 /* Sort by priority and by node address, so that a
220 "remove - modify - enqueue" sequence will re-add
221 the node at the same place in the list it was
223 ForeachNode(list
, scannode
)
225 if (((struct Node
*)node
)->ln_Pri
> scannode
->ln_Pri
)
227 if (((struct Node
*)node
)->ln_Pri
== scannode
->ln_Pri
)
229 if ((IPTR
) node
> (IPTR
) scannode
)
234 Insert(list
, (struct Node
*)node
, scannode
->ln_Pred
);
237 static BOOL
InitCustomFrames(Object
*obj
, struct MUI_RenderInfo
*mri
)
241 for (i
= 0; i
< 16; i
++)
243 mri
->mri_FrameImage
[i
] = NULL
;
246 mri
->mri_FrameImage
[0] =
247 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
248 customframe_config_1
, mri
->mri_Screen
);
249 mri
->mri_FrameImage
[1] =
250 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
251 customframe_config_2
, mri
->mri_Screen
);
252 mri
->mri_FrameImage
[2] =
253 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
254 customframe_config_3
, mri
->mri_Screen
);
255 mri
->mri_FrameImage
[3] =
256 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
257 customframe_config_4
, mri
->mri_Screen
);
258 mri
->mri_FrameImage
[4] =
259 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
260 customframe_config_5
, mri
->mri_Screen
);
261 mri
->mri_FrameImage
[5] =
262 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
263 customframe_config_6
, mri
->mri_Screen
);
264 mri
->mri_FrameImage
[6] =
265 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
266 customframe_config_7
, mri
->mri_Screen
);
267 mri
->mri_FrameImage
[7] =
268 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
269 customframe_config_8
, mri
->mri_Screen
);
270 mri
->mri_FrameImage
[8] =
271 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
272 customframe_config_9
, mri
->mri_Screen
);
273 mri
->mri_FrameImage
[9] =
274 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
275 customframe_config_10
, mri
->mri_Screen
);
276 mri
->mri_FrameImage
[10] =
277 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
278 customframe_config_11
, mri
->mri_Screen
);
279 mri
->mri_FrameImage
[11] =
280 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
281 customframe_config_12
, mri
->mri_Screen
);
282 mri
->mri_FrameImage
[12] =
283 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
284 customframe_config_13
, mri
->mri_Screen
);
285 mri
->mri_FrameImage
[13] =
286 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
287 customframe_config_14
, mri
->mri_Screen
);
288 mri
->mri_FrameImage
[14] =
289 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
290 customframe_config_15
, mri
->mri_Screen
);
291 mri
->mri_FrameImage
[15] =
292 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
293 customframe_config_16
, mri
->mri_Screen
);
298 static void DisposeCustomFrames(struct MUI_RenderInfo
*mri
)
302 for (i
= 0; i
< 16; i
++)
304 dispose_custom_frame(mri
->mri_FrameImage
[i
]);
306 mri
->mri_FrameImage
[i
] = NULL
;
310 static BOOL
SetupRenderInfo(Object
*obj
, struct MUI_WindowData
*data
,
311 struct MUI_RenderInfo
*mri
)
313 ULONG rgbtable
[3 * 3];
318 /* TODO: Move this whole screen locking/opening stuff into the
319 * application class by creating methods for this purpose */
321 /* If no user screen has been specified try to open the application
323 if (!data
->wd_UserScreen
)
325 ULONG screenmodeid
= muiGlobalInfo(obj
)->mgi_Prefs
->screenmodeid
;
327 if (screenmodeid
!= ~0)
329 if (!muiGlobalInfo(obj
)->mgi_CustomScreen
)
331 muiGlobalInfo(obj
)->mgi_CustomScreen
= OpenScreenTags
333 SA_DisplayID
, screenmodeid
,
335 SA_FullPalette
, TRUE
, SA_LikeWorkbench
, TRUE
, TAG_DONE
);
336 /* It's fine if this fails as there is a fallback case below */
339 data
->wd_UserScreen
= muiGlobalInfo(obj
)->mgi_CustomScreen
;
342 if (data
->wd_UserScreen
)
344 mri
->mri_Screen
= data
->wd_UserScreen
;
348 if (data
->wd_UserPublicScreen
)
350 mri
->mri_Screen
= LockPubScreen(data
->wd_UserPublicScreen
);
352 else if (muiGlobalInfo(obj
)->mgi_Prefs
->publicscreen_name
353 && muiGlobalInfo(obj
)->mgi_Prefs
->publicscreen_name
[0])
356 LockPubScreen(muiGlobalInfo(obj
)->mgi_Prefs
->
358 // FIXME: open the public screen if necessary
361 if (mri
->mri_Screen
== NULL
)
363 mri
->mri_Screen
= LockPubScreen(NULL
);
364 if (mri
->mri_Screen
== NULL
)
370 // FIXME: is this the right place for this action?
372 && muiGlobalInfo(obj
)->mgi_Prefs
->publicscreen_pop_to_front
)
374 ScreenToFront(mri
->mri_Screen
);
377 data
->wd_Flags
|= MUIWF_SCREENLOCKED
;
380 if (!(mri
->mri_DrawInfo
= GetScreenDrawInfo(mri
->mri_Screen
)))
382 if (data
->wd_Flags
& MUIWF_SCREENLOCKED
)
384 UnlockPubScreen(NULL
, mri
->mri_Screen
);
385 data
->wd_Flags
&= ~MUIWF_SCREENLOCKED
;
390 if (!InitCustomFrames(obj
, mri
))
392 if (data
->wd_Flags
& MUIWF_SCREENLOCKED
)
394 UnlockPubScreen(NULL
, mri
->mri_Screen
);
395 data
->wd_Flags
&= ~MUIWF_SCREENLOCKED
;
400 mri
->mri_Colormap
= mri
->mri_Screen
->ViewPort
.ColorMap
;
401 mri
->mri_ScreenWidth
= mri
->mri_Screen
->Width
;
402 mri
->mri_ScreenHeight
= mri
->mri_Screen
->Height
;
404 if (mri
->mri_ScreenWidth
/ mri
->mri_ScreenHeight
< 2)
406 mri
->mri_Flags
|= MUIMRI_THINFRAMES
;
409 if (GetBitMapAttr(mri
->mri_Screen
->RastPort
.BitMap
, BMA_DEPTH
) >= 15)
411 mri
->mri_Flags
|= MUIMRI_TRUECOLOR
;
414 mri
->mri_PensStorage
[MPEN_SHINE
] =
415 mri
->mri_DrawInfo
->dri_Pens
[SHINEPEN
];
416 mri
->mri_PensStorage
[MPEN_BACKGROUND
] =
417 mri
->mri_DrawInfo
->dri_Pens
[BACKGROUNDPEN
];
418 mri
->mri_PensStorage
[MPEN_SHADOW
] =
419 mri
->mri_DrawInfo
->dri_Pens
[SHADOWPEN
];
420 mri
->mri_PensStorage
[MPEN_TEXT
] = mri
->mri_DrawInfo
->dri_Pens
[TEXTPEN
];
421 mri
->mri_PensStorage
[MPEN_FILL
] = mri
->mri_DrawInfo
->dri_Pens
[FILLPEN
];
423 GetRGB32(mri
->mri_Colormap
, mri
->mri_DrawInfo
->dri_Pens
[SHINEPEN
], 1,
425 GetRGB32(mri
->mri_Colormap
, mri
->mri_DrawInfo
->dri_Pens
[BACKGROUNDPEN
],
427 GetRGB32(mri
->mri_Colormap
, mri
->mri_DrawInfo
->dri_Pens
[SHADOWPEN
], 1,
430 mri
->mri_PensStorage
[MPEN_HALFSHINE
] = ObtainBestPenA
432 DoHalfshineGun(rgbtable
[0], rgbtable
[3]),
433 DoHalfshineGun(rgbtable
[1], rgbtable
[4]),
434 DoHalfshineGun(rgbtable
[2], rgbtable
[5]), NULL
);
436 mri
->mri_PensStorage
[MPEN_HALFSHADOW
] = ObtainBestPenA
438 DoHalfshadowGun(rgbtable
[6], rgbtable
[3]),
439 DoHalfshadowGun(rgbtable
[7], rgbtable
[4]),
440 DoHalfshadowGun(rgbtable
[8], rgbtable
[5]), NULL
);
442 /* I'm really not sure that MUI does this for MPEN_MARK, but it seems
443 * mostly acceptable -dlc */
444 mri
->mri_PensStorage
[MPEN_MARK
] = ObtainBestPenA
445 (mri
->mri_Colormap
, 0xf4f4f4f4, 0xb5b5b5b5, 0x8b8b8b8b, NULL
);
447 mri
->mri_Pens
= mri
->mri_PensStorage
;
449 for (i
= 0; i
< -MUIV_Font_NegCount
; i
++)
451 mri
->mri_Fonts
[i
] = NULL
;
454 if (data
->wd_Flags
& MUIWF_USEBOTTOMSCROLLER
)
456 mri
->mri_LeftImage
= CreateSysimage(mri
->mri_DrawInfo
, LEFTIMAGE
);
457 mri
->mri_RightImage
= CreateSysimage(mri
->mri_DrawInfo
, RIGHTIMAGE
);
461 mri
->mri_LeftImage
= mri
->mri_RightImage
= NULL
;
464 if (data
->wd_Flags
& MUIWF_USERIGHTSCROLLER
)
466 mri
->mri_UpImage
= CreateSysimage(mri
->mri_DrawInfo
, UPIMAGE
);
467 mri
->mri_DownImage
= CreateSysimage(mri
->mri_DrawInfo
, DOWNIMAGE
);
471 mri
->mri_UpImage
= mri
->mri_DownImage
= NULL
;
474 if ((data
->wd_Flags
& MUIWF_USEBOTTOMSCROLLER
) ||
475 (data
->wd_Flags
& MUIWF_USERIGHTSCROLLER
))
476 mri
->mri_SizeImage
= CreateSysimage(mri
->mri_DrawInfo
, SIZEIMAGE
);
478 mri
->mri_SizeImage
= NULL
;
480 if (data
->wd_CrtFlags
& WFLG_BORDERLESS
)
482 /* In fact borderless windows could also have borders (if they have
483 * a window title e.g. but since they look ugly anyway we ignore it
485 mri
->mri_BorderLeft
= 0;
486 mri
->mri_BorderRight
= 0;
487 mri
->mri_BorderTop
= 0;
488 mri
->mri_BorderBottom
= 0;
492 mri
->mri_BorderLeft
= mri
->mri_Screen
->WBorLeft
;
494 mri
->mri_Screen
->WBorTop
+ mri
->mri_Screen
->Font
->ta_YSize
+ 1;
496 NewObject(NULL
, "sysiclass", SYSIA_DrawInfo
,
497 (IPTR
) mri
->mri_DrawInfo
, SYSIA_Which
, SIZEIMAGE
, TAG_DONE
);
500 GetAttr(IA_Height
, temp_obj
, &val
);
501 DisposeObject(temp_obj
);
502 mri
->mri_BorderBottom
= val
;
505 mri
->mri_BorderBottom
= mri
->mri_Screen
->WBorBottom
;
511 static void CleanupRenderInfo(Object
*obj
, struct MUI_WindowData
*data
,
512 struct MUI_RenderInfo
*mri
)
516 DisposeCustomFrames(mri
);
518 if (mri
->mri_LeftImage
)
520 DisposeObject(mri
->mri_LeftImage
);
521 mri
->mri_LeftImage
= NULL
;
523 if (mri
->mri_RightImage
)
525 DisposeObject(mri
->mri_RightImage
);
526 mri
->mri_RightImage
= NULL
;
528 if (mri
->mri_UpImage
)
530 DisposeObject(mri
->mri_UpImage
);
531 mri
->mri_UpImage
= NULL
;
533 if (mri
->mri_DownImage
)
535 DisposeObject(mri
->mri_DownImage
);
536 mri
->mri_DownImage
= NULL
;
538 if (mri
->mri_SizeImage
)
540 DisposeObject(mri
->mri_SizeImage
);
541 mri
->mri_SizeImage
= NULL
;
544 /* bug("CleanupRenderInfo\n"); */
545 for (i
= 0; i
< -MUIV_Font_NegCount
; i
++)
547 if (mri
->mri_Fonts
[i
])
549 /* bug("CleanupRenderInfo: closing font %p (%s/%d)\n", */
550 /* mri->mri_Fonts[i], */
551 /* mri->mri_Fonts[i]->tf_Message.mn_Node.ln_Name, */
552 /* mri->mri_Fonts[i]->tf_YSize); */
553 CloseFont(mri
->mri_Fonts
[i
]);
554 mri
->mri_Fonts
[i
] = NULL
;
557 ReleasePen(mri
->mri_Colormap
, mri
->mri_PensStorage
[MPEN_MARK
]);
558 ReleasePen(mri
->mri_Colormap
, mri
->mri_PensStorage
[MPEN_HALFSHADOW
]);
559 ReleasePen(mri
->mri_Colormap
, mri
->mri_PensStorage
[MPEN_HALFSHINE
]);
560 FreeScreenDrawInfo(mri
->mri_Screen
, mri
->mri_DrawInfo
);
561 mri
->mri_DrawInfo
= NULL
;
563 /* If a custom screen has been opened by zune, close it as soon as zero
564 * windows are opened. See above for comments about refactorization. */
565 if (muiGlobalInfo(obj
)->mgi_CustomScreen
)
567 BOOL screenclose
= TRUE
;
568 Object
*_app
= _app(obj
);
571 struct List
*store
= NULL
;
572 get(_app
, MUIA_Application_WindowList
, &store
);
575 if (!IsListEmpty(store
))
581 /* If the window's user screen really was the custom screen,
582 * clear the reference */
583 if (data
->wd_UserScreen
== muiGlobalInfo(obj
)->mgi_CustomScreen
)
584 data
->wd_UserScreen
= NULL
;
586 CloseScreen(muiGlobalInfo(obj
)->mgi_CustomScreen
);
587 muiGlobalInfo(obj
)->mgi_CustomScreen
= NULL
;
591 if (data
->wd_Flags
& MUIWF_SCREENLOCKED
)
593 UnlockPubScreen(NULL
, mri
->mri_Screen
);
594 data
->wd_Flags
&= ~MUIWF_SCREENLOCKED
;
596 mri
->mri_Screen
= NULL
;
599 static void ShowRenderInfo(struct MUI_RenderInfo
*mri
)
601 if (mri
->mri_BufferBM
)
603 mri
->mri_RastPort
= &mri
->mri_BufferRP
;
607 mri
->mri_RastPort
= mri
->mri_Window
->RPort
;
611 static void HideRenderInfo(struct MUI_RenderInfo
*mri
)
613 mri
->mri_RastPort
= NULL
;
616 static ULONG
GetDefaultEvents(void)
618 return IDCMP_NEWSIZE
| IDCMP_CHANGEWINDOW
| IDCMP_REFRESHWINDOW
619 | IDCMP_MOUSEBUTTONS
| IDCMP_MOUSEMOVE
| IDCMP_MENUPICK
620 | IDCMP_CLOSEWINDOW
| IDCMP_RAWKEY
| IDCMP_INTUITICKS
621 | IDCMP_ACTIVEWINDOW
| IDCMP_INACTIVEWINDOW
| IDCMP_GADGETUP
;
624 static void ChangeEvents(struct MUI_WindowData
*data
, ULONG new_events
)
627 struct MUI_EventHandlerNode
*ehn
;
628 ULONG old_events
= data
->wd_Events
;
630 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
632 ehn
= (struct MUI_EventHandlerNode
*)mn
;
633 new_events
|= ehn
->ehn_Events
;
636 /* sba: kill the IDCMP_VANILLAKEY flag. MUI doesn't do this but programs
637 ** which use this will behave different if they request for this flag
640 new_events
&= ~IDCMP_VANILLAKEY
;
642 data
->wd_Events
= new_events
;
643 if ((old_events
!= new_events
) && (data
->wd_Flags
& MUIWF_OPENED
))
645 ModifyIDCMP(data
->wd_RenderInfo
.mri_Window
, new_events
);
649 static void CalcWindowPosition(Object
*obj
, struct MUI_WindowData
*data
);
650 static void CreateWindowScrollbars(Object
*obj
,
651 struct MUI_WindowData
*data
);
652 static void CalcAltDimensions(Object
*obj
, struct MUI_WindowData
*data
);
653 static void UndisplayWindow(Object
*obj
, struct MUI_WindowData
*data
);
654 static struct ObjNode
*FindObjNode(struct MinList
*list
, Object
*obj
);
656 static BOOL
DisplayWindow(Object
*obj
, struct MUI_WindowData
*data
)
659 ULONG flags
= data
->wd_CrtFlags
;
661 ULONG backfill
, buttons
;
663 struct Menu
*menu
= NULL
;
664 struct NewMenu
*newmenu
= NULL
;
669 if (!(data
->wd_Flags
& MUIWF_DONTACTIVATE
))
671 flags
|= WFLG_ACTIVATE
;
674 /* Toolboxes are handled differently on AmigaOS */
676 if (data
->wd_Flags
& MUIWF_TOOLBOX
)
677 flags
|= WFLG_TOOLBOX
;
680 if (data
->wd_MinMax
.MinHeight
== data
->wd_MinMax
.MaxHeight
681 && data
->wd_MinMax
.MinWidth
== data
->wd_MinMax
.MaxWidth
)
682 flags
&= ~WFLG_SIZEGADGET
;
684 if (!(flags
& WFLG_SIZEBRIGHT
))
685 flags
|= WFLG_SIZEBBOTTOM
;
687 CalcWindowPosition(obj
, data
);
689 if ((visinfo
= GetVisualInfoA(data
->wd_RenderInfo
.mri_Screen
, NULL
)))
691 if (data
->wd_Menustrip
)
693 get(data
->wd_Menustrip
, MUIA_Menuitem_NewMenu
, &newmenu
);
696 if ((menu
= CreateMenusA(newmenu
, NULL
)))
698 struct TagItem tags
[] = {
699 {GTMN_NewLookMenus
, TRUE
},
700 {TAG_DONE
, (IPTR
) NULL
}
702 LayoutMenusA(menu
, visinfo
, tags
);
706 FreeVisualInfo(visinfo
);
709 CreateWindowScrollbars(obj
, data
);
710 CalcAltDimensions(obj
, data
);
711 altdims
= data
->wd_AltDim
;
713 /* hack to account for border size, as we only know the innersize and
714 * must give the total size.
717 data
->wd_RenderInfo
.mri_Screen
->WBorLeft
+
718 data
->wd_RenderInfo
.mri_Screen
->WBorRight
;
720 data
->wd_RenderInfo
.mri_Screen
->WBorTop
+
721 data
->wd_RenderInfo
.mri_Screen
->WBorBottom
+
722 data
->wd_RenderInfo
.mri_DrawInfo
->dri_Font
->tf_YSize
+ 1;
724 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_redraw
==
725 WINDOW_REDRAW_WITHOUT_CLEAR
)
726 backfill
= WA_BackFill
;
728 backfill
= TAG_IGNORE
;
730 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_refresh
==
731 WINDOW_REFRESH_SMART
)
732 flags
&= ~WFLG_SIMPLE_REFRESH
;
733 set(_app(obj
), MUIA_Application_SearchWinId
, data
->wd_ID
);
734 struct windowpos
*winp
= 0;
735 get(_app(obj
), MUIA_Application_GetWinPos
, &winp
);
738 if (data
->wd_RenderInfo
.mri_ScreenWidth
>
739 (data
->wd_X
+ data
->wd_Width
))
741 data
->wd_X
= winp
->x1
;
742 data
->wd_Width
= winp
->w1
;
744 if (data
->wd_RenderInfo
.mri_ScreenHeight
>
745 (data
->wd_Y
+ data
->wd_Height
))
747 data
->wd_Y
= winp
->y1
;
748 data
->wd_Height
= winp
->h1
;
753 (data
->wd_VertProp
!=
754 NULL
) ? data
->wd_VertProp
: data
->wd_HorizProp
;
755 buttons
= muiGlobalInfo(obj
)->mgi_Prefs
->window_buttons
;
759 WA_Left
, (IPTR
) data
->wd_X
,
760 WA_Top
, (IPTR
) data
->wd_Y
,
761 WA_Flags
, (IPTR
) flags
,
764 TAG_IGNORE
, (IPTR
) data
->wd_Title
,
765 data
->wd_ScreenTitle
?
767 TAG_IGNORE
, (IPTR
) data
->wd_ScreenTitle
,
768 WA_CustomScreen
, (IPTR
) data
->wd_RenderInfo
.mri_Screen
,
769 WA_InnerWidth
, (IPTR
) data
->wd_Width
,
770 WA_InnerHeight
, (IPTR
) data
->wd_Height
,
771 WA_AutoAdjust
, (IPTR
) TRUE
, WA_NewLookMenus
, (IPTR
) TRUE
,
772 /* AmigaOS v4 extension */
774 WA_ToolBox
, (IPTR
) ! !(data
->wd_Flags
& MUIWF_TOOLBOX
),
776 /* MorphOS extensions */
777 #ifdef WA_ExtraGadget_MUI
779 (IPTR
) ((buttons
& MUIV_Window_Button_MUI
) != 0) ? TRUE
: FALSE
,
780 WA_ExtraGadget_PopUp
,
781 (IPTR
) ((buttons
& MUIV_Window_Button_Popup
) != 0) ? TRUE
: FALSE
,
782 WA_ExtraGadget_Snapshot
,
783 (IPTR
) ((buttons
& MUIV_Window_Button_Snapshot
) !=
784 0) ? TRUE
: FALSE
, WA_ExtraGadget_Iconify
,
785 (IPTR
) ((buttons
& MUIV_Window_Button_Iconify
) != 0) ? TRUE
: FALSE
,
789 TAG_IGNORE
, (IPTR
) TRUE
,
790 WA_Gadgets
, (IPTR
) gadgets
,
791 data
->wd_ZoomGadget
?
793 TAG_IGNORE
, (IPTR
) & altdims
,
794 backfill
, (IPTR
) LAYERS_NOBACKFILL
, TAG_DONE
);
799 int hborders
= win
->BorderLeft
+ win
->BorderRight
;
800 int vborders
= win
->BorderTop
+ win
->BorderBottom
;
802 /* recalc window size (which will hopefully equal our requested
804 data
->wd_Width
= win
->GZZWidth
;
805 data
->wd_Height
= win
->GZZHeight
;
807 /* set window limits according to window contents */
809 (win
, data
->wd_MinMax
.MinWidth
+ hborders
,
810 data
->wd_MinMax
.MinHeight
+ vborders
,
811 data
->wd_MinMax
.MaxWidth
+ hborders
,
812 data
->wd_MinMax
.MaxHeight
+ vborders
);
814 win
->UserData
= (BYTE
*) data
->wd_RenderInfo
.mri_WindowObject
;
815 win
->UserPort
= muiGlobalInfo(obj
)->mgi_WindowsPort
;
816 /* Same port for all windows */
817 ModifyIDCMP(win
, data
->wd_Events
);
819 data
->wd_RenderInfo
.mri_Window
= win
;
820 data
->wd_RenderInfo
.mri_VertProp
= data
->wd_VertProp
;
821 data
->wd_RenderInfo
.mri_HorizProp
= data
->wd_HorizProp
;
822 SetDrMd(win
->RPort
, JAM1
);
823 //text is drawn wrong in toolbarclass if not set
827 data
->wd_Menu
= menu
;
828 SetMenuStrip(win
, menu
);
831 if (flags
& WFLG_ACTIVATE
)
833 data
->wd_Flags
|= MUIWF_ACTIVE
;
836 if (data
->wd_Flags
& MUIWF_ISAPPWINDOW
)
838 data
->wd_AppWindow
= AddAppWindowA(0, (IPTR
) obj
, win
,
839 muiGlobalInfo(obj
)->mgi_AppPort
, NULL
);
847 UndisplayWindow(obj
, data
);
853 static void UndisplayWindow(Object
*obj
, struct MUI_WindowData
*data
)
855 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
857 ((muiGlobalInfo(obj
)->mgi_Prefs
->window_position
==
858 WINDOW_POSITION_REMEMBER_ON_EXIT
)
859 || (muiGlobalInfo(obj
)->mgi_Prefs
->window_position
==
860 WINDOW_POSITION_SAVE_ON_EXIT
));
862 if (((data
->wd_XStore
>= 0) && (data
->wd_YStore
>= 0)) || prefssnap
)
864 DoMethod(obj
, MUIM_Window_Snapshot
, 1);
867 data
->wd_RenderInfo
.mri_Window
= NULL
;
868 data
->wd_RenderInfo
.mri_VertProp
= NULL
;
869 data
->wd_RenderInfo
.mri_HorizProp
= NULL
;
871 data
->wd_Flags
&= ~MUIWF_ACTIVE
;
875 /* store position and size */
876 if (data
->wd_XStore
>= 0)
877 data
->wd_X
= win
->LeftEdge
;
879 data
->wd_X
= data
->wd_XStore
;
880 if (data
->wd_YStore
>= 0)
881 data
->wd_Y
= win
->TopEdge
;
883 data
->wd_Y
= data
->wd_YStore
;
884 data
->wd_Width
= win
->GZZWidth
;
885 data
->wd_Height
= win
->GZZHeight
;
890 FreeMenus(data
->wd_Menu
);
891 data
->wd_Menu
= NULL
;
896 struct IntuiMessage
*msg
, *succ
;
898 /* remove all messages pending for this window */
901 (struct IntuiMessage
*)win
->UserPort
->mp_MsgList
.lh_Head
;
903 (struct IntuiMessage
*)msg
->ExecMessage
.mn_Node
.
904 ln_Succ
); msg
= succ
)
906 if (msg
->IDCMPWindow
== win
)
908 Remove((struct Node
*)msg
);
909 ReplyMsg((struct Message
*)msg
);
912 win
->UserPort
= NULL
;
917 /* D(bug("before CloseWindow\n")); */
919 /* D(bug("after CloseWindow\n")); */
922 #define DISPOSEGADGET(x) \
925 DoMethod(obj, MUIM_Window_FreeGadgetID,\
926 ((struct Gadget*)x)->GadgetID);\
931 DISPOSEGADGET(data
->wd_VertProp
);
932 DISPOSEGADGET(data
->wd_UpButton
);
933 DISPOSEGADGET(data
->wd_DownButton
);
934 DISPOSEGADGET(data
->wd_HorizProp
);
935 DISPOSEGADGET(data
->wd_LeftButton
);
936 DISPOSEGADGET(data
->wd_RightButton
);
941 static VOID
RefreshWindow(Object
*oWin
, struct MUI_WindowData
*data
)
943 if (data
->wd_Flags
& MUIWF_RESIZING
)
945 //LONG left,top,right,bottom;
946 if (MUI_BeginRefresh(&data
->wd_RenderInfo
, 0))
948 MUI_EndRefresh(&data
->wd_RenderInfo
, 0);
950 RefreshWindowFrame(data
->wd_RenderInfo
.mri_Window
);
952 data
->wd_Flags
&= ~MUIWF_RESIZING
;
953 _width(data
->wd_RootObject
) = data
->wd_Width
;
954 _height(data
->wd_RootObject
) = data
->wd_Height
;
955 DoMethod(data
->wd_RootObject
, MUIM_Layout
);
956 DoShowMethod(data
->wd_RootObject
);
958 if (muiGlobalInfo(oWin
)->mgi_Prefs
->window_redraw
==
959 WINDOW_REDRAW_WITH_CLEAR
)
961 LONG left
, top
, width
, height
;
963 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
964 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
;
966 data
->wd_RenderInfo
.mri_Window
->Width
-
967 data
->wd_RenderInfo
.mri_Window
->BorderRight
- left
;
969 data
->wd_RenderInfo
.mri_Window
->Height
-
970 data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
972 if (data
->wd_Flags
& MUIWF_ERASEAREA
)
974 //D(bug("%d:zune_imspec_draw(%p) "
975 // "l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
976 // __LINE__, data->wd_Background, left, top, width,
977 // height, left, top));
978 zune_imspec_draw(data
->wd_Background
,
979 &data
->wd_RenderInfo
, left
, top
, width
, height
,
982 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWALL
);
985 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWOBJECT
);
986 // but should only draw focus without using MUIM_GoActive !
987 ActivateObject(data
);
991 if (MUI_BeginRefresh(&data
->wd_RenderInfo
, 0))
993 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWALL
);
994 // but should only draw focus without using MUIM_GoActive !
995 ActivateObject(data
);
996 MUI_EndRefresh(&data
->wd_RenderInfo
, 0);
1002 /* Initialize data->wd_X and data->wd_Y for DisplayWindow */
1003 /* FIXME 20030817: needs some fixing, seems not fully implemented */
1004 static void CalcWindowPosition(Object
*obj
, struct MUI_WindowData
*data
)
1006 data
->wd_XStore
= data
->wd_X
;
1007 data
->wd_YStore
= data
->wd_Y
;
1008 if (NULL
== data
->wd_RefWindow
)
1010 /* The following calculations are not very correct, the size and
1011 * dragbar are ignored also the current overscan view */
1012 if (data
->wd_X
== MUIV_Window_LeftEdge_Centered
)
1015 (data
->wd_RenderInfo
.mri_Screen
->ViewPort
.DWidth
-
1016 data
->wd_Width
) / 2 -
1017 data
->wd_RenderInfo
.mri_Screen
->LeftEdge
;
1019 else if (data
->wd_X
== MUIV_Window_LeftEdge_Moused
)
1021 data
->wd_X
= data
->wd_RenderInfo
.mri_Screen
->MouseX
;
1024 if (data
->wd_Y
== MUIV_Window_TopEdge_Centered
)
1027 (data
->wd_RenderInfo
.mri_Screen
->ViewPort
.DHeight
-
1028 data
->wd_Height
) / 2 -
1029 data
->wd_RenderInfo
.mri_Screen
->TopEdge
;
1031 else if (data
->wd_Y
== MUIV_Window_TopEdge_Moused
)
1033 data
->wd_Y
= data
->wd_RenderInfo
.mri_Screen
->MouseY
;
1035 else if (data
->wd_Y
<= MUIV_Window_TopEdge_Delta(0))
1037 data
->wd_Y
= data
->wd_RenderInfo
.mri_Screen
->BarHeight
+ 1
1038 + MUIV_Window_TopEdge_Delta(0) - data
->wd_Y
;
1046 get(data
->wd_RefWindow
, MUIA_Window_Width
, &w
);
1047 get(data
->wd_RefWindow
, MUIA_Window_LeftEdge
, &x
);
1049 if (data
->wd_X
== MUIV_Window_LeftEdge_Centered
)
1051 data
->wd_X
= x
+ (w
- data
->wd_Width
) / 2;
1058 get(data
->wd_RefWindow
, MUIA_Window_Height
, &h
);
1059 get(data
->wd_RefWindow
, MUIA_Window_TopEdge
, &y
);
1061 if (data
->wd_Y
== MUIV_Window_TopEdge_Centered
)
1063 /* D(bug("y=%ld, h=%ld, wdh=%ld\n", y, h, data->wd_Height)); */
1064 data
->wd_Y
= y
+ (h
- data
->wd_Height
) / 2;
1066 else if (data
->wd_Y
<= MUIV_Window_TopEdge_Delta(0))
1068 /* ??? surely incorrect implementation */
1069 data
->wd_Y
= y
+ 1 + MUIV_Window_TopEdge_Delta(0) - data
->wd_Y
;
1078 /* Initialize data->wd_AltDim for DisplayWindow */
1079 static void CalcAltDimensions(Object
*obj
, struct MUI_WindowData
*data
)
1081 /* Calculate alternate (zoomed) dimensions.
1083 if (data
->wd_AltDim
.Top
== MUIV_Window_AltTopEdge_NoChange
)
1084 data
->wd_AltDim
.Top
= ~0;
1085 else if (data
->wd_AltDim
.Top
== MUIV_Window_AltTopEdge_Centered
)
1086 data
->wd_AltDim
.Top
=
1087 (data
->wd_RenderInfo
.mri_Screen
->Height
- data
->wd_Height
) / 2;
1088 else if (data
->wd_AltDim
.Top
== MUIV_Window_AltTopEdge_Moused
)
1089 /* ? */ data
->wd_AltDim
.Top
= ~0;
1091 if (data
->wd_AltDim
.Left
== MUIV_Window_AltLeftEdge_NoChange
)
1092 data
->wd_AltDim
.Left
= ~0;
1093 else if (data
->wd_AltDim
.Left
== MUIV_Window_AltLeftEdge_Centered
)
1094 data
->wd_AltDim
.Left
=
1095 (data
->wd_RenderInfo
.mri_Screen
->Width
- data
->wd_Width
) / 2;
1096 else if (data
->wd_AltDim
.Left
== MUIV_Window_AltLeftEdge_Moused
)
1097 /* ? */ data
->wd_AltDim
.Left
= ~0;
1100 (MUIV_Window_AltWidth_MinMax(100),
1101 data
->wd_AltDim
.Width
, MUIV_Window_AltWidth_MinMax(0)))
1103 data
->wd_AltDim
.Width
= data
->wd_MinMax
.MinWidth
1104 - data
->wd_AltDim
.Width
1105 * (data
->wd_MinMax
.MaxWidth
- data
->wd_MinMax
.MinWidth
);
1109 (MUIV_Window_AltWidth_Screen(100),
1110 data
->wd_AltDim
.Width
, MUIV_Window_AltWidth_Screen(0)))
1112 data
->wd_AltDim
.Width
= data
->wd_RenderInfo
.mri_ScreenWidth
1113 * (-(data
->wd_AltDim
.Width
+ 200)) / 100;
1117 (MUIV_Window_AltWidth_Visible(100),
1118 data
->wd_AltDim
.Width
, MUIV_Window_AltWidth_Visible(0)))
1120 data
->wd_AltDim
.Width
= data
->wd_RenderInfo
.mri_ScreenWidth
1121 * (-(data
->wd_AltDim
.Width
+ 100)) / 100;
1125 (MUIV_Window_AltHeight_MinMax(100),
1126 data
->wd_AltDim
.Height
, MUIV_Window_AltHeight_MinMax(0)))
1128 data
->wd_AltDim
.Height
= data
->wd_MinMax
.MinHeight
1129 - data
->wd_AltDim
.Height
1130 * (data
->wd_MinMax
.MaxHeight
- data
->wd_MinMax
.MinHeight
);
1134 (MUIV_Window_AltHeight_Screen(100),
1135 data
->wd_AltDim
.Height
, MUIV_Window_AltHeight_Screen(0)))
1137 data
->wd_AltDim
.Height
= data
->wd_RenderInfo
.mri_ScreenHeight
1138 * (-(data
->wd_AltDim
.Height
+ 200)) / 100;
1142 (MUIV_Window_AltHeight_Visible(100),
1143 data
->wd_AltDim
.Height
, MUIV_Window_AltHeight_Visible(0)))
1145 data
->wd_AltDim
.Height
= data
->wd_RenderInfo
.mri_ScreenHeight
1146 * (-(data
->wd_AltDim
.Height
+ 100)) / 100;
1149 data
->wd_AltDim
.Width
= CLAMP
1150 (data
->wd_AltDim
.Width
, data
->wd_MinMax
.MinWidth
,
1151 data
->wd_MinMax
.MaxWidth
);
1152 data
->wd_AltDim
.Height
= CLAMP
1153 (data
->wd_AltDim
.Height
, data
->wd_MinMax
.MinHeight
,
1154 data
->wd_MinMax
.MaxHeight
);
1158 /* Create horiz/vert window scrollbars for DisplayWindow */
1159 static void CreateWindowScrollbars(Object
*obj
,
1160 struct MUI_WindowData
*data
)
1162 struct MUI_RenderInfo
*mri
= &data
->wd_RenderInfo
;
1163 Object
*firstgad
= NULL
;
1164 Object
*prevgad
= NULL
;
1167 /* Create the right border scrollers now if requested */
1168 if (data
->wd_Flags
& MUIWF_USERIGHTSCROLLER
)
1172 voffset
= IM(mri
->mri_DownImage
)->Width
/ 4;
1174 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1175 firstgad
= prevgad
= data
->wd_VertProp
= NewObject
1176 (NULL
, "propgclass",
1177 GA_RelRight
, 1 - (IM(mri
->mri_UpImage
)->Width
- voffset
),
1178 GA_Top
, mri
->mri_BorderTop
+ 2,
1179 GA_Width
, IM(mri
->mri_UpImage
)->Width
- voffset
* 2,
1180 GA_RelHeight
, -(mri
->mri_BorderTop
+ 2)
1181 - IM(mri
->mri_UpImage
)->Height
1182 - IM(mri
->mri_DownImage
)->Height
1183 - IM(mri
->mri_SizeImage
)->Height
- 2,
1184 GA_RightBorder
, TRUE
,
1186 PGA_Borderless
, TRUE
,
1188 PGA_Freedom
, FREEVERT
,
1191 PGA_Visible
, 1, ICA_TARGET
, ICTARGET_IDCMP
, TAG_DONE
);
1193 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1194 prevgad
= data
->wd_UpButton
= NewObject
1195 (NULL
, "buttongclass",
1196 GA_Image
, (IPTR
) mri
->mri_UpImage
,
1197 GA_RelRight
, 1 - IM(mri
->mri_UpImage
)->Width
,
1198 GA_RelBottom
, 1 - IM(mri
->mri_UpImage
)->Height
1199 - IM(mri
->mri_DownImage
)->Height
1200 - IM(mri
->mri_SizeImage
)->Height
,
1201 GA_RightBorder
, TRUE
,
1202 GA_Previous
, (IPTR
) prevgad
,
1203 GA_ID
, id
, ICA_TARGET
, ICTARGET_IDCMP
, TAG_DONE
);
1205 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1206 prevgad
= data
->wd_DownButton
= NewObject
1207 (NULL
, "buttongclass",
1208 GA_Image
, (IPTR
) mri
->mri_DownImage
,
1209 GA_RelRight
, 1 - IM(mri
->mri_DownImage
)->Width
,
1210 GA_RelBottom
, 1 - IM(mri
->mri_DownImage
)->Height
1211 - IM(mri
->mri_SizeImage
)->Height
,
1212 GA_RightBorder
, TRUE
,
1213 GA_Previous
, (IPTR
) prevgad
,
1214 GA_ID
, id
, ICA_TARGET
, ICTARGET_IDCMP
, TAG_DONE
);
1217 /* Create the bottom border scrollers now if requested */
1218 if (data
->wd_Flags
& MUIWF_USEBOTTOMSCROLLER
)
1222 hoffset
= IM(mri
->mri_RightImage
)->Height
/ 4;
1224 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1225 prevgad
= data
->wd_HorizProp
= NewObject
1226 (NULL
, "propgclass",
1227 GA_RelBottom
, 1 - (IM(mri
->mri_LeftImage
)->Height
- hoffset
),
1228 GA_Left
, mri
->mri_BorderLeft
,
1229 GA_Height
, IM(mri
->mri_LeftImage
)->Height
1231 GA_RelWidth
, -(mri
->mri_BorderLeft
)
1232 - IM(mri
->mri_LeftImage
)->Width
1233 - IM(mri
->mri_RightImage
)->Width
1234 - IM(mri
->mri_SizeImage
)->Width
1236 GA_BottomBorder
, TRUE
,
1238 prevgad
? GA_Previous
: TAG_IGNORE
, (IPTR
) prevgad
,
1239 PGA_Borderless
, TRUE
,
1241 PGA_Freedom
, FREEHORIZ
,
1244 PGA_Visible
, 1, ICA_TARGET
, ICTARGET_IDCMP
, TAG_DONE
);
1249 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1250 prevgad
= data
->wd_LeftButton
= NewObject
1251 (NULL
, "buttongclass",
1252 GA_Image
, (IPTR
) mri
->mri_LeftImage
,
1253 GA_RelRight
, 1 - IM(mri
->mri_LeftImage
)->Width
1254 - IM(mri
->mri_RightImage
)->Width
1255 - IM(mri
->mri_SizeImage
)->Width
,
1256 GA_RelBottom
, 1 - IM(mri
->mri_LeftImage
)->Height
,
1257 GA_BottomBorder
, TRUE
,
1258 GA_Previous
, (IPTR
) prevgad
,
1259 GA_ID
, id
, ICA_TARGET
, ICTARGET_IDCMP
, TAG_DONE
);
1261 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1262 prevgad
= data
->wd_RightButton
= NewObject
1263 (NULL
, "buttongclass",
1264 GA_Image
, (IPTR
) mri
->mri_RightImage
,
1265 GA_RelRight
, 1 - IM(mri
->mri_RightImage
)->Width
1266 - IM(mri
->mri_SizeImage
)->Width
,
1267 GA_RelBottom
, 1 - IM(mri
->mri_RightImage
)->Height
,
1268 GA_BottomBorder
, TRUE
,
1269 GA_Previous
, (IPTR
) prevgad
,
1270 GA_ID
, id
, ICA_TARGET
, ICTARGET_IDCMP
, TAG_DONE
);
1274 /* return FALSE only if no resize (dx=dy=0) occured */
1275 static BOOL
WindowResize(struct MUI_WindowData
*data
)
1277 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
1278 int hborders
= win
->BorderLeft
+ win
->BorderRight
;
1279 int vborders
= win
->BorderTop
+ win
->BorderBottom
;
1280 WORD dx
= data
->wd_Width
- win
->Width
+ hborders
;
1281 WORD dy
= data
->wd_Height
- win
->Height
+ vborders
;
1283 /* Temporarily disable window limits to let SizeWindow below work
1284 regardless of the previous limits */
1285 WindowLimits(win
, 1, 1, -1, -1);
1286 /* D(bug("_zune_window_resize : dx=%d, dy=%d\n", dx, dy)); */
1287 SizeWindow(win
, dx
, dy
);
1289 /* Set new window limits */
1291 (win
, data
->wd_MinMax
.MinWidth
+ hborders
,
1292 data
->wd_MinMax
.MinHeight
+ vborders
,
1293 data
->wd_MinMax
.MaxWidth
+ hborders
,
1294 data
->wd_MinMax
.MaxHeight
+ vborders
);
1299 static void KillHelpBubble(struct MUI_WindowData
*data
, Object
*obj
,
1300 BOOL kill_bubblemode
)
1302 if (data
->wd_HelpObject
)
1304 DoMethod(data
->wd_HelpObject
, MUIM_DeleteBubble
,
1305 (IPTR
) data
->wd_HelpBubble
);
1306 data
->wd_HelpObject
= NULL
;
1307 data
->wd_HelpBubble
= NULL
;
1310 if (kill_bubblemode
)
1311 data
->wd_Flags
&= ~MUIWF_BUBBLEMODE
;
1313 if (data
->wd_Flags
& MUIWF_BUBBLEMODE
)
1315 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_LATER
;
1319 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_FIRST
;
1326 typedef BOOL(*UNDERCHECK_FUNC
) (Object
*obj
);
1328 static BOOL
ShortHelpUnderPointerCheck(Object
*obj
)
1330 return muiAreaData(obj
)->mad_ShortHelp
? TRUE
: FALSE
;
1333 static Object
*ObjectUnderPointer(struct MUI_WindowData
*data
, Object
*obj
,
1334 LONG x
, LONG y
, UNDERCHECK_FUNC func
)
1338 struct MinList
*ChildList
= NULL
;
1340 if (!(muiAreaData(obj
)->mad_Flags
& MADF_CANDRAW
))
1343 if (!(x
>= _left(obj
) && x
<= _right(obj
)
1344 && y
>= _top(obj
) && y
<= _bottom(obj
)))
1349 if ((get(obj
, MUIA_Group_ChildList
, &(ChildList
)))
1350 && (ChildList
!= NULL
))
1352 cstate
= (Object
*) ChildList
->mlh_Head
;
1353 while ((child
= NextObject(&cstate
)))
1357 if ((x
>= _left(child
) && x
<= _right(child
)
1359 y
>= _top(child
) && y
<= _bottom(child
))
1360 && (ret
= ObjectUnderPointer(data
, child
, x
, y
, func
)))
1373 static BOOL
ContextMenuUnderPointer(struct MUI_WindowData
*data
,
1374 Object
*obj
, LONG x
, LONG y
)
1378 struct MinList
*ChildList
= NULL
;
1380 if (!(x
>= _left(obj
) && x
<= _right(obj
)
1381 && y
>= _top(obj
) && y
<= _bottom(obj
)))
1386 if ((get(obj
, MUIA_Group_ChildList
, &(ChildList
)))
1387 && (ChildList
!= NULL
))
1390 cstate
= (Object
*) ChildList
->mlh_Head
;
1391 while ((child
= NextObject(&cstate
)))
1393 if ((x
>= _left(child
) && x
<= _right(child
)
1395 y
>= _top(child
) && y
<= _bottom(child
))
1396 && (ContextMenuUnderPointer(data
, child
, x
, y
)))
1401 if (!(muiAreaData(obj
)->mad_Flags
& MADF_CANDRAW
))
1403 if (!(muiAreaData(obj
)->mad_ContextMenu
))
1411 static void ActivateObject(struct MUI_WindowData
*data
)
1413 //bug("Window::ActivateObject (dummy) %08lx\n", data->wd_ActiveObject);
1414 // if (FindObjNode(&data->wd_CycleChain, data->wd_ActiveObject))
1415 // DoMethod(data->wd_ActiveObject, MUIM_GoActive);
1417 // data->wd_ActiveObject = NULL;
1419 //activate better string gadgets.Fix from Georg S On ML List
1420 if (FindObjNode(&data
->wd_CycleChain
, data
->wd_ActiveObject
))
1422 if (!(data
->wd_Flags
& MUIWF_OBJECTGOACTIVESENT
))
1424 data
->wd_Flags
|= MUIWF_OBJECTGOACTIVESENT
;
1425 DoMethod(data
->wd_ActiveObject
, MUIM_GoActive
);
1429 data
->wd_ActiveObject
= NULL
;
1434 /* handle intuimessage while an object is being dragged
1435 * (reply imsg before returning)
1436 * Returns TRUE if finished dragging.
1438 static BOOL
HandleDragging(Object
*oWin
, struct MUI_WindowData
*data
,
1439 struct IntuiMessage
*imsg
)
1441 struct Window
*iWin
;
1442 BOOL finish_drag
= FALSE
;
1444 iWin
= imsg
->IDCMPWindow
;
1446 if (imsg
->Class
== IDCMP_MOUSEMOVE
)
1448 struct Layer
*layer
;
1450 LockLayerInfo(&iWin
->WScreen
->LayerInfo
);
1451 layer
= WhichLayer(&iWin
->WScreen
->LayerInfo
,
1452 iWin
->LeftEdge
+ imsg
->MouseX
, iWin
->TopEdge
+ imsg
->MouseY
);
1453 UnlockLayerInfo(&iWin
->WScreen
->LayerInfo
);
1455 if (data
->wd_DropObject
)
1459 imsg
->MouseX
+ iWin
->LeftEdge
-
1460 data
->wd_DropWindow
->LeftEdge
;
1462 imsg
->MouseY
+ iWin
->TopEdge
- data
->wd_DropWindow
->TopEdge
;
1464 wnd
= _window(data
->wd_DropObject
);
1465 if (mousex
< _left(data
->wd_DropObject
)
1466 || mousex
> _right(data
->wd_DropObject
)
1467 || mousey
< _top(data
->wd_DropObject
)
1468 || mousey
> _bottom(data
->wd_DropObject
)
1469 || layer
!= wnd
->WLayer
)
1471 /* We have left the object */
1472 UndrawDragNDrop(data
->wd_dnd
);
1473 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
,
1474 (IPTR
) data
->wd_DragObject
);
1475 data
->wd_DropObject
= NULL
;
1477 } /* if (data->wd_DropObject) */
1479 if (!data
->wd_DropObject
)
1481 Object
*dest_wnd
= NULL
;
1483 /* Find out if app has an open window at this position */
1488 struct MinList
*ChildList
= 0;
1490 get(_app(oWin
), MUIA_Application_WindowList
, &(ChildList
));
1491 cstate
= (Object
*) ChildList
->mlh_Head
;
1492 while ((child
= NextObject(&cstate
)))
1494 struct Window
*wnd
= NULL
;
1495 get(child
, MUIA_Window_Window
, &wnd
);
1499 if (wnd
->WLayer
== layer
)
1501 data
->wd_DropWindow
= wnd
;
1510 Object
*root
= NULL
;
1511 get(dest_wnd
, MUIA_Window_RootObject
, &root
);
1515 if ((data
->wd_DropObject
= (Object
*) DoMethod
1516 (root
, MUIM_DragQueryExtended
,
1517 (IPTR
) data
->wd_DragObject
,
1518 imsg
->MouseX
+ iWin
->LeftEdge
-
1519 data
->wd_DropWindow
->LeftEdge
,
1520 imsg
->MouseY
+ iWin
->TopEdge
-
1521 data
->wd_DropWindow
->TopEdge
)))
1523 UndrawDragNDrop(data
->wd_dnd
);
1524 DoMethod(data
->wd_DropObject
, MUIM_DragBegin
,
1525 (IPTR
) data
->wd_DragObject
);
1531 if (data
->wd_DropObject
)
1535 for (i
= 0; i
< 2; i
++)
1537 LONG res
= DoMethod(data
->wd_DropObject
, MUIM_DragReport
,
1538 (IPTR
) data
->wd_DragObject
,
1539 imsg
->MouseX
+ iWin
->LeftEdge
-
1540 data
->wd_DropWindow
->LeftEdge
,
1541 imsg
->MouseY
+ iWin
->TopEdge
-
1542 data
->wd_DropWindow
->TopEdge
, update
);
1545 case MUIV_DragReport_Abort
:
1546 UndrawDragNDrop(data
->wd_dnd
);
1547 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
,
1548 (IPTR
) data
->wd_DragObject
);
1549 data
->wd_DropObject
= NULL
;
1553 case MUIV_DragReport_Continue
:
1555 case MUIV_DragReport_Lock
:
1557 case MUIV_DragReport_Refresh
:
1558 UndrawDragNDrop(data
->wd_dnd
);
1564 DrawDragNDrop(data
->wd_dnd
, imsg
->MouseX
+ iWin
->LeftEdge
,
1565 imsg
->MouseY
+ iWin
->TopEdge
);
1568 if (imsg
->Class
== IDCMP_MOUSEBUTTONS
)
1570 if ((imsg
->Code
== MENUDOWN
) || (imsg
->Code
== SELECTUP
))
1572 UndrawDragNDrop(data
->wd_dnd
);
1573 if (imsg
->Code
== SELECTUP
&& data
->wd_DropObject
)
1575 DoMethod(data
->wd_DropObject
, MUIM_DragDrop
,
1576 (IPTR
) data
->wd_DragObject
,
1577 imsg
->MouseX
+ iWin
->LeftEdge
-
1578 data
->wd_DropWindow
->LeftEdge
,
1579 imsg
->MouseY
+ iWin
->TopEdge
-
1580 data
->wd_DropWindow
->TopEdge
);
1581 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
,
1582 (IPTR
) data
->wd_DragObject
);
1583 data
->wd_DropObject
= NULL
;
1585 else if (imsg
->Code
== SELECTUP
)
1587 DoMethod(data
->wd_DragObject
, MUIM_UnknownDropDestination
,
1594 if (imsg
->Class
== IDCMP_CLOSEWINDOW
)
1599 if (data
->wd_DropObject
)
1601 UndrawDragNDrop(data
->wd_dnd
);
1602 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
,
1603 (IPTR
) data
->wd_DragObject
);
1604 data
->wd_DropObject
= NULL
;
1606 DeleteDragNDrop(data
->wd_dnd
);
1607 DoMethod(data
->wd_DragObject
, MUIM_DeleteDragImage
,
1608 (IPTR
) data
->wd_DragImage
);
1609 muiAreaData(data
->wd_DragObject
)->mad_Flags
&= ~MADF_DRAGGING
;
1610 data
->wd_DragImage
= NULL
;
1611 data
->wd_DragObject
= NULL
;
1612 data
->wd_DropWindow
= NULL
;
1613 data
->wd_dnd
= NULL
;
1615 /* stop listening to IDCMP_MOUSEMOVE */
1616 ChangeEvents(data
, GetDefaultEvents());
1619 ReplyMsg((struct Message
*)imsg
);
1624 /* Reply to imsg if handled */
1625 BOOL
HandleWindowEvent(Object
*oWin
, struct MUI_WindowData
*data
,
1626 struct IntuiMessage
*imsg
)
1628 struct Window
*iWin
;
1629 BOOL is_handled
= TRUE
;
1630 BOOL replied
= FALSE
;
1632 iWin
= imsg
->IDCMPWindow
;
1633 switch (imsg
->Class
)
1635 case IDCMP_ACTIVEWINDOW
:
1636 data
->wd_Flags
|= MUIWF_ACTIVE
;
1637 if (data
->wd_OldActive
)
1638 set(oWin
, MUIA_Window_ActiveObject
, data
->wd_OldActive
);
1639 set(oWin
, MUIA_Window_Activate
, TRUE
);
1640 is_handled
= FALSE
; /* forwardable to area event handlers */
1643 case IDCMP_INACTIVEWINDOW
:
1644 KillHelpBubble(data
, oWin
, TRUE
);
1645 if (data
->wd_ActiveObject
)
1647 data
->wd_OldActive
= data
->wd_ActiveObject
;
1648 set(oWin
, MUIA_Window_ActiveObject
,
1649 MUIV_Window_ActiveObject_None
);
1651 data
->wd_Flags
&= ~MUIWF_ACTIVE
;
1652 set(oWin
, MUIA_Window_Activate
, FALSE
);
1653 is_handled
= FALSE
; /* forwardable to area event handlers */
1657 case IDCMP_CHANGEWINDOW
:
1659 int hborders
= iWin
->BorderLeft
+ iWin
->BorderRight
;
1660 int vborders
= iWin
->BorderTop
+ iWin
->BorderBottom
;
1662 /* set window limits according to window contents */
1665 data
->wd_MinMax
.MinWidth
+ hborders
,
1666 data
->wd_MinMax
.MinHeight
+ vborders
,
1667 data
->wd_MinMax
.MaxWidth
+ hborders
,
1668 data
->wd_MinMax
.MaxHeight
+ vborders
);
1671 if ((iWin
->GZZWidth
!= data
->wd_Width
)
1672 || (iWin
->GZZHeight
!= data
->wd_Height
))
1674 data
->wd_Width
= iWin
->GZZWidth
;
1675 data
->wd_Height
= iWin
->GZZHeight
;
1676 DoHideMethod(data
->wd_RootObject
);
1678 data
->wd_Flags
|= MUIWF_RESIZING
;
1679 RefreshWindow(oWin
, data
);
1681 /* Use wd_Class below instead of OCLASS(oWin), because otherwise if oWin is an
1682 instance of a subclass of window class, then superset will go to window class's
1683 OM_SET where MUIA_window_Width|Height for some reason are always set to 0. This has
1684 the side effect that after the first window resize all future window moves(!) too
1685 are interpreted as "window size was changed" (if check above returns TRUE even if
1686 window size did not change) */
1687 superset(data
->wd_Class
, oWin
, MUIA_Window_Width
, data
->wd_Width
);
1688 superset(data
->wd_Class
, oWin
, MUIA_Window_Height
, data
->wd_Height
);
1691 if (iWin
->LeftEdge
!= data
->wd_X
)
1693 data
->wd_X
= iWin
->LeftEdge
;
1694 superset(data
->wd_Class
, oWin
, MUIA_Window_LeftEdge
, data
->wd_X
);
1696 if (iWin
->TopEdge
!= data
->wd_Y
)
1698 data
->wd_Y
= iWin
->TopEdge
;
1699 superset(data
->wd_Class
, oWin
, MUIA_Window_TopEdge
, data
->wd_Y
);
1702 is_handled
= FALSE
; /* forwardable to area event handlers */
1705 case IDCMP_REFRESHWINDOW
:
1706 ReplyMsg((struct Message
*)imsg
);
1708 RefreshWindow(oWin
, data
);
1711 case IDCMP_CLOSEWINDOW
:
1712 ReplyMsg((struct Message
*)imsg
);
1714 set(oWin
, MUIA_Window_CloseRequest
, TRUE
);
1717 case IDCMP_MENUPICK
:
1718 ReplyMsg((struct Message
*)imsg
);
1723 if (MENUNUM(imsg
->Code
) != NOMENU
1724 && ITEMNUM(imsg
->Code
) != NOITEM
)
1726 struct MenuItem
*item
=
1727 ItemAddress(data
->wd_Menu
, imsg
->Code
);
1730 Object
*item_obj
= (Object
*) GTMENUITEM_USERDATA(item
);
1736 if (item
->Flags
& CHECKIT
)
1737 set(item_obj
, MUIA_Menuitem_Checked
,
1738 ! !(item
->Flags
& CHECKED
));
1740 set(item_obj
, MUIA_Menuitem_Trigger
, (IPTR
) item
);
1742 get(oWin
, MUIA_ApplicationObject
, &app
);
1743 get(item_obj
, MUIA_UserData
, &udata
);
1745 set(app
, MUIA_Application_MenuAction
, udata
);
1746 set(oWin
, MUIA_Window_MenuAction
, udata
);
1747 DoMethod(app
, MUIM_Application_ReturnID
, udata
);
1754 case IDCMP_IDCMPUPDATE
:
1755 is_handled
= FALSE
; /* forwardable to area event handlers */
1756 if (data
->wd_VertProp
|| data
->wd_HorizProp
)
1758 struct TagItem
*tag
;
1759 tag
= FindTagItem(GA_ID
, (struct TagItem
*)imsg
->IAddress
);
1762 /* If there's a propclass object connected to the prop
1763 gadget, the prop gadget's userdata will point to
1764 that propclass object. See classes/prop.c */
1766 if (data
->wd_VertProp
)
1768 if (tag
->ti_Data
== GADGETID(data
->wd_VertProp
))
1771 if (tag
->ti_Data
== GADGETID(data
->wd_UpButton
))
1774 (Object
*) ((struct Gadget
*)data
->
1775 wd_VertProp
)->UserData
;
1778 DoMethod(prop
, MUIM_Prop_Decrease
, 1);
1781 if (tag
->ti_Data
== GADGETID(data
->wd_DownButton
))
1784 (Object
*) ((struct Gadget
*)data
->
1785 wd_VertProp
)->UserData
;
1788 DoMethod(prop
, MUIM_Prop_Increase
, 1);
1793 if (data
->wd_HorizProp
)
1795 if (tag
->ti_Data
== GADGETID(data
->wd_HorizProp
))
1798 if (tag
->ti_Data
== GADGETID(data
->wd_LeftButton
))
1801 (Object
*) ((struct Gadget
*)data
->
1802 wd_HorizProp
)->UserData
;
1805 DoMethod(prop
, MUIM_Prop_Decrease
, 1);
1808 if (tag
->ti_Data
== GADGETID(data
->wd_RightButton
))
1811 (Object
*) ((struct Gadget
*)data
->
1812 wd_HorizProp
)->UserData
;
1815 DoMethod(prop
, MUIM_Prop_Increase
, 1);
1823 case IDCMP_INTUITICKS
:
1824 if (data
->wd_HelpTicker
)
1826 data
->wd_HelpTicker
--;
1828 if (data
->wd_HelpTicker
== 0)
1831 ObjectUnderPointer(data
, data
->wd_RootObject
,
1832 imsg
->MouseX
, imsg
->MouseY
,
1833 ShortHelpUnderPointerCheck
);
1835 if (underobj
!= data
->wd_HelpObject
)
1837 if (data
->wd_HelpObject
)
1839 DoMethod(data
->wd_HelpObject
, MUIM_DeleteBubble
,
1840 (IPTR
) data
->wd_HelpBubble
);
1842 data
->wd_HelpObject
= NULL
;
1843 data
->wd_HelpBubble
= NULL
;
1848 data
->wd_HelpBubble
=
1849 (APTR
) DoMethod(underobj
, MUIM_CreateBubble
,
1850 imsg
->MouseX
, imsg
->MouseY
, 0, 0);
1851 if (data
->wd_HelpBubble
)
1853 data
->wd_HelpObject
= underobj
;
1854 data
->wd_Flags
|= MUIWF_BUBBLEMODE
;
1859 if (data
->wd_Flags
& MUIWF_BUBBLEMODE
)
1861 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_LATER
;
1865 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_FIRST
;
1870 is_handled
= FALSE
; /* forwardable to area event handlers */
1873 case IDCMP_MOUSEBUTTONS
:
1874 DoMethod(oWin
, MUIM_Window_Snapshot
, 0);
1875 KillHelpBubble(data
, oWin
, TRUE
);
1880 case IDCMP_MOUSEMOVE
:
1881 KillHelpBubble(data
, oWin
, FALSE
);
1890 if (is_handled
&& !replied
)
1891 ReplyMsg((struct Message
*)imsg
);
1896 static ULONG
InvokeEventHandler(struct MUI_EventHandlerNode
*ehn
,
1897 struct IntuiMessage
*event
, ULONG muikey
)
1901 if (!(_flags(ehn
->ehn_Object
) & MADF_CANDRAW
))
1903 if (!(_flags(ehn
->ehn_Object
) & MADF_SHOWME
))
1907 && event
->Class
== IDCMP_MOUSEBUTTONS
1908 && event
->Code
== SELECTDOWN
1909 && (_flags(ehn
->ehn_Object
) & MADF_INVIRTUALGROUP
))
1912 Here we filter out SELECTDOWN messages if objects is in a virtual
1913 group but the click went out of the virtual group
1915 Object
*obj
= ehn
->ehn_Object
;
1916 Object
*parent
= obj
;
1917 Object
*wnd
= _win(obj
);
1919 while (get(parent
, MUIA_Parent
, &parent
))
1925 if (_flags(parent
) & MADF_ISVIRTUALGROUP
)
1927 if (event
->MouseX
< _mleft(parent
)
1928 || event
->MouseX
> _mright(parent
)
1929 || event
->MouseY
< _mtop(parent
)
1930 || event
->MouseY
> _mbottom(parent
))
1939 if (ehn
->ehn_Flags
& MUI_EHF_HANDLEINPUT
)
1941 DoMethod(ehn
->ehn_Object
, MUIM_HandleInput
, (IPTR
) event
, muikey
);
1948 (ehn
->ehn_Class
, ehn
->ehn_Object
, MUIM_HandleEvent
,
1949 (IPTR
) event
, muikey
);
1952 DoMethod(ehn
->ehn_Object
, MUIM_HandleEvent
, (IPTR
) event
,
1959 static void HandleRawkey(Object
*win
, struct MUI_WindowData
*data
,
1960 struct IntuiMessage
*event
)
1963 struct MUI_EventHandlerNode
*ehn
;
1964 struct IntuiMessage imsg_copy
;
1965 struct InputEvent ie
= { 0 };
1967 LONG muikey
= MUIKEY_NONE
;
1968 Object
*active_object
= NULL
;
1973 KillHelpBubble(data
, win
, BUBBLEHELP_TICKER_FIRST
);
1975 ie
.ie_NextEvent
= NULL
;
1976 ie
.ie_Class
= IECLASS_RAWKEY
;
1978 ie
.ie_Code
= event
->Code
;
1979 ie
.ie_Qualifier
= event
->Qualifier
;
1980 ie
.ie_EventAddress
= (APTR
) * (IPTR
*) event
->IAddress
;
1982 ie
.ie_TimeStamp
.Seconds
= event
->Seconds
;
1983 ie
.ie_TimeStamp
.Microseconds
= event
->Micros
;
1985 ie
.ie_TimeStamp
.tv_secs
= event
->Seconds
;
1986 ie
.ie_TimeStamp
.tv_micro
= event
->Micros
;
1989 set(win
, MUIA_Window_InputEvent
, (IPTR
) & ie
);
1991 /* get the vanilla key for control char */
1995 /* Remove the up prefix as convert key does not convert upkey event */
1996 msg_code
= event
->Code
;
1997 event
->Code
&= ~IECODE_UP_PREFIX
;
1998 key
= ConvertKey(event
);
1999 event
->Code
= msg_code
;
2003 deadkey
= *(ULONG
*) event
->IAddress
;
2004 imsg_copy
.IAddress
= &deadkey
;
2005 ReplyMsg((struct Message
*)event
);
2008 //bug("rawkey: code=%lx, qual=%lx\n", event->Code, event->Qualifier);
2010 /* check if imsg translates to predefined keystroke */
2012 struct InputEvent ievent
;
2013 BOOL matched
= FALSE
;
2015 ievent
.ie_NextEvent
= NULL
;
2016 ievent
.ie_Class
= IECLASS_RAWKEY
;
2017 ievent
.ie_SubClass
= 0;
2018 ievent
.ie_Code
= event
->Code
;
2019 ievent
.ie_Qualifier
= event
->Qualifier
;
2020 /* ie_EventAddress is not used by MatchIX. If needed, it should be
2021 * ensured that it is still a valid address because of the shallow
2022 * IntuiMessage copy currently done in _zune_window_message before
2023 * message is replied.
2025 ievent
.ie_EventAddress
= NULL
;
2026 //ievent.ie_EventAddress = (APTR *) *((ULONG *)(event->IAddress));
2028 for (muikey
= MUIKEY_COUNT
- 1; muikey
>= MUIKEY_PRESS
; muikey
--)
2030 if (muiGlobalInfo(win
)->mgi_Prefs
->muikeys
[muikey
].ix_well
!= 0
2032 &muiGlobalInfo(win
)->mgi_Prefs
->muikeys
[muikey
].ix
))
2041 if (muikey
== MUIKEY_PRESS
&& (event
->Code
& IECODE_UP_PREFIX
))
2042 muikey
= MUIKEY_RELEASE
;
2046 muikey
= MUIKEY_NONE
;
2048 } /* check if imsg translate to predefined keystroke */
2050 if ((muikey
!= MUIKEY_NONE
) && !(data
->wd_DisabledKeys
& (1 << muikey
)))
2052 D(bug("HandleRawkey: try MUIKEY %ld on window %0x08lx\n", muikey
,
2066 case MUIKEY_PAGEDOWN
:
2076 case MUIKEY_WORDLEFT
:
2078 case MUIKEY_WORDRIGHT
:
2080 case MUIKEY_LINESTART
:
2082 case MUIKEY_LINEEND
:
2084 case MUIKEY_GADGET_NEXT
:
2085 set(win
, MUIA_Window_ActiveObject
,
2086 MUIV_Window_ActiveObject_Next
);
2088 case MUIKEY_GADGET_PREV
:
2089 set(win
, MUIA_Window_ActiveObject
,
2090 MUIV_Window_ActiveObject_Prev
);
2092 case MUIKEY_GADGET_OFF
:
2093 set(win
, MUIA_Window_ActiveObject
,
2094 MUIV_Window_ActiveObject_None
);
2096 case MUIKEY_WINDOW_CLOSE
:
2097 set(win
, MUIA_Window_CloseRequest
, TRUE
);
2099 case MUIKEY_WINDOW_NEXT
:
2101 case MUIKEY_WINDOW_PREV
:
2112 active_object
= NULL
;
2113 if ((data
->wd_ActiveObject
!= NULL
)
2114 && (DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
2115 (IPTR
) data
->wd_ActiveObject
) != (IPTR
) NULL
))
2117 active_object
= data
->wd_ActiveObject
;
2118 get(active_object
, MUIA_Disabled
, &disabled
);
2121 data
->wd_ActiveObject
= NULL
;
2123 /* try ActiveObject */
2124 if ((active_object
!= NULL
) && !disabled
)
2128 ** Which method should be used for muikeys? MUIM_HandleInput or
2129 ** MUIM_HandleEvent. Also note that there is a flag MUI_EHF_ALWAYSKEYS
2130 ** which probably means that all keys events are requested??
2131 ** For now MUIM_HandleEvent is used as this is currently implemented
2132 ** in Area class ;) although I guess it should be MUIM_HandleInput as
2136 if (muikey
!= MUIKEY_NONE
)
2139 DoMethod(active_object
, MUIM_HandleEvent
, (IPTR
) event
,
2141 if (res
& MUI_EventHandlerRC_Eat
)
2145 D(bug("HandleRawkey: try active object (%08lx) handlers\n",
2148 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2150 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2152 if ((ehn
->ehn_Object
== active_object
)
2153 && ((ehn
->ehn_Events
& IDCMP_RAWKEY
)
2154 || (ehn
->ehn_Flags
& MUI_EHF_ALWAYSKEYS
)))
2156 D(bug("HandleRawkey: (active) invoking on %p (ehn=%p) "
2157 "event=%p muikey=%p\n",
2158 ehn
->ehn_Object
, ehn
, event
, muikey
));
2159 res
= InvokeEventHandler(ehn
, event
, muikey
);
2160 D(bug("HandleRawkey: (active) got res=%d\n", res
));
2161 if (res
& MUI_EventHandlerRC_Eat
)
2164 /* Leave the loop if a different object has been activated */
2165 if (active_object
!= data
->wd_ActiveObject
)
2170 // event not eaten by active object, try its parents
2171 // this is to implement popup key in Popstring
2172 if (active_object
== data
->wd_ActiveObject
)
2174 Object
*current_obj
= active_object
;
2176 D(bug("HandleRawkey: try active object parents handlers\n"));
2177 while (current_obj
!= NULL
)
2179 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
;
2182 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2184 if ((ehn
->ehn_Object
== current_obj
)
2185 && ((ehn
->ehn_Events
& IDCMP_RAWKEY
)
2186 || (ehn
->ehn_Flags
& MUI_EHF_ALWAYSKEYS
)))
2188 //D(bug("HandleRawkey: (active parents) invoking on "
2189 // "%p (ehn=%p) event=%p muikey=%p\n",
2190 // ehn->ehn_Object, ehn, event, muikey));
2191 res
= InvokeEventHandler(ehn
, event
, muikey
);
2192 //D(bug("HandleRawkey: (active parents) got res=%d\n",
2194 if (res
& MUI_EventHandlerRC_Eat
)
2197 /* Leave the loop if a different object has been
2199 if (active_object
!= data
->wd_ActiveObject
)
2203 current_obj
= (Object
*) XGET(current_obj
, MUIA_Parent
);
2208 D(bug("HandleRawkey: try default object handlers\n"));
2210 /* try DefaultObject */
2211 if (data
->wd_DefaultObject
!= NULL
)
2212 get(data
->wd_DefaultObject
, MUIA_Disabled
, &disabled
);
2214 if ((data
->wd_DefaultObject
!= NULL
) && !disabled
2215 && (active_object
!= data
->wd_DefaultObject
))
2217 /* No, we only should do this if the object actually has requested
2218 * this via RequestIDCMP()! */
2219 // if (muikey != MUIKEY_NONE
2220 // && (_flags(data->wd_DefaultObject) & MADF_CANDRAW))
2222 // DoMethod(data->wd_DefaultObject, MUIM_HandleInput, event, muikey);
2226 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2228 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2230 if ((ehn
->ehn_Object
== data
->wd_DefaultObject
)
2231 && ((ehn
->ehn_Events
& IDCMP_RAWKEY
)
2232 || (ehn
->ehn_Flags
& MUI_EHF_ALWAYSKEYS
)))
2234 //D(bug("HandleRawkey: (default) invoking on %p (ehn=%p) "
2235 //"event=%p muikey=%p\n",
2236 //ehn->ehn_Object, ehn, event, muikey));
2237 res
= InvokeEventHandler(ehn
, event
, muikey
);
2238 //D(bug("HandleRawkey: (default) got res=%d\n", res));
2239 if (res
& MUI_EventHandlerRC_Eat
)
2246 D(bug("HandleRawkey: try other handlers\n"));
2248 // try other handlers
2249 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2251 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2253 // skip Active and Default object as they have already been
2255 if (ehn
->ehn_Object
== data
->wd_ActiveObject
2256 || ehn
->ehn_Object
== data
->wd_DefaultObject
)
2259 if (ehn
->ehn_Events
& IDCMP_RAWKEY
)
2261 //D(bug("HandleRawkey: (others) invoking on %p (ehn=%p) "
2262 //"event=%p muikey=%p\n",
2263 //ehn->ehn_Object, ehn, event, muikey));
2264 res
= InvokeEventHandler(ehn
, event
, MUIKEY_NONE
);
2265 //D(bug("HandleRawkey: (others) got res=%d\n", res));
2266 if (res
& MUI_EventHandlerRC_Eat
)
2271 D(bug("HandleRawkey: try control chars handlers\n"));
2273 /* try Control Chars */
2274 //bug("ctrlchar, key='%c' code=0x%08lx\n", key, event->Code);
2277 for (mn
= data
->wd_CCList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2279 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2281 if (ehn
->ehn_Events
== key
)
2284 LONG muikey2
= ehn
->ehn_Flags
;
2286 get(ehn
->ehn_Object
, MUIA_Disabled
, &disabled
);
2290 //bug("control char\n");
2291 if (event
->Code
& IECODE_UP_PREFIX
)
2293 /* simulate a release */
2294 if (muikey2
== MUIKEY_PRESS
)
2295 muikey2
= MUIKEY_RELEASE
;
2300 if ((muikey2
!= MUIKEY_NONE
)
2301 && (_flags(ehn
->ehn_Object
) & MADF_CANDRAW
)
2302 && (_flags(ehn
->ehn_Object
) & MADF_SHOWME
))
2305 (ehn
->ehn_Class
, ehn
->ehn_Object
, MUIM_HandleEvent
,
2306 (IPTR
) NULL
, muikey2
);
2307 if (res
& MUI_EventHandlerRC_Eat
)
2315 /* forward non-keystroke events to event handlers */
2316 static void HandleInputEvent(Object
*win
, struct MUI_WindowData
*data
,
2317 struct IntuiMessage
*event
)
2320 struct MUI_EventHandlerNode
*ehn
;
2321 struct IntuiMessage imsg_copy
;
2323 ULONG mask
= event
->Class
;
2325 if (mask
!= IDCMP_IDCMPUPDATE
)
2328 imsg_copy
.IAddress
= NULL
; /* be sure to trap access to that */
2329 ReplyMsg((struct Message
*)event
);
2333 if (mask
== IDCMP_MOUSEMOVE
)
2335 struct Window
*iWin
;
2336 iWin
= event
->IDCMPWindow
;
2338 if (ContextMenuUnderPointer(data
, data
->wd_RootObject
,
2339 event
->MouseX
, event
->MouseY
))
2341 iWin
->Flags
|= WFLG_RMBTRAP
;
2343 else if (!data
->wd_NoMenus
)
2345 iWin
->Flags
&= ~WFLG_RMBTRAP
;
2349 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2351 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2353 if (ehn
->ehn_Events
& mask
)
2357 get(ehn
->ehn_Object
, MUIA_Disabled
, &disabled
);
2361 res
= InvokeEventHandler(ehn
, event
, MUIKEY_NONE
);
2362 if (res
& MUI_EventHandlerRC_Eat
)
2368 if (mask
== IDCMP_IDCMPUPDATE
)
2369 ReplyMsg((struct Message
*)event
);
2373 /* process window message; this does a ReplyMsg() to the message */
2374 /* Called from application.c */
2375 void _zune_window_message(struct IntuiMessage
*imsg
)
2377 struct Window
*iWin
;
2379 struct MUI_WindowData
*data
;
2382 iWin
= imsg
->IDCMPWindow
;
2383 oWin
= (Object
*) iWin
->UserData
;
2384 data
= muiWindowData(oWin
);
2386 if (data
->wd_DragObject
)
2388 if (!HandleDragging(oWin
, data
, imsg
))
2392 handled
= HandleWindowEvent(oWin
, data
, imsg
);
2395 if (IDCMP_RAWKEY
== imsg
->Class
)
2396 HandleRawkey(oWin
, data
, imsg
);
2397 else if (IDCMP_GADGETUP
== imsg
->Class
)
2400 if (ETI_MUI
== ((struct Gadget
*)imsg
->IAddress
)->GadgetID
)
2402 DoMethod(_app(oWin
), MUIM_Application_OpenConfigWindow
);
2405 if (ETI_Iconify
== ((struct Gadget
*)imsg
->IAddress
)->GadgetID
)
2407 set(_app(oWin
), MUIA_Application_Iconified
, TRUE
);
2412 HandleInputEvent(oWin
, data
, imsg
);
2417 /**************************************************************************/
2418 /**************************************************************************/
2420 /* code for setting MUIA_Window_RootObject */
2421 static void ChangeRootObject(struct MUI_WindowData
*data
, Object
*obj
,
2426 ASSERT_VALID_PTR(data
);
2427 ASSERT_VALID_PTR(obj
);
2429 oldRoot
= data
->wd_RootObject
;
2430 if (!(data
->wd_Flags
& MUIWF_OPENED
))
2434 if (data
->wd_ActiveObject
== oldRoot
)
2435 set(obj
, MUIA_Window_ActiveObject
,
2436 MUIV_Window_ActiveObject_None
);
2437 DoMethod(oldRoot
, MUIM_DisconnectParent
);
2440 data
->wd_RootObject
= newRoot
;
2443 /* if window is in App tree, inform child */
2444 if (muiNotifyData(obj
)->mnd_GlobalInfo
)
2445 DoMethod(newRoot
, MUIM_ConnectParent
, (IPTR
) obj
);
2450 // find the ObjNode containing a pointer to the given object
2451 // currently only used for cycle chain objects
2452 static struct ObjNode
*FindObjNode(struct MinList
*list
, Object
*obj
)
2454 struct ObjNode
*node
;
2456 ASSERT_VALID_PTR(list
);
2461 ASSERT_VALID_PTR(obj
);
2463 for (node
= (struct ObjNode
*)list
->mlh_Head
;
2464 node
->node
.mln_Succ
; node
= (struct ObjNode
*)node
->node
.mln_Succ
)
2466 if (node
->obj
== obj
)
2474 static Object
*GetFirstActiveObject(struct MUI_WindowData
*data
)
2476 ASSERT_VALID_PTR(data
);
2478 if (!IsListEmpty(&data
->wd_CycleChain
))
2479 return ((struct ObjNode
*)data
->wd_CycleChain
.mlh_Head
)->obj
;
2484 static Object
*GetLastActiveObject(struct MUI_WindowData
*data
)
2486 ASSERT_VALID_PTR(data
);
2488 if (!IsListEmpty(&data
->wd_CycleChain
))
2489 return ((struct ObjNode
*)data
->wd_CycleChain
.mlh_TailPred
)->obj
;
2494 typedef struct ObjNode
*objnode_iterator_t(struct ObjNode
*curr_node
);
2496 static objnode_iterator_t NextObjNodeIterator
;
2497 static objnode_iterator_t PrevObjNodeIterator
;
2499 static struct ObjNode
*NextObjNodeIterator(struct ObjNode
*curr_node
)
2501 if (curr_node
->node
.mln_Succ
->mln_Succ
)
2502 return (struct ObjNode
*)curr_node
->node
.mln_Succ
;
2507 static struct ObjNode
*PrevObjNodeIterator(struct ObjNode
*curr_node
)
2509 if (curr_node
->node
.mln_Pred
->mln_Pred
)
2510 return (struct ObjNode
*)curr_node
->node
.mln_Pred
;
2515 static Object
*GetPrevNextActiveObject(struct ObjNode
*old_activenode
,
2516 objnode_iterator_t node_iterator
)
2518 struct ObjNode
*curr_node
;
2519 struct ObjNode
*node
;
2522 ASSERT_VALID_PTR(old_activenode
);
2524 curr_node
= old_activenode
;
2530 node
= node_iterator(curr_node
);
2535 /* let's see if this object meets cycle requirements
2536 * (enabled & visible) */
2539 IPTR is_disabled
= 0;
2541 get(obj
, MUIA_Disabled
, &is_disabled
);
2543 if (!is_disabled
&& (_flags(obj
) & MADF_SHOWME
))
2557 /**************************************************************************
2558 Code for setting MUIA_Window_ActiveObject
2560 - remove focus drawing for current active object
2561 - find (if needed) the new active object
2562 - set data->wd_ActiveObject to the new object
2563 - draw focus around the new active object
2564 **************************************************************************/
2565 static void SetActiveObject(struct MUI_WindowData
*data
, Object
*obj
,
2568 struct ObjNode
*old_activenode
= NULL
;
2570 ASSERT_VALID_PTR(data
);
2571 ASSERT_VALID_PTR(obj
);
2573 D(bug("MUIC_Window:SetActiveObject(data, obj, %08lx) Active=%p\n",
2574 newval
, data
->wd_ActiveObject
));
2576 if ((data
->wd_ActiveObject
!= NULL
)
2577 && (DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
2578 (IPTR
) data
->wd_ActiveObject
) != (IPTR
) NULL
))
2580 if ((IPTR
) data
->wd_ActiveObject
!= newval
)
2583 FindObjNode(&data
->wd_CycleChain
, data
->wd_ActiveObject
);
2584 if ((data
->wd_Flags
& MUIWF_OBJECTGOACTIVESENT
)
2585 && (_flags(data
->wd_ActiveObject
) & MADF_SETUP
))
2587 D(bug("Deactivate=%p\n", data
->wd_ActiveObject
));
2588 DoMethod(data
->wd_ActiveObject
, MUIM_GoInactive
);
2593 data
->wd_ActiveObject
= NULL
;
2594 data
->wd_Flags
&= ~MUIWF_OBJECTGOACTIVESENT
;
2598 case MUIV_Window_ActiveObject_None
:
2601 case MUIV_Window_ActiveObject_Next
:
2602 if (old_activenode
!= NULL
)
2603 data
->wd_ActiveObject
= GetPrevNextActiveObject(old_activenode
,
2604 NextObjNodeIterator
);
2605 if (NULL
== data
->wd_ActiveObject
)
2606 data
->wd_ActiveObject
= GetFirstActiveObject(data
);
2609 case MUIV_Window_ActiveObject_Prev
:
2611 data
->wd_ActiveObject
= GetPrevNextActiveObject(old_activenode
,
2612 PrevObjNodeIterator
);
2613 if (NULL
== data
->wd_ActiveObject
)
2614 data
->wd_ActiveObject
= GetLastActiveObject(data
);
2618 data
->wd_ActiveObject
= (Object
*) newval
;
2623 if (data
->wd_ActiveObject
!= NULL
2624 && DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
2625 (IPTR
) data
->wd_ActiveObject
)
2626 && (_flags(data
->wd_ActiveObject
) & MADF_CANDRAW
))
2628 D(bug("Activate=%p\n", data
->wd_ActiveObject
));
2629 DoMethod(data
->wd_ActiveObject
, MUIM_GoActive
);
2630 data
->wd_Flags
|= MUIWF_OBJECTGOACTIVESENT
;
2635 static BOOL
InBox(struct IBox
*box
, WORD x
, WORD y
)
2637 return x
>= box
->Left
&& x
< box
->Left
+ box
->Width
2638 && y
>= box
->Top
&& y
< box
->Top
+ box
->Height
;
2643 * Pass on an AppMessage to all objects that it landed on.
2645 static void ForwardAppMessage(struct MUI_WindowData
*data
, Object
*child
,
2646 struct AppMessage
*appmsg
)
2648 WORD x
= appmsg
->am_MouseX
, y
= appmsg
->am_MouseY
;
2650 struct List
*children
= NULL
;
2652 ASSERT_VALID_PTR(data
);
2653 ASSERT_VALID_PTR(child
);
2655 set(child
, MUIA_AppMessage
, appmsg
);
2657 children
= (struct List
*)XGET(child
, MUIA_Group_ChildList
);
2659 if (children
!= NULL
)
2661 cstate
= (Object
*) children
->lh_Head
;
2662 while ((child
= NextObject(&cstate
)))
2664 if (InBox(&muiAreaData(child
)->mad_Box
, x
, y
))
2666 ForwardAppMessage(data
, child
, appmsg
);
2674 * calculate real dimensions from programmer requirements.
2675 * may be overridden by user settings if MUIA_Window_ID is set.
2677 /* MUIV_Window_Height_Screen and MUIV_Window_Height_Visible
2678 * are not handled yet, as their Width couterparts.
2680 static void WindowSelectDimensions(struct MUI_WindowData
*data
)
2682 if (!data
->wd_Width
)
2684 if (data
->wd_ReqWidth
> 0)
2685 data
->wd_Width
= data
->wd_ReqWidth
;
2686 else if (data
->wd_ReqWidth
== MUIV_Window_Width_Default
)
2687 data
->wd_Width
= data
->wd_MinMax
.DefWidth
;
2688 else if (_between(MUIV_Window_Width_MinMax(100),
2689 data
->wd_ReqWidth
, MUIV_Window_Width_MinMax(0)))
2691 data
->wd_Width
= data
->wd_MinMax
.MinWidth
2693 * (data
->wd_MinMax
.MaxWidth
- data
->wd_MinMax
.MinWidth
);
2695 else if (_between(MUIV_Window_Width_Screen(100),
2696 data
->wd_ReqWidth
, MUIV_Window_Width_Screen(0)))
2698 data
->wd_Width
= data
->wd_RenderInfo
.mri_ScreenWidth
2699 * (-(data
->wd_ReqWidth
+ 200)) / 100;
2701 else if (_between(MUIV_Window_Width_Visible(100),
2702 data
->wd_ReqWidth
, MUIV_Window_Width_Visible(0)))
2704 data
->wd_Width
= data
->wd_RenderInfo
.mri_ScreenWidth
2705 * (-(data
->wd_ReqWidth
+ 100)) / 100;
2708 if (data
->wd_ReqHeight
> 0)
2709 data
->wd_Height
= data
->wd_ReqHeight
;
2710 else if (data
->wd_ReqHeight
== MUIV_Window_Height_Default
)
2711 data
->wd_Height
= data
->wd_MinMax
.DefHeight
;
2712 else if (_between(MUIV_Window_Height_MinMax(100),
2713 data
->wd_ReqHeight
, MUIV_Window_Height_MinMax(0)))
2715 data
->wd_Height
= data
->wd_MinMax
.MinHeight
2716 - data
->wd_ReqHeight
2717 * (data
->wd_MinMax
.MaxHeight
- data
->wd_MinMax
.MinHeight
);
2719 else if (_between(MUIV_Window_Height_Screen(100),
2720 data
->wd_ReqHeight
, MUIV_Window_Height_Screen(0)))
2725 scr
= data
->wd_RenderInfo
.mri_Screen
;
2728 scr
->Height
- data
->wd_RenderInfo
.mri_BorderTop
-
2729 data
->wd_RenderInfo
.mri_BorderBottom
;
2731 /* This is new to Zune: If TopEdge Delta is requested
2732 * the screenheight doesn't cover the barlayer */
2733 if (data
->wd_Y
<= MUIV_Window_TopEdge_Delta(0))
2734 height
-= scr
->BarHeight
+ 1;
2736 data
->wd_Height
= height
* (-(data
->wd_ReqHeight
+ 200)) / 100;
2738 else if (_between(MUIV_Window_Height_Visible(100),
2739 data
->wd_ReqHeight
, MUIV_Window_Height_Visible(0)))
2741 data
->wd_Height
= data
->wd_RenderInfo
.mri_ScreenHeight
2742 * (-(data
->wd_ReqHeight
+ 100)) / 100;
2746 if (data
->wd_ReqWidth
== MUIV_Window_Width_Scaled
)
2747 data
->wd_Width
= data
->wd_Height
* data
->wd_MinMax
.MinWidth
2748 / data
->wd_MinMax
.MinHeight
;
2749 else if (data
->wd_ReqHeight
== MUIV_Window_Width_Scaled
)
2750 data
->wd_Height
= data
->wd_Width
* data
->wd_MinMax
.MinHeight
2751 / data
->wd_MinMax
.MinWidth
;
2753 data
->wd_Width
= CLAMP(data
->wd_Width
, data
->wd_MinMax
.MinWidth
,
2754 data
->wd_MinMax
.MaxWidth
);
2755 data
->wd_Height
= CLAMP(data
->wd_Height
, data
->wd_MinMax
.MinHeight
,
2756 data
->wd_MinMax
.MaxHeight
);
2760 /**************************************************************************
2762 **************************************************************************/
2763 IPTR
Window__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
2765 struct MUI_WindowData
*data
;
2766 struct TagItem
*tags
;
2767 struct TagItem
*tag
;
2769 obj
= (Object
*) DoSuperMethodA(cl
, obj
, (Msg
) msg
);
2773 /* Initial local instance data */
2774 data
= INST_DATA(cl
, obj
);
2776 data
->wd_Class
= cl
;
2777 data
->wd_MemoryPool
= CreatePool(0, 4096, 2048);
2778 if (NULL
== data
->wd_MemoryPool
)
2780 CoerceMethod(cl
, obj
, OM_DISPOSE
);
2784 data
->wd_RenderInfo
.mri_WindowObject
= obj
;
2786 NewList((struct List
*)&(data
->wd_EHList
));
2787 NewList((struct List
*)&(data
->wd_CCList
));
2788 NewList((struct List
*)&(data
->wd_CycleChain
));
2789 NewList((struct List
*)&(data
->wd_IDList
));
2791 data
->wd_CrtFlags
= WFLG_SIZEGADGET
| WFLG_DRAGBAR
| WFLG_DEPTHGADGET
2792 | WFLG_CLOSEGADGET
| WFLG_SIMPLE_REFRESH
2793 | WFLG_REPORTMOUSE
| WFLG_NEWLOOKMENUS
;
2794 data
->wd_ZoomGadget
= TRUE
;
2795 data
->wd_Events
= GetDefaultEvents();
2796 data
->wd_ActiveObject
= NULL
;
2798 data
->wd_ReqHeight
= MUIV_Window_Height_Default
;
2799 data
->wd_ReqWidth
= MUIV_Window_Width_Default
;
2800 data
->wd_RootObject
= NULL
;
2801 data
->wd_DefaultObject
= NULL
;
2803 /* alternate dimensions */
2804 /* no change in coordinates */
2805 data
->wd_AltDim
.Top
= MUIV_Window_AltTopEdge_NoChange
;
2806 data
->wd_AltDim
.Left
= MUIV_Window_AltLeftEdge_NoChange
;
2807 /* default to min size */
2808 data
->wd_AltDim
.Width
= MUIV_Window_AltWidth_MinMax(0);
2809 data
->wd_AltDim
.Height
= MUIV_Window_AltHeight_MinMax(0);
2810 data
->wd_X
= MUIV_Window_LeftEdge_Centered
;
2811 data
->wd_Y
= MUIV_Window_TopEdge_Centered
;
2812 data
->wd_DisabledKeys
= 0L;
2813 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_FIRST
;
2815 /* parse initial taglist */
2817 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
));)
2819 switch (tag
->ti_Tag
)
2821 case MUIA_Window_EraseArea
:
2822 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_ERASEAREA
);
2825 case MUIA_Window_ToolBox
:
2826 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_TOOLBOX
);
2829 case MUIA_Window_CloseGadget
:
2830 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
,
2834 case MUIA_Window_SizeGadget
:
2835 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
,
2839 case MUIA_Window_ZoomGadget
:
2840 data
->wd_ZoomGadget
= tag
->ti_Data
;
2843 case MUIA_Window_Backdrop
:
2844 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
,
2848 case MUIA_Window_Borderless
:
2849 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
,
2853 case MUIA_Window_DepthGadget
:
2854 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
,
2858 case MUIA_Window_DragBar
:
2859 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_DRAGBAR
);
2862 case MUIA_Window_SizeRight
:
2863 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
,
2867 case MUIA_Window_Height
:
2868 data
->wd_ReqHeight
= (LONG
) tag
->ti_Data
;
2871 case MUIA_Window_Width
:
2872 data
->wd_ReqWidth
= (LONG
) tag
->ti_Data
;
2875 case MUIA_Window_ID
:
2876 set(obj
, MUIA_Window_ID
, tag
->ti_Data
);
2879 case MUIA_Window_IsSubWindow
:
2880 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
2884 case MUIA_Window_Title
:
2885 set(obj
, MUIA_Window_Title
, tag
->ti_Data
);
2888 case MUIA_Window_ScreenTitle
:
2889 set(obj
, MUIA_Window_ScreenTitle
, tag
->ti_Data
);
2892 case MUIA_Window_Activate
:
2893 _handle_bool_tag(data
->wd_Flags
, !tag
->ti_Data
,
2894 MUIWF_DONTACTIVATE
);
2897 case MUIA_Window_DefaultObject
:
2898 set(obj
, MUIA_Window_DefaultObject
, tag
->ti_Data
);
2901 case MUIA_Window_Menustrip
:
2902 data
->wd_ChildMenustrip
= (Object
*) tag
->ti_Data
;
2905 case MUIA_Window_NoMenus
:
2906 data
->wd_NoMenus
= (BOOL
) tag
->ti_Data
;
2909 case MUIA_Window_RootObject
:
2912 CoerceMethod(cl
, obj
, OM_DISPOSE
);
2915 set(obj
, MUIA_Window_RootObject
, tag
->ti_Data
);
2918 case MUIA_Window_AltHeight
:
2919 data
->wd_AltDim
.Height
= (WORD
) tag
->ti_Data
;
2922 case MUIA_Window_AltWidth
:
2923 data
->wd_AltDim
.Width
= (WORD
) tag
->ti_Data
;
2926 case MUIA_Window_AltLeftEdge
:
2927 data
->wd_AltDim
.Left
= (WORD
) tag
->ti_Data
;
2930 case MUIA_Window_AltTopEdge
:
2931 data
->wd_AltDim
.Top
= (WORD
) tag
->ti_Data
;
2934 case MUIA_Window_AppWindow
:
2935 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
2939 case MUIA_Window_LeftEdge
:
2940 data
->wd_X
= tag
->ti_Data
;
2943 case MUIA_Window_TopEdge
:
2944 data
->wd_Y
= tag
->ti_Data
;
2947 case MUIA_Window_UseBottomBorderScroller
:
2948 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
2949 MUIWF_USEBOTTOMSCROLLER
);
2952 case MUIA_Window_UseRightBorderScroller
:
2953 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
2954 MUIWF_USERIGHTSCROLLER
);
2957 case MUIA_Window_DisableKeys
:
2958 data
->wd_DisabledKeys
= tag
->ti_Data
;
2961 case MUIA_Window_RefWindow
:
2962 data
->wd_RefWindow
= (Object
*) tag
->ti_Data
;
2965 case MUIA_Window_Screen
:
2966 data
->wd_UserScreen
= (struct Screen
*)tag
->ti_Data
;
2969 case MUIA_Window_PublicScreen
:
2970 data
->wd_UserPublicScreen
= (STRPTR
) tag
->ti_Data
;
2975 /* D(bug("muimaster.library/window.c: Window Object created at " */
2976 /* "0x%lx back=%lx\n", */
2977 /* obj,data->wd_Background)); */
2982 /**************************************************************************
2984 **************************************************************************/
2985 IPTR
Window__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
2987 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
2989 /* D(bug("Window_Dispose(%p)\n", obj)); */
2992 /* We no longer clear muiGlobalInfo() during disconnections, so
2993 this can cause problems (remove object which is already removed).
2994 Furthermore AFAIK it is not legal to dispose a window object
2995 which is still ocnnected to the application object, anyway. */
2997 if (muiGlobalInfo(obj
) && _app(obj
))
2999 /* D(bug(" Window_Dispose(%p) : calling app->OM_REMMEMBER\n", obj)); */
3000 DoMethod(_app(obj
), OM_REMMEMBER
, (IPTR
) obj
);
3004 if (data
->wd_RootObject
)
3005 MUI_DisposeObject(data
->wd_RootObject
);
3007 if (data
->wd_ChildMenustrip
)
3008 MUI_DisposeObject(data
->wd_ChildMenustrip
);
3011 FreeVec(data
->wd_Title
);
3013 if (data
->wd_ScreenTitle
)
3014 FreeVec(data
->wd_ScreenTitle
);
3016 DeletePool(data
->wd_MemoryPool
);
3018 /* D(bug(" Window_Dispose(%p) : calling supermethod\n", obj)); */
3019 return DoSuperMethodA(cl
, obj
, msg
);
3022 static ULONG
WindowOpen(struct IClass
*cl
, Object
*obj
);
3023 static ULONG
WindowClose(struct IClass
*cl
, Object
*obj
);
3025 /**************************************************************************
3027 **************************************************************************/
3028 IPTR
Window__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
3030 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3031 struct TagItem
*tags
= msg
->ops_AttrList
;
3032 struct TagItem
*tag
;
3034 while ((tag
= NextTagItem(&tags
)) != NULL
)
3036 switch (tag
->ti_Tag
)
3038 case MUIA_AppMessage
:
3039 ForwardAppMessage(data
, data
->wd_RootObject
,
3040 (struct AppMessage
*)tag
->ti_Data
);
3043 case MUIA_Window_Activate
:
3044 if (data
->wd_RenderInfo
.mri_Window
)
3046 if (tag
->ti_Data
&& !(data
->wd_Flags
& MUIWF_ACTIVE
))
3048 ActivateWindow(data
->wd_RenderInfo
.mri_Window
);
3049 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
3054 _handle_bool_tag(data
->wd_Flags
, !tag
->ti_Data
,
3055 MUIWF_DONTACTIVATE
);
3058 case MUIA_Window_ActiveObject
:
3059 /* D(bug("MUIA_Window_ActiveObject %ld (%p)\n", */
3060 /* tag->ti_Data, tag->ti_Data)); */
3061 SetActiveObject(data
, obj
, tag
->ti_Data
);
3064 case MUIA_Window_DefaultObject
:
3065 data
->wd_DefaultObject
= (APTR
) tag
->ti_Data
;
3068 case MUIA_Window_ID
:
3069 data
->wd_ID
= tag
->ti_Data
;
3072 case MUIA_Window_IsSubWindow
:
3073 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
3077 case MUIA_Window_Open
:
3080 if (data
->wd_Flags
& MUIWF_HIDDEN
)
3081 data
->wd_Flags
|= MUIWF_OPENONUNHIDE
;
3082 else if (!(data
->wd_Flags
& MUIWF_OPENED
))
3083 WindowOpen(cl
, obj
);
3086 DoMethod(obj
, MUIM_Window_ToFront
);
3087 set(obj
, MUIA_Window_Activate
, TRUE
);
3090 else if (data
->wd_Flags
& MUIWF_HIDDEN
)
3091 data
->wd_Flags
&= ~MUIWF_OPENONUNHIDE
;
3092 else if (data
->wd_Flags
& MUIWF_OPENED
)
3093 WindowClose(cl
, obj
);
3096 case MUIA_ShowMe
: /* PRIVATE *abuse* of the Area's ShowMe attr */
3101 if (data
->wd_Flags
& MUIWF_HIDDEN
)
3103 data
->wd_Flags
&= ~MUIWF_HIDDEN
;
3105 if (data
->wd_Flags
& MUIWF_OPENONUNHIDE
)
3107 data
->wd_Flags
&= ~MUIWF_OPENONUNHIDE
;
3108 set(obj
, MUIA_Window_Open
, TRUE
);
3116 if (data
->wd_Flags
& MUIWF_OPENED
)
3118 data
->wd_Flags
|= MUIWF_OPENONUNHIDE
;
3120 set(obj
, MUIA_Window_Open
, FALSE
);
3123 data
->wd_Flags
|= MUIWF_HIDDEN
;
3127 case MUIA_Window_RootObject
:
3128 ChangeRootObject(data
, obj
, (Object
*) tag
->ti_Data
);
3131 case MUIA_Window_Title
:
3133 FreeVec(data
->wd_Title
);
3134 data
->wd_Title
= StrDup((STRPTR
) tag
->ti_Data
);
3135 if (data
->wd_RenderInfo
.mri_Window
)
3136 SetWindowTitles(data
->wd_RenderInfo
.mri_Window
,
3137 data
->wd_Title
, (CONST_STRPTR
) ~ 0);
3140 case MUIA_Window_ScreenTitle
:
3141 if (data
->wd_ScreenTitle
)
3142 FreeVec(data
->wd_ScreenTitle
);
3143 data
->wd_ScreenTitle
= StrDup((STRPTR
) tag
->ti_Data
);
3144 if (data
->wd_RenderInfo
.mri_Window
)
3145 SetWindowTitles(data
->wd_RenderInfo
.mri_Window
,
3146 (CONST_STRPTR
) ~ 0, data
->wd_ScreenTitle
);
3149 case MUIA_Window_NoMenus
:
3150 data
->wd_NoMenus
= (BOOL
) tag
->ti_Data
;
3151 if (data
->wd_RenderInfo
.mri_Window
)
3153 if (data
->wd_NoMenus
)
3154 data
->wd_RenderInfo
.mri_Window
->Flags
|= WFLG_RMBTRAP
;
3156 data
->wd_RenderInfo
.mri_Window
->Flags
&= ~WFLG_RMBTRAP
;
3160 case MUIA_Window_UseBottomBorderScroller
:
3161 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
3162 MUIWF_USEBOTTOMSCROLLER
);
3165 case MUIA_Window_UseRightBorderScroller
:
3166 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
3167 MUIWF_USERIGHTSCROLLER
);
3170 case MUIA_Window_DisableKeys
:
3171 data
->wd_DisabledKeys
= tag
->ti_Data
;
3174 case MUIA_Window_RefWindow
:
3175 data
->wd_RefWindow
= (Object
*) tag
->ti_Data
;
3178 case MUIA_Window_LeftEdge
:
3179 data
->wd_X
= tag
->ti_Data
;
3182 case MUIA_Window_TopEdge
:
3183 data
->wd_Y
= tag
->ti_Data
;
3186 case MUIA_Window_Width
:
3187 data
->wd_ReqWidth
= (LONG
) tag
->ti_Data
;
3188 data
->wd_Width
= 0; /* otherwise windowselectdimensions()
3189 * ignores ReqWidth */
3192 case MUIA_Window_Height
:
3193 data
->wd_ReqHeight
= (LONG
) tag
->ti_Data
;
3194 data
->wd_Height
= 0;
3197 case MUIA_Window_Screen
:
3198 data
->wd_UserScreen
= (struct Screen
*)tag
->ti_Data
;
3201 case MUIA_Window_PublicScreen
:
3202 data
->wd_UserPublicScreen
= (STRPTR
) tag
->ti_Data
;
3205 case MUIA_Window_Sleep
:
3208 data
->wd_SleepCount
++;
3209 if (data
->wd_RenderInfo
.mri_Window
3210 && (data
->wd_SleepCount
== 1))
3213 (data
->wd_RenderInfo
.mri_Window
,
3214 WA_BusyPointer
, TRUE
,
3215 WA_PointerDelay
, TRUE
, TAG_DONE
);
3216 // FIXME: how to disable event handling?
3221 data
->wd_SleepCount
--;
3222 if (data
->wd_RenderInfo
.mri_Window
3223 && (data
->wd_SleepCount
== 0))
3225 SetWindowPointerA(data
->wd_RenderInfo
.mri_Window
, NULL
);
3233 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
3236 /**************************************************************************
3238 **************************************************************************/
3239 IPTR
Window__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
3241 #define STORE *(msg->opg_Storage)
3243 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3247 switch (msg
->opg_AttrID
)
3249 case MUIA_Window_Activate
:
3251 (data
->wd_Flags
& (MUIWF_ACTIVE
| MUIWF_OPENED
)) ==
3252 (MUIWF_ACTIVE
| MUIWF_OPENED
);
3255 case MUIA_Window_Window
:
3256 STORE
= (IPTR
) data
->wd_RenderInfo
.mri_Window
;
3259 case MUIA_Window_Screen
:
3260 STORE
= (IPTR
) data
->wd_RenderInfo
.mri_Screen
;
3263 case MUIA_Window_PublicScreen
:
3264 STORE
= (IPTR
) data
->wd_UserPublicScreen
;
3267 case MUIA_Window_ActiveObject
:
3268 if ((data
->wd_ActiveObject
!= NULL
)
3269 && (DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
3270 (IPTR
) data
->wd_ActiveObject
) != (IPTR
) NULL
))
3271 STORE
= (IPTR
) data
->wd_ActiveObject
;
3273 STORE
= (IPTR
) NULL
;
3276 case MUIA_Window_CloseRequest
:
3280 case MUIA_Window_DefaultObject
:
3281 STORE
= (IPTR
) data
->wd_DefaultObject
;
3284 case MUIA_Window_DisableKeys
:
3285 STORE
= data
->wd_DisabledKeys
;
3288 case MUIA_Window_Height
:
3289 STORE
= (IPTR
) data
->wd_Height
;
3292 case MUIA_Window_ID
:
3293 STORE
= data
->wd_ID
;
3296 case MUIA_Window_IsSubWindow
:
3297 STORE
= (data
->wd_Flags
& MUIWF_ISSUBWINDOW
) == MUIWF_ISSUBWINDOW
;
3300 case MUIA_Window_LeftEdge
:
3301 if (data
->wd_RenderInfo
.mri_Window
)
3302 STORE
= (IPTR
) data
->wd_RenderInfo
.mri_Window
->LeftEdge
;
3307 case MUIA_Window_Open
:
3308 STORE
= (data
->wd_Flags
& MUIWF_OPENED
) == MUIWF_OPENED
;
3311 case MUIA_Window_RootObject
:
3312 STORE
= (IPTR
) data
->wd_RootObject
;
3315 case MUIA_Window_ScreenTitle
:
3316 STORE
= (IPTR
) data
->wd_ScreenTitle
;
3319 case MUIA_Window_Title
:
3320 STORE
= (IPTR
) data
->wd_Title
;
3323 case MUIA_Window_TopEdge
:
3324 if (data
->wd_RenderInfo
.mri_Window
)
3325 STORE
= (IPTR
) data
->wd_RenderInfo
.mri_Window
->TopEdge
;
3330 case MUIA_Window_Width
:
3331 STORE
= (IPTR
) data
->wd_Width
;
3334 case MUIA_Window_Menustrip
:
3335 STORE
= (IPTR
) data
->wd_ChildMenustrip
;
3338 case MUIA_Window_Sleep
:
3339 STORE
= data
->wd_SleepCount
? TRUE
: FALSE
;
3351 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
3356 * MUIM_FindUData : tests if the MUIA_UserData of the object
3357 * contains the given <udata> and returns the object pointer in this case.
3359 IPTR
Window__MUIM_FindUData(struct IClass
*cl
, Object
*obj
,
3360 struct MUIP_FindUData
*msg
)
3362 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3364 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3367 if (data
->wd_RootObject
)
3368 return DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
3375 * MUIM_GetUData : This method tests if the MUIA_UserData of the object
3376 * contains the given <udata> and gets <attr> to <storage> for itself
3379 IPTR
Window__MUIM_GetUData(struct IClass
*cl
, Object
*obj
,
3380 struct MUIP_GetUData
*msg
)
3382 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3384 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3386 get(obj
, msg
->attr
, msg
->storage
);
3390 if (data
->wd_RootObject
)
3391 return DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
3398 * MUIM_SetUData : This method tests if the MUIA_UserData of the object
3399 * contains the given <udata> and sets <attr> to <val> for itself in this case.
3401 IPTR
Window__MUIM_SetUData(struct IClass
*cl
, Object
*obj
,
3402 struct MUIP_SetUData
*msg
)
3404 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3406 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3407 set(obj
, msg
->attr
, msg
->val
);
3409 if (data
->wd_RootObject
)
3410 DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
3417 * MUIM_SetUDataOnce : This method tests if the MUIA_UserData of the object
3418 * contains the given <udata> and sets <attr> to <val> for itself in this case.
3420 IPTR
Window__MUIM_SetUDataOnce(struct IClass
*cl
, Object
*obj
,
3421 struct MUIP_SetUDataOnce
*msg
)
3423 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3425 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3427 set(obj
, msg
->attr
, msg
->val
);
3431 if (data
->wd_RootObject
)
3432 return DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
3437 /**************************************************************************
3438 Called by Application (parent) object whenever this object is added.
3440 **************************************************************************/
3441 IPTR
Window__MUIM_ConnectParent(struct IClass
*cl
, Object
*obj
,
3442 struct MUIP_ConnectParent
*msg
)
3444 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3446 if (!DoSuperMethodA(cl
, obj
, (Msg
) msg
))
3449 if (data
->wd_RootObject
)
3450 DoMethod(data
->wd_RootObject
, MUIM_ConnectParent
, (IPTR
) obj
);
3452 if (data
->wd_ChildMenustrip
)
3453 DoMethod(data
->wd_ChildMenustrip
, MUIM_ConnectParent
, (IPTR
) obj
);
3459 /**************************************************************************
3460 called by parent object
3461 **************************************************************************/
3462 IPTR
Window__MUIM_DisconnectParent(struct IClass
*cl
, Object
*obj
,
3463 struct MUIP_DisconnectParent
*msg
)
3465 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3467 /* D(bug("Window_DisconnectParent(%p) : muiGlobalInfo=%p\n", */
3468 /* muiGlobalInfo(obj))); */
3469 if (muiGlobalInfo(obj
))
3471 /* Close the window before disconnecting all the childs */
3472 if ((data
->wd_Flags
& MUIWF_OPENED
))
3474 /* D(bug(" Window_DisconnectParent(%p) : closing window\n", */
3475 /* muiGlobalInfo(obj))); */
3476 set(obj
, MUIA_Window_Open
, FALSE
);
3478 if (data
->wd_ChildMenustrip
)
3479 DoMethod(data
->wd_ChildMenustrip
, MUIM_DisconnectParent
,
3482 if (data
->wd_RootObject
)
3483 DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
3485 /* D(bug(" Window_DisconnectParent(%p) : calling supermethod\n", */
3486 /* muiGlobalInfo(obj))); */
3487 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
3495 static void SetRootObjInnerSpacing(Object
*obj
,
3496 struct MUI_WindowData
*data
)
3498 UWORD wd_innerLeft
, wd_innerRight
, wd_innerTop
, wd_innerBottom
;
3500 if (data
->wd_CrtFlags
& WFLG_BORDERLESS
)
3509 wd_innerLeft
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_left
;
3510 wd_innerRight
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_right
;
3511 wd_innerTop
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_top
;
3512 wd_innerBottom
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_bottom
;
3515 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERLEFT
))
3517 muiAreaData(data
->wd_RootObject
)->mad_InnerLeft
= wd_innerLeft
;
3520 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERTOP
))
3522 muiAreaData(data
->wd_RootObject
)->mad_InnerTop
= wd_innerTop
;
3525 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERRIGHT
))
3527 muiAreaData(data
->wd_RootObject
)->mad_InnerRight
= wd_innerRight
;
3530 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERBOTTOM
))
3532 muiAreaData(data
->wd_RootObject
)->mad_InnerBottom
= wd_innerBottom
;
3537 * Called before window is opened or resized. It determines its bounds,
3538 * so you can call WindowSelectDimensions() to find the final dims.
3540 static void WindowMinMax(Object
*obj
, struct MUI_WindowData
*data
)
3542 SetRootObjInnerSpacing(obj
, data
);
3543 /* inquire about sizes */
3544 DoMethod(data
->wd_RootObject
, MUIM_AskMinMax
, (IPTR
) & data
->wd_MinMax
);
3545 /* D(bug("*** root minmax = %ld,%ld => %ld,%ld\n", */
3546 /* data->wd_MinMax.MinWidth, */
3547 /* data->wd_MinMax.MinHeight, */
3548 /* data->wd_MinMax.MaxWidth, data->wd_MinMax.MaxHeight)); */
3549 __area_finish_minmax(data
->wd_RootObject
, &data
->wd_MinMax
);
3550 /* D(bug("*** root minmax2 = %ld,%ld => %ld,%ld\n", */
3551 /* data->wd_MinMax.MinWidth, */
3552 /* data->wd_MinMax.MinHeight, */
3553 /* data->wd_MinMax.MaxWidth, data->wd_MinMax.MaxHeight)); */
3557 static void InstallBackbuffer(struct IClass
*cl
, Object
*obj
)
3559 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3561 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
3563 data
->wd_RenderInfo
.mri_BufferBM
=
3564 AllocBitMap(win
->Width
, win
->Height
, win
->RPort
->BitMap
->Depth
,
3565 0, win
->RPort
->BitMap
);
3567 if (data
->wd_RenderInfo
.mri_BufferBM
)
3569 /* D(bug("install_backbuffer : allocated bitmap %dx%dx%d " */
3570 /* "with friend %p\n", */
3571 /* win->Width, win->Height, win->RPort->BitMap->Depth, */
3572 /* win->RPort->BitMap)); */
3573 InitRastPort(&data
->wd_RenderInfo
.mri_BufferRP
);
3574 data
->wd_RenderInfo
.mri_BufferRP
.BitMap
=
3575 data
->wd_RenderInfo
.mri_BufferBM
;
3579 static void DeinstallBackbuffer(struct IClass
*cl
, Object
*obj
)
3581 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3583 if (data
->wd_RenderInfo
.mri_BufferBM
)
3585 DeinitRastPort(&data
->wd_RenderInfo
.mri_BufferRP
);
3586 FreeBitMap(data
->wd_RenderInfo
.mri_BufferBM
);
3587 data
->wd_RenderInfo
.mri_BufferBM
= NULL
;
3592 * Called after window is opened or resized.
3593 * An expose event is already queued, it will trigger
3594 * MUIM_Draw for us when going back to main loop.
3596 static void WindowShow(struct IClass
*cl
, Object
*obj
)
3598 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3599 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
3600 /* D(bug("WindowShow %s %d\n", __FILE__, __LINE__)); */
3602 _left(data
->wd_RootObject
) = win
->BorderLeft
;
3603 _top(data
->wd_RootObject
) = win
->BorderTop
;
3604 _width(data
->wd_RootObject
) = data
->wd_Width
;
3605 _height(data
->wd_RootObject
) = data
->wd_Height
;
3607 DoMethod(data
->wd_RootObject
, MUIM_Layout
);
3609 ShowRenderInfo(&data
->wd_RenderInfo
);
3610 /* D(bug("zune_imspec_show %s %d\n", __FILE__, __LINE__)); */
3611 zune_imspec_show(data
->wd_Background
, obj
);
3612 DoShowMethod(data
->wd_RootObject
);
3615 static ULONG
WindowOpen(struct IClass
*cl
, Object
*obj
)
3617 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3619 if (!data
->wd_RootObject
)
3622 if (!DoMethod(obj
, MUIM_Window_Setup
))
3625 /* I got display info, so calculate your display dependant data */
3626 if (!DoSetupMethod(data
->wd_RootObject
, &data
->wd_RenderInfo
))
3628 DoMethod(obj
, MUIM_Window_Cleanup
);
3632 /* inquire about sizes */
3633 WindowMinMax(obj
, data
);
3634 WindowSelectDimensions(data
);
3636 /* Decide which menustrip should be used */
3637 if (!data
->wd_ChildMenustrip
)
3638 get(_app(obj
), MUIA_Application_Menustrip
, &data
->wd_Menustrip
);
3640 data
->wd_Menustrip
= data
->wd_ChildMenustrip
;
3642 /* open window here ... */
3643 if (!DisplayWindow(obj
, data
))
3645 /* free display dependant data */
3646 data
->wd_Menustrip
= NULL
;
3647 DoMethod(data
->wd_RootObject
, MUIM_Cleanup
);
3648 DoMethod(obj
, MUIM_Window_Cleanup
);
3652 InstallBackbuffer(cl
, obj
);
3654 data
->wd_Flags
|= MUIWF_OPENED
;
3656 WindowShow(cl
, obj
);
3659 LONG left
, top
, width
, height
;
3661 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
3662 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
,
3663 width
= data
->wd_RenderInfo
.mri_Window
->Width
3664 - data
->wd_RenderInfo
.mri_Window
->BorderRight
- left
;
3665 height
= data
->wd_RenderInfo
.mri_Window
->Height
3666 - data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
3668 /* D(bug("zune_imspec_draw %s %d\n", __FILE__, __LINE__)); */
3669 // D(bug("%d:zune_imspec_draw(%p) l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
3670 // __LINE__, data->wd_Background, left, top, width,
3671 // height, left, top));
3673 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
3674 left
, top
, width
, height
, left
, top
, 0);
3677 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWOBJECT
);
3679 D(bug("MUIC_Window:windowOpen() ActiveObject=%p\n",
3680 data
->wd_ActiveObject
));
3681 if (data
->wd_OldActive
!= NULL
)
3683 set(obj
, MUIA_Window_ActiveObject
, data
->wd_OldActive
);
3689 /**************************************************************************/
3690 /**************************************************************************/
3692 static ULONG
WindowClose(struct IClass
*cl
, Object
*obj
)
3694 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3696 if (data
->wd_ActiveObject
!= NULL
)
3698 data
->wd_OldActive
= data
->wd_ActiveObject
;
3699 set(obj
, MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_None
);
3702 KillHelpBubble(data
, obj
, BUBBLEHELP_TICKER_FIRST
);
3704 /* remove from window */
3705 DoHideMethod(data
->wd_RootObject
);
3706 zune_imspec_hide(data
->wd_Background
);
3708 DeinstallBackbuffer(cl
, obj
);
3710 HideRenderInfo(&data
->wd_RenderInfo
);
3712 /* close here ... */
3713 UndisplayWindow(obj
, data
);
3715 data
->wd_Flags
&= ~MUIWF_OPENED
;
3716 data
->wd_Menustrip
= NULL
;
3718 /* free display dependant data */
3719 DoMethod(data
->wd_RootObject
, MUIM_Cleanup
);
3720 DoMethod(obj
, MUIM_Window_Cleanup
);
3724 /* calculate a new layout
3726 * see Group_ExitChange
3730 IPTR
Window__MUIM_RecalcDisplay(struct IClass
*cl
, Object
*obj
,
3731 struct MUIP_Window_RecalcDisplay
*msg
)
3733 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3734 LONG left
, top
, width
, height
;
3735 BOOL resized
, reshow
= FALSE
;
3736 Object
*current_obj
;
3738 if (!(data
->wd_Flags
& MUIWF_OPENED
))
3741 current_obj
= msg
->originator
;
3743 // typically originator is a group which has been added/removed a child
3744 // calculate minmax of current obj
3745 // if new minmax can accomodate current obj size, stop
3746 // else try with its parent
3747 // the resulting object will get a new layout
3748 // it currently produces some redundant AskMinMax but allows
3749 // to not always relayout the whole window
3751 D(bug("RecalcDisplay on %p\n", current_obj
));
3752 while (current_obj
!= NULL
)
3754 DoMethod(current_obj
, MUIM_AskMinMax
,
3755 (IPTR
) & muiAreaData(current_obj
)->mad_MinMax
);
3756 __area_finish_minmax(current_obj
,
3757 &muiAreaData(current_obj
)->mad_MinMax
);
3759 D(bug("size w = %d, h = %d\n", _width(current_obj
),
3760 _height(current_obj
)));
3761 D(bug("new w = %d-%d, h = %d-%d\n", _minwidth(current_obj
),
3762 _maxwidth(current_obj
), _minheight(current_obj
),
3763 _maxheight(current_obj
)));
3765 if (!_between(_minwidth(current_obj
), _width(current_obj
),
3766 _maxwidth(current_obj
))
3767 || !_between(_minheight(current_obj
), _height(current_obj
),
3768 _maxheight(current_obj
)))
3770 current_obj
= _parent(current_obj
);
3771 D(bug("RecalcDisplay, try parent %p\n", current_obj
));
3775 D(bug("found it\n"));
3781 current_obj
= data
->wd_RootObject
;
3783 WindowMinMax(obj
, data
);
3785 /* Important: current_obj could be hidden, like in an inactive page! */
3786 if (_flags(current_obj
) & MADF_CANDRAW
)
3792 DoHideMethod(current_obj
);
3794 /* resize window ? */
3795 WindowSelectDimensions(data
);
3796 resized
= WindowResize(data
);
3800 /* FIXME: Should we short circuit the following
3801 * if the window size didn't change?
3806 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
3807 _left(data
->wd_RootObject
) = win
->BorderLeft
;
3808 _top(data
->wd_RootObject
) = win
->BorderTop
;
3809 _width(data
->wd_RootObject
) = data
->wd_Width
;
3810 _height(data
->wd_RootObject
) = data
->wd_Height
;
3812 DoMethod(current_obj
, MUIM_Layout
);
3815 DoShowMethod(current_obj
);
3817 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_redraw
==
3818 WINDOW_REDRAW_WITHOUT_CLEAR
)
3821 MUI_Redraw(current_obj
, MADF_DRAWOBJECT
);
3825 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
3826 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
;
3827 width
= data
->wd_RenderInfo
.mri_Window
->Width
3828 - data
->wd_RenderInfo
.mri_Window
->BorderRight
- left
;
3829 height
= data
->wd_RenderInfo
.mri_Window
->Height
3830 - data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
3832 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
3833 left
, top
, width
, height
, left
, top
, 0);
3834 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWALL
);
3837 ActivateObject(data
);
3843 /**************************************************************************
3844 MUIM_AddEventHandler
3845 **************************************************************************/
3846 IPTR
Window__MUIM_AddEventHandler(struct IClass
*cl
, Object
*obj
,
3847 struct MUIP_Window_AddEventHandler
*msg
)
3849 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3851 //D(bug("muimaster.library/window.c: Add Eventhandler %p\n", msg->ehnode));
3853 msg
->ehnode
->ehn_Priority
= msg
->ehnode
->ehn_Priority
;
3854 EnqueueByPriAndAddress((struct List
*)&data
->wd_EHList
,
3855 (struct Node
*)msg
->ehnode
);
3856 ChangeEvents(data
, GetDefaultEvents());
3860 /**************************************************************************
3861 MUIM_RemEventHandler
3862 **************************************************************************/
3863 IPTR
Window__MUIM_RemEventHandler(struct IClass
*cl
, Object
*obj
,
3864 struct MUIP_Window_RemEventHandler
*msg
)
3866 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3868 //D(bug("muimaster.library/window.c: Rem Eventhandler %p\n", msg->ehnode));
3870 Remove((struct Node
*)msg
->ehnode
);
3871 ChangeEvents(data
, GetDefaultEvents());
3875 /**************************************************************************
3876 Note that this is MUIM_Window_Setup, not MUIM_Setup
3877 **************************************************************************/
3878 IPTR
Window__MUIM_Setup(struct IClass
*cl
, Object
*obj
, Msg msg
)
3880 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3882 if (!SetupRenderInfo(obj
, data
, &data
->wd_RenderInfo
))
3885 data
->wd_Background
=
3886 zune_imspec_setup(MUII_WindowBack
, &data
->wd_RenderInfo
);
3888 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_redraw
==
3889 WINDOW_REDRAW_WITH_CLEAR
)
3890 data
->wd_Flags
|= MUIWF_ERASEAREA
;
3895 /**************************************************************************
3897 **************************************************************************/
3898 IPTR
Window__MUIM_Cleanup(struct IClass
*cl
, Object
*obj
, Msg msg
)
3900 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3902 zune_imspec_cleanup(data
->wd_Background
);
3906 DeleteDragNDrop(data
->wd_dnd
);
3907 data
->wd_dnd
= NULL
;
3910 CleanupRenderInfo(obj
, data
, &data
->wd_RenderInfo
);
3915 /**************************************************************************
3916 This adds the the control char handler and also do the MUIA_CycleChain
3917 stuff. Orginal MUI does this in an other way.
3918 **************************************************************************/
3919 IPTR
Window__MUIM_AddControlCharHandler(struct IClass
*cl
, Object
*obj
,
3920 struct MUIP_Window_AddControlCharHandler
*msg
)
3922 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3923 struct ObjNode
*node
;
3925 if (msg
->ccnode
->ehn_Events
)
3927 msg
->ccnode
->ehn_Priority
= msg
->ccnode
->ehn_Priority
;
3928 Enqueue((struct List
*)&data
->wd_CCList
,
3929 (struct Node
*)msg
->ccnode
);
3931 /* Due to the lack of a better idea ... */
3932 if (muiAreaData(msg
->ccnode
->ehn_Object
)->mad_Flags
& MADF_CYCLECHAIN
)
3934 node
= AllocPooled(data
->wd_MemoryPool
, sizeof(struct ObjNode
));
3937 node
->obj
= msg
->ccnode
->ehn_Object
;
3938 AddTail((struct List
*)&data
->wd_CycleChain
,
3939 (struct Node
*)node
);
3945 /**************************************************************************
3946 MUIM_RemControlCharHandler
3947 **************************************************************************/
3948 IPTR
Window__MUIM_RemControlCharHandler(struct IClass
*cl
, Object
*obj
,
3949 struct MUIP_Window_RemControlCharHandler
*msg
)
3951 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3952 struct ObjNode
*node
=
3953 FindObjNode(&data
->wd_CycleChain
, msg
->ccnode
->ehn_Object
);
3955 if (msg
->ccnode
->ehn_Events
)
3956 Remove((struct Node
*)msg
->ccnode
);
3960 /* Remove from the chain list */
3961 Remove((struct Node
*)node
);
3962 FreePooled(data
->wd_MemoryPool
, node
, sizeof(struct ObjNode
));
3968 /**************************************************************************
3970 **************************************************************************/
3971 IPTR
Window__MUIM_DragObject(struct IClass
*cl
, Object
*obj
,
3972 struct MUIP_Window_DragObject
*msg
)
3974 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3977 struct DragNDrop
*dnd
;
3978 struct MUI_DragImage
*di
;
3979 struct BitMapNode
*bmn
;
3981 if (!(dnd
= CreateDragNDropA(NULL
)))
3985 (struct MUI_DragImage
*)DoMethod(msg
->obj
,
3986 MUIM_CreateDragImage
, -msg
->touchx
, -msg
->touchy
,
3989 DeleteDragNDrop(dnd
);
3994 DoMethod(msg
->obj
, MUIM_DeleteDragImage
, (IPTR
) di
);
3995 DeleteDragNDrop(dnd
);
3999 if (!(bmn
= CreateBitMapNodeA(TAGLIST(
4000 GUI_BitMap
, (IPTR
)di
->bm
,
4001 GUI_LeftOffset
, di
->touchx
,
4002 GUI_TopOffset
, di
->touchy
,
4003 GUI_Width
, di
->width
,
4004 GUI_Height
, di
->height
,
4005 GUI_SourceAlpha
, !!(di
->flags
& MUIF_DRAGIMAGE_SOURCEALPHA
)))))
4007 DoMethod(msg
->obj
, MUIM_DeleteDragImage
, (IPTR
) di
);
4008 DeleteDragNDrop(dnd
);
4012 AttachBitMapNode(dnd
, bmn
);
4014 if (!PrepareDragNDrop(dnd
, data
->wd_RenderInfo
.mri_Screen
))
4016 DoMethod(msg
->obj
, MUIM_DeleteDragImage
, (IPTR
) di
);
4017 DeleteDragNDrop(dnd
);
4021 muiAreaData(msg
->obj
)->mad_Flags
|= MADF_DRAGGING
;
4023 data
->wd_DragObject
= msg
->obj
;
4025 data
->wd_DragImage
= di
;
4031 /**************************************************************************
4033 **************************************************************************/
4034 IPTR
Window__MUIM_AllocGadgetID(struct IClass
*cl
, Object
*obj
,
4035 struct MUIP_Window_AllocGadgetID
*msg
)
4037 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4038 struct IDNode
*newnode
;
4040 newnode
= AllocPooled(data
->wd_MemoryPool
, sizeof(struct IDNode
));
4046 if (IsListEmpty(&data
->wd_IDList
))
4049 AddHead((struct List
*)&data
->wd_IDList
,
4050 (struct Node
*)&newnode
->node
);
4056 for (mn
= data
->wd_IDList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
4058 struct IDNode
*idn
= (struct IDNode
*)mn
;
4064 Insert((struct List
*)&data
->wd_IDList
,
4065 (struct Node
*)&newnode
->node
, (struct Node
*)mn
);
4072 /**************************************************************************
4074 **************************************************************************/
4075 IPTR
Window__MUIM_FreeGadgetID(struct IClass
*cl
, Object
*obj
,
4076 struct MUIP_Window_FreeGadgetID
*msg
)
4078 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4081 for (mn
= data
->wd_IDList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
4083 struct IDNode
*idn
= (struct IDNode
*)mn
;
4084 if (msg
->gadgetid
== idn
->id
)
4086 Remove((struct Node
*)idn
);
4087 FreePooled(data
->wd_MemoryPool
, idn
, sizeof(struct IDNode
));
4096 /**************************************************************************
4097 MUIM_Window_GetMenuCheck
4098 **************************************************************************/
4099 IPTR
Window__MUIM_GetMenuCheck(struct IClass
*cl
, Object
*obj
,
4100 struct MUIP_Window_GetMenuCheck
*msg
)
4103 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4105 Object
*strip
= data
->wd_ChildMenustrip
;
4107 strip
= data
->wd_Menustrip
;
4110 if (!(item
= (Object
*) DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
)))
4112 get(item
, MUIA_Menuitem_Checked
, &stat
);
4116 /**************************************************************************
4117 MUIM_Window_SetMenuCheck
4118 **************************************************************************/
4119 IPTR
Window__MUIM_SetMenuCheck(struct IClass
*cl
, Object
*obj
,
4120 struct MUIP_Window_SetMenuCheck
*msg
)
4122 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4124 Object
*strip
= data
->wd_ChildMenustrip
;
4126 strip
= data
->wd_Menustrip
;
4129 if (!(item
= (Object
*) DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
)))
4131 set(item
, MUIA_Menuitem_Checked
, msg
->stat
);
4135 /**************************************************************************
4136 MUIM_Window_GetMenuState
4137 **************************************************************************/
4138 IPTR
Window__MUIM_GetMenuState(struct IClass
*cl
, Object
*obj
,
4139 struct MUIP_Window_GetMenuState
*msg
)
4142 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4144 Object
*strip
= data
->wd_ChildMenustrip
;
4146 strip
= data
->wd_Menustrip
;
4149 if (!(item
= (Object
*) DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
)))
4151 get(item
, MUIA_Menuitem_Enabled
, &stat
);
4155 /**************************************************************************
4156 MUIM_Window_SetMenuState
4157 **************************************************************************/
4158 IPTR
Window__MUIM_SetMenuState(struct IClass
*cl
, Object
*obj
,
4159 struct MUIP_Window_SetMenuState
*msg
)
4161 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4163 Object
*strip
= data
->wd_ChildMenustrip
;
4165 strip
= data
->wd_Menustrip
;
4168 if (!(item
= (Object
*) DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
)))
4170 set(item
, MUIA_Menuitem_Enabled
, msg
->stat
);
4174 /**************************************************************************
4175 MUIM_Window_DrawBackground
4176 **************************************************************************/
4177 IPTR
Window__MUIM_DrawBackground(struct IClass
*cl
, Object
*obj
,
4178 struct MUIP_Window_DrawBackground
*msg
)
4180 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4181 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
4184 // D(bug("%d:zune_imspec_draw(%p) l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
4185 // __LINE__, data->wd_Background, msg->left, msg->top, msg->width,
4186 // msg->height, msg->xoffset, msg->yoffset));
4187 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
4188 msg
->left
, msg
->top
, msg
->width
, msg
->height
,
4189 msg
->xoffset
, msg
->yoffset
, 0);
4193 /**************************************************************************
4195 **************************************************************************/
4196 IPTR
Window__MUIM_ToFront(struct IClass
*cl
, Object
*obj
, Msg msg
)
4198 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4199 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
4202 WindowToFront(data
->wd_RenderInfo
.mri_Window
);
4206 /**************************************************************************
4208 **************************************************************************/
4209 IPTR
Window__MUIM_ToBack(struct IClass
*cl
, Object
*obj
, Msg msg
)
4211 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4212 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
4215 WindowToBack(data
->wd_RenderInfo
.mri_Window
);
4219 /**************************************************************************
4220 MUIM_Window_ScreenToBack
4221 **************************************************************************/
4222 IPTR
Window__MUIM_ScreenToBack(struct IClass
*cl
, Object
*obj
, Msg msg
)
4224 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4225 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
4228 ScreenToBack(data
->wd_RenderInfo
.mri_Screen
);
4232 /**************************************************************************
4233 MUIM_Window_ScreenToFront
4234 **************************************************************************/
4235 IPTR
Window__MUIM_ScreenToFront(struct IClass
*cl
, Object
*obj
, Msg msg
)
4237 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4238 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
4241 ScreenToFront(data
->wd_RenderInfo
.mri_Screen
);
4245 /**************************************************************************
4246 MUIM_Window_ActionIconify
4247 **************************************************************************/
4248 IPTR
Window__MUIM_ActionIconify(struct IClass
*cl
, Object
*obj
, Msg msg
)
4250 set(_app(obj
), MUIA_Application_Iconified
, TRUE
);
4256 /* Loads ENV: prefs, add a Window_ID chunk in the MUIW chunk, if no MUIW chunk
4257 * then create it at the same level as MUIC chunk, save prefs.
4258 * Do the same for ENVARC:
4259 * MUIW chunk layout:
4261 * 00 00 00 30 (chunk length for a single window, 0x30L big endian)
4264 * xx xx yy yy (X, Y)
4265 * ww ww hh hh (Width, Height)
4266 * ax ax ay ay (AltX, AltY)
4267 * aw aw ah ah (AltWidth, AltHeight)
4275 static void RememberWindowPosition(Object
*winobj
, ULONG id
)
4281 /* Loads ENV: prefs, remove our Window_ID chunk from the MUIW chunk,
4283 * Do the same for ENVARC:
4284 * This function shouldn't really be in window.c, but rather in a file dealing
4285 * with prefs file stuff.
4287 static void ForgetWindowPosition(Object
*winobj
, ULONG id
)
4293 /**************************************************************************
4294 MUIM_Window_Snapshot
4295 **************************************************************************/
4296 IPTR
Window__MUIM_Snapshot(struct IClass
*cl
, Object
*obj
,
4297 struct MUIP_Window_Snapshot
*msg
)
4299 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4300 struct windowpos winp
;
4303 winp
.id
= data
->wd_ID
;
4304 w
= data
->wd_RenderInfo
.mri_Window
;
4307 winp
.x1
= w
->LeftEdge
;
4308 winp
.y1
= w
->TopEdge
;
4309 winp
.w1
= w
->GZZWidth
;
4310 winp
.h1
= w
->GZZHeight
;
4314 winp
.h2
= 0; //to do save alt dims
4316 set(_app(obj
), MUIA_Application_SetWinPos
, &winp
);
4320 RememberWindowPosition(obj
, data
->wd_ID
);
4322 ForgetWindowPosition(obj
, data
->wd_ID
);
4326 /**************************************************************************
4327 MUIM_Window_UpdateMenu
4328 **************************************************************************/
4329 IPTR
Window__MUIM_UpdateMenu(struct IClass
*cl
, Object
*obj
, Msg msg
)
4331 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4333 struct Menu
*menu
= NULL
;
4334 struct NewMenu
*newmenu
= NULL
;
4335 APTR visinfo
= NULL
;
4336 struct Window
*win
= NULL
;
4338 if (data
->wd_Menustrip
) // only open windows can have a menustrip
4341 GetVisualInfoA(data
->wd_RenderInfo
.mri_Screen
, NULL
)))
4343 win
= data
->wd_RenderInfo
.mri_Window
;
4344 ClearMenuStrip(win
);
4347 FreeMenus(data
->wd_Menu
);
4348 data
->wd_Menu
= NULL
;
4351 get(data
->wd_Menustrip
, MUIA_Menuitem_NewMenu
, &newmenu
);
4354 if ((menu
= CreateMenusA(newmenu
, NULL
)))
4356 struct TagItem tags
[] = {
4357 {GTMN_NewLookMenus
, TRUE
},
4360 LayoutMenusA(menu
, visinfo
, tags
);
4361 data
->wd_Menu
= menu
;
4362 SetMenuStrip(win
, menu
);
4365 FreeVisualInfo(visinfo
);
4372 /**************************************************************************
4374 **************************************************************************/
4375 IPTR
Window__MUIM_Refresh(struct IClass
*cl
, Object
*obj
, Msg msg
)
4377 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4379 RefreshWindow(obj
, data
);
4384 /**************************************************************************
4385 MUIM_Export : to export an object's "contents" to a dataspace object.
4386 **************************************************************************/
4387 static IPTR
Window__MUIM_Export(struct IClass
*cl
, Object
*obj
,
4388 struct MUIP_Export
*msg
)
4390 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4391 DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
4396 /**************************************************************************
4397 MUIM_Import : to import an object's "contents" from a dataspace object.
4398 **************************************************************************/
4399 static IPTR
Window__MUIM_Import(struct IClass
*cl
, Object
*obj
,
4400 struct MUIP_Import
*msg
)
4402 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4403 DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
4407 BOOPSI_DISPATCHER(IPTR
, Window_Dispatcher
, cl
, obj
, msg
)
4409 switch (msg
->MethodID
)
4412 return Window__OM_NEW(cl
, obj
, (struct opSet
*)msg
);
4414 return Window__OM_DISPOSE(cl
, obj
, msg
);
4416 return Window__OM_SET(cl
, obj
, (struct opSet
*)msg
);
4418 return Window__OM_GET(cl
, obj
, (struct opGet
*)msg
);
4419 case MUIM_FindUData
:
4420 return Window__MUIM_FindUData(cl
, obj
,
4421 (struct MUIP_FindUData
*)msg
);
4423 return Window__MUIM_GetUData(cl
, obj
, (struct MUIP_GetUData
*)msg
);
4425 return Window__MUIM_SetUData(cl
, obj
, (struct MUIP_SetUData
*)msg
);
4426 case MUIM_SetUDataOnce
:
4427 return Window__MUIM_SetUDataOnce(cl
, obj
,
4428 (struct MUIP_SetUDataOnce
*)msg
);
4429 case MUIM_Window_AddEventHandler
:
4430 return Window__MUIM_AddEventHandler(cl
, obj
, (APTR
) msg
);
4431 case MUIM_Window_RemEventHandler
:
4432 return Window__MUIM_RemEventHandler(cl
, obj
, (APTR
) msg
);
4433 case MUIM_ConnectParent
:
4434 return Window__MUIM_ConnectParent(cl
, obj
, (APTR
) msg
);
4435 case MUIM_DisconnectParent
:
4436 return Window__MUIM_DisconnectParent(cl
, obj
, (APTR
) msg
);
4437 case MUIM_Window_RecalcDisplay
:
4438 return Window__MUIM_RecalcDisplay(cl
, obj
, (APTR
) msg
);
4439 case MUIM_Window_Setup
:
4440 return Window__MUIM_Setup(cl
, obj
, (APTR
) msg
);
4441 case MUIM_Window_Cleanup
:
4442 return Window__MUIM_Cleanup(cl
, obj
, (APTR
) msg
);
4443 case MUIM_Window_AddControlCharHandler
:
4444 return Window__MUIM_AddControlCharHandler(cl
, obj
, (APTR
) msg
);
4445 case MUIM_Window_RemControlCharHandler
:
4446 return Window__MUIM_RemControlCharHandler(cl
, obj
, (APTR
) msg
);
4447 case MUIM_Window_DragObject
:
4448 return Window__MUIM_DragObject(cl
, obj
, (APTR
) msg
);
4449 case MUIM_Window_AllocGadgetID
:
4450 return Window__MUIM_AllocGadgetID(cl
, obj
, (APTR
) msg
);
4451 case MUIM_Window_FreeGadgetID
:
4452 return Window__MUIM_FreeGadgetID(cl
, obj
, (APTR
) msg
);
4453 case MUIM_Window_GetMenuCheck
:
4454 return Window__MUIM_GetMenuCheck(cl
, obj
, (APTR
) msg
);
4455 case MUIM_Window_SetMenuCheck
:
4456 return Window__MUIM_SetMenuCheck(cl
, obj
, (APTR
) msg
);
4457 case MUIM_Window_GetMenuState
:
4458 return Window__MUIM_GetMenuState(cl
, obj
, (APTR
) msg
);
4459 case MUIM_Window_SetMenuState
:
4460 return Window__MUIM_SetMenuState(cl
, obj
, (APTR
) msg
);
4461 case MUIM_Window_DrawBackground
:
4462 return Window__MUIM_DrawBackground(cl
, obj
, (APTR
) msg
);
4463 case MUIM_Window_ToFront
:
4464 return Window__MUIM_ToFront(cl
, obj
, (APTR
) msg
);
4465 case MUIM_Window_ToBack
:
4466 return Window__MUIM_ToBack(cl
, obj
, (APTR
) msg
);
4467 case MUIM_Window_ScreenToFront
:
4468 return Window__MUIM_ScreenToFront(cl
, obj
, (APTR
) msg
);
4469 case MUIM_Window_ScreenToBack
:
4470 return Window__MUIM_ScreenToBack(cl
, obj
, (APTR
) msg
);
4471 case MUIM_Window_ActionIconify
:
4472 return Window__MUIM_ActionIconify(cl
, obj
, (APTR
) msg
);
4473 case MUIM_Window_Snapshot
:
4474 return Window__MUIM_Snapshot(cl
, obj
, (APTR
) msg
);
4475 case MUIM_Window_UpdateMenu
:
4476 return Window__MUIM_UpdateMenu(cl
, obj
, (APTR
) msg
);
4477 case MUIM_Window_Refresh
:
4478 return Window__MUIM_Refresh(cl
, obj
, (APTR
) msg
);
4480 return Window__MUIM_Export(cl
, obj
, (APTR
) msg
);
4482 return Window__MUIM_Import(cl
, obj
, (APTR
) msg
);
4485 return DoSuperMethodA(cl
, obj
, msg
);
4487 BOOPSI_DISPATCHER_END
4492 const struct __MUIBuiltinClass _MUI_Window_desc
=
4496 sizeof(struct MUI_WindowData
),
4497 (void *) Window_Dispatcher