source: trunk/third/gtkhtml3/src/gtkhtml-embedded.c @ 19539

Revision 19539, 8.7 KB checked in by ghudson, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r19538, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2/*
3 *  Copyright (C) 2000 Helix Code Inc.
4 *
5 *  Authors: Michael Zucchi <notzed@helixcode.com>
6 *
7 *  An embeddable html widget.
8 *
9 *  This program is free software; you can redistribute it and/or
10 *  modify it under the terms of the GNU Library General Public License
11 *  as published by the Free Software Foundation; either version 2 of
12 *  the License, or (at your option) any later version.
13 *
14 *  This program is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU Library General Public License for more details.
18 *
19 *  You should have received a copy of the GNU Library General Public
20 *  License along with this program; if not, write to the Free Software
21 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <config.h>
25#include <gnome.h>
26
27#include "gtkhtml-embedded.h"
28#include "htmlengine.h"
29
30static void gtk_html_embedded_class_init (GtkHTMLEmbeddedClass *class);
31static void gtk_html_embedded_init       (GtkHTMLEmbedded *gspaper);
32
33static void gtk_html_embedded_size_request (GtkWidget *widget, GtkRequisition *requisition);
34static void gtk_html_embedded_size_allocate (GtkWidget *widget, GtkAllocation *allocation);
35
36/* saved parent calls */
37static void (*old_add)(GtkContainer *container, GtkWidget *child);
38static void (*old_remove)(GtkContainer *container, GtkWidget *child);
39
40static GtkBin *parent_class;
41
42enum {
43        DRAW_GDK,
44        DRAW_PRINT,
45        CHANGED,
46        LAST_SIGNAL
47};
48       
49static guint signals [LAST_SIGNAL] = { 0 };
50
51GType
52gtk_html_embedded_get_type (void)
53{
54        static GType embedded_type = 0;
55 
56        if (!embedded_type) {
57                static const GTypeInfo embedded_info =
58                        {
59                                sizeof (GtkHTMLEmbeddedClass),
60                                NULL,           /* base_init */
61                                NULL,           /* base_finalize */
62                                (GClassInitFunc) gtk_html_embedded_class_init,
63                                NULL,           /* class_finalize */
64                                NULL,           /* class_data */
65                                sizeof (GtkHTMLEmbedded),
66                                4,              /* n_preallocs */
67                                (GInstanceInitFunc) gtk_html_embedded_init,
68                        };
69
70                embedded_type = g_type_register_static (GTK_TYPE_BIN, "GtkHTMLEmbedded", &embedded_info, 0);
71        }
72 
73        return embedded_type;
74}
75
76static void
77free_param(void *key, void *value, void *data)
78{
79        g_free (key);
80        g_free (value);
81}
82
83static void
84gtk_html_embedded_finalize (GObject *object)
85{
86        GtkHTMLEmbedded *eb = GTK_HTML_EMBEDDED(object);
87
88        g_hash_table_foreach (eb->params, free_param, 0);
89        g_hash_table_destroy (eb->params);
90        g_free(eb->classid);
91        g_free(eb->type);
92
93        G_OBJECT_CLASS (parent_class)->finalize (object);
94}
95
96static void
97gtk_html_embedded_changed (GtkHTMLEmbedded *ge)
98{
99        g_signal_emit (ge, signals[CHANGED], 0);
100}
101
102static void gtk_html_embedded_add (GtkContainer *container, GtkWidget *child)
103{
104        g_return_if_fail (container != NULL);
105
106        /* can't add something twice */
107        g_return_if_fail( GTK_BIN(container)->child == NULL );
108
109        old_add(container, child);
110        gtk_html_embedded_changed(GTK_HTML_EMBEDDED(container));
111}
112
113static void gtk_html_embedded_remove (GtkContainer *container, GtkWidget *child)
114{
115        g_return_if_fail (container != NULL);
116        g_return_if_fail( GTK_BIN(container)->child != NULL );
117
118        old_remove(container, child);
119
120        gtk_html_embedded_changed(GTK_HTML_EMBEDDED(container));
121}
122
123typedef void (*draw_print_signal)(GtkObject *, gpointer, gpointer);
124typedef void (*draw_gdk_signal)(GtkObject *, gpointer, gpointer, gint, gint, gpointer);
125
126static void
127draw_gdk_signal_marshaller (GClosure     *closure,
128                            GValue       *return_value,
129                            guint         n_param_values,
130                            const GValue *param_values,
131                            gpointer      invocation_hint,
132                            gpointer      marshal_data)
133{
134        register draw_gdk_signal ff;
135        register GCClosure *cc = (GCClosure*) closure;
136        register gpointer data1, data2;
137
138        g_return_if_fail (n_param_values == 5);
139
140        if (G_CCLOSURE_SWAP_DATA (closure))
141                {
142                        data1 = closure->data;
143                        data2 = g_value_peek_pointer (param_values + 0);
144                }
145        else
146                {
147                        data1 = g_value_peek_pointer (param_values + 0);
148                        data2 = closure->data;
149                }
150        ff = (draw_gdk_signal) (marshal_data ? marshal_data : cc->callback);
151
152        ff (data1,
153            g_value_get_pointer (param_values + 1),
154            g_value_get_pointer (param_values + 2),
155            g_value_get_int (param_values + 3),
156            g_value_get_int (param_values + 4),
157            data2);
158}
159
160static void
161gtk_html_embedded_class_init (GtkHTMLEmbeddedClass *class)
162{
163        GObjectClass *gobject_class;
164        GtkObjectClass *object_class;
165        GtkWidgetClass *widget_class;
166        GtkContainerClass *container_class;
167       
168        gobject_class = G_OBJECT_CLASS (class);
169        object_class = GTK_OBJECT_CLASS (class);
170        widget_class = GTK_WIDGET_CLASS (class);
171        container_class = GTK_CONTAINER_CLASS (class);
172
173        parent_class = gtk_type_class (gtk_bin_get_type ());
174
175        signals [CHANGED] =
176                g_signal_new ("changed",
177                              G_TYPE_FROM_CLASS (object_class),
178                              G_SIGNAL_RUN_FIRST,
179                              G_STRUCT_OFFSET (GtkHTMLEmbeddedClass, changed),
180                              NULL, NULL,
181                              g_cclosure_marshal_VOID__VOID,
182                              G_TYPE_NONE, 0);
183        signals [DRAW_GDK] =
184                g_signal_new ("draw_gdk",
185                              G_TYPE_FROM_CLASS (object_class),
186                              G_SIGNAL_RUN_FIRST,
187                              G_STRUCT_OFFSET (GtkHTMLEmbeddedClass, draw_gdk),
188                              NULL, NULL,
189                              draw_gdk_signal_marshaller, G_TYPE_NONE, 4,
190                              G_TYPE_POINTER, G_TYPE_POINTER,
191                              G_TYPE_INT, G_TYPE_INT);
192       
193        signals [DRAW_PRINT] =
194                g_signal_new ("draw_print",
195                              G_TYPE_FROM_CLASS (object_class),
196                              G_SIGNAL_RUN_FIRST,
197                              G_STRUCT_OFFSET (GtkHTMLEmbeddedClass, draw_print),
198                              NULL, NULL,
199                              g_cclosure_marshal_VOID__POINTER,
200                              G_TYPE_NONE, 1,
201                              G_TYPE_POINTER);
202       
203        gobject_class->finalize = gtk_html_embedded_finalize;
204
205        widget_class->size_request = gtk_html_embedded_size_request;
206        widget_class->size_allocate = gtk_html_embedded_size_allocate;
207
208        old_add = container_class->add;
209        container_class->add = gtk_html_embedded_add;
210        old_remove = container_class->remove;
211        container_class->remove = gtk_html_embedded_remove;
212}
213
214static void
215gtk_html_embedded_size_request (GtkWidget *widget, GtkRequisition *requisition)
216{
217        GtkBin *bin;
218       
219        g_return_if_fail (widget != NULL);
220        g_return_if_fail (requisition != NULL);
221       
222        bin = GTK_BIN (widget);
223
224        if (bin->child) {
225                gtk_widget_size_request (bin->child, requisition);
226        } else {
227                requisition->width = widget->requisition.width;
228                requisition->height = widget->requisition.height;
229        }
230}
231
232static void
233gtk_html_embedded_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
234{
235        GtkBin *bin;
236
237        g_return_if_fail (widget != NULL);
238        g_return_if_fail (allocation != NULL);
239       
240        bin = GTK_BIN (widget);
241
242        if (bin->child && GTK_WIDGET_VISIBLE (bin->child)) {
243                gtk_widget_size_allocate(bin->child, allocation);
244        }
245        widget->allocation = *allocation;
246}
247
248static void
249gtk_html_embedded_init (GtkHTMLEmbedded *ge)
250{
251        ge->descent = 0;
252        ge->params  = g_hash_table_new (g_str_hash, g_str_equal);
253}
254
255/**
256 * gtk_html_embedded_new:
257 *
258 * Create a new GtkHTMLEmbedded widget.
259 * Note that this function should never be called outside of gtkhtml.
260 *
261 * Return value: A new GtkHTMLEmbedded widget.
262 **/
263GtkWidget *
264gtk_html_embedded_new (char *classid, char *name, char *type, char *data, int width, int height)
265{
266        GtkHTMLEmbedded *em;
267
268        em = (GtkHTMLEmbedded *) g_object_new (GTK_TYPE_HTML_EMBEDDED, NULL);
269
270        if (width != -1 || height != -1)
271                gtk_widget_set_size_request (GTK_WIDGET (em), width, height);
272
273        em->width = width;
274        em->height = height;
275        em->type = type ? g_strdup(type) : NULL;
276        em->classid = g_strdup(classid);
277        em->name = g_strdup(name);
278        em->data = g_strdup(data);
279
280        return (GtkWidget *)em;
281}
282
283/**
284 * gtk_html_embedded_get_parameter:
285 * @ge: the #GtkHTMLEmbedded widget.
286 * @param: the parameter to examine.
287 *
288 * Returns: the value of the parameter.
289 */
290char *
291gtk_html_embedded_get_parameter (GtkHTMLEmbedded *ge, char *param)
292{
293        return g_hash_table_lookup (ge->params, param);
294}
295
296/**
297 * gtk_html_embedded_set_parameter:
298 * @ge: The #GtkHTMLEmbedded widget.
299 * @param: the name of the parameter to set.
300 * @value: the value of the parameter.
301 *
302 * The parameter named @name to the @value.
303 */
304void
305gtk_html_embedded_set_parameter (GtkHTMLEmbedded *ge, char *param, char *value)
306{
307        gchar *lookup;
308
309        if (!param)
310                return;
311        lookup = (gchar *) g_hash_table_lookup (ge->params, param);
312        if (lookup)
313                g_free (lookup);
314        g_hash_table_insert (ge->params,
315                             lookup ? param : g_strdup (param),
316                             value  ? g_strdup(value) : NULL);
317}
318
319/**
320 * gtk_html_embedded_set_descent:
321 * @ge: the GtkHTMLEmbedded widget.
322 * @descent: the value of the new descent.
323 *
324 * Set the descent of the widget beneath the baseline.
325 */
326void
327gtk_html_embedded_set_descent (GtkHTMLEmbedded *ge, int descent)
328{
329        if (ge->descent == descent)
330                return;
331
332        ge->descent = descent;
333        gtk_html_embedded_changed (ge);
334}
335
Note: See TracBrowser for help on using the repository browser.