Beispiel #1
0
static void pwrsrv_WriteAttribute( rpvd_sMsgWriteAttribute *msg)
{
  rpvd_sMsgAny rmsg;
  pwr_tAName name;
  pwr_tUInt32 asize, aoffs, aelem;
  pwr_tTypeId atid;
  pwr_tStatus sts;
  
  rmsg.Type = rpvd_eMsg_Status;
  rmsg.Id = msg->Id;

  sts = gdh_ObjidToName( msg->Oid, name, sizeof(name), cdh_mName_volumeStrict);
  if ( EVEN(sts)) {
    rmsg.Status = sts;
    udp_Send( (char *)&rmsg, sizeof(rmsg));
    return;
  }

  strcat( name, ".");
  strcat( name, msg->Attribute);

  sts = gdh_GetAttributeCharacteristics( name, &atid, &asize, &aoffs, &aelem);
  if ( EVEN(sts)) {
    rmsg.Status = sts;
    udp_Send( (char *)&rmsg, sizeof(rmsg));
    return;
  }

  sts = gdh_SetObjectInfo( name, &msg->Value, msg->Size);
  rmsg.Status = sts;
  udp_Send( (char *)&rmsg, sizeof(rmsg));
}
Beispiel #2
0
int print_attribute( pwr_tAttrRef *arp, pwr_tClassId classid, char *object_p, char *attributename,
		  int array_element, int index, FILE *fp)
{
  pwr_tTypeId tid;
  pwr_tUInt32 size, offs, elem;
  char objectname[120];
  char parname[120];
  char *s;
  int sts;
  char buf[1024];

  strcpy( objectname, attributename);
  s = strchr( objectname, '.');
  strcpy( parname, s+1);
  *s = 0;

  sts = gdh_GetAttributeCharacteristics( attributename, &tid, &size, &offs, &elem);
  if ( EVEN(sts)) return sts;

  if ( !array_element) {
    sts = gdh_GetObjectInfo( attributename, buf, sizeof(buf));
    if ( EVEN(sts)) return sts;

    print_attr( buf,  arp, objectname, parname, tid, size, 
		0, elem, fp);
  }
  else {
    print_attr( object_p, arp, objectname, parname, tid, size, offs,
		elem, fp);
  }
  return 1;
}
Beispiel #3
0
//
// Check that the current selected item is valid for change
//
int XAttNav::check_attr( int *multiline, brow_tObject *node, char *name,
		char **init_value, int *size)
{
  brow_tNode	*node_list;
  int		node_count;
  Item		*base_item;
  pwr_tStatus   sts;

  *init_value = 0;
  *multiline = 0;
  
  brow_GetSelectedNodes( brow->ctx, &node_list, &node_count);
  if ( !node_count)
    return XATT__NOSELECT;

  brow_GetUserData( node_list[0], (void **)&base_item);
  *node = node_list[0];
  free( node_list);

  switch( base_item->type) {

  case xnav_eItemType_Attr:
  case xnav_eItemType_AttrArrayElem:
  case xnav_eItemType_Collect: {

    pwr_tTypeId a_tid;
    pwr_tUInt32 a_size, a_offs, a_elem;
    ItemBaseAttr *item = (ItemBaseAttr *)base_item;

    if ( item->noedit)
      return XATT__NOCHANGE;
      
    strcpy( name, item->attr);

    sts = gdh_GetAttributeCharacteristics( name, &a_tid, &a_size, &a_offs, &a_elem);
    if ( ODD(sts))
      *size = cdh_TypeToMaxStrSize( (pwr_eType)item->type_id, a_size, a_elem);
    else
      *size = 80;
    
    return 1;
  }
  default:
    return XATT__NOCHANGE;
  }
}
Beispiel #4
0
int main (int argc, char **argv)
{
  pwr_tStatus sts;
  char *c;
  int cidopt = 0;
  pwr_tObjName cidstr;
  pwr_tAName astr;
  int i;

  if ( argc <= 1) {
    usage();
    exit(1);
  }

  sts = gdh_Init("rt_gdhget");
  if ( EVEN(sts)) {
    exit(sts);
  }

  for ( i = 1; i < argc; i++) {
    c = argv[i];
    if ( *c == '-') {
      c++;
      switch ( *c) {
      case 'h':
	usage();
	exit(0);
     
      case 'c':
	if ( argc <= i+1) {
	  usage();
	  exit(1);
	}
	strncpy( cidstr, argv[i+1], sizeof(cidstr));
	cidopt = 1;
	i++;
	break;
      }
    }
    else
      strcpy( astr, argv[i]);
  }
  
  if ( cidopt) {
    // Get the first object of class cidstr, and print the value of attribute 
    // astr in this object

    pwr_tCid cid;
    pwr_tOid oid;
    pwr_tAttrRef aref, aaref;
    pwr_tTid a_tid;
    unsigned int a_size, a_offs, a_dim;
    void *a_valp;
    char str[256];

    sts = gdh_ClassNameToId( cidstr, &cid);
    if ( EVEN(sts)) {
      exit(sts);
    }

    sts = gdh_GetClassList( cid, &oid);
    if ( EVEN(sts)) {
      exit(sts);
    }

    aref = cdh_ObjidToAref( oid);
    sts = gdh_ArefANameToAref( &aref, astr, &aaref);
    if ( EVEN(sts)) {
      exit(sts);
    }

    sts = gdh_GetAttributeCharAttrref( &aaref, &a_tid, &a_size, &a_offs, &a_dim);
    if ( EVEN(sts)) {
      exit(sts);
    }
    a_valp = calloc( 1, a_size);
    sts = gdh_GetObjectInfoAttrref( &aaref, a_valp, a_size);
    if ( EVEN(sts)) {
      free( a_valp);
      exit(sts);
    }
    
    sts = cdh_AttrValueToString( a_tid, a_valp, str, sizeof(str));
    if ( EVEN(sts)) {
      free( a_valp);
      exit(sts);
    }

    printf( "%s\n", str);
    free( a_valp);

    exit(0);

  }
  else {
    // Print the value of the attriute in astr

    pwr_tTypeId a_tid;
    pwr_tUInt32 a_size, a_offs, a_elem;
    void *a_valp;
    char str[256];
    
    sts = gdh_GetAttributeCharacteristics( astr,
					 &a_tid, &a_size, &a_offs, &a_elem);
    if ( EVEN(sts)) {
      exit(sts);
    }
    a_valp = calloc( 1, a_size);

    sts = gdh_GetObjectInfo( astr, a_valp, a_size);
    if ( EVEN(sts)) {
      free( a_valp);
      exit(sts);
    }
    
    sts = cdh_AttrValueToString( a_tid, a_valp, str, sizeof(str));
    if ( EVEN(sts)) {
      free( a_valp);
      exit(sts);
    }

    printf( "%s\n", str);
    free( a_valp);

    exit(0);
  }    
  exit(1);
}
Beispiel #5
0
void fastobject::open( double base_scantime)
{
  pwr_tStatus sts;
  pwr_tUInt32 size, offs, elem;
  pwr_tTypeId type_id;
  pwr_tAName name;

  // Link to object
  sts = gdh_DLRefObjectInfoAttrref( &aref, (void **)&p, &p_dlid); 
  if ( EVEN(sts)) throw co_error(sts);

  // Link to trigg object
  if ( cdh_ObjidIsNotNull( p->TriggObject.Objid)) {
    sts = gdh_DLRefObjectInfoAttrref( &p->TriggObject, (void **)&trigg, &trigg_dlid); 
    if ( EVEN(sts)) {
      if ( p->Function & fast_mFunction_ManTrigg || 
	   p->Function & fast_mFunction_LevelTrigg)
	trigg = 0;
      else
	throw co_error(sts);
    }
  }

  // Link to attributes
  for ( int i = 0; i < FAST_CURVES; i++) {
    if ( cdh_ObjidIsNotNull( p->Attribute[i].Objid)) {
      sts = gdh_DLRefObjectInfoAttrref( &p->Attribute[i], (void **)&attributes[i], &attributes_dlid[i]);
      if ( EVEN(sts)) throw co_error(sts);

      // Get attribute type
      sts = gdh_AttrrefToName( &p->Attribute[i], name, sizeof( name), cdh_mName_volumeStrict);
      if ( EVEN(sts)) throw co_error(sts);
      
      sts = gdh_GetAttributeCharacteristics( name, &p->AttributeType[i],
					     &attributes_size[i], &offs, &elem);
      if ( EVEN(sts)) throw co_error(sts);

      p->CurveValid[i] = true;
    }
  }

  // Link to time buffer
  if ( cdh_ObjidIsNotNull( p->TimeBuffer.Objid)) {
    sts = gdh_DLRefObjectInfoAttrref( &p->TimeBuffer, (void **)&time_buffer, &time_buffer_dlid); 
    if ( EVEN(sts)) throw co_error(sts);

    // Get buffer size
    sts = gdh_AttrrefToName( &p->TimeBuffer, name, sizeof( name), cdh_mName_volumeStrict);
    if ( EVEN(sts)) throw co_error(sts);

    sts = gdh_GetAttributeCharacteristics( name, &type_id, &size, &offs, &elem);
    if ( EVEN(sts)) throw co_error(sts);

    if ( size < p->NoOfPoints * sizeof(pwr_tFloat32))
      p->NoOfPoints = size / sizeof(pwr_tFloat32);
  }

  // Link to attribute buffers
  for ( int i = 0; i < FAST_CURVES; i++) {
    if ( cdh_ObjidIsNotNull( p->Buffers[i].Objid) && p->CurveValid[i]) {
      p->CurveValid[i] = false;
      sts = gdh_DLRefObjectInfoAttrref( &p->Buffers[i], (void **)&buffers[i], &buffers_dlid[i]); 
      if ( EVEN(sts)) throw co_error(sts);

      p->CurveValid[i] = true;

      // Get buffer size
      sts = gdh_AttrrefToName( &p->Buffers[i], name, sizeof( name), cdh_mName_volumeStrict);
      if ( EVEN(sts)) throw co_error(sts);

      sts = gdh_GetAttributeCharacteristics( name, &type_id, &size, &offs, &elem);
      if ( EVEN(sts)) throw co_error(sts);

      if ( size < p->NoOfPoints * attributes_size[i])
	p->NoOfPoints = size / attributes_size[i];
    }
  }

  p->TriggMan = 0;
  p->Active = 0;
  p->Prepare = 0;
  p->TriggIndex = 0;
  if ( trigg)
    *trigg = 0;

  if ( p->ScanTime)
    scan_div = int( p->ScanTime / base_scantime + 0.5);
  else
    scan_div = 1;
  scan_base = base_scantime;
}
Beispiel #6
0
int XNav::getAllMenuItems( xmenu_sMenuCall	*ip,
			   xmenu_sMenuItem	**Item,
			   pwr_tObjid		objid,
			   pwr_tUInt32		Level,
			   int			*nItems,
			   int			AddSeparator,
			   pwr_sAttrRef		*CurrentObject)
{
  int                   sts;
  pwr_tCid	        classid;
  pwr_tObjid            child;
  pwr_sMenuButton	*mbp;
  pwr_sMenuCascade	*mcp;
  pwr_sMenuRef		*mrp;
  pwr_tStatus           (*filter)( xmenu_sMenuCall *);
  int                   sensitive;
  int                   i;


  Level++;
  memset(*Item, 0, sizeof(**Item));

  if(AddSeparator) {
    (*Item)->Level = Level;
    (*Item)->Item = xmenu_eMenuItem_Separator;
    (*Item)->MenuObject = pwr_cNObjid;
    (*Item)++;
    (*nItems)++;
  } 
  else {
    sts = gdh_GetObjectClass( objid, &classid);
    if ( EVEN(sts)) return sts;

    if ( classid == pwr_eClass_MenuButton) {
      sts = gdh_ObjidToPointer( objid, (void **) &mbp);
      if ( EVEN(sts)) return sts;

      
      ip->ChosenItem = *nItems;
      for ( i = 0; i < 5; i++) {
        strcpy( (*Item)->FilterArguments[i], mbp->FilterArguments[i]);
      }

      // Call any filter method
      (*Item)->CurrentObject = *CurrentObject;
      sensitive = 1;
      if ( strcmp( mbp->FilterName, "") != 0) {
        sts = GetMethod( mbp->FilterName, &filter);
        if ( ODD(sts)) {
          sts = (filter) ( ip);
	  if ( sts == XNAV__INSENSITIVE) 
            sensitive = 0;
        }
      }
      else
        sts = XNAV__SUCCESS;

      if ( ODD(sts)) {
        (*Item)->Level = Level;
        (*Item)->Item = xmenu_eMenuItem_Button;
        (*Item)->MenuObject = objid;

        (*Item)->Flags.f.Sensitive = sensitive;
        if (strcmp( mbp->MethodName, "")  == 0)
          (*Item)->Flags.f.Sensitive = 0;

        strcpy((*Item)->Name, mbp->ButtonName);
        strcpy( (*Item)->Method, mbp->MethodName);
        strcpy( (*Item)->Filter, mbp->FilterName);
        for ( i = 0; i < 5; i++) {
          strcpy( (*Item)->MethodArguments[i], mbp->MethodArguments[i]);
        }
        (*Item)++;
        (*nItems)++;
      }
    } 
    else if ( classid == pwr_eClass_MenuSeparator) {
      (*Item)->Level = Level;
      (*Item)->Item = xmenu_eMenuItem_Separator;
      (*Item)->MenuObject = objid;
      (*Item)++;
      (*nItems)++;
    } 
    else if ( classid == pwr_eClass_MenuCascade) {
      sts = gdh_ObjidToPointer( objid, (void **) &mcp);
      if ( EVEN(sts)) return sts;

      // Call any filter method
      (*Item)->CurrentObject = *CurrentObject;
      if ( strcmp( mcp->FilterName, "") != 0) {
        sts = GetMethod( mcp->FilterName, &filter);
        if ( ODD(sts)) {
          sts = (filter) ( ip);
        }
      }
      else
        sts = XNAV__SUCCESS;

      if ( ODD(sts)) {
        (*Item)->Level = Level;
        (*Item)->Item = xmenu_eMenuItem_Cascade;
        (*Item)->Flags.f.Sensitive = 1;
        strcpy((*Item)->Name, mcp->ButtonName);
        (*Item)->MenuObject = objid;
        (*Item)++;
        (*nItems)++;
     
        sts = gdh_GetChild( objid, &child);
        while( ODD(sts)) {
          sts = getAllMenuItems(ip, Item, child, Level, nItems, 0, CurrentObject);
          if ( EVEN(sts)) return sts;
          sts = gdh_GetNextSibling( child, &child);
        }
      }
    }
    else if ( classid == pwr_eClass_MenuRef && 
	      cdh_ObjidIsNull( CurrentObject->Objid)) {
      pwr_tAName aname;
      pwr_sAttrRef currentar;
      pwr_tCid current_cid;
      pwr_tTid a_tid;
      pwr_tUInt32 a_size, a_offs, a_elem;

      sts = gdh_ObjidToPointer( objid, (void **) &mrp);
      if ( EVEN(sts)) return sts;

      // Call any filter method
      (*Item)->CurrentObject = *CurrentObject;
      if ( strcmp( mrp->FilterName, "") != 0) {
        sts = GetMethod( mrp->FilterName, &filter);
        if ( ODD(sts)) {
          sts = (filter) ( ip);
        }
      }
      else
        sts = XNAV__SUCCESS;

      if ( ODD(sts)) {
	int create_object_button = 0;

	if ( strcmp( mrp->RefAttribute, "_SelfObject") == 0) {
	  // Object entry for attributes
	  char *s;

	  sts = gdh_AttrrefToName( &ip->Pointed, aname, sizeof(aname), cdh_mName_volumeStrict);
	  if ( EVEN(sts)) return sts;
	  if ( (s = strrchr( aname, '.')))
	    *s = 0;

	  sts = gdh_NameToAttrref( pwr_cNOid, aname, &currentar);
	  if ( EVEN(sts)) return sts;
	}
	else {
	  sts = gdh_AttrrefToName( &ip->Pointed, aname, sizeof(aname), cdh_mName_volumeStrict);
	  if ( EVEN(sts)) return sts;
	  strcat( aname, ".");
	  strcat( aname, mrp->RefAttribute);
	  
	  sts = gdh_GetAttributeCharacteristics( aname, &a_tid, &a_size,
						 &a_offs, &a_elem);
	  if ( ODD(sts)) {
	    switch ( a_tid) {
	    case pwr_eType_AttrRef:
	      sts = gdh_GetObjectInfo( aname, &currentar, sizeof(currentar));
	      break;
	    case pwr_eType_Objid: {
	      pwr_tOid oid;
	      
	      currentar = pwr_cNAttrRef;
	      sts = gdh_GetObjectInfo( aname, &oid, sizeof(oid));
	      currentar = cdh_ObjidToAref( oid);
	      break;
	    }
	    default:
	      sts = 0;
	  }
	  }
	  create_object_button = 0;
	}
	if ( ODD(sts) && cdh_ObjidIsNotNull( currentar.Objid)) {
	  (*Item)->Level = Level;
	  (*Item)->Item = xmenu_eMenuItem_Ref;
	  (*Item)->Flags.f.Sensitive = 1;
	  strcpy((*Item)->Name, mrp->ButtonName);
	  (*Item)->MenuObject = objid;
	  (*Item)++;
	  (*nItems)++;

	  // Create a label with current object name
	  sts = gdh_AttrrefToName( &currentar, aname, sizeof(aname), 
				   cdh_mNName);
	  if ( ODD(sts) && create_object_button) {
	    (*Item)->Level = Level;
	    (*Item)->Item = xmenu_eMenuItem_Button;
	    (*Item)->MenuObject = pwr_cNObjid;
	    strncpy((*Item)->Name, aname, sizeof((*Item)->Name));
	    (*Item)->Name[sizeof((*Item)->Name)-1] = 0;
	    (*Item)->MenuObject = pwr_cNObjid;
	    (*Item)->CurrentObject = currentar;
	    (*Item)->Flags.f.Sensitive = 1;
	    strcpy( (*Item)->Method, "$Object-OpenObject");
	    (*Item)++;
	    (*nItems)++;
	  }

	  sts = gdh_GetAttrRefTid( &currentar, &current_cid);
	  if ( EVEN(sts)) return sts;

	  xmenu_eItemType item_type = ip->ItemType;
	  if ( currentar.Flags.b.Object)
	    ip->ItemType =  xmenu_eItemType_Object;
	  else
	    ip->ItemType =  xmenu_eItemType_AttrObject;

	  sts = GetObjectMenu(ip, current_cid, Item, Level, nItems, 0, &currentar);
	  if ( EVEN(sts)) return sts;

	  ip->ItemType = item_type;
        }
      }
    }
  }
  return XNAV__SUCCESS;
}
Beispiel #7
0
static void pwrsrv_SubAdd( rpvd_sMsgSubAdd *msg)
{
  rpvd_sMsgAny rmsg;
  pwr_tAName name;
  pwr_tUInt32 asize, aoffs, aelem;
  pwr_tTypeId atid;
  pwr_tStatus sts;
  pwrsrv_sSubItem *si;
  void *p;
  pwr_tRefId dlid;
  
  rmsg.Type = rpvd_eMsg_Status;
  rmsg.Id = msg->Id;

  /* Check that this rix doesn't exist */
  for ( si = pwrsrv_sublist; si; si = si->next) {
    if ( si->rix == msg->Rix) {
      return;
    }
  }

  sts = gdh_ObjidToName( msg->Oid, name, sizeof(name), cdh_mName_volumeStrict);
  if ( EVEN(sts)) {
    rmsg.Status = sts;
    udp_Send( (char *)&rmsg, sizeof(rmsg));
    return;
  }

  if ( strcmp( msg->Attribute, "") != 0) {
    strcat( name, ".");
    strcat( name, msg->Attribute);

    sts = gdh_GetAttributeCharacteristics( name, &atid, &asize, &aoffs, &aelem);
    if ( EVEN(sts)) {
      rmsg.Status = sts;
      udp_Send( (char *)&rmsg, sizeof(rmsg));
      return;
    }
  }
  else {
    sts = gdh_GetObjectSize( msg->Oid, &asize);
    if ( EVEN(sts)) {
      rmsg.Status = sts;
      udp_Send( (char *)&rmsg, sizeof(rmsg));
      return;
    }
  }

  /* Direct link to atttribute */
  sts = gdh_RefObjectInfo( name, &p, &dlid, asize);
  if ( EVEN(sts)) {
    rmsg.Status = sts;
    udp_Send( (char *)&rmsg, sizeof(rmsg));
    return;
  }
       
  /* Insert first in sublist */
  si = (pwrsrv_sSubItem *) calloc( 1, sizeof(pwrsrv_sSubItem));
  si->oid = msg->Oid;
  strcpy( si->attribute, msg->Attribute);
  si->size = asize;
  si->rix = msg->Rix;
  si->p = p;
  si->dlid = dlid;
       
  si->next = pwrsrv_sublist;
  if ( si->next)
    si->next->prev = si;
  pwrsrv_sublist = si;

  
  printf( "SubAdd: %d %s\n", msg->Rix, name);

  rmsg.Status = GDH__SUCCESS;
  udp_Send( (char *)&rmsg, sizeof(rmsg));
}
Beispiel #8
0
static int graph_object_collect_build( Graph *graph, pwr_sAttrRef *attrref)
{
    pwr_sAttrRef *alist, *ap;
    int *is_attrp, *is_attr;
    int sts;
    char name[120];
    double x1, y1;
    grow_sAttrInfo *grow_info, *grow_info_p;
    int grow_info_cnt;
    int i;
    grow_tObject scantime_button;
    grow_tObject hold_button;
    grow_tObject t1, l1;
    double z_width, z_height, z_descent;
    double name_width = 0;
    double trend_width = 48;
    double trend_height = 1.2;
    double y0 = 2.2;
    double x0 = 2;
    pwr_tTypeId attr_type;
    unsigned int attr_size, attr_offset, attr_dimension;
    GeDyn *dyn;
    char attr_name[120];
    grow_sAttributes grow_attr;
    unsigned long mask;
    int trend_cnt = 0;


    if ( ! graph->get_current_objects_cb)
        return 0;

    sts = (graph->get_current_objects_cb) (graph->parent_ctx, &alist, &is_attr);
    if ( EVEN(sts)) return sts;

    if ( cdh_ObjidIsNull( alist->Objid))
        return 0;

    graph->graph_object_data = 0;
    graph->graph_object_close = 0;

    grow_SetPath( graph->grow->ctx, 1, "pwr_exe:");

    // Set graph attributes

    // Default color theme
    mask = grow_eAttr_color_theme;
    strcpy( grow_attr.color_theme, "$default");
    grow_SetAttributes( graph->grow->ctx, &grow_attr, mask);
    grow_ReadCustomColorFile( graph->grow->ctx, 0);

    grow_SetBackgroundColor( graph->grow->ctx, glow_eDrawType_CustomColor1);

    // Scantime input field
    graph->create_node( NULL, "pwrct_valueinputsmallbg", x0, y0 - 1.3, 4, y0 - 1.3 + 1.2,
                        &scantime_button);

    dyn = new GeDyn( graph);
    grow_SetUserData( scantime_button, (void *)dyn);

    dyn->set_dyn( ge_mDynType1_Value, ge_mDynType2_No, ge_mActionType1_ValueInput, ge_mActionType2_No);
    dyn->update_elements();
    dyn->set_access( (glow_mAccess) 65535);
    dyn->set_attribute( scantime_button, "$local.ScanTime##Float32", 0);
    dyn->set_value_input( "%3.0f", 2, 10000000);

    // Hold button
    graph->create_node( "TrendHold", "pwrct_buttonsmalltoggle", x0 + trend_width/2 - 3./2,
                        y0 - 1.4 , x0 + trend_width/2 + 3./2, y0 - 1.4 + 1.2,
                        &hold_button);
    grow_SetAnnotation( hold_button, 1, "Hold", 4);

    dyn = new GeDyn( graph);
    grow_SetUserData( hold_button, (void *)dyn);

    dyn->set_access( (glow_mAccess) 65535);
    dyn->set_attribute( hold_button, "$local.TrendHold##Boolean", 0);

    //  Zero text
    grow_CreateGrowText( graph->grow->ctx, "", "0",
                         x0 + trend_width - 0.2, y0 - 0.3,
                         glow_eDrawType_TextHelvetica, glow_eDrawType_CustomColor5, 3,
                         glow_eFont_LucidaSans, glow_mDisplayLevel_1,
                         NULL, &t1);

    ap = alist;
    is_attrp = is_attr;
    x1 = x0;
    y1 = y0;
    while( cdh_ObjidIsNotNull( ap->Objid)) {
        if ( *is_attrp) {
            sts = gdh_AttrrefToName( ap, name, sizeof(name), cdh_mNName);
            if ( EVEN(sts)) return sts;

            sts = gdh_GetAttributeCharacteristics( name, &attr_type, &attr_size,
                                                   &attr_offset, &attr_dimension);
            if ( EVEN(sts)) return sts;

            switch ( attr_type) {
            case pwr_eType_Boolean: {
                grow_tObject trend;

                grow_CreateGrowTrend( graph->grow->ctx, "ActualValueTrend",
                                      x1, y1, trend_width, trend_height,
                                      glow_eDrawType_Color37,
                                      0, glow_mDisplayLevel_1, 1, 1,
                                      glow_eDrawType_Color40, NULL,
                                      &trend);
                dyn = new GeDyn( graph);
                dyn->dyn_type1 = ge_mDynType1_Trend;
                dyn->update_dyntype( trend);
                dyn->update_elements();
                grow_SetUserData( trend, (void *)dyn);

                grow_GetObjectAttrInfo( trend, NULL,
                                        &grow_info, &grow_info_cnt);

                strcpy( attr_name, name);
                strcat( attr_name, "##Boolean");
                grow_GetUserData( trend, (void **)&dyn);
                strcpy( ((GeTrend *)dyn->elements)->attribute1, attr_name);
                strcpy( ((GeTrend *)dyn->elements)->timerange_attr, "$local.ScanTime##Float32");
                strcpy( ((GeTrend *)dyn->elements)->hold_attr, "$local.TrendHold##Boolean");
                grow_info_p = grow_info;
                for ( i = 0; i < grow_info_cnt; i++) {
                    if ( strcmp( grow_info_p->name, "NoOfPoints") == 0)
                        *(int *) grow_info_p->value_p = 200;
                    else if ( strcmp( grow_info_p->name, "HorizontalLines") == 0)
                        *(int *) grow_info_p->value_p = 0;
                    else if ( strcmp( grow_info_p->name, "VerticalLines") == 0)
                        *(int *) grow_info_p->value_p = 9;
                    else if ( strcmp( grow_info_p->name, "CurveColor1") == 0)
                        *(int *) grow_info_p->value_p = glow_eDrawType_CustomColor68;
                    else if ( strcmp( grow_info_p->name, "MaxValue1") == 0)
                        *(double *) grow_info_p->value_p = 1.2;
                    else if ( strcmp( grow_info_p->name, "MinValue1") == 0)
                        *(double *) grow_info_p->value_p = -0.1;

                    grow_info_p++;
                }
                grow_FreeObjectAttrInfo( grow_info);

                // This will configure the curves
                grow_SetTrendScanTime( trend, 0.5);

                grow_SetObjectOriginalFillColor( trend, glow_eDrawType_CustomColor66);
                grow_SetObjectOriginalBorderColor( trend, glow_eDrawType_CustomColor67);

                grow_GetTextExtent( graph->grow->ctx, name,
                                    strlen(name), glow_eDrawType_TextHelvetica,
                                    4, glow_eFont_LucidaSans, &z_width, &z_height, &z_descent);

                grow_CreateGrowText( graph->grow->ctx, "", name,
                                     x1 + trend_width + 1, y1 + trend_height/2 + z_height/2,
                                     glow_eDrawType_TextHelvetica, glow_eDrawType_CustomColor5, 4,
                                     glow_eFont_LucidaSans, glow_mDisplayLevel_1,
                                     NULL, &t1);
                if ( z_width > name_width)
                    name_width = z_width;

                trend_cnt++;
                y1 += trend_height;
                break;
            }
            default:
                ;
            }
            if ( trend_cnt >= MAX_TREND_OBJECTS)
                break;
        }

        ap++;
        is_attrp++;
    }
    free( alist);
    free( is_attr);

    // Draw separator lines between name texts
    y1 = y0;
    x1 = x0 + trend_width;
    grow_CreateGrowLine( graph->grow->ctx, "",
                         x0 + trend_width, y1, x0 + trend_width + name_width + 2, y1,
                         glow_eDrawType_CustomColor4, 1, 0, NULL, &l1);

    for ( i = 0; i < trend_cnt; i++) {
        y1 += trend_height;

        grow_CreateGrowLine( graph->grow->ctx, "",
                             x0 + trend_width, y1, x0 + trend_width + name_width + 2, y1,
                             glow_eDrawType_CustomColor4, 1, 0, NULL, &l1);
    }

    // Draw frame
    grow_CreateGrowRect( graph->grow->ctx, "R1", x0 - 1.5, y0 - 2.7,
                         trend_width + name_width + 5.5, 1, glow_eDrawType_CustomColor3,
                         1, 0, glow_mDisplayLevel_1, 1, 0, 0,
                         glow_eDrawType_CustomColor3, NULL, &l1);
    grow_CreateGrowRect( graph->grow->ctx, "R2", x0 - 1.5, y0 + trend_cnt * trend_height + 0.5,
                         trend_width + name_width + 5.5, 5, glow_eDrawType_CustomColor3,
                         1, 0, glow_mDisplayLevel_1, 1, 0, 0,
                         glow_eDrawType_CustomColor3, NULL, &l1);
    grow_CreateGrowRect( graph->grow->ctx, "R3", x0 + trend_width + name_width + 2, y0 - 1.7,
                         2, y0 + trend_cnt * trend_height + 0.9, glow_eDrawType_CustomColor3,
                         1, 0, glow_mDisplayLevel_1, 1, 0, 0,
                         glow_eDrawType_CustomColor3, NULL, &l1);
    grow_CreateGrowRect( graph->grow->ctx, "R4", x0 - 1.5, y0 - 1.7,
                         1, y0 + trend_cnt * trend_height + 0.9, glow_eDrawType_CustomColor3,
                         1, 0, glow_mDisplayLevel_1, 1, 0, 0,
                         glow_eDrawType_CustomColor3, NULL, &l1);

    grow_SetLayout( graph->grow->ctx, x0 - 1, y0 - 2.3, x0 + trend_width +
                    name_width + 3, y0 + trend_cnt * trend_height + 1.5);

    // Set graph attributes
    mask = grow_eAttr_double_buffer_on;
    grow_attr.double_buffer_on = 1;
    grow_SetAttributes( graph->grow->ctx, &grow_attr, mask);

    return 1;
}