Как изменить раскладку клавиатуры (решение X11 API) - PullRequest
3 голосов
/ 12 июля 2010

Я хочу изменить раскладку клавиатуры в Linux путем программирования. Какая функция API в X11 делает это?

Ответы [ 4 ]

4 голосов
/ 18 июля 2010

Я нашел одно хорошее решение. Это класс c ++, написанный Джей Бромли, который я могу добавить в свое приложение и использовать его.

исходный код

Это очень удобно:

#include "XKeyboard.h"

XKeyboard xkb;

std::string cGrpName=xkb.currentGroupName(); //return somethings like "USA"
std::string cGrpSymb=xkb.currentGroupSymbol(); //return somethings like "us"

xkb.setGroupByNum(0);//set keyboard layout to first layout in available ones

Вы можете прочитать исходный код и найти некоторые другие полезные функции. для компиляции автономной версии вам нужно откомментировать функцию «int main», присутствующую в «XKeyboard.cpp» (или написать свой собственный main.cpp) и использовать что-то вроде этого:

g++ *.cpp -o getxkblayout -L/usr/lib -lX11
2 голосов
/ 27 мая 2014

Чистое решение API X11 должно выглядеть примерно так:

#include <stdio.h>
#include <X11/XKBlib.h>

int main() {
    Display* _display;
    char* displayName = "";
    _display = XOpenDisplay(displayName);

    XkbDescRec* _kbdDescPtr = XkbAllocKeyboard();
    XkbGetNames(_display, XkbSymbolsNameMask, _kbdDescPtr);
    Atom symName = _kbdDescPtr -> names -> symbols;
    char* layoutString = XGetAtomName(_display, symName);

    XCloseDisplay(_display);
    printf("%s\n", layoutString);
}

Компилировать с -lX11 флагом

Это напечатает что-то вроде pc+us+inet(evdev) для английского (США) макета qwerty, pc+ru+us:2+inet(evdev) для русской раскладки йцукен, pc+us(dvorak)+us:2+inet(evdev) для английской раскладки дворак.

2 голосов
/ 13 июля 2010

Я не уверен, что такое функция библиотеки X11, но setxkbmap - это команда bash, которую я использую для ее достижения.Возможно, поиск по этим линиям найдет то, что вы хотите (или, в крайнем случае, вы можете просто выполнить команду bash).

Пример

setxkbmap dvorak
setxkbmap us

РЕДАКТИРОВАТЬ: ПослеStrace из setxkbmap не нашел ничего полезного, я предлагаю просто позвонить:

system(“setxkbmap us”);
0 голосов
/ 15 декабря 2016

Вчера я пытался сделать автоматический переключатель раскладки на EN для Google xsecurelock.Я пытался найти некоторые существующие решения для API X11, но ...

Поэтому я решил написать свое собственное с помощью С. Рази.Вот код: (запускается с gcc -lX11)

#include <stdio.h>
#include <stdlib.h>
#include <X11/XKBlib.h>

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;
        }
    } 
}
}

Здесь вы можете изменить char * temp = "English" на имя группы вашего макета (например, "русский")простой код переключит ваш текущий макет:)

...