/*
Auto:		smake FIconPrefs
*/


/* $Revision Header built automatically *************** (do not edit) ************
**
** © Copyright by GuntherSoft
**
** File             : SnakeSYS:CPrgs/ForceIcon2/FIconPrefs.c
** Created on       : Wednesday, 16.03.94 16:19:51
** Created by       : Kai Iske
** Current revision : V1.0
**
**
** Purpose
** -------
**   - Prefs Editor for ForceIcon
**
** Revision V1.0
** --------------
** created on Wednesday, 16.03.94 16:19:51  by  Kai Iske.   LogMessage :
**     --- Initial release ---
**
*********************************************************************************/




/**********************************************************************/
/*                     Define for DisplayError()                      */
/**********************************************************************/
#define	PREFSRUN






/**********************************************************************/
/*                      Routines for this module                      */
/**********************************************************************/
static BOOL			OpenAll(void);
static void			CloseAll(void);
static struct	FIconSema	*FindFIconSema(void);
static void			RemoveFIconSema(struct FIconSema *FIconSema);
static BOOL			InitApp(void);
static void			RemoveApp(void);
static ULONG	__saveds __asm	DispViewFunc(register __a0 struct Hook *MyHook, register __a2 char **array, register __a1 struct VolEntry *Data);
static ULONG	__saveds __asm	DisableFunc(register __a0 struct Hook *MyHook, register __a2 APTR Obj, register __a1 APTR *Data);
static ULONG	__saveds __asm	PageChangeFunc(register __a0 struct Hook *MyHook, register __a2 APTR Obj, register __a1 APTR *Data);
static struct	VolEntry	*AddNewVolume(char *Name, ULONG Type, struct VolEntry *CopyPtr);
static BOOL			CheckExists(struct List *CheckList, char *Name);
static BOOL			SavePrefs(BOOL EnvMode, char *ToName);
static void			DskChange(struct VolEntry *ListEntry);
static BOOL			GetTaskList(struct List *AppList);
static BOOL			GetFileName(struct Window *Window, char *Title, char *FileName, ULONG Flags1);
static BOOL			CloneList(struct List *ToList, struct List *FromList);





/**********************************************************************/
/*                    Functions of files included                     */
/**********************************************************************/
	// LoadPrefs.h

static BOOL			LoadPrefs(struct FIconSema *FIconSema, char *TryName);

	// VolList.h

static BOOL			GetDevVolList(struct List *VolList);
static BOOL			GetDosEntries(struct List *VolList, ULONG Mode);
static void			FreeDevVolList(struct List *VolList);
static void			SortList(struct List *VolList, BOOL DisplayType);
static void			SortPartialList(struct List *VolList, UWORD Left, UWORD Right);
static APTR			GetListEntry(struct List *List, WORD EntryNum);
static BOOL			MyStrCmp(char *FromName, char *ToName);

	// Error.h

static BOOL	__stdargs	DisplayError(LONG ErrCode, ULONG Arg1, ...);

	// CheckToolTypes.h

static void			CheckToolTypes(struct WBStartup *WBenchMsg);

	// PoolVec.h

static APTR			AllocVecPool(struct FIconSema *FIconSema, ULONG Size);
static void			FreeVecPool(struct FIconSema *FIconSema, APTR Addr);






/**********************************************************************/
/*                           Library bases                            */
/**********************************************************************/
struct	ExecBase		*SysBase;
struct	IntuitionBase		*IntuitionBase	= NULL;
struct	DosLibrary		*DOSBase	= NULL;
struct	GfxBase			*GfxBase	= NULL;
struct	Library			*IconBase	= NULL;
struct	Library			*UtilityBase	= NULL;
struct	Library			*IFFParseBase	= NULL;
struct	Library			*MUIMasterBase	= NULL;






/**********************************************************************/
/*                         "No-StartUp vars"                          */
/**********************************************************************/
#define	MUIVERS					"$VER: ForceIcon_Prefs "REVISION" ("REVDATE")"
char				_ProgramName[]	= "ForceIconPrefs";
LONG				_OSERR		= 0;




/**********************************************************************/
/*                           Our variables                            */
/**********************************************************************/
static	struct	FIconSema	*FIconSema	= NULL;		// Pointer to our rendezvous semaphore
static	struct	List		AvailableList;
static	struct	List		AppAvailableList;
static	struct	List		BackUpVolList;
static	struct	List		BackUpAppList;
static	UWORD			FlushMemory	= FALSE;




/**********************************************************************/
/*                 Application and window definitions                 */
/**********************************************************************/
static	struct	DiskObject	*DObj		= NULL;
static	APTR			AppObject	= NULL;
static	APTR			MainWindow	= NULL;
static	APTR			UsedList;
static	APTR			EditEntry;
static	APTR			CopyEntry;
static	APTR			RemoveEntry;
static	APTR			AvailList;
static	APTR			AddEntry;
static	APTR			AddEntryMan;
static	APTR			RescanList;
static	APTR			AppUsedList;
static	APTR			AppEditEntry;
static	APTR			AppCopyEntry;
static	APTR			AppRemoveEntry;
static	APTR			AppAvailList;
static	APTR			AppAddEntry;
static	APTR			AppAddEntryMan;
static	APTR			AppRescanList;
static	APTR			SaveObj;
static	APTR			UseObj;
static	APTR			HideObj;

static	APTR			EditWindow;
static	APTR			VolumeName;
static	APTR			VolumeType;
static	APTR			IconPosGroup;
static	APTR			IconPos[2];
static	APTR			IconX;
static	APTR			IconY;
static	APTR			Position;
static	APTR			UseIconGroup;
static	APTR			UseIcon[2];
static	APTR			IconName;
static	APTR			UseWindowGroup;
static	APTR			UseWindow[2];
static	APTR			WinX;
static	APTR			WinY;
static	APTR			WinWidth;
static	APTR			WinHeight;
static	APTR			LookWin;
static	APTR			UseFlagsGroup;
static	APTR			UseFlags[2];
static	APTR			FlagModes;
static	APTR			EditOkObj;
static	APTR			EditCancelObj;

static	APTR			AppEditWindow;
static	APTR			AppTaskName;
static	APTR			AppIconPos;
static	APTR			AppIconX;
static	APTR			AppIconY;
static	APTR			AppPosition;
static	APTR			AppUseIcon;
static	APTR			AppIconName;
static	APTR			AppEditOkObj;
static	APTR			AppEditCancelObj;

static	APTR			ManWindow;
static	APTR			ManVolName;
static	APTR			ManVolType;
static	APTR			ManOkObj;
static	APTR			ManCancelObj;

static	APTR			AppManWindow;
static	APTR			AppManTaskName;
static	APTR			AppManOkObj;
static	APTR			AppManCancelObj;





/**********************************************************************/
/*                            Page titles                             */
/**********************************************************************/
static const char *MainWinPageTitles[] =
{
	"Volumes/Devices",
	"AppIcons",
	NULL
};


/**********************************************************************/
/*                     Strings for Cycle gadgets                      */
/**********************************************************************/
static const char *TypeEntries[] =
{
	"Volume",
	"Device",
	NULL
};


static const char *IconModeEntriesVol[] =
{
	"Ignore",
	"Use",
	"Reset",
	"Inherit",
	NULL
};


static const char *IconModeEntriesDev[] =
{
	"Ignore",
	"Use",
	"Reset",
	NULL
};


static const char *ModeEntriesVol[] =
{
	"Ignore",
	"Use",
	"Inherit",
	NULL
};


static const char *ModeEntriesDev[] =
{
	"Ignore",
	"Use",
	NULL
};


static const char *PositionEntries[] =
{
	"Open position window",
	"Close position window",
	NULL
};



static const char *LookWinEntries[] =
{
	"Open window",
	"Close window",
	NULL
};


static const char *FlagModesEntries[] =
{
	"only icons + view by icon",
	"only icons + view by name",
	"only icons + view by date",
	"only icons + view by size",
	"all files + view by icon",
	"all files + view by name",
	"all files + view by date",
	"all files + view by size",
	NULL
};




/**********************************************************************/
/*                          Menu definition                           */
/**********************************************************************/
static struct	NewMenu MainMenuDef[] =
{
	NM_TITLE, "Project", NULL, 0, NULL, NULL,
	NM_ITEM, "Open...", "O", 0, NULL, (APTR)ID_OPEN,
	NM_ITEM, "Save as...", "A", 0, NULL, (APTR)ID_SAVEAS,
	NM_ITEM, NM_BARLABEL, NULL, 0, NULL, NULL,
	NM_ITEM, "About", "?", 0, NULL, (APTR)ID_ABOUT,
	NM_ITEM, NM_BARLABEL, NULL, 0, NULL, NULL,
	NM_ITEM, "Quit (Prefs + Server)", "Q", 0, NULL, (APTR)ID_QUIT,
	NM_ITEM, "Quit (Prefs)", "H", 0, NULL, (APTR)ID_HIDE,

	NM_TITLE, "Settings", NULL, 0, NULL, NULL,
	NM_ITEM, "Reset to defaults", "D", 0, NULL, (APTR)ID_RESET,
	NM_ITEM, "Last saved", "L", 0, NULL, (APTR)ID_LASTSAVED,
	NM_ITEM, "Restore", "R", 0, NULL, (APTR)ID_RESTORE,

	NM_END, NULL, NULL, 0, NULL, NULL
};

/**********************************************************************/
/*                            Display Hook                            */
/**********************************************************************/
static struct Hook	DispViewHook =
{
	{NULL},
	(APTR)DispViewFunc,
	NULL,
	NULL
};



static struct Hook	DisableHook =
{
	{NULL},
	(APTR)DisableFunc,
	NULL,
	NULL
};



static struct Hook	PageChangeHook =
{
	{NULL},
	(APTR)PageChangeFunc,
	NULL,
	NULL
};



