-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathKeyLayout.cpp
145 lines (108 loc) · 3.57 KB
/
KeyLayout.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "KeyLayout.h"
KeyLayout::KeyLayout()
{
init();
}
KeyLayout::~KeyLayout()
{
}
void KeyLayout::init()
{
// Подключение к рабочему дисплею
display = XOpenDisplay(NULL);
if( display == NULL )
{
printf("Error XOpenDisplay");
exit(1);
}
}
// Получение номера раскладки, которая активна в данный момент
int KeyLayout::getActiveGroup()
{
XkbStateRec state[1];
memset(state, 0, sizeof(state));
XkbGetState(display, XkbUseCoreKbd, state);
return state->group;
}
// Переключение раскладки
// group - номер раскладки (обычно порядковый номер
// в списке включенных раскладок, счет с 0
int KeyLayout::setActiveGroup(int group)
{
// Отправка запроса на переключение раскладки
XkbLockGroup( display, XkbUseCoreKbd, group );
// Вызов XkbGetState() для выполнения запроса,
// без этого вызова переключение раскладки не сработает
XkbStateRec state[1];
memset(state, 0, sizeof(state));
XkbGetState(display, XkbUseCoreKbd, state);
return 0;
}
// Получение списка доступных раскладок клавиатуры
// Массив **names заполняется именами раскладок
// Функция возвращает количество раскладок
int KeyLayout::getLayouts(char **names)
{
XkbDescRec desc[1];
int gc;
memset(desc, 0, sizeof(desc));
desc->device_spec = XkbUseCoreKbd;
XkbGetControls(display, XkbGroupsWrapMask, desc);
XkbGetNames(display, XkbGroupNamesMask, desc);
XGetAtomNames(display, desc->names->groups, gc = desc->ctrls->num_groups, names);
XkbFreeControls(desc, XkbGroupsWrapMask, True);
XkbFreeNames(desc, XkbGroupNamesMask, True);
return gc;
}
// Очистка массива имен доступных раскладок
// Функция получает указатель на массив имен
// И количество доступных раскладок
void KeyLayout::freeLayouts(char **names, int gc)
{
for (; gc--; ++names)
{
if (*names)
{
XFree(*names);
*names = NULL;
}
}
}
void KeyLayout::print()
{
// Массив имен раскладок
char *names[XkbNumKbdGroups];
// Заполнение массива имен раскладок
int gc=getLayouts(names);
// Получение номера активной раскладки
int g=getActiveGroup();
// Печать информации о доступных раскладках
for(int i = 0; i < gc; i++)
{
printf("%d - %s %s\n", i, names[i], i == g ? "(Active)" : "");
}
// Очистка массива имен раскладок
freeLayouts(names, gc);
}
// Получение номера текущей раскладки
int KeyLayout::getLayout()
{
return getActiveGroup();
}
// Включение указанной раскладки
void KeyLayout::setLayout(int n)
{
setActiveGroup(n);
}
// Количество раскладок
int KeyLayout::getLayoutNumber()
{
XkbDescRec desc[1];
memset(desc, 0, sizeof(desc));
desc->device_spec = XkbUseCoreKbd;
XkbGetControls(display, XkbGroupsWrapMask, desc);
return desc->ctrls->num_groups;
}