dmenu-bidi-20210723-b34d318.diff (3015B)
1 From b34d318bfed8557f2a1e53fc523b8ecff7c79374 Mon Sep 17 00:00:00 2001 2 From: Eyal Seelig <eyal.seelig@gmail.com> 3 Date: Fri, 23 Jul 2021 18:31:11 +0300 4 Subject: [PATCH] Added support for RTL languages, such as Hebrew, Arabic, and 5 Farsi, using the FriBiDi library 6 7 --- 8 config.mk | 8 ++++++-- 9 dmenu.c | 29 +++++++++++++++++++++++++++-- 10 2 files changed, 33 insertions(+), 4 deletions(-) 11 12 diff --git a/config.mk b/config.mk 13 index 05d5a3e..eefd0ae 100644 14 --- a/config.mk 15 +++ b/config.mk 16 @@ -8,6 +8,8 @@ MANPREFIX = $(PREFIX)/share/man 17 X11INC = /usr/X11R6/include 18 X11LIB = /usr/X11R6/lib 19 20 +BDINC = /usr/include/fribidi 21 + 22 # Xinerama, comment if you don't want it 23 XINERAMALIBS = -lXinerama 24 XINERAMAFLAGS = -DXINERAMA 25 @@ -18,9 +20,11 @@ FREETYPEINC = /usr/include/freetype2 26 # OpenBSD (uncomment) 27 #FREETYPEINC = $(X11INC)/freetype2 28 29 +BDLIBS = -lfribidi 30 + 31 # includes and libs 32 -INCS = -I$(X11INC) -I$(FREETYPEINC) 33 -LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) 34 +INCS = -I$(X11INC) -I$(FREETYPEINC) -I$(BDINC) 35 +LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) $(BDLIBS) 36 37 # flags 38 CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS) 39 diff --git a/dmenu.c b/dmenu.c 40 index 65f25ce..389916b 100644 41 --- a/dmenu.c 42 +++ b/dmenu.c 43 @@ -16,6 +16,8 @@ 44 #endif 45 #include <X11/Xft/Xft.h> 46 47 +#include <fribidi.h> 48 + 49 #include "drw.h" 50 #include "util.h" 51 52 @@ -35,6 +37,7 @@ struct item { 53 }; 54 55 static char text[BUFSIZ] = ""; 56 +static char fribidi_text[BUFSIZ] = ""; 57 static char *embed; 58 static int bh, mw, mh; 59 static int inputw = 0, promptw; 60 @@ -113,6 +116,26 @@ cistrstr(const char *s, const char *sub) 61 return NULL; 62 } 63 64 +static void 65 +apply_fribidi(char *str) 66 +{ 67 + FriBidiStrIndex len = strlen(str); 68 + FriBidiChar logical[BUFSIZ]; 69 + FriBidiChar visual[BUFSIZ]; 70 + FriBidiParType base = FRIBIDI_PAR_ON; 71 + FriBidiCharSet charset; 72 + fribidi_boolean result; 73 + 74 + fribidi_text[0] = 0; 75 + if (len>0) 76 + { 77 + charset = fribidi_parse_charset("UTF-8"); 78 + len = fribidi_charset_to_unicode(charset, str, len, logical); 79 + result = fribidi_log2vis(logical, len, &base, visual, NULL, NULL, NULL); 80 + len = fribidi_unicode_to_charset(charset, visual, len, fribidi_text); 81 + } 82 +} 83 + 84 static int 85 drawitem(struct item *item, int x, int y, int w) 86 { 87 @@ -123,7 +146,8 @@ drawitem(struct item *item, int x, int y, int w) 88 else 89 drw_setscheme(drw, scheme[SchemeNorm]); 90 91 - return drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0); 92 + apply_fribidi(item->text); 93 + return drw_text(drw, x, y, w, bh, lrpad / 2, fribidi_text, 0); 94 } 95 96 static void 97 @@ -143,7 +167,8 @@ drawmenu(void) 98 /* draw input field */ 99 w = (lines > 0 || !matches) ? mw - x : inputw; 100 drw_setscheme(drw, scheme[SchemeNorm]); 101 - drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0); 102 + apply_fribidi(text); 103 + drw_text(drw, x, 0, w, bh, lrpad / 2, fribidi_text, 0); 104 105 curpos = TEXTW(text) - TEXTW(&text[cursor]); 106 if ((curpos += lrpad / 2 - 1) < w) { 107 -- 108 2.32.0 109