/**********************************************************************/
/*                      This is our main program                      */
/**********************************************************************/
ULONG __saveds main(void)
{
	struct	Process		*MyProc;
	struct	WBStartup	*WBenchMsg	= NULL;
	struct	VolEntry	*EditEntryPtr	= NULL;
	struct	Window		*PosWindow	= NULL,
				*DrawerWindow	= NULL;
	ULONG			MySig,
				ReturnID;
	BOOL			GoOn		= TRUE;




		// Get SysBase

	SysBase	= *((struct ExecBase **)0x4L);


		// Get address of our process

	MyProc = (struct Process *)FindTask(NULL);



		// Determine where we were started from

	if(!MyProc->pr_CLI)
	{
		WaitPort(&MyProc->pr_MsgPort);
		WBenchMsg = (struct WBStartup *)GetMsg(&MyProc->pr_MsgPort);
	}



		// Don`t run under OS < 37

	if(((struct Library *)SysBase)->lib_Version >= 37)
	{
			// Open libraries

		if(OpenAll())
		{
				// Try to find Semaphore

			if((FIconSema = FindFIconSema()))
			{
					// Old version with no AppIcon support running?

				if(!strcmp(FIconSema->FIconSema.ss_Link.ln_Name, "ForceIcon rendezvous"))
				{
					struct	Task	*ServerTask	= FIconSema->ServerTask;

						// Server task found?

					if(ServerTask)
					{
							// Release semaphore

						RemoveFIconSema(FIconSema);

							// Break server program

						Signal(ServerTask, SIGBREAKF_CTRL_C);

							// Display error

						DisplayError(ERR_OLDFICON, NULL);

							// Create new semaphore

						FIconSema	= FindFIconSema();
					}
				}
			}

			if(FIconSema)
			{

					// Check for ToolTypes/commandline options

				CheckToolTypes(WBenchMsg);

					// Create backups of settings

				NewList(&BackUpVolList);
				NewList(&BackUpAppList);


				if(InitApp() && CloneList(&BackUpVolList, &FIconSema->VolumeList) && CloneList(&BackUpAppList, &FIconSema->AppIconList))
				{
					while(GoOn)
					{
						switch(ReturnID = DoMethod(AppObject, MUIM_Application_Input, &MySig))
						{
								// Handle MAINWINDOW


								// Save ?!?!

							case ID_SAVE :
							{
								SavePrefs(FALSE, NULL);
								GoOn	= FALSE;
								break;
							}

								// Use ?!?!

							case ID_USE :
							{
								SavePrefs(TRUE, NULL);
								GoOn	= FALSE;
								break;
							}

								// About ???

							case ID_ABOUT :
							{
								DisplayError(ERR_ABOUT, VERNUM, REVNUM, REVDATE, NULL);
								break;
							}

								// Hide/Quit Prefs ?!?

							case ID_HIDE :
							{
								GoOn	= FALSE;
								break;
							}

								// Hide/Quit Prefs and server ???

							case ID_QUIT :
							{
								struct	Task	*ServerTask;

								ObtainSemaphore(&FIconSema->FIconSema);
								Forbid();
								ServerTask	= FIconSema->ServerTask;
								ReleaseSemaphore(&FIconSema->FIconSema);

									// Tell server to go away

								if(ServerTask)
									Signal(ServerTask, SIGBREAKF_CTRL_C);
								Permit();

								GoOn	= FALSE;
								break;
							}

								// Load prefs?

							case ID_OPEN :
							{
								struct	Window	*Window;
								char		FileName[514];

									// Create standard filename

								strcpy(FileName, "ENV:ForceIcon_prefs.iff");

									// Get pointer to main window

								get(MainWindow, MUIA_Window_Window, &Window);
								if(GetFileName(Window, "Select settings to load...", FileName, 0))
								{
										// Clear old lists

									FreeDevVolList(&FIconSema->VolumeList);
									FreeDevVolList(&FIconSema->AppIconList);
									DoMethod(UsedList, MUIM_List_Clear, NULL);
									DoMethod(AppUsedList, MUIM_List_Clear, NULL);

									if(LoadPrefs(FIconSema, FileName))
									{
										struct	VolEntry	*ThisEntry;

											// Add list of used entries

										ObtainSemaphore(&FIconSema->FIconSema);
										ThisEntry	= (struct VolEntry *)FIconSema->VolumeList.lh_Head;

										while(ThisEntry->Link.ln_Succ)
										{
											DoMethod(UsedList, MUIM_List_InsertSingle, (APTR)ThisEntry, MUIV_List_Insert_Bottom);

											ThisEntry	= (struct VolEntry *)ThisEntry->Link.ln_Succ;
										}
										ReleaseSemaphore(&FIconSema->FIconSema);


										ObtainSemaphore(&FIconSema->FIconSema);
										ThisEntry	= (struct VolEntry *)FIconSema->AppIconList.lh_Head;

										while(ThisEntry->Link.ln_Succ)
										{
											DoMethod(AppUsedList, MUIM_List_InsertSingle, (APTR)ThisEntry, MUIV_List_Insert_Bottom);

											ThisEntry	= (struct VolEntry *)ThisEntry->Link.ln_Succ;
										}
										ReleaseSemaphore(&FIconSema->FIconSema);
									}
								}
								break;
							}

							case ID_SAVEAS :
							{
								struct	Window	*Window;
								char		FileName[514];

									// Create standard filename

								strcpy(FileName, "ENVARC:ForceIcon_prefs.iff");

									// Get pointer to main window

								get(MainWindow, MUIA_Window_Window, &Window);
								if(GetFileName(Window, "Select file to save to...", FileName, 0))
									SavePrefs(FALSE, FileName);
								break;
							}

							case ID_RESET :
							{
								FreeDevVolList(&FIconSema->VolumeList);
								FreeDevVolList(&FIconSema->AppIconList);
								DoMethod(UsedList, MUIM_List_Clear, NULL);
								DoMethod(AppUsedList, MUIM_List_Clear, NULL);
								break;
							}

							case ID_LASTSAVED :
							{
								FreeDevVolList(&FIconSema->VolumeList);
								FreeDevVolList(&FIconSema->AppIconList);
								DoMethod(UsedList, MUIM_List_Clear, NULL);
								DoMethod(AppUsedList, MUIM_List_Clear, NULL);

								if(LoadPrefs(FIconSema, NULL))
								{
									struct	VolEntry	*ThisEntry;

										// Add list of used entries

									ObtainSemaphore(&FIconSema->FIconSema);
									ThisEntry	= (struct VolEntry *)FIconSema->VolumeList.lh_Head;

									while(ThisEntry->Link.ln_Succ)
									{
										DoMethod(UsedList, MUIM_List_InsertSingle, (APTR)ThisEntry, MUIV_List_Insert_Bottom);

										ThisEntry	= (struct VolEntry *)ThisEntry->Link.ln_Succ;
									}
									ReleaseSemaphore(&FIconSema->FIconSema);


									ObtainSemaphore(&FIconSema->FIconSema);
									ThisEntry	= (struct VolEntry *)FIconSema->AppIconList.lh_Head;

									while(ThisEntry->Link.ln_Succ)
									{
										DoMethod(AppUsedList, MUIM_List_InsertSingle, (APTR)ThisEntry, MUIV_List_Insert_Bottom);

										ThisEntry	= (struct VolEntry *)ThisEntry->Link.ln_Succ;
									}
									ReleaseSemaphore(&FIconSema->FIconSema);
								}
								break;
							}

							case ID_RESTORE :
							{
								struct	VolEntry	*ThisEntry;

								FreeDevVolList(&FIconSema->VolumeList);
								FreeDevVolList(&FIconSema->AppIconList);
								DoMethod(UsedList, MUIM_List_Clear, NULL);
								DoMethod(AppUsedList, MUIM_List_Clear, NULL);

								if(CloneList(&FIconSema->VolumeList, &BackUpVolList) && CloneList(&FIconSema->AppIconList, &BackUpAppList))
								{
										// Add list of used entries

									ObtainSemaphore(&FIconSema->FIconSema);
									ThisEntry	= (struct VolEntry *)FIconSema->VolumeList.lh_Head;

									while(ThisEntry->Link.ln_Succ)
									{
										DoMethod(UsedList, MUIM_List_InsertSingle, (APTR)ThisEntry, MUIV_List_Insert_Bottom);

										ThisEntry	= (struct VolEntry *)ThisEntry->Link.ln_Succ;
									}
									ReleaseSemaphore(&FIconSema->FIconSema);


									ObtainSemaphore(&FIconSema->FIconSema);
									ThisEntry	= (struct VolEntry *)FIconSema->AppIconList.lh_Head;

									while(ThisEntry->Link.ln_Succ)
									{
										DoMethod(AppUsedList, MUIM_List_InsertSingle, (APTR)ThisEntry, MUIV_List_Insert_Bottom);

										ThisEntry	= (struct VolEntry *)ThisEntry->Link.ln_Succ;
									}
									ReleaseSemaphore(&FIconSema->FIconSema);
								}
							}


								// Edit entry (Volumes)???

							case ID_USEDLIST :
							case ID_EDITENTRY :
							{
								struct	VolEntry	*ThisEntry;

								DoMethod(UsedList, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &ThisEntry);

								if(ThisEntry)
								{
									set(VolumeName, MUIA_String_Contents, ThisEntry->VolName);
									set(VolumeType, MUIA_Cycle_Active, (ThisEntry->Link.ln_Type == LDF_DEVICES));
									set(IconPos[0], MUIA_Cycle_Active, ThisEntry->IconPos);
									set(IconPos[1], MUIA_Cycle_Active, ThisEntry->IconPos);
									set(IconX, MUIA_String_Integer, ThisEntry->Left);
									set(IconX, MUIA_Disabled, (ThisEntry->IconPos != MODE_USE));
									set(IconY, MUIA_String_Integer, ThisEntry->Top);
									set(IconY, MUIA_Disabled, (ThisEntry->IconPos != MODE_USE));
									set(Position, MUIA_Cycle_Active, 0);
									set(Position, MUIA_Disabled, (ThisEntry->IconPos != MODE_USE));
									set(UseIcon[0], MUIA_Cycle_Active, ThisEntry->UseAlt);
									set(UseIcon[1], MUIA_Cycle_Active, ThisEntry->UseAlt);
									set(IconName, MUIA_String_Contents, ThisEntry->IconName);
									set(IconName, MUIA_Disabled, (ThisEntry->UseAlt != MODE_USE));
									set(UseWindow[0], MUIA_Cycle_Active, ThisEntry->UseWin);
									set(UseWindow[1], MUIA_Cycle_Active, ThisEntry->UseWin);
									set(WinX, MUIA_String_Integer, ThisEntry->WinX);
									set(WinX, MUIA_Disabled, (ThisEntry->UseWin != MODE_USE));
									set(WinY, MUIA_String_Integer, ThisEntry->WinY);
									set(WinY, MUIA_Disabled, (ThisEntry->UseWin != MODE_USE));
									set(WinWidth, MUIA_String_Integer, ThisEntry->WinWidth);
									set(WinWidth, MUIA_Disabled, (ThisEntry->UseWin != MODE_USE));
									set(WinHeight, MUIA_String_Integer, ThisEntry->WinHeight);
									set(WinHeight, MUIA_Disabled, (ThisEntry->UseWin != MODE_USE));
									set(LookWin, MUIA_Cycle_Active, 0);
									set(LookWin, MUIA_Disabled, (ThisEntry->UseWin != MODE_USE));
									set(UseFlags[0], MUIA_Cycle_Active, ThisEntry->UseFlags);
									set(UseFlags[1], MUIA_Cycle_Active, ThisEntry->UseFlags);
									set(FlagModes, MUIA_Cycle_Active, ThisEntry->WinFlags);
									set(FlagModes, MUIA_Disabled, (ThisEntry->UseFlags != MODE_USE));

									set(MainWindow, MUIA_Window_Sleep, TRUE);

									set(EditWindow, MUIA_Window_Open, TRUE);

									EditEntryPtr	= ThisEntry;
								}
								break;
							}

								// Edit entry (AppIcons)???

							case ID_APPUSEDLIST :
							case ID_APPEDITENTRY :
							{
								struct	VolEntry	*ThisEntry;

								DoMethod(AppUsedList, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &ThisEntry);

								if(ThisEntry)
								{
									set(AppTaskName, MUIA_String_Contents, ThisEntry->VolName);
									set(AppIconPos, MUIA_Cycle_Active, ThisEntry->IconPos);
									set(AppIconX, MUIA_String_Integer, ThisEntry->Left);
									set(AppIconX, MUIA_Disabled, (ThisEntry->IconPos != MODE_USE));
									set(AppIconY, MUIA_String_Integer, ThisEntry->Top);
									set(AppIconY, MUIA_Disabled, (ThisEntry->IconPos != MODE_USE));
									set(AppPosition, MUIA_Cycle_Active, 0);
									set(AppPosition, MUIA_Disabled, (ThisEntry->IconPos != MODE_USE));
									set(AppUseIcon, MUIA_Cycle_Active, ThisEntry->UseAlt);
									set(AppIconName, MUIA_String_Contents, ThisEntry->IconName);
									set(AppIconName, MUIA_Disabled, (ThisEntry->UseAlt != MODE_USE));

									set(MainWindow, MUIA_Window_Sleep, TRUE);

									set(AppEditWindow, MUIA_Window_Open, TRUE);

									EditEntryPtr	= ThisEntry;
								}
								break;
							}

								// Copy an entry (Volumes)???

							case ID_COPYENTRY :
							{
								struct	VolEntry	*ThisEntry;


								DoMethod(UsedList, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &ThisEntry);

								if(ThisEntry)
								{
									set(ManVolName, MUIA_String_Contents, ThisEntry->VolName);
									set(ManVolType, MUIA_Cycle_Active, (ThisEntry->Link.ln_Type == LDF_DEVICES));

									set(MainWindow, MUIA_Window_Sleep, TRUE);
									set(ManWindow, MUIA_Window_Title, "Copy entry");
									set(ManWindow, MUIA_Window_Open, TRUE);

									EditEntryPtr	= ThisEntry;
								}
								break;
							}

								// Copy an entry (AppIcons)???

							case ID_APPCOPYENTRY :
							{
								struct	VolEntry	*ThisEntry;


								DoMethod(AppUsedList, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &ThisEntry);

								if(ThisEntry)
								{
									set(AppManTaskName, MUIA_String_Contents, ThisEntry->VolName);

									set(MainWindow, MUIA_Window_Sleep, TRUE);
									set(AppManWindow, MUIA_Window_Title, "Copy entry");
									set(AppManWindow, MUIA_Window_Open, TRUE);

									EditEntryPtr	= ThisEntry;
								}
								break;
							}


								// Remove an entry (Volumes)???

							case ID_REMOVEENTRY :
							{
								struct	VolEntry	*ThisEntry;

								DoMethod(UsedList, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &ThisEntry);

								if(ThisEntry)
								{
									ObtainSemaphore(&FIconSema->FIconSema);

										// Remove entry from listview

									DoMethod(UsedList, MUIM_List_Remove, MUIV_List_Remove_Active);

										// Remove entry from internal list

									Remove(ThisEntry);
									FreeVecPool(FIconSema, ThisEntry);

									FIconSema->VolumeList.lh_Type--;

									ReleaseSemaphore(&FIconSema->FIconSema);
								}
								break;
							}

								// Remove an entry (AppIcons)???

							case ID_APPREMOVEENTRY :
							{
								struct	VolEntry	*ThisEntry;

								DoMethod(AppUsedList, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &ThisEntry);

								if(ThisEntry)
								{
									ObtainSemaphore(&FIconSema->FIconSema);

										// Remove entry from listview

									DoMethod(AppUsedList, MUIM_List_Remove, MUIV_List_Remove_Active);

										// Remove entry from internal list

									Remove(ThisEntry);
									FreeVecPool(FIconSema, ThisEntry);

									FIconSema->AppIconList.lh_Type--;

									ReleaseSemaphore(&FIconSema->FIconSema);
								}
								break;
							}

								// Add an entry (Volumes) ???

							case ID_AVAILLIST :
							case ID_ADDENTRY :
							{
								struct	VolEntry	*ThisEntry;

									// Really get entry ???

								DoMethod(AvailList, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &ThisEntry);

								if(ThisEntry)
									AddNewVolume(ThisEntry->VolName, ThisEntry->Link.ln_Type, NULL);
								break;
							}


								// Add an entry (AppIcon) ???

							case ID_APPAVAILLIST :
							case ID_APPADDENTRY :
							{
								struct	VolEntry	*ThisEntry;

									// Really get entry ???

								DoMethod(AppAvailList, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &ThisEntry);

								if(ThisEntry)
									AddNewVolume(ThisEntry->VolName, FICON_APPICON, NULL);
								break;
							}


								// Manually add an entry (Volumes)???

							case ID_ADDENTRYMAN :
							{
								set(ManVolName, MUIA_String_Contents, "");
								set(ManVolType, MUIA_Cycle_Active, 0);

								set(MainWindow, MUIA_Window_Sleep, TRUE);
								set(ManWindow, MUIA_Window_Title, "Add manually");
								set(ManWindow, MUIA_Window_Open, TRUE);

								EditEntryPtr	= NULL;
								break;
							}


								// Manually add an entry (AppIcons)???

							case ID_APPADDENTRYMAN :
							{
								set(AppManTaskName, MUIA_String_Contents, "");

								set(MainWindow, MUIA_Window_Sleep, TRUE);
								set(AppManWindow, MUIA_Window_Title, "Add manually");
								set(AppManWindow, MUIA_Window_Open, TRUE);

								EditEntryPtr	= NULL;
								break;
							}


								// Rescan list (Volumes)???

							case ID_RESCANLIST :
							{
								struct	VolEntry	*ThisEntry;


									// Remove List from listview

								DoMethod(AvailList, MUIM_List_Clear, NULL);

									// FreeList

								FreeDevVolList(&AvailableList);
								GetDevVolList(&AvailableList);

									// Add list of available entries

								ThisEntry	= (struct VolEntry *)AvailableList.lh_Head;
								while(ThisEntry->Link.ln_Succ)
								{
									DoMethod(AvailList, MUIM_List_InsertSingle, (APTR)ThisEntry, MUIV_List_Insert_Bottom);

									ThisEntry	= (struct VolEntry *)ThisEntry->Link.ln_Succ;
								}
								break;
							}


								// Rescan list (AppIcons)???

							case ID_APPRESCANLIST :
							{
								struct	VolEntry	*ThisEntry;


									// Remove List from listview

								DoMethod(AppAvailList, MUIM_List_Clear, NULL);

									// FreeList

								FreeDevVolList(&AppAvailableList);
								GetTaskList(&AppAvailableList);

									// Add list of available entries

								ThisEntry	= (struct VolEntry *)AppAvailableList.lh_Head;
								while(ThisEntry->Link.ln_Succ)
								{
									DoMethod(AppAvailList, MUIM_List_InsertSingle, (APTR)ThisEntry, MUIV_List_Insert_Bottom);

									ThisEntry	= (struct VolEntry *)ThisEntry->Link.ln_Succ;
								}
								break;
							}



								// Check Edit window


								// New input from IconX/Y gadgets?

							case ID_ICONX :
							case ID_ICONY :
							case ID_APPICONX :
							case ID_APPICONY :
							{
								LONG	PosX,
									PosY;


									// Only do, when PosWindow is open, as values
									// will be obtained on exit, anyway

								if(PosWindow)
								{
									get((ReturnID == ID_ICONX || ReturnID == ID_ICONY) ? IconX : AppIconX, MUIA_String_Integer, &PosX);
									get((ReturnID == ID_ICONX || ReturnID == ID_ICONY) ? IconY : AppIconY, MUIA_String_Integer, &PosY);

									ChangeWindowBox(PosWindow, (PosX < 0 ? PosWindow->WScreen->Width + PosX : PosX), (PosY < 0 ? PosWindow->WScreen->Height + PosY : PosY), PosWindow->Width, PosWindow->Height);
								}
								break;
							}

								// New input from Drawer Windows?

							case ID_WINX :
							case ID_WINY :
							case ID_WINWIDTH :
							case ID_WINHEIGHT :
							{
								ULONG	Left,
									Top,
									Width,
									Height;

								if(DrawerWindow)
								{
									get(WinX, MUIA_String_Integer, &Left);
									get(WinY, MUIA_String_Integer, &Top);
									get(WinWidth, MUIA_String_Integer, &Width);
									get(WinHeight, MUIA_String_Integer, &Height);

									ChangeWindowBox(DrawerWindow, Left, Top, Width, Height);
								}
								break;
							}


								// Open/Close position window ???

							case ID_POSITION :
							case ID_APPPOSITION :
							{
								ULONG	State;

								get((ReturnID == ID_POSITION ? Position : AppPosition), MUIA_Cycle_Active, &State);

								if(State && !PosWindow && EditEntryPtr)
								{
									struct	Screen	*WBScreen;
									LONG		Left,
											Top;

									get((ReturnID == ID_POSITION ? IconX : AppIconX), MUIA_String_Integer, &Left);
									get((ReturnID == ID_POSITION ? IconY : AppIconY), MUIA_String_Integer, &Top);

									if((WBScreen = LockPubScreen(NULL)))
									{
										PosWindow = OpenWindowTags(NULL,
												WA_Left,	(Left < 0 ? WBScreen->Width + Left : Left),
												WA_Top,		(Top < 0 ? WBScreen->Height + Top : Top),
												WA_Width,	(WBScreen->BarLayer->rp->Font->tf_XSize * 4) + 2 + WBScreen->WBorLeft + WBScreen->WBorRight,
												WA_Height,	WBScreen->WBorTop + WBScreen->Font->ta_YSize + 1,
												WA_IDCMP,	IDCMP_CHANGEWINDOW,
												WA_Flags,	WFLG_DRAGBAR|WFLG_RMBTRAP,
												WA_Title,	"Icon",
												WA_PubScreen,	WBScreen,
										TAG_DONE);

										UnlockPubScreen(NULL, WBScreen);

										if(!PosWindow)
										{
											set((ReturnID == ID_POSITION ? Position : AppPosition), MUIA_Cycle_Active, 0);
											DisplayError(ERR_NOMEM, NULL);
										}
									}
								}
								else if(PosWindow)
								{
									CloseWindow(PosWindow);
									PosWindow	= NULL;
								}
								break;
							}

								// Open/Close Drawer Window ???

							case ID_DRAWER :
							{
								ULONG	State;

								get(LookWin, MUIA_Cycle_Active, &State);

								if(State && !DrawerWindow && EditEntryPtr)
								{
									struct	Screen	*WBScreen;
									ULONG		Left,
											Top,
											Width,
											Height;


									get(WinX, MUIA_String_Integer, &Left);
									get(WinY, MUIA_String_Integer, &Top);
									get(WinWidth, MUIA_String_Integer, &Width);
									get(WinHeight, MUIA_String_Integer, &Height);

									if((WBScreen = LockPubScreen(NULL)))
									{
										DrawerWindow = OpenWindowTags(NULL,
												WA_Left,	Left,
												WA_Top,		Top,
												WA_Width,	(Width ? Width: 50),
												WA_Height,	(Height ? Height : 50),
												WA_MaxWidth,	-1,
												WA_MaxHeight,	-1,
												WA_IDCMP,	IDCMP_CHANGEWINDOW,
												WA_Flags,	WFLG_DEPTHGADGET|WFLG_DRAGBAR|WFLG_RMBTRAP|WFLG_SIZEBRIGHT|WFLG_SIZEBBOTTOM,
												WA_Title,	"Drawer window (demo)",
												WA_PubScreen,	WBScreen,
												WA_SizeGadget,	TRUE,
										TAG_DONE);

										UnlockPubScreen(NULL, WBScreen);
										
										if(!DrawerWindow)
										{
											set(LookWin, MUIA_Cycle_Active, 0);
											DisplayError(ERR_NOMEM, NULL);
										}
									}
								}
								else if(DrawerWindow)
								{
									CloseWindow(DrawerWindow);
									DrawerWindow	= NULL;
								}
								break;
							}

								// Ok (Volumes)???

							case ID_EDITOK :
							{
								ULONG	OldType,
									NewName,
									PopAslState;
								BOOL	DoSort	= FALSE;


									// Don`t close window, when FileRequester is open

								get(IconName, MUIA_Popasl_Active, &PopAslState);
								if(!PopAslState)
								{
									set(EditWindow, MUIA_Window_Open, FALSE);
									if(PosWindow)
									{
										CloseWindow(PosWindow);
										PosWindow	= NULL;
									}
									if(DrawerWindow)
									{
										CloseWindow(DrawerWindow);
										DrawerWindow	= NULL;
									}
									set(MainWindow, MUIA_Window_Sleep, FALSE);

										// Copy contents of gadgets to selected entry

									if(EditEntryPtr)
									{
										LONG	Dummy;

										ObtainSemaphore(&FIconSema->FIconSema);

											// Get new settings

										get(VolumeName, MUIA_String_Contents, &Dummy);
										NewName = stricmp(EditEntryPtr->VolName, (char *)Dummy);
										strcpy(EditEntryPtr->VolName, (char *)Dummy);

										get(VolumeType, MUIA_Cycle_Active, &Dummy);
										OldType				= EditEntryPtr->Link.ln_Type;
										EditEntryPtr->Link.ln_Type	= (Dummy ? LDF_DEVICES : LDF_VOLUMES);

										get(IconX, MUIA_String_Integer, &Dummy);
										EditEntryPtr->Left		= Dummy;

										get(IconY, MUIA_String_Integer, &Dummy);
										EditEntryPtr->Top		= Dummy;

										get(IconPos[(UWORD)(EditEntryPtr->Link.ln_Type == LDF_DEVICES)], MUIA_Cycle_Active, &Dummy);
										EditEntryPtr->IconPos	= Dummy;

										get(IconName, MUIA_String_Contents, &Dummy);
										strcpy(EditEntryPtr->IconName, (char *)Dummy);

										get(UseIcon[(UWORD)(EditEntryPtr->Link.ln_Type == LDF_DEVICES)], MUIA_Cycle_Active, &Dummy);
										EditEntryPtr->UseAlt	= Dummy;

										get(UseWindow[(UWORD)(EditEntryPtr->Link.ln_Type == LDF_DEVICES)], MUIA_Cycle_Active, &Dummy);
										EditEntryPtr->UseWin	= Dummy;

										get(WinX, MUIA_String_Integer, &Dummy);
										EditEntryPtr->WinX	= Dummy;

										get(WinY, MUIA_String_Integer, &Dummy);
										EditEntryPtr->WinY	= Dummy;

										get(WinWidth, MUIA_String_Integer, &Dummy);
										EditEntryPtr->WinWidth	= Dummy;

										get(WinHeight, MUIA_String_Integer, &Dummy);
										EditEntryPtr->WinHeight	= Dummy;

										get(UseFlags[(UWORD)(EditEntryPtr->Link.ln_Type == LDF_DEVICES)], MUIA_Cycle_Active, &Dummy);
										EditEntryPtr->UseFlags	= Dummy;

										get(FlagModes, MUIA_Cycle_Active, &Dummy);
										EditEntryPtr->WinFlags	= Dummy;

										if(!strstr(EditEntryPtr->IconName, ".info") && strlen(EditEntryPtr->IconName))
											strcat(EditEntryPtr->IconName, ".info");



											// Type of entry changed ???

										if(OldType != EditEntryPtr->Link.ln_Type)
										{
											Remove(EditEntryPtr);

											if(EditEntryPtr->Link.ln_Type == LDF_DEVICES)
												AddTail(&FIconSema->VolumeList, (struct Node *)EditEntryPtr);
											else
												AddHead(&FIconSema->VolumeList, (struct Node *)EditEntryPtr);

											DoSort	= TRUE;
										}

											// Name changed ???

										if(!DoSort)
											DoSort	= (BOOL)(NewName != 0);

											// Rearrange volume`s/device`s icon

										DskChange(EditEntryPtr);

											// Sort list

										if(DoSort)
										{
											SortList(&FIconSema->VolumeList, TRUE);

												// Remove list

											DoMethod(UsedList, MUIM_List_Clear, NULL);

											EditEntryPtr	= (struct VolEntry *)FIconSema->VolumeList.lh_Head;
											while(EditEntryPtr->Link.ln_Succ)
											{
												DoMethod(UsedList, MUIM_List_InsertSingle, (APTR)EditEntryPtr, MUIV_List_Insert_Bottom);

												EditEntryPtr	= (struct VolEntry *)EditEntryPtr->Link.ln_Succ;
											}
										}
										ReleaseSemaphore(&FIconSema->FIconSema);
									}
									EditEntryPtr	= NULL;
								}
								break;
							}


								// Ok (AppIcons)???

							case ID_APPEDITOK :
							{
								ULONG	NewName,
									PopAslState;
								BOOL	DoSort	= FALSE;


									// Don`t close window, when FileRequester is open

								get(AppIconName, MUIA_Popasl_Active, &PopAslState);
								if(!PopAslState)
								{
									set(AppEditWindow, MUIA_Window_Open, FALSE);
									if(PosWindow)
									{
										CloseWindow(PosWindow);
										PosWindow	= NULL;
									}
									if(DrawerWindow)
									{
										CloseWindow(DrawerWindow);
										DrawerWindow	= NULL;
									}
									set(MainWindow, MUIA_Window_Sleep, FALSE);

										// Copy contents of gadgets to selected entry

									if(EditEntryPtr)
									{
										LONG	Dummy;

										ObtainSemaphore(&FIconSema->FIconSema);

											// Get new settings

										get(AppTaskName, MUIA_String_Contents, &Dummy);
										NewName = stricmp(EditEntryPtr->VolName, (char *)Dummy);
										strcpy(EditEntryPtr->VolName, (char *)Dummy);

										EditEntryPtr->Link.ln_Type	= FICON_APPICON;

										get(AppIconX, MUIA_String_Integer, &Dummy);
										EditEntryPtr->Left		= Dummy;

										get(AppIconY, MUIA_String_Integer, &Dummy);
										EditEntryPtr->Top		= Dummy;

										get(AppIconPos, MUIA_Cycle_Active, &Dummy);
										EditEntryPtr->IconPos	= Dummy;

										get(AppIconName, MUIA_String_Contents, &Dummy);
										strcpy(EditEntryPtr->IconName, (char *)Dummy);

										get(AppUseIcon, MUIA_Cycle_Active, &Dummy);
										EditEntryPtr->UseAlt	= Dummy;

										if(!strstr(EditEntryPtr->IconName, ".info") && strlen(EditEntryPtr->IconName))
											strcat(EditEntryPtr->IconName, ".info");

											// Name changed ???

										if(!DoSort)
											DoSort	= (BOOL)(NewName != 0);

											// Sort list

										if(DoSort)
										{
											SortList(&FIconSema->AppIconList, TRUE);

												// Remove list

											DoMethod(AppUsedList, MUIM_List_Clear, NULL);

											EditEntryPtr	= (struct VolEntry *)FIconSema->AppIconList.lh_Head;
											while(EditEntryPtr->Link.ln_Succ)
											{
												DoMethod(AppUsedList, MUIM_List_InsertSingle, (APTR)EditEntryPtr, MUIV_List_Insert_Bottom);

												EditEntryPtr	= (struct VolEntry *)EditEntryPtr->Link.ln_Succ;
											}
										}
										ReleaseSemaphore(&FIconSema->FIconSema);
									}
									EditEntryPtr	= NULL;
								}
								break;
							}

								// Cancel (Volumes/AppIcons)???

							case ID_EDITCANCEL :
							case ID_APPEDITCANCEL :
							{
								ULONG	PopAslState;

									// Don`t close window, when FileRequester is open

								get(IconName, MUIA_Popasl_Active, &PopAslState);
								if(!PopAslState)
								{
									set(EditWindow, MUIA_Window_Open, FALSE);
									set(AppEditWindow, MUIA_Window_Open, FALSE);
									if(PosWindow)
									{
										CloseWindow(PosWindow);
										PosWindow	= NULL;
									}
									if(DrawerWindow)
									{
										CloseWindow(DrawerWindow);
										DrawerWindow	= NULL;
									}
									set(MainWindow, MUIA_Window_Sleep, FALSE);
								}
								EditEntryPtr	= NULL;
								break;
							}



								// Check man window (Volumes)

							case ID_MANOK :
							{
								char			*VolName;
								ULONG			Type;

								set(ManWindow, MUIA_Window_Open, FALSE);
								set(MainWindow, MUIA_Window_Sleep, FALSE);


								get(ManVolName, MUIA_String_Contents, &VolName);
								get(ManVolType, MUIA_Cycle_Active, &Type);
								Type	= (Type ? LDF_DEVICES : LDF_VOLUMES);

								AddNewVolume(VolName, Type, EditEntryPtr);
								EditEntryPtr	= NULL;
								break;
							}

								// Check man window (AppIcons)

							case ID_APPMANOK :
							{
								char			*VolName;

								set(AppManWindow, MUIA_Window_Open, FALSE);
								set(MainWindow, MUIA_Window_Sleep, FALSE);


								get(AppManTaskName, MUIA_String_Contents, &VolName);

								AddNewVolume(VolName, FICON_APPICON, EditEntryPtr);
								EditEntryPtr	= NULL;
								break;
							}

							case ID_MANCANCEL :
							case ID_APPMANCANCEL :
							{
								set(ManWindow, MUIA_Window_Open, FALSE);
								set(AppManWindow, MUIA_Window_Open, FALSE);
								set(MainWindow, MUIA_Window_Sleep, FALSE);
								EditEntryPtr	= NULL;
								break;
							}
						}


						if(GoOn && MySig)
						{
							if(PosWindow)
								MySig	|= (1 << PosWindow->UserPort->mp_SigBit);

							if(DrawerWindow)
								MySig	|= (1 << DrawerWindow->UserPort->mp_SigBit);

							MySig	= Wait(MySig | SIGBREAKF_CTRL_F);


								// Server snapped icon?

							if(MySig & SIGBREAKF_CTRL_F)
							{
								struct	VolEntry	*ThisEntry;

									// Entry being displayed?

								if(EditEntryPtr)
								{
									set(IconPos[0], MUIA_Cycle_Active, EditEntryPtr->IconPos);
									set(IconPos[1], MUIA_Cycle_Active, EditEntryPtr->IconPos);
									set(IconX, MUIA_String_Integer, EditEntryPtr->Left);
									set(IconX, MUIA_Disabled, (EditEntryPtr->IconPos != MODE_USE));
									set(IconY, MUIA_String_Integer, EditEntryPtr->Top);
									set(IconY, MUIA_Disabled, (EditEntryPtr->IconPos != MODE_USE));
									set(Position, MUIA_Cycle_Active, 0);
									set(Position, MUIA_Disabled, (EditEntryPtr->IconPos != MODE_USE));

									if(PosWindow)
										CloseWindow(PosWindow);
									PosWindow	= NULL;
								}

									// Remove entries from listview (Used)

								DoMethod(UsedList, MUIM_List_Clear, NULL);

									// Sort the list again

								SortList(&FIconSema->VolumeList, TRUE);

									// Readd list

								ThisEntry	= (struct VolEntry *)FIconSema->VolumeList.lh_Head;
								while(ThisEntry->Link.ln_Succ)
								{
									DoMethod(UsedList, MUIM_List_InsertSingle, (APTR)ThisEntry, MUIV_List_Insert_Bottom);

									ThisEntry	= (struct VolEntry *)ThisEntry->Link.ln_Succ;
								}
							}

								// Check for action on PosWindow

							if(PosWindow && (MySig & (1 << PosWindow->UserPort->mp_SigBit)))
							{
								struct	IntuiMessage	*MyMsg;
								ULONG			MsgClass;
								LONG			OldX,
											OldY;


								while((MyMsg = (struct IntuiMessage *)GetMsg(PosWindow->UserPort)))
								{
									MsgClass	= MyMsg->Class;

									ReplyMsg((struct Message *)MyMsg);

									if(MsgClass == IDCMP_CHANGEWINDOW)
									{
											// Get old position

										get(IconX, MUIA_String_Integer, &OldX);
										get(IconY, MUIA_String_Integer, &OldY);

										set(IconX, MUIA_String_Integer, (OldX < 0 ? PosWindow->LeftEdge - PosWindow->WScreen->Width : PosWindow->LeftEdge));
										set(IconY, MUIA_String_Integer, (OldY < 0 ? PosWindow->TopEdge - PosWindow->WScreen->Height : PosWindow->TopEdge));

										get(AppIconX, MUIA_String_Integer, &OldX);
										get(AppIconY, MUIA_String_Integer, &OldY);

										set(AppIconX, MUIA_String_Integer, (OldX < 0 ? PosWindow->LeftEdge - PosWindow->WScreen->Width : PosWindow->LeftEdge));
										set(AppIconY, MUIA_String_Integer, (OldY < 0 ? PosWindow->TopEdge - PosWindow->WScreen->Height : PosWindow->TopEdge));
									}
								}
							}

								// Check for action on DrawerWindow

							if(DrawerWindow && (MySig & (1 << DrawerWindow->UserPort->mp_SigBit)))
							{
								struct	IntuiMessage	*MyMsg;
								ULONG	MsgClass;

								while((MyMsg = (struct IntuiMessage *)GetMsg(DrawerWindow->UserPort)))
								{
									MsgClass	= MyMsg->Class;

									ReplyMsg((struct Message *)MyMsg);

									if(MsgClass == IDCMP_CHANGEWINDOW)
									{
										set(WinX, MUIA_String_Integer, DrawerWindow->LeftEdge);
										set(WinY, MUIA_String_Integer, DrawerWindow->TopEdge);
										set(WinWidth, MUIA_String_Integer, DrawerWindow->Width);
										set(WinHeight, MUIA_String_Integer, DrawerWindow->Height);
									}
								}
							}
						}
					}

					if(PosWindow)
						CloseWindow(PosWindow);
				}

				RemoveApp();

					// Free BackUp lists

				FreeDevVolList(&BackUpVolList);
				FreeDevVolList(&BackUpAppList);

					// Free list of available volumes

				FreeDevVolList(&AvailableList);

					// Free list of available applications

				FreeDevVolList(&AppAvailableList);
			}

			RemoveFIconSema(FIconSema);
		}
	}


		// Close libs

	CloseAll();


		// Flush memory when requested

	if(FlushMemory)
	{
		APTR	FlushPtr;
		int	i;

		for(i = 0; i < 10; i++)
		{
			if((FlushPtr = AllocMem(0x1DCD6500, MEMF_PUBLIC)))
				FreeMem(FlushPtr, 0x1DCD6500);
		}
	}

		// Send back WBStartUp Message

	if(WBenchMsg)
	{
		Forbid();
		ReplyMsg((struct Message *)WBenchMsg);
	}
	return(0);
}






