v08i034: wcl - Widget Creation Library, Part04/06

David E. Smyth david at devvax.Jpl.Nasa.Gov
Fri Jul 6 17:40:54 AEST 1990


Submitted-by: david at devvax.Jpl.Nasa.Gov (David E. Smyth)
Posting-number: Volume 8, Issue 34
Archive-name: wcl/part04

# to unbundle, "sh" this file -- DO NOT use csh
#  SHAR archive format.  Archive created Tue Jul 3 16:49:19 PDT 1990
echo x - WcActions.c
sed 's/^X//' > WcActions.c <<'+FUNKY+STUFF+'
X/*
X** Copyright (c) 1990 Rodney J. Whitby
X**
X** This file was derived from work performed by David E. Smyth under the
X** following copyright:
X**
X*******************************************************************************
X** Copyright (c) 1990 David E. Smyth
X**
X** This file was derived from work performed by Martin Brunecky at
X** Auto-trol Technology Corporation, Denver, Colorado, under the
X** following copyright:
X**
X*******************************************************************************
X* Copyright 1990 by Auto-trol Technology Corporation, Denver, Colorado.
X*
X*                        All Rights Reserved
X*
X* Permission to use, copy, modify, and distribute this software and its
X* documentation for any purpose and without fee is hereby granted, provided
X* that the above copyright notice appears on all copies and that both the
X* copyright and this permission notice appear in supporting documentation
X* and that the name of Auto-trol not be used in advertising or publicity
X* pertaining to distribution of the software without specific, prior written
X* permission.
X*
X* Auto-trol disclaims all warranties with regard to this software, including
X* all implied warranties of merchantability and fitness, in no event shall
X* Auto-trol be liable for any special, indirect or consequential damages or
X* any damages whatsoever resulting from loss of use, data or profits, whether
X* in an action of contract, negligence or other tortious action, arising out
X* of or in connection with the use or performance of this software.
X*******************************************************************************
X**
X** Redistribution and use in source and binary forms are permitted
X** provided that the above copyright notice and this paragraph are
X** duplicated in all such forms and that any documentation, advertising
X** materials, and other materials related to such distribution and use
X** acknowledge that the software was developed by David E. Smyth.  The
X** name of David E. Smyth may not be used to endorse or promote products
X** derived from this software without specific prior written permission.
X** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
X** WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
X** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X**
X*/
X
X/*
X* SCCS_data: @(#)WcActions.c 1.0 ( 30 June 1990 )
X*
X* Subsystem_group:
X*
X*     Widget Creation Library
X*
X* Module_description:
X*
X*     This module contains the convenience actions used to create and 
X*     manage a widget tree using the Xrm databse.
X*
X*     Several convenience actions are provided with the package, allowing 
X*     deferred widget creation, control (manage/unmanage) and other utility
X*     functions.
X*
X* Module_interface_summary: 
X*
X*     Convenience Actions:
X*
X* Module_history:
X*                                                  
X*   All actions and the action registration routine were made by
X*   Rod Whitby following about 30 June 1990.
X*
X* Design_notes:
X*
X*******************************************************************************
X*/
X/*
X*******************************************************************************
X* Include_files.
X*******************************************************************************
X*/
X
X#include "WidgetCreate.h"
X#include "WidgetCreateP.h"
X
X/*
X*******************************************************************************
X* Private_type_declarations.
X*******************************************************************************
X*/
X
X/*
X*******************************************************************************
X* Private_macro_definitions.
X*******************************************************************************
X*/
X
X/*
X*******************************************************************************
X* Private_data_definitions.
X*******************************************************************************
X*/
X
X/*
X*******************************************************************************
X* Private_function_declarations.
X*******************************************************************************
X*/
X
X/*
X*******************************************************************************
X* Public_action_function_declarations.
X*******************************************************************************
X*/
X
X/*
X    -- Create Deferred Children from Xrm Database
X*******************************************************************************
X*/
Xvoid	WcCreateChildrenACT( w, event, params, num_params )
XWidget	    w;
XXEvent	   *event;
XString	   *params;
XCardinal   *num_params;
X{
X  char *data;
X  int	i;
X
X  if (*num_params < 2) {
X    WcCreateChildrenCB(w, "", NULL);
X    return;
X  }
X
X  for (i = 1; i < *num_params; i++) {
X    data = XtMalloc(strlen(params[0]) + strlen(params[i]) + 2);
X    (void)strcpy(data, params[0]);
X    (void)strcat(data, ",");
X    (void)strcat(data, params[i]);
X    WcCreateChildrenCB(w, data, NULL);
X    XtFree(data);
X  }
X}
X
X
X/*
X    -- Manage or Unmanage named widget(s)
X*******************************************************************************
X*/
Xvoid	WcManageACT( w, event, params, num_params )
XWidget	    w;
XXEvent	   *event;
XString	   *params;
XCardinal   *num_params;
X{
X  int	i;
X
X  if (*num_params < 1) {
X    WcManageCB(w, "", NULL);
X    return;
X  }
X
X  for (i = 0; i < *num_params; i++) {
X    WcManageCB(w, params[i], NULL);
X  }
X}
X
X
Xvoid	WcUnmanageACT( w, event, params, num_params )
XWidget	    w;
XXEvent	   *event;
XString	   *params;
XCardinal   *num_params;
X{
X  int	i;
X
X  if (*num_params < 1) {
X    WcUnmanageCB(w, "", NULL);
X    return;
X  }
X
X  for (i = 0; i < *num_params; i++) {
X    WcUnmanageCB(w, params[i], NULL);
X  }
X}
X
X
X/*
X    -- Manage or unamange named children action
X*******************************************************************************
X*/
Xvoid	WcManageChildrenACT( w, event, params, num_params )
XWidget	    w;
XXEvent	   *event;
XString	   *params;
XCardinal   *num_params;
X{
X  int	i;
X
X  char *data;
X
X  if (*num_params < 2) {
X    WcManageChildrenCB(w, "", NULL);
X    return;
X  }
X
X  for (i = 1; i < *num_params; i++) {
X    data = XtMalloc(strlen(params[0]) + strlen(params[i]) + 2);
X    (void)strcpy(data, params[0]);
X    (void)strcat(data, ",");
X    (void)strcat(data, params[i]);
X    WcManageChildrenCB(w, data, NULL);
X    XtFree(data);
X  }
X}
X
X
Xvoid	WcUnmanageChildrenACT( w, event, params, num_params )
XWidget	    w;
XXEvent	   *event;
XString	   *params;
XCardinal   *num_params;
X{
X  int	i;
X
X  char *data;
X
X  if (*num_params < 2) {
X    WcUnmanageChildrenCB(w, "", NULL);
X    return;
X  }
X
X  for (i = 1; i < *num_params; i++) {
X    data = XtMalloc(strlen(params[0]) + strlen(params[i]) + 2);
X    (void)strcpy(data, params[0]);
X    (void)strcat(data, ",");
X    (void)strcat(data, params[i]);
X    WcUnmanageChildrenCB(w, data, NULL);
X    XtFree(data);
X  }
X}
X
X
X/*
X    -- Destroy named children action
X*******************************************************************************
X*/
Xvoid	WcDestroyACT( w, event, params, num_params )
XWidget	    w;
XXEvent	   *event;
XString	   *params;
XCardinal   *num_params;
X{
X  int	i;
X
X  if (*num_params < 1) {
X    WcDestroyCB(w, "", NULL);
X    return;
X  }
X
X  for (i = 0; i < *num_params; i++) {
X    WcDestroyCB(w, params[i], NULL);
X  }
X}
X
X
X/*
X   -- Set Resource Value on Widget
X*******************************************************************************
X*/
Xvoid	WcSetValueACT( w, event, params, num_params )
XWidget	    w;
XXEvent	   *event;
XString	   *params;
XCardinal   *num_params;
X{
X  if (*num_params != 1) {
X    WcSetValueCB(w, "", NULL);
X    return;
X  }
X
X  WcSetValueCB(w, params[0], NULL);
X}
X
X
X/*
X    -- Change sensitivity of widgets.
X*******************************************************************************
X*/
Xvoid	WcSetSensitiveACT( w, event, params, num_params )
XWidget	    w;
XXEvent	   *event;
XString	   *params;
XCardinal   *num_params;
X{
X  int	i;
X
X  if (*num_params < 1) {
X    WcSetSensitiveCB(w, "", NULL);
X    return;
X  }
X
X  for (i = 0; i < *num_params; i++) {
X    WcSetSensitiveCB(w, params[i], NULL);
X  }
X}
X
X
Xvoid	WcSetInsensitiveACT( w, event, params, num_params )
XWidget	    w;
XXEvent	   *event;
XString	   *params;
XCardinal   *num_params;
X{
X  int	i;
X
X  if (*num_params < 1) {
X    WcSetInsensitiveCB(w, "", NULL);
X    return;
X  }
X
X  for (i = 0; i < *num_params; i++) {
X    WcSetInsensitiveCB(w, params[i], NULL);
X  }
X}
X
X
X/*
X    -- Load Resource File
X*******************************************************************************
X*/
Xvoid	WcLoadResourceFileACT( w, event, params, num_params )
XWidget	    w;
XXEvent	   *event;
XString	   *params;
XCardinal   *num_params;
X{
X  if (*num_params != 1) {
X    WcLoadResourceFileCB(w, "", NULL);
X    return;
X  }
X
X  WcLoadResourceFileCB(w, params[0], NULL);
X}
X
X
X/*
X  -- WcTraceAction
X*******************************************************************************
X*/
Xvoid	WcTraceACT( w, event, params, num_params )
XWidget	    w;
XXEvent	   *event;
XString	   *params;
XCardinal   *num_params;
X{
X  if (*num_params != 1) {
X    WcTraceCB(w, "", NULL);
X    return;
X  }
X
X  WcTraceCB(w, params[0], NULL);
X}
X
X
X/*
X  -- Popup named widget
X*******************************************************************************
X*/
Xvoid	WcPopupACT( w, event, params, num_params )
XWidget	    w;
XXEvent	   *event;
XString	   *params;
XCardinal   *num_params;
X{
X  if (*num_params != 1) {
X    WcPopupCB(w, "", NULL);
X    return;
X  }
X
X  WcPopupCB(w, params[0], NULL);
X}
X
X
Xvoid	WcPopupGrabACT( w, event, params, num_params )
XWidget	    w;
XXEvent	   *event;
XString	   *params;
XCardinal   *num_params;
X{
X  if (*num_params != 1) {
X    WcPopupGrabCB(w, "", NULL);
X    return;
X  }
X
X  WcPopupGrabCB(w, params[0], NULL);
X}
X
X
X/*
X  -- Popdown named widget
X*******************************************************************************
X*/
Xvoid	WcPopdownACT( w, event, params, num_params )
XWidget	    w;
XXEvent	   *event;
XString	   *params;
XCardinal   *num_params;
X{
X  if (*num_params != 1) {
X    WcPopdownCB(w, "", NULL);
X    return;
X  }
X
X  WcPopdownCB(w, params[0], NULL);
X}
X
X
X/*
X  -- Invoke shell command
X*******************************************************************************
X*/
Xvoid	WcSystemACT( w, event, params, num_params )
XWidget	    w;
XXEvent	   *event;
XString	   *params;
XCardinal   *num_params;
X{
X  if (*num_params != 1) {
X    WcSystemCB(w, "", NULL);
X    return;
X  }
X
X  WcSystemCB(w, params[0], NULL);
X}
X
X
X/*
X  -- Exit the application
X*******************************************************************************
X*/
Xvoid	WcExitACT( w, event, params, num_params )
XWidget	    w;
XXEvent	   *event;
XString	   *params;
XCardinal   *num_params;
X{
X  if (*num_params != 1) {
X    WcExitCB(w, "", NULL);
X    return;
X  }
X
X  WcExitCB(w, params[0], NULL);
X}
X
X
X/*
X  -- WcRegisterWcActions
X*******************************************************************************
X   Convenience routine, registering all standard actions in one application
X   call.   Called from WcWidgetCreation(), so application usually never needs
X   to call this.
X*/
X
Xvoid WcRegisterWcActions ( app )
XXtAppContext app;
X{
X    static XtActionsRec WcActions[] = {
X      {"WcCreateChildrenACT",	WcCreateChildrenACT	},
X      {"WcManageACT",		WcManageACT		},
X      {"WcUnmanageACT",		WcUnmanageACT		},
X      {"WcManageChildrenACT",	WcManageChildrenACT	},
X      {"WcUnmanageChildrenACT",	WcUnmanageChildrenACT	},
X      {"WcDestroyACT",		WcDestroyACT		},
X      {"WcSetValueACT",		WcSetValueACT		},
X      {"WcSetSensitiveACT",	WcSetSensitiveACT	},
X      {"WcSetInsensitiveACT",	WcSetInsensitiveACT	},
X      {"WcLoadResourceFileACT",	WcLoadResourceFileACT	},
X      {"WcTraceACT",		WcTraceACT		},
X      {"WcPopupACT",		WcPopupACT		},
X      {"WcPopupGrabACT",	WcPopupGrabACT		},
X      {"WcPopdownACT",		WcPopdownACT		},
X      {"WcSystemACT",		WcSystemACT		},
X      {"WcExitACT",		WcExitACT		},
X    };
X
X    static int already = 0;
X
X    if (already++)
X	return;
X
X    XtAppAddActions(app, WcActions, XtNumber(WcActions));
X
X}
+FUNKY+STUFF+
echo '-rw-r--r--  1 david       11914 Jul  2 12:22 WcActions.c    (as sent)'
chmod u=rw,g=r,o=r WcActions.c
ls -l WcActions.c
echo x - WcAthenaP.h
sed 's/^X//' > WcAthenaP.h <<'+FUNKY+STUFF+'
X/*
X** Copyright (c) 1990 David E. Smyth
X** 
X** Redistribution and use in source and binary forms are permitted
X** provided that the above copyright notice and this paragraph are
X** duplicated in all such forms and that any documentation, advertising
X** materials, and other materials related to such distribution and use
X** acknowledge that the software was developed by David E. Smyth.  The
X** name of David E. Smyth may not be used to endorse or promote products
X** derived from this software without specific prior written permission.
X** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
X** WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
X** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X** 
X*/
X
X/*
X* SCCS_data: @(#)WcAthenaP.h 1.0 ( 19 June 1990 )
X*/
X
X#ifndef _WcAthenaP_h_
X#define _WcAthenaP_h_
X
X/* Core, Object, RectObj, WindowObj, 
X** XmGadget, XmPrimitive, and XmComposite, 
X** Shell, OverrideShell, WMShell, VendorShell, TopLevelShell, ApplicationShell, 
X** Constraint, XmManager.
X*/
X#include <X11/IntrinsicP.h>
X
X/* include all the *P.h files in heirarchical order */
X
X#include <X11/CoreP.h>
X#include <X11/ObjectP.h>
X#include <X11/Xaw/SimpleP.h>
X#include <X11/CompositeP.h>
X#include <X11/ConstrainP.h>
X
X/* Core */
X#include <X11/Xaw/ClockP.h>
X#include <X11/Xaw/LogoP.h>
X#include <X11/Xaw/MailboxP.h>
X#include <X11/Xaw/SimpleP.h>
X
X/* Simple */
X#include <X11/Xaw/GripP.h>
X#include <X11/Xaw/LabelP.h>
X#include <X11/Xaw/ListP.h>
X#include <X11/Xaw/ScrollbarP.h>
X#include <X11/Xaw/StripCharP.h>
X#include <X11/Xaw/TextP.h>
X
X/* Label */
X#include <X11/Xaw/CommandP.h>
X#include <X11/Xaw/MenuButtoP.h>
X#include <X11/Xaw/ToggleP.h>
X
X/* Sme */
X#include <X11/Xaw/SmeP.h>
X#include <X11/Xaw/SimpleMenP.h>
X#include <X11/Xaw/SmeBSBP.h>
X#include <X11/Xaw/SmeLineP.h>
X
X
X/* Text */
X#include <X11/Xaw/AsciiTextP.h>
X#include <X11/Xaw/TextSrcP.h>
X#include <X11/Xaw/AsciiSrcP.h>
X#include <X11/Xaw/TextSinkP.h>
X#include <X11/Xaw/AsciiSinkP.h>
X
X/* Composite and Constraint */
X#include <X11/Xaw/BoxP.h>
X#include <X11/Xaw/FormP.h>
X#include <X11/Xaw/PanedP.h>
X
X/* Form */
X#include <X11/Xaw/DialogP.h>
X#include <X11/Xaw/ViewportP.h>
X
X#endif
+FUNKY+STUFF+
echo '-rw-r--r--  1 david        2168 Jul  2 12:22 WcAthenaP.h    (as sent)'
chmod u=rw,g=r,o=r WcAthenaP.h
ls -l WcAthenaP.h
echo x - WcCallbacks.c
sed 's/^X//' > WcCallbacks.c <<'+FUNKY+STUFF+'
X/*
X** Copyright (c) 1990 David E. Smyth
X**
X** This file was derived from work performed by Martin Brunecky at
X** Auto-trol Technology Corporation, Denver, Colorado, under the
X** following copyright:
X**
X*******************************************************************************
X* Copyright 1990 by Auto-trol Technology Corporation, Denver, Colorado.
X*
X*                        All Rights Reserved
X*
X* Permission to use, copy, modify, and distribute this software and its
X* documentation for any purpose and without fee is hereby granted, provided
X* that the above copyright notice appears on all copies and that both the
X* copyright and this permission notice appear in supporting documentation
X* and that the name of Auto-trol not be used in advertising or publicity
X* pertaining to distribution of the software without specific, prior written
X* permission.
X*
X* Auto-trol disclaims all warranties with regard to this software, including
X* all implied warranties of merchantability and fitness, in no event shall
X* Auto-trol be liable for any special, indirect or consequential damages or
X* any damages whatsoever resulting from loss of use, data or profits, whether
X* in an action of contract, negligence or other tortious action, arising out
X* of or in connection with the use or performance of this software.
X*******************************************************************************
X**
X** Redistribution and use in source and binary forms are permitted
X** provided that the above copyright notice and this paragraph are
X** duplicated in all such forms and that any documentation, advertising
X** materials, and other materials related to such distribution and use
X** acknowledge that the software was developed by David E. Smyth.  The
X** name of David E. Smyth may not be used to endorse or promote products
X** derived from this software without specific prior written permission.
X** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
X** WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
X** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X**
X*/
X
X/*
X* SCCS_data: @(#)WcCallbacks.c 1.0 ( 19 June 1990 )
X*
X* Subsystem_group:
X*
X*     Widget Creation Library
X*
X* Module_description:
X*
X*     This module contains the convenience callbacks used to create and 
X*     manage a widget tree using the Xrm databse.
X*
X*     Several convenience callbacks are provided with the package, allowing 
X*     deferred widget creation, control (manage/unmanage) and other utility
X*     functions.
X*
X* Module_interface_summary: 
X*
X*     Convenience Callbacks:
X*
X* Module_history:
X*                                                  
X*   Several of the callbacks and the callback registration routine were
X*   originally written by Martin Brunecky at Auto-Trol, between about
X*   the first of February 1990 until about 18 April 1990.
X*
X*   Additional callbacks and modifications to all callbacks and the
X*   callback registration routine were made by David Smyth at Jet
X*   Propulsion Laboratories following about 15 March 1990.
X*
X* Design_notes:
X*
X*   For VMS, we could have used LIB$FIND_IMAGE_SYMBOL and use dynamic
X*   (runtime) binding. But since most UNIX systems lack such capability,
X*   we stick to the concept of "registration" routines.
X*
X*   All these callbacks could probably be declared as static.  They
X*   were not because applications may want to link them to widgets
X*   via C code.  
X*
X*   When Motif runs on release 4 Intrinsics, then all argument parsing
X*   should be replaced with coverters, so conversions get cached.  This
X*   will improve performance, especially for pop-ups.
X*
X*******************************************************************************
X*/
X/*
X*******************************************************************************
X* Include_files.
X*******************************************************************************
X*/
X
X#include "WidgetCreate.h"
X#include "WidgetCreateP.h"
X
X/*
X*******************************************************************************
X* Private_type_declarations.
X*******************************************************************************
X*/
X
X/*
X*******************************************************************************
X* Private_macro_definitions.
X*******************************************************************************
X*/
X
X/*
X*******************************************************************************
X* Private_data_definitions.
X*******************************************************************************
X*/
X
X/* NOTE: These are shared arrays because they are large: i.e.,
X** this is a performacne optimization intended to reduce page
X** faults which can occur while making large extensions to the
X** stack space.  Wait a minute: wouldn't this just happen
X** once, and then the stack space is alloc'd?  Yes, but a
X** huge stack space runs the risk of getting swapped, which causes
X** page faults.  This is probably a nit-picky sort of optimization.
X** Remember that D.Smyth is an old sys programmer from the stone
X** ages, and pity him instead of flaming him.
X** Be careful when filling msg not to call any funcs in here, 
X** so the message does not get garbled.
X*/
X
Xstatic char	msg[MAX_ERRMSG];
Xstatic char	cleanName[MAX_PATHNAME];
Xstatic Widget	widget_list[MAX_CHILDREN];
X
X/*
X*******************************************************************************
X* Private_function_declarations.
X*******************************************************************************
X*/
X
X/*
X*******************************************************************************
X* Public_callback_function_declarations.
X*******************************************************************************
X    The client data argument of callbacks MUST be a null terminated
X    string.  If client == (char*)0 this is an error.  The correct way
X    to pass no client information is *client == '\0'. The CvtStringToCallback
X    converter which actually causes these functions to be called (adds
X    these functions to widget's callback lists) does ensure that the
X    client data is a proper null terminated string.
X
X    Callbacks are not intended to be re-entrant nor recursive.  Many of
X    these use static buffers.
X*******************************************************************************
X*/
X
X/*
X    -- Create Deferred Children from Xrm Database
X*******************************************************************************
X    This callback creates one or more specified children of a parent widget.
X    If parent name is `this' then widget invoking callback is used as the
X    parent.  Parent name can also be a wildcarded path name.  Child names
X    must be single part, specific children of the parent. Client data format:
X
X             parent, child [,child] ...
X    
X    This callback is used for deferred sub-tree creation, where named child
X    creation has been postponed due to a resource specification of the form:
X
X	    *foobar.WcDeferred:  True
X*/
X
Xvoid WcCreateChildrenCB ( w, parent_children, unused )
X    Widget w;
X    char* parent_children;	/* parent + list of named children */
X    caddr_t unused;		/* call data from widget, not used */
X{
X    char*	children;
X    Widget	parent;
X
X    if ( *parent_children == NUL ) 
X    {
X	XtWarning(
X            "WcCreateChildrenCB ( ) - Failed \n\
X             Usage: WcCreateChildrenCB ( parent, child [, child ] ...) \n\
X                    Name of parent can be `this' or wildcarded pathname, \n\
X                    Name of child must be single part name from parent. \n\
X             Problem: No widget names provided.");
X	return;
X    }
X
X    children = WcCleanName( parent_children, cleanName );
X
X    children = WcSkipWhitespace_Comma( children );
X
X    if ((Widget)NULL == (parent = WcFullNameToWidget( w, cleanName )) )
X    {
X	sprintf( msg,
X            "WcCreateChildrenCB (%s) - Failed \n\
X             Usage: WcCreateChildrenCB ( parent, child [, child ] ...) \n\
X                    Name of parent can be `this' or wildcarded pathname, \n\
X                    Name of child must be single part name from parent. \n\
X             Problem: Parent widget named `%s' not found.",
X	    parent_children, cleanName);
X	XtWarning( msg );
X	return;
X    }
X
X    if (*children == NUL)
X    {
X        sprintf( msg,
X            "WcCreateChildrenCB (%s) - Failed \n\
X             Usage: WcCreateChildrenCB ( parent, child [, child ] ...) \n\
X                    Name of parent can be `this' or wildcarded pathname, \n\
X                    Name of child must be single part name from parent. \n\
X             Problem: No children names provided.",
X	    parent_children );
X	XtWarning( msg );
X        return;
X    }
X
X    WcCreateDeferredChildren ( parent, children );
X}
X
X/******************************************************************************
X**  Manage or Unmanage named widget(s)
X*******************************************************************************
X    This callback translates string passed in as client data into one or more
X    widget ids, and manages or unmanages it or them.  Client data format:
X	name [, name] ...
X    Name can include `this' and other path names.
X******************************************************************************/
X
X#ifdef FUNCTION_PROTOTYPES
Xstatic void ManageOrUnmanage( Widget, char*, char*, void (*proc)() );
X#else
Xstatic void ManageOrUnmanage();
X#endif
X
Xvoid WcManageCB ( w, widgetNames, unused )
X    Widget w;
X    char* widgetNames;
X    caddr_t unused;		/* call data from widget, not used */
X{
X    ManageOrUnmanage( w, widgetNames, "WcManageCB", XtManageChildren );
X}
X
Xvoid WcUnmanageCB ( w, widgetNames, unused )
X    Widget w;
X    char* widgetNames;
X    caddr_t unused;             /* call data from widget, not used */
X{
X    ManageOrUnmanage( w, widgetNames, "WcUnmanageCB", XtUnmanageChildren );
X}
X
Xstatic void ManageOrUnmanage ( w, widgetNames, callbackName, proc )
X    Widget w;
X    char* widgetNames;
X    char* callbackName;
X    void (*proc)();
X{
X    int         numWidgets = 0;
X    char*       s = widgetNames;
X
X    while (*s && numWidgets < MAX_CHILDREN)
X    {
X        s = WcCleanName ( s, cleanName );
X        s = WcSkipWhitespace_Comma ( s );
X        if ( widget_list[numWidgets] = WcFullNameToWidget ( w, cleanName ) )
X            numWidgets++;
X        else
X        {
X            sprintf(msg,
X            "%s (%s) - Widget `%s' ignored \n\
X             Usage:   %s ( widget_name [, widget_name] ... ) \n\
X             Problem: Could not find widget named `%s'.",
X             callbackName, widgetNames, cleanName, callbackName, cleanName);
X            XtWarning( msg );
X        }
X    }
X    if (numWidgets >= MAX_CHILDREN)
X    {
X	sprintf(msg,
X            "%s (%s) - Failed \n\
X             Usage:   %s ( widget_name [, widget_name] ... ) \n\
X             Problem: Too many widgets (more than MAX_CHILDREN).",
X             callbackName, widgetNames, callbackName);
X	XtWarning( msg );
X	numWidgets = 0;
X    }
X
X    if ( numWidgets )
X        /* proc is either XtManageChildren or XtUnmanageChildren */
X        proc ( widget_list, numWidgets );
X}
X
X/*
X    -- Manage or unamange named children callback
X*******************************************************************************
X    These callbacks translates a string passed in as client data into a parent
X    widget id, and names of children of that parent.  If parent name is
X    `this' then widget invoking callback is used as the parent.  Parent
X    name can also be a wildcarded path name.  Child names must be single
X    part, specific children of the parent. Client data format:
X
X             parent, child [,child] ...
X
X    This callback can be used as an alternate for WcManageCB but it is
X    really intended to be used to manage/unmanage children of widgets 
X    which have multiple instances, and where the parent name is `this'.
X*/
X#ifdef FUNCTION_PROTOTYPES
Xstatic void ManageOrUnmanageChildren( Widget, char*, char*, void (*proc)() );
X#else
Xstatic void ManageOrUnmanageChildren();
X#endif
X
Xvoid WcManageChildrenCB ( w, parent_children, unused )
X    Widget 	w;
X    char*	parent_children;/* client data, list of named children  */
X    caddr_t	unused;		/* call data from widget		*/
X{
X    ManageOrUnmanageChildren( w, parent_children, 
X				"WcManageChildrenCB", XtManageChildren );
X}
X
Xvoid WcUnmanageChildrenCB ( w, parent_children, unused )
X    Widget      w;
X    char*       parent_children;/* client data, list of named children  */
X    caddr_t     unused;         /* call data from widget                */
X{
X    ManageOrUnmanageChildren( w, parent_children,
X                                "WcUnmanageChildrenCB", XtUnmanageChildren );
X}
X
Xstatic void ManageOrUnmanageChildren( w, parent_children, callbackName, proc )
X    Widget w;
X    char* parent_children;      /* client data, list of named children  */
X    char* callbackName;		/* WcManageChildrenCB or WcUnmanageChildrenCB */
X    void (*proc)();		/* XtManageChildren or XtUnmanageChildren */
X{
X    int         	numWidgets = 0;
X    char*		next;
X    Widget		parent;
X
X    if ( *parent_children == NUL )
X    {
X        sprintf(msg,
X            "%s ( ) - Failed \n\
X             Usage: %s ( parent, child [, child ] ...) \n\
X                    Name of parent can be `this' or wildcarded pathname, \n\
X                    Name of child must be single part name from parent. \n\
X             Problem: No widget names provided.",
X	    callbackName, callbackName);
X	XtWarning( msg );
X        return;
X    }
X
X    next = WcCleanName( parent_children, cleanName );
X    if ((Widget)NULL == (parent = WcFullNameToWidget( w, cleanName )) )
X    {
X        sprintf( msg,
X            "%s (%s) - Failed \n\
X             Usage: %s ( parent, child [, child ] ...) \n\
X                    Name of parent can be `this' or wildcarded pathname, \n\
X                    Name of child must be single part name from parent. \n\
X             Problem: Parent widget named `%s' not found.",
X            callbackName, parent_children, callbackName, cleanName);
X        XtWarning( msg );
X        return;
X    }
X
X    while (*next && numWidgets < MAX_CHILDREN)
X    {
X        next = WcCleanName( next, cleanName );
X	if (widget_list[numWidgets] = WcChildNameToWidget( parent, cleanName ))
X	    numWidgets++;
X	else
X	{
X	    sprintf( msg,
X            "%s (%s) - Child `%s' ignored \n\
X             Usage: %s ( parent, child [, child ] ...) \n\
X                    Name of parent can be `this' or wildcarded pathname, \n\
X                    Name of child must be single part name from parent. \n\
X             Problem: Child widget named `%s' not found.",
X	    callbackName, parent_children, callbackName, cleanName);
X	    XtWarning( msg );
X	}
X    }
X
X    if (numWidgets >= MAX_CHILDREN)
X    {
X        sprintf(msg,
X            "%s (%s) - Failed \n\
X             Usage: %s ( parent, child [, child ] ...) \n\
X                    Name of parent can be `this' or wildcarded pathname, \n\
X                    Name of child must be single part name from parent. \n\
X             Problem: Too many widgets (more than MAX_CHILDREN).",
X             callbackName, parent_children, callbackName);
X        XtWarning( msg );
X        numWidgets = 0;
X    }
X
X    if ( numWidgets )
X        /* proc is either XtManageChildren or XtUnmanageChildren */
X        proc ( widget_list, numWidgets );
X}
X
X/*
X    -- Destroy named children callback
X*******************************************************************************
X    This callback translates string passed in as client data into a widget id
X    and destroys it. A comma separated list of widgets can be specified.
X    `this' means the invoking widget.
X*/
X
Xvoid WcDestroyCB ( w, widgetNames, unused )
X    Widget  w;
X    char*   widgetNames;	/* client data, widgets to be destroyed */
X    caddr_t unused;		/* call data from widget, not used	*/
X{
X    Cardinal	widget_count = MAX_CHILDREN;
X    char*	unConvertedNames;
X    int         i;
X
X    unConvertedNames = WcNamesToWidgetList ( w, widgetNames, 
X				    widget_list, &widget_count );
X    if ( unConvertedNames[0] != NUL )
X    {
X	sprintf(msg,
X            "WcDestroyCB (%s) \n\
X             Usage: WcDestroyCB ( widget [, widget ] ...) \n\
X                    Name of widget can be `this' or wildcarded pathname. \n\
X		    Problem: No widgets found named %s.",
X             widgetNames, unConvertedNames);
X        XtWarning( msg );
X    }
X
X    for (i=0; i<widget_count; i++)
X       XtDestroyWidget ( widget_list[i] );
X}
X
X/*
X   -- Set Resource Value on Widget
X*******************************************************************************
X    This callback sets a resource value on the named widget.
X
X    The client data argument has a format:
X
X        target_widget_name.resource_name: resource value
X
X    The special resource value of "this" means "this widget."  Typically,
X    using "this" as the resource value is used to set the "XmNdefaultButton"
X    resource on a XmbulletinBoard, "menuBar", "workArea", etc on XmMainWindows,
X    the subMenuId resource on menuBar cascade buttons, and so on.
X*/
X
Xvoid WcSetValueCB ( w, name_res_resVal, unused )
X    Widget  w;  
X    char*   name_res_resVal;		/* client data: name.resName: resVal */
X    caddr_t unused;			/* call data from wudget, not used   */
X{
X    /* Note: static buffers make this routine NON-REENTRANT!! */
X    static char    target_name[MAX_XRMSTRING];
X    static char    resource[MAX_XRMSTRING];
X    static char    res_val[MAX_XRMSTRING];
X
X    Widget         target;
X    register char *d,*s;
X    Arg            args[1];
X
X    s = name_res_resVal;
X    /* copy from name_res_resVal into target_name[],
X    ** ignore initial whitespace, stop at trailing `:'  
X    ** Then backup to get final segment, the resource name
X    */
X    for ( s = name_res_resVal ; *s && *s <= ' ' ; s++ )
X	;	/* skip initial whitespace */
X    for ( d = target_name ; *s && *s != ':' ; s++, d++ )
X	*d = *s;
X    for ( ; target_name < d && (*d != '.' && *d != '*') ; s--, d-- )
X	;
X    *d = NUL;
X
X    /* OK, now target_name is null terminated.
X    ** s points at final `.' or `*' in name_resName, 
X    ** now we copy to resource[].
X    */
X    for ( s++, d = resource ; *s && *s != ':' ; s++, d++ )
X        *d = *s;
X    *d = NUL;
X
X    /* OK, now resource is null terminated.
X    ** s points at the `:' now we skip whitespace and the rest is value
X    ** until we hit whitespace again.
X    */
X    for (s++ ; *s && *s <= ' ' ; s++ )
X        ;       /* skip initial whitespace */
X    for (d = res_val ; *s && *s >= ' ' ; s++, d++ )
X	*d = *s;
X    *d = NUL;
X
X    /* Check for syntax error: if any of the strings are null, wrongo!
X    */
X    if ( target_name[0] == NUL || resource[0] == NUL || res_val[0] == NUL )
X    {
X        char *missing;
X
X        if (target_name[0] == NUL)
X            missing = "target_widget_name";
X        else if (resource[0] == NUL)
X            missing = "res_name";
X        else if (res_val[0] == NUL)
X            missing = "res_value";
X        else
X            missing = "** WcSetValueCB BUG **";
X
X        sprintf ( msg,
X            "WcSetValueCB (%s) - Failed \n\
X             Usage:   WcSetValueCB( target_widget_name.res_name: res_value ) \n\
X             Problem: Missing %s argument.",
X            name_res_resVal);
X        XtWarning( msg ); 
X	return;
X    }
X
X    /* The target widget name is rooted at the appShell */
X    if ( target = WcFullNameToWidget ( w, target_name ) )
X    {
X        /* Found the target widget.  Set the resource on it */
X
X	char* widgetName = WcStripWhitespaceFromBothEnds( res_val );
X
X        if (0 == strcmp(widgetName,"this"))
X        {
X            args[0].name  = resource;
X            args[0].value = (XtArgVal)w;
X
X            XtSetValues ( target, args, 1 );
X        }
X        else
X        {
X            /* convert to appropriate value and call XtSetValue() */
X            WcSetValueFromString( target, resource, res_val );
X        }
X	XtFree(widgetName);
X    }
X    else
X    {
X        sprintf ( msg,
X            "WcSetValueCB (%s)  \n\
X             Usage:   WcSetValueCB( target_widget_name.res_name: res_value ) \n\
X             Problem: Could not find widget named `%s'",
X             name_res_resVal, target_name );
X        XtWarning( msg );
X        return;
X    }
X}
X
X/*
X    -- Change sensitivity of widgets.
X*******************************************************************************
X    This callback translates string passed in as client data into widget ids
X    and sets each to be sensitve/insensitive. A comma separated list of 
X    widgets can be specified.  `this' means the invoking widget.  
X
X    This callback someday should take care of the problem with text
X    widgets - they don't get grey when insensitive, which must be a bug.
X*/
X
X#ifdef FUNCTION_PROTOTYPES
Xstatic void ChangeSensitivity( Widget, char*, char*, int );
X#else
Xstatic void ChangeSensitivity();
X#endif
X
Xvoid WcSetSensitiveCB ( w, widgetNames, unused )
X    Widget  w;
X    char*   widgetNames;        /* client data, widgets to be destroyed */
X    caddr_t unused;		/* call data from widget is not used    */
X{
X    ChangeSensitivity ( w, widgetNames, "WcSetSensitiveCB", (Boolean)TRUE );
X}
X
Xvoid WcSetInsensitiveCB ( w, widgetNames, unused )
X    Widget  w;
X    char*   widgetNames;        /* client data, widgets to be destroyed */
X    caddr_t unused;             /* call data from widget is not used    */
X{
X    ChangeSensitivity ( w, widgetNames, "WcSetInsensitiveCB", (Boolean)FALSE );
X}
X
Xstatic void ChangeSensitivity ( w, widgetNames, callbackName, sensitive )
X    Widget  w;
X    char*   widgetNames;        /* client data, widgets to be destroyed */
X    char*   callbackName;	/* "WcSetSensitiveCB" or "WcSetInsensitiveCB" */
X    int     sensitive;
X{
X    Cardinal    widget_count = MAX_CHILDREN;
X    char*       unConvertedNames;
X    int         i;
X
X    unConvertedNames = WcNamesToWidgetList ( w, widgetNames,
X                                    widget_list, &widget_count );
X    if ( unConvertedNames[0] != NUL )
X    {
X        sprintf(msg,
X            "%s (%s) - One or more widget names ignored \n\
X             Usage: %s ( widget [, widget ] ...) \n\
X                    Name of widget can be `this' or wildcarded pathname. \n\
X                    Problem: No widgets found named %s.",
X             callbackName, widgetNames, callbackName, unConvertedNames);
X        XtWarning( msg );
X    }
X
X    for (i=0; i<widget_count; i++)
X	XtSetSensitive ( widget_list[i], sensitive );
X}
X
X/*
X    -- Load Resource File
X*******************************************************************************
X    This callbacks loads specified resource file into application
X    resource database. It allows to load resources on as-needed
X    basis, reducing the intitial resource file load overhead. 
X    The file to load is specified as client data. The directory search 
X    for the file (should be) the same as for application class resource file.
X    
X    To prevent repeated loads of the same file, the callback changes
X    the 1st character of the string argument into a control-D.
X    Beware this feature when using callback from the C code !
X
X    NOTE:
X    The file search list rule used here is a gross simplification of the R3
X    resource file search mechanism, without the $LANG provision.
X    I hope I can use R4 soon and do it RIGHT, but I depend on Motif for now,
X    and do not want to duplicate all the Motif code here.
X    Here I look into two directories only, which may be defined as environmental
X    variables:
X         XAPPLRESDIR  - defaults to "/usr/lib/X11/app-defaults/"
X	 XUSERRESDIR  - defaults to HOME directory
X*/
X
X#ifdef VAX
X#define XAPPLRESDIR "sys$library:"
X#else
X#define XAPPLRESDIR "/usr/lib/X11/app-defaults/"
X#endif
X
Xvoid WcLoadResourceFileCB ( w,  resFileName, unused )
X    Widget w;
X    char*  resFileName;	/* client data, X resources file name */
X    caddr_t unused;	/* call data,   not used */
X{
X    static char  name[MAX_PATHNAME];
X    char 	*path;
X    char  	 filename[MAX_PATHNAME];
X    XrmDatabase  rdb;
X    Display     *dpy = XtDisplay(w);
X    extern char *getenv();
X    Boolean      found = FALSE;
X
X/*  -- check for repeated invocation, flagged by control-D */
X    if ( *resFileName == ALREADY_LOADED_RESOURCE_FILE ) return;
X
X    (void) WcCleanName( resFileName, name );
X
X/*  -- check pathname presence */
X    if ( *name == NUL )
X    {
X        XtWarning ( 
X            "WcLoadResourceFileCB () - Failed \n\
X             Usage:   WcLoadResourceFileCB( resource_file_name ) \n\
X             Problem: No file name provided.");
X        return;
X    }
X
X/*  -- Look for file in application class resources file directory */
X    if ((path = getenv("XAPPLRESDIR")) == NULL) 
X    {
X	path = XAPPLRESDIR ;
X    } 
X    strcpy ( filename, path );
X    strcat ( filename, name );
X 
X    if ((rdb = XrmGetFileDatabase(filename)) != NULL )
X    {
X	XrmMergeDatabases (rdb, &(dpy->db) );
X	found = TRUE;
X    }	
X
X#ifdef I_DONT_KNOW_WHY_THIS_IS_HERE
X/*  -- Look for file in user class resources file directory */
X    if ((path = getenv("XUSERRESDIR")) == NULL) 
X    {
X	path = ( char* )malloc (MAX_PATHNAME);
X        strcpy ( path, RootDirName(filename));
X    } 
X    strcpy ( filename, path );
X    strcat ( filename, name );
X    free   ( path );
X    if ((rdb = XrmGetFileDatabase(filename)) != NULL )
X    {
X	XrmMergeDatabases (rdb, &(dpy->db) );
X        found = TRUE;
X    }
X#endif
X
X/*  -- Look for file in current working directory */
X    strcpy ( filename, name );
X    if ((rdb = XrmGetFileDatabase(filename)) != NULL )
X    {
X        XrmMergeDatabases (rdb, &(dpy->db) );
X        found = TRUE;
X    }
X
X/*  -- warn the user if no file found */
X    if (!found)
X    {
X	sprintf  ( msg, 
X            "WcLoadResourceFileCB ( %s ) - Failed \n\
X             Usage:   WcLoadResourceFileCB( resource_file_name ) \n\
X             Problem: Cannot load resource file %s",
X	resFileName, name );
X	XtWarning( msg );
X    }
X
X
X/*  -- change 1st char of file name to ^D to flag resource load is complete */
X    resFileName[0] = ALREADY_LOADED_RESOURCE_FILE;
X}
X
X/*
X  -- WcTraceCallback
X*******************************************************************************
X    This is a simple traceback callback, used to assist in interface
X    debugging. The callback prints the invoking wiget pathname and
X    a specified message on std. output.
X*/
X
Xvoid WcTraceCB ( w, annotation, unused )
X    Widget w;
X    char* annotation;	/* client data, traceback annotation */
X    caddr_t unused;	/* call data,   not used */
X{
X    char* name = WcWidgetToFullName( w );
X    
X    printf("TraceCB for %s: %s\n", name, annotation );
X    XtFree( name );
X}
X
X/*
X  -- Popup named widget
X*******************************************************************************
X    These callbacks translate a string passed in as client data into a 
X    widget id.  
X
X    A grab kind value of XtGrabNonexclusive has the effect of allowing 
X    non-modal popups.  This is the preferred type: rarely use modal pop-ups.
X    This is registered as PopupCB.
X
X    A grab kind value of XtGrabExclusive has the effect of grabbing all
X    application events, allowing modal popups.  This is registered as 
X    PopupGrabCB.
X*/
X
X#ifdef FUNCTION_PROTOTYPES
Xstatic void Popup ( Widget, char*, char*, XtGrabKind );
X#else
Xstatic void Popup ();
X#endif
X
Xvoid WcPopupCB ( w, name, unused )
X    Widget      w;
X    char*       name;
X    caddr_t	unused;
X{
X    Popup ( w, name, "WcPopupCB", XtGrabNonexclusive );
X}
X
Xvoid WcPopupGrabCB ( w, name, unused )
X    Widget      w;
X    char*       name;
X    caddr_t     unused;
X{
X    Popup ( w, name, "WcPopupGrabCB", XtGrabExclusive );
X}
X
Xstatic void Popup ( w, name, callbackName, grab )
X    Widget	w;
X    char*	name;
X    char*	callbackName;
X    XtGrabKind	grab;
X{
X    Widget      widget;
X
X    (void)WcCleanName ( name, cleanName );
X    widget = WcFullNameToWidget ( w, cleanName );
X
X    if (XtIsShell(widget))
X    {
X        XtPopup  ( widget, grab );
X    }
X    else
X    {
X        sprintf( msg,
X            "%s (%s) - Failed \n\
X             Usage: %s (shell_widget_name) \n\
X             Problem: `%s' is not a shell widget.",
X             callbackName, name, callbackName, cleanName);
X        XtWarning( msg );
X    }
X}
X
X/*
X  -- Popdown named widget
X*******************************************************************************
X    This callback translates string passed in as client data into a widget id
X    and pops-down a popup shell widget.
X*/
X
Xvoid WcPopdownCB ( w, name, unused ) 
X    Widget	w;
X    char*	name;
X    caddr_t	unused;
X{
X    Widget      widget;
X
X    (void)WcCleanName ( name, cleanName );
X    widget = WcFullNameToWidget ( w, cleanName );
X
X    if (XtIsShell(widget))
X    {
X        XtPopdown  ( widget );
X    }
X    else
X    {
X        sprintf( msg,
X            "WcPopdownCB (%s) Failed \n\
X             Usage: WcPopdownCB (shell_widget_name) \n\
X             Problem: `%s' is not a shell widget.",
X             name, cleanName);
X        XtWarning( msg );
X    }
X}
X
X/*
X  -- Invoke shell command
X*******************************************************************************
X    Call system().
X*/
X
Xvoid WcSystemCB ( w, shellCmdString, unused )
X    Widget      w;
X    char*       shellCmdString;
X    caddr_t     unused;
X{
X    system( shellCmdString );
X}
X
X/*
X  -- Exit the application
X*******************************************************************************
X    Call exit().
X*/
X
Xvoid WcExitCB ( w, exitValString, unused )
X    Widget	w;
X    char*	exitValString;
X    caddr_t	unused;
X{
X    int exitval = 0;
X
X    /* skip leading garbage before int */
X    while (*exitValString)
X    {
X        if ('0' < *exitValString && *exitValString <= '9')
X            break; /* found numbers, convert to exitval */
X        exitValString++;
X    }
X
X    /* convert to int */
X    while (*exitValString)
X    {
X        if ('0' < *exitValString && *exitValString <= '9')
X        {
X            exitval = exitval * 10 + (*exitValString - '0');
X            exitValString++;
X        }
X        else
X            break;  /* ignore trailing garbage */
X    }
X
X    exit( exitval );
X}
X
X/*
X  -- WcRegisterCreateCallbacks
X*******************************************************************************
X   Convenience routine, registering all standard callbacks in one application
X   call.   Called from WcWidgetCreation(), so application usually never needs
X   to call this.
X*/
X
Xvoid WcRegisterWcCallbacks ( app )
XXtAppContext app;
X{
X#define RCALL( name, func ) WcRegisterCallback ( app, name, func, NULL )
X
X    static int already = 0;
X
X    if (already++)
X	return;
X
X    RCALL( "WcCreateChildrenCB",	WcCreateChildrenCB	);
X    RCALL( "WcManageCB",		WcManageCB		);
X    RCALL( "WcUnmanageCB",		WcUnmanageCB		);
X    RCALL( "WcManageChildrenCB",	WcManageChildrenCB	);
X    RCALL( "WcUnmanageChildrenCB",	WcUnmanageChildrenCB	);
X    RCALL( "WcDestroyCB",		WcDestroyCB		);
X    RCALL( "WcSetValueCB",		WcSetValueCB		);
X    RCALL( "WcSetSensitiveCB",		WcSetSensitiveCB	);
X    RCALL( "WcSetInsensitiveCB",	WcSetInsensitiveCB	);
X    RCALL( "WcLoadResourceFileCB",	WcLoadResourceFileCB	);
X    RCALL( "WcTraceCB",			WcTraceCB		);
X    RCALL( "WcPopupCB",			WcPopupCB		);
X    RCALL( "WcPopupGrabCB",		WcPopupGrabCB		);
X    RCALL( "WcPopdownCB",		WcPopdownCB		);
X    RCALL( "WcSystemCB",		WcSystemCB		);
X    RCALL( "WcExitCB",			WcExitCB		);
X
X#undef CALLBACK
X}
+FUNKY+STUFF+
echo '-rw-r--r--  1 david       31160 Jul  2 12:22 WcCallbacks.c    (as sent)'
chmod u=rw,g=r,o=r WcCallbacks.c
ls -l WcCallbacks.c
echo x - WcConverters.c
sed 's/^X//' > WcConverters.c <<'+FUNKY+STUFF+'
X/*
X** Copyright (c) 1990 David E. Smyth
X**
X** This file was derived from work performed by Martin Brunecky at
X** Auto-trol Technology Corporation, Denver, Colorado, under the
X** following copyright:
X**
X*******************************************************************************
X* Copyright 1990 by Auto-trol Technology Corporation, Denver, Colorado.
X*
X*                        All Rights Reserved
X*
X* Permission to use, copy, modify, and distribute this software and its
X* documentation for any purpose and without fee is hereby granted, provided
X* that the above copyright notice appears on all copies and that both the
X* copyright and this permission notice appear in supporting documentation
X* and that the name of Auto-trol not be used in advertising or publicity
X* pertaining to distribution of the software without specific, prior written
X* permission.
X*
X* Auto-trol disclaims all warranties with regard to this software, including
X* all implied warranties of merchantability and fitness, in no event shall
X* Auto-trol be liable for any special, indirect or consequential damages or
X* any damages whatsoever resulting from loss of use, data or profits, whether
X* in an action of contract, negligence or other tortious action, arising out
X* of or in connection with the use or performance of this software.
X*******************************************************************************
X**
X** Redistribution and use in source and binary forms are permitted
X** provided that the above copyright notice and this paragraph are
X** duplicated in all such forms and that any documentation, advertising
X** materials, and other materials related to such distribution and use
X** acknowledge that the software was developed by David E. Smyth.  The
X** name of David E. Smyth may not be used to endorse or promote products
X** derived from this software without specific prior written permission.
X** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
X** WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
X** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X**
X*/
X
X/*
X* SCCS_data: @(#)WcConverters.c 1.0 ( 19 June 1990 )
X*
X* Subsystem_group:
X*
X*     Widget Creation Library
X*
X* Module_description:
X*
X*     This module contains Xt converter functions which convert strings,
X*     as found in the Xrm database, into useful types.  
X*
X*     It also contains the routine which registers all Wc converters.
X*
X*     The CvtStringToWidget converter takes a pathname which starts 
X*     from the application shell an proceeds to a specific widget.  The
X*     widget must already have been created.   Note that this converter
X*     needs to be used INSTEAD of the XmuCvtStringToWidget which gets
X*     registered by the Athena widgets.  The Xmu converter is not se
X*     user friendly.  This means this file also declares an external
X*     function XmuCvtStringToWidget() which is really CvtStringToWidget,
X*     an this nees to be linked before Xmu.
X*
X*     The CvtStringToCallback converter parses the resource string in 
X*     the format:
X*
X*       ...path:   name[(args)][,name[(args)]]...
X*
X*     where:  name:   specifies the registered callback function name
X*             args:   specifies the string passed to a callback as
X*		      "client data".
X*
X*     Multiple callbacks can be specified for a single callback list
X*     resource.  Any callbacks must be "registered" by the application
X*     prior converter invocation (.i.e.prior widget creation).
X*     If no "args" string is provided, the default "client data" 
X*     specified at callback registration are used.
X*
X*     The CvtStringToConstructor converter searches the Constructor
X*     cache for a registered constructor.  
X*
X*     The CvtStringToClass converter searches the Class cache for a 
X*     registered object (widget) class pointer name.
X*
X*     The CvtStringToClassName converter searches the ClassName cache
X*     for a registered object (widget) class name.
X
X*
X* Module_interface_summary: 
X*
X*     Resource converter is invoked indirectly by the toolkit. The
X*     converter is added to the toolkit by widgets calling
X*     WcAddConverters() in the Wc intialization code.
X*
X* Module_history:
X*                                                  
X*   mm/dd/yy  initials  function  action
X*   --------  --------  --------  ---------------------------------------------
X*   06/08/90  D.Smyth   Class, ClassName, and Constructor converters.
X*   05/24/90  D.Smyth   WcAddConverters created from something similar
X*   04/03/90  MarBru    CvtStr..  Fixed argument termination with a NUL char
X*   02/26/90  MarBru    All       Created
X*
X* Design_notes:
X*
X*   For VMS, we could have used LIB$FIND_IMAGE_SYMBOL and use dynamic
X*   (runtime) binding. But since most UNIX systems lack such capability,
X*   we stick to the concept of "registration" routines.
X*
X*   One time, I considered applying conversion to callback argument, which
X*   would take the burden of conversion from the callback code (runtime)
X*   to the callback  conversion (one time initialization). The problem is
X*   that some conversions are widget context specific (color to pixel needs
X*   display connection), and at the time of callback conversion I do not
X*   have a widget. I could require the widget argument, but this would kill
X*   caching of the conversion result.
X*
X*   The sequential search of the callback cache is far from optimal. I should
X*   use binary search, or the R4 conversion cache.  I can't use the R4 cache
X*   until Motif 1.1 is released which will (supposedly) run on R4 Intrinsics.
X*   
X*******************************************************************************
X*/
X/*
X*******************************************************************************
X* Include_files.
X*******************************************************************************
X*/
X
X#include <ctype.h>	/* isupper() and tolower macros */
X#include <stdio.h>
X
X/*  -- X Window System includes */
X#include <X11/StringDefs.h> 
X
X/*  -- Widget Creation Library includes */
X#include "WidgetCreate.h"
X#include "WidgetCreateP.h"
X
X#ifdef MOTIF
X
X/*  -- Motif specific includes for CvtStringToMenuWidget */
X#include <Xm/Xm.h>
X#include <Xm/RowColumn.h>
X#include <Xm/RowColumnP.h>
X
X#endif MOTIF
X
X/*
X*******************************************************************************
X* Private_constant_declarations.
X*******************************************************************************
X*/
X
X/*
X*******************************************************************************
X* Private_type_declarations.
X*******************************************************************************
X*/
X
X/*
X*******************************************************************************
X* Private_macro_definitions.
X*******************************************************************************
X*/
X
X#define done( type, value ) 			\
X{						\
X    if ( toVal->addr != NULL )			\
X    {						\
X	if ( toVal->size < sizeof( type ) )	\
X	{					\
X	    toVal->size = sizeof( type );	\
X	    return;				\
X	}					\
X	*(type*)(toVal->addr) = (value);	\
X    }						\
X    else					\
X    {						\
X	static type static_val;			\
X	static_val = (value);			\
X	toVal->addr = (caddr_t)&static_val;	\
X    }						\
X    toVal->size = sizeof(type);			\
X    return;					\
X}
X
X/*
X*******************************************************************************
X* Private_data_definitions.
X*******************************************************************************
X*/
X
X/*
X*******************************************************************************
X* Private_function_declarations.
X*******************************************************************************
X*/
X
X/*
X    -- Convert String To ClassPtr
X*******************************************************************************
X    This conversion searches the Object Class cache for the appropriate
X    Cache record.  The resource database string is simply the name
X    of the class pointer, case insensitive.  The value provided is the
X    widget class pointer, as passed to XtCreateWidget().
X*/
X
Xvoid CvtStringToClassPtr (args, num_args, fromVal, toVal )
X    XrmValue  *args;
X    Cardinal  *num_args;
X    XrmValue  *fromVal;
X    XrmValue  *toVal;
X{
X    char*       string = (char *) fromVal->addr;
X    char        cleanName[MAX_XRMSTRING];
X    char*       lowerCase;
X    XrmQuark    quark;
X    int         i;
X
X    (void)WcCleanName ( string, cleanName );
X    lowerCase = WcLowerCaseCopy ( cleanName );
X    quark = XrmStringToQuark ( lowerCase );
X    XtFree ( lowerCase );
X
X    for (i=0; i<classes_num; i++)
X    {
X        if ( classes_ptr[i].quark == quark )
X        {
X            done( WidgetClass, classes_ptr[i].class );
X        }
X    }
X    XtStringConversionWarning (cleanName, "Object Class, not registered.");
X}
X
X/*
X    -- Convert String To ClassName
X*******************************************************************************
X    This conversion searches the Class Name cache for the appropriate
X    Cache record.  The resource database string is simply the name
X    of the class, case insensitive.  The value provided is the widget 
X    class pointer, as passed to XtCreateWidget().
X*/
X
Xvoid CvtStringToClassName (args, num_args, fromVal, toVal )
X    XrmValue  *args;
X    Cardinal  *num_args;
X    XrmValue  *fromVal;
X    XrmValue  *toVal;
X{
X    char*	string = (char *) fromVal->addr;
X    char	cleanName[MAX_XRMSTRING];
X    char* 	lowerCase;
X    XrmQuark	quark;
X    int		i;
X
X    (void)WcCleanName ( string, cleanName );
X    lowerCase = WcLowerCaseCopy ( cleanName );
X    quark = XrmStringToQuark ( lowerCase );
X    XtFree ( lowerCase );
X
X    for (i=0; i<cl_nm_num; i++)
X    {
X        if ( cl_nm_ptr[i].quark == quark )
X        {
X	    done( WidgetClass, cl_nm_ptr[i].class );
X        }
X    }
X    XtStringConversionWarning (cleanName, "Class Name, not registered.");
X}
X
X/*
X    -- Convert String To Constructor
X*******************************************************************************
X    This conversion searches the Constructor Cache for the appropriate
X    Cache record.  The resource database string is simply the name
X    of the constructor, case insensitive.  The value provided is a
X    Contrstructor Cache Record.  The constructor (func ptr) itself is
X    not provided, as the user of this value (generally WcCreateDatabaseChild)
X    also likes to have the constructor name as registered for error messages.
X*/
X
Xvoid CvtStringToConstructor (args, num_args, fromVal, toVal)
X    XrmValue *args;
X    Cardinal *num_args;
X    XrmValue *fromVal;
X    XrmValue *toVal;
X{
X    char*       string = (char *) fromVal->addr;
X    char        cleanName[MAX_XRMSTRING];
X    char*       lowerCase;
X    XrmQuark    quark;
X    int         i;
X
X    (void)WcCleanName ( string, cleanName );
X    lowerCase = WcLowerCaseCopy ( cleanName );
X    quark = XrmStringToQuark ( lowerCase );
X    XtFree ( lowerCase );
X
X    for (i=0; i<constrs_num; i++)
X    {
X	if ( constrs_ptr[i].quark == quark )
X	{
X	    done( ConCacheRec*, &(constrs_ptr[i]) );
X	}
X    }
X    XtStringConversionWarning (cleanName, "Constructor, not registered.");
X}
X
X/*
X    -- Convert String To Callback
X*******************************************************************************
X    This conversion creates a callback list structure from the X resource
X    database string in format:
X
X    name(arg),name(arg).....
X
X    Note "name" is not case sensitive, while "arg" may be - it is passed to
X    a callback as client data as a null terminated string (first level
X    parenthesis stripped off).  Even if nothing is specified e.g.,
X    SomeCallback() there is a null terminated string passed as client
X    data to the callback.  If it is empty, then it is the null string.
X
X    Note also that the argument CANNOT be converted at this point: frequently,
X    the argument refers to a widget which has not yet been created, or
X    uses the context of the callback (i.e., WcUnmanageCB( this ) uses the
X    widget which invoked the callback).  
X*/
X
Xvoid CvtStringToCallback (args, num_args, fromVal, toVal)
X    XrmValue *args;
X    Cardinal *num_args;
X    XrmValue *fromVal;
X    XrmValue *toVal;
X{
X    typedef struct 
X    {
X	char *nsta,*nend;		/* callback name start, end */
X	char *asta,*aend;		/* argument string start, end */
X    } Segment;
X
X    static XtCallbackRec *cb;
X    XtCallbackRec	  callback_list[MAX_CALLBACKS];
X    int                   callback_num = 0;
X    String                string = (char *) fromVal->addr;
X    Segment               segs[MAX_CALLBACKS];	
X    Segment              *seg;
X    register char        *s;
X    register int          i,ipar;
X
X/*  -- assume error or undefined input argument */
X    toVal->size = 0;
X    toVal->addr = (caddr_t) NULL;
X    if (string == NULL) return;
X
X/*  -- parse input string finding segments   "name(arg)" comma separated */
X    ipar = 0;
X    seg  = segs;
X    seg->nsta = seg->nend = seg->asta = seg->aend = (char*)NULL;
X
X    for ( s=string;  ;  s++ )
X    {
X	switch (*s)
X	{
X        case NUL:
X	case ',':  if ( ipar > 0 ) break;  /* commas in arguments ignored  */
X		   if ( seg->nend == NULL ) seg->nend = s-1;  /* no argument */
X	           seg++;		   /* start the next segment */
X    		   seg->nsta = seg->nend = seg->asta = seg->aend = (char*)NULL;
X		   break;		   
X
X	case '(':  if ( ipar++ == 0 ) { seg->nend = s-1; seg->asta = s+1; };
X	           break;
X		   
X	case ')':  if ( --ipar == 0 ) { seg->aend = s-1; };
X		   break;
X
X	default:   if ( *s > ' '  &&  seg->nsta == NULL )
X			/* only start a new segment on non-blank char */
X	                seg->nsta = s;
X	}
X	if (*s == NUL) break;
X    }
X    seg++;		   /* start the terminating segment */
X    seg->nsta = (char*)NULL;
X
X    if (ipar)
X    {
X	XtStringConversionWarning (string, "Callback, unbalanced parenthesis");
X	return;
X    }
X
X/*  -- process individual callback string segments "name(arg)" */
X    for( seg = segs;  seg->nsta;   seg++)
X    {
X        char           	  cb_name[MAX_XRMSTRING];
X	XtCallbackProc 	  found = (XtCallbackProc)NULL;
X	XrmQuark       	  quark;
X	register char    *d;
X	register char    *end;
X
X	/* our callback cache names are case insensitive, no white space */
X	for ( s=seg->nsta, d=cb_name; s<=seg->nend; )
X	   if ( *s > ' ')
X             *d++ = (isupper(*s) ) ? tolower (*s++) : *s++;
X	   else
X	      s++;
X	*d   = NUL;
X
X        /* try to locate callback in our cache of callbacks */
X        quark = XrmStringToQuark (cb_name);
X	for (i=0; i<callbacks_num; i++)
X	    if ( callbacks_ptr[i].quark == quark )
X	    {
X	        register XtCallbackRec *rec = &callback_list[callback_num];
X		rec->callback = found = callbacks_ptr[i].callback;
X	        rec->closure  = callbacks_ptr[i].closure;
X		break;
X	    }
X
X	/* we have found a registered callback, process arguments */
X	if (found)
X	{
X	   register char *arg;
X	   register int   alen;
X	   register XtCallbackRec *rec = &callback_list[callback_num];
X	   
X	   if ( seg->asta )
X	   {
X	       alen = (int)seg->aend - (int)seg->asta +1;
X	       arg  = XtMalloc(alen+1);
X	       strncpy ( arg, seg->asta, alen );
X	       arg[alen]    = NUL;
X	       rec->closure = (caddr_t)arg;
X	   }
X	   else
X	   {
X	       /* there is always a char[], it may have only a NUL */
X               rec->closure = (caddr_t)"\0";
X	   }
X	   callback_num++;
X        }
X	else
X	{
X           XtStringConversionWarning (cb_name, 
X			"Callback, unknown callback name");
X	}
X    } /* end for seg loop */
X
X/*  -- terminate the callback list */
X    {
X	register XtCallbackRec *rec = &callback_list[callback_num];
X        rec->callback = NULL;
X	rec->closure  = NULL;
X	callback_num++;
X    }
X
X/*  -- make a permanent copy of the new callback list, and return a pointer */
X    cb = (XtCallbackRec*)XtMalloc( callback_num * sizeof (XtCallbackRec) );
X    memcpy ( (char*)cb, (char*)callback_list,  
X              callback_num * sizeof (XtCallbackRec));
X    toVal->size = sizeof (XtCallbackRec*);
X    toVal->addr = (caddr_t)&cb;
X}
X
X/*
X    -- Convert String To Widget
X*******************************************************************************
X    This conversion creates a Widget id from the X resource database string.
X    The conversion will fail, and WcFullNameToWidget() will issue a warning,
X    if the widget so named has not been created when this converter is called.
X    For example, if a widget refers to itself for some reason, during
X    its creation when this converter is called, it is not yet created: 
X    therefore, the converter will fail.
X*/
X
Xvoid XmuCvtStringToWidget (args, num_args, fromVal, toVal)
X    XrmValue *args;
X    Cardinal *num_args;
X    XrmValue *fromVal;
X    XrmValue *toVal;
X{
X    toVal->addr = 
X	(caddr_t) WcFullNameToWidget( WcRootWidget(NULL), fromVal->addr);
X    toVal->size = sizeof(Widget);
X}
X
X#ifdef MOTIF
X/*
X    -- Convert String To MenuWidget
X*******************************************************************************
X    This conversion converts strings into menu widgets for use on
X    cascade button subMenuId resource specifications.
X*/
X
Xvoid CvtStringToMenuWidget (args, num_args, fromVal, toVal)
X    XrmValue *args;
X    Cardinal *num_args;
X    XrmValue *fromVal;
X    XrmValue *toVal;
X{
X    char	cleanName[MAX_XRMSTRING];
X    Widget	widget;
X    Arg		existing[1];
X
X    (void)WcCleanName( fromVal->addr, cleanName );
X
X    widget = WcFullNameToWidget( WcRootWidget(NULL), cleanName );
X
X    if ( widget == NULL )
X    {
X	XtStringConversionWarning (cleanName,
X                "MenuWidget - no such widget.  Misspelled? Forgot the path?");
X	return;
X    }
X    else if ( XmIsRowColumn( widget ) 
X      && (   RC_Type ( (XmRowColumnWidget)widget ) == XmMENU_PULLDOWN
X          || RC_Type ( (XmRowColumnWidget)widget ) == XmMENU_POPUP    ) )
X    {
X	done ( Widget, widget );
X    }
X    XtStringConversionWarning (cleanName, 
X		"MenuWidget - not XmMENU_PULLDOWN or XmMENU_POPUP.");
X}
X#endif MOTIF
X
X/*
X*******************************************************************************
X* Public_function_declarations.
X*******************************************************************************
X*/
X
X/*
X    -- Add String To ... Convertors
X*******************************************************************************
X*/
X
Xvoid WcAddConverters ( unused )
X    XtAppContext unused;	/* maybe someday... */
X{
X    static Boolean added = FALSE;
X    if ( !added++ )
X    {
X
X       XtAddConverter    (XtRString,
X                          WcRClassPtr,
X                          CvtStringToClassPtr,
X                          (XtConvertArgList)NULL,
X                          (Cardinal)0);
X
X       XtAddConverter    (XtRString,
X                          WcRClassName,
X                          CvtStringToClassName,
X                          (XtConvertArgList)NULL,
X                          (Cardinal)0);
X
X       XtAddConverter    (XtRString,
X                          WcRConstructor,
X                          CvtStringToConstructor,
X                          (XtConvertArgList)NULL,
X                          (Cardinal)0);
X
X       XtAddConverter    (XtRString, 
X                          XtRCallback,
X                          CvtStringToCallback,
X                          (XtConvertArgList)NULL,
X                          (Cardinal)0);
X
X#ifndef MOTIF
X       XtAddConverter    (XtRString,
X                          XtRWidget,
X                          XmuCvtStringToWidget,
X                          (XtConvertArgList)NULL,
X                          (Cardinal)0);
X#else
X       XtAddConverter    (XtRString,
X                          WcRWidget,  /* "Window" is wrong, but it works !?! */
X                          XmuCvtStringToWidget,
X                          (XtConvertArgList)NULL,
X                          (Cardinal)0);
X
X       XtAddConverter    (XtRString,
X                          XmRMenuWidget,
X                          CvtStringToMenuWidget,
X                          (XtConvertArgList)NULL,
X                          (Cardinal)0);
X#endif !MOTIF
X    }
X}
+FUNKY+STUFF+
echo '-rw-r--r--  1 david       19854 Jun 28 09:13 WcConverters.c    (as sent)'
chmod u=rw,g=r,o=r WcConverters.c
ls -l WcConverters.c
exit 0

dan
----------------------------------------------------
O'Reilly && Associates   argv at sun.com / argv at ora.com
Opinions expressed reflect those of the author only.



More information about the Comp.sources.x mailing list