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