/****************************************************************************** * XRSRC.C * * Extended Resource-Manager. RSC-Files can now have up to * 4294967295 bytes length. * ******************************************************************************/ #include #include #include #include #include #include #include #ifdef __GNUC__ #include #else #include #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; }