/**********************************************************************/
/*                        Functionreplacements                        */
/**********************************************************************/
void chkabort(void){;}
void __stdargs _XCEXIT(LONG Val){;}




/**********************************************************************/
/*                           Open libraries                           */
/**********************************************************************/
static BOOL OpenAll(void)
{
	if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37)))
	{
		DisplayError(ERR_OPEN, (ULONG)"intuition.library", 37);
		return(FALSE);
	}

	if(!(MUIMasterBase = OpenLibrary("muimaster.library", 7)))
	{
		DisplayError(ERR_OPEN, (ULONG)"muimaster.library", 7);
		return(FALSE);
	}

	if(!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37)))
	{
		DisplayError(ERR_OPEN, (ULONG)"dos.library", 37);
		return(FALSE);
	}

	if(!(IconBase = OpenLibrary("icon.library", 37)))
	{
		DisplayError(ERR_OPEN, (ULONG)"icon.library", 37);
		return(FALSE);
	}

	if(!(UtilityBase = OpenLibrary("utility.library", 37)))
	{
		DisplayError(ERR_OPEN, (ULONG)"utility.library", 37);
		return(FALSE);
	}

	if(!(IFFParseBase = OpenLibrary("iffparse.library", 37)))
	{
		DisplayError(ERR_OPEN, (ULONG)"iffparse.library", 37);
		return(FALSE);
	}

	if(!(AslBase = OpenLibrary("asl.library", 36)))
	{
		DisplayError(ERR_OPEN, (ULONG)"asl.library", 36);
		return(FALSE);
	}

	if(!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 37)))
	{
		DisplayError(ERR_OPEN, (ULONG)"graphics.library", 37);
		return(FALSE);
	}

	return(TRUE);
}








