2 Copyright 1999, David Le Corfec.
3 Copyright 2002-2012, The AROS Development Team.
9 #include <exec/types.h>
10 #include <devices/timer.h>
11 #include <dos/dostags.h>
12 #include <dos/datetime.h>
13 #include <utility/date.h>
14 #include <prefs/prefhdr.h>
20 #include <clib/alib_protos.h>
21 #include <libraries/commodities.h>
22 #include <rexx/errors.h>
23 #include <rexx/storage.h>
24 #include <rexx/rxslib.h>
25 #include <proto/alib.h>
26 #include <proto/exec.h>
27 #include <proto/dos.h>
28 #include <proto/intuition.h>
29 #include <proto/utility.h>
30 #include <proto/commodities.h>
31 #include <proto/muimaster.h>
32 #include <proto/iffparse.h>
33 #include <proto/rexxsyslib.h>
34 #include <proto/workbench.h>
35 #include <proto/icon.h>
41 #include "muimaster_intern.h"
47 extern struct Library
*MUIMasterBase
;
52 struct MinNode tn_Node
;
53 Object
*tn_Application
;
56 struct MUI_ApplicationData
58 struct MUI_GlobalInfo app_GlobalInfo
;
59 APTR app_WindowFamily
; /* delegates window list */
60 struct MinList app_IHList
;
61 struct MinList app_MethodQueue
;
62 struct SignalSemaphore app_MethodSemaphore
;
63 struct MinList app_ReturnIDQueue
;
64 struct Hook
*app_BrokerHook
;
65 struct MsgPort
*app_BrokerPort
;
66 struct MsgPort
*app_TimerPort
;
67 struct timerequest
*app_TimerReq
;
68 struct Task
*app_Task
;
70 Object
*app_Menustrip
;
76 STRPTR app_Description
;
80 BOOL app_VersionAllocated
;
81 STRPTR app_Version_Number
;
82 STRPTR app_Version_Date
;
83 STRPTR app_Version_Extra
;
84 WORD app_SleepCount
; // attribute nests
85 ULONG app_TimerOutstanding
;
86 ULONG app_MenuAction
; /* Remember last action */
92 struct TrackingNode app_TrackingNode
;
93 BOOL app_is_TNode_in_list
;
95 LONG winposused
; //dont add other vars before windowpos all is save together
96 struct windowpos winpos
[MAXWINS
];
97 struct MsgPort
*app_RexxPort
;
98 struct RexxMsg
*app_RexxMsg
;
99 struct Hook
*app_RexxHook
;
100 struct MUI_Command
*app_Commands
;
101 STRPTR app_RexxString
;
103 struct MsgPort
*app_AppPort
; /* Port for handling AppIcon / AppMenu */
104 struct AppIcon
*app_AppIcon
;
105 struct DiskObject
*app_DiskObject
; /* This is only pointer to client-managed object */
106 struct DiskObject
*app_DefaultDiskObject
; /* This is complete object managed by the class */
109 struct timerequest_ext
111 struct timerequest treq
;
112 struct MUI_InputHandlerNode
*ihn
;
116 * Application class is the master class for all
117 * MUI applications. It serves as a kind of anchor
118 * for all input, either coming from the user or
119 * somewhere from the system, e.g. commodities
120 * or ARexx messages. (hemm forget theses last 2 for Zune :)
122 * An application can have any number of sub windows,
123 * these windows are the children of the application.
124 * (FYI, it delegates child handling to a Family object).
128 MUIA_Application_Active [ISG] done
129 MUIA_Application_Author [I.G] done
130 MUIA_Application_Base [I.G] done
131 MUIA_Application_Broker [..G] done
132 MUIA_Application_BrokerHook [ISG] done
133 MUIA_Application_BrokerPort [..G] done
134 MUIA_Application_BrokerPri [I.G] done
135 MUIA_Application_Commands [ISG] needs Arexx
136 MUIA_Application_Copyright [I.G] done
137 MUIA_Application_Description [I.G] done
138 MUIA_Application_DiskObject [ISG] done
139 MUIA_Application_DoubleStart [..G] not triggered yet (todo)
140 MUIA_Application_DropObject [IS.] needs AppMessage
141 MUIA_Application_ForceQuit [..G] not triggered yet
142 MUIA_Application_HelpFile [ISG] unused/dummy
143 MUIA_Application_Iconified [.SG] done
144 MUIA_Application_Menu [I.G] unimplemented (OBSOLETE)
145 MUIA_Application_MenuAction [..G] done
146 MUIA_Application_MenuHelp [..G] todo (ditto)
147 MUIA_Application_Menustrip [I..] done
148 MUIA_Application_RexxHook [ISG] needs Arexx
149 MUIA_Application_RexxMsg [..G] needs Arexx
150 MUIA_Application_RexxString [.S.] needs Arexx
151 MUIA_Application_SingleTask [I..] done
152 MUIA_Application_Sleep [.S.] todo
153 MUIA_Application_Title [I.G] done
154 MUIA_Application_UseCommodities [I..] done
155 MUIA_Application_UseRexx [I..] done
156 MUIA_Application_Version [I.G] done
157 MUIA_Application_Window [I..] done
158 MUIA_Application_WindowList [..G] done
162 MUIM_Application_AboutMUI todo
163 MUIM_Application_AddInputHandler done ?
164 MUIM_Application_CheckRefresh todo (implementable ?)
165 MUIM_Application_GetMenuCheck OBSOLETE
166 MUIM_Application_GetMenuState OBSOLETE
167 MUIM_Application_Input OBSOLETE
168 MUIM_Application_InputBuffered todo
169 MUIM_Application_Load
170 MUIM_Application_NewInput done
171 MUIM_Application_OpenConfigWindow
172 MUIM_Application_PushMethod
173 MUIM_Application_RemInputHandler done ?
174 MUIM_Application_ReturnID done
175 MUIM_Application_Save
176 MUIM_Application_SetConfigItem
177 MUIM_Application_SetMenuCheck
178 MUIM_Application_SetMenuState
179 MUIM_Application_ShowHelp
181 Notify.mui/MUIM_FindUData done
182 Notify.mui/MUIM_GetUData done
183 Notify.mui/MUIM_SetUData done
184 Notify.mui/MUIM_SetUDataOnce done
187 static const int __version
= 1;
188 static const int __revision
= 1;
196 struct MinNode mq_Node
;
205 struct FilePrefHeader
212 #define ID_MUIO MAKE_ID('M','U','I','O')
215 * Allocates an MethodQueue Method
217 static struct MQNode
*CreateMQNode(LONG count
)
221 mq
= (struct MQNode
*)mui_alloc(sizeof(struct MQNode
) +
222 (count
* sizeof(IPTR
)));
226 mq
->mq_Count
= count
;
227 mq
->mq_Msg
= (IPTR
*) (((char *)mq
) + sizeof(struct MQNode
));
232 * Free an IQ Method got from CreateIQMethod()
234 static void DeleteMQNode(struct MQNode
*mq
)
241 * Queue of Return IDs
245 struct MinNode rid_Node
;
250 static struct RIDNode
*CreateRIDNode(struct MUI_ApplicationData
*data
,
255 if ((rid
= mui_alloc_struct(struct RIDNode
)))
257 rid
->rid_Value
= retid
;
263 static void DeleteRIDNode(struct MUI_ApplicationData
*data
,
270 /**************************************************************************
271 Process a pushed method.
272 **************************************************************************/
273 static BOOL
application_do_pushed_method(struct MUI_ApplicationData
*data
)
277 ObtainSemaphore(&data
->app_MethodSemaphore
);
279 if ((mq
= (struct MQNode
*)RemHead((struct List
*)&data
->app_MethodQueue
)))
281 ReleaseSemaphore(&data
->app_MethodSemaphore
);
283 DoMethodA(mq
->mq_Dest
, (Msg
) mq
->mq_Msg
);
287 ReleaseSemaphore(&data
->app_MethodSemaphore
);
291 static Object
*find_application_by_base(struct IClass
*cl
, Object
*obj
,
294 struct TrackingNode
*tn
;
295 Object
*retval
= NULL
;
297 ObtainSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
298 ForeachNode(&MUIMB(MUIMasterBase
)->Applications
, tn
)
302 get(tn
->tn_Application
, MUIA_Application_Base
, &tn_base
);
304 if (tn_base
&& (strcmp(base
, tn_base
)) == 0)
306 retval
= tn
->tn_Application
;
310 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
315 /**************************************************************************
317 **************************************************************************/
318 static IPTR
Application__OM_NEW(struct IClass
*cl
, Object
*obj
,
321 struct MUI_ApplicationData
*data
;
322 struct TagItem
*tags
, *tag
;
323 BOOL bad_childs
= FALSE
;
325 obj
= (Object
*) DoSuperMethodA(cl
, obj
, (Msg
) msg
);
329 /* Initial local instance data */
330 data
= INST_DATA(cl
, obj
);
332 /* init input handler list */
333 NewList((struct List
*)&(data
->app_IHList
));
335 /* init input queue */
336 NewList((struct List
*)&(data
->app_MethodQueue
));
338 /* init return ids queue */
339 NewList((struct List
*)&(data
->app_ReturnIDQueue
));
342 data
->app_WindowFamily
= MUI_NewObjectA(MUIC_Family
, NULL
);
343 if (!data
->app_WindowFamily
)
345 CoerceMethod(cl
, obj
, OM_DISPOSE
);
349 data
->app_GlobalInfo
.mgi_ApplicationObject
= obj
;
350 if (!(data
->app_GlobalInfo
.mgi_WindowsPort
= CreateMsgPort()))
352 CoerceMethod(cl
, obj
, OM_DISPOSE
);
356 data
->app_Task
= FindTask(NULL
);
359 data
->app_SingleTask
=
360 (BOOL
) GetTagData(MUIA_Application_SingleTask
, FALSE
,
363 (STRPTR
) GetTagData(MUIA_Application_Base
, (IPTR
) "UNNAMED",
365 if (!data
->app_Base
|| strpbrk(data
->app_Base
, ":/()#?*,"))
367 data
->app_Base
= NULL
; /* don't remove */
368 CoerceMethod(cl
, obj
, OM_DISPOSE
);
373 if (!data
->app_SingleTask
)
375 /* must append .1, .2, ... to the base name */
379 for (i
= 1; i
< 1000; i
++)
381 snprintf(portname
, 255, "%s.%d", data
->app_Base
, (int)i
);
382 if (!find_application_by_base(cl
, obj
, portname
))
385 data
->app_Base
= StrDup(portname
);
391 ObtainSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
392 if ((other_app
= find_application_by_base(cl
, obj
, data
->app_Base
)))
394 //FIXME "Is calling MUIM_Application_PushMethod on an alien application object safe?"
395 DoMethod(other_app
, MUIM_Application_PushMethod
,
396 (IPTR
) other_app
, 3, MUIM_Set
, MUIA_Application_DoubleStart
,
398 data
->app_Base
= NULL
;
400 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
402 data
->app_Base
= StrDup(data
->app_Base
);
407 CoerceMethod(cl
, obj
, OM_DISPOSE
);
411 data
->app_GlobalInfo
.mgi_Configdata
=
412 MUI_NewObject(MUIC_Configdata
, MUIA_Configdata_Application
, obj
,
414 if (!data
->app_GlobalInfo
.mgi_Configdata
)
416 CoerceMethod(cl
, obj
, OM_DISPOSE
);
419 get(data
->app_GlobalInfo
.mgi_Configdata
, MUIA_Configdata_ZunePrefs
,
420 &data
->app_GlobalInfo
.mgi_Prefs
);
422 // D(bug("muimaster.library/application.c: Message Port created at 0x%lx\n",
423 // data->app_GlobalInfo.mgi_WindowPort));
425 /* Setup timer stuff */
426 if (!(data
->app_TimerPort
= CreateMsgPort()))
428 CoerceMethod(cl
, obj
, OM_DISPOSE
);
432 if (!(data
->app_TimerReq
=
433 (struct timerequest
*)CreateIORequest(data
->app_TimerPort
,
434 sizeof(struct timerequest
))))
436 CoerceMethod(cl
, obj
, OM_DISPOSE
);
440 if (OpenDevice(TIMERNAME
, UNIT_VBLANK
,
441 (struct IORequest
*)data
->app_TimerReq
, 0))
443 CoerceMethod(cl
, obj
, OM_DISPOSE
);
447 InitSemaphore(&data
->app_MethodSemaphore
);
449 muiNotifyData(obj
)->mnd_GlobalInfo
= &data
->app_GlobalInfo
;
451 /* parse initial taglist */
453 data
->app_Active
= 1;
454 data
->app_Title
= "Unnamed";
455 data
->app_Version
= "Unnamed 0.0";
456 data
->app_Description
= "?";
458 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
));)
462 case MUIA_Application_Author
:
463 data
->app_Author
= (STRPTR
) tag
->ti_Data
;
466 case MUIA_Application_Base
:
467 /* moved before config parsing */
470 case MUIA_Application_Copyright
:
471 data
->app_Copyright
= (STRPTR
) tag
->ti_Data
;
474 case MUIA_Application_Description
:
475 data
->app_Description
= (STRPTR
) tag
->ti_Data
;
478 case MUIA_Application_HelpFile
:
479 data
->app_HelpFile
= (STRPTR
) tag
->ti_Data
;
482 case MUIA_Application_SingleTask
:
483 /* moved before config parsing */
486 case MUIA_Application_Title
:
487 data
->app_Title
= (STRPTR
) tag
->ti_Data
;
490 case MUIA_Application_Version
:
491 data
->app_Version
= (STRPTR
) tag
->ti_Data
;
494 case MUIA_Application_Version_Number
:
495 data
->app_Version_Number
= (STRPTR
) tag
->ti_Data
;
498 case MUIA_Application_Version_Date
:
499 data
->app_Version_Date
= (STRPTR
) tag
->ti_Data
;
502 case MUIA_Application_Version_Extra
:
503 data
->app_Version_Extra
= (STRPTR
) tag
->ti_Data
;
506 case MUIA_Application_Window
:
508 DoMethod(obj
, OM_ADDMEMBER
, tag
->ti_Data
);
513 case MUIA_Application_Menustrip
:
514 data
->app_Menustrip
= (Object
*) tag
->ti_Data
;
517 case MUIA_Application_BrokerPri
:
518 data
->app_BrokerPri
= (BYTE
) tag
->ti_Data
;
521 case MUIA_Application_BrokerHook
:
522 data
->app_BrokerHook
= (struct Hook
*)tag
->ti_Data
;
525 case MUIA_Application_Active
:
526 data
->app_Active
= tag
->ti_Data
? TRUE
: FALSE
;
529 case MUIA_Application_UsedClasses
:
531 STRPTR
*list
= (STRPTR
*) tag
->ti_Data
;
536 struct IClass
*icl
= MUI_GetClass(*list
);
544 case MUIA_Application_UseRexx
:
545 data
->app_UseRexx
= tag
->ti_Data
? TRUE
: FALSE
;
548 case MUIA_Application_Commands
:
549 data
->app_Commands
= (struct MUI_Command
*)tag
->ti_Data
;
552 case MUIA_Application_RexxHook
:
553 data
->app_RexxHook
= (struct Hook
*)tag
->ti_Data
;
556 case MUIA_Application_DiskObject
:
557 data
->app_DiskObject
= (struct DiskObject
*)tag
->ti_Data
;
563 /* create MUIA_Application_Version if NULL */
564 if (data
->app_Version
== NULL
565 && data
->app_Title
!= NULL
&& data
->app_Version_Number
!= NULL
)
567 STRPTR result
= NULL
;
570 /* Calculate length */
571 length
= strlen("$VER: ") + strlen(data
->app_Title
) + 1 /* space */
572 + strlen(data
->app_Version_Number
) + 1 /* NULL */ ;
574 if (data
->app_Version_Date
!= NULL
)
576 length
+= 1 /* space */ + 1 /* ( */
577 + strlen(data
->app_Version_Date
) + 1 /* ) */ ;
580 if (data
->app_Version_Extra
!= NULL
)
582 length
+= 1 /* space */ + 1 /* [ */
583 + strlen(data
->app_Version_Extra
) + 1 /* ] */ ;
586 /* Allocate memory */
587 result
= AllocVec(length
, MEMF_ANY
);
594 strlcat(result
, "$VER: ", length
);
595 strlcat(result
, data
->app_Title
, length
);
596 strlcat(result
, " ", length
);
597 strlcat(result
, data
->app_Version_Number
, length
);
599 if (data
->app_Version_Date
!= NULL
)
601 strlcat(result
, " (", length
);
602 strlcat(result
, data
->app_Version_Date
, length
);
603 strlcat(result
, ")", length
);
606 if (data
->app_Version_Extra
!= NULL
)
608 strlcat(result
, " [", length
);
609 strlcat(result
, data
->app_Version_Extra
, length
);
610 strlcat(result
, "]", length
);
613 data
->app_Version
= result
;
614 data
->app_VersionAllocated
= TRUE
;
621 CoerceMethod(cl
, obj
, OM_DISPOSE
);
626 && GetTagData(MUIA_Application_UseCommodities
, TRUE
,
629 data
->app_BrokerPort
= CreateMsgPort();
631 if (data
->app_BrokerPort
)
635 nb
.nb_Version
= NB_VERSION
;
637 data
->app_Title
? data
->app_Title
: (STRPTR
) "Unnamed";
639 data
->app_Version
? data
->app_Version
: (STRPTR
) "Unnamed";
641 data
->app_Description
? data
->
642 app_Description
: (STRPTR
) "?";
644 nb
.nb_Flags
= COF_SHOW_HIDE
;
645 nb
.nb_Pri
= data
->app_BrokerPri
;
646 nb
.nb_Port
= data
->app_BrokerPort
;
647 nb
.nb_ReservedChannel
= 0;
649 if (strncmp(nb
.nb_Title
, "$VER: ", 6) == 0)
652 data
->app_Broker
= CxBroker(&nb
, 0);
654 if (data
->app_Broker
)
656 if (data
->app_Active
)
657 ActivateCxObj(data
->app_Broker
, 1);
662 if (data
->app_UseRexx
)
664 data
->app_RexxPort
= CreateMsgPort();
665 if (data
->app_RexxPort
)
667 data
->app_RexxPort
->mp_Node
.ln_Name
= StrDup(data
->app_Base
);
668 if (data
->app_RexxPort
->mp_Node
.ln_Name
!= NULL
)
670 D(bug("[MUI] %s is using REXX!\n",
671 data
->app_RexxPort
->mp_Node
.ln_Name
));
673 for (i
= data
->app_RexxPort
->mp_Node
.ln_Name
; *i
!= '\0';
678 AddPort(data
->app_RexxPort
);
682 DeleteMsgPort(data
->app_RexxPort
);
683 data
->app_RexxPort
= NULL
;
688 if (data
->app_Menustrip
)
689 DoMethod(data
->app_Menustrip
, MUIM_ConnectParent
, (IPTR
) obj
);
691 data
->app_AppPort
= CreateMsgPort();
693 ObtainSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
694 data
->app_TrackingNode
.tn_Application
= obj
;
695 AddTail((struct List
*)&MUIMB(MUIMasterBase
)->Applications
,
696 (struct Node
*)&data
->app_TrackingNode
);
697 data
->app_is_TNode_in_list
= TRUE
;
698 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
705 /**************************************************************************
707 **************************************************************************/
708 static IPTR
Application__OM_DISPOSE(struct IClass
*cl
, Object
*obj
,
711 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
718 positionmode
= data
->app_GlobalInfo
.mgi_Prefs
->window_position
;
719 if (positionmode
>= 1)
721 snprintf(filename
, 255, "ENV:zune/%s.prefs", data
->app_Base
);
722 DoMethod(data
->app_GlobalInfo
.mgi_Configdata
,
723 MUIM_Configdata_Save
, (IPTR
) filename
);
725 if (positionmode
== 2)
727 snprintf(filename
, 255, "ENVARC:zune/%s.prefs", data
->app_Base
);
728 DoMethod(data
->app_GlobalInfo
.mgi_Configdata
,
729 MUIM_Configdata_Save
, (IPTR
) filename
);
733 if (data
->app_is_TNode_in_list
)
735 ObtainSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
736 Remove((struct Node
*)&data
->app_TrackingNode
);
737 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
740 if (data
->app_WindowFamily
)
742 struct MinList
*children
= NULL
;
746 /* special loop because the next object may have been removed/freed by
747 * the previous. so restart from listhead each time.
751 get(data
->app_WindowFamily
, MUIA_Family_List
, &children
);
752 if (children
== NULL
)
755 cstate
= (Object
*) children
->mlh_Head
;
756 if ((child
= NextObject(&cstate
)))
758 D(bug("Application_Dispose(%p) : OM_REMMEMBER(%p)\n", obj
,
760 DoMethod(obj
, OM_REMMEMBER
, (IPTR
) child
);
761 D(bug("Application_Dispose(%p) : MUI_DisposeObject(%p)\n",
763 MUI_DisposeObject(child
);
771 MUI_DisposeObject(data
->app_WindowFamily
);
774 if (data
->app_Menustrip
)
775 MUI_DisposeObject(data
->app_Menustrip
);
777 if (data
->app_VersionAllocated
&& data
->app_Version
!= NULL
)
779 FreeVec(data
->app_Version
);
782 /* free commodities stuff */
784 if (data
->app_Broker
)
786 DeleteCxObjAll(data
->app_Broker
);
789 if (data
->app_BrokerPort
)
793 while ((msg
= GetMsg(data
->app_BrokerPort
)))
798 DeleteMsgPort(data
->app_BrokerPort
);
801 /* free timer stuff */
802 if (data
->app_TimerReq
)
804 if (data
->app_TimerReq
->tr_node
.io_Device
)
806 while (data
->app_TimerOutstanding
)
808 if (Wait(1L << data
->app_TimerPort
->
809 mp_SigBit
| 4096) & 4096)
811 data
->app_TimerOutstanding
--;
813 CloseDevice((struct IORequest
*)data
->app_TimerReq
);
815 DeleteIORequest((struct IORequest
*)data
->app_TimerReq
);
817 if (data
->app_TimerPort
)
818 DeleteMsgPort(data
->app_TimerPort
);
820 if (data
->app_RexxPort
)
823 while ((msg
= GetMsg(data
->app_RexxPort
)))
827 RemPort(data
->app_RexxPort
);
829 if (data
->app_RexxPort
->mp_Node
.ln_Name
!= NULL
)
830 FreeVec(data
->app_RexxPort
->mp_Node
.ln_Name
);
832 DeleteMsgPort(data
->app_RexxPort
);
835 if (data
->app_AppIcon
)
836 RemoveAppIcon(data
->app_AppIcon
);
838 if (data
->app_DefaultDiskObject
)
839 FreeDiskObject(data
->app_DefaultDiskObject
);
841 if (data
->app_AppPort
)
844 while ((msg
= GetMsg(data
->app_AppPort
)))
847 DeleteMsgPort(data
->app_AppPort
);
850 if (data
->app_GlobalInfo
.mgi_Configdata
)
851 MUI_DisposeObject(data
->app_GlobalInfo
.mgi_Configdata
);
853 if (data
->app_GlobalInfo
.mgi_WindowsPort
)
854 DeleteMsgPort(data
->app_GlobalInfo
.mgi_WindowsPort
);
856 FreeVec(data
->app_Base
);
858 /* free returnid stuff */
861 (struct RIDNode
*)RemHead((struct List
*)&data
->
864 DeleteRIDNode(data
, rid
);
867 return DoSuperMethodA(cl
, obj
, msg
);
871 /**************************************************************************
873 **************************************************************************/
874 static IPTR
Application__OM_SET(struct IClass
*cl
, Object
*obj
,
877 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
878 struct TagItem
*tags
= msg
->ops_AttrList
;
881 /* There are many ways to find out what tag items provided by set()
882 ** we do know. The best way should be using NextTagItem() and simply
883 ** browsing through the list.
885 while ((tag
= NextTagItem(&tags
)) != NULL
)
891 case MUIA_Application_SearchWinId
:
892 data
->searchwinid
= tag
->ti_Data
;
895 case MUIA_Application_CopyWinPosToApp
:
896 addr
= (IPTR
*) tag
->ti_Data
;
897 CopyMem((CONST_APTR
) tag
->ti_Data
, &data
->winposused
, *(addr
));
900 case MUIA_Application_SetWinPos
:
902 struct windowpos
*winp
;
903 winp
= (struct windowpos
*)tag
->ti_Data
;
904 //kprintf("SetWinPos %d %d %d %d %d\n", winp->id, winp->x1,
905 // winp->y1, winp->w1, winp->h1);
907 for (i
= 0; i
< MAXWINS
- 1; i
++)
909 if (data
->winpos
[i
].w1
)
911 if (winp
->id
== data
->winpos
[i
].id
)
913 //existing entry is overwritten
914 data
->winpos
[i
].x1
= winp
->x1
;
915 data
->winpos
[i
].y1
= winp
->y1
;
916 data
->winpos
[i
].w1
= winp
->w1
;
917 data
->winpos
[i
].h1
= winp
->h1
;
918 data
->winpos
[i
].x2
= winp
->x2
;
919 data
->winpos
[i
].y2
= winp
->y2
;
920 data
->winpos
[i
].w2
= winp
->w2
;
921 data
->winpos
[i
].h2
= winp
->h2
;
927 // a new entry is added
928 data
->winpos
[i
].id
= winp
->id
;
929 data
->winpos
[i
].x1
= winp
->x1
;
930 data
->winpos
[i
].y1
= winp
->y1
;
931 data
->winpos
[i
].w1
= winp
->w1
;
932 data
->winpos
[i
].h1
= winp
->h1
;
933 data
->winpos
[i
].x2
= winp
->x2
;
934 data
->winpos
[i
].y2
= winp
->y2
;
935 data
->winpos
[i
].w2
= winp
->w2
;
936 data
->winpos
[i
].h2
= winp
->h2
;
943 case MUIA_Application_Configdata
:
944 DoMethod(obj
, MUIM_Application_PushMethod
, (IPTR
) obj
, 2,
945 MUIM_Application_SetConfigdata
, tag
->ti_Data
);
948 case MUIA_Application_HelpFile
:
949 data
->app_HelpFile
= (STRPTR
) tag
->ti_Data
;
952 case MUIA_Application_Iconified
:
954 BOOL do_iconify
= tag
->ti_Data
== 1;
955 if (data
->app_Iconified
!= do_iconify
)
957 data
->app_Iconified
= do_iconify
;
959 nnset(obj
, MUIA_ShowMe
, !data
->app_Iconified
);
961 /* Inform workbench.library */
962 if (data
->app_Iconified
)
965 data
->app_Title
? data
->
966 app_Title
: (STRPTR
) "Unnamed";
967 struct DiskObject
*dobj
=
968 (struct DiskObject
*)XGET(obj
,
969 MUIA_Application_DiskObject
);
973 /* Get default AppIcon in ENV:SYS or ENVARC:SYS */
974 dobj
= GetDefDiskObject(WBAPPICON
);
976 data
->app_DefaultDiskObject
= dobj
;
979 /* First default: ENV:SYS/def_MUI.info */
980 dobj
= GetDiskObject("ENV:SYS/def_MUI");
982 data
->app_DefaultDiskObject
= dobj
;
985 /* Second default: ENV:SYS/def_Zune.info */
987 GetDiskObject("ENV:SYS/def_Zune");
989 data
->app_DefaultDiskObject
= dobj
;
992 /* Third default: default tool icon */
993 dobj
= GetDefDiskObject(WBTOOL
);
995 data
->app_DefaultDiskObject
=
1005 dobj
->do_CurrentX
= NO_ICON_POSITION
;
1006 dobj
->do_CurrentY
= NO_ICON_POSITION
;
1009 AddAppIconA(0L, 0L, appname
, data
->app_AppPort
,
1014 if (data
->app_AppIcon
)
1016 RemoveAppIcon(data
->app_AppIcon
);
1017 data
->app_AppIcon
= NULL
;
1019 if (data
->app_DefaultDiskObject
)
1021 FreeDiskObject(data
->app_DefaultDiskObject
);
1022 data
->app_DefaultDiskObject
= NULL
;
1031 /* Ok ok, you think this stinks? Well, think of it as
1032 an attribute belonging to an interface which
1033 MUIC_Application, together with MUIC_Area and a few
1034 others implement. It makes sense now, yes? */
1035 struct List
*wlist
= NULL
;
1037 Object
*curwin
= NULL
;
1038 Object
*lastwin
= NULL
;
1040 /* MUIA_ShowMe can cause MUIM_Setup/MUIM_Cleanup to be issued.
1041 * On the other hand it is allowed to add/remove other
1042 * application windows in MUIM_Setup/MUIM_Cleanup.
1043 * This means after processing a window from internal list,
1044 * the list needs to be re-read and iteration started again,
1045 * because wstate can become invalid.
1046 * Note: The code below assumes that the window won't remove
1047 * itself from the list.
1052 get(data
->app_WindowFamily
, MUIA_Family_List
, &wlist
);
1053 wstate
= (Object
*) wlist
->lh_Head
;
1054 while ((curwin
= NextObject(&wstate
)))
1056 if (lastwin
== NULL
)
1058 if (curwin
== lastwin
)
1060 curwin
= NextObject(&wstate
);
1065 /* This is the window to be processed */
1068 set(curwin
, MUIA_ShowMe
, tag
->ti_Data
);
1073 /* No more windows */
1080 case MUIA_Application_Sleep
:
1082 struct List
*wlist
= NULL
;
1088 data
->app_SleepCount
++;
1089 if (data
->app_SleepCount
== 1)
1091 get(obj
, MUIA_Application_WindowList
, &wlist
);
1094 wstate
= wlist
->lh_Head
;
1095 while ((curwin
= NextObject(&wstate
)))
1097 set(curwin
, MUIA_Window_Sleep
, TRUE
);
1104 data
->app_SleepCount
--;
1105 if (data
->app_SleepCount
== 0)
1107 get(obj
, MUIA_Application_WindowList
, &wlist
);
1110 wstate
= wlist
->lh_Head
;
1111 while ((curwin
= NextObject(&wstate
)))
1113 set(curwin
, MUIA_Window_Sleep
, FALSE
);
1121 case MUIA_Application_MenuAction
:
1122 data
->app_MenuAction
= tag
->ti_Data
;
1125 case MUIA_Application_BrokerHook
:
1126 data
->app_BrokerHook
= (struct Hook
*)tag
->ti_Data
;
1129 case MUIA_Application_Active
:
1130 data
->app_Active
= tag
->ti_Data
? TRUE
: FALSE
;
1131 if (data
->app_Broker
)
1133 ActivateCxObj(data
->app_Broker
, data
->app_Active
);
1137 case MUIA_Application_Commands
:
1138 data
->app_Commands
= (struct MUI_Command
*)tag
->ti_Data
;
1141 case MUIA_Application_RexxString
:
1142 data
->app_RexxString
= (STRPTR
) tag
->ti_Data
;
1145 case MUIA_Application_RexxHook
:
1146 data
->app_RexxHook
= (struct Hook
*)tag
->ti_Data
;
1149 case MUIA_Application_DiskObject
:
1150 data
->app_DiskObject
= (struct DiskObject
*)tag
->ti_Data
;
1155 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
1162 static IPTR
Application__OM_GET(struct IClass
*cl
, Object
*obj
,
1165 #define STORE *(msg->opg_Storage)
1167 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1169 switch (msg
->opg_AttrID
)
1171 case MUIA_Application_GetWinPosAddr
:
1172 STORE
= (IPTR
) & data
->winposused
;
1175 case MUIA_Application_GetWinPosSize
:
1178 for (i
= 0; i
< MAXWINS
- 1; i
++)
1180 if (!data
->winpos
[i
].w1
)
1182 i
*= sizeof(struct windowpos
);
1184 data
->winposused
= i
;
1193 case MUIA_Application_GetWinPos
:
1196 if (data
->searchwinid
)
1198 for (i
= 0; i
< MAXWINS
- 1; i
++)
1200 if (data
->winpos
[i
].w1
)
1202 if (data
->searchwinid
== data
->winpos
[i
].id
)
1204 STORE
= (IPTR
) & data
->winpos
[i
].id
;
1225 case MUIA_Application_Author
:
1226 STORE
= (IPTR
) data
->app_Author
;
1229 case MUIA_Application_Base
:
1230 STORE
= (IPTR
) data
->app_Base
;
1233 case MUIA_Application_Copyright
:
1234 STORE
= (IPTR
) data
->app_Copyright
;
1237 case MUIA_Application_Description
:
1238 STORE
= (IPTR
) data
->app_Description
;
1241 case MUIA_Application_DoubleStart
:
1244 case MUIA_Application_ForceQuit
:
1245 STORE
= (IPTR
) data
->app_ForceQuit
;
1248 case MUIA_Application_HelpFile
:
1249 STORE
= (IPTR
) data
->app_HelpFile
;
1252 case MUIA_Application_Iconified
:
1253 STORE
= (IPTR
) data
->app_Iconified
;
1256 case MUIA_Application_Title
:
1257 STORE
= (IPTR
) data
->app_Title
;
1260 case MUIA_Application_Version
:
1261 STORE
= (IPTR
) data
->app_Version
;
1264 case MUIA_Application_Version_Number
:
1265 STORE
= (IPTR
) data
->app_Version_Number
;
1268 case MUIA_Application_Version_Date
:
1269 STORE
= (IPTR
) data
->app_Version_Date
;
1272 case MUIA_Application_Version_Extra
:
1273 STORE
= (IPTR
) data
->app_Version_Extra
;
1276 case MUIA_Application_WindowList
:
1277 return GetAttr(MUIA_Family_List
, data
->app_WindowFamily
,
1280 case MUIA_Application_Menustrip
:
1281 STORE
= (IPTR
) data
->app_Menustrip
;
1284 case MUIA_Application_MenuAction
:
1285 STORE
= (IPTR
) data
->app_MenuAction
;
1288 case MUIA_Application_BrokerPort
:
1289 STORE
= (IPTR
) data
->app_BrokerPort
;
1292 case MUIA_Application_BrokerPri
:
1293 STORE
= (IPTR
) data
->app_BrokerPri
;
1296 case MUIA_Application_BrokerHook
:
1297 STORE
= (IPTR
) data
->app_BrokerHook
;
1300 case MUIA_Application_Broker
:
1301 STORE
= (IPTR
) data
->app_Broker
;
1304 case MUIA_Application_Active
:
1305 STORE
= data
->app_Active
;
1308 case MUIA_Application_Commands
:
1309 STORE
= (IPTR
) data
->app_Commands
;
1312 case MUIA_Application_RexxMsg
:
1313 STORE
= (IPTR
) data
->app_RexxMsg
;
1316 case MUIA_Application_RexxHook
:
1317 STORE
= (IPTR
) data
->app_RexxHook
;
1320 case MUIA_Application_DiskObject
:
1321 STORE
= (IPTR
) data
->app_DiskObject
;
1325 /* our handler didn't understand the attribute, we simply pass
1326 ** it to our superclass now
1328 return (DoSuperMethodA(cl
, obj
, (Msg
) msg
));
1333 /**************************************************************************
1335 **************************************************************************/
1336 static IPTR
Application__OM_ADDMEMBER(struct IClass
*cl
, Object
*obj
,
1337 struct opMember
*msg
)
1339 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1341 D(bug("Application_AddMember: Adding 0x%lx to window member list\n",
1344 DoMethodA(data
->app_WindowFamily
, (Msg
) msg
);
1345 /* Application knows its GlobalInfo, so we can inform window */
1346 DoMethod(msg
->opam_Object
, MUIM_ConnectParent
, (IPTR
) obj
);
1351 /**************************************************************************
1353 **************************************************************************/
1354 static IPTR
Application__OM_REMMEMBER(struct IClass
*cl
, Object
*obj
,
1355 struct opMember
*msg
)
1357 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1359 D(bug("Application_RemMember: Removing 0x%lx from window member list\n",
1362 DoMethod(msg
->opam_Object
, MUIM_DisconnectParent
);
1363 DoMethodA(data
->app_WindowFamily
, (Msg
) msg
);
1369 /**************************************************************************
1370 MUIM_Application_AddInputHandler
1371 **************************************************************************/
1372 static IPTR
Application__MUIM_AddInputHandler(struct IClass
*cl
,
1373 Object
*obj
, struct MUIP_Application_AddInputHandler
*msg
)
1375 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1377 if (msg
->ihnode
->ihn_Flags
& MUIIHNF_TIMER
)
1379 struct timerequest_ext
*time_ext
=
1380 (struct timerequest_ext
*)AllocVec(sizeof(struct
1381 timerequest_ext
), MEMF_PUBLIC
);
1384 /* Store the request inside the input handler, so that we can
1385 ** remove the inputhandler without problems */
1386 msg
->ihnode
->ihn_Node
.mln_Pred
= (struct MinNode
*)time_ext
;
1388 time_ext
->treq
= *data
->app_TimerReq
;
1389 time_ext
->treq
.tr_node
.io_Command
= TR_ADDREQUEST
;
1390 time_ext
->treq
.tr_time
.tv_secs
= msg
->ihnode
->ihn_Millis
/ 1000;
1391 time_ext
->treq
.tr_time
.tv_micro
=
1392 (msg
->ihnode
->ihn_Millis
% 1000) * 1000;
1393 time_ext
->ihn
= msg
->ihnode
;
1394 SendIO((struct IORequest
*)time_ext
);
1398 AddTail((struct List
*)&data
->app_IHList
,
1399 (struct Node
*)msg
->ihnode
);
1404 /**************************************************************************
1405 MUIM_Application_RemInputHandler
1406 **************************************************************************/
1407 static IPTR
Application__MUIM_RemInputHandler(struct IClass
*cl
,
1408 Object
*obj
, struct MUIP_Application_RemInputHandler
*msg
)
1410 //struct MUI_ApplicationData *data = INST_DATA(cl, obj);
1411 if (msg
->ihnode
->ihn_Flags
& MUIIHNF_TIMER
)
1413 struct timerequest_ext
*time_ext
=
1414 (struct timerequest_ext
*)msg
->ihnode
->ihn_Node
.mln_Pred
;
1415 if (!CheckIO((struct IORequest
*)time_ext
))
1416 AbortIO((struct IORequest
*)time_ext
);
1417 WaitIO((struct IORequest
*)time_ext
);
1421 Remove((struct Node
*)msg
->ihnode
);
1427 void _zune_window_message(struct IntuiMessage
*imsg
); /* from window.c */
1430 * MUIM_Application_InputBuffered : process all pending events
1432 static IPTR
Application__MUIM_InputBuffered(struct IClass
*cl
, Object
*obj
,
1433 struct MUIP_Application_InputBuffered
*msg
)
1435 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1436 struct IntuiMessage
*imsg
;
1438 /* process all pushed methods */
1439 while (application_do_pushed_method(data
))
1443 (struct IntuiMessage
*)GetMsg(data
->app_GlobalInfo
.mgi_WindowsPort
);
1446 /* Let window object process message */
1447 _zune_window_message(imsg
); /* will reply the message */
1452 /**************************************************************************
1453 MUIM_Application_NewInput : application main loop
1454 **************************************************************************/
1455 static IPTR
Application__MUIM_NewInput(struct IClass
*cl
, Object
*obj
,
1456 struct MUIP_Application_NewInput
*msg
)
1458 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1459 struct RIDNode
*rid
;
1461 ULONG signal
, signalmask
;
1462 ULONG handler_mask
= 0; /* the mask of the signal handlers */
1465 //struct MinNode ihn_Node;
1467 signal
= *msg
->signal
;
1469 /* process all pushed methods */
1470 while (application_do_pushed_method(data
))
1473 /* query the signal for the handlers */
1474 for (mn
= data
->app_IHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
1476 struct MUI_InputHandlerNode
*ihn
;
1477 ihn
= (struct MUI_InputHandlerNode
*)mn
;
1478 handler_mask
|= ihn
->ihn_Signals
;
1481 signalmask
= (1L << data
->app_GlobalInfo
.mgi_WindowsPort
->mp_SigBit
)
1482 | (1L << data
->app_TimerPort
->mp_SigBit
) | handler_mask
;
1484 if (data
->app_Broker
)
1485 signalmask
|= (1L << data
->app_BrokerPort
->mp_SigBit
);
1487 if (data
->app_RexxPort
)
1488 signalmask
|= (1L << data
->app_RexxPort
->mp_SigBit
);
1490 if (data
->app_AppPort
)
1491 signalmask
|= (1L << data
->app_AppPort
->mp_SigBit
);
1495 /* Stupid app which (always) passes 0 in signals. It's impossible to
1496 know which signals were really set as the app will already have
1497 called Wait() which has cleared the task's tc_SigRecvd. So assume
1498 the window, timer, and broker signals all to be set. Also all of
1499 the inputhandler signals (MUI does that too). */
1501 signal
= signalmask
;
1504 if (signal
& signalmask
)
1506 if (signal
& (1L << data
->app_GlobalInfo
.mgi_WindowsPort
->
1509 struct IntuiMessage
*imsg
;
1510 /* process all pushed methods */
1513 (struct IntuiMessage
*)GetMsg(data
->app_GlobalInfo
.
1516 /* Let window object process message */
1517 _zune_window_message(imsg
); /* will reply the message */
1521 if (signal
& (1L << data
->app_TimerPort
->mp_SigBit
))
1523 struct timerequest_ext
*time_ext
;
1528 /* At first we fetch all messages from the message port and store
1529 ** them in a list, we use the node of the Message here */
1531 (struct timerequest_ext
*)GetMsg(data
->app_TimerPort
)))
1532 AddTail(&list
, (struct Node
*)time_ext
);
1534 /* Now we proccess the list and resend the timer io, no loop can
1535 ** happen. We use RemHead() because the handler can remove it
1536 ** itself and so a FreeVec() could happen in
1537 ** MUIM_Application_RemInputHandler which would destroy the
1538 ** ln->Succ of course */
1539 while ((n
= RemHead(&list
)))
1541 struct timerequest_ext
*time_ext
=
1542 (struct timerequest_ext
*)n
;
1543 struct MUI_InputHandlerNode
*ihn
= time_ext
->ihn
;
1544 time_ext
->treq
.tr_time
.tv_secs
=
1545 time_ext
->ihn
->ihn_Millis
/ 1000;
1546 time_ext
->treq
.tr_time
.tv_micro
=
1547 (time_ext
->ihn
->ihn_Millis
% 1000) * 1000;
1548 SendIO((struct IORequest
*)&time_ext
->treq
);
1549 DoMethod(ihn
->ihn_Object
, ihn
->ihn_Method
);
1553 if (data
->app_BrokerPort
1554 && (signal
& (1L << data
->app_BrokerPort
->mp_SigBit
)))
1558 while ((msg
= (CxMsg
*) GetMsg(data
->app_BrokerPort
)))
1560 switch (CxMsgType(msg
))
1563 switch (CxMsgID(msg
))
1566 set(obj
, MUIA_Application_Active
, FALSE
);
1570 set(obj
, MUIA_Application_Active
, TRUE
);
1574 case CXCMD_DISAPPEAR
:
1575 /* No default handling - application needs to be in
1576 * control of this */
1580 SetSignal(SIGBREAKF_CTRL_C
, SIGBREAKF_CTRL_C
);
1586 if (data
->app_BrokerHook
)
1588 CallHookPkt(data
->app_BrokerHook
, obj
, msg
);
1591 ReplyMsg((struct Message
*)msg
);
1595 if (data
->app_RexxPort
1596 && (signal
& (1L << data
->app_RexxPort
->mp_SigBit
)))
1599 D(bug("[MUI] Got Rexx message!\n"));
1600 struct Message
*msg
;
1601 while ((msg
= GetMsg(data
->app_RexxPort
)))
1607 if (data
->app_AppPort
1608 && (signal
& (1L << data
->app_AppPort
->mp_SigBit
)))
1610 struct AppMessage
*appmsg
;
1612 (struct AppMessage
*)GetMsg(data
->app_AppPort
)))
1614 if ((appmsg
->am_Type
== AMTYPE_APPICON
)
1615 && (appmsg
->am_NumArgs
== 0)
1616 && (appmsg
->am_ArgList
== NULL
)
1617 && (XGET(obj
, MUIA_Application_Iconified
) == TRUE
))
1619 /* Reply before removing AppIcon */
1620 ReplyMsg((struct Message
*)appmsg
);
1621 set(obj
, MUIA_Application_Iconified
, FALSE
);
1625 ReplyMsg((struct Message
*)appmsg
);
1629 if (signal
& handler_mask
)
1631 for (mn
= data
->app_IHList
.mlh_Head
; mn
->mln_Succ
;
1634 struct MUI_InputHandlerNode
*ihn
;
1635 ihn
= (struct MUI_InputHandlerNode
*)mn
;
1636 if (signal
& ihn
->ihn_Signals
)
1637 DoMethod(ihn
->ihn_Object
, ihn
->ihn_Method
);
1642 /* process all pushed methods - again */
1643 while (application_do_pushed_method(data
))
1646 *msg
->signal
= signalmask
;
1648 /* set return code */
1650 (struct RIDNode
*)RemHead((struct List
*)&data
->
1651 app_ReturnIDQueue
)))
1653 retval
= rid
->rid_Value
;
1654 DeleteRIDNode(data
, rid
);
1660 /**************************************************************************
1661 MUIM_Application_Input : application main loop
1662 This method shouldn't be used in any new program. As it polls all signals.
1663 **************************************************************************/
1664 static IPTR
Application__MUIM_Input(struct IClass
*cl
, Object
*obj
,
1665 struct MUIP_Application_Input
*msg
)
1667 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1668 ULONG signal
= 0, handler_mask
= 0;
1671 /* query the signal for the handlers */
1672 for (mn
= data
->app_IHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
1674 struct MUI_InputHandlerNode
*ihn
;
1675 ihn
= (struct MUI_InputHandlerNode
*)mn
;
1676 handler_mask
|= ihn
->ihn_Flags
;
1679 signal
= (1L << data
->app_GlobalInfo
.mgi_WindowsPort
->mp_SigBit
)
1680 | (1L << data
->app_TimerPort
->mp_SigBit
) | handler_mask
;
1682 if (data
->app_RexxPort
)
1683 signal
|= (1L << data
->app_RexxPort
->mp_SigBit
);
1685 if (data
->app_AppPort
)
1686 signal
|= (1L << data
->app_AppPort
->mp_SigBit
);
1689 *msg
->signal
= signal
;
1690 return Application__MUIM_NewInput(cl
, obj
, (APTR
) msg
);
1693 /**************************************************************************
1694 MUIM_Application_PushMethod: Add a method in the method FIFO. Will
1695 be executed in the next event loop.
1696 **************************************************************************/
1697 static IPTR
Application__MUIM_PushMethod(struct IClass
*cl
, Object
*obj
,
1698 struct MUIP_Application_PushMethod
*msg
)
1700 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1703 IPTR
*m
= (IPTR
*) & msg
->count
; /* FIXME: breaks on 64-bit BigEndian systems */
1706 count
= msg
->count
& 0xf; /* MUI4 uses count to pass additional info */
1708 mq
= CreateMQNode(count
);
1711 mq
->mq_Dest
= msg
->dest
;
1714 for (i
= 0; i
< count
; i
++)
1715 mq
->mq_Msg
[i
] = *(m
+ 1 + i
);
1717 /* enqueue method */
1718 ObtainSemaphore(&data
->app_MethodSemaphore
);
1719 AddTail((struct List
*)&data
->app_MethodQueue
, (struct Node
*)mq
);
1720 ReleaseSemaphore(&data
->app_MethodSemaphore
);
1722 /* CHECKME: to wake task up as soon as possible! */
1723 Signal(data
->app_Task
,
1724 1L << data
->app_GlobalInfo
.mgi_WindowsPort
->mp_SigBit
);
1731 * MUIM_Application_ReturnID : Tell MUI to return the given id with
1732 * the next call to MUIM_Application_NewInput. kinda obsolete :)
1734 static IPTR
Application__MUIM_ReturnID(struct IClass
*cl
, Object
*obj
,
1735 struct MUIP_Application_ReturnID
*msg
)
1737 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1738 struct RIDNode
*rid
;
1741 if (!data->app_RIDMemChunk)
1743 data->app_RIDMemChunk =
1744 g_mem_chunk_create(struct RIDNode, 10, G_ALLOC_AND_FREE);
1747 rid
= CreateRIDNode(data
, msg
->retid
);
1750 AddTail((struct List
*)&data
->app_ReturnIDQueue
, (struct Node
*)rid
);
1756 * MUIM_FindUData : tests if the MUIA_UserData of the object
1757 * contains the given <udata> and returns the object pointer in this case.
1759 static IPTR
Application__MUIM_FindUData(struct IClass
*cl
, Object
*obj
,
1760 struct MUIP_FindUData
*msg
)
1762 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1764 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
1767 return DoMethodA(data
->app_WindowFamily
, (Msg
) msg
);
1772 * MUIM_GetUData : This method tests if the MUIA_UserData of the object
1773 * contains the given <udata> and gets <attr> to <storage> for itself
1776 static IPTR
Application__MUIM_GetUData(struct IClass
*cl
, Object
*obj
,
1777 struct MUIP_GetUData
*msg
)
1779 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1781 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
1783 get(obj
, msg
->attr
, msg
->storage
);
1786 return DoMethodA(data
->app_WindowFamily
, (Msg
) msg
);
1791 * MUIM_SetUData : This method tests if the MUIA_UserData of the object
1792 * contains the given <udata> and sets <attr> to <val> for itself in this case.
1794 static IPTR
Application__MUIM_SetUData(struct IClass
*cl
, Object
*obj
,
1795 struct MUIP_SetUData
*msg
)
1797 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1799 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
1800 set(obj
, msg
->attr
, msg
->val
);
1802 DoMethodA(data
->app_WindowFamily
, (Msg
) msg
);
1808 * MUIM_SetUDataOnce : This method tests if the MUIA_UserData of the object
1809 * contains the given <udata> and sets <attr> to <val> for itself in this case.
1811 static IPTR
Application__MUIM_SetUDataOnce(struct IClass
*cl
, Object
*obj
,
1812 struct MUIP_SetUDataOnce
*msg
)
1814 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1816 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
1818 set(obj
, msg
->attr
, msg
->val
);
1821 return DoMethodA(data
->app_WindowFamily
, (Msg
) msg
);
1825 /**************************************************************************
1826 MUIM_Application_AboutMUI: brought up the about window, centered on refwindow
1827 **************************************************************************/
1828 static IPTR
Application__MUIM_AboutMUI(struct IClass
*cl
, Object
*obj
,
1829 struct MUIP_Application_AboutMUI
*msg
)
1831 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1833 if (!data
->app_AboutWin
)
1835 data
->app_AboutWin
= AboutmuiObject
,
1836 msg
->refwindow
? MUIA_Window_RefWindow
: TAG_IGNORE
,
1837 msg
->refwindow
, MUIA_Window_LeftEdge
,
1838 MUIV_Window_LeftEdge_Centered
, MUIA_Window_TopEdge
,
1839 MUIV_Window_TopEdge_Centered
, MUIA_Aboutmui_Application
, obj
,
1841 if (!data
->app_AboutWin
)
1843 DoMethod(data
->app_AboutWin
, MUIM_Notify
, MUIA_Window_CloseRequest
,
1844 TRUE
, (IPTR
) obj
, 3, MUIM_WriteLong
, 0L,
1845 (IPTR
) & data
->app_AboutWin
);
1846 } /* if (!data->app_AboutWin) */
1848 if (data
->app_AboutWin
)
1851 set(data
->app_AboutWin
, MUIA_Window_Open
, TRUE
);
1856 static IPTR
Application__MUIM_SetConfigdata(struct IClass
*cl
, Object
*obj
,
1857 struct MUIP_Application_SetConfigdata
*msg
)
1859 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1860 struct MinList
*children
= NULL
;
1864 get(data
->app_WindowFamily
, MUIA_Family_List
, &children
);
1867 cstate
= (Object
*) children
->mlh_Head
;
1868 if ((child
= NextObject(&cstate
)))
1870 D(bug("closing window %p\n", child
));
1872 set(child
, MUIA_Window_Open
, FALSE
);
1876 if (data
->app_GlobalInfo
.mgi_Configdata
)
1877 MUI_DisposeObject(data
->app_GlobalInfo
.mgi_Configdata
);
1878 data
->app_GlobalInfo
.mgi_Configdata
= msg
->configdata
;
1879 get(data
->app_GlobalInfo
.mgi_Configdata
, MUIA_Configdata_ZunePrefs
,
1880 &data
->app_GlobalInfo
.mgi_Prefs
);
1882 DoMethod(obj
, MUIM_Application_PushMethod
, (IPTR
) obj
, 1,
1883 MUIM_Application_OpenWindows
);
1888 /* MUIM_Application_OpenWindows
1889 * Opens all windows of an application
1891 static IPTR
Application__MUIM_OpenWindows(struct IClass
*cl
, Object
*obj
,
1892 struct MUIP_Application_OpenWindows
*msg
)
1894 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1895 struct MinList
*children
= NULL
;
1899 get(data
->app_WindowFamily
, MUIA_Family_List
, &children
);
1903 cstate
= (Object
*) children
->mlh_Head
;
1904 if ((child
= NextObject(&cstate
)))
1906 set(child
, MUIA_Window_Open
, TRUE
);
1912 static IPTR
Application__MUIM_OpenConfigWindow(struct IClass
*cl
,
1913 Object
*obj
, struct MUIP_Application_OpenConfigWindow
*msg
)
1915 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1916 struct TagItem tags
[] = {
1917 {SYS_Asynch
, FALSE
},
1920 {NP_StackSize
, AROS_STACKSIZE
},
1925 snprintf(cmd
, 255, "sys:prefs/Zune %s %ld",
1926 data
->app_Base
? data
->app_Base
: (STRPTR
) "", (long)obj
);
1928 if (SystemTagList(cmd
, tags
) == -1)
1936 snprintf(cmd
, 255, "ENV:zune/%s.prefs", data
->app_Base
);
1937 DoMethod(data
->app_GlobalInfo
.mgi_Configdata
, MUIM_Configdata_Load
,
1944 static IPTR
Application__MUIM_Execute(Class
*CLASS
, Object
*self
,
1950 (DoMethod(self
, MUIM_Application_NewInput
, (IPTR
) & signals
)
1951 != MUIV_Application_ReturnID_Quit
)
1955 signals
= Wait(signals
| SIGBREAKF_CTRL_C
);
1956 if (signals
& SIGBREAKF_CTRL_C
)
1965 static IPTR
Application__MUIM_UpdateMenus(struct IClass
*cl
, Object
*obj
,
1968 struct List
*wlist
= NULL
;
1972 get(obj
, MUIA_Application_WindowList
, &wlist
);
1976 wstate
= wlist
->lh_Head
;
1977 while ((curwin
= NextObject(&wstate
)))
1979 DoMethod(curwin
, MUIM_Window_UpdateMenu
);
1986 static IPTR
Application__MUIM_Load(struct IClass
*cl
, Object
*obj
,
1987 struct MUIP_Application_Load
*message
)
1989 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1990 struct IFFHandle
*iff
;
1994 struct MinList
*children
= NULL
;
1998 if (!data
->app_Base
)
2001 dataspace
= MUI_NewObject(MUIC_Dataspace
, TAG_DONE
);
2005 if (message
->name
== MUIV_Application_Load_ENV
)
2006 snprintf(name
, sizeof(name
), "ENV:Zune/%s.cfg", data
->app_Base
);
2007 else if (message
->name
== MUIV_Application_Load_ENVARC
)
2008 snprintf(name
, sizeof(name
), "ENVARC:Zune/%s.cfg", data
->app_Base
);
2010 strncpy(name
, message
->name
, sizeof(name
));
2012 fh
= Open(name
, MODE_OLDFILE
);
2015 if ((iff
= AllocIFF()))
2017 iff
->iff_Stream
= (IPTR
) fh
;
2021 if (!OpenIFF(iff
, IFFF_READ
))
2023 if (!StopChunk(iff
, ID_PREF
, ID_MUIO
))
2025 if (!ParseIFF(iff
, IFFPARSE_SCAN
))
2027 DoMethod(dataspace
, MUIM_Dataspace_ReadIFF
, iff
,
2039 get(data
->app_WindowFamily
, MUIA_Family_List
, &children
);
2040 cstate
= (Object
*) children
->mlh_Head
;
2041 while ((child
= NextObject(&cstate
)))
2043 DoMethod(child
, MUIM_Import
, dataspace
);
2046 MUI_DisposeObject(dataspace
);
2051 static IPTR
Application__MUIM_Save(struct IClass
*cl
, Object
*obj
,
2052 struct MUIP_Application_Save
*message
)
2054 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
2055 struct IFFHandle
*iff
;
2059 struct MinList
*children
= NULL
;
2063 if (!data
->app_Base
)
2066 dataspace
= MUI_NewObject(MUIC_Dataspace
, TAG_DONE
);
2070 get(data
->app_WindowFamily
, MUIA_Family_List
, &children
);
2071 cstate
= (Object
*) children
->mlh_Head
;
2072 while ((child
= NextObject(&cstate
)))
2074 DoMethod(child
, MUIM_Export
, dataspace
);
2077 if (message
->name
== MUIV_Application_Save_ENV
)
2078 snprintf(name
, sizeof(name
), "ENV:Zune/%s.cfg", data
->app_Base
);
2079 else if (message
->name
== MUIV_Application_Save_ENVARC
)
2080 snprintf(name
, sizeof(name
), "ENVARC:Zune/%s.cfg", data
->app_Base
);
2082 strncpy(name
, message
->name
, sizeof(name
));
2084 fh
= Open(name
, MODE_NEWFILE
);
2087 if ((iff
= AllocIFF()))
2089 iff
->iff_Stream
= (IPTR
) fh
;
2093 if (!OpenIFF(iff
, IFFF_WRITE
))
2095 if (!PushChunk(iff
, ID_PREF
, ID_FORM
, IFFSIZE_UNKNOWN
))
2097 if (!PushChunk(iff
, ID_PREF
, ID_PRHD
,
2098 sizeof(struct FilePrefHeader
)))
2100 struct FilePrefHeader head
;
2102 head
.ph_Version
= PHV_CURRENT
;
2106 head
.ph_Flags
[2] = head
.ph_Flags
[3] = 0;
2108 if (WriteChunkBytes(iff
, &head
,
2109 sizeof(head
)) == sizeof(head
))
2112 DoMethod(dataspace
, MUIM_Dataspace_WriteIFF
,
2113 iff
, ID_PREF
, ID_MUIO
);
2129 MUI_DisposeObject(dataspace
);
2135 * The class dispatcher
2137 BOOPSI_DISPATCHER(IPTR
, Application_Dispatcher
, cl
, obj
, msg
)
2139 switch (msg
->MethodID
)
2142 return Application__OM_NEW(cl
, obj
, (struct opSet
*)msg
);
2144 return Application__OM_DISPOSE(cl
, obj
, msg
);
2146 return Application__OM_SET(cl
, obj
, (struct opSet
*)msg
);
2148 return Application__OM_GET(cl
, obj
, (struct opGet
*)msg
);
2150 return Application__OM_ADDMEMBER(cl
, obj
, (APTR
) msg
);
2152 return Application__OM_REMMEMBER(cl
, obj
, (APTR
) msg
);
2153 case MUIM_Application_AddInputHandler
:
2154 return Application__MUIM_AddInputHandler(cl
, obj
, (APTR
) msg
);
2155 case MUIM_Application_RemInputHandler
:
2156 return Application__MUIM_RemInputHandler(cl
, obj
, (APTR
) msg
);
2157 case MUIM_Application_Input
:
2158 return Application__MUIM_Input(cl
, obj
, (APTR
) msg
);
2159 case MUIM_Application_InputBuffered
:
2160 return Application__MUIM_InputBuffered(cl
, obj
, (APTR
) msg
);
2161 case MUIM_Application_NewInput
:
2162 return Application__MUIM_NewInput(cl
, obj
, (APTR
) msg
);
2163 case MUIM_Application_PushMethod
:
2164 return Application__MUIM_PushMethod(cl
, obj
, (APTR
) msg
);
2165 case MUIM_Application_ReturnID
:
2166 return Application__MUIM_ReturnID(cl
, obj
, (APTR
) msg
);
2167 case MUIM_FindUData
:
2168 return Application__MUIM_FindUData(cl
, obj
, (APTR
) msg
);
2170 return Application__MUIM_GetUData(cl
, obj
, (APTR
) msg
);
2172 return Application__MUIM_SetUData(cl
, obj
, (APTR
) msg
);
2173 case MUIM_SetUDataOnce
:
2174 return Application__MUIM_SetUDataOnce(cl
, obj
, (APTR
) msg
);
2175 case MUIM_Application_AboutMUI
:
2176 return Application__MUIM_AboutMUI(cl
, obj
, (APTR
) msg
);
2177 case MUIM_Application_SetConfigdata
:
2178 return Application__MUIM_SetConfigdata(cl
, obj
, (APTR
) msg
);
2179 case MUIM_Application_OpenWindows
:
2180 return Application__MUIM_OpenWindows(cl
, obj
, (APTR
) msg
);
2181 case MUIM_Application_OpenConfigWindow
:
2182 return Application__MUIM_OpenConfigWindow(cl
, obj
, (APTR
) msg
);
2183 case MUIM_Application_Execute
:
2184 return Application__MUIM_Execute(cl
, obj
, msg
);
2185 case MUIM_Application_UpdateMenus
:
2186 return Application__MUIM_UpdateMenus(cl
, obj
, msg
);
2187 case MUIM_Application_Load
:
2188 return Application__MUIM_Load(cl
, obj
, (APTR
) msg
);
2189 case MUIM_Application_Save
:
2190 return Application__MUIM_Save(cl
, obj
, (APTR
) msg
);
2193 return (DoSuperMethodA(cl
, obj
, msg
));
2195 BOOPSI_DISPATCHER_END
2199 const struct __MUIBuiltinClass _MUI_Application_desc
=
2203 sizeof(struct MUI_ApplicationData
),
2204 (void *) Application_Dispatcher