2 Copyright 1999, David Le Corfec.
3 Copyright 2002-2012, 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>
30 #define MUI_OBSOLETE /* for the obsolete menu stuff */
34 #include "classes/window.h"
35 #include "classes/area.h"
37 #include "datatypescache.h"
39 #include "dragndrop.h"
41 #include "muimaster_intern.h"
46 extern struct Library
*MUIMasterBase
;
48 static const int __version
= 1;
49 static const int __revision
= 1;
51 #define IM(x) ((struct Image*)(x))
52 #define G(x) ((struct Gadget*)(x))
53 #define GADGETID(x) (((struct Gadget*)(x))->GadgetID)
55 /* this is for the cycle list */
62 /* For the gadget ids */
69 struct MUI_ImageSpec_intern
;
73 struct MUI_RenderInfo wd_RenderInfo
;
74 struct MUI_MinMax wd_MinMax
;
75 struct IBox wd_AltDim
; /* zoomed dimensions */
76 BOOL wd_ZoomGadget
; /* enable/disable zoomgadget (altdim stuff) */
77 APTR wd_MemoryPool
; /* for nodes and stuff to deallocate at
79 struct MinList wd_CycleChain
; /* objects activated with tab */
80 struct MinList wd_EHList
; /* event handlers */
81 struct MinList wd_CCList
; /* control chars */
82 struct MinList wd_IDList
; /* gadget ids */
83 ULONG wd_Events
; /* events received */
84 ULONG wd_CrtFlags
; /* window creation flags, see below */
85 Object
*wd_ActiveObject
; /* the active object */
86 Object
*wd_OldActive
; /* active object before window was closed */
87 APTR wd_DefaultObject
;
90 STRPTR wd_ScreenTitle
;
91 LONG wd_Height
; /* Current dimensions */
95 LONG wd_ReqHeight
; /* given by programmer */
97 APTR wd_RootObject
; /* unique child */
98 ULONG wd_Flags
; /* various status flags */
99 struct MUI_ImageSpec_intern
*wd_Background
;
100 ULONG wd_DisabledKeys
;
101 BOOL wd_NoMenus
; /* MUIA_Window_NoMenus */
103 Object
*wd_DragObject
; /* the object which is being dragged */
104 struct Window
*wd_DropWindow
; /* the destination window, for faster
106 Object
*wd_DropObject
; /* the destination object */
107 struct DragNDrop
*wd_dnd
;
108 struct MUI_DragImage
*wd_DragImage
;
110 Object
*wd_Menustrip
; /* The menustrip object which is actually
111 * used (either apps or windows or NULL) */
112 Object
*wd_ChildMenustrip
; /* If window has an own Menustrip */
113 struct Menu
*wd_Menu
; /* the intuition menustrip */
117 Object
*wd_DownButton
;
119 Object
*wd_HorizProp
;
120 Object
*wd_LeftButton
;
121 Object
*wd_RightButton
;
122 Object
*wd_RefWindow
;
124 Object
*wd_MUIGadget
;
126 Object
*wd_HelpObject
;
130 struct Screen
*wd_UserScreen
;
131 STRPTR wd_UserPublicScreen
;
132 LONG wd_XStore
; /* store MUIV_Window_LeftEdge_Centered Tags
133 * etc. because wd_X is overwritten by a
134 * value in CalcDimension. Popup windows work
135 * OK on AmiGG when main window is moved */
138 WORD wd_SleepCount
; /* MUIA_Window_Sleep nests */
141 #ifndef WFLG_SIZEGADGET
143 #define WFLG_CLOSEGADGET (1<<0) /* has close gadget */
144 #define WFLG_SIZEGADGET (1<<1) /* has size gadget */
145 #define WFLG_BACKDROP (1<<2) /* is backdrop window */
146 #define WFLG_BORDERLESS (1<<3) /* has no borders */
147 #define WFLG_DEPTHGADGET (1<<4) /* has depth gadget */
148 #define WFLG_DRAGBAR (1<<5) /* is draggable */
149 #define WFLG_SIZEBRIGHT (1<<6) /* size gadget is in right border */
154 #define MUIWF_OPENED (1<<0) /* window currently opened */
155 #define MUIWF_HIDDEN (1<<1) /* window currently iconified */
156 #define MUIWF_ACTIVE (1<<2) /* window currently active */
157 #define MUIWF_RESIZING (1<<4) /* window currently resizing,
158 * for simple refresh */
159 #define MUIWF_DONTACTIVATE (1<<7) /* do not activate the window when
161 #define MUIWF_USERIGHTSCROLLER (1<<8) /* should have right scroller */
162 #define MUIWF_USEBOTTOMSCROLLER (1<<9) /* should have bottom scroller */
163 #define MUIWF_ERASEAREA (1<<10) /* Erase area after a window resize */
164 #define MUIWF_ISAPPWINDOW (1<<11) /* Is an AppWindow */
165 #define MUIWF_ISSUBWINDOW (1<<12) /* Don't get automatically disposed
167 #define MUIWF_BUBBLEMODE (1<<13) /* Quick bubble mode. Bubbles appear
168 * quick when moving */
169 #define MUIWF_OPENONUNHIDE (1<<14) /* Open the window when unhiding */
170 #define MUIWF_SCREENLOCKED (1<<15) /* A pub screen was locked in
171 * SetupRenderInfo. Unlock it in
172 * CleanupRenderInfo! */
173 #define MUIWF_OBJECTGOACTIVESENT (1<<16) /* A MUIM_GoActive msg was sent to
174 * window's active object */
175 #define MUIWF_TOOLBOX (1<<17) /* Window should be opened as
178 #define BUBBLEHELP_TICKER_FIRST 10
179 #define BUBBLEHELP_TICKER_LATER 3
183 struct MUI_NotifyData mnd
;
184 struct MUI_WindowData mwd
;
187 #define muiWindowData(obj) (&(((struct __dummyXFC3__ *)(obj))->mwd))
189 static ULONG
DoHalfshineGun(ULONG a
, ULONG b
)
191 ULONG val
= ((((a
) >> 24) + 3 * ((b
) >> 24)) / 4);
192 val
= val
+ (val
<< 8) + (val
<< 16) + (val
<< 24);
196 static ULONG
DoHalfshadowGun(ULONG a
, ULONG b
)
198 ULONG val
= ((((a
) >> 24) + 5 * ((b
) >> 24)) / 6);
199 val
= val
+ (val
<< 8) + (val
<< 16) + (val
<< 24);
203 static Object
*CreateSysimage(struct DrawInfo
*dri
, ULONG which
)
205 return NewObject(NULL
, "sysiclass",
206 SYSIA_DrawInfo
, (IPTR
) dri
, SYSIA_Which
, which
, TAG_DONE
);
209 static void EnqueueByPriAndAddress(struct List
*list
, struct Node
*node
)
211 struct Node
*scannode
;
213 /* Sort by priority and by node address, so that a
214 "remove - modify - enqueue" sequence will re-add
215 the node at the same place in the list it was
217 ForeachNode(list
, scannode
)
219 if (((struct Node
*)node
)->ln_Pri
> scannode
->ln_Pri
)
221 if (((struct Node
*)node
)->ln_Pri
== scannode
->ln_Pri
)
223 if ((IPTR
) node
> (IPTR
) scannode
)
228 Insert(list
, (struct Node
*)node
, scannode
->ln_Pred
);
231 static BOOL
InitCustomFrames(Object
*obj
, struct MUI_RenderInfo
*mri
)
235 for (i
= 0; i
< 16; i
++)
237 mri
->mri_FrameImage
[i
] = NULL
;
240 mri
->mri_FrameImage
[0] =
241 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
242 customframe_config_1
, mri
->mri_Screen
);
243 mri
->mri_FrameImage
[1] =
244 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
245 customframe_config_2
, mri
->mri_Screen
);
246 mri
->mri_FrameImage
[2] =
247 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
248 customframe_config_3
, mri
->mri_Screen
);
249 mri
->mri_FrameImage
[3] =
250 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
251 customframe_config_4
, mri
->mri_Screen
);
252 mri
->mri_FrameImage
[4] =
253 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
254 customframe_config_5
, mri
->mri_Screen
);
255 mri
->mri_FrameImage
[5] =
256 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
257 customframe_config_6
, mri
->mri_Screen
);
258 mri
->mri_FrameImage
[6] =
259 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
260 customframe_config_7
, mri
->mri_Screen
);
261 mri
->mri_FrameImage
[7] =
262 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
263 customframe_config_8
, mri
->mri_Screen
);
264 mri
->mri_FrameImage
[8] =
265 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
266 customframe_config_9
, mri
->mri_Screen
);
267 mri
->mri_FrameImage
[9] =
268 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
269 customframe_config_10
, mri
->mri_Screen
);
270 mri
->mri_FrameImage
[10] =
271 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
272 customframe_config_11
, mri
->mri_Screen
);
273 mri
->mri_FrameImage
[11] =
274 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
275 customframe_config_12
, mri
->mri_Screen
);
276 mri
->mri_FrameImage
[12] =
277 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
278 customframe_config_13
, mri
->mri_Screen
);
279 mri
->mri_FrameImage
[13] =
280 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
281 customframe_config_14
, mri
->mri_Screen
);
282 mri
->mri_FrameImage
[14] =
283 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
284 customframe_config_15
, mri
->mri_Screen
);
285 mri
->mri_FrameImage
[15] =
286 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
287 customframe_config_16
, mri
->mri_Screen
);
292 static void DisposeCustomFrames(struct MUI_RenderInfo
*mri
)
296 for (i
= 0; i
< 16; i
++)
298 dispose_custom_frame(mri
->mri_FrameImage
[i
]);
300 mri
->mri_FrameImage
[i
] = NULL
;
304 static BOOL
SetupRenderInfo(Object
*obj
, struct MUI_WindowData
*data
,
305 struct MUI_RenderInfo
*mri
)
307 ULONG rgbtable
[3 * 3];
312 /* TODO: Move this whole screen locking/opening stuff into the
313 * application class by creating methods for this purpose */
315 /* If no user screen has been specified try to open the application
317 if (!data
->wd_UserScreen
)
319 ULONG screenmodeid
= muiGlobalInfo(obj
)->mgi_Prefs
->screenmodeid
;
321 if (screenmodeid
!= ~0)
323 if (!muiGlobalInfo(obj
)->mgi_CustomScreen
)
325 muiGlobalInfo(obj
)->mgi_CustomScreen
= OpenScreenTags
327 SA_DisplayID
, screenmodeid
,
329 SA_FullPalette
, TRUE
, SA_LikeWorkbench
, TRUE
, TAG_DONE
);
330 /* It's fine if this fails as there is a fallback case below */
333 data
->wd_UserScreen
= muiGlobalInfo(obj
)->mgi_CustomScreen
;
336 if (data
->wd_UserScreen
)
338 mri
->mri_Screen
= data
->wd_UserScreen
;
342 if (data
->wd_UserPublicScreen
)
344 mri
->mri_Screen
= LockPubScreen(data
->wd_UserPublicScreen
);
346 else if (muiGlobalInfo(obj
)->mgi_Prefs
->publicscreen_name
347 && muiGlobalInfo(obj
)->mgi_Prefs
->publicscreen_name
[0])
350 LockPubScreen(muiGlobalInfo(obj
)->mgi_Prefs
->
352 // FIXME: open the public screen if necessary
355 if (mri
->mri_Screen
== NULL
)
357 mri
->mri_Screen
= LockPubScreen(NULL
);
358 if (mri
->mri_Screen
== NULL
)
364 // FIXME: is this the right place for this action?
366 && muiGlobalInfo(obj
)->mgi_Prefs
->publicscreen_pop_to_front
)
368 ScreenToFront(mri
->mri_Screen
);
371 data
->wd_Flags
|= MUIWF_SCREENLOCKED
;
374 if (!(mri
->mri_DrawInfo
= GetScreenDrawInfo(mri
->mri_Screen
)))
376 if (data
->wd_Flags
& MUIWF_SCREENLOCKED
)
378 UnlockPubScreen(NULL
, mri
->mri_Screen
);
379 data
->wd_Flags
&= ~MUIWF_SCREENLOCKED
;
384 if (!InitCustomFrames(obj
, mri
))
386 if (data
->wd_Flags
& MUIWF_SCREENLOCKED
)
388 UnlockPubScreen(NULL
, mri
->mri_Screen
);
389 data
->wd_Flags
&= ~MUIWF_SCREENLOCKED
;
394 mri
->mri_Colormap
= mri
->mri_Screen
->ViewPort
.ColorMap
;
395 mri
->mri_ScreenWidth
= mri
->mri_Screen
->Width
;
396 mri
->mri_ScreenHeight
= mri
->mri_Screen
->Height
;
398 if (mri
->mri_ScreenWidth
/ mri
->mri_ScreenHeight
< 2)
400 mri
->mri_Flags
|= MUIMRI_THINFRAMES
;
403 if (GetBitMapAttr(mri
->mri_Screen
->RastPort
.BitMap
, BMA_DEPTH
) >= 15)
405 mri
->mri_Flags
|= MUIMRI_TRUECOLOR
;
408 mri
->mri_PensStorage
[MPEN_SHINE
] =
409 mri
->mri_DrawInfo
->dri_Pens
[SHINEPEN
];
410 mri
->mri_PensStorage
[MPEN_BACKGROUND
] =
411 mri
->mri_DrawInfo
->dri_Pens
[BACKGROUNDPEN
];
412 mri
->mri_PensStorage
[MPEN_SHADOW
] =
413 mri
->mri_DrawInfo
->dri_Pens
[SHADOWPEN
];
414 mri
->mri_PensStorage
[MPEN_TEXT
] = mri
->mri_DrawInfo
->dri_Pens
[TEXTPEN
];
415 mri
->mri_PensStorage
[MPEN_FILL
] = mri
->mri_DrawInfo
->dri_Pens
[FILLPEN
];
417 GetRGB32(mri
->mri_Colormap
, mri
->mri_DrawInfo
->dri_Pens
[SHINEPEN
], 1,
419 GetRGB32(mri
->mri_Colormap
, mri
->mri_DrawInfo
->dri_Pens
[BACKGROUNDPEN
],
421 GetRGB32(mri
->mri_Colormap
, mri
->mri_DrawInfo
->dri_Pens
[SHADOWPEN
], 1,
424 mri
->mri_PensStorage
[MPEN_HALFSHINE
] = ObtainBestPenA
426 DoHalfshineGun(rgbtable
[0], rgbtable
[3]),
427 DoHalfshineGun(rgbtable
[1], rgbtable
[4]),
428 DoHalfshineGun(rgbtable
[2], rgbtable
[5]), NULL
);
430 mri
->mri_PensStorage
[MPEN_HALFSHADOW
] = ObtainBestPenA
432 DoHalfshadowGun(rgbtable
[6], rgbtable
[3]),
433 DoHalfshadowGun(rgbtable
[7], rgbtable
[4]),
434 DoHalfshadowGun(rgbtable
[8], rgbtable
[5]), NULL
);
436 /* I'm really not sure that MUI does this for MPEN_MARK, but it seems
437 * mostly acceptable -dlc */
438 mri
->mri_PensStorage
[MPEN_MARK
] = ObtainBestPenA
439 (mri
->mri_Colormap
, 0xf4f4f4f4, 0xb5b5b5b5, 0x8b8b8b8b, NULL
);
441 mri
->mri_Pens
= mri
->mri_PensStorage
;
443 for (i
= 0; i
< -MUIV_Font_NegCount
; i
++)
445 mri
->mri_Fonts
[i
] = NULL
;
448 if (data
->wd_Flags
& MUIWF_USEBOTTOMSCROLLER
)
450 mri
->mri_LeftImage
= CreateSysimage(mri
->mri_DrawInfo
, LEFTIMAGE
);
451 mri
->mri_RightImage
= CreateSysimage(mri
->mri_DrawInfo
, RIGHTIMAGE
);
455 mri
->mri_LeftImage
= mri
->mri_RightImage
= NULL
;
458 if (data
->wd_Flags
& MUIWF_USERIGHTSCROLLER
)
460 mri
->mri_UpImage
= CreateSysimage(mri
->mri_DrawInfo
, UPIMAGE
);
461 mri
->mri_DownImage
= CreateSysimage(mri
->mri_DrawInfo
, DOWNIMAGE
);
465 mri
->mri_UpImage
= mri
->mri_DownImage
= NULL
;
468 if ((data
->wd_Flags
& MUIWF_USEBOTTOMSCROLLER
) ||
469 (data
->wd_Flags
& MUIWF_USERIGHTSCROLLER
))
470 mri
->mri_SizeImage
= CreateSysimage(mri
->mri_DrawInfo
, SIZEIMAGE
);
472 mri
->mri_SizeImage
= NULL
;
474 if (data
->wd_CrtFlags
& WFLG_BORDERLESS
)
476 /* Infact borderless windows could also have borders (if they have
477 * a window title e.g. but since they look ugly anyway we ignore it
479 mri
->mri_BorderLeft
= 0;
480 mri
->mri_BorderRight
= 0;
481 mri
->mri_BorderTop
= 0;
482 mri
->mri_BorderBottom
= 0;
486 mri
->mri_BorderLeft
= mri
->mri_Screen
->WBorLeft
;
488 mri
->mri_Screen
->WBorTop
+ mri
->mri_Screen
->Font
->ta_YSize
+ 1;
490 NewObject(NULL
, "sysiclass", SYSIA_DrawInfo
,
491 (IPTR
) mri
->mri_DrawInfo
, SYSIA_Which
, SIZEIMAGE
, TAG_DONE
);
494 GetAttr(IA_Height
, temp_obj
, &val
);
495 DisposeObject(temp_obj
);
496 mri
->mri_BorderBottom
= val
;
499 mri
->mri_BorderBottom
= mri
->mri_Screen
->WBorBottom
;
505 static void CleanupRenderInfo(Object
*obj
, struct MUI_WindowData
*data
,
506 struct MUI_RenderInfo
*mri
)
510 DisposeCustomFrames(mri
);
512 if (mri
->mri_LeftImage
)
514 DisposeObject(mri
->mri_LeftImage
);
515 mri
->mri_LeftImage
= NULL
;
517 if (mri
->mri_RightImage
)
519 DisposeObject(mri
->mri_RightImage
);
520 mri
->mri_RightImage
= NULL
;
522 if (mri
->mri_UpImage
)
524 DisposeObject(mri
->mri_UpImage
);
525 mri
->mri_UpImage
= NULL
;
527 if (mri
->mri_DownImage
)
529 DisposeObject(mri
->mri_DownImage
);
530 mri
->mri_DownImage
= NULL
;
532 if (mri
->mri_SizeImage
)
534 DisposeObject(mri
->mri_SizeImage
);
535 mri
->mri_SizeImage
= NULL
;
538 /* bug("CleanupRenderInfo\n"); */
539 for (i
= 0; i
< -MUIV_Font_NegCount
; i
++)
541 if (mri
->mri_Fonts
[i
])
543 /* bug("CleanupRenderInfo: closing font %p (%s/%d)\n", */
544 /* mri->mri_Fonts[i], */
545 /* mri->mri_Fonts[i]->tf_Message.mn_Node.ln_Name, */
546 /* mri->mri_Fonts[i]->tf_YSize); */
547 CloseFont(mri
->mri_Fonts
[i
]);
548 mri
->mri_Fonts
[i
] = NULL
;
551 ReleasePen(mri
->mri_Colormap
, mri
->mri_PensStorage
[MPEN_MARK
]);
552 ReleasePen(mri
->mri_Colormap
, mri
->mri_PensStorage
[MPEN_HALFSHADOW
]);
553 ReleasePen(mri
->mri_Colormap
, mri
->mri_PensStorage
[MPEN_HALFSHINE
]);
554 FreeScreenDrawInfo(mri
->mri_Screen
, mri
->mri_DrawInfo
);
555 mri
->mri_DrawInfo
= NULL
;
557 /* If a custom screen has been opened by zune, close it as soon as zero
558 * windows are opened. See above for comments about refactorization. */
559 if (muiGlobalInfo(obj
)->mgi_CustomScreen
)
561 BOOL screenclose
= TRUE
;
562 Object
*_app
= _app(obj
);
565 struct List
*store
= NULL
;
566 get(_app
, MUIA_Application_WindowList
, &store
);
569 if (!IsListEmpty(store
))
575 /* If the window's user screen really was the custom screen,
576 * clear the reference */
577 if (data
->wd_UserScreen
== muiGlobalInfo(obj
)->mgi_CustomScreen
)
578 data
->wd_UserScreen
= NULL
;
580 CloseScreen(muiGlobalInfo(obj
)->mgi_CustomScreen
);
581 muiGlobalInfo(obj
)->mgi_CustomScreen
= NULL
;
585 if (data
->wd_Flags
& MUIWF_SCREENLOCKED
)
587 UnlockPubScreen(NULL
, mri
->mri_Screen
);
588 data
->wd_Flags
&= ~MUIWF_SCREENLOCKED
;
590 mri
->mri_Screen
= NULL
;
593 static void ShowRenderInfo(struct MUI_RenderInfo
*mri
)
595 if (mri
->mri_BufferBM
)
597 mri
->mri_RastPort
= &mri
->mri_BufferRP
;
601 mri
->mri_RastPort
= mri
->mri_Window
->RPort
;
605 static void HideRenderInfo(struct MUI_RenderInfo
*mri
)
607 mri
->mri_RastPort
= NULL
;
610 static ULONG
GetDefaultEvents(void)
612 return IDCMP_NEWSIZE
| IDCMP_REFRESHWINDOW
613 | IDCMP_MOUSEBUTTONS
| IDCMP_MOUSEMOVE
| IDCMP_MENUPICK
614 | IDCMP_CLOSEWINDOW
| IDCMP_RAWKEY
| IDCMP_INTUITICKS
615 | IDCMP_ACTIVEWINDOW
| IDCMP_INACTIVEWINDOW
| IDCMP_GADGETUP
;
618 static void ChangeEvents(struct MUI_WindowData
*data
, ULONG new_events
)
621 struct MUI_EventHandlerNode
*ehn
;
622 ULONG old_events
= data
->wd_Events
;
624 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
626 ehn
= (struct MUI_EventHandlerNode
*)mn
;
627 new_events
|= ehn
->ehn_Events
;
630 /* sba: kill the IDCMP_VANILLAKEY flag. MUI doesn't do this but programs
631 ** which use this will behave different if they request for this flag
634 new_events
&= ~IDCMP_VANILLAKEY
;
636 data
->wd_Events
= new_events
;
637 if ((old_events
!= new_events
) && (data
->wd_Flags
& MUIWF_OPENED
))
639 ModifyIDCMP(data
->wd_RenderInfo
.mri_Window
, new_events
);
643 static void CalcWindowPosition(Object
*obj
, struct MUI_WindowData
*data
);
644 static void CreateWindowScrollbars(Object
*obj
,
645 struct MUI_WindowData
*data
);
646 static void CalcAltDimensions(Object
*obj
, struct MUI_WindowData
*data
);
647 static void UndisplayWindow(Object
*obj
, struct MUI_WindowData
*data
);
648 static struct ObjNode
*FindObjNode(struct MinList
*list
, Object
*obj
);
650 static BOOL
DisplayWindow(Object
*obj
, struct MUI_WindowData
*data
)
653 ULONG flags
= data
->wd_CrtFlags
;
655 ULONG backfill
, buttons
;
657 struct Menu
*menu
= NULL
;
658 struct NewMenu
*newmenu
= NULL
;
663 if (!(data
->wd_Flags
& MUIWF_DONTACTIVATE
))
665 flags
|= WFLG_ACTIVATE
;
668 /* Toolboxes are handled differently on AmigaOS */
670 if (data
->wd_Flags
& MUIWF_TOOLBOX
)
671 flags
|= WFLG_TOOLBOX
;
674 if (data
->wd_MinMax
.MinHeight
== data
->wd_MinMax
.MaxHeight
675 && data
->wd_MinMax
.MinWidth
== data
->wd_MinMax
.MaxWidth
)
676 flags
&= ~WFLG_SIZEGADGET
;
678 if (!(flags
& WFLG_SIZEBRIGHT
))
679 flags
|= WFLG_SIZEBBOTTOM
;
681 CalcWindowPosition(obj
, data
);
683 if ((visinfo
= GetVisualInfoA(data
->wd_RenderInfo
.mri_Screen
, NULL
)))
685 if (data
->wd_Menustrip
)
687 get(data
->wd_Menustrip
, MUIA_Menuitem_NewMenu
, &newmenu
);
690 if ((menu
= CreateMenusA(newmenu
, NULL
)))
692 struct TagItem tags
[] = {
693 {GTMN_NewLookMenus
, TRUE
},
694 {TAG_DONE
, (IPTR
) NULL
}
696 LayoutMenusA(menu
, visinfo
, tags
);
700 FreeVisualInfo(visinfo
);
703 CreateWindowScrollbars(obj
, data
);
704 CalcAltDimensions(obj
, data
);
705 altdims
= data
->wd_AltDim
;
707 /* hack to account for border size, as we only know the innersize and
708 * must give the total size.
711 data
->wd_RenderInfo
.mri_Screen
->WBorLeft
+
712 data
->wd_RenderInfo
.mri_Screen
->WBorRight
;
714 data
->wd_RenderInfo
.mri_Screen
->WBorTop
+
715 data
->wd_RenderInfo
.mri_Screen
->WBorBottom
+
716 data
->wd_RenderInfo
.mri_DrawInfo
->dri_Font
->tf_YSize
+ 1;
718 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_redraw
==
719 WINDOW_REDRAW_WITHOUT_CLEAR
)
720 backfill
= WA_BackFill
;
722 backfill
= TAG_IGNORE
;
724 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_refresh
==
725 WINDOW_REFRESH_SMART
)
726 flags
&= ~WFLG_SIMPLE_REFRESH
;
727 set(_app(obj
), MUIA_Application_SearchWinId
, data
->wd_ID
);
728 struct windowpos
*winp
= 0;
729 get(_app(obj
), MUIA_Application_GetWinPos
, &winp
);
732 if (data
->wd_RenderInfo
.mri_ScreenWidth
>
733 (data
->wd_X
+ data
->wd_Width
))
735 data
->wd_X
= winp
->x1
;
736 data
->wd_Width
= winp
->w1
;
738 if (data
->wd_RenderInfo
.mri_ScreenHeight
>
739 (data
->wd_Y
+ data
->wd_Height
))
741 data
->wd_Y
= winp
->y1
;
742 data
->wd_Height
= winp
->h1
;
747 (data
->wd_VertProp
!=
748 NULL
) ? data
->wd_VertProp
: data
->wd_HorizProp
;
749 buttons
= muiGlobalInfo(obj
)->mgi_Prefs
->window_buttons
;
753 WA_Left
, (IPTR
) data
->wd_X
,
754 WA_Top
, (IPTR
) data
->wd_Y
,
755 WA_Flags
, (IPTR
) flags
,
758 TAG_IGNORE
, (IPTR
) data
->wd_Title
,
759 data
->wd_ScreenTitle
?
761 TAG_IGNORE
, (IPTR
) data
->wd_ScreenTitle
,
762 WA_CustomScreen
, (IPTR
) data
->wd_RenderInfo
.mri_Screen
,
763 WA_InnerWidth
, (IPTR
) data
->wd_Width
,
764 WA_InnerHeight
, (IPTR
) data
->wd_Height
,
765 WA_AutoAdjust
, (IPTR
) TRUE
, WA_NewLookMenus
, (IPTR
) TRUE
,
766 /* AmigaOS v4 extension */
768 WA_ToolBox
, (IPTR
) ! !(data
->wd_Flags
& MUIWF_TOOLBOX
),
770 /* MorphOS extensions */
771 #ifdef WA_ExtraGadget_MUI
773 (IPTR
) ((buttons
& MUIV_Window_Button_MUI
) != 0) ? TRUE
: FALSE
,
774 WA_ExtraGadget_PopUp
,
775 (IPTR
) ((buttons
& MUIV_Window_Button_Popup
) != 0) ? TRUE
: FALSE
,
776 WA_ExtraGadget_Snapshot
,
777 (IPTR
) ((buttons
& MUIV_Window_Button_Snapshot
) !=
778 0) ? TRUE
: FALSE
, WA_ExtraGadget_Iconify
,
779 (IPTR
) ((buttons
& MUIV_Window_Button_Iconify
) != 0) ? TRUE
: FALSE
,
783 TAG_IGNORE
, (IPTR
) TRUE
,
784 WA_Gadgets
, (IPTR
) gadgets
,
785 data
->wd_ZoomGadget
?
787 TAG_IGNORE
, (IPTR
) & altdims
,
788 backfill
, (IPTR
) LAYERS_NOBACKFILL
, TAG_DONE
);
793 int hborders
= win
->BorderLeft
+ win
->BorderRight
;
794 int vborders
= win
->BorderTop
+ win
->BorderBottom
;
796 /* recalc window size (which will hopefully equal our requested
798 data
->wd_Width
= win
->GZZWidth
;
799 data
->wd_Height
= win
->GZZHeight
;
801 /* set window limits according to window contents */
803 (win
, data
->wd_MinMax
.MinWidth
+ hborders
,
804 data
->wd_MinMax
.MinHeight
+ vborders
,
805 data
->wd_MinMax
.MaxWidth
+ hborders
,
806 data
->wd_MinMax
.MaxHeight
+ vborders
);
808 win
->UserData
= (BYTE
*) data
->wd_RenderInfo
.mri_WindowObject
;
809 win
->UserPort
= muiGlobalInfo(obj
)->mgi_WindowsPort
;
810 /* Same port for all windows */
811 ModifyIDCMP(win
, data
->wd_Events
);
813 data
->wd_RenderInfo
.mri_Window
= win
;
814 data
->wd_RenderInfo
.mri_VertProp
= data
->wd_VertProp
;
815 data
->wd_RenderInfo
.mri_HorizProp
= data
->wd_HorizProp
;
816 SetDrMd(win
->RPort
, JAM1
);
817 //text is draw wrong in toolbarclass if not set
821 data
->wd_Menu
= menu
;
822 SetMenuStrip(win
, menu
);
825 if (flags
& WFLG_ACTIVATE
)
827 data
->wd_Flags
|= MUIWF_ACTIVE
;
835 UndisplayWindow(obj
, data
);
841 static void UndisplayWindow(Object
*obj
, struct MUI_WindowData
*data
)
843 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
845 ((muiGlobalInfo(obj
)->mgi_Prefs
->window_position
==
846 WINDOW_POSITION_REMEMBER_ON_EXIT
)
847 || (muiGlobalInfo(obj
)->mgi_Prefs
->window_position
==
848 WINDOW_POSITION_SAVE_ON_EXIT
));
850 if (((data
->wd_XStore
>= 0) && (data
->wd_YStore
>= 0)) || prefssnap
)
852 DoMethod(obj
, MUIM_Window_Snapshot
, 0);
855 data
->wd_RenderInfo
.mri_Window
= NULL
;
856 data
->wd_RenderInfo
.mri_VertProp
= NULL
;
857 data
->wd_RenderInfo
.mri_HorizProp
= NULL
;
859 data
->wd_Flags
&= ~MUIWF_ACTIVE
;
863 /* store position and size */
864 if (data
->wd_XStore
>= 0)
865 data
->wd_X
= win
->LeftEdge
;
867 data
->wd_X
= data
->wd_XStore
;
868 if (data
->wd_YStore
>= 0)
869 data
->wd_Y
= win
->TopEdge
;
871 data
->wd_Y
= data
->wd_YStore
;
872 data
->wd_Width
= win
->GZZWidth
;
873 data
->wd_Height
= win
->GZZHeight
;
878 FreeMenus(data
->wd_Menu
);
879 data
->wd_Menu
= NULL
;
884 struct IntuiMessage
*msg
, *succ
;
886 /* remove all messages pending for this window */
889 (struct IntuiMessage
*)win
->UserPort
->mp_MsgList
.lh_Head
;
891 (struct IntuiMessage
*)msg
->ExecMessage
.mn_Node
.
892 ln_Succ
); msg
= succ
)
894 if (msg
->IDCMPWindow
== win
)
896 Remove((struct Node
*)msg
);
897 ReplyMsg((struct Message
*)msg
);
900 win
->UserPort
= NULL
;
905 /* D(bug("before CloseWindow\n")); */
907 /* D(bug("after CloseWindow\n")); */
910 #define DISPOSEGADGET(x) \
913 DoMethod(obj, MUIM_Window_FreeGadgetID,\
914 ((struct Gadget*)x)->GadgetID);\
919 DISPOSEGADGET(data
->wd_VertProp
);
920 DISPOSEGADGET(data
->wd_UpButton
);
921 DISPOSEGADGET(data
->wd_DownButton
);
922 DISPOSEGADGET(data
->wd_HorizProp
);
923 DISPOSEGADGET(data
->wd_LeftButton
);
924 DISPOSEGADGET(data
->wd_RightButton
);
929 /* Initialize data->wd_X and data->wd_Y for DisplayWindow */
930 /* FIXME 20030817: needs some fixing, seems not fully implemented */
931 static void CalcWindowPosition(Object
*obj
, struct MUI_WindowData
*data
)
933 data
->wd_XStore
= data
->wd_X
;
934 data
->wd_YStore
= data
->wd_Y
;
935 if (NULL
== data
->wd_RefWindow
)
937 /* The following calculations are not very correct, the size and
938 * dragbar are ignored also the current overscan view */
939 if (data
->wd_X
== MUIV_Window_LeftEdge_Centered
)
942 (data
->wd_RenderInfo
.mri_Screen
->ViewPort
.DWidth
-
943 data
->wd_Width
) / 2 -
944 data
->wd_RenderInfo
.mri_Screen
->LeftEdge
;
946 else if (data
->wd_X
== MUIV_Window_LeftEdge_Moused
)
948 data
->wd_X
= data
->wd_RenderInfo
.mri_Screen
->MouseX
;
951 if (data
->wd_Y
== MUIV_Window_TopEdge_Centered
)
954 (data
->wd_RenderInfo
.mri_Screen
->ViewPort
.DHeight
-
955 data
->wd_Height
) / 2 -
956 data
->wd_RenderInfo
.mri_Screen
->TopEdge
;
958 else if (data
->wd_Y
== MUIV_Window_TopEdge_Moused
)
960 data
->wd_Y
= data
->wd_RenderInfo
.mri_Screen
->MouseY
;
962 else if (data
->wd_Y
<= MUIV_Window_TopEdge_Delta(0))
964 data
->wd_Y
= data
->wd_RenderInfo
.mri_Screen
->BarHeight
+ 1
965 + MUIV_Window_TopEdge_Delta(0) - data
->wd_Y
;
973 get(data
->wd_RefWindow
, MUIA_Window_Width
, &w
);
974 get(data
->wd_RefWindow
, MUIA_Window_LeftEdge
, &x
);
976 if (data
->wd_X
== MUIV_Window_LeftEdge_Centered
)
978 data
->wd_X
= x
+ (w
- data
->wd_Width
) / 2;
985 get(data
->wd_RefWindow
, MUIA_Window_Height
, &h
);
986 get(data
->wd_RefWindow
, MUIA_Window_TopEdge
, &y
);
988 if (data
->wd_Y
== MUIV_Window_TopEdge_Centered
)
990 /* D(bug("y=%ld, h=%ld, wdh=%ld\n", y, h, data->wd_Height)); */
991 data
->wd_Y
= y
+ (h
- data
->wd_Height
) / 2;
993 else if (data
->wd_Y
<= MUIV_Window_TopEdge_Delta(0))
995 /* ??? surely incorrect implementation */
996 data
->wd_Y
= y
+ 1 + MUIV_Window_TopEdge_Delta(0) - data
->wd_Y
;
1005 /* Initialize data->wd_AltDim for DisplayWindow */
1006 static void CalcAltDimensions(Object
*obj
, struct MUI_WindowData
*data
)
1008 /* Calculate alternate (zoomed) dimensions.
1010 if (data
->wd_AltDim
.Top
== MUIV_Window_AltTopEdge_NoChange
)
1011 data
->wd_AltDim
.Top
= ~0;
1012 else if (data
->wd_AltDim
.Top
== MUIV_Window_AltTopEdge_Centered
)
1013 data
->wd_AltDim
.Top
=
1014 (data
->wd_RenderInfo
.mri_Screen
->Height
- data
->wd_Height
) / 2;
1015 else if (data
->wd_AltDim
.Top
== MUIV_Window_AltTopEdge_Moused
)
1016 /* ? */ data
->wd_AltDim
.Top
= ~0;
1018 if (data
->wd_AltDim
.Left
== MUIV_Window_AltLeftEdge_NoChange
)
1019 data
->wd_AltDim
.Left
= ~0;
1020 else if (data
->wd_AltDim
.Left
== MUIV_Window_AltLeftEdge_Centered
)
1021 data
->wd_AltDim
.Left
=
1022 (data
->wd_RenderInfo
.mri_Screen
->Width
- data
->wd_Width
) / 2;
1023 else if (data
->wd_AltDim
.Left
== MUIV_Window_AltLeftEdge_Moused
)
1024 /* ? */ data
->wd_AltDim
.Left
= ~0;
1027 (MUIV_Window_AltWidth_MinMax(100),
1028 data
->wd_AltDim
.Width
, MUIV_Window_AltWidth_MinMax(0)))
1030 data
->wd_AltDim
.Width
= data
->wd_MinMax
.MinWidth
1031 - data
->wd_AltDim
.Width
1032 * (data
->wd_MinMax
.MaxWidth
- data
->wd_MinMax
.MinWidth
);
1036 (MUIV_Window_AltWidth_Screen(100),
1037 data
->wd_AltDim
.Width
, MUIV_Window_AltWidth_Screen(0)))
1039 data
->wd_AltDim
.Width
= data
->wd_RenderInfo
.mri_ScreenWidth
1040 * (-(data
->wd_AltDim
.Width
+ 200)) / 100;
1044 (MUIV_Window_AltWidth_Visible(100),
1045 data
->wd_AltDim
.Width
, MUIV_Window_AltWidth_Visible(0)))
1047 data
->wd_AltDim
.Width
= data
->wd_RenderInfo
.mri_ScreenWidth
1048 * (-(data
->wd_AltDim
.Width
+ 100)) / 100;
1052 (MUIV_Window_AltHeight_MinMax(100),
1053 data
->wd_AltDim
.Height
, MUIV_Window_AltHeight_MinMax(0)))
1055 data
->wd_AltDim
.Height
= data
->wd_MinMax
.MinHeight
1056 - data
->wd_AltDim
.Height
1057 * (data
->wd_MinMax
.MaxHeight
- data
->wd_MinMax
.MinHeight
);
1061 (MUIV_Window_AltHeight_Screen(100),
1062 data
->wd_AltDim
.Height
, MUIV_Window_AltHeight_Screen(0)))
1064 data
->wd_AltDim
.Height
= data
->wd_RenderInfo
.mri_ScreenHeight
1065 * (-(data
->wd_AltDim
.Height
+ 200)) / 100;
1069 (MUIV_Window_AltHeight_Visible(100),
1070 data
->wd_AltDim
.Height
, MUIV_Window_AltHeight_Visible(0)))
1072 data
->wd_AltDim
.Height
= data
->wd_RenderInfo
.mri_ScreenHeight
1073 * (-(data
->wd_AltDim
.Height
+ 100)) / 100;
1076 data
->wd_AltDim
.Width
= CLAMP
1077 (data
->wd_AltDim
.Width
, data
->wd_MinMax
.MinWidth
,
1078 data
->wd_MinMax
.MaxWidth
);
1079 data
->wd_AltDim
.Height
= CLAMP
1080 (data
->wd_AltDim
.Height
, data
->wd_MinMax
.MinHeight
,
1081 data
->wd_MinMax
.MaxHeight
);
1085 /* Create horiz/vert window scrollbars for DisplayWindow */
1086 static void CreateWindowScrollbars(Object
*obj
,
1087 struct MUI_WindowData
*data
)
1089 struct MUI_RenderInfo
*mri
= &data
->wd_RenderInfo
;
1090 Object
*firstgad
= NULL
;
1091 Object
*prevgad
= NULL
;
1094 /* Create the right border scrollers now if requested */
1095 if (data
->wd_Flags
& MUIWF_USERIGHTSCROLLER
)
1099 voffset
= IM(mri
->mri_DownImage
)->Width
/ 4;
1101 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1102 firstgad
= prevgad
= data
->wd_VertProp
= NewObject
1103 (NULL
, "propgclass",
1104 GA_RelRight
, 1 - (IM(mri
->mri_UpImage
)->Width
- voffset
),
1105 GA_Top
, mri
->mri_BorderTop
+ 2,
1106 GA_Width
, IM(mri
->mri_UpImage
)->Width
- voffset
* 2,
1107 GA_RelHeight
, -(mri
->mri_BorderTop
+ 2)
1108 - IM(mri
->mri_UpImage
)->Height
1109 - IM(mri
->mri_DownImage
)->Height
1110 - IM(mri
->mri_SizeImage
)->Height
- 2,
1111 GA_RightBorder
, TRUE
,
1113 PGA_Borderless
, TRUE
,
1115 PGA_Freedom
, FREEVERT
,
1118 PGA_Visible
, 1, ICA_TARGET
, ICTARGET_IDCMP
, TAG_DONE
);
1120 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1121 prevgad
= data
->wd_UpButton
= NewObject
1122 (NULL
, "buttongclass",
1123 GA_Image
, (IPTR
) mri
->mri_UpImage
,
1124 GA_RelRight
, 1 - IM(mri
->mri_UpImage
)->Width
,
1125 GA_RelBottom
, 1 - IM(mri
->mri_UpImage
)->Height
1126 - IM(mri
->mri_DownImage
)->Height
1127 - IM(mri
->mri_SizeImage
)->Height
,
1128 GA_RightBorder
, TRUE
,
1129 GA_Previous
, (IPTR
) prevgad
,
1130 GA_ID
, id
, ICA_TARGET
, ICTARGET_IDCMP
, TAG_DONE
);
1132 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1133 prevgad
= data
->wd_DownButton
= NewObject
1134 (NULL
, "buttongclass",
1135 GA_Image
, (IPTR
) mri
->mri_DownImage
,
1136 GA_RelRight
, 1 - IM(mri
->mri_DownImage
)->Width
,
1137 GA_RelBottom
, 1 - IM(mri
->mri_DownImage
)->Height
1138 - IM(mri
->mri_SizeImage
)->Height
,
1139 GA_RightBorder
, TRUE
,
1140 GA_Previous
, (IPTR
) prevgad
,
1141 GA_ID
, id
, ICA_TARGET
, ICTARGET_IDCMP
, TAG_DONE
);
1144 /* Create the bottom border scrollers now if requested */
1145 if (data
->wd_Flags
& MUIWF_USEBOTTOMSCROLLER
)
1149 hoffset
= IM(mri
->mri_RightImage
)->Height
/ 4;
1151 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1152 prevgad
= data
->wd_HorizProp
= NewObject
1153 (NULL
, "propgclass",
1154 GA_RelBottom
, 1 - (IM(mri
->mri_LeftImage
)->Height
- hoffset
),
1155 GA_Left
, mri
->mri_BorderLeft
,
1156 GA_Height
, IM(mri
->mri_LeftImage
)->Height
1158 GA_RelWidth
, -(mri
->mri_BorderLeft
)
1159 - IM(mri
->mri_LeftImage
)->Width
1160 - IM(mri
->mri_RightImage
)->Width
1161 - IM(mri
->mri_SizeImage
)->Width
1163 GA_BottomBorder
, TRUE
,
1165 prevgad
? GA_Previous
: TAG_IGNORE
, (IPTR
) prevgad
,
1166 PGA_Borderless
, TRUE
,
1168 PGA_Freedom
, FREEHORIZ
,
1171 PGA_Visible
, 1, ICA_TARGET
, ICTARGET_IDCMP
, TAG_DONE
);
1176 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1177 prevgad
= data
->wd_LeftButton
= NewObject
1178 (NULL
, "buttongclass",
1179 GA_Image
, (IPTR
) mri
->mri_LeftImage
,
1180 GA_RelRight
, 1 - IM(mri
->mri_LeftImage
)->Width
1181 - IM(mri
->mri_RightImage
)->Width
1182 - IM(mri
->mri_SizeImage
)->Width
,
1183 GA_RelBottom
, 1 - IM(mri
->mri_LeftImage
)->Height
,
1184 GA_BottomBorder
, TRUE
,
1185 GA_Previous
, (IPTR
) prevgad
,
1186 GA_ID
, id
, ICA_TARGET
, ICTARGET_IDCMP
, TAG_DONE
);
1188 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1189 prevgad
= data
->wd_RightButton
= NewObject
1190 (NULL
, "buttongclass",
1191 GA_Image
, (IPTR
) mri
->mri_RightImage
,
1192 GA_RelRight
, 1 - IM(mri
->mri_RightImage
)->Width
1193 - IM(mri
->mri_SizeImage
)->Width
,
1194 GA_RelBottom
, 1 - IM(mri
->mri_RightImage
)->Height
,
1195 GA_BottomBorder
, TRUE
,
1196 GA_Previous
, (IPTR
) prevgad
,
1197 GA_ID
, id
, ICA_TARGET
, ICTARGET_IDCMP
, TAG_DONE
);
1201 /* return FALSE only if no resize (dx=dy=0) occured */
1202 static BOOL
WindowResize(struct MUI_WindowData
*data
)
1204 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
1205 int hborders
= win
->BorderLeft
+ win
->BorderRight
;
1206 int vborders
= win
->BorderTop
+ win
->BorderBottom
;
1207 WORD dx
= data
->wd_Width
- win
->Width
+ hborders
;
1208 WORD dy
= data
->wd_Height
- win
->Height
+ vborders
;
1210 /* Temporarily disable window limits to let SizeWindow below work
1211 regardless of the previous limits */
1212 WindowLimits(win
, 1, 1, -1, -1);
1213 /* D(bug("_zune_window_resize : dx=%d, dy=%d\n", dx, dy)); */
1214 SizeWindow(win
, dx
, dy
);
1216 /* Set new window limits */
1218 (win
, data
->wd_MinMax
.MinWidth
+ hborders
,
1219 data
->wd_MinMax
.MinHeight
+ vborders
,
1220 data
->wd_MinMax
.MaxWidth
+ hborders
,
1221 data
->wd_MinMax
.MaxHeight
+ vborders
);
1226 static void KillHelpBubble(struct MUI_WindowData
*data
, Object
*obj
,
1227 BOOL kill_bubblemode
)
1229 if (data
->wd_HelpObject
)
1231 DoMethod(data
->wd_HelpObject
, MUIM_DeleteBubble
,
1232 (IPTR
) data
->wd_HelpBubble
);
1233 data
->wd_HelpObject
= NULL
;
1234 data
->wd_HelpBubble
= NULL
;
1237 if (kill_bubblemode
)
1238 data
->wd_Flags
&= ~MUIWF_BUBBLEMODE
;
1240 if (data
->wd_Flags
& MUIWF_BUBBLEMODE
)
1242 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_LATER
;
1246 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_FIRST
;
1253 typedef BOOL(*UNDERCHECK_FUNC
) (Object
*obj
);
1255 static BOOL
ShortHelpUnderPointerCheck(Object
*obj
)
1257 return muiAreaData(obj
)->mad_ShortHelp
? TRUE
: FALSE
;
1260 static Object
*ObjectUnderPointer(struct MUI_WindowData
*data
, Object
*obj
,
1261 LONG x
, LONG y
, UNDERCHECK_FUNC func
)
1265 struct MinList
*ChildList
= NULL
;
1267 if (!(muiAreaData(obj
)->mad_Flags
& MADF_CANDRAW
))
1270 if (!(x
>= _left(obj
) && x
<= _right(obj
)
1271 && y
>= _top(obj
) && y
<= _bottom(obj
)))
1276 if ((get(obj
, MUIA_Group_ChildList
, &(ChildList
)))
1277 && (ChildList
!= NULL
))
1279 cstate
= (Object
*) ChildList
->mlh_Head
;
1280 while ((child
= NextObject(&cstate
)))
1284 if ((x
>= _left(child
) && x
<= _right(child
)
1286 y
>= _top(child
) && y
<= _bottom(child
))
1287 && (ret
= ObjectUnderPointer(data
, child
, x
, y
, func
)))
1300 static BOOL
ContextMenuUnderPointer(struct MUI_WindowData
*data
,
1301 Object
*obj
, LONG x
, LONG y
)
1305 struct MinList
*ChildList
= NULL
;
1307 if (!(x
>= _left(obj
) && x
<= _right(obj
)
1308 && y
>= _top(obj
) && y
<= _bottom(obj
)))
1313 if ((get(obj
, MUIA_Group_ChildList
, &(ChildList
)))
1314 && (ChildList
!= NULL
))
1317 cstate
= (Object
*) ChildList
->mlh_Head
;
1318 while ((child
= NextObject(&cstate
)))
1320 if ((x
>= _left(child
) && x
<= _right(child
)
1322 y
>= _top(child
) && y
<= _bottom(child
))
1323 && (ContextMenuUnderPointer(data
, child
, x
, y
)))
1328 if (!(muiAreaData(obj
)->mad_Flags
& MADF_CANDRAW
))
1330 if (!(muiAreaData(obj
)->mad_ContextMenu
))
1338 static void ActivateObject(struct MUI_WindowData
*data
)
1340 //bug("Window::ActivateObject (dummy) %08lx\n", data->wd_ActiveObject);
1341 // if (FindObjNode(&data->wd_CycleChain, data->wd_ActiveObject))
1342 // DoMethod(data->wd_ActiveObject, MUIM_GoActive);
1344 // data->wd_ActiveObject = NULL;
1346 //activate better string gadgets.Fix from Georg S On ML List
1347 if (FindObjNode(&data
->wd_CycleChain
, data
->wd_ActiveObject
))
1349 if (!(data
->wd_Flags
& MUIWF_OBJECTGOACTIVESENT
))
1351 data
->wd_Flags
|= MUIWF_OBJECTGOACTIVESENT
;
1352 DoMethod(data
->wd_ActiveObject
, MUIM_GoActive
);
1356 data
->wd_ActiveObject
= NULL
;
1361 static void HandleInputEvent(Object
*win
, struct MUI_WindowData
*data
,
1362 struct IntuiMessage
*event
);
1364 /* handle intuimessage while an object is being dragged
1365 * (reply imsg before returning)
1367 void HandleDragging(Object
*oWin
, struct MUI_WindowData
*data
,
1368 struct IntuiMessage
*imsg
)
1370 struct Window
*iWin
;
1371 int finish_drag
= 0;
1373 iWin
= imsg
->IDCMPWindow
;
1375 if (imsg
->Class
== IDCMP_MOUSEMOVE
)
1377 struct Layer
*layer
;
1379 WhichLayer(&iWin
->WScreen
->LayerInfo
,
1380 iWin
->LeftEdge
+ imsg
->MouseX
, iWin
->TopEdge
+ imsg
->MouseY
);
1382 if (data
->wd_DropObject
)
1386 imsg
->MouseX
+ iWin
->LeftEdge
-
1387 data
->wd_DropWindow
->LeftEdge
;
1389 imsg
->MouseY
+ iWin
->TopEdge
- data
->wd_DropWindow
->TopEdge
;
1391 wnd
= _window(data
->wd_DropObject
);
1392 if (mousex
< _left(data
->wd_DropObject
)
1393 || mousex
> _right(data
->wd_DropObject
)
1394 || mousey
< _top(data
->wd_DropObject
)
1395 || mousey
> _bottom(data
->wd_DropObject
)
1396 || layer
!= wnd
->WLayer
)
1398 /* We have left the object */
1399 UndrawDragNDrop(data
->wd_dnd
);
1400 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
,
1401 (IPTR
) data
->wd_DragObject
);
1402 data
->wd_DropObject
= NULL
;
1404 } /* if (data->wd_DropObject) */
1406 if (!data
->wd_DropObject
)
1408 Object
*dest_wnd
= NULL
;
1410 /* Find out if app has an openend window at this position */
1415 struct MinList
*ChildList
= 0;
1417 get(_app(oWin
), MUIA_Application_WindowList
, &(ChildList
));
1418 cstate
= (Object
*) ChildList
->mlh_Head
;
1419 while ((child
= NextObject(&cstate
)))
1421 struct Window
*wnd
= NULL
;
1422 get(child
, MUIA_Window_Window
, &wnd
);
1426 if (wnd
->WLayer
== layer
)
1428 data
->wd_DropWindow
= wnd
;
1437 Object
*root
= NULL
;
1438 get(dest_wnd
, MUIA_Window_RootObject
, &root
);
1442 if ((data
->wd_DropObject
= (Object
*) DoMethod
1443 (root
, MUIM_DragQueryExtended
,
1444 (IPTR
) data
->wd_DragObject
,
1445 imsg
->MouseX
+ iWin
->LeftEdge
-
1446 data
->wd_DropWindow
->LeftEdge
,
1447 imsg
->MouseY
+ iWin
->TopEdge
-
1448 data
->wd_DropWindow
->TopEdge
)))
1450 UndrawDragNDrop(data
->wd_dnd
);
1451 DoMethod(data
->wd_DropObject
, MUIM_DragBegin
,
1452 (IPTR
) data
->wd_DragObject
);
1458 if (data
->wd_DropObject
)
1462 for (i
= 0; i
< 2; i
++)
1464 LONG res
= DoMethod(data
->wd_DropObject
, MUIM_DragReport
,
1465 (IPTR
) data
->wd_DragObject
,
1466 imsg
->MouseX
+ iWin
->LeftEdge
-
1467 data
->wd_DropWindow
->LeftEdge
,
1468 imsg
->MouseY
+ iWin
->TopEdge
-
1469 data
->wd_DropWindow
->TopEdge
, update
);
1472 case MUIV_DragReport_Abort
:
1473 UndrawDragNDrop(data
->wd_dnd
);
1474 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
,
1475 (IPTR
) data
->wd_DragObject
);
1476 data
->wd_DropObject
= NULL
;
1480 case MUIV_DragReport_Continue
:
1482 case MUIV_DragReport_Lock
:
1484 case MUIV_DragReport_Refresh
:
1485 UndrawDragNDrop(data
->wd_dnd
);
1491 DrawDragNDrop(data
->wd_dnd
, imsg
->MouseX
+ iWin
->LeftEdge
,
1492 imsg
->MouseY
+ iWin
->TopEdge
);
1495 if (imsg
->Class
== IDCMP_MOUSEBUTTONS
)
1497 if ((imsg
->Code
== MENUDOWN
) || (imsg
->Code
== SELECTUP
))
1499 if (imsg
->Code
== SELECTUP
&& data
->wd_DropObject
)
1501 UndrawDragNDrop(data
->wd_dnd
);
1502 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
,
1503 (IPTR
) data
->wd_DragObject
);
1504 DoMethod(data
->wd_DropObject
, MUIM_DragDrop
,
1505 (IPTR
) data
->wd_DragObject
,
1506 imsg
->MouseX
+ iWin
->LeftEdge
-
1507 data
->wd_DropWindow
->LeftEdge
,
1508 imsg
->MouseY
+ iWin
->TopEdge
-
1509 data
->wd_DropWindow
->TopEdge
);
1510 data
->wd_DropObject
= NULL
;
1512 else if (imsg
->Code
== SELECTUP
)
1514 DoMethod(data
->wd_DragObject
, MUIM_UnknownDropDestination
,
1521 if (imsg
->Class
== IDCMP_CLOSEWINDOW
)
1526 UndrawDragNDrop(data
->wd_dnd
);
1527 if (data
->wd_DropObject
)
1529 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
,
1530 (IPTR
) data
->wd_DragObject
);
1531 data
->wd_DropObject
= NULL
;
1533 DeleteDragNDrop(data
->wd_dnd
);
1534 DoMethod(data
->wd_DragObject
, MUIM_DeleteDragImage
,
1535 (IPTR
) data
->wd_DragImage
);
1536 muiAreaData(data
->wd_DragObject
)->mad_Flags
&= ~MADF_DRAGGING
;
1537 data
->wd_DragImage
= NULL
;
1538 data
->wd_DragObject
= NULL
;
1539 data
->wd_DropWindow
= NULL
;
1540 data
->wd_dnd
= NULL
;
1542 /* stop listening to IDCMP_MOUSEMOVE */
1543 ChangeEvents(data
, GetDefaultEvents());
1545 ReplyMsg((struct Message
*)imsg
);
1548 /* Reply to imsg if handled */
1549 BOOL
HandleWindowEvent(Object
*oWin
, struct MUI_WindowData
*data
,
1550 struct IntuiMessage
*imsg
)
1552 struct Window
*iWin
;
1553 BOOL is_handled
= TRUE
;
1554 BOOL replied
= FALSE
;
1556 iWin
= imsg
->IDCMPWindow
;
1557 switch (imsg
->Class
)
1559 case IDCMP_ACTIVEWINDOW
:
1560 data
->wd_Flags
|= MUIWF_ACTIVE
;
1561 if (data
->wd_OldActive
)
1562 set(oWin
, MUIA_Window_ActiveObject
, data
->wd_OldActive
);
1563 set(oWin
, MUIA_Window_Activate
, TRUE
);
1564 is_handled
= FALSE
; /* forwardable to area event handlers */
1567 case IDCMP_INACTIVEWINDOW
:
1568 KillHelpBubble(data
, oWin
, TRUE
);
1569 if (data
->wd_ActiveObject
)
1571 data
->wd_OldActive
= data
->wd_ActiveObject
;
1572 set(oWin
, MUIA_Window_ActiveObject
,
1573 MUIV_Window_ActiveObject_None
);
1575 data
->wd_Flags
&= ~MUIWF_ACTIVE
;
1576 set(oWin
, MUIA_Window_Activate
, FALSE
);
1577 is_handled
= FALSE
; /* forwardable to area event handlers */
1581 ReplyMsg((struct Message
*)imsg
);
1585 int hborders
= iWin
->BorderLeft
+ iWin
->BorderRight
;
1586 int vborders
= iWin
->BorderTop
+ iWin
->BorderBottom
;
1588 /* set window limits according to window contents */
1591 data
->wd_MinMax
.MinWidth
+ hborders
,
1592 data
->wd_MinMax
.MinHeight
+ vborders
,
1593 data
->wd_MinMax
.MaxWidth
+ hborders
,
1594 data
->wd_MinMax
.MaxHeight
+ vborders
);
1597 if ((iWin
->GZZWidth
!= data
->wd_Width
)
1598 || (iWin
->GZZHeight
!= data
->wd_Height
))
1600 data
->wd_Width
= iWin
->GZZWidth
;
1601 data
->wd_Height
= iWin
->GZZHeight
;
1602 DoHideMethod(data
->wd_RootObject
);
1605 // why only simple refresh? was: if (
1606 // data->wd_RenderInfo.mri_Window->Flags & WFLG_SIMPLE_REFRESH)
1608 data
->wd_Flags
|= MUIWF_RESIZING
;
1612 _width(data
->wd_RootObject
) = data
->wd_Width
;
1613 _height(data
->wd_RootObject
) = data
->wd_Height
;
1614 DoMethod(data
->wd_RootObject
, MUIM_Layout
);
1615 DoShowMethod(data
->wd_RootObject
);
1617 LONG left
, top
, width
, height
;
1619 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
1620 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
,
1621 width
= data
->wd_RenderInfo
.mri_Window
->Width
1622 - data
->wd_RenderInfo
.mri_Window
->BorderRight
-
1625 data
->wd_RenderInfo
.mri_Window
->Height
-
1626 data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
1628 //D(bug("%d:zune_imspec_draw(%p) "
1629 // "l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
1630 // __LINE__, data->wd_Background, left, top, width,
1631 // height, left, top));
1632 zune_imspec_draw(data
->wd_Background
,
1633 &data
->wd_RenderInfo
, left
, top
, width
, height
,
1636 if (muiGlobalInfo(oWin
)->mgi_Prefs
->window_redraw
==
1637 WINDOW_REDRAW_WITHOUT_CLEAR
)
1638 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWOBJECT
);
1640 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWALL
);
1641 // but should only draw focus without using MUIM_GoActive !
1642 ActivateObject(data
);
1647 case IDCMP_REFRESHWINDOW
:
1648 ReplyMsg((struct Message
*)imsg
);
1650 if (data
->wd_Flags
& MUIWF_RESIZING
)
1652 //LONG left,top,right,bottom;
1653 if (MUI_BeginRefresh(&data
->wd_RenderInfo
, 0))
1655 MUI_EndRefresh(&data
->wd_RenderInfo
, 0);
1657 RefreshWindowFrame(data
->wd_RenderInfo
.mri_Window
);
1659 data
->wd_Flags
&= ~MUIWF_RESIZING
;
1660 _width(data
->wd_RootObject
) = data
->wd_Width
;
1661 _height(data
->wd_RootObject
) = data
->wd_Height
;
1662 DoMethod(data
->wd_RootObject
, MUIM_Layout
);
1663 DoShowMethod(data
->wd_RootObject
);
1665 if (muiGlobalInfo(oWin
)->mgi_Prefs
->window_redraw
==
1666 WINDOW_REDRAW_WITH_CLEAR
)
1668 LONG left
, top
, width
, height
;
1670 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
1671 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
;
1673 data
->wd_RenderInfo
.mri_Window
->Width
-
1674 data
->wd_RenderInfo
.mri_Window
->BorderRight
- left
;
1676 data
->wd_RenderInfo
.mri_Window
->Height
-
1677 data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
1679 if (data
->wd_Flags
& MUIWF_ERASEAREA
)
1681 //D(bug("%d:zune_imspec_draw(%p) "
1682 // "l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
1683 // __LINE__, data->wd_Background, left, top, width,
1684 // height, left, top));
1685 zune_imspec_draw(data
->wd_Background
,
1686 &data
->wd_RenderInfo
, left
, top
, width
, height
,
1689 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWALL
);
1692 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWOBJECT
);
1693 // but should only draw focus without using MUIM_GoActive !
1694 ActivateObject(data
);
1698 if (MUI_BeginRefresh(&data
->wd_RenderInfo
, 0))
1700 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWALL
);
1701 // but should only draw focus without using MUIM_GoActive !
1702 ActivateObject(data
);
1703 MUI_EndRefresh(&data
->wd_RenderInfo
, 0);
1708 case IDCMP_CLOSEWINDOW
:
1709 ReplyMsg((struct Message
*)imsg
);
1711 set(oWin
, MUIA_Window_CloseRequest
, TRUE
);
1714 case IDCMP_MENUPICK
:
1715 ReplyMsg((struct Message
*)imsg
);
1720 if (MENUNUM(imsg
->Code
) != NOMENU
1721 && ITEMNUM(imsg
->Code
) != NOITEM
)
1723 struct MenuItem
*item
=
1724 ItemAddress(data
->wd_Menu
, imsg
->Code
);
1727 Object
*item_obj
= (Object
*) GTMENUITEM_USERDATA(item
);
1733 if (item
->Flags
& CHECKIT
)
1734 set(item_obj
, MUIA_Menuitem_Checked
,
1735 ! !(item
->Flags
& CHECKED
));
1737 set(item_obj
, MUIA_Menuitem_Trigger
, (IPTR
) item
);
1739 get(oWin
, MUIA_ApplicationObject
, &app
);
1740 get(item_obj
, MUIA_UserData
, &udata
);
1742 set(app
, MUIA_Application_MenuAction
, udata
);
1743 set(oWin
, MUIA_Window_MenuAction
, udata
);
1744 DoMethod(app
, MUIM_Application_ReturnID
, udata
);
1751 case IDCMP_IDCMPUPDATE
:
1752 is_handled
= FALSE
; /* forwardable to area event handlers */
1753 if (data
->wd_VertProp
|| data
->wd_HorizProp
)
1755 struct TagItem
*tag
;
1756 tag
= FindTagItem(GA_ID
, (struct TagItem
*)imsg
->IAddress
);
1759 /* If there's a propclass object connected to the prop
1760 gadget, the prop gadget's userdata will point to
1761 that propclass object. See classes/prop.c */
1763 if (data
->wd_VertProp
)
1765 if (tag
->ti_Data
== GADGETID(data
->wd_VertProp
))
1768 if (tag
->ti_Data
== GADGETID(data
->wd_UpButton
))
1771 (Object
*) ((struct Gadget
*)data
->
1772 wd_VertProp
)->UserData
;
1775 DoMethod(prop
, MUIM_Prop_Decrease
, 1);
1778 if (tag
->ti_Data
== GADGETID(data
->wd_DownButton
))
1781 (Object
*) ((struct Gadget
*)data
->
1782 wd_VertProp
)->UserData
;
1785 DoMethod(prop
, MUIM_Prop_Increase
, 1);
1790 if (data
->wd_HorizProp
)
1792 if (tag
->ti_Data
== GADGETID(data
->wd_HorizProp
))
1795 if (tag
->ti_Data
== GADGETID(data
->wd_LeftButton
))
1798 (Object
*) ((struct Gadget
*)data
->
1799 wd_HorizProp
)->UserData
;
1802 DoMethod(prop
, MUIM_Prop_Decrease
, 1);
1805 if (tag
->ti_Data
== GADGETID(data
->wd_RightButton
))
1808 (Object
*) ((struct Gadget
*)data
->
1809 wd_HorizProp
)->UserData
;
1812 DoMethod(prop
, MUIM_Prop_Increase
, 1);
1820 case IDCMP_INTUITICKS
:
1821 if (data
->wd_HelpTicker
)
1823 data
->wd_HelpTicker
--;
1825 if (data
->wd_HelpTicker
== 0)
1828 ObjectUnderPointer(data
, data
->wd_RootObject
,
1829 imsg
->MouseX
, imsg
->MouseY
,
1830 ShortHelpUnderPointerCheck
);
1832 if (underobj
!= data
->wd_HelpObject
)
1834 if (data
->wd_HelpObject
)
1836 DoMethod(data
->wd_HelpObject
, MUIM_DeleteBubble
,
1837 (IPTR
) data
->wd_HelpBubble
);
1839 data
->wd_HelpObject
= NULL
;
1840 data
->wd_HelpBubble
= NULL
;
1845 data
->wd_HelpBubble
=
1846 (APTR
) DoMethod(underobj
, MUIM_CreateBubble
,
1847 imsg
->MouseX
, imsg
->MouseY
, 0, 0);
1848 if (data
->wd_HelpBubble
)
1850 data
->wd_HelpObject
= underobj
;
1851 data
->wd_Flags
|= MUIWF_BUBBLEMODE
;
1856 if (data
->wd_Flags
& MUIWF_BUBBLEMODE
)
1858 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_LATER
;
1862 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_FIRST
;
1867 is_handled
= FALSE
; /* forwardable to area event handlers */
1870 case IDCMP_MOUSEBUTTONS
:
1871 DoMethod(oWin
, MUIM_Window_Snapshot
, 0);
1872 KillHelpBubble(data
, oWin
, TRUE
);
1877 case IDCMP_MOUSEMOVE
:
1878 KillHelpBubble(data
, oWin
, FALSE
);
1887 if (is_handled
&& !replied
)
1888 ReplyMsg((struct Message
*)imsg
);
1893 static ULONG
InvokeEventHandler(struct MUI_EventHandlerNode
*ehn
,
1894 struct IntuiMessage
*event
, ULONG muikey
)
1898 if (!(_flags(ehn
->ehn_Object
) & MADF_CANDRAW
))
1900 if (!(_flags(ehn
->ehn_Object
) & MADF_SHOWME
))
1904 && event
->Class
== IDCMP_MOUSEBUTTONS
1905 && event
->Code
== SELECTDOWN
1906 && (_flags(ehn
->ehn_Object
) & MADF_INVIRTUALGROUP
))
1909 Here we filter out SELECTDOWN messages if objects is in a virtual
1910 group but the click went out of the virtual group
1912 Object
*obj
= ehn
->ehn_Object
;
1913 Object
*parent
= obj
;
1914 Object
*wnd
= _win(obj
);
1916 while (get(parent
, MUIA_Parent
, &parent
))
1922 if (_flags(parent
) & MADF_ISVIRTUALGROUP
)
1924 if (event
->MouseX
< _mleft(parent
)
1925 || event
->MouseX
> _mright(parent
)
1926 || event
->MouseY
< _mtop(parent
)
1927 || event
->MouseY
> _mbottom(parent
))
1936 if (ehn
->ehn_Flags
& MUI_EHF_HANDLEINPUT
)
1938 DoMethod(ehn
->ehn_Object
, MUIM_HandleInput
, (IPTR
) event
, muikey
);
1945 (ehn
->ehn_Class
, ehn
->ehn_Object
, MUIM_HandleEvent
,
1946 (IPTR
) event
, muikey
);
1949 DoMethod(ehn
->ehn_Object
, MUIM_HandleEvent
, (IPTR
) event
,
1955 static void HandleRawkey(Object
*win
, struct MUI_WindowData
*data
,
1956 struct IntuiMessage
*event
)
1959 struct MUI_EventHandlerNode
*ehn
;
1960 struct IntuiMessage imsg_copy
;
1961 struct InputEvent ie
= { 0 };
1963 LONG muikey
= MUIKEY_NONE
;
1964 Object
*active_object
= NULL
;
1969 KillHelpBubble(data
, win
, BUBBLEHELP_TICKER_FIRST
);
1971 ie
.ie_NextEvent
= NULL
;
1972 ie
.ie_Class
= IECLASS_RAWKEY
;
1974 ie
.ie_Code
= event
->Code
;
1975 ie
.ie_Qualifier
= event
->Qualifier
;
1976 ie
.ie_EventAddress
= (APTR
) * (IPTR
*) event
->IAddress
;
1978 ie
.ie_TimeStamp
.Seconds
= event
->Seconds
;
1979 ie
.ie_TimeStamp
.Microseconds
= event
->Micros
;
1981 ie
.ie_TimeStamp
.tv_secs
= event
->Seconds
;
1982 ie
.ie_TimeStamp
.tv_micro
= event
->Micros
;
1985 set(win
, MUIA_Window_InputEvent
, (IPTR
) & ie
);
1987 /* get the vanilla key for control char */
1991 /* Remove the up prefix as convert key does not convert upkey event */
1992 msg_code
= event
->Code
;
1993 event
->Code
&= ~IECODE_UP_PREFIX
;
1994 key
= ConvertKey(event
);
1995 event
->Code
= msg_code
;
1999 deadkey
= *(ULONG
*) event
->IAddress
;
2000 imsg_copy
.IAddress
= &deadkey
;
2001 ReplyMsg((struct Message
*)event
);
2004 //bug("rawkey: code=%lx, qual=%lx\n", event->Code, event->Qualifier);
2006 /* check if imsg translate to predefined keystroke */
2008 struct InputEvent ievent
;
2009 BOOL matched
= FALSE
;
2011 ievent
.ie_NextEvent
= NULL
;
2012 ievent
.ie_Class
= IECLASS_RAWKEY
;
2013 ievent
.ie_SubClass
= 0;
2014 ievent
.ie_Code
= event
->Code
;
2015 ievent
.ie_Qualifier
= event
->Qualifier
;
2016 /* ie_EventAddress is not used by MatchIX. If needed, it should be
2017 * ensured that it is still a valid adress because of the shallow
2018 * IntuiMessage copy currently done in _zune_window_message before
2019 * message is replied.
2021 ievent
.ie_EventAddress
= NULL
;
2022 //ievent.ie_EventAddress = (APTR *) *((ULONG *)(event->IAddress));
2024 for (muikey
= MUIKEY_COUNT
- 1; muikey
>= MUIKEY_PRESS
; muikey
--)
2026 if (muiGlobalInfo(win
)->mgi_Prefs
->muikeys
[muikey
].ix_well
!= 0
2028 &muiGlobalInfo(win
)->mgi_Prefs
->muikeys
[muikey
].ix
))
2037 if (muikey
== MUIKEY_PRESS
&& (event
->Code
& IECODE_UP_PREFIX
))
2038 muikey
= MUIKEY_RELEASE
;
2042 muikey
= MUIKEY_NONE
;
2044 } /* check if imsg translate to predefined keystroke */
2046 if ((muikey
!= MUIKEY_NONE
) && !(data
->wd_DisabledKeys
& (1 << muikey
)))
2048 D(bug("HandleRawkey: try MUIKEY %ld on window %0x08lx\n", muikey
,
2062 case MUIKEY_PAGEDOWN
:
2072 case MUIKEY_WORDLEFT
:
2074 case MUIKEY_WORDRIGHT
:
2076 case MUIKEY_LINESTART
:
2078 case MUIKEY_LINEEND
:
2080 case MUIKEY_GADGET_NEXT
:
2081 set(win
, MUIA_Window_ActiveObject
,
2082 MUIV_Window_ActiveObject_Next
);
2084 case MUIKEY_GADGET_PREV
:
2085 set(win
, MUIA_Window_ActiveObject
,
2086 MUIV_Window_ActiveObject_Prev
);
2088 case MUIKEY_GADGET_OFF
:
2089 set(win
, MUIA_Window_ActiveObject
,
2090 MUIV_Window_ActiveObject_None
);
2092 case MUIKEY_WINDOW_CLOSE
:
2093 set(win
, MUIA_Window_CloseRequest
, TRUE
);
2095 case MUIKEY_WINDOW_NEXT
:
2097 case MUIKEY_WINDOW_PREV
:
2108 active_object
= NULL
;
2109 if ((data
->wd_ActiveObject
!= NULL
)
2110 && (DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
2111 (IPTR
) data
->wd_ActiveObject
) != (IPTR
) NULL
))
2113 active_object
= data
->wd_ActiveObject
;
2114 get(active_object
, MUIA_Disabled
, &disabled
);
2117 data
->wd_ActiveObject
= NULL
;
2119 /* try ActiveObject */
2120 if ((active_object
!= NULL
) && !disabled
)
2124 ** Which method should be used for muikeys? MUIM_HandleInput or
2125 ** MUIM_HandleEvent. Also note that there is a flag MUI_EHF_ALWAYSKEYS
2126 ** which probably means that all keys events are requested??
2127 ** For now MUIM_HandleEvent is used as this is currently implemented
2128 ** in Area class ;) although I guess it should be MUIM_HandleInput as
2132 if (muikey
!= MUIKEY_NONE
)
2135 DoMethod(active_object
, MUIM_HandleEvent
, (IPTR
) event
,
2137 if (res
& MUI_EventHandlerRC_Eat
)
2141 D(bug("HandleRawkey: try active object (%08lx) handlers\n",
2144 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2146 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2148 if ((ehn
->ehn_Object
== active_object
)
2149 && ((ehn
->ehn_Events
& IDCMP_RAWKEY
)
2150 || (ehn
->ehn_Flags
& MUI_EHF_ALWAYSKEYS
)))
2152 D(bug("HandleRawkey: (active) invoking on %p (ehn=%p) "
2153 "event=%p muikey=%p\n",
2154 ehn
->ehn_Object
, ehn
, event
, muikey
));
2155 res
= InvokeEventHandler(ehn
, event
, muikey
);
2156 D(bug("HandleRawkey: (active) got res=%d\n", res
));
2157 if (res
& MUI_EventHandlerRC_Eat
)
2160 /* Leave the loop if a different object has been activated */
2161 if (active_object
!= data
->wd_ActiveObject
)
2166 // event not eaten by active object, try its parents
2167 // this is to implement popup key in Popstring
2168 if (active_object
== data
->wd_ActiveObject
)
2170 Object
*current_obj
= active_object
;
2172 D(bug("HandleRawkey: try active object parents handlers\n"));
2173 while (current_obj
!= NULL
)
2175 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
;
2178 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2180 if ((ehn
->ehn_Object
== current_obj
)
2181 && ((ehn
->ehn_Events
& IDCMP_RAWKEY
)
2182 || (ehn
->ehn_Flags
& MUI_EHF_ALWAYSKEYS
)))
2184 //D(bug("HandleRawkey: (active parents) invoking on "
2185 // "%p (ehn=%p) event=%p muikey=%p\n",
2186 // ehn->ehn_Object, ehn, event, muikey));
2187 res
= InvokeEventHandler(ehn
, event
, muikey
);
2188 //D(bug("HandleRawkey: (active parents) got res=%d\n",
2190 if (res
& MUI_EventHandlerRC_Eat
)
2193 /* Leave the loop if a different object has been
2195 if (active_object
!= data
->wd_ActiveObject
)
2199 current_obj
= (Object
*) XGET(current_obj
, MUIA_Parent
);
2204 D(bug("HandleRawkey: try default object handlers\n"));
2206 /* try DefaultObject */
2207 if (data
->wd_DefaultObject
!= NULL
)
2208 get(data
->wd_DefaultObject
, MUIA_Disabled
, &disabled
);
2210 if ((data
->wd_DefaultObject
!= NULL
) && !disabled
2211 && (active_object
!= data
->wd_DefaultObject
))
2213 /* No, we only should do this if the object actually has requested
2214 * this via RequestIDCMP()! */
2215 // if (muikey != MUIKEY_NONE
2216 // && (_flags(data->wd_DefaultObject) & MADF_CANDRAW))
2218 // DoMethod(data->wd_DefaultObject, MUIM_HandleInput, event, muikey);
2222 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2224 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2226 if ((ehn
->ehn_Object
== data
->wd_DefaultObject
)
2227 && ((ehn
->ehn_Events
& IDCMP_RAWKEY
)
2228 || (ehn
->ehn_Flags
& MUI_EHF_ALWAYSKEYS
)))
2230 //D(bug("HandleRawkey: (default) invoking on %p (ehn=%p) "
2231 //"event=%p muikey=%p\n",
2232 //ehn->ehn_Object, ehn, event, muikey));
2233 res
= InvokeEventHandler(ehn
, event
, muikey
);
2234 //D(bug("HandleRawkey: (default) got res=%d\n", res));
2235 if (res
& MUI_EventHandlerRC_Eat
)
2242 D(bug("HandleRawkey: try other handlers\n"));
2244 // try other handlers
2245 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2247 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2249 // skip Active and Default object as they have already been
2251 if (ehn
->ehn_Object
== data
->wd_ActiveObject
2252 || ehn
->ehn_Object
== data
->wd_DefaultObject
)
2255 if (ehn
->ehn_Events
& IDCMP_RAWKEY
)
2257 //D(bug("HandleRawkey: (others) invoking on %p (ehn=%p) "
2258 //"event=%p muikey=%p\n",
2259 //ehn->ehn_Object, ehn, event, muikey));
2260 res
= InvokeEventHandler(ehn
, event
, MUIKEY_NONE
);
2261 //D(bug("HandleRawkey: (others) got res=%d\n", res));
2262 if (res
& MUI_EventHandlerRC_Eat
)
2267 D(bug("HandleRawkey: try control chars handlers\n"));
2269 /* try Control Chars */
2270 //bug("ctrlchar, key='%c' code=0x%08lx\n", key, event->Code);
2273 for (mn
= data
->wd_CCList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2275 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2277 if (ehn
->ehn_Events
== key
)
2280 LONG muikey2
= ehn
->ehn_Flags
;
2282 get(ehn
->ehn_Object
, MUIA_Disabled
, &disabled
);
2286 //bug("control char\n");
2287 if (event
->Code
& IECODE_UP_PREFIX
)
2289 /* simulate a release */
2290 if (muikey2
== MUIKEY_PRESS
)
2291 muikey2
= MUIKEY_RELEASE
;
2296 if ((muikey2
!= MUIKEY_NONE
)
2297 && (_flags(ehn
->ehn_Object
) & MADF_CANDRAW
)
2298 && (_flags(ehn
->ehn_Object
) & MADF_SHOWME
))
2301 (ehn
->ehn_Class
, ehn
->ehn_Object
, MUIM_HandleEvent
,
2302 (IPTR
) NULL
, muikey2
);
2303 if (res
& MUI_EventHandlerRC_Eat
)
2311 /* forward non-keystroke events to event handlers */
2312 static void HandleInputEvent(Object
*win
, struct MUI_WindowData
*data
,
2313 struct IntuiMessage
*event
)
2316 struct MUI_EventHandlerNode
*ehn
;
2317 struct IntuiMessage imsg_copy
;
2319 ULONG mask
= event
->Class
;
2321 if (mask
!= IDCMP_IDCMPUPDATE
)
2324 imsg_copy
.IAddress
= NULL
; /* be sure to trap access to that */
2325 ReplyMsg((struct Message
*)event
);
2329 if (mask
== IDCMP_MOUSEMOVE
)
2331 struct Window
*iWin
;
2332 iWin
= event
->IDCMPWindow
;
2334 if (ContextMenuUnderPointer(data
, data
->wd_RootObject
,
2335 event
->MouseX
, event
->MouseY
))
2337 iWin
->Flags
|= WFLG_RMBTRAP
;
2339 else if (!data
->wd_NoMenus
)
2341 iWin
->Flags
&= ~WFLG_RMBTRAP
;
2345 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2347 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2349 if (ehn
->ehn_Events
& mask
)
2353 get(ehn
->ehn_Object
, MUIA_Disabled
, &disabled
);
2357 res
= InvokeEventHandler(ehn
, event
, MUIKEY_NONE
);
2358 if (res
& MUI_EventHandlerRC_Eat
)
2364 if (mask
== IDCMP_IDCMPUPDATE
)
2365 ReplyMsg((struct Message
*)event
);
2369 /* process window message, this does a ReplyMsg() to the message */
2370 /* Called from application.c */
2371 void _zune_window_message(struct IntuiMessage
*imsg
)
2373 struct Window
*iWin
;
2375 struct MUI_WindowData
*data
;
2378 iWin
= imsg
->IDCMPWindow
;
2379 oWin
= (Object
*) iWin
->UserData
;
2380 data
= muiWindowData(oWin
);
2382 if (data
->wd_DragObject
)
2384 HandleDragging(oWin
, data
, imsg
);
2388 handled
= HandleWindowEvent(oWin
, data
, imsg
);
2391 if (IDCMP_RAWKEY
== imsg
->Class
)
2392 HandleRawkey(oWin
, data
, imsg
);
2393 else if (IDCMP_GADGETUP
== imsg
->Class
)
2396 if (ETI_MUI
== ((struct Gadget
*)imsg
->IAddress
)->GadgetID
)
2398 DoMethod(_app(oWin
), MUIM_Application_OpenConfigWindow
);
2401 if (ETI_Iconify
== ((struct Gadget
*)imsg
->IAddress
)->GadgetID
)
2403 set(_app(oWin
), MUIA_Application_Iconified
, TRUE
);
2408 HandleInputEvent(oWin
, data
, imsg
);
2413 /**************************************************************************/
2414 /**************************************************************************/
2416 /* code for setting MUIA_Window_RootObject */
2417 static void ChangeRootObject(struct MUI_WindowData
*data
, Object
*obj
,
2422 ASSERT_VALID_PTR(data
);
2423 ASSERT_VALID_PTR(obj
);
2425 oldRoot
= data
->wd_RootObject
;
2426 if (!(data
->wd_Flags
& MUIWF_OPENED
))
2430 if (data
->wd_ActiveObject
== oldRoot
)
2431 set(obj
, MUIA_Window_ActiveObject
,
2432 MUIV_Window_ActiveObject_None
);
2433 DoMethod(oldRoot
, MUIM_DisconnectParent
);
2436 data
->wd_RootObject
= newRoot
;
2439 /* if window is in App tree, inform child */
2440 if (muiNotifyData(obj
)->mnd_GlobalInfo
)
2441 DoMethod(newRoot
, MUIM_ConnectParent
, (IPTR
) obj
);
2446 // find the ObjNode containing a pointer to the given object
2447 // currently only used for cycle chain objects
2448 static struct ObjNode
*FindObjNode(struct MinList
*list
, Object
*obj
)
2450 struct ObjNode
*node
;
2452 ASSERT_VALID_PTR(list
);
2457 ASSERT_VALID_PTR(obj
);
2459 for (node
= (struct ObjNode
*)list
->mlh_Head
;
2460 node
->node
.mln_Succ
; node
= (struct ObjNode
*)node
->node
.mln_Succ
)
2462 if (node
->obj
== obj
)
2470 static Object
*GetFirstActiveObject(struct MUI_WindowData
*data
)
2472 ASSERT_VALID_PTR(data
);
2474 if (!IsListEmpty((struct List
*)&data
->wd_CycleChain
))
2475 return ((struct ObjNode
*)data
->wd_CycleChain
.mlh_Head
)->obj
;
2480 static Object
*GetLastActiveObject(struct MUI_WindowData
*data
)
2482 ASSERT_VALID_PTR(data
);
2484 if (!IsListEmpty((struct List
*)&data
->wd_CycleChain
))
2485 return ((struct ObjNode
*)data
->wd_CycleChain
.mlh_TailPred
)->obj
;
2490 typedef struct ObjNode
*objnode_iterator_t(struct ObjNode
*curr_node
);
2492 static objnode_iterator_t NextObjNodeIterator
;
2493 static objnode_iterator_t PrevObjNodeIterator
;
2495 static struct ObjNode
*NextObjNodeIterator(struct ObjNode
*curr_node
)
2497 if (curr_node
->node
.mln_Succ
->mln_Succ
)
2498 return (struct ObjNode
*)curr_node
->node
.mln_Succ
;
2503 static struct ObjNode
*PrevObjNodeIterator(struct ObjNode
*curr_node
)
2505 if (curr_node
->node
.mln_Pred
->mln_Pred
)
2506 return (struct ObjNode
*)curr_node
->node
.mln_Pred
;
2511 static Object
*GetPrevNextActiveObject(struct ObjNode
*old_activenode
,
2512 objnode_iterator_t node_iterator
)
2514 struct ObjNode
*curr_node
;
2515 struct ObjNode
*node
;
2518 ASSERT_VALID_PTR(old_activenode
);
2520 curr_node
= old_activenode
;
2526 node
= node_iterator(curr_node
);
2531 /* let's see if this object meets cycle requirements
2532 * (enabled & visible) */
2535 IPTR is_disabled
= 0;
2537 get(obj
, MUIA_Disabled
, &is_disabled
);
2539 if (!is_disabled
&& (_flags(obj
) & MADF_SHOWME
))
2553 /**************************************************************************
2554 Code for setting MUIA_Window_ActiveObject
2556 - remove focus drawing for current active object
2557 - find (if needed) the new active object
2558 - set data->wd_ActiveObject to the new object
2559 - draw focus around the new active object
2560 **************************************************************************/
2561 static void SetActiveObject(struct MUI_WindowData
*data
, Object
*obj
,
2564 struct ObjNode
*old_activenode
= NULL
;
2566 ASSERT_VALID_PTR(data
);
2567 ASSERT_VALID_PTR(obj
);
2569 D(bug("MUIC_Window:SetActiveObject(data, obj, %08lx) Active=%p\n",
2570 newval
, data
->wd_ActiveObject
));
2572 if ((data
->wd_ActiveObject
!= NULL
)
2573 && (DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
2574 (IPTR
) data
->wd_ActiveObject
) != (IPTR
) NULL
))
2576 if ((IPTR
) data
->wd_ActiveObject
!= newval
)
2579 FindObjNode(&data
->wd_CycleChain
, data
->wd_ActiveObject
);
2580 //if (_flags(data->wd_ActiveObject) & MADF_CANDRAW)
2581 if (data
->wd_Flags
& MUIWF_OBJECTGOACTIVESENT
)
2583 D(bug("Inactivate=%p\n", data
->wd_ActiveObject
));
2584 DoMethod(data
->wd_ActiveObject
, MUIM_GoInactive
);
2589 data
->wd_ActiveObject
= NULL
;
2590 data
->wd_Flags
&= ~MUIWF_OBJECTGOACTIVESENT
;
2594 case MUIV_Window_ActiveObject_None
:
2597 case MUIV_Window_ActiveObject_Next
:
2598 if (old_activenode
!= NULL
)
2599 data
->wd_ActiveObject
= GetPrevNextActiveObject(old_activenode
,
2600 NextObjNodeIterator
);
2601 if (NULL
== data
->wd_ActiveObject
)
2602 data
->wd_ActiveObject
= GetFirstActiveObject(data
);
2605 case MUIV_Window_ActiveObject_Prev
:
2607 data
->wd_ActiveObject
= GetPrevNextActiveObject(old_activenode
,
2608 PrevObjNodeIterator
);
2609 if (NULL
== data
->wd_ActiveObject
)
2610 data
->wd_ActiveObject
= GetLastActiveObject(data
);
2614 data
->wd_ActiveObject
= (Object
*) newval
;
2619 if (data
->wd_ActiveObject
!= NULL
2620 && DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
2621 (IPTR
) data
->wd_ActiveObject
)
2622 && (_flags(data
->wd_ActiveObject
) & MADF_CANDRAW
))
2624 D(bug("Activate=%p\n", data
->wd_ActiveObject
));
2625 DoMethod(data
->wd_ActiveObject
, MUIM_GoActive
);
2626 data
->wd_Flags
|= MUIWF_OBJECTGOACTIVESENT
;
2632 * calculate real dimensions from programmer requirements.
2633 * may be overridden by user settings if MUIA_Window_ID is set.
2635 /* MUIV_Window_Height_Screen and MUIV_Window_Height_Visible
2636 * are not handled yet, as their Width couterparts.
2638 static void WindowSelectDimensions(struct MUI_WindowData
*data
)
2640 if (!data
->wd_Width
)
2642 if (data
->wd_ReqWidth
> 0)
2643 data
->wd_Width
= data
->wd_ReqWidth
;
2644 else if (data
->wd_ReqWidth
== MUIV_Window_Width_Default
)
2645 data
->wd_Width
= data
->wd_MinMax
.DefWidth
;
2646 else if (_between(MUIV_Window_Width_MinMax(100),
2647 data
->wd_ReqWidth
, MUIV_Window_Width_MinMax(0)))
2649 data
->wd_Width
= data
->wd_MinMax
.MinWidth
2651 * (data
->wd_MinMax
.MaxWidth
- data
->wd_MinMax
.MinWidth
);
2653 else if (_between(MUIV_Window_Width_Screen(100),
2654 data
->wd_ReqWidth
, MUIV_Window_Width_Screen(0)))
2656 data
->wd_Width
= data
->wd_RenderInfo
.mri_ScreenWidth
2657 * (-(data
->wd_ReqWidth
+ 200)) / 100;
2659 else if (_between(MUIV_Window_Width_Visible(100),
2660 data
->wd_ReqWidth
, MUIV_Window_Width_Visible(0)))
2662 data
->wd_Width
= data
->wd_RenderInfo
.mri_ScreenWidth
2663 * (-(data
->wd_ReqWidth
+ 100)) / 100;
2666 if (data
->wd_ReqHeight
> 0)
2667 data
->wd_Height
= data
->wd_ReqHeight
;
2668 else if (data
->wd_ReqHeight
== MUIV_Window_Height_Default
)
2669 data
->wd_Height
= data
->wd_MinMax
.DefHeight
;
2670 else if (_between(MUIV_Window_Height_MinMax(100),
2671 data
->wd_ReqHeight
, MUIV_Window_Height_MinMax(0)))
2673 data
->wd_Height
= data
->wd_MinMax
.MinHeight
2674 - data
->wd_ReqHeight
2675 * (data
->wd_MinMax
.MaxHeight
- data
->wd_MinMax
.MinHeight
);
2677 else if (_between(MUIV_Window_Height_Screen(100),
2678 data
->wd_ReqHeight
, MUIV_Window_Height_Screen(0)))
2683 scr
= data
->wd_RenderInfo
.mri_Screen
;
2686 scr
->Height
- data
->wd_RenderInfo
.mri_BorderTop
-
2687 data
->wd_RenderInfo
.mri_BorderBottom
;
2689 /* This is new to Zune: If TopEdge Delta is requested
2690 * the screenheight doesn't cover the barlayer */
2691 if (data
->wd_Y
<= MUIV_Window_TopEdge_Delta(0))
2692 height
-= scr
->BarHeight
+ 1;
2694 data
->wd_Height
= height
* (-(data
->wd_ReqHeight
+ 200)) / 100;
2696 else if (_between(MUIV_Window_Height_Visible(100),
2697 data
->wd_ReqHeight
, MUIV_Window_Height_Visible(0)))
2699 data
->wd_Height
= data
->wd_RenderInfo
.mri_ScreenHeight
2700 * (-(data
->wd_ReqHeight
+ 100)) / 100;
2704 if (data
->wd_ReqWidth
== MUIV_Window_Width_Scaled
)
2705 data
->wd_Width
= data
->wd_Height
* data
->wd_MinMax
.MinWidth
2706 / data
->wd_MinMax
.MinHeight
;
2707 else if (data
->wd_ReqHeight
== MUIV_Window_Width_Scaled
)
2708 data
->wd_Height
= data
->wd_Width
* data
->wd_MinMax
.MinHeight
2709 / data
->wd_MinMax
.MinWidth
;
2711 data
->wd_Width
= CLAMP(data
->wd_Width
, data
->wd_MinMax
.MinWidth
,
2712 data
->wd_MinMax
.MaxWidth
);
2713 data
->wd_Height
= CLAMP(data
->wd_Height
, data
->wd_MinMax
.MinHeight
,
2714 data
->wd_MinMax
.MaxHeight
);
2718 /**************************************************************************
2720 **************************************************************************/
2721 IPTR
Window__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
2723 struct MUI_WindowData
*data
;
2724 struct TagItem
*tags
;
2725 struct TagItem
*tag
;
2727 obj
= (Object
*) DoSuperMethodA(cl
, obj
, (Msg
) msg
);
2731 /* Initial local instance data */
2732 data
= INST_DATA(cl
, obj
);
2734 data
->wd_MemoryPool
= CreatePool(0, 4096, 2048);
2735 if (NULL
== data
->wd_MemoryPool
)
2737 CoerceMethod(cl
, obj
, OM_DISPOSE
);
2741 data
->wd_RenderInfo
.mri_WindowObject
= obj
;
2743 NewList((struct List
*)&(data
->wd_EHList
));
2744 NewList((struct List
*)&(data
->wd_CCList
));
2745 NewList((struct List
*)&(data
->wd_CycleChain
));
2746 NewList((struct List
*)&(data
->wd_IDList
));
2748 data
->wd_CrtFlags
= WFLG_SIZEGADGET
| WFLG_DRAGBAR
| WFLG_DEPTHGADGET
2749 | WFLG_CLOSEGADGET
| WFLG_SIMPLE_REFRESH
2750 | WFLG_REPORTMOUSE
| WFLG_NEWLOOKMENUS
;
2751 data
->wd_ZoomGadget
= TRUE
;
2752 data
->wd_Events
= GetDefaultEvents();
2753 data
->wd_ActiveObject
= NULL
;
2755 data
->wd_ReqHeight
= MUIV_Window_Height_Default
;
2756 data
->wd_ReqWidth
= MUIV_Window_Width_Default
;
2757 data
->wd_RootObject
= NULL
;
2758 data
->wd_DefaultObject
= NULL
;
2760 /* alternate dimensions */
2761 /* no change in coordinates */
2762 data
->wd_AltDim
.Top
= MUIV_Window_AltTopEdge_NoChange
;
2763 data
->wd_AltDim
.Left
= MUIV_Window_AltLeftEdge_NoChange
;
2764 /* default to min size */
2765 data
->wd_AltDim
.Width
= MUIV_Window_AltWidth_MinMax(0);
2766 data
->wd_AltDim
.Height
= MUIV_Window_AltHeight_MinMax(0);
2767 data
->wd_X
= MUIV_Window_LeftEdge_Centered
;
2768 data
->wd_Y
= MUIV_Window_TopEdge_Centered
;
2769 data
->wd_DisabledKeys
= 0L;
2770 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_FIRST
;
2772 /* parse initial taglist */
2774 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
));)
2776 switch (tag
->ti_Tag
)
2778 case MUIA_Window_EraseArea
:
2779 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_ERASEAREA
);
2782 case MUIA_Window_ToolBox
:
2783 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_TOOLBOX
);
2786 case MUIA_Window_CloseGadget
:
2787 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
,
2791 case MUIA_Window_SizeGadget
:
2792 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
,
2796 case MUIA_Window_ZoomGadget
:
2797 data
->wd_ZoomGadget
= tag
->ti_Data
;
2800 case MUIA_Window_Backdrop
:
2801 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
,
2805 case MUIA_Window_Borderless
:
2806 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
,
2810 case MUIA_Window_DepthGadget
:
2811 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
,
2815 case MUIA_Window_DragBar
:
2816 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_DRAGBAR
);
2819 case MUIA_Window_SizeRight
:
2820 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
,
2824 case MUIA_Window_Height
:
2825 data
->wd_ReqHeight
= (LONG
) tag
->ti_Data
;
2828 case MUIA_Window_Width
:
2829 data
->wd_ReqWidth
= (LONG
) tag
->ti_Data
;
2832 case MUIA_Window_ID
:
2833 set(obj
, MUIA_Window_ID
, tag
->ti_Data
);
2836 case MUIA_Window_IsSubWindow
:
2837 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
2841 case MUIA_Window_Title
:
2842 set(obj
, MUIA_Window_Title
, tag
->ti_Data
);
2845 case MUIA_Window_ScreenTitle
:
2846 set(obj
, MUIA_Window_ScreenTitle
, tag
->ti_Data
);
2849 case MUIA_Window_Activate
:
2850 _handle_bool_tag(data
->wd_Flags
, !tag
->ti_Data
,
2851 MUIWF_DONTACTIVATE
);
2854 case MUIA_Window_DefaultObject
:
2855 set(obj
, MUIA_Window_DefaultObject
, tag
->ti_Data
);
2858 case MUIA_Window_Menustrip
:
2859 data
->wd_ChildMenustrip
= (Object
*) tag
->ti_Data
;
2862 case MUIA_Window_NoMenus
:
2863 data
->wd_NoMenus
= (BOOL
) tag
->ti_Data
;
2866 case MUIA_Window_RootObject
:
2869 CoerceMethod(cl
, obj
, OM_DISPOSE
);
2872 set(obj
, MUIA_Window_RootObject
, tag
->ti_Data
);
2875 case MUIA_Window_AltHeight
:
2876 data
->wd_AltDim
.Height
= (WORD
) tag
->ti_Data
;
2879 case MUIA_Window_AltWidth
:
2880 data
->wd_AltDim
.Width
= (WORD
) tag
->ti_Data
;
2883 case MUIA_Window_AltLeftEdge
:
2884 data
->wd_AltDim
.Left
= (WORD
) tag
->ti_Data
;
2887 case MUIA_Window_AltTopEdge
:
2888 data
->wd_AltDim
.Top
= (WORD
) tag
->ti_Data
;
2891 case MUIA_Window_AppWindow
:
2892 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
2896 case MUIA_Window_LeftEdge
:
2897 data
->wd_X
= tag
->ti_Data
;
2900 case MUIA_Window_TopEdge
:
2901 data
->wd_Y
= tag
->ti_Data
;
2904 case MUIA_Window_UseBottomBorderScroller
:
2905 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
2906 MUIWF_USEBOTTOMSCROLLER
);
2909 case MUIA_Window_UseRightBorderScroller
:
2910 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
2911 MUIWF_USERIGHTSCROLLER
);
2914 case MUIA_Window_DisableKeys
:
2915 data
->wd_DisabledKeys
= tag
->ti_Data
;
2918 case MUIA_Window_RefWindow
:
2919 data
->wd_RefWindow
= (Object
*) tag
->ti_Data
;
2922 case MUIA_Window_Screen
:
2923 data
->wd_UserScreen
= (struct Screen
*)tag
->ti_Data
;
2926 case MUIA_Window_PublicScreen
:
2927 data
->wd_UserPublicScreen
= (STRPTR
) tag
->ti_Data
;
2932 /* D(bug("muimaster.library/window.c: Window Object created at " */
2933 /* "0x%lx back=%lx\n", */
2934 /* obj,data->wd_Background)); */
2939 /**************************************************************************
2941 **************************************************************************/
2942 IPTR
Window__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
2944 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
2946 /* D(bug("Window_Dispose(%p)\n", obj)); */
2949 /* We no longer clear muiGlobalInfo() during disconnections, so
2950 this can cause problems (remove object which is already removed).
2951 Furthermore AFAIK it is not legal to dispose a window object
2952 which is still ocnnected to the application object, anyway. */
2954 if (muiGlobalInfo(obj
) && _app(obj
))
2956 /* D(bug(" Window_Dispose(%p) : calling app->OM_REMMEMBER\n", obj)); */
2957 DoMethod(_app(obj
), OM_REMMEMBER
, (IPTR
) obj
);
2961 if (data
->wd_RootObject
)
2962 MUI_DisposeObject(data
->wd_RootObject
);
2964 if (data
->wd_ChildMenustrip
)
2965 MUI_DisposeObject(data
->wd_ChildMenustrip
);
2968 FreeVec(data
->wd_Title
);
2970 if (data
->wd_ScreenTitle
)
2971 FreeVec(data
->wd_ScreenTitle
);
2973 DeletePool(data
->wd_MemoryPool
);
2975 /* D(bug(" Window_Dispose(%p) : calling supermethod\n", obj)); */
2976 return DoSuperMethodA(cl
, obj
, msg
);
2979 static ULONG
WindowOpen(struct IClass
*cl
, Object
*obj
);
2980 static ULONG
WindowClose(struct IClass
*cl
, Object
*obj
);
2982 /**************************************************************************
2984 **************************************************************************/
2985 IPTR
Window__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
2987 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
2988 struct TagItem
*tags
= msg
->ops_AttrList
;
2989 struct TagItem
*tag
;
2991 while ((tag
= NextTagItem(&tags
)) != NULL
)
2993 switch (tag
->ti_Tag
)
2995 case MUIA_Window_Activate
:
2996 if (data
->wd_RenderInfo
.mri_Window
)
2998 if (tag
->ti_Data
&& !(data
->wd_Flags
& MUIWF_ACTIVE
))
3000 ActivateWindow(data
->wd_RenderInfo
.mri_Window
);
3001 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
3006 _handle_bool_tag(data
->wd_Flags
, !tag
->ti_Data
,
3007 MUIWF_DONTACTIVATE
);
3010 case MUIA_Window_ActiveObject
:
3011 /* D(bug("MUIA_Window_ActiveObject %ld (%p)\n", */
3012 /* tag->ti_Data, tag->ti_Data)); */
3013 SetActiveObject(data
, obj
, tag
->ti_Data
);
3016 case MUIA_Window_DefaultObject
:
3017 data
->wd_DefaultObject
= (APTR
) tag
->ti_Data
;
3020 case MUIA_Window_ID
:
3021 data
->wd_ID
= tag
->ti_Data
;
3024 case MUIA_Window_IsSubWindow
:
3025 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
3029 case MUIA_Window_Open
:
3032 if (data
->wd_Flags
& MUIWF_HIDDEN
)
3033 data
->wd_Flags
|= MUIWF_OPENONUNHIDE
;
3034 else if (!(data
->wd_Flags
& MUIWF_OPENED
))
3035 WindowOpen(cl
, obj
);
3038 DoMethod(obj
, MUIM_Window_ToFront
);
3039 set(obj
, MUIA_Window_Activate
, TRUE
);
3042 else if (data
->wd_Flags
& MUIWF_HIDDEN
)
3043 data
->wd_Flags
&= ~MUIWF_OPENONUNHIDE
;
3044 else if (data
->wd_Flags
& MUIWF_OPENED
)
3045 WindowClose(cl
, obj
);
3048 case MUIA_ShowMe
: /* PRIVATE *abuse* of the Area's ShowMe attr */
3053 if (data
->wd_Flags
& MUIWF_HIDDEN
)
3055 data
->wd_Flags
&= ~MUIWF_HIDDEN
;
3057 if (data
->wd_Flags
& MUIWF_OPENONUNHIDE
)
3059 data
->wd_Flags
&= ~MUIWF_OPENONUNHIDE
;
3060 set(obj
, MUIA_Window_Open
, TRUE
);
3068 if (data
->wd_Flags
& MUIWF_OPENED
)
3070 data
->wd_Flags
|= MUIWF_OPENONUNHIDE
;
3072 set(obj
, MUIA_Window_Open
, FALSE
);
3075 data
->wd_Flags
|= MUIWF_HIDDEN
;
3079 case MUIA_Window_RootObject
:
3080 ChangeRootObject(data
, obj
, (Object
*) tag
->ti_Data
);
3083 case MUIA_Window_Title
:
3085 FreeVec(data
->wd_Title
);
3086 data
->wd_Title
= StrDup((STRPTR
) tag
->ti_Data
);
3087 if (data
->wd_RenderInfo
.mri_Window
)
3088 SetWindowTitles(data
->wd_RenderInfo
.mri_Window
,
3089 data
->wd_Title
, (CONST_STRPTR
) ~ 0);
3092 case MUIA_Window_ScreenTitle
:
3093 if (data
->wd_ScreenTitle
)
3094 FreeVec(data
->wd_ScreenTitle
);
3095 data
->wd_ScreenTitle
= StrDup((STRPTR
) tag
->ti_Data
);
3096 if (data
->wd_RenderInfo
.mri_Window
)
3097 SetWindowTitles(data
->wd_RenderInfo
.mri_Window
,
3098 (CONST_STRPTR
) ~ 0, data
->wd_ScreenTitle
);
3101 case MUIA_Window_NoMenus
:
3102 data
->wd_NoMenus
= (BOOL
) tag
->ti_Data
;
3103 if (data
->wd_RenderInfo
.mri_Window
)
3105 if (data
->wd_NoMenus
)
3106 data
->wd_RenderInfo
.mri_Window
->Flags
|= WFLG_RMBTRAP
;
3108 data
->wd_RenderInfo
.mri_Window
->Flags
&= ~WFLG_RMBTRAP
;
3112 case MUIA_Window_UseBottomBorderScroller
:
3113 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
3114 MUIWF_USEBOTTOMSCROLLER
);
3117 case MUIA_Window_UseRightBorderScroller
:
3118 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
3119 MUIWF_USERIGHTSCROLLER
);
3122 case MUIA_Window_DisableKeys
:
3123 data
->wd_DisabledKeys
= tag
->ti_Data
;
3126 case MUIA_Window_RefWindow
:
3127 data
->wd_RefWindow
= (Object
*) tag
->ti_Data
;
3130 case MUIA_Window_LeftEdge
:
3131 data
->wd_X
= tag
->ti_Data
;
3134 case MUIA_Window_TopEdge
:
3135 data
->wd_Y
= tag
->ti_Data
;
3138 case MUIA_Window_Width
:
3139 data
->wd_ReqWidth
= (LONG
) tag
->ti_Data
;
3140 data
->wd_Width
= 0; /* otherwise windowselectdimensions()
3141 * ignores ReqWidth */
3144 case MUIA_Window_Height
:
3145 data
->wd_ReqHeight
= (LONG
) tag
->ti_Data
;
3146 data
->wd_Height
= 0;
3149 case MUIA_Window_Screen
:
3150 data
->wd_UserScreen
= (struct Screen
*)tag
->ti_Data
;
3153 case MUIA_Window_PublicScreen
:
3154 data
->wd_UserPublicScreen
= (STRPTR
) tag
->ti_Data
;
3157 case MUIA_Window_Sleep
:
3160 data
->wd_SleepCount
++;
3161 if (data
->wd_RenderInfo
.mri_Window
3162 && (data
->wd_SleepCount
== 1))
3165 (data
->wd_RenderInfo
.mri_Window
,
3166 WA_BusyPointer
, TRUE
,
3167 WA_PointerDelay
, TRUE
, TAG_DONE
);
3168 // FIXME: how to disable event handling?
3173 data
->wd_SleepCount
--;
3174 if (data
->wd_RenderInfo
.mri_Window
3175 && (data
->wd_SleepCount
== 0))
3177 SetWindowPointerA(data
->wd_RenderInfo
.mri_Window
, NULL
);
3185 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
3188 /**************************************************************************
3190 **************************************************************************/
3191 IPTR
Window__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
3193 #define STORE *(msg->opg_Storage)
3195 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3199 switch (msg
->opg_AttrID
)
3201 case MUIA_Window_Activate
:
3203 (data
->wd_Flags
& (MUIWF_ACTIVE
| MUIWF_OPENED
)) ==
3204 (MUIWF_ACTIVE
| MUIWF_OPENED
);
3207 case MUIA_Window_Window
:
3208 STORE
= (IPTR
) data
->wd_RenderInfo
.mri_Window
;
3211 case MUIA_Window_Screen
:
3212 STORE
= (IPTR
) data
->wd_RenderInfo
.mri_Screen
;
3215 case MUIA_Window_PublicScreen
:
3216 STORE
= (IPTR
) data
->wd_UserPublicScreen
;
3219 case MUIA_Window_ActiveObject
:
3220 if ((data
->wd_ActiveObject
!= NULL
)
3221 && (DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
3222 (IPTR
) data
->wd_ActiveObject
) != (IPTR
) NULL
))
3223 STORE
= (IPTR
) data
->wd_ActiveObject
;
3225 STORE
= (IPTR
) NULL
;
3228 case MUIA_Window_CloseRequest
:
3232 case MUIA_Window_DefaultObject
:
3233 STORE
= (IPTR
) data
->wd_DefaultObject
;
3236 case MUIA_Window_DisableKeys
:
3237 STORE
= data
->wd_DisabledKeys
;
3240 case MUIA_Window_Height
:
3241 STORE
= (IPTR
) data
->wd_Height
;
3244 case MUIA_Window_ID
:
3245 STORE
= data
->wd_ID
;
3248 case MUIA_Window_IsSubWindow
:
3249 STORE
= (data
->wd_Flags
& MUIWF_ISSUBWINDOW
) == MUIWF_ISSUBWINDOW
;
3252 case MUIA_Window_LeftEdge
:
3253 if (data
->wd_RenderInfo
.mri_Window
)
3254 STORE
= (IPTR
) data
->wd_RenderInfo
.mri_Window
->LeftEdge
;
3259 case MUIA_Window_Open
:
3260 STORE
= (data
->wd_Flags
& MUIWF_OPENED
) == MUIWF_OPENED
;
3263 case MUIA_Window_RootObject
:
3264 STORE
= (IPTR
) data
->wd_RootObject
;
3267 case MUIA_Window_ScreenTitle
:
3268 STORE
= (IPTR
) data
->wd_ScreenTitle
;
3271 case MUIA_Window_Title
:
3272 STORE
= (IPTR
) data
->wd_Title
;
3275 case MUIA_Window_TopEdge
:
3276 if (data
->wd_RenderInfo
.mri_Window
)
3277 STORE
= (IPTR
) data
->wd_RenderInfo
.mri_Window
->TopEdge
;
3282 case MUIA_Window_Width
:
3283 STORE
= (IPTR
) data
->wd_Width
;
3286 case MUIA_Window_Menustrip
:
3287 STORE
= (IPTR
) data
->wd_ChildMenustrip
;
3290 case MUIA_Window_Sleep
:
3291 STORE
= data
->wd_SleepCount
? TRUE
: FALSE
;
3303 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
3308 * MUIM_FindUData : tests if the MUIA_UserData of the object
3309 * contains the given <udata> and returns the object pointer in this case.
3311 IPTR
Window__MUIM_FindUData(struct IClass
*cl
, Object
*obj
,
3312 struct MUIP_FindUData
*msg
)
3314 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3316 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3319 if (data
->wd_RootObject
)
3320 return DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
3327 * MUIM_GetUData : This method tests if the MUIA_UserData of the object
3328 * contains the given <udata> and gets <attr> to <storage> for itself
3331 IPTR
Window__MUIM_GetUData(struct IClass
*cl
, Object
*obj
,
3332 struct MUIP_GetUData
*msg
)
3334 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3336 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3338 get(obj
, msg
->attr
, msg
->storage
);
3342 if (data
->wd_RootObject
)
3343 return DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
3350 * MUIM_SetUData : This method tests if the MUIA_UserData of the object
3351 * contains the given <udata> and sets <attr> to <val> for itself in this case.
3353 IPTR
Window__MUIM_SetUData(struct IClass
*cl
, Object
*obj
,
3354 struct MUIP_SetUData
*msg
)
3356 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3358 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3359 set(obj
, msg
->attr
, msg
->val
);
3361 if (data
->wd_RootObject
)
3362 DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
3369 * MUIM_SetUDataOnce : This method tests if the MUIA_UserData of the object
3370 * contains the given <udata> and sets <attr> to <val> for itself in this case.
3372 IPTR
Window__MUIM_SetUDataOnce(struct IClass
*cl
, Object
*obj
,
3373 struct MUIP_SetUDataOnce
*msg
)
3375 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3377 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3379 set(obj
, msg
->attr
, msg
->val
);
3383 if (data
->wd_RootObject
)
3384 return DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
3389 /**************************************************************************
3390 Called by Application (parent) object whenever this object is added.
3392 **************************************************************************/
3393 IPTR
Window__MUIM_ConnectParent(struct IClass
*cl
, Object
*obj
,
3394 struct MUIP_ConnectParent
*msg
)
3396 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3398 if (!DoSuperMethodA(cl
, obj
, (Msg
) msg
))
3401 if (data
->wd_RootObject
)
3402 DoMethod(data
->wd_RootObject
, MUIM_ConnectParent
, (IPTR
) obj
);
3404 if (data
->wd_ChildMenustrip
)
3405 DoMethod(data
->wd_ChildMenustrip
, MUIM_ConnectParent
, (IPTR
) obj
);
3411 /**************************************************************************
3412 called by parent object
3413 **************************************************************************/
3414 IPTR
Window__MUIM_DisconnectParent(struct IClass
*cl
, Object
*obj
,
3415 struct MUIP_DisconnectParent
*msg
)
3417 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3419 /* D(bug("Window_DisconnectParent(%p) : muiGlobalInfo=%p\n", */
3420 /* muiGlobalInfo(obj))); */
3421 if (muiGlobalInfo(obj
))
3423 /* Close the window before disconnecting all the childs */
3424 if ((data
->wd_Flags
& MUIWF_OPENED
))
3426 /* D(bug(" Window_DisconnectParent(%p) : closing window\n", */
3427 /* muiGlobalInfo(obj))); */
3428 set(obj
, MUIA_Window_Open
, FALSE
);
3430 if (data
->wd_ChildMenustrip
)
3431 DoMethod(data
->wd_ChildMenustrip
, MUIM_DisconnectParent
,
3434 if (data
->wd_RootObject
)
3435 DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
3437 /* D(bug(" Window_DisconnectParent(%p) : calling supermethod\n", */
3438 /* muiGlobalInfo(obj))); */
3439 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
3447 static void SetRootObjInnerSpacing(Object
*obj
,
3448 struct MUI_WindowData
*data
)
3450 UWORD wd_innerLeft
, wd_innerRight
, wd_innerTop
, wd_innerBottom
;
3452 if (data
->wd_CrtFlags
& WFLG_BORDERLESS
)
3461 wd_innerLeft
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_left
;
3462 wd_innerRight
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_right
;
3463 wd_innerTop
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_top
;
3464 wd_innerBottom
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_bottom
;
3467 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERLEFT
))
3469 muiAreaData(data
->wd_RootObject
)->mad_InnerLeft
= wd_innerLeft
;
3472 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERTOP
))
3474 muiAreaData(data
->wd_RootObject
)->mad_InnerTop
= wd_innerTop
;
3477 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERRIGHT
))
3479 muiAreaData(data
->wd_RootObject
)->mad_InnerRight
= wd_innerRight
;
3482 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERBOTTOM
))
3484 muiAreaData(data
->wd_RootObject
)->mad_InnerBottom
= wd_innerBottom
;
3489 * Called before window is opened or resized. It determines its bounds,
3490 * so you can call WindowSelectDimensions() to find the final dims.
3492 static void WindowMinMax(Object
*obj
, struct MUI_WindowData
*data
)
3494 SetRootObjInnerSpacing(obj
, data
);
3495 /* inquire about sizes */
3496 DoMethod(data
->wd_RootObject
, MUIM_AskMinMax
, (IPTR
) & data
->wd_MinMax
);
3497 /* D(bug("*** root minmax = %ld,%ld => %ld,%ld\n", */
3498 /* data->wd_MinMax.MinWidth, */
3499 /* data->wd_MinMax.MinHeight, */
3500 /* data->wd_MinMax.MaxWidth, data->wd_MinMax.MaxHeight)); */
3501 __area_finish_minmax(data
->wd_RootObject
, &data
->wd_MinMax
);
3502 /* D(bug("*** root minmax2 = %ld,%ld => %ld,%ld\n", */
3503 /* data->wd_MinMax.MinWidth, */
3504 /* data->wd_MinMax.MinHeight, */
3505 /* data->wd_MinMax.MaxWidth, data->wd_MinMax.MaxHeight)); */
3509 static void InstallBackbuffer(struct IClass
*cl
, Object
*obj
)
3511 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3513 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
3515 data
->wd_RenderInfo
.mri_BufferBM
=
3516 AllocBitMap(win
->Width
, win
->Height
, win
->RPort
->BitMap
->Depth
,
3517 0, win
->RPort
->BitMap
);
3519 if (data
->wd_RenderInfo
.mri_BufferBM
)
3521 /* D(bug("install_backbuffer : allocated bitmap %dx%dx%d " */
3522 /* "with friend %p\n", */
3523 /* win->Width, win->Height, win->RPort->BitMap->Depth, */
3524 /* win->RPort->BitMap)); */
3525 InitRastPort(&data
->wd_RenderInfo
.mri_BufferRP
);
3526 data
->wd_RenderInfo
.mri_BufferRP
.BitMap
=
3527 data
->wd_RenderInfo
.mri_BufferBM
;
3531 static void DeinstallBackbuffer(struct IClass
*cl
, Object
*obj
)
3533 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3535 if (data
->wd_RenderInfo
.mri_BufferBM
)
3537 DeinitRastPort(&data
->wd_RenderInfo
.mri_BufferRP
);
3538 FreeBitMap(data
->wd_RenderInfo
.mri_BufferBM
);
3539 data
->wd_RenderInfo
.mri_BufferBM
= NULL
;
3544 * Called after window is opened or resized.
3545 * An expose event is already queued, it will trigger
3546 * MUIM_Draw for us when going back to main loop.
3548 static void WindowShow(struct IClass
*cl
, Object
*obj
)
3550 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3551 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
3552 /* D(bug("window_show %s %d\n", __FILE__, __LINE__)); */
3554 _left(data
->wd_RootObject
) = win
->BorderLeft
;
3555 _top(data
->wd_RootObject
) = win
->BorderTop
;
3556 _width(data
->wd_RootObject
) = data
->wd_Width
;
3557 _height(data
->wd_RootObject
) = data
->wd_Height
;
3559 DoMethod(data
->wd_RootObject
, MUIM_Layout
);
3561 ShowRenderInfo(&data
->wd_RenderInfo
);
3562 /* D(bug("zune_imspec_show %s %d\n", __FILE__, __LINE__)); */
3563 zune_imspec_show(data
->wd_Background
, obj
);
3564 DoShowMethod(data
->wd_RootObject
);
3567 static ULONG
WindowOpen(struct IClass
*cl
, Object
*obj
)
3569 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3571 if (!data
->wd_RootObject
)
3574 if (!DoMethod(obj
, MUIM_Window_Setup
))
3577 /* I got display info, so calculate your display dependant data */
3578 if (!DoSetupMethod(data
->wd_RootObject
, &data
->wd_RenderInfo
))
3580 DoMethod(obj
, MUIM_Window_Cleanup
);
3584 /* inquire about sizes */
3585 WindowMinMax(obj
, data
);
3586 WindowSelectDimensions(data
);
3588 /* Decide which menustrip should be used */
3589 if (!data
->wd_ChildMenustrip
)
3590 get(_app(obj
), MUIA_Application_Menustrip
, &data
->wd_Menustrip
);
3592 data
->wd_Menustrip
= data
->wd_ChildMenustrip
;
3594 /* open window here ... */
3595 if (!DisplayWindow(obj
, data
))
3597 /* free display dependant data */
3598 data
->wd_Menustrip
= NULL
;
3599 DoMethod(data
->wd_RootObject
, MUIM_Cleanup
);
3600 DoMethod(obj
, MUIM_Window_Cleanup
);
3604 InstallBackbuffer(cl
, obj
);
3606 data
->wd_Flags
|= MUIWF_OPENED
;
3608 WindowShow(cl
, obj
);
3611 LONG left
, top
, width
, height
;
3613 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
3614 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
,
3615 width
= data
->wd_RenderInfo
.mri_Window
->Width
3616 - data
->wd_RenderInfo
.mri_Window
->BorderRight
- left
;
3617 height
= data
->wd_RenderInfo
.mri_Window
->Height
3618 - data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
3620 /* D(bug("zune_imspec_draw %s %d\n", __FILE__, __LINE__)); */
3621 // D(bug("%d:zune_imspec_draw(%p) l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
3622 // __LINE__, data->wd_Background, left, top, width,
3623 // height, left, top));
3625 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
3626 left
, top
, width
, height
, left
, top
, 0);
3629 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWOBJECT
);
3631 D(bug("MUIC_Window:windowOpen() ActiveObject=%p\n",
3632 data
->wd_ActiveObject
));
3633 if (data
->wd_OldActive
!= NULL
)
3635 set(obj
, MUIA_Window_ActiveObject
, data
->wd_OldActive
);
3641 /**************************************************************************/
3642 /**************************************************************************/
3644 static ULONG
WindowClose(struct IClass
*cl
, Object
*obj
)
3646 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3648 if (data
->wd_ActiveObject
!= NULL
)
3650 data
->wd_OldActive
= data
->wd_ActiveObject
;
3651 set(obj
, MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_None
);
3654 KillHelpBubble(data
, obj
, BUBBLEHELP_TICKER_FIRST
);
3656 /* remove from window */
3657 DoHideMethod(data
->wd_RootObject
);
3658 zune_imspec_hide(data
->wd_Background
);
3660 DeinstallBackbuffer(cl
, obj
);
3662 HideRenderInfo(&data
->wd_RenderInfo
);
3664 /* close here ... */
3665 UndisplayWindow(obj
, data
);
3667 data
->wd_Flags
&= ~MUIWF_OPENED
;
3668 data
->wd_Menustrip
= NULL
;
3670 /* free display dependant data */
3671 DoMethod(data
->wd_RootObject
, MUIM_Cleanup
);
3672 DoMethod(obj
, MUIM_Window_Cleanup
);
3676 /* calculate a new layout
3678 * see Group_ExitChange
3682 IPTR
Window__MUIM_RecalcDisplay(struct IClass
*cl
, Object
*obj
,
3683 struct MUIP_Window_RecalcDisplay
*msg
)
3685 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3686 LONG left
, top
, width
, height
;
3687 BOOL resized
, reshow
= FALSE
;
3688 Object
*current_obj
;
3690 if (!(data
->wd_Flags
& MUIWF_OPENED
))
3693 current_obj
= msg
->originator
;
3695 // typically originator is a group which has been added/removed a child
3696 // calculate minmax of current obj
3697 // if new minmax can accomodate current obj size, stop
3698 // else try with its parent
3699 // the resulting object will get a new layout
3700 // it currently produces some redundant AskMinMax but allows
3701 // to not always relayout the whole window
3703 D(bug("RecalcDisplay on %p\n", current_obj
));
3704 while (current_obj
!= NULL
)
3706 DoMethod(current_obj
, MUIM_AskMinMax
,
3707 (IPTR
) & muiAreaData(current_obj
)->mad_MinMax
);
3708 __area_finish_minmax(current_obj
,
3709 &muiAreaData(current_obj
)->mad_MinMax
);
3711 D(bug("size w = %d, h = %d\n", _width(current_obj
),
3712 _height(current_obj
)));
3713 D(bug("new w = %d-%d, h = %d-%d\n", _minwidth(current_obj
),
3714 _maxwidth(current_obj
), _minheight(current_obj
),
3715 _maxheight(current_obj
)));
3717 if (!_between(_minwidth(current_obj
), _width(current_obj
),
3718 _maxwidth(current_obj
))
3719 || !_between(_minheight(current_obj
), _height(current_obj
),
3720 _maxheight(current_obj
)))
3722 current_obj
= _parent(current_obj
);
3723 D(bug("RecalcDisplay, try parent %p\n", current_obj
));
3727 D(bug("found it\n"));
3733 current_obj
= data
->wd_RootObject
;
3735 WindowMinMax(obj
, data
);
3737 /* Important: current_obj could be hidden, like in an inactive page! */
3738 if (_flags(current_obj
) & MADF_CANDRAW
)
3744 DoHideMethod(current_obj
);
3746 /* resize window ? */
3747 WindowSelectDimensions(data
);
3748 resized
= WindowResize(data
);
3752 /* FIXME: Should we short circuit the following
3753 * if the window size didn't change?
3758 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
3759 _left(data
->wd_RootObject
) = win
->BorderLeft
;
3760 _top(data
->wd_RootObject
) = win
->BorderTop
;
3761 _width(data
->wd_RootObject
) = data
->wd_Width
;
3762 _height(data
->wd_RootObject
) = data
->wd_Height
;
3764 DoMethod(current_obj
, MUIM_Layout
);
3767 DoShowMethod(current_obj
);
3769 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_redraw
==
3770 WINDOW_REDRAW_WITHOUT_CLEAR
)
3773 MUI_Redraw(current_obj
, MADF_DRAWOBJECT
);
3777 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
3778 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
;
3779 width
= data
->wd_RenderInfo
.mri_Window
->Width
3780 - data
->wd_RenderInfo
.mri_Window
->BorderRight
- left
;
3781 height
= data
->wd_RenderInfo
.mri_Window
->Height
3782 - data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
3784 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
3785 left
, top
, width
, height
, left
, top
, 0);
3786 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWALL
);
3789 ActivateObject(data
);
3795 /**************************************************************************
3796 MUIM_AddEventHandler
3797 **************************************************************************/
3798 IPTR
Window__MUIM_AddEventHandler(struct IClass
*cl
, Object
*obj
,
3799 struct MUIP_Window_AddEventHandler
*msg
)
3801 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3803 //D(bug("muimaster.library/window.c: Add Eventhandler %p\n", msg->ehnode));
3805 msg
->ehnode
->ehn_Priority
= msg
->ehnode
->ehn_Priority
;
3806 EnqueueByPriAndAddress((struct List
*)&data
->wd_EHList
,
3807 (struct Node
*)msg
->ehnode
);
3808 ChangeEvents(data
, GetDefaultEvents());
3812 /**************************************************************************
3813 MUIM_RemEventHandler
3814 **************************************************************************/
3815 IPTR
Window__MUIM_RemEventHandler(struct IClass
*cl
, Object
*obj
,
3816 struct MUIP_Window_RemEventHandler
*msg
)
3818 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3820 //D(bug("muimaster.library/window.c: Rem Eventhandler %p\n", msg->ehnode));
3822 Remove((struct Node
*)msg
->ehnode
);
3823 ChangeEvents(data
, GetDefaultEvents());
3827 /**************************************************************************
3828 Note that this is MUIM_Window_Setup, not MUIM_Setup
3829 **************************************************************************/
3830 IPTR
Window__MUIM_Setup(struct IClass
*cl
, Object
*obj
, Msg msg
)
3832 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3834 if (!SetupRenderInfo(obj
, data
, &data
->wd_RenderInfo
))
3837 data
->wd_Background
=
3838 zune_imspec_setup(MUII_WindowBack
, &data
->wd_RenderInfo
);
3840 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_redraw
==
3841 WINDOW_REDRAW_WITH_CLEAR
)
3842 data
->wd_Flags
|= MUIWF_ERASEAREA
;
3847 /**************************************************************************
3849 **************************************************************************/
3850 IPTR
Window__MUIM_Cleanup(struct IClass
*cl
, Object
*obj
, Msg msg
)
3852 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3854 zune_imspec_cleanup(data
->wd_Background
);
3858 DeleteDragNDrop(data
->wd_dnd
);
3859 data
->wd_dnd
= NULL
;
3862 CleanupRenderInfo(obj
, data
, &data
->wd_RenderInfo
);
3867 /**************************************************************************
3868 This adds the the control char handler and also do the MUIA_CycleChain
3869 stuff. Orginal MUI does this in an other way.
3870 **************************************************************************/
3871 IPTR
Window__MUIM_AddControlCharHandler(struct IClass
*cl
, Object
*obj
,
3872 struct MUIP_Window_AddControlCharHandler
*msg
)
3874 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3875 struct ObjNode
*node
;
3877 if (msg
->ccnode
->ehn_Events
)
3879 msg
->ccnode
->ehn_Priority
= msg
->ccnode
->ehn_Priority
;
3880 Enqueue((struct List
*)&data
->wd_CCList
,
3881 (struct Node
*)msg
->ccnode
);
3883 /* Due to the lack of a better idea ... */
3884 if (muiAreaData(msg
->ccnode
->ehn_Object
)->mad_Flags
& MADF_CYCLECHAIN
)
3886 node
= AllocPooled(data
->wd_MemoryPool
, sizeof(struct ObjNode
));
3889 node
->obj
= msg
->ccnode
->ehn_Object
;
3890 AddTail((struct List
*)&data
->wd_CycleChain
,
3891 (struct Node
*)node
);
3897 /**************************************************************************
3898 MUIM_RemControlCharHandler
3899 **************************************************************************/
3900 IPTR
Window__MUIM_RemControlCharHandler(struct IClass
*cl
, Object
*obj
,
3901 struct MUIP_Window_RemControlCharHandler
*msg
)
3903 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3904 struct ObjNode
*node
=
3905 FindObjNode(&data
->wd_CycleChain
, msg
->ccnode
->ehn_Object
);
3907 if (msg
->ccnode
->ehn_Events
)
3908 Remove((struct Node
*)msg
->ccnode
);
3912 /* Remove from the chain list */
3913 Remove((struct Node
*)node
);
3914 FreePooled(data
->wd_MemoryPool
, node
, sizeof(struct ObjNode
));
3920 /**************************************************************************
3922 **************************************************************************/
3923 IPTR
Window__MUIM_DragObject(struct IClass
*cl
, Object
*obj
,
3924 struct MUIP_Window_DragObject
*msg
)
3926 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3929 struct DragNDrop
*dnd
;
3930 struct MUI_DragImage
*di
;
3931 struct BitMapNode
*bmn
;
3933 if (!(dnd
= CreateDragNDropA(NULL
)))
3937 (struct MUI_DragImage
*)DoMethod(msg
->obj
,
3938 MUIM_CreateDragImage
, -msg
->touchx
, -msg
->touchy
,
3941 DeleteDragNDrop(dnd
);
3946 DoMethod(msg
->obj
, MUIM_DeleteDragImage
, (IPTR
) di
);
3947 DeleteDragNDrop(dnd
);
3951 if (!(bmn
= CreateBitMapNodeA(TAGLIST(
3952 GUI_BitMap
, (IPTR
)di
->bm
,
3953 GUI_LeftOffset
, di
->touchx
,
3954 GUI_TopOffset
, di
->touchy
,
3955 GUI_Width
, di
->width
,
3956 GUI_Height
, di
->height
,
3957 GUI_SourceAlpha
, !!(di
->flags
& MUIF_DRAGIMAGE_SOURCEALPHA
)))))
3959 DoMethod(msg
->obj
, MUIM_DeleteDragImage
, (IPTR
) di
);
3960 DeleteDragNDrop(dnd
);
3964 AttachBitMapNode(dnd
, bmn
);
3966 if (!PrepareDragNDrop(dnd
, data
->wd_RenderInfo
.mri_Screen
))
3968 DoMethod(msg
->obj
, MUIM_DeleteDragImage
, (IPTR
) di
);
3969 DeleteDragNDrop(dnd
);
3973 muiAreaData(msg
->obj
)->mad_Flags
|= MADF_DRAGGING
;
3975 data
->wd_DragObject
= msg
->obj
;
3977 data
->wd_DragImage
= di
;
3983 /**************************************************************************
3985 **************************************************************************/
3986 IPTR
Window__MUIM_AllocGadgetID(struct IClass
*cl
, Object
*obj
,
3987 struct MUIP_Window_AllocGadgetID
*msg
)
3989 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3990 struct IDNode
*newnode
;
3992 newnode
= AllocPooled(data
->wd_MemoryPool
, sizeof(struct IDNode
));
3998 if (IsListEmpty((struct List
*)&data
->wd_IDList
))
4001 AddHead((struct List
*)&data
->wd_IDList
,
4002 (struct Node
*)&newnode
->node
);
4008 for (mn
= data
->wd_IDList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
4010 struct IDNode
*idn
= (struct IDNode
*)mn
;
4016 Insert((struct List
*)&data
->wd_IDList
,
4017 (struct Node
*)&newnode
->node
, (struct Node
*)mn
);
4024 /**************************************************************************
4026 **************************************************************************/
4027 IPTR
Window__MUIM_FreeGadgetID(struct IClass
*cl
, Object
*obj
,
4028 struct MUIP_Window_FreeGadgetID
*msg
)
4030 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4033 for (mn
= data
->wd_IDList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
4035 struct IDNode
*idn
= (struct IDNode
*)mn
;
4036 if (msg
->gadgetid
== idn
->id
)
4038 Remove((struct Node
*)idn
);
4039 FreePooled(data
->wd_MemoryPool
, idn
, sizeof(struct IDNode
));
4048 /**************************************************************************
4049 MUIM_Window_GetMenuCheck
4050 **************************************************************************/
4051 IPTR
Window__MUIM_GetMenuCheck(struct IClass
*cl
, Object
*obj
,
4052 struct MUIP_Window_GetMenuCheck
*msg
)
4055 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4057 Object
*strip
= data
->wd_ChildMenustrip
;
4059 strip
= data
->wd_Menustrip
;
4062 if (!(item
= (Object
*) DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
)))
4064 get(item
, MUIA_Menuitem_Checked
, &stat
);
4068 /**************************************************************************
4069 MUIM_Window_SetMenuCheck
4070 **************************************************************************/
4071 IPTR
Window__MUIM_SetMenuCheck(struct IClass
*cl
, Object
*obj
,
4072 struct MUIP_Window_SetMenuCheck
*msg
)
4074 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4076 Object
*strip
= data
->wd_ChildMenustrip
;
4078 strip
= data
->wd_Menustrip
;
4081 if (!(item
= (Object
*) DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
)))
4083 set(item
, MUIA_Menuitem_Checked
, msg
->stat
);
4087 /**************************************************************************
4088 MUIM_Window_GetMenuState
4089 **************************************************************************/
4090 IPTR
Window__MUIM_GetMenuState(struct IClass
*cl
, Object
*obj
,
4091 struct MUIP_Window_GetMenuState
*msg
)
4094 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4096 Object
*strip
= data
->wd_ChildMenustrip
;
4098 strip
= data
->wd_Menustrip
;
4101 if (!(item
= (Object
*) DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
)))
4103 get(item
, MUIA_Menuitem_Enabled
, &stat
);
4107 /**************************************************************************
4108 MUIM_Window_SetMenuState
4109 **************************************************************************/
4110 IPTR
Window__MUIM_SetMenuState(struct IClass
*cl
, Object
*obj
,
4111 struct MUIP_Window_SetMenuState
*msg
)
4113 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4115 Object
*strip
= data
->wd_ChildMenustrip
;
4117 strip
= data
->wd_Menustrip
;
4120 if (!(item
= (Object
*) DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
)))
4122 set(item
, MUIA_Menuitem_Enabled
, msg
->stat
);
4126 /**************************************************************************
4127 MUIM_Window_DrawBackground
4128 **************************************************************************/
4129 IPTR
Window__MUIM_DrawBackground(struct IClass
*cl
, Object
*obj
,
4130 struct MUIP_Window_DrawBackground
*msg
)
4132 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4133 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
4136 // D(bug("%d:zune_imspec_draw(%p) l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
4137 // __LINE__, data->wd_Background, msg->left, msg->top, msg->width,
4138 // msg->height, msg->xoffset, msg->yoffset));
4139 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
4140 msg
->left
, msg
->top
, msg
->width
, msg
->height
,
4141 msg
->xoffset
, msg
->yoffset
, 0);
4145 /**************************************************************************
4147 **************************************************************************/
4148 IPTR
Window__MUIM_ToFront(struct IClass
*cl
, Object
*obj
, Msg msg
)
4150 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4151 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
4154 WindowToFront(data
->wd_RenderInfo
.mri_Window
);
4158 /**************************************************************************
4160 **************************************************************************/
4161 IPTR
Window__MUIM_ToBack(struct IClass
*cl
, Object
*obj
, Msg msg
)
4163 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4164 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
4167 WindowToBack(data
->wd_RenderInfo
.mri_Window
);
4171 /**************************************************************************
4172 MUIM_Window_ScreenToBack
4173 **************************************************************************/
4174 IPTR
Window__MUIM_ScreenToBack(struct IClass
*cl
, Object
*obj
, Msg msg
)
4176 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4177 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
4180 ScreenToBack(data
->wd_RenderInfo
.mri_Screen
);
4184 /**************************************************************************
4185 MUIM_Window_ScreenToFront
4186 **************************************************************************/
4187 IPTR
Window__MUIM_ScreenToFront(struct IClass
*cl
, Object
*obj
, Msg msg
)
4189 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4190 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
4193 ScreenToFront(data
->wd_RenderInfo
.mri_Screen
);
4197 /**************************************************************************
4198 MUIM_Window_ActionIconify
4199 **************************************************************************/
4200 IPTR
Window__MUIM_ActionIconify(struct IClass
*cl
, Object
*obj
, Msg msg
)
4202 set(_app(obj
), MUIA_Application_Iconified
, TRUE
);
4208 /* Loads ENV: prefs, add a Window_ID chunk in the MUIW chunk, if no MUIW chunk
4209 * then create it at the same level as MUIC chunk, save prefs.
4210 * Do the same for ENVARC:
4211 * MUIW chunk layout:
4213 * 00 00 00 30 (chunk length for a single window, 0x30L big endian)
4216 * xx xx yy yy (X, Y)
4217 * ww ww hh hh (Width, Height)
4218 * ax ax ay ay (AltX, AltY)
4219 * aw aw ah ah (AltWidth, AltHeight)
4227 static void RememberWindowPosition(Object
*winobj
, ULONG id
)
4233 /* Loads ENV: prefs, remove our Window_ID chunk from the MUIW chunk,
4235 * Do the same for ENVARC:
4236 * This function shouldn't really be in window.c, but rather in a file dealing
4237 * with prefs file stuff.
4239 static void ForgetWindowPosition(Object
*winobj
, ULONG id
)
4245 /**************************************************************************
4246 MUIM_Window_Snapshot
4247 **************************************************************************/
4248 IPTR
Window__MUIM_Snapshot(struct IClass
*cl
, Object
*obj
,
4249 struct MUIP_Window_Snapshot
*msg
)
4251 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4252 struct windowpos winp
;
4254 winp
.id
= data
->wd_ID
;
4255 w
= data
->wd_RenderInfo
.mri_Window
;
4258 winp
.x1
= w
->LeftEdge
;
4259 winp
.y1
= w
->TopEdge
;
4260 winp
.w1
= w
->GZZWidth
;
4261 winp
.h1
= w
->GZZHeight
;
4265 winp
.h2
= 0; //to do save alt dims
4267 set(_app(obj
), MUIA_Application_SetWinPos
, &winp
);
4271 RememberWindowPosition(obj
, data
->wd_ID
);
4273 ForgetWindowPosition(obj
, data
->wd_ID
);
4277 /**************************************************************************
4278 MUIM_Window_UpdateMenu
4279 **************************************************************************/
4280 IPTR
Window__MUIM_UpdateMenu(struct IClass
*cl
, Object
*obj
, Msg msg
)
4282 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4284 struct Menu
*menu
= NULL
;
4285 struct NewMenu
*newmenu
= NULL
;
4286 APTR visinfo
= NULL
;
4287 struct Window
*win
= NULL
;
4289 if (data
->wd_Menustrip
) // only open windows can have a menustrip
4292 GetVisualInfoA(data
->wd_RenderInfo
.mri_Screen
, NULL
)))
4294 win
= data
->wd_RenderInfo
.mri_Window
;
4295 ClearMenuStrip(win
);
4298 FreeMenus(data
->wd_Menu
);
4299 data
->wd_Menu
= NULL
;
4302 get(data
->wd_Menustrip
, MUIA_Menuitem_NewMenu
, &newmenu
);
4305 if ((menu
= CreateMenusA(newmenu
, NULL
)))
4307 struct TagItem tags
[] = {
4308 {GTMN_NewLookMenus
, TRUE
},
4311 LayoutMenusA(menu
, visinfo
, tags
);
4312 data
->wd_Menu
= menu
;
4313 SetMenuStrip(win
, menu
);
4316 FreeVisualInfo(visinfo
);
4323 /**************************************************************************
4324 MUIM_Export : to export an objects "contents" to a dataspace object.
4325 **************************************************************************/
4326 static IPTR
Window__MUIM_Export(struct IClass
*cl
, Object
*obj
,
4327 struct MUIP_Export
*msg
)
4329 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4330 DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
4335 /**************************************************************************
4336 MUIM_Import : to import an objects "contents" from a dataspace object.
4337 **************************************************************************/
4338 static IPTR
Window__MUIM_Import(struct IClass
*cl
, Object
*obj
,
4339 struct MUIP_Import
*msg
)
4341 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4342 DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
4346 BOOPSI_DISPATCHER(IPTR
, Window_Dispatcher
, cl
, obj
, msg
)
4348 switch (msg
->MethodID
)
4351 return Window__OM_NEW(cl
, obj
, (struct opSet
*)msg
);
4353 return Window__OM_DISPOSE(cl
, obj
, msg
);
4355 return Window__OM_SET(cl
, obj
, (struct opSet
*)msg
);
4357 return Window__OM_GET(cl
, obj
, (struct opGet
*)msg
);
4358 case MUIM_FindUData
:
4359 return Window__MUIM_FindUData(cl
, obj
,
4360 (struct MUIP_FindUData
*)msg
);
4362 return Window__MUIM_GetUData(cl
, obj
, (struct MUIP_GetUData
*)msg
);
4364 return Window__MUIM_SetUData(cl
, obj
, (struct MUIP_SetUData
*)msg
);
4365 case MUIM_SetUDataOnce
:
4366 return Window__MUIM_SetUDataOnce(cl
, obj
,
4367 (struct MUIP_SetUDataOnce
*)msg
);
4368 case MUIM_Window_AddEventHandler
:
4369 return Window__MUIM_AddEventHandler(cl
, obj
, (APTR
) msg
);
4370 case MUIM_Window_RemEventHandler
:
4371 return Window__MUIM_RemEventHandler(cl
, obj
, (APTR
) msg
);
4372 case MUIM_ConnectParent
:
4373 return Window__MUIM_ConnectParent(cl
, obj
, (APTR
) msg
);
4374 case MUIM_DisconnectParent
:
4375 return Window__MUIM_DisconnectParent(cl
, obj
, (APTR
) msg
);
4376 case MUIM_Window_RecalcDisplay
:
4377 return Window__MUIM_RecalcDisplay(cl
, obj
, (APTR
) msg
);
4378 case MUIM_Window_Setup
:
4379 return Window__MUIM_Setup(cl
, obj
, (APTR
) msg
);
4380 case MUIM_Window_Cleanup
:
4381 return Window__MUIM_Cleanup(cl
, obj
, (APTR
) msg
);
4382 case MUIM_Window_AddControlCharHandler
:
4383 return Window__MUIM_AddControlCharHandler(cl
, obj
, (APTR
) msg
);
4384 case MUIM_Window_RemControlCharHandler
:
4385 return Window__MUIM_RemControlCharHandler(cl
, obj
, (APTR
) msg
);
4386 case MUIM_Window_DragObject
:
4387 return Window__MUIM_DragObject(cl
, obj
, (APTR
) msg
);
4388 case MUIM_Window_AllocGadgetID
:
4389 return Window__MUIM_AllocGadgetID(cl
, obj
, (APTR
) msg
);
4390 case MUIM_Window_FreeGadgetID
:
4391 return Window__MUIM_FreeGadgetID(cl
, obj
, (APTR
) msg
);
4392 case MUIM_Window_GetMenuCheck
:
4393 return Window__MUIM_GetMenuCheck(cl
, obj
, (APTR
) msg
);
4394 case MUIM_Window_SetMenuCheck
:
4395 return Window__MUIM_SetMenuCheck(cl
, obj
, (APTR
) msg
);
4396 case MUIM_Window_GetMenuState
:
4397 return Window__MUIM_GetMenuState(cl
, obj
, (APTR
) msg
);
4398 case MUIM_Window_SetMenuState
:
4399 return Window__MUIM_SetMenuState(cl
, obj
, (APTR
) msg
);
4400 case MUIM_Window_DrawBackground
:
4401 return Window__MUIM_DrawBackground(cl
, obj
, (APTR
) msg
);
4402 case MUIM_Window_ToFront
:
4403 return Window__MUIM_ToFront(cl
, obj
, (APTR
) msg
);
4404 case MUIM_Window_ToBack
:
4405 return Window__MUIM_ToBack(cl
, obj
, (APTR
) msg
);
4406 case MUIM_Window_ScreenToFront
:
4407 return Window__MUIM_ScreenToFront(cl
, obj
, (APTR
) msg
);
4408 case MUIM_Window_ScreenToBack
:
4409 return Window__MUIM_ScreenToBack(cl
, obj
, (APTR
) msg
);
4410 case MUIM_Window_ActionIconify
:
4411 return Window__MUIM_ActionIconify(cl
, obj
, (APTR
) msg
);
4412 case MUIM_Window_Snapshot
:
4413 return Window__MUIM_Snapshot(cl
, obj
, (APTR
) msg
);
4414 case MUIM_Window_UpdateMenu
:
4415 return Window__MUIM_UpdateMenu(cl
, obj
, (APTR
) msg
);
4417 return Window__MUIM_Export(cl
, obj
, (APTR
) msg
);
4419 return Window__MUIM_Import(cl
, obj
, (APTR
) msg
);
4422 return DoSuperMethodA(cl
, obj
, msg
);
4424 BOOPSI_DISPATCHER_END
4429 const struct __MUIBuiltinClass _MUI_Window_desc
=
4433 sizeof(struct MUI_WindowData
),
4434 (void *) Window_Dispatcher