1 1.7 msaitoh /* $NetBSD: ripoffline.c,v 1.7 2022/01/01 08:34:35 msaitoh Exp $ */ 2 1.1 roy 3 1.1 roy /*- 4 1.1 roy * Copyright (c) 2017 The NetBSD Foundation, Inc. 5 1.1 roy * All rights reserved. 6 1.1 roy * 7 1.1 roy * This code is derived from software contributed to The NetBSD Foundation 8 1.1 roy * by Roy Marples. 9 1.1 roy * 10 1.1 roy * Redistribution and use in source and binary forms, with or without 11 1.1 roy * modification, are permitted provided that the following conditions 12 1.1 roy * are met: 13 1.1 roy * 1. Redistributions of source code must retain the above copyright 14 1.1 roy * notice, this list of conditions and the following disclaimer. 15 1.1 roy * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 roy * notice, this list of conditions and the following disclaimer in the 17 1.1 roy * documentation and/or other materials provided with the distribution. 18 1.1 roy * 19 1.1 roy * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 roy * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 roy * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 roy * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 roy * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 roy * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 roy * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 roy * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 roy * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 roy * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 roy * POSSIBILITY OF SUCH DAMAGE. 30 1.1 roy */ 31 1.1 roy 32 1.1 roy #include <sys/cdefs.h> 33 1.1 roy #ifndef lint 34 1.7 msaitoh __RCSID("$NetBSD: ripoffline.c,v 1.7 2022/01/01 08:34:35 msaitoh Exp $"); 35 1.1 roy #endif /* not lint */ 36 1.1 roy 37 1.1 roy #include "curses.h" 38 1.1 roy #include "curses_private.h" 39 1.1 roy 40 1.1 roy /* List of ripoffline calls */ 41 1.1 roy static struct ripoff { 42 1.1 roy int nlines; 43 1.1 roy int (*init)(WINDOW *, int); 44 1.1 roy } ripoffs[MAX_RIPS]; 45 1.1 roy static int nrips; 46 1.1 roy 47 1.1 roy /* 48 1.1 roy * ripoffline -- 49 1.1 roy * Ripoff a line from the top of bottom of stdscr. 50 1.1 roy * Must be called before initscr or newterm. 51 1.1 roy */ 52 1.1 roy int 53 1.1 roy ripoffline(int line, int (*init)(WINDOW *, int)) 54 1.1 roy { 55 1.1 roy 56 1.4 roy __CTRACE(__CTRACE_WINDOW, "ripoffline: %d\n", line); 57 1.1 roy 58 1.1 roy if (nrips >= MAX_RIPS || init == NULL) 59 1.1 roy return ERR; /* This makes sense, but not standards compliant. */ 60 1.1 roy if (line == 0) 61 1.1 roy return OK; 62 1.1 roy ripoffs[nrips].nlines = line < 0 ? -1 : 1; 63 1.1 roy ripoffs[nrips++].init = init; 64 1.1 roy return OK; 65 1.1 roy } 66 1.1 roy 67 1.1 roy /* 68 1.1 roy * __rippedlines -- 69 1.1 roy * Returns the number of ripped lines from the screen. 70 1.1 roy */ 71 1.1 roy int 72 1.4 roy __rippedlines(const SCREEN *screen, int line) 73 1.1 roy { 74 1.1 roy const struct __ripoff *rip; 75 1.1 roy int i, n; 76 1.1 roy 77 1.1 roy n = 0; 78 1.1 roy for (i = 0, rip = screen->ripped; i < screen->nripped; i++, rip++) { 79 1.4 roy if (line < 1 && rip->nlines < 0) 80 1.1 roy n += -rip->nlines; 81 1.4 roy else if (line > 0 && rip->nlines > 0) 82 1.1 roy n += rip->nlines; 83 1.1 roy } 84 1.1 roy return n; 85 1.1 roy } 86 1.1 roy 87 1.1 roy /* 88 1.1 roy * __ripoffscreen -- 89 1.1 roy * Rips lines from the screen by creating a WINDOW per ripoffline call. 90 1.1 roy * Although the POSIX API only allows for one line WINDOWS to be created, 91 1.7 msaitoh * this implementation allows for N lines if needed. 92 1.1 roy */ 93 1.1 roy int 94 1.4 roy __ripoffscreen(SCREEN *screen) 95 1.1 roy { 96 1.4 roy int i, nlines, rbot, rtop; 97 1.1 roy const struct ripoff *srip; 98 1.1 roy struct __ripoff *rip; 99 1.1 roy WINDOW *w; 100 1.1 roy 101 1.1 roy rip = screen->ripped; 102 1.4 roy rbot = LINES; 103 1.4 roy rtop = 0; 104 1.1 roy for (i = 0, srip = ripoffs; i < nrips; i++, srip++) { 105 1.3 roy if (srip->nlines == 0) 106 1.3 roy continue; 107 1.1 roy nlines = srip->nlines < 0 ? -srip->nlines : srip->nlines; 108 1.1 roy w = __newwin(screen, nlines, 0, 109 1.4 roy srip->nlines < 0 ? rbot - nlines : rtop, 110 1.4 roy 0, FALSE, FALSE); 111 1.1 roy if (w != NULL) { 112 1.1 roy rip->win = w; 113 1.1 roy rip->nlines = srip->nlines; 114 1.1 roy rip++; 115 1.1 roy screen->nripped++; 116 1.4 roy if (srip->nlines > 0) 117 1.4 roy rtop += nlines; 118 1.4 roy else 119 1.4 roy rbot -= nlines; 120 1.1 roy } 121 1.1 roy if (srip->init(w, COLS) == ERR) 122 1.1 roy return ERR; 123 1.1 roy #ifdef DEBUG 124 1.1 roy if (w != NULL) 125 1.4 roy __CTRACE(__CTRACE_WINDOW, 126 1.4 roy "newterm: %p ripped %d line(s) from the %s\n", 127 1.4 roy w, nlines, srip->nlines < 0 ? "bottom" : "top"); 128 1.1 roy #endif 129 1.1 roy } 130 1.1 roy nrips = 0; /* Reset the stack. */ 131 1.1 roy return OK; 132 1.1 roy } 133 1.1 roy 134 1.1 roy /* 135 1.1 roy * __ripoffresize -- 136 1.1 roy * Called from resizeterm to ensure the ripped off lines are correctly 137 1.1 roy * placed and refreshed. 138 1.1 roy */ 139 1.5 roy int 140 1.1 roy __ripoffresize(SCREEN *screen) 141 1.1 roy { 142 1.5 roy int rbot = screen->LINES, i, nlines, ret = OK; 143 1.1 roy struct __ripoff *rip; 144 1.1 roy 145 1.2 roy for (i = 0, rip = screen->ripped; i < screen->nripped; i++, rip++) { 146 1.5 roy if (rip->nlines == 0) 147 1.5 roy continue; 148 1.5 roy nlines = rip->nlines < 0 ? -rip->nlines : rip->nlines; 149 1.5 roy if (wresize(rip->win, nlines, screen->COLS) == ERR) 150 1.5 roy ret = ERR; 151 1.5 roy if (rip->nlines < 0) { 152 1.1 roy /* Reposition the lower windows. */ 153 1.5 roy if (mvwin(rip->win, rbot + rip->nlines, 0) == ERR) 154 1.5 roy ret = ERR; 155 1.5 roy else 156 1.5 roy rbot += rip->nlines; 157 1.1 roy } 158 1.1 roy } 159 1.5 roy 160 1.5 roy return ret; 161 1.1 roy } 162 1.3 roy 163 1.3 roy /* 164 1.4 roy * __ripofftouch -- 165 1.4 roy * Displays the ripped off lines from initscr. 166 1.4 roy */ 167 1.4 roy void 168 1.4 roy __ripofftouch(SCREEN *screen) 169 1.4 roy { 170 1.4 roy int i; 171 1.4 roy struct __ripoff *rip; 172 1.4 roy 173 1.4 roy for (i = 0, rip = screen->ripped; i < screen->nripped; i++, rip++) { 174 1.4 roy touchwin(rip->win); 175 1.4 roy wnoutrefresh(rip->win); 176 1.4 roy } 177 1.4 roy } 178 1.4 roy 179 1.4 roy /* 180 1.3 roy * __unripoffline -- 181 1.3 roy * Used by __slk_init to remove the ripoffline reservation it made 182 1.3 roy * because the terminal natively supports soft label keys. 183 1.3 roy */ 184 1.3 roy int 185 1.3 roy __unripoffline(int (*init)(WINDOW *, int)) 186 1.3 roy { 187 1.3 roy struct ripoff *rip; 188 1.3 roy int i, unripped = 0; 189 1.3 roy 190 1.3 roy for (i = 0, rip = ripoffs; i < nrips; i++, rip++) { 191 1.3 roy if (rip->init == init) { 192 1.3 roy rip->nlines = 0; 193 1.3 roy unripped++; 194 1.3 roy } 195 1.3 roy } 196 1.3 roy return unripped; 197 1.3 roy } 198