
/* setictext.c
 *
 * Wimp function library
 *  Joseph Heenan, 1998.
 *
 * Sets the indirected text for a text / text & sprite icon
 * or sets the sprite for a sprite icon
 *
 * $Log: setictext,v $
 * Revision 1.7  1998/11/07 12:08:48  joseph
 * Null terminator wasn't being added when a left aligned icon was too
 * small for the text.
 *
 * Revision 1.6  1998/09/17 10:20:00  joseph
 * Only update icon if text has changed
 *
 * Revision 1.5  1998/08/18 20:58:37  joseph
 * Changed window id in error mesage to hex.
 *
 * Revision 1.4  1998/08/11 17:48:11  joseph
 * Right justified icons are now trimmed sensibly when the text is too long.
 * Icons with borders are redrawn in a way that prevents them flickering.
 *
 * Revision 1.3  1998/05/24 13:11:34  joseph
 * Also handles indirected sprite icons
 *
 * Revision 1.2  1998/05/10 20:13:11  jogu
 * Added names to file headers
 * Added implicit cast for frontend_taskname to wimp_report_error
 *   (it defines 'name' without 'const')
 *
 * Revision 1.1.1.1  1998/05/10 19:56:03  jogu
 * WimpCLib V1.00 (created from newshound c.wimpc rev 1.2)
 *
 *
 */

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>

#include "swis.h"
#include "wimplib.h"

#include "wimpclib.h"


int wimpc_seticontext(int window, int icon, const char *text)
{
  WimpGetIconStateBlock block;
  WimpSetIconStateBlock seticon;
  int size = strlen( text ) + 1;

  block.window_handle = window;
  block.icon_handle   = icon;

  E_CHECK_RETURN( -1, wimp_get_icon_state(&block) );

  if ( !( block.icon.flags & WimpIcon_Indirected && block.icon.flags & (WimpIcon_Sprite | WimpIcon_Text) )
       || block.icon.data.it.buffer_size==0 )
  {
    _kernel_oserror eabort;
    eabort.errnum = 0;
    sprintf( eabort.errmess, "Icon %d in window %x is not an indirected text/sprite icon", icon, window );
    wimp_report_error( &eabort, 0, (char *)frontend_taskname, 0, 0, 0 );
    return -1;
  }

  if ( !memcmp( block.icon.data.it.buffer, text, size ) )
    return 0; /* text hasn't changed! */

  if ( size > block.icon.data.it.buffer_size )
  {
    /* given text won't fit in icon - shall we trim the left or the right? */
    if ( block.icon.flags & WimpIcon_RJustified )
    {
      text += size - block.icon.data.it.buffer_size; /* advance text so right end shown */
      memcpy( block.icon.data.it.buffer, text, block.icon.data.it.buffer_size );
    }
    else
    {
      memcpy( block.icon.data.it.buffer, text, block.icon.data.it.buffer_size - 1 );
      block.icon.data.it.buffer[ block.icon.data.it.buffer_size - 1 ] = 0; /* add null terminator */
    }
  }
  else
  {
    /* whole string will fit */
    memcpy( block.icon.data.it.buffer, text, size );
  }

  if ( block.icon.flags & WimpIcon_Border )
  {
    /* force a redraw of the icon, excluding the border */
    E_CHECK_RETURN( -1, wimp_force_redraw( window, block.icon.bbox.xmin + 4, block.icon.bbox.ymin + 4,
                                    block.icon.bbox.xmax - 4, block.icon.bbox.ymax - 4 ) );
  }
  else
  {
    /* force a redraw of the icon */
    seticon.window_handle = window;
    seticon.icon_handle   = icon;
    seticon.EOR_word      = 0;
    seticon.clear_word    = 0;
    E_CHECK_RETURN( -1, wimp_set_icon_state(&seticon) );
  }

  return 0;
}
