]> git.sur5r.net Git - i3/i3/commitdiff
Consolidate all convert_* functions into libi3.
authorFernando Tarlá Cardoso Lemos <fernandotcl@gmail.com>
Fri, 11 Nov 2011 23:18:37 +0000 (21:18 -0200)
committerMichael Stapelberg <michael@stapelberg.de>
Wed, 16 Nov 2011 20:54:30 +0000 (20:54 +0000)
Some minor fixes along the way as well. Very minor stuff, unlikely
to ever be visible to the user.

14 files changed:
i3-input/i3-input.h
i3-input/main.c
i3-input/ucs2_to_utf8.c [deleted file]
i3bar/include/common.h
i3bar/include/ucs2_to_utf8.h [deleted file]
i3bar/src/ucs2_to_utf8.c [deleted file]
include/libi3.h
include/util.h
include/xcb.h
libi3/ucs2_conversion.c [new file with mode: 0644]
src/sighandler.c
src/util.c
src/window.c
src/xcb.c

index d97807d1749decec42982bf935e50fb37d6028f3..f494cbd56704c260c4806e486a17fd301948c4b8 100644 (file)
@@ -14,7 +14,4 @@ while (0)
 
 extern xcb_window_t root;
 
-char *convert_ucs_to_utf8(char *input);
-char *convert_utf8_to_ucs2(char *input, int *real_strlen);
-
 #endif
index def6848177464d7a86eec2aa8b91ef3ad4b7f2f7..3eabd15d89fe7be91746351388594dd91bb483c5 100644 (file)
@@ -260,14 +260,14 @@ static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press
 
     printf("inp[0] = %02x, inp[1] = %02x, inp[2] = %02x\n", inp[0], inp[1], inp[2]);
     /* convert it to UTF-8 */
-    char *out = convert_ucs_to_utf8((char*)inp);
+    char *out = convert_ucs2_to_utf8((xcb_char2b_t*)inp, 1);
     printf("converted to %s\n", out);
 
     glyphs_ucs[input_position] = malloc(3 * sizeof(uint8_t));
     if (glyphs_ucs[input_position] == NULL)
         err(EXIT_FAILURE, "malloc() failed\n");
     memcpy(glyphs_ucs[input_position], inp, 3);
-    glyphs_utf8[input_position] = strdup(out);
+    glyphs_utf8[input_position] = out;
     input_position++;
 
     if (input_position == limit)
