1 /* Public Domain Curses */ 2 3 #include <curspriv.h> 4 5 /*man-start************************************************************** 6 7 overlay 8 ------- 9 10 ### Synopsis 11 12 int overlay(const WINDOW *src_w, WINDOW *dst_w) 13 int overwrite(const WINDOW *src_w, WINDOW *dst_w) 14 int copywin(const WINDOW *src_w, WINDOW *dst_w, int src_tr, 15 int src_tc, int dst_tr, int dst_tc, int dst_br, 16 int dst_bc, bool overlay) 17 18 ### Description 19 20 overlay() and overwrite() copy all the text from src_w into 21 dst_w. The windows need not be the same size. Those characters 22 in the source window that intersect with the destination window 23 are copied, so that the characters appear in the same physical 24 position on the screen. The difference between the two functions 25 is that overlay() is non-destructive (blanks are not copied) 26 while overwrite() is destructive (blanks are copied). 27 28 copywin() is similar, but doesn't require that the two windows 29 overlap. The arguments src_tc and src_tr specify the top left 30 corner of the region to be copied. dst_tc, dst_tr, dst_br, and 31 dst_bc specify the region within the destination window to copy 32 to. The argument "overlay", if TRUE, indicates that the copy is move(int y,int x)33 done non-destructively (as in overlay()); blanks in the source 34 window are not copied to the destination window. When overlay is 35 FALSE, blanks are copied. 36 37 ### Return Value 38 39 All functions return OK on success and ERR on error. 40 41 ### Portability 42 X/Open BSD SYS V 43 overlay Y Y Y 44 overwrite Y Y Y 45 copywin Y - 3.0 46 47 **man-end****************************************************************/ 48 49 /* Thanks to Andreas Otte <venn@@uni-paderborn.de> for the 50 corrected overlay()/overwrite() behavior. */ 51 52 static int _copy_win(const WINDOW *src_w, WINDOW *dst_w, int src_tr, 53 int src_tc, int src_br, int src_bc, int dst_tr, 54 int dst_tc, bool _overlay) 55 { 56 int col, line, y1, fc, *minchng, *maxchng; 57 chtype *w1ptr, *w2ptr; 58 59 int lc = 0; 60 int xdiff = src_bc - src_tc; 61 int ydiff = src_br - src_tr; 62 63 if (!src_w || !dst_w) 64 return ERR; 65 66 minchng = dst_w->_firstch; 67 maxchng = dst_w->_lastch; 68 69 for (y1 = 0; y1 < dst_tr; y1++) 70 { 71 minchng++; 72 maxchng++; 73 } 74 75 for (line = 0; line < ydiff; line++) 76 { 77 w1ptr = src_w->_y[line + src_tr] + src_tc; 78 w2ptr = dst_w->_y[line + dst_tr] + dst_tc; 79 80 fc = _NO_CHANGE; 81 82 for (col = 0; col < xdiff; col++) 83 { 84 if ((*w1ptr) != (*w2ptr) && 85 !((*w1ptr & A_CHARTEXT) == ' ' && _overlay)) 86 { 87 *w2ptr = *w1ptr; 88 89 if (fc == _NO_CHANGE) 90 fc = col + dst_tc; 91 92 lc = col + dst_tc; 93 } 94 95 w1ptr++; 96 w2ptr++; 97 } 98 99 if (*minchng == _NO_CHANGE) 100 { 101 *minchng = fc; 102 *maxchng = lc; 103 } 104 else if (fc != _NO_CHANGE) 105 { 106 if (fc < *minchng) 107 *minchng = fc; 108 if (lc > *maxchng) 109 *maxchng = lc; 110 } 111 112 minchng++; 113 maxchng++; 114 } 115 116 return OK; 117 } 118 119 int _copy_overlap(const WINDOW *src_w, WINDOW *dst_w, bool overlay) 120 { 121 int first_line, first_col, last_line, last_col; 122 int src_start_x, src_start_y, dst_start_x, dst_start_y; 123 int xdiff, ydiff; 124 125 if (!src_w || !dst_w) 126 return ERR; 127 128 first_col = max(dst_w->_begx, src_w->_begx); 129 first_line = max(dst_w->_begy, src_w->_begy); 130 131 last_col = min(src_w->_begx + src_w->_maxx, dst_w->_begx + dst_w->_maxx); 132 last_line = min(src_w->_begy + src_w->_maxy, dst_w->_begy + dst_w->_maxy); 133 134 /* determine the overlapping region of the two windows in real 135 coordinates */ 136 137 /* if no overlapping region, do nothing */ 138 139 if ((last_col < first_col) || (last_line < first_line)) 140 return OK; 141 142 /* size of overlapping region */ 143 144 xdiff = last_col - first_col; 145 ydiff = last_line - first_line; 146 147 if (src_w->_begx <= dst_w->_begx) 148 { 149 src_start_x = dst_w->_begx - src_w->_begx; 150 dst_start_x = 0; 151 } 152 else 153 { 154 dst_start_x = src_w->_begx - dst_w->_begx; 155 src_start_x = 0; 156 } 157 158 if (src_w->_begy <= dst_w->_begy) 159 { 160 src_start_y = dst_w->_begy - src_w->_begy; 161 dst_start_y = 0; 162 } 163 else 164 { 165 dst_start_y = src_w->_begy - dst_w->_begy; 166 src_start_y = 0; 167 } 168 169 return _copy_win(src_w, dst_w, src_start_y, src_start_x, 170 src_start_y + ydiff, src_start_x + xdiff, 171 dst_start_y, dst_start_x, overlay); 172 } 173 174 int overlay(const WINDOW *src_w, WINDOW *dst_w) 175 { 176 PDC_LOG(("overlay() - called\n")); 177 178 return _copy_overlap(src_w, dst_w, TRUE); 179 } 180 181 int overwrite(const WINDOW *src_w, WINDOW *dst_w) 182 { 183 PDC_LOG(("overwrite() - called\n")); 184 185 return _copy_overlap(src_w, dst_w, FALSE); 186 } 187 188 int copywin(const WINDOW *src_w, WINDOW *dst_w, int src_tr, int src_tc, 189 int dst_tr, int dst_tc, int dst_br, int dst_bc, int _overlay) 190 { 191 int src_end_x, src_end_y; 192 int src_rows, src_cols, dst_rows, dst_cols; 193 int min_rows, min_cols; 194 195 PDC_LOG(("copywin() - called\n")); 196 197 if (!src_w || !dst_w || dst_w == curscr || dst_br >= dst_w->_maxy 198 || dst_bc >= dst_w->_maxx || dst_tr < 0 || dst_tc < 0) 199 return ERR; 200 201 src_rows = src_w->_maxy - src_tr; 202 src_cols = src_w->_maxx - src_tc; 203 dst_rows = dst_br - dst_tr + 1; 204 dst_cols = dst_bc - dst_tc + 1; 205 206 min_rows = min(src_rows, dst_rows); 207 min_cols = min(src_cols, dst_cols); 208 209 src_end_y = src_tr + min_rows; 210 src_end_x = src_tc + min_cols; 211 212 return _copy_win(src_w, dst_w, src_tr, src_tc, src_end_y, src_end_x, 213 dst_tr, dst_tc, (bool)_overlay); 214 } 215