]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blob - liblightdm-gobject/layout.c
add variants to layout list too
[sojka/lightdm.git] / liblightdm-gobject / layout.c
1 /*
2  * Copyright (C) 2010 Robert Ancell.
3  * Author: Robert Ancell <robert.ancell@canonical.com>
4  * 
5  * This library is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU Lesser General Public License as published by the Free
7  * Software Foundation; either version 3 of the License, or (at your option) any
8  * later version. See http://www.gnu.org/copyleft/lgpl.html the full text of the
9  * license.
10  */
11
12 #include <libxklavier/xklavier.h>
13
14 #include "lightdm/layout.h"
15
16 enum {
17     PROP_0,
18     PROP_NAME,
19     PROP_SHORT_DESCRIPTION,
20     PROP_DESCRIPTION
21 };
22
23 typedef struct
24 {
25     gchar *name;
26     gchar *short_description;
27     gchar *description;
28 } LightDMLayoutPrivate;
29
30 G_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
34 static gboolean have_layouts = FALSE;
35 static Display *display = NULL;
36 static XklEngine *xkl_engine = NULL;
37 static XklConfigRec *xkl_config = NULL;
38 static GList *layouts = NULL;
39
40 static void
41 variant_cb (XklConfigRegistry *config,
42            const XklConfigItem *item,
43            gpointer data)
44 {
45     LightDMLayout *layout;
46
47     layout = g_object_new (LIGHTDM_TYPE_LAYOUT, "name", item->name, "short-description", item->short_description, "description", item->description, NULL);
48     layouts = g_list_append (layouts, layout);
49 }
50
51 static void
52 layout_cb (XklConfigRegistry *config,
53            const XklConfigItem *item,
54            gpointer data)
55 {
56     LightDMLayout *layout;
57
58     layout = g_object_new (LIGHTDM_TYPE_LAYOUT, "name", item->name, "short-description", item->short_description, "description", item->description, NULL);
59     layouts = g_list_append (layouts, layout);
60
61     xkl_config_registry_foreach_layout_variant (config, item->name, variant_cb, NULL);
62 }
63
64 /**
65  * lightdm_get_layouts:
66  *
67  * Get a list of keyboard layouts to present to the user.
68  *
69  * Return value: (element-type LightDMLayout) (transfer none): A list of #LightDMLayout that should be presented to the user.
70  **/
71 GList *
72 lightdm_get_layouts (void)
73 {
74     XklConfigRegistry *registry;
75
76     if (have_layouts)
77         return layouts;
78
79     display = XOpenDisplay (NULL);
80     xkl_engine = xkl_engine_get_instance (display);
81     xkl_config = xkl_config_rec_new ();
82     if (!xkl_config_rec_get_from_server (xkl_config, xkl_engine))
83         g_warning ("Failed to get Xkl configuration from server");
84
85     registry = xkl_config_registry_get_instance (xkl_engine);
86     xkl_config_registry_load (registry, FALSE);
87     xkl_config_registry_foreach_layout (registry, layout_cb, NULL);
88     g_object_unref (registry);
89
90     have_layouts = TRUE;
91
92     return layouts;
93 }
94
95 /**
96  * lightdm_set_layout:
97  * @layout: The layout to use
98  *
99  * Set the layout for this session.
100  **/
101 void
102 lightdm_set_layout (LightDMLayout *layout)
103 {
104     XklConfigRec *config;
105
106     g_return_if_fail (layout != NULL);
107
108     g_debug ("Setting keyboard layout to %s", lightdm_layout_get_name (layout));
109
110     config = xkl_config_rec_new ();
111     config->layouts = g_malloc (sizeof (gchar *) * 2);
112     config->model = g_strdup (xkl_config->model);
113     config->layouts[0] = g_strdup (lightdm_layout_get_name (layout));
114     config->layouts[1] = NULL;
115     if (!xkl_config_rec_activate (config, xkl_engine))
116         g_warning ("Failed to activate XKL config");
117     g_object_unref (config);
118 }
119
120 /**
121  * lightdm_get_layout:
122  *
123  * Get the current keyboard layout.
124  *
125  * Return value: (transfer none): The currently active layout for this user.
126  **/
127 LightDMLayout *
128 lightdm_get_layout (void)
129 {
130     lightdm_get_layouts ();
131     if (layouts)
132         return (LightDMLayout *) g_list_first (layouts)->data;
133     else
134         return NULL;
135 }
136
137 /**
138  * lightdm_layout_get_name:
139  * @layout: A #LightDMLayout
140  * 
141  * Get the name of a layout.
142  * 
143  * Return value: The name of the layout
144  **/
145 const gchar *
146 lightdm_layout_get_name (LightDMLayout *layout)
147 {
148     g_return_val_if_fail (LIGHTDM_IS_LAYOUT (layout), NULL);
149     return GET_PRIVATE (layout)->name;
150 }
151
152 /**
153  * lightdm_layout_get_short_description:
154  * @layout: A #LightDMLayout
155  * 
156  * Get the short description of a layout.
157  *
158  * Return value: A short description of the layout
159  **/
160 const gchar *
161 lightdm_layout_get_short_description (LightDMLayout *layout)
162 {
163     g_return_val_if_fail (LIGHTDM_IS_LAYOUT (layout), NULL);
164     return GET_PRIVATE (layout)->short_description;
165 }
166
167 /**
168  * lightdm_layout_get_description:
169  * @layout: A #LightDMLayout
170  * 
171  * Get the long description of a layout.
172  * 
173  * Return value: A long description of the layout
174  **/
175 const gchar *
176 lightdm_layout_get_description (LightDMLayout *layout)
177 {
178     g_return_val_if_fail (LIGHTDM_IS_LAYOUT (layout), NULL);
179     return GET_PRIVATE (layout)->description;
180 }
181
182 static void
183 lightdm_layout_init (LightDMLayout *layout)
184 {
185 }
186
187 static void
188 lightdm_layout_set_property (GObject      *object,
189                          guint         prop_id,
190                          const GValue *value,
191                          GParamSpec   *pspec)
192 {
193     LightDMLayout *self = LIGHTDM_LAYOUT (object);
194     LightDMLayoutPrivate *priv = GET_PRIVATE (self);
195
196     switch (prop_id) {
197     case PROP_NAME:
198         g_free (priv->name);
199         priv->name = g_strdup (g_value_get_string (value));
200         break;
201     case PROP_SHORT_DESCRIPTION:
202         g_free (priv->short_description);
203         priv->short_description = g_strdup (g_value_get_string (value));
204         break;
205     case PROP_DESCRIPTION:
206         g_free (priv->description);
207         priv->description = g_strdup (g_value_get_string (value));
208         break;
209     default:
210         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
211         break;
212     }
213 }
214
215 static void
216 lightdm_layout_get_property (GObject    *object,
217                          guint       prop_id,
218                          GValue     *value,
219                          GParamSpec *pspec)
220 {
221     LightDMLayout *self;
222
223     self = LIGHTDM_LAYOUT (object);
224
225     switch (prop_id) {
226     case PROP_NAME:
227         g_value_set_string (value, lightdm_layout_get_name (self));
228         break;
229     case PROP_SHORT_DESCRIPTION:
230         g_value_set_string (value, lightdm_layout_get_short_description (self));
231         break;
232     case PROP_DESCRIPTION:
233         g_value_set_string (value, lightdm_layout_get_description (self));
234         break;
235     default:
236         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
237         break;
238     }
239 }
240
241 static void
242 lightdm_layout_class_init (LightDMLayoutClass *klass)
243 {
244     GObjectClass *object_class = G_OBJECT_CLASS (klass);
245   
246     g_type_class_add_private (klass, sizeof (LightDMLayoutPrivate));
247
248     object_class->set_property = lightdm_layout_set_property;
249     object_class->get_property = lightdm_layout_get_property;
250
251     g_object_class_install_property (object_class,
252                                      PROP_NAME,
253                                      g_param_spec_string ("name",
254                                                           "name",
255                                                           "Name of the layout",
256                                                           NULL,
257                                                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
258     g_object_class_install_property (object_class,
259                                      PROP_SHORT_DESCRIPTION,
260                                      g_param_spec_string ("short-description",
261                                                           "short-description",
262                                                           "Short description of the layout",
263                                                           NULL,
264                                                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
265     g_object_class_install_property (object_class,
266                                      PROP_DESCRIPTION,
267                                      g_param_spec_string ("description",
268                                                           "description",
269                                                           "Long description of the layout",
270                                                           NULL,
271                                                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
272 }