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