Find the answer to your Linux question:
Results 1 to 2 of 2
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Linux Enthusiast
    Join Date
    Dec 2011
    Turtle Island West

    ncurses and key modifiers (console/XWindows) - solved

    I don't know if anyone still programs with ncurses these days, but I still use it for applications that don't demand a very sophisticated interface, and it's so easy to get things up and running compared to most of the TKs out there. It can be a very effective prototyping library.

    Anyway, I've been working on a list manager type of thing where I need to select items in a list, then move them around, invert the selection, cut/copy/paste, delete, save to files, load from files, you know, pretty standard stuff.

    "Select All = Control-A" <- no problem
    "Invert Selection = Control-Shift-A" <- fails to work

    ncurses does not support the key modifiers outside of whatever terminfo/termcap provide, and after much googling, I realized you need to do a little hacking to get this to work:

    // For XWindows:
    //     -I/usr/X11R6/include
    //     -L/usr/X11R6/lib -lX11
    // need to be in the Makefile
    #include <X11/Xlib.h>
    // for Linux Console this is all you need
    #include <sys/ioctl.h>
    // X Windows
    #define ShiftMask               (1<<0) // <-
    #define LockMask                (1<<1)
    #define ControlMask             (1<<2) // <-
    #define Mod1Mask                (1<<3)
    #define Mod2Mask                (1<<4)
    #define Mod3Mask                (1<<5)
    #define Mod4Mask                (1<<6)
    #define Mod5Mask                (1<<7)
    // Linux Console
    #define KEYMOD_SHIFT            (1<<0) // <-
    #define KEYMOD_ALTR             (1<<1)
    #define KEYMOD_CONTROL          (1<<2) // <-
    #define KEYMOD_ALTL             (1<<3)
    #define KEYMOD_16               (1<<4)
    #define KEYMOD_32               (1<<5)
    #define KEYMOD_SUPER            (1<<6)
    #define KEYMOD_128              (1<<7)
    unsigned int key_get_mods ( void ) {
        unsigned int mods = 0;
        char * XDisplay = getenv("DISPLAY");
        if ( XDisplay ) { // X must be running
            static Display *display = NULL;
            static Window  rootwin;
            Window root, child;
            int rx, ry, wx, wy;
            unsigned int mask;
            if (!display) {
                int screen;
                display     = XOpenDisplay(NULL);
                screen      = XDefaultScreen(display);
                rootwin     = XRootWindow(display, screen);
            XQueryPointer(display, rootwin,
                          &root, &child,
                          &rx, &ry, &wx, &wy,
                          &mask); // <- this is the one we want
            mods = mask;
        } else { // Linux console
            unsigned char modifiers;
            modifiers = 6;
            if ( ioctl ( 0, TIOCLINUX, &modifiers ) < 0 )
                return 0;
            mods = (unsigned int) modifiers;
        return mods;
    Pretty simple actually, and if all you want is the Control and Shift mods, you can ignore most of the #defines.

    Thought I'd put this out there, maybe save someone some head scratching over the very same topic.

    Peace and Cheer.

  2. #2
    Linux Guru Rubberman's Avatar
    Join Date
    Apr 2009
    I can be found either 40 miles west of Chicago, in Chicago, or in a galaxy far, far away.
    Good post Miven. I've done a lot of curses/ncurses programming in the past, and usually I just did such stuff the hard way. Good example of code that can run in either a console or xwindow.
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts