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