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) 1988 AT&T */ 23 /* All Rights Reserved */ 24 25 26 /* 27 * Copyright (c) 1997, by Sun Microsystems, Inc. 28 * All rights reserved. 29 */ 30 31 /* 32 * Copyright (c) 2018, Joyent, Inc. 33 */ 34 35 /*LINTLIBRARY*/ 36 37 #include <sys/types.h> 38 #include <stdlib.h> 39 #include "utility.h" 40 41 /* 42 * default field 43 */ 44 45 static FIELD default_field = 46 { 47 0, /* status */ 48 0, /* rows */ 49 0, /* cols */ 50 0, /* frow */ 51 0, /* fcol */ 52 0, /* drows */ 53 0, /* dcols */ 54 0, /* maxgrow */ 55 0, /* nrow */ 56 0, /* nbuf */ 57 NO_JUSTIFICATION, /* just */ 58 0, /* page */ 59 0, /* index */ 60 ' ', /* pad */ 61 A_NORMAL, /* fore */ 62 A_NORMAL, /* back */ 63 O_VISIBLE | 64 O_ACTIVE | 65 O_PUBLIC | 66 O_EDIT | 67 O_WRAP | 68 O_BLANK | 69 O_AUTOSKIP | 70 O_NULLOK | 71 O_PASSOK | 72 O_STATIC, /* opts */ 73 (FIELD *)0, /* snext */ 74 (FIELD *)0, /* sprev */ 75 (FIELD *)0, /* link */ 76 (FORM *)0, /* form */ 77 (FIELDTYPE *)0, /* type */ 78 (char *)0, /* arg */ 79 (char *)0, /* buf */ 80 (char *)0, /* usrptr */ 81 }; 82 83 FIELD * _DEFAULT_FIELD = &default_field; 84 85 /* 86 * MakeType 87 */ 88 89 static int 90 MakeType(FIELD *f, va_list *ap) 91 { 92 int err = 0; 93 94 f->arg = MakeArg(f, ap, &err); /* pick off type specific args */ 95 96 if (err) { 97 FreeArg(f); /* release type specific args */ 98 f->type = (FIELDTYPE *)0; 99 f->arg = (char *)0; 100 return (FALSE); 101 } 102 IncrType(f->type); /* increment reference count */ 103 return (TRUE); 104 } 105 106 /* 107 * CopyType 108 */ 109 110 static int 111 CopyType(FIELD *f, FIELD *fsrc) 112 { 113 int err = 0; 114 115 f->type = fsrc->type; /* copy field type */ 116 f->arg = CopyArg(fsrc, &err); /* copy type specific info */ 117 118 if (err) { 119 FreeArg(f); /* release type specific args */ 120 f->type = (FIELDTYPE *)0; 121 f->arg = (char *)0; 122 return (FALSE); 123 } 124 IncrType(f->type); /* increment reference count */ 125 return (TRUE); 126 } 127 128 /* 129 * FreeType 130 */ 131 132 static void 133 FreeType(FIELD *f) 134 { 135 DecrType(f->type); /* decrement reference count */ 136 FreeArg(f); /* release type specific args */ 137 } 138 139 /* 140 * new_field 141 */ 142 143 FIELD * 144 new_field(int rows, int cols, int frow, int fcol, int nrow, int nbuf) 145 146 /* int rows; number of visible rows */ 147 /* int cols; number of visible cols */ 148 /* int frow; first row relative to form origin */ 149 /* int fcol; first col relative to form origin */ 150 /* int nrow; number of off screen rows */ 151 /* int nbuf; number of additional buffers */ 152 { 153 FIELD *f = (FIELD *) 0; 154 int i, size; 155 156 if (rows > 0 && cols > 0 && frow >= 0 && fcol >= 0 && nrow >= 0 && 157 nbuf >= 0 && Alloc(f, FIELD)) { 158 *f = *_DEFAULT_FIELD; 159 160 f->rows = rows; 161 f->cols = cols; 162 f->frow = frow; 163 f->fcol = fcol; 164 f->drows = rows + nrow; 165 f->dcols = cols; 166 f->nrow = nrow; 167 f->nbuf = nbuf; 168 f->link = f; 169 170 if (CopyType(f, _DEFAULT_FIELD)) { 171 size = TotalBuf(f); 172 173 if (arrayAlloc(Buf(f), size, char)) { 174 (void) memset(Buf(f), ' ', size); 175 176 for (i = 0; i <= f->nbuf; ++i) 177 *(Buffer(f, i + 1) - 1) = '\0'; 178 return (f); 179 } 180 } 181 } 182 (void) free_field(f); 183 return ((FIELD *) 0); 184 } 185 186 /* 187 * dup_field 188 */ 189 190 FIELD * 191 dup_field(FIELD *field, int frow, int fcol) 192 193 /* FIELD * field; field to duplicate */ 194 /* int frow; first row relative to form origin */ 195 /* int fcol; first col relative to form origin */ 196 { 197 FIELD *f = (FIELD *) 0; 198 int size; 199 200 if (field && frow >= 0 && fcol >= 0 && Alloc(f, FIELD)) { 201 *f = *_DEFAULT_FIELD; 202 203 f->frow = frow; 204 f->fcol = fcol; 205 f->link = f; 206 207 f->rows = field->rows; 208 f->cols = field->cols; 209 f->drows = field->drows; 210 f->dcols = field->dcols; 211 f->maxgrow = field->maxgrow; 212 f->nrow = field->nrow; 213 f->nbuf = field->nbuf; 214 f->just = field->just; 215 f->fore = field->fore; 216 f->back = field->back; 217 f->pad = field->pad; 218 f->opts = field->opts; 219 f->usrptr = field->usrptr; 220 f->status = Status(field, GROWABLE); 221 222 if (CopyType(f, field)) { 223 size = TotalBuf(f); 224 225 if (arrayAlloc(Buf(f), size, char)) { 226 (void) memcpy(Buf(f), Buf(field), size); 227 return (f); 228 } 229 } 230 } 231 (void) free_field(f); 232 return ((FIELD *) 0); 233 } 234 235 /* 236 * link_field 237 */ 238 239 FIELD * 240 link_field(FIELD *field, int frow, int fcol) 241 242 /* FIELD * field; field to link to */ 243 /* int frow; first row relative to form origin */ 244 /* int fcol; first col relative to form origin */ 245 { 246 FIELD *f = (FIELD *) 0; 247 248 if (field && frow >= 0 && fcol >= 0 && Alloc(f, FIELD)) { 249 *f = *_DEFAULT_FIELD; 250 251 f->frow = frow; 252 f->fcol = fcol; 253 254 f->link = field->link; 255 field->link = f; /* add field to linked list */ 256 257 f->buf = field->buf; 258 f->rows = field->rows; 259 f->cols = field->cols; 260 f->drows = field->drows; 261 f->dcols = field->dcols; 262 f->maxgrow = field->maxgrow; 263 f->nrow = field->nrow; 264 f->nbuf = field->nbuf; 265 f->just = field->just; 266 f->fore = field->fore; 267 f->back = field->back; 268 f->pad = field->pad; 269 f->opts = field->opts; 270 f->usrptr = field->usrptr; 271 f->status = Status(field, GROWABLE); 272 273 if (CopyType(f, field)) 274 return (f); 275 } 276 (void) free_field(f); 277 return ((FIELD *) 0); 278 } 279 280 /* 281 * free_field 282 */ 283 284 int 285 free_field(FIELD *f) 286 { 287 FIELD *p; 288 289 if (!f) 290 return (E_BAD_ARGUMENT); 291 292 if (f->form) 293 return (E_CONNECTED); 294 295 if (f->link != f) { /* check for linked field */ 296 for (p = f->link; p->link != f; p = p->link) 297 ; 298 p->link = f->link; /* delete from list */ 299 } else 300 Free(Buf(f)); /* free buffer space */ 301 302 FreeType(f); 303 Free(f); 304 return (E_OK); 305 } 306 307 /* 308 * field_info 309 */ 310 311 int 312 field_info(FIELD *f, int *rows, int *cols, int *frow, int *fcol, 313 int *nrow, int *nbuf) 314 315 /* FIELD *f; field whose information is wanted */ 316 /* int *rows; number of visible rows */ 317 /* int *cols; number of visible cols */ 318 /* int *frow; first row relative to form origin */ 319 /* int *fcol; first col relative to form origin */ 320 /* int *nrow; number of off screen rows */ 321 /* int *nbuf; number of additional buffers */ 322 { 323 if (!f) 324 return (E_BAD_ARGUMENT); 325 326 *rows = f->rows; 327 *cols = f->cols; 328 *frow = f->frow; 329 *fcol = f->fcol; 330 *nrow = f->nrow; 331 *nbuf = f->nbuf; 332 return (E_OK); 333 } 334 335 /* 336 * set_max_field 337 */ 338 339 int 340 set_max_field(FIELD *f, int max) 341 { 342 BOOLEAN onerow; 343 344 if (!f) 345 return (E_BAD_ARGUMENT); 346 347 onerow = OneRow(f); 348 349 if (max && ((onerow && f->dcols > max) || 350 (!onerow && f->drows > max))) 351 return (E_BAD_ARGUMENT); 352 353 f->maxgrow = max; 354 Clr(f, GROWABLE); 355 356 if (!Opt(f, O_STATIC) && ((!max || onerow && f->dcols < max) || 357 (!onerow && f->drows < max))) { 358 Set(f, GROWABLE); 359 } 360 361 return (E_OK); 362 } 363 364 /* 365 * dynamic_field_info 366 */ 367 368 int 369 dynamic_field_info(FIELD *f, int *drows, int *dcols, int *max) 370 371 /* FIELD *f; field whose information is wanted */ 372 /* int *drows; number of actual rows */ 373 /* int *dcols; number of actual cols */ 374 /* int *max; maximum growth allowable, else -1 */ 375 { 376 if (!f) 377 return (E_BAD_ARGUMENT); 378 379 *drows = f->drows; 380 *dcols = f->dcols; 381 *max = f->maxgrow; 382 return (E_OK); 383 } 384 385 /* 386 * move_field 387 */ 388 389 int 390 move_field(FIELD *f, int frow, int fcol) 391 392 /* FIELD *f; field to move */ 393 /* int frow; first row relative to form origin */ 394 /* int fcol; first col relative to form origin */ 395 { 396 if (! f || frow < 0 || fcol < 0) 397 return (E_BAD_ARGUMENT); 398 399 if (f->form) 400 return (E_CONNECTED); 401 402 f->frow = frow; 403 f->fcol = fcol; 404 return (E_OK); 405 } 406 407 /* 408 * set_field_type 409 */ 410 411 int 412 set_field_type(FIELD *f, FIELDTYPE *ft, ...) 413 { 414 va_list ap; 415 int v = E_SYSTEM_ERROR; 416 417 va_start(ap, ft); 418 f = Field(f); 419 FreeType(f); /* free old type */ 420 f->type = ft; 421 422 if (MakeType(f, &ap)) /* set up new type */ 423 v = E_OK; 424 va_end(ap); 425 return (v); 426 } 427 428 FIELDTYPE * 429 field_type(FIELD *f) 430 { 431 return (Field(f)->type); 432 } 433 434 char * 435 field_arg(FIELD *f) 436 { 437 return (Field(f)->arg); 438 } 439 440 /* 441 * set_new_page 442 */ 443 444 int 445 set_new_page(FIELD *f, int flag) 446 { 447 f = Field(f); 448 449 if (f->form) 450 return (E_CONNECTED); 451 452 if (flag) 453 Set(f, NEW_PAGE); 454 else 455 Clr(f, NEW_PAGE); 456 457 return (E_OK); 458 } 459 460 int 461 new_page(FIELD *f) 462 { 463 if (Status(Field(f), NEW_PAGE)) 464 return (TRUE); 465 else 466 return (FALSE); 467 }