Notes on Building the Desktop Icon Files Gregg Morris 03/27/87 Introduction There are two Desktop icon files: DESKLO.ICN for low resolution (640x200) and DESKHI.ICN for high resolution (Hercules, EGA, etc.) systems. Structurally, they are identical. There are differences within the structure which are described below. The files are built by compiling, linking, and running a very small C program named COMPICON. There are two batch files used to do this: BLDLOICN.BAT and BLDHIICN.BAT. These batch files copy the corresponding .H file ICONLO.H or ICONHI.H to the file ICONLIST.H, compile, link, and run COMPICON, then rename the created file DESKTOP.IMG to either DESKLO.ICN or DESKHI.ICN. (NOTE: for historical reasons, the Lattice C compiler and LINK86 are used.) The COMPICON.C File This program declares a variable beg_file, #includes a .H file named ICONLIST.H, then declares another variable end_file. These two variables are used to calculate the size of the data included in the .H file. The block of memory containing the included data is then written to a file. The ICONLIST.H File The ICONLIST.H file is a copy of either the ICONLO.H or ICONHI.H file. This is so COMPICON.C need not be changed each time a different icon set is produced. The file contains three main parts: the declaration of an array of ICONBLKs, the inclusion of a bunch of .ICN files (the kind created by GEM IconEdit), and the declaration of an array of strings. I'll describe these in reverse order. The array of strings are the names of the application/document icon pairs used in the Configure Application dialog in the Desktop. Each name has a leading and trailing space because it is used as a "window title" in the dialog. The order of the names corresponds to the order of the icons in the ICONBLK array (described below). (IMPORTANT NOTE: If the number of ICONBLKs is changed, then the number of strings declared must be changed correspondingly, and the Desktop itself must be changed as well. See the routine app_rdicon in DESKAPP.C for the code that actually reads the icon files into the Desktop.) The #include statements are used to include the actual icon definitions in the ICONLIST.H file. The icon definitions are created by GEM IconEdit or GEM Resource Construction Set. The order of inclusion corresponds to the order of the icons in the ICONBLK array; this is described in detail below. The names of the files are descriptive of the their contents: the general form is: Ix????yz.ICN where x = G for GEM (used for the system icons) A for Application icons D for Document icons y = M for mask D for data z = L for low resolution (48x24 pixels) H for high resolution (32x32 pixels) ???? is a 4 letter descriptive (!) name for the icon. For example, IGFDSKML.ICN is the system (G) floppy disk (FDSK) mask (M) low resolution (L) icon. IASPRDDH.ICN is the application (A) spreadsheet (SPRD) data (D) high resolution (H) icon. The ICONBLK Array There are 72 ICONBLKs in this array. (IMPORTANT NOTE: If this number is changed, the number of strings declared (see above) and the Desktop itself must be changed as well. See the routine app_rdicon in DESKAPP.C for the code that actually reads the icon files into the Desktop.) Of the 72 ICONBLKs, 8 are system icons (disk drive icons, folder icons), 32 are application icons, and 32 are document icons. Of the system icons, originally only 4 were used; because of the Apple-mandated changes, the trash can was removed, so only three system icons are used now. The application and document icons should be thought of as pairs, since that is the way the Desktop uses them. At this writing, I have just added icon pair #17 to the list, so there are still 15 unused pairs in the array. Adding a New Icon The elements in the array are ordered as follows: the first 8 elements are the system icons, the next 32 are the application icons, and the last 32 are the document icons. A new icon is added by replacing one of the reserved/unused icons. This can be tricky depending on the icon being added. Application and Document icons all use the generic application (IAGENRMz.ICN) or generic document (IDGENRMz.ICN) mask. Thus you don't need a unique mask for each application or document icon. The system icons, on the other hand, each use a unique mask. Look at the entries for the system icons in the ICONBLK array: 0x0L, 0x1L, -1L, 0x1000,6,7, 15,0,48,24, 4,24,72,10, /*IGHARD 0*/ 0x2L, 0x3L, -1L, 0x1000,7,5, 15,0,48,24, 4,24,72,10, /*IGFLOPPY 1*/ 0x4L, 0x5L, -1L, 0x1000,0,0, 15,0,48,24, 4,24,72,10, /*IGFOLDER 2*/ 0x6L, 0x7L, -1L, 0x1000,0,0, 15,0,48,24, 4,24,72,10, /*IGTRASH 3*/ 0x8L, 0x9L, -1L, 0x1000,0,0, 15,0,48,24, 4,24,72,10, /*IG4RESV 4*/ 0x8L, 0x9L, -1L, 0x1000,0,0, 15,0,48,24, 4,24,72,10, /*IG5RESV 5*/ 0x8L, 0x9L, -1L, 0x1000,0,0, 15,0,48,24, 4,24,72,10, /*IG6RESV 6*/ 0x8L, 0x9L, -1L, 0x1000,0,0, 15,0,48,24, 4,24,72,10, /*IG7RESV 7*/ The first two numbers in each entry are offsets to the mask and data, respectively. It is these numbers that determine the order of the #include files following. In this case, the hard disk mask file is first, followed by the hard disk data, then the floppy disk mask, the floppy disk data, and so on. Notice that this pattern changes at the fifth entry, then repeats from that entry on: these are the "reserved" or unused entries for system icons. The mask value is pointing to the generic application mask, and the data value is pointing to the generic application data. If you count the #include entries, starting at zero and skipping the commented-out placedholders, you'll see that the #include statement at line 8 is for the application generic mask (IAGENRMz.ICN). Now look at the entries immediately following those above, for the application icons: 0x8L, 0x9L, -1L, 0x1000,0,0, 15,0,48,24, 4,24,72,10, /*IAGENER 8*/ 0x8L, 0xAL, -1L, 0x1000,0,0, 15,0,48,24, 4,24,72,10, /*IASS 9*/ 0x8L, 0xBL, -1L, 0x1000,0,0, 15,0,48,24, 4,24,72,10, /*IAWP 10*/ Note that the first entry here is for the generic application icon as we saw above. The second entry, though, uses the same mask as the generic entry, and so does the third entry. Only the data value is changing now. This pattern continues until we reach the end of the entries in use. After that, you'll notice the pattern goes back to the generic application icon and continues until we get to the entries for the document icons: 0x1AL, 0x1BL, -1L, 0x1000,0,0, 15,0,48,24, 4,24,72,10, /*IDGENER 40*/ 0x1AL, 0x1CL, -1L, 0x1000,0,0, 15,0,48,24, 4,24,72,10, /*IDSS 41*/ 0x1AL, 0x1DL, -1L, 0x1000,0,0, 15,0,48,24, 4,24,72,10, /*IDWP 42*/ Notice the mask offset has changed: now it's the offset of the generic document mask, instead of the generic application mask. The pattern we saw before continues here: the mask offset is the same, the data offset changes. Here's where things get tricky: when you add a new application/document pair, you include new icon files in the list. This shifts down all the offsets below it. For example, when you include the new application icon, the offset of the generic document mask changes: it increases by one. This means that all references to the generic document mask must be changed, or very weird things will happen. Likewise, if you add a new system icon, BOTH the generic application mask AND the generic document mask will increase by one. For example, let's suppose we're adding a new application/document pair for GEM VisiCarp to the low resolution icon set. First, we modify the next available unused application entry from this: 0x8L, 0x9L, -1L, 0x1000,0,0, 15,0,48,24, 4,24,72,10, /*IARSV 2*/ to this: 0x8L, 0x1AL, -1L, 0x1000,0,0, 15,0,48,24, 4,24,72,10,/*IACARP */ Next, since we're adding an icon into the list, we have to change the offset of the generic document mask. Currently it is 0x1A; we'll change it to 0x1B. Then we must change all the mask values of 0x1A to 0x1B. Next, since we added an icon, we have to add 1 to all the existing document icon offsets: 0x1B becomes 0x1C, 0x1C becomes 0x1D, and so on. Then, in the list of #include statements, we add this: #include right after the last application icon included. Likewise, we add #include right after the last document icon included. Finally, we add a string to the string array at the bottom, right after the last string in the list. Don't forget the leading and trailing space! Execute the batch file BLDLOICN, and presto! Try out the file by putting in the GEMDESK directory and running GEM. It's probably a good idea to preserve your old DESKLO.ICN file.