1 /*
2 * Copyright 2008 Codethink Ltd.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20 #include <stdio.h>
21 #include <string.h>
22 #include <atk/atk.h>
23
24 #include "my-atk-object.h"
25 #include "my-atk-action.h"
26
27 static GObjectClass *parent_class = NULL;
28 //implementation of the interface
my_atk_action_do_action(AtkAction * action,gint i)29 static gboolean my_atk_action_do_action(AtkAction *action, gint i)
30 {
31 MyAtkAction *self = (MyAtkAction*)action;
32 gboolean result = (i>=0) && (i < self->n);
33 self->last_performed_action = result? i : -1;
34 return result;
35 }
my_atk_action_get_n_actions(AtkAction * action)36 static gint my_atk_action_get_n_actions(AtkAction *action)
37 {
38 MyAtkAction *self = (MyAtkAction*)action;
39 return self->n;
40 }
my_atk_action_get_description(AtkAction * action,gint i)41 static const gchar* my_atk_action_get_description(AtkAction *action, gint i)
42 {
43 MyAtkAction *self = (MyAtkAction*)action;
44 if((i>=0) && (i<self->n))
45 {
46 return self->actions[i].description;
47 }
48 else
49 {
50 printf("get_description: Wrong index.\n");
51 return NULL;
52 }
53 }
my_atk_action_get_name(AtkAction * action,gint i)54 static const gchar* my_atk_action_get_name(AtkAction *action, gint i)
55 {
56 MyAtkAction *self = (MyAtkAction*)action;
57 if((i >= 0) && (i < self->n))
58 {
59 return self->actions[i].name;
60 }
61 else
62 {
63 printf("get_name: Wrong index.\n");
64 return NULL;
65 }
66 }
my_atk_action_get_localized_name(AtkAction * action,gint i)67 static const gchar* my_atk_action_get_localized_name(AtkAction *action, gint i)
68 {
69 return my_atk_action_get_name(action,i);
70 }
71
my_atk_action_get_keybinding(AtkAction * action,gint i)72 static const gchar* my_atk_action_get_keybinding(AtkAction *action, gint i)
73 {
74 MyAtkAction *self = (MyAtkAction*)action;
75 if((i >= 0) && (i < self->n))
76 {
77 gchar* keyb = self->actions[i].keybinding;
78 if(keyb == NULL || keybinding_note_define == NULL)
79 {
80 //anywhere(if action has keybinding or not) NULL will return
81 return NULL;
82 }
83 else
84 {
85 //verify, if string mean "no keybinding"
86 return strcmp(keyb, keybinding_note_define) != 0 ? keyb : NULL;
87 }
88 }
89 else
90 {
91 printf("get_keybinding: Wrong index.\n");
92 return NULL;
93 }
94 }
my_atk_action_set_description(AtkAction * action,gint i,const gchar * desc)95 static gboolean my_atk_action_set_description(AtkAction *action, gint i, const gchar *desc)
96 {
97 MyAtkAction *self = (MyAtkAction*)action;
98
99 if(!((i >= 0) && (i < self->n)) )
100 {
101 //index out of range, but this is not application error according documentation
102 return FALSE;
103 }
104 //index in correct range
105 if(self->actions[i].description == desc)
106 {
107 //self assignment - return immediately
108 return TRUE;
109 }
110 if(self->actions[i].description != NULL)
111 {
112 //free old value of description if it is not NULL
113 free(self->actions[i].description);
114 }
115 if(desc != NULL)
116 {
117 //dump new value of description if it is not NULL
118 self->actions[i].description = (gchar*)strdup((const char*)desc);
119 }
120 return TRUE;
121 }
122 //////////
my_atk_action_instance_init(GTypeInstance * instance,gpointer g_class)123 static void my_atk_action_instance_init(GTypeInstance *instance, gpointer g_class)
124 {
125 int i;
126 MyAtkAction *self = (MyAtkAction*)instance;
127 self->n = DEFAULT_NUMBER_ACTIONS;
128 self->actions = g_new(struct OneAction, self->n);
129 if(self->actions == NULL)
130 {
131 self->n = 0;
132 return;
133 }
134 //init fields of action 0 with values which differ from others actions
135 self->actions[0].name = (gchar*)strdup(FIRST_ACTION_NAME);
136 self->actions[0].description = (gchar*)strdup(FIRST_ACTION_DESCRIPTION);
137 self->actions[0].keybinding = (gchar*)strdup(FIRST_ACTION_KEYBINDING);
138
139 for(i = 1; i < self->n; i++)
140 {
141 self->actions[i].name = (gchar*)strdup(DEFAULT_ACTION_NAME);
142 self->actions[i].description = (gchar*)strdup(DEFAULT_ACTION_DESCRIPTION);
143 self->actions[i].keybinding = g_strdup_printf("%d", i);
144 }
145 self->disposed = FALSE;
146 self->last_performed_action = -1;
147 }
148
149 static void
my_atk_action_interface_init(gpointer g_iface,gpointer iface_data)150 my_atk_action_interface_init(gpointer g_iface, gpointer iface_data)
151 {
152 AtkActionIface *klass = (AtkActionIface *)g_iface;
153
154 klass->do_action = my_atk_action_do_action;
155 klass->get_n_actions = my_atk_action_get_n_actions;
156 klass->get_description = my_atk_action_get_description;
157 klass->get_name = my_atk_action_get_name;
158 klass->get_localized_name = my_atk_action_get_localized_name;
159 klass->get_keybinding = my_atk_action_get_keybinding;
160 klass->set_description = my_atk_action_set_description;
161 }
162
163 static void
my_atk_action_dispose(GObject * obj)164 my_atk_action_dispose(GObject *obj)
165 {
166 MyAtkAction *self = (MyAtkAction*)obj;
167
168 if(self->disposed)
169 {
170 return;
171 }
172 self->disposed = TRUE;
173
174 G_OBJECT_CLASS(parent_class)->dispose(obj);
175 }
176
177 static void
my_atk_action_finalize(GObject * obj)178 my_atk_action_finalize(GObject *obj)
179 {
180 MyAtkAction *self = (MyAtkAction*)obj;
181 int i;
182
183 for(i = 0; i < self->n; i++)
184 {
185 struct OneAction oneAction = self->actions[i];
186 if(oneAction.name != NULL)
187 free(oneAction.name);
188 if(oneAction.description != NULL)
189 free(oneAction.description);
190 if(oneAction.keybinding != NULL)
191 free(oneAction.keybinding);
192 }
193 if(self->actions != NULL)
194 g_free(self->actions);
195
196 G_OBJECT_CLASS(parent_class)->finalize(obj);
197 }
198 static void
my_atk_action_class_init(gpointer g_class,gpointer g_class_data)199 my_atk_action_class_init (gpointer g_class, gpointer g_class_data)
200 {
201 GObjectClass *gobject_class = G_OBJECT_CLASS(g_class);
202 MyAtkActionClass *klass = MY_ATK_ACTION_CLASS (g_class);
203
204 gobject_class->dispose = my_atk_action_dispose;
205 gobject_class->finalize = my_atk_action_finalize;
206
207 parent_class = g_type_class_peek_parent(klass);
208 }
my_atk_action_get_type(void)209 GType my_atk_action_get_type(void)
210 {
211 static GType type = 0;
212 if(type == 0)
213 {
214 static const GTypeInfo info =
215 {
216 sizeof (MyAtkActionClass),
217 NULL, /* base_init */
218 NULL, /* base_finalize */
219 my_atk_action_class_init, /* class_init */
220 NULL, /* class_finalize */
221 NULL, /* class_data */
222 sizeof (MyAtkAction),
223 0, /* n_preallocs */
224 my_atk_action_instance_init /* instance_init */
225 };
226
227 static const GInterfaceInfo iface_info =
228 {
229 (GInterfaceInitFunc) my_atk_action_interface_init, /* interface_init */
230 NULL, /* interface_finalize */
231 NULL /* interface_data */
232 };
233 type = g_type_register_static (MY_TYPE_ATK_OBJECT,
234 "MyAtkAction",
235 &info, 0);
236 g_type_add_interface_static (type,
237 ATK_TYPE_ACTION,
238 &iface_info);
239 }
240 return type;
241 }
242