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__) 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