Esempio n. 1
0
int main(int argc,char **argv)
{
	font_data *data;

	// Need dopus library
	if (!(DOpusBase=OpenLibrary("dopus5.library",LIB_VERSION)))
		if (!(DOpusBase=OpenLibrary("dopus5:libs/dopus5.library",55)))
			return(10);
#ifdef __amigaos4__
	if (!(IDOpus = (struct DOpusIFace *)GetInterface(DOpusBase, "main", 1, NULL)))
	{
		CloseLibrary(DOpusBase);
		return(10);
	}
#endif

	// Allocate data
	if (!(data=AllocVec(sizeof(font_data),MEMF_CLEAR)))
	{
		font_free(0);
		return(5);
	}

	// Parse arguments
	data->args=
		ReadArgs(
			"FONT,SIZE/N,B=BOLD/S,I=ITALIC/S,U=ULINE/S,PUBSCREEN/K",
			(APTR)data->arg_array,
			NULL);

	// Default to topaz 8
#ifdef __AROS__
	strcpy(data->font_name,"ttcourier.font");
#else
	strcpy(data->font_name,"topaz.font");
#endif
	data->font_size=8;

	// Got font name?
	if (data->arg_array[ARG_FONT])
		font_get_name(data,(char *)data->arg_array[ARG_FONT]);

	// Got a font size?
	if (data->arg_array[ARG_SIZE] && *((long *)data->arg_array[ARG_SIZE]))
	{
		data->font_size=*((long *)data->arg_array[ARG_SIZE]);
		data->first=TRUE;
	}

	// Initialise locale
	init_locale_data(&data->locale);

	// Got locale library?
	if (LocaleBase)
	{
		BPTR lock;

		// Change PROGDIR: to dopus5:
		if ((lock=Lock("dopus5:",ACCESS_READ)))
#ifdef __AROS__
			// the lock returned here is the initial PROGDIR: which belongs to the system,
			// so it's not a very good idea to just UnLock it
			SetProgramDir(lock);
#else
			UnLock(SetProgramDir(lock));
#endif

		// Initialise
		data->locale.li_LocaleBase=LocaleBase;
		data->locale.li_Catalog=OpenCatalogA(0,"viewfont.catalog",0);
		data->locale.li_Locale=OpenLocale(0);
	}

	// Create message port
	data->appport=CreateMsgPort();

	// Open window
	if (!(font_open(data)))
	{
		font_free(data);
		return(5);
	}

	// Initial gadget settings
	if (data->arg_array[ARG_BOLD]) SetGadgetValue(data->list,GAD_FONT_BOLD,1);
	if (data->arg_array[ARG_ITALIC]) SetGadgetValue(data->list,GAD_FONT_ITALIC,1);
	if (data->arg_array[ARG_ULINE]) SetGadgetValue(data->list,GAD_FONT_ULINE,1);

	// Show font
	font_show_font(data,FALSE);

	// Initialise refresh hook
	data->refresh_hook.h_Entry=(ULONG (*)())font_refresh;
	data->refresh_hook.h_Data=data;

	// Event loop
	FOREVER
	{
		struct IntuiMessage *msg;
		BOOL quit_flag=FALSE;

		// AppWindow?
		if (data->appwindow)
		{
			struct AppMessage *amsg;

			// Get messages
			while ((amsg=(struct AppMessage *)GetMsg(data->appport)))
			{
				// Got file?
				if (amsg->am_NumArgs>0)
				{
					char buf[256];

					// Get name
					DevNameFromLockDopus(amsg->am_ArgList[0].wa_Lock,buf,256);
					if (amsg->am_ArgList[0].wa_Name && *amsg->am_ArgList[0].wa_Name)
						AddPart(buf,amsg->am_ArgList[0].wa_Name,256);

					// Get font name
					font_get_name(data,buf);

					// Get new font
					font_get_font(data);
					font_show_font(data,FALSE);
				}

				// Reply to message
				ReplyMsg((struct Message *)amsg);
			}
		}

		// Requester?
		if (data->about)
		{
			// Handle requester
			if (SysReqHandler(data->about,0,0)>=0)
			{
				// Close requester
				FreeSysRequest(data->about);
				data->about=NULL;
			}
		}

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

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

				// Get gadget ID
				if (msg_copy.Class==IDCMP_GADGETUP)
					id=((struct Gadget *)msg_copy.IAddress)->GadgetID;

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


					// New size
					case IDCMP_NEWSIZE:

						// Redraw font
						font_show_font(data,FALSE);

						// Set flag to say we resized
						data->resized=TRUE;
						break;


					// Menu
					case IDCMP_MENUPICK:
						{
							struct MenuItem *item;

							// Get item
							if (!(item=ItemAddress(data->window->MenuStrip,msg_copy.Code)))
								break;

							// Get ID
							id=GTMENUITEM_USERDATA(item);

							// Fall through
						}

					// Gadget
					case IDCMP_GADGETUP:
						switch (id)
						{
							// Show requester
							case GAD_FONT_FONT_POPUP:
							case MENU_OPEN_FONT:

								// Ask for name
								font_ask_name(data);
								break;


							// Font name typed
							case GAD_FONT_FONT:

								// Get name
								font_get_name(data,(char *)GetGadgetValue(data->list,GAD_FONT_FONT));

								// Get new font
								font_get_font(data);
								font_show_font(data,FALSE);
								break;


							// Font size up/down
							case GAD_FONT_UP:
							case GAD_FONT_DOWN:
								{
									short size;

									// Get next size
									size=font_get_size(data,(id==GAD_FONT_UP)?1:-1);

									// No change?
									if (size==data->font_size) break;

									// Use this size
									data->font_size=size;
									SetGadgetValue(data->list,GAD_FONT_SIZE,size);
								}

							// Font size given
							case GAD_FONT_CYCLE:

								// Check id
								if (id==GAD_FONT_CYCLE)
								{
									short size;

									// Get size
									if (!(size=atoi(data->size_labels[msg_copy.Code])))
										break;

									// Refresh gadget
									data->font_size=size;
									SetGadgetValue(data->list,GAD_FONT_SIZE,data->font_size);
								}

							// Font size
							case GAD_FONT_SIZE:

								// Entered size
								if (id==GAD_FONT_SIZE)
								{
									// Bounds check gadget
									data->font_size=
										BoundsCheckGadget(
											data->list,
											GAD_FONT_SIZE,
											4,
											255);
								}

								// Get new font
								font_get_font(data);
								font_show_font(data,FALSE);
								break;

							// Styles changed
							case GAD_FONT_BOLD:
							case GAD_FONT_ITALIC:
							case GAD_FONT_ULINE:

								// Redraw font
								font_show_font(data,FALSE);
								break;


							// Save settings
							case MENU_SAVE_SETTINGS:
								font_save_settings(data);
								break;


							// Quit
							case MENU_QUIT:
								quit_flag=TRUE;
								break;


							// About
							case MENU_ABOUT:
								font_show_about(data);
								break;
						}
						break;


					// Rawkey
					case IDCMP_RAWKEY:

						// Help?
						if (msg_copy.Code==0x5f)
							font_show_about(data);

					// Key
					case IDCMP_VANILLAKEY:

						// Escape does quit
						if (msg_copy.Code==0x1b) quit_flag=TRUE;
						break;


					// Refresh
					case IDCMP_REFRESHWINDOW:

						// Have we just resized?
						if (data->resized)
						{
							// Don't need to refresh
							BeginRefresh(data->window);
							EndRefresh(data->window,TRUE);
							data->resized=FALSE;
							break;
						}

						// Refresh font display
						font_show_font(data,TRUE);
						break;
				}

				// Check window is still valid
				if (!data->window) break;
			}
		}

		if (quit_flag) break;

		// Wait for signal (ctrl-c breaks)
		if ((Wait(SIGBREAKF_CTRL_C|
					((data->window)?(1<<data->window->UserPort->mp_SigBit):0)|
					((data->about)?(1<<data->about->UserPort->mp_SigBit):0)|
					((data->appwindow)?(1<<data->appport->mp_SigBit):0)))&SIGBREAKF_CTRL_C) break;
	}

	// Free stuff
	font_free(data);
	return(0);
}
Esempio n. 2
0
int LIBFUNC L_Module_Entry(
	REG(a0, struct List *files),
	REG(a1, struct Screen *screen),
	REG(a2, IPCData *ipc),
	REG(a3, IPCData *main_ipc),
	REG(d0, ULONG mod_id),
	REG(d1, ULONG mod_data))
{
	config_path_data *data;
	short success=1;

	// Allocate data
	if (!(data=AllocVec(sizeof(config_path_data),MEMF_CLEAR)) ||
		!(data->path_list=Att_NewList(0)))
	{
		FreeVec(data);
		return 0;
	}

	// Store data pointers
	data->paths=files;
	data->ipc=ipc;
	data->main_ipc=main_ipc;
	data->memory=(APTR)mod_id;
	data->def_format=(ListFormat *)mod_data;

	// AppPort
	data->appport=CreateMsgPort();

	// Open commodities library
	/*data->cxbase=OpenLibrary("commodities.library",0);
	#ifdef __amigaos4__
	ICommodities=(struct CommoditiesIFace *)GetInterface(data->cxbase,"main",1,NULL); 
	#endif	*/
	
	// Build path list
	config_paths_build_list(data);

	// Open window
	if (!(config_paths_open(data,screen)))
		return 0;

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

		// IPC messages?
		while ((imsg=(IPCMessage *)GetMsg(ipc->command_port)))
		{
			// Quit?
			if (imsg->command==IPC_QUIT)
			{
				quit_flag=1;
				success=0;
			}

			// Hide?
			else if (imsg->command==IPC_HIDE)
			{
				RemoveAppWindow(data->appwindow);
				data->appwindow=0;
				CloseConfigWindow(data->window);	
				data->window=0;
			}

			// Show?
			else if (imsg->command==IPC_SHOW)
			{
				if (!(config_paths_open(data,imsg->data)))
				{
					quit_flag=1;
					success=0;
				}
			}

			// Activate
			else if (imsg->command==IPC_ACTIVATE)
			{
				if (data->window)
				{
					WindowToFront(data->window);
					ActivateWindow(data->window);
				}
			}

			// Reply
			IPC_Reply(imsg);
		}

		// Any messages to the window?
		if (data->window)
		{
			while ((msg=GetWindowMsg(data->window->UserPort)))
			{
				struct IntuiMessage msg_copy;
				UWORD gadgetid;

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

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


					// Gadget
					case IDCMP_GADGETUP:
					case IDCMP_GADGETDOWN:

						// Get GadgetID
						gadgetid=((struct Gadget *)msg_copy.IAddress)->GadgetID;

						// Look at gadget
						switch (gadgetid)
						{
							// Cancel
							case GAD_PATHFORMAT_CANCEL:
								success=0;

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


							// Add an entry
							case GAD_PATHFORMAT_ADD:
								config_paths_add(data,TRUE);
								break;


							// Change path name
							case GAD_PATHFORMAT_PATH:
								config_paths_change(data);
								break;


							// Select an entry
							case GAD_PATHFORMAT_PATHS:
								{
									Att_Node *node;

									// Find selected entry
									node=Att_FindNode(data->path_list,msg_copy.Code);

									// Double-click?
									if (DoubleClick(data->seconds,data->micros,msg_copy.Seconds,msg_copy.Micros) &&
										node==data->path_sel)
									{
										// Edit it	
										config_paths_edit(data);
										break;
									}

									// Store double-click time
									data->seconds=msg_copy.Seconds;
									data->micros=msg_copy.Micros;

									// Not already selected?
									if (node!=data->path_sel)
									{
										// Select it
										config_paths_select(data,node,FALSE);
									}
								}
								break;


							// Key
							case GAD_PATHFORMAT_KEY:
								config_paths_get_key(data);
								break;


							// Open new lister
							case GAD_PATHFORMAT_NEW_LISTER:

								// Valid selection?
								if (data->path_sel)
								{
									position_rec *pos=(position_rec *)data->path_sel->data;

									// Open new lister?
									if (msg_copy.Code)
									{
										// Set flag
										pos->flags|=POSITIONF_OPEN_NEW;
	
										// Clear type flags
										pos->flags&=~(POSITIONF_ICON|POSITIONF_ICON_ACTION);

										// Icon action?
										if (msg_copy.Code==MODE_ACTION)
											pos->flags|=POSITIONF_ICON|POSITIONF_ICON_ACTION;

										// Icon?
										else
										if (msg_copy.Code==MODE_ICON)
											pos->flags|=POSITIONF_ICON;
									}

									// No lister
									else pos->flags&=~POSITIONF_OPEN_NEW;
								}
								break;


							// Remove
							case GAD_PATHFORMAT_REMOVE:
								config_paths_remove(data,TRUE);
								break;


							// Edit
							case GAD_PATHFORMAT_EDIT:
								config_paths_edit(data);
								break;
						}
						break;


					// Key press
					case IDCMP_RAWKEY:

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

								// Send help request
								IPC_Command(main_ipc,IPC_HELP,(1<<31),"Paths",0,(struct MsgPort *)-1);

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

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

		// Check quit flag
		if (quit_flag) break;

		// App messages?
		if (data->appport)
		{
			struct AppMessage *msg;

			// Get messages
			while ((msg=(struct AppMessage *)GetMsg(data->appport)))
			{
				// Get first argument
				if (msg->am_NumArgs>0)
				{
					// Is it a directory?
					if (!msg->am_ArgList[0].wa_Name || !*msg->am_ArgList[0].wa_Name)
					{
						char buf[256];

						// Expand path name	
						if (NameFromLock(msg->am_ArgList[0].wa_Lock,buf,256))
						{
							Att_Node *node;

							// Fix trailing /
							AddPart(buf,"",256);

							// Check it's not already in the list
							if (!(node=(Att_Node *)FindNameI((struct List *)data->path_list,buf)))
							{
								// Add a new entry
								config_paths_add(data,FALSE);

								// Copy path to path field
								SetGadgetValue(data->objlist,GAD_PATHFORMAT_PATH,(ULONG)buf);

								// Accept the new path
								config_paths_change(data);
							}

							// It is, select this entry
							else config_paths_select(data,node,FALSE);
						}
					}
				}

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

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

	// Free stuff
	config_paths_cleanup(data);
	return success;
}
Esempio n. 3
0
int __asm __saveds L_Module_Entry(
	register __a0 struct List *files,
	register __a1 struct Screen *callback1,
	register __a2 IPCData *callback2,
	register __a3 IPCData *main_ipc,
	register __d0 ULONG mod_id,
	register __d1 ULONG mod_data)
{
	NewConfigWindow newwin;
	struct Window *window;
	ObjectList *objlist;
	Att_List *list;
	TimerHandle *timer;
	short count=0;
	struct Task *task;
	rego_data test={0};

	// Call back to main program
	((void __asm (*)
		(register __a0 struct List *,
		register __a1 rego_data *,
		register __a2 rego_data *,
		register __a3 void **,
		register __d0 ULONG))callback2)(files,&test,&rego,&newwin.parent,global_checksum);

	// Won't work with DOpus library > 55
	if (DOpusBase->lib_Version>55)
		return 0;

	// Fix IPC
	main_ipc->proc=(struct Process *)FindTask(0);
	main_ipc->proc->pr_Task.tc_UserData=main_ipc;
	main_ipc->list=0;
	if (!main_ipc->command_port)
		main_ipc->command_port=CreateMsgPort();

	// Fill out new window
	newwin.parent=0;
	newwin.dims=&serial_window;
	newwin.title=GetString(locale,MSG_TITLE);
	newwin.locale=locale;
	newwin.port=0;
	newwin.flags=WINDOW_VISITOR|WINDOW_NO_CLOSE|WINDOW_REQ_FILL|WINDOW_AUTO_KEYS;
	newwin.font=0;

	// Initialise timer
	if (!(timer=AllocTimer(UNIT_VBLANK,0)))
		return 0;

	// Open window
	if (!(window=OpenConfigWindow(&newwin)) ||
		!(objlist=AddObjectList(window,serial_objects)))
	{
		CloseConfigWindow(window);
		FreeTimer(timer);
		return 0;
	}

	// Set ok flag
	*((ULONG *)mod_data)|=(1<<28);

	// Display text
	list=build_text_display(window,objlist,message0);

	// Start timer
	StartTimer(timer,DELAY,0);

	// Event loop
	FOREVER
	{
		struct IntuiMessage *msg;
		BOOL break_flag=0;

		// Timer returned?
		if (CheckTimer(timer))
		{
			// Exit
			break_flag=1;
		}

		// Any Intuition messages?
		while (msg=GetWindowMsg(window->UserPort))
		{
			struct IntuiMessage copy_msg;

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

			// Gadget?
			if (copy_msg.Class==IDCMP_GADGETUP)
			{
				struct Gadget *gadget;

				// Get gadget
				gadget=(struct Gadget *)copy_msg.IAddress;

				// Look at gadget ID
				switch (gadget->GadgetID)
				{
					// Ok
					case GAD_SERIAL_OKAY:

						break_flag=1;
						break;
				}
			}
		}

		if (break_flag) break;

		Wait(1<<window->UserPort->mp_SigBit|1<<timer->port->mp_SigBit);
	}

	// Close window
	CloseConfigWindow(window);

	// Free list and timer
	Att_RemList(list,0);
	FreeTimer(timer);

	// Success
	return 1;
}
void FunctionEditor(void)
{
	struct IntuiMessage *gmsg,msg;
	int break_flag=0;
	UWORD gadgetid=0;
	ULONG waitbits;
	FuncEdData *data;
	IPCData *ipc;
	NewConfigWindow newwin;
	FunctionStartup *startup=0;
	IPCMessage *submsg;
	int success=0;
	BOOL open_window=1;
	BPTR lock;
	ConfigWindow windims;

	// Do startup
	if (!(ipc=Local_IPC_ProcStartup((ULONG *)&startup, (APTR)&funced_init)))
	{
		funced_cleanup(startup->data);
		return;
	}

	// Get data pointer
	data=startup->data;

	// Lock RAM: and CD to it
	if ((lock=Lock("ram:",ACCESS_READ)))
		lock=CurrentDir(lock);

	// Copy dimensions
	if (startup->flags&FUNCEDF_CENTER)
		windims=_function_editor_window_center;
	else
	if (startup->flags&FUNCEDF_LABEL)
		windims=_function_editor_label_window;
	else
		windims=_function_editor_window;

	// Fill in new window
	newwin.parent=startup->window;
	newwin.dims=&windims;
	newwin.title=(startup->title[0])?startup->title:(char *)GetString(startup->locale,MSG_FUNCED_TITLE);
	newwin.locale=startup->locale;
	newwin.port=0;
	newwin.flags=WINDOW_VISITOR|WINDOW_AUTO_KEYS|WINDOW_REQ_FILL;//|WINDOW_SIZE_BOTTOM;
	newwin.font=0;

	// Build flag list
	funced_build_flaglist(data);
	waitbits=1<<ipc->command_port->mp_SigBit|1<<data->drag.timer->port->mp_SigBit;

	// Event loop
	FOREVER
	{
		// Check drag
		if (config_drag_check(&data->drag))
		{
			// End drag
			functioned_end_drag(data,0);
		}

		// Task message?
		while ((submsg=(IPCMessage *)GetMsg(ipc->command_port)))
		{
			// Close message?
			if (submsg->command==IPC_QUIT)
			{
				// Keep changes?
				success=submsg->flags;

				// Set break flag
				break_flag=1;
			}

			// Activate
			else
			if (submsg->command==IPC_ACTIVATE && data->window)
			{
				WindowToFront(data->window);
				ActivateWindow(data->window);
			}

			// Hide
			else
			if (submsg->command==IPC_HIDE && data->window)
			{
				// Store changes in function
				funced_store_edits(data);

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

				// Remove AppWindow
				RemoveAppWindow(data->appwindow);
				data->appwindow=0;

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

				// Zero stuff
				data->window=0;
				data->objlist=0;
				waitbits=1<<ipc->command_port->mp_SigBit;
			}

			// Show
			else
			if (submsg->command==IPC_SHOW && !data->window)
			{
				// Set flag to open window
				open_window=1;
				newwin.parent=(struct Window *)submsg->data;
			}

			// Passed-along app message
			else
			if (submsg->command==CFG_APPMESSAGE_PASS)
			{
				funced_appmsg(data,submsg->data);
				ReplyMsg((struct Message *)submsg->data);
			}

			// Update our identity
			else
			if (submsg->command==CFG_NEW_ID)
			{
				data->function->function.func_type=submsg->flags;
				startup->object_flags=(ULONG)submsg->data;
			}

			// Copy a function
			else
			if (submsg->command==FUNCTIONEDIT_COPY_LINE)
			{
				FunctionEntry *entry,*next;

				// Copy function
				functioned_copy_line(
					data,
					(FunctionEntry *)submsg->data,
					0,
					(Point *)submsg->data_free);

				// Free function
				entry=(FunctionEntry *)submsg->data;
				while (entry)
				{
					// Get next
					next=(FunctionEntry *)entry->node;

					// Free entry
					FreeVec(entry);
					entry=next;
				}
			}

			// Clip button
			else
			if (submsg->command==BUTTONEDIT_CLIP_BUTTON)
			{
				Cfg_ButtonFunction *func;

				// Show busy pointer
				SetWindowBusy(data->window);

				// Stop editing
				funced_end_edit(data,data->edit_node,0,0);
				data->edit_node=0;

				// Get first function
				if ((func=(Cfg_ButtonFunction *)
					FindFunctionType(
						(struct List *)&((Cfg_Button *)submsg->data)->function_list,
						FTYPE_LEFT_BUTTON)))
				{
					FunctionEntry dummy;
					Cfg_Instruction *ins;

					// Go through instructions
					for (ins=(Cfg_Instruction *)func->instructions.mlh_Head;
						ins->node.mln_Succ;
						ins=(Cfg_Instruction *)ins->node.mln_Succ)
					{
						// Fill out dummy entry
						dummy.type=ins->type;
						if (ins->string) strcpy(dummy.buffer,ins->string);
						else dummy.buffer[0]=0;

						// Copy function line
						data->edit_node=funced_new_entry(data,0,&dummy);
					}

					// Start editing last line
					funced_start_edit(data);

					// Get flags
					data->function->function.flags=func->function.flags;
					data->function->function.code=func->function.code;
					data->function->function.qual=func->function.qual;
					data->function->function.qual_mask=func->function.qual_mask;
					data->function->function.qual_same=func->function.qual_same;

					// Update flag list
					funced_update_flaglist(data);

					// Update key
					funced_show_key(data);
				}

				// Free button
				FreeButton((Cfg_Button *)submsg->data);

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

			// Reply the message
			IPC_Reply(submsg);
		}

		// Open window?
		if (open_window)
		{
			// Open window
			if (!(data->window=OpenConfigWindow(&newwin)) ||
				!(data->p_objlist=AddObjectList(
					data->window,
					(startup->flags&FUNCEDF_IMAGE)?_function_editor_image_objects:
						((startup->flags&FUNCEDF_LABEL)?_function_editor_label_objects:
														_function_editor_normal_objects))) ||
				!(data->objlist=AddObjectList(data->window,_function_editor_objects)))
				break;

			// Add use or save button
			AddObjectList(data->window,(startup->flags&FUNCEDF_SAVE)?_function_editor_objects_save:_function_editor_objects_use);

			// Store window for drag
			data->drag.window=data->window;

			// Set window ID
			SetWindowID(data->window,0,WINDOW_FUNCTION_EDITOR,(struct MsgPort *)ipc);

			// Add menus
			AddWindowMenus(data->window,_funced_menus);

			// Make this an AppWindow
			data->appwindow=AddAppWindowA(0,0,data->window,data->appport,0);

			// Get waitbits
			waitbits|=1<<data->window->UserPort->mp_SigBit;
			if (data->appwindow) waitbits|=1<<data->appport->mp_SigBit;

			// Disable key?
			if (startup->flags&FUNCEDF_NO_KEY)
			{
				DisableObject(data->objlist,GAD_FUNCED_KEY,TRUE);
			}

			// Initialise gadgets with function data.
			funced_init_gads(data);
			open_window=0;
		}

		// Intuimessage
		if (data->window)
		{
			while ((gmsg=GetWindowMsg(data->window->UserPort)))
			{
				Att_Node *node;

				// Copy message and reply (unless IDCMPUPDATE)
				msg=*gmsg;
				if (gmsg->Class!=IDCMP_IDCMPUPDATE)
				{
					ReplyWindowMsg(gmsg);
					gmsg=0;
				}

				// Get GadgetID
				if (msg.Class==IDCMP_GADGETDOWN ||
					msg.Class==IDCMP_GADGETUP)
					gadgetid=((struct Gadget *)msg.IAddress)->GadgetID;

				// Look at message
				switch (msg.Class)
				{
					// Key press
					case IDCMP_VANILLAKEY:

						// If editing something, activate string gadget
						if (data->edit_node)
							ActivateStrGad(GADGET(GetObject(data->objlist,GAD_FUNCED_EDIT)),data->window);
						break;


					// Close window
					case IDCMP_CLOSEWINDOW:

						// Set break flag
						break_flag=1;
						break;


					// Mouse move
					case IDCMP_MOUSEMOVE:

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


					// Inactive window does menu down
					case IDCMP_INACTIVEWINDOW:
						msg.Code=MENUDOWN;

					// Mouse buttons
					case IDCMP_MOUSEBUTTONS:

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

							// Dropped ok?
							if (msg.Code==SELECTUP)
							{
								// Is shift down?
								if (msg.Qualifier&(IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
									data->drag_shift=1;
								else data->drag_shift=0;

								// 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.Code==MENUDOWN)
							{
								// Set abort
								ok=0;
							}

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


					// Menu
					case IDCMP_MENUPICK:

						{
							struct MenuItem *item;

							// Get item
							if (!(item=ItemAddress(data->window->MenuStrip,msg.Code)))
								break;

							// Treat as gadget
							gadgetid=MENUID(item);
						}

					// Gadget
					case IDCMP_GADGETUP:
					case IDCMP_GADGETDOWN:

						// Look at gadget ID
						switch (gadgetid)
						{
							// Hotkey
							case GAD_FUNCED_KEY:
								{
									IX ix;
									char *ptr;

									// Get key, see if it's invalid
									if ((ptr=(char *)GetGadgetValue(data->objlist,GAD_FUNCED_KEY)) && *ptr)
									{
										// Try to parse
										if (ParseIX(ptr,&ix))
										{
											// Flash screen
											DisplayBeep(data->window->WScreen);

											// Activate key field again
											ActivateStrGad(GADGET(GetObject(data->objlist,GAD_FUNCED_KEY)),data->window);
										}
										else
										{
											data->function->function.code=ix.ix_Code;
											data->function->function.qual=QualValid(ix.ix_Qualifier);
											data->function->function.qual_mask=ix.ix_QualMask;
											data->function->function.qual_same=ix.ix_QualSame;
										}
									}
								}
								break;


							// Flag selected
							case GAD_FUNCED_FLAGS:

								// Get selected node
								node=Att_FindNode(data->flag_list,msg.Code);

								// Set flag
								data->function->function.flags^=node->data;

								// Check change
								funced_check_flag(&data->function->function.flags,node->data);

								// Update flag list
								funced_update_flaglist(data);
								break;


							// Edit a line
							case GAD_FUNCED_LISTER:

								// Get selected node
								node=Att_FindNode(data->func_display_list,msg.Code);

								// Is this the node we're already editing?
								if (node==data->edit_node) break;

								// If we're editing another one, store its contents
								if (data->edit_node)
									funced_end_edit(data,data->edit_node,0,0);

								// Start editing this entry
								data->edit_node=node;
								funced_start_edit(data);
								break;


							// Return pressed in edit line
							case GAD_FUNCED_EDIT:

								// See if we were editing something
								if (data->edit_node)
								{
									// Stop editing
									funced_end_edit(data,data->edit_node,END_DISABLE,msg.Qualifier);
									data->edit_node=0;
								}
								break;


							// New entry
							case GAD_FUNCED_NEW_ENTRY:
							case GAD_FUNCED_INSERT_ENTRY:

								// Create new entry
								functioned_copy_line(data,0,gadgetid,0);
								break;


							// Delete entry
							case GAD_FUNCED_DELETE_ENTRY:
								// Check we were editing something
								if (!data->edit_node) break;

								// Stop editing (signal delete)
								funced_end_edit(data,data->edit_node,END_DISABLE|END_DELETE,0);
								data->edit_node=0;
								break;


							// Function type
							case GAD_FUNCED_FUNCTION_TYPE:
								// Check we were editing something
								if (!data->edit_node) break;

								// Store type
								((FunctionEntry *)data->edit_node->data)->type=msg.Code;

								// Disable popup button if no functions
								DisableObject(
									data->objlist,
									GAD_FUNCED_EDIT_GLASS,
									(msg.Code==INST_COMMAND && !data->startup->func_list));
								break;


							// Glass gadget
							case GAD_FUNCED_EDIT_GLASS:

								// Check we were editing something
								if (data->edit_node)
								{
									char buffer[256];

									// Put up requester
									if (!(funced_command_req(
										data,
										buffer,
										((FunctionEntry *)data->edit_node->data)->type)))
										break;

									// Insert string in edit line
									funced_edit_insertstring(
										data->objlist,
										GAD_FUNCED_EDIT,
										buffer,
										DOpusBase,(struct Library *)IntuitionBase);
								}
								break;


							// Argument list
							case GAD_FUNCED_EDIT_ARGUMENT:

								// Check we were editing something
								if (data->edit_node)
								{
									char buffer[80];

									// Put up requester
									if (!(funced_command_req(
										data,
										buffer,
										-1))) break;

									// Insert string in edit line
									funced_edit_insertstring(
										data->objlist,
										GAD_FUNCED_EDIT,
										buffer,
										DOpusBase,(struct Library *)IntuitionBase);
								}
								break;


							// Export
							case MENU_FUNCED_EXPORT_ASCII:
							case MENU_FUNCED_EXPORT_CMD:

								// Got file requester?
								if (WINREQUESTER(data->window))
								{
									struct TagItem tags[6];
									struct FileRequester *req=WINREQUESTER(data->window);

									// Show busy pointer
									SetWindowBusy(data->window);

									// File requester tags
									tags[0].ti_Tag=ASLFR_Window;
									tags[0].ti_Data=(ULONG)data->window;
									tags[1].ti_Tag=ASLFR_TitleText;
									tags[1].ti_Data=(ULONG)GetString(startup->locale,MSG_FUNCED_SELECT_FILE);
									tags[2].ti_Tag=ASLFR_Flags1;
									tags[2].ti_Data=FRF_DOSAVEMODE|FRF_PRIVATEIDCMP;
									tags[3].ti_Tag=ASLFR_Flags2;
									tags[3].ti_Data=FRF_REJECTICONS;
									tags[4].ti_Tag=(gadgetid==MENU_FUNCED_EXPORT_CMD)?ASLFR_InitialDrawer:TAG_DONE;
									tags[4].ti_Data=(ULONG)"DOpus5:Commands";
									tags[5].ti_Tag=TAG_DONE;

									// Show filerequester
									if (AslRequest(req,tags))
									{
										// Build filename
										strcpy(data->buffer,req->fr_Drawer);
										AddPart(data->buffer,req->fr_File,256);

										// Store changes in function
										funced_store_edits(data);

										// Do export
										if (gadgetid==MENU_FUNCED_EXPORT_CMD)
											function_export_cmd(data->buffer,0,data->function);
										else
											L_FunctionExportASCII(data->buffer,0,data->function,startup->a4);
									}

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


							// Cut/Copy
							case MENU_FUNCED_CUT:
							case MENU_FUNCED_COPY:
								{
									APTR iff;

									// Set busy pointer
									SetWindowBusy(data->window);

									// Open clipboard
									if ((iff=IFFOpen((char *)0,IFF_CLIP_WRITE,ID_OPUS)))
									{
										// Stop editing
										funced_end_edit(data,data->edit_node,END_DISABLE,0);
										data->edit_node=0;

										// Store changes in function
										funced_store_edits(data);

										// Save function
										SaveFunction(iff,data->function);

										// Close clipboard
										IFFClose(iff);
									}

									// Just copy, not cut?
									if (gadgetid==MENU_FUNCED_COPY)
									{
										// Clear busy pointer
										ClearWindowBusy(data->window);
										break;
									}

									// Fall through, paste null function
								}

							// Paste
							case MENU_FUNCED_PASTE:
								{
									Cfg_Function *func=0;

									// Set busy pointer
									SetWindowBusy(data->window);

									// End any edit
									funced_end_edit(data,data->edit_node,END_DISABLE,0);
									data->edit_node=0;

									// Paste?
									if (gadgetid==MENU_FUNCED_PASTE)
									{
										APTR iff;

										// Open clipboard
										if ((iff=IFFOpen((char *)0,IFF_CLIP_READ,ID_OPUS)))
										{
											// Find function
											if (IFFNextChunk(iff,ID_FUNC))
											{
												// Read function
												func=ReadFunction(iff,0,0,0);
											}

											// Close clipboard
											IFFClose(iff);
										}

										// No valid function?
										if (!func)
										{
											// Flash error
											DisplayBeep(data->window->WScreen);
											ClearWindowBusy(data->window);
											break;
										}
									}

									// Detach existing list
									SetGadgetChoices(data->objlist,GAD_FUNCED_FLAGS,(APTR)~0);

									// Clear function list
									Att_RemList(data->function_list,REMLIST_SAVELIST|REMLIST_FREEDATA);

									// Free existing instructions
									FreeInstructionList(data->function);

									// Rebuild display list
									funced_build_display(data);

									// Clear flags
									data->function->function.flags=0;
									funced_update_flaglist(data);

									// Clear key
									data->function->function.code=0xffff;
									SetGadgetValue(data->objlist,GAD_FUNCED_KEY,0);

									// Clear label
									if (startup->flags&FUNCEDF_LABEL)
									{
										data->label[0]=0;
										SetGadgetValue(data->p_objlist,GAD_FUNCED_LABEL,0);
									}

									// Paste function in?
									if (func)
									{
										short type;

										// Save type
										type=data->function->function.func_type;

										// Copy function in
										CopyFunction(func,0,data->function);
										data->function->function.func_type=type;

										// Free copied function
										FreeFunction(func);

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


							// Use
							case GAD_FUNCED_USE:
								success=1;

							// Cancel
							case GAD_FUNCED_CANCEL:
								break_flag=1;
								break;
						}
						break;


					// Key press
					case IDCMP_RAWKEY:

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

							// Send help command
							IPC_Command(startup->main_owner,IPC_HELP,(1<<31),"Function Editor",0,REPLY_NO_PORT);

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


					// BOOPSI message
					case IDCMP_IDCMPUPDATE:
						{
							struct TagItem *tags=(struct TagItem *)msg.IAddress;
							short item;

							// Check ID
							if (GetTagData(GA_ID,0,tags)!=GAD_FUNCED_LISTER)
								break;

							// Get item
							if ((item=GetTagData(DLV_DragNotify,-1,tags))!=-1)
							{
								// Start the drag
								config_drag_start(&data->drag,data->func_display_list,item,tags,TRUE);
							}
						}
						break;


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

				// Reply to any outstanding message
				if (gmsg) ReplyWindowMsg(gmsg);
			}
		}

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

			while ((msg=(struct AppMessage *)GetMsg(data->appport)))
			{
				// Make sure window is active
				ActivateWindow(data->window);

				// Handle message
				funced_appmsg(data,msg);
				ReplyMsg((struct Message *)msg);
			}
		}

		// Check break flag
		if (break_flag) break;

		// Wait for message
		Wait(waitbits);
	}

	// Restore CD
	if (lock) UnLock(CurrentDir(lock));

	// Edit successful?
	if (success)
	{
		FunctionReturn ret;

		// Store changes in function
		funced_store_edits(data);

		// Fill out return data
		ret.object=startup->object;
		ret.object_flags=startup->object_flags;
		ret.function=data->function;

		// Send new function back
		IPC_Command(startup->owner_ipc,FUNCTIONEDIT_RETURN,0,&ret,0,REPLY_NO_PORT);
	}

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

	// Free edit function
	FreeFunction(data->function);

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

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

	// Say goodbye
	IPC_Goodbye(ipc,startup->owner_ipc,startup->object_flags);

	// Delete IPC data
	Forbid();
	IPC_Free(ipc);

	// Free data
	funced_cleanup(data);
	FreeVec(startup);
}
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);
}
// Get search data
static int search_get_data(
	FunctionHandle *handle,
	SearchData *data)
{
	NewConfigWindow new_win;
	struct Window *window;
	ObjectList *objlist;
	Lister *lister;
	short cancel=1;

	// Fill out new window
	if ((lister=function_lister_current(&handle->source_paths)))
	{
		new_win.parent=lister->window;
		new_win.flags=0;
	}
	else
	{
		new_win.parent=GUI->screen_pointer;
		new_win.flags=WINDOW_SCREEN_PARENT;
	}
	new_win.dims=&search_window;
	new_win.title=GetString(&locale,MSG_ENTER_SEARCH_STRING);
	new_win.locale=&locale;
	new_win.port=0;
	new_win.flags|=WINDOW_NO_CLOSE|WINDOW_VISITOR|WINDOW_AUTO_KEYS|WINDOW_REQ_FILL;
	new_win.font=0;

	// Open window
	if (!(window=OpenConfigWindow(&new_win)) ||
		!(objlist=AddObjectList(window,search_objects)))
	{
		CloseConfigWindow(window);
		return 0;
	}

	// Initial settings
	SetGadgetValue(objlist,GAD_SEARCH_TEXT,(ULONG)data->search_text);
	SetGadgetValue(objlist,GAD_SEARCH_CASE,data->search_flags&SEARCH_NOCASE);
	SetGadgetValue(objlist,GAD_SEARCH_WILD,data->search_flags&SEARCH_WILDCARD);
	SetGadgetValue(objlist,GAD_SEARCH_ONLYWORD,data->search_flags&SEARCH_ONLYWORDS);
	SetGadgetValue(objlist,GAD_SEARCH_RESULT,data->search_result);

	// Activate text field
	ActivateStrGad(GADGET(GetObject(objlist,GAD_SEARCH_TEXT)),window);

	// Event loop
	FOREVER
	{
		struct IntuiMessage *msg;
		BOOL break_flag=0;

		// Check for abort
		if (function_check_abort(handle))
			break;

		// Activate?
		if (handle->flags2&FUNCF_ACTIVATE_ME)
		{
			ActivateWindow(window);
			WindowToFront(window);
			handle->flags2&=~FUNCF_ACTIVATE_ME;
		}

		// Any Intuition messages?
		while ((msg=GetWindowMsg(window->UserPort)))
		{
			struct IntuiMessage copy_msg;

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

			// Gadget?
			if (copy_msg.Class==IDCMP_GADGETUP)
			{
				UWORD gadgetid;

				// Get gadget id
				gadgetid=((struct Gadget *)copy_msg.IAddress)->GadgetID;

				// Look at gadget ID
				switch (gadgetid)
				{
					// Okay
					case GAD_SEARCH_TEXT:
					case GAD_SEARCH_OKAY:

						// Store flags
						data->search_flags=0;
						if (GetGadgetValue(objlist,GAD_SEARCH_CASE))
							data->search_flags|=SEARCH_NOCASE;
						if (GetGadgetValue(objlist,GAD_SEARCH_WILD))
							data->search_flags|=SEARCH_WILDCARD;
						if (GetGadgetValue(objlist,GAD_SEARCH_ONLYWORD))
							data->search_flags|=SEARCH_ONLYWORDS;
						data->search_result=GetGadgetValue(objlist,GAD_SEARCH_RESULT);

						// Get search text
						strcpy(data->search_text,(char *)GetGadgetValue(objlist,GAD_SEARCH_TEXT));
						cancel=0;

					// Cancel
					case GAD_SEARCH_CANCEL:
						break_flag=1;
						break;
				}
			}
		}

		// Check break flag
		if (break_flag) break;

		// Wait for an event
		Wait(1<<window->UserPort->mp_SigBit|1<<handle->ipc->command_port->mp_SigBit);
	}

	// Close window
	CloseConfigWindow(window);

	// Return
	return !cancel;
}
Esempio n. 7
0
void SAVEDS PaletteBox(void)
{
	PaletteBoxData *data;
	struct Window *window;
	IPCData *ipc;

	// Do startup
	if (!(ipc=Local_IPC_ProcStartup((ULONG *)&data,0)))
	{
		Forbid();
		return;
	}

	// Get pen count
	data->pen_count=data->screen_data.pen_count;

	// Open window
	if ((window=palette_box_open(data,data->stuff.stuff1.object_def,data->pen_array,data->pen_array)))
	{
		// Event loop
		FOREVER
		{
			struct IntuiMessage *msg;
			IPCMessage *imsg;
			short break_flag=0;

			// IPC messages
			while ((imsg=(IPCMessage *)GetMsg(ipc->command_port)))
			{
				switch (imsg->command)
				{
					// Quit
					case IPC_QUIT:
						break_flag=1;
						break;

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

					// Hide
					case IPC_HIDE:
						CloseConfigWindow(window);
						window=0;
						break;

					// Show
					case IPC_SHOW:
						data->newwin.parent=(void *)imsg->data;
						if (!(window=palette_box_open(data,data->stuff.stuff1.object_def,data->pen_array,data->pen_array)))
							break_flag=1;
						break;
				}

				IPC_Reply(imsg);
			}

			// Intuition messages
			if (window)
			{
				while ((msg=GetWindowMsg(window->UserPort)))
				{
					struct IntuiMessage msg_copy;
					msg_copy=*msg;
					ReplyWindowMsg(msg);

					// Close
					if (msg_copy.Class==IDCMP_CLOSEWINDOW)
						break_flag=1;

					// Gadget
					else
					if (msg_copy.Class==IDCMP_GADGETUP)
					{
						short fg,bg;

						// Get foreground and background colours
						fg=GetGadgetValue(OBJLIST(window),GAD_PALETTE_FOREGROUND);
						bg=GetGadgetValue(OBJLIST(window),GAD_PALETTE_BACKGROUND);

						// Fix pens
						if (((struct Library*)IntuitionBase)->lib_Version>=39)
						{
							if (fg>=4 && fg<8) fg=248+fg;
							else
							if (fg>7) fg-=4;
							if (bg>=4 && bg<8) bg=248+bg;
							else
							if (bg>7) bg-=4;
						}
						data->fgpen=fg;
						data->bgpen=bg;

						// Send new colours
						IPC_Command(
							data->owner_ipc,
							BUTTONEDIT_NEW_COLOURS,
							data->fgpen,
							(APTR)data->bgpen,
							0,
							0);
					}

					// Key
					else
					if (msg_copy.Class==IDCMP_RAWKEY)
					{
						// Help?
						if (msg_copy.Code==0x5f &&
							!(msg_copy.Qualifier&VALID_QUALIFIERS))
						{
							// Set busy pointer
							SetWindowBusy(window);

							// Send help command
							IPC_Command(data->main_ipc,IPC_HELP,(1<<31),"Select Colours",0,REPLY_NO_PORT);

							// Clear busy pointer
							ClearWindowBusy(window);
						}
					}
				}
			}

			if (break_flag) break;

			Wait(1<<ipc->command_port->mp_SigBit|
				((window)?1<<window->UserPort->mp_SigBit:0));
		}

		CloseConfigWindow(window);
	}
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;
}