cdesktopenv/cde/examples/dtprint/Print.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;
}