home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 3 / PDCD_3.iso / utilities / utilsd / explain / !Explain / c / main < prev    next >
Encoding:
Text File  |  1995-03-21  |  18.9 KB  |  779 lines

  1. /* main.c */
  2.  
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <ctype.h>
  6.  
  7. #include "swis.h"
  8.  
  9. #include "bbc.h"
  10. #include "wimp.h"
  11. #include "wimpt.h"
  12. #include "template.h"
  13. #include "alarm.h"
  14. #include "visdelay.h"
  15. #include "res.h"
  16. #include "resspr.h"
  17. #include "msgs.h"
  18. #include "version.h"
  19. #include "werr.h"
  20. #include "win.h"
  21. #include "event.h"
  22. #include "font.h"
  23. #include "coords.h"
  24. #include "baricon.h"
  25. #include "dbox.h"
  26. #include "help.h"
  27. #include "options.h"
  28. #include "flex.h"
  29.  
  30. #include "intalk.h"
  31.  
  32. #include "misc.h"
  33. #include "lookup.h"
  34.  
  35. #include "tracker.h"
  36.  
  37. #define main_HELPMAX     4096
  38. #define main_HELPMAXLINE 100
  39. #define main_HELPLMAX    256
  40.  
  41. #define main_TFONT       "Homerton.Medium"
  42. #define main_SFONT       "WIMPSymbol"
  43. #define main_FONTSIZE    10
  44. #define main_DFONT       "BitFont.Medium"
  45. #define main_DSIZE       12
  46.  
  47. #define main_MARGIN 16
  48.  
  49. enum { menu_INFO = 1, menu_QUIT };
  50.  
  51. typedef struct main__font
  52. {  struct main__font *downgrade;
  53.    char              name[40];
  54.    int               size;
  55. } main__font;
  56.  
  57. static wimp_w panel, shadow;
  58. static wimp_i icon;
  59. static char main_helpbuf[main_HELPMAX];
  60. static char main_newbuf[main_HELPMAX];
  61. static char main_lbuf[main_HELPLMAX];
  62. static int  main__wimpver;
  63. static main__font *main__text, *main__symbols;
  64.  
  65. /* Formatting information for the text in main_helpbuf */
  66.  
  67. static struct
  68. {  char *lp;
  69.    int len;
  70. } main__fline[main_HELPMAXLINE];
  71. static int lused;
  72. static int lspc, base;
  73. static BOOL active;
  74.  
  75. #define main__iswimp(c) ((c) >= 0x80 && (c) < 0x90)
  76.  
  77. static main__font *main__declarefont(char *name, int size, main__font *downgrade)
  78. {  main__font *fnt;
  79.  
  80.    if (fnt = malloc(sizeof(main__font)), !fnt)
  81.       werr(TRUE, "No memory for font data");
  82.  
  83.    fnt->downgrade = downgrade;
  84.    strcpy(fnt->name, name);
  85.    fnt->size = size;
  86.  
  87.    return fnt;
  88. }
  89.  
  90. static os_error *main__findfont(main__font *font, font *hp)
  91. {  os_error *err;
  92.  
  93.    if (err = font_find(font->name, font->size * 16, font->size * 16, 0, 0, hp), !err)
  94.       return NULL;
  95.  
  96.    if (font->downgrade) return main__findfont(font->downgrade, hp);
  97.    return err;
  98. }
  99.  
  100. static char *main__process(char *s, font tf, font sf)
  101. {  int bp;
  102.    BOOL sym = FALSE;
  103.  
  104.    bp = 0;
  105.    main_lbuf[bp++] = 26;
  106.    main_lbuf[bp++] = tf;
  107.  
  108.    while (*s && bp < main_HELPLMAX-4)
  109.    {  if (main__iswimp(*s))
  110.       {  if (!sym)
  111.          {  main_lbuf[bp++] = 26;
  112.             main_lbuf[bp++] = sf;
  113.             sym = TRUE;
  114.          }
  115.       }
  116.       else
  117.       {  if (sym)
  118.          {  main_lbuf[bp++] = 26;
  119.             main_lbuf[bp++] = tf;
  120.             sym = FALSE;
  121.          }
  122.       }
  123.       
  124.       main_lbuf[bp++] = *s++;
  125.    }
  126.  
  127.    main_lbuf[bp] = '\0';
  128.  
  129.    return main_lbuf;
  130. }
  131.  
  132. static os_error *main__open(int x, int y, int newheight)
  133. {  wimp_wstate state;
  134.    os_error *err;
  135.    int rx = (bbc_vduvar(bbc_XWindLimit) + 1) << bbc_vduvar(bbc_XEigFactor);
  136.  
  137.    if (err = wimp_get_wind_state(panel, &state), err) return err;
  138.  
  139.    if (*main_helpbuf == '\0' || !active)
  140.    {  if (state.flags & wimp_WOPEN)
  141.       {   if ((err = wimp_close_wind(panel), err) ||
  142.              (err = wimp_close_wind(shadow), err))
  143.             return err;
  144.       }
  145.       return NULL;
  146.    }
  147.  
  148.    state.o.behind = -1;
  149.  
  150.    /* change height? */
  151.  
  152.    if (newheight >= 0) state.o.box.y0 = state.o.box.y1 - newheight;
  153.  
  154.    misc_boxto(&state.o.box, x + 32, y - 32 - (state.o.box.y1 - state.o.box.y0));
  155.  
  156.    if (state.o.box.x1 + 16 + 16 > rx)
  157.       misc_boxby(&state.o.box, -(state.o.box.x1 - state.o.box.x0 + 16 + 16 + 48), 0);
  158.  
  159.    if (state.o.box.y0 - 16 - 16 < 0)
  160.       misc_boxby(&state.o.box, 0, state.o.box.y1 - state.o.box.y0 + 16 + 16);
  161.  
  162.    if (err = wimp_open_wind(&state.o), err) return err;
  163.  
  164.    misc_boxby(&state.o.box, 16, -16);
  165.  
  166.    state.o.w = shadow;
  167.    state.o.behind = panel;
  168.  
  169.    if (err = wimp_open_wind(&state.o), err) return err;
  170.  
  171.    return NULL;
  172. }
  173.  
  174. static os_error *main__paintbit(wimp_redrawstr *r)
  175. {  wimp_box clip, fill;
  176.    int fl, ll, l, eolc;
  177.    os_error *err;
  178.    font tf, sf;
  179.    os_regset regs;
  180.    struct
  181.    {  int spx, spy;
  182.       int ltx, lty;
  183.       int x0, y0, x1, y1;
  184.    } r5b;
  185.  
  186.    clip = r->g;
  187.    coords_box_toworkarea(&clip, (coords_cvtstr *) &r->box);
  188.  
  189.    if (err = main__findfont(main__text,    &tf), err) return err;
  190.    if (err = main__findfont(main__symbols, &sf), err) sf = (font) -1;
  191.  
  192.    fl = misc_max(-(clip.y1 + main_MARGIN) / lspc, 0);
  193.    ll = misc_min(-(clip.y0 + main_MARGIN) / lspc, lused-1);
  194.  
  195.    if (err = misc_setfontcolours(tf, 0, 7), err) goto fail1;
  196.    if (err = misc_setfontcolours(sf, 0, 7), err) goto fail1;
  197.  
  198.    /* Paint the bit before the first line */
  199.  
  200.    wimp_setcolour(0);
  201.  
  202.    fill.x0 = r->box.x0;
  203.    fill.y0 = r->box.y1 - r->scy - main_MARGIN;
  204.    fill.x1 = r->box.x1;
  205.    fill.y1 = r->box.y1;
  206.  
  207.    misc_fillrect(&fill);
  208.  
  209.    for (l = fl; l <= ll; l++)
  210.    {  r5b.spx = r5b.spy = 0;
  211.       r5b.ltx = r5b.lty = 0;
  212.       
  213.       r5b.x0 = r->box.x0 * 400;
  214.       r5b.y0 = (-(main_MARGIN + lspc * (l+1)) + r->box.y1 - r->scy) * 400;
  215.       r5b.x1 = r->box.x1 * 400;
  216.       r5b.y1 = r5b.y0 + lspc * 400;
  217.  
  218.       eolc = main__fline[l].lp[main__fline[l].len];
  219.       main__fline[l].lp[main__fline[l].len] = '\0';
  220.  
  221.       regs.r[0] = tf;
  222.       regs.r[1] = (int) (sf == (font) -1 ? main__fline[l].lp : main__process(main__fline[l].lp, tf, sf));
  223.       regs.r[2] = 0x322;
  224.       regs.r[3] = (main_MARGIN + r->box.x0 - r->scx) * 400;
  225.       regs.r[4] = (-(main_MARGIN + lspc * (l+1)) + base + r->box.y1 - r->scy) * 400;
  226.       regs.r[5] = (int) &r5b;
  227.       regs.r[6] = 0;
  228.       regs.r[7] = 0;
  229.  
  230.       if (err = os_swix(Font_Paint, ®s), err) goto fail1;
  231.  
  232.       main__fline[l].lp[main__fline[l].len] = eolc;
  233.    }
  234.  
  235.    wimp_setcolour(0);
  236.  
  237.    fill.x0 = r->box.x0;
  238.    fill.y0 = r->box.y0;
  239.    fill.x1 = r->box.x1;
  240.    fill.y1 = r->box.y1 - r->scy - main_MARGIN - lspc * lused;
  241.  
  242.    misc_fillrect(&fill);
  243.  
  244.    if (sf != (font) -1 && (err = font_lose(sf), err)) goto fail;
  245.    if (err = font_lose(tf), err) return err;
  246.  
  247.    return NULL;
  248.  
  249. fail1:
  250.    main__fline[l].lp[main__fline[l].len] = eolc;
  251.    if (sf != (font) -1) font_lose(sf);
  252. fail:
  253.    font_lose(tf);
  254.    return err;
  255. }
  256.  
  257. static os_error *main__update(int x, int y, int newheight, BOOL fixed)
  258. {  static int ox = -1000, oy = -1000;
  259.    static BOOL actwas = -1;
  260.    os_error *err;
  261.    int nx, ny;
  262.  
  263.    if ((!fixed && (x != ox || y != oy)) || active != actwas || newheight >= 0)
  264.    {  if (fixed) { nx = ox; ny = oy; } else { nx = x; ny = y; }
  265.       if (err = main__open(nx, ny, newheight), err) return err;
  266.       ox = nx;
  267.       oy = ny;
  268.       actwas = active;
  269.    }
  270.    return NULL;
  271. }
  272.  
  273. static os_error *main__splitat(char *bp, int maxw, int *splitpos, font tf, font sf)
  274. {  os_regset regs;
  275.    os_error *err;
  276.    BOOL iswimp;
  277.    char *sp, *ep;
  278.    int ec;
  279.  
  280.    struct
  281.    {  int spx, spy;
  282.       int ltx, lty;
  283.       int split;
  284.       int x0, y0, x1, y1;
  285.    } r5b;
  286.  
  287.    maxw *= 400;
  288.  
  289.    iswimp = main__iswimp(*bp);
  290.  
  291.    if (splitpos) *splitpos = strlen(bp);
  292.  
  293.    for (sp = bp; *sp; )
  294.    {  for (ep = sp; *ep && iswimp == main__iswimp(*ep); ep++)
  295.          ;
  296.  
  297.       ec = *ep;
  298.       *ep = '\0';
  299.  
  300.       regs.r[0] = (iswimp && sf != (font) -1) ? sf : tf;
  301.       regs.r[1] = (int) sp;                                               
  302.       regs.r[2] = 0x320;
  303.       regs.r[3] = maxw;  /* max. width before split */
  304.       regs.r[4] = 0x7FFFFFFF;
  305.       regs.r[5] = (int) &r5b;
  306.       regs.r[6] = 0;           /* not used */
  307.       regs.r[7] = 0;
  308.    
  309.       r5b.spx =
  310.       r5b.spy =
  311.       r5b.ltx =
  312.       r5b.lty = 0;
  313.       r5b.split = ' ';
  314.    
  315.       if (err = os_swix(Font_ScanString, ®s), err) return err;
  316.  
  317.       *ep = ec;  /* restore character */
  318.  
  319.       if ((char *) regs.r[1] < ep || *ep == '\0')
  320.       {  if (splitpos) *splitpos = (char *) regs.r[1] - bp;
  321.          return NULL;
  322.       }
  323.  
  324.       maxw -= regs.r[3];
  325.       sp = ep;
  326.       iswimp = !iswimp;
  327.    }
  328.  
  329.    return NULL;
  330. }
  331.  
  332. /* Format the contents of main_helpbuf */ 
  333.  
  334. static os_error *main__format()
  335. {  char *bp, *lp, *ep;
  336.    int eolc, lc, split, width;
  337.    font tf, sf;
  338.    wimp_wstate state;
  339.    os_error *err;
  340.    wimp_mousestr mse;
  341.  
  342.    if (err = wimp_get_wind_state(panel, &state), err) return err;
  343.  
  344.    width = state.o.box.x1 - state.o.box.x0 - main_MARGIN * 2;
  345.  
  346.    if (err = main__findfont(main__text,    &tf), err) return err;
  347.    if (err = main__findfont(main__symbols, &sf), err) sf = (font) -1;
  348.  
  349.    bp = main_helpbuf;
  350.    lp = bp + strlen(bp);
  351.    lc = 0; /* line count */
  352.  
  353.    do
  354.    {  for (ep = bp; ep < lp && *ep != '\n'; ep++) ;  /* end of buffer or '\n' */
  355.       eolc = *ep; *ep = '\0';   /* temp. term. line */
  356.  
  357.       /* split physical line into logical lines */
  358.  
  359.       do
  360.       {  main__fline[lc].lp = bp;  /* remember line start */
  361.          if (err = main__splitat(bp, width, &split, tf, sf), err) goto fail2;
  362.          main__fline[lc].len = split;
  363.  
  364.          if (++lc >= main_HELPMAXLINE)
  365.             goto done;
  366.  
  367.          bp += split;
  368.          while (bp < ep && *bp == ' ') bp++;
  369.  
  370.       } while (bp < ep);
  371.  
  372.       *ep = eolc;
  373.  
  374.       if (bp < lp && *bp == '\n') bp++;
  375.  
  376.    } while (bp < lp);
  377.  
  378. done: /* used when line count overflows */
  379.    lused = lc;
  380.  
  381.    font_lose(tf);
  382.    if (sf != -1) font_lose(sf);
  383.  
  384.    if (err = wimp_get_point_info(&mse), err) return err;
  385.    if (err = main__update(mse.x, mse.y, main_MARGIN * 2 + lspc * lused, bbc_inkey(-1)), err) return err;
  386.    if (err = misc_force(panel), err) return err;
  387.  
  388.    return NULL;
  389.  
  390. fail2:
  391.    *ep = eolc;
  392.    font_lose(tf);
  393.    if (sf != -1) font_lose(sf);
  394.    return err;
  395. }
  396.  
  397. /* Perform message expansion */
  398.  
  399. static char *main__expand(char *message)
  400. {  char *mp;
  401.    int bp;
  402.  
  403.    for (bp = 0, mp = message; bp < main_HELPMAX - 1 && *mp; )
  404.    {  if (*mp == '\\')
  405.       {  mp++;
  406.          if (*mp == '\\')
  407.             main_newbuf[bp++] = *mp++;
  408.          else
  409.          {  char tokn[8], *message;
  410.             int len;
  411.  
  412.             strcpy(tokn, "T?:?");
  413.             tokn[1] = *mp++;
  414.             message = lookup(tokn);
  415.  
  416.             len = misc_min(strlen(message), main_HELPMAX - 1 - bp);
  417.             strncpy(main_newbuf + bp, message, len);
  418.             bp += len;
  419.          }
  420.       }
  421.       else if (*mp == '|')
  422.       {  mp++;;
  423.          if (tolower(*mp) == 'm')
  424.          {  main_newbuf[bp++] = '\n';
  425.             mp++;;
  426.          }
  427.          else
  428.             main_newbuf[bp++] = *mp++;
  429.       }
  430.       else
  431.          main_newbuf[bp++] = *mp++;
  432.    }
  433.    
  434.    main_newbuf[bp] = '\0';
  435.  
  436.    return main_newbuf;
  437. }
  438.  
  439. static os_error *main__mkwind(wimp_w *wp, char *name)
  440. {  wimp_wind *wdef;
  441.    os_error *err;
  442.  
  443.    if (err = misc_template(name, &wdef), err) return err;
  444.    if (err = wimp_create_wind(wdef, wp), err) return err;
  445.    return NULL;
  446. }
  447.  
  448. static os_error *main__redraw(void)
  449. {  wimp_redrawstr r;
  450.    BOOL more;
  451.    os_error *err, *perr;
  452.  
  453.    r.w = panel;
  454.    if (err = wimp_redraw_wind(&r, &more), err) return err;
  455.  
  456.    perr = NULL;
  457.  
  458.    while (more)
  459.    {  if (!perr) perr = main__paintbit(&r);
  460.       if (err = wimp_get_rectangle(&r, &more), err) return err;
  461.    }
  462.  
  463.    return perr;
  464. }
  465.  
  466. static void main__handler(wimp_eventstr *e, void *handle)
  467. {  switch (e->e)
  468.    {  case wimp_EREDRAW:
  469.          wimpt_complain(main__redraw());
  470.          break;
  471.  
  472.       case wimp_EOPEN:
  473.          wimpt_complain(wimp_open_wind(&e->data.o));
  474.          break;
  475.    }
  476. }
  477.  
  478. static void main__gothelp(char *text)
  479. {  if (strcmp(main__expand(text), main_helpbuf) != 0)
  480.    {  strcpy(main_helpbuf, main_newbuf);
  481.       wimpt_complain(main__format());
  482.    }
  483. }
  484.  
  485. static char *main__getstockhelp(int icn, int sub)
  486. {  char token[32];
  487.    char *msg;                 
  488.  
  489.    if (sub == 0)
  490.       sprintf(token, "HelpI%d:(not found)", -icn);
  491.    else
  492.       sprintf(token, "HelpI%d%c:(not found)", -icn, 'a' + sub - 1);
  493.  
  494.    if (msg = lookup(token), strcmp(msg, "(not found)") == 0)
  495.       return NULL;
  496.  
  497.    return msg;
  498. }
  499.  
  500. static void main__fakehelp(void)
  501. {  main__gothelp("");
  502. }
  503.  
  504. static BOOL main__ukhandler(wimp_eventstr *e, void *handle)
  505. {  intalk_msgstr *msg;
  506.  
  507.    switch (e->e)
  508.    {  case wimp_ESEND:
  509.       case wimp_ESENDWANTACK:
  510.          if (help_process(e))  /* our help stuff! */
  511.             return TRUE;
  512.          else switch (e->data.msg.hdr.action)
  513.          {  case wimp_MHELPREPLY:
  514.                if (*e->data.msg.data.helpreply.text)
  515.                {  char *hp = e->data.msg.data.helpreply.text;
  516.  
  517.                   for (hp = e->data.msg.data.helpreply.text; *hp >= ' '; hp++)
  518.                      ;
  519.  
  520.                   *hp = '\0';   
  521.  
  522.                   /* Protect ourselves from unterminated strings */
  523.  
  524.                   main__gothelp(e->data.msg.data.helpreply.text);
  525.                }
  526.                else
  527.                   main__fakehelp();
  528.                return TRUE;
  529.  
  530.             case wimp_MHELPREQUEST:
  531.                if (e->data.msg.data.helprequest.m.w == -2 &&
  532.                    e->data.msg.data.helprequest.m.i == icon)
  533.                   help_reply(msgs_lookup("ihelp")); 
  534.                return TRUE;
  535.  
  536.             case (wimp_msgaction) intalk_MBALLOONSWITCH:
  537.                msg = (intalk_msgstr *) &e->data.msg;
  538.                active = msg->data.balloonswitch.show;                           
  539.                icon = baricon_newsprite(active ? "active" : "inactive");
  540.                msg->hdr.your_ref = msg->hdr.my_ref;
  541.                wimpt_complain(wimp_sendmessage(wimp_EACK, &e->data.msg, msg->hdr.task));
  542.                return TRUE;
  543.  
  544.             case (wimp_msgaction) intalk_MBALLOONRQSTATE:
  545.                msg = (intalk_msgstr *) &e->data.msg;
  546.                if (msg->hdr.task != wimpt_task())
  547.                {  msg->hdr.action = (wimp_msgaction) intalk_MBALLOONSTATEIS;
  548.                   msg->data.balloonswitch.show = active;
  549.                   msg->hdr.your_ref = msg->hdr.my_ref;
  550.                   wimpt_complain(wimp_sendmessage(wimp_ESEND, &e->data.msg, msg->hdr.task));
  551.                }
  552.                return TRUE;
  553.  
  554.             /* Means we're already loaded */   
  555.  
  556.             case (wimp_msgaction) intalk_MBALLOONSTATEIS:
  557.                exit(0);
  558.                return TRUE;
  559.          }
  560.          break;
  561.  
  562.       case wimp_EACK:
  563.          switch (e->data.msg.hdr.action)
  564.          {  case wimp_MHELPREQUEST:
  565.                main__fakehelp();
  566.                return TRUE;
  567.          }
  568.          break;
  569.    }
  570.  
  571.    return FALSE;
  572. }
  573.  
  574. static void main__alarm(int calledat, void *handle)
  575. {  wimp_mousestr mse;
  576.    char stocktext[200], *st;
  577.    int sub = 0;
  578.    static int click;
  579.  
  580.    calledat = calledat;
  581.  
  582.    wimpt_noerr(wimp_get_point_info(&mse));
  583.  
  584.    if (++click >= 10 && mse.w != -1 && mse.w != panel && mse.w != shadow)
  585.    {  wimp_msgstr msg;
  586.  
  587.       if (mse.w > 0 && mse.i <= -2 && mse.i >= -13)
  588.       {  *stocktext = '\0';
  589.    
  590.          st = main__getstockhelp(mse.i, sub++);
  591.          while (st)
  592.          {  strcat(stocktext, st);
  593.             st = main__getstockhelp(mse.i, sub++);
  594.          }   
  595.    
  596.          main__gothelp(stocktext);
  597.       }
  598.       else
  599.       {  msg.hdr.action = wimp_MHELPREQUEST;
  600.          msg.hdr.size   = sizeof(wimp_msghdr) + sizeof(wimp_mousestr);
  601.          msg.data.helprequest.m = mse;
  602.    
  603.          wimpt_complain(wimp_sendwmessage(wimp_ESENDWANTACK, &msg, mse.w, mse.i));
  604.       }
  605.       click = 0;
  606.    }
  607.  
  608.    wimpt_noerr(main__update(mse.x, mse.y, -1, bbc_inkey(-1)));
  609.  
  610.    alarm_set(alarm_timenow() + (active ? 1 : 50), main__alarm, handle);
  611. }
  612.  
  613. static os_error *main__fontinfo(void)
  614. {  os_error *err;
  615.    font tf;
  616.    font_info info;
  617.  
  618.    if (err = main__findfont(main__text, &tf), err) return err;
  619.    if (err = font_readinfo(tf, &info), err) goto fail;
  620.  
  621.    lspc = (info.maxy - info.miny) + 2;
  622.    base = -info.miny; /* height above baseline */
  623.  
  624.    font_lose(tf);
  625.    return NULL;
  626.  
  627. fail:
  628.    font_lose(tf);
  629.    return err;
  630.  
  631. }
  632.  
  633. static void main__barclick(wimp_i i)
  634. {  i = i;
  635.  
  636.    active = !active;
  637.    icon = baricon_newsprite(active ? "active" : "inactive");
  638. }
  639.  
  640. static os_error *main__info(void)
  641. {  dbox inf;
  642.  
  643.    if (inf = dbox_new("progInfo"), !inf)
  644.       return misc_err("main2");
  645.  
  646.    dbox_raw_eventhandler(inf, help_dboxrawevents, "info");
  647.  
  648.    dbox_setfield(inf, 3, "1.00 (29 Apr 94)");
  649.    dbox_show(inf);
  650.    dbox_fillin(inf);
  651.    dbox_dispose(&inf);
  652.  
  653.    return NULL;      
  654. }
  655.  
  656. static void main__menuhandler(void *handle, char *hit)
  657. {  handle = handle;
  658.  
  659.    switch (hit[0])
  660.    {  case menu_INFO:
  661.          if (hit[1]) wimpt_complain(main__info());
  662.          break;
  663.  
  664.       case menu_QUIT:
  665.          exit(0);
  666.          break;
  667.    }
  668. }
  669.  
  670. static wimp_msgaction okm[] =
  671. {  wimp_MDATASAVE, wimp_MDATASAVEOK, wimp_MDATALOAD, wimp_MDATALOADOK,
  672.    wimp_MDATAOPEN, wimp_MRAMFETCH, wimp_MRAMTRANSMIT, wimp_MPREQUIT,
  673.    wimp_PALETTECHANGE, wimp_SAVEDESK, wimp_MDEVICECLAIM, wimp_MDEVICEINUSE,
  674.    wimp_MDATASAVED, wimp_MMENUWARN, wimp_MMODECHANGE, wimp_MSLOTCHANGE,
  675.    wimp_MSETSLOT, wimp_MTASKNAMERQ, wimp_MTASKNAMEIS, wimp_MTASKSTARTED,
  676.    wimp_MHELPREQUEST, wimp_MHELPREPLY, wimp_MPrintFile, wimp_MWillPrint,
  677.    wimp_MPrintTypeOdd, wimp_MPrintTypeKnown, wimp_MPrinterChange,
  678.    (wimp_msgaction) intalk_MBALLOONSWITCH,
  679.    (wimp_msgaction) intalk_MBALLOONRQSTATE,
  680.    (wimp_msgaction) intalk_MBALLOONSTATEIS,
  681.    (wimp_msgaction) 0
  682. };
  683.  
  684. static os_error *main__getver(char *varname)
  685. {  os_regset regs;
  686.    os_error *err;
  687.    char varbuf[20];
  688.  
  689.    regs.r[0] = (int) varname;
  690.    regs.r[1] = (int) varbuf;
  691.    regs.r[2] = 19;
  692.    regs.r[3] = 0;
  693.    regs.r[4] = 3;
  694.  
  695.    if (err = os_swix(0x23 /* OS_ReadVarVal */, ®s), err) return err;
  696.    varbuf[regs.r[2]] = '\0';
  697.  
  698.    main__wimpver = atoi(varbuf);
  699.  
  700.    return NULL;
  701. }
  702.  
  703. int main(void)
  704. {  intalk_msgstr msg;
  705.    main__font *downgrade;
  706.    char tfont[256];
  707.    int  fontsize;
  708.  
  709.    wimpt_noerr(main__getver("Explain$WimpVer")); 
  710.  
  711. #ifdef LIBTRACE
  712.    trace_on();
  713. #endif   
  714.  
  715.    wimpt_wimpversion(main__wimpver > 200 ? 300 : 200); 
  716.    if (main__wimpver > 200) wimpt_messages(okm); 
  717.  
  718.    misc_init("Explain"); 
  719.    flex_init(); 
  720.  
  721.    visdelay_init(); 
  722.    visdelay_begin(); 
  723.  
  724.    res_init("Explain"); 
  725.  
  726.    resspr_init(); 
  727.    alarm_init(); 
  728.  
  729.    msgs_init(); 
  730.    wimpt_noerr(lookup_init("<Help$Msgs>"));   /* load help's token file */
  731.    
  732.    template_init(); 
  733.  
  734.    wimpt_noerr(options_init()); 
  735.  
  736.    wimpt_noerr(options_readstr("Explain$FontName", tfont, 255)); 
  737.    if (*tfont == '\0') strcpy(tfont, main_TFONT); 
  738.  
  739.    wimpt_noerr(options_readint("Explain$FontSize", &fontsize)); 
  740.    if (fontsize == 0) fontsize = main_FONTSIZE; 
  741.  
  742.    downgrade     = main__declarefont(main_DFONT, main_DSIZE, NULL); 
  743.    main__text    = main__declarefont(tfont,      fontsize,   downgrade); 
  744.    main__symbols = main__declarefont(main_SFONT, fontsize,   downgrade); 
  745.  
  746.    wimpt_noerr(main__fontinfo()); 
  747.  
  748.    if (__versionnumber() < 3.80)
  749.       werr(TRUE, "Explain has been linked with an out of date RISC OS library"); 
  750.  
  751.    wimpt_noerr(main__mkwind(&panel, "panel")); 
  752.    wimpt_noerr(main__mkwind(&shadow, "shadow")); 
  753.  
  754.    win_register_event_handler(panel, main__handler, NULL); 
  755.    win_register_event_handler(shadow, main__handler, NULL); 
  756.    win_add_unknown_event_processor(main__ukhandler, NULL); 
  757.  
  758.    alarm_set(alarm_timenow() + 1, main__alarm, NULL); 
  759.  
  760.    active = TRUE; 
  761.    icon = baricon("active", (int) resspr_area(), main__barclick); 
  762.  
  763.    event_attachmenu(win_ICONBAR,
  764.                     menu_new("Explain", msgs_lookup("main1")),
  765.                     main__menuhandler, NULL); 
  766.  
  767.    help_register_handler(help_simplehandler, "ihelp"); 
  768.  
  769.    msg.hdr.action = (wimp_msgaction) intalk_MBALLOONRQSTATE; 
  770.    msg.hdr.size   = sizeof(wimp_msghdr) + sizeof(intalk_balloonswitch); 
  771.  
  772.    wimpt_noerr(wimp_sendmessage(wimp_ESEND, (wimp_msgstr *) &msg, (wimp_t) 0)); 
  773.  
  774.    visdelay_end(); 
  775.  
  776.    for (;;)
  777.       event_process();
  778. }
  779.