% SUBJECT: Professional GEM, Appendix C
% 12.11.90
%

\subsection{Folder {\tt $\backslash$rsconv}}
\nopagebreak

\subsubsection{\tt rsconv.h}

\begin{verbatim} 
#define MODE 0          /* TREE */
#define N2F 7           /* OBJECT in TREE #0 */
#define F2N 8           /* OBJECT in TREE #0 */
#define DEF2 15         /* OBJECT in TREE #0 */
#define HELPMODE 21     /* OBJECT in TREE #0 */
#define CONVMODE 22     /* OBJECT in TREE #0 */
#define QUITMODE 23     /* OBJECT in TREE #0 */
#define NODEF 0         /* STRING */
#define DEFYES 18       /* OBJECT in TREE #0 */
#define DEFNO 19        /* OBJECT in TREE #0 */
#define HELP 1          /* TREE */
#define NOMEM 1         /* STRING */
#define DFNYES 20       /* OBJECT in TREE #0 */
#define DEF1 13         /* OBJECT in TREE #0 */
#define RSC1 10         /* OBJECT in TREE #0 */
#define RSC2 12         /* OBJECT in TREE #0 */
#define PROGRESS 2      /* TREE */
#define STRINGS 3       /* TREE */
#define PLINE 2         /* OBJECT in TREE #2 */
#define IMGALIGN 2      /* OBJECT in TREE #3 */
#define RSCREAD 1       /* OBJECT in TREE #3 */
#define BYTESWAP 3      /* OBJECT in TREE #3 */
#define RSCWRITE 4      /* OBJECT in TREE #3 */
#define DEFREAD 5       /* OBJECT in TREE #3 */
#define DEFWRITE 6      /* OBJECT in TREE #3 */

\end{verbatim}
\newpage

\subsubsection{\tt rcfile.c}
\begin{verbatim} 
/*------------------------------*/
/*      includes                */
/*------------------------------*/

#include "portab.h"     /* portable coding conv */
#include "machine.h"    /* machine depndnt conv */
#include "osbind.h"     /* BDOS defintions      */
#include "gemdefs.h"

/*------------------------------*/
/*      open_file               */
/*------------------------------*/
        WORD
open_file(file_name)
        BYTE    *file_name;
        {
        LONG    dos_hndl;

        FOREVER
                {
                dos_hndl = Fopen(file_name, 0);
                if (dos_hndl >= 0)
                        return ((WORD) dos_hndl);
                if ( !dos_error((WORD) dos_hndl) )
                        return (-1);
                }

        return (-1);            /* Appease lint */
        }

/*------------------------------*/
/*      create_file             */
/*------------------------------*/
        WORD
create_file(file_name)
        BYTE    *file_name;
        {
        LONG    dos_hndl;

        FOREVER
                {
                dos_hndl = Fcreate(file_name, 0);
                if (dos_hndl >= 0)
                        return ((WORD) dos_hndl);
                if ( !dos_error((WORD) dos_hndl) )
                        return (-1);
                }

        return (-1);  /* Appease lint */
        }

/*------------------------------*/
/*      dos_error               */
/*------------------------------*/
        WORD
dos_error(tos_err)
        WORD    tos_err;
        {
        WORD    f_ret;

        graf_mouse(ARROW, 0x0L);
        if (tos_err > -50)
                {
                tos_err += 31;
                tos_err = -tos_err;
                }
        f_ret = form_error(tos_err);
        close_files();
        return (f_ret);
        }

/*------------------------------*/
/*      get_file                */
/*------------------------------*/
        WORD
get_file(extnt, got_file)
        BYTE    *extnt, *got_file;
        {
        WORD    butn, ii;
        BYTE    tmp_path[64], tmp_name[13];

        tmp_name[0] = '\0';
        tmp_path[0] = '\0';

        if (*got_file)
                parse_fname(got_file, tmp_path,
                            tmp_name, extnt);
        if (!tmp_path[0])
                get_path(&tmp_path[0], extnt);

        fsel_input(tmp_path, tmp_name, &butn);
        if (butn)
                {
                strcpy(got_file, tmp_path);
                for (ii = 0;
                     got_file[ii] && got_file[ii] != '*';
                     ii++);
                got_file[ii - 1] = '\0';
                strcat (got_file, "\\");
                strcat(got_file, tmp_name);
                return (TRUE);
                }
        else
                return (FALSE);
        }

/*------------------------------*/
/*      parse_fname             */
/*------------------------------*/
        VOID
