// Build display entry for a function
void funced_build_entrydisplay(
	FuncEdData *data,
	Att_Node *node,
	FunctionEntry *entry)
{
	// If node is 0, create a new one
	if (!node) node=Att_NewNode(data->func_display_list,0,(ULONG)entry,0);

	// Check valid node and data
	if (!node || !node->node.ln_Succ || !entry) return;

	// If node has a name, free it
	FreeMemH(node->node.ln_Name);

	// Get new name
	if ((node->node.ln_Name=AllocMemH(data->func_display_list->memory,strlen(entry->buffer)+32)))
	{
		// Build new name
		strcpy(node->node.ln_Name,GetString(data->locale,data->startup->func_labels[entry->type]));
		if (entry->buffer[0])
		{
			strcat(node->node.ln_Name,"\a\xc");
			strcat(node->node.ln_Name,entry->buffer);
		}
	}
}
// Add path 
PathNode *function_add_path(FunctionHandle *handle,PathList *list,Lister *lister,char *path)
{
	PathNode *node;

	// Allocate node
	if ((node=AllocMemH(handle->memory,sizeof(PathNode))))
	{
		// Copy path
		if (path) strcpy(node->path_buf,path);

		// Store lister pointer
		node->lister=lister;

		// Add to path list
		AddHead((struct List *)list,(struct Node *)node);

		// Make this the current path
		list->current=node;

		// Set appropriate flag
		if (list==&handle->source_paths)
			handle->func_flags|=FUNCF_GOT_SOURCE;
		else handle->func_flags|=FUNCF_GOT_DEST;
	}

	return node;
}
Beispiel #3
0
// Add PopUp extensions
void add_popup_ext(char *menu,Att_List *type_list,char *command,ULONG flags)
{
	Att_Node *node;

	// Go through menu list
	for (node=(Att_Node *)type_list->list.lh_Head;
		node->node.ln_Succ;
		node=(Att_Node *)node->node.ln_Succ)
	{
		Cfg_Filetype *ftype=0;
		ULONG type=0;
		short a;

		// No name?
		if (!node->node.ln_Name) continue;

		// Special type?
		for (a=0;icon_types[a];a++)
		{
			// Compare string
			if (stricmp(node->node.ln_Name,icon_types[a])==0)
			{
				// All?
				if (a==0) type=POPUP_ALL;
				else type=a;
				break;
			}
		}

		// Search filetypes?
		if (!type)
		{
			// Try to find filetype
			if (!(ftype=filetype_find(node->node.ln_Name,1)))
				ftype=filetype_find(node->node.ln_Name,0);
		}

		// Got something to match on?
		if (type || ftype)
		{
			PopUpExt *ext;

			// Allocate PopUpExtension
			if ((ext=AllocMemH(global_memory_pool,sizeof(PopUpExt))))
			{
				// Fill it out
				ext->pe_Type=type;
				if (ftype) stccpy(ext->pe_FileType,ftype->type.name,sizeof(ext->pe_FileType));
				stccpy(ext->pe_Command,command,40);
				stccpy(ext->pe_Menu,menu,40);
				ext->pe_Flags=flags;

				// Lock list and add new entry
				lock_listlock(&GUI->popupext_list,TRUE);
				AddTail(&GUI->popupext_list.list,(struct Node *)ext);
				unlock_listlock(&GUI->popupext_list);
			}
		}
	}
}
// Read filetype list
void filetype_read_list(
	APTR memory,
	struct List *main_list)
{
	Cfg_FiletypeList *list;
#ifdef __amigaos4__	
	struct AnchorPathOld *anchor;
#else	
	struct AnchorPath *anchor;
#endif	
	long error;

	// Allocate anchor path
#ifdef __amigaos4__	
	if (!(anchor=AllocMemH(memory,sizeof(struct AnchorPathOld)+256)))
		return;
#else
	if (!(anchor=AllocMemH(memory,sizeof(struct AnchorPath)+256)))
		return;
#endif		

	// Initialise anchor path
	anchor->ap_Strlen=256;
	anchor->ap_BreakBits=IPCSIG_QUIT;
	anchor->ap_Flags=APF_DOWILD;

	// Search for filetypes
	error=MatchFirst("dopus5:filetypes/~(#?.info)",anchor);

	// Continue while there's files
	while (!error)
	{
		// Read new filetype list
		if ((list=ReadFiletypes(anchor->ap_Buf,memory)))
		{
			// Add to list
			AddTail(main_list,&list->node);
		}

		// Find next file in directory
		error=MatchNext(anchor);
	}

