/*
* 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 HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef REV_INFO
#ifndef lint
static char rcsid[] = "$TOG: Mrmwvalues.c /main/12 1999/04/16 09:42:44 mgreess $"
#endif
#endif
/*
* (c) Copyright 1989, 1990, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */
/*
*++
* FACILITY:
*
* UIL Resource Manager (URM):
*
* ABSTRACT:
*
* This module contains the routines which implement modifying
* a widget (XtSetValues) from UID literals.
*
*--
*/
/*
*
* INCLUDE FILES
*
*/
#include <Mrm/MrmAppl.h>
#include <Mrm/Mrm.h>
/*
*
* TABLE OF CONTENTS
*
* UrmFetchSetValues Do XtSetValues from UID literals.
*
*/
/*
*++
*
* PROCEDURE DESCRIPTION:
*
* UrmFetchSetValues is the internal routine which will
* modify a widget via XtSetValues on an argument list whose values
* are evaluated literals from a URM hierarchy.
*
* The args list has ordinary Strings as each tag name. Each value
* is interpreted as a String whose value is the index of a literal
* to be fetched and evaluated as the actual value. This routine
* constructs its own arglist, copying each tag, and setting the
* value to the fetched, fixed up, and converted literal value. The
* argument is not set in this list (is dropped) if there are any
* errors.
*
* This code must also handle pixmaps in the same way that URM does;
* it defers converting icons and inserting them in the list
* until all the rest of the arglist is done; this allows FG/BG
* values to be uncovered in the list for use in the pixmap.
*
* FORMAL PARAMETERS:
*
* hierarchy_id URM hierarchy from which to read public resources
* w widget to be modified
* args arglist, with literal indexes as values
* num_args # args in args
*
* IMPLICIT INPUTS:
*
* IMPLICIT OUTPUTS:
*
* FUNCTION VALUE:
*
* MrmSUCCESS operation succeeded
* MrmPARTIAL_SUCCESS at least one fetch suboperation succeeded
* other any error fatal to the operation
*
* SIDE EFFECTS:
*
*--
*/
Cardinal
UrmFetchSetValues (MrmHierarchy hierarchy_id ,
Widget w ,
ArgList args ,
Cardinal num_args )
{
/*
* Local structures
*/
typedef struct {
RGMIconImagePtr icon ; /* icon to be converted */
int pixndx ; /* argument in arglist (args) */
} _SavePixmapArg, *_SavePixmapArgPtr ;
/*
* Local variables
*/
Cardinal result ; /* function results */
int num_succ = 0; /* # of successful fetches */
int fet_fail = 0; /* # of failed fetches */
int cvt_fail = 0; /* # failed conversions */
Cardinal badfet_res = MrmNOT_FOUND; /* to save NOT_FOUND */
ArgList locargs ; /* local arglist */
Cardinal num_used = 0 ; /* # args used in arglist */
RGMResourceDescPtr resptr ; /* descriptor for literals */
int indexlen = 0 ; /* longest literal length */
URMPointerListPtr ptrlist ; /* to hold scratch contexts */
int ndx ; /* loop index */
IDBFile file_id ; /* file from which literal read */
MrmType reptype ; /* arg value representation type */
long val ; /* value as immediate or pointer */
int vec_count ; /* number of items in val if vector */
int vec_size ;
_SavePixmapArg pixargs[10] ; /* to save pixmap args */
Cardinal pixargs_cnt = 0 ; /* # pixargs saved */
_SavePixmapArgPtr savepix ; /* current saved pixmap entry */
Screen *screen ; /* screen for pixmaps */
Display *display ; /* display for pixmaps */
Pixel fgint = (Pixel) -1 ; /* fg for pixmaps. */
Pixel bgint = (Pixel) -1 ; /* background for pixmaps */
Pixmap pixmap ; /* pixmap created from icon */
Boolean swap_needed = FALSE;
/*
* Create local arglist and pointer list for contexts.
*/
locargs = (ArgList) XtMalloc (num_args*sizeof(Arg)) ;
UrmPlistInit (num_args, &ptrlist) ;
/*
* Find the longest literal index, and allocate a resource descriptor
* which can hold it. Set the fixed fields of the descriptor.
*/
for ( ndx=0 ; ndx<num_args ; ndx++ )
indexlen = MAX (indexlen, strlen((char*)args[ndx].value)) ;
/*
* Create a resource descriptor which can be reused to fetch each literal
*/
resptr = (RGMResourceDescPtr) XtMalloc (sizeof(RGMResourceDesc)+indexlen) ;
resptr->access = URMaPublic ;
resptr->type = URMrIndex ;
resptr->res_group = URMgLiteral ;
resptr->cvt_type = URMtNul ;
/*
* Loop through all the entries in the given arglist. Copy each tag into
* the local arglist. Create a new context to hold the literal, then
* try to read it from the hierarchy.
*/
for ( ndx=0 ; ndx<num_args ; ndx++ )
{
locargs[num_used].name = args[ndx].name ;
strcpy (resptr->key.index, (char*)args[ndx].value) ;
result = Urm__CW_ReadLiteral (resptr, hierarchy_id, NULL,
ptrlist, &reptype, &val, &vec_count,
&file_id, &vec_size) ;
if ( result == MrmSUCCESS )
num_succ += 1;
else
{
fet_fail += 1;
if ( result != MrmNOT_FOUND )
badfet_res = result;
continue;
}
/*
* Fix up and perform conversion on the value. If this succeeds, put it
* in the local arglist. Special casing is required for some types,
* particularly icons.
*
* Type conversion for some ASCIZ strings is also provided as a V1
* compatibility feature.
*/
switch ( reptype )
{
case MrmRtypeIconImage:
savepix = &pixargs[pixargs_cnt] ;
savepix->icon = (RGMIconImagePtr) val ;
savepix->pixndx = ndx ;
pixargs_cnt += 1 ;
continue ;
case MrmRtypeFontList:
/* Check for 1.1 version and malloc new fontlist if necessary. */
if (strcmp(file_id->db_version, URM1_1version) <= 0)
{
int count = ((OldRGMFontListPtr)val)->count;
RGMFontListPtr fontlist = (RGMFontListPtr)
XtMalloc(sizeof(RGMFontList) +
(sizeof(RGMFontItem) * (count - 1)));
result = Urm__CW_FixupValue((long)fontlist, reptype,
(XtPointer)val, file_id,
&swap_needed);
XtFree((char *)val);
val = (long)fontlist;
}
else
result = Urm__CW_FixupValue (val, reptype, (XtPointer)val,
file_id, &swap_needed) ;
default:
result =
Urm__CW_FixupValue (val, reptype, (XtPointer)val, file_id,
&swap_needed) ;
if ( result != MrmSUCCESS )
{
num_succ -= 1;
cvt_fail += 1;
continue;
}
if (XtIsWidget(w))
display = XtDisplay(w);
else
display = XtDisplay(XtParent(w));
result = Urm__CW_ConvertValue (XtParent(w), &val, reptype, (MrmType)0,
display, hierarchy_id, NULL) ;
if ( result != MrmSUCCESS )
{
num_succ -= 1;
cvt_fail += 1;
continue;
}
locargs[num_used].value = (XtArgVal)val ;
num_used += 1 ;
break ;
}
/*
* Do any processing based on specific arguments (after conversion):
* - retain FG/BG info
*/
switch ( reptype )
{
case MrmRtypeColor:
if ( strcmp(args[ndx].name,XmNforeground) == 0 )
fgint = val;
else if ( strcmp (args[ndx].name,XmNbackground) == 0 )
bgint = val;
break ;
}
} /* end loop */
/*
* Now set any pixmap arguments. This requires finding the display, screen,
* foreground, and background values for this widget. These values are
* available from the parent widget and the arglist.
*/
if ( pixargs_cnt > 0 )
{
Urm__CW_GetPixmapParms (w, &screen, &display, &fgint, &bgint) ;
for ( ndx=0,savepix=pixargs ; ndx<pixargs_cnt ; ndx++,savepix++ )
{
result = UrmCreatePixmap (savepix->icon, screen, display,
(Pixel)fgint, (Pixel)bgint, &pixmap, w) ;
if ( result != MrmSUCCESS )
{
num_succ -= 1;
cvt_fail += 1;
continue;
}
locargs[num_used].name = args[savepix->pixndx].name ;
locargs[num_used].value = (XtArgVal) pixmap ;
num_used += 1 ;
}
}
/*
* arglist creation complete. Modify the widget if we have succeeded in
* fetching any values. Deallocate resources.
*/
if ( num_used > 0 )
XtSetValues (w, locargs, num_used) ;
XtFree ((char*)locargs) ;
XtFree ((char*)resptr) ;
for ( ndx=0 ; ndx<UrmPlistNum(ptrlist) ; ndx++ )
UrmFreeResourceContext ((URMResourceContextPtr)UrmPlistPtrN(ptrlist,ndx)) ;
UrmPlistFree (ptrlist) ;
/*
* Result depends on number of successes vs. number of failurs
*/
if ( num_succ > 0 )
{
if ( fet_fail==0 && cvt_fail == 0 )
return MrmSUCCESS;
else
return MrmPARTIAL_SUCCESS;
}
if ( fet_fail > 0 )
return badfet_res;
else
return MrmFAILURE;
}