Print.c 14 KB

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