2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
5 Open a drawer or launch a program.
8 #include <aros/debug.h>
10 #include <exec/types.h>
11 #include <exec/ports.h>
12 #include <utility/tagitem.h>
13 #include <intuition/intuition.h>
14 #include <workbench/workbench.h>
15 #include <proto/utility.h>
16 #include <proto/dos.h>
20 #include "workbench_intern.h"
22 #include "support_messages.h"
24 #include "handler_support.h"
26 /*** Prototypes *************************************************************/
27 BOOL
__CLI_LaunchProgram(CONST_STRPTR command
, struct TagItem
*tags
, struct WorkbenchBase
*WorkbenchBase
);
28 STRPTR
__CLI_BuildCommandLine(CONST_STRPTR command
, struct TagItem
*tags
, struct WorkbenchBase
*WorkbenchBase
);
29 BOOL
__WB_LaunchProgram(BPTR lock
, CONST_STRPTR name
, struct TagItem
*tags
, struct WorkbenchBase
*WorkbenchBase
);
30 BOOL
__WB_BuildArguments(struct WBStartup
*startup
, BPTR lock
, CONST_STRPTR name
, struct TagItem
*tags
, struct WorkbenchBase
*WorkbenchBase
);
32 /*** Macros *****************************************************************/
33 #define CLI_LaunchProgram(name, tags) (__CLI_LaunchProgram((name), (tags), WorkbenchBase))
34 #define CLI_BuildCommandLine(name, tags) (__CLI_BuildCommandLine((name), (tags), WorkbenchBase))
35 #define WB_LaunchProgram(lock, name, tags) (__WB_LaunchProgram((lock), (name), (tags), WorkbenchBase))
36 #define WB_BuildArguments(startup, lock, name, tags) (__WB_BuildArguments((startup), (lock), (name), (tags), WorkbenchBase))
38 /*****************************************************************************
42 #include <proto/workbench.h>
44 AROS_LH2(BOOL
, OpenWorkbenchObjectA
,
47 AROS_LHA(STRPTR
, name
, A0
),
48 AROS_LHA(struct TagItem
*, tags
, A1
),
51 struct WorkbenchBase
*, WorkbenchBase
, 16, Workbench
)
69 ******************************************************************************/
74 LONG isDefaultIcon
= 42;
76 struct DiskObject
*icon
= GetIconTags
79 ICONGETA_FailIfUnavailable
, FALSE
,
80 ICONGETA_IsDefaultIcon
, (IPTR
) &isDefaultIcon
,
84 ASSERT_VALID_PTR(name
);
85 ASSERT_VALID_PTR_OR_NULL(tags
);
87 D(bug("[WBLIB] OpenWorkbenchObjectA: name = %s\n", name
));
88 D(bug("[WBLIB] OpenWorkbenchObjectA: isDefaultIcon = %ld\n", isDefaultIcon
));
92 switch (icon
->do_Type
)
98 Since it's a directory or volume, tell the Workbench
99 Application to open the corresponding drawer.
102 D(bug("[WBLIB] OpenWorkbenchObjectA: it's a DISK, DRAWER or GARBAGE\n"));
105 struct WBCommandMessage
*wbcm
= NULL
;
106 struct WBHandlerMessage
*wbhm
= NULL
;
107 CONST_STRPTR namecopy
= NULL
;
111 (wbcm
= CreateWBCM(WBCM_TYPE_RELAY
)) != NULL
112 && (wbhm
= CreateWBHM(WBHM_TYPE_OPEN
)) != NULL
113 && (namecopy
= StrDup(name
)) != NULL
117 wbhm
->wbhm_Data
.Open
.Name
= namecopy
;
118 wbcm
->wbcm_Data
.Relay
.Message
= wbhm
;
120 PutMsg(&(WorkbenchBase
->wb_HandlerPort
), (struct Message
*) wbcm
);
124 FreeVec((STRPTR
)namecopy
);
134 It's an executable. Before I launch it, I must check
135 whether it is a Workbench program or a CLI program.
138 D(bug("[WBLIB] OpenWorkbenchObjectA: it's a TOOL\n"));
143 && FindToolType(icon
->do_ToolTypes
, "CLI") == NULL
146 /* It's a Workbench program */
147 BPTR lock
= Lock(name
, ACCESS_READ
);
149 D(bug("[WBLIB] OpenWorkbenchObjectA: it's a WB program\n"));
153 BPTR parent
= ParentDir(lock
);
157 IPTR stacksize
= icon
->do_StackSize
;
159 if (stacksize
< WorkbenchBase
->wb_DefaultStackSize
)
160 stacksize
= WorkbenchBase
->wb_DefaultStackSize
;
162 D(bug("[WBLIB] OpenWorkbenchObjectA: stack size: %d Bytes\n", stacksize
));
164 struct TagItem wbp_Tags
[] =
166 { NP_StackSize
, stacksize
},
167 { TAG_MORE
, (IPTR
)tags
},
172 wbp_Tags
[1].ti_Tag
= TAG_IGNORE
;
174 success
= WB_LaunchProgram
176 parent
, FilePart(name
), wbp_Tags
182 Fallback to launching it as a CLI program.
183 Most likely it will also fail, but we
186 success
= CLI_LaunchProgram(name
, wbp_Tags
);
197 /* It's a CLI program */
199 D(bug("[WBLIB] OpenWorkbenchObjectA: it's a CLI program\n"));
201 success
= CLI_LaunchProgram(name
, tags
);
206 /* It's a project; try to launch it via its default tool. */
208 D(bug("[WBLIB] OpenWorkbenchObjectA: it's a PROJECT\n"));
209 D(bug("[WBLIB] OpenWorkbenchObjectA: default tool: %s\n", icon
->do_DefaultTool
));
213 icon
->do_DefaultTool
!= NULL
214 && strlen(icon
->do_DefaultTool
) > 0
217 BPTR lock
= (BPTR
)NULL
, parent
= (BPTR
)NULL
;
219 lock
= Lock(name
, ACCESS_READ
);
220 if (lock
!= (BPTR
)NULL
)
221 parent
= ParentDir(lock
);
222 if (parent
!= (BPTR
)NULL
)
224 IPTR stacksize
= icon
->do_StackSize
;
226 if (stacksize
< WorkbenchBase
->wb_DefaultStackSize
)
227 stacksize
= WorkbenchBase
->wb_DefaultStackSize
;
229 D(bug("[WBLIB] OpenWorkbenchObjectA: stack size: %d Bytes\n", stacksize
));
231 struct TagItem tags2
[] =
233 { NP_StackSize
, stacksize
},
234 { WBOPENA_ArgLock
, (IPTR
) parent
},
235 { WBOPENA_ArgName
, (IPTR
) FilePart(name
) },
236 { TAG_MORE
, (IPTR
) tags
},
241 tags2
[3].ti_Tag
= TAG_IGNORE
;
243 if (FindToolType(icon
->do_ToolTypes
, "CLI") == NULL
)
245 BPTR lock2
= (BPTR
)NULL
, parent2
= (BPTR
)NULL
;
247 lock2
= Lock(icon
->do_DefaultTool
, ACCESS_READ
);
248 if (lock2
!= (BPTR
)NULL
)
249 parent2
= ParentDir(lock2
);
252 success
= WB_LaunchProgram
254 parent2
, FilePart(icon
->do_DefaultTool
), tags2
262 success
= CLI_LaunchProgram
264 icon
->do_DefaultTool
, tags
275 // FIXME: open execute command?
280 FreeDiskObject(icon
);
285 Getting (a possibly default) icon for the path failed, and
286 therefore there is no such file. We need to search the default
287 search path for an executable of that name and launch it. This
288 only makes sense if the name is *not* an (absolute or relative)
289 path: that is, it must not contain any ':' or '/'.
292 if (strpbrk(name
, "/:") == NULL
)
294 struct CommandLineInterface
*cli
= Cli();
297 BPTR
*paths
; /* Path list */
300 /* Iterate over all paths in the path list */
303 paths
= (BPTR
*) BADDR(cli
->cli_CommandDir
);
304 running
== TRUE
&& paths
!= NULL
;
305 paths
= (BPTR
*) BADDR(paths
[0]) /* next path */
308 BPTR cd
= CurrentDir(paths
[1]);
309 BPTR lock
= Lock(name
, SHARED_LOCK
);
313 success
= OpenWorkbenchObjectA(name
, tags
);
325 D(bug("[WBLIB] OpenWorkbenchObjectA: success = %d\n", success
));
330 } /* OpenWorkbenchObjectA() */
332 STRPTR __CLI_BuildCommandLine
334 CONST_STRPTR command
, struct TagItem
*tags
,
335 struct WorkbenchBase
*WorkbenchBase
338 const struct TagItem
*tstate
= tags
;
339 const struct TagItem
*tag
= NULL
;
340 BPTR lastLock
= NULL
;
341 STRPTR buffer
= NULL
;
342 ULONG length
= strlen(command
) + 3 /* NULL + 2 '"' */;
344 /*-- Calculate length of resulting string ------------------------------*/
345 while ((tag
= NextTagItem(&tstate
)) != NULL
)
349 case WBOPENA_ArgLock
:
350 lastLock
= (BPTR
) tag
->ti_Data
;
353 case WBOPENA_ArgName
:
354 if (lastLock
!= NULL
)
356 BPTR cd
= CurrentDir(lastLock
);
357 BPTR lock
= Lock((STRPTR
) tag
->ti_Data
, ACCESS_READ
);
360 STRPTR path
= AllocateNameFromLock(lock
);
363 length
+= 3 /* space + 2 '"' */ + strlen(path
);
376 /*-- Allocate space for command line string ----------------------------*/
377 buffer
= AllocVec(length
, MEMF_ANY
);
383 /*-- Build command line --------------------------------------------*/
384 strcat(buffer
, "\"");
385 strcat(buffer
, command
);
386 strcat(buffer
, "\"");
388 tstate
= tags
; lastLock
= NULL
;
389 while ((tag
= NextTagItem(&tstate
)) != NULL
)
393 case WBOPENA_ArgLock
:
394 lastLock
= (BPTR
) tag
->ti_Data
;
397 case WBOPENA_ArgName
:
398 if (lastLock
!= NULL
)
400 BPTR cd
= CurrentDir(lastLock
);
401 BPTR lock
= Lock((STRPTR
) tag
->ti_Data
, ACCESS_READ
);
404 STRPTR path
= AllocateNameFromLock(lock
);
407 strcat(buffer
, " \"");
408 strcat(buffer
, path
);
409 strcat(buffer
, "\"");
424 SetIoErr(ERROR_NO_FREE_STORE
);
430 BOOL __CLI_LaunchProgram
432 CONST_STRPTR command
, struct TagItem
*tags
,
433 struct WorkbenchBase
*WorkbenchBase
437 STRPTR commandline
= NULL
;
438 IPTR stacksize
= WorkbenchBase
->wb_DefaultStackSize
;
439 struct TagItem
*foundTag
= NULL
;
441 input
= Open("CON:////Output Window/CLOSE/AUTO/WAIT", MODE_OLDFILE
);
442 if (input
== NULL
) goto error
;
444 commandline
= CLI_BuildCommandLine(command
, tags
);
445 if (commandline
== NULL
) goto error
;
447 if ((tags
) && ((foundTag
= FindTagItem(NP_StackSize
, tags
)) != NULL
))
448 stacksize
= foundTag
->ti_Data
;
453 Launch the program. Note that there is no advantage of doing this
454 in the handler, since we need to wait for the return value anyway
455 (and thus we cannot cut down the blocking time by returning before
456 the program is loaded from disk).
463 SYS_Input
, (IPTR
) input
,
464 SYS_Output
, (IPTR
) NULL
,
465 SYS_Error
, (IPTR
) NULL
,
466 NP_StackSize
, stacksize
,
473 FreeVec(commandline
);
478 if (input
!= NULL
) Close(input
);
479 if (commandline
!= NULL
) FreeVec(commandline
);
484 BOOL __WB_BuildArguments
486 struct WBStartup
*startup
, BPTR lock
, CONST_STRPTR name
, struct TagItem
*tags
,
487 struct WorkbenchBase
*WorkbenchBase
490 const struct TagItem
*tstate
= tags
,
492 BPTR lastLock
= NULL
;
493 struct WBArg
*args
= NULL
;
495 /*-- Calculate the number of arguments ---------------------------------*/
496 startup
->sm_NumArgs
= 1;
497 while ((tag
= NextTagItem(&tstate
)) != NULL
)
501 case WBOPENA_ArgLock
:
502 lastLock
= (BPTR
) tag
->ti_Data
;
505 case WBOPENA_ArgName
:
507 Filter out args where both lock AND name are NULL, since
508 they are completely worthless to the application.
510 if (lastLock
!= NULL
|| (STRPTR
) tag
->ti_Data
!= NULL
)
512 startup
->sm_NumArgs
++;
518 /*-- Allocate memory for the arguments ---------------------------------*/
519 args
= AllocMem(sizeof(struct WBArg
) * startup
->sm_NumArgs
, MEMF_ANY
| MEMF_CLEAR
);
524 startup
->sm_ArgList
= args
;
526 /*-- Build the argument list ---------------------------------------*/
529 (args
[i
].wa_Lock
= DupLock(lock
)) == NULL
530 || (args
[i
].wa_Name
= StrDup(name
)) == NULL
537 tstate
= tags
; lastLock
= NULL
;
538 while ((tag
= NextTagItem(&tstate
)) != NULL
)
542 case WBOPENA_ArgLock
:
543 lastLock
= (BPTR
) tag
->ti_Data
;
546 case WBOPENA_ArgName
:
548 Filter out args where both lock AND name are NULL,
549 since they are completely worthless to the application.
551 if (lastLock
!= NULL
|| (STRPTR
) tag
->ti_Data
!= NULL
)
553 STRPTR name
= (STRPTR
) tag
->ti_Data
;
555 /* Duplicate the lock */
556 if (lastLock
!= NULL
)
558 args
[i
].wa_Lock
= DupLock(lastLock
);
560 if (args
[i
].wa_Lock
== NULL
)
562 D(bug("[WBLIB] WB_BuildArguments: Failed to duplicate lock!\n"));
569 args
[i
].wa_Lock
= NULL
;
572 /* Duplicate the name */
575 args
[i
].wa_Name
= StrDup(name
);
577 if (args
[i
].wa_Name
== NULL
)
579 D(bug("[WBLIB] WB_BuildArguments: Failed to duplicate string!\n"));
586 args
[i
].wa_Name
= NULL
;
599 D(bug("[WBLIB] WB_BuildArguments: Failed to allocate memory for argument array\n"));
603 D(bug("[WBLIB] WB_BuildArguments: Freeing resources after error...\n"));
604 /* Free allocated resources */
609 for (i
= 0; i
< startup
->sm_NumArgs
; i
++)
611 if (args
[i
].wa_Lock
!= NULL
) UnLock(args
[i
].wa_Lock
);
612 if (args
[i
].wa_Name
!= NULL
) FreeVec(args
[i
].wa_Name
);
615 FreeMem(args
, sizeof(struct WBArg
) * startup
->sm_NumArgs
);
618 startup
->sm_NumArgs
= 0;
619 startup
->sm_ArgList
= NULL
;
624 BOOL __WB_LaunchProgram
626 BPTR lock
, CONST_STRPTR name
, struct TagItem
*tags
,
627 struct WorkbenchBase
*WorkbenchBase
630 struct WBStartup
*startup
= NULL
;
631 struct WBCommandMessage
*message
= NULL
;
632 struct TagItem
*foundTag
= NULL
;
634 /*-- Allocate memory for messages --------------------------------------*/
635 startup
= CreateWBS();
638 D(bug("[WBLIB] WB_LaunchProgram: Failed to allocate memory for startup message\n"));
639 SetIoErr(ERROR_NO_FREE_STORE
);
643 message
= CreateWBCM(WBCM_TYPE_LAUNCH
);
646 D(bug("[WBLIB] WB_LaunchProgram: Failed to allocate memory for launch message\n"));
647 SetIoErr(ERROR_NO_FREE_STORE
);
651 if ((tags
) && ((foundTag
= FindTagItem(NP_StackSize
, tags
)) != NULL
))
653 message
->wbcm_Tags
= AllocateTagItems(2);
654 message
->wbcm_Tags
[0].ti_Tag
= foundTag
->ti_Tag
;
655 message
->wbcm_Tags
[0].ti_Data
= foundTag
->ti_Data
;
656 message
->wbcm_Tags
[1].ti_Tag
= TAG_DONE
;
659 /*-- Build the arguments array -----------------------------------------*/
660 if (!WB_BuildArguments(startup
, lock
, name
, tags
))
662 D(bug("[WBLIB] WB_LaunchProgram: Failed to build arguments\n"));
666 /*-- Send message to handler -------------------------------------------*/
667 /* NOTE: The handler will deallocate all resources of this message! */
668 message
->wbcm_Data
.Launch
.Startup
= startup
;
670 PutMsg(&(WorkbenchBase
->wb_HandlerPort
), (struct Message
*) message
);
672 D(bug("[WBLIB] WB_LaunchProgram: Success\n"));
677 if (startup
!= NULL
) DestroyWBS(startup
);
678 if (message
!= NULL
) DestroyWBCM(message
);
680 D(bug("[WBLIB] WB_LaunchProgram: Failure\n"));