a5af5cf7d7f0b6cbaec3e3ec491a090bcf2a383c
[senf.git] / senf / Utils / Termlib / Terminfo.hh
1 // $Id$
2 //
3 // Copyright (C) 2009
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief Terminfo public header */
25
26 #ifndef HH_SENF_Utils_Termlib_Terminfo_
27 #define HH_SENF_Utils_Termlib_Terminfo_ 1
28
29 // Custom includes
30 #include <string>
31 #include <vector>
32 #include <map>
33 #include <iostream>
34 #include <boost/cstdint.hpp>
35 #include <boost/array.hpp>
36 #include <senf/Utils/Exception.hh>
37
38 //#include "Terminfo.mpp"
39 //-/////////////////////////////////////////////////////////////////////////////////////////////////
40
41 namespace senf {
42 namespace term {
43
44     /** \defgroup terminfo_group Terminfo
45
46         This facility provides access to the terminfo database. It partially re-implements the
47         terminfo suppoprt in \c libncurses.
48
49         \li The senf::term::Terminfo class provides basic terminfo property access and supports terminfo string
50             formatting
51         \li The senf::term::KeyParser class uses the properties found in a Terminfo instance to
52             parser keyboard escape sequences into key codes
53
54         The terminfo implementation is based on the \c utio library by Mike Sharov
55         <msharov@users.sourceforge.net> found at http://sourceforge.net/projects/utio.
56      */
57
58     /** \brief Terminfo database entry
59
60         This class reads a single terminfo database entry and allows to access the terminfo
61         properties.
62
63         \ingroup terminfo_group
64      */
65     class Terminfo
66     {
67     public:
68         //-////////////////////////////////////////////////////////////////////////
69         // Types
70
71         /** \brief NoValue constant
72             This value represents the absence of a numeric property value */
73         enum { NoValue = -1 };
74
75         /** \brief Terminfo property constants
76
77             This class provides a namespace for all Terminfo property constants
78          */
79         struct properties
80         {
81             /** \brief Boolean terminfo properties */
82             enum Boolean {
83                 AutoLeftMargin, AutoRightMargin, NoEscCtlc, CeolStandoutGlitch, EatNewlineGlitch,
84                 EraseOverstrike, GenericType, HardCopy, HasMetaKey, HasStatusLine, InsertNullGlitch,
85                 MemoryAbove, MemoryBelow, MoveInsertMode, MoveStandoutMode, OverStrike,
86                 StatusLineEscOk, DestTabsMagicSmso, TildeGlitch, TransparentUnderline, XonXoff,
87                 NeedsXonXoff, PrtrSilent, HardCursor, NonRevRmcup, NoPadChar, NonDestScrollRegion,
88                 CanChange, BackColorErase, HueLightnessSaturation, ColAddrGlitch,
89                 CrCancelsMicroMode, HasPrintWheel, RowAddrGlitch, SemiAutoRightMargin,
90                 CpiChangesRes, LpiChangesRes, BackspacesWithBs, CrtNoScrolling,
91                 NoCorrectlyWorkingCr, GnuHasMetaKey, LinefeedIsNewline, HasHardwareTabs,
92                 ReturnDoesClrEol };
93
94             /** \brief Boolean property names
95                 \hideinitializer */
96             static char const * const BooleanNames[];
97
98             /** \brief Numeric terminfo properties */
99             enum Numeric {
100                 Columns, InitTabs, Lines, LinesOfMemory, MagicCookieGlitch, PaddingBaudRate,
101                 VirtualTerminal, WidthStatusLine, NumLabels, LabelHeight, LabelWidth, MaxAttributes,
102                 MaximumWindows, MaxColors, MaxPairs, NoColorVideo, BufferCapacity, DotVertSpacing,
103                 DotHorzSpacing, MaxMicroAddress, MaxMicroJump, MicroColSize, MicroLineSize,
104                 NumberOfPins, OutputResChar, OutputResLine, OutputResHorzInch, OutputResVertInch,
105                 PrintRate, WideCharSize, Buttons, BitImageEntwining, BitImageType,
106                 MagicCookieGlitchUl, CarriageReturnDelay, NewLineDelay, BackspaceDelay,
107                 HorizontalTabDelay, NumberOfFunctionKeys };
108
109             /** \brief Numeric property names
110                 \hideinitializer */
111             static char const * const NumericNames[];
112
113             /** \brief String terminfo properties */
114             enum String {
115                 BackTab, Bell, CarriageReturn, ChangeScrollRegion, ClearAllTabs, ClearScreen,
116                 ClrEol, ClrEos, ColumnAddress, CommandCharacter, CursorAddress, CursorDown,
117                 CursorHome, CursorInvisible, CursorLeft, CursorMemAddress, CursorNormal,
118                 CursorRight, CursorToLl, CursorUp, CursorVisible, DeleteCharacter, DeleteLine,
119                 DisStatusLine, DownHalfLine, EnterAltCharsetMode, EnterBlinkMode, EnterBoldMode,
120                 EnterCaMode, EnterDeleteMode, EnterDimMode, EnterInsertMode, EnterSecureMode,
121                 EnterProtectedMode, EnterReverseMode, EnterStandoutMode, EnterUnderlineMode,
122                 EraseChars, ExitAltCharsetMode, ExitAttributeMode, ExitCaMode, ExitDeleteMode,
123                 ExitInsertMode, ExitStandoutMode, ExitUnderlineMode, FlashScreen, FormFeed,
124                 FromStatusLine, Init1string, Init2string, Init3string, InitFile, InsertCharacter,
125                 InsertLine, InsertPadding, KeyBackspace, KeyCatab, KeyClear, KeyCtab, KeyDc, KeyDl,
126                 KeyDown, KeyEic, KeyEol, KeyEos, KeyF0, KeyF1, KeyF10, KeyF2, KeyF3, KeyF4, KeyF5,
127                 KeyF6, KeyF7, KeyF8, KeyF9, KeyHome, KeyIc, KeyIl, KeyLeft, KeyLl, KeyNpage,
128                 KeyPpage, KeyRight, KeySf, KeySr, KeyStab, KeyUp, KeypadLocal, KeypadXmit, LabF0,
129                 LabF1, LabF10, LabF2, LabF3, LabF4, LabF5, LabF6, LabF7, LabF8, LabF9, MetaOff,
130                 MetaOn, Newline, PadChar, ParmDch, ParmDeleteLine, ParmDownCursor, ParmIch,
131                 ParmIndex, ParmInsertLine, ParmLeftCursor, ParmRightCursor, ParmRindex,
132                 ParmUpCursor, PkeyKey, PkeyLocal, PkeyXmit, PrintScreen, PrtrOff, PrtrOn,
133                 RepeatChar, Reset1string, Reset2string, Reset3string, ResetFile, RestoreCursor,
134                 RowAddress, SaveCursor, ScrollForward, ScrollReverse, SetAttributes, SetTab,
135                 SetWindow, Tab, ToStatusLine, UnderlineChar, UpHalfLine, InitProg, KeyA1, KeyA3,
136                 KeyB2, KeyC1, KeyC3, PrtrNon, CharPadding, AcsChars, PlabNorm, KeyBtab,
137                 EnterXonMode, ExitXonMode, EnterAmMode, ExitAmMode, XonCharacter, XoffCharacter,
138                 EnaAcs, LabelOn, LabelOff, KeyBeg, KeyCancel, KeyClose, KeyCommand, KeyCopy,
139                 KeyCreate, KeyEnd, KeyEnter, KeyExit, KeyFind, KeyHelp, KeyMark, KeyMessage,
140                 KeyMove, KeyNext, KeyOpen, KeyOptions, KeyPrevious, KeyPrint, KeyRedo, KeyReference,
141                 KeyRefresh, KeyReplace, KeyRestart, KeyResume, KeySave, KeySuspend, KeyUndo,
142                 KeySbeg, KeyScancel, KeyScommand, KeyScopy, KeyScreate, KeySdc, KeySdl, KeySelect,
143                 KeySend, KeySeol, KeySexit, KeySfind, KeyShelp, KeyShome, KeySic, KeySleft,
144                 KeySmessage, KeySmove, KeySnext, KeySoptions, KeySprevious, KeySprint, KeySredo,
145                 KeySreplace, KeySright, KeySrsume, KeySsave, KeySsuspend, KeySundo, ReqForInput,
146                 KeyF11, KeyF12, KeyF13, KeyF14, KeyF15, KeyF16, KeyF17, KeyF18, KeyF19, KeyF20,
147                 KeyF21, KeyF22, KeyF23, KeyF24, KeyF25, KeyF26, KeyF27, KeyF28, KeyF29, KeyF30,
148                 KeyF31, KeyF32, KeyF33, KeyF34, KeyF35, KeyF36, KeyF37, KeyF38, KeyF39, KeyF40,
149                 KeyF41, KeyF42, KeyF43, KeyF44, KeyF45, KeyF46, KeyF47, KeyF48, KeyF49, KeyF50,
150                 KeyF51, KeyF52, KeyF53, KeyF54, KeyF55, KeyF56, KeyF57, KeyF58, KeyF59, KeyF60,
151                 KeyF61, KeyF62, KeyF63, ClrBol, ClearMargins, SetLeftMargin, SetRightMargin,
152                 LabelFormat, SetClock, DisplayClock, RemoveClock, CreateWindow, GotoWindow, Hangup,
153                 DialPhone, QuickDial, Tone, Pulse, FlashHook, FixedPause, WaitTone, User0, User1,
154                 User2, User3, User4, User5, User6, User7, User8, User9, OrigPair, OrigColors,
155                 InitializeColor, InitializePair, SetColorPair, SetForeground, SetBackground,
156                 ChangeCharPitch, ChangeLinePitch, ChangeResHorz, ChangeResVert, DefineChar,
157                 EnterDoublewideMode, EnterDraftQuality, EnterItalicsMode, EnterLeftwardMode,
158                 EnterMicroMode, EnterNearLetterQuality, EnterNormalQuality, EnterShadowMode,
159                 EnterSubscriptMode, EnterSuperscriptMode, EnterUpwardMode, ExitDoublewideMode,
160                 ExitItalicsMode, ExitLeftwardMode, ExitMicroMode, ExitShadowMode, ExitSubscriptMode,
161                 ExitSuperscriptMode, ExitUpwardMode, MicroColumnAddress, MicroDown, MicroLeft,
162                 MicroRight, MicroRowAddress, MicroUp, OrderOfPins, ParmDownMicro, ParmLeftMicro,
163                 ParmRightMicro, ParmUpMicro, SelectCharSet, SetBottomMargin, SetBottomMarginParm,
164                 SetLeftMarginParm, SetRightMarginParm, SetTopMargin, SetTopMarginParm,
165                 StartBitImage, StartCharSetDef, StopBitImage, StopCharSetDef, SubscriptCharacters,
166                 SuperscriptCharacters, TheseCauseCr, ZeroMotion, CharSetNames, KeyMouse, MouseInfo,
167                 ReqMousePos, GetMouse, SetAForeground, SetABackground, PkeyPlab, DeviceType,
168                 CodeSetInit, Set0DesSeq, Set1DesSeq, Set2DesSeq, Set3DesSeq, SetLrMargin,
169                 SetTbMargin, BitImageRepeat, BitImageNewline, BitImageCarriageReturn, ColorNames,
170                 DefineBitImageRegion, EndBitImageRegion, SetColorBand, SetPageLength, DisplayPcChar,
171                 EnterPcCharsetMode, ExitPcCharsetMode, EnterScancodeMode, ExitScancodeMode,
172                 PcTermOptions, ScancodeEscape, AltScancodeEsc, EnterHorizontalHlMode,
173                 EnterLeftHlMode, EnterLowHlMode, EnterRightHlMode, EnterTopHlMode,
174                 EnterVerticalHlMode, SetAAttributes, SetPglenInch, TermcapInit2, TermcapReset,
175                 LinefeedIfNotLf, BackspaceIfNotBs, OtherNonFunctionKeys, ArrowKeyMap, AcsUlcorner,
176                 AcsLlcorner, AcsUrcorner, AcsLrcorner, AcsLtee, AcsRtee, AcsBtee, AcsTtee, AcsHline,
177                 AcsVline, AcsPlus, MemoryLock, MemoryUnlock, BoxChars1 };
178
179             /** \brief String property names
180                 \hideinitializer */
181             static char const * const StringNames[];
182         };
183
184         typedef boost::int16_t number_t; ///< Numeric terminfo property type
185         typedef char const* string_t;   ///< String terminfo property type
186
187         //-////////////////////////////////////////////////////////////////////////
188
189         Terminfo();
190         explicit Terminfo(std::string const & term); ///< Load terminfo entry \a term
191         void load(std::string const & term); ///< Load terminfo entry \a term
192
193         bool getFlag(properties::Boolean p) const; ///< Get boolean property value
194         number_t getNumber(properties::Numeric p) const; ///< Get numeric property value
195         string_t getString(properties::String p) const; ///< Get string property value
196                                         /**< If the property does not exist, 0 is returned */
197         bool hasProperty(properties::Boolean p) const; ///< \c true, if boolean property \a p exists
198         bool hasProperty(properties::Numeric p ) const; ///< \c true, if numeric property \a p exists
199         bool hasProperty(properties::String p ) const; ///< \c true, if string property \a p exists
200
201         std::string formatString(properties::String p,
202                                  number_t arg1=NoValue, number_t arg2=NoValue,
203                                  number_t arg3=NoValue, number_t arg4=NoValue,
204                                  number_t arg5=NoValue, number_t arg6=NoValue,
205                                  number_t arg7=NoValue, number_t arg8=NoValue,
206                                  number_t arg9=NoValue) const;
207                                         ///< Format string property value
208                                         /**< Formats the string property \a p containing special
209                                              terminfo codes. Terminfo supports up to 9 parameters. */
210
211         //-////////////////////////////////////////////////////////////////////////
212
213         void dump(std::ostream & os) const; ///< Dump a description of the terminfo entry
214
215         /** \brief Invalid, incomplete or non-existent terminfo entry exception */
216         struct InvalidTerminfoException : public senf::Exception
217         { InvalidTerminfoException() : senf::Exception("Unreadable terminfo file") {} };
218
219     private:
220         typedef std::vector<bool> BoolVec;
221         typedef std::vector<number_t> NumberVec;
222         typedef std::vector<string_t> StringVec;
223         typedef std::vector<char> StringPool;
224
225         std::string findTerminfo(std::string const & name);
226         void load(std::istream & is);
227
228         std::string name_;
229         BoolVec booleans_;
230         NumberVec numbers_;
231         StringVec strings_;
232         StringPool stringPool_;
233     };
234
235     /** \brief Parse key escape sequences
236
237         The KeyParser will read the relevant properties from a terminfo entry and then provides
238         functions to parser keyboard escape sequences.
239
240         All keys are returned as keyboard code's. Values 0 to 255 represent ordinary ASCII
241         characters, larger values are special keys taken from the KeyCode \c enum
242
243         \ingroup terminfo_group
244      */
245     class KeyParser
246     {
247     public:
248         //-////////////////////////////////////////////////////////////////////////
249         // Types
250
251         /** \brief Special keyboard key codes */
252         enum KeyCode {
253             Space = ' ', Tab = '\t', Return = '\r', First = 0xE000, Esc = First, Backspace, Backtab,
254             Begin, CATab, CTab, Cancel, Center, Clear, ClearToEOL, ClearToEOS, Close, Command, Copy,
255             Create, Delete, DeleteLine, Down, DownLeft, DownRight, End, Enter, Exit, F0, F1, F2, F3,
256             F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, F22,
257             F23, F24, F25, F26, F27, F28, F29, F30, F31, F32, F33, F34, F35, F36, F37, F38, F39,
258             F40, F41, F42, F43, F44, F45, F46, F47, F48, F49, F50, F51, F52, F53, F54, F55, F56,
259             F57, F58, F59, F60, F61, F62, F63, Find, Help, Home, Insert, InsertLine, Left, Mark,
260             Message, Mouse, Move, Next, Open, Options, PageDown, PageUp, Previous, Print, Redo,
261             Reference, Refresh, Replace, Restart, Resume, Right, Save, Select, ShiftBegin,
262             ShiftCancel, ShiftCommand, ShiftCopy, ShiftCreate, ShiftDelete, ShiftDeleteLine,
263             ShiftEnd, ShiftClearToEOL, ShiftExit, ShiftFind, ShiftHelp, ShiftHome, ShiftInsert,
264             ShiftLeft, ShiftMessage, ShiftMove, ShiftNext, ShiftOptions, ShiftPrevious, ShiftPrint,
265             ShiftRedo, ShiftReplace, ShiftResume, ShiftRight, ShiftSave, ShiftSuspend, ShiftTab,
266             ShiftUndo, Suspend, Undo, Up, UpLeft, UpRight, Incomplete = 0xE0FF };
267
268         /** \brief Special key code names
269             \hideinitializer */
270         static char const * const KeyNames[];
271
272         typedef wchar_t keycode_t;      ///< Key code data type
273         typedef std::string::size_type size_type; ///< String length type
274
275         /** \brief Helper to convert uppercase char to Control key code */
276         static keycode_t Ctrl(char ch) { return ch-'@'; }
277
278         //-////////////////////////////////////////////////////////////////////////
279
280         KeyParser();
281         explicit KeyParser(Terminfo const & ti); ///< Load keymap information from \a ti
282         void load(Terminfo const & ti); ///< Load keymap information from \a ti
283
284         std::pair<keycode_t, size_type> lookup(std::string const & key) const;
285                                         ///< Lookup up string \a key
286                                         /**< This call will look up the string in \a key in the
287                                              keymap. The return value is a pair.
288                                              \li the first value is the key code
289                                              \li the second value is the number of characters in \a
290                                                  key which have been interpreted and returned in the
291                                                  first value
292
293                                              If \a key is not a complete key sequence, the return
294                                              key code will be the \c Invalid value and the returned
295                                              escape sequence size will be 0.
296
297                                              If \a key does not start with an escape sequence, the
298                                              returned key code will be the first character from \a
299                                              key and the escape sequence size will be 1.
300
301                                              Otherwise \a key starts with a complete escape
302                                              sequence. The returned key code will be a value from
303                                              the KeyCode enum and the escape sequence size will be
304                                              returned accordingly. */
305         static std::string describe(keycode_t key); ///< Return descriptive, printable key name
306
307         void dump(std::ostream & os) const; ///< Dump keymap for debug purposes
308
309     private:
310         typedef std::map<std::string, KeyCode> Keytable;
311
312         Keytable table_;
313     };
314
315 }}
316
317 //-/////////////////////////////////////////////////////////////////////////////////////////////////
318 //#include "Terminfo.cci"
319 //#include "Terminfo.ct"
320 //#include "Terminfo.cti"
321 #endif
322
323 \f
324 // Local Variables:
325 // mode: c++
326 // fill-column: 100
327 // comment-column: 40
328 // c-file-style: "senf"
329 // indent-tabs-mode: nil
330 // ispell-local-dictionary: "american"
331 // compile-command: "scons -u test"
332 // End: