updated on Sat Jan 21 04:00:54 UTC 2012
[aur-mirror.git] / slim-unicode / unicode.patch
blob17e94e4a1ece67977e3ebb07e133b11fd0614a5c
1 Binary files a/PAM.o and b/PAM.o differ
2 diff -U 3 -H -d -p -r -N -- a/app.cpp b/app.cpp
3 --- a/app.cpp 2011-09-19 22:53:39.000000000 +0200
4 +++ b/app.cpp 2011-09-20 21:00:47.000000000 +0200
5 @@ -112,7 +112,7 @@ int xioerror(Display *disp) {
6 void CatchSignal(int sig) {
7 cerr << APPNAME << ": unexpected signal " << sig << endl;
9 - if (LoginApp->serverStarted)
10 + if (LoginApp->isServerStarted())
11 LoginApp->StopServer();
13 LoginApp->RemoveLock();
14 diff -U 3 -H -d -p -r -N -- a/app.h b/app.h
15 --- a/app.h 2011-09-19 22:53:39.000000000 +0200
16 +++ b/app.h 2011-09-20 21:00:47.000000000 +0200
17 @@ -36,11 +36,13 @@ public:
18 int GetServerPID();
19 void RestartServer();
20 void StopServer();
22 - bool serverStarted;
24 // Lock functions
25 void GetLock();
26 void RemoveLock();
27 + bool isServerStarted() {
28 + return serverStarted;
29 + }
31 private:
32 void Login();
33 @@ -77,6 +79,7 @@ private:
34 Panel* LoginPanel;
35 int ServerPID;
36 const char* DisplayName;
37 + bool serverStarted;
39 #ifdef USE_PAM
40 PAM::Authenticator pam;
41 Binary files a/app.o and b/app.o differ
42 diff -U 3 -H -d -p -r -N -- a/cfg.cpp b/cfg.cpp
43 --- a/cfg.cpp 2010-07-08 07:04:10.000000000 +0200
44 +++ b/cfg.cpp 2011-09-20 21:00:47.000000000 +0200
45 @@ -220,6 +220,14 @@ string Cfg::getWelcomeMessage(){
46 return s;
49 +/* Return the option as an integer, if we failed to parse
50 + * the string to an integer,the default value is returned */
51 +int Cfg::getIntOption(std::string option, int defaultVal) {
52 + char* err = 0;
53 + int l = (int)strtol(options[option].c_str(), &err, 10);
54 + return (*err == 0) ? l : defaultVal;
57 int Cfg::string2int(const char* string, bool* ok) {
58 char* err = 0;
59 int l = (int)strtol(string, &err, 10);
60 diff -U 3 -H -d -p -r -N -- a/cfg.h b/cfg.h
61 --- a/cfg.h 2010-07-08 07:04:10.000000000 +0200
62 +++ b/cfg.h 2011-09-20 21:00:47.000000000 +0200
63 @@ -15,9 +15,6 @@
64 #include <map>
65 #include <vector>
67 -#define INPUT_MAXLENGTH_NAME 30
68 -#define INPUT_MAXLENGTH_PASSWD 50
70 #define CFGFILE SYSCONFDIR"/slim.conf"
71 #define THEMESDIR PKGDATADIR"/themes"
72 #define THEMESFILE "/slim.theme"
73 @@ -28,11 +25,12 @@ public:
74 Cfg();
75 ~Cfg();
76 bool readConf(std::string configfile);
77 - std::string parseOption(std::string line, std::string option);
78 const std::string& getError() const;
79 std::string& getOption(std::string option);
80 + int getIntOption(std::string option, int defaultVal = 0);
81 std::string getWelcomeMessage();
84 + static std::string parseOption(std::string line, std::string option);
85 static int absolutepos(const std::string& position, int max, int width);
86 static int string2int(const char* string, bool* ok = 0);
87 static void split(std::vector<std::string>& v, const std::string& str,
88 @@ -49,7 +47,6 @@ private:
89 std::vector<std::string> sessions;
90 int currentSession;
91 std::string error;
95 #endif
96 Binary files a/cfg.o and b/cfg.o differ
97 diff -U 3 -H -d -p -r -N -- a/const.h b/const.h
98 --- a/const.h 2010-07-08 07:04:10.000000000 +0200
99 +++ b/const.h 2011-09-20 21:00:47.000000000 +0200
100 @@ -26,9 +26,6 @@
101 #define HIDE 0
102 #define SHOW 1
104 -#define GET_NAME 0
105 -#define GET_PASSWD 1
107 #define OK_EXIT 0
108 #define ERR_EXIT 1
110 @@ -42,4 +39,11 @@
111 // variables replaced in pre-session_cmd and post-session_cmd
112 #define USER_VAR "%user"
114 +// Define the right charset to use
115 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
116 +#define CHARSET_UTF_16 "UTF-16LE"
117 +#else
118 +#define CHARSET_UTF_16 "UTF-16BE"
119 +#endif
121 #endif
122 Binary files a/image.o and b/image.o differ
123 Binary files a/jpeg.o and b/jpeg.o differ
124 diff -U 3 -H -d -p -r -N -- a/main.cpp b/main.cpp
125 --- a/main.cpp 2010-07-08 07:04:10.000000000 +0200
126 +++ b/main.cpp 2011-09-20 21:00:47.000000000 +0200
127 @@ -15,6 +15,8 @@
128 App* LoginApp = 0;
130 int main(int argc, char** argv) {
131 + // We need to set the locale to use the iconv conversion fonction
132 + setlocale (LC_ALL, "");
133 LoginApp = new App(argc, argv);
134 LoginApp->Run();
135 return 0;
136 Binary files a/main.o and b/main.o differ
137 Binary files a/numlock.o and b/numlock.o differ
138 diff -U 3 -H -d -p -r -N -- a/panel.cpp b/panel.cpp
139 --- a/panel.cpp 2011-09-19 22:53:39.000000000 +0200
140 +++ b/panel.cpp 2011-09-20 21:00:47.000000000 +0200
141 @@ -12,6 +12,7 @@
142 #include <sstream>
143 #include <poll.h>
144 #include "panel.h"
145 +#include "util.h"
147 using namespace std;
149 @@ -57,15 +58,43 @@ Panel::Panel(Display* dpy, int scr, Wind
150 XftColorAllocName(Dpy, DefaultVisual(Dpy, Scr), colormap,
151 cfg->getOption("session_shadow_color").c_str(), &sessionshadowcolor);
153 +#ifdef X_HAVE_UTF8_STRING
154 + // Build XIC and XIM to be able to get unicode string from keyboard events
155 + char classname = 0;
156 + displayIm = XOpenIM(Dpy, NULL, &classname, &classname);
157 + if(displayIm) {
158 + displayIc = XCreateIC(displayIm,
159 + XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
160 + XNResourceName, &classname,
161 + XNResourceClass, &classname,
162 + NULL);
164 + else {
165 + displayIc = NULL;
167 +#endif
169 + // Allocate descriptor for character set conversion, from and to UTF-16
170 + iconvLocaleToUtf16 = iconv_open(CHARSET_UTF_16, "");
171 + iconvUtf16ToLocale = iconv_open("", CHARSET_UTF_16);
173 // Load properties from config / theme
174 - input_name_x = Cfg::string2int(cfg->getOption("input_name_x").c_str());
175 - input_name_y = Cfg::string2int(cfg->getOption("input_name_y").c_str());
176 - input_pass_x = Cfg::string2int(cfg->getOption("input_pass_x").c_str());
177 - input_pass_y = Cfg::string2int(cfg->getOption("input_pass_y").c_str());
178 - inputShadowXOffset =
179 - Cfg::string2int(cfg->getOption("input_shadow_xoffset").c_str());
180 - inputShadowYOffset =
181 - Cfg::string2int(cfg->getOption("input_shadow_yoffset").c_str());
182 + input_name_x = cfg->getIntOption("input_name_x");
183 + input_name_y = cfg->getIntOption("input_name_y");
184 + input_pass_x = cfg->getIntOption("input_pass_x");
185 + input_pass_y = cfg->getIntOption("input_pass_y");
187 + input_maxlength_name = cfg->getIntOption("input_maxlength_name", 20);
188 + nameBuffer = (uint16_t*) calloc (input_maxlength_name, sizeof(uint16_t));
189 + nameBufferLen = 0;
191 + input_maxlength_passwd = cfg->getIntOption("input_maxlength_passwd", 20);
192 + passwdBuffer = (uint16_t*) calloc (input_maxlength_passwd, sizeof(uint16_t));
193 + hiddenPasswdBuffer = (uint16_t*) calloc (input_maxlength_passwd, sizeof(uint16_t));
194 + passwdBufferLen = 0;
196 + inputShadowXOffset = cfg->getIntOption("input_shadow_xoffset");
197 + inputShadowYOffset = cfg->getIntOption("input_shadow_yoffset");
199 if (input_pass_x < 0 || input_pass_y < 0){ // single inputbox mode
200 input_pass_x = input_name_x;
201 @@ -140,6 +169,21 @@ Panel::Panel(Display* dpy, int scr, Wind
204 Panel::~Panel() {
206 +#ifdef X_HAVE_UTF8_STRING
207 + if(displayIc) {
208 + XDestroyIC(displayIc);
210 + if(displayIm) {
211 + XCloseIM(displayIm);
213 +#endif
214 + if(iconvLocaleToUtf16 != (iconv_t)(-1)) {
215 + iconv_close(iconvLocaleToUtf16);
217 + if(iconvUtf16ToLocale != (iconv_t)(-1)) {
218 + iconv_close(iconvUtf16ToLocale);
220 XftColorFree (Dpy, DefaultVisual(Dpy, Scr), DefaultColormap(Dpy, Scr), &inputcolor);
221 XftColorFree (Dpy, DefaultVisual(Dpy, Scr), DefaultColormap(Dpy, Scr), &msgcolor);
222 XftColorFree (Dpy, DefaultVisual(Dpy, Scr), DefaultColormap(Dpy, Scr), &welcomecolor);
223 @@ -152,6 +196,9 @@ Panel::~Panel() {
224 XftFontClose(Dpy, introfont);
225 XftFontClose(Dpy, welcomefont);
226 XftFontClose(Dpy, enterfont);
227 + free(nameBuffer);
228 + free(passwdBuffer);
229 + free(hiddenPasswdBuffer);
230 delete image;
233 @@ -202,24 +249,24 @@ void Panel::Message(const string& text)
234 XGlyphInfo extents;
235 XftDraw *draw = XftDrawCreate(Dpy, Root,
236 DefaultVisual(Dpy, Scr), DefaultColormap(Dpy, Scr));
237 - XftTextExtents8(Dpy, msgfont, reinterpret_cast<const XftChar8*>(text.c_str()),
238 - text.length(), &extents);
239 + int textLen = text.length();
240 + uint16_t *textBuf = (uint16_t*)calloc(textLen, sizeof(uint16_t));
241 + textLen = Util::localeStringToUtf16(iconvLocaleToUtf16, text, textBuf, textLen);
243 + XftTextExtents16(Dpy, msgfont, (XftChar16*)textBuf, textLen, &extents);
244 cfgX = cfg->getOption("msg_x");
245 cfgY = cfg->getOption("msg_y");
246 - int shadowXOffset =
247 - Cfg::string2int(cfg->getOption("msg_shadow_xoffset").c_str());
248 - int shadowYOffset =
249 - Cfg::string2int(cfg->getOption("msg_shadow_yoffset").c_str());
250 + int shadowXOffset = cfg->getIntOption("msg_shadow_xoffset");
251 + int shadowYOffset = cfg->getIntOption("msg_shadow_yoffset");
253 int msg_x = Cfg::absolutepos(cfgX, XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)), extents.width);
254 int msg_y = Cfg::absolutepos(cfgY, XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)), extents.height);
256 - SlimDrawString8 (draw, &msgcolor, msgfont, msg_x, msg_y,
257 - text,
258 - &msgshadowcolor,
259 - shadowXOffset, shadowYOffset);
260 + SlimDrawString16(draw, &msgcolor, msgfont, msg_x, msg_y,
261 + textBuf, textLen, &msgshadowcolor, shadowXOffset, shadowYOffset);
262 XFlush(Dpy);
263 XftDrawDestroy(draw);
264 + free(textBuf);
267 void Panel::Error(const string& text) {
268 @@ -247,29 +294,31 @@ unsigned long Panel::GetColor(const char
271 void Panel::Cursor(int visible) {
272 - const char* text;
273 - int xx, yy, y2, cheight;
274 + const uint16_t* text;
275 + int xx, yy, y2, cheight, textLen;
276 const char* txth = "Wj"; // used to get cursor height
278 switch(field) {
279 case Get_Passwd:
280 - text = HiddenPasswdBuffer.c_str();
281 + text = hiddenPasswdBuffer;
282 + textLen = passwdBufferLen;
283 xx = input_pass_x;
284 yy = input_pass_y;
285 break;
287 case Get_Name:
288 - text = NameBuffer.c_str();
289 + text = nameBuffer;
290 + textLen = nameBufferLen;
291 xx = input_name_x;
292 yy = input_name_y;
293 break;
296 XGlyphInfo extents;
297 - XftTextExtents8(Dpy, font, (XftChar8*)txth, strlen(txth), &extents);
298 + XftTextExtents8(Dpy, font, (XftChar8*)txth, 2, &extents);
299 cheight = extents.height;
300 y2 = yy - extents.y + extents.height;
301 - XftTextExtents8(Dpy, font, (XftChar8*)text, strlen(text), &extents);
302 + XftTextExtents16(Dpy, font, (XftChar16*)text, textLen, &extents);
303 xx += extents.width;
305 if(visible == SHOW) {
306 @@ -317,28 +366,28 @@ void Panel::OnExpose(void) {
307 XftDraw *draw = XftDrawCreate(Dpy, Win,
308 DefaultVisual(Dpy, Scr), DefaultColormap(Dpy, Scr));
309 XClearWindow(Dpy, Win);
310 - if (input_pass_x != input_name_x || input_pass_y != input_name_y){
311 - SlimDrawString8 (draw, &inputcolor, font, input_name_x, input_name_y,
312 - NameBuffer,
313 - &inputshadowcolor,
314 + if (input_pass_x != input_name_x || input_pass_y != input_name_y) {
315 + SlimDrawString16(draw, &inputcolor, font, input_name_x, input_name_y,
316 + nameBuffer, nameBufferLen, &inputshadowcolor,
317 inputShadowXOffset, inputShadowYOffset);
318 - SlimDrawString8 (draw, &inputcolor, font, input_pass_x, input_pass_y,
319 - HiddenPasswdBuffer,
320 - &inputshadowcolor,
322 + SlimDrawString16(draw, &inputcolor, font, input_pass_x, input_pass_y,
323 + hiddenPasswdBuffer, passwdBufferLen, &inputshadowcolor,
324 inputShadowXOffset, inputShadowYOffset);
325 - } else { //single input mode
327 + else { //single input mode
328 switch(field) {
329 case Get_Passwd:
330 - SlimDrawString8 (draw, &inputcolor, font,
331 + SlimDrawString16(draw, &inputcolor, font,
332 input_pass_x, input_pass_y,
333 - HiddenPasswdBuffer,
334 + hiddenPasswdBuffer, passwdBufferLen,
335 &inputshadowcolor,
336 inputShadowXOffset, inputShadowYOffset);
337 break;
338 case Get_Name:
339 - SlimDrawString8 (draw, &inputcolor, font,
340 + SlimDrawString16(draw, &inputcolor, font,
341 input_name_x, input_name_y,
342 - NameBuffer,
343 + nameBuffer, nameBufferLen,
344 &inputshadowcolor,
345 inputShadowXOffset, inputShadowYOffset);
346 break;
347 @@ -350,17 +399,47 @@ void Panel::OnExpose(void) {
348 ShowText();
351 +/* Check if the input character is allowed */
352 +bool Panel::isUtf16CharAllowed(uint16_t c) {
353 + return ((0x020 <= c && c <= 0x07E) || (0x0A0 <= c && c != 0x0AD));
356 +#define SIZE_BUFFER_KEY_PRESS 64
358 bool Panel::OnKeyPress(XEvent& event) {
359 - char ascii;
361 + int formerTextBufferLen = -1;
362 + int textBufferLen = -1;
363 + uint16_t *textBuffer = NULL;
364 KeySym keysym;
365 - XComposeStatus compstatus;
366 - int xx;
367 - int yy;
368 - string text;
369 - string formerString = "";
370 + int nbReadBuf = -1;
371 + uint16_t utf16buf[SIZE_BUFFER_KEY_PRESS];
373 - XLookupString(&event.xkey, &ascii, 1, &keysym, &compstatus);
374 - switch(keysym){
375 +#ifdef X_HAVE_UTF8_STRING
376 + if(displayIc) {
377 + Status status;
378 + char databuf[SIZE_BUFFER_KEY_PRESS];
379 + nbReadBuf = Xutf8LookupString(displayIc, &event.xkey, databuf,
380 + SIZE_BUFFER_KEY_PRESS, &keysym, &status);
381 + if(nbReadBuf > 0) {
382 + nbReadBuf = Util::utf8ToUtf16((unsigned char*)databuf, nbReadBuf,
383 + utf16buf, SIZE_BUFFER_KEY_PRESS);
386 + else
387 +#endif
389 + XComposeStatus compstatus;
390 + char databuf[SIZE_BUFFER_KEY_PRESS];
391 + nbReadBuf = XLookupString(&event.xkey, databuf,
392 + SIZE_BUFFER_KEY_PRESS, &keysym, &compstatus);
393 + if(nbReadBuf > 0) {
394 + nbReadBuf = Util::localeStringToUtf16(iconvLocaleToUtf16, databuf,
395 + nbReadBuf, utf16buf, SIZE_BUFFER_KEY_PRESS);
399 + switch(keysym) {
400 case XK_F1:
401 SwitchSession();
402 return true;
403 @@ -374,17 +453,17 @@ bool Panel::OnKeyPress(XEvent& event) {
404 case XK_KP_Enter:
405 if (field==Get_Name){
406 // Don't allow an empty username
407 - if (NameBuffer.empty()) return true;
408 + if (nameBufferLen <= 0) return true;
410 - if (NameBuffer==CONSOLE_STR){
411 + if (Util::utf16EqualToAscii(CONSOLE_STR, nameBuffer, nameBufferLen)) {
412 action = Console;
413 - } else if (NameBuffer==HALT_STR){
414 + } else if (Util::utf16EqualToAscii(HALT_STR, nameBuffer, nameBufferLen)) {
415 action = Halt;
416 - } else if (NameBuffer==REBOOT_STR){
417 + } else if (Util::utf16EqualToAscii(REBOOT_STR, nameBuffer, nameBufferLen)) {
418 action = Reboot;
419 - } else if (NameBuffer==SUSPEND_STR){
420 + } else if (Util::utf16EqualToAscii(SUSPEND_STR, nameBuffer, nameBufferLen)) {
421 action = Suspend;
422 - } else if (NameBuffer==EXIT_STR){
423 + } else if (Util::utf16EqualToAscii(EXIT_STR, nameBuffer, nameBufferLen)) {
424 action = Exit;
425 } else{
426 action = Login;
427 @@ -400,17 +479,20 @@ bool Panel::OnKeyPress(XEvent& event) {
428 case XK_Delete:
429 case XK_BackSpace:
430 switch(field) {
431 - case GET_NAME:
432 - if (! NameBuffer.empty()){
433 - formerString=NameBuffer;
434 - NameBuffer.erase(--NameBuffer.end());
435 + case Get_Name:
436 + if (nameBufferLen > 0) {
437 + formerTextBufferLen = nameBufferLen;
438 + nameBufferLen--;
439 + textBuffer = nameBuffer;
440 + textBufferLen = nameBufferLen;
442 break;
443 - case GET_PASSWD:
444 - if (! PasswdBuffer.empty()){
445 - formerString=HiddenPasswdBuffer;
446 - PasswdBuffer.erase(--PasswdBuffer.end());
447 - HiddenPasswdBuffer.erase(--HiddenPasswdBuffer.end());
448 + case Get_Passwd:
449 + if (passwdBufferLen > 0) {
450 + formerTextBufferLen = passwdBufferLen;
451 + passwdBufferLen--;
452 + textBuffer = hiddenPasswdBuffer;
453 + textBufferLen = passwdBufferLen;
455 break;
457 @@ -421,14 +503,17 @@ bool Panel::OnKeyPress(XEvent& event) {
458 if (reinterpret_cast<XKeyEvent&>(event).state & ControlMask) {
459 switch(field) {
460 case Get_Passwd:
461 - formerString = HiddenPasswdBuffer;
462 - HiddenPasswdBuffer.clear();
463 - PasswdBuffer.clear();
464 + formerTextBufferLen = passwdBufferLen;
465 + passwdBufferLen = 0;
466 + textBuffer = hiddenPasswdBuffer;
467 + textBufferLen = 0;
468 break;
470 case Get_Name:
471 - formerString = NameBuffer;
472 - NameBuffer.clear();
473 + formerTextBufferLen = nameBufferLen;
474 + nameBufferLen = 0;
475 + textBuffer = nameBuffer;
476 + textBufferLen = 0;
477 break;
479 break;
480 @@ -436,65 +521,78 @@ bool Panel::OnKeyPress(XEvent& event) {
481 // Deliberate fall-through
483 default:
484 - if (isprint(ascii) && (keysym < XK_Shift_L || keysym > XK_Hyper_R)){
485 + if(nbReadBuf > 0) {
486 switch(field) {
487 - case GET_NAME:
488 - formerString=NameBuffer;
489 - if (NameBuffer.length() < INPUT_MAXLENGTH_NAME-1){
490 - NameBuffer.append(&ascii,1);
491 - };
492 + case Get_Name:
493 + formerTextBufferLen = nameBufferLen;
494 + for(int i = 0; i < nbReadBuf &&
495 + nameBufferLen < input_maxlength_name; i++) {
497 + if(isUtf16CharAllowed(utf16buf[i])) {
498 + nameBuffer[nameBufferLen] = utf16buf[i];
499 + nameBufferLen++;
502 + textBuffer = nameBuffer;
503 + textBufferLen = nameBufferLen;
504 + break;
506 + case Get_Passwd:
507 + formerTextBufferLen = passwdBufferLen;
508 + for(int i = 0; i < nbReadBuf &&
509 + passwdBufferLen < input_maxlength_passwd; i++) {
511 + if(isUtf16CharAllowed(utf16buf[i])) {
512 + passwdBuffer[passwdBufferLen] = utf16buf[i];
513 + hiddenPasswdBuffer[passwdBufferLen] = (uint16_t)'*';
514 + passwdBufferLen++;
517 + textBuffer = hiddenPasswdBuffer;
518 + textBufferLen = passwdBufferLen;
519 break;
520 - case GET_PASSWD:
521 - formerString=HiddenPasswdBuffer;
522 - if (PasswdBuffer.length() < INPUT_MAXLENGTH_PASSWD-1){
523 - PasswdBuffer.append(&ascii,1);
524 - HiddenPasswdBuffer.append("*");
525 - };
526 - break;
528 - };
530 break;
533 + XftDraw *draw = NULL;
534 + int xx, yy;
536 + if (formerTextBufferLen > 0 || textBufferLen > 0) {
537 + draw = XftDrawCreate(Dpy, Win, DefaultVisual(Dpy, Scr), DefaultColormap(Dpy, Scr));
538 + switch(field) {
539 + case Get_Name:
540 + xx = input_name_x;
541 + yy = input_name_y;
542 + break;
544 - XGlyphInfo extents;
545 - XftDraw *draw = XftDrawCreate(Dpy, Win,
546 - DefaultVisual(Dpy, Scr), DefaultColormap(Dpy, Scr));
548 - switch(field) {
549 - case Get_Name:
550 - text = NameBuffer;
551 - xx = input_name_x;
552 - yy = input_name_y;
553 - break;
555 - case Get_Passwd:
556 - text = HiddenPasswdBuffer;
557 - xx = input_pass_x;
558 - yy = input_pass_y;
559 - break;
560 + case Get_Passwd:
561 + xx = input_pass_x;
562 + yy = input_pass_y;
563 + break;
567 - if (!formerString.empty()){
568 + if (formerTextBufferLen > 0) {
569 + XGlyphInfo extents;
570 const char* txth = "Wj"; // get proper maximum height ?
571 - XftTextExtents8(Dpy, font, reinterpret_cast<const XftChar8*>(txth), strlen(txth), &extents);
572 + XftTextExtents8(Dpy, font, (XftChar8*)txth, 2, &extents);
573 int maxHeight = extents.height;
575 - XftTextExtents8(Dpy, font, reinterpret_cast<const XftChar8*>(formerString.c_str()),
576 - formerString.length(), &extents);
577 + XftTextExtents16(Dpy, font, (XftChar16*)textBuffer, formerTextBufferLen, &extents);
578 int maxLength = extents.width;
580 XClearArea(Dpy, Win, xx-3, yy-maxHeight-3,
581 - maxLength+6, maxHeight+6, false);
582 + maxLength+6, maxHeight+6, false);
585 - if (!text.empty()) {
586 - SlimDrawString8 (draw, &inputcolor, font, xx, yy,
587 - text,
588 - &inputshadowcolor,
589 - inputShadowXOffset, inputShadowYOffset);
590 + if(textBufferLen > 0) {
591 + SlimDrawString16(draw, &inputcolor, font, xx, yy, textBuffer, textBufferLen,
592 + &inputshadowcolor, inputShadowXOffset, inputShadowYOffset);
595 - XftDrawDestroy (draw);
596 + if(draw != NULL) {
597 + XftDrawDestroy(draw);
600 Cursor(SHOW);
601 return true;
603 @@ -511,58 +609,67 @@ void Panel::ShowText(){
604 XftDraw *draw = XftDrawCreate(Dpy, Win,
605 DefaultVisual(Dpy, Scr), DefaultColormap(Dpy, Scr));
606 /* welcome message */
607 - XftTextExtents8(Dpy, welcomefont, (XftChar8*)welcome_message.c_str(),
608 - strlen(welcome_message.c_str()), &extents);
609 + int textLen = welcome_message.length();
610 + uint16_t *textBuf = (uint16_t*)calloc(textLen, sizeof(uint16_t));
611 + textLen = Util::localeStringToUtf16(iconvLocaleToUtf16, welcome_message, textBuf, textLen);
613 + XftTextExtents16(Dpy, welcomefont, (XftChar16*)textBuf, textLen, &extents);
614 cfgX = cfg->getOption("welcome_x");
615 cfgY = cfg->getOption("welcome_y");
616 - int shadowXOffset =
617 - Cfg::string2int(cfg->getOption("welcome_shadow_xoffset").c_str());
618 - int shadowYOffset =
619 - Cfg::string2int(cfg->getOption("welcome_shadow_yoffset").c_str());
620 + int shadowXOffset = cfg->getIntOption("welcome_shadow_xoffset");
621 + int shadowYOffset = cfg->getIntOption("welcome_shadow_yoffset");
622 welcome_x = Cfg::absolutepos(cfgX, image->Width(), extents.width);
623 welcome_y = Cfg::absolutepos(cfgY, image->Height(), extents.height);
624 if (welcome_x >= 0 && welcome_y >= 0) {
625 - SlimDrawString8 (draw, &welcomecolor, welcomefont,
626 - welcome_x, welcome_y,
627 - welcome_message,
628 + SlimDrawString16(draw, &welcomecolor, welcomefont,
629 + welcome_x, welcome_y, textBuf, textLen,
630 &welcomeshadowcolor, shadowXOffset, shadowYOffset);
632 + free(textBuf);
634 /* Enter username-password message */
635 string msg;
636 if (!singleInputMode|| field == Get_Passwd ) {
637 msg = cfg->getOption("password_msg");
638 - XftTextExtents8(Dpy, enterfont, (XftChar8*)msg.c_str(),
639 - strlen(msg.c_str()), &extents);
641 + textLen = msg.length();
642 + textBuf = (uint16_t*)calloc(textLen, sizeof(uint16_t));
643 + textLen = Util::localeStringToUtf16(iconvLocaleToUtf16, msg, textBuf, textLen);
645 + XftTextExtents16(Dpy, enterfont, (XftChar16*)textBuf, textLen, &extents);
646 cfgX = cfg->getOption("password_x");
647 cfgY = cfg->getOption("password_y");
648 - int shadowXOffset =
649 - Cfg::string2int(cfg->getOption("username_shadow_xoffset").c_str());
650 - int shadowYOffset =
651 - Cfg::string2int(cfg->getOption("username_shadow_yoffset").c_str());
652 + int shadowXOffset = cfg->getIntOption("username_shadow_xoffset");
653 + int shadowYOffset = cfg->getIntOption("username_shadow_yoffset");
654 password_x = Cfg::absolutepos(cfgX, image->Width(), extents.width);
655 password_y = Cfg::absolutepos(cfgY, image->Height(), extents.height);
656 if (password_x >= 0 && password_y >= 0){
657 - SlimDrawString8 (draw, &entercolor, enterfont, password_x, password_y,
658 - msg, &entershadowcolor, shadowXOffset, shadowYOffset);
659 + SlimDrawString16(draw, &entercolor, enterfont, password_x, password_y,
660 + textBuf, textLen, &entershadowcolor,
661 + shadowXOffset, shadowYOffset);
663 + free(textBuf);
665 if (!singleInputMode|| field == Get_Name ) {
666 msg = cfg->getOption("username_msg");
667 - XftTextExtents8(Dpy, enterfont, (XftChar8*)msg.c_str(),
668 - strlen(msg.c_str()), &extents);
670 + textLen = msg.length();
671 + textBuf = (uint16_t*)calloc(textLen, sizeof(uint16_t));
672 + textLen = Util::localeStringToUtf16(iconvLocaleToUtf16, msg, textBuf, textLen);
674 + XftTextExtents16(Dpy, enterfont, (XftChar16*)textBuf, textLen, &extents);
675 cfgX = cfg->getOption("username_x");
676 cfgY = cfg->getOption("username_y");
677 - int shadowXOffset =
678 - Cfg::string2int(cfg->getOption("username_shadow_xoffset").c_str());
679 - int shadowYOffset =
680 - Cfg::string2int(cfg->getOption("username_shadow_yoffset").c_str());
681 + int shadowXOffset = cfg->getIntOption("username_shadow_xoffset");
682 + int shadowYOffset = cfg->getIntOption("username_shadow_yoffset");
683 username_x = Cfg::absolutepos(cfgX, image->Width(), extents.width);
684 username_y = Cfg::absolutepos(cfgY, image->Height(), extents.height);
685 if (username_x >= 0 && username_y >= 0){
686 - SlimDrawString8 (draw, &entercolor, enterfont, username_x, username_y,
687 - msg, &entershadowcolor, shadowXOffset, shadowYOffset);
688 + SlimDrawString16(draw, &entercolor, enterfont, username_x, username_y,
689 + textBuf, textLen, &entershadowcolor,
690 + shadowXOffset, shadowYOffset);
692 + free(textBuf);
694 XftDrawDestroy(draw);
696 @@ -581,45 +688,43 @@ void Panel::SwitchSession() {
698 // Display session type on the screen
699 void Panel::ShowSession() {
700 - string msg_x, msg_y;
701 + string msg_x, msg_y;
702 XClearWindow(Dpy, Root);
703 string currsession = cfg->getOption("session_msg") + " " + session;
704 XGlyphInfo extents;
706 - sessionfont = XftFontOpenName(Dpy, Scr, cfg->getOption("session_font").c_str());
707 + sessionfont = XftFontOpenName(Dpy, Scr, cfg->getOption("session_font").c_str());
709 - XftDraw *draw = XftDrawCreate(Dpy, Root,
710 + int textLen = currsession.length();
711 + uint16_t *textBuf = (uint16_t*)calloc(textLen, sizeof(uint16_t));
712 + textLen = Util::localeStringToUtf16(iconvLocaleToUtf16, currsession, textBuf, textLen);
714 + XftDraw *draw = XftDrawCreate(Dpy, Root,
715 DefaultVisual(Dpy, Scr), DefaultColormap(Dpy, Scr));
716 - XftTextExtents8(Dpy, sessionfont, reinterpret_cast<const XftChar8*>(currsession.c_str()),
717 - currsession.length(), &extents);
718 + XftTextExtents16(Dpy, sessionfont, (XftChar16*)textBuf, textLen, &extents);
719 msg_x = cfg->getOption("session_x");
720 msg_y = cfg->getOption("session_y");
721 int x = Cfg::absolutepos(msg_x, XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)), extents.width);
722 int y = Cfg::absolutepos(msg_y, XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)), extents.height);
723 - int shadowXOffset =
724 - Cfg::string2int(cfg->getOption("session_shadow_xoffset").c_str());
725 - int shadowYOffset =
726 - Cfg::string2int(cfg->getOption("session_shadow_yoffset").c_str());
727 + int shadowXOffset = cfg->getIntOption("session_shadow_xoffset");
728 + int shadowYOffset = cfg->getIntOption("session_shadow_yoffset");
730 - SlimDrawString8(draw, &sessioncolor, sessionfont, x, y,
731 - currsession,
732 - &sessionshadowcolor,
733 + SlimDrawString16(draw, &sessioncolor, sessionfont, x, y,
734 + textBuf, textLen, &sessionshadowcolor,
735 shadowXOffset, shadowYOffset);
736 XFlush(Dpy);
737 XftDrawDestroy(draw);
738 + free(textBuf);
742 -void Panel::SlimDrawString8(XftDraw *d, XftColor *color, XftFont *font,
743 - int x, int y, const string& str,
744 - XftColor* shadowColor,
745 - int xOffset, int yOffset)
746 +void Panel::SlimDrawString16(XftDraw *d, XftColor *color, XftFont *font,
747 + int x, int y, uint16_t *str, int strLen,
748 + XftColor* shadowColor, int xOffset, int yOffset)
750 if (xOffset && yOffset) {
751 - XftDrawString8(d, shadowColor, font, x+xOffset, y+yOffset,
752 - reinterpret_cast<const FcChar8*>(str.c_str()), str.length());
753 + XftDrawString16(d, shadowColor, font, x+xOffset, y+yOffset,
754 + (XftChar16*)str, strLen);
756 - XftDrawString8(d, color, font, x, y, reinterpret_cast<const FcChar8*>(str.c_str()), str.length());
757 + XftDrawString16(d, color, font, x, y, (XftChar16*)str, strLen);
761 @@ -634,21 +739,19 @@ void Panel::Reset(void){
764 void Panel::ResetName(void){
765 - NameBuffer.clear();
766 + nameBufferLen = 0;
769 void Panel::ResetPasswd(void){
770 - PasswdBuffer.clear();
771 - HiddenPasswdBuffer.clear();
772 + passwdBufferLen = 0;
775 -void Panel::SetName(const string& name){
776 - NameBuffer=name;
777 - return;
778 +void Panel::SetName(const string& name) {
779 + nameBufferLen = Util::localeStringToUtf16(iconvLocaleToUtf16, name, nameBuffer, input_maxlength_name);
781 -const string& Panel::GetName(void) const{
782 - return NameBuffer;
783 +const string Panel::GetName(void) const {
784 + return Util::utf16StringToLocale(iconvUtf16ToLocale, nameBuffer, nameBufferLen);
786 -const string& Panel::GetPasswd(void) const{
787 - return PasswdBuffer;
788 +const string Panel::GetPasswd(void) const {
789 + return Util::utf16StringToLocale(iconvUtf16ToLocale, passwdBuffer, passwdBufferLen);
791 diff -U 3 -H -d -p -r -N -- a/panel.h b/panel.h
792 --- a/panel.h 2010-07-08 07:04:10.000000000 +0200
793 +++ b/panel.h 2011-09-20 21:00:47.000000000 +0200
794 @@ -19,9 +19,11 @@
795 #include <X11/Xmu/WinUtil.h>
796 #include <sys/wait.h>
797 #include <stdlib.h>
798 +#include <stdint.h>
799 #include <signal.h>
800 #include <iostream>
801 #include <string>
802 +#include <iconv.h>
804 #ifdef NEEDS_BASENAME
805 #include <libgen.h>
806 @@ -64,8 +66,8 @@ public:
807 void ResetName(void);
808 void ResetPasswd(void);
809 void SetName(const std::string& name);
810 - const std::string& GetName(void) const;
811 - const std::string& GetPasswd(void) const;
812 + const std::string GetName(void) const;
813 + const std::string GetPasswd(void) const;
814 private:
815 Panel();
816 void Cursor(int visible);
817 @@ -75,11 +77,11 @@ private:
818 void ShowText();
819 void SwitchSession();
820 void ShowSession();
822 - void SlimDrawString8(XftDraw *d, XftColor *color, XftFont *font,
823 - int x, int y, const std::string& str,
824 - XftColor* shadowColor,
825 - int xOffset, int yOffset);
827 + static bool isUtf16CharAllowed(uint16_t c);
828 + static void SlimDrawString16(XftDraw *d, XftColor *color, XftFont *font,
829 + int x, int y, uint16_t *str, int strLen,
830 + XftColor* shadowColor, int xOffset, int yOffset);
832 Cfg* cfg;
834 @@ -109,15 +111,25 @@ private:
835 XftColor entershadowcolor;
836 ActionType action;
837 FieldType field;
838 +#ifdef X_HAVE_UTF8_STRING
839 + XIM displayIm;
840 + XIC displayIc;
841 +#endif
842 + iconv_t iconvLocaleToUtf16;
843 + iconv_t iconvUtf16ToLocale;
845 // Username/Password
846 - std::string NameBuffer;
847 - std::string PasswdBuffer;
848 - std::string HiddenPasswdBuffer;
849 + uint16_t *nameBuffer;
850 + int nameBufferLen;
851 + uint16_t *passwdBuffer;
852 + int passwdBufferLen;
853 + uint16_t *hiddenPasswdBuffer;
855 // Configuration
856 int input_name_x;
857 int input_name_y;
858 + int input_maxlength_passwd;
859 + int input_maxlength_name;
860 int input_pass_x;
861 int input_pass_y;
862 int inputShadowXOffset;
863 Binary files a/panel.o and b/panel.o differ
864 diff -U 3 -H -d -p -r -N -- a/png.c b/png.c
865 --- a/png.c 2010-07-08 07:04:10.000000000 +0200
866 +++ b/png.c 2011-09-20 21:00:47.000000000 +0200
867 @@ -56,8 +56,8 @@ read_png(const char *filename, int *widt
868 fclose(infile);
869 return(0);
872 - if (setjmp(png_ptr->jmpbuf))
874 + if (setjmp(png_jmpbuf(png_ptr)))
876 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
877 fclose(infile);
878 Binary files a/png.o and b/png.o differ
879 Binary files a/slim and b/slim differ
880 diff -U 3 -H -d -p -r -N -- a/switchuser.cpp b/switchuser.cpp
881 --- a/switchuser.cpp 2010-07-08 07:04:10.000000000 +0200
882 +++ b/switchuser.cpp 2011-09-20 21:00:47.000000000 +0200
883 @@ -55,10 +55,8 @@ void SwitchUser::Execute(const char* cmd
886 void SwitchUser::SetClientAuth(const char* mcookie) {
887 - bool r;
888 string home = string(Pw->pw_dir);
889 string authfile = home + "/.Xauthority";
890 remove(authfile.c_str());
891 - r = Util::add_mcookie(mcookie, ":0", cfg->getOption("xauth_path"),
892 - authfile);
893 + Util::add_mcookie(mcookie, ":0", cfg->getOption("xauth_path"), authfile);
895 diff -U 3 -H -d -p -r -N -- a/switchuser.h b/switchuser.h
896 --- a/switchuser.h 2011-09-19 22:53:39.000000000 +0200
897 +++ b/switchuser.h 2011-09-20 21:00:47.000000000 +0200
898 @@ -33,14 +33,12 @@ public:
899 void Login(const char* cmd, const char* mcookie);
901 private:
902 - SwitchUser();
903 - void SetEnvironment();
904 void SetUserId();
905 void Execute(const char* cmd);
906 void SetClientAuth(const char* mcookie);
908 Cfg* cfg;
909 struct passwd *Pw;
911 std::string displayName;
912 char** env;
914 Binary files a/switchuser.o and b/switchuser.o differ
915 diff -U 3 -H -d -p -r -N -- a/util.cpp b/util.cpp
916 --- a/util.cpp 2010-07-08 07:04:10.000000000 +0200
917 +++ b/util.cpp 2011-09-20 21:00:47.000000000 +0200
918 @@ -67,3 +67,174 @@ long Util::makeseed(void)
920 return pid + tm + (ts.tv_sec ^ ts.tv_nsec);
923 +/* Given a UTF-8 encoded string pointed to by utf8 of length length in
924 + bytes, returns the corresponding UTF-16 encoded string in the
925 + buffer pointed to by utf16. The maximum number of UTF-16 encoding
926 + units (i.e., Unit16s) allowed in the buffer is specified in
927 + utf16_max_length. The return value is the number of UTF-16
928 + encoding units placed in the output buffer pointed to by utf16.
930 + In case of an error, -1 is returned, leaving some unusable partial
931 + results in the output buffer.
933 + The caller must estimate the size of utf16 buffer by itself before
934 + calling this function. Insufficient output buffer is considered as
935 + an error, and once an error occured, this function doesn't give any
936 + clue how large the result will be.
938 + The error cases include following:
940 + - Invalid byte sequences were in the input UTF-8 bytes. The caller
941 + has no way to know what point in the input buffer was the
942 + errornous byte.
944 + - The input contained a character (a valid UTF-8 byte sequence)
945 + whose scalar value exceeded the range that UTF-16 can represent
946 + (i.e., characters whose Unicode scalar value above 0x110000).
948 + - The output buffer has no enough space to hold entire utf16 data.
950 + Please note:
952 + - '\0'-termination is not assumed both on the input UTF-8 string
953 + and on the output UTF-16 string; any legal zero byte in the input
954 + UTF-8 string will be converted to a 16-bit zero in output. As a
955 + side effect, the last UTF-16 encoding unit stored in the output
956 + buffer will have a non-zero value if the input UTF-8 was not
957 + '\0'-terminated.
959 + - UTF-8 aliases are *not* considered as an error. They are
960 + converted to UTF-16. For example, 0xC0 0xA0, 0xE0 0x80 0xA0,
961 + and 0xF0 0x80 0x80 0xA0 are all mapped to a single UTF-16
962 + encoding unit 0x0020.
964 + - Three byte UTF-8 sequences whose value corresponds to a surrogate
965 + code or other reserved scalar value are not considered as an
966 + error either. They may cause an invalid UTF-16 data (e.g., those
967 + containing unpaired surrogates).
971 +int Util::utf8ToUtf16(const unsigned char *utf8, const int utf8_length, uint16_t *utf16, const int utf16_max_length) {
973 + /* p moves over the output buffer. max_ptr points to the next to the last slot of the buffer. */
974 + uint16_t *p = utf16;
975 + const uint16_t *max_ptr = utf16 + utf16_max_length;
977 + /* end_of_input points to the last byte of input as opposed to the next to the last byte. */
978 + unsigned char const *const end_of_input = utf8 + utf8_length - 1;
980 + while (utf8 <= end_of_input) {
981 + const unsigned char c = *utf8;
982 + if (p >= max_ptr) {
983 + /* No more output space. */
984 + return -1;
986 + if (c < 0x80) {
987 + /* One byte ASCII. */
988 + *p++ = c;
989 + utf8 += 1;
990 + } else if (c < 0xC0) {
991 + /* Follower byte without preceeding leader bytes. */
992 + return -1;
993 + } else if (c < 0xE0) {
994 + /* Two byte sequence. We need one follower byte. */
995 + if (end_of_input - utf8 < 1 || (((utf8[1] ^ 0x80)) & 0xC0)) {
996 + return -1;
998 + *p++ = (uint16_t)(0xCF80 + (c << 6) + utf8[1]);
999 + utf8 += 2;
1000 + } else if (c < 0xF0) {
1001 + /* Three byte sequence. We need two follower byte. */
1002 + if (end_of_input - utf8 < 2 || (((utf8[1] ^ 0x80) | (utf8[2] ^ 0x80)) & 0xC0)) {
1003 + return -1;
1005 + *p++ = (uint16_t)(0xDF80 + (c << 12) + (utf8[1] << 6) + utf8[2]);
1006 + utf8 += 3;
1007 + } else if (c < 0xF8) {
1008 + int plane;
1009 + /* Four byte sequence. We need three follower bytes. */
1010 + if (end_of_input - utf8 < 3 || (((utf8[1] ^ 0x80) | (utf8[2] ^0x80) | (utf8[3] ^ 0x80)) & 0xC0)) {
1011 + return -1;
1013 + plane = (-0xC8 + (c << 2) + (utf8[1] >> 4));
1014 + if (plane == 0) {
1015 + /* This four byte sequence is an alias that
1016 + corresponds to a Unicode scalar value in BMP.
1017 + It fits in an UTF-16 encoding unit. */
1018 + *p++ = (uint16_t)(0xDF80 + (utf8[1] << 12) + (utf8[2] << 6) + utf8[3]);
1019 + } else if (plane <= 16) {
1020 + /* This is a legal four byte sequence that corresponds to a surrogate pair. */
1021 + if (p + 1 >= max_ptr) {
1022 + /* No enough space on the output buffer for the pair. */
1023 + return -1;
1025 + *p++ = (uint16_t)(0xE5B8 + (c << 8) + (utf8[1] << 2) + (utf8[2] >> 4));
1026 + *p++ = (uint16_t)(0xDB80 + ((utf8[2] & 0x0F) << 6) + utf8[3]);
1027 + } else {
1028 + /* This four byte sequence is out of UTF-16 code space. */
1029 + return -1;
1031 + utf8 += 4;
1032 + } else {
1033 + /* Longer sequence or unused byte. */
1034 + return -1;
1037 + return p - utf16;
1040 +/* Compare an ASCII string with an UTF-16 string */
1041 +bool Util::utf16EqualToAscii(const char *ascii, uint16_t *utf16, int utf16Len) {
1043 + while(*ascii != 0 && utf16Len > 0) {
1044 + if(*utf16 != (uint16_t)*ascii) {
1045 + return false;
1047 + utf16++;
1048 + ascii++;
1049 + utf16Len--;
1051 + return *ascii == 0 && utf16Len == 0;
1054 +/* Convert a string using the locale encoding to an UTF-16 string */
1055 +int Util::localeStringToUtf16(iconv_t cd, const std::string& str, uint16_t *utf16Buf, int utf16BufLen)
1057 + return localeStringToUtf16(cd, str.c_str(), str.length(), utf16Buf, utf16BufLen);
1060 +/* Convert a string using the locale encoding to an UTF-16 string */
1061 +int Util::localeStringToUtf16(iconv_t cd, const char *str, size_t inbytesleft, uint16_t *utf16Buf, int utf16BufLen)
1063 + size_t outbytesleft = utf16BufLen * 2;
1064 + char *ptOutBuf = (char *)utf16Buf;
1065 + char *ptStr = (char *)str;
1067 + if(iconv(cd, &ptStr, &inbytesleft, &ptOutBuf, &outbytesleft) == 0) {
1068 + int lenWrit = ptOutBuf - (char *)utf16Buf;
1069 + if(lenWrit % 2 == 0) {
1070 + return lenWrit / 2;
1073 + return 0;
1076 +/* Convert an UTF-16 string to a string using the locale encoding */
1077 +std::string Util::utf16StringToLocale(iconv_t cd, uint16_t *utf16Buf, int lenBuf)
1079 + size_t inbytesleft = lenBuf * 2;
1080 + size_t outbytesleft = inbytesleft;
1081 + char *outBuf = (char*)calloc(outbytesleft, sizeof(char));
1082 + char *ptOutBuf = outBuf;
1083 + char *ptStr = (char *)utf16Buf;
1085 + if(iconv(cd, &ptStr, &inbytesleft, &ptOutBuf, &outbytesleft) == 0) {
1086 + std::string retStr(outBuf, ptOutBuf - outBuf);
1087 + free(outBuf);
1088 + return retStr;
1090 + free(outBuf);
1091 + return "";
1093 diff -U 3 -H -d -p -r -N -- a/util.h b/util.h
1094 --- a/util.h 2010-07-08 07:04:10.000000000 +0200
1095 +++ b/util.h 2011-09-20 21:00:47.000000000 +0200
1096 @@ -10,15 +10,25 @@
1097 #define __UTIL_H__
1099 #include <string>
1100 +#include <stdint.h>
1101 +#include <iconv.h>
1103 namespace Util {
1104 - bool add_mcookie(const std::string &mcookie, const char *display,
1105 - const std::string &xauth_cmd, const std::string &authfile);
1107 - void srandom(unsigned long seed);
1108 - long random(void);
1109 + bool add_mcookie(const std::string &mcookie, const char *display,
1110 + const std::string &xauth_cmd, const std::string &authfile);
1112 - long makeseed(void);
1113 + void srandom(unsigned long seed);
1114 + long random(void);
1115 + long makeseed(void);
1116 + int utf8ToUtf16(const unsigned char *utf8, const int utf8_length,
1117 + uint16_t *utf16, const int utf16_max_length);
1118 + bool utf16EqualToAscii(const char *ascii, uint16_t *utf16, int utf16Len);
1119 + int localeStringToUtf16(iconv_t cd, const std::string& str,
1120 + uint16_t *utf16Buf, int utf16BufLen);
1121 + int localeStringToUtf16(iconv_t cd, const char *str,
1122 + size_t inbytesleft, uint16_t *utf16Buf, int utf16BufLen);
1124 + std::string utf16StringToLocale(iconv_t cd, uint16_t *utf16Buf, int lenBuf);
1127 #endif /* __UTIL_H__ */
1128 Binary files a/util.o and b/util.o differ