Safer handling of Booleans.
[AROS.git] / workbench / libs / muimaster / classes / popasl.c
blob7df269c2795e1b175762b3339a4b3326585e6964
1 /*
2 Copyright © 2002-2012, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define MUIMASTER_YES_INLINE_STDARG
8 #include <string.h>
9 #include <stdio.h>
11 #include <graphics/gfx.h>
12 #include <graphics/view.h>
13 #include <dos/dostags.h>
14 #include <libraries/asl.h>
15 #include <clib/alib_protos.h>
16 #include <proto/exec.h>
17 #include <proto/graphics.h>
18 #include <proto/utility.h>
19 #include <proto/intuition.h>
20 #include <proto/asl.h>
21 #include <proto/dos.h>
22 #include <proto/muimaster.h>
24 #include "mui.h"
25 #include "muimaster_intern.h"
26 #include "support.h"
27 #include "support_classes.h"
28 #include "popasl_private.h"
30 extern struct Library *MUIMasterBase;
32 struct Asl_Startup
34 struct Message msg;
35 APTR asl_req;
36 struct TagItem *tags;
37 Object *app; /* the application */
38 Object *pop;
39 STRPTR buf; /* asl_entry must FreeVec() this before exiting!!! */
42 SAVEDS static LONG Asl_Entry(void)
44 struct Process *proc;
45 struct Asl_Startup *msg;
47 APTR asl_req;
48 struct TagItem *tags;
49 Object *app;
50 Object *pop;
51 STRPTR buf;
53 proc = (struct Process *)FindTask(NULL);
54 WaitPort(&proc->pr_MsgPort); /* Wait for the startup message */
55 msg = (struct Asl_Startup *)GetMsg(&proc->pr_MsgPort);
57 asl_req = msg->asl_req;
58 tags = msg->tags;
59 app = msg->app;
60 pop = msg->pop;
61 buf = msg->buf;
63 ReplyMsg(&msg->msg);
65 if (AslRequest(asl_req, tags))
66 DoMethod(app, MUIM_Application_PushMethod, (IPTR) pop, 2,
67 MUIM_Popstring_Close, TRUE);
68 else
69 DoMethod(app, MUIM_Application_PushMethod, (IPTR) pop, 2,
70 MUIM_Popstring_Close, FALSE);
72 FreeVec(buf);
74 return 0;
77 static ULONG Popasl_Open_Function(struct Hook *hook, Object *obj,
78 void **msg)
80 char *buf = NULL;
81 struct Popasl_DATA *data = (struct Popasl_DATA *)hook->h_Data;
82 struct Asl_Startup *startup;
83 Object *string = (Object *) msg[0];
84 struct MsgPort *msg_port;
86 if (data->asl_proc)
87 return 0;
89 data->tag_list[0].ti_Tag = ASLFR_Screen;
90 data->tag_list[0].ti_Data = (IPTR) _screen(obj);
91 data->tag_list[1].ti_Tag = ASLFR_PrivateIDCMP;
92 data->tag_list[1].ti_Data = 1;
93 data->tag_list[2].ti_Tag = ASLFR_InitialLeftEdge;
94 data->tag_list[2].ti_Data = _left(obj);
95 data->tag_list[3].ti_Tag = ASLFR_InitialTopEdge;
96 data->tag_list[3].ti_Data = _top(obj);
97 data->tag_list[4].ti_Tag = ASLFR_InitialWidth;
98 data->tag_list[4].ti_Data = _width(obj);
99 data->tag_list[5].ti_Tag = TAG_DONE;
100 data->tag_list[5].ti_Data = 0;
102 if (data->start_hook)
104 if (!(CallHookPkt(data->start_hook, obj, data->tag_list)))
105 return 0;
107 else
109 if (data->type == ASL_FileRequest)
111 char *str = NULL;
112 char *path_end;
114 get(string, MUIA_String_Contents, &str);
116 path_end = PathPart(str);
117 buf = (char *)AllocVec(path_end - str + 10, MEMF_PUBLIC);
118 if (!buf)
119 return 0;
121 strncpy(buf, str, path_end - str);
122 buf[path_end - str] = 0;
124 data->tag_list[5].ti_Tag = ASLFR_InitialFile;
125 data->tag_list[5].ti_Data = (IPTR) FilePart(str);
126 data->tag_list[6].ti_Tag = ASLFR_InitialDrawer;
127 data->tag_list[6].ti_Data = (IPTR) buf;
128 data->tag_list[7].ti_Tag = TAG_DONE;
129 data->tag_list[7].ti_Data = 0;
132 if (data->type == ASL_FontRequest)
134 char *str = NULL;
135 char *name_end;
136 LONG size;
138 get(string, MUIA_String_Contents, &str);
140 if (str)
142 name_end = PathPart(str);
143 buf = (char *)AllocVec(name_end - str + 10, MEMF_PUBLIC);
144 if (!buf)
145 return 0;
147 strncpy(buf, str, name_end - str);
148 strcpy(buf + (name_end - str), ".font");
149 StrToLong(FilePart(str), &size);
151 data->tag_list[5].ti_Tag = ASLFO_InitialName;
152 data->tag_list[5].ti_Data = (IPTR) buf;
153 data->tag_list[6].ti_Tag = ASLFO_InitialSize;
154 data->tag_list[6].ti_Data = size;
155 data->tag_list[7].ti_Tag = TAG_DONE;
156 data->tag_list[7].ti_Data = 0;
161 if (!(msg_port = CreateMsgPort()))
162 return 0;
163 if (!(startup =
164 (struct Asl_Startup *)AllocVec(sizeof(struct Asl_Startup),
165 MEMF_PUBLIC)))
167 DeleteMsgPort(msg_port);
168 return 0;
172 const struct TagItem processTags[2] = {
173 {NP_Entry, (IPTR) Asl_Entry},
174 {TAG_DONE, 0}
177 if (!(data->asl_proc = CreateNewProc(processTags)))
179 FreeVec(startup);
180 DeleteMsgPort(msg_port);
181 return 0;
185 startup->msg.mn_ReplyPort = msg_port;
186 startup->msg.mn_Length = sizeof(struct Asl_Startup);
187 startup->tags = data->tag_list;
188 startup->app = _app(obj);
189 startup->asl_req = data->asl_req;
190 startup->pop = obj;
191 startup->buf = buf;
192 PutMsg(&data->asl_proc->pr_MsgPort, &startup->msg);
193 WaitPort(msg_port);
195 FreeVec(startup);
196 DeleteMsgPort(msg_port);
198 return 1;
202 static ULONG Popasl_Close_Function(struct Hook *hook, Object *obj,
203 void **msg)
205 struct Popasl_DATA *data = (struct Popasl_DATA *)hook->h_Data;
206 Object *string = (Object *) msg[0];
207 IPTR suc = (IPTR) msg[1];
209 if (suc)
211 if (data->stop_hook)
213 CallHookPkt(data->stop_hook, obj, data->asl_req);
215 else
217 char *buf = NULL;
219 if (data->type == ASL_FileRequest)
221 struct FileRequester *file_req =
222 (struct FileRequester *)data->asl_req;
223 char *file =
224 (char *)file_req->fr_File ? (char *)file_req->
225 fr_File : (char *)"";
226 char *drawer =
227 (char *)file_req->fr_Drawer ? (char *)file_req->
228 fr_Drawer : (char *)"";
229 int len = strlen(file) + strlen(drawer) + 10;
231 buf = (char *)AllocVec(len, MEMF_CLEAR);
232 if (buf)
234 strcpy(buf, drawer);
235 AddPart(buf, file, len);
238 else if (data->type == ASL_FontRequest)
240 struct FontRequester *font_req =
241 (struct FontRequester *)data->asl_req;
242 char *name = font_req->fo_Attr.ta_Name;
244 if (name)
246 LONG size = font_req->fo_Attr.ta_YSize;
247 int len = strlen(name) + 20;
249 buf = AllocVec(len, MEMF_CLEAR);
250 if (buf)
252 char num_buf[20];
253 char *font_ext;
255 strcpy(buf, name);
257 /* Remove the .font extension */
258 if ((font_ext = strstr(buf, ".font")))
259 *font_ext = 0;
261 snprintf(num_buf, 20, "%ld", (long)size);
262 AddPart(buf, num_buf, len);
267 if (buf)
269 IPTR contents = 0;
271 set(string, MUIA_String_Contents, (IPTR) buf);
272 get(string, MUIA_String_Contents, &contents);
274 /* trigger string notification */
275 set(string, MUIA_String_Acknowledge, contents);
277 FreeVec(buf);
282 data->asl_proc = NULL;
283 nfset(obj, MUIA_Popasl_Active, FALSE);
285 return 0;
288 IPTR Popasl__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
290 struct Popasl_DATA *data;
291 struct TagItem *tags;
292 struct TagItem *tag;
293 ULONG asl_type =
294 GetTagData(MUIA_Popasl_Type, ASL_FileRequest, msg->ops_AttrList);
295 APTR asl_req;
297 if (!(asl_req = AllocAslRequest(asl_type, msg->ops_AttrList)))
298 return 0;
300 obj = (Object *) DoSuperNewTags(cl, obj, NULL,
301 MUIA_Popstring_Toggle, FALSE, TAG_MORE, (IPTR) msg->ops_AttrList);
302 if (!obj)
303 return FALSE;
305 data = INST_DATA(cl, obj);
307 /* parse initial taglist */
309 for (tags = msg->ops_AttrList; (tag = NextTagItem(&tags));)
311 switch (tag->ti_Tag)
313 case MUIA_Popasl_StartHook:
314 data->start_hook = (struct Hook *)tag->ti_Data;
315 break;
317 case MUIA_Popasl_StopHook:
318 data->stop_hook = (struct Hook *)tag->ti_Data;
319 break;
323 data->open_hook.h_Entry = HookEntry;
324 data->open_hook.h_SubEntry = (HOOKFUNC) Popasl_Open_Function;
325 data->open_hook.h_Data = data;
326 data->close_hook.h_Entry = HookEntry;
327 data->close_hook.h_SubEntry = (HOOKFUNC) Popasl_Close_Function;
328 data->close_hook.h_Data = data;
329 data->asl_req = asl_req;
330 data->type = asl_type;
332 SetAttrs(obj,
333 MUIA_Popstring_OpenHook, (IPTR) & data->open_hook,
334 MUIA_Popstring_CloseHook, (IPTR) & data->close_hook,
335 MUIA_Popstring_Toggle, FALSE, TAG_DONE);
337 return (IPTR) obj;
340 IPTR Popasl__OM_DISPOSE(struct IClass *cl, Object *obj, Msg msg)
342 struct Popasl_DATA *data = INST_DATA(cl, obj);
343 if (data->asl_req)
344 FreeAslRequest(data->asl_req);
345 return DoSuperMethodA(cl, obj, (Msg) msg);
348 #define STORE *(msg->opg_Storage)
349 IPTR Popasl__OM_GET(struct IClass *cl, Object *obj, struct opGet *msg)
351 struct Popasl_DATA *data = INST_DATA(cl, obj);
353 switch (msg->opg_AttrID)
355 case MUIA_Popasl_Active:
356 STORE = ! !data->asl_proc;
357 return 1;
359 return DoSuperMethodA(cl, obj, (Msg) msg);
361 #undef STORE
363 IPTR Popasl__OM_SET(struct IClass *cl, Object *obj, struct opSet *msg)
365 struct Popasl_DATA *data = INST_DATA(cl, obj);
366 struct TagItem *tags = msg->ops_AttrList;
367 struct TagItem *tag;
369 while ((tag = NextTagItem(&tags)) != NULL)
371 switch (tag->ti_Tag)
373 case MUIA_Popasl_StartHook:
374 data->start_hook = (struct Hook *)tag->ti_Data;
375 break;
376 case MUIA_Popasl_StopHook:
377 data->stop_hook = (struct Hook *)tag->ti_Data;
378 break;
382 return DoSuperMethodA(cl, obj, (Msg) msg);
385 IPTR Popasl__MUIM_Cleanup(struct IClass *cl, Object *obj,
386 struct MUIP_Cleanup *msg)
388 struct Popasl_DATA *data = INST_DATA(cl, obj);
389 if (data->asl_proc)
390 AbortAslRequest(data->asl_req);
391 return DoSuperMethodA(cl, obj, (Msg) msg);
394 #if ZUNE_BUILTIN_POPASL
395 BOOPSI_DISPATCHER(IPTR, Popasl_Dispatcher, cl, obj, msg)
397 switch (msg->MethodID)
399 case OM_NEW:
400 return Popasl__OM_NEW(cl, obj, (struct opSet *)msg);
401 case OM_DISPOSE:
402 return Popasl__OM_DISPOSE(cl, obj, msg);
403 case OM_GET:
404 return Popasl__OM_GET(cl, obj, (struct opGet *)msg);
405 case OM_SET:
406 return Popasl__OM_SET(cl, obj, (struct opSet *)msg);
407 case MUIM_Cleanup:
408 return Popasl__MUIM_Cleanup(cl, obj, (struct MUIP_Cleanup *)msg);
409 default:
410 return DoSuperMethodA(cl, obj, msg);
413 BOOPSI_DISPATCHER_END
415 const struct __MUIBuiltinClass _MUI_Popasl_desc =
417 MUIC_Popasl,
418 MUIC_Popstring,
419 sizeof(struct Popasl_DATA),
420 (void *) Popasl_Dispatcher
422 #endif /* ZUNE_BUILTIN_POPASL */