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 /* 23 * Copyright 1997 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1988 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * University Copyright- Copyright (c) 1982, 1986, 1988 32 * The Regents of the University of California 33 * All Rights Reserved 34 * 35 * University Acknowledgment- Portions of this document are derived from 36 * software developed by the University of California, Berkeley, and its 37 * contributors. 38 */ 39 40 #pragma ident "%Z%%M% %I% %E% SMI" 41 42 /*LINTLIBRARY*/ 43 44 #include <stdlib.h> 45 #include <string.h> 46 #include <sys/types.h> 47 #include "curses_inc.h" 48 49 /* 50 * Duplicate a window. 51 * 52 * SS: calling makenew to allocate a new window is wastefull, since 53 * makenew initializes all the variables, and then we re-initialize 54 * the desired values to these variables. 55 */ 56 57 WINDOW * 58 dupwin(WINDOW *win) 59 { 60 WINDOW *new; 61 int i, ncolumns = win->_maxx, nlines = win->_maxy; 62 size_t line_size = nlines * sizeof (short); 63 chtype **wincp, **newcp; 64 int ncolsav = ncolumns; 65 66 /* allocate storage for new window and do block copy of */ 67 /* old one into new */ 68 69 if ((new = (WINDOW *) malloc(sizeof (WINDOW))) == NULL) 70 goto out0; 71 72 (void) memcpy(new, win, sizeof (WINDOW)); 73 74 /* allocate storage for "malloced" fields of the new window */ 75 76 if ((new->_firstch = (short *)malloc((unsigned)2 * line_size)) == NULL) 77 goto out1; 78 else 79 win->_lastch = win->_firstch + nlines; 80 81 if ((new->_y = (chtype **) malloc(nlines * sizeof (chtype *))) == 82 NULL) { 83 /* 84 * We put the free's here rather than after the image call, this 85 * is because _image free's all the rest of the malloc'ed areas. 86 */ 87 free((char *)new->_firstch); 88 out1: 89 free((char *)new); 90 goto out0; 91 } 92 93 if (_image(new) == ERR) { 94 out0: 95 curs_errno = CURS_BAD_MALLOC; 96 #ifdef DEBUG 97 strcpy(curs_parm_err, "dupwin"); 98 curserr(); 99 #endif /* DEBUG */ 100 return ((WINDOW *) NULL); 101 } 102 103 /* copy information from "malloced" areas of the old window into new */ 104 105 wincp = win->_y; 106 newcp = new->_y; 107 for (i = 0; i < nlines; ++i, ++wincp, ++newcp) { 108 chtype *ws, *we, *ns, *ne, wc; 109 int n; 110 111 ws = *wincp; 112 we = ws + ncolsav - 1; 113 /* skip partial characters */ 114 for (; ws <= we; ++ws) 115 if (!ISCBIT(*ws)) 116 break; 117 for (; we >= ws; --we) 118 if (!ISCBIT(*we)) 119 break; 120 if (we >= ws) { 121 wc = *we; 122 n = _curs_scrwidth[TYPE(wc)]; 123 if ((we + n) <= (*wincp + ncolsav)) 124 we += n; 125 ns = *newcp + (ws - *wincp); 126 ne = *newcp + (we - *wincp); 127 (void) memcpy((char *)ns, (char *)ws, 128 (ne-ns)*sizeof (chtype)); 129 } else 130 ns = ne = *newcp + ncolsav; 131 /* fill the rest with background chars */ 132 wc = win->_bkgd; 133 for (ws = *newcp; ws < ns; ++ws) 134 *ws = wc; 135 for (ws = *newcp+ncolsav-1; ws >= ne; --ws) 136 *ws = wc; 137 } 138 139 (void) memcpy((char *)new->_firstch, (char *)win->_firstch, 140 2 * line_size); 141 142 new->_flags |= _WINCHANGED; 143 new->_ndescs = 0; 144 /* 145 * Just like we don't create this window as a subwin if the one 146 * sent is, we don't create a padwin. Besides, if the user 147 * calls p*refresh a padwin will be created then. 148 */ 149 new->_padwin = new->_parent = (WINDOW *) NULL; 150 new->_pary = new->_parx = -1; 151 152 new->_index = win->_index; 153 new->_nbyte = win->_nbyte; 154 new->_insmode = win->_insmode; 155 (void) memcpy((char *)new->_waitc, (char *)win->_waitc, 156 _csmax * sizeof (char)); 157 158 return (new); 159 } 160