xref: /titanic_41/usr/src/cmd/hal/probing/xkb/probe-xkb.c (revision c7e764a768ca0fd0b1061d79d1d33548a9ad15b4)
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
drop_privileges()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
get_kbd_layout_type(char * device_file,int * kbd_type,int * kbd_layout)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 *
skipwhite(char * ptr)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 *
getaline(FILE * fp)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
sun_find_xkbnames(int kb_type,int kb_layout,char ** xkb_keymap,char ** xkb_model,char ** xkb_layout)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
main(int argc,char * argv[])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