home *** CD-ROM | disk | FTP | other *** search
- /* misc.c */
-
- /*
- #define FAKE_RISCOS_2
- */
-
- #include <stdio.h>
- #include <stdarg.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
-
- #include "os.h"
- #include "msgs.h"
- #include "swis.h"
- #include "sprite.h"
- #include "bbc.h"
- #include "wimp.h"
- #include "template.h"
- #include "colourtran.h"
- #include "flex.h"
- #include "coords.h"
- #include "misc.h"
- #include "wimpt.h"
- #include "win.h"
- #include "werr.h"
-
- #include "tracker.h"
-
- #define LGAP 4
- #define BGAP 44
- #define RGAP 44
- #define TGAP 44
-
- #define MARGIN 80
-
- static int offset = 0;
- static int wimpver;
-
- int misc_xeig, misc_yeig, misc_pixx, misc_pixy;
- wimp_palettestr misc_wimpcols;
-
- os_error *misc_err(char *msg, ...)
- { static os_error eb;
- va_list ap;
-
- va_start(ap, msg);
- vsprintf(eb.errmess, msgs_lookup(msg), ap);
- va_end(ap);
-
- return &eb;
- }
-
- void misc_boxby(wimp_box *b, int dx, int dy)
- { b->x0 += dx;
- b->y0 += dy;
- b->x1 += dx;
- b->y1 += dy;
- }
-
- void misc_boxto(wimp_box *b, int x, int y)
- { misc_boxby(b, x - b->x0, y - b->y0);
- }
-
- void misc_clipbox(wimp_box *obox, wimp_box *clip)
- { if (obox->x0 < clip->x0)
- obox->x0 = clip->x0;
- else if (obox->x0 > clip->x1)
- obox->x0 = clip->x1;
-
- if (obox->y0 < clip->y0)
- obox->y0 = clip->y0;
- else if (obox->y0 > clip->y1)
- obox->y0 = clip->y1;
-
- if (obox->x1 < clip->x0)
- obox->x1 = clip->x0;
- else if (obox->x1 > clip->x1)
- obox->x1 = clip->x1;
-
- if (obox->y1 < clip->y0)
- obox->y1 = clip->y0;
- else if (obox->y1 > clip->y1)
- obox->y1 = clip->y1;
- }
-
- os_error *misc_template(char *name, wimp_wind **wdefp)
- { wimp_wind *wdef;
-
- if (wdef = template_syshandle(name), !wdef)
- return misc_err("misc1:Can't find template %s", name);
-
- *wdefp = wdef;
-
- return NULL;
- }
-
- BOOL misc_overlap(wimp_box *a, wimp_box *b)
- { return a->x0 < b->x1 && a->x1 > b->x0 &&
- a->y0 < b->y1 && a->y1 > b->y0;
- }
-
- BOOL misc_commonbox(wimp_box *obox, wimp_box *ibox)
- { if (!misc_overlap(obox, ibox))
- return FALSE;
-
- obox->x0 = misc_max(obox->x0, ibox->x0);
- obox->y0 = misc_max(obox->y0, ibox->y0);
- obox->x1 = misc_min(obox->x1, ibox->x1);
- obox->y1 = misc_min(obox->y1, ibox->y1);
-
- return TRUE;
- }
-
- void misc_boundbox(wimp_box *obox, wimp_box *ibox)
- { obox->x0 = misc_min(obox->x0, ibox->x0);
- obox->y0 = misc_min(obox->y0, ibox->y0);
- obox->x1 = misc_max(obox->x1, ibox->x1);
- obox->y1 = misc_max(obox->y1, ibox->y1);
- }
-
- void misc_makebox(wimp_box *obox, int x0, int y0, int x1, int y1)
- { obox->x0 = misc_min(x0, x1);
- obox->y0 = misc_min(y0, y1);
- obox->x1 = misc_max(x0, x1);
- obox->y1 = misc_max(y0, y1);
- }
-
- BOOL misc_inbox(wimp_box *box, int x, int y)
- { return x >= box->x0 && x < box->x1 && y >= box->y0 && y < box->y1;
- }
-
- /* Sprite plotting */
-
- typedef struct
- { int mode;
- BOOL notrans;
- sprite_pixtrans trans[16];
- sprite_factors factors;
- } misc_sprinfo;
-
- static struct
- { misc_sprinfo *info;
- int size, used;
- } misc__sic;
-
- void misc_newmode(void)
- { misc_xeig = bbc_vduvar(bbc_XEigFactor);
- misc_yeig = bbc_vduvar(bbc_YEigFactor);
- misc_pixx = 1 << misc_xeig;
- misc_pixy = 1 << misc_yeig;
-
- wimpt_noerr(wimp_readpalette(&misc_wimpcols));
-
- if (misc__sic.size > 0)
- { misc__sic.size =
- misc__sic.used = 0;
- free(misc__sic.info);
- misc__sic.info = NULL;
- }
- }
-
- os_error *misc_sprput(sprite_area *area, sprite_id *id, int x, int y)
- { sprite_info info;
- os_error *err;
- int hi, lo, mid;
-
- if (err = sprite_readsize(area, id, &info), err)
- return err;
-
- /* Find mapping for this mode in cache, and if not present add it */
-
- for (lo = 0, hi = misc__sic.used; lo <= hi; )
- { mid = (lo + hi) / 2;
-
- if (misc__sic.info[mid].mode < info.mode)
- lo = mid + 1;
- else if (misc__sic.info[mid].mode > info.mode)
- hi = mid - 1;
- else
- goto gotinfo;
- }
-
- /* Info wasn't found so make room for it */
-
- if (misc__sic.used >= misc__sic.size)
- { if (misc__sic.size > 0)
- { void *newp;
-
- if (newp = realloc(misc__sic.info, sizeof(misc_sprinfo) * (10 + misc__sic.size)), !newp)
- return misc_err("misc2");
-
- misc__sic.info = newp;
- }
- else
- { if (misc__sic.info = malloc(sizeof(misc_sprinfo) * 10), !misc__sic.info)
- return misc_err("misc2");
- }
- misc__sic.size += 10;
- }
-
- for (mid = 0; mid < misc__sic.used && misc__sic.info[mid].mode < info.mode; mid++)
- ;
-
- if (mid < misc__sic.used)
- memmove(&misc__sic.info[mid + 1],
- &misc__sic.info[mid],
- sizeof(misc_sprinfo) * (misc__sic.used - mid));
-
- misc__sic.info[mid].mode = info.mode;
-
- if (err = wimp_readpixtrans(area, id, &misc__sic.info[mid].factors, misc__sic.info[mid].trans), err)
- return err;
-
- if (bbc_modevar(info.mode, bbc_NColour) <= 15)
- { misc__sic.info[mid].notrans = TRUE;
-
- for (lo = 0; lo < 16; lo++)
- { if (misc__sic.info[mid].trans[lo] != lo)
- { misc__sic.info[mid].notrans = FALSE;
- break;
- }
-
- if (misc__sic.info[mid].factors.xmag != misc__sic.info[mid].factors.xdiv ||
- misc__sic.info[mid].factors.ymag != misc__sic.info[mid].factors.ydiv)
- misc__sic.info[mid].notrans = FALSE;
- }
- }
- else
- misc__sic.info[mid].notrans = FALSE;
-
- gotinfo:
-
- if (misc__sic.info[mid].notrans)
- return sprite_put_given(area, id, 8, x, y);
- else
- return sprite_put_scaled(area, id, 8, x, y, &misc__sic.info[mid].factors,
- misc__sic.info[mid].trans);
- }
-
- os_error *misc_sprputn(sprite_area *area, char *name, int x, int y)
- { sprite_id id;
- id.s.name = name;
- id.tag = sprite_id_name;
- return misc_sprput(area, &id, x, y);
- }
-
- #ifdef DEVELOPER
- os_error *misc__fix(char *file, int line, os_error *err)
- { if (err)
- tracker_printf("File %s, line %d: %s\n", file, line, err->errmess);
- else
- tracker_printf("File %s, line %d: misc_fix() invoked with NULL argument!\n");
- return err;
- }
- #endif
-
- #if 0
- os_error *misc_mousespeed(int dx, int dy)
- { int x, y;
- os_error *err;
- char wb[3];
-
- x = 194;
- if (err = os_byte(161, &x, &y), err)
- return misc_fix(err);
-
- wb[0] = 2;
- wb[1] = (dx == 0 ? y : dx);
- wb[2] = (dy == 0 ? y : dy);
-
- return os_word(21, wb);
- }
- #endif
-
- os_error *misc_settype(char *name, int ftype)
- { os_filestr fcb;
-
- fcb.action = 18;
- fcb.name = name;
- fcb.loadaddr = ftype;
-
- return os_file(&fcb);
- }
-
- os_error *misc_windowbox(wimp_box *box, BOOL shrink)
- { wimp_box scrn;
- int sx, sy;
- int bw, bh;
-
- scrn.x0 = LGAP;
- scrn.y0 = BGAP;
- scrn.x1 = ((bbc_vduvar(bbc_XWindLimit) - 1) << bbc_vduvar(bbc_XEigFactor)) - RGAP;
- scrn.y1 = ((bbc_vduvar(bbc_YWindLimit) - 1) << bbc_vduvar(bbc_YEigFactor)) - TGAP;
-
- sx = (scrn.x0 + scrn.x1) / 2;
- sy = (scrn.y0 + scrn.y1) / 2;
-
- if (shrink)
- { bw = (scrn.x1 - scrn.x0) / 2;
- bh = (scrn.y1 - scrn.y0) / 2;
- }
- else
- { bw = box->x1 - box->x0;
- bh = box->y1 - box->y0;
- }
-
- box->x0 = sx - bw / 2;
- box->y0 = sy - bh / 2;
- box->x1 = box->x0 + bw;
- box->y1 = box->y0 + bh;
-
- if (box->y0 + offset - MARGIN < scrn.y0)
- offset = scrn.y1 - box->y1 - MARGIN;
-
- box->y0 += offset;
- box->y1 += offset;
-
- offset -= 44;
-
- return NULL;
- }
-
- os_error *misc_opendir(char *dirname)
- { os_regset regs;
- char cbuf[300];
-
- sprintf(cbuf, "Filer_OpenDir %s", dirname);
- regs.r[0] = (int) cbuf;
-
- return os_swix(OS_CLI, ®s);
- }
-
- /* Safe memory management stuff */
-
- os_error *misc_falloc(void **ptr, int size)
- {
-
- if (!flex_alloc(ptr, size))
- return misc_err("misc2");
-
- return NULL;
- }
-
- os_error *misc_fextend(void **ptr, int by)
- { if (!flex_extend(ptr, by))
- return misc_err("misc2");
-
- return NULL;
- }
-
- os_error *misc_fmidextend(void **ptr, int at, int by)
- { if (!flex_midextend(ptr, at, by))
- return misc_err("misc2");
-
- return NULL;
- }
-
- int misc_fsize(void **ptr)
- { return flex_size(ptr);
- }
-
- void misc_ffree(void **ptr)
- { if (*ptr) flex_free(ptr);
- }
-
- #ifdef MEMTRACE
-
- typedef struct
- { char *file;
- int line;
- int size;
- } meminfo;
-
- typedef struct remember
- { struct remember *link;
- int tag; /* This is either the anchor for a flex block, or the returned
- * address for a malloc block.
- */
-
- meminfo original;
- meminfo latest;
- } remember;
-
- static remember *allmem;
-
- static remember *findmem(int tag)
- { remember *r;
-
- for (r = allmem; r; r = r->link)
- if (r->tag == tag)
- return r;
-
- return NULL;
- }
-
- static remember *unlink(remember *list, remember *r)
- { if (r == list)
- return list->link;
-
- list->link = unlink(list->link, r);
- return list;
- }
-
- static void losemem(char *file, int line, int tag)
- { remember *r;
-
- if (r = findmem(tag), !r)
- werr(TRUE, "%s: %d, Attempt to free nonexistant block %08x", file, line, tag);
-
- allmem = unlink(allmem, r);
- (free)(r);
- }
-
- static void remem(char *file, int line, int size, int tag)
- { remember *r;
- meminfo *i;
-
- if (r = findmem(tag), r)
- i = &(r->latest);
- else
- { if (r = (malloc)(sizeof(remember)), !r)
- werr(TRUE, "Not enough memory to remember allocation");
-
- r->tag = tag;
- i = &(r->original);
- r->latest.file = NULL;
- r->link = allmem;
- allmem = r;
- }
-
- i->file = file;
- i->line = line;
- i->size = size;
- }
-
- void __memreport(void)
- { remember *r;
-
- tracker_printf("\fMemory usage\n\n");
- tracker_printf("%-10s%-34s%s\n\n", "Tag", "Original", "Latest");
-
- for (r = allmem; r; r = r->link)
- {
- tracker_printf("%08x, %16s, %5d, %8d ", r->tag,
- r->original.file,
- r->original.line,
- r->original.size);
-
- if (r->latest.file)
- tracker_printf("%16s, %5d, %8d\n", r->latest.file,
- r->latest.line,
- r->latest.size);
- else
- tracker_printf("unchanged\n");
- }
- }
-
- /* Replace memory allocation routines */
-
- int __flex_alloc(char *name, int line, flex_ptr anchor, int n)
- { int ok = (flex_alloc)(anchor, n);
-
- if (ok) remem(name, line, n, (int) anchor);
- return ok;
- }
-
- int __flex_extend(char *name, int line, flex_ptr anchor, int n)
- { int ok = (flex_extend)(anchor, n);
- if (ok) remem(name, line, n, (int) anchor);
- return ok;
- }
-
- void __flex_free(char *name, int line, flex_ptr anchor)
- { name = name;
- line = line;
- losemem(name, line, (int) anchor);
- (flex_free)(anchor);
- }
-
- void *__malloc(char *name, int line, size_t size)
- { void *m = (malloc)(size);
-
- if (m)
- remem(name, line, size, (int) m);
-
- return m;
- }
-
- void *__realloc(char *name, int line, void *m, size_t size)
- { void *m2;
-
- m2 = (realloc)(m, size);
-
- if (m2)
- { losemem(name, line, (int) m);
- if (size) remem(name, line, size, (int) m2);
- }
-
- return m2;
- }
-
- void __free(char *name, int line, void *m)
- { name = name;
- line = line;
-
- if (m)
- losemem(name, line, (int) m);
- (free)(m);
- }
-
- os_error *(misc_malloc)(char *name, int line, void **ptr, int size)
- { void *mem = NULL;
-
- if (size && (mem = __malloc(name, line, size), !mem))
- return misc_err("misc2");
-
- *ptr = mem;
- return NULL;
- }
-
- void (misc_free)(char *name, int line, void **ptr)
- { if (*ptr) __free(name, line, *ptr);
- *ptr = NULL;
- }
-
- #else
- void __memreport(void) {}
-
- os_error *misc_malloc(void **ptr, int size)
- { void *mem = NULL;
-
- if (size && (mem = malloc(size), !mem))
- return misc_err("misc2");
-
- *ptr = mem;
- return NULL;
- }
-
- void misc_free(void **ptr)
- { if (*ptr) free(*ptr);
- *ptr = NULL;
- }
-
- #endif
-
- os_error *misc_force(wimp_w w)
- { wimp_wstate state;
- wimp_redrawstr r;
- os_error *err;
-
- r.w = w;
-
- if (err = wimp_get_wind_state(r.w, &state), err)
- return misc_fix(err);
-
- r.box = state.o.box;
- coords_box_toworkarea(&r.box, (coords_cvtstr *) &state.o.box);
-
- return wimp_force_redraw(&r);
- }
-
- os_error *misc_chtitle(wimp_w w)
- { wimp_wstate state;
- wimp_redrawstr r;
- os_error *err;
-
- r.w = w;
-
- if (err = wimp_get_wind_state(r.w, &state), err)
- return misc_fix(err);
-
- if (!(state.flags & wimp_WOPEN))
- return NULL;
-
- if (err = wimp_getwindowoutline(&r), err)
- return misc_fix(err);
-
- r.box.y0 = state.o.box.y1;
- r.w = -1;
-
- return wimp_force_redraw(&r);
- }
-
- void misc_growbox(wimp_box *box, int dx, int dy)
- { box->x0 -= dx;
- box->y0 -= dy;
- box->x1 += dx;
- box->y1 += dy;
- }
-
- static os_error *misc__getsprites(void)
- { os_regset regs;
-
- regs.r[0] = (int) "%IconSprites <AWMerge$Dir>.!Sprites";
- return os_swix(OS_CLI, ®s);
-
- }
-
- static BOOL ukproc(wimp_eventstr *e, void *handle)
- { handle = handle;
-
- switch (e->e)
- { case wimp_ESEND:
- case wimp_ESENDWANTACK:
- switch (e->data.msg.hdr.action)
- { case wimp_MMODECHANGE:
- wimpt_noerr(misc__getsprites());
- case wimp_PALETTECHANGE:
- misc_newmode();
- break;
- }
- }
- return FALSE;
- }
-
- int misc_wimpver(void)
- { return wimpver;
- }
-
- void misc_report(char *tag, ...)
- { va_list ap;
- static char msg[256];
-
- va_start(ap, tag);
- vsprintf(msg, msgs_lookup(tag), ap);
- va_end(ap);
-
- werr(FALSE, msg);
- }
-
- int misc_min(int a, int b)
- { return a < b ? a : b;
- }
-
- int misc_max(int a, int b)
- { return a > b ? a : b;
- }
-
- char *misc_leaf(char *fname)
- { char *leafp;
-
- for (leafp = fname; *fname; ++fname)
- { if (*fname == '.' || *fname == ':')
- leafp = fname+1;
- }
-
- return leafp;
- }
-
- os_error *misc_strdup(char **dest, const char *source)
- { os_error *err;
-
- if (err = misc_malloc((void **) dest, strlen(source) + 1), err)
- return misc_fix(err);
-
- strcpy(*dest, source);
-
- return NULL;
- }
-
- int misc_strcicmp(const char *s1, const char *s2)
- { while (*s1 && toupper(*s1) == toupper(*s2))
- s1++, s2++;
-
- return toupper(*s1) - toupper(*s2);
- }
-
- os_error *misc_counticons(wimp_w w, int *countp)
- { wimp_i i;
- wimp_icon icn;
- os_error *err;
-
- for (i = 0; ; i++)
- { if (err = wimp_get_icon_info(w, i, &icn), err)
- return misc_fix(err);
-
- if (icn.flags == wimp_IDELETED)
- { *countp = i;
- return NULL;
- }
- }
-
- return NULL;
- }
-
- os_error *misc_icontextlen(wimp_w w, wimp_i i, int *lenp)
- { wimp_icon icn;
- os_error *err;
- char *s;
- int l;
-
- if (err = wimp_get_icon_info(w, i, &icn), err) return misc_fix(err);
-
- if (icn.flags & wimp_ITEXT)
- { if (icn.flags & wimp_INDIRECT)
- s = icn.data.indirecttext.buffer;
- else
- s = icn.data.text;
-
- for (l = 0; *s >= ' '; s++, l++)
- ;
-
- *lenp = l;
- }
- else
- *lenp = 0;
-
- return NULL;
- }
-
- /* Advance the caret to the end of the next writeable icon if there is one,
- * and return FALSE through wrap or if there are no more writeables put the
- * caret into limbo (still in the window, but no particular icon) and return
- * TRUE through wrap. If misc_nextwriteable() is called when the caret is in
- * 'limbo' the first writeable will be selected. Circular caret motion can
- * be created by calling this function, checking wrap, and if it's set call
- * this function again.
- */
- os_error *misc_nextwriteable(wimp_w w, BOOL *wrap)
- { os_error *err;
- int icons;
- wimp_caretstr c;
- wimp_i i;
- wimp_icon icn;
-
- if (err = misc_counticons(w, &icons), err) return misc_fix(err);
-
- if (err = wimp_get_caret_pos(&c), err) return misc_fix(err);
-
- /* c.i + 1 handles case where i == -1 correctly */
-
- for (i = (c.i < 0 || c.i >= icons) ? 0 : c.i + 1; i < icons; i++)
- { if (err = wimp_get_icon_info(w, i, &icn), err) return misc_fix(err);
-
- if (((icn.flags >> 12) & 0x0E) == 0x0E)
- break;
- }
-
- if (i < icons)
- { c.w = w;
- c.i = i;
- c.x = 0;
- c.y = 0;
- c.height = -1;
-
- if (err = misc_icontextlen(w, i, &c.index), err)
- return misc_fix(err);
-
- *wrap = FALSE;
-
- if (err = wimp_set_caret_pos(&c), err)
- return misc_fix(err);
-
- }
- else
- *wrap = TRUE;
-
- return NULL;
- }
-
- os_error *misc_prevwriteable(wimp_w w, BOOL *wrap)
- { os_error *err;
- int icons;
- wimp_caretstr c;
- wimp_i i;
- wimp_icon icn;
-
- if (err = misc_counticons(w, &icons), err) return misc_fix(err);
- if (err = wimp_get_caret_pos(&c), err) return misc_fix(err);
-
- for (i = (c.i < 0 || c.i >= icons) ? icons-1 : c.i-1; i >= 0; i--)
- { if (err = wimp_get_icon_info(w, i, &icn), err) return misc_fix(err);
-
- if (((icn.flags >> 12) & 0x0E) == 0x0E)
- break;
- }
-
- if (i >= 0)
- { c.w = w;
- c.i = i;
- c.x = 0;
- c.y = 0;
- c.height = -1;
-
- if (err = misc_icontextlen(w, i, &c.index), err)
- return misc_fix(err);
-
- *wrap = FALSE;
-
- if (err = wimp_set_caret_pos(&c), err)
- return misc_fix(err);
-
- }
- else
- *wrap = TRUE;
-
- return NULL;
- }
-
- os_error *misc_fillrect(wimp_box *box)
- { if (box->x1 > box->x0 && box->y1 > box->y0)
- { bbc_move(box->x0, box->y0);
- bbc_plot(bbc_RectangleFill | bbc_DrawAbsFore,
- box->x1 - 1, box->y1 - 1);
- }
- return NULL;
- }
-
- os_error *misc_setfontrgb(int fh, int bcol, int fcol)
- { os_regset regs;
-
- regs.r[0] = (int) fh;
- regs.r[1] = bcol;
- regs.r[2] = fcol;
- regs.r[3] = 14;
-
- return os_swix(ColourTrans_SetFontColours, ®s);
- }
-
- os_error *misc_setfontcolours(int fh, int bcol, int fcol)
- { os_regset regs;
-
- regs.r[0] = (int) fh;
- regs.r[1] = misc_wimpcols.c[bcol].word;
- regs.r[2] = misc_wimpcols.c[fcol].word;
- regs.r[3] = 14;
-
- return os_swix(ColourTrans_SetFontColours, ®s);
- }
-
- os_error *misc_settitle(wimp_w w, char *title)
- { os_error *err;
- int nicons;
- wimp_winfo *info;
-
- if (err = misc_counticons(w, &nicons), err) return err;
-
- if (err = misc_malloc((void **) &info, sizeof(wimp_winfo) + sizeof(wimp_icon) * nicons), err)
- return err;
-
- info->w = w;
-
- if (err = wimp_get_wind_info(info), err) goto fail;
-
- strncpy(info->info.title.indirecttext.buffer, title, info->info.title.indirecttext.bufflen-1);
- info->info.title.indirecttext.buffer[info->info.title.indirecttext.bufflen-1] = '\0';
-
- misc_free((void **) &info);
-
- return misc_chtitle(w);
-
- fail:
- misc_free((void **) &info);
- return err;
- }
-
- int misc_init(char *taskname)
- { misc__sic.size =
- misc__sic.used = 0;
- misc__sic.info = NULL;
- misc_newmode();
- win_add_unknown_event_processor(ukproc, NULL);
- #ifdef FAKE_RISCOS_2
- wimpt_init(taskname);
- wimpver = 200;
- return 200;
- #else
- return wimpver = wimpt_init(taskname), wimpver;
- #endif
- }
-