/*
 * This file contains routines to draw and update the screen.
 *
 * Copyright 1990 by the Massachusetts Institute of Technology.
 *
 * For copying and distribution information, please see the file
 * <mit-copyright.h>.
 *
 * Tom Coppeto
 * MIT Network Services
 * 8 August 1990
 *
 *    $Source: /afs/net.mit.edu/tools/src/xport/RCS/xstuff.c,v $
 *    $Author: tom $
 *    $Locker: tom $
 *    $Log:     xstuff.c,v $
 * Revision 1.2  90/08/19  16:19:18  tom
 * *** empty log message ***
 *
 * Revision 1.1  90/08/15  01:13:17  tom
 * Initial revision
 *
 */

#ifndef lint
static char *rcsid = "$Header: /afs/net.mit.edu/tools/src/xport/RCS/xstuff.c,v 1.2 90/08/19 16:19:18 tom Exp Locker: tom $";
#endif

#include <X11/Xatom.h>
#include <X11/IntrinsicP.h>
#include <X11/CompositeP.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include <X11/Xaw/Paned.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/Command.h>
#include <X11/Xaw/Toggle.h>
#include <X11/Xaw/Box.h>
#include <X11/Xaw/Viewport.h>
#include <X11/Xaw/Label.h>
#include <X11/Xaw/StripChart.h>
#include <X11/Xaw/Cardinals.h>
#include <X11/Xaw/AsciiText.h>
#include <X11/cursorfont.h>
#include <X11/Xaw/Dialog.h>
#include <X11/cursorfont.h>
#include <X11/Xaw/MenuButton.h>
#include <X11/Xaw/SimpleMenu.h>
#include <X11/Xaw/Sme.h>
#include <X11/Xaw/SmeBSB.h>
#include <X11/Xaw/Repeater.h>
#include <X11/Xaw/ScrollbarP.h>
#include <X11/Xaw/Viewport.h>

#include <X11/Xtw/Rolo.h>

#include <rope.h>

#include "xrmonwatch.h"

extern Widget toplevel;
static void make_resource();

struct TABLE parse_table();

static XtResource tableResources[] = 
{
  {"tableEtherTypes", XtCString, XtRString, sizeof(String),
     0, XtRString, NULL},
  {"tableEtherVendors", XtCString, XtRString, sizeof(String),
     sizeof(char *), XtRString, NULL},
  {"tableEtherMCasts", XtCString, XtRString, sizeof(String),
     2 * sizeof(char *), XtRString, NULL},
  {"tableARPTypes", XtCString, XtRString, sizeof(String),
     3 * sizeof(char *), XtRString, NULL},
  {"tableAARPTypes", XtCString, XtRString, sizeof(String),
     4 * sizeof(char *), XtRString, NULL},
  {"tableIPProtocols", XtCString, XtRString, sizeof(String),
     5 * sizeof(char *), XtRString, NULL},
  {"tableICMPTypes", XtCString, XtRString, sizeof(String),
     6 * sizeof(char *), XtRString, NULL},
  {"tableICMPUnreachableTypes", XtCString, XtRString, sizeof(String),
     7 * sizeof(char *), XtRString, NULL},
  {"tableICMPRedirectTypes", XtCString, XtRString, sizeof(String),
     8 * sizeof(char *), XtRString, NULL},
  {"tableICMPTimeXceedTypes", XtCString, XtRString, sizeof(String),
     9 * sizeof(char *), XtRString, NULL},
  {"tableRVDTypes", XtCString, XtRString, sizeof(String),
     10 * sizeof(char *), XtRString, NULL},
  {"tableTCPFlags", XtCString, XtRString, sizeof(String),
     11 * sizeof(char *), XtRString, NULL},
  {"tableDDPProtocols", XtCString, XtRString, sizeof(String),
     12 * sizeof(char *), XtRString, NULL},
  {"tableRTMPTypes", XtCString, XtRString, sizeof(String),
     13 * sizeof(char *), XtRString, NULL},
  {"tableEchoTypes", XtCString, XtRString, sizeof(String),
     14 * sizeof(char *), XtRString, NULL},
  {"tableNBPTypes", XtCString, XtRString, sizeof(String),
     15 * sizeof(char *), XtRString, NULL},
  {"tableZIPTypes", XtCString, XtRString, sizeof(String),
     16 * sizeof(char *), XtRString, NULL},
  {"tableADSPTypes", XtCString, XtRString, sizeof(String),
     17 * sizeof(char *), XtRString, NULL},
};


