Logo Search packages:      
Sourcecode: kbd version File versions  Download package

setleds.c

/*
 * setleds.c - aeb, 940130, 940909, 991008
 *
 * Call: setleds [-L] [-D] [-F] [{+|-}{num|caps|scroll}]*
 * will set or clear the indicated flags on the stdin tty,
 * and report the settings before and after.
 * In particular, setleds without arguments will only report.
 */

#include <stdio.h>
#include <fcntl.h>
#include <linux/kd.h>
#include <sys/ioctl.h>
#include "nls.h"
#include "version.h"

#ifdef __sparc__
#include <asm/kbio.h>
#endif

static void
usage(void)
{
    fprintf(stderr, _(
"Usage:\n"
"     setleds [-v] [-L] [-D] [-F] [[+|-][ num | caps | scroll %s]]\n"
"Thus,\n"
"     setleds +caps -num\n"
"will set CapsLock, clear NumLock and leave ScrollLock unchanged.\n"
"The settings before and after the change (if any) are reported\n"
"when the -v option is given or when no change is requested.\n"
"Normally, setleds influences the vt flag settings\n"
"(and these are usually reflected in the leds).\n"
"With -L, setleds only sets the leds, and leaves the flags alone.\n"
"With -D, setleds sets both the flags and the default flags, so\n"
"that a subsequent reset will not change the flags.\n"
),
#ifdef __sparc__
    "| compose "
#else
    ""
#endif
    );
    exit(1);
}

#define onoff(a) ((a) ? _("on ") : _("off"))

/* report the bits, in the order seen on the (my) keyboard */
#define LED_NLOCK  1
#define LED_CMPOSE 2
#define LED_SCRLCK 4
#define LED_CLOCK  8

static void
sunreport(int leds) {
      printf("NumLock %s   Compose %s   ScrollLock %s   CapsLock %s\n",
             onoff(leds & LED_NLOCK),
             onoff(leds & LED_CMPOSE),
             onoff(leds & LED_SCRLCK),
             onoff(leds & LED_CLOCK));
}

static void
report(int leds) {
        printf("NumLock %s   CapsLock %s   ScrollLock %s\n",
             onoff(leds & LED_NUM),
             onoff(leds & LED_CAP),
             onoff(leds & LED_SCR));
}

struct led {
    char *name;
    int bit;
    int sunbit;
} leds[] = {
    { "scroll", LED_SCR, LED_SCRLCK },
    { "num",    LED_NUM, LED_NLOCK },
    { "caps",   LED_CAP, LED_CLOCK },
#ifdef __sparc__
    { "compose",   0,    LED_CMPOSE }
#endif
};

static void
getleds(char *leds) {
    if (ioctl(0, KDGETLED, leds)) {
      perror("KDGETLED");
      fprintf(stderr,
        _("Error reading current led setting. Maybe stdin is not a VT?\n"));
      exit(1);
    }
}

static int
setleds(char leds) {
    if (ioctl(0, KDSETLED, leds)) {
      perror("KDSETLED");
      return -1;
    }
    return 0;
}

static void
getflags(char *flags) {
    if (ioctl(0, KDGKBLED, flags)) {
      perror("KDGKBLED");
      fprintf(stderr,
          _("Error reading current flags setting. "
          "Maybe you are not on the console?\n"));
      exit(1);
    }
}

static int sunkbdfd = -1;

static void
sungetleds(char *leds) {
#ifdef KIOCGLED
    if (ioctl(sunkbdfd, KIOCGLED, leds)) {
      perror("KIOCGLED");
      fprintf(stderr,
        _("Error reading current led setting from /dev/kbd.\n"));
      exit(1);
    }
#else
    fprintf(stderr, _("KIOCGLED unavailable?\n"));
    exit(1);
#endif
}

static void
sunsetleds(char *leds) {
#ifdef KIOCSLED
    if (ioctl(sunkbdfd, KIOCSLED, leds)) {
      perror("KIOCSLED");
      fprintf(stderr,
        _("Error reading current led setting from /dev/kbd.\n"));
      exit(1);
    }
#else
    fprintf(stderr, _("KIOCSLED unavailable?\n"));
    exit(1);
#endif
}

