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