parse_fname(full, path, name, extnt)
        BYTE    *full, *path, *name, *extnt;
        {
        WORD    i, j;
        BYTE    *s, *d;

        /* scan for end of path */
        for (i = strlen(full); i--; )
                if (full[i] == '\\' || full[i] == ':')
                        break;
        if (i == -1)
                strcpy(name, full); /* "Naked" file name */
        else
                {
                strcpy(name, &full[i+1]);
                for (s = full, d = path, j = 0;
                     j++ < i + 1;
                     *d++ = *s++)
                   ;
                strcpy(&path[i+1], "*.");
                strcat(path, extnt);
                }
        }

/*------------------------------*/
/*      get_path                */
/*------------------------------*/
        VOID
get_path(tmp_path, spec)
        BYTE    *tmp_path, *spec;
        {
        WORD    cur_drv;

        cur_drv = Dgetdrv();
        tmp_path[0] = cur_drv + 'A';
        tmp_path[1] = ':';
        Dgetpath(&tmp_path[2], 0);
        if (strlen(tmp_path) > 3)
                strcat(tmp_path, "\\");
        else
                tmp_path[2] = '\0';
        strcat(tmp_path, "*.");
        strcat(tmp_path, spec);
        }

/*------------------------------*/
/*      new_ext                 */
/*------------------------------*/
        VOID
new_ext(o_fname, n_fname, ext)
        BYTE    *o_fname, *n_fname, *ext;
        {
        WORD    ii, jj;

        strcpy(n_fname, o_fname);
        for (ii = (jj = strlen(n_fname)) - 1;
             ii && n_fname[ii] != '.'; ii--   );
        if (!ii)
                n_fname[ii = jj] = '.';
        strcpy(&n_fname[++ii], ext);
        }
\end{verbatim}
\newpage

\subsubsection{\tt rclib.c}
\begin{verbatim} 
/*------------------------------*/
/*      includes                */
/*------------------------------*/

#include "portab.h"     /* portable coding conv */
#include "machine.h"    /* machine depndnt conv */
#include "obdefs.h"     /* object definitions   */
#include "gembind.h"    /* gem binding structs  */
#include "taddr.h"
#include "rsconv.h"


/*------------------------------*/
/*      defines                 */
/*------------------------------*/

#define NIL             -1
#define DESK            0
#define ARROW           0
#define HOUR_GLASS      2                       
#define END_UPDATE      0
#define BEG_UPDATE      1

#define TE_PTEXT(x)     (x)
#define TE_TXTLEN(x)    ((x) + 24)

/*------------------------------*/
/*      do_obj                  */
/*------------------------------*/
/* set specified bit in object state */
        VOID
do_obj(tree, which, bit)
        OBJECT  *tree;
        WORD    which, bit;
        {
        (tree + which)->ob_state |= bit;
        }


/*------------------------------*/
/*      undo_obj                */
/*------------------------------*/
/* clear specified bit in object state */
        VOID
undo_obj(tree, which, bit)
        OBJECT  *tree;
        WORD    which, bit;
        {
        (tree + which)->ob_state &= (~bit);
        }

/*------------------------------*/
/*      sel_obj                 */
/*------------------------------*/
        WORD
sel_obj(tree, which)
        OBJECT  *tree;
        WORD    which;
        {
        do_obj(tree, which, SELECTED);
        return (TRUE);
        }

/*------------------------------*/
/*      desel_obj               */
/*------------------------------*/
        WORD
desel_obj(tree, which)
        OBJECT  *tree;
        WORD    which;
        {
        undo_obj(tree, which, SELECTED);
        return (TRUE);
        }

/*------------------------------*/
/*      disab_obj               */
/*------------------------------*/
        WORD
disab_obj(tree, obj)
        OBJECT  *tree;
        WORD    obj;
        {
        undo_obj(tree, obj, DISABLED);
        return (TRUE);
        }

/*------------------------------*/
/*      objc_xywh               */
/*------------------------------*/
        VOID
objc_xywh(tree, obj, p)
        OBJECT  *tree;
        WORD    obj;
        GRECT   *p;
        {
        objc_offset(tree, obj, &p->g_x, &p->g_y);
        p->g_w = (tree + obj)->ob_width;
        p->g_h = (tree + obj)->ob_height;
        }

/*------------------------------*/
/*      disp_obj                */
/*------------------------------*/
        VOID
