/* * Copyright (c) 2003-2005 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/GtkMenu.xs,v 1.23 2005/01/02 17:45:21 kaffeetisch Exp $ */ #include "gtk2perl.h" #include /* * yet another special case that isn't appropriate for either * GPerlClosure or GPerlCallback --- the menu position function has * mostly output parameters, so we need to change the callbacks's * signature for perl, getting multiple return values from the stack. * this one's easy, though. */ /* this is public so that other extensions which use GtkMenuPosFunc (e.g. * libgnomeui) don't need to reimplement it. */ void gtk2perl_menu_position_func (GtkMenu * menu, gint * x, gint * y, gboolean * push_in, GPerlCallback * callback) { int n; dGPERL_CALLBACK_MARSHAL_SP; GPERL_CALLBACK_MARSHAL_INIT (callback); ENTER; SAVETMPS; PUSHMARK (SP); EXTEND (SP, 3); PUSHs (sv_2mortal (newSVGtkMenu (menu))); PUSHs (sv_2mortal (newSViv (*x))); PUSHs (sv_2mortal (newSViv (*y))); if (callback->data) XPUSHs (sv_2mortal (newSVsv (callback->data))); PUTBACK; n = call_sv (callback->func, G_ARRAY); SPAGAIN; if (n < 2 || n > 3) croak ("menu position callback must return two integers (x, and y) or three integers (x, y, and push_in)"); /* POPi takes things off the *end* of the stack! */ if (n > 2) *push_in = POPi; if (n > 1) *y = POPi; if (n > 0) *x = POPi; PUTBACK; FREETMPS; LEAVE; } static GPerlCallback * gtk2perl_menu_detach_func_create (SV *func, SV *data) { GType param_types [2]; param_types[0] = GTK_TYPE_WIDGET; param_types[1] = GTK_TYPE_MENU; return gperl_callback_new (func, data, G_N_ELEMENTS (param_types), param_types, 0); } static void gtk2perl_menu_detach_func (GtkWidget *attach_widget, GtkMenu *menu) { GPerlCallback *callback; callback = g_object_get_data (G_OBJECT (attach_widget), "__gtk2perl_menu_detach_func__"); if (callback) gperl_callback_invoke (callback, NULL, attach_widget, menu); } MODULE = Gtk2::Menu PACKAGE = Gtk2::Menu PREFIX = gtk_menu_ GtkWidget* gtk_menu_new (class) C_ARGS: /* void */ void gtk_menu_popup (menu, parent_menu_shell, parent_menu_item, menu_pos_func, data, button, activate_time) GtkMenu * menu GtkWidget_ornull * parent_menu_shell GtkWidget_ornull * parent_menu_item SV * menu_pos_func SV * data guint button guint activate_time ###guint32 activate_time CODE: if (! (menu_pos_func && SvOK (menu_pos_func))) { gtk_menu_popup (menu, parent_menu_shell, parent_menu_item, NULL, NULL, button, activate_time); } else { GPerlCallback * callback; /* we don't need to worry about the callback arg types since * we already have to marshall this callback ourselves. */ callback = gperl_callback_new (menu_pos_func, data, 0, NULL, 0); gtk_menu_popup (menu, parent_menu_shell, parent_menu_item, (GtkMenuPositionFunc) gtk2perl_menu_position_func, callback, button, activate_time); /* The menu will store the callback we give it, and can * conceivably invoke the callback multiple times * (repositioning, changing screens, etc). Each call to * gtk_menu_popup() replaces the function pointer. So, * if we use a weak reference, we can leak multiple callbacks; * if we use object data, we can clean up the ones we install * and reinstall. Not likely, of course, but there are * pathological programmers out there. */ g_object_set_data_full (G_OBJECT (menu), "_menu_pos_callback", callback, (GDestroyNotify) gperl_callback_destroy); } void gtk_menu_reposition (menu) GtkMenu * menu void gtk_menu_popdown (menu) GtkMenu *menu GtkWidget * gtk_menu_get_active (menu) GtkMenu *menu void gtk_menu_set_active (menu, index) GtkMenu *menu guint index void gtk_menu_set_accel_group (menu, accel_group) GtkMenu * menu GtkAccelGroup * accel_group GtkAccelGroup* gtk_menu_get_accel_group (menu) GtkMenu *menu void gtk_menu_set_accel_path (menu, accel_path) GtkMenu *menu const gchar *accel_path void gtk_menu_attach_to_widget (menu, attach_widget, detacher) GtkMenu *menu GtkWidget *attach_widget SV *detacher PREINIT: GPerlCallback *callback; CODE: callback = gtk2perl_menu_detach_func_create (detacher, NULL); g_object_set_data_full (G_OBJECT (attach_widget), "__gtk2perl_menu_detach_func__", callback, (GDestroyNotify) gperl_callback_destroy); gtk_menu_attach_to_widget (menu, attach_widget, gtk2perl_menu_detach_func); void gtk_menu_detach (menu) GtkMenu *menu GtkWidget * gtk_menu_get_attach_widget (menu) GtkMenu * menu void gtk_menu_set_tearoff_state (menu, torn_off) GtkMenu *menu gboolean torn_off gboolean gtk_menu_get_tearoff_state (menu) GtkMenu *menu void gtk_menu_set_title (menu, title) GtkMenu * menu const gchar * title ## void gtk_menu_reorder_child (GtkMenu *menu, GtkWidget *child, gint position) void gtk_menu_reorder_child (menu, child, position) GtkMenu *menu GtkWidget *child gint position ##gchar * gtk_menu_get_title (GtkMenu *menu) const gchar * gtk_menu_get_title (menu) GtkMenu * menu #if GTK_CHECK_VERSION(2,2,0) ##void gtk_menu_set_screen (GtkMenu *menu, GdkScreen *screen) void gtk_menu_set_screen (menu, screen) GtkMenu * menu GdkScreen * screen #endif #if GTK_CHECK_VERSION(2,4,0) void gtk_menu_attach (GtkMenu *menu, GtkWidget *child, guint left_attach, guint right_attach, guint top_attach, guint bottom_attach); void gtk_menu_set_monitor (GtkMenu *menu, gint monitor_num); #endif #if GTK_CHECK_VERSION(2,6,0) ## GList* gtk_menu_get_for_attach_widget (GtkWidget *widget); void gtk_menu_get_for_attach_widget (class, widget) GtkWidget *widget PREINIT: GList *list, *i; PPCODE: list = gtk_menu_get_for_attach_widget (widget); for (i = list; i; i = i->next) XPUSHs (sv_2mortal (newSVGtkMenu (i->data))); #endif