How to change Keyboard Layout (a X11 API solution)

前端 未结 4 2217
Happy的楠姐
Happy的楠姐 2020-12-17 05:15

I want to change keyboard layout in Linux by programming, What X11\'s API function does this?

4条回答
  •  旧巷少年郎
    2020-12-17 06:09

    Yesterday I was trying to make auto layuout switcher to EN for Google's xsecurelock. I tryed to find some existing solutions for X11 api, but...

    So I decided to write my own with some help from S. Razi. Here is the code: (run with gcc -lX11)

    #include 
    #include 
    #include 
    
    int main(){
    
    Display* _display;
    char* displayName = "";
    _display = XOpenDisplay(displayName);
    
    int _deviceId = XkbUseCoreKbd;
    int i = 0;
    int _groupCount = 0;
    
    XkbDescRec* kbdDescPtr = XkbAllocKeyboard();
    if (kbdDescPtr == NULL) {
    printf("%s\n", "Failed to get keyboard description."); 
    return False;
    }
    
    kbdDescPtr->dpy = _display;
    if (_deviceId != XkbUseCoreKbd) {
        kbdDescPtr->device_spec = _deviceId;
    }
    
    XkbGetControls(_display, XkbAllControlsMask, kbdDescPtr);
    XkbGetNames(_display, XkbSymbolsNameMask, kbdDescPtr);
    XkbGetNames(_display, XkbGroupNamesMask, kbdDescPtr);
    
             /* count groups */
    
    Atom* groupSource = kbdDescPtr->names->groups;
    if (kbdDescPtr->ctrls != NULL) {
        _groupCount = kbdDescPtr->ctrls->num_groups;
    } else {
        _groupCount = 0;
        while (_groupCount < XkbNumKbdGroups &&
               groupSource[_groupCount] != 0) {
            _groupCount++;
        }
    }
    
            /* get group names */
    Atom* tmpGroupSource = kbdDescPtr->names->groups;
    Atom curGroupAtom;
    char* groupName;
    for (i = 0; i < _groupCount; i++) {
        if ((curGroupAtom = tmpGroupSource[i]) != None) {
            char* groupNameC = XGetAtomName(_display, curGroupAtom);
                if (groupNameC == NULL) {
                continue;
    
            } else {
                groupName =  groupNameC;
                char *temp = "English";
    
                if (strncmp(temp, groupName, 7) == 0){
                    printf ("%s\n", groupName);
                    printf ("%d\n", i);
                    XkbLockGroup(_display, _deviceId, i);
                    XFree(groupNameC);
                    XCloseDisplay(_display);
                }
                return 0;
            }
        } 
    }
    }
    

    Here you can change char* temp = "English" to name of the group of your layout (exmp: "Russian"), and this simple code will switch your current layout :)

提交回复
热议问题