/**********************************************************************/
/*                          Close libraries                           */
/**********************************************************************/
static void CloseAll(void)
{
	CloseLibrary(MUIMasterBase);
	CloseLibrary((struct Library *)GfxBase);
	CloseLibrary(AslBase);
	CloseLibrary(IFFParseBase);
	CloseLibrary(UtilityBase);
	CloseLibrary(IconBase);
	CloseLibrary((struct Library *)DOSBase);
	CloseLibrary((struct Library *)IntuitionBase);
}







/**********************************************************************/
/*                         Create application                         */
/**********************************************************************/
static BOOL InitApp(void)
{
		// Init list, in case the App can not be created

	NewList(&AvailableList);

		// Create the Application window

	AppObject	= ApplicationObject,
				MUIA_Application_Title,		"ForceIcon",
				MUIA_Application_Version,	MUIVERS,
				MUIA_Application_Copyright,	"©1993/94 Kai Iske",
				MUIA_Application_Author,	"Kai Iske",
				MUIA_Application_Description,	"Forces Disk.info to image/position",
				MUIA_Application_Base,		"FIcon",
				MUIA_Application_SingleTask,	TRUE,
				MUIA_Application_DiskObject,	DObj	= GetDiskObjectNew("PROGDIR:ForceIcon"),
				MUIA_Application_HelpFile,	"ForceIcon.guide",

			// Now head for the main window

		SubWindow, MainWindow =	WindowObject,
						MUIA_Window_Title,	"ForceIcon "REVISION" - "REVDATE,
						MUIA_Window_ID,		'FIMW',
						MUIA_Window_SizeGadget,	TRUE,
						MUIA_Window_Menu,	&MainMenuDef,
						MUIA_HelpNode,		NODE_MAIN,

				// Do the gadgets

			WindowContents, VGroup,

				Child, RegisterGroup(MainWinPageTitles),
					MUIA_Register_Frame, TRUE,


					Child, VGroup, // Volume group

							// Columns of input

						Child, ColGroup(2),

								// Create left column

							Child, VGroup,
								MUIA_HelpNode,	NODE_LEFT,
								GroupFrameT("Used volumes/devices"),


									// Create ListView

								Child, UsedList		=	ListviewObject,
													MUIA_Listview_Input,		TRUE,
													MUIA_Listview_List,		ListObject, InputListFrame,
														MUIA_Background,		MUII_ListBack,
														MUIA_List_Format,		"COL=0",
														MUIA_List_DisplayHook,		&DispViewHook,
													End,
												End,

								Child, EditEntry	=	TextObject, ButtonFrame,
													MUIA_Text_Contents,	"Edit entry...",
													MUIA_Text_PreParse,	"\33c",
													MUIA_Background,	MUII_ButtonBack,
													MUIA_InputMode,		MUIV_InputMode_RelVerify,
													MUIA_Text_HiChar,	'E',
													MUIA_ControlChar,	'e',
													MUIA_Disabled,		TRUE,
												End,

								Child, CopyEntry	=	TextObject, ButtonFrame,
													MUIA_Text_Contents,	"Copy entry...",
													MUIA_Text_PreParse,	"\33c",
													MUIA_Background,	MUII_ButtonBack,
													MUIA_InputMode,		MUIV_InputMode_RelVerify,
													MUIA_Text_HiChar,	'p',
													MUIA_ControlChar,	'p',
													MUIA_Disabled,		TRUE,
												End,

								Child, RemoveEntry	=	TextObject, ButtonFrame,
													MUIA_Text_Contents,	"Remove entry",
													MUIA_Text_PreParse,	"\33c",
													MUIA_Background,	MUII_ButtonBack,
													MUIA_InputMode,		MUIV_InputMode_RelVerify,
													MUIA_Text_HiChar,	'R',
													MUIA_ControlChar,	'r',
													MUIA_Disabled,		TRUE,
												End,
							End, // First column


								// Create right column

							Child, VGroup,
								MUIA_HelpNode,	NODE_RIGHT,
								GroupFrameT("Available volumes/devices"),

									// Create ListView

								Child, AvailList	=	ListviewObject,
													MUIA_Listview_Input,		TRUE,
													MUIA_Listview_List,		ListObject, InputListFrame,
														MUIA_Background,		MUII_ListBack,
														MUIA_List_Format,		"COL=0",
														MUIA_List_DisplayHook,		&DispViewHook,
													End,
												End,

								Child, AddEntry		=	TextObject, ButtonFrame,
													MUIA_Text_Contents,	"Add entry",
													MUIA_Text_PreParse,	"\33c",
													MUIA_Background,	MUII_ButtonBack,
													MUIA_InputMode,		MUIV_InputMode_RelVerify,
													MUIA_Text_HiChar,	'd',
													MUIA_ControlChar,	'd',
													MUIA_Disabled,		TRUE,
												End,

								Child, AddEntryMan	=	TextObject, ButtonFrame,
													MUIA_Text_Contents,	"Add manually...",
													MUIA_Text_PreParse,	"\33c",
													MUIA_Background,	MUII_ButtonBack,
													MUIA_InputMode,		MUIV_InputMode_RelVerify,
													MUIA_Text_HiChar,	'm',
													MUIA_ControlChar,	'm',
												End,

								Child, RescanList	=	TextObject, ButtonFrame,
													MUIA_Text_Contents,	"Rescan list",
													MUIA_Text_PreParse,	"\33c",
													MUIA_Background,	MUII_ButtonBack,
													MUIA_InputMode,		MUIV_InputMode_RelVerify,
													MUIA_Text_HiChar,	'l',
													MUIA_ControlChar,	'l',
												End,
							End, // Second column
						End, // Columns
					End, // Volume/Device Page


					Child, VGroup, // AppIcon group

							// Columns of input

						Child, ColGroup(2),

								// Create left column

							Child, VGroup,
								MUIA_HelpNode,	NODE_LEFT,
								GroupFrameT("Used applications"),


									// Create ListView

								Child, AppUsedList	=	ListviewObject,
													MUIA_Listview_Input,		TRUE,
													MUIA_Listview_List,		ListObject, InputListFrame,
														MUIA_Background,		MUII_ListBack,
														MUIA_List_Format,		"COL=0",
														MUIA_List_DisplayHook,		&DispViewHook,
													End,
												End,

								Child, AppEditEntry	=	TextObject, ButtonFrame,
													MUIA_Text_Contents,	"Edit entry...",
													MUIA_Text_PreParse,	"\33c",
													MUIA_Background,	MUII_ButtonBack,
													MUIA_InputMode,		MUIV_InputMode_RelVerify,
													MUIA_Text_HiChar,	'E',
													MUIA_ControlChar,	'e',
													MUIA_Disabled,		TRUE,
												End,

								Child, AppCopyEntry	=	TextObject, ButtonFrame,
													MUIA_Text_Contents,	"Copy entry...",
													MUIA_Text_PreParse,	"\33c",
													MUIA_Background,	MUII_ButtonBack,
													MUIA_InputMode,		MUIV_InputMode_RelVerify,
													MUIA_Text_HiChar,	'p',
													MUIA_ControlChar,	'p',
													MUIA_Disabled,		TRUE,
												End,

								Child, AppRemoveEntry	=	TextObject, ButtonFrame,
													MUIA_Text_Contents,	"Remove entry",
													MUIA_Text_PreParse,	"\33c",
													MUIA_Background,	MUII_ButtonBack,
													MUIA_InputMode,		MUIV_InputMode_RelVerify,
													MUIA_Text_HiChar,	'R',
													MUIA_ControlChar,	'r',
													MUIA_Disabled,		TRUE,
												End,
							End, // First column


								// Create right column

							Child, VGroup,
								MUIA_HelpNode,	NODE_RIGHT,
								GroupFrameT("Available applications"),

									// Create ListView

								Child, AppAvailList	=	ListviewObject,
													MUIA_Listview_Input,		TRUE,
													MUIA_Listview_List,		ListObject, InputListFrame,
														MUIA_Background,		MUII_ListBack,
														MUIA_List_Format,		"COL=0",
														MUIA_List_DisplayHook,		&DispViewHook,
													End,
												End,

								Child, AppAddEntry	=	TextObject, ButtonFrame,
													MUIA_Text_Contents,	"Add entry",
													MUIA_Text_PreParse,	"\33c",
													MUIA_Background,	MUII_ButtonBack,
													MUIA_InputMode,		MUIV_InputMode_RelVerify,
													MUIA_Text_HiChar,	'd',
													MUIA_ControlChar,	'd',
													MUIA_Disabled,		TRUE,
												End,

								Child, AppAddEntryMan	=	TextObject, ButtonFrame,
													MUIA_Text_Contents,	"Add manually...",
													MUIA_Text_PreParse,	"\33c",
													MUIA_Background,	MUII_ButtonBack,
													MUIA_InputMode,		MUIV_InputMode_RelVerify,
													MUIA_Text_HiChar,	'm',
													MUIA_ControlChar,	'm',
												End,

								Child, AppRescanList	=	TextObject, ButtonFrame,
													MUIA_Text_Contents,	"Rescan list",
													MUIA_Text_PreParse,	"\33c",
													MUIA_Background,	MUII_ButtonBack,
													MUIA_InputMode,		MUIV_InputMode_RelVerify,
													MUIA_Text_HiChar,	'l',
													MUIA_ControlChar,	'l',
												End,
							End, // Second column
						End, // Columns
					End, // AppIcon Page
				End, // Page group


				Child, VSpace(1),

					// Control group

				Child, VGroup,

						// Create control gadgets

					Child, HGroup, MUIA_Group_SameWidth, TRUE,

						Child, SaveObj		=	TextObject, ButtonFrame,
											MUIA_Text_Contents,	"Save",
											MUIA_Text_PreParse,	"\33c",
											MUIA_Background,	MUII_ButtonBack,
											MUIA_InputMode,		MUIV_InputMode_RelVerify,
											MUIA_Text_HiChar,	'S',
											MUIA_ControlChar,	's',
										End,

						Child, UseObj		=	TextObject, ButtonFrame,
											MUIA_Text_Contents,	"Use",
											MUIA_Text_PreParse,	"\33c",
											MUIA_Background,	MUII_ButtonBack,
											MUIA_InputMode,		MUIV_InputMode_RelVerify,
											MUIA_Text_HiChar,	'U',
											MUIA_ControlChar,	'u',
										End,

						Child, HideObj		=	TextObject, ButtonFrame,
											MUIA_Text_Contents,	"Cancel",
											MUIA_Text_PreParse,	"\33c",
											MUIA_Background,	MUII_ButtonBack,
											MUIA_InputMode,		MUIV_InputMode_RelVerify,
											MUIA_Text_HiChar,	'C',
											MUIA_ControlChar,	'c',
										End,
					End, // Control panel
				End, // Last group
			End, // window contents
		End, // Main window






			// Head for Editwindow

		SubWindow, EditWindow = WindowObject,
						MUIA_Window_Title,	"Edit entry",
						MUIA_Window_ID,		'FIEW',
						MUIA_Window_SizeGadget,	TRUE,
						MUIA_Window_NoMenus,	TRUE,
						MUIA_HelpNode,		NODE_EDIT,

			WindowContents, VGroup,

					// Volume group

				Child, VGroup, GroupFrameT("Entry type/name"), MUIA_Group_SameWidth, TRUE,
					Child, ColGroup(2),
						Child, KeyLabel1("Volume", 'V'),
						Child, VolumeName	=	StringObject, StringFrame,
											MUIA_String_Contents,	"",
											MUIA_String_MaxLen,	128,
											MUIA_String_Format,	MUIV_String_Format_Left,
											MUIA_String_BufferPos,	0,
											MUIA_String_Reject,	":/",
											MUIA_ControlChar,	'v',
										End,

						Child, KeyLabel1("Type", 'e'),
						Child, VolumeType	=	KeyCycle(TypeEntries, 'e'),
					End,
				End, // Volume group


				Child, ColGroup(2),
						// Position group

					Child, VGroup, GroupFrameT("Position settings"), MUIA_Group_SameWidth, TRUE,

						Child, ColGroup(2),

							Child, KeyLabel1("IconPos", 's'),
							Child, IconPosGroup = PageGroup,

								Child, IconPos[0] =	CycleObject, ButtonFrame,
													MUIA_Cycle_Active,	0,
													MUIA_Cycle_Entries,	IconModeEntriesVol,
													MUIA_ControlChar,	's',
											End,

								Child, IconPos[1] =	CycleObject, ButtonFrame,
													MUIA_Cycle_Active,	0,
													MUIA_Cycle_Entries,	IconModeEntriesDev,
													MUIA_ControlChar,	's',
											End,
							End,

							Child, KeyLabel1("Current X", 'X'),
							Child, HGroup,
								Child, IconX	=	StringObject, StringFrame,
												MUIA_String_Contents,	"",
												MUIA_String_MaxLen,	7,
												MUIA_String_Format,	MUIV_String_Format_Center,
												MUIA_String_BufferPos,	1,
												MUIA_String_Integer,	TRUE,
												MUIA_ControlChar,	'x',
											End,

								Child, KeyLabel1("Current Y", 'Y'),
								Child, IconY	=	StringObject, StringFrame,
												MUIA_String_Contents,	"",
												MUIA_String_MaxLen,	7,
												MUIA_String_Format,	MUIV_String_Format_Center,
												MUIA_String_BufferPos,	1,
												MUIA_String_Integer,	TRUE,
												MUIA_ControlChar,	'y',
											End,
							End,

							Child, KeyLabel1("Position", 'P'),
							Child, Position	=	CycleObject, ButtonFrame,
												MUIA_Cycle_Active,	0,
												MUIA_Cycle_Entries,	PositionEntries,
												MUIA_ControlChar,	'p',
										End,
						End,
					End, // position group



						// Icon group

					Child, VGroup, GroupFrameT("Icon settings"), MUIA_Group_SameWidth, TRUE,

						Child, VSpace(0),
						Child, ColGroup(2),

							Child, KeyLabel1("Use Icon", 'U'),
							Child, UseIconGroup	= PageGroup,

								Child, UseIcon[0] =	CycleObject, ButtonFrame,
													MUIA_Cycle_Active,	0,
													MUIA_Cycle_Entries,	ModeEntriesVol,
													MUIA_ControlChar,	'u',
											End,

								Child, UseIcon[1] =	CycleObject, ButtonFrame,
													MUIA_Cycle_Active,	0,
													MUIA_Cycle_Entries,	ModeEntriesDev,
													MUIA_ControlChar,	'u',
											End,
							End,


							Child, KeyLabel1("Icon", 'I'),
							Child, IconName			= PopaslObject,
												MUIA_Popstring_String,		KeyString(0, 254, 'i'),
												MUIA_Popstring_Button,		PopButton(MUII_PopFile),
												MUIA_Popasl_Type,		ASL_FileRequest,
												ASLFR_TitleText,		"Please select an icon...",
											End,
						End,
						Child, VSpace(0),
					End, // Icon group
				End,

					// Create window group

				Child, VGroup, GroupFrameT("Window settings"), MUIA_Group_SameWidth, TRUE,

					Child, ColGroup(2),

						Child, KeyLabel1("Use window", 'd'),
						Child, UseWindowGroup	= PageGroup,

							Child, UseWindow[0] =	CycleObject, ButtonFrame,
												MUIA_Cycle_Active,	0,
												MUIA_Cycle_Entries,	ModeEntriesVol,
												MUIA_ControlChar,	'd',
										End,

							Child, UseWindow[1] =	CycleObject, ButtonFrame,
												MUIA_Cycle_Active,	0,
												MUIA_Cycle_Entries,	ModeEntriesDev,
												MUIA_ControlChar,	'd',
										End,
						End,


						Child, KeyLabel2("Left", 'L'),
						Child, HGroup,
							Child, WinX	=	StringObject, StringFrame,
											MUIA_String_Contents,	"",
											MUIA_String_MaxLen,	5,
											MUIA_String_Format,	MUIV_String_Format_Center,
											MUIA_String_BufferPos,	1,
											MUIA_String_Integer,	TRUE,
											MUIA_ControlChar,	'l',
										End,

							Child, KeyLabel1("Top", 'T'),
							Child, WinY	=	StringObject, StringFrame,
											MUIA_String_Contents,	"",
											MUIA_String_MaxLen,	5,
											MUIA_String_Format,	MUIV_String_Format_Center,
											MUIA_String_BufferPos,	1,
											MUIA_String_Integer,	TRUE,
											MUIA_ControlChar,	't',
										End,

							Child, KeyLabel2("Width", 'W'),
							Child, WinWidth	=	StringObject, StringFrame,
											MUIA_String_Contents,	"",
											MUIA_String_MaxLen,	5,
											MUIA_String_Format,	MUIV_String_Format_Center,
											MUIA_String_BufferPos,	1,
											MUIA_String_Integer,	TRUE,
											MUIA_ControlChar,	'h',
										End,

							Child, KeyLabel1("Height", 'H'),
							Child, WinHeight =	StringObject, StringFrame,
											MUIA_String_Contents,	"",
											MUIA_String_MaxLen,	5,
											MUIA_String_Format,	MUIV_String_Format_Center,
											MUIA_String_BufferPos,	1,
											MUIA_String_Integer,	TRUE,
											MUIA_ControlChar,	'w',
										End,
						End,

						Child, KeyLabel1("Window", 'n'),
						Child, LookWin =	CycleObject, ButtonFrame,
											MUIA_Cycle_Active,	0,
											MUIA_Cycle_Entries,	LookWinEntries,
											MUIA_ControlChar,	'n',
									End,



						Child, KeyLabel1("Use flags", 'f'),
						Child, UseFlagsGroup	= PageGroup,

							Child, UseFlags[0] =	CycleObject, ButtonFrame,
												MUIA_Cycle_Active,	0,
												MUIA_Cycle_Entries,	ModeEntriesVol,
												MUIA_ControlChar,	'f',
										End,

							Child, UseFlags[1] =	CycleObject, ButtonFrame,
												MUIA_Cycle_Active,	0,
												MUIA_Cycle_Entries,	ModeEntriesDev,
												MUIA_ControlChar,	'f',
										End,
						End,

						Child, KeyLabel1("Flags", 'g'),
						Child, FlagModes	=	CycleObject, ButtonFrame,
											MUIA_Cycle_Active,	0,
											MUIA_Cycle_Entries,	FlagModesEntries,
											MUIA_ControlChar,	'g',
									End,
					End,
				End, // window group



				Child, VSpace(1),

					// Create control gadgets

				Child, HGroup, MUIA_Group_SameWidth, TRUE,

					Child, EditOkObj	=	TextObject, ButtonFrame,
										MUIA_Text_Contents,	"Ok",
										MUIA_Text_PreParse,	"\33c",
										MUIA_Background,	MUII_ButtonBack,
										MUIA_InputMode,		MUIV_InputMode_RelVerify,
										MUIA_Text_HiChar,	'O',
										MUIA_ControlChar,	'o',
									End,

					Child, EditCancelObj	=	TextObject, ButtonFrame,
										MUIA_Text_Contents,	"Cancel",
										MUIA_Text_PreParse,	"\33c",
										MUIA_Background,	MUII_ButtonBack,
										MUIA_InputMode,		MUIV_InputMode_RelVerify,
										MUIA_Text_HiChar,	'C',
										MUIA_ControlChar,	'c',
									End,
				End, // Control gadgets
			End, // Edit contents
		End, // AppIcon Edit window




			// Head for AppIcon Editwindow

		SubWindow, AppEditWindow = WindowObject,
						MUIA_Window_Title,	"Edit entry",
						MUIA_Window_ID,		'FIAE',
						MUIA_Window_SizeGadget,	TRUE,
						MUIA_Window_NoMenus,	TRUE,
						MUIA_HelpNode,		NODE_EDIT,

			WindowContents, VGroup,

					// Taskname group

				Child, VGroup, GroupFrameT("Entry name"), MUIA_Group_SameWidth, TRUE,
					Child, ColGroup(2),
						Child, KeyLabel1("Task", 'T'),
						Child, AppTaskName =	StringObject, StringFrame,
											MUIA_String_Contents,	"",
											MUIA_String_MaxLen,	128,
											MUIA_String_Format,	MUIV_String_Format_Left,
											MUIA_String_BufferPos,	0,
											MUIA_ControlChar,	't',
										End,
					End,
				End, // Taskname group


				Child, ColGroup(2),
						// Position group

					Child, VGroup, GroupFrameT("Position settings"), MUIA_Group_SameWidth, TRUE,

						Child, ColGroup(2),

							Child, KeyLabel1("IconPos", 's'),
							Child, AppIconPos =	CycleObject, ButtonFrame,
												MUIA_Cycle_Active,	0,
												MUIA_Cycle_Entries,	ModeEntriesDev,
												MUIA_ControlChar,	's',
										End,

							Child, KeyLabel1("Current X", 'X'),
							Child, HGroup,
								Child, AppIconX	=	StringObject, StringFrame,
												MUIA_String_Contents,	"",
												MUIA_String_MaxLen,	7,
												MUIA_String_Format,	MUIV_String_Format_Center,
												MUIA_String_BufferPos,	1,
												MUIA_String_Integer,	TRUE,
												MUIA_ControlChar,	'x',
											End,

								Child, KeyLabel1("Current Y", 'Y'),
								Child, AppIconY	=	StringObject, StringFrame,
												MUIA_String_Contents,	"",
												MUIA_String_MaxLen,	7,
												MUIA_String_Format,	MUIV_String_Format_Center,
												MUIA_String_BufferPos,	1,
												MUIA_String_Integer,	TRUE,
												MUIA_ControlChar,	'y',
											End,
							End,

							Child, KeyLabel1("Position", 'P'),
							Child, AppPosition =	CycleObject, ButtonFrame,
												MUIA_Cycle_Active,	0,
												MUIA_Cycle_Entries,	PositionEntries,
												MUIA_ControlChar,	'p',
										End,
						End,
					End, // position group



						// Icon group

					Child, VGroup, GroupFrameT("Icon settings"), MUIA_Group_SameWidth, TRUE,

						Child, VSpace(0),
						Child, ColGroup(2),

							Child, KeyLabel1("Use Icon", 'U'),
							Child, AppUseIcon =	CycleObject, ButtonFrame,
												MUIA_Cycle_Active,	0,
												MUIA_Cycle_Entries,	ModeEntriesDev,
												MUIA_ControlChar,	'u',
										End,


							Child, KeyLabel1("Icon", 'I'),
							Child, AppIconName		= PopaslObject,
												MUIA_Popstring_String,		KeyString(0, 254, 'i'),
												MUIA_Popstring_Button,		PopButton(MUII_PopFile),
												MUIA_Popasl_Type,		ASL_FileRequest,
												ASLFR_TitleText,		"Please select an icon...",
											End,
						End,
						Child, VSpace(0),
					End, // Icon group
				End,


				Child, VSpace(1),

					// Create control gadgets

				Child, HGroup, MUIA_Group_SameWidth, TRUE,

					Child, AppEditOkObj	=	TextObject, ButtonFrame,
										MUIA_Text_Contents,	"Ok",
										MUIA_Text_PreParse,	"\33c",
										MUIA_Background,	MUII_ButtonBack,
										MUIA_InputMode,		MUIV_InputMode_RelVerify,
										MUIA_Text_HiChar,	'O',
										MUIA_ControlChar,	'o',
									End,

					Child, AppEditCancelObj	=	TextObject, ButtonFrame,
										MUIA_Text_Contents,	"Cancel",
										MUIA_Text_PreParse,	"\33c",
										MUIA_Background,	MUII_ButtonBack,
										MUIA_InputMode,		MUIV_InputMode_RelVerify,
										MUIA_Text_HiChar,	'C',
										MUIA_ControlChar,	'c',
									End,
				End, // Control gadgets
			End, // Edit contents
		End, // Edit window



			// Head for "manually" window

		SubWindow, ManWindow = WindowObject,
						MUIA_Window_Title,	"",
						MUIA_Window_ID,		'FINW',
						MUIA_Window_SizeGadget,	TRUE,
						MUIA_Window_NoMenus,	TRUE,
						MUIA_HelpNode,		NODE_MANUAL,

			WindowContents, VGroup,

				Child, VGroup, GroupFrameT("Entry type/name"),

						// String gadget

					Child, ColGroup(2),

						Child, KeyLabel1("Volume", 'V'),
						Child, ManVolName	=	StringObject, StringFrame,
										MUIA_String_Contents,	"",
										MUIA_String_MaxLen,	128,
										MUIA_String_Format,	MUIV_String_Format_Left,
										MUIA_String_BufferPos,	1,
										MUIA_String_Reject,	":/",
										MUIA_ControlChar,	'v',
									End,

						Child, KeyLabel1("Type", 'T'),
						Child, ManVolType	=	KeyCycle(TypeEntries, 't'),
					End,
				End,

				Child, VSpace(1),

					// Control gadgets

				Child, HGroup, MUIA_Group_SameWidth, TRUE,

					Child, ManOkObj	=		TextObject, ButtonFrame,
										MUIA_Text_Contents,	"Ok",
										MUIA_Text_PreParse,	"\33c",
										MUIA_Background,	MUII_ButtonBack,
										MUIA_InputMode,		MUIV_InputMode_RelVerify,
										MUIA_Text_HiChar,	'O',
										MUIA_ControlChar,	'o',
									End,

					Child, ManCancelObj	=	TextObject, ButtonFrame,
										MUIA_Text_Contents,	"Cancel",
										MUIA_Text_PreParse,	"\33c",
										MUIA_Background,	MUII_ButtonBack,
										MUIA_InputMode,		MUIV_InputMode_RelVerify,
										MUIA_Text_HiChar,	'C',
										MUIA_ControlChar,	'c',
									End,
				End, // Control gadgets
			End, // Man contents
		End, // Man window


			// Head for "manually" window (AppIcons)

		SubWindow, AppManWindow = WindowObject,
						MUIA_Window_Title,	"",
						MUIA_Window_ID,		'FINW',
						MUIA_Window_SizeGadget,	TRUE,
						MUIA_Window_NoMenus,	TRUE,
						MUIA_HelpNode,		NODE_MANUAL,

			WindowContents, VGroup,

				Child, VGroup, GroupFrameT("Entry type/name"),

						// String gadget

					Child, ColGroup(2),

						Child, KeyLabel1("Taskname", 'T'),
						Child, AppManTaskName	=	StringObject, StringFrame,
										MUIA_String_Contents,	"",
										MUIA_String_MaxLen,	128,
										MUIA_String_Format,	MUIV_String_Format_Left,
										MUIA_String_BufferPos,	1,
										MUIA_String_Reject,	":/",
										MUIA_ControlChar,	't',
									End,
					End,
				End,

				Child, VSpace(1),

					// Control gadgets

				Child, HGroup, MUIA_Group_SameWidth, TRUE,

					Child, AppManOkObj	=	TextObject, ButtonFrame,
										MUIA_Text_Contents,	"Ok",
										MUIA_Text_PreParse,	"\33c",
										MUIA_Background,	MUII_ButtonBack,
										MUIA_InputMode,		MUIV_InputMode_RelVerify,
										MUIA_Text_HiChar,	'O',
										MUIA_ControlChar,	'o',
									End,

					Child, AppManCancelObj	=	TextObject, ButtonFrame,
										MUIA_Text_Contents,	"Cancel",
										MUIA_Text_PreParse,	"\33c",
										MUIA_Background,	MUII_ButtonBack,
										MUIA_InputMode,		MUIV_InputMode_RelVerify,
										MUIA_Text_HiChar,	'C',
										MUIA_ControlChar,	'c',
									End,
				End, // Control gadgets
			End, // Man contents
		End, // Man window
	End; // End application

		// Appobject there and got a list of available entries ???

	if(AppObject && GetDevVolList(&AvailableList) && GetTaskList(&AppAvailableList))
	{
		struct	VolEntry	*ThisEntry;
		int			i;


			// Main window settings


			// SetCycle chain

		DoMethod(MainWindow, MUIM_Window_SetCycleChain,
			UsedList,
			AvailList,
			EditEntry,
			CopyEntry,
			RemoveEntry,
			AddEntry,
			AddEntryMan,
			RescanList,
			AppUsedList,
			AppAvailList,
			AppEditEntry,
			AppCopyEntry,
			AppRemoveEntry,
			AppAddEntry,
			AppAddEntryMan,
			AppRescanList,
			SaveObj,
			UseObj,
			HideObj,
		NULL);

			// Set default object

		set(MainWindow, MUIA_Window_DefaultObject, AvailList);

			// Set notifications

		DoMethod(MainWindow, MUIM_Notify,
			MUIA_Window_CloseRequest,	TRUE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_HIDE);

			// Set IDs for gadgets

		DoMethod(UsedList, MUIM_Notify,
			MUIA_Listview_DoubleClick,	TRUE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_USEDLIST);

		DoMethod(EditEntry, MUIM_Notify,
			MUIA_Pressed,			FALSE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_EDITENTRY);

		DoMethod(CopyEntry, MUIM_Notify,
			MUIA_Pressed,			FALSE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_COPYENTRY);

		DoMethod(RemoveEntry, MUIM_Notify,
			MUIA_Pressed,			FALSE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_REMOVEENTRY);

		DoMethod(AvailList, MUIM_Notify,
			MUIA_Listview_DoubleClick,	TRUE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_AVAILLIST);

		DoMethod(AddEntry, MUIM_Notify,
			MUIA_Pressed,			FALSE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_ADDENTRY);

		DoMethod(AddEntryMan, MUIM_Notify,
			MUIA_Pressed,			FALSE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_ADDENTRYMAN);

		DoMethod(RescanList, MUIM_Notify,
			MUIA_Pressed,			FALSE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_RESCANLIST);

		DoMethod(AppUsedList, MUIM_Notify,
			MUIA_Listview_DoubleClick,	TRUE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_APPUSEDLIST);

		DoMethod(AppEditEntry, MUIM_Notify,
			MUIA_Pressed,			FALSE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_APPEDITENTRY);

		DoMethod(AppCopyEntry, MUIM_Notify,
			MUIA_Pressed,			FALSE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_APPCOPYENTRY);

		DoMethod(AppRemoveEntry, MUIM_Notify,
			MUIA_Pressed,			FALSE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_APPREMOVEENTRY);

		DoMethod(AppAvailList, MUIM_Notify,
			MUIA_Listview_DoubleClick,	TRUE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_APPAVAILLIST);

		DoMethod(AppAddEntry, MUIM_Notify,
			MUIA_Pressed,			FALSE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_APPADDENTRY);

		DoMethod(AppAddEntryMan, MUIM_Notify,
			MUIA_Pressed,			FALSE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_APPADDENTRYMAN);

		DoMethod(AppRescanList, MUIM_Notify,
			MUIA_Pressed,			FALSE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_APPRESCANLIST);

		DoMethod(SaveObj, MUIM_Notify,
			MUIA_Pressed,			FALSE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_SAVE);

		DoMethod(UseObj, MUIM_Notify,
			MUIA_Pressed,			FALSE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_USE);

		DoMethod(HideObj, MUIM_Notify,
			MUIA_Pressed,			FALSE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_HIDE);

			// Set disable notify-hooks

		DoMethod(UsedList, MUIM_Notify,
			MUIA_List_Active,		MUIV_EveryTime,
			AppObject,			3,
			MUIM_CallHook,			&DisableHook, UsedList);


		DoMethod(AvailList, MUIM_Notify,
			MUIA_List_Active,		MUIV_EveryTime,
			AppObject,			3,
			MUIM_CallHook,			&DisableHook, AvailList);

		DoMethod(AppUsedList, MUIM_Notify,
			MUIA_List_Active,		MUIV_EveryTime,
			AppObject,			3,
			MUIM_CallHook,			&DisableHook, AppUsedList);


		DoMethod(AppAvailList, MUIM_Notify,
			MUIA_List_Active,		MUIV_EveryTime,
			AppObject,			3,
			MUIM_CallHook,			&DisableHook, AppAvailList);



			// Edit window settings (Volumes)

			// Set cycle chain

		DoMethod(EditWindow, MUIM_Window_SetCycleChain,
			VolumeName,
			VolumeType,
			IconPos[0],
			IconPos[1],
			IconX,
			IconY,
			Position,
			UseIcon[0],
			UseIcon[1],
			IconName,
			UseWindow[0],
			UseWindow[1],
			WinX,
			WinY,
			WinWidth,
			WinHeight,
			UseFlags[0],
			UseFlags[1],
			FlagModes,
			EditOkObj,
			EditCancelObj,
		NULL);


			// Set notifications

		DoMethod(EditWindow, MUIM_Notify,
			MUIA_Window_CloseRequest,	TRUE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_EDITCANCEL);


		DoMethod(EditOkObj, MUIM_Notify,
			MUIA_Pressed,			FALSE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_EDITOK);

		DoMethod(EditCancelObj, MUIM_Notify,
			MUIA_Pressed,			FALSE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_EDITCANCEL);

		DoMethod(Position, MUIM_Notify,
			MUIA_Cycle_Active,		MUIV_EveryTime,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_POSITION);

		DoMethod(LookWin, MUIM_Notify,
			MUIA_Cycle_Active,		MUIV_EveryTime,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_DRAWER);

		DoMethod(IconX, MUIM_Notify,
			MUIA_String_Acknowledge,	MUIV_EveryTime,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_ICONX);

		DoMethod(IconY, MUIM_Notify,
			MUIA_String_Acknowledge,	MUIV_EveryTime,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_ICONY);

		DoMethod(WinX, MUIM_Notify,
			MUIA_String_Acknowledge,	MUIV_EveryTime,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_WINX);

		DoMethod(WinY, MUIM_Notify,
			MUIA_String_Acknowledge,	MUIV_EveryTime,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_WINY);

		DoMethod(WinWidth, MUIM_Notify,
			MUIA_String_Acknowledge,	MUIV_EveryTime,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_WINWIDTH);

		DoMethod(WinHeight, MUIM_Notify,
			MUIA_String_Acknowledge,	MUIV_EveryTime,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_WINHEIGHT);

		DoMethod(VolumeType, MUIM_Notify,
			MUIA_Cycle_Active,		MUIV_EveryTime,
			IconPosGroup,			3,
			MUIM_Set, MUIA_Group_ActivePage, MUIV_TriggerValue);

		DoMethod(VolumeType, MUIM_Notify,
			MUIA_Cycle_Active,		MUIV_EveryTime,
			AppObject,			2,
			MUIM_CallHook, &PageChangeHook);

		DoMethod(VolumeType, MUIM_Notify,
			MUIA_Cycle_Active,		MUIV_EveryTime,
			UseIconGroup,			3,
			MUIM_Set, MUIA_Group_ActivePage, MUIV_TriggerValue);

		DoMethod(VolumeType, MUIM_Notify,
			MUIA_Cycle_Active,		MUIV_EveryTime,
			UseWindowGroup,			3,
			MUIM_Set, MUIA_Group_ActivePage, MUIV_TriggerValue);

		DoMethod(VolumeType, MUIM_Notify,
			MUIA_Cycle_Active,		MUIV_EveryTime,
			UseFlagsGroup,			3,
			MUIM_Set, MUIA_Group_ActivePage, MUIV_TriggerValue);


		for(i = 0; i < 2; i++)
		{
			DoMethod(IconPos[i], MUIM_Notify,
				MUIA_Cycle_Active,		MUIV_EveryTime,
				AppObject,			3,
				MUIM_CallHook,			&DisableHook, IconPos[i]);


			DoMethod(UseIcon[i], MUIM_Notify,
				MUIA_Cycle_Active,		MUIV_EveryTime,
				AppObject,			3,
				MUIM_CallHook,			&DisableHook, UseIcon[i]);


			DoMethod(UseWindow[i], MUIM_Notify,
				MUIA_Cycle_Active,		MUIV_EveryTime,
				AppObject,			3,
				MUIM_CallHook,			&DisableHook, UseWindow[i]);


			DoMethod(UseFlags[i], MUIM_Notify,
				MUIA_Cycle_Active,		MUIV_EveryTime,
				AppObject,			3,
				MUIM_CallHook,			&DisableHook, UseFlags[i]);
		}




			// Edit window settings (AppIcon)

			// Set cycle chain

		DoMethod(AppEditWindow, MUIM_Window_SetCycleChain,
			AppTaskName,
			AppIconPos,
			AppIconX,
			AppIconY,
			AppPosition,
			AppUseIcon,
			AppIconName,
			AppEditOkObj,
			AppEditCancelObj,
		NULL);


			// Set notifications

		DoMethod(AppEditWindow, MUIM_Notify,
			MUIA_Window_CloseRequest,	TRUE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_APPEDITCANCEL);

		DoMethod(AppEditOkObj, MUIM_Notify,
			MUIA_Pressed,			FALSE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_APPEDITOK);

		DoMethod(AppEditCancelObj, MUIM_Notify,
			MUIA_Pressed,			FALSE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_APPEDITCANCEL);

		DoMethod(AppPosition, MUIM_Notify,
			MUIA_Cycle_Active,		MUIV_EveryTime,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_APPPOSITION);

		DoMethod(AppIconX, MUIM_Notify,
			MUIA_String_Acknowledge,	MUIV_EveryTime,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_APPICONX);

		DoMethod(AppIconY, MUIM_Notify,
			MUIA_String_Acknowledge,	MUIV_EveryTime,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_APPICONY);

		DoMethod(AppIconPos, MUIM_Notify,
			MUIA_Cycle_Active,		MUIV_EveryTime,
			AppObject,			3,
			MUIM_CallHook,			&DisableHook, AppIconPos);

		DoMethod(AppUseIcon, MUIM_Notify,
			MUIA_Cycle_Active,		MUIV_EveryTime,
			AppObject,			3,
			MUIM_CallHook,			&DisableHook, AppUseIcon);






			// Man window settings (Volumes)

			// Set cycle chaing

		DoMethod(ManWindow, MUIM_Window_SetCycleChain,
			ManVolName,
			ManVolType,
			ManOkObj,
			ManCancelObj,
		NULL);


			// Set notifications

		DoMethod(ManWindow, MUIM_Notify,
			MUIA_Window_CloseRequest,	TRUE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_MANCANCEL);


		DoMethod(ManOkObj, MUIM_Notify,
			MUIA_Pressed,			FALSE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_MANOK);


		DoMethod(ManCancelObj, MUIM_Notify,
			MUIA_Pressed,			FALSE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_MANCANCEL);



			// Man window settings (AppIcons)

			// Set cycle chaing

		DoMethod(AppManWindow, MUIM_Window_SetCycleChain,
			AppManTaskName,
			AppManOkObj,
			AppManCancelObj,
		NULL);


			// Set notifications

		DoMethod(AppManWindow, MUIM_Notify,
			MUIA_Window_CloseRequest,	TRUE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_APPMANCANCEL);


		DoMethod(AppManOkObj, MUIM_Notify,
			MUIA_Pressed,			FALSE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_APPMANOK);


		DoMethod(AppManCancelObj, MUIM_Notify,
			MUIA_Pressed,			FALSE,
			AppObject,			2,
			MUIM_Application_ReturnID,	ID_APPMANCANCEL);




			// Add list of used entries

		ObtainSemaphore(&FIconSema->FIconSema);
		ThisEntry	= (struct VolEntry *)FIconSema->VolumeList.lh_Head;

		while(ThisEntry->Link.ln_Succ)
		{
			DoMethod(UsedList, MUIM_List_InsertSingle, (APTR)ThisEntry, MUIV_List_Insert_Bottom);

			ThisEntry	= (struct VolEntry *)ThisEntry->Link.ln_Succ;
		}
		ReleaseSemaphore(&FIconSema->FIconSema);


		ObtainSemaphore(&FIconSema->FIconSema);
		ThisEntry	= (struct VolEntry *)FIconSema->AppIconList.lh_Head;

		while(ThisEntry->Link.ln_Succ)
		{
			DoMethod(AppUsedList, MUIM_List_InsertSingle, (APTR)ThisEntry, MUIV_List_Insert_Bottom);

			ThisEntry	= (struct VolEntry *)ThisEntry->Link.ln_Succ;
		}
		ReleaseSemaphore(&FIconSema->FIconSema);



			// Add list of available entries

		ThisEntry	= (struct VolEntry *)AvailableList.lh_Head;

		while(ThisEntry->Link.ln_Succ)
		{
			DoMethod(AvailList, MUIM_List_InsertSingle, (APTR)ThisEntry, MUIV_List_Insert_Bottom);

			ThisEntry	= (struct VolEntry *)ThisEntry->Link.ln_Succ;
		}



		ThisEntry	= (struct VolEntry *)AppAvailableList.lh_Head;

		while(ThisEntry->Link.ln_Succ)
		{
			DoMethod(AppAvailList, MUIM_List_InsertSingle, (APTR)ThisEntry, MUIV_List_Insert_Bottom);

			ThisEntry	= (struct VolEntry *)ThisEntry->Link.ln_Succ;
		}




			// Open main window

		set(MainWindow, MUIA_Window_Open, TRUE);
	}
	else
	{
		if(MUI_Error() != MUIE_SingleTask)
			DisplayError(ERR_NO_APP, NULL);
	}


	return((BOOL)(AppObject != NULL));
}




