david@devvax.Jpl.Nasa.Gov (David E. Smyth) (07/06/90)
Submitted-by: david@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@sun.com / argv@ora.com Opinions expressed reflect those of the author only.