home *** CD-ROM | disk | FTP | other *** search
/ Acorn User 2 / AUCD2.iso / program / vista.arc / c / icon < prev    next >
Text File  |  1996-02-01  |  23KB  |  962 lines

  1. // **************************************************************************
  2. //                     Copyright 1996 David Allison
  3. //
  4. //             VV    VV    IIIIII     SSSSS     TTTTTT       AA
  5. //             VV    VV      II      SS           TT       AA  AA
  6. //             VV    VV      II        SSSS       TT      AA    AA
  7. //              VV  VV       II           SS      TT      AAAAAAAA
  8. //                VV       IIIIII     SSSS        TT      AA    AA
  9. //
  10. //                    MULTI-THREADED C++ WIMP CLASS LIBRARY
  11. //                                for RISC OS
  12. // **************************************************************************
  13. //
  14. //             P U B L I C    D O M A I N    L I C E N C E
  15. //             -------------------------------------------
  16. //
  17. //     This library is copyright. You may not sell the library for
  18. //     profit, but you may sell products which use it providing
  19. //     those products are presented as executable code and are not
  20. //     libraries themselves.  The library is supplied without any
  21. //     warranty and the copyright owner cannot be held responsible for
  22. //     damage resulting from failure of any part of this library.
  23. //
  24. //          See the User Manual for details of the licence.
  25. //
  26. // *************************************************************************
  27.  
  28. //
  29. // c.icon
  30. //
  31.  
  32.  
  33. #include "Vista:icon.h"
  34. #include "Vista:window.h"
  35. #include <kernel.h>
  36. #include <stdlib.h>
  37. #include <swis.h>
  38. #include <string.h>
  39. #include <stdio.h>
  40. #include <stdarg.h>
  41. #include "Vista:task.h"
  42. #include <ctype.h>
  43.  
  44.  
  45. Icon::Icon()       // default constructor
  46.    {
  47.    }
  48.  
  49. Icon::Icon (int priority, int window, int x0, int y0, int x1, int y1, iconflags flags, IconData *data, void *ref)
  50.    {
  51.    _kernel_swi_regs r ;
  52.    _kernel_oserror *e ;
  53.    int icon[9] ;
  54.    r.r[0] = priority ;
  55.    r.r[1] = (int)icon ;
  56.    icon[0] = window ;
  57.    icon[1] = x0 ;
  58.    icon[2] = y0 ;
  59.    icon[3] = x1 ;
  60.    icon[4] = y1 ;
  61.    icon[5] = (int)flags ;
  62.    memcpy (&icon[6], data, sizeof (IconData)) ;
  63.    if ((e = _kernel_swi (Wimp_CreateIcon, &r, &r)) != NULL)
  64.       throw (e) ;
  65.    delete_wimp_icon = true ;
  66.    window = NULL ;
  67.    handle = r.r[0] ;
  68.    prev = NULL ;
  69.    next = NULL ;
  70.    user_ref = ref ;
  71.    default_menu = NULL ;
  72.    }
  73.  
  74.  
  75. Icon::Icon (Window *w, int iconnum, void *ref, char *menu)
  76.    {
  77.    prev = NULL ;
  78.    next = NULL ;
  79.    user_ref = ref ;
  80.    if (menu == NULL)
  81.       default_menu = NULL ;
  82.    else
  83.       {
  84.       default_menu = w->task->find_menu (menu) ;
  85.       if (default_menu == NULL)
  86.          throw ("Unknown menu") ;
  87.       }
  88.    delete_wimp_icon = false ;
  89.    attach (w,iconnum) ;
  90.    }
  91.  
  92. Icon::~Icon()
  93.    {
  94.    if (window != NULL)
  95.      {
  96.       if (delete_wimp_icon)
  97.          {
  98.          _kernel_swi_regs r ;
  99.          _kernel_oserror *e ;
  100.          int block[2] ;
  101.          r.r[1] = (int)block ;
  102.          block[0] = window->handle ;
  103.          block[1] = handle ;
  104.          if ((e = _kernel_swi (Wimp_DeleteIcon, &r, &r)) != NULL)
  105.             throw (e) ;
  106.          }
  107.       window->remove_icon (this) ;
  108.      }
  109.    }
  110.  
  111. Icon::Icon (Window *w, Icon *temp, Direction direction, int gap, void *ref, char *menu)
  112.    {
  113.    _kernel_swi_regs r ;
  114.    _kernel_oserror *e ;
  115.    int block[40] ;
  116.  
  117.    if (menu == NULL)
  118.       default_menu = NULL ;
  119.    else
  120.       {
  121.       default_menu = w->task->find_menu (menu) ;
  122.       if (default_menu == NULL)
  123.          throw ("Unknown menu") ;
  124.       }
  125.    block[0] = w->handle ;
  126.    block[1] = temp->handle ;
  127.    r.r[1] = (int)block ;
  128.    if ((e = _kernel_swi (Wimp_GetIconState, &r, &r)) != NULL)
  129.       throw (e) ;
  130.    int size ;
  131.    Box *box = (Box*)&block[2] ;
  132.    IconData *data = (IconData*)&block[7] ;
  133.    switch (direction)
  134.       {
  135.       case UP:
  136.          size = box->y1 - box->y0 + gap ;
  137.          box->y0 += size ;
  138.          box->y1 += size ;
  139.          break ;
  140.       case DOWN:
  141.          size = box->y1 - box->y0 + gap ;
  142.          box->y0 -= size ;
  143.          box->y1 -= size ;
  144.          break ;
  145.       case LEFT:
  146.          size = box->x1 - box->x0 + gap ;
  147.          box->x0 -= size ;
  148.          box->x1 -= size ;
  149.          break ;
  150.       case RIGHT:
  151.          size = box->x1 - box->x0 + gap ;
  152.          box->x0 += size ;
  153.          box->x1 += size ;
  154.          break ;
  155.       }
  156.    if (block[6] & INDIRECT && block[6] & ITEXT)
  157.       {
  158.       char *p = (char*)malloc (data->indirecttext.bufflen) ;
  159.       if (p == NULL)
  160.          throw ("Out of Memory") ;
  161.       data->indirecttext.buffer = p ;
  162.       p[0] = 0 ;
  163.       }
  164.    block[1] = w->handle ;       // copy window handle to right place
  165.    r.r[1] = (int)&block[1] ;
  166.    if ((e = _kernel_swi (Wimp_CreateIcon, &r, &r)) != NULL)
  167.       throw (e) ;
  168.    prev = NULL ;
  169.    next = NULL ;
  170.    user_ref = ref ;
  171.    delete_wimp_icon = true ;
  172.    attach (w,r.r[0]) ;
  173.    }
  174.  
  175. Icon::Icon (Window *w, Icon *temp, int x, int y, void *ref, char *menu)
  176.    {
  177.    _kernel_swi_regs r ;
  178.    _kernel_oserror *e ;
  179.    int block[40] ;
  180.  
  181.    if (menu == NULL)
  182.       default_menu = NULL ;
  183.    else
  184.       {
  185.       default_menu = w->task->find_menu (menu) ;
  186.       if (default_menu == NULL)
  187.          throw ("Unknown menu") ;
  188.       }
  189.    block[0] = w->handle ;
  190.    block[1] = temp->handle ;
  191.    r.r[1] = (int)block ;
  192.    if ((e = _kernel_swi (Wimp_GetIconState, &r, &r)) != NULL)
  193.       throw (e) ;
  194.    int xsize, ysize ;
  195.    Box *box = (Box*)&block[2] ;
  196.    IconData *data = (IconData*)&block[7] ;
  197.    xsize = box->x1 - box->x0 ;
  198.    ysize = box->y1 - box->y0 ;
  199.    box->x0 = x ;
  200.    box->x1 = box->x0 + xsize ;
  201.    box->y0 = y ;
  202.    box->y1 = box->y0 + ysize ;
  203.    if (block[6] & INDIRECT && block[6] & ITEXT)
  204.       {
  205.       char *p = (char*)malloc (data->indirecttext.bufflen) ;
  206.       if (p == NULL)
  207.          throw ("Out of Memory") ;
  208.       data->indirecttext.buffer = p ;
  209.       p[0] = 0 ;
  210.       }
  211.    block[1] = w->handle ;       // copy window handle to right place
  212.    r.r[1] = (int)&block[1] ;
  213.    if ((e = _kernel_swi (Wimp_CreateIcon, &r, &r)) != NULL)
  214.       throw (e) ;
  215.    prev = NULL ;
  216.    next = NULL ;
  217.    user_ref = ref ;
  218.    delete_wimp_icon = true ;
  219.    attach (w,r.r[0]) ;
  220.    }
  221.  
  222.  
  223. void Icon::attach (Window *w, int iconnum)
  224.    {
  225.    window = w ;
  226.    handle = iconnum ;
  227.    w->add_icon (this) ;
  228.    }
  229.  
  230. void Icon::move (int dx, int dy)
  231.    {
  232.    _kernel_swi_regs r ;
  233.    _kernel_oserror *e ;
  234.    int block[40] ;
  235.    int delblock[2] ;
  236.  
  237.    block[0] = window->handle ;
  238.    block[1] = handle ;
  239.    r.r[1] = (int)block ;
  240.    if ((e = _kernel_swi (Wimp_GetIconState, &r, &r)) != NULL)
  241.       throw (e) ;
  242.    Box *box = (Box*)&block[2] ;
  243.    box->x0 += dx ;
  244.    box->x1 += dx ;
  245.    box->y0 += dy ;
  246.    box->y1 += dy ;
  247.    delblock[0] = window->handle ;
  248.    delblock[1] = handle ;
  249.    r.r[1] = (int)delblock ;
  250.    if ((e = _kernel_swi (Wimp_DeleteIcon, &r, &r)) != NULL)
  251.       throw (e) ;
  252.    r.r[1] = (int)&block[1] ;
  253.    r.r[0] = handle ;
  254.    block[1] = window->handle ;   // set window handle
  255.    if ((e = _kernel_swi (Wimp_CreateIcon, &r, &r)) != NULL)
  256.       throw (e) ;
  257.    r.r[0] = window->handle ;
  258.    r.r[1] = block[2] ;
  259.    r.r[2] = block[3] ;
  260.    r.r[3] = block[4] ;
  261.    r.r[4] = block[5] ;
  262.    if ((e = _kernel_swi (Wimp_ForceRedraw, &r, &r)) != NULL)
  263.       throw (e) ;
  264.    }
  265.  
  266. void Icon::move (Direction direction, int dist)
  267.    {
  268.    _kernel_swi_regs r ;
  269.    _kernel_oserror *e ;
  270.    int block[40] ;
  271.    int delblock[2] ;
  272.  
  273.    block[0] = window->handle ;
  274.    block[1] = handle ;
  275.    r.r[1] = (int)block ;
  276.    if ((e = _kernel_swi (Wimp_GetIconState, &r, &r)) != NULL)
  277.       throw (e) ;
  278.    Box *box = (Box*)&block[2] ;
  279.    switch (direction)
  280.       {
  281.       case UP:
  282.          box->y0 += dist ;
  283.          box->y1 += dist ;
  284.          break ;
  285.       case DOWN:
  286.          box->y0 -= dist ;
  287.          box->y1 -= dist ;
  288.          break ;
  289.       case LEFT:
  290.          box->x0 += dist ;
  291.          box->x1 += dist ;
  292.          break ;
  293.       case RIGHT:
  294.          box->x0 -= dist ;
  295.          box->x1 -= dist ;
  296.          break ;
  297.       }
  298.    delblock[0] = window->handle ;
  299.    delblock[1] = handle ;
  300.    r.r[1] = (int)delblock ;
  301.    if ((e = _kernel_swi (Wimp_DeleteIcon, &r, &r)) != NULL)
  302.       throw (e) ;
  303.    r.r[1] = (int)&block[1] ;
  304.    r.r[0] = handle ;
  305.    block[1] = window->handle ;   // set window handle
  306.    if ((e = _kernel_swi (Wimp_CreateIcon, &r, &r)) != NULL)
  307.       throw (e) ;
  308.    r.r[0] = window->handle ;
  309.    r.r[1] = block[2] ;
  310.    r.r[2] = block[3] ;
  311.    r.r[3] = block[4] ;
  312.    r.r[4] = block[5] ;
  313.    if ((e = _kernel_swi (Wimp_ForceRedraw, &r, &r)) != NULL)
  314.       throw (e) ;
  315.    }
  316.  
  317. void Icon::move_to (int x, int y)
  318.    {
  319.    _kernel_swi_regs r ;
  320.    _kernel_oserror *e ;
  321.    int block[40] ;
  322.    int delblock[2] ;
  323.  
  324. //   ::print ("moving icon to %d, %d",x,y) ;
  325. //   print ("%d,%d",x,y) ;
  326.    block[0] = window->handle ;
  327.    block[1] = handle ;
  328.    r.r[1] = (int)block ;
  329.    if ((e = _kernel_swi (Wimp_GetIconState, &r, &r)) != NULL)
  330.       throw (e) ;
  331.    Box *box = (Box*)&block[2] ;
  332.    int xsize = box->x1 - box->x0 ;
  333.    int ysize = box->y1 - box->y0 ;
  334.    box->x0 = x ;
  335.    box->x1 = box->x0 + xsize ;
  336.    box->y0 = y ;
  337.    box->y1 = box->y0 + ysize ;
  338.    delblock[0] = window->handle ;
  339.    delblock[1] = handle ;
  340.    r.r[1] = (int)delblock ;
  341.    if ((e = _kernel_swi (Wimp_DeleteIcon, &r, &r)) != NULL)
  342.       throw (e) ;
  343.    r.r[1] = (int)&block[1] ;
  344.    r.r[0] = handle ;
  345.    block[1] = window->handle ;   // set window handle
  346.    if ((e = _kernel_swi (Wimp_CreateIcon, &r, &r)) != NULL)
  347.       throw (e) ;
  348. //   r.r[0] = window->handle ;
  349. //   r.r[1] = block[2] ;
  350. //   r.r[2] = block[3] ;
  351. //   r.r[3] = block[4] ;
  352. //   r.r[4] = block[5] ;
  353. //   if ((e = _kernel_swi (Wimp_ForceRedraw, &r, &r)) != NULL)
  354. //      throw (e) ;
  355.    }
  356.  
  357. void Icon::resize (int width, int height)
  358.    {
  359.    _kernel_swi_regs r ;
  360.    _kernel_oserror *e ;
  361.    int block[40] ;
  362.    int delblock[2] ;
  363.  
  364.    block[0] = window->handle ;
  365.    block[1] = handle ;
  366.    r.r[1] = (int)block ;
  367.    if ((e = _kernel_swi (Wimp_GetIconState, &r, &r)) != NULL)
  368.       throw (e) ;
  369.    Box *box = (Box*)&block[2] ;
  370.    box->x1 = box->x0 + width ;
  371.    box->y1 = box->y0 + height ;
  372.    delblock[0] = window->handle ;
  373.    delblock[1] = handle ;
  374.    r.r[1] = (int)delblock ;
  375.    if ((e = _kernel_swi (Wimp_DeleteIcon, &r, &r)) != NULL)
  376.       throw (e) ;
  377.    r.r[1] = (int)&block[1] ;
  378.    r.r[0] = handle ;
  379.    block[1] = window->handle ;   // set window handle
  380.    if ((e = _kernel_swi (Wimp_CreateIcon, &r, &r)) != NULL)
  381.       throw (e) ;
  382.    }
  383.  
  384. void Icon::redraw (int x0, int y0, int x1, int y1)
  385.    {
  386.    _kernel_swi_regs r ;
  387.    _kernel_oserror *e ;
  388.    int block[40] ;
  389.  
  390.    block[0] = window->handle ;
  391.    block[1] = handle ;
  392.    r.r[1] = (int)block ;
  393.    if ((e = _kernel_swi (Wimp_GetIconState, &r, &r)) != NULL)
  394.       throw (e) ;
  395.    Box *box = (Box*)&block[2] ;
  396.    if (x0 <= box->x1 && x1 >= box->x0 && y1 >= box->y0 && y0 <= box->y1)
  397.       {
  398.       r.r[1] = (int)block ;
  399.       if ((e = _kernel_swi (Wimp_PlotIcon, &r, &r)) != NULL)
  400.          throw (e) ;
  401.       }
  402.    }
  403.  
  404.  
  405. void Icon::plot ()
  406.    {
  407.    _kernel_swi_regs r ;
  408.    _kernel_oserror *e ;
  409.    int block[40] ;
  410.  
  411.    block[0] = window->handle ;
  412.    block[1] = handle ;
  413.    r.r[1] = (int)block ;
  414.    if ((e = _kernel_swi (Wimp_GetIconState, &r, &r)) != NULL)
  415.       throw (e) ;
  416.    r.r[1] = (int)block ;
  417.    if ((e = _kernel_swi (Wimp_PlotIcon, &r, &r)) != NULL)
  418.       throw (e) ;
  419.  
  420.    }
  421.  
  422. void Icon::drag(int mx, int my, int buttons)
  423.    {
  424.    _kernel_swi_regs r ;
  425.    _kernel_oserror *e ;
  426.    int block[40] ;
  427.    IconData *data ;
  428.    bool drag_sprite ;
  429.    char sprite_name[32] ;
  430.  
  431.    block[0] = window->handle ;
  432.    block[1] = handle ;
  433.    r.r[1] = (int)block ;
  434.    if ((e = _kernel_swi (Wimp_GetIconState, &r, &r)) != NULL)
  435.       throw (e) ;
  436.    r.r[0] = 161 ;
  437.    r.r[1] = 28 ;
  438.    _kernel_swi (OS_Byte, &r, &r) ;
  439.    drag_sprite = false ;
  440.    if (r.r[2] & 2)
  441.       {
  442.       data = (IconData*)&block[7] ;
  443.       if (block[6] & ISPRITE)
  444.          {
  445.          if (block[6] & INDIRECT)                   // indirect
  446.             {
  447.             if (!(block[6] & ITEXT))
  448.                {
  449.                strcpy (sprite_name, data->indirectsprite.name) ;
  450.                drag_sprite = true ;
  451.                }
  452.             else
  453.                {
  454.                if (data->indirecttext.validstring[0] == 'S' || data->indirecttext.validstring[0] == 's')
  455.                   {
  456.                   strcpy (sprite_name, &data->indirecttext.validstring[1]) ;
  457.                   drag_sprite = true ;
  458.                   }
  459.                }
  460.             }
  461.          else
  462.             {
  463.             strncpy (sprite_name, data->sprite_name, 12) ;
  464.             sprite_name[12] = 0 ;
  465.             drag_sprite = true ;
  466.             }
  467.          }
  468.       }
  469.    if (drag_sprite)
  470.       window->do_drag (sprite_name, window->xtoscreen (block[2]), window->ytoscreen(block[3]),
  471.                           window->xtoscreen (block[4]), window->ytoscreen(block[5]), 0xc5, 0,0,0,0) ;
  472.    else
  473.       window->do_drag (5, window->xtoscreen (block[2]), window->ytoscreen(block[3]),
  474.                           window->xtoscreen (block[4]), window->ytoscreen(block[5])) ;
  475.    }
  476.  
  477.  
  478. void Icon::read_position (Box &box)
  479.    {
  480.    _kernel_swi_regs r ;
  481.    _kernel_oserror *e ;
  482.    int block[40] ;
  483.  
  484.    block[0] = window->handle ;
  485.    block[1] = handle ;
  486.    r.r[1] = (int)block ;
  487.    if ((e = _kernel_swi (Wimp_GetIconState, &r, &r)) != NULL)
  488.       throw (e) ;
  489.    box = *(Box*)&block[2] ;
  490.    }
  491.  
  492. void Icon::click (int mx, int my, int button, int icon)
  493.    {
  494.    }
  495.  
  496. void Icon::key (int icon,  int x, int y, int height, int index, int code)
  497.    {
  498.    }
  499.  
  500. void Icon::select ()
  501.    {
  502.    _kernel_swi_regs r ;
  503.    _kernel_oserror *e ;
  504.    int block[4] ;
  505.    block[0] = window->handle ;
  506.    block[1] = handle ;
  507.    block[2] = ISELECTED ;
  508.    block[3] = ISELECTED ;
  509.    r.r[1] = (int)block ;
  510.    if ((e = _kernel_swi (Wimp_SetIconState, &r, &r)) != NULL)
  511.       throw (e) ;
  512.    }
  513.  
  514. void Icon::unselect ()
  515.    {
  516.    _kernel_swi_regs r ;
  517.    _kernel_oserror *e ;
  518.    int block[4] ;
  519.    block[0] = window->handle ;
  520.    block[1] = handle ;
  521.    block[2] = 0 ;
  522.    block[3] = ISELECTED ;
  523.    r.r[1] = (int)block ;
  524.    if ((e = _kernel_swi (Wimp_SetIconState, &r, &r)) != NULL)
  525.       throw (e) ;
  526.    }
  527.  
  528. void Icon::fade ()
  529.    {
  530.    _kernel_swi_regs r ;
  531.    _kernel_oserror *e ;
  532.    int block[4] ;
  533.    block[0] = window->handle ;
  534.    block[1] = handle ;
  535.    block[2] = INOSELECT ;
  536.    block[3] = INOSELECT ;
  537.    r.r[1] = (int)block ;
  538.    if ((e = _kernel_swi (Wimp_SetIconState, &r, &r)) != NULL)
  539.       throw (e) ;
  540.    }
  541.  
  542. void Icon::unfade ()
  543.    {
  544.    _kernel_swi_regs r ;
  545.    _kernel_oserror *e ;
  546.    int block[4] ;
  547.    block[0] = window->handle ;
  548.    block[1] = handle ;
  549.    block[2] = 0 ;
  550.    block[3] = INOSELECT ;
  551.    r.r[1] = (int)block ;
  552.    if ((e = _kernel_swi (Wimp_SetIconState, &r, &r)) != NULL)
  553.       throw (e) ;
  554.    }
  555.  
  556. void Icon::set_fore_colour (int colour)
  557.    {
  558.    _kernel_swi_regs r ;
  559.    _kernel_oserror *e ;
  560.    int block[4] ;
  561.    block[0] = window->handle ;
  562.    block[1] = handle ;
  563.    block[2] = colour << 24 ;
  564.    block[3] = ForeMask ;
  565.    r.r[1] = (int)block ;
  566.    if ((e = _kernel_swi (Wimp_SetIconState, &r, &r)) != NULL)
  567.       throw (e) ;
  568.    }
  569.  
  570. void Icon::set_back_colour (int colour)
  571.    {
  572.    _kernel_swi_regs r ;
  573.    _kernel_oserror *e ;
  574.    int block[4] ;
  575.    block[0] = window->handle ;
  576.    block[1] = handle ;
  577.    block[2] = colour << 28 ;
  578.    block[3] = BackMask ;
  579.    r.r[1] = (int)block ;
  580.    if ((e = _kernel_swi (Wimp_SetIconState, &r, &r)) != NULL)
  581.       throw (e) ;
  582.    }
  583.  
  584. int Icon::is_writeable ()
  585.    {
  586.    _kernel_swi_regs r ;
  587.    _kernel_oserror *e ;
  588.    int block[40] ;
  589.  
  590.    block[0] = window->handle ;
  591.    block[1] = handle ;
  592.    r.r[1] = (int)block ;
  593.    if ((e = _kernel_swi (Wimp_GetIconState, &r, &r)) != NULL)
  594.       throw (e) ;
  595.    int btype = (block[6] >> 12) & 0x0f ;
  596.    return btype == BWRITABLE ;
  597.    }
  598.  
  599. int Icon::is_selected ()
  600.    {
  601.    _kernel_swi_regs r ;
  602.    _kernel_oserror *e ;
  603.    int block[40] ;
  604.  
  605.    block[0] = window->handle ;
  606.    block[1] = handle ;
  607.    r.r[1] = (int)block ;
  608.    if ((e = _kernel_swi (Wimp_GetIconState, &r, &r)) != NULL)
  609.       throw (e) ;
  610.    return (block[6] & ISELECTED) ;
  611.    }
  612.  
  613.  
  614. int Icon::compare (int icon)
  615.    {
  616.    return icon == handle ;
  617.    }
  618.  
  619. int Icon::compare (Icon *icon)
  620.    {
  621.    int block[10] ;
  622.    _kernel_swi_regs r ;
  623.    _kernel_oserror *e ;
  624.    char *text1, *text2 ;
  625.    IconData *data ;
  626.    block[0] = window->handle ;
  627.    block[1] = handle ;
  628.    r.r[1] = (int)block ;
  629.    if ((e = _kernel_swi (Wimp_GetIconState, &r, &r)) != NULL)
  630.       throw (e) ;
  631.    data = (IconData*)&block[7] ;
  632.    if (!(block[6] & INDIRECT))
  633.       throw ("Icon is not indirected") ;
  634.    text1 = data->indirecttext.buffer ;
  635.    block[0] = icon->window->handle ;
  636.    block[1] = icon->handle ;
  637.    r.r[1] = (int)block ;
  638.    if ((e = _kernel_swi (Wimp_GetIconState, &r, &r)) != NULL)
  639.       throw (e) ;
  640.    data = (IconData*)&block[7] ;
  641.    if (!(block[6] & INDIRECT))
  642.       throw ("Icon is not indirected") ;
  643.    text2 = data->indirecttext.buffer ;
  644.    while (*text1 && *text2)
  645.       if (toupper(*text1) != toupper (*text2))
  646.          break ;
  647.       else
  648.          text1++, text2++ ;
  649.    return toupper(*text1) - toupper (*text2) ;
  650.    }
  651.  
  652.  
  653.  
  654. void Icon::print (char *format ...)
  655.    {
  656.    va_list arg ;
  657.    int block[10] ;
  658.    _kernel_swi_regs r ;
  659.    _kernel_oserror *e ;
  660.    IconData *data ;
  661.    block[0] = window->handle ;
  662.    block[1] = handle ;
  663.    r.r[1] = (int)block ;
  664.    if ((e = _kernel_swi (Wimp_GetIconState, &r, &r)) != NULL)
  665.       throw (e) ;
  666.    data = (IconData*)&block[7] ;
  667.    if (!(block[6] & INDIRECT))
  668.       throw ("Icon is not indirected") ;
  669.    va_start (arg,format) ;
  670.    vsprintf (data->indirecttext.buffer, format, arg) ;
  671.    block[2] = 0 ;
  672.    block[3] = 0 ;
  673.    r.r[1] = (int)block ;
  674.    if ((e = _kernel_swi (Wimp_SetIconState, &r, &r)) != NULL)
  675.       throw (e) ;
  676.    }
  677.  
  678. void Icon::change_sprite (char *sprite_name, int area)
  679.    {
  680.    int block[10] ;
  681.    int delblock[2] ;
  682.    _kernel_swi_regs r ;
  683.    _kernel_oserror *e ;
  684.    IconData *data ;
  685.    block[0] = window->handle ;
  686.    block[1] = handle ;
  687.    r.r[1] = (int)block ;
  688.    if ((e = _kernel_swi (Wimp_GetIconState, &r, &r)) != NULL)
  689.       throw (e) ;
  690.    data = (IconData*)&block[7] ;
  691.    if (!(block[6] & ISPRITE))
  692.       throw ("Icon doesn't contain a sprite") ;
  693.    if (block[6] & INDIRECT)                   // indirect
  694.       {
  695.       if (!(block[6] & ITEXT))
  696.          {
  697.          data->indirectsprite.nameisname = strlen (sprite_name) ;
  698.          data->indirectsprite.name = sprite_name ;
  699.          data->indirectsprite.spritearea = (void*)area ;
  700.          }
  701.       else
  702.          {
  703.          char *p = new char [strlen(sprite_name) + 2] ;  // allow for s and 0
  704.          sprintf (p, "S%s",sprite_name) ;
  705.          data->indirecttext.validstring = p ;       // possible memory leak if icon deleted
  706.          }
  707.       }
  708.    else
  709.       strncpy (data->sprite_name, sprite_name, 12) ;
  710.    delblock[0] = window->handle ;
  711.    delblock[1] = handle ;
  712.    r.r[1] = (int)delblock ;
  713.    if ((e = _kernel_swi (Wimp_DeleteIcon, &r, &r)) != NULL)
  714.       throw (e) ;
  715.    r.r[1] = (int)&block[1] ;
  716.    r.r[0] = handle ;
  717.    block[1] = window->handle ;   // set window handle
  718.    if ((e = _kernel_swi (Wimp_CreateIcon, &r, &r)) != NULL)
  719.       throw (e) ;
  720.    }
  721.  
  722. void Icon::read_sprite (char *sprite_name)
  723.    {
  724.    int block[10] ;
  725.    int delblock[2] ;
  726.    _kernel_swi_regs r ;
  727.    _kernel_oserror *e ;
  728.    IconData *data ;
  729.    block[0] = window->handle ;
  730.    block[1] = handle ;
  731.    r.r[1] = (int)block ;
  732.    if ((e = _kernel_swi (Wimp_GetIconState, &r, &r)) != NULL)
  733.       throw (e) ;
  734.    data = (IconData*)&block[7] ;
  735.    if (!(block[6] & ISPRITE))
  736.       throw ("Icon doesn't contain a sprite") ;
  737.    if (block[6] & INDIRECT)                   // indirect
  738.       {
  739.       if (!(block[6] & ITEXT))
  740.          strcpy (sprite_name, data->indirectsprite.name) ;
  741.       else
  742.          {
  743.          if (data->indirecttext.validstring[0] != 'S' && data->indirecttext.validstring[0] != 's')
  744.             throw ("Icon doesn't contain a sprite") ;
  745.          strcpy (sprite_name, &data->indirecttext.validstring[1]) ;
  746.          }
  747.       }
  748.    else
  749.       {
  750.       strncpy (sprite_name, data->sprite_name, 12) ;
  751.       sprite_name[12] = 0 ;
  752.       }
  753.  
  754.    }
  755.  
  756. void Icon::set_caret()
  757.    {
  758.    int block[10] ;
  759.    _kernel_swi_regs r ;
  760.    _kernel_oserror *e ;
  761.    IconData *data ;
  762.    block[0] = window->handle ;
  763.    block[1] = handle ;
  764.    r.r[1] = (int)block ;
  765.    if ((e = _kernel_swi (Wimp_GetIconState, &r, &r)) != NULL)
  766.       throw (e) ;
  767.    if (!(block[6] & (ITEXT|INDIRECT)))
  768.       throw ("Icon has no text or is not indirect") ;
  769.    if (!is_writeable())
  770.       throw ("Icon is not writeable") ;
  771.    data = (IconData*)&block[7] ;
  772.    r.r[0] = window->handle ;
  773.    r.r[1] = handle ;
  774.    r.r[2] = r.r[3] = 0 ;
  775.    r.r[4] = -1 ;
  776.    r.r[5] = strlen (data->indirecttext.buffer) ;
  777.    if ((e = _kernel_swi (Wimp_SetCaretPosition, &r, &r)) != NULL)
  778.       throw (e) ;
  779.    }
  780.  
  781.  
  782. void Icon::read (char *s)
  783.    {
  784.    int block[10] ;
  785.    _kernel_swi_regs r ;
  786.    _kernel_oserror *e ;
  787.    IconData *data ;
  788.    block[0] = window->handle ;
  789.    block[1] = handle ;
  790.    r.r[1] = (int)block ;
  791.    if ((e = _kernel_swi (Wimp_GetIconState, &r, &r)) != NULL)
  792.       throw (e) ;
  793.    data = (IconData*)&block[7] ;
  794.    if (!(block[6] & INDIRECT))
  795.       throw ("Icon is not indirected") ;
  796.    strcpy (s, data->indirecttext.buffer) ;
  797.    char *cr = strchr (s,'\r') ;               // overwrite CR by 0
  798.    if (cr != NULL)
  799.       *cr = 0 ;
  800.    }
  801.  
  802. void Icon::read (int &n)
  803.    {
  804.    char buffer[10] ;
  805.    read (buffer) ;
  806.    sscanf (buffer, "%d", &n) ;
  807.    }
  808.  
  809. void Icon::read (float &n)
  810.    {
  811.    char buffer[30] ;
  812.    read (buffer) ;
  813.    sscanf (buffer, "%f", &n) ;
  814.    }
  815.  
  816. void Icon::read (double &n)
  817.    {
  818.    char buffer[30] ;
  819.    read (buffer) ;
  820.    sscanf (buffer, "%lf", &n) ;
  821.    }
  822.  
  823.  
  824. void Icon::write (char *s)
  825.    {
  826.    print (s) ;
  827.    }
  828.  
  829. void Icon::write (int n)
  830.    {
  831.    print ("%d",n) ;
  832.    }
  833.  
  834. void Icon::write (float n)
  835.    {
  836.    print ("%g",n) ;
  837.    }
  838.  
  839. void Icon::write (double n)
  840.    {
  841.    print ("%g",n) ;
  842.    }
  843.  
  844. Menu *Icon::display_menu (int x, int y, int button, int icon)
  845.    {
  846.    if (default_menu == NULL)
  847.       {
  848.       char *menu_name = get_menu(x, y, button, icon) ;
  849.       if (menu_name == NULL)
  850.          return NULL ;
  851.       Menu *m = window->task->find_menu (menu_name) ;
  852.       if (m != NULL)
  853.          {
  854.          m->open (x - 40, y) ;
  855.          return m ;
  856.          }
  857.       return NULL ;       // no menu
  858.       }
  859.    else
  860.       {
  861.       pre_menu (default_menu, x,  y,  button,  icon) ;
  862.       default_menu->open (x - 40, y) ;
  863.       return default_menu ;
  864.       }
  865.    }
  866.  
  867. //
  868. // give user a chance to change the menu before display
  869. //
  870.  
  871. void Icon::pre_menu (Menu *m, int x, int y, int button, int icon)
  872.    {
  873.    }
  874.  
  875. //
  876. // this window doesn't have a default menu, ask the user to provide one
  877. //
  878.  
  879.  
  880. char *Icon::get_menu (int x, int y, int button, int icon)
  881.    {
  882.    return NULL ;
  883.    }
  884.  
  885. void Icon::menu (MenuItem item[])
  886.    {
  887.    }
  888.  
  889.  
  890. char *Icon::help (int mx, int my, int buttons)
  891.    {
  892.    return NULL ;
  893.    }
  894.  
  895. //
  896. //  a set of icons
  897. //
  898.  
  899. IconSet::IconSet (int nicons)
  900.    {
  901.    max_icons = nicons ;
  902.    if ((icons = (int*)malloc (max_icons * sizeof (int))) == NULL)
  903.       throw ("Out of memory") ;
  904.    num_icons = 0 ;
  905.    }
  906.  
  907. IconSet::~IconSet()
  908.    {
  909.    free (icons) ;
  910.    }
  911.  
  912. int IconSet::compare (int icon)
  913.    {
  914.    int i ;
  915.    for (i = 0 ; i < num_icons ; i++)
  916.       if (icons[i] == icon)
  917.          return 1 ;
  918.    return 0 ;
  919.    }
  920.  
  921. void IconSet::add_icon(int icon)
  922.    {
  923.    if (num_icons == max_icons)
  924.       throw ("Too many icons") ;
  925.    icons[num_icons++] = icon ;
  926.    }
  927.  
  928. void IconSet::select (int icon)
  929.    {
  930.    }
  931.  
  932. void IconSet::select ()
  933.    {
  934.    }
  935.  
  936. void IconSet::fade (int icon)
  937.    {
  938.    }
  939.  
  940. void IconSet::fade ()
  941.    {
  942.    }
  943.  
  944. void IconSet::unselect (int icon)
  945.    {
  946.    }
  947.  
  948. void IconSet::unselect ()
  949.    {
  950.    }
  951.  
  952. void IconSet::unfade (int icon)
  953.    {
  954.    }
  955.  
  956. void IconSet::unfade ()
  957.    {
  958.    }
  959.  
  960.  
  961.  
  962.