1b453864fSLin Guo - Sun Microsystems /*************************************************************************** 2b453864fSLin Guo - Sun Microsystems * 3b453864fSLin Guo - Sun Microsystems * probe-xkb.c : Probe for keyboard device information 4b453864fSLin Guo - Sun Microsystems * 5b453864fSLin Guo - Sun Microsystems * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 6b453864fSLin Guo - Sun Microsystems * Use is subject to license terms. 7b453864fSLin Guo - Sun Microsystems * 8b453864fSLin Guo - Sun Microsystems * Licensed under the Academic Free License version 2.1 9b453864fSLin Guo - Sun Microsystems * 10b453864fSLin Guo - Sun Microsystems **************************************************************************/ 11b453864fSLin Guo - Sun Microsystems 12b453864fSLin Guo - Sun Microsystems #ifdef HAVE_CONFIG_H 13b453864fSLin Guo - Sun Microsystems #include <config.h> 14b453864fSLin Guo - Sun Microsystems #endif 15b453864fSLin Guo - Sun Microsystems 16b453864fSLin Guo - Sun Microsystems #include <errno.h> 17b453864fSLin Guo - Sun Microsystems #include <string.h> 18b453864fSLin Guo - Sun Microsystems #include <strings.h> 19b453864fSLin Guo - Sun Microsystems #include <ctype.h> 20b453864fSLin Guo - Sun Microsystems #include <stdlib.h> 21b453864fSLin Guo - Sun Microsystems #include <stdio.h> 22b453864fSLin Guo - Sun Microsystems #include <sys/ioctl.h> 23b453864fSLin Guo - Sun Microsystems #include <sys/stropts.h> 24b453864fSLin Guo - Sun Microsystems #include <fcntl.h> 25b453864fSLin Guo - Sun Microsystems #include <unistd.h> 26b453864fSLin Guo - Sun Microsystems #include <priv.h> 27b453864fSLin Guo - Sun Microsystems 28b453864fSLin Guo - Sun Microsystems #include <sys/kbd.h> 29b453864fSLin Guo - Sun Microsystems #include <sys/kbio.h> 30b453864fSLin Guo - Sun Microsystems 31b453864fSLin Guo - Sun Microsystems #include <libhal.h> 32b453864fSLin Guo - Sun Microsystems #include <logger.h> 33b453864fSLin Guo - Sun Microsystems 34b453864fSLin Guo - Sun Microsystems #define MAXLINELEN 256 35b453864fSLin Guo - Sun Microsystems #define COMMENTCHAR '#' 36b453864fSLin Guo - Sun Microsystems #define KBD_DEFAULT_DEVICE "/dev/kbd" 37b453864fSLin Guo - Sun Microsystems #define XKBTABLE_PATH "/usr/X11/lib/X11/xkb/xkbtable.map" 38b453864fSLin Guo - Sun Microsystems 39b453864fSLin Guo - Sun Microsystems static int global_linenumber = 0; 40b453864fSLin Guo - Sun Microsystems static char line[MAXLINELEN + 1]; 41b453864fSLin Guo - Sun Microsystems 42b453864fSLin Guo - Sun Microsystems static void 43b453864fSLin Guo - Sun Microsystems drop_privileges() 44b453864fSLin Guo - Sun Microsystems { 45b453864fSLin Guo - Sun Microsystems priv_set_t *pPrivSet = NULL; 46b453864fSLin Guo - Sun Microsystems priv_set_t *lPrivSet = NULL; 47b453864fSLin Guo - Sun Microsystems 48b453864fSLin Guo - Sun Microsystems /* 49b453864fSLin Guo - Sun Microsystems * Start with the 'basic' privilege set and then remove any 50b453864fSLin Guo - Sun Microsystems * of the 'basic' privileges that will not be needed. 51b453864fSLin Guo - Sun Microsystems */ 52b453864fSLin Guo - Sun Microsystems if ((pPrivSet = priv_str_to_set("basic", ",", NULL)) == NULL) { 53b453864fSLin Guo - Sun Microsystems HAL_INFO(("Error in setting the priv")); 54b453864fSLin Guo - Sun Microsystems return; 55b453864fSLin Guo - Sun Microsystems } 56b453864fSLin Guo - Sun Microsystems 57b453864fSLin Guo - Sun Microsystems /* Clear privileges we will not need from the 'basic' set */ 58b453864fSLin Guo - Sun Microsystems (void) priv_delset(pPrivSet, PRIV_FILE_LINK_ANY); 59b453864fSLin Guo - Sun Microsystems (void) priv_delset(pPrivSet, PRIV_PROC_INFO); 60b453864fSLin Guo - Sun Microsystems (void) priv_delset(pPrivSet, PRIV_PROC_SESSION); 61b453864fSLin Guo - Sun Microsystems (void) priv_delset(pPrivSet, PRIV_PROC_EXEC); 62b453864fSLin Guo - Sun Microsystems (void) priv_delset(pPrivSet, PRIV_PROC_FORK); 63b453864fSLin Guo - Sun Microsystems 64b453864fSLin Guo - Sun Microsystems (void) priv_addset(pPrivSet, PRIV_SYS_DEVICES); 65b453864fSLin Guo - Sun Microsystems (void) priv_addset(pPrivSet, PRIV_FILE_DAC_READ); 66b453864fSLin Guo - Sun Microsystems 67b453864fSLin Guo - Sun Microsystems /* Set the permitted privilege set. */ 68b453864fSLin Guo - Sun Microsystems if (setppriv(PRIV_SET, PRIV_PERMITTED, pPrivSet) != 0) { 69b453864fSLin Guo - Sun Microsystems return; 70b453864fSLin Guo - Sun Microsystems } 71b453864fSLin Guo - Sun Microsystems 72b453864fSLin Guo - Sun Microsystems /* Clear the limit set. */ 73b453864fSLin Guo - Sun Microsystems if ((lPrivSet = priv_allocset()) == NULL) { 74b453864fSLin Guo - Sun Microsystems return; 75b453864fSLin Guo - Sun Microsystems } 76b453864fSLin Guo - Sun Microsystems 77b453864fSLin Guo - Sun Microsystems priv_emptyset(lPrivSet); 78b453864fSLin Guo - Sun Microsystems 79b453864fSLin Guo - Sun Microsystems if (setppriv(PRIV_SET, PRIV_LIMIT, lPrivSet) != 0) { 80b453864fSLin Guo - Sun Microsystems return; 81b453864fSLin Guo - Sun Microsystems } 82b453864fSLin Guo - Sun Microsystems 83b453864fSLin Guo - Sun Microsystems priv_freeset(lPrivSet); 84b453864fSLin Guo - Sun Microsystems priv_freeset(pPrivSet); 85b453864fSLin Guo - Sun Microsystems } 86b453864fSLin Guo - Sun Microsystems 87b453864fSLin Guo - Sun Microsystems static int 88b453864fSLin Guo - Sun Microsystems get_kbd_layout_type(char *device_file, int *kbd_type, int *kbd_layout) 89b453864fSLin Guo - Sun Microsystems { 90b453864fSLin Guo - Sun Microsystems int ret = 1; 91b453864fSLin Guo - Sun Microsystems int fd = -1; 92b453864fSLin Guo - Sun Microsystems 93b453864fSLin Guo - Sun Microsystems if ((fd = open(device_file, O_RDONLY | O_NONBLOCK)) < 0) { 94b453864fSLin Guo - Sun Microsystems HAL_DEBUG(("Cannot open %s: %s", device_file, strerror(errno))); 95b453864fSLin Guo - Sun Microsystems goto out; 96b453864fSLin Guo - Sun Microsystems } 97b453864fSLin Guo - Sun Microsystems 98b453864fSLin Guo - Sun Microsystems /* 99b453864fSLin Guo - Sun Microsystems * For usb keyboard devices, we need to first push "usbkbm" module upon 100b453864fSLin Guo - Sun Microsystems * the stream. 101b453864fSLin Guo - Sun Microsystems */ 102b453864fSLin Guo - Sun Microsystems if (strstr(device_file, "hid") != NULL) { 103b453864fSLin Guo - Sun Microsystems if (ioctl(fd, I_FIND, "usbkbm") == 0) { 104b453864fSLin Guo - Sun Microsystems (void) ioctl(fd, I_PUSH, "usbkbm"); 105b453864fSLin Guo - Sun Microsystems HAL_DEBUG(("usbkbm module has been pushed %s", strerror(errno))); 106b453864fSLin Guo - Sun Microsystems } 107b453864fSLin Guo - Sun Microsystems } 108b453864fSLin Guo - Sun Microsystems 109b453864fSLin Guo - Sun Microsystems if (ioctl(fd, KIOCTYPE, kbd_type) < 0) { 110b453864fSLin Guo - Sun Microsystems HAL_DEBUG(("get keyboard type failed %s: %s", 111b453864fSLin Guo - Sun Microsystems device_file, strerror(errno))); 112b453864fSLin Guo - Sun Microsystems goto out; 113b453864fSLin Guo - Sun Microsystems } 114b453864fSLin Guo - Sun Microsystems if (ioctl(fd, KIOCLAYOUT, kbd_layout) < 0) { 115b453864fSLin Guo - Sun Microsystems HAL_DEBUG(("get keyboard layout failed %s: %s", 116b453864fSLin Guo - Sun Microsystems device_file, strerror(errno))); 117b453864fSLin Guo - Sun Microsystems goto out; 118b453864fSLin Guo - Sun Microsystems } 119b453864fSLin Guo - Sun Microsystems 120b453864fSLin Guo - Sun Microsystems ret = 0; 121b453864fSLin Guo - Sun Microsystems 122b453864fSLin Guo - Sun Microsystems out: if (fd >= 0) { 123b453864fSLin Guo - Sun Microsystems close(fd); 124b453864fSLin Guo - Sun Microsystems } 125b453864fSLin Guo - Sun Microsystems 126b453864fSLin Guo - Sun Microsystems return (ret); 127b453864fSLin Guo - Sun Microsystems } 128b453864fSLin Guo - Sun Microsystems 129b453864fSLin Guo - Sun Microsystems /* Skips over the white space character in the string. */ 130b453864fSLin Guo - Sun Microsystems static char * 131b453864fSLin Guo - Sun Microsystems skipwhite(char *ptr) 132b453864fSLin Guo - Sun Microsystems { 133b453864fSLin Guo - Sun Microsystems while ((*ptr == ' ') || (*ptr == '\t')) { 134b453864fSLin Guo - Sun Microsystems ptr++; 135b453864fSLin Guo - Sun Microsystems } 136b453864fSLin Guo - Sun Microsystems 137b453864fSLin Guo - Sun Microsystems /* This should not occur. but .. */ 138b453864fSLin Guo - Sun Microsystems if (*ptr == '\n') { 139b453864fSLin Guo - Sun Microsystems ptr = '\0'; 140b453864fSLin Guo - Sun Microsystems } 141b453864fSLin Guo - Sun Microsystems 142b453864fSLin Guo - Sun Microsystems return (ptr); 143b453864fSLin Guo - Sun Microsystems } 144b453864fSLin Guo - Sun Microsystems 145b453864fSLin Guo - Sun Microsystems static char * 146b453864fSLin Guo - Sun Microsystems getaline(FILE *fp) 147b453864fSLin Guo - Sun Microsystems { 148b453864fSLin Guo - Sun Microsystems char *ptr; 149b453864fSLin Guo - Sun Microsystems char *tmp; 150b453864fSLin Guo - Sun Microsystems int index; 151b453864fSLin Guo - Sun Microsystems int c; 152b453864fSLin Guo - Sun Microsystems 153b453864fSLin Guo - Sun Microsystems while (1) { 154b453864fSLin Guo - Sun Microsystems ptr = fgets(line, MAXLINELEN, fp); 155b453864fSLin Guo - Sun Microsystems if (!ptr) { 156b453864fSLin Guo - Sun Microsystems (void) fclose(fp); 157b453864fSLin Guo - Sun Microsystems return (NULL); 158b453864fSLin Guo - Sun Microsystems } 159b453864fSLin Guo - Sun Microsystems 160b453864fSLin Guo - Sun Microsystems global_linenumber++; 161b453864fSLin Guo - Sun Microsystems 162b453864fSLin Guo - Sun Microsystems /* Comment line */ 163b453864fSLin Guo - Sun Microsystems if (ptr[0] == COMMENTCHAR) { 164b453864fSLin Guo - Sun Microsystems continue; 165b453864fSLin Guo - Sun Microsystems } 166b453864fSLin Guo - Sun Microsystems 167b453864fSLin Guo - Sun Microsystems /* Blank line */ 168b453864fSLin Guo - Sun Microsystems if (ptr[0] == '\n') { 169b453864fSLin Guo - Sun Microsystems continue; 170b453864fSLin Guo - Sun Microsystems } 171b453864fSLin Guo - Sun Microsystems 172b453864fSLin Guo - Sun Microsystems if ((tmp = strchr(ptr, '#')) != NULL) { 173b453864fSLin Guo - Sun Microsystems *tmp = '\0'; 174b453864fSLin Guo - Sun Microsystems } 175b453864fSLin Guo - Sun Microsystems 176b453864fSLin Guo - Sun Microsystems if (ptr[strlen(ptr) - 1] == '\n') { 177b453864fSLin Guo - Sun Microsystems /* get rid of '\n' */ 178b453864fSLin Guo - Sun Microsystems ptr[strlen(ptr) - 1] = '\0'; 179b453864fSLin Guo - Sun Microsystems } 180b453864fSLin Guo - Sun Microsystems 181b453864fSLin Guo - Sun Microsystems ptr = skipwhite(ptr); 182b453864fSLin Guo - Sun Microsystems if (*ptr) { 183b453864fSLin Guo - Sun Microsystems break; 184b453864fSLin Guo - Sun Microsystems } 185b453864fSLin Guo - Sun Microsystems } 186b453864fSLin Guo - Sun Microsystems return (ptr); 187b453864fSLin Guo - Sun Microsystems } 188b453864fSLin Guo - Sun Microsystems 189b453864fSLin Guo - Sun Microsystems static int 190b453864fSLin Guo - Sun Microsystems sun_find_xkbnames(int kb_type, int kb_layout, char **xkb_keymap, 191b453864fSLin Guo - Sun Microsystems char **xkb_model, char **xkb_layout) 192b453864fSLin Guo - Sun Microsystems { 193b453864fSLin Guo - Sun Microsystems const char *type, *layout; 194b453864fSLin Guo - Sun Microsystems char *keymap, *defkeymap = NULL; 195b453864fSLin Guo - Sun Microsystems char *model, *defmodel = NULL; 196b453864fSLin Guo - Sun Microsystems char *xkblay, *defxkblay = NULL; 197b453864fSLin Guo - Sun Microsystems FILE *fp; 198b453864fSLin Guo - Sun Microsystems int found_error = 0, found_keytable = 0; 199b453864fSLin Guo - Sun Microsystems int ret = 1; 200b453864fSLin Guo - Sun Microsystems 201b453864fSLin Guo - Sun Microsystems if ((fp = fopen(XKBTABLE_PATH, "r")) == NULL) { 202b453864fSLin Guo - Sun Microsystems return (ret); 203b453864fSLin Guo - Sun Microsystems } 204b453864fSLin Guo - Sun Microsystems 205b453864fSLin Guo - Sun Microsystems global_linenumber = 0; 206b453864fSLin Guo - Sun Microsystems while (getaline(fp)) { 207b453864fSLin Guo - Sun Microsystems if ((type = strtok(line, " \t\n")) == NULL) { 208b453864fSLin Guo - Sun Microsystems found_error = 1; 209b453864fSLin Guo - Sun Microsystems } 210b453864fSLin Guo - Sun Microsystems 211b453864fSLin Guo - Sun Microsystems if ((layout = strtok(NULL, " \t\n")) == NULL) { 212b453864fSLin Guo - Sun Microsystems found_error = 1; 213b453864fSLin Guo - Sun Microsystems } 214b453864fSLin Guo - Sun Microsystems 215b453864fSLin Guo - Sun Microsystems if ((keymap = strtok(NULL, " \t\n")) == NULL) { 216b453864fSLin Guo - Sun Microsystems found_error = 1; 217b453864fSLin Guo - Sun Microsystems } 218b453864fSLin Guo - Sun Microsystems 219b453864fSLin Guo - Sun Microsystems /* These two are optional entries */ 220b453864fSLin Guo - Sun Microsystems model = strtok(NULL, " \t\n"); 221b453864fSLin Guo - Sun Microsystems if ((model == NULL) || (*model == COMMENTCHAR)) { 222b453864fSLin Guo - Sun Microsystems model = xkblay = NULL; 223b453864fSLin Guo - Sun Microsystems } else { 224b453864fSLin Guo - Sun Microsystems xkblay = strtok(NULL, " \t\n"); 225b453864fSLin Guo - Sun Microsystems if ((xkblay != NULL) && (*xkblay == COMMENTCHAR)) { 226b453864fSLin Guo - Sun Microsystems xkblay = NULL; 227b453864fSLin Guo - Sun Microsystems } 228b453864fSLin Guo - Sun Microsystems } 229b453864fSLin Guo - Sun Microsystems 230b453864fSLin Guo - Sun Microsystems if (found_error) { 231b453864fSLin Guo - Sun Microsystems found_error = 0; 232b453864fSLin Guo - Sun Microsystems continue; 233b453864fSLin Guo - Sun Microsystems } 234b453864fSLin Guo - Sun Microsystems 235b453864fSLin Guo - Sun Microsystems /* record default entry if/when found */ 236b453864fSLin Guo - Sun Microsystems if (*type == '*') { 237b453864fSLin Guo - Sun Microsystems if (defkeymap == NULL) { 238*c7e764a7SLin Guo - Sun Microsystems defkeymap = strdup(keymap); 239*c7e764a7SLin Guo - Sun Microsystems defmodel = strdup(model); 240*c7e764a7SLin Guo - Sun Microsystems defxkblay = strdup(xkblay); 241b453864fSLin Guo - Sun Microsystems } 242b453864fSLin Guo - Sun Microsystems } else if (atoi(type) == kb_type) { 243*c7e764a7SLin Guo - Sun Microsystems if (*layout == '*') { 244*c7e764a7SLin Guo - Sun Microsystems defkeymap = strdup(keymap); 245*c7e764a7SLin Guo - Sun Microsystems defmodel = strdup(model); 246*c7e764a7SLin Guo - Sun Microsystems defxkblay = strdup(xkblay); 247b453864fSLin Guo - Sun Microsystems } else if (atoi(layout) == kb_layout) { 248b453864fSLin Guo - Sun Microsystems found_keytable = 1; 249b453864fSLin Guo - Sun Microsystems break; 250b453864fSLin Guo - Sun Microsystems } 251b453864fSLin Guo - Sun Microsystems } 252b453864fSLin Guo - Sun Microsystems } 253b453864fSLin Guo - Sun Microsystems 254b453864fSLin Guo - Sun Microsystems (void) fclose(fp); 255b453864fSLin Guo - Sun Microsystems 256b453864fSLin Guo - Sun Microsystems if (!found_keytable) { 257b453864fSLin Guo - Sun Microsystems keymap = defkeymap; 258b453864fSLin Guo - Sun Microsystems model = defmodel; 259b453864fSLin Guo - Sun Microsystems xkblay = defxkblay; 260b453864fSLin Guo - Sun Microsystems } 261b453864fSLin Guo - Sun Microsystems 262b453864fSLin Guo - Sun Microsystems if ((keymap != NULL) && (strcmp(keymap, "-") != 0)) { 263b453864fSLin Guo - Sun Microsystems *xkb_keymap = keymap; 264b453864fSLin Guo - Sun Microsystems } 265b453864fSLin Guo - Sun Microsystems if ((model != NULL) && (strcmp(model, "-") != 0)) { 266b453864fSLin Guo - Sun Microsystems *xkb_model = model; 267b453864fSLin Guo - Sun Microsystems } 268b453864fSLin Guo - Sun Microsystems if ((xkblay != NULL) && (strcmp(xkblay, "-") != 0)) { 269b453864fSLin Guo - Sun Microsystems *xkb_layout = xkblay; 270b453864fSLin Guo - Sun Microsystems } 271b453864fSLin Guo - Sun Microsystems 272b453864fSLin Guo - Sun Microsystems return (0); 273b453864fSLin Guo - Sun Microsystems } 274b453864fSLin Guo - Sun Microsystems 275b453864fSLin Guo - Sun Microsystems int 276b453864fSLin Guo - Sun Microsystems main(int argc, char *argv[]) 277b453864fSLin Guo - Sun Microsystems { 278b453864fSLin Guo - Sun Microsystems int ret = 1; 279b453864fSLin Guo - Sun Microsystems char *udi; 280b453864fSLin Guo - Sun Microsystems char *device_file; 281b453864fSLin Guo - Sun Microsystems LibHalContext *ctx = NULL; 282b453864fSLin Guo - Sun Microsystems LibHalChangeSet *cs = NULL; 283b453864fSLin Guo - Sun Microsystems DBusError error; 284b453864fSLin Guo - Sun Microsystems int kbd_type, kbd_layout; 285b453864fSLin Guo - Sun Microsystems char *xkbkeymap = NULL, *xkbmodel = NULL, *xkblayout = NULL; 286b453864fSLin Guo - Sun Microsystems 287b453864fSLin Guo - Sun Microsystems if ((udi = getenv("UDI")) == NULL) { 288b453864fSLin Guo - Sun Microsystems goto out; 289b453864fSLin Guo - Sun Microsystems } 290b453864fSLin Guo - Sun Microsystems 291b453864fSLin Guo - Sun Microsystems if ((device_file = getenv("HAL_PROP_INPUT_DEVICE")) == NULL) { 292b453864fSLin Guo - Sun Microsystems goto out; 293b453864fSLin Guo - Sun Microsystems } 294b453864fSLin Guo - Sun Microsystems 295b453864fSLin Guo - Sun Microsystems drop_privileges(); 296b453864fSLin Guo - Sun Microsystems setup_logger(); 297b453864fSLin Guo - Sun Microsystems 298b453864fSLin Guo - Sun Microsystems dbus_error_init(&error); 299b453864fSLin Guo - Sun Microsystems if ((ctx = libhal_ctx_init_direct(&error)) == NULL) { 300b453864fSLin Guo - Sun Microsystems goto out; 301b453864fSLin Guo - Sun Microsystems } 302b453864fSLin Guo - Sun Microsystems 303b453864fSLin Guo - Sun Microsystems if ((cs = libhal_device_new_changeset(udi)) == NULL) { 304b453864fSLin Guo - Sun Microsystems HAL_DEBUG(("Cannot allocate changeset")); 305b453864fSLin Guo - Sun Microsystems goto out; 306b453864fSLin Guo - Sun Microsystems } 307b453864fSLin Guo - Sun Microsystems 308b453864fSLin Guo - Sun Microsystems HAL_DEBUG(("Doing probe-xkb for %s (udi=%s)", device_file, udi)); 309b453864fSLin Guo - Sun Microsystems 310b453864fSLin Guo - Sun Microsystems if (get_kbd_layout_type(device_file, &kbd_type, &kbd_layout)) { 311b453864fSLin Guo - Sun Microsystems goto out; 312b453864fSLin Guo - Sun Microsystems } 313b453864fSLin Guo - Sun Microsystems 314b453864fSLin Guo - Sun Microsystems /* 315b453864fSLin Guo - Sun Microsystems * For some usb keyboard that is not self-identifying, get keyboard's 316b453864fSLin Guo - Sun Microsystems * layout and type from system default keyboard device--/dev/kbd. 317b453864fSLin Guo - Sun Microsystems */ 318b453864fSLin Guo - Sun Microsystems if ((kbd_layout == 0) && (strstr(device_file, "hid") != NULL)) { 319b453864fSLin Guo - Sun Microsystems if (get_kbd_layout_type(KBD_DEFAULT_DEVICE, 320b453864fSLin Guo - Sun Microsystems &kbd_type, &kbd_layout)) { 321b453864fSLin Guo - Sun Microsystems goto out; 322b453864fSLin Guo - Sun Microsystems } 323b453864fSLin Guo - Sun Microsystems } 324b453864fSLin Guo - Sun Microsystems 325b453864fSLin Guo - Sun Microsystems if (sun_find_xkbnames(kbd_type, kbd_layout, 326b453864fSLin Guo - Sun Microsystems &xkbkeymap, &xkbmodel, &xkblayout)) { 327b453864fSLin Guo - Sun Microsystems goto out; 328b453864fSLin Guo - Sun Microsystems } 329b453864fSLin Guo - Sun Microsystems 330*c7e764a7SLin Guo - Sun Microsystems /* 331*c7e764a7SLin Guo - Sun Microsystems * If doesn't find matching entry in xkbtable.map, using default 332*c7e764a7SLin Guo - Sun Microsystems * values setting in 10-x11-input.fdi 333*c7e764a7SLin Guo - Sun Microsystems */ 334*c7e764a7SLin Guo - Sun Microsystems if ((xkbmodel != NULL) && (xkblayout != NULL)) { 335b453864fSLin Guo - Sun Microsystems libhal_changeset_set_property_string(cs, 336b453864fSLin Guo - Sun Microsystems "input.x11_options.XkbModel", xkbmodel); 337b453864fSLin Guo - Sun Microsystems libhal_changeset_set_property_string(cs, 338b453864fSLin Guo - Sun Microsystems "input.x11_options.XkbLayout", xkblayout); 339b453864fSLin Guo - Sun Microsystems 340b453864fSLin Guo - Sun Microsystems libhal_device_commit_changeset(ctx, cs, &error); 341*c7e764a7SLin Guo - Sun Microsystems } 342b453864fSLin Guo - Sun Microsystems 343b453864fSLin Guo - Sun Microsystems ret = 0; 344b453864fSLin Guo - Sun Microsystems 345b453864fSLin Guo - Sun Microsystems out: 346b453864fSLin Guo - Sun Microsystems if (cs != NULL) { 347b453864fSLin Guo - Sun Microsystems libhal_device_free_changeset(cs); 348b453864fSLin Guo - Sun Microsystems } 349b453864fSLin Guo - Sun Microsystems 350b453864fSLin Guo - Sun Microsystems if (ctx != NULL) { 351b453864fSLin Guo - Sun Microsystems libhal_ctx_shutdown(ctx, &error); 352b453864fSLin Guo - Sun Microsystems libhal_ctx_free(ctx); 353b453864fSLin Guo - Sun Microsystems if (dbus_error_is_set(&error)) { 354b453864fSLin Guo - Sun Microsystems dbus_error_free(&error); 355b453864fSLin Guo - Sun Microsystems } 356b453864fSLin Guo - Sun Microsystems } 357b453864fSLin Guo - Sun Microsystems return (ret); 358b453864fSLin Guo - Sun Microsystems } 359