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

  1. // **************************************************************************
  2. //                     Copyright 1996 David Allison
  3. //
  4. //             VV    VV    IIIIII     SSSSS     TTTTTT       AA
  5. //             VV    VV      II      SS           TT       AA  AA
  6. //             VV    VV      II        SSSS       TT      AA    AA
  7. //              VV  VV       II           SS      TT      AAAAAAAA
  8. //                VV       IIIIII     SSSS        TT      AA    AA
  9. //
  10. //                    MULTI-THREADED C++ WIMP CLASS LIBRARY
  11. //                                for RISC OS
  12. // **************************************************************************
  13. //
  14. //             P U B L I C    D O M A I N    L I C E N C E
  15. //             -------------------------------------------
  16. //
  17. //     This library is copyright. You may not sell the library for
  18. //     profit, but you may sell products which use it providing
  19. //     those products are presented as executable code and are not
  20. //     libraries themselves.  The library is supplied without any
  21. //     warranty and the copyright owner cannot be held responsible for
  22. //     damage resulting from failure of any part of this library.
  23. //
  24. //          See the User Manual for details of the licence.
  25. //
  26. // *************************************************************************
  27.  
  28.  
  29. //
  30. // template.c
  31. //
  32.  
  33. #include <stdio.h>
  34. #include <stdlib.h>
  35. #include <ctype.h>
  36. #include <string.h>
  37. #include "Vista:template.h"
  38. #include "Vista:task.h"
  39. #include "Vista:icon.h"
  40.  
  41.  
  42. static int read_word(FILE *fp)
  43.    {
  44.    int w ;
  45.    w = fgetc(fp) ;
  46.    w |= fgetc(fp) << 8 ;
  47.    w |= fgetc(fp) << 16 ;
  48.    w |= fgetc(fp) << 24 ;
  49.    return w ;
  50.    }
  51.  
  52. static void read_string(FILE *fp, char *s)
  53.    {
  54.    int i = 1 ;
  55.    while (!iscntrl(*s++ = fgetc(fp)))
  56.       i++ ;
  57.    s[-1] = 0 ;                        // overwrite ctrl char with EOS
  58.    while (i < 12)                     // skip up to 12 bytes
  59.       {
  60.       fgetc(fp) ;
  61.       i++ ;
  62.       }
  63.    }
  64.  
  65. //
  66. // relocate any indirect icons in the window definition
  67. //
  68.  
  69. struct icon_block
  70.    {
  71.    char pad[16] ;
  72.    int flags ;
  73.    IconData data ;
  74.    } ;
  75.  
  76. struct window_defn
  77.    {
  78.    char pad1[56] ;        // up to title icon flags
  79.    int title_flags ;
  80.    char pad2[12] ;
  81.    IconData title ;       // title icon data
  82.    int num_icons ;
  83.    icon_block icons[1] ;
  84.    } ;
  85.  
  86. static void relocate_icon (window_defn *w, IconData *icon)
  87.    {
  88.    char *p, *q ;
  89.    int offset ;
  90.    int length ;
  91.    char *buffer ;
  92.    int start = (int)w ;
  93.    offset = (int)icon->indirecttext.buffer ;
  94.    length = icon->indirecttext.bufflen ;
  95.    if (length > 0)
  96.       {
  97.       buffer = (char*)malloc (length) ;
  98.       if (buffer == NULL)
  99.          throw ("Out of memory") ;
  100.       p = (char*)(start + offset) ;
  101.       q = buffer ;
  102.       while (!iscntrl (*p))
  103.          *q++ = *p++ ;
  104.       *q = *p ;
  105.       icon->indirecttext.buffer = buffer ;
  106.       }
  107.    offset = (int)icon->indirecttext.validstring ;
  108.    if (offset > 1)
  109.       icon->indirecttext.validstring = (char*)(start + offset) ;
  110.    }
  111.  
  112. static void relocate_indirect_icons (TemplateEntry *entry)
  113.    {
  114.    window_defn *w = (window_defn*)entry->data ;
  115.    char *p, *q ;
  116.    int offset ;
  117.    int length ;
  118.    int i ;
  119.    char *buffer ;
  120.  
  121.    if (w->title_flags & Icon::INDIRECT)                 // is title indirect
  122.       relocate_icon (w, &w->title) ;
  123.    for (i = 0 ; i < w->num_icons ; i++)
  124.       {
  125.       if (w->icons[i].flags & Icon::INDIRECT)
  126.          relocate_icon (w, &w->icons[i].data) ;
  127.       }
  128.    }
  129.  
  130. static void copy_icon (window_defn *w, IconData *icon)
  131.    {
  132.    char *p = icon->indirecttext.buffer ;
  133.    int length = icon->indirecttext.bufflen ;
  134.    if (length > 0)
  135.       {
  136.       char *buffer = (char*)malloc (length) ;
  137.       if (buffer == NULL)
  138.          throw ("Out of memory") ;
  139.       char *q = buffer ;
  140.       while (!iscntrl (*p))
  141.          *q++ = *p++ ;
  142.       *q = *p ;
  143.       icon->indirecttext.buffer = buffer ;
  144.       }
  145.    }
  146.  
  147.  
  148. static void *copy_template (TemplateEntry *entry)
  149.    {
  150.    window_defn *w = (window_defn*)entry->data ;
  151.    window_defn *win = (window_defn*)new char [entry->size] ;
  152.    memcpy (win, w, entry->size) ;
  153.    if (win->title_flags & Icon::INDIRECT)
  154.       copy_icon (win, &win->title) ;
  155.    for (int i = 0 ; i < win->num_icons ; i++)
  156.       {
  157.       if (win->icons[i].flags & Icon::INDIRECT)
  158.          copy_icon (win, &win->icons[i].data) ;
  159.       }
  160.    return win ;
  161.    }
  162.  
  163. static void free_icon (IconData *icon)
  164.    {
  165.    char *p = icon->indirecttext.buffer ;
  166.    int length = icon->indirecttext.bufflen ;
  167.    if (length > 0)
  168.       free (p) ;
  169.    }
  170.  
  171.  
  172. Template::Template (Task *task, char *filename)
  173.    {
  174.    FILE *fp ;
  175.    int value ;
  176.    TemplateEntry *entry ;
  177.    IconData *icon ;
  178.    int font_offset ;
  179.  
  180. //   t->print ("opening templates, this = %x\n",this) ;
  181.    if ((fp = fopen (filename, "r")) == NULL)
  182.       throw ("Can't open Templates") ;
  183.    templates = NULL ;
  184.    font_offset = read_word (fp) ;           // read font offset
  185.    read_word(fp) ;                    // ignore
  186.    read_word(fp) ;                    // ignore
  187.    read_word(fp) ;                    // ignore
  188.    while ((value = read_word(fp)) != 0)
  189.       {
  190.       entry = new TemplateEntry ;
  191.       entry->offset = value ;
  192.       entry->size = read_word(fp) ;
  193.       entry->type = read_word(fp) ;
  194.       read_string (fp, entry->name) ;
  195.       entry->next = templates ;
  196.       templates = entry ;
  197.       }
  198.    for (entry = templates ; entry != NULL ; entry = entry->next)
  199.       {
  200.       entry->data= new char [entry->size] ;
  201.       if (fseek (fp, entry->offset, SEEK_SET) != 0)
  202.          throw ("Can't seek to template offset") ;
  203.       if (fread (entry->data, 1, entry->size, fp) != entry->size)
  204.          throw ("Failed to read template") ;
  205.       relocate_indirect_icons(entry) ;
  206.       }
  207.    if (font_offset != -1)
  208.       {
  209.       int xsize ;
  210.       int ysize ;
  211.       char name[48] ;
  212.       if (fseek (fp, font_offset, SEEK_SET) != 0)
  213.          throw ("Can't seek to font offset") ;
  214.       while (!feof (fp))
  215.          {
  216.          xsize = read_word (fp) ;
  217.          if (xsize == EOF)
  218.             break ;
  219.          ysize = read_word (fp) ;
  220.          fread (name, 1, 40, fp) ;
  221.          task->open_font (name, xsize, ysize) ;
  222.          }
  223.       }
  224.    fclose (fp) ;
  225. //   t->print ("finished, templates = %x, &templates = %x\n",templates, &templates) ;
  226.    }
  227.  
  228. Template::~Template()
  229.    {
  230.    TemplateEntry *entry, *next ;
  231. //   t->print ("delete templates") ;
  232.    for (entry = templates ; entry != NULL ; entry = next)
  233.        {
  234.        next = entry->next ;
  235.        delete [] entry->data ;
  236.        delete entry ;
  237.        }
  238.    }
  239.  
  240. void *Template::find(char *name)
  241.    {
  242. //   t->print ("finding template %s, this = %x. templates = %x, &templates = %x", name,this, templates, &templates) ;
  243.    for (TemplateEntry *entry = templates ; entry != NULL ; entry = entry->next)
  244.       {
  245. //      t->print ("looking at %s",entry->name);
  246.        if (strcmp (name, entry->name) == 0)
  247.           return copy_template (entry) ;
  248.       }
  249.    return NULL ;
  250.    }
  251.  
  252. void Template::free (void *defn)
  253.    {
  254.    window_defn *w = (window_defn*)defn ;
  255.    if (w->title_flags & Icon::INDIRECT)
  256.       free_icon (&w->title) ;
  257.    for (int i = 0 ; i < w->num_icons ; i++)
  258.       {
  259.       if (w->icons[i].flags & Icon::INDIRECT)
  260.          free_icon (&w->icons[i].data) ;
  261.       }
  262.    delete [] (char*)defn ;
  263.    }
  264.  
  265.