/* * Block drivers call this function to signal completion of an I/O request. */ void block_request_completed(struct block_device *dev, struct request *req) { req->buf->b_flags |= BUF_UPTODATE; release_buffer(req->buf); buffer_unlock(req->buf); slab_free(request_cachep, req); if (request_queue_empty(dev)) return; req = list_first_entry(&dev->requests, struct request, chain); list_del(&req->chain); dev->handle_request(dev, req); }
// Handle a notify message void lister_handle_notify(Lister *lister,DOpusNotify *notify,char *name) { BOOL show=0; // Lock buffer buffer_lock(lister->cur_buffer,TRUE); // Create dir? if (notify->dn_Flags&DNF_DOS_CREATEDIR) { DirEntry *entry; BPTR lock; struct FileInfoBlock __aligned fib; // Lock directory if (lock=Lock(name,ACCESS_READ)) { // Examine it Examine(lock,&fib); UnLock(lock); // Create entry if (entry=create_file_entry( lister->cur_buffer,0, fib.fib_FileName, fib.fib_Size, fib.fib_DirEntryType, &fib.fib_Date, fib.fib_Comment, fib.fib_Protection, 0,0,0,0)) { // Add to buffer add_file_entry(lister->cur_buffer,entry,0); // Save date in buffer (assume this is the latest thing!) lister->cur_buffer->buf_DirectoryDate=fib.fib_Date; // Mark for refresh show=1; } } } // Unlock buffer buffer_unlock(lister->cur_buffer); // Refresh? if (show) lister_refresh_display(lister,REFRESHF_SLIDERS|REFRESHF_STATUS); }
// 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; }
// 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); }
// Sort selected entries to the top of the list void buffer_sort_selected(DirBuffer *buffer) { struct MinList temp; DirEntry *entry,*first_file=0,*first_pos=0; // Lock buffer buffer_lock(buffer,TRUE); // Initialise temporary list NewList((struct List *)&temp); // Go through entries for (entry=(DirEntry *)buffer->entry_list.mlh_Head; entry->de_Node.dn_Succ;) { DirEntry *next=(DirEntry *)entry->de_Node.dn_Succ; // File? if (ENTRYTYPE(entry->de_Node.dn_Type)==ENTRY_FILE) { // Remove and add to temporary if selected if (entry->de_Flags&ENTF_SELECTED) { // Remember first position if (!first_pos) first_pos=(DirEntry *)entry->de_Node.dn_Pred; // Remove and re-add Remove((struct Node *)entry); AddTail((struct List *)&temp,(struct Node *)entry); } // Remember if the first file else if (!first_file) first_file=entry; } // Get next entry=next; } // Something in the temporary list? if (!(IsListEmpty((struct List *)&temp))) { // If we have a first file, get its predecessor if (first_file) first_pos=(DirEntry *)first_file->de_Node.dn_Pred; // Go through temporary list, add after first position for (entry=(DirEntry *)temp.mlh_Head; entry->de_Node.dn_Succ;) { DirEntry *next=(DirEntry *)entry->de_Node.dn_Succ; // Remove and add after last one Remove((struct Node *)entry); Insert((struct List *)&buffer->entry_list,(struct Node *)entry,(struct Node *)first_pos); // Bump next position first_pos=(DirEntry *)entry; // Get next entry=next; } } // Unlock buffer buffer_unlock(buffer); }