/*************************************************************************** * * fedora-setup-keyboard.c: Apply /etc/sysconfig/keyboard to X * Copyright 2008 Red Hat, Inc. * * Shamelessly stolen from: * * hal_set_property.c : Set property for a device * * Copyright (C) 2003 David Zeuthen, * * Licensed under the Academic Free License version 2.1 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * **************************************************************************/ #include #include #include #include #include #include static LibHalContext *hal_ctx; static void load_esk(void) { FILE *f; char *name, *value, *line; f = fopen("/etc/sysconfig/keyboard", "r"); if (!f) exit(1); while (fscanf(f, "%as\n", &line) == 1) { if (sscanf(line, "%as=\"%as\"\n", &name, &value) != 2) { free(line); continue; } setenv(name, value, 1); free(name); free(value); free(line); } fclose(f); } struct model { char *layout; char *model; char *variant; char *options; } models[] = { { "be", "pc105", "", "" }, { "br", "abnt2", "", "" }, { "ca(fr)", "pc105", "", "" }, { "ch", "pc105", "fr", "" }, { "cz", "pc105", "qwerty", "" }, { "de", "pc105", "", "" }, { "dk", "pc105", "", "" }, { "ee", "pc105", "", "" }, { "es", "pc105", "", "" }, { "fi", "pc105", "", "" }, { "fr", "pc105", "", "" }, { "gb", "pc105", "", "" }, { "hr", "pc105", "", "" }, { "hu", "pc105", "", "" }, { "ie", "pc105", "", "" }, { "is", "pc105", "", "" }, { "it", "pc105", "", "" }, { "jp", "jp106", "", "" }, { "kr", "pc105", "", "" }, { "latam", "pc105", "", "" }, { "nl", "pc105", "", "" }, { "no", "pc105", "", "" }, { "pl", "pc105", "", "" }, { "pt", "pc105", "", "" }, { "ro", "pc105", "", "" }, { "rs", "pc105", "", "" }, { "se", "pc105", "", "" }, { "si", "pc105", "", "" }, { "sk", "pc105", "", "qwerty" }, { "tr", "pc105", "", "" }, { "us", "pc105+inet", "", "" }, { "us,ara", "pc105", "qwerty", "grp:shifts_toggle,grp_led:scroll" }, { "us,bg", "pc105", "", "grp:shifts_toggle,grp_led:scroll" }, { "us,cz", "pc105", "", "grp:shifts_toggle,grp_led:scroll" }, { "us,dev", "pc105", "", "grp:shifts_toggle,grp_led:scroll" }, { "us,gr", "pc105", "", "grp:shifts_toggle,grp_led:scroll" }, { "us,gur", "pc105", "", "grp:shifts_toggle,grp_led:scroll" }, { "us,in", "pc105", "tam", "grp:shifts_toggle,grp_led:scroll" }, { "us,mkd", "pc105", "", "grp:shifts_toggle,grp_led:scroll" }, { "us,ru", "pc105", "", "grp:shifts_toggle,grp_led:scroll" }, { "us,ua", "pc105", "", "grp:shifts_toggle,grp_led:scroll" }, { "", "", "", "" }, }; static int set_xkb_option(char *udi, char *name, char *value, DBusError *error) { dbus_bool_t rc = 0; if (!value || !strlen(value)) { rc = libhal_device_remove_property(hal_ctx, udi, name, error); } else { rc = libhal_device_set_property_string(hal_ctx, udi, name, value, error); } if (!rc) { LIBHAL_FREE_DBUS_ERROR (error); return 1; } return 0; } int main (int argc, char *argv[]) { char *udi = NULL; char *keytable = NULL; char *layout = NULL, *model = NULL, *variant = NULL, *options = NULL; DBusError error; int rc = 0; int fd = open("/tmp/fsk.log", O_RDWR); write(fd, "q\n", 2); fsync(fd); load_esk(); write(fd, "0\n", 2); if (!(udi = getenv("UDI"))) return 1; write(fd, "1\n", 2); keytable = getenv("KEYTABLE"); layout = getenv("LAYOUT"); model = getenv("MODEL"); variant = getenv("VARIANT"); options = getenv("OPTIONS"); if (!keytable && !layout) return 1; dbus_error_init (&error); if ((hal_ctx = libhal_ctx_init_direct (&error)) == NULL) { LIBHAL_FREE_DBUS_ERROR (&error); return 1; } if (layout) { /* good, we have explicit setup */ rc |= set_xkb_option(udi, "input.xkb.layout", layout, &error); rc |= set_xkb_option(udi, "input.xkb.model", model, &error); rc |= set_xkb_option(udi, "input.xkb.variant", variant, &error); rc |= set_xkb_option(udi, "input.xkb.options", options, &error); } else if (keytable) { /* argh, legacy file, take a wild guess */ struct model *m; for (m = models; *m->layout != '\0'; m++) { if (!strcmp(m->layout, keytable)) { rc |= set_xkb_option(udi, "input.xkb.layout", m->layout, &error); rc |= set_xkb_option(udi, "input.xkb.model", m->model, &error); rc |= set_xkb_option(udi, "input.xkb.variant", m->variant, &error); rc |= set_xkb_option(udi, "input.xkb.options", m->options, &error); break; } } } return rc; }