home *** CD-ROM | disk | FTP | other *** search
- /* main.c */
-
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
-
- #include "swis.h"
-
- #include "bbc.h"
- #include "wimp.h"
- #include "wimpt.h"
- #include "template.h"
- #include "alarm.h"
- #include "visdelay.h"
- #include "res.h"
- #include "resspr.h"
- #include "msgs.h"
- #include "version.h"
- #include "werr.h"
- #include "win.h"
- #include "event.h"
- #include "font.h"
- #include "coords.h"
- #include "baricon.h"
- #include "dbox.h"
- #include "help.h"
- #include "options.h"
- #include "flex.h"
-
- #include "intalk.h"
-
- #include "misc.h"
- #include "lookup.h"
-
- #include "tracker.h"
-
- #define main_HELPMAX 4096
- #define main_HELPMAXLINE 100
- #define main_HELPLMAX 256
-
- #define main_TFONT "Homerton.Medium"
- #define main_SFONT "WIMPSymbol"
- #define main_FONTSIZE 10
- #define main_DFONT "BitFont.Medium"
- #define main_DSIZE 12
-
- #define main_MARGIN 16
-
- enum { menu_INFO = 1, menu_QUIT };
-
- typedef struct main__font
- { struct main__font *downgrade;
- char name[40];
- int size;
- } main__font;
-
- static wimp_w panel, shadow;
- static wimp_i icon;
- static char main_helpbuf[main_HELPMAX];
- static char main_newbuf[main_HELPMAX];
- static char main_lbuf[main_HELPLMAX];
- static int main__wimpver;
- static main__font *main__text, *main__symbols;
-
- /* Formatting information for the text in main_helpbuf */
-
- static struct
- { char *lp;
- int len;
- } main__fline[main_HELPMAXLINE];
- static int lused;
- static int lspc, base;
- static BOOL active;
-
- #define main__iswimp(c) ((c) >= 0x80 && (c) < 0x90)
-
- static main__font *main__declarefont(char *name, int size, main__font *downgrade)
- { main__font *fnt;
-
- if (fnt = malloc(sizeof(main__font)), !fnt)
- werr(TRUE, "No memory for font data");
-
- fnt->downgrade = downgrade;
- strcpy(fnt->name, name);
- fnt->size = size;
-
- return fnt;
- }
-
- static os_error *main__findfont(main__font *font, font *hp)
- { os_error *err;
-
- if (err = font_find(font->name, font->size * 16, font->size * 16, 0, 0, hp), !err)
- return NULL;
-
- if (font->downgrade) return main__findfont(font->downgrade, hp);
- return err;
- }
-
- static char *main__process(char *s, font tf, font sf)
- { int bp;
- BOOL sym = FALSE;
-
- bp = 0;
- main_lbuf[bp++] = 26;
- main_lbuf[bp++] = tf;
-
- while (*s && bp < main_HELPLMAX-4)
- { if (main__iswimp(*s))
- { if (!sym)
- { main_lbuf[bp++] = 26;
- main_lbuf[bp++] = sf;
- sym = TRUE;
- }
- }
- else
- { if (sym)
- { main_lbuf[bp++] = 26;
- main_lbuf[bp++] = tf;
- sym = FALSE;
- }
- }
-
- main_lbuf[bp++] = *s++;
- }
-
- main_lbuf[bp] = '\0';
-
- return main_lbuf;
- }
-
- static os_error *main__open(int x, int y, int newheight)
- { wimp_wstate state;
- os_error *err;
- int rx = (bbc_vduvar(bbc_XWindLimit) + 1) << bbc_vduvar(bbc_XEigFactor);
-
- if (err = wimp_get_wind_state(panel, &state), err) return err;
-
- if (*main_helpbuf == '\0' || !active)
- { if (state.flags & wimp_WOPEN)
- { if ((err = wimp_close_wind(panel), err) ||
- (err = wimp_close_wind(shadow), err))
- return err;
- }
- return NULL;
- }
-
- state.o.behind = -1;
-
- /* change height? */
-
- if (newheight >= 0) state.o.box.y0 = state.o.box.y1 - newheight;
-
- misc_boxto(&state.o.box, x + 32, y - 32 - (state.o.box.y1 - state.o.box.y0));
-
- if (state.o.box.x1 + 16 + 16 > rx)
- misc_boxby(&state.o.box, -(state.o.box.x1 - state.o.box.x0 + 16 + 16 + 48), 0);
-
- if (state.o.box.y0 - 16 - 16 < 0)
- misc_boxby(&state.o.box, 0, state.o.box.y1 - state.o.box.y0 + 16 + 16);
-
- if (err = wimp_open_wind(&state.o), err) return err;
-
- misc_boxby(&state.o.box, 16, -16);
-
- state.o.w = shadow;
- state.o.behind = panel;
-
- if (err = wimp_open_wind(&state.o), err) return err;
-
- return NULL;
- }
-
- static os_error *main__paintbit(wimp_redrawstr *r)
- { wimp_box clip, fill;
- int fl, ll, l, eolc;
- os_error *err;
- font tf, sf;
- os_regset regs;
- struct
- { int spx, spy;
- int ltx, lty;
- int x0, y0, x1, y1;
- } r5b;
-
- clip = r->g;
- coords_box_toworkarea(&clip, (coords_cvtstr *) &r->box);
-
- if (err = main__findfont(main__text, &tf), err) return err;
- if (err = main__findfont(main__symbols, &sf), err) sf = (font) -1;
-
- fl = misc_max(-(clip.y1 + main_MARGIN) / lspc, 0);
- ll = misc_min(-(clip.y0 + main_MARGIN) / lspc, lused-1);
-
- if (err = misc_setfontcolours(tf, 0, 7), err) goto fail1;
- if (err = misc_setfontcolours(sf, 0, 7), err) goto fail1;
-
- /* Paint the bit before the first line */
-
- wimp_setcolour(0);
-
- fill.x0 = r->box.x0;
- fill.y0 = r->box.y1 - r->scy - main_MARGIN;
- fill.x1 = r->box.x1;
- fill.y1 = r->box.y1;
-
- misc_fillrect(&fill);
-
- for (l = fl; l <= ll; l++)
- { r5b.spx = r5b.spy = 0;
- r5b.ltx = r5b.lty = 0;
-
- r5b.x0 = r->box.x0 * 400;
- r5b.y0 = (-(main_MARGIN + lspc * (l+1)) + r->box.y1 - r->scy) * 400;
- r5b.x1 = r->box.x1 * 400;
- r5b.y1 = r5b.y0 + lspc * 400;
-
- eolc = main__fline[l].lp[main__fline[l].len];
- main__fline[l].lp[main__fline[l].len] = '\0';
-
- regs.r[0] = tf;
- regs.r[1] = (int) (sf == (font) -1 ? main__fline[l].lp : main__process(main__fline[l].lp, tf, sf));
- regs.r[2] = 0x322;
- regs.r[3] = (main_MARGIN + r->box.x0 - r->scx) * 400;
- regs.r[4] = (-(main_MARGIN + lspc * (l+1)) + base + r->box.y1 - r->scy) * 400;
- regs.r[5] = (int) &r5b;
- regs.r[6] = 0;
- regs.r[7] = 0;
-
- if (err = os_swix(Font_Paint, ®s), err) goto fail1;
-
- main__fline[l].lp[main__fline[l].len] = eolc;
- }
-
- wimp_setcolour(0);
-
- fill.x0 = r->box.x0;
- fill.y0 = r->box.y0;
- fill.x1 = r->box.x1;
- fill.y1 = r->box.y1 - r->scy - main_MARGIN - lspc * lused;
-
- misc_fillrect(&fill);
-
- if (sf != (font) -1 && (err = font_lose(sf), err)) goto fail;
- if (err = font_lose(tf), err) return err;
-
- return NULL;
-
- fail1:
- main__fline[l].lp[main__fline[l].len] = eolc;
- if (sf != (font) -1) font_lose(sf);
- fail:
- font_lose(tf);
- return err;
- }
-
- static os_error *main__update(int x, int y, int newheight, BOOL fixed)
- { static int ox = -1000, oy = -1000;
- static BOOL actwas = -1;
- os_error *err;
- int nx, ny;
-
- if ((!fixed && (x != ox || y != oy)) || active != actwas || newheight >= 0)
- { if (fixed) { nx = ox; ny = oy; } else { nx = x; ny = y; }
- if (err = main__open(nx, ny, newheight), err) return err;
- ox = nx;
- oy = ny;
- actwas = active;
- }
- return NULL;
- }
-
- static os_error *main__splitat(char *bp, int maxw, int *splitpos, font tf, font sf)
- { os_regset regs;
- os_error *err;
- BOOL iswimp;
- char *sp, *ep;
- int ec;
-
- struct
- { int spx, spy;
- int ltx, lty;
- int split;
- int x0, y0, x1, y1;
- } r5b;
-
- maxw *= 400;
-
- iswimp = main__iswimp(*bp);
-
- if (splitpos) *splitpos = strlen(bp);
-
- for (sp = bp; *sp; )
- { for (ep = sp; *ep && iswimp == main__iswimp(*ep); ep++)
- ;
-
- ec = *ep;
- *ep = '\0';
-
- regs.r[0] = (iswimp && sf != (font) -1) ? sf : tf;
- regs.r[1] = (int) sp;
- regs.r[2] = 0x320;
- regs.r[3] = maxw; /* max. width before split */
- regs.r[4] = 0x7FFFFFFF;
- regs.r[5] = (int) &r5b;
- regs.r[6] = 0; /* not used */
- regs.r[7] = 0;
-
- r5b.spx =
- r5b.spy =
- r5b.ltx =
- r5b.lty = 0;
- r5b.split = ' ';
-
- if (err = os_swix(Font_ScanString, ®s), err) return err;
-
- *ep = ec; /* restore character */
-
- if ((char *) regs.r[1] < ep || *ep == '\0')
- { if (splitpos) *splitpos = (char *) regs.r[1] - bp;
- return NULL;
- }
-
- maxw -= regs.r[3];
- sp = ep;
- iswimp = !iswimp;
- }
-
- return NULL;
- }
-
- /* Format the contents of main_helpbuf */
-
- static os_error *main__format()
- { char *bp, *lp, *ep;
- int eolc, lc, split, width;
- font tf, sf;
- wimp_wstate state;
- os_error *err;
- wimp_mousestr mse;
-
- if (err = wimp_get_wind_state(panel, &state), err) return err;
-
- width = state.o.box.x1 - state.o.box.x0 - main_MARGIN * 2;
-
- if (err = main__findfont(main__text, &tf), err) return err;
- if (err = main__findfont(main__symbols, &sf), err) sf = (font) -1;
-
- bp = main_helpbuf;
- lp = bp + strlen(bp);
- lc = 0; /* line count */
-
- do
- { for (ep = bp; ep < lp && *ep != '\n'; ep++) ; /* end of buffer or '\n' */
- eolc = *ep; *ep = '\0'; /* temp. term. line */
-
- /* split physical line into logical lines */
-
- do
- { main__fline[lc].lp = bp; /* remember line start */
- if (err = main__splitat(bp, width, &split, tf, sf), err) goto fail2;
- main__fline[lc].len = split;
-
- if (++lc >= main_HELPMAXLINE)
- goto done;
-
- bp += split;
- while (bp < ep && *bp == ' ') bp++;
-
- } while (bp < ep);
-
- *ep = eolc;
-
- if (bp < lp && *bp == '\n') bp++;
-
- } while (bp < lp);
-
- done: /* used when line count overflows */
- lused = lc;
-
- font_lose(tf);
- if (sf != -1) font_lose(sf);
-
- if (err = wimp_get_point_info(&mse), err) return err;
- if (err = main__update(mse.x, mse.y, main_MARGIN * 2 + lspc * lused, bbc_inkey(-1)), err) return err;
- if (err = misc_force(panel), err) return err;
-
- return NULL;
-
- fail2:
- *ep = eolc;
- font_lose(tf);
- if (sf != -1) font_lose(sf);
- return err;
- }
-
- /* Perform message expansion */
-
- static char *main__expand(char *message)
- { char *mp;
- int bp;
-
- for (bp = 0, mp = message; bp < main_HELPMAX - 1 && *mp; )
- { if (*mp == '\\')
- { mp++;
- if (*mp == '\\')
- main_newbuf[bp++] = *mp++;
- else
- { char tokn[8], *message;
- int len;
-
- strcpy(tokn, "T?:?");
- tokn[1] = *mp++;
- message = lookup(tokn);
-
- len = misc_min(strlen(message), main_HELPMAX - 1 - bp);
- strncpy(main_newbuf + bp, message, len);
- bp += len;
- }
- }
- else if (*mp == '|')
- { mp++;;
- if (tolower(*mp) == 'm')
- { main_newbuf[bp++] = '\n';
- mp++;;
- }
- else
- main_newbuf[bp++] = *mp++;
- }
- else
- main_newbuf[bp++] = *mp++;
- }
-
- main_newbuf[bp] = '\0';
-
- return main_newbuf;
- }
-
- static os_error *main__mkwind(wimp_w *wp, char *name)
- { wimp_wind *wdef;
- os_error *err;
-
- if (err = misc_template(name, &wdef), err) return err;
- if (err = wimp_create_wind(wdef, wp), err) return err;
- return NULL;
- }
-
- static os_error *main__redraw(void)
- { wimp_redrawstr r;
- BOOL more;
- os_error *err, *perr;
-
- r.w = panel;
- if (err = wimp_redraw_wind(&r, &more), err) return err;
-
- perr = NULL;
-
- while (more)
- { if (!perr) perr = main__paintbit(&r);
- if (err = wimp_get_rectangle(&r, &more), err) return err;
- }
-
- return perr;
- }
-
- static void main__handler(wimp_eventstr *e, void *handle)
- { switch (e->e)
- { case wimp_EREDRAW:
- wimpt_complain(main__redraw());
- break;
-
- case wimp_EOPEN:
- wimpt_complain(wimp_open_wind(&e->data.o));
- break;
- }
- }
-
- static void main__gothelp(char *text)
- { if (strcmp(main__expand(text), main_helpbuf) != 0)
- { strcpy(main_helpbuf, main_newbuf);
- wimpt_complain(main__format());
- }
- }
-
- static char *main__getstockhelp(int icn, int sub)
- { char token[32];
- char *msg;
-
- if (sub == 0)
- sprintf(token, "HelpI%d:(not found)", -icn);
- else
- sprintf(token, "HelpI%d%c:(not found)", -icn, 'a' + sub - 1);
-
- if (msg = lookup(token), strcmp(msg, "(not found)") == 0)
- return NULL;
-
- return msg;
- }
-
- static void main__fakehelp(void)
- { main__gothelp("");
- }
-
- static BOOL main__ukhandler(wimp_eventstr *e, void *handle)
- { intalk_msgstr *msg;
-
- switch (e->e)
- { case wimp_ESEND:
- case wimp_ESENDWANTACK:
- if (help_process(e)) /* our help stuff! */
- return TRUE;
- else switch (e->data.msg.hdr.action)
- { case wimp_MHELPREPLY:
- if (*e->data.msg.data.helpreply.text)
- { char *hp = e->data.msg.data.helpreply.text;
-
- for (hp = e->data.msg.data.helpreply.text; *hp >= ' '; hp++)
- ;
-
- *hp = '\0';
-
- /* Protect ourselves from unterminated strings */
-
- main__gothelp(e->data.msg.data.helpreply.text);
- }
- else
- main__fakehelp();
- return TRUE;
-
- case wimp_MHELPREQUEST:
- if (e->data.msg.data.helprequest.m.w == -2 &&
- e->data.msg.data.helprequest.m.i == icon)
- help_reply(msgs_lookup("ihelp"));
- return TRUE;
-
- case (wimp_msgaction) intalk_MBALLOONSWITCH:
- msg = (intalk_msgstr *) &e->data.msg;
- active = msg->data.balloonswitch.show;
- icon = baricon_newsprite(active ? "active" : "inactive");
- msg->hdr.your_ref = msg->hdr.my_ref;
- wimpt_complain(wimp_sendmessage(wimp_EACK, &e->data.msg, msg->hdr.task));
- return TRUE;
-
- case (wimp_msgaction) intalk_MBALLOONRQSTATE:
- msg = (intalk_msgstr *) &e->data.msg;
- if (msg->hdr.task != wimpt_task())
- { msg->hdr.action = (wimp_msgaction) intalk_MBALLOONSTATEIS;
- msg->data.balloonswitch.show = active;
- msg->hdr.your_ref = msg->hdr.my_ref;
- wimpt_complain(wimp_sendmessage(wimp_ESEND, &e->data.msg, msg->hdr.task));
- }
- return TRUE;
-
- /* Means we're already loaded */
-
- case (wimp_msgaction) intalk_MBALLOONSTATEIS:
- exit(0);
- return TRUE;
- }
- break;
-
- case wimp_EACK:
- switch (e->data.msg.hdr.action)
- { case wimp_MHELPREQUEST:
- main__fakehelp();
- return TRUE;
- }
- break;
- }
-
- return FALSE;
- }
-
- static void main__alarm(int calledat, void *handle)
- { wimp_mousestr mse;
- char stocktext[200], *st;
- int sub = 0;
- static int click;
-
- calledat = calledat;
-
- wimpt_noerr(wimp_get_point_info(&mse));
-
- if (++click >= 10 && mse.w != -1 && mse.w != panel && mse.w != shadow)
- { wimp_msgstr msg;
-
- if (mse.w > 0 && mse.i <= -2 && mse.i >= -13)
- { *stocktext = '\0';
-
- st = main__getstockhelp(mse.i, sub++);
- while (st)
- { strcat(stocktext, st);
- st = main__getstockhelp(mse.i, sub++);
- }
-
- main__gothelp(stocktext);
- }
- else
- { msg.hdr.action = wimp_MHELPREQUEST;
- msg.hdr.size = sizeof(wimp_msghdr) + sizeof(wimp_mousestr);
- msg.data.helprequest.m = mse;
-
- wimpt_complain(wimp_sendwmessage(wimp_ESENDWANTACK, &msg, mse.w, mse.i));
- }
- click = 0;
- }
-
- wimpt_noerr(main__update(mse.x, mse.y, -1, bbc_inkey(-1)));
-
- alarm_set(alarm_timenow() + (active ? 1 : 50), main__alarm, handle);
- }
-
- static os_error *main__fontinfo(void)
- { os_error *err;
- font tf;
- font_info info;
-
- if (err = main__findfont(main__text, &tf), err) return err;
- if (err = font_readinfo(tf, &info), err) goto fail;
-
- lspc = (info.maxy - info.miny) + 2;
- base = -info.miny; /* height above baseline */
-
- font_lose(tf);
- return NULL;
-
- fail:
- font_lose(tf);
- return err;
-
- }
-
- static void main__barclick(wimp_i i)
- { i = i;
-
- active = !active;
- icon = baricon_newsprite(active ? "active" : "inactive");
- }
-
- static os_error *main__info(void)
- { dbox inf;
-
- if (inf = dbox_new("progInfo"), !inf)
- return misc_err("main2");
-
- dbox_raw_eventhandler(inf, help_dboxrawevents, "info");
-
- dbox_setfield(inf, 3, "1.00 (29 Apr 94)");
- dbox_show(inf);
- dbox_fillin(inf);
- dbox_dispose(&inf);
-
- return NULL;
- }
-
- static void main__menuhandler(void *handle, char *hit)
- { handle = handle;
-
- switch (hit[0])
- { case menu_INFO:
- if (hit[1]) wimpt_complain(main__info());
- break;
-
- case menu_QUIT:
- exit(0);
- break;
- }
- }
-
- static wimp_msgaction okm[] =
- { wimp_MDATASAVE, wimp_MDATASAVEOK, wimp_MDATALOAD, wimp_MDATALOADOK,
- wimp_MDATAOPEN, wimp_MRAMFETCH, wimp_MRAMTRANSMIT, wimp_MPREQUIT,
- wimp_PALETTECHANGE, wimp_SAVEDESK, wimp_MDEVICECLAIM, wimp_MDEVICEINUSE,
- wimp_MDATASAVED, wimp_MMENUWARN, wimp_MMODECHANGE, wimp_MSLOTCHANGE,
- wimp_MSETSLOT, wimp_MTASKNAMERQ, wimp_MTASKNAMEIS, wimp_MTASKSTARTED,
- wimp_MHELPREQUEST, wimp_MHELPREPLY, wimp_MPrintFile, wimp_MWillPrint,
- wimp_MPrintTypeOdd, wimp_MPrintTypeKnown, wimp_MPrinterChange,
- (wimp_msgaction) intalk_MBALLOONSWITCH,
- (wimp_msgaction) intalk_MBALLOONRQSTATE,
- (wimp_msgaction) intalk_MBALLOONSTATEIS,
- (wimp_msgaction) 0
- };
-
- static os_error *main__getver(char *varname)
- { os_regset regs;
- os_error *err;
- char varbuf[20];
-
- regs.r[0] = (int) varname;
- regs.r[1] = (int) varbuf;
- regs.r[2] = 19;
- regs.r[3] = 0;
- regs.r[4] = 3;
-
- if (err = os_swix(0x23 /* OS_ReadVarVal */, ®s), err) return err;
- varbuf[regs.r[2]] = '\0';
-
- main__wimpver = atoi(varbuf);
-
- return NULL;
- }
-
- int main(void)
- { intalk_msgstr msg;
- main__font *downgrade;
- char tfont[256];
- int fontsize;
-
- wimpt_noerr(main__getver("Explain$WimpVer"));
-
- #ifdef LIBTRACE
- trace_on();
- #endif
-
- wimpt_wimpversion(main__wimpver > 200 ? 300 : 200);
- if (main__wimpver > 200) wimpt_messages(okm);
-
- misc_init("Explain");
- flex_init();
-
- visdelay_init();
- visdelay_begin();
-
- res_init("Explain");
-
- resspr_init();
- alarm_init();
-
- msgs_init();
- wimpt_noerr(lookup_init("<Help$Msgs>")); /* load help's token file */
-
- template_init();
-
- wimpt_noerr(options_init());
-
- wimpt_noerr(options_readstr("Explain$FontName", tfont, 255));
- if (*tfont == '\0') strcpy(tfont, main_TFONT);
-
- wimpt_noerr(options_readint("Explain$FontSize", &fontsize));
- if (fontsize == 0) fontsize = main_FONTSIZE;
-
- downgrade = main__declarefont(main_DFONT, main_DSIZE, NULL);
- main__text = main__declarefont(tfont, fontsize, downgrade);
- main__symbols = main__declarefont(main_SFONT, fontsize, downgrade);
-
- wimpt_noerr(main__fontinfo());
-
- if (__versionnumber() < 3.80)
- werr(TRUE, "Explain has been linked with an out of date RISC OS library");
-
- wimpt_noerr(main__mkwind(&panel, "panel"));
- wimpt_noerr(main__mkwind(&shadow, "shadow"));
-
- win_register_event_handler(panel, main__handler, NULL);
- win_register_event_handler(shadow, main__handler, NULL);
- win_add_unknown_event_processor(main__ukhandler, NULL);
-
- alarm_set(alarm_timenow() + 1, main__alarm, NULL);
-
- active = TRUE;
- icon = baricon("active", (int) resspr_area(), main__barclick);
-
- event_attachmenu(win_ICONBAR,
- menu_new("Explain", msgs_lookup("main1")),
- main__menuhandler, NULL);
-
- help_register_handler(help_simplehandler, "ihelp");
-
- msg.hdr.action = (wimp_msgaction) intalk_MBALLOONRQSTATE;
- msg.hdr.size = sizeof(wimp_msghdr) + sizeof(intalk_balloonswitch);
-
- wimpt_noerr(wimp_sendmessage(wimp_ESEND, (wimp_msgstr *) &msg, (wimp_t) 0));
-
- visdelay_end();
-
- for (;;)
- event_process();
- }
-