disp_obj(tree, obj)
        OBJECT  *tree;
        WORD    obj;
        {
        GRECT   box;

        objc_xywh(tree, obj, &box);
        objc_draw(tree, ROOT, MAX_DEPTH,
                  box.g_x, box.g_y,
                  box.g_w, box.g_h);
        }

/*------------------------------*/
/*      selected                */
/*------------------------------*/
        WORD
selected(tree, obj)
        OBJECT  *tree;
        WORD    obj;
        {
        return (SELECTED & (tree + obj)->ob_state)
                ? TRUE : FALSE;
        }

/*------------------------------*/
/*      map_tree                */
/*------------------------------*/
        VOID
map_tree(tree, this, last, routine)
        OBJECT          *tree;
        WORD            this, last;
        WORD            (*routine)();
        {
        WORD            tmp1;
 
        tmp1 = this;
             /* Initialize to impossible value: */
             /* TAIL won't point to self!       */
             /* Look until final node, or off   */
             /* the end of tree                 */ 
        while (this != last && this != NIL)
             /* Did we 'pop' into this node     */
             /* for the second time?            */
                if ((tree + this)->ob_tail != tmp1)
                        {
                        tmp1 = this;
                        /* This is a new node       */
                        this = NIL;
                        /* Apply operation, testing  */
                        /* for rejection of sub-tree */

                        if ((*routine)(tree, tmp1))
                                this = (tree + tmp1)->ob_head;
                                /* Subtree path not taken, */
                                /* so traverse right       */ 
                        if (this == NIL)
                                this = (tree + tmp1)->ob_next;
                        }
                else            /* Revisiting parent:        */
                                /* No operation, move right  */
                        {
                        tmp1 = this;
                        this = (tree + tmp1)->ob_next;
                        }
        }

/*------------------------------*/
/*      hndl_dial               */
/*------------------------------*/
        VOID
hndl_dial(tree, def, x, y, w, h)
        OBJECT  *tree;
        WORD    def;
        WORD    x, y, w, h;
        {
        WORD    xdial, ydial, wdial, hdial, exitobj;
        UWORD   xtype;

        form_center(tree,
                    &xdial, &ydial, &wdial, &hdial);
        form_dial(0, x, y, w, h,
                  xdial, ydial, wdial, hdial);
        form_dial(1, x, y, w, h,
                  xdial, ydial, wdial, hdial);
        objc_draw(tree, ROOT, MAX_DEPTH,
                  xdial, ydial, wdial, hdial);
        exitobj = form_do(tree, def) & 0x7FFF;
        form_dial(2, x, y, w, h,
                  xdial, ydial, wdial, hdial);
        form_dial(3, x, y, w, h,
                  xdial, ydial, wdial, hdial);

        return (exitobj);
        }

/*------------------------------*/
/*      set_text                */
/*------------------------------*/
        VOID
set_text(tree, obj, str, len)
        OBJECT  *tree;
        BYTE    *str;
        WORD    obj, len;
        {
        TEDINFO *obspec;

        obspec = (TEDINFO *) (tree + obj)->ob_spec;
        obspec->te_ptext = str;
        obspec->te_txtlen = len;
        }

/*------------------------------*/
/*      beg_prog                */
/*------------------------------*/
        VOID
beg_prog(rect)
        GRECT   *rect;
        {
        OBJECT  *tree;
        WORD    xdial, ydial, wdial, hdial;

        rsrc_gaddr(R_TREE, PROGRESS, &tree);
        form_center(tree, &rect->g_x, &rect->g_y,
                          &rect->g_w, &rect->g_h);
        form_dial(0, 0, 0, 0, 0, rect->g_x, rect->g_y, 
                rect->g_w, rect->g_h);
        objc_draw(tree, ROOT, MAX_DEPTH,
                  rect->g_x, rect->g_y, 
                  rect->g_w, rect->g_h);
        }

/*------------------------------*/
/*      end_prog                */
/*------------------------------*/
        VOID
end_prog(rect)
        GRECT   *rect;
        {
        form_dial(3, 0, 0, 0, 0,
                  rect->g_x, rect->g_y,
                  rect->g_w, rect->g_h);
        }

/*------------------------------*/
/*      set_prog                */
/*------------------------------*/
        VOID
set_prog(strno)
        UWORD   strno;
        {
        OBJECT  *tree;
        BYTE    *saddr;

        rsrc_gaddr(R_TREE, STRINGS, &tree);
        saddr = (BYTE *) (tree + strno)->ob_spec;
        rsrc_gaddr(R_TREE, PROGRESS, &tree);
        set_text(tree, PLINE, saddr);
        disp_obj(tree, PLINE);
        }

