1 static const char CVSID
[] = "$Id: printUtils.c,v 1.25 2004/08/01 10:06:12 yooden Exp $";
2 /*******************************************************************************
4 * printUtils.c -- Nirvana library Printer Menu & Printing Routines *
6 * Copyright (C) 1999 Mark Edel *
8 * This is free software; you can redistribute it and/or modify it under the *
9 * terms of the GNU General Public License as published by the Free Software *
10 * Foundation; either version 2 of the License, or (at your option) any later *
11 * version. In addition, you may distribute version of this program linked to *
12 * Motif or Open Motif. See README for details. *
14 * This software is distributed in the hope that it will be useful, but WITHOUT *
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
19 * You should have received a copy of the GNU General Public License along with *
20 * software; if not, write to the Free Software Foundation, Inc., 59 Temple *
21 * Place, Suite 330, Boston, MA 02111-1307 USA *
23 * Nirvana Text Editor *
27 * Written by Arnulfo Zepeda-Navratil *
28 * Centro de Investigacion y Estudio Avanzados ( CINVESTAV ) *
29 * Dept. Fisica - Mexico *
30 * BITNET: ZEPEDA@CINVESMX *
32 * Modified by Donna Reid and Joy Kyriakopulos 4/8/93 - VMS port *
34 *******************************************************************************/
37 #include "../config.h"
40 #include "printUtils.h"
50 #include <sys/types.h>
54 #include <lib$routines.h>
64 #endif /* USE_DIRENT */
66 #include <sys/param.h>
71 #include <X11/StringDefs.h>
72 #include <X11/Intrinsic.h>
73 #include <X11/Shell.h>
76 #include <Xm/LabelG.h>
78 #include <Xm/SeparatoG.h>
85 /* Separator between directory references in PATH environmental variable */
86 #ifdef __EMX__ /* For OS/2 */
92 /* Number of extra pixels down to place a label even with a text widget */
93 #define LABEL_TEXT_DIFF 6
95 /* Maximum text string lengths */
96 #define MAX_OPT_STR 20
97 #define MAX_QUEUE_STR 60
98 #define MAX_INT_STR 13
99 #define MAX_HOST_STR 100
100 #define MAX_PCMD_STR 100
101 #define MAX_NAME_STR 100
102 #define MAX_CMD_STR 256
103 #define VMS_MAX_JOB_NAME_STR 39
105 #define N_PRINT_PREFS 7 /* must agree with number of preferences below */
106 struct printPrefDescrip
{
107 PrefDescripRec printCommand
;
108 PrefDescripRec copiesOption
;
109 PrefDescripRec queueOption
;
110 PrefDescripRec nameOption
;
111 PrefDescripRec hostOption
;
112 PrefDescripRec defaultQueue
;
113 PrefDescripRec defaultHost
;
116 /* Function Prototypes */
117 static Widget
createForm(Widget parent
);
118 static void allowOnlyNumInput(Widget widget
, caddr_t client_data
,
119 XmTextVerifyCallbackStruct
*call_data
);
120 static void noSpaceOrPunct(Widget widget
, caddr_t client_data
,
121 XmTextVerifyCallbackStruct
*call_data
);
122 static void updatePrintCmd(Widget w
, caddr_t client_data
, caddr_t call_data
);
123 static void printCmdModified(Widget w
, caddr_t client_data
, caddr_t call_data
);
124 static void printButtonCB(Widget widget
, caddr_t client_data
, caddr_t call_data
);
125 static void cancelButtonCB(Widget widget
, caddr_t client_data
, caddr_t call_data
);
126 static void setQueueLabelText(void);
127 static int fileInDir(const char *filename
, const char *dirpath
, unsigned short mode_flags
);
128 static int fileInPath(const char *filename
, unsigned short mode_flags
);
129 static int flprPresent(void);
130 #ifdef USE_LPR_PRINT_CMD
131 static void getLprQueueDefault(char *defqueue
);
133 #ifndef USE_LPR_PRINT_CMD
134 static void getLpQueueDefault(char *defqueue
);
136 static void setHostLabelText(void);
138 static void getVmsQueueDefault(char *defqueue
);
140 static void getFlprHostDefault(char *defhost
);
141 static void getFlprQueueDefault(char *defqueue
);
144 /* Module Global Variables */
145 static Boolean DoneWithDialog
;
146 static Boolean PreferencesLoaded
= False
;
148 static Widget Label2
;
149 static Widget Label3
;
154 static const char *PrintFileName
;
155 static const char *PrintJobName
;
156 static char PrintCommand
[MAX_PCMD_STR
]; /* print command string */
157 static char CopiesOption
[MAX_OPT_STR
]; /* # of copies argument string */
158 static char QueueOption
[MAX_OPT_STR
]; /* queue name argument string */
159 static char NameOption
[MAX_OPT_STR
]; /* print job name argument string */
160 static char HostOption
[MAX_OPT_STR
]; /* host name argument string */
161 static char DefaultQueue
[MAX_QUEUE_STR
];/* default print queue */
162 static char DefaultHost
[MAX_HOST_STR
]; /* default host name */
163 static char Copies
[MAX_INT_STR
] = ""; /* # of copies last entered by user */
164 static char Queue
[MAX_QUEUE_STR
] = ""; /* queue name last entered by user */
165 static char Host
[MAX_HOST_STR
] = ""; /* host name last entered by user */
166 static char CmdText
[MAX_CMD_STR
] = ""; /* print command last entered by user */
167 static int CmdFieldModified
= False
; /* user last changed the print command
168 field, so don't trust the rest */
170 static int DeleteFile
; /* append /DELETE to VMS print command*/
173 static struct printPrefDescrip PrintPrefDescrip
= {
174 {"printCommand", "PrintCommand", PREF_STRING
, NULL
,
175 PrintCommand
, (void *)MAX_PCMD_STR
, False
},
176 {"printCopiesOption", "PrintCopiesOption", PREF_STRING
, NULL
,
177 CopiesOption
, (void *)MAX_OPT_STR
, False
},
178 {"printQueueOption", "PrintQueueOption", PREF_STRING
, NULL
,
179 QueueOption
, (void *)MAX_OPT_STR
, False
},
180 {"printNameOption", "PrintNameOption", PREF_STRING
, NULL
,
181 NameOption
, (void *)MAX_OPT_STR
, False
},
182 {"printHostOption", "PrintHostOption", PREF_STRING
, NULL
,
183 HostOption
, (void *)MAX_OPT_STR
, False
},
184 {"printDefaultQueue", "PrintDefaultQueue", PREF_STRING
, NULL
,
185 DefaultQueue
, (void *)MAX_QUEUE_STR
, False
},
186 {"printDefaultHost", "PrintDefaultHost", PREF_STRING
, NULL
,
187 DefaultHost
, (void *)MAX_HOST_STR
, False
},
191 ** PrintFile(Widget parent, char *printFile, char *jobName);
193 ** function to put up an application-modal style Print Panel dialog
196 ** parent Parent widget for displaying dialog
197 ** printFile File to print (assumed to be a temporary file
198 ** and not revealed to the user)
199 ** jobName Title for the print banner page
202 void PrintFile(Widget parent
, const char *printFile
, const char *jobName
, int delete)
204 void PrintFile(Widget parent
, const char *printFile
, const char *jobName
)
207 /* In case the program hasn't called LoadPrintPreferences, set up the
208 default values for the print preferences */
209 if (!PreferencesLoaded
)
210 LoadPrintPreferences(NULL
, "", "", True
);
212 /* Make the PrintFile information available to the callback routines */
213 PrintFileName
= printFile
;
214 PrintJobName
= jobName
;
219 /* Create and display the print dialog */
220 DoneWithDialog
= False
;
221 Form
= createForm(parent
);
222 ManageDialogCenteredOnPointer(Form
);
224 /* Process events until the user is done with the print dialog */
225 while (!DoneWithDialog
)
226 XtAppProcessEvent(XtWidgetToApplicationContext(Form
), XtIMAll
);
228 /* Destroy the dialog. Print dialogs are not preserved across calls
229 to PrintFile so that it may be called with different parents and
230 to generally simplify the call (this, of course, makes it slower) */
231 XtDestroyWidget(Form
);
235 ** LoadPrintPreferences
237 ** Read an X database to obtain print dialog preferences.
239 ** prefDB X database potentially containing print preferences
240 ** appName Application name which can be used to qualify
241 ** resource names for database lookup.
242 ** appClass Application class which can be used to qualify
243 ** resource names for database lookup.
244 ** lookForFlpr Check if the flpr print command is installed
245 ** and use that for the default if it's found.
246 ** (flpr is a Fermilab utility for printing on
247 ** arbitrary systems that support the lpr protocol)
249 void LoadPrintPreferences(XrmDatabase prefDB
, const char *appName
,
250 const char *appClass
, int lookForFlpr
)
252 static char defaultQueue
[MAX_QUEUE_STR
], defaultHost
[MAX_HOST_STR
];
255 /* VMS built-in print command */
256 getVmsQueueDefault(defaultQueue
);
257 PrintPrefDescrip
.printCommand
.defaultString
= "print";
258 PrintPrefDescrip
.copiesOption
.defaultString
= "/copies=";
259 PrintPrefDescrip
.queueOption
.defaultString
= "/queue=";
260 PrintPrefDescrip
.nameOption
.defaultString
= "/name=";
261 PrintPrefDescrip
.hostOption
.defaultString
= "";
262 PrintPrefDescrip
.defaultQueue
.defaultString
= defaultQueue
;
263 PrintPrefDescrip
.defaultHost
.defaultString
= "";
266 /* check if flpr is installed, and otherwise choose appropriate
267 printer per system type */
268 if (lookForFlpr
&& flprPresent()) {
269 getFlprQueueDefault(defaultQueue
);
270 getFlprHostDefault(defaultHost
);
271 PrintPrefDescrip
.printCommand
.defaultString
= "flpr";
272 PrintPrefDescrip
.copiesOption
.defaultString
= "";
273 PrintPrefDescrip
.queueOption
.defaultString
= "-q";
274 PrintPrefDescrip
.nameOption
.defaultString
= "-j ";
275 PrintPrefDescrip
.hostOption
.defaultString
= "-h";
276 PrintPrefDescrip
.defaultQueue
.defaultString
= defaultQueue
;
277 PrintPrefDescrip
.defaultHost
.defaultString
= defaultHost
;
279 #ifdef USE_LPR_PRINT_CMD
280 getLprQueueDefault(defaultQueue
);
281 PrintPrefDescrip
.printCommand
.defaultString
= "lpr";
282 PrintPrefDescrip
.copiesOption
.defaultString
= "-# ";
283 PrintPrefDescrip
.queueOption
.defaultString
= "-P ";
284 PrintPrefDescrip
.nameOption
.defaultString
= "-J ";
285 PrintPrefDescrip
.hostOption
.defaultString
= "";
286 PrintPrefDescrip
.defaultQueue
.defaultString
= defaultQueue
;
287 PrintPrefDescrip
.defaultHost
.defaultString
= "";
289 getLpQueueDefault(defaultQueue
);
290 PrintPrefDescrip
.printCommand
.defaultString
= "lp"; /* was lp -c */
291 PrintPrefDescrip
.copiesOption
.defaultString
= "-n";
292 PrintPrefDescrip
.queueOption
.defaultString
= "-d";
293 PrintPrefDescrip
.nameOption
.defaultString
= "-t";
294 PrintPrefDescrip
.hostOption
.defaultString
= "";
295 PrintPrefDescrip
.defaultQueue
.defaultString
= defaultQueue
;
296 PrintPrefDescrip
.defaultHost
.defaultString
= "";
301 /* Read in the preferences from the X database using the mechanism from
302 prefFile.c (this allows LoadPrintPreferences to work before any
303 widgets are created, which is more convenient than XtGetApplication-
304 Resources for applications which have no main window) */
305 RestorePreferences(NULL
, prefDB
, appName
, appClass
,
306 (PrefDescripRec
*)&PrintPrefDescrip
, N_PRINT_PREFS
);
308 PreferencesLoaded
= True
;
311 static Widget
createForm(Widget parent
)
313 Widget form
, printOk
, printCancel
, label1
, separator
;
314 Widget topWidget
= NULL
;
318 Widget bwidgetarray
[30];
321 /************************ FORM ***************************/
323 XtSetArg(args
[argcnt
], XmNdialogStyle
, XmDIALOG_FULL_APPLICATION_MODAL
);
325 XtSetArg(args
[argcnt
], XmNdialogTitle
, (st0
=XmStringCreateLtoR(
326 "Print", XmSTRING_DEFAULT_CHARSET
))); argcnt
++;
327 XtSetArg(args
[argcnt
], XmNautoUnmanage
, False
); argcnt
++;
328 form
= CreateFormDialog(parent
, "printForm", args
, argcnt
);
329 XtVaSetValues(form
, XmNshadowThickness
, 0, NULL
);
333 /*********************** LABEL 1 and TEXT BOX 1 *********************/
334 if (CopiesOption
[0] != '\0') {
336 XtSetArg(args
[argcnt
], XmNlabelString
, (st0
=XmStringCreateLtoR(
337 "Number of copies (1)", XmSTRING_DEFAULT_CHARSET
))); argcnt
++;
338 XtSetArg(args
[argcnt
], XmNmnemonic
, 'N'); argcnt
++;
339 XtSetArg(args
[argcnt
], XmNtopAttachment
, XmATTACH_FORM
); argcnt
++;
340 XtSetArg(args
[argcnt
], XmNtopOffset
, LABEL_TEXT_DIFF
+5); argcnt
++;
341 XtSetArg(args
[argcnt
], XmNleftAttachment
, XmATTACH_FORM
); argcnt
++;
342 XtSetArg(args
[argcnt
], XmNleftOffset
, 8); argcnt
++;
343 label1
= XmCreateLabelGadget(form
, "label1", args
, argcnt
);
345 bwidgetarray
[bwidgetcnt
] = label1
; bwidgetcnt
++;
348 XtSetArg(args
[argcnt
], XmNshadowThickness
, (short)2); argcnt
++;
349 XtSetArg(args
[argcnt
], XmNcolumns
, 3); argcnt
++;
350 XtSetArg(args
[argcnt
], XmNrows
, 1); argcnt
++;
351 XtSetArg(args
[argcnt
], XmNvalue
, Copies
); argcnt
++;
352 XtSetArg(args
[argcnt
], XmNmaxLength
, 3); argcnt
++;
353 XtSetArg(args
[argcnt
], XmNtopAttachment
, XmATTACH_FORM
); argcnt
++;
354 XtSetArg(args
[argcnt
], XmNtopOffset
, 5); argcnt
++;
355 XtSetArg(args
[argcnt
], XmNleftAttachment
, XmATTACH_WIDGET
); argcnt
++;
356 XtSetArg(args
[argcnt
], XmNleftWidget
, label1
); argcnt
++;
357 Text1
= XmCreateText(form
, "text1", args
, argcnt
);
358 bwidgetarray
[bwidgetcnt
] = Text1
; bwidgetcnt
++;
359 XtAddCallback(Text1
, XmNmodifyVerifyCallback
,
360 (XtCallbackProc
)allowOnlyNumInput
, NULL
);
361 XtAddCallback(Text1
, XmNvalueChangedCallback
,
362 (XtCallbackProc
)updatePrintCmd
, NULL
);
363 RemapDeleteKey(Text1
);
365 XtVaSetValues(label1
, XmNuserData
, Text1
, NULL
); /* mnemonic procesing */
368 /************************ LABEL 2 and TEXT 2 ************************/
369 if (QueueOption
[0] != '\0') {
371 XtSetArg(args
[argcnt
], XmNlabelString
, (st0
=XmStringCreateLtoR(
372 " ", XmSTRING_DEFAULT_CHARSET
))); argcnt
++;
373 XtSetArg(args
[argcnt
], XmNmnemonic
, 'Q'); argcnt
++;
374 XtSetArg(args
[argcnt
], XmNrecomputeSize
, True
); argcnt
++;
375 XtSetArg(args
[argcnt
], XmNtopAttachment
,
376 topWidget
==NULL
?XmATTACH_FORM
:XmATTACH_WIDGET
); argcnt
++;
377 XtSetArg(args
[argcnt
], XmNtopWidget
, topWidget
); argcnt
++;
378 XtSetArg(args
[argcnt
], XmNleftAttachment
, XmATTACH_FORM
); argcnt
++;
379 XtSetArg(args
[argcnt
], XmNtopOffset
, LABEL_TEXT_DIFF
+4); argcnt
++;
380 XtSetArg(args
[argcnt
], XmNleftOffset
, 8); argcnt
++;
381 Label2
= XmCreateLabelGadget(form
, "label2", args
, argcnt
);
383 bwidgetarray
[bwidgetcnt
] = Label2
; bwidgetcnt
++;
387 XtSetArg(args
[argcnt
], XmNshadowThickness
, (short)2); argcnt
++;
388 XtSetArg(args
[argcnt
], XmNcolumns
, (short)17); argcnt
++;
389 XtSetArg(args
[argcnt
], XmNmaxLength
, MAX_QUEUE_STR
); argcnt
++;
390 XtSetArg(args
[argcnt
], XmNvalue
, Queue
); argcnt
++;
391 XtSetArg(args
[argcnt
], XmNrightAttachment
, XmATTACH_FORM
); argcnt
++;
392 XtSetArg(args
[argcnt
], XmNleftAttachment
, XmATTACH_WIDGET
); argcnt
++;
393 XtSetArg(args
[argcnt
], XmNleftWidget
, Label2
); argcnt
++;
394 XtSetArg(args
[argcnt
], XmNtopAttachment
,
395 topWidget
==NULL
?XmATTACH_FORM
:XmATTACH_WIDGET
); argcnt
++;
396 XtSetArg(args
[argcnt
], XmNtopWidget
, topWidget
); argcnt
++;
397 XtSetArg(args
[argcnt
], XmNrightOffset
, 8); argcnt
++;
398 XtSetArg(args
[argcnt
], XmNtopOffset
, 4); argcnt
++;
399 Text2
= XmCreateText(form
, "text2", args
, argcnt
);
400 XtAddCallback(Text2
, XmNmodifyVerifyCallback
,
401 (XtCallbackProc
)noSpaceOrPunct
, NULL
);
402 XtAddCallback(Text2
, XmNvalueChangedCallback
,
403 (XtCallbackProc
)updatePrintCmd
, NULL
);
404 bwidgetarray
[bwidgetcnt
] = Text2
; bwidgetcnt
++;
405 RemapDeleteKey(Text2
);
406 XtVaSetValues(Label2
, XmNuserData
, Text2
, NULL
); /* mnemonic procesing */
410 /****************** LABEL 3 and TEXT 3 *********************/
411 if (HostOption
[0] != '\0') {
413 XtSetArg(args
[argcnt
], XmNlabelString
, (st0
=XmStringCreateLtoR(
414 " ", XmSTRING_DEFAULT_CHARSET
))); argcnt
++;
415 XtSetArg(args
[argcnt
], XmNmnemonic
, 'H'); argcnt
++;
416 XtSetArg(args
[argcnt
], XmNrecomputeSize
, True
); argcnt
++;
417 XtSetArg(args
[argcnt
], XmNvalue
, ""); argcnt
++;
418 XtSetArg(args
[argcnt
], XmNtopAttachment
,
419 topWidget
==NULL
?XmATTACH_FORM
:XmATTACH_WIDGET
); argcnt
++;
420 XtSetArg(args
[argcnt
], XmNtopWidget
, topWidget
); argcnt
++;
421 XtSetArg(args
[argcnt
], XmNleftAttachment
, XmATTACH_FORM
); argcnt
++;
422 XtSetArg(args
[argcnt
], XmNleftOffset
, 8); argcnt
++;
423 XtSetArg(args
[argcnt
], XmNtopOffset
, LABEL_TEXT_DIFF
+4); argcnt
++;
424 Label3
= XmCreateLabelGadget(form
, "label3", args
, argcnt
);
426 bwidgetarray
[bwidgetcnt
] = Label3
; bwidgetcnt
++;
430 XtSetArg(args
[argcnt
], XmNcolumns
, 17); argcnt
++;
431 XtSetArg(args
[argcnt
], XmNrows
, 1); argcnt
++;
432 XtSetArg(args
[argcnt
], XmNvalue
, Host
); argcnt
++;
433 XtSetArg(args
[argcnt
], XmNmaxLength
, MAX_HOST_STR
); argcnt
++;
434 XtSetArg(args
[argcnt
], XmNrightAttachment
, XmATTACH_FORM
); argcnt
++;
435 XtSetArg(args
[argcnt
], XmNleftAttachment
, XmATTACH_WIDGET
); argcnt
++;
436 XtSetArg(args
[argcnt
], XmNleftWidget
, Label3
); argcnt
++;
437 XtSetArg(args
[argcnt
], XmNtopAttachment
,
438 topWidget
==NULL
?XmATTACH_FORM
:XmATTACH_WIDGET
); argcnt
++;
439 XtSetArg(args
[argcnt
], XmNtopWidget
, topWidget
); argcnt
++;
440 XtSetArg(args
[argcnt
], XmNrightOffset
, 8); argcnt
++;
441 XtSetArg(args
[argcnt
], XmNtopOffset
, 4); argcnt
++;
442 Text3
= XmCreateText(form
, "Text3", args
, argcnt
);
443 XtAddCallback(Text3
, XmNmodifyVerifyCallback
,
444 (XtCallbackProc
)noSpaceOrPunct
, NULL
);
445 XtAddCallback(Text3
, XmNvalueChangedCallback
,
446 (XtCallbackProc
)updatePrintCmd
, NULL
);
447 bwidgetarray
[bwidgetcnt
] = Text3
; bwidgetcnt
++;
448 RemapDeleteKey(Text3
);
449 XtVaSetValues(Label3
, XmNuserData
, Text3
, NULL
); /* mnemonic procesing */
453 /************************** TEXT 4 ***************************/
455 XtSetArg(args
[argcnt
], XmNvalue
, CmdText
); argcnt
++;
456 XtSetArg(args
[argcnt
], XmNcolumns
, 50); argcnt
++;
457 XtSetArg(args
[argcnt
], XmNleftAttachment
, XmATTACH_FORM
); argcnt
++;
458 XtSetArg(args
[argcnt
], XmNleftOffset
, 8); argcnt
++;
459 XtSetArg(args
[argcnt
], XmNtopAttachment
, XmATTACH_WIDGET
); argcnt
++;
460 XtSetArg(args
[argcnt
], XmNtopOffset
, 8); argcnt
++;
461 XtSetArg(args
[argcnt
], XmNtopWidget
, topWidget
); argcnt
++;
462 XtSetArg(args
[argcnt
], XmNrightAttachment
, XmATTACH_FORM
); argcnt
++;
463 XtSetArg(args
[argcnt
], XmNrightOffset
, 8); argcnt
++;
464 Text4
= XmCreateText(form
, "Text4", args
, argcnt
);
465 XtAddCallback(Text4
, XmNmodifyVerifyCallback
,
466 (XtCallbackProc
)printCmdModified
, NULL
);
467 bwidgetarray
[bwidgetcnt
] = Text4
; bwidgetcnt
++;
468 RemapDeleteKey(Text4
);
470 if (!CmdFieldModified
)
471 updatePrintCmd(NULL
, NULL
, NULL
);
473 /*********************** SEPARATOR **************************/
475 XtSetArg(args
[argcnt
], XmNleftAttachment
, XmATTACH_FORM
); argcnt
++;
476 XtSetArg(args
[argcnt
], XmNtopAttachment
, XmATTACH_WIDGET
); argcnt
++;
477 XtSetArg(args
[argcnt
], XmNrightAttachment
, XmATTACH_FORM
); argcnt
++;
478 XtSetArg(args
[argcnt
], XmNtopOffset
, 8); argcnt
++;
479 XtSetArg(args
[argcnt
], XmNtopWidget
, topWidget
); argcnt
++;
480 separator
= XmCreateSeparatorGadget(form
, "separator", args
, argcnt
);
481 bwidgetarray
[bwidgetcnt
] = separator
; bwidgetcnt
++;
482 topWidget
= separator
;
484 /********************** CANCEL BUTTON *************************/
486 XtSetArg(args
[argcnt
], XmNlabelString
, (st0
=XmStringCreateLtoR(
487 "Cancel", XmSTRING_DEFAULT_CHARSET
))); argcnt
++;
488 XtSetArg(args
[argcnt
], XmNleftAttachment
, XmATTACH_POSITION
); argcnt
++;
489 XtSetArg(args
[argcnt
], XmNleftPosition
, 60); argcnt
++;
490 XtSetArg(args
[argcnt
], XmNtopAttachment
, XmATTACH_WIDGET
); argcnt
++;
491 XtSetArg(args
[argcnt
], XmNtopWidget
, topWidget
); argcnt
++;
492 XtSetArg(args
[argcnt
], XmNtopOffset
, 7); argcnt
++;
493 printCancel
= XmCreatePushButton(form
, "printCancel", args
, argcnt
);
495 bwidgetarray
[bwidgetcnt
] = printCancel
; bwidgetcnt
++;
496 XtAddCallback (printCancel
, XmNactivateCallback
,
497 (XtCallbackProc
)cancelButtonCB
, NULL
);
499 /*********************** PRINT BUTTON **************************/
501 XtSetArg(args
[argcnt
], XmNlabelString
, (st0
=XmStringCreateLtoR(
502 "Print", XmSTRING_DEFAULT_CHARSET
))); argcnt
++;
503 XtSetArg(args
[argcnt
], XmNshowAsDefault
, True
); argcnt
++;
504 XtSetArg(args
[argcnt
], XmNrightAttachment
, XmATTACH_POSITION
); argcnt
++;
505 XtSetArg(args
[argcnt
], XmNrightPosition
, 40); argcnt
++;
506 XtSetArg(args
[argcnt
], XmNtopAttachment
, XmATTACH_WIDGET
); argcnt
++;
507 XtSetArg(args
[argcnt
], XmNtopWidget
, topWidget
); argcnt
++;
508 XtSetArg(args
[argcnt
], XmNtopOffset
, 7); argcnt
++;
509 printOk
= XmCreatePushButton(form
, "printOk", args
, argcnt
);
511 bwidgetarray
[bwidgetcnt
] = printOk
; bwidgetcnt
++;
512 XtAddCallback (printOk
, XmNactivateCallback
,
513 (XtCallbackProc
)printButtonCB
, NULL
);
516 XtSetArg(args
[argcnt
], XmNcancelButton
, printCancel
); argcnt
++;
517 XtSetArg(args
[argcnt
], XmNdefaultButton
, printOk
); argcnt
++;
518 XtSetValues(form
, args
, argcnt
);
520 XtManageChildren(bwidgetarray
, bwidgetcnt
);
521 AddDialogMnemonicHandler(form
, FALSE
);
525 static void setQueueLabelText(void)
530 char tmp_buf
[MAX_QUEUE_STR
+8];
532 if (DefaultQueue
[0] != '\0')
533 sprintf(tmp_buf
, "Queue (%s)", DefaultQueue
);
535 sprintf(tmp_buf
, "Queue");
537 XtSetArg(args
[argcnt
], XmNlabelString
, (st0
=XmStringCreateLtoR(
538 tmp_buf
, XmSTRING_DEFAULT_CHARSET
))); argcnt
++;
539 XtSetValues (Label2
, args
, argcnt
);
543 static void setHostLabelText(void)
548 char tmp_buf
[MAX_HOST_STR
+7];
550 if (strcmp(DefaultHost
, ""))
551 sprintf(tmp_buf
, "Host (%s)", DefaultHost
);
553 sprintf(tmp_buf
, "Host");
555 XtSetArg(args
[argcnt
], XmNlabelString
, (st0
=XmStringCreateLtoR(
556 tmp_buf
, XmSTRING_DEFAULT_CHARSET
))); argcnt
++;
558 XtSetValues (Label3
, args
, argcnt
);
562 static void allowOnlyNumInput(Widget widget
, caddr_t client_data
,
563 XmTextVerifyCallbackStruct
*call_data
)
565 int i
, textInserted
, nInserted
;
567 nInserted
= call_data
->text
->length
;
568 textInserted
= (nInserted
> 0);
569 if ((call_data
->reason
== XmCR_MODIFYING_TEXT_VALUE
) && textInserted
) {
570 for (i
=0; i
<nInserted
; i
++) {
571 if (!isdigit((unsigned char)call_data
->text
->ptr
[i
])) {
572 call_data
->doit
= False
;
577 call_data
->doit
= True
;
581 ** Prohibit a relatively random sampling of characters that will cause
582 ** problems on command lines
584 static void noSpaceOrPunct(Widget widget
, caddr_t client_data
,
585 XmTextVerifyCallbackStruct
*call_data
)
587 int i
, j
, textInserted
, nInserted
;
589 static char prohibited
[] = " \t,;|<>()[]{}!@?";
591 static char prohibited
[] = " \t,;|@+";
594 nInserted
= call_data
->text
->length
;
595 textInserted
= (nInserted
> 0);
596 if ((call_data
->reason
== XmCR_MODIFYING_TEXT_VALUE
) && textInserted
) {
597 for (i
=0; i
<nInserted
; i
++) {
598 for (j
=0; j
<(int)XtNumber(prohibited
); j
++) {
599 if (call_data
->text
->ptr
[i
] == prohibited
[j
]) {
600 call_data
->doit
= False
;
606 call_data
->doit
= True
;
609 static void updatePrintCmd(Widget w
, caddr_t client_data
, caddr_t call_data
)
611 char command
[MAX_CMD_STR
], copiesArg
[MAX_OPT_STR
+MAX_INT_STR
];
612 char jobArg
[MAX_NAME_STR
], hostArg
[MAX_OPT_STR
+MAX_HOST_STR
];
613 char queueArg
[MAX_OPT_STR
+MAX_QUEUE_STR
];
617 char printJobName
[VMS_MAX_JOB_NAME_STR
+1];
620 /* read each text field in the dialog and generate the corresponding
622 if (CopiesOption
[0] == '\0') {
625 str
= XmTextGetString(Text1
);
626 if (str
[0] == '\0') {
629 if (sscanf(str
, "%d", &nCopies
) != 1) {
632 sprintf(copiesArg
, " %s%s", CopiesOption
, str
);
637 if (QueueOption
[0] == '\0') {
640 str
= XmTextGetString(Text2
);
644 sprintf(queueArg
, " %s%s", QueueOption
, str
);
647 if (HostOption
[0] == '\0') {
650 str
= XmTextGetString(Text3
);
654 sprintf(hostArg
, " %s%s", HostOption
, str
);
657 if (NameOption
[0] == '\0')
661 /* truncate job name on VMS systems or it will cause problems */
662 strncpy(printJobName
,PrintJobName
,VMS_MAX_JOB_NAME_STR
);
663 printJobName
[VMS_MAX_JOB_NAME_STR
] = '\0';
664 sprintf(jobArg
, " %s\"%s\"", NameOption
, printJobName
);
666 sprintf(jobArg
, " %s\"%s\"", NameOption
, PrintJobName
);
670 /* Compose the command from the options determined above */
671 sprintf(command
, "%s%s%s%s%s", PrintCommand
, copiesArg
,
672 queueArg
, hostArg
, jobArg
);
674 /* display it in the command text area */
675 XmTextSetString(Text4
, command
);
677 /* Indicate that the command field was synthesized from the other fields,
678 so future dialog invocations can safely re-generate the command without
679 overwriting commands specifically entered by the user */
680 CmdFieldModified
= False
;
683 static void printCmdModified(Widget w
, caddr_t client_data
, caddr_t call_data
)
685 /* Indicate that the user has specifically modified the print command
686 and that this field should be left as is in subsequent dialogs */
687 CmdFieldModified
= True
;
690 static void printButtonCB(Widget widget
, caddr_t client_data
, caddr_t call_data
)
692 char *str
, command
[MAX_CMD_STR
];
695 int spawnFlags
=CLI$M_NOCLISYM
;
696 struct dsc$descriptor cmdDesc
;
698 /* get the print command from the command text area */
699 str
= XmTextGetString(Text4
);
701 /* add the file name to the print command */
702 sprintf(command
, "%s %s", str
, PrintFileName
);
706 /* append /DELETE to print command if requested */
708 strcat(command
, "/DELETE");
710 /* spawn the print command */
711 cmdDesc
.dsc$w_length
= strlen(command
);
712 cmdDesc
.dsc$b_dtype
= DSC$K_DTYPE_T
;
713 cmdDesc
.dsc$b_class
= DSC$K_CLASS_S
;
714 cmdDesc
.dsc$a_pointer
= command
;
715 spawn_sts
= lib$
spawn(&cmdDesc
,0,0,&spawnFlags
,0,0,0,0,0,0,0,0);
717 if (spawn_sts
!= SS$_NORMAL
)
719 DialogF(DF_WARN
, widget
, 1, "Print Error",
720 "Unable to Print:\n%d - %s\n spawnFlags = %d\n", "OK",
721 spawn_sts
, strerror(EVMSERR
, spawn_sts
), spawnFlags
);
727 char errorString
[MAX_PRINT_ERROR_LENGTH
], discarded
[1024];
729 /* get the print command from the command text area */
730 str
= XmTextGetString(Text4
);
732 /* add the file name and output redirection to the print command */
733 sprintf(command
, "cat %s | %s 2>&1", PrintFileName
, str
);
736 /* Issue the print command using a popen call and recover error messages
737 from the output stream of the command. */
738 pipe
= popen(command
,"r");
741 DialogF(DF_WARN
, widget
, 1, "Print Error", "Unable to Print:\n%s",
742 "OK", strerror(errno
));
747 nRead
= fread(errorString
, sizeof(char), MAX_PRINT_ERROR_LENGTH
-1, pipe
);
748 /* Make sure that the print command doesn't get stuck when trying to
749 write a lot of output on stderr (pipe may fill up). We discard
750 the additional output, though. */
751 while (fread(discarded
, sizeof(char), 1024, pipe
) > 0);
755 errorString
[nRead
] = '\0';
760 DialogF(DF_WARN
, widget
, 1, "Print Error", "Unable to Print:\n%s",
766 /* Print command succeeded, so retain the current print parameters */
767 if (CopiesOption
[0] != '\0') {
768 str
= XmTextGetString(Text1
);
772 if (QueueOption
[0] != '\0') {
773 str
= XmTextGetString(Text2
);
777 if (HostOption
[0] != '\0') {
778 str
= XmTextGetString(Text3
);
782 str
= XmTextGetString(Text4
);
783 strcpy(CmdText
, str
);
787 /* Pop down the dialog */
788 DoneWithDialog
= True
;
791 static void cancelButtonCB(Widget widget
, caddr_t client_data
, caddr_t call_data
)
793 DoneWithDialog
= True
;
794 CmdFieldModified
= False
;
799 ** Is the filename file in the directory dirpath
800 ** and does it have at least some of the mode_flags enabled ?
802 static int fileInDir(const char *filename
, const char *dirpath
, unsigned short mode_flags
)
806 struct dirent
*DirEntryPtr
;
808 struct direct
*DirEntryPtr
;
811 char fullname
[MAXPATHLEN
];
813 dfile
= opendir(dirpath
);
815 while ((DirEntryPtr
=readdir(dfile
)) != NULL
) {
816 if (!strcmp(DirEntryPtr
->d_name
, filename
)) {
817 strcpy(fullname
,dirpath
);
818 strcat(fullname
,"/");
819 strcat(fullname
,filename
);
820 stat(fullname
,&statbuf
);
822 return statbuf
.st_mode
& mode_flags
;
831 ** Is the filename file in the environment path directories
832 ** and does it have at least some of the mode_flags enabled ?
834 static int fileInPath(const char *filename
, unsigned short mode_flags
)
836 char path
[MAXPATHLEN
];
837 char *pathstring
,*lastchar
;
839 /* Get environmental value of PATH */
840 pathstring
= getenv("PATH");
841 if (pathstring
== NULL
)
844 /* parse the pathstring and search on each directory found */
846 /* if final path in list is empty, don't search it */
847 if (!strcmp(pathstring
, ""))
849 /* locate address of next : character */
850 lastchar
= strchr(pathstring
, SEPARATOR
);
851 if (lastchar
!= NULL
) {
852 /* if more directories remain in pathstring, copy up to : */
853 strncpy(path
, pathstring
, lastchar
-pathstring
);
854 path
[lastchar
-pathstring
] = '\0';
856 /* if it's the last directory, just copy it */
857 strcpy(path
, pathstring
);
859 /* search for the file in this path */
860 if(fileInDir(filename
, path
, mode_flags
))
861 return True
; /* found it !! */
862 /* point pathstring to start of new dir string */
863 pathstring
= lastchar
+ 1;
864 } while( lastchar
!= NULL
);
869 ** Is flpr present in the search path and is it executable ?
871 static int flprPresent(void)
873 /* Is flpr present in the search path and is it executable ? */
874 return fileInPath("flpr",0111);
877 static int foundTag(const char *tagfilename
, const char *tagname
, char *result
)
880 char tagformat
[512],line
[512];
882 strcpy(tagformat
, tagname
);
883 strcat(tagformat
, " %s");
885 tfile
= fopen(tagfilename
,"r");
887 while (!feof(tfile
)) {
888 fgets(line
,sizeof(line
),tfile
);
889 if (sscanf(line
,tagformat
,result
) != 0) {
899 static int foundEnv(const char *EnvVarName
, char *result
)
903 dqstr
= getenv(EnvVarName
);
905 strcpy(result
,dqstr
);
911 static void getFlprHostDefault(char *defhost
)
913 if (!foundEnv("FLPHOST",defhost
))
914 if(!foundTag("/usr/local/etc/flp.defaults", "host", defhost
))
918 static void getFlprQueueDefault(char *defqueue
)
920 if (!foundEnv("FLPQUE",defqueue
))
921 if (!foundTag("/usr/local/etc/flp.defaults", "queue", defqueue
))
925 #ifdef USE_LPR_PRINT_CMD
926 static void getLprQueueDefault(char *defqueue
)
928 if (!foundEnv("PRINTER",defqueue
))
933 #ifndef USE_LPR_PRINT_CMD
934 static void getLpQueueDefault(char *defqueue
)
936 if (!foundEnv("LPDEST",defqueue
))
943 static void getVmsQueueDefault(char *defqueue
)
947 char logicl
[12], tabl
[15];
955 struct dsc$descriptor tabName
;
956 struct dsc$descriptor logName
;
958 sprintf(tabl
, "LNM$FILE_DEV");
960 tabName
.dsc$w_length
= strlen(tabl
);
961 tabName
.dsc$b_dtype
= DSC$K_DTYPE_T
;
962 tabName
.dsc$b_class
= DSC$K_CLASS_S
;
963 tabName
.dsc$a_pointer
= tabl
;
965 sprintf(logicl
, "SYS$PRINT");
967 logName
.dsc$w_length
= strlen(logicl
);
968 logName
.dsc$b_dtype
= DSC$K_DTYPE_T
;
969 logName
.dsc$b_class
= DSC$K_CLASS_S
;
970 logName
.dsc$a_pointer
= logicl
;
972 translStruct
.itemCode
= LNM$_STRING
;
973 translStruct
.lngth
= &ret_len
;
974 translStruct
.bufL
= 99;
975 translStruct
.end_entry
= 0;
976 translStruct
.queName
= defqueue
;
977 translate_sts
= sys$
trnlnm(0,&tabName
,&logName
,0,&translStruct
);
979 if (translate_sts
!= SS$_NORMAL
&& translate_sts
!= SS$_NOLOGNAM
){
980 fprintf(stderr
, "Error return from sys$trnlnm: %d\n", translate_sts
);
981 DialogF(DF_WARN
, Label2
, 1, "Error", "Error translating SYS$PRINT",
986 /* printf("return status from sys$trnlnm = %d\n", translate_sts); */
987 if (translate_sts
== SS$_NOLOGNAM
)
992 strncpy(defqueue
, translStruct
.queName
, ret_len
);
993 defqueue
[ret_len
] = '\0';
994 /* printf("defqueue = %s, length = %d\n", defqueue, ret_len); */