/*
* Motif
*
* Copyright (c) 1987-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these librararies and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/*
* HISTORY
*/
#ifdef REV_INFO
#ifndef lint
static char rcsid[] = "$XConsortium: ExtObject.c /main/13 1995/10/25 20:03:50 cde-sun $"
#endif
#endif
/* (c) Copyright 1989, 1990 DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */
/* (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 HEWLETT-PACKARD COMPANY */
/* (c) Copyright 1988 MASSACHUSETTS INSTITUTE OF TECHNOLOGY */
/* (c) Copyright 1988 MICROSOFT CORPORATION */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <string.h>
#include "BaseClassI.h"
#include "ExtObjectI.h"
#include "SyntheticI.h"
#include "XmI.h"
/******** Static Function Declarations ********/
static void ClassInitialize(void);
static void ClassPartInitPrehook(WidgetClass c);
static void ClassPartInitPosthook(WidgetClass c);
static void ClassPartInitialize(WidgetClass c);
static void InitializePrehook(Widget req, Widget new_w,
ArgList args, Cardinal *num_args);
static void Initialize(Widget req, Widget new_w,
ArgList args, Cardinal *num_args);
static Boolean SetValuesPrehook(Widget req, Widget curr, Widget new_w,
ArgList args, Cardinal *num_args);
static void GetValuesPrehook(Widget new_w, ArgList args, Cardinal *num_args);
static Boolean SetValues(Widget old, Widget ref, Widget new_w,
ArgList args, Cardinal *num_args);
static void GetValuesHook(Widget new_w, ArgList args, Cardinal *num_args);
static void Destroy(Widget wid);
static void UseParent(Widget w, int offset, XrmValue *value);
/******** End Static Function Declarations ********/
/***************************************************************************
*
* ExtObject Resources
*
***************************************************************************/
#define Offset(field) XtOffsetOf(struct _XmExtRec, ext.field)
static XtResource extResources[] =
{
{
XmNlogicalParent, XmCLogicalParent, XmRWidget,
sizeof (Widget), Offset (logicalParent),
XmRCallProc, (XtPointer)UseParent
},
{
XmNextensionType, XmCExtensionType, XmRExtensionType,
sizeof (unsigned char), Offset (extensionType),
XmRImmediate, (XtPointer)XmDEFAULT_EXTENSION
}
};
#undef Offset
#define XmNUM_ELEMENTS 4
#define XmNUM_BYTES 255
typedef struct _XmExtCache {
char data[XmNUM_BYTES];
Boolean inuse;
} XmExtCache;
typedef union {
XmExtCache cache;
double force_alignment;
} Aligned_XmExtCache;
static Aligned_XmExtCache extarray[XmNUM_ELEMENTS];
static XmBaseClassExtRec myBaseClassExtRec = {
NULL, /* Next extension */
NULLQUARK, /* record type XmQmotif */
XmBaseClassExtVersion, /* version */
sizeof(XmBaseClassExtRec), /* size */
InitializePrehook, /* initialize prehook */
SetValuesPrehook, /* set_values prehook */
NULL, /* initialize posthook */
NULL, /* set_values posthook */
NULL, /* secondary class */
NULL, /* creation proc */
NULL, /* getSecRes data */
{ 0 }, /* fast subclass */
GetValuesPrehook, /* get_values prehook */
NULL, /* get_values posthook */
ClassPartInitPrehook, /* class_part_prehook */
ClassPartInitPosthook, /* class_part_posthook */
NULL, /* compiled_ext_resources */
NULL, /* ext_resources */
0, /* resource_count */
FALSE /* use_sub_resources */
};
externaldef(xmextclassrec)
XmExtClassRec xmExtClassRec = {
{
(WidgetClass) &objectClassRec,/* superclass */
"dynamic", /* class_name */
sizeof(XmExtRec), /* size */
ClassInitialize, /* Class Initializer */
ClassPartInitialize, /* class_part_init */
FALSE, /* Class init'ed ? */
Initialize, /* initialize */
NULL, /* initialize_notify */
NULL, /* realize */
NULL, /* actions */
0, /* num_actions */
extResources, /* resources */
XtNumber(extResources), /* resource_count */
NULLQUARK, /* xrm_class */
FALSE, /* compress_motion */
FALSE, /* compress_exposure */
FALSE, /* compress_enterleave */
FALSE, /* visible_interest */
Destroy, /* destroy */
NULL, /* resize */
NULL, /* expose */
SetValues, /* set_values */
NULL, /* set_values_hook */
NULL, /* set_values_almost */
GetValuesHook, /* get_values_hook */
NULL, /* accept_focus */
XtVersion, /* intrinsics version */
NULL, /* callback offsets */
NULL, /* tm_table */
NULL, /* query_geometry */
NULL, /* display_accelerator */
(XtPointer)&myBaseClassExtRec /* extension */
},
{
NULL, /* synthetic resources */
0 /* num syn resources */
}
};
externaldef(xmextobjectclass)
WidgetClass xmExtObjectClass = (WidgetClass) (&xmExtClassRec);
/*ARGSUSED*/
static void
UseParent(Widget w,
int offset, /* unused */
XrmValue *value)
{
value->addr = (XPointer) &(w->core.parent);
}
/************************************************************************
*
* ClassInitialize
*
************************************************************************/
static void
ClassInitialize(void)
{
myBaseClassExtRec.record_type = XmQmotif;
}
/************************************************************************
*
* ClassPartInitPrehook
*
************************************************************************/
static void
ClassPartInitPrehook(WidgetClass c)
{
XmExtObjectClass wc = (XmExtObjectClass) c;
if ((WidgetClass)wc != xmExtObjectClass)
{
XmExtObjectClass sc = (XmExtObjectClass) c->core_class.superclass;
XmBaseClassExt *scePtr = _XmGetBaseClassExtPtr(sc, XmQmotif);
/*
* If our superclass uses subresources, then we need to
* temporarily fill it's core resource fields so that objectClass
* classPartInit will be able to find them for merging. We
* assume that we only need to set things up for the
* superclass and not any deeper ancestors.
*/
if ((*scePtr)->use_sub_resources)
{
sc->object_class.resources = (*scePtr)->compiled_ext_resources;
sc->object_class.num_resources = (*scePtr)->num_ext_resources;
}
}
}
/************************************************************************
*
* ClassPartInitPosthook
*
************************************************************************/
static void
ClassPartInitPosthook(WidgetClass c)
{
XmExtObjectClass wc = (XmExtObjectClass) c;
XmBaseClassExt *wcePtr = _XmGetBaseClassExtPtr(wc, XmQmotif);
if ((*wcePtr) && (*wcePtr)->use_sub_resources)
{
/*
* Put our compiled resources back and zero out oject class so
* it's invisible to object class create processing.
*/
(*wcePtr)->compiled_ext_resources = wc->object_class.resources;
(*wcePtr)->num_ext_resources = wc->object_class.num_resources;
}
}
/************************************************************************
*
* ClassPartInitialize
* Set up the inheritance mechanism for the routines exported by
* vendorShells class part.
*
************************************************************************/
static void
ClassPartInitialize(WidgetClass c)
{
XmExtObjectClass wc = (XmExtObjectClass) c;
if (wc == (XmExtObjectClass)xmExtObjectClass)
return;
_XmBuildExtResources(c);
}
/*ARGSUSED*/
static void
InitializePrehook(Widget req, /* unused */
Widget new_w,
ArgList args,
Cardinal *num_args)
{
XmExtObjectClass ec = (XmExtObjectClass) XtClass(new_w);
XmBaseClassExt *wcePtr = _XmGetBaseClassExtPtr(ec, XmQmotif);
if ((*wcePtr)->use_sub_resources)
{
/*
* Get a uncompiled resource list to use with XtGetSubresources.
* We can't do this in ClassPartInitPosthook because Xt doesn't
* set class_inited at the right place and thereby mishandles
* the XtGetResourceList call.
*/
_XmProcessLock();
if ((*wcePtr)->ext_resources == NULL)
{
ec->object_class.resources = (*wcePtr)->compiled_ext_resources;
ec->object_class.num_resources = (*wcePtr)->num_ext_resources;
XtGetResourceList((WidgetClass) ec,
&((*wcePtr)->ext_resources),
&((*wcePtr)->num_ext_resources));
}
XtGetSubresources(XtParent(new_w),
(XtPointer)new_w,
NULL, NULL,
(*wcePtr)->ext_resources,
(*wcePtr)->num_ext_resources,
args, *num_args);
_XmProcessUnlock();
}
}
static void
Initialize(Widget req,
Widget new_w,
ArgList args,
Cardinal *num_args)
{
XmExtObject ne = (XmExtObject) new_w;
XmExtObjectClass ec = (XmExtObjectClass) XtClass(new_w);
Widget resParent = ne->ext.logicalParent;
XmWidgetExtData extData;
XmBaseClassExt *wcePtr = _XmGetBaseClassExtPtr(ec, XmQmotif);
if (!(*wcePtr)->use_sub_resources)
{
if (resParent)
{
extData = (XmWidgetExtData) XtCalloc(1, sizeof(XmWidgetExtDataRec));
_XmPushWidgetExtData(resParent, extData, ne->ext.extensionType);
extData->widget = new_w;
_XmProcessLock();
extData->reqWidget = (Widget)
_XmExtObjAlloc(XtClass(new_w)->core_class.widget_size);
memcpy((char *)extData->reqWidget, (char *)req,
XtClass(new_w)->core_class.widget_size);
_XmProcessUnlock();
/* Convert the fields from unit values to pixel values */
_XmExtImportArgs(new_w, args, num_args);
}
}
}
/*ARGSUSED*/
static Boolean
SetValuesPrehook(Widget req, /* unused */
Widget curr, /* unused */
Widget new_w,
ArgList args,
Cardinal *num_args)
{
XmExtObjectClass ec = (XmExtObjectClass) XtClass(new_w);
XmBaseClassExt *wcePtr = _XmGetBaseClassExtPtr(ec, XmQmotif);
if ((*wcePtr)->use_sub_resources)
{
_XmProcessLock();
XtSetSubvalues((XtPointer)new_w,
(*wcePtr)->ext_resources,
(*wcePtr)->num_ext_resources,
args, *num_args);
_XmProcessUnlock();
}
return False;
}
static void
GetValuesPrehook(Widget new_w,
ArgList args,
Cardinal *num_args)
{
XmExtObjectClass ec = (XmExtObjectClass) XtClass(new_w);
XmBaseClassExt *wcePtr = _XmGetBaseClassExtPtr(ec, XmQmotif);
if ((*wcePtr)->use_sub_resources)
{
_XmProcessLock();
XtGetSubvalues((XtPointer)new_w,
(*wcePtr)->ext_resources,
(*wcePtr)->num_ext_resources,
args, *num_args);
_XmProcessUnlock();
}
}
/************************************************************************
*
* SetValues
*
************************************************************************/
/*ARGSUSED*/
static Boolean
SetValues(Widget old,
Widget ref,
Widget new_w,
ArgList args,
Cardinal *num_args)
{
XmExtObject ne = (XmExtObject) new_w;
Widget resParent = ne->ext.logicalParent;
XmWidgetExtData ext = _XmGetWidgetExtData(resParent, ne->ext.extensionType);
Cardinal extSize;
if(ext == NULL)
{
#ifdef DEBUG
XmeWarning(NULL, "_XmGetWidgetExtData() returned NULL pointer.");
#endif
return FALSE;
}
if (resParent)
{
_XmProcessLock();
extSize = XtClass(new_w)->core_class.widget_size;
ext->widget = new_w;
ext->oldWidget = (Widget) _XmExtObjAlloc(extSize);
memcpy((char *)ext->oldWidget, (char *)old, extSize);
ext->reqWidget = (Widget) _XmExtObjAlloc(extSize);
memcpy((char *)ext->reqWidget, (char *)ref, extSize);
_XmProcessUnlock();
/* Convert the necessary fields from unit values to pixel values. */
_XmExtImportArgs(new_w, args, num_args);
}
return FALSE;
}
/************************************************************************
*
* GetValuesHook
*
************************************************************************/
static void
GetValuesHook(Widget new_w,
ArgList args,
Cardinal *num_args)
{
XmExtObject ne = (XmExtObject) new_w;
Widget resParent = ne->ext.logicalParent;
XmWidgetExtData ext;
if (resParent)
{
ext = _XmGetWidgetExtData(resParent, ne->ext.extensionType);
if(ext == NULL)
{
#ifdef DEBUG
XmeWarning(NULL, "_XmGetWidgetExtData() returned NULL pointer.");
#endif
return;
}
ext->widget = new_w;
_XmExtGetValuesHook(new_w, args, num_args);
}
}
/************************************************************************
*
* Destroy
*
************************************************************************/
static void
Destroy(Widget wid)
{
XmExtObject extObj = (XmExtObject) wid;
Widget resParent = extObj->ext.logicalParent;
if (resParent)
{
XmWidgetExtData extData;
_XmPopWidgetExtData(resParent, &extData, extObj->ext.extensionType);
XtFree((char *) extData);
}
}
char *
_XmExtObjAlloc(int size)
{
register int i;
if (size <= XmNUM_BYTES)
{
for (i = 0; i < XmNUM_ELEMENTS; i++)
if (! extarray[i].cache.inuse)
{
extarray[i].cache.inuse = TRUE;
return extarray[i].cache.data;
}
}
return XtMalloc(size);
}
void
_XmExtObjFree(XtPointer element)
{
register int i;
for (i = 0; i < XmNUM_ELEMENTS; i++)
if (extarray[i].cache.data == (char*)element)
{
extarray[i].cache.inuse = FALSE;
return;
}
XtFree((char *) element);
}
/**********************************************************************
*
* _XmBuildExtResources
* Build up the ext's synthetic
* resource processing list by combining the super classes with
* this class.
*
**********************************************************************/
void
_XmBuildExtResources(WidgetClass c)
{
XmExtObjectClass wc = (XmExtObjectClass) c;
XmExtObjectClass sc;
_XmProcessLock();
_XmInitializeSyntheticResources(wc->ext_class.syn_resources,
wc->ext_class.num_syn_resources);
if (wc != (XmExtObjectClass) xmExtObjectClass)
{
sc = (XmExtObjectClass) wc->object_class.superclass;
_XmBuildResources (&(wc->ext_class.syn_resources),
&(wc->ext_class.num_syn_resources),
sc->ext_class.syn_resources,
sc->ext_class.num_syn_resources);
}
_XmProcessUnlock();
}