cdesktopenv/cde/programs/dtappbuilder/src/abmf/args.c

1541 lines
39 KiB
C

/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-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 libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/*
* $TOG: args.c /main/5 1999/11/04 18:05:03 mgreess $
*
* @(#)args.c 1.28 16 Feb 1994 cde_app_builder/src/abmf
*
* RESTRICTED CONFIDENTIAL INFORMATION:
*
* The information in this document is subject to special restrictions in a
* confidential disclosure agreement between HP, IBM, Sun, USL, SCO and
* Univel. Do not distribute this document outside HP, IBM, Sun, USL, SCO,
* or Univel without Sun's specific written approval. This document and all
* copies and derivative works thereof must be returned or destroyed at Sun's
* request.
*
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
*
*/
/*
* args.c - handles argument printing, et cetera
*/
#include <stdio.h>
#include <stdint.h>
#include <assert.h>
#include <Xm/Xm.h>
#include <Xm/XmStrDefs.h>
#include <Dt/SpinBox.h>
#include <Dt/Term.h>
#include <ab_private/objxm.h>
#include <ab_private/abio.h>
#include "abmfP.h"
#include "utilsP.h"
#include "instancesP.h"
#include "motifdefsP.h"
#include "obj_namesP.h"
#include "argsP.h"
#include "msg_cvt.h"
/*************************************************************************
** **
** Constants (#define and const) **
** **
**************************************************************************/
/*************************************************************************
** **
** Private Functions (C declarations and macros) **
** **
**************************************************************************/
static int abmfP_obj_spew_one_class_args(
GenCodeInfo genCodeInfo,
ABObj obj,
ABMF_ARG_CLASS argClass,
ABMF_ARG_LIST_FORMAT argFormat
);
static int spew_extra_item_strings_args(
GenCodeInfo genCodeInfo,
ABObj first_item,
int num_items,
STRING strings_res_name,
STRING strings_count_res_name
);
static int spew_extra_choice_args(
GenCodeInfo genCodeInfo,
ABObj obj,
ABMF_ARG_CLASS argClasses,
ABMF_ARG_LIST_FORMAT argFormat
);
static int spew_extra_list_args(
GenCodeInfo genCodeInfo,
ABObj obj,
ABMF_ARG_CLASS argClasses
);
static int spew_extra_spinbox_args(
GenCodeInfo genCodeInfo,
ABObj obj,
ABMF_ARG_CLASS argClasses
);
static BOOL get_wclass_and_res_value(
ABObj obj,
STRING argName,
WidgetClass *wClassOut,
XtArgVal *resValueOut
);
static BOOL arg_has_default_value(ABObj obj, STRING argName);
static STRING fmt_strval_for_res_file(STRING string);
#define safe_c_str(s) (((s) == NULL)? nullCStr:(s))
/*************************************************************************
** **
** Data **
** **
**************************************************************************/
#ifndef objxm_obj_get_num_args
#define objxm_obj_get_num_args(obj) \
(objxm_get_num_args(objxm_obj_get_ui_args(obj)))
#endif
static STRING nullCStr = "NULL";
/* typed args */
StringList typed_arg_names= NULL;
#ifdef BOGUS
/* L3 related resources of type INT */
static char *IntArray[] =
{
"x",
"y",
NULL
};
/*
* L3 related resources for all widgets Arranged in order of freq of access.
* If we switch to binary search, sort this alphabetically ...
*/
static StringList i18nl3_resources = NULL;
/*
* L3 related resources for list pane
*/
static StringList list_i18nl3_resources = NULL;
#endif /* BOGUS */
/*************************************************************************
** **
** Function Definitions **
** **
**************************************************************************/
int
abmfP_args_init(void)
{
static BOOL inited = FALSE;
ISTRING *istr_entry = NULL;
if (inited)
{
return 0;
}
inited = TRUE;
/*
* Call istr_const so that the string list will not allocate a new
* string (it is implemented using ISTRINGs).
*/
#define addit(s) (istr_const(s), strlist_add_str(typed_arg_names, (s), NULL))
typed_arg_names= strlist_create();
addit(XmNbackground);
addit(XmNfontList);
addit(XmNforeground);
addit(XmNlabelString);
strlist_shrink_mem_to_fit(typed_arg_names);
#undef addit
#ifdef BOGUS
#define addit(s) (istr_const(s), strlist_add_str(i18nl3_resources, (s), NULL))
i18nl3_resources = strlist_create();
addit(XmNlabelString);
addit(XmNtitleString);
addit(XmNstring);
strlist_shrink_mem_to_fit(i18nl3_resources);
#undef addit
#define addit(s) (istr_const(s), strlist_add_str(list_i18nl3_resources, (s), NULL))
list_i18nl3_resources = strlist_create();
addit(XmNheight);
strlist_shrink_mem_to_fit(list_i18nl3_resources);
#undef addit
#endif /* BOGUS */
return 0;
}
/*
* dump - dump to resource file
* write - write to C file
* spew = either dump or write
*/
/* INT VALUES */
#define dump_int_resource(inst,name,value) \
(wroteResource = TRUE, \
fprintf(fp,"%s.%s:\t%d\n", inst, name, (int)(intptr_t)value))
#define write_int_resource(name,value) \
(wroteResource = TRUE, abio_printf(fp,"%s, %d", name, (int)(intptr_t)(value)))
/* STRING values */
#define dump_str_resource(inst,name,value) \
wroteResource = TRUE; \
fprintf(fp,"%s.%s:", inst, name); \
strval2 = fmt_strval_for_res_file((STRING)value); \
(strval2 == NULL? fputs(nlstr,fp) :fprintf(fp, "\t%s\n", strval2)); \
if (strval2 != ((STRING)value)) {util_free(strval2)}; \
strval2 = NULL;
#define write_str_resource(name,value) \
(wroteResource = TRUE, \
abio_printf(fp, "%s, ", name), \
(value == NULL? \
abio_puts(fp, nullCStr) \
: \
abio_put_string(fp, (STRING)(value))))
/* ISTRING values */
#define dump_istr_resource(inst, name,value) \
dump_str_resource(inst, name, istr_string((ISTRING)(value)))
#define write_istr_resource(name,value) \
write_str_resource(name, istr_string((ISTRING)(value)))
/* LITERAL values (doesn't quote the value string) */
#define write_str_literal_resource(name,value) \
(wroteResource = TRUE, \
abio_printf(fp, "%s, %s", name, (STRING)(value)))
#define write_istr_literal_resource(name,value) \
write_str_literal_resource(name,istr_string((ISTRING)(value)))
/*
* Formats and writes a resource.
*
* if dumpResources is TRUE, writes the resource out in resource file format.
* Otherwise, writes it out in C format. Does not write out a newline!
*
* obj may be NULL if dumpResources is FALSE
*
* These are the values expected for the specific types of arguments:
* - AB_ARG_XMSTRING : ISTRING
* - AB_ARG_PIXEL : ISTRING
* - AB_ARG_PIXMAP : ISTRING
* - AB_ARG_LITERAL : ISTRING
* - AB_ARG_WIDGET : ISTRING (object name, *not* widget name)
*/
int
abmfP_write_arg_val(
GenCodeInfo genCodeInfo,
BOOL dumpResource, /* put in res. file format */
STRING argName,
void *argValue,
ABObj obj /* obj the arg belongs to */
)
{
ISTRING i_name = objxm_get_res_strname(argName);
STRING c_arg_name = istr_string(i_name);
AB_ARG_TYPE arg_type = AB_ARG_UNDEF;
char dumpWidgetName[MAX_NAME_SIZE];
char strval[MAX_NAME_SIZE+10];
STRING strval2 = NULL;
BOOL wroteResource= FALSE;
FILE *fp= (dumpResource?
(genCodeInfo->resource_file)
: (genCodeInfo->code_file));
*dumpWidgetName = 0;
*strval = 0;
if (fp == NULL)
{
return ERR_BAD_PARAM;
}
if (dumpResource && (obj != NULL))
{
ABObj resourceObj = obj;
if ( (util_streq(argName, XmNscrollBarDisplayPolicy))
&& (obj_is_list(obj_get_root(obj)))
&& (ObjWClassIsScrolledWindow(abmfP_parent(obj)))
)
{
/* this resource was put on the wrong widget */
resourceObj = abmfP_parent(obj);
}
util_strncpy(dumpWidgetName,
abmfP_get_widget_name_for_res_file(resourceObj),
MAX_NAME_SIZE);
}
/* These macros use formal parameters from this specific function */
arg_type = abmfP_get_res_type(argName, obj);
switch (arg_type)
{
case AB_ARG_INT:
if (dumpResource)
{
wroteResource = TRUE;
dump_int_resource(dumpWidgetName, argName, argValue);
}
else
{
if (obj_is_menu_item(obj) || obj_is_choice_item(obj))
{
}
else
{
wroteResource = TRUE;
abio_printf(fp, "%s,", c_arg_name);
abio_printf(fp, " %d", argValue);
}
}
break;
case AB_ARG_STRING:
if (dumpResource)
{
dump_str_resource(dumpWidgetName, argName, argValue);
}
else
{
/*
* We try not to call catgets() on a per-resource basis because
* it might lead to cascaded catgets() calls. However, not doing
* that means we have to be smart enough to have a local variable
* to hold the fetched string. We'll handle all those cases we
* know about explicitly, and then fall through to using catgets
* just to make sure we don't miss something. Still, we should
* try and make sure there are local variables for all string-valued
* resources...
*/
/* Local variable case #1: XmNtitle */
if (util_streq(argName, XmNtitle)
&& (abmfP_title_str_var_has_value(genCodeInfo)) )
{
write_istr_literal_resource(c_arg_name,
abmfP_title_str_var(genCodeInfo));
wroteResource= TRUE;
break;
}
/* Local variable case #2: XmNvalue (for text objects *only*) */
if (obj_is_text(obj) && util_streq(argName, XmNvalue)
&& (abmfP_value_str_var_has_value(genCodeInfo)) )
{
write_istr_literal_resource(c_arg_name,
abmfP_value_str_var(genCodeInfo));
wroteResource= TRUE;
break;
}
/* Local variable case #3: XmNiconName */
if (util_streq(argName, XmNiconName)
&& (abmfP_icon_name_str_var_has_value(genCodeInfo)) )
{
write_istr_literal_resource(c_arg_name,
abmfP_icon_name_str_var(genCodeInfo));
wroteResource= TRUE;
break;
}
/*
* TBD: Streamline this and update macros like
* write_str_resource to handle i18n transparently
*/
/* XmNaccelerator should NOT be localized. */
if (genCodeInfo->i18n_method == ABMF_I18N_XPG4_API &&
!util_streq(argName, XmNaccelerator))
{
char *prefix_fmt, *suffix;
char *str = (char *)argValue;
wroteResource = TRUE;
if (util_streq(argName, XmNtitle) ||
util_streq(argName, XmNiconName))
{
prefix_fmt = "%s, XtNewString(%s";
suffix = "))";
}
else
{
prefix_fmt = "%s, %s";
suffix = ")";
}
abio_printf(fp, prefix_fmt, c_arg_name,
abmfP_catgets_prefix_str(genCodeInfo, obj, str));
abio_put_string(fp, str);
abio_puts(fp, suffix);
}
else
{
write_str_resource(c_arg_name, argValue);
}
}
break;
case AB_ARG_VOID_PTR:
if (util_streq(argName, XmNentryClass))
{
/* widget class */
STRING wclass_name= abmfP_convert_wclass_ptr_to_name(
(WidgetClass)(argValue));
if (wclass_name != NULL)
{
if (dumpResource)
{
dump_str_resource(dumpWidgetName, argName, wclass_name);
}
else
{
write_str_literal_resource(c_arg_name, wclass_name);
}
}
}
break;
case AB_ARG_XMSTRING:
if (dumpResource)
{
dump_istr_resource(dumpWidgetName, argName, argValue);
}
else
{
if (util_streq(argName, XmNlabelString))
{
if (abmfP_label_xmstr_var_has_value(genCodeInfo))
{
write_istr_literal_resource(c_arg_name,
abmfP_label_xmstr_var(genCodeInfo));
wroteResource= TRUE;
}
else
{
if (obj_is_item(obj) &&
abmfP_label_array_var(genCodeInfo) != NULL)
{
sprintf(strval, "%s[%s]",
istr_string(abmfP_label_array_var(genCodeInfo)),
istr_string(abmfP_counter_var(genCodeInfo)));
wroteResource= TRUE;
}
}
}
else if (util_streq(argName, XmNacceleratorText))
{
if (abmfP_acceltext_xmstr_var_has_value(genCodeInfo))
{
write_istr_literal_resource(c_arg_name,
abmfP_acceltext_xmstr_var(genCodeInfo));
wroteResource = TRUE;
}
}
else if (util_streq(argName, XmNokLabelString))
{
if (abmfP_ok_label_xmstr_var_has_value(genCodeInfo))
{
write_istr_literal_resource(c_arg_name,
abmfP_ok_label_xmstr_var(genCodeInfo));
wroteResource = TRUE;
}
}
else if (util_streq(argName, XmNdirectory))
{
if (abmfP_directory_xmstr_var_has_value(genCodeInfo))
{
write_istr_literal_resource(c_arg_name,
abmfP_directory_xmstr_var(genCodeInfo));
wroteResource = TRUE;
}
}
else if (util_streq(argName, XmNpattern))
{
if (abmfP_pattern_xmstr_var_has_value(genCodeInfo))
{
write_istr_literal_resource(c_arg_name,
abmfP_pattern_xmstr_var(genCodeInfo));
wroteResource = TRUE;
}
}
if (!wroteResource)
{
if (argValue == NULL)
{
abio_printf(fp, "%s, %s,\n", c_arg_name, nullCStr);
wroteResource = TRUE;
}
else
{
sprintf(strval, "\"%s\"",
istr_string((ISTRING)(argValue)));
abio_printf(fp, "XtVaTypedArg, %s,\n", c_arg_name);
abio_indent(fp);
wroteResource = TRUE;
/*
* TBD: passing array references for items won't
* work with catgets: need to fix that
*/
/*
* TBD: Streamline this and update macros like
* write_str_resource to handle i18n transparently
*/
if (genCodeInfo->i18n_method == ABMF_I18N_XPG4_API)
{
char *unq_str_val = istr_string((ISTRING)(argValue));
char *str_catg;
str_catg = abmfP_catgets_prefix_str(genCodeInfo, obj,
unq_str_val);
abio_printf(fp, "XmRString, %s%s), strlen(%s%s))+1",
str_catg, strval, str_catg, strval);
}
else
{
abio_printf(fp, "XmRString, %s, strlen(%s)+1",
strval, strval);
}
abio_outdent(fp);
} /* !argValue == NULL */
} /* !wroteResource */
}
break;
case AB_ARG_MNEMONIC:
if (dumpResource)
{
wroteResource = TRUE;
dump_istr_resource(dumpWidgetName, argName, argValue);
}
else
{
wroteResource = TRUE;
abio_printf(fp, "%s, ", c_arg_name);
if (obj_is_item(obj) &&
abmfP_mnemonic_array_var(genCodeInfo) != NULL)
{
sprintf(strval, "%s[i]",
istr_string(abmfP_mnemonic_array_var(genCodeInfo)));
abio_printf(fp, "%s? (KeySym)XStringToKeysym(%s) : (KeySym)NULL", strval, strval);
}
else
{
sprintf(strval, "\"%s\"",
istr_string((ISTRING)(argValue)));
abio_printf(fp, "XStringToKeysym(%s)", strval);
}
}
break;
case AB_ARG_PIXEL:
if (dumpResource)
{
dump_istr_resource(dumpWidgetName, argName, argValue);
}
else
{
STRING strval= istr_string((ISTRING)(argValue));
STRING parentWidgetName =
abmfP_get_widget_parent_name(genCodeInfo, obj);
if (parentWidgetName == NULL)
{
parentWidgetName= abmfP_get_c_name(genCodeInfo, obj);
}
wroteResource= TRUE;
abio_printf(fp, "%s, dtb_cvt_string_to_pixel(%s, ",
c_arg_name, parentWidgetName);
abio_put_string(fp, strval);
abio_puts(fp, ")");
/*
abio_printf(fp, "XtVaTypedArg, %s,\n", c_arg_name);
abio_indent(fp);
abio_printf(fp, "XmRString, \"%s\", strlen(\"%s\")+1",
strval, strval);
abio_outdent(fp);
*/
}
break;
case AB_ARG_PIXMAP:
if (dumpResource)
{
}
else
{
if (util_streq(argName, XmNlabelPixmap))
{
if (abmfP_label_pixmap_var_has_value(genCodeInfo))
{
write_str_literal_resource(c_arg_name,
istr_string(abmfP_label_pixmap_var(genCodeInfo)));
}
}
else if (util_streq(argName, XmNiconPixmap))
{
if (abmfP_icon_pixmap_var_has_value(genCodeInfo))
{
write_str_literal_resource(c_arg_name,
istr_string(abmfP_icon_pixmap_var(genCodeInfo)));
}
}
else if (util_streq(argName, XmNiconMask))
{
if (abmfP_icon_mask_pixmap_var_has_value(genCodeInfo))
{
write_str_literal_resource(c_arg_name,
istr_string(abmfP_icon_mask_pixmap_var(genCodeInfo)));
}
}
}
break;
case AB_ARG_FONT:
if (dumpResource)
{
dump_str_resource(dumpWidgetName, argName, argValue);
}
else
{
wroteResource= TRUE;
abio_printf(fp, "XtVaTypedArg, %s,\n", c_arg_name);
abio_indent(fp);
abio_printf(fp, "XmRString, %s, strlen(%s)+1",
(STRING)argValue, (STRING) argValue);
abio_printf(fp, ",\n");
abio_outdent(fp);
}
break;
case AB_ARG_BOOLEAN:
if (dumpResource)
{
char *rstring = (argValue? "true" : "false");
dump_str_resource(dumpWidgetName, argName, rstring);
}
else
{
if ( obj_is_item(obj)
&& (util_streq(argName, XmNset)) )
{
/* use the "selected" local array */
wroteResource = TRUE;
if (genCodeInfo->i18n_method != ABMF_I18N_XPG4_API)
abio_printf(fp, "%s, %s[%s]", c_arg_name,
abmfP_get_c_array_of_selected_bools_name(obj),
istr_string(abmfP_counter_var(genCodeInfo)));
else
abio_printf(fp, "%s, %s", c_arg_name,
obj_is_initially_selected(obj)? "True":"False");
}
else
{
wroteResource= TRUE;
abio_printf(fp, "%s, %s", c_arg_name,
(((Boolean)(unsigned long)argValue)? "True" : "False") );
}
}
break;
case AB_ARG_LITERAL:
if (dumpResource)
{
dump_istr_resource(dumpWidgetName, argName, argValue);
}
else if (obj_is_choice_item(obj))
{
break;
}
else
{
write_istr_literal_resource(c_arg_name, argValue);
}
break;
case AB_ARG_WIDGET:
{
ABObj module= obj_get_module(obj);
ABObj attachObj= NULL;
if (module != NULL)
{
STRING attachObjName= istr_string((ISTRING)(argValue));
attachObj = obj_scoped_find_by_name(module, attachObjName);
}
assert(attachObj != NULL);
assert(!dumpResource); /* can't dump widget resources */
write_str_literal_resource(c_arg_name,
abmfP_get_c_name(genCodeInfo, attachObj));
}
break;
#ifdef DEBUG
default:
util_dprintf(0, "unknown AB_ARG_TYPE %d (argName:%s)\n",
arg_type, util_strsafe(argName));
#endif /* DEBUG */
/* break; */
}
return wroteResource? 0:-1;
}
/*
* writes out a complete resource-setting line, including
* XSetArg(..) or end of a va_list line
*/
int
abmfP_write_arg_val_line(
GenCodeInfo genCodeInfo,
BOOL dumpResource, /* put in res. file format */
STRING argName,
void *argValue,
ABObj obj, /* obj the arg belongs to */
ABMF_ARG_LIST_FORMAT argFormat
)
{
File codeFile = genCodeInfo->code_file;
if (!dumpResource)
{
switch (argFormat)
{
case ABMF_ARGFMT_ARRAY:
abio_printf(codeFile, "XtSetArg(args[%s], ",
istr_string(abmfP_arg_counter_var(genCodeInfo)));
break;
case ABMF_ARGFMT_VA_LIST:
break;
}
}
abmfP_write_arg_val(genCodeInfo, dumpResource, argName, argValue, obj);
if (!dumpResource)
{
switch (argFormat)
{
case ABMF_ARGFMT_ARRAY:
abio_printf(codeFile, "); ++%s;\n",
istr_string(abmfP_arg_counter_var(genCodeInfo)));
break;
case ABMF_ARGFMT_VA_LIST:
abio_puts(codeFile, ",\n");
break;
}
}
return 0;
}
int
abmfP_write_resource(
GenCodeInfo genCodeInfo,
BOOL dumpResource, /* put in res. file format */
Arg *arg, /* argument to format/write*/
ABObj obj /* obj the arg belongs to */
)
{
return abmfP_write_arg_val(genCodeInfo,
dumpResource, arg->name, (void *)(arg->value), obj);
}
/*
* Writes all arguments, untyped before typed
*
* Does *not* print out the i = 0 or XtVaSetValues before spewing
* the resources! This must have already been done.
*/
int
abmfP_obj_spew_args(
GenCodeInfo genCodeInfo,
ABObj obj,
ABMF_ARG_CLASS argClasses,
ABMF_ARG_LIST_FORMAT argFormat
)
{
int return_value = 0;
int iRC = 0;/* int return code */
if ((argClasses & ABMF_ARGCLASS_OTHER) != 0)
{
iRC = abmfP_obj_spew_one_class_args(genCodeInfo, obj,
ABMF_ARGCLASS_OTHER, argFormat);
return_if_err(iRC, iRC);
}
if ((argClasses & ABMF_ARGCLASS_SENSITIVITY) != 0)
{
iRC = abmfP_obj_spew_one_class_args(genCodeInfo, obj,
ABMF_ARGCLASS_SENSITIVITY, argFormat);
return_if_err(iRC, iRC);
}
if ((argClasses & ABMF_ARGCLASS_TYPED) != 0)
{
iRC = abmfP_obj_spew_one_class_args(genCodeInfo, obj,
ABMF_ARGCLASS_TYPED, argFormat);
return_if_err(iRC, iRC);
}
if ((argClasses & ABMF_ARGCLASS_WIDGET_REF) != 0)
{
iRC = abmfP_obj_spew_one_class_args(genCodeInfo, obj,
ABMF_ARGCLASS_WIDGET_REF, argFormat);
return_if_err(iRC, iRC);
}
switch (obj_get_type(obj))
{
case AB_TYPE_LIST:
spew_extra_list_args(genCodeInfo, obj, argClasses);
break;
case AB_TYPE_CHOICE:
spew_extra_choice_args(genCodeInfo, obj, argClasses, argFormat);
break;
case AB_TYPE_SPIN_BOX:
spew_extra_spinbox_args(genCodeInfo, obj, argClasses);
break;
}
epilogue:
return return_value;
}
/*
* Assumes: argClass has exactly one bit set.
*
* If arg is to be written, bug argFormat is ABMF_ARGFMT_UNDEF, the
* arg is ignored.
*/
static int
abmfP_obj_spew_one_class_args(
GenCodeInfo genCodeInfo,
ABObj obj,
ABMF_ARG_CLASS argClass,
ABMF_ARG_LIST_FORMAT argFormat
)
{
int return_value = 0;
int objCount = 0;
ABObj actualObj = obj_get_actual_obj(obj);
ArgList argList = NULL;
Arg *arg = NULL;
ABObj project = obj_get_project(obj);
ABObj menu = NULL;
for (objCount = 0; objCount < 2; ++objCount)
{
if (objCount == 0)
{
argList = objxm_obj_get_ui_args(obj);
}
else
{
if ((actualObj == NULL) || (actualObj == obj))
{
continue; /* no reference! */
}
else
{
/* we have a reference to another obj - dump its resources
* as if they were on this obj.
*/
argList = objxm_obj_get_ui_args(actualObj);
}
}
for (arg = (Arg *) argList;
(arg != NULL) && (arg->name != NULL); ++arg)
{
switch (argClass)
{
case ABMF_ARGCLASS_SENSITIVITY:
if (!abmfP_arg_is_sensitivity(arg->name))
{
continue;
}
break;
case ABMF_ARGCLASS_TYPED:
if (!abmfP_arg_is_typed(arg->name))
{
continue;
}
break;
case ABMF_ARGCLASS_WIDGET_REF:
if (!abmfP_arg_is_widget_ref(arg->name))
{
continue;
}
break;
case ABMF_ARGCLASS_OTHER:
if ( abmfP_arg_is_sensitivity(arg->name)
|| abmfP_arg_is_typed(arg->name)
|| abmfP_arg_is_widget_ref(arg->name))
{
continue;
}
break;
default:
continue;
/* break; */
}
/***** IT QUALIFIES - SPEW IT *****/
if (abmfP_arg_is_dumped(genCodeInfo, arg->name, obj))
{
abmfP_write_resource(genCodeInfo, TRUE, arg, obj);
}
else if (abmfP_arg_is_written(genCodeInfo, arg->name, obj))
{
if ( (argFormat == ABMF_ARGFMT_VA_LIST)
|| (argFormat == ABMF_ARGFMT_ARRAY) )
{
File codeFile= genCodeInfo->code_file;
if ( (!abmfP_label_pixmap_var_has_value(genCodeInfo))
&& ( (util_streq(arg->name, XmNlabelPixmap))
|| (util_streq(arg->name, XmNlabelType)) ))
{
/* Don't write label resources - a dtb_ convenience
* function will be written out that sets the label.
*/
}
else switch (argFormat)
{
case ABMF_ARGFMT_VA_LIST:
if (abmfP_write_resource(genCodeInfo, FALSE, arg, obj) >= 0)
{
abio_printf(codeFile, ",\n");
}
break;
case ABMF_ARGFMT_ARRAY:
abio_printf(codeFile, "XtSetArg(args[%s], ",
istr_string(abmfP_arg_counter_var(genCodeInfo)));
abmfP_write_resource(genCodeInfo, FALSE, arg, obj);
abio_printf(codeFile, "); ++%s;\n",
istr_string(abmfP_arg_counter_var(genCodeInfo)));
break;
}
}
} /* abmfP_arg_is_written */
} /* for arg */
} /* for objCount */
return return_value;
}
static int
spew_extra_item_strings_args(
GenCodeInfo genCodeInfo,
ABObj first_item,
int num_items,
STRING strings_res_name,
STRING strings_count_res_name
)
{
FILE *codeFile = genCodeInfo->code_file;
if (abmfP_arg_counter_var(genCodeInfo) &&
abmfP_get_c_array_of_xmstrings_name(first_item))
{
abio_printf(codeFile, "XtSetArg(args[%s], "
"%s, (XtArgVal)%s); %s++;\n",
istr_string(abmfP_arg_counter_var(genCodeInfo)),
strings_res_name,
abmfP_get_c_array_of_xmstrings_name(first_item),
istr_string(abmfP_arg_counter_var(genCodeInfo)));
abio_printf(codeFile,
"XtSetArg(args[%s], "
"%s, (XtArgVal)%d); %s++;\n",
istr_string(abmfP_arg_counter_var(genCodeInfo)),
strings_count_res_name,
num_items,
istr_string(abmfP_arg_counter_var(genCodeInfo)));
}
return 0;
}
static int
spew_extra_choice_args(
GenCodeInfo genCodeInfo,
ABObj obj,
ABMF_ARG_CLASS argClasses,
ABMF_ARG_LIST_FORMAT argFormat
)
{
int numItems = 0;
ABObj wholeObj = obj_get_root(obj);
ABObj actualObj = objxm_comp_get_subobj(wholeObj, AB_CFG_OBJECT_OBJ);
if ( (obj_get_choice_type(wholeObj) != AB_CHOICE_OPTION_MENU)
|| (actualObj != obj))
{
return 0;
}
numItems = obj_get_num_items(wholeObj);
/*
* subMenuId resource - we don't consider this a widget-ref resource
*/
if (((argClasses & ABMF_ARGCLASS_OTHER) != 0) && (numItems > 0))
{
ABObj menuObj = objxm_comp_get_subobj(wholeObj, AB_CFG_PARENT_OBJ);
/* this choice has items, which are contained in a menu pane */
if (menuObj != NULL)
{
#ifdef OBSOLETE
abio_printf(genCodeInfo->code_file, "XtSetArg(args[%s], "
"XmNsubMenuId, (XtArgVal)%s); %s++;\n",
istr_string(abmfP_arg_counter_var(genCodeInfo)),
abmfP_abmfP_get_c_name(genCodeInfo, menuObj),
istr_string(abmfP_arg_counter_var(genCodeInfo)));
#endif /* OBSOLETE */
STRING argName = XmNsubMenuId;
ISTRING objName = istr_dup(obj_get_name_istr(menuObj));
abmfP_write_arg_val_line(
genCodeInfo,
abmfP_arg_is_dumped(genCodeInfo, argName, menuObj),
argName,
objName,
menuObj,
argFormat);
istr_destroy(objName);
}
}
return 0;
}
static int
spew_extra_list_args(
GenCodeInfo genCodeInfo,
ABObj obj,
ABMF_ARG_CLASS argClasses
)
{
FILE *codeFile = genCodeInfo->code_file;
int num_items= obj_get_num_items(obj);
ABObj first_item= obj_get_item(obj, 0);
ABObj parent= abmfP_parent(obj);
ABObj actual_obj= objxm_comp_get_subobj(obj, AB_CFG_OBJECT_OBJ);
BOOL obj_is_actual_obj= (actual_obj == obj);
/*
* If the parent is not written out, we need to write it's args here
*/
if ( obj_is_actual_obj
&& (obj_get_root(obj) == obj_get_root(parent))
&& (ObjWClassIsScrolledWindow(parent))
)
{
abmfP_obj_spew_args(genCodeInfo, parent, argClasses, ABMF_ARGFMT_ARRAY);
if ((num_items > 0) && ((argClasses & ABMF_ARGCLASS_OTHER) != 0))
spew_extra_item_strings_args(genCodeInfo, first_item, num_items,
"XmNitems","XmNitemCount");
}
return 0;
}
static int
spew_extra_spinbox_args(
GenCodeInfo genCodeInfo,
ABObj obj,
ABMF_ARG_CLASS argClasses
)
{
FILE *codeFile = genCodeInfo->code_file;
int num_items= obj_get_num_items(obj);
ABObj first_item= obj_get_item(obj, 0);
if (obj == objxm_comp_get_subobj(obj, AB_CFG_OBJECT_OBJ) &&
obj_get_text_type(obj_get_root(obj)) == AB_TEXT_DEFINED_STRING)
{
if ((num_items > 0) && ((argClasses & ABMF_ARGCLASS_OTHER) != 0))
spew_extra_item_strings_args(genCodeInfo, first_item, num_items,
"DtNvalues","DtNnumValues");
}
return 0;
}
/*
* Formats a string value for a resource file.
*
* If the string is OK, returns string, otherwise, mallocs() a new
* string.
*
* Be sure to free the returned value, if it is NOT == string.
*/
static STRING
fmt_strval_for_res_file(STRING string)
{
BOOL modified = FALSE;
int i = 0;
int len = 0;
char *newStr = NULL;
int newStrI = 0;
int newStrLen = 0;
if (string == NULL)
{
return NULL;
}
len = strlen(string);
newStrLen = len;
for (i = 0; i < len; ++i)
{
if (string[i] == '\n')
{
modified = TRUE;
++newStrLen;
}
}
/*
* Duplicate it.
*/
if (!modified)
{
newStr = string;
}
else
{
if ((newStr = (STRING)util_malloc((newStrLen+1)*sizeof(char))) == NULL)
{
return NULL;
}
newStrI = 0;
for (i = 0; i < len; ++i)
{
if (string[i] == '\n')
{
newStr[newStrI++] = '\\';
newStr[newStrI++] = 'n';
}
else
{
newStr[newStrI++] = string[i];
}
}
newStr[newStrLen] = 0;
}
return newStr;
}
/*
* TRUE if the arg is dumped to the resource file, OR written to the
* C file. If this routine returns FALSE, the argument is ignored and
* not stored anywhere.
*/
BOOL
abmfP_arg_is_spewed(GenCodeInfo genCodeInfo, STRING argName, ABObj obj)
{
/*
* We set resources on items in a loop, but we don't check properly to
* see if we can remove default values. This is a bug! Unfortunately,
* we can't fix it, at this point - the easiest thing to do is to always
* generate resources for all items.
*/
return ( obj_is_item(obj)
|| (!arg_has_default_value(obj, argName)) );
}
/*
* TRUE if the arg is dumped to the resource file
*/
BOOL
abmfP_arg_is_dumped(GenCodeInfo genCodeInfo, STRING argName, ABObj obj)
{
AB_ARG_CLASS argClass = objxm_get_res_class(argName);
AB_ARG_CLASS_FLAGS argClassFlag = util_arg_class_to_flag(argClass);
/* widget-ref resources are never dumped (Xt doesn't deal with it
* There is no conversion proc for slidingMode
* There is no conversion proc for XmNtearOffModel
* There is no conversion proc for DtNarrowLayout
* There is no conversion proc for DtNspinBoxChildType
* subMenuId should probably be considered a widgetRef resource, but
* it's not, for other reasons. Nonetheless, it CANNOT go
* in the resource file!
*/
return ( ((genCodeInfo->dumped_resources & argClassFlag) != 0)
&& (!abmfP_arg_is_widget_ref(argName))
&& (!util_streq(argName, "slidingMode"))
&& (!util_streq(argName, XmNsubMenuId))
&& (!util_streq(argName, XmNtearOffModel))
&& (!util_streq(argName, DtNarrowLayout))
&& (!util_streq(argName, DtNspinBoxChildType))
&& (abmfP_arg_is_spewed(genCodeInfo, argName, obj))
);
}
/*
* TRUE if the arg is written to the C file
*/
BOOL
abmfP_arg_is_written(GenCodeInfo genCodeInfo, STRING argName, ABObj obj)
{
return ( (abmfP_arg_is_spewed(genCodeInfo, argName, obj))
&& (!abmfP_arg_is_dumped(genCodeInfo, argName, obj))
);
}
/*
* Determines whether a resource is has a widget reference for its value
*/
BOOL
abmfP_arg_is_widget_ref(STRING argName)
{
/* we don't consider subMenuId a widget-ref resource because
* it gets handled more like other resources, and doesn't affect
* layout.
*/
return
( (abmfP_get_res_type(argName, NULL) == AB_ARG_WIDGET)
&& (!util_streq(argName, XmNsubMenuId)) );
}
/*
* Determine whether a resource specifies a callback.
*/
BOOL
abmfP_arg_is_callback(STRING argName)
{
return (abmfP_get_res_type(argName, NULL) == AB_ARG_CALLBACK);
}
BOOL
abmfP_arg_is_sensitivity(STRING argName)
{
return util_streq(argName, XmNsensitive);
}
/*
* Determine if this is a typed arg
*/
BOOL
abmfP_arg_is_typed(STRING argName)
{
BOOL isIt = FALSE;
AB_ARG_TYPE arg_type = abmfP_get_res_type(argName, NULL);
switch (arg_type)
{
case AB_ARG_PIXEL:
case AB_ARG_XMSTRING:
case AB_ARG_FONT:
isIt = TRUE;
break;
}
return isIt;
}
/*
* Get the number of args to be written for this beastie
*/
int
abmfP_get_num_args_of_classes(ABObj obj, ABMF_ARG_CLASS argClasses)
{
int num_args= 0;
ABObj actualObj = obj_get_actual_obj(obj);
BOOL countSensitivity =
((argClasses & ABMF_ARGCLASS_SENSITIVITY) != 0);
BOOL countTyped= ((argClasses & ABMF_ARGCLASS_TYPED) != 0);
BOOL countWidgetRef= ((argClasses & ABMF_ARGCLASS_WIDGET_REF) != 0);
BOOL countOther= ((argClasses & ABMF_ARGCLASS_OTHER) != 0);
if (argClasses == ABMF_ARGCLASS_ALL)
{
num_args= objxm_obj_get_num_ui_args(obj);
}
else
{
Arg *arg= NULL;
for (arg= objxm_obj_get_ui_args(obj);
(arg != NULL) && (arg->name != NULL); ++arg)
{
if (countSensitivity && abmfP_arg_is_sensitivity(arg->name))
{
++num_args;
continue;
}
if (countTyped && abmfP_arg_is_typed(arg->name))
{
++num_args;
continue;
}
if (countWidgetRef && abmfP_arg_is_widget_ref(arg->name))
{
++num_args;
continue;
}
if ( countOther
&& (! ( abmfP_arg_is_sensitivity(arg->name)
|| abmfP_arg_is_typed(arg->name)
|| abmfP_arg_is_widget_ref(arg->name) )))
{
++num_args;
continue;
}
} /* for arg */
}
if (countOther && obj_is_list(obj))
{
if (obj_get_num_items(obj) > 0)
{
num_args += 2; /* itemCount, itemArray */
}
}
if (countOther && obj_is_term_pane(obj))
{
if (objxm_comp_get_subobj(obj, AB_CFG_SCROLLBAR_OBJ) != NULL)
{
++num_args;
}
}
/*
* The arguments for the obj this one references will get spit out
* as part of this obj, as well.
*/
if (actualObj != obj)
{
num_args += abmfP_get_num_args_of_classes(actualObj, argClasses);
}
return num_args;
}
/*
* If obj is NULL, returns type if arg type is the same for all objects
*/
AB_ARG_TYPE
abmfP_get_res_type(STRING res_xmname, ABObj obj)
{
AB_ARG_TYPE arg_type = objxm_get_res_type(res_xmname);
if ((arg_type != AB_ARG_VARIABLE) || (obj == NULL))
{
return arg_type;
}
/*
* The arg type may depend on the object
*/
if (util_streq(res_xmname, XmNvalue))
{
arg_type = AB_ARG_INT;
switch (obj_get_type(obj))
{
case AB_TYPE_TEXT_FIELD:
case AB_TYPE_TEXT_PANE:
arg_type = AB_ARG_STRING;
break;
}
}
return arg_type;
}
int
abmfP_xt_va_list_open(GenCodeInfo genCodeInfo)
{
abio_indent(genCodeInfo->code_file);
return 0;
}
int
abmfP_xt_va_list_open_setvalues(GenCodeInfo genCodeInfo, ABObj obj)
{
abio_printf(genCodeInfo->code_file, "XtVaSetValues(%s,\n",
abmfP_get_c_name(genCodeInfo, obj));
abio_indent(genCodeInfo->code_file);
return 0;
}
int
abmfP_xt_va_list_close(GenCodeInfo genCodeInfo)
{
abio_printf(genCodeInfo->code_file, "NULL);\n");
abio_outdent(genCodeInfo->code_file);
return 0;
}
/*************************************************************************
** **
** COMPOSITE OBJECTS **
** **
*************************************************************************/
int
abmfP_comp_get_num_args_of_classes(ABObj obj, ABMF_ARG_CLASS argClasses)
{
int num_args = 0;
AB_TRAVERSAL compTrav;
ABObj subobj = NULL;
for (trav_open(&compTrav, obj, AB_TRAV_COMP_SUBOBJS);
(subobj = trav_next(&compTrav)) != NULL; )
{
num_args += abmfP_get_num_args_of_classes(obj, argClasses);
}
trav_next(&compTrav);
return num_args;
}
static BOOL
get_wclass_and_res_value(
ABObj obj,
STRING argName,
WidgetClass *wClassOut,
XtArgVal *resValueOut
)
{
WidgetClass wClass = objxm_get_class_ptr(obj_get_class_name(obj));
Arg *arg = NULL;
BOOL foundEm = FALSE;
*wClassOut = NULL;
*resValueOut = 0;
if (wClass == NULL)
{
goto epilogue;
}
(*wClassOut) = wClass;
for (arg = objxm_obj_get_ui_args(obj);
((arg != NULL) && (arg->name != NULL)); ++arg)
{
if (util_streq(argName, arg->name))
{
(*resValueOut) = arg->value;
foundEm = TRUE;
break;
}
}
epilogue:
return foundEm? 0:-1;
}
static BOOL
arg_has_default_value(ABObj obj, STRING argName)
{
WidgetClass wClass = NULL;
XtArgVal resValue = (XtArgVal)NULL;
ABObj compRoot = obj_get_root(obj);
return FALSE;
if (get_wclass_and_res_value(obj, argName, &wClass, &resValue) < 0)
{
return FALSE;
}
/*
* REMIND: move this functionality to libABObjXm
*/
if (util_streq(argName, XmNradioBehavior))
{
if (obj_is_choice(compRoot))
{
/* return TRUE, if the boolean values are logically equal */
return (!util_xor(TRUE, obj_get_exclusive(compRoot)));
}
}
return objxm_res_value_is_default(argName, wClass, resValue);
}