1/* 2 * This is a curses module for Python. 3 * 4 * Based on prior work by Lance Ellinghaus and Oliver Andrich 5 * Version 1.2 of this module: Copyright 1994 by Lance Ellinghouse, 6 * Cathedral City, California Republic, United States of America. 7 * 8 * Version 1.5b1, heavily extended for ncurses by Oliver Andrich: 9 * Copyright 1996,1997 by Oliver Andrich, Koblenz, Germany. 10 * 11 * Tidied for Python 1.6, and currently maintained by <amk@amk.ca>. 12 * 13 * Permission is hereby granted, free of charge, to any person obtaining 14 * a copy of this source file to use, copy, modify, merge, or publish it 15 * subject to the following conditions: 16 * 17 * The above copyright notice and this permission notice shall be included 18 * in all copies or in any new file that contains a substantial portion of 19 * this file. 20 * 21 * THE AUTHOR MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF 22 * THE SOFTWARE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT 23 * EXPRESS OR IMPLIED WARRANTY. THE AUTHOR DISCLAIMS ALL WARRANTIES 24 * WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES 25 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 * NON-INFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE 27 * AUTHOR BE LIABLE TO YOU OR ANY OTHER PARTY FOR ANY SPECIAL, 28 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER 29 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE, STRICT LIABILITY OR 30 * ANY OTHER ACTION ARISING OUT OF OR IN CONNECTION WITH THE USE OR 31 * PERFORMANCE OF THIS SOFTWARE. 32 */ 33 34/* 35 36 A number of SysV or ncurses functions don't have wrappers yet; if you 37 need a given function, add it and send a patch. See 38 https://www.python.org/dev/patches/ for instructions on how to submit 39 patches to Python. 40 41 Here's a list of currently unsupported functions: 42 43 addchnstr addchstr color_set define_key 44 del_curterm delscreen dupwin inchnstr inchstr innstr keyok 45 mcprint mvaddchnstr mvaddchstr mvcur mvinchnstr 46 mvinchstr mvinnstr mmvwaddchnstr mvwaddchstr 47 mvwinchnstr mvwinchstr mvwinnstr newterm 48 restartterm ripoffline scr_dump 49 scr_init scr_restore scr_set scrl set_curterm set_term setterm 50 tgetent tgetflag tgetnum tgetstr tgoto timeout tputs 51 vidattr vidputs waddchnstr waddchstr 52 wcolor_set winchnstr winchstr winnstr wmouse_trafo wscrl 53 54 Low-priority: 55 slk_attr slk_attr_off slk_attr_on slk_attr_set slk_attroff 56 slk_attron slk_attrset slk_clear slk_color slk_init slk_label 57 slk_noutrefresh slk_refresh slk_restore slk_set slk_touch 58 59 Menu extension (ncurses and probably SYSV): 60 current_item free_item free_menu item_count item_description 61 item_index item_init item_name item_opts item_opts_off 62 item_opts_on item_term item_userptr item_value item_visible 63 menu_back menu_driver menu_fore menu_format menu_grey 64 menu_init menu_items menu_mark menu_opts menu_opts_off 65 menu_opts_on menu_pad menu_pattern menu_request_by_name 66 menu_request_name menu_spacing menu_sub menu_term menu_userptr 67 menu_win new_item new_menu pos_menu_cursor post_menu 68 scale_menu set_current_item set_item_init set_item_opts 69 set_item_term set_item_userptr set_item_value set_menu_back 70 set_menu_fore set_menu_format set_menu_grey set_menu_init 71 set_menu_items set_menu_mark set_menu_opts set_menu_pad 72 set_menu_pattern set_menu_spacing set_menu_sub set_menu_term 73 set_menu_userptr set_menu_win set_top_row top_row unpost_menu 74 75 Form extension (ncurses and probably SYSV): 76 current_field data_ahead data_behind dup_field 77 dynamic_fieldinfo field_arg field_back field_buffer 78 field_count field_fore field_index field_info field_init 79 field_just field_opts field_opts_off field_opts_on field_pad 80 field_status field_term field_type field_userptr form_driver 81 form_fields form_init form_opts form_opts_off form_opts_on 82 form_page form_request_by_name form_request_name form_sub 83 form_term form_userptr form_win free_field free_form 84 link_field link_fieldtype move_field new_field new_form 85 new_page pos_form_cursor post_form scale_form 86 set_current_field set_field_back set_field_buffer 87 set_field_fore set_field_init set_field_just set_field_opts 88 set_field_pad set_field_status set_field_term set_field_type 89 set_field_userptr set_fieldtype_arg set_fieldtype_choice 90 set_form_fields set_form_init set_form_opts set_form_page 91 set_form_sub set_form_term set_form_userptr set_form_win 92 set_max_field set_new_page unpost_form 93 94 95*/ 96 97/* Release Number */ 98 99static const char PyCursesVersion[] = "2.2"; 100 101/* Includes */ 102 103#ifndef Py_BUILD_CORE_BUILTIN 104# define Py_BUILD_CORE_MODULE 1 105#endif 106#define NEEDS_PY_IDENTIFIER 107 108#define PY_SSIZE_T_CLEAN 109 110#include "Python.h" 111#include "pycore_long.h" // _PyLong_GetZero() 112#include "pycore_structseq.h" // _PyStructSequence_NewType() 113 114#ifdef __hpux 115#define STRICT_SYSV_CURSES 116#endif 117 118#define CURSES_MODULE 119#include "py_curses.h" 120 121#if defined(HAVE_TERM_H) || defined(__sgi) 122/* For termname, longname, putp, tigetflag, tigetnum, tigetstr, tparm 123 which are not declared in SysV curses and for setupterm. */ 124#include <term.h> 125/* Including <term.h> #defines many common symbols. */ 126#undef lines 127#undef columns 128#endif 129 130#ifdef HAVE_LANGINFO_H 131#include <langinfo.h> 132#endif 133 134#if !defined(HAVE_NCURSES_H) && (defined(sgi) || defined(__sun) || defined(SCO5)) 135#define STRICT_SYSV_CURSES /* Don't use ncurses extensions */ 136typedef chtype attr_t; /* No attr_t type is available */ 137#endif 138 139#if defined(_AIX) 140#define STRICT_SYSV_CURSES 141#endif 142 143#if NCURSES_EXT_FUNCS+0 >= 20170401 && NCURSES_EXT_COLORS+0 >= 20170401 144#define _NCURSES_EXTENDED_COLOR_FUNCS 1 145#else 146#define _NCURSES_EXTENDED_COLOR_FUNCS 0 147#endif 148 149#if _NCURSES_EXTENDED_COLOR_FUNCS 150#define _CURSES_COLOR_VAL_TYPE int 151#define _CURSES_COLOR_NUM_TYPE int 152#define _CURSES_INIT_COLOR_FUNC init_extended_color 153#define _CURSES_INIT_PAIR_FUNC init_extended_pair 154#define _COLOR_CONTENT_FUNC extended_color_content 155#define _CURSES_PAIR_CONTENT_FUNC extended_pair_content 156#else 157#define _CURSES_COLOR_VAL_TYPE short 158#define _CURSES_COLOR_NUM_TYPE short 159#define _CURSES_INIT_COLOR_FUNC init_color 160#define _CURSES_INIT_PAIR_FUNC init_pair 161#define _COLOR_CONTENT_FUNC color_content 162#define _CURSES_PAIR_CONTENT_FUNC pair_content 163#endif /* _NCURSES_EXTENDED_COLOR_FUNCS */ 164 165/*[clinic input] 166module _curses 167class _curses.window "PyCursesWindowObject *" "&PyCursesWindow_Type" 168[clinic start generated code]*/ 169/*[clinic end generated code: output=da39a3ee5e6b4b0d input=43265c372c2887d6]*/ 170 171/* Definition of exception curses.error */ 172 173static PyObject *PyCursesError; 174 175/* Tells whether setupterm() has been called to initialise terminfo. */ 176static int initialised_setupterm = FALSE; 177 178/* Tells whether initscr() has been called to initialise curses. */ 179static int initialised = FALSE; 180 181/* Tells whether start_color() has been called to initialise color usage. */ 182static int initialisedcolors = FALSE; 183 184static char *screen_encoding = NULL; 185 186/* Utility Macros */ 187#define PyCursesSetupTermCalled \ 188 if (initialised_setupterm != TRUE) { \ 189 PyErr_SetString(PyCursesError, \ 190 "must call (at least) setupterm() first"); \ 191 return 0; } 192 193#define PyCursesInitialised \ 194 if (initialised != TRUE) { \ 195 PyErr_SetString(PyCursesError, \ 196 "must call initscr() first"); \ 197 return 0; } 198 199#define PyCursesInitialisedColor \ 200 if (initialisedcolors != TRUE) { \ 201 PyErr_SetString(PyCursesError, \ 202 "must call start_color() first"); \ 203 return 0; } 204 205/* Utility Functions */ 206 207/* 208 * Check the return code from a curses function and return None 209 * or raise an exception as appropriate. These are exported using the 210 * capsule API. 211 */ 212 213static PyObject * 214PyCursesCheckERR(int code, const char *fname) 215{ 216 if (code != ERR) { 217 Py_RETURN_NONE; 218 } else { 219 if (fname == NULL) { 220 PyErr_SetString(PyCursesError, catchall_ERR); 221 } else { 222 PyErr_Format(PyCursesError, "%s() returned ERR", fname); 223 } 224 return NULL; 225 } 226} 227 228/* Convert an object to a byte (an integer of type chtype): 229 230 - int 231 - bytes of length 1 232 - str of length 1 233 234 Return 1 on success, 0 on error (invalid type or integer overflow). */ 235static int 236PyCurses_ConvertToChtype(PyCursesWindowObject *win, PyObject *obj, chtype *ch) 237{ 238 long value; 239 if(PyBytes_Check(obj) && PyBytes_Size(obj) == 1) { 240 value = (unsigned char)PyBytes_AsString(obj)[0]; 241 } 242 else if (PyUnicode_Check(obj)) { 243 if (PyUnicode_GetLength(obj) != 1) { 244 PyErr_Format(PyExc_TypeError, 245 "expect bytes or str of length 1, or int, " 246 "got a str of length %zi", 247 PyUnicode_GET_LENGTH(obj)); 248 return 0; 249 } 250 value = PyUnicode_READ_CHAR(obj, 0); 251 if (128 < value) { 252 PyObject *bytes; 253 const char *encoding; 254 if (win) 255 encoding = win->encoding; 256 else 257 encoding = screen_encoding; 258 bytes = PyUnicode_AsEncodedString(obj, encoding, NULL); 259 if (bytes == NULL) 260 return 0; 261 if (PyBytes_GET_SIZE(bytes) == 1) 262 value = (unsigned char)PyBytes_AS_STRING(bytes)[0]; 263 else 264 value = -1; 265 Py_DECREF(bytes); 266 if (value < 0) 267 goto overflow; 268 } 269 } 270 else if (PyLong_CheckExact(obj)) { 271 int long_overflow; 272 value = PyLong_AsLongAndOverflow(obj, &long_overflow); 273 if (long_overflow) 274 goto overflow; 275 } 276 else { 277 PyErr_Format(PyExc_TypeError, 278 "expect bytes or str of length 1, or int, got %s", 279 Py_TYPE(obj)->tp_name); 280 return 0; 281 } 282 *ch = (chtype)value; 283 if ((long)*ch != value) 284 goto overflow; 285 return 1; 286 287overflow: 288 PyErr_SetString(PyExc_OverflowError, 289 "byte doesn't fit in chtype"); 290 return 0; 291} 292 293/* Convert an object to a byte (chtype) or a character (cchar_t): 294 295 - int 296 - bytes of length 1 297 - str of length 1 298 299 Return: 300 301 - 2 if obj is a character (written into *wch) 302 - 1 if obj is a byte (written into *ch) 303 - 0 on error: raise an exception */ 304static int 305PyCurses_ConvertToCchar_t(PyCursesWindowObject *win, PyObject *obj, 306 chtype *ch 307#ifdef HAVE_NCURSESW 308 , wchar_t *wch 309#endif 310 ) 311{ 312 long value; 313#ifdef HAVE_NCURSESW 314 wchar_t buffer[2]; 315#endif 316 317 if (PyUnicode_Check(obj)) { 318#ifdef HAVE_NCURSESW 319 if (PyUnicode_AsWideChar(obj, buffer, 2) != 1) { 320 PyErr_Format(PyExc_TypeError, 321 "expect bytes or str of length 1, or int, " 322 "got a str of length %zi", 323 PyUnicode_GET_LENGTH(obj)); 324 return 0; 325 } 326 *wch = buffer[0]; 327 return 2; 328#else 329 return PyCurses_ConvertToChtype(win, obj, ch); 330#endif 331 } 332 else if(PyBytes_Check(obj) && PyBytes_Size(obj) == 1) { 333 value = (unsigned char)PyBytes_AsString(obj)[0]; 334 } 335 else if (PyLong_CheckExact(obj)) { 336 int overflow; 337 value = PyLong_AsLongAndOverflow(obj, &overflow); 338 if (overflow) { 339 PyErr_SetString(PyExc_OverflowError, 340 "int doesn't fit in long"); 341 return 0; 342 } 343 } 344 else { 345 PyErr_Format(PyExc_TypeError, 346 "expect bytes or str of length 1, or int, got %s", 347 Py_TYPE(obj)->tp_name); 348 return 0; 349 } 350 351 *ch = (chtype)value; 352 if ((long)*ch != value) { 353 PyErr_Format(PyExc_OverflowError, 354 "byte doesn't fit in chtype"); 355 return 0; 356 } 357 return 1; 358} 359 360/* Convert an object to a byte string (char*) or a wide character string 361 (wchar_t*). Return: 362 363 - 2 if obj is a character string (written into *wch) 364 - 1 if obj is a byte string (written into *bytes) 365 - 0 on error: raise an exception */ 366static int 367PyCurses_ConvertToString(PyCursesWindowObject *win, PyObject *obj, 368 PyObject **bytes, wchar_t **wstr) 369{ 370 char *str; 371 if (PyUnicode_Check(obj)) { 372#ifdef HAVE_NCURSESW 373 assert (wstr != NULL); 374 375 *wstr = PyUnicode_AsWideCharString(obj, NULL); 376 if (*wstr == NULL) 377 return 0; 378 return 2; 379#else 380 assert (wstr == NULL); 381 *bytes = PyUnicode_AsEncodedString(obj, win->encoding, NULL); 382 if (*bytes == NULL) 383 return 0; 384 /* check for embedded null bytes */ 385 if (PyBytes_AsStringAndSize(*bytes, &str, NULL) < 0) { 386 Py_CLEAR(*bytes); 387 return 0; 388 } 389 return 1; 390#endif 391 } 392 else if (PyBytes_Check(obj)) { 393 Py_INCREF(obj); 394 *bytes = obj; 395 /* check for embedded null bytes */ 396 if (PyBytes_AsStringAndSize(*bytes, &str, NULL) < 0) { 397 Py_DECREF(obj); 398 return 0; 399 } 400 return 1; 401 } 402 403 PyErr_Format(PyExc_TypeError, "expect bytes or str, got %s", 404 Py_TYPE(obj)->tp_name); 405 return 0; 406} 407 408static int 409color_allow_default_converter(PyObject *arg, void *ptr) 410{ 411 long color_number; 412 int overflow; 413 414 color_number = PyLong_AsLongAndOverflow(arg, &overflow); 415 if (color_number == -1 && PyErr_Occurred()) 416 return 0; 417 418 if (overflow > 0 || color_number >= COLORS) { 419 PyErr_Format(PyExc_ValueError, 420 "Color number is greater than COLORS-1 (%d).", 421 COLORS - 1); 422 return 0; 423 } 424 else if (overflow < 0 || color_number < 0) { 425 color_number = -1; 426 } 427 428 *(int *)ptr = (int)color_number; 429 return 1; 430} 431 432static int 433color_converter(PyObject *arg, void *ptr) 434{ 435 if (!color_allow_default_converter(arg, ptr)) { 436 return 0; 437 } 438 if (*(int *)ptr < 0) { 439 PyErr_SetString(PyExc_ValueError, 440 "Color number is less than 0."); 441 return 0; 442 } 443 return 1; 444} 445 446/*[python input] 447class color_converter(CConverter): 448 type = 'int' 449 converter = 'color_converter' 450[python start generated code]*/ 451/*[python end generated code: output=da39a3ee5e6b4b0d input=4260d2b6e66b3709]*/ 452 453/*[python input] 454class color_allow_default_converter(CConverter): 455 type = 'int' 456 converter = 'color_allow_default_converter' 457[python start generated code]*/ 458/*[python end generated code: output=da39a3ee5e6b4b0d input=975602bc058a872d]*/ 459 460static int 461pair_converter(PyObject *arg, void *ptr) 462{ 463 long pair_number; 464 int overflow; 465 466 pair_number = PyLong_AsLongAndOverflow(arg, &overflow); 467 if (pair_number == -1 && PyErr_Occurred()) 468 return 0; 469 470#if _NCURSES_EXTENDED_COLOR_FUNCS 471 if (overflow > 0 || pair_number > INT_MAX) { 472 PyErr_Format(PyExc_ValueError, 473 "Color pair is greater than maximum (%d).", 474 INT_MAX); 475 return 0; 476 } 477#else 478 if (overflow > 0 || pair_number >= COLOR_PAIRS) { 479 PyErr_Format(PyExc_ValueError, 480 "Color pair is greater than COLOR_PAIRS-1 (%d).", 481 COLOR_PAIRS - 1); 482 return 0; 483 } 484#endif 485 else if (overflow < 0 || pair_number < 0) { 486 PyErr_SetString(PyExc_ValueError, 487 "Color pair is less than 0."); 488 return 0; 489 } 490 491 *(int *)ptr = (int)pair_number; 492 return 1; 493} 494 495/*[python input] 496class pair_converter(CConverter): 497 type = 'int' 498 converter = 'pair_converter' 499[python start generated code]*/ 500/*[python end generated code: output=da39a3ee5e6b4b0d input=1a918ae6a1b32af7]*/ 501 502static int 503component_converter(PyObject *arg, void *ptr) 504{ 505 long component; 506 int overflow; 507 508 component = PyLong_AsLongAndOverflow(arg, &overflow); 509 if (component == -1 && PyErr_Occurred()) 510 return 0; 511 512 if (overflow > 0 || component > 1000) { 513 PyErr_SetString(PyExc_ValueError, 514 "Color component is greater than 1000"); 515 return 0; 516 } 517 else if (overflow < 0 || component < 0) { 518 PyErr_SetString(PyExc_ValueError, 519 "Color component is less than 0"); 520 return 0; 521 } 522 523 *(short *)ptr = (short)component; 524 return 1; 525} 526 527/*[python input] 528class component_converter(CConverter): 529 type = 'short' 530 converter = 'component_converter' 531[python start generated code]*/ 532/*[python end generated code: output=da39a3ee5e6b4b0d input=38e9be01d33927fb]*/ 533 534/* Function versions of the 3 functions for testing whether curses has been 535 initialised or not. */ 536 537static int func_PyCursesSetupTermCalled(void) 538{ 539 PyCursesSetupTermCalled; 540 return 1; 541} 542 543static int func_PyCursesInitialised(void) 544{ 545 PyCursesInitialised; 546 return 1; 547} 548 549static int func_PyCursesInitialisedColor(void) 550{ 551 PyCursesInitialisedColor; 552 return 1; 553} 554 555/***************************************************************************** 556 The Window Object 557******************************************************************************/ 558 559/* Definition of the window type */ 560 561PyTypeObject PyCursesWindow_Type; 562 563/* Function prototype macros for Window object 564 565 X - function name 566 TYPE - parameter Type 567 ERGSTR - format string for construction of the return value 568 PARSESTR - format string for argument parsing 569*/ 570 571#define Window_NoArgNoReturnFunction(X) \ 572 static PyObject *PyCursesWindow_ ## X \ 573 (PyCursesWindowObject *self, PyObject *Py_UNUSED(ignored)) \ 574 { return PyCursesCheckERR(X(self->win), # X); } 575 576#define Window_NoArgTrueFalseFunction(X) \ 577 static PyObject * PyCursesWindow_ ## X \ 578 (PyCursesWindowObject *self, PyObject *Py_UNUSED(ignored)) \ 579 { \ 580 return PyBool_FromLong(X(self->win)); } 581 582#define Window_NoArgNoReturnVoidFunction(X) \ 583 static PyObject * PyCursesWindow_ ## X \ 584 (PyCursesWindowObject *self, PyObject *Py_UNUSED(ignored)) \ 585 { \ 586 X(self->win); Py_RETURN_NONE; } 587 588#define Window_NoArg2TupleReturnFunction(X, TYPE, ERGSTR) \ 589 static PyObject * PyCursesWindow_ ## X \ 590 (PyCursesWindowObject *self, PyObject *Py_UNUSED(ignored)) \ 591 { \ 592 TYPE arg1, arg2; \ 593 X(self->win,arg1,arg2); return Py_BuildValue(ERGSTR, arg1, arg2); } 594 595#define Window_OneArgNoReturnVoidFunction(X, TYPE, PARSESTR) \ 596 static PyObject * PyCursesWindow_ ## X \ 597 (PyCursesWindowObject *self, PyObject *args) \ 598 { \ 599 TYPE arg1; \ 600 if (!PyArg_ParseTuple(args, PARSESTR, &arg1)) return NULL; \ 601 X(self->win,arg1); Py_RETURN_NONE; } 602 603#define Window_OneArgNoReturnFunction(X, TYPE, PARSESTR) \ 604 static PyObject * PyCursesWindow_ ## X \ 605 (PyCursesWindowObject *self, PyObject *args) \ 606 { \ 607 TYPE arg1; \ 608 if (!PyArg_ParseTuple(args,PARSESTR, &arg1)) return NULL; \ 609 return PyCursesCheckERR(X(self->win, arg1), # X); } 610 611#define Window_TwoArgNoReturnFunction(X, TYPE, PARSESTR) \ 612 static PyObject * PyCursesWindow_ ## X \ 613 (PyCursesWindowObject *self, PyObject *args) \ 614 { \ 615 TYPE arg1, arg2; \ 616 if (!PyArg_ParseTuple(args,PARSESTR, &arg1, &arg2)) return NULL; \ 617 return PyCursesCheckERR(X(self->win, arg1, arg2), # X); } 618 619/* ------------- WINDOW routines --------------- */ 620 621Window_NoArgNoReturnFunction(untouchwin) 622Window_NoArgNoReturnFunction(touchwin) 623Window_NoArgNoReturnFunction(redrawwin) 624Window_NoArgNoReturnFunction(winsertln) 625Window_NoArgNoReturnFunction(werase) 626Window_NoArgNoReturnFunction(wdeleteln) 627 628Window_NoArgTrueFalseFunction(is_wintouched) 629 630Window_NoArgNoReturnVoidFunction(wsyncup) 631Window_NoArgNoReturnVoidFunction(wsyncdown) 632Window_NoArgNoReturnVoidFunction(wstandend) 633Window_NoArgNoReturnVoidFunction(wstandout) 634Window_NoArgNoReturnVoidFunction(wcursyncup) 635Window_NoArgNoReturnVoidFunction(wclrtoeol) 636Window_NoArgNoReturnVoidFunction(wclrtobot) 637Window_NoArgNoReturnVoidFunction(wclear) 638 639Window_OneArgNoReturnVoidFunction(idcok, int, "i;True(1) or False(0)") 640#ifdef HAVE_CURSES_IMMEDOK 641Window_OneArgNoReturnVoidFunction(immedok, int, "i;True(1) or False(0)") 642#endif 643Window_OneArgNoReturnVoidFunction(wtimeout, int, "i;delay") 644 645Window_NoArg2TupleReturnFunction(getyx, int, "ii") 646Window_NoArg2TupleReturnFunction(getbegyx, int, "ii") 647Window_NoArg2TupleReturnFunction(getmaxyx, int, "ii") 648Window_NoArg2TupleReturnFunction(getparyx, int, "ii") 649 650Window_OneArgNoReturnFunction(clearok, int, "i;True(1) or False(0)") 651Window_OneArgNoReturnFunction(idlok, int, "i;True(1) or False(0)") 652Window_OneArgNoReturnFunction(keypad, int, "i;True(1) or False(0)") 653Window_OneArgNoReturnFunction(leaveok, int, "i;True(1) or False(0)") 654Window_OneArgNoReturnFunction(nodelay, int, "i;True(1) or False(0)") 655Window_OneArgNoReturnFunction(notimeout, int, "i;True(1) or False(0)") 656Window_OneArgNoReturnFunction(scrollok, int, "i;True(1) or False(0)") 657Window_OneArgNoReturnFunction(winsdelln, int, "i;nlines") 658#ifdef HAVE_CURSES_SYNCOK 659Window_OneArgNoReturnFunction(syncok, int, "i;True(1) or False(0)") 660#endif 661 662Window_TwoArgNoReturnFunction(mvwin, int, "ii;y,x") 663Window_TwoArgNoReturnFunction(mvderwin, int, "ii;y,x") 664Window_TwoArgNoReturnFunction(wmove, int, "ii;y,x") 665#ifndef STRICT_SYSV_CURSES 666Window_TwoArgNoReturnFunction(wresize, int, "ii;lines,columns") 667#endif 668 669/* Allocation and deallocation of Window Objects */ 670 671static PyObject * 672PyCursesWindow_New(WINDOW *win, const char *encoding) 673{ 674 PyCursesWindowObject *wo; 675 676 if (encoding == NULL) { 677#if defined(MS_WINDOWS) 678 char *buffer[100]; 679 UINT cp; 680 cp = GetConsoleOutputCP(); 681 if (cp != 0) { 682 PyOS_snprintf(buffer, sizeof(buffer), "cp%u", cp); 683 encoding = buffer; 684 } 685#elif defined(CODESET) 686 const char *codeset = nl_langinfo(CODESET); 687 if (codeset != NULL && codeset[0] != 0) 688 encoding = codeset; 689#endif 690 if (encoding == NULL) 691 encoding = "utf-8"; 692 } 693 694 wo = PyObject_New(PyCursesWindowObject, &PyCursesWindow_Type); 695 if (wo == NULL) return NULL; 696 wo->win = win; 697 wo->encoding = _PyMem_Strdup(encoding); 698 if (wo->encoding == NULL) { 699 Py_DECREF(wo); 700 PyErr_NoMemory(); 701 return NULL; 702 } 703 return (PyObject *)wo; 704} 705 706static void 707PyCursesWindow_Dealloc(PyCursesWindowObject *wo) 708{ 709 if (wo->win != stdscr) delwin(wo->win); 710 if (wo->encoding != NULL) 711 PyMem_Free(wo->encoding); 712 PyObject_Free(wo); 713} 714 715/* Addch, Addstr, Addnstr */ 716 717/*[clinic input] 718_curses.window.addch 719 720 [ 721 y: int 722 Y-coordinate. 723 x: int 724 X-coordinate. 725 ] 726 727 ch: object 728 Character to add. 729 730 [ 731 attr: long(c_default="A_NORMAL") = _curses.A_NORMAL 732 Attributes for the character. 733 ] 734 / 735 736Paint the character. 737 738Paint character ch at (y, x) with attributes attr, 739overwriting any character previously painted at that location. 740By default, the character position and attributes are the 741current settings for the window object. 742[clinic start generated code]*/ 743 744static PyObject * 745_curses_window_addch_impl(PyCursesWindowObject *self, int group_left_1, 746 int y, int x, PyObject *ch, int group_right_1, 747 long attr) 748/*[clinic end generated code: output=00f4c37af3378f45 input=95ce131578458196]*/ 749{ 750 int coordinates_group = group_left_1; 751 int rtn; 752 int type; 753 chtype cch = 0; 754#ifdef HAVE_NCURSESW 755 wchar_t wstr[2]; 756 cchar_t wcval; 757#endif 758 const char *funcname; 759 760#ifdef HAVE_NCURSESW 761 type = PyCurses_ConvertToCchar_t(self, ch, &cch, wstr); 762 if (type == 2) { 763 funcname = "add_wch"; 764 wstr[1] = L'\0'; 765 setcchar(&wcval, wstr, attr, PAIR_NUMBER(attr), NULL); 766 if (coordinates_group) 767 rtn = mvwadd_wch(self->win,y,x, &wcval); 768 else { 769 rtn = wadd_wch(self->win, &wcval); 770 } 771 } 772 else 773#else 774 type = PyCurses_ConvertToCchar_t(self, ch, &cch); 775#endif 776 if (type == 1) { 777 funcname = "addch"; 778 if (coordinates_group) 779 rtn = mvwaddch(self->win,y,x, cch | (attr_t) attr); 780 else { 781 rtn = waddch(self->win, cch | (attr_t) attr); 782 } 783 } 784 else { 785 return NULL; 786 } 787 return PyCursesCheckERR(rtn, funcname); 788} 789 790/*[clinic input] 791_curses.window.addstr 792 793 [ 794 y: int 795 Y-coordinate. 796 x: int 797 X-coordinate. 798 ] 799 800 str: object 801 String to add. 802 803 [ 804 attr: long 805 Attributes for characters. 806 ] 807 / 808 809Paint the string. 810 811Paint the string str at (y, x) with attributes attr, 812overwriting anything previously on the display. 813By default, the character position and attributes are the 814current settings for the window object. 815[clinic start generated code]*/ 816 817static PyObject * 818_curses_window_addstr_impl(PyCursesWindowObject *self, int group_left_1, 819 int y, int x, PyObject *str, int group_right_1, 820 long attr) 821/*[clinic end generated code: output=65a928ea85ff3115 input=ff6cbb91448a22a3]*/ 822{ 823 int rtn; 824 int strtype; 825 PyObject *bytesobj = NULL; 826#ifdef HAVE_NCURSESW 827 wchar_t *wstr = NULL; 828#endif 829 attr_t attr_old = A_NORMAL; 830 int use_xy = group_left_1, use_attr = group_right_1; 831 const char *funcname; 832 833#ifdef HAVE_NCURSESW 834 strtype = PyCurses_ConvertToString(self, str, &bytesobj, &wstr); 835#else 836 strtype = PyCurses_ConvertToString(self, str, &bytesobj, NULL); 837#endif 838 if (strtype == 0) { 839 return NULL; 840 } 841 if (use_attr) { 842 attr_old = getattrs(self->win); 843 (void)wattrset(self->win,attr); 844 } 845#ifdef HAVE_NCURSESW 846 if (strtype == 2) { 847 funcname = "addwstr"; 848 if (use_xy) 849 rtn = mvwaddwstr(self->win,y,x,wstr); 850 else 851 rtn = waddwstr(self->win,wstr); 852 PyMem_Free(wstr); 853 } 854 else 855#endif 856 { 857 const char *str = PyBytes_AS_STRING(bytesobj); 858 funcname = "addstr"; 859 if (use_xy) 860 rtn = mvwaddstr(self->win,y,x,str); 861 else 862 rtn = waddstr(self->win,str); 863 Py_DECREF(bytesobj); 864 } 865 if (use_attr) 866 (void)wattrset(self->win,attr_old); 867 return PyCursesCheckERR(rtn, funcname); 868} 869 870/*[clinic input] 871_curses.window.addnstr 872 873 [ 874 y: int 875 Y-coordinate. 876 x: int 877 X-coordinate. 878 ] 879 880 str: object 881 String to add. 882 883 n: int 884 Maximal number of characters. 885 886 [ 887 attr: long 888 Attributes for characters. 889 ] 890 / 891 892Paint at most n characters of the string. 893 894Paint at most n characters of the string str at (y, x) with 895attributes attr, overwriting anything previously on the display. 896By default, the character position and attributes are the 897current settings for the window object. 898[clinic start generated code]*/ 899 900static PyObject * 901_curses_window_addnstr_impl(PyCursesWindowObject *self, int group_left_1, 902 int y, int x, PyObject *str, int n, 903 int group_right_1, long attr) 904/*[clinic end generated code: output=6d21cee2ce6876d9 input=72718415c2744a2a]*/ 905{ 906 int rtn; 907 int strtype; 908 PyObject *bytesobj = NULL; 909#ifdef HAVE_NCURSESW 910 wchar_t *wstr = NULL; 911#endif 912 attr_t attr_old = A_NORMAL; 913 int use_xy = group_left_1, use_attr = group_right_1; 914 const char *funcname; 915 916#ifdef HAVE_NCURSESW 917 strtype = PyCurses_ConvertToString(self, str, &bytesobj, &wstr); 918#else 919 strtype = PyCurses_ConvertToString(self, str, &bytesobj, NULL); 920#endif 921 if (strtype == 0) 922 return NULL; 923 924 if (use_attr) { 925 attr_old = getattrs(self->win); 926 (void)wattrset(self->win,attr); 927 } 928#ifdef HAVE_NCURSESW 929 if (strtype == 2) { 930 funcname = "addnwstr"; 931 if (use_xy) 932 rtn = mvwaddnwstr(self->win,y,x,wstr,n); 933 else 934 rtn = waddnwstr(self->win,wstr,n); 935 PyMem_Free(wstr); 936 } 937 else 938#endif 939 { 940 const char *str = PyBytes_AS_STRING(bytesobj); 941 funcname = "addnstr"; 942 if (use_xy) 943 rtn = mvwaddnstr(self->win,y,x,str,n); 944 else 945 rtn = waddnstr(self->win,str,n); 946 Py_DECREF(bytesobj); 947 } 948 if (use_attr) 949 (void)wattrset(self->win,attr_old); 950 return PyCursesCheckERR(rtn, funcname); 951} 952 953/*[clinic input] 954_curses.window.bkgd 955 956 ch: object 957 Background character. 958 attr: long(c_default="A_NORMAL") = _curses.A_NORMAL 959 Background attributes. 960 / 961 962Set the background property of the window. 963[clinic start generated code]*/ 964 965static PyObject * 966_curses_window_bkgd_impl(PyCursesWindowObject *self, PyObject *ch, long attr) 967/*[clinic end generated code: output=058290afb2cf4034 input=634015bcb339283d]*/ 968{ 969 chtype bkgd; 970 971 if (!PyCurses_ConvertToChtype(self, ch, &bkgd)) 972 return NULL; 973 974 return PyCursesCheckERR(wbkgd(self->win, bkgd | attr), "bkgd"); 975} 976 977/*[clinic input] 978_curses.window.attroff 979 980 attr: long 981 / 982 983Remove attribute attr from the "background" set. 984[clinic start generated code]*/ 985 986static PyObject * 987_curses_window_attroff_impl(PyCursesWindowObject *self, long attr) 988/*[clinic end generated code: output=8a2fcd4df682fc64 input=786beedf06a7befe]*/ 989{ 990 return PyCursesCheckERR(wattroff(self->win, (attr_t)attr), "attroff"); 991} 992 993/*[clinic input] 994_curses.window.attron 995 996 attr: long 997 / 998 999Add attribute attr from the "background" set. 1000[clinic start generated code]*/ 1001 1002static PyObject * 1003_curses_window_attron_impl(PyCursesWindowObject *self, long attr) 1004/*[clinic end generated code: output=7afea43b237fa870 input=5a88fba7b1524f32]*/ 1005{ 1006 return PyCursesCheckERR(wattron(self->win, (attr_t)attr), "attron"); 1007} 1008 1009/*[clinic input] 1010_curses.window.attrset 1011 1012 attr: long 1013 / 1014 1015Set the "background" set of attributes. 1016[clinic start generated code]*/ 1017 1018static PyObject * 1019_curses_window_attrset_impl(PyCursesWindowObject *self, long attr) 1020/*[clinic end generated code: output=84e379bff20c0433 input=42e400c0d0154ab5]*/ 1021{ 1022 return PyCursesCheckERR(wattrset(self->win, (attr_t)attr), "attrset"); 1023} 1024 1025/*[clinic input] 1026_curses.window.bkgdset 1027 1028 ch: object 1029 Background character. 1030 attr: long(c_default="A_NORMAL") = _curses.A_NORMAL 1031 Background attributes. 1032 / 1033 1034Set the window's background. 1035[clinic start generated code]*/ 1036 1037static PyObject * 1038_curses_window_bkgdset_impl(PyCursesWindowObject *self, PyObject *ch, 1039 long attr) 1040/*[clinic end generated code: output=8cb994fc4d7e2496 input=e09c682425c9e45b]*/ 1041{ 1042 chtype bkgd; 1043 1044 if (!PyCurses_ConvertToChtype(self, ch, &bkgd)) 1045 return NULL; 1046 1047 wbkgdset(self->win, bkgd | attr); 1048 return PyCursesCheckERR(0, "bkgdset"); 1049} 1050 1051/*[clinic input] 1052_curses.window.border 1053 1054 ls: object(c_default="NULL") = _curses.ACS_VLINE 1055 Left side. 1056 rs: object(c_default="NULL") = _curses.ACS_VLINE 1057 Right side. 1058 ts: object(c_default="NULL") = _curses.ACS_HLINE 1059 Top side. 1060 bs: object(c_default="NULL") = _curses.ACS_HLINE 1061 Bottom side. 1062 tl: object(c_default="NULL") = _curses.ACS_ULCORNER 1063 Upper-left corner. 1064 tr: object(c_default="NULL") = _curses.ACS_URCORNER 1065 Upper-right corner. 1066 bl: object(c_default="NULL") = _curses.ACS_LLCORNER 1067 Bottom-left corner. 1068 br: object(c_default="NULL") = _curses.ACS_LRCORNER 1069 Bottom-right corner. 1070 / 1071 1072Draw a border around the edges of the window. 1073 1074Each parameter specifies the character to use for a specific part of the 1075border. The characters can be specified as integers or as one-character 1076strings. A 0 value for any parameter will cause the default character to be 1077used for that parameter. 1078[clinic start generated code]*/ 1079 1080static PyObject * 1081_curses_window_border_impl(PyCursesWindowObject *self, PyObject *ls, 1082 PyObject *rs, PyObject *ts, PyObject *bs, 1083 PyObject *tl, PyObject *tr, PyObject *bl, 1084 PyObject *br) 1085/*[clinic end generated code: output=670ef38d3d7c2aa3 input=e015f735d67a240b]*/ 1086{ 1087 chtype ch[8]; 1088 int i; 1089 1090 /* Clear the array of parameters */ 1091 for(i=0; i<8; i++) 1092 ch[i] = 0; 1093 1094#define CONVERTTOCHTYPE(obj, i) \ 1095 if ((obj) != NULL && !PyCurses_ConvertToChtype(self, (obj), &ch[(i)])) \ 1096 return NULL; 1097 1098 CONVERTTOCHTYPE(ls, 0); 1099 CONVERTTOCHTYPE(rs, 1); 1100 CONVERTTOCHTYPE(ts, 2); 1101 CONVERTTOCHTYPE(bs, 3); 1102 CONVERTTOCHTYPE(tl, 4); 1103 CONVERTTOCHTYPE(tr, 5); 1104 CONVERTTOCHTYPE(bl, 6); 1105 CONVERTTOCHTYPE(br, 7); 1106 1107#undef CONVERTTOCHTYPE 1108 1109 wborder(self->win, 1110 ch[0], ch[1], ch[2], ch[3], 1111 ch[4], ch[5], ch[6], ch[7]); 1112 Py_RETURN_NONE; 1113} 1114 1115/*[clinic input] 1116_curses.window.box 1117 1118 [ 1119 verch: object(c_default="_PyLong_GetZero()") = 0 1120 Left and right side. 1121 horch: object(c_default="_PyLong_GetZero()") = 0 1122 Top and bottom side. 1123 ] 1124 / 1125 1126Draw a border around the edges of the window. 1127 1128Similar to border(), but both ls and rs are verch and both ts and bs are 1129horch. The default corner characters are always used by this function. 1130[clinic start generated code]*/ 1131 1132static PyObject * 1133_curses_window_box_impl(PyCursesWindowObject *self, int group_right_1, 1134 PyObject *verch, PyObject *horch) 1135/*[clinic end generated code: output=f3fcb038bb287192 input=f00435f9c8c98f60]*/ 1136{ 1137 chtype ch1 = 0, ch2 = 0; 1138 if (group_right_1) { 1139 if (!PyCurses_ConvertToChtype(self, verch, &ch1)) { 1140 return NULL; 1141 } 1142 if (!PyCurses_ConvertToChtype(self, horch, &ch2)) { 1143 return NULL; 1144 } 1145 } 1146 box(self->win,ch1,ch2); 1147 Py_RETURN_NONE; 1148} 1149 1150#if defined(HAVE_NCURSES_H) || defined(MVWDELCH_IS_EXPRESSION) 1151#define py_mvwdelch mvwdelch 1152#else 1153int py_mvwdelch(WINDOW *w, int y, int x) 1154{ 1155 mvwdelch(w,y,x); 1156 /* On HP/UX, mvwdelch already returns. On other systems, 1157 we may well run into this return statement. */ 1158 return 0; 1159} 1160#endif 1161 1162#if defined(HAVE_CURSES_IS_PAD) 1163#define py_is_pad(win) is_pad(win) 1164#elif defined(WINDOW_HAS_FLAGS) 1165#define py_is_pad(win) ((win) ? ((win)->_flags & _ISPAD) != 0 : FALSE) 1166#endif 1167 1168/* chgat, added by Fabian Kreutz <fabian.kreutz at gmx.net> */ 1169#ifdef HAVE_CURSES_WCHGAT 1170/*[-clinic input] 1171_curses.window.chgat 1172 1173 [ 1174 y: int 1175 Y-coordinate. 1176 x: int 1177 X-coordinate. 1178 ] 1179 1180 n: int = -1 1181 Number of characters. 1182 1183 attr: long 1184 Attributes for characters. 1185 / 1186 1187Set the attributes of characters. 1188 1189Set the attributes of num characters at the current cursor position, or at 1190position (y, x) if supplied. If no value of num is given or num = -1, the 1191attribute will be set on all the characters to the end of the line. This 1192function does not move the cursor. The changed line will be touched using 1193the touchline() method so that the contents will be redisplayed by the next 1194window refresh. 1195[-clinic start generated code]*/ 1196static PyObject * 1197PyCursesWindow_ChgAt(PyCursesWindowObject *self, PyObject *args) 1198{ 1199 int rtn; 1200 int x, y; 1201 int num = -1; 1202 short color; 1203 attr_t attr = A_NORMAL; 1204 long lattr; 1205 int use_xy = FALSE; 1206 1207 switch (PyTuple_Size(args)) { 1208 case 1: 1209 if (!PyArg_ParseTuple(args,"l;attr", &lattr)) 1210 return NULL; 1211 attr = lattr; 1212 break; 1213 case 2: 1214 if (!PyArg_ParseTuple(args,"il;n,attr", &num, &lattr)) 1215 return NULL; 1216 attr = lattr; 1217 break; 1218 case 3: 1219 if (!PyArg_ParseTuple(args,"iil;int,int,attr", &y, &x, &lattr)) 1220 return NULL; 1221 attr = lattr; 1222 use_xy = TRUE; 1223 break; 1224 case 4: 1225 if (!PyArg_ParseTuple(args,"iiil;int,int,n,attr", &y, &x, &num, &lattr)) 1226 return NULL; 1227 attr = lattr; 1228 use_xy = TRUE; 1229 break; 1230 default: 1231 PyErr_SetString(PyExc_TypeError, "chgat requires 1 to 4 arguments"); 1232 return NULL; 1233 } 1234 1235 color = (short) PAIR_NUMBER(attr); 1236 attr = attr & A_ATTRIBUTES; 1237 1238 if (use_xy) { 1239 rtn = mvwchgat(self->win,y,x,num,attr,color,NULL); 1240 touchline(self->win,y,1); 1241 } else { 1242 getyx(self->win,y,x); 1243 rtn = wchgat(self->win,num,attr,color,NULL); 1244 touchline(self->win,y,1); 1245 } 1246 return PyCursesCheckERR(rtn, "chgat"); 1247} 1248#endif 1249 1250/*[clinic input] 1251_curses.window.delch 1252 1253 [ 1254 y: int 1255 Y-coordinate. 1256 x: int 1257 X-coordinate. 1258 ] 1259 / 1260 1261Delete any character at (y, x). 1262[clinic start generated code]*/ 1263 1264static PyObject * 1265_curses_window_delch_impl(PyCursesWindowObject *self, int group_right_1, 1266 int y, int x) 1267/*[clinic end generated code: output=22e77bb9fa11b461 input=d2f79e630a4fc6d0]*/ 1268{ 1269 if (!group_right_1) { 1270 return PyCursesCheckERR(wdelch(self->win), "wdelch"); 1271 } 1272 else { 1273 return PyCursesCheckERR(py_mvwdelch(self->win, y, x), "mvwdelch"); 1274 } 1275} 1276 1277/*[clinic input] 1278_curses.window.derwin 1279 1280 [ 1281 nlines: int = 0 1282 Height. 1283 ncols: int = 0 1284 Width. 1285 ] 1286 begin_y: int 1287 Top side y-coordinate. 1288 begin_x: int 1289 Left side x-coordinate. 1290 / 1291 1292Create a sub-window (window-relative coordinates). 1293 1294derwin() is the same as calling subwin(), except that begin_y and begin_x 1295are relative to the origin of the window, rather than relative to the entire 1296screen. 1297[clinic start generated code]*/ 1298 1299static PyObject * 1300_curses_window_derwin_impl(PyCursesWindowObject *self, int group_left_1, 1301 int nlines, int ncols, int begin_y, int begin_x) 1302/*[clinic end generated code: output=7924b112d9f70d6e input=966d9481f7f5022e]*/ 1303{ 1304 WINDOW *win; 1305 1306 win = derwin(self->win,nlines,ncols,begin_y,begin_x); 1307 1308 if (win == NULL) { 1309 PyErr_SetString(PyCursesError, catchall_NULL); 1310 return NULL; 1311 } 1312 1313 return (PyObject *)PyCursesWindow_New(win, NULL); 1314} 1315 1316/*[clinic input] 1317_curses.window.echochar 1318 1319 ch: object 1320 Character to add. 1321 1322 attr: long(c_default="A_NORMAL") = _curses.A_NORMAL 1323 Attributes for the character. 1324 / 1325 1326Add character ch with attribute attr, and refresh. 1327[clinic start generated code]*/ 1328 1329static PyObject * 1330_curses_window_echochar_impl(PyCursesWindowObject *self, PyObject *ch, 1331 long attr) 1332/*[clinic end generated code: output=13e7dd875d4b9642 input=e7f34b964e92b156]*/ 1333{ 1334 chtype ch_; 1335 1336 if (!PyCurses_ConvertToChtype(self, ch, &ch_)) 1337 return NULL; 1338 1339#ifdef py_is_pad 1340 if (py_is_pad(self->win)) { 1341 return PyCursesCheckERR(pechochar(self->win, ch_ | (attr_t)attr), 1342 "echochar"); 1343 } 1344 else 1345#endif 1346 return PyCursesCheckERR(wechochar(self->win, ch_ | (attr_t)attr), 1347 "echochar"); 1348} 1349 1350#ifdef NCURSES_MOUSE_VERSION 1351/*[clinic input] 1352_curses.window.enclose 1353 1354 y: int 1355 Y-coordinate. 1356 x: int 1357 X-coordinate. 1358 / 1359 1360Return True if the screen-relative coordinates are enclosed by the window. 1361[clinic start generated code]*/ 1362 1363static PyObject * 1364_curses_window_enclose_impl(PyCursesWindowObject *self, int y, int x) 1365/*[clinic end generated code: output=8679beef50502648 input=4fd3355d723f7bc9]*/ 1366{ 1367 return PyBool_FromLong(wenclose(self->win, y, x)); 1368} 1369#endif 1370 1371/*[clinic input] 1372_curses.window.getbkgd -> long 1373 1374Return the window's current background character/attribute pair. 1375[clinic start generated code]*/ 1376 1377static long 1378_curses_window_getbkgd_impl(PyCursesWindowObject *self) 1379/*[clinic end generated code: output=c52b25dc16b215c3 input=a69db882fa35426c]*/ 1380{ 1381 return (long) getbkgd(self->win); 1382} 1383 1384/*[clinic input] 1385_curses.window.getch -> int 1386 1387 [ 1388 y: int 1389 Y-coordinate. 1390 x: int 1391 X-coordinate. 1392 ] 1393 / 1394 1395Get a character code from terminal keyboard. 1396 1397The integer returned does not have to be in ASCII range: function keys, 1398keypad keys and so on return numbers higher than 256. In no-delay mode, -1 1399is returned if there is no input, else getch() waits until a key is pressed. 1400[clinic start generated code]*/ 1401 1402static int 1403_curses_window_getch_impl(PyCursesWindowObject *self, int group_right_1, 1404 int y, int x) 1405/*[clinic end generated code: output=980aa6af0c0ca387 input=bb24ebfb379f991f]*/ 1406{ 1407 int rtn; 1408 1409 Py_BEGIN_ALLOW_THREADS 1410 if (!group_right_1) { 1411 rtn = wgetch(self->win); 1412 } 1413 else { 1414 rtn = mvwgetch(self->win, y, x); 1415 } 1416 Py_END_ALLOW_THREADS 1417 1418 return rtn; 1419} 1420 1421/*[clinic input] 1422_curses.window.getkey 1423 1424 [ 1425 y: int 1426 Y-coordinate. 1427 x: int 1428 X-coordinate. 1429 ] 1430 / 1431 1432Get a character (string) from terminal keyboard. 1433 1434Returning a string instead of an integer, as getch() does. Function keys, 1435keypad keys and other special keys return a multibyte string containing the 1436key name. In no-delay mode, an exception is raised if there is no input. 1437[clinic start generated code]*/ 1438 1439static PyObject * 1440_curses_window_getkey_impl(PyCursesWindowObject *self, int group_right_1, 1441 int y, int x) 1442/*[clinic end generated code: output=8490a182db46b10f input=be2dee34f5cf57f8]*/ 1443{ 1444 int rtn; 1445 1446 Py_BEGIN_ALLOW_THREADS 1447 if (!group_right_1) { 1448 rtn = wgetch(self->win); 1449 } 1450 else { 1451 rtn = mvwgetch(self->win, y, x); 1452 } 1453 Py_END_ALLOW_THREADS 1454 1455 if (rtn == ERR) { 1456 /* getch() returns ERR in nodelay mode */ 1457 PyErr_CheckSignals(); 1458 if (!PyErr_Occurred()) 1459 PyErr_SetString(PyCursesError, "no input"); 1460 return NULL; 1461 } else if (rtn <= 255) { 1462#ifdef NCURSES_VERSION_MAJOR 1463#if NCURSES_VERSION_MAJOR*100+NCURSES_VERSION_MINOR <= 507 1464 /* Work around a bug in ncurses 5.7 and earlier */ 1465 if (rtn < 0) { 1466 rtn += 256; 1467 } 1468#endif 1469#endif 1470 return PyUnicode_FromOrdinal(rtn); 1471 } else { 1472 const char *knp = keyname(rtn); 1473 return PyUnicode_FromString((knp == NULL) ? "" : knp); 1474 } 1475} 1476 1477#ifdef HAVE_NCURSESW 1478/*[clinic input] 1479_curses.window.get_wch 1480 1481 [ 1482 y: int 1483 Y-coordinate. 1484 x: int 1485 X-coordinate. 1486 ] 1487 / 1488 1489Get a wide character from terminal keyboard. 1490 1491Return a character for most keys, or an integer for function keys, 1492keypad keys, and other special keys. 1493[clinic start generated code]*/ 1494 1495static PyObject * 1496_curses_window_get_wch_impl(PyCursesWindowObject *self, int group_right_1, 1497 int y, int x) 1498/*[clinic end generated code: output=9f4f86e91fe50ef3 input=dd7e5367fb49dc48]*/ 1499{ 1500 int ct; 1501 wint_t rtn; 1502 1503 Py_BEGIN_ALLOW_THREADS 1504 if (!group_right_1) { 1505 ct = wget_wch(self->win ,&rtn); 1506 } 1507 else { 1508 ct = mvwget_wch(self->win, y, x, &rtn); 1509 } 1510 Py_END_ALLOW_THREADS 1511 1512 if (ct == ERR) { 1513 if (PyErr_CheckSignals()) 1514 return NULL; 1515 1516 /* get_wch() returns ERR in nodelay mode */ 1517 PyErr_SetString(PyCursesError, "no input"); 1518 return NULL; 1519 } 1520 if (ct == KEY_CODE_YES) 1521 return PyLong_FromLong(rtn); 1522 else 1523 return PyUnicode_FromOrdinal(rtn); 1524} 1525#endif 1526 1527/*[-clinic input] 1528_curses.window.getstr 1529 1530 [ 1531 y: int 1532 Y-coordinate. 1533 x: int 1534 X-coordinate. 1535 ] 1536 n: int = 1023 1537 Maximal number of characters. 1538 / 1539 1540Read a string from the user, with primitive line editing capacity. 1541[-clinic start generated code]*/ 1542 1543static PyObject * 1544PyCursesWindow_GetStr(PyCursesWindowObject *self, PyObject *args) 1545{ 1546 int x, y, n; 1547 char rtn[1024]; /* This should be big enough.. I hope */ 1548 int rtn2; 1549 1550 switch (PyTuple_Size(args)) { 1551 case 0: 1552 Py_BEGIN_ALLOW_THREADS 1553 rtn2 = wgetnstr(self->win,rtn, 1023); 1554 Py_END_ALLOW_THREADS 1555 break; 1556 case 1: 1557 if (!PyArg_ParseTuple(args,"i;n", &n)) 1558 return NULL; 1559 if (n < 0) { 1560 PyErr_SetString(PyExc_ValueError, "'n' must be nonnegative"); 1561 return NULL; 1562 } 1563 Py_BEGIN_ALLOW_THREADS 1564 rtn2 = wgetnstr(self->win, rtn, Py_MIN(n, 1023)); 1565 Py_END_ALLOW_THREADS 1566 break; 1567 case 2: 1568 if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x)) 1569 return NULL; 1570 Py_BEGIN_ALLOW_THREADS 1571#ifdef STRICT_SYSV_CURSES 1572 rtn2 = wmove(self->win,y,x)==ERR ? ERR : wgetnstr(self->win, rtn, 1023); 1573#else 1574 rtn2 = mvwgetnstr(self->win,y,x,rtn, 1023); 1575#endif 1576 Py_END_ALLOW_THREADS 1577 break; 1578 case 3: 1579 if (!PyArg_ParseTuple(args,"iii;y,x,n", &y, &x, &n)) 1580 return NULL; 1581 if (n < 0) { 1582 PyErr_SetString(PyExc_ValueError, "'n' must be nonnegative"); 1583 return NULL; 1584 } 1585#ifdef STRICT_SYSV_CURSES 1586 Py_BEGIN_ALLOW_THREADS 1587 rtn2 = wmove(self->win,y,x)==ERR ? ERR : 1588 wgetnstr(self->win, rtn, Py_MIN(n, 1023)); 1589 Py_END_ALLOW_THREADS 1590#else 1591 Py_BEGIN_ALLOW_THREADS 1592 rtn2 = mvwgetnstr(self->win, y, x, rtn, Py_MIN(n, 1023)); 1593 Py_END_ALLOW_THREADS 1594#endif 1595 break; 1596 default: 1597 PyErr_SetString(PyExc_TypeError, "getstr requires 0 to 3 arguments"); 1598 return NULL; 1599 } 1600 if (rtn2 == ERR) 1601 rtn[0] = 0; 1602 return PyBytes_FromString(rtn); 1603} 1604 1605/*[clinic input] 1606_curses.window.hline 1607 1608 [ 1609 y: int 1610 Starting Y-coordinate. 1611 x: int 1612 Starting X-coordinate. 1613 ] 1614 1615 ch: object 1616 Character to draw. 1617 n: int 1618 Line length. 1619 1620 [ 1621 attr: long(c_default="A_NORMAL") = _curses.A_NORMAL 1622 Attributes for the characters. 1623 ] 1624 / 1625 1626Display a horizontal line. 1627[clinic start generated code]*/ 1628 1629static PyObject * 1630_curses_window_hline_impl(PyCursesWindowObject *self, int group_left_1, 1631 int y, int x, PyObject *ch, int n, 1632 int group_right_1, long attr) 1633/*[clinic end generated code: output=c00d489d61fc9eef input=81a4dea47268163e]*/ 1634{ 1635 chtype ch_; 1636 1637 if (!PyCurses_ConvertToChtype(self, ch, &ch_)) 1638 return NULL; 1639 if (group_left_1) { 1640 if (wmove(self->win, y, x) == ERR) { 1641 return PyCursesCheckERR(ERR, "wmove"); 1642 } 1643 } 1644 return PyCursesCheckERR(whline(self->win, ch_ | (attr_t)attr, n), "hline"); 1645} 1646 1647/*[clinic input] 1648_curses.window.insch 1649 1650 [ 1651 y: int 1652 Y-coordinate. 1653 x: int 1654 X-coordinate. 1655 ] 1656 1657 ch: object 1658 Character to insert. 1659 1660 [ 1661 attr: long(c_default="A_NORMAL") = _curses.A_NORMAL 1662 Attributes for the character. 1663 ] 1664 / 1665 1666Insert a character before the current or specified position. 1667 1668All characters to the right of the cursor are shifted one position right, with 1669the rightmost characters on the line being lost. 1670[clinic start generated code]*/ 1671 1672static PyObject * 1673_curses_window_insch_impl(PyCursesWindowObject *self, int group_left_1, 1674 int y, int x, PyObject *ch, int group_right_1, 1675 long attr) 1676/*[clinic end generated code: output=ade8cfe3a3bf3e34 input=336342756ee19812]*/ 1677{ 1678 int rtn; 1679 chtype ch_ = 0; 1680 1681 if (!PyCurses_ConvertToChtype(self, ch, &ch_)) 1682 return NULL; 1683 1684 if (!group_left_1) { 1685 rtn = winsch(self->win, ch_ | (attr_t)attr); 1686 } 1687 else { 1688 rtn = mvwinsch(self->win, y, x, ch_ | (attr_t)attr); 1689 } 1690 1691 return PyCursesCheckERR(rtn, "insch"); 1692} 1693 1694/*[clinic input] 1695_curses.window.inch -> unsigned_long 1696 1697 [ 1698 y: int 1699 Y-coordinate. 1700 x: int 1701 X-coordinate. 1702 ] 1703 / 1704 1705Return the character at the given position in the window. 1706 1707The bottom 8 bits are the character proper, and upper bits are the attributes. 1708[clinic start generated code]*/ 1709 1710static unsigned long 1711_curses_window_inch_impl(PyCursesWindowObject *self, int group_right_1, 1712 int y, int x) 1713/*[clinic end generated code: output=6c4719fe978fe86a input=fac23ee11e3b3a66]*/ 1714{ 1715 unsigned long rtn; 1716 1717 if (!group_right_1) { 1718 rtn = winch(self->win); 1719 } 1720 else { 1721 rtn = mvwinch(self->win, y, x); 1722 } 1723 1724 return rtn; 1725} 1726 1727/*[-clinic input] 1728_curses.window.instr 1729 1730 [ 1731 y: int 1732 Y-coordinate. 1733 x: int 1734 X-coordinate. 1735 ] 1736 n: int = 1023 1737 Maximal number of characters. 1738 / 1739 1740Return a string of characters, extracted from the window. 1741 1742Return a string of characters, extracted from the window starting at the 1743current cursor position, or at y, x if specified. Attributes are stripped 1744from the characters. If n is specified, instr() returns a string at most 1745n characters long (exclusive of the trailing NUL). 1746[-clinic start generated code]*/ 1747static PyObject * 1748PyCursesWindow_InStr(PyCursesWindowObject *self, PyObject *args) 1749{ 1750 int x, y, n; 1751 char rtn[1024]; /* This should be big enough.. I hope */ 1752 int rtn2; 1753 1754 switch (PyTuple_Size(args)) { 1755 case 0: 1756 rtn2 = winnstr(self->win,rtn, 1023); 1757 break; 1758 case 1: 1759 if (!PyArg_ParseTuple(args,"i;n", &n)) 1760 return NULL; 1761 if (n < 0) { 1762 PyErr_SetString(PyExc_ValueError, "'n' must be nonnegative"); 1763 return NULL; 1764 } 1765 rtn2 = winnstr(self->win, rtn, Py_MIN(n, 1023)); 1766 break; 1767 case 2: 1768 if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x)) 1769 return NULL; 1770 rtn2 = mvwinnstr(self->win,y,x,rtn,1023); 1771 break; 1772 case 3: 1773 if (!PyArg_ParseTuple(args, "iii;y,x,n", &y, &x, &n)) 1774 return NULL; 1775 if (n < 0) { 1776 PyErr_SetString(PyExc_ValueError, "'n' must be nonnegative"); 1777 return NULL; 1778 } 1779 rtn2 = mvwinnstr(self->win, y, x, rtn, Py_MIN(n,1023)); 1780 break; 1781 default: 1782 PyErr_SetString(PyExc_TypeError, "instr requires 0 or 3 arguments"); 1783 return NULL; 1784 } 1785 if (rtn2 == ERR) 1786 rtn[0] = 0; 1787 return PyBytes_FromString(rtn); 1788} 1789 1790/*[clinic input] 1791_curses.window.insstr 1792 1793 [ 1794 y: int 1795 Y-coordinate. 1796 x: int 1797 X-coordinate. 1798 ] 1799 1800 str: object 1801 String to insert. 1802 1803 [ 1804 attr: long 1805 Attributes for characters. 1806 ] 1807 / 1808 1809Insert the string before the current or specified position. 1810 1811Insert a character string (as many characters as will fit on the line) 1812before the character under the cursor. All characters to the right of 1813the cursor are shifted right, with the rightmost characters on the line 1814being lost. The cursor position does not change (after moving to y, x, 1815if specified). 1816[clinic start generated code]*/ 1817 1818static PyObject * 1819_curses_window_insstr_impl(PyCursesWindowObject *self, int group_left_1, 1820 int y, int x, PyObject *str, int group_right_1, 1821 long attr) 1822/*[clinic end generated code: output=c259a5265ad0b777 input=6827cddc6340a7f3]*/ 1823{ 1824 int rtn; 1825 int strtype; 1826 PyObject *bytesobj = NULL; 1827#ifdef HAVE_NCURSESW 1828 wchar_t *wstr = NULL; 1829#endif 1830 attr_t attr_old = A_NORMAL; 1831 int use_xy = group_left_1, use_attr = group_right_1; 1832 const char *funcname; 1833 1834#ifdef HAVE_NCURSESW 1835 strtype = PyCurses_ConvertToString(self, str, &bytesobj, &wstr); 1836#else 1837 strtype = PyCurses_ConvertToString(self, str, &bytesobj, NULL); 1838#endif 1839 if (strtype == 0) 1840 return NULL; 1841 1842 if (use_attr) { 1843 attr_old = getattrs(self->win); 1844 (void)wattrset(self->win, (attr_t)attr); 1845 } 1846#ifdef HAVE_NCURSESW 1847 if (strtype == 2) { 1848 funcname = "inswstr"; 1849 if (use_xy) 1850 rtn = mvwins_wstr(self->win,y,x,wstr); 1851 else 1852 rtn = wins_wstr(self->win,wstr); 1853 PyMem_Free(wstr); 1854 } 1855 else 1856#endif 1857 { 1858 const char *str = PyBytes_AS_STRING(bytesobj); 1859 funcname = "insstr"; 1860 if (use_xy) 1861 rtn = mvwinsstr(self->win,y,x,str); 1862 else 1863 rtn = winsstr(self->win,str); 1864 Py_DECREF(bytesobj); 1865 } 1866 if (use_attr) 1867 (void)wattrset(self->win,attr_old); 1868 return PyCursesCheckERR(rtn, funcname); 1869} 1870 1871/*[clinic input] 1872_curses.window.insnstr 1873 1874 [ 1875 y: int 1876 Y-coordinate. 1877 x: int 1878 X-coordinate. 1879 ] 1880 1881 str: object 1882 String to insert. 1883 1884 n: int 1885 Maximal number of characters. 1886 1887 [ 1888 attr: long 1889 Attributes for characters. 1890 ] 1891 / 1892 1893Insert at most n characters of the string. 1894 1895Insert a character string (as many characters as will fit on the line) 1896before the character under the cursor, up to n characters. If n is zero 1897or negative, the entire string is inserted. All characters to the right 1898of the cursor are shifted right, with the rightmost characters on the line 1899being lost. The cursor position does not change (after moving to y, x, if 1900specified). 1901[clinic start generated code]*/ 1902 1903static PyObject * 1904_curses_window_insnstr_impl(PyCursesWindowObject *self, int group_left_1, 1905 int y, int x, PyObject *str, int n, 1906 int group_right_1, long attr) 1907/*[clinic end generated code: output=971a32ea6328ec8b input=70fa0cd543901a4c]*/ 1908{ 1909 int rtn; 1910 int strtype; 1911 PyObject *bytesobj = NULL; 1912#ifdef HAVE_NCURSESW 1913 wchar_t *wstr = NULL; 1914#endif 1915 attr_t attr_old = A_NORMAL; 1916 int use_xy = group_left_1, use_attr = group_right_1; 1917 const char *funcname; 1918 1919#ifdef HAVE_NCURSESW 1920 strtype = PyCurses_ConvertToString(self, str, &bytesobj, &wstr); 1921#else 1922 strtype = PyCurses_ConvertToString(self, str, &bytesobj, NULL); 1923#endif 1924 if (strtype == 0) 1925 return NULL; 1926 1927 if (use_attr) { 1928 attr_old = getattrs(self->win); 1929 (void)wattrset(self->win, (attr_t)attr); 1930 } 1931#ifdef HAVE_NCURSESW 1932 if (strtype == 2) { 1933 funcname = "insn_wstr"; 1934 if (use_xy) 1935 rtn = mvwins_nwstr(self->win,y,x,wstr,n); 1936 else 1937 rtn = wins_nwstr(self->win,wstr,n); 1938 PyMem_Free(wstr); 1939 } 1940 else 1941#endif 1942 { 1943 const char *str = PyBytes_AS_STRING(bytesobj); 1944 funcname = "insnstr"; 1945 if (use_xy) 1946 rtn = mvwinsnstr(self->win,y,x,str,n); 1947 else 1948 rtn = winsnstr(self->win,str,n); 1949 Py_DECREF(bytesobj); 1950 } 1951 if (use_attr) 1952 (void)wattrset(self->win,attr_old); 1953 return PyCursesCheckERR(rtn, funcname); 1954} 1955 1956/*[clinic input] 1957_curses.window.is_linetouched 1958 1959 line: int 1960 Line number. 1961 / 1962 1963Return True if the specified line was modified, otherwise return False. 1964 1965Raise a curses.error exception if line is not valid for the given window. 1966[clinic start generated code]*/ 1967 1968static PyObject * 1969_curses_window_is_linetouched_impl(PyCursesWindowObject *self, int line) 1970/*[clinic end generated code: output=ad4a4edfee2db08c input=a7be0c189f243914]*/ 1971{ 1972 int erg; 1973 erg = is_linetouched(self->win, line); 1974 if (erg == ERR) { 1975 PyErr_SetString(PyExc_TypeError, 1976 "is_linetouched: line number outside of boundaries"); 1977 return NULL; 1978 } 1979 return PyBool_FromLong(erg); 1980} 1981 1982#ifdef py_is_pad 1983/*[clinic input] 1984_curses.window.noutrefresh 1985 1986 [ 1987 pminrow: int 1988 pmincol: int 1989 sminrow: int 1990 smincol: int 1991 smaxrow: int 1992 smaxcol: int 1993 ] 1994 / 1995 1996Mark for refresh but wait. 1997 1998This function updates the data structure representing the desired state of the 1999window, but does not force an update of the physical screen. To accomplish 2000that, call doupdate(). 2001[clinic start generated code]*/ 2002 2003static PyObject * 2004_curses_window_noutrefresh_impl(PyCursesWindowObject *self, 2005 int group_right_1, int pminrow, int pmincol, 2006 int sminrow, int smincol, int smaxrow, 2007 int smaxcol) 2008/*[clinic end generated code: output=809a1f3c6a03e23e input=3e56898388cd739e]*/ 2009#else 2010/*[clinic input] 2011_curses.window.noutrefresh 2012 2013Mark for refresh but wait. 2014 2015This function updates the data structure representing the desired state of the 2016window, but does not force an update of the physical screen. To accomplish 2017that, call doupdate(). 2018[clinic start generated code]*/ 2019 2020static PyObject * 2021_curses_window_noutrefresh_impl(PyCursesWindowObject *self) 2022/*[clinic end generated code: output=6ef6dec666643fee input=876902e3fa431dbd]*/ 2023#endif 2024{ 2025 int rtn; 2026 2027#ifdef py_is_pad 2028 if (py_is_pad(self->win)) { 2029 if (!group_right_1) { 2030 PyErr_SetString(PyCursesError, 2031 "noutrefresh() called for a pad " 2032 "requires 6 arguments"); 2033 return NULL; 2034 } 2035 Py_BEGIN_ALLOW_THREADS 2036 rtn = pnoutrefresh(self->win, pminrow, pmincol, 2037 sminrow, smincol, smaxrow, smaxcol); 2038 Py_END_ALLOW_THREADS 2039 return PyCursesCheckERR(rtn, "pnoutrefresh"); 2040 } 2041 if (group_right_1) { 2042 PyErr_SetString(PyExc_TypeError, 2043 "noutrefresh() takes no arguments (6 given)"); 2044 return NULL; 2045 } 2046#endif 2047 Py_BEGIN_ALLOW_THREADS 2048 rtn = wnoutrefresh(self->win); 2049 Py_END_ALLOW_THREADS 2050 return PyCursesCheckERR(rtn, "wnoutrefresh"); 2051} 2052 2053/*[clinic input] 2054_curses.window.overlay 2055 2056 destwin: object(type="PyCursesWindowObject *", subclass_of="&PyCursesWindow_Type") 2057 2058 [ 2059 sminrow: int 2060 smincol: int 2061 dminrow: int 2062 dmincol: int 2063 dmaxrow: int 2064 dmaxcol: int 2065 ] 2066 / 2067 2068Overlay the window on top of destwin. 2069 2070The windows need not be the same size, only the overlapping region is copied. 2071This copy is non-destructive, which means that the current background 2072character does not overwrite the old contents of destwin. 2073 2074To get fine-grained control over the copied region, the second form of 2075overlay() can be used. sminrow and smincol are the upper-left coordinates 2076of the source window, and the other variables mark a rectangle in the 2077destination window. 2078[clinic start generated code]*/ 2079 2080static PyObject * 2081_curses_window_overlay_impl(PyCursesWindowObject *self, 2082 PyCursesWindowObject *destwin, int group_right_1, 2083 int sminrow, int smincol, int dminrow, 2084 int dmincol, int dmaxrow, int dmaxcol) 2085/*[clinic end generated code: output=82bb2c4cb443ca58 input=7edd23ad22cc1984]*/ 2086{ 2087 int rtn; 2088 2089 if (group_right_1) { 2090 rtn = copywin(self->win, destwin->win, sminrow, smincol, 2091 dminrow, dmincol, dmaxrow, dmaxcol, TRUE); 2092 return PyCursesCheckERR(rtn, "copywin"); 2093 } 2094 else { 2095 rtn = overlay(self->win, destwin->win); 2096 return PyCursesCheckERR(rtn, "overlay"); 2097 } 2098} 2099 2100/*[clinic input] 2101_curses.window.overwrite 2102 2103 destwin: object(type="PyCursesWindowObject *", subclass_of="&PyCursesWindow_Type") 2104 2105 [ 2106 sminrow: int 2107 smincol: int 2108 dminrow: int 2109 dmincol: int 2110 dmaxrow: int 2111 dmaxcol: int 2112 ] 2113 / 2114 2115Overwrite the window on top of destwin. 2116 2117The windows need not be the same size, in which case only the overlapping 2118region is copied. This copy is destructive, which means that the current 2119background character overwrites the old contents of destwin. 2120 2121To get fine-grained control over the copied region, the second form of 2122overwrite() can be used. sminrow and smincol are the upper-left coordinates 2123of the source window, the other variables mark a rectangle in the destination 2124window. 2125[clinic start generated code]*/ 2126 2127static PyObject * 2128_curses_window_overwrite_impl(PyCursesWindowObject *self, 2129 PyCursesWindowObject *destwin, 2130 int group_right_1, int sminrow, int smincol, 2131 int dminrow, int dmincol, int dmaxrow, 2132 int dmaxcol) 2133/*[clinic end generated code: output=12ae007d1681be28 input=ea5de1b35cd948e0]*/ 2134{ 2135 int rtn; 2136 2137 if (group_right_1) { 2138 rtn = copywin(self->win, destwin->win, sminrow, smincol, 2139 dminrow, dmincol, dmaxrow, dmaxcol, FALSE); 2140 return PyCursesCheckERR(rtn, "copywin"); 2141 } 2142 else { 2143 rtn = overwrite(self->win, destwin->win); 2144 return PyCursesCheckERR(rtn, "overwrite"); 2145 } 2146} 2147 2148/*[clinic input] 2149_curses.window.putwin 2150 2151 file: object 2152 / 2153 2154Write all data associated with the window into the provided file object. 2155 2156This information can be later retrieved using the getwin() function. 2157[clinic start generated code]*/ 2158 2159static PyObject * 2160_curses_window_putwin(PyCursesWindowObject *self, PyObject *file) 2161/*[clinic end generated code: output=3a25e2a5e7a040ac input=0608648e09c8ea0a]*/ 2162{ 2163 /* We have to simulate this by writing to a temporary FILE*, 2164 then reading back, then writing to the argument file. */ 2165 FILE *fp; 2166 PyObject *res = NULL; 2167 2168 fp = tmpfile(); 2169 if (fp == NULL) 2170 return PyErr_SetFromErrno(PyExc_OSError); 2171 if (_Py_set_inheritable(fileno(fp), 0, NULL) < 0) 2172 goto exit; 2173 res = PyCursesCheckERR(putwin(self->win, fp), "putwin"); 2174 if (res == NULL) 2175 goto exit; 2176 fseek(fp, 0, 0); 2177 while (1) { 2178 char buf[BUFSIZ]; 2179 Py_ssize_t n = fread(buf, 1, BUFSIZ, fp); 2180 _Py_IDENTIFIER(write); 2181 2182 if (n <= 0) 2183 break; 2184 Py_DECREF(res); 2185 res = _PyObject_CallMethodId(file, &PyId_write, "y#", buf, n); 2186 if (res == NULL) 2187 break; 2188 } 2189 2190exit: 2191 fclose(fp); 2192 return res; 2193} 2194 2195/*[clinic input] 2196_curses.window.redrawln 2197 2198 beg: int 2199 Starting line number. 2200 num: int 2201 The number of lines. 2202 / 2203 2204Mark the specified lines corrupted. 2205 2206They should be completely redrawn on the next refresh() call. 2207[clinic start generated code]*/ 2208 2209static PyObject * 2210_curses_window_redrawln_impl(PyCursesWindowObject *self, int beg, int num) 2211/*[clinic end generated code: output=ea216e334f9ce1b4 input=152155e258a77a7a]*/ 2212{ 2213 return PyCursesCheckERR(wredrawln(self->win,beg,num), "redrawln"); 2214} 2215 2216/*[clinic input] 2217_curses.window.refresh 2218 2219 [ 2220 pminrow: int 2221 pmincol: int 2222 sminrow: int 2223 smincol: int 2224 smaxrow: int 2225 smaxcol: int 2226 ] 2227 / 2228 2229Update the display immediately. 2230 2231Synchronize actual screen with previous drawing/deleting methods. 2232The 6 optional arguments can only be specified when the window is a pad 2233created with newpad(). The additional parameters are needed to indicate 2234what part of the pad and screen are involved. pminrow and pmincol specify 2235the upper left-hand corner of the rectangle to be displayed in the pad. 2236sminrow, smincol, smaxrow, and smaxcol specify the edges of the rectangle to 2237be displayed on the screen. The lower right-hand corner of the rectangle to 2238be displayed in the pad is calculated from the screen coordinates, since the 2239rectangles must be the same size. Both rectangles must be entirely contained 2240within their respective structures. Negative values of pminrow, pmincol, 2241sminrow, or smincol are treated as if they were zero. 2242[clinic start generated code]*/ 2243 2244static PyObject * 2245_curses_window_refresh_impl(PyCursesWindowObject *self, int group_right_1, 2246 int pminrow, int pmincol, int sminrow, 2247 int smincol, int smaxrow, int smaxcol) 2248/*[clinic end generated code: output=42199543115e6e63 input=95e01cb5ffc635d0]*/ 2249{ 2250 int rtn; 2251 2252#ifdef py_is_pad 2253 if (py_is_pad(self->win)) { 2254 if (!group_right_1) { 2255 PyErr_SetString(PyCursesError, 2256 "refresh() for a pad requires 6 arguments"); 2257 return NULL; 2258 } 2259 Py_BEGIN_ALLOW_THREADS 2260 rtn = prefresh(self->win, pminrow, pmincol, 2261 sminrow, smincol, smaxrow, smaxcol); 2262 Py_END_ALLOW_THREADS 2263 return PyCursesCheckERR(rtn, "prefresh"); 2264 } 2265#endif 2266 if (group_right_1) { 2267 PyErr_SetString(PyExc_TypeError, 2268 "refresh() takes no arguments (6 given)"); 2269 return NULL; 2270 } 2271 Py_BEGIN_ALLOW_THREADS 2272 rtn = wrefresh(self->win); 2273 Py_END_ALLOW_THREADS 2274 return PyCursesCheckERR(rtn, "prefresh"); 2275} 2276 2277/*[clinic input] 2278_curses.window.setscrreg 2279 2280 top: int 2281 First line number. 2282 bottom: int 2283 Last line number. 2284 / 2285 2286Define a software scrolling region. 2287 2288All scrolling actions will take place in this region. 2289[clinic start generated code]*/ 2290 2291static PyObject * 2292_curses_window_setscrreg_impl(PyCursesWindowObject *self, int top, 2293 int bottom) 2294/*[clinic end generated code: output=486ab5db218d2b1a input=1b517b986838bf0e]*/ 2295{ 2296 return PyCursesCheckERR(wsetscrreg(self->win, top, bottom), "wsetscrreg"); 2297} 2298 2299/*[clinic input] 2300_curses.window.subwin 2301 2302 [ 2303 nlines: int = 0 2304 Height. 2305 ncols: int = 0 2306 Width. 2307 ] 2308 begin_y: int 2309 Top side y-coordinate. 2310 begin_x: int 2311 Left side x-coordinate. 2312 / 2313 2314Create a sub-window (screen-relative coordinates). 2315 2316By default, the sub-window will extend from the specified position to the 2317lower right corner of the window. 2318[clinic start generated code]*/ 2319 2320static PyObject * 2321_curses_window_subwin_impl(PyCursesWindowObject *self, int group_left_1, 2322 int nlines, int ncols, int begin_y, int begin_x) 2323/*[clinic end generated code: output=93e898afc348f59a input=2129fa47fd57721c]*/ 2324{ 2325 WINDOW *win; 2326 2327 /* printf("Subwin: %i %i %i %i \n", nlines, ncols, begin_y, begin_x); */ 2328#ifdef py_is_pad 2329 if (py_is_pad(self->win)) { 2330 win = subpad(self->win, nlines, ncols, begin_y, begin_x); 2331 } 2332 else 2333#endif 2334 win = subwin(self->win, nlines, ncols, begin_y, begin_x); 2335 2336 if (win == NULL) { 2337 PyErr_SetString(PyCursesError, catchall_NULL); 2338 return NULL; 2339 } 2340 2341 return (PyObject *)PyCursesWindow_New(win, self->encoding); 2342} 2343 2344/*[clinic input] 2345_curses.window.scroll 2346 2347 [ 2348 lines: int = 1 2349 Number of lines to scroll. 2350 ] 2351 / 2352 2353Scroll the screen or scrolling region. 2354 2355Scroll upward if the argument is positive and downward if it is negative. 2356[clinic start generated code]*/ 2357 2358static PyObject * 2359_curses_window_scroll_impl(PyCursesWindowObject *self, int group_right_1, 2360 int lines) 2361/*[clinic end generated code: output=4541a8a11852d360 input=c969ca0cfabbdbec]*/ 2362{ 2363 if (!group_right_1) { 2364 return PyCursesCheckERR(scroll(self->win), "scroll"); 2365 } 2366 else { 2367 return PyCursesCheckERR(wscrl(self->win, lines), "scroll"); 2368 } 2369} 2370 2371/*[clinic input] 2372_curses.window.touchline 2373 2374 start: int 2375 count: int 2376 [ 2377 changed: bool(accept={int}) = True 2378 ] 2379 / 2380 2381Pretend count lines have been changed, starting with line start. 2382 2383If changed is supplied, it specifies whether the affected lines are marked 2384as having been changed (changed=True) or unchanged (changed=False). 2385[clinic start generated code]*/ 2386 2387static PyObject * 2388_curses_window_touchline_impl(PyCursesWindowObject *self, int start, 2389 int count, int group_right_1, int changed) 2390/*[clinic end generated code: output=65d05b3f7438c61d input=918ad1cbdadf93ea]*/ 2391{ 2392 if (!group_right_1) { 2393 return PyCursesCheckERR(touchline(self->win, start, count), "touchline"); 2394 } 2395 else { 2396 return PyCursesCheckERR(wtouchln(self->win, start, count, changed), "touchline"); 2397 } 2398} 2399 2400/*[clinic input] 2401_curses.window.vline 2402 2403 [ 2404 y: int 2405 Starting Y-coordinate. 2406 x: int 2407 Starting X-coordinate. 2408 ] 2409 2410 ch: object 2411 Character to draw. 2412 n: int 2413 Line length. 2414 2415 [ 2416 attr: long(c_default="A_NORMAL") = _curses.A_NORMAL 2417 Attributes for the character. 2418 ] 2419 / 2420 2421Display a vertical line. 2422[clinic start generated code]*/ 2423 2424static PyObject * 2425_curses_window_vline_impl(PyCursesWindowObject *self, int group_left_1, 2426 int y, int x, PyObject *ch, int n, 2427 int group_right_1, long attr) 2428/*[clinic end generated code: output=287ad1cc8982217f input=a6f2dc86a4648b32]*/ 2429{ 2430 chtype ch_; 2431 2432 if (!PyCurses_ConvertToChtype(self, ch, &ch_)) 2433 return NULL; 2434 if (group_left_1) { 2435 if (wmove(self->win, y, x) == ERR) 2436 return PyCursesCheckERR(ERR, "wmove"); 2437 } 2438 return PyCursesCheckERR(wvline(self->win, ch_ | (attr_t)attr, n), "vline"); 2439} 2440 2441static PyObject * 2442PyCursesWindow_get_encoding(PyCursesWindowObject *self, void *closure) 2443{ 2444 return PyUnicode_FromString(self->encoding); 2445} 2446 2447static int 2448PyCursesWindow_set_encoding(PyCursesWindowObject *self, PyObject *value, void *Py_UNUSED(ignored)) 2449{ 2450 PyObject *ascii; 2451 char *encoding; 2452 2453 /* It is illegal to del win.encoding */ 2454 if (value == NULL) { 2455 PyErr_SetString(PyExc_TypeError, 2456 "encoding may not be deleted"); 2457 return -1; 2458 } 2459 2460 if (!PyUnicode_Check(value)) { 2461 PyErr_SetString(PyExc_TypeError, 2462 "setting encoding to a non-string"); 2463 return -1; 2464 } 2465 ascii = PyUnicode_AsASCIIString(value); 2466 if (ascii == NULL) 2467 return -1; 2468 encoding = _PyMem_Strdup(PyBytes_AS_STRING(ascii)); 2469 Py_DECREF(ascii); 2470 if (encoding == NULL) { 2471 PyErr_NoMemory(); 2472 return -1; 2473 } 2474 PyMem_Free(self->encoding); 2475 self->encoding = encoding; 2476 return 0; 2477} 2478 2479#include "clinic/_cursesmodule.c.h" 2480 2481static PyMethodDef PyCursesWindow_Methods[] = { 2482 _CURSES_WINDOW_ADDCH_METHODDEF 2483 _CURSES_WINDOW_ADDNSTR_METHODDEF 2484 _CURSES_WINDOW_ADDSTR_METHODDEF 2485 _CURSES_WINDOW_ATTROFF_METHODDEF 2486 _CURSES_WINDOW_ATTRON_METHODDEF 2487 _CURSES_WINDOW_ATTRSET_METHODDEF 2488 _CURSES_WINDOW_BKGD_METHODDEF 2489#ifdef HAVE_CURSES_WCHGAT 2490 {"chgat", (PyCFunction)PyCursesWindow_ChgAt, METH_VARARGS}, 2491#endif 2492 _CURSES_WINDOW_BKGDSET_METHODDEF 2493 _CURSES_WINDOW_BORDER_METHODDEF 2494 _CURSES_WINDOW_BOX_METHODDEF 2495 {"clear", (PyCFunction)PyCursesWindow_wclear, METH_NOARGS}, 2496 {"clearok", (PyCFunction)PyCursesWindow_clearok, METH_VARARGS}, 2497 {"clrtobot", (PyCFunction)PyCursesWindow_wclrtobot, METH_NOARGS}, 2498 {"clrtoeol", (PyCFunction)PyCursesWindow_wclrtoeol, METH_NOARGS}, 2499 {"cursyncup", (PyCFunction)PyCursesWindow_wcursyncup, METH_NOARGS}, 2500 _CURSES_WINDOW_DELCH_METHODDEF 2501 {"deleteln", (PyCFunction)PyCursesWindow_wdeleteln, METH_NOARGS}, 2502 _CURSES_WINDOW_DERWIN_METHODDEF 2503 _CURSES_WINDOW_ECHOCHAR_METHODDEF 2504 _CURSES_WINDOW_ENCLOSE_METHODDEF 2505 {"erase", (PyCFunction)PyCursesWindow_werase, METH_NOARGS}, 2506 {"getbegyx", (PyCFunction)PyCursesWindow_getbegyx, METH_NOARGS}, 2507 _CURSES_WINDOW_GETBKGD_METHODDEF 2508 _CURSES_WINDOW_GETCH_METHODDEF 2509 _CURSES_WINDOW_GETKEY_METHODDEF 2510 _CURSES_WINDOW_GET_WCH_METHODDEF 2511 {"getmaxyx", (PyCFunction)PyCursesWindow_getmaxyx, METH_NOARGS}, 2512 {"getparyx", (PyCFunction)PyCursesWindow_getparyx, METH_NOARGS}, 2513 {"getstr", (PyCFunction)PyCursesWindow_GetStr, METH_VARARGS}, 2514 {"getyx", (PyCFunction)PyCursesWindow_getyx, METH_NOARGS}, 2515 _CURSES_WINDOW_HLINE_METHODDEF 2516 {"idcok", (PyCFunction)PyCursesWindow_idcok, METH_VARARGS}, 2517 {"idlok", (PyCFunction)PyCursesWindow_idlok, METH_VARARGS}, 2518#ifdef HAVE_CURSES_IMMEDOK 2519 {"immedok", (PyCFunction)PyCursesWindow_immedok, METH_VARARGS}, 2520#endif 2521 _CURSES_WINDOW_INCH_METHODDEF 2522 _CURSES_WINDOW_INSCH_METHODDEF 2523 {"insdelln", (PyCFunction)PyCursesWindow_winsdelln, METH_VARARGS}, 2524 {"insertln", (PyCFunction)PyCursesWindow_winsertln, METH_NOARGS}, 2525 _CURSES_WINDOW_INSNSTR_METHODDEF 2526 _CURSES_WINDOW_INSSTR_METHODDEF 2527 {"instr", (PyCFunction)PyCursesWindow_InStr, METH_VARARGS}, 2528 _CURSES_WINDOW_IS_LINETOUCHED_METHODDEF 2529 {"is_wintouched", (PyCFunction)PyCursesWindow_is_wintouched, METH_NOARGS}, 2530 {"keypad", (PyCFunction)PyCursesWindow_keypad, METH_VARARGS}, 2531 {"leaveok", (PyCFunction)PyCursesWindow_leaveok, METH_VARARGS}, 2532 {"move", (PyCFunction)PyCursesWindow_wmove, METH_VARARGS}, 2533 {"mvderwin", (PyCFunction)PyCursesWindow_mvderwin, METH_VARARGS}, 2534 {"mvwin", (PyCFunction)PyCursesWindow_mvwin, METH_VARARGS}, 2535 {"nodelay", (PyCFunction)PyCursesWindow_nodelay, METH_VARARGS}, 2536 {"notimeout", (PyCFunction)PyCursesWindow_notimeout, METH_VARARGS}, 2537 _CURSES_WINDOW_NOUTREFRESH_METHODDEF 2538 _CURSES_WINDOW_OVERLAY_METHODDEF 2539 _CURSES_WINDOW_OVERWRITE_METHODDEF 2540 _CURSES_WINDOW_PUTWIN_METHODDEF 2541 _CURSES_WINDOW_REDRAWLN_METHODDEF 2542 {"redrawwin", (PyCFunction)PyCursesWindow_redrawwin, METH_NOARGS}, 2543 _CURSES_WINDOW_REFRESH_METHODDEF 2544#ifndef STRICT_SYSV_CURSES 2545 {"resize", (PyCFunction)PyCursesWindow_wresize, METH_VARARGS}, 2546#endif 2547 _CURSES_WINDOW_SCROLL_METHODDEF 2548 {"scrollok", (PyCFunction)PyCursesWindow_scrollok, METH_VARARGS}, 2549 _CURSES_WINDOW_SETSCRREG_METHODDEF 2550 {"standend", (PyCFunction)PyCursesWindow_wstandend, METH_NOARGS}, 2551 {"standout", (PyCFunction)PyCursesWindow_wstandout, METH_NOARGS}, 2552 {"subpad", (PyCFunction)_curses_window_subwin, METH_VARARGS, _curses_window_subwin__doc__}, 2553 _CURSES_WINDOW_SUBWIN_METHODDEF 2554 {"syncdown", (PyCFunction)PyCursesWindow_wsyncdown, METH_NOARGS}, 2555#ifdef HAVE_CURSES_SYNCOK 2556 {"syncok", (PyCFunction)PyCursesWindow_syncok, METH_VARARGS}, 2557#endif 2558 {"syncup", (PyCFunction)PyCursesWindow_wsyncup, METH_NOARGS}, 2559 {"timeout", (PyCFunction)PyCursesWindow_wtimeout, METH_VARARGS}, 2560 _CURSES_WINDOW_TOUCHLINE_METHODDEF 2561 {"touchwin", (PyCFunction)PyCursesWindow_touchwin, METH_NOARGS}, 2562 {"untouchwin", (PyCFunction)PyCursesWindow_untouchwin, METH_NOARGS}, 2563 _CURSES_WINDOW_VLINE_METHODDEF 2564 {NULL, NULL} /* sentinel */ 2565}; 2566 2567static PyGetSetDef PyCursesWindow_getsets[] = { 2568 {"encoding", 2569 (getter)PyCursesWindow_get_encoding, 2570 (setter)PyCursesWindow_set_encoding, 2571 "the typecode character used to create the array"}, 2572 {NULL, NULL, NULL, NULL } /* sentinel */ 2573}; 2574 2575/* -------------------------------------------------------*/ 2576 2577PyTypeObject PyCursesWindow_Type = { 2578 PyVarObject_HEAD_INIT(NULL, 0) 2579 "_curses.window", /*tp_name*/ 2580 sizeof(PyCursesWindowObject), /*tp_basicsize*/ 2581 0, /*tp_itemsize*/ 2582 /* methods */ 2583 (destructor)PyCursesWindow_Dealloc, /*tp_dealloc*/ 2584 0, /*tp_vectorcall_offset*/ 2585 (getattrfunc)0, /*tp_getattr*/ 2586 (setattrfunc)0, /*tp_setattr*/ 2587 0, /*tp_as_async*/ 2588 0, /*tp_repr*/ 2589 0, /*tp_as_number*/ 2590 0, /*tp_as_sequence*/ 2591 0, /*tp_as_mapping*/ 2592 0, /*tp_hash*/ 2593 0, /*tp_call*/ 2594 0, /*tp_str*/ 2595 0, /*tp_getattro*/ 2596 0, /*tp_setattro*/ 2597 0, /*tp_as_buffer*/ 2598 Py_TPFLAGS_DEFAULT, /*tp_flags*/ 2599 0, /*tp_doc*/ 2600 0, /*tp_traverse*/ 2601 0, /*tp_clear*/ 2602 0, /*tp_richcompare*/ 2603 0, /*tp_weaklistoffset*/ 2604 0, /*tp_iter*/ 2605 0, /*tp_iternext*/ 2606 PyCursesWindow_Methods, /*tp_methods*/ 2607 0, /* tp_members */ 2608 PyCursesWindow_getsets, /* tp_getset */ 2609}; 2610 2611/* Function Prototype Macros - They are ugly but very, very useful. ;-) 2612 2613 X - function name 2614 TYPE - parameter Type 2615 ERGSTR - format string for construction of the return value 2616 PARSESTR - format string for argument parsing 2617 */ 2618 2619#define NoArgNoReturnFunctionBody(X) \ 2620{ \ 2621 PyCursesInitialised \ 2622 return PyCursesCheckERR(X(), # X); } 2623 2624#define NoArgOrFlagNoReturnFunctionBody(X, flag) \ 2625{ \ 2626 PyCursesInitialised \ 2627 if (flag) \ 2628 return PyCursesCheckERR(X(), # X); \ 2629 else \ 2630 return PyCursesCheckERR(no ## X(), # X); \ 2631} 2632 2633#define NoArgReturnIntFunctionBody(X) \ 2634{ \ 2635 PyCursesInitialised \ 2636 return PyLong_FromLong((long) X()); } 2637 2638 2639#define NoArgReturnStringFunctionBody(X) \ 2640{ \ 2641 PyCursesInitialised \ 2642 return PyBytes_FromString(X()); } 2643 2644#define NoArgTrueFalseFunctionBody(X) \ 2645{ \ 2646 PyCursesInitialised \ 2647 return PyBool_FromLong(X()); } 2648 2649#define NoArgNoReturnVoidFunctionBody(X) \ 2650{ \ 2651 PyCursesInitialised \ 2652 X(); \ 2653 Py_RETURN_NONE; } 2654 2655/********************************************************************* 2656 Global Functions 2657**********************************************************************/ 2658 2659#ifdef HAVE_CURSES_FILTER 2660/*[clinic input] 2661_curses.filter 2662 2663[clinic start generated code]*/ 2664 2665static PyObject * 2666_curses_filter_impl(PyObject *module) 2667/*[clinic end generated code: output=fb5b8a3642eb70b5 input=668c75a6992d3624]*/ 2668{ 2669 /* not checking for PyCursesInitialised here since filter() must 2670 be called before initscr() */ 2671 filter(); 2672 Py_RETURN_NONE; 2673} 2674#endif 2675 2676/*[clinic input] 2677_curses.baudrate 2678 2679Return the output speed of the terminal in bits per second. 2680[clinic start generated code]*/ 2681 2682static PyObject * 2683_curses_baudrate_impl(PyObject *module) 2684/*[clinic end generated code: output=3c63c6c401d7d9c0 input=921f022ed04a0fd9]*/ 2685NoArgReturnIntFunctionBody(baudrate) 2686 2687/*[clinic input] 2688_curses.beep 2689 2690Emit a short attention sound. 2691[clinic start generated code]*/ 2692 2693static PyObject * 2694_curses_beep_impl(PyObject *module) 2695/*[clinic end generated code: output=425274962abe49a2 input=a35698ca7d0162bc]*/ 2696NoArgNoReturnFunctionBody(beep) 2697 2698/*[clinic input] 2699_curses.can_change_color 2700 2701Return True if the programmer can change the colors displayed by the terminal. 2702[clinic start generated code]*/ 2703 2704static PyObject * 2705_curses_can_change_color_impl(PyObject *module) 2706/*[clinic end generated code: output=359df8c3c77d8bf1 input=d7718884de0092f2]*/ 2707NoArgTrueFalseFunctionBody(can_change_color) 2708 2709/*[clinic input] 2710_curses.cbreak 2711 2712 flag: bool(accept={int}) = True 2713 If false, the effect is the same as calling nocbreak(). 2714 / 2715 2716Enter cbreak mode. 2717 2718In cbreak mode (sometimes called "rare" mode) normal tty line buffering is 2719turned off and characters are available to be read one by one. However, 2720unlike raw mode, special characters (interrupt, quit, suspend, and flow 2721control) retain their effects on the tty driver and calling program. 2722Calling first raw() then cbreak() leaves the terminal in cbreak mode. 2723[clinic start generated code]*/ 2724 2725static PyObject * 2726_curses_cbreak_impl(PyObject *module, int flag) 2727/*[clinic end generated code: output=9f9dee9664769751 input=150be619eb1f1458]*/ 2728NoArgOrFlagNoReturnFunctionBody(cbreak, flag) 2729 2730/*[clinic input] 2731_curses.color_content 2732 2733 color_number: color 2734 The number of the color (0 - (COLORS-1)). 2735 / 2736 2737Return the red, green, and blue (RGB) components of the specified color. 2738 2739A 3-tuple is returned, containing the R, G, B values for the given color, 2740which will be between 0 (no component) and 1000 (maximum amount of component). 2741[clinic start generated code]*/ 2742 2743static PyObject * 2744_curses_color_content_impl(PyObject *module, int color_number) 2745/*[clinic end generated code: output=17b466df7054e0de input=03b5ed0472662aea]*/ 2746{ 2747 _CURSES_COLOR_VAL_TYPE r,g,b; 2748 2749 PyCursesInitialised; 2750 PyCursesInitialisedColor; 2751 2752 if (_COLOR_CONTENT_FUNC(color_number, &r, &g, &b) == ERR) { 2753 PyErr_Format(PyCursesError, "%s() returned ERR", 2754 Py_STRINGIFY(_COLOR_CONTENT_FUNC)); 2755 return NULL; 2756 } 2757 2758 return Py_BuildValue("(iii)", r, g, b); 2759} 2760 2761/*[clinic input] 2762_curses.color_pair 2763 2764 pair_number: int 2765 The number of the color pair. 2766 / 2767 2768Return the attribute value for displaying text in the specified color. 2769 2770This attribute value can be combined with A_STANDOUT, A_REVERSE, and the 2771other A_* attributes. pair_number() is the counterpart to this function. 2772[clinic start generated code]*/ 2773 2774static PyObject * 2775_curses_color_pair_impl(PyObject *module, int pair_number) 2776/*[clinic end generated code: output=60718abb10ce9feb input=6034e9146f343802]*/ 2777{ 2778 PyCursesInitialised; 2779 PyCursesInitialisedColor; 2780 2781 return PyLong_FromLong(COLOR_PAIR(pair_number)); 2782} 2783 2784/*[clinic input] 2785_curses.curs_set 2786 2787 visibility: int 2788 0 for invisible, 1 for normal visible, or 2 for very visible. 2789 / 2790 2791Set the cursor state. 2792 2793If the terminal supports the visibility requested, the previous cursor 2794state is returned; otherwise, an exception is raised. On many terminals, 2795the "visible" mode is an underline cursor and the "very visible" mode is 2796a block cursor. 2797[clinic start generated code]*/ 2798 2799static PyObject * 2800_curses_curs_set_impl(PyObject *module, int visibility) 2801/*[clinic end generated code: output=ee8e62483b1d6cd4 input=81a7924a65d29504]*/ 2802{ 2803 int erg; 2804 2805 PyCursesInitialised; 2806 2807 erg = curs_set(visibility); 2808 if (erg == ERR) return PyCursesCheckERR(erg, "curs_set"); 2809 2810 return PyLong_FromLong((long) erg); 2811} 2812 2813/*[clinic input] 2814_curses.def_prog_mode 2815 2816Save the current terminal mode as the "program" mode. 2817 2818The "program" mode is the mode when the running program is using curses. 2819 2820Subsequent calls to reset_prog_mode() will restore this mode. 2821[clinic start generated code]*/ 2822 2823static PyObject * 2824_curses_def_prog_mode_impl(PyObject *module) 2825/*[clinic end generated code: output=05d5a351fff874aa input=768b9cace620dda5]*/ 2826NoArgNoReturnFunctionBody(def_prog_mode) 2827 2828/*[clinic input] 2829_curses.def_shell_mode 2830 2831Save the current terminal mode as the "shell" mode. 2832 2833The "shell" mode is the mode when the running program is not using curses. 2834 2835Subsequent calls to reset_shell_mode() will restore this mode. 2836[clinic start generated code]*/ 2837 2838static PyObject * 2839_curses_def_shell_mode_impl(PyObject *module) 2840/*[clinic end generated code: output=d6e42f5c768f860f input=5ead21f6f0baa894]*/ 2841NoArgNoReturnFunctionBody(def_shell_mode) 2842 2843/*[clinic input] 2844_curses.delay_output 2845 2846 ms: int 2847 Duration in milliseconds. 2848 / 2849 2850Insert a pause in output. 2851[clinic start generated code]*/ 2852 2853static PyObject * 2854_curses_delay_output_impl(PyObject *module, int ms) 2855/*[clinic end generated code: output=b6613a67f17fa4f4 input=5316457f5f59196c]*/ 2856{ 2857 PyCursesInitialised; 2858 2859 return PyCursesCheckERR(delay_output(ms), "delay_output"); 2860} 2861 2862/*[clinic input] 2863_curses.doupdate 2864 2865Update the physical screen to match the virtual screen. 2866[clinic start generated code]*/ 2867 2868static PyObject * 2869_curses_doupdate_impl(PyObject *module) 2870/*[clinic end generated code: output=f34536975a75680c input=8da80914432a6489]*/ 2871NoArgNoReturnFunctionBody(doupdate) 2872 2873/*[clinic input] 2874_curses.echo 2875 2876 flag: bool(accept={int}) = True 2877 If false, the effect is the same as calling noecho(). 2878 / 2879 2880Enter echo mode. 2881 2882In echo mode, each character input is echoed to the screen as it is entered. 2883[clinic start generated code]*/ 2884 2885static PyObject * 2886_curses_echo_impl(PyObject *module, int flag) 2887/*[clinic end generated code: output=03acb2ddfa6c8729 input=2e9e891d637eac5d]*/ 2888NoArgOrFlagNoReturnFunctionBody(echo, flag) 2889 2890/*[clinic input] 2891_curses.endwin 2892 2893De-initialize the library, and return terminal to normal status. 2894[clinic start generated code]*/ 2895 2896static PyObject * 2897_curses_endwin_impl(PyObject *module) 2898/*[clinic end generated code: output=c0150cd96d2f4128 input=e172cfa43062f3fa]*/ 2899NoArgNoReturnFunctionBody(endwin) 2900 2901/*[clinic input] 2902_curses.erasechar 2903 2904Return the user's current erase character. 2905[clinic start generated code]*/ 2906 2907static PyObject * 2908_curses_erasechar_impl(PyObject *module) 2909/*[clinic end generated code: output=3df305dc6b926b3f input=628c136c3c5758d3]*/ 2910{ 2911 char ch; 2912 2913 PyCursesInitialised; 2914 2915 ch = erasechar(); 2916 2917 return PyBytes_FromStringAndSize(&ch, 1); 2918} 2919 2920/*[clinic input] 2921_curses.flash 2922 2923Flash the screen. 2924 2925That is, change it to reverse-video and then change it back in a short interval. 2926[clinic start generated code]*/ 2927 2928static PyObject * 2929_curses_flash_impl(PyObject *module) 2930/*[clinic end generated code: output=488b8a0ebd9ea9b8 input=02fdfb06c8fc3171]*/ 2931NoArgNoReturnFunctionBody(flash) 2932 2933/*[clinic input] 2934_curses.flushinp 2935 2936Flush all input buffers. 2937 2938This throws away any typeahead that has been typed by the user and has not 2939yet been processed by the program. 2940[clinic start generated code]*/ 2941 2942static PyObject * 2943_curses_flushinp_impl(PyObject *module) 2944/*[clinic end generated code: output=7e7a1fc1473960f5 input=59d042e705cef5ec]*/ 2945NoArgNoReturnVoidFunctionBody(flushinp) 2946 2947#ifdef getsyx 2948/*[clinic input] 2949_curses.getsyx 2950 2951Return the current coordinates of the virtual screen cursor. 2952 2953Return a (y, x) tuple. If leaveok is currently true, return (-1, -1). 2954[clinic start generated code]*/ 2955 2956static PyObject * 2957_curses_getsyx_impl(PyObject *module) 2958/*[clinic end generated code: output=c8e6c3f42349a038 input=9e1f862f3b4f7cba]*/ 2959{ 2960 int x = 0; 2961 int y = 0; 2962 2963 PyCursesInitialised; 2964 2965 getsyx(y, x); 2966 2967 return Py_BuildValue("(ii)", y, x); 2968} 2969#endif 2970 2971#ifdef NCURSES_MOUSE_VERSION 2972/*[clinic input] 2973_curses.getmouse 2974 2975Retrieve the queued mouse event. 2976 2977After getch() returns KEY_MOUSE to signal a mouse event, this function 2978returns a 5-tuple (id, x, y, z, bstate). 2979[clinic start generated code]*/ 2980 2981static PyObject * 2982_curses_getmouse_impl(PyObject *module) 2983/*[clinic end generated code: output=ccf4242546b9cfa8 input=5b756ee6f5b481b1]*/ 2984{ 2985 int rtn; 2986 MEVENT event; 2987 2988 PyCursesInitialised; 2989 2990 rtn = getmouse( &event ); 2991 if (rtn == ERR) { 2992 PyErr_SetString(PyCursesError, "getmouse() returned ERR"); 2993 return NULL; 2994 } 2995 return Py_BuildValue("(hiiik)", 2996 (short)event.id, 2997 (int)event.x, (int)event.y, (int)event.z, 2998 (unsigned long) event.bstate); 2999} 3000 3001/*[clinic input] 3002_curses.ungetmouse 3003 3004 id: short 3005 x: int 3006 y: int 3007 z: int 3008 bstate: unsigned_long(bitwise=True) 3009 / 3010 3011Push a KEY_MOUSE event onto the input queue. 3012 3013The following getmouse() will return the given state data. 3014[clinic start generated code]*/ 3015 3016static PyObject * 3017_curses_ungetmouse_impl(PyObject *module, short id, int x, int y, int z, 3018 unsigned long bstate) 3019/*[clinic end generated code: output=3430c9b0fc5c4341 input=fd650b2ca5a01e8f]*/ 3020{ 3021 MEVENT event; 3022 3023 PyCursesInitialised; 3024 3025 event.id = id; 3026 event.x = x; 3027 event.y = y; 3028 event.z = z; 3029 event.bstate = bstate; 3030 return PyCursesCheckERR(ungetmouse(&event), "ungetmouse"); 3031} 3032#endif 3033 3034/*[clinic input] 3035_curses.getwin 3036 3037 file: object 3038 / 3039 3040Read window related data stored in the file by an earlier putwin() call. 3041 3042The routine then creates and initializes a new window using that data, 3043returning the new window object. 3044[clinic start generated code]*/ 3045 3046static PyObject * 3047_curses_getwin(PyObject *module, PyObject *file) 3048/*[clinic end generated code: output=a79e0df3379af756 input=f713d2bba0e4c929]*/ 3049{ 3050 FILE *fp; 3051 PyObject *data; 3052 size_t datalen; 3053 WINDOW *win; 3054 _Py_IDENTIFIER(read); 3055 PyObject *res = NULL; 3056 3057 PyCursesInitialised; 3058 3059 fp = tmpfile(); 3060 if (fp == NULL) 3061 return PyErr_SetFromErrno(PyExc_OSError); 3062 3063 if (_Py_set_inheritable(fileno(fp), 0, NULL) < 0) 3064 goto error; 3065 3066 data = _PyObject_CallMethodIdNoArgs(file, &PyId_read); 3067 if (data == NULL) 3068 goto error; 3069 if (!PyBytes_Check(data)) { 3070 PyErr_Format(PyExc_TypeError, 3071 "f.read() returned %.100s instead of bytes", 3072 Py_TYPE(data)->tp_name); 3073 Py_DECREF(data); 3074 goto error; 3075 } 3076 datalen = PyBytes_GET_SIZE(data); 3077 if (fwrite(PyBytes_AS_STRING(data), 1, datalen, fp) != datalen) { 3078 Py_DECREF(data); 3079 PyErr_SetFromErrno(PyExc_OSError); 3080 goto error; 3081 } 3082 Py_DECREF(data); 3083 3084 fseek(fp, 0, 0); 3085 win = getwin(fp); 3086 if (win == NULL) { 3087 PyErr_SetString(PyCursesError, catchall_NULL); 3088 goto error; 3089 } 3090 res = PyCursesWindow_New(win, NULL); 3091 3092error: 3093 fclose(fp); 3094 return res; 3095} 3096 3097/*[clinic input] 3098_curses.halfdelay 3099 3100 tenths: byte 3101 Maximal blocking delay in tenths of seconds (1 - 255). 3102 / 3103 3104Enter half-delay mode. 3105 3106Use nocbreak() to leave half-delay mode. 3107[clinic start generated code]*/ 3108 3109static PyObject * 3110_curses_halfdelay_impl(PyObject *module, unsigned char tenths) 3111/*[clinic end generated code: output=e92cdf0ef33c0663 input=e42dce7259c15100]*/ 3112{ 3113 PyCursesInitialised; 3114 3115 return PyCursesCheckERR(halfdelay(tenths), "halfdelay"); 3116} 3117 3118/*[clinic input] 3119_curses.has_colors 3120 3121Return True if the terminal can display colors; otherwise, return False. 3122[clinic start generated code]*/ 3123 3124static PyObject * 3125_curses_has_colors_impl(PyObject *module) 3126/*[clinic end generated code: output=db5667483139e3e2 input=b2ec41b739d896c6]*/ 3127NoArgTrueFalseFunctionBody(has_colors) 3128 3129/*[clinic input] 3130_curses.has_ic 3131 3132Return True if the terminal has insert- and delete-character capabilities. 3133[clinic start generated code]*/ 3134 3135static PyObject * 3136_curses_has_ic_impl(PyObject *module) 3137/*[clinic end generated code: output=6be24da9cb1268fe input=9bc2d3a797cc7324]*/ 3138NoArgTrueFalseFunctionBody(has_ic) 3139 3140/*[clinic input] 3141_curses.has_il 3142 3143Return True if the terminal has insert- and delete-line capabilities. 3144[clinic start generated code]*/ 3145 3146static PyObject * 3147_curses_has_il_impl(PyObject *module) 3148/*[clinic end generated code: output=d45bd7788ff9f5f4 input=cd939d5607ee5427]*/ 3149NoArgTrueFalseFunctionBody(has_il) 3150 3151#ifdef HAVE_CURSES_HAS_KEY 3152/*[clinic input] 3153_curses.has_key 3154 3155 key: int 3156 Key number. 3157 / 3158 3159Return True if the current terminal type recognizes a key with that value. 3160[clinic start generated code]*/ 3161 3162static PyObject * 3163_curses_has_key_impl(PyObject *module, int key) 3164/*[clinic end generated code: output=19ad48319414d0b1 input=78bd44acf1a4997c]*/ 3165{ 3166 PyCursesInitialised; 3167 3168 return PyBool_FromLong(has_key(key)); 3169} 3170#endif 3171 3172/*[clinic input] 3173_curses.init_color 3174 3175 color_number: color 3176 The number of the color to be changed (0 - (COLORS-1)). 3177 r: component 3178 Red component (0 - 1000). 3179 g: component 3180 Green component (0 - 1000). 3181 b: component 3182 Blue component (0 - 1000). 3183 / 3184 3185Change the definition of a color. 3186 3187When init_color() is used, all occurrences of that color on the screen 3188immediately change to the new definition. This function is a no-op on 3189most terminals; it is active only if can_change_color() returns true. 3190[clinic start generated code]*/ 3191 3192static PyObject * 3193_curses_init_color_impl(PyObject *module, int color_number, short r, short g, 3194 short b) 3195/*[clinic end generated code: output=d7ed71b2d818cdf2 input=ae2b8bea0f152c80]*/ 3196{ 3197 PyCursesInitialised; 3198 PyCursesInitialisedColor; 3199 3200 return PyCursesCheckERR(_CURSES_INIT_COLOR_FUNC(color_number, r, g, b), 3201 Py_STRINGIFY(_CURSES_INIT_COLOR_FUNC)); 3202} 3203 3204/*[clinic input] 3205_curses.init_pair 3206 3207 pair_number: pair 3208 The number of the color-pair to be changed (1 - (COLOR_PAIRS-1)). 3209 fg: color_allow_default 3210 Foreground color number (-1 - (COLORS-1)). 3211 bg: color_allow_default 3212 Background color number (-1 - (COLORS-1)). 3213 / 3214 3215Change the definition of a color-pair. 3216 3217If the color-pair was previously initialized, the screen is refreshed and 3218all occurrences of that color-pair are changed to the new definition. 3219[clinic start generated code]*/ 3220 3221static PyObject * 3222_curses_init_pair_impl(PyObject *module, int pair_number, int fg, int bg) 3223/*[clinic end generated code: output=a0bba03d2bbc3ee6 input=54b421b44c12c389]*/ 3224{ 3225 PyCursesInitialised; 3226 PyCursesInitialisedColor; 3227 3228 if (_CURSES_INIT_PAIR_FUNC(pair_number, fg, bg) == ERR) { 3229 if (pair_number >= COLOR_PAIRS) { 3230 PyErr_Format(PyExc_ValueError, 3231 "Color pair is greater than COLOR_PAIRS-1 (%d).", 3232 COLOR_PAIRS - 1); 3233 } 3234 else { 3235 PyErr_Format(PyCursesError, "%s() returned ERR", 3236 Py_STRINGIFY(_CURSES_INIT_PAIR_FUNC)); 3237 } 3238 return NULL; 3239 } 3240 3241 Py_RETURN_NONE; 3242} 3243 3244static PyObject *ModDict; 3245 3246/*[clinic input] 3247_curses.initscr 3248 3249Initialize the library. 3250 3251Return a WindowObject which represents the whole screen. 3252[clinic start generated code]*/ 3253 3254static PyObject * 3255_curses_initscr_impl(PyObject *module) 3256/*[clinic end generated code: output=619fb68443810b7b input=514f4bce1821f6b5]*/ 3257{ 3258 WINDOW *win; 3259 PyCursesWindowObject *winobj; 3260 3261 if (initialised) { 3262 wrefresh(stdscr); 3263 return (PyObject *)PyCursesWindow_New(stdscr, NULL); 3264 } 3265 3266 win = initscr(); 3267 3268 if (win == NULL) { 3269 PyErr_SetString(PyCursesError, catchall_NULL); 3270 return NULL; 3271 } 3272 3273 initialised = initialised_setupterm = TRUE; 3274 3275/* This was moved from initcurses() because it core dumped on SGI, 3276 where they're not defined until you've called initscr() */ 3277#define SetDictInt(string,ch) \ 3278 do { \ 3279 PyObject *o = PyLong_FromLong((long) (ch)); \ 3280 if (o && PyDict_SetItemString(ModDict, string, o) == 0) { \ 3281 Py_DECREF(o); \ 3282 } \ 3283 } while (0) 3284 3285 /* Here are some graphic symbols you can use */ 3286 SetDictInt("ACS_ULCORNER", (ACS_ULCORNER)); 3287 SetDictInt("ACS_LLCORNER", (ACS_LLCORNER)); 3288 SetDictInt("ACS_URCORNER", (ACS_URCORNER)); 3289 SetDictInt("ACS_LRCORNER", (ACS_LRCORNER)); 3290 SetDictInt("ACS_LTEE", (ACS_LTEE)); 3291 SetDictInt("ACS_RTEE", (ACS_RTEE)); 3292 SetDictInt("ACS_BTEE", (ACS_BTEE)); 3293 SetDictInt("ACS_TTEE", (ACS_TTEE)); 3294 SetDictInt("ACS_HLINE", (ACS_HLINE)); 3295 SetDictInt("ACS_VLINE", (ACS_VLINE)); 3296 SetDictInt("ACS_PLUS", (ACS_PLUS)); 3297#if !defined(__hpux) || defined(HAVE_NCURSES_H) 3298 /* On HP/UX 11, these are of type cchar_t, which is not an 3299 integral type. If this is a problem on more platforms, a 3300 configure test should be added to determine whether ACS_S1 3301 is of integral type. */ 3302 SetDictInt("ACS_S1", (ACS_S1)); 3303 SetDictInt("ACS_S9", (ACS_S9)); 3304 SetDictInt("ACS_DIAMOND", (ACS_DIAMOND)); 3305 SetDictInt("ACS_CKBOARD", (ACS_CKBOARD)); 3306 SetDictInt("ACS_DEGREE", (ACS_DEGREE)); 3307 SetDictInt("ACS_PLMINUS", (ACS_PLMINUS)); 3308 SetDictInt("ACS_BULLET", (ACS_BULLET)); 3309 SetDictInt("ACS_LARROW", (ACS_LARROW)); 3310 SetDictInt("ACS_RARROW", (ACS_RARROW)); 3311 SetDictInt("ACS_DARROW", (ACS_DARROW)); 3312 SetDictInt("ACS_UARROW", (ACS_UARROW)); 3313 SetDictInt("ACS_BOARD", (ACS_BOARD)); 3314 SetDictInt("ACS_LANTERN", (ACS_LANTERN)); 3315 SetDictInt("ACS_BLOCK", (ACS_BLOCK)); 3316#endif 3317 SetDictInt("ACS_BSSB", (ACS_ULCORNER)); 3318 SetDictInt("ACS_SSBB", (ACS_LLCORNER)); 3319 SetDictInt("ACS_BBSS", (ACS_URCORNER)); 3320 SetDictInt("ACS_SBBS", (ACS_LRCORNER)); 3321 SetDictInt("ACS_SBSS", (ACS_RTEE)); 3322 SetDictInt("ACS_SSSB", (ACS_LTEE)); 3323 SetDictInt("ACS_SSBS", (ACS_BTEE)); 3324 SetDictInt("ACS_BSSS", (ACS_TTEE)); 3325 SetDictInt("ACS_BSBS", (ACS_HLINE)); 3326 SetDictInt("ACS_SBSB", (ACS_VLINE)); 3327 SetDictInt("ACS_SSSS", (ACS_PLUS)); 3328 3329 /* The following are never available with strict SYSV curses */ 3330#ifdef ACS_S3 3331 SetDictInt("ACS_S3", (ACS_S3)); 3332#endif 3333#ifdef ACS_S7 3334 SetDictInt("ACS_S7", (ACS_S7)); 3335#endif 3336#ifdef ACS_LEQUAL 3337 SetDictInt("ACS_LEQUAL", (ACS_LEQUAL)); 3338#endif 3339#ifdef ACS_GEQUAL 3340 SetDictInt("ACS_GEQUAL", (ACS_GEQUAL)); 3341#endif 3342#ifdef ACS_PI 3343 SetDictInt("ACS_PI", (ACS_PI)); 3344#endif 3345#ifdef ACS_NEQUAL 3346 SetDictInt("ACS_NEQUAL", (ACS_NEQUAL)); 3347#endif 3348#ifdef ACS_STERLING 3349 SetDictInt("ACS_STERLING", (ACS_STERLING)); 3350#endif 3351 3352 SetDictInt("LINES", LINES); 3353 SetDictInt("COLS", COLS); 3354 3355 winobj = (PyCursesWindowObject *)PyCursesWindow_New(win, NULL); 3356 screen_encoding = winobj->encoding; 3357 return (PyObject *)winobj; 3358} 3359 3360/*[clinic input] 3361_curses.setupterm 3362 3363 term: str(accept={str, NoneType}) = None 3364 Terminal name. 3365 If omitted, the value of the TERM environment variable will be used. 3366 fd: int = -1 3367 File descriptor to which any initialization sequences will be sent. 3368 If not supplied, the file descriptor for sys.stdout will be used. 3369 3370Initialize the terminal. 3371[clinic start generated code]*/ 3372 3373static PyObject * 3374_curses_setupterm_impl(PyObject *module, const char *term, int fd) 3375/*[clinic end generated code: output=4584e587350f2848 input=4511472766af0c12]*/ 3376{ 3377 int err; 3378 3379 if (fd == -1) { 3380 PyObject* sys_stdout; 3381 3382 sys_stdout = PySys_GetObject("stdout"); 3383 3384 if (sys_stdout == NULL || sys_stdout == Py_None) { 3385 PyErr_SetString( 3386 PyCursesError, 3387 "lost sys.stdout"); 3388 return NULL; 3389 } 3390 3391 fd = PyObject_AsFileDescriptor(sys_stdout); 3392 3393 if (fd == -1) { 3394 return NULL; 3395 } 3396 } 3397 3398 if (!initialised_setupterm && setupterm((char *)term, fd, &err) == ERR) { 3399 const char* s = "setupterm: unknown error"; 3400 3401 if (err == 0) { 3402 s = "setupterm: could not find terminal"; 3403 } else if (err == -1) { 3404 s = "setupterm: could not find terminfo database"; 3405 } 3406 3407 PyErr_SetString(PyCursesError,s); 3408 return NULL; 3409 } 3410 3411 initialised_setupterm = TRUE; 3412 3413 Py_RETURN_NONE; 3414} 3415 3416#if defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20081102 3417// https://invisible-island.net/ncurses/NEWS.html#index-t20080119 3418 3419/*[clinic input] 3420_curses.get_escdelay 3421 3422Gets the curses ESCDELAY setting. 3423 3424Gets the number of milliseconds to wait after reading an escape character, 3425to distinguish between an individual escape character entered on the 3426keyboard from escape sequences sent by cursor and function keys. 3427[clinic start generated code]*/ 3428 3429static PyObject * 3430_curses_get_escdelay_impl(PyObject *module) 3431/*[clinic end generated code: output=222fa1a822555d60 input=be2d5b3dd974d0a4]*/ 3432{ 3433 return PyLong_FromLong(ESCDELAY); 3434} 3435/*[clinic input] 3436_curses.set_escdelay 3437 ms: int 3438 length of the delay in milliseconds. 3439 / 3440 3441Sets the curses ESCDELAY setting. 3442 3443Sets the number of milliseconds to wait after reading an escape character, 3444to distinguish between an individual escape character entered on the 3445keyboard from escape sequences sent by cursor and function keys. 3446[clinic start generated code]*/ 3447 3448static PyObject * 3449_curses_set_escdelay_impl(PyObject *module, int ms) 3450/*[clinic end generated code: output=43818efbf7980ac4 input=7796fe19f111e250]*/ 3451{ 3452 if (ms <= 0) { 3453 PyErr_SetString(PyExc_ValueError, "ms must be > 0"); 3454 return NULL; 3455 } 3456 3457 return PyCursesCheckERR(set_escdelay(ms), "set_escdelay"); 3458} 3459 3460/*[clinic input] 3461_curses.get_tabsize 3462 3463Gets the curses TABSIZE setting. 3464 3465Gets the number of columns used by the curses library when converting a tab 3466character to spaces as it adds the tab to a window. 3467[clinic start generated code]*/ 3468 3469static PyObject * 3470_curses_get_tabsize_impl(PyObject *module) 3471/*[clinic end generated code: output=7e9e51fb6126fbdf input=74af86bf6c9f5d7e]*/ 3472{ 3473 return PyLong_FromLong(TABSIZE); 3474} 3475/*[clinic input] 3476_curses.set_tabsize 3477 size: int 3478 rendered cell width of a tab character. 3479 / 3480 3481Sets the curses TABSIZE setting. 3482 3483Sets the number of columns used by the curses library when converting a tab 3484character to spaces as it adds the tab to a window. 3485[clinic start generated code]*/ 3486 3487static PyObject * 3488_curses_set_tabsize_impl(PyObject *module, int size) 3489/*[clinic end generated code: output=c1de5a76c0daab1e input=78cba6a3021ad061]*/ 3490{ 3491 if (size <= 0) { 3492 PyErr_SetString(PyExc_ValueError, "size must be > 0"); 3493 return NULL; 3494 } 3495 3496 return PyCursesCheckERR(set_tabsize(size), "set_tabsize"); 3497} 3498#endif 3499 3500/*[clinic input] 3501_curses.intrflush 3502 3503 flag: bool(accept={int}) 3504 / 3505 3506[clinic start generated code]*/ 3507 3508static PyObject * 3509_curses_intrflush_impl(PyObject *module, int flag) 3510/*[clinic end generated code: output=c1986df35e999a0f input=fcba57bb28dfd795]*/ 3511{ 3512 PyCursesInitialised; 3513 3514 return PyCursesCheckERR(intrflush(NULL, flag), "intrflush"); 3515} 3516 3517/*[clinic input] 3518_curses.isendwin 3519 3520Return True if endwin() has been called. 3521[clinic start generated code]*/ 3522 3523static PyObject * 3524_curses_isendwin_impl(PyObject *module) 3525/*[clinic end generated code: output=d73179e4a7e1eb8c input=6cdb01a7ebf71397]*/ 3526NoArgTrueFalseFunctionBody(isendwin) 3527 3528#ifdef HAVE_CURSES_IS_TERM_RESIZED 3529/*[clinic input] 3530_curses.is_term_resized 3531 3532 nlines: int 3533 Height. 3534 ncols: int 3535 Width. 3536 / 3537 3538Return True if resize_term() would modify the window structure, False otherwise. 3539[clinic start generated code]*/ 3540 3541static PyObject * 3542_curses_is_term_resized_impl(PyObject *module, int nlines, int ncols) 3543/*[clinic end generated code: output=aafe04afe50f1288 input=ca9c0bd0fb8ab444]*/ 3544{ 3545 PyCursesInitialised; 3546 3547 return PyBool_FromLong(is_term_resized(nlines, ncols)); 3548} 3549#endif /* HAVE_CURSES_IS_TERM_RESIZED */ 3550 3551/*[clinic input] 3552_curses.keyname 3553 3554 key: int 3555 Key number. 3556 / 3557 3558Return the name of specified key. 3559[clinic start generated code]*/ 3560 3561static PyObject * 3562_curses_keyname_impl(PyObject *module, int key) 3563/*[clinic end generated code: output=fa2675ab3f4e056b input=ee4b1d0f243a2a2b]*/ 3564{ 3565 const char *knp; 3566 3567 PyCursesInitialised; 3568 3569 if (key < 0) { 3570 PyErr_SetString(PyExc_ValueError, "invalid key number"); 3571 return NULL; 3572 } 3573 knp = keyname(key); 3574 3575 return PyBytes_FromString((knp == NULL) ? "" : knp); 3576} 3577 3578/*[clinic input] 3579_curses.killchar 3580 3581Return the user's current line kill character. 3582[clinic start generated code]*/ 3583 3584static PyObject * 3585_curses_killchar_impl(PyObject *module) 3586/*[clinic end generated code: output=31c3a45b2c528269 input=1ff171c38df5ccad]*/ 3587{ 3588 char ch; 3589 3590 ch = killchar(); 3591 3592 return PyBytes_FromStringAndSize(&ch, 1); 3593} 3594 3595/*[clinic input] 3596_curses.longname 3597 3598Return the terminfo long name field describing the current terminal. 3599 3600The maximum length of a verbose description is 128 characters. It is defined 3601only after the call to initscr(). 3602[clinic start generated code]*/ 3603 3604static PyObject * 3605_curses_longname_impl(PyObject *module) 3606/*[clinic end generated code: output=fdf30433727ef568 input=84c3f20201b1098e]*/ 3607NoArgReturnStringFunctionBody(longname) 3608 3609/*[clinic input] 3610_curses.meta 3611 3612 yes: bool(accept={int}) 3613 / 3614 3615Enable/disable meta keys. 3616 3617If yes is True, allow 8-bit characters to be input. If yes is False, 3618allow only 7-bit characters. 3619[clinic start generated code]*/ 3620 3621static PyObject * 3622_curses_meta_impl(PyObject *module, int yes) 3623/*[clinic end generated code: output=22f5abda46a605d8 input=af9892e3a74f35db]*/ 3624{ 3625 PyCursesInitialised; 3626 3627 return PyCursesCheckERR(meta(stdscr, yes), "meta"); 3628} 3629 3630#ifdef NCURSES_MOUSE_VERSION 3631/*[clinic input] 3632_curses.mouseinterval 3633 3634 interval: int 3635 Time in milliseconds. 3636 / 3637 3638Set and retrieve the maximum time between press and release in a click. 3639 3640Set the maximum time that can elapse between press and release events in 3641order for them to be recognized as a click, and return the previous interval 3642value. 3643[clinic start generated code]*/ 3644 3645static PyObject * 3646_curses_mouseinterval_impl(PyObject *module, int interval) 3647/*[clinic end generated code: output=c4f5ff04354634c5 input=75aaa3f0db10ac4e]*/ 3648{ 3649 PyCursesInitialised; 3650 3651 return PyCursesCheckERR(mouseinterval(interval), "mouseinterval"); 3652} 3653 3654/*[clinic input] 3655_curses.mousemask 3656 3657 newmask: unsigned_long(bitwise=True) 3658 / 3659 3660Set the mouse events to be reported, and return a tuple (availmask, oldmask). 3661 3662Return a tuple (availmask, oldmask). availmask indicates which of the 3663specified mouse events can be reported; on complete failure it returns 0. 3664oldmask is the previous value of the given window's mouse event mask. 3665If this function is never called, no mouse events are ever reported. 3666[clinic start generated code]*/ 3667 3668static PyObject * 3669_curses_mousemask_impl(PyObject *module, unsigned long newmask) 3670/*[clinic end generated code: output=9406cf1b8a36e485 input=bdf76b7568a3c541]*/ 3671{ 3672 mmask_t oldmask, availmask; 3673 3674 PyCursesInitialised; 3675 availmask = mousemask((mmask_t)newmask, &oldmask); 3676 return Py_BuildValue("(kk)", 3677 (unsigned long)availmask, (unsigned long)oldmask); 3678} 3679#endif 3680 3681/*[clinic input] 3682_curses.napms 3683 3684 ms: int 3685 Duration in milliseconds. 3686 / 3687 3688Sleep for specified time. 3689[clinic start generated code]*/ 3690 3691static PyObject * 3692_curses_napms_impl(PyObject *module, int ms) 3693/*[clinic end generated code: output=a40a1da2e39ea438 input=20cd3af2b6900f56]*/ 3694{ 3695 PyCursesInitialised; 3696 3697 return Py_BuildValue("i", napms(ms)); 3698} 3699 3700 3701/*[clinic input] 3702_curses.newpad 3703 3704 nlines: int 3705 Height. 3706 ncols: int 3707 Width. 3708 / 3709 3710Create and return a pointer to a new pad data structure. 3711[clinic start generated code]*/ 3712 3713static PyObject * 3714_curses_newpad_impl(PyObject *module, int nlines, int ncols) 3715/*[clinic end generated code: output=de52a56eb1098ec9 input=93f1272f240d8894]*/ 3716{ 3717 WINDOW *win; 3718 3719 PyCursesInitialised; 3720 3721 win = newpad(nlines, ncols); 3722 3723 if (win == NULL) { 3724 PyErr_SetString(PyCursesError, catchall_NULL); 3725 return NULL; 3726 } 3727 3728 return (PyObject *)PyCursesWindow_New(win, NULL); 3729} 3730 3731/*[clinic input] 3732_curses.newwin 3733 3734 nlines: int 3735 Height. 3736 ncols: int 3737 Width. 3738 [ 3739 begin_y: int = 0 3740 Top side y-coordinate. 3741 begin_x: int = 0 3742 Left side x-coordinate. 3743 ] 3744 / 3745 3746Return a new window. 3747 3748By default, the window will extend from the specified position to the lower 3749right corner of the screen. 3750[clinic start generated code]*/ 3751 3752static PyObject * 3753_curses_newwin_impl(PyObject *module, int nlines, int ncols, 3754 int group_right_1, int begin_y, int begin_x) 3755/*[clinic end generated code: output=c1e0a8dc8ac2826c input=29312c15a72a003d]*/ 3756{ 3757 WINDOW *win; 3758 3759 PyCursesInitialised; 3760 3761 win = newwin(nlines,ncols,begin_y,begin_x); 3762 if (win == NULL) { 3763 PyErr_SetString(PyCursesError, catchall_NULL); 3764 return NULL; 3765 } 3766 3767 return (PyObject *)PyCursesWindow_New(win, NULL); 3768} 3769 3770/*[clinic input] 3771_curses.nl 3772 3773 flag: bool(accept={int}) = True 3774 If false, the effect is the same as calling nonl(). 3775 / 3776 3777Enter newline mode. 3778 3779This mode translates the return key into newline on input, and translates 3780newline into return and line-feed on output. Newline mode is initially on. 3781[clinic start generated code]*/ 3782 3783static PyObject * 3784_curses_nl_impl(PyObject *module, int flag) 3785/*[clinic end generated code: output=b39cc0ffc9015003 input=cf36a63f7b86e28a]*/ 3786NoArgOrFlagNoReturnFunctionBody(nl, flag) 3787 3788/*[clinic input] 3789_curses.nocbreak 3790 3791Leave cbreak mode. 3792 3793Return to normal "cooked" mode with line buffering. 3794[clinic start generated code]*/ 3795 3796static PyObject * 3797_curses_nocbreak_impl(PyObject *module) 3798/*[clinic end generated code: output=eabf3833a4fbf620 input=e4b65f7d734af400]*/ 3799NoArgNoReturnFunctionBody(nocbreak) 3800 3801/*[clinic input] 3802_curses.noecho 3803 3804Leave echo mode. 3805 3806Echoing of input characters is turned off. 3807[clinic start generated code]*/ 3808 3809static PyObject * 3810_curses_noecho_impl(PyObject *module) 3811/*[clinic end generated code: output=cc95ab45bc98f41b input=76714df529e614c3]*/ 3812NoArgNoReturnFunctionBody(noecho) 3813 3814/*[clinic input] 3815_curses.nonl 3816 3817Leave newline mode. 3818 3819Disable translation of return into newline on input, and disable low-level 3820translation of newline into newline/return on output. 3821[clinic start generated code]*/ 3822 3823static PyObject * 3824_curses_nonl_impl(PyObject *module) 3825/*[clinic end generated code: output=99e917e9715770c6 input=9d37dd122d3022fc]*/ 3826NoArgNoReturnFunctionBody(nonl) 3827 3828/*[clinic input] 3829_curses.noqiflush 3830 3831Disable queue flushing. 3832 3833When queue flushing is disabled, normal flush of input and output queues 3834associated with the INTR, QUIT and SUSP characters will not be done. 3835[clinic start generated code]*/ 3836 3837static PyObject * 3838_curses_noqiflush_impl(PyObject *module) 3839/*[clinic end generated code: output=8b95a4229bbf0877 input=ba3e6b2e3e54c4df]*/ 3840NoArgNoReturnVoidFunctionBody(noqiflush) 3841 3842/*[clinic input] 3843_curses.noraw 3844 3845Leave raw mode. 3846 3847Return to normal "cooked" mode with line buffering. 3848[clinic start generated code]*/ 3849 3850static PyObject * 3851_curses_noraw_impl(PyObject *module) 3852/*[clinic end generated code: output=39894e5524c430cc input=6ec86692096dffb5]*/ 3853NoArgNoReturnFunctionBody(noraw) 3854 3855/*[clinic input] 3856_curses.pair_content 3857 3858 pair_number: pair 3859 The number of the color pair (0 - (COLOR_PAIRS-1)). 3860 / 3861 3862Return a tuple (fg, bg) containing the colors for the requested color pair. 3863[clinic start generated code]*/ 3864 3865static PyObject * 3866_curses_pair_content_impl(PyObject *module, int pair_number) 3867/*[clinic end generated code: output=4a726dd0e6885f3f input=03970f840fc7b739]*/ 3868{ 3869 _CURSES_COLOR_NUM_TYPE f, b; 3870 3871 PyCursesInitialised; 3872 PyCursesInitialisedColor; 3873 3874 if (_CURSES_PAIR_CONTENT_FUNC(pair_number, &f, &b) == ERR) { 3875 if (pair_number >= COLOR_PAIRS) { 3876 PyErr_Format(PyExc_ValueError, 3877 "Color pair is greater than COLOR_PAIRS-1 (%d).", 3878 COLOR_PAIRS - 1); 3879 } 3880 else { 3881 PyErr_Format(PyCursesError, "%s() returned ERR", 3882 Py_STRINGIFY(_CURSES_PAIR_CONTENT_FUNC)); 3883 } 3884 return NULL; 3885 } 3886 3887 return Py_BuildValue("(ii)", f, b); 3888} 3889 3890/*[clinic input] 3891_curses.pair_number 3892 3893 attr: int 3894 / 3895 3896Return the number of the color-pair set by the specified attribute value. 3897 3898color_pair() is the counterpart to this function. 3899[clinic start generated code]*/ 3900 3901static PyObject * 3902_curses_pair_number_impl(PyObject *module, int attr) 3903/*[clinic end generated code: output=85bce7d65c0aa3f4 input=d478548e33f5e61a]*/ 3904{ 3905 PyCursesInitialised; 3906 PyCursesInitialisedColor; 3907 3908 return PyLong_FromLong(PAIR_NUMBER(attr)); 3909} 3910 3911/*[clinic input] 3912_curses.putp 3913 3914 string: str(accept={robuffer}) 3915 / 3916 3917Emit the value of a specified terminfo capability for the current terminal. 3918 3919Note that the output of putp() always goes to standard output. 3920[clinic start generated code]*/ 3921 3922static PyObject * 3923_curses_putp_impl(PyObject *module, const char *string) 3924/*[clinic end generated code: output=e98081d1b8eb5816 input=1601faa828b44cb3]*/ 3925{ 3926 return PyCursesCheckERR(putp(string), "putp"); 3927} 3928 3929/*[clinic input] 3930_curses.qiflush 3931 3932 flag: bool(accept={int}) = True 3933 If false, the effect is the same as calling noqiflush(). 3934 / 3935 3936Enable queue flushing. 3937 3938If queue flushing is enabled, all output in the display driver queue 3939will be flushed when the INTR, QUIT and SUSP characters are read. 3940[clinic start generated code]*/ 3941 3942static PyObject * 3943_curses_qiflush_impl(PyObject *module, int flag) 3944/*[clinic end generated code: output=9167e862f760ea30 input=e9e4a389946a0dbc]*/ 3945{ 3946 PyCursesInitialised; 3947 3948 if (flag) { 3949 qiflush(); 3950 } 3951 else { 3952 noqiflush(); 3953 } 3954 Py_RETURN_NONE; 3955} 3956 3957/* Internal helper used for updating curses.LINES, curses.COLS, _curses.LINES 3958 * and _curses.COLS */ 3959#if defined(HAVE_CURSES_RESIZETERM) || defined(HAVE_CURSES_RESIZE_TERM) 3960static int 3961update_lines_cols(void) 3962{ 3963 PyObject *o; 3964 PyObject *m = PyImport_ImportModule("curses"); 3965 _Py_IDENTIFIER(LINES); 3966 _Py_IDENTIFIER(COLS); 3967 3968 if (!m) 3969 return 0; 3970 3971 o = PyLong_FromLong(LINES); 3972 if (!o) { 3973 Py_DECREF(m); 3974 return 0; 3975 } 3976 if (_PyObject_SetAttrId(m, &PyId_LINES, o)) { 3977 Py_DECREF(m); 3978 Py_DECREF(o); 3979 return 0; 3980 } 3981 /* PyId_LINES.object will be initialized here. */ 3982 if (PyDict_SetItem(ModDict, _PyUnicode_FromId(&PyId_LINES), o)) { 3983 Py_DECREF(m); 3984 Py_DECREF(o); 3985 return 0; 3986 } 3987 Py_DECREF(o); 3988 o = PyLong_FromLong(COLS); 3989 if (!o) { 3990 Py_DECREF(m); 3991 return 0; 3992 } 3993 if (_PyObject_SetAttrId(m, &PyId_COLS, o)) { 3994 Py_DECREF(m); 3995 Py_DECREF(o); 3996 return 0; 3997 } 3998 if (PyDict_SetItem(ModDict, _PyUnicode_FromId(&PyId_COLS), o)) { 3999 Py_DECREF(m); 4000 Py_DECREF(o); 4001 return 0; 4002 } 4003 Py_DECREF(o); 4004 Py_DECREF(m); 4005 return 1; 4006} 4007 4008/*[clinic input] 4009_curses.update_lines_cols 4010 4011[clinic start generated code]*/ 4012 4013static PyObject * 4014_curses_update_lines_cols_impl(PyObject *module) 4015/*[clinic end generated code: output=423f2b1e63ed0f75 input=5f065ab7a28a5d90]*/ 4016{ 4017 if (!update_lines_cols()) { 4018 return NULL; 4019 } 4020 Py_RETURN_NONE; 4021} 4022 4023#endif 4024 4025/*[clinic input] 4026_curses.raw 4027 4028 flag: bool(accept={int}) = True 4029 If false, the effect is the same as calling noraw(). 4030 / 4031 4032Enter raw mode. 4033 4034In raw mode, normal line buffering and processing of interrupt, quit, 4035suspend, and flow control keys are turned off; characters are presented to 4036curses input functions one by one. 4037[clinic start generated code]*/ 4038 4039static PyObject * 4040_curses_raw_impl(PyObject *module, int flag) 4041/*[clinic end generated code: output=a750e4b342be015b input=e36d8db27832b848]*/ 4042NoArgOrFlagNoReturnFunctionBody(raw, flag) 4043 4044/*[clinic input] 4045_curses.reset_prog_mode 4046 4047Restore the terminal to "program" mode, as previously saved by def_prog_mode(). 4048[clinic start generated code]*/ 4049 4050static PyObject * 4051_curses_reset_prog_mode_impl(PyObject *module) 4052/*[clinic end generated code: output=15eb765abf0b6575 input=3d82bea2b3243471]*/ 4053NoArgNoReturnFunctionBody(reset_prog_mode) 4054 4055/*[clinic input] 4056_curses.reset_shell_mode 4057 4058Restore the terminal to "shell" mode, as previously saved by def_shell_mode(). 4059[clinic start generated code]*/ 4060 4061static PyObject * 4062_curses_reset_shell_mode_impl(PyObject *module) 4063/*[clinic end generated code: output=0238de2962090d33 input=1c738fa64bd1a24f]*/ 4064NoArgNoReturnFunctionBody(reset_shell_mode) 4065 4066/*[clinic input] 4067_curses.resetty 4068 4069Restore terminal mode. 4070[clinic start generated code]*/ 4071 4072static PyObject * 4073_curses_resetty_impl(PyObject *module) 4074/*[clinic end generated code: output=ff4b448e80a7cd63 input=940493de03624bb0]*/ 4075NoArgNoReturnFunctionBody(resetty) 4076 4077#ifdef HAVE_CURSES_RESIZETERM 4078/*[clinic input] 4079_curses.resizeterm 4080 4081 nlines: int 4082 Height. 4083 ncols: int 4084 Width. 4085 / 4086 4087Resize the standard and current windows to the specified dimensions. 4088 4089Adjusts other bookkeeping data used by the curses library that record the 4090window dimensions (in particular the SIGWINCH handler). 4091[clinic start generated code]*/ 4092 4093static PyObject * 4094_curses_resizeterm_impl(PyObject *module, int nlines, int ncols) 4095/*[clinic end generated code: output=56d6bcc5194ad055 input=0fca02ebad5ffa82]*/ 4096{ 4097 PyObject *result; 4098 4099 PyCursesInitialised; 4100 4101 result = PyCursesCheckERR(resizeterm(nlines, ncols), "resizeterm"); 4102 if (!result) 4103 return NULL; 4104 if (!update_lines_cols()) { 4105 Py_DECREF(result); 4106 return NULL; 4107 } 4108 return result; 4109} 4110 4111#endif 4112 4113#ifdef HAVE_CURSES_RESIZE_TERM 4114/*[clinic input] 4115_curses.resize_term 4116 4117 nlines: int 4118 Height. 4119 ncols: int 4120 Width. 4121 / 4122 4123Backend function used by resizeterm(), performing most of the work. 4124 4125When resizing the windows, resize_term() blank-fills the areas that are 4126extended. The calling application should fill in these areas with appropriate 4127data. The resize_term() function attempts to resize all windows. However, 4128due to the calling convention of pads, it is not possible to resize these 4129without additional interaction with the application. 4130[clinic start generated code]*/ 4131 4132static PyObject * 4133_curses_resize_term_impl(PyObject *module, int nlines, int ncols) 4134/*[clinic end generated code: output=9e26d8b9ea311ed2 input=2197edd05b049ed4]*/ 4135{ 4136 PyObject *result; 4137 4138 PyCursesInitialised; 4139 4140 result = PyCursesCheckERR(resize_term(nlines, ncols), "resize_term"); 4141 if (!result) 4142 return NULL; 4143 if (!update_lines_cols()) { 4144 Py_DECREF(result); 4145 return NULL; 4146 } 4147 return result; 4148} 4149#endif /* HAVE_CURSES_RESIZE_TERM */ 4150 4151/*[clinic input] 4152_curses.savetty 4153 4154Save terminal mode. 4155[clinic start generated code]*/ 4156 4157static PyObject * 4158_curses_savetty_impl(PyObject *module) 4159/*[clinic end generated code: output=6babc49f12b42199 input=fce6b2b7d2200102]*/ 4160NoArgNoReturnFunctionBody(savetty) 4161 4162#ifdef getsyx 4163/*[clinic input] 4164_curses.setsyx 4165 4166 y: int 4167 Y-coordinate. 4168 x: int 4169 X-coordinate. 4170 / 4171 4172Set the virtual screen cursor. 4173 4174If y and x are both -1, then leaveok is set. 4175[clinic start generated code]*/ 4176 4177static PyObject * 4178_curses_setsyx_impl(PyObject *module, int y, int x) 4179/*[clinic end generated code: output=23dcf753511a2464 input=fa7f2b208e10a557]*/ 4180{ 4181 PyCursesInitialised; 4182 4183 setsyx(y,x); 4184 4185 Py_RETURN_NONE; 4186} 4187#endif 4188 4189/*[clinic input] 4190_curses.start_color 4191 4192Initializes eight basic colors and global variables COLORS and COLOR_PAIRS. 4193 4194Must be called if the programmer wants to use colors, and before any other 4195color manipulation routine is called. It is good practice to call this 4196routine right after initscr(). 4197 4198It also restores the colors on the terminal to the values they had when the 4199terminal was just turned on. 4200[clinic start generated code]*/ 4201 4202static PyObject * 4203_curses_start_color_impl(PyObject *module) 4204/*[clinic end generated code: output=8b772b41d8090ede input=0ca0ecb2b77e1a12]*/ 4205{ 4206 int code; 4207 PyObject *c, *cp; 4208 4209 PyCursesInitialised; 4210 4211 code = start_color(); 4212 if (code != ERR) { 4213 initialisedcolors = TRUE; 4214 c = PyLong_FromLong((long) COLORS); 4215 if (c == NULL) 4216 return NULL; 4217 if (PyDict_SetItemString(ModDict, "COLORS", c) < 0) { 4218 Py_DECREF(c); 4219 return NULL; 4220 } 4221 Py_DECREF(c); 4222 cp = PyLong_FromLong((long) COLOR_PAIRS); 4223 if (cp == NULL) 4224 return NULL; 4225 if (PyDict_SetItemString(ModDict, "COLOR_PAIRS", cp) < 0) { 4226 Py_DECREF(cp); 4227 return NULL; 4228 } 4229 Py_DECREF(cp); 4230 Py_RETURN_NONE; 4231 } else { 4232 PyErr_SetString(PyCursesError, "start_color() returned ERR"); 4233 return NULL; 4234 } 4235} 4236 4237/*[clinic input] 4238_curses.termattrs 4239 4240Return a logical OR of all video attributes supported by the terminal. 4241[clinic start generated code]*/ 4242 4243static PyObject * 4244_curses_termattrs_impl(PyObject *module) 4245/*[clinic end generated code: output=b06f437fce1b6fc4 input=0559882a04f84d1d]*/ 4246NoArgReturnIntFunctionBody(termattrs) 4247 4248/*[clinic input] 4249_curses.termname 4250 4251Return the value of the environment variable TERM, truncated to 14 characters. 4252[clinic start generated code]*/ 4253 4254static PyObject * 4255_curses_termname_impl(PyObject *module) 4256/*[clinic end generated code: output=96375577ebbd67fd input=33c08d000944f33f]*/ 4257NoArgReturnStringFunctionBody(termname) 4258 4259/*[clinic input] 4260_curses.tigetflag 4261 4262 capname: str 4263 The terminfo capability name. 4264 / 4265 4266Return the value of the Boolean capability. 4267 4268The value -1 is returned if capname is not a Boolean capability, or 0 if 4269it is canceled or absent from the terminal description. 4270[clinic start generated code]*/ 4271 4272static PyObject * 4273_curses_tigetflag_impl(PyObject *module, const char *capname) 4274/*[clinic end generated code: output=8853c0e55542195b input=b0787af9e3e9a6ce]*/ 4275{ 4276 PyCursesSetupTermCalled; 4277 4278 return PyLong_FromLong( (long) tigetflag( (char *)capname ) ); 4279} 4280 4281/*[clinic input] 4282_curses.tigetnum 4283 4284 capname: str 4285 The terminfo capability name. 4286 / 4287 4288Return the value of the numeric capability. 4289 4290The value -2 is returned if capname is not a numeric capability, or -1 if 4291it is canceled or absent from the terminal description. 4292[clinic start generated code]*/ 4293 4294static PyObject * 4295_curses_tigetnum_impl(PyObject *module, const char *capname) 4296/*[clinic end generated code: output=46f8b0a1b5dff42f input=5cdf2f410b109720]*/ 4297{ 4298 PyCursesSetupTermCalled; 4299 4300 return PyLong_FromLong( (long) tigetnum( (char *)capname ) ); 4301} 4302 4303/*[clinic input] 4304_curses.tigetstr 4305 4306 capname: str 4307 The terminfo capability name. 4308 / 4309 4310Return the value of the string capability. 4311 4312None is returned if capname is not a string capability, or is canceled or 4313absent from the terminal description. 4314[clinic start generated code]*/ 4315 4316static PyObject * 4317_curses_tigetstr_impl(PyObject *module, const char *capname) 4318/*[clinic end generated code: output=f22b576ad60248f3 input=36644df25c73c0a7]*/ 4319{ 4320 PyCursesSetupTermCalled; 4321 4322 capname = tigetstr( (char *)capname ); 4323 if (capname == NULL || capname == (char*) -1) { 4324 Py_RETURN_NONE; 4325 } 4326 return PyBytes_FromString( capname ); 4327} 4328 4329/*[clinic input] 4330_curses.tparm 4331 4332 str: str(accept={robuffer}) 4333 Parameterized byte string obtained from the terminfo database. 4334 i1: int = 0 4335 i2: int = 0 4336 i3: int = 0 4337 i4: int = 0 4338 i5: int = 0 4339 i6: int = 0 4340 i7: int = 0 4341 i8: int = 0 4342 i9: int = 0 4343 / 4344 4345Instantiate the specified byte string with the supplied parameters. 4346[clinic start generated code]*/ 4347 4348static PyObject * 4349_curses_tparm_impl(PyObject *module, const char *str, int i1, int i2, int i3, 4350 int i4, int i5, int i6, int i7, int i8, int i9) 4351/*[clinic end generated code: output=599f62b615c667ff input=5e30b15786f032aa]*/ 4352{ 4353 char* result = NULL; 4354 4355 PyCursesSetupTermCalled; 4356 4357 result = tparm((char *)str,i1,i2,i3,i4,i5,i6,i7,i8,i9); 4358 if (!result) { 4359 PyErr_SetString(PyCursesError, "tparm() returned NULL"); 4360 return NULL; 4361 } 4362 4363 return PyBytes_FromString(result); 4364} 4365 4366#ifdef HAVE_CURSES_TYPEAHEAD 4367/*[clinic input] 4368_curses.typeahead 4369 4370 fd: int 4371 File descriptor. 4372 / 4373 4374Specify that the file descriptor fd be used for typeahead checking. 4375 4376If fd is -1, then no typeahead checking is done. 4377[clinic start generated code]*/ 4378 4379static PyObject * 4380_curses_typeahead_impl(PyObject *module, int fd) 4381/*[clinic end generated code: output=084bb649d7066583 input=f2968d8e1805051b]*/ 4382{ 4383 PyCursesInitialised; 4384 4385 return PyCursesCheckERR(typeahead( fd ), "typeahead"); 4386} 4387#endif 4388 4389/*[clinic input] 4390_curses.unctrl 4391 4392 ch: object 4393 / 4394 4395Return a string which is a printable representation of the character ch. 4396 4397Control characters are displayed as a caret followed by the character, 4398for example as ^C. Printing characters are left as they are. 4399[clinic start generated code]*/ 4400 4401static PyObject * 4402_curses_unctrl(PyObject *module, PyObject *ch) 4403/*[clinic end generated code: output=8e07fafc430c9434 input=cd1e35e16cd1ace4]*/ 4404{ 4405 chtype ch_; 4406 4407 PyCursesInitialised; 4408 4409 if (!PyCurses_ConvertToChtype(NULL, ch, &ch_)) 4410 return NULL; 4411 4412 return PyBytes_FromString(unctrl(ch_)); 4413} 4414 4415/*[clinic input] 4416_curses.ungetch 4417 4418 ch: object 4419 / 4420 4421Push ch so the next getch() will return it. 4422[clinic start generated code]*/ 4423 4424static PyObject * 4425_curses_ungetch(PyObject *module, PyObject *ch) 4426/*[clinic end generated code: output=9b19d8268376d887 input=6681e6ae4c42e5eb]*/ 4427{ 4428 chtype ch_; 4429 4430 PyCursesInitialised; 4431 4432 if (!PyCurses_ConvertToChtype(NULL, ch, &ch_)) 4433 return NULL; 4434 4435 return PyCursesCheckERR(ungetch(ch_), "ungetch"); 4436} 4437 4438#ifdef HAVE_NCURSESW 4439/* Convert an object to a character (wchar_t): 4440 4441 - int 4442 - str of length 1 4443 4444 Return 1 on success, 0 on error. */ 4445static int 4446PyCurses_ConvertToWchar_t(PyObject *obj, 4447 wchar_t *wch) 4448{ 4449 if (PyUnicode_Check(obj)) { 4450 wchar_t buffer[2]; 4451 if (PyUnicode_AsWideChar(obj, buffer, 2) != 1) { 4452 PyErr_Format(PyExc_TypeError, 4453 "expect str of length 1 or int, " 4454 "got a str of length %zi", 4455 PyUnicode_GET_LENGTH(obj)); 4456 return 0; 4457 } 4458 *wch = buffer[0]; 4459 return 2; 4460 } 4461 else if (PyLong_CheckExact(obj)) { 4462 long value; 4463 int overflow; 4464 value = PyLong_AsLongAndOverflow(obj, &overflow); 4465 if (overflow) { 4466 PyErr_SetString(PyExc_OverflowError, 4467 "int doesn't fit in long"); 4468 return 0; 4469 } 4470 *wch = (wchar_t)value; 4471 if ((long)*wch != value) { 4472 PyErr_Format(PyExc_OverflowError, 4473 "character doesn't fit in wchar_t"); 4474 return 0; 4475 } 4476 return 1; 4477 } 4478 else { 4479 PyErr_Format(PyExc_TypeError, 4480 "expect str of length 1 or int, got %s", 4481 Py_TYPE(obj)->tp_name); 4482 return 0; 4483 } 4484} 4485 4486/*[clinic input] 4487_curses.unget_wch 4488 4489 ch: object 4490 / 4491 4492Push ch so the next get_wch() will return it. 4493[clinic start generated code]*/ 4494 4495static PyObject * 4496_curses_unget_wch(PyObject *module, PyObject *ch) 4497/*[clinic end generated code: output=1974c9fb01d37863 input=0d56dc65a46feebb]*/ 4498{ 4499 wchar_t wch; 4500 4501 PyCursesInitialised; 4502 4503 if (!PyCurses_ConvertToWchar_t(ch, &wch)) 4504 return NULL; 4505 return PyCursesCheckERR(unget_wch(wch), "unget_wch"); 4506} 4507#endif 4508 4509#ifdef HAVE_CURSES_USE_ENV 4510/*[clinic input] 4511_curses.use_env 4512 4513 flag: bool(accept={int}) 4514 / 4515 4516Use environment variables LINES and COLUMNS. 4517 4518If used, this function should be called before initscr() or newterm() are 4519called. 4520 4521When flag is False, the values of lines and columns specified in the terminfo 4522database will be used, even if environment variables LINES and COLUMNS (used 4523by default) are set, or if curses is running in a window (in which case 4524default behavior would be to use the window size if LINES and COLUMNS are 4525not set). 4526[clinic start generated code]*/ 4527 4528static PyObject * 4529_curses_use_env_impl(PyObject *module, int flag) 4530/*[clinic end generated code: output=b2c445e435c0b164 input=1778eb1e9151ea37]*/ 4531{ 4532 use_env(flag); 4533 Py_RETURN_NONE; 4534} 4535#endif 4536 4537#ifndef STRICT_SYSV_CURSES 4538/*[clinic input] 4539_curses.use_default_colors 4540 4541Allow use of default values for colors on terminals supporting this feature. 4542 4543Use this to support transparency in your application. The default color 4544is assigned to the color number -1. 4545[clinic start generated code]*/ 4546 4547static PyObject * 4548_curses_use_default_colors_impl(PyObject *module) 4549/*[clinic end generated code: output=a3b81ff71dd901be input=656844367470e8fc]*/ 4550{ 4551 int code; 4552 4553 PyCursesInitialised; 4554 PyCursesInitialisedColor; 4555 4556 code = use_default_colors(); 4557 if (code != ERR) { 4558 Py_RETURN_NONE; 4559 } else { 4560 PyErr_SetString(PyCursesError, "use_default_colors() returned ERR"); 4561 return NULL; 4562 } 4563} 4564#endif /* STRICT_SYSV_CURSES */ 4565 4566 4567#ifdef NCURSES_VERSION 4568 4569PyDoc_STRVAR(ncurses_version__doc__, 4570"curses.ncurses_version\n\ 4571\n\ 4572Ncurses version information as a named tuple."); 4573 4574static PyStructSequence_Field ncurses_version_fields[] = { 4575 {"major", "Major release number"}, 4576 {"minor", "Minor release number"}, 4577 {"patch", "Patch release number"}, 4578 {0} 4579}; 4580 4581static PyStructSequence_Desc ncurses_version_desc = { 4582 "curses.ncurses_version", /* name */ 4583 ncurses_version__doc__, /* doc */ 4584 ncurses_version_fields, /* fields */ 4585 3 4586}; 4587 4588static PyObject * 4589make_ncurses_version(PyTypeObject *type) 4590{ 4591 PyObject *ncurses_version; 4592 int pos = 0; 4593 4594 ncurses_version = PyStructSequence_New(type); 4595 if (ncurses_version == NULL) { 4596 return NULL; 4597 } 4598 4599#define SetIntItem(flag) \ 4600 PyStructSequence_SET_ITEM(ncurses_version, pos++, PyLong_FromLong(flag)); \ 4601 if (PyErr_Occurred()) { \ 4602 Py_CLEAR(ncurses_version); \ 4603 return NULL; \ 4604 } 4605 4606 SetIntItem(NCURSES_VERSION_MAJOR) 4607 SetIntItem(NCURSES_VERSION_MINOR) 4608 SetIntItem(NCURSES_VERSION_PATCH) 4609#undef SetIntItem 4610 4611 return ncurses_version; 4612} 4613 4614#endif /* NCURSES_VERSION */ 4615 4616/*[clinic input] 4617_curses.has_extended_color_support 4618 4619Return True if the module supports extended colors; otherwise, return False. 4620 4621Extended color support allows more than 256 color-pairs for terminals 4622that support more than 16 colors (e.g. xterm-256color). 4623[clinic start generated code]*/ 4624 4625static PyObject * 4626_curses_has_extended_color_support_impl(PyObject *module) 4627/*[clinic end generated code: output=68f1be2b57d92e22 input=4b905f046e35ee9f]*/ 4628{ 4629 return PyBool_FromLong(_NCURSES_EXTENDED_COLOR_FUNCS); 4630} 4631 4632/* List of functions defined in the module */ 4633 4634static PyMethodDef PyCurses_methods[] = { 4635 _CURSES_BAUDRATE_METHODDEF 4636 _CURSES_BEEP_METHODDEF 4637 _CURSES_CAN_CHANGE_COLOR_METHODDEF 4638 _CURSES_CBREAK_METHODDEF 4639 _CURSES_COLOR_CONTENT_METHODDEF 4640 _CURSES_COLOR_PAIR_METHODDEF 4641 _CURSES_CURS_SET_METHODDEF 4642 _CURSES_DEF_PROG_MODE_METHODDEF 4643 _CURSES_DEF_SHELL_MODE_METHODDEF 4644 _CURSES_DELAY_OUTPUT_METHODDEF 4645 _CURSES_DOUPDATE_METHODDEF 4646 _CURSES_ECHO_METHODDEF 4647 _CURSES_ENDWIN_METHODDEF 4648 _CURSES_ERASECHAR_METHODDEF 4649 _CURSES_FILTER_METHODDEF 4650 _CURSES_FLASH_METHODDEF 4651 _CURSES_FLUSHINP_METHODDEF 4652 _CURSES_GETMOUSE_METHODDEF 4653 _CURSES_UNGETMOUSE_METHODDEF 4654 _CURSES_GETSYX_METHODDEF 4655 _CURSES_GETWIN_METHODDEF 4656 _CURSES_HAS_COLORS_METHODDEF 4657 _CURSES_HAS_EXTENDED_COLOR_SUPPORT_METHODDEF 4658 _CURSES_HAS_IC_METHODDEF 4659 _CURSES_HAS_IL_METHODDEF 4660 _CURSES_HAS_KEY_METHODDEF 4661 _CURSES_HALFDELAY_METHODDEF 4662 _CURSES_INIT_COLOR_METHODDEF 4663 _CURSES_INIT_PAIR_METHODDEF 4664 _CURSES_INITSCR_METHODDEF 4665 _CURSES_INTRFLUSH_METHODDEF 4666 _CURSES_ISENDWIN_METHODDEF 4667 _CURSES_IS_TERM_RESIZED_METHODDEF 4668 _CURSES_KEYNAME_METHODDEF 4669 _CURSES_KILLCHAR_METHODDEF 4670 _CURSES_LONGNAME_METHODDEF 4671 _CURSES_META_METHODDEF 4672 _CURSES_MOUSEINTERVAL_METHODDEF 4673 _CURSES_MOUSEMASK_METHODDEF 4674 _CURSES_NAPMS_METHODDEF 4675 _CURSES_NEWPAD_METHODDEF 4676 _CURSES_NEWWIN_METHODDEF 4677 _CURSES_NL_METHODDEF 4678 _CURSES_NOCBREAK_METHODDEF 4679 _CURSES_NOECHO_METHODDEF 4680 _CURSES_NONL_METHODDEF 4681 _CURSES_NOQIFLUSH_METHODDEF 4682 _CURSES_NORAW_METHODDEF 4683 _CURSES_PAIR_CONTENT_METHODDEF 4684 _CURSES_PAIR_NUMBER_METHODDEF 4685 _CURSES_PUTP_METHODDEF 4686 _CURSES_QIFLUSH_METHODDEF 4687 _CURSES_RAW_METHODDEF 4688 _CURSES_RESET_PROG_MODE_METHODDEF 4689 _CURSES_RESET_SHELL_MODE_METHODDEF 4690 _CURSES_RESETTY_METHODDEF 4691 _CURSES_RESIZETERM_METHODDEF 4692 _CURSES_RESIZE_TERM_METHODDEF 4693 _CURSES_SAVETTY_METHODDEF 4694#if defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20081102 4695 _CURSES_GET_ESCDELAY_METHODDEF 4696 _CURSES_SET_ESCDELAY_METHODDEF 4697#endif 4698 _CURSES_GET_TABSIZE_METHODDEF 4699 _CURSES_SET_TABSIZE_METHODDEF 4700 _CURSES_SETSYX_METHODDEF 4701 _CURSES_SETUPTERM_METHODDEF 4702 _CURSES_START_COLOR_METHODDEF 4703 _CURSES_TERMATTRS_METHODDEF 4704 _CURSES_TERMNAME_METHODDEF 4705 _CURSES_TIGETFLAG_METHODDEF 4706 _CURSES_TIGETNUM_METHODDEF 4707 _CURSES_TIGETSTR_METHODDEF 4708 _CURSES_TPARM_METHODDEF 4709 _CURSES_TYPEAHEAD_METHODDEF 4710 _CURSES_UNCTRL_METHODDEF 4711 _CURSES_UNGETCH_METHODDEF 4712 _CURSES_UPDATE_LINES_COLS_METHODDEF 4713 _CURSES_UNGET_WCH_METHODDEF 4714 _CURSES_USE_ENV_METHODDEF 4715 _CURSES_USE_DEFAULT_COLORS_METHODDEF 4716 {NULL, NULL} /* sentinel */ 4717}; 4718 4719/* Initialization function for the module */ 4720 4721 4722static struct PyModuleDef _cursesmodule = { 4723 PyModuleDef_HEAD_INIT, 4724 "_curses", 4725 NULL, 4726 -1, 4727 PyCurses_methods, 4728 NULL, 4729 NULL, 4730 NULL, 4731 NULL 4732}; 4733 4734static void 4735curses_destructor(PyObject *op) 4736{ 4737 void *ptr = PyCapsule_GetPointer(op, PyCurses_CAPSULE_NAME); 4738 Py_DECREF(*(void **)ptr); 4739 PyMem_Free(ptr); 4740} 4741 4742PyMODINIT_FUNC 4743PyInit__curses(void) 4744{ 4745 PyObject *m, *d, *v, *c_api_object; 4746 4747 /* Initialize object type */ 4748 if (PyType_Ready(&PyCursesWindow_Type) < 0) 4749 return NULL; 4750 4751 /* Create the module and add the functions */ 4752 m = PyModule_Create(&_cursesmodule); 4753 if (m == NULL) 4754 return NULL; 4755 4756 /* Add some symbolic constants to the module */ 4757 d = PyModule_GetDict(m); 4758 if (d == NULL) 4759 return NULL; 4760 ModDict = d; /* For PyCurses_InitScr to use later */ 4761 4762 void **PyCurses_API = PyMem_Calloc(PyCurses_API_pointers, sizeof(void *)); 4763 if (PyCurses_API == NULL) { 4764 PyErr_NoMemory(); 4765 return NULL; 4766 } 4767 /* Initialize the C API pointer array */ 4768 PyCurses_API[0] = (void *)Py_NewRef(&PyCursesWindow_Type); 4769 PyCurses_API[1] = (void *)func_PyCursesSetupTermCalled; 4770 PyCurses_API[2] = (void *)func_PyCursesInitialised; 4771 PyCurses_API[3] = (void *)func_PyCursesInitialisedColor; 4772 4773 /* Add a capsule for the C API */ 4774 c_api_object = PyCapsule_New(PyCurses_API, PyCurses_CAPSULE_NAME, 4775 curses_destructor); 4776 if (c_api_object == NULL) { 4777 Py_DECREF(PyCurses_API[0]); 4778 PyMem_Free(PyCurses_API); 4779 return NULL; 4780 } 4781 if (PyDict_SetItemString(d, "_C_API", c_api_object) < 0) { 4782 Py_DECREF(c_api_object); 4783 return NULL; 4784 } 4785 Py_DECREF(c_api_object); 4786 4787 /* For exception curses.error */ 4788 PyCursesError = PyErr_NewException("_curses.error", NULL, NULL); 4789 PyDict_SetItemString(d, "error", PyCursesError); 4790 4791 /* Make the version available */ 4792 v = PyBytes_FromString(PyCursesVersion); 4793 PyDict_SetItemString(d, "version", v); 4794 PyDict_SetItemString(d, "__version__", v); 4795 Py_DECREF(v); 4796 4797#ifdef NCURSES_VERSION 4798 /* ncurses_version */ 4799 PyTypeObject *version_type; 4800 version_type = _PyStructSequence_NewType(&ncurses_version_desc, 4801 Py_TPFLAGS_DISALLOW_INSTANTIATION); 4802 if (version_type == NULL) { 4803 return NULL; 4804 } 4805 v = make_ncurses_version(version_type); 4806 Py_DECREF(version_type); 4807 if (v == NULL) { 4808 return NULL; 4809 } 4810 PyDict_SetItemString(d, "ncurses_version", v); 4811 Py_DECREF(v); 4812#endif /* NCURSES_VERSION */ 4813 4814 SetDictInt("ERR", ERR); 4815 SetDictInt("OK", OK); 4816 4817 /* Here are some attributes you can add to chars to print */ 4818 4819 SetDictInt("A_ATTRIBUTES", A_ATTRIBUTES); 4820 SetDictInt("A_NORMAL", A_NORMAL); 4821 SetDictInt("A_STANDOUT", A_STANDOUT); 4822 SetDictInt("A_UNDERLINE", A_UNDERLINE); 4823 SetDictInt("A_REVERSE", A_REVERSE); 4824 SetDictInt("A_BLINK", A_BLINK); 4825 SetDictInt("A_DIM", A_DIM); 4826 SetDictInt("A_BOLD", A_BOLD); 4827 SetDictInt("A_ALTCHARSET", A_ALTCHARSET); 4828 SetDictInt("A_INVIS", A_INVIS); 4829 SetDictInt("A_PROTECT", A_PROTECT); 4830 SetDictInt("A_CHARTEXT", A_CHARTEXT); 4831 SetDictInt("A_COLOR", A_COLOR); 4832 4833 /* The following are never available with strict SYSV curses */ 4834#ifdef A_HORIZONTAL 4835 SetDictInt("A_HORIZONTAL", A_HORIZONTAL); 4836#endif 4837#ifdef A_LEFT 4838 SetDictInt("A_LEFT", A_LEFT); 4839#endif 4840#ifdef A_LOW 4841 SetDictInt("A_LOW", A_LOW); 4842#endif 4843#ifdef A_RIGHT 4844 SetDictInt("A_RIGHT", A_RIGHT); 4845#endif 4846#ifdef A_TOP 4847 SetDictInt("A_TOP", A_TOP); 4848#endif 4849#ifdef A_VERTICAL 4850 SetDictInt("A_VERTICAL", A_VERTICAL); 4851#endif 4852 4853 /* ncurses extension */ 4854#ifdef A_ITALIC 4855 SetDictInt("A_ITALIC", A_ITALIC); 4856#endif 4857 4858 SetDictInt("COLOR_BLACK", COLOR_BLACK); 4859 SetDictInt("COLOR_RED", COLOR_RED); 4860 SetDictInt("COLOR_GREEN", COLOR_GREEN); 4861 SetDictInt("COLOR_YELLOW", COLOR_YELLOW); 4862 SetDictInt("COLOR_BLUE", COLOR_BLUE); 4863 SetDictInt("COLOR_MAGENTA", COLOR_MAGENTA); 4864 SetDictInt("COLOR_CYAN", COLOR_CYAN); 4865 SetDictInt("COLOR_WHITE", COLOR_WHITE); 4866 4867#ifdef NCURSES_MOUSE_VERSION 4868 /* Mouse-related constants */ 4869 SetDictInt("BUTTON1_PRESSED", BUTTON1_PRESSED); 4870 SetDictInt("BUTTON1_RELEASED", BUTTON1_RELEASED); 4871 SetDictInt("BUTTON1_CLICKED", BUTTON1_CLICKED); 4872 SetDictInt("BUTTON1_DOUBLE_CLICKED", BUTTON1_DOUBLE_CLICKED); 4873 SetDictInt("BUTTON1_TRIPLE_CLICKED", BUTTON1_TRIPLE_CLICKED); 4874 4875 SetDictInt("BUTTON2_PRESSED", BUTTON2_PRESSED); 4876 SetDictInt("BUTTON2_RELEASED", BUTTON2_RELEASED); 4877 SetDictInt("BUTTON2_CLICKED", BUTTON2_CLICKED); 4878 SetDictInt("BUTTON2_DOUBLE_CLICKED", BUTTON2_DOUBLE_CLICKED); 4879 SetDictInt("BUTTON2_TRIPLE_CLICKED", BUTTON2_TRIPLE_CLICKED); 4880 4881 SetDictInt("BUTTON3_PRESSED", BUTTON3_PRESSED); 4882 SetDictInt("BUTTON3_RELEASED", BUTTON3_RELEASED); 4883 SetDictInt("BUTTON3_CLICKED", BUTTON3_CLICKED); 4884 SetDictInt("BUTTON3_DOUBLE_CLICKED", BUTTON3_DOUBLE_CLICKED); 4885 SetDictInt("BUTTON3_TRIPLE_CLICKED", BUTTON3_TRIPLE_CLICKED); 4886 4887 SetDictInt("BUTTON4_PRESSED", BUTTON4_PRESSED); 4888 SetDictInt("BUTTON4_RELEASED", BUTTON4_RELEASED); 4889 SetDictInt("BUTTON4_CLICKED", BUTTON4_CLICKED); 4890 SetDictInt("BUTTON4_DOUBLE_CLICKED", BUTTON4_DOUBLE_CLICKED); 4891 SetDictInt("BUTTON4_TRIPLE_CLICKED", BUTTON4_TRIPLE_CLICKED); 4892 4893#if NCURSES_MOUSE_VERSION > 1 4894 SetDictInt("BUTTON5_PRESSED", BUTTON5_PRESSED); 4895 SetDictInt("BUTTON5_RELEASED", BUTTON5_RELEASED); 4896 SetDictInt("BUTTON5_CLICKED", BUTTON5_CLICKED); 4897 SetDictInt("BUTTON5_DOUBLE_CLICKED", BUTTON5_DOUBLE_CLICKED); 4898 SetDictInt("BUTTON5_TRIPLE_CLICKED", BUTTON5_TRIPLE_CLICKED); 4899#endif 4900 4901 SetDictInt("BUTTON_SHIFT", BUTTON_SHIFT); 4902 SetDictInt("BUTTON_CTRL", BUTTON_CTRL); 4903 SetDictInt("BUTTON_ALT", BUTTON_ALT); 4904 4905 SetDictInt("ALL_MOUSE_EVENTS", ALL_MOUSE_EVENTS); 4906 SetDictInt("REPORT_MOUSE_POSITION", REPORT_MOUSE_POSITION); 4907#endif 4908 /* Now set everything up for KEY_ variables */ 4909 { 4910 int key; 4911 char *key_n; 4912 char *key_n2; 4913 for (key=KEY_MIN;key < KEY_MAX; key++) { 4914 key_n = (char *)keyname(key); 4915 if (key_n == NULL || strcmp(key_n,"UNKNOWN KEY")==0) 4916 continue; 4917 if (strncmp(key_n,"KEY_F(",6)==0) { 4918 char *p1, *p2; 4919 key_n2 = PyMem_Malloc(strlen(key_n)+1); 4920 if (!key_n2) { 4921 PyErr_NoMemory(); 4922 break; 4923 } 4924 p1 = key_n; 4925 p2 = key_n2; 4926 while (*p1) { 4927 if (*p1 != '(' && *p1 != ')') { 4928 *p2 = *p1; 4929 p2++; 4930 } 4931 p1++; 4932 } 4933 *p2 = (char)0; 4934 } else 4935 key_n2 = key_n; 4936 SetDictInt(key_n2,key); 4937 if (key_n2 != key_n) 4938 PyMem_Free(key_n2); 4939 } 4940 SetDictInt("KEY_MIN", KEY_MIN); 4941 SetDictInt("KEY_MAX", KEY_MAX); 4942 } 4943 4944 if (PyModule_AddType(m, &PyCursesWindow_Type) < 0) { 4945 return NULL; 4946 } 4947 return m; 4948} 4949