2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010,
3 // 2011 Free Software Foundation, Inc
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 #include "gnashconfig.h"
27 #include <boost/algorithm/string/case_conv.hpp>
31 #include <gdk/gdkkeysyms.h>
37 #include "as_object.h"
38 #include "as_function.h"
41 #include "as_function.h"
48 #define dbglogfile cerr // FIXME: use log_*()
50 // prototypes for the callbacks required by Gnash
51 as_value
gtkext_window_new(const fn_call
& fn
);
52 as_value
gtkext_signal_connect(const fn_call
& fn
);
53 as_value
gtkext_container_set_border_width(const fn_call
& fn
);
54 as_value
gtkext_button_new_with_label(const fn_call
& fn
);
55 as_value
gtkext_signal_connect_swapped(const fn_call
& fn
);
56 as_value
gtkext_container_add(const fn_call
& fn
);
57 as_value
gtkext_widget_show(const fn_call
& fn
);
58 as_value
gtkext_main(const fn_call
& fn
);
60 // Sigh... We can't store the callbacks for the events in the GtkExt
61 // class object because that data is inaccessible to a C symbol based
63 static map
<string
, as_value
> callbacks
;
65 void dump_callbacks(map
<string
, as_value
> &calls
)
67 // GNASH_REPORT_FUNCTION;
68 map
<string
, as_value
>::const_iterator it
;
69 dbglogfile
<< "# of callbacks is: " << calls
.size() << endl
;
70 for (it
=calls
.begin(); it
!= calls
.end(); it
++) {
71 string name
= (*it
).first
;
72 as_value as
= (*it
).second
;
73 dbglogfile
<< "Event \"" << name
.c_str() << "\" has AS function" << as
.to_string() << endl
;
79 generic_callback(GtkWidget
* /*widget*/, gpointer data
)
81 // GNASH_REPORT_FUNCTION;
82 // g_print ("Hello World - %d\n", *(int *)data;
83 const char *event
= (const char *)data
;
85 as_value handler
= callbacks
[event
];
86 as_function
*as_func
= handler
.to_function();
88 // start the debugger when this callback is activated.
89 // debugger.enabled(true);
90 // debugger.console();
92 // FIXME: Delete events don't seem to pass in data in a form we
93 // can access it. So for now we just hack in a quit, since we know
94 // we're done, we hope...
99 cerr
<< "event is: \"" << event
<< "\"" << endl
;
103 as_environment
env(getVM(*as_func
));
106 args
+= handler
, event
, handler
;
108 as_object obj
= val
.to_object(*getGlobal(fn
));
110 // Call the AS function defined in the source file using this extension
111 (*as_func
)(fn_call(&obj
, &env
, args
));
115 attachInterface(as_object
*obj
)
117 // GNASH_REPORT_FUNCTION;
119 obj
->init_member("window_new", gl
->createFunction(gtkext_window_new
));
120 obj
->init_member("signal_connect", gl
->createFunction(gtkext_signal_connect
));
121 obj
->init_member("container_set_border_width", gl
->createFunction(gtkext_container_set_border_width
));
122 obj
->init_member("button_new_with_label", gl
->createFunction(gtkext_button_new_with_label
));
123 obj
->init_member("signal_connect_swapped", gl
->createFunction(gtkext_signal_connect_swapped
));
124 obj
->init_member("container_add", gl
->createFunction(gtkext_container_add
));
125 obj
->init_member("widget_show", gl
->createFunction(gtkext_widget_show
));
126 obj
->init_member("main", gl
->createFunction(gtkext_main
));
132 // GNASH_REPORT_FUNCTION;
133 static boost::intrusive_ptr
<as_object
> o
;
141 gtkext_ctor(const fn_call
& /*fn*/)
143 // GNASH_REPORT_FUNCTION;
144 GtkExt
*obj
= new GtkExt();
146 attachInterface(obj
);
147 return as_value(obj
); // will keep alive
153 // GNASH_REPORT_FUNCTION;
156 gtk_init (&argc
, &argv
);
161 // GNASH_REPORT_FUNCTION;
167 GNASH_REPORT_FUNCTION
;
168 // std::auto_ptr<Gui> ggg = player.getGuiHandle();
169 // player.getGuiHandle();
171 _window
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
175 // GtkExt::signal_connect()
177 // GNASH_REPORT_FUNCTION;
180 // void gtk_container_set_border_width (GtkContainer *container, guint border_width);
182 GtkExt::container_set_border_width(int width
)
184 // GNASH_REPORT_FUNCTION;
186 gtk_container_set_border_width (GTK_CONTAINER (_window
), width
);
190 // GtkWidget *gtk_button_new_with_label (const gchar *label);
192 GtkExt::button_new_with_label(const char *label
)
194 // GNASH_REPORT_FUNCTION;
195 _window
= gtk_button_new_with_label (label
);
202 // GNASH_REPORT_FUNCTION;
205 // this callback takes no arguments
206 as_value
gtkext_window_new(const fn_call
& fn
)
208 // GNASH_REPORT_FUNCTION;
209 boost::intrusive_ptr
<GtkExt
> ptr
= ensureType
<GtkExt
>(fn
.this_ptr
);
211 GtkExt
*obj
= new GtkExt
;
213 return as_value(obj
);
216 // this callback takes 4 arguments, we only need two of them
217 // g_signal_connect (instance, detailed_signal, c_handler, data)
218 as_value
gtkext_signal_connect(const fn_call
& fn
)
220 // GNASH_REPORT_FUNCTION;
221 boost::intrusive_ptr
<GtkExt
> ptr
= ensureType
<GtkExt
>(fn
.this_ptr
);
224 GtkExt
*window
= dynamic_cast<GtkExt
*>(fn
.arg(0).to_object(*getGlobal(fn
)).get());
225 string name
= fn
.arg(1).to_string();
226 as_value func
= fn
.arg(2).to_function();
227 //int data = fn.arg(3).to_int();
229 dbglogfile
<< "Adding callback " << func
.to_string()
230 << " for event \"" << name
<< "\"" << endl
;
231 callbacks
[name
] = func
;
232 g_signal_connect (G_OBJECT (window
->getWindow()), name
.c_str(),
233 G_CALLBACK (generic_callback
), (void *)name
.c_str());
238 // this callback takes 2 arguments
239 // void gtk_container_set_border_width (GtkContainer *container, guint border_width);
240 as_value
gtkext_container_set_border_width(const fn_call
& fn
)
242 // GNASH_REPORT_FUNCTION;
244 boost::intrusive_ptr
<GtkExt
> ptr
= ensureType
<GtkExt
>(fn
.this_ptr
);
247 GtkExt
*window
= dynamic_cast<GtkExt
*>(fn
.arg(0).to_object(*getGlobal(fn
)).get());
248 int width
= fn
.arg(1).to_int();
249 window
->container_set_border_width(width
);
250 dbglogfile
<< "set container border width to " << width
<< " !" << endl
;
255 // Creates a new button with the label "Hello World".
256 // GtkWidget *gtk_button_new_with_label (const gchar *label);
257 as_value
gtkext_button_new_with_label(const fn_call
& fn
)
259 // GNASH_REPORT_FUNCTION;
260 boost::intrusive_ptr
<GtkExt
> ptr
= ensureType
<GtkExt
>(fn
.this_ptr
);
263 string label
= fn
.arg(0).to_string();
264 GtkExt
*obj
= new GtkExt
;
265 obj
->button_new_with_label(label
.c_str());
266 return as_value(obj
);
271 // g_signal_connect_swapped(instance, detailed_signal, c_handler, data)
273 // Connects a GCallback function to a signal for a particular object.
275 // The instance on which the signal is emitted and data will be swapped when calling the handler.
276 // instance : the instance to connect to.
277 // detailed_signal : a string of the form "signal-name::detail".
278 // c_handler : the GCallback to connect.
279 // data : data to pass to c_handler calls.
280 // Returns : the handler id
281 as_value
gtkext_signal_connect_swapped(const fn_call
& fn
)
283 GNASH_REPORT_FUNCTION
;
284 boost::intrusive_ptr
<GtkExt
> ptr
= ensureType
<GtkExt
>(fn
.this_ptr
);
287 GtkExt
*parent
= dynamic_cast<GtkExt
*>(fn
.arg(0).to_object(*getGlobal(fn
)).get());
288 string name
= (fn
.arg(1).to_string());
289 GtkExt
*child
= dynamic_cast<GtkExt
*>(fn
.arg(3).to_object(*getGlobal(fn
)).get());
291 // as_value *callback = dynamic_cast<as_value *>(fn.arg(2).to_object(*getGlobal(fn)));
293 // FIXME: This seems to cause an Gobject warning
294 g_signal_connect_swapped (G_OBJECT (child
->getWindow()), name
.c_str(),
295 G_CALLBACK (gtk_widget_destroy
),
296 G_OBJECT (parent
->getWindow()));
301 // this takes two arguments
302 as_value
gtkext_container_add(const fn_call
& fn
)
304 // GNASH_REPORT_FUNCTION;
305 boost::intrusive_ptr
<GtkExt
> ptr
= ensureType
<GtkExt
>(fn
.this_ptr
);
308 GtkExt
*parent
= dynamic_cast<GtkExt
*>(fn
.arg(0).to_object(*getGlobal(fn
)).get());
309 GtkExt
*child
= dynamic_cast<GtkExt
*>(fn
.arg(1).to_object(*getGlobal(fn
)).get());
310 gtk_container_add (GTK_CONTAINER (parent
->getWindow()), child
->getWindow());
311 return as_value(true);
313 return as_value(false);
316 as_value
gtkext_widget_show(const fn_call
& fn
)
318 // GNASH_REPORT_FUNCTION;
319 boost::intrusive_ptr
<GtkExt
> ptr
= ensureType
<GtkExt
>(fn
.this_ptr
);
322 GtkExt
*window
= dynamic_cast<GtkExt
*>(fn
.arg(0).to_object(*getGlobal(fn
)).get());
323 gtk_widget_show(window
->getWindow());
328 // gtk_main takes no arguments.
329 as_value
gtkext_main(const fn_call
& fn
)
331 // GNASH_REPORT_FUNCTION;
332 boost::intrusive_ptr
<GtkExt
> ptr
= ensureType
<GtkExt
>(fn
.this_ptr
);
338 std::auto_ptr
<as_object
>
339 init_gtkext_instance()
341 return std::auto_ptr
<as_object
>(new GtkExt());
346 gtkext_class_init(as_object
&obj
)
348 // GNASH_REPORT_FUNCTION;
349 // This is going to be the global "class"/"function"
350 static boost::intrusive_ptr
<builtin_function
> cl
;
352 as_object
* proto
= getInterface();
353 Global_as
* gl
= getGlobal(global
);
354 cl
= gl
->createClass(>kext_ctor
, proto
);
355 // replicate all interface to class, to be able to access
356 // all methods as static functions
357 attachInterface(cl
.get());
360 obj
.init_member("GtkExt", cl
.get());
365 } // end of gnash namespace
369 // indent-tabs-mode: t