2010-07-12 3 views

ответ

4

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

source code

Это очень проста в использовании:

#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 

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

g++ *.cpp -o getxkblayout -L/usr/lib -lX11 
2

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

Пример

setxkbmap dvorak 
setxkbmap us 

EDIT: После Трассирование из setxkbmap не оказаться ничего полезного я предлагаю просто звоню:

system(“setxkbmap us”); 
+0

вы могли бы хотя бы перефразировать ответ, чтобы он звучал как «посмотрите в исходный код setxkbmap». Я бы опубликовал ответ вчера - если бы у меня было время найти источники. Аналогично проверяем источники апплетов клавиатуры в KDE/Gnome/Xfce. – Dummy00001

+0

Да, это работает, но если на компьютере установлено более одной группы, то использование «setxkbmap us» отключит все остальные языки. –

+0

@ Dummy00001: Я изучаю исходный код setxkbmap, прежде чем задавать этот вопрос, это очень «низкий уровень» для моих знаний по программированию Linux! –

2

Чистый раствор 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); 
} 

Compile с -lX11 флагом

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

0

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

Поэтому я решил написать свою помощь с помощью С. Рази. Вот код: (запуск с 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; 
     } 
    } 
} 
} 

Здесь вы можете изменить символ * Темп = «английский язык» для имени группы макета (exmp: «Русский»), и это просто код переключит ваш текущий макет :)