Example #1
0
int
main(void)
{
    struct xkb_context *context = test_get_context(0);
    struct xkb_keymap *keymap;

    assert(context);

    /* Make sure these are allowed. */
    xkb_context_unref(NULL);
    xkb_keymap_unref(NULL);
    xkb_state_unref(NULL);

    keymap = test_compile_rules(context, "evdev", "pc104", "us,ru", NULL, "grp:menu_toggle");
    assert(keymap);

    test_update_key(keymap);
    test_serialisation(keymap);
    test_repeat(keymap);
    test_consume(keymap);
    test_range(keymap);
    test_get_utf8_utf32(keymap);
    test_ctrl_string_transformation(keymap);

    xkb_keymap_unref(keymap);
    keymap = test_compile_rules(context, "evdev", NULL, "ch", "fr", NULL);
    assert(keymap);

    test_caps_keysym_transformation(keymap);

    xkb_keymap_unref(keymap);
    xkb_context_unref(context);
}
Example #2
0
int uxkb_desc_init(struct uterm_input *input,
		   const char *model,
		   const char *layout,
		   const char *variant,
		   const char *options)
{
	int ret;
	struct xkb_rule_names rmlvo = {
		.rules = "evdev",
		.model = model,
		.layout = layout,
		.variant = variant,
		.options = options,
	};

	input->ctx = xkb_context_new(0);
	if (!input->ctx) {
		log_error("cannot create XKB context");
		return -ENOMEM;
	}

	input->keymap = xkb_keymap_new_from_names(input->ctx, &rmlvo, 0);
	if (!input->keymap) {
		log_warn("failed to create keymap (%s, %s, %s, %s), "
			 "reverting to default system keymap",
			 model, layout, variant, options);

		rmlvo.model = "";
		rmlvo.layout = "";
		rmlvo.variant = "";
		rmlvo.options = "";

		input->keymap = xkb_keymap_new_from_names(input->ctx,
							  &rmlvo, 0);
		if (!input->keymap) {
			log_warn("failed to create XKB keymap");
			ret = -EFAULT;
			goto err_ctx;
		}
	}

	log_debug("new keyboard description (%s, %s, %s, %s)",
		  model, layout, variant, options);
	return 0;

err_ctx:
	xkb_context_unref(input->ctx);
	return ret;
}