\end{verbatim}
\newpage

\subsubsection{\tt rcmain.c}
\begin{verbatim} 
/*------------------------------*/
/*      includes                */
/*------------------------------*/

#include "portab.h"     /* portable coding conv */
#include "machine.h"    /* machine depndnt conv */
#include "obdefs.h"     /* object definitions   */
#include "gembind.h"    /* gem binding structs  */
#include "osbind.h"     /* BDOS definitions     */
#include "gemdefs.h"
#include "rsconv.h"


/*------------------------------*/
/*      defines                 */
/*------------------------------*/

#define NIL             -1
#define DESK            0
#define ARROW           0
#define HOUR_GLASS      2                       
#define END_UPDATE      0
#define BEG_UPDATE      1

typedef struct memform
        {
        WORD   *mp;
        WORD   fwp;
        WORD   fh;
        WORD   fww;
        WORD   ff;
        WORD   np;
        WORD   r1;
        WORD   r2;
        WORD   r3;
        } MFDB;

/*------------------------------*/
/*      Global                  */
/*------------------------------*/
GLOBAL  WORD    gl_apid;

GLOBAL WORD   contrl[11]; /* control inputs         */
GLOBAL WORD   intin[80];  /* max string length      */
GLOBAL WORD   ptsin[256]; /* polygon fill points    */
GLOBAL WORD   intout[45]; /* open workstation output*/
GLOBAL WORD   ptsout[12];

GLOBAL WORD   gl_wchar;     /* character width          */
GLOBAL WORD   gl_hchar;     /* character height         */
GLOBAL WORD   gl_wbox;      /* box (cell) width         */
GLOBAL WORD   gl_hbox;      /* box (cell) height        */
GLOBAL WORD   gem_handle;   /* GEM handle               */
GLOBAL WORD   vdi_handle;   /* VDI handle               */
GLOBAL WORD   work_out[57]; /* open virt.workst. values */
GLOBAL GRECT  scrn_area;    /* scrn area                */
GLOBAL MFDB   scrn_mfdb;    /* scrn memory def'n for blt*/
GLOBAL GRECT  full;         /* desktop size             */

/*------------------------------*/
/*      External                */
/*------------------------------*/

EXTERN  WORD    desel_obj();

/*------------------------------*/
/*      Local                   */
/*------------------------------*/

MLOCAL  WORD    native_in = TRUE;
                /* TRUE: input .RSC is native   */
                /* FALSE: input .RSC is foreign */

MLOCAL  WORD    conv_def = TRUE;    /* TRUE: convert .DEF also    */
MLOCAL  WORD    new_dfn = FALSE;    /* TRUE: use new symbol fmt   */
MLOCAL  BYTE    old_rsc[4] = "RSC"; /* new resource file extent   */
MLOCAL  BYTE    new_rsc[4] = "RS2"; /* new resource file extent   */
MLOCAL  BYTE    old_def[4] = "DEF"; /* new definition file extend */
MLOCAL  BYTE    new_def[4] = "DF2"; /* new definition file extend */
MLOCAL  BYTE    r_file[81];         /* resource file name         */
MLOCAL  BYTE    d_file[81];         /* definition file name       */
MLOCAL  BYTE    r2_file[81];        /* output resource name       */
MLOCAL  BYTE    d2_file[81];        /* output definition name     */
MLOCAL  WORD    r_hndl = -1;        /* resource file handle       */
MLOCAL  WORD    d_hndl = -1;        /* definition file handle     */
MLOCAL  WORD    r2_hndl = -1;       /* output resource handle     */
MLOCAL  WORD    d2_hndl = -1;       /* output definition handle   */

MLOCAL  LONG    f_err;              /* file error                 */
MLOCAL  BYTE    *head;              /* location of buffer         */
MLOCAL  LONG    buff_size;          /* size of buffer             */
MLOCAL  BYTE    buff[20];           /* def file work area         */
MLOCAL  UWORD   img_offset, addr;   /* for image fixup            */
MLOCAL  WORD    img_odd;            /* image fixup needed?        */
MLOCAL  GRECT   prog_rect;          /* rectangle for prog indic.  */

/*------------------------------*/
/*      swap_bytes              */
/*------------------------------*/
        VOID
swap_bytes(where, len)
        BYTE    *where;
        WORD    len;
        {
        BYTE    swap;

        for (; len > 0; len -= 2)
                {
                swap = *where;
                *where = *(where + 1);
                *(where + 1) = swap;
                where += 2;
                }
        }

