// 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; }
void FiletypeEditor(void) { filetype_ed_data *data=0; IPCData *ipc; short success=0,pending_quit=0; BOOL change_flag=0; // Do startup if (!(ipc=Local_IPC_ProcStartup((ULONG *)&data, (APTR)&_filetypeed_init))) return; // Create App stuff if ((data->app_port=CreateMsgPort())) { data->app_window=AddAppWindowA(0,0,data->window,data->app_port,0); } // Get icon image if (data->type->icon_path) { #ifdef USE_DRAWICONSTATE { char *path_copy; data->icon_image=NULL; if ((path_copy=AllocMemH(0,strlen(data->type->icon_path)+1))) { // icon_path is guaranteed to have a .info at the end stccpy(path_copy,data->type->icon_path,strlen(data->type->icon_path)-4); data->icon_image=GetCachedDiskObject(path_copy,0); FreeMemH(path_copy); } } #else data->icon_image=OpenImage(data->type->icon_path,0); #endif // Show icon image filetypeed_show_icon(data); } // Launch class editor immediately? if (data->edit_flag) filetypeed_edit_definition(data); // Message loop FOREVER { IPCMessage *msg; struct IntuiMessage *imsg; short break_flag=0; // Check drag if (config_drag_check(&data->drag)) { // End drag filetypeed_end_drag(data,0); } // Task message? while ((msg=(IPCMessage *)GetMsg(ipc->command_port))) { switch (msg->command) { // Close message? case IPC_QUIT: if (!pending_quit) { success=msg->flags; break_flag=1; } break; // Activate case IPC_ACTIVATE: if (data->window) { WindowToFront(data->window); ActivateWindow(data->window); } break; // Editor saying goodbye case IPC_GOODBYE: { ULONG which; // What's just gone? which=IPC_GetGoodbye(msg); // Class editor? if (which==(ULONG)-1) data->class_editor=0; // Icon menu editor? else if (which>15) { Att_Node *node; // Go through icon list for (node=(Att_Node *)data->icon_list->list.lh_Head; node->node.ln_Succ; node=(Att_Node *)node->node.ln_Succ) { // Match function if (((func_node *)node->data)->func==(Cfg_Function *)which) { // Clear editor pointer ((func_node *)node->data)->editor=0; // Check for invalid function if (filetypeed_check_iconmenu(data,node,FALSE)) change_flag=1; break; } } } // Normal filetype editor else data->editor[which]=0; } break; // Editor returning a function case FUNCTIONEDIT_RETURN: { short ret; if ((ret=filetypeed_receive_edit( data, (FunctionReturn *)msg->data))) { change_flag=1; filetypeed_update_actions(data); if (ret==2) filetypeed_update_iconmenu(data); } } break; // Class editor returning case CLASSEDIT_RETURN: filetypeed_receive_class(data,(Cfg_Filetype *)msg->data); change_flag=1; break; // Get a copy of a button case BUTTONEDIT_CLIP_BUTTON: // Handle this button if (filetypeed_get_button(data,(Cfg_Button *)msg->data,(Point *)msg->data_free)) change_flag=1; break; } // Reply the message IPC_Reply(msg); } // Intuimessage if (data->window) { while ((imsg=GetWindowMsg(data->window->UserPort))) { struct IntuiMessage msg_copy; struct Gadget *gadget; struct TagItem *tags; // Copy message msg_copy=*imsg; // Don't reply to IDCMPUPDATE messages just yet if (imsg->Class!=IDCMP_IDCMPUPDATE) { ReplyWindowMsg(imsg); imsg=0; } // Get gadget and tag pointers gadget=(struct Gadget *)msg_copy.IAddress; tags=(struct TagItem *)gadget; // Look at message switch (msg_copy.Class) { // Close window case IDCMP_CLOSEWINDOW: if (!pending_quit) break_flag=1; break; // Gadget case IDCMP_GADGETUP: switch (gadget->GadgetID) { // Use case GAD_FILETYPEED_USE: success=1; // Cancel case GAD_FILETYPEED_CANCEL: if (!pending_quit) break_flag=1; break; // Select a function case GAD_FILETYPEED_ACTION_LIST: { Att_Node *node; // Get selected node if (!(node=Att_FindNode(data->action_list,msg_copy.Code))) break; // Enable edit action button DisableObject(data->objlist,GAD_FILETYPES_EDIT_ACTION,FALSE); // Double-click? if (!(DoubleClick(data->last_sec,data->last_mic,msg_copy.Seconds,msg_copy.Micros)) || node!=data->last_sel) { data->last_sec=msg_copy.Seconds; data->last_mic=msg_copy.Micros; data->last_sel=node; data->last_icon=0; break; } } // Fall through case GAD_FILETYPES_EDIT_ACTION: // No current selection? if (!data->last_sel) break; // Is editor already up for this action? if (data->editor[data->last_sel->data]) IPC_Command(data->editor[data->last_sel->data],IPC_ACTIVATE,0,0,0,0); // Need to launch editor else filetypeed_edit_action(data,data->last_sel->data,data->last_sel->node.ln_Name); break; // Delete action case GAD_FILETYPES_DEL_ACTION: // No current selection? if (!data->last_sel) break; // Is editor up for this action? if (data->editor[data->last_sel->data]) IPC_Command(data->editor[data->last_sel->data],IPC_QUIT,0,0,0,0); // Delete it if (filetypeed_del_action(data,data->last_sel->data)) change_flag=1; break; // Edit filetype definition case GAD_FILETYPEED_EDIT_CLASS: // Is class editor already up for this action? if (data->class_editor) IPC_Command(data->class_editor,IPC_ACTIVATE,0,0,0,0); // Need to launch editor else filetypeed_edit_definition(data); break; // Select icon case GAD_FILETYPEED_SELECT_ICON: if (filetypeed_pick_icon(data)) change_flag=1; break; // Add to icon menu case GAD_FILETYPES_ADD_ICON_MENU: filetypeed_add_iconmenu(data); break; // Select an icon menu case GAD_FILETYPES_ICON_MENU: { Att_Node *last=data->last_icon; // Handle selection if (!(filetypeed_sel_icon(data,msg_copy.Code))) break; // Double-click? if (data->last_icon!=last || !(DoubleClick( data->last_sec, data->last_mic, msg_copy.Seconds, msg_copy.Micros))) { data->last_sec=msg_copy.Seconds; data->last_mic=msg_copy.Micros; data->last_sel=0; break; } } // Fall through case GAD_FILETYPES_EDIT_ICON_MENU: // No current selection? if (!data->last_icon) break; // Edit it filetypeed_edit_iconmenu(data,data->last_icon); break; // Delete from icon menu case GAD_FILETYPES_DEL_ICON_MENU: // No current selection? if (!data->last_icon) break; // Delete function if (filetypeed_check_iconmenu(data,data->last_icon,TRUE)) change_flag=1; break; } break; // BOOPSI message case IDCMP_IDCMPUPDATE: { short item; // Icon list? if (GetTagData(GA_ID,0,tags)!=GAD_FILETYPES_ICON_MENU) break; // Get item if ((item=GetTagData(DLV_DragNotify,-1,tags))!=-1) { // Handle selection filetypeed_sel_icon(data,item); // Start the drag config_drag_start(&data->drag,data->icon_list,item,tags,TRUE); } } break; // Ticks case IDCMP_INTUITICKS: ++data->drag.tick_count; break; // Mouse move case IDCMP_MOUSEMOVE: // Handle drag move config_drag_move(&data->drag); break; // Mouse buttons case IDCMP_MOUSEBUTTONS: // Valid drag info? if (data->drag.drag) { short ok=-1; // Dropped ok? if (msg_copy.Code==SELECTUP) { // Remember last position data->drag.drag_x=data->window->WScreen->MouseX; data->drag.drag_y=data->window->WScreen->MouseY; ok=1; } // Aborted else if (msg_copy.Code==MENUDOWN) ok=0; // End drag? if (ok!=-1 && filetypeed_end_drag(data,ok)) change_flag=1; } break; // Key press case IDCMP_RAWKEY: // Help? if (msg_copy.Code==0x5f && !(msg_copy.Qualifier&VALID_QUALIFIERS)) { // Set busy pointer SetWindowBusy(data->window); // Send help command IPC_Command(data->func_startup.main_owner,IPC_HELP,(1<<31),"File Type Editor",0,REPLY_NO_PORT); // Clear busy pointer ClearWindowBusy(data->window); } break; } // Reply to outstanding messages if (imsg) ReplyWindowMsg(imsg); } // Check break flag if (break_flag || pending_quit) { // See if all the editors are gone if (IsListEmpty(&data->proc_list.list)) break; // Send quit? if (break_flag) { IPC_ListQuit(&data->proc_list,0,success,FALSE); SetWindowBusy(data->window); } pending_quit=1; } } // AppMessage if (data->app_window) { struct AppMessage *msg; while ((msg=(struct AppMessage *)GetMsg(data->app_port))) { // Got an argument? if (msg->am_NumArgs>0) { char name[256]; short len; APTR image; // Get full name NameFromLock(msg->am_ArgList[0].wa_Lock,name,256); if (msg->am_ArgList[0].wa_Name && *msg->am_ArgList[0].wa_Name) AddPart(name,msg->am_ArgList[0].wa_Name,256); // Add .info if ((len=strlen(name))<6 || stricmp(name+len-5,".info")!=0) strcat(name,".info"); // Try to get image #ifdef USE_DRAWICONSTATE { char *path_copy; image=NULL; if ((path_copy=AllocMemH(0,strlen(name)+1))) { // icon_path is guaranteed to have a .info at the end stccpy(path_copy,name,strlen(name)-4); image=GetCachedDiskObject(path_copy,0); FreeMemH(path_copy); } } #else image=OpenImage(name,0); #endif if (image) { // Store path FreeMemH(data->type->icon_path); if ((data->type->icon_path=AllocMemH(0,strlen(name)+1))) strcpy(data->type->icon_path,name); // Free existing image #ifdef USE_DRAWICONSTATE FreeCachedDiskObject(data->icon_image); #else CloseImage(data->icon_image); #endif data->icon_image=image; // Show new image filetypeed_show_icon(data); change_flag=1; } } // Reply message ReplyMsg((struct Message *)msg); } } Wait(1<<ipc->command_port->mp_SigBit| 1<<data->drag.timer->port->mp_SigBit| ((data->window)?(1<<data->window->UserPort->mp_SigBit):0)| ((data->app_window)?(1<<data->app_port->mp_SigBit):0)); } // End any drag in progress filetypeed_end_drag(data,0); // Need to send button back? if (success==1 && change_flag) { if (IPC_Command( data->owner_ipc, FILETYPEEDIT_RETURN, (ULONG)data->type, data->node, 0, REPLY_NO_PORT)) { data->node=0; } } // Free edit filetype FreeFiletype(data->type); // Remove AppWindow RemoveAppWindow(data->app_window); // Close window CloseConfigWindow(data->window); // Close app port if (data->app_port) { struct Message *msg; while ((msg=GetMsg(data->app_port))) ReplyMsg(msg); DeleteMsgPort(data->app_port); } // Say goodbye IPC_Goodbye(ipc,data->owner_ipc,(success==-1)?0:(ULONG)data->node); // Free icon image #ifdef USE_DRAWICONSTATE FreeCachedDiskObject(data->icon_image); #else CloseImage(data->icon_image); #endif // Close timer FreeTimer(data->drag.timer); // Free data IPC_Free(ipc); Att_RemList(data->action_list,0); Att_RemList(data->icon_list,REMLIST_FREEDATA); FreeVec(data); }
// 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; }