From: tb@liszt.thorn-emi-crl.co.uk (Tim Browse) Date: 23 Feb 93 14:06:26 GMT Proposed Glass File Format ========================== This file/message concerns the proposal of a new Template file format. Objectives ~~~~~~~~~ * An alternative to the current Template file. * Facility to hold information about entities other than windows and icons e.g. menus, icon names, meta-icons etc. * Make it simple to use, namely: + Provide a template editor that can create Glass files and convert Glass <-> Template files. + Provide support code to use any special features (e.g. meta-icons, position independent menus etc) + Provide a program to create Template files from Glass files so Risc OS Lib will work ok, and generally ease the transition. * Reasonably efficient format, within reason - e.g. 32-bit words will be used for number storage as opposed to bytes - I think we can handle an overhead of a few hundred bytes in our files (at worst). Unless lots of numbers are stored. * Make it an extensible tagged file format. Divide information into chunks, and have keys + file offsets to find them. Then if you don't understand a certain chunk, it's ignored. Also, a chunk must only contain relative file offsets *within* itself so that chunks may just be copied verbatim from one file to another. This means someone could write a simple filter to map the font chunk entries to different fonts and still preserve the rest of the Glass data. i.e. it should be possible to divide up the chunks of a Glass format file, and write them back in any order and the file would still be a legal Glass file, as long as the header entries point to the correct data. * As you may have noticed, the above is very similar to Acorn's chunk file format, and hence I propose to use the Chunk file format. The format of the chunks themselves will of course be defined by myself and others. The reason I intend to use the chunk file format is that everything it does is needed by Glass files, and I see no reason to re-invent wheels. A filetype is still needed so I and all the other lazy people can just double click on the file to edit it :-) A considerable amount of file structure will be present in the chunks themselves, and it may seem unncessary to bother with chunk files with this first standard, but bear in mind that this format is meant to be extended. Remember that if this standard is adopted, you're stuck with it - so it had better be able to handle what you might want to do in the future. * Make people *want* to use it by providing features they want(!) * Where necessary, a chunk will be timestamped to indicate when it was last edited. * Don't use icon validation strings - there's already too much crap in them. * Structure the file so that it's reasonably quick to load. i.e. don't make it necessary to have to guess memory requirements (can you say Wimp_LoadTemplate?) or to do excessive disc thrashing. I have, in a number of places, made various trade-offs between efficiency and convenience. To establish a standard ~~~~~~~~~~~~~~~~~~~~~~ For the first standard, the objective is simple. The format will allow storage of Templates as in a normal Template file, and also a system for naming Icons, so that names rather than icon numbers can be used to identify icons in programs. Most programmers use #defines (or their equivalent) instead of numbers at the moment, but this will automate the process, by generating one or more header files containing the #defines/equates necessary. The programmer would use a template editor to associate names with icons. The reasoning behind this is: * People are more likely to adopt a standard if it is initially simple and provides some feature they like (e.g. like saving them the trouble of checking icon numbers). I certainly need it - some windows I use have in excess of 100 icons. * People are more likely to *comment* on a standard if the basic framework is put in place and then extensions are added as and when required. People are, I think, less likely to wade through a 35-page document that comes at them from nowhere, like some electronic custard pie. And if people don't comment on it, some important feature may be missed, causing the standard to fall from favour, and hence from use. * If a simple standard is put forward, it will be agreed on reasonably quickly (I hope!) and it can start to be used. If some huge standard is introduced it will be argued over for ages and will probably die. I don't want this - I want something I can use, without having to keep on re-inventing wheels. This concept may pass over the heads of ARM assembler programmers ;-) * I don't have time at present to think in depth about all the features required and produce a *complete* standard. And if I can't think about it in depth, I'll probably get it wrong, and I don't want to do that. * The important thing is to have an extensible standard! Chunk files make this possible. The Proposed Standard ===================== Basic Format ~~~~~~~~~~~ As mentioned, the file will be a chunk file as specified in the Acorn C (and, I assume, Objasm) manuals. For Desktop C, it's on pp226-228 of the "Acorn Desktop Development Environment" manual. If anyone doesn't have access to it I'm sure myself or someone else could outline the format if necessary. In this explanation, the chunk file offset for Glass files is assumed to be "GLS_". Chunks in Glass files ~~~~~~~~~~~~~~~~~~~~ Name Use ~~~ ~~~ GLS_INFO Miscellaneous info about this file and the Glass version it conforms to. GLS_FONT Maps fonthandles used in Glass file to Risc OS font names. GLS_WIND Window and icon definitions (much the same as Templates) GLS_NAME Names used to refer to icons and icon groups. Chunk formats ~~~~~~~~~~~~ Bear in mind throughout these descriptions that we know the total size of each chunk from the chunk file header. Also, please bear in mind that although some structures may seem slightly wasteful of memory, this is the format of a disc file, and these wastages may not necessarily translate into memory wastages (e.g. indexes will only be used while loading the file, and then wholly or partially discarded). GLS_INFO ======== Chunk Field Field Name & Offset: Size: Meaning: 0 4 Info_HeaderSize Size of this header in bytes. 4 4 Info_GlassVersion This is the version of the Glass Format that this file conforms to. An unsigned word, at present assigned as follows: MSB LSB AAAABBCC where: AA = reserved BB = Major version number CC = Minor version number So version 2.12 would be encoded as &0000020C. 8 4 Info_CreatorName Chunk offset of a null-terminated string indicating the program that created this Glass file. e.g. "TemplEd" or "Glazier" Comments ~~~~~~~ Good so far, innit? GLS_FONT ======== Chunk Field Field Name & Offset: Size: Meaning: Header: 0 4 Font_HeaderSize - size of header in bytes 4 5 Font_TimeStamp - time stamp of this chunk 9 3 Reserved - must be 0 12 4 Font_Num (0 => no fonts used in Glass file) Number of font handles defined in this chunk. Font handles always numbered 0 to Font_Num-1. Font handle index: i+0 4 Font_Offset 0 Chunk offset to font data for handle 0. i+4 4 Font_Offset 1 Chunk offset to font data for handle 1. ... i+(n-1*4) 4 Font_Offset n-1 Chunk offset to font data for handle n-1. Font data entries: (pointed to by index entries) d+0 4 Font_XSize x point size * 16 d+4 4 Font_YSize y point size * 16 d+8 ? Font_Name A null-terminated string. (e.g. "Trinity.Medium.Italic\0") Comments ~~~~~~~ If no GLS_FONT chunk, it is assumed the file uses no anti-aliased fonts. The font data entries must be word aligned. GLS_WIND ======== Chunk Field Field Offset: Size: Meaning: Header: 0 4 Wind_HeaderSize - size of this header in bytes 4 5 Wind_TimeStamp - time stamp of this chunk 9 1 Wind_Flags - flag field for this window chunk. At present the following flags are defined: bit 0: Wind_AntiAliased 0 => This window chunk primarily uses the System font. 1 => This window chunk primarily uses anti-aliased fonts bit 1: Window_ThreeD 0 => This window chunk primarily uses 'standard' Risc OS icons 1 => This window chunk primarily uses 3D 'bordered' icons to achieve a 3D look and feel. All other bits in this word should be 0. 10 2 Reserved - must be 0 12 4 Wind_NumWindows - number of windows defined in this chunk. 16 4 Wind_WindDefnSize Size of the Wind_WindDefn Fields in window data blocks (see below). At present 88, but may change. 20 4 Wind_IconDefnSize Size of the IconDefn fields in window data blocks (see below). At present 32, but may change. 24 4 Wind_IndexSize - size of index entries At present it is 36. 28 4 Wind_MessageFile Chunk offset of 0-terminated filename of the message file to use to expand message tags. 0 if the default message file (whatever that means to the programmer's library) is to be used, or if no message tags are used. Index: i+0 12 Wind_Id A null-terminated string identifying the window. e.g. "ProgInfo". i+12 4 Wind_Offset Chunk offset for data for this window entry. i+16 4 Wind_Size Size of data for this window entry. i+20 4 Wind_IndDataOffset Chunk offset of indirected data for this window. i+24 4 Wind_IndDataSize Size of indirected data for this entry. i+28 4 Wind_NumGroups Number of icon groups for this window. i+32 4 Wind_GroupOffset Chunk offset of group definitions for this entry. i+Wind_IndexSize Start of next index entry (i.e. Wind_Id). Window Data blocks: d+0 88 Wind_WindDefn A window definition block as passed to the SWI Wimp_CreateWindow, with the exceptions noted below. The number of icons is explicitly obtained from this block from the usual field (d+84). d+88 32 Wind_IconDefn 0 Icon definition for first icon of this window (if any). Block is as passed to the SWI Wimp_CreateIcon, with the exceptions noted below. d+120 32 Wind_IconDefn 1 etc... Indirected Data blocks (pointed to by Wind_IndDataOffset): Free-form entries, of byte resolution, but each entry *must* be terminated by a 0. Entries for icons such as writable icons which may have a large buffer but only a short string initially should be padded to full length with 0s. This is to ensure that the indirected data size returned by the Glass SWI is correct. Icon Group Blocks (pointed to by Wind_GroupOffset): g+0 12 Group_Name Null-terminated string describing group. Unique within the icon group block. Used in conjunction with the GLS_NAME chunk. g+12 4 Group_Type for icon group 0. 0 => Positional group. No other group types allocated. g+16 4 Group_NumIcons Number of icons in this group. g+20 4 Handle of first icon of this group g+24 4 Handle of second icon of this group. ... 4 Handle of last icon in this group. Followed by the rest of the icon group definitions. Comments ~~~~~~~ Window chunk flags ~~~~~~~~~~~~~~~~~ These flags are, at present, mainly used for customising which set of templates an application loads. The Glass file may contain only one type of templates - the Glass loader routine will attempt a 'best-fit' approach to choosing which set to load. The caller will supply the flags to match when loading template sets. There must *not* be more than one window chunk with the same flags. In practice, at run-time, only one GLS_WIND chunk will be loaded. Window data blocks ~~~~~~~~~~~~~~~~~ Offsets in these blocks should not be taken to be valid forever - use Wind_WindDefnSize and Wind_IconDefnSize to ensure any embarrassments are avoided. Window data blocks need not be in the order they appear in the index, so long as the chunk offsets are correct. They need not be contiguous in the chunk either. The exceptions in window/icon definition blocks are as follows: Sprite area control block pointers ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In Glass files, sprite areas are interpreted as follows: 0 => Default application sprite area 1 => Wimp sprite area Option for indirected sprite-only icons only: 2 => Use this window's sprite area pointer. Option for window sprite areas only: Any other value => Offset into indirected data area which specifies filename of sprite file to be used for this window. This string may be a message tag - see below. Indirected data ~~~~~~~~~~~~~~ When indirected icons (including the window title bar) occur, the datum for a sprite name, text buffer or a validation string is actually divided into two fields, flags and offset: MSB LSB FFOOOOOO The 8-bit FF field is a flag field. These flags will be allocated for various purposes as and when they become necessary. At present, only the most significant bit of the flags is allocated - it is the 'message tag bit' - if clear, the indirected data is the actual data to use in the icon, if not, it is the message tag to use to look up the actual data. The message tag format is undefined - i.e. msgstrans or DeskLib format tags or anything else is legal. The OOOOOO field is a 24-bit offset value. This allows for indirected data blocks of up to 16Mb in size - this should be sufficient for most occasions. I am open to the suggestion that this field be defined as 16 bits of flag and 16 bits of offset. Font handles ~~~~~~~~~~~ These are, of course, the internal font handles used throughout the Glass file, and not font handles as understood by the Risc OS FontManager module. The GLS_FONT chunk can be used to convert them to real font handles - this will usually be done by the library routines that support Glass files. Groups ~~~~~ So far, only positional groups have been allocated a group type (0). Positional groups are groups of icons that are treated as a unit in a Glass editor - they are moved in one operation etc, like a group in !Draw. GLS_NAME ======== Chunk Field Field Offset: Size: Meaning: Header: 0 4 Name_HeaderSize Size in bytes of this header 4 5 Name_TimeStamp Standard 5-byte Risc OS Time stamp. See Risc OS 2 PRMs, p550, "Real time". 9 1 Name_Flags - the flag field for this name chunk. At present the following flags are defined: bit 0: Name_AntiAliased 0 => This name chunk refers to the GLS_WIND chunk that primarily uses the System font. 1 => This name chunk refers to the GLS_WIND chunk that primarily uses anti-aliased fonts bit 1: Name_ThreeD 0 => This name chunk refers to the GLS_WIND chunk that primarily uses 'standard' Risc OS icons 1 => This name chunk refers to the GLS_WIND chunk that primarily uses 3D 'bordered' icons to achieve a 3D look and feel. All other bits in this word should be 0. 10 2 Reserved - must be 0 12 4 Name_IconPrefix Chunk offset of null-terminated string specifying the global prefix for icon names. 0 => no prefix. 16 4 Name_IconSuffix Chunk offset of null-terminated string specifying the global suffix for icon names. 0 => no suffix. 20 4 Name_GroupPrefix Chunk offset of null-terminated string specifying the global prefix for group names. 0 => no prefix. 24 4 Name_GroupSuffix Chunk offset of null-terminated string specifying the global suffix for group names. 0 => no suffix. 28 4 Name_IndexSize Size in bytes of name index entries. Window name index entries: i+0 12 Name_WindowId Window ID of the window this naming block refers to. (see GLS_WIND chunk details). i+12 4 Name_WindowPrefix Chunk offset of null-terminated string specifying the prefix for names of icons in this window. 0 => no prefix. i+16 4 Name_WindowSuffix Chunk offset of null-terminated string specifying the suffix for names of icons in this window. 0 => no suffix. i+20 4 Name_IconOffset Chunk offset of icon name block for this window. i+Name_IndexSize Next index entry Icon name block: i+0 4 Name_IconName 0 Chunk offset of null-terminated string specifying the name of icon 0 of this window 0 => anonymous icon i+4 4 Name_IconName 1 Chunk offset of null-terminated string specifying the name of icon 1 of this window 0 => anonymous icon ... i+4*n 4 Name_IconName n-1 Chunk offset of null-terminated string specifying the name of icon (n-1) of this window 0 => anonymous icon i+4+4*n ? Data for icon names... Comments ~~~~~~~ There is a window name index entry + icon name block for each window that contains icons referenced by name. Hence a window with no icons referenced by name (eg a window with no icons such as Edit's main window) would not have a window name index entry or icon name block. As with the GLS_WIND chunk, although there may be multiple GLS_NAME chunks in the file, only one is loaded at run-time, according to flags passed to the Glass loader by the client application. Icon/Group names have 5 components, all but one of which, the actual icon or group name, may be null. These may be combined in one of two orders: (Icon is used here but these orders also apply to groups) Name_IconPrefix + Name_WindowPrefix + Name_IconName + Name_WindowSuffix + Name_IconSuffix OR ~~ Name_WindowPrefix + Name_IconPrefix + Name_IconName + Name_IconSuffix + Name_WindowSuffix This allows for (almost) any naming scheme the user can think of. The actual ordering used is not specified in the file - it is specified to the Glass support module when decoding names. There may not be two windows with the same name, two icon groups with the same name, or two icons with the same name. 'name' here means the full name, i.e. after all the prefixes/suffixes have been added. End Of Proposed Standard ------ oOo ------ Glass Relocatable Module ======================== There will be support for the Glass file format in the form of a relocatable module (RM), which will provide SWIs to access and use Glass files. A number of these will be analogues of Wimp SWIs for handling template. I have a volunteer to write the first version of this module, and I hope to be able to thrash out the details of the SWIs with him soon. Below are some tentative ideas about what should be provided. Contact me if you think anything's been missed. It seems to me that without careful thought, SWI number allocations can be 'wasted' by not bothering with reason codes and just having a different SWI for everything, and then realising a new chunk is needed - for this reason only two SWIs are defined so far. Obviously this requires an official SWI chunk from Acorn, so I am writing to request one (as well as an official chunk file prefix). SWIs: Glass_FileOp ============ Operations on Glass files. Reason codes: Glass_FileOp 0 : Open Glass File Glass_FileOp 1 : Close Glass File Glass_FileOp 2 : Load Window Template Glass_FileOp 3 : Load Name Information Glass_FileOp 4 : Get File Version Information Glass_NameOp ============ Services to decode icon/group names. Reason codes: Glass_NameOp 0 : Decode icon name Glass_NameOp 1 : Decode group name Registering message tags converters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ It was an interesting exercise collecting all the comments on Glass as I kept coming up with solutions to problems I thought quite neat, only to discover that someone else had come up with the same idea a few messages later :-(. Anyway, one of the main points of interest was the issue of message tags. It would be nice to 'msgtrans' the whole window template(s) automatically down to the level of icon text. This is supported by the format at present, but the client has to convert the messages 'by hand'. I thought (and so did TMOTA) that the ideal solution would be to register a message tag converter function which the Glass module would use to convert the messages automatically when loading a template. The only problem with this is that as far as I can tell, the main systems in use are Acorn's msgtrans module, RISCOS_lib's msgs module, and DeskLib's Msgs module, and these all work in different ways, and have different calling patterns. As I see it, there are two solutions: (1) Define a standard function type/interface to be registered with the Glass module. Then the client can write a veneer (or use a standard one) for whatever function they want to use. (2) Support the main libraries used, and specify what 'type' the function being registered is - i.e. DeskLib/RISCOS_lib/msgtrans. Personally I prefer (1), but I would welcome comments on this. Obviously, if option (2) is supported, then option (1) is too, with no extra work. (i.e. choose the function type closest to the one you use and write a veneer for it). Another connected problem is that it would be nice to specify message tags in the Glass file but not have to provide a tag. i.e. in a similar way to the DeskLib automatic help handler, if the indirected data field of an icon has the message tag bit set, but the chunk offset is 0, then a tag is synthesised using the window name and icon number, e.g. proginfo.1 options.3 and so on. The problem is that there are different syntaxes for message tags around. Some are nicer than others, but ideally all should be supported. Again, maybe a small set of different syntaxes could be supported rather like the support for different call patterns of message tags conversion functions. Comments please! This facility would make de-nationalising templates very easy as a Glass file editor could then have an option to save a de-nationalised version and automatically generate the message tags directly from the icon data. Scene of the Crime ================== If anyone wants to contact me, I read comp.sys.acorn{,.tech}, and occasionally post to it. I am omni-present on Arcade BBS's message areas. Arcade is a UK ANSI board: 081-654-2212/081-655-4412, most speeds. Prefix with international code if outside UK, and probably lose the 0 from the front of 081 too, I shouldn't wonder. Failing that you might be able to get me on internet: tbrowse@thorn-emi-crl.co.uk <---- N.B. This is a new address. (And it may even work!) Failing that, Snailmail: 1, Arkle House, 6, Chiltern View Road, Uxbridge, Middlesex. UB8 2PA United Kingdom. I think that's it - I await your comments. I'll pursue the module SWI interface and post it when it's half decent. Cheers, Tim Browse