1 /**
2  * \brief   Helper functions for resource widgets
3  *
4  * \author  Bas Wassink <b.wassink@ziggo.nl>
5  */
6 
7 /*
8  * This file is part of VICE, the Versatile Commodore Emulator.
9  * See README for copyright notice.
10  *
11  *  This program is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; either version 2 of the License, or
14  *  (at your option) any later version.
15  *
16  *  This program is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *
21  *  You should have received a copy of the GNU General Public License
22  *  along with this program; if not, write to the Free Software
23  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
24  *  02111-1307  USA.
25  */
26 
27 #include "vice.h"
28 #include <gtk/gtk.h>
29 #include "lib.h"
30 #include "resources.h"
31 
32 #include "resourcehelpers.h"
33 
34 
35 /** \brief  Set property \a key of \a widget to integer \a value
36  *
37  * Sets \a key to \a value using g_object_set_data(). Since this is a simple
38  * scalar, it shouldn't be freed.
39  *
40  * \param[in,out]   widget  widget
41  * \param[in]       key     property name
42  * \param[in]       value   property value
43  */
resource_widget_set_int(GtkWidget * widget,const char * key,int value)44 void resource_widget_set_int(GtkWidget *widget, const char *key, int value)
45 {
46     g_object_set_data(G_OBJECT(widget), key, GINT_TO_POINTER(value));
47 }
48 
49 
50 /** \brief  Get integer value of  property \a key of \a widget
51  *
52  * \param[in,out]   widget  widget
53  * \param[in]       key     property name
54  *
55  * \return  integer value of property \a key
56  */
resource_widget_get_int(GtkWidget * widget,const char * key)57 int resource_widget_get_int(GtkWidget *widget, const char *key)
58 {
59     return GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), key));
60 }
61 
62 
63 /** \brief  Set property \a key of \a widget to string \a value
64  *
65  * Sets \a key to \a value using g_object_set_data() using lib_strdup(), so
66  * this function can be called with temporary data from the caller.
67  * Needs to be freed with resource_widget_free_string().
68  *
69  * \param[in,out]   widget  widget
70  * \param[in]       key     property name
71  * \param[in]       value   property value
72  */
resource_widget_set_string(GtkWidget * widget,const char * key,const char * value)73 void resource_widget_set_string(GtkWidget *widget,
74                                 const char *key,
75                                 const char *value)
76 {
77     g_object_set_data(G_OBJECT(widget), key,
78             (gpointer)lib_strdup(value != NULL ? value : ""));
79 }
80 
81 
82 /** \brief  Get string value for property \a key of \a widget
83  *
84  * \param[in]   widget  widget
85  * \param[in]   key     property name
86  *
87  * \return  value for \a key
88  */
resource_widget_get_string(GtkWidget * widget,const char * key)89 const char *resource_widget_get_string(GtkWidget *widget, const char *key)
90 {
91     return (const char *)g_object_get_data(G_OBJECT(widget), key);
92 }
93 
94 
95 /** \brief  Free memory used by property \a key in \a widget
96  *
97  * Frees the string allocated on the heap by lib_strdup().
98  *
99  * \param[in,out]   widget  widget
100  * \param[in]       key     property name
101  */
resource_widget_free_string(GtkWidget * widget,const char * key)102 void resource_widget_free_string(GtkWidget *widget, const char *key)
103 {
104     /* free(NULL) is valid, so this is safe */
105     lib_free(g_object_get_data(G_OBJECT(widget), key));
106 }
107 
108 
109 /** \brief  Set the "ResourceName" property of \a widget to \a resoucre
110  *
111  * Stores a copy of \a resource in \a widget using lib_strdup()
112  *
113  * \param[in]   widget      widget
114  * \param[in]   resource    resource name
115  */
resource_widget_set_resource_name(GtkWidget * widget,const char * resource)116 void resource_widget_set_resource_name(GtkWidget *widget, const char *resource)
117 {
118     resource_widget_set_string(widget, "ResourceName", resource);
119 }
120 
121 
122 /** \brief  Get name of resource currently registerd to \a widget
123  *
124  * \param[in]   widget  widget
125  *
126  * \return  value of the "ResourceName" property of \a widget
127  */
resource_widget_get_resource_name(GtkWidget * widget)128 const char *resource_widget_get_resource_name(GtkWidget *widget)
129 {
130     return resource_widget_get_string(widget, "ResourceName");
131 }
132 
133 
134 /** \brief  Free memory used by the "ResourceName" property of \a widget
135  *
136  * \param[in,out]   widget  widget
137  */
resource_widget_free_resource_name(GtkWidget * widget)138 void resource_widget_free_resource_name(GtkWidget *widget)
139 {
140     resource_widget_free_string(widget, "ResourceName");
141 }
142 
143 
144 /** \brief  Register the reset(), factory() and sync() methods for \a widget
145  *
146  * \param[in,out]   widget  vice resource widget
147  * \param[in]       reset   reset() method pointer
148  * \param[in]       factory factory() method pointer
149  * \param[in]       sync    sync() method pointer
150  */
resource_widget_register_methods(GtkWidget * widget,gboolean (* reset)(GtkWidget *),gboolean (* factory)(GtkWidget *),gboolean (* sync)(GtkWidget *))151 void resource_widget_register_methods(
152         GtkWidget *widget,
153         gboolean (*reset)(GtkWidget *),
154         gboolean (*factory)(GtkWidget *),
155         gboolean (*sync)(GtkWidget *))
156 {
157     g_object_set_data(G_OBJECT(widget), "MethodReset", (gpointer)reset);
158     g_object_set_data(G_OBJECT(widget), "MethodFactory", (gpointer)factory);
159     g_object_set_data(G_OBJECT(widget), "MethodSync", (gpointer)sync);
160 }
161 
162 
163 /** \brief  Get the \a method function pointer of \a widget
164  *
165  * Tries to retrieve the \a method from the data in \a widget as set by
166  * resource_widget_register_methods() and stores the function pointer in
167  * \a func.
168  *
169  * On error this function returns FALSE and \a func  is set to `NULL`.
170  *
171  * \param[in]   widget  resource widget to retrieve the \a method from
172  * \param[out]  func    object to store the function pointer
173  * \param[in]   method  name of the method (ie "MethodSync", "MethodReset", etc)
174  *
175  * \return  bool
176  */
resource_widget_get_method_helper(GtkWidget * widget,gboolean * (* func)(GtkWidget *),const char * method)177 static gboolean resource_widget_get_method_helper(
178         GtkWidget *widget,
179         gboolean *(*func)(GtkWidget *),
180         const char *method)
181 {
182     return FALSE;
183 }
184 
185 
186 /** \brief  Get the reset method of \a widget
187  *
188  * \param[in]   widget  resource widget
189  * \param[out]  reset   object to store the reset() function pointer
190  *
191  * \return bool
192  */
resource_widget_get_method_reset(GtkWidget * widget,gboolean * (* reset)(GtkWidget *))193 gboolean resource_widget_get_method_reset(
194         GtkWidget *widget,
195         gboolean *(*reset)(GtkWidget *))
196 {
197     return resource_widget_get_method_helper(widget, reset, "MethodReset");
198 }
199 
200 
201 /** \brief  Get the factory method of \a widget
202  *
203  * \param[in]   widget  resource widget
204  * \param[out]  factory object to store the factory() function pointer
205  *
206  * \return bool
207  */
resource_widget_get_method_factory(GtkWidget * widget,gboolean * (* factory)(GtkWidget *))208 gboolean resource_widget_get_method_factory(
209         GtkWidget *widget,
210         gboolean *(*factory)(GtkWidget *))
211 {
212     return resource_widget_get_method_helper(widget, factory, "MethodFactory");
213 }
214 
215 
216 /** \brief  Get the sync method of \a widget
217  *
218  * \param[in]   widget  resource widget
219  * \param[out]  sync    object to store the sync() function pointer
220  *
221  * \return bool
222  */
resource_widget_get_method_sync(GtkWidget * widget,gboolean * (* sync)(GtkWidget *))223 gboolean resource_widget_get_method_sync(
224         GtkWidget *widget,
225         gboolean *(*sync)(GtkWidget *))
226 {
227     return resource_widget_get_method_helper(widget, sync, "MethodReset");
228 }
229 
230 
231 /** \brief  Set the AutoUpdate property of \a widget to \a state
232  *
233  * The AutoUpdate property decides whether a resource-bound widget updates its
234  * value when it changes. This is TRUE by default.
235  *
236  * \param[in,out]   widget  resource-bound widget
237  * \param[in]       state   do auto-update
238  */
resource_widget_set_auto_update(GtkWidget * widget,gboolean state)239 void resource_widget_set_auto_update(GtkWidget *widget, gboolean state)
240 {
241     resource_widget_set_int(widget, "AutoUpdate", (int)state);
242 }
243 
244 
245 /** \brief  Get the AutoUpdate property of \a widget to \a state
246  *
247  * The AutoUpdate property decides whether a resource-bound widget updates its
248  * value when it changes. This is TRUE by default.
249  *
250  * \param[in,out]   widget  resource-bound widget
251  *
252  * \return  auto-update state
253  */
resource_widget_get_auto_update(GtkWidget * widget)254 gboolean resource_widget_get_auto_update(GtkWidget *widget)
255 {
256     return (gboolean)resource_widget_get_int(widget, "AutoUpdate");
257 }
258