home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Acorn User 2
/
AUCD2.iso
/
program
/
vista.arc
/
c
/
template
< prev
next >
Wrap
Text File
|
1996-02-01
|
7KB
|
265 lines
// **************************************************************************
// 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 ;
}