~ubuntu-branches/debian/sid/ncurses/sid-200908151543

« back to all changes in this revision

Viewing changes to c++/cursesw.cc

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2008-12-14 21:06:00 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20081214210600-2rdjwvpplgvh3zeb
Tags: 5.7+20081213-1
MergingĀ upstreamĀ versionĀ 5.7+20081213.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
// * this is for making emacs happy: -*-Mode: C++;-*-
 
2
/****************************************************************************
 
3
 * Copyright (c) 2007,2008 Free Software Foundation, Inc.                   *
 
4
 *                                                                          *
 
5
 * Permission is hereby granted, free of charge, to any person obtaining a  *
 
6
 * copy of this software and associated documentation files (the            *
 
7
 * "Software"), to deal in the Software without restriction, including      *
 
8
 * without limitation the rights to use, copy, modify, merge, publish,      *
 
9
 * distribute, distribute with modifications, sublicense, and/or sell       *
 
10
 * copies of the Software, and to permit persons to whom the Software is    *
 
11
 * furnished to do so, subject to the following conditions:                 *
 
12
 *                                                                          *
 
13
 * The above copyright notice and this permission notice shall be included  *
 
14
 * in all copies or substantial portions of the Software.                   *
 
15
 *                                                                          *
 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
 
17
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
 
18
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
 
19
 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
 
20
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
 
21
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
 
22
 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
 
23
 *                                                                          *
 
24
 * Except as contained in this notice, the name(s) of the above copyright   *
 
25
 * holders shall not be used in advertising or otherwise to promote the     *
 
26
 * sale, use or other dealings in this Software without prior written       *
 
27
 * authorization.                                                           *
 
28
 ****************************************************************************/
2
29
 
3
30
/*
4
 
  Copyright (C) 1989 Free Software Foundation
5
 
  written by Eric Newton (newton@rocky.oswego.edu)
6
 
 
7
 
  This file is part of the GNU C++ Library.  This library is free
8
 
  software; you can redistribute it and/or modify it under the terms of
9
 
  the GNU Library General Public License as published by the Free
10
 
  Software Foundation; either version 2 of the License, or (at your
11
 
  option) any later version.  This library is distributed in the hope
12
 
  that it will be useful, but WITHOUT ANY WARRANTY; without even the
13
 
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14
 
  PURPOSE.  See the GNU Library General Public License for more details.
15
 
  You should have received a copy of the GNU Library General Public
16
 
  License along with this library; if not, write to the Free Software
17
 
  Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18
 
 
19
 
  modified by Ulrich Drepper  (drepper@karlsruhe.gmd.de)
20
 
          and Anatoly Ivasyuk (anatoly@nick.csh.rit.edu)
21
 
 
22
 
  modified by Juergen Pfeifer
23
 
  and Thomas Dickey (noting that more than 70% of this file has been changed)
24
 
*/
 
31
 * Authors:
 
32
 *      Thomas E. Dickey
 
33
 *      Juergen Pfeifer
 
34
 *
 
35
 * The NCursesWindow class was originally based on a file written by
 
36
 * Eric Newton, later modified by Ulrich Drepper and Anatoly Ivasyuk.
 
37
 * However, aside from the compatible interface definition, no trace
 
38
 * of the original code remains in this version: it consists only of
 
39
 * changes introduced since 1995.
 
40
 */
25
41
 
26
42
#include "internal.h"
27
43
#include "cursesw.h"
28
44
 
29
 
MODULE_ID("$Id: cursesw.cc,v 1.32 2005/08/13 18:12:17 tom Exp $")
 
45
MODULE_ID("$Id: cursesw.cc,v 1.50 2008/11/23 00:17:31 juergen Exp $")
30
46
 
31
47
#define COLORS_NEED_INITIALIZATION  -1
32
48
#define COLORS_NOT_INITIALIZED       0
33
49
#define COLORS_MONOCHROME            1
34
50
#define COLORS_ARE_REALLY_THERE      2
35
51
 
 
52
#define HaveColors() (colorInitialized == COLORS_ARE_REALLY_THERE)
 
