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