/**********************************************************************/
/*                       Remove our application                       */
/**********************************************************************/
static void RemoveApp(void)
{
	if(AppObject)
	{
		set(MainWindow, MUIA_Window_Open, FALSE);
		MUI_DisposeObject(AppObject);
	}

		// Dispose DiskObject

	if(DObj)
		FreeDiskObject(DObj);
}







/**********************************************************************/
/*                          Display function                          */
/**********************************************************************/
static ULONG	__saveds __asm DispViewFunc(register __a0 struct Hook *MyHook, register __a2 char **array, register __a1 struct VolEntry *Data)
{
	static		char	Buffer[140];

	if(Data->Link.ln_Type == LDF_VOLUMES)
	{
		strcpy(Buffer, "\0338");
		strcat(Buffer, Data->VolName);
	}
	else
		strcpy(Buffer, Data->VolName);

	*array		= Buffer;

	return(NULL);
}






/**********************************************************************/
/*                   Hook for setting gadgetstates                    */
/**********************************************************************/
static ULONG	__saveds __asm DisableFunc(register __a0 struct Hook *MyHook, register __a2 APTR Obj, register __a1 APTR *Data)
{
	ULONG	State;

	if(*Data == UsedList)
	{
		get(UsedList, MUIA_List_Active, &State);
		State	= (State == MUIV_List_Active_Off ? TRUE : FALSE);
		set(EditEntry, MUIA_Disabled, State);
		set(CopyEntry, MUIA_Disabled, State);
		set(RemoveEntry, MUIA_Disabled, State);
	}
	else if(*Data == AppUsedList)
	{
		get(AppUsedList, MUIA_List_Active, &State);
		State	= (State == MUIV_List_Active_Off ? TRUE : FALSE);
		set(AppEditEntry, MUIA_Disabled, State);
		set(AppCopyEntry, MUIA_Disabled, State);
		set(AppRemoveEntry, MUIA_Disabled, State);
	}
	else if(*Data == AvailList)
	{
		get(AvailList, MUIA_List_Active, &State);
		State	= (State == MUIV_List_Active_Off ? TRUE : FALSE);
		set(AddEntry, MUIA_Disabled, State);
	}
	else if(*Data == AppAvailList)
	{
		get(AppAvailList, MUIA_List_Active, &State);
		State	= (State == MUIV_List_Active_Off ? TRUE : FALSE);
		set(AppAddEntry, MUIA_Disabled, State);
	}
	else if((*Data == IconPos[0]) || (*Data == IconPos[1]))
	{
		get(*Data, MUIA_Cycle_Active, &State);
		set(IconX, MUIA_Disabled, (State != MODE_USE));
		set(IconY, MUIA_Disabled, (State != MODE_USE));
		set(Position, MUIA_Disabled, (State != MODE_USE));
	}
	else if(*Data == AppIconPos)
	{
		get(*Data, MUIA_Cycle_Active, &State);
		set(AppIconX, MUIA_Disabled, (State != MODE_USE));
		set(AppIconY, MUIA_Disabled, (State != MODE_USE));
		set(AppPosition, MUIA_Disabled, (State != MODE_USE));
	}
	else if((*Data == UseIcon[0]) || (*Data == UseIcon[1]))
	{
		get(*Data, MUIA_Cycle_Active, &State);
		set(IconName, MUIA_Disabled, (State != MODE_USE));
	}
	else if(*Data == AppUseIcon)
	{
		get(AppUseIcon, MUIA_Cycle_Active, &State);
		set(AppIconName, MUIA_Disabled, (State != MODE_USE));
	}
	else if((*Data == UseWindow[0]) || (*Data == UseWindow[1]))
	{
		get(*Data, MUIA_Cycle_Active, &State);
		set(WinX, MUIA_Disabled, (State != MODE_USE));
		set(WinY, MUIA_Disabled, (State != MODE_USE));
		set(WinWidth, MUIA_Disabled, (State != MODE_USE));
		set(WinHeight, MUIA_Disabled, (State != MODE_USE));
		set(LookWin, MUIA_Disabled, (State != MODE_USE));
	}
	else if((*Data == UseFlags[0]) || (*Data == UseFlags[1]))
	{
		get(*Data, MUIA_Cycle_Active, &State);
		set(FlagModes, MUIA_Disabled, (State != MODE_USE));
	}

	return(0);
}






