///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//         This example code is from the book:
//
//           Object-Oriented Programming with C++ and OSF/Motif, 2nd Edition
//         by
//           Douglas Young
//           Prentice Hall, 1995
//           ISBN 0-13-20925507
//
//         Copyright 1995 by Prentice Hall
//         All Rights Reserved
//
//  Permission to use, copy, modify, and distribute this software for 
//  any purpose except publication and without fee is hereby granted, provided 
//  that the above copyright notice appear in all copies of the software.
///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////
// UIComponent.C: Base class for all C++/Motif UI components
/////////////////////////////////////////////////////////////////

#include "UIComponent.h"
#include <assert.h>
#include <stdio.h>

UIComponent::UIComponent ( const char *name ) : BasicComponent ( name )
{
    // Empty
}
void UIComponent::widgetDestroyedCallback ( Widget, 
					    XtPointer clientData, 
					    XtPointer )
{
    UIComponent * obj = ( UIComponent * ) clientData;	
    obj->widgetDestroyed();
}
void UIComponent::widgetDestroyed()
{
    _w = NULL;
}
void UIComponent::installDestroyHandler()
{
    assert ( _w != NULL );
    XtAddCallback ( _w, XmNdestroyCallback,
		    &UIComponent::widgetDestroyedCallback, 
		    ( XtPointer ) this );
}
void UIComponent::manage()
{
    assert ( _w != NULL );
    assert ( XtHasCallbacks ( _w, XmNdestroyCallback ) ==
	     XtCallbackHasSome );
    XtManageChild ( _w );
}
UIComponent::~UIComponent()
{
    // Make sure the widget hasnÕt already been destroyed
    
    if ( _w ) 
    {
	// Remove destroy callback so Xt canÕt call the callback
	// with a pointer to an object that has already been freed
	
	XtRemoveCallback ( _w, 
			   XmNdestroyCallback,
			   &UIComponent::widgetDestroyedCallback,
			   ( XtPointer ) this );	
    }
}
void UIComponent::getResources ( const XtResourceList resources,
				 int numResources )
{
    // Check for errors
    
    assert ( _w != NULL );
    assert ( resources != NULL );
    
    // Retrieve the requested resources relative to the 
    // parent of this objectÕs base widget
    
    XtGetSubresources ( XtParent( _w ), ( XtPointer ) this, 
			_name,      className(),
			resources,  numResources,
			NULL,       0 );
}

void UIComponent::setDefaultResources ( const Widget w, 
					const String *resourceSpec )
{
    int         i;	
    Display    *dpy = XtDisplay ( w );	  // Retrieve the display pointer
    XrmDatabase rdb = NULL;             // A resource database
    
    // Create an empty resource database
    
    rdb = XrmGetStringDatabase ( "" );
    
    // Add the Component resources, prepending the name of the component
    
    i = 0;
    while ( resourceSpec[i] != NULL )
    {
	char buf[1000];
	
	sprintf(buf, "*%s%s", _name, resourceSpec[i++]);
	XrmPutLineResource( &rdb, buf );
    }
    
    // Merge them into the Xt database, with lowest precedence
    
    if ( rdb )
    {
	XrmDatabase db = XtDatabase(dpy);
	XrmCombineDatabase ( rdb, &db, FALSE ); 
    }
}


























