Files
FireBee_Setup-Dev/devtools/orcs218/extra/xrsrc/xrsrc.c
2023-06-12 09:14:09 +02:00

2237 lines
54 KiB
C

/******************************************************************************
* XRSRC.C
*
* Extended Resource-Manager. RSC-Files can now have up to
* 4294967295 bytes length.
*
******************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <tos.h>
#include <vdi.h>
#include <aes.h>
#include <assert.h>
#ifdef __GNUC__
#include <sys/stat.h>
#else
#include <ext.h>
#endif
#include "xrsrc.h"
/* horizontal text alignment */
#ifndef ALI_LEFT
#define ALI_LEFT 0
#define ALI_CENTER 1
#define ALI_RIGHT 2
#endif
#ifndef ALI_TOP
#define ALI_TOP 5
#endif
#ifndef R_IBPTEXT
#define R_IBPTEXT 13
#endif
#ifndef FALSE
# define FALSE 0
# define TRUE 1
#endif
#ifndef _CDECL
#ifdef __GNUC__
#define _CDECL /**/
#else
#define _CDECL cdecl
#endif
#endif
#ifndef G_SHORTCUT
#define G_SHORTCUT 38
#endif
#ifndef G_EXTBOX
#define G_EXTBOX 40
#endif
#ifndef G_WHITE
#define G_WHITE 0
#endif
#ifndef G_BLACK
#define G_BLACK 1
#endif
#ifndef OS_SELECTED
#define OS_SELECTED SELECTED
#endif
#undef fclose
#ifndef _AESrscfile
# define _AESrscfile (((AES_GLOBAL *)_GemParBlk.global)->ap_ptree)
# define _AESrscmem (((AES_GLOBAL *)_GemParBlk.global)->ap_rscmem)
#endif
#define USE_NICELINES 0
#define ICOLSPEC_GET_DATACOL(color) ( ((color) >> 12) & 0x0f )
#define ICOLSPEC_GET_MASKCOL(color) ( ((color) >> 8) & 0x0f )
#define ICOLSPEC_GET_CHARACTER(color) ( ((color) ) & 0xff )
/****** TYPES ****************************************************************/
struct userdef {
OBJECT orig;
USERBLK user;
_WORD obj;
};
struct userdef_list {
struct userdef_list *next;
RSHDR *hdr;
OBJECT *objects;
_WORD nobjs;
_WORD nuserobjs;
struct userdef userobjs[1];
};
/****** VARIABLES ************************************************************/
static struct userdef_list *userdefs;
/*
* vdi handle used for drawing USERDEF objects
* It's safe to directly use the AES handle here,
* because we save/restore all attributes we change
*/
static _WORD aes_handle;
#define TEST_COLOR 15
#define XMAX_PLANES 32
#define XMAX_COLOR 256
typedef _WORD table4[XMAX_COLOR][4];
/*
* vdi handle used for initializing the color icon tables
*/
#define xvdi_handle aes_handle
static _WORD xscrn_planes;
/* number of bytes per pixel (0 == planeoriented) */
static _WORD xpixelbytes = -1;
/* table for plane oriented images */
static _WORD *colortbl;
/* table for pixel oriented imaged */
static _ULONG colortbl2[XMAX_COLOR];
/* wether an palette has already been set */
static _BOOL is_std_palette;
static table4 rgb_palette;
static _WORD xscr_w, xscr_h;
static _WORD const pixtbl[XMAX_COLOR] = {
0, 2, 3, 6, 4, 7, 5, 8, 9, 10, 11, 14, 12, 15, 13, 255,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32 , 33 , 34 , 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48 , 49 , 50 , 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64 , 65 , 66 , 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80 , 81 , 82 , 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 1
};
/******************************************************************************/
/*** ---------------------------------------------------------------------- ***/
/******************************************************************************/
static _BOOL xywh2pxy(_WORD x, _WORD y, _WORD w, _WORD h, _WORD *pxy, _WORD max_w, _WORD max_h)
{
if (x < 0)
{
w += x;
x = 0;
}
if (x >= max_w)
{
x = 0;
w = 0;
}
if (x + w > max_w)
{
w = max_w - x;
}
if (y < 0)
{
h += y;
y = 0;
}
if (y >= max_h)
{
y = 0;
h = 0;
}
if (y + h > max_h)
{
h = max_h - y;
}
pxy[0] = x;
pxy[1] = y;
pxy[2] = x + w - 1;
pxy[3] = y + h - 1;
return w > 0 && h > 0;
}
/*** ---------------------------------------------------------------------- ***/
static void save_fillattr(_WORD handle, _WORD attrib[5])
{
vqf_attributes(handle, attrib);
}
/*** ---------------------------------------------------------------------- ***/
static void restore_fillattr(_WORD handle, _WORD attrib[5])
{
vsf_interior(handle, attrib[0]);
vsf_color(handle, attrib[1]);
vsf_style(handle, attrib[2]);
vswr_mode(handle, attrib[3]);
vsf_perimeter(handle, attrib[4]);
}
/*** ---------------------------------------------------------------------- ***/
static void save_lineattr(_WORD handle, _WORD attrib[6])
{
vql_attributes(handle, attrib);
}
/*** ---------------------------------------------------------------------- ***/
static void restore_lineattr(_WORD handle, _WORD attrib[6])
{
vsl_type(handle, attrib[0]);
vsl_color(handle, attrib[1]);
vswr_mode(handle, attrib[2]);
vsl_width(handle, attrib[3]);
vsl_ends(handle, attrib[4], attrib[5]);
}
/*** ---------------------------------------------------------------------- ***/
static void save_textattr(_WORD handle, _WORD attrib[10])
{
_WORD dummy;
vqt_attributes(handle, attrib);
vst_effects(handle, 0);
vst_alignment(handle, ALI_LEFT, ALI_TOP, &dummy, &dummy);
vst_rotation(handle, 0);
}
/*** ---------------------------------------------------------------------- ***/
static void save_clip(_WORD handle, _WORD clip[5])
{
_WORD wo[57];
vq_extnd(handle, 1, wo);
clip[0] = wo[45];
clip[1] = wo[46];
clip[2] = wo[47];
clip[3] = wo[48];
clip[4] = wo[19];
}
/*** ---------------------------------------------------------------------- ***/
static void restore_clip(_WORD handle, _WORD clip[5])
{
vs_clip(handle, clip[4], clip);
}
/*** ---------------------------------------------------------------------- ***/
/*
* set VDI clipping to coordinates in PARMBLK structure.
* Neccessary on some AES that don't set the clipping
* rectangle during objc_draw() (i.e. XaAES)
*/
static void set_user_clip(_WORD handle, PARMBLK *pb)
{
_WORD pxy[4];
pxy[0] = pb->pb_xc;
pxy[1] = pb->pb_yc;
pxy[2] = pb->pb_xc + pb->pb_wc - 1;
pxy[3] = pb->pb_yc + pb->pb_hc - 1;
vs_clip(handle, TRUE, pxy);
}
/*** ---------------------------------------------------------------------- ***/
static void restore_textattr(_WORD handle, _WORD attrib[10])
{
_WORD dummy;
vst_color(handle, attrib[1]);
vst_rotation(handle, attrib[2]);
vst_alignment(handle, attrib[3], attrib[4], &dummy, &dummy);
/* original vqt_attributes returns mode-1 */
vswr_mode(handle, attrib[5] + 1);
vst_height(handle, attrib[7], &dummy, &dummy, &dummy, &dummy);
}
/*** ---------------------------------------------------------------------- ***/
static void GetScreenSize(_WORD *width, _WORD *height)
{
*width = xscr_w;
*height = xscr_h;
}
/*** ---------------------------------------------------------------------- ***/
static void scrfdb(MFDB *fdb)
{
fdb->fd_addr = (void *) 0;
GetScreenSize(&fdb->fd_w, &fdb->fd_h);
fdb->fd_wdwidth = (fdb->fd_w + 15) >> 4;
fdb->fd_stand = FALSE;
fdb->fd_nplanes = xscrn_planes;
fdb->fd_r1 = fdb->fd_r2 = fdb->fd_r3 = 0;
}
/******************************************************************************/
/*** ---------------------------------------------------------------------- ***/
/******************************************************************************/
void GetTextSize(_WORD *width, _WORD *height)
{
_WORD dummy;
graf_handle(width, height, &dummy, &dummy);
}
/*** ---------------------------------------------------------------------- ***/
static void rsc_obfix(OBJECT *tree, _ULONG count)
{
_WORD wchar, hchar;
GetTextSize(&wchar, &hchar);
while (count)
{
tree->ob_x = wchar * (tree->ob_x & 0xff) + (tree->ob_x >> 8);
tree->ob_y = hchar * (tree->ob_y & 0xff) + (tree->ob_y >> 8);
tree->ob_width = wchar * (tree->ob_width & 0xff) + (tree->ob_width >> 8);
tree->ob_height = hchar * (tree->ob_height & 0xff) + (tree->ob_height >> 8);
tree++;
count--;
}
}
/*** ---------------------------------------------------------------------- ***/
static _WORD _CDECL draw_nothing(PARMBLK *pb)
{
(void) pb;
return 0;
}
/*** ---------------------------------------------------------------------- ***/
static void xrsrc_hdr2xrsc(RSXHDR *xrsc_header, RSHDR *header)
{
xrsc_header->rsh_vrsn = 3 | (header->rsh_vrsn & ~RSC_VERSION_MASK);
xrsc_header->rsh_extvrsn = XRSC_VRSN_ORCS;
xrsc_header->rsh_object = header->rsh_object;
xrsc_header->rsh_tedinfo = header->rsh_tedinfo;
xrsc_header->rsh_iconblk = header->rsh_iconblk;
xrsc_header->rsh_bitblk = header->rsh_bitblk;
xrsc_header->rsh_frstr = header->rsh_frstr;
xrsc_header->rsh_string = header->rsh_string;
xrsc_header->rsh_imdata = header->rsh_imdata;
xrsc_header->rsh_frimg = header->rsh_frimg;
xrsc_header->rsh_trindex = header->rsh_trindex;
xrsc_header->rsh_nobs = header->rsh_nobs;
xrsc_header->rsh_ntree = header->rsh_ntree;
xrsc_header->rsh_nted = header->rsh_nted;
xrsc_header->rsh_nib = header->rsh_nib;
xrsc_header->rsh_nbb = header->rsh_nbb;
xrsc_header->rsh_nstring = header->rsh_nstring;
xrsc_header->rsh_nimages = header->rsh_nimages;
xrsc_header->rsh_rssize = header->rsh_rssize;
}
/*** ---------------------------------------------------------------------- ***/
static void std_palette(table4 palette)
{
_WORD color;
for (color = 0; color < XMAX_COLOR; color++)
{
vq_color(xvdi_handle, pixtbl[color], 1, palette[color]);
palette[color][3] = pixtbl[color];
}
}
/*****************************************************************************/
/* Test how many bytes per pixel are needed in device-dependent format */
/*****************************************************************************/
static _WORD test_rez(void)
{
_WORD i, np, color, bpp = 0;
_WORD pxy[8], rgb[3];
_UWORD backup[XMAX_PLANES], test[XMAX_PLANES], test2[XMAX_PLANES];
_WORD black[3] = { 0, 0, 0 };
_WORD white[3] = { 1000, 1000, 1000 };
MFDB screen;
MFDB pixel;
MFDB stdfm;
pixel.fd_addr = NULL;
pixel.fd_w = 16;
pixel.fd_h = 1;
pixel.fd_wdwidth = 1;
pixel.fd_stand = FALSE;
pixel.fd_nplanes = xscrn_planes;
pixel.fd_r1 = 0;
pixel.fd_r2 = 0;
pixel.fd_r3 = 0;
stdfm = pixel;
stdfm.fd_stand = TRUE;
if (xscrn_planes >= 8)
{
if (xscrn_planes == 8)
{
color = 0xff;
memset(test, 0, sizeof(test));
memset(test2, 0, sizeof(test2));
for (np = 0; np < xscrn_planes; np++)
test2[np] = (color & (1 << np)) << (15 - np);
pixel.fd_addr = test;
stdfm.fd_addr = test2;
vr_trnfm(xvdi_handle, &stdfm, &pixel);
for (i = 1; i < xscrn_planes; i++)
if (test[i])
break;
if (i >= xscrn_planes && !(test[0] & 0x00ff))
bpp = 1;
} else
{
_WORD lineattrib[6];
_WORD clip[5];
save_lineattr(xvdi_handle, lineattrib);
save_clip(xvdi_handle, clip);
scrfdb(&screen);
pxy[0] = 0;
pxy[1] = 0;
pxy[2] = screen.fd_w - 1;
pxy[3] = screen.fd_h - 1;
vs_clip(xvdi_handle, FALSE, pxy);
memset(backup, 0, sizeof(backup));
vswr_mode(xvdi_handle, MD_REPLACE);
vsl_ends(xvdi_handle, 0, 0);
vsl_type(xvdi_handle, SOLID);
vsl_width(xvdi_handle, 1);
pxy[0] = 0;
pxy[1] = 0;
pxy[2] = 0;
pxy[3] = 0;
pxy[4] = 0;
pxy[5] = 0;
pxy[6] = 0;
pxy[7] = 0;
v_hide_c(xvdi_handle);
/* save pixel */
pixel.fd_addr = backup;
vro_cpyfm(xvdi_handle, S_ONLY, pxy, &screen, &pixel);
/* save old color */
vq_color(xvdi_handle, TEST_COLOR, 1, rgb);
/* set 1 white pixel */
vsl_color(xvdi_handle, TEST_COLOR);
vs_color(xvdi_handle, TEST_COLOR, white);
v_pline(xvdi_handle, 2, pxy);
/* fetch pixel value */
memset(test, 0, sizeof(test));
pixel.fd_addr = test;
vro_cpyfm(xvdi_handle, S_ONLY, pxy, &screen, &pixel);
for (i = ((xscrn_planes + 15) >> 4) * 2; i < xscrn_planes; i++)
if (test[i])
break;
if (i >= xscrn_planes)
{
vs_color(xvdi_handle, TEST_COLOR, black);
v_pline(xvdi_handle, 2, pxy);
memset(test, 0, sizeof(test));
vro_cpyfm(xvdi_handle, S_ONLY, pxy, &screen, &pixel);
for (i = ((xscrn_planes + 15) >> 4) * 2; i < xscrn_planes; i++)
if (test[i])
break;
if (i >= xscrn_planes)
bpp = (xscrn_planes + 7) >> 3;
}
/* restore old color */
vs_color(xvdi_handle, TEST_COLOR, rgb);
/* restore saved pixel */
pixel.fd_addr = backup;
vro_cpyfm(xvdi_handle, S_ONLY, pxy, &pixel, &screen);
restore_lineattr(xvdi_handle, lineattrib);
restore_clip(xvdi_handle, clip);
v_show_c(xvdi_handle, 1);
}
}
return bpp;
}
/*****************************************************************************/
/* determine pixel values for the selected palette */
/*****************************************************************************/
static void xfill_colortbl(void)
{
_WORD np, color, backup[XMAX_PLANES * 4];
_WORD pxy[8], rgb[3];
MFDB screen;
MFDB pixel;
MFDB stdfm;
_UWORD pixel_data[XMAX_PLANES];
_UWORD pixel_data2[XMAX_PLANES];
pixel.fd_addr = NULL;
pixel.fd_w = 16;
pixel.fd_h = 1;
pixel.fd_wdwidth = 1;
pixel.fd_stand = FALSE;
pixel.fd_nplanes = xscrn_planes;
pixel.fd_r1 = 0;
pixel.fd_r2 = 0;
pixel.fd_r3 = 0;
stdfm = pixel;
stdfm.fd_stand = TRUE;
if (xscrn_planes >= 8)
{
if (xscrn_planes > 8)
{
_WORD lineattrib[6];
_WORD clip[5];
save_lineattr(xvdi_handle, lineattrib);
save_clip(xvdi_handle, clip);
scrfdb(&screen);
pxy[0] = 0;
pxy[1] = 0;
pxy[2] = screen.fd_w - 1;
pxy[3] = screen.fd_h - 1;
vs_clip(xvdi_handle, TRUE, pxy);
v_hide_c(xvdi_handle);
if (xpixelbytes == 0 && colortbl == NULL)
{
colortbl = (_WORD *)malloc(xscrn_planes * XMAX_COLOR * sizeof(_WORD));
}
memset(backup, 0, sizeof(backup));
if (colortbl != NULL)
memset(colortbl, 0, xscrn_planes * XMAX_COLOR * sizeof(_WORD));
vswr_mode(xvdi_handle, MD_REPLACE);
vsl_ends(xvdi_handle, 0, 0);
vsl_type(xvdi_handle, SOLID);
vsl_width(xvdi_handle, 1);
/* save pixel value */
memset(pxy, 0, sizeof(pxy));
pxy[2] = 1;
pxy[6] = 1;
pixel.fd_addr = backup;
vro_cpyfm(xvdi_handle, S_ONLY, pxy, &screen, &pixel);
pxy[6] = 0;
/* save old color */
vq_color(xvdi_handle, TEST_COLOR, 1, rgb);
for (color = 0; color < XMAX_COLOR; color++)
{
vs_color(xvdi_handle, TEST_COLOR, rgb_palette[color]);
vsl_color(xvdi_handle, TEST_COLOR);
pxy[2] = 1;
v_pline(xvdi_handle, 2, pxy);
pixel.fd_addr = pixel_data;
stdfm.fd_addr = pixel_data2;
/* vro_cpyfm, because v_get_pixel does not work for TrueColor */
pxy[2] = 0;
memset(pixel_data, 0, sizeof(pixel_data));
vro_cpyfm(xvdi_handle, S_ONLY, pxy, &screen, &pixel);
if (xpixelbytes != 0)
{
colortbl2[color] = 0L;
memcpy(&colortbl2[color], pixel.fd_addr, xpixelbytes);
} else
{
memset(pixel_data2, 0, sizeof(pixel_data2));
vr_trnfm(xvdi_handle, &pixel, &stdfm);
for (np = 0; np < xscrn_planes; np++)
if (pixel_data2[np])
pixel_data2[np] = 0xffff;
if (colortbl != NULL)
memcpy(&colortbl[color * xscrn_planes], pixel_data2, xscrn_planes * sizeof(_WORD));
}
}
/* restore old color */
vs_color(xvdi_handle, TEST_COLOR, rgb);
/* restore old pixel */
pixel.fd_addr = backup;
pxy[2] = 1;
pxy[6] = 1;
vro_cpyfm(xvdi_handle, S_ONLY, pxy, &pixel, &screen);
/* restore line attributes */
restore_lineattr(xvdi_handle, lineattrib);
restore_clip(xvdi_handle, clip);
v_show_c(xvdi_handle, 1);
} else
{
if (xpixelbytes != 0)
for (color = 0; color < XMAX_COLOR; color++)
*(unsigned char *)&colortbl2[color] = color;
}
}
}
/*****************************************************************************/
/* std_to_byte converts an image from standard format to device dependent */
/* format (for resolutions >= 16 Planes) */
/*****************************************************************************/
static void std_to_byte(_UWORD *col_data, _LONG len, _WORD old_planes, _ULONG *colortbl2, MFDB *s)
{
_LONG x, i, pos;
_UWORD np, *new_data, pixel, color, back[XMAX_PLANES];
_WORD memflag = FALSE;
unsigned char *p1, *p2;
_ULONG colback = 0;
_UWORD *plane_ptr[XMAX_PLANES];
if ((s->fd_addr = (_UWORD *)malloc(len * 2 * s->fd_nplanes)) == NULL)
{
return;
}
memcpy(s->fd_addr, col_data, len * 2 * old_planes);
new_data = (_UWORD *)s->fd_addr;
p1 = (unsigned char *)new_data;
if (old_planes < 8)
{
colback = colortbl2[(1 << old_planes) - 1];
colortbl2[(1 << old_planes) - 1] = colortbl2[XMAX_COLOR - 1];
}
for (i = 0; i < old_planes; i++)
plane_ptr[i] = &col_data[i * len];
pos = 0;
for (x = 0; x < len; x++)
{
for (np = 0; np < old_planes; np++)
back[np] = plane_ptr[np][x];
for (pixel = 0; pixel < 16; pixel++)
{
color = 0;
for (np = 0; np < old_planes; np++)
{
color |= ((back[np] & 0x8000) >> (15 - np));
back[np] <<= 1;
}
switch (xpixelbytes)
{
case 2:
new_data[pos++] = *(_UWORD *) &colortbl2[color];
break;
case 3:
p2 = (unsigned char *) &colortbl2[color];
*(p1++) = *(p2++);
*(p1++) = *(p2++);
*(p1++) = *(p2++);
break;
case 4:
((_ULONG *)new_data)[pos++] = colortbl2[color];
break;
}
}
}
if (old_planes < 8)
colortbl2[(1 << old_planes) - 1] = colback;
if (memflag)
free(col_data);
}
/*** ---------------------------------------------------------------------- ***/
static _BOOL W_Cicon_Setpalette(_WORD *palette)
{
_BOOL need_recalc = FALSE;
if (palette != NULL)
{
_WORD i;
table4 palbuf;
std_palette(palbuf);
is_std_palette = TRUE;
for (i = 0; i < XMAX_COLOR; i++)
{
if (rgb_palette[i][0] != palette[0] ||
rgb_palette[i][1] != palette[1] ||
rgb_palette[i][2] != palette[2])
need_recalc = TRUE;
if (palbuf[i][0] != palette[0] ||
palbuf[i][1] != palette[1] ||
palbuf[i][2] != palette[2])
is_std_palette = FALSE;
rgb_palette[i][0] = *palette++;
rgb_palette[i][1] = *palette++;
rgb_palette[i][2] = *palette++;
rgb_palette[i][3] = *palette++;
}
} else
{
need_recalc = !is_std_palette;
std_palette(rgb_palette);
is_std_palette = TRUE;
}
if (xpixelbytes < 0)
{
xpixelbytes = test_rez();
need_recalc = TRUE;
}
if (need_recalc)
xfill_colortbl();
return TRUE;
}
/******************************************************************************/
/*** ---------------------------------------------------------------------- ***/
/******************************************************************************/
static void *rs_load(const char *filename)
{
register _UWORD UObj;
register CICONBLK *cicon_p;
RSXHDR xrsc_header;
unsigned char *buf = NULL;
FILE *fp;
_ULONG filesize;
cicon_p = NULL;
{
char fname_buf[128];
strncpy(fname_buf, filename, sizeof(fname_buf));
fname_buf[sizeof(fname_buf) - 1] = '\0';
if (!shel_find(fname_buf) || (fp = fopen(fname_buf, "rb")) == NULL)
{
form_error(2); /* ENOENT */
return NULL;
}
}
{
struct stat st;
if (fstat(fileno(fp), &st) < 0)
{
fclose(fp);
return NULL;
}
filesize = st.st_size;
}
if ((buf = (unsigned char *)malloc((size_t)filesize)) == NULL)
{
fclose(fp);
form_error(8); /* ENOMEM */
return NULL;
}
if (fread(buf, 1, (size_t)filesize, fp) != filesize)
{
free(buf);
fclose(fp);
return NULL;
}
fclose(fp);
if (!IS_XRSC_HEADER(buf))
xrsrc_hdr2xrsc(&xrsc_header, (RSHDR *)buf);
else
xrsc_header = *((RSXHDR *)buf);
if (xrsc_header.rsh_vrsn & RSC_EXT_FLAG)
{
_LONG *p;
_BOOL ok = TRUE;
p = (_LONG *)(buf + (size_t)xrsc_header.rsh_rssize);
if ((_ULONG)p[RSC_EXT_FILESIZE] != filesize)
{
ok = FALSE;
} else if (p[RSC_EXT_CICONBLK] < 0 || (_ULONG)p[RSC_EXT_CICONBLK] >= filesize)
{
ok = FALSE;
} else
{
_LONG *cp = p + RSC_EXT_CICONBLK + 1;
while (ok != FALSE)
{
if ((_ULONG)((unsigned char *)cp - buf) >= filesize)
ok = FALSE;
else if (*cp == 0)
break;
else if (*cp != -1)
{
/* ok = FALSE; */
if (cp == (p + RSC_EXT_PALETTE))
{
_WORD *palette = (_WORD *)(buf + (size_t)(*cp));
W_Cicon_Setpalette(palette);
}
break;
}
cp++;
}
}
if (ok != FALSE)
{
p = (_LONG *)(buf + (size_t)p[RSC_EXT_CICONBLK]);
while (ok != FALSE)
{
if ((_ULONG)((unsigned char *)p - buf) >= filesize)
ok = FALSE;
else if (*p == -1)
break;
else if (*p != 0)
ok = FALSE;
else
p++;
}
if (ok != FALSE && *p == -1)
{
p++;
cicon_p = (CICONBLK *)p;
}
}
if (ok == FALSE)
{
free(buf);
return NULL;
}
}
{
OBJECT *_rs_object;
_rs_object = (OBJECT *)(buf + (size_t)xrsc_header.rsh_object);
rsc_obfix(_rs_object, xrsc_header.rsh_nobs);
for (UObj = 0; UObj < xrsc_header.rsh_nobs; UObj++)
{
switch (_rs_object->ob_type & 0xff)
{
case G_BOX:
case G_IBOX:
case G_BOXCHAR:
case G_EXTBOX:
break;
case G_STRING:
case G_TITLE:
case G_BUTTON:
case G_TEXT:
case G_FTEXT:
case G_BOXTEXT:
case G_FBOXTEXT:
case G_IMAGE:
case G_ICON:
_rs_object->ob_spec.free_string = (char *)buf + (size_t)(_rs_object->ob_spec.index);
break;
case G_SHORTCUT:
/* not changed to G_STRING here;
might be displayed in window
where we use our own functions
*/
_rs_object->ob_spec.free_string = (char *)buf + (size_t)(_rs_object->ob_spec.index);
break;
case G_CICON:
if (cicon_p == NULL)
{
/* !!! */
} else
{
CICON *dp;
CICONBLK *cicon;
_LONG size;
unsigned char *p;
_LONG num_cicons;
_LONG idx;
cicon = cicon_p;
cicon_p++;
_rs_object->ob_spec.ciconblk = cicon;
size = ((cicon->monoblk.ib_wicon + 15) / 16) * 2l * cicon->monoblk.ib_hicon;
p = (unsigned char *)cicon_p;
cicon->monoblk.ib_pdata = (_WORD *)p;
p += (size_t)size;
cicon->monoblk.ib_pmask = (_WORD *)p;
p += (size_t)size;
idx = (_LONG)cicon->monoblk.ib_ptext;
if (idx <= 0 || (buf + (size_t)idx) == p || idx < (_LONG)xrsc_header.rsh_string || idx >= (_LONG)xrsc_header.rsh_rssize)
cicon->monoblk.ib_ptext = (char *)p;
else
cicon->monoblk.ib_ptext = (char *)buf + (size_t)idx;
p += 12; /* skip reserved space for icon text */
dp = (CICON *)p;
num_cicons = (_LONG)(cicon->mainlist);
if (p > (buf + (size_t)filesize))
{
free(buf);
return NULL;
}
if (num_cicons == 0)
{
cicon->mainlist = NULL;
} else
{
cicon->mainlist = dp;
while (num_cicons != 0)
{
p += sizeof(CICON);
dp->col_data = (_WORD *)p;
p += (size_t)(size * dp->num_planes);
dp->col_mask = (_WORD *)p;
p += (size_t)size;
if (dp->sel_data != NULL)
{
dp->sel_data = (_WORD *)p;
p += (size_t)(size * dp->num_planes);
dp->sel_mask = (_WORD *)p;
p += (size_t)size;
} else
{
dp->sel_data = NULL;
dp->sel_mask = NULL;
}
num_cicons--;
if (num_cicons == 0)
{
dp->next_res = NULL;
} else
{
dp->next_res = (CICON *)p;
}
dp = (CICON *)p;
}
}
cicon_p = (CICONBLK *)p;
}
break;
case G_USERDEF:
_rs_object->ob_spec.userblk = (USERBLK *)(buf + (size_t)_rs_object->ob_spec.index);
/*
* It's up to the application to set the appropiate function.
* To be on the safe side, let it point to some function
* that draws a box only, or simply does nothing.
*/
_rs_object->ob_spec.userblk->ub_code = draw_nothing;
break;
}
_rs_object++;
}
}
{
TEDINFO *_rs_tedinfo;
_rs_tedinfo = (TEDINFO *)(buf + (size_t)xrsc_header.rsh_tedinfo);
for (UObj = 0; UObj < xrsc_header.rsh_nted; UObj++)
{
_rs_tedinfo->te_ptext += (size_t)buf;
_rs_tedinfo->te_ptmplt += (size_t)buf;
_rs_tedinfo->te_pvalid += (size_t)buf;
_rs_tedinfo++;
}
}
{
ICONBLK *_rs_iconblk;
_rs_iconblk = (ICONBLK *)(buf + (size_t)xrsc_header.rsh_iconblk);
for (UObj = 0; UObj < xrsc_header.rsh_nib; UObj++)
{
_rs_iconblk->ib_pmask = (_WORD *)(buf + (size_t)(_rs_iconblk->ib_pmask));
_rs_iconblk->ib_pdata = (_WORD *)(buf + (size_t)(_rs_iconblk->ib_pdata));
_rs_iconblk->ib_ptext = (char *)buf + (size_t)_rs_iconblk->ib_ptext;
_rs_iconblk++;
}
}
{
BITBLK *_rs_bitblk;
_rs_bitblk = (BITBLK *)(buf + (size_t)xrsc_header.rsh_bitblk);
for (UObj = 0; UObj < xrsc_header.rsh_nbb; UObj++)
{
_rs_bitblk->bi_pdata = (_WORD *)(buf + (size_t)(_rs_bitblk->bi_pdata));
_rs_bitblk++;
}
}
{
char **_rs_frstr;
_rs_frstr = (char **)(buf + (size_t)xrsc_header.rsh_frstr);
for (UObj = 0; UObj < xrsc_header.rsh_nstring; UObj++)
{
*_rs_frstr += (size_t)buf;
_rs_frstr++;
}
}
{
BITBLK **_rs_frimg;
_rs_frimg = (BITBLK **)(buf + (size_t)xrsc_header.rsh_frimg);
for (UObj = 0; UObj < xrsc_header.rsh_nimages; UObj++)
{
*_rs_frimg = (BITBLK *)(buf + (size_t)(*_rs_frimg));
_rs_frimg++;
}
}
{
OBJECT **_rs_trindex;
_rs_trindex = (OBJECT **)(buf + (size_t)xrsc_header.rsh_trindex);
#if 0
/*
* settings these variables in the global array
* would actually allow using rsrc_gaddr(),
* but rsrc_free() might bomb since we did not use rsrc_load before
*/
_AESrscfile = _rs_trindex;
_AESrscmem = buf;
#endif
for (UObj = 0; UObj < xrsc_header.rsh_ntree; UObj++)
{
*_rs_trindex = (OBJECT *)(buf + (size_t)(*_rs_trindex));
_rs_trindex++;
}
}
{
OBJECT *_rs_object;
_rs_object = (OBJECT *)(buf + (size_t)xrsc_header.rsh_object);
hfix_objs((RSHDR *)buf, _rs_object, (_WORD)xrsc_header.rsh_nobs);
}
return buf;
}
/*****************************************************************************/
/* Convert icon data to current resolution */
/* (e.g. 4 Plane Icon to 24 Plane TrueColor) */
/*****************************************************************************/
static _BOOL xfix_cicon(_UWORD *col_data, _LONG len, _WORD old_planes, _WORD new_planes, MFDB *s)
{
_LONG x, i, old_len, rest_len, new_len;
_UWORD np, *new_data, mask, pixel, bit, color, back[XMAX_PLANES];
MFDB d;
len >>= 1;
s->fd_nplanes = new_planes;
if (old_planes == new_planes)
{
d = *s;
d.fd_stand = FALSE;
s->fd_addr = col_data;
if ((d.fd_addr = malloc(len * 2 * new_planes)) == NULL)
d.fd_addr = s->fd_addr;
vr_trnfm(xvdi_handle, s, &d);
if (d.fd_addr != s->fd_addr)
{
memcpy(s->fd_addr, d.fd_addr, len * 2 * new_planes);
free(d.fd_addr);
}
return TRUE;
}
old_len = old_planes * len;
new_len = new_planes * len;
rest_len = new_len - old_len;
if (new_planes <= 8)
{
s->fd_addr = malloc(new_len * 2);
if (s->fd_addr != NULL)
{
new_data = &((_UWORD *)s->fd_addr)[old_len];
memset(new_data, 0, rest_len * 2);
memcpy(s->fd_addr, col_data, old_len * 2);
col_data = (_UWORD *)s->fd_addr;
for (x = 0; x < len; x++)
{
mask = 0xffff;
for (i = 0; i < old_len; i += len)
mask &= col_data[x + i];
if (mask)
for (i = 0; i < rest_len; i += len)
new_data[x + i] |= mask;
}
/* convert to device dependent format */
d = *s;
d.fd_stand = FALSE;
if ((d.fd_addr = malloc(len * 2 * new_planes)) == NULL)
d.fd_addr = s->fd_addr;
vr_trnfm(xvdi_handle, s, &d);
if (d.fd_addr != s->fd_addr)
{
memcpy(s->fd_addr, d.fd_addr, len * 2 * new_planes);
free(d.fd_addr);
}
}
} else
{
/* TrueColor */
if (xpixelbytes == 0)
{
s->fd_addr = NULL;
if (colortbl != NULL)
{
_UWORD *plane_ptr[XMAX_PLANES], *pos;
_UWORD old_col[XMAX_PLANES];
_UWORD maxcol = 0;
if (old_planes < 8)
{
maxcol = (1 << old_planes) - 1;
memcpy(old_col, &colortbl[maxcol * new_planes], new_planes * sizeof(_WORD));
memset(&colortbl[maxcol * new_planes], 0, new_planes * sizeof(_WORD));
}
if ((new_data = (_UWORD *)malloc(len * 2 * new_planes)) != NULL)
{
_WORD *colp;
memcpy(new_data, col_data, old_len * 2);
memset(new_data + old_len, 0, rest_len * 2);
for (i = 0; i < new_planes; i++)
plane_ptr[i] = &new_data[i * len];
for (x = 0; x < len; x++)
{
bit = 1;
for (np = 0; np < old_planes; np++)
back[np] = plane_ptr[np][x];
for (pixel = 0; pixel < 16; pixel++)
{
color = 0;
for (np = 0; np < old_planes; np++)
{
color += ((back[np] & 1) << np);
back[np] >>= 1;
}
colp = &colortbl[color * new_planes];
for (np = 0; np < new_planes; np++)
{
pos = plane_ptr[np] + x;
*pos = (*pos & ~bit) | (colp[np] & bit);
}
bit <<= 1;
}
}
if (old_planes < 8)
memcpy(&colortbl[maxcol * new_planes], old_col, new_planes * sizeof(_WORD));
/* convert to device dependent format */
d = *s;
s->fd_addr = new_data;
d.fd_stand = FALSE;
if ((d.fd_addr = malloc(len * 2 * new_planes)) == NULL)
d.fd_addr = s->fd_addr;
vr_trnfm(xvdi_handle, s, &d);
if (d.fd_addr != s->fd_addr)
{
memcpy(s->fd_addr, d.fd_addr, len * 2 * new_planes);
free(d.fd_addr);
}
}
}
} else
{
std_to_byte(col_data, len, old_planes, colortbl2, s);
}
}
if (s->fd_addr == NULL)
{
return FALSE;
}
return TRUE;
}
/*** ---------------------------------------------------------------------- ***/
static void xfix_make_selmask(_WORD w, _WORD h, void *dst, const void *src)
{
_UWORD mask = 0x5555;
_WORD x, y;
_UWORD *d = (_UWORD *)dst;
const _UWORD *s = (const _UWORD *)src;
w = (w + 15) >> 4;
for (y = h; --y >= 0;)
{
for (x = w; --x >= 0; )
*d++ = (*s++) & mask;
mask = ~mask;
}
}
/******************************************************************************/
/*** ---------------------------------------------------------------------- ***/
/******************************************************************************/
#if USE_NICELINES
/*** ---------------------------------------------------------------------- ***/
static void rect2pxy(const GRECT *gr, _WORD *pxy, _WORD max_w, _WORD max_h)
{
xywh2pxy(gr->g_x, gr->g_y, gr->g_w, gr->g_h, pxy, max_w, max_h);
}
/*** ---------------------------------------------------------------------- ***/
static _WORD _CDECL draw_niceline(PARMBLK *pb)
{
GRECT gr;
GRECT clip;
_WORD pxy[4];
_WORD aes_clip[5];
save_clip(aes_handle, aes_clip);
set_user_clip(aes_handle, pb);
gr.g_x = pb->pb_x;
gr.g_y = pb->pb_y + pb->pb_h / 2 - 1;
gr.g_w = pb->pb_w;
gr.g_h = 2;
clip.g_x = pb->pb_xc;
clip.g_y = pb->pb_yc;
clip.g_w = pb->pb_wc;
clip.g_h = pb->pb_hc;
if (rc_intersect(&clip, &gr))
{
_WORD attrib[5];
_WORD max_w, max_h;
save_fillattr(aes_handle, attrib);
vswr_mode(aes_handle, MD_REPLACE);
vsf_perimeter(aes_handle, FALSE);
GetScreenSize(&max_w, &max_h);
rect2pxy(&gr, pxy, max_w, max_h);
if (xscrn_planes >= 4)
{
vsf_color(aes_handle, G_LBLACK);
vsf_interior(aes_handle, FIS_SOLID);
vsf_style(aes_handle, 0);
} else
{
vsf_color(aes_handle, G_BLACK);
vsf_interior(aes_handle, FIS_PATTERN);
vsf_style(aes_handle, 4);
}
vr_recfl(aes_handle, pxy);
restore_fillattr(aes_handle, attrib);
}
restore_clip(aes_handle, aes_clip);
return OS_NORMAL;
}
#endif
/*** ---------------------------------------------------------------------- ***/
static void draw_small_text(char *text, _WORD *pxy)
{
_WORD extent[8];
_WORD textw, texth;
vqt_extent(aes_handle, text, extent);
textw = extent[2] - extent[0];
texth = extent[5] - extent[3];
pxy[0] += (pxy[2] - pxy[0] + 1 - textw) / 2;
pxy[1] += (pxy[3] - pxy[1] + 1 - texth) / 2;
v_gtext(aes_handle, pxy[0], pxy[1], text);
}
/*** ---------------------------------------------------------------------- ***/
static void draw_icon_text(ICONBLK *ib, _WORD xpos, _WORD ypos, _WORD selected)
{
_WORD x, y, w, h;
_WORD pxy[4];
_WORD datacol = ICOLSPEC_GET_DATACOL(ib->ib_char);
_WORD maskcol = ICOLSPEC_GET_MASKCOL(ib->ib_char);
char c[2];
_WORD max_w, max_h;
_WORD dummy;
_WORD cw, ch;
_WORD attrib[5];
_WORD textattrib[10];
save_fillattr(aes_handle, attrib);
save_textattr(aes_handle, textattrib);
GetScreenSize(&max_w, &max_h);
x = xpos + ib->ib_xtext;
y = ypos + ib->ib_ytext;
w = ib->ib_wtext;
h = ib->ib_htext;
vsf_interior(aes_handle, FIS_SOLID);
vsf_style(aes_handle, 0);
vst_height(aes_handle, 4, &dummy, &dummy, &cw, &ch);
vswr_mode(aes_handle, MD_TRANS);
if (w > 0 && h > 0 && ib->ib_ptext && *ib->ib_ptext &&
xywh2pxy(x, y, w, h, pxy, max_w, max_h))
{
if (selected)
{
vsf_color(aes_handle, datacol);
if (datacol != G_WHITE)
vr_recfl(aes_handle, pxy);
vst_color(aes_handle, maskcol);
draw_small_text(ib->ib_ptext, pxy);
} else
{
vsf_color(aes_handle, maskcol);
if (maskcol != G_WHITE)
vr_recfl(aes_handle, pxy);
vst_color(aes_handle, datacol);
draw_small_text(ib->ib_ptext, pxy);
}
}
c[0] = ib->ib_char;
c[1] = 0;
if (c[0] != 0)
{
x = xpos + ib->ib_xicon + ib->ib_xchar;
y = ypos + ib->ib_yicon + ib->ib_ychar;
if (xywh2pxy(x, y, cw, ch, pxy, max_w, max_h))
{
vst_color(aes_handle, selected ? maskcol : datacol);
v_gtext(aes_handle, pxy[0], pxy[1], c);
}
}
restore_textattr(aes_handle, textattrib);
restore_fillattr(aes_handle, attrib);
}
/*** ---------------------------------------------------------------------- ***/
static CICON *cicon_best_match(CICONBLK *cib, _WORD planes)
{
_WORD best_match = 0;
CICON *best = NULL;
CICON *list;
for (list = cib->mainlist; list != NULL; list = list->next_res)
{
if (list->num_planes > best_match && list->num_planes <= planes)
{
best_match = list->num_planes;
best = list;
}
}
return best;
}
/*** ---------------------------------------------------------------------- ***/
static _WORD _CDECL draw_cicon(PARMBLK *pb)
{
MFDB src, dst;
_WORD pxy[8];
struct userdef *u = (struct userdef *)pb->pb_parm;
CICONBLK *ciconblk = u->orig.ob_spec.ciconblk;
ICONBLK *ib = &ciconblk->monoblk;
_WORD x = pb->pb_x + ib->ib_xicon;
_WORD y = pb->pb_y + ib->ib_yicon;
_WORD w = ib->ib_wicon;
_WORD h = ib->ib_hicon;
_WORD datacol = ICOLSPEC_GET_DATACOL(ib->ib_char);
_WORD maskcol = ICOLSPEC_GET_MASKCOL(ib->ib_char);
_WORD colind[2];
_WORD selected = pb->pb_currstate & OS_SELECTED;
CICON *cicon;
void *pdata, *pmask;
_WORD aes_clip[5];
save_clip(aes_handle, aes_clip);
set_user_clip(aes_handle, pb);
scrfdb(&dst);
src.fd_w = w;
src.fd_h = h;
src.fd_wdwidth = (src.fd_w + 15) >> 4;
src.fd_stand = TRUE;
src.fd_nplanes = 1;
src.fd_r1 = src.fd_r2 = src.fd_r3 = 0;
if (xywh2pxy(x, y, w, h, &pxy[4], dst.fd_w, dst.fd_h))
{
pxy[0] = pxy[4] - x;
pxy[1] = pxy[5] - y;
pxy[2] = pxy[6] - x;
pxy[3] = pxy[7] - y;
cicon = ciconblk->mainlist;
if (selected)
{
if (cicon->sel_data != NULL)
{
pmask = cicon->sel_mask;
pdata = cicon->sel_data;
selected = FALSE;
} else
{
pmask = cicon->col_mask;
pdata = cicon->col_data;
/*
* for >1 planes, draw selection by darken the image
* instead of inverting, if the icon didn't have a mask
*/
if (cicon->sel_mask != NULL && cicon->num_planes > 1)
selected = 2;
}
} else
{
pmask = cicon->col_mask;
pdata = cicon->col_data;
}
src.fd_addr = pmask;
src.fd_nplanes = 1;
src.fd_stand = TRUE;
colind[0] = selected == 1 ? datacol : maskcol;
colind[1] = G_WHITE;
vrt_cpyfm(aes_handle, MD_TRANS, pxy, &src, &dst, colind);
src.fd_nplanes = cicon->num_planes;
if (src.fd_nplanes == 1)
{
src.fd_addr = pdata;
src.fd_stand = TRUE;
colind[0] = selected ? maskcol : datacol;
colind[1] = G_WHITE;
vrt_cpyfm(aes_handle, MD_TRANS, pxy, &src, &dst, colind);
} else
{
_WORD mode;
if (dst.fd_nplanes > 8)
mode = S_AND_D;
else
mode = S_OR_D;
src.fd_addr = pdata;
src.fd_stand = FALSE;
src.fd_nplanes = xscrn_planes;
vro_cpyfm(aes_handle, mode, pxy, &src, &dst);
if (selected == 2)
{
src.fd_nplanes = 1;
src.fd_addr = cicon->sel_mask;
src.fd_stand = TRUE;
colind[0] = G_BLACK;
colind[1] = G_WHITE;
vrt_cpyfm(aes_handle, MD_TRANS, pxy, &src, &dst, colind);
}
}
}
draw_icon_text(ib, pb->pb_x, pb->pb_y, selected);
restore_clip(aes_handle, aes_clip);
return pb->pb_currstate & ~OS_SELECTED;
}
/*** ---------------------------------------------------------------------- ***/
static void release_list(struct userdef_list *list)
{
OBJECT *tree = list->objects;
_WORD i;
for (i = 0; i < list->nuserobjs; i++)
{
tree[list->userobjs[i].obj] = list->userobjs[i].orig;
switch (list->userobjs[i].orig.ob_type & 0xff)
{
case G_CICON:
{
CICONBLK *ciconblk = list->userobjs[i].orig.ob_spec.ciconblk;
CICON *cicon;
cicon = ciconblk->mainlist;
assert(cicon != NULL);
if (cicon->num_planes > 1 && cicon->num_planes != xscrn_planes)
{
free(cicon->col_data);
if (cicon->sel_data)
free(cicon->sel_data);
}
if (cicon->num_planes > 1 && cicon->sel_data == NULL)
free(cicon->sel_mask);
}
break;
}
}
if (list->hdr)
{
free(list->hdr);
list->hdr = NULL;
}
}
/******************************************************************************/
/*** Exported functions ***/
/******************************************************************************/
/*
* This function is called by inlined sources
*/
void *hfix_objs(RSHDR *hdr, OBJECT *objects, _WORD num_objs)
{
_WORD i;
_WORD num_user;
_WORD dummy;
struct userdef_list *list;
aes_handle = graf_handle(&dummy, &dummy, &dummy, &dummy);
{
_WORD wo[57];
vq_extnd(aes_handle, 1, wo);
xscrn_planes = wo[4];
}
if (xpixelbytes < 0)
{
xpixelbytes = test_rez();
std_palette(rgb_palette);
}
xfill_colortbl();
num_user = 0;
for (i = 0; i < num_objs; i++)
{
OBJECT *ob = &objects[i];
switch (ob->ob_type & 0xff)
{
case G_ICON:
break;
case G_CICON:
{
CICONBLK *cicon = ob->ob_spec.ciconblk;
if (cicon_best_match(cicon, xscrn_planes) != NULL)
++num_user;
}
break;
case G_IMAGE:
break;
case G_FTEXT:
case G_FBOXTEXT:
break;
case G_TEXT:
case G_BOXTEXT:
break;
case G_TITLE:
case G_BUTTON:
break;
case G_STRING:
case G_SHORTCUT:
#if USE_NICELINES
if ((ob->ob_state & OS_DISABLED) &&
ob->ob_spec.free_string[0] == '-')
{
num_user++;
}
#endif
break;
}
}
list = (struct userdef_list *)malloc(sizeof(*list) + (num_user - 1) * sizeof(struct userdef));
if (list == NULL)
return NULL;
list->hdr = hdr;
list->objects = objects;
list->nobjs = num_objs;
list->nuserobjs = num_user;
list->next = userdefs;
userdefs = list;
#define adduser(f) \
list->userobjs[num_user].orig = *ob; \
list->userobjs[num_user].obj = i; \
list->userobjs[num_user].user.ub_code = f; \
list->userobjs[num_user].user.ub_parm = (_LONG)&list->userobjs[num_user]; \
ob->ob_type = G_USERDEF; \
ob->ob_spec.userblk = &list->userobjs[num_user].user; \
num_user++
num_user = 0;
for (i = 0; i < num_objs; i++)
{
OBJECT *ob = &objects[i];
switch (ob->ob_type & 0xff)
{
case G_ICON:
break;
case G_CICON:
{
CICONBLK *ciconblk = ob->ob_spec.ciconblk;
CICON *cicon;
MFDB d;
_LONG len;
cicon = cicon_best_match(ciconblk, xscrn_planes);
if (cicon != NULL)
{
if (cicon->num_planes > 1)
{
d.fd_w = ciconblk->monoblk.ib_wicon;
d.fd_h = ciconblk->monoblk.ib_hicon;
d.fd_wdwidth = (d.fd_w + 15) >> 4;
d.fd_stand = TRUE;
d.fd_nplanes = xscrn_planes;
len = (_LONG) d.fd_wdwidth * 2l * d.fd_h;
xfix_cicon((_UWORD *)cicon->col_data, len, cicon->num_planes, xscrn_planes, &d);
cicon->col_data = d.fd_addr;
if (cicon->sel_data)
{
xfix_cicon((_UWORD *)cicon->sel_data, len, cicon->num_planes, xscrn_planes, &d);
cicon->sel_data = d.fd_addr;
} else
{
/* prepare darken mask */
cicon->sel_mask = malloc(len);
if (cicon->sel_mask != NULL)
xfix_make_selmask(d.fd_w, d.fd_h, cicon->sel_mask, cicon->col_mask);
}
}
ciconblk->mainlist = cicon;
cicon->next_res = NULL;
adduser(draw_cicon);
} else
{
ob->ob_spec.iconblk = &ciconblk->monoblk;
ob->ob_type = (ob->ob_type & 0xff00) | G_ICON;
}
}
break;
case G_IMAGE:
break;
case G_FTEXT:
case G_FBOXTEXT:
break;
case G_TEXT:
case G_BOXTEXT:
break;
case G_TITLE:
case G_BUTTON:
break;
case G_STRING:
case G_SHORTCUT:
#if USE_NICELINES
if ((ob->ob_state & OS_DISABLED) &&
ob->ob_spec.free_string[0] == '-')
{
adduser(draw_niceline);
}
#endif
break;
}
}
assert(num_user == list->nuserobjs);
#undef adduser
return list;
}
/*** ---------------------------------------------------------------------- ***/
RSHDR *xrsrc_load(const char *re_lpfname)
{
return rs_load(re_lpfname);
}
/*** ---------------------------------------------------------------------- ***/
_WORD xrsrc_free(RSHDR *hdr)
{
struct userdef_list **list, *l;
for (list = &userdefs; (l = *list) != NULL; list = &l->next)
{
if (l->hdr == hdr)
{
*list = l->next;
release_list(l);
free(l);
return 1;
}
}
return 0;
}
/*** ---------------------------------------------------------------------- ***/
/*
* xrsrc_gaddr: like rsrc_gaddr(), taking an extra parameter for the resource
*/
_BOOL xrsrc_gaddr(RSHDR *handle, _WORD type, _WORD idx, void *gaddr)
{
RSXHDR xrsc_header;
if (gaddr == NULL)
return FALSE;
*(void **)gaddr = NULL;
if (handle == NULL)
{
return FALSE;
}
if (IS_XRSC_HEADER(handle))
{
xrsc_header = *((RSXHDR *)handle);
} else
{
xrsrc_hdr2xrsc(&xrsc_header, handle);
}
switch (type)
{
case R_TREE:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_ntree)
{
return FALSE;
}
{
OBJECT **_rs_trindex = (OBJECT **)((char *)handle + (size_t)xrsc_header.rsh_trindex);
*((OBJECT **)gaddr) = _rs_trindex[idx];
}
break;
case R_OBJECT:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nobs)
{
return FALSE;
}
{
OBJECT *_rs_object = (OBJECT *)((char *)handle + (size_t)xrsc_header.rsh_object);
*((OBJECT **)gaddr) = &_rs_object[idx];
}
break;
case R_TEDINFO:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nted)
{
return FALSE;
}
{
TEDINFO *_rs_tedinfo = (TEDINFO *)((char *)handle + (size_t)xrsc_header.rsh_tedinfo);
*((TEDINFO **)gaddr) = &_rs_tedinfo[idx];
}
break;
case R_ICONBLK:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nib)
{
return FALSE;
}
{
ICONBLK *_rs_iconblk = (ICONBLK *)((char *)handle + (size_t)xrsc_header.rsh_iconblk);
*((ICONBLK **)gaddr) = &_rs_iconblk[idx];
}
break;
case R_BITBLK:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nbb)
{
return FALSE;
}
{
BITBLK *_rs_bitblk = (BITBLK *)((char *)handle + (size_t)xrsc_header.rsh_bitblk);
*((BITBLK **)gaddr) = &_rs_bitblk[idx];
}
break;
case R_STRING:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nstring)
{
return FALSE;
}
{
char **_rs_frstr = (char **)((char *)handle + (size_t)xrsc_header.rsh_frstr);
*((char **)gaddr) = _rs_frstr[idx];
}
break;
case R_IMAGEDATA:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nimages)
{
return FALSE;
}
{
BITBLK **_rs_frimg = (BITBLK **)((char *)handle + (size_t)xrsc_header.rsh_frimg);
*((BITBLK **)gaddr) = _rs_frimg[idx];
}
break;
case R_OBSPEC:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nobs)
{
return FALSE;
}
{
OBJECT *_rs_object = (OBJECT *)((char *)handle + (size_t)xrsc_header.rsh_object);
*((_LONG **)gaddr) = &_rs_object[idx].ob_spec.index;
}
break;
case R_TEPTEXT:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nted)
{
return FALSE;
}
{
TEDINFO *_rs_tedinfo = (TEDINFO *)((char *)handle + (size_t)xrsc_header.rsh_tedinfo);
*((char ***)gaddr) = &_rs_tedinfo[idx].te_ptext;
}
break;
case R_TEPTMPLT:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nted)
{
return FALSE;
}
{
TEDINFO *_rs_tedinfo = (TEDINFO *)((char *)handle + (size_t)xrsc_header.rsh_tedinfo);
*((char ***)gaddr) = &_rs_tedinfo[idx].te_ptmplt;
}
break;
case R_TEPVALID:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nted)
{
return FALSE;
}
{
TEDINFO *_rs_tedinfo = (TEDINFO *)((char *)handle + (size_t)xrsc_header.rsh_tedinfo);
*((char ***)gaddr) = &_rs_tedinfo[idx].te_pvalid;
}
break;
case R_IBPMASK:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nib)
{
return FALSE;
}
{
ICONBLK *_rs_iconblk = (ICONBLK *)((char *)handle + (size_t)xrsc_header.rsh_iconblk);
*((char ***)gaddr) = (char **)&_rs_iconblk[idx].ib_pmask;
}
break;
case R_IBPDATA:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nib)
{
return FALSE;
}
{
ICONBLK *_rs_iconblk = (ICONBLK *)((char *)handle + (size_t)xrsc_header.rsh_iconblk);
*((char ***)gaddr) = (char **)&_rs_iconblk[idx].ib_pdata;
}
break;
case R_IBPTEXT:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nib)
{
return FALSE;
}
{
ICONBLK *_rs_iconblk = (ICONBLK *)((char *)handle + (size_t)xrsc_header.rsh_iconblk);
*((char ***)gaddr) = &_rs_iconblk[idx].ib_ptext;
}
break;
case R_BIPDATA:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nbb)
{
return FALSE;
}
{
BITBLK *_rs_bitblk = (BITBLK *)((char *)handle + (size_t)xrsc_header.rsh_bitblk);
*((char ***)gaddr) = (char **)&_rs_bitblk[idx].bi_pdata;
}
break;
case R_FRSTR:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nstring)
{
return FALSE;
}
{
char **_rs_frstr = (char **)((char *)handle + (size_t)xrsc_header.rsh_frstr);
*((char ***)gaddr) = &_rs_frstr[idx];
}
break;
case R_FRIMG:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nimages)
{
return FALSE;
}
{
BITBLK **_rs_frimg = (BITBLK **)((char *)handle + (size_t)xrsc_header.rsh_frimg);
*((BITBLK ***)gaddr) = &_rs_frimg[idx];
}
break;
default:
return FALSE;
}
return TRUE;
}
/*** ---------------------------------------------------------------------- ***/
/*
* xrsrc_gaddr: like rsrc_gaddr(), taking an extra parameter for the resource
*/
_BOOL xrsrc_saddr(RSHDR *handle, _WORD type, _WORD idx, void *saddr)
{
RSXHDR xrsc_header;
if (handle == NULL)
{
return FALSE;
}
if (IS_XRSC_HEADER(handle))
{
xrsc_header = *((RSXHDR *)handle);
} else
{
xrsrc_hdr2xrsc(&xrsc_header, handle);
}
switch (type)
{
case R_TREE:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_ntree)
{
return FALSE;
}
{
OBJECT **_rs_trindex = (OBJECT **)((char *)handle + (size_t)xrsc_header.rsh_trindex);
_rs_trindex[idx] = saddr;
}
break;
/*
* setting the address of an OBJECT simply does not work;
* current AES implementations (including GEM/3) trash the
* first 2 WORD of the OBJECT structure
*/
case R_OBJECT:
return FALSE;
/*
* current AES implementations (including GEM/3) set the first
* first member of the TEDINFO structure (te_ptext)
*/
case R_TEDINFO:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nted)
{
return FALSE;
}
{
TEDINFO *_rs_tedinfo = (TEDINFO *)((char *)handle + (size_t)xrsc_header.rsh_tedinfo);
_rs_tedinfo[idx].te_ptext = saddr;
}
break;
/*
* current AES implementations (including GEM/3) set the first
* first member of the ICONBLK structure (ib_pmask)
*/
case R_ICONBLK:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nib)
{
return FALSE;
}
{
ICONBLK *_rs_iconblk = (ICONBLK *)((char *)handle + (size_t)xrsc_header.rsh_iconblk);
_rs_iconblk[idx].ib_pmask = saddr;
}
break;
/*
* current AES implementations (including GEM/3) set the first
* first member of the BITBLK structure (ib_pdata)
*/
case R_BITBLK:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nbb)
{
return FALSE;
}
{
BITBLK *_rs_bitblk = (BITBLK *)((char *)handle + (size_t)xrsc_header.rsh_bitblk);
_rs_bitblk[idx].bi_pdata = saddr;
}
break;
/*
* setting the address of a string simply does not work;
* current AES implementations (including GEM/3) trash the
* first 4 bytes of the string
*/
case R_STRING:
return FALSE;
case R_IMAGEDATA:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nimages)
{
return FALSE;
}
{
BITBLK **_rs_frimg = (BITBLK **)((char *)handle + (size_t)xrsc_header.rsh_frimg);
_rs_frimg[idx]->bi_pdata = saddr;
}
break;
case R_OBSPEC:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nobs)
{
return FALSE;
}
{
OBJECT *_rs_object = (OBJECT *)((char *)handle + (size_t)xrsc_header.rsh_object);
_rs_object[idx].ob_spec.indirect = saddr;
}
break;
case R_TEPTEXT:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nted)
{
return FALSE;
}
{
TEDINFO *_rs_tedinfo = (TEDINFO *)((char *)handle + (size_t)xrsc_header.rsh_tedinfo);
_rs_tedinfo[idx].te_ptext = saddr;
}
break;
case R_TEPTMPLT:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nted)
{
return FALSE;
}
{
TEDINFO *_rs_tedinfo = (TEDINFO *)((char *)handle + (size_t)xrsc_header.rsh_tedinfo);
_rs_tedinfo[idx].te_ptmplt = saddr;
}
break;
case R_TEPVALID:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nted)
{
return FALSE;
}
{
TEDINFO *_rs_tedinfo = (TEDINFO *)((char *)handle + (size_t)xrsc_header.rsh_tedinfo);
_rs_tedinfo[idx].te_pvalid = saddr;
}
break;
case R_IBPMASK:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nib)
{
return FALSE;
}
{
ICONBLK *_rs_iconblk = (ICONBLK *)((char *)handle + (size_t)xrsc_header.rsh_iconblk);
_rs_iconblk[idx].ib_pmask = saddr;
}
break;
case R_IBPDATA:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nib)
{
return FALSE;
}
{
ICONBLK *_rs_iconblk = (ICONBLK *)((char *)handle + (size_t)xrsc_header.rsh_iconblk);
_rs_iconblk[idx].ib_pdata = saddr;
}
break;
case R_IBPTEXT:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nib)
{
return FALSE;
}
{
ICONBLK *_rs_iconblk = (ICONBLK *)((char *)handle + (size_t)xrsc_header.rsh_iconblk);
_rs_iconblk[idx].ib_ptext = saddr;
}
break;
case R_BIPDATA:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nbb)
{
return FALSE;
}
{
BITBLK *_rs_bitblk = (BITBLK *)((char *)handle + (size_t)xrsc_header.rsh_bitblk);
_rs_bitblk[idx].bi_pdata = saddr;
}
break;
case R_FRSTR:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nstring)
{
return FALSE;
}
{
char **_rs_frstr = (char **)((char *)handle + (size_t)xrsc_header.rsh_frstr);
_rs_frstr[idx] = saddr;
}
break;
case R_FRIMG:
if (idx < 0 || (_ULONG)idx >= xrsc_header.rsh_nimages)
{
return FALSE;
}
{
BITBLK **_rs_frimg = (BITBLK **)((char *)handle + (size_t)xrsc_header.rsh_frimg);
_rs_frimg[idx] = saddr;
}
break;
default:
return FALSE;
}
return TRUE;
}
/*** ---------------------------------------------------------------------- ***/
_WORD xrsrc_obfix(OBJECT *re_otree, _WORD re_oobject)
{
rsc_obfix(&re_otree[re_oobject], 1);
return TRUE;
}
/*** ---------------------------------------------------------------------- ***/
_BOOL init_xrsrc(void)
{
_WORD dummy;
aes_handle = graf_handle(&dummy, &dummy, &dummy, &dummy);
{
_WORD workout[57];
vq_extnd(aes_handle, 0, workout);
xscr_w = workout[0] + 1;
xscr_h = workout[1] + 1;
vq_extnd(aes_handle, 1, workout);
xscrn_planes = workout[4];
}
std_palette(rgb_palette);
is_std_palette = TRUE;
return TRUE;
}
/*** ---------------------------------------------------------------------- ***/
void term_xrsrc(void)
{
struct userdef_list *list, *next;
for (list = userdefs; list != NULL; list = next)
{
next = list->next;
release_list(list);
free(list);
}
userdefs = NULL;
free(colortbl);
colortbl = NULL;
}