/**********************************************************************/
/*   Change gadget states on settings of cycle gadget (VolumeType)    */
/**********************************************************************/
static ULONG	__saveds __asm PageChangeFunc(register __a0 struct Hook *MyHook, register __a2 APTR Obj, register __a1 APTR *Data)
{
	ULONG	Page;
	ULONG	State;

		// Get current page

	get(VolumeType, MUIA_Cycle_Active, &Page);

		// Set gadget states

	get(IconPos[Page], MUIA_Cycle_Active, &State);

		// Running in Device mode?

	if(Page)
	{
		if(State == MODE_INHERIT)
			State	= MODE_USE;
	}

	set(IconPos[Page], MUIA_Cycle_Active, State);
	set(IconX, MUIA_Disabled, (State != MODE_USE));
	set(IconY, MUIA_Disabled, (State != MODE_USE));
	set(Position, MUIA_Disabled, (State != MODE_USE));

	get(UseIcon[Page], MUIA_Cycle_Active, &State);
	set(IconName, MUIA_Disabled, (State != MODE_USE));

	get(UseWindow[Page], MUIA_Cycle_Active, &State);
	set(WinX, MUIA_Disabled, (State != MODE_USE));
	set(WinY, MUIA_Disabled, (State != MODE_USE));
	set(WinWidth, MUIA_Disabled, (State != MODE_USE));
	set(WinHeight, MUIA_Disabled, (State != MODE_USE));
	set(LookWin, MUIA_Disabled, (State != MODE_USE));

	get(UseFlags[Page], MUIA_Cycle_Active, &State);
	set(FlagModes, MUIA_Disabled, (State != MODE_USE));

	return(0);
}