	// Clean up match stuff
	MatchEnd(anchor);
	FreeMemH(anchor);
}
// Add an entry to the OpenWith file
void add_open_with(char *line)
{
	APTR file;
	struct Node *node;

	// Lock list
	lock_listlock(&GUI->open_with_list,1);

	// Too many nodes?
	if (Att_NodeCount((Att_List *)&GUI->open_with_list)>=environment->env->settings.max_openwith)
	{
		// List is empty?
		if (IsListEmpty((struct List *)&GUI->open_with_list.list))
			return;

		// Get first node
		node=GUI->open_with_list.list.lh_Head;

		// Remove first node and free it
		RemHead((struct List *)&GUI->open_with_list);
		FreeMemH(node);
	}

	// Allocate a new node
	if (node=AllocMemH(global_memory_pool,sizeof(struct Node)+strlen(line)+1))
	{
		// Initialise node and copy string
		node->ln_Name=(char *)(node+1);
		strcpy(node->ln_Name,line);

		// Add to Open With list
		AddTail((struct List *)&GUI->open_with_list,node);
	}

	// Open file for output
	if (file=OpenBuf("DOpus5:System/OpenWith",MODE_NEWFILE,4000))
	{
		// Write lines
		for (node=GUI->open_with_list.list.lh_Head;node->ln_Succ;node=node->ln_Succ)
		{
			// Write line
			WriteBuf(file,node->ln_Name,strlen(node->ln_Name));
			WriteBuf(file,"\n",1);
		}

		// Close file
		CloseBuf(file);
	}

	// Unlock list
	unlock_listlock(&GUI->open_with_list);
}
// Allocate a new environment structure
Cfg_Environment *environment_new(void)
{
	Cfg_Environment *env;

	// Allocate new environment structure
	if (!(env=AllocVec(sizeof(Cfg_Environment),MEMF_CLEAR)) ||
		!(env->memory=NewMemHandle(0,0,MEMF_CLEAR)) ||
		!(env->desktop_memory=NewMemHandle(1024,512,MEMF_PUBLIC|MEMF_CLEAR)) ||
		!(env->volatile_memory=NewMemHandle(1024,sizeof(ButtonBankNode)+256,MEMF_PUBLIC|MEMF_CLEAR)))
	{
		environment_free(env);
		return 0;
	}

	// Initialise environment
	InitSemaphore(&env->lock);
	NewList((struct List *)&env->path_formats);
	NewList((struct List *)&env->path_list);
	NewList((struct List *)&env->sound_list);
	strcpy(env->toolbar_path,"dopus5:buttons/toolbar");
	strcpy(env->menu_path,"dopus5:buttons/lister menu");
	strcpy(env->user_menu_path,"dopus5:buttons/user menu");
	strcpy(env->hotkeys_path,"dopus5:buttons/hotkeys");
	strcpy(env->scripts_path,"dopus5:buttons/scripts");
	NewList((struct List *)&env->desktop);
	InitSemaphore(&env->desktop_lock);
	InitSemaphore(&env->sound_lock);

	// Allocate space for settings
	if (!(env->env=AllocMemH(env->memory,sizeof(CFG_ENVR))))
	{
		environment_free(env);
		return 0;
	}

	// Get default settings
	DefaultEnvironment(env->env);
	return env;
}
Beispiel #7
0
// Add an entry
void config_paths_add(config_path_data *data,BOOL activate)
{
	position_rec *pos;
	Att_Node *node;

	// Create a new entry
	if ((pos=(position_rec *)AllocMemH(data->memory,sizeof(position_rec)+256)))
	{
		// Initialise entry
		pos->node.ln_Type=PTYPE_POSITION;
		pos->node.ln_Name=pos->name;
		pos->flags|=POSITIONF_USER|POSITIONF_NEW;
		if (data->def_format)
			CopyMem((char *)data->def_format,(char *)&pos->format,sizeof(ListFormatStorage));

		// Initialise key
		pos->code=0xffff;

		// Add to list path list
		AddTail(data->paths,(struct Node *)pos);

		// Remove list from gadget
		SetGadgetChoices(data->objlist,GAD_PATHFORMAT_PATHS,(APTR)~0);

		// Add to lister
		node=Att_NewNode(data->path_list,0,(ULONG)pos,ADDNODE_SORT);

		// Attach list to gadget
		SetGadgetChoices(data->objlist,GAD_PATHFORMAT_PATHS,data->path_list);

		// Select the new node
		config_paths_select(data,node,TRUE);

		// Activate path field
		if (activate) ActivateStrGad(GADGET(GetObject(data->objlist,GAD_PATHFORMAT_PATH)),data->window);
	}
}
Beispiel #8
0
// Allocate a new object
BackdropObject *backdrop_new_object(
	BackdropInfo *info,
	char *name,
	char *extra,
	short type)
{
	BackdropObject *object;
	short len=0;

	// Extra space?
	if (extra)
	{
		if (!*extra) extra=0;
		else len=strlen(extra)+1;
	}

	// Allocate object
	if (!(object=AllocMemH(info->memory,sizeof(BackdropObject)+len)))
		return 0;

	// Set name
	object->node.ln_Name=object->name;
	if (name) stccpy(object->name,name,31);

	// Set type
	object->type=type;

	// Any extra?
	if (extra)
	{
		// Copy extra
		object->device_name=(char *)(object+1);
		strcpy(object->device_name,extra);
	}

	return object;
}
// Read the OpenWith file
void startup_read_openwith(void)
{
	APTR file;

	// Lock list
	lock_listlock(&GUI->open_with_list,1);

	// Open file
	if (file=OpenBuf("DOpus5:System/OpenWith",MODE_OLDFILE,4000))
	{
		char line[256];
		short len;

		// Read lines
		while ((len=ReadBufLine(file,line,255))>0)
		{
			struct Node *node;

			// Allocate node
			if (node=AllocMemH(global_memory_pool,sizeof(struct Node)+len+1))
			{
				// Initialise node and copy string
				node->ln_Name=(char *)(node+1);
				strcpy(node->ln_Name,line);

				// Add to Open With list
				AddTail((struct List *)&GUI->open_with_list,node);
			}
		}

		// Close file
		CloseBuf(file);
	}

	// Unlock list
	unlock_listlock(&GUI->open_with_list);
}
// Receive an edited class definition
void filetypeed_receive_class(
	filetype_ed_data *data,
	Cfg_Filetype *type)
{
	// Store name, id and priority
	strcpy(data->type->type.name,type->type.name);
	strcpy(data->type->type.id,type->type.id);
	data->type->type.priority=type->type.priority;

	// Free recognition string
	FreeMemH(data->type->recognition);
	data->type->recognition=0;

	// Allocate new recognition
	if (type->recognition &&
		(data->type->recognition=AllocMemH(0,strlen(type->recognition)+1)))
		strcpy(data->type->recognition,type->recognition);

	// Set new window title
	if (data->window)
	{
		SetWindowTitles(data->window,data->type->type.name,(char *)-1);
	}
}
void FiletypeEditor(void)
{
	filetype_ed_data *data=0;
	IPCData *ipc;
	short success=0,pending_quit=0;
	BOOL change_flag=0;

	// Do startup
	if (!(ipc=Local_IPC_ProcStartup((ULONG *)&data, (APTR)&_filetypeed_init)))
		return;

	// Create App stuff
	if ((data->app_port=CreateMsgPort()))
	{
		data->app_window=AddAppWindowA(0,0,data->window,data->app_port,0);
	}

	// Get icon image
	if (data->type->icon_path)
	{
#ifdef USE_DRAWICONSTATE
		{
			char *path_copy;
			data->icon_image=NULL;
			if ((path_copy=AllocMemH(0,strlen(data->type->icon_path)+1)))
			{
				// icon_path is guaranteed to have a .info at the end
				stccpy(path_copy,data->type->icon_path,strlen(data->type->icon_path)-4);
				data->icon_image=GetCachedDiskObject(path_copy,0);
				FreeMemH(path_copy);
			}
		}
#else
		data->icon_image=OpenImage(data->type->icon_path,0);
#endif
		// Show icon image
		filetypeed_show_icon(data);
	}

	// Launch class editor immediately?
	if (data->edit_flag) filetypeed_edit_definition(data);

	// Message loop
	FOREVER
	{
		IPCMessage *msg;
		struct IntuiMessage *imsg;
		short break_flag=0;

		// Check drag
		if (config_drag_check(&data->drag))
		{
			// End drag
			filetypeed_end_drag(data,0);
		}

		// Task message?
		while ((msg=(IPCMessage *)GetMsg(ipc->command_port)))
		{
			switch (msg->command)
			{
				// Close message?
				case IPC_QUIT:
					if (!pending_quit)
					{
						success=msg->flags;
						break_flag=1;
					}
					break;


				// Activate
				case IPC_ACTIVATE:
					if (data->window)
					{
						WindowToFront(data->window);
						ActivateWindow(data->window);
					}
					break;


				// Editor saying goodbye
				case IPC_GOODBYE:
					{
						ULONG which;

						// What's just gone?
						which=IPC_GetGoodbye(msg);

						// Class editor?
						if (which==(ULONG)-1) data->class_editor=0;

						// Icon menu editor?
						else
						if (which>15)
						{
							Att_Node *node;

							// Go through icon list
							for (node=(Att_Node *)data->icon_list->list.lh_Head;
								node->node.ln_Succ;
								node=(Att_Node *)node->node.ln_Succ)
							{
								// Match function
								if (((func_node *)node->data)->func==(Cfg_Function *)which)
								{
									// Clear editor pointer
									((func_node *)node->data)->editor=0;

									// Check for invalid function
									if (filetypeed_check_iconmenu(data,node,FALSE))
										change_flag=1;
									break;
								}
							}
						}

						// Normal filetype editor
						else data->editor[which]=0;
					}
					break;


				// Editor returning a function
				case FUNCTIONEDIT_RETURN:
					{
						short ret;

						if ((ret=filetypeed_receive_edit(
							data,
							(FunctionReturn *)msg->data)))
						{
							change_flag=1;
							filetypeed_update_actions(data);
							if (ret==2) filetypeed_update_iconmenu(data);
						}
					}
					break;


				// Class editor returning
				case CLASSEDIT_RETURN:
					filetypeed_receive_class(data,(Cfg_Filetype *)msg->data);
					change_flag=1;
					break;


				// Get a copy of a button
				case BUTTONEDIT_CLIP_BUTTON:

					// Handle this button
					if (filetypeed_get_button(data,(Cfg_Button *)msg->data,(Point *)msg->data_free))
						change_flag=1;
					break;
			}

			// Reply the message
			IPC_Reply(msg);
		}

		// Intuimessage
		if (data->window)
		{
			while ((imsg=GetWindowMsg(data->window->UserPort)))
			{
				struct IntuiMessage msg_copy;
				struct Gadget *gadget;
				struct TagItem *tags;

				// Copy message
				msg_copy=*imsg;

				// Don't reply to IDCMPUPDATE messages just yet
				if (imsg->Class!=IDCMP_IDCMPUPDATE)
				{
					ReplyWindowMsg(imsg);
					imsg=0;
				}

				// Get gadget and tag pointers
				gadget=(struct Gadget *)msg_copy.IAddress;
				tags=(struct TagItem *)gadget;

				// Look at message
				switch (msg_copy.Class)
				{
					// Close window
					case IDCMP_CLOSEWINDOW:
						if (!pending_quit) break_flag=1;
						break;


					// Gadget
					case IDCMP_GADGETUP:
						switch (gadget->GadgetID)
						{
							// Use
							case GAD_FILETYPEED_USE:
								success=1;

							// Cancel
							case GAD_FILETYPEED_CANCEL:
								if (!pending_quit) break_flag=1;
								break;


							// Select a function
							case GAD_FILETYPEED_ACTION_LIST:
								{
									Att_Node *node;

									// Get selected node
									if (!(node=Att_FindNode(data->action_list,msg_copy.Code)))
										break;

									// Enable edit action button
									DisableObject(data->objlist,GAD_FILETYPES_EDIT_ACTION,FALSE);

									// Double-click?
									if (!(DoubleClick(data->last_sec,data->last_mic,msg_copy.Seconds,msg_copy.Micros)) ||
										node!=data->last_sel)
									{
										data->last_sec=msg_copy.Seconds;
										data->last_mic=msg_copy.Micros;
										data->last_sel=node;
										data->last_icon=0;
										break;
									}
								}

								// Fall through

							case GAD_FILETYPES_EDIT_ACTION:

								// No current selection?
								if (!data->last_sel) break;

								// Is editor already up for this action?	
								if (data->editor[data->last_sel->data])
									IPC_Command(data->editor[data->last_sel->data],IPC_ACTIVATE,0,0,0,0);

								// Need to launch editor
								else filetypeed_edit_action(data,data->last_sel->data,data->last_sel->node.ln_Name);
								break;


							// Delete action
							case GAD_FILETYPES_DEL_ACTION:

								// No current selection?
								if (!data->last_sel) break;

								// Is editor up for this action?	
								if (data->editor[data->last_sel->data])
									IPC_Command(data->editor[data->last_sel->data],IPC_QUIT,0,0,0,0);

								// Delete it
								if (filetypeed_del_action(data,data->last_sel->data))
									change_flag=1;
								break;


							// Edit filetype definition
							case GAD_FILETYPEED_EDIT_CLASS:

								// Is class editor already up for this action?	
								if (data->class_editor)
									IPC_Command(data->class_editor,IPC_ACTIVATE,0,0,0,0);

								// Need to launch editor
								else filetypeed_edit_definition(data);
								break;


							// Select icon
							case GAD_FILETYPEED_SELECT_ICON:
								if (filetypeed_pick_icon(data))
									change_flag=1;
								break;


							// Add to icon menu
							case GAD_FILETYPES_ADD_ICON_MENU:
								filetypeed_add_iconmenu(data);
								break;


							// Select an icon menu
							case GAD_FILETYPES_ICON_MENU:
								{
									Att_Node *last=data->last_icon;

									// Handle selection
									if (!(filetypeed_sel_icon(data,msg_copy.Code))) break;

									// Double-click?
									if (data->last_icon!=last ||
										!(DoubleClick(
											data->last_sec,
											data->last_mic,
											msg_copy.Seconds,
											msg_copy.Micros)))
									{
										data->last_sec=msg_copy.Seconds;
										data->last_mic=msg_copy.Micros;
										data->last_sel=0;
										break;
									}
								}

								// Fall through

							case GAD_FILETYPES_EDIT_ICON_MENU:

								// No current selection?
								if (!data->last_icon) break;

								// Edit it
								filetypeed_edit_iconmenu(data,data->last_icon);
								break;


							// Delete from icon menu
							case GAD_FILETYPES_DEL_ICON_MENU:

								// No current selection?
								if (!data->last_icon) break;

								// Delete function
								if (filetypeed_check_iconmenu(data,data->last_icon,TRUE))
									change_flag=1;
								break;
						}
						break;


					// BOOPSI message
					case IDCMP_IDCMPUPDATE:
						{
							short item;

							// Icon list?
							if (GetTagData(GA_ID,0,tags)!=GAD_FILETYPES_ICON_MENU) break;

							// Get item
							if ((item=GetTagData(DLV_DragNotify,-1,tags))!=-1)
							{
								// Handle selection
								filetypeed_sel_icon(data,item);

								// Start the drag
								config_drag_start(&data->drag,data->icon_list,item,tags,TRUE);
							}
						}
						break;


					// Ticks
					case IDCMP_INTUITICKS:
						++data->drag.tick_count;
						break;


					// Mouse move
					case IDCMP_MOUSEMOVE:

						// Handle drag move
						config_drag_move(&data->drag);
						break;


					// Mouse buttons
					case IDCMP_MOUSEBUTTONS:

						// Valid drag info?
						if (data->drag.drag)
						{
							short ok=-1;

							// Dropped ok?
							if (msg_copy.Code==SELECTUP)
							{
								// Remember last position
								data->drag.drag_x=data->window->WScreen->MouseX;
								data->drag.drag_y=data->window->WScreen->MouseY;
								ok=1;
							}

							// Aborted
							else
							if (msg_copy.Code==MENUDOWN) ok=0;

							// End drag?
							if (ok!=-1 && filetypeed_end_drag(data,ok)) change_flag=1;
						}
						break;


					// Key press
					case IDCMP_RAWKEY:

						// Help?
						if (msg_copy.Code==0x5f &&
							!(msg_copy.Qualifier&VALID_QUALIFIERS))
						{
							// Set busy pointer
							SetWindowBusy(data->window);

							// Send help command
							IPC_Command(data->func_startup.main_owner,IPC_HELP,(1<<31),"File Type Editor",0,REPLY_NO_PORT);

							// Clear busy pointer
							ClearWindowBusy(data->window);
						}
						break;
				}

				// Reply to outstanding messages
				if (imsg) ReplyWindowMsg(imsg);
			}

			// Check break flag
			if (break_flag || pending_quit)
			{
				// See if all the editors are gone
				if (IsListEmpty(&data->proc_list.list))
					break;

				// Send quit?
				if (break_flag)
				{
					IPC_ListQuit(&data->proc_list,0,success,FALSE);
					SetWindowBusy(data->window);
				}
				pending_quit=1;
			}
		}

		// AppMessage
		if (data->app_window)
		{
			struct AppMessage *msg;

			while ((msg=(struct AppMessage *)GetMsg(data->app_port)))
			{
				// Got an argument?
				if (msg->am_NumArgs>0)
				{
					char name[256];
					short len;
					APTR image;

					// Get full name
					NameFromLock(msg->am_ArgList[0].wa_Lock,name,256);
					if (msg->am_ArgList[0].wa_Name &&
						*msg->am_ArgList[0].wa_Name)
						AddPart(name,msg->am_ArgList[0].wa_Name,256);

					// Add .info
					if ((len=strlen(name))<6 ||
						stricmp(name+len-5,".info")!=0) strcat(name,".info");

					// Try to get image
#ifdef USE_DRAWICONSTATE
					{
						char *path_copy;
						image=NULL;
						if ((path_copy=AllocMemH(0,strlen(name)+1)))
						{
							// icon_path is guaranteed to have a .info at the end
							stccpy(path_copy,name,strlen(name)-4);
							image=GetCachedDiskObject(path_copy,0);
							FreeMemH(path_copy);
						}
					}
#else
					image=OpenImage(name,0);
#endif

					if (image)
					{
						// Store path
						FreeMemH(data->type->icon_path);
						if ((data->type->icon_path=AllocMemH(0,strlen(name)+1)))
							strcpy(data->type->icon_path,name);

						// Free existing image
#ifdef USE_DRAWICONSTATE
						FreeCachedDiskObject(data->icon_image);
#else
						CloseImage(data->icon_image);
#endif
						data->icon_image=image;

						// Show new image
						filetypeed_show_icon(data);
						change_flag=1;
					}
				}

				// Reply message
				ReplyMsg((struct Message *)msg);
			}
		}

		Wait(1<<ipc->command_port->mp_SigBit|
			1<<data->drag.timer->port->mp_SigBit|
			((data->window)?(1<<data->window->UserPort->mp_SigBit):0)|
			((data->app_window)?(1<<data->app_port->mp_SigBit):0));
	}

	// End any drag in progress
	filetypeed_end_drag(data,0);

	// Need to send button back?
	if (success==1 && change_flag)
	{
		if (IPC_Command(
			data->owner_ipc,
			FILETYPEEDIT_RETURN,
			(ULONG)data->type,
			data->node,
			0,
			REPLY_NO_PORT))
		{
			data->node=0;
		}
	}

	// Free edit filetype
	FreeFiletype(data->type);

	// Remove AppWindow
	RemoveAppWindow(data->app_window);

	// Close window
	CloseConfigWindow(data->window);

	// Close app port
	if (data->app_port)
	{
		struct Message *msg;
		while ((msg=GetMsg(data->app_port)))
			ReplyMsg(msg);
		DeleteMsgPort(data->app_port);
	}

	// Say goodbye
	IPC_Goodbye(ipc,data->owner_ipc,(success==-1)?0:(ULONG)data->node);

	// Free icon image
#ifdef USE_DRAWICONSTATE
	FreeCachedDiskObject(data->icon_image);
#else
	CloseImage(data->icon_image);
#endif

	// Close timer
	FreeTimer(data->drag.timer);

	// Free data
	IPC_Free(ipc);
	Att_RemList(data->action_list,0);
	Att_RemList(data->icon_list,REMLIST_FREEDATA);
	FreeVec(data);
}
Beispiel #12
0
// Create a global memory pool and GUI structure
void startup_init_gui()
{
    short a,proc=0;

    // Create a global memory pool and GUI structure
    if (!(global_memory_pool=NewMemHandle(1024,512,MEMF_CLEAR|MEMF_PUBLIC)) ||
            !(GUI=AllocMemH(global_memory_pool,sizeof(GUI_Glue))) ||
            !(GUI->screen_title=AllocMemH(global_memory_pool,256)) ||
            !(GUI->filter_string=AllocMemH(global_memory_pool,256)))
        quit(0);

    // Initialise lists
    InitListLock(&GUI->lister_list,0);
    InitListLock(&GUI->buffer_list,0);
    InitListLock(&GUI->buttons_list,0);
    InitListLock(&GUI->process_list,0);
    InitListLock(&GUI->group_list,0);
    InitListLock(&GUI->filetypes,0);
    InitListLock(&GUI->notify_process_list,0);
    InitListLock(&GUI->function_traps,0);
    InitListLock(&GUI->positions,0);
    InitListLock(&GUI->rexx_readers,0);
    InitListLock(&GUI->function_list,0);
    InitListLock(&GUI->rexx_apps,0);
    InitListLock(&GUI->command_list,0);
#ifdef __AROS__
    GUI->command_list.list.lh_Type = 255; // requires special handling
#endif
    InitListLock(&GUI->original_cmd_list,0);
    InitListLock(&GUI->modules_list,0);
    InitListLock(&GUI->popupext_list,0);
    InitListLock(&GUI->iconpos_list,0);
    InitListLock(&GUI->startmenu_list,0);
    InitListLock(&GUI->open_with_list,0);
    GUI->command_history=Att_NewList(LISTF_POOL|LISTF_LOCK);

    // Initialise locks
    InitSemaphore(&GUI->select_lock);
    InitSemaphore(&GUI->req_lock);
    InitSemaphore(&GUI->lister_menu_lock);
    InitSemaphore(&GUI->hotkeys_lock);
    InitSemaphore(&GUI->findfile_lock);
    InitSemaphore(&GUI->filter_lock);
    InitSemaphore(&GUI->scripts_lock);
    InitSemaphore(&GUI->user_menu_lock);
    InitSemaphore(&GUI->custom_pen_lock);

    // Signal for getting screen close
    GUI->screen_signal=AllocSignal(-1);

    // This pointer is cleared by the registration module; big crashes if that doesn't happen
#if 0
    GUI->screen=(struct Screen *)1;
#endif
    GUI->def_filename_length=FILENAME_LEN;

    // Initialise filter string
    strcpy(GUI->filter_string,"#?");

    // Initial requester coordinates
    GUI->req_coords.Left=64;
    GUI->req_coords.Top=32;
    GUI->req_coords.Width=320;
    GUI->req_coords.Height=200;

    // Initialise selection data
    GUI->select_data.type=SELECT_SIMPLE;
    GUI->select_data.entry_type=SELECT_ENTRY_BOTH;
    strcpy(GUI->select_data.name,"*");
    GUI->select_data.name_match=SELECT_MATCH_MATCH;
    GUI->select_data.date_from[0]=0;
    GUI->select_data.date_to[0]=0;
    GUI->select_data.date_match=SELECT_MATCH_IGNORE;
    GUI->select_data.bits=0;
    GUI->select_data.bits_match=SELECT_MATCH_IGNORE;
    GUI->select_data.compare=0;
    GUI->select_data.compare_match=SELECT_MATCH_IGNORE;
    GUI->select_data.include=SELECT_INCLUDE;

    // Get decimal separator
    GUI->decimal_sep=(locale.li_Locale)?locale.li_Locale->loc_GroupSeparator[0]:',';

    // Locale patches installed?
    if (locale.li_LocaleBase &&
            ((struct LocaleBase *)locale.li_LocaleBase)->lb_SysPatches) GUI->flags|=GUIF_LOCALE_OK;

    // Calculate width of date field
    if (locale.li_LocaleBase)
    {
        char *str;
        short day,len;
#define LocaleBase locale.li_LocaleBase

        // Get lengths of days of the week
        for (day=DAY_1; day<=DAY_7; day++)
        {
            if ((str=(char *)GetLocaleStr(locale.li_Locale,day)) &&
                    (len=strlen(str))>GUI->date_length)
                GUI->date_length=len;
        }

        // Yesterday, etc
        for (day=YESTERDAYSTR; day<=FUTURESTR; day++)
        {
            if ((str=(char *)GetLocaleStr(locale.li_Locale,day)) &&
                    (len=strlen(str))>GUI->date_length)
                GUI->date_length=len;
        }
    }

    // Otherwise, use default (Yesterday)
    else GUI->date_length=9;

    // See if SysIHack is running
    if (FindTask("« sysihack »")) GUI->flags|=GUIF_SYSIHACK;

    // Allocate a string for spaces, and the global undo buffer
    if (!(str_space_string=AllocMemH(global_memory_pool,MAXDISPLAYLENGTH)) ||
            !(GUI->global_undo_buffer=AllocMemH(global_memory_pool,1024)))
        quit(0);
    for (a=0; a<MAXDISPLAYLENGTH-1; a++) str_space_string[a]=' ';

    // Allocate backdrop patterns
    if (!(GUI->pattern=AllocMemH(global_memory_pool,sizeof(PatternData)*3)))
        quit(0);

    // Initialise requester pattern
#if defined(__MORPHOS__)
    GUI->req_pattern.hook.h_Entry = (HOOKFUNC)HookEntry;
    GUI->req_pattern.hook.h_SubEntry=(ULONG (*)())PatternBackfill;
#else
    GUI->req_pattern.hook.h_Entry=(ULONG (*)())PatternBackfill;
#endif
    GUI->req_pattern.hook.h_Data=0;
    GUI->req_pattern.pattern=&GUI->pattern[PATTERN_REQ];
    GUI->req_pattern.disabled=FALSE;

    // Set requester pattern hook in library
    SetReqBackFill(&GUI->req_pattern.hook,&GUI->screen_pointer);
    GUI->flags2|=GUIF2_BACKFILL_SET;

    // Build kickstart version string
    if (GetVar("Kickstart",GUI->ver_kickstart,15,GVF_GLOBAL_ONLY)<1)
    {
        char *ptr3;
        ULONG ptr,*ptr2;
        UWORD ver,rev;

#ifdef __AROS__
        ver = ((struct Library *)SysBase)->lib_Version;
        rev = ((struct Library *)SysBase)->lib_Revision;
#else
        ptr2=(ULONG *)0xffffec;
        ptr=0x1000000-(*ptr2);
        ptr3=(char *)ptr+12;
        ptr2=(ULONG *)ptr3;
        ptr=*ptr2;

        ver=ptr>>16;
        rev=ptr&(((1<<32)-(1<<16))-1);
#endif

        lsprintf(GUI->ver_kickstart,"%ld.%ld",ver,rev);
    }
Beispiel #13
0
// Read an environment
BOOL environment_open(Cfg_Environment *env,char *name,BOOL first,APTR prog)
{
	struct OpenEnvironmentData *opendata;
	BOOL success;
	short progress=1;

	// Free volatile memory
	ClearMemHandle(env->volatile_memory);

	// Initialise open structure
	if (!(opendata=AllocMemH(env->volatile_memory,sizeof(struct OpenEnvironmentData))))
		return 0;
	opendata->memory=env->desktop_memory;
	opendata->volatile_memory=env->volatile_memory;
	opendata->flags=OEDF_ALL;


	// Initialise progress
	SetProgressWindowTags(prog,PW_FileCount,14,PW_FileNum,1,TAG_END);


	// Read environment
	if ((success=OpenEnvironment((name)?name:env->path,opendata)))
	{
		// Check stack setting and increase if too low
		if (opendata->env.default_stack < STACK_DEFAULT)
			opendata->env.default_stack = STACK_DEFAULT;

		// Copy things back to the environment
		CopyMem((char *)&opendata->env,(char *)env->env,sizeof(CFG_ENVR));
		strcpy(env->toolbar_path,opendata->toolbar_path);
		strcpy(env->menu_path,opendata->menu_path);
		strcpy(env->user_menu_path,opendata->user_menu_path);
		strcpy(env->scripts_path,opendata->scripts_path);
		strcpy(env->hotkeys_path,opendata->hotkeys_path);
		
		// Get maximum filename length
		// we have to do this before the listers are opened
		GUI->def_filename_length=environment->env->settings.max_filename;
		if (GUI->def_filename_length<FILENAME_LEN)
			GUI->def_filename_length=FILENAME_LEN;
		else
		if (GUI->def_filename_length>107)
			GUI->def_filename_length=107;
	}

	// Successful?
	if (success || first)
	{
		ButtonBankNode *button;
		OpenListerNode *lister;

		// Bump progress
		main_bump_progress(prog,progress++,0);

		// Store new environment path
		if (name) strcpy(env->path,name);

		// Bump progress
		main_bump_progress(prog,progress++,0);

		// Get new toolbar
		FreeToolBar(GUI->toolbar);
		GUI->toolbar=OpenToolBar(0,env->toolbar_path);

		// Bump progress
		main_bump_progress(prog,progress++,0);

		// Free lister menu, get new one
		CloseButtonBank(GUI->lister_menu);
		if ((GUI->lister_menu=OpenButtonBank(env->menu_path)))
		{
			// Check if it needs conversion
			if (!(GUI->lister_menu->window.flags&BTNWF_FIX_MENU))
			{
				// Convert it to new format
				ConvertStartMenu(GUI->lister_menu);
				GUI->lister_menu->window.flags|=BTNWF_FIX_MENU;
			}
		}

		// Bump progress
		main_bump_progress(prog,progress++,0);

		// Free user menu, get new one
		CloseButtonBank(GUI->user_menu);
		GUI->user_menu=OpenButtonBank(env->user_menu_path);

		// Bump progress
		main_bump_progress(prog,progress++,0);

		// Free scripts, get new set
		CloseButtonBank(GUI->scripts);
		GUI->scripts=OpenButtonBank(env->scripts_path);

		// Bump progress
		main_bump_progress(prog,progress++,0);

		// Free hotkeys, get new ones
		send_main_reset_cmd(CONFIG_CHANGE_HOTKEYS,0,0);

		// Go through buttons to open
		for (button=(ButtonBankNode *)opendata->buttons.mlh_Head;
			button->node.ln_Succ;)
		{
			ButtonBankNode *next=(ButtonBankNode *)button->node.ln_Succ;
			Buttons *but;

			// Create button bank from this node
			if ((but=buttons_new(button->node.ln_Name,0,&button->pos,0,button->flags|BUTTONF_FAIL)))
			{
				// Set icon position
				but->icon_pos_x=button->icon_pos_x;
				but->icon_pos_y=button->icon_pos_y;
			}

			// Free this node, get next
			Remove((struct Node *)button);
			FreeMemH(button->node.ln_Name);
			FreeMemH(button);
			button=next;
		}

		// Bump progress
		main_bump_progress(prog,progress++,0);

		// Go through StartMenus to open
		for (button=(ButtonBankNode *)opendata->startmenus.mlh_Head;
			button->node.ln_Succ;)
		{
			ButtonBankNode *next=(ButtonBankNode *)button->node.ln_Succ;

			// Create new start menu
			start_new(button->node.ln_Name,0,0,button->pos.Left,button->pos.Top);

			// Free this node, get next
			Remove((struct Node *)button);
			FreeMemH(button->node.ln_Name);
			FreeMemH(button);
			button=next;
		}

		// Bump progress
		main_bump_progress(prog,progress++,0);

		// Go through listers to open
		for (lister=(OpenListerNode *)opendata->listers.mlh_Head;
			lister->node.ln_Succ;)
		{
			OpenListerNode *next=(OpenListerNode *)lister->node.ln_Succ;

			// Create lister from this node
			if (lister->lister)
				lister_new((Cfg_Lister *)lister->lister);

			// Free this node, get next
			Remove((struct Node *)lister);
			FreeMemH(lister);
			lister=next;
		}

		// Bump progress
		main_bump_progress(prog,progress++,0);

		// Free existing desktop list
		env_free_desktop(&env->desktop);

		// Copy new desktop into list
		if (!(IsListEmpty((struct List *)&opendata->desktop)))
		{
			env->desktop=opendata->desktop;
			env->desktop.mlh_TailPred->mln_Succ=(struct MinNode *)&env->desktop.mlh_Tail;
			env->desktop.mlh_Head->mln_Pred=(struct MinNode *)&env->desktop.mlh_Head;
		}

		// Free existing path list
		env_free_desktop(&env->path_list);

		// Copy new pathlist into list
		if (!(IsListEmpty((struct List *)&opendata->pathlist)))
		{
			env->path_list=opendata->pathlist;
			env->path_list.mlh_TailPred->mln_Succ=(struct MinNode *)&env->path_list.mlh_Tail;
			env->path_list.mlh_Head->mln_Pred=(struct MinNode *)&env->path_list.mlh_Head;
		}

		// Free existing sound list
		env_free_desktop(&env->sound_list);

		// Copy new sound list into list
		if (!(IsListEmpty((struct List *)&opendata->soundlist)))
		{
			env->sound_list=opendata->soundlist;
			env->sound_list.mlh_TailPred->mln_Succ=(struct MinNode *)&env->sound_list.mlh_Tail;
			env->sound_list.mlh_Head->mln_Pred=(struct MinNode *)&env->sound_list.mlh_Head;
		}

		// Bump progress
		main_bump_progress(prog,progress++,0);

		// Update priority
		IPC_Command(&main_ipc,
			IPC_PRIORITY,
			env->env->settings.pri_main[1],
			(APTR)env->env->settings.pri_main[0],
			0,0);

		// Fix lister priorities
		lister_fix_priority(0);

		// Bump progress
		main_bump_progress(prog,progress++,0);
	}

	// Failed, free temp lists
	else
	{
		env_free_desktop(&opendata->desktop);
		env_free_desktop(&opendata->pathlist);
		env_free_desktop(&opendata->soundlist);
		env_free_desktop(&opendata->startmenus);
		env_free_desktop(&opendata->buttons);
		env_free_desktop(&opendata->listers);
	}

	// Free open data structure
	FreeMemH(opendata);

	// Bump progress
	main_bump_progress(prog,progress,0);

	// Build the user menu (needed even if there is none)
	display_build_user_menu();

	// Initialise progress
	SetProgressWindowTags(prog,PW_FileCount,1,PW_FileNum,1,TAG_END);

	// Set library flag for 'Move AppIcons to Tools Menu'
	SetLibraryFlags((env->env->display_options&DISPOPTF_SHIFT_APPICONS)?LIBDF_REDIRECT_TOOLS:0,LIBDF_REDIRECT_TOOLS);

	// Set library flag for borderless icons
	SetLibraryFlags((env->env->desktop_flags&DESKTOPF_NO_BORDERS)?LIBDF_BORDERS_OFF:0,LIBDF_BORDERS_OFF);

	// No icon caching?
	SetLibraryFlags((env->env->desktop_flags&DESKTOPF_NO_CACHE)?LIBDF_NO_CACHING:0,LIBDF_NO_CACHING);

	// Set NewIcons flags
	SetNewIconsFlags(env->env->env_NewIconsFlags,env->env->env_NewIconsPrecision);

	// No custom drag?
	SetLibraryFlags((env->env->desktop_flags&DESKTOPF_NO_CUSTOMDRAG)?LIBDF_NO_CUSTOM_DRAG:0,LIBDF_NO_CUSTOM_DRAG);

	// Thin borders?
	SetLibraryFlags((env->env->display_options&DISPOPTF_THIN_BORDERS)?LIBDF_THIN_BORDERS:0,LIBDF_THIN_BORDERS);

	// Update pathlist environment variable
	env_update_pathlist();

	// Set popup delay
	SetPopUpDelay(env->env->settings.popup_delay);

	// Fix MUFS library
	env_fix_mufs();

	// Assign themes path
	env_fix_themes();

	// Initialise sound events
	InitSoundEvents(TRUE);

	return success;
}
Beispiel #14
0
// Save an environment
int environment_save(Cfg_Environment *env,char *name,short snapshot,CFG_ENVR *data)
{
	APTR iff;
	long success=0;
	struct OpenEnvironmentData *opendata=0;
#ifdef __AROS__
	CFG_ENVR *env_be;
#endif

	// Invalid name?
	if (!name || !*name) return 0;

	// Get data pointer if not supplied
	if (!data) data=env->env;

#ifdef __AROS__
	if (!(env_be=AllocVec(sizeof(CFG_ENVR),MEMF_CLEAR)))
		return 0;
#endif

	// Update main window position
	if (snapshot&ENVSAVE_WINDOW)
	{
		GetSemaphore(&GUI->backdrop->window_lock,SEMF_SHARED,0);
		display_store_pos();
		FreeSemaphore(&GUI->backdrop->window_lock);
	}

	// Not snapshotting listers?
	if (!(snapshot&ENVSAVE_LAYOUT))
	{
		if ((opendata=AllocMemH(env->volatile_memory,sizeof(struct OpenEnvironmentData))))
		{
			opendata->memory=env->desktop_memory;
			opendata->volatile_memory=env->volatile_memory;
			opendata->flags=OEDF_BANK|OEDF_LSTR;
			OpenEnvironment(name,opendata);
		}
	}

	// Try to open file to write
	while ((iff=IFFOpen(name,MODE_NEWFILE,ID_EPUS)))
	{
		IPCData *ipc;
		Lister *lister;
		Buttons *buttons;
		Cfg_Desktop *desk;
		struct MinNode *node;
		Cfg_SoundEntry *sound;

		// Write environment settings
#ifdef __AROS__
		CopyMem(data,env_be,sizeof(CFG_ENVR));

		{
			int i;
		
			env_be->screen_mode = AROS_LONG2BE(env_be->screen_mode);
			env_be->screen_flags = AROS_WORD2BE(env_be->screen_flags);
			env_be->screen_depth = AROS_WORD2BE(env_be->screen_depth);
			env_be->screen_width = AROS_WORD2BE(env_be->screen_width);
			env_be->screen_height = AROS_WORD2BE(env_be->screen_height);

			for (i=0; i<50; i++)
				env_be->palette[i] = AROS_LONG2BE(env_be->palette[i]);
			
			env_be->window_pos.Left = AROS_WORD2BE(env_be->window_pos.Left);
			env_be->window_pos.Top = AROS_WORD2BE(env_be->window_pos.Top);
			env_be->window_pos.Width = AROS_WORD2BE(env_be->window_pos.Width);
			env_be->window_pos.Height = AROS_WORD2BE(env_be->window_pos.Height);
			env_be->general_screen_flags = AROS_LONG2BE(env_be->general_screen_flags);
			env_be->palette_count = AROS_WORD2BE(env_be->palette_count);
			
			for (i=0; i<CUST_PENS; i++)
			{
				env_be->env_Colours[i][0][0] = AROS_LONG2BE(env_be->env_Colours[i][0][0]);
				env_be->env_Colours[i][0][1] = AROS_LONG2BE(env_be->env_Colours[i][0][1]);
				env_be->env_Colours[i][0][2] = AROS_LONG2BE(env_be->env_Colours[i][0][2]);
				env_be->env_Colours[i][1][0] = AROS_LONG2BE(env_be->env_Colours[i][1][0]);
				env_be->env_Colours[i][1][1] = AROS_LONG2BE(env_be->env_Colours[i][1][1]);
				env_be->env_Colours[i][1][2] = AROS_LONG2BE(env_be->env_Colours[i][1][2]);
			}
			
			env_be->env_ColourFlag = AROS_LONG2BE(env_be->env_ColourFlag);
			env_be->env_NewIconsFlags = AROS_LONG2BE(env_be->env_NewIconsFlags);
			env_be->display_options = AROS_WORD2BE(env_be->display_options);
			env_be->main_window_type = AROS_WORD2BE(env_be->main_window_type);
			env_be->hotkey_flags = AROS_WORD2BE(env_be->hotkey_flags);
			env_be->hotkey_code = AROS_WORD2BE(env_be->hotkey_code);
			env_be->hotkey_qual = AROS_WORD2BE(env_be->hotkey_qual);
			env_be->default_stack = AROS_LONG2BE(env_be->default_stack);
			env_be->lister_options = AROS_WORD2BE(env_be->lister_options);
			env_be->flags = AROS_LONG2BE(env_be->flags);
			env_be->lister_popup_code = AROS_WORD2BE(env_be->lister_popup_code);
			env_be->lister_popup_qual = AROS_WORD2BE(env_be->lister_popup_qual);
			env_be->env_flags = AROS_LONG2BE(env_be->env_flags);
			env_be->clock_left = AROS_WORD2BE(env_be->clock_left);
			env_be->clock_top = AROS_WORD2BE(env_be->clock_top);
			env_be->lister_width = AROS_WORD2BE(env_be->lister_width);
			env_be->lister_height = AROS_WORD2BE(env_be->lister_height);
			env_be->version = AROS_WORD2BE(env_be->version);
			env_be->desktop_flags = AROS_LONG2BE(env_be->desktop_flags);
			
			for (i=0; i<4; i++)
				env_be->env_BackgroundFlags[i] = AROS_WORD2BE(env_be->env_BackgroundFlags[i]);
		
			env_be->settings.copy_flags = AROS_LONG2BE(env_be->settings.copy_flags);
			env_be->settings.delete_flags = AROS_LONG2BE(env_be->settings.delete_flags);
			env_be->settings.error_flags = AROS_LONG2BE(env_be->settings.error_flags);
			env_be->settings.general_flags = AROS_LONG2BE(env_be->settings.general_flags);
			env_be->settings.icon_flags = AROS_LONG2BE(env_be->settings.icon_flags);
			env_be->settings.replace_method = AROS_WORD2BE(env_be->settings.replace_method);
			env_be->settings.replace_flags = AROS_WORD2BE(env_be->settings.replace_flags);
			env_be->settings.update_flags = AROS_LONG2BE(env_be->settings.update_flags);
			env_be->settings.dir_flags = AROS_LONG2BE(env_be->settings.dir_flags);
			env_be->settings.view_flags = AROS_LONG2BE(env_be->settings.view_flags);
			env_be->settings.max_buffer_count = AROS_WORD2BE(env_be->settings.max_buffer_count);
			env_be->settings.date_format = AROS_WORD2BE(env_be->settings.date_format);
			env_be->settings.date_flags = AROS_WORD2BE(env_be->settings.date_flags);
			env_be->settings.pop_code = AROS_WORD2BE(env_be->settings.pop_code);
			env_be->settings.pop_qual = AROS_WORD2BE(env_be->settings.pop_qual);
			env_be->settings.pop_qual_mask = AROS_WORD2BE(env_be->settings.pop_qual_mask);
			env_be->settings.pop_qual_same = AROS_WORD2BE(env_be->settings.pop_qual_same);
			env_be->settings.popup_delay = AROS_WORD2BE(env_be->settings.popup_delay);
			env_be->settings.max_openwith = AROS_WORD2BE(env_be->settings.max_openwith);
			env_be->settings.command_line_length = AROS_WORD2BE(env_be->settings.command_line_length);
			env_be->settings.max_filename = AROS_WORD2BE(env_be->settings.max_filename);
			env_be->settings.flags = AROS_LONG2BE(env_be->settings.flags);
			
			for (i=0; i<4; i++)
				env_be->env_BackgroundBorderColour[i] = AROS_LONG2BE(env_be->env_BackgroundBorderColour[i]);
		}

		if (!(IFFWriteChunk(iff,env_be,ID_ENVR,sizeof(CFG_ENVR))))
#else
		if (!(IFFWriteChunk(iff,data,ID_ENVR,sizeof(CFG_ENVR))))
#endif
		{
			success=IoErr();
			break;
		}

		// Write some path names
		if ((success=write_env_string(iff,env->toolbar_path,ID_TBAR)) ||
			(success=write_env_string(iff,env->menu_path,ID_LMEN)) ||
			(success=write_env_string(iff,env->user_menu_path,ID_UMEN)) ||
			(success=write_env_string(iff,env->scripts_path,ID_SCRP)) ||
			(success=write_env_string(iff,env->hotkeys_path,ID_HKEY)))
			break;

		// Not snapshotting?
		if (!(snapshot&ENVSAVE_LAYOUT) && opendata)
		{
			ButtonBankNode *button;
			OpenListerNode *lister;

			// Go through existing listers
			for (lister=(OpenListerNode *)opendata->listers.mlh_Head;
				lister->node.ln_Succ;)
			{
				OpenListerNode *next=(OpenListerNode *)lister->node.ln_Succ;

				// Write lister data
				if (!(SaveListerDef(iff,(Cfg_Lister *)lister->lister))) break;

				// Remove this node, get next
				Remove((struct Node *)lister);
				lister=next;
			}

			// Go through buttons to open
			for (button=(ButtonBankNode *)opendata->buttons.mlh_Head;
				button->node.ln_Succ;)
			{
				ButtonBankNode *next=(ButtonBankNode *)button->node.ln_Succ;
				ULONG pad[5];
#ifdef __AROS__
				struct IBox pos_be;
#endif

				// Write bank header
				if (!(IFFPushChunk(iff,ID_BANK))) break;

				// Fill out padding
				pad[0]=0;
				pad[1]=0;
				pad[2]=button->icon_pos_x;
				pad[3]=button->icon_pos_y;
				pad[4]=button->flags&BUTTONF_ICONIFIED;

#ifdef __AROS__
				CopyMem(&button->pos,&pos_be,sizeof(struct IBox));

				pos_be.Left = AROS_WORD2BE(pos_be.Left);
				pos_be.Top = AROS_WORD2BE(pos_be.Top);
				pos_be.Width = AROS_WORD2BE(pos_be.Width);
				pos_be.Height = AROS_WORD2BE(pos_be.Height);

				pad[2] = AROS_LONG2BE(pad[2]);
				pad[3] = AROS_LONG2BE(pad[3]);
				pad[4] = AROS_LONG2BE(pad[4]);
				
				if (!(IFFWriteChunkBytes(iff,pad,sizeof(pad))) ||
					!(IFFWriteChunkBytes(iff,&pos_be,sizeof(struct IBox))) ||
					!(IFFWriteChunkBytes(iff,button->node.ln_Name,strlen(button->node.ln_Name)+1)) ||
					!(IFFPopChunk(iff))) break;
#else
				// Write padding and position and path
				if (!(IFFWriteChunkBytes(iff,pad,sizeof(pad))) ||
					!(IFFWriteChunkBytes(iff,&button->pos,sizeof(struct IBox))) ||
					!(IFFWriteChunkBytes(iff,button->node.ln_Name,strlen(button->node.ln_Name)+1)) ||
					!(IFFPopChunk(iff))) break;
#endif

				// Remove this node, get next
				Remove((struct Node *)button);
				button=next;
			}

			// Go through StartMenus to open
			for (button=(ButtonBankNode *)opendata->startmenus.mlh_Head;
				button->node.ln_Succ;)
			{
				ButtonBankNode *next=(ButtonBankNode *)button->node.ln_Succ;
				ULONG pad[5];
#ifdef __AROS__
				struct IBox pos_be;
#endif

				// Write bank header
				if (!(IFFPushChunk(iff,ID_STRT))) break;

				// Fill out padding
				pad[0]=0;
				pad[1]=0;
				pad[2]=button->icon_pos_x;
				pad[3]=button->icon_pos_y;
				pad[4]=button->flags;

#ifdef __AROS__
				CopyMem(&button->pos,&pos_be,sizeof(struct IBox));

				pos_be.Left = AROS_WORD2BE(pos_be.Left);
				pos_be.Top = AROS_WORD2BE(pos_be.Top);
				pos_be.Width = AROS_WORD2BE(pos_be.Width);
				pos_be.Height = AROS_WORD2BE(pos_be.Height);

				pad[2] = AROS_LONG2BE(pad[2]);
				pad[3] = AROS_LONG2BE(pad[3]);
				pad[4] = AROS_LONG2BE(pad[4]);
				
				if (!(IFFWriteChunkBytes(iff,pad,sizeof(pad))) ||
					!(IFFWriteChunkBytes(iff,&pos_be,sizeof(struct IBox))) ||
					!(IFFWriteChunkBytes(iff,button->node.ln_Name,strlen(button->node.ln_Name)+1)) ||
					!(IFFPopChunk(iff))) break;
#else
				// Write padding and position and path
				if (!(IFFWriteChunkBytes(iff,pad,sizeof(pad))) ||
					!(IFFWriteChunkBytes(iff,&button->pos,sizeof(struct IBox))) ||
					!(IFFWriteChunkBytes(iff,button->node.ln_Name,strlen(button->node.ln_Name)+1)) ||
					!(IFFPopChunk(iff))) break;
#endif

				// Remove this node, get next
				Remove((struct Node *)button);
				button=next;
			}
		}

		// Otherwise, snapshotting current layout
		else
		{
			// Lock lister list
			lock_listlock(&GUI->lister_list,FALSE);

			// Write lister definitions
			for (ipc=(IPCData *)GUI->lister_list.list.lh_Head;
				ipc->node.mln_Succ;
				ipc=(IPCData *)ipc->node.mln_Succ)
			{
				// Get lister
				lister=IPCDATA(ipc);

				// Valid lister definition?
				if (lister->lister)
				{
					// Update lister
					lister_update(lister);

					// Write lister data
					if (!(SaveListerDef(iff,lister->lister))) break;
				}
			}

			// Unlock lister list
			unlock_listlock(&GUI->lister_list);

			// Fail?
			if (ipc->node.mln_Succ)
			{
				success=IoErr();
				break;
			}

			// Lock buttons list
			lock_listlock(&GUI->buttons_list,FALSE);

			// Write button file paths
			for (ipc=(IPCData *)GUI->buttons_list.list.lh_Head;
				ipc->node.mln_Succ;
				ipc=(IPCData *)ipc->node.mln_Succ)
			{
				// Get buttons pointer
				buttons=IPCDATA(ipc);

				// Valid button configuration?
				if (buttons->bank && buttons->bank->path[0])
				{
					ULONG pad[5];
#ifdef __AROS__
					struct IBox pos_be;
#endif

					// Update buttons
					buttons_update(buttons);

					// Write bank header
					if (!(IFFPushChunk(iff,ID_BANK))) break;

					// Fill out padding
					pad[0]=0;
					pad[1]=0;
					pad[2]=buttons->icon_pos_x;
					pad[3]=buttons->icon_pos_y;
					pad[4]=buttons->flags&BUTTONF_ICONIFIED;

#ifdef __AROS__
					CopyMem(&buttons->pos,&pos_be,sizeof(struct IBox));

					pos_be.Left = AROS_WORD2BE(pos_be.Left);
					pos_be.Top = AROS_WORD2BE(pos_be.Top);
					pos_be.Width = AROS_WORD2BE(pos_be.Width);
					pos_be.Height = AROS_WORD2BE(pos_be.Height);

					pad[2] = AROS_LONG2BE(pad[2]);
					pad[3] = AROS_LONG2BE(pad[3]);
					pad[4] = AROS_LONG2BE(pad[4]);
					
					if (!(IFFWriteChunkBytes(iff,pad,sizeof(pad))) ||
						!(IFFWriteChunkBytes(iff,&pos_be,sizeof(struct IBox))) ||
						!(IFFWriteChunkBytes(iff,buttons->bank->path,strlen(buttons->bank->path)+1)) ||
						!(IFFPopChunk(iff))) break;
#else
					// Write padding and position and path
					if (!(IFFWriteChunkBytes(iff,pad,sizeof(pad))) ||
						!(IFFWriteChunkBytes(iff,&buttons->pos,sizeof(struct IBox))) ||
						!(IFFWriteChunkBytes(iff,buttons->bank->path,strlen(buttons->bank->path)+1)) ||
						!(IFFPopChunk(iff))) break;
#endif
				}
			}

			// Unlock buttons list
			unlock_listlock(&GUI->buttons_list);

			// Fail?
			if (ipc->node.mln_Succ)
			{
				success=IoErr();
				break;
			}

			// Lock StartMenu list
			lock_listlock(&GUI->startmenu_list,FALSE);

			// Write StartMenu paths
			for (ipc=(IPCData *)GUI->startmenu_list.list.lh_Head;
				ipc->node.mln_Succ;
				ipc=(IPCData *)ipc->node.mln_Succ)
			{
				StartMenu *menu;

				// Get menu pointer
				menu=(StartMenu *)IPCDATA(ipc);

				// Lock the bank
				GetSemaphore(&menu->lock,SEMF_SHARED,0);

				// Valid configuration?
				if (menu->bank && menu->bank->path[0])
				{
					ULONG pad[5];
					struct IBox pos;

					// Get position
					pos.Left=menu->bank->window.pos.Left;
					pos.Top=menu->bank->window.pos.Top;
#ifdef __AROS__
					pos.Left = AROS_WORD2BE(pos.Left);
					pos.Top = AROS_WORD2BE(pos.Top);
#endif

					// Write menu header
					if (!(IFFPushChunk(iff,ID_STRT))) break;

					// Fill out padding
					pad[0]=0;
					pad[1]=0;
					pad[2]=0;
					pad[3]=0;
					pad[4]=0;

					// Write padding and position and path
					if (!(IFFWriteChunkBytes(iff,pad,sizeof(pad))) ||
						!(IFFWriteChunkBytes(iff,&pos,sizeof(struct IBox))) ||
						!(IFFWriteChunkBytes(iff,menu->bank->path,strlen(menu->bank->path)+1)) ||
						!(IFFPopChunk(iff))) break;
				}

				// Unlock bank
				FreeSemaphore(&menu->lock);
			}

			// Unlock startmenu list
			unlock_listlock(&GUI->startmenu_list);

			// Fail?
			if (ipc->node.mln_Succ) success=IoErr();
		}

		// Failed?
		if (success) break;

		// Go through desktop list
		for (desk=(Cfg_Desktop *)env->desktop.mlh_Head;
			desk->node.mln_Succ;
			desk=(Cfg_Desktop *)desk->node.mln_Succ)
		{
#ifdef __AROS__
			char buffer[64]; // 12 bytes CFG_DESK + 34 bytes device name + 18 bytes extra
			CFG_DESK *desk_be = (CFG_DESK *)buffer;

			CopyMem(&desk->data,desk_be,desk->data.dt_Size);

			desk_be->dt_Type = AROS_WORD2BE(desk_be->dt_Type);
			desk_be->dt_Size = AROS_WORD2BE(desk_be->dt_Size);
			desk_be->dt_Flags = AROS_LONG2BE(desk_be->dt_Flags);
			if (desk->data.dt_Type != DESKTOP_HIDE_BAD && desk->data.dt_Type != DESKTOP_HIDE)
				desk_be->dt_Data = AROS_LONG2BE(desk_be->dt_Data);

			if (!(IFFWriteChunk(iff,desk_be,ID_DESK,desk->data.dt_Size)))
#else
			// Write chunk
			if (!(IFFWriteChunk(iff,&desk->data,ID_DESK,desk->data.dt_Size)))
#endif
			{
				success=IoErr();
				break;
			}
		}

		// Go through pathlist
		for (node=env->path_list.mlh_Head;node->mln_Succ;node=node->mln_Succ)
		{
			// Write chunk
			if (!(IFFWriteChunk(iff,(char *)(node+1),ID_PATH,strlen((char *)(node+1)))))
			{
				success=IoErr();
				break;
			}
		}

		// Go through sound list
		for (sound=(Cfg_SoundEntry *)env->sound_list.mlh_Head;sound->dse_Node.ln_Succ;sound=(Cfg_SoundEntry *)sound->dse_Node.ln_Succ)
		{
#ifdef __AROS__
			Cfg_SoundEntry sound_be;

			CopyMem(&sound,&sound_be,sizeof(Cfg_SoundEntry));

			sound_be.dse_Volume = AROS_WORD2BE(sound_be.dse_Volume);
			sound_be.dse_Flags = AROS_WORD2BE(sound_be.dse_Flags);

			if (!(IFFWriteChunk(iff,sound_be.dse_Name,ID_SNDX,32+2+2+strlen(sound->dse_Sound)+1)))
#else
			// Write chunk
			if (!(IFFWriteChunk(iff,sound->dse_Name,ID_SNDX,32+2+2+strlen(sound->dse_Sound)+1)))
#endif
			{
				success=IoErr();
				break;
			}
		}
		break;
	}

	// Close file
	if (!iff) success=IoErr();
	else IFFClose(iff);

#ifdef __AROS__
	FreeVec(env_be);
#endif

	// Write icon if successful (and enabled)
	if ((!success) && (GUI->flags&GUIF_SAVE_ICONS))
	{
		WriteFileIcon("dopus5:icons/Environment",name);
	}

	// Free stuff
	FreeMemH(opendata);
	ClearMemHandle(env->volatile_memory);
	return success;
}
Beispiel #15
0
// Add an AppIcon from rexx
long rexx_add_appicon(char *str,struct RexxMsg *msg)
{
	char iconfile[256],menustem[80];
	RexxAppThing *app;
	struct TagItem *tags;
	short key,menu_count=0,count;
	long base=0;
	APTR memory;

	// Allocate AppNode
	if (!(app=AllocVec(sizeof(RexxAppThing),MEMF_CLEAR)))
		return 0;

	// Allocate memory handle
	if (!(memory=NewMemHandle(0,0,MEMF_CLEAR)))
	{
		FreeVec(app);
		return 0;
	}

	// Set type
	app->node.ln_Type=REXXAPP_ICON;

	// Initialise position
	app->pos_x=NO_ICON_POSITION;
	app->pos_y=NO_ICON_POSITION;

	// Get port name
	rexx_parse_word(&str,app->port_name,sizeof(app->port_name));

	// Get icon name
	rexx_parse_word(&str,app->icon_name,sizeof(app->icon_name));

	// Get ID
	rexx_skip_space(&str);
	app->id=rexx_parse_number(&str,0,0);

	// Clear buffers
	iconfile[0]=0;
	menustem[0]=0;

	// Position set?
	rexx_skip_space(&str);
	while ((key=rexx_match_keyword(&str,pos_keys,0))!=-1)
	{
		// Position?
		if (key==APPARG_POS)
		{
			// Get position
			app->pos_x=rexx_parse_number(&str,1,NO_ICON_POSITION);
			app->pos_y=rexx_parse_number(&str,0,NO_ICON_POSITION);
		}

		// Quotes?
		else
		if (key==APPARG_QUOTES) app->flags|=RATF_QUOTES;

		// Info?
		else
		if (key==APPARG_INFO) app->flags|=RATF_INFO;

		// Snapshot
		else
		if (key==APPARG_SNAP) app->flags|=RATF_SNAP;

		// Close
		else
		if (key==APPARG_CLOSE) app->flags|=RATF_CLOSE;

		// Local
		else
		if (key==APPARG_LOCAL) app->flags|=RATF_LOCAL;

		// Locked
		else
		if (key==APPARG_LOCKED) app->flags|=RATF_LOCKED;

		// Icon
		else
		if (key==APPARG_ICON)
		{
			// Get filename
			rexx_parse_word(&str,iconfile,256);
		}

		// Menu
		else
		if (key==APPARG_MENU)
		{
			// Get menu stem
			if (rexx_parse_word(&str,menustem,30))
			{
				// Check stem has a period
				if (menustem[0] && menustem[strlen(menustem)-1]!='.')
					strcat(menustem,".");
			}
		}

		// Skip spaces
		rexx_skip_space(&str);
	}

	// Try and get icon
	if (iconfile[0]) app->icon=GetCachedDiskObject(iconfile,GCDOF_NOCACHE);

	// Failed? Get default
	if (!app->icon &&
		!(app->icon=GetCachedDefDiskObject(WBTOOL|GCDOF_NOCACHE)))
	{
		// Failed completely
		FreeVec(app);
		return 0;
	}

	// Set icon position
	app->icon->do_CurrentX=app->pos_x-WBICONMAGIC_X;
	app->icon->do_CurrentY=app->pos_y-WBICONMAGIC_Y;
	SetIconFlags(app->icon,GetIconFlags(app->icon)&~ICONF_POSITION_OK);

	// Remap the icon (only if a local one)
	if (app->flags&RATF_LOCAL)
		RemapIcon(app->icon,GUI->screen_pointer,FALSE);

	// Menu items?
	if (menustem[0])
	{
		char buffer[10];

		// Get count
		rexx_get_var(msg,menustem,"COUNT",buffer,10);
		menu_count=atoi(buffer);

		// Get base
		if (rexx_get_var(msg,menustem,"BASE",buffer,10))
			base=atoi(buffer);
	}

	// Number of tags needed
	count=7+menu_count;

	// Allocate tags
	if ((tags=AllocMemH(memory,sizeof(struct TagItem)*count)))
	{
		// Initialise tags
		tags[0].ti_Tag=DAE_SnapShot;
		tags[0].ti_Data=(app->flags&RATF_SNAP)?1:0;
		tags[1].ti_Tag=DAE_Info;
		tags[1].ti_Data=(app->flags&RATF_INFO)?1:0;
		tags[2].ti_Tag=DAE_Close;
		tags[2].ti_Data=(app->flags&RATF_CLOSE)?1:0;
		tags[3].ti_Tag=(app->flags&RATF_LOCAL)?DAE_Local:TAG_IGNORE;
		tags[3].ti_Data=1;
		tags[4].ti_Tag=DAE_Locked;
		tags[4].ti_Data=(app->flags&RATF_LOCKED)?1:0;
		tags[5].ti_Tag=DAE_MenuBase;
		tags[5].ti_Data=base;

		// Go through menus
		for (count=0;count<menu_count;count++)
		{
			char buffer[80];

			// Build variable name
			lsprintf(iconfile,"%ld",count);

			// Get variable
			if (rexx_get_var(msg,menustem,iconfile,buffer,80))
			{
				// Allocate buffer
				if ((tags[count+6].ti_Data=(ULONG)AllocMemH(memory,strlen(buffer)+1)))
				{
					// Copy name
					strcpy((char *)tags[count+6].ti_Data,buffer);

					// Set tag ID
					tags[count+6].ti_Tag=DAE_Menu;
				}
				else tags[count+6].ti_Tag=TAG_IGNORE;
			}

			// Skip this tag
			else tags[count+6].ti_Tag=TAG_IGNORE;
		}
	}

	// Add AppIcon
	app->app_thing=
		AddAppIconA(
			app->id,
			(ULONG)app,
			app->icon_name,
			GUI->rexx_app_port,
			0,
			app->icon,
			tags);

	// Free memory
	FreeMemHandle(memory);

	// Failed?
	if (!app->app_thing)
	{
		// Failed
		if (app->flags&RATF_LOCAL)
			RemapIcon(app->icon,GUI->screen_pointer,FALSE);
		FreeCachedDiskObject(app->icon);
		FreeVec(app);
		return 0;
	}

	// Add to AppList
	lock_listlock(&GUI->rexx_apps,TRUE);
	AddTail(&GUI->rexx_apps.list,(struct Node *)app);
	unlock_listlock(&GUI->rexx_apps);

	return (long)app;
}
short LIBFUNC L_Config_Filetypes(
	REG(a0, struct Screen *screen),
	REG(a1, IPCData *ipc),
	REG(a2, IPCData *owner_ipc),
	REG(d0, ULONG command_list),
	REG(a3, char *name))
{
	config_filetypes_data *data;
	IPCMessage *quit_msg=0;
	short undo_flag=0,pending_quit=0;
	short ret=0,fontsize;
	struct IBox pos;
	ConfigWindow dims;

	// Allocate data and memory handle
	if (!(data=AllocVec(sizeof(config_filetypes_data),MEMF_CLEAR)) ||
		!(data->memory=NewMemHandle(4096,256,MEMF_CLEAR)))
		return 0;

	// Save pointers
	data->ipc=ipc;
	data->owner_ipc=owner_ipc;
	data->command_list=command_list;

	// Initialise data
	NewList(&data->list_list);
	InitListLock(&data->proc_list,0);

	// Fill in new window
	data->newwin.parent=screen;
	data->newwin.dims=&dims;
	data->newwin.title=GetString(locale,MSG_FILETYPES_TITLE);
	data->newwin.locale=locale;
	data->newwin.flags=WINDOW_SCREEN_PARENT|WINDOW_VISITOR|WINDOW_REQ_FILL|WINDOW_AUTO_KEYS|WINDOW_SIZE_BOTTOM;

	// Get default size
	dims=_config_filetypes_window;

	// Get saved position
	if (LoadPos("dopus/windows/filetypes",&pos,&fontsize))
	{
		dims.char_dim.Width=0;
		dims.char_dim.Height=0;
		dims.fine_dim.Width=pos.Width;
		dims.fine_dim.Height=pos.Height;
	}
		
	// Open window and add objects
	if (!(data->window=OpenConfigWindow(&data->newwin)) ||
		!(data->objlist=AddObjectList(data->window,_config_filetypes_objects)))
	{
		CloseConfigWindow(data->window);
		FreeMemHandle(data->memory);
		FreeVec(data);
		return 0;
	}

	// Set minimum size
	SetConfigWindowLimits(data->window,&_config_filetypes_window,0);

	// Read filetype list
	SetWindowBusy(data->window);
	filetype_read_list(data->memory,&data->list_list);

	// Build display list
	filetype_build_list(data);
	ClearWindowBusy(data->window);

	// Name to edit?
	if (name) filetype_edit_name(data,name);

	// Event loop
	FOREVER
	{
		struct IntuiMessage *msg;
		IPCMessage *imsg;
		int quit_flag=0;

		// Any IPC messages?
		while ((imsg=(IPCMessage *)GetMsg(ipc->command_port)))
		{
			// Look at command
			switch (imsg->command)
			{
				// Quit
				case IPC_QUIT:
					quit_flag=1;
					quit_msg=imsg;
					imsg=0;
					data->change=0;
					break;


				// Activate
				case IPC_ACTIVATE:
					if (data->window)
					{
						// Bring window to front
						WindowToFront(data->window);
						ActivateWindow(data->window);

						// Edit name supplied?
						if (imsg->data) filetype_edit_name(data,(char *)imsg->data);
					}
					break;


				// Process saying goodbye
				case IPC_GOODBYE:
					{
						FiletypeNode *node;

						// Handle goodbye
						if ((node=(FiletypeNode *)IPC_GetGoodbye(imsg)))
						{
							// Node no longer has an editor
							node->editor=0;
						}

						// All process gone and pending quit?
						if (pending_quit && (IsListEmpty(&data->proc_list.list)))
						{
							quit_flag=1;
							pending_quit=2;
						}
					}
					break;


				// Got a filetype back from the editor
				case FILETYPEEDIT_RETURN:
					if (filetype_receive_edit(
						data,
						(Cfg_Filetype *)imsg->flags,
						(FiletypeNode *)imsg->data))
					{
						data->change=1;
						imsg->command=1;
					}
					else imsg->command=0;
					break;
			}

			// Reply message
			IPC_Reply(imsg);

			// Check quit flag
			if (quit_flag) break;
		}

		// Intuimessages
		if (data->window)
		{
			while ((msg=GetWindowMsg(data->window->UserPort)))
			{
				struct IntuiMessage msg_copy;
				UWORD id;

				// Copy message and reply
				msg_copy=*msg;
				ReplyWindowMsg(msg);

				if (pending_quit) continue;

				// Look at message
				switch (msg_copy.Class)
				{
					// Close window
					case IDCMP_CLOSEWINDOW:
						quit_flag=1;
						undo_flag=1;
						break;


					// Gadget
					case IDCMP_GADGETUP:

						id=((struct Gadget *)msg_copy.IAddress)->GadgetID;
						switch (id)
						{
							// Cancel
							case GAD_FILETYPES_CANCEL:
								undo_flag=1;

							// Use
							case GAD_FILETYPES_USE:
								quit_flag=1;
								break;


							// Filetype selected
							case GAD_FILETYPES_LIST:
								{
									Att_Node *node;

									// Enable buttons
									filetype_able_buttons(data,FALSE);

									// Get selection
									if (!(node=Att_FindNode(data->filetype_list,msg_copy.Code)))
										break;

									// Double-click?
									if (node==data->sel_filetype &&
										DoubleClick(
											data->seconds,data->micros,
											msg_copy.Seconds,msg_copy.Micros))
									{
										// Launch editor for this filetype
										filetype_edit(data,(FiletypeNode *)data->sel_filetype->data,0);
									}

									// New selection
									else
									{
										data->sel_filetype=node;
										data->seconds=msg_copy.Seconds;
										data->micros=msg_copy.Micros;
									}
								}
								break;


							// Add a new filetype
							case GAD_FILETYPES_DUPLICATE:
								if (!data->sel_filetype) break;
							case GAD_FILETYPES_ADD:
								{
									Cfg_FiletypeList *list;
									Cfg_Filetype *type=0;

									// Allocate a new filetype list
									if ((list=AllocMemH(data->memory,sizeof(Cfg_FiletypeList))))
									{
										// Initialise list
										NewList(&list->filetype_list);

										// Copy existing filetype?
										if ((((struct Gadget *)msg_copy.IAddress)->GadgetID==
											GAD_FILETYPES_DUPLICATE))
										{
											// Copy filetype
											type=CopyFiletype(
												((FiletypeNode *)data->sel_filetype->data)->type,
												data->memory);
										}

										// Allocate a new filetype
										else if ((type=NewFiletype(data->memory)))
										{
											// Initialise name
											strcpy(type->type.name,GetString(locale,MSG_UNTITLED));
										}

										// Get a filetype?
										if (type)
										{
											// Add filetype list to main list
											AddTail(&data->list_list,&list->node);

											// Add filetype to list
											AddTail(&list->filetype_list,&type->node);

											// Set list pointer
											type->list=list;
											list->flags=FTLISTF_CHANGED;
										}

										// Failed
										else FreeMemH(list);
									}

									// Got new filetype?
									if (type)
									{
										Att_Node *node;

										// Remove existing list
										SetGadgetChoices(
											data->objlist,
											GAD_FILETYPES_LIST,
											(APTR)~0);

										// Add entry for this filetype
										node=filetype_add_entry(data,type);

										// Handle new nodes
										filetype_new_node(data,node);
									}
								}
								break;


							// Edit filetype
							case GAD_FILETYPES_EDIT:

								// Valid selection?
								if (data->sel_filetype)
								{
									// Launch editor for this filetype
									filetype_edit(data,(FiletypeNode *)data->sel_filetype->data,0);
								}
								break;


							// Remove/Store
							case GAD_FILETYPES_REMOVE:
							case GAD_FILETYPES_STORE:

								// Valid selection?
								if (data->sel_filetype)
								{
									short ret;

									// Remove filetype
									if ((ret=
										filetype_remove(
											data,
											data->sel_filetype,
											(id==GAD_FILETYPES_STORE)))==1)
									{
										data->change=1;
										data->sel_filetype=0;
									}

									// Quit?
									else if (ret==-1)
									{
										quit_flag=1;
									}
								}
								break;
						}
						break;


					// Key press
					case IDCMP_RAWKEY:

						// Help?
						if (msg_copy.Code==0x5f &&
							!(msg_copy.Qualifier&VALID_QUALIFIERS))
						{
							// Set busy pointer
							SetWindowBusy(data->window);

							// Send help command
							IPC_Command(data->owner_ipc,IPC_HELP,(1<<31),"File Types",0,REPLY_NO_PORT);

							// Clear busy pointer
							ClearWindowBusy(data->window);
						}
						break;
				}

				// Check quit flag
				if (quit_flag) break;
			}
		}

		// Check quit flag
		if (quit_flag)
		{
			if (!pending_quit)
			{
				SetWindowBusy(data->window);
				if (!(IPC_ListQuit(&data->proc_list,0,!undo_flag,FALSE)))
					pending_quit=2;
				else
					pending_quit=1;
			}
		}

		// Set to break?
		if (pending_quit==2)
		{
			// Save filetypes?
			if (data->change && !undo_flag)
			{
				if (!(ret=filetype_save(data)))
				{
					// Abort save/quit
					ClearWindowBusy(data->window);
					pending_quit=0;
					continue;
				}
			}
			break;
		}

		// Wait for an event
		Wait(1<<ipc->command_port->mp_SigBit|
			((data->window)?1<<data->window->UserPort->mp_SigBit:0));
	}

	// Save window position
	if (data->window)
	{
		struct IBox pos;
		pos.Left=data->window->LeftEdge;
		pos.Top=data->window->TopEdge;
		pos.Width=data->window->Width-data->window->BorderLeft-data->window->BorderRight;
		pos.Height=data->window->Height-data->window->BorderTop-data->window->BorderBottom;
		SavePos("dopus/windows/filetypes",(struct IBox *)&pos,data->window->RPort->TxHeight);
	}

	// Close up
	CloseConfigWindow(data->window);

	// Free data
	Att_RemList(data->filetype_list,REMLIST_FREEDATA);
	FreeMemHandle(data->memory);
	FreeVec(data);

	// Reply quit message
	IPC_Reply(quit_msg);
	return ret;
}
// Snapshot objects
void backdrop_snapshot(BackdropInfo *info,BOOL unsnapshot,BOOL all,BackdropObject *icon)
{
	BackdropObject *object;
	Lister *lister;
	IPCData *ipc;
	BPTR old,lock;
	short count=0,beep=0;
#ifdef DISTINCT_OK
	BOOL save_env=0;
#endif
	BOOL savepos=0;

	// Lock backdrop list
	lock_listlock(&info->objects,0);

	// Lock lister list
	lock_listlock(&GUI->lister_list,0);

	// Lock group list
	lock_listlock(&GUI->group_list,0);

	// Go through backdrop list
	for (object=(BackdropObject *)info->objects.list.lh_Head;
		object->node.ln_Succ;
		object=(BackdropObject *)object->node.ln_Succ)
	{
		BOOL ok=0;

		// Icon supplied?
		if (icon)
		{
			// Does it match?
			if (object!=icon || !object->icon) continue;
		}

		// Is object selected?
		else
		if ((!object->state && !all) || !object->icon) continue;
		beep=1;

		// Appicon?
		if (object->type==BDO_APP_ICON)
		{
			// Does icon support snapshot itself?
			if (WB_AppIconFlags((struct AppIcon *)object->misc_data)&APPENTF_SNAPSHOT)
			{
				backdrop_appicon_message(object,(unsnapshot)?BAPPF_UNSNAPSHOT:0);
				++count;
			}

			// Otherwise, fake snapshot
			else
			if (*object->name) ok=1;
		}

		// Otherwise, is it ok to snapshot?
		else
		if (object->type!=BDO_BAD_DISK) ok=1;

		// Ok to snapshot?
		if (ok)
		{
			short x,y;

			// UnShapshot?
			if (unsnapshot)
			{
				// Set "no position" position
				x=-1;
				y=-1;
			}

			// Snapshot
			else
			{
				// Drawer?
				if (object->icon->do_DrawerData)
				{
					// Group icon?
					if (object->type==BDO_GROUP)
					{
						GroupData *group;

						// See if group is open
						if ((group=backdrop_find_group(object)))
						{
							// Update window position
							*((struct IBox *)&object->icon->do_DrawerData->dd_NewWindow.LeftEdge)=group->dimensions;
						}
					}

					// Otherwise go through listers
					else
					for (ipc=(IPCData *)GUI->lister_list.list.lh_Head;
						ipc->node.mln_Succ;
						ipc=(IPCData *)ipc->node.mln_Succ)
					{
						// Get lister
						lister=IPCDATA(ipc);

						// Is lister from this icon?
						if (lister->backdrop==object)
						{
							// Update lister
							PositionUpdate(lister,POSUPF_SAVE);
							break;
						}
					}
				}

				// Get position
				x=object->pos.Left;
				y=object->pos.Top;
			}

			// AppIcon?
			if (object->type==BDO_APP_ICON)
			{
				leftout_record *left;

				// Lock position list
				lock_listlock(&GUI->positions,TRUE);

				// Look for entry for icon
				for (left=(leftout_record *)&GUI->positions.list.lh_Head;
					left->node.ln_Succ;
					left=(leftout_record *)left->node.ln_Succ)
				{
					// Leftout?
					if (left->node.ln_Type==PTYPE_APPICON)
					{
						// Match this icon?
						if (strcmp(left->icon_label,object->name)==0)
							break;
					}
				}

				// Didn't find one?
				if (!(left->node.ln_Succ) && !unsnapshot)
				{
					// Create a new entry
					if ((left=AllocMemH(GUI->position_memory,sizeof(leftout_record))))
					{
						// Fill out entry
						stccpy(left->icon_label,object->name,sizeof(left->icon_label));
						left->node.ln_Name=left->name;
						left->node.ln_Type=PTYPE_APPICON;

						// Add to list
						AddTail((struct List *)&GUI->positions,(struct Node *)left);
					}
				}

				// Got one?
				if (left->node.ln_Succ)
				{
					// Unsnapshot?
					if (unsnapshot)
					{
						// Remove entry and free it
						Remove((struct Node *)left);
						FreeMemH(left);
					}

					// Update entry
					else
					{
						ULONG iflags;

						// Adjust for borders?
						if (!((iflags=GetIconFlags(object->icon))&ICONF_BORDER_OFF) &&
							(!(environment->env->desktop_flags&DESKTOPF_NO_BORDERS) || (iflags&ICONF_BORDER_ON)))
						{
							// Shift back by border size
							x-=ICON_BORDER_X;
							y-=ICON_BORDER_Y_TOP;
						}

						// Save position
						left->icon_x=x;
						left->icon_y=y;
						left->flags&=~LEFTOUTF_NO_POSITION;
					}

					// Set flag to save positions
					savepos=1;
				}

				// Can't snapshot for some reason
				else
				if (!unsnapshot) beep=1;

				// Unlock position list
				unlock_listlock(&GUI->positions);
			}

			// Left-out on desktop?
			else
			if (object->type==BDO_LEFT_OUT && !(object->flags&BDOF_DESKTOP_FOLDER) && info->flags&BDIF_MAIN_DESKTOP)
			{
				leftout_record *left;

				// Lock position list
				lock_listlock(&GUI->positions,0);

				// Look for entry for icon
				for (left=(leftout_record *)&GUI->positions.list.lh_Head;
					left->node.ln_Succ;
					left=(leftout_record *)left->node.ln_Succ)
				{
					// Leftout?
					if (left->node.ln_Type==PTYPE_LEFTOUT)
					{
						// Match this icon?
						if (object->misc_data==(ULONG)left) break;
					}
				}

				// Got one?
				if (left->node.ln_Succ)
				{
					// Save position
					left->icon_x=x;
					left->icon_y=y;
					left->flags&=~LEFTOUTF_NO_POSITION;

					// Set flag to save positions
					savepos=1;
				}

				// Must be temporary
				else beep=1;

				// Unlock position list
				unlock_listlock(&GUI->positions);
			}

#ifdef DISTINCT_OK
			// Distinct icon positions?
			else
			if (environment->env->desktop_flags&DESKTOPF_DISTINCT &&
				info->flags&BDIF_MAIN_DESKTOP)
			{
				// Snapshot icon for this environment
				desktop_snapshot_icon(object,x,y);
				save_env=1;
			}
#endif

			// Group icon?
			else
			if (info->flags&BDIF_GROUP)
			{
				// Snapshot in group
				group_snapshot_icon(info,object,x,y);
			}

			// Save to icon
			else
			{
				// Using Workbench positions?
				if (environment->env->display_options&DISPOPTF_ICON_POS)
				{
					// Set position
					object->icon->do_CurrentX=(unsnapshot)?NO_ICON_POSITION:x-WBICONMAGIC_X;
					object->icon->do_CurrentY=(unsnapshot)?NO_ICON_POSITION:y-WBICONMAGIC_Y;

					// Removing Opus positions?
					if (environment->env->display_options&DISPOPTF_REMOPUSPOS)
					{
						// Remove Opus position from icon
						SetIconFlags(object->icon,GetIconFlags(object->icon)&~ICONF_POSITION_OK);
					}
				}

				// Using Opus positions
				else
				{
					// Set "position ok" flag
					SetIconFlags(object->icon,GetIconFlags(object->icon)|ICONF_POSITION_OK);

					// Update icon position
					SetIconPosition(object->icon,x,y);
				}

				// Get icon lock
				if ((lock=backdrop_icon_lock(object)))
				{
					// Change directory
					old=CurrentDir(lock);

					// Save this object out
					if (!(WriteIcon((object->icon->do_Type==WBDISK)?"Disk":object->name,object->icon)))
						beep=1;

					// Success; is this in a lister?
					else
					if (info->lister)
					{
						char name[256];

						// Get icon name
						strcpy(name,(object->icon->do_Type==WBDISK)?"Disk":object->name);
						strcat(name,".info");

						// Reload the file
						rexx_lister_reload_file(info->lister,name);
					}

					// Restore directory
					CurrentDir(old);
					UnLock(lock);
				}
			}

			++count;
		}

		// Icon supplied?
		if (icon) break;
	}

	// Failed to do anything?
	if (!count && beep) DisplayBeep(info->window->WScreen);

	// Unlock group list
	unlock_listlock(&GUI->group_list);

	// Unlock backdrop list
	unlock_listlock(&info->objects);

	// Unlock lister list
	unlock_listlock(&GUI->lister_list);

#ifdef DISTINCT_OK
	// Save environment file?
	if (save_env && environment->env->flags&ENVF_CHANGED)
	{
		// Save environment
		if (environment_save(environment,environment->path,0,0))
			environment->env->flags&=~ENVF_CHANGED;
	}
#endif

	// Save positions?
	if (savepos)
	{
		// Lock list
		lock_listlock(&GUI->positions,0);

		// Save list
		SavePositions(&GUI->positions.list,GUI->position_name);

		// Unlock list
		unlock_listlock(&GUI->positions);
	}

	// If this is a lister, update its datestamp
	if (info->lister) update_buffer_stamp(info->lister);
}