1 /* guile-gnome
2  * Copyright (C) 2003,2004,2010 Andy Wingo <wingo at pobox dot com>
3  *
4  * glade-support.c: Support routines for the libglade wrapper
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, contact:
18  *
19  * Free Software Foundation           Voice:  +1-617-542-5942
20  * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652
21  * Boston, MA  02111-1307,  USA       gnu@gnu.org
22  */
23 
24 #include "glade-support.h"
25 #include <string.h>
26 #include "guile-gnome-gobject.h"
27 
28 #define GRUNTIME_ERROR(format, func_name, args...) \
29   scm_error_scm (scm_from_locale_symbol ("gruntime-error"), scm_from_locale_string (func_name), \
30                  scm_simple_format (SCM_BOOL_F, scm_from_locale_string (format), \
31                                     scm_list_n (args, SCM_UNDEFINED)), \
32                  SCM_EOL, SCM_EOL)
33 
34 GladeXML*
_wrap_glade_xml_new_from_buffer(const char * buffer,const char * root,const char * domain)35 _wrap_glade_xml_new_from_buffer (const char *buffer, const char *root,
36                                  const char *domain)
37 {
38     return glade_xml_new_from_buffer (buffer, strlen (buffer), root, domain);
39 }
40 
41 static void
connect_one(const gchar * handler_name,GObject * object,const gchar * signal_name,const gchar * signal_data,GObject * connect_object,gboolean after,gpointer user_data)42 connect_one (const gchar *handler_name, GObject *object, const gchar *signal_name,
43              const gchar *signal_data, GObject *connect_object, gboolean after,
44              gpointer user_data)
45 {
46     static SCM gtype_instance_signal_connect = SCM_BOOL_F;
47     SCM proc;
48 
49     if (SCM_FALSEP (gtype_instance_signal_connect))
50         gtype_instance_signal_connect =
51             SCM_VARIABLE_REF (scm_c_module_lookup (scm_glade_module,
52                                                    "gtype-instance-signal-connect"));
53 
54     proc = GPOINTER_TO_SCM (user_data);
55     scm_call_4 (gtype_instance_signal_connect,
56                 scm_c_gtype_instance_to_scm (object),
57                 scm_from_locale_symbol (signal_name),
58                 proc,
59                 after ? SCM_BOOL_T : SCM_BOOL_F);
60 }
61 
62 void
_wrap_glade_xml_signal_connect(GladeXML * xml,const char * handlername,SCM proc)63 _wrap_glade_xml_signal_connect (GladeXML *xml, const char *handlername, SCM proc)
64 #define FUNC_NAME "glade-xml-signal-connect"
65 {
66     SCM_VALIDATE_PROC (3, proc);
67     glade_xml_signal_connect_full (xml, handlername, connect_one,
68                                    SCM_TO_GPOINTER (proc));
69 }
70 #undef FUNC_NAME
71 
handle_read_error(char * handler_name,SCM tag,SCM throw_args)72 SCM handle_read_error (char *handler_name, SCM tag, SCM throw_args)
73 {
74     GRUNTIME_ERROR ("Error while reading signal handler ~S: ~A: ~S",
75                     "glade-xml-signal-autoconnect", scm_from_locale_string (handler_name),
76                     tag, throw_args);
77 }
78 
79 static void
connect_many(const gchar * handler_name,GObject * object,const gchar * signal_name,const gchar * signal_data,GObject * connect_object,gboolean after,gpointer user_data)80 connect_many (const gchar *handler_name, GObject *object, const gchar *signal_name,
81               const gchar *signal_data, GObject *connect_object, gboolean after,
82               gpointer user_data)
83 {
84     SCM module = GPOINTER_TO_SCM (user_data);
85     SCM proc = SCM_BOOL_F;
86 
87     proc = scm_eval (scm_internal_catch (SCM_BOOL_T,
88                                          (scm_t_catch_body)scm_c_read_string,
89                                          (void*)handler_name,
90                                          (scm_t_catch_handler)handle_read_error,
91                                          (void*)handler_name),
92                      module);
93     if (SCM_FALSEP (scm_procedure_p (proc)))
94         GRUNTIME_ERROR ("Tried to set `~A' to handle signal `~A', but it's not a procedure",
95                         "glade-xml-signal-autoconnect", scm_from_locale_string (handler_name),
96                         scm_from_locale_string (signal_name));
97 
98     connect_one (NULL, object, signal_name, NULL, NULL, after,
99                  SCM_TO_GPOINTER (proc));
100 }
101 
102 void
_wrap_glade_xml_signal_autoconnect(GladeXML * xml,SCM module)103 _wrap_glade_xml_signal_autoconnect (GladeXML *xml, SCM module)
104 {
105     glade_xml_signal_autoconnect_full (xml, connect_many,
106                                        SCM_TO_GPOINTER (module));
107 }
108 
109 GtkWidget*
guile_glade_custom_handler(GladeXML * xml,gchar * func,gchar * name,gchar * string1,gchar * string2,gint int1,gint int2,gpointer user_data)110 guile_glade_custom_handler (GladeXML *xml, gchar *func, gchar *name, gchar *string1,
111                             gchar *string2, gint int1, gint int2, gpointer user_data)
112 #define FUNC_NAME "%guile-glade-custom-handler"
113 {
114     SCM ret;
115     GtkWidget *widget;
116 
117     ret = scm_c_eval_string (func);
118     SCM_VALIDATE_GOBJECT (0, ret);
119     widget = (GtkWidget*)scm_c_scm_to_gtype_instance_typed (ret, GTK_TYPE_WIDGET);
120     gtk_widget_show (widget);
121     return widget;
122 }
123 #undef FUNC_NAME
124