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

  1. /* misc.c */
  2.  
  3. /*
  4. #define FAKE_RISCOS_2
  5. */
  6.  
  7. #include <stdio.h>
  8. #include <stdarg.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <ctype.h>
  12.  
  13. #include "os.h"
  14. #include "msgs.h"
  15. #include "swis.h"
  16. #include "sprite.h"
  17. #include "bbc.h"
  18. #include "wimp.h"
  19. #include "template.h"
  20. #include "colourtran.h"
  21. #include "flex.h"
  22. #include "coords.h"
  23. #include "misc.h"
  24. #include "wimpt.h"
  25. #include "win.h"
  26. #include "werr.h"
  27.  
  28. #include "tracker.h"
  29.  
  30. #define LGAP      4
  31. #define BGAP     44
  32. #define RGAP     44
  33. #define TGAP     44
  34.  
  35. #define MARGIN   40
  36.  
  37. static int offset = 0;
  38. static int wimpver;
  39.  
  40. int misc_xeig, misc_yeig, misc_pixx, misc_pixy;
  41. wimp_palettestr misc_wimpcols;
  42.  
  43. os_error *misc_err(char *msg, ...)
  44. {  static os_error eb;
  45.    va_list ap;
  46.  
  47.    va_start(ap, msg);
  48.    vsprintf(eb.errmess, msgs_lookup(msg), ap);
  49.    va_end(ap);
  50.  
  51.    return &eb;
  52. }
  53.  
  54. void misc_boxby(wimp_box *b, int dx, int dy)
  55. {  b->x0 += dx;
  56.    b->y0 += dy;
  57.    b->x1 += dx;
  58.    b->y1 += dy;
  59. }
  60.  
  61. void misc_boxto(wimp_box *b, int x, int y)
  62. {  misc_boxby(b, x - b->x0, y - b->y0);
  63. }
  64.  
  65. void misc_clipbox(wimp_box *obox, wimp_box *clip)
  66. {  if (obox->x0 < clip->x0)
  67.       obox->x0 = clip->x0;
  68.    else if (obox->x0 > clip->x1)
  69.       obox->x0 = clip->x1;
  70.  
  71.    if (obox->y0 < clip->y0)
  72.       obox->y0 = clip->y0;
  73.    else if (obox->y0 > clip->y1)
  74.       obox->y0 = clip->y1;
  75.  
  76.    if (obox->x1 < clip->x0)
  77.       obox->x1 = clip->x0;
  78.    else if (obox->x1 > clip->x1)
  79.       obox->x1 = clip->x1;
  80.  
  81.    if (obox->y1 < clip->y0)
  82.       obox->y1 = clip->y0;
  83.    else if (obox->y1 > clip->y1)
  84.       obox->y1 = clip->y1;
  85. }
  86.  
  87. os_error *misc_template(char *name, wimp_wind **wdefp)
  88. {  wimp_wind *wdef;
  89.  
  90.    if (wdef = template_syshandle(name), !wdef)
  91.       return misc_err("misc1:Can't find template %s", name);
  92.  
  93.    *wdefp = wdef;
  94.  
  95.    return NULL;
  96. }
  97.  
  98. BOOL misc_overlap(wimp_box *a, wimp_box *b)
  99. {  return a->x0 < b->x1 && a->x1 > b->x0 &&
  100.           a->y0 < b->y1 && a->y1 > b->y0;
  101. }
  102.  
  103. BOOL misc_commonbox(wimp_box *obox, wimp_box *ibox)
  104. {  if (!misc_overlap(obox, ibox))
  105.       return FALSE;
  106.  
  107.    obox->x0 = misc_max(obox->x0, ibox->x0);
  108.    obox->y0 = misc_max(obox->y0, ibox->y0);
  109.    obox->x1 = misc_min(obox->x1, ibox->x1);
  110.    obox->y1 = misc_min(obox->y1, ibox->y1);
  111.  
  112.    return TRUE;
  113. }
  114.  
  115. void misc_boundbox(wimp_box *obox, wimp_box *ibox)
  116. {  obox->x0 = misc_min(obox->x0, ibox->x0);
  117.    obox->y0 = misc_min(obox->y0, ibox->y0);
  118.    obox->x1 = misc_max(obox->x1, ibox->x1);
  119.    obox->y1 = misc_max(obox->y1, ibox->y1);
  120. }
  121.  
  122. void misc_makebox(wimp_box *obox, int x0, int y0, int x1, int y1)
  123. {  obox->x0 = misc_min(x0, x1);
  124.    obox->y0 = misc_min(y0, y1);
  125.    obox->x1 = misc_max(x0, x1);
  126.    obox->y1 = misc_max(y0, y1);
  127. }
  128.  
  129. BOOL misc_inbox(wimp_box *box, int x, int y)
  130. {  return x >= box->x0 && x < box->x1 && y >= box->y0 && y < box->y1;
  131. }
  132.  
  133. /* Sprite plotting */
  134.  
  135. typedef struct
  136. {  int mode;
  137.    BOOL notrans;
  138.    sprite_pixtrans trans[16];
  139.    sprite_factors  factors;
  140. } misc_sprinfo;
  141.  
  142. static struct
  143. {  misc_sprinfo *info;
  144.    int size, used;
  145. } misc__sic;
  146.  
  147. void misc_newmode(void)
  148. {  misc_xeig = bbc_vduvar(bbc_XEigFactor);
  149.    misc_yeig = bbc_vduvar(bbc_YEigFactor);
  150.    misc_pixx = 1 << misc_xeig;
  151.    misc_pixy = 1 << misc_yeig;
  152.  
  153.    wimpt_noerr(wimp_readpalette(&misc_wimpcols));
  154.  
  155.    if (misc__sic.size > 0)
  156.    {  misc__sic.size =
  157.       misc__sic.used = 0;
  158.       free(misc__sic.info);
  159.       misc__sic.info = NULL;
  160.    }
  161. }
  162.  
  163. os_error *misc_sprput(sprite_area *area, sprite_id *id, int x, int y)
  164. {  sprite_info info;
  165.    os_error *err;
  166.    int hi, lo, mid;
  167.  
  168.    if (err = sprite_readsize(area, id, &info), err)
  169.       return err;
  170.  
  171.    /* Find mapping for this mode in cache, and if not present add it */
  172.  
  173.    for (lo = 0, hi = misc__sic.used; lo <= hi; )
  174.    {  mid = (lo + hi) / 2;
  175.  
  176.       if (misc__sic.info[mid].mode < info.mode)
  177.          lo = mid + 1;
  178.       else if (misc__sic.info[mid].mode > info.mode)
  179.          hi = mid - 1;
  180.       else
  181.          goto gotinfo;
  182.    }
  183.  
  184.    /* Info wasn't found so make room for it */
  185.  
  186.    if (misc__sic.used >= misc__sic.size)
  187.    {  if (misc__sic.size > 0)
  188.       {  void *newp;
  189.  
  190.          if (newp = realloc(misc__sic.info, sizeof(misc_sprinfo) * (10 + misc__sic.size)), !newp)
  191.             return misc_err("misc2");
  192.  
  193.          misc__sic.info = newp;
  194.       }
  195.       else
  196.       {  if (misc__sic.info = malloc(sizeof(misc_sprinfo) * 10), !misc__sic.info)
  197.             return misc_err("misc2");
  198.       }
  199.       misc__sic.size += 10;
  200.    }
  201.  
  202.    for (mid = 0; mid < misc__sic.used && misc__sic.info[mid].mode < info.mode; mid++)
  203.       ;
  204.  
  205.    if (mid < misc__sic.used)
  206.       memmove(&misc__sic.info[mid + 1],
  207.               &misc__sic.info[mid],
  208.               sizeof(misc_sprinfo) * (misc__sic.used - mid));
  209.  
  210.    misc__sic.info[mid].mode = info.mode;
  211.    
  212.    if (err = wimp_readpixtrans(area, id, &misc__sic.info[mid].factors, misc__sic.info[mid].trans), err)
  213.       return err;
  214.  
  215.    if (bbc_modevar(info.mode, bbc_NColour) <= 15)
  216.    {  misc__sic.info[mid].notrans = TRUE;
  217.  
  218.       for (lo = 0; lo < 16; lo++)
  219.       {  if (misc__sic.info[mid].trans[lo] != lo)
  220.          {  misc__sic.info[mid].notrans = FALSE;
  221.             break;
  222.          }
  223.  
  224.          if (misc__sic.info[mid].factors.xmag != misc__sic.info[mid].factors.xdiv ||
  225.              misc__sic.info[mid].factors.ymag != misc__sic.info[mid].factors.ydiv)
  226.             misc__sic.info[mid].notrans = FALSE;
  227.       }
  228.    }
  229.    else
  230.       misc__sic.info[mid].notrans = FALSE;
  231.  
  232.    tracker_printf("Added info for mode %d sprites at position %d (%s)\n",
  233.                info.mode, mid, misc__sic.info[mid].notrans ? "notrans" : "trans");
  234.  
  235. gotinfo:
  236.  
  237.    if (misc__sic.info[mid].notrans)
  238.       return sprite_put_given(area, id, 8, x, y);
  239.    else
  240.       return sprite_put_scaled(area, id, 8, x, y, &misc__sic.info[mid].factors,
  241.                                                   misc__sic.info[mid].trans);
  242. }
  243.  
  244. #ifdef DEVELOPER
  245. os_error *misc__fix(char *file, int line, os_error *err)
  246. {  if (err)
  247.       tracker_printf("File %s, line %d: %s\n", file, line, err->errmess);
  248.    else
  249.       tracker_printf("File %s, line %d: misc_fix() invoked with NULL argument!\n");
  250.    return err;
  251. }
  252. #endif
  253.  
  254. #if 0
  255. os_error *misc_mousespeed(int dx, int dy)
  256. {  int x, y;
  257.    os_error *err;
  258.    char wb[3];
  259.  
  260.    x = 194;
  261.    if (err = os_byte(161, &x, &y), err)
  262.       return misc_fix(err);
  263.  
  264.    wb[0] = 2;
  265.    wb[1] = (dx == 0 ? y : dx);
  266.    wb[2] = (dy == 0 ? y : dy);
  267.  
  268.    return os_word(21, wb);
  269. }
  270. #endif
  271.  
  272. os_error *misc_settype(char *name, int ftype)
  273. {  os_filestr fcb;
  274.  
  275.    fcb.action   = 18;
  276.    fcb.name     = name;
  277.    fcb.loadaddr = ftype;
  278.  
  279.    return os_file(&fcb);
  280. }
  281.  
  282. os_error *misc_windowbox(wimp_box *box, BOOL shrink)
  283. {  wimp_box scrn;
  284.    int sx, sy;
  285.    int bw, bh;
  286.  
  287.    scrn.x0 = LGAP;
  288.    scrn.y0 = BGAP;
  289.    scrn.x1 = ((bbc_vduvar(bbc_XWindLimit) - 1) << bbc_vduvar(bbc_XEigFactor)) - RGAP;
  290.    scrn.y1 = ((bbc_vduvar(bbc_YWindLimit) - 1) << bbc_vduvar(bbc_YEigFactor)) - TGAP;
  291.  
  292.    sx = (scrn.x0 + scrn.x1) / 2;
  293.    sy = (scrn.y0 + scrn.y1) / 2;
  294.  
  295.    if (shrink)
  296.    {  bw = (scrn.x1 - scrn.x0) / 2;
  297.       bh = (scrn.y1 - scrn.y0) / 2;
  298.    }
  299.    else
  300.    {  bw = box->x1 - box->x0;
  301.       bh = box->y1 - box->y0;
  302.    }
  303.  
  304.    box->x0 = sx - bw / 2;
  305.    box->y0 = sy - bh / 2;
  306.    box->x1 = box->x0 + bw;
  307.    box->y1 = box->y0 + bh;
  308.  
  309.    if (box->y0 + offset - MARGIN < scrn.y0)
  310.       offset = scrn.y1 - box->y1 - MARGIN;
  311.  
  312.    box->y0 += offset;
  313.    box->y1 += offset;
  314.  
  315.    offset -= 44;
  316.  
  317.    return NULL;
  318. }
  319.  
  320. os_error *misc_opendir(char *dirname)
  321. {  os_regset regs;
  322.    char cbuf[300];
  323.  
  324.    sprintf(cbuf, "Filer_OpenDir %s", dirname);
  325.    regs.r[0] = (int) cbuf;
  326.  
  327.    return os_swix(OS_CLI, ®s);
  328. }
  329.  
  330. /* Safe memory management stuff */
  331.  
  332. os_error *misc_falloc(void **ptr, int size)
  333. {
  334.  
  335.    if (!flex_alloc(ptr, size))
  336.       return misc_err("misc2");
  337.  
  338.    return NULL;
  339. }
  340.  
  341. os_error *misc_fextend(void **ptr, int by)
  342. {  if (!flex_extend(ptr, by))
  343.       return misc_err("misc2");
  344.  
  345.    return NULL;
  346. }
  347.  
  348. os_error *misc_fmidextend(void **ptr, int at, int by)
  349. {  if (!flex_midextend(ptr, at, by))
  350.       return misc_err("misc2");
  351.  
  352.    return NULL;
  353. }
  354.  
  355. int misc_fsize(void **ptr)
  356. {  return flex_size(ptr);
  357. }
  358.  
  359. void misc_ffree(void **ptr)
  360. {  if (*ptr) flex_free(ptr);
  361. }
  362.  
  363. #ifdef MEMTRACE
  364.  
  365. typedef struct
  366. {  char *file;
  367.    int line;
  368.    int size;
  369. } meminfo;
  370.  
  371. typedef struct remember
  372. {  struct remember *link;
  373.    int tag;  /* This is either the anchor for a flex block, or the returned
  374.               * address for a malloc block.
  375.               */
  376.  
  377.    meminfo original;
  378.    meminfo latest;
  379. } remember;
  380.  
  381. static remember *allmem;
  382.  
  383. static remember *findmem(int tag)
  384. {  remember *r;
  385.  
  386.    for (r = allmem; r; r = r->link)
  387.       if (r->tag == tag)
  388.          return r;
  389.  
  390.    return NULL;
  391. }
  392.  
  393. static remember *unlink(remember *list, remember *r)
  394. {  if (r == list)
  395.       return list->link;
  396.  
  397.    list->link = unlink(list->link, r);
  398.    return list;
  399. }
  400.  
  401. static void losemem(char *file, int line, int tag)
  402. {  remember *r;
  403.  
  404.    if (r = findmem(tag), !r)
  405.       werr(TRUE, "%s: %d, Attempt to free nonexistant block %08x", file, line, tag);
  406.  
  407.    allmem = unlink(allmem, r);
  408.    (free)(r);
  409. }
  410.  
  411. static void remem(char *file, int line, int size, int tag)
  412. {  remember *r;
  413.    meminfo  *i;
  414.  
  415.    if (r = findmem(tag), r)
  416.       i = &(r->latest);
  417.    else
  418.    {  if (r = (malloc)(sizeof(remember)), !r)
  419.          werr(TRUE, "Not enough memory to remember allocation");
  420.  
  421.       r->tag = tag;
  422.       i = &(r->original);
  423.       r->latest.file = NULL;
  424.       r->link = allmem;
  425.       allmem = r;
  426.    }
  427.  
  428.    i->file = file;
  429.    i->line = line;
  430.    i->size = size;
  431. }
  432.  
  433. void __memreport(void)
  434. {  remember *r;
  435.  
  436.    tracker_printf("\fMemory usage\n\n");
  437.    tracker_printf("%-10s%-34s%s\n\n", "Tag", "Original", "Latest");
  438.  
  439.    for (r = allmem; r; r = r->link)
  440.    {
  441.       tracker_printf("%08x, %16s, %5d, %8d ", r->tag,
  442.                                               r->original.file,
  443.                                               r->original.line,
  444.                                               r->original.size);
  445.  
  446.       if (r->latest.file)
  447.          tracker_printf("%16s, %5d, %8d\n", r->latest.file,
  448.                                             r->latest.line,
  449.                                             r->latest.size);
  450.       else
  451.          tracker_printf("unchanged\n");
  452.    }
  453. }
  454.  
  455. /* Replace memory allocation routines */
  456.  
  457. int __flex_alloc(char *name, int line, flex_ptr anchor, int n)
  458. {  int ok = (flex_alloc)(anchor, n);
  459.  
  460.    if (ok) remem(name, line, n, (int) anchor);
  461.    return ok;
  462. }
  463.  
  464. int __flex_extend(char *name, int line, flex_ptr anchor, int n)
  465. {  int ok = (flex_extend)(anchor, n);
  466.    if (ok) remem(name, line, n, (int) anchor);
  467.    return ok;
  468. }
  469.  
  470. void __flex_free(char *name, int line, flex_ptr anchor)
  471. {  name = name;
  472.    line = line;
  473.    losemem(name, line, (int) anchor);
  474.    (flex_free)(anchor);
  475. }
  476.  
  477. void *__malloc(char *name, int line, size_t size)
  478. {  void *m = (malloc)(size);
  479.  
  480.    if (m)
  481.       remem(name, line, size, (int) m);
  482.  
  483.    return m;
  484. }
  485.  
  486. void *__realloc(char *name, int line, void *m, size_t size)
  487. {  void *m2;
  488.  
  489.    m2 = (realloc)(m, size);
  490.  
  491.    if (m2)
  492.    {  losemem(name, line, (int) m);
  493.       if (size) remem(name, line, size, (int) m2);
  494.    }
  495.  
  496.    return m2;
  497. }
  498.  
  499. void __free(char *name, int line, void *m)
  500. {  name = name;
  501.    line = line;
  502.  
  503.    if (m)
  504.       losemem(name, line, (int) m);
  505.    (free)(m);
  506. }
  507.  
  508. os_error *(misc_malloc)(char *name, int line, void **ptr, int size)
  509. {  void *mem = NULL;
  510.  
  511.    if (size && (mem = __malloc(name, line, size), !mem))
  512.       return misc_err("misc2");
  513.  
  514.    *ptr = mem;
  515.    return NULL;
  516. }
  517.  
  518. void (misc_free)(char *name, int line, void **ptr)
  519. {  if (*ptr) __free(name, line, *ptr);
  520.    *ptr = NULL;
  521. }
  522.  
  523. #else
  524. void __memreport(void) {}
  525.  
  526. os_error *misc_malloc(void **ptr, int size)
  527. {  void *mem = NULL;
  528.  
  529.    if (size && (mem = malloc(size), !mem))
  530.       return misc_err("misc2");
  531.  
  532.    *ptr = mem;
  533.    return NULL;
  534. }
  535.  
  536. void misc_free(void **ptr)
  537. {  if (*ptr) free(*ptr);
  538.    *ptr = NULL;
  539. }
  540.  
  541. #endif
  542.  
  543. os_error *misc_force(wimp_w w)
  544. {  wimp_wstate state;
  545.    wimp_redrawstr r;
  546.    os_error *err;
  547.  
  548.    r.w = w;
  549.  
  550.    if (err = wimp_get_wind_state(r.w, &state), err)
  551.       return misc_fix(err);
  552.  
  553.    r.box = state.o.box;
  554.    coords_box_toworkarea(&r.box, (coords_cvtstr *) &state.o.box);
  555.  
  556.    return wimp_force_redraw(&r);
  557. }
  558.  
  559. os_error *misc_chtitle(wimp_w w)
  560. {  wimp_wstate state;
  561.    wimp_redrawstr r;
  562.    os_error *err;
  563.  
  564.    r.w = w;
  565.  
  566.    if (err = wimp_get_wind_state(r.w, &state), err)
  567.       return misc_fix(err);
  568.  
  569.    if (!(state.flags & wimp_WOPEN))
  570.       return NULL;
  571.  
  572.    if (err = wimp_getwindowoutline(&r), err)
  573.       return misc_fix(err);
  574.  
  575.    r.box.y0 = state.o.box.y1;
  576.    r.w = -1;
  577.  
  578.    return wimp_force_redraw(&r);
  579. }
  580.  
  581. void misc_growbox(wimp_box *box, int dx, int dy)
  582. {  box->x0 -= dx;
  583.    box->y0 -= dy;
  584.    box->x1 += dx;
  585.    box->y1 += dy;
  586. }
  587.  
  588. static BOOL ukproc(wimp_eventstr *e, void *handle)
  589. {  handle = handle;
  590.  
  591.    switch (e->e)
  592.    {  case wimp_ESEND:
  593.       case wimp_ESENDWANTACK:
  594.          switch (e->data.msg.hdr.action)
  595.          {  case wimp_PALETTECHANGE:
  596.                misc_newmode();
  597.                break;
  598.          }
  599.    }
  600.    return FALSE;
  601. }
  602.  
  603. int misc_wimpver(void)
  604. {  return wimpver;
  605. }
  606.  
  607. void misc_report(char *tag, ...)
  608. {  va_list ap;
  609.    static char msg[256];
  610.  
  611.    va_start(ap, tag);
  612.    vsprintf(msg, msgs_lookup(tag), ap);
  613.    va_end(ap);
  614.  
  615.    werr(FALSE, msg);
  616. }
  617.  
  618. int misc_min(int a, int b)
  619. {  return a < b ? a : b;
  620. }
  621.  
  622. int misc_max(int a, int b)
  623. {  return a > b ? a : b;
  624. }
  625.  
  626. char *misc_leaf(char *fname)
  627. {  char *leafp;
  628.  
  629.    for (leafp = fname; *fname; ++fname)
  630.    {  if (*fname == '.' || *fname == ':')
  631.          leafp = fname+1;
  632.    }
  633.  
  634.    return leafp;
  635. }
  636.  
  637. os_error *misc_strdup(char **dest, const char *source)
  638. {  os_error *err;
  639.  
  640.    if (err = misc_malloc((void **) dest, strlen(source) + 1), err)
  641.       return misc_fix(err);
  642.  
  643.    strcpy(*dest, source);
  644.  
  645.    return NULL;
  646. }
  647.  
  648. int misc_strcicmp(const char *s1, const char *s2)
  649. {  while (*s1 && toupper(*s1) == toupper(*s2))
  650.       s1++, s2++;
  651.  
  652.    return toupper(*s1) - toupper(*s2);
  653. }
  654.  
  655. os_error *misc_counticons(wimp_w w, int *countp)
  656. {  wimp_i i;
  657.    wimp_icon icn;
  658.    os_error *err;
  659.  
  660.    for (i = 0; ; i++)
  661.    {  if (err = wimp_get_icon_info(w, i, &icn), err)
  662.          return misc_fix(err);
  663.  
  664.       if (icn.flags == wimp_IDELETED)
  665.       {  *countp = i;
  666.          return NULL;
  667.       }
  668.    }
  669.  
  670.    return NULL;
  671. }
  672.  
  673. os_error *misc_icontextlen(wimp_w w, wimp_i i, int *lenp)
  674. {  wimp_icon icn;
  675.    os_error *err;
  676.    char *s;
  677.    int l;
  678.  
  679.    if (err = wimp_get_icon_info(w, i, &icn), err) return misc_fix(err);
  680.  
  681.    if (icn.flags & wimp_ITEXT)
  682.    {  if (icn.flags & wimp_INDIRECT)
  683.          s = icn.data.indirecttext.buffer;
  684.       else
  685.          s = icn.data.text;
  686.  
  687.       for (l = 0; *s >= ' '; s++, l++)
  688.          ;
  689.  
  690.       *lenp = l;
  691.    }
  692.    else
  693.       *lenp = 0;
  694.  
  695.    return NULL;
  696. }
  697.  
  698. /* Advance the caret to the end of the next writeable icon if there is one,
  699.  * and return FALSE through wrap or if there are no more writeables put the
  700.  * caret into limbo (still in the window, but no particular icon) and return
  701.  * TRUE through wrap. If misc_nextwriteable() is called when the caret is in
  702.  * 'limbo' the first writeable will be selected. Circular caret motion can
  703.  * be created by calling this function, checking wrap, and if it's set call
  704.  * this function again.
  705.  */
  706. os_error *misc_nextwriteable(wimp_w w, BOOL *wrap)
  707. {  os_error *err;
  708.    int icons;
  709.    wimp_caretstr c;
  710.    wimp_i i;
  711.    wimp_icon icn;
  712.  
  713.    if (err = misc_counticons(w, &icons), err) return misc_fix(err);
  714.  
  715.    if (err = wimp_get_caret_pos(&c), err) return misc_fix(err);
  716.  
  717.    /* c.i + 1 handles case where i == -1 correctly */
  718.  
  719.    for (i = (c.i < 0 || c.i >= icons) ? 0 : c.i + 1; i < icons; i++)
  720.    {  if (err = wimp_get_icon_info(w, i, &icn), err) return misc_fix(err);
  721.  
  722.       if (((icn.flags >> 12) & 0x0E) == 0x0E)
  723.          break;
  724.    }
  725.  
  726.    if (i < icons)
  727.    {  c.w = w;
  728.       c.i = i;
  729.       c.x = 0;
  730.       c.y = 0;
  731.       c.height = -1;
  732.  
  733.       if (err = misc_icontextlen(w, i, &c.index), err)
  734.          return misc_fix(err);
  735.  
  736.       *wrap = FALSE;
  737.  
  738.       if (err = wimp_set_caret_pos(&c), err)
  739.          return misc_fix(err);
  740.  
  741.    }
  742.    else
  743.       *wrap = TRUE;
  744.  
  745.    return NULL;
  746. }
  747.  
  748. os_error *misc_prevwriteable(wimp_w w, BOOL *wrap)
  749. {  os_error *err;
  750.    int icons;
  751.    wimp_caretstr c;
  752.    wimp_i i;
  753.    wimp_icon icn;
  754.  
  755.    if (err = misc_counticons(w, &icons), err) return misc_fix(err);
  756.    if (err = wimp_get_caret_pos(&c), err) return misc_fix(err);
  757.  
  758.    for (i = (c.i < 0 || c.i >= icons) ? icons-1 : c.i-1; i >= 0; i--)
  759.    {  if (err = wimp_get_icon_info(w, i, &icn), err) return misc_fix(err);
  760.  
  761.       if (((icn.flags >> 12) & 0x0E) == 0x0E)
  762.          break;
  763.    }
  764.  
  765.    if (i >= 0)
  766.    {  c.w = w;
  767.       c.i = i;
  768.       c.x = 0;
  769.       c.y = 0;
  770.       c.height = -1;
  771.  
  772.       if (err = misc_icontextlen(w, i, &c.index), err)
  773.          return misc_fix(err);
  774.  
  775.       *wrap = FALSE;
  776.  
  777.       if (err = wimp_set_caret_pos(&c), err)
  778.          return misc_fix(err);
  779.  
  780.    }
  781.    else
  782.       *wrap = TRUE;
  783.  
  784.    return NULL;
  785. }
  786.  
  787. os_error *misc_fillrect(wimp_box *box)
  788. {  if (box->x1 > box->x0 && box->y1 > box->y0)
  789.    {  bbc_move(box->x0, box->y0);
  790.       bbc_plot(bbc_RectangleFill | bbc_DrawAbsFore,
  791.                box->x1 - 1, box->y1 - 1);
  792.    }
  793.    return NULL;
  794. }
  795.  
  796. os_error *misc_setfontrgb(int fh, int bcol, int fcol)
  797. {  os_regset regs;
  798.  
  799.    regs.r[0] = (int) fh;
  800.    regs.r[1] = bcol;
  801.    regs.r[2] = fcol;
  802.    regs.r[3] = 14;
  803.  
  804.    return os_swix(ColourTrans_SetFontColours, ®s);
  805. }
  806.  
  807. os_error *misc_setfontcolours(int fh, int bcol, int fcol)
  808. {  os_regset regs;
  809.  
  810.    regs.r[0] = (int) fh;
  811.    regs.r[1] = misc_wimpcols.c[bcol].word;
  812.    regs.r[2] = misc_wimpcols.c[fcol].word;
  813.    regs.r[3] = 14;
  814.  
  815.    return os_swix(ColourTrans_SetFontColours, ®s);
  816. }
  817.  
  818. os_error *misc_settitle(wimp_w w, char *title)
  819. {  os_error *err;
  820.    int nicons;
  821.    wimp_winfo *info;
  822.  
  823.    if (err = misc_counticons(w, &nicons), err) return err;
  824.  
  825.    if (err = misc_malloc((void **) &info, sizeof(wimp_winfo) + sizeof(wimp_icon) * nicons), err)
  826.       return err;
  827.  
  828.    info->w = w;
  829.  
  830.    if (err = wimp_get_wind_info(info), err) goto fail;
  831.  
  832.    strncpy(info->info.title.indirecttext.buffer, title, info->info.title.indirecttext.bufflen-1);
  833.    info->info.title.indirecttext.buffer[info->info.title.indirecttext.bufflen-1] = '\0';
  834.  
  835.    misc_free((void **) &info);
  836.  
  837.    return misc_chtitle(w);
  838.  
  839. fail:
  840.    misc_free((void **) &info);
  841.    return err;
  842. }
  843.  
  844. int misc_init(char *taskname)
  845. {  misc__sic.size =
  846.    misc__sic.used = 0;
  847.    misc__sic.info = NULL;
  848.    misc_newmode();
  849.    win_add_unknown_event_processor(ukproc, NULL);
  850. #ifdef FAKE_RISCOS_2
  851.    wimpt_init(taskname);
  852.    wimpver = 200;
  853.    return 200;
  854. #else
  855.    return wimpver = wimpt_init(taskname), wimpver;
  856. #endif
  857. }
  858.