// 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); }
// 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); }
// 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); }
// 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); }
// 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); }
// 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); }
// 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); } } } }
// 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; }
// 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); }
// 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); }
// 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; }
// 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); }
// 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); }
// 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); }
// 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); }
// 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; }
// 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); }
// 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; }
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); }
// 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; }
// 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); }
// 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; }
// 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; }
// 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; }
// 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); }
// 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); }
// 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); } }
// 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); }
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); }
// 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); }