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 #if 0 && defined(PRINTING_SUPPORTED)
293 me->printer_descriptor = PdmXpGetStringValue(me->pdm_xp,
295 pdmoid_att_descriptor);
296 me->printer_name = PdmXpGetStringValue(me->pdm_xp,
298 pdmoid_att_printer_name);
299 #endif /* PRINTING_SUPPORTED */
301 * call the get attributes proc for each setup box child
303 for(node = me->box_list_head; node != (PdmBoxNode*)NULL; node = node->next)
305 PdmSetupBox* box = node->box;
307 (*box->get_attr_proc)(box, me->pdm_xp);
312 * ------------------------------------------------------------------------
313 * Name: PdmMainWinOkCB
317 * Callback for the main window OK button. This function first calls
318 * the verify values method for each of the child setup boxes. If the
319 * values for all of the children are Ok, the new values are set into
320 * the print context, and the program exits. Otherwise the program
321 * resumes. In this case, it is assumed that the child setup box will
322 * present a message to the user indicating that its values are not
323 * Ok. This function will move the invalid child setup notebook page
328 * None, although it usually ends the program with an exit code of
335 XtPointer client_data,
338 PdmMainWin* me = (PdmMainWin*)client_data;
342 * call the verify values proc for each setup box child
344 for(node = me->box_list_head, page = 1;
345 node != (PdmBoxNode*)NULL;
346 node = node->next, page++)
348 PdmSetupBox* box = node->box;
350 if((*box->verify_attr_proc)(box, me->pdm_xp) != PDM_SUCCESS)
353 * Ensure this setup box is the top notebook page; the setup
354 * box is responsible for providing error messages to the
357 * developer hint: do not use the setup box as the parent of
358 * a message box; if the setup box is not the
359 * current notebook page, the message box
360 * will not be positioned properly; use the
361 * first shell ancestor (or even the parent)
362 * of the setup box instead
364 XtVaSetValues(me->notebook, XmNcurrentPageNumber, page, NULL);
366 * stop verifying and return
372 * call the set attributes proc for each setup box child
374 for(node = me->box_list_head; node != (PdmBoxNode*)NULL; node = node->next)
376 PdmSetupBox* box = node->box;
378 (*box->set_attr_proc)(box, me->pdm_xp);
381 * set the updated attributes into the print context
383 PdmXpUpdateAttributes(me->pdm_xp);
387 PdmMainWinDelete(me);
392 * ------------------------------------------------------------------------
393 * Name: PdmMainWinCancelCB
397 * Callback for the main window Cancel button. This function simply
398 * ends the PDM program.
402 * None, although it will end the program with an exit code of
409 XtPointer client_data,
412 PdmMainWin* me = (PdmMainWin*)client_data;
413 PdmMainWinDelete(me);
414 exit(PDM_EXIT_CANCEL);
418 * ------------------------------------------------------------------------
419 * Name: PdmMainWinHelpCB
429 PdmMainWinHelpCB(Widget w, XtPointer client_data, XtPointer call_data)
431 PdmMainWin* me = (PdmMainWin*)client_data;
433 struct _box_resources
439 * create the help dialog if needed
441 if((Widget)NULL == me->help_dialog)
444 DtCreateHelpDialog(XtParent(me->widget), "HelpDialog", NULL, 0);
445 XtAddCallback(me->help_dialog, XmNdestroyCallback,
446 PdmMainWinHelpDestroyCB, (XtPointer)me);
449 * determine the current setup box
452 XtArgVal current_page;
456 XtVaGetValues(me->notebook, XmNcurrentPageNumber, ¤t_page, NULL);
457 node = me->box_list_head;
458 for(i = 1; i < (int)current_page; i++)
463 * the help volume name and location id are obtained up as application
464 * resources qualified for each setup box
467 XtResource resources[2];
469 * initialize res struct for help volume
471 resources[0].resource_name = DtNhelpVolume;
472 resources[0].resource_class = DtCHelpVolume;
473 resources[0].resource_type = XmRString;
474 resources[0].resource_size = sizeof(String);
475 resources[0].resource_offset =
476 XtOffsetOf(struct _box_resources, help_volume);
477 resources[0].default_type = XmRImmediate;
478 resources[0].default_addr = (XtPointer)NULL;
480 * initialize res struct for location id
482 resources[1].resource_name = DtNlocationId;
483 resources[1].resource_class = DtCLocationId;
484 resources[1].resource_type = XmRString;
485 resources[1].resource_size = sizeof(String);
486 resources[1].resource_offset =
487 XtOffsetOf(struct _box_resources, location_id);
488 resources[1].default_type = XmRImmediate;
489 resources[1].default_addr = (XtPointer)NULL;
491 * get the resource values for the current setup box widget
493 XtGetApplicationResources(box->widget, (XtPointer)&box_resources,
494 resources, XtNumber(resources),
498 * set the help volume and location
500 XtVaSetValues(me->help_dialog,
501 DtNhelpVolume, box_resources.help_volume,
502 DtNlocationId, box_resources.location_id,
503 DtNhelpType, DtHELP_TYPE_TOPIC,
506 * pop up the help dialog
508 XtManageChild(me->help_dialog);
512 * ------------------------------------------------------------------------
513 * Name: PdmMainWinHelpCB
517 * Update the main window instance structure to reflect destruction
518 * of the help dialog.
525 PdmMainWinHelpDestroyCB(Widget w, XtPointer client_data, XtPointer call_data)
527 PdmMainWin* me = (PdmMainWin*)client_data;
528 me->help_dialog = (Widget)NULL;
532 * ------------------------------------------------------------------------
533 * Name: PdmMainWinCreate
537 * Creates the PDM main window, including setup box children added
538 * via PdmMainWinAddSetupBox.
542 * The passed PdmMainWin pointer.
546 PdmMainWinCreate(PdmMainWin* me,
548 String print_display_spec,
549 String print_context_str)
552 * establish the print server connection
554 if(PdmXpOpen(me->pdm_xp, print_display_spec, print_context_str)
558 * unable to open the print display
560 PdmMainWinDelete(me);
561 exit(PDM_EXIT_PXAUTH);
564 * make a copy of the print display spec
566 me->print_display_spec = XtNewString(print_display_spec);
568 * get attributes for the main window and the setup box children
570 PdmMainWinGetAttributes(me);
572 * create the main window
574 PdmMainWinCreateWindow(me, parent);
576 * add the registered setup boxes to the notebook
578 PdmMainWinCreateSetupBoxes(me);
586 * ------------------------------------------------------------------------
587 * Name: PdmMainWinCreateWindow
591 * Creates the PDM main window, including setup box children added
592 * via PdmMainWinAddSetupBox.
596 * The main window widget ID.
600 PdmMainWinCreateWindow(PdmMainWin* me,
609 * create the main window
612 XtVaCreateManagedWidget("Main",
613 xmMessageBoxWidgetClass,
615 XmNdialogType, XmDIALOG_MESSAGE,
617 XtUnmanageChild(XtNameToWidget(me->widget, "Message"));
618 XtUnmanageChild(XtNameToWidget(me->widget, "Symbol"));
620 * add OK, Cancel and Help pushbutton callbacks
622 XtAddCallback(me->widget, XmNokCallback,
623 PdmMainWinOkCB, (XtPointer)me);
624 XtAddCallback(me->widget, XmNcancelCallback,
625 PdmMainWinCancelCB, (XtPointer)me);
626 XtAddCallback(me->widget, XmNhelpCallback,
627 PdmMainWinHelpCB, (XtPointer)me);
629 * create the main manager widget
631 manager = XtVaCreateManagedWidget("Manager",
632 xmRowColumnWidgetClass,
636 * create the printer description row
638 if(me->printer_descriptor != (const char*)NULL)
643 row = XtVaCreateManagedWidget(
644 "PrinterDescriptionRow",
645 xmRowColumnWidgetClass,
647 XmNorientation, XmHORIZONTAL,
650 * create the printer description label
652 w = XtVaCreateManagedWidget("PrinterDescriptionLabel",
657 * create the printer description using just the 1st line
659 desc = XtNewString(me->printer_descriptor);
660 ptr = Dt_strchr(desc, '\n');
663 label = XmStringCreateLocalized(desc);
665 w = XtVaCreateManagedWidget("PrinterDescription",
668 XmNlabelString, label,
673 * create the printer name row
675 if(me->printer_name != (const char*)NULL)
678 int printer_spec_len;
680 row = XtVaCreateManagedWidget(
682 xmRowColumnWidgetClass,
684 XmNorientation, XmHORIZONTAL,
687 * create the printer name label
689 w = XtVaCreateManagedWidget("PrinterNameLabel",
694 * build the X printer specifier
696 printer_spec_len = strlen(me->printer_name);
697 if(me->print_display_spec != (char*)NULL)
698 printer_spec_len += strlen(me->print_display_spec) + 1;
699 printer_spec = XtMalloc(printer_spec_len + 1);
700 strcpy(printer_spec, me->printer_name);
701 if(me->print_display_spec != (char*)NULL)
703 strcat(printer_spec, "@");
704 strcat(printer_spec, me->print_display_spec);
707 * create the printer name
709 label = XmStringCreateLocalized(printer_spec);
710 XtFree(printer_spec);
711 w = XtVaCreateManagedWidget("PrinterName",
714 XmNlabelString, label,
721 w = XtVaCreateManagedWidget("TopSeparator",
722 xmSeparatorGadgetClass,
728 row = XtVaCreateManagedWidget(
730 xmRowColumnWidgetClass,
732 XmNorientation, XmHORIZONTAL,
734 w = XtVaCreateManagedWidget("NotebookLabel",
739 * create the notebook
741 row = XtVaCreateManagedWidget(
743 xmRowColumnWidgetClass,
745 XmNorientation, XmHORIZONTAL,
748 XtVaCreateManagedWidget(
750 xmNotebookWidgetClass,
754 * Create an unmanaged notebook page scroller (i.e. a widget that has
755 * the XmQTnavigator trait), otherwise the notebook widget will
756 * create a default page scroller when it is realized. If this
757 * default page scroller is unmanaged after realization, the parent
758 * manager of the notebook does not shrink in order to reclaim the
759 * space previously occupied by the page scroller.
761 XtVaCreateWidget("DummyPageScroller",
762 xmScrollBarWidgetClass,