ksh: fix up shipin for more modern systems WRT test and wc
[oweals/cde.git] / cde / examples / dtprint / Print.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: Print.c /main/16 1996/11/11 10:56:18 drk $ */
24
25 #include "PrintDemo.h"
26
27 /*
28  * static function declarations
29  */
30 static void PrintCB(Widget, XtPointer, XtPointer);
31 static void DoPrint(Widget widget, AppPrintData * p) ;
32 static void StartJobCB(Widget, XtPointer, XtPointer);
33 static void Print(AppPrintData *p);
34 static void PrintCloseDisplayCB(Widget, XtPointer, XtPointer);
35 static void PageSetupCB(Widget, XtPointer, XtPointer);
36 static void PdmNotifyCB(Widget, XtPointer, XtPointer);
37 static void PrintSetupCB(Widget, XtPointer, XtPointer);
38 static void FinishPrintToFile(Display*, XPContext, XPGetDocStatus, XPointer);
39 static void CreatePrintShell(Widget, AppPrintData*);
40
41 /*
42  * ------------------------------------------------------------------------
43  * Name: PdmNotifyCB
44  *
45  * Description:
46  *
47  *     Called when the PDM is up, or down.
48  *
49  */
50 static void 
51 PdmNotifyCB(Widget pr_shell, XtPointer client_data, XtPointer call_data)
52 {
53     XmPrintShellCallbackStruct* pr_cbs = 
54         (XmPrintShellCallbackStruct*) call_data;
55     AppPrintData * p = (AppPrintData *) client_data ;
56     
57     if (pr_cbs->reason == XmCR_PDM_NONE) {
58         /* put out a real message dialog */
59         printf("No PDM found in the environment\n");
60     } else 
61     if (pr_cbs->reason == XmCR_PDM_START_ERROR) {
62         /* put out a real message dialog */
63         printf("Cannot start the PDM\n");
64     } else 
65     if (pr_cbs->reason == XmCR_PDM_START_VXAUTH) {
66         /* put out a real message dialog */
67         printf("PDM is not authorized to connect to Video display\n");
68     } else 
69     if (pr_cbs->reason == XmCR_PDM_START_PXAUTH) {
70         /* put out a real message dialog */
71         printf("PDM is not authorized to connect to Print display\n");
72     }
73  
74 }
75
76 /*
77  * ------------------------------------------------------------------------
78  * Name: PrintMenuCB
79  *
80  * Description:
81  *
82  *     Called when the user selects the "Print..." menu item.
83  *
84  */
85 void 
86 PrintMenuCB(Widget pr_button, XtPointer client_data, XtPointer call_data)
87 {
88     AppPrintData* p = (AppPrintData*)client_data;
89     
90     /* only propose a new print job if one is not already running 
91        shouldn't happen since we put the button insensitive */
92     if (!p->printed_lines) {
93         CreatePrintSetup(pr_button, p);
94
95         XtManageChild(p->print_dialog); /* popup dialog each time */
96
97     } else {
98         /* real dialog here */
99         printf("Print job already running\n");
100     }
101 }
102
103 /*
104  * ------------------------------------------------------------------------
105  * Name: CreatePrintShell
106  *
107  * Description:
108  *
109  *     Called when the user selects the "Print" or the "Setup..." button
110  *       in the setupbox.
111  *
112  */
113
114 static void CreatePrintShell(Widget widget, AppPrintData* p)
115 {
116     /*
117      * create a print_shell if none available.  the print dialog callback
118      * always provides valid printer context and print display initialized: 
119      * XpInitContext called, attributes set.
120      */
121
122     if (!p->print_shell) {
123         p->print_shell = 
124             XmPrintSetup(widget, 
125                          XpGetScreenOfContext(p->print_data->print_display,
126                                               p->print_data->print_context),
127                          "Print", NULL, 0);
128
129         XtAddCallback(p->print_shell, XmNpageSetupCallback, 
130                       PageSetupCB, (XtPointer)p);
131         XtAddCallback(p->print_shell, XmNpdmNotificationCallback, 
132                       PdmNotifyCB, (XtPointer)p);
133     }
134 }
135
136
137  /*
138  * ------------------------------------------------------------------------
139  * Name: PrintSetupCB
140  *
141  * Description:
142  *
143  *     Called when the user presses the setup box "Setup..." button.
144  *
145  */
146 static void 
147 PrintSetupCB(Widget print_dialog, XtPointer client_data, XtPointer call_data)
148 {
149     AppPrintData *p = (AppPrintData*)client_data;
150     DtPrintSetupCallbackStruct *pbs = (DtPrintSetupCallbackStruct*)call_data;
151     int copies ;
152
153     XtVaGetValues(print_dialog, DtNcopies, &copies, NULL);
154     if (copies == 3) {
155         String attr ;
156         Display * pdpy = pbs->print_data->print_display ;
157         XPContext pcontext = pbs->print_data->print_context ;
158
159         attr = XpGetAttributes (pdpy, pcontext,  XPPageAttr);
160         if (attr) printf ("XPPageAttr:\n%s\n----------------------\n", attr);
161         attr = XpGetAttributes (pdpy, pcontext,  XPDocAttr);
162         if (attr) printf ("XPDocAttr:\n%s\n----------------------\n", attr);
163         attr = XpGetAttributes (pdpy, pcontext, XPJobAttr);
164         if (attr) printf ("XPJobAttr:\n%s\n----------------------\n", attr);
165         attr = XpGetAttributes (pdpy, pcontext,  XPPrinterAttr);
166         if (attr) printf ("XPPrinterAttr:\n%s\n----------------------\n", attr);
167         attr = XpGetAttributes (pdpy, pcontext,  XPServerAttr);
168         if (attr) printf ("XPServerAttr:\n%s\n----------------------\n", attr);
169         
170         return ;
171     }
172
173    /* copy the setup data into our space */
174     if (p->print_data->print_display != NULL)
175         DtPrintFreeSetupData(p->print_data);
176     DtPrintCopySetupData(p->print_data, pbs->print_data);
177  
178     /* create a print shell if not already done */
179     CreatePrintShell(print_dialog, p);
180
181     /* pop up the PDM */
182     if (XmPrintPopupPDM(p->print_shell, XtParent(print_dialog)) 
183         != XmPDM_NOTIFY_SUCCESS) {
184         /* post a message error dialog */
185         printf("XmPrintPopupPDM failed\n");
186     }
187
188     /* Free the setup data - use fresh data when Print button pressed. */
189     DtPrintFreeSetupData(p->print_data);
190 }
191
192 static void 
193 CancelCB(Widget print_dialog, XtPointer client_data, XtPointer call_data)
194 {
195     AppPrintData *p = (AppPrintData*)client_data;
196     DtPrintSetupCallbackStruct *pbs = (DtPrintSetupCallbackStruct*)call_data;
197
198     /* mostly to try it out */
199     XtDestroyWidget(print_dialog); p->print_dialog = NULL ; 
200 }
201
202 /*
203  * ------------------------------------------------------------------------
204  * Name: CreatePrintSetup
205  *
206  * Description:
207  *
208  *     Creates a DtPrintSetupBox dialog.
209  *
210  */
211 void
212 CreatePrintSetup(Widget parent, AppPrintData* p)
213 {
214     /*
215      * only create one PrintSetupBox 
216      */
217     if(!p->print_dialog)
218     {
219         Cardinal n = 0;
220         Arg args[5];
221
222         /* can be called when print_only is up, which means no need
223            for a dialog */
224         if(XtIsApplicationShell(parent))
225             p->print_dialog =
226                 DtCreatePrintSetupBox(parent, "PrintSetup", NULL, 0);
227         else
228         {
229             XmString title = XmStringCreateLocalized("Print");
230             XtSetArg(args[n], XmNdialogTitle, title); n++;
231             p->print_dialog =
232                 DtCreatePrintSetupDialog(parent, "PrintSetup", args, n);
233             XmStringFree(title);
234         }
235         /*
236          * allow the application to customize the print setup box
237          */
238         AppObject_customizePrintSetupBox(p->app_object, p->print_dialog);
239         /*
240          * add typically used callbacks
241          */
242         XtAddCallback(p->print_dialog, DtNclosePrintDisplayCallback,
243                       PrintCloseDisplayCB, p);
244         XtAddCallback(p->print_dialog, DtNsetupCallback,
245                       PrintSetupCB, p);
246          XtAddCallback(p->print_dialog, DtNprintCallback,
247                       PrintCB, p);
248         XtAddCallback(p->print_dialog, DtNcancelCallback,
249                       CancelCB, p);
250         /*
251          * other callbacks, for attributes management, are available 
252          */
253     }
254 }
255
256
257 /*
258  * ------------------------------------------------------------------------
259  * Name: PrintCB
260  *
261  * Description:
262  *
263  *     Called when the user presses the setup box "Print" button.
264  *
265  */
266 static void 
267 PrintCB(Widget print_dialog, XtPointer client_data, XtPointer call_data)
268 {
269     AppPrintData *p = (AppPrintData*)client_data;
270     DtPrintSetupCallbackStruct *pbs = (DtPrintSetupCallbackStruct*)call_data;
271
272     /*
273      * get the new printer data from the DtPrintSetupBox, and copy it
274      * into our AppPrint data
275      */
276     if (p->print_data->print_display != NULL)
277          DtPrintFreeSetupData(p->print_data);
278     DtPrintCopySetupData(p->print_data, pbs->print_data);
279  
280     DoPrint(print_dialog, p);
281 }
282
283 /*
284  * ------------------------------------------------------------------------
285  * Name: QuickPrintCB
286  *
287  * Description:
288  *
289  *     Called when the user hits "Print" quick button.
290  */
291 void 
292 QuickPrintCB(Widget pr_button, XtPointer client_data, XtPointer call_data)
293 {
294     AppPrintData *p = (AppPrintData*)client_data;
295
296     CreatePrintSetup(pr_button, p);
297
298     /*
299      * check if the DtPrintSetupBox ("Print...") has been called yet 
300      */
301     if(p->print_data->print_display == NULL)
302     {
303         /*
304          * first time thru print setup, so get default data 
305          */
306         if (DtPrintFillSetupData(p->print_dialog, p->print_data)
307             != DtPRINT_SUCCESS) {
308             /* post some message error dialog */
309             printf("DtPrintFillSetupData failed\n");
310             return ;
311         }
312     }
313  
314     DoPrint(pr_button, p) ;
315 }
316
317 /*
318  * ------------------------------------------------------------------------
319  * Name: FinishPrintToFile
320  *
321  * Description:
322  *
323  *     App-specific print data holder allocate function.
324  *
325  */
326 static void FinishPrintToFile(Display *display,
327                               XPContext context,
328                               XPGetDocStatus status,
329                               XPointer client_data)
330 {
331     if (status != XPGetDocFinished)
332         /* put out a real message dialog */
333         printf("Something went wrong with XmPrintToFile...\n");
334     else 
335         printf("XmPrintToFile completed OK\n");
336 }
337
338
339 /*
340  * ------------------------------------------------------------------------
341  * Name: DoPrint
342  *
343  * Description:
344  *     
345  *     Routine used from the "Print" button and from the OK button of the
346  *     "Print..." dialog.
347  *
348  */
349 static void 
350 DoPrint(Widget widget, AppPrintData * p) 
351 {
352     int save_data = XPSpool;
353
354     /* create print shell, if not done yet */
355     CreatePrintShell(widget, p);
356
357     if (p->print_data->destination == DtPRINT_TO_FILE)
358         save_data = XPGetData;
359
360     /* start job must precede XpGetDocumentData in XmPrintToFile */
361     XpStartJob(XtDisplay(p->print_shell), save_data);  
362
363     /* setup print to file */
364     if (p->print_data->destination == DtPRINT_TO_FILE)
365     {
366         if (!XmPrintToFile(XtDisplay(p->print_shell), 
367                            p->print_data->dest_info, FinishPrintToFile, NULL))
368         {
369             /* Add real error message here. */
370             printf("XmPrintToFile: Unable to print to file %s\n",
371                    p->print_data->dest_info);
372
373             XpCancelJob(XtDisplay(p->print_shell), False);
374
375             /* we can go back to the event loop as if we had never
376                printed */
377             return;
378         }
379     }
380
381     XtSetSensitive(p->pr_button, False);
382 }
383
384 /*
385  * ------------------------------------------------------------------------
386  * Name: PageSetupCB
387  *
388  * Description:
389  *
390  *     Called when the print shell receives the XP events.
391  *
392  */
393 static void 
394 PageSetupCB(Widget widget, XtPointer client_data, XtPointer call_data)
395 {
396     Widget pshell = widget ;
397     XmPrintShellCallbackStruct* pr_cbs = 
398         (XmPrintShellCallbackStruct*) call_data;
399     AppPrintData * p = (AppPrintData *) client_data ;
400
401     /* could have real indicator of progress here */
402     printf("Printed Lines %d\n", p->printed_lines);
403
404     /* the first time around, create a print text widget and get
405        line info - equivalent for testing for first page*/
406     if (!pr_cbs->last_page && !p->printed_lines) {
407
408         /* create the widgets once */
409         if (!p->pform) {
410             /* create a form widget with some fixed margins */
411             p->pform = XtVaCreateManagedWidget("pform", xmFormWidgetClass, 
412                                                pshell, NULL);
413             /* create a text widget */
414             p->ptext = XtVaCreateManagedWidget("ptext", xmTextWidgetClass, 
415                                                p->pform, NULL);
416         }
417         /* transfer value from file buffer to print text widget */
418         XmTextSetString(p->ptext, p->app_object->file_buffer );
419
420         /* get lines per page and total lines */
421         XtVaGetValues(p->ptext, XmNrows, &(p->lines_per_page), 
422                       XmNtotalLines, &(p->total_lines), NULL);
423
424         p->printed_lines += p->lines_per_page ;
425
426         /* If I'm already done: fit in one page, set last_page up */
427         if (p->printed_lines >= p->total_lines) 
428             pr_cbs->last_page = True ;
429         /* that will have for effect in the shell to start a page, end it, 
430            and then end the job */
431         return ;
432     }
433
434     /* if not the first page - see previous test, and not the last
435        scroll for next page */
436     if (!pr_cbs->last_page) {
437         XmTextScroll(p->ptext, p->lines_per_page);
438         p->printed_lines += p->lines_per_page ;
439         /* if last page, say it */
440         if (p->printed_lines >= p->total_lines) pr_cbs->last_page = True ;
441     } else {
442         /* job done. reset our counter, and keep print shell around
443            for next print job, just pop it down 
444            reset the Print... button sensitive */
445         XtPopdown(pshell);
446         p->printed_lines = 0 ;  
447         XtSetSensitive(p->pr_button, True);
448
449     }
450
451     
452 }
453
454 /*
455  * ------------------------------------------------------------------------
456  * Name: PrintCloseDisplayCB
457  *
458  * Description:
459  *
460  *     Called when the print setup box is about to close the print
461  *     display (in response to a new printer on a different display, or
462  *     when the setup box is destroyed, or from DtPrintResetConnection).
463  */
464 static void
465 PrintCloseDisplayCB(
466                     Widget widget,
467                     XtPointer client_data,
468                     XtPointer call_data)
469 {
470     DtPrintSetupCallbackStruct *pbs = (DtPrintSetupCallbackStruct*)call_data;
471     AppPrintData *p = (AppPrintData*)client_data;
472
473     if (p->print_shell)
474     {
475         XtDestroyWidget(p->print_shell);
476         p->print_shell = (Widget)NULL ;
477         
478         /* must remember that the children are gone, as well */
479         p->ptext = p->pform = NULL;
480     }
481
482     DtPrintFreeSetupData(p->print_data); 
483     /* that nulls out p->print_data->print_display */
484 }
485
486 /*
487  * ------------------------------------------------------------------------
488  * Name: AppPrintData_new
489  *
490  * Description:
491  *
492  *     App-specific print data holder allocate function.
493  *
494  */
495 AppPrintData*
496 AppPrintData_new()
497 {
498     AppPrintData* p = (AppPrintData*)XtCalloc(1, sizeof(AppPrintData));
499     p->print_data = (DtPrintSetupData*)XtCalloc(1, sizeof(DtPrintSetupData));
500
501     return p;
502 }
503