diff --git a/eiconman/Jamfile b/eiconman/Jamfile index 4d5783c..97d2deb 100644 --- a/eiconman/Jamfile +++ b/eiconman/Jamfile @@ -10,7 +10,7 @@ SubDir TOP eiconman ; -SOURCE = eiconman.cpp Utils.cpp Wallpaper.cpp DesktopIcon.cpp NotifyBox.cpp ; +SOURCE = eiconman.cpp Utils.cpp Wallpaper.cpp DesktopIcon.cpp NotifyBox.cpp Utf8.cpp ; EdeProgram eiconman : $(SOURCE) ; TranslationStrings locale : $(SOURCE) ; diff --git a/eiconman/Utf8.cpp b/eiconman/Utf8.cpp new file mode 100644 index 0000000..ace9250 --- /dev/null +++ b/eiconman/Utf8.cpp @@ -0,0 +1,48 @@ +#include "Utf8.h" + +int utf16_to_utf8(unsigned int from, char* to) { + if(from < 0x000080) { + to[0] = from; + return 1; + } else if(from < 0x000800) { + to[0] = 0xC0 | (from >> 6); + to[1] = 0x80 | (from & 0x3F); + return 2; + } else if(from < 0x010000) { + to[0] = 0xE0 | (from >> 12); + to[1] = 0x80 | ((from >> 6) & 0x3F); + to[2] = 0x80 | (from & 0x3F); + return 3; + } else if(from < 0x00200000) { + to[0] = 0xF0 | (from >> 18); + to[1] = 0x80 | ((from >> 12) & 0x3F); + to[2] = 0x80 | ((from >> 6) & 0x3F); + to[3] = 0x80 | (from & 0x3F); + return 4; + } else if(from < 0x01000000) { + to[0] = 0xF8 | (from >> 24); + to[1] = 0x80 | ((from >> 18) & 0x3F); + to[2] = 0x80 | ((from >> 12) & 0x3F); + to[3] = 0x80 | ((from >> 6) & 0x3F); + to[4] = 0x80 | (from & 0x3F); + return 5; + } + to[0] = '?'; + return -1; +} + +int utf16_to_utf8_str(unsigned short* from, int len, char* to) { + int j = 0; + for(int i = 0; i < len; i++) { + int s = utf16_to_utf8((unsigned int)from[i], to + j); + if(s < 1) + j += 1; + else + j += s; + } + return j; +} + +bool is_utf16(unsigned short* from, int len) { + return !(from[0] < 0x000080); +} diff --git a/eiconman/Utf8.h b/eiconman/Utf8.h new file mode 100644 index 0000000..9a636e0 --- /dev/null +++ b/eiconman/Utf8.h @@ -0,0 +1,13 @@ +#ifndef __UTF8_H__ +#define __UTF8_H__ + +// 'to' must be at least 5 bytes long +int utf16_to_utf8(unsigned int from, char* to); + +// 'to' must be at least len * 5 long +int utf16_to_utf8_str(unsigned short* from, int len, char* to); + +// check if characters are in UTF-16 encoding +bool is_utf16(unsigned short* from, int len); + +#endif diff --git a/eiconman/Utils.cpp b/eiconman/Utils.cpp index e74b73d..be6231c 100644 --- a/eiconman/Utils.cpp +++ b/eiconman/Utils.cpp @@ -173,6 +173,7 @@ bool ede_get_desktop_notify(char* txt, int txt_len) { } strncpy(txt, vnames[0], txt_len); + txt[txt_len] = '\0'; XFreeStringList(vnames); return true; } diff --git a/eiconman/eiconman.cpp b/eiconman/eiconman.cpp index 2b95953..890a8ec 100644 --- a/eiconman/eiconman.cpp +++ b/eiconman/eiconman.cpp @@ -15,6 +15,7 @@ #include "Utils.h" #include "Wallpaper.h" #include "NotifyBox.h" +#include "Utf8.h" #include #include @@ -678,10 +679,25 @@ void Desktop::drop_source(const char* src, int src_len, int x, int y) { if(src_len < 1) return; +#if 0 + /* + * Commented for now since is_utf16() does not works as expected; + * on other hand, UTF-16 conversion is fine + */ + if(is_utf16((unsigned short*)src, src_len)) { + char* utf_src = new char[src_len * 5]; + if(utf16_to_utf8_str((unsigned short*)src, src_len, utf_src)) { + utf_src[src_len] = '\0'; + EDEBUG(ESTRLOC ":==========> %s|\n", utf_src); + } + + delete [] utf_src; + } +#endif char* src_copy = new char[src_len + 1]; int real_len = 0; - // mozilla sends junk in form: ascii<0>ascii<0>..., don't know why + // mozilla sends UTF-16 form; for now use this hack untill Utf8.cpp code is ready for(int i = 0, j = 0; i < src_len; i++) { if(src[i] != 0) { src_copy[j++] = src[i];