/*------------------------------*/
/*      swap_words              */
/*------------------------------*/
        VOID
swap_words(where, len)
        WORD    *where;
        WORD    len;
        {
        UWORD   swap;

        for (; len > 0; len -= 4)
                {
                swap = *where;
                *where = *(where + 1);
                *(where + 1) = swap;
                where += 2;
                }
        }

/*------------------------------*/
/*      swap_images             */
/*------------------------------*/
        VOID
swap_images()
        {
        BITBLK  *where;
        ICONBLK *where2;
        BYTE    *taddr;
        WORD    num;
        WORD    wb, hl;

        where = (BITBLK *)
                (head + ((RSHDR *) head)->rsh_bitblk);
        num = ((RSHDR *) head)->rsh_nbb;
        for (; num--; where++)
                {
                taddr = where->bi_pdata;
                wb = where->bi_wb;
                hl = where->bi_hl;
                if ((LONG) taddr != -1L)
                        {
                        if (img_odd)
                                where->bi_pdata = ++taddr;
                        swap_bytes(head + taddr, wb * hl);
                        }
                }

        where2 = (ICONBLK *)
                 (head + ((RSHDR *) head)->rsh_iconblk);
        num = ((RSHDR *) head)->rsh_nib;
        for (; num--; where2++)
                {
                wb = (where2->ib_wicon + 7) >> 3;
                hl = where2->ib_hicon;
                taddr = where2->ib_pdata;
                if ((LONG) taddr != -1L)
                        {
                        if (img_odd)
                                where2->ib_pdata = ++taddr;
                        swap_bytes(head + taddr, wb * hl);
                        }
                taddr = where2->ib_pmask;
                if ((LONG) taddr != -1L)
                        {
                        if (img_odd)
                                where2->ib_pmask = ++taddr;
                        swap_bytes(head + taddr, wb * hl);
                        }
                }
        }

/*------------------------------*/
/*      swap_trees              */
/*------------------------------*/
        VOID
swap_trees()
        {
        BYTE    *where;
        WORD    size;

        where = head + ((RSHDR *) head)->rsh_trindex;
        size = ((RSHDR *) head)->rsh_ntree * sizeof(LONG);
        swap_bytes(where, size);
        swap_words((WORD *) where, size);
        }

/*------------------------------*/
/*      swap_objs               */
/*------------------------------*/
        VOID
swap_objs()
        {
        OBJECT  *where;
        WORD    num;

        where = (OBJECT *)
                (head + ((RSHDR *) head)->rsh_object);
        num = ((RSHDR *) head)->rsh_nobs;
        swap_bytes((BYTE *) where, num * sizeof(OBJECT));
        for (; num--; where++)
                swap_words((WORD *) &where->ob_spec,
                                    sizeof(LONG));
        }

/*------------------------------*/
/*      swap_teds               */
/*------------------------------*/
        VOID
swap_teds()
        {
        TEDINFO *where;
        WORD    num;

        where = (TEDINFO *)
                (head + ((RSHDR *) head)->rsh_tedinfo);
        num = ((RSHDR *) head)->rsh_nted;
        swap_bytes((BYTE *) where, num * sizeof(TEDINFO));
        for (; num--; where++)
                {
                swap_words((WORD *) &where->te_ptext,
                                    sizeof(LONG));
                swap_words((WORD *) &where->te_ptmplt,
                                    sizeof(LONG));
                swap_words((WORD *) &where->te_pvalid,
                                    sizeof(LONG));
                }
        }

/*------------------------------*/
/*      swap_ibs                */
/*------------------------------*/
        VOID
swap_ibs()
        {
        ICONBLK *where;
        WORD    num;

        where = (ICONBLK *)
                (head + ((RSHDR *) head)->rsh_iconblk);
        num = ((RSHDR *) head)->rsh_nib;
        swap_bytes((BYTE *) where, num * sizeof(ICONBLK));
        for (; num--; where++)
                {
                swap_words((WORD *) &where->ib_pdata,
                                    sizeof(LONG));
                swap_words((WORD *) &where->ib_pmask,
                                    sizeof(LONG));
                swap_words((WORD *) &where->ib_ptext,
                                    sizeof(LONG));
                }
        }

/*------------------------------*/
/*      swap_bbs                */
/*------------------------------*/
        VOID
