1 /* $XConsortium: PsubDefProc.c /main/14 1996/12/02 10:51:20 rswiston $ */
3 * DtPrint/PsubDefProc.c
6 * (c) Copyright 1996 Digital Equipment Corporation.
7 * (c) Copyright 1996 Hewlett-Packard Company.
8 * (c) Copyright 1996 International Business Machines Corp.
9 * (c) Copyright 1996 Sun Microsystems, Inc.
10 * (c) Copyright 1996 Novell, Inc.
11 * (c) Copyright 1996 FUJITSU LIMITED.
12 * (c) Copyright 1996 Hitachi.
15 * ------------------------------------------------------------------------
25 #include <Dt/HelpDialog.h>
26 #include <Dt/DtNlUtils.h>
27 #include <Dt/HourGlass.h>
30 * PrintSetupBP.h is included only for access to the DtPrintDefProcData
31 * member of the widget instance structure.
33 #include <Dt/PrintSetupBP.h>
35 #include <Dt/PsubUtilI.h>
38 * ------------------------------------------------------------------------
39 * Constant Definitions
42 #define HELP_VOLUME "LibDtPrint"
43 #define PRINTER_INFO_HELP_ID "PrinterInfo"
44 #define SELECT_PRINTER_HELP_ID "SelectPrinter"
45 #define SELECT_FILE_HELP_ID "SelectFile"
48 * ------------------------------------------------------------------------
49 * Static Function Declarations
52 static XtEnum BuildPrinterLists(
54 DtPrintDefaultProcData* dpd,
56 static XmStringTable BuildPrinterSelectionItems(
58 DtPrintDefaultProcData* dpd,
60 String initial_printer,
62 static void CloseSelectPrinterInfoConnection(
63 DtPrintDefaultProcData* dpd);
64 static int CompareSelectPrinterRecs(const void*,
66 static String CompoundTextToString(
68 unsigned char* compound_text);
69 static XtEnum CreateFileSelectionBox(
72 DtPrintDefaultProcData* dpd);
73 static XtEnum CreatePrinterInfoBox(
76 DtPrintDefaultProcData* dpd);
77 static XtEnum CreatePrinterSelectionBox(
80 DtPrintDefaultProcData* dpd);
81 static void DestroyWidgetCB(
83 XtPointer client_data,
85 static void DtPrintDefProcDestroyCB(Widget w,
86 XtPointer client_data,
88 static void ErrorMessageDestroyCB(
90 XtPointer client_data,
92 static String FindSelectedPrinter(
94 DtPrintDefaultProcData* dpd);
95 static void FreeSelectPrinterData(
96 DtPrintDefaultProcData* dpd);
97 static Widget GetWMShellAncestor(
99 static void HelpDialogDestroyCB(
101 XtPointer client_data,
102 XtPointer call_data);
103 static void InfoBoxLayoutCB(
105 XtPointer client_data,
106 XtPointer call_data);
107 static void ParseFileNameSpec(
108 const char* file_name,
111 static void PresentErrorDialog(
116 static void PresentHelp(
118 const char* help_volume,
119 const char* location_id);
120 static void PresentVerifyError(
123 String printer_spec);
124 static void PrinterInfoDestroyCB(
126 XtPointer client_data,
127 XtPointer call_data);
128 static void PrinterInfoHelpCB(
130 XtPointer client_data,
131 XtPointer call_data);
132 static void SelectFileDestroyCB(
134 XtPointer client_data,
135 XtPointer call_data);
136 static void SelectFileHelpCB(
138 XtPointer client_data,
139 XtPointer call_data);
140 static void SelectPrinterCB(
142 XtPointer client_data,
143 XtPointer call_data);
144 static void SelectPrinterDestroyCB(
146 XtPointer client_data,
147 XtPointer call_data);
148 static void SelectPrinterHelpCB(
150 XtPointer client_data,
151 XtPointer call_data);
152 static void SelectPrinterInfoCB(
154 XtPointer client_data,
155 XtPointer call_data);
156 static void SelectPrinterItemCB(
158 XtPointer client_data,
159 XtPointer call_data);
160 static void SetListBoxSelection(
163 static void UpdateFileNameCB(
165 XtPointer client_data,
166 XtPointer call_data);
169 * ------------------------------------------------------------------------
170 * Name: BuildPrinterLists
174 * Retrieves lists of printers from the Xp server found in the
175 * XpServerList resource or XPSERVERLIST env var.
185 DtPrintDefaultProcData* dpd,
194 XPPrinterList xp_printer_list;
195 DtPrintSelectPrinterList printer_list;
197 * clean up previous lists if needed
199 FreeSelectPrinterData(dpd);
201 * get the list of servers
203 server_list = _DtPrintGetXpServerList(w);
204 if((String*)NULL == server_list)
205 return DtPRINT_FAILURE;
207 * get the printer list for each valid Xp server
209 for(server_count = 0;
210 (String)NULL != server_list[server_count];
212 dpd->xp_server_list =
213 (String*)XtCalloc(server_count, sizeof(String));
214 dpd->printer_lists = (DtPrintSelectPrinterList*)
215 XtCalloc(server_count, sizeof(DtPrintSelectPrinterList));
216 dpd->printer_counts =
217 (int*)XtCalloc(server_count, sizeof(int));
218 for(i = 0, *item_count = 0; i < server_count; i++)
221 * ensure the server is a valid Xp server
223 display = XOpenDisplay(server_list[i]);
224 if((Display*)NULL == display)
226 if(!XpQueryExtension(display, &event_base, &error_base))
228 XCloseDisplay(display);
232 * add the server to the xp server list
234 dpd->xp_server_list[dpd->xp_server_count] =
235 XtNewString(server_list[i]);
237 * get the printer list for the server
240 XpGetPrinterList(display, (char*)NULL,
241 &dpd->printer_counts[dpd->xp_server_count]);
243 * save a copy of the compound text printer name and
244 * string versions of the name and description for
245 * eventual use in the printer selection list.
247 dpd->printer_lists[dpd->xp_server_count] = (DtPrintSelectPrinterList)
248 XtCalloc(dpd->printer_counts[dpd->xp_server_count],
249 sizeof(DtPrintSelectPrinterRec));
250 printer_list = dpd->printer_lists[dpd->xp_server_count];
251 for(j = 0; j < dpd->printer_counts[dpd->xp_server_count]; j++)
253 printer_list[j].printer_name_ct =
254 XtNewString(xp_printer_list[j].name);
255 printer_list[j].printer_name =
256 CompoundTextToString(display,
257 (unsigned char*)xp_printer_list[j].name);
258 printer_list[j].description =
259 CompoundTextToString(display,
260 (unsigned char*)xp_printer_list[j].desc);
262 XpFreePrinterList(xp_printer_list);
264 * sort the printer list
266 if(0 < dpd->printer_counts[dpd->xp_server_count])
267 qsort((void*)printer_list,
268 dpd->printer_counts[dpd->xp_server_count],
269 sizeof(DtPrintSelectPrinterRec), CompareSelectPrinterRecs);
271 *item_count += dpd->printer_counts[dpd->xp_server_count];
272 ++dpd->xp_server_count;
273 XCloseDisplay(display);
275 _DtPrintFreeStringList(server_list);
278 FreeSelectPrinterData(dpd);
279 return DtPRINT_FAILURE;
282 return DtPRINT_SUCCESS;
286 * ------------------------------------------------------------------------
287 * Name: BuildPrinterSelectionItems
291 * Builds the list of XmString items (printer name + desc) to be set
292 * in the printer selection list box.
300 BuildPrinterSelectionItems(
302 DtPrintDefaultProcData* dpd,
304 String initial_printer,
309 char* buf = (char*)NULL;
310 Cardinal buf_size = 0;
313 String name, full_name, desc;
317 items = (XmStringTable)XtCalloc(item_count, sizeof(XmString));
318 for(i = 0, current_item = 0; i < dpd->xp_server_count; i++)
320 server_name = dpd->xp_server_list[i];
321 server_len = strlen(server_name);
323 for(j = 0; j < dpd->printer_counts[i]; j++, current_item++)
326 * build a fully qualified X printer specifier
328 name = (dpd->printer_lists[i])[j].printer_name;
329 (dpd->printer_lists[i])[j].printer_name = (String)NULL;
331 _DtPrintCreateXPrinterSpecifier(name, server_name,
332 DtPRINT_NET_UNSPECIFIED,
336 * check to see if this should be the initially selected printer
338 if(dpd->selected_printer == 0
339 && (String)NULL != initial_printer)
340 if(strcmp(initial_printer, full_name) == 0)
341 dpd->selected_printer = current_item + 1;
343 * convert the printer description
345 desc = (dpd->printer_lists[i])[j].description;
346 (dpd->printer_lists[i])[j].description = (String)NULL;
347 if((String)NULL != desc && '\0' != *desc)
350 * chop the description after the 1st line
352 char* ptr = Dt_strchr(desc, '\n');
353 if((char*)NULL != ptr)
357 * ensure the format buffer is large enough to contain
358 * the formatted list item
361 new_size += full_name ? strlen(full_name) : 0;
362 new_size += desc ? strlen(desc) : 0;
363 if(new_size > buf_size)
366 buf = XtRealloc(buf, buf_size);
369 * format the item, and add it to the item list
371 sprintf(buf, "%s\t%s",
372 full_name ? full_name : "",
376 items[current_item] =
377 XmStringGenerate((XtPointer)buf, (XmStringTag)NULL,
378 XmMULTIBYTE_TEXT, tag);
386 * ------------------------------------------------------------------------
387 * Name: CloseSelectPrinterInfoConnection
391 * Close the X printer connection maintained for the Select Printer
392 * dialog's Printer Information dialog.
400 CloseSelectPrinterInfoConnection(
401 DtPrintDefaultProcData* dpd)
403 if((Display*)NULL != dpd->select_printer_info_display)
405 if((XPContext)None != dpd->select_printer_info_context)
407 XpDestroyContext(dpd->select_printer_info_display,
408 dpd->select_printer_info_context);
409 dpd->select_printer_info_context = (XPContext)None;
411 XCloseDisplay(dpd->select_printer_info_display);
412 dpd->select_printer_info_display = (Display*)NULL;
417 * ------------------------------------------------------------------------
418 * Name: CompareSelectPrinterRecs
422 * Compares the printer names in two DtPrintSelectPrinterRecs.
426 * Returns an integer greater than, equal to, or less than zero,
427 * according to whether the printer name in spr1 is greater
428 * than, equal to, or less than the printer name in spr2.
432 CompareSelectPrinterRecs(const void* spr1,
435 return strcoll(((DtPrintSelectPrinterRec*)spr1)->printer_name,
436 ((DtPrintSelectPrinterRec*)spr2)->printer_name);
440 * ------------------------------------------------------------------------
441 * Name: CompoundTextToString
453 CompoundTextToString(
455 unsigned char* compound_text)
457 String str = (String)NULL;
459 if((unsigned char*)NULL != compound_text)
461 XTextProperty text_prop;
465 text_prop.encoding = XInternAtom(display, "COMPOUND_TEXT", False);
466 text_prop.format = 8;
467 text_prop.value = compound_text;
468 text_prop.nitems = strlen((char*)text_prop.value);
470 XmbTextPropertyToTextList(display, &text_prop, &list, &count))
473 str = XtNewString(list[0]);
474 XFreeStringList(list);
481 * ------------------------------------------------------------------------
482 * Name: CreateFileSelectionBox
486 * Creates the file selection dialog box.
494 CreateFileSelectionBox(
497 DtPrintDefaultProcData* dpd)
501 XmString title_xmstr;
503 title_xmstr = XmStringCreateLocalized(SELECT_FILE_TITLE);
509 XtSetArg(args[n], XmNdialogTitle, title_xmstr); n++;
510 XtSetArg(args[n], XmNdialogStyle,
511 XmDIALOG_PRIMARY_APPLICATION_MODAL); n++;
512 XtSetArg(args[n], XmNdeleteResponse, XmUNMAP); n++;
514 * file selection box resources
516 XtSetArg(args[n], XmNautoUnmanage, True); n++;
518 * create the file selection box dialog
520 dpd->file_selection_box =
521 XmCreateFileSelectionDialog(parent, "_PsubDefProcFileSelectionBox",
523 XmStringFree(title_xmstr);
524 if(dpd->file_selection_box == (Widget)NULL)
525 return DtPRINT_FAILURE;
529 XtAddCallback(dpd->file_selection_box, XmNokCallback,
530 UpdateFileNameCB, (XtPointer)psub);
531 XtAddCallback(dpd->file_selection_box, XmNhelpCallback,
532 SelectFileHelpCB, (XtPointer)psub);
533 XtAddCallback(dpd->file_selection_box, XmNdestroyCallback,
534 SelectFileDestroyCB, (XtPointer)psub);
538 return DtPRINT_SUCCESS;
542 * ------------------------------------------------------------------------
543 * Name: CreatePrinterInfoBox
547 * Creates the printer information dialog box.
555 CreatePrinterInfoBox(
558 DtPrintDefaultProcData* dpd)
562 XmString title_xmstr;
564 Widget description_label, description;
565 Widget name_label, name;
566 Widget format_label, format;
567 Widget model_label, model;
570 title_xmstr = XmStringCreateLocalized(PRINTER_INFO_TITLE);
576 XtSetArg(args[n], XmNdialogTitle, title_xmstr); n++;
577 XtSetArg(args[n], XmNdialogStyle,
578 XmDIALOG_PRIMARY_APPLICATION_MODAL); n++;
579 XtSetArg(args[n], XmNdeleteResponse, XmUNMAP); n++;
581 * printer info box resources
583 XtSetArg(args[n], XmNautoUnmanage, True); n++;
587 dpd->printer_info_box =
588 XmCreateInformationDialog(parent, "_PsubDefProcPrinterInfoBox",
590 XmStringFree(title_xmstr);
591 if(dpd->printer_info_box == (Widget)NULL)
592 return DtPRINT_FAILURE;
596 XtAddCallback(dpd->printer_info_box, XmNhelpCallback,
597 PrinterInfoHelpCB, (XtPointer)psub);
598 XtAddCallback(dpd->printer_info_box, XmNdestroyCallback,
599 PrinterInfoDestroyCB, (XtPointer)psub);
600 XtAddCallback(dpd->printer_info_box, XmNmapCallback,
601 InfoBoxLayoutCB, (XtPointer)dpd);
603 * unmanage unwanted children
605 XtUnmanageChild(XtNameToWidget(dpd->printer_info_box, "Cancel"));
606 XtUnmanageChild(XtNameToWidget(dpd->printer_info_box, "Message"));
607 XtUnmanageChild(XtNameToWidget(dpd->printer_info_box, "Symbol"));
609 * create the control manager
612 XtVaCreateManagedWidget("PrinterInfoForm", xmFormWidgetClass,
613 dpd->printer_info_box,
614 XmNallowOverlap, False,
617 * printer description
619 label = XmStringCreateLocalized(DESCRIPTION_LABEL);
621 XtVaCreateManagedWidget("DescriptionLabel",
624 XmNlabelString, label,
625 XmNleftAttachment, XmATTACH_FORM,
626 XmNtopAttachment, XmATTACH_FORM,
631 XtVaCreateManagedWidget("Description",
634 XmNalignment, XmALIGNMENT_BEGINNING,
635 XmNleftAttachment, XmATTACH_WIDGET,
636 XmNleftWidget, description_label,
638 XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
639 XmNtopWidget, description_label,
644 label = XmStringCreateLocalized(PRINTER_NAME_LABEL);
646 XtVaCreateManagedWidget("NameLabel",
649 XmNlabelString, label,
650 XmNleftAttachment, XmATTACH_FORM,
651 XmNtopAttachment, XmATTACH_WIDGET,
652 XmNtopWidget, description,
657 XtVaCreateManagedWidget("Name",
660 XmNleftAttachment, XmATTACH_WIDGET,
661 XmNleftWidget, name_label,
663 XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
664 XmNtopWidget, name_label,
669 label = XmStringCreateLocalized(FORMAT_LABEL);
671 XtVaCreateManagedWidget("FormatLabel",
674 XmNlabelString, label,
675 XmNleftAttachment, XmATTACH_FORM,
676 XmNtopAttachment, XmATTACH_WIDGET,
677 XmNtopWidget, name_label,
682 XtVaCreateManagedWidget("Format",
685 XmNleftAttachment, XmATTACH_WIDGET,
686 XmNleftWidget, format_label,
688 XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
689 XmNtopWidget, format_label,
694 label = XmStringCreateLocalized(MODEL_LABEL);
696 XtVaCreateManagedWidget("ModelLabel",
699 XmNlabelString, label,
700 XmNleftAttachment, XmATTACH_FORM,
701 XmNtopAttachment, XmATTACH_WIDGET,
702 XmNtopWidget, format_label,
707 XtVaCreateManagedWidget("Model",
710 XmNalignment, XmALIGNMENT_BEGINNING,
711 XmNleftAttachment, XmATTACH_WIDGET,
712 XmNleftWidget, model_label,
714 XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
715 XmNtopWidget, model_label,
720 return DtPRINT_SUCCESS;
724 * ------------------------------------------------------------------------
725 * Name: CreatePrinterSelectionBox
729 * Creates the printer selection dialog box.
737 CreatePrinterSelectionBox(
740 DtPrintDefaultProcData* dpd)
746 XmString title_xmstr;
749 title_xmstr = XmStringCreateLocalized(MORE_PRINTERS_TITLE);
750 list_label = XmStringCreateLocalized(PRINTER_LIST_LABEL);
751 info_label = XmStringCreateLocalized(PRINTER_INFO_LABEL);
757 XtSetArg(args[n], XmNdialogTitle, title_xmstr); n++;
758 XtSetArg(args[n], XmNdialogStyle,
759 XmDIALOG_PRIMARY_APPLICATION_MODAL); n++;
760 XtSetArg(args[n], XmNdeleteResponse, XmDESTROY); n++;
762 * selection box resources
764 XtSetArg(args[n], XmNautoUnmanage, True); n++;
765 XtSetArg(args[n], XmNlistLabelString, list_label); n++;
766 XtSetArg(args[n], XmNapplyLabelString, info_label); n++;
770 dpd->printer_selection_box =
771 XmCreateSelectionDialog(parent, "_PsubDefProcPrinterSelectionBox",
773 XmStringFree(list_label);
774 XmStringFree(info_label);
775 XmStringFree(title_xmstr);
776 if(dpd->printer_selection_box == (Widget)NULL)
777 return DtPRINT_FAILURE;
781 XtAddCallback(dpd->printer_selection_box, XmNokCallback,
782 SelectPrinterCB, (XtPointer)psub);
783 XtAddCallback(dpd->printer_selection_box, XmNapplyCallback,
784 SelectPrinterInfoCB, (XtPointer)psub);
785 XtAddCallback(dpd->printer_selection_box, XmNcancelCallback,
786 SelectPrinterCB, (XtPointer)psub);
787 XtAddCallback(dpd->printer_selection_box, XmNhelpCallback,
788 SelectPrinterHelpCB, (XtPointer)psub);
789 XtAddCallback(dpd->printer_selection_box, XmNdestroyCallback,
790 SelectPrinterDestroyCB, (XtPointer)psub);
792 * get the list box widget ID
794 dpd->printer_list_box =
795 XtNameToWidget(dpd->printer_selection_box, "*ItemsList");
796 XtAddCallback(dpd->printer_list_box, XmNbrowseSelectionCallback,
797 SelectPrinterItemCB, (XtPointer)psub);
799 * unmanaged unwanted children
801 control = XtNameToWidget(dpd->printer_selection_box, "*Selection");
802 if(control != (Widget)NULL)
803 XtUnmanageChild(control);
804 control = XtNameToWidget(dpd->printer_selection_box, "*Text");
805 if(control != (Widget)NULL)
806 XtUnmanageChild(control);
810 return DtPRINT_SUCCESS;
814 * ------------------------------------------------------------------------
815 * Name: DestroyWidgetCB
819 * Destroys the Widget passed as client_data.
829 XtPointer client_data,
832 XtDestroyWidget((Widget)client_data);
836 * ------------------------------------------------------------------------
837 * Name: DtPrintDefProcDestroyCB
841 * Free resources allocated for the default procedure data structure
842 * in response to the destruction of the DtPrintSetupBox.
844 * Calls destroy callbacks for dialogs *directly* because the dialogs
845 * aren't children of the DtPrintSetupBox, but instead are more like
846 * siblings or cousins of the PrintSetupBox whose common ancestor is
847 * the shell parent of the PrintSetupBox. As such the dialogs may or
848 * may not otherwise be destroyed when the PrintSetupBox is
849 * destroyed. Furthermore the 2nd phase of the XtDestroyWidget calls
850 * made in this routine isn't reached until after the PrintSetupBox
851 * instance record has been destroyed (as part of the destroy phase
852 * of which *this* call is a part).
854 * The main reason this is a concern is because data associated with
855 * these dialogs is stored in the PrintSetupBox widget instance
864 DtPrintDefProcDestroyCB(Widget w,
865 XtPointer client_data,
868 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
870 if(dpd->error_message_box)
872 XtRemoveCallback(dpd->error_message_box, XmNdestroyCallback,
873 ErrorMessageDestroyCB, (XtPointer)w);
874 XtDestroyWidget(dpd->error_message_box);
875 ErrorMessageDestroyCB(dpd->error_message_box,
876 (XtPointer)w, (XtPointer)NULL);
880 XtRemoveCallback(dpd->help_dialog, XmNdestroyCallback,
881 HelpDialogDestroyCB, (XtPointer)w);
882 XtDestroyWidget(dpd->help_dialog);
883 HelpDialogDestroyCB(dpd->help_dialog,
884 (XtPointer)w, (XtPointer)NULL);
886 if(dpd->file_selection_box)
888 XtRemoveCallback(dpd->file_selection_box, XmNdestroyCallback,
889 SelectFileDestroyCB, (XtPointer)w);
890 XtDestroyWidget(dpd->file_selection_box);
891 SelectFileDestroyCB(dpd->file_selection_box,
892 (XtPointer)w, (XtPointer)NULL);
894 if(dpd->printer_selection_box)
896 XtRemoveCallback(dpd->printer_selection_box, XmNdestroyCallback,
897 SelectPrinterDestroyCB, (XtPointer)w);
898 XtDestroyWidget(dpd->printer_selection_box);
899 SelectPrinterDestroyCB(dpd->printer_selection_box,
900 (XtPointer)w, (XtPointer)NULL);
902 if(dpd->printer_info_box)
904 XtRemoveCallback(dpd->printer_info_box, XmNdestroyCallback,
905 PrinterInfoDestroyCB, (XtPointer)w);
906 XtDestroyWidget(dpd->printer_info_box);
907 PrinterInfoDestroyCB(dpd->printer_info_box,
908 (XtPointer)w, (XtPointer)NULL);
914 * ------------------------------------------------------------------------
915 * Name: ErrorMessageDestroyCB
919 * Reset the error message widget ID instance data when the message
922 * This callback is considered part of the default resource
923 * procedures and not part of the setup box widget proper.
931 ErrorMessageDestroyCB(
933 XtPointer client_data,
936 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(client_data);
938 dpd->error_message_box = (Widget)NULL;
942 * ------------------------------------------------------------------------
943 * Name: FindSelectedPrinter
947 * Build a full printer name by locating the currently selected
948 * printer in the server list and printer list.
953 * A newly allocated full printer name. It is the caller's
954 * responsibility to free the returned String by calling XtFree.
960 DtPrintDefaultProcData* dpd)
967 * return if any of the structures are not in place
969 if(dpd->xp_server_list == (String*)NULL
971 dpd->printer_counts == (int*)NULL
973 dpd->printer_lists == (DtPrintSelectPrinterList*)NULL)
978 * find the printer list containing the selected printer
980 if(0 == dpd->selected_printer)
983 printer_index = dpd->selected_printer - 1;
985 for(i = 0, printer_count = 0; i < dpd->xp_server_count; i++)
987 if(printer_index < printer_count + (dpd->printer_counts)[i])
990 printer_count += (dpd->printer_counts)[i];
992 if(i < dpd->xp_server_count)
995 * build and return the printer name
997 DtPrintSelectPrinterList printer_list;
1000 char* printer_name_ct;
1003 display_spec = (dpd->xp_server_list)[i];
1004 printer_list = (dpd->printer_lists)[i];
1006 printer_list[printer_index - printer_count].printer_name_ct;
1008 CompoundTextToString(display, (unsigned char*)printer_name_ct);
1009 if((String)NULL != printer_name)
1012 _DtPrintCreateXPrinterSpecifier(printer_name,
1014 DtPRINT_NET_UNSPECIFIED,
1016 XtFree(printer_name);
1017 return printer_spec;
1020 return (String)NULL;
1024 * ------------------------------------------------------------------------
1025 * Name: FreeSelectPrinterData
1029 * Deallocate and reset data items associated with the printer
1037 FreeSelectPrinterData(
1038 DtPrintDefaultProcData* dpd)
1041 DtPrintSelectPrinterList printer_list;
1043 for(i = 0; i < dpd->xp_server_count; i++)
1045 printer_list = dpd->printer_lists[i];
1046 for(j = 0; j < dpd->printer_counts[i]; j++)
1048 XtFree(printer_list[j].printer_name_ct);
1050 XtFree((char*)printer_list);
1052 XtFree((char*)dpd->printer_lists);
1053 dpd->printer_lists = (DtPrintSelectPrinterList*)NULL;
1054 XtFree((char*)dpd->xp_server_list);
1055 dpd->xp_server_list = (String*)NULL;
1056 dpd->xp_server_count = 0;
1057 dpd->selected_printer = 0;
1061 * ------------------------------------------------------------------------
1062 * Name: GetWMShellAncestor
1066 * Obtains the widget ID of the closest WMShell ancestor for
1067 * the passed widget.
1071 * The widget ID of the closest WMShell ancestor.
1075 GetWMShellAncestor(Widget w)
1077 Widget wmshell_ancestor = XtParent(w);
1078 while(wmshell_ancestor != (Widget)NULL)
1080 if(XtIsWMShell(wmshell_ancestor))
1083 wmshell_ancestor = XtParent(wmshell_ancestor);
1085 return wmshell_ancestor;
1089 * ------------------------------------------------------------------------
1090 * Name: HelpDialogDestroyCB
1094 * Reset the help dialog widget ID instance data when the widget
1097 * This callback is considered part of the default resource
1098 * procedures and not part of the setup box widget proper.
1106 HelpDialogDestroyCB(
1108 XtPointer client_data,
1109 XtPointer call_data)
1111 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(client_data);
1113 dpd->help_dialog = (Widget)NULL;
1117 * ------------------------------------------------------------------------
1118 * Name: InfoBoxLayoutCB
1122 * Callback to right justify printer information dialog labels at
1134 XtPointer client_data,
1135 XtPointer call_data)
1137 DtPrintDefaultProcData* dpd = (DtPrintDefaultProcData*)client_data;
1140 Dimension width, max_width;
1142 * only need to do this once after the widget is created
1144 XtRemoveCallback(widget, XmNmapCallback, InfoBoxLayoutCB, client_data);
1146 * get the label widget ids
1148 w[0] = XtNameToWidget(dpd->printer_info_box,
1149 "PrinterInfoForm.DescriptionLabel");
1150 w[1] = XtNameToWidget(dpd->printer_info_box,
1151 "PrinterInfoForm.NameLabel");
1152 w[2] = XtNameToWidget(dpd->printer_info_box,
1153 "PrinterInfoForm.FormatLabel");
1154 w[3] = XtNameToWidget(dpd->printer_info_box,
1155 "PrinterInfoForm.ModelLabel");
1157 * find the widest label
1159 for(i = 0, widest = 0, max_width = 0; i < 4; i++)
1161 XtVaGetValues(w[i], XmNwidth, &width, NULL);
1162 if(width > max_width)
1169 * sever the top attachment on the widest label in order to avoid
1170 * circular dependencies in form children; apparently one of the form
1171 * widget's many talents is the inability to manage the vertical and
1172 * horizontal attachments independently...
1174 XtVaSetValues(w[widest], XmNtopAttachment, XmATTACH_SELF, NULL);
1176 * attach the right side of the smaller labels to the right side of
1179 for(i = 0; i < 4; i++)
1182 XmNleftAttachment, XmATTACH_NONE,
1183 XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET,
1184 XmNrightWidget, w[widest],
1189 * ------------------------------------------------------------------------
1190 * Name: ParseFileNameSpec
1194 * Parse the passed file name to create a file selection box filter
1195 * pattern and the name only portion of the full name spec.
1197 * It is the caller's responsibility to free the allocated memory
1198 * returned in 'pattern' and 'name_only' using XmStringFree and
1199 * XtFree respectively.
1208 ParseFileNameSpec(const char* file_name,
1209 XmString* pattern_xmstr,
1215 * start off with a copy of the file name, ensuring there is
1216 * enough space for the added "*" and the string terminator.
1218 pattern = XtMalloc(strlen(file_name)+2);
1219 strcpy(pattern, file_name);
1221 * find the last slash
1223 ptr = DtStrrchr(pattern, '/');
1224 if(ptr != (String)NULL)
1227 * grab the name portion of the file name
1229 *name_only = XtNewString(ptr+1);
1231 * set the wildcard character immediately following the last
1235 *pattern_xmstr = XmStringCreateLocalized(pattern);
1240 * no slash found; use the default pattern
1242 *pattern_xmstr = (XmString)NULL;
1243 *name_only = XtNewString(file_name);
1249 * ------------------------------------------------------------------------
1250 * Name: PresentErrorDialog
1254 * This is a utility function that will present an Error Dialog. It
1255 * takes a title, a message, and a variable list of Strings to
1256 * include in the message. The message parm is treated like a
1257 * printf-style format string, except that only the "%s" directive is
1260 * This function is to be used exclusively by the default
1261 * resource procedures (e.g. _DtPrintSetupBoxVerifyXPrinterProc).
1263 * The variable list of String parms must be terminated by
1280 String expanded_message;
1282 XmString message_xmstr;
1283 XmString title_xmstr;
1286 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
1287 Widget wmshell_ancestor;
1288 WidgetList wmshell_ancestors_children = (WidgetList)NULL;
1290 wmshell_ancestor = GetWMShellAncestor(w);
1292 if (wmshell_ancestor)
1295 XtSetArg(args[n], XmNchildren, &wmshell_ancestors_children); n++;
1296 XtGetValues(wmshell_ancestor, args, n);
1299 if(dpd->error_message_box != (Widget)NULL)
1302 * present only one message box
1304 XtDestroyWidget(dpd->error_message_box);
1307 title_xmstr = XmStringCreateLocalized(title);
1309 * determine length of expanded message
1311 message_len = strlen(message);
1312 va_start(arg_marker, message);
1313 while((str_n = va_arg(arg_marker, String)) != (String)NULL)
1315 message_len += strlen(str_n);
1320 * expand the message
1322 expanded_message = XtMalloc(message_len);
1323 va_start(arg_marker, message);
1324 vsprintf(expanded_message, message, arg_marker);
1327 * convert message to XmString
1329 message_xmstr = XmStringCreateLocalized(expanded_message);
1330 XtFree(expanded_message);
1332 * create the error dialog
1335 XtSetArg(args[n], XmNdialogTitle, title_xmstr); n++;
1336 XtSetArg(args[n], XmNmessageString, message_xmstr); n++;
1337 XtSetArg(args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); n++;
1338 XtSetArg(args[n], XmNdeleteResponse, XmDESTROY); n++;
1339 dpd->error_message_box =
1340 XmCreateErrorDialog(wmshell_ancestors_children ?
1341 wmshell_ancestors_children[0] :
1343 "_PsubDefProcErrorMsg", args, n);
1344 XmStringFree(title_xmstr);
1345 XmStringFree(message_xmstr);
1347 XtUnmanageChild(XtNameToWidget(dpd->error_message_box, "Cancel"));
1348 XtUnmanageChild(XtNameToWidget(dpd->error_message_box, "Help"));
1350 XtAddCallback(dpd->error_message_box, XmNokCallback,
1351 DestroyWidgetCB, (XtPointer)dpd->error_message_box);
1352 XtAddCallback(dpd->error_message_box, XmNcancelCallback,
1353 DestroyWidgetCB, (XtPointer)dpd->error_message_box);
1354 XtAddCallback(dpd->error_message_box, XmNdestroyCallback,
1355 ErrorMessageDestroyCB, (XtPointer)w);
1357 * manage the message box according to the hint
1359 if(DtPRINT_HINT_MESSAGES_OK == dpd->messages_hint)
1360 XtManageChild(dpd->error_message_box);
1362 #ifdef XXX_JUNGLE_REMOVE
1364 * manage the message box only if the psub is mapped
1365 * and the focus is not in the printer name field
1368 XWindowAttributes attr;
1370 Window window = XtWindow(w);
1373 status = XGetWindowAttributes(XtDisplay(w), window, &attr);
1374 if(status == 0 || attr.map_state == IsViewable)
1376 Widget name_w = XtNameToWidget(w, "Name");
1379 for(child = XmGetFocusWidget(w);
1380 child != wmshell_ancestor && child != name_w
1381 && child != (Widget)NULL;
1382 child = XtParent(child));
1384 if(child != name_w && child != (Widget)NULL)
1385 XtManageChild(dpd->error_message_box);
1389 #endif /* XXX_JUNGLE_REMOVE */
1393 * ------------------------------------------------------------------------
1398 * Presents a help dialog whose widget instance may be shared between
1399 * the default dialogs.
1406 static void PresentHelp(
1408 const char* help_volume,
1409 const char* location_id)
1411 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
1412 Widget wmshell_ancestor;
1413 Widget dialog_shell;
1419 wmshell_ancestor = GetWMShellAncestor(w);
1421 if((Widget)NULL == dpd->help_dialog)
1428 title = XmStringCreateLocalized(HELP_DLG_TITLE);
1429 XtSetArg(args[n], XmNdialogTitle, title); n++;
1431 DtCreateHelpDialog(wmshell_ancestor, "_PsubDefProcHelpDialog",
1433 XmStringFree(title);
1434 XtAddCallback(dpd->help_dialog, XmNdestroyCallback,
1435 HelpDialogDestroyCB, (XtPointer)w);
1438 * set the help volume and location
1440 XtVaSetValues(dpd->help_dialog,
1441 DtNhelpVolume, help_volume,
1442 DtNlocationId, location_id,
1443 DtNhelpType, DtHELP_TYPE_TOPIC,
1446 * pop up the help dialog
1448 XtManageChild(dpd->help_dialog);
1449 dialog_shell = XtParent(dpd->help_dialog);
1450 if(None != XtWindow(dialog_shell))
1451 XRaiseWindow(XtDisplay(dialog_shell), XtWindow(dialog_shell));
1455 * ------------------------------------------------------------------------
1456 * Name: PresentVerifyError
1460 * Presents a error dialog appropriate for an error status returned
1461 * by _DtPrintVerifyXPrinter.
1472 String printer_spec)
1474 String printer_name;
1475 String display_spec;
1477 _DtPrintParseXPrinterSpecifier(printer_spec,
1482 case DtPRINT_PRINTER_MISSING:
1483 PresentErrorDialog(w, INVALID_PRINTER_TITLE,
1484 PRINTER_MISSING_MESSAGE,
1489 case DtPRINT_NO_DEFAULT:
1490 PresentErrorDialog(w, INVALID_PRINTER_TITLE,
1495 case DtPRINT_NO_DEFAULT_DISPLAY:
1496 PresentErrorDialog(w, INVALID_PRINTER_TITLE,
1497 NO_DEFAULT_DISPLAY_MESSAGE,
1502 case DtPRINT_NO_PRINTER:
1503 PresentErrorDialog(w, INVALID_PRINTER_TITLE,
1504 INVALID_PRINTER_MESSAGE,
1505 printer_name, display_spec,
1509 case DtPRINT_NOT_XP_DISPLAY:
1510 PresentErrorDialog(w, INVALID_PRINTER_TITLE,
1511 NOT_XP_DISPLAY_MESSAGE,
1516 case DtPRINT_INVALID_DISPLAY:
1517 PresentErrorDialog(w, INVALID_PRINTER_TITLE,
1518 INVALID_DISPLAY_MESSAGE,
1523 XtFree(printer_name);
1524 XtFree(display_spec);
1529 * ------------------------------------------------------------------------
1530 * Name: PrinterInfoDestroyCB
1534 * Reset data items used in conjunction with the
1535 * printer information selection dialog.
1543 PrinterInfoDestroyCB(
1545 XtPointer client_data,
1546 XtPointer call_data)
1548 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(client_data);
1550 dpd->printer_info_box = (Widget)NULL;
1554 * ------------------------------------------------------------------------
1555 * Name: PrinterInfoHelpCB
1559 * Display context sensitive help.
1569 XtPointer client_data,
1570 XtPointer call_data)
1572 PresentHelp((Widget)client_data, HELP_VOLUME, PRINTER_INFO_HELP_ID);
1576 * ------------------------------------------------------------------------
1577 * Name: SelectFileDestroyCB
1581 * Reset data items used in conjunction with the
1582 * file selection dialog.
1590 SelectFileDestroyCB(
1592 XtPointer client_data,
1593 XtPointer call_data)
1595 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(client_data);
1597 dpd->file_selection_box = (Widget)NULL;
1601 * ------------------------------------------------------------------------
1602 * Name: SelectFileHelpCB
1606 * Display context sensitive help.
1616 XtPointer client_data,
1617 XtPointer call_data)
1619 PresentHelp((Widget)client_data, HELP_VOLUME, SELECT_FILE_HELP_ID);
1623 * ------------------------------------------------------------------------
1624 * Name: SelectPrinterCB
1628 * Callback to handle the printer selection box OK and Cancel
1639 XtPointer client_data,
1640 XtPointer call_data)
1642 XmSelectionBoxCallbackStruct* cbs =
1643 (XmSelectionBoxCallbackStruct*)call_data;
1644 Widget psub = (Widget)client_data;
1645 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(psub);
1647 String printer_spec;
1650 * close the info dialog display connection if it's been opened
1652 CloseSelectPrinterInfoConnection(dpd);
1658 * set the selected printer name in the PrintSetupBox
1660 printer_spec = FindSelectedPrinter(XtDisplay(psub), dpd);
1661 if((String)NULL != printer_spec)
1663 XtVaSetValues(psub, DtNprinterName, printer_spec, NULL);
1664 XtFree(printer_spec);
1672 * deallocate and reset the lists
1674 FreeSelectPrinterData(dpd);
1675 if(dpd->printer_list_box != (Widget)NULL)
1676 XmListDeleteAllItems(dpd->printer_list_box);
1682 * ------------------------------------------------------------------------
1683 * Name: SelectPrinterDestroyCB
1687 * Deallocate and reset data items used in conjunction with the
1688 * printer selection dialog.
1696 SelectPrinterDestroyCB(
1698 XtPointer client_data,
1699 XtPointer call_data)
1701 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(client_data);
1703 dpd->printer_selection_box = (Widget)NULL;
1704 dpd->printer_list_box = (Widget)NULL;
1705 CloseSelectPrinterInfoConnection(dpd);
1706 FreeSelectPrinterData(dpd);
1710 * ------------------------------------------------------------------------
1711 * Name: SelectPrinterHelpCB
1715 * Display context sensitive help.
1723 SelectPrinterHelpCB(
1725 XtPointer client_data,
1726 XtPointer call_data)
1728 PresentHelp((Widget)client_data, HELP_VOLUME, SELECT_PRINTER_HELP_ID);
1732 * ------------------------------------------------------------------------
1733 * Name: SelectPrinterInfoCB
1737 * Callback attached to the printer selection box "Info..."
1738 * button. The "Info..." button is intended to behave just like the
1739 * PrintSetupBox "Info..." button, so it is implemented to call the
1740 * procedure set for the PrintSetupBox DtNprinterInfoProc resource.
1741 * As such, this function needs to open a new display connection to
1742 * the print server indicated by the currently selected printer in
1743 * the list. The connection is not closed until a selection is made
1744 * in the list, or the printer selection dialog is dismissed. This is
1745 * because no assumptions about the Printer Info dialog's widget
1746 * heirarchy can be made.
1754 SelectPrinterInfoCB(
1756 XtPointer client_data,
1757 XtPointer call_data)
1759 Widget psub = (Widget)client_data;
1760 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(psub);
1761 DtPrintSetupProc info_proc;
1763 CloseSelectPrinterInfoConnection(dpd);
1764 XtVaGetValues(psub, DtNprinterInfoProc, &info_proc, NULL);
1765 if((DtPrintSetupProc)NULL != info_proc)
1767 String printer_spec;
1769 printer_spec = FindSelectedPrinter(XtDisplay(psub), dpd);
1770 if((String)NULL != printer_spec)
1772 String new_printer_spec; /*
1773 * will always be set to NULL by
1774 * _DtPrintVerifyXPrinter when
1775 * called from within this routine
1780 * open a connection to the X printer
1783 _DtPrintVerifyXPrinter(psub,
1786 &dpd->select_printer_info_display,
1787 &dpd->select_printer_info_context);
1788 if(status == DtPRINT_SUCCESS)
1790 DtPrintSetupData psd;
1792 memset(&psd, 0, sizeof(DtPrintSetupData));
1793 psd.printer_name = printer_spec;
1794 psd.print_display = dpd->select_printer_info_display;
1795 psd.print_context = dpd->select_printer_info_context;
1796 (*info_proc)(psub, &psd);
1801 * this should only happen if, while a user is viewing
1802 * the printer selection dialog, a server rehash is
1803 * performed that deletes the currently selected printer
1805 PresentVerifyError(w, status, printer_spec);
1807 XtFree(printer_spec);
1813 * ------------------------------------------------------------------------
1814 * Name: SelectPrinterItemCB
1818 * Callback to handle the a selection in the printer selection list
1827 SelectPrinterItemCB(
1829 XtPointer client_data,
1830 XtPointer call_data)
1832 XmListCallbackStruct* cbs =
1833 (XmListCallbackStruct*)call_data;
1834 Widget psub = (Widget)client_data;
1835 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(psub);
1838 if(dpd->selected_printer != cbs->item_position)
1840 dpd->selected_printer = cbs->item_position;
1841 info_button = XtNameToWidget(dpd->printer_selection_box, "*Apply");
1842 if(0 == dpd->selected_printer)
1843 XtSetSensitive(info_button, False);
1845 XtSetSensitive(info_button, True);
1847 * update the default printer info dialog if it is visible
1849 if(dpd->printer_info_box && XtIsManaged(dpd->printer_info_box))
1850 SelectPrinterInfoCB(w, client_data, (XtPointer)NULL);
1855 * ------------------------------------------------------------------------
1856 * Name: SetListBoxSelection
1867 SetListBoxSelection(Widget list_box, int position)
1869 int visible_item_count;
1872 int first_visible_pos;
1874 * Scroll the list, making the item at the indicated position
1875 * visible in the center of the list box, and make
1876 * it the initial selection.
1878 XtVaGetValues(list_box,
1879 XmNitemCount, &item_count,
1880 XmNvisibleItemCount, &visible_item_count,
1883 if(item_count > visible_item_count)
1885 middle_offset = (visible_item_count+1) / 2;
1886 if(position > middle_offset)
1887 if(position > item_count - middle_offset)
1888 first_visible_pos = item_count - visible_item_count +1;
1890 first_visible_pos = position - middle_offset + 1;
1892 first_visible_pos = 1;
1893 XmListSetPos(list_box, first_visible_pos);
1897 XmListSelectPos(list_box, position, True);
1899 XmListDeselectAllItems(list_box);
1903 * ------------------------------------------------------------------------
1904 * Name: UpdateFileNameCB
1908 * Updates the PrintSetupBox fileName resource based on the selection
1909 * make in the file selection box.
1919 XtPointer client_data,
1920 XtPointer call_data)
1923 Widget psub = (Widget)client_data;
1926 * get the file name from the file selection box text field
1928 text_field = XtNameToWidget(w, "Text");
1931 XtVaGetValues(text_field, XmNvalue, &file_name, NULL);
1935 * set the file name in the print setup box
1937 XtVaSetValues(psub, DtNfileName, file_name, NULL);
1939 * free the file name retrieved from the text field
1947 * ------------------------------------------------------------------------
1948 * Name: _DtPrintDefProcInitialize
1959 _DtPrintDefProcInitialize(Widget w)
1961 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
1963 dpd->error_message_box = (Widget)NULL;
1964 dpd->messages_hint = DtPRINT_HINT_MESSAGES_OK;
1965 dpd->help_dialog = (Widget)NULL;
1966 dpd->file_selection_box = (Widget)NULL;
1967 dpd->printer_selection_box = (Widget)NULL;
1968 dpd->printer_list_box = (Widget)NULL;
1969 dpd->xp_server_list = (String*)NULL;
1970 dpd->xp_server_count = 0;
1971 dpd->printer_lists = (DtPrintSelectPrinterList*)NULL;
1972 dpd->selected_printer = 0;
1973 dpd->select_printer_info_display = (Display*)NULL;
1974 dpd->select_printer_info_context = (XPContext)None;
1975 dpd->printer_info_box = (Widget)NULL;
1977 XtAddCallback(w, XmNdestroyCallback,
1978 DtPrintDefProcDestroyCB, (XtPointer)NULL);
1982 * ------------------------------------------------------------------------
1983 * Name: _DtPrintDefProcManageErrorBox
1987 * Manage the Error Message Box if it exists.
1994 _DtPrintDefProcManageErrorBox(
1995 DtPrintDefaultProcData* dpd)
1997 if(dpd->error_message_box != (Widget)NULL)
1998 XtManageChild(dpd->error_message_box);
2002 * ------------------------------------------------------------------------
2003 * Name: _DtPrintSetupBoxXPrinterInfoProc
2007 * Default Xp mode function for the DtNprinterInfoProc resource.
2014 _DtPrintSetupBoxXPrinterInfoProc(
2016 DtPrintSetupData* print_data)
2018 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
2019 Widget wmshell_ancestor;
2022 char* attr_value_ct;
2024 XmString empty_label;
2025 Widget name_label_top;
2028 Widget manager = NULL;
2029 Widget dialog_shell;
2031 wmshell_ancestor = GetWMShellAncestor(w);
2032 _DtTurnOnHourGlass(wmshell_ancestor);
2033 empty_label = XmStringCreateLocalized("");
2035 * if needed, create the printer information dialog
2037 if(dpd->printer_info_box == (Widget)NULL)
2039 XtEnum status = CreatePrinterInfoBox(wmshell_ancestor, w, dpd);
2040 if(status != DtPRINT_SUCCESS)
2042 _DtTurnOffHourGlass(wmshell_ancestor);
2045 dialog_shell = XtParent(dpd->printer_info_box);
2050 * hide the widget during re-layout
2052 manager = XtNameToWidget(dpd->printer_info_box, "*PrinterInfoForm");
2053 XtUnmapWidget(dpd->printer_info_box);
2054 dialog_shell = XtParent(dpd->printer_info_box);
2055 XtVaSetValues(dialog_shell, XmNallowShellResize, False, NULL);
2056 XtUnmanageChild(manager);
2061 ctl = XtNameToWidget(dpd->printer_info_box, "*Description");
2062 XtVaSetValues(ctl, XmNlabelString, empty_label, NULL);
2063 attr_value_ct = XpGetOneAttribute(print_data->print_display,
2064 print_data->print_context,
2067 if((char*)NULL != attr_value_ct)
2070 CompoundTextToString(XtDisplay(w), (unsigned char*)attr_value_ct);
2071 XFree(attr_value_ct);
2072 if((String)NULL != attr_value)
2074 label = XmStringGenerate((XtPointer)attr_value, (XmStringTag)NULL,
2075 XmMULTIBYTE_TEXT, (XmStringTag)NULL);
2077 XtVaSetValues(ctl, XmNlabelString, label, NULL);
2078 XmStringFree(label);
2082 * set the top attachment for the name label
2084 XtVaGetValues(ctl, XmNy, &y, XmNheight, &height, NULL);
2086 name_label_top = ctl;
2087 ctl = XtNameToWidget(dpd->printer_info_box, "*DescriptionLabel");
2088 XtVaGetValues(ctl, XmNy, &y, XmNheight, &height, NULL);
2089 if(y+height > max_y)
2090 name_label_top = ctl;
2091 ctl = XtNameToWidget(dpd->printer_info_box, "*NameLabel");
2092 XtVaSetValues(ctl, XmNtopWidget, name_label_top, NULL);
2096 ctl = XtNameToWidget(dpd->printer_info_box, "*Name");
2097 label = XmStringCreateLocalized(print_data->printer_name);
2098 XtVaSetValues(ctl, XmNlabelString, label, NULL);
2099 XmStringFree(label);
2103 ctl = XtNameToWidget(dpd->printer_info_box, "*Format");
2104 XtVaSetValues(ctl, XmNlabelString, empty_label, NULL);
2105 attr_value = XpGetOneAttribute(print_data->print_display,
2106 print_data->print_context,
2109 if((String)NULL != attr_value)
2112 format_start = strchr(attr_value, '{');
2113 if((char*)NULL != format_start)
2117 format_end = strchr(format_start, '}');
2118 if((char*)NULL != format_end)
2121 label = XmStringCreateLocalized(format_start);
2122 XtVaSetValues(ctl, XmNlabelString, label, NULL);
2123 XmStringFree(label);
2131 ctl = XtNameToWidget(dpd->printer_info_box, "*Model");
2132 XtVaSetValues(ctl, XmNlabelString, empty_label, NULL);
2133 attr_value_ct = XpGetOneAttribute(print_data->print_display,
2134 print_data->print_context,
2137 if((char*)NULL != attr_value_ct)
2140 CompoundTextToString(XtDisplay(w), (unsigned char*)attr_value_ct);
2141 XFree(attr_value_ct);
2142 if((String)NULL != attr_value)
2144 label = XmStringGenerate((XtPointer)attr_value, (XmStringTag)NULL,
2145 XmCHARSET_TEXT, (XmStringTag)NULL);
2147 XtVaSetValues(ctl, XmNlabelString, label, NULL);
2148 XmStringFree(label);
2152 * pop up the printer info dialog and return
2154 XmStringFree(empty_label);
2157 XtVaSetValues(dialog_shell, XmNallowShellResize, True, NULL);
2158 XtManageChild(manager);
2159 XtMapWidget(dpd->printer_info_box);
2161 XtManageChild(dpd->printer_info_box);
2162 if(None != XtWindow(dialog_shell))
2163 XRaiseWindow(XtDisplay(dialog_shell), XtWindow(dialog_shell));
2164 _DtTurnOffHourGlass(wmshell_ancestor);
2165 return DtPRINT_SUCCESS;
2169 * ------------------------------------------------------------------------
2170 * Name: _DtPrintSetupBoxSelectFileProc
2174 * Default function for the DtNselectFileProc resource.
2181 _DtPrintSetupBoxSelectFileProc(
2183 DtPrintSetupData* print_data)
2185 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
2191 Widget wmshell_ancestor;
2193 wmshell_ancestor = GetWMShellAncestor(w);
2194 _DtTurnOnHourGlass(wmshell_ancestor);
2196 * if needed, create the file selection dialog
2198 if(dpd->file_selection_box == (Widget)NULL)
2200 XtEnum status = CreateFileSelectionBox(wmshell_ancestor, w, dpd);
2201 if(status != DtPRINT_SUCCESS)
2203 _DtTurnOffHourGlass(wmshell_ancestor);
2208 * get the file name passed from the PrintSetupBox
2210 file_name = print_data->dest_info;
2212 * parse the file name to create the filter pattern and the name only
2213 * portion of the full name spec
2215 ParseFileNameSpec(file_name, &pattern, &name_only);
2217 * set the filter pattern in the file selection box
2219 XtVaSetValues(dpd->file_selection_box, XmNpattern, pattern, NULL);
2220 if(pattern != (XmString)NULL)
2221 XmStringFree(pattern);
2223 * select the current file name in the file names list
2225 file_list = XtNameToWidget(dpd->file_selection_box, "*ItemsList");
2226 if(file_list != (Widget)NULL)
2228 XmString file_name_xmstr;
2231 text_field = XtNameToWidget(dpd->file_selection_box, "Text");
2232 if(text_field != (Widget)NULL)
2236 * recreate the file name from the name_only and the current
2237 * dir spec as determined by the file selection box
2239 * Note: the char* value retrieved directly from the text
2240 * field is used, because forming the file name from a
2241 * concatenation of XmStrings causes XmListItemPos to fail
2242 * even though the file name is actually in the list.
2244 XtVaGetValues(text_field, XmNvalue, &dir_spec, NULL);
2245 file_name = XtMalloc(strlen(dir_spec)+strlen(name_only)+1);
2246 strcpy(file_name, dir_spec);
2247 strcat(file_name, name_only);
2248 file_name_xmstr = XmStringCreateLocalized(file_name);
2253 file_name_xmstr = XmStringCreateLocalized(file_name);
2255 * find the position of the file name in the list
2257 position = XmListItemPos(file_list, file_name_xmstr);
2258 SetListBoxSelection(file_list, position);
2262 * The file name is not in the list. Manually set in the
2263 * "Selection" text field.
2265 XtVaSetValues(dpd->file_selection_box,
2266 XmNdirSpec, file_name_xmstr,
2269 XmStringFree(file_name_xmstr);
2273 * pop up the file selection dialog and return
2275 XtManageChild(dpd->file_selection_box);
2276 _DtTurnOffHourGlass(wmshell_ancestor);
2277 return DtPRINT_SUCCESS;
2281 * ------------------------------------------------------------------------
2282 * Name: _DtPrintSetupBoxSelectXPrinterProc
2286 * Default Xp mode function for the DtNselectPrinterProc resource.
2293 _DtPrintSetupBoxSelectXPrinterProc(
2295 DtPrintSetupData* print_data)
2297 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
2298 Widget wmshell_ancestor;
2299 XmStringTable items;
2303 XmRenderTable render_table, new_render_table;
2306 XmRendition rendition;
2310 wmshell_ancestor = GetWMShellAncestor(w);
2311 _DtTurnOnHourGlass(wmshell_ancestor);
2313 * build the list of servers and printers
2315 if(DtPRINT_SUCCESS != BuildPrinterLists(w, dpd, &item_count))
2317 PresentErrorDialog(w, PRLIST_ERROR_TITLE,
2318 NO_PRINTERS_MESSAGE,
2320 _DtTurnOffHourGlass(wmshell_ancestor);
2321 return DtPRINT_FAILURE;
2324 * create the dialog if it doesn't exist
2326 if(dpd->printer_selection_box == (Widget)NULL)
2328 XtEnum status = CreatePrinterSelectionBox(wmshell_ancestor, w, dpd);
2329 if(status != DtPRINT_SUCCESS)
2331 _DtTurnOffHourGlass(wmshell_ancestor);
2336 * get a copy of the list widget's render table
2338 XtVaGetValues(dpd->printer_list_box,
2339 XmNrenderTable, &render_table,
2341 render_table = XmRenderTableCopy(render_table, (XmStringTag*)NULL, 0);
2343 * build the item list for the list box
2345 count = XmRenderTableGetTags(render_table, &tags);
2346 items = BuildPrinterSelectionItems(XtDisplay(w), dpd, item_count,
2347 print_data->printer_name, tags[0]);
2349 * generate a tab list for the items
2351 tab_list = XmStringTableProposeTablist(items, item_count,
2352 dpd->printer_list_box,
2355 * get a copy of the first rendition in the render table
2357 rendition = XmRenderTableGetRendition(render_table, tags[0]);
2358 for(i = 0; i < count; i++)
2360 XtFree((char*)tags);
2362 * update the copy with the new tab list
2365 XtSetArg(args[n], XmNtabList, tab_list); n++;
2366 XmRenditionUpdate(rendition, args, n);
2367 XmTabListFree(tab_list);
2369 * create a new render table replacing the first entry with the
2372 new_render_table = XmRenderTableAddRenditions(render_table, &rendition,
2373 1, XmMERGE_REPLACE);
2374 XmRenditionFree(rendition);
2376 * set the new render table and list items in the list box
2378 XtVaSetValues(dpd->printer_list_box,
2379 XmNrenderTable, new_render_table,
2381 XmNitemCount, item_count,
2383 XmRenderTableFree(new_render_table);
2384 for(i = 0; i < item_count; i++)
2385 XmStringFree(items[i]);
2386 XtFree((char*)items);
2387 SetListBoxSelection(dpd->printer_list_box, dpd->selected_printer);
2389 * disable the info button if nothing is selected
2391 if(0 == dpd->selected_printer)
2392 XtSetSensitive(XtNameToWidget(dpd->printer_selection_box, "*Apply"),
2395 * manage the dialog and return
2397 XtManageChild(dpd->printer_selection_box);
2398 _DtTurnOffHourGlass(wmshell_ancestor);
2399 return DtPRINT_SUCCESS;
2403 * ------------------------------------------------------------------------
2404 * Name: _DtPrintSetupBoxVerifyXPrinterProc
2408 * Default function for the DtNverifyPrinterProc resource when the
2411 * (this rest of this description outlines the responsibilities of a
2412 * DtNverifyPrinterProc in general)
2414 * This function verifies the printer name passed in the
2415 * PrintSetupData structure.
2417 * If needed, the DtNprintSetupMode resource may be obtained via a
2418 * GetValues call in order to determine the current setup mode.
2420 * It is the responsibility of this proc to return a valid print
2421 * Display handle and print context by setting the print_display and
2422 * print_context in the PrintSetupData. Conceptually, this is a
2423 * side-effect of this proc, but since it will be necessary to open a
2424 * display connection in order to properly verify the X printer,
2425 * there's no point in doing it twice.
2427 * If the passed printer name is incomplete, this proc may attempt to
2428 * determine a default or fully-qualified name (e.g. fill in a
2429 * missing display spec for an X Printer Specifier). The new default
2430 * or fully-qualified printer name should be set in the PrintSetupBox
2431 * by updating the DtNprinterName resource via a SetValues call. If a
2432 * fully-qualified name cannot be determined, this proc simply
2433 * returns DtPRINT_FAILURE.
2435 * If the printer cannot be verified, it is the responsibiliy of this
2436 * function to present an appropriate message to the user.
2441 * if the printer name has been successfully verified.
2444 * if the printer name is invalid.
2449 _DtPrintSetupBoxVerifyXPrinterProc(
2451 DtPrintSetupData* psd)
2453 DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
2455 String new_printer_spec;
2456 Display* new_display;
2457 XPContext new_context;
2458 Widget wmshell_ancestor;
2460 wmshell_ancestor = GetWMShellAncestor(w);
2461 _DtTurnOnHourGlass(wmshell_ancestor);
2463 * verify the printer
2465 status = _DtPrintVerifyXPrinter(w,
2470 if(status == DtPRINT_SUCCESS)
2473 * update the passed print setup data with the new display and
2476 psd->print_display = new_display;
2477 psd->print_context = new_context;
2482 * unable to open the printer; present a message to the user
2483 * according to the hint set in the setup data
2485 dpd->messages_hint = psd->messages_hint;
2486 PresentVerifyError(w, status,
2488 ? new_printer_spec : psd->printer_name);
2490 * reset the hint since the error dialog is also used
2491 * by the other default procs
2493 dpd->messages_hint = DtPRINT_HINT_MESSAGES_OK;
2495 * this function only indicates success or failure
2497 status = DtPRINT_FAILURE;
2499 if(new_printer_spec)
2502 * set the new printer spec, even if the verify failed
2505 DtNprinterName, new_printer_spec,
2507 XtFree(new_printer_spec);
2512 _DtTurnOffHourGlass(wmshell_ancestor);