/**********************************************************************/
/*             Add a new volumes/device to the used list              */
/**********************************************************************/
static struct VolEntry *AddNewVolume(char *Name, ULONG Type, struct VolEntry *CopyPtr)
{
	struct	List		*CheckList	= (Type == FICON_APPICON ? &FIconSema->AppIconList : &FIconSema->VolumeList);
	struct	VolEntry	*NewEntry	= NULL,
				*ThisEntry;

		// Check for exitance

	if(CheckExists(CheckList, Name))
	{
		DisplayError(ERR_EXISTS, (ULONG)Name);
		return(NewEntry);
	}

		// Try to get our semaphore

	ObtainSemaphore(&FIconSema->FIconSema);

		// Get memory for new entry

	if((NewEntry = AllocVecPool(FIconSema, sizeof(struct VolEntry))))
	{
			// One entry plus

		CheckList->lh_Type++;

			// Add entry and fill out structure

		if(Type == LDF_VOLUMES)
			AddHead(CheckList, (struct Node *)NewEntry);
		else
			AddTail(CheckList, (struct Node *)NewEntry);

		NewEntry->Link.ln_Name	= NewEntry->VolName;
		NewEntry->Link.ln_Type	= Type;
		strcpy(NewEntry->VolName, Name);

			// Copy contents of other entry ???

		if(CopyPtr)
		{
			strcpy(NewEntry->IconName, CopyPtr->IconName);
			NewEntry->Left		= CopyPtr->Left;
			NewEntry->Top		= CopyPtr->Top;
			NewEntry->IconPos	= CopyPtr->IconPos;
			NewEntry->UseAlt	= CopyPtr->UseAlt;
			NewEntry->UseWin	= CopyPtr->UseWin;
			NewEntry->WinX		= CopyPtr->WinX;
			NewEntry->WinY		= CopyPtr->WinY;
			NewEntry->WinWidth	= CopyPtr->WinWidth;
			NewEntry->WinHeight	= CopyPtr->WinHeight;
			NewEntry->UseFlags	= CopyPtr->UseFlags;
			NewEntry->WinFlags	= CopyPtr->WinFlags;
		}

			// Remove entries from listview (Used)

		DoMethod((Type == FICON_APPICON ? AppUsedList : UsedList), MUIM_List_Clear, NULL);

			// Sort the list again

		SortList(CheckList, TRUE);

			// Readd list

		ThisEntry	= (struct VolEntry *)CheckList->lh_Head;
		while(ThisEntry->Link.ln_Succ)
		{
			DoMethod((Type == FICON_APPICON ? AppUsedList : UsedList), MUIM_List_InsertSingle, (APTR)ThisEntry, MUIV_List_Insert_Bottom);

			ThisEntry	= (struct VolEntry *)ThisEntry->Link.ln_Succ;
		}
	}
	else
	{
		DisplayError(ERR_NOMEM, NULL);
		NewEntry	= NULL;
	}

		// Free our semaphore

	ReleaseSemaphore(&FIconSema->FIconSema);

	return(NewEntry);
}








