Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 1 | <!-- |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 2 | $Id: hackguide.html,v 1.36 2022/11/26 19:31:56 tom Exp $ |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 3 | **************************************************************************** |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 4 | * Copyright 2019-2020,2022 Thomas E. Dickey * |
| 5 | * Copyright 2000-2013,2017 Free Software Foundation, Inc. * |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 6 | * * |
| 7 | * Permission is hereby granted, free of charge, to any person obtaining a * |
| 8 | * copy of this software and associated documentation files (the * |
| 9 | * "Software"), to deal in the Software without restriction, including * |
| 10 | * without limitation the rights to use, copy, modify, merge, publish, * |
| 11 | * distribute, distribute with modifications, sublicense, and/or sell * |
| 12 | * copies of the Software, and to permit persons to whom the Software is * |
| 13 | * furnished to do so, subject to the following conditions: * |
| 14 | * * |
| 15 | * The above copyright notice and this permission notice shall be included * |
| 16 | * in all copies or substantial portions of the Software. * |
| 17 | * * |
| 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * |
| 19 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * |
| 20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * |
| 21 | * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * |
| 22 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * |
| 23 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * |
| 24 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * |
| 25 | * * |
| 26 | * Except as contained in this notice, the name(s) of the above copyright * |
| 27 | * holders shall not be used in advertising or otherwise to promote the * |
| 28 | * sale, use or other dealings in this Software without prior written * |
| 29 | * authorization. * |
| 30 | **************************************************************************** |
| 31 | --> |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 32 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"> |
| 33 | <html> |
| 34 | <head> |
| 35 | <meta name="generator" content= |
| 36 | "HTML Tidy for HTML5 for Linux version 5.6.0"> |
| 37 | <title>A Hacker's Guide to Ncurses Internals</title> |
| 38 | <link rel="author" href="mailto:bugs-ncurses@gnu.org"> |
| 39 | <meta http-equiv="Content-Type" content= |
| 40 | "text/html; charset=us-ascii"><!-- |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 41 | This document is self-contained, *except* that there is one relative link to |
| 42 | the ncurses-intro.html document, expected to be in the same directory with |
| 43 | this one. |
| 44 | --> |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 45 | </head> |
| 46 | <body> |
| 47 | <h1 class="no-header">A Hacker's Guide to NCURSES</h1> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 48 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 49 | <h2>A Hacker's Guide to NCURSES</h2> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 50 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 51 | <div class="nav"> |
| 52 | <h2>Contents</h2> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 53 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 54 | <ul> |
| 55 | <li><a href="#abstract">Abstract</a></li> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 56 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 57 | <li> |
| 58 | <a href="#objective">Objective of the Package</a> |
| 59 | <ul> |
| 60 | <li><a href="#whysvr4">Why System V Curses?</a></li> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 61 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 62 | <li><a href="#extensions">How to Design Extensions</a></li> |
| 63 | </ul> |
| 64 | </li> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 65 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 66 | <li><a href="#portability">Portability and Configuration</a></li> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 67 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 68 | <li><a href="#documentation">Documentation Conventions</a></li> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 69 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 70 | <li><a href="#bugtrack">How to Report Bugs</a></li> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 71 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 72 | <li> |
| 73 | <a href="#ncurslib">A Tour of the Ncurses Library</a> |
| 74 | <ul> |
| 75 | <li><a href="#loverview">Library Overview</a></li> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 76 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 77 | <li><a href="#engine">The Engine Room</a></li> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 78 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 79 | <li><a href="#input">Keyboard Input</a></li> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 80 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 81 | <li><a href="#mouse">Mouse Events</a></li> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 82 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 83 | <li><a href="#output">Output and Screen Updating</a></li> |
| 84 | </ul> |
| 85 | </li> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 86 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 87 | <li><a href="#fmnote">The Forms and Menu Libraries</a></li> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 88 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 89 | <li> |
| 90 | <a href="#tic">A Tour of the Terminfo Compiler</a> |
| 91 | <ul> |
| 92 | <li><a href="#nonuse">Translation of |
| 93 | Non-<strong>use</strong> Capabilities</a></li> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 94 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 95 | <li><a href="#uses">Use Capability Resolution</a></li> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 96 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 97 | <li><a href="#translation">Source-Form Translation</a></li> |
| 98 | </ul> |
| 99 | </li> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 100 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 101 | <li><a href="#utils">Other Utilities</a></li> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 102 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 103 | <li><a href="#style">Style Tips for Developers</a></li> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 104 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 105 | <li><a href="#port">Porting Hints</a></li> |
| 106 | </ul> |
| 107 | </div> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 108 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 109 | <h2><a name="abstract" id="abstract">Abstract</a></h2> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 110 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 111 | <p>This document is a hacker's tour of the |
| 112 | <strong>ncurses</strong> library and utilities. It discusses |
| 113 | design philosophy, implementation methods, and the conventions |
| 114 | used for coding and documentation. It is recommended reading for |
| 115 | anyone who is interested in porting, extending or improving the |
| 116 | package.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 117 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 118 | <h2><a name="objective" id="objective">Objective of the |
| 119 | Package</a></h2> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 120 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 121 | <p>The objective of the <strong>ncurses</strong> package is to |
| 122 | provide a free software API for character-cell terminals and |
| 123 | terminal emulators with the following characteristics:</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 124 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 125 | <ul> |
| 126 | <li>Source-compatible with historical curses implementations |
| 127 | (including the original BSD curses and System V curses.</li> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 128 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 129 | <li>Conformant with the XSI Curses standard issued as part of |
| 130 | XPG4 by X/Open.</li> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 131 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 132 | <li>High-quality — stable and reliable code, wide |
| 133 | portability, good packaging, superior documentation.</li> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 134 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 135 | <li>Featureful — should eliminate as much of the drudgery |
| 136 | of C interface programming as possible, freeing programmers to |
| 137 | think at a higher level of design.</li> |
| 138 | </ul> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 139 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 140 | <p>These objectives are in priority order. So, for example, |
| 141 | source compatibility with older version must trump featurefulness |
| 142 | — we cannot add features if it means breaking the portion |
| 143 | of the API corresponding to historical curses versions.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 144 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 145 | <h3><a name="whysvr4" id="whysvr4">Why System V Curses?</a></h3> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 146 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 147 | <p>We used System V curses as a model, reverse-engineering their |
| 148 | API, in order to fulfill the first two objectives.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 149 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 150 | <p>System V curses implementations can support BSD curses |
| 151 | programs with just a recompilation, so by capturing the System V |
| 152 | API we also capture BSD's.</p> |
| 153 | |
| 154 | <p>More importantly for the future, the XSI Curses standard |
| 155 | issued by X/Open is explicitly and closely modeled on System V. |
| 156 | So conformance with System V took us most of the way to |
| 157 | base-level XSI conformance.</p> |
| 158 | |
| 159 | <h3><a name="extensions" id="extensions">How to Design |
| 160 | Extensions</a></h3> |
| 161 | |
| 162 | <p>The third objective (standards conformance) requires that it |
| 163 | be easy to condition source code using <strong>ncurses</strong> |
| 164 | so that the absence of nonstandard extensions does not break the |
| 165 | code.</p> |
| 166 | |
| 167 | <p>Accordingly, we have a policy of associating with each |
| 168 | nonstandard extension a feature macro, so that ncurses client |
| 169 | code can use this macro to condition in or out the code that |
| 170 | requires the <strong>ncurses</strong> extension.</p> |
| 171 | |
| 172 | <p>For example, there is a macro |
| 173 | <code>NCURSES_MOUSE_VERSION</code> which XSI Curses does not |
| 174 | define, but which is defined in the <strong>ncurses</strong> |
| 175 | library header. You can use this to condition the calls to the |
| 176 | mouse API calls.</p> |
| 177 | |
| 178 | <h2><a name="portability" id="portability">Portability and |
| 179 | Configuration</a></h2> |
| 180 | |
| 181 | <p>Code written for <strong>ncurses</strong> may assume an |
| 182 | ANSI-standard C compiler and POSIX-compatible OS interface. It |
| 183 | may also assume the presence of a System-V-compatible |
| 184 | <em>select(2)</em> call.</p> |
| 185 | |
| 186 | <p>We encourage (but do not require) developers to make the code |
| 187 | friendly to less-capable UNIX environments wherever possible.</p> |
| 188 | |
| 189 | <p>We encourage developers to support OS-specific optimizations |
| 190 | and methods not available under POSIX/ANSI, provided only |
| 191 | that:</p> |
| 192 | |
| 193 | <ul> |
| 194 | <li>All such code is properly conditioned so the build process |
| 195 | does not attempt to compile it under a plain ANSI/POSIX |
| 196 | environment.</li> |
| 197 | |
| 198 | <li>Adding such implementation methods does not introduce |
| 199 | incompatibilities in the <strong>ncurses</strong> API between |
| 200 | platforms.</li> |
| 201 | </ul> |
| 202 | |
| 203 | <p>We use GNU <code>autoconf(1)</code> as a tool to deal with |
| 204 | portability issues. The right way to leverage an OS-specific |
| 205 | feature is to modify the autoconf specification files |
| 206 | (configure.in and aclocal.m4) to set up a new feature macro, |
| 207 | which you then use to condition your code.</p> |
| 208 | |
| 209 | <h2><a name="documentation" id="documentation">Documentation |
| 210 | Conventions</a></h2> |
| 211 | |
| 212 | <p>There are three kinds of documentation associated with this |
| 213 | package. Each has a different preferred format:</p> |
| 214 | |
| 215 | <ul> |
| 216 | <li>Package-internal files (README, INSTALL, TO-DO etc.)</li> |
| 217 | |
| 218 | <li>Manual pages.</li> |
| 219 | |
| 220 | <li>Everything else (i.e., narrative documentation).</li> |
| 221 | </ul> |
| 222 | |
| 223 | <p>Our conventions are simple:</p> |
| 224 | |
| 225 | <ol> |
| 226 | <li><strong>Maintain package-internal files in plain |
| 227 | text.</strong> The expected viewer for them is <em>more(1)</em> or |
| 228 | an editor window; there is no point in elaborate mark-up.</li> |
| 229 | |
| 230 | <li><strong>Mark up manual pages in the man macros.</strong> |
| 231 | These have to be viewable through traditional <em>man(1)</em> |
| 232 | programs.</li> |
| 233 | |
| 234 | <li><strong>Write everything else in HTML.</strong> |
| 235 | </li> |
| 236 | </ol> |
| 237 | |
| 238 | <p>When in doubt, HTMLize a master and use <em>lynx(1)</em> to |
| 239 | generate plain ASCII (as we do for the announcement |
| 240 | document).</p> |
| 241 | |
| 242 | <p>The reason for choosing HTML is that it is (a) well-adapted |
| 243 | for on-line browsing through viewers that are everywhere; (b) |
| 244 | more easily readable as plain text than most other mark-ups, if |
| 245 | you do not have a viewer; and (c) carries enough information that |
| 246 | you can generate a nice-looking printed version from it. Also, of |
| 247 | course, it make exporting things like the announcement document |
| 248 | to WWW pretty trivial.</p> |
| 249 | |
| 250 | <h2><a name="bugtrack" id="bugtrack">How to Report Bugs</a></h2> |
| 251 | |
| 252 | <p>The <a name="bugreport" id="bugreport">reporting address for |
| 253 | bugs</a> is <a href= |
| 254 | "mailto:bug-ncurses@gnu.org">bug-ncurses@gnu.org</a>. This is a |
| 255 | majordomo list; to join, write to |
| 256 | <code>bug-ncurses-request@gnu.org</code> with a message |
| 257 | containing the line:</p> |
| 258 | |
| 259 | <pre class="code-block"> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 260 | subscribe <name>@<host.domain> |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 261 | </pre> |
| 262 | <p>The <code>ncurses</code> code is maintained by a small group |
| 263 | of volunteers. While we try our best to fix bugs promptly, we |
| 264 | simply do not have a lot of hours to spend on elementary |
| 265 | hand-holding. We rely on intelligent cooperation from our users. |
| 266 | If you think you have found a bug in <code>ncurses</code>, there |
| 267 | are some steps you can take before contacting us that will help |
| 268 | get the bug fixed quickly.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 269 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 270 | <p>In order to use our bug-fixing time efficiently, we put people |
| 271 | who show us they have taken these steps at the head of our queue. |
| 272 | This means that if you do not, you will probably end up at the |
| 273 | tail end and have to wait a while.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 274 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 275 | <ol> |
| 276 | <li><p>Develop a recipe to reproduce the bug. |
| 277 | <p>Bugs we can reproduce are likely to be fixed very quickly, |
| 278 | often within days. The most effective single thing you can do |
| 279 | to get a quick fix is develop a way we can duplicate the bad |
| 280 | behavior — ideally, by giving us source for a small, |
| 281 | portable test program that breaks the library. (Even better |
| 282 | is a keystroke recipe using one of the test programs provided |
| 283 | with the distribution.)</p> |
| 284 | </li> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 285 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 286 | <li><p>Try to reproduce the bug on a different terminal type. |
| 287 | <p>In our experience, most of the behaviors people report as |
| 288 | library bugs are actually due to subtle problems in terminal |
| 289 | descriptions. This is especially likely to be true if you are |
| 290 | using a traditional asynchronous terminal or PC-based |
| 291 | terminal emulator, rather than xterm or a UNIX console |
| 292 | entry.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 293 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 294 | <p>It is therefore extremely helpful if you can tell us |
| 295 | whether or not your problem reproduces on other terminal |
| 296 | types. Usually you will have both a console type and xterm |
| 297 | available; please tell us whether or not your bug reproduces |
| 298 | on both.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 299 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 300 | <p>If you have xterm available, it is also good to collect |
| 301 | xterm reports for different window sizes. This is especially |
| 302 | true if you normally use an unusual xterm window size — |
| 303 | a surprising number of the bugs we have seen are either |
| 304 | triggered or masked by these.</p> |
| 305 | </li> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 306 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 307 | <li><p>Generate and examine a trace file for the broken behavior. |
| 308 | <p>Recompile your program with the debugging versions of the |
| 309 | libraries. Insert a <code>trace()</code> call with the |
| 310 | argument set to <code>TRACE_UPDATE</code>. (See <a href= |
| 311 | "ncurses-intro.html#debugging">"Writing Programs with |
| 312 | NCURSES"</a> for details on trace levels.) Reproduce your |
| 313 | bug, then look at the trace file to see what the library was |
| 314 | actually doing.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 315 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 316 | <p>Another frequent cause of apparent bugs is application |
| 317 | coding errors that cause the wrong things to be put on the |
| 318 | virtual screen. Looking at the virtual-screen dumps in the |
| 319 | trace file will tell you immediately if this is happening, |
| 320 | and save you from the possible embarrassment of being told |
| 321 | that the bug is in your code and is your problem rather than |
| 322 | ours.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 323 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 324 | <p>If the virtual-screen dumps look correct but the bug |
| 325 | persists, it is possible to crank up the trace level to give |
| 326 | more and more information about the library's update actions |
| 327 | and the control sequences it issues to perform them. The test |
| 328 | directory of the distribution contains a tool for digesting |
| 329 | these logs to make them less tedious to wade through.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 330 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 331 | <p>Often you will find terminfo problems at this stage by |
| 332 | noticing that the escape sequences put out for various |
| 333 | capabilities are wrong. If not, you are likely to learn |
| 334 | enough to be able to characterize any bug in the |
| 335 | screen-update logic quite exactly.</p> |
| 336 | </li> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 337 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 338 | <li><p>Report details and symptoms, not just interpretations. |
| 339 | <p>If you do the preceding two steps, it is very likely that |
| 340 | you will discover the nature of the problem yourself and be |
| 341 | able to send us a fix. This will create happy feelings all |
| 342 | around and earn you good karma for the first time you run |
| 343 | into a bug you really cannot characterize and fix |
| 344 | yourself.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 345 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 346 | <p>If you are still stuck, at least you will know what to |
| 347 | tell us. Remember, we need details. If you guess about what |
| 348 | is safe to leave out, you are too likely to be wrong.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 349 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 350 | <p>If your bug produces a bad update, include a trace file. |
| 351 | Try to make the trace at the <em>least</em> voluminous level |
| 352 | that pins down the bug. Logs that have been through |
| 353 | tracemunch are OK, it does not throw away any information |
| 354 | (actually they are better than un-munched ones because they |
| 355 | are easier to read).</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 356 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 357 | <p>If your bug produces a core-dump, please include a |
| 358 | symbolic stack trace generated by gdb(1) or your local |
| 359 | equivalent.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 360 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 361 | <p>Tell us about every terminal on which you have reproduced |
| 362 | the bug — and every terminal on which you cannot. |
| 363 | Ideally, send us terminfo sources for all of these (yours |
| 364 | might differ from ours).</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 365 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 366 | <p>Include your ncurses version and your OS/machine type, of |
| 367 | course! You can find your ncurses version in the |
| 368 | <code>curses.h</code> file.</p> |
| 369 | </li> |
| 370 | </ol> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 371 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 372 | <p>If your problem smells like a logic error or in cursor |
| 373 | movement or scrolling or a bad capability, there are a couple of |
| 374 | tiny test frames for the library algorithms in the progs |
| 375 | directory that may help you isolate it. These are not part of the |
| 376 | normal build, but do have their own make productions.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 377 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 378 | <p>The most important of these is <code>mvcur</code>, a test |
| 379 | frame for the cursor-movement optimization code. With this |
| 380 | program, you can see directly what control sequences will be |
| 381 | emitted for any given cursor movement or scroll/insert/delete |
| 382 | operations. If you think you have got a bad capability |
| 383 | identified, you can disable it and test again. The program is |
| 384 | command-driven and has on-line help.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 385 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 386 | <p>If you think the vertical-scroll optimization is broken, or |
| 387 | just want to understand how it works better, build |
| 388 | <code>hashmap</code> and read the header comments of |
| 389 | <code>hardscroll.c</code> and <code>hashmap.c</code>; then try it |
| 390 | out. You can also test the hardware-scrolling optimization |
| 391 | separately with <code>hardscroll</code>.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 392 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 393 | <h2><a name="ncurslib" id="ncurslib">A Tour of the Ncurses |
| 394 | Library</a></h2> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 395 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 396 | <h3><a name="loverview" id="loverview">Library Overview</a></h3> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 397 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 398 | <p>Most of the library is superstructure — fairly trivial |
| 399 | convenience interfaces to a small set of basic functions and data |
| 400 | structures used to manipulate the virtual screen (in particular, |
| 401 | none of this code does any I/O except through calls to more |
| 402 | fundamental modules described below). The files</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 403 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 404 | <blockquote> |
| 405 | <code>lib_addch.c lib_bkgd.c lib_box.c lib_chgat.c lib_clear.c |
| 406 | lib_clearok.c lib_clrbot.c lib_clreol.c lib_colorset.c |
| 407 | lib_data.c lib_delch.c lib_delwin.c lib_echo.c lib_erase.c |
| 408 | lib_gen.c lib_getstr.c lib_hline.c lib_immedok.c lib_inchstr.c |
| 409 | lib_insch.c lib_insdel.c lib_insstr.c lib_instr.c |
| 410 | lib_isendwin.c lib_keyname.c lib_leaveok.c lib_move.c |
| 411 | lib_mvwin.c lib_overlay.c lib_pad.c lib_printw.c lib_redrawln.c |
| 412 | lib_scanw.c lib_screen.c lib_scroll.c lib_scrollok.c |
| 413 | lib_scrreg.c lib_set_term.c lib_slk.c lib_slkatr_set.c |
| 414 | lib_slkatrof.c lib_slkatron.c lib_slkatrset.c lib_slkattr.c |
| 415 | lib_slkclear.c lib_slkcolor.c lib_slkinit.c lib_slklab.c |
| 416 | lib_slkrefr.c lib_slkset.c lib_slktouch.c lib_touch.c |
| 417 | lib_unctrl.c lib_vline.c lib_wattroff.c lib_wattron.c |
| 418 | lib_window.c</code> |
| 419 | </blockquote> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 420 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 421 | <p>are all in this category. They are very unlikely to need |
| 422 | change, barring bugs or some fundamental reorganization in the |
| 423 | underlying data structures.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 424 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 425 | <p>These files are used only for debugging support:</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 426 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 427 | <blockquote> |
| 428 | <code>lib_trace.c lib_traceatr.c lib_tracebits.c lib_tracechr.c |
| 429 | lib_tracedmp.c lib_tracemse.c trace_buf.c</code> |
| 430 | </blockquote> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 431 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 432 | <p>It is rather unlikely you will ever need to change these, |
| 433 | unless you want to introduce a new debug trace level for some |
| 434 | reason.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 435 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 436 | <p>There is another group of files that do direct I/O via |
| 437 | <em>tputs()</em>, computations on the terminal capabilities, or |
| 438 | queries to the OS environment, but nevertheless have only fairly |
| 439 | low complexity. These include:</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 440 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 441 | <blockquote> |
| 442 | <code>lib_acs.c lib_beep.c lib_color.c lib_endwin.c |
| 443 | lib_initscr.c lib_longname.c lib_newterm.c lib_options.c |
| 444 | lib_termcap.c lib_ti.c lib_tparm.c lib_tputs.c lib_vidattr.c |
| 445 | read_entry.c.</code> |
| 446 | </blockquote> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 447 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 448 | <p>They are likely to need revision only if ncurses is being |
| 449 | ported to an environment without an underlying terminfo |
| 450 | capability representation.</p> |
| 451 | |
| 452 | <p>These files have serious hooks into the tty driver and signal |
| 453 | facilities:</p> |
| 454 | |
| 455 | <blockquote> |
| 456 | <code>lib_kernel.c lib_baudrate.c lib_raw.c lib_tstp.c |
| 457 | lib_twait.c</code> |
| 458 | </blockquote> |
| 459 | |
| 460 | <p>If you run into porting snafus moving the package to another |
| 461 | UNIX, the problem is likely to be in one of these files. The file |
| 462 | <code>lib_print.c</code> uses sleep(2) and also falls in this |
| 463 | category.</p> |
| 464 | |
| 465 | <p>Almost all of the real work is done in the files</p> |
| 466 | |
| 467 | <blockquote> |
| 468 | <code>hardscroll.c hashmap.c lib_addch.c lib_doupdate.c |
| 469 | lib_getch.c lib_mouse.c lib_mvcur.c lib_refresh.c lib_setup.c |
| 470 | lib_vidattr.c</code> |
| 471 | </blockquote> |
| 472 | |
| 473 | <p>Most of the algorithmic complexity in the library lives in |
| 474 | these files. If there is a real bug in <strong>ncurses</strong> |
| 475 | itself, it is probably here. We will tour some of these files in |
| 476 | detail below (see <a href="#engine">The Engine Room</a>).</p> |
| 477 | |
| 478 | <p>Finally, there is a group of files that is actually most of |
| 479 | the terminfo compiler. The reason this code lives in the |
| 480 | <strong>ncurses</strong> library is to support fallback to |
| 481 | /etc/termcap. These files include</p> |
| 482 | |
| 483 | <blockquote> |
| 484 | <code>alloc_entry.c captoinfo.c comp_captab.c comp_error.c |
| 485 | comp_hash.c comp_parse.c comp_scan.c parse_entry.c |
| 486 | read_termcap.c write_entry.c</code> |
| 487 | </blockquote> |
| 488 | |
| 489 | <p>We will discuss these in the compiler tour.</p> |
| 490 | |
| 491 | <h3><a name="engine" id="engine">The Engine Room</a></h3> |
| 492 | |
| 493 | <h4><a name="input" id="input">Keyboard Input</a></h4> |
| 494 | |
| 495 | <p>All <code>ncurses</code> input funnels through the function |
| 496 | <code>wgetch()</code>, defined in <code>lib_getch.c</code>. This |
| 497 | function is tricky; it has to poll for keyboard and mouse events |
| 498 | and do a running match of incoming input against the set of |
| 499 | defined special keys.</p> |
| 500 | |
| 501 | <p>The central data structure in this module is a FIFO queue, |
| 502 | used to match multiple-character input sequences against |
| 503 | special-key capabilities; also to implement pushback via |
| 504 | <code>ungetch()</code>.</p> |
| 505 | |
| 506 | <p>The <code>wgetch()</code> code distinguishes between function |
| 507 | key sequences and the same sequences typed manually by doing a |
| 508 | timed wait after each input character that could lead a function |
| 509 | key sequence. If the entire sequence takes less than 1 second, it |
| 510 | is assumed to have been generated by a function key press.</p> |
| 511 | |
| 512 | <p>Hackers bruised by previous encounters with variant |
| 513 | <code>select(2)</code> calls may find the code in |
| 514 | <code>lib_twait.c</code> interesting. It deals with the problem |
| 515 | that some BSD selects do not return a reliable time-left value. |
| 516 | The function <code>timed_wait()</code> effectively simulates a |
| 517 | System V select.</p> |
| 518 | |
| 519 | <h4><a name="mouse" id="mouse">Mouse Events</a></h4> |
| 520 | |
| 521 | <p>If the mouse interface is active, <code>wgetch()</code> polls |
| 522 | for mouse events each call, before it goes to the keyboard for |
| 523 | input. It is up to <code>lib_mouse.c</code> how the polling is |
| 524 | accomplished; it may vary for different devices.</p> |
| 525 | |
| 526 | <p>Under xterm, however, mouse event notifications come in via |
| 527 | the keyboard input stream. They are recognized by having the |
| 528 | <strong>kmous</strong> capability as a prefix. This is kind of |
| 529 | klugey, but trying to wire in recognition of a mouse key prefix |
| 530 | without going through the function-key machinery would be just |
| 531 | too painful, and this turns out to imply having the prefix |
| 532 | somewhere in the function-key capabilities at terminal-type |
| 533 | initialization.</p> |
| 534 | |
| 535 | <p>This kluge only works because <strong>kmous</strong> is not |
| 536 | actually used by any historic terminal type or curses |
| 537 | implementation we know of. Best guess is it is a relic of some |
| 538 | forgotten experiment in-house at Bell Labs that did not leave any |
| 539 | traces in the publicly-distributed System V terminfo files. If |
| 540 | System V or XPG4 ever gets serious about using it again, this |
| 541 | kluge may have to change.</p> |
| 542 | |
| 543 | <p>Here are some more details about mouse event handling:</p> |
| 544 | |
| 545 | <p>The <code>lib_mouse()</code> code is logically split into a |
| 546 | lower level that accepts event reports in a device-dependent |
| 547 | format and an upper level that parses mouse gestures and filters |
| 548 | events. The mediating data structure is a circular queue of event |
| 549 | structures.</p> |
| 550 | |
| 551 | <p>Functionally, the lower level's job is to pick up primitive |
| 552 | events and put them on the circular queue. This can happen in one |
| 553 | of two ways: either (a) <code>_nc_mouse_event()</code> detects a |
| 554 | series of incoming mouse reports and queues them, or (b) code in |
| 555 | <code>lib_getch.c</code> detects the <strong>kmous</strong> |
| 556 | prefix in the keyboard input stream and calls _nc_mouse_inline to |
| 557 | queue up a series of adjacent mouse reports.</p> |
| 558 | |
| 559 | <p>In either case, <code>_nc_mouse_parse()</code> should be |
| 560 | called after the series is accepted to parse the digested mouse |
| 561 | reports (low-level events) into a gesture (a high-level or |
| 562 | composite event).</p> |
| 563 | |
| 564 | <h4><a name="output" id="output">Output and Screen Updating</a></h4> |
| 565 | |
| 566 | <p>With the single exception of character echoes during a |
| 567 | <code>wgetnstr()</code> call (which simulates cooked-mode line |
| 568 | editing in an ncurses window), the library normally does all its |
| 569 | output at refresh time.</p> |
| 570 | |
| 571 | <p>The main job is to go from the current state of the screen (as |
| 572 | represented in the <code>curscr</code> window structure) to the |
| 573 | desired new state (as represented in the <code>newscr</code> |
| 574 | window structure), while doing as little I/O as possible.</p> |
| 575 | |
| 576 | <p>The brains of this operation are the modules |
| 577 | <code>hashmap.c</code>, <code>hardscroll.c</code> and |
| 578 | <code>lib_doupdate.c</code>; the latter two use |
| 579 | <code>lib_mvcur.c</code>. Essentially, what happens looks like |
| 580 | this:</p> |
| 581 | |
| 582 | <ul> |
| 583 | <li> |
| 584 | <p>The <code>hashmap.c</code> module tries to detect vertical |
| 585 | motion changes between the real and virtual screens. This |
| 586 | information is represented by the oldindex members in the |
| 587 | newscr structure. These are modified by vertical-motion and |
| 588 | clear operations, and both are re-initialized after each |
| 589 | update. To this change-journalling information, the hashmap |
| 590 | code adds deductions made using a modified Heckel algorithm |
| 591 | on hash values generated from the line contents.</p> |
| 592 | </li> |
| 593 | |
| 594 | <li> |
| 595 | <p>The <code>hardscroll.c</code> module computes an optimum |
| 596 | set of scroll, insertion, and deletion operations to make the |
| 597 | indices match. It calls <code>_nc_mvcur_scrolln()</code> in |
| 598 | <code>lib_mvcur.c</code> to do those motions.</p> |
| 599 | </li> |
| 600 | |
| 601 | <li> |
| 602 | <p>Then <code>lib_doupdate.c</code> goes to work. Its job is |
| 603 | to do line-by-line transformations of <code>curscr</code> |
| 604 | lines to <code>newscr</code> lines. Its main tool is the |
| 605 | routine <code>mvcur()</code> in <code>lib_mvcur.c</code>. |
| 606 | This routine does cursor-movement optimization, attempting to |
| 607 | get from given screen location A to given location B in the |
| 608 | fewest output characters possible.</p> |
| 609 | </li> |
| 610 | </ul> |
| 611 | |
| 612 | <p>If you want to work on screen optimizations, you should use |
| 613 | the fact that (in the trace-enabled version of the library) |
| 614 | enabling the <code>TRACE_TIMES</code> trace level causes a report |
| 615 | to be emitted after each screen update giving the elapsed time |
| 616 | and a count of characters emitted during the update. You can use |
| 617 | this to tell when an update optimization improves efficiency.</p> |
| 618 | |
| 619 | <p>In the trace-enabled version of the library, it is also |
| 620 | possible to disable and re-enable various optimizations at |
| 621 | runtime by tweaking the variable |
| 622 | <code>_nc_optimize_enable</code>. See the file |
| 623 | <code>include/curses.h.in</code> for mask values, near the |
| 624 | end.</p> |
| 625 | |
| 626 | <h2><a name="fmnote" id="fmnote">The Forms and Menu Libraries</a></h2> |
| 627 | |
| 628 | <p>The forms and menu libraries should work reliably in any |
| 629 | environment you can port ncurses to. The only portability issue |
| 630 | anywhere in them is what flavor of regular expressions the |
| 631 | built-in form field type TYPE_REGEXP will recognize.</p> |
| 632 | |
| 633 | <p>The configuration code prefers the POSIX regex facility, |
| 634 | modeled on System V's, but will settle for BSD regexps if the |
| 635 | former is not available.</p> |
| 636 | |
| 637 | <p>Historical note: the panels code was written primarily to |
| 638 | assist in porting u386mon 2.0 (comp.sources.misc v14i001-4) to |
| 639 | systems lacking panels support; u386mon 2.10 and beyond use it. |
| 640 | This version has been slightly cleaned up for |
| 641 | <code>ncurses</code>.</p> |
| 642 | |
| 643 | <h2><a name="tic" id="tic">A Tour of the Terminfo Compiler</a></h2> |
| 644 | |
| 645 | <p>The <strong>ncurses</strong> implementation of |
| 646 | <strong>tic</strong> is rather complex internally; it has to do a |
| 647 | trying combination of missions. This starts with the fact that, |
| 648 | in addition to its normal duty of compiling terminfo sources into |
| 649 | loadable terminfo binaries, it has to be able to handle termcap |
| 650 | syntax and compile that too into terminfo entries.</p> |
| 651 | |
| 652 | <p>The implementation therefore starts with a table-driven, |
| 653 | dual-mode lexical analyzer (in <code>comp_scan.c</code>). The |
| 654 | lexer chooses its mode (termcap or terminfo) based on the first |
| 655 | “,” or “:” it finds in each entry. The |
| 656 | lexer does all the work of recognizing capability names and |
| 657 | values; the grammar above it is trivial, just "parse entries till |
| 658 | you run out of file".</p> |
| 659 | |
| 660 | <h3><a name="nonuse" id="nonuse">Translation of |
| 661 | Non-<strong>use</strong> Capabilities</a></h3> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 662 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 663 | <p>Translation of most things besides <strong>use</strong> |
| 664 | capabilities is pretty straightforward. The lexical analyzer's |
| 665 | tokenizer hands each capability name to a hash function, which |
| 666 | drives a table lookup. The table entry yields an index which is |
| 667 | used to look up the token type in another table, and controls |
| 668 | interpretation of the value.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 669 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 670 | <p>One possibly interesting aspect of the implementation is the |
| 671 | way the compiler tables are initialized. All the tables are |
| 672 | generated by various awk/sed/sh scripts from a master table |
| 673 | <code>include/Caps</code>; these scripts actually write C |
| 674 | initializers which are linked to the compiler. Furthermore, the |
| 675 | hash table is generated in the same way, so it doesn't have to be |
| 676 | generated at compiler startup time (another benefit of this |
| 677 | organization is that the hash table can be in shareable text |
| 678 | space).</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 679 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 680 | <p>Thus, adding a new capability is usually pretty trivial, just |
| 681 | a matter of adding one line to the <code>include/Caps</code> |
| 682 | file. We will have more to say about this in the section on |
| 683 | <a href="#translation">Source-Form Translation</a>.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 684 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 685 | <h3><a name="uses" id="uses">Use Capability Resolution</a></h3> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 686 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 687 | <p>The background problem that makes <strong>tic</strong> tricky |
| 688 | is not the capability translation itself, it is the resolution of |
| 689 | <strong>use</strong> capabilities. Older versions would not |
| 690 | handle forward <strong>use</strong> references for this reason |
| 691 | (that is, a using terminal always had to follow its use target in |
| 692 | the source file). By doing this, they got away with a simple |
| 693 | implementation tactic; compile everything as it blows by, then |
| 694 | resolve uses from compiled entries.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 695 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 696 | <p>This will not do for <strong>ncurses</strong>. The problem is |
| 697 | that that the whole compilation process has to be embeddable in |
| 698 | the <strong>ncurses</strong> library so that it can be called by |
| 699 | the startup code to translate termcap entries on the fly. The |
| 700 | embedded version cannot go promiscuously writing everything it |
| 701 | translates out to disk — for one thing, it will typically |
| 702 | be running with non-root permissions.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 703 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 704 | <p>So our <strong>tic</strong> is designed to parse an entire |
| 705 | terminfo file into a doubly-linked circular list of entry |
| 706 | structures in-core, and then do <strong>use</strong> resolution |
| 707 | in-memory before writing everything out. This design has other |
| 708 | advantages: it makes forward and back use-references equally easy |
| 709 | (so we get the latter for free), and it makes checking for name |
| 710 | collisions before they are written out easy to do.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 711 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 712 | <p>And this is exactly how the embedded version works. But the |
| 713 | stand-alone user-accessible version of <strong>tic</strong> |
| 714 | partly reverts to the historical strategy; it writes to disk (not |
| 715 | keeping in core) any entry with no <strong>use</strong> |
| 716 | references.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 717 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 718 | <p>This is strictly a core-economy kluge, implemented because the |
| 719 | terminfo master file is large enough that some core-poor systems |
| 720 | swap like crazy when you compile it all in memory...there have |
| 721 | been reports of this process taking <strong>three hours</strong>, |
| 722 | rather than the twenty seconds or less typical on the author's |
| 723 | development box.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 724 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 725 | <p>So. The executable <strong>tic</strong> passes the |
| 726 | entry-parser a hook that <em>immediately</em> writes out the |
| 727 | referenced entry if it has no use capabilities. The compiler main |
| 728 | loop refrains from adding the entry to the in-core list when this |
| 729 | hook fires. If some other entry later needs to reference an entry |
| 730 | that got written immediately, that is OK; the resolution code |
| 731 | will fetch it off disk when it cannot find it in core.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 732 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 733 | <p>Name collisions will still be detected, just not as cleanly. |
| 734 | The <code>write_entry()</code> code complains before overwriting |
| 735 | an entry that postdates the time of <strong>tic</strong>'s first |
| 736 | call to <code>write_entry()</code>, Thus it will complain about |
| 737 | overwriting entries newly made during the <strong>tic</strong> |
| 738 | run, but not about overwriting ones that predate it.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 739 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 740 | <h3><a name="translation" id="translation">Source-Form |
| 741 | Translation</a></h3> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 742 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 743 | <p>Another use of <strong>tic</strong> is to do source |
| 744 | translation between various termcap and terminfo formats. There |
| 745 | are more variants out there than you might think; the ones we |
| 746 | know about are described in the <strong>captoinfo(1)</strong> |
| 747 | manual page.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 748 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 749 | <p>The translation output code (<code>dump_entry()</code> in |
| 750 | <code>ncurses/dump_entry.c</code>) is shared with the |
| 751 | <strong>infocmp(1)</strong> utility. It takes the same internal |
| 752 | representation used to generate the binary form and dumps it to |
| 753 | standard output in a specified format.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 754 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 755 | <p>The <code>include/Caps</code> file has a header comment |
| 756 | describing ways you can specify source translations for |
| 757 | nonstandard capabilities just by altering the master table. It is |
| 758 | possible to set up capability aliasing or tell the compiler to |
| 759 | plain ignore a given capability without writing any C code at |
| 760 | all.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 761 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 762 | <p>For circumstances where you need to do algorithmic |
| 763 | translation, there are functions in <code>parse_entry.c</code> |
| 764 | called after the parse of each entry that are specifically |
| 765 | intended to encapsulate such translations. This, for example, is |
| 766 | where the AIX <strong>box1</strong> capability get translated to |
| 767 | an <strong>acsc</strong> string.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 768 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 769 | <h2><a name="utils" id="utils">Other Utilities</a></h2> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 770 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 771 | <p>The <strong>infocmp</strong> utility is just a wrapper around |
| 772 | the same entry-dumping code used by <strong>tic</strong> for |
| 773 | source translation. Perhaps the one interesting aspect of the |
| 774 | code is the use of a predicate function passed in to |
| 775 | <code>dump_entry()</code> to control which capabilities are |
| 776 | dumped. This is necessary in order to handle both the ordinary |
| 777 | De-compilation case and entry difference reporting.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 778 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 779 | <p>The <strong>tput</strong> and <strong>clear</strong> utilities |
| 780 | just do an entry load followed by a <code>tputs()</code> of a |
| 781 | selected capability.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 782 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 783 | <h2><a name="style" id="style">Style Tips for Developers</a></h2> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 784 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 785 | <p>See the TO-DO file in the top-level directory of the source |
| 786 | distribution for additions that would be particularly useful.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 787 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 788 | <p>The prefix <code>_nc_</code> should be used on library public |
| 789 | functions that are not part of the curses API in order to prevent |
| 790 | pollution of the application namespace. If you have to add to or |
| 791 | modify the function prototypes in curses.h.in, read |
| 792 | ncurses/MKlib_gen.sh first so you can avoid breaking XSI |
| 793 | conformance. Please join the ncurses mailing list. See the |
| 794 | INSTALL file in the top level of the distribution for details on |
| 795 | the list.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 796 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 797 | <p>Look for the string <code>FIXME</code> in source files to tag |
| 798 | minor bugs and potential problems that could use fixing.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 799 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 800 | <p>Do not try to auto-detect OS features in the main body of the |
| 801 | C code. That is the job of the configuration system.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 802 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 803 | <p>To hold down complexity, do make your code data-driven. |
| 804 | Especially, if you can drive logic from a table filtered out of |
| 805 | <code>include/Caps</code>, do it. If you find you need to augment |
| 806 | the data in that file in order to generate the proper table, that |
| 807 | is still preferable to ad-hoc code — that is why the fifth |
| 808 | field (flags) is there.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 809 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 810 | <p>Have fun!</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 811 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 812 | <h2><a name="port" id="port">Porting Hints</a></h2> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 813 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 814 | <p>The following notes are intended to be a first step towards |
| 815 | DOS and Macintosh ports of the ncurses libraries.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 816 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 817 | <p>The following library modules are “pure curses”; |
| 818 | they operate only on the curses internal structures, do all |
| 819 | output through other curses calls (not including |
| 820 | <code>tputs()</code> and <code>putp()</code>) and do not call any |
| 821 | other UNIX routines such as signal(2) or the stdio library. Thus, |
| 822 | they should not need to be modified for single-terminal |
| 823 | ports.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 824 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 825 | <blockquote> |
| 826 | <code>lib_addch.c lib_addstr.c lib_bkgd.c lib_box.c lib_clear.c |
| 827 | lib_clrbot.c lib_clreol.c lib_delch.c lib_delwin.c lib_erase.c |
| 828 | lib_inchstr.c lib_insch.c lib_insdel.c lib_insstr.c |
| 829 | lib_keyname.c lib_move.c lib_mvwin.c lib_newwin.c lib_overlay.c |
| 830 | lib_pad.c lib_printw.c lib_refresh.c lib_scanw.c lib_scroll.c |
| 831 | lib_scrreg.c lib_set_term.c lib_touch.c lib_tparm.c lib_tputs.c |
| 832 | lib_unctrl.c lib_window.c panel.c</code> |
| 833 | </blockquote> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 834 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 835 | <p>This module is pure curses, but calls outstr():</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 836 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 837 | <blockquote> |
| 838 | <code>lib_getstr.c</code> |
| 839 | </blockquote> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 840 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 841 | <p>These modules are pure curses, except that they use |
| 842 | <code>tputs()</code> and <code>putp()</code>:</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 843 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 844 | <blockquote> |
| 845 | <code>lib_beep.c lib_color.c lib_endwin.c lib_options.c |
| 846 | lib_slk.c lib_vidattr.c</code> |
| 847 | </blockquote> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 848 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 849 | <p>This modules assist in POSIX emulation on non-POSIX |
| 850 | systems:</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 851 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 852 | <dl> |
| 853 | <dt>sigaction.c</dt> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 854 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 855 | <dd>signal calls</dd> |
| 856 | </dl> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 857 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 858 | <p>The following source files will not be needed for a |
| 859 | single-terminal-type port.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 860 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 861 | <blockquote> |
| 862 | <code>alloc_entry.c captoinfo.c clear.c comp_captab.c |
| 863 | comp_error.c comp_hash.c comp_main.c comp_parse.c comp_scan.c |
| 864 | dump_entry.c infocmp.c parse_entry.c read_entry.c tput.c |
| 865 | write_entry.c</code> |
| 866 | </blockquote> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 867 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 868 | <p>The following modules will use |
| 869 | open()/read()/write()/close()/lseek() on files, but no other OS |
| 870 | calls.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 871 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 872 | <dl> |
| 873 | <dt>lib_screen.c</dt> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 874 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 875 | <dd>used to read/write screen dumps</dd> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 876 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 877 | <dt>lib_trace.c</dt> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 878 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 879 | <dd>used to write trace data to the logfile</dd> |
| 880 | </dl> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 881 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 882 | <p>Modules that would have to be modified for a port start |
| 883 | here:</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 884 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 885 | <p>The following modules are “pure curses” but |
| 886 | contain assumptions inappropriate for a memory-mapped port.</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 887 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 888 | <dl> |
| 889 | <dt>lib_longname.c</dt> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 890 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 891 | <dd>assumes there may be multiple terminals</dd> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 892 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 893 | <dt>lib_acs.c</dt> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 894 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 895 | <dd>assumes acs_map as a double indirection</dd> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 896 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 897 | <dt>lib_mvcur.c</dt> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 898 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 899 | <dd>assumes cursor moves have variable cost</dd> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 900 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 901 | <dt>lib_termcap.c</dt> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 902 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 903 | <dd>assumes there may be multiple terminals</dd> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 904 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 905 | <dt>lib_ti.c</dt> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 906 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 907 | <dd>assumes there may be multiple terminals</dd> |
| 908 | </dl> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 909 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 910 | <p>The following modules use UNIX-specific calls:</p> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 911 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 912 | <dl> |
| 913 | <dt>lib_doupdate.c</dt> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 914 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 915 | <dd>input checking</dd> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 916 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 917 | <dt>lib_getch.c</dt> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 918 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 919 | <dd>read()</dd> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 920 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 921 | <dt>lib_initscr.c</dt> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 922 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 923 | <dd>getenv()</dd> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 924 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 925 | <dt>lib_newterm.c</dt> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 926 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 927 | <dt>lib_baudrate.c</dt> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 928 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 929 | <dt>lib_kernel.c</dt> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 930 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 931 | <dd>various tty-manipulation and system calls</dd> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 932 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 933 | <dt>lib_raw.c</dt> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 934 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 935 | <dd>various tty-manipulation calls</dd> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 936 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 937 | <dt>lib_setup.c</dt> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 938 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 939 | <dd>various tty-manipulation calls</dd> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 940 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 941 | <dt>lib_restart.c</dt> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 942 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 943 | <dd>various tty-manipulation calls</dd> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 944 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 945 | <dt>lib_tstp.c</dt> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 946 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 947 | <dd>signal-manipulation calls</dd> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 948 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 949 | <dt>lib_twait.c</dt> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 950 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 951 | <dd>gettimeofday(), select().</dd> |
| 952 | </dl> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 953 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 954 | <hr> |
Amit Daniel Kachhap | e6a01f5 | 2011-07-20 11:45:59 +0530 | [diff] [blame] | 955 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 956 | <address> |
| 957 | Eric S. Raymond <esr@snark.thyrsus.com> |
| 958 | </address> |
| 959 | (Note: This is <em>not</em> the <a href="#bugtrack">bug |
| 960 | address</a>!) |
| 961 | </body> |
| 962 | </html> |