2 Copyright © 1999, David Le Corfec.
3 Copyright © 2002-2017, The AROS Development Team.
8 #include <exec/types.h>
9 #include <exec/memory.h>
13 #include <intuition/imageclass.h>
14 #include <intuition/icclass.h>
15 #include <intuition/gadgetclass.h>
17 #include <intuition/extensions.h>
19 #include <clib/alib_protos.h>
20 #include <graphics/gfxmacros.h>
21 #include <proto/exec.h>
22 #include <proto/intuition.h>
23 #include <proto/utility.h>
24 #include <proto/graphics.h>
25 #include <proto/commodities.h>
26 #include <proto/layers.h>
27 #include <proto/gadtools.h>
28 #include <proto/muimaster.h>
29 #include <proto/workbench.h>
31 #define MUI_OBSOLETE /* for the obsolete menu stuff */
35 #include "classes/window.h"
36 #include "classes/area.h"
38 #include "datatypescache.h"
40 #include "dragndrop.h"
42 #include "muimaster_intern.h"
47 extern struct Library
*MUIMasterBase
;
49 static const int __version
= 1;
50 static const int __revision
= 1;
52 #define IM(x) ((struct Image*)(x))
53 #define G(x) ((struct Gadget*)(x))
54 #define GADGETID(x) (((struct Gadget*)(x))->GadgetID)
56 /* this is for the cycle list */
63 /* For the gadget ids */
70 struct MUI_ImageSpec_intern
;
74 struct MUI_RenderInfo wd_RenderInfo
;
75 struct MUI_MinMax wd_MinMax
;
76 struct IBox wd_AltDim
; /* zoomed dimensions */
77 BOOL wd_ZoomGadget
; /* enable/disable zoomgadget (altdim stuff) */
78 APTR wd_MemoryPool
; /* for nodes and stuff to deallocate at
80 struct MinList wd_CycleChain
; /* objects activated with tab */
81 struct MinList wd_EHList
; /* event handlers */
82 struct MinList wd_CCList
; /* control chars */
83 struct MinList wd_IDList
; /* gadget ids */
84 ULONG wd_Events
; /* events received */
85 ULONG wd_CrtFlags
; /* window creation flags, see below */
86 Object
*wd_ActiveObject
; /* the active object */
87 Object
*wd_OldActive
; /* active object before window was closed */
88 APTR wd_DefaultObject
;
91 STRPTR wd_ScreenTitle
;
92 LONG wd_Height
; /* Current dimensions */
96 LONG wd_ReqHeight
; /* given by programmer */
100 APTR wd_RootObject
; /* unique child */
101 ULONG wd_Flags
; /* various status flags */
102 struct MUI_ImageSpec_intern
*wd_Background
;
103 ULONG wd_DisabledKeys
;
104 BOOL wd_NoMenus
; /* MUIA_Window_NoMenus */
106 Object
*wd_DragObject
; /* the object which is being dragged */
107 struct Window
*wd_DropWindow
; /* the destination window, for faster
109 Object
*wd_DropObject
; /* the destination object */
110 struct DragNDrop
*wd_dnd
;
111 struct MUI_DragImage
*wd_DragImage
;
112 struct AppWindow
*wd_AppWindow
;
114 Object
*wd_Menustrip
; /* The menustrip object which is actually
115 * used (either app's or window's or NULL) */
116 Object
*wd_ChildMenustrip
; /* If window has its own Menustrip */
117 struct Menu
*wd_Menu
; /* the intuition menustrip */
121 Object
*wd_DownButton
;
123 Object
*wd_HorizProp
;
124 Object
*wd_LeftButton
;
125 Object
*wd_RightButton
;
126 Object
*wd_RefWindow
;
128 Object
*wd_MUIGadget
;
130 Object
*wd_HelpObject
;
134 struct Screen
*wd_UserScreen
;
135 STRPTR wd_UserPublicScreen
;
137 WORD wd_SleepCount
; /* MUIA_Window_Sleep nests */
138 LONG wd_SleepMaxHeight
; /* Remember Min/Max values for wakeup */
139 LONG wd_SleepMaxWidth
;
140 LONG wd_SleepMinHeight
;
141 LONG wd_SleepMinWidth
;
143 struct IClass
*wd_Class
;
146 #ifndef WFLG_SIZEGADGET
148 #define WFLG_CLOSEGADGET (1<<0) /* has close gadget */
149 #define WFLG_SIZEGADGET (1<<1) /* has size gadget */
150 #define WFLG_BACKDROP (1<<2) /* is backdrop window */
151 #define WFLG_BORDERLESS (1<<3) /* has no borders */
152 #define WFLG_DEPTHGADGET (1<<4) /* has depth gadget */
153 #define WFLG_DRAGBAR (1<<5) /* is draggable */
154 #define WFLG_SIZEBRIGHT (1<<6) /* size gadget is in right border */
159 #define MUIWF_OPENED (1<<0) /* window currently opened */
160 #define MUIWF_HIDDEN (1<<1) /* window currently iconified */
161 #define MUIWF_ACTIVE (1<<2) /* window currently active */
162 #define MUIWF_RESIZING (1<<4) /* window currently resizing */
163 #define MUIWF_DONTACTIVATE (1<<7) /* do not activate the window when
165 #define MUIWF_USERIGHTSCROLLER (1<<8) /* should have right scroller */
166 #define MUIWF_USEBOTTOMSCROLLER (1<<9) /* should have bottom scroller */
167 #define MUIWF_ERASEAREA (1<<10) /* Erase area after a window resize */
168 #define MUIWF_ISAPPWINDOW (1<<11) /* Is an AppWindow */
169 #define MUIWF_ISSUBWINDOW (1<<12) /* Don't get automatically disposed
171 #define MUIWF_BUBBLEMODE (1<<13) /* Quick bubble mode. Bubbles appear
172 * quick when moving */
173 #define MUIWF_OPENONUNHIDE (1<<14) /* Open the window when unhiding */
174 #define MUIWF_SCREENLOCKED (1<<15) /* A pub screen was locked in
175 * SetupRenderInfo. Unlock it in
176 * CleanupRenderInfo! */
177 #define MUIWF_OBJECTGOACTIVESENT (1<<16) /* A MUIM_GoActive msg was sent to
178 * window's active object */
179 #define MUIWF_TOOLBOX (1<<17) /* Window should be opened as
182 #define BUBBLEHELP_TICKER_FIRST 10
183 #define BUBBLEHELP_TICKER_LATER 3
187 struct MUI_NotifyData mnd
;
188 struct MUI_WindowData mwd
;
191 #define muiWindowData(obj) (&(((struct __dummyXFC3__ *)(obj))->mwd))
193 /****** List.mui/MUIA_Window_DragBar *****************************************
196 * MUIA_Window_DragBar -- (V4) [I..], BOOL
199 * Allow the window to be dragged. Defaults to TRUE.
202 * MUIA_Window_DepthGadget, MUIA_Window_SizeGadget
204 ******************************************************************************
208 /****** List.mui/MUIA_Window_ScreenTitle *************************************
211 * MUIA_Window_ScreenTitle -- (V5) [ISG], STRPTR
214 * The title shown in the drag bar of the window's screen when the
215 * screen is active. If set to NULL, the screen's default title is shown.
216 * The set string is not copied.
221 ******************************************************************************
225 /****** List.mui/MUIA_Window_Title *******************************************
228 * MUIA_Window_Title -- (V4) [ISG], STRPTR
231 * The window title, as shown in the drag bar. If set to NULL, no title
232 * is shown. The set string is not copied.
235 * MUIA_Window_ScreenTitle
237 ******************************************************************************
241 static void ActivateObject(struct MUI_WindowData
*data
);
242 static void HandleInputEvent(Object
*win
, struct MUI_WindowData
*data
,
243 struct IntuiMessage
*event
);
245 static ULONG
DoHalfshineGun(ULONG a
, ULONG b
)
247 ULONG val
= ((((a
) >> 24) + 3 * ((b
) >> 24)) / 4);
248 val
= val
+ (val
<< 8) + (val
<< 16) + (val
<< 24);
252 static ULONG
DoHalfshadowGun(ULONG a
, ULONG b
)
254 ULONG val
= ((((a
) >> 24) + 5 * ((b
) >> 24)) / 6);
255 val
= val
+ (val
<< 8) + (val
<< 16) + (val
<< 24);
259 static Object
*CreateSysimage(struct DrawInfo
*dri
, ULONG which
)
261 return NewObject(NULL
, "sysiclass",
262 SYSIA_DrawInfo
, (IPTR
) dri
, SYSIA_Which
, which
, TAG_DONE
);
265 static void EnqueueByPriAndAddress(struct List
*list
, struct Node
*node
)
267 struct Node
*scannode
;
269 /* Sort by priority and by node address, so that a
270 "remove - modify - enqueue" sequence will re-add
271 the node at the same place in the list it was
273 ForeachNode(list
, scannode
)
275 if (((struct Node
*)node
)->ln_Pri
> scannode
->ln_Pri
)
277 if (((struct Node
*)node
)->ln_Pri
== scannode
->ln_Pri
)
279 if ((IPTR
) node
> (IPTR
) scannode
)
284 Insert(list
, (struct Node
*)node
, scannode
->ln_Pred
);
287 static BOOL
InitCustomFrames(Object
*obj
, struct MUI_RenderInfo
*mri
)
291 for (i
= 0; i
< 16; i
++)
293 mri
->mri_FrameImage
[i
] = NULL
;
296 mri
->mri_FrameImage
[0] =
297 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
298 customframe_config_1
, mri
->mri_Screen
);
299 mri
->mri_FrameImage
[1] =
300 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
301 customframe_config_2
, mri
->mri_Screen
);
302 mri
->mri_FrameImage
[2] =
303 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
304 customframe_config_3
, mri
->mri_Screen
);
305 mri
->mri_FrameImage
[3] =
306 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
307 customframe_config_4
, mri
->mri_Screen
);
308 mri
->mri_FrameImage
[4] =
309 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
310 customframe_config_5
, mri
->mri_Screen
);
311 mri
->mri_FrameImage
[5] =
312 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
313 customframe_config_6
, mri
->mri_Screen
);
314 mri
->mri_FrameImage
[6] =
315 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
316 customframe_config_7
, mri
->mri_Screen
);
317 mri
->mri_FrameImage
[7] =
318 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
319 customframe_config_8
, mri
->mri_Screen
);
320 mri
->mri_FrameImage
[8] =
321 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
322 customframe_config_9
, mri
->mri_Screen
);
323 mri
->mri_FrameImage
[9] =
324 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
325 customframe_config_10
, mri
->mri_Screen
);
326 mri
->mri_FrameImage
[10] =
327 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
328 customframe_config_11
, mri
->mri_Screen
);
329 mri
->mri_FrameImage
[11] =
330 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
331 customframe_config_12
, mri
->mri_Screen
);
332 mri
->mri_FrameImage
[12] =
333 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
334 customframe_config_13
, mri
->mri_Screen
);
335 mri
->mri_FrameImage
[13] =
336 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
337 customframe_config_14
, mri
->mri_Screen
);
338 mri
->mri_FrameImage
[14] =
339 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
340 customframe_config_15
, mri
->mri_Screen
);
341 mri
->mri_FrameImage
[15] =
342 load_custom_frame(muiGlobalInfo(obj
)->mgi_Prefs
->
343 customframe_config_16
, mri
->mri_Screen
);
348 static void DisposeCustomFrames(struct MUI_RenderInfo
*mri
)
352 for (i
= 0; i
< 16; i
++)
354 dispose_custom_frame(mri
->mri_FrameImage
[i
]);
356 mri
->mri_FrameImage
[i
] = NULL
;
360 static BOOL
SetupRenderInfo(Object
*obj
, struct MUI_WindowData
*data
,
361 struct MUI_RenderInfo
*mri
)
363 ULONG rgbtable
[3 * 3];
368 /* TODO: Move this whole screen locking/opening stuff into the
369 * application class by creating methods for this purpose */
371 /* If no user screen has been specified try to open the application
373 if (!data
->wd_UserScreen
)
375 ULONG screenmodeid
= muiGlobalInfo(obj
)->mgi_Prefs
->screenmodeid
;
377 if (screenmodeid
!= ~0)
379 if (!muiGlobalInfo(obj
)->mgi_CustomScreen
)
381 muiGlobalInfo(obj
)->mgi_CustomScreen
= OpenScreenTags
383 SA_DisplayID
, screenmodeid
,
385 SA_FullPalette
, TRUE
, SA_LikeWorkbench
, TRUE
, TAG_DONE
);
386 /* It's fine if this fails as there is a fallback case below */
389 data
->wd_UserScreen
= muiGlobalInfo(obj
)->mgi_CustomScreen
;
392 if (data
->wd_UserScreen
)
394 mri
->mri_Screen
= data
->wd_UserScreen
;
398 if (data
->wd_UserPublicScreen
)
400 mri
->mri_Screen
= LockPubScreen(data
->wd_UserPublicScreen
);
402 else if (muiGlobalInfo(obj
)->mgi_Prefs
->publicscreen_name
403 && muiGlobalInfo(obj
)->mgi_Prefs
->publicscreen_name
[0])
406 LockPubScreen(muiGlobalInfo(obj
)->mgi_Prefs
->
408 // FIXME: open the public screen if necessary
411 if (mri
->mri_Screen
== NULL
)
413 mri
->mri_Screen
= LockPubScreen(NULL
);
414 if (mri
->mri_Screen
== NULL
)
420 // FIXME: is this the right place for this action?
422 && muiGlobalInfo(obj
)->mgi_Prefs
->publicscreen_pop_to_front
)
424 ScreenToFront(mri
->mri_Screen
);
427 data
->wd_Flags
|= MUIWF_SCREENLOCKED
;
430 if (!(mri
->mri_DrawInfo
= GetScreenDrawInfo(mri
->mri_Screen
)))
432 if (data
->wd_Flags
& MUIWF_SCREENLOCKED
)
434 UnlockPubScreen(NULL
, mri
->mri_Screen
);
435 data
->wd_Flags
&= ~MUIWF_SCREENLOCKED
;
440 if (!InitCustomFrames(obj
, mri
))
442 if (data
->wd_Flags
& MUIWF_SCREENLOCKED
)
444 UnlockPubScreen(NULL
, mri
->mri_Screen
);
445 data
->wd_Flags
&= ~MUIWF_SCREENLOCKED
;
450 mri
->mri_Colormap
= mri
->mri_Screen
->ViewPort
.ColorMap
;
451 mri
->mri_ScreenWidth
= mri
->mri_Screen
->Width
;
452 mri
->mri_ScreenHeight
= mri
->mri_Screen
->Height
;
454 if (mri
->mri_ScreenWidth
/ mri
->mri_ScreenHeight
< 2)
456 mri
->mri_Flags
|= MUIMRI_THINFRAMES
;
459 if (GetBitMapAttr(mri
->mri_Screen
->RastPort
.BitMap
, BMA_DEPTH
) >= 15)
461 mri
->mri_Flags
|= MUIMRI_TRUECOLOR
;
464 mri
->mri_PensStorage
[MPEN_SHINE
] =
465 mri
->mri_DrawInfo
->dri_Pens
[SHINEPEN
];
466 mri
->mri_PensStorage
[MPEN_BACKGROUND
] =
467 mri
->mri_DrawInfo
->dri_Pens
[BACKGROUNDPEN
];
468 mri
->mri_PensStorage
[MPEN_SHADOW
] =
469 mri
->mri_DrawInfo
->dri_Pens
[SHADOWPEN
];
470 mri
->mri_PensStorage
[MPEN_TEXT
] = mri
->mri_DrawInfo
->dri_Pens
[TEXTPEN
];
471 mri
->mri_PensStorage
[MPEN_FILL
] = mri
->mri_DrawInfo
->dri_Pens
[FILLPEN
];
473 GetRGB32(mri
->mri_Colormap
, mri
->mri_DrawInfo
->dri_Pens
[SHINEPEN
], 1,
475 GetRGB32(mri
->mri_Colormap
, mri
->mri_DrawInfo
->dri_Pens
[BACKGROUNDPEN
],
477 GetRGB32(mri
->mri_Colormap
, mri
->mri_DrawInfo
->dri_Pens
[SHADOWPEN
], 1,
480 mri
->mri_PensStorage
[MPEN_HALFSHINE
] = ObtainBestPenA
482 DoHalfshineGun(rgbtable
[0], rgbtable
[3]),
483 DoHalfshineGun(rgbtable
[1], rgbtable
[4]),
484 DoHalfshineGun(rgbtable
[2], rgbtable
[5]), NULL
);
486 mri
->mri_PensStorage
[MPEN_HALFSHADOW
] = ObtainBestPenA
488 DoHalfshadowGun(rgbtable
[6], rgbtable
[3]),
489 DoHalfshadowGun(rgbtable
[7], rgbtable
[4]),
490 DoHalfshadowGun(rgbtable
[8], rgbtable
[5]), NULL
);
492 /* I'm really not sure that MUI does this for MPEN_MARK, but it seems
493 * mostly acceptable -dlc */
494 mri
->mri_PensStorage
[MPEN_MARK
] = ObtainBestPenA
495 (mri
->mri_Colormap
, 0xf4f4f4f4, 0xb5b5b5b5, 0x8b8b8b8b, NULL
);
497 mri
->mri_Pens
= mri
->mri_PensStorage
;
499 for (i
= 0; i
< -MUIV_Font_NegCount
; i
++)
501 mri
->mri_Fonts
[i
] = NULL
;
504 if (data
->wd_Flags
& MUIWF_USEBOTTOMSCROLLER
)
506 mri
->mri_LeftImage
= CreateSysimage(mri
->mri_DrawInfo
, LEFTIMAGE
);
507 mri
->mri_RightImage
= CreateSysimage(mri
->mri_DrawInfo
, RIGHTIMAGE
);
511 mri
->mri_LeftImage
= mri
->mri_RightImage
= NULL
;
514 if (data
->wd_Flags
& MUIWF_USERIGHTSCROLLER
)
516 mri
->mri_UpImage
= CreateSysimage(mri
->mri_DrawInfo
, UPIMAGE
);
517 mri
->mri_DownImage
= CreateSysimage(mri
->mri_DrawInfo
, DOWNIMAGE
);
521 mri
->mri_UpImage
= mri
->mri_DownImage
= NULL
;
524 if ((data
->wd_Flags
& MUIWF_USEBOTTOMSCROLLER
) ||
525 (data
->wd_Flags
& MUIWF_USERIGHTSCROLLER
))
526 mri
->mri_SizeImage
= CreateSysimage(mri
->mri_DrawInfo
, SIZEIMAGE
);
528 mri
->mri_SizeImage
= NULL
;
530 if (data
->wd_CrtFlags
& WFLG_BORDERLESS
)
532 /* In fact borderless windows could also have borders (e.g. if they
533 * have a window title) but since they look ugly anyway we ignore it
535 mri
->mri_BorderLeft
= 0;
536 mri
->mri_BorderRight
= 0;
537 mri
->mri_BorderTop
= 0;
538 mri
->mri_BorderBottom
= 0;
542 mri
->mri_BorderLeft
= mri
->mri_Screen
->WBorLeft
;
543 mri
->mri_BorderRight
= mri
->mri_Screen
->WBorRight
;
545 mri
->mri_Screen
->WBorTop
+ mri
->mri_Screen
->Font
->ta_YSize
+ 1;
547 NewObject(NULL
, "sysiclass", SYSIA_DrawInfo
,
548 (IPTR
) mri
->mri_DrawInfo
, SYSIA_Which
, SIZEIMAGE
, TAG_DONE
);
551 GetAttr(IA_Height
, temp_obj
, &val
);
552 DisposeObject(temp_obj
);
553 mri
->mri_BorderBottom
= val
;
556 mri
->mri_BorderBottom
= mri
->mri_Screen
->WBorBottom
;
562 static void CleanupRenderInfo(Object
*obj
, struct MUI_WindowData
*data
,
563 struct MUI_RenderInfo
*mri
)
567 DisposeCustomFrames(mri
);
569 if (mri
->mri_LeftImage
)
571 DisposeObject(mri
->mri_LeftImage
);
572 mri
->mri_LeftImage
= NULL
;
574 if (mri
->mri_RightImage
)
576 DisposeObject(mri
->mri_RightImage
);
577 mri
->mri_RightImage
= NULL
;
579 if (mri
->mri_UpImage
)
581 DisposeObject(mri
->mri_UpImage
);
582 mri
->mri_UpImage
= NULL
;
584 if (mri
->mri_DownImage
)
586 DisposeObject(mri
->mri_DownImage
);
587 mri
->mri_DownImage
= NULL
;
589 if (mri
->mri_SizeImage
)
591 DisposeObject(mri
->mri_SizeImage
);
592 mri
->mri_SizeImage
= NULL
;
595 /* bug("CleanupRenderInfo\n"); */
596 for (i
= 0; i
< -MUIV_Font_NegCount
; i
++)
598 if (mri
->mri_Fonts
[i
])
600 /* bug("CleanupRenderInfo: closing font %p (%s/%d)\n", */
601 /* mri->mri_Fonts[i], */
602 /* mri->mri_Fonts[i]->tf_Message.mn_Node.ln_Name, */
603 /* mri->mri_Fonts[i]->tf_YSize); */
604 CloseFont(mri
->mri_Fonts
[i
]);
605 mri
->mri_Fonts
[i
] = NULL
;
608 ReleasePen(mri
->mri_Colormap
, mri
->mri_PensStorage
[MPEN_MARK
]);
609 ReleasePen(mri
->mri_Colormap
, mri
->mri_PensStorage
[MPEN_HALFSHADOW
]);
610 ReleasePen(mri
->mri_Colormap
, mri
->mri_PensStorage
[MPEN_HALFSHINE
]);
611 FreeScreenDrawInfo(mri
->mri_Screen
, mri
->mri_DrawInfo
);
612 mri
->mri_DrawInfo
= NULL
;
614 /* If a custom screen has been opened by zune, close it as soon as zero
615 * windows are opened. See above for comments about refactorization. */
616 if (muiGlobalInfo(obj
)->mgi_CustomScreen
)
618 BOOL screenclose
= TRUE
;
619 Object
*_app
= _app(obj
);
622 struct List
*store
= NULL
;
623 get(_app
, MUIA_Application_WindowList
, &store
);
626 if (!IsListEmpty(store
))
632 /* If the window's user screen really was the custom screen,
633 * clear the reference */
634 if (data
->wd_UserScreen
== muiGlobalInfo(obj
)->mgi_CustomScreen
)
635 data
->wd_UserScreen
= NULL
;
637 CloseScreen(muiGlobalInfo(obj
)->mgi_CustomScreen
);
638 muiGlobalInfo(obj
)->mgi_CustomScreen
= NULL
;
642 if (data
->wd_Flags
& MUIWF_SCREENLOCKED
)
644 UnlockPubScreen(NULL
, mri
->mri_Screen
);
645 data
->wd_Flags
&= ~MUIWF_SCREENLOCKED
;
647 mri
->mri_Screen
= NULL
;
650 static void ShowRenderInfo(struct MUI_RenderInfo
*mri
)
652 if (mri
->mri_BufferBM
)
654 mri
->mri_RastPort
= &mri
->mri_BufferRP
;
658 mri
->mri_RastPort
= mri
->mri_Window
->RPort
;
662 static void HideRenderInfo(struct MUI_RenderInfo
*mri
)
664 mri
->mri_RastPort
= NULL
;
667 static ULONG
GetDefaultEvents(void)
669 return IDCMP_NEWSIZE
| IDCMP_CHANGEWINDOW
| IDCMP_REFRESHWINDOW
670 | IDCMP_MOUSEBUTTONS
| IDCMP_MOUSEMOVE
| IDCMP_MENUPICK
671 | IDCMP_CLOSEWINDOW
| IDCMP_RAWKEY
| IDCMP_INTUITICKS
672 | IDCMP_ACTIVEWINDOW
| IDCMP_INACTIVEWINDOW
| IDCMP_GADGETUP
;
675 static void ChangeEvents(struct MUI_WindowData
*data
, ULONG new_events
)
678 struct MUI_EventHandlerNode
*ehn
;
679 ULONG old_events
= data
->wd_Events
;
681 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
683 ehn
= (struct MUI_EventHandlerNode
*)mn
;
684 new_events
|= ehn
->ehn_Events
;
687 /* sba: kill the IDCMP_VANILLAKEY flag. MUI doesn't do this but programs
688 ** which use this will behave different if they request for this flag
691 new_events
&= ~IDCMP_VANILLAKEY
;
693 data
->wd_Events
= new_events
;
694 if ((old_events
!= new_events
) && (data
->wd_Flags
& MUIWF_OPENED
))
696 ModifyIDCMP(data
->wd_RenderInfo
.mri_Window
, new_events
);
700 static void CalcWindowPosition(Object
*obj
, struct MUI_WindowData
*data
);
701 static void CreateWindowScrollbars(Object
*obj
,
702 struct MUI_WindowData
*data
);
703 static void CalcAltDimensions(Object
*obj
, struct MUI_WindowData
*data
,
704 struct IBox
*altdims
);
705 static void UndisplayWindow(Object
*obj
, struct MUI_WindowData
*data
);
706 static struct ObjNode
*FindObjNode(struct MinList
*list
, Object
*obj
);
708 static BOOL
DisplayWindow(Object
*obj
, struct MUI_WindowData
*data
)
711 ULONG flags
= data
->wd_CrtFlags
;
713 ULONG backfill
, buttons
;
715 struct Menu
*menu
= NULL
;
716 struct NewMenu
*newmenu
= NULL
;
721 if (!(data
->wd_Flags
& MUIWF_DONTACTIVATE
))
723 flags
|= WFLG_ACTIVATE
;
726 /* Toolboxes are handled differently on AmigaOS */
728 if (data
->wd_Flags
& MUIWF_TOOLBOX
)
729 flags
|= WFLG_TOOLBOX
;
732 if (data
->wd_MinMax
.MinHeight
== data
->wd_MinMax
.MaxHeight
733 && data
->wd_MinMax
.MinWidth
== data
->wd_MinMax
.MaxWidth
)
734 flags
&= ~WFLG_SIZEGADGET
;
736 if (!(flags
& WFLG_SIZEBRIGHT
))
737 flags
|= WFLG_SIZEBBOTTOM
;
739 CalcWindowPosition(obj
, data
);
741 if ((visinfo
= GetVisualInfoA(data
->wd_RenderInfo
.mri_Screen
, NULL
)))
743 if (data
->wd_Menustrip
)
745 get(data
->wd_Menustrip
, MUIA_Menuitem_NewMenu
, &newmenu
);
748 if ((menu
= CreateMenusA(newmenu
, NULL
)))
750 struct TagItem tags
[] = {
751 {GTMN_NewLookMenus
, TRUE
},
752 {TAG_DONE
, (IPTR
) NULL
}
754 LayoutMenusA(menu
, visinfo
, tags
);
758 FreeVisualInfo(visinfo
);
761 CreateWindowScrollbars(obj
, data
);
762 altdims
= data
->wd_AltDim
;
763 CalcAltDimensions(obj
, data
, &altdims
);
765 /* hack to account for border size, as we only know the innersize and
766 * must give the total size.
769 data
->wd_RenderInfo
.mri_Screen
->WBorLeft
+
770 data
->wd_RenderInfo
.mri_Screen
->WBorRight
;
772 data
->wd_RenderInfo
.mri_Screen
->WBorTop
+
773 data
->wd_RenderInfo
.mri_Screen
->WBorBottom
+
774 data
->wd_RenderInfo
.mri_DrawInfo
->dri_Font
->tf_YSize
+ 1;
776 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_redraw
==
777 WINDOW_REDRAW_WITHOUT_CLEAR
)
778 backfill
= WA_BackFill
;
780 backfill
= TAG_IGNORE
;
782 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_refresh
==
783 WINDOW_REFRESH_SMART
)
784 flags
&= ~WFLG_SIMPLE_REFRESH
;
785 set(_app(obj
), MUIA_Application_SearchWinId
, data
->wd_ID
);
786 struct windowpos
*winp
= 0;
787 get(_app(obj
), MUIA_Application_GetWinPos
, &winp
);
790 if (data
->wd_RenderInfo
.mri_ScreenWidth
>
791 (data
->wd_X
+ data
->wd_Width
))
793 data
->wd_X
= winp
->x1
;
794 data
->wd_Width
= winp
->w1
;
796 if (data
->wd_RenderInfo
.mri_ScreenHeight
>
797 (data
->wd_Y
+ data
->wd_Height
))
799 data
->wd_Y
= winp
->y1
;
800 data
->wd_Height
= winp
->h1
;
805 (data
->wd_VertProp
!=
806 NULL
) ? data
->wd_VertProp
: data
->wd_HorizProp
;
807 buttons
= muiGlobalInfo(obj
)->mgi_Prefs
->window_buttons
;
811 WA_Left
, (IPTR
) data
->wd_X
,
812 WA_Top
, (IPTR
) data
->wd_Y
,
813 WA_Flags
, (IPTR
) flags
,
816 TAG_IGNORE
, (IPTR
) data
->wd_Title
,
817 data
->wd_ScreenTitle
?
819 TAG_IGNORE
, (IPTR
) data
->wd_ScreenTitle
,
820 WA_CustomScreen
, (IPTR
) data
->wd_RenderInfo
.mri_Screen
,
821 WA_InnerWidth
, (IPTR
) data
->wd_Width
,
822 WA_InnerHeight
, (IPTR
) data
->wd_Height
,
823 WA_AutoAdjust
, (IPTR
) TRUE
, WA_NewLookMenus
, (IPTR
) TRUE
,
824 /* AmigaOS v4 extension */
826 WA_ToolBox
, (IPTR
) ! !(data
->wd_Flags
& MUIWF_TOOLBOX
),
828 /* MorphOS extensions */
829 #ifdef WA_ExtraGadget_MUI
831 (IPTR
) ((buttons
& MUIV_Window_Button_MUI
) != 0) ? TRUE
: FALSE
,
832 WA_ExtraGadget_PopUp
,
833 (IPTR
) ((buttons
& MUIV_Window_Button_Popup
) != 0) ? TRUE
: FALSE
,
834 WA_ExtraGadget_Snapshot
,
835 (IPTR
) ((buttons
& MUIV_Window_Button_Snapshot
) !=
836 0) ? TRUE
: FALSE
, WA_ExtraGadget_Iconify
,
837 (IPTR
) ((buttons
& MUIV_Window_Button_Iconify
) != 0) ? TRUE
: FALSE
,
841 TAG_IGNORE
, (IPTR
) TRUE
,
842 WA_Gadgets
, (IPTR
) gadgets
,
843 data
->wd_ZoomGadget
?
845 TAG_IGNORE
, (IPTR
) & altdims
,
846 backfill
, (IPTR
) LAYERS_NOBACKFILL
, TAG_DONE
);
851 int hborders
= win
->BorderLeft
+ win
->BorderRight
;
852 int vborders
= win
->BorderTop
+ win
->BorderBottom
;
854 /* recalc window size (which will hopefully equal our requested
856 data
->wd_Width
= win
->GZZWidth
;
857 data
->wd_Height
= win
->GZZHeight
;
859 /* set window limits according to window contents */
861 (win
, data
->wd_MinMax
.MinWidth
+ hborders
,
862 data
->wd_MinMax
.MinHeight
+ vborders
,
863 data
->wd_MinMax
.MaxWidth
+ hborders
,
864 data
->wd_MinMax
.MaxHeight
+ vborders
);
866 win
->UserData
= (BYTE
*) data
->wd_RenderInfo
.mri_WindowObject
;
867 win
->UserPort
= muiGlobalInfo(obj
)->mgi_WindowsPort
;
868 /* Same port for all windows */
869 ModifyIDCMP(win
, data
->wd_Events
);
871 data
->wd_RenderInfo
.mri_Window
= win
;
872 data
->wd_RenderInfo
.mri_VertProp
= data
->wd_VertProp
;
873 data
->wd_RenderInfo
.mri_HorizProp
= data
->wd_HorizProp
;
874 SetDrMd(win
->RPort
, JAM1
);
875 //text is drawn wrong in toolbarclass if not set
879 data
->wd_Menu
= menu
;
880 SetMenuStrip(win
, menu
);
883 if (flags
& WFLG_ACTIVATE
)
885 data
->wd_Flags
|= MUIWF_ACTIVE
;
888 if (data
->wd_Flags
& MUIWF_ISAPPWINDOW
)
890 data
->wd_AppWindow
= AddAppWindowA(0, (IPTR
) obj
, win
,
891 muiGlobalInfo(obj
)->mgi_AppPort
, NULL
);
899 UndisplayWindow(obj
, data
);
905 static void UndisplayWindow(Object
*obj
, struct MUI_WindowData
*data
)
907 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
910 ((muiGlobalInfo(obj
)->mgi_Prefs
->window_position
==
911 WINDOW_POSITION_REMEMBER_ON_EXIT
)
912 || (muiGlobalInfo(obj
)->mgi_Prefs
->window_position
==
913 WINDOW_POSITION_SAVE_ON_EXIT
));
917 DoMethod(obj
, MUIM_Window_Snapshot
, 1);
920 data
->wd_RenderInfo
.mri_Window
= NULL
;
921 data
->wd_RenderInfo
.mri_VertProp
= NULL
;
922 data
->wd_RenderInfo
.mri_HorizProp
= NULL
;
924 data
->wd_Flags
&= ~MUIWF_ACTIVE
;
931 FreeMenus(data
->wd_Menu
);
932 data
->wd_Menu
= NULL
;
937 struct IntuiMessage
*msg
, *succ
;
939 /* remove all messages pending for this window */
942 (struct IntuiMessage
*)win
->UserPort
->mp_MsgList
.lh_Head
;
944 (struct IntuiMessage
*)msg
->ExecMessage
.mn_Node
.
945 ln_Succ
); msg
= succ
)
947 if (msg
->IDCMPWindow
== win
)
949 Remove((struct Node
*)msg
);
950 ReplyMsg((struct Message
*)msg
);
953 win
->UserPort
= NULL
;
958 /* D(bug("before CloseWindow\n")); */
960 /* D(bug("after CloseWindow\n")); */
963 #define DISPOSEGADGET(x) \
966 DoMethod(obj, MUIM_Window_FreeGadgetID,\
967 ((struct Gadget*)x)->GadgetID);\
972 DISPOSEGADGET(data
->wd_VertProp
);
973 DISPOSEGADGET(data
->wd_UpButton
);
974 DISPOSEGADGET(data
->wd_DownButton
);
975 DISPOSEGADGET(data
->wd_HorizProp
);
976 DISPOSEGADGET(data
->wd_LeftButton
);
977 DISPOSEGADGET(data
->wd_RightButton
);
982 static VOID
RefreshWindow(Object
*oWin
, struct MUI_WindowData
*data
)
984 if (data
->wd_Flags
& MUIWF_RESIZING
)
986 //LONG left,top,right,bottom;
987 if (MUI_BeginRefresh(&data
->wd_RenderInfo
, 0))
989 MUI_EndRefresh(&data
->wd_RenderInfo
, 0);
991 RefreshWindowFrame(data
->wd_RenderInfo
.mri_Window
);
993 data
->wd_Flags
&= ~MUIWF_RESIZING
;
994 _width(data
->wd_RootObject
) = data
->wd_Width
;
995 _height(data
->wd_RootObject
) = data
->wd_Height
;
996 DoMethod(data
->wd_RootObject
, MUIM_Layout
);
997 DoShowMethod(data
->wd_RootObject
);
999 if (muiGlobalInfo(oWin
)->mgi_Prefs
->window_redraw
==
1000 WINDOW_REDRAW_WITH_CLEAR
)
1002 LONG left
, top
, width
, height
;
1004 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
1005 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
;
1007 data
->wd_RenderInfo
.mri_Window
->Width
-
1008 data
->wd_RenderInfo
.mri_Window
->BorderRight
- left
;
1010 data
->wd_RenderInfo
.mri_Window
->Height
-
1011 data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
1013 if (data
->wd_Flags
& MUIWF_ERASEAREA
)
1015 //D(bug("%d:zune_imspec_draw(%p) "
1016 // "l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
1017 // __LINE__, data->wd_Background, left, top, width,
1018 // height, left, top));
1019 zune_imspec_draw(data
->wd_Background
,
1020 &data
->wd_RenderInfo
, left
, top
, width
, height
,
1023 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWALL
);
1026 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWOBJECT
);
1027 // but should only draw focus without using MUIM_GoActive !
1028 ActivateObject(data
);
1032 if (MUI_BeginRefresh(&data
->wd_RenderInfo
, 0))
1034 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWALL
);
1035 // but should only draw focus without using MUIM_GoActive !
1036 ActivateObject(data
);
1037 MUI_EndRefresh(&data
->wd_RenderInfo
, 0);
1043 /* Initialize data->wd_X and data->wd_Y for DisplayWindow */
1044 static void CalcWindowPosition(Object
*obj
, struct MUI_WindowData
*data
)
1046 struct MUI_RenderInfo
*mri
= &data
->wd_RenderInfo
;
1047 struct Screen
*scr
= mri
->mri_Screen
;
1048 WORD width
= mri
->mri_BorderLeft
+ data
->wd_Width
+ mri
->mri_BorderRight
,
1049 height
= mri
->mri_BorderTop
+ data
->wd_Height
+ mri
->mri_BorderBottom
;
1050 ULONG refw
= 0, refx
= 0, refh
= 0, refy
= 0;
1052 data
->wd_X
= data
->wd_ReqX
;
1053 data
->wd_Y
= data
->wd_ReqY
;
1055 /* Get dimensions of reference window */
1056 if (data
->wd_RefWindow
!= NULL
)
1058 get(data
->wd_RefWindow
, MUIA_Window_LeftEdge
, &refx
);
1059 get(data
->wd_RefWindow
, MUIA_Window_Width
, &refw
);
1060 get(data
->wd_RefWindow
, MUIA_Window_TopEdge
, &refy
);
1061 get(data
->wd_RefWindow
, MUIA_Window_Height
, &refh
);
1065 if (data
->wd_X
== MUIV_Window_LeftEdge_Centered
)
1067 if (data
->wd_RefWindow
!= NULL
)
1068 /* FIXME: only correct if border thickness is the same for both
1070 data
->wd_X
= refx
+ (refw
- width
) / 2;
1072 data
->wd_X
= (scr
->ViewPort
.DWidth
- width
) / 2;
1074 else if (data
->wd_X
== MUIV_Window_LeftEdge_Moused
)
1075 data
->wd_X
= scr
->MouseX
- width
/ 2;
1076 else if (data
->wd_RefWindow
!= NULL
)
1080 if (data
->wd_Y
== MUIV_Window_TopEdge_Centered
)
1082 if (data
->wd_RefWindow
!= NULL
)
1083 data
->wd_Y
= refy
+ (refh
- data
->wd_Height
) / 2;
1085 data
->wd_Y
= (scr
->ViewPort
.DHeight
- height
) / 2;
1087 else if (data
->wd_Y
== MUIV_Window_TopEdge_Moused
)
1088 data
->wd_Y
= scr
->MouseY
- height
/ 2;
1089 else if (data
->wd_Y
<= MUIV_Window_TopEdge_Delta(0)
1090 && data
->wd_Y
> MUIV_Window_TopEdge_Delta(7))
1092 data
->wd_Y
= MUIV_Window_TopEdge_Delta(0) - data
->wd_Y
;
1093 if (data
->wd_RefWindow
!= NULL
)
1094 data
->wd_Y
+= refy
+ mri
->mri_BorderTop
;
1096 data
->wd_Y
+= scr
->BarHeight
+ 1;
1098 else if (data
->wd_RefWindow
!= NULL
)
1102 /* Initialize alternative dimensions for DisplayWindow */
1103 static void CalcAltDimensions(Object
*obj
, struct MUI_WindowData
*data
,
1104 struct IBox
*altdims
)
1106 /* Calculate alternate (zoomed) dimensions.
1108 if (altdims
->Top
== MUIV_Window_AltTopEdge_NoChange
)
1110 else if (altdims
->Top
== MUIV_Window_AltTopEdge_Centered
)
1112 (data
->wd_RenderInfo
.mri_Screen
->Height
- data
->wd_Height
) / 2;
1113 else if (altdims
->Top
== MUIV_Window_AltTopEdge_Moused
)
1114 /* ? */ altdims
->Top
= ~0;
1116 if (altdims
->Left
== MUIV_Window_AltLeftEdge_NoChange
)
1118 else if (altdims
->Left
== MUIV_Window_AltLeftEdge_Centered
)
1120 (data
->wd_RenderInfo
.mri_Screen
->Width
- data
->wd_Width
) / 2;
1121 else if (altdims
->Left
== MUIV_Window_AltLeftEdge_Moused
)
1122 /* ? */ altdims
->Left
= ~0;
1125 (MUIV_Window_AltWidth_MinMax(100),
1126 altdims
->Width
, MUIV_Window_AltWidth_MinMax(0)))
1128 altdims
->Width
= data
->wd_MinMax
.MinWidth
1130 * (data
->wd_MinMax
.MaxWidth
- data
->wd_MinMax
.MinWidth
);
1134 (MUIV_Window_AltWidth_Screen(100),
1135 altdims
->Width
, MUIV_Window_AltWidth_Screen(0)))
1137 altdims
->Width
= data
->wd_RenderInfo
.mri_ScreenWidth
1138 * (-(altdims
->Width
+ 200)) / 100;
1142 (MUIV_Window_AltWidth_Visible(100),
1143 altdims
->Width
, MUIV_Window_AltWidth_Visible(0)))
1145 altdims
->Width
= data
->wd_RenderInfo
.mri_ScreenWidth
1146 * (-(altdims
->Width
+ 100)) / 100;
1150 (MUIV_Window_AltHeight_MinMax(100),
1151 altdims
->Height
, MUIV_Window_AltHeight_MinMax(0)))
1153 altdims
->Height
= data
->wd_MinMax
.MinHeight
1155 * (data
->wd_MinMax
.MaxHeight
- data
->wd_MinMax
.MinHeight
);
1159 (MUIV_Window_AltHeight_Screen(100),
1160 altdims
->Height
, MUIV_Window_AltHeight_Screen(0)))
1162 altdims
->Height
= data
->wd_RenderInfo
.mri_ScreenHeight
1163 * (-(altdims
->Height
+ 200)) / 100;
1167 (MUIV_Window_AltHeight_Visible(100),
1168 altdims
->Height
, MUIV_Window_AltHeight_Visible(0)))
1170 altdims
->Height
= data
->wd_RenderInfo
.mri_ScreenHeight
1171 * (-(altdims
->Height
+ 100)) / 100;
1174 altdims
->Width
= CLAMP
1175 (altdims
->Width
, data
->wd_MinMax
.MinWidth
,
1176 data
->wd_MinMax
.MaxWidth
);
1177 altdims
->Height
= CLAMP
1178 (altdims
->Height
, data
->wd_MinMax
.MinHeight
,
1179 data
->wd_MinMax
.MaxHeight
);
1183 /* Create horiz/vert window scrollbars for DisplayWindow */
1184 static void CreateWindowScrollbars(Object
*obj
,
1185 struct MUI_WindowData
*data
)
1187 struct MUI_RenderInfo
*mri
= &data
->wd_RenderInfo
;
1188 Object
*firstgad
= NULL
;
1189 Object
*prevgad
= NULL
;
1192 /* Create the right border scrollers now if requested */
1193 if (data
->wd_Flags
& MUIWF_USERIGHTSCROLLER
)
1197 voffset
= IM(mri
->mri_DownImage
)->Width
/ 4;
1199 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1200 firstgad
= prevgad
= data
->wd_VertProp
= NewObject
1201 (NULL
, "propgclass",
1202 GA_RelRight
, 1 - (IM(mri
->mri_UpImage
)->Width
- voffset
),
1203 GA_Top
, mri
->mri_BorderTop
+ 2,
1204 GA_Width
, IM(mri
->mri_UpImage
)->Width
- voffset
* 2,
1205 GA_RelHeight
, -(mri
->mri_BorderTop
+ 2)
1206 - IM(mri
->mri_UpImage
)->Height
1207 - IM(mri
->mri_DownImage
)->Height
1208 - IM(mri
->mri_SizeImage
)->Height
- 2,
1209 GA_RightBorder
, TRUE
,
1211 PGA_Borderless
, TRUE
,
1213 PGA_Freedom
, FREEVERT
,
1216 PGA_Visible
, 1, ICA_TARGET
, ICTARGET_IDCMP
, TAG_DONE
);
1218 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1219 prevgad
= data
->wd_UpButton
= NewObject
1220 (NULL
, "buttongclass",
1221 GA_Image
, (IPTR
) mri
->mri_UpImage
,
1222 GA_RelRight
, 1 - IM(mri
->mri_UpImage
)->Width
,
1223 GA_RelBottom
, 1 - IM(mri
->mri_UpImage
)->Height
1224 - IM(mri
->mri_DownImage
)->Height
1225 - IM(mri
->mri_SizeImage
)->Height
,
1226 GA_RightBorder
, TRUE
,
1227 GA_Previous
, (IPTR
) prevgad
,
1228 GA_ID
, id
, ICA_TARGET
, ICTARGET_IDCMP
, TAG_DONE
);
1230 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1231 prevgad
= data
->wd_DownButton
= NewObject
1232 (NULL
, "buttongclass",
1233 GA_Image
, (IPTR
) mri
->mri_DownImage
,
1234 GA_RelRight
, 1 - IM(mri
->mri_DownImage
)->Width
,
1235 GA_RelBottom
, 1 - IM(mri
->mri_DownImage
)->Height
1236 - IM(mri
->mri_SizeImage
)->Height
,
1237 GA_RightBorder
, TRUE
,
1238 GA_Previous
, (IPTR
) prevgad
,
1239 GA_ID
, id
, ICA_TARGET
, ICTARGET_IDCMP
, TAG_DONE
);
1242 /* Create the bottom border scrollers now if requested */
1243 if (data
->wd_Flags
& MUIWF_USEBOTTOMSCROLLER
)
1247 hoffset
= IM(mri
->mri_RightImage
)->Height
/ 4;
1249 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1250 prevgad
= data
->wd_HorizProp
= NewObject
1251 (NULL
, "propgclass",
1252 GA_RelBottom
, 1 - (IM(mri
->mri_LeftImage
)->Height
- hoffset
),
1253 GA_Left
, mri
->mri_BorderLeft
,
1254 GA_Height
, IM(mri
->mri_LeftImage
)->Height
1256 GA_RelWidth
, -(mri
->mri_BorderLeft
)
1257 - IM(mri
->mri_LeftImage
)->Width
1258 - IM(mri
->mri_RightImage
)->Width
1259 - IM(mri
->mri_SizeImage
)->Width
1261 GA_BottomBorder
, TRUE
,
1263 prevgad
? GA_Previous
: TAG_IGNORE
, (IPTR
) prevgad
,
1264 PGA_Borderless
, TRUE
,
1266 PGA_Freedom
, FREEHORIZ
,
1269 PGA_Visible
, 1, ICA_TARGET
, ICTARGET_IDCMP
, TAG_DONE
);
1274 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1275 prevgad
= data
->wd_LeftButton
= NewObject
1276 (NULL
, "buttongclass",
1277 GA_Image
, (IPTR
) mri
->mri_LeftImage
,
1278 GA_RelRight
, 1 - IM(mri
->mri_LeftImage
)->Width
1279 - IM(mri
->mri_RightImage
)->Width
1280 - IM(mri
->mri_SizeImage
)->Width
,
1281 GA_RelBottom
, 1 - IM(mri
->mri_LeftImage
)->Height
,
1282 GA_BottomBorder
, TRUE
,
1283 GA_Previous
, (IPTR
) prevgad
,
1284 GA_ID
, id
, ICA_TARGET
, ICTARGET_IDCMP
, TAG_DONE
);
1286 id
= DoMethod(obj
, MUIM_Window_AllocGadgetID
);
1287 prevgad
= data
->wd_RightButton
= NewObject
1288 (NULL
, "buttongclass",
1289 GA_Image
, (IPTR
) mri
->mri_RightImage
,
1290 GA_RelRight
, 1 - IM(mri
->mri_RightImage
)->Width
1291 - IM(mri
->mri_SizeImage
)->Width
,
1292 GA_RelBottom
, 1 - IM(mri
->mri_RightImage
)->Height
,
1293 GA_BottomBorder
, TRUE
,
1294 GA_Previous
, (IPTR
) prevgad
,
1295 GA_ID
, id
, ICA_TARGET
, ICTARGET_IDCMP
, TAG_DONE
);
1299 /* return FALSE only if no resize (dx=dy=0) occured */
1300 static BOOL
WindowResize(struct MUI_WindowData
*data
)
1302 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
1303 int hborders
= win
->BorderLeft
+ win
->BorderRight
;
1304 int vborders
= win
->BorderTop
+ win
->BorderBottom
;
1305 WORD dx
= data
->wd_Width
- win
->Width
+ hborders
;
1306 WORD dy
= data
->wd_Height
- win
->Height
+ vborders
;
1308 /* Temporarily disable window limits to let SizeWindow below work
1309 regardless of the previous limits */
1310 WindowLimits(win
, 1, 1, -1, -1);
1311 /* D(bug("_zune_window_resize : dx=%d, dy=%d\n", dx, dy)); */
1312 SizeWindow(win
, dx
, dy
);
1314 /* Set new window limits */
1316 (win
, data
->wd_MinMax
.MinWidth
+ hborders
,
1317 data
->wd_MinMax
.MinHeight
+ vborders
,
1318 data
->wd_MinMax
.MaxWidth
+ hborders
,
1319 data
->wd_MinMax
.MaxHeight
+ vborders
);
1324 static void KillHelpBubble(struct MUI_WindowData
*data
, Object
*obj
,
1325 BOOL kill_bubblemode
)
1327 if (data
->wd_HelpObject
)
1329 DoMethod(data
->wd_HelpObject
, MUIM_DeleteBubble
,
1330 (IPTR
) data
->wd_HelpBubble
);
1331 data
->wd_HelpObject
= NULL
;
1332 data
->wd_HelpBubble
= NULL
;
1335 if (kill_bubblemode
)
1336 data
->wd_Flags
&= ~MUIWF_BUBBLEMODE
;
1338 if (data
->wd_Flags
& MUIWF_BUBBLEMODE
)
1340 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_LATER
;
1344 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_FIRST
;
1351 typedef BOOL(*UNDERCHECK_FUNC
) (Object
*obj
);
1353 static BOOL
ShortHelpUnderPointerCheck(Object
*obj
)
1355 return muiAreaData(obj
)->mad_ShortHelp
? TRUE
: FALSE
;
1358 static Object
*ObjectUnderPointer(struct MUI_WindowData
*data
, Object
*obj
,
1359 LONG x
, LONG y
, UNDERCHECK_FUNC func
)
1363 struct MinList
*ChildList
= NULL
;
1365 if (!(muiAreaData(obj
)->mad_Flags
& MADF_CANDRAW
))
1368 if (!(x
>= _left(obj
) && x
<= _right(obj
)
1369 && y
>= _top(obj
) && y
<= _bottom(obj
)))
1374 if ((get(obj
, MUIA_Group_ChildList
, &(ChildList
)))
1375 && (ChildList
!= NULL
))
1377 cstate
= (Object
*) ChildList
->mlh_Head
;
1378 while ((child
= NextObject(&cstate
)))
1382 if ((x
>= _left(child
) && x
<= _right(child
)
1384 y
>= _top(child
) && y
<= _bottom(child
))
1385 && (ret
= ObjectUnderPointer(data
, child
, x
, y
, func
)))
1398 static BOOL
ContextMenuUnderPointer(struct MUI_WindowData
*data
,
1399 Object
*obj
, LONG x
, LONG y
)
1403 struct MinList
*ChildList
= NULL
;
1405 if (!(x
>= _left(obj
) && x
<= _right(obj
)
1406 && y
>= _top(obj
) && y
<= _bottom(obj
)))
1411 if ((get(obj
, MUIA_Group_ChildList
, &(ChildList
)))
1412 && (ChildList
!= NULL
))
1415 cstate
= (Object
*) ChildList
->mlh_Head
;
1416 while ((child
= NextObject(&cstate
)))
1418 if ((x
>= _left(child
) && x
<= _right(child
)
1420 y
>= _top(child
) && y
<= _bottom(child
))
1421 && (ContextMenuUnderPointer(data
, child
, x
, y
)))
1426 if (!(muiAreaData(obj
)->mad_Flags
& MADF_CANDRAW
))
1428 if (!(muiAreaData(obj
)->mad_ContextMenu
))
1436 static void ActivateObject(struct MUI_WindowData
*data
)
1438 //bug("Window::ActivateObject (dummy) %08lx\n", data->wd_ActiveObject);
1439 // if (FindObjNode(&data->wd_CycleChain, data->wd_ActiveObject))
1440 // DoMethod(data->wd_ActiveObject, MUIM_GoActive);
1442 // data->wd_ActiveObject = NULL;
1444 //activate better string gadgets.Fix from Georg S On ML List
1445 if (FindObjNode(&data
->wd_CycleChain
, data
->wd_ActiveObject
))
1447 if (!(data
->wd_Flags
& MUIWF_OBJECTGOACTIVESENT
))
1449 data
->wd_Flags
|= MUIWF_OBJECTGOACTIVESENT
;
1450 DoMethod(data
->wd_ActiveObject
, MUIM_GoActive
);
1454 data
->wd_ActiveObject
= NULL
;
1459 /* handle intuimessage while an object is being dragged
1460 * (reply imsg before returning)
1461 * Returns TRUE if finished dragging.
1463 static BOOL
HandleDragging(Object
*oWin
, struct MUI_WindowData
*data
,
1464 struct IntuiMessage
*imsg
)
1466 struct Window
*iWin
;
1467 BOOL finish_drag
= FALSE
;
1469 iWin
= imsg
->IDCMPWindow
;
1471 if (imsg
->Class
== IDCMP_MOUSEMOVE
)
1473 struct Layer
*layer
;
1475 LockLayerInfo(&iWin
->WScreen
->LayerInfo
);
1476 layer
= WhichLayer(&iWin
->WScreen
->LayerInfo
,
1477 iWin
->LeftEdge
+ imsg
->MouseX
, iWin
->TopEdge
+ imsg
->MouseY
);
1478 UnlockLayerInfo(&iWin
->WScreen
->LayerInfo
);
1480 if (data
->wd_DropObject
)
1484 imsg
->MouseX
+ iWin
->LeftEdge
-
1485 data
->wd_DropWindow
->LeftEdge
;
1487 imsg
->MouseY
+ iWin
->TopEdge
- data
->wd_DropWindow
->TopEdge
;
1489 wnd
= _window(data
->wd_DropObject
);
1490 if (mousex
< _left(data
->wd_DropObject
)
1491 || mousex
> _right(data
->wd_DropObject
)
1492 || mousey
< _top(data
->wd_DropObject
)
1493 || mousey
> _bottom(data
->wd_DropObject
)
1494 || layer
!= wnd
->WLayer
)
1496 /* We have left the object */
1497 UndrawDragNDrop(data
->wd_dnd
);
1498 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
,
1499 (IPTR
) data
->wd_DragObject
);
1500 data
->wd_DropObject
= NULL
;
1502 } /* if (data->wd_DropObject) */
1504 if (!data
->wd_DropObject
)
1506 Object
*dest_wnd
= NULL
;
1508 /* Find out if app has an open window at this position */
1513 struct MinList
*ChildList
= 0;
1515 get(_app(oWin
), MUIA_Application_WindowList
, &(ChildList
));
1516 cstate
= (Object
*) ChildList
->mlh_Head
;
1517 while ((child
= NextObject(&cstate
)))
1519 struct Window
*wnd
= NULL
;
1520 get(child
, MUIA_Window_Window
, &wnd
);
1524 if (wnd
->WLayer
== layer
)
1526 data
->wd_DropWindow
= wnd
;
1535 Object
*root
= NULL
;
1536 get(dest_wnd
, MUIA_Window_RootObject
, &root
);
1540 if ((data
->wd_DropObject
= (Object
*) DoMethod
1541 (root
, MUIM_DragQueryExtended
,
1542 (IPTR
) data
->wd_DragObject
,
1543 imsg
->MouseX
+ iWin
->LeftEdge
-
1544 data
->wd_DropWindow
->LeftEdge
,
1545 imsg
->MouseY
+ iWin
->TopEdge
-
1546 data
->wd_DropWindow
->TopEdge
)))
1548 UndrawDragNDrop(data
->wd_dnd
);
1549 DoMethod(data
->wd_DropObject
, MUIM_DragBegin
,
1550 (IPTR
) data
->wd_DragObject
);
1556 if (data
->wd_DropObject
)
1560 for (i
= 0; i
< 2; i
++)
1562 LONG res
= DoMethod(data
->wd_DropObject
, MUIM_DragReport
,
1563 (IPTR
) data
->wd_DragObject
,
1564 imsg
->MouseX
+ iWin
->LeftEdge
-
1565 data
->wd_DropWindow
->LeftEdge
,
1566 imsg
->MouseY
+ iWin
->TopEdge
-
1567 data
->wd_DropWindow
->TopEdge
, update
);
1570 case MUIV_DragReport_Abort
:
1571 UndrawDragNDrop(data
->wd_dnd
);
1572 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
,
1573 (IPTR
) data
->wd_DragObject
);
1574 data
->wd_DropObject
= NULL
;
1578 case MUIV_DragReport_Continue
:
1580 case MUIV_DragReport_Lock
:
1582 case MUIV_DragReport_Refresh
:
1583 UndrawDragNDrop(data
->wd_dnd
);
1589 DrawDragNDrop(data
->wd_dnd
, imsg
->MouseX
+ iWin
->LeftEdge
,
1590 imsg
->MouseY
+ iWin
->TopEdge
);
1593 if (imsg
->Class
== IDCMP_MOUSEBUTTONS
)
1595 if ((imsg
->Code
== MENUDOWN
) || (imsg
->Code
== SELECTUP
))
1597 UndrawDragNDrop(data
->wd_dnd
);
1598 if (imsg
->Code
== SELECTUP
&& data
->wd_DropObject
)
1600 DoMethod(data
->wd_DropObject
, MUIM_DragDrop
,
1601 (IPTR
) data
->wd_DragObject
,
1602 imsg
->MouseX
+ iWin
->LeftEdge
-
1603 data
->wd_DropWindow
->LeftEdge
,
1604 imsg
->MouseY
+ iWin
->TopEdge
-
1605 data
->wd_DropWindow
->TopEdge
);
1606 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
,
1607 (IPTR
) data
->wd_DragObject
);
1608 data
->wd_DropObject
= NULL
;
1610 else if (imsg
->Code
== SELECTUP
)
1612 DoMethod(data
->wd_DragObject
, MUIM_UnknownDropDestination
,
1619 if (imsg
->Class
== IDCMP_CLOSEWINDOW
)
1624 if (data
->wd_DropObject
)
1626 UndrawDragNDrop(data
->wd_dnd
);
1627 DoMethod(data
->wd_DropObject
, MUIM_DragFinish
,
1628 (IPTR
) data
->wd_DragObject
);
1629 data
->wd_DropObject
= NULL
;
1631 DeleteDragNDrop(data
->wd_dnd
);
1632 DoMethod(data
->wd_DragObject
, MUIM_DeleteDragImage
,
1633 (IPTR
) data
->wd_DragImage
);
1634 muiAreaData(data
->wd_DragObject
)->mad_Flags
&= ~MADF_DRAGGING
;
1635 data
->wd_DragImage
= NULL
;
1636 data
->wd_DragObject
= NULL
;
1637 data
->wd_DropWindow
= NULL
;
1638 data
->wd_dnd
= NULL
;
1640 /* stop listening to IDCMP_MOUSEMOVE */
1641 ChangeEvents(data
, GetDefaultEvents());
1644 ReplyMsg((struct Message
*)imsg
);
1649 /* Reply to imsg if handled */
1650 BOOL
HandleWindowEvent(Object
*oWin
, struct MUI_WindowData
*data
,
1651 struct IntuiMessage
*imsg
)
1653 struct Window
*iWin
;
1654 BOOL is_handled
= TRUE
;
1655 BOOL replied
= FALSE
;
1657 iWin
= imsg
->IDCMPWindow
;
1658 switch (imsg
->Class
)
1660 case IDCMP_ACTIVEWINDOW
:
1661 data
->wd_Flags
|= MUIWF_ACTIVE
;
1662 if (data
->wd_OldActive
)
1663 set(oWin
, MUIA_Window_ActiveObject
, data
->wd_OldActive
);
1664 set(oWin
, MUIA_Window_Activate
, TRUE
);
1665 is_handled
= FALSE
; /* forwardable to area event handlers */
1668 case IDCMP_INACTIVEWINDOW
:
1669 KillHelpBubble(data
, oWin
, TRUE
);
1670 if (data
->wd_ActiveObject
)
1672 data
->wd_OldActive
= data
->wd_ActiveObject
;
1673 set(oWin
, MUIA_Window_ActiveObject
,
1674 MUIV_Window_ActiveObject_None
);
1676 data
->wd_Flags
&= ~MUIWF_ACTIVE
;
1677 set(oWin
, MUIA_Window_Activate
, FALSE
);
1678 is_handled
= FALSE
; /* forwardable to area event handlers */
1682 case IDCMP_CHANGEWINDOW
:
1684 int hborders
= iWin
->BorderLeft
+ iWin
->BorderRight
;
1685 int vborders
= iWin
->BorderTop
+ iWin
->BorderBottom
;
1687 /* set window limits according to window contents */
1690 data
->wd_MinMax
.MinWidth
+ hborders
,
1691 data
->wd_MinMax
.MinHeight
+ vborders
,
1692 data
->wd_MinMax
.MaxWidth
+ hborders
,
1693 data
->wd_MinMax
.MaxHeight
+ vborders
);
1696 if ((iWin
->GZZWidth
!= data
->wd_Width
)
1697 || (iWin
->GZZHeight
!= data
->wd_Height
))
1699 data
->wd_Width
= iWin
->GZZWidth
;
1700 data
->wd_Height
= iWin
->GZZHeight
;
1701 DoHideMethod(data
->wd_RootObject
);
1703 data
->wd_Flags
|= MUIWF_RESIZING
;
1704 RefreshWindow(oWin
, data
);
1706 /* Use wd_Class below instead of OCLASS(oWin), because otherwise if oWin is an
1707 instance of a subclass of window class, then superset will go to window class's
1708 OM_SET where MUIA_Window_Width|Height for some reason are always set to 0. This has
1709 the side effect that after the first window resize all future window moves(!) too
1710 are interpreted as "window size was changed" (if check above returns TRUE even if
1711 window size did not change) */
1712 superset(data
->wd_Class
, oWin
, MUIA_Window_Width
, data
->wd_Width
);
1713 superset(data
->wd_Class
, oWin
, MUIA_Window_Height
, data
->wd_Height
);
1716 if (iWin
->LeftEdge
!= data
->wd_X
)
1718 data
->wd_X
= iWin
->LeftEdge
;
1719 superset(data
->wd_Class
, oWin
, MUIA_Window_LeftEdge
, data
->wd_X
);
1721 if (iWin
->TopEdge
!= data
->wd_Y
)
1723 data
->wd_Y
= iWin
->TopEdge
;
1724 superset(data
->wd_Class
, oWin
, MUIA_Window_TopEdge
, data
->wd_Y
);
1727 is_handled
= FALSE
; /* forwardable to area event handlers */
1730 case IDCMP_REFRESHWINDOW
:
1731 ReplyMsg((struct Message
*)imsg
);
1733 RefreshWindow(oWin
, data
);
1736 case IDCMP_CLOSEWINDOW
:
1737 ReplyMsg((struct Message
*)imsg
);
1739 set(oWin
, MUIA_Window_CloseRequest
, TRUE
);
1742 case IDCMP_MENUPICK
:
1743 ReplyMsg((struct Message
*)imsg
);
1748 if (MENUNUM(imsg
->Code
) != NOMENU
1749 && ITEMNUM(imsg
->Code
) != NOITEM
)
1751 struct MenuItem
*item
=
1752 ItemAddress(data
->wd_Menu
, imsg
->Code
);
1755 Object
*item_obj
= (Object
*) GTMENUITEM_USERDATA(item
);
1761 if (item
->Flags
& CHECKIT
)
1762 set(item_obj
, MUIA_Menuitem_Checked
,
1763 ! !(item
->Flags
& CHECKED
));
1765 set(item_obj
, MUIA_Menuitem_Trigger
, (IPTR
) item
);
1767 get(oWin
, MUIA_ApplicationObject
, &app
);
1768 get(item_obj
, MUIA_UserData
, &udata
);
1770 set(app
, MUIA_Application_MenuAction
, udata
);
1771 set(oWin
, MUIA_Window_MenuAction
, udata
);
1772 DoMethod(app
, MUIM_Application_ReturnID
, udata
);
1779 case IDCMP_IDCMPUPDATE
:
1780 is_handled
= FALSE
; /* forwardable to area event handlers */
1781 if (data
->wd_VertProp
|| data
->wd_HorizProp
)
1783 struct TagItem
*tag
;
1784 tag
= FindTagItem(GA_ID
, (struct TagItem
*)imsg
->IAddress
);
1787 /* If there's a propclass object connected to the prop
1788 gadget, the prop gadget's userdata will point to
1789 that propclass object. See classes/prop.c */
1791 if (data
->wd_VertProp
)
1793 if (tag
->ti_Data
== GADGETID(data
->wd_VertProp
))
1796 if (tag
->ti_Data
== GADGETID(data
->wd_UpButton
))
1799 (Object
*) ((struct Gadget
*)data
->
1800 wd_VertProp
)->UserData
;
1803 DoMethod(prop
, MUIM_Prop_Decrease
, 1);
1806 if (tag
->ti_Data
== GADGETID(data
->wd_DownButton
))
1809 (Object
*) ((struct Gadget
*)data
->
1810 wd_VertProp
)->UserData
;
1813 DoMethod(prop
, MUIM_Prop_Increase
, 1);
1818 if (data
->wd_HorizProp
)
1820 if (tag
->ti_Data
== GADGETID(data
->wd_HorizProp
))
1823 if (tag
->ti_Data
== GADGETID(data
->wd_LeftButton
))
1826 (Object
*) ((struct Gadget
*)data
->
1827 wd_HorizProp
)->UserData
;
1830 DoMethod(prop
, MUIM_Prop_Decrease
, 1);
1833 if (tag
->ti_Data
== GADGETID(data
->wd_RightButton
))
1836 (Object
*) ((struct Gadget
*)data
->
1837 wd_HorizProp
)->UserData
;
1840 DoMethod(prop
, MUIM_Prop_Increase
, 1);
1848 case IDCMP_INTUITICKS
:
1849 if (data
->wd_HelpTicker
)
1851 data
->wd_HelpTicker
--;
1853 if (data
->wd_HelpTicker
== 0)
1856 ObjectUnderPointer(data
, data
->wd_RootObject
,
1857 imsg
->MouseX
, imsg
->MouseY
,
1858 ShortHelpUnderPointerCheck
);
1860 if (underobj
!= data
->wd_HelpObject
)
1862 if (data
->wd_HelpObject
)
1864 DoMethod(data
->wd_HelpObject
, MUIM_DeleteBubble
,
1865 (IPTR
) data
->wd_HelpBubble
);
1867 data
->wd_HelpObject
= NULL
;
1868 data
->wd_HelpBubble
= NULL
;
1873 data
->wd_HelpBubble
=
1874 (APTR
) DoMethod(underobj
, MUIM_CreateBubble
,
1875 imsg
->MouseX
, imsg
->MouseY
, 0, 0);
1876 if (data
->wd_HelpBubble
)
1878 data
->wd_HelpObject
= underobj
;
1879 data
->wd_Flags
|= MUIWF_BUBBLEMODE
;
1884 if (data
->wd_Flags
& MUIWF_BUBBLEMODE
)
1886 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_LATER
;
1890 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_FIRST
;
1895 is_handled
= FALSE
; /* forwardable to area event handlers */
1898 case IDCMP_MOUSEBUTTONS
:
1899 DoMethod(oWin
, MUIM_Window_Snapshot
, 0);
1900 KillHelpBubble(data
, oWin
, TRUE
);
1905 case IDCMP_MOUSEMOVE
:
1906 KillHelpBubble(data
, oWin
, FALSE
);
1915 if (is_handled
&& !replied
)
1916 ReplyMsg((struct Message
*)imsg
);
1921 static ULONG
InvokeEventHandler(struct MUI_EventHandlerNode
*ehn
,
1922 struct IntuiMessage
*event
, ULONG muikey
)
1926 if (!(_flags(ehn
->ehn_Object
) & MADF_CANDRAW
))
1928 if (!(_flags(ehn
->ehn_Object
) & MADF_SHOWME
))
1932 && event
->Class
== IDCMP_MOUSEBUTTONS
1933 && event
->Code
== SELECTDOWN
1934 && (_flags(ehn
->ehn_Object
) & MADF_INVIRTUALGROUP
))
1937 Here we filter out SELECTDOWN messages if objects is in a virtual
1938 group but the click went out of the virtual group
1940 Object
*obj
= ehn
->ehn_Object
;
1941 Object
*parent
= obj
;
1942 Object
*wnd
= _win(obj
);
1944 while (get(parent
, MUIA_Parent
, &parent
))
1950 if (_flags(parent
) & MADF_ISVIRTUALGROUP
)
1952 if (event
->MouseX
< _mleft(parent
)
1953 || event
->MouseX
> _mright(parent
)
1954 || event
->MouseY
< _mtop(parent
)
1955 || event
->MouseY
> _mbottom(parent
))
1964 if (ehn
->ehn_Flags
& MUI_EHF_HANDLEINPUT
)
1966 DoMethod(ehn
->ehn_Object
, MUIM_HandleInput
, (IPTR
) event
, muikey
);
1973 (ehn
->ehn_Class
, ehn
->ehn_Object
, MUIM_HandleEvent
,
1974 (IPTR
) event
, muikey
);
1977 DoMethod(ehn
->ehn_Object
, MUIM_HandleEvent
, (IPTR
) event
,
1984 static void HandleRawkey(Object
*win
, struct MUI_WindowData
*data
,
1985 struct IntuiMessage
*event
)
1988 struct MUI_EventHandlerNode
*ehn
;
1989 struct IntuiMessage imsg_copy
;
1990 struct InputEvent ie
= { 0 };
1992 LONG muikey
= MUIKEY_NONE
;
1993 Object
*active_object
= NULL
;
1998 KillHelpBubble(data
, win
, BUBBLEHELP_TICKER_FIRST
);
2000 ie
.ie_NextEvent
= NULL
;
2001 ie
.ie_Class
= IECLASS_RAWKEY
;
2003 ie
.ie_Code
= event
->Code
;
2004 ie
.ie_Qualifier
= event
->Qualifier
;
2005 ie
.ie_EventAddress
= (APTR
) * (IPTR
*) event
->IAddress
;
2007 ie
.ie_TimeStamp
.Seconds
= event
->Seconds
;
2008 ie
.ie_TimeStamp
.Microseconds
= event
->Micros
;
2010 ie
.ie_TimeStamp
.tv_secs
= event
->Seconds
;
2011 ie
.ie_TimeStamp
.tv_micro
= event
->Micros
;
2014 set(win
, MUIA_Window_InputEvent
, (IPTR
) & ie
);
2016 /* get the vanilla key for control char */
2020 /* Remove the up prefix as convert key does not convert upkey event */
2021 msg_code
= event
->Code
;
2022 event
->Code
&= ~IECODE_UP_PREFIX
;
2023 key
= ConvertKey(event
);
2024 event
->Code
= msg_code
;
2028 deadkey
= *(ULONG
*) event
->IAddress
;
2029 imsg_copy
.IAddress
= &deadkey
;
2030 ReplyMsg((struct Message
*)event
);
2033 //bug("rawkey: code=%lx, qual=%lx\n", event->Code, event->Qualifier);
2035 /* check if imsg translates to predefined keystroke */
2037 struct InputEvent ievent
;
2038 BOOL matched
= FALSE
;
2040 ievent
.ie_NextEvent
= NULL
;
2041 ievent
.ie_Class
= IECLASS_RAWKEY
;
2042 ievent
.ie_SubClass
= 0;
2043 ievent
.ie_Code
= event
->Code
;
2044 ievent
.ie_Qualifier
= event
->Qualifier
;
2045 /* ie_EventAddress is not used by MatchIX. If needed, it should be
2046 * ensured that it is still a valid address because of the shallow
2047 * IntuiMessage copy currently done in _zune_window_message before
2048 * message is replied.
2050 ievent
.ie_EventAddress
= NULL
;
2051 //ievent.ie_EventAddress = (APTR *) *((ULONG *)(event->IAddress));
2053 for (muikey
= MUIKEY_COUNT
- 1; muikey
>= MUIKEY_PRESS
; muikey
--)
2055 if (muiGlobalInfo(win
)->mgi_Prefs
->muikeys
[muikey
].ix_well
!= 0
2057 &muiGlobalInfo(win
)->mgi_Prefs
->muikeys
[muikey
].ix
))
2066 if (muikey
== MUIKEY_PRESS
&& (event
->Code
& IECODE_UP_PREFIX
))
2067 muikey
= MUIKEY_RELEASE
;
2071 muikey
= MUIKEY_NONE
;
2073 } /* check if imsg translate to predefined keystroke */
2075 if ((muikey
!= MUIKEY_NONE
) && !(data
->wd_DisabledKeys
& (1 << muikey
)))
2077 D(bug("HandleRawkey: try MUIKEY %ld on window %0x08lx\n", muikey
,
2091 case MUIKEY_PAGEDOWN
:
2101 case MUIKEY_WORDLEFT
:
2103 case MUIKEY_WORDRIGHT
:
2105 case MUIKEY_LINESTART
:
2107 case MUIKEY_LINEEND
:
2109 case MUIKEY_GADGET_NEXT
:
2110 set(win
, MUIA_Window_ActiveObject
,
2111 MUIV_Window_ActiveObject_Next
);
2113 case MUIKEY_GADGET_PREV
:
2114 set(win
, MUIA_Window_ActiveObject
,
2115 MUIV_Window_ActiveObject_Prev
);
2117 case MUIKEY_GADGET_OFF
:
2118 set(win
, MUIA_Window_ActiveObject
,
2119 MUIV_Window_ActiveObject_None
);
2121 case MUIKEY_WINDOW_CLOSE
:
2122 set(win
, MUIA_Window_CloseRequest
, TRUE
);
2124 case MUIKEY_WINDOW_NEXT
:
2126 case MUIKEY_WINDOW_PREV
:
2137 active_object
= NULL
;
2138 if ((data
->wd_ActiveObject
!= NULL
)
2139 && (DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
2140 (IPTR
) data
->wd_ActiveObject
) != (IPTR
) NULL
))
2142 active_object
= data
->wd_ActiveObject
;
2143 get(active_object
, MUIA_Disabled
, &disabled
);
2146 data
->wd_ActiveObject
= NULL
;
2148 /* try ActiveObject */
2149 if ((active_object
!= NULL
) && !disabled
)
2153 ** Which method should be used for muikeys? MUIM_HandleInput or
2154 ** MUIM_HandleEvent. Also note that there is a flag MUI_EHF_ALWAYSKEYS
2155 ** which probably means that all keys events are requested??
2156 ** For now MUIM_HandleEvent is used as this is currently implemented
2157 ** in Area class ;) although I guess it should be MUIM_HandleInput as
2161 if (muikey
!= MUIKEY_NONE
)
2164 DoMethod(active_object
, MUIM_HandleEvent
, (IPTR
) event
,
2166 if (res
& MUI_EventHandlerRC_Eat
)
2170 D(bug("HandleRawkey: try active object (%08lx) handlers\n",
2173 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2175 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2177 if ((ehn
->ehn_Object
== active_object
)
2178 && ((ehn
->ehn_Events
& IDCMP_RAWKEY
)
2179 || (ehn
->ehn_Flags
& MUI_EHF_ALWAYSKEYS
)))
2181 D(bug("HandleRawkey: (active) invoking on %p (ehn=%p) "
2182 "event=%p muikey=%p\n",
2183 ehn
->ehn_Object
, ehn
, event
, muikey
));
2184 res
= InvokeEventHandler(ehn
, event
, muikey
);
2185 D(bug("HandleRawkey: (active) got res=%d\n", res
));
2186 if (res
& MUI_EventHandlerRC_Eat
)
2189 /* Leave the loop if a different object has been activated */
2190 if (active_object
!= data
->wd_ActiveObject
)
2195 // event not eaten by active object, try its parents
2196 // this is to implement popup key in Popstring
2197 if (active_object
== data
->wd_ActiveObject
)
2199 Object
*current_obj
= active_object
;
2201 D(bug("HandleRawkey: try active object parents handlers\n"));
2202 while (current_obj
!= NULL
)
2204 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
;
2207 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2209 if ((ehn
->ehn_Object
== current_obj
)
2210 && ((ehn
->ehn_Events
& IDCMP_RAWKEY
)
2211 || (ehn
->ehn_Flags
& MUI_EHF_ALWAYSKEYS
)))
2213 //D(bug("HandleRawkey: (active parents) invoking on "
2214 // "%p (ehn=%p) event=%p muikey=%p\n",
2215 // ehn->ehn_Object, ehn, event, muikey));
2216 res
= InvokeEventHandler(ehn
, event
, muikey
);
2217 //D(bug("HandleRawkey: (active parents) got res=%d\n",
2219 if (res
& MUI_EventHandlerRC_Eat
)
2222 /* Leave the loop if a different object has been
2224 if (active_object
!= data
->wd_ActiveObject
)
2228 current_obj
= (Object
*) XGET(current_obj
, MUIA_Parent
);
2233 D(bug("HandleRawkey: try default object handlers\n"));
2235 /* try DefaultObject */
2236 if (data
->wd_DefaultObject
!= NULL
)
2237 get(data
->wd_DefaultObject
, MUIA_Disabled
, &disabled
);
2239 if ((data
->wd_DefaultObject
!= NULL
) && !disabled
2240 && (active_object
!= data
->wd_DefaultObject
))
2242 /* No, we only should do this if the object actually has requested
2243 * this via RequestIDCMP()! */
2244 // if (muikey != MUIKEY_NONE
2245 // && (_flags(data->wd_DefaultObject) & MADF_CANDRAW))
2247 // DoMethod(data->wd_DefaultObject, MUIM_HandleInput, event, muikey);
2251 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2253 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2255 if ((ehn
->ehn_Object
== data
->wd_DefaultObject
)
2256 && ((ehn
->ehn_Events
& IDCMP_RAWKEY
)
2257 || (ehn
->ehn_Flags
& MUI_EHF_ALWAYSKEYS
)))
2259 //D(bug("HandleRawkey: (default) invoking on %p (ehn=%p) "
2260 //"event=%p muikey=%p\n",
2261 //ehn->ehn_Object, ehn, event, muikey));
2262 res
= InvokeEventHandler(ehn
, event
, muikey
);
2263 //D(bug("HandleRawkey: (default) got res=%d\n", res));
2264 if (res
& MUI_EventHandlerRC_Eat
)
2271 D(bug("HandleRawkey: try other handlers\n"));
2273 // try other handlers
2274 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2276 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2278 // skip Active and Default object as they have already been
2280 if (ehn
->ehn_Object
== data
->wd_ActiveObject
2281 || ehn
->ehn_Object
== data
->wd_DefaultObject
)
2284 if (ehn
->ehn_Events
& IDCMP_RAWKEY
)
2286 //D(bug("HandleRawkey: (others) invoking on %p (ehn=%p) "
2287 //"event=%p muikey=%p\n",
2288 //ehn->ehn_Object, ehn, event, muikey));
2289 res
= InvokeEventHandler(ehn
, event
, MUIKEY_NONE
);
2290 //D(bug("HandleRawkey: (others) got res=%d\n", res));
2291 if (res
& MUI_EventHandlerRC_Eat
)
2296 D(bug("HandleRawkey: try control chars handlers\n"));
2298 /* try Control Chars */
2299 //bug("ctrlchar, key='%c' code=0x%08lx\n", key, event->Code);
2302 for (mn
= data
->wd_CCList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2304 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2306 if (ehn
->ehn_Events
== key
)
2309 LONG muikey2
= ehn
->ehn_Flags
;
2311 get(ehn
->ehn_Object
, MUIA_Disabled
, &disabled
);
2315 //bug("control char\n");
2316 if (event
->Code
& IECODE_UP_PREFIX
)
2318 /* simulate a release */
2319 if (muikey2
== MUIKEY_PRESS
)
2320 muikey2
= MUIKEY_RELEASE
;
2325 if ((muikey2
!= MUIKEY_NONE
)
2326 && (_flags(ehn
->ehn_Object
) & MADF_CANDRAW
)
2327 && (_flags(ehn
->ehn_Object
) & MADF_SHOWME
))
2330 (ehn
->ehn_Class
, ehn
->ehn_Object
, MUIM_HandleEvent
,
2331 (IPTR
) NULL
, muikey2
);
2332 if (res
& MUI_EventHandlerRC_Eat
)
2340 /* forward non-keystroke events to event handlers */
2341 static void HandleInputEvent(Object
*win
, struct MUI_WindowData
*data
,
2342 struct IntuiMessage
*event
)
2345 struct MUI_EventHandlerNode
*ehn
;
2346 struct IntuiMessage imsg_copy
;
2348 ULONG mask
= event
->Class
;
2350 if (mask
!= IDCMP_IDCMPUPDATE
)
2353 imsg_copy
.IAddress
= NULL
; /* be sure to trap access to that */
2354 ReplyMsg((struct Message
*)event
);
2358 if (mask
== IDCMP_MOUSEMOVE
)
2360 struct Window
*iWin
;
2361 iWin
= event
->IDCMPWindow
;
2363 if (ContextMenuUnderPointer(data
, data
->wd_RootObject
,
2364 event
->MouseX
, event
->MouseY
))
2366 iWin
->Flags
|= WFLG_RMBTRAP
;
2368 else if (!data
->wd_NoMenus
)
2370 iWin
->Flags
&= ~WFLG_RMBTRAP
;
2374 for (mn
= data
->wd_EHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
2376 ehn
= (struct MUI_EventHandlerNode
*)mn
;
2378 if (ehn
->ehn_Events
& mask
)
2382 get(ehn
->ehn_Object
, MUIA_Disabled
, &disabled
);
2386 res
= InvokeEventHandler(ehn
, event
, MUIKEY_NONE
);
2387 if (res
& MUI_EventHandlerRC_Eat
)
2393 if (mask
== IDCMP_IDCMPUPDATE
)
2394 ReplyMsg((struct Message
*)event
);
2398 /* process window message; this does a ReplyMsg() to the message */
2399 /* Called from application.c */
2400 void _zune_window_message(struct IntuiMessage
*imsg
)
2402 struct Window
*iWin
;
2404 struct MUI_WindowData
*data
;
2407 iWin
= imsg
->IDCMPWindow
;
2408 oWin
= (Object
*) iWin
->UserData
;
2409 data
= muiWindowData(oWin
);
2411 if (data
->wd_SleepCount
> 0)
2414 /* Window is sleeping, so we just ignore (and reply) all messages.
2415 * MUI 3.8/AmigaOS3 also receives all messages (IDCMP Flags
2416 * are not modified during sleeping). MUI refreshes the window
2417 * contents, so it seems to handle IDCMP_REFRESHWINDOW messages.
2418 * If any other messages are handled by MUI is unsure/not tested.
2420 if (imsg
->Class
== IDCMP_REFRESHWINDOW
)
2424 ReplyMsg((struct Message
*)imsg
);
2427 RefreshWindow(oWin
, data
);
2432 if (data
->wd_DragObject
)
2434 if (!HandleDragging(oWin
, data
, imsg
))
2438 handled
= HandleWindowEvent(oWin
, data
, imsg
);
2441 if (IDCMP_RAWKEY
== imsg
->Class
)
2442 HandleRawkey(oWin
, data
, imsg
);
2443 else if (IDCMP_GADGETUP
== imsg
->Class
)
2446 if (ETI_MUI
== ((struct Gadget
*)imsg
->IAddress
)->GadgetID
)
2448 DoMethod(_app(oWin
), MUIM_Application_OpenConfigWindow
);
2451 if (ETI_Iconify
== ((struct Gadget
*)imsg
->IAddress
)->GadgetID
)
2453 set(_app(oWin
), MUIA_Application_Iconified
, TRUE
);
2458 HandleInputEvent(oWin
, data
, imsg
);
2463 /**************************************************************************/
2464 /**************************************************************************/
2466 /* code for setting MUIA_Window_RootObject */
2467 static void ChangeRootObject(struct MUI_WindowData
*data
, Object
*obj
,
2472 ASSERT_VALID_PTR(data
);
2473 ASSERT_VALID_PTR(obj
);
2475 oldRoot
= data
->wd_RootObject
;
2476 if (!(data
->wd_Flags
& MUIWF_OPENED
))
2480 if (data
->wd_ActiveObject
== oldRoot
)
2481 set(obj
, MUIA_Window_ActiveObject
,
2482 MUIV_Window_ActiveObject_None
);
2483 DoMethod(oldRoot
, MUIM_DisconnectParent
);
2486 data
->wd_RootObject
= newRoot
;
2489 /* if window is in App tree, inform child */
2490 if (muiNotifyData(obj
)->mnd_GlobalInfo
)
2491 DoMethod(newRoot
, MUIM_ConnectParent
, (IPTR
) obj
);
2496 // find the ObjNode containing a pointer to the given object
2497 // currently only used for cycle chain objects
2498 static struct ObjNode
*FindObjNode(struct MinList
*list
, Object
*obj
)
2500 struct ObjNode
*node
;
2502 ASSERT_VALID_PTR(list
);
2507 ASSERT_VALID_PTR(obj
);
2509 for (node
= (struct ObjNode
*)list
->mlh_Head
;
2510 node
->node
.mln_Succ
; node
= (struct ObjNode
*)node
->node
.mln_Succ
)
2512 if (node
->obj
== obj
)
2520 static Object
*GetFirstActiveObject(struct MUI_WindowData
*data
)
2522 ASSERT_VALID_PTR(data
);
2524 if (!IsListEmpty(&data
->wd_CycleChain
))
2525 return ((struct ObjNode
*)data
->wd_CycleChain
.mlh_Head
)->obj
;
2530 static Object
*GetLastActiveObject(struct MUI_WindowData
*data
)
2532 ASSERT_VALID_PTR(data
);
2534 if (!IsListEmpty(&data
->wd_CycleChain
))
2535 return ((struct ObjNode
*)data
->wd_CycleChain
.mlh_TailPred
)->obj
;
2540 typedef struct ObjNode
*objnode_iterator_t(struct ObjNode
*curr_node
);
2542 static objnode_iterator_t NextObjNodeIterator
;
2543 static objnode_iterator_t PrevObjNodeIterator
;
2545 static struct ObjNode
*NextObjNodeIterator(struct ObjNode
*curr_node
)
2547 if (curr_node
->node
.mln_Succ
->mln_Succ
)
2548 return (struct ObjNode
*)curr_node
->node
.mln_Succ
;
2553 static struct ObjNode
*PrevObjNodeIterator(struct ObjNode
*curr_node
)
2555 if (curr_node
->node
.mln_Pred
->mln_Pred
)
2556 return (struct ObjNode
*)curr_node
->node
.mln_Pred
;
2561 static Object
*GetPrevNextActiveObject(struct ObjNode
*old_activenode
,
2562 objnode_iterator_t node_iterator
)
2564 struct ObjNode
*curr_node
;
2565 struct ObjNode
*node
;
2568 ASSERT_VALID_PTR(old_activenode
);
2570 curr_node
= old_activenode
;
2576 node
= node_iterator(curr_node
);
2581 /* let's see if this object meets cycle requirements
2582 * (enabled & visible) */
2585 IPTR is_disabled
= 0;
2587 get(obj
, MUIA_Disabled
, &is_disabled
);
2589 if (!is_disabled
&& (_flags(obj
) & MADF_SHOWME
))
2603 /**************************************************************************
2604 Code for setting MUIA_Window_ActiveObject
2606 - remove focus drawing for current active object
2607 - find (if needed) the new active object
2608 - set data->wd_ActiveObject to the new object
2609 - draw focus around the new active object
2610 **************************************************************************/
2611 static void SetActiveObject(struct MUI_WindowData
*data
, Object
*obj
,
2614 struct ObjNode
*old_activenode
= NULL
;
2616 ASSERT_VALID_PTR(data
);
2617 ASSERT_VALID_PTR(obj
);
2619 D(bug("MUIC_Window:SetActiveObject(data, obj, %08lx) Active=%p\n",
2620 newval
, data
->wd_ActiveObject
));
2622 /* If the window is closed, we just store the object for later activation
2623 * when the window is (re)opened */
2624 if (!(data
->wd_Flags
& MUIWF_OPENED
))
2626 data
->wd_OldActive
= (Object
*)newval
;
2630 if ((data
->wd_ActiveObject
!= NULL
)
2631 && (DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
2632 (IPTR
) data
->wd_ActiveObject
) != (IPTR
) NULL
))
2634 if ((IPTR
) data
->wd_ActiveObject
!= newval
)
2637 FindObjNode(&data
->wd_CycleChain
, data
->wd_ActiveObject
);
2638 if ((data
->wd_Flags
& MUIWF_OBJECTGOACTIVESENT
)
2639 && (_flags(data
->wd_ActiveObject
) & MADF_SETUP
))
2641 D(bug("Deactivate=%p\n", data
->wd_ActiveObject
));
2642 DoMethod(data
->wd_ActiveObject
, MUIM_GoInactive
);
2647 data
->wd_ActiveObject
= NULL
;
2648 data
->wd_Flags
&= ~MUIWF_OBJECTGOACTIVESENT
;
2652 case MUIV_Window_ActiveObject_None
:
2655 case MUIV_Window_ActiveObject_Next
:
2656 if (old_activenode
!= NULL
)
2657 data
->wd_ActiveObject
= GetPrevNextActiveObject(old_activenode
,
2658 NextObjNodeIterator
);
2659 if (NULL
== data
->wd_ActiveObject
)
2660 data
->wd_ActiveObject
= GetFirstActiveObject(data
);
2663 case MUIV_Window_ActiveObject_Prev
:
2665 data
->wd_ActiveObject
= GetPrevNextActiveObject(old_activenode
,
2666 PrevObjNodeIterator
);
2667 if (NULL
== data
->wd_ActiveObject
)
2668 data
->wd_ActiveObject
= GetLastActiveObject(data
);
2672 data
->wd_ActiveObject
= (Object
*) newval
;
2677 if (data
->wd_ActiveObject
!= NULL
2678 && DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
2679 (IPTR
) data
->wd_ActiveObject
)
2680 && (_flags(data
->wd_ActiveObject
) & MADF_CANDRAW
))
2682 D(bug("Activate=%p\n", data
->wd_ActiveObject
));
2683 DoMethod(data
->wd_ActiveObject
, MUIM_GoActive
);
2684 data
->wd_Flags
|= MUIWF_OBJECTGOACTIVESENT
;
2689 static BOOL
InBox(struct IBox
*box
, WORD x
, WORD y
)
2691 return x
>= box
->Left
&& x
< box
->Left
+ box
->Width
2692 && y
>= box
->Top
&& y
< box
->Top
+ box
->Height
;
2697 * Pass on an AppMessage to all objects that it landed on.
2699 static void ForwardAppMessage(struct MUI_WindowData
*data
, Object
*child
,
2700 struct AppMessage
*appmsg
)
2702 WORD x
= appmsg
->am_MouseX
, y
= appmsg
->am_MouseY
;
2704 struct List
*children
= NULL
;
2706 ASSERT_VALID_PTR(data
);
2707 ASSERT_VALID_PTR(child
);
2709 set(child
, MUIA_AppMessage
, appmsg
);
2711 children
= (struct List
*)XGET(child
, MUIA_Group_ChildList
);
2713 if (children
!= NULL
)
2715 cstate
= (Object
*) children
->lh_Head
;
2716 while ((child
= NextObject(&cstate
)))
2718 if (InBox(&muiAreaData(child
)->mad_Box
, x
, y
))
2720 ForwardAppMessage(data
, child
, appmsg
);
2728 * calculate real dimensions from programmer requirements.
2729 * may be overridden by user settings if MUIA_Window_ID is set.
2731 /* MUIV_Window_Height_Screen and MUIV_Window_Height_Visible
2732 * are not handled yet, as their Width couterparts.
2734 static void WindowSelectDimensions(struct MUI_WindowData
*data
)
2736 if (!data
->wd_Width
)
2738 if (data
->wd_ReqWidth
> 0)
2739 data
->wd_Width
= data
->wd_ReqWidth
;
2740 else if (data
->wd_ReqWidth
== MUIV_Window_Width_Default
)
2741 data
->wd_Width
= data
->wd_MinMax
.DefWidth
;
2742 else if (_between(MUIV_Window_Width_MinMax(100),
2743 data
->wd_ReqWidth
, MUIV_Window_Width_MinMax(0)))
2745 data
->wd_Width
= data
->wd_MinMax
.MinWidth
2747 * (data
->wd_MinMax
.MaxWidth
- data
->wd_MinMax
.MinWidth
);
2749 else if (_between(MUIV_Window_Width_Screen(100),
2750 data
->wd_ReqWidth
, MUIV_Window_Width_Screen(0)))
2752 data
->wd_Width
= data
->wd_RenderInfo
.mri_ScreenWidth
2753 * (-(data
->wd_ReqWidth
+ 200)) / 100;
2755 else if (_between(MUIV_Window_Width_Visible(100),
2756 data
->wd_ReqWidth
, MUIV_Window_Width_Visible(0)))
2758 data
->wd_Width
= data
->wd_RenderInfo
.mri_ScreenWidth
2759 * (-(data
->wd_ReqWidth
+ 100)) / 100;
2762 if (data
->wd_ReqHeight
> 0)
2763 data
->wd_Height
= data
->wd_ReqHeight
;
2764 else if (data
->wd_ReqHeight
== MUIV_Window_Height_Default
)
2765 data
->wd_Height
= data
->wd_MinMax
.DefHeight
;
2766 else if (_between(MUIV_Window_Height_MinMax(100),
2767 data
->wd_ReqHeight
, MUIV_Window_Height_MinMax(0)))
2769 data
->wd_Height
= data
->wd_MinMax
.MinHeight
2770 - data
->wd_ReqHeight
2771 * (data
->wd_MinMax
.MaxHeight
- data
->wd_MinMax
.MinHeight
);
2773 else if (_between(MUIV_Window_Height_Screen(100),
2774 data
->wd_ReqHeight
, MUIV_Window_Height_Screen(0)))
2779 scr
= data
->wd_RenderInfo
.mri_Screen
;
2782 scr
->Height
- data
->wd_RenderInfo
.mri_BorderTop
-
2783 data
->wd_RenderInfo
.mri_BorderBottom
;
2785 data
->wd_Height
= height
* (-(data
->wd_ReqHeight
+ 200)) / 100;
2787 else if (_between(MUIV_Window_Height_Visible(100),
2788 data
->wd_ReqHeight
, MUIV_Window_Height_Visible(0)))
2790 data
->wd_Height
= data
->wd_RenderInfo
.mri_ScreenHeight
2791 * (-(data
->wd_ReqHeight
+ 100)) / 100;
2795 if (data
->wd_ReqWidth
== MUIV_Window_Width_Scaled
)
2796 data
->wd_Width
= data
->wd_Height
* data
->wd_MinMax
.MinWidth
2797 / data
->wd_MinMax
.MinHeight
;
2798 else if (data
->wd_ReqHeight
== MUIV_Window_Width_Scaled
)
2799 data
->wd_Height
= data
->wd_Width
* data
->wd_MinMax
.MinHeight
2800 / data
->wd_MinMax
.MinWidth
;
2802 data
->wd_Width
= CLAMP(data
->wd_Width
, data
->wd_MinMax
.MinWidth
,
2803 data
->wd_MinMax
.MaxWidth
);
2804 data
->wd_Height
= CLAMP(data
->wd_Height
, data
->wd_MinMax
.MinHeight
,
2805 data
->wd_MinMax
.MaxHeight
);
2809 /**************************************************************************
2811 **************************************************************************/
2812 IPTR
Window__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
2814 struct MUI_WindowData
*data
;
2815 struct TagItem
*tags
;
2816 struct TagItem
*tag
;
2818 obj
= (Object
*) DoSuperMethodA(cl
, obj
, (Msg
) msg
);
2822 /* Initial local instance data */
2823 data
= INST_DATA(cl
, obj
);
2825 data
->wd_Class
= cl
;
2826 data
->wd_MemoryPool
= CreatePool(0, 4096, 2048);
2827 if (NULL
== data
->wd_MemoryPool
)
2829 CoerceMethod(cl
, obj
, OM_DISPOSE
);
2833 data
->wd_RenderInfo
.mri_WindowObject
= obj
;
2835 NewList((struct List
*)&(data
->wd_EHList
));
2836 NewList((struct List
*)&(data
->wd_CCList
));
2837 NewList((struct List
*)&(data
->wd_CycleChain
));
2838 NewList((struct List
*)&(data
->wd_IDList
));
2840 data
->wd_CrtFlags
= WFLG_SIZEGADGET
| WFLG_DRAGBAR
| WFLG_DEPTHGADGET
2841 | WFLG_CLOSEGADGET
| WFLG_SIMPLE_REFRESH
2842 | WFLG_REPORTMOUSE
| WFLG_NEWLOOKMENUS
;
2843 data
->wd_ZoomGadget
= TRUE
;
2844 data
->wd_Events
= GetDefaultEvents();
2845 data
->wd_ActiveObject
= NULL
;
2847 data
->wd_ReqHeight
= MUIV_Window_Height_Default
;
2848 data
->wd_ReqWidth
= MUIV_Window_Width_Default
;
2849 data
->wd_RootObject
= NULL
;
2850 data
->wd_DefaultObject
= NULL
;
2852 data
->wd_AltDim
.Top
= MUIV_Window_AltTopEdge_NoChange
;
2853 data
->wd_AltDim
.Left
= MUIV_Window_AltLeftEdge_NoChange
;
2854 data
->wd_AltDim
.Width
= MUIV_Window_AltWidth_MinMax(0);
2855 data
->wd_AltDim
.Height
= MUIV_Window_AltHeight_MinMax(0);
2856 data
->wd_ReqX
= MUIV_Window_LeftEdge_Centered
;
2857 data
->wd_ReqY
= MUIV_Window_TopEdge_Centered
;
2858 data
->wd_DisabledKeys
= 0L;
2859 data
->wd_HelpTicker
= BUBBLEHELP_TICKER_FIRST
;
2861 /* parse initial taglist */
2863 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
));)
2865 switch (tag
->ti_Tag
)
2867 case MUIA_Window_EraseArea
:
2868 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_ERASEAREA
);
2871 case MUIA_Window_ToolBox
:
2872 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
, MUIWF_TOOLBOX
);
2875 case MUIA_Window_CloseGadget
:
2876 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
,
2880 case MUIA_Window_SizeGadget
:
2881 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
,
2885 case MUIA_Window_ZoomGadget
:
2886 data
->wd_ZoomGadget
= tag
->ti_Data
;
2889 case MUIA_Window_Backdrop
:
2890 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
,
2894 case MUIA_Window_Borderless
:
2895 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
,
2899 case MUIA_Window_DepthGadget
:
2900 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
,
2904 case MUIA_Window_DragBar
:
2905 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
, WFLG_DRAGBAR
);
2908 case MUIA_Window_SizeRight
:
2909 _handle_bool_tag(data
->wd_CrtFlags
, tag
->ti_Data
,
2913 case MUIA_Window_Height
:
2914 data
->wd_ReqHeight
= (LONG
) tag
->ti_Data
;
2917 case MUIA_Window_Width
:
2918 data
->wd_ReqWidth
= (LONG
) tag
->ti_Data
;
2921 case MUIA_Window_ID
:
2922 set(obj
, MUIA_Window_ID
, tag
->ti_Data
);
2925 case MUIA_Window_IsSubWindow
:
2926 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
2930 case MUIA_Window_Title
:
2931 set(obj
, MUIA_Window_Title
, tag
->ti_Data
);
2934 case MUIA_Window_ScreenTitle
:
2935 set(obj
, MUIA_Window_ScreenTitle
, tag
->ti_Data
);
2938 case MUIA_Window_Activate
:
2939 _handle_bool_tag(data
->wd_Flags
, !tag
->ti_Data
,
2940 MUIWF_DONTACTIVATE
);
2943 case MUIA_Window_DefaultObject
:
2944 set(obj
, MUIA_Window_DefaultObject
, tag
->ti_Data
);
2947 case MUIA_Window_Menustrip
:
2948 data
->wd_ChildMenustrip
= (Object
*) tag
->ti_Data
;
2951 case MUIA_Window_NoMenus
:
2952 data
->wd_NoMenus
= (BOOL
) tag
->ti_Data
;
2955 case MUIA_Window_RootObject
:
2958 CoerceMethod(cl
, obj
, OM_DISPOSE
);
2961 set(obj
, MUIA_Window_RootObject
, tag
->ti_Data
);
2964 case MUIA_Window_AltHeight
:
2965 data
->wd_AltDim
.Height
= (WORD
) tag
->ti_Data
;
2968 case MUIA_Window_AltWidth
:
2969 data
->wd_AltDim
.Width
= (WORD
) tag
->ti_Data
;
2972 case MUIA_Window_AltLeftEdge
:
2973 data
->wd_AltDim
.Left
= (WORD
) tag
->ti_Data
;
2976 case MUIA_Window_AltTopEdge
:
2977 data
->wd_AltDim
.Top
= (WORD
) tag
->ti_Data
;
2980 case MUIA_Window_AppWindow
:
2981 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
2985 case MUIA_Window_LeftEdge
:
2986 data
->wd_ReqX
= tag
->ti_Data
;
2989 case MUIA_Window_TopEdge
:
2990 data
->wd_ReqY
= tag
->ti_Data
;
2993 case MUIA_Window_UseBottomBorderScroller
:
2994 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
2995 MUIWF_USEBOTTOMSCROLLER
);
2998 case MUIA_Window_UseRightBorderScroller
:
2999 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
3000 MUIWF_USERIGHTSCROLLER
);
3003 case MUIA_Window_DisableKeys
:
3004 data
->wd_DisabledKeys
= tag
->ti_Data
;
3007 case MUIA_Window_RefWindow
:
3008 data
->wd_RefWindow
= (Object
*) tag
->ti_Data
;
3011 case MUIA_Window_Screen
:
3012 data
->wd_UserScreen
= (struct Screen
*)tag
->ti_Data
;
3015 case MUIA_Window_PublicScreen
:
3016 data
->wd_UserPublicScreen
= (STRPTR
) tag
->ti_Data
;
3021 /* D(bug("muimaster.library/window.c: Window Object created at " */
3022 /* "0x%lx back=%lx\n", */
3023 /* obj,data->wd_Background)); */
3028 /**************************************************************************
3030 **************************************************************************/
3031 IPTR
Window__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
3033 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3035 /* D(bug("Window_Dispose(%p)\n", obj)); */
3038 /* We no longer clear muiGlobalInfo() during disconnections, so
3039 this can cause problems (remove object which is already removed).
3040 Furthermore AFAIK it is not legal to dispose a window object
3041 which is still ocnnected to the application object, anyway. */
3043 if (muiGlobalInfo(obj
) && _app(obj
))
3045 /* D(bug(" Window_Dispose(%p) : calling app->OM_REMMEMBER\n", obj)); */
3046 DoMethod(_app(obj
), OM_REMMEMBER
, (IPTR
) obj
);
3050 if (data
->wd_RootObject
)
3051 MUI_DisposeObject(data
->wd_RootObject
);
3053 if (data
->wd_ChildMenustrip
)
3054 MUI_DisposeObject(data
->wd_ChildMenustrip
);
3056 DeletePool(data
->wd_MemoryPool
);
3058 /* D(bug(" Window_Dispose(%p) : calling supermethod\n", obj)); */
3059 return DoSuperMethodA(cl
, obj
, msg
);
3062 static ULONG
WindowOpen(struct IClass
*cl
, Object
*obj
);
3063 static ULONG
WindowClose(struct IClass
*cl
, Object
*obj
);
3065 /**************************************************************************
3067 **************************************************************************/
3068 IPTR
Window__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
3070 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3071 struct TagItem
*tags
= msg
->ops_AttrList
;
3072 struct TagItem
*tag
;
3074 while ((tag
= NextTagItem(&tags
)) != NULL
)
3076 switch (tag
->ti_Tag
)
3078 case MUIA_AppMessage
:
3079 ForwardAppMessage(data
, data
->wd_RootObject
,
3080 (struct AppMessage
*)tag
->ti_Data
);
3083 case MUIA_Window_Activate
:
3084 if (data
->wd_RenderInfo
.mri_Window
)
3086 if (tag
->ti_Data
&& !(data
->wd_Flags
& MUIWF_ACTIVE
))
3088 ActivateWindow(data
->wd_RenderInfo
.mri_Window
);
3089 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
3094 _handle_bool_tag(data
->wd_Flags
, !tag
->ti_Data
,
3095 MUIWF_DONTACTIVATE
);
3098 case MUIA_Window_ActiveObject
:
3099 /* D(bug("MUIA_Window_ActiveObject %ld (%p)\n", */
3100 /* tag->ti_Data, tag->ti_Data)); */
3101 SetActiveObject(data
, obj
, tag
->ti_Data
);
3104 case MUIA_Window_DefaultObject
:
3105 data
->wd_DefaultObject
= (APTR
) tag
->ti_Data
;
3108 case MUIA_Window_ID
:
3109 data
->wd_ID
= tag
->ti_Data
;
3112 case MUIA_Window_IsSubWindow
:
3113 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
3117 case MUIA_Window_Open
:
3120 if (data
->wd_Flags
& MUIWF_HIDDEN
)
3121 data
->wd_Flags
|= MUIWF_OPENONUNHIDE
;
3122 else if (!(data
->wd_Flags
& MUIWF_OPENED
))
3123 WindowOpen(cl
, obj
);
3126 DoMethod(obj
, MUIM_Window_ToFront
);
3127 set(obj
, MUIA_Window_Activate
, TRUE
);
3130 else if (data
->wd_Flags
& MUIWF_HIDDEN
)
3131 data
->wd_Flags
&= ~MUIWF_OPENONUNHIDE
;
3132 else if (data
->wd_Flags
& MUIWF_OPENED
)
3133 WindowClose(cl
, obj
);
3136 case MUIA_ShowMe
: /* PRIVATE *abuse* of the Area's ShowMe attr */
3141 if (data
->wd_Flags
& MUIWF_HIDDEN
)
3143 data
->wd_Flags
&= ~MUIWF_HIDDEN
;
3145 if (data
->wd_Flags
& MUIWF_OPENONUNHIDE
)
3147 data
->wd_Flags
&= ~MUIWF_OPENONUNHIDE
;
3148 set(obj
, MUIA_Window_Open
, TRUE
);
3156 if (data
->wd_Flags
& MUIWF_OPENED
)
3158 data
->wd_Flags
|= MUIWF_OPENONUNHIDE
;
3160 set(obj
, MUIA_Window_Open
, FALSE
);
3163 data
->wd_Flags
|= MUIWF_HIDDEN
;
3167 case MUIA_Window_RootObject
:
3168 ChangeRootObject(data
, obj
, (Object
*) tag
->ti_Data
);
3171 case MUIA_Window_Title
:
3172 data
->wd_Title
= (STRPTR
) tag
->ti_Data
;
3173 if (data
->wd_RenderInfo
.mri_Window
)
3174 SetWindowTitles(data
->wd_RenderInfo
.mri_Window
,
3175 data
->wd_Title
, (CONST_STRPTR
) ~ 0);
3178 case MUIA_Window_ScreenTitle
:
3179 data
->wd_ScreenTitle
= (STRPTR
) tag
->ti_Data
;
3180 if (data
->wd_RenderInfo
.mri_Window
)
3181 SetWindowTitles(data
->wd_RenderInfo
.mri_Window
,
3182 (CONST_STRPTR
) ~ 0, data
->wd_ScreenTitle
);
3185 case MUIA_Window_NoMenus
:
3186 data
->wd_NoMenus
= (BOOL
) tag
->ti_Data
;
3187 if (data
->wd_RenderInfo
.mri_Window
)
3189 if (data
->wd_NoMenus
)
3190 data
->wd_RenderInfo
.mri_Window
->Flags
|= WFLG_RMBTRAP
;
3192 data
->wd_RenderInfo
.mri_Window
->Flags
&= ~WFLG_RMBTRAP
;
3196 case MUIA_Window_UseBottomBorderScroller
:
3197 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
3198 MUIWF_USEBOTTOMSCROLLER
);
3201 case MUIA_Window_UseRightBorderScroller
:
3202 _handle_bool_tag(data
->wd_Flags
, tag
->ti_Data
,
3203 MUIWF_USERIGHTSCROLLER
);
3206 case MUIA_Window_DisableKeys
:
3207 data
->wd_DisabledKeys
= tag
->ti_Data
;
3210 case MUIA_Window_RefWindow
:
3211 data
->wd_RefWindow
= (Object
*) tag
->ti_Data
;
3214 case MUIA_Window_LeftEdge
:
3215 data
->wd_ReqX
= tag
->ti_Data
;
3218 case MUIA_Window_TopEdge
:
3219 data
->wd_ReqY
= tag
->ti_Data
;
3222 case MUIA_Window_Width
:
3223 data
->wd_ReqWidth
= (LONG
) tag
->ti_Data
;
3224 data
->wd_Width
= 0; /* otherwise windowselectdimensions()
3225 * ignores ReqWidth */
3228 case MUIA_Window_Height
:
3229 data
->wd_ReqHeight
= (LONG
) tag
->ti_Data
;
3230 data
->wd_Height
= 0;
3233 case MUIA_Window_Screen
:
3234 data
->wd_UserScreen
= (struct Screen
*)tag
->ti_Data
;
3237 case MUIA_Window_PublicScreen
:
3238 data
->wd_UserPublicScreen
= (STRPTR
) tag
->ti_Data
;
3241 case MUIA_Window_Sleep
:
3244 data
->wd_SleepCount
++;
3245 if (data
->wd_RenderInfo
.mri_Window
3246 && (data
->wd_SleepCount
== 1))
3249 (data
->wd_RenderInfo
.mri_Window
,
3250 WA_BusyPointer
, TRUE
,
3251 WA_PointerDelay
, TRUE
, TAG_DONE
);
3253 /* event handling is disabled in _zune_window_message() */
3255 data
->wd_SleepMaxHeight
=data
->wd_RenderInfo
.mri_Window
->MaxHeight
;
3256 data
->wd_SleepMinHeight
=data
->wd_RenderInfo
.mri_Window
->MinHeight
;
3257 data
->wd_SleepMaxWidth
=data
->wd_RenderInfo
.mri_Window
->MaxWidth
;
3258 data
->wd_SleepMinWidth
=data
->wd_RenderInfo
.mri_Window
->MaxWidth
;
3259 /* According to MUI autodocs, sleeping windows can't be resized.
3260 * MUI 3.8/AmigaOS also changes min/max values with WindowLimits */
3261 WindowLimits(data
->wd_RenderInfo
.mri_Window
,
3262 data
->wd_RenderInfo
.mri_Window
->Width
,
3263 data
->wd_RenderInfo
.mri_Window
->Height
,
3264 data
->wd_RenderInfo
.mri_Window
->Width
,
3265 data
->wd_RenderInfo
.mri_Window
->Height
);
3270 data
->wd_SleepCount
--;
3271 if (data
->wd_RenderInfo
.mri_Window
3272 && (data
->wd_SleepCount
== 0))
3274 SetWindowPointerA(data
->wd_RenderInfo
.mri_Window
, NULL
);
3276 /* Only restore settings, if they have been saved
3277 * during (MUIA_Window_Sleep, TRUE) call */
3278 if (data
->wd_SleepMaxHeight
> 0)
3280 WindowLimits(data
->wd_RenderInfo
.mri_Window
,
3281 data
->wd_SleepMinWidth
,
3282 data
->wd_SleepMinHeight
,
3283 data
->wd_SleepMaxWidth
,
3284 data
->wd_SleepMaxHeight
);
3285 data
->wd_SleepMinHeight
=0;
3286 data
->wd_SleepMaxHeight
=0;
3287 data
->wd_SleepMinWidth
=0;
3288 data
->wd_SleepMaxWidth
=0;
3297 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
3300 /**************************************************************************
3302 **************************************************************************/
3303 IPTR
Window__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
3305 #define STORE *(msg->opg_Storage)
3307 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3311 switch (msg
->opg_AttrID
)
3313 case MUIA_Window_Activate
:
3315 (data
->wd_Flags
& (MUIWF_ACTIVE
| MUIWF_OPENED
)) ==
3316 (MUIWF_ACTIVE
| MUIWF_OPENED
);
3319 case MUIA_Window_Window
:
3320 STORE
= (IPTR
) data
->wd_RenderInfo
.mri_Window
;
3323 case MUIA_Window_Screen
:
3324 STORE
= (IPTR
) data
->wd_RenderInfo
.mri_Screen
;
3327 case MUIA_Window_PublicScreen
:
3328 STORE
= (IPTR
) data
->wd_UserPublicScreen
;
3331 case MUIA_Window_ActiveObject
:
3332 if ((data
->wd_ActiveObject
!= NULL
)
3333 && (DoMethod(data
->wd_RootObject
, MUIM_FindAreaObject
,
3334 (IPTR
) data
->wd_ActiveObject
) != (IPTR
) NULL
))
3335 STORE
= (IPTR
) data
->wd_ActiveObject
;
3337 STORE
= (IPTR
) NULL
;
3340 case MUIA_Window_CloseRequest
:
3344 case MUIA_Window_DefaultObject
:
3345 STORE
= (IPTR
) data
->wd_DefaultObject
;
3348 case MUIA_Window_DisableKeys
:
3349 STORE
= data
->wd_DisabledKeys
;
3352 case MUIA_Window_Height
:
3353 if (data
->wd_RenderInfo
.mri_Window
!= NULL
)
3354 STORE
= (IPTR
) data
->wd_RenderInfo
.mri_Window
->GZZHeight
;
3359 case MUIA_Window_ID
:
3360 STORE
= data
->wd_ID
;
3363 case MUIA_Window_IsSubWindow
:
3364 STORE
= (data
->wd_Flags
& MUIWF_ISSUBWINDOW
) == MUIWF_ISSUBWINDOW
;
3367 case MUIA_Window_LeftEdge
:
3368 if (data
->wd_RenderInfo
.mri_Window
)
3369 STORE
= (IPTR
) data
->wd_RenderInfo
.mri_Window
->LeftEdge
;
3374 case MUIA_Window_Open
:
3375 STORE
= (data
->wd_Flags
& MUIWF_OPENED
) == MUIWF_OPENED
;
3378 case MUIA_Window_RootObject
:
3379 STORE
= (IPTR
) data
->wd_RootObject
;
3382 case MUIA_Window_ScreenTitle
:
3383 STORE
= (IPTR
) data
->wd_ScreenTitle
;
3386 case MUIA_Window_Title
:
3387 STORE
= (IPTR
) data
->wd_Title
;
3390 case MUIA_Window_TopEdge
:
3391 if (data
->wd_RenderInfo
.mri_Window
)
3392 STORE
= (IPTR
) data
->wd_RenderInfo
.mri_Window
->TopEdge
;
3397 case MUIA_Window_Width
:
3398 if (data
->wd_RenderInfo
.mri_Window
!= NULL
)
3399 STORE
= (IPTR
) data
->wd_RenderInfo
.mri_Window
->GZZWidth
;
3404 case MUIA_Window_Menustrip
:
3405 STORE
= (IPTR
) data
->wd_ChildMenustrip
;
3408 case MUIA_Window_Sleep
:
3409 STORE
= data
->wd_SleepCount
? TRUE
: FALSE
;
3420 case MUIA_Window_AltLeftEdge
:
3421 STORE
= (IPTR
) data
->wd_AltDim
.Left
;
3424 case MUIA_Window_AltTopEdge
:
3425 STORE
= (IPTR
) data
->wd_AltDim
.Top
;
3428 case MUIA_Window_AltWidth
:
3429 STORE
= (IPTR
) data
->wd_AltDim
.Width
;
3432 case MUIA_Window_AltHeight
:
3433 STORE
= (IPTR
) data
->wd_AltDim
.Height
;
3437 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
3442 * MUIM_FindUData : tests if the MUIA_UserData of the object
3443 * contains the given <udata> and returns the object pointer in this case.
3445 IPTR
Window__MUIM_FindUData(struct IClass
*cl
, Object
*obj
,
3446 struct MUIP_FindUData
*msg
)
3448 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3450 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3453 if (data
->wd_RootObject
)
3454 return DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
3461 * MUIM_GetUData : This method tests if the MUIA_UserData of the object
3462 * contains the given <udata> and gets <attr> to <storage> for itself
3465 IPTR
Window__MUIM_GetUData(struct IClass
*cl
, Object
*obj
,
3466 struct MUIP_GetUData
*msg
)
3468 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3470 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3472 get(obj
, msg
->attr
, msg
->storage
);
3476 if (data
->wd_RootObject
)
3477 return DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
3484 * MUIM_SetUData : This method tests if the MUIA_UserData of the object
3485 * contains the given <udata> and sets <attr> to <val> for itself in this case.
3487 IPTR
Window__MUIM_SetUData(struct IClass
*cl
, Object
*obj
,
3488 struct MUIP_SetUData
*msg
)
3490 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3492 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3493 set(obj
, msg
->attr
, msg
->val
);
3495 if (data
->wd_RootObject
)
3496 DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
3503 * MUIM_SetUDataOnce : This method tests if the MUIA_UserData of the object
3504 * contains the given <udata> and sets <attr> to <val> for itself in this case.
3506 IPTR
Window__MUIM_SetUDataOnce(struct IClass
*cl
, Object
*obj
,
3507 struct MUIP_SetUDataOnce
*msg
)
3509 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3511 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
3513 set(obj
, msg
->attr
, msg
->val
);
3517 if (data
->wd_RootObject
)
3518 return DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
3523 /**************************************************************************
3524 Called by Application (parent) object whenever this object is added.
3526 **************************************************************************/
3527 IPTR
Window__MUIM_ConnectParent(struct IClass
*cl
, Object
*obj
,
3528 struct MUIP_ConnectParent
*msg
)
3530 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3532 if (!DoSuperMethodA(cl
, obj
, (Msg
) msg
))
3535 if (data
->wd_RootObject
)
3536 DoMethod(data
->wd_RootObject
, MUIM_ConnectParent
, (IPTR
) obj
);
3538 if (data
->wd_ChildMenustrip
)
3539 DoMethod(data
->wd_ChildMenustrip
, MUIM_ConnectParent
, (IPTR
) obj
);
3545 /**************************************************************************
3546 called by parent object
3547 **************************************************************************/
3548 IPTR
Window__MUIM_DisconnectParent(struct IClass
*cl
, Object
*obj
,
3549 struct MUIP_DisconnectParent
*msg
)
3551 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3553 /* D(bug("Window_DisconnectParent(%p) : muiGlobalInfo=%p\n", */
3554 /* muiGlobalInfo(obj))); */
3555 if (muiGlobalInfo(obj
))
3557 /* Close the window before disconnecting all the childs */
3558 if ((data
->wd_Flags
& MUIWF_OPENED
))
3560 /* D(bug(" Window_DisconnectParent(%p) : closing window\n", */
3561 /* muiGlobalInfo(obj))); */
3562 set(obj
, MUIA_Window_Open
, FALSE
);
3564 if (data
->wd_ChildMenustrip
)
3565 DoMethod(data
->wd_ChildMenustrip
, MUIM_DisconnectParent
,
3568 if (data
->wd_RootObject
)
3569 DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
3571 /* D(bug(" Window_DisconnectParent(%p) : calling supermethod\n", */
3572 /* muiGlobalInfo(obj))); */
3573 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
3581 static void SetRootObjInnerSpacing(Object
*obj
,
3582 struct MUI_WindowData
*data
)
3584 UWORD wd_innerLeft
, wd_innerRight
, wd_innerTop
, wd_innerBottom
;
3586 if (data
->wd_CrtFlags
& WFLG_BORDERLESS
)
3595 wd_innerLeft
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_left
;
3596 wd_innerRight
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_right
;
3597 wd_innerTop
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_top
;
3598 wd_innerBottom
= muiGlobalInfo(obj
)->mgi_Prefs
->window_inner_bottom
;
3601 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERLEFT
))
3603 muiAreaData(data
->wd_RootObject
)->mad_InnerLeft
= wd_innerLeft
;
3606 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERTOP
))
3608 muiAreaData(data
->wd_RootObject
)->mad_InnerTop
= wd_innerTop
;
3611 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERRIGHT
))
3613 muiAreaData(data
->wd_RootObject
)->mad_InnerRight
= wd_innerRight
;
3616 if (!(muiAreaData(data
->wd_RootObject
)->mad_Flags
& MADF_INNERBOTTOM
))
3618 muiAreaData(data
->wd_RootObject
)->mad_InnerBottom
= wd_innerBottom
;
3623 * Called before window is opened or resized. It determines its bounds,
3624 * so you can call WindowSelectDimensions() to find the final dims.
3626 static void WindowMinMax(Object
*obj
, struct MUI_WindowData
*data
)
3628 SetRootObjInnerSpacing(obj
, data
);
3629 /* inquire about sizes */
3630 DoMethod(data
->wd_RootObject
, MUIM_AskMinMax
, (IPTR
) & data
->wd_MinMax
);
3631 /* D(bug("*** root minmax = %ld,%ld => %ld,%ld\n", */
3632 /* data->wd_MinMax.MinWidth, */
3633 /* data->wd_MinMax.MinHeight, */
3634 /* data->wd_MinMax.MaxWidth, data->wd_MinMax.MaxHeight)); */
3635 __area_finish_minmax(data
->wd_RootObject
, &data
->wd_MinMax
);
3636 /* D(bug("*** root minmax2 = %ld,%ld => %ld,%ld\n", */
3637 /* data->wd_MinMax.MinWidth, */
3638 /* data->wd_MinMax.MinHeight, */
3639 /* data->wd_MinMax.MaxWidth, data->wd_MinMax.MaxHeight)); */
3643 static void InstallBackbuffer(struct IClass
*cl
, Object
*obj
)
3645 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3647 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
3649 data
->wd_RenderInfo
.mri_BufferBM
=
3650 AllocBitMap(win
->Width
, win
->Height
, win
->RPort
->BitMap
->Depth
,
3651 0, win
->RPort
->BitMap
);
3653 if (data
->wd_RenderInfo
.mri_BufferBM
)
3655 /* D(bug("install_backbuffer : allocated bitmap %dx%dx%d " */
3656 /* "with friend %p\n", */
3657 /* win->Width, win->Height, win->RPort->BitMap->Depth, */
3658 /* win->RPort->BitMap)); */
3659 InitRastPort(&data
->wd_RenderInfo
.mri_BufferRP
);
3660 data
->wd_RenderInfo
.mri_BufferRP
.BitMap
=
3661 data
->wd_RenderInfo
.mri_BufferBM
;
3665 static void DeinstallBackbuffer(struct IClass
*cl
, Object
*obj
)
3667 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3669 if (data
->wd_RenderInfo
.mri_BufferBM
)
3671 DeinitRastPort(&data
->wd_RenderInfo
.mri_BufferRP
);
3672 FreeBitMap(data
->wd_RenderInfo
.mri_BufferBM
);
3673 data
->wd_RenderInfo
.mri_BufferBM
= NULL
;
3678 * Called after window is opened or resized.
3679 * An expose event is already queued, it will trigger
3680 * MUIM_Draw for us when going back to main loop.
3682 static void WindowShow(struct IClass
*cl
, Object
*obj
)
3684 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3685 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
3686 /* D(bug("WindowShow %s %d\n", __FILE__, __LINE__)); */
3688 _left(data
->wd_RootObject
) = win
->BorderLeft
;
3689 _top(data
->wd_RootObject
) = win
->BorderTop
;
3690 _width(data
->wd_RootObject
) = data
->wd_Width
;
3691 _height(data
->wd_RootObject
) = data
->wd_Height
;
3693 DoMethod(data
->wd_RootObject
, MUIM_Layout
);
3695 ShowRenderInfo(&data
->wd_RenderInfo
);
3696 /* D(bug("zune_imspec_show %s %d\n", __FILE__, __LINE__)); */
3697 zune_imspec_show(data
->wd_Background
, obj
);
3698 DoShowMethod(data
->wd_RootObject
);
3701 static ULONG
WindowOpen(struct IClass
*cl
, Object
*obj
)
3703 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3705 if (!data
->wd_RootObject
)
3708 if (!DoMethod(obj
, MUIM_Window_Setup
))
3711 /* I got display info, so calculate your display dependant data */
3712 if (!DoSetupMethod(data
->wd_RootObject
, &data
->wd_RenderInfo
))
3714 DoMethod(obj
, MUIM_Window_Cleanup
);
3718 /* inquire about sizes */
3719 WindowMinMax(obj
, data
);
3720 WindowSelectDimensions(data
);
3722 /* Decide which menustrip should be used */
3723 if (!data
->wd_ChildMenustrip
)
3724 get(_app(obj
), MUIA_Application_Menustrip
, &data
->wd_Menustrip
);
3726 data
->wd_Menustrip
= data
->wd_ChildMenustrip
;
3728 /* open window here ... */
3729 if (!DisplayWindow(obj
, data
))
3731 /* free display dependant data */
3732 data
->wd_Menustrip
= NULL
;
3733 DoMethod(data
->wd_RootObject
, MUIM_Cleanup
);
3734 DoMethod(obj
, MUIM_Window_Cleanup
);
3738 InstallBackbuffer(cl
, obj
);
3740 data
->wd_Flags
|= MUIWF_OPENED
;
3742 WindowShow(cl
, obj
);
3745 LONG left
, top
, width
, height
;
3747 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
3748 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
,
3749 width
= data
->wd_RenderInfo
.mri_Window
->Width
3750 - data
->wd_RenderInfo
.mri_Window
->BorderRight
- left
;
3751 height
= data
->wd_RenderInfo
.mri_Window
->Height
3752 - data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
3754 /* D(bug("zune_imspec_draw %s %d\n", __FILE__, __LINE__)); */
3755 // D(bug("%d:zune_imspec_draw(%p) l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
3756 // __LINE__, data->wd_Background, left, top, width,
3757 // height, left, top));
3759 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
3760 left
, top
, width
, height
, left
, top
, 0);
3763 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWOBJECT
);
3765 D(bug("MUIC_Window:windowOpen() ActiveObject=%p\n",
3766 data
->wd_ActiveObject
));
3767 if (data
->wd_OldActive
!= NULL
)
3769 set(obj
, MUIA_Window_ActiveObject
, data
->wd_OldActive
);
3775 /**************************************************************************/
3776 /**************************************************************************/
3778 static ULONG
WindowClose(struct IClass
*cl
, Object
*obj
)
3780 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3782 if (data
->wd_ActiveObject
!= NULL
)
3784 data
->wd_OldActive
= data
->wd_ActiveObject
;
3785 set(obj
, MUIA_Window_ActiveObject
, MUIV_Window_ActiveObject_None
);
3788 KillHelpBubble(data
, obj
, BUBBLEHELP_TICKER_FIRST
);
3790 /* remove from window */
3791 DoHideMethod(data
->wd_RootObject
);
3792 zune_imspec_hide(data
->wd_Background
);
3794 DeinstallBackbuffer(cl
, obj
);
3796 HideRenderInfo(&data
->wd_RenderInfo
);
3798 /* close here ... */
3799 UndisplayWindow(obj
, data
);
3801 data
->wd_Flags
&= ~MUIWF_OPENED
;
3802 data
->wd_Menustrip
= NULL
;
3804 /* free display dependant data */
3805 DoMethod(data
->wd_RootObject
, MUIM_Cleanup
);
3806 DoMethod(obj
, MUIM_Window_Cleanup
);
3810 /* calculate a new layout
3812 * see Group_ExitChange
3816 IPTR
Window__MUIM_RecalcDisplay(struct IClass
*cl
, Object
*obj
,
3817 struct MUIP_Window_RecalcDisplay
*msg
)
3819 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3820 LONG left
, top
, width
, height
;
3821 BOOL resized
, reshow
= FALSE
;
3822 Object
*current_obj
;
3824 if (!(data
->wd_Flags
& MUIWF_OPENED
))
3827 current_obj
= msg
->originator
;
3829 // typically originator is a group which has been added/removed a child
3830 // calculate minmax of current obj
3831 // if new minmax can accomodate current obj size, stop
3832 // else try with its parent
3833 // the resulting object will get a new layout
3834 // it currently produces some redundant AskMinMax but allows
3835 // to not always relayout the whole window
3837 D(bug("RecalcDisplay on %p\n", current_obj
));
3838 while (current_obj
!= NULL
)
3840 DoMethod(current_obj
, MUIM_AskMinMax
,
3841 (IPTR
) & muiAreaData(current_obj
)->mad_MinMax
);
3842 __area_finish_minmax(current_obj
,
3843 &muiAreaData(current_obj
)->mad_MinMax
);
3845 D(bug("size w = %d, h = %d\n", _width(current_obj
),
3846 _height(current_obj
)));
3847 D(bug("new w = %d-%d, h = %d-%d\n", _minwidth(current_obj
),
3848 _maxwidth(current_obj
), _minheight(current_obj
),
3849 _maxheight(current_obj
)));
3851 if (!_between(_minwidth(current_obj
), _width(current_obj
),
3852 _maxwidth(current_obj
))
3853 || !_between(_minheight(current_obj
), _height(current_obj
),
3854 _maxheight(current_obj
)))
3856 current_obj
= _parent(current_obj
);
3857 D(bug("RecalcDisplay, try parent %p\n", current_obj
));
3861 D(bug("found it\n"));
3867 current_obj
= data
->wd_RootObject
;
3869 WindowMinMax(obj
, data
);
3871 /* Important: current_obj could be hidden, like in an inactive page! */
3872 if (_flags(current_obj
) & MADF_CANDRAW
)
3878 DoHideMethod(current_obj
);
3880 /* resize window ? */
3881 WindowSelectDimensions(data
);
3882 resized
= WindowResize(data
);
3886 /* FIXME: Should we short circuit the following
3887 * if the window size didn't change?
3892 struct Window
*win
= data
->wd_RenderInfo
.mri_Window
;
3893 _left(data
->wd_RootObject
) = win
->BorderLeft
;
3894 _top(data
->wd_RootObject
) = win
->BorderTop
;
3895 _width(data
->wd_RootObject
) = data
->wd_Width
;
3896 _height(data
->wd_RootObject
) = data
->wd_Height
;
3898 DoMethod(current_obj
, MUIM_Layout
);
3901 DoShowMethod(current_obj
);
3903 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_redraw
==
3904 WINDOW_REDRAW_WITHOUT_CLEAR
)
3907 MUI_Redraw(current_obj
, MADF_DRAWOBJECT
);
3911 left
= data
->wd_RenderInfo
.mri_Window
->BorderLeft
;
3912 top
= data
->wd_RenderInfo
.mri_Window
->BorderTop
;
3913 width
= data
->wd_RenderInfo
.mri_Window
->Width
3914 - data
->wd_RenderInfo
.mri_Window
->BorderRight
- left
;
3915 height
= data
->wd_RenderInfo
.mri_Window
->Height
3916 - data
->wd_RenderInfo
.mri_Window
->BorderBottom
- top
;
3918 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
3919 left
, top
, width
, height
, left
, top
, 0);
3920 MUI_Redraw(data
->wd_RootObject
, MADF_DRAWALL
);
3923 ActivateObject(data
);
3929 /**************************************************************************
3930 MUIM_AddEventHandler
3931 **************************************************************************/
3932 IPTR
Window__MUIM_AddEventHandler(struct IClass
*cl
, Object
*obj
,
3933 struct MUIP_Window_AddEventHandler
*msg
)
3935 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3937 //D(bug("muimaster.library/window.c: Add Eventhandler %p\n", msg->ehnode));
3939 msg
->ehnode
->ehn_Priority
= msg
->ehnode
->ehn_Priority
;
3940 EnqueueByPriAndAddress((struct List
*)&data
->wd_EHList
,
3941 (struct Node
*)msg
->ehnode
);
3942 ChangeEvents(data
, GetDefaultEvents());
3946 /**************************************************************************
3947 MUIM_RemEventHandler
3948 **************************************************************************/
3949 IPTR
Window__MUIM_RemEventHandler(struct IClass
*cl
, Object
*obj
,
3950 struct MUIP_Window_RemEventHandler
*msg
)
3952 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3954 //D(bug("muimaster.library/window.c: Rem Eventhandler %p\n", msg->ehnode));
3956 Remove((struct Node
*)msg
->ehnode
);
3957 ChangeEvents(data
, GetDefaultEvents());
3961 /**************************************************************************
3962 Note that this is MUIM_Window_Setup, not MUIM_Setup
3963 **************************************************************************/
3964 IPTR
Window__MUIM_Setup(struct IClass
*cl
, Object
*obj
, Msg msg
)
3966 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3968 if (!SetupRenderInfo(obj
, data
, &data
->wd_RenderInfo
))
3971 data
->wd_Background
=
3972 zune_imspec_setup(MUII_WindowBack
, &data
->wd_RenderInfo
);
3974 if (muiGlobalInfo(obj
)->mgi_Prefs
->window_redraw
==
3975 WINDOW_REDRAW_WITH_CLEAR
)
3976 data
->wd_Flags
|= MUIWF_ERASEAREA
;
3981 /**************************************************************************
3983 **************************************************************************/
3984 IPTR
Window__MUIM_Cleanup(struct IClass
*cl
, Object
*obj
, Msg msg
)
3986 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
3988 zune_imspec_cleanup(data
->wd_Background
);
3992 DeleteDragNDrop(data
->wd_dnd
);
3993 data
->wd_dnd
= NULL
;
3996 CleanupRenderInfo(obj
, data
, &data
->wd_RenderInfo
);
4001 /**************************************************************************
4002 This adds the the control char handler and also does the MUIA_CycleChain
4003 stuff. Orginal MUI does this another way.
4004 **************************************************************************/
4005 IPTR
Window__MUIM_AddControlCharHandler(struct IClass
*cl
, Object
*obj
,
4006 struct MUIP_Window_AddControlCharHandler
*msg
)
4008 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4009 struct ObjNode
*node
;
4011 if (msg
->ccnode
->ehn_Events
)
4013 msg
->ccnode
->ehn_Priority
= msg
->ccnode
->ehn_Priority
;
4014 Enqueue((struct List
*)&data
->wd_CCList
,
4015 (struct Node
*)msg
->ccnode
);
4017 /* Due to the lack of a better idea ... */
4018 if (muiAreaData(msg
->ccnode
->ehn_Object
)->mad_Flags
& MADF_CYCLECHAIN
)
4020 node
= AllocPooled(data
->wd_MemoryPool
, sizeof(struct ObjNode
));
4023 node
->obj
= msg
->ccnode
->ehn_Object
;
4024 AddTail((struct List
*)&data
->wd_CycleChain
,
4025 (struct Node
*)node
);
4031 /**************************************************************************
4032 MUIM_RemControlCharHandler
4033 **************************************************************************/
4034 IPTR
Window__MUIM_RemControlCharHandler(struct IClass
*cl
, Object
*obj
,
4035 struct MUIP_Window_RemControlCharHandler
*msg
)
4037 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4038 struct ObjNode
*node
=
4039 FindObjNode(&data
->wd_CycleChain
, msg
->ccnode
->ehn_Object
);
4041 if (msg
->ccnode
->ehn_Events
)
4042 Remove((struct Node
*)msg
->ccnode
);
4046 /* Remove from the chain list */
4047 Remove((struct Node
*)node
);
4048 FreePooled(data
->wd_MemoryPool
, node
, sizeof(struct ObjNode
));
4054 /**************************************************************************
4056 **************************************************************************/
4057 IPTR
Window__MUIM_DragObject(struct IClass
*cl
, Object
*obj
,
4058 struct MUIP_Window_DragObject
*msg
)
4060 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4063 struct DragNDrop
*dnd
;
4064 struct MUI_DragImage
*di
;
4065 struct BitMapNode
*bmn
;
4067 if (!(dnd
= CreateDragNDropA(NULL
)))
4071 (struct MUI_DragImage
*)DoMethod(msg
->obj
,
4072 MUIM_CreateDragImage
, -msg
->touchx
, -msg
->touchy
,
4075 DeleteDragNDrop(dnd
);
4080 DoMethod(msg
->obj
, MUIM_DeleteDragImage
, (IPTR
) di
);
4081 DeleteDragNDrop(dnd
);
4085 if (!(bmn
= CreateBitMapNodeA(TAGLIST(
4086 GUI_BitMap
, (IPTR
)di
->bm
,
4087 GUI_LeftOffset
, di
->touchx
,
4088 GUI_TopOffset
, di
->touchy
,
4089 GUI_Width
, di
->width
,
4090 GUI_Height
, di
->height
,
4091 GUI_SourceAlpha
, !!(di
->flags
& MUIF_DRAGIMAGE_SOURCEALPHA
)))))
4093 DoMethod(msg
->obj
, MUIM_DeleteDragImage
, (IPTR
) di
);
4094 DeleteDragNDrop(dnd
);
4098 AttachBitMapNode(dnd
, bmn
);
4100 if (!PrepareDragNDrop(dnd
, data
->wd_RenderInfo
.mri_Screen
))
4102 DoMethod(msg
->obj
, MUIM_DeleteDragImage
, (IPTR
) di
);
4103 DeleteDragNDrop(dnd
);
4107 muiAreaData(msg
->obj
)->mad_Flags
|= MADF_DRAGGING
;
4109 data
->wd_DragObject
= msg
->obj
;
4111 data
->wd_DragImage
= di
;
4117 /**************************************************************************
4119 **************************************************************************/
4120 IPTR
Window__MUIM_AllocGadgetID(struct IClass
*cl
, Object
*obj
,
4121 struct MUIP_Window_AllocGadgetID
*msg
)
4123 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4124 struct IDNode
*newnode
;
4126 newnode
= AllocPooled(data
->wd_MemoryPool
, sizeof(struct IDNode
));
4132 if (IsListEmpty(&data
->wd_IDList
))
4135 AddHead((struct List
*)&data
->wd_IDList
,
4136 (struct Node
*)&newnode
->node
);
4142 for (mn
= data
->wd_IDList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
4144 struct IDNode
*idn
= (struct IDNode
*)mn
;
4150 Insert((struct List
*)&data
->wd_IDList
,
4151 (struct Node
*)&newnode
->node
, (struct Node
*)mn
);
4158 /**************************************************************************
4160 **************************************************************************/
4161 IPTR
Window__MUIM_FreeGadgetID(struct IClass
*cl
, Object
*obj
,
4162 struct MUIP_Window_FreeGadgetID
*msg
)
4164 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4167 for (mn
= data
->wd_IDList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
4169 struct IDNode
*idn
= (struct IDNode
*)mn
;
4170 if (msg
->gadgetid
== idn
->id
)
4172 Remove((struct Node
*)idn
);
4173 FreePooled(data
->wd_MemoryPool
, idn
, sizeof(struct IDNode
));
4182 /**************************************************************************
4183 MUIM_Window_GetMenuCheck
4184 **************************************************************************/
4185 IPTR
Window__MUIM_GetMenuCheck(struct IClass
*cl
, Object
*obj
,
4186 struct MUIP_Window_GetMenuCheck
*msg
)
4189 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4191 Object
*strip
= data
->wd_ChildMenustrip
;
4193 strip
= data
->wd_Menustrip
;
4196 if (!(item
= (Object
*) DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
)))
4198 get(item
, MUIA_Menuitem_Checked
, &stat
);
4202 /**************************************************************************
4203 MUIM_Window_SetMenuCheck
4204 **************************************************************************/
4205 IPTR
Window__MUIM_SetMenuCheck(struct IClass
*cl
, Object
*obj
,
4206 struct MUIP_Window_SetMenuCheck
*msg
)
4208 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4210 Object
*strip
= data
->wd_ChildMenustrip
;
4212 strip
= data
->wd_Menustrip
;
4215 if (!(item
= (Object
*) DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
)))
4217 set(item
, MUIA_Menuitem_Checked
, msg
->stat
);
4221 /**************************************************************************
4222 MUIM_Window_GetMenuState
4223 **************************************************************************/
4224 IPTR
Window__MUIM_GetMenuState(struct IClass
*cl
, Object
*obj
,
4225 struct MUIP_Window_GetMenuState
*msg
)
4228 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4230 Object
*strip
= data
->wd_ChildMenustrip
;
4232 strip
= data
->wd_Menustrip
;
4235 if (!(item
= (Object
*) DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
)))
4237 get(item
, MUIA_Menuitem_Enabled
, &stat
);
4241 /**************************************************************************
4242 MUIM_Window_SetMenuState
4243 **************************************************************************/
4244 IPTR
Window__MUIM_SetMenuState(struct IClass
*cl
, Object
*obj
,
4245 struct MUIP_Window_SetMenuState
*msg
)
4247 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4249 Object
*strip
= data
->wd_ChildMenustrip
;
4251 strip
= data
->wd_Menustrip
;
4254 if (!(item
= (Object
*) DoMethod(strip
, MUIM_FindUData
, msg
->MenuID
)))
4256 set(item
, MUIA_Menuitem_Enabled
, msg
->stat
);
4260 /**************************************************************************
4261 MUIM_Window_DrawBackground
4262 **************************************************************************/
4263 IPTR
Window__MUIM_DrawBackground(struct IClass
*cl
, Object
*obj
,
4264 struct MUIP_Window_DrawBackground
*msg
)
4266 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4267 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
4270 // D(bug("%d:zune_imspec_draw(%p) l=%d t=%d w=%d h=%d xo=%d yo=%d\n",
4271 // __LINE__, data->wd_Background, msg->left, msg->top, msg->width,
4272 // msg->height, msg->xoffset, msg->yoffset));
4273 zune_imspec_draw(data
->wd_Background
, &data
->wd_RenderInfo
,
4274 msg
->left
, msg
->top
, msg
->width
, msg
->height
,
4275 msg
->xoffset
, msg
->yoffset
, 0);
4279 /**************************************************************************
4281 **************************************************************************/
4282 IPTR
Window__MUIM_ToFront(struct IClass
*cl
, Object
*obj
, Msg msg
)
4284 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4285 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
4288 WindowToFront(data
->wd_RenderInfo
.mri_Window
);
4292 /**************************************************************************
4294 **************************************************************************/
4295 IPTR
Window__MUIM_ToBack(struct IClass
*cl
, Object
*obj
, Msg msg
)
4297 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4298 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
4301 WindowToBack(data
->wd_RenderInfo
.mri_Window
);
4305 /**************************************************************************
4306 MUIM_Window_ScreenToBack
4307 **************************************************************************/
4308 IPTR
Window__MUIM_ScreenToBack(struct IClass
*cl
, Object
*obj
, Msg msg
)
4310 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4311 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
4314 ScreenToBack(data
->wd_RenderInfo
.mri_Screen
);
4318 /**************************************************************************
4319 MUIM_Window_ScreenToFront
4320 **************************************************************************/
4321 IPTR
Window__MUIM_ScreenToFront(struct IClass
*cl
, Object
*obj
, Msg msg
)
4323 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4324 if (!(data
->wd_RenderInfo
.mri_Window
)) /* not between show/hide */
4327 ScreenToFront(data
->wd_RenderInfo
.mri_Screen
);
4331 /**************************************************************************
4332 MUIM_Window_ActionIconify
4333 **************************************************************************/
4334 IPTR
Window__MUIM_ActionIconify(struct IClass
*cl
, Object
*obj
, Msg msg
)
4336 set(_app(obj
), MUIA_Application_Iconified
, TRUE
);
4342 /* Loads ENV: prefs, add a Window_ID chunk in the MUIW chunk, if no MUIW chunk
4343 * then create it at the same level as MUIC chunk, save prefs.
4344 * Do the same for ENVARC:
4345 * MUIW chunk layout:
4347 * 00 00 00 30 (chunk length for a single window, 0x30L big endian)
4350 * xx xx yy yy (X, Y)
4351 * ww ww hh hh (Width, Height)
4352 * ax ax ay ay (AltX, AltY)
4353 * aw aw ah ah (AltWidth, AltHeight)
4361 static void RememberWindowPosition(Object
*winobj
, ULONG id
)
4367 /* Loads ENV: prefs, remove our Window_ID chunk from the MUIW chunk,
4369 * Do the same for ENVARC:
4370 * This function shouldn't really be in window.c, but rather in a file dealing
4371 * with prefs file stuff.
4373 static void ForgetWindowPosition(Object
*winobj
, ULONG id
)
4379 /**************************************************************************
4380 MUIM_Window_Snapshot
4381 **************************************************************************/
4382 IPTR
Window__MUIM_Snapshot(struct IClass
*cl
, Object
*obj
,
4383 struct MUIP_Window_Snapshot
*msg
)
4385 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4386 struct windowpos winp
;
4389 winp
.id
= data
->wd_ID
;
4390 w
= data
->wd_RenderInfo
.mri_Window
;
4393 winp
.x1
= w
->LeftEdge
;
4394 winp
.y1
= w
->TopEdge
;
4395 winp
.w1
= w
->GZZWidth
;
4396 winp
.h1
= w
->GZZHeight
;
4400 winp
.h2
= 0; //to do save alt dims
4402 set(_app(obj
), MUIA_Application_SetWinPos
, &winp
);
4406 RememberWindowPosition(obj
, data
->wd_ID
);
4408 ForgetWindowPosition(obj
, data
->wd_ID
);
4412 /**************************************************************************
4413 MUIM_Window_UpdateMenu
4414 **************************************************************************/
4415 IPTR
Window__MUIM_UpdateMenu(struct IClass
*cl
, Object
*obj
, Msg msg
)
4417 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4419 struct Menu
*menu
= NULL
;
4420 struct NewMenu
*newmenu
= NULL
;
4421 APTR visinfo
= NULL
;
4422 struct Window
*win
= NULL
;
4424 if (data
->wd_Menustrip
) // only open windows can have a menustrip
4427 GetVisualInfoA(data
->wd_RenderInfo
.mri_Screen
, NULL
)))
4429 win
= data
->wd_RenderInfo
.mri_Window
;
4430 ClearMenuStrip(win
);
4433 FreeMenus(data
->wd_Menu
);
4434 data
->wd_Menu
= NULL
;
4437 get(data
->wd_Menustrip
, MUIA_Menuitem_NewMenu
, &newmenu
);
4440 if ((menu
= CreateMenusA(newmenu
, NULL
)))
4442 struct TagItem tags
[] = {
4443 {GTMN_NewLookMenus
, TRUE
},
4446 LayoutMenusA(menu
, visinfo
, tags
);
4447 data
->wd_Menu
= menu
;
4448 SetMenuStrip(win
, menu
);
4451 FreeVisualInfo(visinfo
);
4458 /**************************************************************************
4460 **************************************************************************/
4461 IPTR
Window__MUIM_Refresh(struct IClass
*cl
, Object
*obj
, Msg msg
)
4463 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4465 RefreshWindow(obj
, data
);
4470 /**************************************************************************
4471 MUIM_Export : to export an object's "contents" to a dataspace object.
4472 **************************************************************************/
4473 static IPTR
Window__MUIM_Export(struct IClass
*cl
, Object
*obj
,
4474 struct MUIP_Export
*msg
)
4476 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4477 DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
4482 /**************************************************************************
4483 MUIM_Import : to import an object's "contents" from a dataspace object.
4484 **************************************************************************/
4485 static IPTR
Window__MUIM_Import(struct IClass
*cl
, Object
*obj
,
4486 struct MUIP_Import
*msg
)
4488 struct MUI_WindowData
*data
= INST_DATA(cl
, obj
);
4489 DoMethodA(data
->wd_RootObject
, (Msg
) msg
);
4493 BOOPSI_DISPATCHER(IPTR
, Window_Dispatcher
, cl
, obj
, msg
)
4495 switch (msg
->MethodID
)
4498 return Window__OM_NEW(cl
, obj
, (struct opSet
*)msg
);
4500 return Window__OM_DISPOSE(cl
, obj
, msg
);
4502 return Window__OM_SET(cl
, obj
, (struct opSet
*)msg
);
4504 return Window__OM_GET(cl
, obj
, (struct opGet
*)msg
);
4505 case MUIM_FindUData
:
4506 return Window__MUIM_FindUData(cl
, obj
,
4507 (struct MUIP_FindUData
*)msg
);
4509 return Window__MUIM_GetUData(cl
, obj
, (struct MUIP_GetUData
*)msg
);
4511 return Window__MUIM_SetUData(cl
, obj
, (struct MUIP_SetUData
*)msg
);
4512 case MUIM_SetUDataOnce
:
4513 return Window__MUIM_SetUDataOnce(cl
, obj
,
4514 (struct MUIP_SetUDataOnce
*)msg
);
4515 case MUIM_Window_AddEventHandler
:
4516 return Window__MUIM_AddEventHandler(cl
, obj
, (APTR
) msg
);
4517 case MUIM_Window_RemEventHandler
:
4518 return Window__MUIM_RemEventHandler(cl
, obj
, (APTR
) msg
);
4519 case MUIM_ConnectParent
:
4520 return Window__MUIM_ConnectParent(cl
, obj
, (APTR
) msg
);
4521 case MUIM_DisconnectParent
:
4522 return Window__MUIM_DisconnectParent(cl
, obj
, (APTR
) msg
);
4523 case MUIM_Window_RecalcDisplay
:
4524 return Window__MUIM_RecalcDisplay(cl
, obj
, (APTR
) msg
);
4525 case MUIM_Window_Setup
:
4526 return Window__MUIM_Setup(cl
, obj
, (APTR
) msg
);
4527 case MUIM_Window_Cleanup
:
4528 return Window__MUIM_Cleanup(cl
, obj
, (APTR
) msg
);
4529 case MUIM_Window_AddControlCharHandler
:
4530 return Window__MUIM_AddControlCharHandler(cl
, obj
, (APTR
) msg
);
4531 case MUIM_Window_RemControlCharHandler
:
4532 return Window__MUIM_RemControlCharHandler(cl
, obj
, (APTR
) msg
);
4533 case MUIM_Window_DragObject
:
4534 return Window__MUIM_DragObject(cl
, obj
, (APTR
) msg
);
4535 case MUIM_Window_AllocGadgetID
:
4536 return Window__MUIM_AllocGadgetID(cl
, obj
, (APTR
) msg
);
4537 case MUIM_Window_FreeGadgetID
:
4538 return Window__MUIM_FreeGadgetID(cl
, obj
, (APTR
) msg
);
4539 case MUIM_Window_GetMenuCheck
:
4540 return Window__MUIM_GetMenuCheck(cl
, obj
, (APTR
) msg
);
4541 case MUIM_Window_SetMenuCheck
:
4542 return Window__MUIM_SetMenuCheck(cl
, obj
, (APTR
) msg
);
4543 case MUIM_Window_GetMenuState
:
4544 return Window__MUIM_GetMenuState(cl
, obj
, (APTR
) msg
);
4545 case MUIM_Window_SetMenuState
:
4546 return Window__MUIM_SetMenuState(cl
, obj
, (APTR
) msg
);
4547 case MUIM_Window_DrawBackground
:
4548 return Window__MUIM_DrawBackground(cl
, obj
, (APTR
) msg
);
4549 case MUIM_Window_ToFront
:
4550 return Window__MUIM_ToFront(cl
, obj
, (APTR
) msg
);
4551 case MUIM_Window_ToBack
:
4552 return Window__MUIM_ToBack(cl
, obj
, (APTR
) msg
);
4553 case MUIM_Window_ScreenToFront
:
4554 return Window__MUIM_ScreenToFront(cl
, obj
, (APTR
) msg
);
4555 case MUIM_Window_ScreenToBack
:
4556 return Window__MUIM_ScreenToBack(cl
, obj
, (APTR
) msg
);
4557 case MUIM_Window_ActionIconify
:
4558 return Window__MUIM_ActionIconify(cl
, obj
, (APTR
) msg
);
4559 case MUIM_Window_Snapshot
:
4560 return Window__MUIM_Snapshot(cl
, obj
, (APTR
) msg
);
4561 case MUIM_Window_UpdateMenu
:
4562 return Window__MUIM_UpdateMenu(cl
, obj
, (APTR
) msg
);
4563 case MUIM_Window_Refresh
:
4564 return Window__MUIM_Refresh(cl
, obj
, (APTR
) msg
);
4566 return Window__MUIM_Export(cl
, obj
, (APTR
) msg
);
4568 return Window__MUIM_Import(cl
, obj
, (APTR
) msg
);
4571 return DoSuperMethodA(cl
, obj
, msg
);
4573 BOOPSI_DISPATCHER_END
4578 const struct __MUIBuiltinClass _MUI_Window_desc
=
4582 sizeof(struct MUI_WindowData
),
4583 (void *) Window_Dispatcher