void uxkb_desc_destroy(struct uterm_input *input)
{
	xkb_keymap_unref(input->keymap);
	xkb_context_unref(input->ctx);
}
static void
clutter_wayland_handle_keymap (void *data,
                               struct wl_keyboard *keyboard,
                               uint32_t format,
                               int32_t fd,
                               uint32_t size)
{
  ClutterInputDeviceWayland *device = data;
  struct xkb_context *ctx;
  struct xkb_keymap *keymap;
  char *map_str;

  if (device->xkb)
    {
      xkb_state_unref (device->xkb);
      device->xkb = NULL;
    }

  ctx = xkb_context_new (0);
  if (!ctx)
    {
      close (fd);
      return;
    }

  if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1)
    {
      close (fd);
      return;
    }

  map_str = mmap (NULL, size, PROT_READ, MAP_SHARED, fd, 0);
  if (map_str == MAP_FAILED)
    {
      close(fd);
      return;
    }

  keymap = xkb_map_new_from_string (ctx,
                                    map_str,
                                    XKB_KEYMAP_FORMAT_TEXT_V1,
                                    0);
  xkb_context_unref (ctx);
  munmap (map_str, size);
  close (fd);

  if (!keymap)
    {
      g_warning ("failed to compile keymap\n");
      return;
    }

  device->xkb = xkb_state_new(keymap);
  xkb_map_unref (keymap);
  if (!device->xkb)
    {
      g_warning ("failed to create XKB state object\n");
      return;
    }
}
Example #4
0
int
main(int argc, char *argv[])
{
    struct xkb_context *ctx;
    struct xkb_keymap *keymap;
    struct bench_timer timer;
    char *elapsed;
    int i;

    ctx = test_get_context(0);
    assert(ctx);

    xkb_context_set_log_level(ctx, XKB_LOG_LEVEL_CRITICAL);
    xkb_context_set_log_verbosity(ctx, 0);

    bench_timer_reset(&timer);

    bench_timer_start(&timer);
    for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
        keymap = test_compile_rules(ctx, "evdev", "evdev", "us", "", "");
        assert(keymap);
        xkb_keymap_unref(keymap);
    }
    bench_timer_stop(&timer);

    elapsed = bench_timer_get_elapsed_time_str(&timer);
    fprintf(stderr, "compiled %d keymaps in %ss\n",
            BENCHMARK_ITERATIONS, elapsed);
    free(elapsed);

    xkb_context_unref(ctx);
    return 0;
}
static kbdctx *kbdctx_unref(kbdctx *kc) {
        if (!kc)
                return NULL;

        assert_return(kc->ref > 0, NULL);

        if (--kc->ref > 0)
                return NULL;

        free(kc->last_x11_options);
        free(kc->last_x11_variant);
        free(kc->last_x11_layout);
        free(kc->last_x11_model);
        free(kc->locale_x11_options);
        free(kc->locale_x11_variant);
        free(kc->locale_x11_layout);
        free(kc->locale_x11_model);
        free(kc->locale_lang);
        kc->slot_locale_get_all = sd_bus_slot_unref(kc->slot_locale_get_all);
        kc->slot_locale_props_changed = sd_bus_slot_unref(kc->slot_locale_props_changed);
        kc->kbdtbl = kbdtbl_unref(kc->kbdtbl);
        kc->kbdmap = kbdmap_unref(kc->kbdmap);
        xkb_context_unref(kc->xkb_context);
        hashmap_remove_value(kc->context->data_map, KBDCTX_KEY, kc);
        free(kc);

        return NULL;
}
Example #6
0
int
main(void)
{
    struct xkb_context *ctx = test_get_context(0);

    assert(test_file(ctx, "keymaps/basic.xkb"));
    assert(test_file(ctx, "keymaps/comprehensive-plus-geom.xkb"));
    assert(test_file(ctx, "keymaps/no-types.xkb"));
    assert(test_file(ctx, "keymaps/quartz.xkb"));

    assert(!test_file(ctx, "keymaps/divide-by-zero.xkb"));
    assert(!test_file(ctx, "keymaps/bad.xkb"));
    assert(!test_file(ctx, "keymaps/syntax-error.xkb"));
    assert(!test_file(ctx, "keymaps/syntax-error2.xkb"));
    assert(!test_file(ctx, "does not exist"));

    /* Test response to invalid flags and formats. */
    fclose(stdin);
    assert(!xkb_keymap_new_from_file(ctx, NULL, XKB_KEYMAP_FORMAT_TEXT_V1, 0));
    assert(!xkb_keymap_new_from_file(ctx, stdin, 0, 0));
    assert(!xkb_keymap_new_from_file(ctx, stdin, XKB_KEYMAP_USE_ORIGINAL_FORMAT, 0));
    assert(!xkb_keymap_new_from_file(ctx, stdin, 1234, 0));
    assert(!xkb_keymap_new_from_file(ctx, stdin, XKB_KEYMAP_FORMAT_TEXT_V1, -1));
    assert(!xkb_keymap_new_from_file(ctx, stdin, XKB_KEYMAP_FORMAT_TEXT_V1, 1234));

    xkb_context_unref(ctx);

    return 0;
}
void EglFSWaylandInput::releaseKeymap()
{
    if (m_xkbState)
        xkb_state_unref(m_xkbState);
    if (m_xkbKeymap)
        xkb_map_unref(m_xkbKeymap);
    if (m_xkbContext)
        xkb_context_unref(m_xkbContext);
}
Example #8
0
int
main(int argc, char *argv[])
{
    int opt;
    struct xkb_rule_names rmlvo = { NULL };
    struct xkb_context *ctx;
    struct xkb_component_names kccgst;

    while ((opt = getopt(argc, argv, "r:m:l:v:o:h")) != -1) {
        switch (opt) {
        case 'r':
            rmlvo.rules = optarg;
            break;
        case 'm':
            rmlvo.model = optarg;
            break;
        case 'l':
            rmlvo.layout = optarg;
            break;
        case 'v':
            rmlvo.variant = optarg;
            break;
        case 'o':
            rmlvo.options = optarg;
            break;
        case 'h':
        case '?':
            fprintf(stderr, "Usage: %s [-r <rules>] [-m <model>] "
                    "[-l <layout>] [-v <variant>] [-o <options>]\n",
                    argv[0]);
            return 1;
        }
    }

    ctx = test_get_context(0);
    if (!ctx) {
        fprintf(stderr, "Failed to get xkb context\n");
        return 1;
    }

    xkb_context_sanitize_rule_names(ctx, &rmlvo);

    if (!xkb_components_from_rules(ctx, &rmlvo, &kccgst))
        return 1;

    printf("keycodes: %s\n", kccgst.keycodes);
    printf("types:    %s\n", kccgst.types);
    printf("compat:   %s\n", kccgst.compat);
    printf("symbols:  %s\n", kccgst.symbols);

    free(kccgst.keycodes);
    free(kccgst.types);
    free(kccgst.compat);
    free(kccgst.symbols);
    xkb_context_unref(ctx);
    return 0;
}
Example #9
0
/*virtual*/ Display::~Display()
{
	if (xkbContext_)
	{
		xkb_context_unref(xkbContext_);
	}
	wl_registry_destroy(wl_registry_);
	wl_display_disconnect(*this);
}
Example #10
0
QLibInputKeyboard::~QLibInputKeyboard()
{
#ifndef QT_NO_XKBCOMMON_EVDEV
    if (m_state)
        xkb_state_unref(m_state);
    if (m_keymap)
        xkb_keymap_unref(m_keymap);
    if (m_ctx)
        xkb_context_unref(m_ctx);
#endif
}
Example #11
0
/**
 * Create a new context.
 */
XKB_EXPORT struct xkb_context *
xkb_context_new(enum xkb_context_flags flags)
{
    const char *env;
    struct xkb_context *ctx = calloc(1, sizeof(*ctx));

    if (!ctx)
        return NULL;

    ctx->refcnt = 1;
    ctx->log_fn = default_log_fn;
    ctx->log_level = XKB_LOG_LEVEL_ERROR;
    ctx->log_verbosity = 0;

    /* Environment overwrites defaults. */
    env = getenv("XKB_LOG_LEVEL");
    if (env)
        xkb_context_set_log_level(ctx, log_level(env));

    env = getenv("XKB_LOG_VERBOSITY");
    if (env)
        xkb_context_set_log_verbosity(ctx, log_verbosity(env));

    if (!(flags & XKB_CONTEXT_NO_DEFAULT_INCLUDES) &&
        !xkb_context_include_path_append_default(ctx)) {
        log_err(ctx, "failed to add default include path %s\n",
                DFLT_XKB_CONFIG_ROOT);
        xkb_context_unref(ctx);
        return NULL;
    }

    ctx->use_environment_names = !(flags & XKB_CONTEXT_NO_ENVIRONMENT_NAMES);

    ctx->atom_table = atom_table_new();
    if (!ctx->atom_table) {
        xkb_context_unref(ctx);
        return NULL;
    }

    return ctx;
}
QWaylandKeyboardPrivate::~QWaylandKeyboardPrivate()
{
#ifndef QT_NO_WAYLAND_XKB
    if (xkb_context) {
        if (keymap_area)
            munmap(keymap_area, keymap_size);
        close(keymap_fd);
        xkb_context_unref(xkb_context);
        xkb_state_unref(xkb_state);
    }
#endif
}
Example #13
0
void
xrtb_keyboard_fini(struct xcb_rutabaga *xrtb)
{
	assert(xrtb->xkb_ctx);

	xkb_context_unref(xrtb->xkb_ctx);

	if (xrtb->xkb_keymap)
		xkb_keymap_unref(xrtb->xkb_keymap);

	if (xrtb->xkb_state)
		xkb_state_unref(xrtb->xkb_state);
}
Example #14
0
/*
 * Try closing the input device(s)
 */
