Set NumLock according to /etc/sysconfig/keyboard. https://bugzilla.novell.com/show_bug.cgi?id=746595 Authors: Stanislav Brabec Cristian Rodríguez --- Makefile.am | 13 ++++++++++ rules/73-seat-numlock.rules | 8 ++++++ src/login/numlock-on.c | 34 +++++++++++++++++++++++++++ src/vconsole/vconsole-setup.c | 40 ++++++++++++++++++++++++++++++-- units/systemd-vconsole-setup.service.in | 2 - 5 files changed, 94 insertions(+), 3 deletions(-) Index: systemd-218/Makefile.am =================================================================== --- systemd-218.orig/Makefile.am +++ systemd-218/Makefile.am @@ -3715,6 +3715,19 @@ dist_udevrules_DATA += \ rules/61-accelerometer.rules # ------------------------------------------------------------------------------ +numlock_on_SOURCES = \ + src/login/numlock-on.c + +numlock_on_CFLAGS = \ + $(AM_CFLAGS) + +udevlibexec_PROGRAMS += \ + numlock-on + +dist_udevrules_DATA += \ + rules/73-seat-numlock.rules + +# ------------------------------------------------------------------------------ if ENABLE_GUDEV if ENABLE_GTK_DOC SUBDIRS += \ Index: systemd-218/rules/73-seat-numlock.rules =================================================================== --- /dev/null +++ systemd-218/rules/73-seat-numlock.rules @@ -0,0 +1,8 @@ +# This file is part of SUSE customization of systemd. +# +# systemd 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. + +SUBSYSTEM=="tty", ACTION=="add", KERNEL=="tty[0-9]|tty1[0-2]", TEST=="/run/numlock-on", RUN+="numlock-on $env{DEVNAME}" Index: systemd-218/src/login/numlock-on.c =================================================================== --- /dev/null +++ systemd-218/src/login/numlock-on.c @@ -0,0 +1,34 @@ +/* + * numlock-on.c: Turn numlock-on + * + * This file may be freely copied under the terms of the GNU General + * Public License (GPL), version 2, or at your option any later + * version. + + * Copyright (C) 2013 Stanislav Brabec, SUSE + * + * based on setleds.c, which is + * Copyright (C) 1994-1999 Andries E. Brouwer + */ + +#include +#include +#include +#include + +int +main(int argc, char **argv) { + char flags; + + if (ioctl(0, KDGKBLED, &flags)) { + perror("KDGKBLED"); + exit(1); + } + + if (ioctl(0, KDSKBLED, flags | LED_NUM | (LED_NUM << 4))) { + perror("KDSKBLED"); + exit(1); + } + + exit(0); +} Index: systemd-218/src/vconsole/vconsole-setup.c =================================================================== --- systemd-218.orig/src/vconsole/vconsole-setup.c +++ systemd-218/src/vconsole/vconsole-setup.c @@ -42,6 +42,10 @@ #include "fileio.h" #include "strv.h" +#define BIOS_DATA_AREA 0x400 +#define BDA_KEYBOARD_STATUS_FLAGS_4 0x97 +#define BDA_KSF4_NUMLOCK_MASK 0x02 + static bool is_vconsole(int fd) { unsigned char data[1]; @@ -342,10 +346,11 @@ int main(int argc, char **argv) { #ifdef HAVE_SYSV_COMPAT _cleanup_free_ char *vc_kbd_delay = NULL, *vc_kbd_rate = NULL, - *vc_kbd_disable_caps_lock = NULL, *vc_compose_table = NULL; + *vc_kbd_disable_caps_lock = NULL, *vc_compose_table = NULL, + *vc_kbd_numlock = NULL; pid_t kbd_rate_pid = 0, compose_table_pid = 0; #endif - bool disable_capslock = false; + bool disable_capslock = false, numlock = false; _cleanup_close_ int fd = -1; bool utf8; pid_t font_pid = 0, keymap_pid = 0; @@ -384,6 +389,7 @@ int main(int argc, char **argv) { "KBD_DELAY", &vc_kbd_delay, "KBD_RATE", &vc_kbd_rate, "KBD_DISABLE_CAPS_LOCK", &vc_kbd_disable_caps_lock, + "KBD_NUMLOCK", &vc_kbd_numlock, "COMPOSETABLE", &vc_compose_table, NULL); if (r < 0 && r != -ENOENT) @@ -398,6 +404,32 @@ int main(int argc, char **argv) { log_warning("Failed to read /etc/sysconfig/console: %s", strerror(-r)); disable_capslock = vc_kbd_disable_caps_lock && strcasecmp(vc_kbd_disable_caps_lock, "YES") == 0; +#if defined(__i386__) || defined(__x86_64__) + if (vc_kbd_numlock && strcaseeq(vc_kbd_numlock, "bios")) { + int _cleanup_close_ fdmem; + char c; + + fdmem = open ("/dev/mem", O_RDONLY); + if (fdmem < 0) { + log_error("Failed to open /dev/mem: %m"); + return EXIT_FAILURE; + } + + if (lseek(fdmem, BIOS_DATA_AREA + BDA_KEYBOARD_STATUS_FLAGS_4, SEEK_SET) == (off_t) -1) { + log_error("Failed to seek /dev/mem: %m"); + return EXIT_FAILURE; + } + + if (read (fdmem, &c, sizeof(char)) == -1) { + log_error("Failed to read /dev/mem: %m"); + return EXIT_FAILURE; + } + + if (c & BDA_KSF4_NUMLOCK_MASK) + numlock = true; + } else +#endif + numlock = vc_kbd_numlock && strcaseeq(vc_kbd_numlock, "yes"); #endif r = parse_env_file("/etc/vconsole.conf", NEWLINE, @@ -444,6 +476,10 @@ int main(int argc, char **argv) { log_error_errno(r, "Failed to start " KBD_LOADKEYS ": %m"); return EXIT_FAILURE; } + if (numlock) + touch("/run/numlock-on"); + else + unlink("/run/numlock-on"); #ifdef HAVE_SYSV_COMPAT r = load_compose_table(vc, vc_compose_table, &compose_table_pid); if (r < 0) { Index: systemd-218/units/systemd-vconsole-setup.service.in =================================================================== --- systemd-218.orig/units/systemd-vconsole-setup.service.in +++ systemd-218/units/systemd-vconsole-setup.service.in @@ -10,7 +10,7 @@ Description=Setup Virtual Console Documentation=man:systemd-vconsole-setup.service(8) man:vconsole.conf(5) DefaultDependencies=no Conflicts=shutdown.target -Before=sysinit.target shutdown.target +Before=sysinit.target shutdown.target systemd-udev-trigger.service ConditionPathExists=/dev/tty0 [Service]