コード例 #1
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;
}
コード例 #2
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);
	}
コード例 #3
0
// Start dragging
BOOL backdrop_start_drag(BackdropInfo *info,short x,short y)
{
	BackdropObject *object;

	// Set drag flag
	info->flags|=BDIF_DRAGGING;

	// Copy RastPort and initialise GELs
	GUI->drag_screen_rp=GUI->screen_pointer->RastPort;
	GUI->drag_screen_rp.GelsInfo=&GUI->drag_info;
	InitGels(&GUI->drag_head,&GUI->drag_tail,&GUI->drag_info);

	// Custom dragging?
	if (DragCustomOk(GUI->drag_screen_rp.BitMap))
	{
		// Set custom flag
		info->flags|=BDIF_CUSTOM_DRAG;
	}

	// Normal dragging
	else info->flags&=~BDIF_CUSTOM_DRAG;

	// Reset saved coords
	info->last_x=x;
	info->last_y=y;

	// Stop menu actions, start mouse reporting
	info->window->Flags|=WFLG_RMBTRAP|WFLG_REPORTMOUSE;

	// Turn ticks on
	ModifyIDCMP(info->window,info->window->IDCMPFlags|IDCMP_INTUITICKS);
	info->tick_count=1;
	info->last_tick=0;

	// Get start time
	CurrentTime(&info->drag_sec,&info->drag_mic);

	// Last selected icon?
	if ((object=info->last_sel_object) && object->state)
	{
		// Check icon isn't locked
		if (object->flags&BDOF_LOCKED)
		{
			// Can't drag at all
			backdrop_stop_drag(info);
			return 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 selected?
		if (object->state)
		{
			// Check icon isn't locked
			if (object->flags&BDOF_LOCKED) continue;

			// Start dragging
			if (!(backdrop_drag_object(info,object)))
			{
				// Failed
				backdrop_stop_drag(info);
				return 0;
			}
		}
	}

	return 1;
}