swap_bbs()
        {
        BITBLK  *where;
        WORD    num;

        where = (BITBLK *)
                (head + ((RSHDR *) head)->rsh_bitblk);
        num = ((RSHDR *) head)->rsh_nbb;
        swap_bytes((BYTE *) where, num * sizeof(BITBLK));
        for (; num--; where++)
                swap_words((WORD *) &where->bi_pdata,
                                    sizeof(LONG));
        }

/*------------------------------*/
/*      swap_fstr               */
/*------------------------------*/
        VOID
swap_fstr()
        {
        BYTE    *where;
        WORD    size;

        where = head + ((RSHDR *) head)->rsh_frstr;
        size = ((RSHDR *) head)->rsh_nstring * sizeof(LONG);
        swap_bytes(where, size);
        swap_words((WORD *) where, size);
        }

/*------------------------------*/
/*      swap_fimg               */
/*------------------------------*/
        VOID
swap_fimg()
        {
        LONG    where;
        WORD    size;

        where = head + ((RSHDR *) head)->rsh_frimg;
        size = ((RSHDR *) head)->rsh_nimages * sizeof(LONG);
        swap_bytes(where, size);
        swap_words((WORD *) where, size);
        }

/*------------------------------*/
/*      close_files             */
/*------------------------------*/
        VOID
close_files()
        {
        if (r_hndl != -1)
                Fclose(r_hndl);
        if (d_hndl != -1)
                Fclose(d_hndl);
        if (r2_hndl != -1)
                Fclose(r2_hndl);
        if (d2_hndl != -1)
                Fclose(d2_hndl);
        r_hndl = d_hndl = r2_hndl = d2_hndl = -1; 
        }

/*------------------------------*/
/*      do_conv                 */
/*------------------------------*/
        WORD
do_conv()
        {
        BYTE    *str; 
        LONG    size;
        WORD    reply, nsym;

        r_file[0] = '\0';

        if (!get_file(old_rsc, r_file))
                return;
        if ((r_hndl = open_file(r_file)) == -1)
                return;
        if (conv_def)
                {
                new_ext(r_file, d_file, old_def);
                FOREVER {
                        d_hndl = (WORD) Fopen(d_file, 0);
                        if (d_hndl >= 0)
                                break;
                        rsrc_gaddr(R_STRING, NODEF, &str);
                        reply = form_alert(1, str);
                        if (reply == 3)
                                {
                                close_files();
                                return;
                                }
                        if (reply == 1)
                                {
                                conv_def = FALSE;
                                break;
                                }
                                /* if (reply == 2) */
                        if (!get_file(old_def, d_file))
                                break;
                        }
                }

        graf_mouse(HOUR_GLASS, 0x0L);
        beg_prog(&prog_rect);
        set_prog(RSCREAD);

        f_err = Fread(r_hndl, (LONG) sizeof(RSHDR), head);
        if ( f_err < 0)
                {
                dos_error((WORD) f_err);
                return;
                }

        if (!native_in)
                swap_bytes(head, sizeof(RSHDR));

        size = ((RSHDR *) head)->rsh_rssize;

        if (buff_size < size)
                {
                graf_mouse(ARROW, 0x0L); /* Before alert */
                rsrc_gaddr(R_STRING, NOMEM, &str);
                form_alert(1, str);
                close_files();
                return;
                }

        f_err = Fread(r_hndl, size - sizeof(RSHDR),
                      head + sizeof(RSHDR));
        if ( f_err < 0)
                {
                dos_error((WORD) f_err);
                return;
                }

        img_offset = ((RSHDR *) head)->rsh_imdata;
        if ( (img_odd = img_offset & 0x0001) )
                {
                set_prog(IMGALIGN);
                ((RSHDR *) head)->rsh_rssize = img_offset + 1;
                for (addr = ((RSHDR *) head)->rsh_frstr;
                     --addr > img_offset; )
                        *(head + addr) = *(head + addr - 1);
                }

        set_prog(BYTESWAP);
        if (native_in)
                swap_images();

        swap_trees();
        swap_objs();
        swap_teds();
        swap_ibs();
        swap_bbs();
        swap_fstr();
        swap_fimg();

        if (native_in)
                swap_bytes(head, sizeof(RSHDR));
        else
                swap_images();

        set_prog(RSCWRITE);
        new_ext(r_file, r2_file, new_rsc);
        if ( (r2_hndl = create_file(r2_file)) == -1)
                {
                close_files();
                return;
                }
        graf_mouse(HOUR_GLASS, 0x0L);
        /* Create_file could reset */

        f_err = Fwrite(r2_hndl, size, head);
        if ( f_err < 0)
                {
                dos_error((WORD) f_err);
                return;
                }

        if (!conv_def)
                {
                close_files();
                end_prog(&prog_rect);
                return;
                }

        set_prog(DEFREAD);
        new_ext(r_file, d2_file, new_def);
        if ( (d2_hndl = create_file(d2_file)) == -1)
                {
                close_files();
                return;
                }

        f_err = Fread(d_hndl, (LONG) sizeof(WORD), &nsym);
        if ( f_err < 0)
                {
                dos_error((WORD) f_err);
                return;
                }


        set_prog(BYTESWAP);
        reply = nsym;
        swap_bytes(&reply, 2);

        f_err = Fwrite(d2_hndl,
                       (LONG) sizeof(WORD),
                       new_dfn ? &nsym : &reply);
        if ( f_err < 0)
                {
                dos_error((WORD) f_err);
                return;
                }

        if (!native_in || new_dfn)
                nsym = reply;

        for (; nsym--; )
                {
                if (!new_dfn)   /* Spare words only if */
                                /* using old format    */
                if (!native_in)
                        {       /* insert spare word */
                        reply = 0;
                        f_err = Fwrite(d2_hndl,
                                       (LONG) sizeof(WORD),
                                       &reply);
                        if ( f_err < 0)
                                {
                                dos_error((WORD) f_err);
                                return;
                                }
                        }
                else
                        {       /* delete extra word */ 
                        f_err = Fread(d_hndl,
                                      (LONG) sizeof(WORD),
                                      buff);
                        if ( f_err < 0)
                                {
                                dos_error((WORD) f_err);
                                return;
                                }
                        }

                f_err = Fread(d_hndl,
                              (LONG) sizeof(WORD),
                              buff);
                if ( f_err < 0)
                        {
                        dos_error((WORD) f_err);
                        return;
                        }

                if (!new_dfn)   /* Just copy for new fmt */
                        swap_bytes(buff, 2);

                f_err = Fwrite(d2_hndl,
                               (LONG) sizeof(WORD),
                               buff);
                if ( f_err < 0)
                        {
                        dos_error((WORD) f_err);
                        return;
                        }
                f_err = Fread(d_hndl,
                              (LONG) (sizeof(WORD) + 10),
                              buff);
                if ( f_err < 0)
                        {
                        dos_error((WORD) f_err);
                        return;
                        }

                if (!new_dfn)
                        swap_bytes(buff, 2); /* only swap value */

                f_err = Fwrite(d2_hndl,
                              (LONG) (sizeof(WORD) + 10),
                              buff);
                if ( f_err < 0)
                        {
                        dos_error((WORD) f_err);
                        return;
                        }
                }

        set_prog(DEFWRITE);
        close_files();
        end_prog(&prog_rect);
        }

