cdesktopenv/cde/programs/dtappbuilder/src/libABobjXm/objxm_create.c

1094 lines
30 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
*/
/*
* $XConsortium: objxm_create.c /main/4 1995/11/06 18:45:52 rswiston $
*
* @(#)objxm_create.c 1.45 18 Jan 1994 cde_app_builder/src/libABobjXm
*
* 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.
*
*/
/*
***********************************************************************
* objxm_create.c - instantiates AB objects into motif widgets
*
*
***********************************************************************
*/
#include <stdio.h>
#include <ab_private/XmAll.h>
#include <Dt/TermPrim.h>
#include <Dt/Term.h>
#include <ab_private/trav.h>
#include "objxmP.h"
#define MAX_FORMS 24
/*************************************************************************
** **
** Private Function Declarations **
** **
**************************************************************************/
static int xm_instantiate_tree(
ABObj root,
BOOL map
);
static int xm_instantiate_obj(
ABObj obj,
BOOL map
);
static int xm_instantiate_menu(
ABObj obj,
Widget owner,
Widget parent,
BOOL submenu
);
static int post_instantiate_tree(
ABObj root,
BOOL map
);
static int post_instantiate_obj(
ABObj obj,
BOOL map
);
static Widget instantiate_widget(
ABObj obj,
Widget parent,
BOOL map
);
static int xm_map_obj(
ABObj obj
);
static int xm_unmap_obj(
ABObj obj
);
static WidgetClass
xm_get_class(
ISTRING class_name
);
static int formlist_append(
Widget newform
);
static int formlist_force_resize(
);
/*
* Event Handlers
*/
static void xm_popup_menu(
Widget w,
XtPointer client_data,
XEvent *ev,
Boolean *cont
);
/*************************************************************************
** **
** Global Data **
** **
**************************************************************************/
static Widget form_list[MAX_FORMS];
static int form_list_count = 0;
/*************************************************************************
** **
** Function Definitions **
** **
**************************************************************************/
int
objxm_fully_instantiate_tree(
ABObj root,
BOOL map
)
{
/* Instantiate all widgets
*/
xm_instantiate_tree(root, FALSE);
/* Set resources that must be set AFTER all widgets
* are instantiated.
*/
post_instantiate_tree(root, map);
/* WORKAROUND for Motif XmForm bug (it ignores child resize request
* if x,y have not also changed). So, we have to force it.
*/
formlist_force_resize();
return OK;
}
int
objxm_map_tree(
ABObj root,
BOOL map
)
{
AB_TRAVERSAL trav;
ABObj obj;
if (root == NULL)
return -1;
/*
for (trav_open(&trav, root, AB_TRAV_CHILDREN);
(obj = trav_next(&trav)) != NULL; )
objxm_map_tree(obj, map);
*/
if (map)
xm_map_obj(root);
else
xm_unmap_obj(root);
return 0;
}
static int
xm_map_obj(
ABObj obj
)
{
Widget widget;
if (!obj_has_flag(obj, InstantiatedFlag))
{
if (util_get_verbosity() > 2)
fprintf(stderr,"xm_map_obj: %s must be instantiated first\n",
obj_get_name(obj));
return -1;
}
if (!obj_has_flag(obj, MappedFlag))
{
/* If the object has an associated widget and is NOT a menu-pane,
* then Manage it...
*/
if ((widget = (Widget)obj->ui_handle) != NULL)
{
if (XtIsSubclass(widget, topLevelShellWidgetClass))
XtPopup(widget, XtGrabNone);
/* Manage everything but menushells & menupanes */
else if (!objxm_is_menu_widget(widget))
XtSetMappedWhenManaged(widget, TRUE);
}
obj_set_flag(obj, MappedFlag);
}
return 0;
}
static int
xm_unmap_obj(
ABObj obj
)
{
Widget widget;
if (obj_has_flag(obj, MappedFlag))
{
if ((widget = (Widget)obj->ui_handle) != NULL)
{
if (XtIsSubclass(widget, topLevelShellWidgetClass))
XtPopdown(widget);
else if (!objxm_is_menu_widget(widget))
XtSetMappedWhenManaged(widget, FALSE);
}
obj_clear_flag(obj, MappedFlag);
}
return 0;
}
static int
xm_instantiate_tree(
ABObj root,
BOOL map
)
{
AB_TRAVERSAL trav;
ABObj child;
if (root == NULL)
return -1;
/* Top-down traversal is crucial */
xm_instantiate_obj(root, map);
for (trav_open(&trav, root, AB_TRAV_CHILDREN);
(child = trav_next(&trav)) != NULL; )
{
xm_instantiate_tree(child, map);
}
trav_close(&trav);
return 0;
}
static int
post_instantiate_tree(
ABObj root,
BOOL map
)
{
AB_TRAVERSAL trav;
ABObj child;
if (root == NULL)
return -1;
/* Bottom-up traversal is crucial*/
for (trav_open(&trav, root, AB_TRAV_UI);
(child = trav_next(&trav)) != NULL; )
post_instantiate_obj(child, map);
trav_close(&trav);
return 0;
}
static int
xm_instantiate_obj(
ABObj obj,
BOOL map
)
{
ABObj parentobj;
Widget widget;
Widget parent;
if (!obj_has_flag(obj, XmConfiguredFlag) ||
obj_has_flag(obj, InstantiatedFlag) ||
obj_has_flag(obj, BeingDestroyedFlag))
return OK; /* not considered an error */
if (obj_is_menu_ref(obj))
return OK;
if (obj_is_virtual(obj))
{
obj_set_flag(obj, InstantiatedFlag);
if (map)
xm_map_obj(obj);
return OK;
}
/* List Items are not separate widgets */
if (obj_is_item(obj) && obj->info.item.type == AB_ITEM_FOR_LIST)
{
XmString xmitem;
if ((parent = (Widget)(obj_get_parent(obj)->ui_handle)) != NULL)
{
xmitem = XmStringCreateLocalized(obj_get_label(obj));
XmListAddItem(parent, xmitem, 0);
XmStringFree(xmitem);
obj_set_flag(obj, InstantiatedFlag);
if (map)
xm_map_obj(obj);
return OK;
}
else
return ERROR;
}
/* Determine parent.. */
/* If obj is a window, parent it off the AB toplevel during
* build-mode to ensure it's independence during UI editing
*/
if (obj_is_window(obj))
parent = Objxm_toplevel;
else
{
parentobj = obj_get_parent(obj);
while (obj_is_virtual(parentobj))
parentobj = obj_get_parent(parentobj);
parent = (Widget)parentobj->ui_handle;
}
if (parent == NULL)
{
if (util_get_verbosity() > 2)
fprintf(stderr,"xm_instantiate_obj: %s: ui_handle for parent is NULL\n",
istr_string_safe(obj->name));
return ERROR;
}
widget = instantiate_widget(obj, parent, map);
if (widget != NULL)
{
/* If we have an OptionMenu menupane, we need to hook it
* up to the XmOptionMenu (XmRowColumn) in time for the
* XmOptionMenu's instantiation...ugly, but haven't found
* a better place to do this yet...
*/
if (objxm_is_menu_widget(widget) &&
XtIsSubclass(widget, xmRowColumnWidgetClass))
{
ABObj robj = obj_get_comp_rootobj(obj);
if (obj_is_choice(robj))
{
ABObj o_obj = objxm_get_config_obj(robj, AB_CFG_OBJECT_OBJ);
objxm_set_ui_arg(o_obj, AB_ARG_WIDGET, XmNsubMenuId, widget);
}
}
/* if widget is being replaced, destroy old one */
if (obj->ui_handle != NULL)
objxm_uninstantiate_tree(obj, TRUE);
/* obj & widget point to each other...*/
XtVaSetValues(widget, XmNuserData, obj, NULL);
obj->ui_handle = (void*)widget;
objxm_remove_all_ui_args(obj);
obj_set_flag(obj, InstantiatedFlag);
obj_clear_flag(obj, AttrChangedFlag);
return OK;
}
return ERROR;
}
int
objxm_instantiate_menus(
ABObj root
)
{
AB_TRAVERSAL trav;
ABObj obj;
ABObj m_parent;
if (root == NULL)
return -1;
for (trav_open(&trav, root, AB_TRAV_UI);
(obj = trav_next(&trav)) != NULL; )
/* Instantiate a menu for the object if one exists.
* NOTE: SubMenus (menus off of other menu-items) are
* actually instantiated using recursion in xm_instantiate_menu(),
* thus we do not call xm_instantiate_menu() for them directly.
*/
if (obj_is_salient(obj) &&
obj_get_menu_name(obj) != NULL && !obj_is_menu_item(obj))
{
m_parent = objxm_get_config_obj(obj, AB_CFG_MENU_PARENT_OBJ);
xm_instantiate_menu(obj, (Widget)obj->ui_handle,
(Widget)m_parent->ui_handle, FALSE);
}
trav_close(&trav);
return 0;
}
/*
* Since we support the concept of virtual "Sharable" menus (the same Menu
* object can be attached to multiple objects) and Motif does NOT, we must
* use special handling when instantiating menus. Although the virtual or
* "shared" Menu obj is used to determine the structure of the menu, the actual
* widget ID of the menu is stored in the Menu-Reference obj attached directly
* to the object which "owns" a copy of the menu.
*
* Both "owner" & "parent" are required because for casacdes, Motif requires a
* menu to be parented off the *parent* of the cascade...
*
* NOTE: for menus containing cascading sub-menus, ONLY the TOP-MOST
* menu is stored in the Menu-Reference obj.
*/
static int
xm_instantiate_menu(
ABObj obj,
Widget owner,
Widget parent,
BOOL submenu
)
{
AB_TRAVERSAL trav;
AB_MENU_TYPE m_type;
ABObj menu_ref;
ABObj menu;
ABObj item;
Widget menu_w;
Widget item_w;
if ((menu_ref = objxm_get_config_obj(obj, AB_CFG_MENU_OBJ)) != NULL)
{
/* Get Virtual Menu & object to parent menu off of */
menu = obj_get_ref_menu(menu_ref);
if (menu != NULL && parent != NULL)
{
/* Set Pseudo-class for Menu based on the type
* of object that owns it
*/
if (obj_is_item(obj) &&
(obj->info.item.type == AB_ITEM_FOR_MENU ||
obj->info.item.type == AB_ITEM_FOR_MENUBAR))
{
m_type = AB_MENU_PULLDOWN;
obj_set_class_name(menu, _xmPulldownMenu);
}
else
{
m_type = AB_MENU_POPUP;
obj_set_class_name(menu, _xmPopupMenu);
}
menu_w = instantiate_widget(menu, parent, TRUE);
if (m_type == AB_MENU_PULLDOWN)
XtVaSetValues(owner, XmNsubMenuId, menu_w, NULL);
else /* PopupMenu */
XtAddEventHandler(parent, ButtonPressMask, False, xm_popup_menu, obj);
/* Instantiate Menu Items */
for (trav_open(&trav, menu, AB_TRAV_CHILDREN);
(item = trav_next(&trav)) != NULL; )
{
item_w = instantiate_widget(item, menu_w, TRUE);
/* If SubMenu exists, instantiate it */
if (obj_get_menu_name(item) != NULL)
xm_instantiate_menu(item, item_w, menu_w, TRUE);
}
trav_close(&trav);
/* ONLY store widget-ids for top-most menus */
if (!submenu)
menu_ref->ui_handle = (void*)menu_w;
}
else
{
if (util_get_verbosity() > 2)
fprintf(stderr,"xm_instantiate_menu: could not instantiate menu for %s\n",
istr_string_safe(obj->name));
return -1;
}
}
return 0;
}
int
objxm_destroy_menus(
ABObj root
)
{
AB_TRAVERSAL trav;
ABObj obj;
ABObj menu;
AB_MENU_TYPE m_type;
ABObj menu_ref;
ABObj menu_p;
if (root == NULL)
return -1;
for (trav_open(&trav, root, AB_TRAV_UI);
(obj = trav_next(&trav)) != NULL; )
if (obj_is_salient(obj) && !obj_is_menu_item(obj) &&
(menu_ref = objxm_get_config_obj(obj, AB_CFG_MENU_OBJ)) != NULL)
{
if (menu_ref->ui_handle != NULL)
{
menu = obj_get_ref_menu(menu_ref);
if (obj_is_item(obj) &&
(obj->info.item.type == AB_ITEM_FOR_MENU ||
obj->info.item.type == AB_ITEM_FOR_MENUBAR))
m_type = AB_MENU_PULLDOWN;
else
m_type = AB_MENU_POPUP;
if (m_type == AB_MENU_POPUP) /* Remove EventHandler that pops up menu */
{
menu_p = objxm_get_config_obj(obj, AB_CFG_MENU_PARENT_OBJ);
XtRemoveEventHandler((Widget)menu_p->ui_handle, ButtonPressMask,
False, xm_popup_menu, obj);
}
/*
fprintf(stderr,"DESTROY_MENU: %s\n", XtName(menu_ref->ui_handle));
*/
XtDestroyWidget((Widget)menu_ref->ui_handle);
menu_ref->ui_handle = (void*)NULL;
}
}
trav_close(&trav);
return 0;
}
static Widget
instantiate_widget(
ABObj obj,
Widget parent,
BOOL map
)
{
Widget widget = NULL;
WidgetClass xmclass;
XmCreateFunc xmcreate_func;
STRING classname;
String name;
int num_args;
ArgList all_args = NULL;
name = (String)obj_get_name(obj);
if (name == NULL)
{
if (util_get_verbosity() > 2)
fprintf(stderr,"instantiate_widget: object must have name\n");
return NULL;
}
if ((classname = obj_get_class_name(obj)) == NULL)
{
classname = objxm_get_default_motif_class(obj);
obj_set_class_name(obj, classname);
}
if (obj->ui_args == NULL) /* Make sure Resources are set */
objxm_set_obj_ui_args(obj, OBJXM_CONFIG_BUILD, TRUE);
/* Instantiate Widget using class & arglist
*/
if (istr_equal(obj->class_name, istr_const(_topLevelShell)))
{
all_args = objxmP_merge_arglists((ArgList)obj->ui_args,
objxm_get_num_args((ArgList)obj->ui_args),
(ArgList)obj->tk_args,
objxm_get_num_args((ArgList)obj->tk_args));
num_args = objxm_get_num_args(all_args);
widget = XtCreatePopupShell(name,
topLevelShellWidgetClass,
parent,
all_args,
num_args);
}
else /* Non TopLevel */
{
objxm_set_ui_arg(obj, AB_ARG_BOOLEAN, XtNmappedWhenManaged, map);
all_args = objxmP_merge_arglists((Arg *)obj->ui_args,
objxm_get_num_args((Arg *)obj->ui_args),
(Arg *)obj->tk_args,
objxm_get_num_args((Arg *)obj->tk_args));
num_args = objxm_get_num_args(all_args);
/*
fprintf(stderr,"INSTANTIATING: %s part_of(%s), class=%s\n", name,
obj->part_of? istr_string_safe(obj->part_of->name) : "null",obj_get_class_name(obj));
objxm_dump_arglist(obj, all_args, num_args);
*/
xmcreate_func = objxm_get_xmcreate_func(obj);
if (xmcreate_func != NULL)
widget = (*xmcreate_func)(parent, name, all_args, num_args);
else
{
xmclass = (WidgetClass)xm_get_class(obj->class_name);
widget = XtCreateWidget(name, xmclass, parent, all_args, num_args);
}
if (!objxm_is_menu_widget(widget))
XtManageChild(widget);
}
XtFree((char *)all_args);
return widget;
}
static int
post_instantiate_obj(
ABObj obj,
BOOL map
)
{
Widget widget;
ABObj parent_obj;
ArgList args;
int num_args;
Dimension w,h;
widget = (Widget)obj->ui_handle;
if (widget == NULL)
return 0;
if (obj_is_salient(obj))
objxmP_type_post_instantiate(obj);
if (obj->attachments != NULL)
objxm_set_attachment_args(obj);
if (!obj_is_window(obj))
{
parent_obj = obj_get_parent(obj);
if (XtIsSubclass((Widget)parent_obj->ui_handle, xmFormWidgetClass))
formlist_append((Widget)parent_obj->ui_handle);
}
if (obj_has_flag(obj,AttrChangedFlag))
{
args = (ArgList)obj->ui_args;
num_args = objxm_get_num_args(args);
/*
fprintf(stderr,"(PI) CHANGE_ATTRS: %s\n", istr_string_safe(obj->name));
objxm_dump_arglist(obj, args, num_args);
*/
XtSetValues(widget, args, num_args);
obj_clear_flag(obj, AttrChangedFlag);
objxm_remove_all_ui_args(obj);
}
if (map)
xm_map_obj(obj);
return 0;
}
int
objxmP_destroy(
ObjEvDestroyInfo info
)
{
Widget widget = (Widget)info->obj->ui_handle;
if (widget != NULL)
{
/*
fprintf(stderr,"DESTROY: %s\n", istr_string_safe(info->obj->name));
*/
XtDestroyWidget(widget);
info->obj->ui_handle = NULL;
}
return 0;
}
int
objxm_destroy_tree(
ABObj root
)
{
if (root == NULL)
return -1;
/* Destroy any existing widgets */
objxm_uninstantiate_tree(root, TRUE);
/* Destroy ABObj tree */
obj_destroy(root);
return 0;
}
int
objxm_uninstantiate_tree(
ABObj root,
BOOL topmost
)
{
AB_TRAVERSAL trav;
ABObj child;
if (root == NULL || root->ui_handle == NULL)
return -1;
if (topmost)
{
/*
fprintf(stderr,"DESTROY2: %s\n", istr_string_safe(root->name));
*/
XtDestroyWidget((Widget)root->ui_handle);
}
for (trav_open(&trav, root, AB_TRAV_CHILDREN);
(child = trav_next(&trav)) != NULL; )
{
objxm_uninstantiate_tree(child, FALSE);
}
root->ui_handle = NULL;
obj_clear_flag(root, InstantiatedFlag);
obj_clear_flag(root, MappedFlag);
trav_close(&trav);
return OK;
}
static WidgetClass
xm_get_class(
ISTRING class_name
)
{
WidgetClass wclass;
/* REMIND: aim,8/25/93 - change to a switch statement? */
if (istr_equal(class_name, istr_const(_topLevelShell)))
wclass = topLevelShellWidgetClass;
else if (istr_equal(class_name, istr_const(_dtTerm)))
wclass = dtTermWidgetClass;
else if (istr_equal(class_name, istr_const(_xmArrowButton)))
wclass = xmArrowButtonWidgetClass;
else if (istr_equal(class_name, istr_const(_xmBulletinBoard)))
wclass = xmBulletinBoardWidgetClass;
else if (istr_equal(class_name, istr_const(_xmCascadeButton)))
wclass = xmCascadeButtonWidgetClass;
else if (istr_equal(class_name, istr_const(_xmCommand)))
wclass = xmCommandWidgetClass;
else if (istr_equal(class_name, istr_const(_xmDialogShell)))
wclass = xmDialogShellWidgetClass;
else if (istr_equal(class_name, istr_const(_xmDrawingArea)))
wclass = xmDrawingAreaWidgetClass;
else if (istr_equal(class_name, istr_const(_xmDrawnButton)))
wclass = xmDrawnButtonWidgetClass;
else if (istr_equal(class_name, istr_const(_xmFileSelectionBox)))
wclass = xmFileSelectionBoxWidgetClass;
else if (istr_equal(class_name, istr_const(_xmForm)))
wclass = xmFormWidgetClass;
else if (istr_equal(class_name, istr_const(_xmFrame)))
wclass = xmFrameWidgetClass;
else if (istr_equal(class_name, istr_const(_xmLabel)))
wclass = xmLabelWidgetClass;
else if (istr_equal(class_name, istr_const(_xmLabelGadget)))
wclass = xmLabelGadgetClass;
else if (istr_equal(class_name, istr_const(_xmList)))
wclass = xmListWidgetClass;
else if (istr_equal(class_name, istr_const(_xmMainWindow)))
wclass = xmMainWindowWidgetClass;
else if (istr_equal(class_name, istr_const(_xmManager)))
wclass = xmManagerWidgetClass;
else if (istr_equal(class_name, istr_const(_xmMenuShell)))
wclass = xmMenuShellWidgetClass;
else if (istr_equal(class_name, istr_const(_xmMessageBox)))
wclass = xmMessageBoxWidgetClass;
else if (istr_equal(class_name, istr_const(_xmPanedWindow)))
wclass = xmPanedWindowWidgetClass;
else if (istr_equal(class_name, istr_const(_xmPopupMenu)))
wclass = xmMenuShellWidgetClass;
else if (istr_equal(class_name, istr_const(_xmPrimitive)))
wclass = xmPrimitiveWidgetClass;
else if (istr_equal(class_name, istr_const(_xmPulldownMenu)))
wclass = xmMenuShellWidgetClass;
else if (istr_equal(class_name, istr_const(_xmPushButton)))
wclass = xmPushButtonWidgetClass;
else if (istr_equal(class_name, istr_const(_xmRowColumn)))
wclass = xmRowColumnWidgetClass;
else if (istr_equal(class_name, istr_const(_xmScale)))
wclass = xmScaleWidgetClass;
else if (istr_equal(class_name, istr_const(_xmScrollBar)))
wclass = xmScrollBarWidgetClass;
else if (istr_equal(class_name, istr_const(_xmScrolledWindow)))
wclass = xmScrolledWindowWidgetClass;
else if (istr_equal(class_name, istr_const(_xmSelectionBox)))
wclass = xmSelectionBoxWidgetClass;
else if (istr_equal(class_name, istr_const(_xmSeparator)))
wclass = xmSeparatorWidgetClass;
else if (istr_equal(class_name, istr_const(_xmSeparatorGadget)))
wclass = xmSeparatorGadgetClass;
else if (istr_equal(class_name, istr_const(_xmText)))
wclass = xmTextWidgetClass;
else if (istr_equal(class_name, istr_const(_xmTextField)))
wclass = xmTextFieldWidgetClass;
else if (istr_equal(class_name, istr_const(_xmToggleButton)))
wclass = xmToggleButtonWidgetClass;
else if (istr_equal(class_name, istr_const(_xmToggleButtonGadget)))
wclass = xmToggleButtonGadgetClass;
else /* Unknown Widget class */
wclass = NULL;
return(wclass);
}
XmCreateFunc
objxm_get_xmcreate_func(
ABObj obj
)
{
ABObj robj = obj_get_comp_rootobj(obj);
ISTRING class_name = obj->class_name;
XmCreateFunc xmcreate_func;
if (class_name == NULL)
return NULL;
/* REMIND: aim,8/25/93 - change to a switch statement? */
if (istr_equal(class_name, istr_const(_xmArrowButton)))
xmcreate_func = XmCreateArrowButton;
else if (istr_equal(class_name, istr_const(_xmBulletinBoard)))
xmcreate_func = XmCreateBulletinBoard;
else if (istr_equal(class_name, istr_const(_xmCascadeButton)))
xmcreate_func = XmCreateCascadeButton;
else if (istr_equal(class_name, istr_const(_xmCommand)))
xmcreate_func = XmCreateCommand;
else if (istr_equal(class_name, istr_const(_xmDialogShell)))
xmcreate_func = XmCreateDialogShell;
else if (istr_equal(class_name, istr_const(_xmDrawingArea)))
xmcreate_func = XmCreateDrawingArea;
else if (istr_equal(class_name, istr_const(_xmDrawnButton)))
xmcreate_func = XmCreateDrawnButton;
else if (istr_equal(class_name, istr_const(_xmFileSelectionBox)))
xmcreate_func = XmCreateFileSelectionBox;
else if (istr_equal(class_name, istr_const(_xmForm)))
xmcreate_func = XmCreateForm;
else if (istr_equal(class_name, istr_const(_xmFrame)))
xmcreate_func = XmCreateFrame;
else if (istr_equal(class_name, istr_const(_xmLabel)))
xmcreate_func = XmCreateLabel;
else if (istr_equal(class_name, istr_const(_xmLabelGadget)))
xmcreate_func = XmCreateLabelGadget;
else if (istr_equal(class_name, istr_const(_xmList)))
xmcreate_func = XmCreateList;
else if (istr_equal(class_name, istr_const(_xmMainWindow)))
xmcreate_func = XmCreateMainWindow;
else if (istr_equal(class_name, istr_const(_xmMenuShell)))
xmcreate_func = XmCreateMenuShell;
else if (istr_equal(class_name, istr_const(_xmMessageBox)))
{
AB_COMPOUND_INFO *info = (AB_COMPOUND_INFO*)&(obj->info.compound);
switch(info->type)
{
case AB_COMP_INFO_BOX:
xmcreate_func = XmCreateInformationDialog;
break;
case AB_COMP_ERROR_BOX:
xmcreate_func = XmCreateErrorDialog;
break;
case AB_COMP_QUESTION_BOX:
xmcreate_func = XmCreateQuestionDialog;
break;
case AB_COMP_TEMPLATE_BOX:
xmcreate_func = XmCreateTemplateDialog;
break;
case AB_COMP_WARNING_BOX:
xmcreate_func = XmCreateWarningDialog;
break;
case AB_COMP_WORKING_BOX:
xmcreate_func = XmCreateWorkingDialog;
break;
case AB_COMP_MESSAGE_BOX:
xmcreate_func = XmCreateMessageDialog;
break;
default:
xmcreate_func = XmCreateMessageBox;
}
}
else if (istr_equal(class_name, istr_const(_xmPanedWindow)))
xmcreate_func = XmCreatePanedWindow;
else if (istr_equal(class_name, istr_const(_xmPopupMenu)))
xmcreate_func = XmCreatePopupMenu;
else if (istr_equal(class_name, istr_const(_xmPulldownMenu)))
xmcreate_func = XmCreatePulldownMenu;
else if (istr_equal(class_name, istr_const(_xmPushButton)))
xmcreate_func = XmCreatePushButton;
else if (istr_equal(class_name, istr_const(_xmRowColumn)))
{
if (obj_is_menubar(obj))
xmcreate_func = XmCreateMenuBar;
else if (obj_is_choice(obj))
{
AB_CHOICE_INFO *info = (AB_CHOICE_INFO *)&(robj->info.choice);
if (objxm_get_config_obj(robj, AB_CFG_OBJECT_OBJ) == obj)
{
switch(info->type)
{
case AB_CHOICE_EXCLUSIVE:
xmcreate_func = XmCreateRadioBox;
break;
case AB_CHOICE_NONEXCLUSIVE:
xmcreate_func = XmCreateSimpleCheckBox;
break;
case AB_CHOICE_OPTION_MENU:
xmcreate_func = XmCreateOptionMenu;
break;
default:
xmcreate_func = XmCreateRowColumn;
}
}
else
xmcreate_func = XmCreateRowColumn;
}
else
xmcreate_func = XmCreateRowColumn;
}
else if (istr_equal(class_name, istr_const(_xmScale)))
xmcreate_func = XmCreateScale;
else if (istr_equal(class_name, istr_const(_xmScrollBar)))
xmcreate_func = XmCreateScrollBar;
else if (istr_equal(class_name, istr_const(_xmScrolledList)))
xmcreate_func = XmCreateScrolledList;
else if (istr_equal(class_name, istr_const(_xmScrolledWindow)))
xmcreate_func = XmCreateScrolledWindow;
else if (istr_equal(class_name, istr_const(_xmSelectionBox)))
xmcreate_func = XmCreateSelectionBox;
else if (istr_equal(class_name, istr_const(_xmSeparator)))
xmcreate_func = XmCreateSeparator;
else if (istr_equal(class_name, istr_const(_xmSeparatorGadget)))
xmcreate_func = XmCreateSeparatorGadget;
else if (istr_equal(class_name, istr_const(_xmText)))
xmcreate_func = XmCreateText;
else if (istr_equal(class_name, istr_const(_xmTextField)))
xmcreate_func = XmCreateTextField;
else if (istr_equal(class_name, istr_const(_xmToggleButton)))
xmcreate_func = XmCreateToggleButton;
else if (istr_equal(class_name, istr_const(_xmToggleButtonGadget)))
xmcreate_func = XmCreateToggleButtonGadget;
else /* Unknown Widget class */
xmcreate_func = NULL;
return(xmcreate_func);
}
/*
* Store widget-id of XmForm widget which contains children
* which have changed size
*/
static int
formlist_append(
Widget newform
)
{
int iRet = 0;
int i;
/* If form is already on list, return */
for (i=0; i < form_list_count; i++)
if (form_list[i] == newform)
return iRet;
if (form_list_count < MAX_FORMS)
form_list[form_list_count++] = newform;
else
{
if (util_get_verbosity() > 0)
fprintf(stderr,"formlist_append: form_list FULL\n");
iRet = -1;
}
return iRet;
}
/*
* For each XmForm on the form_list, force it to grant it's
* children's resize requests by 'faking' a geometry change
* on the XmForm itself.
*
* Yes, this is ugly, but is currently the only workaround
* for the Motif bug where the XmForm refuses childrens'
* resize requests after they've been already managed.
*/
static int
formlist_force_resize(
)
{
Dimension f_width, f_height;
int i;
for (i= form_list_count-1; i >= 0; i--)
{
/* UGLY! */
XtVaGetValues(form_list[i], XmNwidth, &f_width, XmNheight, &f_height, NULL);
XtVaSetValues(form_list[i], XmNwidth, f_width+1,XmNheight, f_height+1,NULL);
XtVaSetValues(form_list[i], XmNwidth, f_width, XmNheight, f_height, NULL);
form_list[i] = NULL;
}
form_list_count = 0;
return 0;
}
static void
xm_popup_menu(
Widget widget,
XtPointer client_data,
XEvent *event,
Boolean *cont
)
{
XButtonEvent *bevent = (XButtonEvent*)event;
ABObj obj = (ABObj)client_data;
ABObj menu_ref;
Widget menu;
if (bevent->button == 3)
{
menu_ref = objxm_get_config_obj(obj, AB_CFG_MENU_OBJ);
if (menu_ref != NULL && (menu = (Widget)menu_ref->ui_handle) != NULL)
{
XmMenuPosition(menu, (XButtonPressedEvent*)bevent);
XtManageChild(menu);
}
}
}