void fgPlatformCloseInputDevices( void )
{
    if( fgDisplay.pDisplay.touch )
      wl_touch_destroy( fgDisplay.pDisplay.touch );
    if( fgDisplay.pDisplay.pointer )
      wl_pointer_destroy( fgDisplay.pDisplay.pointer );
    if( fgDisplay.pDisplay.keyboard )
      wl_keyboard_destroy( fgDisplay.pDisplay.keyboard );
    if( fgDisplay.pDisplay.xkb_state )
      xkb_state_unref( fgDisplay.pDisplay.xkb_state );
    if( fgDisplay.pDisplay.xkb_context )
      xkb_context_unref( fgDisplay.pDisplay.xkb_context );
}
int
main(void)
{
    struct xkb_context *context = test_get_context(0);

    assert(context);

    assert(xkb_context_num_include_paths(context) == 1);
    assert(!xkb_context_include_path_append(context, "¡NONSENSE!"));
    assert(xkb_context_num_include_paths(context) == 1);

    xkb_context_unref(context);

    return 0;
}
WaylandDisplay::~WaylandDisplay()
{
    if (m_eventSource)
        g_source_unref(m_eventSource);
    m_eventSource = nullptr;

    if (m_interfaces.compositor)
        wl_compositor_destroy(m_interfaces.compositor);
    if (m_interfaces.data_device_manager)
        wl_data_device_manager_destroy(m_interfaces.data_device_manager);
    if (m_interfaces.drm)
        wl_drm_destroy(m_interfaces.drm);
    if (m_interfaces.seat)
        wl_seat_destroy(m_interfaces.seat);
    if (m_interfaces.xdg)
        xdg_shell_destroy(m_interfaces.xdg);
    if (m_interfaces.ivi_application)
        ivi_application_destroy(m_interfaces.ivi_application);
    m_interfaces = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr };

    if (m_registry)
        wl_registry_destroy(m_registry);
    m_registry = nullptr;
    if (m_display)
        wl_display_disconnect(m_display);
    m_display = nullptr;

    if (m_seatData.pointer.object)
        wl_pointer_destroy(m_seatData.pointer.object);
    if (m_seatData.keyboard.object)
        wl_keyboard_destroy(m_seatData.keyboard.object);
    if (m_seatData.touch.object)
        wl_touch_destroy(m_seatData.touch.object);
    if (m_seatData.xkb.context)
        xkb_context_unref(m_seatData.xkb.context);
    if (m_seatData.xkb.keymap)
        xkb_keymap_unref(m_seatData.xkb.keymap);
    if (m_seatData.xkb.state)
        xkb_state_unref(m_seatData.xkb.state);
    if (m_seatData.xkb.composeTable)
        xkb_compose_table_unref(m_seatData.xkb.composeTable);
    if (m_seatData.xkb.composeState)
        xkb_compose_state_unref(m_seatData.xkb.composeState);
    if (m_seatData.repeatData.eventSource)
        g_source_remove(m_seatData.repeatData.eventSource);
    m_seatData = SeatData{ };
}
Example #17
0
static struct xkb_keymap *
meta_backend_x11_get_keymap (MetaBackend *backend)
{
  MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
  MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);

  if (priv->keymap == NULL)
    {
      struct xkb_context *context = xkb_context_new (XKB_CONTEXT_NO_FLAGS);
      priv->keymap = xkb_x11_keymap_new_from_device (context,
                                                     priv->xcb,
                                                     xkb_x11_get_core_keyboard_device_id (priv->xcb),
                                                     XKB_KEYMAP_COMPILE_NO_FLAGS);
      xkb_context_unref (context);
    }

  return priv->keymap;
}
void free_xkb(void)
{
   if (mod_map_idx)
      free(mod_map_idx);
   if (mod_map_bit)
      free(mod_map_bit);
   if (xkb_map)
      xkb_keymap_unref(xkb_map);
   if (xkb_ctx)
      xkb_context_unref(xkb_ctx);
   if (xkb_state)
      xkb_state_unref(xkb_state);

   mod_map_idx = NULL;
   mod_map_bit = NULL;
   xkb_map     = NULL;
   xkb_ctx     = NULL;
   xkb_state   = NULL;
}
Example #19
0
static void udev_input_free(void *data)
{
   unsigned i;
   udev_input_t *udev = (udev_input_t*)data;

   if (!data || !udev)
      return;

   if (udev->joypad)
      udev->joypad->destroy();

   if (udev->epfd >= 0)
      close(udev->epfd);

   for (i = 0; i < udev->num_devices; i++)
   {
      close(udev->devices[i]->fd);
      free(udev->devices[i]);
   }
   free(udev->devices);

   if (udev->monitor)
      udev_monitor_unref(udev->monitor);
   if (udev->udev)
      udev_unref(udev->udev);

#ifdef HAVE_XKBCOMMON
   if (udev->mod_map_idx)
      free(udev->mod_map_idx);
   if (udev->mod_map_bit)
      free(udev->mod_map_bit);
   if (udev->xkb_map)
      xkb_keymap_unref(udev->xkb_map);
   if (udev->xkb_ctx)
      xkb_context_unref(udev->xkb_ctx);
   if (udev->xkb_state)
      xkb_state_unref(udev->xkb_state);
#endif

   free(udev);
}
Example #20
0
XKB_EXPORT void
xkb_keymap_unref(struct xkb_keymap *keymap)
{
    if (!keymap || --keymap->refcnt > 0)
        return;

    if (keymap->keys) {
        struct xkb_key *key;
        xkb_keys_foreach(key, keymap) {
            if (key->groups) {
                for (unsigned i = 0; i < key->num_groups; i++) {
                    if (key->groups[i].levels) {
                        for (unsigned j = 0; j < XkbKeyNumLevels(key, i); j++)
                            if (key->groups[i].levels[j].num_syms > 1)
                                free(key->groups[i].levels[j].u.syms);
                        free(key->groups[i].levels);
                    }
                }
                free(key->groups);
            }
        }
        free(keymap->keys);
    }
    if (keymap->types) {
        for (unsigned i = 0; i < keymap->num_types; i++) {
            free(keymap->types[i].entries);
            free(keymap->types[i].level_names);
        }
        free(keymap->types);
    }
    free(keymap->sym_interprets);
    free(keymap->key_aliases);
    free(keymap->group_names);
    free(keymap->keycodes_section_name);
    free(keymap->symbols_section_name);
    free(keymap->types_section_name);
    free(keymap->compat_section_name);
    xkb_context_unref(keymap->ctx);
    free(keymap);
}
Example #21
0
WaylandInputEvent::~WaylandInputEvent()
{
    if (!m_wlEventSource)
        wl_event_source_remove(m_wlEventSource);

    if (m_xkbInfo.keymap)
        xkb_map_unref(m_xkbInfo.keymap);

    if (m_xkbInfo.keymap_area)
        munmap(m_xkbInfo.keymap_area, m_xkbInfo.keymap_size);

    if (m_xkbInfo.keymap_fd >= 0)
        close(m_xkbInfo.keymap_fd);

    xkb_context_unref(m_xkbContext);

    free((char*)m_xkbNames.rules);
    free((char*)m_xkbNames.model);
    free((char*)m_xkbNames.layout);
    free((char*)m_xkbNames.variant);
    free((char*)m_xkbNames.options);
}
Example #22
0
int
main(void)
{
    struct xkb_context *ctx;
    struct xkb_keymap *keymap;
    struct xkb_state *state;
    struct bench bench;
    char *elapsed;

    ctx = test_get_context(0);
    assert(ctx);

    keymap = test_compile_rules(ctx, "evdev", "pc104", "us,ru,il,de",
                                ",,,neo", "grp:menu_toggle");
    assert(keymap);

    state = xkb_state_new(keymap);
    assert(state);

    xkb_context_set_log_level(ctx, XKB_LOG_LEVEL_CRITICAL);
    xkb_context_set_log_verbosity(ctx, 0);

    srand(time(NULL));

    bench_start(&bench);
    bench_key_proc(state);
    bench_stop(&bench);

    elapsed = bench_elapsed_str(&bench);
    fprintf(stderr, "ran %d iterations in %ss\n",
            BENCHMARK_ITERATIONS, elapsed);
    free(elapsed);

    xkb_state_unref(state);
    xkb_keymap_unref(keymap);
    xkb_context_unref(ctx);

    return 0;
}
Example #23
0
void _glfwPlatformTerminate(void)
{
    _glfwTerminateEGL();
    _glfwTerminateJoysticksLinux();
    _glfwTerminateThreadLocalStoragePOSIX();

    xkb_keymap_unref(_glfw.wl.xkb.keymap);
    xkb_state_unref(_glfw.wl.xkb.state);
    xkb_context_unref(_glfw.wl.xkb.context);

    if (_glfw.wl.cursorTheme)
        wl_cursor_theme_destroy(_glfw.wl.cursorTheme);
    if (_glfw.wl.cursorSurface)
        wl_surface_destroy(_glfw.wl.cursorSurface);
    if (_glfw.wl.compositor)
        wl_compositor_destroy(_glfw.wl.compositor);
    if (_glfw.wl.shm)
        wl_shm_destroy(_glfw.wl.shm);
    if (_glfw.wl.shell)
        wl_shell_destroy(_glfw.wl.shell);
    if (_glfw.wl.pointer)
        wl_pointer_destroy(_glfw.wl.pointer);
    if (_glfw.wl.keyboard)
        wl_keyboard_destroy(_glfw.wl.keyboard);
    if (_glfw.wl.seat)
        wl_seat_destroy(_glfw.wl.seat);
    if (_glfw.wl.relativePointerManager)
        zwp_relative_pointer_manager_v1_destroy(_glfw.wl.relativePointerManager);
    if (_glfw.wl.pointerConstraints)
        zwp_pointer_constraints_v1_destroy(_glfw.wl.pointerConstraints);
    if (_glfw.wl.registry)
        wl_registry_destroy(_glfw.wl.registry);
    if (_glfw.wl.display)
    {
        wl_display_flush(_glfw.wl.display);
        wl_display_disconnect(_glfw.wl.display);
    }
}
Example #24
0
int main()
{
    xkb_rule_names names;
    names.rules = strdup("evdev");
    names.model = strdup("pc105");
    names.layout = strdup("us");
    names.variant = strdup("");
    names.options = strdup("");

    xkb_context *context = xkb_context_new(xkb_context_flags(0));
    if (context) {
        xkb_keymap * keymap = xkb_map_new_from_names(context, &names, xkb_map_compile_flags(0));
        if (keymap) {
            xkb_state *state = xkb_state_new(keymap);
            if (state)
                xkb_state_unref(state);
            xkb_map_unref(keymap);
        }
        xkb_context_unref(context);
    }

    return 0;
}
Example #25
0
int
main(int argc, char **argv)
{
    struct xkb_context *ctx;
    struct xkb_keymap *keymap;
    struct xkb_rule_names names = {
        .rules = NULL,
        .model = NULL,
        .layout = NULL,
        .variant = NULL,
        .options = NULL,
    };
    int rc;

    if (argc <= 1) {
        usage();
        return 1;
    }

    if (!parse_options(argc, argv, &names))
        return 1;

    ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
    assert(ctx);

    keymap = xkb_keymap_new_from_names(ctx, &names, XKB_KEYMAP_COMPILE_NO_FLAGS);
    rc = (keymap == NULL);

    if (rc == 0 && print)
        printf("%s\n", xkb_keymap_get_as_string(keymap,
                                                XKB_KEYMAP_FORMAT_TEXT_V1));

    xkb_keymap_unref(keymap);
    xkb_context_unref(ctx);

    return rc;
}
int
main(int argc, char *argv[])
{
    struct xkb_context *ctx = test_get_context(0);
    struct xkb_keymap *keymap;
    char *original, *dump;

    assert(ctx);

    /* Load in a prebuilt keymap, make sure we can compile it from a string,
     * then compare it to make sure we get the same result when dumping it
     * to a string. */
    original = test_read_file(DATA_PATH);
    assert(original);

    keymap = test_compile_string(ctx, original);
    assert(keymap);

    dump = xkb_keymap_get_as_string(keymap, XKB_KEYMAP_USE_ORIGINAL_FORMAT);
    assert(dump);

    if (!streq(original, dump)) {
        fprintf(stderr,
                "round-trip test failed: dumped map differs from original\n");
        fprintf(stderr, "path to original file: %s\n",
                test_get_path(DATA_PATH));
        fprintf(stderr, "length: dumped %lu, original %lu\n",
                (unsigned long) strlen(dump),
                (unsigned long) strlen(original));
        fprintf(stderr, "dumped map:\n");
        fprintf(stderr, "%s\n", dump);
        fflush(stderr);
        assert(0);
    }

    free(original);
    free(dump);
    xkb_keymap_unref(keymap);

    /* Make sure we can't (falsely claim to) compile an empty string. */
    keymap = test_compile_string(ctx, "");
    assert(!keymap);

    /* Make sure we can recompile our output for a normal keymap from rules. */
    keymap = test_compile_rules(ctx, NULL, NULL,
                                "ru,ca,de,us", ",multix,neo,intl", NULL);
    assert(keymap);
    dump = xkb_keymap_get_as_string(keymap, XKB_KEYMAP_USE_ORIGINAL_FORMAT);
    assert(dump);
    xkb_keymap_unref(keymap);
    keymap = test_compile_string(ctx, dump);
    assert(keymap);

    /* Test response to invalid formats and flags. */
    assert(!xkb_keymap_new_from_string(ctx, dump, 0, 0));
    assert(!xkb_keymap_new_from_string(ctx, dump, -1, 0));
    assert(!xkb_keymap_new_from_string(ctx, dump, XKB_KEYMAP_FORMAT_TEXT_V1+1, 0));
    assert(!xkb_keymap_new_from_string(ctx, dump, XKB_KEYMAP_FORMAT_TEXT_V1, -1));
    assert(!xkb_keymap_new_from_string(ctx, dump, XKB_KEYMAP_FORMAT_TEXT_V1, 1414));
    assert(!xkb_keymap_get_as_string(keymap, 0));
    assert(!xkb_keymap_get_as_string(keymap, 4893));

    xkb_keymap_unref(keymap);
    free(dump);

    xkb_context_unref(ctx);

    return 0;
}
Example #27
0
static int uxkb_desc_init(struct kbd_desc **out,
			  const char *layout,
			  const char *variant,
			  const char *options)
{
	int ret;
	struct kbd_desc *desc;
	struct xkb_rule_names rmlvo = {
		.rules = "evdev",
		.model = "evdev",
		.layout = layout,
		.variant = variant,
		.options = options,
	};

	if (!out)
		return -EINVAL;

	desc = malloc(sizeof(*desc));
	if (!desc)
		return -ENOMEM;

	memset(desc, 0, sizeof(*desc));
	desc->ref = 1;
	desc->ops = &uxkb_desc_ops;

	desc->uxkb.ctx = xkb_context_new(0);
	if (!desc->uxkb.ctx) {
		ret = -ENOMEM;
		goto err_desc;
	}

	desc->uxkb.keymap = xkb_map_new_from_names(desc->uxkb.ctx, &rmlvo, 0);
	if (!desc->uxkb.keymap) {
		log_warn("failed to create keymap (%s, %s, %s), "
			 "reverting to default US keymap",
			 layout, variant, options);

		rmlvo.layout = "us";
		rmlvo.variant = "";
		rmlvo.options = "";

		desc->uxkb.keymap = xkb_map_new_from_names(desc->uxkb.ctx,
							   &rmlvo, 0);
		if (!desc->uxkb.keymap) {
			log_warn("failed to create keymap");
			ret = -EFAULT;
			goto err_ctx;
		}
	}

	log_debug("new keyboard description (%s, %s, %s)",
			layout, variant, options);
	*out = desc;
	return 0;

err_ctx:
	xkb_context_unref(desc->uxkb.ctx);
err_desc:
	free(desc);
	return ret;
}

