v10i059: wcl -- Widget Creation Library, Part11/11
David E. Smyth
david at jpl-devvax.jpl.nasa.gov
Tue Dec 18 13:06:07 AEST 1990
Submitted-by: david at jpl-devvax.jpl.nasa.gov (David E. Smyth)
Posting-number: Volume 10, Issue 59
Archive-name: wcl/part11
# to unbundle, "sh" this file -- DO NOT use csh
# SHAR archive format. Archive created Fri Oct 19 09:33:30 PDT 1990
echo x - WcCreateP.h
sed 's/^X//' > WcCreateP.h <<'+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: @(#)WcCreateP.h 1.03 ( 13 July 1990 )
X*
X* Include_name:
X*
X* WcCreateP.h
X*
X* Subsystem_group:
X*
X* Widget Creation Library
X*
X* Include_description:
X*
X* Private defines for the Widget Creation Library supporting widget
X* tree creation from the Xrm database.
X*
X* Include_history:
X*
X* mm/dd/yy initials action
X* -------- -------- -------------------------------------------------------
X* 06/30/90 R.Whitby added Action declarations
X* 05/24/90 D.Smyth created from provate section of WsCreate.h
X* 03/02/90 marbru created
X*
X*******************************************************************************
X*/
X#ifndef _WcCreateP_h
X#define _WcCreateP_h
X
X/*
X*******************************************************************************
X* Private_constant_declarations.
X*******************************************************************************
X*/
X#undef NUL
X#define NUL '\0'
X#define MAX_XRMSTRING 4096 /* max length of the Xrm DB string */
X#define MAX_ERRMSG 1024 /* max length of error message */
X#define MAX_CHILDREN 1024 /* max number of widget's children */
X#define MAX_PATHNAME 1024 /* max length of the pathname */
X#define INCR_REGISTRY 32 /* incr of cl, con, cb registries */
X#define MAX_CALLBACKS 64 /* max callbacks per Xrm resource */
X#define MAX_WIDGETS 512 /* max depth of a widget tree */
X#define MAX_ROOT_WIDGETS 32 /* max # separate widget trees */
X#define MAX_RES_FILES 512 /* max # res file names per interf */
X
X#define WcNwcResFile "wcResFile"
X#define WcNwcChildren "wcChildren"
X#define WcNwcClass "wcClass"
X#define WcNwcClassName "wcClassName"
X#define WcNwcConstructor "wcConstructor"
X#define WcNwcManaged "wcManaged"
X#define WcNwcTrace "wcTrace"
X#define WcNwcCallback "wcCallback"
X
X#define WcCWcResFile "WcResFile"
X#define WcCWcChildren "WcChildren"
X#define WcCWcClass "WcClass"
X#define WcCWcClassName "WcClassName"
X#define WcCWcConstructor "WcConstructor"
X#define WcCWcManaged "WcManaged"
X#define WcCWcTrace "WcTrace"
X#define WcCWcCallback "WcCallback"
X
X/* Motif 1.0 has a bug: widgets ask for Windows
X** instead of Widgets for their resources...
X*/
X#define WcRWidget "Window"
X#define WcRClassPtr "ClassPtr"
X#define WcRClassName "ClassName"
X#define WcRConstructor "Constructor"
X/*
X*******************************************************************************
X* Private_type_declarations.
X*******************************************************************************
X*/
X
Xtypedef Widget (*PtrFuncWidget)(); /* ptr to func returning Widget */
X
X/* Registration structs: It is a good idea if the classes, class names,
X** constructors, and callbacks are registered with the same upper & lower
X** case names as the names in the ref manuals and source files, as this
X** makes the user error messages clearer.
X*/
X
Xtypedef struct /* Class cache record */
X{
X String name; /* class ptr name as registered */
X XrmQuark quark; /* quarkified class ptr name */
X WidgetClass class; /* widget class pointer */
X} ClCacheRec;
X
Xtypedef struct /* Class Name cache record */
X{
X String name; /* class name as registered */
X XrmQuark quark; /* quarkified class name */
X WidgetClass class; /* widget class pointer */
X} ClNameCacheRec;
X
Xtypedef struct /* Constructor cache record */
X{
X String name; /* constructor as registered */
X XrmQuark quark; /* quarkified constructor name */
X Widget (*constructor)(); /* constructor function ptr */
X} ConCacheRec;
X
Xtypedef struct /* Callback cache record */
X{
X String name; /* name as registered */
X XrmQuark quark; /* quarkified callback name */
X XtCallbackProc callback; /* callback procedure pointer */
X caddr_t closure; /* default client data */
X} CBCacheRec;
X
Xtypedef struct _ResourceRec
X{
X String resFile; /* additional resource file name */
X String children; /* list of children names to create */
X WidgetClass class; /* widget class pointer */
X WidgetClass classFromName; /* widget class pointer */
X ConCacheRec* constructor; /* ptr to Constructo cache record */
X Boolean managed; /* created managed (default TRUE) */
X Boolean deferred; /* deferred creation, (def FALSE) */
X Boolean trace; /* creation trace required */
X XtCallbackList callback; /* creation callback list */
X} ResourceRec, *ResourceRecPtr;
X
X/*
X*******************************************************************************
X* Private_macro_definitions.
X*******************************************************************************
X*/
X
X#define ONCE_PER_XtAppContext( app ) \
X{ \
X static XtAppContext already[1024]; \
X static int apps = 0; \
X int i; \
X \
X for (i = 0; i < apps ; i++) \
X if (already[i]) \
X return; \
X \
X already[++apps] = app; \
X}
X
X/*
X*******************************************************************************
X* Private_data_definitions.
X*******************************************************************************
X The following cache/registry of known widget classes and contructors,
X initially empty, are loaded by the application using "registration"
X routines.
X Assuming small numbers of constructors, the sequential search
X of such cache is (initially) considered acceptable.
X*/
X
X/* -- Named class pointer cache, intially empty */
X
Xextern int classes_num;
Xextern int classes_max;
Xextern ClCacheRec* classes_ptr;
X
X/* -- Class name cache, intially empty */
X
Xextern int cl_nm_num;
Xextern int cl_nm_max;
Xextern ClNameCacheRec* cl_nm_ptr;
X
X/* -- Named object constructor cache, intially empty */
X
Xextern int constrs_num;
Xextern int constrs_max;
Xextern ConCacheRec* constrs_ptr;
X
X/* -- Callback function cache, initially empty */
X
Xextern int callbacks_num;
Xextern int callbacks_max;
Xextern CBCacheRec* callbacks_ptr;
X/* -- Widget Creation resources */
X
Xextern XtResource wc_resources[];
X
X/*
X*******************************************************************************
X* Private_function_declarations.
X*******************************************************************************
X The following functions are generally private functions to the
X WcCreate routines, but they may be defined in different files from
X where they are used. Client programs probably should not invoke
X these functions directly.
X*/
X
X#ifdef FUNCTION_PROTOTYPES
X/****************************** ANSI FUNC DECLS ******************************/
X
X#define EV extern void
X
X/* -- Resource converters */
X
XEV WcAddConverters ( XtAppContext );
XEV CvtStringToClassPtr ( XrmValue*, Cardinal*, XrmValue*, XrmValue* );
XEV CvtStringToClassName ( XrmValue*, Cardinal*, XrmValue*, XrmValue* );
XEV CvtStringToConstructor ( XrmValue*, Cardinal*, XrmValue*, XrmValue* );
XEV CvtStringToCallback ( XrmValue*, Cardinal*, XrmValue*, XrmValue* );
XEV CvtStringToWidget ( XrmValue*, Cardinal*, XrmValue*, XrmValue* );
X
X/* -- Find root widget of argument, remember if never seen before */
X
Xextern Widget WcRootWidget ( Widget );
X
X/* -- Convenience Callbacks - Clients generally invoke these only
X by binding them to widgets via the resource file. They can
X be programmatically bound, but generally should not be.
X*/
X
XEV WcCreateChildrenCB (Widget w, char* parent_children, caddr_t unused );
XEV WcManageCB (Widget w, char* widgetNames, caddr_t unused );
XEV WcUnmanageCB (Widget w, char* widgetNames, caddr_t unused );
XEV WcManageChildrenCB (Widget w, char* parent_children, caddr_t unused );
XEV WcUnmanageChildrenCB (Widget w, char* parent_children, caddr_t unused );
XEV WcDestroyCB (Widget w, char* widgetNames, caddr_t unused );
XEV WcSetValueCB (Widget w, char* name_res_resVal, caddr_t unused );
XEV WcSetSensitiveCB (Widget w, char* widgetNames, caddr_t unused );
XEV WcSetInsensitiveCB (Widget w, char* widgetNames, caddr_t unused );
XEV WcLoadResourceFileCB (Widget w, char* resFileName, caddr_t unused );
XEV WcTraceCB (Widget w, char* annotation, caddr_t unused );
XEV WcPopupCB (Widget w, char* widgetName, caddr_t unused );
XEV WcPopupGrabCB (Widget w, char* widgetName, caddr_t unused );
XEV WcPopdownCB (Widget w, char* widgetName, caddr_t unused );
XEV WcMapCB (Widget w, char* widgetName, caddr_t unused );
XEV WcUnmapCB (Widget w, char* widgetName, caddr_t unused );
XEV WcSystemCB (Widget w, char* shellCmdString, caddr_t unused );
XEV WcExitCB (Widget w, char* exitValue, caddr_t unused );
X
X/* -- Convenience Actions - Clients generally invoke these only
X by binding them to widgets via the resource file. They can
X be programmatically bound, but generally should not be.
X*/
X
X#define ACT_ARGS Widget w, XEvent *event, String *params, Cardinal *num_params
X
XEV WcCreateChildrenACT ( ACT_ARGS );
XEV WcManageACT ( ACT_ARGS );
XEV WcUnmanageACT ( ACT_ARGS );
XEV WcManageChildrenACT ( ACT_ARGS );
XEV WcUnmanageChildrenACT ( ACT_ARGS );
XEV WcDestroyACT ( ACT_ARGS );
XEV WcSetValueACT ( ACT_ARGS );
XEV WcSetSensitiveACT ( ACT_ARGS );
XEV WcSetInsensitiveACT ( ACT_ARGS );
XEV WcLoadResourceFileACT ( ACT_ARGS );
XEV WcTraceACT ( ACT_ARGS );
XEV WcPopupACT ( ACT_ARGS );
XEV WcPopupGrabACT ( ACT_ARGS );
XEV WcPopdownACT ( ACT_ARGS );
XEV WcMapACT ( ACT_ARGS );
XEV WcUnmapACT ( ACT_ARGS );
XEV WcSystemACT ( ACT_ARGS );
XEV WcExitACT ( ACT_ARGS );
X
X#undef ACT_ARGS
X#undef EV
X
X#else
X/**************************** NON-ANSI FUNC DECLS ****************************/
X
X/* -- Resource converters */
X
Xextern void WcAddConverters ();
Xextern void CvtStringToClassPtr ();
Xextern void CvtStringToClassName ();
Xextern void CvtStringToConstructor ();
Xextern void CvtStringToCallback ();
Xextern void CvtStringToWidget ();
X
X/* -- Find root widget of argument, remember if never seen before */
X
Xextern Widget WcRootWidget ();
X
X/* -- Convenience Callbacks - Clients generally invoke these only
X by binding them to widgets via the resource file. They can
X be programmatically bound, but generally should not be.
X*/
X
Xextern void WcCreateChildrenCB ();
Xextern void WcManageCB ();
Xextern void WcUnmanageCB ();
Xextern void WcManageChildrenCB ();
Xextern void WcUnmanageChildrenCB ();
Xextern void WcDestroyCB ();
Xextern void WcSetValueCB ();
Xextern void WcSetSensitiveCB ();
Xextern void WcSetInsensitiveCB ();
Xextern void WcLoadResourceFileCB ();
Xextern void WcTraceCB ();
Xextern void WcPopupCB ();
Xextern void WcPopupGrabCB ();
Xextern void WcPopdownCB ();
Xextern void WcMapCB ();
Xextern void WcUnmapCB ();
Xextern void WcSystemCB ();
Xextern void WcExitCB ();
X
X/* -- Convenience Actions - Clients generally invoke these only
X by binding them to widgets via the resource file. They can
X be programmatically bound, but generally should not be.
X*/
X
Xextern void WcCreateChildrenACT ();
Xextern void WcManageACT ();
Xextern void WcUnmanageACT ();
Xextern void WcManageChildrenACT ();
Xextern void WcUnmanageChildrenACT ();
Xextern void WcDestroyACT ();
Xextern void WcSetValueACT ();
Xextern void WcSetSensitiveACT ();
Xextern void WcSetInsensitiveACT ();
Xextern void WcLoadResourceFileACT ();
Xextern void WcTraceACT ();
Xextern void WcPopupACT ();
Xextern void WcPopupGrabACT ();
Xextern void WcPopdownACT ();
Xextern void WcMapACT ();
Xextern void WcUnmapACT ();
Xextern void WcSystemACT ();
Xextern void WcExitACT ();
X
X#endif /* FUNCTION_PROTOTYPES */
X
X#ifdef DEBUG
X#ifdef MOTIF
X#include "WcMotifP.h"
X#else
X#include "WcAthenaP.h"
X#endif
X#endif
X
X#endif /* _WcCreateP_h */
+FUNKY+STUFF+
echo '-rw-r--r-- 1 david 14725 Oct 16 14:38 WcCreateP.h (as sent)'
chmod u=rw,g=r,o=r WcCreateP.h
ls -l WcCreateP.h
echo x - WcMotifP.h
sed 's/^X//' > WcMotifP.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: @(#)WcMotifP.h 1.0 ( 19 June 1990 )
X*/
X
X#ifndef _WcMotifP_h_
X#define _WcMotifP_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 <Xm/XmP.h>
X
X/* XmGadget Subclasses
X*/
X#include <Xm/ArrowBGP.h>
X#include <Xm/SeparatoGP.h>
X#include <Xm/LabelGP.h>
X#include <Xm/CascadeBGP.h>
X#include <Xm/PushBGP.h>
X#include <Xm/ToggleBGP.h>
X
X/* XmPrimitive Subclasses
X*/
X#include <Xm/ArrowBP.h>
X#include <Xm/ListP.h>
X#include <Xm/ScrollBarP.h>
X#include <Xm/SeparatorP.h>
X#include <Xm/TextP.h>
X#include <Xm/LabelP.h>
X#include <Xm/CascadeBP.h>
X#include <Xm/DrawnBP.h>
X#include <Xm/PushBP.h>
X#include <Xm/ToggleBP.h>
X
X/* XmManager Subclasses
X*/
X#include <Xm/DrawingAP.h>
X#include <Xm/FrameP.h>
X#include <Xm/PanedWP.h>
X#include <Xm/RowColumnP.h>
X#include <Xm/ScaleP.h>
X#include <Xm/ScrolledWP.h>
X#include <Xm/MainWP.h>
X#include <Xm/BulletinBP.h>
X#include <Xm/FormP.h>
X#include <Xm/MessageBP.h>
X#include <Xm/SelectioBP.h>
X#include <Xm/CommandP.h>
X#include <Xm/FileSBP.h>
X
X/* Shell Subclasses
X*/
X#include <X11/ShellP.h>
X#include <X11/VendorP.h>
X#include <Xm/MenuShellP.h>
X#include <Xm/DialogSP.h>
X
X/* Apparently Obsolete
X*/
X#include <Xm/SashP.h>
X
X#endif
+FUNKY+STUFF+
echo '-rw-r--r-- 1 david 2048 Aug 6 09:36 WcMotifP.h (as sent)'
chmod u=rw,g=r,o=r WcMotifP.h
ls -l WcMotifP.h
echo x - WcName.c
sed 's/^X//' > WcName.c <<'+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: @(#)WcName.c 1.0 ( 19 June 1990 )
X**
X** Description: Implements several name-to-widget and widget-to-name
X** functions which are generally useful, especially a name
X** to widget function which really works:
X**
X** Widget WcFullNameToWidget(char* widget_name)
X**
X** The widget names understood by WcFullNameToWidget() are
X** a superset of those understood by XtNameToWidget in
X** the X11R4 version of libXt. XtNameToWidget only knows
X** how to find children of a reference widget, and so the
X** names start _below- the refernce widget. However,
X** WcFullNameToWidget knows how to find widgets anywhere
X** in the widget tree: it normally starts the name search
X** from the root of the widget tree, but it can also
X** perform the name search relatively from the reference
X** widget, both up and down the widget tree.
X**
X** When name searches start at the root of the widget
X** tree, the same syntax as that understood by Xrm is
X** used. Below are four examples of acceptable names:
X**
X** *foo *foo.XmRowColumn*glorp
X** Mri.some*other.foo *Form.glorp
X**
X** Note that components may be class names, such as
X** XmRowColumn, or may be instance names of the widgets.
X** Ambiguous names are resolved exactly as done by
X** XtNameToWidget: shallowest wins, `.' binds tighter
X** than `*', instance names bind tighter than class
X** names.
X**
X** In addition to resolving names from the root of the
X** widget tree, WcFullNameToWidget also can find widget
X** using a relative root prefix. Three special characters
X** are used:
X**
X** ^ means "parent"
X** ~ means the closest shell ancestor
X** . means start at the reference widget
X**
X** The relative root prefix characters are exactly that:
X** a prefix of a name which will then be passed to
X** XtNameToWidget. Some examples:
X**
X** .foo a child of the reference widget
X** ^foo a sibling of the reference widget
X** ^^foo a sibling of the ref' widgets's parent
X** ~foo a child of the shell ancestor.
X** ~~*foo some child of the shell's shell ancestor.
X**
X** The ^ and ~ prefix characters are only valid at the
X** beginning. They effectively operate on the reference
X** widget.
X**
X** In all cases, the characters are scanned left to right.
X** So, the first character is acted upon, then the second,
X** and so on.
X**
X** Notes: Most of the "private" part of this file goes away when
X** the bug in the Xt Intrinsics is fixed which causes
X** XtNameToWidget() to dump core whenever a Gadget exists
X** in the widget heirarchy...
X**
X******************************************************************************/
X
X/******************************************************************************
X* Include_files.
X******************************************************************************/
X
X#include <ctype.h> /* isupper() and tolower macros */
X
X/* -- X Window System includes */
X#include <X11/StringDefs.h>
X
X#ifdef MOTIF
X#include <Xm/XmP.h>
X#endif
X
X/* -- Widget Creation Library includes */
X#include "WcCreate.h"
X#include "WcCreateP.h"
X
X/*
X*******************************************************************************
X* Private_data_definitions.
X*******************************************************************************
X*/
X
X/* shared error message and name buffers
X*******************************************************************************
X** NOTE: These are shared arrays because they are large: i.e.,
X** this is a performacne optimization intended to reduce page
X** faults which can occur while making large extensions to the
X** stack space. Wait a minute: wouldn't this just happen
X** once, and then the stack space is alloc'd? Yes, but a
X** huge stack space runs the risk of getting swapped, which causes
X** page faults. This is probably a nit-picky sort of optimization.
X** Remember that D.Smyth is an old sys programmer from the stone
X** ages, and pity him instead of flaming him.
X** Be careful when filling msg not to call any funcs in here,
X** so the message does not get garbled.
X*/
X
Xstatic char msg[MAX_ERRMSG];
Xstatic char cleanName[MAX_PATHNAME];
X
X/* Private Data involving the root widget list
X*******************************************************************************
X*/
X
Xstatic int numRoots = 0;
Xstatic Widget rootWidgets[MAX_ROOT_WIDGETS];
X
X/*
X*******************************************************************************
X* Private_function definitions.
X*******************************************************************************
X/*
X The following is the XtGetConstraintResourceList function from
X the R4 Intrinsics. This function is not provided by the Motif
X 1.0 Intrinsics. Only change: ConstraintClassFlag was changed to
X _XtConstraintBit.
X*/
X
X#if defined(MOTIF) && defined(MOTIF_MINOR) && MOTIF == 1 && MOTIF_MINOR == 0
X#include <X11/IntrinsicP.h>
X/*************** Begin source from X11R4 GetResList.c ***************/
X
Xstatic Boolean ClassIsSubclassOf(class, superclass)
X WidgetClass class, superclass;
X{
X for (; class != NULL; class = class->core_class.superclass) {
X if (class == superclass) return True;
X }
X return False;
X}
X
Xvoid XtGetConstraintResourceList(widget_class, resources, num_resources)
X WidgetClass widget_class;
X XtResourceList *resources;
X Cardinal *num_resources;
X{
X int size;
X register int i, dest = 0;
X register XtResourceList *list, dlist;
X ConstraintWidgetClass class = (ConstraintWidgetClass)widget_class;
X
X if ( (class->core_class.class_inited &&
X !(class->core_class.class_inited & _XtConstraintBit)) /* DES */
X || (!class->core_class.class_inited &&
X !ClassIsSubclassOf(widget_class, constraintWidgetClass))
X || class->constraint_class.num_resources == 0) {
X
X *resources = NULL;
X *num_resources = 0;
X return;
X }
X
X size = class->constraint_class.num_resources * sizeof(XtResource);
X *resources = (XtResourceList) XtMalloc((unsigned) size);
X
X if (!class->core_class.class_inited) {
X /* Easy case */
X
X bcopy((char *)class->constraint_class.resources,
X (char *) *resources, size);
X *num_resources = class->constraint_class.num_resources;
X return;
X }
X
X /* Nope, it's the hard case */
X
X list = (XtResourceList *) class->constraint_class.resources;
X dlist = *resources;
X for (i = 0; i < class->constraint_class.num_resources; i++) {
X if (list[i] != NULL) {
X dlist[dest].resource_name = (String)
X XrmQuarkToString((XrmQuark) list[i]->resource_name);
X dlist[dest].resource_class = (String)
X XrmQuarkToString((XrmQuark) list[i]->resource_class);
X dlist[dest].resource_type = (String)
X XrmQuarkToString((XrmQuark) list[i]->resource_type);
X dlist[dest].resource_size = list[i]->resource_size;
X dlist[dest].resource_offset = -(list[i]->resource_offset + 1);
X dlist[dest].default_type = (String)
X XrmQuarkToString((XrmQuark) list[i]->default_type);
X dlist[dest].default_addr = list[i]->default_addr;
X dest++;
X }
X }
X *num_resources = dest;
X}
X
X/*************** End source from X11R4 GetResList.c ***************/
X#endif /* MOTIF 1.0 */
X
X/*
X The following implements XtNameToWidget() in a way which really works.
X
X Note: the #if defined... assumes a FIXED version of R4. The version
X even as of 19 June 1990 still is not correct (dumps core on Gadgets).
X*/
X
X#if defined(XtSpecificationRelease) && XtSpecificationRelease > 4
X
XWidget WcChildNameToWidget( Widget ref, char* childName)
X{
X return XtNameToWidget( ref, childName );
X}
X
X#else
X
X/* NOTE: The Motif 1.0 XtNameToWidget is broken: it cannot find
X** names with wild cards. The R4 XtNameToWidget is also broken: it
X** cannot handle encounters with Gadgets.
X**
X** Below is the code extracted from the X11R4 distribution, with very
X** minor changes to make it independent from the rest of the R4 Intrinsics,
X** and to fix the bug in encountering Gadgets.
X**
X** Fixes: Added the two lines following this comment block.
X** Renamed XtNameToWidget to WcChildNameToWidget to avoid warning.
X** Removed "register" from arg type decls, as dbx does these
X** incorrectly, and a decent compiler (gcc) does this anyway.
X** --> Before looking for children, see if a widget is a gadget.
X** Gadgets can't have children, in fact those fields are
X** something else entirely!!!
X*/
X
X/*************** Begin source from X11R4 Xtos.h ***************/
X
X#ifndef ALLOCATE_LOCAL
X#define ALLOCATE_LOCAL(size) XtMalloc((unsigned long)(size))
X#define DEALLOCATE_LOCAL(ptr) XtFree((caddr_t)(ptr))
X#endif /* ALLOCATE_LOCAL */
X
X/*************** End source from X11R4 Xtos.h ***************/
X
X#define _XtAllocError XtError
X
X/*************** Begin source from X11R4 lib/Xt/Intrinsics.c ***************/
X
Xstatic Widget NameListToWidget();
X
Xtypedef Widget (*NameMatchProc)();
X
Xstatic Widget MatchExactChildren(names, bindings, children, num,
X in_depth, out_depth, found_depth)
X XrmNameList names;
X XrmBindingList bindings;
X WidgetList children;
X int num;
X int in_depth, *out_depth, *found_depth;
X{
X Cardinal i;
X XrmName name = *names;
X Widget w, result = NULL;
X int d, min = 10000;
X
X for (i = 0; i < num; i++) {
X if (name == children[i]->core.xrm_name) {
X w = NameListToWidget(children[i], &names[1], &bindings[1],
X in_depth+1, &d, found_depth);
X if (w != NULL && d < min) {result = w; min = d;}
X }
X }
X *out_depth = min;
X return result;
X}
X
Xstatic Widget MatchWildChildren(names, bindings, children, num,
X in_depth, out_depth, found_depth)
X XrmNameList names;
X XrmBindingList bindings;
X WidgetList children;
X int num;
X int in_depth, *out_depth, *found_depth;
X{
X Cardinal i;
X Widget w, result = NULL;
X int d, min = 10000;
X
X for (i = 0; i < num; i++) {
X w = NameListToWidget(children[i], names, bindings,
X in_depth+1, &d, found_depth);
X if (w != NULL && d < min) {result = w; min = d;}
X }
X *out_depth = min;
X return result;
X}
X
Xstatic Widget SearchChildren(root, names, bindings, matchproc,
X in_depth, out_depth, found_depth)
X Widget root;
X XrmNameList names;
X XrmBindingList bindings;
X NameMatchProc matchproc;
X int in_depth, *out_depth, *found_depth;
X{
X Widget w1, w2;
X int d1, d2;
X
X#if defined(MOTIF) && MOTIF == 1 && MOTIF_MINOR == 0
X if (XmIsGadget(root)) {
X#else
X if (!XtIsWidget(root)) {
X#endif
X *out_depth = 10000; /* I don't know what this should be */
X return (Widget)NULL;
X }
X if (XtIsComposite(root)) {
X w1 = (*matchproc)(names, bindings,
X ((CompositeWidget) root)->composite.children,
X ((CompositeWidget) root)->composite.num_children,
X in_depth, &d1, found_depth);
X } else d1 = 10000;
X w2 = (*matchproc)(names, bindings, root->core.popup_list,
X root->core.num_popups, in_depth, &d2, found_depth);
X *out_depth = (d1 < d2 ? d1 : d2);
X return (d1 < d2 ? w1 : w2);
X}
X
Xstatic Widget NameListToWidget(root, names, bindings,
X in_depth, out_depth, found_depth)
X Widget root;
X XrmNameList names;
X XrmBindingList bindings;
X int in_depth, *out_depth, *found_depth;
X{
X Widget w1, w2;
X int d1, d2;
X
X if (in_depth >= *found_depth) {
X *out_depth = 10000;
X return NULL;
X }
X
X if (names[0] == NULLQUARK) {
X *out_depth = *found_depth = in_depth;
X return root;
X }
X
X if (*bindings == XrmBindTightly) {
X return SearchChildren(root, names, bindings, MatchExactChildren,
X in_depth, out_depth, found_depth);
X
X } else { /* XrmBindLoosely */
X w1 = SearchChildren(root, names, bindings, MatchExactChildren,
X in_depth, &d1, found_depth);
X w2 = SearchChildren(root, names, bindings, MatchWildChildren,
X in_depth, &d2, found_depth);
X *out_depth = (d1 < d2 ? d1 : d2);
X return (d1 < d2 ? w1 : w2);
X }
X} /* NameListToWidget */
X
XWidget WcChildNameToWidget( ref, name ) /* was XtNameToWidget */
X Widget ref;
X char* name;
X{
X XrmName *names;
X XrmBinding *bindings;
X int len, depth, found = 10000;
X Widget result;
X
X len = strlen(name);
X if (len == 0) return NULL;
X
X names = (XrmName *) ALLOCATE_LOCAL((unsigned) (len+1) * sizeof(XrmName));
X bindings = (XrmBinding *)
X ALLOCATE_LOCAL((unsigned) (len+1) * sizeof(XrmBinding));
X if (names == NULL || bindings == NULL) _XtAllocError("alloca");
X
X XrmStringToBindingQuarkList(name, bindings, names);
X if (names[0] == NULLQUARK) {
X DEALLOCATE_LOCAL((char *) names);
X DEALLOCATE_LOCAL((char *) bindings);
X return NULL;
X }
X
X result = NameListToWidget(ref, names, bindings, 0, &depth, &found);
X
X DEALLOCATE_LOCAL((char *) names);
X DEALLOCATE_LOCAL((char *) bindings);
X return result;
X} /* WcChildNameToWidget */
X
X/*************** End of source from X11R4 lib/Xt/Intrinsics.c ***************/
X#endif
X
X/******************************************************************************
X** Public functions
X******************************************************************************/
X
X/*******************************************************************************
X** Allocate and return a lower case copy of the input string.
X** Caller must free output string!
X*******************************************************************************/
X
Xchar* WcLowerCaseCopy( in )
X char* in;
X{
X char* retVal = (char*)XtMalloc( 1 + strlen ( in ) );
X char* cp = retVal;
X
X while (*in)
X {
X *cp = (isupper(*in) ? tolower(*in) : *in );
X cp++ ; in++ ;
X }
X *cp = NUL;
X return retVal;
X}
X
X/******************************************************************************
X** Return "clean" widget name, resource, or value from string
X*******************************************************************************
X This function strips leading and trailing whitespace from the
X passed in char*. Note that the caller must allocate and free
X the returned character buffer.
X******************************************************************************/
X
Xchar* WcSkipWhitespace( cp )
X char* cp;
X{
X while ( *cp && *cp <= ' ' )
X cp++;
X return cp;
X}
X
Xchar* WcSkipWhitespace_Comma( cp )
X char* cp;
X{
X while ( *cp && *cp <= ' ' ) /* cp = WcSkipWhitespace ( cp ); */
X cp++;
X if ( *cp == ',' )
X cp++;
X return cp;
X}
X
Xchar* WcCleanName( in, out )
X char* in;
X char* out;
X{
X /* copy from in[] into out[],
X ** ignore initial whitespace,
X ** stop at trailing whitespace or comma.
X ** Returns pointer to whitespace or comma following name.
X */
X while ( *in && *in <= ' ' ) /* in = WcSkipWhitespace( in ); */
X in++;
X for ( ; (*in > ' ' && *in != ',') ; in++ )
X *out++ = *in;
X *out = NUL;
X return in; /* this points at 1st whitespace or comma following "out" */
X}
X
X/* This function is necessary because XtNameToWidget cannot really
X** take a widget name which begins at the top level shell, but rather
X** only names which pretend the widget BELOW the top level shell is
X** the top level shell. I have no idea why some thought the
X** Xt implementation is correct. Quoting from the Xt manual:
X**
X** XtNameToWidget returns the descendent [of root] ... according to
X** the following rules, ... :
X**
X** o ... qualifying the name of each object with the names of all
X** its ancestors up to _but_not_including_ the reference widget.
X**
X** Since this is not useful for our purposes, we need to first do some
X** screwing around to see if the user specified the widget name like one
X** would specify any other widget name in the resource file.
X*/
X
Xchar* WcStripWhitespaceFromBothEnds( name )
X char* name;
X{
X char* first;
X char* last;
X char* buff;
X char* bp;
X
X for ( first = name ; *first <= ' ' ; first ++ )
X ;
X for ( last = first ; *last ; last++ )
X ;
X for ( last-- ; *last <= ' ' ; last-- )
X ;
X buff = (char*)XtMalloc( (last - first) + 2 );
X for ( bp = buff ; first <= last ; bp++, first++ )
X *bp = *first;
X *bp = NUL;
X
X return buff;
X}
X
X/*
X -- Find the named widget
X*******************************************************************************
X
X This function uses WcChildNameToWidget to search a widget tree for a
X widget with the given name. WcChildNameToWidget is basically
X XtNameToWidget from X11R4, but hacked so it works when there are
X Gadgets in the widget tree.
X
X WcChildNameToWidget, like XtNameToWidget, starts searching for children
X of a reference widget. WcFullNameToWidget examines the first few
X characters of the `name' argument in order to determine which widget is
X the reference whidget where the search will begin.
X
X The possibilities are these: The `name' can begin with one or more of
X the relative prefix characters: ^ or ~, which means the reference
X widget will be some relative node in the widget tree, such as the
X parent or the shell ancestor. Otherwise, the root widget will be the
X starting point.
X*/
X
XWidget WcFullNameToWidget( w, name )
X Widget w;
X char* name;
X{
X Widget retWidget;
X char *widgetName;
X char *lowerName;
X int i;
X
X widgetName = WcStripWhitespaceFromBothEnds( name ); /* must be XtFree'd */
X
X if ( widgetName[0] == '*' )
X {
X retWidget = WcChildNameToWidget( WcRootWidget(w), widgetName );
X XtFree( widgetName );
X return retWidget;
X }
X
X if (widgetName[0] == '^'
X || widgetName[0] == '~'
X || widgetName[0] == '.')
X {
X i = 0;
X while (widgetName[i] == '^' /* parent */
X || widgetName[i] == '~' /* shell ancestor */
X || widgetName[i] == '.') /* eaten and ignored */
X {
X if (widgetName[i] == '^')
X {
X w = XtParent( w );
X }
X else if (widgetName[i] == '~')
X {
X /* There is a bug in /usr/include/X11/IntrinsicP.h, in
X ** the XtIsShell() macro. It does not parenthesize its
X ** argument when it uses it. Therefore, the extra
X ** parens are necessary here!
X */
X while (! XtIsShell( (w = XtParent(w)) ) )
X ;
X }
X i++;
X }
X if (widgetName[i] == '\0')
X retWidget = w;
X else
X retWidget = WcChildNameToWidget( w, &(widgetName[i]) );
X XtFree( widgetName );
X return retWidget;
X }
X
X lowerName = WcLowerCaseCopy( widgetName ); /* must be XtFree'd */
X
X if ( 0 == strcmp( "this", lowerName ) )
X {
X XtFree( widgetName );
X XtFree( lowerName );
X return w;
X }
X
X /* Apparently, the widget name starts with a name. We need to find
X ** which root widget has this name. We need to go down the list of
X ** root widgets maintained by WcRootWidget().
X */
X
X {
X Widget root;
X Widget root_of_w;
X char* rootName;
X char* lowerRootName;
X int widgetNameLen = strlen(lowerName);
X int rootNameLen;
X int startsWithRootName;
X char* stripped;
X
X /* most of the time, a widget names something else in its
X ** own widget heirarchy. Therefore, see if the naming starts
X ** at the root widget of `w' but don't check that widget again.
X */
X root_of_w = root = WcRootWidget( w ) ;
X i = -1;
X
X while(1)
X {
X rootName = XrmQuarkToString( root->core.xrm_name );
X lowerRootName = WcLowerCaseCopy( rootName ); /* XtFree this */
X rootNameLen = strlen( lowerRootName );
X startsWithRootName = !strncmp(lowerName,lowerRootName,rootNameLen);
X
X if ( startsWithRootName && widgetName[rootNameLen] == '*' )
X {
X /* the root widget name is followed by a `*' so strip the
X ** root name, but keep the star as it implies loose binding.
X */
X stripped = &widgetName[rootNameLen];
X retWidget = WcChildNameToWidget( root, stripped );
X XtFree( widgetName );
X XtFree( lowerName );
X XtFree( lowerRootName );
X return retWidget;
X }
X
X else if ( startsWithRootName && widgetName[rootNameLen] == '.' )
X {
X /* the root widget name is followed by a `.' so strip the
X ** root name and the period to imply tight binding.
X */
X stripped = &widgetName[++rootNameLen];
X retWidget = WcChildNameToWidget( root, stripped );
X XtFree( widgetName );
X XtFree( lowerName );
X XtFree( lowerRootName );
X return retWidget;
X }
X
X else if ( startsWithRootName && (widgetNameLen == rootNameLen) )
X {
X /* widgetName is the root widget. */
X XtFree( widgetName );
X XtFree( lowerName );
X XtFree( lowerRootName );
X return root;
X }
X
X /* Did not find the root name. Try the next, but skip the
X ** root_of_w which we checked first.
X */
X if (++i == numRoots)
X break;
X if (root_of_w == (root = rootWidgets[i]) )
X {
X if (++i == numRoots)
X break;
X root = rootWidgets[i];
X }
X }
X
X /* Completely unsucessful in parsing this name. */
X#ifdef DEBUG
X sprintf( msg,
X "WcFullNameToWidget cannot convert `%s' to widget \n\
X Problem: Widget name must start with `*' or `.' or `~' or `^'\n\
X or `<aRoot>*' or `<aRoot>.' or be `this'" ,
X widgetName );
X XtWarning( msg );
X#endif
X
X XtFree( widgetName );
X XtFree( lowerName );
X XtFree( lowerRootName );
X return NULL;
X }
X}
X
X/*
X -- Names to Widget List
X******************************************************************************
X This routine converts a string of comma separated widget names
X (or widget paths) into a list of widget id's. Blank space ignored.
X If a NULL string is provided, NULL is put on the list.
X
X The return value is the list of names which could NOT be
X converted. Note that this list is fixed size, and is re-used.
X*/
X
Xchar* WcNamesToWidgetList ( w, names, widget_list, widget_count )
X Widget w; /* reference widget */
X char* names; /* string of widget names */
X Widget widget_list[]; /* returned widget list */
X int *widget_count; /* in widget_list[len], out widget count */
X{
X static char ignored[MAX_XRMSTRING];
X char* next = names;
X int max = *widget_count;
X
X/* -- parse the input names "widgetpath [, widgetpath] ..." */
X ignored[0] = NUL;
X *widget_count = 0;
X
X do
X {
X next = WcCleanName ( next, cleanName );
X
X if ( widget_list[*widget_count] = WcFullNameToWidget ( w, cleanName ) )
X (*widget_count)++;
X else
X {
X if (ignored[0] == NUL)
X strcpy(ignored, cleanName);
X else
X {
X strcat(ignored, ", ");
X strcat(ignored, cleanName);
X }
X }
X next = WcSkipWhitespace_Comma ( next );
X
X } while ( *next && *widget_count < max) ;
X
X return ignored;
X}
X
X/*
X -- WidgetToFullName
X*******************************************************************************
X Traverse up the widget tree, sprintf each name right up to
X the root of the widget tree. sprintf the names to buffer. Use
X recursion so order of names comes out right. Client MUST free
X the char string alloc's and returned by WcWidgetToFullName().
X
X Note: If using the Motif widget set, it is likely (almost inavoidable)
X that the "widget" may actually be a Gadget. Well, Gadgets don't have
X many things, particularly a core.name member. Therefore, if using
X Motif we must check to see if the "widget" is not actually an XmGadget.
X If is it, then we must use XrmQuarkToString(w->core.xrm_name) rather
X than core.name (unfortunately). I'd rather not use the xrm name because
X the case has been flattened: everything is lower case. Name something
X SomeComplexLongName and you get back somecomplexlongname. The case
X is always insignificant, but the mixed case name is easier to read.
X*/
X
Xstatic char* nextChar;
X
Xstatic int FullNameLen( w )
X Widget w;
X{
X int len;
X
X#if defined(MOTIF) && MOTIF == 1 && MOTIF_MINOR == 0
X if (XmIsGadget(w))
X#else
X if (XtIsWidget(w) == 0)
X#endif
X len = 1 + strlen ( XrmQuarkToString(w->core.xrm_name) );
X else
X len = 1 + strlen ( w->core.name );
X
X if (w->core.parent)
X len += FullNameLen(w->core.parent);
X return len;
X}
X
Xstatic void WidgetToFullName( w )
X Widget w;
X{
X char* cp;
X
X if (w->core.parent)
X {
X WidgetToFullName( w->core.parent ); /* nextChar AFTER parent name */
X *nextChar++ = '.'; /* inter-name `dot' */
X }
X
X#if defined(MOTIF) && MOTIF == 1 && MOTIF_MINOR == 0
X if (XmIsGadget(w))
X#else
X if (XtIsWidget(w) == 0)
X#endif
X cp = XrmQuarkToString(w->core.xrm_name);
X else
X cp = w->core.name;
X
X while (*cp)
X *nextChar++ = *cp++;
X}
X
Xchar* WcWidgetToFullName( w )
X Widget w;
X{
X char* buff = XtMalloc( FullNameLen( w ) );
X
X nextChar = buff;
X
X WidgetToFullName( w );
X *nextChar = NUL;
X
X return buff;
X}
X
X/*
X -- Search widget's resource list for resource_type
X*******************************************************************************
X Gets the XtResourceList from the widget, searches the list for
X the resource name to determine the type required, which is then
X returned to the caller.
X*/
X
Xchar* WcGetResourceType( w, res_name )
X Widget w;
X char* res_name;
X{
X XtResource* res_list;
X int i, num;
X char* retstr;
X
X XtGetResourceList( w->core.widget_class, &res_list, &num );
X
X for ( i = 0 ; i < num ; i++ )
X {
X if (0 == strcmp( res_name, res_list[i].resource_name)
X || 0 == strcmp( res_name, res_list[i].resource_class) )
X {
X retstr = XtNewString(res_list[i].resource_type);
X XtFree( res_list );
X return retstr;
X }
X }
X
X w = XtParent( w );
X if (XtIsConstraint( w ))
X {
X XtGetConstraintResourceList( w->core.widget_class, &res_list, &num );
X
X for ( i = 0 ; i < num ; i++ )
X {
X if (0 == strcmp( res_name, res_list[i].resource_name)
X || 0 == strcmp( res_name, res_list[i].resource_class) )
X {
X retstr = XtNewString(res_list[i].resource_type);
X XtFree( res_list );
X return retstr;
X }
X }
X }
X
X return NULL;
X}
X
X/*
X -- Convert resource value from string to whatever the widget needs
X*******************************************************************************
X Gets the XtResourceList from the widget, searches the list for
X the resource name to determine the type required, then uses the
X resource manager to convert from string to the required type.
X Calls XtSetValue with converted type.
X
X Note that if the widget does not have the specified resource
X type, it is not set. WcGetResourceType() checks for both
X widget resources and constraint resources.
X
X Note also that no converter-failed behavior is necessary,
X because converters generally give their own error messages.
X*/
X
Xvoid WcSetValueFromString( w, res_name, res_val )
X Widget w; /* MUST already be init'd */
X char* res_name;
X char* res_val; /* NUL terminated, should NOT have whitespace */
X{
X char* res_type; /* must be XtFree'd */
X
X if ( res_type = WcGetResourceType( w, res_name ) )
X {
X /* This widget does know about this resource type */
X WcSetValueFromStringAndType( w, res_name, res_val, res_type );
X }
X XtFree( res_type );
X}
X
Xvoid WcSetValueFromStringAndType( w, res_name, res_val, res_type )
X Widget w;
X char* res_name;
X char* res_val;
X char* res_type;
X{
X XrmValue fr_val;
X XrmValue to_val;
X Arg arg[1];
X
X fr_val.size = strlen(res_val) + 1;
X fr_val.addr = (caddr_t)res_val;
X to_val.size = 0;
X to_val.addr = NULL;
X XtConvert(
X w, /* the widget */
X XtRString, /* from type */
X &fr_val, /* from value */
X res_type, /* to type */
X &to_val /* the converted value */
X );
X
X if (to_val.addr)
X {
X /* Conversion worked. */
X if ( 0 == strcmp(res_type, "String"))
X XtSetArg( arg[0], res_name, to_val.addr );
X else
X {
X switch(to_val.size)
X {
X case sizeof(char):
X XtSetArg( arg[0], res_name, *(char*)to_val.addr );
X break;
X case sizeof(short):
X XtSetArg( arg[0], res_name, *(short*)to_val.addr );
X break;
X case sizeof(int):
X XtSetArg( arg[0], res_name, *(int*)to_val.addr );
X break;
X default:
X XtSetArg( arg[0], res_name, to_val.addr );
X }
X }
X XtSetValues( w, arg, 1 );
X }
X}
X
X/*
X*******************************************************************************
X* Private Data involving the root widget list, declared at top of this file
X* static int numRoots = 0;
X* static Widget rootWidgets[MAX_ROOT_WIDGETS];
X*******************************************************************************
X*/
X
X
X/*
X -- Forget about a root widget
X*******************************************************************************
X When a root widget gets destroyed, we need to take that widget out
X of our list of root widgets. This is a destroy callback routine
X which is added to a root widget's destroy callback list by WcRootWidget.
X*/
X
Xstatic void ForgetRoot ( w, client, call )
X Widget w;
X caddr_t client;
X caddr_t call;
X{
X int i;
X for (i = 0 ; i < numRoots ; i++ )
X {
X if ( w == rootWidgets[i] )
X {
X /* move all following widgets up to close the gap */
X for ( ; i < numRoots ; i++ )
X {
X rootWidgets[i] = rootWidgets[i+1];
X }
X numRoots-- ;
X return;
X }
X }
X /* should never get here */
X}
X
X/*
X -- Find root widget
X*******************************************************************************
X If a widget is passed, then find the root of that widget. See if
X it is one of the root widgets we already know about. Add to list
X if not. Return the root widget.
X
X If no widget is passed, then return the first root widget we know
X about. If we know of no root widgets, then we will return a NULL
X since the rootWidgets[] array starts out filled with nulls, and
X gets re-filled as roots are destroyed.
X*/
X
XWidget WcRootWidget( w )
X Widget w;
X{
X int i;
X
X if (w)
X {
X while ( XtParent(w) )
X w = XtParent(w);
X
X for (i = 0 ; i < numRoots ; i++)
X {
X if ( w == rootWidgets[i] )
X return w;
X }
X
X rootWidgets[i] = w;
X numRoots++;
X XtAddCallback( w, XtNdestroyCallback, ForgetRoot, NULL );
X return w;
X }
X else
X {
X return rootWidgets[0];
X }
X}
X
X/*
X -- Equivalent to ANSI C library function strstr()
X*******************************************************************************
X This function is only necessary on systems which do not have
X ANSI C libraries. Soon, it looks like everybody will have
X such libraries, what with the recent SVR4 and OSF efforts
X to include everything for everybody. In the meantime,
X this will always be included in the library. Why not put
X #ifdef's around it? because the problem really arises not
X when the library is built, but when applications are built.
X I can't very well require all application writers in the
X world to know what this library uses...
X*/
X
Xchar* WcStrStr( s1, s2 )
X char* s1;
X char* s2;
X{
X while (*s1)
X {
X if (*s1 == *s2)
X {
X char* start = s1;
X char* c = s2;
X while (*++s1 & *++c && *s1 == *c)
X ;
X if (*c == '\0')
X return start;
X else
X s1 = ++start;
X }
X else
X {
X s1++ ;
X }
X }
X return (char*)0;
X}
+FUNKY+STUFF+
echo '-rw-r--r-- 1 david 31942 Oct 15 10:15 WcName.c (as sent)'
chmod u=rw,g=r,o=r WcName.c
ls -l WcName.c
exit 0
dan
----------------------------------------------------
O'Reilly && Associates argv at sun.com / argv at ora.com
Opinions expressed reflect those of the author only.
--
dan
----------------------------------------------------
O'Reilly && Associates argv at sun.com / argv at ora.com
Opinions expressed reflect those of the author only.
More information about the Comp.sources.x
mailing list