david@jpl-devvax.jpl.nasa.gov (David E. Smyth) (12/18/90)
Submitted-by: david@jpl-devvax.jpl.nasa.gov (David E. Smyth) Posting-number: Volume 10, Issue 57 Archive-name: wcl/part09 # to unbundle, "sh" this file -- DO NOT use csh # SHAR archive format. Archive created Fri Oct 19 09:33:17 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 "WcCreate.h" X#include "WcCreateP.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 Xstatic char msg[1024]; X X/* X******************************************************************************* X* Private_function_declarations. X******************************************************************************* X*/ X X#define COMMAS 1 X#define NO_COMMAS 0 X Xstatic char* AllocAndBuildString( params, num_params, commas ) X char *params[]; X int *num_params; X int commas; X{ X char *data; X int len, i; X X for ( len = 0, i = 0; i < *num_params; i++ ) X len += strlen( params[i] ) + 1; X X data = XtMalloc(len + 1); X X (void)strcpy(data, params[0]); X for ( i = 1; i < *num_params; i++ ) X { X if (commas) X strcat(data, ","); X else X strcat(data, " "); X (void)strcat(data, params[i]); X } X return data; X} X Xstatic void SendToCallback( callback, w, params, num_params, min_reqd, commas ) X XtCallbackProc callback; X Widget w; X char *params[]; X int *num_params; X int min_reqd; X int commas; X{ X char* data; X X if ( *num_params < min_reqd ) X { X callback( w, "", NULL ); X return; X } X X data = AllocAndBuildString( params, num_params, commas ); X X callback( w, data, NULL ); X XtFree(data); X} X X/* X******************************************************************************* X* Public_action_function_declarations. X******************************************************************************* X*/ X X/* X -- Create Dynamic Children from Xrm Database X******************************************************************************* X WcCreateChildrenACT( parent, child [, child ... ] ) X*/ Xvoid WcCreateChildrenACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcCreateChildrenCB, w, params, num_params, 2, COMMAS ); X} X X/* X -- Manage or Unmanage named widget(s) X******************************************************************************* X WcManageACT ( widget_path [, widget_path ... ] ) X WcUnmanageACT( widget_path [, widget_path ... ] ) X*/ Xvoid WcManageACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcManageCB, w, params, num_params, 1, COMMAS ); X} X Xvoid WcUnmanageACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcUnmanageCB, w, params, num_params, 1, COMMAS ); X} X X/* X -- Manage or unamange named children action X******************************************************************************* X WcManageChildrenACT ( parent, child [, child ... ] ) X WcUnmanageChildrenACT( parent, child [, child ... ] ) X*/ Xvoid WcManageChildrenACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcManageChildrenCB, w, params, num_params, 2, COMMAS ); X} X Xvoid WcUnmanageChildrenACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcUnmanageChildrenCB, w, params, num_params, 2, COMMAS ); X} X X/* X -- Destroy named children action X******************************************************************************* X WcDestroyACT( widget_path [, widget_path ... ] ) X*/ Xvoid WcDestroyACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcDestroyCB, w, params, num_params, 1, COMMAS ); X} X X/* X -- Set Resource Value on Widget X******************************************************************************* X WcSetValueACT( widget_path.res_name: res_val ) X*/ Xvoid WcSetValueACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X /* note: blanks are optional, so we really don't know how many params X ** we get from the translation manager: anything from 1 to 3. X */ X SendToCallback( WcSetValueCB, w, params, num_params, 1, NO_COMMAS ); X} X X/* X -- Change sensitivity of widgets. X******************************************************************************* X WcSetSensitiveACT ( widget_path [, widget_path ... ] ) X WcSetInsensitiveACT( widget_path [, widget_path ... ] ) X*/ Xvoid WcSetSensitiveACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcSetSensitiveCB, w, params, num_params, 1, COMMAS ); X} X Xvoid WcSetInsensitiveACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcSetInsensitiveCB, w, params, num_params, 1, COMMAS ); X} X X/* X -- Load Resource File X******************************************************************************* X WcLoadResourceFileACT( file_name ) X*/ Xvoid WcLoadResourceFileACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcLoadResourceFileCB, w, params, num_params, 1, COMMAS ); X} X X/* X -- WcTraceAction X******************************************************************************* X WcTraceACT( [ annotation ] ) X*/ Xvoid WcTraceACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcTraceCB, w, params, num_params, 1, COMMAS ); X} X X/* X -- Popup and Popdown named widget X******************************************************************************* X WcPopupACT ( widget_path ) X WcPopupGrabACT( widget_path ) X WcPopdownACT ( widget_path ) X*/ Xvoid WcPopupACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcPopupCB, w, params, num_params, 1, COMMAS ); X} X Xvoid WcPopupGrabACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcPopupGrabCB, w, params, num_params, 1, COMMAS ); X} X Xvoid WcPopdownACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcPopdownCB, w, params, num_params, 1, COMMAS ); X} X X/* X -- Map and Unmap named widget X******************************************************************************* X WcMapACT ( widget_path ) X WcUnmapACT( widget_path ) X*/ Xvoid WcMapACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcMapCB, w, params, num_params, 1, COMMAS ); X} X Xvoid WcUnmapACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcUnmapCB, w, params, num_params, 1, COMMAS ); X} X X/* X -- Invoke shell command X******************************************************************************* X WcSystemACT( any shell command line ) X*/ Xvoid WcSystemACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcSystemCB, w, params, num_params, 1, NO_COMMAS ); X} X X/* X -- Exit the application X******************************************************************************* X WcExitACT( [ integer_exit_code ] ) X*/ Xvoid WcExitACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcExitCB, w, params, num_params, 1, COMMAS ); 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 {"WcMapACT", WcMapACT }, X {"WcUnmapACT", WcUnmapACT }, X {"WcSystemACT", WcSystemACT }, X {"WcExitACT", WcExitACT }, X }; X X ONCE_PER_XtAppContext( app ); X X XtAppAddActions(app, WcActions, XtNumber(WcActions)); X} +FUNKY+STUFF+ echo '-rw-r--r-- 1 david 12898 Oct 18 17:06 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 Aug 6 09:36 WcAthenaP.h (as sent)' chmod u=rw,g=r,o=r WcAthenaP.h ls -l WcAthenaP.h echo x - WcCallb.c sed 's/^X//' > WcCallb.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: @(#)WcCallb.c 1.04 ( 30 September 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* WcLoadResourceFileCB enhanced to remember which resource files have X* been loaded (by resource file name, not complete path name). 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 "WcCreate.h" X#include "WcCreateP.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 performance 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 Dynamically Created 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 because it was not included in a wcChildren X resource value. 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 WcCreateNamedChildren ( 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 int 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 -- Parse name_res_resVal into name, res, resVal X******************************************************************************* X This is a private function to WcSetValueCB() X*/ X Xstatic void XParseNameResResVal( name_res_resVal, target_name, resource, res_val ) X char* name_res_resVal; /* input */ X char* target_name; /* output */ X char* resource; /* output */ X char* res_val; /* output */ X{ X register char *d,*s; 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 the NUL terminator. X */ X for (s++ ; *s && *s <= ' ' ; s++ ) X ; /* skip initial whitespace */ X for (d = res_val ; *s ; s++, d++ ) X *d = *s; X do X *d = NUL; /* null terminate, delete trailing whitespace */ X while (*--d <= ' '); 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 Just about everything this function does is related to providing X nice error messages. 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 Widget res_widget; X char* res_type; /* must be XtFree'd */ X X ParseNameResResVal( name_res_resVal, target_name, resource, res_val ); 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) missing = "target_widget_name"; X else if (resource[0] == NUL) missing = "res_name"; X else if (res_val[0] == NUL) missing = "res_value"; 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, missing ); X XtWarning( msg ); X return; X } X X /* See if we can find the target widget */ X if (! (target = WcFullNameToWidget( w, target_name )) ) 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 /* Make certain widget has this resource type */ X if (! (res_type = WcGetResourceType( target, resource )) ) X { X sprintf ( msg, X "WcSetValueCB (%s) - Failed \n\ X Usage: WcSetValueCB( target_widget_name.res_name: res_value ) \n\ X Problem: widget %s does not have a resource named %s.", X name_res_resVal, target_name, resource); X XtWarning(msg); X return; X } X X /* Try this heuristic: if the resource type has "Widget" somewhere within X ** it, then see if we can convert the resource value to a widget using X ** WcFullNameToWidget. This allow relative naming from the calling X ** widget, including `this' or ^^foobar. X ** WcStrStr( res_type, "Widget") returns NULL if "Widget" is not in res_type X */ X if ( WcStrStr( res_type, "Widget") X#ifdef MOTIF X || WcStrStr( res_type, "Window") /* wrong: but that's a menuWidget */ X#endif X ) X { X Widget res_widget; X Arg arg[1]; X X if (res_widget = WcFullNameToWidget( w, res_val )) X { X XtSetArg( arg[0], resource, res_widget); X XtSetValues( target, arg, 1 ); X return; X } X } X X /* We have the type, so do conversion, and then call XtSetValues. */ X X WcSetValueFromStringAndType( target, resource, res_val, res_type ); X XtFree( res_type ); 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 int 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 keeps X track of each filename. Note that I do not allow a file to be X re-loaded even if it is changed, or if a new file of the same X name appears on the search path. This was done for two reasons: X first, it makes the code more portable, as I don't have to depend X upon various system calls. Second, resources can't be un-written, X so a user might get the wrong impression that a resource specification X can be deleted, and the resource file re-loaded, and something will X happen. It just isn't so. 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]; /* so not on stack */ X XrmQuark nameQ; X static XrmQuark nameQuarks[MAX_RES_FILES]; /* initially all 0 */ X int i; X char* path; X static char filename[MAX_PATHNAME]; /* so not on stack */ X XrmDatabase rdb; X Display* dpy = XtDisplay(w); X extern char* getenv(); X Boolean found = FALSE; 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/* -- check for repeated load, remember if first load */ X nameQ = XrmStringToQuark( name ); X i = 0; X while ( nameQuarks[i] && i < MAX_RES_FILES ) X { X if ( nameQuarks[i] == nameQ ) X return; /* NB: not an error, its even common */ X else X i++; X } X nameQuarks[i] = nameQ; 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/* 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 XtGrabNone 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", XtGrabNone ); 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 -- Map and Unmap named widget X******************************************************************************* X These callbacks translate a string passed as client data into a widget id X and invokes either XtMapWidget() os XtUnmapWidget() as appropriate. X*/ X Xvoid WcMapCB (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 XtMapWidget ( widget ); X } X else X { X sprintf( msg, X "WcMapCB (%s) Failed \n\ X Usage: WcMapCB (shell_widget_name) \n\ X Problem: `%s' is not a shell widget.", X name, cleanName); X XtWarning( msg ); X } X} X Xvoid WcUnmapCB (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 XtUnmapWidget ( widget ); X } X else X { X sprintf( msg, X "WcUnmapCB (%s) Failed \n\ X Usage: WcUnmapCB (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 /* ONCE_PER_XtAppContext( app ); */ X static int already = 0; 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( "WcMapCB", WcMapCB ); X RCALL( "WcUnmapCB", WcUnmapCB ); X RCALL( "WcSystemCB", WcSystemCB ); X RCALL( "WcExitCB", WcExitCB ); X X#undef CALLBACK X} +FUNKY+STUFF+ echo '-rw-r--r-- 1 david 34636 Oct 16 14:35 WcCallb.c (as sent)' chmod u=rw,g=r,o=r WcCallb.c ls -l WcCallb.c exit 0 From david@jpl-devvax.jpl.nasa.gov Tue Oct 23 13:05:49 1990 Return-Path: <david@jpl-devvax.jpl.nasa.gov> Received: from snail.Sun.COM (snail.Corp.Sun.COM) by turnpike.Eng.Sun.COM (4.0/SMI-4.0) id AA20479; Tue, 23 Oct 90 13:05:42 PDT Received: from Sun.COM (sun-barr) by snail.Sun.COM (4.1/SMI-4.1) id AA04721; Tue, 23 Oct 90 13:05:39 PDT Received: from uunet.uu.net by Sun.COM (4.1/SMI-4.1) id AA22788; Tue, 23 Oct 90 13:05:31 PDT Received: from jato.jpl.nasa.gov by uunet.uu.net (5.61/1.14) with SMTP id AA02157; Tue, 23 Oct 90 16:04:56 -0400 Received: from devvax.Jpl.Nasa.Gov (jpl-devvax.jpl.nasa.gov) by jato.Jpl.Nasa.Gov (4.1/SMI-4.1+DXRm2.2) id AA24063; Tue, 23 Oct 90 11:14:12 PDT Received: by devvax.Jpl.Nasa.Gov (5.61/4.7) id AA03909; Tue, 23 Oct 90 10:25:57 -0700 From: david@jpl-devvax.jpl.nasa.gov (David E. Smyth) Message-Id: <9010231725.AA03909@devvax.Jpl.Nasa.Gov> To: comp-sources-x@uunet.uu.net Subject: Widget Creation Library - part08 of 11 Status: OS # to unbundle, "sh" this file -- DO NOT use csh # SHAR archive format. Archive created Fri Oct 19 09:33:17 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 "WcCreate.h" X#include "WcCreateP.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 Xstatic char msg[1024]; X X/* X******************************************************************************* X* Private_function_declarations. X******************************************************************************* X*/ X X#define COMMAS 1 X#define NO_COMMAS 0 X Xstatic char* AllocAndBuildString( params, num_params, commas ) X char *params[]; X int *num_params; X int commas; X{ X char *data; X int len, i; X X for ( len = 0, i = 0; i < *num_params; i++ ) X len += strlen( params[i] ) + 1; X X data = XtMalloc(len + 1); X X (void)strcpy(data, params[0]); X for ( i = 1; i < *num_params; i++ ) X { X if (commas) X strcat(data, ","); X else X strcat(data, " "); X (void)strcat(data, params[i]); X } X return data; X} X Xstatic void SendToCallback( callback, w, params, num_params, min_reqd, commas ) X XtCallbackProc callback; X Widget w; X char *params[]; X int *num_params; X int min_reqd; X int commas; X{ X char* data; X X if ( *num_params < min_reqd ) X { X callback( w, "", NULL ); X return; X } X X data = AllocAndBuildString( params, num_params, commas ); X X callback( w, data, NULL ); X XtFree(data); X} X X/* X******************************************************************************* X* Public_action_function_declarations. X******************************************************************************* X*/ X X/* X -- Create Dynamic Children from Xrm Database X******************************************************************************* X WcCreateChildrenACT( parent, child [, child ... ] ) X*/ Xvoid WcCreateChildrenACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcCreateChildrenCB, w, params, num_params, 2, COMMAS ); X} X X/* X -- Manage or Unmanage named widget(s) X******************************************************************************* X WcManageACT ( widget_path [, widget_path ... ] ) X WcUnmanageACT( widget_path [, widget_path ... ] ) X*/ Xvoid WcManageACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcManageCB, w, params, num_params, 1, COMMAS ); X} X Xvoid WcUnmanageACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcUnmanageCB, w, params, num_params, 1, COMMAS ); X} X X/* X -- Manage or unamange named children action X******************************************************************************* X WcManageChildrenACT ( parent, child [, child ... ] ) X WcUnmanageChildrenACT( parent, child [, child ... ] ) X*/ Xvoid WcManageChildrenACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcManageChildrenCB, w, params, num_params, 2, COMMAS ); X} X Xvoid WcUnmanageChildrenACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcUnmanageChildrenCB, w, params, num_params, 2, COMMAS ); X} X X/* X -- Destroy named children action X******************************************************************************* X WcDestroyACT( widget_path [, widget_path ... ] ) X*/ Xvoid WcDestroyACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcDestroyCB, w, params, num_params, 1, COMMAS ); X} X X/* X -- Set Resource Value on Widget X******************************************************************************* X WcSetValueACT( widget_path.res_name: res_val ) X*/ Xvoid WcSetValueACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X /* note: blanks are optional, so we really don't know how many params X ** we get from the translation manager: anything from 1 to 3. X */ X SendToCallback( WcSetValueCB, w, params, num_params, 1, NO_COMMAS ); X} X X/* X -- Change sensitivity of widgets. X******************************************************************************* X WcSetSensitiveACT ( widget_path [, widget_path ... ] ) X WcSetInsensitiveACT( widget_path [, widget_path ... ] ) X*/ Xvoid WcSetSensitiveACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcSetSensitiveCB, w, params, num_params, 1, COMMAS ); X} X Xvoid WcSetInsensitiveACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcSetInsensitiveCB, w, params, num_params, 1, COMMAS ); X} X X/* X -- Load Resource File X******************************************************************************* X WcLoadResourceFileACT( file_name ) X*/ Xvoid WcLoadResourceFileACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcLoadResourceFileCB, w, params, num_params, 1, COMMAS ); X} X X/* X -- WcTraceAction X******************************************************************************* X WcTraceACT( [ annotation ] ) X*/ Xvoid WcTraceACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcTraceCB, w, params, num_params, 1, COMMAS ); X} X X/* X -- Popup and Popdown named widget X******************************************************************************* X WcPopupACT ( widget_path ) X WcPopupGrabACT( widget_path ) X WcPopdownACT ( widget_path ) X*/ Xvoid WcPopupACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcPopupCB, w, params, num_params, 1, COMMAS ); X} X Xvoid WcPopupGrabACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcPopupGrabCB, w, params, num_params, 1, COMMAS ); X} X Xvoid WcPopdownACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcPopdownCB, w, params, num_params, 1, COMMAS ); X} X X/* X -- Map and Unmap named widget X******************************************************************************* X WcMapACT ( widget_path ) X WcUnmapACT( widget_path ) X*/ Xvoid WcMapACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcMapCB, w, params, num_params, 1, COMMAS ); X} X Xvoid WcUnmapACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcUnmapCB, w, params, num_params, 1, COMMAS ); X} X X/* X -- Invoke shell command X******************************************************************************* X WcSystemACT( any shell command line ) X*/ Xvoid WcSystemACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcSystemCB, w, params, num_params, 1, NO_COMMAS ); X} X X/* X -- Exit the application X******************************************************************************* X WcExitACT( [ integer_exit_code ] ) X*/ Xvoid WcExitACT( w, event, params, num_params ) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X SendToCallback( WcExitCB, w, params, num_params, 1, COMMAS ); 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 {"WcMapACT", WcMapACT }, X {"WcUnmapACT", WcUnmapACT }, X {"WcSystemACT", WcSystemACT }, X {"WcExitACT", WcExitACT }, X }; X X ONCE_PER_XtAppContext( app ); X X XtAppAddActions(app, WcActions, XtNumber(WcActions)); X} +FUNKY+STUFF+ echo '-rw-r--r-- 1 david 12898 Oct 18 17:06 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 Aug 6 09:36 WcAthenaP.h (as sent)' chmod u=rw,g=r,o=r WcAthenaP.h ls -l WcAthenaP.h echo x - WcCallb.c sed 's/^X//' > WcCallb.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: @(#)WcCallb.c 1.04 ( 30 September 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* WcLoadResourceFileCB enhanced to remember which resource files have X* been loaded (by resource file name, not complete path name). 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 "WcCreate.h" X#include "WcCreateP.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 performance 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 Dynamically Created 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 because it was not included in a wcChildren X resource value. 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 WcCreateNamedChildren ( 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 int 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 -- Parse name_res_resVal into name, res, resVal X******************************************************************************* X This is a private function to WcSetValueCB() X*/ X Xstatic void XParseNameResResVal( name_res_resVal, target_name, resource, res_val ) X char* name_res_resVal; /* input */ X char* target_name; /* output */ X char* resource; /* output */ X char* res_val; /* output */ X{ X register char *d,*s; 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 the NUL terminator. X */ X for (s++ ; *s && *s <= ' ' ; s++ ) X ; /* skip initial whitespace */ X for (d = res_val ; *s ; s++, d++ ) X *d = *s; X do X *d = NUL; /* null terminate, delete trailing whitespace */ X while (*--d <= ' '); 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 Just about everything this function does is related to providing X nice error messages. 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 Widget res_widget; X char* res_type; /* must be XtFree'd */ X X ParseNameResResVal( name_res_resVal, target_name, resource, res_val ); 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) missing = "target_widget_name"; X else if (resource[0] == NUL) missing = "res_name"; X else if (res_val[0] == NUL) missing = "res_value"; 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, missing ); X XtWarning( msg ); X return; X } X X /* See if we can find the target widget */ X if (! (target = WcFullNameToWidget( w, target_name )) ) 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 /* Make certain widget has this resource type */ X if (! (res_type = WcGetResourceType( target, resource )) ) X { X sprintf ( msg, X "WcSetValueCB (%s) - Failed \n\ X Usage: WcSetValueCB( target_widget_name.res_name: res_value ) \n\ X Problem: widget %s does not have a resource named %s.", X name_res_resVal, target_name, resource); X XtWarning(msg); X return; X } X X /* Try this heuristic: if the resource type has "Widget" somewhere within X ** it, then see if we can convert the resource value to a widget using X ** WcFullNameToWidget. This allow relative naming from the calling X ** widget, including `this' or ^^foobar. X ** WcStrStr( res_type, "Widget") returns NULL if "Widget" is not in res_type X */ X if ( WcStrStr( res_type, "Widget") X#ifdef MOTIF X || WcStrStr( res_type, "Window") /* wrong: but that's a menuWidget */ X#endif X ) X { X Widget res_widget; X Arg arg[1]; X X if (res_widget = WcFullNameToWidget( w, res_val )) X { X XtSetArg( arg[0], resource, res_widget); X XtSetValues( target, arg, 1 ); X return; X } X } X X /* We have the type, so do conversion, and then call XtSetValues. */ X X WcSetValueFromStringAndType( target, resource, res_val, res_type ); X XtFree( res_type ); 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 int 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 keeps X track of each filename. Note that I do not allow a file to be X re-loaded even if it is changed, or if a new file of the same X name appears on the search path. This was done for two reasons: X first, it makes the code more portable, as I don't have to depend X upon various system calls. Second, resources can't be un-written, X so a user might get the wrong impression that a resource specification X can be deleted, and the resource file re-loaded, and something will X happen. It just isn't so. 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]; /* so not on stack */ X XrmQuark nameQ; X static XrmQuark nameQuarks[MAX_RES_FILES]; /* initially all 0 */ X int i; X char* path; X static char filename[MAX_PATHNAME]; /* so not on stack */ X XrmDatabase rdb; X Display* dpy = XtDisplay(w); X extern char* getenv(); X Boolean found = FALSE; 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/* -- check for repeated load, remember if first load */ X nameQ = XrmStringToQuark( name ); X i = 0; X while ( nameQuarks[i] && i < MAX_RES_FILES ) X { X if ( nameQuarks[i] == nameQ ) X return; /* NB: not an error, its even common */ X else X i++; X } X nameQuarks[i] = nameQ; 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/* 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 XtGrabNone 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", XtGrabNone ); 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 -- Map and Unmap named widget X******************************************************************************* X These callbacks translate a string passed as client data into a widget id X and invokes either XtMapWidget() os XtUnmapWidget() as appropriate. X*/ X Xvoid WcMapCB (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 XtMapWidget ( widget ); X } X else X { X sprintf( msg, X "WcMapCB (%s) Failed \n\ X Usage: WcMapCB (shell_widget_name) \n\ X Problem: `%s' is not a shell widget.", X name, cleanName); X XtWarning( msg ); X } X} X Xvoid WcUnmapCB (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 XtUnmapWidget ( widget ); X } X else X { X sprintf( msg, X "WcUnmapCB (%s) Failed \n\ X Usage: WcUnmapCB (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 /* ONCE_PER_XtAppContext( app ); */ X static int already = 0; 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( "WcMapCB", WcMapCB ); X RCALL( "WcUnmapCB", WcUnmapCB ); X RCALL( "WcSystemCB", WcSystemCB ); X RCALL( "WcExitCB", WcExitCB ); X X#undef CALLBACK X} +FUNKY+STUFF+ echo '-rw-r--r-- 1 david 34636 Oct 16 14:35 WcCallb.c (as sent)' chmod u=rw,g=r,o=r WcCallb.c ls -l WcCallb.c exit 0 dan ---------------------------------------------------- O'Reilly && Associates argv@sun.com / argv@ora.com Opinions expressed reflect those of the author only. -- dan ---------------------------------------------------- O'Reilly && Associates argv@sun.com / argv@ora.com Opinions expressed reflect those of the author only.