// Change entry's path void config_paths_change(config_path_data *data) { char *str; BPTR lock; char path[256]; position_rec *pos; Att_Node *node; struct List *search; // No path selected? if (!data->path_sel) return; // Get path string str=(char *)GetGadgetValue(data->objlist,GAD_PATHFORMAT_PATH); // Invalid? if (!str || !*str) { // Remove this path config_paths_remove(data,TRUE); return; } // Try to lock if ((lock=Lock(str,ACCESS_READ))) { // Get full pathname NameFromLock(lock,path,256); UnLock(lock); } // Otherwise, use entered path else strcpy(path,str); // Fix path with trailing / AddPart(path,"",256); // See if path is already in edit list if ((node=(Att_Node *)FindNameI((struct List *)data->path_list,path))) { // Not the currently selected node? if (node!=data->path_sel) { // Error DisplayBeep(data->window->WScreen); ActivateStrGad(GADGET(GetObject(data->objlist,GAD_PATHFORMAT_PATH)),data->window); return; } } // Is path already in snapshot list? search=data->paths; while ((pos=(position_rec *)FindNameI(search,path))) { // Position entry? if (pos->node.ln_Type==PTYPE_POSITION) break; search=(struct List *)pos; } // Found it? if (pos) { // Different entry? if (pos!=(position_rec *)data->path_sel->data) { // Remove current entry from list Remove((struct Node *)data->path_sel->data); // Free current data FreeMemH((void *)data->path_sel->data); data->path_sel->data=(ULONG)pos; } // If path exists, clear "new" flag if (lock) pos->flags&=~POSITIONF_NEW; } // It is now else pos=(position_rec *)data->path_sel->data; // Set its user flag pos->flags|=POSITIONF_USER; // Store new name strcpy(pos->name,path); // Remove list from gadget SetGadgetChoices(data->objlist,GAD_PATHFORMAT_PATHS,(APTR)~0); // Remove existing node and add new one Att_RemNode(data->path_sel); // Add to list data->path_sel=Att_NewNode(data->path_list,pos->node.ln_Name,(ULONG)pos,ADDNODE_SORT); // Attach list to gadget SetGadgetChoices(data->objlist,GAD_PATHFORMAT_PATHS,data->path_list); // Select the new node config_paths_select(data,data->path_sel,TRUE); }
int LIBFUNC L_Module_Entry( REG(a0, struct List *files), REG(a1, struct Screen *screen), REG(a2, IPCData *ipc), REG(a3, IPCData *main_ipc), REG(d0, ULONG mod_id), REG(d1, ULONG mod_data)) { config_path_data *data; short success=1; // Allocate data if (!(data=AllocVec(sizeof(config_path_data),MEMF_CLEAR)) || !(data->path_list=Att_NewList(0))) { FreeVec(data); return 0; } // Store data pointers data->paths=files; data->ipc=ipc; data->main_ipc=main_ipc; data->memory=(APTR)mod_id; data->def_format=(ListFormat *)mod_data; // AppPort data->appport=CreateMsgPort(); // Open commodities library /*data->cxbase=OpenLibrary("commodities.library",0); #ifdef __amigaos4__ ICommodities=(struct CommoditiesIFace *)GetInterface(data->cxbase,"main",1,NULL); #endif */ // Build path list config_paths_build_list(data); // Open window if (!(config_paths_open(data,screen))) return 0; // Event loop FOREVER { IPCMessage *imsg; struct IntuiMessage *msg; int quit_flag=0; // IPC messages? while ((imsg=(IPCMessage *)GetMsg(ipc->command_port))) { // Quit? if (imsg->command==IPC_QUIT) { quit_flag=1; success=0; } // Hide? else if (imsg->command==IPC_HIDE) { RemoveAppWindow(data->appwindow); data->appwindow=0; CloseConfigWindow(data->window); data->window=0; } // Show? else if (imsg->command==IPC_SHOW) { if (!(config_paths_open(data,imsg->data))) { quit_flag=1; success=0; } } // Activate else if (imsg->command==IPC_ACTIVATE) { if (data->window) { WindowToFront(data->window); ActivateWindow(data->window); } } // Reply IPC_Reply(imsg); } // Any messages to the window? if (data->window) { while ((msg=GetWindowMsg(data->window->UserPort))) { struct IntuiMessage msg_copy; UWORD gadgetid; // Copy message and reply msg_copy=*msg; ReplyWindowMsg(msg); // Look at message switch (msg_copy.Class) { // Close window case IDCMP_CLOSEWINDOW: quit_flag=1; success=0; break; // Gadget case IDCMP_GADGETUP: case IDCMP_GADGETDOWN: // Get GadgetID gadgetid=((struct Gadget *)msg_copy.IAddress)->GadgetID; // Look at gadget switch (gadgetid) { // Cancel case GAD_PATHFORMAT_CANCEL: success=0; // Use case GAD_PATHFORMAT_SAVE: quit_flag=1; break; // Add an entry case GAD_PATHFORMAT_ADD: config_paths_add(data,TRUE); break; // Change path name case GAD_PATHFORMAT_PATH: config_paths_change(data); break; // Select an entry case GAD_PATHFORMAT_PATHS: { Att_Node *node; // Find selected entry node=Att_FindNode(data->path_list,msg_copy.Code); // Double-click? if (DoubleClick(data->seconds,data->micros,msg_copy.Seconds,msg_copy.Micros) && node==data->path_sel) { // Edit it config_paths_edit(data); break; } // Store double-click time data->seconds=msg_copy.Seconds; data->micros=msg_copy.Micros; // Not already selected? if (node!=data->path_sel) { // Select it config_paths_select(data,node,FALSE); } } break; // Key case GAD_PATHFORMAT_KEY: config_paths_get_key(data); break; // Open new lister case GAD_PATHFORMAT_NEW_LISTER: // Valid selection? if (data->path_sel) { position_rec *pos=(position_rec *)data->path_sel->data; // Open new lister? if (msg_copy.Code) { // Set flag pos->flags|=POSITIONF_OPEN_NEW; // Clear type flags pos->flags&=~(POSITIONF_ICON|POSITIONF_ICON_ACTION); // Icon action? if (msg_copy.Code==MODE_ACTION) pos->flags|=POSITIONF_ICON|POSITIONF_ICON_ACTION; // Icon? else if (msg_copy.Code==MODE_ICON) pos->flags|=POSITIONF_ICON; } // No lister else pos->flags&=~POSITIONF_OPEN_NEW; } break; // Remove case GAD_PATHFORMAT_REMOVE: config_paths_remove(data,TRUE); break; // Edit case GAD_PATHFORMAT_EDIT: config_paths_edit(data); break; } break; // Key press case IDCMP_RAWKEY: // Help? if (msg_copy.Code==0x5f && !(msg_copy.Qualifier&VALID_QUALIFIERS)) { // Valid main IPC? if (main_ipc) { // Set busy pointer SetWindowBusy(data->window); // Send help request IPC_Command(main_ipc,IPC_HELP,(1<<31),"Paths",0,(struct MsgPort *)-1); // Clear busy pointer ClearWindowBusy(data->window); } } break; } // Check quit flag if (quit_flag) break; } } // Check quit flag if (quit_flag) break; // App messages? if (data->appport) { struct AppMessage *msg; // Get messages while ((msg=(struct AppMessage *)GetMsg(data->appport))) { // Get first argument if (msg->am_NumArgs>0) { // Is it a directory? if (!msg->am_ArgList[0].wa_Name || !*msg->am_ArgList[0].wa_Name) { char buf[256]; // Expand path name if (NameFromLock(msg->am_ArgList[0].wa_Lock,buf,256)) { Att_Node *node; // Fix trailing / AddPart(buf,"",256); // Check it's not already in the list if (!(node=(Att_Node *)FindNameI((struct List *)data->path_list,buf))) { // Add a new entry config_paths_add(data,FALSE); // Copy path to path field SetGadgetValue(data->objlist,GAD_PATHFORMAT_PATH,(ULONG)buf); // Accept the new path config_paths_change(data); } // It is, select this entry else config_paths_select(data,node,FALSE); } } } // Reply message ReplyMsg((struct Message *)msg); } } // Wait for input Wait( ((data->window)?(1<<data->window->UserPort->mp_SigBit):0)| ((data->appport)?(1<<data->appport->mp_SigBit):0)| 1<<ipc->command_port->mp_SigBit); } // Free stuff config_paths_cleanup(data); return success; }
// Got a notify message from PutDiskObject() BOOL backdrop_check_notify( BackdropInfo *info, DOpusNotify *notify, Lister *lister) { char *name_buf; BOOL disk=0,ret=0; struct List *search; BackdropObject *object; if (!(name_buf=AllocVec(256,0))) return 0; // Disk icon? if (notify->dn_Name[strlen(notify->dn_Name)-1]==':') { char *ptr; // Get volume name if ((ptr=strchr(notify->dn_Name,':'))) { stccpy(name_buf,notify->dn_Name,ptr-notify->dn_Name+1); disk=1; } } // Otherwise copy name and clear it else { // Get name pointer char *name=FilePart(notify->dn_Name); // Copy name strcpy(name_buf,name); *name=0; // Strip trailing '/' if (*(name-1)=='/') *(name-1)=0; } // Is this a lister? if (lister) { short len; BOOL ok=0; // Match length len=strlen(notify->dn_Name); // See if strings match if (strnicmp(lister->cur_buffer->buf_Path,notify->dn_Name,len)==0) { // Check termination if (lister->cur_buffer->buf_Path[len]=='\0') ok=1; // / can terminate too else if (lister->cur_buffer->buf_Path[len]=='/' && lister->cur_buffer->buf_Path[len+1]=='\0') ok=1; } // Didn't match? if (!ok) { // Free message ReplyFreeMsg(notify); FreeVec(name_buf); return 0; } } // Lock backdrop list lock_listlock(&info->objects,1); // See if there's an icon of this name search=&info->objects.list; while ((object=(BackdropObject *)FindNameI(search,name_buf))) { // Disk? if (object->type==BDO_DISK && disk) { // Matched break; } // Valid object? else if (object->type!=BDO_APP_ICON && object->type!=BDO_BAD_DISK && object->path) { char *path=0; BPTR lock; // If no lister, get full path of object if (!lister && (path=AllocVec(512,0))) { // Lock path if ((lock=Lock(object->path,ACCESS_READ))) { // Get full path DevNameFromLockDopus(lock,path,512); UnLock(lock); } // Failed else strcpy(path,object->path); } // Objects in same directory? if (lister || stricmp(notify->dn_Name,(path)?path:object->path)==0) { // Free path if (path) FreeVec(path); // Matched break; } // Free path if (path) FreeVec(path); } // If this is a lister, there could only be one if (lister) { object=0; break; } // Keep searching from this object search=(struct List *)object; } // Got object? if (object) { ULONG old_image1=0,old_image2=0,new_image1,new_image2,old_flags=0,new_flags; BOOL redraw=0; struct DiskObject *old; // Save old icon old=object->icon; object->icon=0; // Not deleted? if (!notify->dn_Flags) { // Get image checksums old_image1=IconCheckSum(old,0); old_image2=IconCheckSum(old,1); old_flags=GetIconFlags(old); // Get new icon backdrop_get_icon(info,object,GETICON_CD|GETICON_NO_POS|GETICON_FAIL); } // No icon now? if (!object->icon) { // Replace old icon object->icon=old; // Erase old object backdrop_erase_icon(info,object,BDSF_RECALC); // Is object a disk? if (object->type==BDO_DISK) { // Signal to refresh drives IPC_Command(info->ipc,MAINCMD_REFRESH_DRIVES,0,0,0,0); } // Remove object from list backdrop_remove_object(info,object); } // Ok to keep going else { // Get image checksums new_image1=IconCheckSum(object->icon,0); new_image2=IconCheckSum(object->icon,1); new_flags=GetIconFlags(object->icon); // Mask out uninteresting flag bits old_flags&=ICONF_BORDER_OFF|ICONF_BORDER_ON|ICONF_NO_LABEL; new_flags&=ICONF_BORDER_OFF|ICONF_BORDER_ON|ICONF_NO_LABEL; // Need to redraw? if (old_image1!=new_image1 || old_image2!=new_image2 || old_flags!=new_flags) { // Erase old object backdrop_erase_icon(info,object,0); redraw=1; } // Free old icon if (old) { // Free icon remapping RemapIcon(old,(info->window)?info->window->WScreen:0,1); // Free icon FreeCachedDiskObject(old); } // Fix new icon size backdrop_get_icon(info,object,GETICON_POS_ONLY|GETICON_SAVE_POS|GETICON_KEEP); // Need to get masks? if (!backdrop_icon_border(object)) { // Get masks for this icon backdrop_get_masks(object); } // Show new icon if (redraw) backdrop_render_object(info,object,BRENDERF_CLIP); } ret=1; } // Otherwise, got lister? else if (lister) { // Tell lister to get icons IPC_Command(lister->ipc,LISTER_GET_ICONS,0,0,0,0); ret=1; } // Or, on the desktop? else if (info->flags&BDIF_MAIN_DESKTOP) { BPTR lock1,lock2; // Lock the desktop folder and the changed directory if ((lock1=Lock(environment->env->desktop_location,ACCESS_READ)) && (lock2=Lock(notify->dn_Name,ACCESS_READ))) { // Same directory? if (SameLock(lock1,lock2)==LOCK_SAME) { // Update the desktop folder misc_startup("dopus_desktop_update",MENU_UPDATE_DESKTOP,GUI->window,0,TRUE); } // Unlock second lock UnLock(lock2); } // Unlock first lock UnLock(lock1); } // Unlock list unlock_listlock(&info->objects); // Free message ReplyFreeMsg(notify); FreeVec(name_buf); return ret; }
// 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); }
// Edit a specific filetype void filetype_edit_name(config_filetypes_data *data,char *name) { Att_Node *node; char *path; // Store path pointer path=name; // Full path specified? if (strchr(name,':') || strchr(name,'/')) { // Get pointer to filename only name=FilePart(name); } // Find node if ((node=(Att_Node *)FindNameI((struct List *)data->filetype_list,name))) { // Select the new entry data->sel_filetype=node; SetGadgetValue(data->objlist,GAD_FILETYPES_LIST,Att_FindNodeNumber(data->filetype_list,node)); // Launch editor filetype_edit(data,(FiletypeNode *)node->data,0); } // Load from disk? else { Cfg_FiletypeList *list; // Try to load filetype from disk if ((list=ReadFiletypes(path,data->memory))) { Cfg_Filetype *type; Att_Node *node=0; // Add filetype list to main list AddTail(&data->list_list,&list->node); // Fix list path and flags strcpy(list->path,"dopus5:filetypes/"); strcat(list->path,name); list->flags=FTLISTF_CHANGED; // Remove list from gadget SetGadgetChoices(data->objlist,GAD_FILETYPES_LIST,(APTR)~0); // Go through filetypes in list for (type=(Cfg_Filetype *)list->filetype_list.lh_Head; type->node.ln_Succ; type=(Cfg_Filetype *)type->node.ln_Succ) { // Add entry for this filetype node=filetype_add_entry(data,type); } // Handle new node filetype_new_node(data,node); } } // Free name FreeVec(path); }