Add to git.
[monolith.git] / src / ml_widget.c
1 /* Monolith widget class.
2  * - by Richard W.M. Jones <rich@annexia.org>
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 Free
16  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  *
18  * $Id: ml_widget.c,v 1.5 2002/11/29 10:43:03 rich Exp $
19  */
20
21 #include "config.h"
22
23 #include <stdlib.h>
24 #include <stdarg.h>
25
26 #ifdef HAVE_ASSERT_H
27 #include <assert.h>
28 #endif
29
30 #ifdef HAVE_STRING_H
31 #include <string.h>
32 #endif
33
34 #include "monolith.h"
35 #include "ml_widget.h"
36
37 /* This is what generic widget objects *actually* look like. */
38 struct widget
39 {
40   struct ml_widget_operations *ops;
41 };
42
43 void
44 ml_widget_repaint (void *vw, ml_session session, const char *windowid,
45                    io_handle io)
46 {
47   struct widget *w = (struct widget *) vw;
48
49   if (w->ops->repaint) w->ops->repaint (vw, session, windowid, io);
50 }
51
52 const struct ml_widget_property *
53 ml_widget_get_properties (void *vw)
54 {
55   struct widget *w = (struct widget *) vw;
56
57   return w->ops->properties;
58 }
59
60 void
61 ml_widget_set_property (void *vw, const char *property_name, ...)
62 {
63   struct widget *w = (struct widget *) vw;
64   struct ml_widget_property *properties = w->ops->properties;
65   va_list args;
66
67   /* If you hit this assertion, then you've tried to set properties
68    * on a widget which isn't property-aware.
69    */
70   assert (properties != 0);
71
72   /* Search for the appropriate property. */
73   while (properties->name)
74     {
75       if (strcmp (properties->name, property_name) == 0)
76         {
77           /* Read-only? */
78           assert (!(properties->flags & ML_PROP_READ_ONLY));
79
80           va_start (args, property_name);
81
82           /* Update it. */
83           switch (properties->type) {
84           case ML_PROP_STRING:
85             {
86               char **v = (char **) (vw + properties->offset);
87               *v = va_arg (args, char *);
88               break;
89             }
90           case ML_PROP_INT:
91             {
92               int *v = (int *) (vw + properties->offset);
93               *v = va_arg (args, int);
94               break;
95             }
96           case ML_PROP_CHAR:
97             {
98               char *v = (char *) (vw + properties->offset);
99               *v = va_arg (args, int); /* sic */
100               break;
101             }
102           case ML_PROP_WIDGET:
103             {
104               ml_widget *v = (ml_widget *) (vw + properties->offset);
105               *v = va_arg (args, ml_widget);
106               break;
107             }
108           default:
109             abort ();           /* Unknown type. */
110           }
111
112           va_end (args);
113
114           if (properties->on_set) properties->on_set (vw);
115
116           return;
117         }
118
119       properties++;
120     }
121
122   /* If you reach here, then you've tried to update a non-existant
123    * property in a widget.
124    */
125   fprintf (stderr,
126            "ml_widget_set_property: unknown property name: %s\n",
127            property_name);
128   abort ();
129 }
130
131 void
132 _ml_widget_get_property (void *vw, const char *property_name, void *varptr)
133 {
134   struct widget *w = (struct widget *) vw;
135   struct ml_widget_property *properties = w->ops->properties;
136   int size;
137
138   /* If you hit this assertion, then you've tried to get properties
139    * on a widget which isn't property-aware.
140    */
141   assert (properties != 0);
142
143   /* Search for the appropriate property. */
144   while (properties->name)
145     {
146       if (strcmp (properties->name, property_name) == 0)
147         {
148           /* Write-only? */
149           assert (!(properties->flags & ML_PROP_WRITE_ONLY));
150
151           if (properties->on_get) properties->on_get (vw);
152
153           /* Retrieve it. */
154           switch (properties->type) {
155           case ML_PROP_STRING:
156             size = sizeof (char *); break;
157           case ML_PROP_INT:
158             size = sizeof (int); break;
159           case ML_PROP_CHAR:
160             size = sizeof (char); break;
161           case ML_PROP_WIDGET:
162             size = sizeof (ml_widget); break;
163           default:
164             abort ();           /* Unknown type. */
165           }
166
167           memcpy (varptr, vw + properties->offset, size);
168
169           return;
170         }
171
172       properties++;
173     }
174
175   /* If you reach here, then you've tried to update a non-existant
176    * property in a widget.
177    */
178   fprintf (stderr,
179            "_ml_widget_get_property: unknown property name: %s\n",
180            property_name);
181   abort ();
182 }