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