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
:
905 /* First element is storing size and is a 32-bit integer, even on 64-bit systems */
906 CopyMem((CONST_APTR
) tag
->ti_Data
, &data
->winposused
, *(LONG
*)(addr
));
909 case MUIA_Application_SetWinPos
:
911 struct windowpos
*winp
;
912 winp
= (struct windowpos
*)tag
->ti_Data
;
913 //kprintf("SetWinPos %d %d %d %d %d\n", winp->id, winp->x1,
914 // winp->y1, winp->w1, winp->h1);
916 for (i
= 0; i
< MAXWINS
- 1; i
++)
918 if (data
->winpos
[i
].w1
)
920 if (winp
->id
== data
->winpos
[i
].id
)
922 //existing entry is overwritten
923 data
->winpos
[i
].x1
= winp
->x1
;
924 data
->winpos
[i
].y1
= winp
->y1
;
925 data
->winpos
[i
].w1
= winp
->w1
;
926 data
->winpos
[i
].h1
= winp
->h1
;
927 data
->winpos
[i
].x2
= winp
->x2
;
928 data
->winpos
[i
].y2
= winp
->y2
;
929 data
->winpos
[i
].w2
= winp
->w2
;
930 data
->winpos
[i
].h2
= winp
->h2
;
936 // a new entry is added
937 data
->winpos
[i
].id
= winp
->id
;
938 data
->winpos
[i
].x1
= winp
->x1
;
939 data
->winpos
[i
].y1
= winp
->y1
;
940 data
->winpos
[i
].w1
= winp
->w1
;
941 data
->winpos
[i
].h1
= winp
->h1
;
942 data
->winpos
[i
].x2
= winp
->x2
;
943 data
->winpos
[i
].y2
= winp
->y2
;
944 data
->winpos
[i
].w2
= winp
->w2
;
945 data
->winpos
[i
].h2
= winp
->h2
;
952 case MUIA_Application_Configdata
:
953 DoMethod(obj
, MUIM_Application_PushMethod
, (IPTR
) obj
, 2,
954 MUIM_Application_SetConfigdata
, tag
->ti_Data
);
957 case MUIA_Application_HelpFile
:
958 data
->app_HelpFile
= (STRPTR
) tag
->ti_Data
;
961 case MUIA_Application_Iconified
:
963 BOOL do_iconify
= tag
->ti_Data
== 1;
964 if (data
->app_Iconified
!= do_iconify
)
966 data
->app_Iconified
= do_iconify
;
968 nnset(obj
, MUIA_ShowMe
, !data
->app_Iconified
);
970 /* Inform workbench.library */
971 if (data
->app_Iconified
)
974 data
->app_Title
? data
->
975 app_Title
: (STRPTR
) "Unnamed";
976 struct DiskObject
*dobj
=
977 (struct DiskObject
*)XGET(obj
,
978 MUIA_Application_DiskObject
);
982 /* Get default AppIcon in ENV:SYS or ENVARC:SYS */
983 dobj
= GetDefDiskObject(WBAPPICON
);
985 data
->app_DefaultDiskObject
= dobj
;
988 /* First default: ENV:SYS/def_MUI.info */
989 dobj
= GetDiskObject("ENV:SYS/def_MUI");
991 data
->app_DefaultDiskObject
= dobj
;
994 /* Second default: ENV:SYS/def_Zune.info */
996 GetDiskObject("ENV:SYS/def_Zune");
998 data
->app_DefaultDiskObject
= dobj
;
1001 /* Third default: default tool icon */
1002 dobj
= GetDefDiskObject(WBTOOL
);
1004 data
->app_DefaultDiskObject
=
1014 dobj
->do_CurrentX
= NO_ICON_POSITION
;
1015 dobj
->do_CurrentY
= NO_ICON_POSITION
;
1018 AddAppIconA(0L, 0L, appname
, data
->app_AppPort
,
1023 if (data
->app_AppIcon
)
1025 RemoveAppIcon(data
->app_AppIcon
);
1026 data
->app_AppIcon
= NULL
;
1028 if (data
->app_DefaultDiskObject
)
1030 FreeDiskObject(data
->app_DefaultDiskObject
);
1031 data
->app_DefaultDiskObject
= NULL
;
1040 /* Ok ok, you think this stinks? Well, think of it as
1041 an attribute belonging to an interface which
1042 MUIC_Application, together with MUIC_Area and a few
1043 others implement. It makes sense now, yes? */
1044 struct List
*wlist
= NULL
;
1046 Object
*curwin
= NULL
;
1047 Object
*lastwin
= NULL
;
1049 /* MUIA_ShowMe can cause MUIM_Setup/MUIM_Cleanup to be issued.
1050 * On the other hand it is allowed to add/remove other
1051 * application windows in MUIM_Setup/MUIM_Cleanup.
1052 * This means after processing a window from internal list,
1053 * the list needs to be re-read and iteration started again,
1054 * because wstate can become invalid.
1055 * Note: The code below assumes that the window won't remove
1056 * itself from the list.
1061 get(data
->app_WindowFamily
, MUIA_Family_List
, &wlist
);
1062 wstate
= (Object
*) wlist
->lh_Head
;
1063 while ((curwin
= NextObject(&wstate
)))
1065 if (lastwin
== NULL
)
1067 if (curwin
== lastwin
)
1069 curwin
= NextObject(&wstate
);
1074 /* This is the window to be processed */
1077 set(curwin
, MUIA_ShowMe
, tag
->ti_Data
);
1082 /* No more windows */
1089 case MUIA_Application_Sleep
:
1091 struct List
*wlist
= NULL
;
1097 data
->app_SleepCount
++;
1098 if (data
->app_SleepCount
== 1)
1100 get(obj
, MUIA_Application_WindowList
, &wlist
);
1103 wstate
= wlist
->lh_Head
;
1104 while ((curwin
= NextObject(&wstate
)))
1106 set(curwin
, MUIA_Window_Sleep
, TRUE
);
1113 data
->app_SleepCount
--;
1114 if (data
->app_SleepCount
== 0)
1116 get(obj
, MUIA_Application_WindowList
, &wlist
);
1119 wstate
= wlist
->lh_Head
;
1120 while ((curwin
= NextObject(&wstate
)))
1122 set(curwin
, MUIA_Window_Sleep
, FALSE
);
1130 case MUIA_Application_MenuAction
:
1131 data
->app_MenuAction
= tag
->ti_Data
;
1134 case MUIA_Application_BrokerHook
:
1135 data
->app_BrokerHook
= (struct Hook
*)tag
->ti_Data
;
1138 case MUIA_Application_Active
:
1139 data
->app_Active
= tag
->ti_Data
? TRUE
: FALSE
;
1140 if (data
->app_Broker
)
1142 ActivateCxObj(data
->app_Broker
, data
->app_Active
);
1146 case MUIA_Application_Commands
:
1147 data
->app_Commands
= (struct MUI_Command
*)tag
->ti_Data
;
1150 case MUIA_Application_RexxString
:
1151 data
->app_RexxString
= (STRPTR
) tag
->ti_Data
;
1154 case MUIA_Application_RexxHook
:
1155 data
->app_RexxHook
= (struct Hook
*)tag
->ti_Data
;
1158 case MUIA_Application_DiskObject
:
1159 data
->app_DiskObject
= (struct DiskObject
*)tag
->ti_Data
;
1164 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
1171 static IPTR
Application__OM_GET(struct IClass
*cl
, Object
*obj
,
1174 #define STORE *(msg->opg_Storage)
1176 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1178 switch (msg
->opg_AttrID
)
1180 case MUIA_Application_GetWinPosAddr
:
1181 STORE
= (IPTR
) & data
->winposused
;
1184 case MUIA_Application_GetWinPosSize
:
1187 for (i
= 0; i
< MAXWINS
- 1; i
++)
1189 if (!data
->winpos
[i
].w1
)
1191 i
*= sizeof(struct windowpos
);
1193 data
->winposused
= i
;
1202 case MUIA_Application_GetWinPos
:
1205 if (data
->searchwinid
)
1207 for (i
= 0; i
< MAXWINS
- 1; i
++)
1209 if (data
->winpos
[i
].w1
)
1211 if (data
->searchwinid
== data
->winpos
[i
].id
)
1213 STORE
= (IPTR
) & data
->winpos
[i
].id
;
1234 case MUIA_Application_Author
:
1235 STORE
= (IPTR
) data
->app_Author
;
1238 case MUIA_Application_Base
:
1239 STORE
= (IPTR
) data
->app_Base
;
1242 case MUIA_Application_Copyright
:
1243 STORE
= (IPTR
) data
->app_Copyright
;
1246 case MUIA_Application_Description
:
1247 STORE
= (IPTR
) data
->app_Description
;
1250 case MUIA_Application_DoubleStart
:
1253 case MUIA_Application_ForceQuit
:
1254 STORE
= (IPTR
) data
->app_ForceQuit
;
1257 case MUIA_Application_HelpFile
:
1258 STORE
= (IPTR
) data
->app_HelpFile
;
1261 case MUIA_Application_Iconified
:
1262 STORE
= (IPTR
) data
->app_Iconified
;
1265 case MUIA_Application_Title
:
1266 STORE
= (IPTR
) data
->app_Title
;
1269 case MUIA_Application_Version
:
1270 STORE
= (IPTR
) data
->app_Version
;
1273 case MUIA_Application_Version_Number
:
1274 STORE
= (IPTR
) data
->app_Version_Number
;
1277 case MUIA_Application_Version_Date
:
1278 STORE
= (IPTR
) data
->app_Version_Date
;
1281 case MUIA_Application_Version_Extra
:
1282 STORE
= (IPTR
) data
->app_Version_Extra
;
1285 case MUIA_Application_WindowList
:
1286 return GetAttr(MUIA_Family_List
, data
->app_WindowFamily
,
1289 case MUIA_Application_Menustrip
:
1290 STORE
= (IPTR
) data
->app_Menustrip
;
1293 case MUIA_Application_MenuAction
:
1294 STORE
= (IPTR
) data
->app_MenuAction
;
1297 case MUIA_Application_BrokerPort
:
1298 STORE
= (IPTR
) data
->app_BrokerPort
;
1301 case MUIA_Application_BrokerPri
:
1302 STORE
= (IPTR
) data
->app_BrokerPri
;
1305 case MUIA_Application_BrokerHook
:
1306 STORE
= (IPTR
) data
->app_BrokerHook
;
1309 case MUIA_Application_Broker
:
1310 STORE
= (IPTR
) data
->app_Broker
;
1313 case MUIA_Application_Active
:
1314 STORE
= data
->app_Active
;
1317 case MUIA_Application_Commands
:
1318 STORE
= (IPTR
) data
->app_Commands
;
1321 case MUIA_Application_RexxMsg
:
1322 STORE
= (IPTR
) data
->app_RexxMsg
;
1325 case MUIA_Application_RexxHook
:
1326 STORE
= (IPTR
) data
->app_RexxHook
;
1329 case MUIA_Application_DiskObject
:
1330 STORE
= (IPTR
) data
->app_DiskObject
;
1334 /* our handler didn't understand the attribute, we simply pass
1335 ** it to our superclass now
1337 return (DoSuperMethodA(cl
, obj
, (Msg
) msg
));
1342 /**************************************************************************
1344 **************************************************************************/
1345 static IPTR
Application__OM_ADDMEMBER(struct IClass
*cl
, Object
*obj
,
1346 struct opMember
*msg
)
1348 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1350 D(bug("Application_AddMember: Adding 0x%lx to window member list\n",
1353 DoMethodA(data
->app_WindowFamily
, (Msg
) msg
);
1354 /* Application knows its GlobalInfo, so we can inform window */
1355 DoMethod(msg
->opam_Object
, MUIM_ConnectParent
, (IPTR
) obj
);
1360 /**************************************************************************
1362 **************************************************************************/
1363 static IPTR
Application__OM_REMMEMBER(struct IClass
*cl
, Object
*obj
,
1364 struct opMember
*msg
)
1366 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1368 D(bug("Application_RemMember: Removing 0x%lx from window member list\n",
1371 DoMethod(msg
->opam_Object
, MUIM_DisconnectParent
);
1372 DoMethodA(data
->app_WindowFamily
, (Msg
) msg
);
1379 /**************************************************************************
1380 MUIM_Application_AddInputHandler
1381 **************************************************************************/
1382 static IPTR
Application__MUIM_AddInputHandler(struct IClass
*cl
,
1383 Object
*obj
, struct MUIP_Application_AddInputHandler
*msg
)
1385 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1387 if (msg
->ihnode
->ihn_Flags
& MUIIHNF_TIMER
)
1389 struct timerequest_ext
*time_ext
=
1390 (struct timerequest_ext
*)AllocVec(sizeof(struct
1391 timerequest_ext
), MEMF_PUBLIC
);
1394 /* Store the request inside the input handler, so that we can
1395 ** remove the inputhandler without problems */
1396 msg
->ihnode
->ihn_Node
.mln_Pred
= (struct MinNode
*)time_ext
;
1398 time_ext
->treq
= *data
->app_TimerReq
;
1399 time_ext
->treq
.tr_node
.io_Command
= TR_ADDREQUEST
;
1400 time_ext
->treq
.tr_time
.tv_secs
= msg
->ihnode
->ihn_Millis
/ 1000;
1401 time_ext
->treq
.tr_time
.tv_micro
=
1402 (msg
->ihnode
->ihn_Millis
% 1000) * 1000;
1403 time_ext
->ihn
= msg
->ihnode
;
1404 SendIO((struct IORequest
*)time_ext
);
1408 AddTail((struct List
*)&data
->app_IHList
,
1409 (struct Node
*)msg
->ihnode
);
1414 /**************************************************************************
1415 MUIM_Application_RemInputHandler
1416 **************************************************************************/
1417 static IPTR
Application__MUIM_RemInputHandler(struct IClass
*cl
,
1418 Object
*obj
, struct MUIP_Application_RemInputHandler
*msg
)
1420 //struct MUI_ApplicationData *data = INST_DATA(cl, obj);
1421 if (msg
->ihnode
->ihn_Flags
& MUIIHNF_TIMER
)
1423 struct timerequest_ext
*time_ext
=
1424 (struct timerequest_ext
*)msg
->ihnode
->ihn_Node
.mln_Pred
;
1425 if (!CheckIO((struct IORequest
*)time_ext
))
1426 AbortIO((struct IORequest
*)time_ext
);
1427 WaitIO((struct IORequest
*)time_ext
);
1431 Remove((struct Node
*)msg
->ihnode
);
1437 void _zune_window_message(struct IntuiMessage
*imsg
); /* from window.c */
1440 * MUIM_Application_InputBuffered : process all pending events
1442 static IPTR
Application__MUIM_InputBuffered(struct IClass
*cl
, Object
*obj
,
1443 struct MUIP_Application_InputBuffered
*msg
)
1445 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1446 struct IntuiMessage
*imsg
;
1448 /* process all pushed methods */
1449 while (application_do_pushed_method(data
))
1453 (struct IntuiMessage
*)GetMsg(data
->app_GlobalInfo
.mgi_WindowsPort
);
1456 /* Let window object process message */
1457 _zune_window_message(imsg
); /* will reply the message */
1462 /**************************************************************************
1463 MUIM_Application_NewInput : application main loop
1464 **************************************************************************/
1465 static IPTR
Application__MUIM_NewInput(struct IClass
*cl
, Object
*obj
,
1466 struct MUIP_Application_NewInput
*msg
)
1468 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1469 struct RIDNode
*rid
;
1471 ULONG signal
, signalmask
;
1472 ULONG handler_mask
= 0; /* the mask of the signal handlers */
1475 //struct MinNode ihn_Node;
1477 signal
= *msg
->signal
;
1479 /* process all pushed methods */
1480 while (application_do_pushed_method(data
))
1483 /* query the signal for the handlers */
1484 for (mn
= data
->app_IHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
1486 struct MUI_InputHandlerNode
*ihn
;
1487 ihn
= (struct MUI_InputHandlerNode
*)mn
;
1488 handler_mask
|= ihn
->ihn_Signals
;
1491 signalmask
= (1L << data
->app_GlobalInfo
.mgi_WindowsPort
->mp_SigBit
)
1492 | (1L << data
->app_TimerPort
->mp_SigBit
) | handler_mask
;
1494 if (data
->app_Broker
)
1495 signalmask
|= (1L << data
->app_BrokerPort
->mp_SigBit
);
1497 if (data
->app_RexxPort
)
1498 signalmask
|= (1L << data
->app_RexxPort
->mp_SigBit
);
1500 if (data
->app_AppPort
)
1501 signalmask
|= (1L << data
->app_AppPort
->mp_SigBit
);
1505 /* Stupid app which (always) passes 0 in signals. It's impossible to
1506 know which signals were really set as the app will already have
1507 called Wait() which has cleared the task's tc_SigRecvd. So assume
1508 the window, timer, and broker signals all to be set. Also all of
1509 the inputhandler signals (MUI does that too). */
1511 signal
= signalmask
;
1514 if (signal
& signalmask
)
1516 if (signal
& (1L << data
->app_GlobalInfo
.mgi_WindowsPort
->
1519 struct IntuiMessage
*imsg
;
1520 /* process all pushed methods */
1523 (struct IntuiMessage
*)GetMsg(data
->app_GlobalInfo
.
1526 /* Let window object process message */
1527 _zune_window_message(imsg
); /* will reply the message */
1531 if (signal
& (1L << data
->app_TimerPort
->mp_SigBit
))
1533 struct timerequest_ext
*time_ext
;
1538 /* At first we fetch all messages from the message port and store
1539 ** them in a list, we use the node of the Message here */
1541 (struct timerequest_ext
*)GetMsg(data
->app_TimerPort
)))
1542 AddTail(&list
, (struct Node
*)time_ext
);
1544 /* Now we proccess the list and resend the timer io, no loop can
1545 ** happen. We use RemHead() because the handler can remove it
1546 ** itself and so a FreeVec() could happen in
1547 ** MUIM_Application_RemInputHandler which would destroy the
1548 ** ln->Succ of course */
1549 while ((n
= RemHead(&list
)))
1551 struct timerequest_ext
*time_ext
=
1552 (struct timerequest_ext
*)n
;
1553 struct MUI_InputHandlerNode
*ihn
= time_ext
->ihn
;
1554 time_ext
->treq
.tr_time
.tv_secs
=
1555 time_ext
->ihn
->ihn_Millis
/ 1000;
1556 time_ext
->treq
.tr_time
.tv_micro
=
1557 (time_ext
->ihn
->ihn_Millis
% 1000) * 1000;
1558 SendIO((struct IORequest
*)&time_ext
->treq
);
1559 DoMethod(ihn
->ihn_Object
, ihn
->ihn_Method
);
1563 if (data
->app_BrokerPort
1564 && (signal
& (1L << data
->app_BrokerPort
->mp_SigBit
)))
1568 while ((msg
= (CxMsg
*) GetMsg(data
->app_BrokerPort
)))
1570 switch (CxMsgType(msg
))
1573 switch (CxMsgID(msg
))
1576 set(obj
, MUIA_Application_Active
, FALSE
);
1580 set(obj
, MUIA_Application_Active
, TRUE
);
1584 case CXCMD_DISAPPEAR
:
1585 /* No default handling - application needs to be in
1586 * control of this */
1590 SetSignal(SIGBREAKF_CTRL_C
, SIGBREAKF_CTRL_C
);
1596 if (data
->app_BrokerHook
)
1598 CallHookPkt(data
->app_BrokerHook
, obj
, msg
);
1601 ReplyMsg((struct Message
*)msg
);
1605 if (data
->app_RexxPort
1606 && (signal
& (1L << data
->app_RexxPort
->mp_SigBit
)))
1609 D(bug("[MUI] Got Rexx message!\n"));
1610 struct Message
*msg
;
1611 while ((msg
= GetMsg(data
->app_RexxPort
)))
1617 if (data
->app_AppPort
1618 && (signal
& (1L << data
->app_AppPort
->mp_SigBit
)))
1620 struct AppMessage
*appmsg
;
1622 (struct AppMessage
*)GetMsg(data
->app_AppPort
)))
1624 if ((appmsg
->am_Type
== AMTYPE_APPICON
)
1625 && (appmsg
->am_NumArgs
== 0)
1626 && (appmsg
->am_ArgList
== NULL
)
1627 && (XGET(obj
, MUIA_Application_Iconified
) == TRUE
))
1629 /* Reply before removing AppIcon */
1630 ReplyMsg((struct Message
*)appmsg
);
1631 set(obj
, MUIA_Application_Iconified
, FALSE
);
1634 else if (appmsg
->am_Type
== AMTYPE_APPWINDOW
)
1636 set((Object
*) appmsg
->am_UserData
, MUIA_AppMessage
,
1640 ReplyMsg((struct Message
*)appmsg
);
1644 if (signal
& handler_mask
)
1646 for (mn
= data
->app_IHList
.mlh_Head
; mn
->mln_Succ
;
1649 struct MUI_InputHandlerNode
*ihn
;
1650 ihn
= (struct MUI_InputHandlerNode
*)mn
;
1651 if (signal
& ihn
->ihn_Signals
)
1652 DoMethod(ihn
->ihn_Object
, ihn
->ihn_Method
);
1657 /* process all pushed methods - again */
1658 while (application_do_pushed_method(data
))
1661 *msg
->signal
= signalmask
;
1663 /* set return code */
1665 (struct RIDNode
*)RemHead((struct List
*)&data
->
1666 app_ReturnIDQueue
)))
1668 retval
= rid
->rid_Value
;
1669 DeleteRIDNode(data
, rid
);
1675 /**************************************************************************
1676 MUIM_Application_Input : application main loop
1677 This method shouldn't be used in any new program. As it polls all signals.
1678 **************************************************************************/
1679 static IPTR
Application__MUIM_Input(struct IClass
*cl
, Object
*obj
,
1680 struct MUIP_Application_Input
*msg
)
1682 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1683 ULONG signal
= 0, handler_mask
= 0;
1686 /* query the signal for the handlers */
1687 for (mn
= data
->app_IHList
.mlh_Head
; mn
->mln_Succ
; mn
= mn
->mln_Succ
)
1689 struct MUI_InputHandlerNode
*ihn
;
1690 ihn
= (struct MUI_InputHandlerNode
*)mn
;
1691 handler_mask
|= ihn
->ihn_Flags
;
1694 signal
= (1L << data
->app_GlobalInfo
.mgi_WindowsPort
->mp_SigBit
)
1695 | (1L << data
->app_TimerPort
->mp_SigBit
) | handler_mask
;
1697 if (data
->app_RexxPort
)
1698 signal
|= (1L << data
->app_RexxPort
->mp_SigBit
);
1700 if (data
->app_AppPort
)
1701 signal
|= (1L << data
->app_AppPort
->mp_SigBit
);
1704 *msg
->signal
= signal
;
1705 return Application__MUIM_NewInput(cl
, obj
, (APTR
) msg
);
1708 /**************************************************************************
1709 MUIM_Application_PushMethod: Add a method in the method FIFO. Will
1710 be executed in the next event loop.
1711 **************************************************************************/
1712 static IPTR
Application__MUIM_PushMethod(struct IClass
*cl
, Object
*obj
,
1713 struct MUIP_Application_PushMethod
*msg
)
1715 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1718 IPTR
*m
= (IPTR
*) &msg
->count
; /* FIXME: breaks on 64-bit BigEndian systems */
1721 count
= msg
->count
& 0xf; /* MUI4 uses count to pass additional info */
1723 mq
= CreateMQNode(count
);
1726 mq
->mq_Dest
= msg
->dest
;
1729 for (i
= 0; i
< count
; i
++)
1730 mq
->mq_Msg
[i
] = *(m
+ 1 + i
);
1732 /* enqueue method */
1733 ObtainSemaphore(&data
->app_MethodSemaphore
);
1734 AddTail((struct List
*)&data
->app_MethodQueue
, (struct Node
*)mq
);
1735 ReleaseSemaphore(&data
->app_MethodSemaphore
);
1737 /* CHECKME: to wake task up as soon as possible! */
1738 Signal(data
->app_Task
,
1739 1L << data
->app_GlobalInfo
.mgi_WindowsPort
->mp_SigBit
);
1744 /**************************************************************************
1745 MUIM_Application_UnpushMethod: Removes a method which was added by
1746 MUIM_Application_PushMethod.
1747 **************************************************************************/
1748 static IPTR
Application__MUIM_UnpushMethod(struct IClass
*cl
, Object
*obj
,
1749 struct MUIP_Application_UnpushMethod
*msg
)
1751 D(bug("[Application__MUIM_UnpushMethod] dest %p id %p method %u\n",
1752 msg
->dest
, msg
->methodid
, msg
->method
));
1754 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1756 struct MQNode
*current
, *next
;
1759 ObtainSemaphore(&data
->app_MethodSemaphore
);
1760 ForeachNodeSafe(&data
->app_MethodQueue
, current
, next
)
1762 D(bug("[Application__MUIM_UnpushMethod] examine dest %p id %p "
1764 current
->mq_Dest
, current
, current
->mq_Msg
[0]));
1765 if (((msg
->dest
== NULL
) || (msg
->dest
== current
->mq_Dest
))
1766 && ((msg
->methodid
== 0) || (msg
->methodid
== (IPTR
)current
))
1767 && ((msg
->method
== 0) || (msg
->method
== current
->mq_Msg
[0]))
1770 Remove((struct Node
*)current
);
1771 DeleteMQNode(current
);
1773 D(bug("[Application__MUIM_UnpushMethod] current %p removed\n",
1777 ReleaseSemaphore(&data
->app_MethodSemaphore
);
1784 * MUIM_Application_ReturnID : Tell MUI to return the given id with
1785 * the next call to MUIM_Application_NewInput. kinda obsolete :)
1787 static IPTR
Application__MUIM_ReturnID(struct IClass
*cl
, Object
*obj
,
1788 struct MUIP_Application_ReturnID
*msg
)
1790 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1791 struct RIDNode
*rid
;
1794 if (!data->app_RIDMemChunk)
1796 data->app_RIDMemChunk =
1797 g_mem_chunk_create(struct RIDNode, 10, G_ALLOC_AND_FREE);
1800 rid
= CreateRIDNode(data
, msg
->retid
);
1803 AddTail((struct List
*)&data
->app_ReturnIDQueue
, (struct Node
*)rid
);
1809 * MUIM_FindUData : tests if the MUIA_UserData of the object
1810 * contains the given <udata> and returns the object pointer in this case.
1812 static IPTR
Application__MUIM_FindUData(struct IClass
*cl
, Object
*obj
,
1813 struct MUIP_FindUData
*msg
)
1815 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1817 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
1820 return DoMethodA(data
->app_WindowFamily
, (Msg
) msg
);
1825 * MUIM_GetUData : This method tests if the MUIA_UserData of the object
1826 * contains the given <udata> and gets <attr> to <storage> for itself
1829 static IPTR
Application__MUIM_GetUData(struct IClass
*cl
, Object
*obj
,
1830 struct MUIP_GetUData
*msg
)
1832 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1834 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
1836 get(obj
, msg
->attr
, msg
->storage
);
1839 return DoMethodA(data
->app_WindowFamily
, (Msg
) msg
);
1844 * MUIM_SetUData : This method tests if the MUIA_UserData of the object
1845 * contains the given <udata> and sets <attr> to <val> for itself in this case.
1847 static IPTR
Application__MUIM_SetUData(struct IClass
*cl
, Object
*obj
,
1848 struct MUIP_SetUData
*msg
)
1850 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1852 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
1853 set(obj
, msg
->attr
, msg
->val
);
1855 DoMethodA(data
->app_WindowFamily
, (Msg
) msg
);
1861 * MUIM_SetUDataOnce : This method tests if the MUIA_UserData of the object
1862 * contains the given <udata> and sets <attr> to <val> for itself in this case.
1864 static IPTR
Application__MUIM_SetUDataOnce(struct IClass
*cl
, Object
*obj
,
1865 struct MUIP_SetUDataOnce
*msg
)
1867 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1869 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
1871 set(obj
, msg
->attr
, msg
->val
);
1874 return DoMethodA(data
->app_WindowFamily
, (Msg
) msg
);
1878 /****** Application.mui/MUIM_Application_AboutMUI ****************************
1881 * MUIM_Application_AboutMUI (V14)
1884 * DoMethod(obj, MUIM_Application_AboutMUI, Object refwindow);
1887 * Show Zune's About window.
1890 * refwindow - the window object relative to which the About window will
1894 * MUIA_Window_RefWindow.
1896 ******************************************************************************
1900 static IPTR
Application__MUIM_AboutMUI(struct IClass
*cl
, Object
*obj
,
1901 struct MUIP_Application_AboutMUI
*msg
)
1903 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1905 if (!data
->app_AboutWin
)
1907 data
->app_AboutWin
= AboutmuiObject
,
1908 msg
->refwindow
? MUIA_Window_RefWindow
: TAG_IGNORE
,
1909 msg
->refwindow
, MUIA_Window_LeftEdge
,
1910 MUIV_Window_LeftEdge_Centered
, MUIA_Window_TopEdge
,
1911 MUIV_Window_TopEdge_Centered
, MUIA_Aboutmui_Application
, obj
,
1915 if (data
->app_AboutWin
)
1916 set(data
->app_AboutWin
, MUIA_Window_Open
, TRUE
);
1921 static IPTR
Application__MUIM_SetConfigdata(struct IClass
*cl
, Object
*obj
,
1922 struct MUIP_Application_SetConfigdata
*msg
)
1924 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1925 struct MinList
*children
= NULL
;
1929 get(data
->app_WindowFamily
, MUIA_Family_List
, &children
);
1932 cstate
= (Object
*) children
->mlh_Head
;
1933 if ((child
= NextObject(&cstate
)))
1935 D(bug("closing window %p\n", child
));
1937 set(child
, MUIA_Window_Open
, FALSE
);
1941 if (data
->app_GlobalInfo
.mgi_Configdata
)
1942 MUI_DisposeObject(data
->app_GlobalInfo
.mgi_Configdata
);
1943 data
->app_GlobalInfo
.mgi_Configdata
= msg
->configdata
;
1944 get(data
->app_GlobalInfo
.mgi_Configdata
, MUIA_Configdata_ZunePrefs
,
1945 &data
->app_GlobalInfo
.mgi_Prefs
);
1947 DoMethod(obj
, MUIM_Application_PushMethod
, (IPTR
) obj
, 1,
1948 MUIM_Application_OpenWindows
);
1953 /* MUIM_Application_OpenWindows
1954 * Opens all windows of an application
1956 static IPTR
Application__MUIM_OpenWindows(struct IClass
*cl
, Object
*obj
,
1957 struct MUIP_Application_OpenWindows
*msg
)
1959 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1960 struct MinList
*children
= NULL
;
1964 get(data
->app_WindowFamily
, MUIA_Family_List
, &children
);
1968 cstate
= (Object
*) children
->mlh_Head
;
1969 if ((child
= NextObject(&cstate
)))
1971 set(child
, MUIA_Window_Open
, TRUE
);
1977 static IPTR
Application__MUIM_OpenConfigWindow(struct IClass
*cl
,
1978 Object
*obj
, struct MUIP_Application_OpenConfigWindow
*msg
)
1980 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
1981 struct TagItem tags
[] = {
1982 {SYS_Asynch
, FALSE
},
1985 {NP_StackSize
, AROS_STACKSIZE
},
1990 snprintf(cmd
, 255, "sys:prefs/Zune %s %ld",
1991 data
->app_Base
? data
->app_Base
: (STRPTR
) "", (long)obj
);
1993 if (SystemTagList(cmd
, tags
) == -1)
2001 snprintf(cmd
, 255, "ENV:zune/%s.prefs", data
->app_Base
);
2002 DoMethod(data
->app_GlobalInfo
.mgi_Configdata
, MUIM_Configdata_Load
,
2009 static IPTR
Application__MUIM_Execute(Class
*CLASS
, Object
*self
,
2015 (DoMethod(self
, MUIM_Application_NewInput
, (IPTR
) & signals
)
2016 != MUIV_Application_ReturnID_Quit
)
2020 signals
= Wait(signals
| SIGBREAKF_CTRL_C
);
2021 if (signals
& SIGBREAKF_CTRL_C
)
2030 static IPTR
Application__MUIM_UpdateMenus(struct IClass
*cl
, Object
*obj
,
2033 struct List
*wlist
= NULL
;
2037 get(obj
, MUIA_Application_WindowList
, &wlist
);
2041 wstate
= wlist
->lh_Head
;
2042 while ((curwin
= NextObject(&wstate
)))
2044 DoMethod(curwin
, MUIM_Window_UpdateMenu
);
2051 static IPTR
Application__MUIM_Load(struct IClass
*cl
, Object
*obj
,
2052 struct MUIP_Application_Load
*message
)
2054 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
2055 struct IFFHandle
*iff
;
2059 struct MinList
*children
= NULL
;
2063 if (!data
->app_Base
)
2066 dataspace
= MUI_NewObject(MUIC_Dataspace
, TAG_DONE
);
2070 if (message
->name
== MUIV_Application_Load_ENV
)
2071 snprintf(name
, sizeof(name
), "ENV:Zune/%s.cfg", data
->app_Base
);
2072 else if (message
->name
== MUIV_Application_Load_ENVARC
)
2073 snprintf(name
, sizeof(name
), "ENVARC:Zune/%s.cfg", data
->app_Base
);
2075 strncpy(name
, message
->name
, sizeof(name
) - 1);
2077 fh
= Open(name
, MODE_OLDFILE
);
2080 if ((iff
= AllocIFF()))
2082 iff
->iff_Stream
= (IPTR
) fh
;
2086 if (!OpenIFF(iff
, IFFF_READ
))
2088 if (!StopChunk(iff
, ID_PREF
, ID_MUIO
))
2090 if (!ParseIFF(iff
, IFFPARSE_SCAN
))
2092 DoMethod(dataspace
, MUIM_Dataspace_ReadIFF
, iff
,
2104 get(data
->app_WindowFamily
, MUIA_Family_List
, &children
);
2105 cstate
= (Object
*) children
->mlh_Head
;
2106 while ((child
= NextObject(&cstate
)))
2108 DoMethod(child
, MUIM_Import
, dataspace
);
2111 MUI_DisposeObject(dataspace
);
2116 static IPTR
Application__MUIM_Save(struct IClass
*cl
, Object
*obj
,
2117 struct MUIP_Application_Save
*message
)
2119 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
2120 struct IFFHandle
*iff
;
2124 struct MinList
*children
= NULL
;
2128 if (!data
->app_Base
)
2131 dataspace
= MUI_NewObject(MUIC_Dataspace
, TAG_DONE
);
2135 get(data
->app_WindowFamily
, MUIA_Family_List
, &children
);
2136 cstate
= (Object
*) children
->mlh_Head
;
2137 while ((child
= NextObject(&cstate
)))
2139 DoMethod(child
, MUIM_Export
, dataspace
);
2142 if (message
->name
== MUIV_Application_Save_ENV
)
2143 snprintf(name
, sizeof(name
), "ENV:Zune/%s.cfg", data
->app_Base
);
2144 else if (message
->name
== MUIV_Application_Save_ENVARC
)
2145 snprintf(name
, sizeof(name
), "ENVARC:Zune/%s.cfg", data
->app_Base
);
2147 strncpy(name
, message
->name
, sizeof(name
) - 1);
2149 fh
= Open(name
, MODE_NEWFILE
);
2152 if ((iff
= AllocIFF()))
2154 iff
->iff_Stream
= (IPTR
) fh
;
2158 if (!OpenIFF(iff
, IFFF_WRITE
))
2160 if (!PushChunk(iff
, ID_PREF
, ID_FORM
, IFFSIZE_UNKNOWN
))
2162 if (!PushChunk(iff
, ID_PREF
, ID_PRHD
,
2163 sizeof(struct FilePrefHeader
)))
2165 struct FilePrefHeader head
;
2167 head
.ph_Version
= PHV_CURRENT
;
2171 head
.ph_Flags
[2] = head
.ph_Flags
[3] = 0;
2173 if (WriteChunkBytes(iff
, &head
,
2174 sizeof(head
)) == sizeof(head
))
2177 DoMethod(dataspace
, MUIM_Dataspace_WriteIFF
,
2178 iff
, ID_PREF
, ID_MUIO
);
2194 MUI_DisposeObject(dataspace
);
2199 /****** Application.mui/MUIM_Application_CheckRefresh ************************
2202 * MUIM_Application_CheckRefresh (V11)
2205 * DoMethod(obj, MUIM_Application_CheckRefresh);
2208 * Redraw any damaged portions within all of the application's windows.
2209 * This method is normally only used in hooks that handle Intuition
2210 * messages received while modal requesters are open (e.g. ASL file
2211 * requesters). If such a hook is not used, a modal requester may damage
2212 * the contents of your application windows when the requester is moved.
2215 * The object attributes needed for the ASL tags in the example below may
2216 * not all have valid values unless the parent window is open. Therefore
2217 * the tags should not be passed to MUI_AllocAslRequestTags() in an
2218 * OM_NEW method (for example), but should instead be passed to
2219 * MUI_AslRequestTags() when the requester is shown.
2223 * \* A hook function to refresh windows when called from asl.library *\
2224 * AROS_UFH3(static void, IMsgHook,
2225 * AROS_UFHA(struct Hook *, hook, A0),
2226 * AROS_UFHA(struct FileRequester *, req, A2),
2227 * AROS_UFHA(struct IntuiMessage *, imsg, A1))
2229 * AROS_USERFUNC_INIT
2231 * if (imsg->Class == IDCMP_REFRESHWINDOW)
2232 * DoMethod(req->fr_UserData, MUIM_Application_CheckRefresh);
2234 * AROS_USERFUNC_EXIT
2239 * \* Show the requester *\
2240 * MUI_AslRequestTags(ASL_FileRequest, req,
2241 * ASLFR_Window, XGET(window, MUIA_Window_Window),
2242 * ASLFR_IntuiMsgFunc, (IPTR)hook,
2243 * ASLFR_UserData, XGET(window, MUIA_ApplicationObject),
2246 ******************************************************************************
2250 static IPTR
Application__MUIM_CheckRefresh(struct IClass
*cl
, Object
*obj
,
2251 struct MUIP_Application_CheckRefresh
*message
)
2253 struct MUI_ApplicationData
*data
= INST_DATA(cl
, obj
);
2254 struct MinList
*children
= NULL
;
2258 get(data
->app_WindowFamily
, MUIA_Family_List
, &children
);
2259 cstate
= (Object
*) children
->mlh_Head
;
2260 while ((child
= NextObject(&cstate
)))
2261 DoMethod(child
, MUIM_Window_Refresh
);
2267 * The class dispatcher
2269 BOOPSI_DISPATCHER(IPTR
, Application_Dispatcher
, cl
, obj
, msg
)
2271 switch (msg
->MethodID
)
2274 return Application__OM_NEW(cl
, obj
, (struct opSet
*)msg
);
2276 return Application__OM_DISPOSE(cl
, obj
, msg
);
2278 return Application__OM_SET(cl
, obj
, (struct opSet
*)msg
);
2280 return Application__OM_GET(cl
, obj
, (struct opGet
*)msg
);
2282 return Application__OM_ADDMEMBER(cl
, obj
, (APTR
) msg
);
2284 return Application__OM_REMMEMBER(cl
, obj
, (APTR
) msg
);
2285 case MUIM_Application_AddInputHandler
:
2286 return Application__MUIM_AddInputHandler(cl
, obj
, (APTR
) msg
);
2287 case MUIM_Application_RemInputHandler
:
2288 return Application__MUIM_RemInputHandler(cl
, obj
, (APTR
) msg
);
2289 case MUIM_Application_Input
:
2290 return Application__MUIM_Input(cl
, obj
, (APTR
) msg
);
2291 case MUIM_Application_InputBuffered
:
2292 return Application__MUIM_InputBuffered(cl
, obj
, (APTR
) msg
);
2293 case MUIM_Application_NewInput
:
2294 return Application__MUIM_NewInput(cl
, obj
, (APTR
) msg
);
2295 case MUIM_Application_PushMethod
:
2296 return Application__MUIM_PushMethod(cl
, obj
, (APTR
) msg
);
2297 case MUIM_Application_UnpushMethod
:
2298 return Application__MUIM_UnpushMethod(cl
, obj
, (APTR
) msg
);
2299 case MUIM_Application_ReturnID
:
2300 return Application__MUIM_ReturnID(cl
, obj
, (APTR
) msg
);
2301 case MUIM_FindUData
:
2302 return Application__MUIM_FindUData(cl
, obj
, (APTR
) msg
);
2304 return Application__MUIM_GetUData(cl
, obj
, (APTR
) msg
);
2306 return Application__MUIM_SetUData(cl
, obj
, (APTR
) msg
);
2307 case MUIM_SetUDataOnce
:
2308 return Application__MUIM_SetUDataOnce(cl
, obj
, (APTR
) msg
);
2309 case MUIM_Application_AboutMUI
:
2310 return Application__MUIM_AboutMUI(cl
, obj
, (APTR
) msg
);
2311 case MUIM_Application_SetConfigdata
:
2312 return Application__MUIM_SetConfigdata(cl
, obj
, (APTR
) msg
);
2313 case MUIM_Application_OpenWindows
:
2314 return Application__MUIM_OpenWindows(cl
, obj
, (APTR
) msg
);
2315 case MUIM_Application_OpenConfigWindow
:
2316 return Application__MUIM_OpenConfigWindow(cl
, obj
, (APTR
) msg
);
2317 case MUIM_Application_Execute
:
2318 return Application__MUIM_Execute(cl
, obj
, msg
);
2319 case MUIM_Application_UpdateMenus
:
2320 return Application__MUIM_UpdateMenus(cl
, obj
, msg
);
2321 case MUIM_Application_Load
:
2322 return Application__MUIM_Load(cl
, obj
, (APTR
) msg
);
2323 case MUIM_Application_Save
:
2324 return Application__MUIM_Save(cl
, obj
, (APTR
) msg
);
2325 case MUIM_Application_CheckRefresh
:
2326 return Application__MUIM_CheckRefresh(cl
, obj
, (APTR
) msg
);
2329 return (DoSuperMethodA(cl
, obj
, msg
));
2331 BOOPSI_DISPATCHER_END
2335 const struct __MUIBuiltinClass _MUI_Application_desc
=
2339 sizeof(struct MUI_ApplicationData
),
2340 (void *) Application_Dispatcher