1 // Copyright (C) 2013-2015 Petr Pavlu <setup@dagobah.cz>
3 // This file is part of CenterIM.
5 // CenterIM is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
10 // CenterIM is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with CenterIM. If not, see <http://www.gnu.org/licenses/>.
18 #include "CppConsUI.h"
20 #include "ColorScheme.h"
21 #include "CoreManager.h"
22 #include "KeyConfig.h"
33 ColorScheme
*color_scheme
= nullptr;
34 CoreManager
*core_manager
= nullptr;
35 KeyConfig
*key_config
= nullptr;
37 Error::Error(ErrorCode code
, const char *string
)
38 : error_code_(code
), error_string_(nullptr)
43 Error::Error(const Error
&other
)
45 assert(other
.error_string_
!= nullptr);
47 error_code_
= other
.error_code_
;
49 std::size_t size
= std::strlen(other
.error_string_
) + 1;
50 error_string_
= new char[size
];
51 std::strcpy(error_string_
, other
.error_string_
);
54 Error
&Error::operator=(const Error
&other
)
56 assert(other
.error_string_
!= nullptr);
58 std::size_t size
= std::strlen(other
.error_string_
) + 1;
59 auto new_string
= new char[size
];
60 std::strcpy(new_string
, other
.error_string_
);
62 error_code_
= other
.error_code_
;
63 delete[] error_string_
;
64 error_string_
= new_string
;
71 delete[] error_string_
;
74 void Error::setCode(ErrorCode code
)
79 void Error::setString(const char *string
)
82 if (string
!= nullptr)
83 size
+= std::strlen(string
);
84 auto new_string
= new char[size
];
85 if (string
!= nullptr)
86 std::strcpy(new_string
, string
);
90 delete[] error_string_
;
91 error_string_
= new_string
;
94 void Error::setFormattedString(const char *format
, ...)
96 assert(format
!= nullptr);
100 va_start(args
, format
);
101 int size
= std::vsnprintf(nullptr, 0, format
, args
) + 1;
104 auto new_string
= new char[size
];
106 va_start(args
, format
);
107 std::vsprintf(new_string
, format
, args
);
110 delete[] error_string_
;
111 error_string_
= new_string
;
116 error_code_
= ERROR_NONE
;
117 delete[] error_string_
;
118 error_string_
= nullptr;
121 void initializeConsUI(AppInterface
&interface
)
123 assert(color_scheme
== nullptr);
124 assert(core_manager
== nullptr);
125 assert(key_config
== nullptr);
127 // Initialize ColorScheme and KeyConfig. These cannot fail.
128 color_scheme
= new ColorScheme
;
129 key_config
= new KeyConfig
;
131 // CoreManager depends on KeyConfig so it has to be initialized after it.
132 core_manager
= new CoreManager(interface
);
135 void finalizeConsUI()
137 assert(color_scheme
!= nullptr);
138 assert(core_manager
!= nullptr);
139 assert(key_config
!= nullptr);
141 // Destroy CoreManager, KeyConfig and ColorScheme.
143 core_manager
= nullptr;
145 key_config
= nullptr;
147 color_scheme
= nullptr;
150 ColorScheme
*getColorSchemeInstance()
152 assert(color_scheme
!= nullptr);
156 CoreManager
*getCoreManagerInstance()
158 assert(core_manager
!= nullptr);
162 KeyConfig
*getKeyConfigInstance()
164 assert(key_config
!= nullptr);
170 // Some code below is based on the GLib code.
172 // Bits Length Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 Byte 6
174 // 11 2 110xxxxx 10xxxxxx
175 // 16 3 1110xxxx 10xxxxxx 10xxxxxx
176 // 21 4 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
177 // 26 5 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
178 // 31 6 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
179 UniChar
getUniChar(const char *p
)
181 assert(p
!= nullptr);
184 unsigned char c
= *p
++;
187 if ((c
& 0x80) == 0x00)
189 else if ((c
& 0xe0) == 0xc0) {
193 else if ((c
& 0xf0) == 0xe0) {
197 else if ((c
& 0xf8) == 0xf0) {
201 else if ((c
& 0xfc) == 0xf8) {
205 else if ((c
& 0xfe) == 0xfc) {
214 if ((c
& 0xc0) != 0x80)
229 int interval_compare(const void *key
, const void *elt
)
231 const UniChar uc
= *static_cast<const UniChar
*>(key
);
232 const Interval
*interval
= static_cast<const Interval
*>(elt
);
234 if (uc
< interval
->start
)
236 if (uc
> interval
->end
)
242 } // anonymous namespace
244 bool isUniCharWide(UniChar uc
)
246 static const Interval wide
[] = {{0x1100, 0x115F}, {0x2329, 0x232A},
247 {0x2E80, 0x2E99}, {0x2E9B, 0x2EF3}, {0x2F00, 0x2FD5}, {0x2FF0, 0x2FFB},
248 {0x3000, 0x303E}, {0x3041, 0x3096}, {0x3099, 0x30FF}, {0x3105, 0x312D},
249 {0x3131, 0x318E}, {0x3190, 0x31BA}, {0x31C0, 0x31E3}, {0x31F0, 0x321E},
250 {0x3220, 0x3247}, {0x3250, 0x32FE}, {0x3300, 0x4DBF}, {0x4E00, 0xA48C},
251 {0xA490, 0xA4C6}, {0xA960, 0xA97C}, {0xAC00, 0xD7A3}, {0xF900, 0xFAFF},
252 {0xFE10, 0xFE19}, {0xFE30, 0xFE52}, {0xFE54, 0xFE66}, {0xFE68, 0xFE6B},
253 {0xFF01, 0xFF60}, {0xFFE0, 0xFFE6}, {0x1B000, 0x1B001}, {0x1F200, 0x1F202},
254 {0x1F210, 0x1F23A}, {0x1F240, 0x1F248}, {0x1F250, 0x1F251},
255 {0x20000, 0x2FFFD}, {0x30000, 0x3FFFD}};
257 if (std::bsearch(&uc
, wide
, sizeof(wide
) / sizeof(wide
[0]), sizeof(wide
[0]),
264 bool isUniCharDigit(UniChar uc
)
266 // Note: this function does not behave according to the Unicode standard.
268 if (uc
> '0' && uc
< '9')
273 bool isUniCharSpace(UniChar uc
)
275 // Note: this function does not behave according to the Unicode standard.
277 if (uc
== '\t' || uc
== '\n' || uc
== '\r' || uc
== '\f')
282 const char *getNextChar(const char *p
)
284 static const char utf8_skip_data
[256] = {
285 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00-0x0f
286 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10-0x1f
287 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x20-0x2f
288 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x30-0x3f
289 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40-0x4f
290 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x50-0x5f
291 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60-0x6f
292 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x70-0x7f
293 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80-0x8f
294 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90-0x9f
295 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0-0xaf
296 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0-0xbf
297 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0-0xcf
298 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0-0xdf
299 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xe0-0xef
300 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 1, 1 // 0xf0-0xff
303 return p
+ utf8_skip_data
[static_cast<unsigned char>(*p
)];
306 const char *getPrevChar(const char *p
)
310 if ((*p
& 0xc0) != 0x80)
315 const char *findNextChar(const char *p
, const char *end
)
318 return getNextChar(p
);
320 while (p
+ 1 < end
) {
322 if ((*p
& 0xc0) != 0x80)
328 const char *findPrevChar(const char *start
, const char *p
)
332 if ((*p
& 0xc0) != 0x80)
340 } // namespace CppConsUI
342 // vim: set tabstop=2 shiftwidth=2 textwidth=80 expandtab: