PageRenderTime 45ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/cde/programs/dtpdm/MainWindow.c

https://bitbucket.org/tifan/cde
C | 766 lines | 366 code | 30 blank | 370 comment | 35 complexity | bbac2d4681403836e99fb2c70b8c8a03 MD5 | raw file
Possible License(s): LGPL-2.1, IPL-1.0, 0BSD
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these librararies and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* $XConsortium: MainWindow.c /main/7 1996/10/31 02:04:14 cde-hp $ */
  24. /*
  25. * dtpdm/MainWindow.c
  26. */
  27. /*
  28. * (c) Copyright 1996 Digital Equipment Corporation.
  29. * (c) Copyright 1996 Hewlett-Packard Company.
  30. * (c) Copyright 1996 International Business Machines Corp.
  31. * (c) Copyright 1996 Sun Microsystems, Inc.
  32. * (c) Copyright 1996 Novell, Inc.
  33. * (c) Copyright 1996 FUJITSU LIMITED.
  34. * (c) Copyright 1996 Hitachi.
  35. */
  36. #include <Xm/XmAll.h>
  37. #include <Dt/HelpDialog.h>
  38. #include <Dt/dtpdmd.h>
  39. #include <Dt/DtNlUtils.h>
  40. #ifdef USE_EXM_TABS
  41. #include <Exm/TabB.h>
  42. #endif
  43. #include "MainWindow.h"
  44. /*
  45. * PdmMainWindow-specific fallback resources
  46. */
  47. static String PdmMainWinFallbackResources[] =
  48. {
  49. "*Notebook.ExmTabButton.notebookChildType: XmMINOR_TAB",
  50. "*Notebook.XmPushButton.notebookChildType: XmMINOR_TAB",
  51. "*HelpDialog_popup.title: Print Setup - Help",
  52. "*Notebook.backPageNumber: 4",
  53. "*Notebook.backPagePlacement: XmTOP_RIGHT",
  54. "*Notebook.bindingType: XmNONE",
  55. "*Notebook.minorTabSpacing: 8",
  56. "*NotebookLabel.labelString: Setup Options:",
  57. "*PrinterDescriptionLabel.labelString: Printer Description:",
  58. "*PrinterNameLabel.labelString: Printer:",
  59. "*helpVolume: PrnSetup"
  60. };
  61. /*
  62. * static function declarations
  63. */
  64. static void PdmMainWinCreateSetupBoxes(PdmMainWin* me);
  65. static Widget PdmMainWinCreateWindow(PdmMainWin* me, Widget parent);
  66. static void PdmMainWinGetAttributes(PdmMainWin* me);
  67. static void PdmMainWinOkCB(Widget, XtPointer, XtPointer);
  68. static void PdmMainWinCancelCB(Widget, XtPointer, XtPointer);
  69. static void PdmMainWinHelpCB(Widget, XtPointer, XtPointer);
  70. static void PdmMainWinHelpDestroyCB(Widget, XtPointer, XtPointer);
  71. /*
  72. * ------------------------------------------------------------------------
  73. * Name: PdmMainWinNew
  74. *
  75. * Description:
  76. *
  77. * Allocates a new PdmMainWin instance structure.
  78. *
  79. * Return value:
  80. *
  81. * A pointer to the new PdmMainWin instance.
  82. *
  83. */
  84. PdmMainWin*
  85. PdmMainWinNew()
  86. {
  87. PdmMainWin* me = (PdmMainWin*)XtCalloc(1, sizeof(PdmMainWin));
  88. me->pdm_xp = PdmXpNew();
  89. return me;
  90. }
  91. /*
  92. * ------------------------------------------------------------------------
  93. * Name: PdmMainWinDelete
  94. *
  95. * Description:
  96. *
  97. * Frees the passed PdmMainWin instance structure.
  98. *
  99. * Return value:
  100. *
  101. * None
  102. *
  103. */
  104. void
  105. PdmMainWinDelete(PdmMainWin* me)
  106. {
  107. PdmBoxNode* node;
  108. /*
  109. * close the print server connection
  110. */
  111. if(me->pdm_xp != (PdmXp*)NULL)
  112. PdmXpDelete(me->pdm_xp);
  113. /*
  114. * destroy the help dialog
  115. */
  116. if((Widget)NULL != me->help_dialog)
  117. {
  118. XtDestroyWidget(me->help_dialog);
  119. }
  120. /*
  121. * clean up the child setup box list
  122. */
  123. while((node = me->box_list_head) != (PdmBoxNode*)NULL)
  124. {
  125. me->box_list_head = node->next;
  126. XtFree((char*)node);
  127. }
  128. /*
  129. * clean up string members
  130. */
  131. XtFree((char*)me->print_display_spec);
  132. /*
  133. * free the instance structure
  134. */
  135. XtFree((char*)me);
  136. }
  137. /*
  138. * ------------------------------------------------------------------------
  139. * Name: PdmMainWinAddSetupBox
  140. *
  141. * Description:
  142. *
  143. * Adds a PDM setup box to the list of setup boxes managed by the
  144. * main window.
  145. *
  146. * Return value:
  147. *
  148. * The passed PdmSetupBox pointer.
  149. *
  150. */
  151. PdmSetupBox*
  152. PdmMainWinAddSetupBox(PdmMainWin* me, PdmSetupBox* box)
  153. {
  154. /*
  155. * create a new setup box node for the passed setup box
  156. * and add it to the end of the list
  157. */
  158. PdmBoxList new_node = (PdmBoxList)XtCalloc(1, sizeof(PdmBoxNode));
  159. new_node->box = box;
  160. if(me->box_list_tail)
  161. me->box_list_tail = me->box_list_tail->next = new_node;
  162. else
  163. me->box_list_head = me->box_list_tail = new_node;
  164. }
  165. /*
  166. * ------------------------------------------------------------------------
  167. * Name: PdmMainWinMergeFallbacks
  168. *
  169. * Description:
  170. *
  171. * Merges the fallback resources defined by the main window and each
  172. * of the setup boxes with the passed set of fallback resources.
  173. *
  174. * Return value:
  175. *
  176. * The merged array of fallback resources. The passed set of
  177. * fallback appear first in the list, followed by the main window
  178. * fallbacks, followed by the fallbacks for each setup box. The last
  179. * entry in the list is set to NULL. It is the caller's
  180. * responsibility to free the returned list using XtFree.
  181. *
  182. */
  183. String* PdmMainWinMergeFallbacks(PdmMainWin* me,
  184. const String* app_fallbacks,
  185. int count)
  186. {
  187. String* new_fallbacks;
  188. int res_count;
  189. PdmBoxNode* node;
  190. String* ptr;
  191. res_count = count;
  192. res_count += XtNumber(PdmMainWinFallbackResources);
  193. for(node = me->box_list_head; node != (PdmBoxNode*)NULL; node = node->next)
  194. res_count += node->box->fallback_resources_count;
  195. new_fallbacks = (String*)XtCalloc(res_count+1, sizeof(String));
  196. ptr = new_fallbacks;
  197. memcpy(ptr, app_fallbacks, count*sizeof(String));
  198. ptr += count;
  199. memcpy(ptr, PdmMainWinFallbackResources,
  200. XtNumber(PdmMainWinFallbackResources)*sizeof(String));
  201. ptr += XtNumber(PdmMainWinFallbackResources);
  202. for(node = me->box_list_head; node != (PdmBoxNode*)NULL; node = node->next)
  203. {
  204. memcpy(ptr, node->box->fallback_resources,
  205. node->box->fallback_resources_count*sizeof(String));
  206. ptr += node->box->fallback_resources_count;
  207. }
  208. return new_fallbacks;
  209. }
  210. /*
  211. * ------------------------------------------------------------------------
  212. * Name: PdmMainWinCreateSetupBoxes
  213. *
  214. * Description:
  215. *
  216. * For each setup box added to the setup box list,
  217. * PdmMainWinCreateSetupBoxes calls the setup box's create method,
  218. * passing the notebook as the parent. A tab button is created for
  219. * each setup box.
  220. *
  221. * Return value:
  222. *
  223. * None.
  224. *
  225. */
  226. static void
  227. PdmMainWinCreateSetupBoxes(PdmMainWin* me)
  228. {
  229. PdmBoxNode* node;
  230. for(node = me->box_list_head; node != (PdmBoxNode*)NULL; node = node->next)
  231. {
  232. PdmSetupBox* box = node->box;
  233. /*
  234. * create the setup box widget as a child of the notebook
  235. */
  236. (*box->create_proc)(box, me->notebook);
  237. /*
  238. * create a tab for the new setup box notebook page
  239. */
  240. #ifdef USE_EXM_TABS
  241. node->tab =
  242. XtVaCreateManagedWidget(box->tab_name,
  243. exmTabButtonWidgetClass,
  244. me->notebook,
  245. NULL);
  246. #else
  247. node->tab =
  248. XtVaCreateManagedWidget(box->tab_name,
  249. xmPushButtonWidgetClass,
  250. me->notebook,
  251. NULL);
  252. #endif /* USE_EXM_TABS */
  253. }
  254. }
  255. /*
  256. * ------------------------------------------------------------------------
  257. * Name: PdmMainWinGetAttributes
  258. *
  259. * Description:
  260. *
  261. *
  262. *
  263. * Return value:
  264. *
  265. * None
  266. *
  267. */
  268. static void
  269. PdmMainWinGetAttributes(PdmMainWin* me)
  270. {
  271. PdmBoxNode* node;
  272. /*
  273. * get attributes for the main window
  274. */
  275. me->printer_descriptor = PdmXpGetStringValue(me->pdm_xp,
  276. XPPrinterAttr,
  277. pdmoid_att_descriptor);
  278. me->printer_name = PdmXpGetStringValue(me->pdm_xp,
  279. XPPrinterAttr,
  280. pdmoid_att_printer_name);
  281. /*
  282. * call the get attributes proc for each setup box child
  283. */
  284. for(node = me->box_list_head; node != (PdmBoxNode*)NULL; node = node->next)
  285. {
  286. PdmSetupBox* box = node->box;
  287. (*box->get_attr_proc)(box, me->pdm_xp);
  288. }
  289. }
  290. /*
  291. * ------------------------------------------------------------------------
  292. * Name: PdmMainWinOkCB
  293. *
  294. * Description:
  295. *
  296. * Callback for the main window OK button. This function first calls
  297. * the verify values method for each of the child setup boxes. If the
  298. * values for all of the children are Ok, the new values are set into
  299. * the print context, and the program exits. Otherwise the program
  300. * resumes. In this case, it is assumed that the child setup box will
  301. * present a message to the user indicating that its values are not
  302. * Ok. This function will move the invalid child setup notebook page
  303. * to the top.
  304. *
  305. * Return value:
  306. *
  307. * None, although it usually ends the program with an exit code of
  308. * PDM_EXIT_OK.
  309. *
  310. */
  311. static void
  312. PdmMainWinOkCB(
  313. Widget w,
  314. XtPointer client_data,
  315. XtPointer call_data)
  316. {
  317. PdmMainWin* me = (PdmMainWin*)client_data;
  318. PdmBoxNode* node;
  319. int page;
  320. /*
  321. * call the verify values proc for each setup box child
  322. */
  323. for(node = me->box_list_head, page = 1;
  324. node != (PdmBoxNode*)NULL;
  325. node = node->next, page++)
  326. {
  327. PdmSetupBox* box = node->box;
  328. if((*box->verify_attr_proc)(box, me->pdm_xp) != PDM_SUCCESS)
  329. {
  330. /*
  331. * Ensure this setup box is the top notebook page; the setup
  332. * box is responsible for providing error messages to the
  333. * user.
  334. *
  335. * developer hint: do not use the setup box as the parent of
  336. * a message box; if the setup box is not the
  337. * current notebook page, the message box
  338. * will not be positioned properly; use the
  339. * first shell ancestor (or even the parent)
  340. * of the setup box instead
  341. */
  342. XtVaSetValues(me->notebook, XmNcurrentPageNumber, page, NULL);
  343. /*
  344. * stop verifying and return
  345. */
  346. return;
  347. }
  348. }
  349. /*
  350. * call the set attributes proc for each setup box child
  351. */
  352. for(node = me->box_list_head; node != (PdmBoxNode*)NULL; node = node->next)
  353. {
  354. PdmSetupBox* box = node->box;
  355. (*box->set_attr_proc)(box, me->pdm_xp);
  356. }
  357. /*
  358. * set the updated attributes into the print context
  359. */
  360. PdmXpUpdateAttributes(me->pdm_xp);
  361. /*
  362. * exit the PDM
  363. */
  364. PdmMainWinDelete(me);
  365. exit(PDM_EXIT_OK);
  366. }
  367. /*
  368. * ------------------------------------------------------------------------
  369. * Name: PdmMainWinCancelCB
  370. *
  371. * Description:
  372. *
  373. * Callback for the main window Cancel button. This function simply
  374. * ends the PDM program.
  375. *
  376. * Return value:
  377. *
  378. * None, although it will end the program with an exit code of
  379. * PDM_EXIT_CANCEL.
  380. *
  381. */
  382. static void
  383. PdmMainWinCancelCB(
  384. Widget w,
  385. XtPointer client_data,
  386. XtPointer call_data)
  387. {
  388. PdmMainWin* me = (PdmMainWin*)client_data;
  389. PdmMainWinDelete(me);
  390. exit(PDM_EXIT_CANCEL);
  391. }
  392. /*
  393. * ------------------------------------------------------------------------
  394. * Name: PdmMainWinHelpCB
  395. *
  396. * Description:
  397. *
  398. *
  399. * Return value:
  400. *
  401. *
  402. */
  403. static void
  404. PdmMainWinHelpCB(Widget w, XtPointer client_data, XtPointer call_data)
  405. {
  406. PdmMainWin* me = (PdmMainWin*)client_data;
  407. PdmSetupBox* box;
  408. struct _box_resources
  409. {
  410. String help_volume;
  411. String location_id;
  412. } box_resources;
  413. /*
  414. * create the help dialog if needed
  415. */
  416. if((Widget)NULL == me->help_dialog)
  417. {
  418. me->help_dialog =
  419. DtCreateHelpDialog(XtParent(me->widget), "HelpDialog", NULL, 0);
  420. XtAddCallback(me->help_dialog, XmNdestroyCallback,
  421. PdmMainWinHelpDestroyCB, (XtPointer)me);
  422. }
  423. /*
  424. * determine the current setup box
  425. */
  426. {
  427. int current_page, i;
  428. PdmBoxNode* node;
  429. XtVaGetValues(me->notebook, XmNcurrentPageNumber, &current_page, NULL);
  430. node = me->box_list_head;
  431. for(i = 1; i < current_page; i++)
  432. node = node->next;
  433. box = node->box;
  434. }
  435. /*
  436. * the help volume name and location id are obtained up as application
  437. * resources qualified for each setup box
  438. */
  439. {
  440. XtResource resources[2];
  441. /*
  442. * initialize res struct for help volume
  443. */
  444. resources[0].resource_name = DtNhelpVolume;
  445. resources[0].resource_class = DtCHelpVolume;
  446. resources[0].resource_type = XmRString;
  447. resources[0].resource_size = sizeof(String);
  448. resources[0].resource_offset =
  449. XtOffsetOf(struct _box_resources, help_volume);
  450. resources[0].default_type = XmRImmediate;
  451. resources[0].default_addr = (XtPointer)NULL;
  452. /*
  453. * initialize res struct for location id
  454. */
  455. resources[1].resource_name = DtNlocationId;
  456. resources[1].resource_class = DtCLocationId;
  457. resources[1].resource_type = XmRString;
  458. resources[1].resource_size = sizeof(String);
  459. resources[1].resource_offset =
  460. XtOffsetOf(struct _box_resources, location_id);
  461. resources[1].default_type = XmRImmediate;
  462. resources[1].default_addr = (XtPointer)NULL;
  463. /*
  464. * get the resource values for the current setup box widget
  465. */
  466. XtGetApplicationResources(box->widget, (XtPointer)&box_resources,
  467. resources, XtNumber(resources),
  468. (ArgList)NULL, 0);
  469. }
  470. /*
  471. * set the help volume and location
  472. */
  473. XtVaSetValues(me->help_dialog,
  474. DtNhelpVolume, box_resources.help_volume,
  475. DtNlocationId, box_resources.location_id,
  476. DtNhelpType, DtHELP_TYPE_TOPIC,
  477. NULL);
  478. /*
  479. * pop up the help dialog
  480. */
  481. XtManageChild(me->help_dialog);
  482. }
  483. /*
  484. * ------------------------------------------------------------------------
  485. * Name: PdmMainWinHelpCB
  486. *
  487. * Description:
  488. *
  489. * Update the main window instance structure to reflect destruction
  490. * of the help dialog.
  491. *
  492. * Return value:
  493. *
  494. * None.
  495. */
  496. static void
  497. PdmMainWinHelpDestroyCB(Widget w, XtPointer client_data, XtPointer call_data)
  498. {
  499. PdmMainWin* me = (PdmMainWin*)client_data;
  500. me->help_dialog = (Widget)NULL;
  501. }
  502. /*
  503. * ------------------------------------------------------------------------
  504. * Name: PdmMainWinCreate
  505. *
  506. * Description:
  507. *
  508. * Creates the PDM main window, including setup box children added
  509. * via PdmMainWinAddSetupBox.
  510. *
  511. * Return value:
  512. *
  513. * The passed PdmMainWin pointer.
  514. *
  515. */
  516. PdmMainWin*
  517. PdmMainWinCreate(PdmMainWin* me,
  518. Widget parent,
  519. String print_display_spec,
  520. String print_context_str)
  521. {
  522. /*
  523. * establish the print server connection
  524. */
  525. if(PdmXpOpen(me->pdm_xp, print_display_spec, print_context_str)
  526. == (Display*)NULL)
  527. {
  528. /*
  529. * unable to open the print display
  530. */
  531. PdmMainWinDelete(me);
  532. exit(PDM_EXIT_PXAUTH);
  533. }
  534. /*
  535. * make a copy of the print display spec
  536. */
  537. me->print_display_spec = XtNewString(print_display_spec);
  538. /*
  539. * get attributes for the main window and the setup box children
  540. */
  541. PdmMainWinGetAttributes(me);
  542. /*
  543. * create the main window
  544. */
  545. PdmMainWinCreateWindow(me, parent);
  546. /*
  547. * add the registered setup boxes to the notebook
  548. */
  549. PdmMainWinCreateSetupBoxes(me);
  550. /*
  551. * return
  552. */
  553. return me;
  554. }
  555. /*
  556. * ------------------------------------------------------------------------
  557. * Name: PdmMainWinCreateWindow
  558. *
  559. * Description:
  560. *
  561. * Creates the PDM main window, including setup box children added
  562. * via PdmMainWinAddSetupBox.
  563. *
  564. * Return value:
  565. *
  566. * The main window widget ID.
  567. *
  568. */
  569. static Widget
  570. PdmMainWinCreateWindow(PdmMainWin* me,
  571. Widget parent)
  572. {
  573. Widget manager;
  574. Widget row;
  575. Widget w;
  576. XmString label;
  577. /*
  578. * create the main window
  579. */
  580. me->widget =
  581. XtVaCreateManagedWidget("Main",
  582. xmMessageBoxWidgetClass,
  583. parent,
  584. XmNdialogType, XmDIALOG_MESSAGE,
  585. NULL);
  586. XtUnmanageChild(XtNameToWidget(me->widget, "Message"));
  587. XtUnmanageChild(XtNameToWidget(me->widget, "Symbol"));
  588. /*
  589. * add OK, Cancel and Help pushbutton callbacks
  590. */
  591. XtAddCallback(me->widget, XmNokCallback,
  592. PdmMainWinOkCB, (XtPointer)me);
  593. XtAddCallback(me->widget, XmNcancelCallback,
  594. PdmMainWinCancelCB, (XtPointer)me);
  595. XtAddCallback(me->widget, XmNhelpCallback,
  596. PdmMainWinHelpCB, (XtPointer)me);
  597. /*
  598. * create the main manager widget
  599. */
  600. manager = XtVaCreateManagedWidget("Manager",
  601. xmRowColumnWidgetClass,
  602. me->widget,
  603. NULL);
  604. /*
  605. * create the printer description row
  606. */
  607. if(me->printer_descriptor != (const char*)NULL)
  608. {
  609. char* desc;
  610. char* ptr;
  611. row = XtVaCreateManagedWidget(
  612. "PrinterDescriptionRow",
  613. xmRowColumnWidgetClass,
  614. manager,
  615. XmNorientation, XmHORIZONTAL,
  616. NULL);
  617. /*
  618. * create the printer description label
  619. */
  620. w = XtVaCreateManagedWidget("PrinterDescriptionLabel",
  621. xmLabelGadgetClass,
  622. row,
  623. NULL);
  624. /*
  625. * create the printer description using just the 1st line
  626. */
  627. desc = XtNewString(me->printer_descriptor);
  628. ptr = Dt_strchr(desc, '\n');
  629. if(ptr != NULL)
  630. *ptr = '\0';
  631. label = XmStringCreateLocalized(desc);
  632. XtFree(desc);
  633. w = XtVaCreateManagedWidget("PrinterDescription",
  634. xmLabelGadgetClass,
  635. row,
  636. XmNlabelString, label,
  637. NULL);
  638. XmStringFree(label);
  639. }
  640. /*
  641. * create the printer name row
  642. */
  643. if(me->printer_name != (const char*)NULL)
  644. {
  645. char* printer_spec;
  646. int printer_spec_len;
  647. row = XtVaCreateManagedWidget(
  648. "PrinterNameRow",
  649. xmRowColumnWidgetClass,
  650. manager,
  651. XmNorientation, XmHORIZONTAL,
  652. NULL);
  653. /*
  654. * create the printer name label
  655. */
  656. w = XtVaCreateManagedWidget("PrinterNameLabel",
  657. xmLabelGadgetClass,
  658. row,
  659. NULL);
  660. /*
  661. * build the X printer specifier
  662. */
  663. printer_spec_len = strlen(me->printer_name);
  664. if(me->print_display_spec != (char*)NULL)
  665. printer_spec_len += strlen(me->print_display_spec) + 1;
  666. printer_spec = XtMalloc(printer_spec_len + 1);
  667. strcpy(printer_spec, me->printer_name);
  668. if(me->print_display_spec != (char*)NULL)
  669. {
  670. strcat(printer_spec, "@");
  671. strcat(printer_spec, me->print_display_spec);
  672. }
  673. /*
  674. * create the printer name
  675. */
  676. label = XmStringCreateLocalized(printer_spec);
  677. XtFree(printer_spec);
  678. w = XtVaCreateManagedWidget("PrinterName",
  679. xmLabelGadgetClass,
  680. row,
  681. XmNlabelString, label,
  682. NULL);
  683. XmStringFree(label);
  684. }
  685. /*
  686. * top separator
  687. */
  688. w = XtVaCreateManagedWidget("TopSeparator",
  689. xmSeparatorGadgetClass,
  690. manager,
  691. NULL);
  692. /*
  693. * notebook label
  694. */
  695. row = XtVaCreateManagedWidget(
  696. "PrinterNameRow",
  697. xmRowColumnWidgetClass,
  698. manager,
  699. XmNorientation, XmHORIZONTAL,
  700. NULL);
  701. w = XtVaCreateManagedWidget("NotebookLabel",
  702. xmLabelGadgetClass,
  703. row,
  704. NULL);
  705. /*
  706. * create the notebook
  707. */
  708. row = XtVaCreateManagedWidget(
  709. "NotebookRow",
  710. xmRowColumnWidgetClass,
  711. manager,
  712. XmNorientation, XmHORIZONTAL,
  713. NULL);
  714. me->notebook =
  715. XtVaCreateManagedWidget(
  716. "Notebook",
  717. xmNotebookWidgetClass,
  718. row,
  719. NULL);
  720. /*
  721. * Create an unmanaged notebook page scroller (i.e. a widget that has
  722. * the XmQTnavigator trait), otherwise the notebook widget will
  723. * create a default page scroller when it is realized. If this
  724. * default page scroller is unmanaged after realization, the parent
  725. * manager of the notebook does not shrink in order to reclaim the
  726. * space previously occupied by the page scroller.
  727. */
  728. XtVaCreateWidget("DummyPageScroller",
  729. xmScrollBarWidgetClass,
  730. me->notebook,
  731. NULL);
  732. /*
  733. * return
  734. */
  735. return me->widget;
  736. }