OLD | NEW |
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chromeos_keyboard.h" | 5 #include "chromeos_keyboard.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include <X11/XKBlib.h> | 9 #include <X11/XKBlib.h> |
10 #include <X11/Xlib.h> | 10 #include <X11/Xlib.h> |
11 #include <glib.h> | 11 #include <glib.h> |
12 #include <stdlib.h> | 12 #include <stdlib.h> |
13 #include <string.h> | 13 #include <string.h> |
14 #include <xkeyboard_config_version.h> | 14 #include <xkeyboard_config_version.h> |
15 | 15 |
16 #include "base/logging.h" | 16 #include "base/logging.h" |
17 #include "base/singleton.h" | 17 #include "base/singleton.h" |
18 #include "base/string_util.h" | 18 #include "base/string_util.h" |
| 19 #include "chromeos/process.h" |
19 | 20 |
20 namespace { | 21 namespace { |
21 | 22 |
22 // The default keyboard layout name in the xorg config file. | 23 // The default keyboard layout name in the xorg config file. |
23 const char kDefaultLayoutName[] = "us"; | 24 const char kDefaultLayoutName[] = "us"; |
24 // The command we use to set the current XKB layout and modifier key mapping. | 25 // The command we use to set the current XKB layout and modifier key mapping. |
25 // TODO(yusukes): Use libxkbfile.so instead of the command (crosbug.com/13105) | 26 // TODO(yusukes): Use libxkbfile.so instead of the command (crosbug.com/13105) |
26 const char kSetxkbmapCommand[] = "/usr/bin/setxkbmap"; | 27 const char kSetxkbmapCommand[] = "/usr/bin/setxkbmap"; |
27 // See the comment at ModifierKey in the .h file. | 28 // See the comment at ModifierKey in the .h file. |
28 chromeos::ModifierKey kCustomizableKeys[] = { | 29 chromeos::ModifierKey kCustomizableKeys[] = { |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 chromeos::SetCapsLockEnabled(false); | 213 chromeos::SetCapsLockEnabled(false); |
213 } | 214 } |
214 | 215 |
215 ExecuteSetLayoutCommand(layouts_to_set); | 216 ExecuteSetLayoutCommand(layouts_to_set); |
216 return true; | 217 return true; |
217 } | 218 } |
218 | 219 |
219 // Executes 'setxkbmap -layout ...' command asynchronously. | 220 // Executes 'setxkbmap -layout ...' command asynchronously. |
220 // TODO(yusukes): Use libxkbfile.so instead of the command (crosbug.com/13105) | 221 // TODO(yusukes): Use libxkbfile.so instead of the command (crosbug.com/13105) |
221 void ExecuteSetLayoutCommand(const std::string& layouts_to_set) { | 222 void ExecuteSetLayoutCommand(const std::string& layouts_to_set) { |
222 gchar* argv[] = { | 223 chromeos::ProcessImpl process; |
223 g_strdup(kSetxkbmapCommand), g_strdup("-layout"), | 224 process.AddArg(kSetxkbmapCommand); |
224 g_strdup(layouts_to_set.c_str()), NULL | 225 process.AddStringOption("-layout", layouts_to_set); |
225 }; | 226 if (!process.Start()) { |
| 227 LOG(ERROR) << "Failed to execute setxkbmap: " << layouts_to_set; |
| 228 return; |
| 229 } |
| 230 // g_child_watch_add is necessary to prevent the process from becoming a |
| 231 // zombie. |
| 232 g_child_watch_add(process.pid(), |
| 233 reinterpret_cast<GChildWatchFunc>(OnSetLayoutFinish), |
| 234 this); |
| 235 process.Release(); // do not kill the setxkbmap process on function exit. |
| 236 } |
226 | 237 |
227 const GSpawnFlags flags = static_cast<GSpawnFlags>( | 238 static void OnSetLayoutFinish(GPid pid, gint status, XKeyboard* self) { |
228 G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL); | 239 DLOG(INFO) << "OnSetLayoutFinish: pid=" << pid; |
229 GError* error = NULL; | |
230 g_spawn_async(NULL, // working_directory | |
231 argv, | |
232 NULL, // envp | |
233 flags, | |
234 NULL, // child_setup | |
235 NULL, // user_data | |
236 NULL, // child_pid | |
237 &error); | |
238 | |
239 for (size_t i = 0; argv[i] != NULL; ++i) { | |
240 g_free(argv[i]); | |
241 } | |
242 if (error) { | |
243 if (error->message) { | |
244 LOG(ERROR) << "Failed to execute setxkbmap: " << error->message; | |
245 } | |
246 g_error_free(error); | |
247 } | |
248 } | 240 } |
249 | 241 |
250 // The XKB layout name which we set last time like "us" and "us(dvorak)". | 242 // The XKB layout name which we set last time like "us" and "us(dvorak)". |
251 std::string current_layout_name_; | 243 std::string current_layout_name_; |
252 // The mapping of modifier keys we set last time. | 244 // The mapping of modifier keys we set last time. |
253 chromeos::ModifierMap current_modifier_map_; | 245 chromeos::ModifierMap current_modifier_map_; |
254 | 246 |
255 DISALLOW_COPY_AND_ASSIGN(XKeyboard); | 247 DISALLOW_COPY_AND_ASSIGN(XKeyboard); |
256 }; | 248 }; |
257 | 249 |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
397 // TODO(yusukes): Remove this function. | 389 // TODO(yusukes): Remove this function. |
398 extern "C" | 390 extern "C" |
399 bool ChromeOSGetAutoRepeatRate(chromeos::AutoRepeatRate* out_rate) { | 391 bool ChromeOSGetAutoRepeatRate(chromeos::AutoRepeatRate* out_rate) { |
400 return XKeyboard::Get()->GetAutoRepeatRate(out_rate); | 392 return XKeyboard::Get()->GetAutoRepeatRate(out_rate); |
401 } | 393 } |
402 | 394 |
403 extern "C" | 395 extern "C" |
404 bool ChromeOSSetAutoRepeatRate(const chromeos::AutoRepeatRate& rate) { | 396 bool ChromeOSSetAutoRepeatRate(const chromeos::AutoRepeatRate& rate) { |
405 return XKeyboard::Get()->SetAutoRepeatRate(rate); | 397 return XKeyboard::Get()->SetAutoRepeatRate(rate); |
406 } | 398 } |
OLD | NEW |