CI: Use git master for xkeyboard-config on Linux
[platform/upstream/libxkbcommon.git] / tools / tools-common.c
1 /*
2  * Copyright © 2009 Dan Nicholson <dbn.lists@gmail.com>
3  * Copyright © 2012 Intel Corporation
4  * Copyright © 2012 Ran Benita <ran234@gmail.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  *
23  * Except as contained in this notice, the names of the authors or their
24  * institutions shall not be used in advertising or otherwise to promote the
25  * sale, use or other dealings in this Software without prior written
26  * authorization from the authors.
27  *
28  * Author: Dan Nicholson <dbn.lists@gmail.com>
29  *         Daniel Stone <daniel@fooishbar.org>
30  *         Ran Benita <ran234@gmail.com>
31  */
32
33 #include "config.h"
34
35 #include <errno.h>
36 #include <limits.h>
37 #include <fcntl.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <sys/types.h>
41 #include <sys/stat.h>
42 #ifdef _WIN32
43 #include <io.h>
44 #include <windows.h>
45 #else
46 #include <unistd.h>
47 #include <termios.h>
48 #endif
49
50 #include "tools-common.h"
51
52 void
53 tools_print_keycode_state(struct xkb_state *state,
54                           struct xkb_compose_state *compose_state,
55                           xkb_keycode_t keycode,
56                           enum xkb_consumed_mode consumed_mode)
57 {
58     struct xkb_keymap *keymap;
59
60     xkb_keysym_t sym;
61     const xkb_keysym_t *syms;
62     int nsyms;
63     char s[16];
64     xkb_layout_index_t layout;
65     enum xkb_compose_status status;
66
67     keymap = xkb_state_get_keymap(state);
68
69     nsyms = xkb_state_key_get_syms(state, keycode, &syms);
70
71     if (nsyms <= 0)
72         return;
73
74     status = XKB_COMPOSE_NOTHING;
75     if (compose_state)
76         status = xkb_compose_state_get_status(compose_state);
77
78     if (status == XKB_COMPOSE_COMPOSING || status == XKB_COMPOSE_CANCELLED)
79         return;
80
81     if (status == XKB_COMPOSE_COMPOSED) {
82         sym = xkb_compose_state_get_one_sym(compose_state);
83         syms = &sym;
84         nsyms = 1;
85     }
86     else if (nsyms == 1) {
87         sym = xkb_state_key_get_one_sym(state, keycode);
88         syms = &sym;
89     }
90
91     printf("keysyms [ ");
92     for (int i = 0; i < nsyms; i++) {
93         xkb_keysym_get_name(syms[i], s, sizeof(s));
94         printf("%-*s ", (int) sizeof(s), s);
95     }
96     printf("] ");
97
98     if (status == XKB_COMPOSE_COMPOSED)
99         xkb_compose_state_get_utf8(compose_state, s, sizeof(s));
100     else
101         xkb_state_key_get_utf8(state, keycode, s, sizeof(s));
102     printf("unicode [ %s ] ", s);
103
104     layout = xkb_state_key_get_layout(state, keycode);
105     printf("layout [ %s (%d) ] ",
106            xkb_keymap_layout_get_name(keymap, layout), layout);
107
108     printf("level [ %d ] ",
109            xkb_state_key_get_level(state, keycode, layout));
110
111     printf("mods [ ");
112     for (xkb_mod_index_t mod = 0; mod < xkb_keymap_num_mods(keymap); mod++) {
113         if (xkb_state_mod_index_is_active(state, mod,
114                                           XKB_STATE_MODS_EFFECTIVE) <= 0)
115             continue;
116         if (xkb_state_mod_index_is_consumed2(state, keycode, mod,
117                                              consumed_mode))
118             printf("-%s ", xkb_keymap_mod_get_name(keymap, mod));
119         else
120             printf("%s ", xkb_keymap_mod_get_name(keymap, mod));
121     }
122     printf("] ");
123
124     printf("leds [ ");
125     for (xkb_led_index_t led = 0; led < xkb_keymap_num_leds(keymap); led++) {
126         if (xkb_state_led_index_is_active(state, led) <= 0)
127             continue;
128         printf("%s ", xkb_keymap_led_get_name(keymap, led));
129     }
130     printf("] ");
131
132     printf("\n");
133 }
134
135 void
136 tools_print_state_changes(enum xkb_state_component changed)
137 {
138     if (changed == 0)
139         return;
140
141     printf("changed [ ");
142     if (changed & XKB_STATE_LAYOUT_EFFECTIVE)
143         printf("effective-layout ");
144     if (changed & XKB_STATE_LAYOUT_DEPRESSED)
145         printf("depressed-layout ");
146     if (changed & XKB_STATE_LAYOUT_LATCHED)
147         printf("latched-layout ");
148     if (changed & XKB_STATE_LAYOUT_LOCKED)
149         printf("locked-layout ");
150     if (changed & XKB_STATE_MODS_EFFECTIVE)
151         printf("effective-mods ");
152     if (changed & XKB_STATE_MODS_DEPRESSED)
153         printf("depressed-mods ");
154     if (changed & XKB_STATE_MODS_LATCHED)
155         printf("latched-mods ");
156     if (changed & XKB_STATE_MODS_LOCKED)
157         printf("locked-mods ");
158     if (changed & XKB_STATE_LEDS)
159         printf("leds ");
160     printf("]\n");
161 }
162
163 #ifdef _WIN32
164 void
165 tools_disable_stdin_echo(void)
166 {
167     HANDLE stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
168     DWORD mode = 0;
169     GetConsoleMode(stdin_handle, &mode);
170     SetConsoleMode(stdin_handle, mode & ~ENABLE_ECHO_INPUT);
171 }
172
173 void
174 tools_enable_stdin_echo(void)
175 {
176     HANDLE stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
177     DWORD mode = 0;
178     GetConsoleMode(stdin_handle, &mode);
179     SetConsoleMode(stdin_handle, mode | ENABLE_ECHO_INPUT);
180 }
181 #else
182 void
183 tools_disable_stdin_echo(void)
184 {
185     /* Same as `stty -echo`. */
186     struct termios termios;
187     if (tcgetattr(STDIN_FILENO, &termios) == 0) {
188         termios.c_lflag &= ~ECHO;
189         (void) tcsetattr(STDIN_FILENO, TCSADRAIN, &termios);
190     }
191 }
192
193 void
194 tools_enable_stdin_echo(void)
195 {
196     /* Same as `stty echo`. */
197     struct termios termios;
198     if (tcgetattr(STDIN_FILENO, &termios) == 0) {
199         termios.c_lflag |= ECHO;
200         (void) tcsetattr(STDIN_FILENO, TCSADRAIN, &termios);
201     }
202 }
203
204 #endif
205
206 int
207 tools_exec_command(const char *prefix, int real_argc, char **real_argv)
208 {
209     char *argv[64] = {NULL};
210     char executable[PATH_MAX];
211     const char *command;
212     int rc;
213
214     if (((size_t)real_argc >= ARRAY_SIZE(argv))) {
215         fprintf(stderr, "Too many arguments\n");
216         return EXIT_INVALID_USAGE;
217     }
218
219     command = real_argv[0];
220
221     rc = snprintf(executable, sizeof(executable),
222                   "%s/%s-%s", LIBXKBCOMMON_TOOL_PATH, prefix, command);
223     if (rc < 0 || (size_t) rc >= sizeof(executable)) {
224         fprintf(stderr, "Failed to assemble command\n");
225         return EXIT_FAILURE;
226     }
227
228     argv[0] = executable;
229     for (int i = 1; i < real_argc; i++)
230         argv[i] = real_argv[i];
231
232     execv(executable, argv);
233     if (errno == ENOENT) {
234         fprintf(stderr, "Command '%s' is not available\n", command);
235         return EXIT_INVALID_USAGE;
236     } else {
237         fprintf(stderr, "Failed to execute '%s' (%s)\n",
238                 command, strerror(errno));
239     }
240
241     return EXIT_FAILURE;
242 }