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]
138163module _curses
139164class _curses.window "PyCursesWindowObject *" "&PyCursesWindow_Type"
@@ -387,6 +412,104 @@ PyCurses_ConvertToString(PyCursesWindowObject *win, PyObject *obj,
387412return 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]*/
2597272025982721static 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;
2603272626042727PyCursesInitialised;
26052728PyCursesInitialisedColor;
260627292607-if (color_content(color_number, &r, &g, &b) != ERR)
2730+if (_COLOR_CONTENT_FUNC(color_number, &r, &g, &b) != ERR)
26082731return Py_BuildValue("(iii)", r, g, b);
26092732else {
26102733PyErr_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]*/
2628275126292752static 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{
26332756PyCursesInitialised;
26342757PyCursesInitialisedColor;
@@ -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]*/
3046316930473170static 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{
30523175PyCursesInitialised;
30533176PyCursesInitialisedColor;
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]*/
3074319730753198static 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{
30803202PyCursesInitialised;
30813203PyCursesInitialisedColor;
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}
3085320730863208static 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 /
3703382537043826Return a tuple (fg, bg) containing the colors for the requested color pair.
37053827[clinic start generated code]*/
3706382837073829static 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;
3712383437133835PyCursesInitialised;
37143836PyCursesInitialisedColor;
371538373716-if (pair_content(pair_number, &f, &b)==ERR) {
3838+if (_CURSES_PAIR_NUMBER_FUNC(pair_number, &f, &b)==ERR) {
37173839PyErr_SetString(PyCursesError,
37183840"Argument 1 was out of range. (1..COLOR_PAIRS-1)");
37193841return 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