Exemple #1
0
static void context_free(Context *c) {
        context_free_locale(c);
        context_free_x11(c);
        context_free_vconsole(c);

        bus_verify_polkit_async_registry_free(c->polkit_registry);
};
Exemple #2
0
static int x11_read_data(Context *c) {
        _cleanup_fclose_ FILE *f;
        char line[LINE_MAX];
        bool in_section = false;
        int r;

        context_free_x11(c);

        f = fopen("/etc/X11/xorg.conf.d/00-keyboard.conf", "re");
        if (!f)
                return errno == ENOENT ? 0 : -errno;

        while (fgets(line, sizeof(line), f)) {
                char *l;

                char_array_0(line);
                l = strstrip(line);

                if (l[0] == 0 || l[0] == '#')
                        continue;

                if (in_section && first_word(l, "Option")) {
                        _cleanup_strv_free_ char **a = NULL;

                        r = strv_split_quoted(&a, l, false);
                        if (r < 0)
                                return r;

                        if (strv_length(a) == 3) {
                                if (streq(a[1], "XkbLayout")) {
                                        free_and_replace(&c->x11_layout, a[2]);
                                        a[2] = NULL;
                                } else if (streq(a[1], "XkbModel")) {
                                        free_and_replace(&c->x11_model, a[2]);
                                        a[2] = NULL;
                                } else if (streq(a[1], "XkbVariant")) {
                                        free_and_replace(&c->x11_variant, a[2]);
                                        a[2] = NULL;
                                } else if (streq(a[1], "XkbOptions")) {
                                        free_and_replace(&c->x11_options, a[2]);
                                        a[2] = NULL;
                                }
                        }

                } else if (!in_section && first_word(l, "Section")) {
                        _cleanup_strv_free_ char **a = NULL;

                        r = strv_split_quoted(&a, l, false);
                        if (r < 0)
                                return -ENOMEM;

                        if (strv_length(a) == 2 && streq(a[1], "InputClass"))
                                in_section = true;

                } else if (in_section && first_word(l, "EndSection"))
                        in_section = false;
        }

        return 0;
}
Exemple #3
0
void context_free(Context *c) {
        context_free_locale(c);
        context_free_x11(c);
        context_free_vconsole(c);

        sd_bus_message_unref(c->locale_cache);
        sd_bus_message_unref(c->x11_cache);
        sd_bus_message_unref(c->vc_cache);
};
Exemple #4
0
void context_clear(Context *c) {
        context_free_locale(c);
        context_free_x11(c);
        context_free_vconsole(c);

        sd_bus_message_unref(c->locale_cache);
        sd_bus_message_unref(c->x11_cache);
        sd_bus_message_unref(c->vc_cache);

        bus_verify_polkit_async_registry_free(c->polkit_registry);
};
Exemple #5
0
static int vconsole_convert_to_x11(Context *c, sd_bus *bus) {
        bool modified = false;

        assert(bus);

        if (isempty(c->vc_keymap)) {

                modified =
                        !isempty(c->x11_layout) ||
                        !isempty(c->x11_model) ||
                        !isempty(c->x11_variant) ||
                        !isempty(c->x11_options);

                context_free_x11(c);
        } else {
                _cleanup_fclose_ FILE *f = NULL;
                unsigned n = 0;

                f = fopen(SYSTEMD_KBD_MODEL_MAP, "re");
                if (!f)
                        return -errno;

                for (;;) {
                        _cleanup_strv_free_ char **a = NULL;
                        int r;

                        r = read_next_mapping(f, &n, &a);
                        if (r < 0)
                                return r;
                        if (r == 0)
                                break;

                        if (!streq(c->vc_keymap, a[0]))
                                continue;

                        if (!streq_ptr(c->x11_layout, strnulldash(a[1])) ||
                            !streq_ptr(c->x11_model, strnulldash(a[2])) ||
                            !streq_ptr(c->x11_variant, strnulldash(a[3])) ||
                            !streq_ptr(c->x11_options, strnulldash(a[4]))) {

                                if (free_and_strdup(&c->x11_layout, strnulldash(a[1])) < 0 ||
                                    free_and_strdup(&c->x11_model, strnulldash(a[2])) < 0 ||
                                    free_and_strdup(&c->x11_variant, strnulldash(a[3])) < 0 ||
                                    free_and_strdup(&c->x11_options, strnulldash(a[4])) < 0)
                                        return -ENOMEM;

                                modified = true;
                        }

                        break;
                }
        }

        if (modified) {
                int r;

                r = x11_write_data(c);
                if (r < 0)
                        return log_error_errno(r, "Failed to set X11 keyboard layout: %m");

                log_info("Changed X11 keyboard layout to '%s' model '%s' variant '%s' options '%s'",
                         strempty(c->x11_layout),
                         strempty(c->x11_model),
                         strempty(c->x11_variant),
                         strempty(c->x11_options));

                sd_bus_emit_properties_changed(bus,
                                "/org/freedesktop/locale1",
                                "org.freedesktop.locale1",
                                "X11Layout", "X11Model", "X11Variant", "X11Options", NULL);
        } else
                log_debug("X11 keyboard layout was not modified.");

        return 0;
}
Exemple #6
0
int vconsole_convert_to_x11(Context *c) {
        const char *map;
        int modified = -1;

        map = systemd_kbd_model_map();

        if (isempty(c->vc_keymap)) {
                modified =
                        !isempty(c->x11_layout) ||
                        !isempty(c->x11_model) ||
                        !isempty(c->x11_variant) ||
                        !isempty(c->x11_options);

                context_free_x11(c);
        } else {
                _cleanup_fclose_ FILE *f = NULL;
                unsigned n = 0;

                f = fopen(map, "re");
                if (!f)
                        return -errno;

                for (;;) {
                        _cleanup_strv_free_ char **a = NULL;
                        int r;

                        r = read_next_mapping(map, 5, UINT_MAX, f, &n, &a);
                        if (r < 0)
                                return r;
                        if (r == 0)
                                break;

                        if (!streq(c->vc_keymap, a[0]))
                                continue;

                        if (!streq_ptr(c->x11_layout, strnulldash(a[1])) ||
                            !streq_ptr(c->x11_model, strnulldash(a[2])) ||
                            !streq_ptr(c->x11_variant, strnulldash(a[3])) ||
                            !streq_ptr(c->x11_options, strnulldash(a[4]))) {

                                if (free_and_strdup(&c->x11_layout, strnulldash(a[1])) < 0 ||
                                    free_and_strdup(&c->x11_model, strnulldash(a[2])) < 0 ||
                                    free_and_strdup(&c->x11_variant, strnulldash(a[3])) < 0 ||
                                    free_and_strdup(&c->x11_options, strnulldash(a[4])) < 0)
                                        return -ENOMEM;

                                modified = true;
                        }

                        break;
                }
        }

        if (modified > 0)
                log_info("Changing X11 keyboard layout to '%s' model '%s' variant '%s' options '%s'",
                         strempty(c->x11_layout),
                         strempty(c->x11_model),
                         strempty(c->x11_variant),
                         strempty(c->x11_options));
        else if (modified < 0)
                log_notice("X11 keyboard layout was not modified: no conversion found for \"%s\".",
                           c->vc_keymap);
        else
                log_debug("X11 keyboard layout did not need to be modified.");

        return modified > 0;
}
Exemple #7
0
int x11_read_data(Context *c, sd_bus_message *m) {
        _cleanup_fclose_ FILE *f = NULL;
        bool in_section = false;
        char line[LINE_MAX];
        struct stat st;
        usec_t t;
        int r;

        /* Do not try to re-read the file within single bus operation. */
        if (m) {
                if (m == c->x11_cache)
                        return 0;

                sd_bus_message_unref(c->x11_cache);
                c->x11_cache = sd_bus_message_ref(m);
        }

        if (stat("/etc/X11/xorg.conf.d/00-keyboard.conf", &st) < 0) {
                if (errno != ENOENT)
                        return -errno;

                c->x11_mtime = USEC_INFINITY;
                context_free_x11(c);
                return 0;
        }

        /* If mtime is not changed, then we do not need to re-read */
        t = timespec_load(&st.st_mtim);
        if (c->x11_mtime != USEC_INFINITY && t == c->x11_mtime)
                return 0;

        c->x11_mtime = t;
        context_free_x11(c);

        f = fopen("/etc/X11/xorg.conf.d/00-keyboard.conf", "re");
        if (!f)
                return -errno;

        while (fgets(line, sizeof(line), f)) {
                char *l;

                char_array_0(line);
                l = strstrip(line);

                if (IN_SET(l[0], 0, '#'))
                        continue;

                if (in_section && first_word(l, "Option")) {
                        _cleanup_strv_free_ char **a = NULL;

                        r = strv_split_extract(&a, l, WHITESPACE, EXTRACT_QUOTES);
                        if (r < 0)
                                return r;

                        if (strv_length(a) == 3) {
                                char **p = NULL;

                                if (streq(a[1], "XkbLayout"))
                                        p = &c->x11_layout;
                                else if (streq(a[1], "XkbModel"))
                                        p = &c->x11_model;
                                else if (streq(a[1], "XkbVariant"))
                                        p = &c->x11_variant;
                                else if (streq(a[1], "XkbOptions"))
                                        p = &c->x11_options;

                                if (p) {
                                        free_and_replace(*p, a[2]);
                                }
                        }

                } else if (!in_section && first_word(l, "Section")) {
                        _cleanup_strv_free_ char **a = NULL;

                        r = strv_split_extract(&a, l, WHITESPACE, EXTRACT_QUOTES);
                        if (r < 0)
                                return -ENOMEM;

                        if (strv_length(a) == 2 && streq(a[1], "InputClass"))
                                in_section = true;

                } else if (in_section && first_word(l, "EndSection"))
                        in_section = false;
        }

        return 0;
}
Exemple #8
0
void context_free(Context *c) {
        context_free_locale(c);
        context_free_x11(c);
        context_free_vconsole(c);
};