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