display_init()
{
  XtResource *resources;
  int n = 0, i = 0;
  int nr = 0;
  char *res_tables[20];         /* array for raw tables via resources */
  char *s;

  while(pieces[n++].resource);
  resources = (XtResource *) malloc(sizeof(XtResource) * n * 6);
  parts  = (struct PART *) malloc(sizeof(struct PART) * n);
  if(!resources || !parts)
    {
      fprintf("unable to allocate memory in display_init()\n");
      exit(1);
    }

  bzero(parts, sizeof(struct PART) * n);
  bzero(resources, 6 * n);

  i = 1;
  while(pieces[i].resource)
    {
      if(pieces[i].index)
	*(pieces[i].index) = i;
      parts[i].resource  = str_makeString(pieces[i].resource);
      parts[i].type      = pieces[i].type;
      parts[i].fltproc   = pieces[i].fltproc;
      parts[i].table     = pieces[i].table;
      parts[i].offset    = pieces[i].offset;
      parts[i].index     = i;
      if(pieces[i].base)
	parts[i].base    = *(pieces[i].base);
      
      parts[i].filter    = (struct FILTER * ) malloc(sizeof(struct FILTER));
      bzero(parts[i].filter, sizeof(struct FILTER));
      parts[i].nfilters  = 1;

      make_resource(&resources[nr++], pieces[i].resource, "State", XtCState, 
		    XtRBoolean, sizeof(Boolean), 
		    (unsigned int) &(parts[i].state) - (unsigned int) parts,
		    XtRString, "off"); 
      make_resource(&resources[nr++],pieces[i].resource,"Color", XtCState,
		    XtRPixel, sizeof(Pixel),
		    (unsigned int) &(parts[i].color) - (unsigned int) parts,
		    XtRImmediate, 0);
      make_resource(&resources[nr++],pieces[i].resource,"Highlight", XtCString,
		    XtRPixel, sizeof(Pixel),
		    (unsigned int) &(parts[i].highlight) -(unsigned int) parts,
		    XtRImmediate, 0);
      make_resource(&resources[nr++],pieces[i].resource, "LLength", XtCLength, 
		    XtRInt, sizeof(int),
		    (unsigned int) &(parts[i].llength) - (unsigned int) parts,
		    XtRImmediate, (caddr_t) 0); 
      make_resource(&resources[nr++], pieces[i].resource, "SLabel", XtCLabel, 
		    XtRString, sizeof(String), 
		    (unsigned int) &(parts[i].slabel.s) - (unsigned int) parts,
		    XtRString, ""); 
      make_resource(&resources[nr++], pieces[i].resource, "Label", XtCString, 
		    XtRString, sizeof(String), 
		    (unsigned int) &(parts[i].label.s) - (unsigned int) parts,
		    XtRString, ""); 
      ++i;
    }
  
  XtGetApplicationResources(toplevel, parts, resources, 400, NULL, 0);
  XtGetApplicationResources(toplevel, parts, &resources[400], 400, NULL, 0);
  XtGetApplicationResources(toplevel, parts, &resources[800], nr-800, NULL, 0);
  i = 0;
  while(pieces[i].resource)
    {
      if(parts[i].slabel.s) 
	parts[i].slabel.length = strlen(parts[i].slabel.s);
      if(parts[i].label.s) 
	parts[i].label.length = strlen(parts[i].label.s);
      ++i;
    }
  XtGetApplicationResources(toplevel, res_tables, tableResources, 
			    XtNumber(tableResources), NULL, 0);
  ether_types       = parse_table(res_tables[0]);
  ether_addrs       = parse_table(res_tables[1]);
  ether_mcasts      = parse_table(res_tables[2]);
  arp_types         = parse_table(res_tables[3]);
  aarp_types        = parse_table(res_tables[4]);
  ip_protos         = parse_table(res_tables[5]);
  icmp_types        = parse_table(res_tables[6]);
  icmp_unreachable  = parse_table(res_tables[7]);
  icmp_redirects    = parse_table(res_tables[8]);
  icmp_time_xceed   = parse_table(res_tables[9]);
  rvd_types         = parse_table(res_tables[10]);
  tcp_flags         = parse_table(res_tables[11]);
  ddp_protos        = parse_table(res_tables[12]);
  echo_types        = parse_table(res_tables[13]);
  nbp_types         = parse_table(res_tables[14]);
  zip_types         = parse_table(res_tables[15]);
  adsp_types        = parse_table(res_tables[16]);
}


