Ejemplo n.º 1
0
// Free list of backdrop objects
void backdrop_free_list(BackdropInfo *info)
{
	BackdropObject *object;

	// Invalid info?
	if (!info) return;

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

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

		// Remove object
		backdrop_remove_object(info,object);

		// Get next object
		object=next;
	}

	// Unlock backdrop list
	unlock_listlock(&info->objects);
}
Ejemplo n.º 2
0
// Save from button editor
void buttons_edit_defaults(ULONG id)
{
	IPCData *ipc;

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

	// Go through button banks
	for (ipc=(IPCData *)GUI->buttons_list.list.lh_Head;
		ipc->node.mln_Succ;
		ipc=(IPCData *)ipc->node.mln_Succ)
	{
		// Get buttons pointer
		Buttons *buttons=IPCDATA(ipc);

		// Is this the bank being edited, and is it a toolbar?
		if (buttons->editor && buttons->flags&BUTTONF_TOOLBAR)
		{
			// Send command to button bank
			IPC_Command(buttons->ipc,id,0,0,0,0);
			break;
		}
	}

	// Unlock buttons list
	unlock_listlock(&GUI->buttons_list);
}
Ejemplo n.º 3
0
// Do a global datestamp update
void update_lister_global(char *path)
{
	IPCData *ipc;
	Lister *lister;

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

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

		// Compare path
		if (stricmp(lister->cur_buffer->buf_Path,path)==0)
		{
			// Send update command
			lister_command(lister,LISTER_UPDATE_STAMP,0,0,0,0);
		}
	}

	// Unlock lister list
	unlock_listlock(&GUI->lister_list);
}
Ejemplo n.º 4
0
// Free buffers from a particular lister
void lister_free_caches(Lister *lister,char *handler)
{
	DirBuffer *buffer;

	// Lock buffer list
	lock_listlock(&GUI->buffer_list,TRUE);

	// Go through all buffers
	for (buffer=(DirBuffer *)GUI->buffer_list.list.lh_Head;
		buffer->node.ln_Succ;)
	{
		DirBuffer *next;

		// Save next pointer
		next=(DirBuffer *)buffer->node.ln_Succ;

		// See if buffer matches lister and handler
		if (buffer->buf_OwnerLister==lister &&
			stricmp(buffer->buf_CustomHandler,handler)==0)
		{
			// Check buffer isn't currently displayed
			if (!buffer->buf_CurrentLister)
			{
				// Free buffer
				lister_free_buffer(buffer);
			}
		}

		// Get next pointer
		buffer=next;
	}

	// Unlock buffer list
	unlock_listlock(&GUI->buffer_list);
}
Ejemplo n.º 5
0
// Update a disk name
void backdrop_update_disk(BackdropInfo *info,devname_change *change,BOOL show)
{
	BackdropObject *object;

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

	// Go through icons
	for (object=(BackdropObject *)info->objects.list.lh_Head;
		object->node.ln_Succ;
		object=(BackdropObject *)object->node.ln_Succ)
	{
		// Is this the critter?
		if (object->type==BDO_DISK &&
			stricmp(change->old_name,object->device_name)==0)
		{
			// Erase object
			if (show) backdrop_erase_icon(info,object,0);

			// Store new name
			strcpy(object->name,change->new_name);

			// Show new object
			if (show) backdrop_render_object(info,object,BRENDERF_CLIP);
			break;
		}
	}

	// Unlock main backdrop list
	unlock_listlock(&info->objects);
}
Ejemplo n.º 6
0
// Save from button editor
void buttons_edit_save(ULONG id)
{
	IPCData *ipc;

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

	// Go through button banks
	for (ipc=(IPCData *)GUI->buttons_list.list.lh_Head;
		ipc->node.mln_Succ;
		ipc=(IPCData *)ipc->node.mln_Succ)
	{
		// Get buttons pointer
		Buttons *buttons=IPCDATA(ipc);

		// Is this the bank being edited?
		if (buttons->editor)
		{
			// Send command to button bank
			IPC_Command(
				buttons->ipc,
				(id==BUTTONEDIT_MENU_SAVE)?BUTTONS_SAVE:BUTTONS_SAVEAS,
				0,
				0,
				0,
				0);
			break;
		}
	}

	// Unlock buttons list
	unlock_listlock(&GUI->buttons_list);
}
Ejemplo n.º 7
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);
			}
		}
	}
}
Ejemplo n.º 8
0
// See if there's any extensions for this filetype
BOOL popup_ext_check(char *name)
{
	PopUpExt *ext;
	BOOL ok=0;

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

	// Go through list
	for (ext=(PopUpExt *)GUI->popupext_list.list.lh_Head;
		ext->pe_Node.ln_Succ;
		ext=(PopUpExt *)ext->pe_Node.ln_Succ)
	{
		// Match filetype
		if (stricmp(ext->pe_FileType,name)==0)
		{
			// Got one
			ok=1;
			break;
		}
	}

	// Unlock list
	unlock_listlock(&GUI->popupext_list);
	return ok;
}
Ejemplo n.º 9
0
// Remove PopUp extensions for a command
void remove_popup_ext(char *name)
{
	PopUpExt *ext,*next;

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

	// Go through list
	for (ext=(PopUpExt *)GUI->popupext_list.list.lh_Head;
		ext->pe_Node.ln_Succ;
		ext=next)
	{
		// Cache next
		next=(PopUpExt *)ext->pe_Node.ln_Succ;

		// Match command name
		if (stricmp(ext->pe_Command,name)==0)
		{
			// Remove this and free it
			Remove((struct Node *)ext);
			FreeMemH(ext);
		}
	}

	// Unlock list
	unlock_listlock(&GUI->popupext_list);
}
Ejemplo n.º 10
0
// Handle an AppMessage
void rexx_handle_appmsg(struct AppMessage *msg)
{
	RexxAppThing *app;
	struct AppSnapshotMsg *amsg;
	short type;

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

	// Snapshot?
	if (msg->am_Type==MTYPE_APPSNAPSHOT)
	{
		// Get message pointer
		amsg=(struct AppSnapshotMsg *)msg;

		// Close?
		if (amsg->flags&APPSNAPF_CLOSE) type=REXXAPPCMD_CLOSE;

		// Info?
		else
		if (amsg->flags&APPSNAPF_INFO) type=REXXAPPCMD_INFO;

		// Menu?
		else
		if (amsg->flags&APPSNAPF_MENU) type=REXXAPPCMD_MENU;

		// Snapshot
		else type=REXXAPPCMD_SNAPSHOT;
	}

	// Double-click?
	else
	if (msg->am_NumArgs==0) type=REXXAPPCMD_DOUBLECLICK;

	// Drop
	else type=REXXAPPCMD_DRAGNDROP;

	// Go through list
	for (app=(RexxAppThing *)GUI->rexx_apps.list.lh_Head;
		app->node.ln_Succ;
		app=(RexxAppThing *)app->node.ln_Succ)
	{
		// Match with UserData in AppMessage
		if (app==(RexxAppThing *)msg->am_UserData)
		{
			// Send message
			rexx_send_appmsg(app,type,msg);
			break;
		}
	}

	// Unlock list
	unlock_listlock(&GUI->rexx_apps);
}
Ejemplo n.º 11
0
// Searches for a named buffer and moves to it if found - special version for ARexx
BOOL lister_find_cached_buffer(
	Lister *lister,
	char *path,
	char *handler)
{
	short ret=0;
	DirBuffer *buffer;

	// Lock buffer list
	lock_listlock(&GUI->buffer_list,FALSE);

	// Go through all buffers
	for (buffer=(DirBuffer *)GUI->buffer_list.list.lh_Head;
		buffer->node.ln_Succ;
		buffer=(DirBuffer *)buffer->node.ln_Succ)
	{
		// Skip current buffer
		if (buffer==lister->cur_buffer) continue;

		// See if handler matches
		if (stricmp(buffer->buf_CustomHandler,handler)==0)
		{
			// Does lister match?
			if (buffer->buf_OwnerLister==lister)
			{
				short res;

				// Does pathname match?
				res=(buffer->more_flags&DWF_CASE)?	strcmp(path,buffer->buf_Path):
													stricmp(path,buffer->buf_Path);

				// Match?
				if (res==0)
				{
					ret=1;
					break;
				}
			}
		}
	}

	// Did we find one?
	if (ret)
	{
		// Show buffer in lister
		lister_show_buffer(lister,buffer,1,1);
	}

	// Unlock buffer list
	unlock_listlock(&GUI->buffer_list);

	return ret;
}
Ejemplo n.º 12
0
// 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);
}
Ejemplo n.º 13
0
// Free icon remapping
void backdrop_free_remap(BackdropInfo *info,struct Window *window)
{
	BackdropObject *icon;

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

	// Free icon remapping
	for (icon=(BackdropObject *)info->objects.list.lh_Head;
		icon->node.ln_Succ;
		icon=(BackdropObject *)icon->node.ln_Succ)
	{
		// Remap the icon
		RemapIcon(icon->icon,(window)?window->WScreen:0,1);
	}

	// Unlock icon list
	unlock_listlock(&info->objects);
}
Ejemplo n.º 14
0
// Select all objects
void backdrop_select_all(BackdropInfo *info,short state)
{
	BackdropObject *object;
	BOOL draw=0;

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

	// Go through backdrop list
	for (object=(BackdropObject *)info->objects.list.lh_Head;
		object->node.ln_Succ;
		object=(BackdropObject *)object->node.ln_Succ)
	{
		// Is object not selected?
		if (((state && !object->state) ||
			(!state && object->state)) && object->icon)
		{
			// Select object
			object->state=state;
			object->flags|=BDOF_STATE_CHANGE;

/*
			// Add to selection list
			backdrop_selection_list(info,object);
*/
			draw=1;
		}
	}

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

	// Fix selection count
	backdrop_fix_count(info,1);

	// Fix menus for a lister
	if (info->lister) lister_fix_menus(info->lister,1);

	// Show objects
	if (draw) backdrop_show_objects(info,0);
}
Ejemplo n.º 15
0
// 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);
}
Ejemplo n.º 16
0
// User selected a cache list entry
BOOL lister_select_cache(Lister *lister,DirBuffer *test_buffer)
{
	DirBuffer *buffer;
	BOOL ret=0;

	// Lock buffer list
	lock_listlock(&GUI->buffer_list,FALSE);

	// Go through all buffers
	for (buffer=(DirBuffer *)GUI->buffer_list.list.lh_Head;
		buffer->node.ln_Succ;
		buffer=(DirBuffer *)buffer->node.ln_Succ)
	{
		// Match buffer?
		if (buffer==test_buffer)
		{
			// See if buffer has a custom handler
			if (buffer->buf_CustomHandler[0])
			{
				// If we're currently displaying a special buffer, return to a normal one
				check_special_buffer(lister,0);

				// Show buffer in lister
				lister_show_buffer(lister,buffer,1,0);

				// Send active message
				buffer_active(buffer,1);
				ret=1;
				break;
			}
		}
	}

	// Unlock buffer list
	unlock_listlock(&GUI->buffer_list);
	return ret;
}
Ejemplo n.º 17
0
// Remap rexx icons
void rexx_remap_icons(BOOL free)
{
	RexxAppThing *look;

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

	// Go through list
	for (look=(RexxAppThing *)GUI->rexx_apps.list.lh_Head;
		look->node.ln_Succ;
		look=(RexxAppThing *)look->node.ln_Succ)
	{
		// Icon?
		if (look->node.ln_Type==REXXAPP_ICON)
		{
			// Remap it (if local)
			if (look->flags&RATF_LOCAL)
				RemapIcon(look->icon,GUI->screen_pointer,free);
		}
	}

	// Unlock list
	unlock_listlock(&GUI->rexx_apps);
}
Ejemplo n.º 18
0
// Handle drop on an object
BOOL desktop_drop_on_object(BackdropInfo *info,DOpusAppMessage **msg,BackdropObject *drop_obj,UWORD qual)
{
	char *name;
	short ret=1;

	// Allocate buffer
	if (!(name=AllocVec(1024,0))) return 1;

	// Was it an AppIcon?
	if (drop_obj->type==BDO_APP_ICON)
	{
		// Is the icon busy?
		if (drop_obj->flags&BDOF_BUSY)
		{
			// Flash error
			DisplayBeep(info->window->WScreen);
		}

		// Otherwise, pass message on
		else
		{
			struct MsgPort *port;

			// Turn message into an AppIcon one
			(*msg)->da_Msg.am_Type=MTYPE_APPICON;

			// Get port and info
			port=WB_AppWindowData(
				(struct AppWindow *)drop_obj->misc_data,
				&(*msg)->da_Msg.am_ID,
				&(*msg)->da_Msg.am_UserData);

			// Fix reply port
			(*msg)->da_Msg.am_Message.mn_ReplyPort=GUI->appmsg_port;

			// Send the message on
			PutMsg(port,(struct Message *)*msg);

			// Zero message pointer
			*msg=0;
		}
	}

	// Was it a group?
	else
	if (drop_obj->type==BDO_GROUP)
	{
		short arg;
		GroupData *group;
		BOOL ok=0;

		// Find group if it's open
		lock_listlock(&GUI->group_list,0);
		if (!(group=backdrop_find_group(drop_obj)))
			unlock_listlock(&GUI->group_list);

		// Go through arguments
		for (arg=0;arg<(*msg)->da_Msg.am_NumArgs;arg++)
		{
			// Valid file?
			if ((*msg)->da_Msg.am_ArgList[arg].wa_Name &&
				*(*msg)->da_Msg.am_ArgList[arg].wa_Name)
			{
				// Get filename
				GetWBArgPath(&(*msg)->da_Msg.am_ArgList[arg],name,512);

				// Send add message to group if it's open
				if (group)
				{
					char *copy;

					// Copy name
					if ((copy=AllocVec(strlen(name)+1,0)))
					{
						strcpy(copy,name);
						IPC_Command(group->ipc,GROUP_ADD_ICON,0,0,copy,0);
						ok=1;
					}
				}

				// Otherwise add object to group
				else
				{
					backdrop_group_add_object(drop_obj->name,0,name,-1,-1);
					ok=1;
				}
			}
		}

		// Show error if no ok
		if (!ok) DisplayBeep(GUI->screen_pointer);

		// Unlock process list if it's locked
		if (group) unlock_listlock(&GUI->group_list);
	}

	// Or a project?
	else
	if (drop_obj->icon->do_Type==WBPROJECT)
	{
		// Is it an Opus command?
		if (command_filetype)
		{
			BPTR lock,old;

			// Set failure initially
			ret=0;

			// Get lock on directory
			if ((lock=backdrop_icon_lock(drop_obj)))
			{
				// Go there
				old=CurrentDir(lock);

				// See if it's a command
				if (filetype_match_type(drop_obj->name,command_filetype))
				{
					// Run command with args
					backdrop_object_open(
						info,
						drop_obj,
						0,
						0,
						(*msg)->da_Msg.am_NumArgs,
						(*msg)->da_Msg.am_ArgList);
					ret=1;
				}

				// Restore CD
				CurrentDir(old);
			}
		}

		// Beep if not a command
		if (!ret) DisplayBeep(GUI->screen_pointer);
	}

	// Or a tool?
	else
	if (drop_obj->icon->do_Type==WBTOOL)
	{
		// Run program with args
		backdrop_object_open(
			info,
			drop_obj,
			0,
			0,
			(*msg)->da_Msg.am_NumArgs,
			(*msg)->da_Msg.am_ArgList);
	}


	// Or a disk/directory?
	else
	if (drop_obj->icon->do_Type==WBDISK ||
		drop_obj->icon->do_Type==WBDRAWER ||
		drop_obj->icon->do_Type==WBGARBAGE)
	{
		struct ArgArray *arg_array;

		// Get arg array
		if ((arg_array=AppArgArray(*msg,AAF_ALLOW_DIRS)))
		{
			BPTR lock;

			// Get pathname of first file
			DevNameFromLockDopus((*msg)->da_Msg.am_ArgList[0].wa_Lock,name,512);

			// Need source directory; if no name, get parent
			if ((!(*msg)->da_Msg.am_ArgList[0].wa_Name ||
				!*(*msg)->da_Msg.am_ArgList[0].wa_Name) &&
				(lock=ParentDir((*msg)->da_Msg.am_ArgList[0].wa_Lock)))
			{
				// Get pathname of parent
				DevNameFromLockDopus(lock,name,512);
				UnLock(lock);
			}

			// Get destination path
			if ((lock=backdrop_icon_lock(drop_obj)))
			{
				short action;

				// Get path
				DevNameFromLockDopus(lock,name+512,512);
				UnLock(lock);

				// Is object a left-out?
				if (drop_obj->type==BDO_LEFT_OUT)
				{
					// Add left-out name
					AddPart(name+512,drop_obj->name,512);
				}

				// Get filetype action
				if (qual&IEQUALIFIER_CONTROL) action=FTTYPE_CTRL_DRAGDROP;
				else
				if (qual&(IEQUALIFIER_LALT|IEQUALIFIER_RALT)) action=FTTYPE_ALT_DRAGDROP;
				else
				action=FTTYPE_DRAG_DROP;

				// Do filetype action on files
				function_launch(
					FUNCTION_FILETYPE,
					0,
					action,
					FUNCF_DRAG_DROP|FUNCF_ICONS,
					0,0,
					name,name+512,
					arg_array,
					0,
					(Buttons *)CopyAppMessage(*msg,global_memory_pool));
			}
		}
	}
	else ret=0;

	FreeVec(name);
	return ret;
}
Ejemplo n.º 19
0
void desktop_drop(BackdropInfo *info,DOpusAppMessage *msg,UWORD qual)
{
	BackdropObject *drop_obj;
	short ok=0,x,y;
	char *name,*source_path;
	short arg,action=DESKTOP_POPUP_LEFTOUT;
	struct ArgArray *array=0;
	struct ArgArrayEntry *aae;
	BOOL check;

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

	// See if we dropped stuff on an object
	if ((drop_obj=backdrop_get_object(info,msg->da_Msg.am_MouseX,msg->da_Msg.am_MouseY,0)))
	{
		// Is shift/alt down?
		if ((qual&(IEQUALIFIER_LSHIFT|IEQUALIFIER_LALT))==(IEQUALIFIER_LSHIFT|IEQUALIFIER_LALT))
		{
			char pathname[256];

			// Get path of first file
			GetWBArgPath(&msg->da_Msg.am_ArgList[0],pathname,256);

			// Replace the image
			backdrop_replace_icon_image(info,pathname,drop_obj);

			// Reply the message
			ReplyAppMessage(msg);
		}

		// Handle drop on an object
		else
		if (desktop_drop_on_object(info,&msg,drop_obj,qual))
		{
			// Reply the message
			ReplyAppMessage(msg);
		}

		// Not dropped
		else drop_obj=0;
	}

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

	// Dropped on an object?
	if (drop_obj) return;

	// Get buffer
	if (!(name=AllocVec(1024,MEMF_CLEAR))) return;
	source_path=name+512;

	// Popup menu?
	if (environment->env->env_flags&ENVF_DESKTOP_FOLDER)
	{
		UWORD res;

		// Activate the underlying menu
		ActivateWindow(info->window);

		// Default action set?
		if (environment->env->desktop_popup_default>DESKTOP_POPUP_NONE &&
			!(qual&(IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)))
		{
			// Use default action
			action=environment->env->desktop_popup_default;
		}

		// Ask user what they want to do
		else
		if ((res=DoPopUpMenu(info->window,&GUI->desktop_menu->ph_Menu,0,SELECTDOWN))==(UWORD)-1 || res==MENU_DESKTOP_CANCEL)
		{
			// Cancelled	
			FreeVec(name);
			return;
		}

		// Help?
		else
		if (res&POPUP_HELPFLAG)
		{
			// Do help
			help_menu_help(res&~POPUP_HELPFLAG,0);

			// Cancelled	
			FreeVec(name);
			return;
		}

		// Get action
		else
		if (res==MENU_DESKTOP_COPY) action=DESKTOP_POPUP_COPY;
		else
		if (res==MENU_DESKTOP_MOVE) action=DESKTOP_POPUP_MOVE;
	}
		
	// Set busy pointer
	SetBusyPointer(info->window);

	// DOpus message?
	check=CheckAppMessage(msg);

	// Go through arguments
	for (arg=0;arg<msg->da_Msg.am_NumArgs;arg++)
	{
		// What operation?
		switch (action)
		{
			// Leave out?
			case DESKTOP_POPUP_LEFTOUT:

				// Get path name
				GetWBArgPath(&msg->da_Msg.am_ArgList[arg],name,512);

				// Ignore if it's an icon or a disk
				if (!(isicon(name)) && name[strlen(name)-1]!=':')
				{
					short len,perm=0;
					BackdropObject *icon;

					// Permanent?
					if (GUI->flags2&GUIF2_BENIFY)
						perm=1;

					// Get position
					x=msg->da_Msg.am_MouseX;
					y=msg->da_Msg.am_MouseY;

					// Drop from DOpus?
					if (check)
					{
						// Adjust position for icon offset
						x+=msg->da_DragOffset.x+msg->da_DropPos[arg].x;
						y+=msg->da_DragOffset.y+msg->da_DropPos[arg].y;
					}

					// Strip trailing /
					len=strlen(name)-1;
					if (name[len]=='/') name[len]=0;

					// Leave this out
					if ((icon=backdrop_leave_out(info,name,(perm)?BLOF_PERMANENT:0,x,y)))
					{
						// Position it
						backdrop_place_object(info,icon);

						// Save for permanent leftout
						if (perm) backdrop_save_leftouts(info);
						ok=1;
					}
				}
				break;

			// Copy/Move
			case DESKTOP_POPUP_COPY:
			case DESKTOP_POPUP_MOVE:
				{	
					BOOL dir=0;

					// Create ArgArray if needed
					if (!array &&
						!(array=NewArgArray())) break;

					// Get path name
					GetWBArgPath(&msg->da_Msg.am_ArgList[arg],name,512);

					// Set flag if a directory
					if (!msg->da_Msg.am_ArgList[arg].wa_Name ||
						!*msg->da_Msg.am_ArgList[arg].wa_Name) dir=1;

					// Get source path
					if (!*source_path)
					{
						char *ptr;
	
						// Copy from name
						strcpy(source_path,name);

						// Strip last part
						if ((ptr=FilePart(source_path))) *ptr=0;
					}

					// Create argument
					if ((aae=NewArgArrayEntry(array,FilePart(name))))
					{
						// Set directory flag
						if (dir) aae->ae_Flags|=AEF_DIR;

						// Set OK flag
						ok=1;
					}
				}
				break;
		}
	}

	// Successful?
	if (ok)
	{
		// Left-outs?
		if (action==DESKTOP_POPUP_LEFTOUT)
		{
			// Refresh
			backdrop_show_objects(info,BDSF_RECALC);
		}

		// Otherwise, launch function
		else
		{
			// Launch the function
			function_launch(
				FUNCTION_RUN_FUNCTION_EXTERNAL,
				(action==DESKTOP_POPUP_COPY)?def_function_copy:def_function_move,
				0,
				FUNCF_ICONS|FUNCF_RESCAN_DESKTOP|FUNCF_DRAG_DROP|FUNCF_COPY_NO_MOVE,
				0,0,
				source_path,environment->env->desktop_location,
				array,
				0,
				(Buttons *)CopyAppMessage(msg,global_memory_pool));
		}
	}

	// Otherwise, free array
	else FreeArgArray(array);

	// Free buffer
	FreeVec(name);

	// Clear busy pointer
	ClearPointer(info->window);

	// Reply the message
	ReplyAppMessage(msg);
}
Ejemplo n.º 20
0
// Handle some appstuff
BOOL buttons_app_message(Buttons *buttons,DOpusAppMessage *msg)
{
	short col,row;
	Cfg_Button *button;
	Cfg_Function *function;
	struct ArgArray *arg_array;
	IPCData *ipc;

	// Lock process list
	lock_listlock(&GUI->process_list,FALSE);

	// See if button editor is running
	ipc=IPC_FindProc(&GUI->process_list,NAME_BUTTON_EDITOR_RUN,FALSE,0);

	// Unlock process list
	unlock_listlock(&GUI->process_list);

	// Editor running?
	if (ipc)
	{
		// Send button
		if (buttons_edit_bank(buttons,-1,-1,0,(struct AppMessage *)msg,0))
		{
			// Message was swallowed
			return 1;
		}
	}

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

	// Get button and function we dropped on
	col=msg->da_Msg.am_MouseX;
	row=msg->da_Msg.am_MouseY;
	if (!(button=button_from_point(buttons,&col,&row)) ||
		!(function=button_valid(button,button->current)))
	{
		FreeSemaphore(&buttons->bank->lock);
		return 0;
	}

	// Get arg array
	if ((arg_array=AppArgArray(msg,AAF_ALLOW_DIRS)))
	{
		BPTR lock;
		char pathname[256];

		// Get pathname of first file
		DevNameFromLockDopus(msg->da_Msg.am_ArgList[0].wa_Lock,pathname,256);

		// Need source directory; if no name, get parent
		if ((!msg->da_Msg.am_ArgList[0].wa_Name ||
			!*msg->da_Msg.am_ArgList[0].wa_Name) &&
			(lock=ParentDir(msg->da_Msg.am_ArgList[0].wa_Lock)))
		{
			// Get pathname of parent
			DevNameFromLockDopus(lock,pathname,256);
			UnLock(lock);
		}

		// Launch function
		function_launch(
			FUNCTION_RUN_FUNCTION_EXTERNAL,
			function,
			0,
			0,
			0,0,
			pathname,0,
			arg_array,0,
			buttons);
	}

	// Unlock button lock
	FreeSemaphore(&buttons->bank->lock);

	return 0;
}
Ejemplo n.º 21
0
// Read program groups (icon list must be locked)
void backdrop_read_groups(BackdropInfo *info)
{
	BPTR lock;
	struct FileInfoBlock __aligned fib;
	struct AnchorPath *anchor;
	short error;

	// Allocate anchor
	if (!(anchor=AllocVec(sizeof(struct AnchorPath)+256,MEMF_CLEAR)))
		return;

	// Initialise anchor
	anchor->ap_Strlen=256;

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

	// Continue while there's files
	while (!error)
	{
		char *ptr;

		// Strip .info suffix
		if (ptr=sufcmp(anchor->ap_Buf,".info")) *ptr=0;

		// See if directory exists to go with it
		if (lock=Lock(anchor->ap_Buf,ACCESS_READ))
		{
			// Examine file
			Examine(lock,&fib);
			UnLock(lock);

			// Is it a directory?
			if (fib.fib_DirEntryType>0)
			{
				BackdropObject *object;
				struct List *search;

				// Lock icon list
				lock_listlock(&info->objects,FALSE);

				// See if group already exists
				search=&info->objects.list;
				while (object=(BackdropObject *)FindNameI(search,fib.fib_FileName))
				{
					// Is it a group?
					if (object->type==BDO_GROUP)
						break;

					// Continue search
					search=(struct List *)object;
				}

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

				// Didn't have it already?
				if (!object)
				{
					// Create a new icon for this
					if (object=backdrop_leftout_new(info,anchor->ap_Buf,0,0))
					{
						// Change type to group
						object->type=BDO_GROUP;

						// Get icon
						backdrop_get_icon(info,object,GETICON_CD);
					}
				}
			}
		}

		// Get next entry
		error=MatchNext(anchor);
	}

	// Clean up
	MatchEnd(anchor);
	FreeVec(anchor);
}
Ejemplo n.º 22
0
// Searches for a named buffer and moves to it if found
// Called from the LISTER PROCESS (unless LISTER_BFPF_DONT_MOVE is set)
DirBuffer *lister_find_buffer(
	Lister *lister,
	DirBuffer *start,
	char *path,
	struct DateStamp *stamp,
	char *volume,
	ULONG flags)
{
	short ret=0;
	DirBuffer *buffer;
	char *path_buffer;
	struct FileInfoBlock *fib;

	// Got a lister?
	if (lister)
	{
		path_buffer=lister->work_buffer;
		fib=lister->fib;
	}

	// Need to allocate data
	else
	{
		if (!(path_buffer=AllocVec(512,0)) ||
			!(fib=AllocDosObject(DOS_FIB,0)))
		{
			FreeVec(path_buffer);
			return 0;
		}
	}

	// Copy path, terminate correctly
	strcpy(path_buffer,path);
	AddPart(path_buffer,"",512);

	// Lock buffer list
	if (!(flags&LISTER_BFPF_DONT_LOCK))
		lock_listlock(&GUI->buffer_list,FALSE);

	// Get starting position
	if (start) buffer=start;
	else buffer=(DirBuffer *)GUI->buffer_list.list.lh_Head;

	// Go through all buffers
	for (;buffer->node.ln_Succ;
		buffer=(DirBuffer *)buffer->node.ln_Succ)
	{
		// Valid path in this directory?
		if (buffer->flags&DWF_VALID &&
				(flags&LISTER_BFPF_DONT_LOCK ||
					!buffer->buf_CurrentLister ||
					buffer->buf_CurrentLister==lister))
		{
			// Does pathname match?
			if (stricmp(path_buffer,buffer->buf_Path)==0)
			{
				BOOL match=1;

				// If datestamp is supplied, try that
				if (stamp)
				{
					if (CompareDates(stamp,&buffer->buf_VolumeDate)!=0) match=0;
				}

				// Or if a volume name is provided, test that
				if (volume)
				{
					if (stricmp(volume,buffer->buf_VolumeLabel)!=0) match=0;
				}

				// Matched?
				if (match)
				{
					BPTR lock;

					// Do we need to test dates?
					if (!(flags&LISTER_BFPF_DONT_TEST))
					{
						// Try to lock and examine this directory
						if (lock=Lock(path_buffer,ACCESS_READ))
						{
							// Examine and unlock
							Examine(lock,fib);
							UnLock(lock);

							// If datestamp on directory has changed, don't go to it
							if (CompareDates(&fib->fib_Date,&buffer->buf_DirectoryDate)!=0)
								continue;
						}
						else continue;
					}

					ret=1;
					break;
				}
			}
		}
	}

	// Did we find one?
	if (ret)
	{
		// Go to buffer if requested
		if (!(flags&LISTER_BFPF_DONT_MOVE) && lister)
		{
			// Show buffer in lister
			lister_show_buffer(lister,buffer,1,1);

			// See if buffer needs re-reading
			lister_check_old_buffer(lister,0);
		}
	}
	else buffer=0;

	// Was the list locked?
	if (!(flags&LISTER_BFPF_DONT_LOCK))
	{
		// Allowed to unlock?
		if (!(flags&LISTER_BFPF_DONT_UNLOCK) || !buffer)

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

	// Cleanup
	if (!lister)
	{
		FreeVec(path_buffer);
		FreeDosObject(DOS_FIB,fib);
	}

	return buffer;
}
Ejemplo n.º 23
0
// Handle backdrop icon idcmp stuff
BOOL backdrop_idcmp(BackdropInfo *info,struct IntuiMessage *msg,unsigned short flags)
{
	BOOL handled=1;
	BOOL busy=0;

	// Lister locked?
	if (info->lister && info->lister->flags&LISTERF_LOCK) busy=1;

	// Message class?
	switch (msg->Class)
	{
		// Size change
		case IDCMP_NEWSIZE:
			backdrop_update_size(info);
			break;

		// Refresh window
		case IDCMP_REFRESHWINDOW:

			// If we haven't already refreshed
			if (!(info->flags&BDIF_REFRESHED))
			{
				UWORD ref_flags;

				// Get flags for refreshing
				ref_flags=BDSF_REFRESH;
				if (!(flags&BIDCMPF_LISTER)) ref_flags|=BDSF_REFRESH_DONE;

				// From a resize?
				if (info->flags&BDIF_NEW_SIZE) ref_flags|=BDSF_RECALC;

				// Otherwise, check that size is ok
				else backdrop_check_size(info);

				// Refresh objects
				backdrop_show_objects(info,ref_flags);
			}

			// Clear flags
			info->flags&=~(BDIF_NEW_SIZE|BDIF_REFRESHED);

			// Got a lister?
			if (info->lister)
			{
				// Clear 'sized' flag in lister
				info->lister->flags&=~LISTERF_RESIZED;

				// Save event for lister too
				if (flags&BIDCMPF_LISTER) handled=0;
			}
			break;


		// Mouse moved
		case IDCMP_MOUSEMOVE:

			// Rubber banding?
			if (info->flags&BDIF_RUBBERBAND)
			{
				short x,y;

				// Get coordinates, clip to borders
				x=info->window->MouseX;
				y=info->window->MouseY;
				if (x<info->size.MinX) x=info->size.MinX;
				if (x>info->size.MaxX) x=info->size.MaxX;
				if (y<info->size.MinY) y=info->size.MinY;
				if (y>info->size.MaxY) y=info->size.MaxY;

				// Have coordinates changed?
				if (info->select.MaxX!=x ||
					info->select.MaxY!=y)
				{
					// Erase old box
					backdrop_rubber_band(info,0);

					// New coordinates
					info->select.MaxX=x;
					info->select.MaxY=y;

					// Show new box
					backdrop_rubber_band(info,1);
				}
				break;
			}

			// Are we dragging something?
			else
			if (info->flags&BDIF_DRAGGING && info->last_sel_object)
			{
				// Show drag objects
				backdrop_show_drag(
					info,
					info->last_sel_object,
					info->window->WScreen->MouseX,
					info->window->WScreen->MouseY);
				break;
			}

			// No gadget down, or no real-time scrolling?
			if (!info->down_gadget || !(environment->env->display_options&DISPOPTF_REALTIME_SCROLL))
			{
				// Not handled
				handled=0;
				break;
			}

		// Tick
		case IDCMP_INTUITICKS:

			// Tick?
			if (msg->Class==IDCMP_INTUITICKS)
			{
				// Increment tick count
				++info->tick_count;

				// No gadget down?
				if (!info->down_gadget)
				{
					// Turn ticks off if not dragging
					if (!(info->flags&(BDIF_DRAGGING|BDIF_RUBBERBAND)))
						ModifyIDCMP(info->window,info->window->IDCMPFlags&~IDCMP_INTUITICKS);
					break;
				}

				// Ignore this gadget?
				if (info->flags&BDIF_IGNORE_GADGET)
				{
					info->flags&=~BDIF_IGNORE_GADGET;
					break;
				}
			}

			// Fake gadget down
			msg->IAddress=info->down_gadget;

		// Gadget down
		case IDCMP_GADGETDOWN:

			// Store gadget
			if (info->down_gadget!=(struct Gadget *)msg->IAddress)
			{
				info->down_gadget=(struct Gadget *)msg->IAddress;
				info->flags|=BDIF_IGNORE_GADGET;
				ModifyIDCMP(info->window,info->window->IDCMPFlags|IDCMP_INTUITICKS);
			}

			// Check gadget is selected
			if (!(info->down_gadget->Flags&GFLG_SELECTED))
				break;

			// Look at gadget ID
			switch (info->down_gadget->GadgetID)
			{
				// Up arrow
				case GAD_VERT_ARROW_UP:
					backdrop_scroll(info,0,-1);
					break;

				// Down arrow
				case GAD_VERT_ARROW_DOWN:
					backdrop_scroll(info,0,1);
					break;

				// Left arrow
				case GAD_HORIZ_ARROW_LEFT:
					backdrop_scroll(info,-1,0);
					break;

				// Right arrow
				case GAD_HORIZ_ARROW_RIGHT:
					backdrop_scroll(info,1,0);
					break;

				// Vertical slider
				case GAD_VERT_SCROLLER:
					if (environment->env->display_options&DISPOPTF_REALTIME_SCROLL)
						backdrop_pos_slider(info,SLIDER_VERT);
					break;

				// Horizontal slider
				case GAD_HORIZ_SCROLLER:
					if (environment->env->display_options&DISPOPTF_REALTIME_SCROLL)
						backdrop_pos_slider(info,SLIDER_HORZ);
					break;
			}
			break;


		// Gadget up
		case IDCMP_GADGETUP:
			info->down_gadget=0;
			info->flags&=~BDIF_IGNORE_GADGET;
			ModifyIDCMP(info->window,info->window->IDCMPFlags&~IDCMP_INTUITICKS);

			// Look at gadget ID
			switch (((struct Gadget *)msg->IAddress)->GadgetID)
			{
				// Vertical slider
				case GAD_VERT_SCROLLER:
					backdrop_pos_slider(info,SLIDER_VERT);
					break;

				// Horizontal slider
				case GAD_HORIZ_SCROLLER:
					backdrop_pos_slider(info,SLIDER_HORZ);
					break;

				// Another gadget
				default:
					handled=0;
					break;
			}
			break;


		// Mouse buttons
		case IDCMP_MOUSEBUTTONS:

			// Ignore if busy
			if (busy) break;

			// Clear down gadget
			info->down_gadget=0;
			info->flags&=~BDIF_IGNORE_GADGET;
			ModifyIDCMP(info->window,info->window->IDCMPFlags&~IDCMP_INTUITICKS);

			// Handle button
			handled=backdrop_handle_button(info,msg,flags);

			// Remember the last button pushed
			info->last_button=msg->Code&~IECODE_UP_PREFIX;
			break;


		// Key press
		case IDCMP_RAWKEY:

			// Dragging something?
			if (info->flags&(BDIF_RUBBERBAND|BDIF_DRAGGING))
			{
				// If escape is pressed, cancel drag
				if (msg->Code==0x45) backdrop_stop_drag(info);
				break;
			}

			// Title-barred lister?
			if (info->lister && info->lister->more_flags&LISTERF_TITLEBARRED)
				break;

			// Not handled by default
			handled=0;

			// Look at key
			switch (msg->Code)
			{
				// Space toggles icon selection
				case 0x40:

					// Lister not busy?
					if (!busy)
					{
						BackdropObject *object;

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

						// Turn off?
						if (info->flags&BDIF_KEY_SELECTION)
						{
							// See if current selection is still valid
							if ((object=find_backdrop_object(info,info->current_sel_object)))
							{
								// Clear selection flag and redraw
								object->flags&=~BDOF_SELECTED;
								backdrop_render_object(info,object,BRENDERF_CLIP);
							}

							// Clear selection pointer
							info->current_sel_object=0;
							info->flags&=~BDIF_KEY_SELECTION;
						}

						// Turn on
						else
						{
							// Sort objects into position order
							backdrop_sort_objects(info,0,0);

							// Get first object
							object=(BackdropObject *)info->objects.list.lh_Head;
							if (object->node.ln_Succ)
							{
								// Set selection flag in new object and render
								object->flags|=BDOF_SELECTED;
								backdrop_render_object(info,object,BRENDERF_CLIP);

								// Store object pointer
								info->current_sel_object=object;
								info->flags|=BDIF_KEY_SELECTION;
							}
						}

						// Unlock backdrop list
						unlock_listlock(&info->objects);
						handled=1;
					}
					break;


				// Cursor keys changes selection
				case CURSORUP:
				case CURSORDOWN:
				case CURSORLEFT:
				case CURSORRIGHT:

					// In selection mode?
					if (!busy && info->flags&BDIF_KEY_SELECTION)
					{
						BackdropObject *object=0,*lastobject;
						short horiz=0;

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

						// Horizontal movement?
						if (msg->Code==CURSORLEFT || msg->Code==CURSORRIGHT) horiz=BSORT_HORIZ;

						// Need to resort?
						if ((horiz && !(info->flags&BDIF_LAST_SORT_HORIZ)) ||
							(!horiz && info->flags&BDIF_LAST_SORT_HORIZ))
						{
							// Sort objects into position order
							backdrop_sort_objects(info,horiz,0);
						}

						// See if current selection is still valid
						if ((lastobject=find_backdrop_object(info,info->current_sel_object)))
						{
							// Down or right, get next object
							if (msg->Code==CURSORDOWN || msg->Code==CURSORRIGHT)
								object=(BackdropObject *)lastobject->node.ln_Succ;

							// Up or left, get previous object
							else
								object=(BackdropObject *)lastobject->node.ln_Pred;
						}

						// Invalid object?
						if (!object || !object->node.ln_Succ || !object->node.ln_Pred)
						{
							// Get first (or last) selection
							if (object && !object->node.ln_Pred)
								object=(BackdropObject *)info->objects.list.lh_TailPred;
							else object=(BackdropObject *)info->objects.list.lh_Head;
						}

						// New object different from last?
						if (object!=info->current_sel_object)
						{
							// Was there an old selection?
							if (lastobject)
							{
								// Clear selection flag and redraw
								lastobject->flags&=~BDOF_SELECTED;
								backdrop_render_object(info,lastobject,BRENDERF_CLIP);
							}

							// New valid object?
							if (object)
							{
								// Make sure object is visible
								backdrop_make_visible(info,object);

								// Set selection flag in new object and render
								object->flags|=BDOF_SELECTED;
								backdrop_render_object(info,object,BRENDERF_CLIP);
							}

							// Store object pointer
							info->current_sel_object=object;
						}

						// Unlock backdrop list
						unlock_listlock(&info->objects);
						handled=1;
					}
					break;


				// Return opens an icon
				case 0x44:

					// In selection mode?
					if (!busy && info->flags&BDIF_KEY_SELECTION)
					{
						BackdropObject *object;

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

						// See if current selection is still valid
						if ((object=find_backdrop_object(info,info->current_sel_object)))
						{
							// Open object
							info->last_sel_object=object;
							backdrop_object_open(info,object,msg->Qualifier,1,0,0);

							// Clear selection pointers
							info->current_sel_object=0;
							info->last_sel_object=0;
							info->flags&=~BDIF_KEY_SELECTION;

							// Deselect object
							object->flags&=~BDOF_SELECTED;
							backdrop_render_object(info,object,BRENDERF_CLIP);
						}

						// Unlock backdrop list
						unlock_listlock(&info->objects);
						handled=1;
					}
					break;


				// Page up/Page down
				case PAGEUP:
				case PAGEDOWN:
					{
						ULONG oldpos,pos;
						long newpos,diff;

						// Get old position
						GetAttr(PGA_Top,info->vert_scroller,&oldpos);

						// Get new position
						newpos=info->offset_y-info->area.MinY;
						if (msg->Code==PAGEUP) newpos-=(info->size.MaxY-info->size.MinY)+1;
						else newpos+=(info->size.MaxY-info->size.MinY)+1;
						if (newpos<0) newpos=0;

						// Update gadget
						SetGadgetAttrs(info->vert_scroller,info->window,0,
							PGA_Top,newpos,
							TAG_END);

						// Get new position
						GetAttr(PGA_Top,info->vert_scroller,&pos);

						// Change?
						diff=oldpos-pos;
						if (diff<0) diff=-diff;
						if (diff>2)
						{
							// Update screen
							backdrop_pos_slider(info,SLIDER_VERT);
						}
						handled=1;
					}
					break;


				// Home/End
				case HOME:
				case END:
					{
						ULONG oldpos,pos;
						long diff;

						// Get old position
						GetAttr(PGA_Top,info->horiz_scroller,&oldpos);

						// Update gadget
						SetGadgetAttrs(info->horiz_scroller,info->window,0,
							PGA_Top,(msg->Code==HOME)?0:0xfffffff,
							TAG_END);

						// Get new position
						GetAttr(PGA_Top,info->horiz_scroller,&pos);

						// Change?
						diff=oldpos-pos;
						if (diff<0) diff=-diff;
						if (diff>2)
						{
							// Update screen
							backdrop_pos_slider(info,SLIDER_HORZ);
						}
						handled=1;
					}
					break;
			}
			break;


		// Not handled
		default:
			handled=0;
			break;
	}

	return handled;
}
Ejemplo n.º 24
0
// Searches for an empty buffer, or one with the same name (preferred)
// If a suitable buffer is not found, it uses the current buffer
// Called from the LISTER PROCESS
DirBuffer *lister_buffer_find_empty(Lister *lister,char *path,struct DateStamp *stamp)
{
	DirBuffer *buffer,*first_empty=0,*first_unlocked=0;

#ifdef DEBUG
	if (lister) check_call("lister_buffer_find_empty",lister);
#endif

	// Check we're not showing special
	check_special_buffer(lister,1);

	// If current buffer is empty, use that one
	if (!(lister->cur_buffer->flags&DWF_VALID))
	{
		// Lock buffer
		buffer_lock(lister->cur_buffer,TRUE);

		// Free buffer
		buffer_freedir(lister->cur_buffer,1);

		// Unlock it
		buffer_unlock(lister->cur_buffer);
		return lister->cur_buffer;
	}

	// Lock buffer list
	lock_listlock(&GUI->buffer_list,TRUE);

	// Go through buffers in this list (backwards)
	for (buffer=(DirBuffer *)GUI->buffer_list.list.lh_TailPred;
		buffer->node.ln_Pred;
		buffer=(DirBuffer *)buffer->node.ln_Pred)
	{
		// See if this directory is available and matches our path
		if (path && stricmp(buffer->buf_Path,path)==0 &&
			(!stamp || CompareDates(&buffer->buf_VolumeDate,stamp)==0))
		{
			// Not locked, or in use by this lister?
			if (!buffer->buf_CurrentLister || buffer->buf_CurrentLister==lister)
			{
				// Store pointer
				first_empty=buffer;
				break;
			}
		}

		// If directory is empty, store pointer (if the first one)
		if (!buffer->buf_CurrentLister && !(buffer->flags&DWF_VALID) && !first_empty)
			first_empty=buffer;

		// First unlocked buffer?
		if (!buffer->buf_CurrentLister && !first_unlocked)
		{
			// Because buffers are moved to the head of the list whenever
			// they are accessed, this will point to the unlocked buffer
			// that was accessed the longest time ago
			first_unlocked=buffer;
		}
	}

	// If we found an empty one, use that one
	if (!(buffer=first_empty))
	{
		// Allocate a new buffer if we're allowed to
		if (GUI->buffer_count<environment->env->settings.max_buffer_count &&
			!(environment->env->settings.dir_flags&DIRFLAGS_DISABLE_CACHING))
		{
			// If this fails, use first unlocked
			buffer=lister_new_buffer(lister);
		}
	}

	// If nothing yet, use first unlocked buffer (if there is one)
	if (!buffer && !(buffer=first_unlocked))
	{
		// If not, re-use current buffer
		buffer=lister->cur_buffer;
	}

	// Lock buffer
	buffer_lock(buffer,TRUE);

	// Free buffer
	buffer_freedir(buffer,1);

	// Unlock buffer
	buffer_unlock(buffer);

	// Show buffer in lister
	lister_show_buffer(lister,buffer,0,1);

	// Unlock buffer list
	unlock_listlock(&GUI->buffer_list);

	// Return current buffer
	return lister->cur_buffer;
}
Ejemplo n.º 25
0
// Initialise backdrop info
void backdrop_init_info(
	BackdropInfo *info,
	struct Window *window,
	short no_icons)
{
	// Backdrop window pointer
	info->window=window;

	// Initialise size
	info->size.MinX=window->BorderLeft+info->left_border;
	info->size.MinY=window->BorderTop+info->top_border;
	info->size.MaxX=window->Width-window->BorderRight-info->right_border-1;
	info->size.MaxY=window->Height-window->BorderBottom-info->bottom_border-1;

	// Not re-initialising?
	if (no_icons!=-1)
	{
		BackdropObject *icon;

		// Clone rastport
		info->rp=*window->RPort;

		// Get font
		backdrop_get_font(info);

		// If not backdrop window, add scroll bars
		if (!(window->Flags&WFLG_BACKDROP))
		{
			// Create scroll bars
			if (AddScrollBars(window,&info->boopsi_list,GUI->draw_info,SCROLL_VERT|SCROLL_HORIZ|SCROLL_NOIDCMP))
			{
				// Get scrollers
				info->vert_scroller=FindBOOPSIGadget(&info->boopsi_list,GAD_VERT_SCROLLER);
				info->horiz_scroller=FindBOOPSIGadget(&info->boopsi_list,GAD_HORIZ_SCROLLER);

				// Add to window
				AddGList(window,info->vert_scroller,-1,-1,0);
				RefreshGList(info->vert_scroller,window,0,-1);
			}
		}

		// Get clip region
		info->clip_region=NewRegion();
		info->temp_region=NewRegion();

		// Allocate notification port
		if (info->notify_port=CreateMsgPort())
		{
			// Add notify request
			info->notify_req=AddNotifyRequest(DN_WRITE_ICON,0,info->notify_port);
		}

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

		// Remap existing icons
		for (icon=(BackdropObject *)info->objects.list.lh_Head;
			icon->node.ln_Succ;
			icon=(BackdropObject *)icon->node.ln_Succ)
		{
			// Remap the icon
			if (RemapIcon(icon->icon,info->window->WScreen,0))
			{
				// Had icon never been remapped before?
				if (!(icon->flags&BDOF_REMAPPED))
				{
					// Get new object size, etc
					backdrop_get_icon(info,icon,GETICON_KEEP|GETICON_POS_ONLY|GETICON_SAVE_POS|GETICON_REMAP);

					// Get new masks
					backdrop_get_masks(icon);
				}
			}
			
			// Set flag to say we've been remapped
			icon->flags|=BDOF_REMAPPED;
		}

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

	// Install clip
	if (info->clip_region)
		backdrop_install_clip(info);
}
Ejemplo n.º 26
0
// Run a function on some icons
void icon_function(BackdropInfo *info,BackdropObject *only_one,char *data,Cfg_Function *func,ULONG flags)
{
	short count=0;
	struct ArgArray *array;
	BackdropObject *object;
	DirBuffer *buffer=0;
	char *source_path=0;

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

	// Go through backdrop list
	for (object=(BackdropObject *)info->objects.list.lh_Head;
		object->node.ln_Succ;
		object=(BackdropObject *)object->node.ln_Succ)
	{
		// Skip invalid icons
		if (object->type!=BDO_LEFT_OUT ||
			(!info->lister && !(object->flags&BDOF_DESKTOP_FOLDER))) continue;

		// Want this icon?
		if (!only_one || only_one==object)
		{
			// Is object selected?
			if ((only_one || object->state) && object->icon)
			{
				// Increment counts
				if (object->icon->do_Type==WBDRAWER ||
					object->icon->do_Type==WBGARBAGE ||
					object->icon->do_Type==WBPROJECT ||
					object->icon->do_Type==WBTOOL)
					++count;

				// Only doing one?
				if (only_one) break;
			}
		}
	}

	// Nothing to work on?
	if (count==0 ||
		!(array=NewArgArray()))
	{
		unlock_listlock(&info->objects);
		return;
	}

	// Got a lister?
	if (info->lister)
	{
		// Lock buffer
		buffer_lock((buffer=info->lister->cur_buffer),FALSE);
	}

	// Source path from icon?
	else
	if (only_one && only_one->path &&
		(source_path=AllocVec(strlen(only_one->path)+1,0)))
		strcpy(source_path,only_one->path);

	// Otherwise, assume this is the desktop folder
	else
	if (info->flags&BDIF_MAIN_DESKTOP &&
		(source_path=AllocVec(strlen(environment->env->desktop_location)+1,0)))
		strcpy(source_path,environment->env->desktop_location);

	// Go through backdrop list again
	for (object=(BackdropObject *)info->objects.list.lh_Head;
		object->node.ln_Succ;
		object=(BackdropObject *)object->node.ln_Succ)
	{
		// Skip invalid icons
		if (object->type!=BDO_LEFT_OUT ||
			(!info->lister && !(object->flags&BDOF_DESKTOP_FOLDER))) continue;

		// Want this icon?
		if (!only_one || only_one==object)
		{
			// Is object selected?
			if ((only_one || object->state) && object->icon)
			{
				char name[80];
				BOOL dir=0,link=0,icon=0;
				DirEntry *entry=0;
				struct ArgArrayEntry *aae;

				// Build name
				stccpy(name,object->name,sizeof(name));

				// Got a buffer?
				if (buffer)
				{
					// See if we can find this entry
					if ((entry=find_entry(&buffer->entry_list,object->name,0,buffer->more_flags&DWF_CASE)) ||
						(entry=find_entry(&buffer->reject_list,object->name,0,buffer->more_flags&DWF_CASE)))
					{
						// Directory?
						if (entry->de_Node.dn_Type>=ENTRY_DEVICE) dir=1;

						// Link?
						if (entry->de_Flags&ENTF_LINK) link=1;

						// See if entry has icon
						if (find_entry(&buffer->entry_list,object->name,0,(buffer->more_flags&DWF_CASE)|FINDENTRY_ICON) ||
							find_entry(&buffer->reject_list,object->name,0,(buffer->more_flags&DWF_CASE)|FINDENTRY_ICON))
							icon=1;
					}

					// If not, use the .info name
					else
					{
						// Add .info
						strcat(name,".info");
					}
				}

				// Desktop folder?
				else
				if (info->flags&BDIF_MAIN_DESKTOP)
				{
					// Assume the file has an icon
					icon=1;
				}

				// Get type from icon
				if (!entry)
				{
					if (object->icon->do_Type==WBDRAWER ||
						object->icon->do_Type==WBGARBAGE) dir=1;
					if (object->flags&BDOF_LINK_ICON) link=1;
				}

				// Tack on a / for directories
				if (dir) strcat(name,"/");

				// Allocate array entry
				if (aae=NewArgArrayEntry(array,name))
				{
					// Dir?
					if (dir) aae->ae_Flags|=AEF_DIR;

					// Link?
					if (link) aae->ae_Flags|=AEF_LINK;

					// No icon?
					if (!icon) aae->ae_Flags|=AEF_FAKE_ICON;
				}

				// Only doing one?
				if (only_one) break;
			}
		}
	}

	// Unlock buffer
	if (buffer) buffer_unlock(buffer);

	// Get flags we need
	flags|=(data && *data)?FUNCF_ICONS:FUNCF_ICONS|FUNCF_ASK_DEST;

	// Launch the function
	function_launch(
		FUNCTION_RUN_FUNCTION_EXTERNAL,
		func,
		0,
		flags,
		info->lister,0,
		(info->lister)?info->lister->cur_buffer->buf_Path:source_path,data,
		array,
		0,0);

	// Free source path
	FreeVec(source_path);

	// Unlock list
	unlock_listlock(&info->objects);
}
Ejemplo n.º 27
0
// Open a group
void backdrop_open_group(BackdropInfo *info,BackdropObject *object,BOOL activate)
{
	GroupData *group;
	IPCData *ipc=0;

	// Valid object?
	if (!object || !object->icon || object->icon->do_Type!=WBDRAWER) return;

	// See if it's already open
	lock_listlock(&GUI->group_list,0);
	if (group=backdrop_find_group(object))
	{
		// Send activate message
		if (activate) IPC_Command(group->ipc,IPC_ACTIVATE,0,0,0,0);
	}
	unlock_listlock(&GUI->group_list);

	// If it was open, return
	if (group) return;

	// Allocate group packet
	if (!(group=AllocVec(sizeof(GroupData),MEMF_CLEAR)))
		return;

	// Fill in group packet
	group->screen=info->window->WScreen;
	if (object->icon->do_DrawerData)
		group->dimensions=*((struct IBox *)&object->icon->do_DrawerData->dd_NewWindow.LeftEdge);
	else
	{
		group->dimensions.Left=20;
		group->dimensions.Top=20;
		group->dimensions.Width=200;
		group->dimensions.Height=150;
	}
	strcpy(group->name,object->name);
	group->object=object;

	// Initialise popup menu
	if (group->popup=PopUpNewHandle(0,0,&locale))
	{
		// Add items
		PopUpNewItem(group->popup,MSG_ICON_SNAPSHOT_MENU,MENU_ICON_SNAPSHOT_WINDOW,0);
		PopUpNewItem(group->popup,MSG_ICON_CLEANUP,MENU_ICON_CLEANUP,0);
	}

	// Launch process
	IPC_Launch(
		&GUI->group_list,
		&ipc,
		"dopus_group",
		(ULONG)backdrop_group_handler,
		STACK_DEFAULT,
		(ULONG)group,(struct Library *)DOSBase);

	// Failed?
	if (!ipc)
	{
		// Free
		PopUpFreeHandle(group->popup);
		FreeVec(group);
	}
}
Ejemplo n.º 28
0
// Show the backdrop objects
void backdrop_show_objects(BackdropInfo *info,UWORD flags)
{
	BackdropObject *object;

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

	// Lock window
	GetSemaphore(&info->window_lock,SEMF_EXCLUSIVE,0);

	// Window open?
	if (info->window)
	{
		// Are we in a refresh?
		if (flags&BDSF_IN_REFRESH)
		{
			// Lock layers
#ifdef LOCKLAYER_OK
			LockScreenLayer(info->window->WScreen);
#else
			Forbid();
#endif

			// End refresh temporarily
			EndRefresh(info->window,FALSE);

			// Install new clip region if we have it
			if (info->clip_region)
				InstallClipRegion(info->window->WLayer,info->clip_region);

			// Continue refresh
			BeginRefresh(info->window);
		}

		// Or, are we meant to be refreshing?
		else
		if (flags&BDSF_REFRESH)
		{
			// Start refresh here?
			if ((flags&BDSF_REFRESH_DONE)==BDSF_REFRESH_DONE)
			{
				// Lock layers
#ifdef LOCKLAYER_OK
				LockScreenLayer(info->window->WScreen);
#else
				Forbid();
#endif
			}

			// And our region with damagelist
			if (info->clip_region)
				AndRegionRegion(info->clip_region,info->window->WLayer->DamageList);

			// Begin the refresh
			BeginRefresh(info->window);
		}

		// Install clip region if we have it
		else
		if (!(flags&BDSF_NO_CLIP) && info->clip_region)
			InstallClipRegion(info->window->WLayer,info->clip_region);

		// Clear backdrop window
		if (flags&BDSF_CLEAR)
		{
			EraseRect(&info->rp,
				info->size.MinX,
				info->size.MinY,
				info->size.MaxX,
				info->size.MaxY);
		}

		// Not just clearing?
		if ((flags&BDSF_CLEAR_ONLY)!=BDSF_CLEAR_ONLY)
		{
			// Go through backdrop list (backwards)
			for (object=(BackdropObject *)info->objects.list.lh_TailPred;
				object->node.ln_Pred;
				object=(BackdropObject *)object->node.ln_Pred)
			{
				// Reset?
				if (flags&BDSF_RESET)
				{
					// Need to get masks?
					if (!backdrop_icon_border(object) &&
						!object->image_mask[0])
					{
						// Get masks for this icon
						backdrop_get_masks(object);
					}
				}

				// Valid position?
				if (!(object->flags&BDOF_NO_POSITION))
				{
					// Render this object
					backdrop_draw_object(
						info,
						object,
						BRENDERF_REAL,
						&info->rp,
						object->pos.Left,
						object->pos.Top);
				}
			}
		}

		// Refresh?
		if (flags&BDSF_REFRESH)
		{
			EndRefresh(info->window,((flags&BDSF_REFRESH_DONE)==BDSF_REFRESH_DONE)?TRUE:FALSE);

			// End refresh here?
			if ((flags&BDSF_REFRESH_DONE)==BDSF_REFRESH_DONE)
			{
				// Unlock layers
#ifdef LOCKLAYER_OK
				UnlockScreenLayer(info->window->WScreen);
#else
				Permit();
#endif
			}
		}

		// In refresh?
		else
		if (flags&BDSF_IN_REFRESH)
		{
			// End refresh temporarily
			EndRefresh(info->window,FALSE);

			// Remove clip region
			if (info->clip_region)
				InstallClipRegion(info->window->WLayer,0);

			// Continue refresh
			BeginRefresh(info->window);

			// Unlock layers
#ifdef LOCKLAYER_OK
			UnlockScreenLayer(info->window->WScreen);
#else
			Permit();
#endif
		}

		// Remove clip region
		else
		if (!(flags&BDSF_NO_CLIP) && info->clip_region)
			InstallClipRegion(info->window->WLayer,0);

		// Update virtual size
		if (flags&BDSF_RECALC) backdrop_calc_virtual(info);
	}

	// Unlock window
	FreeSemaphore(&info->window_lock);

	// Unlock backdrop list
	unlock_listlock(&info->objects);
}
Ejemplo n.º 29
0
void file_open_with(struct Window *window,char *name,ULONG flags)
{
	char *buffer;
	short len,wb=0,ok=0;
	struct DiskObject *icon;

	// Allocate buffer
	if (!(buffer=AllocVec(1400,MEMF_CLEAR)))
		return;

	// App already selected?
	if (flags&(1<<30))
	{
		short num;
		struct Node *node;

		// Get application number in list
		num=flags&~(1<<30);

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

		// Find the node
		for (node=GUI->open_with_list.list.lh_Head;
			node->ln_Succ;
			node=node->ln_Succ)
		{
			// Matched?
			if (num--==0) break;
		}

		// Valid node?
		if (node->ln_Succ)
		{
			// Get the application name
			strcpy(buffer+1,node->ln_Name);
			ok=1;
		}

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

	// Need to ask?
	if (!ok)
	{
		// Build title
		lsprintf(buffer+1024,GetString(&locale,MSG_SELECT_APP),FilePart(name));

		// Ask for file
		if (!(request_file(
			window,
			buffer+1024,
			buffer+1,
			0,
			0,0)) || !*(buffer+1))
		{
			FreeVec(buffer);
			return;
		}

		// Add App to OpenWith list
		add_open_with(buffer+1);
	}

	// See if app has an icon
	if (icon=GetDiskObject(buffer+1))
	{
		// Is it a tool?
		if (icon->do_Type==WBTOOL)
		{
			// Launch as Workbench App
			wb=1;
		}

		// Free icon
		FreeDiskObject(icon);
	}

	// Fill in quotes
	buffer[0]='\"';
	buffer[(len=strlen(buffer))]='\"';

	// Add filename in quotes
	buffer[len+1]=' ';
	buffer[len+2]='\"';
	strcpy(buffer+len+3,name);
	buffer[(len=strlen(buffer))]='\"';
	buffer[len+1]=0;

	// Launch the function
	file_launch(buffer,wb,"ram:");

	// Free buffer
	FreeVec(buffer);
}
Ejemplo n.º 30
0
// Group handler
void __saveds backdrop_group_handler(void)
{
	IPCData *ipc;
	GroupData *group=0;

	// Do group
	if (ipc=IPC_ProcStartup((ULONG *)&group,backdrop_group_init))
	{
		// Read objects
		SetBusyPointer(group->window);
		backdrop_read_group_objects(group);
		ClearPointer(group->window);

		// Event loop
		FOREVER
		{
			IPCMessage *msg;
			BOOL quit_flag=0;

			// Got an AppWindow?
			if (group->appwindow)
			{
				DOpusAppMessage *amsg;
				BOOL beep=0;

				// AppMessages?
				while (amsg=(DOpusAppMessage *)GetMsg(group->appport))
				{
					short arg;
					char path[256];
					BackdropObject *drop_obj;

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

					// Set busy pointer
					if (group->window) SetBusyPointer(group->window);

					// Dropped on an object?
					if (drop_obj=backdrop_get_object(group->info,amsg->da_Msg.am_MouseX,amsg->da_Msg.am_MouseY,0))
					{
						USHORT qual;

						// Get qualifiers
						qual=(InputBase)?PeekQualifier():0;
	
						// Is shift/alt down?
						if (qual&(IEQUALIFIER_LSHIFT|IEQUALIFIER_LALT)==(IEQUALIFIER_LSHIFT|IEQUALIFIER_LALT))
						{
							// Get path of first file
							GetWBArgPath(&amsg->da_Msg.am_ArgList[0],path,256);

							// Replace the image
							backdrop_replace_icon_image(group->info,path,drop_obj);
						}

						// Run program with args
						else
						backdrop_object_open(
							group->info,
							drop_obj,
							0,
							0,
							amsg->da_Msg.am_NumArgs,
							amsg->da_Msg.am_ArgList);
					}

					// Otherwise, adding objects to the group
					else
					for (arg=0;arg<amsg->da_Msg.am_NumArgs;arg++)
					{
						// Valid name?
						if (*amsg->da_Msg.am_ArgList[arg].wa_Name)
						{
							short x,y;

							// Get full path name
							GetWBArgPath(&amsg->da_Msg.am_ArgList[arg],path,256);

							// Default to no position
							x=-1;
							y=-1;

							// Dopus app message?
							if (CheckAppMessage(amsg))
							{
								// Get icon position
								x=amsg->da_DragOffset.x+amsg->da_Msg.am_MouseX+amsg->da_DropPos[arg].x;
								y=amsg->da_DragOffset.y+amsg->da_Msg.am_MouseY+amsg->da_DropPos[arg].y;
							}

							// Add group object
							backdrop_group_add_object(group->name,group->info,path,x,y);
						}

						// Otherwise, set beep flag for error
						else
						if (!beep)
						{
							beep=1;
							DisplayBeep(group->window->WScreen);
						}
					}

					// Clear busy pointer
					if (group->window) ClearPointer(group->window);

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

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

			// Icon notification
			if (group->info->notify_req)
			{
				DOpusNotify *notify;

				// Get notify message	
				if (notify=(DOpusNotify *)GetMsg(group->info->notify_port))
					backdrop_check_notify(group->info,notify,0);
			}

			// IPC messages?
			while (msg=(IPCMessage *)GetMsg(ipc->command_port))
			{
				// Look at message
				switch (msg->command)
				{
					// Activate
					case IPC_ACTIVATE:

						// Bring window to front
						if (group->window)
							backdrop_show_group(group);
						break;


					// Quit
					case IPC_QUIT:
						quit_flag=1;
						group->got_quit=1;
						break;


					// Hide
					case IPC_HIDE:
						backdrop_hide_group(group);
						break;


					// Show
					case IPC_SHOW:
						group->screen=(struct Screen *)msg->data;
						backdrop_show_group(group);
						break;


					// Reset (menus)
					case IPC_RESET:

						// Gotta window?
						if (group->window)
						{
							// Reset menus?
							if (msg->flags)
							{
								display_free_menu(group->window);
								display_get_menu(group->window);
							}

							// Fix menus
							display_fix_menu(group->window,WINDOW_GROUP,0);
						}
						break;


					// New font
					case GROUP_NEW_FONT:

						// Get new font
						backdrop_get_font(group->info);

						// Redraw objects
						backdrop_show_objects(group->info,BDSF_CLEAR|BDSF_RESET);
						break;


					// New name
					case GROUP_NEW_NAME:

						// Copy name
						strcpy(group->name,msg->data_free);

						// Update window title
						if (group->window) SetWindowTitles(group->window,group->name,(char *)-1);
						break;


					// Add a new icon
					case GROUP_ADD_ICON:

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

						// Set busy pointer
						if (group->window) SetBusyPointer(group->window);

						// Add object
						backdrop_group_add_object(group->name,group->info,msg->data_free,-1,-1);

						// Clear busy pointer
						if (group->window) ClearPointer(group->window);

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


					// New backfill pattern
					case LISTER_BACKFILL_CHANGE:

						// Window open?
						if (group->window)
						{
							// Install appropriate hook
							InstallLayerHook(
								group->window->WLayer,
								(msg->flags)?&group->pattern.hook:LAYERS_BACKFILL);

							// Redraw window
							erase_window(group->window);

							// Redraw icons
							backdrop_show_objects(group->info,0);
						}
						break;


					// Delete from group
					case GROUP_DELETE:
						SetBusyPointer(group->window);
						backdrop_remove_group_objects(group,(BackdropObject *)msg->data);
						ClearPointer(group->window);
						break;


					// Help
					case IPC_HELP:

						// Show help for group
						help_show_help(HELP_PROGRAM_GROUP,0);
						break;


					// Do a function
					case LISTER_DO_FUNCTION:

						// Arrange icons?
						if (msg->data>=(APTR)MENU_LISTER_ARRANGE_NAME &&
							msg->data<=(APTR)MENU_LISTER_ARRANGE_SIZE)
						{
							// Do cleanup
							backdrop_cleanup(group->info,BSORT_NAME+(((ULONG)msg->data)-MENU_LISTER_ARRANGE_NAME),0);
						}
						break;
				}

				// Reply to message
				IPC_Reply(msg);
			}

			// Is window open?
			if (group->window)
			{
				struct IntuiMessage *imsg;

				// Check timer
				if (CheckTimer(group->timer))
				{
					// Dragging something?
					if (group->info->flags&BDIF_DRAGGING)
					{
						// Check for deadlocks
						if (group->info->last_tick==group->info->tick_count)
						{
							// Stop drag
							backdrop_stop_drag(group->info);
						}

						// Remember tick count
						group->info->last_tick=group->info->tick_count;
					}

					// Re-start timer
					StartTimer(group->timer,0,500000);
				}

				// Window messages
				while (imsg=(struct IntuiMessage *)GetMsg(group->window->UserPort))
				{
					struct IntuiMessage msg_copy;
					struct MenuItem *item;

					// Copy message
					msg_copy=*imsg;

					// Menu verify?
					if (imsg->Class==IDCMP_MENUVERIFY)
					{
						// See if we want to swallow it
						if (!backdrop_test_rmb(group->info,imsg,&msg_copy,TRUE))
						{
							// Did event happen over the window?
							if (imsg->MouseX>=0 &&
								imsg->MouseY>=0 &&
								imsg->MouseX<group->window->Width &&
								imsg->MouseY<group->window->Height &&
								imsg->Qualifier&IEQUALIFIER_RBUTTON)
							{
								// Cancel menu event
								imsg->Code=MENUCANCEL;

								// Change our copy to MOUSEBUTTONS
								msg_copy.Class=IDCMP_MOUSEBUTTONS;
								msg_copy.Code=MENUDOWN;

								// Kludge for MagicMenu
								if (msg_copy.Seconds==0)
									CurrentTime(&msg_copy.Seconds,&msg_copy.Micros);
							}
						}
					}

					// Resize/refresh?
					if (imsg->Class==IDCMP_NEWSIZE ||
						imsg->Class==IDCMP_REFRESHWINDOW)
					{
						// Handle message
						backdrop_idcmp(group->info,imsg,0);

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

					// Reply to message
					ReplyMsg((struct Message *)imsg);

					// Is it a backdrop message?
					if (backdrop_idcmp(group->info,&msg_copy,0))
						continue;

					// Look at message class
					switch (msg_copy.Class)
					{
						// Window closed
						case IDCMP_CLOSEWINDOW:
							quit_flag=1;
							break;


						// Window is inactive
						case IDCMP_INACTIVEWINDOW:

							// Abort timer if running
							StopTimer(group->timer);
							break;


						// Window is active
						case IDCMP_ACTIVEWINDOW:

							// Start timer if not running
							StartTimer(group->timer,1,0);
							break;


						// Key press
						case IDCMP_RAWKEY:

							// Help?
							if (msg_copy.Code==0x5f &&
								!(msg_copy.Qualifier&VALID_QUALIFIERS))	
							{
								help_get_help(
									msg_copy.MouseX+group->window->LeftEdge,
									msg_copy.MouseY+group->window->TopEdge,
									msg_copy.Qualifier);
							}

							// Close?
							else
							if (msg_copy.Code==0x45 &&
								msg_copy.Qualifier&IEQUAL_ANYSHIFT) quit_flag=1;
							break;


						// Button pressed
						case IDCMP_MOUSEBUTTONS:

							// Right button?
							if (msg_copy.Code==MENUDOWN)
							{
								USHORT res;

								// Do popup menu
								if (group->popup &&
									(res=DoPopUpMenu(group->window,&group->popup->ph_Menu,NULL,MENUDOWN))!=(USHORT)-1)
								{
									// Help?
									if (res&POPUP_HELPFLAG)
									{
										// Get help ID
										res&=~POPUP_HELPFLAG;

										// Do help
										help_menu_help(res,0);
										break;
									}

									// Do the function
									quit_flag=backdrop_group_do_function(group,res,0);
								}
							}
							break;


						// Menu event
						case IDCMP_MENUPICK:
						case IDCMP_MENUHELP:
							{
								struct Menu *oldstrip=group->window->MenuStrip;
								USHORT nextselect;

								// Get item
								nextselect=msg_copy.Code;
								while (item=ItemAddress(group->window->MenuStrip,nextselect))
								{
									// get next
									nextselect=item->NextSelect;

									// Help?
									if (msg_copy.Class==IDCMP_MENUHELP)
									{
										help_menu_help((long)GTMENUITEM_USERDATA(item),0);
										break;
									}

									// Do the function
									quit_flag=backdrop_group_do_function(group,(ULONG)GTMENUITEM_USERDATA(item),item);

									// Check valid next
									if (!nextselect || !group->window || oldstrip!=group->window->MenuStrip)
										break;
								}
							}
							break;
					}
				}
			}

			// Check quit flag
			if (quit_flag) break;

			// Wait for event
			Wait(	1<<ipc->command_port->mp_SigBit|
					1<<group->timer->port->mp_SigBit|
					((group->info->notify_req)?(1<<group->info->notify_port->mp_SigBit):0)|
					((group->window)?(1<<group->window->UserPort->mp_SigBit):0)|
					((group->appwindow)?(1<<group->appport->mp_SigBit):0));
		}

		// Close window
		backdrop_free_group(group);

		// Send goodbye
		IPC_Goodbye(ipc,&main_ipc,0);
	}