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