/*------------------------------*/
/*      do_help                 */
/*------------------------------*/
        VOID
do_help()
        {
        OBJECT  *tree;
        WORD    obj;

        rsrc_gaddr(R_TREE, HELP, &tree);
        obj = hndl_dial(tree, 0, 0, 0, 0, 0);
        desel_obj(tree, obj);
        }

/*------------------------------*/
/*      do_mode                 */
/*------------------------------*/
        WORD
do_mode()
        {
        OBJECT  *tree;
        WORD    obj;
        WORD    xdial, ydial, wdial, hdial;

        rsrc_gaddr(R_TREE, MODE, &tree);

        sel_obj(tree, native_in? N2F: F2N);
        if (!conv_def)
                sel_obj(tree, DEFNO);
        else if (!new_dfn)
                sel_obj(tree, DEFYES);
        else
                sel_obj(tree, DFNYES);
        set_text(tree, RSC1, old_rsc, 4);
        set_text(tree, RSC2, new_rsc, 4);
        set_text(tree, DEF1, old_def, 4);
        set_text(tree, DEF2, new_def, 4);

        form_center(tree,
                   &xdial, &ydial,
                   &wdial, &hdial);
        form_dial(0, 0, 0, 0, 0,
                  xdial, ydial,
                  wdial, hdial);
        form_dial(1, 0, 0, 0, 0,
                  xdial, ydial,
                  wdial, hdial);
        objc_draw(tree, ROOT, MAX_DEPTH,
                  xdial, ydial,
                  wdial, hdial);

        while (TRUE)
                {
                obj = form_do(tree, 0) & 0x7FFF;
                if (obj == DEFYES)
                        {
                        if (strcmp(old_def, "DFN") == 0)
                                {
                                strcpy(old_def, "DEF");
                                disp_obj(tree, DEF1);
                                }
                        }
                else if (obj == DFNYES)
                        {
                        if (strcmp(old_def, "DEF") == 0)
                                {
                                strcpy(old_def, "DFN");
                                disp_obj(tree, DEF1);
                                }
                        }
                else
                        break;
                }

        form_dial(2, 0, 0, 0, 0,
                  xdial, ydial, wdial, hdial);
        form_dial(3, 0, 0, 0, 0,
                  xdial, ydial, wdial, hdial);

        native_in = selected(tree, N2F);
        conv_def = !selected(tree, DEFNO);
        new_dfn = selected(tree, DFNYES);

        map_tree(tree, ROOT, NIL, desel_obj);
        return (obj);
        }

