2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
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
23 /* $XConsortium: MainWindow.c /main/7 1996/10/31 02:04:14 cde-hp $ */
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.
37 #include <Dt/HelpDialog.h>
38 #include <Dt/dtpdmd.h>
39 #include <Dt/DtNlUtils.h>
45 #include "MainWindow.h"
48 * PdmMainWindow-specific fallback resources
50 static String PdmMainWinFallbackResources[] =
52 "*Notebook.ExmTabButton.notebookChildType: XmMINOR_TAB",
53 "*Notebook.XmPushButton.notebookChildType: XmMINOR_TAB",
54 "*HelpDialog_popup.title: Print Setup - Help",
55 "*Notebook.backPageNumber: 4",
56 "*Notebook.backPagePlacement: XmTOP_RIGHT",
57 "*Notebook.bindingType: XmNONE",
58 "*Notebook.minorTabSpacing: 8",
59 "*NotebookLabel.labelString: Setup Options:",
60 "*PrinterDescriptionLabel.labelString: Printer Description:",
61 "*PrinterNameLabel.labelString: Printer:",
62 "*helpVolume: PrnSetup"
66 * static function declarations
68 static void PdmMainWinCreateSetupBoxes(PdmMainWin* me);
69 static Widget PdmMainWinCreateWindow(PdmMainWin* me, Widget parent);
70 static void PdmMainWinGetAttributes(PdmMainWin* me);
71 static void PdmMainWinOkCB(Widget, XtPointer, XtPointer);
72 static void PdmMainWinCancelCB(Widget, XtPointer, XtPointer);
73 static void PdmMainWinHelpCB(Widget, XtPointer, XtPointer);
74 static void PdmMainWinHelpDestroyCB(Widget, XtPointer, XtPointer);
77 * ------------------------------------------------------------------------
82 * Allocates a new PdmMainWin instance structure.
86 * A pointer to the new PdmMainWin instance.
92 PdmMainWin* me = (PdmMainWin*)XtCalloc(1, sizeof(PdmMainWin));
93 me->pdm_xp = PdmXpNew();
99 * ------------------------------------------------------------------------
100 * Name: PdmMainWinDelete
104 * Frees the passed PdmMainWin instance structure.
112 PdmMainWinDelete(PdmMainWin* me)
116 * close the print server connection
118 if(me->pdm_xp != (PdmXp*)NULL)
119 PdmXpDelete(me->pdm_xp);
121 * destroy the help dialog
123 if((Widget)NULL != me->help_dialog)
125 XtDestroyWidget(me->help_dialog);
128 * clean up the child setup box list
130 while((node = me->box_list_head) != (PdmBoxNode*)NULL)
132 me->box_list_head = node->next;
136 * clean up string members
138 XtFree((char*)me->print_display_spec);
140 * free the instance structure
146 * ------------------------------------------------------------------------
147 * Name: PdmMainWinAddSetupBox
151 * Adds a PDM setup box to the list of setup boxes managed by the
156 * The passed PdmSetupBox pointer.
160 PdmMainWinAddSetupBox(PdmMainWin* me, PdmSetupBox* box)
163 * create a new setup box node for the passed setup box
164 * and add it to the end of the list
166 PdmBoxList new_node = (PdmBoxList)XtCalloc(1, sizeof(PdmBoxNode));
168 if(me->box_list_tail)
169 me->box_list_tail = me->box_list_tail->next = new_node;
171 me->box_list_head = me->box_list_tail = new_node;
175 * ------------------------------------------------------------------------
176 * Name: PdmMainWinMergeFallbacks
180 * Merges the fallback resources defined by the main window and each
181 * of the setup boxes with the passed set of fallback resources.
185 * The merged array of fallback resources. The passed set of
186 * fallback appear first in the list, followed by the main window
187 * fallbacks, followed by the fallbacks for each setup box. The last
188 * entry in the list is set to NULL. It is the caller's
189 * responsibility to free the returned list using XtFree.
192 String* PdmMainWinMergeFallbacks(PdmMainWin* me,
193 const String* app_fallbacks,
196 String* new_fallbacks;
202 res_count += XtNumber(PdmMainWinFallbackResources);
203 for(node = me->box_list_head; node != (PdmBoxNode*)NULL; node = node->next)
204 res_count += node->box->fallback_resources_count;
206 new_fallbacks = (String*)XtCalloc(res_count+1, sizeof(String));
209 memcpy(ptr, app_fallbacks, count*sizeof(String));
211 memcpy(ptr, PdmMainWinFallbackResources,
212 XtNumber(PdmMainWinFallbackResources)*sizeof(String));
213 ptr += XtNumber(PdmMainWinFallbackResources);
214 for(node = me->box_list_head; node != (PdmBoxNode*)NULL; node = node->next)
216 memcpy(ptr, node->box->fallback_resources,
217 node->box->fallback_resources_count*sizeof(String));
218 ptr += node->box->fallback_resources_count;
220 return new_fallbacks;
225 * ------------------------------------------------------------------------
226 * Name: PdmMainWinCreateSetupBoxes
230 * For each setup box added to the setup box list,
231 * PdmMainWinCreateSetupBoxes calls the setup box's create method,
232 * passing the notebook as the parent. A tab button is created for
241 PdmMainWinCreateSetupBoxes(PdmMainWin* me)
245 for(node = me->box_list_head; node != (PdmBoxNode*)NULL; node = node->next)
247 PdmSetupBox* box = node->box;
249 * create the setup box widget as a child of the notebook
251 (*box->create_proc)(box, me->notebook);
253 * create a tab for the new setup box notebook page
257 XtVaCreateManagedWidget(box->tab_name,
258 exmTabButtonWidgetClass,
263 XtVaCreateManagedWidget(box->tab_name,
264 xmPushButtonWidgetClass,
267 #endif /* USE_EXM_TABS */
273 * ------------------------------------------------------------------------
274 * Name: PdmMainWinGetAttributes
286 PdmMainWinGetAttributes(PdmMainWin* me)
290 * get attributes for the main window
292 me->printer_descriptor = PdmXpGetStringValue(me->pdm_xp,
294 pdmoid_att_descriptor);
295 me->printer_name = PdmXpGetStringValue(me->pdm_xp,
297 pdmoid_att_printer_name);
299 * call the get attributes proc for each setup box child
301 for(node = me->box_list_head; node != (PdmBoxNode*)NULL; node = node->next)
303 PdmSetupBox* box = node->box;
305 (*box->get_attr_proc)(box, me->pdm_xp);
310 * ------------------------------------------------------------------------
311 * Name: PdmMainWinOkCB
315 * Callback for the main window OK button. This function first calls
316 * the verify values method for each of the child setup boxes. If the
317 * values for all of the children are Ok, the new values are set into
318 * the print context, and the program exits. Otherwise the program
319 * resumes. In this case, it is assumed that the child setup box will
320 * present a message to the user indicating that its values are not
321 * Ok. This function will move the invalid child setup notebook page
326 * None, although it usually ends the program with an exit code of
333 XtPointer client_data,
336 PdmMainWin* me = (PdmMainWin*)client_data;
340 * call the verify values proc for each setup box child
342 for(node = me->box_list_head, page = 1;
343 node != (PdmBoxNode*)NULL;
344 node = node->next, page++)
346 PdmSetupBox* box = node->box;
348 if((*box->verify_attr_proc)(box, me->pdm_xp) != PDM_SUCCESS)
351 * Ensure this setup box is the top notebook page; the setup
352 * box is responsible for providing error messages to the
355 * developer hint: do not use the setup box as the parent of
356 * a message box; if the setup box is not the
357 * current notebook page, the message box
358 * will not be positioned properly; use the
359 * first shell ancestor (or even the parent)
360 * of the setup box instead
362 XtVaSetValues(me->notebook, XmNcurrentPageNumber, page, NULL);
364 * stop verifying and return
370 * call the set attributes proc for each setup box child
372 for(node = me->box_list_head; node != (PdmBoxNode*)NULL; node = node->next)
374 PdmSetupBox* box = node->box;
376 (*box->set_attr_proc)(box, me->pdm_xp);
379 * set the updated attributes into the print context
381 PdmXpUpdateAttributes(me->pdm_xp);
385 PdmMainWinDelete(me);
390 * ------------------------------------------------------------------------
391 * Name: PdmMainWinCancelCB
395 * Callback for the main window Cancel button. This function simply
396 * ends the PDM program.
400 * None, although it will end the program with an exit code of
407 XtPointer client_data,
410 PdmMainWin* me = (PdmMainWin*)client_data;
411 PdmMainWinDelete(me);
412 exit(PDM_EXIT_CANCEL);
416 * ------------------------------------------------------------------------
417 * Name: PdmMainWinHelpCB
427 PdmMainWinHelpCB(Widget w, XtPointer client_data, XtPointer call_data)
429 PdmMainWin* me = (PdmMainWin*)client_data;
431 struct _box_resources
437 * create the help dialog if needed
439 if((Widget)NULL == me->help_dialog)
442 DtCreateHelpDialog(XtParent(me->widget), "HelpDialog", NULL, 0);
443 XtAddCallback(me->help_dialog, XmNdestroyCallback,
444 PdmMainWinHelpDestroyCB, (XtPointer)me);
447 * determine the current setup box
453 XtVaGetValues(me->notebook, XmNcurrentPageNumber, ¤t_page, NULL);
454 node = me->box_list_head;
455 for(i = 1; i < current_page; i++)
460 * the help volume name and location id are obtained up as application
461 * resources qualified for each setup box
464 XtResource resources[2];
466 * initialize res struct for help volume
468 resources[0].resource_name = DtNhelpVolume;
469 resources[0].resource_class = DtCHelpVolume;
470 resources[0].resource_type = XmRString;
471 resources[0].resource_size = sizeof(String);
472 resources[0].resource_offset =
473 XtOffsetOf(struct _box_resources, help_volume);
474 resources[0].default_type = XmRImmediate;
475 resources[0].default_addr = (XtPointer)NULL;
477 * initialize res struct for location id
479 resources[1].resource_name = DtNlocationId;
480 resources[1].resource_class = DtCLocationId;
481 resources[1].resource_type = XmRString;
482 resources[1].resource_size = sizeof(String);
483 resources[1].resource_offset =
484 XtOffsetOf(struct _box_resources, location_id);
485 resources[1].default_type = XmRImmediate;
486 resources[1].default_addr = (XtPointer)NULL;
488 * get the resource values for the current setup box widget
490 XtGetApplicationResources(box->widget, (XtPointer)&box_resources,
491 resources, XtNumber(resources),
495 * set the help volume and location
497 XtVaSetValues(me->help_dialog,
498 DtNhelpVolume, box_resources.help_volume,
499 DtNlocationId, box_resources.location_id,
500 DtNhelpType, DtHELP_TYPE_TOPIC,
503 * pop up the help dialog
505 XtManageChild(me->help_dialog);
509 * ------------------------------------------------------------------------
510 * Name: PdmMainWinHelpCB
514 * Update the main window instance structure to reflect destruction
515 * of the help dialog.
522 PdmMainWinHelpDestroyCB(Widget w, XtPointer client_data, XtPointer call_data)
524 PdmMainWin* me = (PdmMainWin*)client_data;
525 me->help_dialog = (Widget)NULL;
529 * ------------------------------------------------------------------------
530 * Name: PdmMainWinCreate
534 * Creates the PDM main window, including setup box children added
535 * via PdmMainWinAddSetupBox.
539 * The passed PdmMainWin pointer.
543 PdmMainWinCreate(PdmMainWin* me,
545 String print_display_spec,
546 String print_context_str)
549 * establish the print server connection
551 if(PdmXpOpen(me->pdm_xp, print_display_spec, print_context_str)
555 * unable to open the print display
557 PdmMainWinDelete(me);
558 exit(PDM_EXIT_PXAUTH);
561 * make a copy of the print display spec
563 me->print_display_spec = XtNewString(print_display_spec);
565 * get attributes for the main window and the setup box children
567 PdmMainWinGetAttributes(me);
569 * create the main window
571 PdmMainWinCreateWindow(me, parent);
573 * add the registered setup boxes to the notebook
575 PdmMainWinCreateSetupBoxes(me);
583 * ------------------------------------------------------------------------
584 * Name: PdmMainWinCreateWindow
588 * Creates the PDM main window, including setup box children added
589 * via PdmMainWinAddSetupBox.
593 * The main window widget ID.
597 PdmMainWinCreateWindow(PdmMainWin* me,
606 * create the main window
609 XtVaCreateManagedWidget("Main",
610 xmMessageBoxWidgetClass,
612 XmNdialogType, XmDIALOG_MESSAGE,
614 XtUnmanageChild(XtNameToWidget(me->widget, "Message"));
615 XtUnmanageChild(XtNameToWidget(me->widget, "Symbol"));
617 * add OK, Cancel and Help pushbutton callbacks
619 XtAddCallback(me->widget, XmNokCallback,
620 PdmMainWinOkCB, (XtPointer)me);
621 XtAddCallback(me->widget, XmNcancelCallback,
622 PdmMainWinCancelCB, (XtPointer)me);
623 XtAddCallback(me->widget, XmNhelpCallback,
624 PdmMainWinHelpCB, (XtPointer)me);
626 * create the main manager widget
628 manager = XtVaCreateManagedWidget("Manager",
629 xmRowColumnWidgetClass,
633 * create the printer description row
635 if(me->printer_descriptor != (const char*)NULL)
640 row = XtVaCreateManagedWidget(
641 "PrinterDescriptionRow",
642 xmRowColumnWidgetClass,
644 XmNorientation, XmHORIZONTAL,
647 * create the printer description label
649 w = XtVaCreateManagedWidget("PrinterDescriptionLabel",
654 * create the printer description using just the 1st line
656 desc = XtNewString(me->printer_descriptor);
657 ptr = Dt_strchr(desc, '\n');
660 label = XmStringCreateLocalized(desc);
662 w = XtVaCreateManagedWidget("PrinterDescription",
665 XmNlabelString, label,
670 * create the printer name row
672 if(me->printer_name != (const char*)NULL)
675 int printer_spec_len;
677 row = XtVaCreateManagedWidget(
679 xmRowColumnWidgetClass,
681 XmNorientation, XmHORIZONTAL,
684 * create the printer name label
686 w = XtVaCreateManagedWidget("PrinterNameLabel",
691 * build the X printer specifier
693 printer_spec_len = strlen(me->printer_name);
694 if(me->print_display_spec != (char*)NULL)
695 printer_spec_len += strlen(me->print_display_spec) + 1;
696 printer_spec = XtMalloc(printer_spec_len + 1);
697 strcpy(printer_spec, me->printer_name);
698 if(me->print_display_spec != (char*)NULL)
700 strcat(printer_spec, "@");
701 strcat(printer_spec, me->print_display_spec);
704 * create the printer name
706 label = XmStringCreateLocalized(printer_spec);
707 XtFree(printer_spec);
708 w = XtVaCreateManagedWidget("PrinterName",
711 XmNlabelString, label,
718 w = XtVaCreateManagedWidget("TopSeparator",
719 xmSeparatorGadgetClass,
725 row = XtVaCreateManagedWidget(
727 xmRowColumnWidgetClass,
729 XmNorientation, XmHORIZONTAL,
731 w = XtVaCreateManagedWidget("NotebookLabel",
736 * create the notebook
738 row = XtVaCreateManagedWidget(
740 xmRowColumnWidgetClass,
742 XmNorientation, XmHORIZONTAL,
745 XtVaCreateManagedWidget(
747 xmNotebookWidgetClass,
751 * Create an unmanaged notebook page scroller (i.e. a widget that has
752 * the XmQTnavigator trait), otherwise the notebook widget will
753 * create a default page scroller when it is realized. If this
754 * default page scroller is unmanaged after realization, the parent
755 * manager of the notebook does not shrink in order to reclaim the
756 * space previously occupied by the page scroller.
758 XtVaCreateWidget("DummyPageScroller",
759 xmScrollBarWidgetClass,