Initial import of Scalos. To decrease size I have
[AROS-Contrib.git] / scalos / main / ScaLibrary.c
blobb51640014eaf7b428dceecfaf551e248620680a4
1 // ScaLibrary.c
2 // $Date$
3 // $Revision$
6 #include <exec/types.h>
7 #include <graphics/gels.h>
8 #include <graphics/rastport.h>
9 #include <intuition/classes.h>
10 #include <intuition/classusr.h>
11 #include <utility/hooks.h>
12 #include <intuition/classusr.h>
13 #include <intuition/gadgetclass.h>
14 #include <intuition/newmouse.h>
15 #include <workbench/workbench.h>
16 #include <workbench/startup.h>
17 #include <libraries/asl.h>
18 #include <devices/timer.h>
19 #include <libraries/gadtools.h>
20 #include <dos/dostags.h>
21 #include <cybergraphx/cybergraphics.h>
23 #define __USE_SYSBASE
25 #include <proto/dos.h>
26 #include <proto/exec.h>
27 #include <proto/layers.h>
28 #include <proto/intuition.h>
29 #include <proto/graphics.h>
30 #include <proto/utility.h>
31 #include <proto/icon.h>
32 #include <proto/gadtools.h>
33 #include <proto/iconobject.h>
34 #include <proto/cybergraphics.h>
35 #include <proto/asl.h>
36 #include "debug.h"
37 #include <proto/scalos.h>
39 #include <clib/alib_protos.h>
41 #include <defs.h>
42 #include <datatypes/iconobject.h>
43 #include <scalos/menu.h>
44 #include <scalos/scalos.h>
46 #include <stdlib.h>
47 #include <stdio.h>
48 #include <string.h>
49 #include <limits.h>
51 #include <DefIcons.h>
53 #include "scalos_structures.h"
54 #include "locale.h"
55 #include "functions.h"
56 #include "Variables.h"
57 #include "ScaLibrary.h"
58 #include "Scalos_rev.h"
60 //----------------------------------------------------------------------------
62 // Scalos.library initialization stuff
64 const char libIdString[] = "scalos.library " VERS_REV_STR " release " RELEASE " (" DATE ")";
65 const char scalosLibName[] = SCALOSNAME;
67 // local data structures
69 enum CheckProject_REQresult { CHKPRJ_Cancel=0, CHKPRJ_SelectTool };
71 typedef void (*NodeSortFuncType)(struct ScalosNodeList *nodeList,
72 struct MinNode *lastNode, ULONG nodeCount, struct Hook *compareHook);
74 //----------------------------------------------------------------------------
76 // local functions
78 static struct List *AllocList(void);
79 static void FreeList(struct List *pl);
80 static struct List *GetProgramList(void);
81 static struct List *GetMenuCommandList(void);
82 static char CheckMenuCommandString(CONST_STRPTR CmdString);
83 static BOOL WaitForReply(struct Process *newProc, struct WblMessage *wblMsg,
84 ULONG WaitDelay, CONST_STRPTR ProgramName, BOOL Arg0Locked);
85 static BOOL CheckProject(Object *IconObject, struct WblInput *wbli,
86 BOOL *CliStart, BOOL *RexxStart, BOOL *Arg0Locked);
87 static struct ScalosClass *FindScalosClass(CONST_STRPTR ClassName);
88 static BOOL RemoveAppIcon(struct internalScaWindowTask *iwt, struct AppObject *appObj);
89 static BOOL RemoveAppWindow(struct internalScaWindowTask *iwt, struct AppObject *appObj);
90 static BOOL RemoveAppMenuItem(struct internalScaWindowTask *iwt, struct AppObject *appObj);
91 static void NewScreenTitle(CONST_STRPTR NewTitle);
92 static ULONG MakeWindowWBArgs(struct ScaWindowStruct *ws,
93 struct ScaIconNode *inExclude,
94 struct WBArg **wbArg, ULONG ArgCount, ULONG MaxArg);
95 static void NodeBubbleSort(struct ScalosNodeList *nodeList,
96 struct MinNode *lastNode, ULONG nodeCount, struct Hook *compareHook);
97 static void NodeSelectionSort(struct ScalosNodeList *nodeList,
98 struct MinNode *lastNode, ULONG nodeCount, struct Hook *compareHook);
99 static void NodeInsertionSort(struct ScalosNodeList *nodeList,
100 struct MinNode *lastNode, ULONG nodeCount, struct Hook *compareHook);
101 static void NodeQuickSort(struct ScalosNodeList *nodeList,
102 struct MinNode *lastNode, ULONG nodeCount, struct Hook *compareHook);
103 static void quickSortList(struct ScalosNodeList *nodeList, struct Hook *compareHook,
104 struct MinNode *firstNode, struct MinNode *lastNode);
105 static struct MinNode *PartitionNodeList(struct ScalosNodeList *nodeList, struct Hook *compareHook,
106 struct MinNode **leftNode, struct MinNode **rightNode);
107 static STRPTR ChkPrjRequestFile(struct WBArg *arg);
108 static ULONG CountWindowWBArgs(struct ScaWindowStruct *ws,
109 struct ScaIconNode *inExclude);
111 //----------------------------------------------------------------------------
113 LIBFUNC_P6(struct AppObject *, sca_NewAddAppIcon,
114 D0, ULONG, ID,
115 D1, ULONG, UserData,
116 A0, Object *, iconObj,
117 A1, struct MsgPort *, msgPort,
118 A2, struct TagItem *, TagList,
119 A6, struct ScalosBase *, ScalosBase)
121 static const struct TagItem AppIconSupportsMap[] =
123 { WBAPPICONA_SupportsOpen, INF_SupportsOpen },
124 { WBAPPICONA_SupportsCopy, INF_SupportsCopy },
125 { WBAPPICONA_SupportsRename, INF_SupportsRename },
126 { WBAPPICONA_SupportsInformation, INF_SupportsInformation },
127 { WBAPPICONA_SupportsSnapshot, INF_SupportsSnapshot },
128 { WBAPPICONA_SupportsUnSnapshot, INF_SupportsUnSnapshot },
129 { WBAPPICONA_SupportsLeaveOut, INF_SupportsLeaveOut },
130 { WBAPPICONA_SupportsPutAway, INF_SupportsPutAway },
131 { WBAPPICONA_SupportsDelete, INF_SupportsDelete },
132 { WBAPPICONA_SupportsFormatDisk, INF_SupportsFormatDisk },
133 { WBAPPICONA_SupportsEmptyTrash, INF_SupportsEmptyTrash },
134 { TAG_DONE, 0 },
136 struct internalScaWindowTask *iwt = (struct internalScaWindowTask *) iInfos.xii_iinfos.ii_AppWindowStruct->ws_WindowTask;
137 struct AppObject *appo;
138 struct ScaIconNode *in;
140 (void)ScalosBase;
142 d1(kprintf("\n" "%s/%s/%ld: ID=%08lx UserData=%08lx IconObj=%08lx MsgPort=%08lx TagList=%08lx\n", \
143 __FILE__, __FUNC__, __LINE__, ID, UserData, iconObj, msgPort, TagList));
145 ScalosObtainSemaphore(iwt->iwt_AppListSemaphore);
147 do {
148 struct ExtGadget *gg = (struct ExtGadget *) iconObj;
149 struct Hook *renderHook;
151 appo = (struct AppObject *) SCA_AllocStdNode((struct ScalosNodeList *) &iwt->iwt_AppList, NTYP_AppObject);
152 if (NULL == appo)
153 break;
155 appo->appo_Kennung = ID_SC;
156 appo->appo_type = APPTYPE_AppIcon;
157 appo->appo_id = ID;
158 appo->appo_userdata = UserData;
159 appo->appo_msgport = msgPort;
160 appo->appo_object.appoo_IconObject = iconObj;
161 appo->appo_TagList = CloneTagItems(TagList);
163 renderHook = (struct Hook *) GetTagData(WBAPPICONA_RenderHook, (ULONG)NULL, TagList);
165 SetAttrs(iconObj,
166 IDTA_Type, WBAPPICON,
167 IDTA_InnerBottom, CurrentPrefs.pref_ImageBorders.Bottom,
168 IDTA_InnerRight, CurrentPrefs.pref_ImageBorders.Right,
169 IDTA_InnerTop, CurrentPrefs.pref_ImageBorders.Top,
170 IDTA_InnerLeft, CurrentPrefs.pref_ImageBorders.Left,
171 IDTA_HalfShinePen, PalettePrefs.pal_PensList[PENIDX_HSHINEPEN],
172 IDTA_HalfShadowPen, PalettePrefs.pal_PensList[PENIDX_HSHADOWPEN],
173 IDTA_FrameType, CurrentPrefs.pref_FrameType,
174 IDTA_FrameTypeSel, CurrentPrefs.pref_FrameTypeSel,
175 IDTA_TextSkip, CurrentPrefs.pref_TextSkip,
176 IDTA_MultiLineText, (ULONG) CurrentPrefs.pref_IconTextMuliLine,
177 IDTA_TextPen, PalettePrefs.pal_PensList[PENIDX_ICONTEXTPEN],
178 IDTA_TextPenSel, PalettePrefs.pal_PensList[PENIDX_ICONTEXTPENSEL],
179 IDTA_TextPenShadow, PalettePrefs.pal_PensList[PENIDX_ICONTEXTSHADOWPEN],
180 IDTA_TextPenOutline, PalettePrefs.pal_PensList[PENIDX_ICONTEXTOUTLINEPEN],
181 IDTA_TextPenBgSel, PalettePrefs.pal_PensList[PENIDX_ICONTEXTPENBGSEL],
182 IDTA_SelectedTextRectangle, CurrentPrefs.pref_SelectedTextRectangle,
183 IDTA_SelTextRectBorderX, CurrentPrefs.pref_SelTextRectBorderX,
184 IDTA_SelTextRectBorderY, CurrentPrefs.pref_SelTextRectBorderY,
185 IDTA_SelTextRectRadius, CurrentPrefs.pref_SelTextRectRadius,
186 IDTA_TextMode, CurrentPrefs.pref_TextMode,
187 IDTA_TextDrawMode, FontPrefs.fprf_TextDrawMode,
188 IDTA_TextBackPen, FontPrefs.fprf_FontBackPen,
189 IDTA_Font, (ULONG) iwt->iwt_IconFont,
190 IDTA_Fonthandle, (ULONG) &iwt->iwt_IconTTFont,
191 IDTA_FontHook, (ULONG) (TTEngineBase ? &ScalosFontHook : NULL),
192 IDTA_RenderHook, (ULONG) renderHook,
193 IDTA_SizeConstraints, (ULONG) &iInfos.xii_iinfos.ii_AppWindowStruct->ws_IconSizeConstraints,
194 IDTA_ScalePercentage, iInfos.xii_iinfos.ii_AppWindowStruct->ws_IconScaleFactor,
195 TAG_END);
197 DoMethod(iwt->iwt_WindowTask.mt_MainObject, SCCM_IconWin_LayoutIcon, iconObj, IOLAYOUTF_NormalImage);
199 ScalosLockIconListExclusive(iwt);
201 in = (struct ScaIconNode *) SCA_AllocStdNode(
202 (struct ScalosNodeList *) (IsNoIconPosition(gg) ? &iwt->iwt_WindowTask.wt_LateIconList : &iwt->iwt_WindowTask.wt_IconList),
203 NTYP_IconNode);
205 if (NULL == in)
207 SCA_FreeNode((struct ScalosNodeList *) &iwt->iwt_AppList, &appo->appo_Node);
208 appo = NULL;
209 ScalosUnLockIconList(iwt);
210 break;
213 d1(kprintf("%s/%s/%ld: in=%08lx Pred=%08lx Succ=%08lx\n", __FILE__, __FUNC__, __LINE__, \
214 in, in->in_Node.mln_Pred, in->in_Node.mln_Succ));
216 in->in_Icon = iconObj;
217 in->in_FileType = (struct TypeNode *) WBAPPICON;
219 in->in_SupportFlags = PackBoolTags(in->in_SupportFlags, TagList, (struct TagItem *) AppIconSupportsMap);
221 ScalosUnLockIconList(iwt);
223 d1(kprintf("%s/%s/%ld: in=%08lx <%s> Left=%ld Top=%ld\n", __FILE__, __FUNC__, __LINE__, \
224 in, in->in_Name, gg->LeftEdge, gg->TopEdge));
226 if (!IsNoIconPosition(gg))
228 d1(kprintf("%s/%s/%ld: \n", __LINE__));
230 if (!CheckPosition(iwt, in) && !CheckOverlap(iwt, in))
231 DoMethod(iwt->iwt_WindowTask.mt_MainObject, SCCM_IconWin_DrawIcon, iconObj);
234 DoMethod(iwt->iwt_WindowTask.mt_MainObject, SCCM_IconWin_CleanUp);
235 } while (0);
237 ScalosReleaseSemaphore(iwt->iwt_AppListSemaphore);
239 return appo;
241 LIBFUNC_END
243 LIBFUNC_P3(ULONG, sca_ScalosControl,
244 A0, CONST_STRPTR, name,
245 A1, struct TagItem *, taglist,
246 A6, struct ScalosBase *, ScalosBase)
248 ULONG TagsSuccessfullyProcessed = 0;
249 struct TagItem *TState = taglist;
250 struct TagItem *Tag;
251 BOOL DoUpdateAll = FALSE;
253 (void) ScalosBase;
255 d1(kprintf("%s/%s/%ld: name=%08lx <%s> taglist=%08lx\n", __FILE__, __FUNC__, __LINE__, name ? name : (STRPTR) "", taglist));
257 (void) name;
259 while ((Tag = NextTagItem(&TState)))
261 LONG ErrorCode = RETURN_OK;
263 switch (Tag->ti_Tag)
265 case SCALOSCTRLA_GetDefaultStackSize:
266 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_GetDefaultStackSize ti_Data=%08lx\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
267 if (Tag->ti_Data)
269 *((ULONG *) Tag->ti_Data) = CurrentPrefs.pref_DefaultStackSize;
271 else
272 ErrorCode = ERROR_REQUIRED_ARG_MISSING;
273 break;
275 case SCALOSCTRLA_SetDefaultStackSize:
276 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_SetDefaultStackSize ti_Data=%lu\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
277 if (Tag->ti_Data >= 8192L)
279 CurrentPrefs.pref_DefaultStackSize = Tag->ti_Data;
281 else
282 ErrorCode = ERROR_BAD_NUMBER;
283 break;
285 case SCALOSCTRLA_GetProgramList:
286 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_GetProgramList ti_Data=%08lx\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
287 if (Tag->ti_Data)
289 *((struct List **) Tag->ti_Data) = GetProgramList();
291 if (NULL == *((struct List **) Tag->ti_Data))
292 ErrorCode = ERROR_NO_FREE_STORE;
294 else
295 ErrorCode = ERROR_REQUIRED_ARG_MISSING;
296 break;
298 case SCALOSCTRLA_FreeProgramList:
299 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_FreeProgramList ti_Data=%08lx\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
300 FreeList((struct List *) Tag->ti_Data);
301 break;
303 case SCALOSCTRLA_GetMenuCommandList:
304 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_GetMenuCommandList ti_Data=%08lx\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
305 if (Tag->ti_Data)
307 *((struct List **) Tag->ti_Data) = GetMenuCommandList();
309 if (NULL == *((struct List **) Tag->ti_Data))
310 ErrorCode = ERROR_NO_FREE_STORE;
312 else
313 ErrorCode = ERROR_REQUIRED_ARG_MISSING;
314 break;
316 case SCALOSCTRLA_FreeMenuCommandList:
317 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_FreeMenuCommandList ti_Data=%08lx\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
318 FreeList((struct List *) Tag->ti_Data);
319 break;
321 case SCALOSCTRLA_GetCloseWBDisabled:
322 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_GetCloseWBDisabled ti_Data=%08lx\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
323 if (Tag->ti_Data)
324 *((ULONG *) Tag->ti_Data) = (CurrentPrefs.pref_DisableCloseWorkbench != 0);
325 else
326 ErrorCode = ERROR_REQUIRED_ARG_MISSING;
327 break;
329 case SCALOSCTRLA_SetCloseWBDisabled:
330 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_SetCloseWBDisabled ti_Data=%lu\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
331 CurrentPrefs.pref_DisableCloseWorkbench = (Tag->ti_Data != 0);
332 break;
334 case SCALOSCTRLA_GetSplashEnable:
335 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_GetSplashEnable ti_Data=%08lx\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
336 if (Tag->ti_Data)
337 *((ULONG *) Tag->ti_Data) = (CurrentPrefs.pref_EnableSplash != 0);
338 else
339 ErrorCode = ERROR_REQUIRED_ARG_MISSING;
340 break;
342 case SCALOSCTRLA_SetSplashEnable:
343 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_SetSplashEnable ti_Data=%lu\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
344 CurrentPrefs.pref_EnableSplash = (Tag->ti_Data != 0);
345 break;
347 case SCALOSCTRLA_GetToolTipEnable:
348 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_GetToolTipEnable ti_Data=%08lx\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
349 if (Tag->ti_Data)
350 *((ULONG *) Tag->ti_Data) = (CurrentPrefs.pref_EnableTooltips != 0);
351 else
352 ErrorCode = ERROR_REQUIRED_ARG_MISSING;
353 break;
355 case SCALOSCTRLA_SetToolTipEnable:
356 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_SetToolTipEnable ti_Data=%lu\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
357 CurrentPrefs.pref_EnableTooltips = (Tag->ti_Data != 0);
358 break;
360 case SCALOSCTRLA_GetToolTipDelay:
361 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_GetToolTipDelay ti_Data=%08lx\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
362 if (Tag->ti_Data)
363 *((ULONG *) Tag->ti_Data) = CurrentPrefs.pref_ToolTipDelaySeconds;
364 else
365 ErrorCode = ERROR_REQUIRED_ARG_MISSING;
366 break;
368 case SCALOSCTRLA_SetToolTipDelay:
369 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_SetToolTipDelay ti_Data=%lu\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
370 if (Tag->ti_Data > 0 && Tag->ti_Data < 600)
371 CurrentPrefs.pref_ToolTipDelaySeconds = Tag->ti_Data;
372 else
373 ErrorCode = ERROR_BAD_NUMBER;
374 break;
376 case SCALOSCTRLA_GetOldDragIconMode:
377 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_GetOldDragIconMode ti_Data=%08lx\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
378 if (Tag->ti_Data)
379 *((ULONG *) Tag->ti_Data) = (CurrentPrefs.pref_UseOldDragIcons != 0);
380 else
381 ErrorCode = ERROR_REQUIRED_ARG_MISSING;
382 break;
384 case SCALOSCTRLA_SetOldDragIconMode:
385 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_SetOldDragIconMode ti_Data=%lu\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
386 CurrentPrefs.pref_UseOldDragIcons = (Tag->ti_Data != 0);
387 break;
389 case SCALOSCTRLA_GetTypeRestartTime:
390 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_GetTypeRestartTime ti_Data=%08lx\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
391 if (Tag->ti_Data)
392 *((ULONG *) Tag->ti_Data) = CurrentPrefs.pref_TypeRestartTime;
393 else
394 ErrorCode = ERROR_REQUIRED_ARG_MISSING;
395 break;
397 case SCALOSCTRLA_SetTypeRestartTime:
398 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_SetTypeRestartTime ti_Data=%lu\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
399 if (Tag->ti_Data > 0)
400 CurrentPrefs.pref_TypeRestartTime = Tag->ti_Data;
401 else
402 ErrorCode = ERROR_BAD_NUMBER;
403 break;
405 case SCALOSCTRLA_GetEmulationMode:
406 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_GetEmulationMode ti_Data=%08lx\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
407 if (Tag->ti_Data)
408 *((ULONG *) Tag->ti_Data) = MainWindowTask->emulation != 0;
409 else
410 ErrorCode = ERROR_REQUIRED_ARG_MISSING;
411 break;
413 case SCALOSCTRLA_GetStatusBarEnable:
414 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_GetStatusBarEnable ti_Data=%08lx\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
415 if (Tag->ti_Data)
416 *((ULONG *) Tag->ti_Data) = (CurrentPrefs.pref_DisplayStatusBar != 0);
417 else
418 ErrorCode = ERROR_REQUIRED_ARG_MISSING;
419 break;
421 case SCALOSCTRLA_SetStatusBarEnable:
422 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_SetStatusBarEnable ti_Data=%lu\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
423 CurrentPrefs.pref_DisplayStatusBar = (Tag->ti_Data != 0);
424 break;
426 case SCALOSCTRLA_GetStripedTextWindows:
427 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_GetStripedTextWindows ti_Data=%08lx\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
428 if (Tag->ti_Data)
429 *((ULONG *) Tag->ti_Data) = (CurrentPrefs.pref_TextWindowStriped != 0);
430 else
431 ErrorCode = ERROR_REQUIRED_ARG_MISSING;
432 break;
434 case SCALOSCTRLA_SetStripedTextWindows:
435 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_SetStripedTextWindows ti_Data=%lu\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
436 CurrentPrefs.pref_TextWindowStriped = (Tag->ti_Data != 0);
437 break;
439 case SCALOSCTRLA_GetWindowDropMarkMode:
440 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_GetWindowDropMarkMode ti_Data=%08lx\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
441 if (Tag->ti_Data)
442 *((ULONG *) Tag->ti_Data) = CurrentPrefs.pref_WindowDropMarkMode;
443 else
444 ErrorCode = ERROR_REQUIRED_ARG_MISSING;
445 break;
447 case SCALOSCTRLA_SetWindowDropMarkMode:
448 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_SetWindowDropMarkMode ti_Data=%lu\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
449 if (Tag->ti_Data >= IDTV_WinDropMark_Never && Tag->ti_Data <= IDTV_WinDropMark_Always)
450 CurrentPrefs.pref_WindowDropMarkMode = Tag->ti_Data;
451 else
452 ErrorCode = ERROR_BAD_NUMBER;
453 break;
455 case SCALOSCTRLA_GetDisplayDragCount:
456 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_GetDisplayDragCount ti_Data=%08lx\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
457 if (Tag->ti_Data)
458 *((ULONG *) Tag->ti_Data) = (CurrentPrefs.pref_ShowDDCountText != 0);
459 else
460 ErrorCode = ERROR_REQUIRED_ARG_MISSING;
461 break;
463 case SCALOSCTRLA_SetDisplayDragCount:
464 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_SetDisplayDragCount ti_Data=%lu\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
465 CurrentPrefs.pref_ShowDDCountText = (Tag->ti_Data != 0);
466 break;
468 case SCALOSCTRLA_GetSupportedIconTypes:
469 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_GetSupportedIconTypes ti_Data=%08lx\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
470 if (Tag->ti_Data)
471 *((ULONG *) Tag->ti_Data) = CurrentPrefs.pref_SupportedIconTypes;
472 else
473 ErrorCode = ERROR_REQUIRED_ARG_MISSING;
474 break;
476 case SCALOSCTRLA_SetSupportedIconTypes:
477 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_SetSupportedIconTypes ti_Data=%08lx\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
478 if (CurrentPrefs.pref_SupportedIconTypes != Tag->ti_Data)
480 DoUpdateAll = TRUE;
481 CurrentPrefs.pref_SupportedIconTypes = Tag->ti_Data;
483 break;
485 case SCALOSCTRLA_GetCopyHook:
486 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_GetCopyHook ti_Data=%08lx\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
487 if (Tag->ti_Data)
488 *((struct Hook **) Tag->ti_Data) = globalCopyHook;
489 else
490 ErrorCode = ERROR_REQUIRED_ARG_MISSING;
491 break;
493 case SCALOSCTRLA_SetCopyHook:
494 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_SetCopyHook ti_Data=%08lx\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
495 ScalosObtainSemaphore(&CopyHookSemaphore);
496 globalCopyHook = (struct Hook *) Tag->ti_Data;
497 ScalosReleaseSemaphore(&CopyHookSemaphore);
498 break;
500 case SCALOSCTRLA_GetCopyBuffSize:
501 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_GetCopyBuffSize ti_Data=%08lx\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
502 if (Tag->ti_Data)
503 *((ULONG *) Tag->ti_Data) = CurrentPrefs.pref_CopyBuffLen;
504 else
505 ErrorCode = ERROR_REQUIRED_ARG_MISSING;
506 break;
508 case SCALOSCTRLA_SetCopyBuffSize:
509 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_SetCopyBuffSize ti_Data=%lu\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
510 if (Tag->ti_Data >= 4096 && Tag->ti_Data <= 0x400000)
511 CurrentPrefs.pref_CopyBuffLen = Tag->ti_Data;
512 else
513 ErrorCode = ERROR_BAD_NUMBER;
514 break;
516 case SCALOSCTRLA_GetDeleteHook:
517 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_GetDeleteHook ti_Data=%08lx\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
518 if (Tag->ti_Data)
519 *((struct Hook **) Tag->ti_Data) = globalDeleteHook;
520 else
521 ErrorCode = ERROR_REQUIRED_ARG_MISSING;
522 break;
524 case SCALOSCTRLA_SetDeleteHook:
525 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_SetDeleteHook ti_Data=%08lx\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
526 if (ScalosAttemptSemaphore(&DeleteHookSemaphore))
528 globalDeleteHook = (struct Hook *) Tag->ti_Data;
529 ScalosReleaseSemaphore(&DeleteHookSemaphore);
531 else
532 ErrorCode = ERROR_OBJECT_IN_USE;
533 break;
535 case SCALOSCTRLA_GetTextInputHook:
536 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_GetTextInputHook ti_Data=%08lx\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
537 if (Tag->ti_Data)
538 *((struct Hook **) Tag->ti_Data) = globalTextInputHook;
539 else
540 ErrorCode = ERROR_REQUIRED_ARG_MISSING;
541 break;
543 case SCALOSCTRLA_SetTextInputHook:
544 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_SetTextInputHook ti_Data=%08lx\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
545 if (ScalosAttemptSemaphore(&TextInputHookSemaphore))
547 globalTextInputHook = (struct Hook *) Tag->ti_Data;
548 ScalosReleaseSemaphore(&TextInputHookSemaphore);
550 else
551 ErrorCode = ERROR_OBJECT_IN_USE;
552 break;
554 case SCALOSCTRLA_AddCloseWBHook:
555 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_AddCloseWBHook ti_Data=%08lx\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
556 if (Tag->ti_Data)
558 BOOL Found = FALSE;
559 struct Hook *hook;
560 struct Hook *newHook = (struct Hook *) Tag->ti_Data;
562 ScalosObtainSemaphore(&CloseWBHookListSemaphore);
564 for (hook = (struct Hook *) globalCloseWBHookList.lh_Head;
565 hook != (struct Hook *) &globalCloseWBHookList.lh_Tail;
566 hook = (struct Hook *) hook->h_MinNode.mln_Succ)
568 if (hook == newHook)
570 Found = TRUE;
571 break;
575 if (Found)
576 ErrorCode = ERROR_OBJECT_EXISTS;
577 else
578 AddTail(&globalCloseWBHookList, (struct Node *) newHook);
580 ScalosReleaseSemaphore(&CloseWBHookListSemaphore);
582 else
583 ErrorCode = ERROR_REQUIRED_ARG_MISSING;
584 break;
586 case SCALOSCTRLA_RemCloseWBHook:
587 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_RemCloseWBHook ti_Data=%08lx\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
588 if (Tag->ti_Data)
590 BOOL Found = FALSE;
591 struct Hook *hook;
592 struct Hook *oldHook = (struct Hook *) Tag->ti_Data;
594 ScalosObtainSemaphore(&CloseWBHookListSemaphore);
596 for (hook = (struct Hook *) globalCloseWBHookList.lh_Head;
597 hook != (struct Hook *) &globalCloseWBHookList.lh_Tail;
598 hook = (struct Hook *) hook->h_MinNode.mln_Succ)
600 if (hook == oldHook)
602 Found = TRUE;
603 break;
607 if (Found)
608 Remove((struct Node *) oldHook);
609 else
610 ErrorCode = ERROR_OBJECT_NOT_FOUND;
612 ScalosReleaseSemaphore(&CloseWBHookListSemaphore);
614 else
615 ErrorCode = ERROR_REQUIRED_ARG_MISSING;
616 break;
618 case SCALOSCTRLA_GetSemaphoreList:
619 d1(kprintf("%s/%s/%ld: SCALOSCTRLA_GetSemaphoreList ti_Data=%08lx\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Data));
620 if (Tag->ti_Data)
621 *((struct ScalosSemaphoreList **) Tag->ti_Data) = GlobalSemaphoreList;
622 else
623 ErrorCode = ERROR_REQUIRED_ARG_MISSING;
624 break;
626 default:
627 d1(kprintf("%s/%s/%ld: unknown ti_Tag=%08lx ti_Data=%08lx\n", __FILE__, __FUNC__, __LINE__, Tag->ti_Tag, Tag->ti_Data));
628 ErrorCode = ERROR_ACTION_NOT_KNOWN;
629 break;
632 d1(kprintf("%s/%s/%ld: ErrorCode=%ld\n", __FILE__, __FUNC__, __LINE__, ErrorCode));
634 if (RETURN_OK == ErrorCode)
635 TagsSuccessfullyProcessed++;
636 else
637 SetIoErr(ErrorCode);
640 if (DoUpdateAll && iInfos.xii_iinfos.ii_MainWindowStruct)
642 UpdateAllProg((struct internalScaWindowTask *) iInfos.xii_iinfos.ii_MainWindowStruct->ws_WindowTask, NULL);
645 d1(kprintf("%s/%s/%ld: TagsSuccessfullyProcessed=%lu\n", __FILE__, __FUNC__, __LINE__, TagsSuccessfullyProcessed));
647 return TagsSuccessfullyProcessed;
649 LIBFUNC_END
652 static struct List *AllocList(void)
654 struct List *pl = ScalosAlloc(sizeof(struct List));
656 if (pl)
658 pl->lh_Type = 0;
660 NewList(pl);
663 return pl;
667 static void FreeList(struct List *pl)
669 struct Node *xNode;
671 if (NULL == pl)
672 return;
674 while ((xNode = RemHead(pl)))
676 if (xNode->ln_Name)
678 ScalosFree(xNode->ln_Name);
679 xNode->ln_Name = NULL;
681 ScalosFree(xNode);
684 free(pl);
688 static struct List *GetProgramList(void)
690 struct List *pl = AllocList();
692 if (pl)
694 struct Node *wbNode;
696 ScalosObtainSemaphoreShared(&WBStartListSema);
698 for (wbNode = WBStartList.lh_Head; wbNode != (struct Node *) &WBStartList.lh_Tail; wbNode = wbNode->ln_Succ)
700 struct Node *newNode = ScalosAlloc(sizeof(struct Node));
702 d1(kprintf("%s/%s/%ld: wbNode=%08lx Name=%08lx\n", __FILE__, __FUNC__, __LINE__, \
703 wbNode, wbNode->ln_Name));
705 if (newNode)
707 newNode->ln_Type = NT_USER;
708 newNode->ln_Name = ScalosAlloc(strlen(wbNode->ln_Name) + 1);
709 if (newNode->ln_Name)
710 strcpy(newNode->ln_Name, wbNode->ln_Name);
712 AddTail(pl, newNode);
716 ScalosReleaseSemaphore(&WBStartListSema);
719 return pl;
723 static struct List *GetMenuCommandList(void)
725 struct List *pl = AllocList();
727 if (pl)
729 const struct ScalosMenuCommand *cmd;
731 for (cmd = &MenuCommandTable[0]; cmd->smcom_CommandName; cmd++)
733 struct Node *newNode = ScalosAlloc(sizeof(struct Node));
735 if (newNode)
737 newNode->ln_Type = NT_USER;
738 newNode->ln_Name = ScalosAlloc(strlen(cmd->smcom_CommandName) + 1);
739 if (newNode->ln_Name)
740 strcpy(newNode->ln_Name, cmd->smcom_CommandName);
742 AddTail(pl, newNode);
747 return pl;
751 // SCA_NewAddAppMenuItem()
752 // AddAppMenuItemA()
753 LIBFUNC_P6(struct AppObject *, sca_NewAddAppMenuItem,
754 D0, ULONG, ID,
755 D1, ULONG, UserData,
756 A0, CONST_STRPTR, MenuText,
757 A1, struct MsgPort *, msgPort,
758 A2, struct TagItem *, TagList,
759 A6, struct ScalosBase *, ScalosBase)
761 struct internalScaWindowTask *iwt = (struct internalScaWindowTask *) iInfos.xii_iinfos.ii_AppWindowStruct->ws_WindowTask;
762 struct Menu *theNewMenu = NULL;
763 struct AppObject *appo;
764 BOOL WinListLocked = FALSE;
765 BOOL Success = FALSE;
767 (void)ScalosBase;
769 ScalosObtainSemaphore(iwt->iwt_AppListSemaphore);
771 d1(kprintf("\n" "%s/%s/%ld: ID=%08lx UserData=%08lx MenuText=<%s>\n", \
772 __FILE__, __FUNC__, __LINE__, ID, UserData, MenuText));
774 do {
775 CONST_STRPTR CmdString;
776 CONST_STRPTR lpc;
777 char CommKey[2];
778 struct AppMenuInfo **SubKey, **TitleKey;
780 appo = (struct AppObject *) SCA_AllocStdNode((struct ScalosNodeList *) &iwt->iwt_AppList, NTYP_AppObject);
781 if (NULL == appo)
782 break;
784 CmdString = (STRPTR) GetTagData(WBAPPMENUA_CommandKeyString, (ULONG) "", TagList);
786 SubKey = (struct AppMenuInfo **) GetTagData(WBAPPMENUA_GetKey, (ULONG)NULL, TagList);
787 TitleKey = (struct AppMenuInfo **) GetTagData(WBAPPMENUA_GetTitleKey, (ULONG)NULL, TagList);
789 appo->appo_Kennung = ID_SC;
790 appo->appo_type = APPTYPE_AppMenuItem;
791 appo->appo_id = ID;
792 appo->appo_userdata = UserData;
793 appo->appo_msgport = msgPort;
794 appo->appo_object.appoo_MenuInfo = ScalosAlloc(sizeof(struct AppMenuInfo));
795 appo->appo_userdata2 = NULL;
797 if (NULL == appo->appo_object.appoo_MenuInfo)
798 break;
800 memset(CommKey, 0, sizeof(CommKey));
801 memset(appo->appo_object.appoo_MenuInfo, 0, sizeof(struct AppMenuInfo));
803 CommKey[0] = CheckMenuCommandString(CmdString);
805 NewList(&appo->appo_object.appoo_MenuInfo->ami_ChildList);
807 appo->appo_object.appoo_MenuInfo->ami_Magic = ID_SAMI;
808 appo->appo_object.appoo_MenuInfo->ami_NewMenu.nm_CommKey = *CommKey ? AllocCopyString(CommKey) : NULL;
809 appo->appo_object.appoo_MenuInfo->ami_NewMenu.nm_Flags = 0;
810 appo->appo_object.appoo_MenuInfo->ami_NewMenu.nm_MutualExclude = 0L;
811 appo->appo_object.appoo_MenuInfo->ami_NewMenu.nm_UserData = appo;
812 appo->appo_object.appoo_MenuInfo->ami_NewMenu.nm_Type = NM_ITEM;
814 d1(kprintf("%s/%s/%ld: TitleKey=%08lx CommKey=%02lx\n", __FILE__, __FUNC__, __LINE__, appo->appo_object.appoo_MenuInfo->ami_NewMenu.nm_CommKey));
815 d1(kprintf("%s/%s/%ld: MenuInfo=%08lx\n", __FILE__, __FUNC__, __LINE__, appo->appo_object.appoo_MenuInfo));
816 d1(kprintf("%s/%s/%ld: TitleKey=%08lx SubKey=%08lx\n", __FILE__, __FUNC__, __LINE__, TitleKey, SubKey));
818 if (TitleKey)
820 appo->appo_object.appoo_MenuInfo->ami_NewMenu.nm_Type = NM_TITLE;
822 *TitleKey = appo->appo_object.appoo_MenuInfo;
824 else if (SubKey)
826 *SubKey = appo->appo_object.appoo_MenuInfo;
829 appo->appo_object.appoo_MenuInfo->ami_Parent = (struct AppMenuInfo *) GetTagData(WBAPPMENUA_UseKey, (ULONG)NULL, TagList);
831 if (appo->appo_object.appoo_MenuInfo->ami_Parent)
833 if (!(TypeOfMem(appo->appo_object.appoo_MenuInfo->ami_Parent) & MEMF_PUBLIC)
834 || ID_SAMI != appo->appo_object.appoo_MenuInfo->ami_Parent->ami_Magic)
836 appo->appo_object.appoo_MenuInfo->ami_Parent = NULL;
840 d1(kprintf("%s/%s/%ld: ami_Parent=%08lx\n", __FILE__, __FUNC__, __LINE__, appo->appo_object.appoo_MenuInfo->ami_Parent));
842 if (appo->appo_object.appoo_MenuInfo->ami_Parent)
844 if (NM_TITLE == appo->appo_object.appoo_MenuInfo->ami_Parent->ami_NewMenu.nm_Type)
846 appo->appo_object.appoo_MenuInfo->ami_NewMenu.nm_Type = NM_ITEM;
848 else
850 appo->appo_object.appoo_MenuInfo->ami_NewMenu.nm_Type = NM_SUB;
852 if (SubKey)
853 break; // cascading of submenus is not allowed
857 d1(kprintf("%s/%s/%ld: nm_Type=%ld\n", __FILE__, __FUNC__, __LINE__, appo->appo_object.appoo_MenuInfo->ami_NewMenu.nm_Type));
859 // starting with V44, any menu
860 // label consisting entirely of '-', '_' or '~' characters will
861 // result in a separator bar to be added in place of a textual item.
863 appo->appo_object.appoo_MenuInfo->ami_NewMenu.nm_Label = NM_BARLABEL;
864 for (lpc=MenuText; *lpc; lpc++)
866 if (*lpc != '-' && *lpc != '_' && *lpc != '~')
868 d1(kprintf("%s/%s/%ld: lpc=<%s>\n", __FILE__, __FUNC__, __LINE__, lpc));
869 appo->appo_object.appoo_MenuInfo->ami_NewMenu.nm_Label = AllocCopyString(MenuText);
870 break;
874 d1(kprintf("%s/%s/%ld: nm_Label=%08lx\n", __FILE__, __FUNC__, __LINE__, appo->appo_object.appoo_MenuInfo->ami_NewMenu.nm_Label));
876 Success = AppMenu_AddItem(appo->appo_object.appoo_MenuInfo);
877 } while (0);
879 if (WinListLocked)
880 SCA_UnLockWindowList();
882 ScalosReleaseSemaphore(iwt->iwt_AppListSemaphore);
884 d1(kprintf("%s/%s/%ld: Success=%ld\n", __FILE__, __FUNC__, __LINE__, Success));
886 if (Success)
887 AppMenu_ResetMenu();
888 else
890 if (theNewMenu)
891 FreeMenus(theNewMenu);
892 if (appo)
894 AppMenu_DisposeAppMenuInfo(appo->appo_object.appoo_MenuInfo);
895 SCA_FreeNode((struct ScalosNodeList *) &iwt->iwt_AppList, &appo->appo_Node);
899 return appo;
901 LIBFUNC_END
904 // check if menu command character *CmdString is already in use
905 static char CheckMenuCommandString(CONST_STRPTR CmdString)
907 char CmdChar;
908 struct Menu *theMenu;
910 if (NULL == CmdString)
911 return 0;
913 CmdChar = *CmdString;
914 if ('\0' == CmdChar)
915 return 0;
917 CmdChar = ToUpper(CmdChar);
919 for (theMenu=MainMenu; theMenu; theMenu=theMenu->NextMenu)
921 struct MenuItem *mItem;
923 for (mItem=theMenu->FirstItem; mItem; mItem=mItem->NextItem)
925 struct MenuItem *mSub;
927 if ((mItem->Flags & COMMSEQ) && mItem->Command == CmdChar)
928 return 0;
930 for (mSub=mItem->SubItem; mSub; mSub=mSub->NextItem)
932 if ((mSub->Flags & COMMSEQ) && mSub->Command == CmdChar)
933 return 0;
938 return CmdChar;
942 // SCA_WBStart()
943 LIBFUNC_P4(BOOL, sca_WBStart,
944 A0, struct WBArg *, ArgArray,
945 A1, struct TagItem *, TagList,
946 D0, ULONG, NumArgs,
947 A6, struct ScalosBase *, ScalosBase)
949 struct WblMessage *wblArg = NULL;
950 BOOL Success = FALSE;
951 struct Process *newProc;
952 BOOL cliStart = FALSE;
953 BOOL RexxStart = FALSE;
954 BOOL Arg0Locked = FALSE;
956 (void) ScalosBase;
958 d1(KPrintF("\n" "%s/%s/%ld: START ArgArray=%08lx TagList=%08lx NumArgs=%ld\n", \
959 __FILE__, __FUNC__, __LINE__, ArgArray, TagList, NumArgs));
961 do {
962 Object *IconObject = NULL;
963 ULONG WaitDelay;
964 ULONG n;
966 if (NumArgs < 1)
967 break;
969 wblArg = AllocVec(sizeof(struct WblMessage) + (1 + NumArgs) * sizeof(struct WBArg), MEMF_CLEAR | MEMF_PUBLIC);
970 if (NULL == wblArg)
971 break;
973 d1(kprintf("%s/%s/%ld: wblArg=%08lx\n", __FILE__, __FUNC__, __LINE__, wblArg));
975 wblArg->wbl_Magic = ID_WBLM;
976 wblArg->wbl_IO.wbl_Input.wbli_Flags = GetTagData(SCA_Flags, 0, TagList);
977 wblArg->wbl_IO.wbl_Input.wbli_Priority = GetTagData(SCA_Priority, 0, TagList);
978 wblArg->wbl_IO.wbl_Input.wbli_StackSize = GetTagData(SCA_Stacksize, CurrentPrefs.pref_DefaultStackSize, TagList);
979 wblArg->wbl_IO.wbl_Input.wbli_NumArgs = NumArgs;
981 d1(kprintf("%s/%s/%ld: Flags=%08lx StackSize=%ld\n", __FILE__, __FUNC__, __LINE__, \
982 wblArg->wbl_IO.wbl_Input.wbli_Flags, wblArg->wbl_IO.wbl_Input.wbli_StackSize));
984 for (n=0; n<NumArgs; n++)
986 wblArg->wbl_IO.wbl_Input.wbli_ArgList[n].wa_Lock = ArgArray[n].wa_Lock;
987 wblArg->wbl_IO.wbl_Input.wbli_ArgList[n].wa_Name = AllocCopyString(ArgArray[n].wa_Name);
989 d1(kprintf("%s/%s/%ld: Arg[%ld]: Name=<%s>\n", __FILE__, __FUNC__, __LINE__, \
990 n, wblArg->wbl_IO.wbl_Input.wbli_ArgList[n].wa_Name));
991 debugLock_d1(wblArg->wbl_IO.wbl_Input.wbli_ArgList[n].wa_Lock);
994 WaitDelay = GetTagData(SCA_WaitTimeout, CurrentPrefs.pref_DoWaitDelay, TagList);
996 d1(kprintf("%s/%s/%ld: WaitDelay=%ld\n", __FILE__, __FUNC__, __LINE__, WaitDelay));
998 if (!(wblArg->wbl_IO.wbl_Input.wbli_Flags & SCAF_WBStart_NoIcon))
1000 IconObject = (Object *) GetTagData(SCA_IconObject, (ULONG)NULL, TagList);
1002 d1(KPrintF("%s/%s/%ld: IconObject=%08lx\n", __FILE__, __FUNC__, __LINE__, IconObject));
1004 if (NULL == IconObject)
1006 BPTR oldDir = CurrentDir(wblArg->wbl_IO.wbl_Input.wbli_ArgList[0].wa_Lock);
1008 IconObject = NewIconObjectTags(wblArg->wbl_IO.wbl_Input.wbli_ArgList[0].wa_Name,
1009 TAG_END);
1011 if (IconObject)
1013 GetAttr(IDTA_Stacksize, IconObject, &wblArg->wbl_IO.wbl_Input.wbli_StackSize);
1015 if (!CheckProject(IconObject, &wblArg->wbl_IO.wbl_Input, &cliStart, &RexxStart, &Arg0Locked))
1017 DisplayScreenTitleError(NULL, MSGID_ERROR_NO_DEFAULTTOOL);
1018 break;
1021 d1(KPrintF("%s/%s/%ld: cliStart=%ld RexxStart=%ld\n", __FILE__, __FUNC__, __LINE__, cliStart, RexxStart));
1023 DisposeIconObject(IconObject);
1026 CurrentDir(oldDir);
1028 else
1030 if (!CheckProject(IconObject, &wblArg->wbl_IO.wbl_Input, &cliStart, &RexxStart, &Arg0Locked))
1032 DisplayScreenTitleError(NULL, MSGID_ERROR_NO_DEFAULTTOOL);
1033 break;
1036 GetAttr(IDTA_Stacksize, IconObject, &wblArg->wbl_IO.wbl_Input.wbli_StackSize);
1040 if (wblArg->wbl_IO.wbl_Input.wbli_StackSize < CurrentPrefs.pref_DefaultStackSize)
1041 wblArg->wbl_IO.wbl_Input.wbli_StackSize = CurrentPrefs.pref_DefaultStackSize;
1043 d1(KPrintF("%s/%s/%ld: cliStart=%ld RexxStart=%ld\n", __FILE__, __FUNC__, __LINE__, cliStart, RexxStart));
1045 if (cliStart)
1047 d1(KPrintF("%s/%s/%ld: CliStart\n", __FUNC__, __LINE__));
1049 Success = CLIStart(wblArg->wbl_IO.wbl_Input.wbli_ArgList[0].wa_Lock,
1050 wblArg->wbl_IO.wbl_Input.wbli_ArgList[0].wa_Name,
1051 IconObject,
1052 wblArg->wbl_IO.wbl_Input.wbli_StackSize);
1054 else if (RexxStart)
1056 d1(KPrintF("%s/%s/%ld: RexxStart\n", __FUNC__, __LINE__));
1057 Success = ArexxToolStart(&MainWindowTask->mwt,
1058 wblArg->wbl_IO.wbl_Input.wbli_ArgList[0].wa_Lock,
1059 wblArg->wbl_IO.wbl_Input.wbli_ArgList[0].wa_Name);
1061 else
1063 STATIC_PATCHFUNC(WblTask)
1064 ULONG Flags = wblArg->wbl_IO.wbl_Input.wbli_Flags;
1066 d1(KPrintF("%s/%s/%ld: WBStart\n", __FILE__, __FUNC__, __LINE__));
1068 newProc = CreateNewProcTags(NP_CurrentDir, NULL,
1069 NP_WindowPtr, NULL,
1070 NP_Priority, wblArg->wbl_IO.wbl_Input.wbli_Priority,
1071 NP_Name, (ULONG) "WBL",
1072 NP_Entry, (ULONG) PATCH_NEWFUNC(WblTask),
1073 TAG_END);
1074 if (NULL == newProc)
1075 break;
1077 d1(kprintf("%s/%s/%ld: newProc=%08lx Flags=%08lx\n", __FILE__, __FUNC__, __LINE__, newProc, Flags));
1079 if (Flags & SCAF_WBStart_Wait)
1081 d1(KPrintF("%s/%s/%ld: WaitForReply\n", __FUNC__, __LINE__));
1082 Success = WaitForReply(newProc, wblArg, WaitDelay, ArgArray[0].wa_Name, Arg0Locked);
1083 d1(kprintf("%s/%s/%ld: Success=%ld\n", __FILE__, __FUNC__, __LINE__, Success));
1085 else
1087 PutMsg(&newProc->pr_MsgPort, &wblArg->wbl_Message);
1088 Success = TRUE;
1091 wblArg = NULL; // don't free wblArg
1093 } while (0);
1095 d1(kprintf("%s/%s/%ld: wblArg=%08lx\n", __FILE__, __FUNC__, __LINE__, wblArg));
1097 if (wblArg)
1098 FreeVec(wblArg);
1100 return Success;
1102 LIBFUNC_END
1105 static BOOL WaitForReply(struct Process *newProc, struct WblMessage *wblMsg,
1106 ULONG WaitDelay, CONST_STRPTR ProgramName, BOOL Arg0Locked)
1108 BOOL Success = FALSE;
1109 struct MsgPort *ReplyPort;
1110 T_TIMEREQUEST *TimerIO = NULL;
1111 BOOL DeviceOpened = FALSE;
1112 BOOL TimerPending = FALSE;
1113 struct DoWait *dw;
1115 do {
1116 BOOL Waiting;
1118 ReplyPort = CreateMsgPort();
1120 d1(kprintf("%s/%s/%ld: ReplyPort=%08lx\n", __FILE__, __FUNC__, __LINE__, ReplyPort));
1121 if (NULL == ReplyPort)
1122 break;
1124 TimerIO = (T_TIMEREQUEST *) CreateIORequest(ReplyPort, sizeof(T_TIMEREQUEST));
1126 d1(kprintf("%s/%s/%ld: TimerIO=%08lx\n", __FILE__, __FUNC__, __LINE__, TimerIO));
1127 if (NULL == TimerIO)
1128 break;
1130 if (0 != OpenDevice(TIMERNAME, UNIT_VBLANK, &TimerIO->tr_node, 0L))
1131 break;
1133 d1(kprintf("%s/%s/%ld: OpenDevice OK\n", __LINE__));
1134 DeviceOpened = TRUE;
1136 ScalosObtainSemaphore(&DoWaitSemaphore);
1138 dw = (struct DoWait *) SCA_AllocNode((struct ScalosNodeList *)(APTR) &DoWaitList, sizeof(struct DoWait));
1140 d1(kprintf("%s/%s/%ld: dw=%08lx\n", __FILE__, __FUNC__, __LINE__, dw));
1141 if (NULL == dw)
1143 ScalosReleaseSemaphore(&DoWaitSemaphore);
1144 break;
1147 dw->dwai_msgport = ReplyPort;
1148 dw->dwai_wblmsg = wblMsg;
1150 d1(kprintf("%s/%s/%ld: wblmsg=%08lx\n", __FILE__, __FUNC__, __LINE__, dw->dwai_wblmsg));
1152 ScalosReleaseSemaphore(&DoWaitSemaphore);
1154 wblMsg->wbl_Message.mn_ReplyPort = iInfos.xii_iinfos.ii_MainMsgPort;
1156 Success = TRUE;
1157 d1(kprintf("%s/%s/%ld: msg=%08lx\n", __FILE__, __FUNC__, __LINE__, &wblMsg->wbl_Message));
1158 PutMsg(&newProc->pr_MsgPort, &wblMsg->wbl_Message);
1160 do {
1161 struct Message *msg;
1163 Waiting = FALSE;
1165 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__, WaitDelay));
1167 if (WaitDelay != 0)
1169 TimerIO->tr_time.tv_secs = WaitDelay;
1170 TimerIO->tr_time.tv_micro = 0;
1171 TimerIO->tr_node.io_Command = TR_ADDREQUEST;
1173 TimerPending = TRUE;
1174 BeginIO(&TimerIO->tr_node);
1177 // wait for program completion or timeout
1178 do {
1179 WaitPort(ReplyPort);
1180 msg = GetMsg(ReplyPort);
1181 } while (NULL == msg);
1183 d1(KPrintF("%s/%s/%ld: msg=%08lx\n", __FILE__, __FUNC__, __LINE__, msg));
1185 if (msg == &TimerIO->tr_node.io_Message)
1187 // Program has not yet finished, timeout
1188 TimerPending = FALSE;
1189 WaitIO(&TimerIO->tr_node);
1191 if (UseRequestArgs(NULL, MSGID_DOWAITERRNAME, MSGID_GADGETSNAME,
1193 ProgramName))
1195 Waiting = TRUE;
1198 else
1200 // program has finished
1201 struct DoWaitFinished *dwf = (struct DoWaitFinished *) msg;
1203 d1(kprintf("%s/%s/%ld: program finished dwf=%08lx\n", __FILE__, __FUNC__, __LINE__, dwf));
1205 FreeVec(dwf);
1207 } while (Waiting);
1209 d1(kprintf("%s/%s/%ld: \n", __LINE__));
1211 ScalosObtainSemaphore(&DoWaitSemaphore);
1212 SCA_FreeNode((struct ScalosNodeList *)(APTR) &DoWaitList, &dw->dwai_Node);
1213 ScalosReleaseSemaphore(&DoWaitSemaphore);
1215 d1(kprintf("%s/%s/%ld: \n", __LINE__));
1216 } while (0);
1218 d1(kprintf("%s/%s/%ld: \n", __LINE__));
1220 if (!Success)
1222 ULONG n;
1224 d1(kprintf("%s/%s/%ld: \n", __LINE__));
1226 for (n=0; n<wblMsg->wbl_IO.wbl_Input.wbli_NumArgs; n++)
1228 FreeCopyString(wblMsg->wbl_IO.wbl_Input.wbli_ArgList[n].wa_Name);
1229 wblMsg->wbl_IO.wbl_Input.wbli_ArgList[n].wa_Name = NULL;
1231 if (Arg0Locked)
1232 UnLock(wblMsg->wbl_IO.wbl_Input.wbli_ArgList[0].wa_Lock);
1234 if (TimerIO)
1236 d1(kprintf("%s/%s/%ld: \n", __LINE__));
1238 if (TimerPending)
1240 AbortIO(&TimerIO->tr_node);
1241 WaitIO(&TimerIO->tr_node);
1243 if (DeviceOpened)
1244 CloseDevice(&TimerIO->tr_node);
1246 DeleteIORequest((APTR)TimerIO);
1248 if (ReplyPort)
1249 DeleteMsgPort(ReplyPort);
1251 d1(kprintf("%s/%s/%ld: finished Success=%ld\n", __FILE__, __FUNC__, __LINE__, Success));
1253 return Success;
1257 static BOOL CheckProject(Object *IconObject, struct WblInput *wbli, BOOL *cliStart, BOOL *RexxStart, BOOL *Arg0Locked)
1259 Object *DefaultIconObject = NULL;
1260 STRPTR Path = NULL;
1261 ULONG IconType;
1262 ULONG ul;
1263 STRPTR tt;
1265 tt = NULL;
1266 if (DoMethod(IconObject, IDTM_FindToolType, "TOOLPRI", &tt))
1268 d1(KPrintF("%s/%s/%ld: TOOLPRI=<%s>\n", __FILE__, __FUNC__, __LINE__, tt));
1270 if (DoMethod(IconObject, IDTM_GetToolTypeValue, tt, &ul))
1271 wbli->wbli_Priority = ul;
1274 tt = NULL;
1275 if (DoMethod(IconObject, IDTM_FindToolType, "CLI", &tt))
1276 *cliStart = TRUE;
1278 tt = NULL;
1279 if (DoMethod(IconObject, IDTM_FindToolType, "REXX", &tt))
1280 *RexxStart = TRUE;
1282 GetAttr(IDTA_Type, IconObject, &IconType);
1284 d1(KPrintF("%s/%s/%ld: IconType=%08lx\n", __FILE__, __FUNC__, __LINE__, IconType));
1286 if (WBPROJECT == IconType && !(wbli->wbli_Flags & SCAF_WBStart_NoIconCheck))
1288 ULONG n;
1289 BPTR oldDir;
1290 STRPTR pp;
1291 char ch;
1292 STRPTR DefaultTool = NULL;
1294 GetAttr(IDTA_DefaultTool, IconObject, (APTR) &DefaultTool);
1296 if (NULL == DefaultTool)
1298 // If no default tool is present, try to get a default icon
1299 // and if present, use default tool from the default icon
1300 DefaultIconObject = ReturnDefIconObjTags(wbli->wbli_ArgList[0].wa_Lock,
1301 wbli->wbli_ArgList[0].wa_Name,
1302 TAG_END);
1304 if (NULL != DefaultIconObject)
1305 GetAttr(IDTA_DefaultTool, DefaultIconObject, (APTR) &DefaultTool);
1308 d1(KPrintF("%s/%s/%ld: DefaultTool=%08lx\n", __FILE__, __FUNC__, __LINE__, DefaultTool));
1309 if (NULL == DefaultTool)
1311 STRPTR IconName = (STRPTR) "";
1312 ULONG ReqResult;
1314 GetAttr(DTA_Name, IconObject, (APTR) &IconName);
1316 ReqResult = UseRequestArgs(NULL, MSGID_NODEFAULTTOOL_REQ, MSGID_NODEFAULTTOOL_REQ_GADGETS,
1318 IconName);
1320 d1(KPrintF("%s/%s/%ld: ReqResult=%ld\n", __FILE__, __FUNC__, __LINE__, ReqResult));
1322 switch (ReqResult)
1324 case CHKPRJ_Cancel:
1325 break;
1327 case CHKPRJ_SelectTool:
1328 DefaultTool = Path = ChkPrjRequestFile(&wbli->wbli_ArgList[0]);
1329 break;
1333 if (NULL == DefaultTool)
1335 if (DefaultIconObject)
1336 DisposeIconObject(DefaultIconObject);
1337 return FALSE;
1340 d1(KPrintF("%s/%s/%ld: DefaultTool=<%s>\n", __FILE__, __FUNC__, __LINE__, DefaultTool));
1342 // make room for new first WBarg
1343 for (n=wbli->wbli_NumArgs; n>0; n--)
1345 wbli->wbli_ArgList[n] = wbli->wbli_ArgList[n-1];
1347 wbli->wbli_NumArgs++;
1349 oldDir = CurrentDir(wbli->wbli_ArgList[0].wa_Lock);
1351 pp = PathPart(DefaultTool);
1352 ch = *pp;
1353 *pp = '\0';
1355 d1(KPrintF("%s/%s/%ld: PathPart=<%s>\n", __FILE__, __FUNC__, __LINE__, pp));
1357 wbli->wbli_ArgList[0].wa_Lock = Lock(DefaultTool, ACCESS_READ);
1359 *pp = ch;
1361 wbli->wbli_ArgList[0].wa_Name = AllocCopyString(FilePart(DefaultTool));
1363 d1(KPrintF("%s/%s/%ld: ArgList[0].wa_Name=<%s>\n", __FILE__, __FUNC__, __LINE__, wbli->wbli_ArgList[0].wa_Name));
1364 debugLock_d1(wbli->wbli_ArgList[0].wa_Lock);
1366 wbli->wbli_Flags |= SCAF_WBStart_PathSearch;
1367 *Arg0Locked = TRUE;
1369 d1(KPrintF("%s/%s/%ld: Flags=%08lx\n", __FILE__, __FUNC__, __LINE__, wbli->wbli_Flags));
1371 CurrentDir(oldDir);
1374 if (DefaultIconObject)
1375 DisposeIconObject(DefaultIconObject);
1376 if (Path)
1377 FreePathBuffer(Path);
1379 return TRUE;
1383 // SCA_MakeScalosClass() implementation
1384 LIBFUNC_P5(struct ScalosClass *, sca_MakeScalosClass,
1385 A0, CONST_STRPTR, ClassName,
1386 A1, CONST_STRPTR, SuperClassName,
1387 D0, UWORD, InstSize,
1388 A2, APTR, DispFunc,
1389 A6, struct ScalosBase *, ScalosBase)
1391 struct ScalosClass *NewScalosClass = NULL;
1392 Class *NewClass = NULL;
1393 ScalosObtainSemaphore(&ClassListSemaphore);
1395 (void)ScalosBase;
1397 d1(kprintf("%s/%s/%ld: ClassName=<%s> SuperClassName=<%s> InstSize=%lu DispFunc=%08lx\n", \
1398 __FILE__, __FUNC__, __LINE__, ClassName, SuperClassName, InstSize, DispFunc));
1400 do {
1401 struct ScalosClass *ClassList = NULL;
1402 struct ScalosClass *SuperClass;
1403 size_t SuperClassLen = strlen(SuperClassName);
1405 if (SuperClassLen < 4 || 0 != strcmp(SuperClassName + SuperClassLen - 4, ".sca"))
1407 // All classes whose names don't end with ".sca" are inherited from
1408 // standard BOOPSI classes instead of other Scalos classes!
1409 d1(KPrintF("%s/%s/%ld: inherit from BOOPSI: SuperClassName=<%s>\n", __FILE__, __FUNC__, __LINE__, SuperClassName));
1410 NewClass = MakeClass(NULL, (STRPTR) SuperClassName, NULL, InstSize, 0);
1412 else
1414 // try to find specified superclass (upper/lower case does matter!)
1415 d1(KPrintF("%s/%s/%ld: inherit from Scalos: SuperClassName=<%s>\n", __FILE__, __FUNC__, __LINE__, SuperClassName));
1416 SuperClass = FindScalosClass(SuperClassName);
1418 d1(kprintf("%s/%s/%ld: SuperClass=%08lx\n", __FILE__, __FUNC__, __LINE__, SuperClass));
1419 if (NULL == SuperClass)
1420 break;
1422 NewClass = MakeClass(NULL, NULL, SuperClass->sccl_class, InstSize, 0);
1424 if (NULL == NewClass)
1425 break;
1427 d1(kprintf("%s/%s/%ld: NewClass=%08lx\n", __FILE__, __FUNC__, __LINE__, NewClass));
1429 NewScalosClass = (struct ScalosClass *) SCA_AllocStdNode((struct ScalosNodeList *)(APTR) &ClassList, NTYP_PluginClass);
1430 if (NULL == NewScalosClass)
1431 break;
1433 #if defined(__MORPHOS__)
1434 NewScalosClass->sccl_EmulEntry.Trap = TRAP_LIB;
1435 NewScalosClass->sccl_EmulEntry.Func = DispFunc;
1436 NewClass->cl_Dispatcher.h_Entry = (APTR) &NewScalosClass->sccl_EmulEntry;
1438 #else
1439 NewClass->cl_Dispatcher.h_Entry = (HOOKFUNC) DispFunc;
1441 #endif /* __MORPHOS__ */
1443 d1(kprintf("%s/%s/%ld: NewScalosClass=%08lx\n", __FILE__, __FUNC__, __LINE__, NewScalosClass));
1445 NewClass->cl_UserData = (ULONG) NewScalosClass;
1446 NewScalosClass->sccl_class = NewClass;
1447 NewScalosClass->sccl_name = (STRPTR) ClassName;
1449 ScalosClassList->sccl_Node.mln_Pred = &NewScalosClass->sccl_Node;
1450 NewScalosClass->sccl_Node.mln_Succ = &ScalosClassList->sccl_Node;
1451 ScalosClassList = NewScalosClass;
1453 NewClass = NULL; // don't free NewClass
1454 } while (0);
1456 ScalosReleaseSemaphore(&ClassListSemaphore);
1458 if (NewClass)
1460 FreeClass(NewClass);
1463 return NewScalosClass;
1465 LIBFUNC_END
1468 // SCA_FreeScalosClass() implementation
1469 LIBFUNC_P2(BOOL, sca_FreeScalosClass,
1470 A0, struct ScalosClass *, sccl,
1471 A6, struct ScalosBase *, ScalosBase)
1473 BOOL Success = FALSE;
1475 (void)ScalosBase;
1477 ScalosObtainSemaphore(&ClassListSemaphore);
1479 if (sccl)
1481 FreeClass(sccl->sccl_class);
1482 sccl->sccl_class = NULL;
1484 SCA_FreeNode((struct ScalosNodeList *)(APTR) &ScalosClassList, &sccl->sccl_Node);
1486 Success = TRUE;
1489 ScalosReleaseSemaphore(&ClassListSemaphore);
1491 return Success;
1493 LIBFUNC_END
1496 //SCA_NewScalosObject()
1497 LIBFUNC_P3(Object *, sca_NewScalosObject,
1498 A0, CONST_STRPTR, ClassName,
1499 A1, struct TagItem *, TagList,
1500 A6, struct ScalosBase *, ScalosBase)
1502 struct ScalosClass *cl;
1503 Object *o = NULL;
1505 (void) ScalosBase;
1507 d1(KPrintF("%s/%s/%ld: \n", __LINE__));
1509 ScalosObtainSemaphoreShared(&ClassListSemaphore);
1511 d1(KPrintF("%s/%s/%ld: \n", __LINE__));
1513 // try to find specified superclass (upper/lower case does matter!)
1514 cl = FindScalosClass(ClassName);
1515 if (cl)
1517 d1(KPrintF("%s/%s/%ld: cl=%08lx sccl_class=%08lx dispatcher=%08lx\n", \
1518 __FILE__, __FUNC__, __LINE__, cl, cl->sccl_class, cl, &cl->sccl_class->cl_Dispatcher));
1519 d1(KPrintF("%s/%s/%ld: dispatcher: entry=%08lx subentry=%08lx data=%08lx\n", \
1520 __FILE__, __FUNC__, __LINE__, cl->sccl_class->cl_Dispatcher.h_Entry, \
1521 cl->sccl_class->cl_Dispatcher.h_SubEntry, \
1522 cl->sccl_class->cl_Dispatcher.h_Data));
1524 o = NewObjectA(cl->sccl_class, NULL, TagList);
1527 d1(KPrintF("%s/%s/%ld: \n", __LINE__));
1529 ScalosReleaseSemaphore(&ClassListSemaphore);
1531 d1(KPrintF("%s/%s/%ld: \n", __LINE__));
1533 return o;
1535 LIBFUNC_END
1538 //SCA_DisposeScalosObject()
1539 LIBFUNC_P2(void, sca_DisposeScalosObject,
1540 A0, Object *, o,
1541 A6, struct ScalosBase *, ScalosBase)
1543 (void) ScalosBase;
1545 DisposeObject(o);
1547 LIBFUNC_END
1550 static struct ScalosClass *FindScalosClass(CONST_STRPTR ClassName)
1552 struct ScalosClass *cl;
1554 d1(kprintf("%s/%s/%ld: ClassName=<%s>\n", __FILE__, __FUNC__, __LINE__, ClassName));
1556 // try to find specified superclass (upper/lower case does matter!)
1557 for (cl=ScalosClassList; cl; cl = (struct ScalosClass *) cl->sccl_Node.mln_Succ)
1559 d1(kprintf("%s/%s/%ld: cl=%08lx <%s> sccl_class=%08lx dispatcher=%08lx\n", \
1560 __FILE__, __FUNC__, __LINE__, cl, cl->sccl_name, cl->sccl_class, cl, &cl->sccl_class->cl_Dispatcher));
1562 if (0 == strcmp(cl->sccl_name, ClassName))
1564 d1(kprintf("%s/%s/%ld: dispatcher: entry=%08lx subentry=%08lx data=%08lx\n", \
1565 __FILE__, __FUNC__, __LINE__, cl->sccl_class->cl_Dispatcher.h_Entry, \
1566 cl->sccl_class->cl_Dispatcher.h_SubEntry, \
1567 cl->sccl_class->cl_Dispatcher.h_Data));
1569 return cl;
1573 d1(kprintf("%s/%s/%ld: return NULL\n", __LINE__));
1575 return NULL;
1579 // SCA_RemoveAppObject()
1580 LIBFUNC_P2(BOOL, sca_RemoveAppObject,
1581 A0, struct AppObject *, appObj,
1582 A6, struct ScalosBase *, ScalosBase)
1584 BOOL Success = TRUE;
1585 struct ScaWindowStruct *ws = iInfos.xii_iinfos.ii_AppWindowStruct;
1586 struct internalScaWindowTask *iwt;
1588 (void) ScalosBase;
1590 if (NULL == ws)
1591 return FALSE;
1593 iwt = (struct internalScaWindowTask *) ws->ws_WindowTask;
1595 ScalosObtainSemaphore(iwt->iwt_AppListSemaphore);
1597 switch (appObj->appo_type)
1599 case APPTYPE_AppIcon:
1600 Success = RemoveAppIcon(iwt, appObj);
1601 break;
1602 case APPTYPE_AppWindow:
1603 Success = RemoveAppWindow(iwt, appObj);
1604 break;
1605 case APPTYPE_AppMenuItem:
1606 Success = RemoveAppMenuItem(iwt, appObj);
1607 break;
1610 ScalosReleaseSemaphore(iwt->iwt_AppListSemaphore);
1612 return Success;
1614 LIBFUNC_END
1617 static BOOL RemoveAppIcon(struct internalScaWindowTask *iwt, struct AppObject *appObj)
1619 struct ScaIconNode *in, *inNext;
1620 struct ScaIconNode *iconList = NULL;
1621 struct AppObject *appo;
1622 BOOL Found = FALSE;
1624 d1(kprintf("%s/%s/%ld: START iconList=%08lx\n", __FILE__, __FUNC__, __LINE__, iconList));
1626 ScalosLockIconListExclusive(iwt);
1628 for (in=iwt->iwt_WindowTask.wt_IconList; !Found && in; in = inNext)
1630 inNext = (struct ScaIconNode *) in->in_Node.mln_Succ;
1632 if (in->in_Icon == appObj->appo_object.appoo_IconObject)
1634 SCA_MoveIconNode(&iwt->iwt_WindowTask.wt_IconList, &iconList, in);
1635 Found = TRUE;
1638 for (in=iwt->iwt_WindowTask.wt_LateIconList; !Found && in; in = inNext)
1640 inNext = (struct ScaIconNode *) in->in_Node.mln_Succ;
1642 if (in->in_Icon == appObj->appo_object.appoo_IconObject)
1644 SCA_MoveIconNode(&iwt->iwt_WindowTask.wt_LateIconList, &iconList, in);
1645 Found = TRUE;
1649 d1(kprintf("%s/%s/%ld: iconList=%08lx\n", __FILE__, __FUNC__, __LINE__, iconList));
1651 if (iconList)
1653 d1(kprintf("%s/%s/%ld: iconList=%08lx\n", __FILE__, __FUNC__, __LINE__, iconList));
1654 RemoveIcons(iwt, &iconList);
1656 for (in=iconList; in; in = (struct ScaIconNode *) in->in_Node.mln_Succ)
1658 // appo_object.appoo_IconObject will be freed later
1659 d1(kprintf("%s/%s/%ld: in=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, in, GetIconName(in)));
1660 in->in_Icon = NULL;
1663 FreeIconList(iwt, &iconList);
1666 ScalosUnLockIconList(iwt);
1668 // ensure appObj is really member of iwt_AppList
1669 for (appo = iwt->iwt_AppList; appo; appo = (struct AppObject *) appo->appo_Node.mln_Succ)
1671 if (appo == appObj)
1673 SCA_FreeNode((struct ScalosNodeList *) &iwt->iwt_AppList, &appObj->appo_Node);
1674 break;
1678 d1(kprintf("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__));
1680 return TRUE;
1684 static BOOL RemoveAppWindow(struct internalScaWindowTask *iwt, struct AppObject *appObj)
1686 struct AppObject *appo;
1688 // ensure appObj is really member of iwt_AppList
1689 for (appo = iwt->iwt_AppList; appo; appo = (struct AppObject *) appo->appo_Node.mln_Succ)
1691 if (appo == appObj)
1693 SCA_FreeNode((struct ScalosNodeList *) &iwt->iwt_AppList, &appObj->appo_Node);
1694 break;
1698 return TRUE;
1702 static BOOL RemoveAppMenuItem(struct internalScaWindowTask *iwt, struct AppObject *appObj)
1704 BOOL Success;
1705 struct AppObject *appo;
1707 Success = AppMenu_RemoveItem(appObj->appo_object.appoo_MenuInfo);
1709 d1(kprintf("%s/%s/%ld: \n", __LINE__));
1711 if (Success)
1712 AppMenu_ResetMenu();
1714 // ensure appObj is really member of iwt_AppList
1715 for (appo = iwt->iwt_AppList; appo; appo = (struct AppObject *) appo->appo_Node.mln_Succ)
1717 if (appo == appObj)
1719 SCA_FreeNode((struct ScalosNodeList *) &iwt->iwt_AppList, &appObj->appo_Node);
1720 break;
1724 return Success;
1728 // SCA_ScreenTitleMsg( Format, Args )
1729 // A0 A1
1731 // void SCA_ScreenTitleMsg ( CONST_STRPTR Format, APTR Args);
1732 LIBFUNC_P3(void, sca_ScreenTitleMsg,
1733 A0, CONST_STRPTR, Format,
1734 A1, APTR, Args,
1735 A6, struct ScalosBase *, ScalosBase)
1737 static BOOL fCustomTitle = FALSE;
1739 (void) ScalosBase;
1741 d1(kprintf("%s/%s/%ld: Format=%08lx\n", __FILE__, __FUNC__, __LINE__, Format));
1743 if (NULL == Format)
1745 // Restore standard screen title
1746 if (fCustomTitle)
1748 fCustomTitle = FALSE;
1750 ScreenTitleBuffer = (STRPTR) DoMethod(ScreenTitleObject, SCCM_Title_Generate);
1752 NewScreenTitle(ScreenTitleBuffer);
1755 else if (((CONST_STRPTR) ~0) == Format)
1757 // to recover the last non-standard title
1758 fCustomTitle = TRUE;
1760 NewScreenTitle(LastScreenTitleBuffer);
1762 else
1764 fCustomTitle = TRUE;
1766 d1(kprintf("%s/%s/%ld: Format=<%s>\n", __FILE__, __FUNC__, __LINE__, Format));
1768 ScaFormatStringArgs(ScreenTitleBuffer, INT_MAX, Format, Args);
1769 strcpy(LastScreenTitleBuffer, ScreenTitleBuffer);
1771 NewScreenTitle(ScreenTitleBuffer);
1774 d1(kprintf("%s/%s/%ld: ScreenTitleBuffer=<%s> LastScreenTitleBuffer=<%s>\n", \
1775 __FILE__, __FUNC__, __LINE__, ScreenTitleBuffer, LastScreenTitleBuffer));
1777 LIBFUNC_END
1780 static void NewScreenTitle(CONST_STRPTR NewTitle)
1782 if (SCA_LockWindowList(SCA_LockWindowList_AttemptShared))
1784 struct ScaWindowStruct *ws;
1786 for (ws=winlist.wl_WindowStruct; ws; ws = (struct ScaWindowStruct *) ws->ws_Node.mln_Succ)
1788 if (ws->ws_Window && !(ws->ws_Flags & WSV_FlagF_TaskSleeps))
1790 LockedSetWindowTitles(ws->ws_Window, (CONST_STRPTR) ~0, NewTitle);
1794 SCA_UnLockWindowList();
1799 // AppObject = SCA_NewAddAppWindow (ID, UserData, Window, MessagePort, Taglist)
1800 // D0 D0 D1 A0 A1 A2
1802 // struct AppObject *SCA_NewAddAppWindow( ULONG ID, ULONG UserData,
1803 // struct Window *, struct MsgPort *,
1804 // struct TagItem *Taglist);
1805 LIBFUNC_P6(struct AppObject *, sca_NewAddAppWindow,
1806 D0, ULONG, ID,
1807 D1, ULONG, UserData,
1808 A0, struct Window *, win,
1809 A1, struct MsgPort *, msgPort,
1810 A2, struct TagItem *, TagList,
1811 A6, struct ScalosBase *, ScalosBase)
1813 struct internalScaWindowTask *iwt = (struct internalScaWindowTask *) iInfos.xii_iinfos.ii_AppWindowStruct->ws_WindowTask;
1814 struct AppObject *appo;
1816 (void) ScalosBase;
1818 ScalosObtainSemaphore(iwt->iwt_AppListSemaphore);
1820 do {
1821 appo = (struct AppObject *) SCA_AllocStdNode((struct ScalosNodeList *) &iwt->iwt_AppList, NTYP_AppObject);
1822 if (NULL == appo)
1823 break;
1825 appo->appo_Kennung = ID_SC;
1826 appo->appo_type = APPTYPE_AppWindow;
1827 appo->appo_id = ID;
1828 appo->appo_userdata = UserData;
1829 appo->appo_msgport = msgPort;
1830 appo->appo_object.appoo_Window = win;
1831 appo->appo_TagList = CloneTagItems(TagList);
1832 } while (0);
1834 ScalosReleaseSemaphore(iwt->iwt_AppListSemaphore);
1836 d1(KPrintF("%s/%s/%ld: appo=%08lx\n", __FILE__, __FUNC__, __LINE__, appo));
1838 return appo;
1840 LIBFUNC_END
1843 // Node = SCA_AllocNode (NodeList, Size)
1844 // D0 A0 D0
1846 // struct MinNode *SCA_AllocNode (struct ScalosNodeList *, ULONG Size);
1847 LIBFUNC_P3(struct MinNode *, sca_AllocNode,
1848 A0, struct ScalosNodeList *, nodeList,
1849 D0, ULONG, ExtraSize,
1850 A6, struct ScalosBase *, ScalosBase)
1852 struct MinNode *newNode;
1854 (void) ScalosBase;
1856 newNode = ScalosAllocNode(sizeof(struct MinNode) + ExtraSize);
1858 if (newNode)
1860 if (nodeList->snl_MinNode)
1862 // append new node at end of list
1863 while (nodeList->snl_MinNode->mln_Succ)
1864 nodeList = (struct ScalosNodeList *) &nodeList->snl_MinNode->mln_Succ;
1866 newNode->mln_Pred = nodeList->snl_MinNode;
1867 nodeList->snl_MinNode->mln_Succ = newNode;
1869 else
1871 nodeList->snl_MinNode = newNode;
1875 return newNode;
1877 LIBFUNC_END
1880 // SCA_FreeNode (NodeList, Node)
1881 // A0 A1
1883 // void SCA_FreeNode (struct ScalosNodeList *, struct MinNode *);
1884 LIBFUNC_P3(void, sca_FreeNode,
1885 A0, struct ScalosNodeList *, nodeList,
1886 A1, struct MinNode *, oldNode,
1887 A6, struct ScalosBase *, ScalosBase)
1889 (void) ScalosBase;
1891 if (oldNode && nodeList->snl_MinNode)
1893 if (oldNode->mln_Succ)
1894 oldNode->mln_Succ->mln_Pred = oldNode->mln_Pred;
1895 if (oldNode->mln_Pred)
1896 oldNode->mln_Pred->mln_Succ = oldNode->mln_Succ;
1897 else
1898 nodeList->snl_MinNode = oldNode->mln_Succ;
1900 ScalosFreeNode(oldNode);
1903 LIBFUNC_END
1906 // SCA_FreeAllNodes (NodeList)
1907 // A0
1909 // void SCA_FreeAllNodes (struct ScalosNodeList *);
1910 LIBFUNC_P2(void, sca_FreeAllNodes,
1911 A0, struct ScalosNodeList *, nodeList,
1912 A6, struct ScalosBase *, ScalosBase)
1914 struct MinNode *oldNode = nodeList->snl_MinNode;
1916 (void) ScalosBase;
1918 while (oldNode)
1920 struct MinNode *nextNode = oldNode->mln_Succ;
1922 ScalosFreeNode(oldNode);
1923 oldNode = nextNode;
1926 nodeList->snl_MinNode = NULL;
1928 LIBFUNC_END
1931 // Node = SCA_AllocStdNode (NodeList, NodeType)
1932 // D0 A0 D0
1934 // struct MinNode *SCA_AllocStdNode (struct ScalosNodeList *, ULONG NodeType);
1935 LIBFUNC_P3(struct MinNode *, sca_AllocStdNode,
1936 A0, struct ScalosNodeList *, nodeList,
1937 D0, ULONG, NodeType,
1938 A6, struct ScalosBase *, ScalosBase)
1940 static const UWORD NodeSizeTable[] =
1942 sizeof(struct ScaIconNode) - sizeof(struct MinNode),
1943 sizeof(struct ScaWindowStruct) - sizeof(struct MinNode),
1944 sizeof(struct DragNode) - sizeof(struct MinNode),
1945 sizeof(struct PatternNode) - sizeof(struct MinNode),
1946 sizeof(struct ScalosArg) - sizeof(struct MinNode),
1947 sizeof(struct ScaDeviceIcon) - sizeof(struct MinNode),
1948 sizeof(struct ScalosMenuTree) - sizeof(struct MinNode),
1949 sizeof(struct ScalosMenuTree) - sizeof(struct MinNode),
1950 sizeof(struct AppObject) - sizeof(struct MinNode),
1951 sizeof(struct MenuInfo) - sizeof(struct MinNode),
1952 sizeof(struct ScalosClass) - sizeof(struct MinNode),
1953 sizeof(struct PluginClass) - sizeof(struct MinNode),
1956 (void)ScalosBase;
1958 if (NodeType >= sizeof(NodeSizeTable)/sizeof(NodeSizeTable[0]))
1959 return NULL;
1961 return SCA_AllocNode(nodeList, NodeSizeTable[NodeType]);
1963 LIBFUNC_END
1966 // ScalosMessage SCA_AllocMessage( messagetype, additional_size)
1967 // D0 D0 D1
1969 // struct ScalosMessage *SCA_AllocMessage ( ULONG messagetype, UWORD additional_size );
1970 LIBFUNC_P3(struct ScalosMessage *, sca_AllocMessage,
1971 D0, ULONG, MessageType,
1972 D1, UWORD, AdditionalSize,
1973 A6, struct ScalosBase *, ScalosBase)
1975 static const UWORD MsgSizeTable[] =
1977 0, //0 no message
1978 sizeof(struct SM_DropProc), //1 MTYP_DropProc
1979 sizeof(struct SM_CloseWindow), //2 MTYP_CloseWindow
1980 sizeof(struct SM_StartWindow), //3 MTYP_StartWindow
1981 sizeof(struct SM_Timer), //4 MTYP_Timer
1982 sizeof(struct SM_Requester), //5 MTYP_Requester
1983 sizeof(struct SM_NewPattern), //6 MTYP_NewPattern
1984 sizeof(struct SM_Sleep), //7 MTYP_Sleep
1985 sizeof(struct SM_Wakeup), //8 MTYP_Wakeup
1986 sizeof(struct SM_AsyncRoutine), //9 MTYP_AsyncRoutine
1987 sizeof(struct SM_RunProcess), //10 MTYP_RunProcess
1988 sizeof(struct SM_AppSleep), //11 MTYP_AppSleep
1989 sizeof(struct SM_AppWakeup), //12 MTYP_AppWakeup
1990 sizeof(struct SM_Redraw), //13 MTYP_Redraw
1991 sizeof(struct SM_Update), //14 MTYP_Update
1992 sizeof(struct SM_UpdateIcon), //15 MTYP_UpdateIcon
1993 sizeof(struct SM_AddIcon), //16 MTYP_AddIcon
1994 sizeof(struct SM_RemIcon), //17 MTYP_RemIcon
1995 sizeof(struct SM_ARexxRoutine), //18 MTYP_ARexxRoutine
1996 sizeof(struct SM_Iconify), //19 MTYP_Iconify
1997 sizeof(struct SM_UnIconify), //20 MTYP_UnIconify
1998 sizeof(struct SM_AsyncBackFill), //21 MTYP_AsyncBackFill
1999 sizeof(struct SM_ShowTitle), //22 MTYP_ShowTitle
2000 sizeof(struct SM_RunMenuCmd), //23 MTYP_RunMenuCmd
2001 sizeof(struct SM_ShowPopupMenu), //24 MTYP_ShowPopupMenu
2002 sizeof(struct SM_ShowStatusBar), //25 MTYP_ShowStatusBar
2003 sizeof(struct SM_RedrawIcon), //26 MTYP_RedrawIcon
2004 sizeof(struct SM_DoPopupMenu), //27 MTYP_DoPopupMenu
2005 sizeof(struct SM_RedrawIconObj), //28 MTYP_RedrawIconObj
2006 sizeof(struct SM_NewPreferences), //29 MTYP_NewPreferences
2007 sizeof(struct SM_DeltaMove), //30 MTYP_DeltaMove
2008 sizeof(struct SM_SetThumbnailImage_Remapped), //31 MTYP_SetThumbnailImage_Remapped
2009 sizeof(struct SM_SetThumbnailImage_ARGB), //32 MTYP_SetThumbnailImage_ARGB
2010 sizeof(struct SM_NewWindowPath), //33 MTYP_NewWindowPath
2011 sizeof(struct SM_PrefsChanged), //34 MTYP_PrefsChanged
2012 sizeof(struct SM_StartChildProcess), //35 MTYP_StartChildProcess
2013 sizeof(struct SM_RootEvent), //36 MTYP_RootEvent
2014 sizeof(struct SM_ShowControlBar), //37 MTYP_ShowStatusBar
2016 struct ScalosMessage *newMsg;
2017 size_t Length;
2019 (void) ScalosBase;
2021 if (MessageType < MTYP_DropProc || MessageType >= Sizeof(MsgSizeTable))
2022 return NULL;
2024 Length = MsgSizeTable[MessageType] + AdditionalSize;
2026 newMsg = ScalosAllocMessage(Length);
2028 if (newMsg)
2030 memset(newMsg, 0, Length);
2032 newMsg->sm_Message.mn_Length = Length;
2033 newMsg->sm_Signature = ID_IMSG;
2034 newMsg->sm_MessageType = MessageType;
2037 return newMsg;
2039 LIBFUNC_END
2042 // SCA_FreeMessage( message )
2043 // A1
2045 // void SCA_FreeMessage ( struct ScalosMessage *);
2046 LIBFUNC_P2(void, sca_FreeMessage,
2047 A1, struct ScalosMessage *, msg,
2048 A6, struct ScalosBase *, ScalosBase)
2050 (void) ScalosBase;
2052 if (msg && ID_IMSG == msg->sm_Signature)
2054 d1(if (MTYP_AsyncBackFill == msg->sm_MessageType) \
2055 KPrintF("%s/%s/%ld: msg=%08lx ReplyPort=%08lx MsgType=%08lx\n", \
2056 __FILE__, __FUNC__, __LINE__, msg, msg->sm_Message.mn_ReplyPort, msg->sm_MessageType));
2057 ScalosFreeMessage(msg);
2060 LIBFUNC_END
2063 // SCA_UpdateIcon( WindowType, SCA_UpdateIcon, UpdateIcon_Size )
2064 // D0 A0 D1
2066 // void SCA_UpdateIcon ( UBYTE WindowType, struct ScaUpdateIcon_IW *,
2067 // ULONG ui_SIZE );
2068 LIBFUNC_P4(void, sca_UpdateIcon,
2069 D0, UBYTE, WindowType,
2070 A0, struct ScaUpdateIcon_IW *, uiiw,
2071 D1, ULONG, ui_SIZE,
2072 A6, struct ScalosBase *, ScalosBase)
2074 (void) ui_SIZE;
2075 (void) ScalosBase;
2077 d1(KPrintF("%s/%s/%ld: START ui_iw_Name=<%s>\n", __FILE__, __FUNC__, __LINE__, uiiw->ui_iw_Name));
2078 debugLock_d1(uiiw->ui_iw_Lock);
2080 if (SCA_LockWindowList(SCA_LockWindowList_AttemptShared))
2082 struct ScaWindowStruct *ws;
2084 d1(KPrintF("%s/%s/%ld: SCA_LockWindowList success!\n", __FILE__, __FUNC__, __LINE__));
2086 for (ws=winlist.wl_WindowStruct; ws; ws = (struct ScaWindowStruct *) ws->ws_Node.mln_Succ)
2088 if (((WSV_Type_IconWindow == WindowType && WSV_Type_DeviceWindow == ws->ws_WindowType)
2089 || ws->ws_WindowType == WindowType)
2090 && ws->ws_Lock
2091 && LOCK_SAME == SameLock(ws->ws_Lock, uiiw->ui_iw_Lock))
2093 struct SM_UpdateIcon *smui;
2095 do {
2096 smui = (struct SM_UpdateIcon *) SCA_AllocMessage(MTYP_UpdateIcon, 0);
2097 d1(KPrintF("%s/%s/%ld: smui=%08lx\n", __FILE__, __FUNC__, __LINE__, smui));
2098 if (NULL == smui)
2099 break;
2101 smui->smui_DirLock = DupLock(uiiw->ui_iw_Lock);
2102 if ((BPTR)NULL == smui->smui_DirLock)
2103 break;
2105 if (ui_SIZE >= offsetof(struct ScaUpdateIcon_IW, ui_IconType) + sizeof(uiiw->ui_IconType))
2106 smui->smui_IconType = uiiw->ui_IconType;
2107 else
2108 smui->smui_IconType = ICONTYPE_NONE;
2110 smui->smui_IconName = AllocVec(1 + strlen(uiiw->ui_iw_Name), MEMF_PUBLIC);
2111 if (NULL == smui->smui_IconName)
2112 break;
2114 strcpy((STRPTR) smui->smui_IconName, uiiw->ui_iw_Name);
2116 debugLock_d1(smui->smui_DirLock);
2117 d1(KPrintF("%s/%s/%ld: smui_IconName=<%s>\n", __FILE__, __FUNC__, __LINE__, smui->smui_IconName));
2119 PutMsg(ws->ws_MessagePort, &smui->ScalosMessage.sm_Message);
2120 smui = NULL;
2121 } while (0);
2123 if (smui)
2125 if (smui->smui_IconName)
2126 FreeCopyString((STRPTR) smui->smui_IconName);
2127 if (smui->smui_DirLock)
2128 UnLock(smui->smui_DirLock);
2129 SCA_FreeMessage(&smui->ScalosMessage);
2135 SCA_UnLockWindowList();
2138 d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__));
2140 LIBFUNC_END
2143 // number = SCA_FreeWBArgs( Buffer, Number, Flags )
2144 // A0 D0 D1
2146 // void SCA_FreeWBArgs ( struct WBArg *Buffer, ULONG Number,
2147 // ULONG Flags);
2148 LIBFUNC_P4(void, sca_FreeWBArgs,
2149 A0, struct WBArg *, wbArg,
2150 D0, ULONG, NumArgs,
2151 D1, ULONG, Flags,
2152 A6, struct ScalosBase *, ScalosBase)
2154 (void) ScalosBase;
2156 d1(KPrintF("%s/%s/%ld: START NumArgs=%lu wbArg=%08lx\n", __FILE__, __FUNC__, __LINE__, NumArgs, wbArg));
2158 while (NumArgs >= 1)
2160 d1(KPrintF("%s/%s/%ld: wa_Lock=%08lx wa_Name=%08lx\n", __FILE__, __FUNC__, __LINE__, wbArg->wa_Lock, wbArg->wa_Name));
2162 if ((Flags & SCAF_FreeLocks) && wbArg->wa_Lock)
2164 UnLock(wbArg->wa_Lock);
2165 wbArg->wa_Lock = (BPTR)NULL;
2167 if ((Flags & SCAF_FreeNames) && wbArg->wa_Name)
2169 FreeCopyString(wbArg->wa_Name);
2170 wbArg->wa_Name = NULL;
2173 NumArgs--;
2174 wbArg++;
2176 d1(KPrintF("%s/%s/%ld: END", __LINE__));
2178 LIBFUNC_END
2181 // number = SCA_MakeWBArgs( Buffer, Iconnode, ArgsSize )
2182 // A0 A1 D0
2184 // ULONG SCA_MakeWBArgs ( struct WBArg *Buffer,
2185 // struct ScaIconNode *Iconnode, ULONG ArgsSize);
2186 LIBFUNC_P4(ULONG, sca_MakeWBArgs,
2187 A0, struct WBArg *, wbArg,
2188 A1, struct ScaIconNode *, in,
2189 D0, ULONG, MaxArg,
2190 A6, struct ScalosBase *, ScalosBase)
2192 struct ScaWindowStruct *ws;
2193 ULONG ArgCount = 0;
2194 struct WBArg *pWBArg = wbArg;
2196 (void) ScalosBase;
2198 d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__));
2200 SCA_LockWindowList(SCA_LockWindowList_Shared);
2202 for (ws=winlist.wl_WindowStruct; ws; ws = (struct ScaWindowStruct *) ws->ws_Node.mln_Succ)
2204 if (!(ws->ws_Flags & WSV_FlagF_TaskSleeps))
2206 ArgCount = MakeWindowWBArgs(ws, in, &pWBArg, ArgCount, MaxArg);
2210 d1(KPrintF("%s/%s/%ld: ArgCount=%lu\n", __FILE__, __FUNC__, __LINE__, ArgCount));
2212 if (NULL == in && 0 == ArgCount)
2214 for (ws=winlist.wl_WindowStruct; (ArgCount < MaxArg) && ws;
2215 ws = (struct ScaWindowStruct *) ws->ws_Node.mln_Succ)
2217 if (!(ws->ws_Flags & WSV_FlagF_TaskSleeps)
2218 && ws->ws_Window
2219 && ws != iInfos.xii_iinfos.ii_MainWindowStruct
2220 && (ws->ws_Window->Flags & WFLG_WINDOWACTIVE))
2222 ArgCount += DoMethod(ws->ws_WindowTask->mt_MainObject, SCCM_IconWin_MakeWBArg, NULL, wbArg);
2227 SCA_UnLockWindowList();
2229 d1(KPrintF("%s/%s/%ld: END ArgCount=%lu\n", __FILE__, __FUNC__, __LINE__, ArgCount));
2231 return ArgCount;
2233 LIBFUNC_END
2236 static ULONG MakeWindowWBArgs(struct ScaWindowStruct *ws,
2237 struct ScaIconNode *inExclude,
2238 struct WBArg **wbArg, ULONG ArgCount, ULONG MaxArg)
2240 struct internalScaWindowTask *iwt = (struct internalScaWindowTask *) ws->ws_WindowTask;
2241 struct ScaIconNode *in;
2243 ScalosLockIconListShared(iwt);
2245 for (in = iwt->iwt_WindowTask.wt_IconList; (ArgCount < MaxArg) && in;
2246 in = (struct ScaIconNode *) in->in_Node.mln_Succ)
2248 struct ExtGadget *gg = (struct ExtGadget *) in->in_Icon;
2250 if (in != inExclude && (gg->Flags & GFLG_SELECTED))
2252 ArgCount += DoMethod(iwt->iwt_WindowTask.mt_MainObject, SCCM_IconWin_MakeWBArg, in, *wbArg);
2253 (*wbArg)++;
2257 ScalosUnLockIconList(iwt);
2259 return ArgCount;
2262 // Windowlist SCA_LockWindowList ( accessmode )
2263 // D0 D0
2264 LIBFUNC_P2(struct ScaWindowList *, sca_LockWindowList,
2265 D0, LONG, accessmode,
2266 A6, struct ScalosBase *, ScalosBase)
2268 struct ScaWindowList *Result = &winlist;
2270 (void) ScalosBase;
2272 switch (accessmode)
2274 case SCA_LockWindowList_Shared:
2275 ScalosObtainSemaphoreShared(&WinListSemaphore);
2276 break;
2277 case SCA_LockWindowList_Exclusiv:
2278 ScalosObtainSemaphore(&WinListSemaphore);
2279 break;
2280 case SCA_LockWindowList_AttemptShared:
2281 if (!ScalosAttemptSemaphoreShared(&WinListSemaphore))
2282 Result = NULL;
2283 break;
2284 case SCA_LockWindowList_AttemptExclusive:
2285 if (!ScalosAttemptSemaphore(&WinListSemaphore))
2286 Result = NULL;
2287 break;
2288 default:
2289 break;
2292 return Result;
2294 LIBFUNC_END
2297 // void SCA_UnLockWindowList ( void );
2298 LIBFUNC_P1(void, sca_UnLockWindowList,
2299 A6, struct ScalosBase *, ScalosBase)
2301 (void) ScalosBase;
2303 ScalosReleaseSemaphore(&WinListSemaphore);
2305 LIBFUNC_END
2307 // SCA_MoveNode (SrcNodeList, DestNodeList, Node)
2308 // A0 A1 D0
2309 LIBFUNC_P4(void, sca_MoveNode,
2310 A0, struct ScalosNodeList *, src,
2311 A1, struct ScalosNodeList *, dest,
2312 D0, struct MinNode *, node,
2313 A6, struct ScalosBase *, ScalosBase)
2315 (void) ScalosBase;
2317 d1(kprintf("\n" "%s/%s/%ld: srcList=%08lx destList=%08lx node=%08lx "\
2318 "ln_Succ=%08lx ln_Pred=%08lx\n", \
2319 __FILE__, __FUNC__, __LINE__, src, dest, node, node->mln_Succ, node->mln_Pred));
2321 if (node->mln_Pred)
2322 src = (struct ScalosNodeList *) node->mln_Pred;
2324 src->snl_MinNode = node->mln_Succ;
2326 if (node->mln_Succ)
2327 node->mln_Succ->mln_Pred = node->mln_Pred;
2329 node->mln_Pred = NULL;
2331 if (dest->snl_MinNode)
2333 while (dest->snl_MinNode)
2334 dest = (struct ScalosNodeList *) dest->snl_MinNode;
2336 node->mln_Pred = (struct MinNode *) dest;
2339 dest->snl_MinNode = node;
2340 node->mln_Succ = NULL;
2342 LIBFUNC_END
2345 // SCA_SwapNodes ( SrcNode, DestNode, NodeList)
2346 // A0 A1 A2
2347 LIBFUNC_P4(void, sca_SwapNodes,
2348 A0, struct MinNode *, srcNode,
2349 A1, struct MinNode *, destNode,
2350 A2, struct ScalosNodeList *, nodeList,
2351 A6, struct ScalosBase *, ScalosBase)
2353 (void) ScalosBase;
2355 d1(kprintf("\n" "%s/%s/%ld: srcNode=%08lx ln_Succ=%08lx ln_Pred=%08lx "\
2356 "destNode=%08lx ln_Succ=%08lx ln_Pred=%08lx *nodeList=%08lx\n", \
2357 __FILE__, __FUNC__, __LINE__, srcNode, srcNode->mln_Succ, srcNode->mln_Pred, destNode, \
2358 destNode->mln_Succ, destNode->mln_Pred, nodeList->snl_MinNode));
2360 if (srcNode == destNode)
2361 return;
2363 if (srcNode->mln_Succ == destNode)
2365 // .nextnode
2366 srcNode->mln_Succ = destNode->mln_Succ;
2367 destNode->mln_Succ = srcNode;
2368 destNode->mln_Pred = srcNode->mln_Pred;
2369 srcNode->mln_Pred = destNode;
2371 else if (srcNode->mln_Pred == destNode)
2373 // .prevnode
2374 destNode->mln_Succ = srcNode->mln_Succ;
2375 srcNode->mln_Succ = destNode;
2376 srcNode->mln_Pred = destNode->mln_Pred;
2377 destNode->mln_Pred = srcNode;
2379 else
2381 struct MinNode *node;
2383 node = destNode->mln_Succ;
2384 destNode->mln_Succ = srcNode->mln_Succ;
2385 srcNode->mln_Succ = node;
2386 node = destNode->mln_Pred;
2387 destNode->mln_Pred = srcNode->mln_Pred;
2388 srcNode->mln_Pred = node;
2391 if (srcNode->mln_Succ)
2392 srcNode->mln_Succ->mln_Pred = srcNode;
2393 if (srcNode->mln_Pred)
2394 srcNode->mln_Pred->mln_Succ = srcNode;
2395 else
2396 nodeList->snl_MinNode = srcNode;
2398 if (destNode->mln_Succ)
2399 destNode->mln_Succ->mln_Pred = destNode;
2400 if (destNode->mln_Pred)
2401 destNode->mln_Pred->mln_Succ = destNode;
2402 else
2403 nodeList->snl_MinNode = destNode;
2405 d1(kprintf("%s/%s/%ld: srcNode=%08lx ln_Succ=%08lx ln_Pred=%08lx "\
2406 "destNode=%08lx ln_Succ=%08lx ln_Pred=%08lx *nodeList=%08lx\n", \
2407 __FILE__, __FUNC__, __LINE__, srcNode, srcNode->mln_Succ, srcNode->mln_Pred, destNode, \
2408 destNode->mln_Succ, destNode->mln_Pred, nodeList->snl_MinNode));
2410 LIBFUNC_END
2413 // SCA_SortNodes (NodeList, CompareFunc, SortType)
2414 // A0 A1 D0
2415 LIBFUNC_P4(void, sca_SortNodes,
2416 A0, struct ScalosNodeList *, nodeList,
2417 A1, struct Hook *, compareHook,
2418 D0, ULONG, SortType,
2419 A6, struct ScalosBase *, ScalosBase)
2421 static const NodeSortFuncType sortingFunctions[] =
2423 NodeBubbleSort,
2424 NodeSelectionSort,
2425 NodeInsertionSort,
2426 NodeQuickSort
2428 struct MinNode *lastNode;
2429 ULONG nodeCount;
2431 (void) ScalosBase;
2433 for (nodeCount=0, lastNode=nodeList->snl_MinNode; lastNode && lastNode->mln_Succ; lastNode=lastNode->mln_Succ)
2435 nodeCount++;
2438 d1(KPrintF("%s/%s/%ld: nodeCount=%lu\n", __FILE__, __FUNC__, __LINE__, nodeCount));
2440 if (nodeCount < 1)
2441 return;
2443 switch (SortType)
2445 case SCA_SortType_Bubble:
2446 case SCA_SortType_Selection:
2447 case SCA_SortType_Insertion:
2448 case SCA_SortType_Quick:
2449 break;
2451 case SCA_SortType_Best:
2452 if (nodeCount < 100)
2453 SortType = SCA_SortType_Selection;
2454 else
2455 SortType = SCA_SortType_Quick;
2456 break;
2458 default:
2459 return; // invalid SortType
2460 break;
2463 (sortingFunctions[SortType])(nodeList, lastNode, nodeCount, compareHook);
2465 LIBFUNC_END
2468 LIBFUNC_P3(Object *, sca_GetDefIconObject,
2469 A0, BPTR, dirLock,
2470 A1, CONST_STRPTR, name,
2471 A6, struct ScalosBase *, ScalosBase)
2473 (void) ScalosBase;
2475 return ReturnDefIconObj(dirLock, name, NULL);
2477 LIBFUNC_END
2480 LIBFUNC_P4(Object *, sca_GetDefIconObjectA,
2481 A0, BPTR, dirLock,
2482 A1, CONST_STRPTR, name,
2483 A2, struct TagItem *, tagList,
2484 A6, struct ScalosBase *, ScalosBase)
2486 (void) ScalosBase;
2488 return ReturnDefIconObj(dirLock, name, tagList);
2490 LIBFUNC_END
2493 LIBFUNC_P3(struct ScaWindowStruct *, sca_OpenDrawerByName,
2494 A0, CONST_STRPTR, path,
2495 A1, struct TagItem *, TagList,
2496 A6, struct ScalosBase *, ScalosBase)
2498 (void) ScalosBase;
2500 return OpenDrawerByName(path, TagList);
2502 LIBFUNC_END
2504 static void NodeBubbleSort(struct ScalosNodeList *nodeList,
2505 struct MinNode *lastNode, ULONG nodeCount, struct Hook *compareHook)
2507 struct MinNode *node = nodeList->snl_MinNode;
2509 d1(KPrintF("%s/%s/%ld: nodeCount=%lu\n", __FILE__, __FUNC__, __LINE__, nodeCount));
2511 while (1)
2513 BOOL Sorted = TRUE;
2515 while (node->mln_Succ)
2517 if ((LONG) CallHookPkt(compareHook, node, node->mln_Succ) > 0)
2519 d1(kprintf("%s/%s/%ld: SWAP leftNode=%08lx rightNode=%08lx\n", __FILE__, __FUNC__, __LINE__, node, node->mln_Succ));
2520 SCA_SwapNodes(node, node->mln_Succ, nodeList);
2521 Sorted = FALSE;
2523 else
2524 node = node->mln_Succ;
2527 if (Sorted)
2528 break;
2530 node = nodeList->snl_MinNode;
2532 d1(KPrintF("%s/%s/%ld: \n", __LINE__));
2536 static void NodeSelectionSort(struct ScalosNodeList *nodeList,
2537 struct MinNode *lastNode, ULONG nodeCount, struct Hook *compareHook)
2539 struct MinNode *firstNode = nodeList->snl_MinNode;
2540 struct MinNode *leftNode = firstNode;
2542 d1(KPrintF("%s/%s/%ld: nodeCount=%lu\n", __FILE__, __FUNC__, __LINE__, nodeCount));
2544 while (1)
2546 struct MinNode *rightNode = leftNode->mln_Succ;
2548 while (1)
2550 if ((LONG) CallHookPkt(compareHook, rightNode, leftNode) < 0)
2552 struct MinNode *tempNode = leftNode;
2554 d1(kprintf("%s/%s/%ld: SWAP leftNode=%08lx rightNode=%08lx\n", __FILE__, __FUNC__, __LINE__, leftNode, rightNode));
2555 SCA_SwapNodes(leftNode, rightNode, nodeList);
2557 leftNode = rightNode;
2558 rightNode = tempNode;
2561 rightNode = rightNode->mln_Succ;
2562 if (NULL == rightNode)
2563 break;
2566 leftNode = leftNode->mln_Succ;
2567 if (NULL == leftNode->mln_Succ)
2568 break;
2571 d1(KPrintF("%s/%s/%ld: \n", __LINE__));
2575 static void NodeInsertionSort(struct ScalosNodeList *nodeList,
2576 struct MinNode *lastNode, ULONG nodeCount, struct Hook *compareHook)
2578 struct MinNode *firstNode = nodeList->snl_MinNode;
2579 struct MinNode *rightNode;
2581 d1(KPrintF("%s/%s/%ld: nodeCount=%lu\n", __FILE__, __FUNC__, __LINE__, nodeCount));
2583 rightNode = firstNode->mln_Succ;
2585 while (1)
2587 struct MinNode *leftNode = rightNode;
2588 struct MinNode *rightNext = rightNode->mln_Succ;
2590 while (1)
2592 d1(kprintf("%s/%s/%ld: leftNode=%08lx firstNode=%08lx\n", __FILE__, __FUNC__, __LINE__, leftNode, firstNode));
2594 if (NULL == leftNode->mln_Pred)
2595 break;
2597 if ((LONG) CallHookPkt(compareHook, leftNode, leftNode->mln_Pred) < 0)
2599 d1(kprintf("%s/%s/%ld: SWAP node1=%08lx node2=%08lx\n", __FILE__, __FUNC__, __LINE__, leftNode->mln_Pred, leftNode));
2600 SCA_SwapNodes(leftNode->mln_Pred, leftNode, nodeList);
2602 else
2603 break;
2605 rightNode = rightNext;
2606 if (rightNext == NULL)
2607 break;
2609 d1(KPrintF("%s/%s/%ld: \n", __LINE__));
2613 static void NodeQuickSort(struct ScalosNodeList *nodeList,
2614 struct MinNode *lastNode, ULONG nodeCount, struct Hook *compareHook)
2616 d1(KPrintF("%s/%s/%ld: \n", __LINE__));
2618 quickSortList(nodeList, compareHook, nodeList->snl_MinNode, lastNode);
2620 d1(KPrintF("%s/%s/%ld: \n", __LINE__));
2624 static void quickSortList(struct ScalosNodeList *nodeList, struct Hook *compareHook,
2625 struct MinNode *firstNode, struct MinNode *lastNode)
2627 struct MinNode *middleNode, *middleNodeNext;
2629 d1(KPrintF("%s/%s/%ld: \n", __LINE__));
2631 if (firstNode == lastNode)
2632 return;
2634 middleNode = PartitionNodeList(nodeList, compareHook, &firstNode, &lastNode);
2636 d1(kprintf("%s/%s/%ld: middleNode=%08lx\n", __FILE__, __FUNC__, __LINE__, middleNode));
2638 middleNodeNext = middleNode->mln_Succ;
2640 if (middleNode != firstNode)
2641 quickSortList(nodeList, compareHook, firstNode, middleNode);
2642 if (middleNode != lastNode)
2643 quickSortList(nodeList, compareHook, middleNodeNext, lastNode);
2645 d1(KPrintF("%s/%s/%ld: \n", __LINE__));
2649 static struct MinNode *PartitionNodeList(struct ScalosNodeList *nodeList, struct Hook *compareHook,
2650 struct MinNode **leftNode, struct MinNode **rightNode)
2652 struct MinNode *pivotNode;
2653 struct MinNode *iNode, *jNode;
2654 BOOL Done;
2655 int nodecount;
2656 struct MinNode *tempNode;
2658 /*********************************************************************
2659 * partition list [leftNode..rightNode], and return pointer to pivot *
2660 *********************************************************************/
2662 d1(kprintf("%s/%s/%ld: START *leftNode=%08lx *rightNode=%08lx\n", __FILE__, __FUNC__, __LINE__, *leftNode, *rightNode));
2664 /* Find centre node in list */
2665 for(pivotNode = *leftNode, nodecount = 0, tempNode=*leftNode;
2666 tempNode && tempNode != *rightNode;
2667 tempNode = tempNode->mln_Succ)
2669 nodecount ^= 1;
2670 if(nodecount == 0)
2672 pivotNode = pivotNode->mln_Succ;
2676 Done = FALSE;
2677 iNode = *leftNode;
2678 jNode = *rightNode;
2680 /* scan from both ends, swapping when needed */
2681 /* care must be taken not to address outside [leftNode..rightNode] with pointers */
2683 while (1)
2685 struct MinNode *tempNode;
2687 d1(kprintf("%s/%s/%ld: iNode=%08lx jNode=%08lx pivotNode=%08lx\n", __FILE__, __FUNC__, __LINE__, iNode, jNode, pivotNode));
2688 d1(kprintf("%s/%s/%ld: *leftNode=%08lx *rightNode=%08lx\n", __FILE__, __FUNC__, __LINE__, *leftNode, *rightNode));
2690 d1({\
2691 struct MinNode *node = nodeList->snl_MinNode;\
2692 while (node)\
2694 kprintf(" node=%08lx prev=%08lx next=%08lx\n", node, node->mln_Pred, node->mln_Succ);\
2695 node = node->mln_Succ;\
2698 while ((LONG) CallHookPkt(compareHook, jNode, pivotNode) > 0)
2700 if (iNode == jNode)
2701 Done = TRUE;
2702 jNode = jNode->mln_Pred;
2704 if (Done)
2705 return jNode;
2706 while ((LONG) CallHookPkt(compareHook, iNode, pivotNode) < 0)
2708 if (iNode == jNode)
2709 Done = TRUE;
2710 iNode = iNode->mln_Succ;
2713 if (iNode == jNode)
2714 return jNode;
2715 if (Done)
2716 return jNode;
2718 d1(kprintf("%s/%s/%ld: iNode=%08lx jNode=%08lx\n", __FILE__, __FUNC__, __LINE__, iNode, jNode));
2720 if (iNode->mln_Succ == jNode)
2721 Done = TRUE;
2722 if (jNode->mln_Pred == iNode)
2723 Done = TRUE;
2725 /* swap iNode, jNode */
2726 d1(kprintf("%s/%s/%ld: SWAP node1=%08lx node2=%08lx\n", __FILE__, __FUNC__, __LINE__, iNode, jNode));
2727 SCA_SwapNodes(iNode, jNode, nodeList);
2729 // adjust swapped leftNode, rightNode
2730 if (iNode == *leftNode)
2731 *leftNode = jNode;
2732 else if (jNode == *leftNode)
2733 *leftNode = iNode;
2735 if (iNode == *rightNode)
2736 *rightNode = jNode;
2737 else if (jNode == *rightNode)
2738 *rightNode = iNode;
2740 /* examine next element */
2741 tempNode = iNode;
2742 if(jNode != *rightNode)
2743 iNode = jNode->mln_Succ;
2744 else
2745 Done = TRUE;
2747 if(tempNode != *leftNode)
2748 jNode = tempNode->mln_Pred;
2749 else
2750 Done = TRUE;
2752 if(iNode->mln_Pred == jNode)
2753 Done = TRUE;
2758 // SCA_RemapBitmap( SrcBitmap, DestBitmap, PenArray )
2759 // A0 A1 A2
2760 LIBFUNC_P4(void, sca_RemapBitmap,
2761 A0, struct BitMap *, bmSrc,
2762 A1, struct BitMap *, bmDest,
2763 A2, const BYTE *, penArray,
2764 A6, struct ScalosBase *, ScalosBase)
2766 // no longer supported
2767 (void) bmSrc;
2768 (void) bmDest;
2769 (void) penArray;
2770 (void) ScalosBase;
2772 LIBFUNC_END
2776 LIBFUNC_P1(ULONG, sca_CountWBArgs,
2777 A0, struct ScaIconNode *, in)
2779 struct ScaWindowStruct *ws;
2780 ULONG ArgCount = 0;
2782 d1(KPrintF("%s/%s/%ld: START in=%08lx\n", __FILE__, __FUNC__, __LINE__, in));
2784 SCA_LockWindowList(SCA_LockWindowList_Shared);
2786 for (ws=winlist.wl_WindowStruct; ws; ws = (struct ScaWindowStruct *) ws->ws_Node.mln_Succ)
2788 if (!(ws->ws_Flags & WSV_FlagF_TaskSleeps))
2790 ArgCount += CountWindowWBArgs(ws, in);
2794 if (NULL == in && 0 == ArgCount)
2796 for (ws=winlist.wl_WindowStruct; ws; ws = (struct ScaWindowStruct *) ws->ws_Node.mln_Succ)
2798 if (!(ws->ws_Flags & WSV_FlagF_TaskSleeps)
2799 && ws->ws_Window
2800 && ws != iInfos.xii_iinfos.ii_MainWindowStruct
2801 && (ws->ws_Window->Flags & WFLG_WINDOWACTIVE))
2803 ArgCount += DoMethod(ws->ws_WindowTask->mt_MainObject, SCCM_IconWin_CountWBArg, NULL);
2808 SCA_UnLockWindowList();
2810 d1(KPrintF("%s/%s/%ld: END ArgCount=%lu\n", __FILE__, __FUNC__, __LINE__, ArgCount));
2812 return ArgCount;
2814 LIBFUNC_END
2817 static STRPTR ChkPrjRequestFile(struct WBArg *arg)
2819 STRPTR Path;
2820 struct FileRequester *fileReq = NULL;
2821 BOOL Success = FALSE;
2823 do {
2824 Path = AllocPathBuffer();
2825 if (NULL == Path)
2826 break;
2828 if (!NameFromLock(arg->wa_Lock, Path, Max_PathLen))
2829 break;
2831 // AllocAslRequest()
2832 fileReq = AllocAslRequestTags(ASL_FileRequest,
2833 ASLFR_PrivateIDCMP, TRUE,
2834 ASLFR_Screen, (ULONG) iInfos.xii_iinfos.ii_Screen,
2835 ASLFR_TitleText, (ULONG) GetLocString(MSGID_REQ_SELECTDEFTOOL),
2836 ASLFR_DoSaveMode, FALSE,
2837 ASLFR_RejectIcons, TRUE,
2838 TAG_END);
2840 if (NULL == fileReq)
2841 break;
2843 // AslRequest()
2844 Success = AslRequestTags(fileReq,
2845 ASLFR_InitialFile, (ULONG) arg->wa_Name,
2846 ASLFR_InitialDrawer, (ULONG) Path,
2847 TAG_END);
2849 if (Success)
2851 stccpy(Path, fileReq->fr_Drawer, Max_PathLen);
2852 AddPart(Path, fileReq->fr_File, Max_PathLen);
2854 } while (0);
2856 if (Path)
2858 if (!Success)
2860 FreePathBuffer(Path);
2861 Path = NULL;
2864 if (fileReq)
2865 FreeAslRequest(fileReq);
2867 return Path;
2871 static ULONG CountWindowWBArgs(struct ScaWindowStruct *ws,
2872 struct ScaIconNode *inExclude)
2874 struct internalScaWindowTask *iwt = (struct internalScaWindowTask *) ws->ws_WindowTask;
2875 struct ScaIconNode *in;
2876 ULONG ArgCount = 0;
2878 d1(KPrintF("%s/%s/%ld: START iwt=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, iwt, iwt->iwt_WinTitle));
2880 ScalosLockIconListShared(iwt);
2882 for (in=iwt->iwt_WindowTask.wt_IconList; in;
2883 in = (struct ScaIconNode *) in->in_Node.mln_Succ)
2885 struct ExtGadget *gg = (struct ExtGadget *) in->in_Icon;
2887 if (in != inExclude && (gg->Flags & GFLG_SELECTED))
2889 ArgCount += DoMethod(iwt->iwt_WindowTask.mt_MainObject, SCCM_IconWin_CountWBArg, in);
2893 ScalosUnLockIconList(iwt);
2895 d1(KPrintF("%s/%s/%ld: END ArgCount=%lu\n", __FILE__, __FUNC__, __LINE__, ArgCount));
2897 return ArgCount;