504 lines
14 KiB
C
504 lines
14 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: Print.c /main/16 1996/11/11 10:56:18 drk $ */
|
|
|
|
#include "PrintDemo.h"
|
|
|
|
/*
|
|
* static function declarations
|
|
*/
|
|
static void PrintCB(Widget, XtPointer, XtPointer);
|
|
static void DoPrint(Widget widget, AppPrintData * p) ;
|
|
static void StartJobCB(Widget, XtPointer, XtPointer);
|
|
static void Print(AppPrintData *p);
|
|
static void PrintCloseDisplayCB(Widget, XtPointer, XtPointer);
|
|
static void PageSetupCB(Widget, XtPointer, XtPointer);
|
|
static void PdmNotifyCB(Widget, XtPointer, XtPointer);
|
|
static void PrintSetupCB(Widget, XtPointer, XtPointer);
|
|
static void FinishPrintToFile(Display*, XPContext, XPGetDocStatus, XPointer);
|
|
static void CreatePrintShell(Widget, AppPrintData*);
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmNotifyCB
|
|
*
|
|
* Description:
|
|
*
|
|
* Called when the PDM is up, or down.
|
|
*
|
|
*/
|
|
static void
|
|
PdmNotifyCB(Widget pr_shell, XtPointer client_data, XtPointer call_data)
|
|
{
|
|
XmPrintShellCallbackStruct* pr_cbs =
|
|
(XmPrintShellCallbackStruct*) call_data;
|
|
AppPrintData * p = (AppPrintData *) client_data ;
|
|
|
|
if (pr_cbs->reason == XmCR_PDM_NONE) {
|
|
/* put out a real message dialog */
|
|
printf("No PDM found in the environment\n");
|
|
} else
|
|
if (pr_cbs->reason == XmCR_PDM_START_ERROR) {
|
|
/* put out a real message dialog */
|
|
printf("Cannot start the PDM\n");
|
|
} else
|
|
if (pr_cbs->reason == XmCR_PDM_START_VXAUTH) {
|
|
/* put out a real message dialog */
|
|
printf("PDM is not authorized to connect to Video display\n");
|
|
} else
|
|
if (pr_cbs->reason == XmCR_PDM_START_PXAUTH) {
|
|
/* put out a real message dialog */
|
|
printf("PDM is not authorized to connect to Print display\n");
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PrintMenuCB
|
|
*
|
|
* Description:
|
|
*
|
|
* Called when the user selects the "Print..." menu item.
|
|
*
|
|
*/
|
|
void
|
|
PrintMenuCB(Widget pr_button, XtPointer client_data, XtPointer call_data)
|
|
{
|
|
AppPrintData* p = (AppPrintData*)client_data;
|
|
|
|
/* only propose a new print job if one is not already running
|
|
shouldn't happen since we put the button insensitive */
|
|
if (!p->printed_lines) {
|
|
CreatePrintSetup(pr_button, p);
|
|
|
|
XtManageChild(p->print_dialog); /* popup dialog each time */
|
|
|
|
} else {
|
|
/* real dialog here */
|
|
printf("Print job already running\n");
|
|
}
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: CreatePrintShell
|
|
*
|
|
* Description:
|
|
*
|
|
* Called when the user selects the "Print" or the "Setup..." button
|
|
* in the setupbox.
|
|
*
|
|
*/
|
|
|
|
static void CreatePrintShell(Widget widget, AppPrintData* p)
|
|
{
|
|
/*
|
|
* create a print_shell if none available. the print dialog callback
|
|
* always provides valid printer context and print display initialized:
|
|
* XpInitContext called, attributes set.
|
|
*/
|
|
|
|
if (!p->print_shell) {
|
|
p->print_shell =
|
|
XmPrintSetup(widget,
|
|
XpGetScreenOfContext(p->print_data->print_display,
|
|
p->print_data->print_context),
|
|
"Print", NULL, 0);
|
|
|
|
XtAddCallback(p->print_shell, XmNpageSetupCallback,
|
|
PageSetupCB, (XtPointer)p);
|
|
XtAddCallback(p->print_shell, XmNpdmNotificationCallback,
|
|
PdmNotifyCB, (XtPointer)p);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PrintSetupCB
|
|
*
|
|
* Description:
|
|
*
|
|
* Called when the user presses the setup box "Setup..." button.
|
|
*
|
|
*/
|
|
static void
|
|
PrintSetupCB(Widget print_dialog, XtPointer client_data, XtPointer call_data)
|
|
{
|
|
AppPrintData *p = (AppPrintData*)client_data;
|
|
DtPrintSetupCallbackStruct *pbs = (DtPrintSetupCallbackStruct*)call_data;
|
|
int copies ;
|
|
|
|
XtVaGetValues(print_dialog, DtNcopies, &copies, NULL);
|
|
if (copies == 3) {
|
|
String attr ;
|
|
Display * pdpy = pbs->print_data->print_display ;
|
|
XPContext pcontext = pbs->print_data->print_context ;
|
|
|
|
attr = XpGetAttributes (pdpy, pcontext, XPPageAttr);
|
|
if (attr) printf ("XPPageAttr:\n%s\n----------------------\n", attr);
|
|
attr = XpGetAttributes (pdpy, pcontext, XPDocAttr);
|
|
if (attr) printf ("XPDocAttr:\n%s\n----------------------\n", attr);
|
|
attr = XpGetAttributes (pdpy, pcontext, XPJobAttr);
|
|
if (attr) printf ("XPJobAttr:\n%s\n----------------------\n", attr);
|
|
attr = XpGetAttributes (pdpy, pcontext, XPPrinterAttr);
|
|
if (attr) printf ("XPPrinterAttr:\n%s\n----------------------\n", attr);
|
|
attr = XpGetAttributes (pdpy, pcontext, XPServerAttr);
|
|
if (attr) printf ("XPServerAttr:\n%s\n----------------------\n", attr);
|
|
|
|
return ;
|
|
}
|
|
|
|
/* copy the setup data into our space */
|
|
if (p->print_data->print_display != NULL)
|
|
DtPrintFreeSetupData(p->print_data);
|
|
DtPrintCopySetupData(p->print_data, pbs->print_data);
|
|
|
|
/* create a print shell if not already done */
|
|
CreatePrintShell(print_dialog, p);
|
|
|
|
/* pop up the PDM */
|
|
if (XmPrintPopupPDM(p->print_shell, XtParent(print_dialog))
|
|
!= XmPDM_NOTIFY_SUCCESS) {
|
|
/* post a message error dialog */
|
|
printf("XmPrintPopupPDM failed\n");
|
|
}
|
|
|
|
/* Free the setup data - use fresh data when Print button pressed. */
|
|
DtPrintFreeSetupData(p->print_data);
|
|
}
|
|
|
|
static void
|
|
CancelCB(Widget print_dialog, XtPointer client_data, XtPointer call_data)
|
|
{
|
|
AppPrintData *p = (AppPrintData*)client_data;
|
|
DtPrintSetupCallbackStruct *pbs = (DtPrintSetupCallbackStruct*)call_data;
|
|
|
|
/* mostly to try it out */
|
|
XtDestroyWidget(print_dialog); p->print_dialog = NULL ;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: CreatePrintSetup
|
|
*
|
|
* Description:
|
|
*
|
|
* Creates a DtPrintSetupBox dialog.
|
|
*
|
|
*/
|
|
void
|
|
CreatePrintSetup(Widget parent, AppPrintData* p)
|
|
{
|
|
/*
|
|
* only create one PrintSetupBox
|
|
*/
|
|
if(!p->print_dialog)
|
|
{
|
|
Cardinal n = 0;
|
|
Arg args[5];
|
|
|
|
/* can be called when print_only is up, which means no need
|
|
for a dialog */
|
|
if(XtIsApplicationShell(parent))
|
|
p->print_dialog =
|
|
DtCreatePrintSetupBox(parent, "PrintSetup", NULL, 0);
|
|
else
|
|
{
|
|
XmString title = XmStringCreateLocalized("Print");
|
|
XtSetArg(args[n], XmNdialogTitle, title); n++;
|
|
p->print_dialog =
|
|
DtCreatePrintSetupDialog(parent, "PrintSetup", args, n);
|
|
XmStringFree(title);
|
|
}
|
|
/*
|
|
* allow the application to customize the print setup box
|
|
*/
|
|
AppObject_customizePrintSetupBox(p->app_object, p->print_dialog);
|
|
/*
|
|
* add typically used callbacks
|
|
*/
|
|
XtAddCallback(p->print_dialog, DtNclosePrintDisplayCallback,
|
|
PrintCloseDisplayCB, p);
|
|
XtAddCallback(p->print_dialog, DtNsetupCallback,
|
|
PrintSetupCB, p);
|
|
XtAddCallback(p->print_dialog, DtNprintCallback,
|
|
PrintCB, p);
|
|
XtAddCallback(p->print_dialog, DtNcancelCallback,
|
|
CancelCB, p);
|
|
/*
|
|
* other callbacks, for attributes management, are available
|
|
*/
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PrintCB
|
|
*
|
|
* Description:
|
|
*
|
|
* Called when the user presses the setup box "Print" button.
|
|
*
|
|
*/
|
|
static void
|
|
PrintCB(Widget print_dialog, XtPointer client_data, XtPointer call_data)
|
|
{
|
|
AppPrintData *p = (AppPrintData*)client_data;
|
|
DtPrintSetupCallbackStruct *pbs = (DtPrintSetupCallbackStruct*)call_data;
|
|
|
|
/*
|
|
* get the new printer data from the DtPrintSetupBox, and copy it
|
|
* into our AppPrint data
|
|
*/
|
|
if (p->print_data->print_display != NULL)
|
|
DtPrintFreeSetupData(p->print_data);
|
|
DtPrintCopySetupData(p->print_data, pbs->print_data);
|
|
|
|
DoPrint(print_dialog, p);
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: QuickPrintCB
|
|
*
|
|
* Description:
|
|
*
|
|
* Called when the user hits "Print" quick button.
|
|
*/
|
|
void
|
|
QuickPrintCB(Widget pr_button, XtPointer client_data, XtPointer call_data)
|
|
{
|
|
AppPrintData *p = (AppPrintData*)client_data;
|
|
|
|
CreatePrintSetup(pr_button, p);
|
|
|
|
/*
|
|
* check if the DtPrintSetupBox ("Print...") has been called yet
|
|
*/
|
|
if(p->print_data->print_display == NULL)
|
|
{
|
|
/*
|
|
* first time thru print setup, so get default data
|
|
*/
|
|
if (DtPrintFillSetupData(p->print_dialog, p->print_data)
|
|
!= DtPRINT_SUCCESS) {
|
|
/* post some message error dialog */
|
|
printf("DtPrintFillSetupData failed\n");
|
|
return ;
|
|
}
|
|
}
|
|
|
|
DoPrint(pr_button, p) ;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: FinishPrintToFile
|
|
*
|
|
* Description:
|
|
*
|
|
* App-specific print data holder allocate function.
|
|
*
|
|
*/
|
|
static void FinishPrintToFile(Display *display,
|
|
XPContext context,
|
|
XPGetDocStatus status,
|
|
XPointer client_data)
|
|
{
|
|
if (status != XPGetDocFinished)
|
|
/* put out a real message dialog */
|
|
printf("Something went wrong with XmPrintToFile...\n");
|
|
else
|
|
printf("XmPrintToFile completed OK\n");
|
|
}
|
|
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: DoPrint
|
|
*
|
|
* Description:
|
|
*
|
|
* Routine used from the "Print" button and from the OK button of the
|
|
* "Print..." dialog.
|
|
*
|
|
*/
|
|
static void
|
|
DoPrint(Widget widget, AppPrintData * p)
|
|
{
|
|
int save_data = XPSpool;
|
|
|
|
/* create print shell, if not done yet */
|
|
CreatePrintShell(widget, p);
|
|
|
|
if (p->print_data->destination == DtPRINT_TO_FILE)
|
|
save_data = XPGetData;
|
|
|
|
/* start job must precede XpGetDocumentData in XmPrintToFile */
|
|
XpStartJob(XtDisplay(p->print_shell), save_data);
|
|
|
|
/* setup print to file */
|
|
if (p->print_data->destination == DtPRINT_TO_FILE)
|
|
{
|
|
if (!XmPrintToFile(XtDisplay(p->print_shell),
|
|
p->print_data->dest_info, FinishPrintToFile, NULL))
|
|
{
|
|
/* Add real error message here. */
|
|
printf("XmPrintToFile: Unable to print to file %s\n",
|
|
p->print_data->dest_info);
|
|
|
|
XpCancelJob(XtDisplay(p->print_shell), False);
|
|
|
|
/* we can go back to the event loop as if we had never
|
|
printed */
|
|
return;
|
|
}
|
|
}
|
|
|
|
XtSetSensitive(p->pr_button, False);
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PageSetupCB
|
|
*
|
|
* Description:
|
|
*
|
|
* Called when the print shell receives the XP events.
|
|
*
|
|
*/
|
|
static void
|
|
PageSetupCB(Widget widget, XtPointer client_data, XtPointer call_data)
|
|
{
|
|
Widget pshell = widget ;
|
|
XmPrintShellCallbackStruct* pr_cbs =
|
|
(XmPrintShellCallbackStruct*) call_data;
|
|
AppPrintData * p = (AppPrintData *) client_data ;
|
|
|
|
/* could have real indicator of progress here */
|
|
printf("Printed Lines %d\n", p->printed_lines);
|
|
|
|
/* the first time around, create a print text widget and get
|
|
line info - equivalent for testing for first page*/
|
|
if (!pr_cbs->last_page && !p->printed_lines) {
|
|
|
|
/* create the widgets once */
|
|
if (!p->pform) {
|
|
/* create a form widget with some fixed margins */
|
|
p->pform = XtVaCreateManagedWidget("pform", xmFormWidgetClass,
|
|
pshell, NULL);
|
|
/* create a text widget */
|
|
p->ptext = XtVaCreateManagedWidget("ptext", xmTextWidgetClass,
|
|
p->pform, NULL);
|
|
}
|
|
/* transfer value from file buffer to print text widget */
|
|
XmTextSetString(p->ptext, p->app_object->file_buffer );
|
|
|
|
/* get lines per page and total lines */
|
|
XtVaGetValues(p->ptext, XmNrows, &(p->lines_per_page),
|
|
XmNtotalLines, &(p->total_lines), NULL);
|
|
|
|
p->printed_lines += p->lines_per_page ;
|
|
|
|
/* If I'm already done: fit in one page, set last_page up */
|
|
if (p->printed_lines >= p->total_lines)
|
|
pr_cbs->last_page = True ;
|
|
/* that will have for effect in the shell to start a page, end it,
|
|
and then end the job */
|
|
return ;
|
|
}
|
|
|
|
/* if not the first page - see previous test, and not the last
|
|
scroll for next page */
|
|
if (!pr_cbs->last_page) {
|
|
XmTextScroll(p->ptext, p->lines_per_page);
|
|
p->printed_lines += p->lines_per_page ;
|
|
/* if last page, say it */
|
|
if (p->printed_lines >= p->total_lines) pr_cbs->last_page = True ;
|
|
} else {
|
|
/* job done. reset our counter, and keep print shell around
|
|
for next print job, just pop it down
|
|
reset the Print... button sensitive */
|
|
XtPopdown(pshell);
|
|
p->printed_lines = 0 ;
|
|
XtSetSensitive(p->pr_button, True);
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PrintCloseDisplayCB
|
|
*
|
|
* Description:
|
|
*
|
|
* Called when the print setup box is about to close the print
|
|
* display (in response to a new printer on a different display, or
|
|
* when the setup box is destroyed, or from DtPrintResetConnection).
|
|
*/
|
|
static void
|
|
PrintCloseDisplayCB(
|
|
Widget widget,
|
|
XtPointer client_data,
|
|
XtPointer call_data)
|
|
{
|
|
DtPrintSetupCallbackStruct *pbs = (DtPrintSetupCallbackStruct*)call_data;
|
|
AppPrintData *p = (AppPrintData*)client_data;
|
|
|
|
if (p->print_shell)
|
|
{
|
|
XtDestroyWidget(p->print_shell);
|
|
p->print_shell = (Widget)NULL ;
|
|
|
|
/* must remember that the children are gone, as well */
|
|
p->ptext = p->pform = NULL;
|
|
}
|
|
|
|
DtPrintFreeSetupData(p->print_data);
|
|
/* that nulls out p->print_data->print_display */
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: AppPrintData_new
|
|
*
|
|
* Description:
|
|
*
|
|
* App-specific print data holder allocate function.
|
|
*
|
|
*/
|
|
AppPrintData*
|
|
AppPrintData_new()
|
|
{
|
|
AppPrintData* p = (AppPrintData*)XtCalloc(1, sizeof(AppPrintData));
|
|
p->print_data = (DtPrintSetupData*)XtCalloc(1, sizeof(DtPrintSetupData));
|
|
|
|
return p;
|
|
}
|
|
|