4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 // Stefan Bund <g0dil@berlios.de>
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.
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.
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.
24 \brief Terminfo non-inline non-template implementation */
26 #include "Terminfo.hh"
27 //#include "Terminfo.ih"
32 #include <boost/filesystem/operations.hpp>
33 #include <senf/config.hh>
34 #include <senf/Utils/hexdump.hh>
38 //#include "Terminfo.mpp"
40 ///////////////////////////////cc.p////////////////////////////////////////
42 char const * const senf::term::Terminfo::properties::BooleanNames [] = {
43 "AutoLeftMargin", "AutoRightMargin", "NoEscCtlc", "CeolStandoutGlitch", "EatNewlineGlitch",
44 "EraseOverstrike", "GenericType", "HardCopy", "HasMetaKey", "HasStatusLine", "InsertNullGlitch",
45 "MemoryAbove", "MemoryBelow", "MoveInsertMode", "MoveStandoutMode", "OverStrike",
46 "StatusLineEscOk", "DestTabsMagicSmso", "TildeGlitch", "TransparentUnderline", "XonXoff",
47 "NeedsXonXoff", "PrtrSilent", "HardCursor", "NonRevRmcup", "NoPadChar", "NonDestScrollRegion",
48 "CanChange", "BackColorErase", "HueLightnessSaturation", "ColAddrGlitch", "CrCancelsMicroMode",
49 "HasPrintWheel", "RowAddrGlitch", "SemiAutoRightMargin", "CpiChangesRes", "LpiChangesRes",
50 "BackspacesWithBs", "CrtNoScrolling", "NoCorrectlyWorkingCr", "GnuHasMetaKey",
51 "LinefeedIsNewline", "HasHardwareTabs", "ReturnDoesClrEol" };
53 char const * const senf::term::Terminfo::properties::NumericNames[] = {
54 "Columns", "InitTabs", "Lines", "LinesOfMemory", "MagicCookieGlitch", "PaddingBaudRate",
55 "VirtualTerminal", "WidthStatusLine", "NumLabels", "LabelHeight", "LabelWidth", "MaxAttributes",
56 "MaximumWindows", "MaxColors", "MaxPairs", "NoColorVideo", "BufferCapacity", "DotVertSpacing",
57 "DotHorzSpacing", "MaxMicroAddress", "MaxMicroJump", "MicroColSize", "MicroLineSize",
58 "NumberOfPins", "OutputResChar", "OutputResLine", "OutputResHorzInch", "OutputResVertInch",
59 "PrintRate", "WideCharSize", "Buttons", "BitImageEntwining", "BitImageType",
60 "MagicCookieGlitchUl", "CarriageReturnDelay", "NewLineDelay", "BackspaceDelay",
61 "HorizontalTabDelay", "NumberOfFunctionKeys" };
63 char const * const senf::term::Terminfo::properties::StringNames[] = {
64 "BackTab", "Bell", "CarriageReturn", "ChangeScrollRegion", "ClearAllTabs", "ClearScreen",
65 "ClrEol", "ClrEos", "ColumnAddress", "CommandCharacter", "CursorAddress", "CursorDown",
66 "CursorHome", "CursorInvisible", "CursorLeft", "CursorMemAddress", "CursorNormal",
67 "CursorRight", "CursorToLl", "CursorUp", "CursorVisible", "DeleteCharacter", "DeleteLine",
68 "DisStatusLine", "DownHalfLine", "EnterAltCharsetMode", "EnterBlinkMode", "EnterBoldMode",
69 "EnterCaMode", "EnterDeleteMode", "EnterDimMode", "EnterInsertMode", "EnterSecureMode",
70 "EnterProtectedMode", "EnterReverseMode", "EnterStandoutMode", "EnterUnderlineMode",
71 "EraseChars", "ExitAltCharsetMode", "ExitAttributeMode", "ExitCaMode", "ExitDeleteMode",
72 "ExitInsertMode", "ExitStandoutMode", "ExitUnderlineMode", "FlashScreen", "FormFeed",
73 "FromStatusLine", "Init1string", "Init2string", "Init3string", "InitFile", "InsertCharacter",
74 "InsertLine", "InsertPadding", "KeyBackspace", "KeyCatab", "KeyClear", "KeyCtab", "KeyDc",
75 "KeyDl", "KeyDown", "KeyEic", "KeyEol", "KeyEos", "KeyF0", "KeyF1", "KeyF10", "KeyF2", "KeyF3",
76 "KeyF4", "KeyF5", "KeyF6", "KeyF7", "KeyF8", "KeyF9", "KeyHome", "KeyIc", "KeyIl", "KeyLeft",
77 "KeyLl", "KeyNpage", "KeyPpage", "KeyRight", "KeySf", "KeySr", "KeyStab", "KeyUp",
78 "KeypadLocal", "KeypadXmit", "LabF0", "LabF1", "LabF10", "LabF2", "LabF3", "LabF4", "LabF5",
79 "LabF6", "LabF7", "LabF8", "LabF9", "MetaOff", "MetaOn", "Newline", "PadChar", "ParmDch",
80 "ParmDeleteLine", "ParmDownCursor", "ParmIch", "ParmIndex", "ParmInsertLine", "ParmLeftCursor",
81 "ParmRightCursor", "ParmRindex", "ParmUpCursor", "PkeyKey", "PkeyLocal", "PkeyXmit",
82 "PrintScreen", "PrtrOff", "PrtrOn", "RepeatChar", "Reset1string", "Reset2string",
83 "Reset3string", "ResetFile", "RestoreCursor", "RowAddress", "SaveCursor", "ScrollForward",
84 "ScrollReverse", "SetAttributes", "SetTab", "SetWindow", "Tab", "ToStatusLine", "UnderlineChar",
85 "UpHalfLine", "InitProg", "KeyA1", "KeyA3", "KeyB2", "KeyC1", "KeyC3", "PrtrNon", "CharPadding",
86 "AcsChars", "PlabNorm", "KeyBtab", "EnterXonMode", "ExitXonMode", "EnterAmMode", "ExitAmMode",
87 "XonCharacter", "XoffCharacter", "EnaAcs", "LabelOn", "LabelOff", "KeyBeg", "KeyCancel",
88 "KeyClose", "KeyCommand", "KeyCopy", "KeyCreate", "KeyEnd", "KeyEnter", "KeyExit", "KeyFind",
89 "KeyHelp", "KeyMark", "KeyMessage", "KeyMove", "KeyNext", "KeyOpen", "KeyOptions",
90 "KeyPrevious", "KeyPrint", "KeyRedo", "KeyReference", "KeyRefresh", "KeyReplace", "KeyRestart",
91 "KeyResume", "KeySave", "KeySuspend", "KeyUndo", "KeySbeg", "KeyScancel", "KeyScommand",
92 "KeyScopy", "KeyScreate", "KeySdc", "KeySdl", "KeySelect", "KeySend", "KeySeol", "KeySexit",
93 "KeySfind", "KeyShelp", "KeyShome", "KeySic", "KeySleft", "KeySmessage", "KeySmove", "KeySnext",
94 "KeySoptions", "KeySprevious", "KeySprint", "KeySredo", "KeySreplace", "KeySright", "KeySrsume",
95 "KeySsave", "KeySsuspend", "KeySundo", "ReqForInput", "KeyF11", "KeyF12", "KeyF13", "KeyF14",
96 "KeyF15", "KeyF16", "KeyF17", "KeyF18", "KeyF19", "KeyF20", "KeyF21", "KeyF22", "KeyF23",
97 "KeyF24", "KeyF25", "KeyF26", "KeyF27", "KeyF28", "KeyF29", "KeyF30", "KeyF31", "KeyF32",
98 "KeyF33", "KeyF34", "KeyF35", "KeyF36", "KeyF37", "KeyF38", "KeyF39", "KeyF40", "KeyF41",
99 "KeyF42", "KeyF43", "KeyF44", "KeyF45", "KeyF46", "KeyF47", "KeyF48", "KeyF49", "KeyF50",
100 "KeyF51", "KeyF52", "KeyF53", "KeyF54", "KeyF55", "KeyF56", "KeyF57", "KeyF58", "KeyF59",
101 "KeyF60", "KeyF61", "KeyF62", "KeyF63", "ClrBol", "ClearMargins", "SetLeftMargin",
102 "SetRightMargin", "LabelFormat", "SetClock", "DisplayClock", "RemoveClock", "CreateWindow",
103 "GotoWindow", "Hangup", "DialPhone", "QuickDial", "Tone", "Pulse", "FlashHook", "FixedPause",
104 "WaitTone", "User0", "User1", "User2", "User3", "User4", "User5", "User6", "User7", "User8",
105 "User9", "OrigPair", "OrigColors", "InitializeColor", "InitializePair", "SetColorPair",
106 "SetForeground", "SetBackground", "ChangeCharPitch", "ChangeLinePitch", "ChangeResHorz",
107 "ChangeResVert", "DefineChar", "EnterDoublewideMode", "EnterDraftQuality", "EnterItalicsMode",
108 "EnterLeftwardMode", "EnterMicroMode", "EnterNearLetterQuality", "EnterNormalQuality",
109 "EnterShadowMode", "EnterSubscriptMode", "EnterSuperscriptMode", "EnterUpwardMode",
110 "ExitDoublewideMode", "ExitItalicsMode", "ExitLeftwardMode", "ExitMicroMode", "ExitShadowMode",
111 "ExitSubscriptMode", "ExitSuperscriptMode", "ExitUpwardMode", "MicroColumnAddress", "MicroDown",
112 "MicroLeft", "MicroRight", "MicroRowAddress", "MicroUp", "OrderOfPins", "ParmDownMicro",
113 "ParmLeftMicro", "ParmRightMicro", "ParmUpMicro", "SelectCharSet", "SetBottomMargin",
114 "SetBottomMarginParm", "SetLeftMarginParm", "SetRightMarginParm", "SetTopMargin",
115 "SetTopMarginParm", "StartBitImage", "StartCharSetDef", "StopBitImage", "StopCharSetDef",
116 "SubscriptCharacters", "SuperscriptCharacters", "TheseCauseCr", "ZeroMotion", "CharSetNames",
117 "KeyMouse", "MouseInfo", "ReqMousePos", "GetMouse", "SetAForeground", "SetABackground",
118 "PkeyPlab", "DeviceType", "CodeSetInit", "Set0DesSeq", "Set1DesSeq", "Set2DesSeq", "Set3DesSeq",
119 "SetLrMargin", "SetTbMargin", "BitImageRepeat", "BitImageNewline", "BitImageCarriageReturn",
120 "ColorNames", "DefineBitImageRegion", "EndBitImageRegion", "SetColorBand", "SetPageLength",
121 "DisplayPcChar", "EnterPcCharsetMode", "ExitPcCharsetMode", "EnterScancodeMode",
122 "ExitScancodeMode", "PcTermOptions", "ScancodeEscape", "AltScancodeEsc",
123 "EnterHorizontalHlMode", "EnterLeftHlMode", "EnterLowHlMode", "EnterRightHlMode",
124 "EnterTopHlMode", "EnterVerticalHlMode", "SetAAttributes", "SetPglenInch", "TermcapInit2",
125 "TermcapReset", "LinefeedIfNotLf", "BackspaceIfNotBs", "OtherNonFunctionKeys", "ArrowKeyMap",
126 "AcsUlcorner", "AcsLlcorner", "AcsUrcorner", "AcsLrcorner", "AcsLtee", "AcsRtee", "AcsBtee",
127 "AcsTtee", "AcsHline", "AcsVline", "AcsPlus", "MemoryLock", "MemoryUnlock", "BoxChars1" };
129 ///////////////////////////////////////////////////////////////////////////
130 // senf::term::Terminfo
132 prefix_ senf::term::Terminfo::Terminfo()
135 prefix_ senf::term::Terminfo::Terminfo(std::string const & term)
140 prefix_ void senf::term::Terminfo::load(std::string const & term)
142 std::string filename (findTerminfo(term));
143 std::ifstream is (filename.c_str());
145 throw InvalidTerminfoException();
149 prefix_ bool senf::term::Terminfo::getFlag(properties::Boolean p)
152 if (BoolVec::size_type(p) >= booleans_.size())
157 prefix_ senf::term::Terminfo::number_t senf::term::Terminfo::getNumber(properties::Numeric p)
160 if (NumberVec::size_type(p) >= numbers_.size())
165 prefix_ senf::term::Terminfo::string_t senf::term::Terminfo::getString(properties::String p)
168 if (StringVec::size_type(p) >= strings_.size())
173 prefix_ void senf::term::Terminfo::dump(std::ostream & os)
176 os << "Terminfo entry: " << name_ << "\n";
177 os << "Booleans: " << booleans_.size() << "\n";
178 os << "Numbers: " << numbers_.size() << "\n";
179 os << "Strings: " << strings_.size() << "\n";
180 os << "String pool size: " << stringPool_.size() << "\n";
185 BoolVec::const_iterator i (booleans_.begin());
186 BoolVec::const_iterator const i_end (booleans_.end());
187 for (; i != i_end; ++i, ++n)
188 if (*i && n < sizeof(properties::BooleanNames)/sizeof(properties::BooleanNames[0]))
189 os << " " << properties::BooleanNames[n] << "\n";
195 NumberVec::const_iterator i (numbers_.begin());
196 NumberVec::const_iterator const i_end (numbers_.end());
197 for (; i != i_end; ++i, ++n)
199 && n < sizeof(properties::NumericNames)/sizeof(properties::NumericNames[0]))
200 os << " " << properties::NumericNames[n] << " = " << *i << "\n";
206 StringVec::const_iterator i (strings_.begin());
207 StringVec::const_iterator const i_end (strings_.end());
208 for (; i != i_end; ++i, ++n)
209 if (*i && n < sizeof(properties::StringNames)/sizeof(properties::StringNames[0])) {
210 os << " " << std::setw(32) << properties::StringNames[n] << " = ";
211 hexdump(*i, *i + strlen(*i), os, 32);
217 prefix_ std::string senf::term::Terminfo::findTerminfo(std::string const & name)
219 boost::filesystem::path subdir (name.substr(0,1)); subdir /= name;
220 boost::filesystem::path tientry, tipath;
223 char const * tivar (::getenv("TERMINFO"));
226 tientry = tipath / subdir;
227 if (boost::filesystem::exists(tientry)) return tientry.native_file_string();
231 tipath = "/etc/terminfo";
232 tientry = tipath / subdir;
233 if (boost::filesystem::exists(tientry)) return tientry.native_file_string();
235 tipath = "/lib/terminfo";
236 tientry = tipath / subdir;
237 if (boost::filesystem::exists(tientry)) return tientry.native_file_string();
239 tipath = "/usr/share/terminfo";
240 tientry = tipath / subdir;
241 if (boost::filesystem::exists(tientry)) return tientry.native_file_string();
248 boost::uint16_t const TerminfoMagic = 0x011A;
250 struct TerminfoHeader {
251 boost::uint16_t magic;
252 boost::uint16_t namesSz;
253 boost::uint16_t nBooleans;
254 boost::uint16_t nNumbers;
255 boost::uint16_t nStrings;
256 boost::uint16_t stringPoolSz;
261 prefix_ void senf::term::Terminfo::load(std::istream & is)
264 is.read(static_cast<char*>(static_cast<void*>(&h)), sizeof(h));
265 if (h.magic != TerminfoMagic)
266 throw InvalidTerminfoException();
268 name_.resize(h.namesSz);
269 is.read(&(name_[0]), name_.size());
271 std::string::size_type n (name_.find('\0'));
272 if (n != std::string::npos)
276 booleans_.resize(h.nBooleans);
277 for (BoolVec::iterator i (booleans_.begin()); i != booleans_.end(); ++i) {
279 is.read(&v, sizeof(v));
282 if (booleans_.size() & 1)
285 numbers_.resize(h.nNumbers);
286 for (NumberVec::iterator i (numbers_.begin()); i != numbers_.end(); ++i) {
288 is.read(static_cast<char*>(static_cast<void*>(&v)), sizeof(v));
292 typedef std::vector<number_t> OffsetVec;
294 offsets.resize (h.nStrings);
295 for (OffsetVec::iterator i (offsets.begin()); i != offsets.end(); ++i) {
297 is.read(static_cast<char*>(static_cast<void*>(&v)), sizeof(v));
301 stringPool_.resize(h.stringPoolSz);
302 is.read(&(stringPool_[0]), stringPool_.size());
304 strings_.resize(offsets.size());
305 StringVec::iterator j (strings_.begin());
306 for (OffsetVec::iterator i (offsets.begin()); i != offsets.end(); ++i, ++j)
308 *j = &(stringPool_[0]) + *i;
311 ///////////////////////////////////////////////////////////////////////////
312 // senf::term::KeyParser
314 char const * const senf::term::KeyParser::KeyNames[] = {
315 "Esc", "Backspace", "Backtab", "Begin", "CATab", "CTab", "Cancel", "Center", "Clear",
316 "ClearToEOL", "ClearToEOS", "Close", "Command", "Copy", "Create", "Delete", "DeleteLine",
317 "Down", "DownLeft", "DownRight", "End", "Enter", "Exit", "F0", "F1", "F2", "F3", "F4", "F5",
318 "F6", "F7", "F8", "F9", "F10", "F11", "F12", "F13", "F14", "F15", "F16", "F17", "F18", "F19",
319 "F20", "F21", "F22", "F23", "F24", "F25", "F26", "F27", "F28", "F29", "F30", "F31", "F32",
320 "F33", "F34", "F35", "F36", "F37", "F38", "F39", "F40", "F41", "F42", "F43", "F44", "F45",
321 "F46", "F47", "F48", "F49", "F50", "F51", "F52", "F53", "F54", "F55", "F56", "F57", "F58",
322 "F59", "F60", "F61", "F62", "F63", "Find", "Help", "Home", "Insert", "InsertLine", "Left",
323 "Mark", "Message", "Mouse", "Move", "Next", "Open", "Options", "PageDown", "PageUp", "Previous",
324 "Print", "Redo", "Reference", "Refresh", "Replace", "Restart", "Resume", "Right", "Save",
325 "Select", "ShiftBegin", "ShiftCancel", "ShiftCommand", "ShiftCopy", "ShiftCreate",
326 "ShiftDelete", "ShiftDeleteLine", "ShiftEnd", "ShiftClearToEOL", "ShiftExit", "ShiftFind",
327 "ShiftHelp", "ShiftHome", "ShiftInsert", "ShiftLeft", "ShiftMessage", "ShiftMove", "ShiftNext",
328 "ShiftOptions", "ShiftPrevious", "ShiftPrint", "ShiftRedo", "ShiftReplace", "ShiftResume",
329 "ShiftRight", "ShiftSave", "ShiftSuspend", "ShiftTab", "ShiftUndo", "Suspend", "Undo", "Up",
330 "UpLeft", "UpRight" };
332 prefix_ senf::term::KeyParser::KeyParser()
335 prefix_ senf::term::KeyParser::KeyParser(Terminfo const & ti)
340 prefix_ void senf::term::KeyParser::load(Terminfo const & ti)
342 static Terminfo::properties::String keyStrings [] = {
343 Terminfo::properties::KeyCommand, Terminfo::properties::KeyBackspace,
344 Terminfo::properties::KeyBtab, Terminfo::properties::KeyBeg, Terminfo::properties::KeyCatab,
345 Terminfo::properties::KeyCtab, Terminfo::properties::KeyCancel, Terminfo::properties::KeyB2,
346 Terminfo::properties::KeyClear, Terminfo::properties::KeyEol, Terminfo::properties::KeyEos,
347 Terminfo::properties::KeyClose, Terminfo::properties::KeyCommand,
348 Terminfo::properties::KeyCopy, Terminfo::properties::KeyCreate, Terminfo::properties::KeyDc,
349 Terminfo::properties::KeyDl, Terminfo::properties::KeyDown, Terminfo::properties::KeyC1,
350 Terminfo::properties::KeyC3, Terminfo::properties::KeyEnd, Terminfo::properties::KeyEnter,
351 Terminfo::properties::KeyExit, Terminfo::properties::KeyF0, Terminfo::properties::KeyF1,
352 Terminfo::properties::KeyF2, Terminfo::properties::KeyF3, Terminfo::properties::KeyF4,
353 Terminfo::properties::KeyF5, Terminfo::properties::KeyF6, Terminfo::properties::KeyF7,
354 Terminfo::properties::KeyF8, Terminfo::properties::KeyF9, Terminfo::properties::KeyF10,
355 Terminfo::properties::KeyF11, Terminfo::properties::KeyF12, Terminfo::properties::KeyF13,
356 Terminfo::properties::KeyF14, Terminfo::properties::KeyF15, Terminfo::properties::KeyF16,
357 Terminfo::properties::KeyF17, Terminfo::properties::KeyF18, Terminfo::properties::KeyF19,
358 Terminfo::properties::KeyF20, Terminfo::properties::KeyF21, Terminfo::properties::KeyF22,
359 Terminfo::properties::KeyF23, Terminfo::properties::KeyF24, Terminfo::properties::KeyF25,
360 Terminfo::properties::KeyF26, Terminfo::properties::KeyF27, Terminfo::properties::KeyF28,
361 Terminfo::properties::KeyF29, Terminfo::properties::KeyF30, Terminfo::properties::KeyF31,
362 Terminfo::properties::KeyF32, Terminfo::properties::KeyF33, Terminfo::properties::KeyF34,
363 Terminfo::properties::KeyF35, Terminfo::properties::KeyF36, Terminfo::properties::KeyF37,
364 Terminfo::properties::KeyF38, Terminfo::properties::KeyF39, Terminfo::properties::KeyF40,
365 Terminfo::properties::KeyF41, Terminfo::properties::KeyF42, Terminfo::properties::KeyF43,
366 Terminfo::properties::KeyF44, Terminfo::properties::KeyF45, Terminfo::properties::KeyF46,
367 Terminfo::properties::KeyF47, Terminfo::properties::KeyF48, Terminfo::properties::KeyF49,
368 Terminfo::properties::KeyF50, Terminfo::properties::KeyF51, Terminfo::properties::KeyF52,
369 Terminfo::properties::KeyF53, Terminfo::properties::KeyF54, Terminfo::properties::KeyF55,
370 Terminfo::properties::KeyF56, Terminfo::properties::KeyF57, Terminfo::properties::KeyF58,
371 Terminfo::properties::KeyF59, Terminfo::properties::KeyF60, Terminfo::properties::KeyF61,
372 Terminfo::properties::KeyF62, Terminfo::properties::KeyF63, Terminfo::properties::KeyFind,
373 Terminfo::properties::KeyHelp, Terminfo::properties::KeyHome, Terminfo::properties::KeyIc,
374 Terminfo::properties::KeyIl, Terminfo::properties::KeyLeft, Terminfo::properties::KeyMark,
375 Terminfo::properties::KeyMessage, Terminfo::properties::KeyMouse,
376 Terminfo::properties::KeyMove, Terminfo::properties::KeyNext, Terminfo::properties::KeyOpen,
377 Terminfo::properties::KeyOptions, Terminfo::properties::KeyNpage,
378 Terminfo::properties::KeyPpage, Terminfo::properties::KeyPrevious,
379 Terminfo::properties::KeyPrint, Terminfo::properties::KeyRedo,
380 Terminfo::properties::KeyReference, Terminfo::properties::KeyRefresh,
381 Terminfo::properties::KeyReplace, Terminfo::properties::KeyRestart,
382 Terminfo::properties::KeyResume, Terminfo::properties::KeyRight,
383 Terminfo::properties::KeySave, Terminfo::properties::KeySelect,
384 Terminfo::properties::KeySbeg, Terminfo::properties::KeyScancel,
385 Terminfo::properties::KeyScommand, Terminfo::properties::KeyScopy,
386 Terminfo::properties::KeyScreate, Terminfo::properties::KeySdc,
387 Terminfo::properties::KeySdl, Terminfo::properties::KeySend, Terminfo::properties::KeySeol,
388 Terminfo::properties::KeySexit, Terminfo::properties::KeySfind,
389 Terminfo::properties::KeyShelp, Terminfo::properties::KeyShome,
390 Terminfo::properties::KeySic, Terminfo::properties::KeySleft,
391 Terminfo::properties::KeySmessage, Terminfo::properties::KeySmove,
392 Terminfo::properties::KeySnext, Terminfo::properties::KeySoptions,
393 Terminfo::properties::KeySprevious, Terminfo::properties::KeySprint,
394 Terminfo::properties::KeySredo, Terminfo::properties::KeySreplace,
395 Terminfo::properties::KeySrsume, Terminfo::properties::KeySright,
396 Terminfo::properties::KeySsave, Terminfo::properties::KeySsuspend,
397 Terminfo::properties::KeyStab, Terminfo::properties::KeySundo,
398 Terminfo::properties::KeySuspend, Terminfo::properties::KeyUndo,
399 Terminfo::properties::KeyUp, Terminfo::properties::KeyA1, Terminfo::properties::KeyA3 };
402 for (unsigned i (0); i < sizeof(keyStrings)/sizeof(keyStrings[0]); ++i) {
403 char const * key (ti.getString(keyStrings[i]));
405 table_.insert(std::make_pair(key, KeyCode(i+First)));
409 prefix_ std::pair<senf::term::KeyParser::keycode_t, std::string::size_type>
410 senf::term::KeyParser::lookup(std::string const & key)
414 return std::make_pair(KeyCode(0), 0);
416 // There are several cases:
417 // a) 'key' is an incomplete key sequence. In this case, 'key' will precede all completions in
418 // the key table. The first possible completion is found by 'upper_bound'
419 // b) 'key' is a complete key sequence. This is the key sequence *preceding* the 'upper_bound'
420 // c) 'key' is a complete key sequence with additional trailing characters. In this case, 'key'
421 // will follow the correct entry in the key table. Again, the correct key sequence is
422 // the one preceding the 'upper_bound'
424 Keytable::const_iterator i (table_.upper_bound(key));
425 if (i != table_.end() && i->first.substr(0, key.size()) == key)
426 return std::make_pair(Incomplete, key.size());
427 if (i == table_.begin())
428 return std::make_pair(keycode_t(key[0]), 1);
430 if (key.substr(0, i->first.size()) == i->first)
431 return std::make_pair(i->second, i->first.size());
432 return std::make_pair(keycode_t(key[0]), 1);
435 prefix_ std::string senf::term::KeyParser::describe(keycode_t key)
437 if (key < keycode_t(' '))
438 return "^" + std::string(1, '@' + key);
440 return std::string(1, char(key));
441 if (key >= keycode_t(First) && key < keycode_t(First + sizeof(KeyNames) / sizeof(KeyNames[0])))
442 return std::string(KeyNames[key-First]);
444 return "<" + boost::lexical_cast<std::string>(unsigned(key)) + ">";
447 prefix_ void senf::term::KeyParser::dump(std::ostream & os)
451 for (Keytable::const_iterator i (table_.begin()); i != table_.end(); ++i) {
452 unsigned index (i->second - First);
453 if (index < sizeof(KeyNames)/sizeof(KeyNames[0])) {
454 std::cout << " " << std::setw(32) << KeyNames[index] << ": ";
455 hexdump(i->first.begin(), i->first.end(), os);
460 ///////////////////////////////cc.e////////////////////////////////////////
462 //#include "Terminfo.mpp"
468 // comment-column: 40
469 // c-file-style: "senf"
470 // indent-tabs-mode: nil
471 // ispell-local-dictionary: "american"
472 // compile-command: "scons -u test"