/*------------------------------*/
/*      rscv_run                */
/*------------------------------*/
        WORD
rscv_run()
        {
        WORD    obj;

        FOREVER {
                obj = do_mode();
                if (obj == HELPMODE)
                        do_help();
                else if (obj == CONVMODE)
                        {
                        do_conv();
                        graf_mouse(ARROW, 0x0L);
                        }
                else 
                        break;
                }
        }

/*------------------------------*/
/*      rscv_term               */
/*------------------------------*/
        VOID
rscv_term(term_type)
        WORD    term_type;
        {
        switch (term_type) /* NOTE: all cases fall through */
                {
                case (0 /* normal termination */):
                        Mfree(head);
                case (2):
                        v_clsvwk( vdi_handle );
                case (3):
                        rsrc_free();
                case (4):
                        if (term_type)
                                wind_update(END_UPDATE);
                        appl_exit();
                case (5):
                        break;
                }
        }

/*------------------------------*/
/*      rscv_init               */
/*------------------------------*/
        WORD
rscv_init()
        {
        WORD    i;
        WORD    work_in[11];
        LONG    tree;

        appl_init();    /* initialize libraries */
        if (gl_apid == -1)
                return (5);     /* No handles ! */
        graf_mouse(HOUR_GLASS, 0x0L);
        wind_update(BEG_UPDATE);
        if (!rsrc_load( "RSCONV.RSC" ))
                {
                graf_mouse(ARROW, 0x0L);
                form_alert(1,
                "[3][Fatal Error !|\
                     RSCONV.RSC|\
                     File Not Found][ Abort ]" );
                return(4); /* Can't find resource */
                }

        for (i=0; i<10; i++)
                {
                work_in[i]=1;
                }
        work_in[10]=2;
        gem_handle = graf_handle(&gl_wchar,&gl_hchar,
                                 &gl_wbox,&gl_hbox);
        vdi_handle = gem_handle;
        /* open virtual work stn*/
        v_opnvwk(work_in,&vdi_handle,work_out);
        if (vdi_handle == 0)
                return (3);

        vqt_attributes (vdi_handle, work_in);

        scrn_area.g_x = 0;
        scrn_area.g_y = 0;
        scrn_area.g_w = work_out[0] + 1;
        scrn_area.g_h = work_out[1] + 1;

        scrn_mfdb.np = work_out[4];
        scrn_mfdb.mp = 0x0L;

        wind_get(DESK, WF_WXYWH,
                 &full.g_x, &full.g_y,
                 &full.g_w, &full.g_h);

        vst_height(vdi_handle, work_in[7],
                   &gl_wchar, &gl_hchar,
                   &gl_wbox,  &gl_hbox);

        buff_size = Malloc(-1L);
        head = Malloc(buff_size - 4000L);

        graf_mouse(ARROW,0x0L);
        wind_update(END_UPDATE);
        return(0);
        }

/*------------------------------*/
/*      main                    */
/*------------------------------*/
main()
        {
        WORD    rscv_code;

        /* initialization       */
        if ( !(rscv_code = rscv_init()) )
                rscv_run();
        rscv_term(rscv_code);
        /* termination          */      
        }
\end{verbatim}
\newpage

\subsubsection{Batchfiles {\tt rlink.bat} and {\tt sylink.bat}}

\noindent rlink.bat:

\begin{verbatim} 
sylink rsconv rcmain,rcfile,rclib
\end{verbatim}

\noindent sylink.bat:

\begin{verbatim}
link68 [s,u] %1.68k=apstart,%2,aesbind,vdibind,osbind,gemlib
relmod %1
rm %1.68K
\end{verbatim}

\newpage

% End of Appendix C
