xref: /openbsd/lib/libcurses/base/new_pair.c (revision c7ef0cfc)
1*c7ef0cfcSnicm /****************************************************************************
2*c7ef0cfcSnicm  * Copyright 2018-2020,2021 Thomas E. Dickey                                *
3*c7ef0cfcSnicm  * Copyright 2017 Free Software Foundation, Inc.                            *
4*c7ef0cfcSnicm  *                                                                          *
5*c7ef0cfcSnicm  * Permission is hereby granted, free of charge, to any person obtaining a  *
6*c7ef0cfcSnicm  * copy of this software and associated documentation files (the            *
7*c7ef0cfcSnicm  * "Software"), to deal in the Software without restriction, including      *
8*c7ef0cfcSnicm  * without limitation the rights to use, copy, modify, merge, publish,      *
9*c7ef0cfcSnicm  * distribute, distribute with modifications, sublicense, and/or sell       *
10*c7ef0cfcSnicm  * copies of the Software, and to permit persons to whom the Software is    *
11*c7ef0cfcSnicm  * furnished to do so, subject to the following conditions:                 *
12*c7ef0cfcSnicm  *                                                                          *
13*c7ef0cfcSnicm  * The above copyright notice and this permission notice shall be included  *
14*c7ef0cfcSnicm  * in all copies or substantial portions of the Software.                   *
15*c7ef0cfcSnicm  *                                                                          *
16*c7ef0cfcSnicm  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
17*c7ef0cfcSnicm  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
18*c7ef0cfcSnicm  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
19*c7ef0cfcSnicm  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
20*c7ef0cfcSnicm  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
21*c7ef0cfcSnicm  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
22*c7ef0cfcSnicm  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
23*c7ef0cfcSnicm  *                                                                          *
24*c7ef0cfcSnicm  * Except as contained in this notice, the name(s) of the above copyright   *
25*c7ef0cfcSnicm  * holders shall not be used in advertising or otherwise to promote the     *
26*c7ef0cfcSnicm  * sale, use or other dealings in this Software without prior written       *
27*c7ef0cfcSnicm  * authorization.                                                           *
28*c7ef0cfcSnicm  ****************************************************************************/
29*c7ef0cfcSnicm 
30*c7ef0cfcSnicm /****************************************************************************
31*c7ef0cfcSnicm  *  Author: Thomas E. Dickey                                                *
32*c7ef0cfcSnicm  ****************************************************************************/
33*c7ef0cfcSnicm 
34*c7ef0cfcSnicm /* new_pair.c
35*c7ef0cfcSnicm  *
36*c7ef0cfcSnicm  * New color-pair functions, alloc_pair and free_pair
37*c7ef0cfcSnicm  */
38*c7ef0cfcSnicm 
39*c7ef0cfcSnicm #define NEW_PAIR_INTERNAL 1
40*c7ef0cfcSnicm #include <curses.priv.h>
41*c7ef0cfcSnicm 
42*c7ef0cfcSnicm #ifndef CUR
43*c7ef0cfcSnicm #define CUR SP_TERMTYPE
44*c7ef0cfcSnicm #endif
45*c7ef0cfcSnicm 
46*c7ef0cfcSnicm #ifdef USE_TERM_DRIVER
47*c7ef0cfcSnicm #define MaxColors      InfoOf(SP_PARM).maxcolors
48*c7ef0cfcSnicm #else
49*c7ef0cfcSnicm #define MaxColors      max_colors
50*c7ef0cfcSnicm #endif
51*c7ef0cfcSnicm 
52*c7ef0cfcSnicm #if NCURSES_EXT_COLORS
53*c7ef0cfcSnicm 
54*c7ef0cfcSnicm /* fix redefinition versys tic.h */
55*c7ef0cfcSnicm #undef entry
56*c7ef0cfcSnicm #define entry my_entry
57*c7ef0cfcSnicm #undef ENTRY
58*c7ef0cfcSnicm #define ENTRY my_ENTRY
59*c7ef0cfcSnicm 
60*c7ef0cfcSnicm #include <search.h>
61*c7ef0cfcSnicm 
62*c7ef0cfcSnicm #endif
63*c7ef0cfcSnicm 
64*c7ef0cfcSnicm MODULE_ID("$Id: new_pair.c,v 1.1 2023/10/17 09:52:09 nicm Exp $")
65*c7ef0cfcSnicm 
66*c7ef0cfcSnicm #if NCURSES_EXT_COLORS
67*c7ef0cfcSnicm 
68*c7ef0cfcSnicm #ifdef NEW_PAIR_DEBUG
69*c7ef0cfcSnicm 
70*c7ef0cfcSnicm static int
prev_len(SCREEN * sp,int pair)71*c7ef0cfcSnicm prev_len(SCREEN *sp, int pair)
72*c7ef0cfcSnicm {
73*c7ef0cfcSnicm     int result = 1;
74*c7ef0cfcSnicm     int base = pair;
75*c7ef0cfcSnicm     colorpair_t *list = sp->_color_pairs;
76*c7ef0cfcSnicm     while (list[pair].prev != base) {
77*c7ef0cfcSnicm 	result++;
78*c7ef0cfcSnicm 	pair = list[pair].prev;
79*c7ef0cfcSnicm     }
80*c7ef0cfcSnicm     return result;
81*c7ef0cfcSnicm }
82*c7ef0cfcSnicm 
83*c7ef0cfcSnicm static int
next_len(SCREEN * sp,int pair)84*c7ef0cfcSnicm next_len(SCREEN *sp, int pair)
85*c7ef0cfcSnicm {
86*c7ef0cfcSnicm     int result = 1;
87*c7ef0cfcSnicm     int base = pair;
88*c7ef0cfcSnicm     colorpair_t *list = sp->_color_pairs;
89*c7ef0cfcSnicm     while (list[pair].next != base) {
90*c7ef0cfcSnicm 	result++;
91*c7ef0cfcSnicm 	pair = list[pair].next;
92*c7ef0cfcSnicm     }
93*c7ef0cfcSnicm     return result;
94*c7ef0cfcSnicm }
95*c7ef0cfcSnicm 
96*c7ef0cfcSnicm /*
97*c7ef0cfcSnicm  * Trace the contents of LRU color-pairs.
98*c7ef0cfcSnicm  */
99*c7ef0cfcSnicm static void
dumpit(SCREEN * sp,int pair,const char * tag)100*c7ef0cfcSnicm dumpit(SCREEN *sp, int pair, const char *tag)
101*c7ef0cfcSnicm {
102*c7ef0cfcSnicm     colorpair_t *list = sp->_color_pairs;
103*c7ef0cfcSnicm     char bigbuf[256 * 20];
104*c7ef0cfcSnicm     char *p = bigbuf;
105*c7ef0cfcSnicm     int n;
106*c7ef0cfcSnicm     size_t have = sizeof(bigbuf);
107*c7ef0cfcSnicm 
108*c7ef0cfcSnicm     _nc_STRCPY(p, tag, have);
109*c7ef0cfcSnicm     for (n = 0; n < sp->_pair_alloc; ++n) {
110*c7ef0cfcSnicm 	if (list[n].mode != cpFREE) {
111*c7ef0cfcSnicm 	    p += strlen(p);
112*c7ef0cfcSnicm 	    if ((size_t) (p - bigbuf) + 50 > have)
113*c7ef0cfcSnicm 		break;
114*c7ef0cfcSnicm 	    _nc_SPRINTF(p, _nc_SLIMIT(have - (p - bigbuf))
115*c7ef0cfcSnicm 			" %d%c(%d,%d)",
116*c7ef0cfcSnicm 			n, n == pair ? '@' : ':', list[n].next, list[n].prev);
117*c7ef0cfcSnicm 	}
118*c7ef0cfcSnicm     }
119*c7ef0cfcSnicm     T(("(%d/%d) %ld - %s",
120*c7ef0cfcSnicm        next_len(sp, 0),
121*c7ef0cfcSnicm        prev_len(sp, 0),
122*c7ef0cfcSnicm        strlen(bigbuf), bigbuf));
123*c7ef0cfcSnicm 
124*c7ef0cfcSnicm     if (next_len(sp, 0) != prev_len(sp, 0)) {
125*c7ef0cfcSnicm 	endwin();
126*c7ef0cfcSnicm 	ExitProgram(EXIT_FAILURE);
127*c7ef0cfcSnicm     }
128*c7ef0cfcSnicm }
129*c7ef0cfcSnicm #else
130*c7ef0cfcSnicm #define dumpit(sp, pair, tag)	/* nothing */
131*c7ef0cfcSnicm #endif
132*c7ef0cfcSnicm 
133*c7ef0cfcSnicm static int
compare_data(const void * a,const void * b)134*c7ef0cfcSnicm compare_data(const void *a, const void *b)
135*c7ef0cfcSnicm {
136*c7ef0cfcSnicm     const colorpair_t *p = (const colorpair_t *) a;
137*c7ef0cfcSnicm     const colorpair_t *q = (const colorpair_t *) b;
138*c7ef0cfcSnicm     return ((p->fg == q->fg)
139*c7ef0cfcSnicm 	    ? (p->bg - q->bg)
140*c7ef0cfcSnicm 	    : (p->fg - q->fg));
141*c7ef0cfcSnicm }
142*c7ef0cfcSnicm 
143*c7ef0cfcSnicm static int
_nc_find_color_pair(SCREEN * sp,int fg,int bg)144*c7ef0cfcSnicm _nc_find_color_pair(SCREEN *sp, int fg, int bg)
145*c7ef0cfcSnicm {
146*c7ef0cfcSnicm     colorpair_t find;
147*c7ef0cfcSnicm     int result = -1;
148*c7ef0cfcSnicm 
149*c7ef0cfcSnicm     find.fg = fg;
150*c7ef0cfcSnicm     find.bg = bg;
151*c7ef0cfcSnicm     if (sp != 0) {
152*c7ef0cfcSnicm 	void *pp;
153*c7ef0cfcSnicm 	if ((pp = tfind(&find, &sp->_ordered_pairs, compare_data)) != 0) {
154*c7ef0cfcSnicm 	    colorpair_t *temp = *(colorpair_t **) pp;
155*c7ef0cfcSnicm 	    result = (int) (temp - sp->_color_pairs);
156*c7ef0cfcSnicm 	}
157*c7ef0cfcSnicm     }
158*c7ef0cfcSnicm     return result;
159*c7ef0cfcSnicm }
160*c7ef0cfcSnicm 
161*c7ef0cfcSnicm static void
delink_color_pair(SCREEN * sp,int pair)162*c7ef0cfcSnicm delink_color_pair(SCREEN *sp, int pair)
163*c7ef0cfcSnicm {
164*c7ef0cfcSnicm     colorpair_t *list = sp->_color_pairs;
165*c7ef0cfcSnicm     int prev = list[pair].prev;
166*c7ef0cfcSnicm     int next = list[pair].next;
167*c7ef0cfcSnicm 
168*c7ef0cfcSnicm     /* delink this from its current location */
169*c7ef0cfcSnicm     if (list[prev].next == pair &&
170*c7ef0cfcSnicm 	list[next].prev == pair) {
171*c7ef0cfcSnicm 	list[prev].next = next;
172*c7ef0cfcSnicm 	list[next].prev = prev;
173*c7ef0cfcSnicm 	dumpit(sp, pair, "delinked");
174*c7ef0cfcSnicm     }
175*c7ef0cfcSnicm }
176*c7ef0cfcSnicm 
177*c7ef0cfcSnicm /*
178*c7ef0cfcSnicm  * Discard all nodes in the fast-index.
179*c7ef0cfcSnicm  */
180*c7ef0cfcSnicm NCURSES_EXPORT(void)
_nc_free_ordered_pairs(SCREEN * sp)181*c7ef0cfcSnicm _nc_free_ordered_pairs(SCREEN *sp)
182*c7ef0cfcSnicm {
183*c7ef0cfcSnicm     if (sp && sp->_ordered_pairs && sp->_pair_alloc) {
184*c7ef0cfcSnicm 	int n;
185*c7ef0cfcSnicm 	for (n = 0; n < sp->_pair_alloc; ++n) {
186*c7ef0cfcSnicm 	    tdelete(&sp->_color_pairs[n], &sp->_ordered_pairs, compare_data);
187*c7ef0cfcSnicm 	}
188*c7ef0cfcSnicm     }
189*c7ef0cfcSnicm }
190*c7ef0cfcSnicm 
191*c7ef0cfcSnicm /*
192*c7ef0cfcSnicm  * Use this call to update the fast-index when modifying an entry in the color
193*c7ef0cfcSnicm  * pair table.
194*c7ef0cfcSnicm  */
195*c7ef0cfcSnicm NCURSES_EXPORT(void)
_nc_reset_color_pair(SCREEN * sp,int pair,colorpair_t * next)196*c7ef0cfcSnicm _nc_reset_color_pair(SCREEN *sp, int pair, colorpair_t * next)
197*c7ef0cfcSnicm {
198*c7ef0cfcSnicm     colorpair_t *last;
199*c7ef0cfcSnicm 
200*c7ef0cfcSnicm     if (ValidPair(sp, pair)) {
201*c7ef0cfcSnicm 	bool used;
202*c7ef0cfcSnicm 
203*c7ef0cfcSnicm 	ReservePairs(sp, pair);
204*c7ef0cfcSnicm 	last = &(sp->_color_pairs[pair]);
205*c7ef0cfcSnicm 	delink_color_pair(sp, pair);
206*c7ef0cfcSnicm 	if (last->mode > cpFREE &&
207*c7ef0cfcSnicm 	    (last->fg != next->fg || last->bg != next->bg)) {
208*c7ef0cfcSnicm 	    /* remove the old entry from fast index */
209*c7ef0cfcSnicm 	    tdelete(last, &sp->_ordered_pairs, compare_data);
210*c7ef0cfcSnicm 	    used = FALSE;
211*c7ef0cfcSnicm 	} else {
212*c7ef0cfcSnicm 	    used = (last->mode != cpFREE);
213*c7ef0cfcSnicm 	}
214*c7ef0cfcSnicm 	if (!used) {
215*c7ef0cfcSnicm 	    /* create a new entry in fast index */
216*c7ef0cfcSnicm 	    *last = *next;
217*c7ef0cfcSnicm 	    tsearch(last, &sp->_ordered_pairs, compare_data);
218*c7ef0cfcSnicm 	}
219*c7ef0cfcSnicm     }
220*c7ef0cfcSnicm }
221*c7ef0cfcSnicm 
222*c7ef0cfcSnicm /*
223*c7ef0cfcSnicm  * Use this call to relink the newest pair to the front of the list, keeping
224*c7ef0cfcSnicm  * "0" first.
225*c7ef0cfcSnicm  */
226*c7ef0cfcSnicm NCURSES_EXPORT(void)
_nc_set_color_pair(SCREEN * sp,int pair,int mode)227*c7ef0cfcSnicm _nc_set_color_pair(SCREEN *sp, int pair, int mode)
228*c7ef0cfcSnicm {
229*c7ef0cfcSnicm     if (ValidPair(sp, pair)) {
230*c7ef0cfcSnicm 	colorpair_t *list = sp->_color_pairs;
231*c7ef0cfcSnicm 	dumpit(sp, pair, "SET_PAIR");
232*c7ef0cfcSnicm 	list[0].mode = cpKEEP;
233*c7ef0cfcSnicm 	if (list[pair].mode <= cpFREE)
234*c7ef0cfcSnicm 	    sp->_pairs_used++;
235*c7ef0cfcSnicm 	list[pair].mode = mode;
236*c7ef0cfcSnicm 	if (list[0].next != pair) {
237*c7ef0cfcSnicm 	    /* link it at the front of the list */
238*c7ef0cfcSnicm 	    list[pair].next = list[0].next;
239*c7ef0cfcSnicm 	    list[list[pair].next].prev = pair;
240*c7ef0cfcSnicm 	    list[pair].prev = 0;
241*c7ef0cfcSnicm 	    list[0].next = pair;
242*c7ef0cfcSnicm 	}
243*c7ef0cfcSnicm 	dumpit(sp, pair, "...after");
244*c7ef0cfcSnicm     }
245*c7ef0cfcSnicm }
246*c7ef0cfcSnicm 
247*c7ef0cfcSnicm /*
248*c7ef0cfcSnicm  * If we reallocate the color-pair array, we have to adjust the fast-index.
249*c7ef0cfcSnicm  */
250*c7ef0cfcSnicm NCURSES_EXPORT(void)
_nc_copy_pairs(SCREEN * sp,colorpair_t * target,colorpair_t * source,int length)251*c7ef0cfcSnicm _nc_copy_pairs(SCREEN *sp, colorpair_t * target, colorpair_t * source, int length)
252*c7ef0cfcSnicm {
253*c7ef0cfcSnicm     int n;
254*c7ef0cfcSnicm     for (n = 0; n < length; ++n) {
255*c7ef0cfcSnicm 	void *find = tfind(source + n, &sp->_ordered_pairs, compare_data);
256*c7ef0cfcSnicm 	if (find != 0) {
257*c7ef0cfcSnicm 	    tdelete(source + n, &sp->_ordered_pairs, compare_data);
258*c7ef0cfcSnicm 	    tsearch(target + n, &sp->_ordered_pairs, compare_data);
259*c7ef0cfcSnicm 	}
260*c7ef0cfcSnicm     }
261*c7ef0cfcSnicm }
262*c7ef0cfcSnicm 
263*c7ef0cfcSnicm NCURSES_EXPORT(int)
NCURSES_SP_NAME(alloc_pair)264*c7ef0cfcSnicm NCURSES_SP_NAME(alloc_pair) (NCURSES_SP_DCLx int fg, int bg)
265*c7ef0cfcSnicm {
266*c7ef0cfcSnicm     int pair;
267*c7ef0cfcSnicm 
268*c7ef0cfcSnicm     T((T_CALLED("alloc_pair(%d,%d)"), fg, bg));
269*c7ef0cfcSnicm     if (SP_PARM == 0) {
270*c7ef0cfcSnicm 	pair = -1;
271*c7ef0cfcSnicm     } else if ((pair = _nc_find_color_pair(SP_PARM, fg, bg)) < 0) {
272*c7ef0cfcSnicm 	/*
273*c7ef0cfcSnicm 	 * Check if all of the slots have been used.  If not, find one and
274*c7ef0cfcSnicm 	 * use that.
275*c7ef0cfcSnicm 	 */
276*c7ef0cfcSnicm 	if (SP_PARM->_pairs_used + 1 < SP_PARM->_pair_limit) {
277*c7ef0cfcSnicm 	    bool found = FALSE;
278*c7ef0cfcSnicm 	    int hint = SP_PARM->_recent_pair;
279*c7ef0cfcSnicm 
280*c7ef0cfcSnicm 	    /*
281*c7ef0cfcSnicm 	     * The linear search is done to allow mixing calls to init_pair()
282*c7ef0cfcSnicm 	     * and alloc_pair().  The former can make gaps...
283*c7ef0cfcSnicm 	     */
284*c7ef0cfcSnicm 	    for (pair = hint + 1; pair < SP_PARM->_pair_alloc; pair++) {
285*c7ef0cfcSnicm 		if (SP_PARM->_color_pairs[pair].mode == cpFREE) {
286*c7ef0cfcSnicm 		    T(("found gap %d", pair));
287*c7ef0cfcSnicm 		    found = TRUE;
288*c7ef0cfcSnicm 		    break;
289*c7ef0cfcSnicm 		}
290*c7ef0cfcSnicm 	    }
291*c7ef0cfcSnicm 	    if (!found && (SP_PARM->_pair_alloc < SP_PARM->_pair_limit)) {
292*c7ef0cfcSnicm 		pair = SP_PARM->_pair_alloc;
293*c7ef0cfcSnicm 		ReservePairs(SP_PARM, pair);
294*c7ef0cfcSnicm 		if (SP_PARM->_color_pairs == 0) {
295*c7ef0cfcSnicm 		    pair = -1;
296*c7ef0cfcSnicm 		} else {
297*c7ef0cfcSnicm 		    found = TRUE;
298*c7ef0cfcSnicm 		}
299*c7ef0cfcSnicm 	    }
300*c7ef0cfcSnicm 	    if (!found && SP_PARM->_color_pairs != NULL) {
301*c7ef0cfcSnicm 		for (pair = 1; pair <= hint; pair++) {
302*c7ef0cfcSnicm 		    if (SP_PARM->_color_pairs[pair].mode == cpFREE) {
303*c7ef0cfcSnicm 			T(("found gap %d", pair));
304*c7ef0cfcSnicm 			found = TRUE;
305*c7ef0cfcSnicm 			break;
306*c7ef0cfcSnicm 		    }
307*c7ef0cfcSnicm 		}
308*c7ef0cfcSnicm 	    }
309*c7ef0cfcSnicm 	    if (found) {
310*c7ef0cfcSnicm 		SP_PARM->_recent_pair = pair;
311*c7ef0cfcSnicm 	    } else {
312*c7ef0cfcSnicm 		pair = ERR;
313*c7ef0cfcSnicm 	    }
314*c7ef0cfcSnicm 	} else {
315*c7ef0cfcSnicm 	    /* reuse the oldest one */
316*c7ef0cfcSnicm 	    pair = SP_PARM->_color_pairs[0].prev;
317*c7ef0cfcSnicm 	    T(("reusing %d", pair));
318*c7ef0cfcSnicm 	}
319*c7ef0cfcSnicm 
320*c7ef0cfcSnicm 	if (_nc_init_pair(SP_PARM, pair, fg, bg) == ERR)
321*c7ef0cfcSnicm 	    pair = ERR;
322*c7ef0cfcSnicm     }
323*c7ef0cfcSnicm     returnCode(pair);
324*c7ef0cfcSnicm }
325*c7ef0cfcSnicm 
326*c7ef0cfcSnicm NCURSES_EXPORT(int)
NCURSES_SP_NAME(find_pair)327*c7ef0cfcSnicm NCURSES_SP_NAME(find_pair) (NCURSES_SP_DCLx int fg, int bg)
328*c7ef0cfcSnicm {
329*c7ef0cfcSnicm     int pair;
330*c7ef0cfcSnicm 
331*c7ef0cfcSnicm     T((T_CALLED("find_pair(%d,%d)"), fg, bg));
332*c7ef0cfcSnicm     pair = _nc_find_color_pair(SP_PARM, fg, bg);
333*c7ef0cfcSnicm     returnCode(pair);
334*c7ef0cfcSnicm }
335*c7ef0cfcSnicm 
336*c7ef0cfcSnicm NCURSES_EXPORT(int)
NCURSES_SP_NAME(free_pair)337*c7ef0cfcSnicm NCURSES_SP_NAME(free_pair) (NCURSES_SP_DCLx int pair)
338*c7ef0cfcSnicm {
339*c7ef0cfcSnicm     int result = ERR;
340*c7ef0cfcSnicm     T((T_CALLED("free_pair(%d)"), pair));
341*c7ef0cfcSnicm     if (ValidPair(SP_PARM, pair) && pair < SP_PARM->_pair_alloc) {
342*c7ef0cfcSnicm 	colorpair_t *cp = &(SP_PARM->_color_pairs[pair]);
343*c7ef0cfcSnicm 	if (pair != 0) {
344*c7ef0cfcSnicm 	    _nc_change_pair(SP_PARM, pair);
345*c7ef0cfcSnicm 	    delink_color_pair(SP_PARM, pair);
346*c7ef0cfcSnicm 	    tdelete(cp, &SP_PARM->_ordered_pairs, compare_data);
347*c7ef0cfcSnicm 	    cp->mode = cpFREE;
348*c7ef0cfcSnicm 	    result = OK;
349*c7ef0cfcSnicm 	    SP_PARM->_pairs_used--;
350*c7ef0cfcSnicm 	}
351*c7ef0cfcSnicm     }
352*c7ef0cfcSnicm     returnCode(result);
353*c7ef0cfcSnicm }
354*c7ef0cfcSnicm 
355*c7ef0cfcSnicm #if NCURSES_SP_FUNCS
356*c7ef0cfcSnicm NCURSES_EXPORT(int)
alloc_pair(int f,int b)357*c7ef0cfcSnicm alloc_pair(int f, int b)
358*c7ef0cfcSnicm {
359*c7ef0cfcSnicm     return NCURSES_SP_NAME(alloc_pair) (CURRENT_SCREEN, f, b);
360*c7ef0cfcSnicm }
361*c7ef0cfcSnicm 
362*c7ef0cfcSnicm NCURSES_EXPORT(int)
find_pair(int f,int b)363*c7ef0cfcSnicm find_pair(int f, int b)
364*c7ef0cfcSnicm {
365*c7ef0cfcSnicm     return NCURSES_SP_NAME(find_pair) (CURRENT_SCREEN, f, b);
366*c7ef0cfcSnicm }
367*c7ef0cfcSnicm 
368*c7ef0cfcSnicm NCURSES_EXPORT(int)
free_pair(int pair)369*c7ef0cfcSnicm free_pair(int pair)
370*c7ef0cfcSnicm {
371*c7ef0cfcSnicm     return NCURSES_SP_NAME(free_pair) (CURRENT_SCREEN, pair);
372*c7ef0cfcSnicm }
373*c7ef0cfcSnicm #endif
374*c7ef0cfcSnicm 
375*c7ef0cfcSnicm #if NO_LEAKS
376*c7ef0cfcSnicm NCURSES_EXPORT(void)
_nc_new_pair_leaks(SCREEN * sp)377*c7ef0cfcSnicm _nc_new_pair_leaks(SCREEN *sp)
378*c7ef0cfcSnicm {
379*c7ef0cfcSnicm     if (sp->_color_pairs) {
380*c7ef0cfcSnicm 	while (sp->_color_pairs[0].next) {
381*c7ef0cfcSnicm 	    free_pair(sp->_color_pairs[0].next);
382*c7ef0cfcSnicm 	}
383*c7ef0cfcSnicm     }
384*c7ef0cfcSnicm }
385*c7ef0cfcSnicm #endif
386*c7ef0cfcSnicm 
387*c7ef0cfcSnicm #else
388*c7ef0cfcSnicm void _nc_new_pair(void);
389*c7ef0cfcSnicm void
390*c7ef0cfcSnicm _nc_new_pair(void)
391*c7ef0cfcSnicm {
392*c7ef0cfcSnicm }
393*c7ef0cfcSnicm #endif /* NCURSES_EXT_COLORS */
394