QWS LinuxInput and Hotplugging USB Keyboards



  • For QWS and Embedded Linux, what is the recommended way of supporting USB keyboards that can be added/removed at any time? (I realize that this may be a rather infrequent use case for most Qt Embedded devs.)

    Providing a /dev/input/eventX node to the keyboard driver implemented by qkbdlinuxinput_qws.cpp does not suffice, as it simply spins on the bad file descriptor once the keyboard has been removed, printing "Could not read from input device:" I'm not sure if this should be reported as a bug, or if I should simply be doing things a different way.

    I am considering modifying/extending the qkbdlinuxinput_qws driver to monitor (via inotify) and scan /proc/bus/input for added keyboards, and then switch over to a newly discovered device after the QT_READ() of the current keyboard device fails. This seems like it'd be a bit of a design overhaul (that I don't think would conform with the existing code) to add this recovery functionality, which makes me think there's probably a cleaner (or perhaps pre-existing) solution -- any comments on this?

    Despite it being a referred to as a "hack" in various Linux documentation files, mousedev (mapping all mouse events to a persistent /dev/input/mice) certainly works well for hotplugging USB mice with QWS. If I remember correctly, there was a similar "keybdev" mechanism that fell out of the kernel a while back...not sure if that's worth investigating for new designs now that it's deprecated...

    Obligatory version info: Currently using 4.7.4, but I see that qkbdlinuxinput_qws.cpp hasn't changed too much in 4.8.0.



  • We also ran into this problem and found an easy workaround.

    Instead of providing the input device as a environment variable, the input device can be set at runtime. We use a QFileSystemWatcher to register that the node does not exists anymore and in that case, close the keyboard. It is also possible to register a new input device and then set it as the default keyboard.

    In our case the only keyboard may be at node /dev/input/event1 so the following code snipped (incomplete) works out well for us:

    //Initialization of QFileSystemWatcher somewhere after startup
    {
        pFileSystemWatcher = new QFileSystemWatcher(this);
        pFileSystemWatcher->addPath("/dev/input/");
        connect(pFileSystemWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(on_fileSystemWatcher_directoryChanged(QString)));
        closeKeyboard();
        on_fileSystemWatcher_directoryChanged(QString());
    }
    
    // Slot to receive a removed or added input device
    void on_fileSystemWatcher_directoryChanged(const QString& path) {
        QFileInfo eventFile("/dev/input/event1");
        if (!keyboardPresent && eventFile.exists()) {
            setKeyboard();
        } else if (keyboardPresent && !eventFile.exists()) {
            closeKeyboard();
        }
    }
    
    void setKeyboard() {
        QWSKeyboardHandler *pKeyboardHandler = QKbdDriverFactory::create("LinuxInput", "/dev/input/event1");
        QWSServer* pQwsServer = QWSServer::instance();
        pQwsServer->setKeyboardHandler(pKeyboardHandler);
        keyboardPresent = true;
    }
    
    void closeKeyboard() {
        QWSServer* pQwsServer = QWSServer::instance();
        pQwsServer->closeKeyboard();
        keyboardPresent = false;
    }
    
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.