/[svn]/linuxsampler/trunk/src/shell/TerminalCtrl.cpp
ViewVC logotype

Annotation of /linuxsampler/trunk/src/shell/TerminalCtrl.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3054 - (hide annotations) (download)
Thu Dec 15 12:47:45 2016 UTC (7 years, 5 months ago) by schoenebeck
File size: 4984 byte(s)
* Fixed numerous compiler warnings.
* Bumped version (2.0.0.svn32).

1 schoenebeck 2515 /*
2     * LSCP Shell
3     *
4 schoenebeck 3054 * Copyright (c) 2014 - 2016 Christian Schoenebeck
5 schoenebeck 2515 *
6     * This program is part of LinuxSampler and released under the same terms.
7     */
8    
9     #include "TerminalCtrl.h"
10    
11     #include <unistd.h>
12     #include <termios.h>
13     #include <string.h>
14     #include <map>
15     #include <assert.h>
16     #include <sys/ioctl.h>
17     #include <stdio.h>
18 schoenebeck 2517 #include "../common/Mutex.h"
19 schoenebeck 2515
20 schoenebeck 2517 using namespace LinuxSampler;
21    
22 schoenebeck 2515 ///////////////////////////////////////////////////////////////////////////
23     // class 'TerminalSetting'
24    
25 schoenebeck 2517 static Mutex g_mutexReferences;
26 schoenebeck 2515 static std::map<void*,int> g_terminalSettingReferences;
27    
28     static termios* _newTermios() {
29     termios* p = new termios;
30 schoenebeck 2517 LockGuard lock(g_mutexReferences);
31 schoenebeck 2515 g_terminalSettingReferences[p] = 1;
32     return p;
33     }
34    
35     static void _releaseTermiosRef(void* p) {
36     if (!p) return;
37 schoenebeck 2517 LockGuard lock(g_mutexReferences);
38 schoenebeck 2515 std::map<void*,int>::iterator it = g_terminalSettingReferences.find(p);
39     assert(it != g_terminalSettingReferences.end());
40     assert(it->second > 0);
41     it->second--;
42     if (!it->second) {
43     g_terminalSettingReferences.erase(it);
44     delete (termios*) p;
45     }
46     }
47    
48     static termios* _bumpTermiosRef(void* p) {
49     if (!p) return NULL;
50 schoenebeck 2517 LockGuard lock(g_mutexReferences);
51 schoenebeck 2515 std::map<void*,int>::iterator it = g_terminalSettingReferences.find(p);
52     assert(it != g_terminalSettingReferences.end());
53     assert(it->second > 0);
54     it->second++;
55     return (termios*) p;
56     }
57    
58     TerminalSetting::TerminalSetting() : p(NULL) {
59     }
60    
61     TerminalSetting::TerminalSetting(const TerminalSetting& ts) : p(_bumpTermiosRef(ts.p)) {
62     }
63    
64     TerminalSetting::~TerminalSetting() {
65     _releaseTermiosRef(p);
66     }
67    
68     bool TerminalSetting::valid() const {
69     return p != NULL;
70     }
71    
72     ///////////////////////////////////////////////////////////////////////////
73     // class 'TerminalCtrl'
74    
75     static termios g_defaults;
76    
77     static void _saveDefaults() {
78     static bool done = false;
79     if (done) return;
80     if (tcgetattr(0, &g_defaults) < 0) return;
81     done = true;
82     }
83    
84     int TerminalCtrl::reset() {
85     _saveDefaults();
86     if (tcsetattr(0, TCSANOW, &g_defaults) < 0) return -1;
87     return 0; // success
88     }
89    
90     int TerminalCtrl::restore(const TerminalSetting& setting) {
91     _saveDefaults();
92     termios* s = (termios*) setting.p;
93     if (tcsetattr(0, TCSADRAIN, s) < 0) return -1;
94     return 0; // success
95     }
96    
97     TerminalSetting TerminalCtrl::now() {
98     _saveDefaults();
99     TerminalSetting setting;
100     if (!setting.p) setting.p = _newTermios();
101     if (tcgetattr(0, (termios*) setting.p) < 0)
102     return TerminalSetting(); // error, return invalid setting
103     return setting; // success
104     }
105    
106     int TerminalCtrl::echoInput(bool b) {
107     _saveDefaults();
108     termios settings = {};
109     if (tcgetattr(0, &settings) < 0) return -1;
110     if (b) {
111     settings.c_lflag |= ECHO;
112     if (tcsetattr(0, TCSADRAIN, &settings) < 0) return -1;
113     } else {
114     settings.c_lflag &= ~ECHO;
115     if (tcsetattr(0, TCSANOW, &settings) < 0) return -1;
116     }
117     return 0; // success
118     }
119    
120     int TerminalCtrl::immediateInput(bool b) {
121     _saveDefaults();
122     termios settings = {};
123     if (tcgetattr(0, &settings) < 0) return -1;
124     if (b) {
125     settings.c_lflag &= ~ICANON;
126     settings.c_cc[VMIN] = 0;
127     settings.c_cc[VTIME] = 0;
128     if (tcsetattr(0, TCSANOW, &settings) < 0) return -1;
129     } else {
130     settings.c_lflag |= ICANON;
131     if (tcsetattr(0, TCSADRAIN, &settings) < 0) return -1;
132     }
133     return 0; // success
134     }
135    
136     std::vector<char> TerminalCtrl::getChars(int max, int blockUntilMin, int burstDeciSeconds) {
137     _saveDefaults();
138     std::vector<char> v;
139    
140     TerminalSetting original = now();
141     if (!original.valid()) return v;
142    
143     termios setting = *(termios*)original.p; // copy
144     setting.c_lflag &= ~ICANON;
145     setting.c_cc[VMIN] = blockUntilMin;
146     setting.c_cc[VTIME] = burstDeciSeconds;
147     if (tcsetattr(0, TCSANOW, &setting) < 0) return v;
148     v.resize(max);
149 schoenebeck 3054 const int n = (int)read(0, &v[0], max);
150 schoenebeck 2515 if (n != max) v.resize(n < 0 ? 0 : n);
151    
152     restore(original);
153     return v;
154     }
155    
156     std::vector<char> TerminalCtrl::getCharsToDelimiter(char delimiter, bool includeDelimiter) {
157     _saveDefaults();
158     std::vector<char> result;
159     while (true) {
160     std::vector<char> v = getChars(1, 1);
161     if (v.empty()) break;
162     if (v[0] == delimiter && !includeDelimiter) break;
163     result.push_back(v[0]);
164     if (v[0] == delimiter) break;
165     }
166     return result;
167     }
168    
169     std::string TerminalCtrl::getStringToDelimiter(char delimiter, bool includeDelimiter) {
170     _saveDefaults();
171     std::string s;
172     std::vector<char> v = getCharsToDelimiter(delimiter, includeDelimiter);
173     if (v.empty()) return s;
174     v.push_back(0);
175 schoenebeck 3054 int n = (int)strlen(&v[0]);
176 schoenebeck 2515 s.resize(n);
177     memcpy(&s[0], &v[0], n);
178     return s;
179     }
180    
181     int TerminalCtrl::columns() {
182     struct winsize w;
183     ioctl(0, TIOCGWINSZ, &w);
184     return w.ws_col;
185     }
186    
187     int TerminalCtrl::rows() {
188     struct winsize w;
189     ioctl(0, TIOCGWINSZ, &w);
190     return w.ws_row;
191     }

  ViewVC Help
Powered by ViewVC