int
main(int argc, char **argv) {
    int optL = 0, optD = 0, optF = 0, verbose = 0;
    char oleds, nleds, oflags, nflags, odefflags, ndefflags;
    char nval, ndef, sign;
    char osunleds, nsunleds, nsunval, nsundef;
    char *ap;
    struct led *lp;

    set_progname(argv[0]);

    setlocale(LC_ALL, "");
    bindtextdomain(PACKAGE, LOCALEDIR);
    textdomain(PACKAGE);

    if (argc == 2 && (!strcmp("-V", argv[1]) || !strcmp("--version", argv[1])))
      print_version_and_exit();

#ifdef __sparc__
    sunkbdfd = open("/dev/kbd", O_RDONLY);
    if (sunkbdfd < 0) {
      perror("/dev/kbd");
      fprintf(stderr, _("Error opening /dev/kbd.\n"));
      /* exit(1); */
    }
#endif

    getflags(&oflags);
    getleds(&oleds);
    if (sunkbdfd >= 0)
          sungetleds(&osunleds);

    while (argc > 1) {
      if (!strcmp("-L", argv[1]))
        optL = 1;
      else if (!strcmp("-D", argv[1]))
        optD = 1;
      else if (!strcmp("-F", argv[1]))
        optF = 1;
      else if (!strcmp("-v", argv[1]))
        verbose = 1;
      else
        break;
      argc--;
      argv++;
    }

    odefflags = ndefflags = ((oflags >> 4) & 7);
    oflags = nflags = (oflags & 7);

    if (argc <= 1) {
      if (optL) {
          nleds = 0xff;
          if (setleds(nleds)) {
            fprintf(stderr, _("Error resetting ledmode\n"));
            exit(1);
          }
      }

      /* If nothing to do, report, even if not verbose */
      if (!optD && !optL && !optF)
        optD = optL = optF = 1;
      if (optD) {
          printf(_("Current default flags:  "));
          report(odefflags);
      }
      if (optF) {
          printf(_("Current flags:          "));
          report(oflags & 07);
      }
      if (optL) {
          printf(_("Current leds:           "));
          if (sunkbdfd >= 0)
            sunreport(osunleds);
          else
              report(oleds);
      }
      exit(0);
    }

    if (!optL)
      optF = 1;
    nval = 0;
    ndef = 0;
    nsunval = 0;
    nsundef = 0;

    while(--argc) {
      ap = *++argv;
      sign = 1;         /* by default: set */
      if(*ap == '+')
        ap++;
      else if(*ap == '-') {
          sign = 0;
          ap++;
      }
      for (lp = leds; lp-leds < sizeof(leds)/sizeof(leds[0]); lp++) {
          if(!strcmp(ap, lp->name)) {
            if(sign) {
              nval |= lp->bit;
              nsunval |= lp->sunbit;
            }
            ndef |= lp->bit;
            nsundef |= lp->sunbit;
            goto nxtarg;
          }
      }
      fprintf(stderr, _("unrecognized argument: _%s_\n\n"), ap);
      usage();

      nxtarg: ;
    }

    if (optD) {
      ndefflags = (odefflags & ~ndef) | nval;
      if (verbose) {
          printf(_("Old default flags:    "));
          report(odefflags);
          printf(_("New default flags:    "));
          report(ndefflags);
      }
    }
    if (optF) {
      nflags = ((oflags & ~ndef) | nval);
      if (verbose) {
          printf(_("Old flags:            "));
          report(oflags & 07);
          printf(_("New flags:            "));
          report(nflags & 07);
      }
    }
    if (optD || optF) {
      if (ioctl(0, KDSKBLED, (ndefflags << 4) | nflags)) {
          perror("KDSKBLED");
          exit(1);
      }
    }
    if (optL) {
      if (sunkbdfd >= 0) {
          nsunleds = (osunleds & ~nsundef) | nsunval;
          if (verbose) {
            printf(_("Old leds:             "));
            sunreport(osunleds);
            printf(_("New leds:             "));
            sunreport(nsunleds);
          }
          sunsetleds(&nsunleds);
      } else {
          nleds = (oleds & ~ndef) | nval;
          if (verbose) {
              printf(_("Old leds:             "));
              report(oleds);
              printf(_("New leds:             "));
              report(nleds);
          }
          if (setleds(nleds))
              exit(1);
      }
    }
    exit(0);
}

Generated by  Doxygen 1.6.0   Back to index