// Get icon for an object void backdrop_get_icon(BackdropInfo *info,BackdropObject *object,short flags) { short x,y,border_x=0,border_y=0; BOOL new_icon=1; // Keeping icon? if (flags&GETICON_KEEP) new_icon=0; // Not AppIcon? if (object->type!=BDO_APP_ICON && !(flags&GETICON_POS_ONLY)) { BPTR lock=0,old=0; // Already got icon? if (object->icon && !(flags&GETICON_KEEP)) { // Free icon remapping RemapIcon(object->icon,(info->window)?info->window->WScreen:0,1); // Free icon FreeCachedDiskObject(object->icon); object->icon=0; // We'll be getting a new one new_icon=1; } // Bad disk? if (object->type==BDO_BAD_DISK) { // Get default disk if (!object->icon && !(object->icon=GetCachedDefDiskObject(WBKICK))) object->icon=GetCachedDefDiskObject(WBDISK); } // Default directory icon? else if (flags&GETICON_DEFDIR) { // Get default drawer icon if (!object->icon) object->icon=GetCachedDefDiskObject(WBDRAWER); } // Get lock on directory else if (!(flags&GETICON_CD) || (lock=backdrop_icon_lock(object))) { // Go to icon directory if (lock) old=CurrentDir(lock); // Disk? if (object->type==BDO_DISK) { // No icon already? if (!object->icon) { BOOL ok=1; Cfg_Filetype *type=0; char name[256],*ptr; // Find a filetype-defined icon if (object->device_name && (type=filetype_identify(object->device_name,FTTYPE_ICON,0,0))) { // Copy icon path, strip .info strcpy(name,type->icon_path); if (ptr=isicon(name)) *ptr=0; // Over-ride flag set in filetype? if (type->type.flags&FILETYPEF_OVERRIDE) { // Try for filetype icon first object->icon=GetCachedDiskObject(name,0); } } // Don't have icon yet? if (!object->icon) { // Is this a MSDOS disk? if (object->misc_data==ID_MSDOS_DISK) { // See if icon actually exists if (type && !(SetProtection("Disk.info",FIBF_ARCHIVE)) && IoErr()==ERROR_OBJECT_NOT_FOUND) { // We'll use default icon ok=0; } } // Get disk icon if (ok) object->icon=GetCachedDiskObject("Disk",0); } // Got icon? if (object->icon) { // If it's a drawer icon, turn it into a disk if (object->icon->do_Type==WBDRAWER) object->icon->do_Type=WBDISK; // Check it is for a disk if (object->icon->do_Type!=WBDISK) { // It's not, free it and use default FreeCachedDiskObject(object->icon); object->icon=0; } } // Still no icon? Get default if (!object->icon && !(flags&GETICON_FAIL)) { // Got type-defined? if (type) { // Try for filetype icon object->icon=GetCachedDiskObject(name,0); } // Still none? Get default if (!object->icon) object->icon=GetCachedDefDiskObject(WBDISK); // Set fake flag if (object->icon) object->flags|=BDOF_FAKE_ICON; } } } // Left out or group else if (object->type==BDO_LEFT_OUT || object->type==BDO_GROUP) { // Try for icon if (!object->icon) { short fake=0; // Want real icon? if (flags&GETICON_FAIL) object->icon=GetCachedDiskObject(object->name,0); // Get default icon if fails else object->icon=GetProperIcon(object->name,&fake,0); // Ended up fake? if (fake) { // Set flag object->flags|=BDOF_FAKE_ICON; } } // Got group icon? if (object->icon && object->type==BDO_GROUP) { // Auto-open group? if (FindToolType(object->icon->do_ToolTypes,"OPEN")) object->flags|=BDOF_AUTO_OPEN; } } // Had a lock? if (lock) { // Got icon? if (object->icon) { // Clear custom position flag object->flags&=~BDOF_CUSTOM_POS; #ifdef DISTINCT_OK // Main desktop, distinct positions? if (info->flags&BDIF_MAIN_DESKTOP && environment->env->desktop_flags&DESKTOPF_DISTINCT) { char path[256]; // Get icon path if (desktop_icon_path(object,path,256,lock)) { // See if position is available if (desktop_find_icon(path,&object->custom_pos)) { // Set "custom position" flag object->flags|=BDOF_CUSTOM_POS; } } } #endif } // Restore current dir CurrentDir(old); // Unlock object lock UnLock(lock); } } // Failed to even get a lock; get default icon if a disk else if (object->type==BDO_DISK) { // Get default icon if (!object->icon && (object->icon=GetCachedDefDiskObject(WBDISK))) object->flags|=BDOF_FAKE_ICON; } } // Got an icon? if (object->icon) { // Ended up fake? if (object->flags&BDOF_FAKE_ICON) { // Make sure default icon has no position if (object->icon) { // Clear 'position ok' flag, set invalid position SetIconFlags(object->icon,GetIconFlags(object->icon)&~ICONF_POSITION_OK); SetIconPosition(object->icon,-1,-1); object->icon->do_CurrentX=NO_ICON_POSITION; object->icon->do_CurrentY=NO_ICON_POSITION; } } // If this is a group, make sure icon is a drawer if (object->type==BDO_GROUP) object->icon->do_Type=WBDRAWER; // Is it a new icon? if (new_icon) { // Window open? if (info->window) { // Remap the icon RemapIcon(object->icon,info->window->WScreen,0); // Set flag object->flags|=BDOF_REMAPPED; } } // Transparent icon? if (!backdrop_icon_border(object)) { border_x=0; border_y=0; } else { border_x=ICON_BORDER_X; border_y=ICON_BORDER_Y; } // No label? if ((GetIconFlags(object->icon)&ICONF_NO_LABEL) && !(environment->env->desktop_flags&DESKTOPF_NO_NOLABELS)) object->flags|=BDOF_NO_LABEL; else object->flags&=~BDOF_NO_LABEL; } // No icon, or no size stuff? if (!object->icon || flags&GETICON_NO_POS) return; // Get masks if (!(flags&GETICON_KEEP)) backdrop_get_masks(object); // Get object size object->pos.Width=object->icon->do_Gadget.Width; object->pos.Height=object->icon->do_Gadget.Height; // (Re)position? if (!(flags&GETICON_SAVE_POS)) { // No position initially object->flags|=BDOF_NO_POSITION; // Auto position? if (object->flags&BDOF_AUTO_POSITION) { return; } // Custom position? else if (object->flags&(BDOF_CUSTOM_POS|BDOF_LEFTOUT_POS)) { // Get custom position x=(object->custom_pos>>16)&0xffff; y=object->custom_pos&0xffff; }
// Add an AppIcon from rexx long rexx_add_appicon(char *str,struct RexxMsg *msg) { char iconfile[256],menustem[80]; RexxAppThing *app; struct TagItem *tags; short key,menu_count=0,count; long base=0; APTR memory; // Allocate AppNode if (!(app=AllocVec(sizeof(RexxAppThing),MEMF_CLEAR))) return 0; // Allocate memory handle if (!(memory=NewMemHandle(0,0,MEMF_CLEAR))) { FreeVec(app); return 0; } // Set type app->node.ln_Type=REXXAPP_ICON; // Initialise position app->pos_x=NO_ICON_POSITION; app->pos_y=NO_ICON_POSITION; // Get port name rexx_parse_word(&str,app->port_name,sizeof(app->port_name)); // Get icon name rexx_parse_word(&str,app->icon_name,sizeof(app->icon_name)); // Get ID rexx_skip_space(&str); app->id=rexx_parse_number(&str,0,0); // Clear buffers iconfile[0]=0; menustem[0]=0; // Position set? rexx_skip_space(&str); while ((key=rexx_match_keyword(&str,pos_keys,0))!=-1) { // Position? if (key==APPARG_POS) { // Get position app->pos_x=rexx_parse_number(&str,1,NO_ICON_POSITION); app->pos_y=rexx_parse_number(&str,0,NO_ICON_POSITION); } // Quotes? else if (key==APPARG_QUOTES) app->flags|=RATF_QUOTES; // Info? else if (key==APPARG_INFO) app->flags|=RATF_INFO; // Snapshot else if (key==APPARG_SNAP) app->flags|=RATF_SNAP; // Close else if (key==APPARG_CLOSE) app->flags|=RATF_CLOSE; // Local else if (key==APPARG_LOCAL) app->flags|=RATF_LOCAL; // Locked else if (key==APPARG_LOCKED) app->flags|=RATF_LOCKED; // Icon else if (key==APPARG_ICON) { // Get filename rexx_parse_word(&str,iconfile,256); } // Menu else if (key==APPARG_MENU) { // Get menu stem if (rexx_parse_word(&str,menustem,30)) { // Check stem has a period if (menustem[0] && menustem[strlen(menustem)-1]!='.') strcat(menustem,"."); } } // Skip spaces rexx_skip_space(&str); } // Try and get icon if (iconfile[0]) app->icon=GetCachedDiskObject(iconfile,GCDOF_NOCACHE); // Failed? Get default if (!app->icon && !(app->icon=GetCachedDefDiskObject(WBTOOL|GCDOF_NOCACHE))) { // Failed completely FreeVec(app); return 0; } // Set icon position app->icon->do_CurrentX=app->pos_x-WBICONMAGIC_X; app->icon->do_CurrentY=app->pos_y-WBICONMAGIC_Y; SetIconFlags(app->icon,GetIconFlags(app->icon)&~ICONF_POSITION_OK); // Remap the icon (only if a local one) if (app->flags&RATF_LOCAL) RemapIcon(app->icon,GUI->screen_pointer,FALSE); // Menu items? if (menustem[0]) { char buffer[10]; // Get count rexx_get_var(msg,menustem,"COUNT",buffer,10); menu_count=atoi(buffer); // Get base if (rexx_get_var(msg,menustem,"BASE",buffer,10)) base=atoi(buffer); } // Number of tags needed count=7+menu_count; // Allocate tags if ((tags=AllocMemH(memory,sizeof(struct TagItem)*count))) { // Initialise tags tags[0].ti_Tag=DAE_SnapShot; tags[0].ti_Data=(app->flags&RATF_SNAP)?1:0; tags[1].ti_Tag=DAE_Info; tags[1].ti_Data=(app->flags&RATF_INFO)?1:0; tags[2].ti_Tag=DAE_Close; tags[2].ti_Data=(app->flags&RATF_CLOSE)?1:0; tags[3].ti_Tag=(app->flags&RATF_LOCAL)?DAE_Local:TAG_IGNORE; tags[3].ti_Data=1; tags[4].ti_Tag=DAE_Locked; tags[4].ti_Data=(app->flags&RATF_LOCKED)?1:0; tags[5].ti_Tag=DAE_MenuBase; tags[5].ti_Data=base; // Go through menus for (count=0;count<menu_count;count++) { char buffer[80]; // Build variable name lsprintf(iconfile,"%ld",count); // Get variable if (rexx_get_var(msg,menustem,iconfile,buffer,80)) { // Allocate buffer if ((tags[count+6].ti_Data=(ULONG)AllocMemH(memory,strlen(buffer)+1))) { // Copy name strcpy((char *)tags[count+6].ti_Data,buffer); // Set tag ID tags[count+6].ti_Tag=DAE_Menu; } else tags[count+6].ti_Tag=TAG_IGNORE; } // Skip this tag else tags[count+6].ti_Tag=TAG_IGNORE; } } // Add AppIcon app->app_thing= AddAppIconA( app->id, (ULONG)app, app->icon_name, GUI->rexx_app_port, 0, app->icon, tags); // Free memory FreeMemHandle(memory); // Failed? if (!app->app_thing) { // Failed if (app->flags&RATF_LOCAL) RemapIcon(app->icon,GUI->screen_pointer,FALSE); FreeCachedDiskObject(app->icon); FreeVec(app); return 0; } // Add to AppList lock_listlock(&GUI->rexx_apps,TRUE); AddTail(&GUI->rexx_apps.list,(struct Node *)app); unlock_listlock(&GUI->rexx_apps); return (long)app; }
// 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; }
// Snapshot objects void backdrop_snapshot(BackdropInfo *info,BOOL unsnapshot,BOOL all,BackdropObject *icon) { BackdropObject *object; Lister *lister; IPCData *ipc; BPTR old,lock; short count=0,beep=0; #ifdef DISTINCT_OK BOOL save_env=0; #endif BOOL savepos=0; // Lock backdrop list lock_listlock(&info->objects,0); // Lock lister list lock_listlock(&GUI->lister_list,0); // Lock group list lock_listlock(&GUI->group_list,0); // Go through backdrop list for (object=(BackdropObject *)info->objects.list.lh_Head; object->node.ln_Succ; object=(BackdropObject *)object->node.ln_Succ) { BOOL ok=0; // Icon supplied? if (icon) { // Does it match? if (object!=icon || !object->icon) continue; } // Is object selected? else if ((!object->state && !all) || !object->icon) continue; beep=1; // Appicon? if (object->type==BDO_APP_ICON) { // Does icon support snapshot itself? if (WB_AppIconFlags((struct AppIcon *)object->misc_data)&APPENTF_SNAPSHOT) { backdrop_appicon_message(object,(unsnapshot)?BAPPF_UNSNAPSHOT:0); ++count; } // Otherwise, fake snapshot else if (*object->name) ok=1; } // Otherwise, is it ok to snapshot? else if (object->type!=BDO_BAD_DISK) ok=1; // Ok to snapshot? if (ok) { short x,y; // UnShapshot? if (unsnapshot) { // Set "no position" position x=-1; y=-1; } // Snapshot else { // Drawer? if (object->icon->do_DrawerData) { // Group icon? if (object->type==BDO_GROUP) { GroupData *group; // See if group is open if ((group=backdrop_find_group(object))) { // Update window position *((struct IBox *)&object->icon->do_DrawerData->dd_NewWindow.LeftEdge)=group->dimensions; } } // Otherwise go through listers else for (ipc=(IPCData *)GUI->lister_list.list.lh_Head; ipc->node.mln_Succ; ipc=(IPCData *)ipc->node.mln_Succ) { // Get lister lister=IPCDATA(ipc); // Is lister from this icon? if (lister->backdrop==object) { // Update lister PositionUpdate(lister,POSUPF_SAVE); break; } } } // Get position x=object->pos.Left; y=object->pos.Top; } // AppIcon? if (object->type==BDO_APP_ICON) { leftout_record *left; // Lock position list lock_listlock(&GUI->positions,TRUE); // Look for entry for icon for (left=(leftout_record *)&GUI->positions.list.lh_Head; left->node.ln_Succ; left=(leftout_record *)left->node.ln_Succ) { // Leftout? if (left->node.ln_Type==PTYPE_APPICON) { // Match this icon? if (strcmp(left->icon_label,object->name)==0) break; } } // Didn't find one? if (!(left->node.ln_Succ) && !unsnapshot) { // Create a new entry if ((left=AllocMemH(GUI->position_memory,sizeof(leftout_record)))) { // Fill out entry stccpy(left->icon_label,object->name,sizeof(left->icon_label)); left->node.ln_Name=left->name; left->node.ln_Type=PTYPE_APPICON; // Add to list AddTail((struct List *)&GUI->positions,(struct Node *)left); } } // Got one? if (left->node.ln_Succ) { // Unsnapshot? if (unsnapshot) { // Remove entry and free it Remove((struct Node *)left); FreeMemH(left); } // Update entry else { ULONG iflags; // Adjust for borders? if (!((iflags=GetIconFlags(object->icon))&ICONF_BORDER_OFF) && (!(environment->env->desktop_flags&DESKTOPF_NO_BORDERS) || (iflags&ICONF_BORDER_ON))) { // Shift back by border size x-=ICON_BORDER_X; y-=ICON_BORDER_Y_TOP; } // Save position left->icon_x=x; left->icon_y=y; left->flags&=~LEFTOUTF_NO_POSITION; } // Set flag to save positions savepos=1; } // Can't snapshot for some reason else if (!unsnapshot) beep=1; // Unlock position list unlock_listlock(&GUI->positions); } // Left-out on desktop? else if (object->type==BDO_LEFT_OUT && !(object->flags&BDOF_DESKTOP_FOLDER) && info->flags&BDIF_MAIN_DESKTOP) { leftout_record *left; // Lock position list lock_listlock(&GUI->positions,0); // Look for entry for icon for (left=(leftout_record *)&GUI->positions.list.lh_Head; left->node.ln_Succ; left=(leftout_record *)left->node.ln_Succ) { // Leftout? if (left->node.ln_Type==PTYPE_LEFTOUT) { // Match this icon? if (object->misc_data==(ULONG)left) break; } } // Got one? if (left->node.ln_Succ) { // Save position left->icon_x=x; left->icon_y=y; left->flags&=~LEFTOUTF_NO_POSITION; // Set flag to save positions savepos=1; } // Must be temporary else beep=1; // Unlock position list unlock_listlock(&GUI->positions); } #ifdef DISTINCT_OK // Distinct icon positions? else if (environment->env->desktop_flags&DESKTOPF_DISTINCT && info->flags&BDIF_MAIN_DESKTOP) { // Snapshot icon for this environment desktop_snapshot_icon(object,x,y); save_env=1; } #endif // Group icon? else if (info->flags&BDIF_GROUP) { // Snapshot in group group_snapshot_icon(info,object,x,y); } // Save to icon else { // Using Workbench positions? if (environment->env->display_options&DISPOPTF_ICON_POS) { // Set position object->icon->do_CurrentX=(unsnapshot)?NO_ICON_POSITION:x-WBICONMAGIC_X; object->icon->do_CurrentY=(unsnapshot)?NO_ICON_POSITION:y-WBICONMAGIC_Y; // Removing Opus positions? if (environment->env->display_options&DISPOPTF_REMOPUSPOS) { // Remove Opus position from icon SetIconFlags(object->icon,GetIconFlags(object->icon)&~ICONF_POSITION_OK); } } // Using Opus positions else { // Set "position ok" flag SetIconFlags(object->icon,GetIconFlags(object->icon)|ICONF_POSITION_OK); // Update icon position SetIconPosition(object->icon,x,y); } // Get icon lock if ((lock=backdrop_icon_lock(object))) { // Change directory old=CurrentDir(lock); // Save this object out if (!(WriteIcon((object->icon->do_Type==WBDISK)?"Disk":object->name,object->icon))) beep=1; // Success; is this in a lister? else if (info->lister) { char name[256]; // Get icon name strcpy(name,(object->icon->do_Type==WBDISK)?"Disk":object->name); strcat(name,".info"); // Reload the file rexx_lister_reload_file(info->lister,name); } // Restore directory CurrentDir(old); UnLock(lock); } } ++count; } // Icon supplied? if (icon) break; } // Failed to do anything? if (!count && beep) DisplayBeep(info->window->WScreen); // Unlock group list unlock_listlock(&GUI->group_list); // Unlock backdrop list unlock_listlock(&info->objects); // Unlock lister list unlock_listlock(&GUI->lister_list); #ifdef DISTINCT_OK // Save environment file? if (save_env && environment->env->flags&ENVF_CHANGED) { // Save environment if (environment_save(environment,environment->path,0,0)) environment->env->flags&=~ENVF_CHANGED; } #endif // Save positions? if (savepos) { // Lock list lock_listlock(&GUI->positions,0); // Save list SavePositions(&GUI->positions.list,GUI->position_name); // Unlock list unlock_listlock(&GUI->positions); } // If this is a lister, update its datestamp if (info->lister) update_buffer_stamp(info->lister); }