home *** CD-ROM | disk | FTP | other *** search
- // **************************************************************************
- // Copyright 1996 David Allison
- //
- // VV VV IIIIII SSSSS TTTTTT AA
- // VV VV II SS TT AA AA
- // VV VV II SSSS TT AA AA
- // VV VV II SS TT AAAAAAAA
- // VV IIIIII SSSS TT AA AA
- //
- // MULTI-THREADED C++ WIMP CLASS LIBRARY
- // for RISC OS
- // **************************************************************************
- //
- // P U B L I C D O M A I N L I C E N C E
- // -------------------------------------------
- //
- // This library is copyright. You may not sell the library for
- // profit, but you may sell products which use it providing
- // those products are presented as executable code and are not
- // libraries themselves. The library is supplied without any
- // warranty and the copyright owner cannot be held responsible for
- // damage resulting from failure of any part of this library.
- //
- // See the User Manual for details of the licence.
- //
- // *************************************************************************
-
-
- //
- // template.c
- //
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include <string.h>
- #include "Vista:template.h"
- #include "Vista:task.h"
- #include "Vista:icon.h"
-
-
- static int read_word(FILE *fp)
- {
- int w ;
- w = fgetc(fp) ;
- w |= fgetc(fp) << 8 ;
- w |= fgetc(fp) << 16 ;
- w |= fgetc(fp) << 24 ;
- return w ;
- }
-
- static void read_string(FILE *fp, char *s)
- {
- int i = 1 ;
- while (!iscntrl(*s++ = fgetc(fp)))
- i++ ;
- s[-1] = 0 ; // overwrite ctrl char with EOS
- while (i < 12) // skip up to 12 bytes
- {
- fgetc(fp) ;
- i++ ;
- }
- }
-
- //
- // relocate any indirect icons in the window definition
- //
-
- struct icon_block
- {
- char pad[16] ;
- int flags ;
- IconData data ;
- } ;
-
- struct window_defn
- {
- char pad1[56] ; // up to title icon flags
- int title_flags ;
- char pad2[12] ;
- IconData title ; // title icon data
- int num_icons ;
- icon_block icons[1] ;
- } ;
-
- static void relocate_icon (window_defn *w, IconData *icon)
- {
- char *p, *q ;
- int offset ;
- int length ;
- char *buffer ;
- int start = (int)w ;
- offset = (int)icon->indirecttext.buffer ;
- length = icon->indirecttext.bufflen ;
- if (length > 0)
- {
- buffer = (char*)malloc (length) ;
- if (buffer == NULL)
- throw ("Out of memory") ;
- p = (char*)(start + offset) ;
- q = buffer ;
- while (!iscntrl (*p))
- *q++ = *p++ ;
- *q = *p ;
- icon->indirecttext.buffer = buffer ;
- }
- offset = (int)icon->indirecttext.validstring ;
- if (offset > 1)
- icon->indirecttext.validstring = (char*)(start + offset) ;
- }
-
- static void relocate_indirect_icons (TemplateEntry *entry)
- {
- window_defn *w = (window_defn*)entry->data ;
- char *p, *q ;
- int offset ;
- int length ;
- int i ;
- char *buffer ;
-
- if (w->title_flags & Icon::INDIRECT) // is title indirect
- relocate_icon (w, &w->title) ;
- for (i = 0 ; i < w->num_icons ; i++)
- {
- if (w->icons[i].flags & Icon::INDIRECT)
- relocate_icon (w, &w->icons[i].data) ;
- }
- }
-
- static void copy_icon (window_defn *w, IconData *icon)
- {
- char *p = icon->indirecttext.buffer ;
- int length = icon->indirecttext.bufflen ;
- if (length > 0)
- {
- char *buffer = (char*)malloc (length) ;
- if (buffer == NULL)
- throw ("Out of memory") ;
- char *q = buffer ;
- while (!iscntrl (*p))
- *q++ = *p++ ;
- *q = *p ;
- icon->indirecttext.buffer = buffer ;
- }
- }
-
-
- static void *copy_template (TemplateEntry *entry)
- {
- window_defn *w = (window_defn*)entry->data ;
- window_defn *win = (window_defn*)new char [entry->size] ;
- memcpy (win, w, entry->size) ;
- if (win->title_flags & Icon::INDIRECT)
- copy_icon (win, &win->title) ;
- for (int i = 0 ; i < win->num_icons ; i++)
- {
- if (win->icons[i].flags & Icon::INDIRECT)
- copy_icon (win, &win->icons[i].data) ;
- }
- return win ;
- }
-
- static void free_icon (IconData *icon)
- {
- char *p = icon->indirecttext.buffer ;
- int length = icon->indirecttext.bufflen ;
- if (length > 0)
- free (p) ;
- }
-
-
- Template::Template (Task *task, char *filename)
- {
- FILE *fp ;
- int value ;
- TemplateEntry *entry ;
- IconData *icon ;
- int font_offset ;
-
- // t->print ("opening templates, this = %x\n",this) ;
- if ((fp = fopen (filename, "r")) == NULL)
- throw ("Can't open Templates") ;
- templates = NULL ;
- font_offset = read_word (fp) ; // read font offset
- read_word(fp) ; // ignore
- read_word(fp) ; // ignore
- read_word(fp) ; // ignore
- while ((value = read_word(fp)) != 0)
- {
- entry = new TemplateEntry ;
- entry->offset = value ;
- entry->size = read_word(fp) ;
- entry->type = read_word(fp) ;
- read_string (fp, entry->name) ;
- entry->next = templates ;
- templates = entry ;
- }
- for (entry = templates ; entry != NULL ; entry = entry->next)
- {
- entry->data= new char [entry->size] ;
- if (fseek (fp, entry->offset, SEEK_SET) != 0)
- throw ("Can't seek to template offset") ;
- if (fread (entry->data, 1, entry->size, fp) != entry->size)
- throw ("Failed to read template") ;
- relocate_indirect_icons(entry) ;
- }
- if (font_offset != -1)
- {
- int xsize ;
- int ysize ;
- char name[48] ;
- if (fseek (fp, font_offset, SEEK_SET) != 0)
- throw ("Can't seek to font offset") ;
- while (!feof (fp))
- {
- xsize = read_word (fp) ;
- if (xsize == EOF)
- break ;
- ysize = read_word (fp) ;
- fread (name, 1, 40, fp) ;
- task->open_font (name, xsize, ysize) ;
- }
- }
- fclose (fp) ;
- // t->print ("finished, templates = %x, &templates = %x\n",templates, &templates) ;
- }
-
- Template::~Template()
- {
- TemplateEntry *entry, *next ;
- // t->print ("delete templates") ;
- for (entry = templates ; entry != NULL ; entry = next)
- {
- next = entry->next ;
- delete [] entry->data ;
- delete entry ;
- }
- }
-
- void *Template::find(char *name)
- {
- // t->print ("finding template %s, this = %x. templates = %x, &templates = %x", name,this, templates, &templates) ;
- for (TemplateEntry *entry = templates ; entry != NULL ; entry = entry->next)
- {
- // t->print ("looking at %s",entry->name);
- if (strcmp (name, entry->name) == 0)
- return copy_template (entry) ;
- }
- return NULL ;
- }
-
- void Template::free (void *defn)
- {
- window_defn *w = (window_defn*)defn ;
- if (w->title_flags & Icon::INDIRECT)
- free_icon (&w->title) ;
- for (int i = 0 ; i < w->num_icons ; i++)
- {
- if (w->icons[i].flags & Icon::INDIRECT)
- free_icon (&w->icons[i].data) ;
- }
- delete [] (char*)defn ;
- }
-
-