home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume8 / wcl / part04 < prev    next >
Encoding:
Internet Message Format  |  1990-07-06  |  67.2 KB

  1. Path: uunet!midway!ncar!asuvax!cs.utexas.edu!sun-barr!newstop!sun!devvax.Jpl.Nasa.Gov
  2. From: david@devvax.Jpl.Nasa.Gov (David E. Smyth)
  3. Newsgroups: comp.sources.x
  4. Subject: v08i034: wcl - Widget Creation Library, Part04/06
  5. Message-ID: <138460@sun.Eng.Sun.COM>
  6. Date: 6 Jul 90 07:40:54 GMT
  7. Sender: news@sun.Eng.Sun.COM
  8. Lines: 2130
  9. Approved: argv@sun.com
  10.  
  11. Submitted-by: david@devvax.Jpl.Nasa.Gov (David E. Smyth)
  12. Posting-number: Volume 8, Issue 34
  13. Archive-name: wcl/part04
  14.  
  15. # to unbundle, "sh" this file -- DO NOT use csh
  16. #  SHAR archive format.  Archive created Tue Jul 3 16:49:19 PDT 1990
  17. echo x - WcActions.c
  18. sed 's/^X//' > WcActions.c <<'+FUNKY+STUFF+'
  19. X/*
  20. X** Copyright (c) 1990 Rodney J. Whitby
  21. X**
  22. X** This file was derived from work performed by David E. Smyth under the
  23. X** following copyright:
  24. X**
  25. X*******************************************************************************
  26. X** Copyright (c) 1990 David E. Smyth
  27. X**
  28. X** This file was derived from work performed by Martin Brunecky at
  29. X** Auto-trol Technology Corporation, Denver, Colorado, under the
  30. X** following copyright:
  31. X**
  32. X*******************************************************************************
  33. X* Copyright 1990 by Auto-trol Technology Corporation, Denver, Colorado.
  34. X*
  35. X*                        All Rights Reserved
  36. X*
  37. X* Permission to use, copy, modify, and distribute this software and its
  38. X* documentation for any purpose and without fee is hereby granted, provided
  39. X* that the above copyright notice appears on all copies and that both the
  40. X* copyright and this permission notice appear in supporting documentation
  41. X* and that the name of Auto-trol not be used in advertising or publicity
  42. X* pertaining to distribution of the software without specific, prior written
  43. X* permission.
  44. X*
  45. X* Auto-trol disclaims all warranties with regard to this software, including
  46. X* all implied warranties of merchantability and fitness, in no event shall
  47. X* Auto-trol be liable for any special, indirect or consequential damages or
  48. X* any damages whatsoever resulting from loss of use, data or profits, whether
  49. X* in an action of contract, negligence or other tortious action, arising out
  50. X* of or in connection with the use or performance of this software.
  51. X*******************************************************************************
  52. X**
  53. X** Redistribution and use in source and binary forms are permitted
  54. X** provided that the above copyright notice and this paragraph are
  55. X** duplicated in all such forms and that any documentation, advertising
  56. X** materials, and other materials related to such distribution and use
  57. X** acknowledge that the software was developed by David E. Smyth.  The
  58. X** name of David E. Smyth may not be used to endorse or promote products
  59. X** derived from this software without specific prior written permission.
  60. X** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  61. X** WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  62. X** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  63. X**
  64. X*/
  65. X
  66. X/*
  67. X* SCCS_data: @(#)WcActions.c 1.0 ( 30 June 1990 )
  68. X*
  69. X* Subsystem_group:
  70. X*
  71. X*     Widget Creation Library
  72. X*
  73. X* Module_description:
  74. X*
  75. X*     This module contains the convenience actions used to create and 
  76. X*     manage a widget tree using the Xrm databse.
  77. X*
  78. X*     Several convenience actions are provided with the package, allowing 
  79. X*     deferred widget creation, control (manage/unmanage) and other utility
  80. X*     functions.
  81. X*
  82. X* Module_interface_summary: 
  83. X*
  84. X*     Convenience Actions:
  85. X*
  86. X* Module_history:
  87. X*                                                  
  88. X*   All actions and the action registration routine were made by
  89. X*   Rod Whitby following about 30 June 1990.
  90. X*
  91. X* Design_notes:
  92. X*
  93. X*******************************************************************************
  94. X*/
  95. X/*
  96. X*******************************************************************************
  97. X* Include_files.
  98. X*******************************************************************************
  99. X*/
  100. X
  101. X#include "WidgetCreate.h"
  102. X#include "WidgetCreateP.h"
  103. X
  104. X/*
  105. X*******************************************************************************
  106. X* Private_type_declarations.
  107. X*******************************************************************************
  108. X*/
  109. X
  110. X/*
  111. X*******************************************************************************
  112. X* Private_macro_definitions.
  113. X*******************************************************************************
  114. X*/
  115. X
  116. X/*
  117. X*******************************************************************************
  118. X* Private_data_definitions.
  119. X*******************************************************************************
  120. X*/
  121. X
  122. X/*
  123. X*******************************************************************************
  124. X* Private_function_declarations.
  125. X*******************************************************************************
  126. X*/
  127. X
  128. X/*
  129. X*******************************************************************************
  130. X* Public_action_function_declarations.
  131. X*******************************************************************************
  132. X*/
  133. X
  134. X/*
  135. X    -- Create Deferred Children from Xrm Database
  136. X*******************************************************************************
  137. X*/
  138. Xvoid    WcCreateChildrenACT( w, event, params, num_params )
  139. XWidget        w;
  140. XXEvent       *event;
  141. XString       *params;
  142. XCardinal   *num_params;
  143. X{
  144. X  char *data;
  145. X  int    i;
  146. X
  147. X  if (*num_params < 2) {
  148. X    WcCreateChildrenCB(w, "", NULL);
  149. X    return;
  150. X  }
  151. X
  152. X  for (i = 1; i < *num_params; i++) {
  153. X    data = XtMalloc(strlen(params[0]) + strlen(params[i]) + 2);
  154. X    (void)strcpy(data, params[0]);
  155. X    (void)strcat(data, ",");
  156. X    (void)strcat(data, params[i]);
  157. X    WcCreateChildrenCB(w, data, NULL);
  158. X    XtFree(data);
  159. X  }
  160. X}
  161. X
  162. X
  163. X/*
  164. X    -- Manage or Unmanage named widget(s)
  165. X*******************************************************************************
  166. X*/
  167. Xvoid    WcManageACT( w, event, params, num_params )
  168. XWidget        w;
  169. XXEvent       *event;
  170. XString       *params;
  171. XCardinal   *num_params;
  172. X{
  173. X  int    i;
  174. X
  175. X  if (*num_params < 1) {
  176. X    WcManageCB(w, "", NULL);
  177. X    return;
  178. X  }
  179. X
  180. X  for (i = 0; i < *num_params; i++) {
  181. X    WcManageCB(w, params[i], NULL);
  182. X  }
  183. X}
  184. X
  185. X
  186. Xvoid    WcUnmanageACT( w, event, params, num_params )
  187. XWidget        w;
  188. XXEvent       *event;
  189. XString       *params;
  190. XCardinal   *num_params;
  191. X{
  192. X  int    i;
  193. X
  194. X  if (*num_params < 1) {
  195. X    WcUnmanageCB(w, "", NULL);
  196. X    return;
  197. X  }
  198. X
  199. X  for (i = 0; i < *num_params; i++) {
  200. X    WcUnmanageCB(w, params[i], NULL);
  201. X  }
  202. X}
  203. X
  204. X
  205. X/*
  206. X    -- Manage or unamange named children action
  207. X*******************************************************************************
  208. X*/
  209. Xvoid    WcManageChildrenACT( w, event, params, num_params )
  210. XWidget        w;
  211. XXEvent       *event;
  212. XString       *params;
  213. XCardinal   *num_params;
  214. X{
  215. X  int    i;
  216. X
  217. X  char *data;
  218. X
  219. X  if (*num_params < 2) {
  220. X    WcManageChildrenCB(w, "", NULL);
  221. X    return;
  222. X  }
  223. X
  224. X  for (i = 1; i < *num_params; i++) {
  225. X    data = XtMalloc(strlen(params[0]) + strlen(params[i]) + 2);
  226. X    (void)strcpy(data, params[0]);
  227. X    (void)strcat(data, ",");
  228. X    (void)strcat(data, params[i]);
  229. X    WcManageChildrenCB(w, data, NULL);
  230. X    XtFree(data);
  231. X  }
  232. X}
  233. X
  234. X
  235. Xvoid    WcUnmanageChildrenACT( w, event, params, num_params )
  236. XWidget        w;
  237. XXEvent       *event;
  238. XString       *params;
  239. XCardinal   *num_params;
  240. X{
  241. X  int    i;
  242. X
  243. X  char *data;
  244. X
  245. X  if (*num_params < 2) {
  246. X    WcUnmanageChildrenCB(w, "", NULL);
  247. X    return;
  248. X  }
  249. X
  250. X  for (i = 1; i < *num_params; i++) {
  251. X    data = XtMalloc(strlen(params[0]) + strlen(params[i]) + 2);
  252. X    (void)strcpy(data, params[0]);
  253. X    (void)strcat(data, ",");
  254. X    (void)strcat(data, params[i]);
  255. X    WcUnmanageChildrenCB(w, data, NULL);
  256. X    XtFree(data);
  257. X  }
  258. X}
  259. X
  260. X
  261. X/*
  262. X    -- Destroy named children action
  263. X*******************************************************************************
  264. X*/
  265. Xvoid    WcDestroyACT( w, event, params, num_params )
  266. XWidget        w;
  267. XXEvent       *event;
  268. XString       *params;
  269. XCardinal   *num_params;
  270. X{
  271. X  int    i;
  272. X
  273. X  if (*num_params < 1) {
  274. X    WcDestroyCB(w, "", NULL);
  275. X    return;
  276. X  }
  277. X
  278. X  for (i = 0; i < *num_params; i++) {
  279. X    WcDestroyCB(w, params[i], NULL);
  280. X  }
  281. X}
  282. X
  283. X
  284. X/*
  285. X   -- Set Resource Value on Widget
  286. X*******************************************************************************
  287. X*/
  288. Xvoid    WcSetValueACT( w, event, params, num_params )
  289. XWidget        w;
  290. XXEvent       *event;
  291. XString       *params;
  292. XCardinal   *num_params;
  293. X{
  294. X  if (*num_params != 1) {
  295. X    WcSetValueCB(w, "", NULL);
  296. X    return;
  297. X  }
  298. X
  299. X  WcSetValueCB(w, params[0], NULL);
  300. X}
  301. X
  302. X
  303. X/*
  304. X    -- Change sensitivity of widgets.
  305. X*******************************************************************************
  306. X*/
  307. Xvoid    WcSetSensitiveACT( w, event, params, num_params )
  308. XWidget        w;
  309. XXEvent       *event;
  310. XString       *params;
  311. XCardinal   *num_params;
  312. X{
  313. X  int    i;
  314. X
  315. X  if (*num_params < 1) {
  316. X    WcSetSensitiveCB(w, "", NULL);
  317. X    return;
  318. X  }
  319. X
  320. X  for (i = 0; i < *num_params; i++) {
  321. X    WcSetSensitiveCB(w, params[i], NULL);
  322. X  }
  323. X}
  324. X
  325. X
  326. Xvoid    WcSetInsensitiveACT( w, event, params, num_params )
  327. XWidget        w;
  328. XXEvent       *event;
  329. XString       *params;
  330. XCardinal   *num_params;
  331. X{
  332. X  int    i;
  333. X
  334. X  if (*num_params < 1) {
  335. X    WcSetInsensitiveCB(w, "", NULL);
  336. X    return;
  337. X  }
  338. X
  339. X  for (i = 0; i < *num_params; i++) {
  340. X    WcSetInsensitiveCB(w, params[i], NULL);
  341. X  }
  342. X}
  343. X
  344. X
  345. X/*
  346. X    -- Load Resource File
  347. X*******************************************************************************
  348. X*/
  349. Xvoid    WcLoadResourceFileACT( w, event, params, num_params )
  350. XWidget        w;
  351. XXEvent       *event;
  352. XString       *params;
  353. XCardinal   *num_params;
  354. X{
  355. X  if (*num_params != 1) {
  356. X    WcLoadResourceFileCB(w, "", NULL);
  357. X    return;
  358. X  }
  359. X
  360. X  WcLoadResourceFileCB(w, params[0], NULL);
  361. X}
  362. X
  363. X
  364. X/*
  365. X  -- WcTraceAction
  366. X*******************************************************************************
  367. X*/
  368. Xvoid    WcTraceACT( w, event, params, num_params )
  369. XWidget        w;
  370. XXEvent       *event;
  371. XString       *params;
  372. XCardinal   *num_params;
  373. X{
  374. X  if (*num_params != 1) {
  375. X    WcTraceCB(w, "", NULL);
  376. X    return;
  377. X  }
  378. X
  379. X  WcTraceCB(w, params[0], NULL);
  380. X}
  381. X
  382. X
  383. X/*
  384. X  -- Popup named widget
  385. X*******************************************************************************
  386. X*/
  387. Xvoid    WcPopupACT( w, event, params, num_params )
  388. XWidget        w;
  389. XXEvent       *event;
  390. XString       *params;
  391. XCardinal   *num_params;
  392. X{
  393. X  if (*num_params != 1) {
  394. X    WcPopupCB(w, "", NULL);
  395. X    return;
  396. X  }
  397. X
  398. X  WcPopupCB(w, params[0], NULL);
  399. X}
  400. X
  401. X
  402. Xvoid    WcPopupGrabACT( w, event, params, num_params )
  403. XWidget        w;
  404. XXEvent       *event;
  405. XString       *params;
  406. XCardinal   *num_params;
  407. X{
  408. X  if (*num_params != 1) {
  409. X    WcPopupGrabCB(w, "", NULL);
  410. X    return;
  411. X  }
  412. X
  413. X  WcPopupGrabCB(w, params[0], NULL);
  414. X}
  415. X
  416. X
  417. X/*
  418. X  -- Popdown named widget
  419. X*******************************************************************************
  420. X*/
  421. Xvoid    WcPopdownACT( w, event, params, num_params )
  422. XWidget        w;
  423. XXEvent       *event;
  424. XString       *params;
  425. XCardinal   *num_params;
  426. X{
  427. X  if (*num_params != 1) {
  428. X    WcPopdownCB(w, "", NULL);
  429. X    return;
  430. X  }
  431. X
  432. X  WcPopdownCB(w, params[0], NULL);
  433. X}
  434. X
  435. X
  436. X/*
  437. X  -- Invoke shell command
  438. X*******************************************************************************
  439. X*/
  440. Xvoid    WcSystemACT( w, event, params, num_params )
  441. XWidget        w;
  442. XXEvent       *event;
  443. XString       *params;
  444. XCardinal   *num_params;
  445. X{
  446. X  if (*num_params != 1) {
  447. X    WcSystemCB(w, "", NULL);
  448. X    return;
  449. X  }
  450. X
  451. X  WcSystemCB(w, params[0], NULL);
  452. X}
  453. X
  454. X
  455. X/*
  456. X  -- Exit the application
  457. X*******************************************************************************
  458. X*/
  459. Xvoid    WcExitACT( w, event, params, num_params )
  460. XWidget        w;
  461. XXEvent       *event;
  462. XString       *params;
  463. XCardinal   *num_params;
  464. X{
  465. X  if (*num_params != 1) {
  466. X    WcExitCB(w, "", NULL);
  467. X    return;
  468. X  }
  469. X
  470. X  WcExitCB(w, params[0], NULL);
  471. X}
  472. X
  473. X
  474. X/*
  475. X  -- WcRegisterWcActions
  476. X*******************************************************************************
  477. X   Convenience routine, registering all standard actions in one application
  478. X   call.   Called from WcWidgetCreation(), so application usually never needs
  479. X   to call this.
  480. X*/
  481. X
  482. Xvoid WcRegisterWcActions ( app )
  483. XXtAppContext app;
  484. X{
  485. X    static XtActionsRec WcActions[] = {
  486. X      {"WcCreateChildrenACT",    WcCreateChildrenACT    },
  487. X      {"WcManageACT",        WcManageACT        },
  488. X      {"WcUnmanageACT",        WcUnmanageACT        },
  489. X      {"WcManageChildrenACT",    WcManageChildrenACT    },
  490. X      {"WcUnmanageChildrenACT",    WcUnmanageChildrenACT    },
  491. X      {"WcDestroyACT",        WcDestroyACT        },
  492. X      {"WcSetValueACT",        WcSetValueACT        },
  493. X      {"WcSetSensitiveACT",    WcSetSensitiveACT    },
  494. X      {"WcSetInsensitiveACT",    WcSetInsensitiveACT    },
  495. X      {"WcLoadResourceFileACT",    WcLoadResourceFileACT    },
  496. X      {"WcTraceACT",        WcTraceACT        },
  497. X      {"WcPopupACT",        WcPopupACT        },
  498. X      {"WcPopupGrabACT",    WcPopupGrabACT        },
  499. X      {"WcPopdownACT",        WcPopdownACT        },
  500. X      {"WcSystemACT",        WcSystemACT        },
  501. X      {"WcExitACT",        WcExitACT        },
  502. X    };
  503. X
  504. X    static int already = 0;
  505. X
  506. X    if (already++)
  507. X    return;
  508. X
  509. X    XtAppAddActions(app, WcActions, XtNumber(WcActions));
  510. X
  511. X}
  512. +FUNKY+STUFF+
  513. echo '-rw-r--r--  1 david       11914 Jul  2 12:22 WcActions.c    (as sent)'
  514. chmod u=rw,g=r,o=r WcActions.c
  515. ls -l WcActions.c
  516. echo x - WcAthenaP.h
  517. sed 's/^X//' > WcAthenaP.h <<'+FUNKY+STUFF+'
  518. X/*
  519. X** Copyright (c) 1990 David E. Smyth
  520. X** 
  521. X** Redistribution and use in source and binary forms are permitted
  522. X** provided that the above copyright notice and this paragraph are
  523. X** duplicated in all such forms and that any documentation, advertising
  524. X** materials, and other materials related to such distribution and use
  525. X** acknowledge that the software was developed by David E. Smyth.  The
  526. X** name of David E. Smyth may not be used to endorse or promote products
  527. X** derived from this software without specific prior written permission.
  528. X** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  529. X** WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  530. X** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  531. X** 
  532. X*/
  533. X
  534. X/*
  535. X* SCCS_data: @(#)WcAthenaP.h 1.0 ( 19 June 1990 )
  536. X*/
  537. X
  538. X#ifndef _WcAthenaP_h_
  539. X#define _WcAthenaP_h_
  540. X
  541. X/* Core, Object, RectObj, WindowObj, 
  542. X** XmGadget, XmPrimitive, and XmComposite, 
  543. X** Shell, OverrideShell, WMShell, VendorShell, TopLevelShell, ApplicationShell, 
  544. X** Constraint, XmManager.
  545. X*/
  546. X#include <X11/IntrinsicP.h>
  547. X
  548. X/* include all the *P.h files in heirarchical order */
  549. X
  550. X#include <X11/CoreP.h>
  551. X#include <X11/ObjectP.h>
  552. X#include <X11/Xaw/SimpleP.h>
  553. X#include <X11/CompositeP.h>
  554. X#include <X11/ConstrainP.h>
  555. X
  556. X/* Core */
  557. X#include <X11/Xaw/ClockP.h>
  558. X#include <X11/Xaw/LogoP.h>
  559. X#include <X11/Xaw/MailboxP.h>
  560. X#include <X11/Xaw/SimpleP.h>
  561. X
  562. X/* Simple */
  563. X#include <X11/Xaw/GripP.h>
  564. X#include <X11/Xaw/LabelP.h>
  565. X#include <X11/Xaw/ListP.h>
  566. X#include <X11/Xaw/ScrollbarP.h>
  567. X#include <X11/Xaw/StripCharP.h>
  568. X#include <X11/Xaw/TextP.h>
  569. X
  570. X/* Label */
  571. X#include <X11/Xaw/CommandP.h>
  572. X#include <X11/Xaw/MenuButtoP.h>
  573. X#include <X11/Xaw/ToggleP.h>
  574. X
  575. X/* Sme */
  576. X#include <X11/Xaw/SmeP.h>
  577. X#include <X11/Xaw/SimpleMenP.h>
  578. X#include <X11/Xaw/SmeBSBP.h>
  579. X#include <X11/Xaw/SmeLineP.h>
  580. X
  581. X
  582. X/* Text */
  583. X#include <X11/Xaw/AsciiTextP.h>
  584. X#include <X11/Xaw/TextSrcP.h>
  585. X#include <X11/Xaw/AsciiSrcP.h>
  586. X#include <X11/Xaw/TextSinkP.h>
  587. X#include <X11/Xaw/AsciiSinkP.h>
  588. X
  589. X/* Composite and Constraint */
  590. X#include <X11/Xaw/BoxP.h>
  591. X#include <X11/Xaw/FormP.h>
  592. X#include <X11/Xaw/PanedP.h>
  593. X
  594. X/* Form */
  595. X#include <X11/Xaw/DialogP.h>
  596. X#include <X11/Xaw/ViewportP.h>
  597. X
  598. X#endif
  599. +FUNKY+STUFF+
  600. echo '-rw-r--r--  1 david        2168 Jul  2 12:22 WcAthenaP.h    (as sent)'
  601. chmod u=rw,g=r,o=r WcAthenaP.h
  602. ls -l WcAthenaP.h
  603. echo x - WcCallbacks.c
  604. sed 's/^X//' > WcCallbacks.c <<'+FUNKY+STUFF+'
  605. X/*
  606. X** Copyright (c) 1990 David E. Smyth
  607. X**
  608. X** This file was derived from work performed by Martin Brunecky at
  609. X** Auto-trol Technology Corporation, Denver, Colorado, under the
  610. X** following copyright:
  611. X**
  612. X*******************************************************************************
  613. X* Copyright 1990 by Auto-trol Technology Corporation, Denver, Colorado.
  614. X*
  615. X*                        All Rights Reserved
  616. X*
  617. X* Permission to use, copy, modify, and distribute this software and its
  618. X* documentation for any purpose and without fee is hereby granted, provided
  619. X* that the above copyright notice appears on all copies and that both the
  620. X* copyright and this permission notice appear in supporting documentation
  621. X* and that the name of Auto-trol not be used in advertising or publicity
  622. X* pertaining to distribution of the software without specific, prior written
  623. X* permission.
  624. X*
  625. X* Auto-trol disclaims all warranties with regard to this software, including
  626. X* all implied warranties of merchantability and fitness, in no event shall
  627. X* Auto-trol be liable for any special, indirect or consequential damages or
  628. X* any damages whatsoever resulting from loss of use, data or profits, whether
  629. X* in an action of contract, negligence or other tortious action, arising out
  630. X* of or in connection with the use or performance of this software.
  631. X*******************************************************************************
  632. X**
  633. X** Redistribution and use in source and binary forms are permitted
  634. X** provided that the above copyright notice and this paragraph are
  635. X** duplicated in all such forms and that any documentation, advertising
  636. X** materials, and other materials related to such distribution and use
  637. X** acknowledge that the software was developed by David E. Smyth.  The
  638. X** name of David E. Smyth may not be used to endorse or promote products
  639. X** derived from this software without specific prior written permission.
  640. X** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  641. X** WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  642. X** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  643. X**
  644. X*/
  645. X
  646. X/*
  647. X* SCCS_data: @(#)WcCallbacks.c 1.0 ( 19 June 1990 )
  648. X*
  649. X* Subsystem_group:
  650. X*
  651. X*     Widget Creation Library
  652. X*
  653. X* Module_description:
  654. X*
  655. X*     This module contains the convenience callbacks used to create and 
  656. X*     manage a widget tree using the Xrm databse.
  657. X*
  658. X*     Several convenience callbacks are provided with the package, allowing 
  659. X*     deferred widget creation, control (manage/unmanage) and other utility
  660. X*     functions.
  661. X*
  662. X* Module_interface_summary: 
  663. X*
  664. X*     Convenience Callbacks:
  665. X*
  666. X* Module_history:
  667. X*                                                  
  668. X*   Several of the callbacks and the callback registration routine were
  669. X*   originally written by Martin Brunecky at Auto-Trol, between about
  670. X*   the first of February 1990 until about 18 April 1990.
  671. X*
  672. X*   Additional callbacks and modifications to all callbacks and the
  673. X*   callback registration routine were made by David Smyth at Jet
  674. X*   Propulsion Laboratories following about 15 March 1990.
  675. X*
  676. X* Design_notes:
  677. X*
  678. X*   For VMS, we could have used LIB$FIND_IMAGE_SYMBOL and use dynamic
  679. X*   (runtime) binding. But since most UNIX systems lack such capability,
  680. X*   we stick to the concept of "registration" routines.
  681. X*
  682. X*   All these callbacks could probably be declared as static.  They
  683. X*   were not because applications may want to link them to widgets
  684. X*   via C code.  
  685. X*
  686. X*   When Motif runs on release 4 Intrinsics, then all argument parsing
  687. X*   should be replaced with coverters, so conversions get cached.  This
  688. X*   will improve performance, especially for pop-ups.
  689. X*
  690. X*******************************************************************************
  691. X*/
  692. X/*
  693. X*******************************************************************************
  694. X* Include_files.
  695. X*******************************************************************************
  696. X*/
  697. X
  698. X#include "WidgetCreate.h"
  699. X#include "WidgetCreateP.h"
  700. X
  701. X/*
  702. X*******************************************************************************
  703. X* Private_type_declarations.
  704. X*******************************************************************************
  705. X*/
  706. X
  707. X/*
  708. X*******************************************************************************
  709. X* Private_macro_definitions.
  710. X*******************************************************************************
  711. X*/
  712. X
  713. X/*
  714. X*******************************************************************************
  715. X* Private_data_definitions.
  716. X*******************************************************************************
  717. X*/
  718. X
  719. X/* NOTE: These are shared arrays because they are large: i.e.,
  720. X** this is a performacne optimization intended to reduce page
  721. X** faults which can occur while making large extensions to the
  722. X** stack space.  Wait a minute: wouldn't this just happen
  723. X** once, and then the stack space is alloc'd?  Yes, but a
  724. X** huge stack space runs the risk of getting swapped, which causes
  725. X** page faults.  This is probably a nit-picky sort of optimization.
  726. X** Remember that D.Smyth is an old sys programmer from the stone
  727. X** ages, and pity him instead of flaming him.
  728. X** Be careful when filling msg not to call any funcs in here, 
  729. X** so the message does not get garbled.
  730. X*/
  731. X
  732. Xstatic char    msg[MAX_ERRMSG];
  733. Xstatic char    cleanName[MAX_PATHNAME];
  734. Xstatic Widget    widget_list[MAX_CHILDREN];
  735. X
  736. X/*
  737. X*******************************************************************************
  738. X* Private_function_declarations.
  739. X*******************************************************************************
  740. X*/
  741. X
  742. X/*
  743. X*******************************************************************************
  744. X* Public_callback_function_declarations.
  745. X*******************************************************************************
  746. X    The client data argument of callbacks MUST be a null terminated
  747. X    string.  If client == (char*)0 this is an error.  The correct way
  748. X    to pass no client information is *client == '\0'. The CvtStringToCallback
  749. X    converter which actually causes these functions to be called (adds
  750. X    these functions to widget's callback lists) does ensure that the
  751. X    client data is a proper null terminated string.
  752. X
  753. X    Callbacks are not intended to be re-entrant nor recursive.  Many of
  754. X    these use static buffers.
  755. X*******************************************************************************
  756. X*/
  757. X
  758. X/*
  759. X    -- Create Deferred Children from Xrm Database
  760. X*******************************************************************************
  761. X    This callback creates one or more specified children of a parent widget.
  762. X    If parent name is `this' then widget invoking callback is used as the
  763. X    parent.  Parent name can also be a wildcarded path name.  Child names
  764. X    must be single part, specific children of the parent. Client data format:
  765. X
  766. X             parent, child [,child] ...
  767. X    
  768. X    This callback is used for deferred sub-tree creation, where named child
  769. X    creation has been postponed due to a resource specification of the form:
  770. X
  771. X        *foobar.WcDeferred:  True
  772. X*/
  773. X
  774. Xvoid WcCreateChildrenCB ( w, parent_children, unused )
  775. X    Widget w;
  776. X    char* parent_children;    /* parent + list of named children */
  777. X    caddr_t unused;        /* call data from widget, not used */
  778. X{
  779. X    char*    children;
  780. X    Widget    parent;
  781. X
  782. X    if ( *parent_children == NUL ) 
  783. X    {
  784. X    XtWarning(
  785. X            "WcCreateChildrenCB ( ) - Failed \n\
  786. X             Usage: WcCreateChildrenCB ( parent, child [, child ] ...) \n\
  787. X                    Name of parent can be `this' or wildcarded pathname, \n\
  788. X                    Name of child must be single part name from parent. \n\
  789. X             Problem: No widget names provided.");
  790. X    return;
  791. X    }
  792. X
  793. X    children = WcCleanName( parent_children, cleanName );
  794. X
  795. X    children = WcSkipWhitespace_Comma( children );
  796. X
  797. X    if ((Widget)NULL == (parent = WcFullNameToWidget( w, cleanName )) )
  798. X    {
  799. X    sprintf( msg,
  800. X            "WcCreateChildrenCB (%s) - Failed \n\
  801. X             Usage: WcCreateChildrenCB ( parent, child [, child ] ...) \n\
  802. X                    Name of parent can be `this' or wildcarded pathname, \n\
  803. X                    Name of child must be single part name from parent. \n\
  804. X             Problem: Parent widget named `%s' not found.",
  805. X        parent_children, cleanName);
  806. X    XtWarning( msg );
  807. X    return;
  808. X    }
  809. X
  810. X    if (*children == NUL)
  811. X    {
  812. X        sprintf( msg,
  813. X            "WcCreateChildrenCB (%s) - Failed \n\
  814. X             Usage: WcCreateChildrenCB ( parent, child [, child ] ...) \n\
  815. X                    Name of parent can be `this' or wildcarded pathname, \n\
  816. X                    Name of child must be single part name from parent. \n\
  817. X             Problem: No children names provided.",
  818. X        parent_children );
  819. X    XtWarning( msg );
  820. X        return;
  821. X    }
  822. X
  823. X    WcCreateDeferredChildren ( parent, children );
  824. X}
  825. X
  826. X/******************************************************************************
  827. X**  Manage or Unmanage named widget(s)
  828. X*******************************************************************************
  829. X    This callback translates string passed in as client data into one or more
  830. X    widget ids, and manages or unmanages it or them.  Client data format:
  831. X    name [, name] ...
  832. X    Name can include `this' and other path names.
  833. X******************************************************************************/
  834. X
  835. X#ifdef FUNCTION_PROTOTYPES
  836. Xstatic void ManageOrUnmanage( Widget, char*, char*, void (*proc)() );
  837. X#else
  838. Xstatic void ManageOrUnmanage();
  839. X#endif
  840. X
  841. Xvoid WcManageCB ( w, widgetNames, unused )
  842. X    Widget w;
  843. X    char* widgetNames;
  844. X    caddr_t unused;        /* call data from widget, not used */
  845. X{
  846. X    ManageOrUnmanage( w, widgetNames, "WcManageCB", XtManageChildren );
  847. X}
  848. X
  849. Xvoid WcUnmanageCB ( w, widgetNames, unused )
  850. X    Widget w;
  851. X    char* widgetNames;
  852. X    caddr_t unused;             /* call data from widget, not used */
  853. X{
  854. X    ManageOrUnmanage( w, widgetNames, "WcUnmanageCB", XtUnmanageChildren );
  855. X}
  856. X
  857. Xstatic void ManageOrUnmanage ( w, widgetNames, callbackName, proc )
  858. X    Widget w;
  859. X    char* widgetNames;
  860. X    char* callbackName;
  861. X    void (*proc)();
  862. X{
  863. X    int         numWidgets = 0;
  864. X    char*       s = widgetNames;
  865. X
  866. X    while (*s && numWidgets < MAX_CHILDREN)
  867. X    {
  868. X        s = WcCleanName ( s, cleanName );
  869. X        s = WcSkipWhitespace_Comma ( s );
  870. X        if ( widget_list[numWidgets] = WcFullNameToWidget ( w, cleanName ) )
  871. X            numWidgets++;
  872. X        else
  873. X        {
  874. X            sprintf(msg,
  875. X            "%s (%s) - Widget `%s' ignored \n\
  876. X             Usage:   %s ( widget_name [, widget_name] ... ) \n\
  877. X             Problem: Could not find widget named `%s'.",
  878. X             callbackName, widgetNames, cleanName, callbackName, cleanName);
  879. X            XtWarning( msg );
  880. X        }
  881. X    }
  882. X    if (numWidgets >= MAX_CHILDREN)
  883. X    {
  884. X    sprintf(msg,
  885. X            "%s (%s) - Failed \n\
  886. X             Usage:   %s ( widget_name [, widget_name] ... ) \n\
  887. X             Problem: Too many widgets (more than MAX_CHILDREN).",
  888. X             callbackName, widgetNames, callbackName);
  889. X    XtWarning( msg );
  890. X    numWidgets = 0;
  891. X    }
  892. X
  893. X    if ( numWidgets )
  894. X        /* proc is either XtManageChildren or XtUnmanageChildren */
  895. X        proc ( widget_list, numWidgets );
  896. X}
  897. X
  898. X/*
  899. X    -- Manage or unamange named children callback
  900. X*******************************************************************************
  901. X    These callbacks translates a string passed in as client data into a parent
  902. X    widget id, and names of children of that parent.  If parent name is
  903. X    `this' then widget invoking callback is used as the parent.  Parent
  904. X    name can also be a wildcarded path name.  Child names must be single
  905. X    part, specific children of the parent. Client data format:
  906. X
  907. X             parent, child [,child] ...
  908. X
  909. X    This callback can be used as an alternate for WcManageCB but it is
  910. X    really intended to be used to manage/unmanage children of widgets 
  911. X    which have multiple instances, and where the parent name is `this'.
  912. X*/
  913. X#ifdef FUNCTION_PROTOTYPES
  914. Xstatic void ManageOrUnmanageChildren( Widget, char*, char*, void (*proc)() );
  915. X#else
  916. Xstatic void ManageOrUnmanageChildren();
  917. X#endif
  918. X
  919. Xvoid WcManageChildrenCB ( w, parent_children, unused )
  920. X    Widget     w;
  921. X    char*    parent_children;/* client data, list of named children  */
  922. X    caddr_t    unused;        /* call data from widget        */
  923. X{
  924. X    ManageOrUnmanageChildren( w, parent_children, 
  925. X                "WcManageChildrenCB", XtManageChildren );
  926. X}
  927. X
  928. Xvoid WcUnmanageChildrenCB ( w, parent_children, unused )
  929. X    Widget      w;
  930. X    char*       parent_children;/* client data, list of named children  */
  931. X    caddr_t     unused;         /* call data from widget                */
  932. X{
  933. X    ManageOrUnmanageChildren( w, parent_children,
  934. X                                "WcUnmanageChildrenCB", XtUnmanageChildren );
  935. X}
  936. X
  937. Xstatic void ManageOrUnmanageChildren( w, parent_children, callbackName, proc )
  938. X    Widget w;
  939. X    char* parent_children;      /* client data, list of named children  */
  940. X    char* callbackName;        /* WcManageChildrenCB or WcUnmanageChildrenCB */
  941. X    void (*proc)();        /* XtManageChildren or XtUnmanageChildren */
  942. X{
  943. X    int             numWidgets = 0;
  944. X    char*        next;
  945. X    Widget        parent;
  946. X
  947. X    if ( *parent_children == NUL )
  948. X    {
  949. X        sprintf(msg,
  950. X            "%s ( ) - Failed \n\
  951. X             Usage: %s ( parent, child [, child ] ...) \n\
  952. X                    Name of parent can be `this' or wildcarded pathname, \n\
  953. X                    Name of child must be single part name from parent. \n\
  954. X             Problem: No widget names provided.",
  955. X        callbackName, callbackName);
  956. X    XtWarning( msg );
  957. X        return;
  958. X    }
  959. X
  960. X    next = WcCleanName( parent_children, cleanName );
  961. X    if ((Widget)NULL == (parent = WcFullNameToWidget( w, cleanName )) )
  962. X    {
  963. X        sprintf( msg,
  964. X            "%s (%s) - Failed \n\
  965. X             Usage: %s ( parent, child [, child ] ...) \n\
  966. X                    Name of parent can be `this' or wildcarded pathname, \n\
  967. X                    Name of child must be single part name from parent. \n\
  968. X             Problem: Parent widget named `%s' not found.",
  969. X            callbackName, parent_children, callbackName, cleanName);
  970. X        XtWarning( msg );
  971. X        return;
  972. X    }
  973. X
  974. X    while (*next && numWidgets < MAX_CHILDREN)
  975. X    {
  976. X        next = WcCleanName( next, cleanName );
  977. X    if (widget_list[numWidgets] = WcChildNameToWidget( parent, cleanName ))
  978. X        numWidgets++;
  979. X    else
  980. X    {
  981. X        sprintf( msg,
  982. X            "%s (%s) - Child `%s' ignored \n\
  983. X             Usage: %s ( parent, child [, child ] ...) \n\
  984. X                    Name of parent can be `this' or wildcarded pathname, \n\
  985. X                    Name of child must be single part name from parent. \n\
  986. X             Problem: Child widget named `%s' not found.",
  987. X        callbackName, parent_children, callbackName, cleanName);
  988. X        XtWarning( msg );
  989. X    }
  990. X    }
  991. X
  992. X    if (numWidgets >= MAX_CHILDREN)
  993. X    {
  994. X        sprintf(msg,
  995. X            "%s (%s) - Failed \n\
  996. X             Usage: %s ( parent, child [, child ] ...) \n\
  997. X                    Name of parent can be `this' or wildcarded pathname, \n\
  998. X                    Name of child must be single part name from parent. \n\
  999. X             Problem: Too many widgets (more than MAX_CHILDREN).",
  1000. X             callbackName, parent_children, callbackName);
  1001. X        XtWarning( msg );
  1002. X        numWidgets = 0;
  1003. X    }
  1004. X
  1005. X    if ( numWidgets )
  1006. X        /* proc is either XtManageChildren or XtUnmanageChildren */
  1007. X        proc ( widget_list, numWidgets );
  1008. X}
  1009. X
  1010. X/*
  1011. X    -- Destroy named children callback
  1012. X*******************************************************************************
  1013. X    This callback translates string passed in as client data into a widget id
  1014. X    and destroys it. A comma separated list of widgets can be specified.
  1015. X    `this' means the invoking widget.
  1016. X*/
  1017. X
  1018. Xvoid WcDestroyCB ( w, widgetNames, unused )
  1019. X    Widget  w;
  1020. X    char*   widgetNames;    /* client data, widgets to be destroyed */
  1021. X    caddr_t unused;        /* call data from widget, not used    */
  1022. X{
  1023. X    Cardinal    widget_count = MAX_CHILDREN;
  1024. X    char*    unConvertedNames;
  1025. X    int         i;
  1026. X
  1027. X    unConvertedNames = WcNamesToWidgetList ( w, widgetNames, 
  1028. X                    widget_list, &widget_count );
  1029. X    if ( unConvertedNames[0] != NUL )
  1030. X    {
  1031. X    sprintf(msg,
  1032. X            "WcDestroyCB (%s) \n\
  1033. X             Usage: WcDestroyCB ( widget [, widget ] ...) \n\
  1034. X                    Name of widget can be `this' or wildcarded pathname. \n\
  1035. X            Problem: No widgets found named %s.",
  1036. X             widgetNames, unConvertedNames);
  1037. X        XtWarning( msg );
  1038. X    }
  1039. X
  1040. X    for (i=0; i<widget_count; i++)
  1041. X       XtDestroyWidget ( widget_list[i] );
  1042. X}
  1043. X
  1044. X/*
  1045. X   -- Set Resource Value on Widget
  1046. X*******************************************************************************
  1047. X    This callback sets a resource value on the named widget.
  1048. X
  1049. X    The client data argument has a format:
  1050. X
  1051. X        target_widget_name.resource_name: resource value
  1052. X
  1053. X    The special resource value of "this" means "this widget."  Typically,
  1054. X    using "this" as the resource value is used to set the "XmNdefaultButton"
  1055. X    resource on a XmbulletinBoard, "menuBar", "workArea", etc on XmMainWindows,
  1056. X    the subMenuId resource on menuBar cascade buttons, and so on.
  1057. X*/
  1058. X
  1059. Xvoid WcSetValueCB ( w, name_res_resVal, unused )
  1060. X    Widget  w;  
  1061. X    char*   name_res_resVal;        /* client data: name.resName: resVal */
  1062. X    caddr_t unused;            /* call data from wudget, not used   */
  1063. X{
  1064. X    /* Note: static buffers make this routine NON-REENTRANT!! */
  1065. X    static char    target_name[MAX_XRMSTRING];
  1066. X    static char    resource[MAX_XRMSTRING];
  1067. X    static char    res_val[MAX_XRMSTRING];
  1068. X
  1069. X    Widget         target;
  1070. X    register char *d,*s;
  1071. X    Arg            args[1];
  1072. X
  1073. X    s = name_res_resVal;
  1074. X    /* copy from name_res_resVal into target_name[],
  1075. X    ** ignore initial whitespace, stop at trailing `:'  
  1076. X    ** Then backup to get final segment, the resource name
  1077. X    */
  1078. X    for ( s = name_res_resVal ; *s && *s <= ' ' ; s++ )
  1079. X    ;    /* skip initial whitespace */
  1080. X    for ( d = target_name ; *s && *s != ':' ; s++, d++ )
  1081. X    *d = *s;
  1082. X    for ( ; target_name < d && (*d != '.' && *d != '*') ; s--, d-- )
  1083. X    ;
  1084. X    *d = NUL;
  1085. X
  1086. X    /* OK, now target_name is null terminated.
  1087. X    ** s points at final `.' or `*' in name_resName, 
  1088. X    ** now we copy to resource[].
  1089. X    */
  1090. X    for ( s++, d = resource ; *s && *s != ':' ; s++, d++ )
  1091. X        *d = *s;
  1092. X    *d = NUL;
  1093. X
  1094. X    /* OK, now resource is null terminated.
  1095. X    ** s points at the `:' now we skip whitespace and the rest is value
  1096. X    ** until we hit whitespace again.
  1097. X    */
  1098. X    for (s++ ; *s && *s <= ' ' ; s++ )
  1099. X        ;       /* skip initial whitespace */
  1100. X    for (d = res_val ; *s && *s >= ' ' ; s++, d++ )
  1101. X    *d = *s;
  1102. X    *d = NUL;
  1103. X
  1104. X    /* Check for syntax error: if any of the strings are null, wrongo!
  1105. X    */
  1106. X    if ( target_name[0] == NUL || resource[0] == NUL || res_val[0] == NUL )
  1107. X    {
  1108. X        char *missing;
  1109. X
  1110. X        if (target_name[0] == NUL)
  1111. X            missing = "target_widget_name";
  1112. X        else if (resource[0] == NUL)
  1113. X            missing = "res_name";
  1114. X        else if (res_val[0] == NUL)
  1115. X            missing = "res_value";
  1116. X        else
  1117. X            missing = "** WcSetValueCB BUG **";
  1118. X
  1119. X        sprintf ( msg,
  1120. X            "WcSetValueCB (%s) - Failed \n\
  1121. X             Usage:   WcSetValueCB( target_widget_name.res_name: res_value ) \n\
  1122. X             Problem: Missing %s argument.",
  1123. X            name_res_resVal);
  1124. X        XtWarning( msg ); 
  1125. X    return;
  1126. X    }
  1127. X
  1128. X    /* The target widget name is rooted at the appShell */
  1129. X    if ( target = WcFullNameToWidget ( w, target_name ) )
  1130. X    {
  1131. X        /* Found the target widget.  Set the resource on it */
  1132. X
  1133. X    char* widgetName = WcStripWhitespaceFromBothEnds( res_val );
  1134. X
  1135. X        if (0 == strcmp(widgetName,"this"))
  1136. X        {
  1137. X            args[0].name  = resource;
  1138. X            args[0].value = (XtArgVal)w;
  1139. X
  1140. X            XtSetValues ( target, args, 1 );
  1141. X        }
  1142. X        else
  1143. X        {
  1144. X            /* convert to appropriate value and call XtSetValue() */
  1145. X            WcSetValueFromString( target, resource, res_val );
  1146. X        }
  1147. X    XtFree(widgetName);
  1148. X    }
  1149. X    else
  1150. X    {
  1151. X        sprintf ( msg,
  1152. X            "WcSetValueCB (%s)  \n\
  1153. X             Usage:   WcSetValueCB( target_widget_name.res_name: res_value ) \n\
  1154. X             Problem: Could not find widget named `%s'",
  1155. X             name_res_resVal, target_name );
  1156. X        XtWarning( msg );
  1157. X        return;
  1158. X    }
  1159. X}
  1160. X
  1161. X/*
  1162. X    -- Change sensitivity of widgets.
  1163. X*******************************************************************************
  1164. X    This callback translates string passed in as client data into widget ids
  1165. X    and sets each to be sensitve/insensitive. A comma separated list of 
  1166. X    widgets can be specified.  `this' means the invoking widget.  
  1167. X
  1168. X    This callback someday should take care of the problem with text
  1169. X    widgets - they don't get grey when insensitive, which must be a bug.
  1170. X*/
  1171. X
  1172. X#ifdef FUNCTION_PROTOTYPES
  1173. Xstatic void ChangeSensitivity( Widget, char*, char*, int );
  1174. X#else
  1175. Xstatic void ChangeSensitivity();
  1176. X#endif
  1177. X
  1178. Xvoid WcSetSensitiveCB ( w, widgetNames, unused )
  1179. X    Widget  w;
  1180. X    char*   widgetNames;        /* client data, widgets to be destroyed */
  1181. X    caddr_t unused;        /* call data from widget is not used    */
  1182. X{
  1183. X    ChangeSensitivity ( w, widgetNames, "WcSetSensitiveCB", (Boolean)TRUE );
  1184. X}
  1185. X
  1186. Xvoid WcSetInsensitiveCB ( w, widgetNames, unused )
  1187. X    Widget  w;
  1188. X    char*   widgetNames;        /* client data, widgets to be destroyed */
  1189. X    caddr_t unused;             /* call data from widget is not used    */
  1190. X{
  1191. X    ChangeSensitivity ( w, widgetNames, "WcSetInsensitiveCB", (Boolean)FALSE );
  1192. X}
  1193. X
  1194. Xstatic void ChangeSensitivity ( w, widgetNames, callbackName, sensitive )
  1195. X    Widget  w;
  1196. X    char*   widgetNames;        /* client data, widgets to be destroyed */
  1197. X    char*   callbackName;    /* "WcSetSensitiveCB" or "WcSetInsensitiveCB" */
  1198. X    int     sensitive;
  1199. X{
  1200. X    Cardinal    widget_count = MAX_CHILDREN;
  1201. X    char*       unConvertedNames;
  1202. X    int         i;
  1203. X
  1204. X    unConvertedNames = WcNamesToWidgetList ( w, widgetNames,
  1205. X                                    widget_list, &widget_count );
  1206. X    if ( unConvertedNames[0] != NUL )
  1207. X    {
  1208. X        sprintf(msg,
  1209. X            "%s (%s) - One or more widget names ignored \n\
  1210. X             Usage: %s ( widget [, widget ] ...) \n\
  1211. X                    Name of widget can be `this' or wildcarded pathname. \n\
  1212. X                    Problem: No widgets found named %s.",
  1213. X             callbackName, widgetNames, callbackName, unConvertedNames);
  1214. X        XtWarning( msg );
  1215. X    }
  1216. X
  1217. X    for (i=0; i<widget_count; i++)
  1218. X    XtSetSensitive ( widget_list[i], sensitive );
  1219. X}
  1220. X
  1221. X/*
  1222. X    -- Load Resource File
  1223. X*******************************************************************************
  1224. X    This callbacks loads specified resource file into application
  1225. X    resource database. It allows to load resources on as-needed
  1226. X    basis, reducing the intitial resource file load overhead. 
  1227. X    The file to load is specified as client data. The directory search 
  1228. X    for the file (should be) the same as for application class resource file.
  1229. X    
  1230. X    To prevent repeated loads of the same file, the callback changes
  1231. X    the 1st character of the string argument into a control-D.
  1232. X    Beware this feature when using callback from the C code !
  1233. X
  1234. X    NOTE:
  1235. X    The file search list rule used here is a gross simplification of the R3
  1236. X    resource file search mechanism, without the $LANG provision.
  1237. X    I hope I can use R4 soon and do it RIGHT, but I depend on Motif for now,
  1238. X    and do not want to duplicate all the Motif code here.
  1239. X    Here I look into two directories only, which may be defined as environmental
  1240. X    variables:
  1241. X         XAPPLRESDIR  - defaults to "/usr/lib/X11/app-defaults/"
  1242. X     XUSERRESDIR  - defaults to HOME directory
  1243. X*/
  1244. X
  1245. X#ifdef VAX
  1246. X#define XAPPLRESDIR "sys$library:"
  1247. X#else
  1248. X#define XAPPLRESDIR "/usr/lib/X11/app-defaults/"
  1249. X#endif
  1250. X
  1251. Xvoid WcLoadResourceFileCB ( w,  resFileName, unused )
  1252. X    Widget w;
  1253. X    char*  resFileName;    /* client data, X resources file name */
  1254. X    caddr_t unused;    /* call data,   not used */
  1255. X{
  1256. X    static char  name[MAX_PATHNAME];
  1257. X    char     *path;
  1258. X    char       filename[MAX_PATHNAME];
  1259. X    XrmDatabase  rdb;
  1260. X    Display     *dpy = XtDisplay(w);
  1261. X    extern char *getenv();
  1262. X    Boolean      found = FALSE;
  1263. X
  1264. X/*  -- check for repeated invocation, flagged by control-D */
  1265. X    if ( *resFileName == ALREADY_LOADED_RESOURCE_FILE ) return;
  1266. X
  1267. X    (void) WcCleanName( resFileName, name );
  1268. X
  1269. X/*  -- check pathname presence */
  1270. X    if ( *name == NUL )
  1271. X    {
  1272. X        XtWarning ( 
  1273. X            "WcLoadResourceFileCB () - Failed \n\
  1274. X             Usage:   WcLoadResourceFileCB( resource_file_name ) \n\
  1275. X             Problem: No file name provided.");
  1276. X        return;
  1277. X    }
  1278. X
  1279. X/*  -- Look for file in application class resources file directory */
  1280. X    if ((path = getenv("XAPPLRESDIR")) == NULL) 
  1281. X    {
  1282. X    path = XAPPLRESDIR ;
  1283. X    } 
  1284. X    strcpy ( filename, path );
  1285. X    strcat ( filename, name );
  1286. X    if ((rdb = XrmGetFileDatabase(filename)) != NULL )
  1287. X    {
  1288. X    XrmMergeDatabases (rdb, &(dpy->db) );
  1289. X    found = TRUE;
  1290. X    }    
  1291. X
  1292. X#ifdef I_DONT_KNOW_WHY_THIS_IS_HERE
  1293. X/*  -- Look for file in user class resources file directory */
  1294. X    if ((path = getenv("XUSERRESDIR")) == NULL) 
  1295. X    {
  1296. X    path = ( char* )malloc (MAX_PATHNAME);
  1297. X        strcpy ( path, RootDirName(filename));
  1298. X    } 
  1299. X    strcpy ( filename, path );
  1300. X    strcat ( filename, name );
  1301. X    free   ( path );
  1302. X    if ((rdb = XrmGetFileDatabase(filename)) != NULL )
  1303. X    {
  1304. X    XrmMergeDatabases (rdb, &(dpy->db) );
  1305. X        found = TRUE;
  1306. X    }
  1307. X#endif
  1308. X
  1309. X/*  -- Look for file in current working directory */
  1310. X    strcpy ( filename, name );
  1311. X    if ((rdb = XrmGetFileDatabase(filename)) != NULL )
  1312. X    {
  1313. X        XrmMergeDatabases (rdb, &(dpy->db) );
  1314. X        found = TRUE;
  1315. X    }
  1316. X
  1317. X/*  -- warn the user if no file found */
  1318. X    if (!found)
  1319. X    {
  1320. X    sprintf  ( msg, 
  1321. X            "WcLoadResourceFileCB ( %s ) - Failed \n\
  1322. X             Usage:   WcLoadResourceFileCB( resource_file_name ) \n\
  1323. X             Problem: Cannot load resource file %s",
  1324. X    resFileName, name );
  1325. X    XtWarning( msg );
  1326. X    }
  1327. X
  1328. X
  1329. X/*  -- change 1st char of file name to ^D to flag resource load is complete */
  1330. X    resFileName[0] = ALREADY_LOADED_RESOURCE_FILE;
  1331. X}
  1332. X
  1333. X/*
  1334. X  -- WcTraceCallback
  1335. X*******************************************************************************
  1336. X    This is a simple traceback callback, used to assist in interface
  1337. X    debugging. The callback prints the invoking wiget pathname and
  1338. X    a specified message on std. output.
  1339. X*/
  1340. X
  1341. Xvoid WcTraceCB ( w, annotation, unused )
  1342. X    Widget w;
  1343. X    char* annotation;    /* client data, traceback annotation */
  1344. X    caddr_t unused;    /* call data,   not used */
  1345. X{
  1346. X    char* name = WcWidgetToFullName( w );
  1347. X    
  1348. X    printf("TraceCB for %s: %s\n", name, annotation );
  1349. X    XtFree( name );
  1350. X}
  1351. X
  1352. X/*
  1353. X  -- Popup named widget
  1354. X*******************************************************************************
  1355. X    These callbacks translate a string passed in as client data into a 
  1356. X    widget id.  
  1357. X
  1358. X    A grab kind value of XtGrabNonexclusive has the effect of allowing 
  1359. X    non-modal popups.  This is the preferred type: rarely use modal pop-ups.
  1360. X    This is registered as PopupCB.
  1361. X
  1362. X    A grab kind value of XtGrabExclusive has the effect of grabbing all
  1363. X    application events, allowing modal popups.  This is registered as 
  1364. X    PopupGrabCB.
  1365. X*/
  1366. X
  1367. X#ifdef FUNCTION_PROTOTYPES
  1368. Xstatic void Popup ( Widget, char*, char*, XtGrabKind );
  1369. X#else
  1370. Xstatic void Popup ();
  1371. X#endif
  1372. X
  1373. Xvoid WcPopupCB ( w, name, unused )
  1374. X    Widget      w;
  1375. X    char*       name;
  1376. X    caddr_t    unused;
  1377. X{
  1378. X    Popup ( w, name, "WcPopupCB", XtGrabNonexclusive );
  1379. X}
  1380. X
  1381. Xvoid WcPopupGrabCB ( w, name, unused )
  1382. X    Widget      w;
  1383. X    char*       name;
  1384. X    caddr_t     unused;
  1385. X{
  1386. X    Popup ( w, name, "WcPopupGrabCB", XtGrabExclusive );
  1387. X}
  1388. X
  1389. Xstatic void Popup ( w, name, callbackName, grab )
  1390. X    Widget    w;
  1391. X    char*    name;
  1392. X    char*    callbackName;
  1393. X    XtGrabKind    grab;
  1394. X{
  1395. X    Widget      widget;
  1396. X
  1397. X    (void)WcCleanName ( name, cleanName );
  1398. X    widget = WcFullNameToWidget ( w, cleanName );
  1399. X
  1400. X    if (XtIsShell(widget))
  1401. X    {
  1402. X        XtPopup  ( widget, grab );
  1403. X    }
  1404. X    else
  1405. X    {
  1406. X        sprintf( msg,
  1407. X            "%s (%s) - Failed \n\
  1408. X             Usage: %s (shell_widget_name) \n\
  1409. X             Problem: `%s' is not a shell widget.",
  1410. X             callbackName, name, callbackName, cleanName);
  1411. X        XtWarning( msg );
  1412. X    }
  1413. X}
  1414. X
  1415. X/*
  1416. X  -- Popdown named widget
  1417. X*******************************************************************************
  1418. X    This callback translates string passed in as client data into a widget id
  1419. X    and pops-down a popup shell widget.
  1420. X*/
  1421. X
  1422. Xvoid WcPopdownCB ( w, name, unused ) 
  1423. X    Widget    w;
  1424. X    char*    name;
  1425. X    caddr_t    unused;
  1426. X{
  1427. X    Widget      widget;
  1428. X
  1429. X    (void)WcCleanName ( name, cleanName );
  1430. X    widget = WcFullNameToWidget ( w, cleanName );
  1431. X
  1432. X    if (XtIsShell(widget))
  1433. X    {
  1434. X        XtPopdown  ( widget );
  1435. X    }
  1436. X    else
  1437. X    {
  1438. X        sprintf( msg,
  1439. X            "WcPopdownCB (%s) Failed \n\
  1440. X             Usage: WcPopdownCB (shell_widget_name) \n\
  1441. X             Problem: `%s' is not a shell widget.",
  1442. X             name, cleanName);
  1443. X        XtWarning( msg );
  1444. X    }
  1445. X}
  1446. X
  1447. X/*
  1448. X  -- Invoke shell command
  1449. X*******************************************************************************
  1450. X    Call system().
  1451. X*/
  1452. X
  1453. Xvoid WcSystemCB ( w, shellCmdString, unused )
  1454. X    Widget      w;
  1455. X    char*       shellCmdString;
  1456. X    caddr_t     unused;
  1457. X{
  1458. X    system( shellCmdString );
  1459. X}
  1460. X
  1461. X/*
  1462. X  -- Exit the application
  1463. X*******************************************************************************
  1464. X    Call exit().
  1465. X*/
  1466. X
  1467. Xvoid WcExitCB ( w, exitValString, unused )
  1468. X    Widget    w;
  1469. X    char*    exitValString;
  1470. X    caddr_t    unused;
  1471. X{
  1472. X    int exitval = 0;
  1473. X
  1474. X    /* skip leading garbage before int */
  1475. X    while (*exitValString)
  1476. X    {
  1477. X        if ('0' < *exitValString && *exitValString <= '9')
  1478. X            break; /* found numbers, convert to exitval */
  1479. X        exitValString++;
  1480. X    }
  1481. X
  1482. X    /* convert to int */
  1483. X    while (*exitValString)
  1484. X    {
  1485. X        if ('0' < *exitValString && *exitValString <= '9')
  1486. X        {
  1487. X            exitval = exitval * 10 + (*exitValString - '0');
  1488. X            exitValString++;
  1489. X        }
  1490. X        else
  1491. X            break;  /* ignore trailing garbage */
  1492. X    }
  1493. X
  1494. X    exit( exitval );
  1495. X}
  1496. X
  1497. X/*
  1498. X  -- WcRegisterCreateCallbacks
  1499. X*******************************************************************************
  1500. X   Convenience routine, registering all standard callbacks in one application
  1501. X   call.   Called from WcWidgetCreation(), so application usually never needs
  1502. X   to call this.
  1503. X*/
  1504. X
  1505. Xvoid WcRegisterWcCallbacks ( app )
  1506. XXtAppContext app;
  1507. X{
  1508. X#define RCALL( name, func ) WcRegisterCallback ( app, name, func, NULL )
  1509. X
  1510. X    static int already = 0;
  1511. X
  1512. X    if (already++)
  1513. X    return;
  1514. X
  1515. X    RCALL( "WcCreateChildrenCB",    WcCreateChildrenCB    );
  1516. X    RCALL( "WcManageCB",        WcManageCB        );
  1517. X    RCALL( "WcUnmanageCB",        WcUnmanageCB        );
  1518. X    RCALL( "WcManageChildrenCB",    WcManageChildrenCB    );
  1519. X    RCALL( "WcUnmanageChildrenCB",    WcUnmanageChildrenCB    );
  1520. X    RCALL( "WcDestroyCB",        WcDestroyCB        );
  1521. X    RCALL( "WcSetValueCB",        WcSetValueCB        );
  1522. X    RCALL( "WcSetSensitiveCB",        WcSetSensitiveCB    );
  1523. X    RCALL( "WcSetInsensitiveCB",    WcSetInsensitiveCB    );
  1524. X    RCALL( "WcLoadResourceFileCB",    WcLoadResourceFileCB    );
  1525. X    RCALL( "WcTraceCB",            WcTraceCB        );
  1526. X    RCALL( "WcPopupCB",            WcPopupCB        );
  1527. X    RCALL( "WcPopupGrabCB",        WcPopupGrabCB        );
  1528. X    RCALL( "WcPopdownCB",        WcPopdownCB        );
  1529. X    RCALL( "WcSystemCB",        WcSystemCB        );
  1530. X    RCALL( "WcExitCB",            WcExitCB        );
  1531. X
  1532. X#undef CALLBACK
  1533. X}
  1534. +FUNKY+STUFF+
  1535. echo '-rw-r--r--  1 david       31160 Jul  2 12:22 WcCallbacks.c    (as sent)'
  1536. chmod u=rw,g=r,o=r WcCallbacks.c
  1537. ls -l WcCallbacks.c
  1538. echo x - WcConverters.c
  1539. sed 's/^X//' > WcConverters.c <<'+FUNKY+STUFF+'
  1540. X/*
  1541. X** Copyright (c) 1990 David E. Smyth
  1542. X**
  1543. X** This file was derived from work performed by Martin Brunecky at
  1544. X** Auto-trol Technology Corporation, Denver, Colorado, under the
  1545. X** following copyright:
  1546. X**
  1547. X*******************************************************************************
  1548. X* Copyright 1990 by Auto-trol Technology Corporation, Denver, Colorado.
  1549. X*
  1550. X*                        All Rights Reserved
  1551. X*
  1552. X* Permission to use, copy, modify, and distribute this software and its
  1553. X* documentation for any purpose and without fee is hereby granted, provided
  1554. X* that the above copyright notice appears on all copies and that both the
  1555. X* copyright and this permission notice appear in supporting documentation
  1556. X* and that the name of Auto-trol not be used in advertising or publicity
  1557. X* pertaining to distribution of the software without specific, prior written
  1558. X* permission.
  1559. X*
  1560. X* Auto-trol disclaims all warranties with regard to this software, including
  1561. X* all implied warranties of merchantability and fitness, in no event shall
  1562. X* Auto-trol be liable for any special, indirect or consequential damages or
  1563. X* any damages whatsoever resulting from loss of use, data or profits, whether
  1564. X* in an action of contract, negligence or other tortious action, arising out
  1565. X* of or in connection with the use or performance of this software.
  1566. X*******************************************************************************
  1567. X**
  1568. X** Redistribution and use in source and binary forms are permitted
  1569. X** provided that the above copyright notice and this paragraph are
  1570. X** duplicated in all such forms and that any documentation, advertising
  1571. X** materials, and other materials related to such distribution and use
  1572. X** acknowledge that the software was developed by David E. Smyth.  The
  1573. X** name of David E. Smyth may not be used to endorse or promote products
  1574. X** derived from this software without specific prior written permission.
  1575. X** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  1576. X** WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  1577. X** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  1578. X**
  1579. X*/
  1580. X
  1581. X/*
  1582. X* SCCS_data: @(#)WcConverters.c 1.0 ( 19 June 1990 )
  1583. X*
  1584. X* Subsystem_group:
  1585. X*
  1586. X*     Widget Creation Library
  1587. X*
  1588. X* Module_description:
  1589. X*
  1590. X*     This module contains Xt converter functions which convert strings,
  1591. X*     as found in the Xrm database, into useful types.  
  1592. X*
  1593. X*     It also contains the routine which registers all Wc converters.
  1594. X*
  1595. X*     The CvtStringToWidget converter takes a pathname which starts 
  1596. X*     from the application shell an proceeds to a specific widget.  The
  1597. X*     widget must already have been created.   Note that this converter
  1598. X*     needs to be used INSTEAD of the XmuCvtStringToWidget which gets
  1599. X*     registered by the Athena widgets.  The Xmu converter is not se
  1600. X*     user friendly.  This means this file also declares an external
  1601. X*     function XmuCvtStringToWidget() which is really CvtStringToWidget,
  1602. X*     an this nees to be linked before Xmu.
  1603. X*
  1604. X*     The CvtStringToCallback converter parses the resource string in 
  1605. X*     the format:
  1606. X*
  1607. X*       ...path:   name[(args)][,name[(args)]]...
  1608. X*
  1609. X*     where:  name:   specifies the registered callback function name
  1610. X*             args:   specifies the string passed to a callback as
  1611. X*              "client data".
  1612. X*
  1613. X*     Multiple callbacks can be specified for a single callback list
  1614. X*     resource.  Any callbacks must be "registered" by the application
  1615. X*     prior converter invocation (.i.e.prior widget creation).
  1616. X*     If no "args" string is provided, the default "client data" 
  1617. X*     specified at callback registration are used.
  1618. X*
  1619. X*     The CvtStringToConstructor converter searches the Constructor
  1620. X*     cache for a registered constructor.  
  1621. X*
  1622. X*     The CvtStringToClass converter searches the Class cache for a 
  1623. X*     registered object (widget) class pointer name.
  1624. X*
  1625. X*     The CvtStringToClassName converter searches the ClassName cache
  1626. X*     for a registered object (widget) class name.
  1627. X
  1628. X*
  1629. X* Module_interface_summary: 
  1630. X*
  1631. X*     Resource converter is invoked indirectly by the toolkit. The
  1632. X*     converter is added to the toolkit by widgets calling
  1633. X*     WcAddConverters() in the Wc intialization code.
  1634. X*
  1635. X* Module_history:
  1636. X*                                                  
  1637. X*   mm/dd/yy  initials  function  action
  1638. X*   --------  --------  --------  ---------------------------------------------
  1639. X*   06/08/90  D.Smyth   Class, ClassName, and Constructor converters.
  1640. X*   05/24/90  D.Smyth   WcAddConverters created from something similar
  1641. X*   04/03/90  MarBru    CvtStr..  Fixed argument termination with a NUL char
  1642. X*   02/26/90  MarBru    All       Created
  1643. X*
  1644. X* Design_notes:
  1645. X*
  1646. X*   For VMS, we could have used LIB$FIND_IMAGE_SYMBOL and use dynamic
  1647. X*   (runtime) binding. But since most UNIX systems lack such capability,
  1648. X*   we stick to the concept of "registration" routines.
  1649. X*
  1650. X*   One time, I considered applying conversion to callback argument, which
  1651. X*   would take the burden of conversion from the callback code (runtime)
  1652. X*   to the callback  conversion (one time initialization). The problem is
  1653. X*   that some conversions are widget context specific (color to pixel needs
  1654. X*   display connection), and at the time of callback conversion I do not
  1655. X*   have a widget. I could require the widget argument, but this would kill
  1656. X*   caching of the conversion result.
  1657. X*
  1658. X*   The sequential search of the callback cache is far from optimal. I should
  1659. X*   use binary search, or the R4 conversion cache.  I can't use the R4 cache
  1660. X*   until Motif 1.1 is released which will (supposedly) run on R4 Intrinsics.
  1661. X*   
  1662. X*******************************************************************************
  1663. X*/
  1664. X/*
  1665. X*******************************************************************************
  1666. X* Include_files.
  1667. X*******************************************************************************
  1668. X*/
  1669. X
  1670. X#include <ctype.h>    /* isupper() and tolower macros */
  1671. X#include <stdio.h>
  1672. X
  1673. X/*  -- X Window System includes */
  1674. X#include <X11/StringDefs.h> 
  1675. X
  1676. X/*  -- Widget Creation Library includes */
  1677. X#include "WidgetCreate.h"
  1678. X#include "WidgetCreateP.h"
  1679. X
  1680. X#ifdef MOTIF
  1681. X
  1682. X/*  -- Motif specific includes for CvtStringToMenuWidget */
  1683. X#include <Xm/Xm.h>
  1684. X#include <Xm/RowColumn.h>
  1685. X#include <Xm/RowColumnP.h>
  1686. X
  1687. X#endif MOTIF
  1688. X
  1689. X/*
  1690. X*******************************************************************************
  1691. X* Private_constant_declarations.
  1692. X*******************************************************************************
  1693. X*/
  1694. X
  1695. X/*
  1696. X*******************************************************************************
  1697. X* Private_type_declarations.
  1698. X*******************************************************************************
  1699. X*/
  1700. X
  1701. X/*
  1702. X*******************************************************************************
  1703. X* Private_macro_definitions.
  1704. X*******************************************************************************
  1705. X*/
  1706. X
  1707. X#define done( type, value )             \
  1708. X{                        \
  1709. X    if ( toVal->addr != NULL )            \
  1710. X    {                        \
  1711. X    if ( toVal->size < sizeof( type ) )    \
  1712. X    {                    \
  1713. X        toVal->size = sizeof( type );    \
  1714. X        return;                \
  1715. X    }                    \
  1716. X    *(type*)(toVal->addr) = (value);    \
  1717. X    }                        \
  1718. X    else                    \
  1719. X    {                        \
  1720. X    static type static_val;            \
  1721. X    static_val = (value);            \
  1722. X    toVal->addr = (caddr_t)&static_val;    \
  1723. X    }                        \
  1724. X    toVal->size = sizeof(type);            \
  1725. X    return;                    \
  1726. X}
  1727. X
  1728. X/*
  1729. X*******************************************************************************
  1730. X* Private_data_definitions.
  1731. X*******************************************************************************
  1732. X*/
  1733. X
  1734. X/*
  1735. X*******************************************************************************
  1736. X* Private_function_declarations.
  1737. X*******************************************************************************
  1738. X*/
  1739. X
  1740. X/*
  1741. X    -- Convert String To ClassPtr
  1742. X*******************************************************************************
  1743. X    This conversion searches the Object Class cache for the appropriate
  1744. X    Cache record.  The resource database string is simply the name
  1745. X    of the class pointer, case insensitive.  The value provided is the
  1746. X    widget class pointer, as passed to XtCreateWidget().
  1747. X*/
  1748. X
  1749. Xvoid CvtStringToClassPtr (args, num_args, fromVal, toVal )
  1750. X    XrmValue  *args;
  1751. X    Cardinal  *num_args;
  1752. X    XrmValue  *fromVal;
  1753. X    XrmValue  *toVal;
  1754. X{
  1755. X    char*       string = (char *) fromVal->addr;
  1756. X    char        cleanName[MAX_XRMSTRING];
  1757. X    char*       lowerCase;
  1758. X    XrmQuark    quark;
  1759. X    int         i;
  1760. X
  1761. X    (void)WcCleanName ( string, cleanName );
  1762. X    lowerCase = WcLowerCaseCopy ( cleanName );
  1763. X    quark = XrmStringToQuark ( lowerCase );
  1764. X    XtFree ( lowerCase );
  1765. X
  1766. X    for (i=0; i<classes_num; i++)
  1767. X    {
  1768. X        if ( classes_ptr[i].quark == quark )
  1769. X        {
  1770. X            done( WidgetClass, classes_ptr[i].class );
  1771. X        }
  1772. X    }
  1773. X    XtStringConversionWarning (cleanName, "Object Class, not registered.");
  1774. X}
  1775. X
  1776. X/*
  1777. X    -- Convert String To ClassName
  1778. X*******************************************************************************
  1779. X    This conversion searches the Class Name cache for the appropriate
  1780. X    Cache record.  The resource database string is simply the name
  1781. X    of the class, case insensitive.  The value provided is the widget 
  1782. X    class pointer, as passed to XtCreateWidget().
  1783. X*/
  1784. X
  1785. Xvoid CvtStringToClassName (args, num_args, fromVal, toVal )
  1786. X    XrmValue  *args;
  1787. X    Cardinal  *num_args;
  1788. X    XrmValue  *fromVal;
  1789. X    XrmValue  *toVal;
  1790. X{
  1791. X    char*    string = (char *) fromVal->addr;
  1792. X    char    cleanName[MAX_XRMSTRING];
  1793. X    char*     lowerCase;
  1794. X    XrmQuark    quark;
  1795. X    int        i;
  1796. X
  1797. X    (void)WcCleanName ( string, cleanName );
  1798. X    lowerCase = WcLowerCaseCopy ( cleanName );
  1799. X    quark = XrmStringToQuark ( lowerCase );
  1800. X    XtFree ( lowerCase );
  1801. X
  1802. X    for (i=0; i<cl_nm_num; i++)
  1803. X    {
  1804. X        if ( cl_nm_ptr[i].quark == quark )
  1805. X        {
  1806. X        done( WidgetClass, cl_nm_ptr[i].class );
  1807. X        }
  1808. X    }
  1809. X    XtStringConversionWarning (cleanName, "Class Name, not registered.");
  1810. X}
  1811. X
  1812. X/*
  1813. X    -- Convert String To Constructor
  1814. X*******************************************************************************
  1815. X    This conversion searches the Constructor Cache for the appropriate
  1816. X    Cache record.  The resource database string is simply the name
  1817. X    of the constructor, case insensitive.  The value provided is a
  1818. X    Contrstructor Cache Record.  The constructor (func ptr) itself is
  1819. X    not provided, as the user of this value (generally WcCreateDatabaseChild)
  1820. X    also likes to have the constructor name as registered for error messages.
  1821. X*/
  1822. X
  1823. Xvoid CvtStringToConstructor (args, num_args, fromVal, toVal)
  1824. X    XrmValue *args;
  1825. X    Cardinal *num_args;
  1826. X    XrmValue *fromVal;
  1827. X    XrmValue *toVal;
  1828. X{
  1829. X    char*       string = (char *) fromVal->addr;
  1830. X    char        cleanName[MAX_XRMSTRING];
  1831. X    char*       lowerCase;
  1832. X    XrmQuark    quark;
  1833. X    int         i;
  1834. X
  1835. X    (void)WcCleanName ( string, cleanName );
  1836. X    lowerCase = WcLowerCaseCopy ( cleanName );
  1837. X    quark = XrmStringToQuark ( lowerCase );
  1838. X    XtFree ( lowerCase );
  1839. X
  1840. X    for (i=0; i<constrs_num; i++)
  1841. X    {
  1842. X    if ( constrs_ptr[i].quark == quark )
  1843. X    {
  1844. X        done( ConCacheRec*, &(constrs_ptr[i]) );
  1845. X    }
  1846. X    }
  1847. X    XtStringConversionWarning (cleanName, "Constructor, not registered.");
  1848. X}
  1849. X
  1850. X/*
  1851. X    -- Convert String To Callback
  1852. X*******************************************************************************
  1853. X    This conversion creates a callback list structure from the X resource
  1854. X    database string in format:
  1855. X
  1856. X    name(arg),name(arg).....
  1857. X
  1858. X    Note "name" is not case sensitive, while "arg" may be - it is passed to
  1859. X    a callback as client data as a null terminated string (first level
  1860. X    parenthesis stripped off).  Even if nothing is specified e.g.,
  1861. X    SomeCallback() there is a null terminated string passed as client
  1862. X    data to the callback.  If it is empty, then it is the null string.
  1863. X
  1864. X    Note also that the argument CANNOT be converted at this point: frequently,
  1865. X    the argument refers to a widget which has not yet been created, or
  1866. X    uses the context of the callback (i.e., WcUnmanageCB( this ) uses the
  1867. X    widget which invoked the callback).  
  1868. X*/
  1869. X
  1870. Xvoid CvtStringToCallback (args, num_args, fromVal, toVal)
  1871. X    XrmValue *args;
  1872. X    Cardinal *num_args;
  1873. X    XrmValue *fromVal;
  1874. X    XrmValue *toVal;
  1875. X{
  1876. X    typedef struct 
  1877. X    {
  1878. X    char *nsta,*nend;        /* callback name start, end */
  1879. X    char *asta,*aend;        /* argument string start, end */
  1880. X    } Segment;
  1881. X
  1882. X    static XtCallbackRec *cb;
  1883. X    XtCallbackRec      callback_list[MAX_CALLBACKS];
  1884. X    int                   callback_num = 0;
  1885. X    String                string = (char *) fromVal->addr;
  1886. X    Segment               segs[MAX_CALLBACKS];    
  1887. X    Segment              *seg;
  1888. X    register char        *s;
  1889. X    register int          i,ipar;
  1890. X
  1891. X/*  -- assume error or undefined input argument */
  1892. X    toVal->size = 0;
  1893. X    toVal->addr = (caddr_t) NULL;
  1894. X    if (string == NULL) return;
  1895. X
  1896. X/*  -- parse input string finding segments   "name(arg)" comma separated */
  1897. X    ipar = 0;
  1898. X    seg  = segs;
  1899. X    seg->nsta = seg->nend = seg->asta = seg->aend = (char*)NULL;
  1900. X
  1901. X    for ( s=string;  ;  s++ )
  1902. X    {
  1903. X    switch (*s)
  1904. X    {
  1905. X        case NUL:
  1906. X    case ',':  if ( ipar > 0 ) break;  /* commas in arguments ignored  */
  1907. X           if ( seg->nend == NULL ) seg->nend = s-1;  /* no argument */
  1908. X               seg++;           /* start the next segment */
  1909. X               seg->nsta = seg->nend = seg->asta = seg->aend = (char*)NULL;
  1910. X           break;           
  1911. X
  1912. X    case '(':  if ( ipar++ == 0 ) { seg->nend = s-1; seg->asta = s+1; };
  1913. X               break;
  1914. X           
  1915. X    case ')':  if ( --ipar == 0 ) { seg->aend = s-1; };
  1916. X           break;
  1917. X
  1918. X    default:   if ( *s > ' '  &&  seg->nsta == NULL )
  1919. X            /* only start a new segment on non-blank char */
  1920. X                    seg->nsta = s;
  1921. X    }
  1922. X    if (*s == NUL) break;
  1923. X    }
  1924. X    seg++;           /* start the terminating segment */
  1925. X    seg->nsta = (char*)NULL;
  1926. X
  1927. X    if (ipar)
  1928. X    {
  1929. X    XtStringConversionWarning (string, "Callback, unbalanced parenthesis");
  1930. X    return;
  1931. X    }
  1932. X
  1933. X/*  -- process individual callback string segments "name(arg)" */
  1934. X    for( seg = segs;  seg->nsta;   seg++)
  1935. X    {
  1936. X        char                 cb_name[MAX_XRMSTRING];
  1937. X    XtCallbackProc       found = (XtCallbackProc)NULL;
  1938. X    XrmQuark             quark;
  1939. X    register char    *d;
  1940. X    register char    *end;
  1941. X
  1942. X    /* our callback cache names are case insensitive, no white space */
  1943. X    for ( s=seg->nsta, d=cb_name; s<=seg->nend; )
  1944. X       if ( *s > ' ')
  1945. X             *d++ = (isupper(*s) ) ? tolower (*s++) : *s++;
  1946. X       else
  1947. X          s++;
  1948. X    *d   = NUL;
  1949. X
  1950. X        /* try to locate callback in our cache of callbacks */
  1951. X        quark = XrmStringToQuark (cb_name);
  1952. X    for (i=0; i<callbacks_num; i++)
  1953. X        if ( callbacks_ptr[i].quark == quark )
  1954. X        {
  1955. X            register XtCallbackRec *rec = &callback_list[callback_num];
  1956. X        rec->callback = found = callbacks_ptr[i].callback;
  1957. X            rec->closure  = callbacks_ptr[i].closure;
  1958. X        break;
  1959. X        }
  1960. X
  1961. X    /* we have found a registered callback, process arguments */
  1962. X    if (found)
  1963. X    {
  1964. X       register char *arg;
  1965. X       register int   alen;
  1966. X       register XtCallbackRec *rec = &callback_list[callback_num];
  1967. X       
  1968. X       if ( seg->asta )
  1969. X       {
  1970. X           alen = (int)seg->aend - (int)seg->asta +1;
  1971. X           arg  = XtMalloc(alen+1);
  1972. X           strncpy ( arg, seg->asta, alen );
  1973. X           arg[alen]    = NUL;
  1974. X           rec->closure = (caddr_t)arg;
  1975. X       }
  1976. X       else
  1977. X       {
  1978. X           /* there is always a char[], it may have only a NUL */
  1979. X               rec->closure = (caddr_t)"\0";
  1980. X       }
  1981. X       callback_num++;
  1982. X        }
  1983. X    else
  1984. X    {
  1985. X           XtStringConversionWarning (cb_name, 
  1986. X            "Callback, unknown callback name");
  1987. X    }
  1988. X    } /* end for seg loop */
  1989. X
  1990. X/*  -- terminate the callback list */
  1991. X    {
  1992. X    register XtCallbackRec *rec = &callback_list[callback_num];
  1993. X        rec->callback = NULL;
  1994. X    rec->closure  = NULL;
  1995. X    callback_num++;
  1996. X    }
  1997. X
  1998. X/*  -- make a permanent copy of the new callback list, and return a pointer */
  1999. X    cb = (XtCallbackRec*)XtMalloc( callback_num * sizeof (XtCallbackRec) );
  2000. X    memcpy ( (char*)cb, (char*)callback_list,  
  2001. X              callback_num * sizeof (XtCallbackRec));
  2002. X    toVal->size = sizeof (XtCallbackRec*);
  2003. X    toVal->addr = (caddr_t)&cb;
  2004. X}
  2005. X
  2006. X/*
  2007. X    -- Convert String To Widget
  2008. X*******************************************************************************
  2009. X    This conversion creates a Widget id from the X resource database string.
  2010. X    The conversion will fail, and WcFullNameToWidget() will issue a warning,
  2011. X    if the widget so named has not been created when this converter is called.
  2012. X    For example, if a widget refers to itself for some reason, during
  2013. X    its creation when this converter is called, it is not yet created: 
  2014. X    therefore, the converter will fail.
  2015. X*/
  2016. X
  2017. Xvoid XmuCvtStringToWidget (args, num_args, fromVal, toVal)
  2018. X    XrmValue *args;
  2019. X    Cardinal *num_args;
  2020. X    XrmValue *fromVal;
  2021. X    XrmValue *toVal;
  2022. X{
  2023. X    toVal->addr = 
  2024. X    (caddr_t) WcFullNameToWidget( WcRootWidget(NULL), fromVal->addr);
  2025. X    toVal->size = sizeof(Widget);
  2026. X}
  2027. X
  2028. X#ifdef MOTIF
  2029. X/*
  2030. X    -- Convert String To MenuWidget
  2031. X*******************************************************************************
  2032. X    This conversion converts strings into menu widgets for use on
  2033. X    cascade button subMenuId resource specifications.
  2034. X*/
  2035. X
  2036. Xvoid CvtStringToMenuWidget (args, num_args, fromVal, toVal)
  2037. X    XrmValue *args;
  2038. X    Cardinal *num_args;
  2039. X    XrmValue *fromVal;
  2040. X    XrmValue *toVal;
  2041. X{
  2042. X    char    cleanName[MAX_XRMSTRING];
  2043. X    Widget    widget;
  2044. X    Arg        existing[1];
  2045. X
  2046. X    (void)WcCleanName( fromVal->addr, cleanName );
  2047. X
  2048. X    widget = WcFullNameToWidget( WcRootWidget(NULL), cleanName );
  2049. X
  2050. X    if ( widget == NULL )
  2051. X    {
  2052. X    XtStringConversionWarning (cleanName,
  2053. X                "MenuWidget - no such widget.  Misspelled? Forgot the path?");
  2054. X    return;
  2055. X    }
  2056. X    else if ( XmIsRowColumn( widget ) 
  2057. X      && (   RC_Type ( (XmRowColumnWidget)widget ) == XmMENU_PULLDOWN
  2058. X          || RC_Type ( (XmRowColumnWidget)widget ) == XmMENU_POPUP    ) )
  2059. X    {
  2060. X    done ( Widget, widget );
  2061. X    }
  2062. X    XtStringConversionWarning (cleanName, 
  2063. X        "MenuWidget - not XmMENU_PULLDOWN or XmMENU_POPUP.");
  2064. X}
  2065. X#endif MOTIF
  2066. X
  2067. X/*
  2068. X*******************************************************************************
  2069. X* Public_function_declarations.
  2070. X*******************************************************************************
  2071. X*/
  2072. X
  2073. X/*
  2074. X    -- Add String To ... Convertors
  2075. X*******************************************************************************
  2076. X*/
  2077. X
  2078. Xvoid WcAddConverters ( unused )
  2079. X    XtAppContext unused;    /* maybe someday... */
  2080. X{
  2081. X    static Boolean added = FALSE;
  2082. X    if ( !added++ )
  2083. X    {
  2084. X
  2085. X       XtAddConverter    (XtRString,
  2086. X                          WcRClassPtr,
  2087. X                          CvtStringToClassPtr,
  2088. X                          (XtConvertArgList)NULL,
  2089. X                          (Cardinal)0);
  2090. X
  2091. X       XtAddConverter    (XtRString,
  2092. X                          WcRClassName,
  2093. X                          CvtStringToClassName,
  2094. X                          (XtConvertArgList)NULL,
  2095. X                          (Cardinal)0);
  2096. X
  2097. X       XtAddConverter    (XtRString,
  2098. X                          WcRConstructor,
  2099. X                          CvtStringToConstructor,
  2100. X                          (XtConvertArgList)NULL,
  2101. X                          (Cardinal)0);
  2102. X
  2103. X       XtAddConverter    (XtRString, 
  2104. X                          XtRCallback,
  2105. X                          CvtStringToCallback,
  2106. X                          (XtConvertArgList)NULL,
  2107. X                          (Cardinal)0);
  2108. X
  2109. X#ifndef MOTIF
  2110. X       XtAddConverter    (XtRString,
  2111. X                          XtRWidget,
  2112. X                          XmuCvtStringToWidget,
  2113. X                          (XtConvertArgList)NULL,
  2114. X                          (Cardinal)0);
  2115. X#else
  2116. X       XtAddConverter    (XtRString,
  2117. X                          WcRWidget,  /* "Window" is wrong, but it works !?! */
  2118. X                          XmuCvtStringToWidget,
  2119. X                          (XtConvertArgList)NULL,
  2120. X                          (Cardinal)0);
  2121. X
  2122. X       XtAddConverter    (XtRString,
  2123. X                          XmRMenuWidget,
  2124. X                          CvtStringToMenuWidget,
  2125. X                          (XtConvertArgList)NULL,
  2126. X                          (Cardinal)0);
  2127. X#endif !MOTIF
  2128. X    }
  2129. X}
  2130. +FUNKY+STUFF+
  2131. echo '-rw-r--r--  1 david       19854 Jun 28 09:13 WcConverters.c    (as sent)'
  2132. chmod u=rw,g=r,o=r WcConverters.c
  2133. ls -l WcConverters.c
  2134. exit 0
  2135.  
  2136. dan
  2137. ----------------------------------------------------
  2138. O'Reilly && Associates   argv@sun.com / argv@ora.com
  2139. Opinions expressed reflect those of the author only.
  2140.