1 /*
2 * Copyright (C) 2018 Red Hat
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17 * 02111-1307, USA.
18 *
19 * Author: Carlos Garnacho <carlosg@gnome.org>
20 */
21
22 #include "clutter-build-config.h"
23
24 #include "clutter-keymap-private.h"
25 #include "clutter-private.h"
26
27 enum
28 {
29 PROP_0,
30
31 PROP_CAPS_LOCK_STATE,
32 PROP_NUM_LOCK_STATE,
33
34 N_PROPS
35 };
36
37 static GParamSpec *obj_props[N_PROPS];
38
39 typedef struct _ClutterKeymapPrivate
40 {
41 gboolean caps_lock_state;
42 gboolean num_lock_state;
43 } ClutterKeymapPrivate;
44
45 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterKeymap, clutter_keymap,
46 G_TYPE_OBJECT)
47
48 enum
49 {
50 STATE_CHANGED,
51 N_SIGNALS
52 };
53
54 static guint signals[N_SIGNALS] = { 0, };
55
56 static void
clutter_keymap_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)57 clutter_keymap_get_property (GObject *object,
58 guint prop_id,
59 GValue *value,
60 GParamSpec *pspec)
61 {
62 ClutterKeymap *keymap = CLUTTER_KEYMAP (object);
63 ClutterKeymapPrivate *priv = clutter_keymap_get_instance_private (keymap);
64
65 switch (prop_id)
66 {
67 case PROP_CAPS_LOCK_STATE:
68 g_value_set_boolean (value, priv->caps_lock_state);
69 break;
70 case PROP_NUM_LOCK_STATE:
71 g_value_set_boolean (value, priv->num_lock_state);
72 break;
73 default:
74 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
75 break;
76 }
77 }
78
79 static void
clutter_keymap_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)80 clutter_keymap_set_property (GObject *object,
81 guint prop_id,
82 const GValue *value,
83 GParamSpec *pspec)
84 {
85 ClutterKeymap *keymap = CLUTTER_KEYMAP (object);
86 ClutterKeymapPrivate *priv = clutter_keymap_get_instance_private (keymap);
87
88 switch (prop_id)
89 {
90 case PROP_CAPS_LOCK_STATE:
91 priv->caps_lock_state = g_value_get_boolean (value);
92 break;
93 case PROP_NUM_LOCK_STATE:
94 priv->num_lock_state = g_value_get_boolean (value);
95 break;
96 default:
97 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
98 break;
99 }
100 }
101
102 static void
clutter_keymap_class_init(ClutterKeymapClass * klass)103 clutter_keymap_class_init (ClutterKeymapClass *klass)
104 {
105 GObjectClass *object_class = G_OBJECT_CLASS (klass);
106
107 object_class->get_property = clutter_keymap_get_property;
108 object_class->set_property = clutter_keymap_set_property;
109
110 obj_props[PROP_CAPS_LOCK_STATE] =
111 g_param_spec_boolean ("caps-lock-state",
112 "Caps lock state",
113 "Caps lock state",
114 FALSE,
115 G_PARAM_READABLE |
116 G_PARAM_STATIC_STRINGS);
117 obj_props[PROP_NUM_LOCK_STATE] =
118 g_param_spec_boolean ("num-lock-state",
119 "Num lock state",
120 "Num lock state",
121 FALSE,
122 G_PARAM_READABLE |
123 G_PARAM_STATIC_STRINGS);
124 g_object_class_install_properties (object_class, N_PROPS, obj_props);
125
126 signals[STATE_CHANGED] =
127 g_signal_new (I_("state-changed"),
128 G_TYPE_FROM_CLASS (klass),
129 G_SIGNAL_RUN_FIRST,
130 0, NULL, NULL,
131 g_cclosure_marshal_VOID__VOID,
132 G_TYPE_NONE, 0);
133 }
134
135 static void
clutter_keymap_init(ClutterKeymap * keymap)136 clutter_keymap_init (ClutterKeymap *keymap)
137 {
138 }
139
140 gboolean
clutter_keymap_get_num_lock_state(ClutterKeymap * keymap)141 clutter_keymap_get_num_lock_state (ClutterKeymap *keymap)
142 {
143 ClutterKeymapPrivate *priv = clutter_keymap_get_instance_private (keymap);
144
145 return priv->num_lock_state;
146 }
147
148 gboolean
clutter_keymap_get_caps_lock_state(ClutterKeymap * keymap)149 clutter_keymap_get_caps_lock_state (ClutterKeymap *keymap)
150 {
151 ClutterKeymapPrivate *priv = clutter_keymap_get_instance_private (keymap);
152
153 return priv->caps_lock_state;
154 }
155
156 PangoDirection
clutter_keymap_get_direction(ClutterKeymap * keymap)157 clutter_keymap_get_direction (ClutterKeymap *keymap)
158 {
159 return CLUTTER_KEYMAP_GET_CLASS (keymap)->get_direction (keymap);
160 }
161
162 void
clutter_keymap_set_lock_modifier_state(ClutterKeymap * keymap,gboolean caps_lock_state,gboolean num_lock_state)163 clutter_keymap_set_lock_modifier_state (ClutterKeymap *keymap,
164 gboolean caps_lock_state,
165 gboolean num_lock_state)
166 {
167 ClutterKeymapPrivate *priv = clutter_keymap_get_instance_private (keymap);
168
169 if (priv->caps_lock_state == caps_lock_state &&
170 priv->num_lock_state == num_lock_state)
171 return;
172
173 if (priv->caps_lock_state != caps_lock_state)
174 {
175 priv->caps_lock_state = caps_lock_state;
176 g_object_notify_by_pspec (G_OBJECT (keymap),
177 obj_props[PROP_CAPS_LOCK_STATE]);
178 }
179
180 if (priv->num_lock_state != num_lock_state)
181 {
182 priv->num_lock_state = num_lock_state;
183 g_object_notify_by_pspec (G_OBJECT (keymap),
184 obj_props[PROP_NUM_LOCK_STATE]);
185 }
186
187 g_debug ("Locks state changed - Num: %s, Caps: %s",
188 priv->num_lock_state ? "set" : "unset",
189 priv->caps_lock_state ? "set" : "unset");
190
191 g_signal_emit (keymap, signals[STATE_CHANGED], 0);
192 }
193