2010-07-12 79 views

回答

4

我找到了一個很好的解決方案。 這是一個由Jay Bromley撰寫的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 

你可以閱讀源代碼,並發現了一些其他有用的功能。 編譯獨立版本,你需要取消評論「INT主」出現在「XKeyboard.cpp」功能(或寫自己的main.cpp)和使用出頭這樣的:

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

我不確定X11庫函數是什麼,但setxkbmap是我用來實現它的bash命令。也許沿着這些線查找會找到你想要的(或者只需執行bash命令即可)。

setxkbmap dvorak 
setxkbmap us 

編輯: 後setxkbmap的strace的不轉了什麼有用的東西,我建議只是打電話:

system(「setxkbmap us」); 
+0

您至少可以將這個答案改爲「查看setxkbmap的源代碼」。我昨天會公佈答案 - 如果只有我有時間找到消息來源。同樣在KDE/Gnome/Xfce中檢查鍵盤切換小程序的來源。 – Dummy00001 2010-07-13 12:41:39

+0

是的,它可以工作,但如果在計算機上安裝了多個組,則使用「setxkbmap us」將禁用所有其他語言。 – 2010-07-18 08:15:50

+0

@ Dummy00001:在問這個問題之前,我先看看setxkbmap的源代碼,這對我的Linux編程知識來說是非常「低級的」! – 2010-07-18 08:16:19

2

純X11 API解決方案應該是這個樣子:

#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)英文dvorak佈局。

0

昨天我試圖讓Google的xsecurelock的auto layuout切換到EN。我嘗試找到一些現有的X11 api解決方案,但是...

所以我決定在S. Razi的幫助下編寫自己的解決方案。 下面是代碼:(用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 =「英語」之類的佈局的名稱(exmp:「俄羅斯」),而這個簡單的代碼將切換您當前的佈局:)