diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2019-01-18 10:24:19 +0100 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2019-01-18 12:27:47 +0100 |
commit | 1eeeaefecb634ea734059685648c058dd600bcae (patch) | |
tree | c03f7dab7aa64179f295ebb83e0d4bdbdb7b5e67 | |
parent | 1e49f9371f39475be7d2a3a9be2994ce5d27870b (diff) | |
download | fbida-1eeeaefecb634ea734059685648c058dd600bcae.tar.gz |
kbd: experimental libinput support
-rw-r--r-- | GNUmakefile | 8 | ||||
-rw-r--r-- | drmtools.c | 5 | ||||
-rw-r--r-- | fbi.c | 8 | ||||
-rw-r--r-- | fbiconfig.c | 10 | ||||
-rw-r--r-- | fbiconfig.h | 4 | ||||
-rw-r--r-- | fbida.spec | 1 | ||||
-rw-r--r-- | fbpdf.c | 4 | ||||
-rw-r--r-- | fbtools.c | 5 | ||||
-rw-r--r-- | gfx.h | 2 | ||||
-rw-r--r-- | kbd.c | 105 | ||||
-rw-r--r-- | kbd.h | 2 | ||||
-rw-r--r-- | kbdtest.c | 2 | ||||
-rw-r--r-- | meson.build | 11 |
13 files changed, 148 insertions, 19 deletions
diff --git a/GNUmakefile b/GNUmakefile index 40e733a..de30fda 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -13,8 +13,9 @@ CFLAGS += -Wno-pointer-sign # hard build deps PKG_CONFIG = pkg-config PKGS_IDA := libexif libpng libtiff-4 pixman-1 -PKGS_FBI := freetype2 fontconfig libdrm libexif libpng libtiff-4 pixman-1 -PKGS_FBPDF := libdrm poppler-glib gbm egl epoxy pixman-1 +PKGS_FBI := freetype2 fontconfig libdrm libexif libpng libtiff-4 pixman-1 libudev libinput +PKGS_FBPDF := libdrm poppler-glib gbm egl epoxy pixman-1 libudev libinput +PKGS_KTEST := libudev libinput HAVE_DEPS := $(shell $(PKG_CONFIG) $(PKGS_FBI) $(PKGS_FBPDF) && echo yes) # map pkg-config names to debian packages using apt-file @@ -201,6 +202,9 @@ fbpdf: $(OBJS_FBPDF) ######################################################################## # rules for kbdtest +kbdtest : CFLAGS += $(shell $(PKG_CONFIG) --cflags $(PKGS_KTEST)) +kbdtest : LDLIBS += $(shell $(PKG_CONFIG) --libs $(PKGS_KTEST)) + kbdtest : kbdtest.o kbd.o ######################################################################## @@ -10,6 +10,7 @@ #include <sys/ioctl.h> #include <sys/mman.h> +#include <sys/stat.h> #include "gfx.h" #include "drmtools.h" @@ -226,6 +227,7 @@ static void drm_flush_display(bool second) gfxstate *drm_init(const char *device, const char *output, const char *mode, bool pageflip) { + struct stat st; gfxstate *gfx; char dev[64]; @@ -266,6 +268,9 @@ gfxstate *drm_init(const char *device, const char *output, gfx->cleanup_display = drm_cleanup_display; gfx->flush_display = drm_flush_display; + fstat(drm_fd, &st); + gfx->devnum = st.st_rdev; + if (pageflip) { if (drm_init_fb(&fb2) == 0) { gfx->mem2 = fb2.mem; @@ -950,7 +950,11 @@ svga_show(struct flist *f, struct flist *prev, case KEY_D: /* need shift state for this one */ return KEY_D | (keymod << 16); + + case KEY_RESERVED: + /* ignored event */ break; + default: return keycode; } @@ -1322,6 +1326,7 @@ int main(int argc, char *argv[]) int once; int i, arg, key; bool framebuffer = false; + bool use_libinput; char *info, *desc, *device, *output, *mode; char linebuffer[128]; struct flist *fprev = NULL; @@ -1376,6 +1381,7 @@ int main(int argc, char *argv[]) timeout = GET_TIMEOUT(); pcd_res = GET_PCD_RES(); interactive = GET_INTERACTIVE(); + use_libinput = GET_LIBINPUT(); fontname = cfg_get_str(O_FONT); filelist = cfg_get_str(O_FILE_LIST); @@ -1442,7 +1448,7 @@ int main(int argc, char *argv[]) shadow_init(gfx); /* svga main loop */ - kbd_init(); + kbd_init(use_libinput, gfx->devnum); desc = NULL; info = NULL; for (;;) { diff --git a/fbiconfig.c b/fbiconfig.c index 44e2321..48c0fca 100644 --- a/fbiconfig.c +++ b/fbiconfig.c @@ -182,6 +182,11 @@ struct cfg_cmdline fbi_cfg[] = { .option = { O_VIDEO_MODE }, .needsarg = 1, .desc = "use video mode <arg> (from /etc/fb.modes)", + },{ + .cmdline = "libinput", + .option = { O_LIBINPUT }, + .yesno = 1, + .desc = "use libinput (experimental)", },{ /* end of list */ @@ -250,6 +255,11 @@ struct cfg_cmdline fbpdf_cfg[] = { .needsarg = 1, .desc = "use video mode <arg> (from /etc/fb.modes)", },{ + .cmdline = "libinput", + .option = { O_LIBINPUT }, + .yesno = 1, + .desc = "use libinput (experimental)", + },{ /* end of list */ } }; diff --git a/fbiconfig.h b/fbiconfig.h index d0b4d32..3fdc2f0 100644 --- a/fbiconfig.h +++ b/fbiconfig.h @@ -30,7 +30,8 @@ #define O_SCROLL O_OPTIONS, "scroll" #define O_TIMEOUT O_OPTIONS, "timeout" #define O_PCD_RES O_OPTIONS, "photocd-res" -#define O_INTERACTIVE O_OPTIONS, "interactive" +#define O_INTERACTIVE O_OPTIONS, "interactive" +#define O_LIBINPUT O_OPTIONS, "libinput" #define O_DEVICE O_OPTIONS, "device" #define O_OUTPUT O_OPTIONS, "output" @@ -65,6 +66,7 @@ #define GET_TIMEOUT() cfg_get_int(O_TIMEOUT, 0) #define GET_PCD_RES() cfg_get_int(O_PCD_RES, 3) #define GET_INTERACTIVE() cfg_get_bool(O_INTERACTIVE, 1) +#define GET_LIBINPUT() cfg_get_bool(O_LIBINPUT, 0) #define GET_OPENGL() cfg_get_bool(O_OPENGL, 0) #define GET_PAGEFLIP() cfg_get_bool(O_PAGEFLIP, 1) @@ -35,6 +35,7 @@ BuildRequires: pkgconfig(gbm) BuildRequires: pkgconfig(egl) BuildRequires: pkgconfig(epoxy) BuildRequires: pkgconfig(cairo) +BuildRequires: pkgconfig(libudev) %description fbida @@ -237,6 +237,7 @@ int main(int argc, char *argv[]) { GError *err = NULL; bool framebuffer = false; + bool use_libinput; bool quit, newpage, pageflip; char cwd[1024]; char uri[1024]; @@ -294,6 +295,7 @@ int main(int argc, char *argv[]) mode = cfg_get_str(O_VIDEO_MODE); fitwidth = GET_FIT_WIDTH(); pageflip = GET_PAGEFLIP(); + use_libinput = GET_LIBINPUT(); if (device) { /* device specified */ @@ -340,7 +342,7 @@ int main(int argc, char *argv[]) gfx->stride); } - kbd_init(); + kbd_init(use_libinput, gfx->devnum); index = 0; newpage = true; @@ -224,6 +224,7 @@ static void fb_cleanup_display(void) gfxstate* fb_init(char *device, char *mode, int vt) { unsigned long page_mask; + struct stat st; gfxstate *gfx; if (vt != 0) @@ -334,6 +335,10 @@ gfxstate* fb_init(char *device, char *mode, int vt) gfx->restore_display = fb_restore_display; gfx->cleanup_display = fb_cleanup_display; + + fstat(fb, &st); + gfx->devnum = st.st_rdev; + return gfx; err: @@ -17,6 +17,8 @@ struct gfxstate { uint32_t rlen, glen, blen, tlen; uint32_t roff, goff, boff, toff; + dev_t devnum; + /* egl */ EGLDisplay dpy; EGLContext ctx; @@ -9,6 +9,9 @@ #include <errno.h> #include <termios.h> +#include <libudev.h> +#include <libinput.h> + #include "kbd.h" /* ---------------------------------------------------------------------- */ @@ -192,34 +195,118 @@ static int file_wait(int fd, int timeout) /* ---------------------------------------------------------------------- */ -void kbd_init(void) +static int devcount; + +static int open_restricted(const char *path, int flags, void *user_data) +{ + int fd; + + fd = open(path, flags); + if (fd < 0) { + fprintf(stderr, "open %s: %s\n", path, strerror(errno)); + return fd; + } + + fprintf(stderr, "using %s\n", path); + ioctl(fd, EVIOCGRAB, 1); + devcount++; + return fd; +} + +static void close_restricted(int fd, void *user_data) +{ + ioctl(fd, EVIOCGRAB, 0); + close(fd); +} + +static const struct libinput_interface interface = { + .open_restricted = open_restricted, + .close_restricted = close_restricted, +}; + +static struct libinput *ctx; + +void kbd_init(int use_libinput, dev_t gfx) { - tty_raw(); + struct udev *udev; + struct udev_device *ugfx; + const char *seat = NULL; + + if (use_libinput) { + udev = udev_new(); + ugfx = udev_device_new_from_devnum(udev, 'c', gfx); + if (ugfx) + seat = udev_device_get_property_value(ugfx, "ID_SEAT"); + if (!seat) + seat = "seat0"; + ctx = libinput_udev_create_context(&interface, NULL, udev); + libinput_udev_assign_seat(ctx, seat); + if (devcount == 0) { + fprintf(stderr, "WARNING: no input devices available\n"); + } + fprintf(stderr, "kbd: using libinput (%d devices, %s)\n", + devcount, seat); + } else { + fprintf(stderr, "kbd: using stdin from terminal\n"); + tty_raw(); + } } void kbd_fini(void) { - tty_restore(); + if (ctx) { + libinput_unref(ctx); + } else { + tty_restore(); + } } int kbd_wait(int timeout) { - return file_wait(STDIN_FILENO, timeout); + if (ctx) { + return file_wait(libinput_get_fd(ctx), timeout); + } else { + return file_wait(STDIN_FILENO, timeout); + } } int kbd_read(char *buf, uint32_t len, uint32_t *keycode, uint32_t *modifier) { + struct libinput_event *evt; + struct libinput_event_keyboard *kbd; int rc; memset(buf, 0, len); *keycode = KEY_RESERVED; *modifier = 0; - rc = read(STDIN_FILENO, buf, len-1); - if (rc < 1) - return -1; + if (ctx) { + rc = libinput_dispatch(ctx); + if (rc < 0) + return -1; + while ((evt = libinput_get_event(ctx)) != NULL) { + switch (libinput_event_get_type(evt)) { + case LIBINPUT_EVENT_KEYBOARD_KEY: + kbd = libinput_event_get_keyboard_event(evt); + if (libinput_event_keyboard_get_key_state(kbd)) + *keycode = libinput_event_keyboard_get_key(kbd); + /* TODO: track modifier state */ + /* TODO: fill buf with typed chars */ + break; + default: + /* ignore event */ + break; + } + libinput_event_destroy(evt); + } + return 0; + } else { + rc = read(STDIN_FILENO, buf, len-1); + if (rc < 1) + return -1; - *keycode = tty_parse(buf, modifier); - return rc; + *keycode = tty_parse(buf, modifier); + return rc; + } } @@ -3,7 +3,7 @@ #define KEY_MOD_SHIFT (1 << 0) #define KEY_MOD_CTRL (1 << 1) -void kbd_init(void); +void kbd_init(int use_libinput, dev_t gfx); int kbd_wait(int timeout); int kbd_read(char *buf, uint32_t len, uint32_t *keycode, uint32_t *modifier); @@ -23,7 +23,7 @@ int main(int argc, char *argv[]) char key[32]; int rc,i; - kbd_init(); + kbd_init(0, 0); for (;;) { kbd_wait(10); diff --git a/meson.build b/meson.build index 3639b97..cbed982 100644 --- a/meson.build +++ b/meson.build @@ -24,6 +24,8 @@ exif_dep = dependency('libexif') png_dep = dependency('libpng') tiff_dep = dependency('libtiff-4') webp_dep = dependency('libwebp', required : false) +udev_dep = dependency('libudev') +input_dep = dependency('libinput') # other library deps cc = meson.get_compiler('c') @@ -84,7 +86,7 @@ fbi_srcs = [ 'fbi.c', 'fb-gui.c', 'desktop.c', fbi_deps = [ freetype_dep, fontconf_dep, drm_dep, pixman_dep, exif_dep, image_deps, - math_dep ] + math_dep, udev_dep, input_dep ] executable('fbi', sources : fbi_srcs, @@ -115,7 +117,8 @@ executable('thumbnail.cgi', fbpdf_srcs = [ 'fbpdf.c', 'parseconfig.c', 'fbiconfig.c', 'vt.c', 'kbd.c', 'fbtools.c', 'drmtools.c', 'drmtools-egl.c' ] fbpdf_deps = [ drm_dep, gbm_dep, epoxy_dep, - pixman_dep, poppler_dep, cairo_dep ] + pixman_dep, poppler_dep, cairo_dep, + udev_dep, input_dep ] executable('fbpdf', sources : fbpdf_srcs, @@ -123,7 +126,9 @@ executable('fbpdf', install : true) # build kbdtest -executable('kbdtest', [ 'kbdtest.c', 'kbd.c' ]) +executable('kbdtest', + sources : [ 'kbdtest.c', 'kbd.c' ], + dependencies : [ udev_dep, input_dep ] ) # build ida mkfallback = find_program('scripts/fallback.pl') |