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 /* A panels subsystem built on curses--Update the pile of panels */ 32 33 #pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.3 */ 34 35 /*LINTLIBRARY*/ 36 37 #include <sys/types.h> 38 #include <stdlib.h> 39 #include <curses.h> 40 #include "private.h" 41 42 /* 43 * touch_top - Touch the line in all windows 44 * which is visible above a given line 45 */ 46 static void 47 touch_top(PANEL *panel, int line, _obscured_list *obs, int start_x, int end_x) 48 { 49 PANEL *pnl; 50 _obscured_list *next_obs; 51 52 do { 53 pnl = obs -> panel_p; 54 if ((next_obs = obs->next) == panel -> obscured -> next) 55 next_obs = 0; 56 57 if (line >= obs -> start && line <= obs -> end && 58 pnl->wstartx <= end_x && pnl->wendx >= start_x) { 59 (void) touchline(pnl->win, line - pnl->wstarty, 1); 60 if (pnl->wstartx > start_x && pnl->wendx < end_x) { 61 if (next_obs) 62 touch_top(panel, line, next_obs, 63 pnl->wendx+1, end_x); 64 end_x = pnl -> wstartx - 1; 65 } else { 66 if (pnl->wstartx <= start_x) 67 start_x = pnl -> wendx + 1; 68 if (pnl->wendx >= end_x) 69 end_x = pnl -> wstartx - 1; 70 if (start_x > end_x) 71 return; 72 } 73 } 74 } 75 while ((obs = next_obs) != 0); 76 } 77 78 /* 79 * std_touch_top 80 * Touch the line in all windows which is visible above a given line. 81 * This routine is almost identical to touch_top, except that the "panel" 82 * is stdscr in this case. The "obscured" list is the list of panels. 83 */ 84 static void 85 std_touch_top(int line, PANEL *obs_pnl, int start_x, int end_x) 86 { 87 PANEL *next_obs; 88 89 do { 90 next_obs = obs_pnl -> below; 91 92 if (line >= obs_pnl->wstarty && line <= obs_pnl->wendy && 93 obs_pnl->wstartx <= end_x && obs_pnl->wendx >= start_x) { 94 (void) touchline(obs_pnl->win, 95 line - obs_pnl->wstarty, 1); 96 if (obs_pnl->wstartx > start_x && 97 obs_pnl->wendx < end_x) { 98 if (next_obs) 99 std_touch_top(line, next_obs, 100 obs_pnl->wendx+1, end_x); 101 end_x = obs_pnl -> wstartx - 1; 102 } else { 103 if (obs_pnl->wstartx <= start_x) 104 start_x = obs_pnl -> wendx + 1; 105 if (obs_pnl->wendx >= end_x) 106 end_x = obs_pnl -> wstartx - 1; 107 if (start_x > end_x) 108 return; 109 } 110 } 111 } 112 while ((obs_pnl = next_obs) != 0); 113 } 114 115 /* touchup - Touch lines in obscuring panals as necessary */ 116 static void 117 touchup(PANEL *panel) 118 { 119 int screen_y, i; 120 121 /* 122 * for each line in the window which has been touched, 123 * touch lines in panals above it. 124 */ 125 126 screen_y = panel->wendy; 127 128 for (i = panel->wendy - panel->wstarty; i >= 0; screen_y--, i--) { 129 if (is_linetouched(panel -> win, i) == TRUE) 130 touch_top(panel, screen_y, panel->obscured->next, 131 panel->wstartx, panel->wendx); 132 } 133 } 134 135 /* 136 * std_touchup 137 * Touch lines in obscuring panals as necessary. This routine is 138 * almost exactly like touchup, except that the "panel" is stdscr, 139 * and the obscured list is the list of panels. 140 */ 141 static void 142 std_touchup(void) 143 { 144 int screen_y; 145 146 /* 147 * for each line in stdscr which has been touched, 148 * touch lines in panals above it. 149 */ 150 151 for (screen_y = LINES - 1; screen_y >= 0; screen_y--) { 152 if (is_linetouched(stdscr, screen_y) == TRUE) 153 std_touch_top(screen_y, _Top_panel, 0, COLS - 1); 154 } 155 } 156 157 /* update_panels - Refresh the pile of panels */ 158 void 159 update_panels(void) 160 { 161 PANEL *panel; 162 163 /* 164 * if stdscr has been touched, touch the visible lines 165 * in each panel. 166 */ 167 168 if (is_wintouched(stdscr)) { 169 if (_Bottom_panel) 170 std_touchup(); 171 172 (void) wnoutrefresh(stdscr); 173 } 174 175 /* 176 * Refresh panals starting at the bottom of the pile. 177 * If a line in a window has been touched, touch all 178 * corresponding lines in the obscuring windows. 179 */ 180 181 for (panel = _Bottom_panel; panel; panel = panel -> above) { 182 if (is_wintouched(panel -> win)) { 183 if (panel -> obscured) 184 touchup(panel); 185 (void) wnoutrefresh(panel -> win); 186 } 187 } 188 } 189