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: 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 XPPrinterList xp_printer_list;
217 DtPrintSelectPrinterList printer_list;
219 * clean up previous lists if needed
221 FreeSelectPrinterData(dpd);
223 * get the list of servers
225 server_list = _DtPrintGetXpServerList(w);
226 if((String*)NULL == server_list)
227 return DtPRINT_FAILURE;
229 * get the printer list for each valid Xp server
231 for(server_count = 0;
232 (String)NULL != server_list[server_count];
234 dpd->xp_server_list =
235 (String*)XtCalloc(server_count, sizeof(String));
236 dpd->printer_lists = (DtPrintSelectPrinterList*)
237 XtCalloc(server_count, sizeof(DtPrintSelectPrinterList));
238 dpd->printer_counts =
239 (int*)XtCalloc(server_count, sizeof(int));
240 for(i = 0, *item_count = 0; i < server_count; i++)
243 * ensure the server is a valid Xp server
245 display = XOpenDisplay(server_list[i]);
246 if((Display*)NULL == display)
248 if(!XpQueryExtension(display, &event_base, &error_base))
250 XCloseDisplay(display);
254 * add the server to the xp server list
256 dpd->xp_server_list[dpd->xp_server_count] =
257 XtNewString(server_list[i]);
259 * get the printer list for the server
262 XpGetPrinterList(display, (char*)NULL,
263 &dpd->printer_counts[dpd->xp_server_count]);
265 * save a copy of the compound text printer name and
266 * string versions of the name and description for
267 * eventual use in the printer selection list.
269 dpd->printer_lists[dpd->xp_server_count] = (DtPrintSelectPrinterList)
270 XtCalloc(dpd->printer_counts[dpd->xp_server_count],
271 sizeof(DtPrintSelectPrinterRec));
272 printer_list = dpd->printer_lists[dpd->xp_server_count];
273 for(j = 0; j < dpd->printer_counts[dpd->xp_server_count]; j++)
275 printer_list[j].printer_name_ct =
276 XtNewString(xp_printer_list[j].name);
277 printer_list[j].printer_name =
278 CompoundTextToString(display,
279 (unsigned char*)xp_printer_list[j].name);
280 printer_list[j].description =
281 CompoundTextToString(display,
282 (unsigned char*)xp_printer_list[j].desc);
284 XpFreePrinterList(xp_printer_list);
286 * sort the printer list
288 if(0 < dpd->printer_counts[dpd->xp_server_count])
289 qsort((void*)printer_list,
290 dpd->printer_counts[dpd->xp_server_count],
291 sizeof(DtPrintSelectPrinterRec), CompareSelectPrinterRecs);
293 *item_count += dpd->printer_counts[dpd->xp_server_count];
294 ++dpd->xp_server_count;
295 XCloseDisplay(display);
297 _DtPrintFreeStringList(server_list);
300 FreeSelectPrinterData(dpd);
301 return DtPRINT_FAILURE;
304 return DtPRINT_SUCCESS;
308 * ------------------------------------------------------------------------
309 * Name: BuildPrinterSelectionItems
313 * Builds the list of XmString items (printer name + desc) to be set
314 * in the printer selection list box.
322 BuildPrinterSelectionItems(
324 DtPrintDefaultProcData* dpd,
326 String initial_printer,
331 char* buf = (char*)NULL;
332 Cardinal buf_size = 0;
335 String name, full_name, desc;
339 items = (XmStringTable)XtCalloc(item_count, sizeof(XmString));
340 for(i = 0, current_item = 0; i < dpd->xp_server_count; i++)
342 server_name = dpd->xp_server_list[i];
343 server_len = strlen(server_name);
345 for(j = 0; j < dpd->printer_counts[i]; j++, current_item++)
348 * build a fully qualified X printer specifier
350 name = (dpd->printer_lists[i])[j].printer_name;
351 (dpd->printer_lists[i])[j].printer_name = (String)NULL;
353 _DtPrintCreateXPrinterSpecifier(name, server_name,
354 DtPRINT_NET_UNSPECIFIED,
358 * check to see if this should be the initially selected printer
360 if(dpd->selected_printer == 0
361 && (String)NULL != initial_printer)
362 if(strcmp(initial_printer, full_name) == 0)
363 dpd->selected_printer = current_item + 1;
365 * convert the printer description
367 desc = (dpd->printer_lists[i])[j].description;
368 (dpd->printer_lists[i])[j].description = (String)NULL;
369 if((String)NULL != desc && '\0' != *desc)
372 * chop the description after the 1st line
374 char* ptr = Dt_strchr(desc, '\n');
375 if((char*)NULL != ptr)
379 * ensure the format buffer is large enough to contain
380 * the formatted list item
383 new_size += full_name ? strlen(full_name) : 0;
384 new_size += desc ? strlen(desc) : 0;
385 if(new_size > buf_size)
388 buf = XtRealloc(buf, buf_size);
391 * format the item, and add it to the item list
393 sprintf(buf, "%s\t%s",
394 full_name ? full_name : "",
398 items[current_item] =
399 XmStringGenerate((XtPointer)buf, (XmStringTag)NULL,
400 XmMULTIBYTE_TEXT, tag);
408 * ------------------------------------------------------------------------
409 * Name: CloseSelectPrinterInfoConnection
413 * Close the X printer connection maintained for the Select Printer
414 * dialog's Printer Information dialog.
422 CloseSelectPrinterInfoConnection(
423 DtPrintDefaultProcData* dpd)
425 if((Display*)NULL != dpd->select_printer_info_display)
427 if((XPContext)None != dpd->select_printer_info_context)
429 XpDestroyContext(dpd->select_printer_info_display,
430 dpd->select_printer_info_context);
431 dpd->select_printer_info_context = (XPContext)None;
433 XCloseDisplay(dpd->select_printer_info_display);
434 dpd->select_printer_info_display = (Display*)NULL;
439 * ------------------------------------------------------------------------
440 * Name: CompareSelectPrinterRecs
444 * Compares the printer names in two DtPrintSelectPrinterRecs.
448 * Returns an integer greater than, equal to, or less than zero,
449 * according to whether the printer name in spr1 is greater
450 * than, equal to, or less than the printer name in spr2.
454 CompareSelectPrinterRecs(const void* spr1,
457 return strcoll(((DtPrintSelectPrinterRec*)spr1)->printer_name,
458 ((DtPrintSelectPrinterRec*)spr2)->printer_name);
462 * ------------------------------------------------------------------------
463 * Name: CompoundTextToString
475 CompoundTextToString(
477 unsigned char* compound_text)
479 String str = (String)NULL;
481 if((unsigned char*)NULL != compound_text)
483 XTextProperty text_prop;
487 text_prop.encoding = XInternAtom(display, "COMPOUND_TEXT", False);
488 text_prop.format = 8;
489 text_prop.value = compound_text;
490 text_prop.nitems = strlen((char*)text_prop.value);
492 XmbTextPropertyToTextList(display, &text_prop, &list, &count))
495 str = XtNewString(list[0]);
496 XFreeStringList(list);
503 * ------------------------------------------------------------------------
504 * Name: CreateFileSelectionBox
508 * Creates the file selection dialog box.
516 CreateFileSelectionBox(
519 DtPrintDefaultProcData* dpd)
523 XmString title_xmstr;
525 title_xmstr = XmStringCreateLocalized(SELECT_FILE_TITLE);
531 XtSetArg(args[n], XmNdialogTitle, title_xmstr); n++;
532 XtSetArg(args[n], XmNdialogStyle,
533 XmDIALOG_PRIMARY_APPLICATION_MODAL); n++;
534 XtSetArg(args[n], XmNdeleteResponse, XmUNMAP); n++;
536 * file selection box resources
538 XtSetArg(args[n], XmNautoUnmanage, True); n++;
540 * create the file selection box dialog
542 dpd->file_selection_box =
543 XmCreateFileSelectionDialog(parent, "_PsubDefProcFileSelectionBox",
545 XmStringFree(title_xmstr);
546 if(dpd->file_selection_box == (Widget)NULL)
547 return DtPRINT_FAILURE;
551 XtAddCallback(dpd->file_selection_box, XmNokCallback,
552 UpdateFileNameCB, (XtPointer)psub);
553 XtAddCallback(dpd->file_selection_box, XmNhelpCallback,
554 SelectFileHelpCB, (XtPointer)psub);
555 XtAddCallback(dpd->file_selection_box, XmNdestroyCallback,
556 SelectFileDestroyCB, (XtPointer)psub);
560 return DtPRINT_SUCCESS;
564 * ------------------------------------------------------------------------
565 * Name: CreatePrinterInfoBox
569 * Creates the printer information dialog box.
577 CreatePrinterInfoBox(
580 DtPrintDefaultProcData* dpd)
584 XmString title_xmstr;
586 Widget description_label, description;
587 Widget name_label, name;
588 Widget format_label, format;
589 Widget model_label, model;
592 title_xmstr = XmStringCreateLocalized(PRINTER_INFO_TITLE);
598 XtSetArg(args[n], XmNdialogTitle, title_xmstr); n++;
599 XtSetArg(args[n], XmNdialogStyle,
600 XmDIALOG_PRIMARY_APPLICATION_MODAL); n++;
601 XtSetArg(args[n], XmNdeleteResponse, XmUNMAP); n++;
603 * printer info box resources
605 XtSetArg(args[n], XmNautoUnmanage, True); n++;
609 dpd->printer_info_box =
610 XmCreateInformationDialog(parent, "_PsubDefProcPrinterInfoBox",
612 XmStringFree(title_xmstr);
613 if(dpd->printer_info_box == (Widget)NULL)
614 return DtPRINT_FAILURE;
618 XtAddCallback(dpd->printer_info_box, XmNhelpCallback,
619 PrinterInfoHelpCB, (XtPointer)psub);
620 XtAddCallback(dpd->printer_info_box, XmNdestroyCallback,
621 PrinterInfoDestroyCB, (XtPointer)psub);
622 XtAddCallback(dpd->printer_info_box, XmNmapCallback,
623 InfoBoxLayoutCB, (XtPointer)dpd);
625 * unmanage unwanted children
627 XtUnmanageChild(XtNameToWidget(dpd->printer_info_box, "Cancel"));
628 XtUnmanageChild(XtNameToWidget(dpd->printer_info_box, "Message"));
629 XtUnmanageChild(XtNameToWidget(dpd->printer_info_box, "Symbol"));
631 * create the control manager
634 XtVaCreateManagedWidget("PrinterInfoForm", xmFormWidgetClass,
635 dpd->printer_info_box,
636 XmNallowOverlap, False,
639 * printer description
641 label = XmStringCreateLocalized(DESCRIPTION_LABEL);
643 XtVaCreateManagedWidget("DescriptionLabel",
646 XmNlabelString, label,
647 XmNleftAttachment, XmATTACH_FORM,
648 XmNtopAttachment, XmATTACH_FORM,
653 XtVaCreateManagedWidget("Description",
656 XmNalignment, XmALIGNMENT_BEGINNING,
657 XmNleftAttachment, XmATTACH_WIDGET,
658 XmNleftWidget, description_label,
660 XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
661 XmNtopWidget, description_label,
666 label = XmStringCreateLocalized(PRINTER_NAME_LABEL);
668 XtVaCreateManagedWidget("NameLabel",
671 XmNlabelString, label,
672 XmNleftAttachment, XmATTACH_FORM,
673 XmNtopAttachment, XmATTACH_WIDGET,
674 XmNtopWidget, description,
679 XtVaCreateManagedWidget("Name",
682 XmNleftAttachment, XmATTACH_WIDGET,
683 XmNleftWidget, name_label,
685 XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
686 XmNtopWidget, name_label,
691 label = XmStringCreateLocalized(FORMAT_LABEL);
693 XtVaCreateManagedWidget("FormatLabel",
696 XmNlabelString, label,
697 XmNleftAttachment, XmATTACH_FORM,
698 XmNtopAttachment, XmATTACH_WIDGET,
699 XmNtopWidget, name_label,
704 XtVaCreateManagedWidget("Format",
707 XmNleftAttachment, XmATTACH_WIDGET,
708 XmNleftWidget, format_label,
710 XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
711 XmNtopWidget, format_label,
716 label = XmStringCreateLocalized(MODEL_LABEL);
718 XtVaCreateManagedWidget("ModelLabel",
721 XmNlabelString, label,
722 XmNleftAttachment, XmATTACH_FORM,
723 XmNtopAttachment, XmATTACH_WIDGET,
724 XmNtopWidget, format_label,
729 XtVaCreateManagedWidget("Model",
732 XmNalignment, XmALIGNMENT_BEGINNING,
733 XmNleftAttachment, XmATTACH_WIDGET,
734 XmNleftWidget, model_label,
736 XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
737 XmNtopWidget, model_label,
742 return DtPRINT_SUCCESS;
746 * ------------------------------------------------------------------------
747 * Name: CreatePrinterSelectionBox
751 * Creates the printer selection dialog box.
759 CreatePrinterSelectionBox(
762 DtPrintDefaultProcData* dpd)
768 XmString title_xmstr;
771 title_xmstr = XmStringCreateLocalized(MORE_PRINTERS_TITLE);
772 list_label = XmStringCreateLocalized(PRINTER_LIST_LABEL);
773 info_label = XmStringCreateLocalized(PRINTER_INFO_LABEL);
779 XtSetArg(args[n], XmNdialogTitle, title_xmstr); n++;
780 XtSetArg(args[n], XmNdialogStyle,
781 XmDIALOG_PRIMARY_APPLICATION_MODAL); n++;
782 XtSetArg(args[n], XmNdeleteResponse, XmDESTROY); n++;
784 * selection box resources
786 XtSetArg(args[n], XmNautoUnmanage, True); n++;
787 XtSetArg(args[n], XmNlistLabelString, list_label); n++;
788 XtSetArg(args[n], XmNapplyLabelString, info_label); n++;
792 dpd->printer_selection_box =
793 XmCreateSelectionDialog(parent, "_PsubDefProcPrinterSelectionBox",
795 XmStringFree(list_label);
796 XmStringFree(info_label);
797 XmStringFree(title_xmstr);
798 if(dpd->printer_selection_box == (Widget)NULL)
799 return DtPRINT_FAILURE;
803 XtAddCallback(dpd->printer_selection_box, XmNokCallback,
804 SelectPrinterCB, (XtPointer)psub);
805 XtAddCallback(dpd->printer_selection_box, XmNapplyCallback,
806 SelectPrinterInfoCB, (XtPointer)psub);
807 XtAddCallback(dpd->printer_selection_box, XmNcancelCallback,
808 SelectPrinterCB, (XtPointer)psub);
809 XtAddCallback(dpd->printer_selection_box, XmNhelpCallback,
810 SelectPrinterHelpCB, (XtPointer)psub);
811 XtAddCallback(dpd->printer_selection_box, XmNdestroyCallback,
812 SelectPrinterDestroyCB, (XtPointer)psub);
814 * get the list box widget ID
816 dpd->printer_list_box =
817 XtNameToWidget(dpd->printer_selection_box, "*ItemsList");
818 XtAddCallback(dpd->printer_list_box, XmNbrowseSelectionCallback,
819 SelectPrinterItemCB, (XtPointer)psub);
821 * unmanaged unwanted children
823 control = XtNameToWidget(dpd->printer_selection_box, "*Selection");
824 if(control != (Widget)NULL)
825 XtUnmanageChild(control);
826 control = XtNameToWidget(dpd->printer_selection_box, "*Text");
827 if(control != (Widget)NULL)
828 XtUnmanageChild(control);
832 return DtPRINT_SUCCESS;
836 * ------------------------------------------------------------------------
837 * Name: DestroyWidgetCB
841 * Destroys the Widget passed as client_data.
851 XtPointer client_data,
854 XtDestroyWidget((Widget)client_data);
858 * ------------------------------------------------------------------------
859 * Name: DtPrintDefProcDestroyCB
863 * Free resources allocated for the default procedure data structure
864 * in response to the destruction of the DtPrintSetupBox.
866 * Calls destroy callbacks for dialogs *directly* because the dialogs
867 * aren't children of the DtPrintSetupBox, but instead are more like
868 * siblings or cousins of the PrintSetupBox whose common ancestor is
869 * the shell parent of the PrintSetupBox. As such the dialogs may or
870 * may not otherwise be destroyed when the PrintSetupBox is
871 * destroyed. Furthermore the 2nd phase of the XtDestroyWidget calls
872 * made in this routine isn't reached until after the PrintSetupBox
873 * instance record has been destroyed (as part of the destroy phase
874 * of which *this* call is a part).
876 * The main reason this is a concern is because data associated with
877 * these dialogs is stored in the PrintSetupBox widget instance
886 DtPrintDefProcDestroyCB(Widget w,
887 XtPointer client_data,
890 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
892 if(dpd->error_message_box)
894 XtRemoveCallback(dpd->error_message_box, XmNdestroyCallback,
895 ErrorMessageDestroyCB, (XtPointer)w);
896 XtDestroyWidget(dpd->error_message_box);
897 ErrorMessageDestroyCB(dpd->error_message_box,
898 (XtPointer)w, (XtPointer)NULL);
902 XtRemoveCallback(dpd->help_dialog, XmNdestroyCallback,
903 HelpDialogDestroyCB, (XtPointer)w);
904 XtDestroyWidget(dpd->help_dialog);
905 HelpDialogDestroyCB(dpd->help_dialog,
906 (XtPointer)w, (XtPointer)NULL);
908 if(dpd->file_selection_box)
910 XtRemoveCallback(dpd->file_selection_box, XmNdestroyCallback,
911 SelectFileDestroyCB, (XtPointer)w);
912 XtDestroyWidget(dpd->file_selection_box);
913 SelectFileDestroyCB(dpd->file_selection_box,
914 (XtPointer)w, (XtPointer)NULL);
916 if(dpd->printer_selection_box)
918 XtRemoveCallback(dpd->printer_selection_box, XmNdestroyCallback,
919 SelectPrinterDestroyCB, (XtPointer)w);
920 XtDestroyWidget(dpd->printer_selection_box);
921 SelectPrinterDestroyCB(dpd->printer_selection_box,
922 (XtPointer)w, (XtPointer)NULL);
924 if(dpd->printer_info_box)
926 XtRemoveCallback(dpd->printer_info_box, XmNdestroyCallback,
927 PrinterInfoDestroyCB, (XtPointer)w);
928 XtDestroyWidget(dpd->printer_info_box);
929 PrinterInfoDestroyCB(dpd->printer_info_box,
930 (XtPointer)w, (XtPointer)NULL);
936 * ------------------------------------------------------------------------
937 * Name: ErrorMessageDestroyCB
941 * Reset the error message widget ID instance data when the message
944 * This callback is considered part of the default resource
945 * procedures and not part of the setup box widget proper.
953 ErrorMessageDestroyCB(
955 XtPointer client_data,
958 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(client_data);
960 dpd->error_message_box = (Widget)NULL;
964 * ------------------------------------------------------------------------
965 * Name: FindSelectedPrinter
969 * Build a full printer name by locating the currently selected
970 * printer in the server list and printer list.
975 * A newly allocated full printer name. It is the caller's
976 * responsibility to free the returned String by calling XtFree.
982 DtPrintDefaultProcData* dpd)
989 * return if any of the structures are not in place
991 if(dpd->xp_server_list == (String*)NULL
993 dpd->printer_counts == (int*)NULL
995 dpd->printer_lists == (DtPrintSelectPrinterList*)NULL)
1000 * find the printer list containing the selected printer
1002 if(0 == dpd->selected_printer)
1003 return (String)NULL;
1005 printer_index = dpd->selected_printer - 1;
1007 for(i = 0, printer_count = 0; i < dpd->xp_server_count; i++)
1009 if(printer_index < printer_count + (dpd->printer_counts)[i])
1012 printer_count += (dpd->printer_counts)[i];
1014 if(i < dpd->xp_server_count)
1017 * build and return the printer name
1019 DtPrintSelectPrinterList printer_list;
1020 String printer_spec;
1021 String printer_name;
1022 char* printer_name_ct;
1025 display_spec = (dpd->xp_server_list)[i];
1026 printer_list = (dpd->printer_lists)[i];
1028 printer_list[printer_index - printer_count].printer_name_ct;
1030 CompoundTextToString(display, (unsigned char*)printer_name_ct);
1031 if((String)NULL != printer_name)
1034 _DtPrintCreateXPrinterSpecifier(printer_name,
1036 DtPRINT_NET_UNSPECIFIED,
1038 XtFree(printer_name);
1039 return printer_spec;
1042 return (String)NULL;
1046 * ------------------------------------------------------------------------
1047 * Name: FreeSelectPrinterData
1051 * Deallocate and reset data items associated with the printer
1059 FreeSelectPrinterData(
1060 DtPrintDefaultProcData* dpd)
1063 DtPrintSelectPrinterList printer_list;
1065 for(i = 0; i < dpd->xp_server_count; i++)
1067 printer_list = dpd->printer_lists[i];
1068 for(j = 0; j < dpd->printer_counts[i]; j++)
1070 XtFree(printer_list[j].printer_name_ct);
1072 XtFree((char*)printer_list);
1074 XtFree((char*)dpd->printer_lists);
1075 dpd->printer_lists = (DtPrintSelectPrinterList*)NULL;
1076 XtFree((char*)dpd->xp_server_list);
1077 dpd->xp_server_list = (String*)NULL;
1078 dpd->xp_server_count = 0;
1079 dpd->selected_printer = 0;
1083 * ------------------------------------------------------------------------
1084 * Name: GetWMShellAncestor
1088 * Obtains the widget ID of the closest WMShell ancestor for
1089 * the passed widget.
1093 * The widget ID of the closest WMShell ancestor.
1097 GetWMShellAncestor(Widget w)
1099 Widget wmshell_ancestor = XtParent(w);
1100 while(wmshell_ancestor != (Widget)NULL)
1102 if(XtIsWMShell(wmshell_ancestor))
1105 wmshell_ancestor = XtParent(wmshell_ancestor);
1107 return wmshell_ancestor;
1111 * ------------------------------------------------------------------------
1112 * Name: HelpDialogDestroyCB
1116 * Reset the help dialog widget ID instance data when the widget
1119 * This callback is considered part of the default resource
1120 * procedures and not part of the setup box widget proper.
1128 HelpDialogDestroyCB(
1130 XtPointer client_data,
1131 XtPointer call_data)
1133 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(client_data);
1135 dpd->help_dialog = (Widget)NULL;
1139 * ------------------------------------------------------------------------
1140 * Name: InfoBoxLayoutCB
1144 * Callback to right justify printer information dialog labels at
1156 XtPointer client_data,
1157 XtPointer call_data)
1159 DtPrintDefaultProcData* dpd = (DtPrintDefaultProcData*)client_data;
1162 Dimension width, max_width;
1164 * only need to do this once after the widget is created
1166 XtRemoveCallback(widget, XmNmapCallback, InfoBoxLayoutCB, client_data);
1168 * get the label widget ids
1170 w[0] = XtNameToWidget(dpd->printer_info_box,
1171 "PrinterInfoForm.DescriptionLabel");
1172 w[1] = XtNameToWidget(dpd->printer_info_box,
1173 "PrinterInfoForm.NameLabel");
1174 w[2] = XtNameToWidget(dpd->printer_info_box,
1175 "PrinterInfoForm.FormatLabel");
1176 w[3] = XtNameToWidget(dpd->printer_info_box,
1177 "PrinterInfoForm.ModelLabel");
1179 * find the widest label
1181 for(i = 0, widest = 0, max_width = 0; i < 4; i++)
1183 XtVaGetValues(w[i], XmNwidth, &width, NULL);
1184 if(width > max_width)
1191 * sever the top attachment on the widest label in order to avoid
1192 * circular dependencies in form children; apparently one of the form
1193 * widget's many talents is the inability to manage the vertical and
1194 * horizontal attachments independently...
1196 XtVaSetValues(w[widest], XmNtopAttachment, XmATTACH_SELF, NULL);
1198 * attach the right side of the smaller labels to the right side of
1201 for(i = 0; i < 4; i++)
1204 XmNleftAttachment, XmATTACH_NONE,
1205 XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET,
1206 XmNrightWidget, w[widest],
1211 * ------------------------------------------------------------------------
1212 * Name: ParseFileNameSpec
1216 * Parse the passed file name to create a file selection box filter
1217 * pattern and the name only portion of the full name spec.
1219 * It is the caller's responsibility to free the allocated memory
1220 * returned in 'pattern' and 'name_only' using XmStringFree and
1221 * XtFree respectively.
1230 ParseFileNameSpec(const char* file_name,
1231 XmString* pattern_xmstr,
1237 * start off with a copy of the file name, ensuring there is
1238 * enough space for the added "*" and the string terminator.
1240 pattern = XtMalloc(strlen(file_name)+2);
1241 strcpy(pattern, file_name);
1243 * find the last slash
1245 ptr = DtStrrchr(pattern, '/');
1246 if(ptr != (String)NULL)
1249 * grab the name portion of the file name
1251 *name_only = XtNewString(ptr+1);
1253 * set the wildcard character immediately following the last
1257 *pattern_xmstr = XmStringCreateLocalized(pattern);
1262 * no slash found; use the default pattern
1264 *pattern_xmstr = (XmString)NULL;
1265 *name_only = XtNewString(file_name);
1271 * ------------------------------------------------------------------------
1272 * Name: PresentErrorDialog
1276 * This is a utility function that will present an Error Dialog. It
1277 * takes a title, a message, and a variable list of Strings to
1278 * include in the message. The message parm is treated like a
1279 * printf-style format string, except that only the "%s" directive is
1282 * This function is to be used exclusively by the default
1283 * resource procedures (e.g. _DtPrintSetupBoxVerifyXPrinterProc).
1285 * The variable list of String parms must be terminated by
1302 String expanded_message;
1304 XmString message_xmstr;
1305 XmString title_xmstr;
1308 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
1309 Widget wmshell_ancestor;
1310 WidgetList wmshell_ancestors_children = (WidgetList)NULL;
1312 wmshell_ancestor = GetWMShellAncestor(w);
1314 if (wmshell_ancestor)
1317 XtSetArg(args[n], XmNchildren, &wmshell_ancestors_children); n++;
1318 XtGetValues(wmshell_ancestor, args, n);
1321 if(dpd->error_message_box != (Widget)NULL)
1324 * present only one message box
1326 XtDestroyWidget(dpd->error_message_box);
1329 title_xmstr = XmStringCreateLocalized(title);
1331 * determine length of expanded message
1333 message_len = strlen(message);
1334 va_start(arg_marker, message);
1335 while((str_n = va_arg(arg_marker, String)) != (String)NULL)
1337 message_len += strlen(str_n);
1342 * expand the message
1344 expanded_message = XtMalloc(message_len);
1345 va_start(arg_marker, message);
1346 vsprintf(expanded_message, message, arg_marker);
1349 * convert message to XmString
1351 message_xmstr = XmStringCreateLocalized(expanded_message);
1352 XtFree(expanded_message);
1354 * create the error dialog
1357 XtSetArg(args[n], XmNdialogTitle, title_xmstr); n++;
1358 XtSetArg(args[n], XmNmessageString, message_xmstr); n++;
1359 XtSetArg(args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); n++;
1360 XtSetArg(args[n], XmNdeleteResponse, XmDESTROY); n++;
1361 dpd->error_message_box =
1362 XmCreateErrorDialog(wmshell_ancestors_children ?
1363 wmshell_ancestors_children[0] :
1365 "_PsubDefProcErrorMsg", args, n);
1366 XmStringFree(title_xmstr);
1367 XmStringFree(message_xmstr);
1369 XtUnmanageChild(XtNameToWidget(dpd->error_message_box, "Cancel"));
1370 XtUnmanageChild(XtNameToWidget(dpd->error_message_box, "Help"));
1372 XtAddCallback(dpd->error_message_box, XmNokCallback,
1373 DestroyWidgetCB, (XtPointer)dpd->error_message_box);
1374 XtAddCallback(dpd->error_message_box, XmNcancelCallback,
1375 DestroyWidgetCB, (XtPointer)dpd->error_message_box);
1376 XtAddCallback(dpd->error_message_box, XmNdestroyCallback,
1377 ErrorMessageDestroyCB, (XtPointer)w);
1379 * manage the message box according to the hint
1381 if(DtPRINT_HINT_MESSAGES_OK == dpd->messages_hint)
1382 XtManageChild(dpd->error_message_box);
1384 #ifdef XXX_JUNGLE_REMOVE
1386 * manage the message box only if the psub is mapped
1387 * and the focus is not in the printer name field
1390 XWindowAttributes attr;
1392 Window window = XtWindow(w);
1395 status = XGetWindowAttributes(XtDisplay(w), window, &attr);
1396 if(status == 0 || attr.map_state == IsViewable)
1398 Widget name_w = XtNameToWidget(w, "Name");
1401 for(child = XmGetFocusWidget(w);
1402 child != wmshell_ancestor && child != name_w
1403 && child != (Widget)NULL;
1404 child = XtParent(child));
1406 if(child != name_w && child != (Widget)NULL)
1407 XtManageChild(dpd->error_message_box);
1411 #endif /* XXX_JUNGLE_REMOVE */
1415 * ------------------------------------------------------------------------
1420 * Presents a help dialog whose widget instance may be shared between
1421 * the default dialogs.
1428 static void PresentHelp(
1430 const char* help_volume,
1431 const char* location_id)
1433 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
1434 Widget wmshell_ancestor;
1435 Widget dialog_shell;
1441 wmshell_ancestor = GetWMShellAncestor(w);
1443 if((Widget)NULL == dpd->help_dialog)
1450 title = XmStringCreateLocalized(HELP_DLG_TITLE);
1451 XtSetArg(args[n], XmNdialogTitle, title); n++;
1453 DtCreateHelpDialog(wmshell_ancestor, "_PsubDefProcHelpDialog",
1455 XmStringFree(title);
1456 XtAddCallback(dpd->help_dialog, XmNdestroyCallback,
1457 HelpDialogDestroyCB, (XtPointer)w);
1460 * set the help volume and location
1462 XtVaSetValues(dpd->help_dialog,
1463 DtNhelpVolume, help_volume,
1464 DtNlocationId, location_id,
1465 DtNhelpType, DtHELP_TYPE_TOPIC,
1468 * pop up the help dialog
1470 XtManageChild(dpd->help_dialog);
1471 dialog_shell = XtParent(dpd->help_dialog);
1472 if(None != XtWindow(dialog_shell))
1473 XRaiseWindow(XtDisplay(dialog_shell), XtWindow(dialog_shell));
1477 * ------------------------------------------------------------------------
1478 * Name: PresentVerifyError
1482 * Presents a error dialog appropriate for an error status returned
1483 * by _DtPrintVerifyXPrinter.
1494 String printer_spec)
1496 String printer_name;
1497 String display_spec;
1499 _DtPrintParseXPrinterSpecifier(printer_spec,
1504 case DtPRINT_PRINTER_MISSING:
1505 PresentErrorDialog(w, INVALID_PRINTER_TITLE,
1506 PRINTER_MISSING_MESSAGE,
1511 case DtPRINT_NO_DEFAULT:
1512 PresentErrorDialog(w, INVALID_PRINTER_TITLE,
1517 case DtPRINT_NO_DEFAULT_DISPLAY:
1518 PresentErrorDialog(w, INVALID_PRINTER_TITLE,
1519 NO_DEFAULT_DISPLAY_MESSAGE,
1524 case DtPRINT_NO_PRINTER:
1525 PresentErrorDialog(w, INVALID_PRINTER_TITLE,
1526 INVALID_PRINTER_MESSAGE,
1527 printer_name, display_spec,
1531 case DtPRINT_NOT_XP_DISPLAY:
1532 PresentErrorDialog(w, INVALID_PRINTER_TITLE,
1533 NOT_XP_DISPLAY_MESSAGE,
1538 case DtPRINT_INVALID_DISPLAY:
1539 PresentErrorDialog(w, INVALID_PRINTER_TITLE,
1540 INVALID_DISPLAY_MESSAGE,
1545 XtFree(printer_name);
1546 XtFree(display_spec);
1551 * ------------------------------------------------------------------------
1552 * Name: PrinterInfoDestroyCB
1556 * Reset data items used in conjunction with the
1557 * printer information selection dialog.
1565 PrinterInfoDestroyCB(
1567 XtPointer client_data,
1568 XtPointer call_data)
1570 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(client_data);
1572 dpd->printer_info_box = (Widget)NULL;
1576 * ------------------------------------------------------------------------
1577 * Name: PrinterInfoHelpCB
1581 * Display context sensitive help.
1591 XtPointer client_data,
1592 XtPointer call_data)
1594 PresentHelp((Widget)client_data, HELP_VOLUME, PRINTER_INFO_HELP_ID);
1598 * ------------------------------------------------------------------------
1599 * Name: SelectFileDestroyCB
1603 * Reset data items used in conjunction with the
1604 * file selection dialog.
1612 SelectFileDestroyCB(
1614 XtPointer client_data,
1615 XtPointer call_data)
1617 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(client_data);
1619 dpd->file_selection_box = (Widget)NULL;
1623 * ------------------------------------------------------------------------
1624 * Name: SelectFileHelpCB
1628 * Display context sensitive help.
1638 XtPointer client_data,
1639 XtPointer call_data)
1641 PresentHelp((Widget)client_data, HELP_VOLUME, SELECT_FILE_HELP_ID);
1645 * ------------------------------------------------------------------------
1646 * Name: SelectPrinterCB
1650 * Callback to handle the printer selection box OK and Cancel
1661 XtPointer client_data,
1662 XtPointer call_data)
1664 XmSelectionBoxCallbackStruct* cbs =
1665 (XmSelectionBoxCallbackStruct*)call_data;
1666 Widget psub = (Widget)client_data;
1667 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(psub);
1669 String printer_spec;
1672 * close the info dialog display connection if it's been opened
1674 CloseSelectPrinterInfoConnection(dpd);
1680 * set the selected printer name in the PrintSetupBox
1682 printer_spec = FindSelectedPrinter(XtDisplay(psub), dpd);
1683 if((String)NULL != printer_spec)
1685 XtVaSetValues(psub, DtNprinterName, printer_spec, NULL);
1686 XtFree(printer_spec);
1694 * deallocate and reset the lists
1696 FreeSelectPrinterData(dpd);
1697 if(dpd->printer_list_box != (Widget)NULL)
1698 XmListDeleteAllItems(dpd->printer_list_box);
1704 * ------------------------------------------------------------------------
1705 * Name: SelectPrinterDestroyCB
1709 * Deallocate and reset data items used in conjunction with the
1710 * printer selection dialog.
1718 SelectPrinterDestroyCB(
1720 XtPointer client_data,
1721 XtPointer call_data)
1723 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(client_data);
1725 dpd->printer_selection_box = (Widget)NULL;
1726 dpd->printer_list_box = (Widget)NULL;
1727 CloseSelectPrinterInfoConnection(dpd);
1728 FreeSelectPrinterData(dpd);
1732 * ------------------------------------------------------------------------
1733 * Name: SelectPrinterHelpCB
1737 * Display context sensitive help.
1745 SelectPrinterHelpCB(
1747 XtPointer client_data,
1748 XtPointer call_data)
1750 PresentHelp((Widget)client_data, HELP_VOLUME, SELECT_PRINTER_HELP_ID);
1754 * ------------------------------------------------------------------------
1755 * Name: SelectPrinterInfoCB
1759 * Callback attached to the printer selection box "Info..."
1760 * button. The "Info..." button is intended to behave just like the
1761 * PrintSetupBox "Info..." button, so it is implemented to call the
1762 * procedure set for the PrintSetupBox DtNprinterInfoProc resource.
1763 * As such, this function needs to open a new display connection to
1764 * the print server indicated by the currently selected printer in
1765 * the list. The connection is not closed until a selection is made
1766 * in the list, or the printer selection dialog is dismissed. This is
1767 * because no assumptions about the Printer Info dialog's widget
1768 * heirarchy can be made.
1776 SelectPrinterInfoCB(
1778 XtPointer client_data,
1779 XtPointer call_data)
1781 Widget psub = (Widget)client_data;
1782 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(psub);
1783 DtPrintSetupProc info_proc;
1785 CloseSelectPrinterInfoConnection(dpd);
1786 XtVaGetValues(psub, DtNprinterInfoProc, &info_proc, NULL);
1787 if((DtPrintSetupProc)NULL != info_proc)
1789 String printer_spec;
1791 printer_spec = FindSelectedPrinter(XtDisplay(psub), dpd);
1792 if((String)NULL != printer_spec)
1794 String new_printer_spec; /*
1795 * will always be set to NULL by
1796 * _DtPrintVerifyXPrinter when
1797 * called from within this routine
1802 * open a connection to the X printer
1805 _DtPrintVerifyXPrinter(psub,
1808 &dpd->select_printer_info_display,
1809 &dpd->select_printer_info_context);
1810 if(status == DtPRINT_SUCCESS)
1812 DtPrintSetupData psd;
1814 memset(&psd, 0, sizeof(DtPrintSetupData));
1815 psd.printer_name = printer_spec;
1816 psd.print_display = dpd->select_printer_info_display;
1817 psd.print_context = dpd->select_printer_info_context;
1818 (*info_proc)(psub, &psd);
1823 * this should only happen if, while a user is viewing
1824 * the printer selection dialog, a server rehash is
1825 * performed that deletes the currently selected printer
1827 PresentVerifyError(w, status, printer_spec);
1829 XtFree(printer_spec);
1835 * ------------------------------------------------------------------------
1836 * Name: SelectPrinterItemCB
1840 * Callback to handle the a selection in the printer selection list
1849 SelectPrinterItemCB(
1851 XtPointer client_data,
1852 XtPointer call_data)
1854 XmListCallbackStruct* cbs =
1855 (XmListCallbackStruct*)call_data;
1856 Widget psub = (Widget)client_data;
1857 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(psub);
1860 if(dpd->selected_printer != cbs->item_position)
1862 dpd->selected_printer = cbs->item_position;
1863 info_button = XtNameToWidget(dpd->printer_selection_box, "*Apply");
1864 if(0 == dpd->selected_printer)
1865 XtSetSensitive(info_button, False);
1867 XtSetSensitive(info_button, True);
1869 * update the default printer info dialog if it is visible
1871 if(dpd->printer_info_box && XtIsManaged(dpd->printer_info_box))
1872 SelectPrinterInfoCB(w, client_data, (XtPointer)NULL);
1877 * ------------------------------------------------------------------------
1878 * Name: SetListBoxSelection
1889 SetListBoxSelection(Widget list_box, int position)
1891 int visible_item_count;
1894 int first_visible_pos;
1896 * Scroll the list, making the item at the indicated position
1897 * visible in the center of the list box, and make
1898 * it the initial selection.
1900 XtVaGetValues(list_box,
1901 XmNitemCount, &item_count,
1902 XmNvisibleItemCount, &visible_item_count,
1905 if(item_count > visible_item_count)
1907 middle_offset = (visible_item_count+1) / 2;
1908 if(position > middle_offset)
1909 if(position > item_count - middle_offset)
1910 first_visible_pos = item_count - visible_item_count +1;
1912 first_visible_pos = position - middle_offset + 1;
1914 first_visible_pos = 1;
1915 XmListSetPos(list_box, first_visible_pos);
1919 XmListSelectPos(list_box, position, True);
1921 XmListDeselectAllItems(list_box);
1925 * ------------------------------------------------------------------------
1926 * Name: UpdateFileNameCB
1930 * Updates the PrintSetupBox fileName resource based on the selection
1931 * make in the file selection box.
1941 XtPointer client_data,
1942 XtPointer call_data)
1945 Widget psub = (Widget)client_data;
1948 * get the file name from the file selection box text field
1950 text_field = XtNameToWidget(w, "Text");
1953 XtVaGetValues(text_field, XmNvalue, &file_name, NULL);
1957 * set the file name in the print setup box
1959 XtVaSetValues(psub, DtNfileName, file_name, NULL);
1961 * free the file name retrieved from the text field
1969 * ------------------------------------------------------------------------
1970 * Name: _DtPrintDefProcInitialize
1981 _DtPrintDefProcInitialize(Widget w)
1983 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
1985 dpd->error_message_box = (Widget)NULL;
1986 dpd->messages_hint = DtPRINT_HINT_MESSAGES_OK;
1987 dpd->help_dialog = (Widget)NULL;
1988 dpd->file_selection_box = (Widget)NULL;
1989 dpd->printer_selection_box = (Widget)NULL;
1990 dpd->printer_list_box = (Widget)NULL;
1991 dpd->xp_server_list = (String*)NULL;
1992 dpd->xp_server_count = 0;
1993 dpd->printer_lists = (DtPrintSelectPrinterList*)NULL;
1994 dpd->selected_printer = 0;
1995 dpd->select_printer_info_display = (Display*)NULL;
1996 dpd->select_printer_info_context = (XPContext)None;
1997 dpd->printer_info_box = (Widget)NULL;
1999 XtAddCallback(w, XmNdestroyCallback,
2000 DtPrintDefProcDestroyCB, (XtPointer)NULL);
2004 * ------------------------------------------------------------------------
2005 * Name: _DtPrintDefProcManageErrorBox
2009 * Manage the Error Message Box if it exists.
2016 _DtPrintDefProcManageErrorBox(
2017 DtPrintDefaultProcData* dpd)
2019 if(dpd->error_message_box != (Widget)NULL)
2020 XtManageChild(dpd->error_message_box);
2024 * ------------------------------------------------------------------------
2025 * Name: _DtPrintSetupBoxXPrinterInfoProc
2029 * Default Xp mode function for the DtNprinterInfoProc resource.
2036 _DtPrintSetupBoxXPrinterInfoProc(
2038 DtPrintSetupData* print_data)
2040 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
2041 Widget wmshell_ancestor;
2044 char* attr_value_ct;
2046 XmString empty_label;
2047 Widget name_label_top;
2050 Widget manager = NULL;
2051 Widget dialog_shell;
2053 wmshell_ancestor = GetWMShellAncestor(w);
2054 _DtTurnOnHourGlass(wmshell_ancestor);
2055 empty_label = XmStringCreateLocalized("");
2057 * if needed, create the printer information dialog
2059 if(dpd->printer_info_box == (Widget)NULL)
2061 XtEnum status = CreatePrinterInfoBox(wmshell_ancestor, w, dpd);
2062 if(status != DtPRINT_SUCCESS)
2064 _DtTurnOffHourGlass(wmshell_ancestor);
2067 dialog_shell = XtParent(dpd->printer_info_box);
2072 * hide the widget during re-layout
2074 manager = XtNameToWidget(dpd->printer_info_box, "*PrinterInfoForm");
2075 XtUnmapWidget(dpd->printer_info_box);
2076 dialog_shell = XtParent(dpd->printer_info_box);
2077 XtVaSetValues(dialog_shell, XmNallowShellResize, False, NULL);
2078 XtUnmanageChild(manager);
2083 ctl = XtNameToWidget(dpd->printer_info_box, "*Description");
2084 XtVaSetValues(ctl, XmNlabelString, empty_label, NULL);
2085 attr_value_ct = XpGetOneAttribute(print_data->print_display,
2086 print_data->print_context,
2089 if((char*)NULL != attr_value_ct)
2092 CompoundTextToString(XtDisplay(w), (unsigned char*)attr_value_ct);
2093 XFree(attr_value_ct);
2094 if((String)NULL != attr_value)
2096 label = XmStringGenerate((XtPointer)attr_value, (XmStringTag)NULL,
2097 XmMULTIBYTE_TEXT, (XmStringTag)NULL);
2099 XtVaSetValues(ctl, XmNlabelString, label, NULL);
2100 XmStringFree(label);
2104 * set the top attachment for the name label
2106 XtVaGetValues(ctl, XmNy, &y, XmNheight, &height, NULL);
2108 name_label_top = ctl;
2109 ctl = XtNameToWidget(dpd->printer_info_box, "*DescriptionLabel");
2110 XtVaGetValues(ctl, XmNy, &y, XmNheight, &height, NULL);
2111 if(y+height > max_y)
2112 name_label_top = ctl;
2113 ctl = XtNameToWidget(dpd->printer_info_box, "*NameLabel");
2114 XtVaSetValues(ctl, XmNtopWidget, name_label_top, NULL);
2118 ctl = XtNameToWidget(dpd->printer_info_box, "*Name");
2119 label = XmStringCreateLocalized(print_data->printer_name);
2120 XtVaSetValues(ctl, XmNlabelString, label, NULL);
2121 XmStringFree(label);
2125 ctl = XtNameToWidget(dpd->printer_info_box, "*Format");
2126 XtVaSetValues(ctl, XmNlabelString, empty_label, NULL);
2127 attr_value = XpGetOneAttribute(print_data->print_display,
2128 print_data->print_context,
2131 if((String)NULL != attr_value)
2134 format_start = strchr(attr_value, '{');
2135 if((char*)NULL != format_start)
2139 format_end = strchr(format_start, '}');
2140 if((char*)NULL != format_end)
2143 label = XmStringCreateLocalized(format_start);
2144 XtVaSetValues(ctl, XmNlabelString, label, NULL);
2145 XmStringFree(label);
2153 ctl = XtNameToWidget(dpd->printer_info_box, "*Model");
2154 XtVaSetValues(ctl, XmNlabelString, empty_label, NULL);
2155 attr_value_ct = XpGetOneAttribute(print_data->print_display,
2156 print_data->print_context,
2159 if((char*)NULL != attr_value_ct)
2162 CompoundTextToString(XtDisplay(w), (unsigned char*)attr_value_ct);
2163 XFree(attr_value_ct);
2164 if((String)NULL != attr_value)
2166 label = XmStringGenerate((XtPointer)attr_value, (XmStringTag)NULL,
2167 XmCHARSET_TEXT, (XmStringTag)NULL);
2169 XtVaSetValues(ctl, XmNlabelString, label, NULL);
2170 XmStringFree(label);
2174 * pop up the printer info dialog and return
2176 XmStringFree(empty_label);
2179 XtVaSetValues(dialog_shell, XmNallowShellResize, True, NULL);
2180 XtManageChild(manager);
2181 XtMapWidget(dpd->printer_info_box);
2183 XtManageChild(dpd->printer_info_box);
2184 if(None != XtWindow(dialog_shell))
2185 XRaiseWindow(XtDisplay(dialog_shell), XtWindow(dialog_shell));
2186 _DtTurnOffHourGlass(wmshell_ancestor);
2187 return DtPRINT_SUCCESS;
2191 * ------------------------------------------------------------------------
2192 * Name: _DtPrintSetupBoxSelectFileProc
2196 * Default function for the DtNselectFileProc resource.
2203 _DtPrintSetupBoxSelectFileProc(
2205 DtPrintSetupData* print_data)
2207 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
2213 Widget wmshell_ancestor;
2215 wmshell_ancestor = GetWMShellAncestor(w);
2216 _DtTurnOnHourGlass(wmshell_ancestor);
2218 * if needed, create the file selection dialog
2220 if(dpd->file_selection_box == (Widget)NULL)
2222 XtEnum status = CreateFileSelectionBox(wmshell_ancestor, w, dpd);
2223 if(status != DtPRINT_SUCCESS)
2225 _DtTurnOffHourGlass(wmshell_ancestor);
2230 * get the file name passed from the PrintSetupBox
2232 file_name = print_data->dest_info;
2234 * parse the file name to create the filter pattern and the name only
2235 * portion of the full name spec
2237 ParseFileNameSpec(file_name, &pattern, &name_only);
2239 * set the filter pattern in the file selection box
2241 XtVaSetValues(dpd->file_selection_box, XmNpattern, pattern, NULL);
2242 if(pattern != (XmString)NULL)
2243 XmStringFree(pattern);
2245 * select the current file name in the file names list
2247 file_list = XtNameToWidget(dpd->file_selection_box, "*ItemsList");
2248 if(file_list != (Widget)NULL)
2250 XmString file_name_xmstr;
2253 text_field = XtNameToWidget(dpd->file_selection_box, "Text");
2254 if(text_field != (Widget)NULL)
2258 * recreate the file name from the name_only and the current
2259 * dir spec as determined by the file selection box
2261 * Note: the char* value retrieved directly from the text
2262 * field is used, because forming the file name from a
2263 * concatenation of XmStrings causes XmListItemPos to fail
2264 * even though the file name is actually in the list.
2266 XtVaGetValues(text_field, XmNvalue, &dir_spec, NULL);
2267 file_name = XtMalloc(strlen(dir_spec)+strlen(name_only)+1);
2268 strcpy(file_name, dir_spec);
2269 strcat(file_name, name_only);
2270 file_name_xmstr = XmStringCreateLocalized(file_name);
2275 file_name_xmstr = XmStringCreateLocalized(file_name);
2277 * find the position of the file name in the list
2279 position = XmListItemPos(file_list, file_name_xmstr);
2280 SetListBoxSelection(file_list, position);
2284 * The file name is not in the list. Manually set in the
2285 * "Selection" text field.
2287 XtVaSetValues(dpd->file_selection_box,
2288 XmNdirSpec, file_name_xmstr,
2291 XmStringFree(file_name_xmstr);
2295 * pop up the file selection dialog and return
2297 XtManageChild(dpd->file_selection_box);
2298 _DtTurnOffHourGlass(wmshell_ancestor);
2299 return DtPRINT_SUCCESS;
2303 * ------------------------------------------------------------------------
2304 * Name: _DtPrintSetupBoxSelectXPrinterProc
2308 * Default Xp mode function for the DtNselectPrinterProc resource.
2315 _DtPrintSetupBoxSelectXPrinterProc(
2317 DtPrintSetupData* print_data)
2319 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
2320 Widget wmshell_ancestor;
2321 XmStringTable items;
2325 XmRenderTable render_table, new_render_table;
2328 XmRendition rendition;
2332 wmshell_ancestor = GetWMShellAncestor(w);
2333 _DtTurnOnHourGlass(wmshell_ancestor);
2335 * build the list of servers and printers
2337 if(DtPRINT_SUCCESS != BuildPrinterLists(w, dpd, &item_count))
2339 PresentErrorDialog(w, PRLIST_ERROR_TITLE,
2340 NO_PRINTERS_MESSAGE,
2342 _DtTurnOffHourGlass(wmshell_ancestor);
2343 return DtPRINT_FAILURE;
2346 * create the dialog if it doesn't exist
2348 if(dpd->printer_selection_box == (Widget)NULL)
2350 XtEnum status = CreatePrinterSelectionBox(wmshell_ancestor, w, dpd);
2351 if(status != DtPRINT_SUCCESS)
2353 _DtTurnOffHourGlass(wmshell_ancestor);
2358 * get a copy of the list widget's render table
2360 XtVaGetValues(dpd->printer_list_box,
2361 XmNrenderTable, &render_table,
2363 render_table = XmRenderTableCopy(render_table, (XmStringTag*)NULL, 0);
2365 * build the item list for the list box
2367 count = XmRenderTableGetTags(render_table, &tags);
2368 items = BuildPrinterSelectionItems(XtDisplay(w), dpd, item_count,
2369 print_data->printer_name, tags[0]);
2371 * generate a tab list for the items
2373 tab_list = XmStringTableProposeTablist(items, item_count,
2374 dpd->printer_list_box,
2377 * get a copy of the first rendition in the render table
2379 rendition = XmRenderTableGetRendition(render_table, tags[0]);
2380 for(i = 0; i < count; i++)
2382 XtFree((char*)tags);
2384 * update the copy with the new tab list
2387 XtSetArg(args[n], XmNtabList, tab_list); n++;
2388 XmRenditionUpdate(rendition, args, n);
2389 XmTabListFree(tab_list);
2391 * create a new render table replacing the first entry with the
2394 new_render_table = XmRenderTableAddRenditions(render_table, &rendition,
2395 1, XmMERGE_REPLACE);
2396 XmRenditionFree(rendition);
2398 * set the new render table and list items in the list box
2400 XtVaSetValues(dpd->printer_list_box,
2401 XmNrenderTable, new_render_table,
2403 XmNitemCount, item_count,
2405 XmRenderTableFree(new_render_table);
2406 for(i = 0; i < item_count; i++)
2407 XmStringFree(items[i]);
2408 XtFree((char*)items);
2409 SetListBoxSelection(dpd->printer_list_box, dpd->selected_printer);
2411 * disable the info button if nothing is selected
2413 if(0 == dpd->selected_printer)
2414 XtSetSensitive(XtNameToWidget(dpd->printer_selection_box, "*Apply"),
2417 * manage the dialog and return
2419 XtManageChild(dpd->printer_selection_box);
2420 _DtTurnOffHourGlass(wmshell_ancestor);
2421 return DtPRINT_SUCCESS;
2425 * ------------------------------------------------------------------------
2426 * Name: _DtPrintSetupBoxVerifyXPrinterProc
2430 * Default function for the DtNverifyPrinterProc resource when the
2433 * (this rest of this description outlines the responsibilities of a
2434 * DtNverifyPrinterProc in general)
2436 * This function verifies the printer name passed in the
2437 * PrintSetupData structure.
2439 * If needed, the DtNprintSetupMode resource may be obtained via a
2440 * GetValues call in order to determine the current setup mode.
2442 * It is the responsibility of this proc to return a valid print
2443 * Display handle and print context by setting the print_display and
2444 * print_context in the PrintSetupData. Conceptually, this is a
2445 * side-effect of this proc, but since it will be necessary to open a
2446 * display connection in order to properly verify the X printer,
2447 * there's no point in doing it twice.
2449 * If the passed printer name is incomplete, this proc may attempt to
2450 * determine a default or fully-qualified name (e.g. fill in a
2451 * missing display spec for an X Printer Specifier). The new default
2452 * or fully-qualified printer name should be set in the PrintSetupBox
2453 * by updating the DtNprinterName resource via a SetValues call. If a
2454 * fully-qualified name cannot be determined, this proc simply
2455 * returns DtPRINT_FAILURE.
2457 * If the printer cannot be verified, it is the responsibiliy of this
2458 * function to present an appropriate message to the user.
2463 * if the printer name has been successfully verified.
2466 * if the printer name is invalid.
2471 _DtPrintSetupBoxVerifyXPrinterProc(
2473 DtPrintSetupData* psd)
2475 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
2477 String new_printer_spec;
2478 Display* new_display;
2479 XPContext new_context;
2480 Widget wmshell_ancestor;
2482 wmshell_ancestor = GetWMShellAncestor(w);
2483 _DtTurnOnHourGlass(wmshell_ancestor);
2485 * verify the printer
2487 status = _DtPrintVerifyXPrinter(w,
2492 if(status == DtPRINT_SUCCESS)
2495 * update the passed print setup data with the new display and
2498 psd->print_display = new_display;
2499 psd->print_context = new_context;
2504 * unable to open the printer; present a message to the user
2505 * according to the hint set in the setup data
2507 dpd->messages_hint = psd->messages_hint;
2508 PresentVerifyError(w, status,
2510 ? new_printer_spec : psd->printer_name);
2512 * reset the hint since the error dialog is also used
2513 * by the other default procs
2515 dpd->messages_hint = DtPRINT_HINT_MESSAGES_OK;
2517 * this function only indicates success or failure
2519 status = DtPRINT_FAILURE;
2521 if(new_printer_spec)
2524 * set the new printer spec, even if the verify failed
2527 DtNprinterName, new_printer_spec,
2529 XtFree(new_printer_spec);
2534 _DtTurnOffHourGlass(wmshell_ancestor);