/* * Copyright (c) 2003 by the gtk2-perl team (see the file AUTHORS) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307 USA. * * $Header: /cvsroot/gtk2-perl/gtk2-perl-xs/Gtk2/xs/Gtk2.xs,v 1.39.2.5 2004/04/04 17:16:39 kaffeetisch Exp $ */ #include "gtk2perl.h" static gboolean gtk2perl_init_add_callback_invoke (GPerlCallback * callback) { GValue return_value = {0,}; gboolean retval; g_value_init (&return_value, callback->return_type); gperl_callback_invoke (callback, &return_value); retval = g_value_get_boolean (&return_value); g_value_unset (&return_value); /* according to the gtk source, init callbacks are forgotten * immediately after use; thus, we need to destroy the callback * object to avoid a leak. */ gperl_callback_destroy(callback); return retval; } static guint gtk2perl_quit_add_callback_invoke (GPerlCallback * callback) { GValue return_value = {0,}; guint retval; g_value_init (&return_value, callback->return_type); gperl_callback_invoke (callback, &return_value); retval = g_value_get_uint (&return_value); g_value_unset (&return_value); return retval; } static gint gtk2perl_key_snoop_func (GtkWidget *grab_widget, GdkEventKey *event, gpointer func_data) { gint ret; GValue retval = {0,}; g_value_init (&retval, G_TYPE_INT); gperl_callback_invoke ((GPerlCallback*)func_data, &retval, grab_widget, event); ret = g_value_get_int (&retval); g_value_unset (&retval); return ret; } /* * we must track the key snoopers ourselves so we can destroy * the callback objects properly. */ static GHashTable * key_snoopers = NULL; static guint install_key_snooper (SV * func, SV * data) { guint id; GPerlCallback * callback; GType param_types[] = { GTK_TYPE_WIDGET, GDK_TYPE_EVENT }; if (!key_snoopers) key_snoopers = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) gperl_callback_destroy); callback = gperl_callback_new (func, data, 2, param_types, G_TYPE_INT); id = gtk_key_snooper_install (gtk2perl_key_snoop_func, callback); g_hash_table_insert (key_snoopers, GUINT_TO_POINTER (id), callback); return id; } static void remove_key_snooper (guint id) { g_return_if_fail (key_snoopers != NULL); gtk_key_snooper_remove (id); g_hash_table_remove (key_snoopers, GUINT_TO_POINTER (id)); } MODULE = Gtk2 PACKAGE = Gtk2 PREFIX = gtk_ ## ## don't allow any unhidden autogenerated pods to fall into the Gtk2 ## namespace, or the pod from Gtk2.pm will be overridden. ## BOOT: { /* include some files autogenerated by Makefile.PL. */ /* register Gtk/Gdk/Atk/Pango classes as perl packages. * be sure to include this autogenerated set first, so that the * hand-written boot code functions called by the next include * can override the registrations if necessary. */ #include "register.xsh" /* call the boot code for all the various other modules */ #include "boot.xsh" /* route Gtk+ log messages through perl's warn() and croak() */ gperl_handle_logs_for ("Gtk"); gperl_handle_logs_for ("Gdk"); gperl_handle_logs_for ("GdkPixbuf"); gperl_handle_logs_for ("Pango"); /* make sure that we're running/linked against a version at least as * new as we built against, otherwise bad things can happen. */ if ((((int)gtk_major_version) < GTK_MAJOR_VERSION) || (gtk_major_version == GTK_MAJOR_VERSION && ((int)gtk_minor_version) < GTK_MINOR_VERSION) || (gtk_major_version == GTK_MAJOR_VERSION && gtk_minor_version == GTK_MINOR_VERSION && ((int)gtk_micro_version) < GTK_MICRO_VERSION)) warn ("*** This build of Gtk2 was compiled with gtk+ %d.%d.%d," " but is currently running with %d.%d.%d, which is too" " old. We'll continue, but expect problems!\n", GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION, gtk_major_version, gtk_minor_version, gtk_micro_version); } ############################################################################# ############################################################################# =for object Gtk2::version Library Version Information =cut =head1 SYNOPSIS use Gtk2 '1.023'; # require at least version 1.023 of the bindings if ($Gtk2::VERSION >= 1.040 and Gtk2->CHECK_VERSION (2, 4, 0)) { # the GtkFileChooser, new in gtk+ 2.4.0 and first supported in # Gtk2-Perl at 1.040, is available } else { # GtkFileChooser is not available, fall back to GtkFileSelection } =head1 DESCRIPTION Since the Gtk2 Perl module is a bridge to an external library with its own versions and API revisions, we have three different versions available for inspection. Which one you need to use at which time depends entirely on the situation. Gtk2 uses the same scheme as Glib and the underlying gtk+ C library; that is, the standard C<$Gtk2::VERSION> for the version of the bindings, all-caps (MAJOR|MINOR|MICRO)_VERSION functions for the bound version, and lower-case (major|minor|micro)_version functions for the runtime version. See L and http://developer.gnome.org/doc/API/2.0/gtk/gtk-Feature-Test-Macros.html for more information. Note also that gtk_check_version() and GTK_CHECK_VERSION() have different semantics in C, and we have preserved those faithfully. =cut =for see_also Glib::version =cut # we have no use for these in perl. ##GTKMAIN_C_VAR const guint gtk_binary_age; ##GTKMAIN_C_VAR const guint gtk_interface_age; =for apidoc =for signature (major, minor, micro) = Gtk2->get_version_info Shorthand to fetch as a list the gtk+ version against which Gtk2 is linked. See C, etc. =cut void gtk_get_version_info (class) PPCODE: EXTEND(SP,3); PUSHs(sv_2mortal(newSViv(gtk_major_version))); PUSHs(sv_2mortal(newSViv(gtk_minor_version))); PUSHs(sv_2mortal(newSViv(gtk_micro_version))); PERL_UNUSED_VAR (ax); =for apidoc Returns undef if the version of gtk+ currently in use is compatible with the given version, otherwise returns a string describing the mismatch. Note that this is not the same logic as C. This check is not terribly reliable, and should not be used to test for availability of widgets or functions in the Gtk2 module --- use C for that. See L for a more detailed description of when you'd want to do a runtime-version test. =cut gchar * gtk_check_version (class, required_major, required_minor, required_micro) guint required_major guint required_minor guint required_micro C_ARGS: required_major, required_minor, required_micro =for apidoc Gtk2::MAJOR_VERSION __function__ The major version of the gtk+ library against which Gtk2 was compiled. Equivalent to gtk+'s GTK_MAJOR_VERSION. =cut =for apidoc Gtk2::MINOR_VERSION __function__ The minor version of the gtk+ library against which Gtk2 was compiled. Equivalent to gtk+'s GTK_MINOR_VERSION. =cut =for apidoc Gtk2::MICRO_VERSION __function__ The micro version of the gtk+ library against which Gtk2 was compiled. Equivalent to gtk+'s GTK_MICRO_VERSION. =cut =for apidoc Gtk2::major_version __function__ The major version of the gtk+ library current in use at runtime. Equivalent to gtk+'s global variable gtk_major_version. =cut =for apidoc Gtk2::minor_version __function__ The minor version of the gtk+ library current in use at runtime. Equivalent to gtk+'s global variable gtk_minor_version. =cut =for apidoc Gtk2::micro_version __function__ The micro version of the gtk+ library current in use at runtime. Equivalent to gtk+'s global variable gtk_micro_version. =cut guint MAJOR_VERSION () ALIAS: Gtk2::MINOR_VERSION = 1 Gtk2::MICRO_VERSION = 2 Gtk2::major_version = 3 Gtk2::minor_version = 4 Gtk2::micro_version = 5 CODE: switch (ix) { case 0: RETVAL = GTK_MAJOR_VERSION; break; case 1: RETVAL = GTK_MINOR_VERSION; break; case 2: RETVAL = GTK_MICRO_VERSION; break; case 3: RETVAL = gtk_major_version; break; case 4: RETVAL = gtk_minor_version; break; case 5: RETVAL = gtk_micro_version; break; default: RETVAL = -1; g_assert_not_reached (); } OUTPUT: RETVAL =for apidoc =for signature (MAJOR, MINOR, MICRO) = Gtk2->GET_VERSION_INFO Shorthand to fetch as a list the gtk+ version for which Gtk2 was compiled. See C, etc. =cut void GET_VERSION_INFO (class) PPCODE: EXTEND (SP, 3); PUSHs (sv_2mortal (newSViv (GTK_MAJOR_VERSION))); PUSHs (sv_2mortal (newSViv (GTK_MINOR_VERSION))); PUSHs (sv_2mortal (newSViv (GTK_MICRO_VERSION))); PERL_UNUSED_VAR (ax); =for apidoc Provides a mechanism for checking the version information that Gtk2 was compiled against. Essentially equvilent to the macro GTK_CHECK_VERSION. In most cases this function should be used rather than Lcheck_version>. =cut gboolean CHECK_VERSION (class, guint required_major, guint required_minor, guint required_micro) CODE: RETVAL = GTK_CHECK_VERSION (required_major, required_minor, required_micro); OUTPUT: RETVAL ############################################################################# ############################################################################# =for object Gtk2::main =cut =for apidoc Gtk2::init_check This is the non-fatal version of C<< Gtk2->init >>; instead of calling C if Gtk+ initialization fails, C<< Gtk2->init_check >> returns false. This allows your application to fall back on some other means of communication with the user - for example a curses or command-line interface. =cut =for apidoc Initialize Gtk+. This must be called before any other Gtk2 functions in a GUI application; the Gtk2 module's import method allows you to pass C<-init> in the C statement to do this automatically. This function also scans I<@ARGV> for any options it knows, and will remove them automagically. Note: this function will terminate your program if it is unable to initialize the gui for any reason. If you want your program to fall back to some other interface, you want to use C<< Gtk2->init_check >> instead. =cut gboolean gtk_init (class=NULL) ALIAS: Gtk2::init_check = 2 PREINIT: GPerlArgv *pargv; CODE: pargv = gperl_argv_new (); if (ix == 2) { RETVAL = gtk_init_check (&pargv->argc, &pargv->argv); } else { gtk_init (&pargv->argc, &pargv->argv); /* gtk_init() either succeeds or does not return. */ RETVAL = TRUE; } gperl_argv_update (pargv); gperl_argv_free (pargv); OUTPUT: RETVAL ##void gtk_disable_setlocale (void); void gtk_disable_setlocale (class) C_ARGS: /*void*/ ##gchar * gtk_set_locale (void); const gchar * gtk_set_locale (class) C_ARGS: /*void*/ ##PangoLanguage *gtk_get_default_language (void); PangoLanguage * gtk_get_default_language (class) C_ARGS: /*void*/ gint gtk_events_pending (class) C_ARGS: /*void*/ ## void gtk_main_do_event (GdkEvent *event); =for apidoc This is the event handler that GTK+ registers with GDK. GTK+ exposes it to allow filtering of events between GDK and GTK+; it is rare that you would need this, except if you are using C. =cut void gtk_main_do_event (class, GdkEvent *event); C_ARGS: event void gtk_main (class) C_ARGS: /*void*/ guint gtk_main_level (class) C_ARGS: /*void*/ void gtk_main_quit (class=NULL) C_ARGS: /*void*/ gboolean gtk_main_iteration (class) C_ARGS: /*void*/ gboolean gtk_main_iteration_do (class, blocking) gboolean blocking C_ARGS: blocking ### gtk-perl implemented these as widget methods, but they are not widget ### methods. they deal with the global grab setting. this is bound to ### be a FAQ. ## Gtk2->grab_add (widget) void gtk_grab_add (class, widget) GtkWidget * widget C_ARGS: widget GtkWidget_ornull * gtk_grab_get_current (class) C_ARGS: /*void*/ ## Gtk2->grab_remove (widget) void gtk_grab_remove (class, widget) GtkWidget * widget C_ARGS: widget void gtk_init_add (class, function, data=NULL) SV * function SV * data PREINIT: GPerlCallback * real_callback; CODE: real_callback = gperl_callback_new(function, data, 0, NULL, G_TYPE_BOOLEAN); gtk_init_add((GtkFunction)gtk2perl_init_add_callback_invoke, real_callback); ## guint gtk_quit_add ## guint gtk_quit_add_full guint gtk_quit_add (class, main_level, function, data=NULL) guint main_level SV * function SV * data PREINIT: GPerlCallback * real_callback; CODE: real_callback = gperl_callback_new(function, data, 0, NULL, G_TYPE_UINT); RETVAL = gtk_quit_add_full(main_level, (GtkFunction)gtk2perl_quit_add_callback_invoke, NULL, real_callback, (GtkDestroyNotify)gperl_callback_destroy); OUTPUT: RETVAL void gtk_quit_remove (class, quit_handler_id) guint quit_handler_id C_ARGS: quit_handler_id ## void gtk_quit_add_destroy (guint main_level, GtkObject *object); void gtk_quit_add_destroy (class, guint main_level, GtkObject *object) C_ARGS: main_level, object ##void gtk_quit_remove_by_data (gpointer data); # these (timeout, idle, and input) are all deprecated in favor of the # corresponding glib functions. ##guint gtk_timeout_add (guint32 interval, ## GtkFunction function, ## gpointer data); ##guint gtk_timeout_add_full (guint32 interval, ## GtkFunction function, ## GtkCallbackMarshal marshal, ## gpointer data, ## GtkDestroyNotify destroy); ##void gtk_timeout_remove (guint timeout_handler_id); ## ##guint gtk_idle_add (GtkFunction function, ## gpointer data); ##guint gtk_idle_add_priority (gint priority, ## GtkFunction function, ## gpointer data); ##guint gtk_idle_add_full (gint priority, ## GtkFunction function, ## GtkCallbackMarshal marshal, ## gpointer data, ## GtkDestroyNotify destroy); ##void gtk_idle_remove (guint idle_handler_id); ##void gtk_idle_remove_by_data (gpointer data); ##guint gtk_input_add_full (gint source, ## GdkInputCondition condition, ## GdkInputFunction function, ## GtkCallbackMarshal marshal, ## gpointer data, ## GtkDestroyNotify destroy); ##void gtk_input_remove (guint input_handler_id); ##guint gtk_key_snooper_install (GtkKeySnoopFunc snooper, gpointer func_data); =for apidoc =for arg snooper (subroutine) function to call on every event, must return a boolean Install a key "snooper" function, which will get called on all key events before those events are delivered normally. These snoopers can be used to implement custom key event handling. I will receive the widget to which the event will be delivered and the event, and also I (if provided). If I returns true, the event propagation will stop (just like normal event handlers). C returns an id that may be used with C. =cut guint gtk_key_snooper_install (class, SV * snooper, SV * func_data=NULL) CODE: RETVAL = install_key_snooper (snooper, func_data); OUTPUT: RETVAL ##void gtk_key_snooper_remove (guint snooper_handler_id); void gtk_key_snooper_remove (class, guint snooper_handler_id) CODE: remove_key_snooper (snooper_handler_id); ##GdkEvent* gtk_get_current_event (void); GdkEvent_own_ornull* gtk_get_current_event (class) C_ARGS: /*void*/ ##guint32 gtk_get_current_event_time (void); guint32 gtk_get_current_event_time (class); C_ARGS: /*void*/ ##gboolean gtk_get_current_event_state (GdkModifierType *state); GdkModifierType gtk_get_current_event_state (class) CODE: if (!gtk_get_current_event_state (&RETVAL)) XSRETURN_UNDEF; OUTPUT: RETVAL ##GtkWidget* gtk_get_event_widget (GdkEvent *event); GtkWidget_ornull * gtk_get_event_widget (class, GdkEvent_ornull * event) C_ARGS: event # this stuff is only here to generate pod pages for abstract and functionless # object, that is the objects exist only as parents and have no functions of # their own =for object Gtk2::Separator =cut =for object Gtk2::Scrollbar =cut MODULE = Gtk2 PACKAGE = Gtk2::Widget PREFIX = gtk_ =for apidoc From gtk+'s API documentation: You most likely don't want to use any of these functions; synthesizing events is rarely needed. Consider asking on the mailing list for better ways to achieve your goals. For example, use Gtk2::Gdk::invalidate_rect or Gtk2::Widget::queue_draw instead of making up expose events. =cut ##void gtk_propagate_event (GtkWidget * widget, GdkEvent * event); void gtk_propagate_event (widget, event) GtkWidget * widget GdkEvent * event MODULE = Gtk2 PACKAGE = Gtk2::Pango PREFIX = PANGO_ # Don't doc these in Gtk2::Pango, or we'll clobber the docs for the # pango constants module! =for object Gtk2::Pango::version =cut =for see_also Gtk2::version =cut =for see_also Glib::version =cut =for apidoc =for signature (MAJOR, MINOR, MICRO) = Gtk2::Pango->GET_VERSION_INFO Fetch as a list the version of pango with which Gtk2 was built. =cut void GET_VERSION_INFO (class) PPCODE: EXTEND (SP, 3); PUSHs (sv_2mortal (newSViv (PANGO_MAJOR_VERSION))); PUSHs (sv_2mortal (newSViv (PANGO_MINOR_VERSION))); PUSHs (sv_2mortal (newSViv (PANGO_MICRO_VERSION))); PERL_UNUSED_VAR (ax); bool PANGO_CHECK_VERSION (class, int major, int minor, int micro) C_ARGS: major, minor, micro