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