2564 lines
66 KiB
C
2564 lines
66 KiB
C
/*
|
|
* CDE - Common Desktop Environment
|
|
*
|
|
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
|
|
*
|
|
* These libraries and programs are free software; you can
|
|
* redistribute them and/or modify them under the terms of the GNU
|
|
* Lesser General Public License as published by the Free Software
|
|
* Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* These libraries and programs are distributed in the hope that
|
|
* they will be useful, but WITHOUT ANY WARRANTY; without even the
|
|
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU Lesser General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with these libraries and programs; if not, write
|
|
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
|
* Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
/* $XConsortium: PsubDefProc.c /main/14 1996/12/02 10:51:20 rswiston $ */
|
|
/*
|
|
* DtPrint/PsubDefProc.c
|
|
*/
|
|
/*
|
|
* (c) Copyright 1996 Digital Equipment Corporation.
|
|
* (c) Copyright 1996 Hewlett-Packard Company.
|
|
* (c) Copyright 1996 International Business Machines Corp.
|
|
* (c) Copyright 1996 Sun Microsystems, Inc.
|
|
* (c) Copyright 1996 Novell, Inc.
|
|
* (c) Copyright 1996 FUJITSU LIMITED.
|
|
* (c) Copyright 1996 Hitachi.
|
|
*/
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Include Files
|
|
*
|
|
*/
|
|
#include <stdlib.h>
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
|
|
#include <Xm/XmAll.h>
|
|
|
|
#include <Dt/HelpDialog.h>
|
|
#include <Dt/DtNlUtils.h>
|
|
#include <Dt/HourGlass.h>
|
|
|
|
/*
|
|
* PrintSetupBP.h is included only for access to the DtPrintDefProcData
|
|
* member of the widget instance structure.
|
|
*/
|
|
#include <Dt/PrintSetupBP.h>
|
|
|
|
#include <Dt/PsubUtilI.h>
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Constant Definitions
|
|
*
|
|
*/
|
|
#define HELP_VOLUME "LibDtPrint"
|
|
#define PRINTER_INFO_HELP_ID "PrinterInfo"
|
|
#define SELECT_PRINTER_HELP_ID "SelectPrinter"
|
|
#define SELECT_FILE_HELP_ID "SelectFile"
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Static Function Declarations
|
|
*
|
|
*/
|
|
static XtEnum BuildPrinterLists(
|
|
Widget w,
|
|
DtPrintDefaultProcData* dpd,
|
|
int* item_count);
|
|
static XmStringTable BuildPrinterSelectionItems(
|
|
Display* display,
|
|
DtPrintDefaultProcData* dpd,
|
|
int item_count,
|
|
String initial_printer,
|
|
XmStringTag tag);
|
|
static void CloseSelectPrinterInfoConnection(
|
|
DtPrintDefaultProcData* dpd);
|
|
static int CompareSelectPrinterRecs(const void*,
|
|
const void*);
|
|
static String CompoundTextToString(
|
|
Display* display,
|
|
unsigned char* compound_text);
|
|
static XtEnum CreateFileSelectionBox(
|
|
Widget parent,
|
|
Widget psub,
|
|
DtPrintDefaultProcData* dpd);
|
|
static XtEnum CreatePrinterInfoBox(
|
|
Widget parent,
|
|
Widget psub,
|
|
DtPrintDefaultProcData* dpd);
|
|
static XtEnum CreatePrinterSelectionBox(
|
|
Widget parent,
|
|
Widget psub,
|
|
DtPrintDefaultProcData* dpd);
|
|
static void DestroyWidgetCB(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data);
|
|
static void DtPrintDefProcDestroyCB(Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data);
|
|
static void ErrorMessageDestroyCB(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data);
|
|
static String FindSelectedPrinter(
|
|
Display* display,
|
|
DtPrintDefaultProcData* dpd);
|
|
static void FreeSelectPrinterData(
|
|
DtPrintDefaultProcData* dpd);
|
|
static Widget GetWMShellAncestor(
|
|
Widget w);
|
|
static void HelpDialogDestroyCB(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data);
|
|
static void InfoBoxLayoutCB(
|
|
Widget widget,
|
|
XtPointer client_data,
|
|
XtPointer call_data);
|
|
static void ParseFileNameSpec(
|
|
const char* file_name,
|
|
XmString* pattern,
|
|
char** name_only);
|
|
static void PresentErrorDialog(
|
|
Widget w,
|
|
String title,
|
|
String message,
|
|
...);
|
|
static void PresentHelp(
|
|
Widget w,
|
|
const char* help_volume,
|
|
const char* location_id);
|
|
static void PresentVerifyError(
|
|
Widget w,
|
|
XtEnum status,
|
|
String printer_spec);
|
|
static void PrinterInfoDestroyCB(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data);
|
|
static void PrinterInfoHelpCB(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data);
|
|
static void SelectFileDestroyCB(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data);
|
|
static void SelectFileHelpCB(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data);
|
|
static void SelectPrinterCB(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data);
|
|
static void SelectPrinterDestroyCB(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data);
|
|
static void SelectPrinterHelpCB(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data);
|
|
static void SelectPrinterInfoCB(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data);
|
|
static void SelectPrinterItemCB(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data);
|
|
static void SetListBoxSelection(
|
|
Widget list_box,
|
|
int position);
|
|
static void UpdateFileNameCB(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data);
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: BuildPrinterLists
|
|
*
|
|
* Description:
|
|
*
|
|
* Retrieves lists of printers from the Xp server found in the
|
|
* XpServerList resource or XPSERVERLIST env var.
|
|
*
|
|
* Return value:
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
static XtEnum
|
|
BuildPrinterLists(
|
|
Widget w,
|
|
DtPrintDefaultProcData* dpd,
|
|
int* item_count)
|
|
{
|
|
String* server_list;
|
|
int server_count;
|
|
int i, j;
|
|
Display* display;
|
|
int error_base;
|
|
int event_base;
|
|
#if 0 && defined(PRINTING_SUPPORTED)
|
|
XPPrinterList xp_printer_list;
|
|
#endif /* PRINTING_SUPPORTED */
|
|
DtPrintSelectPrinterList printer_list;
|
|
/*
|
|
* clean up previous lists if needed
|
|
*/
|
|
FreeSelectPrinterData(dpd);
|
|
/*
|
|
* get the list of servers
|
|
*/
|
|
server_list = _DtPrintGetXpServerList(w);
|
|
if((String*)NULL == server_list)
|
|
return DtPRINT_FAILURE;
|
|
/*
|
|
* get the printer list for each valid Xp server
|
|
*/
|
|
for(server_count = 0;
|
|
(String)NULL != server_list[server_count];
|
|
server_count++);
|
|
dpd->xp_server_list =
|
|
(String*)XtCalloc(server_count, sizeof(String));
|
|
dpd->printer_lists = (DtPrintSelectPrinterList*)
|
|
XtCalloc(server_count, sizeof(DtPrintSelectPrinterList));
|
|
dpd->printer_counts =
|
|
(int*)XtCalloc(server_count, sizeof(int));
|
|
for(i = 0, *item_count = 0; i < server_count; i++)
|
|
{
|
|
/*
|
|
* ensure the server is a valid Xp server
|
|
*/
|
|
display = XOpenDisplay(server_list[i]);
|
|
if((Display*)NULL == display)
|
|
continue;
|
|
#if 0 && defined(PRINTING_SUPPORTED)
|
|
if(!XpQueryExtension(display, &event_base, &error_base))
|
|
{
|
|
#endif /* PRINTING_SUPPORTED */
|
|
XCloseDisplay(display);
|
|
continue;
|
|
#if 0 && defined(PRINTING_SUPPORTED)
|
|
}
|
|
#endif /* PRINTING_SUPPORTED */
|
|
/*
|
|
* add the server to the xp server list
|
|
*/
|
|
dpd->xp_server_list[dpd->xp_server_count] =
|
|
XtNewString(server_list[i]);
|
|
/*
|
|
* get the printer list for the server
|
|
*/
|
|
#if 0 && defined(PRINTING_SUPPORTED)
|
|
xp_printer_list =
|
|
XpGetPrinterList(display, (char*)NULL,
|
|
&dpd->printer_counts[dpd->xp_server_count]);
|
|
#endif /* PRINTING_SUPPORTED */
|
|
/*
|
|
* save a copy of the compound text printer name and
|
|
* string versions of the name and description for
|
|
* eventual use in the printer selection list.
|
|
*/
|
|
dpd->printer_lists[dpd->xp_server_count] = (DtPrintSelectPrinterList)
|
|
XtCalloc(dpd->printer_counts[dpd->xp_server_count],
|
|
sizeof(DtPrintSelectPrinterRec));
|
|
printer_list = dpd->printer_lists[dpd->xp_server_count];
|
|
#if 0 && defined(PRINTING_SUPPORTED)
|
|
for(j = 0; j < dpd->printer_counts[dpd->xp_server_count]; j++)
|
|
{
|
|
printer_list[j].printer_name_ct =
|
|
XtNewString(xp_printer_list[j].name);
|
|
printer_list[j].printer_name =
|
|
CompoundTextToString(display,
|
|
(unsigned char*)xp_printer_list[j].name);
|
|
printer_list[j].description =
|
|
CompoundTextToString(display,
|
|
(unsigned char*)xp_printer_list[j].desc);
|
|
}
|
|
XpFreePrinterList(xp_printer_list);
|
|
#endif /* PRINTING_SUPPORTED */
|
|
/*
|
|
* sort the printer list
|
|
*/
|
|
if(0 < dpd->printer_counts[dpd->xp_server_count])
|
|
qsort((void*)printer_list,
|
|
dpd->printer_counts[dpd->xp_server_count],
|
|
sizeof(DtPrintSelectPrinterRec), CompareSelectPrinterRecs);
|
|
|
|
*item_count += dpd->printer_counts[dpd->xp_server_count];
|
|
++dpd->xp_server_count;
|
|
XCloseDisplay(display);
|
|
}
|
|
_DtPrintFreeStringList(server_list);
|
|
if(0 == *item_count)
|
|
{
|
|
FreeSelectPrinterData(dpd);
|
|
return DtPRINT_FAILURE;
|
|
}
|
|
else
|
|
return DtPRINT_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: BuildPrinterSelectionItems
|
|
*
|
|
* Description:
|
|
*
|
|
* Builds the list of XmString items (printer name + desc) to be set
|
|
* in the printer selection list box.
|
|
*
|
|
* Return value:
|
|
*
|
|
* None.
|
|
*
|
|
*/
|
|
static XmStringTable
|
|
BuildPrinterSelectionItems(
|
|
Display* display,
|
|
DtPrintDefaultProcData* dpd,
|
|
int item_count,
|
|
String initial_printer,
|
|
XmStringTag tag)
|
|
{
|
|
XmStringTable items;
|
|
int i, j;
|
|
char* buf = (char*)NULL;
|
|
Cardinal buf_size = 0;
|
|
Cardinal new_size;
|
|
int current_item;
|
|
String name, full_name, desc;
|
|
char* server_name;
|
|
int server_len;
|
|
|
|
items = (XmStringTable)XtCalloc(item_count, sizeof(XmString));
|
|
for(i = 0, current_item = 0; i < dpd->xp_server_count; i++)
|
|
{
|
|
server_name = dpd->xp_server_list[i];
|
|
server_len = strlen(server_name);
|
|
|
|
for(j = 0; j < dpd->printer_counts[i]; j++, current_item++)
|
|
{
|
|
/*
|
|
* build a fully qualified X printer specifier
|
|
*/
|
|
name = (dpd->printer_lists[i])[j].printer_name;
|
|
(dpd->printer_lists[i])[j].printer_name = (String)NULL;
|
|
full_name =
|
|
_DtPrintCreateXPrinterSpecifier(name, server_name,
|
|
DtPRINT_NET_UNSPECIFIED,
|
|
-1, -1);
|
|
XtFree(name);
|
|
/*
|
|
* check to see if this should be the initially selected printer
|
|
*/
|
|
if(dpd->selected_printer == 0
|
|
&& (String)NULL != initial_printer)
|
|
if(strcmp(initial_printer, full_name) == 0)
|
|
dpd->selected_printer = current_item + 1;
|
|
/*
|
|
* convert the printer description
|
|
*/
|
|
desc = (dpd->printer_lists[i])[j].description;
|
|
(dpd->printer_lists[i])[j].description = (String)NULL;
|
|
if((String)NULL != desc && '\0' != *desc)
|
|
{
|
|
/*
|
|
* chop the description after the 1st line
|
|
*/
|
|
char* ptr = Dt_strchr(desc, '\n');
|
|
if((char*)NULL != ptr)
|
|
*ptr = '\0';
|
|
}
|
|
/*
|
|
* ensure the format buffer is large enough to contain
|
|
* the formatted list item
|
|
*/
|
|
new_size = 2;
|
|
new_size += full_name ? strlen(full_name) : 0;
|
|
new_size += desc ? strlen(desc) : 0;
|
|
if(new_size > buf_size)
|
|
{
|
|
buf_size = new_size;
|
|
buf = XtRealloc(buf, buf_size);
|
|
}
|
|
/*
|
|
* format the item, and add it to the item list
|
|
*/
|
|
sprintf(buf, "%s\t%s",
|
|
full_name ? full_name : "",
|
|
desc ? desc : "");
|
|
XtFree(desc);
|
|
XtFree(full_name);
|
|
items[current_item] =
|
|
XmStringGenerate((XtPointer)buf, (XmStringTag)NULL,
|
|
XmMULTIBYTE_TEXT, tag);
|
|
}
|
|
}
|
|
XtFree(buf);
|
|
return items;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: CloseSelectPrinterInfoConnection
|
|
*
|
|
* Description:
|
|
*
|
|
* Close the X printer connection maintained for the Select Printer
|
|
* dialog's Printer Information dialog.
|
|
*
|
|
* Return value:
|
|
*
|
|
* None.
|
|
*
|
|
*/
|
|
static void
|
|
CloseSelectPrinterInfoConnection(
|
|
DtPrintDefaultProcData* dpd)
|
|
{
|
|
if((Display*)NULL != dpd->select_printer_info_display)
|
|
{
|
|
#if 0 && defined(PRINTING_SUPPORTED)
|
|
if((XPContext)None != dpd->select_printer_info_context)
|
|
{
|
|
XpDestroyContext(dpd->select_printer_info_display,
|
|
dpd->select_printer_info_context);
|
|
dpd->select_printer_info_context = (XPContext)None;
|
|
}
|
|
#endif /* PRINTING_SUPPORTED */
|
|
XCloseDisplay(dpd->select_printer_info_display);
|
|
dpd->select_printer_info_display = (Display*)NULL;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: CompareSelectPrinterRecs
|
|
*
|
|
* Description:
|
|
*
|
|
* Compares the printer names in two DtPrintSelectPrinterRecs.
|
|
*
|
|
* Return value:
|
|
*
|
|
* Returns an integer greater than, equal to, or less than zero,
|
|
* according to whether the printer name in spr1 is greater
|
|
* than, equal to, or less than the printer name in spr2.
|
|
*
|
|
*/
|
|
static int
|
|
CompareSelectPrinterRecs(const void* spr1,
|
|
const void* spr2)
|
|
{
|
|
return strcoll(((DtPrintSelectPrinterRec*)spr1)->printer_name,
|
|
((DtPrintSelectPrinterRec*)spr2)->printer_name);
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: CompoundTextToString
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
* None.
|
|
*
|
|
*/
|
|
static String
|
|
CompoundTextToString(
|
|
Display* display,
|
|
unsigned char* compound_text)
|
|
{
|
|
String str = (String)NULL;
|
|
|
|
if((unsigned char*)NULL != compound_text)
|
|
{
|
|
XTextProperty text_prop;
|
|
char** list;
|
|
int count;
|
|
|
|
text_prop.encoding = XInternAtom(display, "COMPOUND_TEXT", False);
|
|
text_prop.format = 8;
|
|
text_prop.value = compound_text;
|
|
text_prop.nitems = strlen((char*)text_prop.value);
|
|
if(Success ==
|
|
XmbTextPropertyToTextList(display, &text_prop, &list, &count))
|
|
{
|
|
if(count > 0)
|
|
str = XtNewString(list[0]);
|
|
XFreeStringList(list);
|
|
}
|
|
}
|
|
return str;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: CreateFileSelectionBox
|
|
*
|
|
* Description:
|
|
*
|
|
* Creates the file selection dialog box.
|
|
*
|
|
* Return value:
|
|
*
|
|
* None.
|
|
*
|
|
*/
|
|
static XtEnum
|
|
CreateFileSelectionBox(
|
|
Widget parent,
|
|
Widget psub,
|
|
DtPrintDefaultProcData* dpd)
|
|
{
|
|
Arg args[15];
|
|
Cardinal n;
|
|
XmString title_xmstr;
|
|
|
|
title_xmstr = XmStringCreateLocalized(SELECT_FILE_TITLE);
|
|
|
|
n = 0;
|
|
/*
|
|
* dialog resources
|
|
*/
|
|
XtSetArg(args[n], XmNdialogTitle, title_xmstr); n++;
|
|
XtSetArg(args[n], XmNdialogStyle,
|
|
XmDIALOG_PRIMARY_APPLICATION_MODAL); n++;
|
|
XtSetArg(args[n], XmNdeleteResponse, XmUNMAP); n++;
|
|
/*
|
|
* file selection box resources
|
|
*/
|
|
XtSetArg(args[n], XmNautoUnmanage, True); n++;
|
|
/*
|
|
* create the file selection box dialog
|
|
*/
|
|
dpd->file_selection_box =
|
|
XmCreateFileSelectionDialog(parent, "_PsubDefProcFileSelectionBox",
|
|
args, n);
|
|
XmStringFree(title_xmstr);
|
|
if(dpd->file_selection_box == (Widget)NULL)
|
|
return DtPRINT_FAILURE;
|
|
/*
|
|
* add callbacks
|
|
*/
|
|
XtAddCallback(dpd->file_selection_box, XmNokCallback,
|
|
UpdateFileNameCB, (XtPointer)psub);
|
|
XtAddCallback(dpd->file_selection_box, XmNhelpCallback,
|
|
SelectFileHelpCB, (XtPointer)psub);
|
|
XtAddCallback(dpd->file_selection_box, XmNdestroyCallback,
|
|
SelectFileDestroyCB, (XtPointer)psub);
|
|
/*
|
|
* return
|
|
*/
|
|
return DtPRINT_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: CreatePrinterInfoBox
|
|
*
|
|
* Description:
|
|
*
|
|
* Creates the printer information dialog box.
|
|
*
|
|
* Return value:
|
|
*
|
|
* None.
|
|
*
|
|
*/
|
|
static XtEnum
|
|
CreatePrinterInfoBox(
|
|
Widget parent,
|
|
Widget psub,
|
|
DtPrintDefaultProcData* dpd)
|
|
{
|
|
Arg args[15];
|
|
Cardinal n;
|
|
XmString title_xmstr;
|
|
Widget manager;
|
|
Widget description_label, description;
|
|
Widget name_label, name;
|
|
Widget format_label, format;
|
|
Widget model_label, model;
|
|
XmString label;
|
|
|
|
title_xmstr = XmStringCreateLocalized(PRINTER_INFO_TITLE);
|
|
|
|
n = 0;
|
|
/*
|
|
* dialog resources
|
|
*/
|
|
XtSetArg(args[n], XmNdialogTitle, title_xmstr); n++;
|
|
XtSetArg(args[n], XmNdialogStyle,
|
|
XmDIALOG_PRIMARY_APPLICATION_MODAL); n++;
|
|
XtSetArg(args[n], XmNdeleteResponse, XmUNMAP); n++;
|
|
/*
|
|
* printer info box resources
|
|
*/
|
|
XtSetArg(args[n], XmNautoUnmanage, True); n++;
|
|
/*
|
|
* create the dialog
|
|
*/
|
|
dpd->printer_info_box =
|
|
XmCreateInformationDialog(parent, "_PsubDefProcPrinterInfoBox",
|
|
args, n);
|
|
XmStringFree(title_xmstr);
|
|
if(dpd->printer_info_box == (Widget)NULL)
|
|
return DtPRINT_FAILURE;
|
|
/*
|
|
* add callbacks
|
|
*/
|
|
XtAddCallback(dpd->printer_info_box, XmNhelpCallback,
|
|
PrinterInfoHelpCB, (XtPointer)psub);
|
|
XtAddCallback(dpd->printer_info_box, XmNdestroyCallback,
|
|
PrinterInfoDestroyCB, (XtPointer)psub);
|
|
XtAddCallback(dpd->printer_info_box, XmNmapCallback,
|
|
InfoBoxLayoutCB, (XtPointer)dpd);
|
|
/*
|
|
* unmanage unwanted children
|
|
*/
|
|
XtUnmanageChild(XtNameToWidget(dpd->printer_info_box, "Cancel"));
|
|
XtUnmanageChild(XtNameToWidget(dpd->printer_info_box, "Message"));
|
|
XtUnmanageChild(XtNameToWidget(dpd->printer_info_box, "Symbol"));
|
|
/*
|
|
* create the control manager
|
|
*/
|
|
manager =
|
|
XtVaCreateManagedWidget("PrinterInfoForm", xmFormWidgetClass,
|
|
dpd->printer_info_box,
|
|
XmNallowOverlap, False,
|
|
NULL);
|
|
/*
|
|
* printer description
|
|
*/
|
|
label = XmStringCreateLocalized(DESCRIPTION_LABEL);
|
|
description_label =
|
|
XtVaCreateManagedWidget("DescriptionLabel",
|
|
xmLabelWidgetClass,
|
|
manager,
|
|
XmNlabelString, label,
|
|
XmNleftAttachment, XmATTACH_FORM,
|
|
XmNtopAttachment, XmATTACH_FORM,
|
|
XmNtopOffset, 5,
|
|
NULL);
|
|
XmStringFree(label);
|
|
description =
|
|
XtVaCreateManagedWidget("Description",
|
|
xmLabelWidgetClass,
|
|
manager,
|
|
XmNalignment, XmALIGNMENT_BEGINNING,
|
|
XmNleftAttachment, XmATTACH_WIDGET,
|
|
XmNleftWidget, description_label,
|
|
XmNleftOffset, 10,
|
|
XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
XmNtopWidget, description_label,
|
|
NULL);
|
|
/*
|
|
* printer name
|
|
*/
|
|
label = XmStringCreateLocalized(PRINTER_NAME_LABEL);
|
|
name_label =
|
|
XtVaCreateManagedWidget("NameLabel",
|
|
xmLabelWidgetClass,
|
|
manager,
|
|
XmNlabelString, label,
|
|
XmNleftAttachment, XmATTACH_FORM,
|
|
XmNtopAttachment, XmATTACH_WIDGET,
|
|
XmNtopWidget, description,
|
|
XmNtopOffset, 5,
|
|
NULL);
|
|
XmStringFree(label);
|
|
name =
|
|
XtVaCreateManagedWidget("Name",
|
|
xmLabelWidgetClass,
|
|
manager,
|
|
XmNleftAttachment, XmATTACH_WIDGET,
|
|
XmNleftWidget, name_label,
|
|
XmNleftOffset, 10,
|
|
XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
XmNtopWidget, name_label,
|
|
NULL);
|
|
/*
|
|
* printer format
|
|
*/
|
|
label = XmStringCreateLocalized(FORMAT_LABEL);
|
|
format_label =
|
|
XtVaCreateManagedWidget("FormatLabel",
|
|
xmLabelWidgetClass,
|
|
manager,
|
|
XmNlabelString, label,
|
|
XmNleftAttachment, XmATTACH_FORM,
|
|
XmNtopAttachment, XmATTACH_WIDGET,
|
|
XmNtopWidget, name_label,
|
|
XmNtopOffset, 5,
|
|
NULL);
|
|
XmStringFree(label);
|
|
format =
|
|
XtVaCreateManagedWidget("Format",
|
|
xmLabelWidgetClass,
|
|
manager,
|
|
XmNleftAttachment, XmATTACH_WIDGET,
|
|
XmNleftWidget, format_label,
|
|
XmNleftOffset, 10,
|
|
XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
XmNtopWidget, format_label,
|
|
NULL);
|
|
/*
|
|
* printer model
|
|
*/
|
|
label = XmStringCreateLocalized(MODEL_LABEL);
|
|
model_label =
|
|
XtVaCreateManagedWidget("ModelLabel",
|
|
xmLabelWidgetClass,
|
|
manager,
|
|
XmNlabelString, label,
|
|
XmNleftAttachment, XmATTACH_FORM,
|
|
XmNtopAttachment, XmATTACH_WIDGET,
|
|
XmNtopWidget, format_label,
|
|
XmNtopOffset, 5,
|
|
NULL);
|
|
XmStringFree(label);
|
|
model =
|
|
XtVaCreateManagedWidget("Model",
|
|
xmLabelWidgetClass,
|
|
manager,
|
|
XmNalignment, XmALIGNMENT_BEGINNING,
|
|
XmNleftAttachment, XmATTACH_WIDGET,
|
|
XmNleftWidget, model_label,
|
|
XmNleftOffset, 10,
|
|
XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
XmNtopWidget, model_label,
|
|
NULL);
|
|
/*
|
|
* return
|
|
*/
|
|
return DtPRINT_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: CreatePrinterSelectionBox
|
|
*
|
|
* Description:
|
|
*
|
|
* Creates the printer selection dialog box.
|
|
*
|
|
* Return value:
|
|
*
|
|
* None.
|
|
*
|
|
*/
|
|
static XtEnum
|
|
CreatePrinterSelectionBox(
|
|
Widget parent,
|
|
Widget psub,
|
|
DtPrintDefaultProcData* dpd)
|
|
{
|
|
Arg args[15];
|
|
Cardinal n;
|
|
Widget control;
|
|
XmString list_label;
|
|
XmString title_xmstr;
|
|
XmString info_label;
|
|
|
|
title_xmstr = XmStringCreateLocalized(MORE_PRINTERS_TITLE);
|
|
list_label = XmStringCreateLocalized(PRINTER_LIST_LABEL);
|
|
info_label = XmStringCreateLocalized(PRINTER_INFO_LABEL);
|
|
|
|
n = 0;
|
|
/*
|
|
* dialog resources
|
|
*/
|
|
XtSetArg(args[n], XmNdialogTitle, title_xmstr); n++;
|
|
XtSetArg(args[n], XmNdialogStyle,
|
|
XmDIALOG_PRIMARY_APPLICATION_MODAL); n++;
|
|
XtSetArg(args[n], XmNdeleteResponse, XmDESTROY); n++;
|
|
/*
|
|
* selection box resources
|
|
*/
|
|
XtSetArg(args[n], XmNautoUnmanage, True); n++;
|
|
XtSetArg(args[n], XmNlistLabelString, list_label); n++;
|
|
XtSetArg(args[n], XmNapplyLabelString, info_label); n++;
|
|
/*
|
|
* create the dialog
|
|
*/
|
|
dpd->printer_selection_box =
|
|
XmCreateSelectionDialog(parent, "_PsubDefProcPrinterSelectionBox",
|
|
args, n);
|
|
XmStringFree(list_label);
|
|
XmStringFree(info_label);
|
|
XmStringFree(title_xmstr);
|
|
if(dpd->printer_selection_box == (Widget)NULL)
|
|
return DtPRINT_FAILURE;
|
|
/*
|
|
* add callbacks
|
|
*/
|
|
XtAddCallback(dpd->printer_selection_box, XmNokCallback,
|
|
SelectPrinterCB, (XtPointer)psub);
|
|
XtAddCallback(dpd->printer_selection_box, XmNapplyCallback,
|
|
SelectPrinterInfoCB, (XtPointer)psub);
|
|
XtAddCallback(dpd->printer_selection_box, XmNcancelCallback,
|
|
SelectPrinterCB, (XtPointer)psub);
|
|
XtAddCallback(dpd->printer_selection_box, XmNhelpCallback,
|
|
SelectPrinterHelpCB, (XtPointer)psub);
|
|
XtAddCallback(dpd->printer_selection_box, XmNdestroyCallback,
|
|
SelectPrinterDestroyCB, (XtPointer)psub);
|
|
/*
|
|
* get the list box widget ID
|
|
*/
|
|
dpd->printer_list_box =
|
|
XtNameToWidget(dpd->printer_selection_box, "*ItemsList");
|
|
XtAddCallback(dpd->printer_list_box, XmNbrowseSelectionCallback,
|
|
SelectPrinterItemCB, (XtPointer)psub);
|
|
/*
|
|
* unmanaged unwanted children
|
|
*/
|
|
control = XtNameToWidget(dpd->printer_selection_box, "*Selection");
|
|
if(control != (Widget)NULL)
|
|
XtUnmanageChild(control);
|
|
control = XtNameToWidget(dpd->printer_selection_box, "*Text");
|
|
if(control != (Widget)NULL)
|
|
XtUnmanageChild(control);
|
|
/*
|
|
* return
|
|
*/
|
|
return DtPRINT_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: DestroyWidgetCB
|
|
*
|
|
* Description:
|
|
*
|
|
* Destroys the Widget passed as client_data.
|
|
*
|
|
* Return value:
|
|
*
|
|
* None.
|
|
*
|
|
*/
|
|
static void
|
|
DestroyWidgetCB(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data)
|
|
{
|
|
XtDestroyWidget((Widget)client_data);
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: DtPrintDefProcDestroyCB
|
|
*
|
|
* Description:
|
|
*
|
|
* Free resources allocated for the default procedure data structure
|
|
* in response to the destruction of the DtPrintSetupBox.
|
|
*
|
|
* Calls destroy callbacks for dialogs *directly* because the dialogs
|
|
* aren't children of the DtPrintSetupBox, but instead are more like
|
|
* siblings or cousins of the PrintSetupBox whose common ancestor is
|
|
* the shell parent of the PrintSetupBox. As such the dialogs may or
|
|
* may not otherwise be destroyed when the PrintSetupBox is
|
|
* destroyed. Furthermore the 2nd phase of the XtDestroyWidget calls
|
|
* made in this routine isn't reached until after the PrintSetupBox
|
|
* instance record has been destroyed (as part of the destroy phase
|
|
* of which *this* call is a part).
|
|
*
|
|
* The main reason this is a concern is because data associated with
|
|
* these dialogs is stored in the PrintSetupBox widget instance
|
|
* structure.
|
|
*
|
|
* Return value:
|
|
*
|
|
* None.
|
|
*
|
|
*/
|
|
static void
|
|
DtPrintDefProcDestroyCB(Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data)
|
|
{
|
|
DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
|
|
|
|
if(dpd->error_message_box)
|
|
{
|
|
XtRemoveCallback(dpd->error_message_box, XmNdestroyCallback,
|
|
ErrorMessageDestroyCB, (XtPointer)w);
|
|
XtDestroyWidget(dpd->error_message_box);
|
|
ErrorMessageDestroyCB(dpd->error_message_box,
|
|
(XtPointer)w, (XtPointer)NULL);
|
|
}
|
|
if(dpd->help_dialog)
|
|
{
|
|
XtRemoveCallback(dpd->help_dialog, XmNdestroyCallback,
|
|
HelpDialogDestroyCB, (XtPointer)w);
|
|
XtDestroyWidget(dpd->help_dialog);
|
|
HelpDialogDestroyCB(dpd->help_dialog,
|
|
(XtPointer)w, (XtPointer)NULL);
|
|
}
|
|
if(dpd->file_selection_box)
|
|
{
|
|
XtRemoveCallback(dpd->file_selection_box, XmNdestroyCallback,
|
|
SelectFileDestroyCB, (XtPointer)w);
|
|
XtDestroyWidget(dpd->file_selection_box);
|
|
SelectFileDestroyCB(dpd->file_selection_box,
|
|
(XtPointer)w, (XtPointer)NULL);
|
|
}
|
|
if(dpd->printer_selection_box)
|
|
{
|
|
XtRemoveCallback(dpd->printer_selection_box, XmNdestroyCallback,
|
|
SelectPrinterDestroyCB, (XtPointer)w);
|
|
XtDestroyWidget(dpd->printer_selection_box);
|
|
SelectPrinterDestroyCB(dpd->printer_selection_box,
|
|
(XtPointer)w, (XtPointer)NULL);
|
|
}
|
|
if(dpd->printer_info_box)
|
|
{
|
|
XtRemoveCallback(dpd->printer_info_box, XmNdestroyCallback,
|
|
PrinterInfoDestroyCB, (XtPointer)w);
|
|
XtDestroyWidget(dpd->printer_info_box);
|
|
PrinterInfoDestroyCB(dpd->printer_info_box,
|
|
(XtPointer)w, (XtPointer)NULL);
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: ErrorMessageDestroyCB
|
|
*
|
|
* Description:
|
|
*
|
|
* Reset the error message widget ID instance data when the message
|
|
* box is destroyed.
|
|
*
|
|
* This callback is considered part of the default resource
|
|
* procedures and not part of the setup box widget proper.
|
|
*
|
|
* Return value:
|
|
*
|
|
* None.
|
|
*
|
|
*/
|
|
static void
|
|
ErrorMessageDestroyCB(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data)
|
|
{
|
|
DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(client_data);
|
|
|
|
dpd->error_message_box = (Widget)NULL;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: FindSelectedPrinter
|
|
*
|
|
* Description:
|
|
*
|
|
* Build a full printer name by locating the currently selected
|
|
* printer in the server list and printer list.
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
* A newly allocated full printer name. It is the caller's
|
|
* responsibility to free the returned String by calling XtFree.
|
|
*
|
|
*/
|
|
static String
|
|
FindSelectedPrinter(
|
|
Display* display,
|
|
DtPrintDefaultProcData* dpd)
|
|
{
|
|
int printer_count;
|
|
int i;
|
|
int printer_index;
|
|
|
|
/*
|
|
* return if any of the structures are not in place
|
|
*/
|
|
if(dpd->xp_server_list == (String*)NULL
|
|
||
|
|
dpd->printer_counts == (int*)NULL
|
|
||
|
|
dpd->printer_lists == (DtPrintSelectPrinterList*)NULL)
|
|
{
|
|
return (String)NULL;
|
|
}
|
|
/*
|
|
* find the printer list containing the selected printer
|
|
*/
|
|
if(0 == dpd->selected_printer)
|
|
return (String)NULL;
|
|
else
|
|
printer_index = dpd->selected_printer - 1;
|
|
|
|
for(i = 0, printer_count = 0; i < dpd->xp_server_count; i++)
|
|
{
|
|
if(printer_index < printer_count + (dpd->printer_counts)[i])
|
|
break;
|
|
else
|
|
printer_count += (dpd->printer_counts)[i];
|
|
}
|
|
if(i < dpd->xp_server_count)
|
|
{
|
|
/*
|
|
* build and return the printer name
|
|
*/
|
|
DtPrintSelectPrinterList printer_list;
|
|
String printer_spec;
|
|
String printer_name;
|
|
char* printer_name_ct;
|
|
char* display_spec;
|
|
|
|
display_spec = (dpd->xp_server_list)[i];
|
|
printer_list = (dpd->printer_lists)[i];
|
|
printer_name_ct =
|
|
printer_list[printer_index - printer_count].printer_name_ct;
|
|
printer_name =
|
|
CompoundTextToString(display, (unsigned char*)printer_name_ct);
|
|
if((String)NULL != printer_name)
|
|
{
|
|
printer_spec =
|
|
_DtPrintCreateXPrinterSpecifier(printer_name,
|
|
display_spec,
|
|
DtPRINT_NET_UNSPECIFIED,
|
|
-1, -1);
|
|
XtFree(printer_name);
|
|
return printer_spec;
|
|
}
|
|
}
|
|
return (String)NULL;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: FreeSelectPrinterData
|
|
*
|
|
* Description:
|
|
*
|
|
* Deallocate and reset data items associated with the printer
|
|
* selection dialog.
|
|
*
|
|
* Return value:
|
|
*
|
|
* None.
|
|
*/
|
|
static void
|
|
FreeSelectPrinterData(
|
|
DtPrintDefaultProcData* dpd)
|
|
{
|
|
int i, j;
|
|
DtPrintSelectPrinterList printer_list;
|
|
|
|
for(i = 0; i < dpd->xp_server_count; i++)
|
|
{
|
|
printer_list = dpd->printer_lists[i];
|
|
for(j = 0; j < dpd->printer_counts[i]; j++)
|
|
{
|
|
XtFree(printer_list[j].printer_name_ct);
|
|
}
|
|
XtFree((char*)printer_list);
|
|
}
|
|
XtFree((char*)dpd->printer_lists);
|
|
dpd->printer_lists = (DtPrintSelectPrinterList*)NULL;
|
|
XtFree((char*)dpd->xp_server_list);
|
|
dpd->xp_server_list = (String*)NULL;
|
|
dpd->xp_server_count = 0;
|
|
dpd->selected_printer = 0;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: GetWMShellAncestor
|
|
*
|
|
* Description:
|
|
*
|
|
* Obtains the widget ID of the closest WMShell ancestor for
|
|
* the passed widget.
|
|
*
|
|
* Return value:
|
|
*
|
|
* The widget ID of the closest WMShell ancestor.
|
|
*
|
|
*/
|
|
static Widget
|
|
GetWMShellAncestor(Widget w)
|
|
{
|
|
Widget wmshell_ancestor = XtParent(w);
|
|
while(wmshell_ancestor != (Widget)NULL)
|
|
{
|
|
if(XtIsWMShell(wmshell_ancestor))
|
|
break;
|
|
else
|
|
wmshell_ancestor = XtParent(wmshell_ancestor);
|
|
}
|
|
return wmshell_ancestor;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: HelpDialogDestroyCB
|
|
*
|
|
* Description:
|
|
*
|
|
* Reset the help dialog widget ID instance data when the widget
|
|
* is destroyed.
|
|
*
|
|
* This callback is considered part of the default resource
|
|
* procedures and not part of the setup box widget proper.
|
|
*
|
|
* Return value:
|
|
*
|
|
* None.
|
|
*
|
|
*/
|
|
static void
|
|
HelpDialogDestroyCB(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data)
|
|
{
|
|
DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(client_data);
|
|
|
|
dpd->help_dialog = (Widget)NULL;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: InfoBoxLayoutCB
|
|
*
|
|
* Description:
|
|
*
|
|
* Callback to right justify printer information dialog labels at
|
|
* mapping time.
|
|
*
|
|
* Return value:
|
|
*
|
|
* None.
|
|
*
|
|
*
|
|
*/
|
|
static void
|
|
InfoBoxLayoutCB(
|
|
Widget widget,
|
|
XtPointer client_data,
|
|
XtPointer call_data)
|
|
{
|
|
DtPrintDefaultProcData* dpd = (DtPrintDefaultProcData*)client_data;
|
|
Widget w[4];
|
|
int i, widest;
|
|
Dimension width, max_width;
|
|
/*
|
|
* only need to do this once after the widget is created
|
|
*/
|
|
XtRemoveCallback(widget, XmNmapCallback, InfoBoxLayoutCB, client_data);
|
|
/*
|
|
* get the label widget ids
|
|
*/
|
|
w[0] = XtNameToWidget(dpd->printer_info_box,
|
|
"PrinterInfoForm.DescriptionLabel");
|
|
w[1] = XtNameToWidget(dpd->printer_info_box,
|
|
"PrinterInfoForm.NameLabel");
|
|
w[2] = XtNameToWidget(dpd->printer_info_box,
|
|
"PrinterInfoForm.FormatLabel");
|
|
w[3] = XtNameToWidget(dpd->printer_info_box,
|
|
"PrinterInfoForm.ModelLabel");
|
|
/*
|
|
* find the widest label
|
|
*/
|
|
for(i = 0, widest = 0, max_width = 0; i < 4; i++)
|
|
{
|
|
XtVaGetValues(w[i], XmNwidth, &width, NULL);
|
|
if(width > max_width)
|
|
{
|
|
widest = i;
|
|
max_width = width;
|
|
}
|
|
}
|
|
/*
|
|
* sever the top attachment on the widest label in order to avoid
|
|
* circular dependencies in form children; apparently one of the form
|
|
* widget's many talents is the inability to manage the vertical and
|
|
* horizontal attachments independently...
|
|
*/
|
|
XtVaSetValues(w[widest], XmNtopAttachment, XmATTACH_SELF, NULL);
|
|
/*
|
|
* attach the right side of the smaller labels to the right side of
|
|
* the widest label
|
|
*/
|
|
for(i = 0; i < 4; i++)
|
|
if(i != widest)
|
|
XtVaSetValues(w[i],
|
|
XmNleftAttachment, XmATTACH_NONE,
|
|
XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET,
|
|
XmNrightWidget, w[widest],
|
|
NULL);
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: ParseFileNameSpec
|
|
*
|
|
* Description:
|
|
*
|
|
* Parse the passed file name to create a file selection box filter
|
|
* pattern and the name only portion of the full name spec.
|
|
*
|
|
* It is the caller's responsibility to free the allocated memory
|
|
* returned in 'pattern' and 'name_only' using XmStringFree and
|
|
* XtFree respectively.
|
|
*
|
|
* Return value:
|
|
*
|
|
* None.
|
|
*
|
|
*
|
|
*/
|
|
static void
|
|
ParseFileNameSpec(const char* file_name,
|
|
XmString* pattern_xmstr,
|
|
char** name_only)
|
|
{
|
|
String ptr;
|
|
String pattern;
|
|
/*
|
|
* start off with a copy of the file name, ensuring there is
|
|
* enough space for the added "*" and the string terminator.
|
|
*/
|
|
pattern = XtMalloc(strlen(file_name)+2);
|
|
strcpy(pattern, file_name);
|
|
/*
|
|
* find the last slash
|
|
*/
|
|
ptr = DtStrrchr(pattern, '/');
|
|
if(ptr != (String)NULL)
|
|
{
|
|
/*
|
|
* grab the name portion of the file name
|
|
*/
|
|
*name_only = XtNewString(ptr+1);
|
|
/*
|
|
* set the wildcard character immediately following the last
|
|
* slash
|
|
*/
|
|
strcpy(ptr+1, "*");
|
|
*pattern_xmstr = XmStringCreateLocalized(pattern);
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* no slash found; use the default pattern
|
|
*/
|
|
*pattern_xmstr = (XmString)NULL;
|
|
*name_only = XtNewString(file_name);
|
|
}
|
|
XtFree(pattern);
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PresentErrorDialog
|
|
*
|
|
* Description:
|
|
*
|
|
* This is a utility function that will present an Error Dialog. It
|
|
* takes a title, a message, and a variable list of Strings to
|
|
* include in the message. The message parm is treated like a
|
|
* printf-style format string, except that only the "%s" directive is
|
|
* supported.
|
|
*
|
|
* This function is to be used exclusively by the default
|
|
* resource procedures (e.g. _DtPrintSetupBoxVerifyXPrinterProc).
|
|
*
|
|
* The variable list of String parms must be terminated by
|
|
* (String)NULL.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* None.
|
|
*
|
|
*/
|
|
static void
|
|
PresentErrorDialog(
|
|
Widget w,
|
|
String title,
|
|
String message,
|
|
...)
|
|
{
|
|
Arg args[15];
|
|
Cardinal n;
|
|
String expanded_message;
|
|
String str_n;
|
|
XmString message_xmstr;
|
|
XmString title_xmstr;
|
|
int message_len;
|
|
va_list arg_marker;
|
|
DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
|
|
Widget wmshell_ancestor;
|
|
WidgetList wmshell_ancestors_children = (WidgetList)NULL;
|
|
|
|
wmshell_ancestor = GetWMShellAncestor(w);
|
|
|
|
if (wmshell_ancestor)
|
|
{
|
|
n = 0;
|
|
XtSetArg(args[n], XmNchildren, &wmshell_ancestors_children); n++;
|
|
XtGetValues(wmshell_ancestor, args, n);
|
|
}
|
|
|
|
if(dpd->error_message_box != (Widget)NULL)
|
|
{
|
|
/*
|
|
* present only one message box
|
|
*/
|
|
XtDestroyWidget(dpd->error_message_box);
|
|
}
|
|
|
|
title_xmstr = XmStringCreateLocalized(title);
|
|
/*
|
|
* determine length of expanded message
|
|
*/
|
|
message_len = strlen(message);
|
|
va_start(arg_marker, message);
|
|
while((str_n = va_arg(arg_marker, String)) != (String)NULL)
|
|
{
|
|
message_len += strlen(str_n);
|
|
}
|
|
va_end(arg_marker);
|
|
++message_len;
|
|
/*
|
|
* expand the message
|
|
*/
|
|
expanded_message = XtMalloc(message_len);
|
|
va_start(arg_marker, message);
|
|
vsprintf(expanded_message, message, arg_marker);
|
|
va_end(arg_marker);
|
|
/*
|
|
* convert message to XmString
|
|
*/
|
|
message_xmstr = XmStringCreateLocalized(expanded_message);
|
|
XtFree(expanded_message);
|
|
/*
|
|
* create the error dialog
|
|
*/
|
|
n = 0;
|
|
XtSetArg(args[n], XmNdialogTitle, title_xmstr); n++;
|
|
XtSetArg(args[n], XmNmessageString, message_xmstr); n++;
|
|
XtSetArg(args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); n++;
|
|
XtSetArg(args[n], XmNdeleteResponse, XmDESTROY); n++;
|
|
dpd->error_message_box =
|
|
XmCreateErrorDialog(wmshell_ancestors_children ?
|
|
wmshell_ancestors_children[0] :
|
|
wmshell_ancestor,
|
|
"_PsubDefProcErrorMsg", args, n);
|
|
XmStringFree(title_xmstr);
|
|
XmStringFree(message_xmstr);
|
|
|
|
XtUnmanageChild(XtNameToWidget(dpd->error_message_box, "Cancel"));
|
|
XtUnmanageChild(XtNameToWidget(dpd->error_message_box, "Help"));
|
|
|
|
XtAddCallback(dpd->error_message_box, XmNokCallback,
|
|
DestroyWidgetCB, (XtPointer)dpd->error_message_box);
|
|
XtAddCallback(dpd->error_message_box, XmNcancelCallback,
|
|
DestroyWidgetCB, (XtPointer)dpd->error_message_box);
|
|
XtAddCallback(dpd->error_message_box, XmNdestroyCallback,
|
|
ErrorMessageDestroyCB, (XtPointer)w);
|
|
/*
|
|
* manage the message box according to the hint
|
|
*/
|
|
if(DtPRINT_HINT_MESSAGES_OK == dpd->messages_hint)
|
|
XtManageChild(dpd->error_message_box);
|
|
|
|
#ifdef XXX_JUNGLE_REMOVE
|
|
/*
|
|
* manage the message box only if the psub is mapped
|
|
* and the focus is not in the printer name field
|
|
*/
|
|
{
|
|
XWindowAttributes attr;
|
|
Status status;
|
|
Window window = XtWindow(w);
|
|
if(window)
|
|
{
|
|
status = XGetWindowAttributes(XtDisplay(w), window, &attr);
|
|
if(status == 0 || attr.map_state == IsViewable)
|
|
{
|
|
Widget name_w = XtNameToWidget(w, "Name");
|
|
Widget child;
|
|
|
|
for(child = XmGetFocusWidget(w);
|
|
child != wmshell_ancestor && child != name_w
|
|
&& child != (Widget)NULL;
|
|
child = XtParent(child));
|
|
|
|
if(child != name_w && child != (Widget)NULL)
|
|
XtManageChild(dpd->error_message_box);
|
|
}
|
|
}
|
|
}
|
|
#endif /* XXX_JUNGLE_REMOVE */
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PresentHelp
|
|
*
|
|
* Description:
|
|
*
|
|
* Presents a help dialog whose widget instance may be shared between
|
|
* the default dialogs.
|
|
*
|
|
* Return value:
|
|
*
|
|
* None.
|
|
*
|
|
*/
|
|
static void PresentHelp(
|
|
Widget w,
|
|
const char* help_volume,
|
|
const char* location_id)
|
|
{
|
|
DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
|
|
Widget wmshell_ancestor;
|
|
Widget dialog_shell;
|
|
|
|
wmshell_ancestor = GetWMShellAncestor(w);
|
|
|
|
if((Widget)NULL == dpd->help_dialog)
|
|
{
|
|
Arg args[5];
|
|
Cardinal n;
|
|
XmString title;
|
|
|
|
n = 0;
|
|
title = XmStringCreateLocalized(HELP_DLG_TITLE);
|
|
XtSetArg(args[n], XmNdialogTitle, title); n++;
|
|
dpd->help_dialog =
|
|
DtCreateHelpDialog(wmshell_ancestor, "_PsubDefProcHelpDialog",
|
|
args, n);
|
|
XmStringFree(title);
|
|
XtAddCallback(dpd->help_dialog, XmNdestroyCallback,
|
|
HelpDialogDestroyCB, (XtPointer)w);
|
|
}
|
|
/*
|
|
* set the help volume and location
|
|
*/
|
|
XtVaSetValues(dpd->help_dialog,
|
|
DtNhelpVolume, help_volume,
|
|
DtNlocationId, location_id,
|
|
DtNhelpType, DtHELP_TYPE_TOPIC,
|
|
NULL);
|
|
/*
|
|
* pop up the help dialog
|
|
*/
|
|
XtManageChild(dpd->help_dialog);
|
|
dialog_shell = XtParent(dpd->help_dialog);
|
|
if(None != XtWindow(dialog_shell))
|
|
XRaiseWindow(XtDisplay(dialog_shell), XtWindow(dialog_shell));
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PresentVerifyError
|
|
*
|
|
* Description:
|
|
*
|
|
* Presents a error dialog appropriate for an error status returned
|
|
* by _DtPrintVerifyXPrinter.
|
|
*
|
|
* Return value:
|
|
*
|
|
* None.
|
|
*
|
|
*/
|
|
static void
|
|
PresentVerifyError(
|
|
Widget w,
|
|
XtEnum status,
|
|
String printer_spec)
|
|
{
|
|
String printer_name;
|
|
String display_spec;
|
|
|
|
_DtPrintParseXPrinterSpecifier(printer_spec,
|
|
&printer_name,
|
|
&display_spec);
|
|
switch(status)
|
|
{
|
|
case DtPRINT_PRINTER_MISSING:
|
|
PresentErrorDialog(w, INVALID_PRINTER_TITLE,
|
|
PRINTER_MISSING_MESSAGE,
|
|
printer_spec,
|
|
(String)NULL);
|
|
break;
|
|
|
|
case DtPRINT_NO_DEFAULT:
|
|
PresentErrorDialog(w, INVALID_PRINTER_TITLE,
|
|
NO_DEFAULT_MESSAGE,
|
|
(String)NULL);
|
|
break;
|
|
|
|
case DtPRINT_NO_DEFAULT_DISPLAY:
|
|
PresentErrorDialog(w, INVALID_PRINTER_TITLE,
|
|
NO_DEFAULT_DISPLAY_MESSAGE,
|
|
printer_name,
|
|
(String)NULL);
|
|
break;
|
|
|
|
case DtPRINT_NO_PRINTER:
|
|
PresentErrorDialog(w, INVALID_PRINTER_TITLE,
|
|
INVALID_PRINTER_MESSAGE,
|
|
printer_name, display_spec,
|
|
(String)NULL);
|
|
break;
|
|
|
|
case DtPRINT_NOT_XP_DISPLAY:
|
|
PresentErrorDialog(w, INVALID_PRINTER_TITLE,
|
|
NOT_XP_DISPLAY_MESSAGE,
|
|
display_spec,
|
|
(String)NULL);
|
|
break;
|
|
|
|
case DtPRINT_INVALID_DISPLAY:
|
|
PresentErrorDialog(w, INVALID_PRINTER_TITLE,
|
|
INVALID_DISPLAY_MESSAGE,
|
|
display_spec,
|
|
(String)NULL);
|
|
break;
|
|
}
|
|
XtFree(printer_name);
|
|
XtFree(display_spec);
|
|
}
|
|
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PrinterInfoDestroyCB
|
|
*
|
|
* Description:
|
|
*
|
|
* Reset data items used in conjunction with the
|
|
* printer information selection dialog.
|
|
*
|
|
* Return value:
|
|
*
|
|
* None.
|
|
*
|
|
*/
|
|
static void
|
|
PrinterInfoDestroyCB(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data)
|
|
{
|
|
DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(client_data);
|
|
|
|
dpd->printer_info_box = (Widget)NULL;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PrinterInfoHelpCB
|
|
*
|
|
* Description:
|
|
*
|
|
* Display context sensitive help.
|
|
*
|
|
* Return value:
|
|
*
|
|
* None.
|
|
*
|
|
*/
|
|
static void
|
|
PrinterInfoHelpCB(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data)
|
|
{
|
|
PresentHelp((Widget)client_data, HELP_VOLUME, PRINTER_INFO_HELP_ID);
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: SelectFileDestroyCB
|
|
*
|
|
* Description:
|
|
*
|
|
* Reset data items used in conjunction with the
|
|
* file selection dialog.
|
|
*
|
|
* Return value:
|
|
*
|
|
* None.
|
|
*
|
|
*/
|
|
static void
|
|
SelectFileDestroyCB(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data)
|
|
{
|
|
DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(client_data);
|
|
|
|
dpd->file_selection_box = (Widget)NULL;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: SelectFileHelpCB
|
|
*
|
|
* Description:
|
|
*
|
|
* Display context sensitive help.
|
|
*
|
|
* Return value:
|
|
*
|
|
* None.
|
|
*
|
|
*/
|
|
static void
|
|
SelectFileHelpCB(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data)
|
|
{
|
|
PresentHelp((Widget)client_data, HELP_VOLUME, SELECT_FILE_HELP_ID);
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: SelectPrinterCB
|
|
*
|
|
* Description:
|
|
*
|
|
* Callback to handle the printer selection box OK and Cancel
|
|
* buttons.
|
|
*
|
|
* Return value:
|
|
*
|
|
* None.
|
|
*
|
|
*/
|
|
static void
|
|
SelectPrinterCB(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data)
|
|
{
|
|
XmSelectionBoxCallbackStruct* cbs =
|
|
(XmSelectionBoxCallbackStruct*)call_data;
|
|
Widget psub = (Widget)client_data;
|
|
DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(psub);
|
|
String printer_spec;
|
|
|
|
/*
|
|
* close the info dialog display connection if it's been opened
|
|
*/
|
|
CloseSelectPrinterInfoConnection(dpd);
|
|
|
|
switch(cbs->reason)
|
|
{
|
|
case XmCR_OK:
|
|
/*
|
|
* set the selected printer name in the PrintSetupBox
|
|
*/
|
|
printer_spec = FindSelectedPrinter(XtDisplay(psub), dpd);
|
|
if((String)NULL != printer_spec)
|
|
{
|
|
XtVaSetValues(psub, DtNprinterName, printer_spec, NULL);
|
|
XtFree(printer_spec);
|
|
}
|
|
/*
|
|
* no break
|
|
*/
|
|
|
|
case XmCR_CANCEL:
|
|
/*
|
|
* deallocate and reset the lists
|
|
*/
|
|
FreeSelectPrinterData(dpd);
|
|
if(dpd->printer_list_box != (Widget)NULL)
|
|
XmListDeleteAllItems(dpd->printer_list_box);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: SelectPrinterDestroyCB
|
|
*
|
|
* Description:
|
|
*
|
|
* Deallocate and reset data items used in conjunction with the
|
|
* printer selection dialog.
|
|
*
|
|
* Return value:
|
|
*
|
|
* None.
|
|
*
|
|
*/
|
|
static void
|
|
SelectPrinterDestroyCB(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data)
|
|
{
|
|
DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(client_data);
|
|
|
|
dpd->printer_selection_box = (Widget)NULL;
|
|
dpd->printer_list_box = (Widget)NULL;
|
|
CloseSelectPrinterInfoConnection(dpd);
|
|
FreeSelectPrinterData(dpd);
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: SelectPrinterHelpCB
|
|
*
|
|
* Description:
|
|
*
|
|
* Display context sensitive help.
|
|
*
|
|
* Return value:
|
|
*
|
|
* None.
|
|
*
|
|
*/
|
|
static void
|
|
SelectPrinterHelpCB(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data)
|
|
{
|
|
PresentHelp((Widget)client_data, HELP_VOLUME, SELECT_PRINTER_HELP_ID);
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: SelectPrinterInfoCB
|
|
*
|
|
* Description:
|
|
*
|
|
* Callback attached to the printer selection box "Info..."
|
|
* button. The "Info..." button is intended to behave just like the
|
|
* PrintSetupBox "Info..." button, so it is implemented to call the
|
|
* procedure set for the PrintSetupBox DtNprinterInfoProc resource.
|
|
* As such, this function needs to open a new display connection to
|
|
* the print server indicated by the currently selected printer in
|
|
* the list. The connection is not closed until a selection is made
|
|
* in the list, or the printer selection dialog is dismissed. This is
|
|
* because no assumptions about the Printer Info dialog's widget
|
|
* hierarchy can be made.
|
|
*
|
|
* Return value:
|
|
*
|
|
* None.
|
|
*
|
|
*/
|
|
static void
|
|
SelectPrinterInfoCB(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data)
|
|
{
|
|
Widget psub = (Widget)client_data;
|
|
DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(psub);
|
|
DtPrintSetupProc info_proc;
|
|
|
|
CloseSelectPrinterInfoConnection(dpd);
|
|
XtVaGetValues(psub, DtNprinterInfoProc, &info_proc, NULL);
|
|
if((DtPrintSetupProc)NULL != info_proc)
|
|
{
|
|
String printer_spec;
|
|
|
|
printer_spec = FindSelectedPrinter(XtDisplay(psub), dpd);
|
|
if((String)NULL != printer_spec)
|
|
{
|
|
String new_printer_spec; /*
|
|
* will always be set to NULL by
|
|
* _DtPrintVerifyXPrinter when
|
|
* called from within this routine
|
|
*/
|
|
XtEnum status;
|
|
|
|
/*
|
|
* open a connection to the X printer
|
|
*/
|
|
status =
|
|
_DtPrintVerifyXPrinter(psub,
|
|
printer_spec,
|
|
&new_printer_spec,
|
|
&dpd->select_printer_info_display
|
|
#if 0 && defined(PRINTING_SUPPORTED)
|
|
,&dpd->select_printer_info_context
|
|
#endif /* PRINTING_SUPPORTED */
|
|
);
|
|
if(status == DtPRINT_SUCCESS)
|
|
{
|
|
DtPrintSetupData psd;
|
|
|
|
memset(&psd, 0, sizeof(DtPrintSetupData));
|
|
psd.printer_name = printer_spec;
|
|
psd.print_display = dpd->select_printer_info_display;
|
|
#if 0 && defined(PRINTING_SUPPORTED)
|
|
psd.print_context = dpd->select_printer_info_context;
|
|
#endif /* PRINTING_SUPPORTED */
|
|
(*info_proc)(psub, &psd);
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* this should only happen if, while a user is viewing
|
|
* the printer selection dialog, a server rehash is
|
|
* performed that deletes the currently selected printer
|
|
*/
|
|
PresentVerifyError(w, status, printer_spec);
|
|
}
|
|
XtFree(printer_spec);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: SelectPrinterItemCB
|
|
*
|
|
* Description:
|
|
*
|
|
* Callback to handle the a selection in the printer selection list
|
|
* box.
|
|
*
|
|
* Return value:
|
|
*
|
|
* None.
|
|
*
|
|
*/
|
|
static void
|
|
SelectPrinterItemCB(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data)
|
|
{
|
|
XmListCallbackStruct* cbs =
|
|
(XmListCallbackStruct*)call_data;
|
|
Widget psub = (Widget)client_data;
|
|
DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(psub);
|
|
Widget info_button;
|
|
|
|
if(dpd->selected_printer != cbs->item_position)
|
|
{
|
|
dpd->selected_printer = cbs->item_position;
|
|
info_button = XtNameToWidget(dpd->printer_selection_box, "*Apply");
|
|
if(0 == dpd->selected_printer)
|
|
XtSetSensitive(info_button, False);
|
|
else
|
|
XtSetSensitive(info_button, True);
|
|
/*
|
|
* update the default printer info dialog if it is visible
|
|
*/
|
|
if(dpd->printer_info_box && XtIsManaged(dpd->printer_info_box))
|
|
SelectPrinterInfoCB(w, client_data, (XtPointer)NULL);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: SetListBoxSelection
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
* None.
|
|
*
|
|
*/
|
|
static void
|
|
SetListBoxSelection(Widget list_box, int position)
|
|
{
|
|
int visible_item_count;
|
|
int item_count;
|
|
int middle_offset;
|
|
int first_visible_pos;
|
|
/*
|
|
* Scroll the list, making the item at the indicated position
|
|
* visible in the center of the list box, and make
|
|
* it the initial selection.
|
|
*/
|
|
XtVaGetValues(list_box,
|
|
XmNitemCount, &item_count,
|
|
XmNvisibleItemCount, &visible_item_count,
|
|
NULL);
|
|
|
|
if(item_count > visible_item_count)
|
|
{
|
|
middle_offset = (visible_item_count+1) / 2;
|
|
if(position > middle_offset)
|
|
if(position > item_count - middle_offset)
|
|
first_visible_pos = item_count - visible_item_count +1;
|
|
else
|
|
first_visible_pos = position - middle_offset + 1;
|
|
else
|
|
first_visible_pos = 1;
|
|
XmListSetPos(list_box, first_visible_pos);
|
|
}
|
|
|
|
if(position > 0)
|
|
XmListSelectPos(list_box, position, True);
|
|
else
|
|
XmListDeselectAllItems(list_box);
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: UpdateFileNameCB
|
|
*
|
|
* Description:
|
|
*
|
|
* Updates the PrintSetupBox fileName resource based on the selection
|
|
* make in the file selection box.
|
|
*
|
|
* Return value:
|
|
*
|
|
* None.
|
|
*
|
|
*/
|
|
static void
|
|
UpdateFileNameCB(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data)
|
|
{
|
|
Widget text_field;
|
|
Widget psub = (Widget)client_data;
|
|
String file_name;
|
|
/*
|
|
* get the file name from the file selection box text field
|
|
*/
|
|
text_field = XtNameToWidget(w, "Text");
|
|
if(text_field)
|
|
{
|
|
XtVaGetValues(text_field, XmNvalue, &file_name, NULL);
|
|
if(file_name)
|
|
{
|
|
/*
|
|
* set the file name in the print setup box
|
|
*/
|
|
XtVaSetValues(psub, DtNfileName, file_name, NULL);
|
|
/*
|
|
* free the file name retrieved from the text field
|
|
*/
|
|
XtFree(file_name);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: _DtPrintDefProcInitialize
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*
|
|
*/
|
|
void
|
|
_DtPrintDefProcInitialize(Widget w)
|
|
{
|
|
DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
|
|
|
|
dpd->error_message_box = (Widget)NULL;
|
|
dpd->messages_hint = DtPRINT_HINT_MESSAGES_OK;
|
|
dpd->help_dialog = (Widget)NULL;
|
|
dpd->file_selection_box = (Widget)NULL;
|
|
dpd->printer_selection_box = (Widget)NULL;
|
|
dpd->printer_list_box = (Widget)NULL;
|
|
dpd->xp_server_list = (String*)NULL;
|
|
dpd->xp_server_count = 0;
|
|
dpd->printer_lists = (DtPrintSelectPrinterList*)NULL;
|
|
dpd->selected_printer = 0;
|
|
dpd->select_printer_info_display = (Display*)NULL;
|
|
#if 0 && defined(PRINTING_SUPPORTED)
|
|
dpd->select_printer_info_context = (XPContext)None;
|
|
#endif /* PRINTING_SUPPORTED */
|
|
dpd->printer_info_box = (Widget)NULL;
|
|
|
|
XtAddCallback(w, XmNdestroyCallback,
|
|
DtPrintDefProcDestroyCB, (XtPointer)NULL);
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: _DtPrintDefProcManageErrorBox
|
|
*
|
|
* Description:
|
|
*
|
|
* Manage the Error Message Box if it exists.
|
|
*
|
|
* Return value:
|
|
*
|
|
*
|
|
*/
|
|
void
|
|
_DtPrintDefProcManageErrorBox(
|
|
DtPrintDefaultProcData* dpd)
|
|
{
|
|
if(dpd->error_message_box != (Widget)NULL)
|
|
XtManageChild(dpd->error_message_box);
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: _DtPrintSetupBoxXPrinterInfoProc
|
|
*
|
|
* Description:
|
|
*
|
|
* Default Xp mode function for the DtNprinterInfoProc resource.
|
|
*
|
|
* Return value:
|
|
*
|
|
*
|
|
*/
|
|
XtEnum
|
|
_DtPrintSetupBoxXPrinterInfoProc(
|
|
Widget w,
|
|
DtPrintSetupData* print_data)
|
|
{
|
|
DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
|
|
Widget wmshell_ancestor;
|
|
Widget ctl;
|
|
XmString label;
|
|
char* attr_value_ct = NULL;
|
|
String attr_value = NULL;
|
|
XmString empty_label;
|
|
Widget name_label_top;
|
|
Position max_y, y;
|
|
Dimension height;
|
|
Widget manager = NULL;
|
|
Widget dialog_shell;
|
|
|
|
wmshell_ancestor = GetWMShellAncestor(w);
|
|
_DtTurnOnHourGlass(wmshell_ancestor);
|
|
empty_label = XmStringCreateLocalized("");
|
|
/*
|
|
* if needed, create the printer information dialog
|
|
*/
|
|
if(dpd->printer_info_box == (Widget)NULL)
|
|
{
|
|
XtEnum status = CreatePrinterInfoBox(wmshell_ancestor, w, dpd);
|
|
if(status != DtPRINT_SUCCESS)
|
|
{
|
|
_DtTurnOffHourGlass(wmshell_ancestor);
|
|
return status;
|
|
}
|
|
dialog_shell = XtParent(dpd->printer_info_box);
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* hide the widget during re-layout
|
|
*/
|
|
manager = XtNameToWidget(dpd->printer_info_box, "*PrinterInfoForm");
|
|
XtUnmapWidget(dpd->printer_info_box);
|
|
dialog_shell = XtParent(dpd->printer_info_box);
|
|
XtVaSetValues(dialog_shell, XmNallowShellResize, False, NULL);
|
|
XtUnmanageChild(manager);
|
|
}
|
|
/*
|
|
* description
|
|
*/
|
|
ctl = XtNameToWidget(dpd->printer_info_box, "*Description");
|
|
XtVaSetValues(ctl, XmNlabelString, empty_label, NULL);
|
|
#if 0 && defined(PRINTING_SUPPORTED)
|
|
attr_value_ct = XpGetOneAttribute(print_data->print_display,
|
|
print_data->print_context,
|
|
XPPrinterAttr,
|
|
"descriptor");
|
|
#endif /* PRINTING_SUPPORTED */
|
|
if((char*)NULL != attr_value_ct)
|
|
{
|
|
attr_value =
|
|
CompoundTextToString(XtDisplay(w), (unsigned char*)attr_value_ct);
|
|
XFree(attr_value_ct);
|
|
if((String)NULL != attr_value)
|
|
{
|
|
label = XmStringGenerate((XtPointer)attr_value, (XmStringTag)NULL,
|
|
XmMULTIBYTE_TEXT, (XmStringTag)NULL);
|
|
XtFree(attr_value);
|
|
XtVaSetValues(ctl, XmNlabelString, label, NULL);
|
|
XmStringFree(label);
|
|
}
|
|
}
|
|
/*
|
|
* set the top attachment for the name label
|
|
*/
|
|
XtVaGetValues(ctl, XmNy, &y, XmNheight, &height, NULL);
|
|
max_y = y + height;
|
|
name_label_top = ctl;
|
|
ctl = XtNameToWidget(dpd->printer_info_box, "*DescriptionLabel");
|
|
XtVaGetValues(ctl, XmNy, &y, XmNheight, &height, NULL);
|
|
if(y+height > max_y)
|
|
name_label_top = ctl;
|
|
ctl = XtNameToWidget(dpd->printer_info_box, "*NameLabel");
|
|
XtVaSetValues(ctl, XmNtopWidget, name_label_top, NULL);
|
|
/*
|
|
* printer name
|
|
*/
|
|
ctl = XtNameToWidget(dpd->printer_info_box, "*Name");
|
|
label = XmStringCreateLocalized(print_data->printer_name);
|
|
XtVaSetValues(ctl, XmNlabelString, label, NULL);
|
|
XmStringFree(label);
|
|
/*
|
|
* document format
|
|
*/
|
|
ctl = XtNameToWidget(dpd->printer_info_box, "*Format");
|
|
XtVaSetValues(ctl, XmNlabelString, empty_label, NULL);
|
|
#if 0 && defined(PRINTING_SUPPORTED)
|
|
attr_value = XpGetOneAttribute(print_data->print_display,
|
|
print_data->print_context,
|
|
XPDocAttr,
|
|
"document-format");
|
|
#endif /* PRINTING_SUPPORTED */
|
|
if((String)NULL != attr_value)
|
|
{
|
|
char* format_start;
|
|
format_start = strchr(attr_value, '{');
|
|
if((char*)NULL != format_start)
|
|
{
|
|
char* format_end;
|
|
++format_start;
|
|
format_end = strchr(format_start, '}');
|
|
if((char*)NULL != format_end)
|
|
{
|
|
*format_end = '\0';
|
|
label = XmStringCreateLocalized(format_start);
|
|
XtVaSetValues(ctl, XmNlabelString, label, NULL);
|
|
XmStringFree(label);
|
|
}
|
|
}
|
|
XFree(attr_value);
|
|
}
|
|
/*
|
|
* printer model
|
|
*/
|
|
ctl = XtNameToWidget(dpd->printer_info_box, "*Model");
|
|
XtVaSetValues(ctl, XmNlabelString, empty_label, NULL);
|
|
#if 0 && defined(PRINTING_SUPPORTED)
|
|
attr_value_ct = XpGetOneAttribute(print_data->print_display,
|
|
print_data->print_context,
|
|
XPPrinterAttr,
|
|
"printer-model");
|
|
#endif /* PRINTING_SUPPORTED */
|
|
if((char*)NULL != attr_value_ct)
|
|
{
|
|
attr_value =
|
|
CompoundTextToString(XtDisplay(w), (unsigned char*)attr_value_ct);
|
|
XFree(attr_value_ct);
|
|
if((String)NULL != attr_value)
|
|
{
|
|
label = XmStringGenerate((XtPointer)attr_value, (XmStringTag)NULL,
|
|
XmCHARSET_TEXT, (XmStringTag)NULL);
|
|
XtFree(attr_value);
|
|
XtVaSetValues(ctl, XmNlabelString, label, NULL);
|
|
XmStringFree(label);
|
|
}
|
|
}
|
|
/*
|
|
* pop up the printer info dialog and return
|
|
*/
|
|
XmStringFree(empty_label);
|
|
if(manager)
|
|
{
|
|
XtVaSetValues(dialog_shell, XmNallowShellResize, True, NULL);
|
|
XtManageChild(manager);
|
|
XtMapWidget(dpd->printer_info_box);
|
|
}
|
|
XtManageChild(dpd->printer_info_box);
|
|
if(None != XtWindow(dialog_shell))
|
|
XRaiseWindow(XtDisplay(dialog_shell), XtWindow(dialog_shell));
|
|
_DtTurnOffHourGlass(wmshell_ancestor);
|
|
return DtPRINT_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: _DtPrintSetupBoxSelectFileProc
|
|
*
|
|
* Description:
|
|
*
|
|
* Default function for the DtNselectFileProc resource.
|
|
*
|
|
* Return value:
|
|
*
|
|
*
|
|
*/
|
|
XtEnum
|
|
_DtPrintSetupBoxSelectFileProc(
|
|
Widget w,
|
|
DtPrintSetupData* print_data)
|
|
{
|
|
DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
|
|
String name_only;
|
|
String file_name;
|
|
XmString pattern;
|
|
Widget file_list;
|
|
Widget text_field;
|
|
Widget wmshell_ancestor;
|
|
|
|
wmshell_ancestor = GetWMShellAncestor(w);
|
|
_DtTurnOnHourGlass(wmshell_ancestor);
|
|
/*
|
|
* if needed, create the file selection dialog
|
|
*/
|
|
if(dpd->file_selection_box == (Widget)NULL)
|
|
{
|
|
XtEnum status = CreateFileSelectionBox(wmshell_ancestor, w, dpd);
|
|
if(status != DtPRINT_SUCCESS)
|
|
{
|
|
_DtTurnOffHourGlass(wmshell_ancestor);
|
|
return status;
|
|
}
|
|
}
|
|
/*
|
|
* get the file name passed from the PrintSetupBox
|
|
*/
|
|
file_name = print_data->dest_info;
|
|
/*
|
|
* parse the file name to create the filter pattern and the name only
|
|
* portion of the full name spec
|
|
*/
|
|
ParseFileNameSpec(file_name, &pattern, &name_only);
|
|
/*
|
|
* set the filter pattern in the file selection box
|
|
*/
|
|
XtVaSetValues(dpd->file_selection_box, XmNpattern, pattern, NULL);
|
|
if(pattern != (XmString)NULL)
|
|
XmStringFree(pattern);
|
|
/*
|
|
* select the current file name in the file names list
|
|
*/
|
|
file_list = XtNameToWidget(dpd->file_selection_box, "*ItemsList");
|
|
if(file_list != (Widget)NULL)
|
|
{
|
|
XmString file_name_xmstr;
|
|
int position;
|
|
|
|
text_field = XtNameToWidget(dpd->file_selection_box, "Text");
|
|
if(text_field != (Widget)NULL)
|
|
{
|
|
String dir_spec;
|
|
/*
|
|
* recreate the file name from the name_only and the current
|
|
* dir spec as determined by the file selection box
|
|
*
|
|
* Note: the char* value retrieved directly from the text
|
|
* field is used, because forming the file name from a
|
|
* concatenation of XmStrings causes XmListItemPos to fail
|
|
* even though the file name is actually in the list.
|
|
*/
|
|
XtVaGetValues(text_field, XmNvalue, &dir_spec, NULL);
|
|
file_name = XtMalloc(strlen(dir_spec)+strlen(name_only)+1);
|
|
strcpy(file_name, dir_spec);
|
|
strcat(file_name, name_only);
|
|
file_name_xmstr = XmStringCreateLocalized(file_name);
|
|
XtFree(dir_spec);
|
|
XtFree(file_name);
|
|
}
|
|
else
|
|
file_name_xmstr = XmStringCreateLocalized(file_name);
|
|
/*
|
|
* find the position of the file name in the list
|
|
*/
|
|
position = XmListItemPos(file_list, file_name_xmstr);
|
|
SetListBoxSelection(file_list, position);
|
|
if(position == 0)
|
|
{
|
|
/*
|
|
* The file name is not in the list. Manually set in the
|
|
* "Selection" text field.
|
|
*/
|
|
XtVaSetValues(dpd->file_selection_box,
|
|
XmNdirSpec, file_name_xmstr,
|
|
NULL);
|
|
}
|
|
XmStringFree(file_name_xmstr);
|
|
}
|
|
XtFree(name_only);
|
|
/*
|
|
* pop up the file selection dialog and return
|
|
*/
|
|
XtManageChild(dpd->file_selection_box);
|
|
_DtTurnOffHourGlass(wmshell_ancestor);
|
|
return DtPRINT_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: _DtPrintSetupBoxSelectXPrinterProc
|
|
*
|
|
* Description:
|
|
*
|
|
* Default Xp mode function for the DtNselectPrinterProc resource.
|
|
*
|
|
* Return value:
|
|
*
|
|
*
|
|
*/
|
|
XtEnum
|
|
_DtPrintSetupBoxSelectXPrinterProc(
|
|
Widget w,
|
|
DtPrintSetupData* print_data)
|
|
{
|
|
DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
|
|
Widget wmshell_ancestor;
|
|
XmStringTable items;
|
|
int item_count;
|
|
int i;
|
|
XmTabList tab_list;
|
|
XmRenderTable render_table, new_render_table;
|
|
int count;
|
|
XmStringTag* tags;
|
|
XmRendition rendition;
|
|
Arg args[2];
|
|
Cardinal n;
|
|
|
|
wmshell_ancestor = GetWMShellAncestor(w);
|
|
_DtTurnOnHourGlass(wmshell_ancestor);
|
|
/*
|
|
* build the list of servers and printers
|
|
*/
|
|
if(DtPRINT_SUCCESS != BuildPrinterLists(w, dpd, &item_count))
|
|
{
|
|
PresentErrorDialog(w, PRLIST_ERROR_TITLE,
|
|
NO_PRINTERS_MESSAGE,
|
|
(String)NULL);
|
|
_DtTurnOffHourGlass(wmshell_ancestor);
|
|
return DtPRINT_FAILURE;
|
|
}
|
|
/*
|
|
* create the dialog if it doesn't exist
|
|
*/
|
|
if(dpd->printer_selection_box == (Widget)NULL)
|
|
{
|
|
XtEnum status = CreatePrinterSelectionBox(wmshell_ancestor, w, dpd);
|
|
if(status != DtPRINT_SUCCESS)
|
|
{
|
|
_DtTurnOffHourGlass(wmshell_ancestor);
|
|
return status;
|
|
}
|
|
}
|
|
/*
|
|
* get a copy of the list widget's render table
|
|
*/
|
|
XtVaGetValues(dpd->printer_list_box,
|
|
XmNrenderTable, &render_table,
|
|
NULL);
|
|
render_table = XmRenderTableCopy(render_table, (XmStringTag*)NULL, 0);
|
|
/*
|
|
* build the item list for the list box
|
|
*/
|
|
count = XmRenderTableGetTags(render_table, &tags);
|
|
items = BuildPrinterSelectionItems(XtDisplay(w), dpd, item_count,
|
|
print_data->printer_name, tags[0]);
|
|
/*
|
|
* generate a tab list for the items
|
|
*/
|
|
tab_list = XmStringTableProposeTablist(items, item_count,
|
|
dpd->printer_list_box,
|
|
20, XmRELATIVE);
|
|
/*
|
|
* get a copy of the first rendition in the render table
|
|
*/
|
|
rendition = XmRenderTableGetRendition(render_table, tags[0]);
|
|
for(i = 0; i < count; i++)
|
|
XtFree(tags[i]);
|
|
XtFree((char*)tags);
|
|
/*
|
|
* update the copy with the new tab list
|
|
*/
|
|
n = 0;
|
|
XtSetArg(args[n], XmNtabList, tab_list); n++;
|
|
XmRenditionUpdate(rendition, args, n);
|
|
XmTabListFree(tab_list);
|
|
/*
|
|
* create a new render table replacing the first entry with the
|
|
* updated rendition
|
|
*/
|
|
new_render_table = XmRenderTableAddRenditions(render_table, &rendition,
|
|
1, XmMERGE_REPLACE);
|
|
XmRenditionFree(rendition);
|
|
/*
|
|
* set the new render table and list items in the list box
|
|
*/
|
|
XtVaSetValues(dpd->printer_list_box,
|
|
XmNrenderTable, new_render_table,
|
|
XmNitems, items,
|
|
XmNitemCount, item_count,
|
|
NULL);
|
|
XmRenderTableFree(new_render_table);
|
|
for(i = 0; i < item_count; i++)
|
|
XmStringFree(items[i]);
|
|
XtFree((char*)items);
|
|
SetListBoxSelection(dpd->printer_list_box, dpd->selected_printer);
|
|
/*
|
|
* disable the info button if nothing is selected
|
|
*/
|
|
if(0 == dpd->selected_printer)
|
|
XtSetSensitive(XtNameToWidget(dpd->printer_selection_box, "*Apply"),
|
|
False);
|
|
/*
|
|
* manage the dialog and return
|
|
*/
|
|
XtManageChild(dpd->printer_selection_box);
|
|
_DtTurnOffHourGlass(wmshell_ancestor);
|
|
return DtPRINT_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: _DtPrintSetupBoxVerifyXPrinterProc
|
|
*
|
|
* Description:
|
|
*
|
|
* Default function for the DtNverifyPrinterProc resource when the
|
|
* setup mode is XP.
|
|
*
|
|
* (this rest of this description outlines the responsibilities of a
|
|
* DtNverifyPrinterProc in general)
|
|
*
|
|
* This function verifies the printer name passed in the
|
|
* PrintSetupData structure.
|
|
*
|
|
* If needed, the DtNprintSetupMode resource may be obtained via a
|
|
* GetValues call in order to determine the current setup mode.
|
|
*
|
|
* It is the responsibility of this proc to return a valid print
|
|
* Display handle and print context by setting the print_display and
|
|
* print_context in the PrintSetupData. Conceptually, this is a
|
|
* side-effect of this proc, but since it will be necessary to open a
|
|
* display connection in order to properly verify the X printer,
|
|
* there's no point in doing it twice.
|
|
*
|
|
* If the passed printer name is incomplete, this proc may attempt to
|
|
* determine a default or fully-qualified name (e.g. fill in a
|
|
* missing display spec for an X Printer Specifier). The new default
|
|
* or fully-qualified printer name should be set in the PrintSetupBox
|
|
* by updating the DtNprinterName resource via a SetValues call. If a
|
|
* fully-qualified name cannot be determined, this proc simply
|
|
* returns DtPRINT_FAILURE.
|
|
*
|
|
* If the printer cannot be verified, it is the responsibiliy of this
|
|
* function to present an appropriate message to the user.
|
|
*
|
|
* Return value:
|
|
*
|
|
* DtPRINT_SUCCESS
|
|
* if the printer name has been successfully verified.
|
|
*
|
|
* DtPRINT_FAILURE
|
|
* if the printer name is invalid.
|
|
*
|
|
*
|
|
*/
|
|
XtEnum
|
|
_DtPrintSetupBoxVerifyXPrinterProc(
|
|
Widget w,
|
|
DtPrintSetupData* psd)
|
|
{
|
|
DtPrintDefaultProcData* dpd = &PSUB_DefaultProcData(w);
|
|
XtEnum status;
|
|
String new_printer_spec;
|
|
Display* new_display;
|
|
#if 0 && defined(PRINTING_SUPPORTED)
|
|
XPContext new_context;
|
|
#endif /* PRINTING_SUPPORTED */
|
|
Widget wmshell_ancestor;
|
|
|
|
wmshell_ancestor = GetWMShellAncestor(w);
|
|
_DtTurnOnHourGlass(wmshell_ancestor);
|
|
/*
|
|
* verify the printer
|
|
*/
|
|
status = _DtPrintVerifyXPrinter(w,
|
|
psd->printer_name,
|
|
&new_printer_spec,
|
|
&new_display
|
|
#if 0 && defined(PRINTING_SUPPORTED)
|
|
,&new_context
|
|
#endif /* PRINTING_SUPPORTED */
|
|
);
|
|
if(status == DtPRINT_SUCCESS)
|
|
{
|
|
/*
|
|
* update the passed print setup data with the new display and
|
|
* context
|
|
*/
|
|
psd->print_display = new_display;
|
|
#if 0 && defined(PRINTING_SUPPORTED)
|
|
psd->print_context = new_context;
|
|
#endif /* PRINTING_SUPPORTED */
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* unable to open the printer; present a message to the user
|
|
* according to the hint set in the setup data
|
|
*/
|
|
dpd->messages_hint = psd->messages_hint;
|
|
PresentVerifyError(w, status,
|
|
new_printer_spec
|
|
? new_printer_spec : psd->printer_name);
|
|
/*
|
|
* reset the hint since the error dialog is also used
|
|
* by the other default procs
|
|
*/
|
|
dpd->messages_hint = DtPRINT_HINT_MESSAGES_OK;
|
|
/*
|
|
* this function only indicates success or failure
|
|
*/
|
|
status = DtPRINT_FAILURE;
|
|
}
|
|
if(new_printer_spec)
|
|
{
|
|
/*
|
|
* set the new printer spec, even if the verify failed
|
|
*/
|
|
XtVaSetValues(w,
|
|
DtNprinterName, new_printer_spec,
|
|
NULL);
|
|
XtFree(new_printer_spec);
|
|
}
|
|
/*
|
|
* return
|
|
*/
|
|
_DtTurnOffHourGlass(wmshell_ancestor);
|
|
return status;
|
|
}
|