1. This forum section is a read-only archive which contains old newsgroup posts. If you wish to post a query, please do so in one of our main forum sections (here). This way you will get a faster, better response from the members on Motherboard Point.

NumLock on at login!?

Discussion in 'Sun Hardware' started by Peter, Nov 12, 2003.

  1. Peter

    Peter Guest

    Hey,

    is there a way to activate NumLock automatically when I login at the
    console (or in general)?

    uname -a yields " SunOS host 5.8 Generic_108528-21 sun4u sparc
    SUNW,Ultra-5_10 ".

    I would appreciate helpful hints, especially when they are not too cryptic
    ;-) since I'm a novice.

    Thanks,

    Peter
     
    Peter, Nov 12, 2003
    #1
    1. Advertisements

  2. Peter

    Greg Sellers Guest

    You mean so you don't have to "push" the NumLock key when you login,
    like when you power on your peecee, right?

    Nope, there is no way to do this. It drives me nuts, I bug my buddy
    at Sun about it all the time too. Best idea we came up with was to
    wait after logging out for the login screen to appear and then push
    the NumLock before you leave for the day, then it is already set for
    the next day...just have to remember to do it.

    -Greg
     
    Greg Sellers, Nov 13, 2003
    #2
    1. Advertisements

  3. I found a program meant for Linux to do this. Unfortunately, it compiles,
    but doesn't seem to have any effect.

    http://sdb.suse.de/sdb/en/html/cg_x11numlock.html

    It uses the XTEST extension to generate a press and release of numlock.

    However, that got me to thinking: the lock keys on Sun keyboards don't
    physically lock, that's handled in software. So I commented out the
    second call to XTestFakeKeyEvent (the one that generates the release),
    and it worked!

    Unfortunately, it doesn't turn on the numlock light. But someone could
    fix that if they wanted to; setting the lights is easy enough. However,
    there's probably no portable way to do it, since XGetKeyboardControl(3)
    says "No standard interpretation of LEDs is defined.", i.e. which LED
    is the NumLock LED varies across different implementations of the X server.

    One could maybe come up with a proper way of doing it all by enabling and
    using the X keyboard extension, but to my mind, that's not quite ready for
    prime time yet (still too many quirks), although it's getting better.
     
    Richard L. Hamilton, Nov 20, 2003
    #3
  4. I modified the original considerably, and now it should try to do it
    the original way, and if that doesn't work, try to do it without the
    release. That works for me on Solaris; it should also work on Linux,
    but I don't have anything to test it on.

    I also added some code that on Solaris only will turn on the NumLock LED.
    It uses a hard-coded table of server vendor string vs LED number; that
    could be extended to handle other servers, or other tricks could be added.

    It's probably neither clean nor robust in the face of all possible
    failures, but it seems to work fine.

    Code follows. Remember to link with -lX11 -lXtst (and precede on older
    Solaris with -L/usr/openwin/lib -R/usr/openwin/lib).


    /* numlock.c */
    /*
    * heavily modified version of something seen at
    * http://sdb.suse.de/sdb/en/html/cg_x11numlock.html
    *
    *
    */

    #include <X11/extensions/XTest.h>
    #include <X11/keysym.h>
    #include <stdlib.h>
    #include <string.h>

    #define PRESS 1
    #define RELEASE 2
    #define BOTH (PRESS|RELEASE)

    void
    fake_key_events(Display *disp, int key, int which)
    {
    if (which&PRESS)
    XTestFakeKeyEvent(disp,key,True,CurrentTime);
    if (which&RELEASE)
    XTestFakeKeyEvent(disp,key,False,CurrentTime);
    }

    void
    numlock_on(Display *disp)
    {
    static KeyCode numlock=0;
    static unsigned int numlockmask=0;
    static struct {
    char *name;
    int lednum;
    } vendor2NumLockLED[] = {
    { "Sun Microsystems, Inc.", 1},
    { "The XFree86 Project, Inc", 0}, /* none did it on laptop I tried */
    { NULL, 0 }
    };
    Window rr, cr;
    int rxr, ryr, wxr, wyr, led=0, l;
    unsigned int before, after;
    char *p;

    if (numlock == 0) {
    XModifierKeymap *mk;
    int m, k;

    numlock=XKeysymToKeycode(disp,XK_Num_Lock);
    mk=XGetModifierMapping(disp);
    for (m=0;m<8;m++) {
    for (k=0;k < mk->max_keypermod; k++) {
    if (mk->modifiermap[m*mk->max_keypermod+k]==numlock) {
    numlockmask=(1<<m);
    break;
    }
    }
    }
    XFreeModifiermap(mk);
    if (numlockmask==0) {
    /* num lock key not assigned to any modifier */
    XCloseDisplay(disp);
    exit(2);
    }
    }

    XQueryPointer(disp, DefaultRootWindow(disp),&rr,&cr,&rxr,&ryr,&wxr,&wyr,
    &before);
    before &= numlockmask;

    fake_key_events(disp, numlock, BOTH); /* try like the original version */

    XQueryPointer(disp, DefaultRootWindow(disp),&rr,&cr,&rxr,&ryr,&wxr,&wyr,
    &after);
    after &= numlockmask;

    if (before==after) /* i.e. if that didn't work */
    fake_key_events(disp, numlock, PRESS); /* try just the press */

    /* now take a shot at guessing the right LED for NumLock based on the
    server's vendor string using the hardcoded table previously declared */
    p=ServerVendor(disp);

    for (l=0;vendor2NumLockLED[l].name!=NULL;l++)
    if (!strcmp(p,vendor2NumLockLED[l].name) &&
    vendor2NumLockLED[l].lednum) {
    led=vendor2NumLockLED[l].lednum;
    break;
    }

    if (led) {
    XKeyboardControl values;
    values.led=led;
    values.led_mode=LedModeOn;
    XChangeKeyboardControl(disp,KBLed|KBLedMode,&values);
    }
    }

    int
    main(int argc, char **argv)
    {
    Display *disp = XOpenDisplay(NULL);
    if (disp == NULL)
    return 1;

    numlock_on(disp);

    XCloseDisplay(disp);

    return 0;
    }
     
    Richard L. Hamilton, Nov 20, 2003
    #4
  5. (Richard L. Hamilton) writes in comp.sys.sun.hardware:
    |Unfortunately, it doesn't turn on the numlock light. But someone could
    |fix that if they wanted to; setting the lights is easy enough. However,
    |there's probably no portable way to do it, since XGetKeyboardControl(3)
    |says "No standard interpretation of LEDs is defined.", i.e. which LED
    |is the NumLock LED varies across different implementations of the X server.

    For XFree86, using XKB should get you the LED mappings. For Xsun when
    XKB is not enabled (the default on current releases), there is a way to
    find out - _SUN_LED_MAP. I don't think it's really documented (it's
    mentioned without details in the keytables in /usr/openwin/etc/keytables
    ), but there is some sample code out there using it:
    http://www.mit.edu/afs/sipb/project/xview/src/clients/olwm/client.c

    You would look for which one has the value XK_Num_Lock. On my system,
    xprop -root shows:
    _SUN_LED_MAP(INTEGER) = 4, 65407, 65312, 65300, 65509, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

    /usr/include/X11/keysymdef.h says:
    #define XK_Num_Lock 0xFF7F

    which translates to 65407 decimal, or LED #1. (Of course grepping
    through the keytables, it looks like 1 is the only value we ever use, so
    hardcoding it works just as well.)
     
    Alan Coopersmith, Nov 20, 2003
    #5
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.