Hi On Wed, Aug 14, 2013 at 2:30 AM, Kristian Høgsberg <hoegsb...@gmail.com> wrote: > On Thu, Aug 01, 2013 at 01:49:03PM +0800, Peng Wu wrote: >> By jumping two columns when wide character prints, >> and draw wide cursor under wide character. > > Hi Peng, > > I do want this feature in weston-terminal, but there's still a few > issues to address - see below. > >> --- >> clients/Makefile.am | 2 +- >> clients/terminal.c | 26 ++++++++++++++++++++++++-- >> 2 files changed, 25 insertions(+), 3 deletions(-) >> >> diff --git a/clients/Makefile.am b/clients/Makefile.am >> index 09963cc..e7c0ece 100644 >> --- a/clients/Makefile.am >> +++ b/clients/Makefile.am >> @@ -113,7 +113,7 @@ weston_screenshooter_SOURCES = \ >> weston_screenshooter_LDADD = libtoytoolkit.la >> >> weston_terminal_SOURCES = terminal.c >> -weston_terminal_LDADD = libtoytoolkit.la -lutil >> +weston_terminal_LDADD = libtoytoolkit.la -lutil $(PANGO_LIBS) > > Again, I don't want to link to pango or glib... remember, the only > reason for weston-terminal to exist is that it doesn't have any > dependencies except cairo and the wayland libraries. > >> weston_image_SOURCES = image.c >> weston_image_LDADD = libtoytoolkit.la >> diff --git a/clients/terminal.c b/clients/terminal.c >> index 0d4f726..dc56745 100644 >> --- a/clients/terminal.c >> +++ b/clients/terminal.c >> @@ -33,6 +33,10 @@ >> #include <ctype.h> >> #include <cairo.h> >> #include <sys/epoll.h> >> +#include <glib.h> >> +#define __USE_XOPEN >> +#include <wchar.h> >> +#include <locale.h> >> >> #include <wayland-client.h> >> >> @@ -93,6 +97,11 @@ union utf8_char { >> uint32_t ch; >> }; >> >> +static bool is_wide(union utf8_char utf8){ >> + gunichar unichar = g_utf8_get_char((const char*) utf8.byte); >> + return wcwidth(unichar) > 1; >> +} > > ... but I just committed a patch to make the utf-8 state machine > assemble the unicode value from the utf-8, so you can now use > get_unicode() instead of g_utf8_get_char(). > > Please follow the coding conventions and leave 'static int' on it's > own line and put the opening '{' of the function on it's own line. > >> enum utf8_state { >> utf8state_start, >> utf8state_accept, >> @@ -942,6 +951,7 @@ redraw_handler(struct widget *widget, void *data) >> struct glyph_run run; >> cairo_font_extents_t extents; >> double average_width; >> + double unichar_width; >> >> surface = window_get_surface(terminal->window); >> widget_get_allocation(terminal->widget, &allocation); >> @@ -967,6 +977,7 @@ redraw_handler(struct widget *widget, void *data) >> allocation.y + top_margin); >> /* paint the background */ >> for (row = 0; row < terminal->height; row++) { >> + p_row = terminal_get_row(terminal, row); >> for (col = 0; col < terminal->width; col++) { >> /* get the attributes for this character cell */ >> terminal_decode_attr(terminal, row, col, &attr); >> @@ -974,12 +985,17 @@ redraw_handler(struct widget *widget, void *data) >> if (attr.attr.bg == terminal->color_scheme->border) >> continue; >> >> + if(is_wide(p_row[col])) >> + unichar_width = 2 * average_width; >> + else >> + unichar_width = average_width; >> + >> terminal_set_color(terminal, cr, attr.attr.bg); >> cairo_move_to(cr, col * average_width, >> row * extents.height); >> - cairo_rel_line_to(cr, average_width, 0); >> + cairo_rel_line_to(cr, unichar_width, 0); >> cairo_rel_line_to(cr, 0, extents.height); >> - cairo_rel_line_to(cr, -average_width, 0); >> + cairo_rel_line_to(cr, -unichar_width, 0); >> cairo_close_path(cr); >> cairo_fill(cr); >> } >> @@ -1871,6 +1887,10 @@ handle_char(struct terminal *terminal, union >> utf8_char utf8) >> row[terminal->column] = utf8; >> attr_row[terminal->column++] = terminal->curr_attr; >> >> + /* cursor jump for wide character. */ >> + if (is_wide(utf8)) >> + row[terminal->column++].ch = 0; > > Inserting this 0 here confuses the selection logic which thinks 0 > means "end of line". I think we can use an invalid utf-8 character > instead to indicate that this cell is a wide-char filler. We then > also need to handle that in terminal_send_selection(), where we must > ignore those filler cells when writing the selection to the fd. > > >> if (utf8.ch != terminal->last_char.ch) >> terminal->last_char = utf8; >> } >> @@ -2711,6 +2731,8 @@ int main(int argc, char *argv[]) >> struct terminal *terminal; >> int config_fd; >> >> + setlocale(LC_ALL, ""); > > What is this for?
This is to work around the horrible glibc API. wcwidth() depends on LC_CTYPE, that is, LC_ALL. I avoided forcing any locale and added my own wcwidth() implementation to kmscon: https://github.com/dvdhrm/kmscon/blob/master/external/wcwidth.c Sadly, there is no way to get access to the underlying ucs4_wcwidth() in glibc (who designs such ****?). So either force a locale or feel free to copy wcwidth.c. Regards David _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel