home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 3 / PDCD_3.iso / utilities / utilsd / explain / !AWMerge / c / misc < prev   
Encoding:
Text File  |  1995-01-03  |  18.2 KB  |  872 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   80
  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. gotinfo:
  233.  
  234.    if (misc__sic.info[mid].notrans)
  235.       return sprite_put_given(area, id, 8, x, y);
  236.    else
  237.       return sprite_put_scaled(area, id, 8, x, y, &misc__sic.info[mid].factors,
  238.                                                   misc__sic.info[mid].trans);
  239. }
  240.  
  241. os_error *misc_sprputn(sprite_area *area, char *name, int x, int y)
  242. {  sprite_id id;
  243.    id.s.name = name;
  244.    id.tag    = sprite_id_name;
  245.    return misc_sprput(area, &id, x, y);
  246. }
  247.  
  248. #ifdef DEVELOPER
  249. os_error *misc__fix(char *file, int line, os_error *err)
  250. {  if (err)
  251.       tracker_printf("File %s, line %d: %s\n", file, line, err->errmess);
  252.    else
  253.       tracker_printf("File %s, line %d: misc_fix() invoked with NULL argument!\n");
  254.    return err;
  255. }
  256. #endif
  257.  
  258. #if 0
  259. os_error *misc_mousespeed(int dx, int dy)
  260. {  int x, y;
  261.    os_error *err;
  262.    char wb[3];
  263.  
  264.    x = 194;
  265.    if (err = os_byte(161, &x, &y), err)
  266.       return misc_fix(err);
  267.  
  268.    wb[0] = 2;
  269.    wb[1] = (dx == 0 ? y : dx);
  270.    wb[2] = (dy == 0 ? y : dy);
  271.  
  272.    return os_word(21, wb);
  273. }
  274. #endif
  275.  
  276. os_error *misc_settype(char *name, int ftype)
  277. {  os_filestr fcb;
  278.  
  279.    fcb.action   = 18;
  280.    fcb.name     = name;
  281.    fcb.loadaddr = ftype;
  282.  
  283.    return os_file(&fcb);
  284. }
  285.  
  286. os_error *misc_windowbox(wimp_box *box, BOOL shrink)
  287. {  wimp_box scrn;
  288.    int sx, sy;
  289.    int bw, bh;
  290.  
  291.    scrn.x0 = LGAP;
  292.    scrn.y0 = BGAP;
  293.    scrn.x1 = ((bbc_vduvar(bbc_XWindLimit) - 1) << bbc_vduvar(bbc_XEigFactor)) - RGAP;
  294.    scrn.y1 = ((bbc_vduvar(bbc_YWindLimit) - 1) << bbc_vduvar(bbc_YEigFactor)) - TGAP;
  295.  
  296.    sx = (scrn.x0 + scrn.x1) / 2;
  297.    sy = (scrn.y0 + scrn.y1) / 2;
  298.  
  299.    if (shrink)
  300.    {  bw = (scrn.x1 - scrn.x0) / 2;
  301.       bh = (scrn.y1 - scrn.y0) / 2;
  302.    }
  303.    else
  304.    {  bw = box->x1 - box->x0;
  305.       bh = box->y1 - box->y0;
  306.    }
  307.  
  308.    box->x0 = sx - bw / 2;
  309.    box->y0 = sy - bh / 2;
  310.    box->x1 = box->x0 + bw;
  311.    box->y1 = box->y0 + bh;
  312.  
  313.    if (box->y0 + offset - MARGIN < scrn.y0)
  314.       offset = scrn.y1 - box->y1 - MARGIN;
  315.  
  316.    box->y0 += offset;
  317.    box->y1 += offset;
  318.  
  319.    offset -= 44;
  320.  
  321.    return NULL;
  322. }
  323.  
  324. os_error *misc_opendir(char *dirname)
  325. {  os_regset regs;
  326.    char cbuf[300];
  327.  
  328.    sprintf(cbuf, "Filer_OpenDir %s", dirname);
  329.    regs.r[0] = (int) cbuf;
  330.  
  331.    return os_swix(OS_CLI, ®s);
  332. }
  333.  
  334. /* Safe memory management stuff */
  335.  
  336. os_error *misc_falloc(void **ptr, int size)
  337. {
  338.  
  339.    if (!flex_alloc(ptr, size))
  340.       return misc_err("misc2");
  341.  
  342.    return NULL;
  343. }
  344.  
  345. os_error *misc_fextend(void **ptr, int by)
  346. {  if (!flex_extend(ptr, by))
  347.       return misc_err("misc2");
  348.  
  349.    return NULL;
  350. }
  351.  
  352. os_error *misc_fmidextend(void **ptr, int at, int by)
  353. {  if (!flex_midextend(ptr, at, by))
  354.       return misc_err("misc2");
  355.  
  356.    return NULL;
  357. }
  358.  
  359. int misc_fsize(void **ptr)
  360. {  return flex_size(ptr);
  361. }
  362.  
  363. void misc_ffree(void **ptr)
  364. {  if (*ptr) flex_free(ptr);
  365. }
  366.  
  367. #ifdef MEMTRACE
  368.  
  369. typedef struct
  370. {  char *file;
  371.    int line;
  372.    int size;
  373. } meminfo;
  374.  
  375. typedef struct remember
  376. {  struct remember *link;
  377.    int tag;  /* This is either the anchor for a flex block, or the returned
  378.               * address for a malloc block.
  379.               */
  380.  
  381.    meminfo original;
  382.    meminfo latest;
  383. } remember;
  384.  
  385. static remember *allmem;
  386.  
  387. static remember *findmem(int tag)
  388. {  remember *r;
  389.  
  390.    for (r = allmem; r; r = r->link)
  391.       if (r->tag == tag)
  392.          return r;
  393.  
  394.    return NULL;
  395. }
  396.  
  397. static remember *unlink(remember *list, remember *r)
  398. {  if (r == list)
  399.       return list->link;
  400.  
  401.    list->link = unlink(list->link, r);
  402.    return list;
  403. }
  404.  
  405. static void losemem(char *file, int line, int tag)
  406. {  remember *r;
  407.  
  408.    if (r = findmem(tag), !r)
  409.       werr(TRUE, "%s: %d, Attempt to free nonexistant block %08x", file, line, tag);
  410.  
  411.    allmem = unlink(allmem, r);
  412.    (free)(r);
  413. }
  414.  
  415. static void remem(char *file, int line, int size, int tag)
  416. {  remember *r;
  417.    meminfo  *i;
  418.  
  419.    if (r = findmem(tag), r)
  420.       i = &(r->latest);
  421.    else
  422.    {  if (r = (malloc)(sizeof(remember)), !r)
  423.          werr(TRUE, "Not enough memory to remember allocation");
  424.  
  425.       r->tag = tag;
  426.       i = &(r->original);
  427.       r->latest.file = NULL;
  428.       r->link = allmem;
  429.       allmem = r;
  430.    }
  431.  
  432.    i->file = file;
  433.    i->line = line;
  434.    i->size = size;
  435. }
  436.  
  437. void __memreport(void)
  438. {  remember *r;
  439.  
  440.    tracker_printf("\fMemory usage\n\n");
  441.    tracker_printf("%-10s%-34s%s\n\n", "Tag", "Original", "Latest");
  442.  
  443.    for (r = allmem; r; r = r->link)
  444.    {
  445.       tracker_printf("%08x, %16s, %5d, %8d ", r->tag,
  446.                                               r->original.file,
  447.                                               r->original.line,
  448.                                               r->original.size);
  449.  
  450.       if (r->latest.file)
  451.          tracker_printf("%16s, %5d, %8d\n", r->latest.file,
  452.                                             r->latest.line,
  453.                                             r->latest.size);
  454.       else
  455.          tracker_printf("unchanged\n");
  456.    }
  457. }
  458.  
  459. /* Replace memory allocation routines */
  460.  
  461. int __flex_alloc(char *name, int line, flex_ptr anchor, int n)
  462. {  int ok = (flex_alloc)(anchor, n);
  463.  
  464.    if (ok) remem(name, line, n, (int) anchor);
  465.    return ok;
  466. }
  467.  
  468. int __flex_extend(char *name, int line, flex_ptr anchor, int n)
  469. {  int ok = (flex_extend)(anchor, n);
  470.    if (ok) remem(name, line, n, (int) anchor);
  471.    return ok;
  472. }
  473.  
  474. void __flex_free(char *name, int line, flex_ptr anchor)
  475. {  name = name;
  476.    line = line;
  477.    losemem(name, line, (int) anchor);
  478.    (flex_free)(anchor);
  479. }
  480.  
  481. void *__malloc(char *name, int line, size_t size)
  482. {  void *m = (malloc)(size);
  483.  
  484.    if (m)
  485.       remem(name, line, size, (int) m);
  486.  
  487.    return m;
  488. }
  489.  
  490. void *__realloc(char *name, int line, void *m, size_t size)
  491. {  void *m2;
  492.  
  493.    m2 = (realloc)(m, size);
  494.  
  495.    if (m2)
  496.    {  losemem(name, line, (int) m);
  497.       if (size) remem(name, line, size, (int) m2);
  498.    }
  499.  
  500.    return m2;
  501. }
  502.  
  503. void __free(char *name, int line, void *m)
  504. {  name = name;
  505.    line = line;
  506.  
  507.    if (m)
  508.       losemem(name, line, (int) m);
  509.    (free)(m);
  510. }
  511.  
  512. os_error *(misc_malloc)(char *name, int line, void **ptr, int size)
  513. {  void *mem = NULL;
  514.  
  515.    if (size && (mem = __malloc(name, line, size), !mem))
  516.       return misc_err("misc2");
  517.  
  518.    *ptr = mem;
  519.    return NULL;
  520. }
  521.  
  522. void (misc_free)(char *name, int line, void **ptr)
  523. {  if (*ptr) __free(name, line, *ptr);
  524.    *ptr = NULL;
  525. }
  526.  
  527. #else
  528. void __memreport(void) {}
  529.  
  530. os_error *misc_malloc(void **ptr, int size)
  531. {  void *mem = NULL;
  532.  
  533.    if (size && (mem = malloc(size), !mem))
  534.       return misc_err("misc2");
  535.  
  536.    *ptr = mem;
  537.    return NULL;
  538. }
  539.  
  540. void misc_free(void **ptr)
  541. {  if (*ptr) free(*ptr);
  542.    *ptr = NULL;
  543. }
  544.  
  545. #endif
  546.  
  547. os_error *misc_force(wimp_w w)
  548. {  wimp_wstate state;
  549.    wimp_redrawstr r;
  550.    os_error *err;
  551.  
  552.    r.w = w;
  553.  
  554.    if (err = wimp_get_wind_state(r.w, &state), err)
  555.       return misc_fix(err);
  556.  
  557.    r.box = state.o.box;
  558.    coords_box_toworkarea(&r.box, (coords_cvtstr *) &state.o.box);
  559.  
  560.    return wimp_force_redraw(&r);
  561. }
  562.  
  563. os_error *misc_chtitle(wimp_w w)
  564. {  wimp_wstate state;
  565.    wimp_redrawstr r;
  566.    os_error *err;
  567.  
  568.    r.w = w;
  569.  
  570.    if (err = wimp_get_wind_state(r.w, &state), err)
  571.       return misc_fix(err);
  572.  
  573.    if (!(state.flags & wimp_WOPEN))
  574.       return NULL;
  575.  
  576.    if (err = wimp_getwindowoutline(&r), err)
  577.       return misc_fix(err);
  578.  
  579.    r.box.y0 = state.o.box.y1;
  580.    r.w = -1;
  581.  
  582.    return wimp_force_redraw(&r);
  583. }
  584.  
  585. void misc_growbox(wimp_box *box, int dx, int dy)
  586. {  box->x0 -= dx;
  587.    box->y0 -= dy;
  588.    box->x1 += dx;
  589.    box->y1 += dy;
  590. }
  591.  
  592. static os_error *misc__getsprites(void)
  593. {  os_regset regs;
  594.  
  595.    regs.r[0] = (int) "%IconSprites <AWMerge$Dir>.!Sprites";
  596.    return os_swix(OS_CLI, ®s);
  597.  
  598. }
  599.  
  600. static BOOL ukproc(wimp_eventstr *e, void *handle)
  601. {  handle = handle;
  602.  
  603.    switch (e->e)
  604.    {  case wimp_ESEND:
  605.       case wimp_ESENDWANTACK:
  606.          switch (e->data.msg.hdr.action)
  607.          {  case wimp_MMODECHANGE:
  608.                wimpt_noerr(misc__getsprites());
  609.             case wimp_PALETTECHANGE:
  610.                misc_newmode();
  611.                break;
  612.          }
  613.    }
  614.    return FALSE;
  615. }
  616.  
  617. int misc_wimpver(void)
  618. {  return wimpver;
  619. }
  620.  
  621. void misc_report(char *tag, ...)
  622. {  va_list ap;
  623.    static char msg[256];
  624.  
  625.    va_start(ap, tag);
  626.    vsprintf(msg, msgs_lookup(tag), ap);
  627.    va_end(ap);
  628.  
  629.    werr(FALSE, msg);
  630. }
  631.  
  632. int misc_min(int a, int b)
  633. {  return a < b ? a : b;
  634. }
  635.  
  636. int misc_max(int a, int b)
  637. {  return a > b ? a : b;
  638. }
  639.  
  640. char *misc_leaf(char *fname)
  641. {  char *leafp;
  642.  
  643.    for (leafp = fname; *fname; ++fname)
  644.    {  if (*fname == '.' || *fname == ':')
  645.          leafp = fname+1;
  646.    }
  647.  
  648.    return leafp;
  649. }
  650.  
  651. os_error *misc_strdup(char **dest, const char *source)
  652. {  os_error *err;
  653.  
  654.    if (err = misc_malloc((void **) dest, strlen(source) + 1), err)
  655.       return misc_fix(err);
  656.  
  657.    strcpy(*dest, source);
  658.  
  659.    return NULL;
  660. }
  661.  
  662. int misc_strcicmp(const char *s1, const char *s2)
  663. {  while (*s1 && toupper(*s1) == toupper(*s2))
  664.       s1++, s2++;
  665.  
  666.    return toupper(*s1) - toupper(*s2);
  667. }
  668.  
  669. os_error *misc_counticons(wimp_w w, int *countp)
  670. {  wimp_i i;
  671.    wimp_icon icn;
  672.    os_error *err;
  673.  
  674.    for (i = 0; ; i++)
  675.    {  if (err = wimp_get_icon_info(w, i, &icn), err)
  676.          return misc_fix(err);
  677.  
  678.       if (icn.flags == wimp_IDELETED)
  679.       {  *countp = i;
  680.          return NULL;
  681.       }
  682.    }
  683.  
  684.    return NULL;
  685. }
  686.  
  687. os_error *misc_icontextlen(wimp_w w, wimp_i i, int *lenp)
  688. {  wimp_icon icn;
  689.    os_error *err;
  690.    char *s;
  691.    int l;
  692.  
  693.    if (err = wimp_get_icon_info(w, i, &icn), err) return misc_fix(err);
  694.  
  695.    if (icn.flags & wimp_ITEXT)
  696.    {  if (icn.flags & wimp_INDIRECT)
  697.          s = icn.data.indirecttext.buffer;
  698.       else
  699.          s = icn.data.text;
  700.  
  701.       for (l = 0; *s >= ' '; s++, l++)
  702.          ;
  703.  
  704.       *lenp = l;
  705.    }
  706.    else
  707.       *lenp = 0;
  708.  
  709.    return NULL;
  710. }
  711.  
  712. /* Advance the caret to the end of the next writeable icon if there is one,
  713.  * and return FALSE through wrap or if there are no more writeables put the
  714.  * caret into limbo (still in the window, but no particular icon) and return
  715.  * TRUE through wrap. If misc_nextwriteable() is called when the caret is in
  716.  * 'limbo' the first writeable will be selected. Circular caret motion can
  717.  * be created by calling this function, checking wrap, and if it's set call
  718.  * this function again.
  719.  */
  720. os_error *misc_nextwriteable(wimp_w w, BOOL *wrap)
  721. {  os_error *err;
  722.    int icons;
  723.    wimp_caretstr c;
  724.    wimp_i i;
  725.    wimp_icon icn;
  726.  
  727.    if (err = misc_counticons(w, &icons), err) return misc_fix(err);
  728.  
  729.    if (err = wimp_get_caret_pos(&c), err) return misc_fix(err);
  730.  
  731.    /* c.i + 1 handles case where i == -1 correctly */
  732.  
  733.    for (i = (c.i < 0 || c.i >= icons) ? 0 : c.i + 1; i < icons; i++)
  734.    {  if (err = wimp_get_icon_info(w, i, &icn), err) return misc_fix(err);
  735.  
  736.       if (((icn.flags >> 12) & 0x0E) == 0x0E)
  737.          break;
  738.    }
  739.  
  740.    if (i < icons)
  741.    {  c.w = w;
  742.       c.i = i;
  743.       c.x = 0;
  744.       c.y = 0;
  745.       c.height = -1;
  746.  
  747.       if (err = misc_icontextlen(w, i, &c.index), err)
  748.          return misc_fix(err);
  749.  
  750.       *wrap = FALSE;
  751.  
  752.       if (err = wimp_set_caret_pos(&c), err)
  753.          return misc_fix(err);
  754.  
  755.    }
  756.    else
  757.       *wrap = TRUE;
  758.  
  759.    return NULL;
  760. }
  761.  
  762. os_error *misc_prevwriteable(wimp_w w, BOOL *wrap)
  763. {  os_error *err;
  764.    int icons;
  765.    wimp_caretstr c;
  766.    wimp_i i;
  767.    wimp_icon icn;
  768.  
  769.    if (err = misc_counticons(w, &icons), err) return misc_fix(err);
  770.    if (err = wimp_get_caret_pos(&c), err) return misc_fix(err);
  771.  
  772.    for (i = (c.i < 0 || c.i >= icons) ? icons-1 : c.i-1; i >= 0; i--)
  773.    {  if (err = wimp_get_icon_info(w, i, &icn), err) return misc_fix(err);
  774.  
  775.       if (((icn.flags >> 12) & 0x0E) == 0x0E)
  776.          break;
  777.    }
  778.  
  779.    if (i >= 0)
  780.    {  c.w = w;
  781.       c.i = i;
  782.       c.x = 0;
  783.       c.y = 0;
  784.       c.height = -1;
  785.  
  786.       if (err = misc_icontextlen(w, i, &c.index), err)
  787.          return misc_fix(err);
  788.  
  789.       *wrap = FALSE;
  790.  
  791.       if (err = wimp_set_caret_pos(&c), err)
  792.          return misc_fix(err);
  793.  
  794.    }
  795.    else
  796.       *wrap = TRUE;
  797.  
  798.    return NULL;
  799. }
  800.  
  801. os_error *misc_fillrect(wimp_box *box)
  802. {  if (box->x1 > box->x0 && box->y1 > box->y0)
  803.    {  bbc_move(box->x0, box->y0);
  804.       bbc_plot(bbc_RectangleFill | bbc_DrawAbsFore,
  805.                box->x1 - 1, box->y1 - 1);
  806.    }
  807.    return NULL;
  808. }
  809.  
  810. os_error *misc_setfontrgb(int fh, int bcol, int fcol)
  811. {  os_regset regs;
  812.  
  813.    regs.r[0] = (int) fh;
  814.    regs.r[1] = bcol;
  815.    regs.r[2] = fcol;
  816.    regs.r[3] = 14;
  817.  
  818.    return os_swix(ColourTrans_SetFontColours, ®s);
  819. }
  820.  
  821. os_error *misc_setfontcolours(int fh, int bcol, int fcol)
  822. {  os_regset regs;
  823.  
  824.    regs.r[0] = (int) fh;
  825.    regs.r[1] = misc_wimpcols.c[bcol].word;
  826.    regs.r[2] = misc_wimpcols.c[fcol].word;
  827.    regs.r[3] = 14;
  828.  
  829.    return os_swix(ColourTrans_SetFontColours, ®s);
  830. }
  831.  
  832. os_error *misc_settitle(wimp_w w, char *title)
  833. {  os_error *err;
  834.    int nicons;
  835.    wimp_winfo *info;
  836.  
  837.    if (err = misc_counticons(w, &nicons), err) return err;
  838.  
  839.    if (err = misc_malloc((void **) &info, sizeof(wimp_winfo) + sizeof(wimp_icon) * nicons), err)
  840.       return err;
  841.  
  842.    info->w = w;
  843.  
  844.    if (err = wimp_get_wind_info(info), err) goto fail;
  845.  
  846.    strncpy(info->info.title.indirecttext.buffer, title, info->info.title.indirecttext.bufflen-1);
  847.    info->info.title.indirecttext.buffer[info->info.title.indirecttext.bufflen-1] = '\0';
  848.  
  849.    misc_free((void **) &info);
  850.  
  851.    return misc_chtitle(w);
  852.  
  853. fail:
  854.    misc_free((void **) &info);
  855.    return err;
  856. }
  857.  
  858. int misc_init(char *taskname)
  859. {  misc__sic.size =
  860.    misc__sic.used = 0;
  861.    misc__sic.info = NULL;
  862.    misc_newmode();
  863.    win_add_unknown_event_processor(ukproc, NULL);
  864. #ifdef FAKE_RISCOS_2
  865.    wimpt_init(taskname);
  866.    wimpver = 200;
  867.    return 200;
  868. #else
  869.    return wimpver = wimpt_init(taskname), wimpver;
  870. #endif
  871. }
  872.