2 Copyright © 1999, David Le Corfec.
3 Copyright © 2002-2013, 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
97 struct windowpos winpos
[MAXWINS
];
98 struct MsgPort
*app_RexxPort
;
99 struct RexxMsg
*app_RexxMsg
;
100 struct Hook
*app_RexxHook
;
101 struct MUI_Command
*app_Commands
;
102 STRPTR app_RexxString
;
104 struct MsgPort
*app_AppPort
; /* Port for AppIcon/AppMenu/AppWindow */
105 struct AppIcon
*app_AppIcon
;
106 struct DiskObject
*app_DiskObject
; /* This is only pointer to
107 * client-managed object */
108 struct DiskObject
*app_DefaultDiskObject
; /* This is complete
113 struct timerequest_ext
115 struct timerequest treq
;
116 struct MUI_InputHandlerNode
*ihn
;
120 * Application class is the master class for all
121 * MUI applications. It serves as a kind of anchor
122 * for all input, either coming from the user or
123 * somewhere from the system, e.g. commodities
124 * or ARexx messages. (hemm forget theses last 2 for Zune :)
126 * An application can have any number of sub windows,
127 * these windows are the children of the application.
128 * (FYI, it delegates child handling to a Family object).
132 MUIA_Application_Active [ISG] done
133 MUIA_Application_Author [I.G] done
134 MUIA_Application_Base [I.G] done
135 MUIA_Application_Broker [..G] done
136 MUIA_Application_BrokerHook [ISG] done
137 MUIA_Application_BrokerPort [..G] done
138 MUIA_Application_BrokerPri [I.G] done
139 MUIA_Application_Commands [ISG] needs Arexx
140 MUIA_Application_Copyright [I.G] done
141 MUIA_Application_Description [I.G] done
142 MUIA_Application_DiskObject [ISG] done
143 MUIA_Application_DoubleStart [..G] not triggered yet (todo)
144 MUIA_Application_DropObject [IS.] todo
145 MUIA_Application_ForceQuit [..G] not triggered yet
146 MUIA_Application_HelpFile [ISG] unused/dummy
147 MUIA_Application_Iconified [.SG] done
148 MUIA_Application_Menu [I.G] unimplemented (OBSOLETE)
149 MUIA_Application_MenuAction [..G] done
150 MUIA_Application_MenuHelp [..G] todo (ditto)
151 MUIA_Application_Menustrip [I..] done
152 MUIA_Application_RexxHook [ISG] needs Arexx
153 MUIA_Application_RexxMsg [..G] needs Arexx
154 MUIA_Application_RexxString [.S.] needs Arexx
155 MUIA_Application_SingleTask [I..] done
156 MUIA_Application_Sleep [.S.] todo
157 MUIA_Application_Title [I.G] done
158 MUIA_Application_UseCommodities [I..] done
159 MUIA_Application_UseRexx [I..] done
160 MUIA_Application_Version [I.G] done
161 MUIA_Application_Window [I..] done
162 MUIA_Application_WindowList [..G] done
166 MUIM_Application_AboutMUI todo
167 MUIM_Application_AddInputHandler done ?
168 MUIM_Application_CheckRefresh todo (implementable ?)
169 MUIM_Application_GetMenuCheck OBSOLETE
170 MUIM_Application_GetMenuState OBSOLETE
171 MUIM_Application_Input OBSOLETE
172 MUIM_Application_InputBuffered todo
173 MUIM_Application_Load
174 MUIM_Application_NewInput done
175 MUIM_Application_OpenConfigWindow
176 MUIM_Application_PushMethod
177 MUIM_Application_RemInputHandler done ?
178 MUIM_Application_ReturnID done
179 MUIM_Application_Save
180 MUIM_Application_SetConfigItem
181 MUIM_Application_SetMenuCheck
182 MUIM_Application_SetMenuState
183 MUIM_Application_ShowHelp
185 Notify.mui/MUIM_FindUData done
186 Notify.mui/MUIM_GetUData done
187 Notify.mui/MUIM_SetUData done
188 Notify.mui/MUIM_SetUDataOnce done
191 static const int __version
= 1;
192 static const int __revision
= 1;
200 struct MinNode mq_Node
;
209 struct FilePrefHeader
216 #define ID_MUIO MAKE_ID('M','U','I','O')
219 * Allocates an MethodQueue Method
221 static struct MQNode
*CreateMQNode(LONG count
)
225 mq
= (struct MQNode
*)mui_alloc(sizeof(struct MQNode
) +
226 (count
* sizeof(IPTR
)));
230 mq
->mq_Count
= count
;
231 mq
->mq_Msg
= (IPTR
*) (((char *)mq
) + sizeof(struct MQNode
));
236 * Free an IQ Method got from CreateIQMethod()
238 static void DeleteMQNode(struct MQNode
*mq
)
245 * Queue of Return IDs
249 struct MinNode rid_Node
;
254 static struct RIDNode
*CreateRIDNode(struct MUI_ApplicationData
*data
,
259 if ((rid
= mui_alloc_struct(struct RIDNode
)))
261 rid
->rid_Value
= retid
;
267 static void DeleteRIDNode(struct MUI_ApplicationData
*data
,
274 /**************************************************************************
275 Process a pushed method.
276 **************************************************************************/
277 static BOOL
application_do_pushed_method(struct MUI_ApplicationData
*data
)
281 ObtainSemaphore(&data
->app_MethodSemaphore
);
283 if ((mq
= (struct MQNode
*)RemHead((struct List
*)&data
->app_MethodQueue
)))
285 ReleaseSemaphore(&data
->app_MethodSemaphore
);
287 DoMethodA(mq
->mq_Dest
, (Msg
) mq
->mq_Msg
);
291 ReleaseSemaphore(&data
->app_MethodSemaphore
);
295 static Object
*find_application_by_base(struct IClass
*cl
, Object
*obj
,
298 struct TrackingNode
*tn
;
299 Object
*retval
= NULL
;
301 ObtainSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
302 ForeachNode(&MUIMB(MUIMasterBase
)->Applications
, tn
)
306 get(tn
->tn_Application
, MUIA_Application_Base
, &tn_base
);
308 if (tn_base
&& (strcmp(base
, tn_base
)) == 0)
310 retval
= tn
->tn_Application
;
314 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
319 /**************************************************************************
321 **************************************************************************/
322 static IPTR
Application__OM_NEW(struct IClass
*cl
, Object
*obj
,
325 struct MUI_ApplicationData
*data
;
326 struct TagItem
*tags
, *tag
;
327 BOOL bad_childs
= FALSE
;
329 obj
= (Object
*) DoSuperMethodA(cl
, obj
, (Msg
) msg
);
333 /* Initial local instance data */
334 data
= INST_DATA(cl
, obj
);
336 /* init input handler list */
337 NewList((struct List
*)&(data
->app_IHList
));
339 /* init input queue */
340 NewList((struct List
*)&(data
->app_MethodQueue
));
342 /* init return ids queue */
343 NewList((struct List
*)&(data
->app_ReturnIDQueue
));
346 data
->app_WindowFamily
= MUI_NewObjectA(MUIC_Family
, NULL
);
347 if (!data
->app_WindowFamily
)
349 CoerceMethod(cl
, obj
, OM_DISPOSE
);
353 data
->app_GlobalInfo
.mgi_ApplicationObject
= obj
;
354 if (!(data
->app_GlobalInfo
.mgi_WindowsPort
= CreateMsgPort()))
356 CoerceMethod(cl
, obj
, OM_DISPOSE
);
360 data
->app_Task
= FindTask(NULL
);
363 data
->app_SingleTask
=
364 (BOOL
) GetTagData(MUIA_Application_SingleTask
, FALSE
,
367 (STRPTR
) GetTagData(MUIA_Application_Base
, (IPTR
) "UNNAMED",
369 if (!data
->app_Base
|| strpbrk(data
->app_Base
, ":/()#?*,"))
371 data
->app_Base
= NULL
; /* don't remove */
372 CoerceMethod(cl
, obj
, OM_DISPOSE
);
377 if (!data
->app_SingleTask
)
379 /* must append .1, .2, ... to the base name */
383 for (i
= 1; i
< 1000; i
++)
385 snprintf(portname
, 255, "%s.%d", data
->app_Base
, (int)i
);
386 if (!find_application_by_base(cl
, obj
, portname
))
389 data
->app_Base
= StrDup(portname
);
395 ObtainSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
396 if ((other_app
= find_application_by_base(cl
, obj
, data
->app_Base
)))
398 //FIXME "Is calling MUIM_Application_PushMethod on an alien
399 //application object safe?"
400 DoMethod(other_app
, MUIM_Application_PushMethod
,
401 (IPTR
) other_app
, 3, MUIM_Set
, MUIA_Application_DoubleStart
,
403 data
->app_Base
= NULL
;
405 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
407 data
->app_Base
= StrDup(data
->app_Base
);
412 CoerceMethod(cl
, obj
, OM_DISPOSE
);
416 data
->app_GlobalInfo
.mgi_Configdata
=
417 MUI_NewObject(MUIC_Configdata
, MUIA_Configdata_Application
, obj
,
419 if (!data
->app_GlobalInfo
.mgi_Configdata
)
421 CoerceMethod(cl
, obj
, OM_DISPOSE
);
424 get(data
->app_GlobalInfo
.mgi_Configdata
, MUIA_Configdata_ZunePrefs
,
425 &data
->app_GlobalInfo
.mgi_Prefs
);
427 // D(bug("muimaster.library/application.c: Message Port created at 0x%lx\n",
428 // data->app_GlobalInfo.mgi_WindowPort));
430 /* Setup timer stuff */
431 if (!(data
->app_TimerPort
= CreateMsgPort()))
433 CoerceMethod(cl
, obj
, OM_DISPOSE
);
437 if (!(data
->app_TimerReq
=
438 (struct timerequest
*)CreateIORequest(data
->app_TimerPort
,
439 sizeof(struct timerequest
))))
441 CoerceMethod(cl
, obj
, OM_DISPOSE
);
445 if (OpenDevice(TIMERNAME
, UNIT_VBLANK
,
446 (struct IORequest
*)data
->app_TimerReq
, 0))
448 CoerceMethod(cl
, obj
, OM_DISPOSE
);
452 InitSemaphore(&data
->app_MethodSemaphore
);
454 muiNotifyData(obj
)->mnd_GlobalInfo
= &data
->app_GlobalInfo
;
456 /* parse initial taglist */
458 data
->app_Active
= 1;
459 data
->app_Title
= "Unnamed";
460 data
->app_Version
= "Unnamed 0.0";
461 data
->app_Description
= "?";
463 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
));)
467 case MUIA_Application_Author
:
468 data
->app_Author
= (STRPTR
) tag
->ti_Data
;
471 case MUIA_Application_Base
:
472 /* moved before config parsing */
475 case MUIA_Application_Copyright
:
476 data
->app_Copyright
= (STRPTR
) tag
->ti_Data
;
479 case MUIA_Application_Description
:
480 data
->app_Description
= (STRPTR
) tag
->ti_Data
;
483 case MUIA_Application_HelpFile
:
484 data
->app_HelpFile
= (STRPTR
) tag
->ti_Data
;
487 case MUIA_Application_SingleTask
:
488 /* moved before config parsing */
491 case MUIA_Application_Title
:
492 data
->app_Title
= (STRPTR
) tag
->ti_Data
;
495 case MUIA_Application_Version
:
496 data
->app_Version
= (STRPTR
) tag
->ti_Data
;
499 case MUIA_Application_Version_Number
:
500 data
->app_Version_Number
= (STRPTR
) tag
->ti_Data
;
503 case MUIA_Application_Version_Date
:
504 data
->app_Version_Date
= (STRPTR
) tag
->ti_Data
;
507 case MUIA_Application_Version_Extra
:
508 data
->app_Version_Extra
= (STRPTR
) tag
->ti_Data
;
511 case MUIA_Application_Window
:
513 DoMethod(obj
, OM_ADDMEMBER
, tag
->ti_Data
);
518 case MUIA_Application_Menustrip
:
519 data
->app_Menustrip
= (Object
*) tag
->ti_Data
;
522 case MUIA_Application_BrokerPri
:
523 data
->app_BrokerPri
= (BYTE
) tag
->ti_Data
;
526 case MUIA_Application_BrokerHook
:
527 data
->app_BrokerHook
= (struct Hook
*)tag
->ti_Data
;
530 case MUIA_Application_Active
:
531 data
->app_Active
= tag
->ti_Data
? TRUE
: FALSE
;
534 case MUIA_Application_UsedClasses
:
536 STRPTR
*list
= (STRPTR
*) tag
->ti_Data
;
541 struct IClass
*icl
= MUI_GetClass(*list
);
549 case MUIA_Application_UseRexx
:
550 data
->app_UseRexx
= tag
->ti_Data
? TRUE
: FALSE
;
553 case MUIA_Application_Commands
:
554 data
->app_Commands
= (struct MUI_Command
*)tag
->ti_Data
;
557 case MUIA_Application_RexxHook
:
558 data
->app_RexxHook
= (struct Hook
*)tag
->ti_Data
;
561 case MUIA_Application_DiskObject
:
562 data
->app_DiskObject
= (struct DiskObject
*)tag
->ti_Data
;
568 /* create MUIA_Application_Version if NULL */
569 if (data
->app_Version
== NULL
570 && data
->app_Title
!= NULL
&& data
->app_Version_Number
!= NULL
)
572 STRPTR result
= NULL
;
575 /* Calculate length */
576 length
= strlen("$VER: ") + strlen(data
->app_Title
) + 1 /* space */
577 + strlen(data
->app_Version_Number
) + 1 /* NULL */ ;
579 if (data
->app_Version_Date
!= NULL
)
581 length
+= 1 /* space */ + 1 /* ( */
582 + strlen(data
->app_Version_Date
) + 1 /* ) */ ;
585 if (data
->app_Version_Extra
!= NULL
)
587 length
+= 1 /* space */ + 1 /* [ */
588 + strlen(data
->app_Version_Extra
) + 1 /* ] */ ;
591 /* Allocate memory */
592 result
= AllocVec(length
, MEMF_ANY
);
599 strlcat(result
, "$VER: ", length
);
600 strlcat(result
, data
->app_Title
, length
);
601 strlcat(result
, " ", length
);
602 strlcat(result
, data
->app_Version_Number
, length
);
604 if (data
->app_Version_Date
!= NULL
)
606 strlcat(result
, " (", length
);
607 strlcat(result
, data
->app_Version_Date
, length
);
608 strlcat(result
, ")", length
);
611 if (data
->app_Version_Extra
!= NULL
)
613 strlcat(result
, " [", length
);
614 strlcat(result
, data
->app_Version_Extra
, length
);
615 strlcat(result
, "]", length
);
618 data
->app_Version
= result
;
619 data
->app_VersionAllocated
= TRUE
;
626 CoerceMethod(cl
, obj
, OM_DISPOSE
);
631 && GetTagData(MUIA_Application_UseCommodities
, TRUE
,
634 data
->app_BrokerPort
= CreateMsgPort();
636 if (data
->app_BrokerPort
)
640 nb
.nb_Version
= NB_VERSION
;
642 data
->app_Title
? data
->app_Title
: (STRPTR
) "Unnamed";
644 data
->app_Version
? data
->app_Version
: (STRPTR
) "Unnamed";
646 data
->app_Description
? data
->
647 app_Description
: (STRPTR
) "?";
649 nb
.nb_Flags
= COF_SHOW_HIDE
;
650 nb
.nb_Pri
= data
->app_BrokerPri
;
651 nb
.nb_Port
= data
->app_BrokerPort
;
652 nb
.nb_ReservedChannel
= 0;
654 if (strncmp(nb
.nb_Title
, "$VER: ", 6) == 0)
657 data
->app_Broker
= CxBroker(&nb
, 0);
659 if (data
->app_Broker
)
661 if (data
->app_Active
)
662 ActivateCxObj(data
->app_Broker
, 1);
667 if (data
->app_UseRexx
)
669 data
->app_RexxPort
= CreateMsgPort();
670 if (data
->app_RexxPort
)
672 data
->app_RexxPort
->mp_Node
.ln_Name
= StrDup(data
->app_Base
);
673 if (data
->app_RexxPort
->mp_Node
.ln_Name
!= NULL
)
675 D(bug("[MUI] %s is using REXX!\n",
676 data
->app_RexxPort
->mp_Node
.ln_Name
));
678 for (i
= data
->app_RexxPort
->mp_Node
.ln_Name
; *i
!= '\0';
683 AddPort(data
->app_RexxPort
);
687 DeleteMsgPort(data
->app_RexxPort
);
688 data
->app_RexxPort
= NULL
;
693 if (data
->app_Menustrip
)
694 DoMethod(data
->app_Menustrip
, MUIM_ConnectParent
, (IPTR
) obj
);
696 data
->app_AppPort
= CreateMsgPort();
697 data
->app_GlobalInfo
.mgi_AppPort
= data
->app_AppPort
;
698 if (data
->app_AppPort
== NULL
)
700 CoerceMethod(cl
, obj
, OM_DISPOSE
);
704 ObtainSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
705 data
->app_TrackingNode
.tn_Application
= obj
;
706 AddTail((struct List
*)&MUIMB(MUIMasterBase
)->Applications
,
707 (struct Node
*)&data
->app_TrackingNode
);
708 data
->app_is_TNode_in_list
= TRUE
;
709 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
716 /**************************************************************************
718 **************************************************************************/
719 static IPTR
Application__OM_DISPOSE(struct IClass
*cl
, Object
*obj
,
722 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
729 positionmode
= data
->app_GlobalInfo
.mgi_Prefs
->window_position
;
730 if (positionmode
>= 1)
732 snprintf(filename
, 255, "ENV:zune/%s.prefs", data
->app_Base
);
733 DoMethod(data
->app_GlobalInfo
.mgi_Configdata
,
734 MUIM_Configdata_Save
, (IPTR
) filename
);
736 if (positionmode
== 2)
738 snprintf(filename
, 255, "ENVARC:zune/%s.prefs", data
->app_Base
);
739 DoMethod(data
->app_GlobalInfo
.mgi_Configdata
,
740 MUIM_Configdata_Save
, (IPTR
) filename
);
744 if (data
->app_is_TNode_in_list
)
746 ObtainSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
747 Remove((struct Node
*)&data
->app_TrackingNode
);
748 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
751 if (data
->app_WindowFamily
)
753 struct MinList
*children
= NULL
;
757 /* special loop because the next object may have been removed/freed by
758 * the previous. so restart from listhead each time.
762 get(data
->app_WindowFamily
, MUIA_Family_List
, &children
);
763 if (children
== NULL
)
766 cstate
= (Object
*) children
->mlh_Head
;
767 if ((child
= NextObject(&cstate
)))
769 D(bug("Application_Dispose(%p) : OM_REMMEMBER(%p)\n", obj
,
771 DoMethod(obj
, OM_REMMEMBER
, (IPTR
) child
);
772 D(bug("Application_Dispose(%p) : MUI_DisposeObject(%p)\n",
774 MUI_DisposeObject(child
);
782 MUI_DisposeObject(data
->app_WindowFamily
);
785 if (data
->app_Menustrip
)
786 MUI_DisposeObject(data
->app_Menustrip
);
788 if (data
->app_VersionAllocated
&& data
->app_Version
!= NULL
)
790 FreeVec(data
->app_Version
);
793 /* free commodities stuff */
795 if (data
->app_Broker
)
797 DeleteCxObjAll(data
->app_Broker
);
800 if (data
->app_BrokerPort
)
804 while ((msg
= GetMsg(data
->app_BrokerPort
)))
809 DeleteMsgPort(data
->app_BrokerPort
);
812 /* free timer stuff */
813 if (data
->app_TimerReq
)
815 if (data
->app_TimerReq
->tr_node
.io_Device
)
817 while (data
->app_TimerOutstanding
)
819 if (Wait(1L << data
->app_TimerPort
->
820 mp_SigBit
| 4096) & 4096)
822 data
->app_TimerOutstanding
--;
824 CloseDevice((struct IORequest
*)data
->app_TimerReq
);
826 DeleteIORequest((struct IORequest
*)data
->app_TimerReq
);
828 DeleteMsgPort(data
->app_TimerPort
);
830 if (data
->app_RexxPort
)
833 while ((msg
= GetMsg(data
->app_RexxPort
)))
837 RemPort(data
->app_RexxPort
);
839 FreeVec(data
->app_RexxPort
->mp_Node
.ln_Name
);
840 DeleteMsgPort(data
->app_RexxPort
);
843 if (data
->app_AppIcon
)
844 RemoveAppIcon(data
->app_AppIcon
);
846 if (data
->app_DefaultDiskObject
)
847 FreeDiskObject(data
->app_DefaultDiskObject
);
849 if (data
->app_AppPort
)
852 while ((msg
= GetMsg(data
->app_AppPort
)))
855 DeleteMsgPort(data
->app_AppPort
);
858 if (data
->app_GlobalInfo
.mgi_Configdata
)
859 MUI_DisposeObject(data
->app_GlobalInfo
.mgi_Configdata
);
861 DeleteMsgPort(data
->app_GlobalInfo
.mgi_WindowsPort
);
863 FreeVec(data
->app_Base
);
865 /* free returnid stuff */
868 (struct RIDNode
*)RemHead((struct List
*)&data
->
871 DeleteRIDNode(data
, rid
);
874 return DoSuperMethodA(cl
, obj
, msg
);
878 /**************************************************************************
880 **************************************************************************/
881 static IPTR
Application__OM_SET(struct IClass
*cl
, Object
*obj
,
884 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
885 struct TagItem
*tags
= msg
->ops_AttrList
;
888 /* There are many ways to find out what tag items provided by set()
889 ** we do know. The best way should be using NextTagItem() and simply
890 ** browsing through the list.
892 while ((tag
= NextTagItem(&tags
)) != NULL
)
898 case MUIA_Application_SearchWinId
:
899 data
->searchwinid
= tag
->ti_Data
;
902 case MUIA_Application_CopyWinPosToApp
:
903 addr
= (IPTR
*) tag
->ti_Data
;
904 CopyMem((CONST_APTR
) tag
->ti_Data
, &data
->winposused
, *(addr
));
907 case MUIA_Application_SetWinPos
:
909 struct windowpos
*winp
;
910 winp
= (struct windowpos
*)tag
->ti_Data
;
911 //kprintf("SetWinPos %d %d %d %d %d\n", winp->id, winp->x1,
912 // winp->y1, winp->w1, winp->h1);
914 for (i
= 0; i
< MAXWINS
- 1; i
++)
916 if (data
->winpos
[i
].w1
)
918 if (winp
->id
== data
->winpos
[i
].id
)
920 //existing entry is overwritten
921 data
->winpos
[i
].x1
= winp
->x1
;
922 data
->winpos
[i
].y1
= winp
->y1
;
923 data
->winpos
[i
].w1
= winp
->w1
;
924 data
->winpos
[i
].h1
= winp
->h1
;
925 data
->winpos
[i
].x2
= winp
->x2
;
926 data
->winpos
[i
].y2
= winp
->y2
;
927 data
->winpos
[i
].w2
= winp
->w2
;
928 data
->winpos
[i
].h2
= winp
->h2
;
934 // a new entry is added
935 data
->winpos
[i
].id
= winp
->id
;
936 data
->winpos
[i
].x1
= winp
->x1
;
937 data
->winpos
[i
].y1
= winp
->y1
;
938 data
->winpos
[i
].w1
= winp
->w1
;
939 data
->winpos
[i
].h1
= winp
->h1
;
940 data
->winpos
[i
].x2
= winp
->x2
;
941 data
->winpos
[i
].y2
= winp
->y2
;
942 data
->winpos
[i
].w2
= winp
->w2
;
943 data
->winpos
[i
].h2
= winp
->h2
;
950 case MUIA_Application_Configdata
:
951 DoMethod(obj
, MUIM_Application_PushMethod
, (IPTR
) obj
, 2,
952 MUIM_Application_SetConfigdata
, tag
->ti_Data
);
955 case MUIA_Application_HelpFile
:
956 data
->app_HelpFile
= (STRPTR
) tag
->ti_Data
;
959 case MUIA_Application_Iconified
:
961 BOOL do_iconify
= tag
->ti_Data
== 1;
962 if (data
->app_Iconified
!= do_iconify
)
964 data
->app_Iconified
= do_iconify
;
966 nnset(obj
, MUIA_ShowMe
, !data
->app_Iconified
);
968 /* Inform workbench.library */
969 if (data
->app_Iconified
)
972 data
->app_Title
? data
->
973 app_Title
: (STRPTR
) "Unnamed";
974 struct DiskObject
*dobj
=
975 (struct DiskObject
*)XGET(obj
,
976 MUIA_Application_DiskObject
);
980 /* Get default AppIcon in ENV:SYS or ENVARC:SYS */
981 dobj
= GetDefDiskObject(WBAPPICON
);
983 data
->app_DefaultDiskObject
= dobj
;
986 /* First default: ENV:SYS/def_MUI.info */
987 dobj
= GetDiskObject("ENV:SYS/def_MUI");
989 data
->app_DefaultDiskObject
= dobj
;
992 /* Second default: ENV:SYS/def_Zune.info */
994 GetDiskObject("ENV:SYS/def_Zune");
996 data
->app_DefaultDiskObject
= dobj
;
999 /* Third default: default tool icon */
1000 dobj
= GetDefDiskObject(WBTOOL
);
1002 data
->app_DefaultDiskObject
=
1012 dobj
->do_CurrentX
= NO_ICON_POSITION
;
1013 dobj
->do_CurrentY
= NO_ICON_POSITION
;
1016 AddAppIconA(0L, 0L, appname
, data
->app_AppPort
,
1021 if (data
->app_AppIcon
)
1023 RemoveAppIcon(data
->app_AppIcon
);
1024 data
->app_AppIcon
= NULL
;
1026 if (data
->app_DefaultDiskObject
)
1028 FreeDiskObject(data
->app_DefaultDiskObject
);
1029 data
->app_DefaultDiskObject
= NULL
;
1038 /* Ok ok, you think this stinks? Well, think of it as
1039 an attribute belonging to an interface which
1040 MUIC_Application, together with MUIC_Area and a few
1041 others implement. It makes sense now, yes? */
1042 struct List
*wlist
= NULL
;
1044 Object
*curwin
= NULL
;
1045 Object
*lastwin
= NULL
;
1047 /* MUIA_ShowMe can cause MUIM_Setup/MUIM_Cleanup to be issued.
1048 * On the other hand it is allowed to add/remove other
1049 * application windows in MUIM_Setup/MUIM_Cleanup.
1050 * This means after processing a window from internal list,
1051 * the list needs to be re-read and iteration started again,
1052 * because wstate can become invalid.
1053 * Note: The code below assumes that the window won't remove
1054 * itself from the list.
1059 get(data
->app_WindowFamily
, MUIA_Family_List
, &wlist
);
1060 wstate
= (Object
*) wlist
->lh_Head
;
1061 while ((curwin
= NextObject(&wstate
)))
1063 if (lastwin
== NULL
)
1065 if (curwin
== lastwin
)
1067 curwin
= NextObject(&wstate
);
1072 /* This is the window to be processed */
1075 set(curwin
, MUIA_ShowMe
, tag
->ti_Data
);
1080 /* No more windows */
1087 case MUIA_Application_Sleep
:
1089 struct List
*wlist
= NULL
;
1095 data
->app_SleepCount
++;
1096 if (data
->app_SleepCount
== 1)
1098 get(obj
, MUIA_Application_WindowList
, &wlist
);
1101 wstate
= wlist
->lh_Head
;
1102 while ((curwin
= NextObject(&wstate
)))
1104 set(curwin
, MUIA_Window_Sleep
, TRUE
);
1111 data
->app_SleepCount
--;
1112 if (data
->app_SleepCount
== 0)
1114 get(obj
, MUIA_Application_WindowList
, &wlist
);
1117 wstate
= wlist
->lh_Head
;
1118 while ((curwin
= NextObject(&wstate
)))
1120 set(curwin
, MUIA_Window_Sleep
, FALSE
);
1128 case MUIA_Application_MenuAction
:
1129 data
->app_MenuAction
= tag
->ti_Data
;
1132 case MUIA_Application_BrokerHook
:
1133 data
->app_BrokerHook
= (struct Hook
*)tag
->ti_Data
;
1136 case MUIA_Application_Active
:
1137 data
->app_Active
= tag
->ti_Data
? TRUE
: FALSE
;
1138 if (data
->app_Broker
)
1140 ActivateCxObj(data
->app_Broker
, data
->app_Active
);
1144 case MUIA_Application_Commands
:
1145 data
->app_Commands
= (struct MUI_Command
*)tag
->ti_Data
;
1148 case MUIA_Application_RexxString
:
1149 data
->app_RexxString
= (STRPTR
) tag
->ti_Data
;
1152 case MUIA_Application_RexxHook
:
1153 data
->app_RexxHook
= (struct Hook
*)tag
->ti_Data
;
1156 case MUIA_Application_DiskObject
:
1157 data
->app_DiskObject
= (struct DiskObject
*)tag
->ti_Data
;
1162 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
1169 static IPTR
Application__OM_GET(struct IClass
*cl
, Object
*obj
,
1172 #define STORE *(msg->opg_Storage)
1174 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1176 switch (msg
->opg_AttrID
)
1178 case MUIA_Application_GetWinPosAddr
:
1179 STORE
= (IPTR
) & data
->winposused
;
1182 case MUIA_Application_GetWinPosSize
:
1185 for (i
= 0; i
< MAXWINS
- 1; i
++)
1187 if (!data
->winpos
[i
].w1
)
1189 i
*= sizeof(struct windowpos
);
1191 data
->winposused
= i
;
1200 case MUIA_Application_GetWinPos
:
1203 if (data
->searchwinid
)
1205 for (i
= 0; i
< MAXWINS
- 1; i
++)
1207 if (data
->winpos
[i
].w1
)
1209 if (data
->searchwinid
== data
->winpos
[i
].id
)
1211 STORE
= (IPTR
) & data
->winpos
[i
].id
;
1232 case MUIA_Application_Author
:
1233 STORE
= (IPTR
) data
->app_Author
;
1236 case MUIA_Application_Base
:
1237 STORE
= (IPTR
) data
->app_Base
;
1240 case MUIA_Application_Copyright
:
1241 STORE
= (IPTR
) data
->app_Copyright
;
1244 case MUIA_Application_Description
:
1245 STORE
= (IPTR
) data
->app_Description
;
1248 case MUIA_Application_DoubleStart
:
1251 case MUIA_Application_ForceQuit
:
1252 STORE
= (IPTR
) data
->app_ForceQuit
;
1255 case MUIA_Application_HelpFile
:
1256 STORE
= (IPTR
) data
->app_HelpFile
;
1259 case MUIA_Application_Iconified
:
1260 STORE
= (IPTR
) data
->app_Iconified
;
1263 case MUIA_Application_Title
:
1264 STORE
= (IPTR
) data
->app_Title
;
1267 case MUIA_Application_Version
:
1268 STORE
= (IPTR
) data
->app_Version
;
1271 case MUIA_Application_Version_Number
:
1272 STORE
= (IPTR
) data
->app_Version_Number
;
1275 case MUIA_Application_Version_Date
:
1276 STORE
= (IPTR
) data
->app_Version_Date
;
1279 case MUIA_Application_Version_Extra
:
1280 STORE
= (IPTR
) data
->app_Version_Extra
;
1283 case MUIA_Application_WindowList
:
1284 return GetAttr(MUIA_Family_List
, data
->app_WindowFamily
,
1287 case MUIA_Application_Menustrip
:
1288 STORE
= (IPTR
) data
->app_Menustrip
;
1291 case MUIA_Application_MenuAction
:
1292 STORE
= (IPTR
) data
->app_MenuAction
;
1295 case MUIA_Application_BrokerPort
:
1296 STORE
= (IPTR
) data
->app_BrokerPort
;
1299 case MUIA_Application_BrokerPri
:
1300 STORE
= (IPTR
) data
->app_BrokerPri
;
1303 case MUIA_Application_BrokerHook
:
1304 STORE
= (IPTR
) data
->app_BrokerHook
;
1307 case MUIA_Application_Broker
:
1308 STORE
= (IPTR
) data
->app_Broker
;
1311 case MUIA_Application_Active
:
1312 STORE
= data
->app_Active
;
1315 case MUIA_Application_Commands
:
1316 STORE
= (IPTR
) data
->app_Commands
;
1319 case MUIA_Application_RexxMsg
:
1320 STORE
= (IPTR
) data
->app_RexxMsg
;
1323 case MUIA_Application_RexxHook
:
1324 STORE
= (IPTR
) data
->app_RexxHook
;
1327 case MUIA_Application_DiskObject
:
1328 STORE
= (IPTR
) data
->app_DiskObject
;
1332 /* our handler didn't understand the attribute, we simply pass
1333 ** it to our superclass now
1335 return (DoSuperMethodA(cl
, obj
, (Msg
) msg
));
1340 /**************************************************************************
1342 **************************************************************************/
1343 static IPTR
Application__OM_ADDMEMBER(struct IClass
*cl
, Object
*obj
,
1344 struct opMember
*msg
)
1346 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1348 D(bug("Application_AddMember: Adding 0x%lx to window member list\n",
1351 DoMethodA(data
->app_WindowFamily
, (Msg
) msg
);
1352 /* Application knows its GlobalInfo, so we can inform window */
1353 DoMethod(msg
->opam_Object
, MUIM_ConnectParent
, (IPTR
) obj
);
1358 /**************************************************************************
1360 **************************************************************************/
1361 static IPTR
Application__OM_REMMEMBER(struct IClass
*cl
, Object
*obj
,
1362 struct opMember
*msg
)
1364 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1366 D(bug("Application_RemMember: Removing 0x%lx from window member list\n",
1369 DoMethod(msg
->opam_Object
, MUIM_DisconnectParent
);
1370 DoMethodA(data
->app_WindowFamily
, (Msg
) msg
);
1377 /**************************************************************************
1378 MUIM_Application_AddInputHandler
1379 **************************************************************************/
1380 static IPTR
Application__MUIM_AddInputHandler(struct IClass
*cl
,
1381 Object
*obj
, struct MUIP_Application_AddInputHandler
*msg
)
1383 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1385 if (msg
->ihnode
->ihn_Flags
& MUIIHNF_TIMER
)
1387 struct timerequest_ext
*time_ext
=
1388 (struct timerequest_ext
*)AllocVec(sizeof(struct
1389 timerequest_ext
), MEMF_PUBLIC
);
1392 /* Store the request inside the input handler, so that we can
1393 ** remove the inputhandler without problems */
1394 msg
->ihnode
->ihn_Node
.mln_Pred
= (struct MinNode
*)time_ext
;
1396 time_ext
->treq
= *data
->app_TimerReq
;
1397 time_ext
->treq
.tr_node
.io_Command
= TR_ADDREQUEST
;
1398 time_ext
->treq
.tr_time
.tv_secs
= msg
->ihnode
->ihn_Millis
/ 1000;
1399 time_ext
->treq
.tr_time
.tv_micro
=
1400 (msg
->ihnode
->ihn_Millis
% 1000) * 1000;
1401 time_ext
->ihn
= msg
->ihnode
;
1402 SendIO((struct IORequest
*)time_ext
);
1406 AddTail((struct List
*)&data
->app_IHList
,
1407 (struct Node
*)msg
->ihnode
);
1412 /**************************************************************************
1413 MUIM_Application_RemInputHandler
1414 **************************************************************************/
1415 static IPTR
Application__MUIM_RemInputHandler(struct IClass
*cl
,
1416 Object
*obj
, struct MUIP_Application_RemInputHandler
*msg
)
1418 //struct MUI_ApplicationData *data = INST_DATA(cl, obj);
1419 if (msg
->ihnode
->ihn_Flags
& MUIIHNF_TIMER
)
1421 struct timerequest_ext
*time_ext
=
1422 (struct timerequest_ext
*)msg
->ihnode
->ihn_Node
.mln_Pred
;
1423 if (!CheckIO((struct IORequest
*)time_ext
))
1424 AbortIO((struct IORequest
*)time_ext
);
1425 WaitIO((struct IORequest
*)time_ext
);
1429 Remove((struct Node
*)msg
->ihnode
);
1435 void _zune_window_message(struct IntuiMessage
*imsg
); /* from window.c */
1438 * MUIM_Application_InputBuffered : process all pending events
1440 static IPTR
Application__MUIM_InputBuffered(struct IClass
*cl
, Object
*obj
,
1441 struct MUIP_Application_InputBuffered
*msg
)
1443 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1444 struct IntuiMessage
*imsg
;
1446 /* process all pushed methods */
1447 while (application_do_pushed_method(data
))
1451 (struct IntuiMessage
*)GetMsg(data
->app_GlobalInfo
.mgi_WindowsPort
);
1454 /* Let window object process message */
1455 _zune_window_message(imsg
); /* will reply the message */
1460 /**************************************************************************
1461 MUIM_Application_NewInput : application main loop
1462 **************************************************************************/
1463 static IPTR
Application__MUIM_NewInput(struct IClass
*cl
, Object
*obj
,
1464 struct MUIP_Application_NewInput
*msg
)
1466 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1467 struct RIDNode
*rid
;
1469 ULONG signal
, signalmask
;
1470 ULONG handler_mask
= 0; /* the mask of the signal handlers */
1473 //struct MinNode ihn_Node;
1475 signal
= *msg
->signal
;
1477 /* process all pushed methods */
1478 while (application_do_pushed_method(data
))
1481 /* query the signal for the handlers */
1482 for (mn
= data
->app_IHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
1484 struct MUI_InputHandlerNode
*ihn
;
1485 ihn
= (struct MUI_InputHandlerNode
*)mn
;
1486 handler_mask
|= ihn
->ihn_Signals
;
1489 signalmask
= (1L << data
->app_GlobalInfo
.mgi_WindowsPort
->mp_SigBit
)
1490 | (1L << data
->app_TimerPort
->mp_SigBit
) | handler_mask
;
1492 if (data
->app_Broker
)
1493 signalmask
|= (1L << data
->app_BrokerPort
->mp_SigBit
);
1495 if (data
->app_RexxPort
)
1496 signalmask
|= (1L << data
->app_RexxPort
->mp_SigBit
);
1498 if (data
->app_AppPort
)
1499 signalmask
|= (1L << data
->app_AppPort
->mp_SigBit
);
1503 /* Stupid app which (always) passes 0 in signals. It's impossible to
1504 know which signals were really set as the app will already have
1505 called Wait() which has cleared the task's tc_SigRecvd. So assume
1506 the window, timer, and broker signals all to be set. Also all of
1507 the inputhandler signals (MUI does that too). */
1509 signal
= signalmask
;
1512 if (signal
& signalmask
)
1514 if (signal
& (1L << data
->app_GlobalInfo
.mgi_WindowsPort
->
1517 struct IntuiMessage
*imsg
;
1518 /* process all pushed methods */
1521 (struct IntuiMessage
*)GetMsg(data
->app_GlobalInfo
.
1524 /* Let window object process message */
1525 _zune_window_message(imsg
); /* will reply the message */
1529 if (signal
& (1L << data
->app_TimerPort
->mp_SigBit
))
1531 struct timerequest_ext
*time_ext
;
1536 /* At first we fetch all messages from the message port and store
1537 ** them in a list, we use the node of the Message here */
1539 (struct timerequest_ext
*)GetMsg(data
->app_TimerPort
)))
1540 AddTail(&list
, (struct Node
*)time_ext
);
1542 /* Now we proccess the list and resend the timer io, no loop can
1543 ** happen. We use RemHead() because the handler can remove it
1544 ** itself and so a FreeVec() could happen in
1545 ** MUIM_Application_RemInputHandler which would destroy the
1546 ** ln->Succ of course */
1547 while ((n
= RemHead(&list
)))
1549 struct timerequest_ext
*time_ext
=
1550 (struct timerequest_ext
*)n
;
1551 struct MUI_InputHandlerNode
*ihn
= time_ext
->ihn
;
1552 time_ext
->treq
.tr_time
.tv_secs
=
1553 time_ext
->ihn
->ihn_Millis
/ 1000;
1554 time_ext
->treq
.tr_time
.tv_micro
=
1555 (time_ext
->ihn
->ihn_Millis
% 1000) * 1000;
1556 SendIO((struct IORequest
*)&time_ext
->treq
);
1557 DoMethod(ihn
->ihn_Object
, ihn
->ihn_Method
);
1561 if (data
->app_BrokerPort
1562 && (signal
& (1L << data
->app_BrokerPort
->mp_SigBit
)))
1566 while ((msg
= (CxMsg
*) GetMsg(data
->app_BrokerPort
)))
1568 switch (CxMsgType(msg
))
1571 switch (CxMsgID(msg
))
1574 set(obj
, MUIA_Application_Active
, FALSE
);
1578 set(obj
, MUIA_Application_Active
, TRUE
);
1582 case CXCMD_DISAPPEAR
:
1583 /* No default handling - application needs to be in
1584 * control of this */
1588 SetSignal(SIGBREAKF_CTRL_C
, SIGBREAKF_CTRL_C
);
1594 if (data
->app_BrokerHook
)
1596 CallHookPkt(data
->app_BrokerHook
, obj
, msg
);
1599 ReplyMsg((struct Message
*)msg
);
1603 if (data
->app_RexxPort
1604 && (signal
& (1L << data
->app_RexxPort
->mp_SigBit
)))
1607 D(bug("[MUI] Got Rexx message!\n"));
1608 struct Message
*msg
;
1609 while ((msg
= GetMsg(data
->app_RexxPort
)))
1615 if (data
->app_AppPort
1616 && (signal
& (1L << data
->app_AppPort
->mp_SigBit
)))
1618 struct AppMessage
*appmsg
;
1620 (struct AppMessage
*)GetMsg(data
->app_AppPort
)))
1622 if ((appmsg
->am_Type
== AMTYPE_APPICON
)
1623 && (appmsg
->am_NumArgs
== 0)
1624 && (appmsg
->am_ArgList
== NULL
)
1625 && (XGET(obj
, MUIA_Application_Iconified
) == TRUE
))
1627 /* Reply before removing AppIcon */
1628 ReplyMsg((struct Message
*)appmsg
);
1629 set(obj
, MUIA_Application_Iconified
, FALSE
);
1632 else if (appmsg
->am_Type
== AMTYPE_APPWINDOW
)
1634 set((Object
*) appmsg
->am_UserData
, MUIA_AppMessage
,
1638 ReplyMsg((struct Message
*)appmsg
);
1642 if (signal
& handler_mask
)
1644 for (mn
= data
->app_IHList
.mlh_Head
; mn
->mln_Succ
;
1647 struct MUI_InputHandlerNode
*ihn
;
1648 ihn
= (struct MUI_InputHandlerNode
*)mn
;
1649 if (signal
& ihn
->ihn_Signals
)
1650 DoMethod(ihn
->ihn_Object
, ihn
->ihn_Method
);
1655 /* process all pushed methods - again */
1656 while (application_do_pushed_method(data
))
1659 *msg
->signal
= signalmask
;
1661 /* set return code */
1663 (struct RIDNode
*)RemHead((struct List
*)&data
->
1664 app_ReturnIDQueue
)))
1666 retval
= rid
->rid_Value
;
1667 DeleteRIDNode(data
, rid
);
1673 /**************************************************************************
1674 MUIM_Application_Input : application main loop
1675 This method shouldn't be used in any new program. As it polls all signals.
1676 **************************************************************************/
1677 static IPTR
Application__MUIM_Input(struct IClass
*cl
, Object
*obj
,
1678 struct MUIP_Application_Input
*msg
)
1680 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1681 ULONG signal
= 0, handler_mask
= 0;
1684 /* query the signal for the handlers */
1685 for (mn
= data
->app_IHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
1687 struct MUI_InputHandlerNode
*ihn
;
1688 ihn
= (struct MUI_InputHandlerNode
*)mn
;
1689 handler_mask
|= ihn
->ihn_Flags
;
1692 signal
= (1L << data
->app_GlobalInfo
.mgi_WindowsPort
->mp_SigBit
)
1693 | (1L << data
->app_TimerPort
->mp_SigBit
) | handler_mask
;
1695 if (data
->app_RexxPort
)
1696 signal
|= (1L << data
->app_RexxPort
->mp_SigBit
);
1698 if (data
->app_AppPort
)
1699 signal
|= (1L << data
->app_AppPort
->mp_SigBit
);
1702 *msg
->signal
= signal
;
1703 return Application__MUIM_NewInput(cl
, obj
, (APTR
) msg
);
1706 /**************************************************************************
1707 MUIM_Application_PushMethod: Add a method in the method FIFO. Will
1708 be executed in the next event loop.
1709 **************************************************************************/
1710 static IPTR
Application__MUIM_PushMethod(struct IClass
*cl
, Object
*obj
,
1711 struct MUIP_Application_PushMethod
*msg
)
1713 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1716 IPTR
*m
= (IPTR
*) & msg
->count
; /* FIXME: breaks on 64-bit BigEndian systems */
1719 count
= msg
->count
& 0xf; /* MUI4 uses count to pass additional info */
1721 mq
= CreateMQNode(count
);
1724 mq
->mq_Dest
= msg
->dest
;
1727 for (i
= 0; i
< count
; i
++)
1728 mq
->mq_Msg
[i
] = *(m
+ 1 + i
);
1730 /* enqueue method */
1731 ObtainSemaphore(&data
->app_MethodSemaphore
);
1732 AddTail((struct List
*)&data
->app_MethodQueue
, (struct Node
*)mq
);
1733 ReleaseSemaphore(&data
->app_MethodSemaphore
);
1735 /* CHECKME: to wake task up as soon as possible! */
1736 Signal(data
->app_Task
,
1737 1L << data
->app_GlobalInfo
.mgi_WindowsPort
->mp_SigBit
);
1744 * MUIM_Application_ReturnID : Tell MUI to return the given id with
1745 * the next call to MUIM_Application_NewInput. kinda obsolete :)
1747 static IPTR
Application__MUIM_ReturnID(struct IClass
*cl
, Object
*obj
,
1748 struct MUIP_Application_ReturnID
*msg
)
1750 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1751 struct RIDNode
*rid
;
1754 if (!data->app_RIDMemChunk)
1756 data->app_RIDMemChunk =
1757 g_mem_chunk_create(struct RIDNode, 10, G_ALLOC_AND_FREE);
1760 rid
= CreateRIDNode(data
, msg
->retid
);
1763 AddTail((struct List
*)&data
->app_ReturnIDQueue
, (struct Node
*)rid
);
1769 * MUIM_FindUData : tests if the MUIA_UserData of the object
1770 * contains the given <udata> and returns the object pointer in this case.
1772 static IPTR
Application__MUIM_FindUData(struct IClass
*cl
, Object
*obj
,
1773 struct MUIP_FindUData
*msg
)
1775 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1777 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
1780 return DoMethodA(data
->app_WindowFamily
, (Msg
) msg
);
1785 * MUIM_GetUData : This method tests if the MUIA_UserData of the object
1786 * contains the given <udata> and gets <attr> to <storage> for itself
1789 static IPTR
Application__MUIM_GetUData(struct IClass
*cl
, Object
*obj
,
1790 struct MUIP_GetUData
*msg
)
1792 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1794 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
1796 get(obj
, msg
->attr
, msg
->storage
);
1799 return DoMethodA(data
->app_WindowFamily
, (Msg
) msg
);
1804 * MUIM_SetUData : This method tests if the MUIA_UserData of the object
1805 * contains the given <udata> and sets <attr> to <val> for itself in this case.
1807 static IPTR
Application__MUIM_SetUData(struct IClass
*cl
, Object
*obj
,
1808 struct MUIP_SetUData
*msg
)
1810 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1812 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
1813 set(obj
, msg
->attr
, msg
->val
);
1815 DoMethodA(data
->app_WindowFamily
, (Msg
) msg
);
1821 * MUIM_SetUDataOnce : This method tests if the MUIA_UserData of the object
1822 * contains the given <udata> and sets <attr> to <val> for itself in this case.
1824 static IPTR
Application__MUIM_SetUDataOnce(struct IClass
*cl
, Object
*obj
,
1825 struct MUIP_SetUDataOnce
*msg
)
1827 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1829 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
1831 set(obj
, msg
->attr
, msg
->val
);
1834 return DoMethodA(data
->app_WindowFamily
, (Msg
) msg
);
1838 /****** Application.mui/MUIM_Application_AboutMUI ****************************
1841 * MUIM_Application_AboutMUI (V14)
1844 * DoMethod(obj, MUIM_Application_AboutMUI, Object refwindow);
1847 * Show Zune's About window.
1850 * refwindow - the window object relative to which the About window will
1854 * MUIA_Window_RefWindow.
1856 ******************************************************************************
1860 static IPTR
Application__MUIM_AboutMUI(struct IClass
*cl
, Object
*obj
,
1861 struct MUIP_Application_AboutMUI
*msg
)
1863 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1865 if (!data
->app_AboutWin
)
1867 data
->app_AboutWin
= AboutmuiObject
,
1868 msg
->refwindow
? MUIA_Window_RefWindow
: TAG_IGNORE
,
1869 msg
->refwindow
, MUIA_Window_LeftEdge
,
1870 MUIV_Window_LeftEdge_Centered
, MUIA_Window_TopEdge
,
1871 MUIV_Window_TopEdge_Centered
, MUIA_Aboutmui_Application
, obj
,
1875 if (data
->app_AboutWin
)
1876 set(data
->app_AboutWin
, MUIA_Window_Open
, TRUE
);
1881 static IPTR
Application__MUIM_SetConfigdata(struct IClass
*cl
, Object
*obj
,
1882 struct MUIP_Application_SetConfigdata
*msg
)
1884 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1885 struct MinList
*children
= NULL
;
1889 get(data
->app_WindowFamily
, MUIA_Family_List
, &children
);
1892 cstate
= (Object
*) children
->mlh_Head
;
1893 if ((child
= NextObject(&cstate
)))
1895 D(bug("closing window %p\n", child
));
1897 set(child
, MUIA_Window_Open
, FALSE
);
1901 if (data
->app_GlobalInfo
.mgi_Configdata
)
1902 MUI_DisposeObject(data
->app_GlobalInfo
.mgi_Configdata
);
1903 data
->app_GlobalInfo
.mgi_Configdata
= msg
->configdata
;
1904 get(data
->app_GlobalInfo
.mgi_Configdata
, MUIA_Configdata_ZunePrefs
,
1905 &data
->app_GlobalInfo
.mgi_Prefs
);
1907 DoMethod(obj
, MUIM_Application_PushMethod
, (IPTR
) obj
, 1,
1908 MUIM_Application_OpenWindows
);
1913 /* MUIM_Application_OpenWindows
1914 * Opens all windows of an application
1916 static IPTR
Application__MUIM_OpenWindows(struct IClass
*cl
, Object
*obj
,
1917 struct MUIP_Application_OpenWindows
*msg
)
1919 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1920 struct MinList
*children
= NULL
;
1924 get(data
->app_WindowFamily
, MUIA_Family_List
, &children
);
1928 cstate
= (Object
*) children
->mlh_Head
;
1929 if ((child
= NextObject(&cstate
)))
1931 set(child
, MUIA_Window_Open
, TRUE
);
1937 static IPTR
Application__MUIM_OpenConfigWindow(struct IClass
*cl
,
1938 Object
*obj
, struct MUIP_Application_OpenConfigWindow
*msg
)
1940 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1941 struct TagItem tags
[] = {
1942 {SYS_Asynch
, FALSE
},
1945 {NP_StackSize
, AROS_STACKSIZE
},
1950 snprintf(cmd
, 255, "sys:prefs/Zune %s %ld",
1951 data
->app_Base
? data
->app_Base
: (STRPTR
) "", (long)obj
);
1953 if (SystemTagList(cmd
, tags
) == -1)
1961 snprintf(cmd
, 255, "ENV:zune/%s.prefs", data
->app_Base
);
1962 DoMethod(data
->app_GlobalInfo
.mgi_Configdata
, MUIM_Configdata_Load
,
1969 static IPTR
Application__MUIM_Execute(Class
*CLASS
, Object
*self
,
1975 (DoMethod(self
, MUIM_Application_NewInput
, (IPTR
) & signals
)
1976 != MUIV_Application_ReturnID_Quit
)
1980 signals
= Wait(signals
| SIGBREAKF_CTRL_C
);
1981 if (signals
& SIGBREAKF_CTRL_C
)
1990 static IPTR
Application__MUIM_UpdateMenus(struct IClass
*cl
, Object
*obj
,
1993 struct List
*wlist
= NULL
;
1997 get(obj
, MUIA_Application_WindowList
, &wlist
);
2001 wstate
= wlist
->lh_Head
;
2002 while ((curwin
= NextObject(&wstate
)))
2004 DoMethod(curwin
, MUIM_Window_UpdateMenu
);
2011 static IPTR
Application__MUIM_Load(struct IClass
*cl
, Object
*obj
,
2012 struct MUIP_Application_Load
*message
)
2014 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
2015 struct IFFHandle
*iff
;
2019 struct MinList
*children
= NULL
;
2023 if (!data
->app_Base
)
2026 dataspace
= MUI_NewObject(MUIC_Dataspace
, TAG_DONE
);
2030 if (message
->name
== MUIV_Application_Load_ENV
)
2031 snprintf(name
, sizeof(name
), "ENV:Zune/%s.cfg", data
->app_Base
);
2032 else if (message
->name
== MUIV_Application_Load_ENVARC
)
2033 snprintf(name
, sizeof(name
), "ENVARC:Zune/%s.cfg", data
->app_Base
);
2035 strncpy(name
, message
->name
, sizeof(name
));
2037 fh
= Open(name
, MODE_OLDFILE
);
2040 if ((iff
= AllocIFF()))
2042 iff
->iff_Stream
= (IPTR
) fh
;
2046 if (!OpenIFF(iff
, IFFF_READ
))
2048 if (!StopChunk(iff
, ID_PREF
, ID_MUIO
))
2050 if (!ParseIFF(iff
, IFFPARSE_SCAN
))
2052 DoMethod(dataspace
, MUIM_Dataspace_ReadIFF
, iff
,
2064 get(data
->app_WindowFamily
, MUIA_Family_List
, &children
);
2065 cstate
= (Object
*) children
->mlh_Head
;
2066 while ((child
= NextObject(&cstate
)))
2068 DoMethod(child
, MUIM_Import
, dataspace
);
2071 MUI_DisposeObject(dataspace
);
2076 static IPTR
Application__MUIM_Save(struct IClass
*cl
, Object
*obj
,
2077 struct MUIP_Application_Save
*message
)
2079 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
2080 struct IFFHandle
*iff
;
2084 struct MinList
*children
= NULL
;
2088 if (!data
->app_Base
)
2091 dataspace
= MUI_NewObject(MUIC_Dataspace
, TAG_DONE
);
2095 get(data
->app_WindowFamily
, MUIA_Family_List
, &children
);
2096 cstate
= (Object
*) children
->mlh_Head
;
2097 while ((child
= NextObject(&cstate
)))
2099 DoMethod(child
, MUIM_Export
, dataspace
);
2102 if (message
->name
== MUIV_Application_Save_ENV
)
2103 snprintf(name
, sizeof(name
), "ENV:Zune/%s.cfg", data
->app_Base
);
2104 else if (message
->name
== MUIV_Application_Save_ENVARC
)
2105 snprintf(name
, sizeof(name
), "ENVARC:Zune/%s.cfg", data
->app_Base
);
2107 strncpy(name
, message
->name
, sizeof(name
));
2109 fh
= Open(name
, MODE_NEWFILE
);
2112 if ((iff
= AllocIFF()))
2114 iff
->iff_Stream
= (IPTR
) fh
;
2118 if (!OpenIFF(iff
, IFFF_WRITE
))
2120 if (!PushChunk(iff
, ID_PREF
, ID_FORM
, IFFSIZE_UNKNOWN
))
2122 if (!PushChunk(iff
, ID_PREF
, ID_PRHD
,
2123 sizeof(struct FilePrefHeader
)))
2125 struct FilePrefHeader head
;
2127 head
.ph_Version
= PHV_CURRENT
;
2131 head
.ph_Flags
[2] = head
.ph_Flags
[3] = 0;
2133 if (WriteChunkBytes(iff
, &head
,
2134 sizeof(head
)) == sizeof(head
))
2137 DoMethod(dataspace
, MUIM_Dataspace_WriteIFF
,
2138 iff
, ID_PREF
, ID_MUIO
);
2154 MUI_DisposeObject(dataspace
);
2160 * The class dispatcher
2162 BOOPSI_DISPATCHER(IPTR
, Application_Dispatcher
, cl
, obj
, msg
)
2164 switch (msg
->MethodID
)
2167 return Application__OM_NEW(cl
, obj
, (struct opSet
*)msg
);
2169 return Application__OM_DISPOSE(cl
, obj
, msg
);
2171 return Application__OM_SET(cl
, obj
, (struct opSet
*)msg
);
2173 return Application__OM_GET(cl
, obj
, (struct opGet
*)msg
);
2175 return Application__OM_ADDMEMBER(cl
, obj
, (APTR
) msg
);
2177 return Application__OM_REMMEMBER(cl
, obj
, (APTR
) msg
);
2178 case MUIM_Application_AddInputHandler
:
2179 return Application__MUIM_AddInputHandler(cl
, obj
, (APTR
) msg
);
2180 case MUIM_Application_RemInputHandler
:
2181 return Application__MUIM_RemInputHandler(cl
, obj
, (APTR
) msg
);
2182 case MUIM_Application_Input
:
2183 return Application__MUIM_Input(cl
, obj
, (APTR
) msg
);
2184 case MUIM_Application_InputBuffered
:
2185 return Application__MUIM_InputBuffered(cl
, obj
, (APTR
) msg
);
2186 case MUIM_Application_NewInput
:
2187 return Application__MUIM_NewInput(cl
, obj
, (APTR
) msg
);
2188 case MUIM_Application_PushMethod
:
2189 return Application__MUIM_PushMethod(cl
, obj
, (APTR
) msg
);
2190 case MUIM_Application_ReturnID
:
2191 return Application__MUIM_ReturnID(cl
, obj
, (APTR
) msg
);
2192 case MUIM_FindUData
:
2193 return Application__MUIM_FindUData(cl
, obj
, (APTR
) msg
);
2195 return Application__MUIM_GetUData(cl
, obj
, (APTR
) msg
);
2197 return Application__MUIM_SetUData(cl
, obj
, (APTR
) msg
);
2198 case MUIM_SetUDataOnce
:
2199 return Application__MUIM_SetUDataOnce(cl
, obj
, (APTR
) msg
);
2200 case MUIM_Application_AboutMUI
:
2201 return Application__MUIM_AboutMUI(cl
, obj
, (APTR
) msg
);
2202 case MUIM_Application_SetConfigdata
:
2203 return Application__MUIM_SetConfigdata(cl
, obj
, (APTR
) msg
);
2204 case MUIM_Application_OpenWindows
:
2205 return Application__MUIM_OpenWindows(cl
, obj
, (APTR
) msg
);
2206 case MUIM_Application_OpenConfigWindow
:
2207 return Application__MUIM_OpenConfigWindow(cl
, obj
, (APTR
) msg
);
2208 case MUIM_Application_Execute
:
2209 return Application__MUIM_Execute(cl
, obj
, msg
);
2210 case MUIM_Application_UpdateMenus
:
2211 return Application__MUIM_UpdateMenus(cl
, obj
, msg
);
2212 case MUIM_Application_Load
:
2213 return Application__MUIM_Load(cl
, obj
, (APTR
) msg
);
2214 case MUIM_Application_Save
:
2215 return Application__MUIM_Save(cl
, obj
, (APTR
) msg
);
2218 return (DoSuperMethodA(cl
, obj
, msg
));
2220 BOOPSI_DISPATCHER_END
2224 const struct __MUIBuiltinClass _MUI_Application_desc
=
2228 sizeof(struct MUI_ApplicationData
),
2229 (void *) Application_Dispatcher