/**********************************************************************/
/*        Check for existance of a volume within the user list        */
/**********************************************************************/
static BOOL CheckExists(struct List *CheckList, char *Name)
{
	BOOL	RetVal = FALSE;

	ObtainSemaphore(&FIconSema->FIconSema);

	if(!IsListEmpty(CheckList))
	{
		struct	VolEntry	*ThisEntry	= (struct VolEntry *)CheckList->lh_Head;

		do
		{
			if(!stricmp(ThisEntry->VolName, Name))
				RetVal = TRUE;

			ThisEntry = (struct VolEntry *)ThisEntry->Link.ln_Succ;
		} while(!RetVal && ThisEntry->Link.ln_Succ);
	}

	ReleaseSemaphore(&FIconSema->FIconSema);

	return(RetVal);
}







/**********************************************************************/
/*                       Save Prefs to disk/env                       */
/**********************************************************************/
static BOOL			DoSavePrefs(char *PrefsName);
static BOOL SavePrefs(BOOL EnvMode, char *ToName)
{
	if(ToName)
		return(DoSavePrefs(ToName));

	else
	{
			// On ENV: mode, simply save to ENV: only

		if(DoSavePrefs("ENV:ForceIcon_prefs.iff"))
		{
				// Otherwise write to envarc: as well

			if(!EnvMode)
				return(DoSavePrefs("ENVARC:ForceIcon_prefs.iff"));
			else
				return(TRUE);
		}
	}
	return(FALSE);
}
static BOOL DoSavePrefs(char *PrefsName)
{
	struct	IFFHandle	*PrefsHandle;
	LONG	Error;
	BOOL	GoOn = FALSE;
	UWORD	VersChunk[] =
	{
		VERNUM,
		REVNUM
	};


	ObtainSemaphore(&FIconSema->FIconSema);

		// Get handle for IFF

	if((PrefsHandle = AllocIFF()))
	{
			// Open file for save

		if((PrefsHandle->iff_Stream = Open(PrefsName, MODE_NEWFILE)))
		{
				// Init Handle

			InitIFFasDOS(PrefsHandle);

				// Open Handle

			if(!(Error = OpenIFF(PrefsHandle, IFFF_WRITE)))
			{
					// Write FORM chunk

				if(!(Error = PushChunk(PrefsHandle, 'FOIC', 'FORM', IFFSIZE_UNKNOWN)))
				{
						// Write version chunk

					if(!(Error = PushChunk(PrefsHandle, 'FOIC', 'VERS', IFFSIZE_UNKNOWN)))
					{
						if((Error = WriteChunkBytes(PrefsHandle, &VersChunk[0], (sizeof(UWORD) * 2))) == (sizeof(UWORD) * 2))
							Error = PopChunk(PrefsHandle);
						else
							Error = IoErr();
					}

						// Write Prefs chunk

					if(!Error && !(Error = PushChunk(PrefsHandle, 'FOIC', 'PREF', IFFSIZE_UNKNOWN)))
					{
						struct	VolEntry	*ThisEntry;
						UWORD	NumEntriesVol			= FIconSema->VolumeList.lh_Type,
							NumEntriesApp			= FIconSema->AppIconList.lh_Type,
							NumEntries			= NumEntriesVol + NumEntriesApp;
						BOOL	NoErr = TRUE;

								// Write all entries of volume list

						if((Error = WriteChunkBytes(PrefsHandle, &NumEntries, sizeof(UWORD))) == sizeof(UWORD))
						{
							ThisEntry	= (struct VolEntry *)FIconSema->VolumeList.lh_Head;

								// Write list of volumes

							while(NumEntriesVol-- && NoErr)
							{
								UWORD	EntryType = ThisEntry->Link.ln_Type;

								if((Error = WriteChunkBytes(PrefsHandle, &EntryType, sizeof(UWORD))) == sizeof(UWORD))
								{
									if((Error = WriteChunkBytes(PrefsHandle, &ThisEntry->VolName, 130)) == 130)
									{
										if((Error = WriteChunkBytes(PrefsHandle, &ThisEntry->IconName, 256)) == 256)
										{
											if((Error = WriteChunkBytes(PrefsHandle, &ThisEntry->Left, (sizeof(UWORD) * 36))) != (sizeof(UWORD) * 36))
												NoErr = FALSE;
										}
									}
								}

								ThisEntry = (struct VolEntry *)ThisEntry->Link.ln_Succ;
							}

								// Write list of AppIcons

							ThisEntry	= (struct VolEntry *)FIconSema->AppIconList.lh_Head;
							while(NumEntriesApp-- && NoErr)
							{
								UWORD	EntryType = ThisEntry->Link.ln_Type;

								if((Error = WriteChunkBytes(PrefsHandle, &EntryType, sizeof(UWORD))) == sizeof(UWORD))
								{
									if((Error = WriteChunkBytes(PrefsHandle, &ThisEntry->VolName, 130)) == 130)
									{
										if((Error = WriteChunkBytes(PrefsHandle, &ThisEntry->IconName, 256)) == 256)
										{
											if((Error = WriteChunkBytes(PrefsHandle, &ThisEntry->Left, (sizeof(UWORD) * 36))) != (sizeof(UWORD) * 36))
												NoErr = FALSE;
										}
									}
								}

								ThisEntry = (struct VolEntry *)ThisEntry->Link.ln_Succ;
							}

							if(NoErr)
							{
								if(!(Error = PopChunk(PrefsHandle)))
									GoOn = TRUE;
							}
						}
					}
				}

				if((Error = PopChunk(PrefsHandle)))
					GoOn = FALSE;

				CloseIFF(PrefsHandle);
			}

			Close(PrefsHandle->iff_Stream);
		}
		else
			Error = IoErr();

		FreeIFF(PrefsHandle);
	}
	else
		Error = ERR_NOMEM;

	if(!GoOn)
		DisplayError(Error, (ULONG)PrefsName);

	ReleaseSemaphore(&FIconSema->FIconSema);

	return(GoOn);
}





/**********************************************************************/
/*                  Make a specific entry diskchange                  */
/**********************************************************************/
static void DskChange(struct VolEntry *ListEntry)
{
	struct	List	ChangeList;

	NewList(&ChangeList);


		// Create list of connected devices

	if(GetDosEntries(&ChangeList, LDF_VOLUMES))
	{
		struct	DosList		*DList;
		struct	VolEntry	*ThisEntry;
		struct	DevProc		*DevProc;
		char			DevName[130];
		BOOL			FoundDev,
					DoDskCh;

			// Loop for all volumes in list

		while((ThisEntry = (struct VolEntry *)RemHead(&ChangeList)))
		{
			FoundDev	= FALSE;

				// Find name of device this volume resides in

			if((DList = LockDosList(LDF_DEVICES|LDF_READ)))
			{
				while((DList = NextDosEntry(DList, LDF_DEVICES|LDF_READ)))
				{
					if(ThisEntry->DriverTask == DList->dol_Task)
					{
						setmem(DevName, 130, 0);
						strncpy(DevName, ((char *)BADDR(DList->dol_Name) + 1), *((char *)BADDR(DList->dol_Name)));
						FoundDev	= TRUE;
					}
				}
				UnLockDosList(LDF_DEVICES|LDF_READ);
			}

				// Found corresponding device ???

			if(FoundDev)
			{
					// Check whether to diskchange

				if(ListEntry->Link.ln_Type == LDF_DEVICES)
					DoDskCh	= (MyStrCmp(ListEntry->VolName, DevName) == 0);
				else
					DoDskCh	= (MyStrCmp(ListEntry->VolName, ThisEntry->VolName) == 0);

					// Diskchange device ???

				if(DoDskCh)
				{
					strcat(DevName, ":");

					if(ThisEntry->DriverTask && (DevProc = GetDeviceProc(DevName, NULL)))
					{
						if(TypeOfMem(DevProc->dvp_Port))
						{
							if(DoPkt(DevProc->dvp_Port, ACTION_INHIBIT, DOSTRUE, NULL, NULL, NULL, NULL))
								DoPkt(DevProc->dvp_Port, ACTION_INHIBIT, DOSFALSE, NULL, NULL, NULL, NULL);
						}
						FreeDeviceProc(DevProc);
					}
				}
			}

			FreeVecPool(FIconSema, ThisEntry);
		}
	}
}






/**********************************************************************/
/*                 Get a list of all available tasks                  */
/**********************************************************************/
static BOOL AddTaskEntry(struct Task *NewTask)
{
	struct	Process		*NewProc	= (struct Process *)NewTask;
	struct	VolEntry	*NewEntry;
	char			*TaskName	= NewTask->tc_Node.ln_Name,
				Buffer[132];
	UWORD			NameLen		= strlen(TaskName);


		// Task a process?

	if(NewTask->tc_Node.ln_Type == NT_PROCESS && NewProc->pr_CLI)
	{
		struct	CommandLineInterface	*CLI = BADDR(NewProc->pr_CLI);

		if(CLI->cli_Module && CLI->cli_CommandName)
		{
			char	*Dummy	= BADDR(CLI->cli_CommandName);

			NameLen		= *Dummy++;
			TaskName	= Dummy;
		}
	}

	setmem(Buffer, 132, 0);
	strncpy(Buffer, TaskName, (NameLen >= 130 ? 130 : NameLen));

	if((NewEntry = AllocVecPool(FIconSema, sizeof(struct VolEntry))))
	{
		AddTail(&AppAvailableList, (struct Node *)NewEntry);

		strcpy(NewEntry->VolName, Buffer);

		NewEntry->Link.ln_Name		= NewEntry->VolName;
		NewEntry->Link.ln_Type		= FICON_APPICON;

		AppAvailableList.lh_Type++;

		return(TRUE);
	}
	return(FALSE);
}
static BOOL GetTaskList(struct List *AppList)
{
	struct	Task	*SelectTask;
	BOOL		Failed;

	NewList(AppList);

	Forbid();

		// Add my task

	Failed	= !AddTaskEntry(SysBase->ThisTask);

		// Add ready tasks

	if(!Failed && !IsListEmpty(&SysBase->TaskReady))
	{
		SelectTask	= (struct Task *)SysBase->TaskReady.lh_Head;

		while(SelectTask->tc_Node.ln_Succ && !Failed)
		{
			Failed		= !AddTaskEntry(SelectTask);

			SelectTask	= (struct Task *)SelectTask->tc_Node.ln_Succ;
		}
	}

		// Add waiting tasks

	if(!Failed && !IsListEmpty(&SysBase->TaskWait))
	{
		SelectTask	= (struct Task *)SysBase->TaskWait.lh_Head;

		while(SelectTask->tc_Node.ln_Succ && !Failed)
		{
			Failed		= !AddTaskEntry(SelectTask);

			SelectTask	= (struct Task *)SelectTask->tc_Node.ln_Succ;
		}
	}

	Permit();

		// Sort list

	SortList(AppList, TRUE);

		// Indicate failure

	return((BOOL)(!Failed));
}





/**********************************************************************/
/*                          Query a filename                          */
/**********************************************************************/
static BOOL GetFileName(struct Window *Window, char *Title, char *FileName, ULONG Flags1)
{
	struct	Rectangle	ScrRec;
	struct	FileRequester	*FileReq;
	char			Drawer[514],
				File[514];
	UWORD			Left,
				Top,
				Width,
				Height;
	BOOL			Result	= FALSE;


	if(QueryOverscan(GetVPModeID(&Window->WScreen->ViewPort), &ScrRec, OSCAN_TEXT))
	{
		Width	= ((ScrRec.MaxX - ScrRec.MinX + 1) * 45) / 100;
		Height	= ((ScrRec.MaxY - ScrRec.MinY + 1) * 8) / 10;
		Left	= (((ScrRec.MaxX + 1) - Width) >> 1) - Window->WScreen->LeftEdge;
		Top	= (((ScrRec.MaxY + 1) - Height) >> 1) - Window->WScreen->TopEdge;

			// Get Patch of filename

		setmem(Drawer, 514, 0);
		if((char *)PathPart(FileName) != (char *)&FileName[0])
		{
			strncpy(Drawer, FileName, (PathPart(FileName) - FileName));
		}

			// Get Filename

		strcpy(File, FilePart(FileName));

			// Set up pattern

		if((FileReq = AllocAslRequestTags(ASL_FileRequest,
			ASLFR_Screen,		Window->WScreen,
			ASLFR_Window,		Window,
			ASLFR_PrivateIDCMP,	TRUE,
			ASLFR_SleepWindow, 	TRUE,
			ASLFR_TitleText,	Title,
			ASLFR_InitialDrawer,	(ULONG)Drawer,
			ASLFR_InitialFile,	(ULONG)File,
			ASLFR_InitialLeftEdge,	Left,
			ASLFR_InitialTopEdge,	Top,
			ASLFR_InitialWidth,	Width,
			ASLFR_InitialHeight,	Height,
			ASLFR_Flags1,		Flags1,
			ASLFR_Flags2,		FRF_REJECTICONS,
		TAG_DONE)))
		{
			if(AslRequest(FileReq, NULL) && (strlen(FileReq->fr_File)))
			{
					// Create filetypes again

				strcpy(FileName, "");

				AddPart(FileName, FileReq->fr_Drawer, 512);
				AddPart(FileName, FileReq->fr_File, 512);
				Result = TRUE;
			}

			FreeAslRequest(FileReq);
		}
	}

	return(Result);
}




/**********************************************************************/
/*                    Clone the contents of a list                    */
/**********************************************************************/
static BOOL CloneList(struct List *ToList, struct List *FromList)
{
	struct	VolEntry	*FromEntry,
				*ToEntry;
	BOOL			Result		= TRUE;

	NewList(ToList);

	FromEntry	= (struct VolEntry *)FromList->lh_Head;
	ToList->lh_Type	= FromList->lh_Type;

	while(FromEntry->Link.ln_Succ && Result)
	{
		if((ToEntry = AllocVecPool(FIconSema, sizeof(struct VolEntry))))
		{
			*ToEntry		= *FromEntry;

			ToEntry->Link.ln_Name	= ToEntry->VolName;

			AddTail(ToList, (struct Node *)ToEntry);
		}
		else
			Result	= FALSE;

		FromEntry	= (struct VolEntry *)FromEntry->Link.ln_Succ;
	}

	if(!Result)
	{
		FreeDevVolList(ToList);
		DisplayError(ERR_NOMEM, NULL);
	}

	return(Result);
}




/**********************************************************************/
/*       Now include the LoadRoutine and the VolumeList routine       */
/**********************************************************************/
#include	"LoadPrefs.h"
#include	"VolList.h"
#include	"Error.h"
#include	"Rendezvous.h"
#include	"CheckToolTypes.h"
#include	"PoolVec.h"
