Example #1
0
// Get icon for an object
void backdrop_get_icon(BackdropInfo *info,BackdropObject *object,short flags)
{
	short x,y,border_x=0,border_y=0;
	BOOL new_icon=1;

	// Keeping icon?
	if (flags&GETICON_KEEP) new_icon=0;

	// Not AppIcon?
	if (object->type!=BDO_APP_ICON && !(flags&GETICON_POS_ONLY))
	{
		BPTR lock=0,old=0;

		// Already got icon?
		if (object->icon && !(flags&GETICON_KEEP))
		{
			// Free icon remapping
			RemapIcon(object->icon,(info->window)?info->window->WScreen:0,1);

			// Free icon
			FreeCachedDiskObject(object->icon);
			object->icon=0;

			// We'll be getting a new one
			new_icon=1;
		}

		// Bad disk?
		if (object->type==BDO_BAD_DISK)
		{
			// Get default disk
			if (!object->icon && !(object->icon=GetCachedDefDiskObject(WBKICK)))
				object->icon=GetCachedDefDiskObject(WBDISK);
		}

		// Default directory icon?
		else
		if (flags&GETICON_DEFDIR)
		{
			// Get default drawer icon
			if (!object->icon) object->icon=GetCachedDefDiskObject(WBDRAWER);
		}

		// Get lock on directory
		else
		if (!(flags&GETICON_CD) || (lock=backdrop_icon_lock(object)))
		{
			// Go to icon directory
			if (lock) old=CurrentDir(lock);

			// Disk?
			if (object->type==BDO_DISK)
			{
				// No icon already?
				if (!object->icon)
				{
					BOOL ok=1;
					Cfg_Filetype *type=0;
					char name[256],*ptr;

					// Find a filetype-defined icon
					if (object->device_name &&
						(type=filetype_identify(object->device_name,FTTYPE_ICON,0,0)))
					{
						// Copy icon path, strip .info
						strcpy(name,type->icon_path);
						if (ptr=isicon(name)) *ptr=0;

						// Over-ride flag set in filetype?
						if (type->type.flags&FILETYPEF_OVERRIDE)
						{
							// Try for filetype icon first
							object->icon=GetCachedDiskObject(name,0);
						}
					}

					// Don't have icon yet?
					if (!object->icon)
					{
						// Is this a MSDOS disk?
						if (object->misc_data==ID_MSDOS_DISK)
						{
							// See if icon actually exists
							if (type && !(SetProtection("Disk.info",FIBF_ARCHIVE)) &&
								IoErr()==ERROR_OBJECT_NOT_FOUND)
							{
								// We'll use default icon
								ok=0;
							}
						}
						
						// Get disk icon
						if (ok)
							object->icon=GetCachedDiskObject("Disk",0);
					}

					// Got icon?
					if (object->icon)
					{
						// If it's a drawer icon, turn it into a disk
						if (object->icon->do_Type==WBDRAWER)
							object->icon->do_Type=WBDISK;

						// Check it is for a disk
						if (object->icon->do_Type!=WBDISK)
						{
							// It's not, free it and use default
							FreeCachedDiskObject(object->icon);
							object->icon=0;
						}
					}

					// Still no icon? Get default
					if (!object->icon && !(flags&GETICON_FAIL))
					{
						// Got type-defined?
						if (type)
						{
							// Try for filetype icon
							object->icon=GetCachedDiskObject(name,0);
						}

						// Still none? Get default
						if (!object->icon)
							object->icon=GetCachedDefDiskObject(WBDISK);

						// Set fake flag
						if (object->icon)
							object->flags|=BDOF_FAKE_ICON;
					}
				}
			}

			// Left out or group
			else
			if (object->type==BDO_LEFT_OUT || object->type==BDO_GROUP)
			{
				// Try for icon
				if (!object->icon)
				{
					short fake=0;

					// Want real icon?
					if (flags&GETICON_FAIL) object->icon=GetCachedDiskObject(object->name,0);

					// Get default icon if fails
					else object->icon=GetProperIcon(object->name,&fake,0);

					// Ended up fake?
					if (fake)
					{
						// Set flag
						object->flags|=BDOF_FAKE_ICON;
					}
				}

				// Got group icon?
				if (object->icon && object->type==BDO_GROUP)
				{
					// Auto-open group?
					if (FindToolType(object->icon->do_ToolTypes,"OPEN"))
						object->flags|=BDOF_AUTO_OPEN;
				}
			}

			// Had a lock?
			if (lock)
			{
				// Got icon?
				if (object->icon)
				{
					// Clear custom position flag
					object->flags&=~BDOF_CUSTOM_POS;

#ifdef DISTINCT_OK
					// Main desktop, distinct positions?
					if (info->flags&BDIF_MAIN_DESKTOP &&
						environment->env->desktop_flags&DESKTOPF_DISTINCT)
					{
						char path[256];

						// Get icon path
						if (desktop_icon_path(object,path,256,lock))
						{
							// See if position is available
							if (desktop_find_icon(path,&object->custom_pos))
							{
								// Set "custom position" flag
								object->flags|=BDOF_CUSTOM_POS;
							}
						}
					}
#endif
				}

				// Restore current dir
				CurrentDir(old);

				// Unlock object lock
				UnLock(lock);
			}
		}

		// Failed to even get a lock; get default icon if a disk
		else
		if (object->type==BDO_DISK)
		{
			// Get default icon
			if (!object->icon && (object->icon=GetCachedDefDiskObject(WBDISK)))
				object->flags|=BDOF_FAKE_ICON;
		}
	}

	// Got an icon?
	if (object->icon)
	{
		// Ended up fake?
		if (object->flags&BDOF_FAKE_ICON)
		{
			// Make sure default icon has no position
			if (object->icon)
			{
				// Clear 'position ok' flag, set invalid position
				SetIconFlags(object->icon,GetIconFlags(object->icon)&~ICONF_POSITION_OK);
				SetIconPosition(object->icon,-1,-1);
				object->icon->do_CurrentX=NO_ICON_POSITION;
				object->icon->do_CurrentY=NO_ICON_POSITION;
			}
		}

		// If this is a group, make sure icon is a drawer
		if (object->type==BDO_GROUP)
			object->icon->do_Type=WBDRAWER;

		// Is it a new icon?
		if (new_icon)
		{
			// Window open?
			if (info->window)
			{
				// Remap the icon
				RemapIcon(object->icon,info->window->WScreen,0);

				// Set flag
				object->flags|=BDOF_REMAPPED;
			}
		}

		// Transparent icon?
		if (!backdrop_icon_border(object))
		{
			border_x=0;
			border_y=0;
		}
		else
		{
			border_x=ICON_BORDER_X;
			border_y=ICON_BORDER_Y;
		}

		// No label?
		if ((GetIconFlags(object->icon)&ICONF_NO_LABEL) && !(environment->env->desktop_flags&DESKTOPF_NO_NOLABELS))
			object->flags|=BDOF_NO_LABEL;
		else
			object->flags&=~BDOF_NO_LABEL;
	}

	// No icon, or no size stuff?
	if (!object->icon || flags&GETICON_NO_POS) return;

	// Get masks
	if (!(flags&GETICON_KEEP)) backdrop_get_masks(object);

	// Get object size
	object->pos.Width=object->icon->do_Gadget.Width;
	object->pos.Height=object->icon->do_Gadget.Height;

	// (Re)position?
	if (!(flags&GETICON_SAVE_POS))
	{
		// No position initially
		object->flags|=BDOF_NO_POSITION;

		// Auto position?
		if (object->flags&BDOF_AUTO_POSITION)
		{
			return;
		}

		// Custom position?
		else
		if (object->flags&(BDOF_CUSTOM_POS|BDOF_LEFTOUT_POS))
		{
			// Get custom position
			x=(object->custom_pos>>16)&0xffff;
			y=object->custom_pos&0xffff;
		}
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);
}
Example #3
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;
}