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