2 Copyright © 1999, David Le Corfec.
3 Copyright © 2002-2015, 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 done
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 MUIMasterBase_intern
*intZuneBase
= (struct MUIMasterBase_intern
*)MUIMasterBase
;
299 struct TrackingNode
*tn
;
300 Object
*retval
= NULL
;
302 ObtainSemaphore(&intZuneBase
->ZuneSemaphore
);
303 ForeachNode(&intZuneBase
->Applications
, tn
)
307 get(tn
->tn_Application
, MUIA_Application_Base
, &tn_base
);
309 if (tn_base
&& (strcmp(base
, tn_base
)) == 0)
311 retval
= tn
->tn_Application
;
315 ReleaseSemaphore(&intZuneBase
->ZuneSemaphore
);
320 /**************************************************************************
322 **************************************************************************/
323 static IPTR
Application__OM_NEW(struct IClass
*cl
, Object
*obj
,
326 struct MUI_ApplicationData
*data
;
327 struct TagItem
*tags
, *tag
;
328 BOOL bad_childs
= FALSE
;
330 obj
= (Object
*) DoSuperMethodA(cl
, obj
, (Msg
) msg
);
334 /* Initial local instance data */
335 data
= INST_DATA(cl
, obj
);
337 /* init input handler list */
338 NewList((struct List
*)&(data
->app_IHList
));
340 /* init input queue */
341 NewList((struct List
*)&(data
->app_MethodQueue
));
343 /* init return ids queue */
344 NewList((struct List
*)&(data
->app_ReturnIDQueue
));
347 data
->app_WindowFamily
= MUI_NewObjectA(MUIC_Family
, NULL
);
348 if (!data
->app_WindowFamily
)
350 CoerceMethod(cl
, obj
, OM_DISPOSE
);
354 data
->app_GlobalInfo
.mgi_ApplicationObject
= obj
;
355 if (!(data
->app_GlobalInfo
.mgi_WindowsPort
= CreateMsgPort()))
357 CoerceMethod(cl
, obj
, OM_DISPOSE
);
361 data
->app_Task
= FindTask(NULL
);
364 data
->app_SingleTask
=
365 (BOOL
) GetTagData(MUIA_Application_SingleTask
, FALSE
,
368 (STRPTR
) GetTagData(MUIA_Application_Base
, (IPTR
) "UNNAMED",
370 if (!data
->app_Base
|| strpbrk(data
->app_Base
, ":/()#?*,"))
372 data
->app_Base
= NULL
; /* don't remove */
373 CoerceMethod(cl
, obj
, OM_DISPOSE
);
378 if (!data
->app_SingleTask
)
380 /* must append .1, .2, ... to the base name */
384 for (i
= 1; i
< 1000; i
++)
386 snprintf(portname
, 255, "%s.%d", data
->app_Base
, (int)i
);
387 if (!find_application_by_base(cl
, obj
, portname
))
390 data
->app_Base
= StrDup(portname
);
396 ObtainSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
397 if ((other_app
= find_application_by_base(cl
, obj
, data
->app_Base
)))
399 //FIXME "Is calling MUIM_Application_PushMethod on an alien
400 //application object safe?"
401 DoMethod(other_app
, MUIM_Application_PushMethod
,
402 (IPTR
) other_app
, 3, MUIM_Set
, MUIA_Application_DoubleStart
,
404 data
->app_Base
= NULL
;
406 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
408 data
->app_Base
= StrDup(data
->app_Base
);
413 CoerceMethod(cl
, obj
, OM_DISPOSE
);
417 data
->app_GlobalInfo
.mgi_Configdata
=
418 MUI_NewObject(MUIC_Configdata
, MUIA_Configdata_Application
, obj
,
420 if (!data
->app_GlobalInfo
.mgi_Configdata
)
422 CoerceMethod(cl
, obj
, OM_DISPOSE
);
425 get(data
->app_GlobalInfo
.mgi_Configdata
, MUIA_Configdata_ZunePrefs
,
426 &data
->app_GlobalInfo
.mgi_Prefs
);
428 // D(bug("muimaster.library/application.c: Message Port created at 0x%lx\n",
429 // data->app_GlobalInfo.mgi_WindowPort));
431 /* Setup timer stuff */
432 if (!(data
->app_TimerPort
= CreateMsgPort()))
434 CoerceMethod(cl
, obj
, OM_DISPOSE
);
438 if (!(data
->app_TimerReq
=
439 (struct timerequest
*)CreateIORequest(data
->app_TimerPort
,
440 sizeof(struct timerequest
))))
442 CoerceMethod(cl
, obj
, OM_DISPOSE
);
446 if (OpenDevice(TIMERNAME
, UNIT_VBLANK
,
447 (struct IORequest
*)data
->app_TimerReq
, 0))
449 CoerceMethod(cl
, obj
, OM_DISPOSE
);
453 InitSemaphore(&data
->app_MethodSemaphore
);
455 muiNotifyData(obj
)->mnd_GlobalInfo
= &data
->app_GlobalInfo
;
457 /* parse initial taglist */
459 data
->app_Active
= 1;
460 data
->app_Title
= "Unnamed";
461 data
->app_Version
= "Unnamed 0.0";
462 data
->app_Description
= "?";
464 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
));)
468 case MUIA_Application_Author
:
469 data
->app_Author
= (STRPTR
) tag
->ti_Data
;
472 case MUIA_Application_Base
:
473 /* moved before config parsing */
476 case MUIA_Application_Copyright
:
477 data
->app_Copyright
= (STRPTR
) tag
->ti_Data
;
480 case MUIA_Application_Description
:
481 data
->app_Description
= (STRPTR
) tag
->ti_Data
;
484 case MUIA_Application_HelpFile
:
485 data
->app_HelpFile
= (STRPTR
) tag
->ti_Data
;
488 case MUIA_Application_SingleTask
:
489 /* moved before config parsing */
492 case MUIA_Application_Title
:
493 data
->app_Title
= (STRPTR
) tag
->ti_Data
;
496 case MUIA_Application_Version
:
497 data
->app_Version
= (STRPTR
) tag
->ti_Data
;
500 case MUIA_Application_Version_Number
:
501 data
->app_Version_Number
= (STRPTR
) tag
->ti_Data
;
504 case MUIA_Application_Version_Date
:
505 data
->app_Version_Date
= (STRPTR
) tag
->ti_Data
;
508 case MUIA_Application_Version_Extra
:
509 data
->app_Version_Extra
= (STRPTR
) tag
->ti_Data
;
512 case MUIA_Application_Window
:
514 DoMethod(obj
, OM_ADDMEMBER
, tag
->ti_Data
);
519 case MUIA_Application_Menustrip
:
520 data
->app_Menustrip
= (Object
*) tag
->ti_Data
;
523 case MUIA_Application_BrokerPri
:
524 data
->app_BrokerPri
= (BYTE
) tag
->ti_Data
;
527 case MUIA_Application_BrokerHook
:
528 data
->app_BrokerHook
= (struct Hook
*)tag
->ti_Data
;
531 case MUIA_Application_Active
:
532 data
->app_Active
= tag
->ti_Data
? TRUE
: FALSE
;
535 case MUIA_Application_UsedClasses
:
537 STRPTR
*list
= (STRPTR
*) tag
->ti_Data
;
542 struct IClass
*icl
= MUI_GetClass(*list
);
550 case MUIA_Application_UseRexx
:
551 data
->app_UseRexx
= tag
->ti_Data
? TRUE
: FALSE
;
554 case MUIA_Application_Commands
:
555 data
->app_Commands
= (struct MUI_Command
*)tag
->ti_Data
;
558 case MUIA_Application_RexxHook
:
559 data
->app_RexxHook
= (struct Hook
*)tag
->ti_Data
;
562 case MUIA_Application_DiskObject
:
563 data
->app_DiskObject
= (struct DiskObject
*)tag
->ti_Data
;
569 /* create MUIA_Application_Version if NULL */
570 if (data
->app_Version
== NULL
571 && data
->app_Title
!= NULL
&& data
->app_Version_Number
!= NULL
)
573 STRPTR result
= NULL
;
576 /* Calculate length */
577 length
= strlen("$VER: ") + strlen(data
->app_Title
) + 1 /* space */
578 + strlen(data
->app_Version_Number
) + 1 /* NULL */ ;
580 if (data
->app_Version_Date
!= NULL
)
582 length
+= 1 /* space */ + 1 /* ( */
583 + strlen(data
->app_Version_Date
) + 1 /* ) */ ;
586 if (data
->app_Version_Extra
!= NULL
)
588 length
+= 1 /* space */ + 1 /* [ */
589 + strlen(data
->app_Version_Extra
) + 1 /* ] */ ;
592 /* Allocate memory */
593 result
= AllocVec(length
, MEMF_ANY
);
600 strlcat(result
, "$VER: ", length
);
601 strlcat(result
, data
->app_Title
, length
);
602 strlcat(result
, " ", length
);
603 strlcat(result
, data
->app_Version_Number
, length
);
605 if (data
->app_Version_Date
!= NULL
)
607 strlcat(result
, " (", length
);
608 strlcat(result
, data
->app_Version_Date
, length
);
609 strlcat(result
, ")", length
);
612 if (data
->app_Version_Extra
!= NULL
)
614 strlcat(result
, " [", length
);
615 strlcat(result
, data
->app_Version_Extra
, length
);
616 strlcat(result
, "]", length
);
619 data
->app_Version
= result
;
620 data
->app_VersionAllocated
= TRUE
;
627 CoerceMethod(cl
, obj
, OM_DISPOSE
);
632 && GetTagData(MUIA_Application_UseCommodities
, TRUE
,
635 data
->app_BrokerPort
= CreateMsgPort();
637 if (data
->app_BrokerPort
)
641 nb
.nb_Version
= NB_VERSION
;
643 data
->app_Title
? data
->app_Title
: (STRPTR
) "Unnamed";
645 data
->app_Version
? data
->app_Version
: (STRPTR
) "Unnamed";
647 data
->app_Description
? data
->
648 app_Description
: (STRPTR
) "?";
650 nb
.nb_Flags
= COF_SHOW_HIDE
;
651 nb
.nb_Pri
= data
->app_BrokerPri
;
652 nb
.nb_Port
= data
->app_BrokerPort
;
653 nb
.nb_ReservedChannel
= 0;
655 if (strncmp(nb
.nb_Title
, "$VER: ", 6) == 0)
658 data
->app_Broker
= CxBroker(&nb
, 0);
660 if (data
->app_Broker
)
662 if (data
->app_Active
)
663 ActivateCxObj(data
->app_Broker
, 1);
668 if (data
->app_UseRexx
)
670 data
->app_RexxPort
= CreateMsgPort();
671 if (data
->app_RexxPort
)
673 data
->app_RexxPort
->mp_Node
.ln_Name
= StrDup(data
->app_Base
);
674 if (data
->app_RexxPort
->mp_Node
.ln_Name
!= NULL
)
676 D(bug("[MUI] %s is using REXX!\n",
677 data
->app_RexxPort
->mp_Node
.ln_Name
));
679 for (i
= data
->app_RexxPort
->mp_Node
.ln_Name
; *i
!= '\0';
684 AddPort(data
->app_RexxPort
);
688 DeleteMsgPort(data
->app_RexxPort
);
689 data
->app_RexxPort
= NULL
;
694 if (data
->app_Menustrip
)
695 DoMethod(data
->app_Menustrip
, MUIM_ConnectParent
, (IPTR
) obj
);
697 data
->app_AppPort
= CreateMsgPort();
698 data
->app_GlobalInfo
.mgi_AppPort
= data
->app_AppPort
;
699 if (data
->app_AppPort
== NULL
)
701 CoerceMethod(cl
, obj
, OM_DISPOSE
);
705 ObtainSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
706 data
->app_TrackingNode
.tn_Application
= obj
;
707 AddTail((struct List
*)&MUIMB(MUIMasterBase
)->Applications
,
708 (struct Node
*)&data
->app_TrackingNode
);
709 data
->app_is_TNode_in_list
= TRUE
;
710 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
717 /**************************************************************************
719 **************************************************************************/
720 static IPTR
Application__OM_DISPOSE(struct IClass
*cl
, Object
*obj
,
723 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
730 positionmode
= data
->app_GlobalInfo
.mgi_Prefs
->window_position
;
731 if (positionmode
>= 1)
733 snprintf(filename
, 255, "ENV:zune/%s.prefs", data
->app_Base
);
734 DoMethod(data
->app_GlobalInfo
.mgi_Configdata
,
735 MUIM_Configdata_Save
, (IPTR
) filename
);
737 if (positionmode
== 2)
739 snprintf(filename
, 255, "ENVARC:zune/%s.prefs", data
->app_Base
);
740 DoMethod(data
->app_GlobalInfo
.mgi_Configdata
,
741 MUIM_Configdata_Save
, (IPTR
) filename
);
745 if (data
->app_is_TNode_in_list
)
747 ObtainSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
748 Remove((struct Node
*)&data
->app_TrackingNode
);
749 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
752 if (data
->app_WindowFamily
)
754 struct MinList
*children
= NULL
;
758 /* special loop because the next object may have been removed/freed by
759 * the previous. so restart from listhead each time.
763 get(data
->app_WindowFamily
, MUIA_Family_List
, &children
);
764 if (children
== NULL
)
767 cstate
= (Object
*) children
->mlh_Head
;
768 if ((child
= NextObject(&cstate
)))
770 D(bug("Application_Dispose(%p) : OM_REMMEMBER(%p)\n", obj
,
772 DoMethod(obj
, OM_REMMEMBER
, (IPTR
) child
);
773 D(bug("Application_Dispose(%p) : MUI_DisposeObject(%p)\n",
775 MUI_DisposeObject(child
);
783 MUI_DisposeObject(data
->app_WindowFamily
);
786 if (data
->app_Menustrip
)
787 MUI_DisposeObject(data
->app_Menustrip
);
789 if (data
->app_VersionAllocated
&& data
->app_Version
!= NULL
)
791 FreeVec(data
->app_Version
);
794 /* free commodities stuff */
796 if (data
->app_Broker
)
798 DeleteCxObjAll(data
->app_Broker
);
801 if (data
->app_BrokerPort
)
805 while ((msg
= GetMsg(data
->app_BrokerPort
)))
810 DeleteMsgPort(data
->app_BrokerPort
);
813 /* free timer stuff */
814 if (data
->app_TimerReq
)
816 if (data
->app_TimerReq
->tr_node
.io_Device
)
818 while (data
->app_TimerOutstanding
)
820 if (Wait(1L << data
->app_TimerPort
->
821 mp_SigBit
| 4096) & 4096)
823 data
->app_TimerOutstanding
--;
825 CloseDevice((struct IORequest
*)data
->app_TimerReq
);
827 DeleteIORequest((struct IORequest
*)data
->app_TimerReq
);
829 DeleteMsgPort(data
->app_TimerPort
);
831 if (data
->app_RexxPort
)
834 while ((msg
= GetMsg(data
->app_RexxPort
)))
838 RemPort(data
->app_RexxPort
);
840 FreeVec(data
->app_RexxPort
->mp_Node
.ln_Name
);
841 DeleteMsgPort(data
->app_RexxPort
);
844 if (data
->app_AppIcon
)
845 RemoveAppIcon(data
->app_AppIcon
);
847 if (data
->app_DefaultDiskObject
)
848 FreeDiskObject(data
->app_DefaultDiskObject
);
850 if (data
->app_AppPort
)
853 while ((msg
= GetMsg(data
->app_AppPort
)))
856 DeleteMsgPort(data
->app_AppPort
);
859 if (data
->app_GlobalInfo
.mgi_Configdata
)
860 MUI_DisposeObject(data
->app_GlobalInfo
.mgi_Configdata
);
862 DeleteMsgPort(data
->app_GlobalInfo
.mgi_WindowsPort
);
864 FreeVec(data
->app_Base
);
866 /* free returnid stuff */
869 (struct RIDNode
*)RemHead((struct List
*)&data
->
872 DeleteRIDNode(data
, rid
);
875 return DoSuperMethodA(cl
, obj
, msg
);
879 /**************************************************************************
881 **************************************************************************/
882 static IPTR
Application__OM_SET(struct IClass
*cl
, Object
*obj
,
885 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
886 struct TagItem
*tags
= msg
->ops_AttrList
;
889 /* There are many ways to find out what tag items provided by set()
890 ** we do know. The best way should be using NextTagItem() and simply
891 ** browsing through the list.
893 while ((tag
= NextTagItem(&tags
)) != NULL
)
899 case MUIA_Application_SearchWinId
:
900 data
->searchwinid
= tag
->ti_Data
;
903 case MUIA_Application_CopyWinPosToApp
:
904 addr
= (IPTR
*) tag
->ti_Data
;
905 CopyMem((CONST_APTR
) tag
->ti_Data
, &data
->winposused
, *(addr
));
908 case MUIA_Application_SetWinPos
:
910 struct windowpos
*winp
;
911 winp
= (struct windowpos
*)tag
->ti_Data
;
912 //kprintf("SetWinPos %d %d %d %d %d\n", winp->id, winp->x1,
913 // winp->y1, winp->w1, winp->h1);
915 for (i
= 0; i
< MAXWINS
- 1; i
++)
917 if (data
->winpos
[i
].w1
)
919 if (winp
->id
== data
->winpos
[i
].id
)
921 //existing entry is overwritten
922 data
->winpos
[i
].x1
= winp
->x1
;
923 data
->winpos
[i
].y1
= winp
->y1
;
924 data
->winpos
[i
].w1
= winp
->w1
;
925 data
->winpos
[i
].h1
= winp
->h1
;
926 data
->winpos
[i
].x2
= winp
->x2
;
927 data
->winpos
[i
].y2
= winp
->y2
;
928 data
->winpos
[i
].w2
= winp
->w2
;
929 data
->winpos
[i
].h2
= winp
->h2
;
935 // a new entry is added
936 data
->winpos
[i
].id
= winp
->id
;
937 data
->winpos
[i
].x1
= winp
->x1
;
938 data
->winpos
[i
].y1
= winp
->y1
;
939 data
->winpos
[i
].w1
= winp
->w1
;
940 data
->winpos
[i
].h1
= winp
->h1
;
941 data
->winpos
[i
].x2
= winp
->x2
;
942 data
->winpos
[i
].y2
= winp
->y2
;
943 data
->winpos
[i
].w2
= winp
->w2
;
944 data
->winpos
[i
].h2
= winp
->h2
;
951 case MUIA_Application_Configdata
:
952 DoMethod(obj
, MUIM_Application_PushMethod
, (IPTR
) obj
, 2,
953 MUIM_Application_SetConfigdata
, tag
->ti_Data
);
956 case MUIA_Application_HelpFile
:
957 data
->app_HelpFile
= (STRPTR
) tag
->ti_Data
;
960 case MUIA_Application_Iconified
:
962 BOOL do_iconify
= tag
->ti_Data
== 1;
963 if (data
->app_Iconified
!= do_iconify
)
965 data
->app_Iconified
= do_iconify
;
967 nnset(obj
, MUIA_ShowMe
, !data
->app_Iconified
);
969 /* Inform workbench.library */
970 if (data
->app_Iconified
)
973 data
->app_Title
? data
->
974 app_Title
: (STRPTR
) "Unnamed";
975 struct DiskObject
*dobj
=
976 (struct DiskObject
*)XGET(obj
,
977 MUIA_Application_DiskObject
);
981 /* Get default AppIcon in ENV:SYS or ENVARC:SYS */
982 dobj
= GetDefDiskObject(WBAPPICON
);
984 data
->app_DefaultDiskObject
= dobj
;
987 /* First default: ENV:SYS/def_MUI.info */
988 dobj
= GetDiskObject("ENV:SYS/def_MUI");
990 data
->app_DefaultDiskObject
= dobj
;
993 /* Second default: ENV:SYS/def_Zune.info */
995 GetDiskObject("ENV:SYS/def_Zune");
997 data
->app_DefaultDiskObject
= dobj
;
1000 /* Third default: default tool icon */
1001 dobj
= GetDefDiskObject(WBTOOL
);
1003 data
->app_DefaultDiskObject
=
1013 dobj
->do_CurrentX
= NO_ICON_POSITION
;
1014 dobj
->do_CurrentY
= NO_ICON_POSITION
;
1017 AddAppIconA(0L, 0L, appname
, data
->app_AppPort
,
1022 if (data
->app_AppIcon
)
1024 RemoveAppIcon(data
->app_AppIcon
);
1025 data
->app_AppIcon
= NULL
;
1027 if (data
->app_DefaultDiskObject
)
1029 FreeDiskObject(data
->app_DefaultDiskObject
);
1030 data
->app_DefaultDiskObject
= NULL
;
1039 /* Ok ok, you think this stinks? Well, think of it as
1040 an attribute belonging to an interface which
1041 MUIC_Application, together with MUIC_Area and a few
1042 others implement. It makes sense now, yes? */
1043 struct List
*wlist
= NULL
;
1045 Object
*curwin
= NULL
;
1046 Object
*lastwin
= NULL
;
1048 /* MUIA_ShowMe can cause MUIM_Setup/MUIM_Cleanup to be issued.
1049 * On the other hand it is allowed to add/remove other
1050 * application windows in MUIM_Setup/MUIM_Cleanup.
1051 * This means after processing a window from internal list,
1052 * the list needs to be re-read and iteration started again,
1053 * because wstate can become invalid.
1054 * Note: The code below assumes that the window won't remove
1055 * itself from the list.
1060 get(data
->app_WindowFamily
, MUIA_Family_List
, &wlist
);
1061 wstate
= (Object
*) wlist
->lh_Head
;
1062 while ((curwin
= NextObject(&wstate
)))
1064 if (lastwin
== NULL
)
1066 if (curwin
== lastwin
)
1068 curwin
= NextObject(&wstate
);
1073 /* This is the window to be processed */
1076 set(curwin
, MUIA_ShowMe
, tag
->ti_Data
);
1081 /* No more windows */
1088 case MUIA_Application_Sleep
:
1090 struct List
*wlist
= NULL
;
1096 data
->app_SleepCount
++;
1097 if (data
->app_SleepCount
== 1)
1099 get(obj
, MUIA_Application_WindowList
, &wlist
);
1102 wstate
= wlist
->lh_Head
;
1103 while ((curwin
= NextObject(&wstate
)))
1105 set(curwin
, MUIA_Window_Sleep
, TRUE
);
1112 data
->app_SleepCount
--;
1113 if (data
->app_SleepCount
== 0)
1115 get(obj
, MUIA_Application_WindowList
, &wlist
);
1118 wstate
= wlist
->lh_Head
;
1119 while ((curwin
= NextObject(&wstate
)))
1121 set(curwin
, MUIA_Window_Sleep
, FALSE
);
1129 case MUIA_Application_MenuAction
:
1130 data
->app_MenuAction
= tag
->ti_Data
;
1133 case MUIA_Application_BrokerHook
:
1134 data
->app_BrokerHook
= (struct Hook
*)tag
->ti_Data
;
1137 case MUIA_Application_Active
:
1138 data
->app_Active
= tag
->ti_Data
? TRUE
: FALSE
;
1139 if (data
->app_Broker
)
1141 ActivateCxObj(data
->app_Broker
, data
->app_Active
);
1145 case MUIA_Application_Commands
:
1146 data
->app_Commands
= (struct MUI_Command
*)tag
->ti_Data
;
1149 case MUIA_Application_RexxString
:
1150 data
->app_RexxString
= (STRPTR
) tag
->ti_Data
;
1153 case MUIA_Application_RexxHook
:
1154 data
->app_RexxHook
= (struct Hook
*)tag
->ti_Data
;
1157 case MUIA_Application_DiskObject
:
1158 data
->app_DiskObject
= (struct DiskObject
*)tag
->ti_Data
;
1163 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
1170 static IPTR
Application__OM_GET(struct IClass
*cl
, Object
*obj
,
1173 #define STORE *(msg->opg_Storage)
1175 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1177 switch (msg
->opg_AttrID
)
1179 case MUIA_Application_GetWinPosAddr
:
1180 STORE
= (IPTR
) & data
->winposused
;
1183 case MUIA_Application_GetWinPosSize
:
1186 for (i
= 0; i
< MAXWINS
- 1; i
++)
1188 if (!data
->winpos
[i
].w1
)
1190 i
*= sizeof(struct windowpos
);
1192 data
->winposused
= i
;
1201 case MUIA_Application_GetWinPos
:
1204 if (data
->searchwinid
)
1206 for (i
= 0; i
< MAXWINS
- 1; i
++)
1208 if (data
->winpos
[i
].w1
)
1210 if (data
->searchwinid
== data
->winpos
[i
].id
)
1212 STORE
= (IPTR
) & data
->winpos
[i
].id
;
1233 case MUIA_Application_Author
:
1234 STORE
= (IPTR
) data
->app_Author
;
1237 case MUIA_Application_Base
:
1238 STORE
= (IPTR
) data
->app_Base
;
1241 case MUIA_Application_Copyright
:
1242 STORE
= (IPTR
) data
->app_Copyright
;
1245 case MUIA_Application_Description
:
1246 STORE
= (IPTR
) data
->app_Description
;
1249 case MUIA_Application_DoubleStart
:
1252 case MUIA_Application_ForceQuit
:
1253 STORE
= (IPTR
) data
->app_ForceQuit
;
1256 case MUIA_Application_HelpFile
:
1257 STORE
= (IPTR
) data
->app_HelpFile
;
1260 case MUIA_Application_Iconified
:
1261 STORE
= (IPTR
) data
->app_Iconified
;
1264 case MUIA_Application_Title
:
1265 STORE
= (IPTR
) data
->app_Title
;
1268 case MUIA_Application_Version
:
1269 STORE
= (IPTR
) data
->app_Version
;
1272 case MUIA_Application_Version_Number
:
1273 STORE
= (IPTR
) data
->app_Version_Number
;
1276 case MUIA_Application_Version_Date
:
1277 STORE
= (IPTR
) data
->app_Version_Date
;
1280 case MUIA_Application_Version_Extra
:
1281 STORE
= (IPTR
) data
->app_Version_Extra
;
1284 case MUIA_Application_WindowList
:
1285 return GetAttr(MUIA_Family_List
, data
->app_WindowFamily
,
1288 case MUIA_Application_Menustrip
:
1289 STORE
= (IPTR
) data
->app_Menustrip
;
1292 case MUIA_Application_MenuAction
:
1293 STORE
= (IPTR
) data
->app_MenuAction
;
1296 case MUIA_Application_BrokerPort
:
1297 STORE
= (IPTR
) data
->app_BrokerPort
;
1300 case MUIA_Application_BrokerPri
:
1301 STORE
= (IPTR
) data
->app_BrokerPri
;
1304 case MUIA_Application_BrokerHook
:
1305 STORE
= (IPTR
) data
->app_BrokerHook
;
1308 case MUIA_Application_Broker
:
1309 STORE
= (IPTR
) data
->app_Broker
;
1312 case MUIA_Application_Active
:
1313 STORE
= data
->app_Active
;
1316 case MUIA_Application_Commands
:
1317 STORE
= (IPTR
) data
->app_Commands
;
1320 case MUIA_Application_RexxMsg
:
1321 STORE
= (IPTR
) data
->app_RexxMsg
;
1324 case MUIA_Application_RexxHook
:
1325 STORE
= (IPTR
) data
->app_RexxHook
;
1328 case MUIA_Application_DiskObject
:
1329 STORE
= (IPTR
) data
->app_DiskObject
;
1333 /* our handler didn't understand the attribute, we simply pass
1334 ** it to our superclass now
1336 return (DoSuperMethodA(cl
, obj
, (Msg
) msg
));
1341 /**************************************************************************
1343 **************************************************************************/
1344 static IPTR
Application__OM_ADDMEMBER(struct IClass
*cl
, Object
*obj
,
1345 struct opMember
*msg
)
1347 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1349 D(bug("Application_AddMember: Adding 0x%lx to window member list\n",
1352 DoMethodA(data
->app_WindowFamily
, (Msg
) msg
);
1353 /* Application knows its GlobalInfo, so we can inform window */
1354 DoMethod(msg
->opam_Object
, MUIM_ConnectParent
, (IPTR
) obj
);
1359 /**************************************************************************
1361 **************************************************************************/
1362 static IPTR
Application__OM_REMMEMBER(struct IClass
*cl
, Object
*obj
,
1363 struct opMember
*msg
)
1365 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1367 D(bug("Application_RemMember: Removing 0x%lx from window member list\n",
1370 DoMethod(msg
->opam_Object
, MUIM_DisconnectParent
);
1371 DoMethodA(data
->app_WindowFamily
, (Msg
) msg
);
1378 /**************************************************************************
1379 MUIM_Application_AddInputHandler
1380 **************************************************************************/
1381 static IPTR
Application__MUIM_AddInputHandler(struct IClass
*cl
,
1382 Object
*obj
, struct MUIP_Application_AddInputHandler
*msg
)
1384 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1386 if (msg
->ihnode
->ihn_Flags
& MUIIHNF_TIMER
)
1388 struct timerequest_ext
*time_ext
=
1389 (struct timerequest_ext
*)AllocVec(sizeof(struct
1390 timerequest_ext
), MEMF_PUBLIC
);
1393 /* Store the request inside the input handler, so that we can
1394 ** remove the inputhandler without problems */
1395 msg
->ihnode
->ihn_Node
.mln_Pred
= (struct MinNode
*)time_ext
;
1397 time_ext
->treq
= *data
->app_TimerReq
;
1398 time_ext
->treq
.tr_node
.io_Command
= TR_ADDREQUEST
;
1399 time_ext
->treq
.tr_time
.tv_secs
= msg
->ihnode
->ihn_Millis
/ 1000;
1400 time_ext
->treq
.tr_time
.tv_micro
=
1401 (msg
->ihnode
->ihn_Millis
% 1000) * 1000;
1402 time_ext
->ihn
= msg
->ihnode
;
1403 SendIO((struct IORequest
*)time_ext
);
1407 AddTail((struct List
*)&data
->app_IHList
,
1408 (struct Node
*)msg
->ihnode
);
1413 /**************************************************************************
1414 MUIM_Application_RemInputHandler
1415 **************************************************************************/
1416 static IPTR
Application__MUIM_RemInputHandler(struct IClass
*cl
,
1417 Object
*obj
, struct MUIP_Application_RemInputHandler
*msg
)
1419 //struct MUI_ApplicationData *data = INST_DATA(cl, obj);
1420 if (msg
->ihnode
->ihn_Flags
& MUIIHNF_TIMER
)
1422 struct timerequest_ext
*time_ext
=
1423 (struct timerequest_ext
*)msg
->ihnode
->ihn_Node
.mln_Pred
;
1424 if (!CheckIO((struct IORequest
*)time_ext
))
1425 AbortIO((struct IORequest
*)time_ext
);
1426 WaitIO((struct IORequest
*)time_ext
);
1430 Remove((struct Node
*)msg
->ihnode
);
1436 void _zune_window_message(struct IntuiMessage
*imsg
); /* from window.c */
1439 * MUIM_Application_InputBuffered : process all pending events
1441 static IPTR
Application__MUIM_InputBuffered(struct IClass
*cl
, Object
*obj
,
1442 struct MUIP_Application_InputBuffered
*msg
)
1444 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1445 struct IntuiMessage
*imsg
;
1447 /* process all pushed methods */
1448 while (application_do_pushed_method(data
))
1452 (struct IntuiMessage
*)GetMsg(data
->app_GlobalInfo
.mgi_WindowsPort
);
1455 /* Let window object process message */
1456 _zune_window_message(imsg
); /* will reply the message */
1461 /**************************************************************************
1462 MUIM_Application_NewInput : application main loop
1463 **************************************************************************/
1464 static IPTR
Application__MUIM_NewInput(struct IClass
*cl
, Object
*obj
,
1465 struct MUIP_Application_NewInput
*msg
)
1467 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1468 struct RIDNode
*rid
;
1470 ULONG signal
, signalmask
;
1471 ULONG handler_mask
= 0; /* the mask of the signal handlers */
1474 //struct MinNode ihn_Node;
1476 signal
= *msg
->signal
;
1478 /* process all pushed methods */
1479 while (application_do_pushed_method(data
))
1482 /* query the signal for the handlers */
1483 for (mn
= data
->app_IHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
1485 struct MUI_InputHandlerNode
*ihn
;
1486 ihn
= (struct MUI_InputHandlerNode
*)mn
;
1487 handler_mask
|= ihn
->ihn_Signals
;
1490 signalmask
= (1L << data
->app_GlobalInfo
.mgi_WindowsPort
->mp_SigBit
)
1491 | (1L << data
->app_TimerPort
->mp_SigBit
) | handler_mask
;
1493 if (data
->app_Broker
)
1494 signalmask
|= (1L << data
->app_BrokerPort
->mp_SigBit
);
1496 if (data
->app_RexxPort
)
1497 signalmask
|= (1L << data
->app_RexxPort
->mp_SigBit
);
1499 if (data
->app_AppPort
)
1500 signalmask
|= (1L << data
->app_AppPort
->mp_SigBit
);
1504 /* Stupid app which (always) passes 0 in signals. It's impossible to
1505 know which signals were really set as the app will already have
1506 called Wait() which has cleared the task's tc_SigRecvd. So assume
1507 the window, timer, and broker signals all to be set. Also all of
1508 the inputhandler signals (MUI does that too). */
1510 signal
= signalmask
;
1513 if (signal
& signalmask
)
1515 if (signal
& (1L << data
->app_GlobalInfo
.mgi_WindowsPort
->
1518 struct IntuiMessage
*imsg
;
1519 /* process all pushed methods */
1522 (struct IntuiMessage
*)GetMsg(data
->app_GlobalInfo
.
1525 /* Let window object process message */
1526 _zune_window_message(imsg
); /* will reply the message */
1530 if (signal
& (1L << data
->app_TimerPort
->mp_SigBit
))
1532 struct timerequest_ext
*time_ext
;
1537 /* At first we fetch all messages from the message port and store
1538 ** them in a list, we use the node of the Message here */
1540 (struct timerequest_ext
*)GetMsg(data
->app_TimerPort
)))
1541 AddTail(&list
, (struct Node
*)time_ext
);
1543 /* Now we proccess the list and resend the timer io, no loop can
1544 ** happen. We use RemHead() because the handler can remove it
1545 ** itself and so a FreeVec() could happen in
1546 ** MUIM_Application_RemInputHandler which would destroy the
1547 ** ln->Succ of course */
1548 while ((n
= RemHead(&list
)))
1550 struct timerequest_ext
*time_ext
=
1551 (struct timerequest_ext
*)n
;
1552 struct MUI_InputHandlerNode
*ihn
= time_ext
->ihn
;
1553 time_ext
->treq
.tr_time
.tv_secs
=
1554 time_ext
->ihn
->ihn_Millis
/ 1000;
1555 time_ext
->treq
.tr_time
.tv_micro
=
1556 (time_ext
->ihn
->ihn_Millis
% 1000) * 1000;
1557 SendIO((struct IORequest
*)&time_ext
->treq
);
1558 DoMethod(ihn
->ihn_Object
, ihn
->ihn_Method
);
1562 if (data
->app_BrokerPort
1563 && (signal
& (1L << data
->app_BrokerPort
->mp_SigBit
)))
1567 while ((msg
= (CxMsg
*) GetMsg(data
->app_BrokerPort
)))
1569 switch (CxMsgType(msg
))
1572 switch (CxMsgID(msg
))
1575 set(obj
, MUIA_Application_Active
, FALSE
);
1579 set(obj
, MUIA_Application_Active
, TRUE
);
1583 case CXCMD_DISAPPEAR
:
1584 /* No default handling - application needs to be in
1585 * control of this */
1589 SetSignal(SIGBREAKF_CTRL_C
, SIGBREAKF_CTRL_C
);
1595 if (data
->app_BrokerHook
)
1597 CallHookPkt(data
->app_BrokerHook
, obj
, msg
);
1600 ReplyMsg((struct Message
*)msg
);
1604 if (data
->app_RexxPort
1605 && (signal
& (1L << data
->app_RexxPort
->mp_SigBit
)))
1608 D(bug("[MUI] Got Rexx message!\n"));
1609 struct Message
*msg
;
1610 while ((msg
= GetMsg(data
->app_RexxPort
)))
1616 if (data
->app_AppPort
1617 && (signal
& (1L << data
->app_AppPort
->mp_SigBit
)))
1619 struct AppMessage
*appmsg
;
1621 (struct AppMessage
*)GetMsg(data
->app_AppPort
)))
1623 if ((appmsg
->am_Type
== AMTYPE_APPICON
)
1624 && (appmsg
->am_NumArgs
== 0)
1625 && (appmsg
->am_ArgList
== NULL
)
1626 && (XGET(obj
, MUIA_Application_Iconified
) == TRUE
))
1628 /* Reply before removing AppIcon */
1629 ReplyMsg((struct Message
*)appmsg
);
1630 set(obj
, MUIA_Application_Iconified
, FALSE
);
1633 else if (appmsg
->am_Type
== AMTYPE_APPWINDOW
)
1635 set((Object
*) appmsg
->am_UserData
, MUIA_AppMessage
,
1639 ReplyMsg((struct Message
*)appmsg
);
1643 if (signal
& handler_mask
)
1645 for (mn
= data
->app_IHList
.mlh_Head
; mn
->mln_Succ
;
1648 struct MUI_InputHandlerNode
*ihn
;
1649 ihn
= (struct MUI_InputHandlerNode
*)mn
;
1650 if (signal
& ihn
->ihn_Signals
)
1651 DoMethod(ihn
->ihn_Object
, ihn
->ihn_Method
);
1656 /* process all pushed methods - again */
1657 while (application_do_pushed_method(data
))
1660 *msg
->signal
= signalmask
;
1662 /* set return code */
1664 (struct RIDNode
*)RemHead((struct List
*)&data
->
1665 app_ReturnIDQueue
)))
1667 retval
= rid
->rid_Value
;
1668 DeleteRIDNode(data
, rid
);
1674 /**************************************************************************
1675 MUIM_Application_Input : application main loop
1676 This method shouldn't be used in any new program. As it polls all signals.
1677 **************************************************************************/
1678 static IPTR
Application__MUIM_Input(struct IClass
*cl
, Object
*obj
,
1679 struct MUIP_Application_Input
*msg
)
1681 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1682 ULONG signal
= 0, handler_mask
= 0;
1685 /* query the signal for the handlers */
1686 for (mn
= data
->app_IHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
1688 struct MUI_InputHandlerNode
*ihn
;
1689 ihn
= (struct MUI_InputHandlerNode
*)mn
;
1690 handler_mask
|= ihn
->ihn_Flags
;
1693 signal
= (1L << data
->app_GlobalInfo
.mgi_WindowsPort
->mp_SigBit
)
1694 | (1L << data
->app_TimerPort
->mp_SigBit
) | handler_mask
;
1696 if (data
->app_RexxPort
)
1697 signal
|= (1L << data
->app_RexxPort
->mp_SigBit
);
1699 if (data
->app_AppPort
)
1700 signal
|= (1L << data
->app_AppPort
->mp_SigBit
);
1703 *msg
->signal
= signal
;
1704 return Application__MUIM_NewInput(cl
, obj
, (APTR
) msg
);
1707 /**************************************************************************
1708 MUIM_Application_PushMethod: Add a method in the method FIFO. Will
1709 be executed in the next event loop.
1710 **************************************************************************/
1711 static IPTR
Application__MUIM_PushMethod(struct IClass
*cl
, Object
*obj
,
1712 struct MUIP_Application_PushMethod
*msg
)
1714 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1717 IPTR
*m
= (IPTR
*) &msg
->count
; /* FIXME: breaks on 64-bit BigEndian systems */
1720 count
= msg
->count
& 0xf; /* MUI4 uses count to pass additional info */
1722 mq
= CreateMQNode(count
);
1725 mq
->mq_Dest
= msg
->dest
;
1728 for (i
= 0; i
< count
; i
++)
1729 mq
->mq_Msg
[i
] = *(m
+ 1 + i
);
1731 /* enqueue method */
1732 ObtainSemaphore(&data
->app_MethodSemaphore
);
1733 AddTail((struct List
*)&data
->app_MethodQueue
, (struct Node
*)mq
);
1734 ReleaseSemaphore(&data
->app_MethodSemaphore
);
1736 /* CHECKME: to wake task up as soon as possible! */
1737 Signal(data
->app_Task
,
1738 1L << data
->app_GlobalInfo
.mgi_WindowsPort
->mp_SigBit
);
1743 /**************************************************************************
1744 MUIM_Application_UnpushMethod: Removes a method which was added by
1745 MUIM_Application_PushMethod.
1746 **************************************************************************/
1747 static IPTR
Application__MUIM_UnpushMethod(struct IClass
*cl
, Object
*obj
,
1748 struct MUIP_Application_UnpushMethod
*msg
)
1750 D(bug("[Application__MUIM_UnpushMethod] dest %p id %p method %u\n",
1751 msg
->dest
, msg
->methodid
, msg
->method
));
1753 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1755 struct MQNode
*current
, *next
;
1758 ObtainSemaphore(&data
->app_MethodSemaphore
);
1759 ForeachNodeSafe(&data
->app_MethodQueue
, current
, next
)
1761 D(bug("[Application__MUIM_UnpushMethod] examine dest %p id %p "
1763 current
->mq_Dest
, current
, current
->mq_Msg
[0]));
1764 if (((msg
->dest
== NULL
) || (msg
->dest
== current
->mq_Dest
))
1765 && ((msg
->methodid
== 0) || (msg
->methodid
== (IPTR
)current
))
1766 && ((msg
->method
== 0) || (msg
->method
== current
->mq_Msg
[0]))
1769 Remove((struct Node
*)current
);
1770 DeleteMQNode(current
);
1772 D(bug("[Application__MUIM_UnpushMethod] current %p removed\n",
1776 ReleaseSemaphore(&data
->app_MethodSemaphore
);
1783 * MUIM_Application_ReturnID : Tell MUI to return the given id with
1784 * the next call to MUIM_Application_NewInput. kinda obsolete :)
1786 static IPTR
Application__MUIM_ReturnID(struct IClass
*cl
, Object
*obj
,
1787 struct MUIP_Application_ReturnID
*msg
)
1789 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1790 struct RIDNode
*rid
;
1793 if (!data->app_RIDMemChunk)
1795 data->app_RIDMemChunk =
1796 g_mem_chunk_create(struct RIDNode, 10, G_ALLOC_AND_FREE);
1799 rid
= CreateRIDNode(data
, msg
->retid
);
1802 AddTail((struct List
*)&data
->app_ReturnIDQueue
, (struct Node
*)rid
);
1808 * MUIM_FindUData : tests if the MUIA_UserData of the object
1809 * contains the given <udata> and returns the object pointer in this case.
1811 static IPTR
Application__MUIM_FindUData(struct IClass
*cl
, Object
*obj
,
1812 struct MUIP_FindUData
*msg
)
1814 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1816 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
1819 return DoMethodA(data
->app_WindowFamily
, (Msg
) msg
);
1824 * MUIM_GetUData : This method tests if the MUIA_UserData of the object
1825 * contains the given <udata> and gets <attr> to <storage> for itself
1828 static IPTR
Application__MUIM_GetUData(struct IClass
*cl
, Object
*obj
,
1829 struct MUIP_GetUData
*msg
)
1831 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1833 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
1835 get(obj
, msg
->attr
, msg
->storage
);
1838 return DoMethodA(data
->app_WindowFamily
, (Msg
) msg
);
1843 * MUIM_SetUData : This method tests if the MUIA_UserData of the object
1844 * contains the given <udata> and sets <attr> to <val> for itself in this case.
1846 static IPTR
Application__MUIM_SetUData(struct IClass
*cl
, Object
*obj
,
1847 struct MUIP_SetUData
*msg
)
1849 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1851 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
1852 set(obj
, msg
->attr
, msg
->val
);
1854 DoMethodA(data
->app_WindowFamily
, (Msg
) msg
);
1860 * MUIM_SetUDataOnce : This method tests if the MUIA_UserData of the object
1861 * contains the given <udata> and sets <attr> to <val> for itself in this case.
1863 static IPTR
Application__MUIM_SetUDataOnce(struct IClass
*cl
, Object
*obj
,
1864 struct MUIP_SetUDataOnce
*msg
)
1866 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1868 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
1870 set(obj
, msg
->attr
, msg
->val
);
1873 return DoMethodA(data
->app_WindowFamily
, (Msg
) msg
);
1877 /****** Application.mui/MUIM_Application_AboutMUI ****************************
1880 * MUIM_Application_AboutMUI (V14)
1883 * DoMethod(obj, MUIM_Application_AboutMUI, Object refwindow);
1886 * Show Zune's About window.
1889 * refwindow - the window object relative to which the About window will
1893 * MUIA_Window_RefWindow.
1895 ******************************************************************************
1899 static IPTR
Application__MUIM_AboutMUI(struct IClass
*cl
, Object
*obj
,
1900 struct MUIP_Application_AboutMUI
*msg
)
1902 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1904 if (!data
->app_AboutWin
)
1906 data
->app_AboutWin
= AboutmuiObject
,
1907 msg
->refwindow
? MUIA_Window_RefWindow
: TAG_IGNORE
,
1908 msg
->refwindow
, MUIA_Window_LeftEdge
,
1909 MUIV_Window_LeftEdge_Centered
, MUIA_Window_TopEdge
,
1910 MUIV_Window_TopEdge_Centered
, MUIA_Aboutmui_Application
, obj
,
1914 if (data
->app_AboutWin
)
1915 set(data
->app_AboutWin
, MUIA_Window_Open
, TRUE
);
1920 static IPTR
Application__MUIM_SetConfigdata(struct IClass
*cl
, Object
*obj
,
1921 struct MUIP_Application_SetConfigdata
*msg
)
1923 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1924 struct MinList
*children
= NULL
;
1928 get(data
->app_WindowFamily
, MUIA_Family_List
, &children
);
1931 cstate
= (Object
*) children
->mlh_Head
;
1932 if ((child
= NextObject(&cstate
)))
1934 D(bug("closing window %p\n", child
));
1936 set(child
, MUIA_Window_Open
, FALSE
);
1940 if (data
->app_GlobalInfo
.mgi_Configdata
)
1941 MUI_DisposeObject(data
->app_GlobalInfo
.mgi_Configdata
);
1942 data
->app_GlobalInfo
.mgi_Configdata
= msg
->configdata
;
1943 get(data
->app_GlobalInfo
.mgi_Configdata
, MUIA_Configdata_ZunePrefs
,
1944 &data
->app_GlobalInfo
.mgi_Prefs
);
1946 DoMethod(obj
, MUIM_Application_PushMethod
, (IPTR
) obj
, 1,
1947 MUIM_Application_OpenWindows
);
1952 /* MUIM_Application_OpenWindows
1953 * Opens all windows of an application
1955 static IPTR
Application__MUIM_OpenWindows(struct IClass
*cl
, Object
*obj
,
1956 struct MUIP_Application_OpenWindows
*msg
)
1958 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1959 struct MinList
*children
= NULL
;
1963 get(data
->app_WindowFamily
, MUIA_Family_List
, &children
);
1967 cstate
= (Object
*) children
->mlh_Head
;
1968 if ((child
= NextObject(&cstate
)))
1970 set(child
, MUIA_Window_Open
, TRUE
);
1976 static IPTR
Application__MUIM_OpenConfigWindow(struct IClass
*cl
,
1977 Object
*obj
, struct MUIP_Application_OpenConfigWindow
*msg
)
1979 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1980 struct TagItem tags
[] = {
1981 {SYS_Asynch
, FALSE
},
1984 {NP_StackSize
, AROS_STACKSIZE
},
1989 snprintf(cmd
, 255, "sys:prefs/Zune %s %ld",
1990 data
->app_Base
? data
->app_Base
: (STRPTR
) "", (long)obj
);
1992 if (SystemTagList(cmd
, tags
) == -1)
2000 snprintf(cmd
, 255, "ENV:zune/%s.prefs", data
->app_Base
);
2001 DoMethod(data
->app_GlobalInfo
.mgi_Configdata
, MUIM_Configdata_Load
,
2008 static IPTR
Application__MUIM_Execute(Class
*CLASS
, Object
*self
,
2014 (DoMethod(self
, MUIM_Application_NewInput
, (IPTR
) & signals
)
2015 != MUIV_Application_ReturnID_Quit
)
2019 signals
= Wait(signals
| SIGBREAKF_CTRL_C
);
2020 if (signals
& SIGBREAKF_CTRL_C
)
2029 static IPTR
Application__MUIM_UpdateMenus(struct IClass
*cl
, Object
*obj
,
2032 struct List
*wlist
= NULL
;
2036 get(obj
, MUIA_Application_WindowList
, &wlist
);
2040 wstate
= wlist
->lh_Head
;
2041 while ((curwin
= NextObject(&wstate
)))
2043 DoMethod(curwin
, MUIM_Window_UpdateMenu
);
2050 static IPTR
Application__MUIM_Load(struct IClass
*cl
, Object
*obj
,
2051 struct MUIP_Application_Load
*message
)
2053 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
2054 struct IFFHandle
*iff
;
2058 struct MinList
*children
= NULL
;
2062 if (!data
->app_Base
)
2065 dataspace
= MUI_NewObject(MUIC_Dataspace
, TAG_DONE
);
2069 if (message
->name
== MUIV_Application_Load_ENV
)
2070 snprintf(name
, sizeof(name
), "ENV:Zune/%s.cfg", data
->app_Base
);
2071 else if (message
->name
== MUIV_Application_Load_ENVARC
)
2072 snprintf(name
, sizeof(name
), "ENVARC:Zune/%s.cfg", data
->app_Base
);
2074 strncpy(name
, message
->name
, sizeof(name
));
2076 fh
= Open(name
, MODE_OLDFILE
);
2079 if ((iff
= AllocIFF()))
2081 iff
->iff_Stream
= (IPTR
) fh
;
2085 if (!OpenIFF(iff
, IFFF_READ
))
2087 if (!StopChunk(iff
, ID_PREF
, ID_MUIO
))
2089 if (!ParseIFF(iff
, IFFPARSE_SCAN
))
2091 DoMethod(dataspace
, MUIM_Dataspace_ReadIFF
, iff
,
2103 get(data
->app_WindowFamily
, MUIA_Family_List
, &children
);
2104 cstate
= (Object
*) children
->mlh_Head
;
2105 while ((child
= NextObject(&cstate
)))
2107 DoMethod(child
, MUIM_Import
, dataspace
);
2110 MUI_DisposeObject(dataspace
);
2115 static IPTR
Application__MUIM_Save(struct IClass
*cl
, Object
*obj
,
2116 struct MUIP_Application_Save
*message
)
2118 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
2119 struct IFFHandle
*iff
;
2123 struct MinList
*children
= NULL
;
2127 if (!data
->app_Base
)
2130 dataspace
= MUI_NewObject(MUIC_Dataspace
, TAG_DONE
);
2134 get(data
->app_WindowFamily
, MUIA_Family_List
, &children
);
2135 cstate
= (Object
*) children
->mlh_Head
;
2136 while ((child
= NextObject(&cstate
)))
2138 DoMethod(child
, MUIM_Export
, dataspace
);
2141 if (message
->name
== MUIV_Application_Save_ENV
)
2142 snprintf(name
, sizeof(name
), "ENV:Zune/%s.cfg", data
->app_Base
);
2143 else if (message
->name
== MUIV_Application_Save_ENVARC
)
2144 snprintf(name
, sizeof(name
), "ENVARC:Zune/%s.cfg", data
->app_Base
);
2146 strncpy(name
, message
->name
, sizeof(name
));
2148 fh
= Open(name
, MODE_NEWFILE
);
2151 if ((iff
= AllocIFF()))
2153 iff
->iff_Stream
= (IPTR
) fh
;
2157 if (!OpenIFF(iff
, IFFF_WRITE
))
2159 if (!PushChunk(iff
, ID_PREF
, ID_FORM
, IFFSIZE_UNKNOWN
))
2161 if (!PushChunk(iff
, ID_PREF
, ID_PRHD
,
2162 sizeof(struct FilePrefHeader
)))
2164 struct FilePrefHeader head
;
2166 head
.ph_Version
= PHV_CURRENT
;
2170 head
.ph_Flags
[2] = head
.ph_Flags
[3] = 0;
2172 if (WriteChunkBytes(iff
, &head
,
2173 sizeof(head
)) == sizeof(head
))
2176 DoMethod(dataspace
, MUIM_Dataspace_WriteIFF
,
2177 iff
, ID_PREF
, ID_MUIO
);
2193 MUI_DisposeObject(dataspace
);
2198 /****** Application.mui/MUIM_Application_CheckRefresh ************************
2201 * MUIM_Application_CheckRefresh (V11)
2204 * DoMethod(obj, MUIM_Application_CheckRefresh);
2207 * Redraw any damaged portions within all of the application's windows.
2208 * This method is normally only used in hooks that handle Intuition
2209 * messages received while modal requesters are open (e.g. ASL file
2210 * requesters). If such a hook is not used, a modal requester may damage
2211 * the contents of your application windows when the requester is moved.
2214 * The object attributes needed for the ASL tags in the example below may
2215 * not all have valid values unless the parent window is open. Therefore
2216 * the tags should not be passed to MUI_AllocAslRequestTags() in an
2217 * OM_NEW method (for example), but should instead be passed to
2218 * MUI_AslRequestTags() when the requester is shown.
2222 * \* A hook function to refresh windows when called from asl.library *\
2223 * AROS_UFH3(static void, IMsgHook,
2224 * AROS_UFHA(struct Hook *, hook, A0),
2225 * AROS_UFHA(struct FileRequester *, req, A2),
2226 * AROS_UFHA(struct IntuiMessage *, imsg, A1))
2228 * AROS_USERFUNC_INIT
2230 * if (imsg->Class == IDCMP_REFRESHWINDOW)
2231 * DoMethod(req->fr_UserData, MUIM_Application_CheckRefresh);
2233 * AROS_USERFUNC_EXIT
2238 * \* Show the requester *\
2239 * MUI_AslRequestTags(ASL_FileRequest, req,
2240 * ASLFR_Window, XGET(window, MUIA_Window_Window),
2241 * ASLFR_IntuiMsgFunc, (IPTR)hook,
2242 * ASLFR_UserData, XGET(window, MUIA_ApplicationObject),
2245 ******************************************************************************
2249 static IPTR
Application__MUIM_CheckRefresh(struct IClass
*cl
, Object
*obj
,
2250 struct MUIP_Application_CheckRefresh
*message
)
2252 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
2253 struct MinList
*children
= NULL
;
2257 get(data
->app_WindowFamily
, MUIA_Family_List
, &children
);
2258 cstate
= (Object
*) children
->mlh_Head
;
2259 while ((child
= NextObject(&cstate
)))
2260 DoMethod(child
, MUIM_Window_Refresh
);
2266 * The class dispatcher
2268 BOOPSI_DISPATCHER(IPTR
, Application_Dispatcher
, cl
, obj
, msg
)
2270 switch (msg
->MethodID
)
2273 return Application__OM_NEW(cl
, obj
, (struct opSet
*)msg
);
2275 return Application__OM_DISPOSE(cl
, obj
, msg
);
2277 return Application__OM_SET(cl
, obj
, (struct opSet
*)msg
);
2279 return Application__OM_GET(cl
, obj
, (struct opGet
*)msg
);
2281 return Application__OM_ADDMEMBER(cl
, obj
, (APTR
) msg
);
2283 return Application__OM_REMMEMBER(cl
, obj
, (APTR
) msg
);
2284 case MUIM_Application_AddInputHandler
:
2285 return Application__MUIM_AddInputHandler(cl
, obj
, (APTR
) msg
);
2286 case MUIM_Application_RemInputHandler
:
2287 return Application__MUIM_RemInputHandler(cl
, obj
, (APTR
) msg
);
2288 case MUIM_Application_Input
:
2289 return Application__MUIM_Input(cl
, obj
, (APTR
) msg
);
2290 case MUIM_Application_InputBuffered
:
2291 return Application__MUIM_InputBuffered(cl
, obj
, (APTR
) msg
);
2292 case MUIM_Application_NewInput
:
2293 return Application__MUIM_NewInput(cl
, obj
, (APTR
) msg
);
2294 case MUIM_Application_PushMethod
:
2295 return Application__MUIM_PushMethod(cl
, obj
, (APTR
) msg
);
2296 case MUIM_Application_UnpushMethod
:
2297 return Application__MUIM_UnpushMethod(cl
, obj
, (APTR
) msg
);
2298 case MUIM_Application_ReturnID
:
2299 return Application__MUIM_ReturnID(cl
, obj
, (APTR
) msg
);
2300 case MUIM_FindUData
:
2301 return Application__MUIM_FindUData(cl
, obj
, (APTR
) msg
);
2303 return Application__MUIM_GetUData(cl
, obj
, (APTR
) msg
);
2305 return Application__MUIM_SetUData(cl
, obj
, (APTR
) msg
);
2306 case MUIM_SetUDataOnce
:
2307 return Application__MUIM_SetUDataOnce(cl
, obj
, (APTR
) msg
);
2308 case MUIM_Application_AboutMUI
:
2309 return Application__MUIM_AboutMUI(cl
, obj
, (APTR
) msg
);
2310 case MUIM_Application_SetConfigdata
:
2311 return Application__MUIM_SetConfigdata(cl
, obj
, (APTR
) msg
);
2312 case MUIM_Application_OpenWindows
:
2313 return Application__MUIM_OpenWindows(cl
, obj
, (APTR
) msg
);
2314 case MUIM_Application_OpenConfigWindow
:
2315 return Application__MUIM_OpenConfigWindow(cl
, obj
, (APTR
) msg
);
2316 case MUIM_Application_Execute
:
2317 return Application__MUIM_Execute(cl
, obj
, msg
);
2318 case MUIM_Application_UpdateMenus
:
2319 return Application__MUIM_UpdateMenus(cl
, obj
, msg
);
2320 case MUIM_Application_Load
:
2321 return Application__MUIM_Load(cl
, obj
, (APTR
) msg
);
2322 case MUIM_Application_Save
:
2323 return Application__MUIM_Save(cl
, obj
, (APTR
) msg
);
2324 case MUIM_Application_CheckRefresh
:
2325 return Application__MUIM_CheckRefresh(cl
, obj
, (APTR
) msg
);
2328 return (DoSuperMethodA(cl
, obj
, msg
));
2330 BOOPSI_DISPATCHER_END
2334 const struct __MUIBuiltinClass _MUI_Application_desc
=
2338 sizeof(struct MUI_ApplicationData
),
2339 (void *) Application_Dispatcher