From dd7595a3475407a7fa96a97393bae8c5220e8762 Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Wed, 4 Jan 2012 18:41:13 +1000 Subject: Add the base Enlightenment Foundation Libraries - eina, eet, evas, ecore, embryo, and edje. Note that embryo wont be used, but I'm not sure yet if you can build edje without it. --- .../ecore/src/lib/ecore_x/xcb/ecore_xcb_textlist.c | 509 +++++++++++++++++++++ 1 file changed, 509 insertions(+) create mode 100644 libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_textlist.c (limited to 'libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_textlist.c') diff --git a/libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_textlist.c b/libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_textlist.c new file mode 100644 index 0000000..2a5c854 --- /dev/null +++ b/libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_textlist.c @@ -0,0 +1,509 @@ +#include "ecore_xcb_private.h" +//#include "Ecore_X_Atoms.h" +#include +#ifdef HAVE_ICONV +# include +#endif +#ifndef CODESET +# define CODESET "INVALID" +#endif + +static int _ecore_xcb_textlist_get_buffer_size(Eina_Bool is_wide, + void *list, + int count); +static int _ecore_xcb_textlist_get_wc_len(wchar_t *wstr); +static void *_ecore_xcb_textlist_alloc_list(Eina_Bool is_wide, + int count, + int nitems); +static void _ecore_xcb_textlist_copy_list(Eina_Bool is_wide, + void *text, + char **list, + int count); +static wchar_t *_ecore_xcb_textlist_copy_wchar(wchar_t *str1, + wchar_t *str2); +static int _ecore_xcb_textlist_len_wchar(wchar_t *str); + +#ifdef HAVE_ICONV +Eina_Bool +_ecore_xcb_utf8_textlist_to_textproperty(char **list, + int count, + Ecore_Xcb_Encoding_Style style, + Ecore_Xcb_Textproperty *ret) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_textlist_to_textproperty("utf8string", list, count, + style, ret); +} + +#endif + +Eina_Bool +_ecore_xcb_mb_textlist_to_textproperty(char **list, + int count, + Ecore_Xcb_Encoding_Style style, + Ecore_Xcb_Textproperty *ret) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_textlist_to_textproperty("multiByte", list, count, + style, ret); +} + +/* NB: This Function May Not Be Correct !!! + * (as I do not know text conversion, locales, etc, etc very well) + * + * Portions were ripped from libX11 XTextListToTextProperty + */ +Eina_Bool +_ecore_xcb_textlist_to_textproperty(const char *type, + char **list, + int count, + Ecore_Xcb_Encoding_Style style, + Ecore_Xcb_Textproperty *ret) +{ + Eina_Bool is_wide = EINA_FALSE; + Ecore_X_Atom encoding; + int len = 0, nitems = 0, i = 0; + size_t from_left = 0, to_left = 0; + int unconv_num = 0, val = 0; + char *buff, *to, *value, *from; + const char *to_type, *from_type; + char **mb = NULL; + wchar_t **wc = NULL; +#ifdef HAVE_ICONV + iconv_t conv; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!strcmp("wideChar", type)) is_wide = EINA_TRUE; + len = _ecore_xcb_textlist_get_buffer_size(is_wide, list, count); + if (!(buff = (char *)malloc(len * sizeof(char)))) return EINA_FALSE; + from_type = nl_langinfo(CODESET); + switch (style) + { + case XcbStringStyle: + case XcbStdICCTextStyle: + encoding = ECORE_X_ATOM_STRING; + to_type = nl_langinfo(CODESET); +// to_type = "string"; + break; + + case XcbUTF8StringStyle: + encoding = ECORE_X_ATOM_UTF8_STRING; + to_type = "UTF-8"; + break; + + case XcbCompoundTextStyle: + encoding = ECORE_X_ATOM_COMPOUND_TEXT; + to_type = nl_langinfo(CODESET); +// to_type = "compoundText"; + break; + + case XcbTextStyle: + encoding = ECORE_X_ATOM_TEXT; + to_type = nl_langinfo(CODESET); +// to_type = "multiByte"; + if (!is_wide) + { + nitems = 0; + mb = (char **)list; + to = buff; + for (i = 0; ((i < count) && (len > 0)); i++) + { + if (*mb) strcpy(to, *mb); + else *to = '\0'; + from_left = (*mb ? strlen(*mb) : 0) + 1; + nitems += from_left; + to += from_left; + mb++; + } + unconv_num = 0; + goto done; + } + break; + + default: + free(buff); + return EINA_FALSE; + break; + } + + if (count < 1) + { + nitems = 0; + goto done; + } + +retry: +#ifdef HAVE_ICONV + conv = iconv_open(to_type, from_type); +#endif + + if (is_wide) + wc = (wchar_t **)list; + else + mb = (char **)list; + + to = buff; + to_left = len; + unconv_num = 0; + for (i = 1; to_left > 0; i++) + { + if (is_wide) + { + from = (char *)*wc; + from_left = _ecore_xcb_textlist_get_wc_len(*wc); + wc++; + } + else + { + from = *mb; + from_left = (*mb ? strlen(*mb) : 0); + mb++; + } + +#ifdef HAVE_ICONV + val = iconv(conv, &from, &from_left, &to, &to_left); +#endif + if (val < 0) continue; + if ((val > 0) && (style == XcbStdICCTextStyle) && + (encoding == ECORE_X_ATOM_STRING)) + { +#ifdef HAVE_ICONV + iconv_close(conv); +#endif + encoding = ECORE_X_ATOM_COMPOUND_TEXT; + goto retry; + } + + unconv_num += val; + *to++ = '\0'; + to_left--; + if (i >= count) break; + } + +#ifdef HAVE_ICONV + iconv_close(conv); +#endif + nitems = (to - buff); + +done: + if (nitems <= 0) nitems = 1; + if (!(value = (char *)malloc(nitems * sizeof(char)))) + { + free(buff); + return EINA_FALSE; + } + if (nitems == 1) + *value = 0; + else + memcpy(value, buff, nitems); + nitems--; + free(buff); + + ret->value = value; + ret->encoding = encoding; + ret->format = 8; + ret->nitems = nitems; + + return EINA_TRUE; +} + +#ifdef HAVE_ICONV +Eina_Bool +_ecore_xcb_utf8_textproperty_to_textlist(const Ecore_Xcb_Textproperty *text_prop, + char ***list_ret, + int *count_ret) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_textproperty_to_textlist(text_prop, "utf8String", + list_ret, count_ret); +} + +#endif + +Eina_Bool +_ecore_xcb_mb_textproperty_to_textlist(const Ecore_Xcb_Textproperty *text_prop, + char ***list_ret, + int *count_ret) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_textproperty_to_textlist(text_prop, "multiByte", + list_ret, count_ret); +} + +Eina_Bool +_ecore_xcb_textproperty_to_textlist(const Ecore_Xcb_Textproperty *text_prop, + const char *type, + char ***list_ret, + int *count_ret) +{ + Eina_Bool is_wide = EINA_FALSE; + Eina_Bool do_strcpy = EINA_FALSE; + const char *from_type; + char *buff, *to, *from; + char *lptr, *sptr; + int nitems = 0, len = 0, num = 0, ret = 0; + size_t from_left = 0, to_left = 0; +#ifdef HAVE_ICONV + iconv_t conv = 0; +#endif + + *list_ret = NULL; + *count_ret = 0; + if (!strcmp("wideChar", type)) is_wide = EINA_TRUE; + + nitems = text_prop->nitems; + if (nitems <= 0) return EINA_TRUE; + + if (text_prop->format != 8) return EINA_FALSE; + + from_type = nl_langinfo(CODESET); + if (text_prop->encoding == ECORE_X_ATOM_UTF8_STRING) + from_type = "UTF-8"; + + if (is_wide) + len = (text_prop->nitems + 1) * sizeof(wchar_t); + else + { + if (!strcmp(type, "utf8String")) + len = text_prop->nitems * 6 + 1; + else + len = text_prop->nitems * MB_CUR_MAX + 1; + } + + buff = (char *)malloc(len * sizeof(char)); + if (!buff) return EINA_FALSE; + + to = buff; + to_left = len; + + if (!strcmp(from_type, type)) + do_strcpy = EINA_TRUE; + else + { +#ifdef HAVE_ICONV + conv = iconv_open(type, from_type); +#endif + if (!conv) + { + free(buff); + return EINA_FALSE; + } + } + + lptr = sptr = text_prop->value; + num = *count_ret = 0; + while (1) + { + if ((nitems == 0) || (*sptr == 0)) + { + from = lptr; + from_left = sptr - lptr; + lptr = sptr; + if (do_strcpy) + { + int l = 0; + + l = MIN(from_left, to_left); + strncpy(to, from, l); + from += len; + to += len; + from_left -= l; + to_left -= l; + ret = 0; + } + else + ret = iconv(conv, &from, &from_left, &to, &to_left); + + if (ret < 0) continue; + num += ret; + (*count_ret)++; + if (nitems == 0) break; + lptr = ++sptr; + if (is_wide) + { + *((wchar_t *)to) = (wchar_t)0; + to += sizeof(wchar_t); + to_left -= sizeof(wchar_t); + } + else + { + *((char *)to) = '\0'; + to++; + to_left--; + } + } + else + sptr++; + + nitems--; + } + +#if HAVE_ICONV + if (!do_strcpy) iconv_close(conv); +#endif + + if (is_wide) + { + *((wchar_t *)to) = (wchar_t)0; + to_left -= sizeof(wchar_t); + } + else + { + *((char *)to) = '\0'; + to_left--; + } + + *list_ret = + _ecore_xcb_textlist_alloc_list(is_wide, *count_ret, (len - to_left)); + if (*list_ret) + _ecore_xcb_textlist_copy_list(is_wide, buff, *list_ret, *count_ret); + + free(buff); + + return EINA_TRUE; +} + +static int +_ecore_xcb_textlist_get_buffer_size(Eina_Bool is_wide, + void *list, + int count) +{ + int len = 0; + char **mb; + wchar_t **wc; + + if (!list) return 0; + if (is_wide) + { + wc = (wchar_t **)list; + for (; count-- > 0; wc++) + if (*wc) len += _ecore_xcb_textlist_get_wc_len(*wc) + 1; + len *= 5; + } + else + { + mb = (char **)list; + for (; count-- > 0; mb++) + if (*mb) len += strlen(*mb) + 1; + len *= 3; + } + len = (len / 2048 + 1) * 2048; + return len; +} + +static int +_ecore_xcb_textlist_get_wc_len(wchar_t *wstr) +{ + wchar_t *ptr; + + ptr = wstr; + while (*ptr) + ptr++; + + return ptr - wstr; +} + +static void * +_ecore_xcb_textlist_alloc_list(Eina_Bool is_wide, + int count, + int nitems) +{ + if (is_wide) + { + wchar_t **list; + + list = (wchar_t **)malloc(count * sizeof(wchar_t *)); + if (!list) return NULL; + *list = (wchar_t *)malloc(nitems * sizeof(wchar_t)); + if (!*list) + { + free(list); + return NULL; + } + return *list; + } + else + { + char **list; + + list = (char **)malloc(count * sizeof(char *)); + if (!list) return NULL; + *list = (char *)malloc(nitems * sizeof(char)); + if (!*list) + { + free(list); + return NULL; + } + return *list; + } +} + +static void +_ecore_xcb_textlist_copy_list(Eina_Bool is_wide, + void *text, + char **list, + int count) +{ + int len = 0; + + if (is_wide) + { + wchar_t *txt, *str, **wlist; + + txt = (wchar_t *)text; + wlist = (wchar_t **)list; + for (str = *wlist; count > 0; count--, wlist++) + { + _ecore_xcb_textlist_copy_wchar(str, txt); + *wlist = str; + len = (_ecore_xcb_textlist_len_wchar(str) + 1); + str += len; + txt += len; + } + } + else + { + char *txt, *str, **slist; + + txt = (char *)text; + slist = (char **)list; + for (str = *slist; count > 0; count--, slist++) + { + strcpy(str, txt); + *slist = str; + len = strlen(str) + 1; + str += len; + txt += len; + } + } +} + +static wchar_t * +_ecore_xcb_textlist_copy_wchar(wchar_t *str1, + wchar_t *str2) +{ + wchar_t *tmp; + + tmp = str1; + while ((*str1++ = *str2++)) + ; + return tmp; +} + +static int +_ecore_xcb_textlist_len_wchar(wchar_t *str) +{ + wchar_t *ptr; + + ptr = str; + while (*ptr) + ptr++; + return ptr - str; +} + -- cgit v1.1