2 Copyright 1999, David Le Corfec.
3 Copyright 2002-2006, 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 <proto/exec.h>
23 #include <proto/dos.h>
24 #include <proto/intuition.h>
25 #include <proto/utility.h>
26 #include <proto/commodities.h>
27 #include <proto/muimaster.h>
28 #include <proto/iffparse.h>
30 //#define MYDEBUG 1 */
34 #include "muimaster_intern.h"
40 extern struct Library
*MUIMasterBase
;
45 struct MinNode tn_Node
;
46 Object
*tn_Application
;
49 struct MUI_ApplicationData
51 struct MUI_GlobalInfo app_GlobalInfo
;
52 APTR app_WindowFamily
; /* delegates window list */
53 struct MinList app_IHList
;
54 struct MinList app_MethodQueue
;
55 struct SignalSemaphore app_MethodSemaphore
;
56 struct MinList app_ReturnIDQueue
;
57 struct Hook
*app_BrokerHook
;
58 struct MsgPort
*app_BrokerPort
;
59 struct MsgPort
*app_TimerPort
;
60 struct timerequest
*app_TimerReq
;
61 struct Task
*app_Task
;
63 Object
*app_Menustrip
;
69 STRPTR app_Description
;
73 BOOL app_VersionAllocated
;
74 STRPTR app_Version_Number
;
75 STRPTR app_Version_Date
;
76 STRPTR app_Version_Extra
;
78 ULONG app_TimerOutstanding
;
79 ULONG app_MenuAction
; /* Remember last action */
85 struct TrackingNode app_TrackingNode
;
86 BOOL app_is_TNode_in_list
;
88 LONG winposused
; //dont add other vars before windowpos all is save together
89 struct windowpos winpos
[MAXWINS
];
90 struct MsgPort
*app_RexxPort
;
94 struct timerequest_ext
96 struct timerequest treq
;
97 struct MUI_InputHandlerNode
*ihn
;
101 * Application class is the master class for all
102 * MUI applications. It serves as a kind of anchor
103 * for all input, either coming from the user or
104 * somewhere from the system, e.g. commodities
105 * or ARexx messages. (hemm forget theses last 2 for Zune :)
107 * An application can have any number of sub windows,
108 * these windows are the children of the application.
109 * (FYI, it delegates child handling to a Family object).
113 MUIA_Application_Active [ISG] done
114 MUIA_Application_Author [I.G] done
115 MUIA_Application_Base [I.G] done
116 MUIA_Application_Broker [..G] done
117 MUIA_Application_BrokerHook [ISG] done
118 MUIA_Application_BrokerPort [..G] done
119 MUIA_Application_BrokerPri [I.G] done
120 MUIA_Application_Commands [ISG] needs Arexx
121 MUIA_Application_Copyright [I.G] done
122 MUIA_Application_Description [I.G] done
123 MUIA_Application_DiskObject [ISG] needs struct DiskObject
124 MUIA_Application_DoubleStart [..G] not triggered yet (todo)
125 MUIA_Application_DropObject [IS.] needs AppMessage
126 MUIA_Application_ForceQuit [..G] not triggered yet
127 MUIA_Application_HelpFile [ISG] unused/dummy
128 MUIA_Application_Iconified [.SG] complete (handle appicons)
129 MUIA_Application_Menu [I.G] unimplemented (OBSOLETE)
130 MUIA_Application_MenuAction [..G] done
131 MUIA_Application_MenuHelp [..G] todo (ditto)
132 MUIA_Application_Menustrip [I..] done
133 MUIA_Application_RexxHook [ISG] needs Arexx
134 MUIA_Application_RexxMsg [..G] needs Arexx
135 MUIA_Application_RexxString [.S.] needs Arexx
136 MUIA_Application_SingleTask [I..] done
137 MUIA_Application_Sleep [.S.] todo
138 MUIA_Application_Title [I.G] done
139 MUIA_Application_UseCommodities [I..] done
140 MUIA_Application_UseRexx [I..] done ? needs Arexx
141 MUIA_Application_Version [I.G] done
142 MUIA_Application_Window [I..] done
143 MUIA_Application_WindowList [..G] done
147 MUIM_Application_AboutMUI todo
148 MUIM_Application_AddInputHandler done ?
149 MUIM_Application_CheckRefresh todo (implementable ?)
150 MUIM_Application_GetMenuCheck OBSOLETE
151 MUIM_Application_GetMenuState OBSOLETE
152 MUIM_Application_Input OBSOLETE
153 MUIM_Application_InputBuffered todo
154 MUIM_Application_Load
155 MUIM_Application_NewInput todo
156 MUIM_Application_OpenConfigWindow
157 MUIM_Application_PushMethod
158 MUIM_Application_RemInputHandler done ?
159 MUIM_Application_ReturnID done
160 MUIM_Application_Save
161 MUIM_Application_SetConfigItem
162 MUIM_Application_SetMenuCheck
163 MUIM_Application_SetMenuState
164 MUIM_Application_ShowHelp
166 Notify.mui/MUIM_FindUData done
167 Notify.mui/MUIM_GetUData done
168 Notify.mui/MUIM_SetUData done
169 Notify.mui/MUIM_SetUDataOnce done
172 static const int __version
= 1;
173 static const int __revision
= 1;
180 struct MinNode mq_Node
;
189 struct FilePrefHeader
196 #define ID_MUIO MAKE_ID('M','U','I','O')
199 * Allocates an MethodQueue Method
201 static struct MQNode
*CreateMQNode(LONG count
)
205 mq
= (struct MQNode
*)mui_alloc(sizeof(struct MQNode
) + (count
* sizeof(IPTR
)));
209 mq
->mq_Count
= count
;
210 mq
->mq_Msg
= (IPTR
*)(((char *)mq
)+sizeof(struct MQNode
));
215 * Free an IQ Method got from CreateIQMethod()
217 static void DeleteMQNode(struct MQNode
*mq
)
224 * Queue of Return IDs
227 struct MinNode rid_Node
;
232 static struct RIDNode
*CreateRIDNode(struct MUI_ApplicationData
*data
, ULONG retid
)
235 if ((rid
= mui_alloc_struct(struct RIDNode
)))
237 rid
->rid_Value
= retid
;
243 static void DeleteRIDNode (struct MUI_ApplicationData
*data
, struct RIDNode
*rid
)
249 /**************************************************************************
250 Process a pushed method.
251 **************************************************************************/
252 static BOOL
application_do_pushed_method (struct MUI_ApplicationData
*data
)
256 ObtainSemaphore(&data
->app_MethodSemaphore
);
258 if ((mq
= (struct MQNode
*)RemHead((struct List
*)&data
->app_MethodQueue
)))
260 ReleaseSemaphore(&data
->app_MethodSemaphore
);
262 DoMethodA(mq
->mq_Dest
, (Msg
)mq
->mq_Msg
);
266 ReleaseSemaphore(&data
->app_MethodSemaphore
);
270 static Object
*find_application_by_base(struct IClass
*cl
, Object
*obj
, STRPTR base
)
272 struct TrackingNode
*tn
;
273 Object
*retval
= NULL
;
275 ObtainSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
276 ForeachNode(&MUIMB(MUIMasterBase
)->Applications
, tn
)
280 get(tn
->tn_Application
, MUIA_Application_Base
, &tn_base
);
282 if (tn_base
&& (strcmp(base
, tn_base
)) == 0)
284 retval
= tn
->tn_Application
;
288 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
293 /**************************************************************************
295 **************************************************************************/
296 static IPTR
Application__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
298 struct MUI_ApplicationData
*data
;
299 struct TagItem
*tags
,*tag
;
300 BOOL bad_childs
= FALSE
, needrexx
= TRUE
;
302 obj
= (Object
*)DoSuperMethodA(cl
, obj
, (Msg
)msg
);
306 /* Initial local instance data */
307 data
= INST_DATA(cl
, obj
);
309 /* init input handler list */
310 NewList((struct List
*)&(data
->app_IHList
));
312 /* init input queue */
313 NewList((struct List
*)&(data
->app_MethodQueue
));
315 /* init return ids queue */
316 NewList((struct List
*)&(data
->app_ReturnIDQueue
));
319 data
->app_WindowFamily
= MUI_NewObjectA(MUIC_Family
, NULL
);
320 if (!data
->app_WindowFamily
)
322 CoerceMethod(cl
,obj
,OM_DISPOSE
);
326 data
->app_GlobalInfo
.mgi_ApplicationObject
= obj
;
327 if (!(data
->app_GlobalInfo
.mgi_WindowsPort
= CreateMsgPort()))
329 CoerceMethod(cl
,obj
,OM_DISPOSE
);
333 data
->app_Task
= FindTask(NULL
);
336 data
->app_SingleTask
= (BOOL
)GetTagData(MUIA_Application_SingleTask
, FALSE
,
338 data
->app_Base
= (STRPTR
)GetTagData(MUIA_Application_Base
, (IPTR
)"UNNAMED", msg
->ops_AttrList
);
339 if (!data
->app_Base
|| strpbrk(data
->app_Base
, " :/()#?*.,"))
341 data
->app_Base
= NULL
; /* don't remove */
342 CoerceMethod(cl
, obj
, OM_DISPOSE
);
347 if (!data
->app_SingleTask
)
349 /* must append .1, .2, ... to the base name */
353 for (i
= 1; i
< 1000; i
++)
355 snprintf(portname
, 255, "%s.%ld", data
->app_Base
, (LONG
)i
);
356 if (!find_application_by_base(cl
, obj
, portname
))
359 data
->app_Base
= StrDup(portname
);
365 ObtainSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
366 if ((other_app
= find_application_by_base(cl
, obj
, data
->app_Base
)))
368 //FIXME "Is calling MUIM_Application_PushMethod on an alien application object safe?"
369 DoMethod(other_app
, MUIM_Application_PushMethod
, (IPTR
)other_app
, 3,
370 MUIM_Set
, MUIA_Application_DoubleStart
, TRUE
);
371 data
->app_Base
= NULL
;
373 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
375 data
->app_Base
= StrDup(data
->app_Base
);
380 CoerceMethod(cl
, obj
, OM_DISPOSE
);
384 data
->app_GlobalInfo
.mgi_Configdata
=
385 MUI_NewObject(MUIC_Configdata
, MUIA_Configdata_Application
, obj
, TAG_DONE
);
386 if (!data
->app_GlobalInfo
.mgi_Configdata
)
388 CoerceMethod(cl
,obj
,OM_DISPOSE
);
391 get(data
->app_GlobalInfo
.mgi_Configdata
,MUIA_Configdata_ZunePrefs
,
392 &data
->app_GlobalInfo
.mgi_Prefs
);
394 // D(bug("muimaster.library/application.c: Message Port created at 0x%lx\n",
395 // data->app_GlobalInfo.mgi_WindowPort));
397 /* Setup timer stuff */
398 if (!(data
->app_TimerPort
= CreateMsgPort()))
400 CoerceMethod(cl
,obj
,OM_DISPOSE
);
404 if (!(data
->app_TimerReq
= (struct timerequest
*)CreateIORequest(data
->app_TimerPort
, sizeof(struct timerequest
))))
406 CoerceMethod(cl
,obj
,OM_DISPOSE
);
410 if (OpenDevice(TIMERNAME
, UNIT_VBLANK
, (struct IORequest
*)data
->app_TimerReq
, 0))
412 CoerceMethod(cl
,obj
,OM_DISPOSE
);
416 InitSemaphore(&data
->app_MethodSemaphore
);
418 muiNotifyData(obj
)->mnd_GlobalInfo
= &data
->app_GlobalInfo
;
420 /* parse initial taglist */
422 data
->app_Active
= 1;
423 data
->app_Title
= "Unnamed";
424 data
->app_Version
= "Unnamed 0.0";
425 data
->app_Description
= "?";
427 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem((const struct TagItem
**)&tags
)); )
431 case MUIA_Application_Author
:
432 data
->app_Author
= (STRPTR
)tag
->ti_Data
;
435 case MUIA_Application_Base
:
436 /* moved before config parsing */
439 case MUIA_Application_Copyright
:
440 data
->app_Copyright
= (STRPTR
)tag
->ti_Data
;
443 case MUIA_Application_Description
:
444 data
->app_Description
= (STRPTR
)tag
->ti_Data
;
447 case MUIA_Application_HelpFile
:
448 data
->app_HelpFile
= (STRPTR
)tag
->ti_Data
;
451 case MUIA_Application_SingleTask
:
452 /* moved before config parsing */
455 case MUIA_Application_Title
:
456 data
->app_Title
= (STRPTR
)tag
->ti_Data
;
459 case MUIA_Application_Version
:
460 data
->app_Version
= (STRPTR
)tag
->ti_Data
;
463 case MUIA_Application_Version_Number
:
464 data
->app_Version_Number
= (STRPTR
)tag
->ti_Data
;
467 case MUIA_Application_Version_Date
:
468 data
->app_Version_Date
= (STRPTR
)tag
->ti_Data
;
471 case MUIA_Application_Version_Extra
:
472 data
->app_Version_Extra
= (STRPTR
) tag
->ti_Data
;
475 case MUIA_Application_Window
:
476 if (tag
->ti_Data
) DoMethod(obj
,OM_ADDMEMBER
,tag
->ti_Data
);
477 else bad_childs
= TRUE
;
480 case MUIA_Application_Menustrip
:
481 data
->app_Menustrip
= (Object
*)tag
->ti_Data
;
484 case MUIA_Application_BrokerPri
:
485 data
->app_BrokerPri
= (BYTE
)tag
->ti_Data
;
488 case MUIA_Application_BrokerHook
:
489 data
->app_BrokerHook
= (struct Hook
*)tag
->ti_Data
;
492 case MUIA_Application_Active
:
493 data
->app_Active
= tag
->ti_Data
? TRUE
: FALSE
;
496 case MUIA_Application_UsedClasses
:
498 STRPTR
*list
= (STRPTR
*)tag
->ti_Data
;
502 struct IClass
*icl
= MUI_GetClass(*list
);
509 case MUIA_Application_UseRexx
:
510 needrexx
= tag
->ti_Data
? TRUE
: FALSE
;
515 /* create MUIA_Application_Version if NULL */
518 data
->app_Version
== NULL
519 && data
->app_Title
!= NULL
&& data
->app_Version_Number
!= NULL
522 STRPTR result
= NULL
;
525 /* Calculate length */
526 length
= strlen("$VER: ") + strlen(data
->app_Title
) + 1 /* space */
527 + strlen(data
->app_Version_Number
) + 1 /* NULL */;
529 if (data
->app_Version_Date
!= NULL
)
531 length
+= 1 /* space */ + 1 /* ( */
532 + strlen(data
->app_Version_Date
) + 1 /* ) */;
535 if (data
->app_Version_Extra
!= NULL
)
537 length
+= 1 /* space */ + 1 /* [ */
538 + strlen(data
->app_Version_Extra
) + 1 /* ] */;
541 /* Allocate memory */
542 result
= AllocVec(length
, MEMF_ANY
);
549 strlcat(result
, "$VER: ", length
);
550 strlcat(result
, data
->app_Title
, length
);
551 strlcat(result
, " ", length
);
552 strlcat(result
, data
->app_Version_Number
, length
);
554 if (data
->app_Version_Date
!= NULL
)
556 strlcat(result
, " (", length
);
557 strlcat(result
, data
->app_Version_Date
, length
);
558 strlcat(result
, ")", length
);
561 if (data
->app_Version_Extra
!= NULL
)
563 strlcat(result
, " [", length
);
564 strlcat(result
, data
->app_Version_Extra
, length
);
565 strlcat(result
, "]", length
);
568 data
->app_Version
= result
;
569 data
->app_VersionAllocated
= TRUE
;
576 CoerceMethod(cl
, obj
, OM_DISPOSE
);
580 if (CxBase
&& GetTagData(MUIA_Application_UseCommodities
, TRUE
, msg
->ops_AttrList
))
582 data
->app_BrokerPort
= CreateMsgPort();
584 if (data
->app_BrokerPort
)
588 nb
.nb_Version
= NB_VERSION
;
589 nb
.nb_Name
= data
->app_Title
? data
->app_Title
: (STRPTR
)"Unnamed";
590 nb
.nb_Title
= data
->app_Version
? data
->app_Version
: (STRPTR
)"Unnamed";
591 nb
.nb_Descr
= data
->app_Description
? data
->app_Description
: (STRPTR
)"?";
593 nb
.nb_Flags
= COF_SHOW_HIDE
;
594 nb
.nb_Pri
= data
->app_BrokerPri
;
595 nb
.nb_Port
= data
->app_BrokerPort
;
596 nb
.nb_ReservedChannel
= 0;
598 if (strncmp(nb
.nb_Title
, "$VER: ", 6) == 0) nb
.nb_Title
+= 6;
600 data
->app_Broker
= CxBroker(&nb
, 0);
602 if (data
->app_Broker
)
604 if (data
->app_Active
) ActivateCxObj(data
->app_Broker
, 1);
611 data
->app_RexxPort
= CreateMsgPort();
612 if (data
->app_RexxPort
)
614 data
->app_RexxPort
->mp_Node
.ln_Name
= StrDup(data
->app_Base
);
615 if (data
->app_RexxPort
->mp_Node
.ln_Name
!= NULL
)
618 for (i
= data
->app_RexxPort
->mp_Node
.ln_Name
; *i
!= '\0'; i
++)
622 AddPort(data
->app_RexxPort
);
626 DeleteMsgPort(data
->app_RexxPort
);
627 data
->app_RexxPort
= NULL
;
632 if (data
->app_Menustrip
) DoMethod(data
->app_Menustrip
, MUIM_ConnectParent
, (IPTR
)obj
);
634 ObtainSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
635 data
->app_TrackingNode
.tn_Application
= obj
;
636 AddTail((struct List
*)&MUIMB(MUIMasterBase
)->Applications
, (struct Node
*)&data
->app_TrackingNode
);
637 data
->app_is_TNode_in_list
= TRUE
;
638 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
645 /**************************************************************************
647 **************************************************************************/
648 static IPTR
Application__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
650 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
657 positionmode
=data
->app_GlobalInfo
.mgi_Prefs
->window_position
;
658 if (positionmode
>= 1)
660 snprintf(filename
, 255, "ENV:zune/%s.prefs", data
->app_Base
);
661 DoMethod(data
->app_GlobalInfo
.mgi_Configdata
, MUIM_Configdata_Save
, (IPTR
)filename
);
663 if (positionmode
== 2)
665 snprintf(filename
, 255, "ENVARC:zune/%s.prefs", data
->app_Base
);
666 DoMethod(data
->app_GlobalInfo
.mgi_Configdata
, MUIM_Configdata_Save
, (IPTR
)filename
);
670 if (data
->app_is_TNode_in_list
)
672 ObtainSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
673 Remove((struct Node
*)&data
->app_TrackingNode
);
674 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
677 if (data
->app_WindowFamily
)
679 struct MinList
*children
;
683 /* special loop because the next object may have been removed/freed by
684 * the previous. so restart from listhead each time.
688 get(data
->app_WindowFamily
, MUIA_Family_List
, &children
);
689 cstate
= (Object
*)children
->mlh_Head
;
690 if ((child
= NextObject(&cstate
)))
692 D(bug("Application_Dispose(%p) : OM_REMMEMBER(%p)\n", obj
, child
));
693 DoMethod(obj
, OM_REMMEMBER
, (IPTR
)child
);
694 D(bug("Application_Dispose(%p) : MUI_DisposeObject(%p)\n", obj
, child
));
695 MUI_DisposeObject(child
);
703 MUI_DisposeObject(data
->app_WindowFamily
);
706 if (data
->app_Menustrip
)
707 MUI_DisposeObject(data
->app_Menustrip
);
709 if (data
->app_VersionAllocated
&& data
->app_Version
!= NULL
)
711 FreeVec(data
->app_Version
);
714 /* free commodities stuff */
716 if (data
->app_Broker
)
718 DeleteCxObjAll(data
->app_Broker
);
721 if (data
->app_BrokerPort
)
725 while((msg
= GetMsg(data
->app_BrokerPort
)))
730 DeleteMsgPort(data
->app_BrokerPort
);
733 /* free timer stuff */
734 if (data
->app_TimerReq
)
736 if (data
->app_TimerReq
->tr_node
.io_Device
)
738 while (data
->app_TimerOutstanding
)
740 if (Wait(1L << data
->app_TimerPort
->mp_SigBit
| 4096) & 4096)
742 data
->app_TimerOutstanding
--;
744 CloseDevice((struct IORequest
*)data
->app_TimerReq
);
746 DeleteIORequest((struct IORequest
*)data
->app_TimerReq
);
748 if (data
->app_TimerPort
)
749 DeleteMsgPort(data
->app_TimerPort
);
751 if (data
->app_RexxPort
)
754 while((msg
= GetMsg(data
->app_RexxPort
)))
758 RemPort(data
->app_RexxPort
);
760 if (data
->app_RexxPort
->mp_Node
.ln_Name
!= NULL
) FreeVec(data
->app_RexxPort
->mp_Node
.ln_Name
);
762 DeleteMsgPort(data
->app_RexxPort
);
765 if (data
->app_GlobalInfo
.mgi_Configdata
)
766 MUI_DisposeObject(data
->app_GlobalInfo
.mgi_Configdata
);
768 if (data
->app_GlobalInfo
.mgi_WindowsPort
)
769 DeleteMsgPort(data
->app_GlobalInfo
.mgi_WindowsPort
);
771 FreeVec(data
->app_Base
);
773 /* free returnid stuff */
775 while ((rid
= (struct RIDNode
*)RemHead((struct List
*)&data
->app_ReturnIDQueue
)))
777 DeleteRIDNode(data
, rid
);
780 return DoSuperMethodA(cl
, obj
, msg
);
784 /**************************************************************************
786 **************************************************************************/
787 static IPTR
Application__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
789 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
790 struct TagItem
*tags
= msg
->ops_AttrList
;
793 /* There are many ways to find out what tag items provided by set()
794 ** we do know. The best way should be using NextTagItem() and simply
795 ** browsing through the list.
797 while ((tag
= NextTagItem((const struct TagItem
**)&tags
)) != NULL
)
803 case MUIA_Application_SearchWinId
:
804 data
->searchwinid
= tag
->ti_Data
;
807 case MUIA_Application_CopyWinPosToApp
:
808 addr
= (IPTR
*) tag
->ti_Data
;
809 CopyMem((CONST_APTR
) tag
->ti_Data
, &data
->winposused
, *(addr
));
812 case MUIA_Application_SetWinPos
:
814 struct windowpos
*winp
;
815 winp
= (struct windowpos
*) tag
->ti_Data
;
816 //kprintf("SetWinPos %d %d %d %d %d\n",winp->id,winp->x1,winp->y1,winp->w1,winp->h1);
818 for (i
= 0 ; i
< MAXWINS
-1 ; i
++)
820 if (data
->winpos
[i
].w1
)
822 if (winp
->id
== data
->winpos
[i
].id
) //existing entry is overwritten
824 data
->winpos
[i
].x1
= winp
->x1
;data
->winpos
[i
].y1
= winp
->y1
;
825 data
->winpos
[i
].w1
= winp
->w1
;data
->winpos
[i
].h1
= winp
->h1
;
826 data
->winpos
[i
].x2
= winp
->x2
;data
->winpos
[i
].y2
= winp
->y2
;
827 data
->winpos
[i
].w2
= winp
->w2
;data
->winpos
[i
].h2
= winp
->h2
;
832 { // a new entry is add
833 data
->winpos
[i
].id
= winp
->id
;
834 data
->winpos
[i
].x1
= winp
->x1
;data
->winpos
[i
].y1
= winp
->y1
;
835 data
->winpos
[i
].w1
= winp
->w1
;data
->winpos
[i
].h1
= winp
->h1
;
836 data
->winpos
[i
].x2
= winp
->x2
;data
->winpos
[i
].y2
= winp
->y2
;
837 data
->winpos
[i
].w2
= winp
->w2
;data
->winpos
[i
].h2
= winp
->h2
;
844 case MUIA_Application_Configdata
:
845 DoMethod(obj
, MUIM_Application_PushMethod
, (IPTR
)obj
, 2,
846 MUIM_Application_SetConfigdata
, tag
->ti_Data
);
849 case MUIA_Application_HelpFile
:
850 data
->app_HelpFile
= (STRPTR
)tag
->ti_Data
;
853 case MUIA_Application_Iconified
:
855 BOOL do_iconify
= tag
->ti_Data
== 1;
856 if (data
->app_Iconified
!= do_iconify
)
858 data
->app_Iconified
= do_iconify
;
860 nnset(obj
, MUIA_ShowMe
, !data
->app_Iconified
);
861 //FIXME "In case the WB is up, an appicon needs to be placed on the desktop"
868 /* Ok ok, you think this stinks? Well, think of it as
869 an attribute belonging to an interface which MUIC_Application,
870 together with MUIC_Area and a few others implement. It makes
876 get(obj
, MUIA_Application_WindowList
, &wlist
);
880 wstate
= wlist
->lh_Head
;
881 while ((curwin
= NextObject(&wstate
)))
883 set(curwin
, MUIA_ShowMe
, tag
->ti_Data
);
889 case MUIA_Application_Sleep
:
890 if (tag
->ti_Data
) data
->app_SleepCount
++;
891 else data
->app_SleepCount
--;
892 if (data
->app_SleepCount
< 0)
893 data
->app_SleepCount
= 0;
897 * todo SC == 0 (wakeup), SC == 1 (sleep)
902 case MUIA_Application_MenuAction
:
903 data
->app_MenuAction
= tag
->ti_Data
;
906 case MUIA_Application_BrokerHook
:
907 data
->app_BrokerHook
= (struct Hook
*)tag
->ti_Data
;
910 case MUIA_Application_Active
:
911 data
->app_Active
= tag
->ti_Data
? TRUE
: FALSE
;
912 if (data
->app_Broker
)
914 ActivateCxObj(data
->app_Broker
, data
->app_Active
);
921 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
928 static IPTR
Application__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
930 #define STORE *(msg->opg_Storage)
932 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
934 switch(msg
->opg_AttrID
)
936 case MUIA_Application_GetWinPosAddr
:
937 STORE
= (IPTR
) &data
->winposused
;
940 case MUIA_Application_GetWinPosSize
:
943 for (i
=0 ; i
< MAXWINS
-1 ; i
++)
945 if (!data
->winpos
[i
].w1
)
947 i
*= sizeof (struct windowpos
);
958 case MUIA_Application_GetWinPos
:
961 if (data
->searchwinid
)
963 for (i
=0 ; i
< MAXWINS
-1 ; i
++)
965 if (data
->winpos
[i
].w1
)
967 if (data
->searchwinid
== data
->winpos
[i
].id
)
969 STORE
= (IPTR
) &data
->winpos
[i
].id
;
990 case MUIA_Application_Author
:
991 STORE
= (IPTR
)data
->app_Author
;
994 case MUIA_Application_Base
:
995 STORE
= (IPTR
)data
->app_Base
;
998 case MUIA_Application_Copyright
:
999 STORE
= (IPTR
)data
->app_Copyright
;
1002 case MUIA_Application_Description
:
1003 STORE
= (IPTR
)data
->app_Description
;
1006 case MUIA_Application_DoubleStart
:
1009 case MUIA_Application_ForceQuit
:
1010 STORE
= (IPTR
)data
->app_ForceQuit
;
1013 case MUIA_Application_HelpFile
:
1014 STORE
= (IPTR
)data
->app_HelpFile
;
1017 case MUIA_Application_Iconified
:
1018 STORE
= (IPTR
)data
->app_Iconified
;
1021 case MUIA_Application_Title
:
1022 STORE
= (IPTR
)data
->app_Title
;
1025 case MUIA_Application_Version
:
1026 STORE
= (IPTR
)data
->app_Version
;
1029 case MUIA_Application_Version_Number
:
1030 STORE
= (IPTR
) data
->app_Version_Number
;
1033 case MUIA_Application_Version_Date
:
1034 STORE
= (IPTR
) data
->app_Version_Date
;
1037 case MUIA_Application_Version_Extra
:
1038 STORE
= (IPTR
) data
->app_Version_Extra
;
1041 case MUIA_Application_WindowList
:
1042 return GetAttr(MUIA_Family_List
, data
->app_WindowFamily
, msg
->opg_Storage
);
1044 case MUIA_Application_Menustrip
:
1045 STORE
= (IPTR
)data
->app_Menustrip
;
1048 case MUIA_Application_MenuAction
:
1049 STORE
= (IPTR
)data
->app_MenuAction
;
1052 case MUIA_Application_BrokerPort
:
1053 STORE
= (IPTR
)data
->app_BrokerPort
;
1056 case MUIA_Application_BrokerPri
:
1057 STORE
= (IPTR
)data
->app_BrokerPri
;
1060 case MUIA_Application_BrokerHook
:
1061 STORE
= (IPTR
)data
->app_BrokerHook
;
1064 case MUIA_Application_Broker
:
1065 STORE
= (IPTR
)data
->app_Broker
;
1068 case MUIA_Application_Active
:
1069 STORE
= data
->app_Active
;
1073 /* our handler didn't understand the attribute, we simply pass
1074 ** it to our superclass now
1076 return(DoSuperMethodA(cl
, obj
, (Msg
) msg
));
1081 /**************************************************************************
1083 **************************************************************************/
1084 static IPTR
Application__OM_ADDMEMBER(struct IClass
*cl
, Object
*obj
, struct opMember
*msg
)
1086 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1088 D(bug("Application_AddMember: Adding 0x%lx to window member list\n",msg
->opam_Object
));
1090 DoMethodA(data
->app_WindowFamily
, (Msg
)msg
);
1091 /* Application knows its GlobalInfo, so we can inform window */
1092 DoMethod(msg
->opam_Object
, MUIM_ConnectParent
, (IPTR
)obj
);
1097 /**************************************************************************
1099 **************************************************************************/
1100 static IPTR
Application__OM_REMMEMBER(struct IClass
*cl
, Object
*obj
, struct opMember
*msg
)
1102 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1104 D(bug("Application_RemMember: Removing 0x%lx from window member list\n",msg
->opam_Object
));
1106 DoMethod(msg
->opam_Object
, MUIM_DisconnectParent
);
1107 DoMethodA(data
->app_WindowFamily
, (Msg
)msg
);
1113 /**************************************************************************
1114 MUIM_Application_AddInputHandler
1115 **************************************************************************/
1116 static IPTR
Application__MUIM_AddInputHandler(struct IClass
*cl
, Object
*obj
,
1117 struct MUIP_Application_AddInputHandler
*msg
)
1119 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1121 if (msg
->ihnode
->ihn_Flags
& MUIIHNF_TIMER
)
1123 struct timerequest_ext
*time_ext
= (struct timerequest_ext
*)AllocVec(sizeof(struct timerequest_ext
),MEMF_PUBLIC
);
1126 /* Store the request inside the input handler, so the we can remove
1127 ** the inputhandler without problems */
1128 msg
->ihnode
->ihn_Node
.mln_Pred
= (struct MinNode
*)time_ext
;
1130 time_ext
->treq
= *data
->app_TimerReq
;
1131 time_ext
->treq
.tr_node
.io_Command
= TR_ADDREQUEST
;
1132 time_ext
->treq
.tr_time
.tv_secs
= msg
->ihnode
->ihn_Millis
/1000;
1133 time_ext
->treq
.tr_time
.tv_micro
= (msg
->ihnode
->ihn_Millis
%1000)*1000;
1134 time_ext
->ihn
= msg
->ihnode
;
1135 SendIO((struct IORequest
*)time_ext
);
1137 } else AddTail((struct List
*)&data
->app_IHList
, (struct Node
*)msg
->ihnode
);
1142 /**************************************************************************
1143 MUIM_Application_RemInputHandler
1144 **************************************************************************/
1145 static IPTR
Application__MUIM_RemInputHandler(struct IClass
*cl
, Object
*obj
, struct MUIP_Application_RemInputHandler
*msg
)
1147 //struct MUI_ApplicationData *data = INST_DATA(cl, obj);
1148 if (msg
->ihnode
->ihn_Flags
& MUIIHNF_TIMER
)
1150 struct timerequest_ext
*time_ext
= (struct timerequest_ext
*)msg
->ihnode
->ihn_Node
.mln_Pred
;
1151 if (!CheckIO((struct IORequest
*)time_ext
)) AbortIO((struct IORequest
*)time_ext
);
1152 WaitIO((struct IORequest
*)time_ext
);
1154 } else Remove((struct Node
*)msg
->ihnode
);
1160 void _zune_window_message(struct IntuiMessage
*imsg
); /* from window.c */
1163 * MUIM_Application_InputBuffered : process all pending events
1165 static IPTR
Application__MUIM_InputBuffered(struct IClass
*cl
, Object
*obj
,
1166 struct MUIP_Application_InputBuffered
*msg
)
1168 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1169 struct IntuiMessage
*imsg
;
1171 /* process all pushed methods */
1172 while (application_do_pushed_method(data
))
1175 imsg
= (struct IntuiMessage
*)GetMsg(data
->app_GlobalInfo
.mgi_WindowsPort
);
1178 /* Let window object process message */
1179 _zune_window_message(imsg
); /* will reply the message */
1184 /**************************************************************************
1185 MUIM_Application_NewInput : application main loop
1186 **************************************************************************/
1187 static IPTR
Application__MUIM_NewInput(struct IClass
*cl
, Object
*obj
, struct MUIP_Application_NewInput
*msg
)
1189 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1190 struct RIDNode
*rid
;
1192 ULONG signal
, signalmask
;
1193 ULONG handler_mask
= 0; /* the mask of the signal handlers */
1196 //struct MinNode ihn_Node;
1198 signal
= *msg
->signal
;
1200 /* process all pushed methods */
1201 while (application_do_pushed_method(data
))
1204 /* query the signal for the handlers */
1205 for (mn
= data
->app_IHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
1207 struct MUI_InputHandlerNode
*ihn
;
1208 ihn
= (struct MUI_InputHandlerNode
*)mn
;
1209 handler_mask
|= ihn
->ihn_Signals
;
1212 signalmask
= (1L << data
->app_GlobalInfo
.mgi_WindowsPort
->mp_SigBit
)
1213 | (1L << data
->app_TimerPort
->mp_SigBit
) | handler_mask
;
1215 if (data
->app_Broker
)
1216 signalmask
|= (1L << data
->app_BrokerPort
->mp_SigBit
);
1220 /* Stupid app which (always) passes 0 in signals. It's impossible to
1221 know which signals were really set as the app will already have
1222 called Wait() which has cleared the task's tc_SigRecvd. So assume
1223 the window, timer, and broker signals all to be set. Also all of
1224 the inputhandler signals (MUI does that too). */
1226 signal
= signalmask
;
1229 if (signal
& signalmask
)
1231 if (signal
& (1L << data
->app_GlobalInfo
.mgi_WindowsPort
->mp_SigBit
))
1233 struct IntuiMessage
*imsg
;
1234 /* process all pushed methods */
1236 while ((imsg
= (struct IntuiMessage
*)GetMsg(data
->app_GlobalInfo
.mgi_WindowsPort
)))
1238 /* Let window object process message */
1239 _zune_window_message(imsg
); /* will reply the message */
1243 if (signal
& (1L << data
->app_TimerPort
->mp_SigBit
))
1245 struct timerequest_ext
*time_ext
;
1250 /* At first we fetch all messages from the message port and store them
1251 ** in a list, we use the node of the Message here */
1252 while ((time_ext
= (struct timerequest_ext
*)GetMsg(data
->app_TimerPort
)))
1253 AddTail(&list
,(struct Node
*)time_ext
);
1255 /* Now we proccess the list and resend the timer io, no loop can happen
1256 ** we use RemHead() because the handler can remove it itself and so
1257 ** a FreeVec() could happen in MUIM_Application_RemInputHandler which would
1258 ** destroy the the ln->Succ of course */
1259 while ((n
= RemHead(&list
)))
1261 struct timerequest_ext
*time_ext
= (struct timerequest_ext
*)n
;
1262 struct MUI_InputHandlerNode
*ihn
= time_ext
->ihn
;
1263 time_ext
->treq
.tr_time
.tv_secs
= time_ext
->ihn
->ihn_Millis
/1000;
1264 time_ext
->treq
.tr_time
.tv_micro
= (time_ext
->ihn
->ihn_Millis
%1000)*1000;
1265 SendIO((struct IORequest
*)&time_ext
->treq
);
1266 DoMethod(ihn
->ihn_Object
,ihn
->ihn_Method
);
1270 if (data
->app_BrokerPort
&& (signal
& (1L << data
->app_BrokerPort
->mp_SigBit
)))
1274 while((msg
= (CxMsg
*)GetMsg(data
->app_BrokerPort
)))
1276 switch(CxMsgType(msg
))
1279 switch(CxMsgID(msg
))
1282 set(obj
, MUIA_Application_Active
, FALSE
);
1286 set(obj
, MUIA_Application_Active
, TRUE
);
1290 set(obj
, MUIA_Application_Iconified
, FALSE
);
1293 case CXCMD_DISAPPEAR
:
1294 set(obj
, MUIA_Application_Iconified
, TRUE
);
1298 SetSignal(SIGBREAKF_CTRL_C
, SIGBREAKF_CTRL_C
);
1304 if (data
->app_BrokerHook
)
1306 CallHookPkt(data
->app_BrokerHook
, obj
, msg
);
1309 ReplyMsg((struct Message
*)msg
);
1313 if (signal
& handler_mask
)
1315 for (mn
= data
->app_IHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
1317 struct MUI_InputHandlerNode
*ihn
;
1318 ihn
= (struct MUI_InputHandlerNode
*)mn
;
1319 if (signal
& ihn
->ihn_Signals
) DoMethod(ihn
->ihn_Object
,ihn
->ihn_Method
);
1324 /* process all pushed methods - again */
1325 while (application_do_pushed_method(data
))
1328 *msg
->signal
= signalmask
;
1330 /* set return code */
1331 if ((rid
= (struct RIDNode
*)RemHead((struct List
*)&data
->app_ReturnIDQueue
)))
1333 retval
= rid
->rid_Value
;
1334 DeleteRIDNode(data
, rid
);
1340 /**************************************************************************
1341 MUIM_Application_Input : application main loop
1342 This method shouldn't be used in new programm. As it polls all signals.
1343 **************************************************************************/
1344 static IPTR
Application__MUIM_Input(struct IClass
*cl
, Object
*obj
, struct MUIP_Application_Input
*msg
)
1346 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1347 ULONG signal
= 0, handler_mask
= 0;
1350 /* query the signal for the handlers */
1351 for (mn
= data
->app_IHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
1353 struct MUI_InputHandlerNode
*ihn
;
1354 ihn
= (struct MUI_InputHandlerNode
*)mn
;
1355 handler_mask
|= ihn
->ihn_Flags
;
1358 signal
= (1L << data
->app_GlobalInfo
.mgi_WindowsPort
->mp_SigBit
)
1359 | (1L << data
->app_TimerPort
->mp_SigBit
) | handler_mask
;
1360 *msg
->signal
= signal
;
1361 return Application__MUIM_NewInput(cl
, obj
, (APTR
)msg
);
1364 /**************************************************************************
1365 MUIM_Application_PushMethod: Add a method in the method FIFO. Will
1366 be executed in the next event loop.
1367 **************************************************************************/
1368 static IPTR
Application__MUIM_PushMethod(struct IClass
*cl
, Object
*obj
, struct MUIP_Application_PushMethod
*msg
)
1370 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1373 IPTR
*m
= (IPTR
*)&msg
->count
; /* Warning, it will break on 64-bit BigEndian systems!!! */
1375 mq
= CreateMQNode(msg
->count
);
1377 mq
->mq_Dest
= msg
->dest
;
1380 for (i
= 0; i
< msg
->count
; i
++)
1381 mq
->mq_Msg
[i
] = *(m
+ 1 + i
);
1383 /* enqueue method */
1384 ObtainSemaphore(&data
->app_MethodSemaphore
);
1385 AddTail((struct List
*)&data
->app_MethodQueue
, (struct Node
*)mq
);
1386 ReleaseSemaphore(&data
->app_MethodSemaphore
);
1388 /* CHECKME: to wake task up as soon as possible! */
1389 Signal(data
->app_Task
, 1L << data
->app_GlobalInfo
.mgi_WindowsPort
->mp_SigBit
);
1396 * MUIM_Application_ReturnID : Tell MUI to return the given id with
1397 * the next call to MUIM_Application_NewInput. kinda obsolete :)
1399 static IPTR
Application__MUIM_ReturnID(struct IClass
*cl
, Object
*obj
,
1400 struct MUIP_Application_ReturnID
*msg
)
1402 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1403 struct RIDNode
*rid
;
1406 if (!data->app_RIDMemChunk)
1408 data->app_RIDMemChunk =
1409 g_mem_chunk_create(struct RIDNode, 10, G_ALLOC_AND_FREE);
1412 rid
= CreateRIDNode(data
, msg
->retid
);
1415 AddTail((struct List
*)&data
->app_ReturnIDQueue
, (struct Node
*)rid
);
1421 * MUIM_FindUData : tests if the MUIA_UserData of the object
1422 * contains the given <udata> and returns the object pointer in this case.
1424 static IPTR
Application__MUIM_FindUData(struct IClass
*cl
, Object
*obj
, struct MUIP_FindUData
*msg
)
1426 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1428 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
1431 return DoMethodA(data
->app_WindowFamily
, (Msg
)msg
);
1436 * MUIM_GetUData : This method tests if the MUIA_UserData of the object
1437 * contains the given <udata> and gets <attr> to <storage> for itself
1440 static IPTR
Application__MUIM_GetUData(struct IClass
*cl
, Object
*obj
, struct MUIP_GetUData
*msg
)
1442 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1444 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
1446 get(obj
, msg
->attr
, msg
->storage
);
1449 return DoMethodA(data
->app_WindowFamily
, (Msg
)msg
);
1454 * MUIM_SetUData : This method tests if the MUIA_UserData of the object
1455 * contains the given <udata> and sets <attr> to <val> for itself in this case.
1457 static IPTR
Application__MUIM_SetUData(struct IClass
*cl
, Object
*obj
, struct MUIP_SetUData
*msg
)
1459 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1461 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
1462 set(obj
, msg
->attr
, msg
->val
);
1464 DoMethodA(data
->app_WindowFamily
, (Msg
)msg
);
1470 * MUIM_SetUDataOnce : This method tests if the MUIA_UserData of the object
1471 * contains the given <udata> and sets <attr> to <val> for itself in this case.
1473 static IPTR
Application__MUIM_SetUDataOnce(struct IClass
*cl
, Object
*obj
, struct MUIP_SetUDataOnce
*msg
)
1475 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1477 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
1479 set(obj
, msg
->attr
, msg
->val
);
1482 return DoMethodA(data
->app_WindowFamily
, (Msg
)msg
);
1486 /**************************************************************************
1487 MUIM_Application_AboutMUI: brought up the about window, centered on refwindow
1488 **************************************************************************/
1489 static IPTR
Application__MUIM_AboutMUI(struct IClass
*cl
, Object
*obj
, struct MUIP_Application_AboutMUI
*msg
)
1491 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1493 if (!data
->app_AboutWin
)
1495 data
->app_AboutWin
= AboutmuiObject
,
1496 msg
->refwindow
? MUIA_Window_RefWindow
: TAG_IGNORE
, msg
->refwindow
,
1497 MUIA_Window_LeftEdge
, MUIV_Window_LeftEdge_Centered
,
1498 MUIA_Window_TopEdge
, MUIV_Window_TopEdge_Centered
,
1499 MUIA_Aboutmui_Application
, obj
,
1501 if (!data
->app_AboutWin
)
1503 DoMethod(data
->app_AboutWin
, MUIM_Notify
, MUIA_Window_CloseRequest
, TRUE
,
1504 (IPTR
)obj
, 3, MUIM_WriteLong
, 0L, (IPTR
)&data
->app_AboutWin
);
1505 } /* if (!data->app_AboutWin) */
1507 if (data
->app_AboutWin
)
1510 set(data
->app_AboutWin
, MUIA_Window_Open
, TRUE
);
1515 static IPTR
Application__MUIM_SetConfigdata(struct IClass
*cl
, Object
*obj
,
1516 struct MUIP_Application_SetConfigdata
*msg
)
1518 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1519 struct MinList
*children
;
1523 get(data
->app_WindowFamily
, MUIA_Family_List
, &children
);
1524 cstate
= (Object
*)children
->mlh_Head
;
1525 if ((child
= NextObject(&cstate
)))
1527 D(bug("closing window %p\n", child
));
1529 set(child
, MUIA_Window_Open
, FALSE
);
1532 if (data
->app_GlobalInfo
.mgi_Configdata
)
1533 MUI_DisposeObject(data
->app_GlobalInfo
.mgi_Configdata
);
1534 data
->app_GlobalInfo
.mgi_Configdata
= msg
->configdata
;
1535 get(data
->app_GlobalInfo
.mgi_Configdata
,MUIA_Configdata_ZunePrefs
,
1536 &data
->app_GlobalInfo
.mgi_Prefs
);
1538 DoMethod(obj
, MUIM_Application_PushMethod
, (IPTR
)obj
, 1, MUIM_Application_OpenWindows
);
1543 /* MUIM_Application_OpenWindows
1544 * Opens all windows of an application
1546 static IPTR
Application__MUIM_OpenWindows(struct IClass
*cl
, Object
*obj
,
1547 struct MUIP_Application_OpenWindows
*msg
)
1549 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1550 struct MinList
*children
;
1554 get(data
->app_WindowFamily
, MUIA_Family_List
, &children
);
1555 cstate
= (Object
*)children
->mlh_Head
;
1556 if ((child
= NextObject(&cstate
)))
1558 set(child
, MUIA_Window_Open
, TRUE
);
1564 static IPTR
Application__MUIM_OpenConfigWindow(struct IClass
*cl
, Object
*obj
,
1565 struct MUIP_Application_OpenConfigWindow
*msg
)
1567 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1568 struct TagItem tags
[] =
1570 { SYS_Asynch
, FALSE
},
1573 { NP_StackSize
, AROS_STACKSIZE
},
1578 snprintf(cmd
, 255, "sys:prefs/Zune %s %d", data
->app_Base
? data
->app_Base
: (STRPTR
) "", (int) obj
);
1580 if (SystemTagList(cmd
, tags
) == -1)
1588 snprintf(cmd
, 255, "ENV:zune/%s.prefs", data
->app_Base
);
1589 DoMethod(data
->app_GlobalInfo
.mgi_Configdata
, MUIM_Configdata_Load
, (IPTR
)cmd
);
1595 static IPTR
Application__MUIM_Execute(Class
*CLASS
, Object
*self
, Msg message
)
1601 DoMethod(self
, MUIM_Application_NewInput
, (IPTR
) &signals
)
1602 != MUIV_Application_ReturnID_Quit
1607 signals
= Wait(signals
| SIGBREAKF_CTRL_C
);
1608 if (signals
& SIGBREAKF_CTRL_C
) break;
1616 static IPTR
Application__MUIM_UpdateMenus(struct IClass
*cl
, Object
*obj
, Msg message
)
1622 get(obj
, MUIA_Application_WindowList
, &wlist
);
1626 wstate
= wlist
->lh_Head
;
1627 while ((curwin
= NextObject(&wstate
)))
1629 DoMethod(curwin
, MUIM_Window_UpdateMenu
);
1636 static IPTR
Application__MUIM_Load(struct IClass
*cl
, Object
*obj
, struct MUIP_Application_Load
*message
)
1638 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1639 struct IFFHandle
*iff
;
1643 struct MinList
*children
;
1650 dataspace
= MUI_NewObject(MUIC_Dataspace
, TAG_DONE
);
1654 if(message
->name
== MUIV_Application_Load_ENV
)
1655 snprintf(name
, sizeof(name
), "ENV:Zune/%s.cfg", data
->app_Base
);
1656 else if(message
->name
== MUIV_Application_Load_ENVARC
)
1657 snprintf(name
, sizeof(name
), "ENVARC:Zune/%s.cfg", data
->app_Base
);
1659 strncpy(name
, message
->name
, sizeof(name
));
1661 fh
= Open(name
, MODE_OLDFILE
);
1664 if ((iff
= AllocIFF()))
1666 iff
->iff_Stream
= (IPTR
) fh
;
1670 if (!OpenIFF(iff
, IFFF_READ
))
1672 if (!StopChunk(iff
, ID_PREF
, ID_MUIO
))
1674 if (!ParseIFF(iff
, IFFPARSE_SCAN
))
1676 DoMethod(dataspace
, MUIM_Dataspace_ReadIFF
, iff
, ID_PREF
, ID_MUIO
);
1687 get(data
->app_WindowFamily
, MUIA_Family_List
, &children
);
1688 cstate
= (Object
*)children
->mlh_Head
;
1689 while ((child
= NextObject(&cstate
)))
1691 DoMethod(child
, MUIM_Import
, dataspace
);
1694 MUI_DisposeObject(dataspace
);
1699 static IPTR
Application__MUIM_Save(struct IClass
*cl
, Object
*obj
, struct MUIP_Application_Save
*message
)
1701 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1702 struct IFFHandle
*iff
;
1706 struct MinList
*children
;
1713 dataspace
= MUI_NewObject(MUIC_Dataspace
, TAG_DONE
);
1717 get(data
->app_WindowFamily
, MUIA_Family_List
, &children
);
1718 cstate
= (Object
*)children
->mlh_Head
;
1719 while ((child
= NextObject(&cstate
)))
1721 DoMethod(child
, MUIM_Export
, dataspace
);
1724 if(message
->name
== MUIV_Application_Save_ENV
)
1725 snprintf(name
, sizeof(name
), "ENV:Zune/%s.cfg", data
->app_Base
);
1726 else if(message
->name
== MUIV_Application_Save_ENVARC
)
1727 snprintf(name
, sizeof(name
), "ENVARC:Zune/%s.cfg", data
->app_Base
);
1729 strncpy(name
, message
->name
, sizeof(name
));
1731 fh
= Open(name
, MODE_NEWFILE
);
1734 if ((iff
= AllocIFF()))
1736 iff
->iff_Stream
= (IPTR
) fh
;
1740 if (!OpenIFF(iff
, IFFF_WRITE
))
1742 if (!PushChunk(iff
, ID_PREF
, ID_FORM
, IFFSIZE_UNKNOWN
))
1744 if (!PushChunk(iff
, ID_PREF
, ID_PRHD
, sizeof(struct FilePrefHeader
)))
1746 struct FilePrefHeader head
;
1748 head
.ph_Version
= PHV_CURRENT
;
1753 head
.ph_Flags
[3] = 0;
1755 if (WriteChunkBytes(iff
, &head
, sizeof(head
)) == sizeof(head
))
1758 DoMethod(dataspace
, MUIM_Dataspace_WriteIFF
, iff
, ID_PREF
, ID_MUIO
);
1774 MUI_DisposeObject(dataspace
);
1780 * The class dispatcher
1782 BOOPSI_DISPATCHER(IPTR
, Application_Dispatcher
, cl
, obj
, msg
)
1784 switch (msg
->MethodID
)
1786 case OM_NEW
: return Application__OM_NEW(cl
, obj
, (struct opSet
*) msg
);
1787 case OM_DISPOSE
: return Application__OM_DISPOSE(cl
, obj
, msg
);
1788 case OM_SET
: return Application__OM_SET(cl
, obj
, (struct opSet
*)msg
);
1789 case OM_GET
: return Application__OM_GET(cl
, obj
, (struct opGet
*)msg
);
1790 case OM_ADDMEMBER
: return Application__OM_ADDMEMBER(cl
, obj
, (APTR
)msg
);
1791 case OM_REMMEMBER
: return Application__OM_REMMEMBER(cl
, obj
, (APTR
)msg
);
1792 case MUIM_Application_AddInputHandler
: return Application__MUIM_AddInputHandler(cl
, obj
, (APTR
)msg
);
1793 case MUIM_Application_RemInputHandler
: return Application__MUIM_RemInputHandler(cl
, obj
, (APTR
)msg
);
1794 case MUIM_Application_Input
: return Application__MUIM_Input(cl
, obj
, (APTR
)msg
);
1795 case MUIM_Application_InputBuffered
: return Application__MUIM_InputBuffered(cl
, obj
, (APTR
)msg
);
1796 case MUIM_Application_NewInput
: return Application__MUIM_NewInput(cl
, obj
, (APTR
)msg
);
1797 case MUIM_Application_PushMethod
: return Application__MUIM_PushMethod(cl
, obj
, (APTR
)msg
);
1798 case MUIM_Application_ReturnID
: return Application__MUIM_ReturnID(cl
, obj
, (APTR
)msg
);
1799 case MUIM_FindUData
: return Application__MUIM_FindUData(cl
, obj
, (APTR
)msg
);
1800 case MUIM_GetUData
: return Application__MUIM_GetUData(cl
, obj
, (APTR
)msg
);
1801 case MUIM_SetUData
: return Application__MUIM_SetUData(cl
, obj
, (APTR
)msg
);
1802 case MUIM_SetUDataOnce
: return Application__MUIM_SetUDataOnce(cl
, obj
, (APTR
)msg
);
1803 case MUIM_Application_AboutMUI
: return Application__MUIM_AboutMUI(cl
, obj
, (APTR
)msg
);
1804 case MUIM_Application_SetConfigdata
: return Application__MUIM_SetConfigdata(cl
, obj
, (APTR
)msg
);
1805 case MUIM_Application_OpenWindows
: return Application__MUIM_OpenWindows(cl
, obj
, (APTR
)msg
);
1806 case MUIM_Application_OpenConfigWindow
: return Application__MUIM_OpenConfigWindow(cl
, obj
, (APTR
)msg
);
1807 case MUIM_Application_Execute
: return Application__MUIM_Execute(cl
, obj
, msg
);
1808 case MUIM_Application_UpdateMenus
: return Application__MUIM_UpdateMenus(cl
, obj
, msg
);
1809 case MUIM_Application_Load
: return Application__MUIM_Load(cl
, obj
, (APTR
) msg
);
1810 case MUIM_Application_Save
: return Application__MUIM_Save(cl
, obj
, (APTR
) msg
);
1813 return(DoSuperMethodA(cl
, obj
, msg
));
1815 BOOPSI_DISPATCHER_END
1820 const struct __MUIBuiltinClass _MUI_Application_desc
= {
1823 sizeof(struct MUI_ApplicationData
),
1824 (void*)Application_Dispatcher