VirtualBox

source: vbox/trunk/src/VBox/Additions/linux/lightdm-greeter/liblightdm-gobject-1.5.0/layout.c@ 56301

Last change on this file since 56301 was 45170, checked in by vboxsync, 12 years ago

Additions/linux: lightdm-greeter to OSE

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.7 KB
Line 
1/* -*- Mode: C; indent-tabs-mode:nil; tab-width:4 -*-
2 *
3 * Copyright (C) 2010 Robert Ancell.
4 * Author: Robert Ancell <[email protected]>
5 *
6 * This library is free software; you can redistribute it and/or modify it under
7 * the terms of the GNU Lesser General Public License as published by the Free
8 * Software Foundation; either version 2 or version 3 of the License.
9 * See http://www.gnu.org/copyleft/lgpl.html the full text of the license.
10 */
11
12#include <libxklavier/xklavier.h>
13
14#include "lightdm/layout.h"
15
16enum {
17 PROP_0,
18 PROP_NAME,
19 PROP_SHORT_DESCRIPTION,
20 PROP_DESCRIPTION
21};
22
23typedef struct
24{
25 gchar *name;
26 gchar *short_description;
27 gchar *description;
28} LightDMLayoutPrivate;
29
30G_DEFINE_TYPE (LightDMLayout, lightdm_layout, G_TYPE_OBJECT);
31
32#define GET_PRIVATE(obj) G_TYPE_INSTANCE_GET_PRIVATE ((obj), LIGHTDM_TYPE_LAYOUT, LightDMLayoutPrivate)
33
34static gboolean have_layouts = FALSE;
35static Display *display = NULL;
36static XklEngine *xkl_engine = NULL;
37static XklConfigRec *xkl_config = NULL;
38static GList *layouts = NULL;
39static LightDMLayout *default_layout = NULL;
40
41static gchar *
42make_layout_string (const gchar *layout, const gchar *variant)
43{
44 if (!layout || layout[0] == 0)
45 return NULL;
46 else if (!variant || variant[0] == 0)
47 return g_strdup (layout);
48 else
49 return g_strdup_printf ("%s\t%s", layout, variant);
50}
51
52static void
53parse_layout_string (const gchar *name, gchar **layout, gchar **variant)
54{
55 gchar **split;
56
57 *layout = NULL;
58 *variant = NULL;
59
60 if (!name)
61 return;
62
63 split = g_strsplit (name, "\t", 2);
64 if (split[0])
65 {
66 *layout = g_strdup (split[0]);
67 if (split[1])
68 *variant = g_strdup (split[1]);
69 }
70 g_strfreev (split);
71}
72
73static void
74variant_cb (XklConfigRegistry *config,
75 const XklConfigItem *item,
76 gpointer data)
77{
78 LightDMLayout *layout;
79 gchar *full_name;
80
81 full_name = make_layout_string (data, item->name);
82
83 layout = g_object_new (LIGHTDM_TYPE_LAYOUT, "name", full_name, "short-description", item->short_description, "description", item->description, NULL);
84 layouts = g_list_append (layouts, layout);
85
86 g_free (full_name);
87}
88
89static void
90layout_cb (XklConfigRegistry *config,
91 const XklConfigItem *item,
92 gpointer data)
93{
94 LightDMLayout *layout;
95
96 layout = g_object_new (LIGHTDM_TYPE_LAYOUT, "name", item->name, "short-description", item->short_description, "description", item->description, NULL);
97 layouts = g_list_append (layouts, layout);
98
99 xkl_config_registry_foreach_layout_variant (config, item->name, variant_cb, (gpointer) item->name);
100}
101
102/**
103 * lightdm_get_layouts:
104 *
105 * Get a list of keyboard layouts to present to the user.
106 *
107 * Return value: (element-type LightDMLayout) (transfer none): A list of #LightDMLayout that should be presented to the user.
108 **/
109GList *
110lightdm_get_layouts (void)
111{
112 XklConfigRegistry *registry;
113
114 if (have_layouts)
115 return layouts;
116
117 display = XOpenDisplay (NULL);
118 xkl_engine = xkl_engine_get_instance (display);
119 xkl_config = xkl_config_rec_new ();
120 if (!xkl_config_rec_get_from_server (xkl_config, xkl_engine))
121 g_warning ("Failed to get Xkl configuration from server");
122
123 registry = xkl_config_registry_get_instance (xkl_engine);
124 xkl_config_registry_load (registry, FALSE);
125 xkl_config_registry_foreach_layout (registry, layout_cb, NULL);
126 g_object_unref (registry);
127
128 have_layouts = TRUE;
129
130 return layouts;
131}
132
133/**
134 * lightdm_set_layout:
135 * @layout: The layout to use
136 *
137 * Set the layout for this session.
138 **/
139void
140lightdm_set_layout (LightDMLayout *dmlayout)
141{
142 XklConfigRec *config;
143 gchar *layout, *variant;
144
145 g_return_if_fail (dmlayout != NULL);
146
147 g_debug ("Setting keyboard layout to '%s'", lightdm_layout_get_name (dmlayout));
148
149 parse_layout_string (lightdm_layout_get_name (dmlayout), &layout, &variant);
150
151 config = xkl_config_rec_new ();
152 config->layouts = g_malloc (sizeof (gchar *) * 2);
153 config->variants = g_malloc (sizeof (gchar *) * 2);
154 config->model = g_strdup (xkl_config->model);
155 config->layouts[0] = layout;
156 config->layouts[1] = NULL;
157 config->variants[0] = variant;
158 config->variants[1] = NULL;
159 if (!xkl_config_rec_activate (config, xkl_engine))
160 g_warning ("Failed to activate XKL config");
161 g_object_unref (config);
162}
163
164/**
165 * lightdm_get_layout:
166 *
167 * Get the current keyboard layout.
168 *
169 * Return value: (transfer none): The currently active layout for this user.
170 **/
171LightDMLayout *
172lightdm_get_layout (void)
173{
174 lightdm_get_layouts ();
175
176 if (layouts && xkl_config && !default_layout)
177 {
178 gchar *full_name;
179 GList *item;
180
181 full_name = make_layout_string (xkl_config->layouts ? xkl_config->layouts[0] : NULL,
182 xkl_config->variants ? xkl_config->variants[0] : NULL);
183
184 for (item = layouts; item; item = item->next)
185 {
186 LightDMLayout *iter_layout = (LightDMLayout *) item->data;
187 if (g_strcmp0 (lightdm_layout_get_name (iter_layout), full_name) == 0)
188 {
189 default_layout = iter_layout;
190 break;
191 }
192 }
193
194 g_free (full_name);
195 }
196
197 return default_layout;
198}
199
200/**
201 * lightdm_layout_get_name:
202 * @layout: A #LightDMLayout
203 *
204 * Get the name of a layout.
205 *
206 * Return value: The name of the layout
207 **/
208const gchar *
209lightdm_layout_get_name (LightDMLayout *layout)
210{
211 g_return_val_if_fail (LIGHTDM_IS_LAYOUT (layout), NULL);
212 return GET_PRIVATE (layout)->name;
213}
214
215/**
216 * lightdm_layout_get_short_description:
217 * @layout: A #LightDMLayout
218 *
219 * Get the short description of a layout.
220 *
221 * Return value: A short description of the layout
222 **/
223const gchar *
224lightdm_layout_get_short_description (LightDMLayout *layout)
225{
226 g_return_val_if_fail (LIGHTDM_IS_LAYOUT (layout), NULL);
227 return GET_PRIVATE (layout)->short_description;
228}
229
230/**
231 * lightdm_layout_get_description:
232 * @layout: A #LightDMLayout
233 *
234 * Get the long description of a layout.
235 *
236 * Return value: A long description of the layout
237 **/
238const gchar *
239lightdm_layout_get_description (LightDMLayout *layout)
240{
241 g_return_val_if_fail (LIGHTDM_IS_LAYOUT (layout), NULL);
242 return GET_PRIVATE (layout)->description;
243}
244
245static void
246lightdm_layout_init (LightDMLayout *layout)
247{
248}
249
250static void
251lightdm_layout_set_property (GObject *object,
252 guint prop_id,
253 const GValue *value,
254 GParamSpec *pspec)
255{
256 LightDMLayout *self = LIGHTDM_LAYOUT (object);
257 LightDMLayoutPrivate *priv = GET_PRIVATE (self);
258
259 switch (prop_id) {
260 case PROP_NAME:
261 g_free (priv->name);
262 priv->name = g_strdup (g_value_get_string (value));
263 break;
264 case PROP_SHORT_DESCRIPTION:
265 g_free (priv->short_description);
266 priv->short_description = g_strdup (g_value_get_string (value));
267 break;
268 case PROP_DESCRIPTION:
269 g_free (priv->description);
270 priv->description = g_strdup (g_value_get_string (value));
271 break;
272 default:
273 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
274 break;
275 }
276}
277
278static void
279lightdm_layout_get_property (GObject *object,
280 guint prop_id,
281 GValue *value,
282 GParamSpec *pspec)
283{
284 LightDMLayout *self;
285
286 self = LIGHTDM_LAYOUT (object);
287
288 switch (prop_id) {
289 case PROP_NAME:
290 g_value_set_string (value, lightdm_layout_get_name (self));
291 break;
292 case PROP_SHORT_DESCRIPTION:
293 g_value_set_string (value, lightdm_layout_get_short_description (self));
294 break;
295 case PROP_DESCRIPTION:
296 g_value_set_string (value, lightdm_layout_get_description (self));
297 break;
298 default:
299 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
300 break;
301 }
302}
303
304static void
305lightdm_layout_class_init (LightDMLayoutClass *klass)
306{
307 GObjectClass *object_class = G_OBJECT_CLASS (klass);
308
309 g_type_class_add_private (klass, sizeof (LightDMLayoutPrivate));
310
311 object_class->set_property = lightdm_layout_set_property;
312 object_class->get_property = lightdm_layout_get_property;
313
314 g_object_class_install_property (object_class,
315 PROP_NAME,
316 g_param_spec_string ("name",
317 "name",
318 "Name of the layout",
319 NULL,
320 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
321 g_object_class_install_property (object_class,
322 PROP_SHORT_DESCRIPTION,
323 g_param_spec_string ("short-description",
324 "short-description",
325 "Short description of the layout",
326 NULL,
327 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
328 g_object_class_install_property (object_class,
329 PROP_DESCRIPTION,
330 g_param_spec_string ("description",
331 "description",
332 "Long description of the layout",
333 NULL,
334 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
335}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette