LINUX.ORG.RU

Библиотека X11 и получение списка языков

 , ,


0

1

Привет всем. Мне необходимо получить список языков установленных в системе. С помощью кода, который привел ниже я могу получать текущий язык раскладки, а как получить список установленных языков ввода - ума не приложу.

XkbStateRec xkbState;
    Display *display = XOpenDisplay(NULL);
    XkbGetState(display, XkbUseCoreKbd, &xkbState);

    Atom real_prop_type; int fmt;
    unsigned long nitems, extra_bytes;
    char *prop_data = NULL;
    Atom rules_atom = XInternAtom(display, "_XKB_RULES_NAMES", False);
    XGetWindowProperty(display, DefaultRootWindow(display), rules_atom, 0L, 1024,
        False, XA_STRING, &real_prop_type, &fmt, &nitems, &extra_bytes, (unsigned char **) (void *) &prop_data);

    QStringList names;
    for(char* p=prop_data; p-prop_data < (long)nitems && p != NULL; p += strlen(p)+1) names.append( p );
    if (names.count() > 3 ) names = names[2].split(",");
    qDebug()<<names;
    qDebug()<<names[xkbState.group];
    XFree(prop_data);
    XCloseDisplay(display);
    languageLabel->setText(names[xkbState.group]);

И таким образом я получаю только сокращенное название языка (us,by,ru), а необходимо получать полное. Буду очень благодарен за помощь! С данной библиотекой никогда ранее не сталкивался, поэтому плохо понимаю, как ей пользоваться адекватно

Ответ на: комментарий от boganet9993

The following members of class QApplication are obsolete. They are provided to keep old source code working. We strongly advise against using them in new code.

(obsolete) QLocale keyboardInputLocale()

QLocale QApplication::keyboardInputLocale()

Returns the current keyboard input locale. Replaced with QInputMethod::locale()

Я не знаю, что это все должно возвращать вообще. Локаль?

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 2)
Ответ на: комментарий от Zubok

Как я понял, возвращает строку с названием текущего языка, но только компилятор выдает только ругань и непонимание, что от него хотят))

boganet9993
() автор топика
Ответ на: комментарий от boganet9993

Как я понял, возвращает строку с названием текущего языка, но только компилятор выдает только ругань и непонимание, что от него хотят))

Так какого языка? Не факт, что эта функция для X11 реализована вообще. Смотря чем ругается компилятор.

Если ты уж лезешь в XKB, то почему оттуда же взять текущую раскладку не хочешь? XkbGetState.

Zubok ★★★★★
()

Держи. Это часть кода, который автоматически переключает языки при переходе на поле ввода с заданным языком.

/*
 * kbdlist.cpp
 * g++ -std=c++11 kbdlist.cpp -o kbdlist -lX11
 */

#include <X11/XKBlib.h>
#include <vector>
#include <string>

#define MY_LOG_ERROR(format, args...) do {} while(0)

#define EXIT_ON_ERROR(val, errval, retval, format, args...) \
{ \
    if((val) == (errval)) \
    { \
        MY_LOG_ERROR(format, ## args); \
        return retval; \
    } \
} while(0)

#define GOTO_ON_ERROR(val, errval, format, args...) do \
{ \
    if((val) == (errval)) \
    { \
        MY_LOG_ERROR(format, ## args); \
        goto on_error; \
    } \
} while(0)


typedef std::vector<std::string> KbdList;

bool FillLayoutList(KbdList& _kbdlist)
{
	Display *_dpy = XOpenDisplay(NULL);
	XkbDescRec desc = {};
	desc.device_spec = XkbUseCoreKbd;
	Status status = XkbGetControls(_dpy, XkbGroupsWrapMask, &desc);
	EXIT_ON_ERROR(status == Success, false, false, "XkbGetControls error %d", status);
	status = XkbGetNames(_dpy, XkbGroupNamesMask, &desc);
	bool res = status == Success;
	GOTO_ON_ERROR(res, false, "XkbGetNames error %d", status);
	_kbdlist.clear();
	for(int i = 0; i < desc.ctrls->num_groups; ++i)
	{
		char *name = XGetAtomName(_dpy, desc.names->groups[i]);
		std::string kbdname(name);
		XFree(name);
		_kbdlist.emplace_back(kbdname);
	}
on_error:
	XkbFreeControls(&desc, XkbGroupsWrapMask, True);
	XkbFreeNames(&desc, XkbGroupNamesMask, True);
	XCloseDisplay(_dpy);
	return res;
}


int main(int argc, char* argv[])
{
	KbdList kbdlist;
	if(FillLayoutList(kbdlist))
		for(auto kbdname : kbdlist)
			printf("%s\n", kbdname.c_str());
	
	return 0;
}
alexku
()

Текущая раскладка

//Добавь в код предыдущего поста
bool GetCurrentLayoutName(KbdList& _kbdlist, std::string &name)
{
	Display *_dpy = XOpenDisplay(NULL);
	EXIT_ON_ERROR(_dpy, 0, false, "Can't open display");
	XkbStateRec xkb_state;
	Status status = XkbGetState(_dpy, XkbUseCoreKbd, &xkb_state);
	bool res = status == Success;
	GOTO_ON_ERROR(res, false, false, "XkbGetState error %d", status);
	name = _kbdlist[xkb_state.locked_group];
on_error:
	XCloseDisplay(_dpy);
	return res;
}

int main(int argc, char* argv[])
{
	KbdList kbdlist;
	if(FillLayoutList(kbdlist))
		for(auto kbdname : kbdlist)
			printf("%s\n", kbdname.c_str());
	
	std::string current;
	if(GetCurrentLayoutName(kbdlist, current))
			printf("Current layout: %s\n", current.c_str());
	
	return 0;
}
alexku
()
5 января 2019 г.
Ответ на: комментарий от boganet9993

Для простоты я бы ориентировался на xkbcomp :0 -xkb - | grep 'name\[group'. Зависит результат от текущей группы или нет?

И да, какая среда? Не гном ли?

svu ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.