[cwm patch 5/6] Multibyte characters input for menus

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[cwm patch 5/6] Multibyte characters input for menus

Alexander Polakov-2
diff --git a/calmwm.c b/calmwm.c
index 7e0df51..2ebd685 100644
--- a/calmwm.c
+++ b/calmwm.c
@@ -25,6 +25,7 @@
 #include <err.h>
 #include <errno.h>
 #include <getopt.h>
+#include <locale.h>
 #include <signal.h>
 #include <stdlib.h>
 #include <string.h>
@@ -62,6 +63,9 @@ main(int argc, char **argv)
  char *display_name = NULL;
  int ch;
 
+ setlocale(LC_CTYPE, "");
+ mbtowc(NULL, NULL, MB_CUR_MAX);
+
  while ((ch = getopt(argc, argv, "c:d:")) != -1) {
  switch (ch) {
  case 'c':
diff --git a/menu.c b/menu.c
index c40b8ba..6b77f65 100644
--- a/menu.c
+++ b/menu.c
@@ -70,7 +70,7 @@ static void menu_draw(struct screen_ctx *, struct menu_ctx *,
      struct menu_q *, struct menu_q *);
 static int menu_calc_entry(struct screen_ctx *, struct menu_ctx *,
      int, int);
-static int menu_keycode(KeyCode, u_int, enum ctltype *,
+static int menu_keycode(XKeyEvent *, enum ctltype *,
                              char *);
 
 void
@@ -239,16 +239,22 @@ menu_handle_key(XEvent *e, struct menu_ctx *mc, struct menu_q *menuq,
 {
  struct menu *mi;
  enum ctltype ctl;
- char chr, *fcp, *sp;
+ char chr[32], *fcp, *sp;
  size_t len;
+ int clen, i;
+ wchar_t wc;
 
- if (menu_keycode(e->xkey.keycode, e->xkey.state, &ctl, &chr) < 0)
+ if (menu_keycode(&e->xkey, &ctl, chr) < 0)
  return (NULL);
 
  switch (ctl) {
  case CTL_ERASEONE:
  if ((len = strlen(mc->searchstr)) > 0) {
- mc->searchstr[len - 1] = '\0';
+ clen = 1;
+ while (mbtowc(&wc, &mc->searchstr[len-clen], MB_CUR_MAX) == -1)
+ clen++;
+ for (i = 1; i <= clen; i++)
+ mc->searchstr[len - i] = '\0';
  mc->changed = 1;
  }
  break;
@@ -332,13 +338,9 @@ filecomplete:
  break;
  }
 
- if (chr != '\0') {
- char str[2];
-
- str[0] = chr;
- str[1] = '\0';
+ if (chr[0] != '\0') {
  mc->changed = 1;
- (void)strlcat(mc->searchstr, str, sizeof(mc->searchstr));
+ (void)strlcat(mc->searchstr, chr, sizeof(mc->searchstr));
  }
 
  mc->noresult = 0;
@@ -524,15 +526,16 @@ menu_calc_entry(struct screen_ctx *sc, struct menu_ctx *mc, int x, int y)
 }
 
 static int
-menu_keycode(KeyCode kc, u_int state, enum ctltype *ctl, char *chr)
+menu_keycode(XKeyEvent *ev, enum ctltype *ctl, char *chr)
 {
- int ks;
+ KeySym ks;
+ u_int state = ev->state;
 
  *ctl = CTL_NONE;
- *chr = '\0';
-
- ks = XKeycodeToKeysym(X_Dpy, kc, (state & ShiftMask) ? 1 : 0);
+ chr[0] = '\0';
 
+ ks = XKeycodeToKeysym(X_Dpy, ev->keycode, (state & ShiftMask) ? 1 : 0);
+
  /* Look for control characters. */
  switch (ks) {
  case XK_BackSpace:
@@ -600,14 +603,8 @@ menu_keycode(KeyCode kc, u_int state, enum ctltype *ctl, char *chr)
  if (*ctl != CTL_NONE)
  return (0);
 
- /*
- * For regular characters, only (part of, actually) Latin 1
- * for now.
- */
- if (ks < 0x20 || ks > 0x07e)
+ if (XLookupString(ev, chr, 32, &ks, NULL) < 0)
  return (-1);
 
- *chr = (char)ks;
-
  return (0);
 }
--
1.7.6