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 libraries 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: PsubDefProc.c /main/14 1996/12/02 10:51:20 rswiston $ */
25 * DtPrint/PsubDefProc.c
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 * ------------------------------------------------------------------------
47 #include <Dt/HelpDialog.h>
48 #include <Dt/DtNlUtils.h>
49 #include <Dt/HourGlass.h>
52 * PrintSetupBP.h is included only for access to the DtPrintDefProcData
53 * member of the widget instance structure.
55 #include <Dt/PrintSetupBP.h>
57 #include <Dt/PsubUtilI.h>
60 * ------------------------------------------------------------------------
61 * Constant Definitions
64 #define HELP_VOLUME "LibDtPrint"
65 #define PRINTER_INFO_HELP_ID "PrinterInfo"
66 #define SELECT_PRINTER_HELP_ID "SelectPrinter"
67 #define SELECT_FILE_HELP_ID "SelectFile"
70 * ------------------------------------------------------------------------
71 * Static Function Declarations
74 static XtEnum BuildPrinterLists(
76 DtPrintDefaultProcData* dpd,
78 static XmStringTable BuildPrinterSelectionItems(
80 DtPrintDefaultProcData* dpd,
82 String initial_printer,
84 static void CloseSelectPrinterInfoConnection(
85 DtPrintDefaultProcData* dpd);
86 static int CompareSelectPrinterRecs(const void*,
88 static String CompoundTextToString(
90 unsigned char* compound_text);
91 static XtEnum CreateFileSelectionBox(
94 DtPrintDefaultProcData* dpd);
95 static XtEnum CreatePrinterInfoBox(
98 DtPrintDefaultProcData* dpd);
99 static XtEnum CreatePrinterSelectionBox(
102 DtPrintDefaultProcData* dpd);
103 static void DestroyWidgetCB(
105 XtPointer client_data,
106 XtPointer call_data);
107 static void DtPrintDefProcDestroyCB(Widget w,
108 XtPointer client_data,
109 XtPointer call_data);
110 static void ErrorMessageDestroyCB(
112 XtPointer client_data,
113 XtPointer call_data);
114 static String FindSelectedPrinter(
116 DtPrintDefaultProcData* dpd);
117 static void FreeSelectPrinterData(
118 DtPrintDefaultProcData* dpd);
119 static Widget GetWMShellAncestor(
121 static void HelpDialogDestroyCB(
123 XtPointer client_data,
124 XtPointer call_data);
125 static void InfoBoxLayoutCB(
127 XtPointer client_data,
128 XtPointer call_data);
129 static void ParseFileNameSpec(
130 const char* file_name,
133 static void PresentErrorDialog(
138 static void PresentHelp(
140 const char* help_volume,
141 const char* location_id);
142 static void PresentVerifyError(
145 String printer_spec);
146 static void PrinterInfoDestroyCB(
148 XtPointer client_data,
149 XtPointer call_data);
150 static void PrinterInfoHelpCB(
152 XtPointer client_data,
153 XtPointer call_data);
154 static void SelectFileDestroyCB(
156 XtPointer client_data,
157 XtPointer call_data);
158 static void SelectFileHelpCB(
160 XtPointer client_data,
161 XtPointer call_data);
162 static void SelectPrinterCB(
164 XtPointer client_data,
165 XtPointer call_data);
166 static void SelectPrinterDestroyCB(
168 XtPointer client_data,
169 XtPointer call_data);
170 static void SelectPrinterHelpCB(
172 XtPointer client_data,
173 XtPointer call_data);
174 static void SelectPrinterInfoCB(
176 XtPointer client_data,
177 XtPointer call_data);
178 static void SelectPrinterItemCB(
180 XtPointer client_data,
181 XtPointer call_data);
182 static void SetListBoxSelection(
185 static void UpdateFileNameCB(
187 XtPointer client_data,
188 XtPointer call_data);
191 * ------------------------------------------------------------------------
192 * Name: BuildPrinterLists
196 * Retrieves lists of printers from the Xp server found in the
197 * XpServerList resource or XPSERVERLIST env var.
207 DtPrintDefaultProcData* dpd,
216 #if 0 && defined(PRINTING_SUPPORTED)
217 XPPrinterList xp_printer_list;
218 #endif /* PRINTING_SUPPORTED */
219 DtPrintSelectPrinterList printer_list;
221 * clean up previous lists if needed
223 FreeSelectPrinterData(dpd);
225 * get the list of servers
227 server_list = _DtPrintGetXpServerList(w);
228 if((String*)NULL == server_list)
229 return DtPRINT_FAILURE;
231 * get the printer list for each valid Xp server
233 for(server_count = 0;
234 (String)NULL != server_list[server_count];
236 dpd->xp_server_list =
237 (String*)XtCalloc(server_count, sizeof(String));
238 dpd->printer_lists = (DtPrintSelectPrinterList*)
239 XtCalloc(server_count, sizeof(DtPrintSelectPrinterList));
240 dpd->printer_counts =
241 (int*)XtCalloc(server_count, sizeof(int));
242 for(i = 0, *item_count = 0; i < server_count; i++)
245 * ensure the server is a valid Xp server
247 display = XOpenDisplay(server_list[i]);
248 if((Display*)NULL == display)
250 #if 0 && defined(PRINTING_SUPPORTED)
251 if(!XpQueryExtension(display, &event_base, &error_base))
253 #endif /* PRINTING_SUPPORTED */
254 XCloseDisplay(display);
256 #if 0 && defined(PRINTING_SUPPORTED)
258 #endif /* PRINTING_SUPPORTED */
260 * add the server to the xp server list
262 dpd->xp_server_list[dpd->xp_server_count] =
263 XtNewString(server_list[i]);
265 * get the printer list for the server
267 #if 0 && defined(PRINTING_SUPPORTED)
269 XpGetPrinterList(display, (char*)NULL,
270 &dpd->printer_counts[dpd->xp_server_count]);
271 #endif /* PRINTING_SUPPORTED */
273 * save a copy of the compound text printer name and
274 * string versions of the name and description for
275 * eventual use in the printer selection list.
277 dpd->printer_lists[dpd->xp_server_count] = (DtPrintSelectPrinterList)
278 XtCalloc(dpd->printer_counts[dpd->xp_server_count],
279 sizeof(DtPrintSelectPrinterRec));
280 printer_list = dpd->printer_lists[dpd->xp_server_count];
281 #if 0 && defined(PRINTING_SUPPORTED)
282 for(j = 0; j < dpd->printer_counts[dpd->xp_server_count]; j++)
284 printer_list[j].printer_name_ct =
285 XtNewString(xp_printer_list[j].name);
286 printer_list[j].printer_name =
287 CompoundTextToString(display,
288 (unsigned char*)xp_printer_list[j].name);
289 printer_list[j].description =
290 CompoundTextToString(display,
291 (unsigned char*)xp_printer_list[j].desc);
293 XpFreePrinterList(xp_printer_list);
294 #endif /* PRINTING_SUPPORTED */
296 * sort the printer list
298 if(0 < dpd->printer_counts[dpd->xp_server_count])
299 qsort((void*)printer_list,
300 dpd->printer_counts[dpd->xp_server_count],
301 sizeof(DtPrintSelectPrinterRec), CompareSelectPrinterRecs);
303 *item_count += dpd->printer_counts[dpd->xp_server_count];
304 ++dpd->xp_server_count;
305 XCloseDisplay(display);
307 _DtPrintFreeStringList(server_list);
310 FreeSelectPrinterData(dpd);
311 return DtPRINT_FAILURE;
314 return DtPRINT_SUCCESS;
318 * ------------------------------------------------------------------------
319 * Name: BuildPrinterSelectionItems
323 * Builds the list of XmString items (printer name + desc) to be set
324 * in the printer selection list box.
332 BuildPrinterSelectionItems(
334 DtPrintDefaultProcData* dpd,
336 String initial_printer,
341 char* buf = (char*)NULL;
342 Cardinal buf_size = 0;
345 String name, full_name, desc;
349 items = (XmStringTable)XtCalloc(item_count, sizeof(XmString));
350 for(i = 0, current_item = 0; i < dpd->xp_server_count; i++)
352 server_name = dpd->xp_server_list[i];
353 server_len = strlen(server_name);
355 for(j = 0; j < dpd->printer_counts[i]; j++, current_item++)
358 * build a fully qualified X printer specifier
360 name = (dpd->printer_lists[i])[j].printer_name;
361 (dpd->printer_lists[i])[j].printer_name = (String)NULL;
363 _DtPrintCreateXPrinterSpecifier(name, server_name,
364 DtPRINT_NET_UNSPECIFIED,
368 * check to see if this should be the initially selected printer
370 if(dpd->selected_printer == 0
371 && (String)NULL != initial_printer)
372 if(strcmp(initial_printer, full_name) == 0)
373 dpd->selected_printer = current_item + 1;
375 * convert the printer description
377 desc = (dpd->printer_lists[i])[j].description;
378 (dpd->printer_lists[i])[j].description = (String)NULL;
379 if((String)NULL != desc && '\0' != *desc)
382 * chop the description after the 1st line
384 char* ptr = Dt_strchr(desc, '\n');
385 if((char*)NULL != ptr)
389 * ensure the format buffer is large enough to contain
390 * the formatted list item
393 new_size += full_name ? strlen(full_name) : 0;
394 new_size += desc ? strlen(desc) : 0;
395 if(new_size > buf_size)
398 buf = XtRealloc(buf, buf_size);
401 * format the item, and add it to the item list
403 sprintf(buf, "%s\t%s",
404 full_name ? full_name : "",
408 items[current_item] =
409 XmStringGenerate((XtPointer)buf, (XmStringTag)NULL,
410 XmMULTIBYTE_TEXT, tag);
418 * ------------------------------------------------------------------------
419 * Name: CloseSelectPrinterInfoConnection
423 * Close the X printer connection maintained for the Select Printer
424 * dialog's Printer Information dialog.
432 CloseSelectPrinterInfoConnection(
433 DtPrintDefaultProcData* dpd)
435 if((Display*)NULL != dpd->select_printer_info_display)
437 #if 0 && defined(PRINTING_SUPPORTED)
438 if((XPContext)None != dpd->select_printer_info_context)
440 XpDestroyContext(dpd->select_printer_info_display,
441 dpd->select_printer_info_context);
442 dpd->select_printer_info_context = (XPContext)None;
444 #endif /* PRINTING_SUPPORTED */
445 XCloseDisplay(dpd->select_printer_info_display);
446 dpd->select_printer_info_display = (Display*)NULL;
451 * ------------------------------------------------------------------------
452 * Name: CompareSelectPrinterRecs
456 * Compares the printer names in two DtPrintSelectPrinterRecs.
460 * Returns an integer greater than, equal to, or less than zero,
461 * according to whether the printer name in spr1 is greater
462 * than, equal to, or less than the printer name in spr2.
466 CompareSelectPrinterRecs(const void* spr1,
469 return strcoll(((DtPrintSelectPrinterRec*)spr1)->printer_name,
470 ((DtPrintSelectPrinterRec*)spr2)->printer_name);
474 * ------------------------------------------------------------------------
475 * Name: CompoundTextToString
487 CompoundTextToString(
489 unsigned char* compound_text)
491 String str = (String)NULL;
493 if((unsigned char*)NULL != compound_text)
495 XTextProperty text_prop;
499 text_prop.encoding = XInternAtom(display, "COMPOUND_TEXT", False);
500 text_prop.format = 8;
501 text_prop.value = compound_text;
502 text_prop.nitems = strlen((char*)text_prop.value);
504 XmbTextPropertyToTextList(display, &text_prop, &list, &count))
507 str = XtNewString(list[0]);
508 XFreeStringList(list);
515 * ------------------------------------------------------------------------
516 * Name: CreateFileSelectionBox
520 * Creates the file selection dialog box.
528 CreateFileSelectionBox(
531 DtPrintDefaultProcData* dpd)
535 XmString title_xmstr;
537 title_xmstr = XmStringCreateLocalized(SELECT_FILE_TITLE);
543 XtSetArg(args[n], XmNdialogTitle, title_xmstr); n++;
544 XtSetArg(args[n], XmNdialogStyle,
545 XmDIALOG_PRIMARY_APPLICATION_MODAL); n++;
546 XtSetArg(args[n], XmNdeleteResponse, XmUNMAP); n++;
548 * file selection box resources
550 XtSetArg(args[n], XmNautoUnmanage, True); n++;
552 * create the file selection box dialog
554 dpd->file_selection_box =
555 XmCreateFileSelectionDialog(parent, "_PsubDefProcFileSelectionBox",
557 XmStringFree(title_xmstr);
558 if(dpd->file_selection_box == (Widget)NULL)
559 return DtPRINT_FAILURE;
563 XtAddCallback(dpd->file_selection_box, XmNokCallback,
564 UpdateFileNameCB, (XtPointer)psub);
565 XtAddCallback(dpd->file_selection_box, XmNhelpCallback,
566 SelectFileHelpCB, (XtPointer)psub);
567 XtAddCallback(dpd->file_selection_box, XmNdestroyCallback,
568 SelectFileDestroyCB, (XtPointer)psub);
572 return DtPRINT_SUCCESS;
576 * ------------------------------------------------------------------------
577 * Name: CreatePrinterInfoBox
581 * Creates the printer information dialog box.
589 CreatePrinterInfoBox(
592 DtPrintDefaultProcData* dpd)
596 XmString title_xmstr;
598 Widget description_label, description;
599 Widget name_label, name;
600 Widget format_label, format;
601 Widget model_label, model;
604 title_xmstr = XmStringCreateLocalized(PRINTER_INFO_TITLE);
610 XtSetArg(args[n], XmNdialogTitle, title_xmstr); n++;
611 XtSetArg(args[n], XmNdialogStyle,
612 XmDIALOG_PRIMARY_APPLICATION_MODAL); n++;
613 XtSetArg(args[n], XmNdeleteResponse, XmUNMAP); n++;
615 * printer info box resources
617 XtSetArg(args[n], XmNautoUnmanage, True); n++;
621 dpd->printer_info_box =
622 XmCreateInformationDialog(parent, "_PsubDefProcPrinterInfoBox",
624 XmStringFree(title_xmstr);
625 if(dpd->printer_info_box == (Widget)NULL)
626 return DtPRINT_FAILURE;
630 XtAddCallback(dpd->printer_info_box, XmNhelpCallback,
631 PrinterInfoHelpCB, (XtPointer)psub);
632 XtAddCallback(dpd->printer_info_box, XmNdestroyCallback,
633 PrinterInfoDestroyCB, (XtPointer)psub);
634 XtAddCallback(dpd->printer_info_box, XmNmapCallback,
635 InfoBoxLayoutCB, (XtPointer)dpd);
637 * unmanage unwanted children
639 XtUnmanageChild(XtNameToWidget(dpd->printer_info_box, "Cancel"));
640 XtUnmanageChild(XtNameToWidget(dpd->printer_info_box, "Message"));
641 XtUnmanageChild(XtNameToWidget(dpd->printer_info_box, "Symbol"));
643 * create the control manager
646 XtVaCreateManagedWidget("PrinterInfoForm", xmFormWidgetClass,
647 dpd->printer_info_box,
648 XmNallowOverlap, False,
651 * printer description
653 label = XmStringCreateLocalized(DESCRIPTION_LABEL);
655 XtVaCreateManagedWidget("DescriptionLabel",
658 XmNlabelString, label,
659 XmNleftAttachment, XmATTACH_FORM,
660 XmNtopAttachment, XmATTACH_FORM,
665 XtVaCreateManagedWidget("Description",
668 XmNalignment, XmALIGNMENT_BEGINNING,
669 XmNleftAttachment, XmATTACH_WIDGET,
670 XmNleftWidget, description_label,
672 XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
673 XmNtopWidget, description_label,
678 label = XmStringCreateLocalized(PRINTER_NAME_LABEL);
680 XtVaCreateManagedWidget("NameLabel",
683 XmNlabelString, label,
684 XmNleftAttachment, XmATTACH_FORM,
685 XmNtopAttachment, XmATTACH_WIDGET,
686 XmNtopWidget, description,
691 XtVaCreateManagedWidget("Name",
694 XmNleftAttachment, XmATTACH_WIDGET,
695 XmNleftWidget, name_label,
697 XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
698 XmNtopWidget, name_label,
703 label = XmStringCreateLocalized(FORMAT_LABEL);
705 XtVaCreateManagedWidget("FormatLabel",
708 XmNlabelString, label,
709 XmNleftAttachment, XmATTACH_FORM,
710 XmNtopAttachment, XmATTACH_WIDGET,
711 XmNtopWidget, name_label,
716 XtVaCreateManagedWidget("Format",
719 XmNleftAttachment, XmATTACH_WIDGET,
720 XmNleftWidget, format_label,
722 XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
723 XmNtopWidget, format_label,
728 label = XmStringCreateLocalized(MODEL_LABEL);
730 XtVaCreateManagedWidget("ModelLabel",
733 XmNlabelString, label,
734 XmNleftAttachment, XmATTACH_FORM,
735 XmNtopAttachment, XmATTACH_WIDGET,
736 XmNtopWidget, format_label,
741 XtVaCreateManagedWidget("Model",
744 XmNalignment, XmALIGNMENT_BEGINNING,
745 XmNleftAttachment, XmATTACH_WIDGET,
746 XmNleftWidget, model_label,
748 XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
749 XmNtopWidget, model_label,
754 return DtPRINT_SUCCESS;
758 * ------------------------------------------------------------------------
759 * Name: CreatePrinterSelectionBox
763 * Creates the printer selection dialog box.
771 CreatePrinterSelectionBox(
774 DtPrintDefaultProcData* dpd)
780 XmString title_xmstr;
783 title_xmstr = XmStringCreateLocalized(MORE_PRINTERS_TITLE);
784 list_label = XmStringCreateLocalized(PRINTER_LIST_LABEL);
785 info_label = XmStringCreateLocalized(PRINTER_INFO_LABEL);
791 XtSetArg(args[n], XmNdialogTitle, title_xmstr); n++;
792 XtSetArg(args[n], XmNdialogStyle,
793 XmDIALOG_PRIMARY_APPLICATION_MODAL); n++;
794 XtSetArg(args[n], XmNdeleteResponse, XmDESTROY); n++;
796 * selection box resources
798 XtSetArg(args[n], XmNautoUnmanage, True); n++;
799 XtSetArg(args[n], XmNlistLabelString, list_label); n++;
800 XtSetArg(args[n], XmNapplyLabelString, info_label); n++;
804 dpd->printer_selection_box =
805 XmCreateSelectionDialog(parent, "_PsubDefProcPrinterSelectionBox",
807 XmStringFree(list_label);
808 XmStringFree(info_label);
809 XmStringFree(title_xmstr);
810 if(dpd->printer_selection_box == (Widget)NULL)
811 return DtPRINT_FAILURE;
815 XtAddCallback(dpd->printer_selection_box, XmNokCallback,
816 SelectPrinterCB, (XtPointer)psub);
817 XtAddCallback(dpd->printer_selection_box, XmNapplyCallback,
818 SelectPrinterInfoCB, (XtPointer)psub);
819 XtAddCallback(dpd->printer_selection_box, XmNcancelCallback,
820 SelectPrinterCB, (XtPointer)psub);
821 XtAddCallback(dpd->printer_selection_box, XmNhelpCallback,
822 SelectPrinterHelpCB, (XtPointer)psub);
823 XtAddCallback(dpd->printer_selection_box, XmNdestroyCallback,
824 SelectPrinterDestroyCB, (XtPointer)psub);
826 * get the list box widget ID
828 dpd->printer_list_box =
829 XtNameToWidget(dpd->printer_selection_box, "*ItemsList");
830 XtAddCallback(dpd->printer_list_box, XmNbrowseSelectionCallback,
831 SelectPrinterItemCB, (XtPointer)psub);
833 * unmanaged unwanted children
835 control = XtNameToWidget(dpd->printer_selection_box, "*Selection");
836 if(control != (Widget)NULL)
837 XtUnmanageChild(control);
838 control = XtNameToWidget(dpd->printer_selection_box, "*Text");
839 if(control != (Widget)NULL)
840 XtUnmanageChild(control);
844 return DtPRINT_SUCCESS;
848 * ------------------------------------------------------------------------
849 * Name: DestroyWidgetCB
853 * Destroys the Widget passed as client_data.
863 XtPointer client_data,
866 XtDestroyWidget((Widget)client_data);
870 * ------------------------------------------------------------------------
871 * Name: DtPrintDefProcDestroyCB
875 * Free resources allocated for the default procedure data structure
876 * in response to the destruction of the DtPrintSetupBox.
878 * Calls destroy callbacks for dialogs *directly* because the dialogs
879 * aren't children of the DtPrintSetupBox, but instead are more like
880 * siblings or cousins of the PrintSetupBox whose common ancestor is
881 * the shell parent of the PrintSetupBox. As such the dialogs may or
882 * may not otherwise be destroyed when the PrintSetupBox is
883 * destroyed. Furthermore the 2nd phase of the XtDestroyWidget calls
884 * made in this routine isn't reached until after the PrintSetupBox
885 * instance record has been destroyed (as part of the destroy phase
886 * of which *this* call is a part).
888 * The main reason this is a concern is because data associated with
889 * these dialogs is stored in the PrintSetupBox widget instance
898 DtPrintDefProcDestroyCB(Widget w,
899 XtPointer client_data,
902 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
904 if(dpd->error_message_box)
906 XtRemoveCallback(dpd->error_message_box, XmNdestroyCallback,
907 ErrorMessageDestroyCB, (XtPointer)w);
908 XtDestroyWidget(dpd->error_message_box);
909 ErrorMessageDestroyCB(dpd->error_message_box,
910 (XtPointer)w, (XtPointer)NULL);
914 XtRemoveCallback(dpd->help_dialog, XmNdestroyCallback,
915 HelpDialogDestroyCB, (XtPointer)w);
916 XtDestroyWidget(dpd->help_dialog);
917 HelpDialogDestroyCB(dpd->help_dialog,
918 (XtPointer)w, (XtPointer)NULL);
920 if(dpd->file_selection_box)
922 XtRemoveCallback(dpd->file_selection_box, XmNdestroyCallback,
923 SelectFileDestroyCB, (XtPointer)w);
924 XtDestroyWidget(dpd->file_selection_box);
925 SelectFileDestroyCB(dpd->file_selection_box,
926 (XtPointer)w, (XtPointer)NULL);
928 if(dpd->printer_selection_box)
930 XtRemoveCallback(dpd->printer_selection_box, XmNdestroyCallback,
931 SelectPrinterDestroyCB, (XtPointer)w);
932 XtDestroyWidget(dpd->printer_selection_box);
933 SelectPrinterDestroyCB(dpd->printer_selection_box,
934 (XtPointer)w, (XtPointer)NULL);
936 if(dpd->printer_info_box)
938 XtRemoveCallback(dpd->printer_info_box, XmNdestroyCallback,
939 PrinterInfoDestroyCB, (XtPointer)w);
940 XtDestroyWidget(dpd->printer_info_box);
941 PrinterInfoDestroyCB(dpd->printer_info_box,
942 (XtPointer)w, (XtPointer)NULL);
948 * ------------------------------------------------------------------------
949 * Name: ErrorMessageDestroyCB
953 * Reset the error message widget ID instance data when the message
956 * This callback is considered part of the default resource
957 * procedures and not part of the setup box widget proper.
965 ErrorMessageDestroyCB(
967 XtPointer client_data,
970 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(client_data);
972 dpd->error_message_box = (Widget)NULL;
976 * ------------------------------------------------------------------------
977 * Name: FindSelectedPrinter
981 * Build a full printer name by locating the currently selected
982 * printer in the server list and printer list.
987 * A newly allocated full printer name. It is the caller's
988 * responsibility to free the returned String by calling XtFree.
994 DtPrintDefaultProcData* dpd)
1001 * return if any of the structures are not in place
1003 if(dpd->xp_server_list == (String*)NULL
1005 dpd->printer_counts == (int*)NULL
1007 dpd->printer_lists == (DtPrintSelectPrinterList*)NULL)
1009 return (String)NULL;
1012 * find the printer list containing the selected printer
1014 if(0 == dpd->selected_printer)
1015 return (String)NULL;
1017 printer_index = dpd->selected_printer - 1;
1019 for(i = 0, printer_count = 0; i < dpd->xp_server_count; i++)
1021 if(printer_index < printer_count + (dpd->printer_counts)[i])
1024 printer_count += (dpd->printer_counts)[i];
1026 if(i < dpd->xp_server_count)
1029 * build and return the printer name
1031 DtPrintSelectPrinterList printer_list;
1032 String printer_spec;
1033 String printer_name;
1034 char* printer_name_ct;
1037 display_spec = (dpd->xp_server_list)[i];
1038 printer_list = (dpd->printer_lists)[i];
1040 printer_list[printer_index - printer_count].printer_name_ct;
1042 CompoundTextToString(display, (unsigned char*)printer_name_ct);
1043 if((String)NULL != printer_name)
1046 _DtPrintCreateXPrinterSpecifier(printer_name,
1048 DtPRINT_NET_UNSPECIFIED,
1050 XtFree(printer_name);
1051 return printer_spec;
1054 return (String)NULL;
1058 * ------------------------------------------------------------------------
1059 * Name: FreeSelectPrinterData
1063 * Deallocate and reset data items associated with the printer
1071 FreeSelectPrinterData(
1072 DtPrintDefaultProcData* dpd)
1075 DtPrintSelectPrinterList printer_list;
1077 for(i = 0; i < dpd->xp_server_count; i++)
1079 printer_list = dpd->printer_lists[i];
1080 for(j = 0; j < dpd->printer_counts[i]; j++)
1082 XtFree(printer_list[j].printer_name_ct);
1084 XtFree((char*)printer_list);
1086 XtFree((char*)dpd->printer_lists);
1087 dpd->printer_lists = (DtPrintSelectPrinterList*)NULL;
1088 XtFree((char*)dpd->xp_server_list);
1089 dpd->xp_server_list = (String*)NULL;
1090 dpd->xp_server_count = 0;
1091 dpd->selected_printer = 0;
1095 * ------------------------------------------------------------------------
1096 * Name: GetWMShellAncestor
1100 * Obtains the widget ID of the closest WMShell ancestor for
1101 * the passed widget.
1105 * The widget ID of the closest WMShell ancestor.
1109 GetWMShellAncestor(Widget w)
1111 Widget wmshell_ancestor = XtParent(w);
1112 while(wmshell_ancestor != (Widget)NULL)
1114 if(XtIsWMShell(wmshell_ancestor))
1117 wmshell_ancestor = XtParent(wmshell_ancestor);
1119 return wmshell_ancestor;
1123 * ------------------------------------------------------------------------
1124 * Name: HelpDialogDestroyCB
1128 * Reset the help dialog widget ID instance data when the widget
1131 * This callback is considered part of the default resource
1132 * procedures and not part of the setup box widget proper.
1140 HelpDialogDestroyCB(
1142 XtPointer client_data,
1143 XtPointer call_data)
1145 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(client_data);
1147 dpd->help_dialog = (Widget)NULL;
1151 * ------------------------------------------------------------------------
1152 * Name: InfoBoxLayoutCB
1156 * Callback to right justify printer information dialog labels at
1168 XtPointer client_data,
1169 XtPointer call_data)
1171 DtPrintDefaultProcData* dpd = (DtPrintDefaultProcData*)client_data;
1174 Dimension width, max_width;
1176 * only need to do this once after the widget is created
1178 XtRemoveCallback(widget, XmNmapCallback, InfoBoxLayoutCB, client_data);
1180 * get the label widget ids
1182 w[0] = XtNameToWidget(dpd->printer_info_box,
1183 "PrinterInfoForm.DescriptionLabel");
1184 w[1] = XtNameToWidget(dpd->printer_info_box,
1185 "PrinterInfoForm.NameLabel");
1186 w[2] = XtNameToWidget(dpd->printer_info_box,
1187 "PrinterInfoForm.FormatLabel");
1188 w[3] = XtNameToWidget(dpd->printer_info_box,
1189 "PrinterInfoForm.ModelLabel");
1191 * find the widest label
1193 for(i = 0, widest = 0, max_width = 0; i < 4; i++)
1195 XtVaGetValues(w[i], XmNwidth, &width, NULL);
1196 if(width > max_width)
1203 * sever the top attachment on the widest label in order to avoid
1204 * circular dependencies in form children; apparently one of the form
1205 * widget's many talents is the inability to manage the vertical and
1206 * horizontal attachments independently...
1208 XtVaSetValues(w[widest], XmNtopAttachment, XmATTACH_SELF, NULL);
1210 * attach the right side of the smaller labels to the right side of
1213 for(i = 0; i < 4; i++)
1216 XmNleftAttachment, XmATTACH_NONE,
1217 XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET,
1218 XmNrightWidget, w[widest],
1223 * ------------------------------------------------------------------------
1224 * Name: ParseFileNameSpec
1228 * Parse the passed file name to create a file selection box filter
1229 * pattern and the name only portion of the full name spec.
1231 * It is the caller's responsibility to free the allocated memory
1232 * returned in 'pattern' and 'name_only' using XmStringFree and
1233 * XtFree respectively.
1242 ParseFileNameSpec(const char* file_name,
1243 XmString* pattern_xmstr,
1249 * start off with a copy of the file name, ensuring there is
1250 * enough space for the added "*" and the string terminator.
1252 pattern = XtMalloc(strlen(file_name)+2);
1253 strcpy(pattern, file_name);
1255 * find the last slash
1257 ptr = DtStrrchr(pattern, '/');
1258 if(ptr != (String)NULL)
1261 * grab the name portion of the file name
1263 *name_only = XtNewString(ptr+1);
1265 * set the wildcard character immediately following the last
1269 *pattern_xmstr = XmStringCreateLocalized(pattern);
1274 * no slash found; use the default pattern
1276 *pattern_xmstr = (XmString)NULL;
1277 *name_only = XtNewString(file_name);
1283 * ------------------------------------------------------------------------
1284 * Name: PresentErrorDialog
1288 * This is a utility function that will present an Error Dialog. It
1289 * takes a title, a message, and a variable list of Strings to
1290 * include in the message. The message parm is treated like a
1291 * printf-style format string, except that only the "%s" directive is
1294 * This function is to be used exclusively by the default
1295 * resource procedures (e.g. _DtPrintSetupBoxVerifyXPrinterProc).
1297 * The variable list of String parms must be terminated by
1314 String expanded_message;
1316 XmString message_xmstr;
1317 XmString title_xmstr;
1320 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
1321 Widget wmshell_ancestor;
1322 WidgetList wmshell_ancestors_children = (WidgetList)NULL;
1324 wmshell_ancestor = GetWMShellAncestor(w);
1326 if (wmshell_ancestor)
1329 XtSetArg(args[n], XmNchildren, &wmshell_ancestors_children); n++;
1330 XtGetValues(wmshell_ancestor, args, n);
1333 if(dpd->error_message_box != (Widget)NULL)
1336 * present only one message box
1338 XtDestroyWidget(dpd->error_message_box);
1341 title_xmstr = XmStringCreateLocalized(title);
1343 * determine length of expanded message
1345 message_len = strlen(message);
1346 va_start(arg_marker, message);
1347 while((str_n = va_arg(arg_marker, String)) != (String)NULL)
1349 message_len += strlen(str_n);
1354 * expand the message
1356 expanded_message = XtMalloc(message_len);
1357 va_start(arg_marker, message);
1358 vsprintf(expanded_message, message, arg_marker);
1361 * convert message to XmString
1363 message_xmstr = XmStringCreateLocalized(expanded_message);
1364 XtFree(expanded_message);
1366 * create the error dialog
1369 XtSetArg(args[n], XmNdialogTitle, title_xmstr); n++;
1370 XtSetArg(args[n], XmNmessageString, message_xmstr); n++;
1371 XtSetArg(args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); n++;
1372 XtSetArg(args[n], XmNdeleteResponse, XmDESTROY); n++;
1373 dpd->error_message_box =
1374 XmCreateErrorDialog(wmshell_ancestors_children ?
1375 wmshell_ancestors_children[0] :
1377 "_PsubDefProcErrorMsg", args, n);
1378 XmStringFree(title_xmstr);
1379 XmStringFree(message_xmstr);
1381 XtUnmanageChild(XtNameToWidget(dpd->error_message_box, "Cancel"));
1382 XtUnmanageChild(XtNameToWidget(dpd->error_message_box, "Help"));
1384 XtAddCallback(dpd->error_message_box, XmNokCallback,
1385 DestroyWidgetCB, (XtPointer)dpd->error_message_box);
1386 XtAddCallback(dpd->error_message_box, XmNcancelCallback,
1387 DestroyWidgetCB, (XtPointer)dpd->error_message_box);
1388 XtAddCallback(dpd->error_message_box, XmNdestroyCallback,
1389 ErrorMessageDestroyCB, (XtPointer)w);
1391 * manage the message box according to the hint
1393 if(DtPRINT_HINT_MESSAGES_OK == dpd->messages_hint)
1394 XtManageChild(dpd->error_message_box);
1396 #ifdef XXX_JUNGLE_REMOVE
1398 * manage the message box only if the psub is mapped
1399 * and the focus is not in the printer name field
1402 XWindowAttributes attr;
1404 Window window = XtWindow(w);
1407 status = XGetWindowAttributes(XtDisplay(w), window, &attr);
1408 if(status == 0 || attr.map_state == IsViewable)
1410 Widget name_w = XtNameToWidget(w, "Name");
1413 for(child = XmGetFocusWidget(w);
1414 child != wmshell_ancestor && child != name_w
1415 && child != (Widget)NULL;
1416 child = XtParent(child));
1418 if(child != name_w && child != (Widget)NULL)
1419 XtManageChild(dpd->error_message_box);
1423 #endif /* XXX_JUNGLE_REMOVE */
1427 * ------------------------------------------------------------------------
1432 * Presents a help dialog whose widget instance may be shared between
1433 * the default dialogs.
1440 static void PresentHelp(
1442 const char* help_volume,
1443 const char* location_id)
1445 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
1446 Widget wmshell_ancestor;
1447 Widget dialog_shell;
1449 wmshell_ancestor = GetWMShellAncestor(w);
1451 if((Widget)NULL == dpd->help_dialog)
1458 title = XmStringCreateLocalized(HELP_DLG_TITLE);
1459 XtSetArg(args[n], XmNdialogTitle, title); n++;
1461 DtCreateHelpDialog(wmshell_ancestor, "_PsubDefProcHelpDialog",
1463 XmStringFree(title);
1464 XtAddCallback(dpd->help_dialog, XmNdestroyCallback,
1465 HelpDialogDestroyCB, (XtPointer)w);
1468 * set the help volume and location
1470 XtVaSetValues(dpd->help_dialog,
1471 DtNhelpVolume, help_volume,
1472 DtNlocationId, location_id,
1473 DtNhelpType, DtHELP_TYPE_TOPIC,
1476 * pop up the help dialog
1478 XtManageChild(dpd->help_dialog);
1479 dialog_shell = XtParent(dpd->help_dialog);
1480 if(None != XtWindow(dialog_shell))
1481 XRaiseWindow(XtDisplay(dialog_shell), XtWindow(dialog_shell));
1485 * ------------------------------------------------------------------------
1486 * Name: PresentVerifyError
1490 * Presents a error dialog appropriate for an error status returned
1491 * by _DtPrintVerifyXPrinter.
1502 String printer_spec)
1504 String printer_name;
1505 String display_spec;
1507 _DtPrintParseXPrinterSpecifier(printer_spec,
1512 case DtPRINT_PRINTER_MISSING:
1513 PresentErrorDialog(w, INVALID_PRINTER_TITLE,
1514 PRINTER_MISSING_MESSAGE,
1519 case DtPRINT_NO_DEFAULT:
1520 PresentErrorDialog(w, INVALID_PRINTER_TITLE,
1525 case DtPRINT_NO_DEFAULT_DISPLAY:
1526 PresentErrorDialog(w, INVALID_PRINTER_TITLE,
1527 NO_DEFAULT_DISPLAY_MESSAGE,
1532 case DtPRINT_NO_PRINTER:
1533 PresentErrorDialog(w, INVALID_PRINTER_TITLE,
1534 INVALID_PRINTER_MESSAGE,
1535 printer_name, display_spec,
1539 case DtPRINT_NOT_XP_DISPLAY:
1540 PresentErrorDialog(w, INVALID_PRINTER_TITLE,
1541 NOT_XP_DISPLAY_MESSAGE,
1546 case DtPRINT_INVALID_DISPLAY:
1547 PresentErrorDialog(w, INVALID_PRINTER_TITLE,
1548 INVALID_DISPLAY_MESSAGE,
1553 XtFree(printer_name);
1554 XtFree(display_spec);
1559 * ------------------------------------------------------------------------
1560 * Name: PrinterInfoDestroyCB
1564 * Reset data items used in conjunction with the
1565 * printer information selection dialog.
1573 PrinterInfoDestroyCB(
1575 XtPointer client_data,
1576 XtPointer call_data)
1578 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(client_data);
1580 dpd->printer_info_box = (Widget)NULL;
1584 * ------------------------------------------------------------------------
1585 * Name: PrinterInfoHelpCB
1589 * Display context sensitive help.
1599 XtPointer client_data,
1600 XtPointer call_data)
1602 PresentHelp((Widget)client_data, HELP_VOLUME, PRINTER_INFO_HELP_ID);
1606 * ------------------------------------------------------------------------
1607 * Name: SelectFileDestroyCB
1611 * Reset data items used in conjunction with the
1612 * file selection dialog.
1620 SelectFileDestroyCB(
1622 XtPointer client_data,
1623 XtPointer call_data)
1625 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(client_data);
1627 dpd->file_selection_box = (Widget)NULL;
1631 * ------------------------------------------------------------------------
1632 * Name: SelectFileHelpCB
1636 * Display context sensitive help.
1646 XtPointer client_data,
1647 XtPointer call_data)
1649 PresentHelp((Widget)client_data, HELP_VOLUME, SELECT_FILE_HELP_ID);
1653 * ------------------------------------------------------------------------
1654 * Name: SelectPrinterCB
1658 * Callback to handle the printer selection box OK and Cancel
1669 XtPointer client_data,
1670 XtPointer call_data)
1672 XmSelectionBoxCallbackStruct* cbs =
1673 (XmSelectionBoxCallbackStruct*)call_data;
1674 Widget psub = (Widget)client_data;
1675 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(psub);
1676 String printer_spec;
1679 * close the info dialog display connection if it's been opened
1681 CloseSelectPrinterInfoConnection(dpd);
1687 * set the selected printer name in the PrintSetupBox
1689 printer_spec = FindSelectedPrinter(XtDisplay(psub), dpd);
1690 if((String)NULL != printer_spec)
1692 XtVaSetValues(psub, DtNprinterName, printer_spec, NULL);
1693 XtFree(printer_spec);
1701 * deallocate and reset the lists
1703 FreeSelectPrinterData(dpd);
1704 if(dpd->printer_list_box != (Widget)NULL)
1705 XmListDeleteAllItems(dpd->printer_list_box);
1711 * ------------------------------------------------------------------------
1712 * Name: SelectPrinterDestroyCB
1716 * Deallocate and reset data items used in conjunction with the
1717 * printer selection dialog.
1725 SelectPrinterDestroyCB(
1727 XtPointer client_data,
1728 XtPointer call_data)
1730 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(client_data);
1732 dpd->printer_selection_box = (Widget)NULL;
1733 dpd->printer_list_box = (Widget)NULL;
1734 CloseSelectPrinterInfoConnection(dpd);
1735 FreeSelectPrinterData(dpd);
1739 * ------------------------------------------------------------------------
1740 * Name: SelectPrinterHelpCB
1744 * Display context sensitive help.
1752 SelectPrinterHelpCB(
1754 XtPointer client_data,
1755 XtPointer call_data)
1757 PresentHelp((Widget)client_data, HELP_VOLUME, SELECT_PRINTER_HELP_ID);
1761 * ------------------------------------------------------------------------
1762 * Name: SelectPrinterInfoCB
1766 * Callback attached to the printer selection box "Info..."
1767 * button. The "Info..." button is intended to behave just like the
1768 * PrintSetupBox "Info..." button, so it is implemented to call the
1769 * procedure set for the PrintSetupBox DtNprinterInfoProc resource.
1770 * As such, this function needs to open a new display connection to
1771 * the print server indicated by the currently selected printer in
1772 * the list. The connection is not closed until a selection is made
1773 * in the list, or the printer selection dialog is dismissed. This is
1774 * because no assumptions about the Printer Info dialog's widget
1775 * hierarchy can be made.
1783 SelectPrinterInfoCB(
1785 XtPointer client_data,
1786 XtPointer call_data)
1788 Widget psub = (Widget)client_data;
1789 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(psub);
1790 DtPrintSetupProc info_proc;
1792 CloseSelectPrinterInfoConnection(dpd);
1793 XtVaGetValues(psub, DtNprinterInfoProc, &info_proc, NULL);
1794 if((DtPrintSetupProc)NULL != info_proc)
1796 String printer_spec;
1798 printer_spec = FindSelectedPrinter(XtDisplay(psub), dpd);
1799 if((String)NULL != printer_spec)
1801 String new_printer_spec; /*
1802 * will always be set to NULL by
1803 * _DtPrintVerifyXPrinter when
1804 * called from within this routine
1809 * open a connection to the X printer
1812 _DtPrintVerifyXPrinter(psub,
1815 &dpd->select_printer_info_display
1816 #if 0 && defined(PRINTING_SUPPORTED)
1817 ,&dpd->select_printer_info_context
1818 #endif /* PRINTING_SUPPORTED */
1820 if(status == DtPRINT_SUCCESS)
1822 DtPrintSetupData psd;
1824 memset(&psd, 0, sizeof(DtPrintSetupData));
1825 psd.printer_name = printer_spec;
1826 psd.print_display = dpd->select_printer_info_display;
1827 #if 0 && defined(PRINTING_SUPPORTED)
1828 psd.print_context = dpd->select_printer_info_context;
1829 #endif /* PRINTING_SUPPORTED */
1830 (*info_proc)(psub, &psd);
1835 * this should only happen if, while a user is viewing
1836 * the printer selection dialog, a server rehash is
1837 * performed that deletes the currently selected printer
1839 PresentVerifyError(w, status, printer_spec);
1841 XtFree(printer_spec);
1847 * ------------------------------------------------------------------------
1848 * Name: SelectPrinterItemCB
1852 * Callback to handle the a selection in the printer selection list
1861 SelectPrinterItemCB(
1863 XtPointer client_data,
1864 XtPointer call_data)
1866 XmListCallbackStruct* cbs =
1867 (XmListCallbackStruct*)call_data;
1868 Widget psub = (Widget)client_data;
1869 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(psub);
1872 if(dpd->selected_printer != cbs->item_position)
1874 dpd->selected_printer = cbs->item_position;
1875 info_button = XtNameToWidget(dpd->printer_selection_box, "*Apply");
1876 if(0 == dpd->selected_printer)
1877 XtSetSensitive(info_button, False);
1879 XtSetSensitive(info_button, True);
1881 * update the default printer info dialog if it is visible
1883 if(dpd->printer_info_box && XtIsManaged(dpd->printer_info_box))
1884 SelectPrinterInfoCB(w, client_data, (XtPointer)NULL);
1889 * ------------------------------------------------------------------------
1890 * Name: SetListBoxSelection
1901 SetListBoxSelection(Widget list_box, int position)
1903 int visible_item_count;
1906 int first_visible_pos;
1908 * Scroll the list, making the item at the indicated position
1909 * visible in the center of the list box, and make
1910 * it the initial selection.
1912 XtVaGetValues(list_box,
1913 XmNitemCount, &item_count,
1914 XmNvisibleItemCount, &visible_item_count,
1917 if(item_count > visible_item_count)
1919 middle_offset = (visible_item_count+1) / 2;
1920 if(position > middle_offset)
1921 if(position > item_count - middle_offset)
1922 first_visible_pos = item_count - visible_item_count +1;
1924 first_visible_pos = position - middle_offset + 1;
1926 first_visible_pos = 1;
1927 XmListSetPos(list_box, first_visible_pos);
1931 XmListSelectPos(list_box, position, True);
1933 XmListDeselectAllItems(list_box);
1937 * ------------------------------------------------------------------------
1938 * Name: UpdateFileNameCB
1942 * Updates the PrintSetupBox fileName resource based on the selection
1943 * make in the file selection box.
1953 XtPointer client_data,
1954 XtPointer call_data)
1957 Widget psub = (Widget)client_data;
1960 * get the file name from the file selection box text field
1962 text_field = XtNameToWidget(w, "Text");
1965 XtVaGetValues(text_field, XmNvalue, &file_name, NULL);
1969 * set the file name in the print setup box
1971 XtVaSetValues(psub, DtNfileName, file_name, NULL);
1973 * free the file name retrieved from the text field
1981 * ------------------------------------------------------------------------
1982 * Name: _DtPrintDefProcInitialize
1993 _DtPrintDefProcInitialize(Widget w)
1995 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
1997 dpd->error_message_box = (Widget)NULL;
1998 dpd->messages_hint = DtPRINT_HINT_MESSAGES_OK;
1999 dpd->help_dialog = (Widget)NULL;
2000 dpd->file_selection_box = (Widget)NULL;
2001 dpd->printer_selection_box = (Widget)NULL;
2002 dpd->printer_list_box = (Widget)NULL;
2003 dpd->xp_server_list = (String*)NULL;
2004 dpd->xp_server_count = 0;
2005 dpd->printer_lists = (DtPrintSelectPrinterList*)NULL;
2006 dpd->selected_printer = 0;
2007 dpd->select_printer_info_display = (Display*)NULL;
2008 #if 0 && defined(PRINTING_SUPPORTED)
2009 dpd->select_printer_info_context = (XPContext)None;
2010 #endif /* PRINTING_SUPPORTED */
2011 dpd->printer_info_box = (Widget)NULL;
2013 XtAddCallback(w, XmNdestroyCallback,
2014 DtPrintDefProcDestroyCB, (XtPointer)NULL);
2018 * ------------------------------------------------------------------------
2019 * Name: _DtPrintDefProcManageErrorBox
2023 * Manage the Error Message Box if it exists.
2030 _DtPrintDefProcManageErrorBox(
2031 DtPrintDefaultProcData* dpd)
2033 if(dpd->error_message_box != (Widget)NULL)
2034 XtManageChild(dpd->error_message_box);
2038 * ------------------------------------------------------------------------
2039 * Name: _DtPrintSetupBoxXPrinterInfoProc
2043 * Default Xp mode function for the DtNprinterInfoProc resource.
2050 _DtPrintSetupBoxXPrinterInfoProc(
2052 DtPrintSetupData* print_data)
2054 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
2055 Widget wmshell_ancestor;
2058 char* attr_value_ct = NULL;
2059 String attr_value = NULL;
2060 XmString empty_label;
2061 Widget name_label_top;
2064 Widget manager = NULL;
2065 Widget dialog_shell;
2067 wmshell_ancestor = GetWMShellAncestor(w);
2068 _DtTurnOnHourGlass(wmshell_ancestor);
2069 empty_label = XmStringCreateLocalized("");
2071 * if needed, create the printer information dialog
2073 if(dpd->printer_info_box == (Widget)NULL)
2075 XtEnum status = CreatePrinterInfoBox(wmshell_ancestor, w, dpd);
2076 if(status != DtPRINT_SUCCESS)
2078 _DtTurnOffHourGlass(wmshell_ancestor);
2081 dialog_shell = XtParent(dpd->printer_info_box);
2086 * hide the widget during re-layout
2088 manager = XtNameToWidget(dpd->printer_info_box, "*PrinterInfoForm");
2089 XtUnmapWidget(dpd->printer_info_box);
2090 dialog_shell = XtParent(dpd->printer_info_box);
2091 XtVaSetValues(dialog_shell, XmNallowShellResize, False, NULL);
2092 XtUnmanageChild(manager);
2097 ctl = XtNameToWidget(dpd->printer_info_box, "*Description");
2098 XtVaSetValues(ctl, XmNlabelString, empty_label, NULL);
2099 #if 0 && defined(PRINTING_SUPPORTED)
2100 attr_value_ct = XpGetOneAttribute(print_data->print_display,
2101 print_data->print_context,
2104 #endif /* PRINTING_SUPPORTED */
2105 if((char*)NULL != attr_value_ct)
2108 CompoundTextToString(XtDisplay(w), (unsigned char*)attr_value_ct);
2109 XFree(attr_value_ct);
2110 if((String)NULL != attr_value)
2112 label = XmStringGenerate((XtPointer)attr_value, (XmStringTag)NULL,
2113 XmMULTIBYTE_TEXT, (XmStringTag)NULL);
2115 XtVaSetValues(ctl, XmNlabelString, label, NULL);
2116 XmStringFree(label);
2120 * set the top attachment for the name label
2122 XtVaGetValues(ctl, XmNy, &y, XmNheight, &height, NULL);
2124 name_label_top = ctl;
2125 ctl = XtNameToWidget(dpd->printer_info_box, "*DescriptionLabel");
2126 XtVaGetValues(ctl, XmNy, &y, XmNheight, &height, NULL);
2127 if(y+height > max_y)
2128 name_label_top = ctl;
2129 ctl = XtNameToWidget(dpd->printer_info_box, "*NameLabel");
2130 XtVaSetValues(ctl, XmNtopWidget, name_label_top, NULL);
2134 ctl = XtNameToWidget(dpd->printer_info_box, "*Name");
2135 label = XmStringCreateLocalized(print_data->printer_name);
2136 XtVaSetValues(ctl, XmNlabelString, label, NULL);
2137 XmStringFree(label);
2141 ctl = XtNameToWidget(dpd->printer_info_box, "*Format");
2142 XtVaSetValues(ctl, XmNlabelString, empty_label, NULL);
2143 #if 0 && defined(PRINTING_SUPPORTED)
2144 attr_value = XpGetOneAttribute(print_data->print_display,
2145 print_data->print_context,
2148 #endif /* PRINTING_SUPPORTED */
2149 if((String)NULL != attr_value)
2152 format_start = strchr(attr_value, '{');
2153 if((char*)NULL != format_start)
2157 format_end = strchr(format_start, '}');
2158 if((char*)NULL != format_end)
2161 label = XmStringCreateLocalized(format_start);
2162 XtVaSetValues(ctl, XmNlabelString, label, NULL);
2163 XmStringFree(label);
2171 ctl = XtNameToWidget(dpd->printer_info_box, "*Model");
2172 XtVaSetValues(ctl, XmNlabelString, empty_label, NULL);
2173 #if 0 && defined(PRINTING_SUPPORTED)
2174 attr_value_ct = XpGetOneAttribute(print_data->print_display,
2175 print_data->print_context,
2178 #endif /* PRINTING_SUPPORTED */
2179 if((char*)NULL != attr_value_ct)
2182 CompoundTextToString(XtDisplay(w), (unsigned char*)attr_value_ct);
2183 XFree(attr_value_ct);
2184 if((String)NULL != attr_value)
2186 label = XmStringGenerate((XtPointer)attr_value, (XmStringTag)NULL,
2187 XmCHARSET_TEXT, (XmStringTag)NULL);
2189 XtVaSetValues(ctl, XmNlabelString, label, NULL);
2190 XmStringFree(label);
2194 * pop up the printer info dialog and return
2196 XmStringFree(empty_label);
2199 XtVaSetValues(dialog_shell, XmNallowShellResize, True, NULL);
2200 XtManageChild(manager);
2201 XtMapWidget(dpd->printer_info_box);
2203 XtManageChild(dpd->printer_info_box);
2204 if(None != XtWindow(dialog_shell))
2205 XRaiseWindow(XtDisplay(dialog_shell), XtWindow(dialog_shell));
2206 _DtTurnOffHourGlass(wmshell_ancestor);
2207 return DtPRINT_SUCCESS;
2211 * ------------------------------------------------------------------------
2212 * Name: _DtPrintSetupBoxSelectFileProc
2216 * Default function for the DtNselectFileProc resource.
2223 _DtPrintSetupBoxSelectFileProc(
2225 DtPrintSetupData* print_data)
2227 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
2233 Widget wmshell_ancestor;
2235 wmshell_ancestor = GetWMShellAncestor(w);
2236 _DtTurnOnHourGlass(wmshell_ancestor);
2238 * if needed, create the file selection dialog
2240 if(dpd->file_selection_box == (Widget)NULL)
2242 XtEnum status = CreateFileSelectionBox(wmshell_ancestor, w, dpd);
2243 if(status != DtPRINT_SUCCESS)
2245 _DtTurnOffHourGlass(wmshell_ancestor);
2250 * get the file name passed from the PrintSetupBox
2252 file_name = print_data->dest_info;
2254 * parse the file name to create the filter pattern and the name only
2255 * portion of the full name spec
2257 ParseFileNameSpec(file_name, &pattern, &name_only);
2259 * set the filter pattern in the file selection box
2261 XtVaSetValues(dpd->file_selection_box, XmNpattern, pattern, NULL);
2262 if(pattern != (XmString)NULL)
2263 XmStringFree(pattern);
2265 * select the current file name in the file names list
2267 file_list = XtNameToWidget(dpd->file_selection_box, "*ItemsList");
2268 if(file_list != (Widget)NULL)
2270 XmString file_name_xmstr;
2273 text_field = XtNameToWidget(dpd->file_selection_box, "Text");
2274 if(text_field != (Widget)NULL)
2278 * recreate the file name from the name_only and the current
2279 * dir spec as determined by the file selection box
2281 * Note: the char* value retrieved directly from the text
2282 * field is used, because forming the file name from a
2283 * concatenation of XmStrings causes XmListItemPos to fail
2284 * even though the file name is actually in the list.
2286 XtVaGetValues(text_field, XmNvalue, &dir_spec, NULL);
2287 file_name = XtMalloc(strlen(dir_spec)+strlen(name_only)+1);
2288 strcpy(file_name, dir_spec);
2289 strcat(file_name, name_only);
2290 file_name_xmstr = XmStringCreateLocalized(file_name);
2295 file_name_xmstr = XmStringCreateLocalized(file_name);
2297 * find the position of the file name in the list
2299 position = XmListItemPos(file_list, file_name_xmstr);
2300 SetListBoxSelection(file_list, position);
2304 * The file name is not in the list. Manually set in the
2305 * "Selection" text field.
2307 XtVaSetValues(dpd->file_selection_box,
2308 XmNdirSpec, file_name_xmstr,
2311 XmStringFree(file_name_xmstr);
2315 * pop up the file selection dialog and return
2317 XtManageChild(dpd->file_selection_box);
2318 _DtTurnOffHourGlass(wmshell_ancestor);
2319 return DtPRINT_SUCCESS;
2323 * ------------------------------------------------------------------------
2324 * Name: _DtPrintSetupBoxSelectXPrinterProc
2328 * Default Xp mode function for the DtNselectPrinterProc resource.
2335 _DtPrintSetupBoxSelectXPrinterProc(
2337 DtPrintSetupData* print_data)
2339 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
2340 Widget wmshell_ancestor;
2341 XmStringTable items;
2345 XmRenderTable render_table, new_render_table;
2348 XmRendition rendition;
2352 wmshell_ancestor = GetWMShellAncestor(w);
2353 _DtTurnOnHourGlass(wmshell_ancestor);
2355 * build the list of servers and printers
2357 if(DtPRINT_SUCCESS != BuildPrinterLists(w, dpd, &item_count))
2359 PresentErrorDialog(w, PRLIST_ERROR_TITLE,
2360 NO_PRINTERS_MESSAGE,
2362 _DtTurnOffHourGlass(wmshell_ancestor);
2363 return DtPRINT_FAILURE;
2366 * create the dialog if it doesn't exist
2368 if(dpd->printer_selection_box == (Widget)NULL)
2370 XtEnum status = CreatePrinterSelectionBox(wmshell_ancestor, w, dpd);
2371 if(status != DtPRINT_SUCCESS)
2373 _DtTurnOffHourGlass(wmshell_ancestor);
2378 * get a copy of the list widget's render table
2380 XtVaGetValues(dpd->printer_list_box,
2381 XmNrenderTable, &render_table,
2383 render_table = XmRenderTableCopy(render_table, (XmStringTag*)NULL, 0);
2385 * build the item list for the list box
2387 count = XmRenderTableGetTags(render_table, &tags);
2388 items = BuildPrinterSelectionItems(XtDisplay(w), dpd, item_count,
2389 print_data->printer_name, tags[0]);
2391 * generate a tab list for the items
2393 tab_list = XmStringTableProposeTablist(items, item_count,
2394 dpd->printer_list_box,
2397 * get a copy of the first rendition in the render table
2399 rendition = XmRenderTableGetRendition(render_table, tags[0]);
2400 for(i = 0; i < count; i++)
2402 XtFree((char*)tags);
2404 * update the copy with the new tab list
2407 XtSetArg(args[n], XmNtabList, tab_list); n++;
2408 XmRenditionUpdate(rendition, args, n);
2409 XmTabListFree(tab_list);
2411 * create a new render table replacing the first entry with the
2414 new_render_table = XmRenderTableAddRenditions(render_table, &rendition,
2415 1, XmMERGE_REPLACE);
2416 XmRenditionFree(rendition);
2418 * set the new render table and list items in the list box
2420 XtVaSetValues(dpd->printer_list_box,
2421 XmNrenderTable, new_render_table,
2423 XmNitemCount, item_count,
2425 XmRenderTableFree(new_render_table);
2426 for(i = 0; i < item_count; i++)
2427 XmStringFree(items[i]);
2428 XtFree((char*)items);
2429 SetListBoxSelection(dpd->printer_list_box, dpd->selected_printer);
2431 * disable the info button if nothing is selected
2433 if(0 == dpd->selected_printer)
2434 XtSetSensitive(XtNameToWidget(dpd->printer_selection_box, "*Apply"),
2437 * manage the dialog and return
2439 XtManageChild(dpd->printer_selection_box);
2440 _DtTurnOffHourGlass(wmshell_ancestor);
2441 return DtPRINT_SUCCESS;
2445 * ------------------------------------------------------------------------
2446 * Name: _DtPrintSetupBoxVerifyXPrinterProc
2450 * Default function for the DtNverifyPrinterProc resource when the
2453 * (this rest of this description outlines the responsibilities of a
2454 * DtNverifyPrinterProc in general)
2456 * This function verifies the printer name passed in the
2457 * PrintSetupData structure.
2459 * If needed, the DtNprintSetupMode resource may be obtained via a
2460 * GetValues call in order to determine the current setup mode.
2462 * It is the responsibility of this proc to return a valid print
2463 * Display handle and print context by setting the print_display and
2464 * print_context in the PrintSetupData. Conceptually, this is a
2465 * side-effect of this proc, but since it will be necessary to open a
2466 * display connection in order to properly verify the X printer,
2467 * there's no point in doing it twice.
2469 * If the passed printer name is incomplete, this proc may attempt to
2470 * determine a default or fully-qualified name (e.g. fill in a
2471 * missing display spec for an X Printer Specifier). The new default
2472 * or fully-qualified printer name should be set in the PrintSetupBox
2473 * by updating the DtNprinterName resource via a SetValues call. If a
2474 * fully-qualified name cannot be determined, this proc simply
2475 * returns DtPRINT_FAILURE.
2477 * If the printer cannot be verified, it is the responsibiliy of this
2478 * function to present an appropriate message to the user.
2483 * if the printer name has been successfully verified.
2486 * if the printer name is invalid.
2491 _DtPrintSetupBoxVerifyXPrinterProc(
2493 DtPrintSetupData* psd)
2495 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
2497 String new_printer_spec;
2498 Display* new_display;
2499 #if 0 && defined(PRINTING_SUPPORTED)
2500 XPContext new_context;
2501 #endif /* PRINTING_SUPPORTED */
2502 Widget wmshell_ancestor;
2504 wmshell_ancestor = GetWMShellAncestor(w);
2505 _DtTurnOnHourGlass(wmshell_ancestor);
2507 * verify the printer
2509 status = _DtPrintVerifyXPrinter(w,
2513 #if 0 && defined(PRINTING_SUPPORTED)
2515 #endif /* PRINTING_SUPPORTED */
2517 if(status == DtPRINT_SUCCESS)
2520 * update the passed print setup data with the new display and
2523 psd->print_display = new_display;
2524 #if 0 && defined(PRINTING_SUPPORTED)
2525 psd->print_context = new_context;
2526 #endif /* PRINTING_SUPPORTED */
2531 * unable to open the printer; present a message to the user
2532 * according to the hint set in the setup data
2534 dpd->messages_hint = psd->messages_hint;
2535 PresentVerifyError(w, status,
2537 ? new_printer_spec : psd->printer_name);
2539 * reset the hint since the error dialog is also used
2540 * by the other default procs
2542 dpd->messages_hint = DtPRINT_HINT_MESSAGES_OK;
2544 * this function only indicates success or failure
2546 status = DtPRINT_FAILURE;
2548 if(new_printer_spec)
2551 * set the new printer spec, even if the verify failed
2554 DtNprinterName, new_printer_spec,
2556 XtFree(new_printer_spec);
2561 _DtTurnOffHourGlass(wmshell_ancestor);