53
 
36
54
// declare static variables for the class
37
55
long NCursesWindow::count = 0L;
38
56
bool NCursesWindow::b_initialized = FALSE;
39
57
 
40
 
/*
41
 
 * The ncurses library has a fallback for vsscanf(), which may work...
42
 
 */
43
 
#if !(USE_STRSTREAM_VSCAN || USE_STRSTREAM_VSCAN_CAST)
44
 
#  undef  USE_STDIO_VSCAN
45
 
#  define USE_STDIO_VSCAN 1
46
 
#endif
47
 
 
48
 
#if defined(__GNUG__)
49
 
#  ifndef _IO_va_list
50
 
#    define _IO_va_list char *
51
 
#  endif
52
 
#endif
53
 
 
54
58
int
55
59
NCursesWindow::scanw(const char* fmt, ...)
56
60
{
57
61
    int result = ERR;
58
 
    char buf[BUFSIZ];
59
 
 
60
 
    if (::wgetnstr(w, buf, sizeof(buf)) != ERR) {
 
62
 
 
63
    va_list args;
 
64
    va_start(args, fmt);
 
65
    result = ::vw_scanw (w, const_cast<NCURSES_CONST char *>(fmt), args);
 
66
    va_end(args);
 
67
 
 
68
    return result;
 
69
}
 
70
 
 
71
 
 
72
int
 
73
NCursesWindow::scanw(int y, int x, const char* fmt, ...)
 
74
{
 
75
    int result = ERR;
 
76
 
 
77
    if (::wmove(w, y, x) != ERR) {
61
78
        va_list args;
62
79
        va_start(args, fmt);
63
 
#if USE_STDIO_VSCAN
64
 
        if (::vsscanf(buf, fmt, args) != -1)
65
 
            result = OK;
66
 
#elif USE_STRSTREAM_VSCAN       /* powerpc, os390 */
67
 
        strstreambuf ss(buf, sizeof(buf));
68
 
        if (ss.vscan(fmt, args) != -1)
69
 
            result = OK;
70
 
#elif USE_STRSTREAM_VSCAN_CAST  /* pre-gcc 3.0 */
71
 
        strstreambuf ss(buf, sizeof(buf));
72
 
        if (ss.vscan(fmt, (_IO_va_list)args) != -1)
73
 
            result = OK;
74
 
#endif
 
80
        result = ::vw_scanw (w, const_cast<NCURSES_CONST char *>(fmt), args);
75
81
        va_end(args);
76
82
    }
77
83
    return result;
79
85
 
80
86
 
81
87
int
82
 
NCursesWindow::scanw(int y, int x, const char* fmt, ...)
83
 
{
84
 
    int result = ERR;
85
 
    char buf[BUFSIZ];
 
88
NCursesWindow::scanw(const char* fmt, va_list args)
 
89
{
 
90
    int result = ERR;
 
91
 
 
92
    result = ::vw_scanw (w, const_cast<NCURSES_CONST char *>(fmt), args);
 
93
 
 
94
    return result;
 
95
}
 
96
 
 
97
 
 
98
int
 
99
NCursesWindow::scanw(int y, int x, const char* fmt, va_list args)
 
100
{
 
101
    int result = ERR;
86
102
 
87
103
    if (::wmove(w, y, x) != ERR) {
88
 
        if (::wgetnstr(w, buf, sizeof(buf)) != ERR) {
89
 
            va_list args;
90
 
            va_start(args, fmt);
91
 
#if USE_STDIO_VSCAN
92
 
            if (::vsscanf(buf, fmt, args) != -1)
93
 
                result = OK;
94
 
#elif USE_STRSTREAM_VSCAN       /* powerpc, os390 */
95
 
            strstreambuf ss(buf, sizeof(buf));
96
 
            if (ss.vscan(fmt, args) != -1)
97
 
                result = OK;
98
 
#elif USE_STRSTREAM_VSCAN_CAST  /* pre-gcc 3.0 */
99
 
            strstreambuf ss(buf, sizeof(buf));
100
 
            if (ss.vscan(fmt, (_IO_va_list)args) != -1)
101
 
                result = OK;
102
 
#endif
103
 
            va_end(args);
104
 
        }
 
104
        result = ::vw_scanw (w, const_cast<NCURSES_CONST char *>(fmt), args);
105
105
    }
106
106
    return result;
107
107
}
112
112
{
113
113
    va_list args;
114
114
    va_start(args, fmt);
115
 
    char buf[BUFSIZ];
116
 
    ::vsprintf(buf, fmt, args);
 
115
    int result = ::vw_printw(w, fmt, args);
117
116
    va_end(args);
118
 
    return waddstr(w, buf);
 
117
    return result;
119
118
}
120
119
 
121
120
 
126
125
    va_start(args, fmt);
127
126
    int result = ::wmove(w, y, x);
128
127
    if (result == OK) {
129
 
        char buf[BUFSIZ];
130
 
        ::vsprintf(buf, fmt, args);
131
 
        result = waddstr(w, buf);
 
128
        result = ::vw_printw(w, fmt, args);
132
129
    }
133
130
    va_end(args);
134
131
    return result;
135
132
}
136
133
 
137
134
 
 
135
int
 
136
NCursesWindow::printw(const char * fmt, va_list args)
 
137
{
 
138
    int result = ::vw_printw(w, fmt, args);
 
139
    return result;
 
140
}
 
141
 
 
142
 
 
143
int
 
144
NCursesWindow::printw(int y, int x, const char * fmt, va_list args)
 
145
{
 
146
    int result = ::wmove(w, y, x);
 
147
    if (result == OK) {
 
148
        result = ::vw_printw(w, fmt, args);
 
149
    }
 
150
    return result;
 
151
}
 
152
 
 
153
 
138
154
void
139
 
NCursesWindow::init(void)
 
155
NCursesWindow::set_keyboard(void)
140
156
{
141
 
    leaveok(0);
142
 
    keypad(1);
143
 
    meta(1);
 
157
    keypad(TRUE);
 
158
    meta(TRUE);
144
159
}
145
160
 
146
161
void
152
167
void
153
168
NCursesWindow::initialize()
154
169
{
155
 
  if (!b_initialized) {
156
 
    ::initscr();
157
 
    b_initialized = TRUE;
158
 
    if (colorInitialized==COLORS_NEED_INITIALIZATION) {
159
 
      colorInitialized=COLORS_NOT_INITIALIZED;
160
 
      useColors();
 
170
    if (!b_initialized) {
 
171
        ::initscr();
 
172
        b_initialized = TRUE;
 
173
        if (colorInitialized == COLORS_NEED_INITIALIZATION) {
 
174
            colorInitialized = COLORS_NOT_INITIALIZED;
 
175
            useColors();
 
176
        }
 
177
        ::noecho();
 
178
        ::cbreak();
161
179
    }
162
 
    ::noecho();
163
 
    ::cbreak();
164
 
  }
 
180
}
 
181
 
 
182
void
 
183
NCursesWindow::constructing()
 
184
{
 
185
    initialize();
 
186
    ++count;
165
187
}
166
188
 
167
189
NCursesWindow::NCursesWindow()
168
 
  : w(0), alloced(0), par(0), subwins(0), sib(0)
 
190
  : w(0), alloced(FALSE), par(0), subwins(0), sib(0)
169
191
{
170
 
  initialize();
 
192
    constructing();
171
193
 
172
 
  w = static_cast<WINDOW *>(0);
173
 
  init();
174
 
  alloced = FALSE;
175
 
  subwins = par = sib = 0;
176
 
  count++;
 
194
    w = static_cast<WINDOW *>(0);
 
195
    set_keyboard();
177
196
}
178
197
 
179
198
NCursesWindow::NCursesWindow(int nlines, int ncols, int begin_y, int begin_x)
180
 
  : w(0), alloced(0), par(0), subwins(0), sib(0)
 
199
  : w(0), alloced(TRUE), par(0), subwins(0), sib(0)
181
200
{
182
 
    initialize();
 
201
    constructing();
183
202
 
184
203
    w = ::newwin(nlines, ncols, begin_y, begin_x);
185
204
    if (w == 0) {
186
205
        err_handler("Cannot construct window");
187
206
    }
188
 
    init();
189
 
 
190
 
    alloced = TRUE;
191
 
    subwins = par = sib = 0;
192
 
    count++;
 
207
    set_keyboard();
193
208
}
194
209
 
195
 
NCursesWindow::NCursesWindow(WINDOW* &window)
196
 
  : w(0), alloced(0), par(0), subwins(0), sib(0)
 
210
NCursesWindow::NCursesWindow(WINDOW* window)
 
211
  : w(0), alloced(FALSE), par(0), subwins(0), sib(0)
197
212
{
198
 
    initialize();
 
213
    constructing();
199
214
 
200
 
    w = window;
201
 
    init();
202
 
    alloced = FALSE;
203
 
    subwins = par = sib = 0;
204
 
    count++;
 
215
    // We used to use a reference on the "window" parameter, but we cannot do
 
216
    // that with an opaque pointer (see NCURSES_OPAQUE).  If the parameter was
 
217
    // "::stdscr", that is first set via the "constructing() call, and is null
 
218
    // up to that point.  So we allow a null pointer here as meaning the "same"
 
219
    // as "::stdscr".
 
220
    w = window ? window : ::stdscr;
 
221
    set_keyboard();
205
222
}
206
223
 
207
 
NCursesWindow::NCursesWindow(NCursesWindow& win, int l, int c,
 
224
NCursesWindow::NCursesWindow(NCursesWindow& win, int ny, int nx,
208
225
                             int begin_y, int begin_x, char absrel)
209
 
  : w(0), alloced(0), par(0), subwins(0), sib(0)
 
226
  : w(0), alloced(TRUE), par(0), subwins(0), sib(0)
210
227
{
211
 
    initialize();
212
 
    if (absrel == 'a') { // absolute origin
 
228
    constructing();
 
229
    if (absrel == 'a') {        // absolute origin
213
230
        begin_y -= win.begy();
214
231
        begin_x -= win.begx();
215
232
    }
216
233
 
217
 
    // Even though we treat subwindows as a tree, the standard curses
218
 
    // library needs the `subwin' call to link to the parent in
219
 
    // order to correctly perform refreshes, etc.
220
 
    // Friendly enough, this also works for pads.
221
 
    w = ::derwin(win.w, l, c, begin_y, begin_x);
 
234
    // Link this window into its parent's list of subwindows.
 
235
    // We use derwin(), since this also works for pads.
 
236
    w = ::derwin(win.w, ny, nx, begin_y, begin_x);
222
237
    if (w == 0) {
223
238
        err_handler("Cannot construct subwindow");
224
239
    }
226
241
    par = &win;
227
242
    sib = win.subwins;
228
243
    win.subwins = this;
229
 
    subwins = 0;
230
 
    alloced = TRUE;
231
 
    count++;
232
244
}
233
245
 
234
246
NCursesWindow::NCursesWindow(NCursesWindow& win,
235
247
                                bool do_box NCURSES_PARAM_INIT(TRUE))
236
 
  : w(0), alloced(0), par(0), subwins(0), sib(0)
 
248
  : w(0), alloced(TRUE), par(0), subwins(0), sib(0)
237
249
{
238
 
  initialize();
239
 
  int myHeight = win.height();
240
 
  int myWidth  = win.width();
241
 
  w = :: derwin(win.w, myHeight - 2, myWidth - 2, 1, 1);
242
 
  if (w == 0) {
243
 
    err_handler("Cannot construct subwindow");
244
 
  }
245
 
 
246
 
  par = &win;
247
 
  sib = win.subwins;
248
 
  win.subwins = this;
249
 
  subwins = 0;
250
 
  alloced = TRUE;
251
 
  count++;
252
 
 
253
 
  if (do_box) {
254
 
    win.box();
255
 
    win.touchwin();
256
 
  }
 
250
    constructing();
 
251
    int myHeight = win.height();
 
252
    int myWidth  = win.width();
 
253
    w = :: derwin(win.w, myHeight - 2, myWidth - 2, 1, 1);
 
254
    if (w == 0) {
 
255
        err_handler("Cannot construct subwindow");
 
256
    }
 
257
 
 
258
    par = &win;
 
259
    sib = win.subwins;
 
260
    win.subwins = this;
 
261
    subwins = 0;
 
262
 
 
263
    if (do_box) {
 
264
        win.box();
 
265
        win.touchwin();
 
266
    }
257
267
}
258
268
 
259
269
NCursesWindow NCursesWindow::Clone()
260
270
{
261
 
  WINDOW *d = ::dupwin(w);
262
 
  NCursesWindow W(d);
263
 
  W.subwins = subwins;
264
 
  W.sib = sib;
265
 
  W.par = par;
266
 
  W.alloced = alloced;
267
 
  return W;
 
271
    WINDOW *d = ::dupwin(w);
 
272
    NCursesWindow W(d);
 
273
    W.subwins = subwins;
 
274
    W.sib = sib;
 
275
    W.par = par;
 
276
    W.alloced = alloced;
 
277
    return W;
268
278
}
269
279
 
270
280
typedef int (*RIPOFFINIT)(NCursesWindow&);
273
283
static RIPOFFINIT* prip = R_INIT;
274
284
 
275
285
NCursesWindow::NCursesWindow(WINDOW *win, int ncols)
276
 
  : w(0), alloced(0), par(0), subwins(0), sib(0)
 
286
  : w(0), alloced(FALSE), par(0), subwins(0), sib(0)
277
287
{
278
 
  initialize();
279
 
  w = win;
280
 
  assert((w->_maxx+1)==ncols);
281
 
  alloced = FALSE;
282
 
  subwins = par = sib = 0;
 
288
    initialize();
 
289
    w = win;
283
290
}
284
291
 
285
292
int _nc_xx_ripoff_init(WINDOW *w, int ncols)
286
293
{
287
 
  int res = ERR;
 
294
    int res = ERR;
288
295
 
289
 
  RIPOFFINIT init = *prip++;
290
 
  if (init) {
291
 
    NCursesWindow* W = new NCursesWindow(w,ncols);
292
 
    res = init(*W);
293
 
  }
294
 
  return res;
 
296
    RIPOFFINIT init = *prip++;
 
297
    if (init) {
 
298
        NCursesWindow* W = new NCursesWindow(w,ncols);
 
299
        res = init(*W);
 
300
    }
 
301
    return res;
295
302
}
296
303
 
297
304
int NCursesWindow::ripoffline(int ripoff_lines,
298
305
                              int (*init)(NCursesWindow& win))
299
306
{
300
 
  int code = ::_nc_ripoffline(ripoff_lines,_nc_xx_ripoff_init);
301
 
  if (code==OK && init && ripoff_lines) {
302
 
    R_INIT[r_init_idx++] = init;
303
 
  }
304
 
  return code;
 
307
    int code = ::_nc_ripoffline(ripoff_lines,_nc_xx_ripoff_init);
 
308
    if (code == OK && init && ripoff_lines) {
 
309
        R_INIT[r_init_idx++] = init;
 
310
    }
 
311
    return code;
305
312
}
306
313
 
307
314
bool
308
315
NCursesWindow::isDescendant(NCursesWindow& win)
309
316
{
310
 
  for (NCursesWindow* p = subwins; p != NULL; p = p->sib) {
311
 
    if (p==&win)
312
 
      return TRUE;
313
 
    else {
314
 
      if (p->isDescendant(win))
315
 
        return TRUE;
 
317
    bool result = FALSE;
 
318
 
 
319
    for (NCursesWindow* p = subwins; p != NULL; p = p->sib) {
 
320
        if (p == &win || p->isDescendant(win)) {
 
321
            result = TRUE;
 
322
            break;
 
323
        }
316
324
    }
317
 
  }
318
 
  return FALSE;
 
325
    return result;
319
326
}
320
327
 
321
328
void
322
329
NCursesWindow::kill_subwindows()
323
330
{
324
 
    for (NCursesWindow* p = subwins; p != 0; p = p->sib) {
 
331
    NCursesWindow* p = subwins;
 
332
 
 
333
    subwins = 0;
 
334
    while (p != 0) {
 
335
        NCursesWindow* q = p->sib;
325
336
        p->kill_subwindows();
326
337
        if (p->alloced) {
327
338
            if (p->w != 0)
328
339
                ::delwin(p->w);
329
 
            p->alloced = FALSE;
330
340
        }
331
 
        p->w = 0; // cause a run-time error if anyone attempts to use...
 
341
        delete p;
 
342
        p = q;
332
343
    }
333
344
}
334
345
 
337
348
{
338
349
    kill_subwindows();
339
350
 
340
 
    if (par != 0) {  // Snip us from the parent's list of subwindows.
341
 
        NCursesWindow * win = par->subwins;
342
 
        NCursesWindow * trail = 0;
343
 
        for (;;) {
344
 
            if (win == 0)
345
 
                break;
346
 
            else if (win == this) {
347
 
                if (trail != 0)
348
 
                    trail->sib = win->sib;
349
 
                else
350
 
                    par->subwins = win->sib;
351
 
                break;
352
 
            } else {
353
 
                trail = win;
354
 
                win = win->sib;
 
351
    if (par != 0) {
 
352
        // Remove this window from the parent's list of subwindows.
 
353
        NCursesWindow * next = par->subwins;
 
354
        NCursesWindow * prev = 0;
 
355
        while (next != 0) {
 
356
            if (next == this) {
 
357
                if (prev != 0) {
 
358
                    prev->sib = next->sib;
 
359
                } else {
 
360
                    par->subwins = next->sib;
 
361
                }
 
362
                break;
355
363
            }
 
364
            prev = next;
 
365
            next = next->sib;
356
366
        }
357
367
    }
358
368
 
360
370
        ::delwin(w);
361
371
 
362
372
    if (alloced) {
363
 
      --count;
364
 
      if (count == 0) {
365
 
        ::endwin();
366
 
      }
367
 
      else if (count < 0) { // cannot happen!
368
 
        err_handler("Too many windows destroyed");
369
 
      }
 
373
        --count;
 
374
        if (count == 0) {
 
375
            ::endwin();
 
376
        } else if (count < 0) { // cannot happen!
 
377
            err_handler("Too many windows destroyed");
 
378
        }
370
379
    }
371
380
}
372
381
 
379
388
NCursesWindow::useColors(void)
380
389
{
381
390
    if (colorInitialized == COLORS_NOT_INITIALIZED) {
382
 
      if (b_initialized) {
383
 
        if (::has_colors()) {
384
 
          ::start_color();
385
 
          colorInitialized = COLORS_ARE_REALLY_THERE;
 
391
        if (b_initialized) {
 
392
            if (::has_colors()) {
 
393
                ::start_color();
 
394
                colorInitialized = COLORS_ARE_REALLY_THERE;
 
395
            } else {
 
396
                colorInitialized = COLORS_MONOCHROME;
 
397
            }
 
398
        } else {
 
399
            colorInitialized = COLORS_NEED_INITIALIZATION;
386
400
        }
387
 
        else
388
 
          colorInitialized = COLORS_MONOCHROME;
389
 
      }
390
 
      else
391
 
        colorInitialized = COLORS_NEED_INITIALIZATION;
392
401
    }
393
402
}
394
403
 
395
404
short
 
405
NCursesWindow::getPair() const
 
406
{
 
407
    return static_cast<short>(PAIR_NUMBER(getattrs(w)));
 
408
}
 
409
 
 
410
short
396
411
NCursesWindow::getcolor(int getback) const
397
412
{
398
413
    short fore, back;
399
414
 
400
 
    if (colorInitialized==COLORS_ARE_REALLY_THERE) {
401
 
      if (::pair_content(static_cast<short>(PAIR_NUMBER(w->_attrs)), &fore, &back))
402
 
        err_handler("Can't get color pair");
403
 
    }
404
 
    else {
405
 
      // Monochrome means white on black
406
 
      back = COLOR_BLACK;
407
 
      fore = COLOR_WHITE;
 
415
    if (HaveColors()) {
 
416
        if (::pair_content(getPair(), &fore, &back) == ERR)
 
417
            err_handler("Can't get color pair");
 
418
    } else {
 
419
        // Monochrome means white on black
 
420
        back = COLOR_BLACK;
 
421
        fore = COLOR_WHITE;
408
422
    }
409
423
    return getback ? back : fore;
410
424
}
411
425
 
412
426
int NCursesWindow::NumberOfColors()
413
427
{
414
 
  if (colorInitialized==COLORS_ARE_REALLY_THERE)
415
 
    return COLORS;
416
 
  else
417
 
    return 1; // monochrome (actually there are two ;-)
 
428
    return (HaveColors()) ? COLORS : 1;
418
429
}
419
430
 
420
431
short
421
432
NCursesWindow::getcolor() const
422
433
{
423
 
  if (colorInitialized==COLORS_ARE_REALLY_THERE)
424
 
    return PAIR_NUMBER(w->_attrs);
425
 
  else
426
 
    return 0; // we only have pair zero
 
434
    return (HaveColors()) ? getPair() : 0;
427
435
}
428
436
 
429
437
int
430
438
NCursesWindow::setpalette(short fore, short back, short pair)
431
439
{
432
 
  if (colorInitialized==COLORS_ARE_REALLY_THERE)
433
 
    return ::init_pair(pair, fore, back);
434
 
  else
435
 
    return OK;
 
440
    return (HaveColors()) ? ::init_pair(pair, fore, back) : OK;
436
441
}
437
442
 
438
443
int
439
444
NCursesWindow::setpalette(short fore, short back)
440
445
{
441
 
  if (colorInitialized==COLORS_ARE_REALLY_THERE)
442
 
    return setpalette(fore, back, static_cast<short>(PAIR_NUMBER(w->_attrs)));
443
 
  else
444
 
    return OK;
 
446
    return setpalette(fore, back, getPair());
445
447
}
446
448
 
447
449
 
448
450
int
449
451
NCursesWindow::setcolor(short pair)
450
452
{
451
 
  if (colorInitialized==COLORS_ARE_REALLY_THERE) {
452
 
    if ((pair < 1) || (pair > COLOR_PAIRS))
453
 
      err_handler("Can't set color pair");
 
453
    if (HaveColors()) {
 
454
        if ((pair < 1) || (pair > COLOR_PAIRS))
 
455
            err_handler("Can't set color pair");
454
456
 
455
 
    attroff(A_COLOR);
456
 
    attrset(COLOR_PAIR(pair));
457
 
  }
458
 
  return OK;
 
457
        attroff(A_COLOR);
 
458
        attrset(COLOR_PAIR(pair));
 
459
    }
 
460
    return OK;
459
461
}
460
462
 
461
463
#if HAVE_HAS_KEY
462
464
bool NCursesWindow::has_mouse() const
463
465
{
464
 
  return ((::has_key(KEY_MOUSE) || ::_nc_has_mouse())
465
 
          ? TRUE : FALSE);
 
466
    return ((::has_key(KEY_MOUSE) || ::has_mouse())
 
467
             ? TRUE : FALSE);
466
468
}
467
469
#endif