home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 1 / ARM_CLUB_CD.iso / contents / apps / clib / progs / haswinlib / c / templates < prev    next >
Encoding:
Text File  |  1991-02-04  |  16.0 KB  |  378 lines

  1. /* > $.CLIB.C.templates
  2.  *
  3.  *      HASWIN Graphics Library
  4.  *     =========================
  5.  *
  6.  *      Copyright (C) H.A.Shaw 1990.
  7.  *              Howard A. Shaw.
  8.  *              The Unit for Space Sciences,
  9.  *              Room 165,
  10.  *              Physics Building,
  11.  *              University of Kent at Canterbury.
  12.  *              Canterbury.
  13.  *              Kent.  CT2 7NJ
  14.  *      You may use and distribute this code freely, however please leave
  15.  *      it alone.  If you find bugs (and there will be many) please contact
  16.  *      me and the master source can be modified.  If you keep me informed
  17.  *      of who you give copies of this to then I can get release upgrades
  18.  *      to them.
  19.  *
  20.  *      Routines to deal with templates.  Since the WIMP allows only one
  21.  *      template to be open at a time we implement a stack.
  22.  */
  23. #include "includes.h"
  24.  
  25. /*
  26.  *      we can stack open template files up to HASWIN_MAXTEMPLATES levels
  27.  */
  28. #define HASWIN_MAXTEMPLATES 16
  29. static char    (haswin_templatestack[256])[HASWIN_MAXTEMPLATES];
  30. static int     haswin_templatestackptr = 0;
  31.  
  32. void haswin_closetemplate() {
  33.  
  34.         if (haswin_flags & HASWIN_FLAGS_TEMPLATE) {
  35.                 if (haswin_templatewspace) {
  36.                         if (!haswin_free(haswin_templatewspace))
  37.                                 haswin_errorbox("haswin_closetemplate: cannot free template workspace");
  38.                         haswin_templatewspace = 0;
  39.                 }
  40.                 if (haswin_templateptr) {
  41.                         if (!haswin_free(haswin_templateptr))
  42.                                 haswin_errorbox("haswin_closetemplate: cannot free template indirect space");
  43.                         haswin_templateptr = 0;
  44.                 }
  45.                 if (!haswin_swi(HASWIN_Close_template, 0))
  46.                         return;
  47.                 haswin_flags &= ~HASWIN_FLAGS_TEMPLATE;
  48.         }
  49. }
  50.  
  51. /*
  52.  *      open a template file.
  53.  */
  54. int haswin_opentemplate(char *filename) {
  55.  
  56.         int                     fsize;
  57.         _kernel_swi_regs        regs;
  58.  
  59.         if (haswin_flags & HASWIN_FLAGS_TEMPLATE)
  60.                 return(HASWIN_FALSE);
  61.         if ((!filename) || (filename[0] == '\0'))
  62.                 return(HASWIN_TRUE);
  63.         regs.r[0] = 5;          /* get file catalogue */
  64.         regs.r[1] = (int)filename;
  65.         if (!haswin_swi(OS_File, ®s))
  66.                 regs.r[0] = 0;
  67.         switch (regs.r[0]) {
  68.         case 0:
  69.                 haswin_interrorprintf("Cannot find template file %s", filename);
  70.                                 return(HASWIN_FALSE);
  71.         case 2:
  72.                 haswin_interrorprintf("Template file %s is a directory, not a file", filename);
  73.                 return(HASWIN_FALSE);
  74.         }
  75.         if ((regs.r[5] & 0x01) != 0x01) {
  76.                 haswin_interrorprintf("No read access for template file %s",filename);
  77.                 return(HASWIN_FALSE);
  78.         }
  79.         /* create a buffer for the templates.  If it is the size of the
  80.            file then it MUST be enough !! */
  81.         fsize = regs.r[4];
  82.         haswin_templatewspace = (char *)haswin_malloc(fsize, "haswin_opentemplate", "haswin_templatewspace");
  83.         /* create a buffer for the indirected data in the templates.  If it
  84.            is the size of the file then it MUST be enough !! */
  85.         haswin_templateptr = (char *)haswin_malloc(fsize, "haswin_opentemplate", "haswin_templateptr");
  86.         haswin_templateend = haswin_templateptr+fsize-1;
  87.         regs.r[1] = (int)filename;
  88.         if (!haswin_swi(HASWIN_Open_template, ®s))
  89.                  return(HASWIN_FALSE);
  90.         haswin_flags |= HASWIN_FLAGS_TEMPLATE;
  91.         return(HASWIN_TRUE);
  92. }
  93.  
  94. int haswin_pushtemplate(char *fname) {
  95.  
  96.         if (haswin_templatestackptr >= HASWIN_MAXTEMPLATES) {
  97.                 haswin_interrorprintf("haswin_pushtemplate: %s: too many templates on stack (max = %d)", fname, HASWIN_MAXTEMPLATES);
  98.                 return(HASWIN_FALSE);
  99.         }
  100.         /* close existing template */
  101.         haswin_closetemplate();
  102.         /* open the new template */
  103.         if (haswin_opentemplate(fname)) {
  104.                 strncpy(haswin_templatestack[haswin_templatestackptr++], fname, 256);
  105.                 return(HASWIN_TRUE);
  106.         }
  107.         return(HASWIN_FALSE);
  108. }
  109.  
  110. int haswin_poptemplate(void) {
  111.  
  112.         if (haswin_templatestackptr == 1) {
  113.                 haswin_closetemplate();
  114.                 haswin_templatestackptr = 0;
  115.                 return(HASWIN_TRUE);
  116.         } else if (haswin_templatestackptr == 0) {
  117.                         return(HASWIN_FALSE);
  118.         } else if (haswin_templatestackptr < 0) {
  119.                 haswin_interrorprintf("haswin_poptemplate: template stack empty");
  120.                 return(HASWIN_FALSE);
  121.         }
  122.         /* close existing template */
  123.         haswin_closetemplate();
  124.         /*
  125.          *      NB: we move the stack pointer even if the open fails
  126.          *          to stop infinite loops.
  127.          */
  128.         if (!haswin_opentemplate(haswin_templatestack[--haswin_templatestackptr]))
  129.                 return(HASWIN_FALSE);
  130.         return(HASWIN_TRUE);
  131. }
  132.  
  133. /*
  134.  *      get the window ident "title" from the template file.
  135.  *      "flags" are the USER part of the window flags.
  136.  *      Create all the icons required.
  137.  */
  138. window *haswin_loadwindow(char *title, int flags) {
  139.  
  140.         _kernel_swi_regs  regs;
  141.  
  142.         icon    *ic;
  143.         window  *wptr = 0;
  144.         int     i, numicons, *thisicon, *blk, sarea;
  145.         char    fonts[256], realtitle[256];
  146.  
  147.         if (!(haswin_flags & HASWIN_FLAGS_TEMPLATE)) {
  148.                 haswin_internalerror("A Template file is not open");
  149.                 return((window *)0);
  150.         }
  151.         /* clear the fonts array for this window */
  152.         for(i=0; i<256; fonts[i++]='\0')
  153.                 ;
  154.         regs.r[1] = (int)haswin_templatewspace;
  155.         regs.r[2] = (int)haswin_templateptr;
  156.         regs.r[3] = (int)haswin_templateend;
  157.         regs.r[4] = (int)fonts;
  158.    
  159.         strcpy(realtitle, title);
  160.         regs.r[5] = (int)realtitle;
  161.         regs.r[6] = 0;
  162.         if (!haswin_swi(HASWIN_Load_template, ®s))
  163.                 regs.r[6] = 0;
  164.         if (regs.r[6] == 0) {
  165.                 /* template window not found in file */
  166.                 haswin_interrorprintf("Window %s not found in Template file", title);
  167.                 return((window *)0);
  168.         }
  169.         for(i=0; i<256; i++)
  170.                 haswin_fontarray[i] += fonts[i];
  171.  
  172.         wptr=(window *)haswin_malloc(sizeof(window), "haswin_loadwindow", "wptr");
  173.         wptr->win = haswin_malloc(88, "haswin_loadwindow", "window win block");
  174.         ((int *)wptr->win)[ 0] = ((int *)haswin_templatewspace)[ 0];
  175.         ((int *)wptr->win)[ 1] = ((int *)haswin_templatewspace)[ 1];
  176.         ((int *)wptr->win)[ 2] = ((int *)haswin_templatewspace)[ 2];
  177.         ((int *)wptr->win)[ 3] = ((int *)haswin_templatewspace)[ 3];
  178.         ((int *)wptr->win)[ 4] = ((int *)haswin_templatewspace)[ 4];
  179.         ((int *)wptr->win)[ 5] = ((int *)haswin_templatewspace)[ 5];
  180.         ((int *)wptr->win)[ 6] = ((int *)haswin_templatewspace)[ 6];
  181.         ((int *)wptr->win)[ 7] = ((((int *)haswin_templatewspace)[ 7]&WINDOW_WIMPFLAGS) | WINDOW_FLAGS_OR) & ~WINDOW_FLAGS_AND;
  182.         wptr->flags = flags & WINDOW_HASFLAGS;
  183.         wptr->win[32] = haswin_templatewspace[32];
  184.         wptr->win[33] = haswin_templatewspace[33];
  185.         wptr->win[34] = haswin_templatewspace[34];
  186.         wptr->win[35] = haswin_templatewspace[35];
  187.         wptr->win[36] = haswin_templatewspace[36];
  188.         wptr->win[37] = haswin_templatewspace[37];
  189.         wptr->win[38] = haswin_templatewspace[38];
  190.         wptr->win[39] = 0;
  191.         ((int *)wptr->win)[10] = ((int *)haswin_templatewspace)[10];
  192.         ((int *)wptr->win)[11] = ((int *)haswin_templatewspace)[11];
  193.         ((int *)wptr->win)[12] = ((int *)haswin_templatewspace)[12];
  194.         ((int *)wptr->win)[13] = ((int *)haswin_templatewspace)[13];
  195.         ((int *)wptr->win)[14] = ((int *)haswin_templatewspace)[14] | 0x00000100;
  196.         ((int *)wptr->win)[15] = ((int *)haswin_templatewspace)[15];
  197.         wptr->button = ((((int *)haswin_templatewspace)[15])>>12) & 0x0F;
  198.         if (haswin_canbuttondrag(wptr->button))
  199.                 wptr->flags |= WINDOW_DRAGSEL|WINDOW_DRAGADJ;
  200. /* choose a sprite area control block. */
  201. /* if a specific area is not chosen, then choose the WIMP +1 area */
  202.         switch (flags & SPRITE_AREA_MASK) {
  203.         case SPRITE_SYSTEM_AREA:
  204.                 ((int *)wptr->win)[16] = 0;
  205.                 break;
  206.         case SPRITE_WIMP_AREA:
  207.         case SPRITE_RISCOS_AREA:
  208.                 ((int *)wptr->win)[16] = 1;
  209.                 break;
  210.         case SPRITE_HASWIN_AREA:
  211.                 ((int *)wptr->win)[16] = (int)haswin_haswinsprites;
  212.                 break;
  213.         case SPRITE_USER_AREA:
  214.                 ((int *)wptr->win)[16] = (int)haswin_usersprites;
  215.                 break;
  216.         default:
  217.                 haswin_interrorprintf("haswin_loadwindow: unknown sprite area %8.8X", flags & SPRITE_AREA_MASK);
  218.                 /* FALL THRU */
  219.         case 0:
  220.                 ((int *)wptr->win)[16] = +1;
  221.                 break;
  222.         }
  223.         ((int *)wptr->win)[17] = ((int *)haswin_templatewspace)[17];
  224.         if ((((int *)haswin_templatewspace)[14]) & 0x00000100) {
  225.                 ((int *)wptr->win)[18] = (int)haswin_malloc(((int *)haswin_templatewspace)[20], "haswin_loadwindow:", "indirected window title");
  226.                 strncpy((char *)((int *)wptr->win)[18], (char *)(((int *)haswin_templatewspace)[18]), ((int *)haswin_templatewspace)[20]);
  227.                 if ((((int *)haswin_templatewspace)[19] > 0) && (((int *)haswin_templatewspace)[14] & 0x00000002)) {
  228.                         ((int *)wptr->win)[19] = (int)haswin_malloc(asciilen((char *)(((int *)haswin_templatewspace)[19])), "haswin_loadwindow", "window title validation");
  229.                         strcpy((char *)(((int *)wptr->win)[19]), (char *)(((int *)haswin_templatewspace)[19]));
  230.                 } else
  231.                         ((int *)wptr->win)[19] = ((int *)haswin_templatewspace)[19];
  232.                 ((int *)wptr->win)[20] = ((int *)haswin_templatewspace)[20];
  233.         } else {
  234.                 ((int *)wptr->win)[18] = (int)haswin_malloc(13, "haswin_loadwindow:", "window title");
  235.                 strncpy((char *)((int *)wptr->win)[18], haswin_templatewspace + 72, 12);
  236.                 ((char *)((int *)wptr->win)[18])[12] = 0;
  237.                 ((int *)wptr->win)[19] = -1;
  238.                 ((int *)wptr->win)[20] = asciilen((char *)((int *)wptr->win)[18]);
  239.         }
  240.         numicons = ((int *)haswin_templatewspace)[21];
  241.         ((int *)wptr->win)[21] = 0;
  242.  
  243.         regs.r[1] = (int)wptr->win;
  244.         if ((!haswin_swi(HASWIN_Create_window, ®s)) || (regs.r[0] <= 0)) {
  245.                 haswin_free(wptr);
  246.                 return((window *)0);
  247.         }
  248.         wptr->handle = regs.r[0];
  249. /*
  250.  *      we have now created a window from the template.  There are no icons
  251.  *      in this window, as yet.
  252.  */
  253.         wptr->name = haswin_malloc(asciilen(realtitle)+1, "haswin_loadwindow", "window name");
  254.         strcpy(wptr->name, realtitle);
  255.         wptr->numicons = 0;
  256.         wptr->icons = (icon *)0;
  257.         wptr->orgx = wptr->orgy = 0;
  258.         wptr->mousebutton = (int (*)())0;
  259.         wptr->drawroutine = (int (*)())0;
  260.         wptr->dragroutine = (int (*)())0;
  261.         wptr->openroutine = (int (*)())0;
  262.         wptr->keyroutine = (int (*)())0;
  263.         wptr->pointer = (pointer *)0;
  264.         wptr->menu = (menu *)0;
  265.         wptr->scrollx = wptr->scrolly = 0;
  266.         wptr->pagex = wptr->pagey = 0;
  267.         wptr->picture = (char *)0;
  268.         wptr->text = (text *)0;
  269.         wptr->pane = wptr->slide = (window *)0;
  270.         wptr->caret = (caret *)0;
  271.         wptr->help = (window *)0;
  272.         wptr->helpmsg = (char *)0;
  273.         wptr->master = wptr;    /* window is its own master */
  274.         wptr->next = haswin_topwindow;
  275.         haswin_topwindow = wptr;
  276. /*
  277.  *      create the icons
  278.  */
  279.         for (i=0; i<numicons; i++) {
  280.                 thisicon = &(((int *)haswin_templatewspace)[22+i*8]);
  281.                 blk = (int *)haswin_malloc(36, "haswin_loadwindow", "icon SWI block");
  282.                 ic = (icon *)haswin_malloc(sizeof(struct icon), "haswin_loadwindow", "icon");
  283.                 blk[0] = ic->whandle = wptr->handle;
  284.                 blk[1] = thisicon[0];
  285.                 blk[2] = thisicon[1];
  286.                 blk[3] = thisicon[2];
  287.                 blk[4] = thisicon[3];
  288.                 /* our icons are ALWAYS indirected */
  289.                 blk[5] = thisicon[4] | 0x00000100;
  290.                 if (thisicon[4] & 0x00000100) {
  291.                         /* data is indirected */
  292.                         blk[6] = (int)haswin_malloc(thisicon[7]+1, "haswin_loadwindow", "indirected icon data");
  293.                         strncpy((char *)(blk[6]), (char *)(thisicon[5]), thisicon[7]);
  294.                         if ((thisicon[4] & 1) && (thisicon[6] > 0)) {
  295.                                 /* validation string */
  296.                                 blk[7] = (int)haswin_malloc(asciilen((char *)(thisicon[6]))+1, "haswin_loadwindow", "icon validation string");
  297.                                 strcpy((char *)(blk[7]), (char *)(thisicon[6]));
  298.                         } else
  299.                                 blk[7] = thisicon[6];
  300.                 } else {
  301.                         blk[6] = (int)haswin_malloc(13, "haswin_loadwindow", "icon data");
  302.                         strncpy((char *)(blk[6]), ((char *)thisicon)+20, 12);
  303.                         blk[7] = thisicon[6];
  304.                 }                        
  305.                 blk[8] = asciilen((char *)(blk[6]));
  306.                 if ((thisicon[4] & 0x03) == 0x02) {
  307.                         /* sprite only icon */
  308.                         sarea=haswin_findsprite((char *)(blk[6]));
  309.                         if (sarea == HASWIN_UNKNOWN) {
  310.                                 haswin_errorprintf("haswin_loadwindow: cannot find sprite area for sprite only icon '%s' in window '%s'", (char *)(blk[6]), wptr->name);
  311.                         } else
  312.                                 blk[7] = sarea;
  313.                 }
  314.                 ic->name = haswin_malloc(asciilen((char *)blk[6])+1, "haswin_createicon", "icon name buffer");
  315.                 strcpy(ic->name, (char *)blk[6]);
  316.                 ic->button = (blk[5]>>12) & 0x0F;
  317.                 ic->window = (window *)0;
  318.                 ic->menu = (menu *)0;
  319.                 ic->help = (window *)0;
  320.                 ic->helpmsg = (char *)0;
  321.                 if (haswin_canbuttondrag(ic->button))
  322.                         ic->flags = ICON_DRAGSEL|ICON_DRAGADJ;
  323.                 else 
  324.                         ic->flags = 0;
  325.                 ic->mousebutton = 0;
  326.                 ic->dragroutine = 0;
  327.                 regs.r[1] = (int)blk;
  328.                 if (haswin_swi(HASWIN_Create_icon, ®s)) {
  329.                         ic->ihandle = regs.r[0];
  330.                         blk[0] = blk[1];
  331.                         blk[1] = blk[2];
  332.                         blk[2] = blk[3];
  333.                         blk[3] = blk[4];
  334.                         blk[4] = blk[5];
  335.                         blk[5] = blk[6];
  336.                         blk[6] = blk[7];
  337.                         blk[7] = blk[8];
  338.                         blk[8] = 0;
  339.                         ic->ic = blk;
  340.                         ic->next = wptr->icons;
  341.                         wptr->icons = ic;
  342.                         wptr->numicons++;
  343.                 } else {
  344.                         haswin_errorprintf("haswin_loadtemplate: failed to create icon '%s' in window '%s'", haswin_geticontitle(ic), haswin_getwindowtitle(wptr));
  345.                         haswin_free((char *)(blk[6]));
  346.                         haswin_free(blk);
  347.                         haswin_free(ic->name);
  348.                         haswin_free(ic);
  349.                 }
  350.         }
  351.         return(wptr);
  352. }
  353.  
  354. window *haswin_loadpanewindow(window *top, char *title, int flags) {
  355.  
  356.         window  *win;
  357.  
  358.         win = haswin_loadwindow(title, flags|WINDOW_TRESPASS);
  359.         win->master = top;
  360.         while (top->pane)
  361.                 top=top->pane;
  362.         top->pane = win;
  363.         return(win);
  364. }
  365.  
  366. window *haswin_loadslidewindow(window *top, char *title, int flags) {
  367.  
  368.         window  *win;
  369.  
  370.         win = haswin_loadwindow(title, flags|WINDOW_TRESPASS);
  371.         win->master = top;
  372.         while (top->slide)
  373.                 top=top->slide;
  374.         top->slide = win;
  375.         return(win);
  376. }
  377.  
  378.