Christian Heimes | 2202f87 | 2008-02-06 14:31:34 +0000 | [diff] [blame] | 1 | .. _curses-howto: |
| 2 | |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 3 | ********************************** |
| 4 | Curses Programming with Python |
| 5 | ********************************** |
| 6 | |
| 7 | :Author: A.M. Kuchling, Eric S. Raymond |
Christian Heimes | 679db4a | 2008-01-18 09:56:22 +0000 | [diff] [blame] | 8 | :Release: 2.03 |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 9 | |
| 10 | |
| 11 | .. topic:: Abstract |
| 12 | |
| 13 | This document describes how to write text-mode programs with Python 2.x, using |
| 14 | the :mod:`curses` extension module to control the display. |
| 15 | |
| 16 | |
| 17 | What is curses? |
| 18 | =============== |
| 19 | |
| 20 | The curses library supplies a terminal-independent screen-painting and |
| 21 | keyboard-handling facility for text-based terminals; such terminals include |
| 22 | VT100s, the Linux console, and the simulated terminal provided by X11 programs |
| 23 | such as xterm and rxvt. Display terminals support various control codes to |
| 24 | perform common operations such as moving the cursor, scrolling the screen, and |
| 25 | erasing areas. Different terminals use widely differing codes, and often have |
| 26 | their own minor quirks. |
| 27 | |
| 28 | In a world of X displays, one might ask "why bother"? It's true that |
| 29 | character-cell display terminals are an obsolete technology, but there are |
| 30 | niches in which being able to do fancy things with them are still valuable. One |
| 31 | is on small-footprint or embedded Unixes that don't carry an X server. Another |
| 32 | is for tools like OS installers and kernel configurators that may have to run |
| 33 | before X is available. |
| 34 | |
| 35 | The curses library hides all the details of different terminals, and provides |
| 36 | the programmer with an abstraction of a display, containing multiple |
| 37 | non-overlapping windows. The contents of a window can be changed in various |
| 38 | ways-- adding text, erasing it, changing its appearance--and the curses library |
| 39 | will automagically figure out what control codes need to be sent to the terminal |
| 40 | to produce the right output. |
| 41 | |
| 42 | The curses library was originally written for BSD Unix; the later System V |
| 43 | versions of Unix from AT&T added many enhancements and new functions. BSD curses |
| 44 | is no longer maintained, having been replaced by ncurses, which is an |
| 45 | open-source implementation of the AT&T interface. If you're using an |
| 46 | open-source Unix such as Linux or FreeBSD, your system almost certainly uses |
| 47 | ncurses. Since most current commercial Unix versions are based on System V |
| 48 | code, all the functions described here will probably be available. The older |
| 49 | versions of curses carried by some proprietary Unixes may not support |
| 50 | everything, though. |
| 51 | |
| 52 | No one has made a Windows port of the curses module. On a Windows platform, try |
| 53 | the Console module written by Fredrik Lundh. The Console module provides |
| 54 | cursor-addressable text output, plus full support for mouse and keyboard input, |
Christian Heimes | dd15f6c | 2008-03-16 00:07:10 +0000 | [diff] [blame] | 55 | and is available from http://effbot.org/zone/console-index.htm. |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 56 | |
| 57 | |
| 58 | The Python curses module |
| 59 | ------------------------ |
| 60 | |
| 61 | Thy Python module is a fairly simple wrapper over the C functions provided by |
| 62 | curses; if you're already familiar with curses programming in C, it's really |
| 63 | easy to transfer that knowledge to Python. The biggest difference is that the |
| 64 | Python interface makes things simpler, by merging different C functions such as |
| 65 | :func:`addstr`, :func:`mvaddstr`, :func:`mvwaddstr`, into a single |
| 66 | :meth:`addstr` method. You'll see this covered in more detail later. |
| 67 | |
| 68 | This HOWTO is simply an introduction to writing text-mode programs with curses |
| 69 | and Python. It doesn't attempt to be a complete guide to the curses API; for |
| 70 | that, see the Python library guide's section on ncurses, and the C manual pages |
| 71 | for ncurses. It will, however, give you the basic ideas. |
| 72 | |
| 73 | |
| 74 | Starting and ending a curses application |
| 75 | ======================================== |
| 76 | |
| 77 | Before doing anything, curses must be initialized. This is done by calling the |
| 78 | :func:`initscr` function, which will determine the terminal type, send any |
| 79 | required setup codes to the terminal, and create various internal data |
| 80 | structures. If successful, :func:`initscr` returns a window object representing |
| 81 | the entire screen; this is usually called ``stdscr``, after the name of the |
| 82 | corresponding C variable. :: |
| 83 | |
| 84 | import curses |
| 85 | stdscr = curses.initscr() |
| 86 | |
| 87 | Usually curses applications turn off automatic echoing of keys to the screen, in |
| 88 | order to be able to read keys and only display them under certain circumstances. |
| 89 | This requires calling the :func:`noecho` function. :: |
| 90 | |
| 91 | curses.noecho() |
| 92 | |
| 93 | Applications will also commonly need to react to keys instantly, without |
| 94 | requiring the Enter key to be pressed; this is called cbreak mode, as opposed to |
| 95 | the usual buffered input mode. :: |
| 96 | |
| 97 | curses.cbreak() |
| 98 | |
| 99 | Terminals usually return special keys, such as the cursor keys or navigation |
| 100 | keys such as Page Up and Home, as a multibyte escape sequence. While you could |
| 101 | write your application to expect such sequences and process them accordingly, |
| 102 | curses can do it for you, returning a special value such as |
| 103 | :const:`curses.KEY_LEFT`. To get curses to do the job, you'll have to enable |
| 104 | keypad mode. :: |
| 105 | |
| 106 | stdscr.keypad(1) |
| 107 | |
| 108 | Terminating a curses application is much easier than starting one. You'll need |
| 109 | to call :: |
| 110 | |
| 111 | curses.nocbreak(); stdscr.keypad(0); curses.echo() |
| 112 | |
| 113 | to reverse the curses-friendly terminal settings. Then call the :func:`endwin` |
| 114 | function to restore the terminal to its original operating mode. :: |
| 115 | |
| 116 | curses.endwin() |
| 117 | |
| 118 | A common problem when debugging a curses application is to get your terminal |
| 119 | messed up when the application dies without restoring the terminal to its |
| 120 | previous state. In Python this commonly happens when your code is buggy and |
Georg Brandl | 11ee31a | 2012-03-25 08:43:22 +0200 | [diff] [blame] | 121 | raises an uncaught exception. Keys are no longer echoed to the screen when |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 122 | you type them, for example, which makes using the shell difficult. |
| 123 | |
| 124 | In Python you can avoid these complications and make debugging much easier by |
| 125 | importing the module :mod:`curses.wrapper`. It supplies a :func:`wrapper` |
| 126 | function that takes a callable. It does the initializations described above, |
| 127 | and also initializes colors if color support is present. It then runs your |
| 128 | provided callable and finally deinitializes appropriately. The callable is |
| 129 | called inside a try-catch clause which catches exceptions, performs curses |
| 130 | deinitialization, and then passes the exception upwards. Thus, your terminal |
| 131 | won't be left in a funny state on exception. |
| 132 | |
| 133 | |
| 134 | Windows and Pads |
| 135 | ================ |
| 136 | |
| 137 | Windows are the basic abstraction in curses. A window object represents a |
| 138 | rectangular area of the screen, and supports various methods to display text, |
| 139 | erase it, allow the user to input strings, and so forth. |
| 140 | |
| 141 | The ``stdscr`` object returned by the :func:`initscr` function is a window |
| 142 | object that covers the entire screen. Many programs may need only this single |
| 143 | window, but you might wish to divide the screen into smaller windows, in order |
| 144 | to redraw or clear them separately. The :func:`newwin` function creates a new |
| 145 | window of a given size, returning the new window object. :: |
| 146 | |
| 147 | begin_x = 20 ; begin_y = 7 |
| 148 | height = 5 ; width = 40 |
| 149 | win = curses.newwin(height, width, begin_y, begin_x) |
| 150 | |
| 151 | A word about the coordinate system used in curses: coordinates are always passed |
| 152 | in the order *y,x*, and the top-left corner of a window is coordinate (0,0). |
| 153 | This breaks a common convention for handling coordinates, where the *x* |
| 154 | coordinate usually comes first. This is an unfortunate difference from most |
| 155 | other computer applications, but it's been part of curses since it was first |
| 156 | written, and it's too late to change things now. |
| 157 | |
| 158 | When you call a method to display or erase text, the effect doesn't immediately |
| 159 | show up on the display. This is because curses was originally written with slow |
| 160 | 300-baud terminal connections in mind; with these terminals, minimizing the time |
| 161 | required to redraw the screen is very important. This lets curses accumulate |
| 162 | changes to the screen, and display them in the most efficient manner. For |
| 163 | example, if your program displays some characters in a window, and then clears |
| 164 | the window, there's no need to send the original characters because they'd never |
| 165 | be visible. |
| 166 | |
| 167 | Accordingly, curses requires that you explicitly tell it to redraw windows, |
| 168 | using the :func:`refresh` method of window objects. In practice, this doesn't |
| 169 | really complicate programming with curses much. Most programs go into a flurry |
| 170 | of activity, and then pause waiting for a keypress or some other action on the |
| 171 | part of the user. All you have to do is to be sure that the screen has been |
| 172 | redrawn before pausing to wait for user input, by simply calling |
| 173 | ``stdscr.refresh()`` or the :func:`refresh` method of some other relevant |
| 174 | window. |
| 175 | |
| 176 | A pad is a special case of a window; it can be larger than the actual display |
| 177 | screen, and only a portion of it displayed at a time. Creating a pad simply |
| 178 | requires the pad's height and width, while refreshing a pad requires giving the |
| 179 | coordinates of the on-screen area where a subsection of the pad will be |
| 180 | displayed. :: |
| 181 | |
| 182 | pad = curses.newpad(100, 100) |
| 183 | # These loops fill the pad with letters; this is |
| 184 | # explained in the next section |
| 185 | for y in range(0, 100): |
| 186 | for x in range(0, 100): |
| 187 | try: pad.addch(y,x, ord('a') + (x*x+y*y) % 26 ) |
| 188 | except curses.error: pass |
| 189 | |
| 190 | # Displays a section of the pad in the middle of the screen |
| 191 | pad.refresh( 0,0, 5,5, 20,75) |
| 192 | |
| 193 | The :func:`refresh` call displays a section of the pad in the rectangle |
| 194 | extending from coordinate (5,5) to coordinate (20,75) on the screen; the upper |
| 195 | left corner of the displayed section is coordinate (0,0) on the pad. Beyond |
| 196 | that difference, pads are exactly like ordinary windows and support the same |
| 197 | methods. |
| 198 | |
| 199 | If you have multiple windows and pads on screen there is a more efficient way to |
| 200 | go, which will prevent annoying screen flicker at refresh time. Use the |
| 201 | :meth:`noutrefresh` method of each window to update the data structure |
| 202 | representing the desired state of the screen; then change the physical screen to |
| 203 | match the desired state in one go with the function :func:`doupdate`. The |
| 204 | normal :meth:`refresh` method calls :func:`doupdate` as its last act. |
| 205 | |
| 206 | |
| 207 | Displaying Text |
| 208 | =============== |
| 209 | |
| 210 | From a C programmer's point of view, curses may sometimes look like a twisty |
| 211 | maze of functions, all subtly different. For example, :func:`addstr` displays a |
| 212 | string at the current cursor location in the ``stdscr`` window, while |
| 213 | :func:`mvaddstr` moves to a given y,x coordinate first before displaying the |
| 214 | string. :func:`waddstr` is just like :func:`addstr`, but allows specifying a |
| 215 | window to use, instead of using ``stdscr`` by default. :func:`mvwaddstr` follows |
| 216 | similarly. |
| 217 | |
| 218 | Fortunately the Python interface hides all these details; ``stdscr`` is a window |
| 219 | object like any other, and methods like :func:`addstr` accept multiple argument |
| 220 | forms. Usually there are four different forms. |
| 221 | |
| 222 | +---------------------------------+-----------------------------------------------+ |
| 223 | | Form | Description | |
| 224 | +=================================+===============================================+ |
| 225 | | *str* or *ch* | Display the string *str* or character *ch* at | |
| 226 | | | the current position | |
| 227 | +---------------------------------+-----------------------------------------------+ |
| 228 | | *str* or *ch*, *attr* | Display the string *str* or character *ch*, | |
| 229 | | | using attribute *attr* at the current | |
| 230 | | | position | |
| 231 | +---------------------------------+-----------------------------------------------+ |
| 232 | | *y*, *x*, *str* or *ch* | Move to position *y,x* within the window, and | |
| 233 | | | display *str* or *ch* | |
| 234 | +---------------------------------+-----------------------------------------------+ |
| 235 | | *y*, *x*, *str* or *ch*, *attr* | Move to position *y,x* within the window, and | |
| 236 | | | display *str* or *ch*, using attribute *attr* | |
| 237 | +---------------------------------+-----------------------------------------------+ |
| 238 | |
| 239 | Attributes allow displaying text in highlighted forms, such as in boldface, |
| 240 | underline, reverse code, or in color. They'll be explained in more detail in |
| 241 | the next subsection. |
| 242 | |
| 243 | The :func:`addstr` function takes a Python string as the value to be displayed, |
| 244 | while the :func:`addch` functions take a character, which can be either a Python |
| 245 | string of length 1 or an integer. If it's a string, you're limited to |
| 246 | displaying characters between 0 and 255. SVr4 curses provides constants for |
| 247 | extension characters; these constants are integers greater than 255. For |
| 248 | example, :const:`ACS_PLMINUS` is a +/- symbol, and :const:`ACS_ULCORNER` is the |
| 249 | upper left corner of a box (handy for drawing borders). |
| 250 | |
| 251 | Windows remember where the cursor was left after the last operation, so if you |
| 252 | leave out the *y,x* coordinates, the string or character will be displayed |
| 253 | wherever the last operation left off. You can also move the cursor with the |
| 254 | ``move(y,x)`` method. Because some terminals always display a flashing cursor, |
| 255 | you may want to ensure that the cursor is positioned in some location where it |
| 256 | won't be distracting; it can be confusing to have the cursor blinking at some |
| 257 | apparently random location. |
| 258 | |
| 259 | If your application doesn't need a blinking cursor at all, you can call |
| 260 | ``curs_set(0)`` to make it invisible. Equivalently, and for compatibility with |
| 261 | older curses versions, there's a ``leaveok(bool)`` function. When *bool* is |
| 262 | true, the curses library will attempt to suppress the flashing cursor, and you |
| 263 | won't need to worry about leaving it in odd locations. |
| 264 | |
| 265 | |
| 266 | Attributes and Color |
| 267 | -------------------- |
| 268 | |
| 269 | Characters can be displayed in different ways. Status lines in a text-based |
| 270 | application are commonly shown in reverse video; a text viewer may need to |
| 271 | highlight certain words. curses supports this by allowing you to specify an |
| 272 | attribute for each cell on the screen. |
| 273 | |
Georg Brandl | 11ee31a | 2012-03-25 08:43:22 +0200 | [diff] [blame] | 274 | An attribute is an integer, each bit representing a different attribute. You can |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 275 | try to display text with multiple attribute bits set, but curses doesn't |
| 276 | guarantee that all the possible combinations are available, or that they're all |
| 277 | visually distinct. That depends on the ability of the terminal being used, so |
| 278 | it's safest to stick to the most commonly available attributes, listed here. |
| 279 | |
| 280 | +----------------------+--------------------------------------+ |
| 281 | | Attribute | Description | |
| 282 | +======================+======================================+ |
| 283 | | :const:`A_BLINK` | Blinking text | |
| 284 | +----------------------+--------------------------------------+ |
| 285 | | :const:`A_BOLD` | Extra bright or bold text | |
| 286 | +----------------------+--------------------------------------+ |
| 287 | | :const:`A_DIM` | Half bright text | |
| 288 | +----------------------+--------------------------------------+ |
| 289 | | :const:`A_REVERSE` | Reverse-video text | |
| 290 | +----------------------+--------------------------------------+ |
| 291 | | :const:`A_STANDOUT` | The best highlighting mode available | |
| 292 | +----------------------+--------------------------------------+ |
| 293 | | :const:`A_UNDERLINE` | Underlined text | |
| 294 | +----------------------+--------------------------------------+ |
| 295 | |
| 296 | So, to display a reverse-video status line on the top line of the screen, you |
| 297 | could code:: |
| 298 | |
| 299 | stdscr.addstr(0, 0, "Current mode: Typing mode", |
Georg Brandl | a1c6a1c | 2009-01-03 21:26:05 +0000 | [diff] [blame] | 300 | curses.A_REVERSE) |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 301 | stdscr.refresh() |
| 302 | |
Georg Brandl | 11ee31a | 2012-03-25 08:43:22 +0200 | [diff] [blame] | 303 | The curses library also supports color on those terminals that provide it. The |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 304 | most common such terminal is probably the Linux console, followed by color |
| 305 | xterms. |
| 306 | |
| 307 | To use color, you must call the :func:`start_color` function soon after calling |
| 308 | :func:`initscr`, to initialize the default color set (the |
| 309 | :func:`curses.wrapper.wrapper` function does this automatically). Once that's |
| 310 | done, the :func:`has_colors` function returns TRUE if the terminal in use can |
| 311 | actually display color. (Note: curses uses the American spelling 'color', |
| 312 | instead of the Canadian/British spelling 'colour'. If you're used to the |
| 313 | British spelling, you'll have to resign yourself to misspelling it for the sake |
| 314 | of these functions.) |
| 315 | |
| 316 | The curses library maintains a finite number of color pairs, containing a |
| 317 | foreground (or text) color and a background color. You can get the attribute |
| 318 | value corresponding to a color pair with the :func:`color_pair` function; this |
| 319 | can be bitwise-OR'ed with other attributes such as :const:`A_REVERSE`, but |
| 320 | again, such combinations are not guaranteed to work on all terminals. |
| 321 | |
| 322 | An example, which displays a line of text using color pair 1:: |
| 323 | |
| 324 | stdscr.addstr( "Pretty text", curses.color_pair(1) ) |
| 325 | stdscr.refresh() |
| 326 | |
| 327 | As I said before, a color pair consists of a foreground and background color. |
| 328 | :func:`start_color` initializes 8 basic colors when it activates color mode. |
| 329 | They are: 0:black, 1:red, 2:green, 3:yellow, 4:blue, 5:magenta, 6:cyan, and |
| 330 | 7:white. The curses module defines named constants for each of these colors: |
| 331 | :const:`curses.COLOR_BLACK`, :const:`curses.COLOR_RED`, and so forth. |
| 332 | |
| 333 | The ``init_pair(n, f, b)`` function changes the definition of color pair *n*, to |
| 334 | foreground color f and background color b. Color pair 0 is hard-wired to white |
| 335 | on black, and cannot be changed. |
| 336 | |
| 337 | Let's put all this together. To change color 1 to red text on a white |
| 338 | background, you would call:: |
| 339 | |
| 340 | curses.init_pair(1, curses.COLOR_RED, curses.COLOR_WHITE) |
| 341 | |
| 342 | When you change a color pair, any text already displayed using that color pair |
| 343 | will change to the new colors. You can also display new text in this color |
| 344 | with:: |
| 345 | |
| 346 | stdscr.addstr(0,0, "RED ALERT!", curses.color_pair(1) ) |
| 347 | |
| 348 | Very fancy terminals can change the definitions of the actual colors to a given |
| 349 | RGB value. This lets you change color 1, which is usually red, to purple or |
| 350 | blue or any other color you like. Unfortunately, the Linux console doesn't |
| 351 | support this, so I'm unable to try it out, and can't provide any examples. You |
| 352 | can check if your terminal can do this by calling :func:`can_change_color`, |
| 353 | which returns TRUE if the capability is there. If you're lucky enough to have |
| 354 | such a talented terminal, consult your system's man pages for more information. |
| 355 | |
| 356 | |
| 357 | User Input |
| 358 | ========== |
| 359 | |
| 360 | The curses library itself offers only very simple input mechanisms. Python's |
| 361 | support adds a text-input widget that makes up some of the lack. |
| 362 | |
| 363 | The most common way to get input to a window is to use its :meth:`getch` method. |
| 364 | :meth:`getch` pauses and waits for the user to hit a key, displaying it if |
| 365 | :func:`echo` has been called earlier. You can optionally specify a coordinate |
| 366 | to which the cursor should be moved before pausing. |
| 367 | |
| 368 | It's possible to change this behavior with the method :meth:`nodelay`. After |
| 369 | ``nodelay(1)``, :meth:`getch` for the window becomes non-blocking and returns |
| 370 | ``curses.ERR`` (a value of -1) when no input is ready. There's also a |
| 371 | :func:`halfdelay` function, which can be used to (in effect) set a timer on each |
Christian Heimes | 679db4a | 2008-01-18 09:56:22 +0000 | [diff] [blame] | 372 | :meth:`getch`; if no input becomes available within a specified |
| 373 | delay (measured in tenths of a second), curses raises an exception. |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 374 | |
| 375 | The :meth:`getch` method returns an integer; if it's between 0 and 255, it |
| 376 | represents the ASCII code of the key pressed. Values greater than 255 are |
| 377 | special keys such as Page Up, Home, or the cursor keys. You can compare the |
| 378 | value returned to constants such as :const:`curses.KEY_PPAGE`, |
| 379 | :const:`curses.KEY_HOME`, or :const:`curses.KEY_LEFT`. Usually the main loop of |
| 380 | your program will look something like this:: |
| 381 | |
Collin Winter | 4633448 | 2007-09-10 00:49:57 +0000 | [diff] [blame] | 382 | while True: |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 383 | c = stdscr.getch() |
| 384 | if c == ord('p'): PrintDocument() |
| 385 | elif c == ord('q'): break # Exit the while() |
| 386 | elif c == curses.KEY_HOME: x = y = 0 |
| 387 | |
| 388 | The :mod:`curses.ascii` module supplies ASCII class membership functions that |
| 389 | take either integer or 1-character-string arguments; these may be useful in |
| 390 | writing more readable tests for your command interpreters. It also supplies |
| 391 | conversion functions that take either integer or 1-character-string arguments |
| 392 | and return the same type. For example, :func:`curses.ascii.ctrl` returns the |
| 393 | control character corresponding to its argument. |
| 394 | |
| 395 | There's also a method to retrieve an entire string, :const:`getstr()`. It isn't |
| 396 | used very often, because its functionality is quite limited; the only editing |
| 397 | keys available are the backspace key and the Enter key, which terminates the |
| 398 | string. It can optionally be limited to a fixed number of characters. :: |
| 399 | |
| 400 | curses.echo() # Enable echoing of characters |
| 401 | |
Georg Brandl | 48310cd | 2009-01-03 21:18:54 +0000 | [diff] [blame] | 402 | # Get a 15-character string, with the cursor on the top line |
| 403 | s = stdscr.getstr(0,0, 15) |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 404 | |
| 405 | The Python :mod:`curses.textpad` module supplies something better. With it, you |
| 406 | can turn a window into a text box that supports an Emacs-like set of |
| 407 | keybindings. Various methods of :class:`Textbox` class support editing with |
| 408 | input validation and gathering the edit results either with or without trailing |
| 409 | spaces. See the library documentation on :mod:`curses.textpad` for the |
| 410 | details. |
| 411 | |
| 412 | |
| 413 | For More Information |
| 414 | ==================== |
| 415 | |
| 416 | This HOWTO didn't cover some advanced topics, such as screen-scraping or |
| 417 | capturing mouse events from an xterm instance. But the Python library page for |
| 418 | the curses modules is now pretty complete. You should browse it next. |
| 419 | |
| 420 | If you're in doubt about the detailed behavior of any of the ncurses entry |
| 421 | points, consult the manual pages for your curses implementation, whether it's |
| 422 | ncurses or a proprietary Unix vendor's. The manual pages will document any |
| 423 | quirks, and provide complete lists of all the functions, attributes, and |
| 424 | :const:`ACS_\*` characters available to you. |
| 425 | |
| 426 | Because the curses API is so large, some functions aren't supported in the |
| 427 | Python interface, not because they're difficult to implement, but because no one |
| 428 | has needed them yet. Feel free to add them and then submit a patch. Also, we |
Benjamin Peterson | e0124bd | 2009-03-09 21:04:33 +0000 | [diff] [blame] | 429 | don't yet have support for the menu library associated with |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 430 | ncurses; feel free to add that. |
| 431 | |
| 432 | If you write an interesting little program, feel free to contribute it as |
| 433 | another demo. We can always use more of them! |
| 434 | |
Christian Heimes | dd15f6c | 2008-03-16 00:07:10 +0000 | [diff] [blame] | 435 | The ncurses FAQ: http://invisible-island.net/ncurses/ncurses.faq.html |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 436 | |