home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / x / volume10 / wcl / part10 < prev    next >
Internet Message Format  |  1990-12-17  |  53KB

  1. Path: uunet!midway!ncar!elroy.jpl.nasa.gov!usc!apple!sun-barr!newstop!exodus!jpl-devvax.jpl.nasa.gov
  2. From: david@jpl-devvax.jpl.nasa.gov (David E. Smyth)
  3. Newsgroups: comp.sources.x
  4. Subject: v10i058: wcl -- Widget Creation Library, Part10/11
  5. Message-ID: <4692@exodus.Eng.Sun.COM>
  6. Date: 18 Dec 90 02:05:48 GMT
  7. References: <csx-10i049:wcl@uunet.UU.NET>
  8. Sender: news@exodus.Eng.Sun.COM
  9. Lines: 1442
  10. Approved: argv@sun.com
  11.  
  12. Submitted-by: david@jpl-devvax.jpl.nasa.gov (David E. Smyth)
  13. Posting-number: Volume 10, Issue 58
  14. Archive-name: wcl/part10
  15.  
  16. # to unbundle, "sh" this file -- DO NOT use csh
  17. #  SHAR archive format.  Archive created Fri Oct 19 09:33:23 PDT 1990
  18. echo x - WcConvert.c
  19. sed 's/^X//' > WcConvert.c <<'+FUNKY+STUFF+'
  20. X/*
  21. X** Copyright (c) 1990 David E. Smyth
  22. X**
  23. X** This file was derived from work performed by Martin Brunecky at
  24. X** Auto-trol Technology Corporation, Denver, Colorado, under the
  25. X** following copyright:
  26. X**
  27. X*******************************************************************************
  28. X* Copyright 1990 by Auto-trol Technology Corporation, Denver, Colorado.
  29. X*
  30. X*                        All Rights Reserved
  31. X*
  32. X* Permission to use, copy, modify, and distribute this software and its
  33. X* documentation for any purpose and without fee is hereby granted, provided
  34. X* that the above copyright notice appears on all copies and that both the
  35. X* copyright and this permission notice appear in supporting documentation
  36. X* and that the name of Auto-trol not be used in advertising or publicity
  37. X* pertaining to distribution of the software without specific, prior written
  38. X* permission.
  39. X*
  40. X* Auto-trol disclaims all warranties with regard to this software, including
  41. X* all implied warranties of merchantability and fitness, in no event shall
  42. X* Auto-trol be liable for any special, indirect or consequential damages or
  43. X* any damages whatsoever resulting from loss of use, data or profits, whether
  44. X* in an action of contract, negligence or other tortious action, arising out
  45. X* of or in connection with the use or performance of this software.
  46. X*******************************************************************************
  47. X**
  48. X** Redistribution and use in source and binary forms are permitted
  49. X** provided that the above copyright notice and this paragraph are
  50. X** duplicated in all such forms and that any documentation, advertising
  51. X** materials, and other materials related to such distribution and use
  52. X** acknowledge that the software was developed by David E. Smyth.  The
  53. X** name of David E. Smyth may not be used to endorse or promote products
  54. X** derived from this software without specific prior written permission.
  55. X** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  56. X** WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  57. X** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  58. X**
  59. X*/
  60. X
  61. X/*
  62. X* SCCS_data: @(#)WcConvert.c 1.04 ( 30 September 1990 )
  63. X*
  64. X* Subsystem_group:
  65. X*
  66. X*     Widget Creation Library
  67. X*
  68. X* Module_description:
  69. X*
  70. X*     This module contains Xt converter functions which convert strings,
  71. X*     as found in the Xrm database, into useful types.  
  72. X*
  73. X*     It also contains the routine which registers all Wc converters.
  74. X*
  75. X*     The CvtStringToWidget converter takes a pathname which starts 
  76. X*     from the application shell an proceeds to a specific widget.  The
  77. X*     widget must already have been created.   Note that this converter
  78. X*     needs to be used INSTEAD of the XmuCvtStringToWidget which gets
  79. X*     registered by the Athena widgets.  The Xmu converter is not so
  80. X*     user friendly.  This means this file also declares an external
  81. X*     function XmuCvtStringToWidget() which is really CvtStringToWidget,
  82. X*     and this needs to be linked before Xmu.
  83. X*
  84. X*     The CvtStringToCallback converter parses the resource string in 
  85. X*     the format:
  86. X*
  87. X*       ...path:   name[(args)][,name[(args)]]...
  88. X*
  89. X*     where:  name:   specifies the registered callback function name
  90. X*             args:   specifies the string passed to a callback as
  91. X*              "client data".
  92. X*
  93. X*     Multiple callbacks can be specified for a single callback list
  94. X*     resource.  Any callbacks must be "registered" by the application
  95. X*     prior converter invocation (.i.e.prior widget creation).
  96. X*     If no "args" string is provided, the default "client data" 
  97. X*     specified at callback registration are used.
  98. X*
  99. X*     The CvtStringToConstructor converter searches the Constructor
  100. X*     cache for a registered constructor.  
  101. X*
  102. X*     The CvtStringToClass converter searches the Class cache for a 
  103. X*     registered object (widget) class pointer name.
  104. X*
  105. X*     The CvtStringToClassName converter searches the ClassName cache
  106. X*     for a registered object (widget) class name.
  107. X
  108. X*
  109. X* Module_interface_summary: 
  110. X*
  111. X*     Resource converter is invoked indirectly by the toolkit. The
  112. X*     converter is added to the toolkit by widgets calling
  113. X*     WcAddConverters() in the Wc intialization code.
  114. X*
  115. X* Module_history:
  116. X*                                                  
  117. X*   mm/dd/yy  initials  function  action
  118. X*   --------  --------  --------  ---------------------------------------------
  119. X*   06/08/90  D.Smyth   Class, ClassName, and Constructor converters.
  120. X*   05/24/90  D.Smyth   WcAddConverters created from something similar
  121. X*   04/03/90  MarBru    CvtStr..  Fixed argument termination with a NUL char
  122. X*   02/26/90  MarBru    All       Created
  123. X*
  124. X* Design_notes:
  125. X*
  126. X*   For VMS, we could have used LIB$FIND_IMAGE_SYMBOL and use dynamic
  127. X*   (runtime) binding. But since most UNIX systems lack such capability,
  128. X*   we stick to the concept of "registration" routines.
  129. X*
  130. X*   One time, I considered applying conversion to callback argument, which
  131. X*   would take the burden of conversion from the callback code (runtime)
  132. X*   to the callback  conversion (one time initialization). The problem is
  133. X*   that some conversions are widget context specific (color to pixel needs
  134. X*   display connection), and at the time of callback conversion I do not
  135. X*   have a widget. I could require the widget argument, but this would kill
  136. X*   caching of the conversion result.
  137. X*
  138. X*   The sequential search of the callback cache is far from optimal. I should
  139. X*   use binary search, or the R4 conversion cache.  I can't use the R4 cache
  140. X*   until Motif 1.1 is released which will (supposedly) run on R4 Intrinsics.
  141. X*   
  142. X*******************************************************************************
  143. X*/
  144. X/*
  145. X*******************************************************************************
  146. X* Include_files.
  147. X*******************************************************************************
  148. X*/
  149. X
  150. X#include <ctype.h>    /* isupper() and tolower macros */
  151. X#include <stdio.h>
  152. X
  153. X/*  -- X Window System includes */
  154. X#include <X11/StringDefs.h> 
  155. X
  156. X/*  -- Widget Creation Library includes */
  157. X#include "WcCreate.h"
  158. X#include "WcCreateP.h"
  159. X
  160. X#ifdef MOTIF
  161. X
  162. X/*  -- Motif specific includes for CvtStringToMenuWidget */
  163. X#include <Xm/Xm.h>
  164. X#include <Xm/RowColumn.h>
  165. X#include <Xm/RowColumnP.h>
  166. X
  167. X#endif /* MOTIF */
  168. X
  169. X/*
  170. X*******************************************************************************
  171. X* Private_constant_declarations.
  172. X*******************************************************************************
  173. X*/
  174. X
  175. X/*
  176. X*******************************************************************************
  177. X* Private_type_declarations.
  178. X*******************************************************************************
  179. X*/
  180. X
  181. X/*
  182. X*******************************************************************************
  183. X* Private_macro_definitions.
  184. X*******************************************************************************
  185. X*/
  186. X
  187. X#define done( type, value )             \
  188. X{                        \
  189. X    if ( toVal->addr != NULL )            \
  190. X    {                        \
  191. X    if ( toVal->size < sizeof( type ) )    \
  192. X    {                    \
  193. X        toVal->size = sizeof( type );    \
  194. X        return;                \
  195. X    }                    \
  196. X    *(type*)(toVal->addr) = (value);    \
  197. X    }                        \
  198. X    else                    \
  199. X    {                        \
  200. X    static type static_val;            \
  201. X    static_val = (value);            \
  202. X    toVal->addr = (caddr_t)&static_val;    \
  203. X    }                        \
  204. X    toVal->size = sizeof(type);            \
  205. X    return;                    \
  206. X}
  207. X
  208. X/*
  209. X*******************************************************************************
  210. X* Private_data_definitions.
  211. X*******************************************************************************
  212. X*/
  213. X
  214. X/*
  215. X*******************************************************************************
  216. X* Private_function_declarations.
  217. X*******************************************************************************
  218. X*/
  219. X
  220. X/*
  221. X    -- Convert String To ClassPtr
  222. X*******************************************************************************
  223. X    This conversion searches the Object Class cache for the appropriate
  224. X    Cache record.  The resource database string is simply the name
  225. X    of the class pointer, case insensitive.  The value provided is the
  226. X    widget class pointer, as passed to XtCreateWidget().
  227. X*/
  228. X
  229. Xvoid CvtStringToClassPtr (args, num_args, fromVal, toVal )
  230. X    XrmValue  *args;
  231. X    Cardinal  *num_args;
  232. X    XrmValue  *fromVal;
  233. X    XrmValue  *toVal;
  234. X{
  235. X    char*       string = (char *) fromVal->addr;
  236. X    char        cleanName[MAX_XRMSTRING];
  237. X    char*       lowerCase;
  238. X    XrmQuark    quark;
  239. X    int         i;
  240. X
  241. X    (void)WcCleanName ( string, cleanName );
  242. X    lowerCase = WcLowerCaseCopy ( cleanName );
  243. X    quark = XrmStringToQuark ( lowerCase );
  244. X    XtFree ( lowerCase );
  245. X
  246. X    for (i=0; i<classes_num; i++)
  247. X    {
  248. X        if ( classes_ptr[i].quark == quark )
  249. X        {
  250. X            done( WidgetClass, classes_ptr[i].class );
  251. X        }
  252. X    }
  253. X    XtStringConversionWarning (cleanName, "Object Class, not registered.");
  254. X}
  255. X
  256. X/*
  257. X    -- Convert String To ClassName
  258. X*******************************************************************************
  259. X    This conversion searches the Class Name cache for the appropriate
  260. X    Cache record.  The resource database string is simply the name
  261. X    of the class, case insensitive.  The value provided is the widget 
  262. X    class pointer, as passed to XtCreateWidget().
  263. X*/
  264. X
  265. Xvoid CvtStringToClassName (args, num_args, fromVal, toVal )
  266. X    XrmValue  *args;
  267. X    Cardinal  *num_args;
  268. X    XrmValue  *fromVal;
  269. X    XrmValue  *toVal;
  270. X{
  271. X    char*    string = (char *) fromVal->addr;
  272. X    char    cleanName[MAX_XRMSTRING];
  273. X    char*     lowerCase;
  274. X    XrmQuark    quark;
  275. X    int        i;
  276. X
  277. X    (void)WcCleanName ( string, cleanName );
  278. X    lowerCase = WcLowerCaseCopy ( cleanName );
  279. X    quark = XrmStringToQuark ( lowerCase );
  280. X    XtFree ( lowerCase );
  281. X
  282. X    for (i=0; i<cl_nm_num; i++)
  283. X    {
  284. X        if ( cl_nm_ptr[i].quark == quark )
  285. X        {
  286. X        done( WidgetClass, cl_nm_ptr[i].class );
  287. X        }
  288. X    }
  289. X    XtStringConversionWarning (cleanName, "Class Name, not registered.");
  290. X}
  291. X
  292. X/*
  293. X    -- Convert String To Constructor
  294. X*******************************************************************************
  295. X    This conversion searches the Constructor Cache for the appropriate
  296. X    Cache record.  The resource database string is simply the name
  297. X    of the constructor, case insensitive.  The value provided is a
  298. X    Contrstructor Cache Record.  The constructor (func ptr) itself is
  299. X    not provided, as the user of this value (generally WcCreateDatabaseChild)
  300. X    also likes to have the constructor name as registered for error messages.
  301. X*/
  302. X
  303. Xvoid CvtStringToConstructor (args, num_args, fromVal, toVal)
  304. X    XrmValue *args;
  305. X    Cardinal *num_args;
  306. X    XrmValue *fromVal;
  307. X    XrmValue *toVal;
  308. X{
  309. X    char*       string = (char *) fromVal->addr;
  310. X    char        cleanName[MAX_XRMSTRING];
  311. X    char*       lowerCase;
  312. X    XrmQuark    quark;
  313. X    int         i;
  314. X
  315. X    (void)WcCleanName ( string, cleanName );
  316. X    lowerCase = WcLowerCaseCopy ( cleanName );
  317. X    quark = XrmStringToQuark ( lowerCase );
  318. X    XtFree ( lowerCase );
  319. X
  320. X    for (i=0; i<constrs_num; i++)
  321. X    {
  322. X    if ( constrs_ptr[i].quark == quark )
  323. X    {
  324. X        done( ConCacheRec*, &(constrs_ptr[i]) );
  325. X    }
  326. X    }
  327. X    XtStringConversionWarning (cleanName, "Constructor, not registered.");
  328. X}
  329. X
  330. X/*
  331. X    -- Convert String To Callback
  332. X*******************************************************************************
  333. X    This conversion creates a callback list structure from the X resource
  334. X    database string in format:
  335. X
  336. X    name(arg),name(arg).....
  337. X
  338. X    Note "name" is not case sensitive, while "arg" may be - it is passed to
  339. X    a callback as client data as a null terminated string (first level
  340. X    parenthesis stripped off).  Even if nothing is specified e.g.,
  341. X    SomeCallback() there is a null terminated string passed as client
  342. X    data to the callback.  If it is empty, then it is the null string.
  343. X
  344. X    Note also that the argument CANNOT be converted at this point: frequently,
  345. X    the argument refers to a widget which has not yet been created, or
  346. X    uses the context of the callback (i.e., WcUnmanageCB( this ) uses the
  347. X    widget which invoked the callback).  
  348. X*/
  349. X
  350. Xvoid CvtStringToCallback (args, num_args, fromVal, toVal)
  351. X    XrmValue *args;
  352. X    Cardinal *num_args;
  353. X    XrmValue *fromVal;
  354. X    XrmValue *toVal;
  355. X{
  356. X    static XtCallbackRec *cb;        /* return pointer, MUST be static */
  357. X
  358. X    XtCallbackRec      callback_list[MAX_CALLBACKS];
  359. X    XtCallbackRec     *rec = callback_list;
  360. X    int                   callback_list_len = 0;
  361. X
  362. X    typedef struct 
  363. X    {
  364. X    char *nsta,*nend;        /* callback name start, end */
  365. X    char *asta,*aend;        /* argument string start, end */
  366. X    } Segment;
  367. X
  368. X    Segment               name_arg_segments[MAX_CALLBACKS];    
  369. X    Segment              *seg = name_arg_segments;
  370. X    char         *string = (char *) fromVal->addr;
  371. X    register char        *s;
  372. X    register int      in_parens = 0;
  373. X
  374. X    register int          i;
  375. X
  376. X/*  -- assume error or undefined input argument */
  377. X    toVal->size = 0;
  378. X    toVal->addr = (caddr_t) NULL;
  379. X    if (string == NULL) return;
  380. X
  381. X/*  -- parse input string finding segments   "name(arg)" comma separated */
  382. X    seg->nsta = seg->nend = seg->asta = seg->aend = (char*)NULL;
  383. X
  384. X    for ( s=string;  ;  s++ )
  385. X    {
  386. X    switch (*s)
  387. X    {
  388. X    case ',':  if ( in_parens ) break;  /* commas in arguments ignored  */
  389. X    case NUL:  if ( seg->nend == NULL ) seg->nend = s-1;  /* no argument */
  390. X               seg++;           /* start the next segment */
  391. X               seg->nsta = seg->nend = seg->asta = seg->aend = (char*)NULL;
  392. X           break;           
  393. X
  394. X    case '(':  if ( in_parens++ == 0 ) { seg->nend = s-1; seg->asta = s+1; }
  395. X               break;
  396. X           
  397. X    case ')':  if ( --in_parens == 0 ) { seg->aend = s-1; };
  398. X           break;
  399. X
  400. X    default:   if ( *s > ' '  &&  seg->nsta == NULL )
  401. X            /* only start a new segment on non-blank char */
  402. X                    seg->nsta = s;
  403. X    }
  404. X    if (*s == NUL) break;
  405. X    }
  406. X
  407. X    if (in_parens)
  408. X    {
  409. X    XtStringConversionWarning (string, "Callback, unbalanced parenthesis");
  410. X    return;
  411. X    }
  412. X
  413. X/*  -- process individual callback string segments "name(arg)" */
  414. X    for( seg = name_arg_segments;  seg->nsta;   seg++)
  415. X    {
  416. X        char                 cb_name[MAX_XRMSTRING];
  417. X    register char    *d;
  418. X    XrmQuark             quark;
  419. X    int          found;
  420. X
  421. X    /* our callback cache names are case insensitive, no white space */
  422. X    for ( s=seg->nsta, d=cb_name; s<=seg->nend; )
  423. X       if ( *s > ' ')
  424. X             *d++ = (isupper(*s) ) ? tolower (*s++) : *s++;
  425. X       else
  426. X          s++;
  427. X    *d   = NUL;
  428. X
  429. X        /* try to locate callback in our cache of callbacks */
  430. X        quark = XrmStringToQuark (cb_name);
  431. X    for (found = 0, i=0 ; !found && i<callbacks_num ; i++)
  432. X        if ( callbacks_ptr[i].quark == quark )
  433. X        {
  434. X        rec->callback = callbacks_ptr[i].callback;
  435. X        rec->closure  = callbacks_ptr[i].closure;
  436. X        found++;
  437. X        }
  438. X
  439. X    /* we have found a registered callback, process arguments */
  440. X    if (found)
  441. X    {
  442. X       register char *arg;
  443. X       register int   alen;
  444. X       
  445. X       if ( seg->asta )
  446. X       {
  447. X           /* arg in parens - pass as string replacing default closure */
  448. X           alen = (int)seg->aend - (int)seg->asta +1;
  449. X           arg  = XtMalloc(alen+1);
  450. X           strncpy ( arg, seg->asta, alen );
  451. X           arg[alen]    = NUL;
  452. X           rec->closure = (caddr_t)arg;
  453. X       }
  454. X       else
  455. X       {
  456. X           /* no arg in parens.  Make sure closure is something -
  457. X           ** do NOT return NULL in any event.  Causes SEGV too
  458. X           ** easily.  
  459. X           */
  460. X           if (rec->closure == NULL)
  461. X           rec->closure = (caddr_t)"";
  462. X       }
  463. X       rec++;
  464. X       callback_list_len++;
  465. X        }
  466. X    else
  467. X    {
  468. X           XtStringConversionWarning (cb_name, 
  469. X            "Callback, unknown callback name");
  470. X    }
  471. X    } /* end for seg loop */
  472. X
  473. X/*  -- terminate the callback list */
  474. X    {
  475. X        rec->callback = NULL;
  476. X    rec->closure  = NULL;
  477. X    callback_list_len++;
  478. X    }
  479. X
  480. X/*  -- make a permanent copy of the new callback list, and return a pointer */
  481. X    cb = (XtCallbackRec*)XtMalloc( callback_list_len * sizeof (XtCallbackRec) );
  482. X    memcpy ( (char*)cb, (char*)callback_list,  
  483. X              callback_list_len * sizeof (XtCallbackRec));
  484. X    toVal->size = sizeof (XtCallbackRec*);
  485. X    toVal->addr = (caddr_t)&cb;
  486. X}
  487. X
  488. X/*
  489. X    -- Convert String To Widget
  490. X*******************************************************************************
  491. X    This conversion creates a Widget id from the X resource database string.
  492. X    The conversion will fail, and WcFullNameToWidget() will issue a warning,
  493. X    if the widget so named has not been created when this converter is called.
  494. X    For example, if a widget refers to itself for some reason, during
  495. X    its creation when this converter is called, it is not yet created: 
  496. X    therefore, the converter will fail.
  497. X*/
  498. X
  499. Xvoid XmuCvtStringToWidget (args, num_args, fromVal, toVal)
  500. X    XrmValue *args;
  501. X    Cardinal *num_args;
  502. X    XrmValue *fromVal;
  503. X    XrmValue *toVal;
  504. X{
  505. X    toVal->addr = 
  506. X    (caddr_t) WcFullNameToWidget( WcRootWidget(NULL), fromVal->addr);
  507. X    toVal->size = sizeof(Widget);
  508. X}
  509. X
  510. X#ifdef MOTIF
  511. X/*
  512. X    -- Convert String To MenuWidget
  513. X*******************************************************************************
  514. X    This conversion converts strings into menu widgets for use on
  515. X    cascade button subMenuId resource specifications.
  516. X*/
  517. X
  518. Xvoid CvtStringToMenuWidget (args, num_args, fromVal, toVal)
  519. X    XrmValue *args;
  520. X    Cardinal *num_args;
  521. X    XrmValue *fromVal;
  522. X    XrmValue *toVal;
  523. X{
  524. X    char    cleanName[MAX_XRMSTRING];
  525. X    Widget    root;
  526. X    Widget    widget;
  527. X    Arg        existing[1];
  528. X
  529. X    (void)WcCleanName( fromVal->addr, cleanName );
  530. X
  531. X    if ( NULL == (root = WcRootWidget(NULL)) )
  532. X    {
  533. X    XtStringConversionWarning (cleanName,
  534. X                "MenuWidget - can't find a root widget for WcFullNameToWidget");
  535. X    return;
  536. X    }
  537. X
  538. X    if (cleanName[0] == '^' || cleanName[0] == '~')
  539. X    {
  540. X    XtStringConversionWarning (cleanName,
  541. X"MenuWidget - Relative paths cannot be converted.  Use path from root widget."
  542. X    );
  543. X    return;
  544. X    }
  545. X
  546. X    widget = WcFullNameToWidget( root, cleanName );
  547. X
  548. X    if ( widget == NULL )
  549. X    {
  550. X    XtStringConversionWarning (cleanName,
  551. X                "MenuWidget - no such widget.  Misspelled? Forgot the path?");
  552. X    return;
  553. X    }
  554. X    else if ( XmIsRowColumn( widget ) 
  555. X      && (   RC_Type ( (XmRowColumnWidget)widget ) == XmMENU_PULLDOWN
  556. X          || RC_Type ( (XmRowColumnWidget)widget ) == XmMENU_POPUP    ) )
  557. X    {
  558. X    done ( Widget, widget );
  559. X    }
  560. X    XtStringConversionWarning (cleanName, 
  561. X        "MenuWidget - not XmMENU_PULLDOWN or XmMENU_POPUP.");
  562. X}
  563. X#endif /* MOTIF */
  564. X
  565. X/*
  566. X*******************************************************************************
  567. X* Public_function_declarations.
  568. X*******************************************************************************
  569. X*/
  570. X
  571. X/*
  572. X    -- Add String To ... Convertors
  573. X*******************************************************************************
  574. X*/
  575. X
  576. Xvoid WcAddConverters ( app )
  577. X    XtAppContext app;
  578. X{
  579. X    ONCE_PER_XtAppContext( app );
  580. X
  581. X    XtAddConverter       (XtRString,
  582. X                          WcRClassPtr,
  583. X                          CvtStringToClassPtr,
  584. X                          (XtConvertArgList)NULL,
  585. X                          (Cardinal)0);
  586. X
  587. X    XtAddConverter       (XtRString,
  588. X                          WcRClassName,
  589. X                          CvtStringToClassName,
  590. X                          (XtConvertArgList)NULL,
  591. X                          (Cardinal)0);
  592. X
  593. X    XtAddConverter       (XtRString,
  594. X                          WcRConstructor,
  595. X                          CvtStringToConstructor,
  596. X                          (XtConvertArgList)NULL,
  597. X                          (Cardinal)0);
  598. X
  599. X    XtAddConverter       (XtRString, 
  600. X                          XtRCallback,
  601. X                          CvtStringToCallback,
  602. X                          (XtConvertArgList)NULL,
  603. X                          (Cardinal)0);
  604. X
  605. X#ifndef MOTIF
  606. X    XtAddConverter       (XtRString,
  607. X                          XtRWidget,
  608. X                          XmuCvtStringToWidget,
  609. X                          (XtConvertArgList)NULL,
  610. X                          (Cardinal)0);
  611. X#else
  612. X    XtAddConverter       (XtRString,
  613. X                          WcRWidget,  /* "Window" is wrong, but it works !?! */
  614. X                          XmuCvtStringToWidget,
  615. X                          (XtConvertArgList)NULL,
  616. X                          (Cardinal)0);
  617. X
  618. X    XtAddConverter       (XtRString,
  619. X                          XmRMenuWidget,
  620. X                          CvtStringToMenuWidget,
  621. X                          (XtConvertArgList)NULL,
  622. X                          (Cardinal)0);
  623. X#endif /* !MOTIF */
  624. X}
  625. +FUNKY+STUFF+
  626. echo '-rw-r--r--  1 david       20212 Oct  9 17:11 WcConvert.c    (as sent)'
  627. chmod u=rw,g=r,o=r WcConvert.c
  628. ls -l WcConvert.c
  629. echo x - WcCreate.c
  630. sed 's/^X//' > WcCreate.c <<'+FUNKY+STUFF+'
  631. X/*
  632. X** Copyright (c) 1990 David E. Smyth
  633. X**
  634. X** This file was derived from work performed by Martin Brunecky at
  635. X** Auto-trol Technology Corporation, Denver, Colorado, under the
  636. X** following copyright:
  637. X**
  638. X*******************************************************************************
  639. X* Copyright 1990 by Auto-trol Technology Corporation, Denver, Colorado.
  640. X*
  641. X*                        All Rights Reserved
  642. X*
  643. X* Permission to use, copy, modify, and distribute this software and its
  644. X* documentation for any purpose and without fee is hereby granted, provided
  645. X* that the above copyright notice appears on all copies and that both the
  646. X* copyright and this permission notice appear in supporting documentation
  647. X* and that the name of Auto-trol not be used in advertising or publicity
  648. X* pertaining to distribution of the software without specific, prior written
  649. X* permission.
  650. X*
  651. X* Auto-trol disclaims all warranties with regard to this software, including
  652. X* all implied warranties of merchantability and fitness, in no event shall
  653. X* Auto-trol be liable for any special, indirect or consequential damages or
  654. X* any damages whatsoever resulting from loss of use, data or profits, whether
  655. X* in an action of contract, negligence or other tortious action, arising out
  656. X* of or in connection with the use or performance of this software.
  657. X*******************************************************************************
  658. X**
  659. X** Redistribution and use in source and binary forms are permitted
  660. X** provided that the above copyright notice and this paragraph are
  661. X** duplicated in all such forms and that any documentation, advertising
  662. X** materials, and other materials related to such distribution and use
  663. X** acknowledge that the software was developed by David E. Smyth.  The
  664. X** name of David E. Smyth may not be used to endorse or promote products
  665. X** derived from this software without specific prior written permission.
  666. X** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  667. X** WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  668. X** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  669. X**
  670. X*/
  671. X
  672. X/*
  673. X* SCCS_data: @(#)WcCreate.c 1.03 ( 11 July 1990 )
  674. X*
  675. X* Subsystem_group:
  676. X*
  677. X*     Widget Creation Library
  678. X*
  679. X* Module_description:
  680. X*
  681. X*     This module contains the functions used to create and manage 
  682. X*     a widget tree using the Xrm database.
  683. X
  684. X*     The Xrm database format used to prescribe widget's children
  685. X*     is as follows:
  686. X*
  687. X*     ...parent.wcChildren:         childName1, childName2, ...
  688. X*
  689. X*     The type of each child must be specified.  There are three
  690. X*     ways of doing this: (1) by widget class (class pointer name),
  691. X*     (2) by widget class name, and (3) by widget constructor 
  692. X*     function name.  The resource value given is case insensitive,
  693. X*     although one is encouraged to use the capitalization given
  694. X*     in the reference manuals simply on stylistic grounds.  The 
  695. X*     three examples below are effectively equivalent:
  696. X*
  697. X*     ...drawing.wcClass:    xmDrawingAreaWidgetClass
  698. X*     ...drawing.wcClassName:    XmDrawingArea
  699. X*     ...drawing.wcConstructor: XmCreateDrawingArea
  700. X*
  701. X*     Since there are multiple ways of specifying the widget type,
  702. X*     a precedence is defined: wcClass is the highest precedence,
  703. X*     and wcClass > wcClassName > wcConstructor.
  704. X*
  705. X*     Currently, the Motif widget set defines many constructors, such 
  706. X*     as XmCreateForm or XmCreateFileSelectionBox.  Constructors are 
  707. X*     somtimes called Convenience Functions or even Confusion Functions.  
  708. X*     It is highly recommended that you use the WcTrace resource when
  709. X*     first using Constructors in order to see the resulting widget
  710. X*     heirarchy more clearly.  The WcTrace resource is specified as:
  711. X*
  712. X*     ...drawing.wcTrace:    True
  713. X
  714. X*     By default, all widgets created from the Xrm resource database
  715. X*     are managed.  In some cases, this is not what is desired: for
  716. X*     example, pop-up menus are generally not managed when they are
  717. X*     created, rather they are managed due to some mouse event.  In
  718. X*     such cases, the WcManaged resource should be set False, as below:
  719. X*
  720. X*     *fileMenu.wcManaged:    False
  721. X
  722. X*     It is possible to bind one or more callback functions to the
  723. X*     creation of a widget by using the WcCallback resource.  For 
  724. X*     example, using the Motif widget set, when a menu bar is created 
  725. X*     as a child of an XmMainWindow, the menuBar resource of the 
  726. X*     XmMainWindow needs to be set to refer to the menu bar.  For 
  727. X*     example:
  728. X*
  729. X*     App.main.wcClassName:    XmMainWindow
  730. X*     App.main.wcChildren:    mbar
  731. X*     *mbar.wcConstructor:    XmCreateMenuBar
  732. X*     *mbar.wcCallback:        WcSetResourceCB( *main.menuBar: this)
  733. X
  734. X*     Sometimes widget heirarchies are dynamic: many of the widgets
  735. X*     are created at initialization time, but others need to be created
  736. X*     at run time.  Simply do not include the names of the dynamic
  737. X*     created widgets in any wcChildren resource.  They will then still
  738. X*     be defined in the Xrm database, but they will not be created
  739. X*     during the initial widget tree creation.
  740. X
  741. X*     The WcDeferred resource is an obsolete mechanism which should no
  742. X*     longer be used.
  743. X
  744. X*     For example, let's say your interface includes a box world, where
  745. X*     the user can create an arbitrary number of various types of boxes:
  746. X
  747. X*     *box_world.wcClass:    MyBoxWorldWidgetClass
  748. X*
  749. X*     *box_type1.wcClass:    MyBoxType1WidgetClass
  750. X*     *box_type2.wcClass:    MyBoxType2WidgetClass
  751. X*     *box_type3.wcClass:    MyBoxType3WidgetClass
  752. X*     *box_type3.wcChildren:    child1, child2, child3, child4
  753. X*
  754. X*     *button1.callback:    WcCreateChildrenCB( *box_world, box_type1 )
  755. X*     *button2.callback:    WcCreateChildrenCB( *box_world, box_type2 )
  756. X*     *button3.callback:    WcCreateChildrenCB( *box_world, box_type3 )
  757. X*
  758. X*     Initially, when box_world is created, it will have no children.
  759. X*     Each time button1 is pressed, another instance of box_type1 will
  760. X*     be created as a child of box_world, and managed (since wcManaged
  761. X*     is by default True).  Similarly, everytime button2 is pressed
  762. X*     another box_type2 will be created, and everytime button3 is
  763. X*     pressed another box_type3 will be created, along with children
  764. X*     named child1, child2, child3, and child4, and their children as 
  765. X*     applicable.
  766. X
  767. X*     User interfaces are often rather complex.  Since the Widget
  768. X*     Creation Library allows much more of the interface to be
  769. X*     specified in resource files than in prehistoric days of
  770. X*     Widget application programming, it becomes necessary to allow
  771. X*     interfaces to be specified in a collection of resource files.
  772. X*     
  773. X*     It is very desirable that anything in the interface can be
  774. X*     tailored by the user.  Therefore, each resource filename
  775. X*     loaded to describe an interface must be searched for in 
  776. X*     all the locations defined by the Xt Intrinsics.  This is
  777. X*     exactly the same as the initial resource file.
  778. X*
  779. X*     Since a resource file may override any of the resources on
  780. X*     a given widget, including other creation resources, the
  781. X*     resource file name is first fetched before any of the other
  782. X*     wc* resources.
  783. X*
  784. X*     A resource file name is specified as follows:
  785. X*
  786. X*     *menuBar.wcResFile:    MenuBar
  787. X*
  788. X*     Each of the standard directories will be searched in order
  789. X*     for a file named MenuBar, and each merged into the resource database.
  790. X
  791. X*     The following is the complete set of resources which are 
  792. X*     interpreted by the Widget Creation Library:
  793. X*
  794. X*     ...widget.wcChildren:    childName1, childName2, ...
  795. X*     ...widget.wcClass:    classPointerName
  796. X*     ...widget.wcClassName:    className
  797. X*     ...widget.wcConstructor:  constructorFunctionName
  798. X*     ...widget.wcTrace:    true/false (default = false)
  799. X*     ...widget.wcManaged:    true/false (default = true)
  800. X*     ...widget.wcCallback:    callback1(args), callback2(args), ...
  801. X*     ...widget.wcResFile:    filename
  802. X*
  803. X*     In all cases, the Widget Creation resource names can be
  804. X*     specified as Wc<name> or wc<name>, with the capitalized
  805. X*     form having looser binding (representing the resource class).
  806. X
  807. X*     Example:
  808. X*
  809. X*        HelloWorld.wcChildren:  push
  810. X*
  811. X*        *push.wcClass:          xmPushButtonWidgetClass
  812. X*        *push.labelString:      Hello World
  813. X*        *push.activateCallback: WcExitCB(1)
  814. X
  815. X*     Since (for portability reasons) we can not assume runtime binding,
  816. X*     all widget classes or creation routines (constructors) must be 
  817. X*     "registered"  by the application BEFORE widget tree creation.
  818. X*
  819. X*     The widget tree creation is performed by the WcCreateDatabaseChild()
  820. X*     function, which descends the widget tree recursively until no more
  821. X*     children are found, or a non-composite widget/object is found.
  822. X*
  823. X*     Several convenience callbacks are provided with the package, allowing 
  824. X*     deferred widget creation, control (manage/unmanage) and other utility
  825. X*     functions.  These are found in WcCallb.c
  826. X*
  827. X* Module_history:
  828. X                                                  
  829. X*   mm/dd/yy  initials  function  action
  830. X*   --------  --------  --------  ---------------------------------------------
  831. X*   13Aug90   D.Smyth    Got rid of WcDefered stuff
  832. X*   11Jul90   D.Smyth   Added wcResFile resource
  833. X*   30Jun90   R.Whitby    WcWidgetCreation added call to WcRegisterWcActions
  834. X*   19Jun90   D.Smyth    Version 1.0
  835. X*   04/18/90  MarBru    many..    Changed w->core.name to XrmQuarkToString...
  836. X*   03/27/90  MarBru    Creation  Converted to a completely new syntax
  837. X*   02/16/90  MarBru    Create..  Limited creation to composite widgets/objects
  838. X*
  839. X* Design_notes:
  840. X*
  841. X*******************************************************************************
  842. X*/
  843. X/*
  844. X*******************************************************************************
  845. X* Include_files.
  846. X*******************************************************************************
  847. X*/
  848. X
  849. X/*  -- Operating system includes */
  850. X#include <stdio.h>
  851. X
  852. X/*  -- X Window System includes */
  853. X#include <X11/StringDefs.h>
  854. X
  855. X/*  -- Widget Creation Includes */
  856. X#include "WcCreate.h"
  857. X#include "WcCreateP.h"
  858. X
  859. X/*
  860. X*******************************************************************************
  861. X* Private_data_definitions.
  862. X*******************************************************************************
  863. X*/
  864. X
  865. Xstatic char     msg[MAX_ERRMSG];
  866. X
  867. X/*  -- Creation resources 
  868. X    NOTE: All resource values are fetched at once, but if WcResFile
  869. X    is specified, then the resource files must be loaded and then
  870. X    the resources re-fetched.  This is an optimization: usually
  871. X    WcResFile is not specified, so two fetches from the Xrm database
  872. X    do not need to be done in the normal case.  If resource files are
  873. X    loaded and the resources are re-fetched, WcResFile is ignored.
  874. X    NOTE: The WcClass and WcClassName resources are both converted to
  875. X        a class pointer, as we can construct useful error messages using:
  876. X        class->core_class.class_name
  877. X    However, the Constructor must be the entire constructor cache
  878. X    record so we have the name of the constructor for the error
  879. X    messages.
  880. X    NOTE: WcClass and WcClassName write to different ResourceRec
  881. X    members, so we can provide better error messages.
  882. X*/
  883. X
  884. XXtResource wc_resources[] =
  885. X  {
  886. X    { WcNwcResFile,    WcCWcResFile,        XtRString,    sizeof(String),
  887. X      XtOffset(ResourceRecPtr, resFile ),    XtRImmediate,    (caddr_t) NULL
  888. X    },
  889. X    { WcNwcChildren,    WcCWcChildren,        XtRString,    sizeof(String),
  890. X      XtOffset(ResourceRecPtr, children ),    XtRImmediate,    (caddr_t) NULL
  891. X    },
  892. X    { WcNwcClass,    WcCWcClass,        WcRClassPtr,    sizeof(caddr_t),
  893. X      XtOffset(ResourceRecPtr, class ),        XtRImmediate,    (caddr_t) NULL
  894. X    },
  895. X    { WcNwcClassName,    WcCWcClassName,        WcRClassName,    sizeof(caddr_t),
  896. X      XtOffset(ResourceRecPtr, classFromName ),    XtRImmediate,    (caddr_t) NULL
  897. X    },
  898. X    { WcNwcConstructor,    WcCWcConstructor,     WcRConstructor,    sizeof(caddr_t),
  899. X      XtOffset(ResourceRecPtr, constructor ),    XtRImmediate,    (caddr_t) NULL
  900. X    },
  901. X    { WcNwcManaged,    WcCWcManaged,        XtRBoolean,    sizeof(Boolean),
  902. X      XtOffset(ResourceRecPtr, managed),    XtRImmediate,    (caddr_t) TRUE
  903. X    },
  904. X    { WcNwcTrace,    WcCWcTrace,        XtRBoolean,    sizeof(Boolean),
  905. X      XtOffset(ResourceRecPtr, trace),        XtRImmediate,    (caddr_t) FALSE
  906. X    },
  907. X    { WcNwcCallback,    WcCWcCallback,    XtRCallback,    sizeof(XtCallbackList),
  908. X      XtOffset(ResourceRecPtr, callback ),    XtRImmediate,    (caddr_t) NULL
  909. X    }
  910. X  };
  911. X
  912. X/*
  913. X*******************************************************************************
  914. X* Private_function_declarations.
  915. X*******************************************************************************
  916. X*/
  917. X
  918. X/*
  919. X*******************************************************************************
  920. X* Public_function_declarations.
  921. X*******************************************************************************
  922. X*/
  923. X
  924. X/*
  925. X    -- Create Database Child
  926. X*******************************************************************************
  927. X    This function checks the resource database for creation resources
  928. X    of the named widget. If found, the child is created using the specified
  929. X    class, and the creation callbacks are called.
  930. X
  931. X    Note that whenever this function generates a warning message, it
  932. X    uses the parent's name.  In order to improve run-time efficientcy,
  933. X    the parent name is only determined when a warning message is to be
  934. X    generated.  This adds a few lines of code, but it speeds the
  935. X    nominal case where there are no warnings.
  936. X*/
  937. X
  938. XWidget WcCreateDatabaseChild ( pw, name, managed  )
  939. X    Widget      pw;         /* child's parent */
  940. X    char*       name;       /* child name to create */
  941. X    int        *managed;    /* returned T/F: this child to be managed ? */
  942. X{
  943. X    ResourceRec res;               /* child's creation resources */
  944. X    Widget    child;               /* what we create */
  945. X
  946. X    /* Get creation resources for the child to be created.
  947. X    ** After this XtGetSubresources() call, the resource structure `res'
  948. X    ** contains resources specified in the Xrm database or the defaults.
  949. X    */
  950. X    XtGetSubresources ( pw, &res, name, name, 
  951. X       wc_resources, XtNumber(wc_resources), NULL, 0 );
  952. X
  953. X    /* if a resource file is specified for this widget, first
  954. X    ** load the resource file, then re-fetch the resources.
  955. X    ** Notice that we don't check for resFile again.
  956. X    */
  957. X    if ( res.resFile )
  958. X    {
  959. X    WcLoadResourceFileCB ( pw, res.resFile, NULL );
  960. X    XtGetSubresources ( pw, &res, name, name,
  961. X       wc_resources, XtNumber(wc_resources), NULL, 0 );
  962. X    }
  963. X
  964. X    if ( !res.class && !res.classFromName && !res.constructor )
  965. X    {
  966. X    char* parentName = WcWidgetToFullName( pw );
  967. X        sprintf( msg,
  968. X            "WcCreateDatabaseChild (%s.%s) - Failed \n\
  969. X             Problem: No %s, %s, nor %s specified,  \n\
  970. X                      Child `%s' could not be created.",
  971. X             parentName, name, 
  972. X         WcCWcClass, WcCWcClassName, WcCWcConstructor,
  973. X         name );
  974. X        XtWarning( msg );
  975. X    child = (Widget)NULL;
  976. X    XtFree( parentName );
  977. X    }
  978. X
  979. X    else if ( res.class || res.classFromName )
  980. X    {
  981. X    if ( res.class && res.classFromName && res.constructor )
  982. X    {
  983. X        char* parentName = WcWidgetToFullName( pw );
  984. X        sprintf( msg,
  985. X            "WcCreateDatabaseChild (%s.%s) \n\
  986. X             Problem: %s, %s, and %s resources specified, \n\
  987. X              `%s.%s: %s' and \n\
  988. X              `%s.%s: %s' ignored.",
  989. X             parentName, name, 
  990. X         WcCWcClass, WcCWcClassName, WcCWcConstructor,
  991. X         name, WcCWcClassName, res.classFromName->core_class.class_name,
  992. X         name, WcCWcConstructor, res.constructor->name );
  993. X            XtWarning( msg );
  994. X        XtFree( parentName );
  995. X    }
  996. X    else if ( res.class && res.classFromName )
  997. X    {
  998. X        char* parentName = WcWidgetToFullName( pw );
  999. X            sprintf( msg,
  1000. X            "WcCreateDatabaseChild (%s.%s) \n\
  1001. X             Problem: %s and %s resources specified, \n\
  1002. X                      `%s.%s: %s' ignored.",
  1003. X             parentName, name,
  1004. X             WcCWcClass, WcCWcClassName, 
  1005. X             name, WcCWcClassName, res.classFromName->core_class.class_name);
  1006. X            XtWarning( msg );
  1007. X        XtFree( parentName );
  1008. X        }
  1009. X        else if ( res.class && res.constructor )
  1010. X        {
  1011. X        char* parentName = WcWidgetToFullName( pw );
  1012. X            sprintf( msg,
  1013. X            "WcCreateDatabaseChild (%s.%s) \n\
  1014. X             Problem: %s and %s resources specified, \n\
  1015. X                      `%s.%s: %s' ignored.",
  1016. X             parentName, name,
  1017. X             WcCWcClass, WcCWcConstructor,
  1018. X             name, WcCWcConstructor, res.constructor->name );
  1019. X            XtWarning( msg );
  1020. X        XtFree( parentName );
  1021. X        }
  1022. X        else if ( res.classFromName && res.constructor )
  1023. X        {
  1024. X        char* parentName = WcWidgetToFullName( pw );
  1025. X            sprintf( msg,
  1026. X            "WcCreateDatabaseChild (%s.%s) \n\
  1027. X             Problem: %s and %s resources specified, \n\
  1028. X                      `%s.%s: %s' ignored.",
  1029. X             parentName, name,
  1030. X             WcCWcClassName, WcCWcConstructor,
  1031. X             name, WcCWcConstructor, res.constructor->name );
  1032. X            XtWarning( msg );
  1033. X        XtFree( parentName );
  1034. X        }
  1035. X
  1036. X    if ( res.class )
  1037. X        child = XtCreateWidget ( name, res.class, pw, NULL, 0 );
  1038. X    else
  1039. X        child = XtCreateWidget ( name, res.classFromName, pw, NULL, 0 );
  1040. X
  1041. X    if ( !child )
  1042. X    {
  1043. X        char* parentName = WcWidgetToFullName( pw );
  1044. X            sprintf( msg,
  1045. X            "WcCreateDatabaseChild (%s.%s) - Failed \n\
  1046. X             Problem: XtCreateWidget ( %s, %s ) failed.",
  1047. X             parentName, name, name, res.class->core_class.class_name );
  1048. X            XtWarning( msg );
  1049. X        XtFree( parentName );
  1050. X    }
  1051. X    }
  1052. X
  1053. X    else if ( res.constructor )
  1054. X    {
  1055. X    child = res.constructor->constructor( pw, name, NULL, 0 );
  1056. X
  1057. X    if ( !child )
  1058. X        {
  1059. X        char* parentName = WcWidgetToFullName( pw );
  1060. X            sprintf( msg,
  1061. X            "WcCreateDatabaseChild (%s.%s) - Failed \n\
  1062. X             Problem: %s ( %s ) failed.",
  1063. X             parentName, name, res.constructor->name, name );
  1064. X            XtWarning( msg );
  1065. X        XtFree( parentName );
  1066. X        }
  1067. X    }
  1068. X
  1069. X    if ( child )
  1070. X    {
  1071. X    /* A child widget was created.
  1072. X    ** print out creation trace, if required 
  1073. X    */
  1074. X    if ( res.trace )
  1075. X    {
  1076. X        char* childName = WcWidgetToFullName( child );
  1077. X        fprintf(stderr,"Wc %s: %s of class %s\n",
  1078. X        ((res.managed) ? "  managed" : "unmanaged"), childName, 
  1079. X        child->core.widget_class->core_class.class_name);
  1080. X        XtFree( childName  );
  1081. X    }
  1082. X
  1083. X    /* call creation callbacks */
  1084. X    if ( res.callback )
  1085. X    {
  1086. X        XtCallbackRec *cb = res.callback;
  1087. X        for ( ; cb->callback; cb++ )
  1088. X        (*cb->callback)( child, cb->closure, NULL );
  1089. X    }
  1090. X
  1091. X    if ( res.children )
  1092. X    {
  1093. X        if  ( XtIsSubclass( child, compositeWidgetClass ) )
  1094. X        {
  1095. X        /* child is a manager widget, create its children */
  1096. X            WcCreateNamedChildren ( child, res.children );        
  1097. X        }
  1098. X        else
  1099. X        {
  1100. X        char* parentName = WcWidgetToFullName( pw );
  1101. X                sprintf( msg,
  1102. X            "WcCreateDatabaseChild (%s.%s) - children ignored \n\
  1103. X             Problem: %s is not a composite, cannot have children.",
  1104. X             parentName, name, name );
  1105. X                XtWarning( msg );
  1106. X        XtFree( parentName );
  1107. X        }
  1108. X    }
  1109. X    }
  1110. X
  1111. X    *managed = res.managed;
  1112. X    return (child);
  1113. X}
  1114. X
  1115. X/*
  1116. X    -- Create And Manage Named Children from Xrm Database
  1117. X*******************************************************************************
  1118. X    This function creates widget's children specified by names list,
  1119. X    by calling WcCreateDatabaseChild() for each of the names provided.
  1120. X
  1121. X    All the children are then managed, unless WcManaged resource is FALSE.
  1122. X
  1123. X    Note that widgets created by WcCreateDatabaseChild may or may not
  1124. X    be children of `pw' due to the use of constructors.  Only children
  1125. X    of `pw' may be managed via a call to XtManageChildren().  Other
  1126. X    widgets must be managed individually.  Usually, these widgets
  1127. X    are created by the XmCreateScrolled*() or XmCreate*Dialog confusion 
  1128. X    functions.
  1129. X*/
  1130. X
  1131. Xvoid WcCreateNamedChildren ( pw, names )
  1132. X    Widget      pw;         /* children's parent                            */
  1133. X    char*       names;      /* (list of) widget names to create             */
  1134. X{
  1135. X    Widget    child;
  1136. X    int        children = 0;
  1137. X    Widget    widget_children[MAX_CHILDREN];
  1138. X    int        other = 0;
  1139. X    Widget    widget_other[MAX_CHILDREN];
  1140. X    char    cleanName[MAX_XRMSTRING];
  1141. X    char*    next;
  1142. X    int        managed;
  1143. X    int        i;
  1144. X
  1145. X    if  ( !names ) return;
  1146. X
  1147. X    next = WcCleanName( names, cleanName );
  1148. X
  1149. X    while ( cleanName[0] )
  1150. X    {
  1151. X    child = WcCreateDatabaseChild ( pw, cleanName, &managed );
  1152. X    if ( child )
  1153. X    {
  1154. X        if ( managed && (XtParent( child ) == pw ) )
  1155. X        widget_children[children++] = child;
  1156. X        else if ( managed )
  1157. X        widget_other[other++] = child;
  1158. X    }
  1159. X    next = WcSkipWhitespace_Comma( next );
  1160. X    next = WcCleanName( next, cleanName );
  1161. X    }
  1162. X
  1163. X    if ( children ) 
  1164. X    XtManageChildren( widget_children, children );
  1165. X
  1166. X    for (i = 0 ; i < other ; i++)
  1167. X    XtManageChild( widget_other[i] );
  1168. X}
  1169. X
  1170. X/*
  1171. X    -- Create Widget Tree from Xrm Database
  1172. X*******************************************************************************
  1173. X    This routine creates widget children as defined in Xrm database.
  1174. X    It checks the widget resource "WcChildren", which is a list of
  1175. X    names of children to create. Each child must then be further defined
  1176. X    in the databse.
  1177. X
  1178. X    This function is frequently called from an application's main()
  1179. X    procedure after the application shell is created via XtInitialize().
  1180. X
  1181. X    Note that this function registers the converters for StringToWidget,
  1182. X    StringToCallback, and so forth.
  1183. X*/
  1184. X
  1185. Xvoid WcWidgetCreation ( root )
  1186. X    Widget       root;
  1187. X{
  1188. X    XtAppContext app = XtWidgetToApplicationContext( root );
  1189. X    char*     fullName = WcWidgetToFullName( root );    /* must be XtFree'd */
  1190. X    ResourceRec  res;
  1191. X
  1192. X    /* register the root of this widget */
  1193. X    (void)WcRootWidget(root);
  1194. X
  1195. X    /* register the Xt standard widgets */
  1196. X    WcRegisterIntrinsic ( app );
  1197. X
  1198. X    /* register the Wc converters */
  1199. X    WcAddConverters( app );
  1200. X
  1201. X    /* register the Wc callbacks */
  1202. X    WcRegisterWcCallbacks ( app );
  1203. X
  1204. X    /* register the Wc actions */
  1205. X    WcRegisterWcActions ( app );
  1206. X
  1207. X    if ( XtIsSubclass( root, compositeWidgetClass ) )
  1208. X    {
  1209. X        XtGetApplicationResources ( root, &res,
  1210. X              wc_resources, XtNumber(wc_resources), NULL, 0 );
  1211. X    
  1212. X        if ( res.children )
  1213. X           WcCreateNamedChildren ( root, res.children );
  1214. X        else
  1215. X        {
  1216. X            sprintf( msg,
  1217. X            "WcWidgetCreation (%s) - Failed \n\
  1218. X             Problem: No children defined in Xrm database.\n\
  1219. X         Possible: resource file not found (XENVIRONEMENT not set?), \n\
  1220. X         Possible: top level widget in resource file not named %s",
  1221. X             fullName, root->core.name );
  1222. X            XtWarning( msg );
  1223. X    }
  1224. X    }
  1225. X
  1226. X     else
  1227. X    {
  1228. X        sprintf( msg,
  1229. X            "WcWidgetCreation (%s) - Failed \n\
  1230. X             Problem: %s is not a composite widget, cannot have children.",
  1231. X             fullName, fullName );
  1232. X        XtWarning( msg );
  1233. X    }
  1234. X
  1235. X    XtFree ( fullName );
  1236. X}
  1237. +FUNKY+STUFF+
  1238. echo '-rw-r--r--  1 david       22768 Sep  6 13:21 WcCreate.c    (as sent)'
  1239. chmod u=rw,g=r,o=r WcCreate.c
  1240. ls -l WcCreate.c
  1241. echo x - WcCreate.h
  1242. sed 's/^X//' > WcCreate.h <<'+FUNKY+STUFF+'
  1243. X/*
  1244. X** Copyright (c) 1990 David E. Smyth
  1245. X**
  1246. X** This file was derived from work performed by Martin Brunecky at
  1247. X** Auto-trol Technology Corporation, Denver, Colorado, under the
  1248. X** following copyright:
  1249. X**
  1250. X*******************************************************************************
  1251. X* Copyright 1990 by Auto-trol Technology Corporation, Denver, Colorado.
  1252. X*
  1253. X*                        All Rights Reserved
  1254. X*
  1255. X* Permission to use, copy, modify, and distribute this software and its
  1256. X* documentation for any purpose and without fee is hereby granted, provided
  1257. X* that the above copyright notice appears on all copies and that both the
  1258. X* copyright and this permission notice appear in supporting documentation
  1259. X* and that the name of Auto-trol not be used in advertising or publicity
  1260. X* pertaining to distribution of the software without specific, prior written
  1261. X* permission.
  1262. X* 
  1263. X* Auto-trol disclaims all warranties with regard to this software, including
  1264. X* all implied warranties of merchantability and fitness, in no event shall
  1265. X* Auto-trol be liable for any special, indirect or consequential damages or
  1266. X* any damages whatsoever resulting from loss of use, data or profits, whether 
  1267. X* in an action of contract, negligence or other tortious action, arising out 
  1268. X* of or in connection with the use or performance of this software.
  1269. X*******************************************************************************
  1270. X**
  1271. X** Redistribution and use in source and binary forms are permitted
  1272. X** provided that the above copyright notice and this paragraph are
  1273. X** duplicated in all such forms and that any documentation, advertising
  1274. X** materials, and other materials related to such distribution and use
  1275. X** acknowledge that the software was developed by David E. Smyth.  The
  1276. X** name of David E. Smyth may not be used to endorse or promote products
  1277. X** derived from this software without specific prior written permission.
  1278. X** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  1279. X** WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  1280. X** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  1281. X**
  1282. X*/
  1283. X
  1284. X/*
  1285. X* SCCS_data: @(#)WcCreate.h 1.03 ( 16 July 1990 )
  1286. X*
  1287. X* Include_name:
  1288. X*
  1289. X*     WcCreate.h
  1290. X*
  1291. X* Subsystem_group:
  1292. X*
  1293. X*     Widget Creation Library
  1294. X*
  1295. X* Include_description:
  1296. X*
  1297. X*     Public defines for the Widget Creation Library supporting widget 
  1298. X*     tree creation from the Xrm database.
  1299. X*
  1300. X* Include_history:
  1301. X*
  1302. X*   mm/dd/yy  initials  action
  1303. X*   --------  --------  -------------------------------------------------------
  1304. X*   07/16/90   D.Smyth  added WcAllowDuplicate*Reg... decls
  1305. X*   06/30/90   R.Whitby added WcRegisterWcActions declaration
  1306. X*   06/19/90   D.Smyth  Widget Creation Library version 1.0 Release
  1307. X*   04/04/90   marbru   updated, added new callbacks
  1308. X*   03/27/90   marbru   updated for new names
  1309. X*   03/02/90   marbru   created
  1310. X*
  1311. X*******************************************************************************
  1312. X*/
  1313. X#ifndef _WcCreate_h
  1314. X#define _WcCreate_h
  1315. X
  1316. X#include <X11/IntrinsicP.h>
  1317. X#include <X11/CoreP.h>
  1318. X#include <X11/ObjectP.h>
  1319. X
  1320. X#ifdef FUNCTION_PROTOTYPES
  1321. X/****************************** ANSI FUNC DECLS ******************************/
  1322. X
  1323. X#define APP XtAppContext
  1324. X#define EV extern void
  1325. X#define EW extern Widget
  1326. X#define EC extern char*
  1327. X
  1328. X/* -- Widget class, constructor, and callback proc registration routines */
  1329. X
  1330. XEV WcRegisterClassPtr   (APP, char* name,   WidgetClass class);
  1331. XEV WcRegisterClassName  (APP, char* name,   WidgetClass class);
  1332. XEV WcRegisterConstructor(APP, char* name,   Widget(*constructor) () );
  1333. XEV WcRegisterCallback   (APP, char* CBname, XtCallbackProc, caddr_t defCliData);
  1334. XEV WcRegisterAction    (APP, char* name,   XtActionProc proc );
  1335. XEV WcRegisterWcCallbacks(APP );
  1336. X
  1337. X/* -- Allow duplicate registration of classes, constructors, and callbacks */
  1338. X
  1339. XEV WcAllowDuplicateRegistration   ( int allowed );
  1340. XEV WcAllowDuplicateClassPtrReg    ( int allowed );
  1341. XEV WcAllowDuplicateClassNameReg   ( int allowed );
  1342. XEV WcAllowDuplicateConstructorReg ( int allowed );
  1343. XEV WcAllowDuplicateCallbackReg    ( int allowed );
  1344. X
  1345. X/* -- Widget action registration routine */
  1346. X
  1347. XEV WcRegisterWcActions   ( APP );
  1348. X
  1349. X/* -- Widget creation routines */
  1350. X
  1351. XEV WcWidgetCreation      ( Widget root );
  1352. XEV WcCreateNamedChildren ( Widget parent, char* names );
  1353. XEW WcCreateDatabaseChild ( Widget parent, char* name, int* managed );
  1354. X
  1355. X/* -- Widget name routines 
  1356. X**    The character buffer returned by WcNamesToWidgetList contains the
  1357. X**    names which could not be converted to widgets.  This buffer is static,
  1358. X**    so its contents are changed everytime WcNamesToWidgetList is called.
  1359. X**    The character buffer returned by WcWidgetToFullName must be XtFree'd
  1360. X**    by the caller.
  1361. X*/
  1362. X
  1363. XEW WcChildNameToWidget ( Widget w, char* childName );
  1364. XEW WcFullNameToWidget  ( Widget w, char* name );
  1365. XEC WcNamesToWidgetList ( Widget, char* names, Widget widgetList[], int* count);
  1366. XEC WcWidgetToFullName  ( Widget w );
  1367. X
  1368. X/*  -- Useful for argument parsing */
  1369. X
  1370. XEC WcLowerCaseCopy        ( char* in );            /* caller frees buf */
  1371. XEC WcSkipWhitespace       ( char* cp );
  1372. XEC WcSkipWhitespace_Comma ( char* cp );
  1373. XEC WcCleanName            ( char* in, char* out );    /* out[] must exist */
  1374. XEC WcStripWhitespaceFromBothEnds (char* name );        /* caller frees buf */
  1375. X
  1376. XEC WcGetResourceType          ( Widget, char* rName );    /* caller frees buf */
  1377. XEV WcSetValueFromString       ( Widget, char* rName, char* rVal );
  1378. XEV WcSetValueFromStringAndType( Widget, char* rName, char* rVal, char* rType );
  1379. X
  1380. XEC WcStrStr( char* searchThis, char* forThisPattern );    /* like ANSI strstr */
  1381. X
  1382. X#undef APP
  1383. X#undef EV
  1384. X#undef EW
  1385. X#undef EC
  1386. X
  1387. X#else
  1388. X/**************************** NON-ANSI FUNC DECLS ****************************/
  1389. X
  1390. X/* -- Widget constructor registration routine */
  1391. X
  1392. Xextern void WcRegisterClassPtr    ();
  1393. Xextern void WcRegisterClassName   ();
  1394. Xextern void WcRegisterConstructor ();
  1395. Xextern void WcRegisterCallback    ();
  1396. Xextern void WcRegisterAction      ();
  1397. Xextern void WcRegisterWcCallbacks ();
  1398. X
  1399. X/* -- Allow duplicate registration of classes, constructors, and callbacks */
  1400. X
  1401. Xextern void WcAllowDuplicateRegistration   ();
  1402. Xextern void WcAllowDuplicateClassPtrReg    ();
  1403. Xextern void WcAllowDuplicateClassNameReg   ();
  1404. Xextern void WcAllowDuplicateConstructorReg ();
  1405. Xextern void WcAllowDuplicateCallbackReg    ();
  1406. X
  1407. X/* -- Widget action registration routine */
  1408. X
  1409. Xextern void WcRegisterWcActions       ();
  1410. X
  1411. X/* -- Widget creation routines */
  1412. X
  1413. Xextern void   WcWidgetCreation         ();
  1414. Xextern void   WcCreateNamedChildren    ();
  1415. Xextern Widget WcCreateDatabaseChild    ();
  1416. X
  1417. X/* -- Widget name routine */
  1418. X
  1419. Xextern Widget WcChildNameToWidget    ();
  1420. Xextern Widget WcFullNameToWidget    ();
  1421. Xextern char*  WcNamesToWidgetList    ();    /* rets: names not converted */
  1422. Xextern char*  WcWidgetToFullName    ();    /* ret'd buff must be free'd */
  1423. X
  1424. Xextern char* WcLowerCaseCopy               ();    /* ret'd buff must be free'd */
  1425. Xextern char* WcSkipWhitespace              ();
  1426. Xextern char* WcSkipWhitespace_Comma        ();
  1427. Xextern char* WcCleanName                   ();
  1428. Xextern char* WcStripWhitespaceFromBothEnds ();    /* ret'd buff must be free'd */
  1429. X
  1430. Xextern char* WcGetResourceType             ();    /* ret'd buff must be free'd */
  1431. Xextern void  WcSetValueFromString          ();
  1432. Xextern void  WcSetValueFromStringAndType   ();
  1433. X
  1434. Xextern char* WcStrStr ();            /* same as ANSI strstr() */
  1435. X
  1436. X#endif /* FUNCTION_PROTOTYPES */
  1437. X
  1438. X#endif /* _WcCreate_h */
  1439. +FUNKY+STUFF+
  1440. echo '-rw-r--r--  1 david        7319 Oct  9 14:55 WcCreate.h    (as sent)'
  1441. chmod u=rw,g=r,o=r WcCreate.h
  1442. ls -l WcCreate.h
  1443. exit 0
  1444.  
  1445. dan
  1446. ----------------------------------------------------
  1447. O'Reilly && Associates   argv@sun.com / argv@ora.com
  1448. Opinions expressed reflect those of the author only.
  1449. --
  1450. dan
  1451. ----------------------------------------------------
  1452. O'Reilly && Associates   argv@sun.com / argv@ora.com
  1453. Opinions expressed reflect those of the author only.
  1454.