]> git.karo-electronics.de Git - gbdfed.git/blob - grayswatch.c
Fixup several compile faults due to changes in recent distributions,
[gbdfed.git] / grayswatch.c
1 /*
2  * Copyright 2008 Department of Mathematical Sciences, New Mexico State University
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * DEPARTMENT OF MATHEMATICAL SCIENCES OR NEW MEXICO STATE UNIVERSITY BE
18  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
19  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  */
22
23 #include <stdio.h>
24 #include <string.h>
25 #include <gtk/gtkdrawingarea.h>
26 #include <gtk/gtkspinbutton.h>
27 #include "grayswatch.h"
28
29 #ifdef ENABLE_NLS
30 #include <libintl.h>
31 #define _(s) dgettext(GETTEXT_PACKAGE,s)
32 #else
33 #define _(s) (s)
34 #endif
35
36 static GtkVBoxClass *parent_class = 0;
37
38 #define SWATCH_MIN_WIDTH  20
39 #define SWATCH_MIN_HEIGHT 100
40
41 /*
42  * Argument types.
43  */
44 enum {
45     PROP_0 = 0,
46     PROP_GRAYLEVEL
47 };
48
49 /*
50  * Signal names.
51  */
52 enum {
53     VALUE_CHANGED = 0
54 };
55
56 static guint grayswatch_signals[VALUE_CHANGED + 1];
57
58 /**************************************************************************
59  *
60  * Class functions.
61  *
62  **************************************************************************/
63
64 static void
65 value_changed(GtkSpinButton *b, gpointer data)
66 {
67     gint v;
68     Grayswatch *gs = GRAYSWATCH(data);
69     GtkWidget *sw = gs->swatch;
70
71     v = gtk_spin_button_get_value_as_int(b);
72
73     gs->gray = v;
74
75     memset(gs->image, v, gs->image_size);
76
77     if (GTK_WIDGET_DRAWABLE(sw))
78       gdk_draw_gray_image(sw->window,
79                           sw->style->fg_gc[GTK_WIDGET_STATE(sw)],
80                           GTK_CONTAINER(gs)->border_width,
81                           GTK_CONTAINER(gs)->border_width,
82                           sw->allocation.width, sw->allocation.height,
83                           GDK_RGB_DITHER_NONE, gs->image,
84                           sw->allocation.width);
85
86     if (gs->signal_blocked == FALSE)
87       /*
88        * Now we emit the value_changed signal for this widget.
89        */
90       g_signal_emit(G_OBJECT(data), grayswatch_signals[VALUE_CHANGED], 0, v);
91 }
92
93 /**************************************************************************
94  *
95  * Class functions.
96  *
97  **************************************************************************/
98
99 static gboolean
100 grayswatch_configure(GtkWidget *widget, GdkEventConfigure *event,
101                      gpointer data)
102 {
103     Grayswatch *gs = GRAYSWATCH(data);
104     gint nbytes;
105
106     nbytes = gs->swatch->allocation.width *
107         gs->swatch->allocation.height;
108     if (nbytes > gs->image_size) {
109         if (gs->image_size == 0)
110           gs->image = (guchar *) g_malloc(nbytes);
111         else
112           gs->image = (guchar *) g_realloc(gs->image, nbytes);
113         gs->image_size = nbytes;
114     }
115     memset(gs->image, gs->gray, gs->image_size);
116
117     return FALSE;
118 }
119
120 static gboolean
121 grayswatch_expose(GtkWidget *widget, GdkEventExpose *event, gpointer data)
122 {
123     Grayswatch *gs = GRAYSWATCH(data);
124
125     if (gs->image_size > 0)
126       gdk_draw_gray_image(widget->window,
127                           widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
128                           GTK_CONTAINER(gs)->border_width,
129                           GTK_CONTAINER(gs)->border_width,
130                           widget->allocation.width,
131                           widget->allocation.height,
132                           GDK_RGB_DITHER_NONE, gs->image,
133                           widget->allocation.width);
134
135     return FALSE;
136 }
137
138 static void
139 grayswatch_get_property(GObject *obj, guint propid, GValue *val,
140                         GParamSpec *pspec)
141 {
142     Grayswatch *gs;
143
144     gs = GRAYSWATCH(obj);
145
146     if (propid == PROP_GRAYLEVEL)
147       g_value_set_uint(val, gs->gray);
148 }
149
150 static void
151 grayswatch_set_property(GObject *obj, guint propid, const GValue *val,
152                         GParamSpec *pspec)
153 {
154     Grayswatch *gs;
155     guint gray;
156
157     gs = GRAYSWATCH(obj);
158
159     if (propid == PROP_GRAYLEVEL) {
160         gray = g_value_get_uint(val);
161         if (gray > 255)
162           gray = 255;
163         if (gray != gs->gray)
164           gtk_spin_button_set_value(GTK_SPIN_BUTTON(gs->value),
165                                     (gdouble) gray);
166     }
167 }
168
169 static void
170 grayswatch_add(GtkContainer *container, GtkWidget *child)
171 {
172     /*
173      * This is here as a placeholder as it seems the container doesn't
174      * work quite right without it for some reason.
175      */
176 }
177
178 static void
179 grayswatch_remove(GtkContainer *container, GtkWidget *child)
180 {
181     /*
182      * This is here as a placeholder as it seems the container doesn't
183      * work quite right without it for some reason.
184      */
185 }
186
187 static void
188 grayswatch_foreach(GtkContainer *container, gboolean int_kids,
189                    GtkCallback callback, gpointer callback_data)
190 {
191     Grayswatch *gs = GRAYSWATCH(container);
192
193     if (callback != 0) {
194         (*callback)(gs->swatch, callback_data);
195         (*callback)(gs->value, callback_data);
196     }
197 }
198
199 /**************************************************************************
200  *
201  * Class and object initialization routines.
202  *
203  **************************************************************************/
204
205 static void
206 grayswatch_class_init(gpointer g_class, gpointer class_data)
207 {
208     GtkContainerClass *cc = GTK_CONTAINER_CLASS(g_class);
209     GObjectClass *oc = G_OBJECT_CLASS(g_class);
210
211     cc->forall = grayswatch_foreach;
212     cc->add = grayswatch_add;
213     cc->remove = grayswatch_remove;
214
215     oc->set_property = grayswatch_set_property;
216     oc->get_property = grayswatch_get_property;
217
218     g_object_class_install_property(oc, PROP_GRAYLEVEL,
219                                     g_param_spec_uint("grayLevel",
220                                                       _("GrayLevel"),
221                                                       _("The gray level."),
222                                                       0, 255, 0,
223                                                       G_PARAM_READWRITE));
224
225     grayswatch_signals[VALUE_CHANGED] =
226         g_signal_new("value-changed",
227                      G_TYPE_FROM_CLASS(oc),
228                      G_SIGNAL_RUN_FIRST,
229                      G_STRUCT_OFFSET(GrayswatchClass, value_changed),
230                      NULL, NULL,
231                      g_cclosure_marshal_VOID__INT,
232                      G_TYPE_NONE, 1, G_TYPE_INT);
233
234     parent_class = g_type_class_peek_parent(g_class);
235 }
236
237 static void
238 grayswatch_init(GTypeInstance *obj, gpointer klass)
239 {
240     Grayswatch *gs = GRAYSWATCH(obj);
241
242     GTK_WIDGET_SET_FLAGS(obj, GTK_NO_WINDOW);
243     gtk_widget_set_redraw_on_allocate(GTK_WIDGET(obj), FALSE);
244
245     gs->swatch = gtk_drawing_area_new();
246     g_signal_connect(G_OBJECT(gs->swatch), "configure_event",
247                      G_CALLBACK(grayswatch_configure), (gpointer) gs);
248     g_signal_connect(G_OBJECT(gs->swatch), "expose_event",
249                      G_CALLBACK(grayswatch_expose), (gpointer) gs);
250     gtk_box_pack_start(GTK_BOX(obj), gs->swatch, TRUE, TRUE, 0);
251     gtk_widget_show(gs->swatch);
252
253     gs->value = gtk_spin_button_new_with_range(0.0, 255.0, 1.0);
254     g_signal_connect(G_OBJECT(gs->value), "value-changed",
255                      G_CALLBACK(value_changed), (gpointer) gs);
256
257     gtk_box_pack_start(GTK_BOX(obj), gs->value, FALSE, FALSE, 0);
258     gtk_widget_show(gs->value);
259
260     gs->gray = 0;
261     gs->image_size = 0;
262     gs->image = NULL;
263 }
264
265 /**************************************************************************
266  *
267  * API functions.
268  *
269  **************************************************************************/
270
271 static const GTypeInfo grayswatch_info = {
272     sizeof(GrayswatchClass),
273     NULL,
274     NULL,
275     grayswatch_class_init,
276     NULL,
277     NULL,
278     sizeof(Grayswatch),
279     0,
280     grayswatch_init,
281 };
282
283 GType
284 grayswatch_get_type(void)
285 {
286     static GType grayswatch_type = 0;
287
288     if (!grayswatch_type)
289       grayswatch_type = g_type_register_static(GTK_TYPE_VBOX,
290                                                "Grayswatch",
291                                                &grayswatch_info, 0);
292
293     return grayswatch_type;
294 }
295
296 GtkWidget *
297 grayswatch_new(guint gray)
298 {
299     return gtk_widget_new(grayswatch_get_type(),
300                           "grayLevel", gray, NULL);
301 }
302
303 void
304 grayswatch_set_gray(Grayswatch *gs, guint gray)
305 {
306     g_return_if_fail(gs != 0);
307     g_return_if_fail(IS_GRAYSWATCH(gs));
308
309     if (gray > 255)
310       gray = 255;
311
312     gtk_spin_button_set_value(GTK_SPIN_BUTTON(gs->value), gray);
313 }
314
315 guint
316 grayswatch_get_gray(Grayswatch *gs)
317 {
318     g_return_val_if_fail(gs != 0, 256);
319     g_return_val_if_fail(IS_GRAYSWATCH(gs), 256);
320
321     return gs->gray;
322 }
323
324 void
325 grayswatch_block_signal(Grayswatch *gs, gboolean block)
326 {
327     g_return_if_fail(gs != 0);
328     g_return_if_fail(IS_GRAYSWATCH(gs));
329
330     gs->signal_blocked = block;
331 }