static void uxkb_desc_ref(struct kbd_desc *desc)
{
	if (!desc || !desc->ref)
		return;

	++desc->ref;
}

static void uxkb_desc_unref(struct kbd_desc *desc)
{
	if (!desc || !desc->ref || --desc->ref)
		return;

	log_debug("destroying keyboard description");
	xkb_map_unref(desc->uxkb.keymap);
	xkb_context_unref(desc->uxkb.ctx);
	free(desc);
}

static int uxkb_desc_alloc(struct kbd_desc *desc, struct kbd_dev **out)
{
	struct kbd_dev *kbd;

	kbd = malloc(sizeof(*kbd));
	if (!kbd)
		return -ENOMEM;

	memset(kbd, 0, sizeof(*kbd));
	kbd->ref = 1;
	kbd->desc = desc;
	kbd->ops = &uxkb_dev_ops;

	kbd->uxkb.state = xkb_state_new(desc->uxkb.keymap);
	if (!kbd->uxkb.state) {
		free(kbd);
		return -ENOMEM;
	}

	kbd_desc_ref(desc);
	*out = kbd;
	return 0;
}

static void uxkb_keysym_to_string(uint32_t keysym, char *str, size_t size)
{
	xkb_keysym_get_name(keysym, str, size);
}
Example #28
0
int uxkb_desc_init(struct uterm_input *input,
		   const char *model,
		   const char *layout,
		   const char *variant,
		   const char *options,
		   const char *keymap)
{
	int ret;
	struct xkb_rule_names rmlvo = {
		.rules = "evdev",
		.model = model,
		.layout = layout,
		.variant = variant,
		.options = options,
	};

	input->ctx = xkb_context_new(0);
	if (!input->ctx) {
		log_error("cannot create XKB context");
		return -ENOMEM;
	}

	/* If a complete keymap file was given, first try that. */
	if (keymap && *keymap) {
		input->keymap = xkb_keymap_new_from_string(input->ctx,
					keymap, XKB_KEYMAP_FORMAT_TEXT_V1, 0);
		if (input->keymap) {
			log_debug("new keyboard description from memory");
			return 0;
		}

		log_warn("cannot parse keymap, reverting to rmlvo");
	}

	input->keymap = xkb_keymap_new_from_names(input->ctx, &rmlvo, 0);
	if (!input->keymap) {
		log_warn("failed to create keymap (%s, %s, %s, %s), "
			 "reverting to default system keymap",
			 model, layout, variant, options);

		rmlvo.model = "";
		rmlvo.layout = "";
		rmlvo.variant = "";
		rmlvo.options = "";

		input->keymap = xkb_keymap_new_from_names(input->ctx,
							  &rmlvo, 0);
		if (!input->keymap) {
			log_warn("failed to create XKB keymap");
			ret = -EFAULT;
			goto err_ctx;
		}
	}

	log_debug("new keyboard description (%s, %s, %s, %s)",
		  model, layout, variant, options);
	return 0;

err_ctx:
	xkb_context_unref(input->ctx);
	return ret;
}

