bpo-36982: Add support for extended color functions in ncurses 6.1 (G… · python/cpython@da4e09f

@@ -134,6 +134,31 @@ typedef chtype attr_t; /* No attr_t type is available */

134134

#define STRICT_SYSV_CURSES

135135

#endif

136136137+

#if defined(NCURSES_EXT_COLORS) && defined(NCURSES_EXT_FUNCS)

138+

#define _NCURSES_EXTENDED_COLOR_FUNCS 1

139+

#else

140+

#define _NCURSES_EXTENDED_COLOR_FUNCS 0

141+

#endif /* defined(NCURSES_EXT_COLORS) && defined(NCURSES_EXT_FUNCS) */

142+143+

#if _NCURSES_EXTENDED_COLOR_FUNCS

144+

#define _NCURSES_COLOR_VAL_TYPE int

145+

#define _CURSES_INIT_COLOR_FUNC init_extended_color

146+

#define _CURSES_INIT_PAIR_FUNC init_extended_pair

147+

#define _COLOR_CONTENT_FUNC extended_color_content

148+

#define _CURSES_PAIR_NUMBER_FUNC extended_pair_content

149+

#else

150+

#define _NCURSES_COLOR_VAL_TYPE short

151+

#define _CURSES_INIT_COLOR_FUNC init_color

152+

#define _CURSES_INIT_PAIR_FUNC init_pair

153+

#define _COLOR_CONTENT_FUNC color_content

154+

#define _CURSES_PAIR_NUMBER_FUNC pair_content

155+

#endif /* _NCURSES_EXTENDED_COLOR_FUNCS */

156+157+

#define _CURSES_FUNC_NAME_STR(s) #s

158+159+

#define _CURSES_INIT_COLOR_FUNC_NAME _CURSES_FUNC_NAME_STR(_CURSES_INIT_COLOR_FUNC)

160+

#define _CURSES_INIT_PAIR_FUNC_NAME _CURSES_FUNC_NAME_STR(_CURSES_INIT_PAIR_FUNC)

161+137162

/*[clinic input]

138163

module _curses

139164

class _curses.window "PyCursesWindowObject *" "&PyCursesWindow_Type"

@@ -387,6 +412,104 @@ PyCurses_ConvertToString(PyCursesWindowObject *win, PyObject *obj,

387412

return 0;

388413

}

389414415+

static int

416+

color_converter(PyObject *arg, void *ptr)

417+

{

418+

long color_number;

419+

int overflow;

420+421+

color_number = PyLong_AsLongAndOverflow(arg, &overflow);

422+

if (color_number == -1 && PyErr_Occurred())

423+

return 0;

424+425+

if (overflow > 0 || color_number > COLORS) {

426+

PyErr_Format(PyExc_ValueError,

427+

"Color number is greater than COLORS (%d).",

428+

COLORS);

429+

return 0;

430+

}

431+

else if (overflow < 0 || color_number < 0) {

432+

PyErr_SetString(PyExc_ValueError,

433+

"Color number is less than 0.");

434+

return 0;

435+

}

436+437+

*(int *)ptr = (int)color_number;

438+

return 1;

439+

}

440+441+

/*[python input]

442+

class color_converter(CConverter):

443+

type = 'int'

444+

converter = 'color_converter'

445+

[python start generated code]*/

446+

/*[python end generated code: output=da39a3ee5e6b4b0d input=4260d2b6e66b3709]*/

447+448+

static int

449+

pair_converter(PyObject *arg, void *ptr)

450+

{

451+

long pair_number;

452+

int overflow;

453+454+

pair_number = PyLong_AsLongAndOverflow(arg, &overflow);

455+

if (pair_number == -1 && PyErr_Occurred())

456+

return 0;

457+458+

if (overflow > 0 || pair_number > COLOR_PAIRS - 1) {

459+

PyErr_Format(PyExc_ValueError,

460+

"Color pair is greater than COLOR_PAIRS-1 (%d).",

461+

COLOR_PAIRS - 1);

462+

return 0;

463+

}

464+

else if (overflow < 0 || pair_number < 1) {

465+

PyErr_SetString(PyExc_ValueError,

466+

"Color pair is less than 1.");

467+

return 0;

468+

}

469+470+

*(int *)ptr = (int)pair_number;

471+

return 1;

472+

}

473+474+

/*[python input]

475+

class pair_converter(CConverter):

476+

type = 'int'

477+

converter = 'pair_converter'

478+

[python start generated code]*/

479+

/*[python end generated code: output=da39a3ee5e6b4b0d input=1a918ae6a1b32af7]*/

480+481+

static int

482+

component_converter(PyObject *arg, void *ptr)

483+

{

484+

long component;

485+

int overflow;

486+487+

component = PyLong_AsLongAndOverflow(arg, &overflow);

488+

if (component == -1 && PyErr_Occurred())

489+

return 0;

490+491+

if (overflow > 0 || component > 1000) {

492+

PyErr_SetString(PyExc_ValueError,

493+

"Color component is greater than 1000");

494+

return 0;

495+

}

496+

else if (overflow < 0 || component < 0) {

497+

PyErr_SetString(PyExc_ValueError,

498+

"Color component is less than 0");

499+

return 0;

500+

}

501+502+

*(short *)ptr = (short)component;

503+

return 1;

504+

}

505+506+

/*[python input]

507+

class component_converter(CConverter):

508+

type = 'short'

509+

converter = 'component_converter'

510+

[python start generated code]*/

511+

/*[python end generated code: output=da39a3ee5e6b4b0d input=38e9be01d33927fb]*/

512+390513

/* Function versions of the 3 functions for testing whether curses has been

391514

initialised or not. */

392515

@@ -2585,7 +2708,7 @@ NoArgOrFlagNoReturnFunctionBody(cbreak, flag)

25852708

/*[clinic input]

25862709

_curses.color_content

258727102588-

color_number: short

2711+

color_number: color

25892712

The number of the color (0 - COLORS).

25902713

/

25912714

@@ -2596,15 +2719,15 @@ which will be between 0 (no component) and 1000 (maximum amount of component).

25962719

[clinic start generated code]*/

2597272025982721

static PyObject *

2599-

_curses_color_content_impl(PyObject *module, short color_number)

2600-

/*[clinic end generated code: output=cb15cf3120d4bfc1 input=5555abb1c11e11b7]*/

2722+

_curses_color_content_impl(PyObject *module, int color_number)

2723+

/*[clinic end generated code: output=17b466df7054e0de input=c10ef58f694b13ee]*/

26012724

{

2602-

short r,g,b;

2725+

_NCURSES_COLOR_VAL_TYPE r,g,b;

2603272626042727

PyCursesInitialised;

26052728

PyCursesInitialisedColor;

260627292607-

if (color_content(color_number, &r, &g, &b) != ERR)

2730+

if (_COLOR_CONTENT_FUNC(color_number, &r, &g, &b) != ERR)

26082731

return Py_BuildValue("(iii)", r, g, b);

26092732

else {

26102733

PyErr_SetString(PyCursesError,

@@ -2616,7 +2739,7 @@ _curses_color_content_impl(PyObject *module, short color_number)

26162739

/*[clinic input]

26172740

_curses.color_pair

261827412619-

color_number: short

2742+

color_number: color

26202743

The number of the color (0 - COLORS).

26212744

/

26222745

@@ -2627,8 +2750,8 @@ other A_* attributes. pair_number() is the counterpart to this function.

26272750

[clinic start generated code]*/

2628275126292752

static PyObject *

2630-

_curses_color_pair_impl(PyObject *module, short color_number)

2631-

/*[clinic end generated code: output=6a84cb6b29ecaf9a input=a9d3eb6f50e4dc12]*/

2753+

_curses_color_pair_impl(PyObject *module, int color_number)

2754+

/*[clinic end generated code: output=3fd752e8e24c93fb input=b049033819ab4ef5]*/

26322755

{

26332756

PyCursesInitialised;

26342757

PyCursesInitialisedColor;

@@ -3027,13 +3150,13 @@ _curses_has_key_impl(PyObject *module, int key)

30273150

/*[clinic input]

30283151

_curses.init_color

302931523030-

color_number: short

3153+

color_number: color

30313154

The number of the color to be changed (0 - COLORS).

3032-

r: short

3155+

r: component

30333156

Red component (0 - 1000).

3034-

g: short

3157+

g: component

30353158

Green component (0 - 1000).

3036-

b: short

3159+

b: component

30373160

Blue component (0 - 1000).

30383161

/

30393162

@@ -3045,24 +3168,24 @@ most terminals; it is active only if can_change_color() returns 1.

30453168

[clinic start generated code]*/

3046316930473170

static PyObject *

3048-

_curses_init_color_impl(PyObject *module, short color_number, short r,

3049-

short g, short b)

3050-

/*[clinic end generated code: output=280236f5efe9776a input=f3a05bd38f619175]*/

3171+

_curses_init_color_impl(PyObject *module, int color_number, short r, short g,

3172+

short b)

3173+

/*[clinic end generated code: output=d7ed71b2d818cdf2 input=8a2fe94ca9204aa5]*/

30513174

{

30523175

PyCursesInitialised;

30533176

PyCursesInitialisedColor;

305431773055-

return PyCursesCheckERR(init_color(color_number, r, g, b), "init_color");

3178+

return PyCursesCheckERR(_CURSES_INIT_COLOR_FUNC(color_number, r, g, b), _CURSES_INIT_COLOR_FUNC_NAME);

30563179

}

3057318030583181

/*[clinic input]

30593182

_curses.init_pair

306031833061-

pair_number: short

3184+

pair_number: pair

30623185

The number of the color-pair to be changed (1 - (COLOR_PAIRS-1)).

3063-

fg: short

3186+

fg: color

30643187

Foreground color number (0 - COLORS).

3065-

bg: short

3188+

bg: color

30663189

Background color number (0 - COLORS).

30673190

/

30683191

@@ -3073,14 +3196,13 @@ all occurrences of that color-pair are changed to the new definition.

30733196

[clinic start generated code]*/

3074319730753198

static PyObject *

3076-

_curses_init_pair_impl(PyObject *module, short pair_number, short fg,

3077-

short bg)

3078-

/*[clinic end generated code: output=9c2ce39c22f376b6 input=c9f0b11b17a2ac6d]*/

3199+

_curses_init_pair_impl(PyObject *module, int pair_number, int fg, int bg)

3200+

/*[clinic end generated code: output=a0bba03d2bbc3ee6 input=b865583a18061c1f]*/

30793201

{

30803202

PyCursesInitialised;

30813203

PyCursesInitialisedColor;

308232043083-

return PyCursesCheckERR(init_pair(pair_number, fg, bg), "init_pair");

3205+

return PyCursesCheckERR(_CURSES_INIT_PAIR_FUNC(pair_number, fg, bg), _CURSES_INIT_PAIR_FUNC_NAME);

30843206

}

3085320730863208

static PyObject *ModDict;

@@ -3697,23 +3819,23 @@ NoArgNoReturnFunctionBody(noraw)

36973819

/*[clinic input]

36983820

_curses.pair_content

369938213700-

pair_number: short

3822+

pair_number: pair

37013823

The number of the color pair (1 - (COLOR_PAIRS-1)).

37023824

/

3703382537043826

Return a tuple (fg, bg) containing the colors for the requested color pair.

37053827

[clinic start generated code]*/

3706382837073829

static PyObject *

3708-

_curses_pair_content_impl(PyObject *module, short pair_number)

3709-

/*[clinic end generated code: output=5a72aa1a28bbacf3 input=f4d7fec5643b976b]*/

3830+

_curses_pair_content_impl(PyObject *module, int pair_number)

3831+

/*[clinic end generated code: output=4a726dd0e6885f3f input=b42eacf8a4103852]*/

37103832

{

3711-

short f, b;

3833+

_NCURSES_COLOR_VAL_TYPE f, b;

3712383437133835

PyCursesInitialised;

37143836

PyCursesInitialisedColor;

371538373716-

if (pair_content(pair_number, &f, &b)==ERR) {

3838+

if (_CURSES_PAIR_NUMBER_FUNC(pair_number, &f, &b)==ERR) {

37173839

PyErr_SetString(PyCursesError,

37183840

"Argument 1 was out of range. (1..COLOR_PAIRS-1)");

37193841

return NULL;

@@ -4450,6 +4572,21 @@ make_ncurses_version(void)

4450457244514573

#endif /* NCURSES_VERSION */

445245744575+

/*[clinic input]

4576+

_curses.has_extended_color_support

4577+4578+

Return True if the module supports extended colors; otherwise, return False.

4579+4580+

Extended color support allows more than 256 color-pairs for terminals

4581+

that support more than 16 colors (e.g. xterm-256color).

4582+

[clinic start generated code]*/

4583+4584+

static PyObject *

4585+

_curses_has_extended_color_support_impl(PyObject *module)

4586+

/*[clinic end generated code: output=68f1be2b57d92e22 input=4b905f046e35ee9f]*/

4587+

{

4588+

return PyBool_FromLong(_NCURSES_EXTENDED_COLOR_FUNCS);

4589+

}

4453459044544591

/* List of functions defined in the module */

44554592

@@ -4476,6 +4613,7 @@ static PyMethodDef PyCurses_methods[] = {

44764613

_CURSES_GETSYX_METHODDEF

44774614

_CURSES_GETWIN_METHODDEF

44784615

_CURSES_HAS_COLORS_METHODDEF

4616+

_CURSES_HAS_EXTENDED_COLOR_SUPPORT_METHODDEF

44794617

_CURSES_HAS_IC_METHODDEF

44804618

_CURSES_HAS_IL_METHODDEF

44814619

_CURSES_HAS_KEY_METHODDEF