forwarding build fix when MUIA_Scrollgroup_AutoBars is defined (NicJA).
[AROS-Contrib.git] / scalos / main / DoubleClick.c
blob394718ca40a4dea2c15f3193cc39779bd3f1397c
1 // DoubleClick.c
2 // $Date$
3 // $Revision$
6 #include <exec/types.h>
7 #include <exec/execbase.h>
8 #include <graphics/gels.h>
9 #include <graphics/rastport.h>
10 #include <intuition/classes.h>
11 #include <intuition/classusr.h>
12 #include <utility/hooks.h>
13 #include <intuition/gadgetclass.h>
14 #include <intuition/intuition.h>
15 #include <workbench/workbench.h>
16 #include <workbench/startup.h>
17 #include <dos/dostags.h>
18 #include <rexx/rxslib.h>
20 #define __USE_SYSBASE
22 #include <proto/dos.h>
23 #include <proto/exec.h>
24 #include <proto/layers.h>
25 #include <proto/graphics.h>
26 #include <proto/intuition.h>
27 #include <proto/utility.h>
28 #include <proto/iconobject.h>
29 #include <proto/rexxsyslib.h>
30 #include <proto/gadtools.h>
31 #include "debug.h"
32 #include <proto/scalos.h>
34 #include <clib/alib_protos.h>
36 #include <defs.h>
37 #include <datatypes/iconobject.h>
38 #include <scalos/scalos.h>
40 #include <stdlib.h>
41 #include <stdio.h>
42 #include <string.h>
44 #include <DefIcons.h>
46 #include "scalos_structures.h"
47 #include "FsAbstraction.h"
48 #include "locale.h"
49 #include "functions.h"
50 #include "Variables.h"
52 //----------------------------------------------------------------------------
54 // local data structures
56 enum DcrID { DCR_ID_End = 0, DCR_ID_WindowStruct, DCR_ID_IconNode };
58 struct DoubleClickRemember
60 WORD dcr_ID;
61 union {
62 struct ScaWindowStruct *dcro_WindowStruct;
63 struct ScaIconNode *dcro_IconNode;
64 } dcr_Object;
67 struct ARexxToolStartArg
69 BPTR asa_DirLock;
70 STRPTR asa_ProgName;
73 // alloc count of struct DoubleClickRemember
74 #define DCR_MAX 400
76 //----------------------------------------------------------------------------
78 // local functions
80 static Object *DoubleClick_GetIconObject(struct internalScaWindowTask *iwt, struct ScaIconNode *in, BOOL *isDefIcon);
81 static BOOL TestToolStart2(struct internalScaWindowTask *iwt, struct ScaIconNode *in);
82 static BOOL ToolStart(struct internalScaWindowTask *iwt, struct ScaIconNode *in);
83 static BOOL OpenDefaultIcon(struct internalScaWindowTask *iwt, struct ScaIconNode *in, ULONG Flags);
84 static BOOL IconFound(struct internalScaWindowTask *iwt, struct ScaIconNode *in);
85 static struct ScaIconNode *SearchForIcon(ULONG IconType, struct ScaWindowStruct **wsFound);
86 static BOOL TestToolStart(struct internalScaWindowTask *iwt, struct ScaIconNode *in);
87 static BOOL NoToolIcon(struct internalScaWindowTask *iwt, struct ScaIconNode *in);
88 static BOOL AppIconStart(struct internalScaWindowTask *iwt, struct ScaIconNode *in);
89 static BOOL DC_ToolStart(struct ScaIconNode *in);
90 static BOOL OpenIcon(struct internalScaWindowTask *iwt,
91 struct internalScaWindowTask *iwtIcon, struct ScaIconNode *in, ULONG Flags);
92 static SAVEDS(ULONG) AsyncArexxToolStart(struct ARexxToolStartArg *arg, struct SM_RunProcess *msg);
93 static BOOL TestIsDrawer(CONST_STRPTR Name);
94 static BOOL CheckTaskState(struct Task *testTask);
96 //----------------------------------------------------------------------------
98 // public data items
100 //----------------------------------------------------------------------------
103 static Object *DoubleClick_GetIconObject(struct internalScaWindowTask *iwt, struct ScaIconNode *in, BOOL *isDefIcon)
105 T_ExamineData *fib;
106 Object *IconObject;
107 BPTR fLock = (BPTR)NULL;
109 *isDefIcon = FALSE;
111 IconObject = NewIconObject(in->in_Name, NULL);
112 if (IconObject)
113 return IconObject;
115 do {
116 if (!ScalosExamineBegin(&fib))
117 break;
119 fLock = Lock(in->in_Name, ACCESS_READ);
120 if ((BPTR)NULL == fLock)
121 break;
123 if (!ScalosExamineLock(fLock, &fib))
124 break;
126 IconObject = (Object *) DoMethod(iwt->iwt_WindowTask.mt_MainObject,
127 SCCM_IconWin_GetDefIcon,
128 in->in_Name,
129 ScalosExamineGetDirEntryTypeRoot(fib, fLock),
130 ScalosExamineGetProtection(fib),
131 ICONTYPE_NONE);
133 *isDefIcon = TRUE;
134 } while (0);
136 if (fLock)
137 UnLock(fLock);
138 ScalosExamineEnd(&fib);
140 return IconObject;
144 BOOL IconDoubleClick(struct internalScaWindowTask *iwt, struct ScaIconNode *in, ULONG Flags)
146 BOOL Success = FALSE;
148 d1(KPrintF("%s/%s/%ld: iwt=%08lx in=%08lx <%s> Flags=%08lx\n", \
149 __FILE__, __FUNC__, __LINE__, iwt, in, GetIconName(in), Flags));
151 SCA_LockWindowList(SCA_LockWindowList_Shared);
153 if (in)
155 // .icongiven:
156 struct FileTypeDef *ftd;
158 d1(KPrintF("%s/%s/%ld: in=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, in, in->in_Name));
160 SCA_UnLockWindowList();
162 ftd = FindFileType(iwt, in);
163 d1(kprintf("%s/%s/%ld: ftd=%08lx\n", __FILE__, __FUNC__, __LINE__, ftd));
165 if (!(Flags & ICONWINOPENF_IgnoreFileTypes) && ftd && ftd->ftd_DefaultAction)
167 // perform user-defined default action for file type
168 d1(KPrintF("%s/%s/%ld: ftd_Description=<%s> ftd_DefaultAction=%08lx\n", __FILE__, __FUNC__, __LINE__, ftd->ftd_Description, ftd->ftd_DefaultAction));
169 RunMenuCommandExt(iwt, iwt, ftd->ftd_DefaultAction, in, 0);
170 Success = TRUE;
172 else
174 IPTR IconType;
176 d1(kprintf("%s/%s/%ld: ObtainSemaphore iwt=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, iwt, iwt->iwt_WinTitle));
178 #if 0
180 const SCALOSSEMAPHORE *xSema = iwt->iwt_WindowTask.wt_IconSemaphore;
182 if (IsListEmpty((struct List *) &xSema->OwnerList))
184 d1(KPrintF("%s/%s/%ld: wt_IconSemaphore is unlocked\n", __FILE__, __FUNC__, __LINE__));
186 else
188 const struct DebugSemaOwner *Owner;
190 for (Owner = (const struct DebugSemaOwner *) xSema->OwnerList.lh_Head;
191 Owner != (const struct DebugSemaOwner *) &xSema->OwnerList.lh_Tail;
192 Owner = (const struct DebugSemaOwner *) Owner->node.ln_Succ)
194 CONST_STRPTR OwnModeString;
196 if (OWNMODE_EXCLUSIVE == Owner->OwnMode || xSema->Sema.ss_Owner)
197 OwnModeString = "Ex";
198 else
199 OwnModeString = "Sh";
201 d1(KPrintF("%s/%s/%ld: wt_IconSemaphore is owned %s by %s/%s/%ld ProcName=<%s>\n",
202 __FILE__, __FUNC__, __LINE__,
203 OwnModeString,
204 Owner->FileName,
205 Owner->Func, Owner->Line,
206 Owner->Proc->pr_Task.tc_Node.ln_Name));
210 #endif
212 ScalosLockIconListShared(iwt);
214 GetAttr(IDTA_Type, in->in_Icon, &IconType);
216 d1(KPrintF("%s/%s/%ld: IconType=%ld\n", __FILE__, __FUNC__, __LINE__, IconType));
218 switch ((ULONG) IconType)
220 case WBAPPICON:
221 case WBTOOL:
222 case WBPROJECT:
223 case WB_TEXTICON_TOOL:
224 Success = IconFound(iwt, in);
225 break;
227 case WBDISK:
228 case WBDRAWER:
229 case WB_TEXTICON_DRAWER:
230 case WBGARBAGE:
231 case WBDEVICE:
232 Success = OpenDefaultIcon(iwt, in, Flags);
233 break;
235 default:
236 Success = OpenDefaultIcon(iwt, in, Flags);
237 break;
240 d1(KPrintF("%s/%s/%ld: ScalosUnLockIconList iwt=%08lx\n", __FILE__, __FUNC__, __LINE__, iwt));
241 ScalosUnLockIconList(iwt);
244 ReleaseFileType(ftd);
246 else
248 struct ScaWindowStruct *ws;
250 d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
252 // !!! SearchForIcon() does ScalosLockIconListExclusive(iwt) !!!
253 in = SearchForIcon(WBAPPICON, &ws);
254 if (NULL == in)
255 in = SearchForIcon(WBTOOL, &ws);
256 if (NULL == in)
257 in = SearchForIcon(WBPROJECT, &ws);
258 if (NULL == in)
259 in = SearchForIcon(WB_TEXTICON_TOOL, &ws);
261 d1(KPrintF("%s/%s/%ld: in=%08lx\n", __FILE__, __FUNC__, __LINE__, in));
263 if (in)
265 //.iconfound:
266 struct internalScaWindowTask *iwtx = (struct internalScaWindowTask *) ws->ws_WindowTask;
267 struct FileTypeDef *ftd;
269 SCA_UnLockWindowList();
271 ftd = FindFileType(iwtx, in);
272 d1(KPrintF("%s/%s/%ld: ftd=%08lx\n", __FILE__, __FUNC__, __LINE__, ftd));
274 if (!(Flags & ICONWINOPENF_IgnoreFileTypes) && ftd && ftd->ftd_DefaultAction)
276 // perform user-defined default action for file type
277 d1(kprintf("%s/%s/%ld: ftd_DefaultAction=%08lx\n", __FILE__, __FUNC__, __LINE__, ftd->ftd_DefaultAction));
278 RunMenuCommandExt(iwt, iwtx, ftd->ftd_DefaultAction, in, 0);
279 Success = TRUE;
281 else
283 Success = IconFound(iwtx, in);
286 ReleaseFileType(ftd);
288 d1(kprintf("%s/%s/%ld: ReleaseSemaphore iwt=%08lx\n", __FILE__, __FUNC__, __LINE__, iwt));
289 ScalosUnLockIconList(iwtx);
291 else
293 struct DoubleClickRemember *dcr, *dcrAlloc;
294 ULONG dcrCount = DCR_MAX;
296 dcr = dcrAlloc = AllocVec(sizeof(struct DoubleClickRemember) * DCR_MAX, MEMF_PUBLIC);
297 if (dcr)
299 for (ws=winlist.wl_WindowStruct; dcrCount>1 && ws; ws = (struct ScaWindowStruct *) ws->ws_Node.mln_Succ)
301 struct internalScaWindowTask *iwt = (struct internalScaWindowTask *) ws->ws_WindowTask;
303 d1(kprintf("%s/%s/%ld: ws=%08lx\n", __FILE__, __FUNC__, __LINE__, ws));
305 if (!(ws->ws_Flags & WSV_FlagF_TaskSleeps))
307 struct ScaIconNode *in;
309 d1(kprintf("%s/%s/%ld: ObtainSemaphore iwt=%08lx\n", __FILE__, __FUNC__, __LINE__, iwt));
310 ScalosLockIconListShared(iwt);
312 dcr->dcr_ID = DCR_ID_WindowStruct;
313 dcr->dcr_Object.dcro_WindowStruct = ws;
314 d1(kprintf("%s/%s/%ld: dcr=%08lx dcr_ID=%ld\n", __FILE__, __FUNC__, __LINE__, dcr, dcr->dcr_ID));
315 dcr++;
316 dcrCount--;
318 for (in=iwt->iwt_WindowTask.wt_IconList; dcrCount>1 && in; in = (struct ScaIconNode *) in->in_Node.mln_Succ)
320 struct ExtGadget *gg = (struct ExtGadget *) in->in_Icon;
322 d1(kprintf("%s/%s/%ld: in=%08lx <%s> Sel=%ld\n", __FILE__, __FUNC__, __LINE__, \
323 in, in->in_Name, gg->Flags & GFLG_SELECTED));
325 if (gg->Flags & GFLG_SELECTED)
327 dcr->dcr_ID = DCR_ID_IconNode;
328 dcr->dcr_Object.dcro_IconNode = in;
329 d1(kprintf("%s/%s/%ld: dcr=%08lx dcr_ID=%ld\n", __FILE__, __FUNC__, __LINE__, dcr, dcr->dcr_ID));
330 dcr++;
331 dcrCount--;
336 if (DCR_ID_WindowStruct == dcr[-1].dcr_ID)
338 d1(kprintf("%s/%s/%ld: dcr=%08lx dcr_ID=%ld\n", __FILE__, __FUNC__, __LINE__, dcr, dcr->dcr_ID));
339 dcr--;
340 dcrCount++;
342 d1(kprintf("%s/%s/%ld: ReleaseSemaphore iwt=%08lx\n", __FILE__, __FUNC__, __LINE__, iwt));
343 ScalosUnLockIconList(iwt);
347 dcr->dcr_ID = DCR_ID_End;
348 d1(kprintf("%s/%s/%ld: dcr=%08lx dcr_ID=%ld\n", __FILE__, __FUNC__, __LINE__, dcr, dcr->dcr_ID));
350 d1(kprintf("%s/%s/%ld: dcrCount=%ld\n", __FILE__, __FUNC__, __LINE__, dcrCount));
352 SCA_UnLockWindowList();
354 for (dcr=dcrAlloc; DCR_ID_WindowStruct == dcr->dcr_ID; )
356 BPTR oldDir;
357 struct ScaWindowStruct *wsDcr = dcr->dcr_Object.dcro_WindowStruct;
358 struct internalScaWindowTask *iwtDcr = (struct internalScaWindowTask *) wsDcr->ws_WindowTask;
360 oldDir = CurrentDir(wsDcr->ws_Lock);
362 d1(kprintf("%s/%s/%ld: iwtDcr=%08lx dcr=%08lx dcr_ID=%ld\n", __FILE__, __FUNC__, __LINE__, iwtDcr, dcr, dcr->dcr_ID));
364 ++dcr; // skip DCR_ID_WindowStruct
366 while (DCR_ID_IconNode == dcr->dcr_ID)
368 struct ScaIconNode *in = dcr->dcr_Object.dcro_IconNode;
369 struct FileTypeDef *ftd;
371 d1(kprintf("%s/%s/%ld: dcr=%08lx dcr_ID=%ld\n", __FILE__, __FUNC__, __LINE__, dcr, dcr->dcr_ID));
372 d1(kprintf("%s/%s/%ld: in=%08lx <%s> Icon=%08lx\n", __FILE__, __FUNC__, __LINE__, in, in->in_Name, in->in_Icon));
374 ftd = FindFileType(iwtDcr, in);
375 d1(kprintf("%s/%s/%ld: ftd=%08lx\n", __FILE__, __FUNC__, __LINE__, ftd));
377 if (!(Flags & ICONWINOPENF_IgnoreFileTypes) && ftd && ftd->ftd_DefaultAction)
379 // perform user-defined default action for file type
380 d1(kprintf("%s/%s/%ld: ftd_DefaultAction=%08lx\n", __FILE__, __FUNC__, __LINE__, ftd->ftd_DefaultAction));
381 RunMenuCommandExt(iwt, iwtDcr, ftd->ftd_DefaultAction, in, 0);
382 Success = TRUE;
384 else
386 Success |= OpenIcon(iwt, iwtDcr, in, Flags);
389 ReleaseFileType(ftd);
391 dcr++;
394 d1(kprintf("%s/%s/%ld: dcr=%08lx dcr_ID=%ld\n", __FILE__, __FUNC__, __LINE__, dcr, dcr->dcr_ID));
396 d1(kprintf("%s/%s/%ld: ReleaseSemaphore iwt=%08lx\n", __FILE__, __FUNC__, __LINE__, iwtDcr));
397 ScalosUnLockIconList(iwtDcr);
399 CurrentDir(oldDir);
402 FreeVec(dcrAlloc);
404 else
405 SCA_UnLockWindowList();
409 d1(kprintf("%s/%s/%ld: Success=%ld\n", __FILE__, __FUNC__, __LINE__, Success));
411 return Success;
415 static BOOL OpenDefaultIcon(struct internalScaWindowTask *iwt, struct ScaIconNode *in, ULONG Flags)
417 BOOL Success;
419 d1(KPrintF("%s/%s/%ld: iwt=%08lx in=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, iwt, in, in->in_Name));
421 Success = OpenIcon(iwt, iwt, in, Flags);
423 d1(kprintf("%s/%s/%ld: Success=%ld\n", __FILE__, __FUNC__, __LINE__, Success));
425 return Success;
429 static BOOL IconFound(struct internalScaWindowTask *iwt, struct ScaIconNode *in)
431 struct ScaWindowStruct *ws = iwt->iwt_WindowTask.mt_WindowStruct;
432 IPTR IconType;
433 BOOL Success = FALSE;
434 BPTR oldDir;
436 d1(KPrintF("%s/%s/%ld: iwt=%08lx in=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, iwt, in, in->in_Name));
438 oldDir = CurrentDir(ws->ws_Lock);
439 if (in->in_Lock)
440 CurrentDir(in->in_Lock);
442 GetAttr(IDTA_Type, in->in_Icon, &IconType);
444 d1(KPrintF("%s/%s/%ld: IconType=%08lx\n", __FILE__, __FUNC__, __LINE__, IconType));
445 switch ((ULONG) IconType)
447 case WBTOOL:
448 Success = TestToolStart2(iwt, in);
449 break;
450 case WBPROJECT:
451 Success = ToolStart(iwt, in);
452 break;
453 case WBAPPICON:
454 Success = AppIconStart(iwt, in);
455 break;
456 case WB_TEXTICON_TOOL:
457 Success = TestToolStart(iwt, in);
458 break;
460 case WBDISK:
461 case WBDRAWER:
462 case WB_TEXTICON_DRAWER:
463 case WBGARBAGE:
464 case WBDEVICE:
465 break;
467 default:
468 break;
471 CurrentDir(oldDir);
473 return Success;
477 static BOOL TestToolStart2(struct internalScaWindowTask *iwt, struct ScaIconNode *in)
479 BOOL Success;
481 d1(KPrintF("%s/%s/%ld: iwt=%08lx in=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, iwt, in, in->in_Name));
483 if (in->in_Flags & INF_DefaultIcon)
484 Success = NoToolIcon(iwt, in);
485 else
486 Success = ToolStart(iwt, in);
488 return Success;
492 static BOOL ToolStart(struct internalScaWindowTask *iwt, struct ScaIconNode *in)
494 BOOL Success = FALSE;
495 STRPTR ttCli = NULL, ttRexx = NULL, ttDoNotPrompt = NULL;
496 BPTR dirLock;
498 d1(KPrintF("%s/%s/%ld: iwt=%08lx in=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, iwt, in, in->in_Name));
500 DoMethod(in->in_Icon, IDTM_FindToolType, "CLI", &ttCli);
501 DoMethod(in->in_Icon, IDTM_FindToolType, "REXX", &ttRexx);
502 DoMethod(in->in_Icon, IDTM_FindToolType, "DONOTPROMPT", &ttDoNotPrompt);
504 d1(KPrintF("%s/%s/%ld: Cli=%08lx Rexx=%08lx DoNotPrompt=%08lx\n", __FILE__, __FUNC__, __LINE__, ttCli, ttRexx, ttDoNotPrompt));
506 if (in->in_Lock)
507 dirLock = in->in_Lock;
508 else
509 dirLock = iwt->iwt_WindowTask.mt_WindowStruct->ws_Lock;
511 if (ttCli)
513 d1(KPrintF("%s/%s/%ld: ttCli=<%s>\n", __FILE__, __FUNC__, __LINE__, ttCli));
515 if (ttDoNotPrompt)
517 d1(KPrintF("%s/%s/%ld: in=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, in, in->in_Name));
518 Success = CLIStart(dirLock, in->in_Name, in->in_Icon, CurrentPrefs.pref_DefaultStackSize);
520 else
522 STRPTR CliValue;
524 if (strlen(ttCli) > 4)
525 CliValue = ttCli + 4;
526 else
527 CliValue = NULL;
529 if (NULL == CliValue // "CLI"
530 || 'y' == ToLower(*CliValue) // "CLI=Y.."
531 || '1' == ToLower(*CliValue)) // "CLI=1"
533 Success = DC_ToolStart(in);
537 else if (ttRexx)
539 d1(KPrintF("%s/%s/%ld: ttRexx=<%s>\n", __FILE__, __FUNC__, __LINE__, ttRexx));
540 if (ttDoNotPrompt)
542 Success = ArexxToolStart(iwt, dirLock, in->in_Name);
544 else
546 Success = DC_ToolStart(in);
549 else
551 d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
552 Success = DC_ToolStart(in);
555 return Success;
559 // Search all windows for selected icons of type <IconType>
560 static struct ScaIconNode *SearchForIcon(ULONG IconType, struct ScaWindowStruct **wsFound)
562 struct ScaWindowStruct *ws;
563 struct ScaIconNode *inFound = NULL;
565 d1(kprintf("%s/%s/%ld: IconType=%ld\n", __FILE__, __FUNC__, __LINE__, IconType));
567 *wsFound = NULL;
569 for (ws=winlist.wl_WindowStruct; (NULL == inFound) && ws; ws = (struct ScaWindowStruct *) ws->ws_Node.mln_Succ)
571 if (!(ws->ws_Flags & WSV_FlagF_TaskSleeps))
573 struct ScaIconNode *in;
574 struct internalScaWindowTask *iwt = (struct internalScaWindowTask *) ws->ws_WindowTask;
576 d1(kprintf("%s/%s/%ld: ObtainSemaphore iwt=%08lx\n", __FILE__, __FUNC__, __LINE__, iwt));
577 ScalosLockIconListShared(iwt);
579 for (in=iwt->iwt_WindowTask.wt_IconList; in; in = (struct ScaIconNode *) in->in_Node.mln_Succ)
581 struct ExtGadget *gg = (struct ExtGadget *) in->in_Icon;
583 if (gg->Flags & GFLG_SELECTED)
585 IPTR tstIconType;
587 GetAttr(IDTA_Type, in->in_Icon, &tstIconType);
588 if (tstIconType == IconType)
590 *wsFound = ws;
591 inFound = in;
592 break;
597 if (NULL == inFound)
599 d1(kprintf("%s/%s/%ld: ReleaseSemaphore iwt=%08lx\n", __FILE__, __FUNC__, __LINE__, iwt));
600 ScalosUnLockIconList(iwt);
605 d1(kprintf("%s/%s/%ld: inFound=%08lx\n", __FILE__, __FUNC__, __LINE__, inFound));
607 return inFound;
611 static BOOL TestToolStart(struct internalScaWindowTask *iwt, struct ScaIconNode *in)
613 Object *IconObj;
614 BOOL isDefIcon = FALSE;
615 BOOL Success;
617 d1(KPrintF("%s/%s/%ld: in=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, in, in->in_Name ? in->in_Name : (STRPTR) ""));
619 IconObj = DoubleClick_GetIconObject(iwt, in, &isDefIcon);
621 d1(kprintf("%s/%s/%ld: IconObj=%08lx isDefIcon=%ld\n", __FILE__, __FUNC__, __LINE__, IconObj, isDefIcon));
622 if (IconObj)
624 Object *origIconObj = in->in_Icon;
625 IPTR IconType;
627 in->in_Icon = IconObj;
629 GetAttr(IDTA_Type, in->in_Icon, &IconType);
631 switch ((ULONG) IconType)
633 case WBTOOL:
634 case WB_TEXTICON_TOOL:
635 if (!isDefIcon)
637 Success = DC_ToolStart(in);
639 DisposeIconObject(in->in_Icon);
640 in->in_Icon = origIconObj;
642 return Success;
644 break;
646 case WBPROJECT:
647 Success = ToolStart(iwt, in);
649 DisposeIconObject(in->in_Icon);
650 in->in_Icon = origIconObj;
652 return Success;
653 break;
655 default:
656 break;
659 in->in_Icon = origIconObj;
660 DisposeIconObject(IconObj);
663 Success = NoToolIcon(iwt, in);
665 return Success;
669 static BOOL NoToolIcon(struct internalScaWindowTask *iwt, struct ScaIconNode *in)
671 DoMethod(iwt->iwt_WindowTask.mt_MainObject,
672 SCCM_IconWin_MenuCommand,
673 "executecommand",
677 return TRUE;
681 static BOOL AppIconStart(struct internalScaWindowTask *iwt, struct ScaIconNode *in)
683 BOOL Success = FALSE;
684 struct AppObject *appo;
686 d1(kprintf("%s/%s/%ld: iwt=%08lx in=%08lx\n", __FILE__, __FUNC__, __LINE__, iwt, in));
688 if (NULL == iwt->iwt_AppListSemaphore)
689 return Success;
691 ScalosObtainSemaphoreShared(iwt->iwt_AppListSemaphore);
693 for (appo=iwt->iwt_AppList; appo; appo = (struct AppObject *) appo->appo_Node.mln_Succ)
695 if (APPTYPE_AppIcon == appo->appo_type
696 && in->in_Icon == appo->appo_object.appoo_IconObject)
698 d1(kprintf("%s/%s/%ld: mp_SigTask=%08lx\n", __FILE__, __FUNC__, __LINE__, appo->appo_msgport->mp_SigTask));
699 if (!CheckTaskState(appo->appo_msgport->mp_SigTask))
701 ScalosReleaseSemaphore(iwt->iwt_AppListSemaphore);
702 SCA_RemoveAppObject(appo);
703 return FALSE;
706 SendAppMessage(appo, AMCLASSICON_Open, iwt->iwt_WindowTask.wt_Window->MouseX, iwt->iwt_WindowTask.wt_Window->MouseY);
707 Success = TRUE;
708 break;
712 ScalosReleaseSemaphore(iwt->iwt_AppListSemaphore);
714 return Success;
718 static BOOL DC_ToolStart(struct ScaIconNode *in)
720 struct WBArg *args;
721 ULONG ArgCount;
722 ULONG NumberOfWbArgs;
723 BOOL Success;
725 d1(KPrintF("%s/%s/%ld: in=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, in, in->in_Name ? in->in_Name : (STRPTR) ""));
727 if (NULL == in->in_Name)
728 return FALSE;
730 NumberOfWbArgs = 1 + SCA_CountWBArgs(in);
732 args = AllocVec(NumberOfWbArgs * sizeof(struct WBArg), MEMF_PUBLIC | MEMF_CLEAR);
733 if (NULL == args)
734 return FALSE;
736 args[0].wa_Lock = Lock("", ACCESS_READ);
737 args[0].wa_Name = in->in_Name;
739 ArgCount = 1 + SCA_MakeWBArgs(&args[1], in, NumberOfWbArgs);
741 debugLock_d1(args[0].wa_Lock);
742 d1(kprintf("%s/%s/%ld: arg[0].wa_Name=<%s>\n", __FILE__, __FUNC__, __LINE__, args[0].wa_Name));
743 d1(kprintf("%s/%s/%ld: ArgCount=%ld\n", __FILE__, __FUNC__, __LINE__, ArgCount));
745 // SCA_WBStart()
746 Success = SCA_WBStartTags(args, ArgCount,
747 SCA_IconObject, (IPTR) in->in_Icon,
748 TAG_END);
750 SCA_FreeWBArgs(&args[1], ArgCount - 1,
751 Success ? (SCAF_FreeNames) : (SCAF_FreeNames | SCAF_FreeLocks));
753 if (!Success)
754 UnLock(args[0].wa_Lock);
756 FreeVec(args);
758 return Success;
762 static BOOL OpenIcon(struct internalScaWindowTask *iwt,
763 struct internalScaWindowTask *iwtIcon, struct ScaIconNode *in, ULONG Flags)
765 BPTR oldDir;
766 BOOL Success = FALSE;
768 d1(KPrintF("%s/%s/%ld: BEGIN Flags=%08lx\n", __FILE__, __FUNC__, __LINE__, Flags));
770 do {
771 struct IBox *WindowRect;
772 BOOL OpenNewWindow;
773 struct Process *myProcess = (struct Process *) FindTask(NULL);
774 struct MsgPort *ReplyPort;
775 ULONG noActivate;
776 ULONG isDdPopup;
777 ULONG BrowserMode;
779 noActivate = (Flags & ICONWINOPENF_DoNotActivateWindow) ? 1 : 0;
780 isDdPopup = (Flags & ICONWINOPENF_DdPopupWindow) ? 1 : 0;
781 BrowserMode = (Flags & ICONWINOPENF_BrowserWindow) ? 1 : 0;
783 OpenNewWindow = (Flags & ICONWINOPENF_NewWindow)
784 || !(iwt->iwt_WindowTask.mt_WindowStruct->ws_Flags & WSV_FlagF_BrowserMode);
786 if (myProcess == iwt->iwt_WindowProcess)
787 ReplyPort = iwt->iwt_WindowTask.wt_IconPort;
788 else
789 ReplyPort = NULL;
791 d1(KPrintF("%s/%s/%ld: myProcess=%08lx WindowProcess=%08lx ReplyPort=%08lx\n", \
792 __FILE__, __FUNC__, __LINE__, myProcess, iwt->iwt_WindowProcess, ReplyPort));
794 if (in->in_Lock)
795 oldDir = CurrentDir(in->in_Lock);
796 else
797 oldDir = CurrentDir(iwtIcon->iwt_WindowTask.mt_WindowStruct->ws_Lock);
799 if (!TestIsDrawer(GetIconName(in)))
800 break;
802 d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
804 if (in->in_Flags & INF_TextIcon)
806 IPTR ShowFlags, ViewBy;
807 Object *IconObj = NewIconObject(in->in_Name,
808 TAG_END);
810 ShowFlags = iwt->iwt_WindowTask.mt_WindowStruct->ws_ViewAll;
811 ViewBy = iwt->iwt_WindowTask.mt_WindowStruct->ws_Viewmodes;
813 if (IconObj)
815 GetAttr(IDTA_Flags, IconObj, &ShowFlags);
816 GetAttr(IDTA_ViewModes, IconObj, &ViewBy);
818 ViewBy = TranslateViewModesFromIcon(ViewBy);
820 d1(kprintf("%s/%s/%ld: IconObj=%08lx\n", __FILE__, __FUNC__, __LINE__, IconObj));
822 DisposeIconObject(IconObj);
825 d1(KPrintF("%s/%s/%ld: Open text icon ShowFlags=%08lx\n", __FILE__, __FUNC__, __LINE__, ShowFlags));
827 if (OpenNewWindow)
829 Success = SCA_OpenIconWindowTags(SCA_Path, (IPTR) in->in_Name,
830 SCA_Flags, SCAF_OpenWindow_ScalosPort,
831 SCA_MessagePort, (IPTR) ReplyPort,
832 SCA_ShowAllMode, ShowFlags & DDFLAGS_SHOWMASK,
833 SCA_ViewModes, ViewBy,
834 SCA_NoActivateWindow, noActivate,
835 SCA_DdPopupWindow, isDdPopup,
836 SCA_CheckOverlappingIcons, CurrentPrefs.pref_CheckOverlappingIcons,
837 SCA_BrowserMode, BrowserMode,
838 TAG_END);
840 else
842 DoMethod(iwt->iwt_WindowTask.mt_MainObject,
843 SCCM_IconWin_NewPath,
844 GetIconName(in),
845 SCA_ShowAllMode, ShowFlags & DDFLAGS_SHOWMASK,
846 SCA_ViewModes, ViewBy,
847 SCA_DdPopupWindow, isDdPopup,
848 SCA_NoActivateWindow, noActivate,
849 SCA_CheckOverlappingIcons, CurrentPrefs.pref_CheckOverlappingIcons,
850 SCA_BrowserMode, BrowserMode,
851 TAG_END);
852 Success = TRUE;
855 d1(kprintf("%s/%s/%ld: Success=%ld\n", __FILE__, __FUNC__, __LINE__, Success));
857 else
859 GetAttr(IDTA_WindowRect, in->in_Icon, (APTR) &WindowRect);
861 d1(KPrintF("%s/%s/%ld: WindowRect=%08lx\n", __FILE__, __FUNC__, __LINE__, WindowRect));
862 if (NULL == WindowRect)
863 WindowRect = &CurrentPrefs.pref_DefWindowBox;
865 if (in->in_Flags & INF_DefaultIcon)
867 d1(KPrintF("%s/%s/%ld: Open default icon\n", __FILE__, __FUNC__, __LINE__));
869 if (OpenNewWindow)
871 Success = SCA_OpenIconWindowTags(SCA_IconNode, (IPTR) in,
872 SCA_Flags, SCAF_OpenWindow_ScalosPort,
873 SCA_MessagePort, (IPTR) ReplyPort,
874 SCA_ShowAllMode, iwt->iwt_OldShowType,
875 SCA_DdPopupWindow, isDdPopup,
876 SCA_NoActivateWindow, noActivate,
877 SCA_CheckOverlappingIcons, CurrentPrefs.pref_CheckOverlappingIcons,
878 SCA_BrowserMode, BrowserMode,
879 TAG_END);
881 else
883 DoMethod(iwt->iwt_WindowTask.mt_MainObject,
884 SCCM_IconWin_NewPath,
885 GetIconName(in),
886 SCA_ShowAllMode, iwt->iwt_OldShowType,
887 SCA_DdPopupWindow, isDdPopup,
888 SCA_NoActivateWindow, noActivate,
889 SCA_CheckOverlappingIcons, CurrentPrefs.pref_CheckOverlappingIcons,
890 SCA_BrowserMode, BrowserMode,
891 TAG_END);
892 Success = TRUE;
895 d1(KPrintF("%s/%s/%ld: Success=%ld\n", __FILE__, __FUNC__, __LINE__, Success));
897 else
899 d1(KPrintF("%s/%s/%ld: Open non-default icon\n", __FILE__, __FUNC__, __LINE__));
901 if (OpenNewWindow)
903 Success = SCA_OpenIconWindowTags(SCA_IconNode, (IPTR) in,
904 SCA_Flags, SCAF_OpenWindow_ScalosPort,
905 SCA_DdPopupWindow, isDdPopup,
906 SCA_NoActivateWindow, noActivate,
907 SCA_MessagePort, (IPTR) ReplyPort,
908 SCA_CheckOverlappingIcons, CurrentPrefs.pref_CheckOverlappingIcons,
909 SCA_BrowserMode, BrowserMode,
910 TAG_END);
912 else
914 WindowNewPath(iwt, GetIconName(in));
915 Success = TRUE;
918 d1(KPrintF("%s/%s/%ld: Success=%ld\n", __FILE__, __FUNC__, __LINE__, Success));
921 } while (0);
923 CurrentDir(oldDir);
925 d1(kprintf("%s/%s/%ld: Begin\n", __FILE__, __FUNC__, __LINE__));
927 if (!Success)
928 DisplayScreenTitleError(iwt, MSGID_CANNOT_OPEN_DRAWER);
930 d1(kprintf("%s/%s/%ld: Finish\n", __FILE__, __FUNC__, __LINE__));
932 return Success;
936 BOOL ArexxToolStart(struct internalScaWindowTask *iwt, BPTR dirLock, CONST_STRPTR ProgName)
938 struct ARexxToolStartArg Args;
939 BOOL Success;
941 d1(kprintf("%s/%s/%ld: iwt=%08lx\n", __FILE__, __FUNC__, __LINE__, iwt));
943 Args.asa_DirLock = DupLock(dirLock);
944 Args.asa_ProgName = AllocCopyString(ProgName);
946 if (iwt && iwt != &MainWindowTask->mwt)
948 Success = DoMethod(iwt->iwt_WindowTask.mt_MainObject, SCCM_RunProcess, AsyncArexxToolStart,
949 &Args, sizeof(Args), SCCV_RunProcess_NoReply);
951 else
953 Success = RunProcess(&iwt->iwt_WindowTask,
954 (RUNPROCFUNC) AsyncArexxToolStart,
955 sizeof(Args) / sizeof(ULONG),
956 (struct WBArg *)(APTR) &Args,
957 iInfos.xii_iinfos.ii_MainMsgPort);
960 return Success;
965 static SAVEDS(ULONG) AsyncArexxToolStart(struct ARexxToolStartArg *arg, struct SM_RunProcess *msg)
967 struct MsgPort *RexxPort;
968 struct RexxMsg *RxMsg = NULL;
969 BOOL RxMsgFilled = FALSE;
970 struct MsgPort *ReplyPort;
972 d1(kprintf("%s/%s/%ld: iwt=%08lx in=%08lx\n", __FILE__, __FUNC__, __LINE__, arg->asa_ProgName));
973 debugLock_d1(arg->asa_DirLock);
975 do {
976 struct Process *myProc = (struct Process *) FindTask(NULL);
978 myProc->pr_WindowPtr = NULL;
980 ReplyPort = CreateMsgPort();
981 if (NULL == ReplyPort)
982 break;
984 RexxPort = FindPort(RXSDIR);
985 d1(kprintf("%s/%s/%ld: RexxPort=%08lx\n", __FILE__, __FUNC__, __LINE__, RexxPort));
986 if (NULL == RexxPort)
987 break;
989 RxMsg = CreateRexxMsg(ReplyPort, "Rexx", "WORKBENCH");
990 d1(kprintf("%s/%s/%ld: RxMsg=%08lx\n", __FILE__, __FUNC__, __LINE__, RxMsg));
991 if (NULL == RxMsg)
992 break;
994 RxMsg->rm_Args[0] = (IPTR)arg->asa_ProgName;
996 RxMsg->rm_Action = RXCOMM;
998 RxMsg->rm_Stdin = Open("NIL:", MODE_OLDFILE);
999 d1(kprintf("%s/%s/%ld: stdin=%08lx\n", __FILE__, __FUNC__, __LINE__, RxMsg->rm_Stdin));
1000 if ((BPTR)NULL == RxMsg->rm_Stdin)
1001 break;
1003 RxMsg->rm_Stdout = Open((STRPTR) CurrentPrefs.pref_ConsoleName, MODE_NEWFILE);
1004 d1(kprintf("%s/%s/%ld: stdout=%08lx\n", __FILE__, __FUNC__, __LINE__, RxMsg->rm_Stdout));
1005 if ((BPTR)NULL == RxMsg->rm_Stdout)
1006 break;
1008 if (!FillRexxMsg(RxMsg, 1, 0))
1009 break;
1011 d1(kprintf("%s/%s/%ld: FillRexxMsg OK\n", __FILE__, __FUNC__, __LINE__));
1013 RxMsgFilled = TRUE;
1015 PutMsg(RexxPort, (struct Message *) RxMsg);
1017 WaitPort(ReplyPort);
1018 GetMsg(ReplyPort);
1019 } while (0);
1021 if (RxMsg)
1023 if (RxMsg->rm_Stdin)
1024 Close(RxMsg->rm_Stdin);
1026 if (RxMsg->rm_Stdout && RETURN_OK == RxMsg->rm_Result1)
1028 // only close Stdout if no error !
1029 Close(RxMsg->rm_Stdout);
1032 if (RxMsgFilled)
1033 ClearRexxMsg(RxMsg, 16);
1035 DeleteRexxMsg(RxMsg);
1037 if (ReplyPort)
1038 DeleteMsgPort(ReplyPort);
1040 FreeCopyString(arg->asa_ProgName);
1041 UnLock(arg->asa_DirLock);
1043 return 0;
1047 static BOOL TestIsDrawer(CONST_STRPTR Name)
1049 T_ExamineData *fib;
1050 BPTR fLock = BNULL;
1051 BOOL isDrawer = TRUE;
1053 d1(KPrintF("%s/%s/%ld: BEGIN Name=<%s>\n", __FILE__, __FUNC__, __LINE__, Name));
1055 do {
1056 if (!ScalosExamineBegin(&fib))
1057 break;
1059 fLock = Lock((STRPTR) Name, ACCESS_READ);
1060 d1(KPrintF("%s/%s/%ld: fLock=%08lx\n", __FILE__, __FUNC__, __LINE__, fLock));
1061 if (BNULL == fLock)
1062 break;
1064 debugLock_d1(fLock);
1066 if (!ScalosExamineLock(fLock, &fib))
1067 break;
1069 d1(KPrintF("%s/%s/%ld: fib_DirEntryType=%ld\n", __FILE__, __FUNC__, __LINE__, fib->fib_DirEntryType));
1071 isDrawer = ScalosExamineIsDrawer(fib);
1072 } while (0);
1074 if (fLock)
1075 UnLock(fLock);
1076 ScalosExamineEnd(&fib);
1078 d1(KPrintF("%s/%s/%ld: END isDrawer=%ld\n", __FILE__, __FUNC__, __LINE__, isDrawer));
1080 return isDrawer;
1084 // Test if task <testTask> is present and has a valid state
1085 static BOOL CheckTaskState(struct Task *testTask)
1087 BOOL TaskOK = TRUE;
1089 if (testTask)
1091 // check whether the owner is still alive
1092 extern struct ExecBase *SysBase;
1093 struct Task *theTask;
1094 BOOL TaskFound = FALSE;
1096 d1(kprintf("%s/%s/%ld: checking if task is still alife\n", __FILE__, __FUNC__, __LINE__));
1098 Disable();
1099 for (theTask = (struct Task *) SysBase->TaskReady.lh_Head;
1100 theTask != (struct Task *) &SysBase->TaskReady.lh_Tail;
1101 theTask = (struct Task *) theTask->tc_Node.ln_Succ )
1103 if (theTask == testTask)
1105 TaskFound = TRUE;
1106 break;
1109 for (theTask = (struct Task *) SysBase->TaskWait.lh_Head;
1110 !TaskFound && (theTask != (struct Task *) &SysBase->TaskWait.lh_Tail);
1111 theTask = (struct Task *) theTask->tc_Node.ln_Succ )
1113 if (theTask == testTask)
1115 if ((0 == theTask->tc_SigWait)
1116 || (TS_INVALID == theTask->tc_State)
1117 || (TS_REMOVED == theTask->tc_State) )
1119 TaskFound = FALSE;
1121 else
1123 TaskFound = TRUE;
1125 break;
1128 Enable();
1130 d1(kprintf("%s/%s/%ld: TaskFound=%ld\n", __FILE__, __FUNC__, __LINE__, TaskFound));
1132 if (!TaskFound)
1134 TaskOK = FALSE;
1138 return TaskOK;