1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
23 /* All Rights Reserved */
24
25
26 #ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.13 */
27 /* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */
28
29 #include "string.h"
30 #include "stdlib.h"
31
32 #include "lp.h"
33 #include "lp.set.h"
34
35 #if defined(__STDC__)
36
37 char * tparm ( char * , ... );
38 int putp ( char * );
39 int tidbit ( char * , char * , ... );
40
41 #else
42
43 extern char *tparm();
44 int putp();
45 int tidbit();
46
47 #endif
48
49 extern short output_res_char,
50 output_res_line,
51 output_res_horz_inch,
52 output_res_vert_inch;
53
54 /**
55 ** set_size()
56 **/
57
58 int
59 #if defined(__STDC__)
set_size(char * str,int which,int putout)60 set_size (
61 char * str,
62 int which,
63 int putout
64 )
65 #else
66 set_size (str, which, putout)
67 char *str;
68 int which,
69 putout;
70 #endif
71 {
72 static int cleared_margins_already = 0;
73
74 double size;
75
76 int i,
77 isize,
78 ret;
79
80 short curval,
81 output_res,
82 output_res_inch;
83
84 char *rest,
85 *set_margin1,
86 *set_margin2,
87 *set_margin1_parm,
88 *set_margin2_parm,
89 *set_both_margins = 0,
90 *move1,
91 *move2,
92 *step2,
93 *p1,
94 *p2,
95 *sp1,
96 *sp2,
97 *carriage_return,
98 *parm_right_cursor,
99 *column_address,
100 *repeat_char,
101 *cursor_right,
102 *parm_down_cursor,
103 *row_address,
104 *cursor_down,
105 *clear_margins,
106 *finale,
107 *slines;
108
109
110 if (which == 'W') {
111
112 tidbit ((char *)0, "cols", &curval);
113
114 if (output_res_char == -1)
115 tidbit ((char *)0, "orc", &output_res_char);
116 output_res = output_res_char;
117
118 if (output_res_horz_inch == -1)
119 tidbit ((char *)0, "orhi", &output_res_horz_inch);
120 output_res_inch = output_res_horz_inch;
121
122 } else {
123
124 tidbit ((char *)0, "lines", &curval);
125
126 if (output_res_line == -1)
127 tidbit ((char *)0, "orl", &output_res_line);
128 output_res = output_res_line;
129
130 if (output_res_vert_inch == -1)
131 tidbit ((char *)0, "orvi", &output_res_vert_inch);
132 output_res_inch = output_res_vert_inch;
133
134 }
135
136 size = strtod(str, &rest);
137 if (size <= 0)
138 return (E_BAD_ARGS);
139
140 switch (*rest) {
141 case ' ':
142 case 0:
143 break;
144 case 'c':
145 /*
146 * Convert to inches.
147 */
148 size /= 2.54;
149 /* fall through */
150 case 'i':
151 /*
152 * Convert to lines/columns.
153 */
154 if (output_res == -1 || output_res_inch == -1)
155 return (E_FAILURE);
156 size *= output_res_inch / output_res;
157 break;
158 default:
159 return (E_BAD_ARGS);
160 }
161
162
163 if ((isize = R(size)) == curval)
164 return (E_SUCCESS);
165
166 /*
167 * We number things 0 through N (e.g. an 80 column
168 * page is numbered 0 to 79). Thus if we are asked
169 * to set a width of 132, we set the left margin at
170 * 0 and the right at 131.
171 * Of course, if we're using the "slines" string,
172 * we give the length as N+1.
173 */
174 isize--;
175
176 /*
177 * When the width or length is set using the set-margin-at-
178 * current-position caps (e.g. smgl and smgr, smgt, smgb):
179 * If a parameterized motion capability exists, then we'll try
180 * to use it. However, if the instantiation of the capability
181 * (through tparm()) gives nothing, assume this means the motion
182 * is not allowed--don't try the next choice. This is the only
183 * way we have of checking for a width or length beyond the
184 * limits of the printer. If a parameterized motion capability
185 * doesn't exist, we have no way to check out-of-bounds width
186 * and length, sorry.
187 *
188 * When the width or length is set using parameterized caps
189 * (e.g. smglp and smgrp, or slines for length), the above is not
190 * a problem, of course.
191 */
192 if (which == 'W') {
193
194 tidbit ((char *)0, "smgl", &set_margin1);
195 tidbit ((char *)0, "smgr", &set_margin2);
196 tidbit ((char *)0, "smglp", &set_margin1_parm);
197 tidbit ((char *)0, "smgrp", &set_margin2_parm);
198 tidbit ((char *)0, "smglr", &set_both_margins);
199
200 tidbit ((char *)0, "cr", &carriage_return);
201 tidbit ((char *)0, "cuf", &parm_right_cursor);
202 tidbit ((char *)0, "hpa", &column_address);
203 tidbit ((char *)0, "rep", &repeat_char);
204 tidbit ((char *)0, "cuf1", &cursor_right);
205
206 if (OKAY(carriage_return))
207 move1 = carriage_return;
208 else
209 move1 = "\r";
210
211 if (OKAY(parm_right_cursor)) {
212 move2 = tparm(parm_right_cursor, isize);
213 step2 = 0;
214
215 } else if (OKAY(column_address)) {
216 move2 = tparm(column_address, isize);
217 step2 = 0;
218
219 } else if (OKAY(repeat_char)) {
220 move2 = tparm(repeat_char, ' ', isize);
221 step2 = 0;
222
223 } else if (OKAY(cursor_right)) {
224 move2 = 0;
225 step2 = cursor_right;
226
227 } else {
228 move2 = 0;
229 step2 = " ";
230 }
231
232 finale = move1; /* i.e. carriage return */
233
234 } else {
235
236 tidbit ((char *)0, "smgt", &set_margin1);
237 tidbit ((char *)0, "smgb", &set_margin2);
238 tidbit ((char *)0, "smgtp", &set_margin1_parm);
239 tidbit ((char *)0, "smgbp", &set_margin2_parm);
240 tidbit ((char *)0, "smgtb", &set_both_margins);
241
242 /*
243 * For compatibility with SVR3.2 era Terminfo files,
244 * we check "u9" as an alias for "slines" IF a check
245 * of "slines" comes up empty.
246 */
247 slines = 0; /* (in case compiled with old tidbit) */
248 tidbit ((char *)0, "slines", &slines);
249 if (!OKAY(slines))
250 tidbit ((char *)0, "u9", &slines);
251
252 tidbit ((char *)0, "cud", &parm_down_cursor);
253 tidbit ((char *)0, "vpa", &row_address);
254 tidbit ((char *)0, "cud1", &cursor_down);
255
256 move1 = ""; /* Assume we're already at top-of-page */
257
258 if (OKAY(parm_down_cursor)) {
259 move2 = tparm(parm_down_cursor, isize);
260 step2 = 0;
261
262 } else if (OKAY(row_address)) {
263 move2 = tparm(row_address, isize);
264 step2 = 0;
265
266 } else if (OKAY(cursor_down)) {
267 move2 = 0;
268 step2 = cursor_down;
269
270 } else {
271 move2 = 0;
272 step2 = "\n";
273 }
274
275 /*
276 * This has to be smarter, but we don't have the
277 * smarts ourselves, yet; i.e. what do we do if
278 * there is no "ff"?
279 */
280 tidbit ((char *)0, "ff", &finale);
281
282 }
283
284 /*
285 * For a short while we needed a kludge in Terminfo
286 * whereby if only one of the left/right or top/bottom
287 * parameterized margin setters was defined, it was
288 * a parm-string that could set BOTH margins. We now have
289 * separate strings for setting both margins, but we still
290 * allow the kludge.
291 */
292 if (!OKAY(set_both_margins)) {
293 if (OKAY(set_margin1_parm) && !OKAY(set_margin2_parm))
294 set_both_margins = set_margin1_parm;
295 else if (OKAY(set_margin2_parm) && !OKAY(set_margin1_parm))
296 set_both_margins = set_margin2_parm;
297 }
298
299 sp1 = sp2 = 0;
300
301 if (
302 which == 'L'
303 && OKAY(slines)
304 && (p1 = tparm(slines, isize + 1))
305 ) {
306 if (putout)
307 putp (p1);
308 finale = 0;
309 ret = E_SUCCESS;
310
311 } else if (
312 OKAY(set_both_margins)
313 && (p1 = tparm(set_both_margins, 0, isize))
314 && *p1
315 && (sp1 = Strdup(p1))
316 ) {
317
318 if (putout) {
319
320 if (!cleared_margins_already) {
321 tidbit ((char *)0, "mgc", &clear_margins);
322 if (OKAY(clear_margins)) {
323 cleared_margins_already = 1;
324 putp (clear_margins);
325 }
326 }
327
328 putp (sp1);
329
330 }
331 ret = E_SUCCESS;
332
333 /*
334 * The "smgbp" string takes two parameters; each defines the
335 * position of the margin, the first counting lines from the top
336 * of the page, the second counting lines from the bottom of the
337 * page. This shows the flaw in using the set-margin commands
338 * for setting the page length, because BY DEFINITION the second
339 * parameter must be 0 for us. But giving 0 won't cause a change
340 * in the page length, will it!
341 *
342 * Anyway, the "smgrp" expects just one parameter (thus will
343 * ignore a second parameter) so we can safely give the second
344 * parameter without caring which of width or length we're
345 * setting.
346 */
347 } else if (
348 OKAY(set_margin1_parm)
349 && (p1 = tparm(set_margin1_parm, 0))
350 && *p1
351 && (sp1 = Strdup(p1))
352 && OKAY(set_margin2_parm)
353 && (p2 = tparm(set_margin2_parm, isize, 0))
354 && *p2
355 && (sp2 = Strdup(p2))
356 ) {
357
358 if (putout) {
359
360 if (!cleared_margins_already) {
361 tidbit ((char *)0, "mgc", &clear_margins);
362 if (OKAY(clear_margins)) {
363 cleared_margins_already = 1;
364 putp (clear_margins);
365 }
366 }
367
368 putp (sp1);
369 putp (sp2);
370
371 }
372 ret = E_SUCCESS;
373
374 } else if (
375 OKAY(set_margin1)
376 && OKAY(set_margin2)
377 && (OKAY(move2) || OKAY(step2))
378 ) {
379
380 register char *p,
381 *q;
382
383 register int free_it = 0;
384
385 if (putout) {
386
387 if (!cleared_margins_already) {
388 tidbit ((char *)0, "mgc", &clear_margins);
389 if (OKAY(clear_margins)) {
390 cleared_margins_already = 1;
391 putp (clear_margins);
392 }
393 }
394
395 putp (move1);
396 putp (set_margin1);
397
398 if (!move2) {
399 move2 = Malloc(isize * strlen(step2) + 1);
400 if (!move2)
401 return (E_MALLOC);
402 for (p = move2, i = 0; i < isize; i++)
403 for (q = step2; *q; )
404 *p++ = *q++;
405 *p = 0;
406 free_it = 1;
407 }
408
409 putp (move2);
410 putp (set_margin2);
411
412 if (free_it)
413 Free (move2);
414 }
415 ret = E_SUCCESS;
416
417 } else
418 ret = E_FAILURE;
419
420 if (putout && OKAY(finale))
421 putp (finale);
422
423 if (sp1)
424 Free (sp1);
425 if (sp2)
426 Free (sp2);
427 return (ret);
428 }
429