Skip to content

Commit 278802f

Browse files
committed
Support UTF-8 input in caption mode
So far this only works for X11 input; stdin input is still ASCII only
1 parent d53bd81 commit 278802f

5 files changed

Lines changed: 40 additions & 11 deletions

File tree

src/events.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ static void feh_event_handle_ButtonPress(XEvent * ev)
322322

323323
} else {
324324
D(("Received other ButtonPress event\n"));
325-
feh_event_handle_generic(winwid, state, NoSymbol, button);
325+
feh_event_handle_generic(winwid, state, NoSymbol, button, NULL, 0);
326326
}
327327
return;
328328
}
@@ -694,7 +694,7 @@ static void feh_event_handle_MotionNotify(XEvent * ev)
694694
thumbnail = feh_thumbnail_get_thumbnail_from_coords(x, y);
695695
feh_thumbnail_select(winwid, thumbnail);
696696
} else {
697-
feh_event_handle_generic(winwid, ev->xmotion.state | Mod3Mask, NoSymbol, 0);
697+
feh_event_handle_generic(winwid, ev->xmotion.state | Mod3Mask, NoSymbol, 0, NULL, 0);
698698
}
699699
}
700700
}

src/feh.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ void setup_stdin(void);
161161
void restore_stdin(void);
162162
void feh_event_handle_keypress(XEvent * ev);
163163
void feh_event_handle_stdin(void);
164-
void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysym, unsigned int button);
164+
void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysym, unsigned int button, char *buf, unsigned int buf_len);
165165
fehkey *feh_str_to_kb(char * action);
166166
void feh_action_run(feh_file * file, char *action, winwidget winwid);
167167
char *format_size(double size);
@@ -211,10 +211,10 @@ extern XineramaScreenInfo *xinerama_screens;
211211
extern int xinerama_screen;
212212
#endif /* HAVE_LIBXINERAMA */
213213

214-
/* Thumbnail sizes */
215214
extern int cmdargc;
216215
extern char **cmdargv;
217216
extern Window root;
217+
extern XIC input_context;
218218
extern XContext xid_context;
219219
extern Screen *scr;
220220
extern unsigned char reset_output;

src/imlib.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
4444
#include <arpa/inet.h>
4545
#include <netdb.h>
4646

47+
#include <locale.h>
48+
4749
#ifdef HAVE_LIBCURL
4850
#include <curl/curl.h>
4951
#endif
@@ -61,6 +63,7 @@ magic_t magic = NULL;
6163
Display *disp = NULL;
6264
Visual *vis = NULL;
6365
Screen *scr = NULL;
66+
XIC input_context;
6467
Colormap cm;
6568
int depth;
6669
Atom wmDeleteWindow;
@@ -128,6 +131,10 @@ void init_imlib_fonts(void)
128131

129132
void init_x_and_imlib(void)
130133
{
134+
setlocale(LC_ALL, "");
135+
if (XSupportsLocale()) {
136+
XSetLocaleModifiers("@im=none");
137+
}
131138
disp = XOpenDisplay(NULL);
132139
if (!disp)
133140
eprintf("Can't open X display. It *is* running, yeah?");
@@ -138,6 +145,9 @@ void init_x_and_imlib(void)
138145
scr = ScreenOfDisplay(disp, DefaultScreen(disp));
139146
xid_context = XUniqueContext();
140147

148+
XIM im = XOpenIM(disp, NULL, NULL, NULL);
149+
input_context = XCreateIC(im, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, NULL);
150+
141151
#ifdef HAVE_LIBXINERAMA
142152
init_xinerama();
143153
#endif /* HAVE_LIBXINERAMA */

src/keyevents.c

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ void feh_event_handle_stdin(void)
360360
keysym = XStringToKeysym(stdin_buf);
361361

362362
if (window_num && keysym)
363-
feh_event_handle_generic(windows[0], is_esc * Mod1Mask, keysym, 0);
363+
feh_event_handle_generic(windows[0], is_esc * Mod1Mask, keysym, 0, NULL, 0);
364364

365365
is_esc = 0;
366366
}
@@ -383,7 +383,13 @@ void feh_event_handle_keypress(XEvent * ev)
383383
}
384384

385385
kev = (XKeyEvent *) ev;
386-
XLookupString(&ev->xkey, (char *) kbuf, sizeof(kbuf), &keysym, NULL);
386+
int kbuf_used = Xutf8LookupString(input_context, kev, (char *) kbuf, sizeof(kbuf), &keysym, NULL);
387+
if (kbuf_used < sizeof(kbuf)) {
388+
kbuf[kbuf_used] = 0;
389+
} else {
390+
kbuf[19] = 0;
391+
}
392+
D(("Xutf8LookupString set kbuf = %s, keysym = %08x\n", kbuf, keysym));
387393
state = kev->state & (ControlMask | ShiftMask | Mod1Mask | Mod4Mask);
388394

389395
if (ignore_space(keysym))
@@ -410,7 +416,12 @@ void feh_event_handle_keypress(XEvent * ev)
410416
if (winwid == NULL)
411417
return;
412418

413-
feh_event_handle_generic(winwid, state, keysym, 0);
419+
if (XFilterEvent(ev, None)) {
420+
D(("Event filtered\n"));
421+
return;
422+
}
423+
424+
feh_event_handle_generic(winwid, state, keysym, 0, kbuf, kbuf_used);
414425
}
415426

416427
fehkey *feh_str_to_kb(char *action)
@@ -423,7 +434,7 @@ fehkey *feh_str_to_kb(char *action)
423434
return NULL;
424435
}
425436

426-
void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysym, unsigned int button) {
437+
void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysym, unsigned int button, char *buf, unsigned int buf_len) {
427438
int curr_screen = 0;
428439

429440
if (winwid->caption_entry && (keysym != NoSymbol)) {
@@ -468,11 +479,14 @@ void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysy
468479
winwidget_render_image_cached(winwid);
469480
break;
470481
default:
471-
if (isascii(keysym)) {
472-
/* append to caption */
482+
/* append to caption */
483+
if ((buf != NULL) && buf_len) {
484+
ESTRAPPEND(FEH_FILE(winwid->file->data)->caption, buf);
485+
} else if (isascii(keysym)) {
486+
// TODO update feh_event_handle_stdin to pass buf as well.
473487
ESTRAPPEND_CHAR(FEH_FILE(winwid->file->data)->caption, keysym);
474-
winwidget_render_image_cached(winwid);
475488
}
489+
winwidget_render_image_cached(winwid);
476490
break;
477491
}
478492
return;

src/winwidget.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,11 @@ void winwidget_show(winwidget winwid)
858858
XMapWindow(disp, winwid->win);
859859
if (opt.full_screen)
860860
XMoveWindow(disp, winwid->win, 0, 0);
861+
862+
XSetICValues(input_context, XNClientWindow, winwid->win, NULL);
863+
//XSelectInput(disp, winwid->win, ButtonPressMask|StructureNotifyMask|KeyPressMask|KeyReleaseMask);
864+
XSetICFocus(input_context);
865+
861866
/* wait for the window to map */
862867
D(("Waiting for window to map\n"));
863868
XMaskEvent(disp, StructureNotifyMask, &ev);

0 commit comments

Comments
 (0)