void uxkb_desc_destroy(struct uterm_input *input)
{
	xkb_keymap_unref(input->keymap);
	xkb_context_unref(input->ctx);
}
Example #29
0
void fill_keycodes() {

	struct xkb_keymap *keymap;
	struct xkb_context *context;
	const struct xkb_rule_names rules={
		.rules=xkb_names[0],
		.model=xkb_names[1],
		.layout=xkb_names[2],
		.variant=xkb_names[3],
		.options=xkb_names[4]
	};
	struct xkb_state *state;
	enum xkb_state_component current_state;
	int counter;
	int i,j,k;
	char mods[256];
	char keysym_asc[256];
	char file_path[256];
	char command[15];
	uint32_t max_keys;
	int w,h,retval;
	int jumpto;

	context=xkb_context_new(0);
	keymap=xkb_keymap_new_from_names(context,&rules,0);

	state=NULL;

	// Get all the modifier keys
	for(i=8;i<256;i++) {
		state=xkb_state_new(keymap);
		current_state=xkb_state_update_key(state, i,XKB_KEY_DOWN);
		if (current_state!=0) {
			mods[i]=1;
		} else {
			mods[i]=0;
		}
		xkb_state_unref(state);
	}
	mods[7]=1; // fake mod, used for "no mod"

	// Read the keyboard definition files

	sprintf(file_path,"%s/%s.keymap",BASE_CONFIG_DIR,lang_onscreen);

	FILE *keyboard_file=fopen(file_path,"r");
	if (keyboard_file==NULL) {
		printf("Can't open keyboard definition file %s. Trying with US file\n",file_path);
		sprintf(file_path,"%s/us.keymap",BASE_CONFIG_DIR);
		keyboard_file=fopen(file_path,"r");
		if (keyboard_file==NULL) {
			printf("Also failed to open the US keymap file. Aborting.\n");
			exit(-1);
		}
	}
	retval=fscanf(keyboard_file,"%s %d",command,&keyboard_blocks);
	if (retval!=2) {
		printf("Can't read the number of blocks\n");
	} else {
		max_keys=keyboard_blocks*4*KEYS_PER_ROW;
		keyboard_lowercase=(struct key_element *)malloc(max_keys*sizeof(struct key_element));
		memset(keyboard_lowercase,0,max_keys*sizeof(struct key_element));
		for(counter=0;(!feof(keyboard_file))&&(counter<max_keys);counter++) {
			retval=fscanf(keyboard_file,"%s %d %d",command,&w,&h);
			if(retval!=3) {
				break;
			}
			keyboard_lowercase[counter].size=KEYS_FONT_SIZE;
			keyboard_lowercase[counter].g_element[0]=0;
			keyboard_lowercase[counter].w=w;
			keyboard_lowercase[counter].h=h;
			keyboard_lowercase[counter].keycode=0;
			keyboard_lowercase[counter].modifier=0;
			if (!strcmp(command,"BLANK")) {
				keyboard_lowercase[counter].type=KEY_BLANK;
				keyboard_lowercase[counter].keysym=0;
			} else if (!strcmp(command,"KEY")) {
				keyboard_lowercase[counter].type=KEY_PH;
				retval=fscanf(keyboard_file,"%s",keyboard_lowercase[counter].g_element);
				keyboard_lowercase[counter].keysym=init_utf8_to_keysym(keyboard_lowercase[counter].g_element);
				if (keyboard_lowercase[counter].keysym==0) {
					keyboard_lowercase[counter].type=KEY_BLANK;
				}
			} else if ((!strcmp(command,"KEYSYM"))||(!strcmp(command,"KEYSYMTEXT"))) {
				keyboard_lowercase[counter].type=KEY_PH;
				retval=fscanf(keyboard_file,"%s",keysym_asc);
				keyboard_lowercase[counter].keysym=xkb_keysym_from_name(keysym_asc,0);
				if (keyboard_lowercase[counter].keysym==0) {
					printf("Unknown keysym %s\n",keysym_asc);
					keyboard_lowercase[counter].type=KEY_BLANK;
				} else {
					if (!strcmp(command,"KEYSYMTEXT")) {
						retval=fscanf(keyboard_file,"%s",keyboard_lowercase[counter].g_element);
						keyboard_lowercase[counter].size=KEYS_TEXT_FONT_SIZE;
					} else {
						retval=xkb_keysym_to_utf8(keyboard_lowercase[counter].keysym,keyboard_lowercase[counter].g_element,7);
						if (retval==-1) {
							retval++;
						}
						keyboard_lowercase[counter].g_element[retval]=0;// terminate string
					}
				}
			} else if (!strcmp(command,"TAB")) {
				keyboard_lowercase[counter].type=KEY_TAB;
				keyboard_lowercase[counter].keysym=XK_Tab;
			} else if (!strcmp(command,"SPACE")) {
				keyboard_lowercase[counter].type=KEY_SPACE;
				keyboard_lowercase[counter].keysym=XK_space;
			} else if (!strcmp(command,"RETURN")) {
				keyboard_lowercase[counter].type=KEY_RETURN;
				keyboard_lowercase[counter].keysym=XK_Return;
			} else if (!strcmp(command,"DELETE")) {
				keyboard_lowercase[counter].type=KEY_DELETE;
				keyboard_lowercase[counter].keysym=XK_BackSpace;
			} else if (!strcmp(command,"JUMPTO")) {
				retval=fscanf(keyboard_file,"%d %s",&jumpto,command);
				keyboard_lowercase[counter].type=KEY_JUMPTO;
				keyboard_lowercase[counter].keycode=jumpto;
				keyboard_lowercase[counter].keysym=0;
				if (!strcmp(command,"GEN")) {
					keyboard_lowercase[counter].modifier=0;
				} else if (!strcmp(command,"SHIFT")) {
					keyboard_lowercase[counter].modifier=1;
				} else if (!strcmp(command,"SYMBOLS")) {
					keyboard_lowercase[counter].modifier=2;
				} else if (!strcmp(command,"LETTERS")) {
					keyboard_lowercase[counter].modifier=3;
				}
				if (jumpto>=keyboard_blocks) {
					printf("Ilegal jump to block %d (max. is %d)\n",jumpto,keyboard_blocks);
					keyboard_lowercase[counter].type=KEY_BLANK;
				}
			} else if (!strcmp(command,"UP")) {
				keyboard_lowercase[counter].type=KEY_UP;
				keyboard_lowercase[counter].keysym=XK_Up;
			} else if (!strcmp(command,"DOWN")) {
				keyboard_lowercase[counter].type=KEY_DOWN;
				keyboard_lowercase[counter].keysym=XK_Down;
			} else if (!strcmp(command,"LEFT")) {
				keyboard_lowercase[counter].type=KEY_LEFT;
				keyboard_lowercase[counter].keysym=XK_Left;
			} else if (!strcmp(command,"RIGHT")) {
				keyboard_lowercase[counter].type=KEY_RIGHT;
				keyboard_lowercase[counter].keysym=XK_Right;
			} else {
				printf("Unknown command %s\n",command);
				keyboard_lowercase[counter].type=KEY_BLANK;
				keyboard_lowercase[counter].keysym=0;
			}
		}

		xkb_keysym_t  keysym;
		xkb_keycode_t keycode_mod;
		for(i=7;i<256;i++) { // do a loop on every modifier
			if (!mods[i]) {
				continue; // In this loop we test each modifier with each keycode
			}
			state=xkb_state_new(keymap);
			if (i!=7) {
				xkb_state_update_key(state, i,XKB_KEY_DOWN); // press the modifier key
				keycode_mod=i;
			} else {
				keycode_mod=0;
			}
			for(j=8;j<256;j++) {
				if (mods[j]) {
					continue;  // Don't test modifiers; we want "normal" keys
				}
				keysym=xkb_state_key_get_one_sym(state, j);
				if (keysym==XKB_KEY_NoSymbol) {
					continue;
				}
				for(k=0;k<counter;k++) { // and now we check each desired key with the keysymbol obtained
					if ((keyboard_lowercase[k].keycode==0)&&(keyboard_lowercase[k].type!=KEY_BLANK)&&(keyboard_lowercase[k].keysym==keysym)) {
						keyboard_lowercase[k].keycode=j;
						keyboard_lowercase[k].modifier=keycode_mod;
					}
				}
			}
			xkb_state_unref(state);
		}
		/*for(k=0;k<counter;k++) { // and now we check each desired key with the keysymbol obtained
			printf("Texto: %s, Keysym: %d, mod: %d\n",keyboard_lowercase[k].g_element,keyboard_lowercase[k].keycode,keyboard_lowercase[k].modifier);
		}*/

		// Now assign new keysyms to keycodes not used, to allow other keysyms not available in US keyboards

		xcb_key_symbols_t *symbols;

		symbols=xcb_key_symbols_alloc(conn);
		xcb_flush(conn);

		xcb_keycode_t keycode=8;
		xcb_keycode_t keycode_found;

		xcb_keysym_t keysyms[4];
		xcb_keycode_t keycode_shift;

		struct lower_upper_t {xcb_keysym_t upper_first;
				xcb_keysym_t upper_last;
				xcb_keysym_t lower_first;
				xcb_keysym_t lower_last;
			};

		struct lower_upper_t lower_upper[] = {
				{XKB_KEY_Agrave,XKB_KEY_Odiaeresis,XKB_KEY_agrave,XKB_KEY_odiaeresis},
				{XKB_KEY_Oslash,XKB_KEY_THORN,XKB_KEY_oslash,XKB_KEY_thorn},
				{0,0,0,0}
			};
		struct lower_upper_t *iter_lu;

		keycode_shift=*xcb_key_symbols_get_keycode(symbols,XKB_KEY_Shift_L);
		for(k=0;k<max_keys;k++) { // and now we check each desired key with the keysymbol obtained
			if ((keyboard_lowercase[k].keycode==0)&&(keyboard_lowercase[k].type!=KEY_BLANK)&&(keyboard_lowercase[k].type!=KEY_JUMPTO)) {
				// this key is not available in US keyboards; let's redefine a keycode for it
				keycode_found=0;
				while(keycode<256) {
					if ((0==xcb_key_symbols_get_keysym(symbols,keycode,0))&&
						(0==xcb_key_symbols_get_keysym(symbols,keycode,1))&&
						(0==xcb_key_symbols_get_keysym(symbols,keycode,2))&&
						(0==xcb_key_symbols_get_keysym(symbols,keycode,3))) {
							keycode_found=keycode;
							break;
					}
					keycode++;
				}

				if (keycode_found==0) {
					printf("No more codes available\n");
					break; // there are no more free keycodes available
				}
				keycode=keycode_found;
				keysyms[0]=keyboard_lowercase[k].keysym;
				keysyms[1]=0;
				keysyms[2]=keyboard_lowercase[k].keysym;
				keysyms[3]=0;
				for(iter_lu=lower_upper;iter_lu->upper_first;iter_lu++) {
					if ((keysyms[0]>=iter_lu->upper_first)&&(keysyms[0]<=iter_lu->upper_last)) { // it's an uppercase special character
						keysyms[0]|=0x20; // first character as lowercase
						break;
					}
					if ((keysyms[0]>=iter_lu->lower_first)&&(keysyms[0]<=iter_lu->lower_last)) { // it's a lowercase special character
						keysyms[2]&=0xDF; // second character as uppercase
						break;
					}
				}
				xcb_change_keyboard_mapping(conn,1,keycode,4,keysyms); // insert the new keysym
				for(j=k;j<max_keys;j++) { // set the keycode and the shift modifier, if needed, to all keys with that keysyms
					if (keyboard_lowercase[j].keysym==keysyms[0]) {
						keyboard_lowercase[j].keycode=keycode;
						keyboard_lowercase[j].modifier=0;
						continue;
					}
					if (keyboard_lowercase[j].keysym==keysyms[2]) {
						keyboard_lowercase[j].keycode=keycode;
						keyboard_lowercase[j].modifier=keycode_shift;
						continue;
					}
				}
				keycode++;
			}
		}
		xcb_key_symbols_free(symbols);
	}

	fclose(keyboard_file);
	keyboard_current_block=0;
	xkb_keymap_unref(keymap);
	xkb_context_unref(context);
}
Example #30
0
int
main(int argc, char *argv[])
{
    int ret;
    int opt;
    struct keyboard *kbds;
    struct xkb_context *ctx;
    struct xkb_keymap *keymap;
    const char *rules = NULL;
    const char *model = NULL;
    const char *layout = NULL;
    const char *variant = NULL;
    const char *options = NULL;
    const char *keymap_path = NULL;
    struct sigaction act;

    setlocale(LC_ALL, "");

    while ((opt = getopt(argc, argv, "r:m:l:v:o:k:n:c")) != -1) {
        switch (opt) {
        case 'r':
            rules = optarg;
            break;
        case 'm':
            model = optarg;
            break;
        case 'l':
            layout = optarg;
            break;
        case 'v':
            variant = optarg;
            break;
        case 'o':
            options = optarg;
            break;
        case 'k':
            keymap_path = optarg;
            break;
        case 'n':
            errno = 0;
            evdev_offset = strtol(optarg, NULL, 10);
            if (errno) {
                fprintf(stderr, "error: -n option expects a number\n");
                exit(EXIT_FAILURE);
            }
            break;
        case 'c':
            report_state_changes = true;
            break;
        case '?':
            fprintf(stderr, "   Usage: %s [-r <rules>] [-m <model>] "
                    "[-l <layout>] [-v <variant>] [-o <options>]\n",
                    argv[0]);
            fprintf(stderr, "      or: %s -k <path to keymap file>\n",
                    argv[0]);
            fprintf(stderr, "For both: -n <evdev keycode offset>\n"
                            "          -c (to report changes to the state)\n");
            exit(EX_USAGE);
        }
    }

    ctx = test_get_context(0);
    if (!ctx) {
        ret = -1;
        fprintf(stderr, "Couldn't create xkb context\n");
        goto err_out;
    }

    if (keymap_path) {
        FILE *file = fopen(keymap_path, "r");
        if (!file) {
            ret = EXIT_FAILURE;
            fprintf(stderr, "Couldn't open '%s': %s\n",
                    keymap_path, strerror(errno));
            goto err_ctx;
        }
        keymap = xkb_keymap_new_from_file(ctx, file,
                                          XKB_KEYMAP_FORMAT_TEXT_V1, 0);
        fclose(file);
    }
    else {
        keymap = test_compile_rules(ctx, rules, model, layout, variant,
                                    options);
    }

    if (!keymap) {
        ret = -1;
        fprintf(stderr, "Couldn't create xkb keymap\n");
        goto err_ctx;
    }

    kbds = get_keyboards(keymap);
    if (!kbds) {
        ret = -1;
        goto err_xkb;
    }

    act.sa_handler = sigintr_handler;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    sigaction(SIGINT, &act, NULL);
    sigaction(SIGTERM, &act, NULL);

    /* Instead of fiddling with termios.. */
    system("stty -echo");

    ret = loop(kbds);
    if (ret)
        goto err_stty;

err_stty:
    system("stty echo");
    free_keyboards(kbds);
err_xkb:
    xkb_keymap_unref(keymap);
err_ctx:
    xkb_context_unref(ctx);
err_out:
    exit(ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}