tools: don't mangle the path for tools, just exec directly
[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 <limits.h>
36 #include <fcntl.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #ifdef _MSC_VER
42 #include <io.h>
43 #include <windows.h>
44 #ifndef PATH_MAX
45 #define PATH_MAX MAX_PATH
46 #endif
47 #else
48 #include <unistd.h>
49 #include <termios.h>
50 #endif
51
52 #include "utils.h"
53 #include "tools-common.h"
54
55 void
56 tools_print_keycode_state(struct xkb_state *state,
57                           struct xkb_compose_state *compose_state,
58                           xkb_keycode_t keycode,
59                           enum xkb_consumed_mode consumed_mode)
60 {
61     struct xkb_keymap *keymap;
62
63     xkb_keysym_t sym;
64     const xkb_keysym_t *syms;
65     int nsyms;
66     char s[16];
67     xkb_layout_index_t layout;
68     enum xkb_compose_status status;
69
70     keymap = xkb_state_get_keymap(state);
71
72     nsyms = xkb_state_key_get_syms(state, keycode, &syms);
73
74     if (nsyms <= 0)
75         return;
76
77     status = XKB_COMPOSE_NOTHING;
78     if (compose_state)
79         status = xkb_compose_state_get_status(compose_state);
80
81     if (status == XKB_COMPOSE_COMPOSING || status == XKB_COMPOSE_CANCELLED)
82         return;
83
84     if (status == XKB_COMPOSE_COMPOSED) {
85         sym = xkb_compose_state_get_one_sym(compose_state);
86         syms = &sym;
87         nsyms = 1;
88     }
89     else if (nsyms == 1) {
90         sym = xkb_state_key_get_one_sym(state, keycode);
91         syms = &sym;
92     }
93
94     printf("keysyms [ ");
95     for (int i = 0; i < nsyms; i++) {
96         xkb_keysym_get_name(syms[i], s, sizeof(s));
97         printf("%-*s ", (int) sizeof(s), s);
98     }
99     printf("] ");
100
101     if (status == XKB_COMPOSE_COMPOSED)
102         xkb_compose_state_get_utf8(compose_state, s, sizeof(s));
103     else
104         xkb_state_key_get_utf8(state, keycode, s, sizeof(s));
105     printf("unicode [ %s ] ", s);
106
107     layout = xkb_state_key_get_layout(state, keycode);
108     printf("layout [ %s (%d) ] ",
109            xkb_keymap_layout_get_name(keymap, layout), layout);
110
111     printf("level [ %d ] ",
112            xkb_state_key_get_level(state, keycode, layout));
113
114     printf("mods [ ");
115     for (xkb_mod_index_t mod = 0; mod < xkb_keymap_num_mods(keymap); mod++) {
116         if (xkb_state_mod_index_is_active(state, mod,
117                                           XKB_STATE_MODS_EFFECTIVE) <= 0)
118             continue;
119         if (xkb_state_mod_index_is_consumed2(state, keycode, mod,
120                                              consumed_mode))
121             printf("-%s ", xkb_keymap_mod_get_name(keymap, mod));
122         else
123             printf("%s ", xkb_keymap_mod_get_name(keymap, mod));
124     }
125     printf("] ");
126
127     printf("leds [ ");
128     for (xkb_led_index_t led = 0; led < xkb_keymap_num_leds(keymap); led++) {
129         if (xkb_state_led_index_is_active(state, led) <= 0)
130             continue;
131         printf("%s ", xkb_keymap_led_get_name(keymap, led));
132     }
133     printf("] ");
134
135     printf("\n");
136 }
137
138 void
139 tools_print_state_changes(enum xkb_state_component changed)
140 {
141     if (changed == 0)
142         return;
143
144     printf("changed [ ");
145     if (changed & XKB_STATE_LAYOUT_EFFECTIVE)
146         printf("effective-layout ");
147     if (changed & XKB_STATE_LAYOUT_DEPRESSED)
148         printf("depressed-layout ");
149     if (changed & XKB_STATE_LAYOUT_LATCHED)
150         printf("latched-layout ");
151     if (changed & XKB_STATE_LAYOUT_LOCKED)
152         printf("locked-layout ");
153     if (changed & XKB_STATE_MODS_EFFECTIVE)
154         printf("effective-mods ");
155     if (changed & XKB_STATE_MODS_DEPRESSED)
156         printf("depressed-mods ");
157     if (changed & XKB_STATE_MODS_LATCHED)
158         printf("latched-mods ");
159     if (changed & XKB_STATE_MODS_LOCKED)
160         printf("locked-mods ");
161     if (changed & XKB_STATE_LEDS)
162         printf("leds ");
163     printf("]\n");
164 }
165
166 #ifdef _MSC_VER
167 void
168 tools_disable_stdin_echo(void)
169 {
170     HANDLE stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
171     DWORD mode = 0;
172     GetConsoleMode(stdin_handle, &mode);
173     SetConsoleMode(stdin_handle, mode & ~ENABLE_ECHO_INPUT);
174 }
175
176 void
177 tools_enable_stdin_echo(void)
178 {
179     HANDLE stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
180     DWORD mode = 0;
181     GetConsoleMode(stdin_handle, &mode);
182     SetConsoleMode(stdin_handle, mode | ENABLE_ECHO_INPUT);
183 }
184 #else
185 void
186 tools_disable_stdin_echo(void)
187 {
188     /* Same as `stty -echo`. */
189     struct termios termios;
190     if (tcgetattr(STDIN_FILENO, &termios) == 0) {
191         termios.c_lflag &= ~ECHO;
192         (void) tcsetattr(STDIN_FILENO, TCSADRAIN, &termios);
193     }
194 }
195
196 void
197 tools_enable_stdin_echo(void)
198 {
199     /* Same as `stty echo`. */
200     struct termios termios;
201     if (tcgetattr(STDIN_FILENO, &termios) == 0) {
202         termios.c_lflag |= ECHO;
203         (void) tcsetattr(STDIN_FILENO, TCSADRAIN, &termios);
204     }
205 }
206
207 #endif
208
209 int
210 tools_exec_command(const char *prefix, int real_argc, char **real_argv)
211 {
212     char *argv[64] = {NULL};
213     char executable[PATH_MAX];
214     const char *command;
215
216     if (((size_t)real_argc >= ARRAY_SIZE(argv))) {
217         fprintf(stderr, "Too many arguments\n");
218         return EXIT_INVALID_USAGE;
219     }
220
221     command = real_argv[0];
222 #ifdef _MSC_VER
223 #define PATH_SEP '\\'
224 #else
225 #define PATH_SEP '/'
226 #endif
227
228     if (!snprintf_safe(executable, sizeof(executable),
229                        "%s%c%s-%s", LIBXKBCOMMON_TOOL_PATH, PATH_SEP,
230                        prefix, command)) {
231         fprintf(stderr, "Failed to assemble command\n");
232         return EXIT_FAILURE;
233     }
234
235     argv[0] = executable;
236     for (int i = 1; i < real_argc; i++)
237         argv[i] = real_argv[i];
238
239     execv(executable, argv);
240     if (errno == ENOENT) {
241         fprintf(stderr, "Command '%s' is not available\n", command);
242         return EXIT_INVALID_USAGE;
243     } else {
244         fprintf(stderr, "Failed to execute '%s' (%s)\n",
245                 command, strerror(errno));
246     }
247
248     return EXIT_FAILURE;
249 }