/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ #ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.13 */ /* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */ #include "string.h" #include "stdlib.h" #include "lp.h" #include "lp.set.h" #if defined(__STDC__) char * tparm ( char * , ... ); int putp ( char * ); int tidbit ( char * , char * , ... ); #else extern char *tparm(); int putp(); int tidbit(); #endif extern short output_res_char, output_res_line, output_res_horz_inch, output_res_vert_inch; /** ** set_size() **/ int #if defined(__STDC__) set_size ( char * str, int which, int putout ) #else set_size (str, which, putout) char *str; int which, putout; #endif { static int cleared_margins_already = 0; double size; int i, isize, ret; short curval, output_res, output_res_inch; char *rest, *set_margin1, *set_margin2, *set_margin1_parm, *set_margin2_parm, *set_both_margins = 0, *move1, *move2, *step2, *p1, *p2, *sp1, *sp2, *carriage_return, *parm_right_cursor, *column_address, *repeat_char, *cursor_right, *parm_down_cursor, *row_address, *cursor_down, *clear_margins, *finale, *slines; if (which == 'W') { tidbit ((char *)0, "cols", &curval); if (output_res_char == -1) tidbit ((char *)0, "orc", &output_res_char); output_res = output_res_char; if (output_res_horz_inch == -1) tidbit ((char *)0, "orhi", &output_res_horz_inch); output_res_inch = output_res_horz_inch; } else { tidbit ((char *)0, "lines", &curval); if (output_res_line == -1) tidbit ((char *)0, "orl", &output_res_line); output_res = output_res_line; if (output_res_vert_inch == -1) tidbit ((char *)0, "orvi", &output_res_vert_inch); output_res_inch = output_res_vert_inch; } size = strtod(str, &rest); if (size <= 0) return (E_BAD_ARGS); switch (*rest) { case ' ': case 0: break; case 'c': /* * Convert to inches. */ size /= 2.54; /* fall through */ case 'i': /* * Convert to lines/columns. */ if (output_res == -1 || output_res_inch == -1) return (E_FAILURE); size *= output_res_inch / output_res; break; default: return (E_BAD_ARGS); } if ((isize = R(size)) == curval) return (E_SUCCESS); /* * We number things 0 through N (e.g. an 80 column * page is numbered 0 to 79). Thus if we are asked * to set a width of 132, we set the left margin at * 0 and the right at 131. * Of course, if we're using the "slines" string, * we give the length as N+1. */ isize--; /* * When the width or length is set using the set-margin-at- * current-position caps (e.g. smgl and smgr, smgt, smgb): * If a parameterized motion capability exists, then we'll try * to use it. However, if the instantiation of the capability * (through tparm()) gives nothing, assume this means the motion * is not allowed--don't try the next choice. This is the only * way we have of checking for a width or length beyond the * limits of the printer. If a parameterized motion capability * doesn't exist, we have no way to check out-of-bounds width * and length, sorry. * * When the width or length is set using parameterized caps * (e.g. smglp and smgrp, or slines for length), the above is not * a problem, of course. */ if (which == 'W') { tidbit ((char *)0, "smgl", &set_margin1); tidbit ((char *)0, "smgr", &set_margin2); tidbit ((char *)0, "smglp", &set_margin1_parm); tidbit ((char *)0, "smgrp", &set_margin2_parm); tidbit ((char *)0, "smglr", &set_both_margins); tidbit ((char *)0, "cr", &carriage_return); tidbit ((char *)0, "cuf", &parm_right_cursor); tidbit ((char *)0, "hpa", &column_address); tidbit ((char *)0, "rep", &repeat_char); tidbit ((char *)0, "cuf1", &cursor_right); if (OKAY(carriage_return)) move1 = carriage_return; else move1 = "\r"; if (OKAY(parm_right_cursor)) { move2 = tparm(parm_right_cursor, isize); step2 = 0; } else if (OKAY(column_address)) { move2 = tparm(column_address, isize); step2 = 0; } else if (OKAY(repeat_char)) { move2 = tparm(repeat_char, ' ', isize); step2 = 0; } else if (OKAY(cursor_right)) { move2 = 0; step2 = cursor_right; } else { move2 = 0; step2 = " "; } finale = move1; /* i.e. carriage return */ } else { tidbit ((char *)0, "smgt", &set_margin1); tidbit ((char *)0, "smgb", &set_margin2); tidbit ((char *)0, "smgtp", &set_margin1_parm); tidbit ((char *)0, "smgbp", &set_margin2_parm); tidbit ((char *)0, "smgtb", &set_both_margins); /* * For compatibility with SVR3.2 era Terminfo files, * we check "u9" as an alias for "slines" IF a check * of "slines" comes up empty. */ slines = 0; /* (in case compiled with old tidbit) */ tidbit ((char *)0, "slines", &slines); if (!OKAY(slines)) tidbit ((char *)0, "u9", &slines); tidbit ((char *)0, "cud", &parm_down_cursor); tidbit ((char *)0, "vpa", &row_address); tidbit ((char *)0, "cud1", &cursor_down); move1 = ""; /* Assume we're already at top-of-page */ if (OKAY(parm_down_cursor)) { move2 = tparm(parm_down_cursor, isize); step2 = 0; } else if (OKAY(row_address)) { move2 = tparm(row_address, isize); step2 = 0; } else if (OKAY(cursor_down)) { move2 = 0; step2 = cursor_down; } else { move2 = 0; step2 = "\n"; } /* * This has to be smarter, but we don't have the * smarts ourselves, yet; i.e. what do we do if * there is no "ff"? */ tidbit ((char *)0, "ff", &finale); } /* * For a short while we needed a kludge in Terminfo * whereby if only one of the left/right or top/bottom * parameterized margin setters was defined, it was * a parm-string that could set BOTH margins. We now have * separate strings for setting both margins, but we still * allow the kludge. */ if (!OKAY(set_both_margins)) { if (OKAY(set_margin1_parm) && !OKAY(set_margin2_parm)) set_both_margins = set_margin1_parm; else if (OKAY(set_margin2_parm) && !OKAY(set_margin1_parm)) set_both_margins = set_margin2_parm; } sp1 = sp2 = 0; if ( which == 'L' && OKAY(slines) && (p1 = tparm(slines, isize + 1)) ) { if (putout) putp (p1); finale = 0; ret = E_SUCCESS; } else if ( OKAY(set_both_margins) && (p1 = tparm(set_both_margins, 0, isize)) && *p1 && (sp1 = Strdup(p1)) ) { if (putout) { if (!cleared_margins_already) { tidbit ((char *)0, "mgc", &clear_margins); if (OKAY(clear_margins)) { cleared_margins_already = 1; putp (clear_margins); } } putp (sp1); } ret = E_SUCCESS; /* * The "smgbp" string takes two parameters; each defines the * position of the margin, the first counting lines from the top * of the page, the second counting lines from the bottom of the * page. This shows the flaw in using the set-margin commands * for setting the page length, because BY DEFINITION the second * parameter must be 0 for us. But giving 0 won't cause a change * in the page length, will it! * * Anyway, the "smgrp" expects just one parameter (thus will * ignore a second parameter) so we can safely give the second * parameter without caring which of width or length we're * setting. */ } else if ( OKAY(set_margin1_parm) && (p1 = tparm(set_margin1_parm, 0)) && *p1 && (sp1 = Strdup(p1)) && OKAY(set_margin2_parm) && (p2 = tparm(set_margin2_parm, isize, 0)) && *p2 && (sp2 = Strdup(p2)) ) { if (putout) { if (!cleared_margins_already) { tidbit ((char *)0, "mgc", &clear_margins); if (OKAY(clear_margins)) { cleared_margins_already = 1; putp (clear_margins); } } putp (sp1); putp (sp2); } ret = E_SUCCESS; } else if ( OKAY(set_margin1) && OKAY(set_margin2) && (OKAY(move2) || OKAY(step2)) ) { register char *p, *q; register int free_it = 0; if (putout) { if (!cleared_margins_already) { tidbit ((char *)0, "mgc", &clear_margins); if (OKAY(clear_margins)) { cleared_margins_already = 1; putp (clear_margins); } } putp (move1); putp (set_margin1); if (!move2) { move2 = Malloc(isize * strlen(step2) + 1); if (!move2) return (E_MALLOC); for (p = move2, i = 0; i < isize; i++) for (q = step2; *q; ) *p++ = *q++; *p = 0; free_it = 1; } putp (move2); putp (set_margin2); if (free_it) Free (move2); } ret = E_SUCCESS; } else ret = E_FAILURE; if (putout && OKAY(finale)) putp (finale); if (sp1) Free (sp1); if (sp2) Free (sp2); return (ret); }