VirtualBox

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

Last change on this file since 96588 was 69506, checked in by vboxsync, 7 years ago

More scm updates

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