diff --git a/examples/show_lines.sh b/examples/show_lines.sh index 83c82c8..aa52d8a 100755 --- a/examples/show_lines.sh +++ b/examples/show_lines.sh @@ -15,6 +15,7 @@ while printf ''; do {"text":"json object"}, {"text":"json with urgent flag", "urgent":true}, {"text":"json with highlight flag", "highlight": true}, + {"text":"multi-byte unicode: •"}, {"text":"json with markup flag", "markup": true}, {"text":"json toggling markup flag", "markup": $toggleMarkup}, {"text":"json without markup flag", "markup": false}, @@ -29,4 +30,4 @@ EOF sleep 1; if [ "$toggleMarkup" = "true" ]; then toggleMarkup="false"; else toggleMarkup="true"; fi -done | rofi -modi blocks -show blocks "$@" \ No newline at end of file +done | rofi -modi blocks -show blocks "$@" diff --git a/src/blocks.c b/src/blocks.c index f23e5d6..f5821d2 100644 --- a/src/blocks.c +++ b/src/blocks.c @@ -146,6 +146,45 @@ typedef struct utils ***************/ +void json_escape(char *in, char *out) { + while (*in) { + switch (*in) { + case '\\': + *(out++) = '\\'; + *(out++) = *in; + break; + case '"': + *(out++) = '\\'; + *(out++) = '"'; + break; + case '\t': + *(out++) = '\\'; + *(out++) = 't'; + break; + case '\r': + *(out++) = '\\'; + *(out++) = 'r'; + break; + case '\f': + *(out++) = '\\'; + *(out++) = 'f'; + break; + case '\b': + *(out++) = '\\'; + *(out++) = 'b'; + break; + case '\n': + *(out++) = '\\'; + *(out++) = 'n'; + break; + default: + *(out++) = *in; + break; + } + in++; + } +} + // Result is an allocated a new string char *str_replace(const char *orig, const char *rep, const char *with) { char *result; // the return string @@ -199,7 +238,12 @@ char *str_replace_in(char **orig, const char *rep, const char *with) { } char *str_replace_in_escaped(char **orig, const char *rep, const char *with) { - const gchar * escaped_with = g_strescape(with, NULL); + int len = strlen(with); + + gchar * escaped_with = NULL; + escaped_with = (char*)calloc(len*2, sizeof(gchar)); + + json_escape(with, escaped_with); char * result = str_replace_in(orig, rep, escaped_with); g_free((char *) escaped_with); return result; @@ -460,12 +504,14 @@ static gboolean on_new_input ( GIOChannel *source, GIOCondition condition, gpoin gboolean newline = FALSE; GError * error = NULL; - gchar unichar; - gsize bytes_read; + gunichar unichar; + GIOStatus status; + + status = g_io_channel_read_unichar(source, &unichar, &error); - g_io_channel_read_chars(source, &unichar, 1, &bytes_read, &error); - while(bytes_read > 0) { - g_string_append_c(buffer, unichar); + //when there is nothing to read, status is G_IO_STATUS_AGAIN + while(status == G_IO_STATUS_NORMAL) { + g_string_append_unichar(buffer, unichar); if( unichar == '\n' ){ if(buffer->len > 1){ //input is not an empty line g_debug("received new line: %s", buffer->str); @@ -474,7 +520,7 @@ static gboolean on_new_input ( GIOChannel *source, GIOCondition condition, gpoin } g_string_set_size(buffer, 0); } - g_io_channel_read_chars(source, &unichar, 1, &bytes_read, &error); + status = g_io_channel_read_unichar(source, &unichar, &error); } if(newline){