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 — stable and reliable code, wide 133*8d9900a3SBaptiste Daroussin portability, good packaging, superior documentation.</li> 134*8d9900a3SBaptiste Daroussin 135*8d9900a3SBaptiste Daroussin <li>Featureful — 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 — 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 <name>@<host.domain> 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 — 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 — 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 — 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 — 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 “,” or “:” 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 — 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 — 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 “pure curses”; 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 “pure curses” 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 <esr@snark.thyrsus.com> 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