static void
make_resource(resource, name, op, class, type, size, offset, deftype, defaddr)
     XtResource *resource;
     char *name;
     char *op;
     char *class;
     char *type;
     int size;
     int offset;
     char *deftype;
     caddr_t defaddr;
{
  char buf[100];
  static char *save_string();

  sprintf(buf, "%s%s", name, op);
  resource->resource_name   = save_string(buf);  
  resource->resource_class  = class;
  resource->resource_type   = type;
  resource->default_type    = deftype;
  resource->default_addr    = defaddr;
  resource->resource_size   = size;
  resource->resource_offset = offset;
}


struct TABLE
parse_table(s)
     char *s;
{
  struct TABLE table;
  Hash *hp;
  struct ROW *row;
  char *value;
  int i = 0;
  int page = 10;
  char *type;

  bzero(&table, sizeof(table));
  if(!s)
    return(table);
  if(!(row = (struct ROW *) malloc((page + 1) * sizeof(struct ROW))))
    return(table);
  if(!(hp = sh_create(str_saveString("foo"), 100)))
    return(table);

  while(*s)
    {
      if(i == 0)
	{
	  while(isspace(*s))
	    ++s;
	  if(!*s)
	    break;
	  type = s;
	  while(!isspace(*s))
	    ++s;
	  if(!*s)
	    break;
	  *s++ = '\0';
	}
      while(isspace(*s))
	++s;
      if(!*s)
	break;
      value = s;
      while(!isspace(*s))
	{
	  if(isupper(*s))
	    *s = tolower(*s);
	  ++s;
	}
      if(!*s)
	break;
      *s++ = '\0';
      while(isspace(*s))
	++s;
      if(!*s)
	break;
      row[i].name = s;
      while(*s != ':')
	++s;
      if(!*s)
	break;
      *s++ = '\0';
      while(isspace(*s))
	++s;
      if(!*s)
	break;
      row[i].sname = s;
      while(*s != ':')
	++s;
      if(!*s)
	break;
      *s++ = '\0';

      row[i].value = 0;
      row[i].svalue = (char *) NULL;

      if(strncasecmp(type, "integer", strlen(type)) == 0)
	row[i].value = atoi(value);

      if(strncasecmp(type, "hexadecmial", strlen(type)) == 0)
	sscanf(value, "0x%x", &row[i].value);

      if(strncasecmp(type, "string", strlen(type)) == 0)
	row[i].svalue = value;
      
      if(++i >= page)
	{
	  page += 10;
	  if(!(row = (struct ROW *) realloc(row, (page+1) * 
					    sizeof(struct ROW))))
	    return(table);
	}  
    }  
  row[i].name  = (char *) NULL;
  row[i].value = 0;

  i = 0;
  while(row[i].name)
    {
      if(row[i].svalue)
	sh_store(hp, str_saveString(row[i].svalue, strlen(row[i].svalue)+1),
		 str_makeData(&row[i], sizeof(row[i])));
      else
	sh_store(hp, str_saveString(&row[i].value, sizeof(row[i].value)),
		 str_makeData(&row[i], sizeof(row[i])));
      ++i;
    }
  table.rows = row;
  table.hp = hp;
  return(table);
}


static char *
save_string(s)
     char *s;
{
  char *c;

  if(!s)
    return(s);

  if(!(c = (char * ) malloc(strlen(s) + 1)))
    {
      perror("");
      return((char *) NULL);
    }

  strcpy(c, s);
  return(c);
}