@@ -348,7 +348,7 @@ int main(int argc, char *argv[]) {
     sockfd = ipc_connect(socket_path);
 
     if (prompt != NULL)
-        prompt = convert_utf8_to_ucs2(prompt, &prompt_len);
+        prompt = (char*)convert_utf8_to_ucs2(prompt, &prompt_len);
 
     int screens;
     conn = xcb_connect(NULL, &screens);
diff --git a/i3-input/ucs2_to_utf8.c b/i3-input/ucs2_to_utf8.c
deleted file mode 100644 (file)
index df112ee..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * vim:ts=4:sw=4:expandtab
- *
- * i3 - an improved dynamic tiling window manager
- * © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE)
- *
- * ucs2_to_utf8.c: Converts between UCS-2 and UTF-8, both of which are used in
- *                 different contexts in X11.
- *
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <err.h>
-#include <iconv.h>
-
-#include "libi3.h"
-
-static iconv_t conversion_descriptor = 0;
-static iconv_t conversion_descriptor2 = 0;
-
-/*
- * Returns the input string, but converted from UCS-2 to UTF-8. Memory will be
- * allocated, thus the caller has to free the output.
- *
- */
-char *convert_ucs_to_utf8(char *input) {
-    size_t input_size = 2;
-    /* UTF-8 may consume up to 4 byte */
-    int buffer_size = 8;
-
-    char *buffer = scalloc(buffer_size);
-    size_t output_size = buffer_size;
-    /* We need to use an additional pointer, because iconv() modifies it */
-    char *output = buffer;
-
-    /* We convert the input into UCS-2 big endian */
-    if (conversion_descriptor == 0) {
-        conversion_descriptor = iconv_open("UTF-8", "UCS-2BE");
-        if (conversion_descriptor == 0)
-            errx(EXIT_FAILURE, "Error opening the conversion context");
-    }
-
-    /* Get the conversion descriptor back to original state */
-    iconv(conversion_descriptor, NULL, NULL, NULL, NULL);
-
-    /* Convert our text */
-    int rc = iconv(conversion_descriptor, (void*)&input, &input_size, &output, &output_size);
-    if (rc == (size_t)-1) {
-        free(buffer);
-        perror("Converting to UCS-2 failed");
-        return NULL;
-    }
-
-    return buffer;
-}
-
-/*
- * Converts the given string to UCS-2 big endian for use with
- * xcb_image_text_16(). The amount of real glyphs is stored in real_strlen,
- * a buffer containing the UCS-2 encoded string (16 bit per glyph) is
- * returned. It has to be freed when done.
- *
- */
-char *convert_utf8_to_ucs2(char *input, int *real_strlen) {
-    size_t input_size = strlen(input) + 1;
-    /* UCS-2 consumes exactly two bytes for each glyph */
-    int buffer_size = input_size * 2;
-
-    char *buffer = smalloc(buffer_size);
-    size_t output_size = buffer_size;
-    /* We need to use an additional pointer, because iconv() modifies it */
-    char *output = buffer;
-
-    /* We convert the input into UCS-2 big endian */
-    if (conversion_descriptor2 == 0) {
-        conversion_descriptor2 = iconv_open("UCS-2BE", "UTF-8");
-        if (conversion_descriptor2 == 0)
-            errx(EXIT_FAILURE, "Error opening the conversion context");
-    }
-
-    /* Get the conversion descriptor back to original state */
-    iconv(conversion_descriptor2, NULL, NULL, NULL, NULL);
-
-    /* Convert our text */
-    int rc = iconv(conversion_descriptor2, (void*)&input, &input_size, &output, &output_size);
-    if (rc == (size_t)-1) {
-        perror("Converting to UCS-2 failed");
-        free(buffer);
-        if (real_strlen != NULL)
-            *real_strlen = 0;
-        return NULL;
-    }
-
-    if (real_strlen != NULL)
-        *real_strlen = ((buffer_size - output_size) / 2) - 1;
-
-    return buffer;
-}
-
index 3b6967faf347cdace0c353c9b30680ac032eb82f..bce31a4df22cd5c267d3bf9626b97025d424f2cb 100644 (file)
@@ -31,7 +31,6 @@ struct rect_t {
 #include "workspaces.h"
 #include "trayclients.h"
 #include "xcb.h"
-#include "ucs2_to_utf8.h"
 #include "config.h"
 #include "libi3.h"
 
diff --git a/i3bar/include/ucs2_to_utf8.h b/i3bar/include/ucs2_to_utf8.h
deleted file mode 100644 (file)
index a77ed20..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * vim:ts=4:sw=4:expandtab
- *
- * i3 - an improved dynamic tiling window manager
- * © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE)
- *
- * ucs2_to_utf8.c: Converts between UCS-2 and UTF-8, both of which are used in
- *                 different contexts in X11.
- */
-#ifndef _UCS2_TO_UTF8
-#define _UCS2_TO_UTF8
-
-char *convert_utf8_to_ucs2(char *input, int *real_strlen);
-
-#endif
diff --git a/i3bar/src/ucs2_to_utf8.c b/i3bar/src/ucs2_to_utf8.c
deleted file mode 100644 (file)
index 642a72f..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * vim:ts=4:sw=4:expandtab
- *
- * i3 - an improved dynamic tiling window manager
- * © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE)
- *
- * ucs2_to_utf8.c: Converts between UCS-2 and UTF-8, both of which are used in
- *                 different contexts in X11.
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <err.h>
-#include <iconv.h>
-
-#include "libi3.h"
-
-static iconv_t conversion_descriptor = 0;
-static iconv_t conversion_descriptor2 = 0;
-
-/*
- * Returns the input string, but converted from UCS-2 to UTF-8. Memory will be
- * allocated, thus the caller has to free the output.
- *
- */
-char *convert_ucs_to_utf8(char *input) {
-    size_t input_size = 2;
-    /* UTF-8 may consume up to 4 byte */
-    int buffer_size = 8;
-
-    char *buffer = scalloc(buffer_size);
-    size_t output_size = buffer_size;
-    /* We need to use an additional pointer, because iconv() modifies it */
-    char *output = buffer;
-
-    /* We convert the input into UCS-2 big endian */
-    if (conversion_descriptor == 0) {
-        conversion_descriptor = iconv_open("UTF-8", "UCS-2BE");
-        if (conversion_descriptor == 0) {
-            fprintf(stderr, "error opening the conversion context\n");
-            exit(1);
-        }
-    }
-
-    /* Get the conversion descriptor back to original state */
-    iconv(conversion_descriptor, NULL, NULL, NULL, NULL);
-
-    /* Convert our text */
-    int rc = iconv(conversion_descriptor, (void*)&input, &input_size, &output, &output_size);
-    if (rc == (size_t)-1) {
-        perror("Converting to UCS-2 failed");
-        free(buffer);
-        return NULL;
-    }
-
-    return buffer;
-}
-
-/*
- * Converts the given string to UCS-2 big endian for use with
- * xcb_image_text_16(). The amount of real glyphs is stored in real_strlen,
- * a buffer containing the UCS-2 encoded string (16 bit per glyph) is
- * returned. It has to be freed when done.
- *
- */
-char *convert_utf8_to_ucs2(char *input, int *real_strlen) {
-    size_t input_size = strlen(input) + 1;
-    /* UCS-2 consumes exactly two bytes for each glyph */
-    int buffer_size = input_size * 2;
-
-    char *buffer = smalloc(buffer_size);
-    size_t output_size = buffer_size;
-    /* We need to use an additional pointer, because iconv() modifies it */
-    char *output = buffer;
-
-    /* We convert the input into UCS-2 big endian */
-    if (conversion_descriptor2 == 0) {
-        conversion_descriptor2 = iconv_open("UCS-2BE", "UTF-8");
-        if (conversion_descriptor2 == 0) {
-            fprintf(stderr, "error opening the conversion context\n");
-            exit(1);
-        }
-    }
-
-    /* Get the conversion descriptor back to original state */
-    iconv(conversion_descriptor2, NULL, NULL, NULL, NULL);
-
-    /* Convert our text */
-    int rc = iconv(conversion_descriptor2, (void*)&input, &input_size, &output, &output_size);
-    if (rc == (size_t)-1) {
-        perror("Converting to UCS-2 failed");
-        free(buffer);
-        if (real_strlen != NULL)
-            *real_strlen = 0;
-        return NULL;
-    }
-
-    if (real_strlen != NULL)
-        *real_strlen = ((buffer_size - output_size) / 2) - 1;
-
-    return buffer;
-}
index 71fba764540f41ab5c4ff8e2c1e6e50a48373ba0..c87ec3e3d43f64c9a098c5f48a66628b5232e02b 100644 (file)
@@ -179,4 +179,20 @@ uint32_t get_mod_mask_for(uint32_t keysym,
  */
 i3Font load_font(const char *pattern, bool fallback);
 
+/**
+ * Converts the given string to UTF-8 from UCS-2 big endian. The return value
+ * must be freed after use.
+ *
+ */
+char *convert_ucs2_to_utf8(xcb_char2b_t *text, size_t num_glyphs);
+
+/**
+ * Converts the given string to UCS-2 big endian for use with
+ * xcb_image_text_16(). The amount of real glyphs is stored in real_strlen,
+ * a buffer containing the UCS-2 encoded string (16 bit per glyph) is
+ * returned. It has to be freed when done.
+ *
+ */
+xcb_char2b_t *convert_utf8_to_ucs2(char *input, int *real_strlen);
+
 #endif
index 4a5920d2fbfa692627f17a09bc34a3fe5e8d1b97..cd88863c282a90b976bd9ba02fb6b4c3c58ef3ca 100644 (file)
@@ -91,15 +91,6 @@ void exec_i3_utility(char *name, char *argv[]);
 void check_error(xcb_connection_t *conn, xcb_void_cookie_t cookie,
                  char *err_message);
 
-/**
- * Converts the given string to UCS-2 big endian for use with
- * xcb_image_text_16(). The amount of real glyphs is stored in real_strlen, a
- * buffer containing the UCS-2 encoded string (16 bit per glyph) is
- * returned. It has to be freed when done.
- *
- */
-char *convert_utf8_to_ucs2(char *input, int *real_strlen);
-
 /**
  * This function resolves ~ in pathnames.
  * It may resolve wildcards in the first part of the path, but if no match
index 01e2b66728ec28b022e6eaa7b5308b78b9dd2f5e..a1bd22fae27cfff11bbac408ce77c62ceaa17024 100644 (file)
@@ -99,7 +99,7 @@ void xcb_raise_window(xcb_connection_t *conn, xcb_window_t window);
  * real length (amount of glyphs) using the given font.
  *
  */
-int predict_text_width(char *text, int length);
+int predict_text_width(const xcb_char2b_t *text, int length);
 
 /**
  * Configures the given window to have the size/position specified by given rect
diff --git a/libi3/ucs2_conversion.c b/libi3/ucs2_conversion.c
new file mode 100644 (file)
index 0000000..99beb36
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * vim:ts=4:sw=4:expandtab
+ *
+ * i3 - an improved dynamic tiling window manager
+ * © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE)
+ *
+ */
+#include <err.h>
+#include <errno.h>
+#include <iconv.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libi3.h"
+
+static iconv_t utf8_conversion_descriptor = (iconv_t)-1;
+static iconv_t ucs2_conversion_descriptor = (iconv_t)-1;
+
+/*
+ * Converts the given string to UTF-8 from UCS-2 big endian. The return value
+ * must be freed after use.
+ *
+ */
+char *convert_ucs2_to_utf8(xcb_char2b_t *text, size_t num_glyphs) {
+    /* Allocate the output buffer (UTF-8 is at most 4 bytes per glyph) */
+    size_t buffer_size = num_glyphs * 4 * sizeof(char) + 1;
+    char *buffer = scalloc(buffer_size * sizeof(char));
+
+    /* We need to use an additional pointer, because iconv() modifies it */
+    char *output = buffer;
+    size_t output_size = buffer_size - 1;
+
+    if (utf8_conversion_descriptor == (iconv_t)-1) {
+        /* Get a new conversion descriptor */
+        utf8_conversion_descriptor = iconv_open("UTF-8", "UCS-2BE");
+        if (utf8_conversion_descriptor == (iconv_t)-1)
+            err(EXIT_FAILURE, "Error opening the conversion context");
+    }
+    else {
+        /* Reset the existing conversion descriptor */
+        iconv(utf8_conversion_descriptor, NULL, NULL, NULL, NULL);
+    }
+
+    /* Do the conversion */
+    size_t input_len = num_glyphs * sizeof(xcb_char2b_t);
+    size_t rc = iconv(utf8_conversion_descriptor, (char**)&text,
+            &input_len, &output, &output_size);
+    if (rc == (size_t)-1) {
+        perror("Converting to UTF-8 failed");
+        free(buffer);
+        return NULL;
+    }
+
+    return buffer;
+}
+
+/*
+ * Converts the given string to UCS-2 big endian for use with
+ * xcb_image_text_16(). The amount of real glyphs is stored in real_strlen,
+ * a buffer containing the UCS-2 encoded string (16 bit per glyph) is
+ * returned. It has to be freed when done.
+ *
+ */
+xcb_char2b_t *convert_utf8_to_ucs2(char *input, int *real_strlen) {
+    /* Calculate the input buffer size (UTF-8 is strlen-safe) */
+    size_t input_size = strlen(input);
+
+    /* Calculate the output buffer size and allocate the buffer */
+    size_t buffer_size = input_size * sizeof(xcb_char2b_t);
+    xcb_char2b_t *buffer = smalloc(buffer_size);
+
+    /* We need to use an additional pointer, because iconv() modifies it */
+    size_t output_size = buffer_size;
+    xcb_char2b_t *output = buffer;
+
+    if (ucs2_conversion_descriptor == (iconv_t)-1) {
+        /* Get a new conversion descriptor */
+        ucs2_conversion_descriptor = iconv_open("UCS-2BE", "UTF-8");
+        if (ucs2_conversion_descriptor == (iconv_t)-1)
+            err(EXIT_FAILURE, "Error opening the conversion context");
+    }
+    else {
+        /* Reset the existing conversion descriptor */
+        iconv(ucs2_conversion_descriptor, NULL, NULL, NULL, NULL);
+    }
+
+    /* Do the conversion */
+    size_t rc = iconv(ucs2_conversion_descriptor, (char**)&input,
+            &input_size, (char**)&output, &output_size);
+    if (rc == (size_t)-1) {
+        perror("Converting to UCS-2 failed");
+        free(buffer);
+        if (real_strlen != NULL)
+            *real_strlen = 0;
+        return NULL;
+    }
+
+    /* Return the resulting string's length */
+    if (real_strlen != NULL)
+        *real_strlen = (buffer_size - output_size) / sizeof(xcb_char2b_t);
+
+    return buffer;
+}
index a029422bf778645f1396773b49122ad585f132ad..ef8a514b2bdf2e1e2c6f45efdd0b6bde7e71affe 100644 (file)
@@ -51,7 +51,7 @@ static int sig_draw_window(xcb_window_t win, int width, int height, int font_hei
 
     for (int i = 0; i < sizeof(crash_text) / sizeof(char*); i++) {
         int text_len = strlen(crash_text[i]);
-        char *full_text = convert_utf8_to_ucs2(crash_text[i], &text_len);
+        xcb_char2b_t *full_text = convert_utf8_to_ucs2(crash_text[i], &text_len);
         xcb_image_text_16(conn, text_len, pixmap, pixmap_gc, 8 /* X */,
                           3 + (i + 1) * font_height /* Y = baseline of font */,
                           (xcb_char2b_t*)full_text);
@@ -151,7 +151,7 @@ void handle_signal(int sig, siginfo_t *info, void *data) {
 
     /* calculate width for longest text */
     int text_len = strlen(crash_text[crash_text_longest]);
-    char *longest_text = convert_utf8_to_ucs2(crash_text[crash_text_longest], &text_len);
+    xcb_char2b_t *longest_text = convert_utf8_to_ucs2(crash_text[crash_text_longest], &text_len);
     int font_width = predict_text_width(longest_text, text_len);
     int width = font_width + 20;
 
index 72146bff7aa7c1769a1d1d341255a738f1dfc62f..57bfa89bb77051a53a5964ee4c3f7520079391ff 100644 (file)
@@ -12,7 +12,6 @@
 
 #include <sys/wait.h>
 #include <stdarg.h>
-#include <iconv.h>
 #if defined(__OpenBSD__)
 #include <sys/cdefs.h>
 #endif
@@ -24,8 +23,6 @@
 #define SN_API_NOT_YET_FROZEN 1
 #include <libsn/sn-launcher.h>
 
-static iconv_t conversion_descriptor = 0;
-
 int min(int a, int b) {
     return (a < b ? a : b);
 }
@@ -120,51 +117,6 @@ void check_error(xcb_connection_t *conn, xcb_void_cookie_t cookie, char *err_mes
     }
 }
 
-/*
- * Converts the given string to UCS-2 big endian for use with
- * xcb_image_text_16(). The amount of real glyphs is stored in real_strlen,
- * a buffer containing the UCS-2 encoded string (16 bit per glyph) is
- * returned. It has to be freed when done.
- *
- */
-char *convert_utf8_to_ucs2(char *input, int *real_strlen) {
-    size_t input_size = strlen(input) + 1;
-    /* UCS-2 consumes exactly two bytes for each glyph */
-    int buffer_size = input_size * 2;
-
-    char *buffer = smalloc(buffer_size);
-    size_t output_size = buffer_size;
-    /* We need to use an additional pointer, because iconv() modifies it */
-    char *output = buffer;
-
-    /* We convert the input into UCS-2 big endian */
-    if (conversion_descriptor == 0) {
-        conversion_descriptor = iconv_open("UCS-2BE", "UTF-8");
-        if (conversion_descriptor == 0) {
-            fprintf(stderr, "error opening the conversion context\n");
-            exit(1);
-        }
-    }
-
-    /* Get the conversion descriptor back to original state */
-    iconv(conversion_descriptor, NULL, NULL, NULL, NULL);
-
-    /* Convert our text */
-    int rc = iconv(conversion_descriptor, (void*)&input, &input_size, &output, &output_size);
-    if (rc == (size_t)-1) {
-        perror("Converting to UCS-2 failed");
-        FREE(buffer);
-        if (real_strlen != NULL)
-            *real_strlen = 0;
-        return NULL;
-    }
-
-    if (real_strlen != NULL)
-        *real_strlen = ((buffer_size - output_size) / 2) - 1;
-
-    return buffer;
-}
-
 /*
  * This function resolves ~ in pathnames.
  * It may resolve wildcards in the first part of the path, but if no match
index 30957a4b81678e3f629d12acb6303b17812fa8f2..17f2d4a20dc129c64f9b901e62c4bb581acb698d 100644 (file)
@@ -69,7 +69,7 @@ void window_update_name(i3Window *win, xcb_get_property_reply_t *prop, bool befo
     }
     /* Convert it to UCS-2 here for not having to convert it later every time we want to pass it to X */
     int len;
-    char *ucs2_name = convert_utf8_to_ucs2(new_name, &len);
+    xcb_char2b_t *ucs2_name = convert_utf8_to_ucs2(new_name, &len);
     if (ucs2_name == NULL) {
         LOG("Could not convert _NET_WM_NAME to UCS-2, ignoring new hint\n");
         FREE(new_name);
@@ -79,7 +79,7 @@ void window_update_name(i3Window *win, xcb_get_property_reply_t *prop, bool befo
     FREE(win->name_x);
     FREE(win->name_json);
     win->name_json = new_name;
-    win->name_x = ucs2_name;
+    win->name_x = (char*)ucs2_name;
     win->name_len = len;
     win->name_x_changed = true;
     LOG("_NET_WM_NAME changed to \"%s\"\n", win->name_json);
index aa761cac74679873f32f0347d3675cce708de934..739bf9e7b6fc80af897342a645330e7f9b47a73e 100644 (file)
--- a/src/xcb.c
+++ b/src/xcb.c
@@ -135,13 +135,13 @@ void xcb_raise_window(xcb_connection_t *conn, xcb_window_t window) {
  * length (amount of glyphs) using the given font.
  *
  */
-int predict_text_width(char *text, int length) {
+int predict_text_width(const xcb_char2b_t *text, int length) {
     xcb_query_text_extents_cookie_t cookie;
     xcb_query_text_extents_reply_t *reply;
     xcb_generic_error_t *error;
     int width;
 
-    cookie = xcb_query_text_extents(conn, config.font.id, length, (xcb_char2b_t*)text);
+    cookie = xcb_query_text_extents(conn, config.font.id, length, text);
     if ((reply = xcb_query_text_extents_reply(conn, cookie, &error)) == NULL) {
         ELOG("Could not get text extents (X error code %d)\n",
              error->error_code);