summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOsamu Sayama <osamu.sayama@sun.com>2007-05-18 13:27:56 -0700
committerAlan Coopersmith <alan.coopersmith@sun.com>2007-05-18 13:27:56 -0700
commit4abb71337d740fdcca30f4f2f57b769b7f422c13 (patch)
tree411dbf7ce9f2842a0a2c4ac024546dc6a90512ed
parentd335cefbbe5d23c410f8e8b7af0692559b649e67 (diff)
Sun bug 6518500: Use iconv() to convert other charsets to UTF8
<http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=6518500>
-rw-r--r--Clock.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/Clock.c b/Clock.c
index efff6ca..67ef814 100644
--- a/Clock.c
+++ b/Clock.c
@@ -97,6 +97,12 @@ SOFTWARE.
#include <stdio.h>
#include <X11/Xos.h>
#include <X11/Xaw/XawInit.h>
+#ifndef NO_I18N
+#include <iconv.h>
+#include <langinfo.h>
+#include <errno.h>
+#include <limits.h>
+#endif
#if defined(XawVersion) && (XawVersion >= 7000002L)
#define USE_XAW_PIXMAP_CVT
@@ -230,6 +236,7 @@ static void DrawClockFace ( ClockWidget w );
static int clock_round ( double x );
static Boolean SetValues ( Widget gcurrent, Widget grequest, Widget gnew,
ArgList args, Cardinal *num_args );
+static char *clock_to_utf8(const char *);
ClockClassRec clockClassRec = {
{ /* core fields */
@@ -624,10 +631,16 @@ Initialize (Widget request, Widget new, ArgList args, Cardinal *num_args)
if (w->clock.render)
{
XGlyphInfo extents;
+ char *utf8_str;
#ifndef NO_I18N
if (w->clock.utf8)
XftTextExtentsUtf8 (XtDisplay (w), w->clock.face,
(FcChar8 *) str, len, &extents);
+ else if ((utf8_str = clock_to_utf8(str)) != NULL) {
+ XftTextExtentsUtf8 (XtDisplay (w), w->clock.face,
+ (FcChar8 *)utf8_str, strlen(utf8_str), &extents);
+ free(utf8_str);
+ }
else
#endif
XftTextExtents8 (XtDisplay (w), w->clock.face,
@@ -798,6 +811,7 @@ RenderTextBounds (ClockWidget w, char *str, int off, int len,
{
XGlyphInfo head, tail;
int x, y;
+ char *utf8_str;
#ifndef NO_I18N
if (w->clock.utf8)
@@ -807,6 +821,14 @@ RenderTextBounds (ClockWidget w, char *str, int off, int len,
XftTextExtentsUtf8 (XtDisplay (w), w->clock.face,
(FcChar8 *) str + off, len - off, &tail);
}
+ else if ((utf8_str = clock_to_utf8(str)) != NULL)
+ {
+ XftTextExtentsUtf8 (XtDisplay (w), w->clock.face,
+ (FcChar8 *)utf8_str, off, &head);
+ XftTextExtentsUtf8 (XtDisplay (w), w->clock.face,
+ (FcChar8 *)utf8_str + off, strlen(utf8_str) - off, &tail);
+ free(utf8_str);
+ }
else
#endif
{
@@ -1276,6 +1298,7 @@ clock_tic(XtPointer client_data, XtIntervalId *id)
{
XRectangle old_tail, new_tail, head;
int x, y;
+ char *utf8_str;
RenderTextBounds (w, w->clock.prev_time_string, i, prev_len,
&old_tail, 0, 0);
@@ -1303,6 +1326,15 @@ clock_tic(XtPointer client_data, XtIntervalId *id)
(FcChar8 *) time_ptr + i, len - i);
}
+ else if ((utf8_str =
+ clock_to_utf8(time_ptr + i)) != NULL) {
+ XftDrawStringUtf8 (w->clock.draw,
+ &w->clock.fg_color,
+ w->clock.face,
+ x, y,
+ (FcChar8 *)utf8_str, strlen(utf8_str) - i);
+ free(utf8_str);
+ }
else
#endif
{
@@ -2046,3 +2078,51 @@ SetValues(Widget gcurrent, Widget grequest, Widget gnew,
return (redisplay);
}
+
+#ifndef NO_I18N
+static char *
+clock_to_utf8(const char *str)
+{
+ iconv_t cd;
+ char *buf;
+ size_t in_len;
+ size_t buf_size;
+ size_t ileft, oleft;
+ const char *inptr;
+ char *outptr;
+ size_t ret;
+ const char *code_set = nl_langinfo(CODESET);
+
+ if (str == NULL ||code_set == NULL || strcasecmp(code_set, "646") == 0)
+ return NULL;
+
+ if (strcasecmp(code_set, "UTF-8") == 0)
+ return strdup(str);
+
+ cd = iconv_open("UTF-8", code_set);
+ if (cd == (iconv_t)-1)
+ return NULL;
+
+ in_len = strlen(str);
+ buf_size = MB_LEN_MAX * (in_len + 1);
+ if ((buf = malloc(buf_size)) == NULL) {
+ (void) iconv_close(cd);
+ return NULL;
+ }
+
+ inptr = str;
+ ileft = in_len;
+ outptr = buf;
+ oleft = buf_size;
+
+ ret = iconv(cd, &inptr, &ileft, &outptr, &oleft);
+ if (ret == (size_t)(-1) || oleft == 0 ) {
+ free(buf);
+ buf = NULL;
+ } else
+ *outptr = '\0';
+
+ (void) iconv_close(cd);
+ return buf;
+}
+#endif