swami/0000755000175000017500000000000011716016671012064 5ustar alessioalessioswami/README.OSX0000644000175000017500000000156711074170636013424 0ustar alessioalessioSWAMI-2.0 Installation on Mac OS X.5.5 (Leopard) Requirements: - fluidsynth - fink package distribution - X11.app, X11SDK.pkg, OpenGLSDK.pkg and QuickTimeSDK.pkg (Leopard Install DVD) - fink packages: cairo, gtk+2, gtk+2-dev, audiofile, flac, gettext, intltool, libtool14, libgnomecanvas2-dev, libxml2, pygtk2-py24-dev, pkgconfig, libart2, libglade2, pango1-xft2-ft219-dev, fftw3 and gtksourceview for example: "$ fink install gtk+2-dev" libinstpatch: configure && make && sudo make install: $ PKG_CONFIG_PATH=/usr/local/lib/pkgconfig ./configure "LDFLAGS=-L/usr/local/lib -L/sw/lib" "CFLAGS=-I/usr/local/include -I/sw/include" SWAMI: configure && make && sudo make install Ebrahim Mayat Josh Green Last updated: 9th October, 2008 swami/src/0000755000175000017500000000000011716016666012657 5ustar alessioalessioswami/src/swamigui/0000755000175000017500000000000011716016664014502 5ustar alessioalessioswami/src/swamigui/SwamiguiMenu.c0000644000175000017500000003657711667007707017305 0ustar alessioalessio/* * SwamiguiMenu.c - Swami GUI Menu object * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include #include "SwamiguiMenu.h" #include "SwamiguiRoot.h" #include "SwamiguiPref.h" #include "SwamiguiPythonView.h" #include "help.h" #include "patch_funcs.h" #include "i18n.h" #include "icons.h" #include "splash.h" #include "util.h" static void swamigui_menu_class_init (SwamiguiMenuClass *klass); static void swamigui_menu_init (SwamiguiMenu *menubar); static void swamigui_menu_recent_chooser_item_activated (GtkRecentChooser *chooser, gpointer user_data); static void swamigui_menu_realize (GtkWidget *widget); static void swamigui_menu_update_new_type_item (void); static GtkWidget *create_patch_type_menu (SwamiguiMenu *menubar); static int sort_by_type_name (const void *a, const void *b); /* menu callbacks */ static void swamigui_menu_cb_new_patch (GtkWidget *mitem, gpointer data); static void swamigui_menu_cb_load_files (GtkWidget *mitem, gpointer data); static void swamigui_menu_cb_save_all (GtkWidget *mitem, gpointer data); static void swamigui_menu_cb_quit (GtkWidget *mitem, gpointer data); static void swamigui_menu_cb_preferences (GtkWidget *mitem, gpointer data); static void swamigui_menu_cb_swamitips (GtkWidget *mitem, gpointer data); static void swamigui_menu_cb_splash_image (GtkWidget *mitem, gpointer data); #ifdef PYTHON_SUPPORT static void swamigui_menu_cb_python (GtkWidget *mitem, gpointer data); #endif static void swamigui_menu_cb_restart_fluid (GtkWidget *mitem, gpointer data); static GtkWidgetClass *parent_class = NULL; /* the last patch type selected from the NewType menu item */ static GType last_new_type = 0; static GtkWidget *last_new_mitem = NULL; static GtkActionEntry entries[] = { { "FileMenu", NULL, "_File" }, /* name, stock id, label */ { "EditMenu", NULL, "_Edit" }, /* name, stock id, label */ { "PluginsMenu", NULL, "_Plugins" }, /* name, stock id, label */ { "ToolsMenu", NULL, "_Tools" }, /* name, stock id, label */ { "HelpMenu", NULL, "_Help" }, /* name, stock id, label */ /* File Menu */ /* New is not actually on the menu, just used for key accelerator */ { "New", GTK_STOCK_NEW, "_New", /* name, stock id, label */ "N", /* label, accelerator */ NULL, /* tooltip */ G_CALLBACK (swamigui_menu_cb_new_patch) }, { "NewType", GTK_STOCK_NEW, "N_ew...", "", N_("Create a new patch file of type..") }, { "Open", GTK_STOCK_OPEN, /* name, stock id */ "_Open", "O", /* label, accelerator */ NULL, /* tooltip */ G_CALLBACK (swamigui_menu_cb_load_files) }, { "OpenRecent", GTK_STOCK_OPEN, /* name, stock id */ "Open _Recent", "", /* label, accelerator */ NULL, /* tooltip */ NULL }, /* callback */ { "SaveAll", GTK_STOCK_SAVE, /* name, stock id */ "_Save All", "", /* label, accelerator */ NULL, /* tooltip */ G_CALLBACK (swamigui_menu_cb_save_all) }, { "Quit", GTK_STOCK_QUIT, /* name, stock id */ "_Quit", "Q", /* label, accelerator */ NULL, /* tooltip */ G_CALLBACK (swamigui_menu_cb_quit) }, /* Edit Menu */ { "Preferences", GTK_STOCK_PREFERENCES, /* name, stock id */ "_Preferences", "", /* label, accelerator */ NULL, /* tooltip */ G_CALLBACK (swamigui_menu_cb_preferences) }, /* Plugins Menu */ { "RestartFluid", GTK_STOCK_REFRESH, N_("_Restart FluidSynth"), "", N_("Restart FluidSynth plugin"), G_CALLBACK (swamigui_menu_cb_restart_fluid) }, /* Tools Menu */ #ifdef PYTHON_SUPPORT { "Python", SWAMIGUI_STOCK_PYTHON, /* name, stock id */ "_Python", "", /* label, accelerator */ N_("Python script editor and console"), /* tooltip */ G_CALLBACK (swamigui_menu_cb_python) }, #endif /* Help Menu */ { "SwamiTips", GTK_STOCK_HELP, /* name, stock id */ "Swami _Tips", "", /* label, accelerator */ N_("Get helpful tips on using Swami"), /* tooltip */ G_CALLBACK (swamigui_menu_cb_swamitips) }, { "SplashImage", GTK_STOCK_INFO, /* name, stock id */ "_Splash Image", "", /* label, accelerator */ N_("Show splash image"), /* tooltip */ G_CALLBACK (swamigui_menu_cb_splash_image) }, { "About", GTK_STOCK_ABOUT, /* name, stock id */ "_About", "", /* label, accelerator */ N_("About Swami"), /* tooltip */ G_CALLBACK (swamigui_help_about) }, }; static guint n_entries = G_N_ELEMENTS (entries); static const gchar *ui_info = "" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " /* FIXME - Python disabled until crashing is fixed and binding is updated */ #if 0 " " #ifdef PYTHON_SUPPORT " " #endif " " #endif " " " " " " " " " " " " ""; GType swamigui_menu_get_type (void) { static GType obj_type = 0; if (!obj_type) { static const GTypeInfo obj_info = { sizeof (SwamiguiMenuClass), NULL, NULL, (GClassInitFunc) swamigui_menu_class_init, NULL, NULL, sizeof (SwamiguiMenu), 0, (GInstanceInitFunc) swamigui_menu_init, }; obj_type = g_type_register_static (GTK_TYPE_VBOX, "SwamiguiMenu", &obj_info, 0); } return (obj_type); } static void swamigui_menu_class_init (SwamiguiMenuClass *klass) { GtkWidgetClass *widg_class = GTK_WIDGET_CLASS (klass); parent_class = g_type_class_peek_parent (klass); widg_class->realize = swamigui_menu_realize; } static void swamigui_menu_init (SwamiguiMenu *guimenu) { GtkActionGroup *actions; GtkWidget *new_type_menu; GtkWidget *mitem; GError *error = NULL; GtkWidget *recent_menu; GtkRecentManager *manager; GtkRecentFilter *filter; actions = gtk_action_group_new ("Actions"); gtk_action_group_add_actions (actions, entries, n_entries, guimenu); guimenu->ui = gtk_ui_manager_new (); gtk_ui_manager_insert_action_group (guimenu->ui, actions, 0); if (!gtk_ui_manager_add_ui_from_string (guimenu->ui, ui_info, -1, &error)) { g_critical ("Building SwamiGuiMenu failed: %s", error->message); g_error_free (error); return; } gtk_box_pack_start (GTK_BOX (guimenu), gtk_ui_manager_get_widget (guimenu->ui, "/MenuBar"), FALSE, FALSE, 0); /* if last_new_type not set assign it from SwamiguiRoot "default-patch-type" property */ if (!last_new_type) { g_object_get (swamigui_root, "default-patch-type", &last_new_type, NULL); /* also not set? Just set it to SoundFont type */ if (last_new_type == G_TYPE_NONE) last_new_type = IPATCH_TYPE_SF2; } /* set correct label of "New " menu item */ last_new_mitem = gtk_ui_manager_get_widget (guimenu->ui, "/MenuBar/FileMenu/New"); swamigui_menu_update_new_type_item (); /* create patch type menu and add to File->"New .." menu item */ new_type_menu = create_patch_type_menu (guimenu); mitem = gtk_ui_manager_get_widget (guimenu->ui, "/MenuBar/FileMenu/NewType"); gtk_menu_item_set_submenu (GTK_MENU_ITEM (mitem), new_type_menu); /* Recent chooser menu */ manager = gtk_recent_manager_get_default (); recent_menu = gtk_recent_chooser_menu_new_for_manager (manager); /* set the limit to unlimited (FIXME - issues?) */ gtk_recent_chooser_set_limit (GTK_RECENT_CHOOSER (recent_menu), -1); /* filter recent items to only include those stored by Swami */ filter = gtk_recent_filter_new (); gtk_recent_filter_add_application (filter, "swami"); gtk_recent_chooser_set_filter (GTK_RECENT_CHOOSER (recent_menu), filter); /* Set the sort type to most recent first */ gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER (recent_menu), GTK_RECENT_SORT_MRU); mitem = gtk_ui_manager_get_widget (guimenu->ui, "/MenuBar/FileMenu/OpenRecent"); gtk_menu_item_set_submenu (GTK_MENU_ITEM (mitem), recent_menu); g_signal_connect (recent_menu, "item-activated", G_CALLBACK (swamigui_menu_recent_chooser_item_activated), NULL); } /* callback for when the user selects a recent file in the recent files menu */ static void swamigui_menu_recent_chooser_item_activated (GtkRecentChooser *chooser, gpointer user_data) { char *file_uri, *fname; GError *err = NULL; GtkWidget *msgdialog; file_uri = gtk_recent_chooser_get_current_uri (chooser); if (!file_uri) return; fname = g_filename_from_uri (file_uri, NULL, NULL); g_free (file_uri); if (!fname) { g_critical (_("Failed to parse recent file URI '%s'"), file_uri); return; } if (!swami_root_patch_load (SWAMI_ROOT (swamigui_root), fname, NULL, &err)) { msgdialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Failed to load '%s': %s"), fname, ipatch_gerror_message (err)); g_clear_error (&err); if (gtk_dialog_run (GTK_DIALOG (msgdialog)) != GTK_RESPONSE_NONE) gtk_widget_destroy (msgdialog); } g_free (fname); } static void swamigui_menu_realize (GtkWidget *widget) { SwamiguiMenu *guimenu = SWAMIGUI_MENU (widget); GtkWidget *toplevel; parent_class->realize (widget); toplevel = gtk_widget_get_toplevel (widget); if (toplevel) gtk_window_add_accel_group (GTK_WINDOW (toplevel), gtk_ui_manager_get_accel_group (guimenu->ui)); } static void swamigui_menu_update_new_type_item (void) { char *name, *s; char *free_icon, *icon_name; GtkWidget *icon; gint category; ipatch_type_get (last_new_type, "name", &name, NULL); s = g_strdup_printf (_("_New %s"), name); g_free (name); gtk_label_set_text_with_mnemonic (GTK_LABEL (gtk_bin_get_child (GTK_BIN (last_new_mitem))), s); g_free (s); /* get icon stock name */ ipatch_type_get (last_new_type, "icon", &free_icon, "category", &category, NULL); if (!free_icon) icon_name = swamigui_icon_get_category_icon (category); else icon_name = free_icon; icon = gtk_image_new_from_stock (icon_name, GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (last_new_mitem), icon); if (free_icon) g_free (free_icon); } static GtkWidget * create_patch_type_menu (SwamiguiMenu *guimenu) { GtkWidget *menu; GtkWidget *item; GtkWidget *icon; GType *types, *ptype; char *name, *blurb; char *free_icon = NULL, *icon_name; guint n_types; gint category; menu = gtk_menu_new (); types = swami_util_get_child_types (IPATCH_TYPE_BASE, &n_types); qsort (types, n_types, sizeof (GType), sort_by_type_name); for (ptype = types; *ptype; ptype++) { ipatch_type_get (*ptype, "name", &name, "blurb", &blurb, NULL); if (name) { item = gtk_image_menu_item_new_with_label (name); /* get icon stock name */ ipatch_type_get (*ptype, "icon", &free_icon, "category", &category, NULL); if (!free_icon) icon_name = swamigui_icon_get_category_icon (category); else icon_name = free_icon; icon = gtk_image_new_from_stock (icon_name, GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), icon); if (free_icon) g_free (free_icon); g_object_set_data (G_OBJECT (item), "patch-type", GUINT_TO_POINTER (*ptype)); gtk_widget_show_all (item); gtk_container_add (GTK_CONTAINER (menu), item); g_signal_connect (item, "activate", G_CALLBACK (swamigui_menu_cb_new_patch), guimenu); } } g_free (types); return (menu); } static int sort_by_type_name (const void *a, const void *b) { GType *atype = (GType *)a, *btype = (GType *)b; char *aname, *bname; ipatch_type_get (*atype, "name", &aname, NULL); ipatch_type_get (*btype, "name", &bname, NULL); if (!aname && !bname) return (0); else if (!aname) return (1); else if (!bname) return (-1); else return (strcmp (aname, bname)); } /** * swamigui_menu_new: * * Create a Swami main menu object. * * Returns: New Swami menu object. */ GtkWidget * swamigui_menu_new (void) { return (GTK_WIDGET (g_object_new (SWAMIGUI_TYPE_MENU, NULL))); } /* main menu callback to create a new patch objects */ static void swamigui_menu_cb_new_patch (GtkWidget *mitem, gpointer data) { GType patch_type; patch_type = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (mitem), "patch-type")); if (patch_type) { last_new_type = patch_type; swamigui_menu_update_new_type_item (); } else patch_type = last_new_type; swamigui_new_item (NULL, patch_type); } static void swamigui_menu_cb_load_files (GtkWidget *mitem, gpointer data) { SwamiguiRoot *root = swamigui_get_root (data); if (root) swamigui_load_files (root); } /* main menu callback to save files */ static void swamigui_menu_cb_save_all (GtkWidget *mitem, gpointer data) { IpatchList *patches; /* save them all */ patches = ipatch_container_get_children (IPATCH_CONTAINER (swami_root->patch_root), IPATCH_TYPE_BASE); if (patches) { if (patches->items) swamigui_save_files (patches, FALSE); g_object_unref (patches); } } static void swamigui_menu_cb_quit (GtkWidget *mitem, gpointer data) { SwamiguiRoot *root = swamigui_get_root (data); if (root) swamigui_root_quit (root); } static void swamigui_menu_cb_preferences (GtkWidget *mitem, gpointer data) { GtkWidget *pref; pref = swamigui_util_lookup_unique_dialog ("preferences", 0); if (!pref) { pref = swamigui_pref_new (); gtk_widget_show (pref); swamigui_util_register_unique_dialog (pref, "preferences", 0); } } static void swamigui_menu_cb_swamitips (GtkWidget *mitem, gpointer data) { SwamiguiRoot *root = swamigui_get_root (data); if (root) swamigui_help_swamitips_create (root); } static void swamigui_menu_cb_splash_image (GtkWidget *mitem, gpointer data) { swamigui_splash_display (0); } #ifdef PYTHON_SUPPORT static void swamigui_menu_cb_python (GtkWidget *mitem, gpointer data) { GtkWidget *window; GtkWidget *pythonview; window = gtk_window_new (GTK_WINDOW_TOPLEVEL); pythonview = swamigui_python_view_new (); gtk_container_add (GTK_CONTAINER (window), pythonview); gtk_widget_show_all (window); } #endif static void swamigui_menu_cb_restart_fluid (GtkWidget *mitem, gpointer data) { /* FIXME - Should be handled by FluidSynth plugin */ swami_wavetbl_close (swamigui_root->wavetbl); swami_wavetbl_open (swamigui_root->wavetbl, NULL); } swami/src/swamigui/SwamiguiTree.h0000644000175000017500000000740411461334205017254 0ustar alessioalessio/* * SwamiguiTree.h - Swami tabbed tree object header file * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_TREE_H__ #define __SWAMIGUI_TREE_H__ #include #include typedef struct _SwamiguiTree SwamiguiTree; typedef struct _SwamiguiTreeClass SwamiguiTreeClass; #define SWAMIGUI_TYPE_TREE (swamigui_tree_get_type ()) #define SWAMIGUI_TREE(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMIGUI_TYPE_TREE, SwamiguiTree)) #define SWAMIGUI_TREE_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMIGUI_TYPE_TREE, SwamiguiTreeClass)) #define SWAMIGUI_IS_TREE(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMIGUI_TYPE_TREE)) #define SWAMIGUI_IS_TREE_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMIGUI_TYPE_TREE)) /* Swami Tree Object (all fields private) */ struct _SwamiguiTree { GtkVBox parent_instance; /*< private >*/ GtkNotebook *notebook; /* notebook widget */ GtkWidget *search_box; /* the box containing the search widgets */ GtkEntry *search_entry; /* the search entry */ IpatchList *stores; /* list of SwamiguiTreeStore objects for each tab */ GList *treeviews; /* list of GtkTreeView widgets for each tab */ SwamiguiTreeStore *selstore; /* currently selected tree store (not ref'd) */ GtkTreeView *seltree; /* currently selected tree (not ref'd) */ IpatchList *selection; /* current selection of GObjects */ gboolean sel_single; /* TRUE if single item selected */ char *search_text; /* current search text */ GObject *search_start; /* search start item (item in tree, not ref'd) */ GObject *search_match; /* current matching search item (not ref'd) */ int search_start_pos; /* start char pos in search_match label */ int search_end_pos; /* start char pos in search_match label */ GList *search_expanded; /* branches which should be collapsed (items) */ }; /* Swami Tree Object class (all fields private) */ struct _SwamiguiTreeClass { GtkVBoxClass parent_class; }; GType swamigui_tree_get_type (void); GtkWidget *swamigui_tree_new (IpatchList *stores); void swamigui_tree_set_store_list (SwamiguiTree *tree, IpatchList *list); IpatchList *swamigui_tree_get_store_list (SwamiguiTree *tree); void swamigui_tree_set_selected_store (SwamiguiTree *tree, SwamiguiTreeStore *store); SwamiguiTreeStore *swamigui_tree_get_selected_store (SwamiguiTree *tree); GObject *swamigui_tree_get_selection_single (SwamiguiTree *tree); IpatchList *swamigui_tree_get_selection (SwamiguiTree *tree); void swamigui_tree_clear_selection (SwamiguiTree *tree); void swamigui_tree_set_selection (SwamiguiTree *tree, IpatchList *list); void swamigui_tree_spotlight_item (SwamiguiTree *tree, GObject *item); void swamigui_tree_search_set_start (SwamiguiTree *tree, GObject *start); void swamigui_tree_search_set_text (SwamiguiTree *tree, const char *text); void swamigui_tree_search_set_visible (SwamiguiTree *tree, gboolean visible); void swamigui_tree_search_next (SwamiguiTree *tree); void swamigui_tree_search_prev (SwamiguiTree *tree); #endif swami/src/swamigui/icons.h0000644000175000017500000001053711461334205015763 0ustar alessioalessio/* * icons.h - Swami stock icons * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_ICONS_H__ #define __SWAMIGUI_ICONS_H__ /* !! keep synchronized with icons.c !! */ #define SWAMIGUI_STOCK_CONCAVE_NEG_BI "swamigui_concave_neg_bi" #define SWAMIGUI_STOCK_CONCAVE_NEG_UNI "swamigui_concave_neg_uni" #define SWAMIGUI_STOCK_CONCAVE_POS_BI "swamigui_concave_pos_bi" #define SWAMIGUI_STOCK_CONCAVE_POS_UNI "swamigui_concave_pos_uni" #define SWAMIGUI_STOCK_CONVEX_NEG_BI "swamigui_convex_neg_bi" #define SWAMIGUI_STOCK_CONVEX_NEG_UNI "swamigui_convex_neg_uni" #define SWAMIGUI_STOCK_CONVEX_POS_BI "swamigui_convex_pos_bi" #define SWAMIGUI_STOCK_CONVEX_POS_UNI "swamigui_convex_pos_uni" #define SWAMIGUI_STOCK_DLS "swamigui_DLS" #define SWAMIGUI_STOCK_EFFECT_CONTROL "swamigui_effect_control" #define SWAMIGUI_STOCK_EFFECT_DEFAULT "swamigui_effect_default" #define SWAMIGUI_STOCK_EFFECT_GRAPH "swamigui_effect_graph" #define SWAMIGUI_STOCK_EFFECT_SET "swamigui_effect_set" #define SWAMIGUI_STOCK_EFFECT_VIEW "swamigui_effect_view" #define SWAMIGUI_STOCK_GIG "swamigui_GIG" #define SWAMIGUI_STOCK_GLOBAL_ZONE "swamigui_global_zone" #define SWAMIGUI_STOCK_INST "swamigui_inst" #define SWAMIGUI_STOCK_LINEAR_NEG_BI "swamigui_linear_neg_bi" #define SWAMIGUI_STOCK_LINEAR_NEG_UNI "swamigui_linear_neg_uni" #define SWAMIGUI_STOCK_LINEAR_POS_BI "swamigui_linear_pos_bi" #define SWAMIGUI_STOCK_LINEAR_POS_UNI "swamigui_linear_pos_uni" #define SWAMIGUI_STOCK_LOOP_NONE "swamigui_loop_none" #define SWAMIGUI_STOCK_LOOP_STANDARD "swamigui_loop_standard" #define SWAMIGUI_STOCK_LOOP_RELEASE "swamigui_loop_release" #define SWAMIGUI_STOCK_MODENV "swamigui_modenv" #define SWAMIGUI_STOCK_MODENV_ATTACK "swamigui_modenv_attack" #define SWAMIGUI_STOCK_MODENV_DECAY "swamigui_modenv_decay" #define SWAMIGUI_STOCK_MODENV_DELAY "swamigui_modenv_delay" #define SWAMIGUI_STOCK_MODENV_HOLD "swamigui_modenv_hold" #define SWAMIGUI_STOCK_MODENV_RELEASE "swamigui_modenv_release" #define SWAMIGUI_STOCK_MODENV_SUSTAIN "swamigui_modenv_sustain" #define SWAMIGUI_STOCK_MODULATOR_EDITOR "swamigui_modulator_editor" #define SWAMIGUI_STOCK_MODULATOR_JUNCT "swamigui_modulator_junct" #define SWAMIGUI_STOCK_MUTE "swamigui_mute" #define SWAMIGUI_STOCK_PIANO "swamigui_piano" #define SWAMIGUI_STOCK_PRESET "swamigui_preset" #define SWAMIGUI_STOCK_PYTHON "swamigui_python" #define SWAMIGUI_STOCK_SAMPLE "swamigui_sample" #define SWAMIGUI_STOCK_SAMPLE_ROM "swamigui_sample_rom" #define SWAMIGUI_STOCK_SAMPLE_VIEWER "swamigui_sample_viewer" #define SWAMIGUI_STOCK_SOUNDFONT "swamigui_SoundFont" #define SWAMIGUI_STOCK_SPLITS "swamigui_splits" #define SWAMIGUI_STOCK_SWITCH_NEG_BI "swamigui_switch_neg_bi" #define SWAMIGUI_STOCK_SWITCH_NEG_UNI "swamigui_switch_neg_uni" #define SWAMIGUI_STOCK_SWITCH_POS_BI "swamigui_switch_pos_bi" #define SWAMIGUI_STOCK_SWITCH_POS_UNI "swamigui_switch_pos_uni" #define SWAMIGUI_STOCK_TREE "swamigui_tree" #define SWAMIGUI_STOCK_TUNING "swamigui_tuning" #define SWAMIGUI_STOCK_VELOCITY "swamigui_velocity" #define SWAMIGUI_STOCK_VOLENV "swamigui_volenv" #define SWAMIGUI_STOCK_VOLENV_ATTACK "swamigui_volenv_attack" #define SWAMIGUI_STOCK_VOLENV_DECAY "swamigui_volenv_decay" #define SWAMIGUI_STOCK_VOLENV_DELAY "swamigui_volenv_delay" #define SWAMIGUI_STOCK_VOLENV_HOLD "swamigui_volenv_hold" #define SWAMIGUI_STOCK_VOLENV_RELEASE "swamigui_volenv_release" #define SWAMIGUI_STOCK_VOLENV_SUSTAIN "swamigui_volenv_sustain" #define SWAMIGUI_ICON_SIZE_CUSTOM_LARGE1 swamigui_icon_size_custom_large1 extern int swamigui_icon_size_custom_large1; char *swamigui_icon_get_category_icon (int category); #endif swami/src/swamigui/help.c0000644000175000017500000002222211704446464015600 0ustar alessioalessio/* * help.c - User interface help routines * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "SwamiguiRoot.h" #include "help.h" #include "splash.h" #include "icons.h" #include "i18n.h" #include "util.h" static void swamigui_help_swamitips_set_tip (GtkWidget *tips, gint tipnum); static void swamigui_help_cb_swamitips_next (GtkWidget *btn, GtkWidget *tips); static void swamigui_help_cb_swamitips_previous (GtkWidget *btn, GtkWidget *tips); static void swamigui_help_cb_again_toggled (GtkWidget *btn, gpointer data); static gchar *swamitips_msg[] = { N_("Welcome to Swami!\n\n" "Many operations are performed by Right clicking on the instrument tree." " The type of item clicked on determines the options that are available."), N_("To select multiple items in the instrument tree:\n" "Hold down CTRL to mark individual items or SHIFT to mark a range."), N_("To zoom in the sample viewer:\n" "Middle click and drag the mouse to the left or right in the sample" " viewer. A vertical line will appear to mark the position to zoom into," " and the distance from the marker determines how fast the zoom is" " performed. Moving the mouse to the opposite side of" " the zoom marker will unzoom. The mouse Wheel can also be used to zoom.\n" "SHIFT Middle click and drag will scroll the sample left or right."), N_("The right most view in the Sample Editor assists with making seamless" " loops. The sample points surrounding the start of the loop are shown" " in green while the end sample points are red. They are overlaid on one" " another, where they intersect they become yellow. Zooming can be performed" " in the loop viewer, just like the normal sample view. The more yellow points" " surrounding the middle line, the more seamless the loop!"), N_("In the note range view click and drag on the same line as the range and" " the nearest endpoint will be adjusted. Multiple ranges can be selected" " using CTRL and SHIFT. Clicking and dragging with the Middle mouse button" " will move a range. The \"Move\" drop down selector can be used to set" " if the ranges, root notes or both are moved together. The root notes" " are shown as blue circles on the same line as the range they belong to."), N_("To add samples to instruments:\n" "Select the samples and/or instrument zones you want to add and then Right" " click on the instrument you would like to add to and select" " \"Paste\". If an instrument zone was selected all its parameters" " will be copied into the newly created zone. The same procedure is used" " to add instruments to presets."), N_("The sample loop finder is actived by clicking the Finder icon in the" " Sample Editor. Two additional range selectors will appear above the sample" " and allow for setting the loop start and end search \"windows\". The" " Config tab contains additional settings which control the algorithm." " The \"Window size\" sets the number of sample points which are compared" " around the loop end points, \"Min loop size\" sets a minimum loop size" " for the results and sample groups provide settings for grouping results" " by their proximity and size. Once the parameters are to your liking," " click the \"Find Loops\" button. The parameter settings can drastically" " affect the time it takes. Once complete a list of results will be" " displayed, clicking a result will assign the given loop. Click the" " \"Revert\" button to return to the loop setting prior to executing the" " find loops operation."), N_("The FFTune plugin provides semi-automated tuning of samples. To access it" " click the FFTune panel tab when a sample or instrument zone is selected." " An FFT calculation is performed and the spectrum is displayed in the view." " A list of tuning results is shown in the list. Clicking a tuning result" " will automatically assign it to the selected sample or zone. Results are" " based on interpreting the strongest frequency components as MIDI root" " note values and calculating the fine tine adjustment required to play" " back the matched frequency component at the given root note. Your milage" " may vary, depending on the sample content. The \"Sample data\" dropdown" " allows for setting what portion of the sample the calculation is" " performed on: All for the entire sample and Loop for just the loop."), N_("Adjusting knobs is done by clicking and dragging the mouse up or down." " Hold the SHIFT key to make finer adjustments."), N_("No more tips!") }; #define TIPCOUNT (sizeof(swamitips_msg) / sizeof(swamitips_msg[0])) static gint swamitip_current; /* current swami tip # */ void swamigui_help_about (void) { GtkWidget *boutwin; GdkPixbuf *pixbuf; if (swamigui_util_activate_unique_dialog ("about", 0)) return; boutwin = swamigui_util_glade_create ("About"); swamigui_util_register_unique_dialog (boutwin, "about", 0); gtk_about_dialog_set_version (GTK_ABOUT_DIALOG (boutwin), VERSION); /* ++ ref Swami logo icon */ pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), "swami_logo", 160, 0, NULL); gtk_about_dialog_set_logo (GTK_ABOUT_DIALOG (boutwin), pixbuf); if (pixbuf) g_object_unref (pixbuf); /* -- unref pixbuf */ g_signal_connect_swapped (G_OBJECT(boutwin), "response", G_CALLBACK (gtk_widget_destroy), boutwin); gtk_widget_show (boutwin); } /* Create swami tips dialog and load it with current tip */ void swamigui_help_swamitips_create (SwamiguiRoot *root) { GtkWidget *tips; GtkWidget *widg; int i; g_return_if_fail (SWAMIGUI_IS_ROOT (root)); if (swamigui_util_activate_unique_dialog ("tips", 0)) return; tips = swamigui_util_glade_create ("Tips"); swamigui_util_register_unique_dialog (tips, "tips", 0); g_object_set_data (G_OBJECT (tips), "root", root); widg = swamigui_util_glade_lookup (tips, "CHKagain"); /* update check button to state of Tips Enabled on startup config var */ g_object_get (root, "tips-enable", &i, NULL); if (i) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widg), TRUE); g_signal_connect (widg, "toggled", G_CALLBACK (swamigui_help_cb_again_toggled), root); widg = swamigui_util_glade_lookup (tips, "BTNnext"); g_signal_connect (G_OBJECT (widg), "clicked", G_CALLBACK (swamigui_help_cb_swamitips_next), tips); widg = swamigui_util_glade_lookup (tips, "BTNprev"); g_signal_connect (G_OBJECT (widg), "clicked", G_CALLBACK (swamigui_help_cb_swamitips_previous), tips); widg = swamigui_util_glade_lookup (tips, "BTNclose"); g_signal_connect_swapped (G_OBJECT (widg), "clicked", G_CALLBACK (gtk_widget_destroy), tips); g_object_get (root, "tips-position", &i, NULL); swamigui_help_swamitips_set_tip (tips, i); gtk_widget_show (tips); } static void swamigui_help_swamitips_set_tip (GtkWidget *tips, gint tipnum) { SwamiguiRoot *root; GtkWidget *txtview; GtkTextBuffer *buffer; GtkWidget *btn; gchar *msg; tipnum = CLAMP (tipnum, 0, TIPCOUNT - 1); btn = swamigui_util_glade_lookup (tips, "BTNprev"); gtk_widget_set_sensitive (btn, (tipnum != 0)); btn = swamigui_util_glade_lookup (tips, "BTNnext"); gtk_widget_set_sensitive (btn, (tipnum != TIPCOUNT - 1)); txtview = swamigui_util_glade_lookup (tips, "TXTview"); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (txtview)); msg = _(swamitips_msg[tipnum]); /* get the tip */ gtk_text_buffer_set_text (buffer, msg, -1); swamitip_current = tipnum; root = g_object_get_data (G_OBJECT (tips), "root"); if (root) { tipnum++; if (tipnum >= TIPCOUNT) tipnum = TIPCOUNT; g_object_set (root, "tips-position", tipnum, NULL); } } /* next tip callback */ static void swamigui_help_cb_swamitips_next (GtkWidget *btn, GtkWidget *tips) { swamigui_help_swamitips_set_tip (tips, swamitip_current + 1); } /* previous tip callback */ static void swamigui_help_cb_swamitips_previous (GtkWidget *btn, GtkWidget *tips) { swamigui_help_swamitips_set_tip (tips, swamitip_current - 1); } static void swamigui_help_cb_again_toggled (GtkWidget *btn, gpointer data) { SwamiguiRoot *root = SWAMIGUI_ROOT (data); g_object_set (root, "tips-enable", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (btn)), NULL); } swami/src/swamigui/SwamiguiPiano.c0000644000175000017500000011231211704446464017424 0ustar alessioalessio/* * SwamiguiPiano.c - Piano canvas item * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include "SwamiguiPiano.h" #include "SwamiguiRoot.h" #include "SwamiguiStatusbar.h" #include "i18n.h" #include "util.h" /* Piano keys: C C# D D# E F F# G G# A A# B */ enum { PROP_0, PROP_WIDTH_PIXELS, /* width in pixels */ PROP_HEIGHT_PIXELS, /* height in pixels */ PROP_KEY_COUNT, /* number of keys in piano */ PROP_START_OCTAVE, /* piano start octave (first key) */ PROP_LOWER_OCTAVE, /* lower keyboard octave */ PROP_UPPER_OCTAVE, /* upper keyboard octave */ PROP_LOWER_VELOCITY, /* lower keyboard velocity */ PROP_UPPER_VELOCITY, /* upper keyboard velocity */ PROP_MIDI_CONTROL, /* Piano MIDI control */ PROP_EXPRESS_CONTROL, /* Piano expression control */ PROP_MIDI_CHANNEL, /* MIDI channel to send events on */ PROP_BG_COLOR, /* color of border and in between white keys */ PROP_WHITE_KEY_COLOR, /* color of white keys */ PROP_BLACK_KEY_COLOR, /* color of black keys */ PROP_SHADOW_EDGE_COLOR, /* color of white key shadow edge */ PROP_WHITE_KEY_PLAY_COLOR, /* color of white key play highlight color */ PROP_BLACK_KEY_PLAY_COLOR /* color of black key play highlight color */ }; enum { NOTE_ON, NOTE_OFF, LAST_SIGNAL }; #define DEFAULT_BG_COLOR GNOME_CANVAS_COLOR (0, 0, 0) #define DEFAULT_WHITE_KEY_COLOR GNOME_CANVAS_COLOR (255, 255, 255) #define DEFAULT_BLACK_KEY_COLOR GNOME_CANVAS_COLOR (0, 0, 0) #define DEFAULT_SHADOW_EDGE_COLOR GNOME_CANVAS_COLOR (128, 128, 128) #define DEFAULT_WHITE_KEY_PLAY_COLOR GNOME_CANVAS_COLOR (169, 127, 255) #define DEFAULT_BLACK_KEY_PLAY_COLOR GNOME_CANVAS_COLOR (169, 127, 255) /* piano vertical line width to white key width scale */ #define PIANO_VLINE_TO_KEY_SCALE (1.0/5.0) /* piano horizontal line width to piano height scale */ #define PIANO_HLINE_TO_HEIGHT_SCALE (1.0/48.0) /* piano black key height to piano height */ #define PIANO_BLACK_TO_HEIGHT_SCALE (26.0/48.0) /* piano white key grey edge to piano height scale */ #define PIANO_GREY_TO_HEIGHT_SCALE (2.0/48.0) /* piano white key indicator width to key scale */ #define PIANO_WHITE_INDICATOR_WIDTH_SCALE (4.0/8.0) /* piano white key indicator height to piano height scale */ #define PIANO_WHITE_INDICATOR_HEIGHT_SCALE (2.0/48.0) /* piano white key velocity indicator range to height scale */ #define PIANO_WHITE_INDICATOR_RANGE_SCALE (18.0/48.0) /* piano white key velocity offset to height scale */ #define PIANO_WHITE_INDICATOR_OFS_SCALE (28.0/48.0) /* piano black key indicator width to key scale */ #define PIANO_BLACK_INDICATOR_WIDTH_SCALE (3.0/5.0) /* piano black key indicator height to piano height scale */ #define PIANO_BLACK_INDICATOR_HEIGHT_SCALE (3.0/48.0) /* piano black key velocity indicator range scale */ #define PIANO_BLACK_INDICATOR_RANGE_SCALE (22.0/28.0) /* piano black key velocity offset scale */ #define PIANO_BLACK_INDICATOR_OFS_SCALE (2.0/28.0) /* piano active black key shorten scale (to look pressed down) */ #define PIANO_BLACK_SHORTEN_SCALE (1.0/26.0) /* a structure used for each key of a piano */ typedef struct { GnomeCanvasItem *item; /* canvas item for keys (black and white) */ GnomeCanvasItem *indicator; /* indicator item (if set note is active) */ GnomeCanvasItem *shadow; /* bottom shadow edge for white keys */ } KeyInfo; static void swamigui_piano_class_init (SwamiguiPianoClass *klass); static void swamigui_piano_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void swamigui_piano_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void swamigui_piano_init (SwamiguiPiano *piano); static void swamigui_piano_finalize (GObject *object); static void swamigui_piano_midi_ctrl_callback (SwamiControl *control, SwamiControlEvent *event, const GValue *value); static void swamigui_piano_item_realize (GnomeCanvasItem *item); static void swamigui_piano_draw (SwamiguiPiano *piano); static void swamigui_piano_destroy_keys (SwamiguiPiano *piano); static void swamigui_piano_update_key_colors (SwamiguiPiano *piano); static void swamigui_piano_draw_noteon (SwamiguiPiano *piano, int note, int velocity); static void swamigui_piano_draw_noteoff (SwamiguiPiano *piano, int note); static void swamigui_piano_update_mouse_note (SwamiguiPiano *piano, double x, double y); static gboolean swamigui_piano_cb_event (GnomeCanvasItem *item, GdkEvent *event, gpointer data); static gboolean swamigui_piano_note_on_internal (SwamiguiPiano *piano, int note, int velocity); static gboolean swamigui_piano_note_off_internal (SwamiguiPiano *piano, int note, int velocity); static GObjectClass *parent_class = NULL; static guint piano_signals[LAST_SIGNAL] = {0}; GType swamigui_piano_get_type (void) { static GType obj_type = 0; if (!obj_type) { static const GTypeInfo obj_info = { sizeof (SwamiguiPianoClass), NULL, NULL, (GClassInitFunc) swamigui_piano_class_init, NULL, NULL, sizeof (SwamiguiPiano), 0, (GInstanceInitFunc) swamigui_piano_init, }; obj_type = g_type_register_static (GNOME_TYPE_CANVAS_GROUP, "SwamiguiPiano", &obj_info, 0); } return (obj_type); } static void swamigui_piano_class_init (SwamiguiPianoClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); GnomeCanvasItemClass *canvas_item_class = GNOME_CANVAS_ITEM_CLASS (klass); parent_class = g_type_class_peek_parent (klass); obj_class->set_property = swamigui_piano_set_property; obj_class->get_property = swamigui_piano_get_property; obj_class->finalize = swamigui_piano_finalize; canvas_item_class->realize = swamigui_piano_item_realize; piano_signals[NOTE_ON] = g_signal_new ("note-on", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (SwamiguiPianoClass, note_on), NULL, NULL, g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT); piano_signals[NOTE_OFF] = g_signal_new ("note-off", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (SwamiguiPianoClass, note_off), NULL, NULL, g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT); g_object_class_install_property (obj_class, PROP_WIDTH_PIXELS, g_param_spec_int ("width-pixels", _("Pixel Width"), _("Width in pixels"), 1, G_MAXINT, SWAMIGUI_PIANO_DEFAULT_WIDTH, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_HEIGHT_PIXELS, g_param_spec_int ("height-pixels", _("Pixel Height"), _("Height in pixels"), 1, G_MAXINT, SWAMIGUI_PIANO_DEFAULT_HEIGHT, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_KEY_COUNT, g_param_spec_int ("key-count", _("Key Count"), _("Size of piano in keys"), 1, 128, 128, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (obj_class, PROP_START_OCTAVE, g_param_spec_int ("start-octave", _("Start Octave"), _("Piano start octave (0 = MIDI note 0"), 0, 10, 0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_LOWER_OCTAVE, g_param_spec_int ("lower-octave", _("Lower Octave"), _("Lower keyboard start octave"), 0, 10, SWAMIGUI_PIANO_DEFAULT_LOWER_OCTAVE, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_UPPER_OCTAVE, g_param_spec_int ("upper-octave", _("Upper Octave"), _("Upper keyboard start octave"), 0, 10, SWAMIGUI_PIANO_DEFAULT_UPPER_OCTAVE, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_LOWER_VELOCITY, g_param_spec_int ("lower-velocity", _("Lower Velocity"), _("Lower keyboard velocity"), 0, 127, 127, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_UPPER_VELOCITY, g_param_spec_int ("upper-velocity", _("Upper Velocity"), _("Upper keyboard velocity"), 0, 127, 127, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_MIDI_CONTROL, g_param_spec_object ("midi-control", _("MIDI Control"), _("Piano MIDI control"), SWAMI_TYPE_CONTROL, G_PARAM_READABLE)); g_object_class_install_property (obj_class, PROP_EXPRESS_CONTROL, g_param_spec_object ("expression-control", _("Expression Control"), _("Piano expression control (vertical mouse axis)"), SWAMI_TYPE_CONTROL, G_PARAM_READABLE)); g_object_class_install_property (obj_class, PROP_MIDI_CHANNEL, g_param_spec_int ("midi-channel", _("MIDI Channel"), _("MIDI channel to send events on"), 0, 15, 0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_BG_COLOR, ipatch_param_set (g_param_spec_uint ("bg-color", _("Background color"), _("Color of border and between white keys"), 0, G_MAXUINT, DEFAULT_BG_COLOR, G_PARAM_READWRITE), "unit-type", SWAMIGUI_UNIT_RGBA_COLOR, NULL)); g_object_class_install_property (obj_class, PROP_WHITE_KEY_COLOR, ipatch_param_set (g_param_spec_uint ("white-key-color", _("White key color"), _("White key color"), 0, G_MAXUINT, DEFAULT_WHITE_KEY_COLOR, G_PARAM_READWRITE), "unit-type", SWAMIGUI_UNIT_RGBA_COLOR, NULL)); g_object_class_install_property (obj_class, PROP_BLACK_KEY_COLOR, ipatch_param_set (g_param_spec_uint ("black-key-color", _("Black key color"), _("Black key color"), 0, G_MAXUINT, DEFAULT_BLACK_KEY_COLOR, G_PARAM_READWRITE), "unit-type", SWAMIGUI_UNIT_RGBA_COLOR, NULL)); g_object_class_install_property (obj_class, PROP_SHADOW_EDGE_COLOR, ipatch_param_set (g_param_spec_uint ("shadow-edge-color", _("Shadow edge color"), _("Bottom shadow edge color"), 0, G_MAXUINT, DEFAULT_SHADOW_EDGE_COLOR, G_PARAM_READWRITE), "unit-type", SWAMIGUI_UNIT_RGBA_COLOR, NULL)); g_object_class_install_property (obj_class, PROP_WHITE_KEY_PLAY_COLOR, ipatch_param_set (g_param_spec_uint ("white-key-play-color", _("White key player color"), _("Color of white key play highlight"), 0, G_MAXUINT, DEFAULT_WHITE_KEY_PLAY_COLOR, G_PARAM_READWRITE), "unit-type", SWAMIGUI_UNIT_RGBA_COLOR, NULL)); g_object_class_install_property (obj_class, PROP_BLACK_KEY_PLAY_COLOR, ipatch_param_set (g_param_spec_uint ("black-key-play-color", _("Black key play color"), _("Color of black key play highlight"), 0, G_MAXUINT, DEFAULT_BLACK_KEY_PLAY_COLOR, G_PARAM_READWRITE), "unit-type", SWAMIGUI_UNIT_RGBA_COLOR, NULL)); } static void swamigui_piano_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { SwamiguiPiano *piano = SWAMIGUI_PIANO (object); switch (property_id) { case PROP_WIDTH_PIXELS: piano->width = g_value_get_int (value); piano->up2date = FALSE; swamigui_piano_draw (piano); break; case PROP_HEIGHT_PIXELS: piano->height = g_value_get_int (value); piano->up2date = FALSE; swamigui_piano_draw (piano); break; case PROP_KEY_COUNT: piano->key_count = g_value_get_int (value); swamigui_piano_destroy_keys (piano); swamigui_piano_draw (piano); break; case PROP_START_OCTAVE: piano->start_note = g_value_get_int (value) * 12; break; case PROP_LOWER_OCTAVE: piano->lower_octave = g_value_get_int (value); break; case PROP_UPPER_OCTAVE: piano->upper_octave = g_value_get_int (value); break; case PROP_LOWER_VELOCITY: piano->lower_velocity = g_value_get_int (value); break; case PROP_UPPER_VELOCITY: piano->upper_velocity = g_value_get_int (value); break; case PROP_MIDI_CHANNEL: piano->midi_chan = g_value_get_int (value); break; case PROP_BG_COLOR: piano->bg_color = g_value_get_uint (value); if (piano->bg) g_object_set (piano->bg, "fill-color", piano->bg_color, NULL); break; case PROP_WHITE_KEY_COLOR: piano->white_key_color = g_value_get_uint (value); swamigui_piano_update_key_colors (piano); break; case PROP_BLACK_KEY_COLOR: piano->black_key_color = g_value_get_uint (value); swamigui_piano_update_key_colors (piano); break; case PROP_SHADOW_EDGE_COLOR: piano->shadow_edge_color = g_value_get_uint (value); swamigui_piano_update_key_colors (piano); break; case PROP_WHITE_KEY_PLAY_COLOR: piano->white_key_play_color = g_value_get_uint (value); break; case PROP_BLACK_KEY_PLAY_COLOR: piano->black_key_play_color = g_value_get_uint (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_piano_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { SwamiguiPiano *piano = SWAMIGUI_PIANO (object); switch (property_id) { case PROP_WIDTH_PIXELS: g_value_set_int (value, piano->width); break; case PROP_HEIGHT_PIXELS: g_value_set_int (value, piano->height); break; case PROP_KEY_COUNT: g_value_set_int (value, piano->key_count); break; case PROP_START_OCTAVE: g_value_set_int (value, piano->start_note / 12); break; case PROP_LOWER_OCTAVE: g_value_set_int (value, piano->lower_octave); break; case PROP_UPPER_OCTAVE: g_value_set_int (value, piano->upper_octave); break; case PROP_LOWER_VELOCITY: g_value_set_int (value, piano->lower_velocity); break; case PROP_UPPER_VELOCITY: g_value_set_int (value, piano->upper_velocity); break; case PROP_MIDI_CONTROL: g_value_set_object (value, piano->midi_ctrl); break; case PROP_EXPRESS_CONTROL: g_value_set_object (value, piano->express_ctrl); break; case PROP_MIDI_CHANNEL: g_value_set_int (value, piano->midi_chan); break; case PROP_BG_COLOR: g_value_set_uint (value, piano->bg_color); break; case PROP_WHITE_KEY_COLOR: g_value_set_uint (value, piano->white_key_color); break; case PROP_BLACK_KEY_COLOR: g_value_set_uint (value, piano->black_key_color); break; case PROP_SHADOW_EDGE_COLOR: g_value_set_uint (value, piano->shadow_edge_color); break; case PROP_WHITE_KEY_PLAY_COLOR: g_value_set_uint (value, piano->white_key_play_color); break; case PROP_BLACK_KEY_PLAY_COLOR: g_value_set_uint (value, piano->black_key_play_color); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_piano_init (SwamiguiPiano *piano) { int i; /* create MIDI control */ piano->midi_ctrl = SWAMI_CONTROL (swami_control_midi_new ()); swami_control_set_queue (piano->midi_ctrl, swamigui_root->ctrl_queue); swami_control_midi_set_callback (SWAMI_CONTROL_MIDI (piano->midi_ctrl), swamigui_piano_midi_ctrl_callback, piano); /* create expression control */ piano->express_ctrl = SWAMI_CONTROL (swami_control_value_new ()); swami_control_set_queue (piano->express_ctrl, swamigui_root->ctrl_queue); swami_control_set_spec (piano->express_ctrl, g_param_spec_int ("expression", "Expression", "Expression", 0, 127, 0, G_PARAM_READWRITE)); swami_control_value_alloc_value (SWAMI_CONTROL_VALUE (piano->express_ctrl)); piano->velocity = 127; /* default velocity */ piano->key_count = 128; /* FIXME: Shouldn't it get set on construction? */ piano->width = SWAMIGUI_PIANO_DEFAULT_WIDTH; piano->height = SWAMIGUI_PIANO_DEFAULT_HEIGHT; piano->key_info = NULL; piano->start_note = 0; piano->lower_octave = SWAMIGUI_PIANO_DEFAULT_LOWER_OCTAVE; piano->upper_octave = SWAMIGUI_PIANO_DEFAULT_UPPER_OCTAVE; piano->lower_velocity = 127; piano->upper_velocity = 127; piano->mouse_note = 128; /* disabled mouse key (> 127) */ piano->bg_color = DEFAULT_BG_COLOR; piano->white_key_color = DEFAULT_WHITE_KEY_COLOR; piano->black_key_color = DEFAULT_BLACK_KEY_COLOR; piano->shadow_edge_color = DEFAULT_SHADOW_EDGE_COLOR; piano->white_key_play_color = DEFAULT_WHITE_KEY_PLAY_COLOR; piano->black_key_play_color = DEFAULT_BLACK_KEY_PLAY_COLOR; /* get the white key count for the number of keys in the piano */ piano->white_count = piano->key_count / 12 * 7; /* 7 whites per oct */ i = piano->key_count % 12; /* calculate for octave remainder (if any) */ if (i < 6) piano->white_count += (i + 1) / 2; else piano->white_count += (i | 0x1) / 2 + 1; g_signal_connect (G_OBJECT (piano), "event", G_CALLBACK (swamigui_piano_cb_event), piano); } static void swamigui_piano_finalize (GObject *object) { SwamiguiPiano *piano = SWAMIGUI_PIANO (object); g_object_unref (piano->midi_ctrl); /* -- unref MIDI control */ g_object_unref (piano->express_ctrl); /* -- unref expression control */ g_free (piano->key_info); piano->key_info = NULL; if (G_OBJECT_CLASS (parent_class)->finalize) (* G_OBJECT_CLASS (parent_class)->finalize)(object); } /* SwamiControlFunc set value func for MIDI control */ static void swamigui_piano_midi_ctrl_callback (SwamiControl *control, SwamiControlEvent *event, const GValue *value) { SwamiguiPiano *piano = SWAMIGUI_PIANO (SWAMI_CONTROL_FUNC(control)->user_data); GValueArray *valarray = NULL; SwamiMidiEvent *midi; int i, count = 1; /* default for single values */ /* if its multiple values, fetch the value array */ if (G_VALUE_TYPE (value) == G_TYPE_VALUE_ARRAY) { valarray = g_value_get_boxed (value); count = valarray->n_values; } i = 0; while (i < count) { if (valarray) value = g_value_array_get_nth (valarray, i); if (G_VALUE_TYPE (value) == SWAMI_TYPE_MIDI_EVENT && (midi = g_value_get_boxed (value))) { if (midi->channel == piano->midi_chan) { switch (midi->type) { case SWAMI_MIDI_NOTE_ON: swamigui_piano_note_on_internal (piano, midi->data.note.note, midi->data.note.velocity); break; case SWAMI_MIDI_NOTE_OFF: swamigui_piano_note_off_internal (piano, midi->data.note.note, midi->data.note.velocity); break; default: break; } } } i++; } } static void swamigui_piano_item_realize (GnomeCanvasItem *item) { SwamiguiPiano *piano = SWAMIGUI_PIANO (item); if (GNOME_CANVAS_ITEM_CLASS (parent_class)->realize) (*GNOME_CANVAS_ITEM_CLASS (parent_class)->realize) (item); swamigui_piano_draw (piano); } static void swamigui_piano_draw (SwamiguiPiano *piano) { GnomeCanvasGroup *group = GNOME_CANVAS_GROUP (piano); KeyInfo *keyp; gboolean isblack; double x, x1, x2; int i, mod; int vlineh1, vlineh2; /* return if not added to a canvas yet */ if (!GNOME_CANVAS_ITEM (piano)->canvas) return; if (!piano->up2date) { /* convert pixel width and height to world values */ gnome_canvas_c2w (GNOME_CANVAS_ITEM (piano)->canvas, piano->width, piano->height, &piano->world_width, &piano->world_height); piano->key_width = piano->world_width / piano->key_count; piano->key_width_half = piano->key_width / 2; piano->vline_width = (int)(piano->key_width * PIANO_VLINE_TO_KEY_SCALE + 0.5); piano->hline_width = (int)(piano->height * PIANO_HLINE_TO_HEIGHT_SCALE + 0.5); /* black key dimensions */ piano->black_height = piano->world_height * PIANO_BLACK_TO_HEIGHT_SCALE; /* top of grey edge */ piano->shadow_top = piano->world_height - piano->hline_width - piano->world_height * PIANO_GREY_TO_HEIGHT_SCALE; /* black key velocity range and offset cache values */ piano->black_vel_ofs = piano->black_height * PIANO_BLACK_INDICATOR_OFS_SCALE; piano->black_vel_range = piano->black_height * PIANO_BLACK_INDICATOR_RANGE_SCALE; /* white key velocity range and offset cache values */ piano->white_vel_ofs = piano->world_height * PIANO_WHITE_INDICATOR_OFS_SCALE; piano->white_vel_range = piano->world_height * PIANO_WHITE_INDICATOR_RANGE_SCALE; piano->up2date = TRUE; } if (!piano->bg) /* one time canvas item creation */ piano->bg = /* black piano background (border & separators) */ gnome_canvas_item_new (group, GNOME_TYPE_CANVAS_RECT, "x1", (double)0.0, "y1", (double)0.0, "fill-color-rgba", piano->bg_color, "outline-color", NULL, NULL); /* create black and white keys if not already done */ if (!piano->key_info) { piano->key_info = g_new0 (KeyInfo, piano->key_count); for (i = 0, mod = 0, isblack = FALSE; i < piano->key_count; i++, mod++) { if (mod == 12) mod = 0; /* octave modulo */ keyp = &((KeyInfo *)(piano->key_info))[i]; /* create grey edge for white keys */ if (!isblack) { /* bottom grey edge of white keys */ keyp->shadow = gnome_canvas_item_new (group, GNOME_TYPE_CANVAS_RECT, "fill-color-rgba", piano->shadow_edge_color, "outline-color", NULL, NULL); } keyp->item = gnome_canvas_item_new (group, GNOME_TYPE_CANVAS_RECT, "fill-color-rgba", isblack ? piano->black_key_color : piano->white_key_color, NULL); /* lower white keys one step (so previous black key is above it) */ if (i > 0 && !isblack) { gnome_canvas_item_lower (keyp->item, 2); gnome_canvas_item_lower (keyp->shadow, 2); } if (mod != 4 && mod != 11) isblack ^= 1; } } gnome_canvas_item_set (piano->bg, /* set background size */ "x2", piano->world_width, "y2", piano->world_height, NULL); /* calculate halves of vline_width */ vlineh1 = (int)(piano->vline_width + 0.5); vlineh2 = vlineh1 / 2; vlineh1 -= vlineh2; for (i = 0, mod = 0, isblack = FALSE; i < piano->key_count; i++, mod++) { if (mod == 12) mod = 0; /* octave modulo */ keyp = &((KeyInfo *)(piano->key_info))[i]; x = i * piano->world_width / piano->key_count; if (isblack) /* key is black? */ { gnome_canvas_item_set (keyp->item, "x1", x, "x2", x + piano->key_width, "y1", piano->hline_width, "y2", piano->black_height, NULL); } else /* white key */ { if (mod == 0 || mod == 5) x1 = x; else x1 = x - piano->key_width_half; if (mod == 4 || mod == 11) x2 = x + piano->key_width; else if (i != piano->key_count - 1) x2 = x + piano->key_width + piano->key_width_half; else x2 = x + piano->key_width - 1.0; x1 += vlineh1; x2 -= vlineh2; gnome_canvas_item_set (keyp->item, "x1", x1, "x2", x2, "y1", piano->hline_width, "y2", piano->shadow_top, NULL); gnome_canvas_item_set (keyp->shadow, "x1", x1, "x2", x2, "y1", piano->shadow_top, "y2", piano->world_height - piano->hline_width, NULL); } if (mod != 4 && mod != 11) isblack ^= 1; } } /* called to destroy piano keys (used when key count changes for example) */ static void swamigui_piano_destroy_keys (SwamiguiPiano *piano) { KeyInfo *keyp; int i; if (!piano->key_info) return; for (i = 0; i < piano->key_count; i++) { keyp = &((KeyInfo *)(piano->key_info))[i]; if (keyp->item) gtk_object_destroy (GTK_OBJECT (keyp->item)); if (keyp->indicator) gtk_object_destroy (GTK_OBJECT (keyp->indicator)); if (keyp->shadow) gtk_object_destroy (GTK_OBJECT (keyp->shadow)); } g_free (piano->key_info); piano->key_info = NULL; } /* Update the color of keys. * keytype: 0 = white, 1 = black, 2 = grey edge */ static void swamigui_piano_update_key_colors (SwamiguiPiano *piano) { KeyInfo *keyp; gboolean isblack; int i, mod; for (i = 0, mod = 0, isblack = FALSE; i < piano->key_count; i++, mod++) { if (mod == 12) mod = 0; /* octave modulo */ keyp = &((KeyInfo *)(piano->key_info))[i]; if (!isblack) { if (keyp->item) g_object_set (keyp->item, "fill-color-rgba", piano->white_key_color, NULL); if (keyp->shadow) g_object_set (keyp->shadow, "fill-color-rgba", piano->shadow_edge_color, NULL); } else if (keyp->item) g_object_set (keyp->item, "fill-color-rgba", piano->black_key_color, NULL); if (mod != 4 && mod != 11) isblack ^= 1; } } static void swamigui_piano_draw_noteon (SwamiguiPiano *piano, int note, int velocity) { GnomeCanvasGroup *group = GNOME_CANVAS_GROUP (piano); KeyInfo *key_info; double pos, w, vel; int note_ofs; gboolean black; /* get key info structure for note */ note_ofs = note - piano->start_note; key_info = &((KeyInfo *)(piano->key_info))[note_ofs]; pos = swamigui_piano_note_to_pos (piano, note, 0, TRUE, &black); if (!black) /* white key? */ { /* lengthen white key to make it look pressed down */ gnome_canvas_item_set (GNOME_CANVAS_ITEM (key_info->item), "y2", piano->world_height - piano->hline_width, NULL); /* calculate size and velocity position of white key indicator */ w = piano->key_width_half * PIANO_WHITE_INDICATOR_WIDTH_SCALE; vel = velocity * piano->white_vel_range / 127.0 + piano->white_vel_ofs; } else /* black key */ { /* shorten black key to make it look pressed down */ gnome_canvas_item_set (GNOME_CANVAS_ITEM (key_info->item), "y2", piano->black_height - piano->black_height * PIANO_BLACK_SHORTEN_SCALE, NULL); /* calculate size and velocity position of black key indicator */ w = piano->key_width_half * PIANO_BLACK_INDICATOR_WIDTH_SCALE; vel = velocity * piano->black_vel_range / 127.0 + piano->black_vel_ofs; } /* create the indicator */ key_info->indicator = gnome_canvas_item_new (group, GNOME_TYPE_CANVAS_RECT, "x1", pos - w, "y1", piano->hline_width, "x2", pos + w, "y2", vel, "fill-color-rgba", black ? piano->black_key_play_color : piano->white_key_play_color, "outline-color", NULL, NULL); } static void swamigui_piano_draw_noteoff (SwamiguiPiano *piano, int note) { KeyInfo *key_info; int note_ofs, mod; gboolean black; /* get key info structure for note */ note_ofs = note - piano->start_note; key_info = &((KeyInfo *)(piano->key_info))[note_ofs]; if (!key_info->indicator) return; /* destroy indicator */ gtk_object_destroy (GTK_OBJECT (key_info->indicator)); key_info->indicator = NULL; /* determine if key is black or white */ mod = note % 12; if (mod <= 4) black = mod & 1; else black = !(mod & 1); if (black) { /* reset black key back to normal length */ gnome_canvas_item_set (GNOME_CANVAS_ITEM (key_info->item), "y2", piano->black_height, NULL); } else /* reset white key back to normal length */ { gnome_canvas_item_set (GNOME_CANVAS_ITEM (key_info->item), "y2", piano->shadow_top, NULL); } } static void swamigui_piano_update_mouse_note (SwamiguiPiano *piano, double x, double y) { static guint8 last_note = -1; /* cache note number for statusbar */ KeyInfo *key_info; double indicator_y; int note, velocity = 127; char midiNote[5]; char *statusmsg; int *velp = NULL; gboolean isblack; if (x < 0.0) x = 0.0; else if (x > piano->world_width) x = piano->world_width; else velp = &velocity; if (y < 0.0 || y > piano->world_height) { y = 0.0; velp = NULL; } note = swamigui_piano_pos_to_note (piano, x, y, velp, &isblack); note = CLAMP (note, 0, 127); /* force clamp note */ key_info = &((KeyInfo *)(piano->key_info))[note]; if (isblack) indicator_y = piano->black_vel_ofs + (velocity * piano->black_vel_range / 127.0); else indicator_y = piano->white_vel_ofs + (velocity * piano->white_vel_range / 127.0); if (last_note != note) /* update statusbar note value */ { swami_util_midi_note_to_str (note, midiNote); statusmsg = g_strdup_printf (_("Note: %-3s (%d) Velocity: %d"), midiNote, note, velocity); swamigui_statusbar_msg_set_label (swamigui_root->statusbar, 0, "Global", statusmsg); g_free (statusmsg); } if (piano->mouse_note > 127) return; /* if mouse note play not active, we done */ if (note != piano->mouse_note) /* note changed? */ { swamigui_piano_note_off (piano, piano->mouse_note, 127); /* note off */ piano->mouse_note = note; swamigui_piano_note_on (piano, note, velocity); /* new note on */ } else /* same note, update indicator for velocity */ { gnome_canvas_item_set (key_info->indicator, "y2", indicator_y, NULL); } } static gboolean swamigui_piano_cb_event (GnomeCanvasItem *item, GdkEvent *event, gpointer data) { SwamiguiPiano *piano = SWAMIGUI_PIANO (data); GdkEventButton *bevent; GdkEventMotion *mevent; int note, velocity; switch (event->type) { case GDK_BUTTON_PRESS: bevent = (GdkEventButton *)event; if (bevent->button != 1) break; note = swamigui_piano_pos_to_note (piano, bevent->x, bevent->y, &velocity, NULL); if (note < 0) break; /* click not on a note? */ piano->mouse_note = note; swamigui_piano_note_on (piano, note, velocity); gnome_canvas_item_grab (item, GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, NULL, bevent->time); return (TRUE); case GDK_BUTTON_RELEASE: if (piano->mouse_note > 127) break; /* no mouse selected note? */ note = piano->mouse_note; piano->mouse_note = 128; /* no more selected mouse note */ swamigui_piano_note_off (piano, note, 127); gnome_canvas_item_ungrab (item, event->button.time); break; case GDK_MOTION_NOTIFY: mevent = (GdkEventMotion *)event; swamigui_piano_update_mouse_note (piano, mevent->x, mevent->y); break; case GDK_LEAVE_NOTIFY: swamigui_statusbar_msg_set_label (swamigui_root->statusbar, 0, "Global", NULL); break; default: break; } return (FALSE); } /** * swamigui_piano_note_on: * @piano: Piano object * @note: MIDI note number to turn on * @velocity: MIDI velocity number (-1 to use current keyboard velocity) * * Piano note on. Turns on note visually on piano as well as sends an event to * #SwamiControl objects connected to piano MIDI event control. */ void swamigui_piano_note_on (SwamiguiPiano *piano, int note, int velocity) { if (velocity == -1) velocity = piano->velocity; if (velocity == 0) swamigui_piano_note_off (piano, note, velocity); if (swamigui_piano_note_on_internal (piano, note, velocity)) { /* send a note on event */ swami_control_midi_transmit (SWAMI_CONTROL_MIDI (piano->midi_ctrl), SWAMI_MIDI_NOTE_ON, piano->midi_chan, note, velocity); } } /* internal function for visually displaying a note on */ static gboolean swamigui_piano_note_on_internal (SwamiguiPiano *piano, int note, int velocity) { KeyInfo *key_info; int start_note; g_return_val_if_fail (SWAMIGUI_IS_PIANO (piano), FALSE); g_return_val_if_fail (note >= 0 && note <= 127, FALSE); g_return_val_if_fail (velocity >= -1 && velocity <= 127, FALSE); start_note = piano->start_note; if (note < start_note || note >= start_note + piano->key_count) return (FALSE); key_info = &((KeyInfo *)(piano->key_info))[note - start_note]; if (key_info->indicator) return (FALSE); /* note already on? */ swamigui_piano_draw_noteon (piano, note, velocity); return (TRUE); } /** * swamigui_piano_note_off: * @piano: Piano object * @note: MIDI note number to turn off * @velocity: MIDI note off velocity * * Piano note off. Turns off note visually on piano as well as sends an event * to it's connected MIDI driver (if any). */ void swamigui_piano_note_off (SwamiguiPiano *piano, int note, int velocity) { if (swamigui_piano_note_off_internal (piano, note, velocity)) { /* send a note off event */ swami_control_midi_transmit (SWAMI_CONTROL_MIDI (piano->midi_ctrl), SWAMI_MIDI_NOTE_OFF, piano->midi_chan, note, velocity); } } /* updates drawing of piano */ static gboolean swamigui_piano_note_off_internal (SwamiguiPiano *piano, int note, int velocity) { KeyInfo *key_info; int start_note; g_return_val_if_fail (SWAMIGUI_IS_PIANO (piano), FALSE); g_return_val_if_fail (note >= 0 && note <= 127, FALSE); g_return_val_if_fail (velocity >= -1 && velocity <= 127, FALSE); start_note = piano->start_note; if (note < start_note || note >= start_note + piano->key_count) return (FALSE); key_info = &((KeyInfo *)(piano->key_info))[note - start_note]; if (!key_info->indicator) return (FALSE); /* note already off? */ swamigui_piano_draw_noteoff (piano, note); return (TRUE); } /** * swamigui_piano_pos_to_note: * @piano: Piano object * @x: X coordinate in canvas world units * @y: Y coordinate in canvas world units * @velocity: Location to store velocity or %NULL * @isblack: Location to store a boolean if key is black/white, or %NULL * * Get the MIDI note corresponding to a point on the piano. The velocity * relates to the vertical axis of the note. Positions towards the tip * of the key generate higher velocities. * * Returns: The MIDI note number or -1 if not a valid key. */ int swamigui_piano_pos_to_note (SwamiguiPiano *piano, double x, double y, int *velocity, gboolean *isblack) { gboolean black; gdouble keyofs; int note, mod; g_return_val_if_fail (SWAMIGUI_IS_PIANO (piano), -1); /* within piano bounds? */ if (x < 0.0 || x > piano->world_width || y < 0.0 || y > piano->world_height) return (-1); /* calculate note */ note = x / piano->key_width; if (note >= piano->key_count) note = piano->key_count - 1; mod = note % 12; black = (mod == 1 || mod == 3 || mod == 6 || mod == 8 || mod == 10); if (black && y > piano->black_height) /* select white key, if below black keys */ { keyofs = x - (note * piano->key_width); if (keyofs >= piano->key_width_half) { note++; if (note >= piano->key_count) note = piano->key_count - 1; } else note--; black = FALSE; } if (velocity) { if (black) { if (y < piano->black_vel_ofs) *velocity = 1; else if (y > piano->black_vel_ofs + piano->black_vel_range) *velocity = 127; else *velocity = 1.0 + (y - piano->black_vel_ofs) / (piano->black_vel_range) * 126.0 + 0.5; } else /* white key */ { if (y < piano->white_vel_ofs) *velocity = 1; else if (y > piano->white_vel_ofs + piano->white_vel_range) *velocity = 127; else *velocity = 1.0 + (y - piano->white_vel_ofs) / (piano->white_vel_range) * 126.0 + 0.5; } } if (isblack) *isblack = black; return (piano->start_note + note); } /** * swamigui_piano_note_to_pos (SwamiguiPiano *piano, int note, gboolean isblack) * @piano: Piano object * @note: MIDI note number to convert to canvas position * @edge: Which edge to get position of (-1 = left, 0 = center, 1 = right) * @realnote: If %TRUE then the coordinate is adjusted for the actual drawn key * rather than the active area (equal for all keys), when %FALSE is specified. * @isblack: Pointer to store a gboolean which is set if key is black, or %NULL * * Find the canvas X coordinate for a given MIDI note. * * Returns: X canvas coordinate of @note for the specified @edge. */ double swamigui_piano_note_to_pos (SwamiguiPiano *piano, int note, int edge, gboolean realnote, gboolean *isblack) { int noteofs; double pos; gboolean black; int mod; g_return_val_if_fail (SWAMIGUI_IS_PIANO (piano), 0.0); g_return_val_if_fail (note >= piano->start_note, 0.0); noteofs = note - piano->start_note; g_return_val_if_fail (noteofs < piano->key_count, 0.0); /* calculate position to note */ pos = noteofs * piano->world_width / piano->key_count; mod = note % 12; black = (mod == 1 || mod == 3 || mod == 6 || mod == 8 || mod == 10); if (!realnote || black) /* active area request or black key? */ { /* active area is equal for all keys and black keys are equal to active area */ if (edge == 0) pos += piano->key_width_half; else if (edge == 1) { pos += piano->key_width; if (noteofs == piano->key_count - 1) pos -= 1.0; } } else /* white key */ { if (edge == -1) { if (mod != 0 && mod != 5) pos -= piano->key_width_half; } else if (edge == 0) { if (mod == 0 || mod == 5) pos += (piano->key_width + piano->key_width_half) / 2.0; else if (mod == 4 || mod == 11 || noteofs == piano->key_count - 1) pos += piano->key_width_half / 2.0; else pos += piano->key_width_half; } else { if (mod == 0 || mod == 5) pos += piano->key_width + piano->key_width_half; else if (mod == 4 || mod == 11) pos += piano->key_width; else if (noteofs != piano->key_count - 1) pos += piano->key_width + piano->key_width_half; else pos += piano->key_width - 1.0; } } if (isblack) *isblack = black; return (pos); } swami/src/swamigui/SwamiguiSampleEditor.h0000644000175000017500000002366611461334205020755 0ustar alessioalessio/* * SwamiguiSampleEditor.h - Sample editor widget header file * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_SAMPLE_EDITOR_H__ #define __SWAMIGUI_SAMPLE_EDITOR_H__ #include #include #include #include #include #include #include typedef struct _SwamiguiSampleEditor SwamiguiSampleEditor; typedef struct _SwamiguiSampleEditorClass SwamiguiSampleEditorClass; #define SWAMIGUI_TYPE_SAMPLE_EDITOR (swamigui_sample_editor_get_type ()) #define SWAMIGUI_SAMPLE_EDITOR(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMIGUI_TYPE_SAMPLE_EDITOR, \ SwamiguiSampleEditor)) #define SWAMIGUI_SAMPLE_EDITOR_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMIGUI_TYPE_SAMPLE_EDITOR, \ SwamiguiSampleEditorClass)) #define SWAMIGUI_IS_SAMPLE_EDITOR(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMIGUI_TYPE_SAMPLE_EDITOR)) #define SWAMIGUI_IS_SAMPLE_EDITOR_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMIGUI_TYPE_SAMPLE_EDITOR)) typedef enum { SWAMIGUI_SAMPLE_EDITOR_NORMAL, /* no particular status */ SWAMIGUI_SAMPLE_EDITOR_INIT, /* check selection and initialize */ SWAMIGUI_SAMPLE_EDITOR_UPDATE /* selection changed */ } SwamiguiSampleEditorStatus; /** * SwamiguiSampleEditorHandler: * @editor: Sample editor widget * * This function type is used to handle specific patch item types with * sample data and loop info. The @editor object * status field indicates the current * operation which is one of: * * %SWAMIGUI_SAMPLE_EDITOR_INIT - Check selection and initialize the * sample editor if the selection can be handled. Return %TRUE if * selection was handled, which will activate this handler, %FALSE * otherwise. * * %SWAMIGUI_SAMPLE_EDITOR_UPDATE - Item selection has changed, update * sample editor. Return %TRUE if selection change was handled, %FALSE * otherwise which will de-activate this handler. * * Other useful fields of a #SwamiguiSplits object include * selection which defines the current item * selection. * * Returns: Should return %TRUE if operation was handled, %FALSE otherwise. */ typedef gboolean (*SwamiguiSampleEditorHandler)(SwamiguiSampleEditor *editor); /* Sample editor object */ struct _SwamiguiSampleEditor { GtkHBox parent; /* derived from GtkVBox */ SwamiguiSampleEditorStatus status; /* current status */ IpatchList *selection; /* item selection */ SwamiguiSampleEditorHandler handler; /* active handler or NULL */ gpointer handler_data; /* handler defined pointer */ int marker_bar_height; /* height of top marker/loop meter bar */ GList *tracks; /* info for each sample (see SwamiguiSampleEditor.c) */ GList *markers; /* list of markers (see SwamiguiSampleEditor.c) */ guint sample_size; /* cached sample data length, in frames */ SwamiControl *loop_start_hub; /* SwamiControl hub for loop_view start props */ SwamiControl *loop_end_hub; /* SwamiControl hub for loop_view end props */ gboolean marker_cursor; /* TRUE if mouse cursor set for marker move */ int sel_marker; /* index of select marker or -1 */ int sel_marker_edge; /* selected edge -1 = start, 0 = both, 1 = end */ int move_range_ofs; /* if sel_marker_edge == 0, sample ofs of move */ int sel_state; /* see SelState in .c */ int sel_temp; /* tmp pos in samples when sel_state = SEL_MAYBE */ SwamiguiCanvasMod *sample_mod; /* zoom/scroll sample canvas modulator */ double scroll_acc; /* scroll accumulator (since scrolling is integer only) */ SwamiguiCanvasMod *loop_mod; /* zoom/scroll loop view canvas modulator */ double loop_zoom; /* remember last loop zoom between sample loads */ gboolean zoom_all; /* TRUE if entire sample zoomed (remains on resize) */ GtkWidget *mainvbox; /* vbox for toolbar and sample canvases */ GtkWidget *loop_finder_pane; /* pane for loop finder and mainvbox */ SwamiguiLoopFinder *loop_finder_gui; /* loop finder GUI widget */ gboolean loop_finder_active; /* TRUE if loop finder is currently shown */ GnomeCanvas *sample_canvas; /* sample canvas */ GnomeCanvas *loop_canvas; /* sample loop canvas */ GnomeCanvasItem *sample_border_line; /* sample marker bar horizontal line */ GnomeCanvasItem *loop_border_line; /* loop marker bar horizontal line */ GnomeCanvasItem *xsnap_line; /* X zoom/scroll snap line (vertical) */ GnomeCanvasItem *ysnap_line; /* Y zoom/scroll snap line (horizontal) */ GnomeCanvasItem *loop_line; /* loop view center line */ GnomeCanvasItem *loop_snap_line; /* loop zoom snap line */ GtkWidget *loopsel; /* loop selector GtkComboBox */ SwamiControl *loopsel_ctrl; /* control for loop selector */ GtkListStore *loopsel_store; /* loop selector GtkListStore model */ GtkWidget *spinbtn_start; /* start loop spin button */ GtkWidget *spinbtn_end; /* end loop spin button */ SwamiControl *spinbtn_start_ctrl; /* control for loop start spin button */ SwamiControl *spinbtn_end_ctrl; /* control for loop end spin button */ GtkWidget *hscrollbar; /* horizontal scrollbar widget */ GtkWidget *toolbar; /* sample editor toolbar */ GtkWidget *cut_button; /* sample cut button */ GtkWidget *crop_button; /* sample crop button */ GtkWidget *copy_new_button; /* sample copy to new button */ GtkWidget *finder_button; /* loop finder activation button */ GtkWidget *samplesel_button; /* sample selector button */ GtkWidget *dicer_button; /* sample dicer toggle button */ GtkWidget *new_button; /* create new sample from selection button */ GtkWidget *new_name; /* new sample name entry */ guint center_line_color; /* horizontal center line color */ guint marker_border_color; /* color of marker bar horizontal border lines */ guint snap_line_color; /* zoom/scroll snap line color */ guint loop_line_color; /* loop view center line color */ }; /* Sample editor object class */ struct _SwamiguiSampleEditorClass { GtkHBoxClass parent_class; }; /* Flags for swamigui_sample_editor_add_marker() */ typedef enum { SWAMIGUI_SAMPLE_EDITOR_MARKER_SINGLE = 1 << 0, /* Single value (not range) */ SWAMIGUI_SAMPLE_EDITOR_MARKER_VIEW = 1 << 1, /* view only marker */ SWAMIGUI_SAMPLE_EDITOR_MARKER_SIZE = 1 << 2 /* a start/size marker */ } SwamiguiSampleEditorMarkerFlags; /* Builtin markers (always present, although perhaps hidden) */ typedef enum { SWAMIGUI_SAMPLE_EDITOR_MARKER_ID_SELECTION, /* selection marker */ SWAMIGUI_SAMPLE_EDITOR_MARKER_ID_LOOP_FIND_START, /* loop find start window */ SWAMIGUI_SAMPLE_EDITOR_MARKER_ID_LOOP_FIND_END /* loop find end window */ } SwamiguiSampleEditorMarkerId; GType swamigui_sample_editor_get_type (void); GtkWidget *swamigui_sample_editor_new (void); void swamigui_sample_editor_zoom_ofs (SwamiguiSampleEditor *editor, double zoom_amt, double zoom_xpos); void swamigui_sample_editor_scroll_ofs (SwamiguiSampleEditor *editor, int sample_ofs); void swamigui_sample_editor_loop_zoom (SwamiguiSampleEditor *editor, double zoom_amt); void swamigui_sample_editor_set_selection (SwamiguiSampleEditor *editor, IpatchList *items); IpatchList *swamigui_sample_editor_get_selection (SwamiguiSampleEditor *editor); void swamigui_sample_editor_register_handler (SwamiguiSampleEditorHandler handler, SwamiguiPanelCheckFunc check_func); void swamigui_sample_editor_unregister_handler (SwamiguiSampleEditorHandler handler); void swamigui_sample_editor_reset (SwamiguiSampleEditor *editor); void swamigui_sample_editor_get_loop_controls (SwamiguiSampleEditor *editor, SwamiControl **loop_start, SwamiControl **loop_end); int swamigui_sample_editor_add_track (SwamiguiSampleEditor *editor, IpatchSampleData *sample, gboolean right_chan); gboolean swamigui_sample_editor_get_track_info (SwamiguiSampleEditor *editor, guint track, IpatchSampleData **sample, SwamiguiSampleCanvas **sample_view, SwamiguiSampleCanvas **loop_view); void swamigui_sample_editor_remove_track (SwamiguiSampleEditor *editor, guint track); void swamigui_sample_editor_remove_all_tracks (SwamiguiSampleEditor *editor); guint swamigui_sample_editor_add_marker (SwamiguiSampleEditor *editor, guint flags, SwamiControl **start, SwamiControl **end); gboolean swamigui_sample_editor_get_marker_info (SwamiguiSampleEditor *editor, guint marker, guint *flags, GnomeCanvasItem **start_line, GnomeCanvasItem **end_line, SwamiControl **start_ctrl, SwamiControl **end_ctrl); void swamigui_sample_editor_set_marker (SwamiguiSampleEditor *editor, guint marker, guint start, guint end); void swamigui_sample_editor_remove_marker (SwamiguiSampleEditor *editor, guint marker); void swamigui_sample_editor_remove_all_markers (SwamiguiSampleEditor *editor); void swamigui_sample_editor_show_marker (SwamiguiSampleEditor *editor, guint marker, gboolean show_marker); void swamigui_sample_editor_set_loop_types (SwamiguiSampleEditor *editor, int *types, gboolean loop_play_btn); void swamigui_sample_editor_set_active_loop_type (SwamiguiSampleEditor *editor, int type); #endif swami/src/swamigui/SwamiguiBar.h0000644000175000017500000000546311461334205017064 0ustar alessioalessio/* * SwamiguiBar.h - Bar canvas item * A horizontal bar canvas item for displaying pointers or ranges. * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_BAR_H__ #define __SWAMIGUI_BAR_H__ #include #include typedef struct _SwamiguiBar SwamiguiBar; typedef struct _SwamiguiBarClass SwamiguiBarClass; #include #define SWAMIGUI_TYPE_BAR (swamigui_bar_get_type ()) #define SWAMIGUI_BAR(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMIGUI_TYPE_BAR, SwamiguiBar)) #define SWAMIGUI_BAR_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMIGUI_TYPE_BAR, SwamiguiBarClass)) #define SWAMIGUI_IS_BAR(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMIGUI_TYPE_BAR)) #define SWAMIGUI_IS_BAR_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMIGUI_TYPE_BAR)) /* Bar Object */ struct _SwamiguiBar { GnomeCanvasGroup parent_instance; /* derived from GnomeCanvasGroup */ /*< private >*/ int min_height; /* minimum height of pointer items (top) */ int max_height; /* maximum height of pointer items (bottom) */ GList *ptrlist; /* list of PtrInfo structs (SwamiguiBar.c) */ }; struct _SwamiguiBarClass { GnomeCanvasGroupClass parent_class; }; GType swamigui_bar_get_type (void); void swamigui_bar_create_pointer (SwamiguiBar *bar, const char *id, const char *first_property_name, ...); void swamigui_bar_add_pointer (SwamiguiBar *bar, SwamiguiBarPtr *barptr, const char *id); GnomeCanvasItem *swamigui_bar_get_pointer (SwamiguiBar *bar, const char *id); void swamigui_bar_set_pointer_position (SwamiguiBar *bar, const char *id, int position); void swamigui_bar_set_pointer_range (SwamiguiBar *bar, const char *id, int start, int end); int swamigui_bar_get_pointer_order (SwamiguiBar *bar, const char *id); void swamigui_bar_set_pointer_order (SwamiguiBar *bar, const char *id, int pos); void swamigui_bar_raise_pointer_to_top (SwamiguiBar *bar, const char *id); void swamigui_bar_lower_pointer_to_bottom (SwamiguiBar *bar, const char *id); #endif swami/src/swamigui/SwamiguiTree.c0000644000175000017500000014726111461334205017255 0ustar alessioalessio/* * SwamiguiTree.c - Swami tabbed tree object * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include #include #include #include "SwamiguiTree.h" #include "SwamiguiTreeStore.h" #include "SwamiguiItemMenu.h" #include "SwamiguiRoot.h" #include "SwamiguiDnd.h" #include "i18n.h" /* properties */ enum { PROP_0, PROP_SELECTION_SINGLE, PROP_SELECTION, PROP_SELECTED_STORE, /* currently selected store */ PROP_STORE_LIST /* list of tree store objects (multi-tabbed tree) */ }; /* Local Prototypes */ static void swamigui_tree_class_init (SwamiguiTreeClass *klass); static void swamigui_tree_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void swamigui_tree_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void swamigui_tree_init (SwamiguiTree *tree); static void swamigui_tree_cb_switch_page (GtkNotebook *notebook, GtkNotebookPage *page, guint page_num, gpointer user_data); static void swamigui_tree_cb_drag_data_received (GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *selection_data, guint info, guint time, gpointer data); static void swamigui_tree_cb_drag_data_get (GtkWidget *widget, GdkDragContext *drag_context, GtkSelectionData *data, guint info, guint time, gpointer user_data); static void swamigui_tree_real_set_store (SwamiguiTree *tree, SwamiguiTreeStore *store); static void swamigui_tree_update_selection (SwamiguiTree *tree); static void tree_selection_foreach_func (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data); static void swamigui_tree_finalize (GObject *object); static gboolean swamigui_tree_widget_popup_menu (GtkWidget *widg); static void swamigui_tree_cb_search_entry_changed (GtkEntry *entry, gpointer user_data); static void swamigui_tree_cb_search_next_clicked (GtkButton *button, gpointer user_data); static void swamigui_tree_cb_search_prev_clicked (GtkButton *button, gpointer user_data); static GtkWidget * swamigui_tree_create_scrolled_tree_view (SwamiguiTree *tree, SwamiguiTreeStore *store, GtkTreeView **out_treeview); static void swamigui_tree_item_icon_cell_data (GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data); static void swamigui_tree_item_label_cell_data (GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data); static void tree_cb_selection_changed (GtkTreeSelection *selection, SwamiguiTree *tree); static gboolean swamigui_tree_cb_button_press (GtkWidget *widg, GdkEventButton *event, SwamiguiTree *tree); static void swamigui_tree_do_popup_menu (SwamiguiTree *tree, GObject *rclick_item, GdkEventButton *event); static void swamigui_tree_set_selection_real (SwamiguiTree *tree, IpatchList *list, int notify_flags); static void swamigui_tree_real_search_next (SwamiguiTree *tree, gboolean usematch); static void set_search_match_item (SwamiguiTree *tree, GtkTreeIter *iter, GObject *obj, int startpos, const char *search); static void reset_search_match_item (SwamiguiTree *tree, GList **new_ancestry); static int str_index (const char *haystack, const char *needle); static gboolean tree_iter_recursive_next (GtkTreeModel *model, GtkTreeIter *iter); static gboolean tree_iter_recursive_prev (GtkTreeModel *model, GtkTreeIter *iter); static GObjectClass *parent_class = NULL; GType swamigui_tree_get_type (void) { static GType obj_type = 0; if (!obj_type) { static const GTypeInfo obj_info = { sizeof (SwamiguiTreeClass), NULL, NULL, (GClassInitFunc) swamigui_tree_class_init, NULL, NULL, sizeof (SwamiguiTree), 0, (GInstanceInitFunc) swamigui_tree_init, }; obj_type = g_type_register_static (GTK_TYPE_VBOX, "SwamiguiTree", &obj_info, 0); } return (obj_type); } static void swamigui_tree_class_init (SwamiguiTreeClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widg_class = GTK_WIDGET_CLASS (klass); parent_class = g_type_class_peek_parent (klass); widg_class->popup_menu = swamigui_tree_widget_popup_menu; obj_class->set_property = swamigui_tree_set_property; obj_class->get_property = swamigui_tree_get_property; obj_class->finalize = swamigui_tree_finalize; g_object_class_install_property (obj_class, PROP_SELECTION_SINGLE, g_param_spec_object ("selection-single", "Single selection", "Single selected object", G_TYPE_OBJECT, /* FIXME? */ G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_SELECTION, g_param_spec_object ("selection", "Selection", "Selection list (static)", IPATCH_TYPE_LIST, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_SELECTED_STORE, g_param_spec_object ("selected-store", "Selection store", "Selected tree store", SWAMIGUI_TYPE_TREE_STORE, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_STORE_LIST, g_param_spec_object ("store-list", "Store list", "Tree store list", IPATCH_TYPE_LIST, G_PARAM_READWRITE)); } static void swamigui_tree_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { SwamiguiTree *tree = SWAMIGUI_TREE (object); SwamiguiTreeStore *store; IpatchList *list = NULL; GObject *item; switch (property_id) { case PROP_SELECTION_SINGLE: item = g_value_get_object (value); if (item) { list = ipatch_list_new (); /* ++ ref new list */ list->items = g_list_append (list->items, g_object_ref (item)); } swamigui_tree_set_selection_real (tree, list, 1); if (list) g_object_unref (list); /* -- unref list */ break; case PROP_SELECTION: list = g_value_get_object (value); swamigui_tree_set_selection_real (tree, list, 2); break; case PROP_SELECTED_STORE: store = SWAMIGUI_TREE_STORE (g_value_get_object (value)); swamigui_tree_set_selected_store (tree, store); break; case PROP_STORE_LIST: list = IPATCH_LIST (g_value_get_object (value)); swamigui_tree_set_store_list (tree, list); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_tree_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { SwamiguiTree *tree = SWAMIGUI_TREE (object); GObject *item; IpatchList *list; switch (property_id) { case PROP_SELECTION_SINGLE: item = swamigui_tree_get_selection_single (tree); g_value_set_object (value, item); break; case PROP_SELECTION: /* get tree selection (uses directly without ref!) */ list = swamigui_tree_get_selection (tree); g_value_set_object (value, list); break; case PROP_SELECTED_STORE: g_value_set_object (value, tree->selstore); break; case PROP_STORE_LIST: g_value_set_object (value, tree->stores); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_tree_init (SwamiguiTree *tree) { GtkWidget *widg; GtkWidget *image; tree->notebook = GTK_NOTEBOOK (gtk_notebook_new ()); gtk_widget_show (GTK_WIDGET (tree->notebook)); gtk_box_pack_start (GTK_BOX (tree), GTK_WIDGET (tree->notebook), TRUE, TRUE, 0); /* add the search widgets */ tree->search_box = gtk_hbox_new (FALSE, 2); gtk_box_pack_start (GTK_BOX (tree), tree->search_box, FALSE, FALSE, 2); image = gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU); widg = gtk_button_new (); gtk_button_set_image (GTK_BUTTON (widg), image); gtk_button_set_relief (GTK_BUTTON (widg), GTK_RELIEF_NONE); gtk_box_pack_start (GTK_BOX (tree->search_box), widg, FALSE, FALSE, 0); widg = gtk_label_new (_("Search")); gtk_box_pack_start (GTK_BOX (tree->search_box), widg, FALSE, FALSE, 2); tree->search_entry = GTK_ENTRY (gtk_entry_new ()); g_signal_connect (G_OBJECT (tree->search_entry), "changed", G_CALLBACK (swamigui_tree_cb_search_entry_changed), tree); gtk_box_pack_start (GTK_BOX (tree->search_box), GTK_WIDGET (tree->search_entry), TRUE, TRUE, 0); image = gtk_image_new_from_stock (GTK_STOCK_GO_BACK, GTK_ICON_SIZE_MENU); widg = gtk_button_new (); gtk_button_set_image (GTK_BUTTON (widg), image); gtk_button_set_relief (GTK_BUTTON (widg), GTK_RELIEF_NONE); gtk_box_pack_start (GTK_BOX (tree->search_box), widg, FALSE, FALSE, 0); g_signal_connect (G_OBJECT (widg), "clicked", G_CALLBACK (swamigui_tree_cb_search_prev_clicked), tree); image = gtk_image_new_from_stock (GTK_STOCK_GO_FORWARD, GTK_ICON_SIZE_MENU); widg = gtk_button_new (); gtk_button_set_image (GTK_BUTTON (widg), image); gtk_button_set_relief (GTK_BUTTON (widg), GTK_RELIEF_NONE); gtk_box_pack_start (GTK_BOX (tree->search_box), widg, FALSE, FALSE, 0); g_signal_connect (G_OBJECT (widg), "clicked", G_CALLBACK (swamigui_tree_cb_search_next_clicked), tree); gtk_widget_show_all (tree->search_box); /* attach to the "switch-page" signal to update selection when the current notebook page is changed */ g_signal_connect (tree->notebook, "switch-page", G_CALLBACK (swamigui_tree_cb_switch_page), tree); } /* callback when notebook page changes */ static void swamigui_tree_cb_switch_page (GtkNotebook *notebook, GtkNotebookPage *page, guint page_num, gpointer user_data) { SwamiguiTree *tree = SWAMIGUI_TREE (user_data); SwamiguiTreeStore *store; if (!tree->stores) return; store = g_list_nth_data (tree->stores->items, page_num); swamigui_tree_real_set_store (tree, store); } static void swamigui_tree_real_set_store (SwamiguiTree *tree, SwamiguiTreeStore *store) { int n; if (!tree->stores) return; n = g_list_index (tree->stores->items, store); if (n == -1) return; if (store != tree->selstore) { tree->selstore = store; tree->seltree = g_list_nth_data (tree->treeviews, n); /* update tree selection to that of the current selected tree view */ swamigui_tree_update_selection (tree); } } /* update the tree selection to the currently selected tree */ static void swamigui_tree_update_selection (SwamiguiTree *tree) { GtkTreeSelection *selection; gboolean new_sel_single; GList *list = NULL; if (!tree->seltree) return; /* shouldn't happen, but just in case */ selection = gtk_tree_view_get_selection (tree->seltree); if (tree->selection) g_object_unref (tree->selection); /* -- unref old sel */ /* convert tree selection to list */ gtk_tree_selection_selected_foreach (selection, tree_selection_foreach_func, &list); tree->selection = ipatch_list_new (); /* ++ ref new list object */ /* set the origin object of the selection, so swamigui_root can report this to those who want to know. */ swami_object_set_origin (G_OBJECT (tree->selection), G_OBJECT (tree)); if (list) { list = g_list_reverse (list); /* prepended, so reverse it */ tree->selection->items = list; } /* notify single selection change if new single selected or was single */ new_sel_single = list && !list->next; if (new_sel_single || tree->sel_single) g_object_notify (G_OBJECT (tree), "selection-single"); tree->sel_single = new_sel_single; g_object_notify (G_OBJECT (tree), "selection"); /* notify selection change */ } static void tree_selection_foreach_func (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { GList **plist = (GList **)data; GObject *obj; gtk_tree_model_get (model, iter, SWAMIGUI_TREE_STORE_OBJECT_COLUMN, &obj, /* ++ ref obj */ -1); if (obj) *plist = g_list_prepend (*plist, obj); /* !! list takes over reference */ } static void swamigui_tree_finalize (GObject *object) { SwamiguiTree *tree = SWAMIGUI_TREE (object); if (tree->stores) g_object_unref (tree->stores); if (tree->treeviews) g_list_free (tree->treeviews); if (tree->selection) g_object_unref (tree->selection); } static gboolean swamigui_tree_widget_popup_menu (GtkWidget *widg) { SwamiguiTree *tree = SWAMIGUI_TREE (widg); GtkTreeModel *model; GtkTreeIter iter; GObject *rclick_item = NULL; GtkTreePath *path; if (!tree->seltree) return (TRUE); /* shouldn't happen, but just in case */ gtk_tree_view_get_cursor (GTK_TREE_VIEW (tree->seltree), &path, NULL); if (path) { model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree->seltree)); /* convert path to iter */ if (gtk_tree_model_get_iter (model, &iter, path)) { rclick_item = swamigui_tree_store_node_get_item (SWAMIGUI_TREE_STORE (model), &iter); } gtk_tree_path_free (path); } swamigui_tree_do_popup_menu (tree, rclick_item, NULL); return (TRUE); } /** * swamigui_tree_new: * @stores: List of tree stores to use or %NULL to set later * (see swamigui_tree_set_store_list()). * * Create a new Swami tree object * * Returns: Swami tree object */ GtkWidget * swamigui_tree_new (IpatchList *stores) { GtkWidget *tree; tree = GTK_WIDGET (g_object_new (SWAMIGUI_TYPE_TREE, NULL)); if (stores) swamigui_tree_set_store_list (SWAMIGUI_TREE (tree), stores); return (tree); } /** * swamigui_tree_set_store_list: * @tree: Swami GUI tree view * @list: List of #SwamiguiTreeStore objects, this list is used directly and * should not be modified after calling this function. * * Set the tree stores of a tree view. Each tree store gets its own tab * in the tabbed @tree. */ void swamigui_tree_set_store_list (SwamiguiTree *tree, IpatchList *list) { GList *curlist = NULL, *newlist; GList *p, *p2; int pos, index; GtkWidget *page; GtkWidget *label; GtkTreeView *treeview; char *name; g_return_if_fail (SWAMIGUI_IS_TREE (tree)); g_return_if_fail (IPATCH_IS_LIST (list)); if (tree->stores) curlist = tree->stores->items; newlist = list->items; /* check if current and new store lists are equivalent */ if (curlist) { for (p = newlist, p2 = curlist; p && p2; p = p->next, p2 = p2->next) if (p->data != p2->data) break; if (!p && !p2) return; /* they have the same stores? - return */ } /* copy current list so we can modify it (part of an IpatchList) */ if (curlist) curlist = g_list_copy (curlist); for (p = newlist, pos = 0; p; p = p->next, pos++) /* loop over new stores */ { /* store already in current list? */ if (curlist && (index = g_list_index (curlist, p->data)) != -1) { if (index != pos) /* does it need to be moved? */ { /* move the item in our copy of curlist */ curlist = g_list_remove (curlist, p->data); curlist = g_list_insert (curlist, p->data, pos); /* move the notebook page */ page = gtk_notebook_get_nth_page (tree->notebook, index); gtk_notebook_reorder_child (tree->notebook, page, pos); /* update the treeviews list too */ treeview = g_list_nth_data (tree->treeviews, index); tree->treeviews = g_list_remove (tree->treeviews, treeview); tree->treeviews = g_list_insert (tree->treeviews, treeview, pos); } continue; } /* keep curlist in sync with what we are doing */ curlist = g_list_insert (curlist, p->data, pos); /* create a new scrolled tree view */ page = swamigui_tree_create_scrolled_tree_view (tree, SWAMIGUI_TREE_STORE (p->data), &treeview); swami_object_get (p->data, "name", &name, NULL); /* create label for tab */ label = gtk_label_new (name); gtk_widget_show (label); g_free (name); /* insert into the notebook */ gtk_notebook_insert_page (tree->notebook, page, label, pos); /* update treeviews list also */ tree->treeviews = g_list_insert (tree->treeviews, treeview, pos); } /* remove any remaining items in curlist (not part of new store list) */ for (p = g_list_nth (curlist, pos); p; p = p->next, pos++) { /* remove notebook page */ gtk_notebook_remove_page (tree->notebook, pos); /* remove the GtkTreeView list node */ tree->treeviews = g_list_remove_link (tree->treeviews, g_list_nth (tree->treeviews, pos)); } if (tree->stores) g_object_unref (tree->stores); /* -- unref old stores */ tree->stores = g_object_ref (list); g_list_free (curlist); /* duplicated list not needed anymore */ /* Select first tree view if none currently selected. */ if (!tree->seltree && tree->stores && tree->stores->items) swamigui_tree_real_set_store (tree, SWAMIGUI_TREE_STORE (tree->stores->items->data)); } static GtkWidget * swamigui_tree_create_scrolled_tree_view (SwamiguiTree *tree, SwamiguiTreeStore *store, GtkTreeView **out_treeview) { GtkCellRenderer *renderer; GtkTreeViewColumn *column; GtkTreeSelection *selection; GtkWidget *scrollwin; GtkTreeView *treeview; GtkTargetEntry target_table[] = { { SWAMIGUI_DND_OBJECT_NAME, 0, SWAMIGUI_DND_OBJECT_INFO }, { SWAMIGUI_DND_URI_NAME, 0, SWAMIGUI_DND_URI_INFO } }; scrollwin = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_widget_show (scrollwin); treeview = GTK_TREE_VIEW (gtk_tree_view_new ()); /* all rows have same height, enable fixed height mode for increased speed FIXME - Breaks scroll bar, why??? */ // g_object_set (treeview, "fixed-height-mode", TRUE, NULL); /* disable interactive search (breaks playing of piano from keyboard) */ g_object_set (treeview, "enable-search", FALSE, NULL); gtk_container_add (GTK_CONTAINER (scrollwin), GTK_WIDGET (treeview)); gtk_widget_show (GTK_WIDGET (treeview)); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE); /* add pixbuf column to tree view widget */ renderer = gtk_cell_renderer_pixbuf_new (); column = gtk_tree_view_column_new (); // g_object_set (column, "sizing", GTK_TREE_VIEW_COLUMN_FIXED, NULL); gtk_tree_view_column_pack_start (column, renderer, FALSE); gtk_tree_view_column_set_cell_data_func (column, renderer, swamigui_tree_item_icon_cell_data, treeview, NULL); /* add label column to tree view widget */ renderer = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (column, renderer, TRUE); gtk_tree_view_column_set_cell_data_func (column, renderer, swamigui_tree_item_label_cell_data, tree, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); /* assign the tree store */ gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (store)); /* attach selection changed signal handler */ g_signal_connect (selection, "changed", G_CALLBACK (tree_cb_selection_changed), tree); /* for right click menus */ g_signal_connect (treeview, "button-press-event", G_CALLBACK (swamigui_tree_cb_button_press), tree); /* enable tree drag and drop */ gtk_tree_view_enable_model_drag_dest (GTK_TREE_VIEW (treeview), target_table, G_N_ELEMENTS (target_table), GDK_ACTION_COPY); gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (treeview), GDK_BUTTON1_MASK, target_table, G_N_ELEMENTS (target_table), GDK_ACTION_COPY); g_signal_connect (G_OBJECT (treeview), "drag-data-received", G_CALLBACK (swamigui_tree_cb_drag_data_received), tree); g_signal_connect (G_OBJECT (treeview), "drag-data-get", G_CALLBACK (swamigui_tree_cb_drag_data_get), tree); *out_treeview = treeview; return (scrollwin); } /* cell renderer for tree pixmap icons */ static void swamigui_tree_item_icon_cell_data (GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) { GtkTreeView *treeview = GTK_TREE_VIEW (data); GdkPixbuf *icon = NULL; char *stock_id; gtk_tree_model_get (tree_model, iter, SWAMIGUI_TREE_STORE_ICON_COLUMN, &stock_id, -1); if (stock_id) /* ++ ref new closed pixmap */ icon = gtk_widget_render_icon (GTK_WIDGET (treeview), stock_id, GTK_ICON_SIZE_SMALL_TOOLBAR, NULL); g_object_set (cell, "pixbuf", icon, NULL); if (icon) g_object_unref (icon); /* -- unref icon */ } /* cell renderer for tree labels (overridden to allow for search highlighting) */ static void swamigui_tree_item_label_cell_data (GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) { SwamiguiTree *tree = SWAMIGUI_TREE (data); PangoAttrList *alist = NULL; PangoAttribute *attr; char *label; GObject *obj; gtk_tree_model_get (tree_model, iter, SWAMIGUI_TREE_STORE_LABEL_COLUMN, &label, /* ++ alloc */ SWAMIGUI_TREE_STORE_OBJECT_COLUMN, &obj, /* ++ ref */ -1); /* should this object be highlighted for in progress search? */ if (tree->search_match == obj) { alist = pango_attr_list_new (); attr = pango_attr_background_new (0, 65535, 0); attr->start_index = tree->search_start_pos; attr->end_index = tree->search_end_pos; pango_attr_list_insert (alist, attr); } g_object_set (cell, "text", label, "attributes", alist, NULL); if (alist) pango_attr_list_unref (alist); g_object_unref (obj); /* -- unref */ g_free (label); /* -- free */ } /* a callback for when the tree view selection changes */ static void tree_cb_selection_changed (GtkTreeSelection *selection, SwamiguiTree *tree) { GtkTreeView *treeview; treeview = gtk_tree_selection_get_tree_view (selection); /* update currently selected GtkTreeView and store */ tree->seltree = treeview; tree->selstore = SWAMIGUI_TREE_STORE (gtk_tree_view_get_model (treeview)); /* update the current selection to that of the current selected tree */ swamigui_tree_update_selection (tree); } /* when a tree view gets a button press */ static gboolean swamigui_tree_cb_button_press (GtkWidget *widg, GdkEventButton *event, SwamiguiTree *tree) { GtkTreeSelection *tree_sel; GtkTreeModel *model; GtkTreePath *path; GtkTreeIter iter; GObject *rclick_item; int x, y; if (!tree->seltree) return (FALSE); /* Shouldn't happen, but.. */ if (event->button != 3) return (FALSE); x = event->x; /* x and y coordinates are of type double */ y = event->y; /* convert to integer */ /* get the tree path at the given mouse cursor position * ++ alloc path */ gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (tree->seltree), x, y, &path, NULL, NULL, NULL); if (!path) return (FALSE); /* right click */ model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree->seltree)); /* convert path to iter */ if (!gtk_tree_model_get_iter (model, &iter, path)) { gtk_tree_path_free (path); /* -- free path */ return (FALSE); } gtk_tree_path_free (path); /* -- free path */ /* stop button press event propagation */ gtk_signal_emit_stop_by_name (GTK_OBJECT (widg), "button-press-event"); rclick_item = swamigui_tree_store_node_get_item (SWAMIGUI_TREE_STORE (model), &iter); /* check if right click is not part of current selection */ if (!tree->selection || !g_list_find (tree->selection->items, rclick_item)) { /* click not on selection, clear it and select the single item */ tree_sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree->seltree)); gtk_tree_selection_unselect_all (tree_sel); gtk_tree_selection_select_iter (tree_sel, &iter); tree_cb_selection_changed (tree_sel, tree); /* update selection */ } /* do the menu popup */ swamigui_tree_do_popup_menu (tree, rclick_item, event); return (TRUE); } static void swamigui_tree_do_popup_menu (SwamiguiTree *tree, GObject *rclick_item, GdkEventButton *event) { SwamiguiItemMenu *menu; int button, event_time; if (!tree->selection) return; /* No selection, no menu */ menu = swamigui_item_menu_new (); g_object_set (menu, "selection", tree->selection, "right-click", rclick_item, "creator", tree, NULL); swamigui_item_menu_generate (menu); if (event) { button = event->button; event_time = event->time; } else { button = 0; event_time = gtk_get_current_event_time (); } gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, button, event_time); } /* callback for when drag data received */ static void swamigui_tree_cb_drag_data_received (GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *selection_data, guint info, guint time, gpointer data) { SwamiguiTree *tree = SWAMIGUI_TREE (data); SwamiguiTreeStore *store; GtkTreeView *treeview = GTK_TREE_VIEW (widget); char *atomname; if (selection_data->format != 8 || selection_data->length == 0) { g_critical ("DND on Swami tree had invalid format (%d) or length (%d)", selection_data->format, selection_data->length); return; } atomname = gdk_atom_name (selection_data->type); /* drag and drop between or within tree? */ if (strcmp (atomname, SWAMIGUI_DND_OBJECT_NAME) == 0) { GtkTreePath *path; GtkTreeIter iter; IpatchItem *destitem; int itemcount, pastecount; IpatchList *objlist; GList *p; objlist = *((IpatchList **)(selection_data->data)); /* make sure source object is an IpatchList (could be another object type) */ if (!IPATCH_IS_LIST (objlist)) return; /* get path to destination drop row */ if (!gtk_tree_view_get_path_at_pos (treeview, x, y, &path, NULL, NULL, NULL)) return; /* return if no row at drop position */ /* get iterator for path */ if (!gtk_tree_model_get_iter (gtk_tree_view_get_model (treeview), &iter, path)) { gtk_tree_path_free (path); return; } gtk_tree_path_free (path); store = swamigui_tree_get_selected_store (tree); destitem = IPATCH_ITEM (swamigui_tree_store_node_get_item (store, &iter)); if (!destitem) return; /* loop over source items */ for (p = objlist->items, itemcount = 0, pastecount = 0; p; p = p->next, itemcount++) { if (IPATCH_ITEM (p->data)) { if (ipatch_simple_paste (destitem, (IpatchItem *)(p->data), NULL)) pastecount++; } } if (itemcount > 0) { if (itemcount != pastecount) swamigui_statusbar_printf (swamigui_root->statusbar, _("Pasted %d of %d item(s)"), pastecount, itemcount); else swamigui_statusbar_printf (swamigui_root->statusbar, _("Pasted %d item(s)"), itemcount); } } /* drop of external file URI on tree */ else if (strcmp (atomname, SWAMIGUI_DND_URI_NAME) == 0) { char *uri_list; char **uris; char *fname; GError *err = NULL; int i; uri_list = g_strndup ((char *)(selection_data->data), selection_data->length); uris = g_strsplit (uri_list, "\r\n", 0); /* loop over URIs and attempt to open any that are file names */ for (i = 0; uris && uris[i]; i++) { fname = g_filename_from_uri (uris[i], NULL, NULL); if (fname) { if (!swami_root_patch_load (swami_root, fname, NULL, &err)) { g_critical (_("Failed to load DnD file '%s': %s"), fname, ipatch_gerror_message (err)); g_clear_error (&err); } g_free (fname); } } g_strfreev (uris); g_free (uri_list); } } static void swamigui_tree_cb_drag_data_get (GtkWidget *widget, GdkDragContext *drag_context, GtkSelectionData *data, guint info, guint time, gpointer user_data) { SwamiguiTree *tree = SWAMIGUI_TREE (user_data); GdkAtom atom; #if GTK_CHECK_VERSION (2, 10, 0) atom = gdk_atom_intern_static_string (SWAMIGUI_DND_OBJECT_NAME); #else atom = gdk_atom_intern (SWAMIGUI_DND_OBJECT_NAME, FALSE); #endif gtk_selection_data_set (data, atom, 8, (guint8 *)(&tree->selection), sizeof (IpatchList *)); } /* callback for when tree search entry text changes */ static void swamigui_tree_cb_search_entry_changed (GtkEntry *entry, gpointer user_data) { SwamiguiTree *tree = SWAMIGUI_TREE (user_data); const char *search; search = gtk_entry_get_text (entry); /* get current search string */ swamigui_tree_search_set_text (tree, search); } static void swamigui_tree_cb_search_next_clicked (GtkButton *button, gpointer user_data) { SwamiguiTree *tree = SWAMIGUI_TREE (user_data); swamigui_tree_search_next (tree); } static void swamigui_tree_cb_search_prev_clicked (GtkButton *button, gpointer user_data) { SwamiguiTree *tree = SWAMIGUI_TREE (user_data); swamigui_tree_search_prev (tree); } /** * swamigui_tree_get_store_list: * @tree: Swami GUI tree view * * Gets the tree stores of a tree view. * * Returns: List of #SwamiguiTreeStore objects or %NULL if none, NO * reference is added and so the list should only be used within the * context of the calling function unless referenced or duplicated. */ IpatchList * swamigui_tree_get_store_list (SwamiguiTree *tree) { g_return_val_if_fail (SWAMIGUI_IS_TREE (tree), NULL); return (tree->stores); } /** * swamigui_tree_set_selected_store: * @tree: Swami tree object * @store: Store to select as the active store * * Sets the currently selected store. The notebook tab containing @store will * be selected which will cause the current tree selection to be updated to the * item selection of the GtkTreeView contained therein. */ void swamigui_tree_set_selected_store (SwamiguiTree *tree, SwamiguiTreeStore *store) { int store_index; g_return_if_fail (SWAMIGUI_IS_TREE (tree)); g_return_if_fail (SWAMIGUI_IS_TREE_STORE (store)); g_return_if_fail (tree->stores != NULL); store_index = g_list_index (tree->stores->items, store); g_return_if_fail (store_index != -1); gtk_notebook_set_current_page (tree->notebook, store_index); } /** * swamigui_tree_get_selected_store: * @tree: Swami tree object * * Get the currently selected tree store (displayed in the current notebook tab). * * Returns: Currently selected tree store or %NULL if none. Not referenced and * so caller should take care to reference it if using outside of calling scope. */ SwamiguiTreeStore * swamigui_tree_get_selected_store (SwamiguiTree *tree) { g_return_val_if_fail (SWAMIGUI_IS_TREE (tree), NULL); return (tree->selstore); } /** * swamigui_tree_get_selection_single: * @tree: Swami tree object * * Get and insure single item selection in Swami tree object * * Returns: The currently selected single item or %NULL if multiple or no items * are selected. A reference is not added so caller should take care to * reference it if using outside of the calling scope. */ GObject * swamigui_tree_get_selection_single (SwamiguiTree *tree) { GList *sel = NULL; g_return_val_if_fail (SWAMIGUI_IS_TREE (tree), NULL); if (tree->selection) sel = tree->selection->items; if (sel && !sel->next) return (G_OBJECT (sel->data)); else return (NULL); } /** * swamigui_tree_get_selection: * @tree: Swami tree object * * Get Swami tree selection. * * Returns: List of items in the tree selection or %NULL if no items * selected. The returned list object is internal and should not be * modified. * * NOTE - The list's reference count is not incremented, so if it is * desirable to use the list beyond the scope of the calling function * it should be duplicated or a reference added. */ IpatchList * swamigui_tree_get_selection (SwamiguiTree *tree) { g_return_val_if_fail (SWAMIGUI_IS_TREE (tree), NULL); return (tree->selection); } /** * swamigui_tree_clear_selection: * @tree: Swami tree object * * Clear tree selection (unselect all items) */ void swamigui_tree_clear_selection (SwamiguiTree *tree) { GtkTreeSelection *sel; g_return_if_fail (SWAMIGUI_IS_TREE (tree)); if (!tree->seltree) return; sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree->seltree)); gtk_tree_selection_unselect_all (sel); } /** * swamigui_tree_set_selection: * @tree: Swami tree object * @list: List of objects to select * * Set the tree selection. List of objects must be in the same tree store * (notebook tab). If items are in a non selected store it will become * selected. */ void swamigui_tree_set_selection (SwamiguiTree *tree, IpatchList *list) { swamigui_tree_set_selection_real (tree, list, 3); } /* the real selection set function, notify_flags 1 << 0 = "selection" and 1 << 1 = "selection-single" */ static void swamigui_tree_set_selection_real (SwamiguiTree *tree, IpatchList *list, int notify_flags) { GtkTreeModel *model; GtkTreeSelection *selection; GtkTreePath *path, *firstpath = NULL; GtkTreeView *seltree; GtkTreeIter treeiter, parent; gboolean new_sel_single; GObject *item; GList *p, *foundstore; int pos; g_return_if_fail (SWAMIGUI_IS_TREE (tree)); g_return_if_fail (!list || IPATCH_IS_LIST (list)); if (!tree->stores) return; /* no point in selecting nothing, but.. */ /* list contains items? */ if (list && list->items) { /* first item shall suffice (all should be present and in same store) */ item = G_OBJECT (list->items->data); /* locate the store containing the first item */ for (p = tree->stores->items, pos = 0; p; p = p->next, pos++) if (swamigui_tree_store_item_get_node (SWAMIGUI_TREE_STORE (p->data), item, NULL)) break; foundstore = p; if (swami_log_if_fail (foundstore)) return; if (tree->selstore != p->data) /* selected store has changed? */ { tree->selstore = SWAMIGUI_TREE_STORE (p->data); tree->seltree = g_list_nth_data (tree->treeviews, pos); /* switch the page without signaling our switch page handler */ g_signal_handlers_block_by_func (tree, swamigui_tree_cb_switch_page, NULL); gtk_notebook_set_current_page (tree->notebook, pos); g_signal_handlers_unblock_by_func (tree, swamigui_tree_cb_switch_page, NULL); } } /* no items in new list */ else if (!tree->selstore) return; /* no selected store? - return */ if (tree->selection) g_object_unref (tree->selection); /* -- unref old selection */ if (list) tree->selection = ipatch_list_duplicate (list); else tree->selection = ipatch_list_new (); /* set the object's origin so swamigui_root can report this to others */ swami_object_set_origin (G_OBJECT (tree->selection), G_OBJECT (tree)); model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree->seltree)); selection = gtk_tree_view_get_selection (tree->seltree); g_signal_handlers_block_by_func (selection, G_CALLBACK (tree_cb_selection_changed), tree); gtk_tree_selection_unselect_all (selection); seltree = GTK_TREE_VIEW (tree->seltree); /* update the tree view selection and expand all parents of items */ for (p = list ? list->items : NULL; p; p = p->next) { if (swamigui_tree_store_item_get_node (SWAMIGUI_TREE_STORE (model), p->data, &treeiter)) { if (!firstpath) /* ++ alloc path (for first valid item) */ firstpath = gtk_tree_model_get_path (model, &treeiter); /* expand all parents as necessary */ if (gtk_tree_model_iter_parent (model, &parent, &treeiter)) { path = gtk_tree_model_get_path (model, &parent); /* ++ alloc path */ gtk_tree_view_expand_to_path (seltree, path); gtk_tree_path_free (path); /* -- free path */ } /* select item in tree selection */ gtk_tree_selection_select_iter (selection, &treeiter); } } g_signal_handlers_unblock_by_func (selection, G_CALLBACK (tree_cb_selection_changed), tree); /* spotlight the first item in the selection */ if (firstpath) { gtk_tree_view_scroll_to_cell (seltree, firstpath, NULL, FALSE, 0.0, 0.0); gtk_tree_path_free (firstpath); /* -- free path */ } /* notify single selection change if old and new single are not NULL */ new_sel_single = list && list->items && !list->items->next; if ((notify_flags & 2) && (new_sel_single || tree->sel_single)) g_object_notify (G_OBJECT (tree), "selection-single"); tree->sel_single = new_sel_single; if (notify_flags & 1) g_object_notify (G_OBJECT (tree), "selection"); } /** * swamigui_tree_spotlight_item: * @tree: Swami tree object * @item: Object in @tree to spotlight * * Spotlights an item in a Swami tree object by recursively expanding all * nodes up the tree from item and moving the view to position item in the * center of the view and then selects it. If the item is part of an unselected * store (i.e., notebook tab), then it will become selected. */ void swamigui_tree_spotlight_item (SwamiguiTree *tree, GObject *item) { GtkTreeModel *model; GtkTreeSelection *sel; GtkTreeIter iter; GtkTreePath *path; GList *p, *foundstore; int pos; g_return_if_fail (SWAMIGUI_IS_TREE (tree)); g_return_if_fail (G_IS_OBJECT (item)); /* locate the store containing the first item */ for (p = tree->stores->items, pos = 0; p; p = p->next, pos++) if (swamigui_tree_store_item_get_node (SWAMIGUI_TREE_STORE (p->data), item, NULL)) break; foundstore = p; if (swami_log_if_fail (foundstore)) return; /* store is not selected store? */ if ((SwamiguiTreeStore *)(p->data) != tree->selstore) { tree->selstore = SWAMIGUI_TREE_STORE (p->data); tree->seltree = g_list_nth_data (tree->treeviews, pos); /* switch the page without signaling our switch page handler */ g_signal_handlers_block_by_func (tree, swamigui_tree_cb_switch_page, NULL); gtk_notebook_set_current_page (tree->notebook, pos); g_signal_handlers_unblock_by_func (tree, swamigui_tree_cb_switch_page, NULL); } model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree->seltree)); if (!swamigui_tree_store_item_get_node (SWAMIGUI_TREE_STORE (model), item, &iter)) return; sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree->seltree)); /* expand the nodes parents */ path = gtk_tree_model_get_path (model, &iter); if (gtk_tree_path_up (path)) gtk_tree_view_expand_to_path (GTK_TREE_VIEW (tree->seltree), path); gtk_tree_path_free (path); /* scroll to the given item */ path = gtk_tree_model_get_path (model, &iter); gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (tree->seltree), path, NULL, TRUE, 0.5, 0.0); gtk_tree_path_free (path); /* select the item */ gtk_tree_selection_unselect_all (sel); gtk_tree_selection_select_iter (sel, &iter); } /** * swamigui_tree_search_set_start: * @tree: Tree widget * @start: Start object to begin search from (inclusive, %NULL for entire tree) * * Sets the beginning object in tree to start searching from, the passed * object is included in the search (can match). */ void swamigui_tree_search_set_start (SwamiguiTree *tree, GObject *start) { g_return_if_fail (SWAMIGUI_IS_TREE (tree)); g_return_if_fail (!start); /* we don't actually care if it is valid */ tree->search_start = start; } /** * swamigui_tree_search_set_text: * @tree: Tree widget * @text: Text to set search to * * Set the text of the tree's search entry and update search selection. */ void swamigui_tree_search_set_text (SwamiguiTree *tree, const char *text) { g_return_if_fail (SWAMIGUI_IS_TREE (tree)); g_free (tree->search_text); tree->search_text = g_strdup (text); swamigui_tree_real_search_next (tree, FALSE); } /** * swamigui_tree_search_set_visible: * @tree: Tree widget * @active: TRUE to show search entry, FALSE to hide it * * Shows/hides the search entry below the tree. */ void swamigui_tree_search_set_visible (SwamiguiTree *tree, gboolean visible) { g_return_if_fail (SWAMIGUI_IS_TREE (tree)); if (visible) gtk_widget_show (tree->search_box); else gtk_widget_hide (tree->search_box); } /** * swamigui_tree_search_next: * @tree: Tree widget * * Go to the next matching item for the current search. */ void swamigui_tree_search_next (SwamiguiTree *tree) { swamigui_tree_real_search_next (tree, TRUE); } static void swamigui_tree_real_search_next (SwamiguiTree *tree, gboolean usematch) { GtkTreeModel *model; GtkTreeIter iter; char *label; GObject *obj; int index; g_return_if_fail (SWAMIGUI_IS_TREE (tree)); if (!tree->selstore || !tree->seltree) return; /* FIXME: silently fail? */ model = GTK_TREE_MODEL (tree->selstore); /* if search_match is set and valid, set start iter to the next node thereof */ if (usematch && tree->search_match && swamigui_tree_store_item_get_node (tree->selstore, tree->search_match, &iter)) tree_iter_recursive_next (model, &iter); else /* no search match item (or !usematch), try search start */ { if (!tree->search_start || !swamigui_tree_store_item_get_node (tree->selstore, tree->search_start, &iter)) { /* no search start item, try first item in tree */ if (!gtk_tree_model_get_iter_first (model, &iter)) return; /* empty tree? - return */ gtk_tree_model_get (model, &iter, SWAMIGUI_TREE_STORE_OBJECT_COLUMN, &obj, /* ++ ref */ -1); tree->search_start = obj; g_object_unref (obj); /* -- unref */ } } /* iterate over tree looking for matching item */ do { gtk_tree_model_get (model, &iter, SWAMIGUI_TREE_STORE_LABEL_COLUMN, &label, /* ++ alloc */ SWAMIGUI_TREE_STORE_OBJECT_COLUMN, &obj, /* ++ ref */ -1); /* search for sub string in row label */ index = str_index (label, tree->search_text); g_free (label); /* -- free */ if (index >= 0) /* matched? */ { set_search_match_item (tree, &iter, obj, index, tree->search_text); g_object_unref (obj); /* -- unref */ return; /* we done */ } g_object_unref (obj); /* -- unref */ } while (tree_iter_recursive_next (model, &iter)); reset_search_match_item (tree, NULL); /* no match, nothing selected */ } /** * swamigui_tree_search_next: * @tree: Tree widget * * Go to the previous matching item for the current search. */ void swamigui_tree_search_prev (SwamiguiTree *tree) { GtkTreeModel *model; GtkTreeIter iter, current; char *label; GObject *obj; int index; g_return_if_fail (SWAMIGUI_IS_TREE (tree)); if (!tree->selstore || !tree->seltree) return; /* FIXME: silently fail? */ model = GTK_TREE_MODEL (tree->selstore); /* if search_match is set and valid, set start iter to the prev node thereof */ if (tree->search_match && swamigui_tree_store_item_get_node (tree->selstore, tree->search_match, &iter)) { if (!tree_iter_recursive_prev (model, &iter)) return; /* FIXME - Wrap around? */ } else /* no search match item, try search start */ { if (!tree->search_start || !swamigui_tree_store_item_get_node (tree->selstore, tree->search_start, &iter)) { /* no search start, find last item of tree */ if (!gtk_tree_model_get_iter_first (model, &iter)) return; /* empty tree? - return */ /* find last child of last sibling of tree */ do { /* find last sibling at this level */ current = iter; while (gtk_tree_model_iter_next (model, ¤t)) iter = current; current = iter; } while (gtk_tree_model_iter_children (model, &iter, ¤t)); iter = current; gtk_tree_model_get (model, &iter, SWAMIGUI_TREE_STORE_OBJECT_COLUMN, &obj, /* ++ ref */ -1); tree->search_start = obj; g_object_unref (obj); /* -- unref */ } } /* iterate over tree looking for matching item */ do { gtk_tree_model_get (model, &iter, SWAMIGUI_TREE_STORE_LABEL_COLUMN, &label, /* ++ alloc */ SWAMIGUI_TREE_STORE_OBJECT_COLUMN, &obj, /* ++ ref */ -1); /* search for sub string in row label */ index = str_index (label, tree->search_text); g_free (label); /* -- free */ if (index >= 0) /* matched? */ { set_search_match_item (tree, &iter, obj, index, tree->search_text); g_object_unref (obj); /* -- unref */ return; /* we done */ } g_object_unref (obj); /* -- unref */ } while (tree_iter_recursive_prev (model, &iter)); reset_search_match_item (tree, NULL); /* no match, nothing selected */ } static void set_search_match_item (SwamiguiTree *tree, GtkTreeIter *iter, GObject *obj, int startpos, const char *search) { GtkTreeModel *store; GtkTreePath *path, *parent; GtkTreeIter myiter, piter; GList *new_ancestry = NULL; GObject *pobj; GList *p; if (!tree->selstore || !tree->seltree) return; store = GTK_TREE_MODEL (tree->selstore); if (!iter) /* if only the object was passed, lookup tree iter */ { iter = &myiter; if (!swamigui_tree_store_item_get_node (tree->selstore, obj, iter)) return; } path = gtk_tree_model_get_path (store, iter); /* ++ alloc */ parent = gtk_tree_path_copy (path); /* ++ alloc */ /* create ancestry list of new match item */ while (gtk_tree_path_up (parent) && gtk_tree_path_get_depth (parent) > 0) { gtk_tree_model_get_iter (store, &piter, parent); gtk_tree_model_get (store, &piter, SWAMIGUI_TREE_STORE_OBJECT_COLUMN, &pobj, /* ++ ref */ -1); new_ancestry = g_list_prepend (new_ancestry, pobj); g_object_unref (pobj); /* -- unref */ } /* previous match and not the same? - reset it */ if (tree->search_match && tree->search_match != obj) reset_search_match_item (tree, &new_ancestry); /* set the search object and start/end text position */ tree->search_match = obj; tree->search_start_pos = startpos; tree->search_end_pos = startpos + strlen (search); /* Tell the model that the row display should be updated. * GtkTreeCellDataFunc will handle the highlight of the label. */ gtk_tree_model_row_changed (store, path, iter); /* loop on remaining ancestry items (that weren't already in search_expanded) */ for (p = new_ancestry; p; p = g_list_delete_link (p, p)) { /* probably won't fail, but.. */ if (swamigui_tree_store_item_get_node (tree->selstore, p->data, &piter)) { parent = gtk_tree_model_get_path (store, &piter); /* ++ alloc */ /* not expanded? - Add to search_expanded list */ if (!gtk_tree_view_row_expanded (tree->seltree, parent)) tree->search_expanded = g_list_prepend (tree->search_expanded, p->data); gtk_tree_path_free (parent); /* -- free */ } } /* expand all ancestry of the matched node */ parent = gtk_tree_path_copy (path); /* ++ alloc */ if (gtk_tree_path_up (parent)) gtk_tree_view_expand_to_path (tree->seltree, parent); gtk_tree_path_free (parent); /* -- free */ /* scroll if needed so the highlighted item is in view */ gtk_tree_view_scroll_to_cell (tree->seltree, path, NULL, FALSE, 0.0, 0.0); gtk_tree_path_free (path); /* -- free */ } /* resets the current search match item. * new_ancestry is optional and specifies GObject ancestry of a new item which * will become selected. Nodes shared between the old search_expanded list * and the new_ancestry list are not collapsed, not removed from old list and * removed from new list. Nodes in old list which are not in new list are * collapsed and removed from list. Nodes in new list not in old list are * left alone. This allows for branches to remain open which will be part of * a new match item (therefore the scroll to the new item will only be done if * necessary). */ static void reset_search_match_item (SwamiguiTree *tree, GList **new_ancestry) { GtkTreeIter iter; GtkTreePath *path; gboolean retval; GList *p, *tmp, *match; GObject *obj; if (!tree->search_match || !tree->selstore || !tree->seltree) return; /* get the tree node for the current match item */ retval = swamigui_tree_store_item_get_node (tree->selstore, tree->search_match, &iter); tree->search_match = NULL; if (!retval) return; /* can happen if search match gets removed */ /* notify that item row has changed and should be updated (unhighlighted) */ path = gtk_tree_model_get_path (GTK_TREE_MODEL (tree->selstore), &iter); gtk_tree_model_row_changed (GTK_TREE_MODEL (tree->selstore), path, &iter); gtk_tree_path_free (path); /* collapse any parents that were expanded and delete list */ for (p = tree->search_expanded; p; ) { obj = (GObject *)(p->data); if (new_ancestry) /* new ancestry list provided? */ { /* check if object is in new list also */ if ((match = g_list_find (*new_ancestry, obj))) { /* found in new list: remove from new list, leave in old list */ *new_ancestry = g_list_delete_link (*new_ancestry, match); p = p->next; continue; } } /* delete from old list */ tmp = p; p = p->next; tree->search_expanded = g_list_delete_link (tree->search_expanded, tmp); if (!swamigui_tree_store_item_get_node (tree->selstore, obj, &iter)) continue; path = gtk_tree_model_get_path (GTK_TREE_MODEL (tree->selstore), &iter); gtk_tree_view_collapse_row (GTK_TREE_VIEW (tree->seltree), path); gtk_tree_path_free (path); } } /* search for substring case insensitively and return the index of the match * or -1 on no match */ static int str_index (const char *haystack, const char *needle) { const char *s1, *s2; int i; if (!haystack || !needle) return -1; for (i = 0; *haystack; haystack++, i++) { for (s1 = haystack, s2 = needle; toupper (*s1) == toupper (*s2) && *s1 && *s2; s1++, s2++); if (!*s2) return (i); } return (-1); } /* For recursing forwards through tree one node at a time */ static gboolean tree_iter_recursive_next (GtkTreeModel *model, GtkTreeIter *iter) { GtkTreeIter current = *iter; GtkTreeIter parent; /* attempt to go to first child of current node */ if (gtk_tree_model_iter_children (model, iter, ¤t)) return (TRUE); /* attempt to go to next sibling of current node */ *iter = current; if (gtk_tree_model_iter_next (model, iter)) return (TRUE); /* attempt to go to next possible sibling of the closest parent */ while (TRUE) { if (!gtk_tree_model_iter_parent (model, &parent, ¤t)) return (FALSE); *iter = parent; if (gtk_tree_model_iter_next (model, iter)) return (TRUE); current = parent; } } /* For recursing backwards through tree one node at a time */ static gboolean tree_iter_recursive_prev (GtkTreeModel *model, GtkTreeIter *iter) { GtkTreeIter current; GtkTreePath *path; /* get a path, since it is easier to work with for some operations (such a prev) */ path = gtk_tree_model_get_path (model, iter); /* ++ alloc */ /* attempt to go to previous sibling */ if (gtk_tree_path_prev (path)) { gtk_tree_model_get_iter (model, iter, path); /* shouldn't fail */ gtk_tree_path_free (path); /* -- free */ /* attempt to recursively go to last child */ while (gtk_tree_model_iter_children (model, ¤t, iter)) { /* find last sibling */ *iter = current; while (gtk_tree_model_iter_next (model, ¤t)) *iter = current; } /* at this point, its either previous sibling with no children or * deepest last child of previous sibling */ return (TRUE); } gtk_tree_path_free (path); /* -- free */ /* attempt to go to parent */ current = *iter; if (gtk_tree_model_iter_parent (model, iter, ¤t)) return (TRUE); return (FALSE); /* that was the topmost node */ } swami/src/swamigui/SwamiguiTreeStore.c0000644000175000017500000003570111461334205020265 0ustar alessioalessio/* * SwamiguiTreeStore.c - Swami item tree store object * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include "SwamiguiTree.h" #include "SwamiguiRoot.h" #include "icons.h" #include "i18n.h" /* Local Prototypes */ static void swamigui_tree_store_class_init (SwamiguiTreeStoreClass *klass); static void swamigui_tree_store_init (SwamiguiTreeStore *store); static void swamigui_tree_store_finalize (GObject *object); static inline void swamigui_tree_finish_insert (SwamiguiTreeStore *store, GObject *item, const char *label, char *icon, GtkTreeIter *iter); static void tree_store_recursive_remove (SwamiguiTreeStore *store, GtkTreeIter *iter); static GObjectClass *parent_class = NULL; /* a cache of icon names (conserve memory, no need to store for every item) */ static GHashTable *icon_name_cache = NULL; GType swamigui_tree_store_get_type (void) { static GType obj_type = 0; if (!obj_type) { static const GTypeInfo obj_info = { sizeof (SwamiguiTreeStoreClass), NULL, NULL, (GClassInitFunc) swamigui_tree_store_class_init, NULL, NULL, sizeof (SwamiguiTreeStore), 0, (GInstanceInitFunc) swamigui_tree_store_init, }; obj_type = g_type_register_static (GTK_TYPE_TREE_STORE, "SwamiguiTreeStore", &obj_info, G_TYPE_FLAG_ABSTRACT); } return (obj_type); } static void swamigui_tree_store_class_init (SwamiguiTreeStoreClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); parent_class = g_type_class_peek_parent (klass); obj_class->finalize = swamigui_tree_store_finalize; icon_name_cache = g_hash_table_new_full (NULL, NULL, (GDestroyNotify)g_free, NULL); } static void swamigui_tree_store_init (SwamiguiTreeStore *store) { GType types[SWAMIGUI_TREE_STORE_NUM_COLUMNS] = { G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_OBJECT }; /* we use pointer type for icon since its a static string and we don't want it getting duplicated */ /* set up the tree store */ gtk_tree_store_set_column_types (GTK_TREE_STORE (store), SWAMIGUI_TREE_STORE_NUM_COLUMNS, types); /* create a item->tree_node hash with a destroy notify on the item key to unref it, and a destroy on the tree iterator to free it */ store->item_hash = g_hash_table_new_full (NULL, NULL, (GDestroyNotify)g_object_unref, (GDestroyNotify)gtk_tree_iter_free); } static void swamigui_tree_store_finalize (GObject *object) { SwamiguiTreeStore *store = SWAMIGUI_TREE_STORE (object); g_hash_table_destroy (store->item_hash); if (parent_class->finalize) parent_class->finalize (object); } /** * swamigui_tree_store_insert: * @store: Swami tree store to insert tree node into * @item: Object to link to tree node or %NULL * @label: Label for node or %NULL to try and obtain it other ways. * @icon: Stock ID of icon (%NULL to use "icon" type property or category icon) * @parent: Pointer to parent tree node or %NULL if inserting a toplevel node * @pos: Position to insert new node at (0 = prepend, > sibling list to append) * @out_iter: Pointer to a user supplied GtkTreeIter structure to store the * new node in or %NULL to ignore. * * Creates a new tree node and inserts it at the position given by * @parent and @pos, returning the created node in @out_iter (if * supplied). @item is an object to link with the created node. * It is also used if either @label or @icons is %NULL in which case * it obtains the information via other methods. */ void swamigui_tree_store_insert (SwamiguiTreeStore *store, GObject *item, const char *label, char *icon, GtkTreeIter *parent, int pos, GtkTreeIter *out_iter) { GtkTreeIter iter; g_return_if_fail (SWAMIGUI_IS_TREE_STORE (store)); g_return_if_fail (!item || G_IS_OBJECT (item)); gtk_tree_store_insert (GTK_TREE_STORE (store), &iter, parent, pos); swamigui_tree_finish_insert (store, item, label, icon, &iter); if (out_iter) *out_iter = iter; } /** * swamigui_tree_store_insert_before: * @store: Swami tree store to insert tree node into * @item: Object to link to tree node or %NULL * @label: Label for node or %NULL to try and obtain it other ways. * @icon: Stock ID of icon (%NULL to use "icon" type property or category icon) * @parent: Pointer to parent tree node or %NULL if inserting a toplevel node * @sibling: A sibling node to insert the new node before or %NULL to append * @out_iter: Pointer to a user supplied GtkTreeIter structure to store the * new node in or %NULL to ignore. * * Like swamigui_tree_store_insert() but inserts the node before the * specified @sibling instead. */ void swamigui_tree_store_insert_before (SwamiguiTreeStore *store, GObject *item, const char *label, char *icon, GtkTreeIter *parent, GtkTreeIter *sibling, GtkTreeIter *out_iter) { GtkTreeIter iter; g_return_if_fail (SWAMIGUI_IS_TREE_STORE (store)); g_return_if_fail (!item || G_IS_OBJECT (item)); gtk_tree_store_insert_before (GTK_TREE_STORE (store), &iter, parent, sibling); swamigui_tree_finish_insert (store, item, label, icon, &iter); if (out_iter) *out_iter = iter; } /** * swamigui_tree_store_insert_after: * @store: Swami tree store to insert tree node into * @item: Object to link to tree node or %NULL * @label: Label for node or %NULL to try and obtain it other ways. * @icon: Stock ID of icon (%NULL to use "icon" type property or category icon) * @parent: Pointer to parent tree node or %NULL if inserting a toplevel node * @sibling: A sibling node to insert the new node after or %NULL to prepend * @out_iter: Pointer to a user supplied GtkTreeIter structure to store the * new node in or %NULL to ignore. * * Like swamigui_tree_store_insert() but inserts the node after the * specified @sibling instead. */ void swamigui_tree_store_insert_after (SwamiguiTreeStore *store, GObject *item, const char *label, char *icon, GtkTreeIter *parent, GtkTreeIter *sibling, GtkTreeIter *out_iter) { GtkTreeIter iter; g_return_if_fail (SWAMIGUI_IS_TREE_STORE (store)); g_return_if_fail (!item || G_IS_OBJECT (item)); gtk_tree_store_insert_after (GTK_TREE_STORE (store), &iter, parent, sibling); swamigui_tree_finish_insert (store, item, label, icon, &iter); if (out_iter) *out_iter = iter; } static inline void swamigui_tree_finish_insert (SwamiguiTreeStore *store, GObject *item, const char *label, char *icon, GtkTreeIter *iter) { char *item_label = NULL; char *item_icon = NULL; GtkTreeIter *copy; gint category; if (!label) { if (IPATCH_IS_ITEM (item)) g_object_get (item, "title", &item_label, NULL); else swami_object_get (item, "name", &item_label, NULL); if (!item_label) ipatch_type_object_get (item, "name", &item_label, NULL); if (!item_label) item_label = g_strdup (_("Untitled")); label = item_label; } if (!icon) { /* get item icon from type property */ ipatch_type_object_get (G_OBJECT (item), "icon", &item_icon, "category", &category, NULL); if (item_icon) { /* lookup icon name in hash (no need to store name for every icon) */ icon = g_hash_table_lookup (icon_name_cache, item_icon); if (!icon) { icon = g_strdup (item_icon); g_hash_table_insert (icon_name_cache, icon, icon); } g_free (item_icon); } /* if no type icon get category icon, gets default if category not set */ if (!icon) icon = swamigui_icon_get_category_icon (category); } gtk_tree_store_set (GTK_TREE_STORE (store), iter, SWAMIGUI_TREE_STORE_LABEL_COLUMN, label, SWAMIGUI_TREE_STORE_ICON_COLUMN, icon, SWAMIGUI_TREE_STORE_OBJECT_COLUMN, item, -1); if (item) { copy = gtk_tree_iter_copy (iter); g_object_ref (item); /* ++ ref item for item_hash */ g_hash_table_insert (store->item_hash, item, copy); } if (item_label) g_free (item_label); } /** * swamigui_tree_store_change: * @store: Swami tree store * @item: Object in @store to update * @label: New label or %NULL to keep old * @icon: GdkPixbuf icon or %NULL to keep old * * Changes a row in a Swami tree store. */ void swamigui_tree_store_change (SwamiguiTreeStore *store, GObject *item, const char *label, char *icon) { GtkTreeIter iter; g_return_if_fail (SWAMIGUI_IS_TREE_STORE (store)); g_return_if_fail (G_IS_OBJECT (item)); if (!swamigui_tree_store_item_get_node (store, item, &iter)) return; if (label) gtk_tree_store_set (GTK_TREE_STORE (store), &iter, SWAMIGUI_TREE_STORE_LABEL_COLUMN, label, -1); if (icon) gtk_tree_store_set (GTK_TREE_STORE (store), &iter, SWAMIGUI_TREE_STORE_ICON_COLUMN, icon, -1); } /** * swamigui_tree_store_remove: * @store: Swami tree store * @item: Object in @store to remove * * Removes a node (and all its children) from a Swami tree store. */ void swamigui_tree_store_remove (SwamiguiTreeStore *store, GObject *item) { GtkTreeIter iter; g_return_if_fail (SWAMIGUI_IS_TREE_STORE (store)); g_return_if_fail (G_IS_OBJECT (item)); if (swamigui_tree_store_item_get_node (store, item, &iter)) { if (gtk_tree_model_iter_has_child (GTK_TREE_MODEL (store), &iter)) tree_store_recursive_remove (store, &iter); else { gtk_tree_store_remove (GTK_TREE_STORE (store), &iter); g_hash_table_remove (store->item_hash, item); } } } /* recursively remove tree nodes from a Swami tree store and remove the item->node links in item_hash table */ static void tree_store_recursive_remove (SwamiguiTreeStore *store, GtkTreeIter *iter) { GtkTreeIter children, remove; gboolean retval; register GObject *item; /* register to conserve recursive stack */ if (gtk_tree_model_iter_children ((GtkTreeModel *)store, &children, iter)) { do { remove = children; retval = gtk_tree_model_iter_next ((GtkTreeModel *)store, &children); tree_store_recursive_remove (store, &remove); } while (retval); } item = swamigui_tree_store_node_get_item (store, iter); gtk_tree_store_remove ((GtkTreeStore *)store, iter); g_hash_table_remove (store->item_hash, item); } /** * swamigui_tree_store_move_before: * @store: Swami tree store * @item: Item to move * @position: Location to move item before or %NULL for last position * * Move an item from its current location to before @position. @position * must be at the same level as @item in the tree. */ void swamigui_tree_store_move_before (SwamiguiTreeStore *store, GObject *item, GtkTreeIter *position) { GtkTreeIter iter; g_return_if_fail (SWAMIGUI_IS_TREE_STORE (store)); g_return_if_fail (G_IS_OBJECT (item)); if (swamigui_tree_store_item_get_node (store, item, &iter)) gtk_tree_store_move_before (GTK_TREE_STORE (store), &iter, position); } /** * swamigui_tree_store_move_after: * @store: Swami tree store * @item: Item to move * @position: Location to move item after or %NULL for first position * * Move an item from its current location to after @position. @position * must be at the same level as @item in the tree. */ void swamigui_tree_store_move_after (SwamiguiTreeStore *store, GObject *item, GtkTreeIter *position) { GtkTreeIter iter; g_return_if_fail (SWAMIGUI_IS_TREE_STORE (store)); g_return_if_fail (G_IS_OBJECT (item)); if (swamigui_tree_store_item_get_node (store, item, &iter)) gtk_tree_store_move_after (GTK_TREE_STORE (store), &iter, position); } /** * swamigui_tree_store_item_get_node: * @store: Swami tree store * @item: Item that is in @store * @iter: Pointer to a GtkTreeIter structure to store the linked tree node * * Gets a tree node for @item in @store. The tree node is stored in @iter which * should be a pointer to a user supplied GtkTreeIter structure. * * Returns: %TRUE if @iter was set (@item has a linked node in @store), %FALSE * otherwise */ gboolean swamigui_tree_store_item_get_node (SwamiguiTreeStore *store, GObject *item, GtkTreeIter *iter) { GtkTreeIter *lookup_iter; g_return_val_if_fail (SWAMIGUI_IS_TREE_STORE (store), FALSE); g_return_val_if_fail (G_IS_OBJECT (item), FALSE); lookup_iter = g_hash_table_lookup (store->item_hash, item); if (!lookup_iter) return (FALSE); if (iter) *iter = *lookup_iter; return (TRUE); } /** * swamigui_tree_store_node_get_item: * @store: Swami tree store * @iter: Node in @store to find linked item of * * Gets the linked item object for @iter node in @store. The returned item * is not referenced but can be safely used as long as the tree model isn't * changed (possibly causing item to be destroyed). The item should be ref'd * if used for extended periods. * * Returns: The item object linked with @iter node or %NULL if not found. * Item has NOT been referenced, see note above. */ GObject * swamigui_tree_store_node_get_item (SwamiguiTreeStore *store, GtkTreeIter *iter) { GObject *item; g_return_val_if_fail (SWAMIGUI_IS_TREE_STORE (store), NULL); g_return_val_if_fail (iter != NULL, NULL); gtk_tree_model_get (GTK_TREE_MODEL (store), iter, SWAMIGUI_TREE_STORE_OBJECT_COLUMN, &item, -1); return (item); } /** * swamigui_tree_store_add: * @store: Swami tree store * @item: Item to add * * Add an item to a tree store using the item_add class method (specific to * tree store types). */ void swamigui_tree_store_add (SwamiguiTreeStore *store, GObject *item) { SwamiguiTreeStoreClass *klass; g_return_if_fail (SWAMIGUI_IS_TREE_STORE (store)); g_return_if_fail (G_IS_OBJECT (item)); klass = SWAMIGUI_TREE_STORE_GET_CLASS (store); g_return_if_fail (klass->item_add != NULL); klass->item_add (store, item); } /** * swamigui_tree_store_changed: * @store: Swami tree store * @item: Item that changed * * This function updates the title and sorting of an item that changed using * the item_changed class method (specific to tree store types). * Note that re-ordering of the changed item may occur in * a delayed fashion, to prevent delays while user is typing a name for example. */ void swamigui_tree_store_changed (SwamiguiTreeStore *store, GObject *item) { SwamiguiTreeStoreClass *klass; g_return_if_fail (SWAMIGUI_IS_TREE_STORE (store)); g_return_if_fail (G_IS_OBJECT (item)); klass = SWAMIGUI_TREE_STORE_GET_CLASS (store); g_return_if_fail (klass->item_changed != NULL); klass->item_changed (store, item); } swami/src/swamigui/SwamiguiDnd.h0000644000175000017500000000210411461334205017052 0ustar alessioalessio/* * SwamiguiDnd.h - Swami Drag and Drop stuff * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_DND_H__ #define __SWAMIGUI_DND_H__ enum { SWAMIGUI_DND_OBJECT_INFO, SWAMIGUI_DND_URI_INFO }; #define SWAMIGUI_DND_OBJECT_NAME "GObject-type" #define SWAMIGUI_DND_URI_NAME "text/uri-list" #endif swami/src/swamigui/util.c0000644000175000017500000004014711474034033015620 0ustar alessioalessio/* * util.c - GUI utility functions * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include #include #include #include #include #include #include "util.h" #include "i18n.h" #if 0 /* time interval (in milliseconds) to check if log view should be popped */ #define LOG_POPUP_CHECK_INTERVAL 200 static gboolean log_viewactive = FALSE; /* log window active? */ static gint log_poplevel = LogBad; static gboolean log_popview = FALSE; /* log view popup scheduled? */ static GtkWidget *log_view_widg = NULL; /* currently active error view widg */ #endif /* unique dialog system data */ typedef struct { GtkWidget *dialog; gchar *strkey; int key2; } UniqueDialogKey; gboolean unique_dialog_inited = FALSE; GArray *unique_dialog_array; static void swamigui_util_cb_waitfor_widget_destroyed (GtkWidget *widg, gpointer data); static GtkWidget * swamigui_util_custom_glade_widget_handler (GladeXML *xml, gchar *func_name, gchar *name, gchar *string1, gchar *string2, gint int1, gint int2, gpointer user_data); // static gboolean log_check_popup (gpointer data); // static void log_view_cb_destroy (void); /* initialize various utility services (unique dialog, log view timer, etc) */ void swamigui_util_init (void) { unique_dialog_array = g_array_new (FALSE, FALSE, sizeof (UniqueDialogKey)); unique_dialog_inited = TRUE; // g_timeout_add (LOG_POPUP_CHECK_INTERVAL, (GSourceFunc)log_check_popup, NULL); } guint swamigui_util_unit_rgba_color_get_type (void) { static guint unit_type = 0; if (!unit_type) { IpatchUnitInfo *info; info = ipatch_unit_info_new (); info->value_type = G_TYPE_UINT; info->name = "rgba-color"; info->label = _("Color"); info->descr = _("RGBA color value (in the form 0xRRGGBBAA)"); unit_type = ipatch_unit_register (info); ipatch_unit_info_free (info); } return (unit_type); } /** * swamigui_util_canvas_line_set: * @line: #GnomeCanvasLine object or an item with a "points" property * @x1: First X coordinate of line * @y1: First Y coordinate of line * @x2: Second X coordinate of line * @y2: Second Y coordinate of line * * A convenience function to set a #GnomeCanvasLine to a single line segment. * Can also be used on other #GnomeCanvasItem types which have a "points" * property. */ void swamigui_util_canvas_line_set (GnomeCanvasItem *item, double x1, double y1, double x2, double y2) { GnomeCanvasPoints *points; points = gnome_canvas_points_new (2); points->coords[0] = x1; points->coords[1] = y1; points->coords[2] = x2; points->coords[3] = y2; g_object_set (item, "points", points, NULL); gnome_canvas_points_free (points); } /* Unique dialog system is for allowing unique non-modal dialogs for resources identified by a string key and an optional additional integer key, attempting to open up a second dialog for the same resource will cause the first dialog to be brought to the front of view and no additional dialog will be created */ /* looks up a unique dialog widget by its keys, returns the widget or NULL */ GtkWidget * swamigui_util_lookup_unique_dialog (gchar *strkey, gint key2) { UniqueDialogKey *udkeyp; gint i; for (i = unique_dialog_array->len - 1; i >= 0; i--) { udkeyp = &g_array_index (unique_dialog_array, UniqueDialogKey, i); if ((udkeyp->strkey == strkey || strcmp (udkeyp->strkey, strkey) == 0) && udkeyp->key2 == key2) return (udkeyp->dialog); } return (NULL); } /* register a unique dialog, if a dialog already exists with the same keys, then activate the existing dialog and return FALSE, otherwise register the new dialog and return TRUE */ gboolean swamigui_util_register_unique_dialog (GtkWidget *dialog, gchar *strkey, gint key2) { UniqueDialogKey udkey; GtkWidget *widg; if ((widg = swamigui_util_lookup_unique_dialog (strkey, key2))) { gtk_widget_activate (widg); return (FALSE); } udkey.dialog = dialog; udkey.strkey = strkey; udkey.key2 = key2; g_array_append_val (unique_dialog_array, udkey); gtk_signal_connect (GTK_OBJECT (dialog), "destroy", (GtkSignalFunc)swamigui_util_unregister_unique_dialog, NULL); return (TRUE); } void swamigui_util_unregister_unique_dialog (GtkWidget *dialog) { UniqueDialogKey *udkeyp; gint i; for (i = unique_dialog_array->len - 1; i >= 0; i--) { udkeyp = &g_array_index (unique_dialog_array, UniqueDialogKey, i); if (udkeyp->dialog == dialog) break; } if (i >= 0) g_array_remove_index (unique_dialog_array, i); } /* activate (or raise) a unique dialog into view */ gboolean swamigui_util_activate_unique_dialog (gchar *strkey, gint key2) { GtkWidget *dialog; if ((dialog = swamigui_util_lookup_unique_dialog (strkey, key2))) { gdk_window_raise (GTK_WIDGET (dialog)->window); return (TRUE); } return (FALSE); } /* run gtk_main loop until the GtkObject data property "action" is != NULL, mates nicely with swamigui_util_quick_popup, returns value of "action". Useful for complex routines that require a lot of user dialog interaction. Rather than having to save state info and exit and return to a routine, a call to this routine can be made which will wait for the user's choice and return the index of the button (or other user specified value), -1 if the widget was destroyed or -2 if gtk_main_quit was called */ gpointer swamigui_util_waitfor_widget_action (GtkWidget *widg) { GQuark quark; gpointer val = NULL; gboolean destroyed = FALSE; guint sigid; /* initialize the action variable to NULL */ quark = gtk_object_data_force_id ("action"); gtk_object_set_data_by_id (GTK_OBJECT (widg), quark, NULL); /* already passing one variable to destroy signal handler, so bind this one as a GtkObject data item, will notify us if widget was destroyed */ gtk_object_set_data (GTK_OBJECT (widg), "_destroyed", &destroyed); /* val is set to "action" by swamigui_util_cb_waitfor_widget_destroyed if the widget we are waiting for gets killed */ sigid = gtk_signal_connect (GTK_OBJECT (widg), "destroy", GTK_SIGNAL_FUNC (swamigui_util_cb_waitfor_widget_destroyed), &val); do { if (gtk_main_iteration ()) /* run the gtk main loop, wait if no events */ val = GINT_TO_POINTER (-2); /* gtk_main_quit was called, return -2 */ else if (val == NULL) /* check the "action" data property */ val = gtk_object_get_data_by_id (GTK_OBJECT (widg), quark); } while (val == NULL); /* loop until "action" is set */ if (!destroyed) gtk_signal_disconnect (GTK_OBJECT (widg), sigid); return (val); } static void swamigui_util_cb_waitfor_widget_destroyed (GtkWidget *widg, gpointer data) { gpointer *val = data; gpointer action; gboolean *destroyed; action = gtk_object_get_data (GTK_OBJECT (widg), "action"); destroyed = gtk_object_get_data (GTK_OBJECT (widg), "_destroyed"); *destroyed = TRUE; if (action) *val = action; else *val = GINT_TO_POINTER (-1); } /* a callback for widgets (buttons, etc) within a "parent" widget used by swamigui_util_waitfor_widget_action, sets "action" to the specified "value" */ void swamigui_util_widget_action (GtkWidget *cbwidg, gpointer value) { GtkWidget *parent; parent = gtk_object_get_data (GTK_OBJECT (cbwidg), "parent"); gtk_object_set_data (GTK_OBJECT (parent), "action", value); } /* Glade handler to create custom widgets */ static GtkWidget * swamigui_util_custom_glade_widget_handler (GladeXML *xml, gchar *func_name, gchar *name, gchar *string1, gchar *string2, gint int1, gint int2, gpointer user_data) { GModule *module; gpointer funcptr; GtkWidget * (*newwidg)(void); GtkWidget *widg = NULL; module = g_module_open (NULL, 0); if (g_module_symbol (module, func_name, &funcptr)) { newwidg = funcptr; widg = newwidg (); gtk_widget_show (widg); } else g_warning ("Failed to create glade custom widget '%s' with function '%s'", name, func_name); g_module_close (module); return (widg); } /** * swamigui_util_glade_create: * @name: Name of the glade widget to create * * Creates a glade widget, by @name, from the main Swami glade XML file. * Prints a warning if the named widget does not exist. * * Returns: Newly created glade widget or %NULL on error */ GtkWidget * swamigui_util_glade_create (const char *name) { gboolean first_time = TRUE; char *filename; GladeXML *xml; #ifdef MINGW32 char *appdir; gboolean free_filename = FALSE; appdir = g_win32_get_package_installation_directory_of_module (NULL); /* ++ alloc */ if (appdir) { filename = g_build_filename (appdir, "swami-2.glade", NULL); /* ++ alloc */ free_filename = TRUE; g_free (appdir); /* -- free appdir */ } else filename = UIXML_DIR G_DIR_SEPARATOR_S "swami-2.glade"; #else # ifdef SOURCE_BUILD filename = SOURCE_DIR "/src/swamigui/swami-2.glade"; # else filename = UIXML_DIR G_DIR_SEPARATOR_S "swami-2.glade"; # endif #endif if (first_time) { glade_set_custom_handler (swamigui_util_custom_glade_widget_handler, NULL); first_time = FALSE; } xml = glade_xml_new (filename, name, NULL); #ifdef MINGW32 if (free_filename) g_free (filename); /* -- free allocated filename */ #endif glade_xml_signal_autoconnect (xml); return (glade_xml_get_widget (xml, name)); } /** * swamigui_util_glade_lookup: * @widget: A libglade generated widget or a child there of. * @name: Name of widget in same XML tree as @widget to get. * * Find a libglade generated widget, by @name, via any other widget in * the same XML widget tree. A warning is printed if the widget is not found * to help with debugging, when a widget is expected. Use * swamigui_util_glade_lookup_nowarn() to check if the named * widget does not exist, and not display a warning. * * Returns: The widget or %NULL if not found. */ GtkWidget * swamigui_util_glade_lookup (GtkWidget *widget, const char *name) { GtkWidget *w; w = swamigui_util_glade_lookup_nowarn (widget, name); if (!w) g_warning ("libglade widget not found: %s", name); return (w); } /** * swamigui_util_glade_lookup_nowarn: * @widget: A libglade generated widget or a child there of. * @name: Name of widget in same tree as @widget to get. * * Like swamigui_util_glade_lookup() but does not print a warning if named * widget is not found. * * Returns: The widget or %NULL if not found. */ GtkWidget * swamigui_util_glade_lookup_nowarn (GtkWidget *widget, const char *name) { GladeXML *glade_xml; GtkWidget *w; g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); glade_xml = glade_get_widget_tree (widget); g_return_val_if_fail (glade_xml != NULL, NULL); w = glade_xml_get_widget (glade_xml, name); if (!w) g_warning ("libglade widget not found: %s", name); return (w); } int swamigui_util_option_menu_index (GtkWidget *opmenu) { GtkWidget *menu, *actv; g_return_val_if_fail (GTK_IS_OPTION_MENU (opmenu), 0); menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (opmenu)); actv = gtk_menu_get_active (GTK_MENU (menu)); return (g_list_index (GTK_MENU_SHELL (menu)->children, actv)); } #if 0 /* a callback for a glib timeout that periodically checks if the log view should be popped by the GTK thread (see swamigui_util_init) */ static gboolean log_check_popup (gpointer data) { if (log_popview) { log_popview = FALSE; log_view (NULL); } return (TRUE); } /* log_view - Display log view window */ void log_view (gchar * title) { GtkWidget *dialog; GtkWidget *hbox; GtkWidget *msgarea; GtkAdjustment *adj; GtkWidget *vscrollbar; GtkWidget *btn; static GStaticMutex mutex = G_STATIC_MUTEX_INIT; /* need to lock test and set of log_viewactive */ g_static_mutex_lock (&mutex); if (log_viewactive) { g_static_mutex_unlock (&mutex); return; } log_viewactive = TRUE; g_static_mutex_unlock (&mutex); if (title) dialog = gtk_dialog_new (title); else dialog = gtk_dialog_new (_("Swami log")); hbox = gtk_hbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox, TRUE, TRUE, 0); gtk_widget_show (hbox); msgarea = gtk_text_new (NULL, NULL); gtk_widget_set_default_size (msgarea, 400, 100); gtk_text_set_editable (GTK_TEXT (msgarea), FALSE); gtk_text_set_word_wrap (GTK_TEXT (msgarea), FALSE); /* have to lock on log read, another thread might be writing to it */ g_mutex_lock (log_mutex); gtk_text_insert (GTK_TEXT (msgarea), NULL, NULL, NULL, log_buf->str, -1); g_mutex_unlock (log_mutex); gtk_box_pack_start (GTK_BOX (hbox), msgarea, TRUE, TRUE, 0); gtk_widget_show (msgarea); adj = GTK_TEXT (msgarea)->vadj; /* get the message area's vert adj */ vscrollbar = gtk_vscrollbar_new (adj); gtk_box_pack_start (GTK_BOX (hbox), vscrollbar, FALSE, FALSE, 0); gtk_widget_show (vscrollbar); btn = gtk_button_new_with_label (_("OK")); gtk_signal_connect_object (GTK_OBJECT (btn), "clicked", (GtkSignalFunc) gtk_widget_destroy, GTK_OBJECT (dialog)); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), btn, FALSE, FALSE, 0); gtk_widget_show (btn); gtk_signal_connect_object (GTK_OBJECT (dialog), "destroy", GTK_SIGNAL_FUNC (log_view_cb_destroy), NULL); gtk_widget_show (dialog); log_view_widg = NULL; } /* reset dialog active variables */ static void log_view_cb_destroy (void) { log_viewactive = FALSE; log_view_widg = NULL; } #endif /** * swamigui_util_str_crlf2lf: * @str: String to convert * * Convert all dos newlines ("\r\n") to unix newlines "\n" in a string * * Returns: New string with converted newlines, should be freed when done with */ char * swamigui_util_str_crlf2lf (char *str) { char *newstr, *s; newstr = g_new (char, strlen (str) + 1); s = newstr; while (*str != '\0') { if (*str != '\r' || *(str + 1) != '\n') *(s++) = *str; str++; } *s = '\0'; return (newstr); } /** * swamigui_util_str_lf2crlf: * @str: String to convert * * Convert all unix newlines "\n" to dos newlines ("\r\n") in a string * * Returns: New string with converted newlines, should be freed when done with */ char * swamigui_util_str_lf2crlf (char *str) { GString *gs; char *s; gs = g_string_sized_new (sizeof (str)); while (*str != '\0') { if (*str != '\n') gs = g_string_append_c (gs, *str); else gs = g_string_append (gs, "\r\n"); str++; } s = gs->str; g_string_free (gs, FALSE); /* character segment is not free'd */ return (s); } /** * swamigui_util_substrcmp: * @sub: Partial string to search for in str * @str: String to search for sub string in * * Search for a sub string in a string * * Returns: %TRUE if "sub" is found in "str", %FALSE otherwise */ int swamigui_util_substrcmp (char *sub, char *str) { char *s, *s2; if (!*sub) return (TRUE); /* null string, matches */ while (*str) { if (tolower (*str) == tolower (*sub)) { s = sub + 1; s2 = str + 1; while (*s && *s2) { if (tolower (*s) != tolower (*s2)) break; s++; s2++; } if (!*s) return (TRUE); } str++; } return (FALSE); } swami/src/swamigui/SwamiguiPanel.h0000644000175000017500000000523711461334205017416 0ustar alessioalessio/* * SwamiguiPanel.h - Panel control interface type * For managing control interfaces in a plug-able way. * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_PANEL_H__ #define __SWAMIGUI_PANEL_H__ typedef struct _SwamiguiPanel SwamiguiPanel; /* dummy typedef */ typedef struct _SwamiguiPanelIface SwamiguiPanelIface; #include #include #define SWAMIGUI_TYPE_PANEL (swamigui_panel_get_type ()) #define SWAMIGUI_PANEL(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMIGUI_TYPE_PANEL, SwamiguiPanel)) #define SWAMIGUI_PANEL_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMIGUI_TYPE_PANEL, SwamiguiPanelIface)) #define SWAMIGUI_IS_PANEL(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMIGUI_TYPE_PANEL)) #define SWAMIGUI_PANEL_GET_IFACE(obj) \ (G_TYPE_INSTANCE_GET_INTERFACE ((obj), SWAMIGUI_TYPE_PANEL, \ SwamiguiPanelIface)) /** * SwamiguiPanelCheckFunc: * @selection: Item selection to verify (will contain at least 1 item) * @selection_types: 0 terminated array of unique item GTypes found in @selection * * Function prototype used for checking if an item selection is valid for a * panel. * * Returns: Should return %TRUE if item selection is valid, %FALSE otherwise */ typedef gboolean (*SwamiguiPanelCheckFunc)(IpatchList *selection, GType *selection_types); struct _SwamiguiPanelIface { GTypeInterface parent_class; char *label; /* User label name for panel */ char *blurb; /* more descriptive text about panel */ char *stockid; /* stock ID of icon */ SwamiguiPanelCheckFunc check_selection; }; GType swamigui_panel_get_type (void); void swamigui_panel_type_get_info (GType type, char **label, char **blurb, char **stockid); gboolean swamigui_panel_type_check_selection (GType type, IpatchList *selection, GType *selection_types); GType *swamigui_panel_get_types_in_selection (IpatchList *selection); #endif swami/src/swamigui/SwamiguiSampleEditor.c0000644000175000017500000026221211461334205020740 0ustar alessioalessio/* * SwamiguiSampleEditor.c - Sample editor widget * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include #include /* log_if_fail() */ #include "SwamiguiControl.h" #include "SwamiguiRoot.h" #include "SwamiguiSampleEditor.h" #include "SwamiguiSampleCanvas.h" #include "SwamiguiLoopFinder.h" #include "icons.h" #include "util.h" #include "i18n.h" /* number of markers that are built in (don't get removed) */ #define BUILTIN_MARKER_COUNT 3 /* value stored in editor->sel_state for current active selection state */ typedef enum { SEL_INACTIVE, /* no selection is in progress */ SEL_MAYBE, /* a mouse click occurred by not moved enough yet */ SEL_START, /* actively changing selection from start edge */ SEL_END /* actively changing selection from end edge */ } SelState; typedef struct { IpatchSampleData *sample; gboolean right_chan; /* set to TRUE for stereo to use right channel */ GnomeCanvasItem *sample_view; GnomeCanvasItem *loop_view; GnomeCanvasItem *sample_center_line; /* sample view horizonal center line */ GnomeCanvasItem *loop_center_line; /* loop view horizontal center line */ } TrackInfo; typedef struct { guint flags; /* SwamiguiSampleEditorMarkerFlags */ gboolean visible; /* TRUE if visible, FALSE otherwise */ SwamiControl *start_ctrl; /* marker start control */ SwamiControl *end_ctrl; /* marker end control (range only) */ GnomeCanvasItem *start_line; /* marker start line canvas item */ GnomeCanvasItem *end_line; /* marker end line canvas item (range only) */ GnomeCanvasItem *range_box; /* marker range box (range only) */ guint start_pos; /* sample start position of marker */ guint end_pos; /* sample end position of marker (range only) */ SwamiguiSampleEditor *editor; /* so we can pass MarkerInfo to callbacks */ } MarkerInfo; /* min zoom value for sample and loop canvas (samples/pixel) */ #define SAMPLE_CANVAS_MIN_ZOOM 0.02 #define LOOP_CANVAS_MIN_ZOOM 0.02 #define LOOP_CANVAS_DEF_ZOOM 0.2 /* default zoom for loop canvas */ /* default colors */ #define DEFAULT_CENTER_LINE_COLOR 0x7F00FFFF #define DEFAULT_MARKER_BORDER_COLOR 0xBBBBBBFF #define DEFAULT_SNAP_LINE_COLOR 0xFF0000FF #define DEFAULT_LOOP_LINE_COLOR 0x777777FF /* default marker colors */ guint default_marker_colors[] = { GNOME_CANVAS_COLOR (0xC2, 0xFF, 0xB6), /* selection marker */ GNOME_CANVAS_COLOR (0xB5, 0x10, 0xFF), /* loop finder start marker */ GNOME_CANVAS_COLOR (0xFF, 0x10, 0x70), /* loop finder end marker */ GNOME_CANVAS_COLOR (0x21, 0xED, 0x3D), /* loop (handler defined) */ GNOME_CANVAS_COLOR (0xFF, 0xEE, 0x10), GNOME_CANVAS_COLOR (0xFF, 0x30, 0x10), GNOME_CANVAS_COLOR (0x10, 0xC4, 0xFF), GNOME_CANVAS_COLOR (0x10, 0xFF, 0x7B) }; /* default height of marker bar */ #define DEFAULT_MARKER_BAR_HEIGHT 24 /* colors are in RRGGBBAA */ #define MARKER_DEFAULT_COLOR 0x00FF00FF /* interactive marker color */ #define MARKER_NONIACTV_COLOR 0x666666FF /* non-interactive marker color */ #define MARKER_DEFAULT_WIDTH 1 /* width of markers (in pixels) */ #define MARKER_CLICK_DISTANCE 3 /* click area surrounding markers (in pixels) */ enum { PROP_0, PROP_ITEM_SELECTION, PROP_BORDER_WIDTH, PROP_MARKER_BAR_HEIGHT }; static void swamigui_sample_editor_class_init (SwamiguiSampleEditorClass *klass); static void swamigui_sample_editor_panel_iface_init (SwamiguiPanelIface *panel_iface); static gboolean swamigui_sample_editor_panel_iface_check_selection (IpatchList *selection, GType *selection_types); static void swamigui_sample_editor_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void swamigui_sample_editor_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void swamigui_sample_editor_finalize (GObject *object); static void swamigui_sample_editor_init (SwamiguiSampleEditor *editor); #if 0 static void swamigui_sample_editor_cb_cut_sample (GtkToggleToolButton *button, gpointer user_data); static void swamigui_sample_editor_cb_crop_sample (GtkToggleToolButton *button, gpointer user_data); static void swamigui_sample_editor_cb_copy_new_sample (GtkToggleToolButton *button, gpointer user_data); static IpatchSampleData *get_selection_sample_data (SwamiguiSampleEditor *editor); #endif static void swamigui_sample_editor_cb_loop_finder (GtkToggleToolButton *button, gpointer user_data); static void editor_cb_pane_size_allocate (GtkWidget *pane, GtkAllocation *allocation, gpointer user_data); static void swamigui_sample_editor_cb_canvas_size_allocate (GtkWidget *widget, GtkAllocation *allocation, gpointer user_data); static void swamigui_sample_editor_update_sizes (SwamiguiSampleEditor *editor); static void swamigui_sample_editor_update_canvas_size (SwamiguiSampleEditor *editor, GnomeCanvas *canvas); static void swamigui_sample_editor_cb_scroll (GtkAdjustment *adj, gpointer user_data); static gboolean swamigui_sample_editor_cb_sample_canvas_event (GnomeCanvas *canvas, GdkEvent *event, gpointer data); static gboolean swamigui_sample_editor_cb_loop_canvas_event (GnomeCanvas *canvas, GdkEvent *event, gpointer data); static MarkerInfo * pos_is_marker (SwamiguiSampleEditor *editor, int xpos, int ypos, int *marker_edge, gboolean *is_onbox); static void swamigui_sample_editor_sample_mod_update (SwamiguiCanvasMod *mod, double xzoom, double yzoom, double xscroll, double yscroll, double xpos, double ypos, gpointer user_data); static void swamigui_sample_editor_sample_mod_snap (SwamiguiCanvasMod *mod, guint actions, double xsnap, double ysnap, gpointer user_data); static void swamigui_sample_editor_loop_mod_update (SwamiguiCanvasMod *mod, double xzoom, double yzoom, double xscroll, double yscroll, double xpos, double ypos, gpointer user_data); static void swamigui_sample_editor_loop_mod_snap (SwamiguiCanvasMod *mod, guint actions, double xsnap, double ysnap, gpointer user_data); static gboolean swamigui_sample_editor_real_set_selection (SwamiguiSampleEditor *editor, IpatchList *items); static void swamigui_sample_editor_deactivate_handler (SwamiguiSampleEditor *editor); static void swamigui_sample_editor_remove_track_item (SwamiguiSampleEditor *editor, GList *p, gboolean destroy); static void swamigui_sample_editor_set_marker_info (SwamiguiSampleEditor *editor, MarkerInfo *marker_info, guint start, guint end); static void swamigui_sample_editor_remove_marker_item (SwamiguiSampleEditor *editor, GList *p, gboolean destroy); static void start_marker_control_get_value_func (SwamiControl *control, GValue *value); static void start_marker_control_set_value_func (SwamiControl *control, SwamiControlEvent *event, const GValue *value); static void end_marker_control_get_value_func (SwamiControl *control, GValue *value); static void end_marker_control_set_value_func (SwamiControl *control, SwamiControlEvent *event, const GValue *value); static void marker_control_update (MarkerInfo *marker_info); static void marker_control_update_all (SwamiguiSampleEditor *editor); static gboolean swamigui_sample_editor_default_handler (SwamiguiSampleEditor *editor); static gboolean swamigui_sample_editor_default_handler_check_func (IpatchList *selection, GType *selection_types); static void swamigui_sample_editor_loopsel_ctrl_get (SwamiControl *control, GValue *value); static void swamigui_sample_editor_loopsel_ctrl_set (SwamiControl *control, SwamiControlEvent *event, const GValue *value); static void swamigui_sample_editor_loopsel_cb_changed (GtkComboBox *widget, gpointer user_data); static GObjectClass *parent_class = NULL; /* list of SwamiguiSampleEditorHandlers */ static GList *sample_editor_handlers = NULL; /* list of SwamiguiPanelCheckFunc corresponding to sample_editor_handlers */ static GList *sample_editor_check_funcs = NULL; /* loop type info for IpatchSampleLoopType enum GtkComboBox */ struct { int loop_type; char *icon; char *label; char *tooltip; } loop_type_info[] = { { IPATCH_SAMPLE_LOOP_NONE, SWAMIGUI_STOCK_LOOP_NONE, N_("None"), N_("No looping") }, { IPATCH_SAMPLE_LOOP_STANDARD, SWAMIGUI_STOCK_LOOP_STANDARD, N_("Standard"), N_("Standard continuous loop") }, { IPATCH_SAMPLE_LOOP_RELEASE, SWAMIGUI_STOCK_LOOP_RELEASE, N_("Release"), N_("Loop until key is released then play to end of sample") }, { IPATCH_SAMPLE_LOOP_PINGPONG, SWAMIGUI_STOCK_LOOP_STANDARD, /* FIXME */ N_("Ping Pong"), N_("Alternate playing loop forwards and backwards") } }; /* columns from GtkListStore model for loop selector GtkComboBox */ enum { LOOPSEL_COL_LOOP_TYPE, LOOPSEL_COL_ICON, LOOPSEL_COL_LABEL, LOOPSEL_COL_TOOLTIP, LOOPSEL_COL_COUNT }; GType swamigui_sample_editor_get_type (void) { static GType obj_type = 0; if (!obj_type) { static const GTypeInfo obj_info = { sizeof (SwamiguiSampleEditorClass), NULL, NULL, (GClassInitFunc) swamigui_sample_editor_class_init, NULL, NULL, sizeof (SwamiguiSampleEditor), 0, (GInstanceInitFunc) swamigui_sample_editor_init, }; static const GInterfaceInfo panel_info = { (GInterfaceInitFunc)swamigui_sample_editor_panel_iface_init, NULL, NULL }; obj_type = g_type_register_static (GTK_TYPE_HBOX, "SwamiguiSampleEditor", &obj_info, 0); g_type_add_interface_static (obj_type, SWAMIGUI_TYPE_PANEL, &panel_info); /* register default sample editor handler */ swamigui_sample_editor_register_handler (swamigui_sample_editor_default_handler, swamigui_sample_editor_default_handler_check_func); } return (obj_type); } static void swamigui_sample_editor_class_init (SwamiguiSampleEditorClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); parent_class = g_type_class_peek_parent (klass); obj_class->set_property = swamigui_sample_editor_set_property; obj_class->get_property = swamigui_sample_editor_get_property; obj_class->finalize = swamigui_sample_editor_finalize; g_object_class_override_property (obj_class, PROP_ITEM_SELECTION, "item-selection"); g_object_class_install_property (obj_class, PROP_MARKER_BAR_HEIGHT, g_param_spec_int ("marker-bar-height", _("Marker bar height"), _("Height of marker and loop meter bar"), 0, 100, DEFAULT_MARKER_BAR_HEIGHT, G_PARAM_READWRITE)); } static void swamigui_sample_editor_panel_iface_init (SwamiguiPanelIface *panel_iface) { panel_iface->label = _("Sample Editor"); panel_iface->blurb = _("Sample data and loop editor"); panel_iface->stockid = SWAMIGUI_STOCK_SAMPLE_VIEWER; panel_iface->check_selection = swamigui_sample_editor_panel_iface_check_selection; } static gboolean swamigui_sample_editor_panel_iface_check_selection (IpatchList *selection, GType *selection_types) { GList *p; /* loop over handler check functions */ for (p = sample_editor_check_funcs; p; p = p->next) { if (((SwamiguiPanelCheckFunc)(p->data))(selection, selection_types)) return (TRUE); } return (FALSE); } static void swamigui_sample_editor_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { SwamiguiSampleEditor *editor = SWAMIGUI_SAMPLE_EDITOR (object); IpatchList *list; int i; switch (property_id) { case PROP_ITEM_SELECTION: list = g_value_get_object (value); swamigui_sample_editor_real_set_selection (editor, list); break; case PROP_MARKER_BAR_HEIGHT: i = g_value_get_int (value); if (i != editor->marker_bar_height) { editor->marker_bar_height = i; swamigui_sample_editor_update_sizes (editor); } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_sample_editor_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { SwamiguiSampleEditor *editor = SWAMIGUI_SAMPLE_EDITOR (object); switch (property_id) { case PROP_ITEM_SELECTION: g_value_set_object (value, editor->selection); break; case PROP_MARKER_BAR_HEIGHT: g_value_set_int (value, editor->marker_bar_height); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_sample_editor_finalize (GObject *object) { SwamiguiSampleEditor *editor = SWAMIGUI_SAMPLE_EDITOR (object); GList *p, *temp; /* remove all markers (don't destroy GtkObjects though) */ p = editor->markers; while (p) { temp = p; p = g_list_next (p); swamigui_sample_editor_remove_marker_item (editor, temp, FALSE); } /* remove all tracks (don't destroy GtkObjects though) */ p = editor->tracks; while (p) { temp = p; p = g_list_next (p); swamigui_sample_editor_remove_track_item (editor, temp, FALSE); } if (editor->selection) g_object_unref (editor->selection); if (editor->loop_start_hub) g_object_unref (editor->loop_start_hub); if (editor->loop_end_hub) g_object_unref (editor->loop_end_hub); if (editor->loopsel_ctrl) g_object_unref (editor->loopsel_ctrl); if (editor->loopsel_store) g_object_unref (editor->loopsel_store); editor->selection = NULL; editor->loop_start_hub = NULL; editor->loop_end_hub = NULL; editor->loopsel_ctrl = NULL; editor->loopsel_store = NULL; /* remove ref, necessary since pane is added/removed from container */ g_object_unref (editor->loop_finder_pane); if (parent_class->finalize) (*parent_class->finalize)(object); } static void swamigui_sample_editor_init (SwamiguiSampleEditor *editor) { GtkWidget *vbox, *hbox; GtkWidget *frame; GtkWidget *pane; GtkWidget *image; GtkToolItem *item; GtkStyle *style; GtkCellRenderer *renderer; GtkTooltips *tips; SwamiLoopFinder *loop_finder; SwamiControl *marker_start, *marker_end; int id; editor->selection = NULL; editor->marker_bar_height = DEFAULT_MARKER_BAR_HEIGHT; editor->sel_marker = -1; editor->zoom_all = TRUE; editor->sel_state = SEL_INACTIVE; editor->center_line_color = DEFAULT_CENTER_LINE_COLOR; editor->marker_border_color = DEFAULT_MARKER_BORDER_COLOR; editor->snap_line_color = DEFAULT_SNAP_LINE_COLOR; editor->loop_line_color = DEFAULT_LOOP_LINE_COLOR; editor->loop_zoom = LOOP_CANVAS_DEF_ZOOM; /* create zoom/scroll modulator for sample canvas */ editor->sample_mod = swamigui_canvas_mod_new (); /* attach to "update" and "snap" signals */ g_signal_connect (editor->sample_mod, "update", G_CALLBACK (swamigui_sample_editor_sample_mod_update), editor); g_signal_connect (editor->sample_mod, "snap", G_CALLBACK (swamigui_sample_editor_sample_mod_snap), editor); /* create zoom modulator for loop canvas */ editor->loop_mod = swamigui_canvas_mod_new (); /* attach to "update" and "snap" signals */ g_signal_connect (editor->loop_mod, "update", G_CALLBACK (swamigui_sample_editor_loop_mod_update), editor); g_signal_connect (editor->loop_mod, "snap", G_CALLBACK (swamigui_sample_editor_loop_mod_snap), editor); /* create control hubs to control sample loop views for all tracks */ /* editor retains holds references on controls */ editor->loop_start_hub = SWAMI_CONTROL (swami_control_hub_new ()); /* ++ ref */ swamigui_control_set_queue (editor->loop_start_hub); editor->loop_end_hub = SWAMI_CONTROL (swami_control_hub_new ()); /* ++ ref */ swamigui_control_set_queue (editor->loop_end_hub); tips = gtk_tooltips_new (); /* create loop finder widget and pane, only gets packed when active */ editor->loop_finder_gui = SWAMIGUI_LOOP_FINDER (swamigui_loop_finder_new ()); editor->loop_finder_pane = gtk_hpaned_new (); gtk_paned_pack1 (GTK_PANED (editor->loop_finder_pane), GTK_WIDGET (editor->loop_finder_gui), FALSE, TRUE); gtk_widget_show_all (editor->loop_finder_pane); /* we add an extra ref to finder hpane since it will be added/removed as needed */ g_object_ref (editor->loop_finder_pane); /* create main vbox for tool bar and sample canvases and pack in editor hbox */ editor->mainvbox = gtk_vbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (editor), editor->mainvbox, TRUE, TRUE, 0); /* create toolbox area horizontal box */ editor->toolbar = gtk_toolbar_new (); editor->loopsel_store /* ++ ref - editor holds reference to loopsel_store */ = gtk_list_store_new (LOOPSEL_COL_COUNT, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); editor->loopsel = gtk_combo_box_new_with_model (GTK_TREE_MODEL (editor->loopsel_store)); gtk_widget_set_sensitive (editor->loopsel, FALSE); item = gtk_tool_item_new (); gtk_container_add (GTK_CONTAINER (item), editor->loopsel); gtk_toolbar_insert (GTK_TOOLBAR (editor->toolbar), item, -1); /* create the control for the loop type selector */ /* ++ ref - editor holds reference to it */ editor->loopsel_ctrl = SWAMI_CONTROL (swami_control_func_new ()); /* attach to the changed signal of the combo box */ g_signal_connect (editor->loopsel, "changed", G_CALLBACK (swamigui_sample_editor_loopsel_cb_changed), editor); swami_control_func_assign_funcs (SWAMI_CONTROL_FUNC (editor->loopsel_ctrl), swamigui_sample_editor_loopsel_ctrl_get, swamigui_sample_editor_loopsel_ctrl_set, NULL, editor); renderer = gtk_cell_renderer_pixbuf_new (); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (editor->loopsel), renderer, FALSE); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (editor->loopsel), renderer, "stock-id", LOOPSEL_COL_ICON, NULL); renderer = gtk_cell_renderer_text_new (); gtk_cell_layout_pack_end (GTK_CELL_LAYOUT (editor->loopsel), renderer, TRUE); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (editor->loopsel), renderer, "text", LOOPSEL_COL_LABEL, NULL); /* create spin button and spin control */ editor->spinbtn_start = gtk_spin_button_new (NULL, 1.0, 0); gtk_spin_button_set_range (GTK_SPIN_BUTTON (editor->spinbtn_start), 0.0, (gdouble)G_MAXINT); gtk_tooltips_set_tip (tips, editor->spinbtn_start, _("Set loop start position"), NULL); editor->spinbtn_start_ctrl = swamigui_control_new_for_widget_full (G_OBJECT (editor->spinbtn_start), G_TYPE_UINT, NULL, 0); item = gtk_tool_item_new (); gtk_container_add (GTK_CONTAINER (item), editor->spinbtn_start); gtk_toolbar_insert (GTK_TOOLBAR (editor->toolbar), item, -1); /* spin button and spin control */ editor->spinbtn_end = gtk_spin_button_new (NULL, 1.0, 0); gtk_spin_button_set_range (GTK_SPIN_BUTTON (editor->spinbtn_end), 0.0, (gdouble)G_MAXINT); gtk_tooltips_set_tip (tips, editor->spinbtn_end, _("Set loop end position"), NULL); editor->spinbtn_end_ctrl = swamigui_control_new_for_widget_full (G_OBJECT (editor->spinbtn_end), G_TYPE_UINT, NULL, 0); item = gtk_tool_item_new (); gtk_container_add (GTK_CONTAINER (item), editor->spinbtn_end); gtk_toolbar_insert (GTK_TOOLBAR (editor->toolbar), item, -1); /* Disabled until sample editing operations are implemented */ #if 0 /* add separator */ gtk_toolbar_insert (GTK_TOOLBAR (editor->toolbar), gtk_separator_tool_item_new (), -1); /* create cut button */ image = gtk_image_new_from_stock (GTK_STOCK_CUT, GTK_ICON_SIZE_SMALL_TOOLBAR); editor->cut_button = GTK_WIDGET (gtk_tool_button_new (image, _("Cut"))); gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (editor->cut_button), tips, _("Cut selected sample data"), NULL); gtk_toolbar_insert (GTK_TOOLBAR (editor->toolbar), GTK_TOOL_ITEM (editor->cut_button), -1); g_signal_connect (editor->cut_button, "clicked", G_CALLBACK (swamigui_sample_editor_cb_cut_sample), editor); /* create crop button */ image = gtk_image_new_from_stock (GTK_STOCK_GO_DOWN, GTK_ICON_SIZE_SMALL_TOOLBAR); editor->crop_button = GTK_WIDGET (gtk_tool_button_new (image, _("Crop"))); gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (editor->crop_button), tips, _("Crop to current selection"), NULL); gtk_toolbar_insert (GTK_TOOLBAR (editor->toolbar), GTK_TOOL_ITEM (editor->crop_button), -1); g_signal_connect (editor->crop_button, "clicked", G_CALLBACK (swamigui_sample_editor_cb_crop_sample), editor); /* create copy to new button */ image = gtk_image_new_from_stock (GTK_STOCK_NEW, GTK_ICON_SIZE_SMALL_TOOLBAR); editor->copy_new_button = GTK_WIDGET (gtk_tool_button_new (image, _("Copy to new"))); gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (editor->copy_new_button), tips, _("Copy selection to new sample"), NULL); gtk_toolbar_insert (GTK_TOOLBAR (editor->toolbar), GTK_TOOL_ITEM (editor->copy_new_button), -1); g_signal_connect (editor->copy_new_button, "clicked", G_CALLBACK (swamigui_sample_editor_cb_copy_new_sample), editor); /* create sample selector button */ editor->samplesel_button = GTK_WIDGET (gtk_toggle_tool_button_new ()); gtk_tool_button_set_label (GTK_TOOL_BUTTON (editor->samplesel_button), _("Sample selector")); image = gtk_image_new_from_stock (GTK_STOCK_INDEX, GTK_ICON_SIZE_SMALL_TOOLBAR); gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (editor->samplesel_button), image); gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (editor->samplesel_button), tips, _("Make selection the entire sample"), NULL); gtk_toolbar_insert (GTK_TOOLBAR (editor->toolbar), GTK_TOOL_ITEM (editor->samplesel_button), -1); #endif /* add separator */ gtk_toolbar_insert (GTK_TOOLBAR (editor->toolbar), gtk_separator_tool_item_new (), -1); /* create loop finder button */ editor->finder_button = GTK_WIDGET (gtk_toggle_tool_button_new ()); gtk_tool_button_set_label (GTK_TOOL_BUTTON (editor->finder_button), _("Find loops")); image = gtk_image_new_from_stock (GTK_STOCK_FIND, GTK_ICON_SIZE_SMALL_TOOLBAR); gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (editor->finder_button), image); gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (editor->finder_button), tips, _("Loop point finder"), NULL); gtk_toolbar_insert (GTK_TOOLBAR (editor->toolbar), GTK_TOOL_ITEM (editor->finder_button), -1); g_signal_connect (editor->finder_button, "toggled", G_CALLBACK (swamigui_sample_editor_cb_loop_finder), editor); gtk_box_pack_start (GTK_BOX (editor->mainvbox), editor->toolbar, FALSE, FALSE, 0); /* lower inset frame for sample viewer */ frame = gtk_frame_new (NULL); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); gtk_container_set_border_width (GTK_CONTAINER (frame), 0); gtk_box_pack_start (GTK_BOX (editor->mainvbox), frame, TRUE, TRUE, 0); /* vbox within frame to put sample canvas */ vbox = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (frame), vbox); hbox = gtk_hbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); pane = gtk_hpaned_new (); gtk_box_pack_start (GTK_BOX (hbox), pane, TRUE, TRUE, 0); /* connect to the size-allocate signal so we can initialize the gutter pos */ g_signal_connect_after (pane, "size-allocate", G_CALLBACK (editor_cb_pane_size_allocate), NULL); /* create sample editor canvas */ editor->sample_canvas = GNOME_CANVAS (gnome_canvas_new ()); gnome_canvas_set_center_scroll_region (GNOME_CANVAS (editor->sample_canvas), FALSE); gtk_paned_pack1 (GTK_PANED (pane), GTK_WIDGET (editor->sample_canvas), TRUE, TRUE); g_signal_connect (editor->sample_canvas, "event", G_CALLBACK (swamigui_sample_editor_cb_sample_canvas_event), editor); g_signal_connect (editor->sample_canvas, "size-allocate", G_CALLBACK (swamigui_sample_editor_cb_canvas_size_allocate), editor); /* change background color of canvas to black */ style = gtk_style_copy (gtk_widget_get_style (GTK_WIDGET (editor->sample_canvas))); style->bg[GTK_STATE_NORMAL] = style->black; gtk_widget_set_style (GTK_WIDGET (editor->sample_canvas), style); /* create sample view marker bar border horizontal line */ editor->sample_border_line = gnome_canvas_item_new (gnome_canvas_root (editor->sample_canvas), GNOME_TYPE_CANVAS_LINE, "fill-color-rgba", editor->marker_border_color, "width-pixels", 1, NULL); /* create snap lines */ editor->xsnap_line = gnome_canvas_item_new (gnome_canvas_root (editor->sample_canvas), GNOME_TYPE_CANVAS_LINE, "fill-color-rgba", editor->snap_line_color, "width-pixels", 2, NULL); gnome_canvas_item_hide (editor->xsnap_line); editor->ysnap_line = gnome_canvas_item_new (gnome_canvas_root (editor->sample_canvas), GNOME_TYPE_CANVAS_LINE, "fill-color-rgba", editor->snap_line_color, "width-pixels", 2, NULL); gnome_canvas_item_hide (editor->ysnap_line); /* create sample loop canvas */ editor->loop_canvas = GNOME_CANVAS (gnome_canvas_new ()); gnome_canvas_set_center_scroll_region (GNOME_CANVAS (editor->loop_canvas), FALSE); gtk_paned_pack2 (GTK_PANED (pane), GTK_WIDGET (editor->loop_canvas), FALSE, TRUE); g_signal_connect (editor->loop_canvas, "event", G_CALLBACK (swamigui_sample_editor_cb_loop_canvas_event), editor); g_signal_connect (editor->loop_canvas, "size-allocate", G_CALLBACK (swamigui_sample_editor_cb_canvas_size_allocate), editor); /* change background color of canvas to black */ style = gtk_style_copy (gtk_widget_get_style (GTK_WIDGET (editor->loop_canvas))); style->bg[GTK_STATE_NORMAL] = style->black; gtk_widget_set_style (GTK_WIDGET (editor->loop_canvas), style); /* create vertical center line for loop view */ editor->loop_line = gnome_canvas_item_new (gnome_canvas_root (editor->loop_canvas), GNOME_TYPE_CANVAS_LINE, "fill-color-rgba", editor->loop_line_color, "width-pixels", 1, NULL); /* create loop view marker bar border horizontal line */ editor->loop_border_line = gnome_canvas_item_new (gnome_canvas_root (editor->loop_canvas), GNOME_TYPE_CANVAS_LINE, "fill-color-rgba", editor->marker_border_color, "width-pixels", 1, NULL); /* create zoom snap line for loop view */ editor->loop_snap_line = gnome_canvas_item_new (gnome_canvas_root (editor->loop_canvas), GNOME_TYPE_CANVAS_LINE, "fill-color-rgba", editor->snap_line_color, "width-pixels", 2, NULL); gnome_canvas_item_hide (editor->loop_snap_line); /* attach a horizontal scrollbar to the sample viewer */ editor->hscrollbar = gtk_hscrollbar_new (NULL); gtk_box_pack_start (GTK_BOX (editor->mainvbox), editor->hscrollbar, FALSE, FALSE, 0); g_signal_connect_after (gtk_range_get_adjustment (GTK_RANGE (editor->hscrollbar)), "value-changed", G_CALLBACK (swamigui_sample_editor_cb_scroll), editor); gtk_widget_show_all (editor->mainvbox); /* create marker 0 for selection and hide it */ id = swamigui_sample_editor_add_marker (editor, 0, NULL, NULL); swamigui_sample_editor_show_marker (editor, id, FALSE); loop_finder = editor->loop_finder_gui->loop_finder; /* create marker for loop finder start search window and hide it */ id = swamigui_sample_editor_add_marker (editor, 0, &marker_start, &marker_end); swamigui_sample_editor_show_marker (editor, id, FALSE); /* connect the marker controls to the loop finder properties */ swami_control_prop_connect_to_control (G_OBJECT (loop_finder), "window1-start", marker_start, SWAMI_CONTROL_CONN_BIDIR_INIT); swami_control_prop_connect_to_control (G_OBJECT (loop_finder), "window1-end", marker_end, SWAMI_CONTROL_CONN_BIDIR_INIT); /* create marker for loop finder end search window and hide it */ id = swamigui_sample_editor_add_marker (editor, 0, &marker_start, &marker_end); swamigui_sample_editor_show_marker (editor, id, FALSE); /* connect the marker controls to the loop finder properties */ swami_control_prop_connect_to_control (G_OBJECT (loop_finder), "window2-start", marker_start, SWAMI_CONTROL_CONN_BIDIR_INIT); swami_control_prop_connect_to_control (G_OBJECT (loop_finder), "window2-end", marker_end, SWAMI_CONTROL_CONN_BIDIR_INIT); } #if 0 static void swamigui_sample_editor_cb_cut_sample (GtkToggleToolButton *button, gpointer user_data) { SwamiguiSampleEditor *editor = SWAMIGUI_SAMPLE_EDITOR (user_data); MarkerInfo *marker; IpatchSampleData *data; IpatchSampleStore *store; /* shouldn't happen, but.. */ if (!editor->markers || !editor->markers->data) return; /* first marker is selection */ marker = (MarkerInfo *)(editor->markers->data); if (!marker->visible) return; data = get_selection_sample_data (editor); /* ++ ref */ if (!data) return; store = ipatch_sample_data_get_default_store (data); /* ++ ref */ list = ipatch_sample_list_new (); ipatch_sample_list_append (list, store, 0, 0, 0); ipatch_sample_list_cut (list, marker->start_pos, marker->end_pos - marker->start_pos + 1); g_object_unref (data); /* -- unref */ } static void swamigui_sample_editor_cb_crop_sample (GtkToggleToolButton *button, gpointer user_data) { SwamiguiSampleEditor *editor = SWAMIGUI_SAMPLE_EDITOR (user_data); IpatchSampleData *data; data = get_selection_sample_data (editor); if (!data) return; } static void swamigui_sample_editor_cb_copy_new_sample (GtkToggleToolButton *button, gpointer user_data) { SwamiguiSampleEditor *editor = SWAMIGUI_SAMPLE_EDITOR (user_data); IpatchSampleData *data; data = get_selection_sample_data (editor); if (!data) return; } /* returns a IpatchSampleData object for the current selection or NULL if * not a single item which has an IpatchSample interface which allows * get/set of sample data. Caller owns ref to sample data */ static IpatchSampleData * get_selection_sample_data (SwamiguiSampleEditor *editor) { IpatchSample *sample; if (!editor->selection || !editor->selection->items || editor->selection->items->next || !IPATCH_IS_SAMPLE (editor->selection->items->data)) return (NULL); sample = IPATCH_SAMPLE (editor->selection->items->data); if (!ipatch_sample_has_data (sample)) return (NULL); return (ipatch_sample_get_data (sample)); /* !! caller takes reference */ } #endif static void swamigui_sample_editor_cb_loop_finder (GtkToggleToolButton *button, gpointer user_data) { SwamiguiSampleEditor *editor = SWAMIGUI_SAMPLE_EDITOR (user_data); editor->loop_finder_active = gtk_toggle_tool_button_get_active (button); if (editor->loop_finder_active) { /* repack the main vbox into the loop finder pane */ g_object_ref (editor->mainvbox); gtk_container_remove (GTK_CONTAINER (editor), editor->mainvbox); gtk_paned_pack2 (GTK_PANED (editor->loop_finder_pane), editor->mainvbox, TRUE, TRUE); g_object_unref (editor->mainvbox); /* pack the loop finder pane into the editor widget */ gtk_box_pack_start (GTK_BOX (editor), editor->loop_finder_pane, TRUE, TRUE, 0); } else { /* remove the loop finder pane from the editor widget */ gtk_container_remove (GTK_CONTAINER (editor), editor->loop_finder_pane); /* repack the main vbox into the editor */ g_object_ref (editor->mainvbox); gtk_container_remove (GTK_CONTAINER (editor->loop_finder_pane), editor->mainvbox); gtk_box_pack_start (GTK_BOX (editor), editor->mainvbox, TRUE, TRUE, 0); g_object_unref (editor->mainvbox); } /* show/hide finder markers */ swamigui_sample_editor_show_marker (editor, SWAMIGUI_SAMPLE_EDITOR_MARKER_ID_LOOP_FIND_START, editor->loop_finder_active); swamigui_sample_editor_show_marker (editor, SWAMIGUI_SAMPLE_EDITOR_MARKER_ID_LOOP_FIND_END, editor->loop_finder_active); } /* size-allocate callback to initialize hpane gutter position */ static void editor_cb_pane_size_allocate (GtkWidget *pane, GtkAllocation *allocation, gpointer user_data) { int width; /* set loop view size to 1/5 total size or 160 pixels whichever is smallest */ width = allocation->width / 5; if (width > 160) width = 160; /* disconnect the from the signal (one time only init) */ g_signal_handlers_disconnect_by_func (pane, editor_cb_pane_size_allocate, user_data); gtk_paned_set_position (GTK_PANED (pane), allocation->width - width); } static void swamigui_sample_editor_cb_canvas_size_allocate (GtkWidget *widget, GtkAllocation *allocation, gpointer user_data) { SwamiguiSampleEditor *editor = SWAMIGUI_SAMPLE_EDITOR (user_data); GnomeCanvas *canvas = GNOME_CANVAS (widget); swamigui_sample_editor_update_canvas_size (editor, canvas); } static void swamigui_sample_editor_update_sizes (SwamiguiSampleEditor *editor) { swamigui_sample_editor_update_canvas_size (editor, editor->sample_canvas); swamigui_sample_editor_update_canvas_size (editor, editor->loop_canvas); } static void swamigui_sample_editor_update_canvas_size (SwamiguiSampleEditor *editor, GnomeCanvas *canvas) { TrackInfo *track_info; GnomeCanvasItem *item; int width, height, sample_height, count, y, y2, i; double zoom, fullzoom; GList *p; width = GTK_WIDGET (canvas)->allocation.width; height = GTK_WIDGET (canvas)->allocation.height; sample_height = height - editor->marker_bar_height; if (width <= 0) width = 1; if (height <= 0) height = 1; if (sample_height <= 0) sample_height = 1; /* update marker bar border line */ item = canvas == editor->sample_canvas ? editor->sample_border_line : editor->loop_border_line; swamigui_util_canvas_line_set (item, 0, editor->marker_bar_height - 1, width, editor->marker_bar_height - 1); p = editor->tracks; if (!p) return; /* get count and last track in list */ count = 1; while (p->next) { p = g_list_next (p); count++; } /* if sample canvas, calculate full sample zoom and use it if current zoom * would cause complete sample view to be less than the canvas width */ if (canvas == editor->sample_canvas) { fullzoom = (double)(editor->sample_size) / width; track_info = (TrackInfo *)(p->data); g_object_get (track_info->sample_view, "zoom", &zoom, NULL); } /* loop in reverse over list (top sample down) */ for (i = 1, y = editor->marker_bar_height; p; p = g_list_previous (p), i++) { y2 = i * sample_height / count + editor->marker_bar_height; track_info = (TrackInfo *)(p->data); /* update data view */ item = (canvas == editor->sample_canvas) ? track_info->sample_view : track_info->loop_view; g_object_set (item, "y", y, "width", width, "height", y2 - y, NULL); /* set zoom value if current sample zoom would be less than canvas width, * or zoom_all is currently set */ if (canvas == editor->sample_canvas && (editor->zoom_all || fullzoom < zoom)) g_object_set (item, "zoom", fullzoom, NULL); /* update horizontal center line */ item = (canvas == editor->sample_canvas) ? track_info->sample_center_line : track_info->loop_center_line; swamigui_util_canvas_line_set (item, 0, y + (y2 - y) / 2, width - 1, y + (y2 - y) / 2); y = y2 + 1; } if (canvas == editor->sample_canvas) marker_control_update_all (editor); /* update all markers */ else if (canvas == editor->loop_canvas) swamigui_util_canvas_line_set (editor->loop_line, width / 2, 0, width / 2, height); } /* horizontal scroll bar value changed callback */ static void swamigui_sample_editor_cb_scroll (GtkAdjustment *adj, gpointer user_data) { SwamiguiSampleEditor *editor = SWAMIGUI_SAMPLE_EDITOR (user_data); marker_control_update_all (editor); /* update all markers */ } static gboolean swamigui_sample_editor_cb_sample_canvas_event (GnomeCanvas *canvas, GdkEvent *event, gpointer data) { SwamiguiSampleEditor *editor = SWAMIGUI_SAMPLE_EDITOR (data); SwamiguiSampleCanvas *sample_view; TrackInfo *track_info; MarkerInfo *marker_info; GdkEventButton *btn_event; GdkEventMotion *motion_event; GdkCursor *cursor; int val; guint newstart, newend; gboolean onbox; if (!editor->tracks) return (FALSE); track_info = (TrackInfo *)(editor->tracks->data); sample_view = SWAMIGUI_SAMPLE_CANVAS (track_info->sample_view); if (event->type == GDK_BUTTON_PRESS) btn_event = (GdkEventButton *)event; /* don't process zoom/scroll mod events if its a middle marker click */ if (event->type != GDK_BUTTON_PRESS || btn_event->button != 2 || btn_event->y > editor->marker_bar_height) { /* handle zoom/scroll related events */ if (swamigui_canvas_mod_handle_event (editor->sample_mod, event)) return (FALSE); /* was zoom/scroll event - return */ } switch (event->type) { case GDK_MOTION_NOTIFY: motion_event = (GdkEventMotion *)event; if (editor->sel_marker != -1) /* active marker? */ { marker_info = g_list_nth_data (editor->markers, editor->sel_marker); if (!marker_info) break; val = swamigui_sample_canvas_xpos_to_sample (sample_view, motion_event->x, NULL); newstart = marker_info->start_pos; newend = marker_info->end_pos; if (editor->sel_marker_edge == -1) /* start edge selected? */ newstart = CLAMP (val, 0, (int)editor->sample_size); else if (editor->sel_marker_edge == 1) /* end edge selected? */ newend = CLAMP (val, 0, (int)editor->sample_size); else /* range move (both edges selected) */ { val -= editor->move_range_ofs; newstart = CLAMP (val, 0, (int)(editor->sample_size - (newend - newstart))); newend += newstart - marker_info->start_pos; } /* swap selection if endpoints in reverse order */ if (newstart > newend) editor->sel_marker_edge = -editor->sel_marker_edge; /* set the marker */ swamigui_sample_editor_set_marker_info (editor, marker_info, newstart, newend); break; } else if (editor->sel_state != SEL_INACTIVE) /* if drag sel not inactive.. */ { val = swamigui_sample_canvas_xpos_to_sample (sample_view, motion_event->x, NULL); val = CLAMP (val, 0, editor->sample_size); /* get selection marker info */ marker_info = g_list_nth_data (editor->markers, 0); if (editor->sel_state == SEL_MAYBE) /* drag just begun? */ { if (val == editor->sel_temp) break; /* drag position not changed? */ /* just assume end drag, swap below if needed */ editor->sel_state = SEL_END; newstart = editor->sel_temp; newend = val; } else if (editor->sel_state == SEL_START) { newstart = val; newend = marker_info->end_pos; } else { newstart = marker_info->start_pos; newend = val; } if (newstart > newend) /* swap start/end if needed */ editor->sel_state = editor->sel_state == SEL_START ? SEL_END : SEL_START; /* set selection marker - start/end swapped in function if needed */ /* Disabled until sample editing operations implemented */ #if 0 swamigui_sample_editor_show_marker (editor, 0, TRUE); #endif swamigui_sample_editor_set_marker (editor, 0, newstart, newend); } else /* no marker sel or range sel active - mouse cursor over marker? */ { /* see if mouse is over a marker */ marker_info = pos_is_marker (editor, motion_event->x, motion_event->y, NULL, &onbox); /* see if cursor should be changed */ if (!onbox && (marker_info != NULL) != editor->marker_cursor) { if (marker_info) cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW); /* ++ ref */ else cursor = gdk_cursor_new (GDK_LEFT_PTR); gdk_window_set_cursor (GTK_WIDGET (editor->sample_canvas)->window, cursor); gdk_cursor_unref (cursor); editor->marker_cursor = marker_info != NULL; } } break; case GDK_BUTTON_PRESS: btn_event = (GdkEventButton *)event; if (btn_event->button == 2) /* middle click moves marker ranges */ { marker_info = pos_is_marker (editor, btn_event->x, btn_event->y, NULL, &onbox); if (marker_info && onbox) /* if click on a range box.. */ { editor->sel_marker = g_list_index (editor->markers, marker_info); editor->sel_marker_edge = 0; /* calculate offset in samples from range start to click pos */ val = swamigui_sample_canvas_xpos_to_sample (sample_view, btn_event->x, NULL); editor->move_range_ofs = val - marker_info->start_pos; } break; } /* make sure its button 1 */ if (btn_event->button != 1) break; /* is it a marker click? */ marker_info = pos_is_marker (editor, btn_event->x, btn_event->y, &editor->sel_marker_edge, NULL); if (marker_info) { editor->sel_marker = g_list_index (editor->markers, marker_info); break; } /* get sample position of click and assign to sel_temp */ editor->sel_temp = swamigui_sample_canvas_xpos_to_sample (sample_view, btn_event->x, NULL); /* if click is within the sample, we have a potential selection */ if (editor->sel_temp >= 0 && editor->sel_temp < editor->sample_size) editor->sel_state = SEL_MAYBE; break; case GDK_BUTTON_RELEASE: btn_event = (GdkEventButton *)event; if (btn_event->button == 1) { editor->sel_marker = -1; editor->sel_state = SEL_INACTIVE; } else if (btn_event->button == 2) editor->sel_marker = -1; break; default: break; } return (FALSE); } static gboolean swamigui_sample_editor_cb_loop_canvas_event (GnomeCanvas *canvas, GdkEvent *event, gpointer data) { SwamiguiSampleEditor *editor = SWAMIGUI_SAMPLE_EDITOR (data); /* handle zoom/scroll related events */ swamigui_canvas_mod_handle_event (editor->loop_mod, event); return (FALSE); /* was zoom/scroll event - return */ } /* check if a given xpos is on a marker */ static MarkerInfo * pos_is_marker (SwamiguiSampleEditor *editor, int xpos, int ypos, int *marker_edge, gboolean *is_onbox) { MarkerInfo *marker_info, *match = NULL; gboolean match_marker_edge = -1; SwamiguiSampleCanvas *sample_view; GnomeCanvasItem *item; int x, ofs = -1; int inview, onsample, pos; int startdiff, enddiff; GList *p; if (is_onbox) *is_onbox = FALSE; if (marker_edge) *marker_edge = -1; if (!editor->markers || !editor->tracks) return (NULL); sample_view = SWAMIGUI_SAMPLE_CANVAS (((TrackInfo *)(editor->tracks->data))->sample_view); /* click in marker bar area? */ if (ypos <= editor->marker_bar_height) { /* retrieve canvas item at the given coordinates */ item = gnome_canvas_get_item_at (editor->sample_canvas, xpos, ypos); if (!item) return (NULL); for (p = editor->markers; p; p = p->next) { marker_info = (MarkerInfo *)(p->data); if (marker_info->range_box == item) /* range box matches? */ { if (marker_edge) { pos = swamigui_sample_canvas_xpos_to_sample (sample_view, xpos, &onsample); startdiff = marker_info->start_pos - pos; enddiff = marker_info->end_pos - pos; if (ABS (startdiff) <= ABS (enddiff)) *marker_edge = -1; else *marker_edge = 1; } if (is_onbox) *is_onbox = TRUE; return (marker_info); } } return (NULL); } /* click not in marker bar area */ for (p = editor->markers; p; p = p->next) { marker_info = (MarkerInfo *)(p->data); x = swamigui_sample_canvas_sample_to_xpos (sample_view, marker_info->start_pos, &inview); if (inview == 0) { x = ABS (xpos - x); if (x <= MARKER_CLICK_DISTANCE && (ofs == -1 || x < ofs)) { match = marker_info; match_marker_edge = -1; ofs = x; } } x = swamigui_sample_canvas_sample_to_xpos (sample_view, marker_info->end_pos, &inview); if (inview == 0) { x = ABS (xpos - x); if (x <= MARKER_CLICK_DISTANCE && (ofs == -1 || x < ofs)) { match = marker_info; match_marker_edge = 1; ofs = x; } } } if (marker_edge) *marker_edge = match_marker_edge; if (is_onbox) *is_onbox = FALSE; return (match); } /* canvas zoom/scroll modulator update signal handler */ static void swamigui_sample_editor_sample_mod_update (SwamiguiCanvasMod *mod, double xzoom, double yzoom, double xscroll, double yscroll, double xpos, double ypos, gpointer user_data) { SwamiguiSampleEditor *editor = SWAMIGUI_SAMPLE_EDITOR (user_data); GnomeCanvasItem *sample_view; double zoom; int val; if (!editor->tracks) return; if (xzoom != 1.0) swamigui_sample_editor_zoom_ofs (editor, xzoom, xpos); if (xscroll != 0.0) { /* get first sample view item */ sample_view = ((TrackInfo *)(editor->tracks->data))->sample_view; /* get zoom from first sample canvas (samples/pixel) */ g_object_get (sample_view, "zoom", &zoom, NULL); xscroll *= zoom; /* convert from scroll pixels/sec to samples/sec */ /* do accumulation of scroll value, since we can only scroll by samples */ editor->scroll_acc += xscroll; if (editor->scroll_acc >= 1.0) val = editor->scroll_acc; else if (editor->scroll_acc <= -1.0) val = -(int)(-editor->scroll_acc); else val = 0; if (val != 0) { editor->scroll_acc -= val; swamigui_sample_editor_scroll_ofs (editor, val); } } /* no support for Y zoom/scroll yet */ } /* canvas zoom/scroll modulator snap signal handler */ static void swamigui_sample_editor_sample_mod_snap (SwamiguiCanvasMod *mod, guint actions, double xsnap, double ysnap, gpointer user_data) { SwamiguiSampleEditor *editor = SWAMIGUI_SAMPLE_EDITOR (user_data); int height, width; width = GTK_WIDGET (editor->sample_canvas)->allocation.width; height = GTK_WIDGET (editor->sample_canvas)->allocation.height; if (actions & (SWAMIGUI_CANVAS_MOD_ZOOM_X | SWAMIGUI_CANVAS_MOD_SCROLL_X)) { swamigui_util_canvas_line_set (editor->xsnap_line, xsnap, editor->marker_bar_height, xsnap, height); gnome_canvas_item_show (editor->xsnap_line); editor->scroll_acc = 0.0; } else gnome_canvas_item_hide (editor->xsnap_line); if (actions & (SWAMIGUI_CANVAS_MOD_ZOOM_Y | SWAMIGUI_CANVAS_MOD_SCROLL_Y)) { swamigui_util_canvas_line_set (editor->ysnap_line, 0, ysnap, width, ysnap); gnome_canvas_item_show (editor->ysnap_line); } else gnome_canvas_item_hide (editor->ysnap_line); } /* loop canvas zoom modulator update signal handler (scrolling does not apply) */ static void swamigui_sample_editor_loop_mod_update (SwamiguiCanvasMod *mod, double xzoom, double yzoom, double xscroll, double yscroll, double xpos, double ypos, gpointer user_data) { SwamiguiSampleEditor *editor = SWAMIGUI_SAMPLE_EDITOR (user_data); if (xzoom != 1.0) swamigui_sample_editor_loop_zoom (editor, xzoom); /* no support for Y zoom yet */ } /* loop canvas zoom modulator snap signal handler */ static void swamigui_sample_editor_loop_mod_snap (SwamiguiCanvasMod *mod, guint actions, double xsnap, double ysnap, gpointer user_data) { SwamiguiSampleEditor *editor = SWAMIGUI_SAMPLE_EDITOR (user_data); int height; height = GTK_WIDGET (editor->sample_canvas)->allocation.height; if (actions & SWAMIGUI_CANVAS_MOD_ZOOM_X) { swamigui_util_canvas_line_set (editor->loop_snap_line, xsnap, editor->marker_bar_height, xsnap, height); gnome_canvas_item_show (editor->loop_snap_line); } else gnome_canvas_item_hide (editor->loop_snap_line); } /** * swamigui_sample_editor_new: * * Create a new sample view object * * Returns: new widget of type SwamiguiSampleEditor */ GtkWidget * swamigui_sample_editor_new (void) { return (GTK_WIDGET (gtk_type_new (swamigui_sample_editor_get_type ()))); } /** * swamigui_sample_editor_zoom_ofs: * @editor: Sample editor object * @zoom_amt: Zoom multiplier (> 1 = zoom in, < 1 = zoom out) * @zoom_xpos: X coordinate position to keep stationary * * Zoom the sample canvas the specified scale amount and modify the * start sample position to keep the given X coordinate stationary. */ void swamigui_sample_editor_zoom_ofs (SwamiguiSampleEditor *editor, double zoom_amt, double zoom_xpos) { GnomeCanvasItem *sample_view; TrackInfo *track_info; double zoom, newzoom, sample_ofs; guint start, newstart; int width; GList *p; g_return_if_fail (SWAMIGUI_IS_SAMPLE_EDITOR (editor)); if (!editor->tracks) return; /* get first sample view item */ sample_view = ((TrackInfo *)(editor->tracks->data))->sample_view; /* get values from first sample in editor */ g_object_get (sample_view, "zoom", &zoom, "start", &start, "width", &width, NULL); sample_ofs = zoom_xpos * zoom; /* offset, in samples, to zoom xpos */ newzoom = zoom * (1.0 / zoom_amt); newstart = start; editor->zoom_all = FALSE; /* do some bounds checking on the zoom value */ if (newzoom < SAMPLE_CANVAS_MIN_ZOOM) newzoom = SAMPLE_CANVAS_MIN_ZOOM; else if (width * newzoom > editor->sample_size) { /* view exceeds sample data */ newstart = 0; newzoom = editor->sample_size / (double)width; editor->zoom_all = TRUE; } else { sample_ofs -= zoom_xpos * newzoom; /* subtract new zoom offset */ if (sample_ofs < 0.0 && -sample_ofs > newstart) newstart = 0; else newstart += (sample_ofs + 0.5); /* make sure sample doesn't end in the middle of the display */ if (newstart + width * newzoom > editor->sample_size) newstart = editor->sample_size - width * newzoom; } if (newzoom == zoom && newstart == start) return; p = editor->tracks; while (p) { track_info = (TrackInfo *)(p->data); g_object_set (track_info->sample_view, "zoom", newzoom, "start", newstart, NULL); p = g_list_next (p); } } /** * swamigui_sample_editor_scroll_ofs: * @editor: Sample editor object * @sample_ofs: Offset amount in samples * * Scroll the sample canvas by a given offset. */ void swamigui_sample_editor_scroll_ofs (SwamiguiSampleEditor *editor, int sample_ofs) { GnomeCanvasItem *sample_view; double zoom; guint start_sample; int newstart, width; int last_sample; g_return_if_fail (SWAMIGUI_IS_SAMPLE_EDITOR (editor)); if (sample_ofs == 0) return; /* get first sample view item */ sample_view = ((TrackInfo *)(editor->tracks->data))->sample_view; g_object_get (sample_view, "start", &start_sample, "zoom", &zoom, "width", &width, NULL); last_sample = editor->sample_size - zoom * width; if (last_sample < 0) return; /* sample too small for current zoom? */ newstart = (int)start_sample + sample_ofs; newstart = CLAMP (newstart, 0, last_sample); if (newstart == start_sample) return; g_object_set (sample_view, "start", newstart, NULL); } /** * swamigui_sample_editor_loop_zoom: * @editor: Sample editor object * @zoom_amt: Zoom multiplier (> 1 = zoom in, < 1 = zoom out) * * Zoom the loop viewer canvas the specified scale amount. Zoom always occurs * around center of loop cross overlap. */ void swamigui_sample_editor_loop_zoom (SwamiguiSampleEditor *editor, double zoom_amt) { GnomeCanvasItem *loop_view; TrackInfo *track_info; double zoom, newzoom; GList *p; g_return_if_fail (SWAMIGUI_IS_SAMPLE_EDITOR (editor)); if (!editor->tracks) return; /* get first loop view item */ loop_view = ((TrackInfo *)(editor->tracks->data))->loop_view; /* get values from first sample in editor */ g_object_get (loop_view, "zoom", &zoom, NULL); newzoom = zoom * (1.0 / zoom_amt); /* do some bounds checking on the zoom value */ if (newzoom < LOOP_CANVAS_MIN_ZOOM) newzoom = LOOP_CANVAS_MIN_ZOOM; else if (newzoom > 1.0) newzoom = 1.0; if (newzoom == zoom) return; editor->loop_zoom = newzoom; p = editor->tracks; while (p) { track_info = (TrackInfo *)(p->data); g_object_set (track_info->loop_view, "zoom", newzoom, NULL); p = g_list_next (p); } } /** * swamigui_sample_editor_set_selection: * @editor: Sample editor object * @items: List of selected items or %NULL to unset selection * * Set the items of a sample editor widget. The @items list will usually * contain a single patch item that has sample data associated with it, * although sometimes multiple items will be handled as in the case of * stereo pairs. */ void swamigui_sample_editor_set_selection (SwamiguiSampleEditor *editor, IpatchList *items) { if (swamigui_sample_editor_real_set_selection (editor, items)) g_object_notify (G_OBJECT (editor), "item-selection"); } static gboolean swamigui_sample_editor_real_set_selection (SwamiguiSampleEditor *editor, IpatchList *items) { SwamiguiSampleEditorHandler hfunc; GList *p; g_return_val_if_fail (SWAMIGUI_IS_SAMPLE_EDITOR (editor), FALSE); g_return_val_if_fail (!items || IPATCH_IS_LIST (items), FALSE); if (editor->selection) g_object_unref (editor->selection); /* -- unref old */ /* if items list then duplicate it and take over the reference */ if (items) editor->selection = ipatch_list_duplicate (items); /* !! */ else editor->selection = NULL; if (editor->handler) /* active handler? */ { editor->status = SWAMIGUI_SAMPLE_EDITOR_UPDATE; if (!items || !(*editor->handler)(editor)) swamigui_sample_editor_deactivate_handler (editor); } if (items && !editor->handler) /* re-test in case it was de-activated */ { editor->status = SWAMIGUI_SAMPLE_EDITOR_INIT; p = sample_editor_handlers; while (p) /* try handlers */ { hfunc = (SwamiguiSampleEditorHandler)(p->data); if ((*hfunc)(editor)) /* selection handled? */ { editor->handler = hfunc; break; } p = g_list_next (p); } } editor->status = SWAMIGUI_SAMPLE_EDITOR_NORMAL; return (TRUE); } static void swamigui_sample_editor_deactivate_handler (SwamiguiSampleEditor *editor) { swamigui_sample_editor_reset (editor); editor->handler = NULL; editor->handler_data = NULL; } /** * swamigui_sample_editor_get_selection: * @editor: Sample editor widget * * Get the list of active items in a sample editor widget. * * Returns: New list containing selected items which has a ref count of one * which the caller owns or %NULL if no items selected. Remove the * reference when finished with it. */ IpatchList * swamigui_sample_editor_get_selection (SwamiguiSampleEditor *editor) { g_return_val_if_fail (SWAMIGUI_IS_SAMPLE_EDITOR (editor), NULL); if (editor->selection && editor->selection->items) return (ipatch_list_duplicate (editor->selection)); else return (NULL); } /** * swamigui_sample_editor_register_handler: * @handler: Sample editor handler function to register * @check_func: Function used to check if an item selection is valid for this handler * * Registers a new handler for sample editor widgets. Sample editor handlers * interface patch item's of particular types with sample data and related * parameters (such as looping params). * * MT: This function should only be called within GUI thread. */ void swamigui_sample_editor_register_handler (SwamiguiSampleEditorHandler handler, SwamiguiPanelCheckFunc check_func) { g_return_if_fail (handler != NULL); g_return_if_fail (check_func != NULL); sample_editor_handlers = g_list_prepend (sample_editor_handlers, handler); sample_editor_check_funcs = g_list_prepend (sample_editor_check_funcs, check_func); } /** * swamigui_sample_editor_unregister_handler: * @handler: Handler function to unregister * * Unregisters a handler previously registered with * swamigui_sample_editor_register_handler(). * * MT: This function should only be called in GUI thread. */ void swamigui_sample_editor_unregister_handler (SwamiguiSampleEditorHandler handler) { int handler_index; GList *p; g_return_if_fail (handler != NULL); handler_index = g_list_index (sample_editor_handlers, handler); g_return_if_fail (handler_index != -1); sample_editor_handlers = g_list_remove (sample_editor_handlers, handler); /* remove the corresponding check function */ p = g_list_nth (sample_editor_check_funcs, handler_index); sample_editor_check_funcs = g_list_delete_link (sample_editor_check_funcs, p); } /** * swamigui_sample_editor_reset: * @editor: Sample editor widget * * Resets a sample editor by removing all tracks and markers and disconnecting * loop view controls. Usually only used by sample editor handlers. */ void swamigui_sample_editor_reset (SwamiguiSampleEditor *editor) { g_return_if_fail (SWAMIGUI_IS_SAMPLE_EDITOR (editor)); g_object_set (editor->loop_finder_gui->loop_finder, "sample", NULL, NULL); swamigui_sample_editor_remove_all_tracks (editor); swamigui_sample_editor_remove_all_markers (editor); /* disable loop type selector */ swamigui_sample_editor_set_loop_types (editor, NULL, FALSE); /* disconnect any controls connected to loop view hub controls */ swami_control_disconnect_all (editor->loop_start_hub); swami_control_disconnect_all (editor->loop_end_hub); swami_control_disconnect_all (editor->loopsel_ctrl); /* disconnect any controls to spin buttons */ swami_control_disconnect_all (editor->spinbtn_start_ctrl); swami_control_disconnect_all (editor->spinbtn_end_ctrl); } /** * swamigui_sample_editor_get_loop_controls: * @editor: Sample editor object * @loop_start: Output - Loop view start point control (%NULL to ignore) * @loop_end: Output - Loop view end point control (%NULL to ignore) * * Get the loop start and end controls that are connected to all loop view * start and end properties. Essentially controls for the loop view start * and end points. */ void swamigui_sample_editor_get_loop_controls (SwamiguiSampleEditor *editor, SwamiControl **loop_start, SwamiControl **loop_end) { g_return_if_fail (SWAMIGUI_IS_SAMPLE_EDITOR (editor)); if (loop_start) *loop_start = editor->loop_start_hub; if (loop_end) *loop_end = editor->loop_end_hub; } /** * swamigui_sample_editor_add_track: * @editor: Sample editor object * @sample: Object with an #IpatchSample interface to add * @right_chan: Only used if @sample is stereo. If %TRUE the right channel * will be used, %FALSE will use the left channel. * * Add a sample track to a sample editor. Usually only done by * sample editor handlers. This function can be used to add multiple * samples for stereo or multi-track audio. * * Returns: The index of the new track in the sample editor object (starting * from 0). */ int swamigui_sample_editor_add_track (SwamiguiSampleEditor *editor, IpatchSampleData *sample, gboolean right_chan) { TrackInfo *track_info; SwamiControl *ctrl; double zoom; guint sample_size; int width; g_return_val_if_fail (SWAMIGUI_IS_SAMPLE_EDITOR (editor), 0); g_return_val_if_fail (IPATCH_IS_SAMPLE_DATA (sample), 0); /* calculate zoom to view entire sample */ g_object_get (sample, "sample-size", &sample_size, NULL); width = GTK_WIDGET (editor->sample_canvas)->allocation.width; zoom = (double)sample_size / width; if (!editor->tracks) /* if no samples have been added yet */ editor->sample_size = sample_size; /* cache sample size */ track_info = g_new (TrackInfo, 1); track_info->sample = g_object_ref (sample); /* ++ ref sample */ track_info->right_chan = right_chan; /* create sample view horizontal center line */ track_info->sample_center_line = gnome_canvas_item_new (gnome_canvas_root (editor->sample_canvas), GNOME_TYPE_CANVAS_LINE, "fill-color-rgba", editor->center_line_color, "width-pixels", 1, NULL); track_info->sample_view = /* create the sample view canvas item */ gnome_canvas_item_new (gnome_canvas_root (editor->sample_canvas), SWAMIGUI_TYPE_SAMPLE_CANVAS, "sample", sample, "right-chan", right_chan, "zoom", zoom, /* only the first sample item will update adj. */ "update-adj", editor->tracks ? FALSE : TRUE, "adjustment", gtk_range_get_adjustment (GTK_RANGE (editor->hscrollbar)), NULL); /* create loop view horizontal center line */ track_info->loop_center_line = gnome_canvas_item_new (gnome_canvas_root (editor->loop_canvas), GNOME_TYPE_CANVAS_LINE, "fill-color-rgba", editor->center_line_color, "width-pixels", 1, NULL); track_info->loop_view = /* create the loop view canvas item */ gnome_canvas_item_new (gnome_canvas_root (editor->loop_canvas), SWAMIGUI_TYPE_SAMPLE_CANVAS, "sample", sample, "right-chan", right_chan, "loop-mode", TRUE, "zoom", editor->loop_zoom, NULL); gnome_canvas_item_lower_to_bottom (track_info->sample_center_line); gnome_canvas_item_lower_to_bottom (track_info->loop_center_line); gnome_canvas_item_lower_to_bottom (track_info->sample_view); gnome_canvas_item_lower_to_bottom (track_info->loop_view); gnome_canvas_item_lower_to_bottom (editor->loop_line); /* add track to track list */ editor->tracks = g_list_append (editor->tracks, track_info); /* create loop view "loop-start" property control and connect to hub */ ctrl = SWAMI_CONTROL (swami_get_control_prop_by_name /* ++ ref */ (G_OBJECT (track_info->loop_view), "loop-start")); swami_control_connect (editor->loop_start_hub, ctrl, 0); /* hub is queued */ g_object_unref (ctrl); /* -- unref */ /* create loop view "loop-end" property control and connect to hub */ ctrl = SWAMI_CONTROL (swami_get_control_prop_by_name /* ++ ref */ (G_OBJECT (track_info->loop_view), "loop-end")); swami_control_connect (editor->loop_end_hub, ctrl, 0); /* hub is queued */ g_object_unref (ctrl); /* -- unref */ swamigui_sample_editor_update_sizes (editor); return (g_list_length (editor->tracks) - 1); } /** * swamigui_sample_editor_get_track_info: * @editor: Sample editor object * @track: Track index to get info from (starting from 0) * @sample: Output - Sample object (%NULL to ignore) * @sample_view: Output - The sample view canvas (%NULL to ignore) * @loop_view: Output - The loop view canvas (%NULL to ignore) * * Get info for a sample track. No reference counting is done, since * track will not get removed unless the sample editor handler does * so. Returned object pointers should only be used within editor * callback or references should be added. * * Returns: %TRUE if @index is a valid sample index, %FALSE otherwise in * which case the returned pointers are undefined. */ gboolean swamigui_sample_editor_get_track_info (SwamiguiSampleEditor *editor, guint track, IpatchSampleData **sample, SwamiguiSampleCanvas **sample_view, SwamiguiSampleCanvas **loop_view) { TrackInfo *track_info; g_return_val_if_fail (SWAMIGUI_IS_SAMPLE_EDITOR (editor), FALSE); track_info = (TrackInfo *)g_list_nth_data (editor->tracks, track); if (!track_info) return (FALSE); if (sample) *sample = track_info->sample; if (sample_view) *sample_view = SWAMIGUI_SAMPLE_CANVAS (track_info->sample_view); if (loop_view) *loop_view = SWAMIGUI_SAMPLE_CANVAS (track_info->loop_view); return (TRUE); } /** * swamigui_sample_editor_remove_track: * @editor: Sample editor object * @track: Index of track to remove * * Remove a track from a sample editor by its index (starts from 0). */ void swamigui_sample_editor_remove_track (SwamiguiSampleEditor *editor, guint track) { GList *found_track; g_return_if_fail (SWAMIGUI_IS_SAMPLE_EDITOR (editor)); found_track = g_list_nth (editor->tracks, track); g_return_if_fail (found_track != NULL); swamigui_sample_editor_remove_track_item (editor, found_track, TRUE); swamigui_sample_editor_update_sizes (editor); } /* internal function for removing by track info list node, destroy flag is used by finalize (set to FALSE since no need to destroy GtkObjects) */ static void swamigui_sample_editor_remove_track_item (SwamiguiSampleEditor *editor, GList *p, gboolean destroy) { TrackInfo *track_info; track_info = (TrackInfo *)(p->data); g_object_unref (track_info->sample); /* -- unref sample */ if (destroy) { /* destroy sample canvas items */ gtk_object_destroy (GTK_OBJECT (track_info->sample_view)); gtk_object_destroy (GTK_OBJECT (track_info->loop_view)); /* destroy horizontal center lines */ gtk_object_destroy (GTK_OBJECT (track_info->sample_center_line)); gtk_object_destroy (GTK_OBJECT (track_info->loop_center_line)); } g_free (track_info); /* if removing the first track and there are others.. */ if (p == editor->tracks && editor->tracks->next) { track_info = (TrackInfo *)(editor->tracks->next->data); /* the new first sample canvas item now is adjustment master */ g_object_set (track_info->sample_view, "update-adj", TRUE, NULL); } /* remove from list */ editor->tracks = g_list_delete_link (editor->tracks, p); } /** * swamigui_sample_editor_remove_all_tracks: * @editor: Sample editor object * * Remove all tracks from a sample editor. */ void swamigui_sample_editor_remove_all_tracks (SwamiguiSampleEditor *editor) { GList *p, *temp; g_return_if_fail (SWAMIGUI_IS_SAMPLE_EDITOR (editor)); p = editor->tracks; while (p) { temp = p; p = g_list_next (p); swamigui_sample_editor_remove_track_item (editor, temp, TRUE); } } /** * swamigui_sample_editor_add_marker: * @editor: Sample editor object * @flags: #SwamiguiSampleEditorMarkerFlags * - #SWAMIGUI_SAMPLE_EDITOR_MARKER_SINGLE is used for markers which define * a single value. * - #SWAMIGUI_SAMPLE_EDITOR_MARKER_VIEW is used for markers which are view * only and not controllable by user. * - #SWAMIGUI_SAMPLE_EDITOR_MARKER_SIZE is used to define a start/size * marker instead of a start/end marker. This causes the second control to * be the current size of the marker instead of the end position. * Note that passing 0 defines a interactive range marker. * @start: Output - New control for start of marker or %NULL to ignore * @end: Output - New control for end/size of marker (ranges only) or %NULL to * ignore * * Add a new marker to a sample editor. Markers can be used for loop points, * sample start/end points, selections and other position indicators/controls. * Marker 0 is the sample selection marker and it is always present although it * may be hidden. * * Returns: New marker index */ guint swamigui_sample_editor_add_marker (SwamiguiSampleEditor *editor, guint flags, SwamiControl **start, SwamiControl **end) { MarkerInfo *mark_info; guint color; int id; g_return_val_if_fail (SWAMIGUI_IS_SAMPLE_EDITOR (editor), 0); mark_info = g_new0 (MarkerInfo, 1); mark_info->flags = flags; mark_info->editor = editor; mark_info->visible = TRUE; id = g_list_length (editor->markers); color = default_marker_colors [id % G_N_ELEMENTS (default_marker_colors)]; mark_info->start_line = gnome_canvas_item_new (gnome_canvas_root (editor->sample_canvas), GNOME_TYPE_CANVAS_LINE, "fill-color-rgba", color, "width-pixels", MARKER_DEFAULT_WIDTH, NULL); gnome_canvas_item_hide (mark_info->start_line); /* create start marker control (!! editor takes over ref) */ mark_info->start_ctrl = swamigui_control_new (SWAMI_TYPE_CONTROL_FUNC); swami_control_set_value_type (mark_info->start_ctrl, G_TYPE_UINT); swami_control_func_assign_funcs (SWAMI_CONTROL_FUNC (mark_info->start_ctrl), start_marker_control_get_value_func, start_marker_control_set_value_func, NULL, mark_info); /* create end line and range box if a range marker */ if (!(flags & SWAMIGUI_SAMPLE_EDITOR_MARKER_SINGLE)) { mark_info->end_line = gnome_canvas_item_new (gnome_canvas_root (editor->sample_canvas), GNOME_TYPE_CANVAS_LINE, "fill-color-rgba", color, "width-pixels", MARKER_DEFAULT_WIDTH, NULL); gnome_canvas_item_hide (mark_info->end_line); mark_info->range_box = gnome_canvas_item_new (gnome_canvas_root (editor->sample_canvas), GNOME_TYPE_CANVAS_RECT, "fill-color-rgba", color, NULL); gnome_canvas_item_hide (mark_info->range_box); /* create end/size marker control (!! editor takes over ref) */ mark_info->end_ctrl = swamigui_control_new (SWAMI_TYPE_CONTROL_FUNC); swami_control_set_value_type (mark_info->end_ctrl, G_TYPE_UINT); swami_control_func_assign_funcs (SWAMI_CONTROL_FUNC (mark_info->end_ctrl), end_marker_control_get_value_func, end_marker_control_set_value_func, NULL, mark_info); } editor->markers = g_list_append (editor->markers, mark_info); marker_control_update_all (editor); if (start) *start = mark_info->start_ctrl; if (end) *end = mark_info->end_ctrl; return (id); } /** * swamigui_sample_editor_get_marker_info: * @editor: Sample editor object * @marker: Marker index to get info on (starts at 0 - the selection marker) * @flags: #SwamiguiSampleEditorMarkerFlags * @start_line: Output - Gnome canvas line for the start marker (%NULL to ignore) * @end_line: Output - Gnome canvas line for the end marker (%NULL to ignore), * will be %NULL for single markers (non ranges) * @start_ctrl: Output - Control for the start marker (%NULL to ignore) * @end_ctrl: Output - Control for the end/size marker (%NULL to ignore), will be * %NULL for single markers (non ranges) * * Get info for the given @marker index. No reference counting is * done, since marker will not get removed unless the sample editor * handler does so. Returned object pointers should only be used * within editor callback or references should be added. * * Returns: %TRUE if a marker with the given index exists, %FALSE otherwise. */ gboolean swamigui_sample_editor_get_marker_info (SwamiguiSampleEditor *editor, guint marker, guint *flags, GnomeCanvasItem **start_line, GnomeCanvasItem **end_line, SwamiControl **start_ctrl, SwamiControl **end_ctrl) { MarkerInfo *marker_info; g_return_val_if_fail (SWAMIGUI_IS_SAMPLE_EDITOR (editor), FALSE); marker_info = (MarkerInfo *)g_list_nth_data (editor->markers, marker); if (!marker_info) return (FALSE); if (flags) *flags = marker_info->flags; if (start_line) *start_line = marker_info->start_line; if (end_line) *end_line = marker_info->end_line; if (start_ctrl) *start_ctrl = marker_info->start_ctrl; if (end_ctrl) *end_ctrl = marker_info->end_ctrl; return (TRUE); } /** * swamigui_sample_editor_set_marker: * @editor: Sample editor widget * @marker: Marker number * @start: Marker start position * @end: Marker end position * * Set the marker start and end positions. */ void swamigui_sample_editor_set_marker (SwamiguiSampleEditor *editor, guint marker, guint start, guint end) { MarkerInfo *marker_info; g_return_if_fail (SWAMIGUI_IS_SAMPLE_EDITOR (editor)); marker_info = (MarkerInfo *)g_list_nth_data (editor->markers, marker); if (!marker_info) return; swamigui_sample_editor_set_marker_info (editor, marker_info, start, end); } static void swamigui_sample_editor_set_marker_info (SwamiguiSampleEditor *editor, MarkerInfo *marker_info, guint start, guint end) { GValue value = { 0 }; gboolean size_marker; gboolean start_changed = FALSE; guint temp; if (start > end) /* swap if backwards */ { temp = start; start = end; end = temp; } size_marker = (marker_info->flags & SWAMIGUI_SAMPLE_EDITOR_MARKER_SIZE) != 0; g_value_init (&value, G_TYPE_UINT); if (start != marker_info->start_pos) { marker_info->start_pos = start; g_value_set_uint (&value, start); swami_control_transmit_value (marker_info->start_ctrl, &value); start_changed = TRUE; } if (end != marker_info->end_pos || (size_marker && start_changed)) { marker_info->end_pos = end; if (size_marker) g_value_set_uint (&value, end - start + 1); else g_value_set_uint (&value, end); swami_control_transmit_value (marker_info->end_ctrl, &value); } g_value_unset (&value); marker_control_update (marker_info); /* update the marker GUI */ } /** * swamigui_sample_editor_remove_marker: * @editor: Sample editor object * @marker: Index of marker to remove (builtin markers are hidden rather than * removed) * * Remove a marker. */ void swamigui_sample_editor_remove_marker (SwamiguiSampleEditor *editor, guint marker) { GList *p; g_return_if_fail (SWAMIGUI_IS_SAMPLE_EDITOR (editor)); if (marker < BUILTIN_MARKER_COUNT) { swamigui_sample_editor_show_marker (editor, marker, FALSE); return; } p = g_list_nth (editor->markers, marker); if (!p) return; swamigui_sample_editor_remove_marker_item (editor, p, TRUE); } /** * swamigui_sample_editor_remove_all_markers: * @editor: Sample editor object * * Remove all markers (except selection marker 0, which is always present). */ void swamigui_sample_editor_remove_all_markers (SwamiguiSampleEditor *editor) { GList *p, *temp; int i; p = g_list_nth (editor->markers, BUILTIN_MARKER_COUNT); while (p) { temp = p; p = g_list_next (p); swamigui_sample_editor_remove_marker_item (editor, temp, TRUE); } /* hide builtin markers */ for (i = 0; i < BUILTIN_MARKER_COUNT; i++) swamigui_sample_editor_show_marker (editor, i, FALSE); } /* remove a marker, destroy flag is used by finalize function since GtkObjects dont need to be destroyed on finalize */ static void swamigui_sample_editor_remove_marker_item (SwamiguiSampleEditor *editor, GList *p, gboolean destroy) { MarkerInfo *marker_info; SwamiControl *ctrl; marker_info = (MarkerInfo *)(p->data); /* remove from marker list */ editor->markers = g_list_delete_link (editor->markers, p); /* destroy line canvas item */ if (destroy) { gtk_object_destroy (GTK_OBJECT (marker_info->start_line)); if (marker_info->end_line) gtk_object_destroy (GTK_OBJECT (marker_info->end_line)); if (marker_info->range_box) gtk_object_destroy (GTK_OBJECT (marker_info->range_box)); } /* we don't want to depend on the existence of mark_info anymore */ ctrl = marker_info->end_ctrl; /* FIXME - What about start_ctrl !!! */ /* clear data in marker info */ memset (marker_info, 0, sizeof (MarkerInfo)); /* add a week references to the marker controls to free the marker_info structures (since we still might receive queued events) */ g_object_weak_ref (G_OBJECT (ctrl), (GWeakNotify)g_free, marker_info); g_object_unref (ctrl); /* -- remove the editor's reference */ } /* start marker control get value method */ static void start_marker_control_get_value_func (SwamiControl *control, GValue *value) { MarkerInfo *marker_info = SWAMI_CONTROL_FUNC_DATA (control); g_value_set_uint (value, marker_info->start_pos); } /* start marker control set value method */ static void start_marker_control_set_value_func (SwamiControl *control, SwamiControlEvent *event, const GValue *value) { MarkerInfo *marker_info = SWAMI_CONTROL_FUNC_DATA (control); guint u; if (!marker_info->start_line) return; /* in process of being destroyed? */ u = g_value_get_uint (value); if (u != marker_info->start_pos) { marker_info->start_pos = u; marker_control_update (marker_info); } } /* end marker control get value method */ static void end_marker_control_get_value_func (SwamiControl *control, GValue *value) { MarkerInfo *marker_info = SWAMI_CONTROL_FUNC_DATA (control); if (marker_info->flags & SWAMIGUI_SAMPLE_EDITOR_MARKER_SIZE) g_value_set_uint (value, marker_info->end_pos - marker_info->start_pos + 1); else g_value_set_uint (value, marker_info->end_pos); } /* end marker control set value method */ static void end_marker_control_set_value_func (SwamiControl *control, SwamiControlEvent *event, const GValue *value) { MarkerInfo *marker_info = SWAMI_CONTROL_FUNC_DATA (control); guint u; if (!marker_info->end_line) return; /* in process of being destroyed? */ u = g_value_get_uint (value); if (marker_info->flags & SWAMIGUI_SAMPLE_EDITOR_MARKER_SIZE) u += marker_info->start_pos - 1; if (u != marker_info->end_pos && u >= marker_info->start_pos) { marker_info->end_pos = u; marker_control_update (marker_info); } } /* update the display of a single marker in the sample view */ static void marker_control_update (MarkerInfo *marker_info) { SwamiguiSampleEditor *editor = marker_info->editor; SwamiguiSampleCanvas *sample_view = NULL; TrackInfo *track_info; GnomeCanvasPoints *points; int startx, endx, sview = -1, eview = -1; int width, height; int visible_count, pos; int y1 = 0, y2 = 0; GList *p; /* can't position marker lines if no sample canvases, exception is if marker is hidden, then we don't need to update the position */ if (!editor->tracks && marker_info->visible) return; /* count number of visible markers and locate visible position of this marker */ for (p = editor->markers, visible_count = 0; p; p = p->next) { if (p->data == marker_info) pos = visible_count; if (((MarkerInfo *)(p->data))->visible) visible_count++; } pos = visible_count - pos - 1; /* adjust for Y-coord order */ if (editor->tracks) { track_info = (TrackInfo *)(editor->tracks->data); sample_view = SWAMIGUI_SAMPLE_CANVAS (track_info->sample_view); } width = GTK_WIDGET (editor->sample_canvas)->allocation.width; height = GTK_WIDGET (editor->sample_canvas)->allocation.height; /* calculate Y positions of range bar */ if (visible_count > 0) { y1 = (pos * (editor->marker_bar_height - 1)) / visible_count; y2 = ((pos+1) * (editor->marker_bar_height - 1)) / visible_count - 1; } points = gnome_canvas_points_new (2); points->coords[1] = y2; points->coords[3] = height; /* update start marker line */ if (sample_view) startx = swamigui_sample_canvas_sample_to_xpos (sample_view, marker_info->start_pos, &sview); if (sample_view && sview == 0 && marker_info->visible) { points->coords[0] = startx; points->coords[2] = startx; g_object_set (marker_info->start_line, "points", points, NULL); gnome_canvas_item_show (marker_info->start_line); } else { gnome_canvas_item_hide (marker_info->start_line); startx = 0; } /* update end marker and range box (if any) */ if (marker_info->end_line) { if (sample_view) endx = swamigui_sample_canvas_sample_to_xpos (sample_view, marker_info->end_pos, &eview); if (sample_view && eview == 0 && marker_info->visible) { points->coords[0] = endx; points->coords[2] = endx; endx++; /* for marker range_box below */ g_object_set (marker_info->end_line, "points", points, NULL); gnome_canvas_item_show (marker_info->end_line); } else { gnome_canvas_item_hide (marker_info->end_line); endx = width; } /* is marker range box in view? */ if (sample_view && (sview == 0 || eview == 0 || (sview == -1 && eview == 1)) && marker_info->visible) { g_object_set (marker_info->range_box, "x1", (double)startx, "x2", (double)endx, "y1", (double)y1, "y2", (double)y2, NULL); gnome_canvas_item_show (marker_info->range_box); } else gnome_canvas_item_hide (marker_info->range_box); } gnome_canvas_points_free (points); } static void marker_control_update_all (SwamiguiSampleEditor *editor) { MarkerInfo *marker_info; GList *p; for (p = editor->markers; p; p = g_list_next (p)) { marker_info = (MarkerInfo *)(p->data); marker_control_update (marker_info); } } /** * swamigui_sample_editor_show_marker: * @editor: Sample editor widget * @marker: Marker number to set visibility of * @show_marker: %TRUE to show marker, %FALSE to hide * * Set the visibility of a marker. */ void swamigui_sample_editor_show_marker (SwamiguiSampleEditor *editor, guint marker, gboolean show_marker) { MarkerInfo *marker_info; GList *p; g_return_if_fail (SWAMIGUI_IS_SAMPLE_EDITOR (editor)); p = g_list_nth (editor->markers, marker); if (!p) return; marker_info = (MarkerInfo *)(p->data); if (marker_info->visible == show_marker) return; marker_info->visible = show_marker; marker_control_update_all (editor); } /** * swamigui_sample_editor_set_loop_types: * @editor: Sample editor object * @types: -1 terminated array of #IpatchSampleLoopType values to show in * loop selector (%NULL to hide loop selector) * @loop_play_btn: If @types is %NULL, setting this to %TRUE will cause a * play loop toggle button to be shown (for items that dont have a loop type * property, but it is desirable for the user to be able to listen to the loop). * * Usually only used by sample editor handlers. Sets the available loop types * in the loop selector menu. */ void swamigui_sample_editor_set_loop_types (SwamiguiSampleEditor *editor, int *types, gboolean loop_play_btn) { GtkTreeIter iter; int i, i2; gtk_list_store_clear (editor->loopsel_store); if (types) { for (i = 0; i < G_N_ELEMENTS (loop_type_info); i++) { for (i2 = 0; types[i2] != -1; i2++) { if (loop_type_info[i].loop_type == types[i2]) { gtk_list_store_append (editor->loopsel_store, &iter); gtk_list_store_set (editor->loopsel_store, &iter, LOOPSEL_COL_LOOP_TYPE, types[i2], LOOPSEL_COL_ICON, loop_type_info[i].icon, LOOPSEL_COL_LABEL, loop_type_info[i].label, LOOPSEL_COL_TOOLTIP, loop_type_info[i].tooltip, -1); } } } gtk_widget_set_sensitive (editor->loopsel, TRUE); } else gtk_widget_set_sensitive (editor->loopsel, FALSE); } /** * swamigui_sample_editor_set_active_loop_type: * @editor: Sample editor widget * @type: #IpatchSampleLoopType or TRUE/FALSE if using loop play button. * * Set the active loop type in the loop type selector or loop play button. * Usually only used by sample editor handlers. */ void swamigui_sample_editor_set_active_loop_type (SwamiguiSampleEditor *editor, int type) { GtkTreeModel *model = GTK_TREE_MODEL (editor->loopsel_store); GtkTreeIter iter; int cmptype; if (!gtk_tree_model_get_iter_first (model, &iter)) return; do { gtk_tree_model_get (model, &iter, LOOPSEL_COL_LOOP_TYPE, &cmptype, -1); if (cmptype == type) { gtk_combo_box_set_active_iter (GTK_COMBO_BOX (editor->loopsel), &iter); break; } } while (gtk_tree_model_iter_next (model, &iter)); } /* Default IpatchSample interface sample editor handler */ static gboolean swamigui_sample_editor_default_handler (SwamiguiSampleEditor *editor) { IpatchSample *sample; IpatchSampleData *sampledata; SwamiControl *loop_view_start, *loop_view_end; SwamiControl *mark_loop_start, *mark_loop_end; SwamiControl *loop_start_prop, *loop_end_prop, *loop_type_prop; int *loop_types; GObject *obj; /* check if selection is handled (single item with IpatchSample interface) */ if (editor->status == SWAMIGUI_SAMPLE_EDITOR_INIT || editor->status == SWAMIGUI_SAMPLE_EDITOR_UPDATE) { /* only handle single item with IpatchSample interface */ if (!editor->selection || !editor->selection->items || editor->selection->items->next) return (FALSE); obj = editor->selection->items->data; if (!IPATCH_IS_SAMPLE (obj)) return (FALSE); sample = IPATCH_SAMPLE (obj); /* same item already selected? */ if ((gpointer)sample == (gpointer)(editor->handler_data)) return (TRUE); sampledata = ipatch_sample_get_sample_data (sample); /* ++ ref sample data */ /* clear all tracks and markers if updating and a new item is selected */ if (editor->status == SWAMIGUI_SAMPLE_EDITOR_UPDATE) swamigui_sample_editor_reset (editor); editor->handler_data = sample; /* set handler data to selected item */ /* clear loop finder results */ swamigui_loop_finder_clear_results (editor->loop_finder_gui); /* stereo sample data?? */ if (IPATCH_SAMPLE_FORMAT_GET_CHANNELS (ipatch_sample_get_format (sample)) == IPATCH_SAMPLE_STEREO) { swamigui_sample_editor_add_track (editor, sampledata, FALSE); swamigui_sample_editor_add_track (editor, sampledata, TRUE); } else /* mono data */ swamigui_sample_editor_add_track (editor, sampledata, FALSE); /* set sample of loop finder */ g_object_set (editor->loop_finder_gui->loop_finder, "sample", sample, NULL); /* create loop range marker */ swamigui_sample_editor_add_marker (editor, 0, &mark_loop_start, &mark_loop_end); /* ++ ref sample loop property controls */ loop_start_prop = swami_get_control_prop_by_name (G_OBJECT (sample), "loop-start"); loop_end_prop = swami_get_control_prop_by_name (G_OBJECT (sample), "loop-end"); /* connect sample properties to loop markers */ swami_control_connect (loop_start_prop, mark_loop_start, SWAMI_CONTROL_CONN_BIDIR | SWAMI_CONTROL_CONN_INIT); swami_control_connect (loop_end_prop, mark_loop_end, SWAMI_CONTROL_CONN_BIDIR | SWAMI_CONTROL_CONN_INIT); /* connect sample properties to spin buttons */ swami_control_connect (loop_start_prop, editor->spinbtn_start_ctrl, SWAMI_CONTROL_CONN_BIDIR | SWAMI_CONTROL_CONN_INIT); swami_control_connect (loop_end_prop, editor->spinbtn_end_ctrl, SWAMI_CONTROL_CONN_BIDIR | SWAMI_CONTROL_CONN_INIT); /* get loop view controls */ swamigui_sample_editor_get_loop_controls (editor, &loop_view_start, &loop_view_end); /* connect sample properties to loop view controls */ swami_control_connect (loop_start_prop, loop_view_start, SWAMI_CONTROL_CONN_INIT); swami_control_connect (loop_end_prop, loop_view_end, SWAMI_CONTROL_CONN_INIT); /* unref sample property controls */ g_object_unref (loop_start_prop); g_object_unref (loop_end_prop); /* set the available loop types of the loop selector */ loop_types = ipatch_sample_get_loop_types (sample); swamigui_sample_editor_set_loop_types (editor, loop_types, FALSE); if (loop_types) { /* ++ ref new prop control */ loop_type_prop = swami_get_control_prop_by_name (G_OBJECT (sample), "loop-type"); swami_control_connect (loop_type_prop, editor->loopsel_ctrl, SWAMI_CONTROL_CONN_BIDIR | SWAMI_CONTROL_CONN_INIT); g_object_unref (loop_type_prop); /* -- unref prop control */ } /* show finder markers (if finder enabled) */ if (editor->loop_finder_active) { swamigui_sample_editor_show_marker (editor, SWAMIGUI_SAMPLE_EDITOR_MARKER_ID_LOOP_FIND_START, TRUE); swamigui_sample_editor_show_marker (editor, SWAMIGUI_SAMPLE_EDITOR_MARKER_ID_LOOP_FIND_END, TRUE); } g_object_unref (sampledata); /* -- unref sample data */ } /* if INIT or UPDATE */ return (TRUE); } static gboolean swamigui_sample_editor_default_handler_check_func (IpatchList *selection, GType *selection_types) { IpatchSampleData *sampledata; /* only handle single item with IpatchSample interface which returns sample data */ if (selection->items->next || !g_type_is_a (*selection_types, IPATCH_TYPE_SAMPLE) || !(sampledata = ipatch_sample_get_sample_data /* ++ ref sample data */ ((IpatchSample *)(selection->items->data)))) return (FALSE); g_object_unref (sampledata); /* -- unref sample data */ return (TRUE); } /* get value function for loopsel_ctrl */ static void swamigui_sample_editor_loopsel_ctrl_get (SwamiControl *control, GValue *value) { SwamiguiSampleEditor *editor = SWAMIGUI_SAMPLE_EDITOR (SWAMI_CONTROL_FUNC_DATA (control)); GtkTreeIter iter; int loop_type = 0; /* get active loop type or failing that get first loop type */ if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (editor->loopsel), &iter) || gtk_tree_model_get_iter_first (GTK_TREE_MODEL (editor->loopsel_store), &iter)) { gtk_tree_model_get (GTK_TREE_MODEL (editor->loopsel_store), &iter, LOOPSEL_COL_LOOP_TYPE, &loop_type, -1); } g_value_set_enum (value, loop_type); } /* set value function for loopsel_ctrl */ static void swamigui_sample_editor_loopsel_ctrl_set (SwamiControl *control, SwamiControlEvent *event, const GValue *value) { SwamiguiSampleEditor *editor = SWAMIGUI_SAMPLE_EDITOR (SWAMI_CONTROL_FUNC_DATA (control)); int loop_type; loop_type = g_value_get_enum (value); /* block changed signal while setting the combo box selection */ g_signal_handlers_block_by_func (editor->loopsel, swamigui_sample_editor_loopsel_cb_changed, editor); swamigui_sample_editor_set_active_loop_type (editor, loop_type); g_signal_handlers_unblock_by_func (editor->loopsel, swamigui_sample_editor_loopsel_cb_changed, editor); } /* callback for when the loop selector combo box is changed */ static void swamigui_sample_editor_loopsel_cb_changed (GtkComboBox *widget, gpointer user_data) { SwamiguiSampleEditor *editor = SWAMIGUI_SAMPLE_EDITOR (user_data); GtkTreeIter iter; int loop_type; GValue value = { 0 }; if (gtk_combo_box_get_active_iter (widget, &iter)) { gtk_tree_model_get (GTK_TREE_MODEL (editor->loopsel_store), &iter, LOOPSEL_COL_LOOP_TYPE, &loop_type, -1); /* transmit the loop type change */ g_value_init (&value, G_TYPE_INT); g_value_set_int (&value, loop_type); swami_control_transmit_value ((SwamiControl *)editor->loopsel_ctrl, &value); g_value_unset (&value); } } swami/src/swamigui/SwamiguiMenu.h0000644000175000017500000000336211461334205017260 0ustar alessioalessio/* * SwamiguiMenu.h - Swami main menu object * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_MENU_H__ #define __SWAMIGUI_MENU_H__ typedef struct _SwamiguiMenu SwamiguiMenu; typedef struct _SwamiguiMenuClass SwamiguiMenuClass; #include #include "SwamiguiRoot.h" #define SWAMIGUI_TYPE_MENU (swamigui_menu_get_type ()) #define SWAMIGUI_MENU(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMIGUI_TYPE_MENU, SwamiguiMenu)) #define SWAMIGUI_MENU_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMIGUI_TYPE_MENU, SwamiguiMenuClass)) #define SWAMIGUI_IS_MENU(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMIGUI_TYPE_MENU)) #define SWAMIGUI_IS_MENU_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMIGUI_TYPE_MENU)) /* Swami Menu object */ struct _SwamiguiMenu { GtkVBox parent_instance; GtkUIManager *ui; }; struct _SwamiguiMenuClass { GtkVBoxClass parent_class; }; GType swamigui_menu_get_type (void); GtkWidget *swamigui_menu_new (void); #endif swami/src/swamigui/SwamiguiControlAdj.h0000644000175000017500000000444011461334205020411 0ustar alessioalessio/* * SwamiguiControlAdj.h - GtkAdjustment SwamiControl object * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_CONTROL_ADJ_H__ #define __SWAMIGUI_CONTROL_ADJ_H__ typedef struct _SwamiguiControlAdj SwamiguiControlAdj; typedef struct _SwamiguiControlAdjClass SwamiguiControlAdjClass; #include #include #define SWAMIGUI_TYPE_CONTROL_ADJ (swamigui_control_adj_get_type ()) #define SWAMIGUI_CONTROL_ADJ(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMIGUI_TYPE_CONTROL_ADJ, \ SwamiguiControlAdj)) #define SWAMIGUI_CONTROL_ADJ_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMIGUI_TYPE_CONTROL_ADJ, \ SwamiguiControlAdjClass)) #define SWAMIGUI_IS_CONTROL_ADJ(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMIGUI_TYPE_CONTROL_ADJ)) #define SWAMIGUI_IS_CONTROL_ADJ_CLASS(obj) \ (G_TYPE_CHECK_CLASS_TYPE ((obj), SWAMIGUI_TYPE_CONTROL_ADJ)) struct _SwamiguiControlAdj { SwamiControl parent_instance; GtkAdjustment *adj; /* GTK adjustment of control */ GParamSpec *pspec; /* parameter spec */ gulong value_change_id; /* GtkAdjustment value-changed handler ID */ }; struct _SwamiguiControlAdjClass { SwamiControlClass parent_class; }; GType swamigui_control_adj_get_type (void); SwamiguiControlAdj *swamigui_control_adj_new (GtkAdjustment *adj); void swamigui_control_adj_set (SwamiguiControlAdj *ctrladj, GtkAdjustment *adj); void swamigui_control_adj_block_changes (SwamiguiControlAdj *ctrladj); void swamigui_control_adj_unblock_changes (SwamiguiControlAdj *ctrladj); #endif swami/src/swamigui/SwamiguiSpinScale.c0000644000175000017500000001444011461334205020227 0ustar alessioalessio/* * SwamiguiSpinScale.c - A GtkSpinButton/GtkScale combo widget * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include "config.h" #include #include #include #include "SwamiguiSpinScale.h" #include "i18n.h" #include "util.h" enum { PROP_0, PROP_ADJUSTMENT, PROP_DIGITS, PROP_VALUE, PROP_SCALE_FIRST /* the order of the widgets */ }; /* Local Prototypes */ static void swamigui_spin_scale_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void swamigui_spin_scale_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void swamigui_spin_scale_init (SwamiguiSpinScale *spin_scale); static gboolean swamigui_spin_scale_real_set_order (SwamiguiSpinScale *spin_scale, gboolean scale_first); /* define the SwamiguiSpinScale type */ G_DEFINE_TYPE (SwamiguiSpinScale, swamigui_spin_scale, GTK_TYPE_HBOX); static void swamigui_spin_scale_class_init (SwamiguiSpinScaleClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); obj_class->set_property = swamigui_spin_scale_set_property; obj_class->get_property = swamigui_spin_scale_get_property; g_object_class_install_property (obj_class, PROP_ADJUSTMENT, g_param_spec_object ("adjustment", "Adjustment", "Adjustment", GTK_TYPE_ADJUSTMENT, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_DIGITS, g_param_spec_uint ("digits", "Digits", "Digits", 0, 20, 0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_VALUE, g_param_spec_double ("value", "Value", "Value", -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_SCALE_FIRST, g_param_spec_boolean ("scale-first", "Scale first", "Scale first", FALSE, G_PARAM_READWRITE)); } static void swamigui_spin_scale_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { SwamiguiSpinScale *sc = SWAMIGUI_SPIN_SCALE (object); GtkAdjustment *adj; guint digits; double d; switch (property_id) { case PROP_ADJUSTMENT: adj = GTK_ADJUSTMENT (g_value_get_object (value)); gtk_spin_button_set_adjustment (GTK_SPIN_BUTTON (sc->spinbtn), adj); gtk_range_set_adjustment (GTK_RANGE (sc->hscale), adj); break; case PROP_DIGITS: digits = g_value_get_uint (value); gtk_spin_button_set_digits (GTK_SPIN_BUTTON (sc->spinbtn), digits); gtk_scale_set_digits (GTK_SCALE (sc->hscale), digits); break; case PROP_VALUE: d = g_value_get_double (value); adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (sc->spinbtn)); gtk_adjustment_set_value (adj, d); break; case PROP_SCALE_FIRST: swamigui_spin_scale_real_set_order (sc, g_value_get_boolean (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_spin_scale_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { SwamiguiSpinScale *sc = SWAMIGUI_SPIN_SCALE (object); switch (property_id) { case PROP_ADJUSTMENT: g_value_set_object (value, (GObject *)gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (sc->spinbtn))); break; case PROP_DIGITS: g_value_set_uint (value, gtk_spin_button_get_digits (GTK_SPIN_BUTTON (sc->spinbtn))); break; case PROP_VALUE: g_value_set_double (value, gtk_spin_button_get_value (GTK_SPIN_BUTTON (sc->spinbtn))); break; case PROP_SCALE_FIRST: g_value_set_boolean (value, sc->scale_first); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_spin_scale_init (SwamiguiSpinScale *spin_scale) { GtkAdjustment *adj; spin_scale->scale_first = FALSE; adj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0)); spin_scale->spinbtn = gtk_spin_button_new (adj, 1.0, 0); gtk_widget_show (spin_scale->spinbtn); gtk_box_pack_start (GTK_BOX (spin_scale), spin_scale->spinbtn, FALSE, FALSE, 0); spin_scale->hscale = gtk_hscale_new (adj); gtk_scale_set_draw_value (GTK_SCALE (spin_scale->hscale), FALSE); gtk_widget_show (spin_scale->hscale); gtk_box_pack_start (GTK_BOX (spin_scale), spin_scale->hscale, TRUE, TRUE, 0); } /** * swamigui_spin_scale_new: * * Create a new spin button/scale combo widget. * * Returns: New widget. */ GtkWidget * swamigui_spin_scale_new (void) { return (GTK_WIDGET (g_object_new (SWAMIGUI_TYPE_SPIN_SCALE, NULL))); } /** * swamigui_spin_scale_set_order: * @spin_scale: Spin scale widget * @scale_first: %TRUE if the GtkHScale should be before the GtkSpinButton, * %FALSE otherwise. * * Sets the order that the horizontal scale and spin button widgets appear. */ void swamigui_spin_scale_set_order (SwamiguiSpinScale *spin_scale, gboolean scale_first) { if (swamigui_spin_scale_real_set_order (spin_scale, scale_first)) g_object_notify (G_OBJECT (spin_scale), "scale-first"); } static gboolean swamigui_spin_scale_real_set_order (SwamiguiSpinScale *spin_scale, gboolean scale_first) { g_return_val_if_fail (SWAMIGUI_IS_SPIN_SCALE (spin_scale), FALSE); scale_first = (scale_first != 0); /* force booleanize it */ if (spin_scale->scale_first == scale_first) return (FALSE); spin_scale->scale_first = scale_first; gtk_box_reorder_child (GTK_BOX (spin_scale), spin_scale->hscale, !scale_first); return (TRUE); } swami/src/swamigui/SwamiguiPiano.h0000644000175000017500000000765511461334205017433 0ustar alessioalessio/* * SwamiguiPiano.h - Piano canvas item * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_PIANO_H__ #define __SWAMIGUI_PIANO_H__ #include #include #include typedef struct _SwamiguiPiano SwamiguiPiano; typedef struct _SwamiguiPianoClass SwamiguiPianoClass; #define SWAMIGUI_TYPE_PIANO (swamigui_piano_get_type ()) #define SWAMIGUI_PIANO(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMIGUI_TYPE_PIANO, SwamiguiPiano)) #define SWAMIGUI_PIANO_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMIGUI_TYPE_PIANO, \ SwamiguiPianoClass)) #define SWAMIGUI_IS_PIANO(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMIGUI_TYPE_PIANO)) #define SWAMIGUI_IS_PIANO_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMIGUI_TYPE_PIANO)) #define SWAMIGUI_PIANO_DEFAULT_WIDTH 640 /* default width in pixels */ #define SWAMIGUI_PIANO_DEFAULT_HEIGHT 48 /* default hight in pixels */ #define SWAMIGUI_PIANO_DEFAULT_LOWER_OCTAVE 3 /* default lower keys octave */ #define SWAMIGUI_PIANO_DEFAULT_UPPER_OCTAVE 4 /* default upper keys octave */ /* Swami Piano Object */ struct _SwamiguiPiano { GnomeCanvasGroup parent_instance; /* derived from GnomeCanvasGroup */ SwamiControl *midi_ctrl; /* MIDI control object */ SwamiControl *express_ctrl; /* expression control object */ int midi_chan; /* MIDI channel to send events on */ int velocity; /* default MIDI note on velocity to use */ int width, height; /* width and height in pixels */ gpointer key_info; /* array of KeyInfo structures (see SwamiguiPiano.c) */ GnomeCanvasItem *bg; /* black background (outline/separators) */ guint8 key_count; /* number of keys */ guint8 start_note; /* note piano starts on (always note C) */ guint8 lower_octave; /* lower computer keyboard octave # */ guint8 upper_octave; /* upper computer keyboard octave # */ guint8 lower_velocity; /* lower keyboard velocity */ guint8 upper_velocity; /* upper keyboard velocity */ guint8 mouse_note; /* mouse selected note >127 = none */ guint8 reserved; /* cached values */ int white_count; gboolean up2date; /* are variables below up to date? */ double world_width, world_height; double key_width, key_width_half; double shadow_top; double black_height; double vline_width, hline_width; double black_vel_ofs, black_vel_range; double white_vel_ofs, white_vel_range; guint32 bg_color; guint32 white_key_color; guint32 black_key_color; guint32 shadow_edge_color; guint32 white_key_play_color; guint32 black_key_play_color; }; struct _SwamiguiPianoClass { GnomeCanvasGroupClass parent_class; void (*note_on) (SwamiguiPiano *piano, guint keynum); void (*note_off) (SwamiguiPiano *piano, guint keynum); }; GType swamigui_piano_get_type (void); void swamigui_piano_note_on (SwamiguiPiano *piano, int note, int velocity); void swamigui_piano_note_off (SwamiguiPiano *piano, int note, int velocity); int swamigui_piano_pos_to_note (SwamiguiPiano *piano, double x, double y, int *velocity, gboolean *isblack); double swamigui_piano_note_to_pos (SwamiguiPiano *piano, int note, int edge, gboolean realnote, gboolean *isblack); #endif swami/src/swamigui/patch_funcs.c0000644000175000017500000007005711461334205017143 0ustar alessioalessio/* * patch_funcs.c - General instrument patch functions * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include #include "SwamiguiMultiSave.h" #include "SwamiguiPaste.h" #include "SwamiguiProp.h" #include "SwamiguiRoot.h" #include "SwamiguiTree.h" #include "util.h" #include "i18n.h" /* maximum notebook tab length (in characters). Only used for item properties dialog currently. */ #define MAX_NOTEBOOK_TAB_LENGTH 20 /* Columns used in sample export file format combo box list store */ enum { FILE_FORMAT_COL_TEXT, /* Descriptive format label displayed in combo */ FILE_FORMAT_COL_NAME, /* Name identifier of format */ FILE_FORMAT_COL_VALUE, /* Enum value of format */ FILE_FORMAT_COL_COUNT }; /* Local Prototypes */ static void swamigui_cb_load_files_response (GtkWidget *dialog, gint response, gpointer user_data); static void swamigui_cb_load_samples_response (GtkWidget *dialog, gint response, gpointer user_data); static void swamigui_cb_export_samples_response (GtkWidget *dialog, gint response, gpointer user_data); /* global variables */ static char *path_patch_load = NULL; /* last loaded patch path */ //static char *path_patch_save = NULL; /* last saved patch path */ static char *path_sample_load = NULL; /* last sample load path */ static char *path_sample_export = NULL; /* last sample export path */ static char *last_sample_format = NULL; /* last sample export format */ /* clipboard for item selections */ static IpatchList *item_clipboard = NULL; /** * swamigui_load_files: * @root: GUI root object * * Open files routine. Displays a file selection dialog to open patch * files with. */ void swamigui_load_files (SwamiguiRoot *root) { GtkWidget *dialog; dialog = gtk_file_chooser_dialog_new (_("Load files"), NULL, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, GTK_STOCK_ADD, GTK_RESPONSE_APPLY, NULL); /* enable multiple selection mode */ gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE); /* set default response */ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT); /* if load path isn't set, use default patch path from swami.cfg, duplicate it of course :) */ if (!path_patch_load) g_object_get (root, "patch-path", &path_patch_load, NULL); if (path_patch_load && strlen (path_patch_load)) gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), path_patch_load); g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (swamigui_cb_load_files_response), root); gtk_widget_show (dialog); } /* loads the list of user selected files */ static void swamigui_cb_load_files_response (GtkWidget *dialog, gint response, gpointer user_data) { SwamiRoot *root = SWAMI_ROOT (user_data); GSList *file_names, *p; gboolean loaded = FALSE; char *fname; GError *err = NULL; GtkRecentManager *manager; char *file_uri; if (response == GTK_RESPONSE_CANCEL || response == GTK_RESPONSE_DELETE_EVENT) { if (response == GTK_RESPONSE_CANCEL) gtk_widget_destroy (dialog); return; } /* "Add" or "OK" button clicked */ file_names = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (dialog)); /* loop over file names */ for (p = file_names; p; p = g_slist_next (p)) { fname = (char *)(p->data); if (swami_root_patch_load (root, fname, NULL, &err)) { if ((file_uri = g_filename_to_uri (fname, NULL, NULL))) { manager = gtk_recent_manager_get_default (); if (!gtk_recent_manager_add_item (manager, file_uri)) g_warning ("Error while adding file name to recent manager."); g_free (file_uri); } loaded = TRUE; /* only set patch path on successful load */ } else /* error occurred - log it */ { g_critical (_("Failed to load file '%s': %s"), fname, ipatch_gerror_message (err)); g_clear_error (&err); } } if (loaded) { g_free (path_patch_load); /* free old load path */ path_patch_load /* !! takes over allocation */ = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog)); } /* free the file name list and strings */ for (p = file_names; p; p = g_slist_delete_link (p, p)) g_free (p->data); /* destroy dialog if "OK" button was clicked */ if (response == GTK_RESPONSE_ACCEPT) gtk_widget_destroy (dialog); } /** * swamigui_close_files: * @item_list: List of items to close (usually only #IpatchBase derived * objects make sense). * * User interface to close files. */ void swamigui_close_files (IpatchList *item_list) { GtkWidget *dialog; IpatchIter iter; IpatchItem *item; gboolean patch_found = FALSE; gboolean changed; /* see if there are any patch items to close and if they have been changed */ ipatch_list_init_iter (item_list, &iter); item = ipatch_item_first (&iter); while (item) { if (IPATCH_IS_BASE (item)) /* only IpatchBase derived patches */ { patch_found = TRUE; g_object_get (item, "changed", &changed, NULL); if (changed) break; } item = ipatch_item_next (&iter); } if (!patch_found) return; /* no patches to close, return */ /* if no items changed, then go ahead and close files */ if (!item) { item = ipatch_item_first (&iter); /* re-use the same iterator */ while (item) { if (IPATCH_IS_BASE (item)) /* removing, closes patch */ ipatch_item_remove (IPATCH_ITEM (item)); item = ipatch_item_next (&iter); } return; } /* item(s) have been changed, pop user interactive dialog */ dialog = swamigui_multi_save_new (_("Close files"), _("Save changed files before closing?"), SWAMIGUI_MULTI_SAVE_CLOSE_MODE); swamigui_multi_save_set_selection (SWAMIGUI_MULTI_SAVE (dialog), item_list); gtk_widget_show (dialog); } /** * swamigui_save_files: * @item_list: List of items to save. * @saveas: TRUE forces popup of dialog even if all files have previously * been saved (forces "Save As"). * * Save files user interface. If @saveas is %FALSE and all selected files * have already been saved before, then they are saved. If only one file has * not yet been saved then the normal save as file dialog is shown. If * multiple files have not been saved or @saveas is %TRUE then the multi-file * save dialog is used. */ void swamigui_save_files (IpatchList *item_list, gboolean saveas) { GtkWidget *dialog; IpatchItem *item, *base; char *filename; gboolean popup = FALSE, match = FALSE; gboolean saved, changed; GError *err = NULL; int savecount = 0, failcount = 0; GList *p; /* see if any items have been changed */ for (p = item_list->items; p; p = p->next) { item = (IpatchItem *)(p->data); base = ipatch_item_get_base (item); /* ++ ref base object */ if (base) /* only save IpatchBase items or children thereof */ { match = TRUE; /* found a patch base object */ g_object_get (base, "saved", &saved, "changed", &changed, NULL); if (!saved) popup = TRUE; /* never been saved, force dialog */ g_object_unref (base); /* -- unref base */ } } if (!match) return; /* return, if there are no items to save */ popup |= saveas; /* force dialog popup, "Save As"? */ /* no dialog required? (all items previously saved and !saveas) */ if (!popup) { for (p = item_list->items; p; p = p->next) { item = (IpatchItem *)(p->data); base = ipatch_item_get_base (item); /* ++ ref base object */ if (!base) continue; g_object_get (base, "file-name", &filename, NULL); /* ++ alloc filename */ if (!swami_root_patch_save (IPATCH_ITEM (base), filename, &err)) { g_critical (_("Failed to save file '%s': %s"), filename, ipatch_gerror_message (err)); g_clear_error (&err); failcount++; } else savecount++; g_free (filename); /* -- free filename */ g_object_unref (base); /* -- unref base object */ } if (!failcount) swamigui_statusbar_printf (swamigui_root->statusbar, _("Saved %d file(s)"), savecount); else swamigui_statusbar_printf (swamigui_root->statusbar, _("Saved %d file(s), %d FAILED"), savecount, failcount); return; } /* save-as was requested or a file has not yet been saved */ dialog = swamigui_multi_save_new (_("Save files"), _("Select files to save"), 0); swamigui_multi_save_set_selection (SWAMIGUI_MULTI_SAVE (dialog), item_list); gtk_widget_show (dialog); } /** * swamigui_delete_items: * @item_list: List of items to delete * * Delete patch items */ void swamigui_delete_items (IpatchList *item_list) { IpatchItem *parent = NULL; gboolean same_parent = TRUE; IpatchItem *item; IpatchIter iter; IpatchList *list; ipatch_list_init_iter (item_list, &iter); for (item = ipatch_item_first (&iter); item; item = ipatch_item_next (&iter)) { if (IPATCH_IS_ITEM (item) && !IPATCH_IS_BASE (item)) { if (same_parent) { if (parent) { if (parent != ipatch_item_peek_parent (item)) same_parent = FALSE; } else parent = ipatch_item_get_parent (item); /* ++ ref parent */ } ipatch_item_remove (item); } } /* If all items had same parent and it wasn't the patch object, make it the * new selection */ if (same_parent && parent && !IPATCH_IS_BASE (parent)) { list = ipatch_list_new (); /* ++ ref list */ list->items = g_list_append (list->items, g_object_ref (parent)); swamigui_tree_set_selection (SWAMIGUI_TREE (swamigui_root->tree), list); g_object_unref (list); /* -- unref list */ } if (parent) g_object_unref (parent); /* -- unref parent */ } /** * swamigui_wtbl_load_patch: * @item: Patch to load into wavetable. * * Load a patch item */ void swamigui_wtbl_load_patch (IpatchItem *item) { SwamiRoot *root; GObject *wavetbl; GError *err = NULL; /* IpatchBase derived objects only */ if (!IPATCH_IS_BASE (item)) return; root = swami_get_root (G_OBJECT (item)); if (!root) return; wavetbl = swami_object_get_by_type (G_OBJECT (root), "SwamiWavetbl"); if (wavetbl) { if (!swami_wavetbl_load_patch (SWAMI_WAVETBL (wavetbl), item, &err)) { g_critical (_("Patch load failed: %s"), ipatch_gerror_message (err)); g_clear_error (&err); } } } /** * swamigui_new_item: * @parent_hint: The parent of the new item or a hint item. An example of * a hint item is a SWAMIGUI_TREE_PRESET_MELODIC item which would allow the * real IpatchSF2Preset parent to be found, and would also indicate that * the new zone should be in the melodic branch. Can (and should be) NULL for * toplevel patch objects (IpatchSF2, etc). * @type: GType of an #IpatchItem derived type to create. * * Create a new patch item. */ void swamigui_new_item (IpatchItem *parent_hint, GType type) { IpatchItem *new_item, *real_parent = NULL; IpatchVirtualContainerConformFunc conform_func; IpatchList *list; g_return_if_fail (!parent_hint || IPATCH_IS_ITEM (parent_hint)); if (!parent_hint) parent_hint = IPATCH_ITEM (swami_root->patch_root); new_item = g_object_new (type, NULL); /* create new item */ /* parent hint is a virtual container? */ if (IPATCH_IS_VIRTUAL_CONTAINER (parent_hint)) { /* get virtual container conform function if any */ ipatch_type_get (G_OBJECT_TYPE (parent_hint), "virtual-child-conform-func", &conform_func, NULL); real_parent = ipatch_item_get_parent (parent_hint); g_return_if_fail (real_parent != NULL); parent_hint = real_parent; /* force the new item to conform to virtual container parent_hint */ if (conform_func) conform_func ((GObject *)new_item); } /* add and make unique (if appropriate) */ ipatch_container_add_unique (IPATCH_CONTAINER (parent_hint), new_item); /* -- unref real parent object if parent_hint was a virtual container */ if (real_parent) g_object_unref (real_parent); /* update selection to be new item */ list = ipatch_list_new (); /* ++ ref new list */ list->items = g_list_append (list->items, g_object_ref (new_item)); g_object_set (swamigui_root, "selection", list, NULL); g_object_unref (list); /* -- unref new list */ } /** * swamigui_goto_link_item: * @item: Patch item * @tree: Swami tree object * * Goto an item's linked item in a #SwamiguiTree object. * Moves the view and selects the item in a #SwamiguiTree that is linked * by @item. */ void swamigui_goto_link_item (IpatchItem *item, SwamiguiTree *tree) { GObject *link = NULL; g_return_if_fail (IPATCH_IS_ITEM (item)); g_return_if_fail (SWAMIGUI_IS_TREE (tree)); g_object_get (item, "link-item", &link, NULL); /* ++ ref link */ if (link) { swamigui_tree_spotlight_item (tree, link); g_object_unref (link); /* -- unref from g_object_get */ } } /** * swamigui_load_samples: * @parent_hint: Parent of new sample or a child thereof. * * Load sample user interface */ void swamigui_load_samples (IpatchItem *parent_hint) { GtkWidget *dialog; GtkWindow *main_window; /* ++ ref main window */ g_object_get (swamigui_root, "main-window", &main_window, NULL); dialog = gtk_file_chooser_dialog_new (_("Load samples"), main_window, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CLOSE, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, GTK_STOCK_ADD, GTK_RESPONSE_APPLY, NULL); g_object_unref (main_window); /* -- unref main window */ /* enable multiple selection mode */ gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE); /* set default response */ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT); /* if sample load path isn't set, use default from config */ if (!path_sample_load) { SwamiRoot *root = swami_get_root (G_OBJECT (parent_hint)); g_object_get (G_OBJECT (root), "sample-path", &path_sample_load, NULL); } if (path_sample_load && strlen (path_sample_load)) gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), path_sample_load); if (parent_hint) g_object_ref (parent_hint); /* ++ ref for dialog */ g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (swamigui_cb_load_samples_response), parent_hint); gtk_widget_show (dialog); } /* routine that loads the samples from a file selection dialog */ static void swamigui_cb_load_samples_response (GtkWidget *dialog, gint response, gpointer user_data) { IpatchItem *parent_hint = (IpatchItem *)user_data; GSList *file_names, *p; GList *lp; IpatchPaste *paste; IpatchFileHandle *fhandle; IpatchList *biglist, *list; char *fname; gboolean loaded = FALSE; GError *err = NULL; if (response == GTK_RESPONSE_CANCEL || response == GTK_RESPONSE_DELETE_EVENT) { if (parent_hint) g_object_unref (parent_hint); if (response == GTK_RESPONSE_CANCEL) gtk_widget_destroy (dialog); return; } paste = ipatch_paste_new (); /* ++ ref paste object */ biglist = ipatch_list_new (); /* ++ ref list */ /* "Add" or "OK" button clicked */ file_names = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (dialog)); /* loop over file names */ for (p = file_names; p; p = g_slist_next (p)) { fname = (char *)(p->data); /* ++ alloc new file handle */ if (!(fhandle = ipatch_file_identify_open (fname, &err))) { g_critical (_("Failed to identify file '%s': %s"), fname, ipatch_gerror_message (err)); g_clear_error (&err); continue; } if (!IPATCH_IS_SND_FILE (fhandle->file)) { g_critical (_("File '%s' is not a supported sample type"), fname); ipatch_file_close (fhandle); /* -- close file handle */ continue; } /* determine if IpatchSampleFile can be pasted to destination.. */ if (!ipatch_is_paste_possible (IPATCH_ITEM (parent_hint), IPATCH_ITEM (fhandle->file))) { g_critical (_("Not possible to load object of type '%s' to '%s'"), g_type_name (IPATCH_TYPE_SND_FILE), g_type_name (G_OBJECT_TYPE (parent_hint))); ipatch_file_close (fhandle); /* -- close file handle */ continue; } /* paste sample file to destination */ if (!ipatch_paste_objects (paste, IPATCH_ITEM (parent_hint), IPATCH_ITEM (fhandle->file), &err)) { /* object paste failed */ g_critical (_("Failed to load object of type '%s' to '%s': %s"), g_type_name (IPATCH_TYPE_SND_FILE), g_type_name (G_OBJECT_TYPE (parent_hint)), ipatch_gerror_message (err)); g_clear_error (&err); ipatch_file_close (fhandle); /* -- close file handle */ continue; } ipatch_file_close (fhandle); /* -- close file handle */ list = ipatch_paste_get_add_list (paste); /* ++ ref added object list */ if (list) { /* biglist takes over items of list */ for (lp = list->items; lp; lp = g_list_delete_link (lp, lp)) biglist->items = g_list_prepend (biglist->items, lp->data); list->items = NULL; g_object_unref (list); /* -- unref list */ } loaded = TRUE; /* only set sample path on successful load */ } /* finish the paste operation */ if (ipatch_paste_finish (paste, &err)) { /* select all samples which were added */ biglist->items = g_list_reverse (biglist->items); /* put in right order */ g_object_set (swamigui_root, "selection", biglist, NULL); g_object_unref (biglist); /* -- unref list */ } else { g_critical (_("Failed to finish load of samples (paste operation): %s"), ipatch_gerror_message (err)); g_clear_error (&err); } g_object_unref (paste); /* -- unref paste object */ if (loaded) { g_free (path_sample_load); /* free old load path */ path_sample_load /* !! takes over allocation */ = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog)); } /* free the file name list and strings */ for (p = file_names; p; p = g_slist_delete_link (p, p)) g_free (p->data); /* destroy dialog if "OK" button was clicked */ if (response == GTK_RESPONSE_ACCEPT) { if (parent_hint) g_object_unref (parent_hint); gtk_widget_destroy (dialog); } } /** * swamigui_export_samples: * @samples: List of objects (non #IpatchSample interface items are ignored) * * Export one or more samples (object with #IpatchSample interface) to a file * or directory. */ void swamigui_export_samples (IpatchList *samples) { gboolean found_sample = FALSE; GtkWindow *main_window; GtkWidget *dialog; GtkWidget *hbox; GtkWidget *label; GtkWidget *combo; GEnumClass *format_enum; GtkListStore *format_store; GtkCellRenderer *renderer; gboolean multi; GtkTreeIter iter; IpatchSample *sample; int i, sel, def_index; GList *p; g_return_if_fail (IPATCH_IS_LIST (samples)); for (p = samples->items; p; p = p->next) { if (IPATCH_IS_SAMPLE (p->data)) { if (found_sample) break; sample = p->data; found_sample = TRUE; } } if (!found_sample) return; multi = (p != NULL); /* Multi sample selection? */ /* ++ ref main window */ g_object_get (swamigui_root, "main-window", &main_window, NULL); /* if only 1 item found, create a file save dialog, otherwise create a folder selection dialog */ dialog = gtk_file_chooser_dialog_new (_("Export samples"), main_window, multi ? GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER : GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); g_object_unref (main_window); /* -- unref main window */ /* set default response */ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT); /* if sample load path isn't set, use default from config */ if (!path_sample_export) g_object_get (swamigui_root, "sample-path", &path_sample_export, NULL); if (path_sample_export && strlen (path_sample_export)) { gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), path_sample_export); if (!multi) /* Single sample export? */ { char *name, *filename; /* Set the file name to be that of the sample's title */ g_object_get (sample, "title", &name, NULL); /* ++ alloc name */ filename = g_strconcat (name, ".wav", NULL); /* ++ alloc filename */ g_free (name); /* -- free name */ gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), filename); g_free (filename); /* -- free file name */ } } g_object_set_data_full (G_OBJECT (dialog), "samples", g_object_ref (samples), (GDestroyNotify)g_object_unref); g_object_set_data (G_OBJECT (dialog), "multi", GINT_TO_POINTER (multi)); g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (swamigui_cb_export_samples_response), NULL); /* Create file format selector combo */ hbox = gtk_hbox_new (FALSE, 4); gtk_widget_show (hbox); gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox, FALSE, FALSE, 0); label = gtk_label_new (_("File format")); gtk_widget_show (label); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); /* ++ ref new store for file format combo box */ format_store = gtk_list_store_new (FILE_FORMAT_COL_COUNT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT); combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (format_store)); renderer = gtk_cell_renderer_text_new (); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, FALSE); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer, "text", FILE_FORMAT_COL_TEXT, NULL); if (!last_sample_format) { g_object_get (swamigui_root, "sample-format", &last_sample_format, NULL); if (!last_sample_format) last_sample_format = g_strdup ("wav"); } sel = -1; /* selected index */ /* Populate file formats */ format_enum = g_type_class_ref (g_type_from_name ("IpatchSndFileFormat")); /* ++ ref class */ if (format_enum) { for (i = 0; i < format_enum->n_values; i++) { gtk_list_store_append (format_store, &iter); gtk_list_store_set (format_store, &iter, FILE_FORMAT_COL_TEXT, format_enum->values[i].value_nick, FILE_FORMAT_COL_NAME, format_enum->values[i].value_name, FILE_FORMAT_COL_VALUE, format_enum->values[i].value, -1); if (last_sample_format && strcmp (last_sample_format, format_enum->values[i].value_name) == 0) sel = i; if (format_enum->values[i].value == IPATCH_SND_FILE_DEFAULT_FORMAT) def_index = i; } g_type_class_unref (format_enum); /* -- unref enum class */ } gtk_combo_box_set_active (GTK_COMBO_BOX (combo), sel != -1 ? sel : def_index); g_object_unref (format_store); /* -- unref the list store */ gtk_widget_show (combo); gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 0); g_object_set_data (G_OBJECT (dialog), "combo", combo); gtk_widget_show (dialog); } static void swamigui_cb_export_samples_response (GtkWidget *dialog, gint response, gpointer user_data) { IpatchList *samples; IpatchSample *sample; GtkWidget *combo; gboolean multi; char *filepath; /* file name or directory name (single/multi) */ char *filename; GError *err = NULL; GtkTreeModel *format_model; GtkTreeIter iter; char *format_name; int format_value = IPATCH_SND_FILE_DEFAULT_FORMAT; GList *p; if (response == GTK_RESPONSE_CANCEL || response == GTK_RESPONSE_DELETE_EVENT) { if (response == GTK_RESPONSE_CANCEL) gtk_widget_destroy (dialog); return; } samples = IPATCH_LIST (g_object_get_data (G_OBJECT (dialog), "samples")); multi = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dialog), "multi")); combo = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog), "combo")); filepath = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter)) { format_model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo)); gtk_tree_model_get (format_model, &iter, FILE_FORMAT_COL_NAME, &format_name, /* ++ alloc */ FILE_FORMAT_COL_VALUE, &format_value, -1); } /* update last sample format */ if (last_sample_format) g_free (last_sample_format); last_sample_format = format_name; /* !! last_sample_format takes over alloc */ for (p = samples->items; p; p = p->next) { if (!IPATCH_IS_SAMPLE (p->data)) continue; sample = IPATCH_SAMPLE (p->data); /* compose file name */ if (multi) { char *name, *temp; g_object_get (sample, "name", &name, NULL); temp = g_strconcat (name, ".", format_name, NULL); g_free (name); filename = g_build_filename (filepath, temp, NULL); g_free (temp); } else filename = g_strdup (filepath); if (!ipatch_sample_save_to_file (sample, filename, format_value, -1, &err)) { g_critical (_("Failed to save sample '%s': %s"), filename, ipatch_gerror_message (err)); continue; } g_free (filename); } g_free (filepath); gtk_widget_destroy (dialog); } /** * swamigui_copy_items: * @items: List of items to copy or %NULL to clear * * Set the item clipboard to a given list of items. */ void swamigui_copy_items (IpatchList *items) { g_return_if_fail (!items || IPATCH_IS_LIST (items)); if (item_clipboard) { g_object_unref (item_clipboard); item_clipboard = NULL; } if (items) item_clipboard = ipatch_list_duplicate (items); } /* structure used to remember user decisions */ typedef struct { SwamiguiPasteDecision all; /* choice for all items or 0 for none */ GList *types; /* per type choices (RememberTypeChoice) */ } RememberChoices; /* per item type choice structure */ typedef struct { GType type; /* GType of this choice */ SwamiguiPasteDecision choice; /* choice */ } RememberTypeChoice; /** * swamigui_paste_items: * @dstitem: Destination item for paste * @items: List of source items to paste to destination item or %NULL * to use item clipboard * * Paste items user interface routine */ void swamigui_paste_items (IpatchItem *dstitem, GList *items) { IpatchPaste *paste; /* paste instance */ IpatchItem *src; GError *err = NULL; GList *p; /* use clipboard if no items given */ if (!items && item_clipboard) items = item_clipboard->items; paste = ipatch_paste_new (); /* ++ ref new paste instance */ for (p = items; p; p = p->next) /* loop on source items */ { src = IPATCH_ITEM (p->data); if (ipatch_is_paste_possible (dstitem, src)) /* paste possible? */ { /* add paste operation to instance */ if (!ipatch_paste_objects (paste, dstitem, src, &err)) { g_critical (_("Failed to paste item of type %s to %s: %s"), G_OBJECT_TYPE_NAME (src), G_OBJECT_TYPE_NAME (dstitem), ipatch_gerror_message (err)); g_clear_error (&err); } } } /* complete the paste operations */ if (!ipatch_paste_finish (paste, &err)) { g_critical (_("Failed to execute paste operation: %s"), ipatch_gerror_message (err)); g_clear_error (&err); } g_object_unref (paste); /* -- unref paste instance */ } swami/src/swamigui/Makefile.am0000644000175000017500000001277711464144605016551 0ustar alessioalessio## Process this file with automake to produce Makefile.in if PLATFORM_WIN32 runtime_pseudo_reloc = -Wl,--enable-runtime-pseudo-reloc endif # GUI is compiled into a static libtool shared library so we can sic # gtk-doc on it and combine libtool static libs from sub directories. SUBDIRS = images widgets lib_LTLIBRARIES = libswamigui.la bin_PROGRAMS = swami if PYTHON_SUPPORT opt_python_view_h = SwamiguiPythonView.h opt_python_view_c = SwamiguiPythonView.c opt_swami_python_h = swami_python.h opt_swami_python_c = swami_python.c endif EXTRA_DIST = glade_strings.c marshals.list swami-2.glade SwamiguiPythonView.h \ SwamiguiPythonView.c swami_python.h swami_python.c uixmldir = $(pkgdatadir) uixml_DATA = swami-2.glade BUILT_SOURCES = \ builtin_enums.c \ builtin_enums.h \ marshals.c \ marshals.h # correctly clean the generated source files CLEANFILES = $(BUILT_SOURCES) libswamigui_public_h_sources = \ $(opt_python_view_h) \ $(opt_swami_python_h) \ SwamiguiBar.h \ SwamiguiBarPtr.h \ SwamiguiCanvasMod.h \ SwamiguiControl.h \ SwamiguiControlAdj.h \ SwamiguiControlMidiKey.h \ SwamiguiItemMenu.h \ SwamiguiKnob.h \ SwamiguiLoopFinder.h \ SwamiguiMenu.h \ SwamiguiModEdit.h \ SwamiguiMultiSave.h \ SwamiguiNoteSelector.h \ SwamiguiPanel.h \ SwamiguiPanelSelector.h \ SwamiguiPanelSF2Gen.h \ SwamiguiPanelSF2GenEnv.h \ SwamiguiPanelSF2GenMisc.h \ SwamiguiPaste.h \ SwamiguiPiano.h \ SwamiguiPref.h \ SwamiguiProp.h \ SwamiguiRoot.h \ SwamiguiSampleCanvas.h \ SwamiguiSampleEditor.h \ SwamiguiSpectrumCanvas.h \ SwamiguiSpinScale.h \ SwamiguiSplits.h \ SwamiguiStatusbar.h \ SwamiguiTree.h \ SwamiguiTreeStore.h \ SwamiguiTreeStorePatch.h \ help.h \ icons.h \ patch_funcs.h \ splash.h \ util.h \ widgets/combo-box.h \ widgets/icon-combo.h libswamigui_sources = \ $(BUILT_SOURCES) \ $(opt_python_view_c) \ $(opt_swami_python_c) \ SwamiguiBar.c \ SwamiguiBarPtr.c \ SwamiguiCanvasMod.c \ SwamiguiControl.c \ SwamiguiControl_widgets.c \ SwamiguiControlAdj.c \ SwamiguiControlMidiKey.c \ SwamiguiDnd.h \ SwamiguiItemMenu.c \ SwamiguiItemMenu_actions.c \ SwamiguiKnob.c \ SwamiguiLoopFinder.c \ SwamiguiMenu.c \ SwamiguiModEdit.c \ SwamiguiMultiSave.c \ SwamiguiNoteSelector.c \ SwamiguiPanel.c \ SwamiguiPanelSelector.c \ SwamiguiPanelSF2Gen.c \ SwamiguiPanelSF2GenEnv.c \ SwamiguiPanelSF2GenMisc.c \ SwamiguiPaste.c \ SwamiguiPiano.c \ SwamiguiPref.c \ SwamiguiProp.c \ SwamiguiRoot.c \ SwamiguiSampleCanvas.c \ SwamiguiSampleEditor.c \ SwamiguiSpectrumCanvas.c \ SwamiguiSpinScale.c \ SwamiguiSplits.c \ SwamiguiStatusbar.c \ SwamiguiTree.c \ SwamiguiTreeStore.c \ SwamiguiTreeStorePatch.c \ help.c \ i18n.h \ icons.c \ patch_funcs.c \ splash.c \ swamigui.h \ util.c \ widgets/combo-box.c \ widgets/icon-combo.c libswamigui_la_SOURCES = $(libswamigui_public_h_sources) $(libswamigui_sources) libswamigui_la_LIBADD = $(top_srcdir)/src/libswami/libswami.la \ @LIBINSTPATCH_LIBS@ @GUI_LIBS@ @LIBGLADE_LIBS@ @LIBINTL@ \ @GTK_SOURCE_VIEW_LIBS@ @PYGTK_LIBS@ @PYTHON_LIBS@ swami_SOURCES = main.c swami_LDFLAGS = $(runtime_pseudo_reloc) swami_LDADD = libswamigui.la $(top_srcdir)/src/libswami/libswami.la \ @LIBINSTPATCH_LIBS@ @GUI_LIBS@ @LIBGLADE_LIBS@ @LIBINTL@ \ @GTK_SOURCE_VIEW_LIBS@ @PYGTK_LIBS@ @PYTHON_LIBS@ AM_CPPFLAGS = \ -DIMAGES_DIR=\"$(pkgdatadir)/images\" \ -DUIXML_DIR=\"$(pkgdatadir)\" \ -DSOURCE_DIR=\"$(abs_top_srcdir)\" \ -DLOCALEDIR=\"$(datadir)/locale\" \ -I$(top_srcdir) -I$(top_srcdir)/src -I$(top_srcdir)/intl \ @GUI_CFLAGS@ @LIBINSTPATCH_CFLAGS@ @LIBGLADE_CFLAGS@ \ @GTK_SOURCE_VIEW_CFLAGS@ @PYGTK_CFLAGS@ @PYTHON_CFLAGS@ # Installed headers swamiguiincdir = $(includedir)/swami/swamigui swamiguiinc_HEADERS = $(libswamigui_public_h_sources) builtin_enums.h swamigui.h marshals.c: marshals.list echo "/* Autogenerated file (add to marshals.list and 'make update-marshals') */" >marshals.c glib-genmarshal --body --prefix=swamigui_marshal \ marshals.list >>marshals.c marshals.h: marshals.list echo "/* Autogenerated file (add to marshals.list and 'make update-marshals') */" >marshals.h glib-genmarshal --header --prefix=swamigui_marshal \ marshals.list >>marshals.h builtin_enums.c: s-builtin-enums-c @true s-builtin-enums-c: $(libswamigui_public_h_sources) Makefile ( cd $(srcdir) && glib-mkenums \ --fhead "#include " \ --fprod "\n/* enumerations from \"@filename@\" */" \ --vhead "GType\n@enum_name@_get_type (void)\n{\n static GType etype = 0;\n if (etype == 0) {\n static const G@Type@Value values[] = {" \ --vprod " { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \ --vtail " { 0, NULL, NULL }\n };\n etype = g_@type@_register_static (\"@EnumName@\", values);\n }\n return etype;\n}\n" \ $(libswamigui_public_h_sources) ) > xgen-enumc \ && cp xgen-enumc $(srcdir)/builtin_enums.c \ && rm -f xgen-enumc builtin_enums.h: s-builtin-enums-h @true s-builtin-enums-h: $(libswamigui_public_h_sources) Makefile ( cd $(srcdir) && glib-mkenums \ --fhead "#ifndef __SWAMIGUI_BUILTIN_ENUMS_H__\n#define __SWAMIGUI_BUILTIN_ENUMS_H__\n\n#include \n\nG_BEGIN_DECLS\n" \ --fprod "/* enumerations from \"@filename@\" */\n" \ --vhead "GType @enum_name@_get_type (void);\n#define SWAMIGUI_TYPE_@ENUMSHORT@ (@enum_name@_get_type())\n" \ --ftail "G_END_DECLS\n\n#endif /* __SWAMIGUI_BUILTIN_ENUMS_H__ */" \ $(libswamigui_public_h_sources) ) > xgen-enumh \ && (cmp -s xgen-enumh $(srcdir)/builtin_enums.h \ || cp xgen-enumh $(srcdir)/builtin_enums.h ) \ && rm -f xgen-enumh swami/src/swamigui/SwamiguiStatusbar.c0000644000175000017500000003765711461334205020335 0ustar alessioalessio/* * SwamiguiStatusbar.c - A statusbar (multiple labels/progresses) * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include "config.h" #include #include #include #include "SwamiguiStatusbar.h" #include "i18n.h" #include "util.h" #include "libswami/swami_priv.h" enum { PROP_0, PROP_DEFAULT_TIMEOUT }; typedef struct { SwamiguiStatusbar *statusbar; /* parent statusbar instance */ guint id; /* unique message ID */ char *group; /* group ID for this label or NULL */ int timeout; /* timeout for this label in milliseconds (0 for none) */ guint timeout_handle; /* main loop timeout handle or 0 if none */ guint8 pos; /* SwamiguiStatusbarPos */ GtkWidget *widg; /* status widget */ GtkWidget *frame; /* frame around status widget */ } StatusItem; /* allocation and release of status item structs */ #define status_item_new() g_slice_new0 (StatusItem) #define status_item_free(item) g_slice_free (StatusItem, item) /* default message timeout value in milliseconds */ #define DEFAULT_TIMEOUT_VALUE 4000 /* Local Prototypes */ static void swamigui_statusbar_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void swamigui_statusbar_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void swamigui_statusbar_init (SwamiguiStatusbar *statusbar); static gboolean swamigui_statusbar_item_timeout (gpointer data); static GList *swamigui_statusbar_find (SwamiguiStatusbar *statusbar, guint id, const char *group); static void swamigui_statusbar_cb_item_close_clicked (GtkButton *button, gpointer data); /* define the SwamiguiStatusbar type */ G_DEFINE_TYPE (SwamiguiStatusbar, swamigui_statusbar, GTK_TYPE_FRAME); static void swamigui_statusbar_class_init (SwamiguiStatusbarClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); obj_class->set_property = swamigui_statusbar_set_property; obj_class->get_property = swamigui_statusbar_get_property; g_object_class_install_property (obj_class, PROP_DEFAULT_TIMEOUT, g_param_spec_int ("default-timeout", _("Default Timeout"), _("Default timeout in milliseconds"), 0, G_MAXINT, DEFAULT_TIMEOUT_VALUE, G_PARAM_READWRITE)); } static void swamigui_statusbar_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { SwamiguiStatusbar *statusbar = SWAMIGUI_STATUSBAR (object); switch (property_id) { case PROP_DEFAULT_TIMEOUT: statusbar->default_timeout = g_value_get_uint (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_statusbar_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { SwamiguiStatusbar *statusbar = SWAMIGUI_STATUSBAR (object); switch (property_id) { case PROP_DEFAULT_TIMEOUT: g_value_set_uint (value, statusbar->default_timeout); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_statusbar_init (SwamiguiStatusbar *statusbar) { GtkWidget *widg; statusbar->id_counter = 1; statusbar->default_timeout = DEFAULT_TIMEOUT_VALUE; gtk_frame_set_shadow_type (GTK_FRAME (statusbar), GTK_SHADOW_IN); statusbar->box = gtk_hbox_new (FALSE, 0); gtk_widget_show (statusbar->box); gtk_container_add (GTK_CONTAINER (statusbar), statusbar->box); /* add the Global group status label item */ widg = swamigui_statusbar_msg_label_new ("", SWAMIGUI_STATUSBAR_GLOBAL_MAXLEN); swamigui_statusbar_add (statusbar, "Global", 0, SWAMIGUI_STATUSBAR_POS_RIGHT, widg); } /** * swamigui_statusbar_new: * * Create a new status bar widget. * * Returns: New widget. */ GtkWidget * swamigui_statusbar_new (void) { return (GTK_WIDGET (g_object_new (SWAMIGUI_TYPE_STATUSBAR, NULL))); } /** * swamigui_statusbar_add: * @statusbar: Statusbar widget * @group: Group identifier (existing message with same group is replaced, * NULL for no group) * @timeout: Timeout of statusbar message in milliseconds * (see #SwamiguiStatusbarTimeout for special values including * #SWAMIGUI_STATUSBAR_TIMEOUT_FOREVER (0) for no timeout and * #SWAMIGUI_STATUSBAR_TIMEOUT_DEFAULT to use "default-timeout" property * value) * @pos: Position of message (#SwamiguiStatusbarPos, 0 for default - left) * @widg: Status widget to add to status bar * * Add a widget to a status bar. The @widg is usually created with one of the * helper functions, such as swamigui_statusbar_msg_label_new() or * swamigui_statusbar_msg_progress_new(), although an arbitrary widget can * be added. * * Returns: New message unique ID (which can be used to change/remove message) */ guint swamigui_statusbar_add (SwamiguiStatusbar *statusbar, const char *group, int timeout, guint pos, GtkWidget *widg) { StatusItem *item; GList *p; g_return_val_if_fail (SWAMIGUI_IS_STATUSBAR (statusbar), 0); g_return_val_if_fail (GTK_IS_WIDGET (widg), 0); if (timeout == SWAMIGUI_STATUSBAR_TIMEOUT_DEFAULT) timeout = statusbar->default_timeout; if (group) /* if group specified, search for existing item group match */ { for (p = statusbar->items; p; p = p->next) { item = (StatusItem *)(p->data); if (item->group && strcmp (item->group, group) == 0) /* group match? */ { /* replace the widget */ gtk_container_remove (GTK_CONTAINER (item->frame), item->widg); gtk_container_add (GTK_CONTAINER (item->frame), widg); item->widg = widg; gtk_widget_show (widg); g_object_set_data (G_OBJECT (widg), "_item", item); if (item->timeout_handle) /* remove old timeout if any */ g_source_remove (item->timeout_handle); item->timeout = timeout; if (timeout) /* add new timeout callback if timeout given */ g_timeout_add (timeout, swamigui_statusbar_item_timeout, item); return (item->id); } } } item = status_item_new (); item->statusbar = statusbar; item->id = statusbar->id_counter++; item->group = g_strdup (group); item->timeout = timeout; item->pos = pos; item->widg = widg; item->frame = gtk_frame_new (NULL); gtk_frame_set_shadow_type (GTK_FRAME (item->frame), GTK_SHADOW_OUT); statusbar->items = g_list_prepend (statusbar->items, item); gtk_container_add (GTK_CONTAINER (item->frame), widg); gtk_widget_show_all (item->frame); g_object_set_data (G_OBJECT (widg), "_item", item); /* pack the new item into the statusbar */ if (pos == SWAMIGUI_STATUSBAR_POS_LEFT) gtk_box_pack_start (GTK_BOX (statusbar->box), item->frame, FALSE, FALSE, 2); else gtk_box_pack_end (GTK_BOX (statusbar->box), item->frame, FALSE, FALSE, 2); if (timeout) /* add new timeout callback if timeout given */ g_timeout_add (timeout, swamigui_statusbar_item_timeout, item); return (item->id); } /* timeout callback used to remove statusbar items after a timeout period */ static gboolean swamigui_statusbar_item_timeout (gpointer data) { StatusItem *item = (StatusItem *)data; swamigui_statusbar_remove (item->statusbar, item->id, NULL); return (FALSE); } /** * swamigui_statusbar_remove: * @statusbar: Statusbar widget * @id: Unique ID of message (0 if @group is specified) * @group: Group of message to remove (%NULL if @id is specified) * * Remove a message by @id or @group. */ void swamigui_statusbar_remove (SwamiguiStatusbar *statusbar, guint id, const char *group) { StatusItem *item; GList *p; g_return_if_fail (SWAMIGUI_IS_STATUSBAR (statusbar)); g_return_if_fail (id != 0 || group != NULL); p = swamigui_statusbar_find (statusbar, id, group); if (!p) return; item = (StatusItem *)(p->data); g_free (item->group); if (item->timeout_handle) /* remove old timeout if any */ g_source_remove (item->timeout_handle); gtk_container_remove (GTK_CONTAINER (statusbar->box), item->frame); statusbar->items = g_list_delete_link (statusbar->items, p); status_item_free (item); } /** * swamigui_statusbar_printf: * @statusbar: Statusbar widget * @format: printf() style format string. * @...: Additional arguments for @format string * * A convenience function to display a message label to a statusbar with the * "default-timeout" property value for the timeout, no group and positioned * left. This is commonly used to display an operation that was performed. */ void swamigui_statusbar_printf (SwamiguiStatusbar *statusbar, const char *format, ...) { GtkWidget *label; va_list args; char *s; va_start (args, format); s = g_strdup_vprintf (format, args); va_end (args); label = swamigui_statusbar_msg_label_new (s, 0); g_free (s); swamigui_statusbar_add (statusbar, NULL, SWAMIGUI_STATUSBAR_TIMEOUT_DEFAULT, SWAMIGUI_STATUSBAR_POS_LEFT, label); } /* internal function used to find a statusbar item */ static GList * swamigui_statusbar_find (SwamiguiStatusbar *statusbar, guint id, const char *group) { StatusItem *item; GList *p; for (p = statusbar->items; p; p = p->next) { item = (StatusItem *)(p->data); /* criteria matches? */ if ((id && item->id == id) || (group && item->group && strcmp (item->group, group) == 0)) return (p); } return (NULL); } /** * swamigui_statusbar_msg_label_new: * @label: Label text to assign to new widget * @maxlen: Maximum length of label widget (sets size, 0 to set to width of @label) * * A helper function to create a label widget for use in a statusbar. Doesn't * do a whole lot beyond just creating a regular #GtkLabel and setting its * max length. */ GtkWidget * swamigui_statusbar_msg_label_new (const char *label, guint maxlen) { GtkWidget *widg; widg = gtk_label_new (label); if (maxlen > 0) gtk_label_set_width_chars (GTK_LABEL (widg), maxlen); gtk_misc_set_alignment (GTK_MISC (widg), 0.0, 0.5); gtk_widget_show_all (widg); return (widg); } /** * swamigui_statusbar_msg_progress_new: * @label: Label text to assign to new widget * @close: Close callback function (%NULL to not have a close button) * * A helper function to create a progress status bar item. */ GtkWidget * swamigui_statusbar_msg_progress_new (const char *label, SwamiguiStatusbarCloseFunc close) { GtkWidget *hbox; GtkWidget *progress; GtkWidget *btn; GtkWidget *image; hbox = gtk_hbox_new (FALSE, 0); progress = gtk_progress_bar_new (); if (label) gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progress), label); gtk_box_pack_start (GTK_BOX (hbox), progress, FALSE, FALSE, 0); if (close) { btn = gtk_button_new (); image = gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_BUTTON); gtk_container_add (GTK_CONTAINER (btn), image); gtk_box_pack_start (GTK_BOX (hbox), btn, FALSE, FALSE, 0); g_object_set_data (G_OBJECT (hbox), "_close", close); g_signal_connect (G_OBJECT (btn), "clicked", G_CALLBACK (swamigui_statusbar_cb_item_close_clicked), hbox); } /* used by swamigui_statusbar_msg_set_progress() */ g_object_set_data (G_OBJECT (hbox), "_progress", progress); gtk_widget_show_all (hbox); return (hbox); } /* callback which gets called when an item close button is clicked */ static void swamigui_statusbar_cb_item_close_clicked (GtkButton *button, gpointer data) { GtkWidget *hbox = (GtkWidget *)data; SwamiguiStatusbarCloseFunc closefunc; StatusItem *statusitem; closefunc = g_object_get_data (G_OBJECT (hbox), "_close"); g_return_if_fail (closefunc != NULL); /* "_item" gets set when it is added to the statusbar */ statusitem = g_object_get_data (G_OBJECT (hbox), "_item"); g_return_if_fail (statusitem != NULL); if (closefunc (statusitem->statusbar, hbox)) swamigui_statusbar_remove (statusitem->statusbar, statusitem->id, NULL); } /** * swamigui_statusbar_msg_set_timeout: * @statusbar: Statusbar widget * @id: Unique ID of message (0 if @group is specified) * @group: Group of message (%NULL if @id is specified) * @timeout: New timeout of message in milliseconds * (see #SwamiguiStatusbarTimeout for special values including * #SWAMIGUI_STATUSBAR_TIMEOUT_FOREVER (0) for no timeout and * #SWAMIGUI_STATUSBAR_TIMEOUT_DEFAULT to use "default-timeout" property * value) * * Modify the timeout of an existing message in the statusbar. Message is * selected by @id or @group. */ void swamigui_statusbar_msg_set_timeout (SwamiguiStatusbar *statusbar, guint id, const char *group, int timeout) { StatusItem *item; GList *p; g_return_if_fail (SWAMIGUI_IS_STATUSBAR (statusbar)); g_return_if_fail (id != 0 || group != NULL); p = swamigui_statusbar_find (statusbar, id, group); if (!p) return; if (timeout == SWAMIGUI_STATUSBAR_TIMEOUT_DEFAULT) timeout = statusbar->default_timeout; item = (StatusItem *)(p->data); if (item->timeout_handle) /* remove old timeout if any */ g_source_remove (item->timeout_handle); item->timeout = timeout; if (timeout) /* add new timeout callback if timeout given */ g_timeout_add (timeout, swamigui_statusbar_item_timeout, item); } /** * swamigui_statusbar_msg_set_label: * @statusbar: Statusbar widget * @id: Unique ID of message (0 if @group is specified) * @group: Group of message (%NULL if @id is specified) * @label: New label text to assign to statusbar item * * Modify the label of an existing message in the statusbar. Message is * selected by @id or @group. This function should only be used for #GtkLabel * widget status items or those created with * swamigui_statusbar_msg_label_new() and swamigui_statusbar_msg_progress_new(). */ void swamigui_statusbar_msg_set_label (SwamiguiStatusbar *statusbar, guint id, const char *group, const char *label) { StatusItem *item; GtkWidget *progress; GList *p; g_return_if_fail (SWAMIGUI_IS_STATUSBAR (statusbar)); g_return_if_fail (id != 0 || group != NULL); p = swamigui_statusbar_find (statusbar, id, group); if (!p) return; item = (StatusItem *)(p->data); progress = g_object_get_data (G_OBJECT (item->widg), "_progress"); g_return_if_fail (GTK_IS_LABEL (item->widg) || progress); if (progress) gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progress), label); else gtk_label_set_text (GTK_LABEL (item->widg), label); } /** * swamigui_statusbar_msg_set_progress: * @statusbar: Statusbar widget * @id: Unique ID of message (0 if @group is specified) * @group: Group of message (%NULL if @id is specified) * @val: New progress value (0.0 to 1.0) * * Modify the progress indicator of an existing message in the statusbar. * Message is selected by @id or @group. This function should only be used for * widget status items created with swamigui_statusbar_msg_progress_new(). */ void swamigui_statusbar_msg_set_progress (SwamiguiStatusbar *statusbar, guint id, const char *group, double val) { GtkWidget *progress; StatusItem *item; GList *p; g_return_if_fail (SWAMIGUI_IS_STATUSBAR (statusbar)); g_return_if_fail (id != 0 || group != NULL); p = swamigui_statusbar_find (statusbar, id, group); if (!p) return; item = (StatusItem *)(p->data); progress = g_object_get_data (G_OBJECT (item->widg), "_progress"); g_return_if_fail (progress != NULL); gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress), val); } swami/src/swamigui/SwamiguiModEdit.c0000644000175000017500000013257311461334205017703 0ustar alessioalessio/* * SwamiguiModEdit.c - User interface modulator editor widget * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include #include #include "SwamiguiModEdit.h" #include "SwamiguiControl.h" #include "SwamiguiPanel.h" #include "widgets/icon-combo.h" #include "icons.h" #include "util.h" #include "i18n.h" enum { PROP_0, PROP_ITEM_SELECTION, PROP_MODULATORS }; /* tree view list stuff */ enum { DEST_LABEL, SRC_PIXBUF, SRC_LABEL, AMT_PIXBUF, AMT_LABEL, AMT_VALUE, MOD_PTR, /* modulator pointer */ NUM_FIELDS }; /* destination combo box tree store fields */ enum { DEST_COLUMN_TEXT, /* Text to display for this group/generator */ DEST_COLUMN_ID, /* Index of group if group ID, generator ID otherwise */ DEST_COLUMN_COUNT }; /* flag set in DEST_COLUMN_ID for group items (unset for generators) */ #define DEST_COLUMN_ID_IS_GROUP 0x100 /* Modulator General Controller palette descriptions */ struct { int ctrlnum; char *descr; } modctrl_descr[] = { { IPATCH_SF2_MOD_CONTROL_NONE, N_("No Controller") }, { IPATCH_SF2_MOD_CONTROL_NOTE_ON_VELOCITY, N_("Note-On Velocity") }, { IPATCH_SF2_MOD_CONTROL_NOTE_NUMBER, N_("Note-On Key Number") }, { IPATCH_SF2_MOD_CONTROL_POLY_PRESSURE, N_("Poly Pressure") }, { IPATCH_SF2_MOD_CONTROL_CHAN_PRESSURE, N_("Channel Pressure") }, { IPATCH_SF2_MOD_CONTROL_PITCH_WHEEL, N_("Pitch Wheel") }, { IPATCH_SF2_MOD_CONTROL_BEND_RANGE, N_("Bend Range") } }; #define MODCTRL_DESCR_COUNT \ (sizeof (modctrl_descr) / sizeof (modctrl_descr[0])) /* MIDI Continuous Controller descriptions */ struct { int ctrlnum; char *descr; } midicc_descr[] = { { 1, N_("Modulation") }, { 2, N_("Breath Controller") }, { 3, N_("Undefined") }, { 4, N_("Foot Controller") }, { 5, N_("Portamento Time") }, { 7, N_("Main Volume") }, { 8, N_("Balance") }, { 9, N_("Undefined") }, { 10, N_("Panpot") }, { 11, N_("Expression Pedal") }, { 12, N_("Effect Control 1") }, { 13, N_("Effect Control 2") }, { 14, N_("Undefined") }, { 15, N_("Undefined") }, { 16, N_("General Purpose 1") }, { 17, N_("General Purpose 2") }, { 18, N_("General Purpose 3") }, { 19, N_("General Purpose 4") }, /* 20-31 Undefined, 33-63 LSB for controllers 1-31 */ { 64, N_("Hold 1 (Damper)") }, { 65, N_("Portamento") }, { 66, N_("Sostenuto") }, { 67, N_("Soft Pedal") }, { 68, N_("Undefined") }, { 69, N_("Hold 2 (Freeze)") }, /* 70-79 Undefined */ { 80, N_("General Purpose 5") }, { 81, N_("General Purpose 6") }, { 82, N_("General Purpose 7") }, { 83, N_("General Purpose 8") }, /* 84-90 Undefined */ { 91, N_("Effect 1 (Reverb)") }, { 92, N_("Effect 2 (Tremolo)") }, { 93, N_("Effect 3 (Chorus)") }, { 94, N_("Effect 4 (Celeste)") }, { 95, N_("Effect 5 (Phaser)") }, { 96, N_("Data Increment") }, { 97, N_("Data Decrement") } /* 102-119 Undefined */ }; #define MIDICC_DESCR_COUNT (sizeof (midicc_descr) / sizeof (midicc_descr[0])) char *modgroup_names[] = { N_("Sample"), N_("Pitch/Effects"), N_("Volume Envelope"), N_("Modulation Envelope"), N_("Modulation LFO"), N_("Vibrato LFO") }; #define MODGROUP_COUNT (sizeof (modgroup_names) / sizeof (modgroup_names[0])) #define MODGROUP_SEPARATOR (-1) int modgroup_gens[] = { /* Sample group */ IPATCH_SF2_GEN_SAMPLE_START, IPATCH_SF2_GEN_SAMPLE_COARSE_START, IPATCH_SF2_GEN_SAMPLE_END, IPATCH_SF2_GEN_SAMPLE_COARSE_END, IPATCH_SF2_GEN_SAMPLE_LOOP_START, IPATCH_SF2_GEN_SAMPLE_COARSE_LOOP_START, IPATCH_SF2_GEN_SAMPLE_LOOP_END, IPATCH_SF2_GEN_SAMPLE_COARSE_LOOP_END, MODGROUP_SEPARATOR, /* Pitch/Effects group */ IPATCH_SF2_GEN_COARSE_TUNE, IPATCH_SF2_GEN_FINE_TUNE_OVERRIDE, IPATCH_SF2_GEN_FILTER_Q, IPATCH_SF2_GEN_FILTER_CUTOFF, IPATCH_SF2_GEN_REVERB, IPATCH_SF2_GEN_CHORUS, IPATCH_SF2_GEN_PAN, MODGROUP_SEPARATOR, /* Volumen Envelope group */ IPATCH_SF2_GEN_VOL_ENV_DELAY, IPATCH_SF2_GEN_VOL_ENV_ATTACK, IPATCH_SF2_GEN_VOL_ENV_HOLD, IPATCH_SF2_GEN_VOL_ENV_DECAY, IPATCH_SF2_GEN_VOL_ENV_SUSTAIN, IPATCH_SF2_GEN_VOL_ENV_RELEASE, IPATCH_SF2_GEN_ATTENUATION, IPATCH_SF2_GEN_NOTE_TO_VOL_ENV_HOLD, IPATCH_SF2_GEN_NOTE_TO_VOL_ENV_DECAY, MODGROUP_SEPARATOR, /* Modulation Envelope group */ IPATCH_SF2_GEN_MOD_ENV_DELAY, IPATCH_SF2_GEN_MOD_ENV_ATTACK, IPATCH_SF2_GEN_MOD_ENV_HOLD, IPATCH_SF2_GEN_MOD_ENV_DECAY, IPATCH_SF2_GEN_MOD_ENV_SUSTAIN, IPATCH_SF2_GEN_MOD_ENV_RELEASE, IPATCH_SF2_GEN_MOD_ENV_TO_PITCH, IPATCH_SF2_GEN_MOD_ENV_TO_FILTER_CUTOFF, IPATCH_SF2_GEN_NOTE_TO_MOD_ENV_HOLD, IPATCH_SF2_GEN_NOTE_TO_MOD_ENV_DECAY, MODGROUP_SEPARATOR, /* Modulation LFO group */ IPATCH_SF2_GEN_MOD_LFO_DELAY, IPATCH_SF2_GEN_MOD_LFO_FREQ, IPATCH_SF2_GEN_MOD_LFO_TO_PITCH, IPATCH_SF2_GEN_MOD_LFO_TO_FILTER_CUTOFF, IPATCH_SF2_GEN_MOD_LFO_TO_VOLUME, MODGROUP_SEPARATOR, /* Vibrato LFO group */ IPATCH_SF2_GEN_VIB_LFO_DELAY, IPATCH_SF2_GEN_VIB_LFO_FREQ, IPATCH_SF2_GEN_VIB_LFO_TO_PITCH, MODGROUP_SEPARATOR }; #define MODGROUP_GENS_SIZE (sizeof (modgroup_gens) / sizeof (modgroup_gens[0])) /* elements for source modulator transform icon combo widget */ static IconComboElement modtransform_elements[] = { { N_("Linear Positive Unipolar"), SWAMIGUI_STOCK_LINEAR_POS_UNI, IPATCH_SF2_MOD_TYPE_LINEAR | IPATCH_SF2_MOD_DIRECTION_POSITIVE | IPATCH_SF2_MOD_POLARITY_UNIPOLAR }, { N_("Linear Negative Unipolar"), SWAMIGUI_STOCK_LINEAR_NEG_UNI, IPATCH_SF2_MOD_TYPE_LINEAR | IPATCH_SF2_MOD_DIRECTION_NEGATIVE | IPATCH_SF2_MOD_POLARITY_UNIPOLAR }, { N_("Linear Positive Bipolar"), SWAMIGUI_STOCK_LINEAR_POS_BI, IPATCH_SF2_MOD_TYPE_LINEAR | IPATCH_SF2_MOD_DIRECTION_POSITIVE | IPATCH_SF2_MOD_POLARITY_BIPOLAR }, { N_("Linear Negative Bipolar"), SWAMIGUI_STOCK_LINEAR_NEG_BI, IPATCH_SF2_MOD_TYPE_LINEAR | IPATCH_SF2_MOD_DIRECTION_NEGATIVE | IPATCH_SF2_MOD_POLARITY_BIPOLAR }, { N_("Concave Positive Unipolar"), SWAMIGUI_STOCK_CONCAVE_POS_UNI, IPATCH_SF2_MOD_TYPE_CONCAVE | IPATCH_SF2_MOD_DIRECTION_POSITIVE | IPATCH_SF2_MOD_POLARITY_UNIPOLAR }, { N_("Concave Negative Unipolar"), SWAMIGUI_STOCK_CONCAVE_NEG_UNI, IPATCH_SF2_MOD_TYPE_CONCAVE | IPATCH_SF2_MOD_DIRECTION_NEGATIVE | IPATCH_SF2_MOD_POLARITY_UNIPOLAR }, { N_("Concave Positive Bipolar"), SWAMIGUI_STOCK_CONCAVE_POS_BI, IPATCH_SF2_MOD_TYPE_CONCAVE | IPATCH_SF2_MOD_DIRECTION_POSITIVE | IPATCH_SF2_MOD_POLARITY_BIPOLAR }, { N_("Concave Negative Bipolar"), SWAMIGUI_STOCK_CONCAVE_NEG_BI, IPATCH_SF2_MOD_TYPE_CONCAVE | IPATCH_SF2_MOD_DIRECTION_NEGATIVE | IPATCH_SF2_MOD_POLARITY_BIPOLAR }, { N_("Convex Positive Unipolar"), SWAMIGUI_STOCK_CONVEX_POS_UNI, IPATCH_SF2_MOD_TYPE_CONVEX | IPATCH_SF2_MOD_DIRECTION_POSITIVE | IPATCH_SF2_MOD_POLARITY_UNIPOLAR }, { N_("Convex Negative Unipolar"), SWAMIGUI_STOCK_CONVEX_NEG_UNI, IPATCH_SF2_MOD_TYPE_CONVEX | IPATCH_SF2_MOD_DIRECTION_NEGATIVE | IPATCH_SF2_MOD_POLARITY_UNIPOLAR }, { N_("Convex Positive Bipolar"), SWAMIGUI_STOCK_CONVEX_POS_BI, IPATCH_SF2_MOD_TYPE_CONVEX | IPATCH_SF2_MOD_DIRECTION_POSITIVE | IPATCH_SF2_MOD_POLARITY_BIPOLAR }, { N_("Convex Negative Bipolar"), SWAMIGUI_STOCK_CONVEX_NEG_BI, IPATCH_SF2_MOD_TYPE_CONVEX | IPATCH_SF2_MOD_DIRECTION_NEGATIVE | IPATCH_SF2_MOD_POLARITY_BIPOLAR }, { N_("Switch Positive Unipolar"), SWAMIGUI_STOCK_SWITCH_POS_UNI, IPATCH_SF2_MOD_TYPE_SWITCH | IPATCH_SF2_MOD_DIRECTION_POSITIVE | IPATCH_SF2_MOD_POLARITY_UNIPOLAR }, { N_("Switch Negative Unipolar"), SWAMIGUI_STOCK_SWITCH_NEG_UNI, IPATCH_SF2_MOD_TYPE_SWITCH | IPATCH_SF2_MOD_DIRECTION_NEGATIVE | IPATCH_SF2_MOD_POLARITY_UNIPOLAR }, { N_("Switch Positive Bipolar"), SWAMIGUI_STOCK_SWITCH_POS_BI, IPATCH_SF2_MOD_TYPE_SWITCH | IPATCH_SF2_MOD_DIRECTION_POSITIVE | IPATCH_SF2_MOD_POLARITY_BIPOLAR }, { N_("Switch Negative Bipolar"), SWAMIGUI_STOCK_SWITCH_NEG_BI, IPATCH_SF2_MOD_TYPE_SWITCH | IPATCH_SF2_MOD_DIRECTION_NEGATIVE | IPATCH_SF2_MOD_POLARITY_BIPOLAR } }; static void swamigui_mod_edit_class_init (SwamiguiModEditClass *klass); static void swamigui_mod_edit_panel_iface_init (SwamiguiPanelIface *panel_iface); static gboolean swamigui_mod_edit_panel_iface_check_selection (IpatchList *selection, GType *selection_types); static void swamigui_mod_edit_init (SwamiguiModEdit *modedit); static void swamigui_mod_edit_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void swamigui_mod_edit_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void swamigui_mod_edit_finalize (GObject *object); static GtkWidget *swamigui_mod_edit_create_list_view(SwamiguiModEdit *modedit); static GtkTreeStore *swamigui_mod_edit_init_dest_combo_box (GtkWidget *combo_dest); static void swamigui_mod_edit_cb_destination_changed (GtkComboBox *combo, gpointer user_data); static gboolean swamigui_mod_edit_real_set_selection (SwamiguiModEdit *modedit, IpatchList *selection); static gboolean swamigui_mod_edit_real_set_mods (SwamiguiModEdit *modedit, IpatchSF2ModList *mods); static void swamigui_mod_edit_cb_mod_select_changed (GtkTreeSelection *selection, SwamiguiModEdit *modedit); static void swamigui_mod_edit_tree_selection_count (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data); static void swamigui_mod_edit_cb_new_clicked (GtkButton *btn, SwamiguiModEdit *modedit); static void swamigui_mod_edit_cb_delete_clicked (GtkButton *btn, SwamiguiModEdit *modedit); static void swamigui_mod_edit_selection_foreach (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data); static void swamigui_mod_edit_cb_pixcombo_changed (IconCombo *pixcombo, int id, SwamiguiModEdit *modedit); static void swamigui_mod_edit_cb_combo_list_select (GtkList *list, GtkWidget *litem, SwamiguiModEdit *modedit); static void swamigui_mod_edit_cb_amtsrc_changed (GtkAdjustment *adj, SwamiguiModEdit *modedit); static void swamigui_mod_edit_add_source_combo_strings (GtkCombo *combo); static void swamigui_mod_edit_update (SwamiguiModEdit *modedit); static void swamigui_mod_edit_update_store_row (SwamiguiModEdit *modedit, GtkTreeIter *iter); static void swamigui_mod_edit_set_active_mod (SwamiguiModEdit *modedit, GtkTreeIter *iter, gboolean force); static gint swamigui_mod_edit_find_ctrl (gconstpointer a, gconstpointer ctrlnum); static char *swamigui_mod_edit_get_control_name (guint16 modsrc); static char *swamigui_mod_edit_find_transform_icon (guint16 modsrc); static int swamigui_mod_edit_find_gen_group (int genid, int *index); static GObjectClass *parent_class = NULL; GType swamigui_mod_edit_get_type (void) { static GType obj_type = 0; if (!obj_type) { static const GTypeInfo obj_info = { sizeof (SwamiguiModEditClass), NULL, NULL, (GClassInitFunc) swamigui_mod_edit_class_init, NULL, NULL, sizeof (SwamiguiModEdit), 0, (GInstanceInitFunc) swamigui_mod_edit_init, }; static const GInterfaceInfo panel_info = { (GInterfaceInitFunc)swamigui_mod_edit_panel_iface_init, NULL, NULL }; obj_type = g_type_register_static (GTK_TYPE_SCROLLED_WINDOW, "SwamiguiModEdit", &obj_info, 0); g_type_add_interface_static (obj_type, SWAMIGUI_TYPE_PANEL, &panel_info); } return (obj_type); } static void swamigui_mod_edit_class_init (SwamiguiModEditClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); parent_class = g_type_class_peek_parent (klass); obj_class->set_property = swamigui_mod_edit_set_property; obj_class->get_property = swamigui_mod_edit_get_property; obj_class->finalize = swamigui_mod_edit_finalize; g_object_class_override_property (obj_class, PROP_ITEM_SELECTION, "item-selection"); g_object_class_install_property (obj_class, PROP_MODULATORS, g_param_spec_boxed ("modulators", _("Modulators"), _("Modulators"), IPATCH_TYPE_SF2_MOD_LIST, G_PARAM_READWRITE)); } static void swamigui_mod_edit_panel_iface_init (SwamiguiPanelIface *panel_iface) { panel_iface->label = _("Modulators"); panel_iface->blurb = _("Edit real time effect controls"); panel_iface->stockid = SWAMIGUI_STOCK_MODULATOR_EDITOR; panel_iface->check_selection = swamigui_mod_edit_panel_iface_check_selection; } static gboolean swamigui_mod_edit_panel_iface_check_selection (IpatchList *selection, GType *selection_types) { /* one item only and with mod item interface */ return (!selection->items->next && g_type_is_a (*selection_types, IPATCH_TYPE_SF2_MOD_ITEM)); } static void swamigui_mod_edit_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { SwamiguiModEdit *modedit = SWAMIGUI_MOD_EDIT (object); switch (property_id) { case PROP_ITEM_SELECTION: swamigui_mod_edit_real_set_selection (modedit, g_value_get_object (value)); break; case PROP_MODULATORS: swamigui_mod_edit_real_set_mods (modedit, (IpatchSF2ModList *)g_value_get_boxed (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_mod_edit_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { SwamiguiModEdit *modedit = SWAMIGUI_MOD_EDIT (object); switch (property_id) { case PROP_ITEM_SELECTION: g_value_set_object (value, modedit->selection); break; case PROP_MODULATORS: g_value_set_boxed (value, modedit->mods); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_mod_edit_finalize (GObject *object) { SwamiguiModEdit *modedit = SWAMIGUI_MOD_EDIT (object); g_object_unref (modedit->modctrl); if (modedit->selection) g_object_unref (modedit->selection); ipatch_sf2_mod_list_free (modedit->mods, TRUE); if (parent_class->finalize) parent_class->finalize (object); } static void swamigui_mod_edit_init (SwamiguiModEdit *modedit) { GtkWidget *glade_widg; GtkWidget *icon; GtkWidget *pixcombo; GtkWidget *widg; gtk_scrolled_window_set_hadjustment (GTK_SCROLLED_WINDOW (modedit), NULL); gtk_scrolled_window_set_vadjustment (GTK_SCROLLED_WINDOW (modedit), NULL); gtk_container_border_width (GTK_CONTAINER (modedit), 0); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (modedit), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); modedit->mod_selected = FALSE; modedit->block_callbacks = FALSE; /* create control for the "modulators" property and add to GUI queue */ modedit->modctrl = SWAMI_CONTROL (swami_get_control_prop_by_name (G_OBJECT (modedit), "modulators")); swamigui_control_set_queue (modedit->modctrl); glade_widg = swamigui_util_glade_create ("ModEdit"); modedit->glade_widg = glade_widg; /* set up modulator tree view list widget */ swamigui_mod_edit_create_list_view (modedit); /* configure callbacks on action buttons */ widg = swamigui_util_glade_lookup (glade_widg, "BTNNew"); g_signal_connect (widg, "clicked", G_CALLBACK (swamigui_mod_edit_cb_new_clicked), modedit); widg = swamigui_util_glade_lookup (glade_widg, "BTNDel"); g_signal_connect (widg, "clicked", G_CALLBACK (swamigui_mod_edit_cb_delete_clicked), modedit); /* nice modulator junction icon */ icon = gtk_image_new_from_stock (SWAMIGUI_STOCK_MODULATOR_JUNCT, SWAMIGUI_ICON_SIZE_CUSTOM_LARGE1); gtk_widget_show (icon); widg = swamigui_util_glade_lookup (glade_widg, "HBXIcon"); gtk_box_pack_start (GTK_BOX (widg), icon, FALSE, 0, 0); gtk_box_reorder_child (GTK_BOX (widg), icon, 0); /* create source modulator icon combo */ pixcombo = icon_combo_new (modtransform_elements, 4, 4); gtk_widget_show (pixcombo); g_object_set_data (G_OBJECT (glade_widg), "PIXSrc", pixcombo); widg = swamigui_util_glade_lookup (glade_widg, "HBXSrc"); gtk_box_pack_start (GTK_BOX (widg), pixcombo, FALSE, 0, 0); gtk_box_reorder_child (GTK_BOX (widg), pixcombo, 0); g_signal_connect (pixcombo, "changed", G_CALLBACK (swamigui_mod_edit_cb_pixcombo_changed), modedit); /* create amount source modulator icon combo */ pixcombo = icon_combo_new (modtransform_elements, 4, 4); gtk_widget_show (pixcombo); g_object_set_data (G_OBJECT (glade_widg), "PIXAmtSrc", pixcombo); widg = swamigui_util_glade_lookup (glade_widg, "HBXAmtSrc"); gtk_box_pack_start (GTK_BOX (widg), pixcombo, FALSE, 0, 0); gtk_box_reorder_child (GTK_BOX (widg), pixcombo, 0); g_signal_connect (pixcombo, "changed", G_CALLBACK (swamigui_mod_edit_cb_pixcombo_changed), modedit); /* add modulator source controller description strings to combos */ widg = swamigui_util_glade_lookup (glade_widg, "COMSrcCtrl"); swamigui_mod_edit_add_source_combo_strings (GTK_COMBO (widg)); g_signal_connect (GTK_COMBO (widg)->list, "select-child", G_CALLBACK (swamigui_mod_edit_cb_combo_list_select), modedit); widg = swamigui_util_glade_lookup (glade_widg, "COMAmtCtrl"); swamigui_mod_edit_add_source_combo_strings (GTK_COMBO (widg)); g_signal_connect (GTK_COMBO (widg)->list, "select-child", G_CALLBACK (swamigui_mod_edit_cb_combo_list_select), modedit); /* add value changed signal to amount spin button */ widg = swamigui_util_glade_lookup (glade_widg, "SPBAmount"); g_signal_connect (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (widg)), "value-changed", G_CALLBACK (swamigui_mod_edit_cb_amtsrc_changed), modedit); /* add generator groups to option menu */ widg = swamigui_util_glade_lookup (glade_widg, "ComboDestination"); modedit->dest_store = swamigui_mod_edit_init_dest_combo_box (widg); gtk_combo_box_set_model (GTK_COMBO_BOX (widg), GTK_TREE_MODEL (modedit->dest_store)); g_signal_connect (widg, "changed", G_CALLBACK (swamigui_mod_edit_cb_destination_changed), modedit); swamigui_mod_edit_set_active_mod (modedit, NULL, TRUE); /* disable editor */ gtk_widget_show (glade_widg); gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (modedit), glade_widg); } static GtkWidget * swamigui_mod_edit_create_list_view (SwamiguiModEdit *modedit) { GtkWidget *tree; GtkTreeSelection *sel; GtkListStore *store; GtkCellRenderer *renderer; GtkTreeViewColumn *column; tree = swamigui_util_glade_lookup (modedit->glade_widg, "ModList"); store = gtk_list_store_new (NUM_FIELDS, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_INT, IPATCH_TYPE_SF2_MOD); gtk_tree_view_set_model (GTK_TREE_VIEW (tree), GTK_TREE_MODEL (store)); modedit->tree_view = tree; modedit->list_store = store; sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree)); gtk_tree_selection_set_mode (sel, GTK_SELECTION_MULTIPLE); g_signal_connect (sel, "changed", G_CALLBACK (swamigui_mod_edit_cb_mod_select_changed), modedit); /* Disable tree view search, since it breaks piano key playback */ g_object_set (tree, "enable-search", FALSE, NULL); /* destination label column */ renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes (_("Destination"), renderer, "text", DEST_LABEL, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column); /* source pixbuf and label column */ renderer = gtk_cell_renderer_pixbuf_new (); column = gtk_tree_view_column_new_with_attributes (_("Source"), renderer, "pixbuf", SRC_PIXBUF, NULL); renderer = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (column, renderer, TRUE); gtk_tree_view_column_set_attributes (column, renderer, "text", SRC_LABEL, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column); /* amount source pixbuf and label column */ renderer = gtk_cell_renderer_pixbuf_new (); column = gtk_tree_view_column_new_with_attributes (_("Amount Source"), renderer, "pixbuf", AMT_PIXBUF, NULL); renderer = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (column, renderer, TRUE); gtk_tree_view_column_set_attributes (column, renderer, "text", AMT_LABEL, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column); /* amount value column */ renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes (_("Amount"), renderer, "text", AMT_VALUE, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column); return (tree); } static GtkTreeStore * swamigui_mod_edit_init_dest_combo_box (GtkWidget *combo_dest) { GtkCellRenderer *renderer; GtkTreeStore *store; GtkTreeIter group_iter, gen_iter; int group, gen; char *name; store = gtk_tree_store_new (DEST_COLUMN_COUNT, G_TYPE_STRING, G_TYPE_INT); for (group = 0, gen = 0; group < MODGROUP_COUNT; group++) { /* append group name */ gtk_tree_store_append (store, &group_iter, NULL); gtk_tree_store_set (store, &group_iter, DEST_COLUMN_TEXT, modgroup_names[group], DEST_COLUMN_ID, DEST_COLUMN_ID_IS_GROUP | group, -1); while (modgroup_gens[gen] != MODGROUP_SEPARATOR) { gtk_tree_store_append (store, &gen_iter, &group_iter); name = ipatch_sf2_gen_info[modgroup_gens[gen]].label; gtk_tree_store_set (store, &gen_iter, DEST_COLUMN_TEXT, name, DEST_COLUMN_ID, modgroup_gens[gen], -1); gen++; } gen++; } renderer = gtk_cell_renderer_text_new (); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_dest), renderer, TRUE); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_dest), renderer, "text", DEST_COLUMN_TEXT, NULL); return (store); } /** * swamigui_mod_edit_new: * * Create a new modulator editor object * * Returns: New widget of type SwamiguiModEdit */ GtkWidget * swamigui_mod_edit_new (void) { return (GTK_WIDGET (gtk_type_new (swamigui_mod_edit_get_type ()))); } /** * swamigui_mod_edit_set_selection: * @modedit: Modulation editor object * @selection: Item selection to assign to modulator editor or %NULL (should * currently contain one item only) * * Set item to edit modulator list of. If @item does not implement the * #IpatchSF2ModItem interface then it is deactivated. */ void swamigui_mod_edit_set_selection (SwamiguiModEdit *modedit, IpatchList *selection) { if (swamigui_mod_edit_real_set_selection (modedit, selection)) g_object_notify (G_OBJECT (modedit), "item-selection"); } static gboolean swamigui_mod_edit_real_set_selection (SwamiguiModEdit *modedit, IpatchList *selection) { GObject *item = NULL; g_return_val_if_fail (modedit != NULL, FALSE); g_return_val_if_fail (SWAMIGUI_IS_MOD_EDIT (modedit), FALSE); g_return_val_if_fail (!selection || IPATCH_IS_LIST (selection), FALSE); /* valid if single item and it implements the IpatchSF2ModItem interface */ if (selection && selection->items && !selection->items->next && g_type_is_a (G_OBJECT_TYPE (selection->items->data), IPATCH_TYPE_SF2_MOD_ITEM)) item = G_OBJECT (selection->items->data); if (!item) selection = NULL; /* same item already selected? */ if ((!selection && !modedit->selection) || (selection && modedit->selection && selection->items->data == modedit->selection->items->data)) return (FALSE); if (modedit->selection) g_object_unref (modedit->selection); if (selection) modedit->selection = g_object_ref (selection); else modedit->selection = NULL; /* disconnect any current connections to modulator editor "modulators" */ swami_control_disconnect_all (modedit->modctrl); if (modedit->mods) { ipatch_sf2_mod_list_free (modedit->mods, TRUE); modedit->mods = NULL; } /* connect modulator editor to item "modulators" property */ if (item) { swami_control_prop_connect_objects (G_OBJECT (item), "modulators", G_OBJECT (modedit), NULL, SWAMI_CONTROL_CONN_BIDIR); g_object_get (item, "modulators", &modedit->mods, NULL); } swamigui_mod_edit_update (modedit); return (TRUE); } /** * swamigui_mod_edit_set_mods: * @modedit: Modulation editor object * @mods: List of modulators to assign to modulator editor object, and thus its * active item's modulators as well. List is duplicated. * * Assign modulators to a modulator editor object and the item it is editing. */ void swamigui_mod_edit_set_mods (SwamiguiModEdit *modedit, IpatchSF2ModList *mods) { if (swamigui_mod_edit_real_set_mods (modedit, mods)) g_object_notify ((GObject *)modedit, "modulators"); } static gboolean swamigui_mod_edit_real_set_mods (SwamiguiModEdit *modedit, IpatchSF2ModList *mods) { g_return_val_if_fail (SWAMIGUI_IS_MOD_EDIT (modedit), FALSE); if (modedit->mods) ipatch_sf2_mod_list_free (modedit->mods, TRUE); modedit->mods = ipatch_sf2_mod_list_duplicate (mods); swamigui_mod_edit_update (modedit); return (TRUE); } typedef struct { int count; GtkTreeIter iter; } ForeachSelBag; /* callback for when a modulator gets selected in the list */ static void swamigui_mod_edit_cb_mod_select_changed (GtkTreeSelection *selection, SwamiguiModEdit *modedit) { ForeachSelBag selbag; selbag.count = 0; /* count selection and get first selected iter */ gtk_tree_selection_selected_foreach (selection, swamigui_mod_edit_tree_selection_count, &selbag); if (selbag.count == 1) swamigui_mod_edit_set_active_mod (modedit, &selbag.iter, FALSE); else /* disable editor */ swamigui_mod_edit_set_active_mod (modedit, NULL, TRUE); } static void swamigui_mod_edit_tree_selection_count (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { ForeachSelBag *selbag = (ForeachSelBag *)data; selbag->count += 1; if (selbag->count == 1) selbag->iter = *iter; } /* callback for new modulator button click */ static void swamigui_mod_edit_cb_new_clicked (GtkButton *btn, SwamiguiModEdit *modedit) { GtkTreeIter iter; GtkTreeSelection *selection; IpatchSF2Mod *mod; if (!modedit->selection) return; mod = ipatch_sf2_mod_new (); modedit->mods = ipatch_sf2_mod_list_insert (modedit->mods, mod, -1); g_object_notify ((GObject *)modedit, "modulators"); gtk_list_store_append (modedit->list_store, &iter); gtk_list_store_set (modedit->list_store, &iter, MOD_PTR, mod, -1); ipatch_sf2_mod_free (mod); /* select the new item */ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (modedit->tree_view)); gtk_tree_selection_unselect_all (selection); gtk_tree_selection_select_iter (selection, &iter); swamigui_mod_edit_update_store_row (modedit, &iter); } /* callback for delete modulator button click */ static void swamigui_mod_edit_cb_delete_clicked (GtkButton *btn, SwamiguiModEdit *modedit) { GtkTreeSelection *sel; GtkTreeIter *iter; GList *sel_iters = NULL, *p; IpatchSF2Mod *mod; gboolean changed; gboolean anychanged = FALSE; if (!modedit->selection) return; sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (modedit->tree_view)); gtk_tree_selection_selected_foreach (sel, swamigui_mod_edit_selection_foreach, &sel_iters); p = sel_iters; while (p) { iter = (GtkTreeIter *)(p->data); gtk_tree_model_get (GTK_TREE_MODEL (modedit->list_store), iter, MOD_PTR, &mod, -1); if (mod) { modedit->mods = ipatch_sf2_mod_list_remove (modedit->mods, mod, &changed); if (changed) anychanged = TRUE; } gtk_list_store_remove (modedit->list_store, iter); ipatch_sf2_mod_free (mod); /* ## FREE mod from gtk_tree_model_get */ gtk_tree_iter_free (iter); p = g_list_next (p); } g_list_free (sel_iters); if (anychanged) g_object_notify ((GObject *)modedit, "modulators"); } /* a tree selection foreach callback to remove selected modulators */ static void swamigui_mod_edit_selection_foreach (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { GList **sel_iters = (GList **)data; GtkTreeIter *copy; copy = gtk_tree_iter_copy (iter); *sel_iters = g_list_append (*sel_iters, copy); } /* callback when destination combo box is changed */ static void swamigui_mod_edit_cb_destination_changed (GtkComboBox *combo, gpointer user_data) { SwamiguiModEdit *modedit = SWAMIGUI_MOD_EDIT (user_data); IpatchSF2Mod *oldmod, newmod; GtkTreeIter iter, parent; GtkWidget *label; int groupid, genid; char *s; if (modedit->block_callbacks || !modedit->mod_selected) return; label = swamigui_util_glade_lookup (modedit->glade_widg, "LabelDestination"); /* get active combo box item iterator and its parent group, return if none */ if (!gtk_combo_box_get_active_iter (combo, &iter) || !gtk_tree_model_iter_parent (GTK_TREE_MODEL (modedit->dest_store), &parent, &iter)) { gtk_label_set_text (GTK_LABEL (label), ""); return; } /* get the group ID value */ gtk_tree_model_get (GTK_TREE_MODEL (modedit->dest_store), &parent, DEST_COLUMN_ID, &groupid, -1); groupid &= ~DEST_COLUMN_ID_IS_GROUP; /* mask off the IS group flag */ s = g_strdup_printf ("%s", modgroup_names[groupid]); gtk_label_set_markup (GTK_LABEL (label), s); g_free (s); /* get the generator ID of the selected item */ gtk_tree_model_get (GTK_TREE_MODEL (modedit->dest_store), &iter, DEST_COLUMN_ID, &genid, -1); /* get current modulator values (gtk_tree_model_get duplicates mod) */ gtk_tree_model_get (GTK_TREE_MODEL (modedit->list_store), &modedit->mod_iter, MOD_PTR, &oldmod, -1); newmod = *oldmod; newmod.dest = genid; /* set the modulator values in the modulator list and notify property */ if (ipatch_sf2_mod_list_change (modedit->mods, oldmod, &newmod)) g_object_notify ((GObject *)modedit, "modulators"); ipatch_sf2_mod_free (oldmod); /* free oldmod from gtk_tree_model_get */ /* update the modulator in the list store */ gtk_list_store_set (modedit->list_store, &modedit->mod_iter, MOD_PTR, &newmod, -1); swamigui_mod_edit_update_store_row (modedit, &modedit->mod_iter); } /* callback for modulator source controller transform icon combo change */ static void swamigui_mod_edit_cb_pixcombo_changed (IconCombo *pixcombo, int id, SwamiguiModEdit *modedit) { IpatchSF2Mod *oldmod, newmod; guint16 *src; if (modedit->block_callbacks || !modedit->mod_selected) return; /* get current modulator values (gtk_tree_model_get duplicates mod) */ gtk_tree_model_get (GTK_TREE_MODEL (modedit->list_store), &modedit->mod_iter, MOD_PTR, &oldmod, -1); newmod = *oldmod; /* duplicate modulator values */ if (pixcombo == g_object_get_data (G_OBJECT (modedit->glade_widg), "PIXSrc")) src = &newmod.src; else src = &newmod.amtsrc; *src &= ~(IPATCH_SF2_MOD_MASK_TYPE | IPATCH_SF2_MOD_MASK_DIRECTION | IPATCH_SF2_MOD_MASK_POLARITY); *src |= id; /* set the modulator values in the modulator list and notify property */ if (ipatch_sf2_mod_list_change (modedit->mods, oldmod, &newmod)) g_object_notify ((GObject *)modedit, "modulators"); ipatch_sf2_mod_free (oldmod); /* free oldmod from gtk_tree_model_get */ /* update the modulator in the list store */ gtk_list_store_set (modedit->list_store, &modedit->mod_iter, MOD_PTR, &newmod, -1); swamigui_mod_edit_update_store_row (modedit, &modedit->mod_iter); } /* callback for modulator source controller combo list */ static void swamigui_mod_edit_cb_combo_list_select (GtkList *list, GtkWidget *litem, SwamiguiModEdit *modedit) { IpatchSF2Mod *oldmod, newmod; GtkWidget *widg; guint16 *src; int ctrl; if (modedit->block_callbacks || !modedit->mod_selected) return; /* get current modulator values (gtk_tree_model_get duplicates mod) */ gtk_tree_model_get (GTK_TREE_MODEL (modedit->list_store), &modedit->mod_iter, MOD_PTR, &oldmod, -1); newmod = *oldmod; /* duplicate modulator values */ /* which source controller combo list? */ widg = swamigui_util_glade_lookup (modedit->glade_widg, "COMSrcCtrl"); if ((void *)list == (void *)(GTK_COMBO (widg)->list)) src = &newmod.src; else src = &newmod.amtsrc; ctrl = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (litem), "ctrlnum")); *src &= ~(IPATCH_SF2_MOD_MASK_CONTROL | IPATCH_SF2_MOD_MASK_CC); *src |= ctrl; /* set the modulator values in the modulator list and notify property */ if (ipatch_sf2_mod_list_change (modedit->mods, oldmod, &newmod)) g_object_notify ((GObject *)modedit, "modulators"); ipatch_sf2_mod_free (oldmod); /* free oldmod from gtk_tree_model_get */ /* update the modulator in the list store */ gtk_list_store_set (modedit->list_store, &modedit->mod_iter, MOD_PTR, &newmod, -1); swamigui_mod_edit_update_store_row (modedit, &modedit->mod_iter); } /* callback for modulator amount source spin button value change */ static void swamigui_mod_edit_cb_amtsrc_changed (GtkAdjustment *adj, SwamiguiModEdit *modedit) { IpatchSF2Mod *oldmod, newmod; if (modedit->block_callbacks || !modedit->mod_selected) return; /* get current modulator values (gtk_tree_model_get duplicates mod) */ gtk_tree_model_get (GTK_TREE_MODEL (modedit->list_store), &modedit->mod_iter, MOD_PTR, &oldmod, -1); newmod = *oldmod; /* duplicate modulator values */ newmod.amount = (gint16)(adj->value); /* set the modulator values in the modulator list and notify property */ if (ipatch_sf2_mod_list_change (modedit->mods, oldmod, &newmod)) g_object_notify ((GObject *)modedit, "modulators"); ipatch_sf2_mod_free (oldmod); /* free oldmod from gtk_tree_model_get */ /* update the modulator in the list store */ gtk_list_store_set (modedit->list_store, &modedit->mod_iter, MOD_PTR, &newmod, -1); swamigui_mod_edit_update_store_row (modedit, &modedit->mod_iter); } /* add modulator source controller descriptions to a combo list */ static void swamigui_mod_edit_add_source_combo_strings (GtkCombo *combo) { GtkWidget *item; char *descr, *s; int i, descrndx; /* add controls from the General Controller palette */ for (i = 0; i < MODCTRL_DESCR_COUNT; i++) { item = gtk_list_item_new_with_label (_(modctrl_descr[i].descr)); gtk_widget_show (item); g_object_set_data (G_OBJECT (item), "ctrlnum", GINT_TO_POINTER (modctrl_descr[i].ctrlnum)); gtk_container_add (GTK_CONTAINER (GTK_COMBO (combo)->list), item); } /* loop over all MIDI CC controllers up to last valid one (119) */ for (i = 0, descrndx = 0; i < 120; i++) { if (midicc_descr[descrndx].ctrlnum == i) { descr = _(midicc_descr[descrndx].descr); if (descrndx < MIDICC_DESCR_COUNT - 1) descrndx++; } else if ((i >= 20 && i <= 31) || (i >= 70 && i <= 79) || (i >= 84 && i <= 90) || (i >= 102 && i <= 119)) descr = _("Undefined"); else descr = NULL; if (descr) { s = g_strdup_printf (_("CC %d %s"), i, descr); item = gtk_list_item_new_with_label (s); gtk_widget_show (item); g_free (s); /* use the MIDI ctrl number with the modulator CC flag set */ g_object_set_data (G_OBJECT (item), "ctrlnum", GINT_TO_POINTER (i | IPATCH_SF2_MOD_CC_MIDI)); gtk_container_add (GTK_CONTAINER (GTK_COMBO (combo)->list), item); } } } /* synchronizes modulator editor to current modulator list */ static void swamigui_mod_edit_update (SwamiguiModEdit *modedit) { GtkTreeIter iter; GSList *p; gtk_list_store_clear (modedit->list_store); swamigui_mod_edit_set_active_mod (modedit, NULL, FALSE); /* disable editor */ if (!modedit->mods) return; for (p = modedit->mods; p; p = p->next) { gtk_list_store_append (modedit->list_store, &iter); gtk_list_store_set (modedit->list_store, &iter, MOD_PTR, (IpatchSF2Mod *)(p->data), -1); swamigui_mod_edit_update_store_row (modedit, &iter); } } /* update a modulator in the list view */ static void swamigui_mod_edit_update_store_row (SwamiguiModEdit *modedit, GtkTreeIter *iter) { GdkPixbuf *pixbuf; char *stock_id; int group; IpatchSF2Mod *mod; char *s; /* `mod' will be newly allocated */ gtk_tree_model_get (GTK_TREE_MODEL (modedit->list_store), iter, MOD_PTR, &mod, -1); /* set mod destination label */ group = swamigui_mod_edit_find_gen_group (mod->dest, NULL); if (group >= 0) s = g_strdup_printf ("%s: %s", _(modgroup_names[group]), _(ipatch_sf2_gen_info[mod->dest].label)); else s = g_strdup_printf (_("Invalid (genid = %d)"), mod->dest); gtk_list_store_set (modedit->list_store, iter, DEST_LABEL, s, -1); g_free (s); /* set source pixbuf */ stock_id = swamigui_mod_edit_find_transform_icon (mod->src); if (stock_id) { pixbuf = gtk_widget_render_icon (modedit->tree_view, stock_id, GTK_ICON_SIZE_SMALL_TOOLBAR, NULL); gtk_list_store_set (modedit->list_store, iter, SRC_PIXBUF, pixbuf, -1); } /* set source label */ s = swamigui_mod_edit_get_control_name (mod->src); gtk_list_store_set (modedit->list_store, iter, SRC_LABEL, s, -1); g_free (s); stock_id = swamigui_mod_edit_find_transform_icon (mod->amtsrc); if (stock_id) { pixbuf = gtk_widget_render_icon (modedit->tree_view, stock_id, GTK_ICON_SIZE_SMALL_TOOLBAR, NULL); gtk_list_store_set (modedit->list_store, iter, AMT_PIXBUF, pixbuf, -1); } /* set amount source label */ s = swamigui_mod_edit_get_control_name (mod->amtsrc); gtk_list_store_set (modedit->list_store, iter, AMT_LABEL, s, -1); g_free (s); /* set amount value */ gtk_list_store_set (modedit->list_store, iter, AMT_VALUE, mod->amount, -1); ipatch_sf2_mod_free (mod); /* ## FREE modulator from gtk_tree_model_get */ } /* set the modulator that is being edited, or NULL to disable. */ static void swamigui_mod_edit_set_active_mod (SwamiguiModEdit *modedit, GtkTreeIter *iter, gboolean force) { GtkWidget *pixsrc, *comsrc, *comdst, *lbldst, *spbamt, *pixamt, *comamt; GtkTreeIter destiter; IpatchSF2Mod *mod = NULL; GtkWidget *gw; GList *children, *found; int transform, ctrlnum, group, index; int pathcmp = 1; char *pathstr; char *s; /* get paths for new and current GtkTreeIter and compare them to see if request to set already set modulator */ if (iter && modedit->mod_selected) { GtkTreePath *newpath, *curpath; newpath = gtk_tree_model_get_path (GTK_TREE_MODEL (modedit->list_store), iter); curpath = gtk_tree_model_get_path (GTK_TREE_MODEL (modedit->list_store), &modedit->mod_iter); pathcmp = gtk_tree_path_compare (newpath, curpath); gtk_tree_path_free (newpath); gtk_tree_path_free (curpath); } else if (!iter && !modedit->mod_selected) pathcmp = 0; /* already disabled */ if (!force && pathcmp == 0) return; if (iter) { modedit->mod_selected = TRUE; modedit->mod_iter = *iter; gtk_tree_model_get (GTK_TREE_MODEL (modedit->list_store), iter, MOD_PTR, &mod, -1); } else modedit->mod_selected = FALSE; gw = modedit->glade_widg; pixsrc = g_object_get_data (G_OBJECT (gw), "PIXSrc"); comsrc = swamigui_util_glade_lookup (gw, "COMSrcCtrl"); comdst = swamigui_util_glade_lookup (gw, "ComboDestination"); lbldst = swamigui_util_glade_lookup (gw, "LabelDestination"); spbamt = swamigui_util_glade_lookup (gw, "SPBAmount"); pixamt = g_object_get_data (G_OBJECT (gw), "PIXAmtSrc"); comamt = swamigui_util_glade_lookup (gw, "COMAmtCtrl"); gtk_widget_set_sensitive (pixsrc, mod != NULL); gtk_widget_set_sensitive (comsrc, mod != NULL); gtk_widget_set_sensitive (comdst, mod != NULL); gtk_widget_set_sensitive (spbamt, mod != NULL); gtk_widget_set_sensitive (pixamt, mod != NULL); gtk_widget_set_sensitive (comamt, mod != NULL); modedit->block_callbacks = TRUE; /* block signal callbacks */ /* set transform icon for source control */ transform = mod ? mod->src & (IPATCH_SF2_MOD_MASK_TYPE | IPATCH_SF2_MOD_MASK_POLARITY | IPATCH_SF2_MOD_MASK_DIRECTION) : 0; icon_combo_select_icon (ICON_COMBO (pixsrc), transform); /* set control combo for source control */ ctrlnum = mod ? mod->src & (IPATCH_SF2_MOD_MASK_CONTROL | IPATCH_SF2_MOD_MASK_CC) : 0; children = gtk_container_children (GTK_CONTAINER (GTK_COMBO (comsrc)->list)); found = g_list_find_custom (children, GINT_TO_POINTER (ctrlnum), (GCompareFunc)swamigui_mod_edit_find_ctrl); if (found) gtk_list_select_child (GTK_LIST (GTK_COMBO (comsrc)->list), GTK_WIDGET (found->data)); else gtk_list_select_item (GTK_LIST (GTK_COMBO (comsrc)->list), 0); g_list_free (children); /* set destination generator group option menu */ group = mod ? swamigui_mod_edit_find_gen_group (mod->dest, &index) : -1; if (group >= 0) { /* create group:index path string to select active combo box destination generator */ pathstr = g_strdup_printf ("%d:%d", group, index); /* ++ alloc */ if (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (modedit->dest_store), &destiter, pathstr)) gtk_combo_box_set_active_iter (GTK_COMBO_BOX (comdst), &destiter); g_free (pathstr); /* -- free */ s = g_strdup_printf ("%s", modgroup_names[group]); gtk_label_set_markup (GTK_LABEL (lbldst), s); g_free (s); } else { gtk_combo_box_set_active (GTK_COMBO_BOX (comdst), -1); gtk_label_set_text (GTK_LABEL (lbldst), ""); } /* set amount spin button */ gtk_spin_button_set_value (GTK_SPIN_BUTTON (spbamt), mod ? mod->amount : 0); /* set transform icon for amount source control */ transform = mod ? mod->amtsrc & (IPATCH_SF2_MOD_MASK_TYPE | IPATCH_SF2_MOD_MASK_POLARITY | IPATCH_SF2_MOD_MASK_DIRECTION) : 0; icon_combo_select_icon (ICON_COMBO (pixamt), transform); /* set control combo for amount source control */ ctrlnum = mod ? mod->amtsrc & (IPATCH_SF2_MOD_MASK_CONTROL | IPATCH_SF2_MOD_MASK_CC) : 0; children = gtk_container_children (GTK_CONTAINER (GTK_COMBO (comamt)->list)); found = g_list_find_custom (children, GINT_TO_POINTER (ctrlnum), (GCompareFunc)swamigui_mod_edit_find_ctrl); if (found) gtk_list_select_child (GTK_LIST (GTK_COMBO (comamt)->list), GTK_WIDGET (found->data)); else gtk_list_select_item (GTK_LIST (GTK_COMBO (comamt)->list), 0); g_list_free (children); modedit->block_callbacks = FALSE; /* unblock callbacks */ if (mod) ipatch_sf2_mod_free (mod); } /* a GCompareFunc for g_list_find_custom to locate a child GtkListItem in a list with a particular modulator control index */ static gint swamigui_mod_edit_find_ctrl (gconstpointer a, gconstpointer ctrlnum) { GtkListItem *litem = GTK_LIST_ITEM ((GtkListItem *)a); return (!(g_object_get_data (G_OBJECT (litem), "ctrlnum") == ctrlnum)); } /* returns a description for the control of a modulator source enumeration, string should be freed when finished with */ static char * swamigui_mod_edit_get_control_name (guint16 modsrc) { int ctrlnum, i; ctrlnum = modsrc & IPATCH_SF2_MOD_MASK_CONTROL; if (modsrc & IPATCH_SF2_MOD_MASK_CC) { /* MIDI CC controller */ if ((ctrlnum >= 20 && ctrlnum <= 31) || (ctrlnum >= 70 && ctrlnum <= 79) || (ctrlnum >= 84 && ctrlnum <= 90) || (ctrlnum >= 102 && ctrlnum <= 119)) return (g_strdup_printf (_("CC %d Undefined"), ctrlnum)); /* loop over control descriptions */ for (i = 0; i < MIDICC_DESCR_COUNT; i++) { if (midicc_descr[i].ctrlnum == ctrlnum) return (g_strdup_printf (_("CC %d %s"), ctrlnum, _(midicc_descr[i].descr))); } } else { /* general modulator source controller */ for (i = 0; i < MODCTRL_DESCR_COUNT; i++) { if (modctrl_descr[i].ctrlnum == ctrlnum) return (g_strdup (_(modctrl_descr[i].descr))); } } return (g_strdup_printf (_("Invalid (cc = %d, index = %d)"), ((modsrc & IPATCH_SF2_MOD_MASK_CC) != 0), ctrlnum)); } /* returns the icon stock ID for the transform type of the given modulator source enumeration or NULL if invalid */ static char * swamigui_mod_edit_find_transform_icon (guint16 modsrc) { int transform; int i; transform = modsrc & (IPATCH_SF2_MOD_MASK_TYPE | IPATCH_SF2_MOD_MASK_POLARITY | IPATCH_SF2_MOD_MASK_DIRECTION); for (i = 0; i < 16; i++) { if (modtransform_elements[i].id == transform) return (modtransform_elements[i].stock_id); } return (NULL); } /* determines the group a generator is part of and returns the group index or -1 if generator is not a valid modulator source, if index != NULL then the index within the group is stored in it */ static int swamigui_mod_edit_find_gen_group (int genid, int *index) { int group = 0; int i, groupndx = 0; for (i = 0; i < MODGROUP_GENS_SIZE; i++) { if (modgroup_gens[i] != MODGROUP_SEPARATOR) { if (modgroup_gens[i] == genid) break; groupndx++; } else /* group separator */ { group++; groupndx = 0; } } if (index) *index = groupndx; if (i < MODGROUP_GENS_SIZE) return (group); else return (-1); } swami/src/swamigui/main.c0000644000175000017500000001370411466101732015570 0ustar alessioalessio/* * main.c - Main routine to kick things off * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef PYTHON_SUPPORT #include #endif #include #include #include /* for getenv() */ #include #include #include "SwamiguiRoot.h" #include "swami_python.h" #include "i18n.h" static void log_python_output_func (const char *output, gboolean is_stderr); /* global boolean feature hacks */ extern gboolean swamigui_disable_python; extern gboolean swamigui_disable_plugins; int main (int argc, char *argv[]) { SwamiguiRoot *root = NULL; gboolean show_version = FALSE; gboolean default_prefs = FALSE; gchar **scripts = NULL; gchar **files = NULL; const char *loadfile; char *fname; GOptionContext *context; GError *err = NULL; gchar **sptr; GOptionEntry entries[] = { { "version", 'V', 0, G_OPTION_ARG_NONE, &show_version, "Display Swami version number", NULL }, { "run-script", 'r', 0, G_OPTION_ARG_FILENAME_ARRAY, &scripts, "Run one or more Python scripts on startup", NULL }, { "no-plugins", 'p', 0, G_OPTION_ARG_NONE, &swamigui_disable_plugins, "Don't load plugins", NULL}, { "default-prefs", 'd', 0, G_OPTION_ARG_NONE, &default_prefs, "Use default preferences", NULL }, { "disable-python", 'y', 0, G_OPTION_ARG_NONE, &swamigui_disable_python, "Disable runtime Python support", NULL }, { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY, &files, NULL, "[file1.sf2 file2.sf2 ...]" }, { NULL } }; /* FIXME - Kind of a hack, to use relative dirs for GdkPixbuf loaders on WIN32 */ #ifdef MINGW32 g_setenv ("GDK_PIXBUF_MODULE_FILE", "lib/gdk-pixbuf-2.0/2.10.0/loaders.cache", TRUE); g_setenv ("GDK_PIXBUF_MODULEDIR", "lib/gdk-pixbuf-2.0/2.10.0/loaders", TRUE); #endif #if defined(ENABLE_NLS) bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); #endif context = g_option_context_new (NULL); g_option_context_add_main_entries (context, entries, PACKAGE); g_option_context_add_group (context, gtk_get_option_group (TRUE)); if (!g_option_context_parse (context, &argc, &argv, &err)) { g_print ("option parsing failed: %s\n", err->message); return (1); } if (show_version) { g_print ("Swami %s\n", VERSION); return (0); } swamigui_init (&argc, &argv); root = swamigui_root_new (); /* ++ ref root */ /* Load preferences unless disabled */ if (!default_prefs) swamigui_root_load_prefs (root); /* Activate the Swami object */ swamigui_root_activate (root); /* just for me for that added convenience, yah -:] */ if ((loadfile = g_getenv ("SWAMI_LOAD_FILE"))) swami_root_patch_load (SWAMI_ROOT (root), loadfile, NULL, NULL); /* loop over command line non-options, assuming they're files to open */ if (files) { GtkRecentManager *manager; char *file_uri; for (sptr = files; *sptr; sptr++) { /* first try and parse argument as a URI (in case we are called from recent files subsystem), then just use it as a plain file name */ if (!(fname = g_filename_from_uri (*sptr, NULL, NULL))) fname = g_strdup (*sptr); if (swami_root_patch_load (SWAMI_ROOT (root), fname, NULL, &err)) { /* Add file to recent chooser list */ if ((file_uri = g_filename_to_uri (fname, NULL, NULL))) { manager = gtk_recent_manager_get_default (); if (!gtk_recent_manager_add_item (manager, file_uri)) g_warning ("Error while adding file name to recent manager."); g_free (file_uri); } } else { g_critical (_("Failed to open file '%s' given as program argument: %s"), fname, ipatch_gerror_message (err)); g_clear_error (&err); } g_free (fname); } g_strfreev (files); } #ifdef PYTHON_SUPPORT if (scripts && !swamigui_disable_python) /* any scripts to run? */ { /* set to stdout Python output function (FIXME - Use logging?) */ swamigui_python_set_output_func (log_python_output_func); for (sptr = scripts; *sptr; sptr++) { char *script; GError *err = NULL; if (g_file_get_contents (*sptr, &script, NULL, &err)) { PyRun_SimpleString (script); g_free (script); } else { g_critical ("Failed to read Python script '%s': %s", *sptr, ipatch_gerror_message (err)); g_clear_error (&err); } } } #else if (scripts) g_critical ("No Python support, '-r' commands ignored"); #endif if (scripts) g_strfreev (scripts); gdk_threads_enter (); gtk_main (); /* kick it in the main GTK loop */ gdk_threads_leave (); /* we destroy it all so refdbg can tell us what objects leaked */ g_object_unref (root); /* -- unref root */ exit (0); } /* output function which uses glib logging facility */ static void log_python_output_func (const char *output, gboolean is_stderr) { GString *gs; char *found; int pos = 0; /* must escape % chars */ gs = g_string_new (output); while ((found = strchr (&gs->str[pos], '%'))) { pos = found - gs->str; g_string_insert_c (gs, pos + 1, '%'); pos += 2; } if (is_stderr) fputs (gs->str, stderr); else puts (gs->str); g_string_free (gs, TRUE); } swami/src/swamigui/SwamiguiMultiSave.h0000644000175000017500000000525611461334205020271 0ustar alessioalessio/* * SwamiguiMultiSave.h - Multiple file save dialog * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_MULTI_SAVE_H__ #define __SWAMIGUI_MULTI_SAVE_H__ #include #include typedef struct _SwamiguiMultiSave SwamiguiMultiSave; typedef struct _SwamiguiMultiSaveClass SwamiguiMultiSaveClass; #define SWAMIGUI_TYPE_MULTI_SAVE (swamigui_multi_save_get_type ()) #define SWAMIGUI_MULTI_SAVE(obj) \ (GTK_CHECK_CAST ((obj), SWAMIGUI_TYPE_MULTI_SAVE, SwamiguiMultiSave)) #define SWAMIGUI_MULTI_SAVE_CLASS(klass) \ (GTK_CHECK_CLASS_CAST ((klass), SWAMIGUI_TYPE_MULTI_SAVE, \ SwamiguiMultiSaveClass)) #define SWAMIGUI_IS_MULTI_SAVE(obj) \ (GTK_CHECK_TYPE ((obj), SWAMIGUI_TYPE_MULTI_SAVE)) #define SWAMIGUI_IS_MULTI_SAVE_CLASS(klass) \ (GTK_CHECK_CLASS_TYPE ((klass), SWAMIGUI_TYPE_MULTI_SAVE)) /* multi item save dialog */ struct _SwamiguiMultiSave { GtkDialog parent_instance; GtkListStore *store; /* list store */ guint flags; /* SwamiguiMultiSaveFlags */ GtkWidget *accept_btn; /* Save/Close button */ GtkWidget *treeview; /* tree view widget */ GtkWidget *icon; /* the icon of the dialog */ GtkWidget *message; /* message label at top of dialog */ GtkWidget *scroll_win; /* scroll window to put list in */ }; /* multi item save dialog class */ struct _SwamiguiMultiSaveClass { GtkDialogClass parent_class; }; /** * SwamiguiMultiSaveFlags: * @SWAMIGUI_MULTI_SAVE_CLOSE_MODE: Files will be closed upon dialog confirm and * accept button is changed to a "Close" button. * * Some flags for use with swamigui_multi_save_new(). */ typedef enum { SWAMIGUI_MULTI_SAVE_CLOSE_MODE = 1 << 0 } SwamiguiMultiSaveFlags; GType swamigui_multi_save_get_type (void); GtkWidget *swamigui_multi_save_new (char *title, char *message, guint flags); void swamigui_multi_save_set_selection (SwamiguiMultiSave *multi, IpatchList *selection); #endif swami/src/swamigui/SwamiguiControl.c0000644000175000017500000005272511461404311017772 0ustar alessioalessio/* * SwamiguiControl.c - GUI control system * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include "SwamiguiControl.h" #include "SwamiguiRoot.h" #include "libswami/swami_priv.h" #include /* * Notes about SwamiguiControl * * When a control is attached to a widget the following occurs: * - widget holds a reference on control (widget->control) * - widget uses g_object_set_data_full to associate control to widget, * GDestroyNotify handler calls swami_control_disconnect_unref() on control * - control has a reference on widget * - widget "destroy" signal is caught by control to release reference * * When gtk_object_destroy() is called on the widget the following happens: * - "destroy" signal is caught by widget control handler which then NULLifies * any pointers to widget and removes its reference to the widget * - If all references have been removed from widget, it is finalized * - GDestroyNotify is called from widget's finalize function which calls * swami_control_disconnect_unref() which disconnects control and unrefs it * - Control is finalized if there are no more external references * * When writing new SwamiguiControl handlers its important to note that the * control network may be operating in a multi-thread environment, while the * GUI is single threaded. For this reason controls are added to the GUI * queue, which causes all events to be processed from within the GUI thread. * This means that even after a widget has been destroyed there may still be * queued control events. For this reason its important to lock the control * in value set/get callbacks and check if the widget is still alive and handle * the case where it has been destroyed (ignore events usually). * * One caveat of this is that currently a control cannot be removed from a * widget. The widget must be destroyed. Since there is a 1 to 1 mapping of * a widget and its control, this shouldn't really be a problem. */ #define CONTROL_TABLE_ROW_SPACING 2 #define CONTROL_TABLE_COLUMN_SPACING 4 typedef struct { GType widg_type; GType value_type; int flags; /* rank and control/view flags */ SwamiguiControlHandler handler; } HandlerInfo; static int swamigui_control_GCompare_type (gconstpointer a, gconstpointer b); static int swamigui_control_GCompare_rank (gconstpointer a, gconstpointer b); G_LOCK_DEFINE_STATIC (control_handlers); static GList *control_handlers = NULL; /* quark used to associate a control to a widget using g_object_set_qdata */ GQuark swamigui_control_quark = 0; void _swamigui_control_init (void) { swamigui_control_quark = g_quark_from_static_string ("_SwamiguiControl"); } /** * swamigui_control_new: * @type: A #SwamiControl derived GType of control to create * * Create a control of the given @type which should be a * #SwamiControl derived type. The created control is automatically added * to the #SwamiguiRoot GUI control event queue. Just a convenience function * really. * * Returns: New control with a refcount of 1 which the caller owns. */ SwamiControl * swamigui_control_new (GType type) { SwamiControl *control; g_return_val_if_fail (g_type_is_a (type, SWAMI_TYPE_CONTROL), NULL); control = g_object_new (type, NULL); if (control) swamigui_control_set_queue (control); return (control); } /** * swamigui_control_new_for_widget: * @widget: GUI widget to create a control for * * Creates a new control for a GUI widget. Use * swami_control_new_for_widget_full() for additional parameters. * * Returns: The new control or %NULL if @widget not handled. * The returned control does NOT have a reference since the @widget is * the owner of the control. Destroying the @widget will cause the control * to be disconnected and unref'd, if there are no more references the * control will be freed. */ SwamiControl * swamigui_control_new_for_widget (GObject *widget) { g_return_val_if_fail (G_IS_OBJECT (widget), NULL); return (swamigui_control_new_for_widget_full (widget, 0, NULL, 0)); } /** * swamigui_control_new_for_widget_full: * @widget: GUI widget to control * @value_type: Control value type or 0 for default * @pspec: Parameter spec to define valid ranges and other parameters, * should be a GParamSpec of @value_type or %NULL for defaults * @flags: Flags for creating the new control. To create a display only * control just the #SWAMIGUI_CONTROL_VIEW flag can be specified, 0 means * both control and view (#SWAMIGUI_CONTROL_CTRLVIEW). * * Creates a new control for a GUI widget, provided there is a registered * handler for the @widget type/value type combination. The new control is * automatically assigned to the GUI queue in #swamigui_root. A widget's * control can be retrieved with swamigui_control_lookup(). * If the given @widget already has a control it is returned. The @pspec * parameter allows for additional settings to be applied to the @widget * and/or control (such as a valid range or max string length, etc). * * Returns: The new control or %NULL if @widget/@value_type not handled. * The returned control does NOT have a reference since the @widget is * the owner of the control. Destroying the @widget will cause the control * to be disconnected and unref'd, if there are no more references the * control will be freed. */ SwamiControl * swamigui_control_new_for_widget_full (GObject *widget, GType value_type, GParamSpec *pspec, SwamiguiControlFlags flags) { SwamiguiControlHandler hfunc = NULL; SwamiControl *control = NULL; GType cmp_widg_type, cmp_value_type; HandlerInfo *hinfo, *bestmatch = NULL; GList *p; g_return_val_if_fail (G_IS_OBJECT (widget), NULL); g_return_val_if_fail (!pspec || G_IS_PARAM_SPEC (pspec), NULL); /* return existing control (if any) */ control = g_object_get_qdata (widget, swamigui_control_quark); if (control) return (control); value_type = swamigui_control_get_alias_value_type (value_type); /* doesn't make sense to request control only */ flags &= SWAMIGUI_CONTROL_CTRLVIEW; if (!(flags & SWAMIGUI_CONTROL_VIEW)) flags = SWAMIGUI_CONTROL_CTRLVIEW; cmp_widg_type = G_OBJECT_TYPE (widget); switch (G_TYPE_FUNDAMENTAL (value_type)) { case G_TYPE_ENUM: case G_TYPE_FLAGS: cmp_value_type = G_TYPE_FUNDAMENTAL (value_type); break; default: cmp_value_type = value_type; break; } G_LOCK (control_handlers); /* loop over widget control handlers */ for (p = control_handlers; p; p = p->next) { hinfo = (HandlerInfo *)(p->data); /* widget type does not match? - Skip */ if (cmp_widg_type != hinfo->widg_type) continue; /* if wildcard value type or handler type matches compare type, we found it */ if (!cmp_value_type || cmp_value_type == hinfo->value_type) break; /* check if compare value and param can be converted to that of the handlers */ if (G_TYPE_IS_VALUE_TYPE (cmp_value_type) && G_TYPE_IS_VALUE_TYPE (hinfo->value_type) && g_value_type_transformable (cmp_value_type, hinfo->value_type)) // && swami_param_type_transformable_value (cmp_value_type, hinfo->value_type)) { /* check if this match is the best so far */ if (!bestmatch || ((bestmatch->flags & SWAMIGUI_CONTROL_RANK_MASK) < (hinfo->flags & SWAMIGUI_CONTROL_RANK_MASK))) bestmatch = hinfo; } } if (!p && bestmatch) hfunc = bestmatch->handler; else if (p) hfunc = ((HandlerInfo *)(p->data))->handler; G_UNLOCK (control_handlers); if (hfunc) control = hfunc (widget, value_type, pspec, flags); /* ++ ref new ctrl */ if (control) swamigui_control_set_queue (control); /* add to GUI queue */ /* associate control to the widget (!! widget takes over reference) */ g_object_set_qdata_full (widget, swamigui_control_quark, control, (GDestroyNotify)swami_control_disconnect_unref); return (control); } /** * swamigui_control_lookup: * @widget: User interface widget to lookup the #SwamiControl of * * Returns: The associated #SwamiControl or NULL if none. The return control * is NOT referenced for the caller (don't unref it). */ SwamiControl * swamigui_control_lookup (GObject *widget) { SwamiControl *control; g_return_val_if_fail (G_IS_OBJECT (widget), NULL); control = g_object_get_qdata (widget, swamigui_control_quark); if (!control) return (NULL); return (SWAMI_CONTROL (control)); /* do a type cast for debugging purposes */ } /** * swamigui_control_prop_connect_widget: * @object: Object with property to connect * @propname: Property of @object to connect * @widg: Widget to control object property * * A convenience function which connects a widget as a control for a given * @object property. Use swamigui_control_prop_connect_widget_full() for * additional options. */ void swamigui_control_prop_connect_widget (GObject *object, const char *propname, GObject *widget) { SwamiControl *propctrl; SwamiControl *widgctrl; GParamSpec *pspec; g_return_if_fail (G_IS_OBJECT (object)); g_return_if_fail (propname != NULL); g_return_if_fail (G_IS_OBJECT (widget)); pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), propname); g_return_if_fail (pspec != NULL); propctrl = swami_get_control_prop (object, pspec); /* ++ ref */ g_return_if_fail (propctrl != NULL); /* create widget control using value type from pspec and view only if * read only property */ widgctrl = swamigui_control_new_for_widget_full (widget, G_PARAM_SPEC_VALUE_TYPE (pspec), NULL, (pspec->flags & G_PARAM_READWRITE) == G_PARAM_READABLE ? SWAMIGUI_CONTROL_VIEW : 0); if (swami_log_if_fail (widgctrl != NULL)) { g_object_unref (propctrl); /* -- unref */ return; } swami_control_connect (propctrl, widgctrl, SWAMI_CONTROL_CONN_BIDIR_SPEC_INIT); g_object_unref (propctrl); /* -- unref */ } /** * swamigui_control_create_widget: * @widg_type: A base type of new widget (GtkWidget, GnomeCanvasItem, etc) * or 0 for default GtkWidget derived types. * @value_type: Control value type * @pspec: Parameter spec to define valid ranges and other parameters, * should be a GParamSpec of @value_type or %NULL for defaults * @flags: Can be used to specify view only controls by passing * #SWAMIGUI_CONTROL_VIEW in which case view only control handlers will be * preferred. A value of 0 assumes control and view mode * (#SWAMIGUI_CONTROL_CTRLVIEW). * * Creates a GUI widget suitable for controlling values of type @value_type. * The @widg_type parameter is used to specify what base type of widget * to create, GTK_TYPE_WIDGET is assumed if 0. * * Returns: The new GUI widget derived from @widg_type and suitable for * controlling values of type @value_type or %NULL if @value_type/@widg_type * not handled. The new object uses the Gtk reference counting behavior. */ GObject * swamigui_control_create_widget (GType widg_type, GType value_type, GParamSpec *pspec, SwamiguiControlFlags flags) { SwamiguiControlHandler hfunc = NULL; GObject *widget = NULL; HandlerInfo *hinfo; GList *p, *found = NULL; gboolean view_only = FALSE; g_return_val_if_fail (value_type != 0, NULL); if (widg_type == 0) widg_type = GTK_TYPE_WIDGET; value_type = swamigui_control_get_alias_value_type (value_type); /* doesn't make sense to request control only */ flags &= SWAMIGUI_CONTROL_CTRLVIEW; if (!(flags & SWAMIGUI_CONTROL_VIEW)) flags = SWAMIGUI_CONTROL_CTRLVIEW; /* view only control requested? */ if ((flags & SWAMIGUI_CONTROL_CTRLVIEW) == SWAMIGUI_CONTROL_VIEW) view_only = TRUE; G_LOCK (control_handlers); /* search for matching control handler */ p = control_handlers; while (p) { hinfo = (HandlerInfo *)(p->data); /* handler widget is derived from @widg_type and of @value_type? */ if (g_type_is_a (hinfo->widg_type, widg_type) && hinfo->value_type == value_type) { if (!found || ((hinfo->flags & SWAMIGUI_CONTROL_CTRLVIEW) == SWAMIGUI_CONTROL_VIEW)) found = p; /* if view only, keep searching for a view only handler */ if (!view_only || ((hinfo->flags & SWAMIGUI_CONTROL_CTRLVIEW) == SWAMIGUI_CONTROL_VIEW)) break; } p = g_list_next (p); } if (found) { hinfo = (HandlerInfo *)(found->data); hfunc = hinfo->handler; widg_type = hinfo->widg_type; } G_UNLOCK (control_handlers); if (found) { widget = g_object_new (widg_type, NULL); /* call handler function to configure UI widget but don't create control */ hfunc (widget, value_type, pspec, flags | SWAMIGUI_CONTROL_NO_CREATE); } return (widget); } /* a GCompareFunc to find a specific widg_type/value_type handler, a 0 value_type is a wildcard */ static int swamigui_control_GCompare_type (gconstpointer a, gconstpointer b) { HandlerInfo *ainfo = (HandlerInfo *)a, *binfo = (HandlerInfo *)b; return (!(ainfo->widg_type == binfo->widg_type && (!binfo->value_type || ainfo->value_type == binfo->value_type))); } /* compares handler info by rank */ static int swamigui_control_GCompare_rank (gconstpointer a, gconstpointer b) { HandlerInfo *ainfo = (HandlerInfo *)a, *binfo = (HandlerInfo *)b; /* sort highest rank first */ return ((binfo->flags & SWAMIGUI_CONTROL_RANK_MASK) - (ainfo->flags & SWAMIGUI_CONTROL_RANK_MASK)); } /** * swamigui_control_set_queue: * @control: Control to assign to the GUI queue * * Set a control to use a GUI queue which is required for all controls * that may be controlled from a non-GUI thread. */ void swamigui_control_set_queue (SwamiControl *control) { g_return_if_fail (SWAMI_IS_CONTROL (control)); swami_control_set_queue (control, swamigui_root->ctrl_queue); } /** * swamigui_control_register: * @widg_type: Type of object control to register * @value_type: The control value type * @handler: Handler function for creating the control * @flags: A rank value between 1:lowest to 63:highest, 0:default (see * SwamiguiControlRank) or'ed with SwamiguiControlFlags defining the * view/control capabilities of this handler. The rank allows * preferred object types to be chosen when there are multiple object * control handlers for the same value and base object types. If * neither #SWAMIGUI_CONTROL_VIEW or #SWAMIGUI_CONTROL_CTRL are specified * then control/view is assumed (#SWAMIGUI_CONTROL_CTRLVIEW). * * This function registers new GUI control types. It is multi-thread safe * and can be called outside of the GUI thread (from a plugin for instance). * If the given @widg_type/@value_type already exists then the new @handler * is used. The @flags parameter specifies the rank to give preference to * handlers with the same @value_type and also contains control/view * capability flags. */ void swamigui_control_register (GType widg_type, GType value_type, SwamiguiControlHandler handler, guint flags) { HandlerInfo *hinfo, cmp; GList *p; g_return_if_fail (g_type_is_a (widg_type, G_TYPE_OBJECT)); g_return_if_fail (G_TYPE_IS_VALUE_TYPE (value_type) || value_type == G_TYPE_ENUM || value_type == G_TYPE_FLAGS); if ((flags & SWAMIGUI_CONTROL_RANK_MASK) == 0) flags |= SWAMIGUI_CONTROL_RANK_DEFAULT; if (!(flags & SWAMIGUI_CONTROL_CTRLVIEW)) flags |= SWAMIGUI_CONTROL_CTRLVIEW; cmp.widg_type = widg_type; cmp.value_type = value_type; G_LOCK (control_handlers); p = g_list_find_custom (control_handlers, &cmp, swamigui_control_GCompare_type); if (!p) { hinfo = g_slice_new0 (HandlerInfo); control_handlers = g_list_insert_sorted (control_handlers, hinfo, swamigui_control_GCompare_rank); } else hinfo = (HandlerInfo *)(p->data); hinfo->widg_type = widg_type; hinfo->value_type = value_type; hinfo->flags = flags; hinfo->handler = handler; G_UNLOCK (control_handlers); } /** * swamigui_control_unregister: * @widg_type: Object type of control handler to unregister * @value_type: The value type of the control handler * * Unregisters a previous @widg_type/@value_type GUI control handler. * It is multi-thread safe and can be called outside of GUI thread (from a * plugin for instance). */ void swamigui_control_unregister (GType widg_type, GType value_type) { HandlerInfo cmp; GList *p; g_return_if_fail (g_type_is_a (widg_type, GTK_TYPE_OBJECT)); g_return_if_fail (G_TYPE_IS_VALUE (value_type)); cmp.widg_type = widg_type; cmp.value_type = value_type; G_LOCK (control_handlers); p = g_list_find_custom (control_handlers, &cmp, swamigui_control_GCompare_type); if (p) { g_slice_free (HandlerInfo, p->data); control_handlers = g_list_delete_link (control_handlers, p); } G_UNLOCK (control_handlers); if (!p) g_warning ("Failed to find widget handler type '%s' value type '%s'", g_type_name (widg_type), g_type_name (value_type)); } /** * swamigui_control_glade_prop_connect: * @widget: A GTK widget created by libglade * @obj: Object to control properties of or %NULL to unset active object * * This function connects a libglade created @widget, with child widgets whose * names are of the form "PROP::[prop-name]", to the corresponding GObject * properties of @obj ([prop-name] values). An example child widget name would be * "PROP::volume" which would control the "volume" property of an object. * This allows for object GUI interfaces to be created with a minimum of code. */ void swamigui_control_glade_prop_connect (GtkWidget *widget, GObject *obj) { GladeXML *gladexml; GtkWidget *widg; GParamSpec *pspec; const char *name; char *propname; SwamiControl *propctrl, *widgctrl; GObjectClass *objclass = NULL; gboolean viewonly; GList *list, *p; g_return_if_fail (GTK_IS_WIDGET (widget)); g_return_if_fail (!obj || G_IS_OBJECT (obj)); gladexml = glade_get_widget_tree (widget); g_return_if_fail (gladexml != NULL); if (obj) { objclass = g_type_class_peek (G_OBJECT_TYPE (obj)); g_return_if_fail (objclass != NULL); } /* find all widgets whose glade names start with PROP:: */ list = glade_xml_get_widget_prefix (gladexml, "PROP::"); /* ++ alloc */ /* loop over widgets */ for (p = list; p; p = p->next) { widg = (GtkWidget *)(p->data); name = glade_get_widget_name (widg); /* full name of widget */ name += 6; /* skip "PROP::" prefix */ /* to work around duplicate glade names, everything following a ':' char is ignored */ if ((propname = strchr (name, ':'))) propname = g_strndup (name, propname - name); /* ++ alloc */ else propname = g_strdup (name); /* ++ alloc */ /* get parameter spec of the property for object (if obj is set) */ if (obj) { pspec = g_object_class_find_property (objclass, propname); if (!pspec) { g_warning ("Object of type %s has no property '%s'", g_type_name (G_OBJECT_TYPE (obj)), propname); g_free (propname); /* -- free */ continue; } viewonly = (pspec->flags & G_PARAM_WRITABLE) == 0; } /* lookup existing control widget (if any) */ widgctrl = swamigui_control_lookup (G_OBJECT (widg)); if (!widgctrl) { if (!obj) { g_free (propname); /* -- free */ continue; /* no widget control to disconnect, continue */ } /* create or lookup widget control (view only if property is read only) */ widgctrl = swamigui_control_new_for_widget_full (G_OBJECT (widg), G_PARAM_SPEC_VALUE_TYPE (pspec), pspec, viewonly ? SWAMIGUI_CONTROL_VIEW : 0); if (!widgctrl) { g_critical ("Failed to create widget control for '%s' of type '%s'", propname, g_type_name (G_OBJECT_TYPE (widg))); g_free (propname); /* -- free */ continue; } } /* disconnect any existing connections */ else swami_control_disconnect_all (widgctrl); if (obj) { /* get a control for the object's property */ propctrl = swami_get_control_prop (obj, pspec); /* ++ ref */ if (propctrl) { /* connect the property control to the widget control */ swami_control_connect (propctrl, widgctrl, (viewonly ? 0 : SWAMI_CONTROL_CONN_BIDIR) | SWAMI_CONTROL_CONN_INIT | SWAMI_CONTROL_CONN_SPEC); g_object_unref (propctrl); /* -- unref */ } } g_free (propname); /* -- free */ } g_list_free (list); /* -- free list */ } /** * swamigui_control_get_value_alias_type: * @type: Type to get alias type of * * Get the real value type used to control the given @type. * For example, all integer and floating point types are handled by * G_TYPE_DOUBLE controls. * * Returns: The alias type for the @type parameter or the same value if * type has no alias. */ GType swamigui_control_get_alias_value_type (GType type) { switch (type) { case G_TYPE_CHAR: case G_TYPE_UCHAR: case G_TYPE_INT: case G_TYPE_UINT: case G_TYPE_LONG: case G_TYPE_ULONG: case G_TYPE_INT64: case G_TYPE_UINT64: case G_TYPE_FLOAT: return (G_TYPE_DOUBLE); default: return (type); } } swami/src/swamigui/splash.h0000644000175000017500000000203311461334205016132 0ustar alessioalessio/* * splash.h - Header file for splash intro routines * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_SPLASH_H__ #define __SWAMIGUI_SPLASH_H__ #include void swamigui_splash_display (guint timeout); gboolean swamigui_splash_kill (void); #endif swami/src/swamigui/SwamiguiControl_widgets.c0000644000175000017500000012237411461334205021522 0ustar alessioalessio/* * SwamiguiControl_widgets.c - Builtin GtkWidget control handlers * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include #include #include "SwamiguiControl.h" #include "SwamiguiControlAdj.h" #include "SwamiguiSpinScale.h" #include "SwamiguiNoteSelector.h" #include "i18n.h" static void func_control_cb_widget_destroy (GtkObject *object, gpointer user_data); static SwamiControl *adjustment_control_handler (GObject *widget, GType value_type, GParamSpec *pspec, SwamiguiControlFlags flags); static void adjustment_control_cb_spec_changed (SwamiControl *control, GParamSpec *pspec, gpointer user_data); static SwamiControl *entry_control_handler (GObject *widget, GType value_type, GParamSpec *pspec, SwamiguiControlFlags flags); static void entry_control_get_func (SwamiControl *control, GValue *value); static void entry_control_set_func (SwamiControl *control, SwamiControlEvent *event, const GValue *value); static void entry_control_cb_changed (GtkEditable *editable, gpointer user_data); static SwamiControl *combo_box_entry_control_handler (GObject *widget, GType value_type, GParamSpec *pspec, SwamiguiControlFlags flags); static SwamiControl *text_view_control_handler (GObject *widget, GType value_type, GParamSpec *pspec, SwamiguiControlFlags flags); static SwamiControl *text_buffer_control_handler (GObject *widget, GType value_type, GParamSpec *pspec, SwamiguiControlFlags flags); static void text_buffer_control_get_func (SwamiControl *control, GValue *value); static void text_buffer_control_set_func (SwamiControl *control, SwamiControlEvent *event, const GValue *value); static void text_buffer_control_cb_changed (GtkTextBuffer *txtbuf, gpointer user_data); static void text_buffer_widget_weak_notify (gpointer data, GObject *where_the_object_was); static SwamiControl *file_chooser_control_handler (GObject *widget, GType value_type, GParamSpec *pspec, SwamiguiControlFlags flags); static void file_chooser_control_get_func (SwamiControl *control, GValue *value); static void file_chooser_control_set_func (SwamiControl *control, SwamiControlEvent *event, const GValue *value); static void file_chooser_control_cb_changed (GtkFileChooser *chooser, gpointer user_data); static SwamiControl *label_control_handler (GObject *widget, GType value_type, GParamSpec *pspec, SwamiguiControlFlags flags); static void label_control_get_func (SwamiControl *control, GValue *value); static void label_control_set_func (SwamiControl *control, SwamiControlEvent *event, const GValue *value); static SwamiControl *toggle_button_control_handler (GObject *widget, GType value_type, GParamSpec *pspec, SwamiguiControlFlags flags); static void toggle_button_control_get_func (SwamiControl *control, GValue *value); static void toggle_button_control_set_func (SwamiControl *control, SwamiControlEvent *event, const GValue *value); static void toggle_button_control_toggled (GtkToggleButton *btn, gpointer user_data); static SwamiControl *combo_box_string_control_handler (GObject *widget, GType value_type, GParamSpec *pspec, SwamiguiControlFlags flags); static void combo_box_string_control_get_func (SwamiControl *control, GValue *value); static void combo_box_string_control_set_func (SwamiControl *control, SwamiControlEvent *event, const GValue *value); static void combo_box_string_control_changed (GtkComboBox *combo, gpointer user_data); static SwamiControl *combo_box_enum_control_handler (GObject *widget, GType value_type, GParamSpec *pspec, SwamiguiControlFlags flags); static void combo_box_enum_control_get_func (SwamiControl *control, GValue *value); static void combo_box_enum_control_set_func (SwamiControl *control, SwamiControlEvent *event, const GValue *value); static void combo_box_enum_control_changed (GtkComboBox *combo, gpointer user_data); static SwamiControl *combo_box_gtype_control_handler (GObject *widget, GType value_type, GParamSpec *pspec, SwamiguiControlFlags flags); static void combo_box_gtype_control_get_func (SwamiControl *control, GValue *value); static void combo_box_gtype_control_set_func (SwamiControl *control, SwamiControlEvent *event, const GValue *value); static void combo_box_gtype_control_changed (GtkComboBox *combo, gpointer user_data); void _swamigui_control_widgets_init (void) { /* GtkAdjustment based GUI controls */ swamigui_control_register (GTK_TYPE_SPIN_BUTTON, G_TYPE_DOUBLE, adjustment_control_handler, SWAMIGUI_CONTROL_RANK_HIGH); swamigui_control_register (SWAMIGUI_TYPE_SPIN_SCALE, G_TYPE_DOUBLE, adjustment_control_handler, 0); swamigui_control_register (GTK_TYPE_HSCALE, G_TYPE_DOUBLE, adjustment_control_handler, 0); swamigui_control_register (GTK_TYPE_VSCALE, G_TYPE_DOUBLE, adjustment_control_handler, SWAMIGUI_CONTROL_RANK_LOW); swamigui_control_register (GTK_TYPE_HSCROLLBAR, G_TYPE_DOUBLE, adjustment_control_handler, SWAMIGUI_CONTROL_RANK_LOW); swamigui_control_register (GTK_TYPE_VSCROLLBAR, G_TYPE_DOUBLE, adjustment_control_handler, SWAMIGUI_CONTROL_RANK_LOW); swamigui_control_register (SWAMIGUI_TYPE_NOTE_SELECTOR, G_TYPE_DOUBLE, adjustment_control_handler, SWAMIGUI_CONTROL_RANK_LOW); /* string type controls */ swamigui_control_register (GTK_TYPE_ENTRY, G_TYPE_STRING, entry_control_handler, SWAMIGUI_CONTROL_RANK_HIGH); swamigui_control_register (GTK_TYPE_COMBO_BOX_ENTRY, G_TYPE_STRING, combo_box_entry_control_handler, SWAMIGUI_CONTROL_RANK_LOW); swamigui_control_register (GTK_TYPE_TEXT_VIEW, G_TYPE_STRING, text_view_control_handler, SWAMIGUI_CONTROL_RANK_LOW); swamigui_control_register (GTK_TYPE_TEXT_BUFFER, G_TYPE_STRING, text_buffer_control_handler, SWAMIGUI_CONTROL_RANK_LOW); swamigui_control_register (GTK_TYPE_FILE_CHOOSER_BUTTON, G_TYPE_STRING, file_chooser_control_handler, SWAMIGUI_CONTROL_RANK_LOW); swamigui_control_register (GTK_TYPE_LABEL, G_TYPE_STRING, label_control_handler, SWAMIGUI_CONTROL_VIEW | SWAMIGUI_CONTROL_RANK_LOW); /* button controls */ swamigui_control_register (GTK_TYPE_CHECK_BUTTON, G_TYPE_BOOLEAN, toggle_button_control_handler, SWAMIGUI_CONTROL_RANK_HIGH); swamigui_control_register (GTK_TYPE_TOGGLE_BUTTON, G_TYPE_BOOLEAN, toggle_button_control_handler, 0); /* combo box controls */ swamigui_control_register (GTK_TYPE_COMBO_BOX, G_TYPE_STRING, combo_box_string_control_handler, SWAMIGUI_CONTROL_RANK_HIGH); swamigui_control_register (GTK_TYPE_COMBO_BOX, G_TYPE_ENUM, combo_box_enum_control_handler, SWAMIGUI_CONTROL_RANK_LOW); swamigui_control_register (GTK_TYPE_COMBO_BOX, G_TYPE_GTYPE, combo_box_gtype_control_handler, SWAMIGUI_CONTROL_RANK_LOW); /* Additional possible GUI controls: GtkProgressBar, GtkButton */ } /* function used by function control handlers to catch widget "destroy" signal and remove widget reference */ static void func_control_cb_widget_destroy (GtkObject *object, gpointer user_data) { SwamiControlFunc *control = SWAMI_CONTROL_FUNC (user_data); gpointer data; data = SWAMI_CONTROL_FUNC_DATA (control); if (data) /* destroy may be called multiple times */ { SWAMI_LOCK_WRITE (control); SWAMI_CONTROL_FUNC_DATA (control) = NULL; g_object_unref (object); SWAMI_UNLOCK_WRITE (control); } } static SwamiControl * adjustment_control_handler (GObject *widget, GType value_type, GParamSpec *pspec, SwamiguiControlFlags flags) { GtkAdjustment *adj; SwamiControl *control = NULL; IpatchUnitInfo *unitinfo; gdouble min, max, def; gboolean isint = FALSE; guint units; guint digits = 2; /* default digits */ g_object_get (widget, "adjustment", &adj, NULL); g_return_val_if_fail (adj != NULL, NULL); if (GTK_IS_SPIN_BUTTON (widget) && !SWAMIGUI_IS_NOTE_SELECTOR (widget)) gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (widget), TRUE); if (pspec && swami_param_get_limits (pspec, &min, &max, &def, &isint)) { /* set the number of significant decimal digits */ if (g_object_class_find_property (G_OBJECT_GET_CLASS (widget), "digits")) { if (!isint) { /* if unit-type is set.. */ ipatch_param_get (pspec, "unit-type", &units, NULL); if (units) { unitinfo = ipatch_unit_lookup (units); digits = unitinfo->digits; } else ipatch_param_get (pspec, "float-digits", &digits, NULL); } else digits = 0; /* int type, no decimal digits */ g_object_set (widget, "digits", digits, NULL); } adj->lower = min; adj->upper = max; adj->value = def; } else { adj->lower = 0.0; adj->upper = G_MAXINT; adj->value = 0.0; } adj->step_increment = 1.0; adj->page_increment = 10.0; // FIXME - Smarter? gtk_adjustment_changed (adj); gtk_adjustment_value_changed (adj); if (!(flags & SWAMIGUI_CONTROL_NO_CREATE)) { control = SWAMI_CONTROL (swamigui_control_adj_new (adj)); /* if the pspec is not an integer type and widget has the digits property * watch for pspec changes (to update number of decimal digits) */ if (!isint && g_object_class_find_property (G_OBJECT_GET_CLASS (widget), "digits")) g_signal_connect (control, "spec-changed", G_CALLBACK (adjustment_control_cb_spec_changed), widget); } return (control); } /* updates digits if control parameter spec changes */ static void adjustment_control_cb_spec_changed (SwamiControl *control, GParamSpec *pspec, gpointer user_data) { GObject *widget = G_OBJECT (user_data); IpatchUnitInfo *unitinfo; guint digits, units; ipatch_param_get (pspec, "unit-type", &units, NULL); if (units) { unitinfo = ipatch_unit_lookup (units); digits = unitinfo->digits; } else ipatch_param_get (pspec, "float-digits", &digits, NULL); /* changing digits causes control value to change, we block events here */ swamigui_control_adj_block_changes (SWAMIGUI_CONTROL_ADJ (control)); g_object_set (widget, "digits", digits, NULL); swamigui_control_adj_unblock_changes (SWAMIGUI_CONTROL_ADJ (control)); } /* * Entry control handler */ static SwamiControl * entry_control_handler (GObject *widget, GType value_type, GParamSpec *pspec, SwamiguiControlFlags flags) { SwamiControlFunc *control = NULL; if (!(flags & SWAMIGUI_CONTROL_NO_CREATE)) { g_object_ref (widget); /* ++ ref the GtkEntry for the control */ control = swami_control_func_new (); swami_control_set_value_type (SWAMI_CONTROL (control), G_TYPE_STRING); if (!pspec) pspec = g_param_spec_string ("value", "value", "value", NULL, G_PARAM_READWRITE); else g_param_spec_ref (pspec); /* ++ ref for swami_control_set_spec */ swami_control_set_spec (SWAMI_CONTROL (control), pspec); swami_control_func_assign_funcs (control, entry_control_get_func, entry_control_set_func, NULL, widget); g_signal_connect (widget, "destroy", G_CALLBACK (func_control_cb_widget_destroy), control); } if (flags & SWAMIGUI_CONTROL_CTRL) /* controllable? */ { gtk_editable_set_editable (GTK_EDITABLE (widget), TRUE); /* set entry max length */ if (pspec) { guint maxlen; ipatch_param_get (pspec, "string-max-length", &maxlen, NULL); gtk_entry_set_max_length (GTK_ENTRY (widget), maxlen); } if (control) g_signal_connect (widget, "changed", G_CALLBACK (entry_control_cb_changed), control); } /* not controllable */ else gtk_editable_set_editable (GTK_EDITABLE (widget), FALSE); return (SWAMI_CONTROL (control)); } /* GtkEntry handler SwamiControl get value function */ static void entry_control_get_func (SwamiControl *control, GValue *value) { gpointer data; SWAMI_LOCK_READ (control); data = SWAMI_CONTROL_FUNC_DATA (control); if (data) g_value_set_string (value, gtk_entry_get_text (GTK_ENTRY (data))); SWAMI_UNLOCK_READ (control); } /* GtkEntry handler SwamiControl set value function */ static void entry_control_set_func (SwamiControl *control, SwamiControlEvent *event, const GValue *value) { GtkEntry *entry = NULL; gpointer data; const char *s; /* minimize lock and ref the entry */ SWAMI_LOCK_READ (control); data = SWAMI_CONTROL_FUNC_DATA (control); if (data) entry = GTK_ENTRY (g_object_ref (data)); /* ++ ref entry */ SWAMI_UNLOCK_READ (control); if (entry) { g_signal_handlers_block_by_func (entry, entry_control_cb_changed, control); s = g_value_get_string (value); gtk_entry_set_text (entry, s ? s : ""); g_signal_handlers_unblock_by_func (entry, entry_control_cb_changed, control); g_object_unref (entry); /* -- unref entry */ } } /* callback for GtkEntry control to propagate text changes */ static void entry_control_cb_changed (GtkEditable *editable, gpointer user_data) { SwamiControlFunc *control = SWAMI_CONTROL_FUNC (user_data); GValue value = { 0 }; /* transmit the entry change */ g_value_init (&value, G_TYPE_STRING); g_value_take_string (&value, gtk_editable_get_chars (editable, 0, -1)); swami_control_transmit_value ((SwamiControl *)control, &value); g_value_unset (&value); } static SwamiControl * combo_box_entry_control_handler (GObject *widget, GType value_type, GParamSpec *pspec, SwamiguiControlFlags flags) { GtkWidget *entry; entry = gtk_bin_get_child (GTK_BIN (widget)); return (entry_control_handler (G_OBJECT (entry), value_type, pspec, flags)); } /* * Text view control handler (uses text buffer control handler) */ static SwamiControl * text_view_control_handler (GObject *widget, GType value_type, GParamSpec *pspec, SwamiguiControlFlags flags) { GtkTextView *txtview = GTK_TEXT_VIEW (widget); GObject *txtbuf; txtbuf = G_OBJECT (gtk_text_view_get_buffer (txtview)); return (text_buffer_control_handler (txtbuf, value_type, pspec, flags)); } /* * Text buffer control handler */ static SwamiControl * text_buffer_control_handler (GObject *widget, GType value_type, GParamSpec *pspec, SwamiguiControlFlags flags) { SwamiControlFunc *control = NULL; GtkTextBuffer *txtbuf = GTK_TEXT_BUFFER (widget); GtkTextIter start, end; GtkTextTag *tag; if (!(flags & SWAMIGUI_CONTROL_NO_CREATE)) { g_object_ref (widget); /* ++ ref the GtkTextBuffer for the control */ control = swami_control_func_new (); swami_control_set_spec ((SwamiControl *)control, g_param_spec_string ("value", "value", "value", NULL, G_PARAM_READWRITE)); swami_control_func_assign_funcs (control, text_buffer_control_get_func, text_buffer_control_set_func, NULL, widget); if (flags & SWAMIGUI_CONTROL_CTRL) /* controllable? */ g_signal_connect (widget, "changed", G_CALLBACK (text_buffer_control_cb_changed), control); /* not a GtkObject (no "destroy") so we add a weak reference instead */ g_object_weak_ref (widget, text_buffer_widget_weak_notify, control); } if (!(flags & SWAMIGUI_CONTROL_CTRL)) /* view only? */ { /* make text buffer read only */ tag = gtk_text_buffer_create_tag (txtbuf, "read_only", "editable", FALSE, NULL); gtk_text_buffer_get_bounds (txtbuf, &start, &end); gtk_text_buffer_apply_tag (txtbuf, tag, &start, &end); } return (control ? SWAMI_CONTROL (control) : NULL); } /* GtkTextBuffer handler SwamiControlFunc get value function */ static void text_buffer_control_get_func (SwamiControl *control, GValue *value) { gpointer data; GtkTextBuffer *txtbuf; GtkTextIter start, end; SWAMI_LOCK_READ (control); data = SWAMI_CONTROL_FUNC_DATA (control); if (data) { txtbuf = GTK_TEXT_BUFFER (data); gtk_text_buffer_get_bounds (txtbuf, &start, &end); g_value_set_string (value, gtk_text_buffer_get_text (txtbuf, &start, &end, FALSE)); } SWAMI_UNLOCK_READ (control); } /* GtkTextBuffer handler SwamiControlFunc set value function */ static void text_buffer_control_set_func (SwamiControl *control, SwamiControlEvent *event, const GValue *value) { GtkTextBuffer *txtbuf = NULL; gpointer data; const char *s; /* minimize lock and ref the text buffer */ SWAMI_LOCK_READ (control); data = SWAMI_CONTROL_FUNC_DATA (control); if (data) txtbuf = GTK_TEXT_BUFFER (g_object_ref (data)); /* ++ ref */ SWAMI_UNLOCK_READ (control); if (txtbuf) { g_signal_handlers_block_by_func (txtbuf, text_buffer_control_cb_changed, control); s = g_value_get_string (value); gtk_text_buffer_set_text (txtbuf, s ? s : "", -1); g_signal_handlers_unblock_by_func (txtbuf, text_buffer_control_cb_changed, control); g_object_unref (txtbuf); /* -- unref text buffer */ } } /* GtkTextBuffer changed callback */ static void text_buffer_control_cb_changed (GtkTextBuffer *txtbuf, gpointer user_data) { SwamiControlFunc *control = SWAMI_CONTROL_FUNC (user_data); GtkTextIter start, end; GValue value = { 0 }; gtk_text_buffer_get_bounds (txtbuf, &start, &end); g_value_init (&value, G_TYPE_STRING); g_value_set_string (&value, gtk_text_buffer_get_text (txtbuf, &start, &end, FALSE)); swami_control_transmit_value ((SwamiControl *)control, &value); g_value_unset (&value); } /* weak notify when text buffer is destroyed */ static void text_buffer_widget_weak_notify (gpointer data, GObject *where_the_object_was) { SwamiControlFunc *control = SWAMI_CONTROL_FUNC (data); SWAMI_LOCK_WRITE (control); SWAMI_CONTROL_FUNC_DATA (control) = NULL; SWAMI_UNLOCK_WRITE (control); } /* * file chooser control handler */ static SwamiControl * file_chooser_control_handler (GObject *widget, GType value_type, GParamSpec *pspec, SwamiguiControlFlags flags) { SwamiControlFunc *control = NULL; if (!(flags & SWAMIGUI_CONTROL_NO_CREATE)) { g_object_ref (widget); /* ++ ref the GtkEntry for the control */ control = swami_control_func_new (); swami_control_set_spec (SWAMI_CONTROL (control), g_param_spec_string ("value", "value", "value", NULL, G_PARAM_READWRITE)); swami_control_func_assign_funcs (control, file_chooser_control_get_func, file_chooser_control_set_func, NULL, widget); g_signal_connect (widget, "destroy", G_CALLBACK (func_control_cb_widget_destroy), control); } if (flags & SWAMIGUI_CONTROL_CTRL) /* controllable? */ { gtk_widget_set_sensitive ((GtkWidget *)widget, TRUE); if (control) g_signal_connect (widget, "file-set", G_CALLBACK (file_chooser_control_cb_changed), control); } /* not controllable */ else gtk_editable_set_editable (GTK_EDITABLE (widget), FALSE); return (SWAMI_CONTROL (control)); } /* file chooser handler SwamiControl get value function */ static void file_chooser_control_get_func (SwamiControl *control, GValue *value) { GtkFileChooser *chooser; gpointer data; SWAMI_LOCK_READ (control); data = SWAMI_CONTROL_FUNC_DATA (control); if (data) chooser = GTK_FILE_CHOOSER (g_object_ref (data)); /* ++ ref file chooser */ SWAMI_UNLOCK_READ (control); if (chooser) { g_value_take_string (value, gtk_file_chooser_get_filename (chooser)); g_object_unref (chooser); /* -- unref file chooser */ } } /* file chooser handler SwamiControl set value function */ static void file_chooser_control_set_func (SwamiControl *control, SwamiControlEvent *event, const GValue *value) { GtkFileChooser *chooser = NULL; gpointer data; const char *s; /* minimize lock and ref the file chooser */ SWAMI_LOCK_READ (control); data = SWAMI_CONTROL_FUNC_DATA (control); if (data) chooser = GTK_FILE_CHOOSER (g_object_ref (data)); /* ++ ref file chooser */ SWAMI_UNLOCK_READ (control); if (chooser) { g_signal_handlers_block_by_func (chooser, file_chooser_control_cb_changed, control); s = g_value_get_string (value); gtk_file_chooser_set_filename (chooser, s ? s : ""); g_signal_handlers_unblock_by_func (chooser, file_chooser_control_cb_changed, control); g_object_unref (chooser); /* -- unref file chooser */ } } /* callback for file chooser control to propagate text changes */ static void file_chooser_control_cb_changed (GtkFileChooser *chooser, gpointer user_data) { SwamiControlFunc *control = SWAMI_CONTROL_FUNC (user_data); GValue value = { 0 }; /* transmit the file chooser change */ g_value_init (&value, G_TYPE_STRING); g_value_take_string (&value, gtk_file_chooser_get_filename (chooser)); swami_control_transmit_value ((SwamiControl *)control, &value); g_value_unset (&value); } /* * label control handler (display only) */ static SwamiControl * label_control_handler (GObject *widget, GType value_type, GParamSpec *pspec, SwamiguiControlFlags flags) { SwamiControlFunc *control; if (flags & SWAMIGUI_CONTROL_NO_CREATE) return (NULL); g_object_ref (widget); /* ++ ref widget for control */ control = swami_control_func_new (); swami_control_set_spec ((SwamiControl *)control, g_param_spec_string ("value", "value", "value", NULL, G_PARAM_READWRITE)); swami_control_func_assign_funcs (control, label_control_get_func, label_control_set_func, NULL, widget); g_signal_connect (widget, "destroy", G_CALLBACK (func_control_cb_widget_destroy), control); return (SWAMI_CONTROL (control)); } /* GtkLabel handler SwamiControlFunc get value function */ static void label_control_get_func (SwamiControl *control, GValue *value) { gpointer data; SWAMI_LOCK_READ (control); data = SWAMI_CONTROL_FUNC_DATA (control); if (data) g_value_set_string (value, gtk_label_get_text (GTK_LABEL (data))); SWAMI_UNLOCK_READ (control); } /* GtkLabel handler SwamiControlFunc set value function */ static void label_control_set_func (SwamiControl *control, SwamiControlEvent *event, const GValue *value) { GtkLabel *label = NULL; gpointer data; const char *s; /* minimize lock time, ref and do the work outside of lock */ SWAMI_LOCK_READ (control); data = SWAMI_CONTROL_FUNC_DATA (control); if (data) label = GTK_LABEL (g_object_ref (data)); /* -- ref label */ SWAMI_UNLOCK_READ (control); if (label) { s = g_value_get_string (value); gtk_label_set_text (label, s ? s : ""); g_object_unref (label); /* -- unref label */ } } /* * toggle button control handler */ static SwamiControl * toggle_button_control_handler (GObject *widget, GType value_type, GParamSpec *pspec, SwamiguiControlFlags flags) { SwamiControlFunc *control; if (flags & SWAMIGUI_CONTROL_NO_CREATE) return (NULL); g_object_ref (widget); /* ++ ref button widget for control */ control = swami_control_func_new (); swami_control_set_spec ((SwamiControl *)control, g_param_spec_boolean ("value", "value", "value", FALSE, G_PARAM_READWRITE)); swami_control_func_assign_funcs (control, toggle_button_control_get_func, toggle_button_control_set_func, NULL, widget); g_signal_connect (widget, "destroy", G_CALLBACK (func_control_cb_widget_destroy), control); if (flags & SWAMIGUI_CONTROL_CTRL) /* controllable? */ { gtk_widget_set_sensitive ((GtkWidget *)widget, TRUE); g_signal_connect (widget, "toggled", G_CALLBACK (toggle_button_control_toggled), control); } else gtk_widget_set_sensitive ((GtkWidget *)widget, FALSE); return (SWAMI_CONTROL (control)); } /* toggle button handler SwamiControlFunc get value function */ static void toggle_button_control_get_func (SwamiControl *control, GValue *value) { gpointer data; SWAMI_LOCK_READ (control); data = SWAMI_CONTROL_FUNC_DATA (control); if (data) g_value_set_boolean (value, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data))); SWAMI_UNLOCK_READ (control); } /* toggle button handler SwamiControlFunc set value function */ static void toggle_button_control_set_func (SwamiControl *control, SwamiControlEvent *event, const GValue *value) { GtkToggleButton *btn = NULL; gpointer data; /* minimize lock time - ref the button */ SWAMI_LOCK_READ (control); data = SWAMI_CONTROL_FUNC_DATA (control); if (data) btn = GTK_TOGGLE_BUTTON (g_object_ref (data)); /* ++ ref btn */ SWAMI_UNLOCK_READ (control); if (btn) { g_signal_handlers_block_by_func (btn, toggle_button_control_toggled, control); gtk_toggle_button_set_active (btn, g_value_get_boolean (value)); g_signal_handlers_unblock_by_func (btn, toggle_button_control_toggled, control); g_object_unref (btn); /* -- unref button */ } } /* toggle callback to transmit control change to connected controls */ static void toggle_button_control_toggled (GtkToggleButton *btn, gpointer user_data) { SwamiControlFunc *control = SWAMI_CONTROL_FUNC (user_data); GValue value = { 0 }; /* transmit the toggle button change */ g_value_init (&value, G_TYPE_BOOLEAN); g_value_set_boolean (&value, gtk_toggle_button_get_active (btn)); swami_control_transmit_value ((SwamiControl *)control, &value); g_value_unset (&value); } /* * String combo box control handler */ static SwamiControl * combo_box_string_control_handler (GObject *widget, GType value_type, GParamSpec *pspec, SwamiguiControlFlags flags) { SwamiControlFunc *control; g_return_val_if_fail (g_value_type_transformable (value_type, G_TYPE_STRING), NULL); if (flags & SWAMIGUI_CONTROL_NO_CREATE) return (NULL); g_object_ref (widget); /* ++ ref widget for control */ /* Create parameter spec if none or not transformable to string */ if (!pspec || !swami_param_type_transformable (G_PARAM_SPEC_TYPE (pspec), G_TYPE_PARAM_STRING)) pspec = g_param_spec_string ("value", "value", "value", NULL, G_PARAM_READWRITE); else g_param_spec_ref (pspec); /* ++ ref for swami_control_set_spec */ control = swami_control_func_new (); swami_control_set_value_type (SWAMI_CONTROL (control), G_TYPE_STRING); swami_control_set_spec ((SwamiControl *)control, pspec); swami_control_func_assign_funcs (control, combo_box_string_control_get_func, combo_box_string_control_set_func, NULL, widget); g_signal_connect (widget, "destroy", G_CALLBACK (func_control_cb_widget_destroy), control); if (flags & SWAMIGUI_CONTROL_CTRL) /* controllable? */ { gtk_widget_set_sensitive ((GtkWidget *)widget, TRUE); g_signal_connect (widget, "changed", G_CALLBACK (combo_box_string_control_changed), control); } else gtk_widget_set_sensitive ((GtkWidget *)widget, FALSE); return (SWAMI_CONTROL (control)); } /* string combo box handler SwamiControlFunc get value function */ static void combo_box_string_control_get_func (SwamiControl *control, GValue *value) { GtkComboBox *combo = NULL; GtkTreeModel *model; GtkTreeIter iter; GParamSpec *pspec; gpointer data; char *text = NULL; SWAMI_LOCK_READ (control); data = SWAMI_CONTROL_FUNC_DATA (control); if (data) combo = GTK_COMBO_BOX (g_object_ref (data)); /* ++ ref for outside of lock */ pspec = swami_control_get_spec (control); /* ++ ref param spec */ SWAMI_UNLOCK_READ (control); if (combo) { if (gtk_combo_box_get_active_iter (combo, &iter)) { model = gtk_combo_box_get_model (combo); gtk_tree_model_get (model, &iter, 0, &text, /* ++ alloc */ -1); } g_value_set_string (value, text); g_free (text); /* -- free */ g_object_unref (combo); /* -- unref combo box */ } g_param_spec_unref (pspec); /* -- unref param spec */ } /* string combo box handler SwamiControlFunc set value function */ static void combo_box_string_control_set_func (SwamiControl *control, SwamiControlEvent *event, const GValue *value) { GtkComboBox *combo = NULL; GtkTreeModel *model; GtkTreeIter iter; gpointer data; int active = -1; /* defaults to de-selecting active combo item */ const char *activestr; char *str; int i; /* minimize lock time - ref the combo box */ SWAMI_LOCK_READ (control); data = SWAMI_CONTROL_FUNC_DATA (control); if (data) combo = GTK_COMBO_BOX (g_object_ref (data)); /* ++ ref combo box */ SWAMI_UNLOCK_READ (control); if (combo) { activestr = g_value_get_string (value); model = gtk_combo_box_get_model (combo); if (activestr && gtk_tree_model_get_iter_first (model, &iter)) { i = 0; /* look for matching combo text row */ do { gtk_tree_model_get (model, &iter, 0, &str, /* ++ alloc */ -1); if (strcmp (activestr, str) == 0) { g_free (str); /* -- free */ active = i; break; } g_free (str); /* -- free */ i++; } while (gtk_tree_model_iter_next (model, &iter)); g_signal_handlers_block_by_func (combo, combo_box_string_control_changed, control); gtk_combo_box_set_active (combo, active); g_signal_handlers_unblock_by_func (combo, combo_box_string_control_changed, control); } g_object_unref (combo); /* -- unref combo box */ } } /* string combo box changed callback to transmit control change to connected controls */ static void combo_box_string_control_changed (GtkComboBox *combo, gpointer user_data) { SwamiControl *control = SWAMI_CONTROL (user_data); GtkTreeModel *model; GtkTreeIter iter; GValue value = { 0 }; char *str; model = gtk_combo_box_get_model (combo); if (gtk_combo_box_get_active_iter (combo, &iter)) gtk_tree_model_get (model, &iter, 0, &str, /* ++ alloc */ -1); /* transmit the combo box change */ g_value_init (&value, G_TYPE_STRING); g_value_take_string (&value, str); /* !! takes string ownership */ swami_control_transmit_value ((SwamiControl *)control, &value); g_value_unset (&value); } /* * Enum combo box control handler */ static SwamiControl * combo_box_enum_control_handler (GObject *widget, GType value_type, GParamSpec *pspec, SwamiguiControlFlags flags) { SwamiControlFunc *control; GEnumClass *enumklass; GtkCellRenderer *renderer; GtkListStore *store; GtkTreeIter iter; char *s; int i; g_return_val_if_fail (G_TYPE_FUNDAMENTAL (value_type) == G_TYPE_ENUM, NULL); store = gtk_list_store_new (1, G_TYPE_STRING); gtk_combo_box_set_model (GTK_COMBO_BOX (widget), GTK_TREE_MODEL (store)); renderer = gtk_cell_renderer_text_new (); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget), renderer, TRUE); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (widget), renderer, "text", 0, NULL); enumklass = g_type_class_ref (value_type); /* ++ ref enum class */ /* add enum items to combo box */ for (i = 0; i < enumklass->n_values; i++) { gtk_list_store_append (store, &iter); s = g_strdup (enumklass->values[i].value_nick); /* ++ alloc string dup */ s[0] = toupper (s[0]); gtk_list_store_set (store, &iter, 0, _(s), -1); g_free (s); /* -- free string */ } g_type_class_unref (enumklass); /* -- unref enum class */ if (flags & SWAMIGUI_CONTROL_NO_CREATE) return (NULL); g_object_ref (widget); /* ++ ref button widget for control */ if (!pspec) pspec = g_param_spec_enum ("value", "value", "value", value_type, enumklass->minimum, G_PARAM_READWRITE); else g_param_spec_ref (pspec); /* ++ ref for swami_control_set_spec */ control = swami_control_func_new (); swami_control_set_spec ((SwamiControl *)control, pspec); swami_control_func_assign_funcs (control, combo_box_enum_control_get_func, combo_box_enum_control_set_func, NULL, widget); g_signal_connect (widget, "destroy", G_CALLBACK (func_control_cb_widget_destroy), control); if (flags & SWAMIGUI_CONTROL_CTRL) /* controllable? */ { gtk_widget_set_sensitive ((GtkWidget *)widget, TRUE); g_signal_connect (widget, "changed", G_CALLBACK (combo_box_enum_control_changed), control); } else gtk_widget_set_sensitive ((GtkWidget *)widget, FALSE); return (SWAMI_CONTROL (control)); } /* enum combo box handler SwamiControlFunc get value function */ static void combo_box_enum_control_get_func (SwamiControl *control, GValue *value) { GtkComboBox *combo = NULL; GEnumClass *enumklass; GParamSpec *pspec; gpointer data; int active; SWAMI_LOCK_READ (control); data = SWAMI_CONTROL_FUNC_DATA (control); if (data) combo = GTK_COMBO_BOX (g_object_ref (data)); /* ++ ref for outside of lock */ pspec = swami_control_get_spec (control); /* ++ ref param spec */ SWAMI_UNLOCK_READ (control); if (combo) { enumklass = g_type_class_ref (G_PARAM_SPEC_TYPE (pspec)); /* ++ ref enum class */ active = gtk_combo_box_get_active (combo); if (active != -1 && active < enumklass->n_values) g_value_set_enum (value, enumklass->values[active].value); g_type_class_unref (enumklass); /* -- unref enum class */ g_object_unref (combo); /* -- unref combo box */ } g_param_spec_unref (pspec); /* -- unref param spec */ } /* enum combo box handler SwamiControlFunc set value function */ static void combo_box_enum_control_set_func (SwamiControl *control, SwamiControlEvent *event, const GValue *value) { GtkComboBox *combo = NULL; GEnumClass *enumklass; GParamSpec *pspec; gpointer data; int pos, val; GType type; /* minimize lock time - ref the combo box */ SWAMI_LOCK_READ (control); data = SWAMI_CONTROL_FUNC_DATA (control); if (data) combo = GTK_COMBO_BOX (g_object_ref (data)); /* ++ ref combo box */ pspec = swami_control_get_spec (control); /* ++ ref param spec */ SWAMI_UNLOCK_READ (control); type = G_PARAM_SPEC_VALUE_TYPE (pspec); g_param_spec_unref (pspec); /* -- unref param spec */ g_return_if_fail (G_TYPE_FUNDAMENTAL (type) == G_TYPE_ENUM); if (combo) { enumklass = g_type_class_ref (type); /* ++ ref enum class */ val = g_value_get_enum (value); for (pos = 0; pos < enumklass->n_values; pos++) if (enumklass->values[pos].value == val) break; if (pos < enumklass->n_values) { g_signal_handlers_block_by_func (combo, combo_box_enum_control_changed, control); gtk_combo_box_set_active (combo, pos); g_signal_handlers_unblock_by_func (combo, combo_box_enum_control_changed, control); } g_type_class_unref (enumklass); /* -- unref enum class */ g_object_unref (combo); /* -- unref combo box */ } } /* enum combo box changed callback to transmit control change to connected controls */ static void combo_box_enum_control_changed (GtkComboBox *combo, gpointer user_data) { SwamiControl *control = SWAMI_CONTROL (user_data); GEnumClass *enumklass; GParamSpec *pspec; GValue value = { 0 }; GType type; int active; pspec = swami_control_get_spec (control); /* ++ ref param spec */ type = G_PARAM_SPEC_VALUE_TYPE (pspec); g_return_if_fail (G_TYPE_FUNDAMENTAL (type) == G_TYPE_ENUM); enumklass = g_type_class_ref (type); /* ++ ref enum class */ active = gtk_combo_box_get_active (combo); /* transmit the combo box change */ if (active < enumklass->n_values) { g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec)); g_value_set_enum (&value, enumklass->values[active].value); swami_control_transmit_value ((SwamiControl *)control, &value); g_value_unset (&value); } g_type_class_unref (enumklass); /* -- unref enum class */ g_param_spec_unref (pspec); /* -- unref param spec */ } /* * GType combo box control handler */ static SwamiControl * combo_box_gtype_control_handler (GObject *widget, GType value_type, GParamSpec *pspec, SwamiguiControlFlags flags) { SwamiControlFunc *control; GtkCellRenderer *renderer; GtkListStore *store; GtkTreeIter iter; GType basetype; GType *types; char *s; int i; g_return_val_if_fail (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_GTYPE, NULL); store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_GTYPE); gtk_combo_box_set_model (GTK_COMBO_BOX (widget), GTK_TREE_MODEL (store)); renderer = gtk_cell_renderer_text_new (); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget), renderer, TRUE); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (widget), renderer, "text", 0, NULL); basetype = ((GParamSpecGType *)pspec)->is_a_type; /* ++ alloc list of child types of base GType of parameter spec */ types = swami_util_get_child_types (basetype, NULL); /* add types to combo box */ for (i = 0; types[i]; i++) { gtk_list_store_append (store, &iter); s = g_strdup (g_type_name (types[i])); /* ++ alloc string */ gtk_list_store_set (store, &iter, 0, s, 1, types[i], -1); g_free (s); /* -- free string */ } g_free (types); /* -- free type array */ if (flags & SWAMIGUI_CONTROL_NO_CREATE) return (NULL); g_object_ref (widget); /* ++ ref button widget for control */ if (!pspec) pspec = g_param_spec_gtype ("value", "value", "value", basetype, G_PARAM_READWRITE); else g_param_spec_ref (pspec); /* ++ ref for swami_control_set_spec */ control = swami_control_func_new (); swami_control_set_spec ((SwamiControl *)control, pspec); swami_control_func_assign_funcs (control, combo_box_gtype_control_get_func, combo_box_gtype_control_set_func, NULL, widget); g_signal_connect (widget, "destroy", G_CALLBACK (func_control_cb_widget_destroy), control); if (flags & SWAMIGUI_CONTROL_CTRL) /* controllable? */ { gtk_widget_set_sensitive ((GtkWidget *)widget, TRUE); g_signal_connect (widget, "changed", G_CALLBACK (combo_box_gtype_control_changed), control); } else gtk_widget_set_sensitive ((GtkWidget *)widget, FALSE); return (SWAMI_CONTROL (control)); } /* GType combo box handler SwamiControlFunc get value function */ static void combo_box_gtype_control_get_func (SwamiControl *control, GValue *value) { GtkComboBox *combo = NULL; GtkTreeIter iter; GParamSpec *pspec; gpointer data; GType type; SWAMI_LOCK_READ (control); data = SWAMI_CONTROL_FUNC_DATA (control); if (data) combo = GTK_COMBO_BOX (g_object_ref (data)); /* ++ ref for outside of lock */ pspec = swami_control_get_spec (control); /* ++ ref param spec */ SWAMI_UNLOCK_READ (control); if (combo) { if (gtk_combo_box_get_active_iter (combo, &iter)) { /* get the GType value stored for the active item */ gtk_tree_model_get (gtk_combo_box_get_model (combo), &iter, 1, &type, -1); g_value_set_gtype (value, type); } g_object_unref (combo); /* -- unref combo box */ } g_param_spec_unref (pspec); /* -- unref param spec */ } /* GType combo box handler SwamiControlFunc set value function */ static void combo_box_gtype_control_set_func (SwamiControl *control, SwamiControlEvent *event, const GValue *value) { GtkComboBox *combo = NULL; GtkTreeModel *model; gpointer data; GtkTreeIter iter; GType valtype, type; gboolean type_in_list = FALSE; /* minimize lock time - ref the combo box */ SWAMI_LOCK_READ (control); data = SWAMI_CONTROL_FUNC_DATA (control); if (data) combo = GTK_COMBO_BOX (g_object_ref (data)); /* ++ ref combo box */ SWAMI_UNLOCK_READ (control); if (!combo) return; model = gtk_combo_box_get_model (combo); if (gtk_tree_model_get_iter_first (model, &iter)) { valtype = g_value_get_gtype (value); /* look for matching combo box item by GType */ do { gtk_tree_model_get (model, &iter, 1, &type, -1); if (valtype == type) { g_signal_handlers_block_by_func (combo, combo_box_gtype_control_changed, control); gtk_combo_box_set_active_iter (combo, &iter); g_signal_handlers_unblock_by_func (combo, combo_box_gtype_control_changed, control); type_in_list = TRUE; break; } } while (gtk_tree_model_iter_next (model, &iter)); } g_object_unref (combo); /* -- unref combo box */ g_return_if_fail (type_in_list); } /* GType combo box changed callback to transmit control change to connected controls */ static void combo_box_gtype_control_changed (GtkComboBox *combo, gpointer user_data) { SwamiControl *control = SWAMI_CONTROL (user_data); GtkTreeModel *model; GValue value = { 0 }; GtkTreeIter iter; GType type; model = gtk_combo_box_get_model (combo); if (!gtk_combo_box_get_active_iter (combo, &iter)) return; /* get GType of active combo box item */ gtk_tree_model_get (model, &iter, 1, &type, -1); /* transmit the combo box change */ g_value_init (&value, G_TYPE_GTYPE); g_value_set_gtype (&value, type); swami_control_transmit_value ((SwamiControl *)control, &value); g_value_unset (&value); } swami/src/swamigui/CMakeLists.txt0000644000175000017500000001720111464147435017244 0ustar alessioalessio# # Swami # Copyright (C) 1999-2010 Joshua "Element" Green # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; version 2 # of the License only. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA or point your web browser to http://www.gnu.org. # include_directories ( ${CMAKE_SOURCE_DIR}/src ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${GUI_INCLUDEDIR} ${GUI_INCLUDE_DIRS} ${LIBGLADE_INCLUDEDIR} ${LIBGLADE_INCLUDE_DIRS} ${LIBINSTPATCH_INCLUDEDIR} ${LIBINSTPATCH_INCLUDE_DIRS} ) # ************ swamigui Library ************ set ( libswamigui_public_HEADERS SwamiguiBar.h SwamiguiBarPtr.h SwamiguiCanvasMod.h SwamiguiControl.h SwamiguiControlAdj.h SwamiguiControlMidiKey.h SwamiguiItemMenu.h SwamiguiKnob.h SwamiguiLoopFinder.h SwamiguiMenu.h SwamiguiModEdit.h SwamiguiMultiSave.h SwamiguiNoteSelector.h SwamiguiPanel.h SwamiguiPanelSelector.h SwamiguiPanelSF2Gen.h SwamiguiPanelSF2GenEnv.h SwamiguiPanelSF2GenMisc.h SwamiguiPaste.h SwamiguiPiano.h SwamiguiPref.h SwamiguiProp.h SwamiguiRoot.h SwamiguiSampleCanvas.h SwamiguiSampleEditor.h SwamiguiSpectrumCanvas.h SwamiguiSpinScale.h SwamiguiSplits.h SwamiguiStatusbar.h SwamiguiTree.h SwamiguiTreeStore.h SwamiguiTreeStorePatch.h help.h icons.h patch_funcs.h splash.h util.h widgets/combo-box.h widgets/icon-combo.h ) set ( libswamigui_SOURCES SwamiguiBar.c SwamiguiBarPtr.c SwamiguiCanvasMod.c SwamiguiControl.c SwamiguiControl_widgets.c SwamiguiControlAdj.c SwamiguiControlMidiKey.c SwamiguiItemMenu.c SwamiguiItemMenu_actions.c SwamiguiKnob.c SwamiguiLoopFinder.c SwamiguiMenu.c SwamiguiModEdit.c SwamiguiMultiSave.c SwamiguiNoteSelector.c SwamiguiPanel.c SwamiguiPanelSelector.c SwamiguiPanelSF2Gen.c SwamiguiPanelSF2GenEnv.c SwamiguiPanelSF2GenMisc.c SwamiguiPaste.c SwamiguiPiano.c SwamiguiPref.c SwamiguiProp.c SwamiguiRoot.c SwamiguiSampleCanvas.c SwamiguiSampleEditor.c SwamiguiSpectrumCanvas.c SwamiguiSpinScale.c SwamiguiSplits.c SwamiguiStatusbar.c SwamiguiTree.c SwamiguiTreeStore.c SwamiguiTreeStorePatch.c help.c icons.c patch_funcs.c splash.c util.c widgets/combo-box.c widgets/icon-combo.c ) set ( public_main_HEADER swamigui.h ) link_directories ( ${GUI_LIBDIR} ${GUI_LIBRARY_DIRS} ${LIBGLADE_LIBDIR} ${LIBGLADE_LIBRARY_DIRS} ${LIBINSTPATCH_LIBDIR} ${LIBINSTPATCH_LIBRARY_DIRS} ) add_definitions ( -DLOCALEDIR=\"${DATA_INSTALL_DIR}/locale\" -DG_LOG_DOMAIN=\"libswamigui\" ) add_library ( libswamigui ${CMAKE_CURRENT_BINARY_DIR}/builtin_enums.c ${CMAKE_CURRENT_BINARY_DIR}/marshals.c ${libswamigui_SOURCES} ) target_link_libraries ( libswamigui libswami ${GUI_LIBRARIES} ${LIBGLADE_LIBRARIES} ${LIBINSTPATCH_LIBRARIES} ) install ( FILES ${libswamigui_public_HEADERS} ${public_main_HEADER} DESTINATION ${INCLUDE_INSTALL_DIR}/swami/libswamigui ) # ************ Swami GUI application ************ add_executable ( swami main.c ) if ( SWAMI_CPPFLAGS ) set_target_properties ( swami PROPERTIES COMPILE_FLAGS ${SWAMI_CPPFLAGS} ) endif ( SWAMI_CPPFLAGS ) target_link_libraries ( swami libswamigui libswami ${GUI_LIBRARIES} ${LIBGLADE_LIBRARIES} ${LIBINSTPATCH_LIBRARIES} ) # Process subdirectories add_subdirectory ( images ) find_program (GLIB2_MKENUMS glib-mkenums) find_program (SED sed) add_custom_command ( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/builtin_enums.h COMMAND ${GLIB2_MKENUMS} ARGS --fhead \"\#ifndef __SWAMIGUI_BUILTIN_ENUMS_H__\\n\" --fhead \"\#define __SWAMIGUI_BUILTIN_ENUMS_H__\\n\\n\" --fhead \"\#include \\n\\n\" --fhead \"G_BEGIN_DECLS\\n\" --fprod \"/* enumerations from \\"@filename@\\" */\\n\" --vhead \"GType @enum_name@_get_type \(void\)\;\\n\" --vhead \"\#define SWAMIGUI_TYPE_@ENUMSHORT@ \(@enum_name@_get_type\(\)\)\\n\" --ftail \"G_END_DECLS\\n\\n\" --ftail \"\#endif /* __SWAMIGUI_BUILTIN_ENUMS_H__ */\" ${libswamigui_public_HEADERS} > ${CMAKE_CURRENT_BINARY_DIR}/builtin_enums.h WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ${libswamigui_public_HEADERS} ) add_custom_command ( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/builtin_enums.c COMMAND ${GLIB2_MKENUMS} ARGS --fhead \"\#include \\"swamigui.h\\"\\n\" --fprod \"/* enumerations from \\"@filename@\\" */\" --vhead \"static const G@Type@Value _@enum_name@_values[] = {\" --vprod \" { @VALUENAME@, \\"@VALUENAME@\\", \\"@valuenick@\\" },\" --vtail \" { 0, NULL, NULL }\\n}\;\\n\\n\" --vtail \"GType\\n@enum_name@_get_type \(void\)\\n{\\n\" --vtail \" static GType type = 0\;\\n\\n\" --vtail \" if \(G_UNLIKELY \(type == 0\)\)\\n\" --vtail \" type = g_\@type\@_register_static \(\\"@EnumName@\\", _@enum_name@_values\)\;\\n\\n\" --vtail \" return type\;\\n}\\n\\n\" ${libswamigui_public_HEADERS} > ${CMAKE_CURRENT_BINARY_DIR}/builtin_enums.c WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ${libswamigui_public_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/builtin_enums.h ) find_program (GLIB2_GENMARSHAL glib-genmarshal) add_custom_command ( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/marshals.c COMMAND ${GLIB2_GENMARSHAL} ARGS --body --prefix=swamigui_marshal ${CMAKE_CURRENT_SOURCE_DIR}/marshals.list >${CMAKE_CURRENT_BINARY_DIR}/marshals.c WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/marshals.list ${CMAKE_CURRENT_BINARY_DIR}/marshals.h ) add_custom_command ( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/marshals.h COMMAND ${GLIB2_GENMARSHAL} ARGS --header --prefix=swamigui_marshal ${CMAKE_CURRENT_SOURCE_DIR}/marshals.list >${CMAKE_CURRENT_BINARY_DIR}/marshals.h WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/marshals.list ) if ( MACOSX_FRAMEWORK ) set_property ( SOURCE ${libswami_public_HEADERS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/libswamigui ) set_target_properties ( libswamigui PROPERTIES OUTPUT_NAME "libswamigui" FRAMEWORK TRUE PUBLIC_HEADER "${public_main_HEADER}" FRAMEWORK_VERSION "${LIB_VERSION_CURRENT}" INSTALL_NAME_DIR ${FRAMEWORK_INSTALL_DIR} VERSION ${LIB_VERSION_INFO} SOVERSION ${LIB_VERSION_CURRENT} ) else ( MACOSX_FRAMEWORK ) set_target_properties ( libswamigui PROPERTIES PREFIX "lib" OUTPUT_NAME "swamigui" VERSION ${LIB_VERSION_INFO} SOVERSION ${LIB_VERSION_CURRENT} ) endif ( MACOSX_FRAMEWORK ) install ( TARGETS swami libswamigui RUNTIME DESTINATION ${BIN_INSTALL_DIR} LIBRARY DESTINATION ${LIB_INSTALL_DIR}${LIB_SUFFIX} ARCHIVE DESTINATION ${LIB_INSTALL_DIR}${LIB_SUFFIX} FRAMEWORK DESTINATION ${FRAMEWORK_INSTALL_DIR} BUNDLE DESTINATION ${BUNDLE_INSTALL_DIR} ) install ( FILES swami-2.glade DESTINATION ${DATA_INSTALL_DIR}/swami ) swami/src/swamigui/splash.c0000644000175000017500000000703211464144605016137 0ustar alessioalessio/* * splash.c - Swami startup splash image functions * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include "config.h" #include #include #include "splash.h" #include #include "util.h" static void cb_win_destroy (GtkWidget *win); static gboolean cb_button_press (GtkWidget *widg, GdkEventButton *ev); static GtkWidget *splash_win = NULL; static gboolean splash_timeout_active = FALSE; static guint splash_timeout_h; /** * swamigui_splash_display: * @timeout: Timeout in milliseconds or 0 to wait for button click * * Display the Swami splash startup image. If @timeout is %TRUE then the * splash image will be destroyed after a timeout period. */ void swamigui_splash_display (guint timeout) { GtkWidget *image; GdkPixbuf *pixbuf; char *filename; if (splash_win) /* Only one instance at a time :) */ { swamigui_splash_kill (); /* Kill current instance of splash */ return; } #ifdef SOURCE_BUILD /* load splash image from source dir? */ filename = SOURCE_DIR "/src/swamigui/images/splash.png"; #else filename = IMAGES_DIR G_DIR_SEPARATOR_S "splash.png"; #endif pixbuf = gdk_pixbuf_new_from_file (filename, NULL); /* ++ ref new pixbuf */ if (!pixbuf) return; /* fail silently if splash image load fails */ /* splash popup window */ splash_win = gtk_window_new (GTK_WINDOW_POPUP); gtk_window_set_policy (GTK_WINDOW (splash_win), FALSE, FALSE, FALSE); gtk_signal_connect (GTK_OBJECT (splash_win), "destroy", GTK_SIGNAL_FUNC (cb_win_destroy), NULL); gtk_signal_connect (GTK_OBJECT (splash_win), "button-press-event", GTK_SIGNAL_FUNC (cb_button_press), NULL); gtk_widget_add_events (splash_win, GDK_BUTTON_PRESS_MASK); image = gtk_image_new_from_pixbuf (pixbuf); gtk_container_add (GTK_CONTAINER (splash_win), image); gtk_widget_show (image); gtk_window_set_position (GTK_WINDOW (splash_win), GTK_WIN_POS_CENTER); gtk_widget_show (splash_win); g_object_unref (pixbuf); /* -- unref pixbuf creator's ref */ if (timeout) { splash_timeout_active = TRUE; splash_timeout_h = g_timeout_add (timeout, (GSourceFunc)swamigui_splash_kill, NULL); } } /** * swamigui_splash_kill: * * Kills a currently displayed splash image. * * Returns: Always returns %FALSE, since it is used as a GSourceFunc for the * timeout. */ gboolean /* so it can be used as timeout GSourceFunc */ swamigui_splash_kill (void) { if (splash_win) { if (splash_timeout_active) gtk_timeout_remove (splash_timeout_h); gtk_widget_destroy (splash_win); } splash_timeout_active = FALSE; return (FALSE); } static void cb_win_destroy (GtkWidget *win) { splash_win = NULL; } static gboolean cb_button_press (GtkWidget *widg, GdkEventButton *ev) { swamigui_splash_kill (); return (FALSE); } swami/src/swamigui/SwamiguiCanvasMod.h0000644000175000017500000001340211461334205020223 0ustar alessioalessio/* * SwamiguiCanvasMod.h - Zoom/Scroll canvas modulation object * Allows scroll/zoom of canvas as a user interface. * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_CANVAS_MOD_H__ #define __SWAMIGUI_CANVAS_MOD_H__ #include #include typedef struct _SwamiguiCanvasMod SwamiguiCanvasMod; typedef struct _SwamiguiCanvasModClass SwamiguiCanvasModClass; #define SWAMIGUI_TYPE_CANVAS_MOD (swamigui_canvas_mod_get_type ()) #define SWAMIGUI_CANVAS_MOD(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMIGUI_TYPE_CANVAS_MOD, \ SwamiguiCanvasMod)) #define SWAMIGUI_CANVAS_MOD_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMIGUI_TYPE_CANVAS_MOD, \ SwamiguiCanvasModClass)) #define SWAMIGUI_IS_CANVAS_MOD(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMIGUI_TYPE_CANVAS_MOD)) #define SWAMIGUI_IS_CANVAS_MOD_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMIGUI_TYPE_CANVAS_MOD)) /* Canvas modulation type */ typedef enum { SWAMIGUI_CANVAS_MOD_SNAP_ZOOM, /* snap line zoom */ SWAMIGUI_CANVAS_MOD_WHEEL_ZOOM, /* wheel zoom */ SWAMIGUI_CANVAS_MOD_SNAP_SCROLL, /* snap line scroll */ SWAMIGUI_CANVAS_MOD_WHEEL_SCROLL /* wheel scroll */ } SwamiguiCanvasModType; #define SWAMIGUI_CANVAS_MOD_TYPE_COUNT 4 /* axis enum */ typedef enum { SWAMIGUI_CANVAS_MOD_X, SWAMIGUI_CANVAS_MOD_Y } SwamiguiCanvasModAxis; #define SWAMIGUI_CANVAS_MOD_AXIS_COUNT 2 typedef enum { SWAMIGUI_CANVAS_MOD_ENABLED = 1 << 0 /* TRUE if modulator is enabled */ } SwamiguiCanvasModFlags; /* Modifier action flags */ typedef enum { SWAMIGUI_CANVAS_MOD_ZOOM_X = 1 << 0, SWAMIGUI_CANVAS_MOD_ZOOM_Y = 1 << 1, SWAMIGUI_CANVAS_MOD_SCROLL_X = 1 << 2, SWAMIGUI_CANVAS_MOD_SCROLL_Y = 1 << 3 } SwamiguiCanvasModActions; /* Variables used for zoom/scroll equation */ typedef struct { double mult; double power; double ofs; } SwamiguiCanvasModVars; /* canvas zoom object */ struct _SwamiguiCanvasMod { GObject parent_instance; guint zoom_modifier; /* GdkModifierType for zooming */ guint scroll_modifier; /* GdkModifierType for scrolling */ guint axis_modifier; /* GdkModifierType to toggle axis */ guint8 snap_button; /* snap mouse button # (1-5) */ guint8 def_action_zoom; /* TRUE: Zoom = def, FALSE: Scroll = def */ guint8 def_zoom_axis; /* default SwamiguiCanvasModAxis for zoom */ guint8 def_scroll_axis; /* default SwamiguiCanvasModAxis for scroll */ guint32 one_wheel_time; /* time in msecs for first mouse wheel event */ double min_zoom; /* minimum zoom value */ double max_zoom; /* maximum zoom value */ double min_scroll; /* minimum scroll value */ double max_scroll; /* maximum scroll value */ /* variables for [modulator][axis] scroll/zoom equations */ SwamiguiCanvasModVars vars[SWAMIGUI_CANVAS_MOD_AXIS_COUNT][SWAMIGUI_CANVAS_MOD_TYPE_COUNT]; guint timeout_handler; /* timeout callback handler ID */ guint timeout_interval; /* timeout handler interval in msecs */ guint wheel_timeout; /* inactive time in msecs of wheel till stop */ /* for mouse wheel zooming */ GdkScrollDirection last_wheel_dir; /* last wheel direction (UP/DOWN/INACTIVE) */ guint32 last_wheel_time; /* last event time stamp of mouse wheel */ guint32 wheel_time; /* current wheel time value (between events) */ int xwheel; /* X coordinate of last wheel event */ int ywheel; /* Y coordinate of last wheel event */ /* also stores the last wheel time, but in clock time since it doesn't appear * we can arbitrarily load the #&^@ing GDK event time in the timeout callback */ GTimeVal last_wheel_real_time; gboolean snap_active; /* TRUE if snap is active */ int xsnap; /* X coordinate of snap */ int ysnap; /* Y coordinate of snap */ int cur_xsnap; /* current X coordinate */ int cur_ysnap; /* current Y coordinate */ gboolean cur_xchange; /* X coordinate has changed? (needs refresh) */ gboolean cur_ychange; /* Y coordinate has changed? (needs refresh) */ double xzoom_amt; /* current X zoom amount */ double yzoom_amt; /* current Y zoom amount */ double xscroll_amt; /* current X scroll amount */ double yscroll_amt; /* current Y scroll amount */ }; struct _SwamiguiCanvasModClass { GObjectClass parent_class; /* zoom/scroll update signal (zoom = 1.0 or scroll = 0.0 for no change) */ void (* update)(SwamiguiCanvasMod *mod, double xzoom, double yzoom, double xscroll, double yscroll, double xpos, double ypos); void (* snap)(SwamiguiCanvasMod *mod, guint actions, double xsnap, double ysnap); }; GType swamigui_canvas_mod_get_type (void); SwamiguiCanvasMod *swamigui_canvas_mod_new (void); void swamigui_canvas_mod_set_vars (SwamiguiCanvasMod *mod, SwamiguiCanvasModAxis axis, SwamiguiCanvasModType type, double mult, double power, double ofs); void swamigui_canvas_mod_get_vars (SwamiguiCanvasMod *mod, SwamiguiCanvasModAxis axis, SwamiguiCanvasModType type, double *mult, double *power, double *ofs); gboolean swamigui_canvas_mod_handle_event (SwamiguiCanvasMod *mod, GdkEvent *event); #endif swami/src/swamigui/SwamiguiPref.h0000644000175000017500000000507011461404311017242 0ustar alessioalessio/* * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ /** * SECTION: SwamiguiPref * @short_description: Swami preferences widget and registration * @see_also: * @stability: Stable * * Swami GUI preferences widget and preference interface registration. */ #ifndef __SWAMIGUI_PREF_H__ #define __SWAMIGUI_PREF_H__ #include typedef struct _SwamiguiPref SwamiguiPref; typedef struct _SwamiguiPrefClass SwamiguiPrefClass; #define SWAMIGUI_TYPE_PREF (swamigui_pref_get_type ()) #define SWAMIGUI_PREF(obj) \ (GTK_CHECK_CAST ((obj), SWAMIGUI_TYPE_PREF, SwamiguiPref)) #define SWAMIGUI_PREF_CLASS(klass) \ (GTK_CHECK_CLASS_CAST ((klass), SWAMIGUI_TYPE_PREF, SwamiguiPrefClass)) #define SWAMIGUI_IS_PREF(obj) \ (GTK_CHECK_TYPE ((obj), SWAMIGUI_TYPE_PREF)) #define SWAMIGUI_IS_PREF_CLASS(klass) \ (GTK_CHECK_CLASS_TYPE ((klass), SWAMIGUI_TYPE_PREF)) /* Swami preferences widget */ struct _SwamiguiPref { GtkDialog parent; /*< private >*/ GtkWidget *notebook; /* invisible notebook with preference sections */ }; /* Swami preferences widget class */ struct _SwamiguiPrefClass { GtkDialogClass parent_class; }; /** * SwamiguiPrefHandler: * * Function prototype to create a GUI preference interface. * * Returns: The toplevel widget of the preference interface. */ typedef GtkWidget * (*SwamiguiPrefHandler)(void); /** * SWAMIGUI_PREF_ORDER_NAME: * * Value to use for order parameter of swamigui_register_pref_handler() to * sort by name. This should be used for plugins and other interfaces where * specific placement in the preferences list is not needed. */ #define SWAMIGUI_PREF_ORDER_NAME 0 void swamigui_register_pref_handler (const char *name, const char *icon, int order, SwamiguiPrefHandler handler); GType swamigui_pref_get_type (void); GtkWidget *swamigui_pref_new (void); #endif swami/src/swamigui/SwamiguiLoopFinder.c0000644000175000017500000004136511461334205020415 0ustar alessioalessio/* * SwamiguiLoopFinder.c - Sample loop finder widget * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * Thanks to Luis Garrido for the loop finder algorithm code and his * interest in creating this feature for Swami. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include "SwamiguiLoopFinder.h" #include "SwamiguiControl.h" #include "SwamiguiRoot.h" #include "util.h" #include "i18n.h" enum { PROP_0, PROP_FINDER }; /* columns for result list store */ enum { SIZE_COLUMN, START_COLUMN, END_COLUMN, QUALITY_COLUMN }; /* GUI worker thread monitor callback interval in milliseconds */ #define PROGRESS_UPDATE_INTERVAL 100 static void swamigui_loop_finder_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void swamigui_loop_finder_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void swamigui_loop_finder_init (SwamiguiLoopFinder *editor); static void swamigui_loop_finder_finalize (GObject *object); static void swamigui_loop_finder_destroy (GtkObject *object); static void swamigui_loop_finder_cb_selection_changed (GtkTreeSelection *selection, gpointer user_data); static void swamigui_loop_finder_cb_revert (GtkButton *button, gpointer user_data); static void swamigui_loop_finder_cb_find (GtkButton *button, gpointer user_data); static void swamigui_loop_finder_update_find_button (SwamiguiLoopFinder *finder, gboolean find); static gboolean swamigui_loop_finder_thread_monitor (gpointer user_data); static gpointer find_loop_thread (gpointer data); G_DEFINE_TYPE (SwamiguiLoopFinder, swamigui_loop_finder, GTK_TYPE_VBOX); static void swamigui_loop_finder_class_init (SwamiguiLoopFinderClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); GtkObjectClass *gtkobj_class = GTK_OBJECT_CLASS (klass); obj_class->set_property = swamigui_loop_finder_set_property; obj_class->get_property = swamigui_loop_finder_get_property; obj_class->finalize = swamigui_loop_finder_finalize; gtkobj_class->destroy = swamigui_loop_finder_destroy; g_object_class_install_property (obj_class, PROP_FINDER, g_param_spec_object ("finder", _("Finder"), _("Loop finder object"), SWAMI_TYPE_LOOP_FINDER, G_PARAM_READABLE)); } static void swamigui_loop_finder_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { switch (property_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_loop_finder_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { SwamiguiLoopFinder *finder = SWAMIGUI_LOOP_FINDER (object); switch (property_id) { case PROP_FINDER: g_value_set_object (value, finder->loop_finder); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_loop_finder_init (SwamiguiLoopFinder *finder) { GtkCellRenderer *renderer; GtkTreeViewColumn *column; GtkTreeSelection *selection; GtkWidget *treeview; GtkWidget *widg; /* create the loop finder object (!! takes over ref) */ finder->loop_finder = swami_loop_finder_new (); /* create result list store */ finder->store = gtk_list_store_new (4, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_FLOAT); /* create Glade GTK loop finder interface */ finder->glade_widg = swamigui_util_glade_create ("LoopFinder"); gtk_container_add (GTK_CONTAINER (finder), finder->glade_widg); /* fetch the tree view widget (result list) */ treeview = swamigui_util_glade_lookup (finder->glade_widg, "ListMatches"); /* Disable tree view search since it breaks piano key playback */ g_object_set (treeview, "enable-search", FALSE, NULL); /* add size column to tree view widget */ renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes (_("Loop size"), renderer, "text", SIZE_COLUMN, NULL); gtk_tree_view_column_set_sort_column_id (column, SIZE_COLUMN); gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); /* add start column to tree view widget */ renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes (_("Loop start"), renderer, "text", START_COLUMN, NULL); gtk_tree_view_column_set_sort_column_id (column, START_COLUMN); gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); /* add end column to tree view widget */ renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes (_("Loop end"), renderer, "text", END_COLUMN, NULL); gtk_tree_view_column_set_sort_column_id (column, END_COLUMN); gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); /* add quality column to tree view widget */ renderer = gtk_cell_renderer_progress_new (); column = gtk_tree_view_column_new_with_attributes (_("Rating"), renderer, "value", QUALITY_COLUMN, NULL); gtk_tree_view_column_set_sort_column_id (column, QUALITY_COLUMN); gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); /* assign the tree store */ gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (finder->store)); /* connect to list view selection changed signal */ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); g_signal_connect (selection, "changed", G_CALLBACK (swamigui_loop_finder_cb_selection_changed), finder); /* connect analysis window spin button to finder's property */ widg = swamigui_util_glade_lookup (finder->glade_widg, "SpinAnalysisWindow"); swamigui_control_prop_connect_widget (G_OBJECT (finder->loop_finder), "analysis-window", G_OBJECT (widg)); /* connect min loop spin button to finder's property */ widg = swamigui_util_glade_lookup (finder->glade_widg, "SpinMinLoop"); swamigui_control_prop_connect_widget (G_OBJECT (finder->loop_finder), "min-loop-size", G_OBJECT (widg)); /* connect max results spin button to finder's property */ widg = swamigui_util_glade_lookup (finder->glade_widg, "SpinMaxResults"); swamigui_control_prop_connect_widget (G_OBJECT (finder->loop_finder), "max-results", G_OBJECT (widg)); /* connect group pos diff spin button to finder's property */ widg = swamigui_util_glade_lookup (finder->glade_widg, "SpinGroupPosDiff"); swamigui_control_prop_connect_widget (G_OBJECT (finder->loop_finder), "group-pos-diff", G_OBJECT (widg)); /* connect group size diff spin button to finder's property */ widg = swamigui_util_glade_lookup (finder->glade_widg, "SpinGroupSizeDiff"); swamigui_control_prop_connect_widget (G_OBJECT (finder->loop_finder), "group-size-diff", G_OBJECT (widg)); widg = swamigui_util_glade_lookup (finder->glade_widg, "BtnRevert"); g_signal_connect (widg, "clicked", G_CALLBACK (swamigui_loop_finder_cb_revert), finder); /* find button has nothing packed in it, initialize it */ swamigui_loop_finder_update_find_button (finder, TRUE); widg = swamigui_util_glade_lookup (finder->glade_widg, "BtnFind"); g_signal_connect (widg, "clicked", G_CALLBACK (swamigui_loop_finder_cb_find), finder); } static void swamigui_loop_finder_finalize (GObject *object) { SwamiguiLoopFinder *finder = SWAMIGUI_LOOP_FINDER (object); g_object_unref (finder->loop_finder); if (G_OBJECT_CLASS (swamigui_loop_finder_parent_class)->finalize) G_OBJECT_CLASS (swamigui_loop_finder_parent_class)->finalize (object); } /* loop finder widget destroy */ static void swamigui_loop_finder_destroy (GtkObject *object) { SwamiguiLoopFinder *finder = SWAMIGUI_LOOP_FINDER (object); /* signal loop finder object to stop (does nothing if not active) */ g_object_set (finder->loop_finder, "cancel", TRUE, NULL); } static void swamigui_loop_finder_cb_selection_changed (GtkTreeSelection *selection, gpointer user_data) { SwamiguiLoopFinder *finder = SWAMIGUI_LOOP_FINDER (user_data); IpatchSample *sample; GtkTreeModel *model; GtkTreeIter iter; guint loop_start, loop_end; g_object_get (finder->loop_finder, "sample", &sample, NULL); /* ++ ref */ if (!sample) return; if (!gtk_tree_selection_get_selected (selection, &model, &iter)) { g_object_unref (sample); /* -- unref */ return; } gtk_tree_model_get (model, &iter, START_COLUMN, &loop_start, END_COLUMN, &loop_end, -1); g_object_set (sample, "loop-start", loop_start, "loop-end", loop_end, NULL); g_object_unref (sample); /* -- unref */ } /* button to revert to original loop settings */ static void swamigui_loop_finder_cb_revert (GtkButton *button, gpointer user_data) { SwamiguiLoopFinder *finder = SWAMIGUI_LOOP_FINDER (user_data); IpatchSample *sample; g_object_get (finder->loop_finder, "sample", &sample, NULL); /* ++ ref */ if (!sample) return; /* restore original loop */ g_object_set (sample, "loop-start", finder->orig_loop_start, "loop-end", finder->orig_loop_end, NULL); g_object_unref (sample); /* -- unref */ } static void swamigui_loop_finder_cb_find (GtkButton *button, gpointer user_data) { SwamiguiLoopFinder *finder = SWAMIGUI_LOOP_FINDER (user_data); GtkWidget *main_window; GtkWidget *dialog; IpatchSample *sample; GtkWidget *label; GError *err = NULL; gboolean active; g_object_get (finder->loop_finder, "sample", &sample, /* ++ ref */ "active", &active, NULL); if (!sample) return; /* store original loop start/end before any changes (for revert button) */ g_object_get (sample, "loop-start", &finder->orig_loop_start, "loop-end", &finder->orig_loop_end, NULL); g_object_unref (sample); /* -- unref */ if (active) /* if already active, tell it to stop */ { g_object_set (finder->loop_finder, "cancel", TRUE, NULL); return; } /* clear time ellapsed label */ label = swamigui_util_glade_lookup (finder->glade_widg, "LabelTime"); gtk_label_set_text (GTK_LABEL (label), ""); #if 0 { /* For debugging */ SwamiLoopFinder *f = finder->loop_finder; printf ("analysis=%d minloop=%d swinpos=%d swinsize=%d ewinpos=%d ewinsize=%d\n", f->analysis_window, f->min_loop_size, f->start_window_pos, f->start_window_size, f->end_window_pos, f->end_window_size); } #endif /* verify loop finder parameters and nudge them if needed */ if (!swami_loop_finder_verify_params (finder->loop_finder, TRUE, &err)) { g_object_get (swamigui_root, "main-window", &main_window, NULL); dialog = gtk_message_dialog_new (GTK_WINDOW (main_window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, _("Loop find failed: %s"), ipatch_gerror_message (err)); if (err) g_error_free (err); /* Destroy the dialog when the user responds to it */ g_signal_connect_swapped (dialog, "response", G_CALLBACK (gtk_widget_destroy), dialog); return; } #if 0 { /* For debugging */ SwamiLoopFinder *f = finder->loop_finder; printf ("analysis=%d minloop=%d swinpos=%d swinsize=%d ewinpos=%d ewinsize=%d\n", f->analysis_window, f->min_loop_size, f->start_window_pos, f->start_window_size, f->end_window_pos, f->end_window_size); } #endif /* create a thread to do the work */ if (!g_thread_create (find_loop_thread, finder, FALSE, &err)) { g_critical (_("Failed to start loop finder thread: %s"), ipatch_gerror_message (err)); if (err) g_error_free (err); return; } /* update the find button to "Stop" state */ swamigui_loop_finder_update_find_button (finder, FALSE); /* ++ ref finder for worker thread (unref'd in thread monitor timeout) */ g_object_ref (finder); g_timeout_add (PROGRESS_UPDATE_INTERVAL, swamigui_loop_finder_thread_monitor, finder); } /* modifies the find button to reflect the current state (Execute or Stop) */ static void swamigui_loop_finder_update_find_button (SwamiguiLoopFinder *finder, gboolean find) { GtkWidget *btn; GtkWidget *hbox; GtkWidget *image; GtkWidget *label; GList *children, *p; btn = swamigui_util_glade_lookup (finder->glade_widg, "BtnFind"); /* remove current widgets in button */ children = gtk_container_get_children (GTK_CONTAINER (btn)); for (p = children; p; p = p->next) gtk_container_remove (GTK_CONTAINER (btn), GTK_WIDGET (p->data)); g_list_free (children); hbox = gtk_hbox_new (FALSE, 2); gtk_container_add (GTK_CONTAINER (btn), hbox); image = gtk_image_new_from_stock (find ? GTK_STOCK_EXECUTE : GTK_STOCK_STOP, GTK_ICON_SIZE_BUTTON); label = gtk_label_new (find ? _("Find Loops") : _("Stop")); gtk_box_pack_start (GTK_BOX (hbox), image, 0, 0, 0); gtk_box_pack_start (GTK_BOX (hbox), label, 0, 0, 0); gtk_widget_show_all (hbox); } /* monitors worker thread activity and updates GUI */ static gboolean swamigui_loop_finder_thread_monitor (gpointer user_data) { SwamiguiLoopFinder *finder = SWAMIGUI_LOOP_FINDER (user_data); SwamiLoopResults *results; SwamiLoopMatch *matches; GtkTreeIter iter; GtkWidget *label; GtkWidget *prog_widg; float cur_progress; float maxq, diffq, quality; gboolean active; guint match_count; guint exectime; char *s; int i; /* read progress float */ g_object_get (finder->loop_finder, "progress", &cur_progress, "active", &active, NULL); /* progress changed from previous value? */ if (cur_progress != finder->prev_progress) { prog_widg = swamigui_util_glade_lookup (finder->glade_widg, "Progress"); gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (prog_widg), cur_progress); finder->prev_progress = cur_progress; } /* stop the monitor timeout callback if thread is done */ if (!active) { /* update the time ellapsed label */ g_object_get (finder->loop_finder, "exec-time", &exectime, NULL); s = g_strdup_printf (_("%0.2f secs"), exectime / 1000.0); label = swamigui_util_glade_lookup (finder->glade_widg, "LabelTime"); gtk_label_set_text (GTK_LABEL (label), s); g_free (s); swamigui_loop_finder_update_find_button (finder, TRUE); results = swami_loop_finder_get_results (finder->loop_finder); /* ++ ref */ if (!results) return (FALSE); /* no results? */ matches = swami_loop_results_get_values (results, &match_count); gtk_list_store_clear (finder->store); /* clear all items in store */ if (match_count > 0) { maxq = matches[0].quality; diffq = matches[match_count - 1].quality - maxq; } for (i = 0; i < match_count; i++) /* loop over result matches */ { gtk_list_store_append (finder->store, &iter); quality = 100.0 - (matches[i].quality - maxq) / diffq * 100.0; gtk_list_store_set (finder->store, &iter, SIZE_COLUMN, matches[i].end - matches[i].start, START_COLUMN, (guint)matches[i].start, END_COLUMN, (guint)matches[i].end, QUALITY_COLUMN, quality, -1); } g_object_unref (results); /* -- unref */ /* -- remove reference added for worker thread (in cb_find) */ g_object_unref (finder); return (FALSE); /* monitor thread not needed anymore */ } else return (TRUE); } /** * swamigui_loop_finder_new: * * Create a new sample loop finder widget. * * Returns: New widget of type SwamiguiLoopFinder */ GtkWidget * swamigui_loop_finder_new (void) { return (GTK_WIDGET (gtk_type_new (SWAMIGUI_TYPE_LOOP_FINDER))); } static gpointer find_loop_thread (gpointer data) { SwamiguiLoopFinder *finder = SWAMIGUI_LOOP_FINDER (data); GError *err = NULL; if (!swami_loop_finder_find (finder->loop_finder, &err)) { g_critical (_("Find thread failed: %s"), ipatch_gerror_message (err)); if (err) g_error_free (err); } return (NULL); } /** * swamigui_loop_finder_clear_results: * @finder: Loop finder GUI widget * * Clear results of a loop finder widget (if any). */ void swamigui_loop_finder_clear_results (SwamiguiLoopFinder *finder) { g_return_if_fail (SWAMIGUI_IS_LOOP_FINDER (finder)); gtk_list_store_clear (finder->store); } swami/src/swamigui/SwamiguiPythonView.c0000644000175000017500000002351511461334205020465 0ustar alessioalessio/* * SwamiguiPythonView.c - Python source view script editor and shell. * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* FIXME - Hardcoded for now until... */ #define SCRIPT_PATH "/home/josh/.swami-1/scripts" #include #include #include #include #include #ifdef GTK_SOURCE_VIEW_SUPPORT #include #include #include #endif #include "SwamiguiPythonView.h" #include "swami_python.h" #include "util.h" #include "i18n.h" static void swamigui_python_view_refresh_scripts (void); static void swamigui_python_view_class_init (SwamiguiPythonViewClass *klass); static void swamigui_python_view_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void swamigui_python_view_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void swamigui_python_view_init (SwamiguiPythonView *pyview); static void swamigui_python_view_scripts_combo_changed (GtkComboBox *combo, gpointer user_data); static gboolean swamigui_python_view_cb_key_press (GtkWidget *widget, GdkEventKey *event, gpointer user_data); static void swamigui_python_view_python_output_func (const char *output, gboolean is_stderr); static void swamigui_python_view_cb_execute_clicked (GtkButton *button, gpointer user_data); /* view to send Python output to */ static SwamiguiPythonView *output_view = NULL; static GtkListStore *scriptstore = NULL; /* list store for scripts */ /* refresh the list of python scripts */ static void swamigui_python_view_refresh_scripts (void) { const char *fname; GtkTreeIter iter; GDir *dir; if (scriptstore) gtk_list_store_clear (scriptstore); else scriptstore = gtk_list_store_new (1, G_TYPE_STRING); dir = g_dir_open (SCRIPT_PATH, 0, NULL); while ((fname = g_dir_read_name (dir))) { gtk_list_store_append (scriptstore, &iter); gtk_list_store_set (scriptstore, &iter, 0, fname, -1); } g_dir_close (dir); } GType swamigui_python_view_get_type (void) { static GType obj_type = 0; if (!obj_type) { static const GTypeInfo obj_info = { sizeof (SwamiguiPythonViewClass), NULL, NULL, (GClassInitFunc) swamigui_python_view_class_init, NULL, NULL, sizeof (SwamiguiPythonView), 0, (GInstanceInitFunc) swamigui_python_view_init, }; obj_type = g_type_register_static (GTK_TYPE_VBOX, "SwamiguiPythonView", &obj_info, 0); } return (obj_type); } static void swamigui_python_view_class_init (SwamiguiPythonViewClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); obj_class->set_property = swamigui_python_view_set_property; obj_class->get_property = swamigui_python_view_get_property; swamigui_python_view_refresh_scripts (); } static void swamigui_python_view_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { // SwamiguiPythonView *pyview = SWAMIGUI_PYTHON_VIEW (object); switch (property_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_python_view_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { // SwamiguiPythonView *pyview = SWAMIGUI_PYTHON_VIEW (object); switch (property_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_python_view_init (SwamiguiPythonView *pyview) { GtkWidget *frame; GtkWidget *btn; GtkCellRenderer *renderer; #ifdef GTK_SOURCE_VIEW_SUPPORT GtkSourceLanguagesManager *lm; GtkSourceLanguage *lang; #endif pyview->glade_widg = swamigui_util_glade_create ("PythonEditor"); gtk_container_add (GTK_CONTAINER (pyview), pyview->glade_widg); pyview->comboscripts = swamigui_util_glade_lookup (pyview->glade_widg, "ComboScripts"); gtk_combo_box_set_model (GTK_COMBO_BOX (pyview->comboscripts), GTK_TREE_MODEL (scriptstore)); gtk_combo_box_entry_set_text_column (GTK_COMBO_BOX_ENTRY (pyview->comboscripts), 0); g_signal_connect (pyview->comboscripts, "changed", G_CALLBACK (swamigui_python_view_scripts_combo_changed), pyview); renderer = gtk_cell_renderer_text_new (); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (pyview->comboscripts), renderer, TRUE); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (pyview->comboscripts), renderer, "text", 0, NULL); frame = swamigui_util_glade_lookup (pyview->glade_widg, "ScrollScriptEditor"); #ifdef GTK_SOURCE_VIEW_SUPPORT lm = gtk_source_languages_manager_new (); lang = gtk_source_languages_manager_get_language_from_mime_type (lm, "text/x-python"); if (lang) pyview->srcbuf = GTK_TEXT_BUFFER (gtk_source_buffer_new_with_language (lang)); else pyview->srcbuf = GTK_TEXT_BUFFER (gtk_source_buffer_new (NULL)); gtk_source_buffer_set_highlight (GTK_SOURCE_BUFFER (pyview->srcbuf), TRUE); pyview->srcview = gtk_source_view_new_with_buffer (GTK_SOURCE_BUFFER (pyview->srcbuf)); #else pyview->srcbuf = gtk_text_buffer_new (NULL); pyview->srcview = gtk_text_view_new_with_buffer (pyview->srcbuf); #endif gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (pyview->srcview), GTK_WRAP_CHAR); g_signal_connect (pyview->srcview, "key-press-event", G_CALLBACK (swamigui_python_view_cb_key_press), pyview); gtk_widget_show (pyview->srcview); gtk_container_add (GTK_CONTAINER (frame), pyview->srcview); pyview->conbuf = gtk_text_buffer_new (NULL); pyview->conview = swamigui_util_glade_lookup (pyview->glade_widg, "TxtPyConsole"); gtk_text_view_set_buffer (GTK_TEXT_VIEW (pyview->conview), pyview->conbuf); btn = swamigui_util_glade_lookup (pyview->glade_widg, "BtnExecute"); g_signal_connect (btn, "clicked", G_CALLBACK (swamigui_python_view_cb_execute_clicked), pyview); } static void swamigui_python_view_scripts_combo_changed (GtkComboBox *combo, gpointer user_data) { SwamiguiPythonView *pyview = SWAMIGUI_PYTHON_VIEW (user_data); char *fname, *fullname, *buf; GtkTreeModel *model; GtkTreeIter iter; if (!gtk_combo_box_get_active_iter (combo, &iter)) return; model = gtk_combo_box_get_model (combo); gtk_tree_model_get (model, &iter, 0, &fname, -1); fullname = g_strconcat (SCRIPT_PATH, G_DIR_SEPARATOR_S, fname, NULL); g_free (fname); if (!g_file_get_contents (fullname, &buf, NULL, NULL)) { g_free (fullname); return; } g_free (fullname); gtk_text_buffer_set_text (pyview->srcbuf, buf, -1); g_free (buf); } static gboolean swamigui_python_view_cb_key_press (GtkWidget *widget, GdkEventKey *event, gpointer user_data) { SwamiguiPythonView *pyview = SWAMIGUI_PYTHON_VIEW (user_data); GtkWidget *btn; GtkTextMark *cursor; GtkTextIter start_iter, end_iter; char *cmd; if (event->keyval != GDK_Return) return (FALSE); /* return if not in "shell mode" (ENTER executes line) */ btn = swamigui_util_glade_lookup (pyview->glade_widg, "BtnShellMode"); if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (btn))) return (FALSE); /* get cursor position */ cursor = gtk_text_buffer_get_insert (pyview->srcbuf); /* get an iterator for the cursor (end of line) */ gtk_text_buffer_get_iter_at_mark (pyview->srcbuf, &end_iter, cursor); start_iter = end_iter; /* copy iterator */ /* set the iterator to the beginning of the line */ gtk_text_iter_set_line_offset (&start_iter, 0); cmd = gtk_text_buffer_get_text (pyview->srcbuf, &start_iter, &end_iter, FALSE); if (cmd && cmd[0]) /* some command to execute? */ { /* set current output view and Python log function */ output_view = pyview; swamigui_python_set_output_func (swamigui_python_view_python_output_func); PyRun_SimpleString (cmd); output_view = NULL; } g_free (cmd); return (FALSE); } static void swamigui_python_view_python_output_func (const char *output, gboolean is_stderr) { GtkTextIter iter; if (!output_view) return; gtk_text_buffer_get_end_iter (output_view->conbuf, &iter); gtk_text_buffer_insert (output_view->conbuf, &iter, output, -1); } /* Glade callback for Execute toolbar button */ static void swamigui_python_view_cb_execute_clicked (GtkButton *button, gpointer user_data) { SwamiguiPythonView *pyview = SWAMIGUI_PYTHON_VIEW (user_data); GtkTextIter start, end; char *script; gtk_text_buffer_get_bounds (pyview->srcbuf, &start, &end); script = gtk_text_buffer_get_text (pyview->srcbuf, &start, &end, FALSE); output_view = pyview; swamigui_python_set_output_func (swamigui_python_view_python_output_func); PyRun_SimpleString (script); output_view = NULL; g_free (script); } /** * swamigui_python_view_new: * * Create a new GUI python view shell widget. * * Returns: New swami GUI python view. */ GtkWidget * swamigui_python_view_new (void) { return (GTK_WIDGET (g_object_new (SWAMIGUI_TYPE_PYTHON_VIEW, NULL))); } swami/src/swamigui/SwamiguiSplits.h0000644000175000017500000002007111461334205017626 0ustar alessioalessio/* * SwamiguiSplits.h - Key/velocity splits widget header file * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_SPLITS_H__ #define __SWAMIGUI_SPLITS_H__ #include #include #include typedef struct _SwamiguiSplits SwamiguiSplits; typedef struct _SwamiguiSplitsClass SwamiguiSplitsClass; typedef struct _SwamiguiSplitsEntry SwamiguiSplitsEntry; #include "SwamiguiPiano.h" #define SWAMIGUI_TYPE_SPLITS (swamigui_splits_get_type ()) #define SWAMIGUI_SPLITS(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMIGUI_TYPE_SPLITS, SwamiguiSplits)) #define SWAMIGUI_SPLITS_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMIGUI_TYPE_SPLITS, \ SwamiguiSplitsClass)) #define SWAMIGUI_IS_SPLITS(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMIGUI_TYPE_SPLITS)) #define SWAMIGUI_IS_SPLITS_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMIGUI_TYPE_SPLITS)) /* number of white keys in MIDI 128 note range */ #define SWAMIGUI_SPLITS_WHITE_KEY_COUNT 75 /* splits mode */ typedef enum { SWAMIGUI_SPLITS_NOTE, SWAMIGUI_SPLITS_VELOCITY } SwamiguiSplitsMode; typedef enum { SWAMIGUI_SPLITS_NORMAL, /* no particular status */ SWAMIGUI_SPLITS_INIT, /* check selection and initialize splits */ SWAMIGUI_SPLITS_MODE, /* note/velocity mode change */ SWAMIGUI_SPLITS_UPDATE, /* selection changed */ SWAMIGUI_SPLITS_CHANGED /* splits-item changed */ } SwamiguiSplitsStatus; /** * SwamiguiSplitsMoveFlags: * @SWAMIGUI_SPLITS_MOVE_RANGES: Move note ranges * @SWAMIGUI_SPLITS_MOVE_PARAM1: Move parameter 1 (default is root notes) */ typedef enum { SWAMIGUI_SPLITS_MOVE_RANGES = 1 << 0, SWAMIGUI_SPLITS_MOVE_PARAM1 = 1 << 1 } SwamiguiSplitsMoveFlags; /** * SwamiguiSplitsHandler: * @splits: Splits object * * This function type is used to handle specific patch item types with note * or velocity split parameters. The @splits object * status field indicates the current operation * which is one of: * * %SWAMIGUI_SPLITS_INIT - Check selection and install splits and note * pointers if the selection can be handled. Return %TRUE if selection * was handled, which will activate this handler, %FALSE otherwise. * * %SWAMIGUI_SPLITS_MODE - Split mode change (from note to velocity mode for * example). Re-configure splits and note pointers. Return %TRUE if mode * change was handled, %FALSE otherwise which will de-activate this handler. * * %SWAMIGUI_SPLITS_UPDATE - Item selection has changed, update splits and * note pointers. Return %TRUE if selection change was handled, %FALSE * otherwise which will de-activate this handler. * * Other useful fields of a #SwamiguiSplits object include * mode which defines the current mode * (#SwamiguiSplitsMode) and selection which * defines the current item selection. * * Returns: Should return %TRUE if operation was handled, %FALSE otherwise. */ typedef gboolean (*SwamiguiSplitsHandler)(SwamiguiSplits *splits); /* Swami Splits Object */ struct _SwamiguiSplits { GtkVBox parent_instance; /* derived from GtkVBox */ /*< public >*/ SwamiguiSplitsStatus status; /* current status (for handlers) */ int mode; /* current mode (SWAMIGUI_SPLITS_NOTE or SWAMIGUI_SPLITS_VELOCITY) */ int move_flags; /* current move flags (SwamiguiSplitsMoveFlags) */ IpatchList *selection; /* selected items (parent OR child splits) */ IpatchItem *splits_item; /* active item which contains splits */ SwamiguiSplitsHandler handler; /* active splits handler or NULL */ gpointer handler_data; /* handler defined pointer */ /*< private >*/ GtkWidget *gladewidg; /* The embedded glade widget */ GtkWidget *top_canvas; /* piano/velocity/pointers canvas */ GtkWidget *low_canvas; /* lower spans canvas */ GtkWidget *vertical_scrollbar; /* vertical scroll bar */ GtkWidget *notes_btn; /* Notes toggle button */ GtkWidget *velocity_btn; /* Velocity toggle button */ GtkWidget *move_combo; /* Move combo box */ gboolean width_set; /* TRUE when width set, FALSE to resize to window */ GnomeCanvasGroup *vline_group; /* vertical line group */ SwamiguiPiano *piano; /* piano canvas item */ GnomeCanvasItem *velgrad; /* velocity gradient canvas item */ GnomeCanvasItem *bgrect; /* lower canvas background rectangle */ int flags; /* some flags for optimized updating */ GList *entry_list; /* list of SwamiguiSplitsEntry */ guint entry_count; /* count of entries in entry_list */ int active_drag; /* The active drag mode (see ActiveDrag) */ int active_drag_btn; /* The mouse button which caused the drag */ int anchor; /* last clicked split index or -1 */ double active_xpos; /* X coordinate of active click */ double threshold_value; /* threshold pixel movement value */ GList *active_split; /* split being edited (->data = SwamiguiSplitsEntry) */ int move_note_ofs; /* middle click move note click offset */ int height; /* total height of splits lower canvas */ int width; /* Width of splits canvas */ int span_height; /* height of span handles */ int span_spacing; /* vertical spacing between splits */ int vert_lines_width; /* width of background vertical lines */ int move_threshold; /* movement threshold */ guint bg_color; /* background color */ guint span_color; /* span color */ guint span_sel_color; /* selected span color */ guint span_outline_color; /* span outline color */ guint span_sel_outline_color; /* selected span outline color */ guint line_color; /* line color */ guint line_sel_color; /* selected line color */ guint root_note_color; /* root note indicator color */ }; struct _SwamiguiSplitsClass { GtkVBoxClass parent_class; }; GType swamigui_splits_get_type (void); GtkWidget *swamigui_splits_new (void); void swamigui_splits_set_mode (SwamiguiSplits *splits, SwamiguiSplitsMode mode); void swamigui_splits_set_width (SwamiguiSplits *splits, int width); void swamigui_splits_set_selection (SwamiguiSplits *splits, IpatchList *items); IpatchList *swamigui_splits_get_selection (SwamiguiSplits *splits); void swamigui_splits_select_items (SwamiguiSplits *splits, GList *items); void swamigui_splits_select_all (SwamiguiSplits *splits); void swamigui_splits_unselect_all (SwamiguiSplits *splits); void swamigui_splits_item_changed (SwamiguiSplits *splits); void swamigui_splits_register_handler (SwamiguiSplitsHandler handler); void swamigui_splits_unregister_handler (SwamiguiSplitsHandler handler); #define swamigui_splits_add(splits, item) \ swamigui_splits_insert (splits, item, -1) SwamiguiSplitsEntry *swamigui_splits_insert (SwamiguiSplits *splits, GObject *item, int index); SwamiguiSplitsEntry *swamigui_splits_lookup_entry (SwamiguiSplits *splits, GObject *item); void swamigui_splits_remove (SwamiguiSplits *splits, GObject *item); void swamigui_splits_remove_all (SwamiguiSplits *splits); void swamigui_splits_set_span_range (SwamiguiSplits *splits, GObject *item, int low, int high); void swamigui_splits_set_root_note (SwamiguiSplits *splits, GObject *item, int val); SwamiControl *swamigui_splits_entry_get_span_control (SwamiguiSplitsEntry *entry); SwamiControl *swamigui_splits_entry_get_root_note_control (SwamiguiSplitsEntry *entry); int swamigui_splits_entry_get_index (SwamiguiSplitsEntry *entry); #endif swami/src/swamigui/SwamiguiMultiSave.c0000644000175000017500000003325011704446464020272 0ustar alessioalessio/* * SwamiguiMultiSave.h - Multiple file save dialog * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include #include #include "SwamiguiMultiSave.h" #include "i18n.h" enum { SAVE_COLUMN, /* save check box */ CHANGED_COLUMN, /* changed text */ TITLE_COLUMN, /* title of item */ PATH_COLUMN, /* file path */ ITEM_COLUMN, /* associated IpatchItem */ N_COLUMNS }; static void swamigui_multi_save_finalize (GObject *object); static void browse_clicked (GtkButton *button, gpointer user_data); static void browse_file_chooser_response (GtkDialog *dialog, int response, gpointer user_data); static void save_toggled (GtkCellRendererToggle *cell, char *path_str, gpointer data); static void path_edited (GtkCellRendererText *cell, const char *path_string, const char *new_text, gpointer data); static void multi_save_response (GtkDialog *dialog, int response, gpointer user_data); G_DEFINE_TYPE (SwamiguiMultiSave, swamigui_multi_save, GTK_TYPE_DIALOG); static void swamigui_multi_save_class_init (SwamiguiMultiSaveClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); obj_class->finalize = swamigui_multi_save_finalize; } static void swamigui_multi_save_init (SwamiguiMultiSave *multi) { GtkCellRenderer *renderer; GtkTreeViewColumn *column; GtkWidget *hbox; GtkWidget *frame; GtkWidget *btn; GtkWidget *image; GtkTooltips *tooltips; /* tool tips for dialog widgets */ tooltips = gtk_tooltips_new (); gtk_window_set_default_size (GTK_WINDOW (multi), 400, 300); hbox = gtk_hbox_new (FALSE, 8); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (multi)->vbox), hbox, FALSE, FALSE, 8); /* icon image */ multi->icon = gtk_image_new_from_stock (GTK_STOCK_SAVE, GTK_ICON_SIZE_DIALOG); gtk_box_pack_start (GTK_BOX (hbox), multi->icon, FALSE, FALSE, 0); /* message label */ multi->message = gtk_label_new (""); gtk_label_set_line_wrap (GTK_LABEL (multi->message), TRUE); gtk_box_pack_start (GTK_BOX (hbox), multi->message, FALSE, FALSE, 0); /* browse button */ btn = gtk_button_new_with_label (_("Browse")); image = gtk_image_new_from_stock (GTK_STOCK_OPEN, GTK_ICON_SIZE_BUTTON); gtk_button_set_image (GTK_BUTTON (btn), image); gtk_box_pack_end (GTK_BOX (hbox), btn, FALSE, FALSE, 0); g_signal_connect (btn, "clicked", G_CALLBACK (browse_clicked), multi); gtk_widget_show_all (hbox); /* frame for list */ frame = gtk_frame_new (NULL); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (multi)->vbox), frame, TRUE, TRUE, 0); /* scroll window for list */ multi->scroll_win = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (multi->scroll_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_widget_show (multi->scroll_win); gtk_container_add (GTK_CONTAINER (frame), multi->scroll_win); /* list store */ multi->store = gtk_list_store_new (N_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, IPATCH_TYPE_ITEM); /* tree view */ multi->treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (multi->store)); gtk_container_add (GTK_CONTAINER (multi->scroll_win), multi->treeview); renderer = gtk_cell_renderer_toggle_new (); g_signal_connect (renderer, "toggled", G_CALLBACK (save_toggled), multi->store); column = gtk_tree_view_column_new_with_attributes (_("Save"), renderer, "active", SAVE_COLUMN, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (multi->treeview), column); gtk_tooltips_set_tip (tooltips, GTK_TREE_VIEW_COLUMN (column)->button, _("Select which files to save."), NULL); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes (_("Changed"), renderer, "text", CHANGED_COLUMN, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (multi->treeview), column); gtk_tooltips_set_tip (tooltips, GTK_TREE_VIEW_COLUMN (column)->button, _("File changed since last save?"), NULL); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Title", renderer, "text", TITLE_COLUMN, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (multi->treeview), column); renderer = gtk_cell_renderer_text_new (); g_object_set (renderer, "editable", TRUE, NULL); g_signal_connect (renderer, "edited", G_CALLBACK (path_edited), multi->store); column = gtk_tree_view_column_new_with_attributes ("Path", renderer, "text", PATH_COLUMN, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (multi->treeview), column); gtk_widget_show_all (frame); gtk_dialog_add_buttons (GTK_DIALOG (multi), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL); multi->accept_btn = gtk_dialog_add_button (GTK_DIALOG (multi), GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT); g_signal_connect (multi, "response", G_CALLBACK (multi_save_response), NULL); } static void swamigui_multi_save_finalize (GObject *object) { if (G_OBJECT_CLASS (swamigui_multi_save_parent_class)->finalize) G_OBJECT_CLASS (swamigui_multi_save_parent_class)->finalize (object); } /* browse button clicked callback */ static void browse_clicked (GtkButton *button, gpointer user_data) { SwamiguiMultiSave *multi = SWAMIGUI_MULTI_SAVE (user_data); GtkWidget *filesel; GtkTreeModel *model; GtkTreePath *path; GtkTreeSelection *selection; GtkTreeIter iter; char *fname; selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (multi->treeview)); if (!gtk_tree_selection_get_selected (selection, &model, &iter)) return; gtk_tree_model_get (model, &iter, PATH_COLUMN, &fname, /* ++ alloc */ -1); filesel = gtk_file_chooser_dialog_new (_("Save file as"), GTK_WINDOW (multi), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (filesel), fname); g_signal_connect (filesel, "response", G_CALLBACK (browse_file_chooser_response), multi); path = gtk_tree_model_get_path (model, &iter); /* ++ alloc new path */ g_object_set_data_full (G_OBJECT (filesel), "path", path, /* !! takes over alloc */ (GDestroyNotify)gtk_tree_path_free); gtk_widget_show (filesel); g_free (fname); /* -- free file name string */ } /* dialog response callback for file chooser dialog */ static void browse_file_chooser_response (GtkDialog *dialog, int response, gpointer user_data) { SwamiguiMultiSave *multi = SWAMIGUI_MULTI_SAVE (user_data); GtkTreePath *path; GtkTreeIter iter; char *fname; if (response == GTK_RESPONSE_CANCEL || response == GTK_RESPONSE_NONE) { gtk_object_destroy (GTK_OBJECT (dialog)); return; } /* ++ alloc file name from file chooser */ fname = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); path = g_object_get_data (G_OBJECT (dialog), "path"); gtk_tree_model_get_iter (GTK_TREE_MODEL (multi->store), &iter, path); gtk_list_store_set (multi->store, &iter, PATH_COLUMN, fname, -1); g_free (fname); /* -- free file name string */ gtk_object_destroy (GTK_OBJECT (dialog)); } static void save_toggled (GtkCellRendererToggle *cell, char *path_str, gpointer data) { GtkTreeModel *model = (GtkTreeModel *)data; GtkTreeIter iter; GtkTreePath *path; gboolean save; /* ++ alloc path from string */ path = gtk_tree_path_new_from_string (path_str); /* get toggled iter */ gtk_tree_model_get_iter (model, &iter, path); gtk_tree_model_get (model, &iter, SAVE_COLUMN, &save, -1); save ^= 1; /* toggle the value */ /* set new value */ gtk_list_store_set (GTK_LIST_STORE (model), &iter, SAVE_COLUMN, save, -1); gtk_tree_path_free (path); /* -- free path */ } static void path_edited (GtkCellRendererText *cell, const char *path_string, const char *new_text, gpointer data) { GtkTreeModel *model = (GtkTreeModel *)data; GtkTreePath *path; GtkTreeIter iter; path = gtk_tree_path_new_from_string (path_string); gtk_tree_model_get_iter (model, &iter, path); gtk_list_store_set (GTK_LIST_STORE (model), &iter, PATH_COLUMN, new_text, -1); gtk_tree_path_free (path); } /* called when dialog response received (button clicked by user) */ static void multi_save_response (GtkDialog *dialog, int response, gpointer user_data) { SwamiguiMultiSave *multi = SWAMIGUI_MULTI_SAVE (dialog); GtkTreeModel *model = GTK_TREE_MODEL (multi->store); GtkWidget *msgdialog; GtkTreeIter iter; gboolean save; char *path; IpatchItem *item; GError *err = NULL; int result; gboolean close_ok; if (response == GTK_RESPONSE_CANCEL || response == GTK_RESPONSE_NONE) { gtk_object_destroy (GTK_OBJECT (dialog)); return; } /* get first item in list (destroy dialog if no items) */ if (!gtk_tree_model_get_iter_first (model, &iter)) { gtk_object_destroy (GTK_OBJECT (dialog)); return; } do { gtk_tree_model_get (model, &iter, SAVE_COLUMN, &save, PATH_COLUMN, &path, /* ++ alloc path */ ITEM_COLUMN, &item, /* ++ ref item */ -1); close_ok = TRUE; if (save) { if (!swami_root_patch_save (item, path, &err)) { close_ok = FALSE; /* Don't close file if error on save */ msgdialog = gtk_message_dialog_new (GTK_WINDOW (dialog), 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK_CANCEL, _("Error saving '%s': %s"), path, ipatch_gerror_message (err)); g_clear_error (&err); result = gtk_dialog_run (GTK_DIALOG (msgdialog)); if (result != GTK_RESPONSE_NONE) gtk_widget_destroy (msgdialog); if (result == GTK_RESPONSE_CANCEL) { g_free (path); /* -- free path */ g_object_unref (item); /* -- unref item */ return; } } } /* Close if in close mode */ if (close_ok && (multi->flags & SWAMIGUI_MULTI_SAVE_CLOSE_MODE)) ipatch_item_remove (item); g_free (path); /* -- free path */ g_object_unref (item); /* -- unref item */ } while (gtk_tree_model_iter_next (model, &iter)); gtk_object_destroy (GTK_OBJECT (dialog)); } /** * swamigui_multi_save_new: * @title: Title of dialog * @message: Message text * @flags: A value from #SwamiguiMultiSaveFlags or 0 * * Create a new multi file save dialog. * * Returns: New dialog widget. */ GtkWidget * swamigui_multi_save_new (char *title, char *message, guint flags) { SwamiguiMultiSave *multi; multi = g_object_new (SWAMIGUI_TYPE_MULTI_SAVE, NULL); if (title) gtk_window_set_title (GTK_WINDOW (multi), title); if (message) gtk_label_set_text (GTK_LABEL (multi->message), message); multi->flags = flags; if (flags & SWAMIGUI_MULTI_SAVE_CLOSE_MODE) gtk_button_set_label (GTK_BUTTON (multi->accept_btn), GTK_STOCK_CLOSE); return (GTK_WIDGET (multi)); } /** * swamigui_multi_save_set_selection: * @multi: Multi save widget * @selection: Selection of items to save (only #IpatchBase items or children * thereof are considered, children are followed up to their parent * #IpatchBase, duplicates are taken into account). * * Set the item selection of a multi save dialog. This is the list of items * that the user is prompted to save. */ void swamigui_multi_save_set_selection (SwamiguiMultiSave *multi, IpatchList *selection) { GHashTable *base_hash; IpatchItem *item, *base; GtkTreeIter iter; char *title, *path; gboolean changed, saved, close_mode; GList *p; g_return_if_fail (SWAMIGUI_IS_MULTI_SAVE (multi)); g_return_if_fail (IPATCH_IS_LIST (selection)); close_mode = (multi->flags & SWAMIGUI_MULTI_SAVE_CLOSE_MODE) != 0; gtk_list_store_clear (multi->store); /* hash to throw out duplicate base objects quickly */ base_hash = g_hash_table_new (NULL, NULL); for (p = selection->items; p; p = p->next) { item = (IpatchItem *)(p->data); base = ipatch_item_get_base (item); /* ++ ref base */ if (!base) continue; /* skip if this base object is already added to the list */ if (g_hash_table_lookup (base_hash, base)) { g_object_unref (base); /* -- unref base */ continue; } g_hash_table_insert (base_hash, base, GUINT_TO_POINTER (TRUE)); gtk_list_store_append (multi->store, &iter); /* ++ alloc title and path */ g_object_get (base, "title", &title, /* ++ alloc title */ "file-name", &path, /* ++ alloc path */ "changed", &changed, "saved", &saved, NULL); /* SAVE_COLUMN is set to TRUE if save mode or file has already been saved once */ gtk_list_store_set (multi->store, &iter, SAVE_COLUMN, !close_mode || saved, CHANGED_COLUMN, changed ? _("Yes") : _("No"), TITLE_COLUMN, title, PATH_COLUMN, path, ITEM_COLUMN, base, -1); g_free (title); /* -- free title */ g_free (path); /* -- free path */ g_object_unref (base); /* -- unref base */ } g_hash_table_destroy (base_hash); } swami/src/swamigui/SwamiguiControlMidiKey.c0000644000175000017500000004033511461334205021244 0ustar alessioalessio/* * SwamiguiControlMidiKey.c - MIDI keyboard control * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ /* * NOTE: Setting key arrays is NOT multi-thread safe! */ #include #include #include #include #include #include "SwamiguiControlMidiKey.h" #include "SwamiguiRoot.h" /* Some default values */ #define DEFAULT_LOWER_OCTAVE 2 #define DEFAULT_UPPER_OCTAVE DEFAULT_LOWER_OCTAVE + 1 enum { PROP_0, PROP_LOWER_OCTAVE, PROP_UPPER_OCTAVE, PROP_JOIN_OCTAVES, PROP_LOWER_VELOCITY, PROP_UPPER_VELOCITY, PROP_SAME_VELOCITY, PROP_LOWER_CHANNEL, PROP_UPPER_CHANNEL }; typedef struct { guint key; /* GDK key (see gdk/gdkkeysym.h header) */ gint8 active_note; /* active MIDI note or -1 if not active */ gint8 active_chan; /* MIDI channel of active note (if not -1) */ } MidiKey; static void swamigui_control_midi_key_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void swamigui_control_midi_key_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static gint swamigui_control_midi_key_snooper (GtkWidget *grab_widget, GdkEventKey *event, gpointer func_data); static void swamigui_control_midi_key_finalize (GObject *object); /* FIXME - Dynamically determine key map */ /* default lower keys */ static guint default_lower_keys[] = { GDK_z, GDK_s, GDK_x, GDK_d, GDK_c, GDK_v, GDK_g, GDK_b, GDK_h, GDK_n, GDK_j, GDK_m, GDK_comma, GDK_l, GDK_period, GDK_semicolon, GDK_slash }; /* default upper keys */ static guint default_upper_keys[] = { GDK_q, GDK_2, GDK_w, GDK_3, GDK_e, GDK_r, GDK_5, GDK_t, GDK_6, GDK_y, GDK_7, GDK_u, GDK_i, GDK_9, GDK_o, GDK_0, GDK_p, GDK_bracketleft, GDK_equal, GDK_bracketright }; /* Widget types to ignore key presses from (text entries, etc) */ static char *ignore_widget_type_names[] = { "GtkEntry", "GtkTextView" }; /* Allocated and resolved type array, G_TYPE_INVALID terminated */ static GType *ignore_widget_types; G_DEFINE_TYPE (SwamiguiControlMidiKey, swamigui_control_midi_key, SWAMI_TYPE_CONTROL_MIDI); static void swamigui_control_midi_key_class_init (SwamiguiControlMidiKeyClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); int i; obj_class->set_property = swamigui_control_midi_key_set_property; obj_class->get_property = swamigui_control_midi_key_get_property; obj_class->finalize = swamigui_control_midi_key_finalize; g_object_class_install_property (obj_class, PROP_LOWER_OCTAVE, g_param_spec_int ("lower-octave", "Lower octave", "Lower keyboard MIDI octave", -2, 8, DEFAULT_LOWER_OCTAVE, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_UPPER_OCTAVE, g_param_spec_int ("upper-octave", "Upper octave", "Upper keyboard MIDI octave", -2, 8, DEFAULT_UPPER_OCTAVE, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_JOIN_OCTAVES, g_param_spec_boolean ("join-octaves", "Join octaves", "Join upper and lower octaves", TRUE, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_LOWER_VELOCITY, g_param_spec_int ("lower-velocity", "Lower velocity", "Lower keyboard MIDI velocity", 1, 127, 127, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_UPPER_VELOCITY, g_param_spec_int ("upper-velocity", "Upper velocity", "Upper keyboard MIDI velocity", 1, 127, 127, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_SAME_VELOCITY, g_param_spec_boolean ("same-velocity", "Same velocity", "Same velocity for upper and lower", TRUE, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_LOWER_CHANNEL, g_param_spec_int ("lower-channel", "Lower channel", "Lower keyboard MIDI channel", 0, 15, 0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_UPPER_CHANNEL, g_param_spec_int ("upper-channel", "Upper channel", "Upper keyboard MIDI channel", 0, 15, 0, G_PARAM_READWRITE)); ignore_widget_types = g_new (GType, G_N_ELEMENTS (ignore_widget_type_names) + 1); for (i = 0; i < G_N_ELEMENTS (ignore_widget_type_names); i++) ignore_widget_types[i] = g_type_from_name (ignore_widget_type_names[i]); ignore_widget_types[i] = G_TYPE_INVALID; } static void swamigui_control_midi_key_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { SwamiguiControlMidiKey *keyctrl = SWAMIGUI_CONTROL_MIDI_KEY (object); switch (property_id) { case PROP_LOWER_OCTAVE: g_value_set_int (value, keyctrl->lower_octave); break; case PROP_UPPER_OCTAVE: g_value_set_int (value, keyctrl->upper_octave); break; case PROP_JOIN_OCTAVES: g_value_set_boolean (value, keyctrl->join_octaves); break; case PROP_LOWER_VELOCITY: g_value_set_int (value, keyctrl->lower_velocity); break; case PROP_UPPER_VELOCITY: g_value_set_int (value, keyctrl->upper_velocity); break; case PROP_SAME_VELOCITY: g_value_set_boolean (value, keyctrl->same_velocity); break; case PROP_LOWER_CHANNEL: g_value_set_int (value, keyctrl->lower_channel); break; case PROP_UPPER_CHANNEL: g_value_set_int (value, keyctrl->upper_channel); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_control_midi_key_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { SwamiguiControlMidiKey *keyctrl = SWAMIGUI_CONTROL_MIDI_KEY (object); switch (property_id) { case PROP_LOWER_OCTAVE: keyctrl->lower_octave = g_value_get_int (value); if (keyctrl->join_octaves) { keyctrl->upper_octave = keyctrl->lower_octave < 8 ? keyctrl->lower_octave + 1 : 8; g_object_notify (object, "upper-octave"); } break; case PROP_UPPER_OCTAVE: keyctrl->upper_octave = g_value_get_int (value); if (keyctrl->join_octaves) { keyctrl->lower_octave = keyctrl->upper_octave > -2 ? keyctrl->upper_octave - 1 : -2; g_object_notify (object, "lower-octave"); } break; case PROP_JOIN_OCTAVES: keyctrl->join_octaves = g_value_get_boolean (value); if (keyctrl->join_octaves && keyctrl->lower_octave + 1 != keyctrl->upper_octave) { keyctrl->upper_octave = keyctrl->lower_octave < 8 ? keyctrl->lower_octave + 1 : 8; g_object_notify (object, "upper-octave"); } break; case PROP_LOWER_VELOCITY: keyctrl->lower_velocity = g_value_get_int (value); if (keyctrl->same_velocity) { keyctrl->upper_velocity = keyctrl->lower_velocity; g_object_notify (object, "upper-velocity"); } break; case PROP_UPPER_VELOCITY: keyctrl->upper_velocity = g_value_get_int (value); if (keyctrl->same_velocity) { keyctrl->lower_velocity = keyctrl->upper_velocity; g_object_notify (object, "lower-velocity"); } break; case PROP_SAME_VELOCITY: keyctrl->same_velocity = g_value_get_boolean (value); if (keyctrl->same_velocity && keyctrl->lower_velocity != keyctrl->upper_velocity) { keyctrl->upper_velocity = keyctrl->lower_velocity; g_object_notify (object, "upper-velocity"); } break; case PROP_LOWER_CHANNEL: keyctrl->lower_channel = g_value_get_int (value); break; case PROP_UPPER_CHANNEL: keyctrl->upper_channel = g_value_get_int (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_control_midi_key_init (SwamiguiControlMidiKey *keyctrl) { MidiKey midikey; int i; swami_control_set_flags (SWAMI_CONTROL (keyctrl), SWAMI_CONTROL_SENDS); keyctrl->lower_keys = g_array_new (FALSE, FALSE, sizeof (MidiKey)); keyctrl->upper_keys = g_array_new (FALSE, FALSE, sizeof (MidiKey)); keyctrl->lower_octave = DEFAULT_LOWER_OCTAVE; keyctrl->upper_octave = DEFAULT_UPPER_OCTAVE; keyctrl->join_octaves = TRUE; keyctrl->lower_velocity = 127; keyctrl->upper_velocity = 127; keyctrl->same_velocity = TRUE; keyctrl->lower_channel = 0; keyctrl->upper_channel = 0; /* initialize lower and upper key array */ for (i = 0; i < G_N_ELEMENTS (default_lower_keys); i++) { midikey.key = default_lower_keys[i]; midikey.active_note = -1; g_array_append_val (keyctrl->lower_keys, midikey); } for (i = 0; i < G_N_ELEMENTS (default_upper_keys); i++) { midikey.key = default_upper_keys[i]; midikey.active_note = -1; g_array_append_val (keyctrl->upper_keys, midikey); } /* install our key snooper */ keyctrl->snooper_id = gtk_key_snooper_install (swamigui_control_midi_key_snooper, keyctrl); } static gint swamigui_control_midi_key_snooper (GtkWidget *grab_widget, GdkEventKey *event, gpointer func_data) { SwamiguiControlMidiKey *keyctrl = SWAMIGUI_CONTROL_MIDI_KEY (func_data); GtkWidget *toplevel, *focus; GType *ignore; guint key; if (event->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK)) return (FALSE); key = gdk_keyval_to_lower (event->keyval); if (event->type == GDK_KEY_PRESS) { toplevel = gtk_widget_get_toplevel (grab_widget); /* Only listen to key presses on main window, not dialogs (allow releases though) */ if (toplevel != swamigui_root->main_window) return (FALSE); /* Check if focus widget type should be ignored (text entries, etc) */ focus = gtk_window_get_focus (GTK_WINDOW (toplevel)); if (focus) { for (ignore = ignore_widget_types; *ignore != G_TYPE_INVALID; ignore++) { if (g_type_is_a (G_OBJECT_TYPE (focus), *ignore)) return (FALSE); } } swamigui_control_midi_key_press (keyctrl, key); } else if (event->type == GDK_KEY_RELEASE) swamigui_control_midi_key_release (keyctrl, key); return (FALSE); /* don't stop event propagation */ } static void swamigui_control_midi_key_finalize (GObject *object) { SwamiguiControlMidiKey *keyctrl = SWAMIGUI_CONTROL_MIDI_KEY (object); gtk_key_snooper_remove (keyctrl->snooper_id); g_array_free (keyctrl->lower_keys, TRUE); g_array_free (keyctrl->upper_keys, TRUE); if (G_OBJECT_CLASS (swamigui_control_midi_key_parent_class)->finalize) G_OBJECT_CLASS (swamigui_control_midi_key_parent_class)->finalize (object); } /** * swamigui_control_midi_key_new: * * Create a new MIDI keyboard control. * * Returns: New MIDI keyboard control with a refcount of 1 which the * caller owns. */ SwamiguiControlMidiKey * swamigui_control_midi_key_new (void) { return (SWAMIGUI_CONTROL_MIDI_KEY (g_object_new (SWAMIGUI_TYPE_CONTROL_MIDI_KEY, NULL))); } /** * swamigui_control_midi_key_press: * @keyctrl: MIDI keyboard control * @key: GDK keyboard key (see gdk/gdkkeysyms.h header) * * Send a key press to a MIDI keyboard control. */ void swamigui_control_midi_key_press (SwamiguiControlMidiKey *keyctrl, guint key) { MidiKey *midikey, *found = NULL; int newnote, newvel, newchan; int i, count; g_return_if_fail (SWAMIGUI_IS_CONTROL_MIDI_KEY (keyctrl)); /* look for key in lower octave */ count = keyctrl->lower_keys->len; for (i = 0; i < count; i++) { midikey = &g_array_index (keyctrl->lower_keys, MidiKey, i); if (midikey->key == key) /* found key? */ { newnote = (keyctrl->lower_octave + 2) * 12 + i; /* calculate MIDI note */ newvel = keyctrl->lower_velocity; newchan = keyctrl->lower_channel; found = midikey; break; } } if (!found) /* not found in lower octave? */ { /* look for key in upper octave */ count = keyctrl->upper_keys->len; for (i = 0; i < count; i++) { midikey = &g_array_index (keyctrl->upper_keys, MidiKey, i); if (midikey->key == key) /* found key? */ { newnote = (keyctrl->upper_octave + 2) * 12 + i; /* calc MIDI note */ newvel = keyctrl->upper_velocity; newchan = keyctrl->upper_channel; found = midikey; break; } } } /* return if key not found or already active and the same as new note */ if (!found || found->active_note == newnote) return; if (found->active_note != -1) /* previous active note? */ { /* send note off event */ swami_control_midi_transmit (SWAMI_CONTROL_MIDI (keyctrl), SWAMI_MIDI_NOTE_OFF, found->active_chan, found->active_note, 0x7F); found->active_note = -1; } if (newnote <= 127) { /* send note on event */ swami_control_midi_transmit (SWAMI_CONTROL_MIDI (keyctrl), SWAMI_MIDI_NOTE_ON, newchan, newnote, newvel); found->active_note = newnote; found->active_chan = newchan; } } /** * swamigui_control_midi_key_release: * @keyctrl: MIDI keyboard control * @key: GDK keyboard key (see gdk/gdkkeysyms.h header) * * Send a key release to a MIDI keyboard control. */ void swamigui_control_midi_key_release (SwamiguiControlMidiKey *keyctrl, guint key) { MidiKey *midikey, *found = NULL; int i, count; g_return_if_fail (SWAMIGUI_IS_CONTROL_MIDI_KEY (keyctrl)); /* look for key in lower octave */ count = keyctrl->lower_keys->len; for (i = 0; i < count; i++) { midikey = &g_array_index (keyctrl->lower_keys, MidiKey, i); if (midikey->key == key) /* found key? */ { found = midikey; break; } } if (!found) /* not found in lower octave? */ { /* look for key in upper octave */ count = keyctrl->upper_keys->len; for (i = 0; i < count; i++) { midikey = &g_array_index (keyctrl->upper_keys, MidiKey, i); if (midikey->key == key) /* found key? */ { found = midikey; break; } } } if (!found || found->active_note == -1) return; /* send note off event */ swami_control_midi_transmit (SWAMI_CONTROL_MIDI (keyctrl), SWAMI_MIDI_NOTE_OFF, found->active_chan, found->active_note, 0x7F); found->active_note = -1; } /** * swamigui_control_midi_key_set_lower: * @keyctrl: MIDI keyboard control * @keys: Array of GDK key values * @count: Number of values in @keys * * Set the lower keyboard key array. * * Note: Not multi-thread safe */ void swamigui_control_midi_key_set_lower (SwamiguiControlMidiKey *keyctrl, const guint *keys, guint count) { MidiKey midikey; int i; g_return_if_fail (SWAMIGUI_IS_CONTROL_MIDI_KEY (keyctrl)); g_return_if_fail (keys != NULL || count == 0); g_array_set_size (keyctrl->lower_keys, 0); for (i = 0; i < count; i++) { midikey.key = keys[i]; midikey.active_note = -1; g_array_append_val (keyctrl->lower_keys, midikey); } } /** * swamigui_control_midi_key_set_upper: * @keyctrl: MIDI keyboard control * @keys: Array of GDK key values * @count: Number of values in @keys * * Set the upper keyboard key array. * * Note: Not multi-thread safe */ void swamigui_control_midi_key_set_upper (SwamiguiControlMidiKey *keyctrl, const guint *keys, guint count) { MidiKey midikey; int i; g_return_if_fail (SWAMIGUI_IS_CONTROL_MIDI_KEY (keyctrl)); g_return_if_fail (keys != NULL || count == 0); g_array_set_size (keyctrl->upper_keys, 0); for (i = 0; i < count; i++) { midikey.key = keys[i]; midikey.active_note = -1; g_array_append_val (keyctrl->upper_keys, midikey); } } swami/src/swamigui/icons.c0000644000175000017500000001354411474034033015757 0ustar alessioalessio/* * icons.c - Swami stock icons * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include "config.h" #include "icons.h" /* icon mappings for IpatchItem categories */ struct { int category; char *icon; } category_icons[] = { { IPATCH_CATEGORY_NONE, GTK_STOCK_DIRECTORY }, { IPATCH_CATEGORY_BASE, GTK_STOCK_DIRECTORY }, { IPATCH_CATEGORY_PROGRAM, SWAMIGUI_STOCK_PRESET }, { IPATCH_CATEGORY_INSTRUMENT, SWAMIGUI_STOCK_INST }, { IPATCH_CATEGORY_INSTRUMENT_REF, SWAMIGUI_STOCK_INST }, { IPATCH_CATEGORY_SAMPLE, SWAMIGUI_STOCK_SAMPLE }, { IPATCH_CATEGORY_SAMPLE_REF, SWAMIGUI_STOCK_SAMPLE } }; /* stores the registered "CustomLarge1" custom icon size enum */ int swamigui_icon_size_custom_large1; void _swamigui_stock_icons_init (void) { GtkIconFactory *factory; GtkIconTheme *theme = gtk_icon_theme_get_default (); int prefix_len = strlen ("swamigui_"); char *path; int i; /* !! keep synchronized with icons.h !! */ static const char *items[] = { SWAMIGUI_STOCK_CONCAVE_NEG_BI, SWAMIGUI_STOCK_CONCAVE_NEG_UNI, SWAMIGUI_STOCK_CONCAVE_POS_BI, SWAMIGUI_STOCK_CONCAVE_POS_UNI, SWAMIGUI_STOCK_CONVEX_NEG_BI, SWAMIGUI_STOCK_CONVEX_NEG_UNI, SWAMIGUI_STOCK_CONVEX_POS_BI, SWAMIGUI_STOCK_CONVEX_POS_UNI, SWAMIGUI_STOCK_DLS, SWAMIGUI_STOCK_EFFECT_CONTROL, SWAMIGUI_STOCK_EFFECT_DEFAULT, SWAMIGUI_STOCK_EFFECT_GRAPH, SWAMIGUI_STOCK_EFFECT_SET, SWAMIGUI_STOCK_EFFECT_VIEW, SWAMIGUI_STOCK_GIG, SWAMIGUI_STOCK_GLOBAL_ZONE, SWAMIGUI_STOCK_INST, SWAMIGUI_STOCK_LINEAR_NEG_BI, SWAMIGUI_STOCK_LINEAR_NEG_UNI, SWAMIGUI_STOCK_LINEAR_POS_BI, SWAMIGUI_STOCK_LINEAR_POS_UNI, SWAMIGUI_STOCK_LOOP_NONE, SWAMIGUI_STOCK_LOOP_STANDARD, SWAMIGUI_STOCK_LOOP_RELEASE, SWAMIGUI_STOCK_MODENV, SWAMIGUI_STOCK_MODENV_ATTACK, SWAMIGUI_STOCK_MODENV_DECAY, SWAMIGUI_STOCK_MODENV_DELAY, SWAMIGUI_STOCK_MODENV_HOLD, SWAMIGUI_STOCK_MODENV_RELEASE, SWAMIGUI_STOCK_MODENV_SUSTAIN, SWAMIGUI_STOCK_MODULATOR_EDITOR, SWAMIGUI_STOCK_MODULATOR_JUNCT, SWAMIGUI_STOCK_MUTE, SWAMIGUI_STOCK_PIANO, SWAMIGUI_STOCK_PRESET, SWAMIGUI_STOCK_PYTHON, SWAMIGUI_STOCK_SAMPLE, SWAMIGUI_STOCK_SAMPLE_ROM, SWAMIGUI_STOCK_SAMPLE_VIEWER, SWAMIGUI_STOCK_SOUNDFONT, SWAMIGUI_STOCK_SPLITS, SWAMIGUI_STOCK_SWITCH_NEG_BI, SWAMIGUI_STOCK_SWITCH_NEG_UNI, SWAMIGUI_STOCK_SWITCH_POS_BI, SWAMIGUI_STOCK_SWITCH_POS_UNI, SWAMIGUI_STOCK_TREE, SWAMIGUI_STOCK_TUNING, SWAMIGUI_STOCK_VELOCITY, SWAMIGUI_STOCK_VOLENV, SWAMIGUI_STOCK_VOLENV_ATTACK, SWAMIGUI_STOCK_VOLENV_DECAY, SWAMIGUI_STOCK_VOLENV_DELAY, SWAMIGUI_STOCK_VOLENV_HOLD, SWAMIGUI_STOCK_VOLENV_RELEASE, SWAMIGUI_STOCK_VOLENV_SUSTAIN }; /* ++ alloc path */ #ifdef MINGW32 char *appdir; gboolean free_path = FALSE; appdir = g_win32_get_package_installation_directory_of_module (NULL); /* ++ alloc */ if (appdir) { path = g_build_filename (appdir, "images", NULL); /* ++ alloc */ free_path = TRUE; g_free (appdir); /* -- free appdir */ } else path = IMAGES_DIR; #else # ifdef SOURCE_BUILD /* use source dir for loading icons? */ path = SOURCE_DIR "/src/swamigui/images"; # else path = IMAGES_DIR; # endif #endif gtk_icon_theme_append_search_path (theme, path); factory = gtk_icon_factory_new (); gtk_icon_factory_add_default (factory); for (i = 0; i < (int) G_N_ELEMENTS (items); i++) { GtkIconSet *icon_set; GdkPixbuf *pixbuf; char *fn, *s; s = g_strconcat (&items[i][prefix_len], ".png", NULL); fn = g_build_filename (path, s, NULL); g_free (s); pixbuf = gdk_pixbuf_new_from_file (fn, NULL); g_free (fn); if (!pixbuf) continue; if (strcmp (items[i], SWAMIGUI_STOCK_MODULATOR_JUNCT) == 0) { int width, height; width = gdk_pixbuf_get_width (pixbuf); height = gdk_pixbuf_get_height (pixbuf); swamigui_icon_size_custom_large1 = gtk_icon_size_register ("CustomLarge1", width, height); } icon_set = gtk_icon_set_new_from_pixbuf (pixbuf); gtk_icon_factory_add (factory, items[i], icon_set); gtk_icon_set_unref (icon_set); g_object_unref (G_OBJECT (pixbuf)); } g_object_unref (G_OBJECT (factory)); #ifdef MINGW32 if (free_path) g_free (path); /* -- free allocated path */ #endif /* set the default application icon name */ gtk_window_set_default_icon_name ("swami"); } /** * swamigui_icon_get_category_icon: * @category: IpatchItem type property "category" (IPATCH_CATEGORY_*) * * Get the icon used for the specified IpatchItem type category. * * Returns: Stock icon ID or %NULL if no icon for @category or invalid category. */ char * swamigui_icon_get_category_icon (int category) { int i; for (i = 0; i < G_N_ELEMENTS (category_icons); i++) { if (category_icons[i].category == category) return (category_icons[i].icon); } return NULL; } swami/src/swamigui/SwamiguiPaste.h0000644000175000017500000001023411461334205017424 0ustar alessioalessio/* * SwamiguiPaste.h - Header file for Swami item paste object * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_PASTE_H__ #define __SWAMIGUI_PASTE_H__ /* FIXME - Put me somewhere useful * * Paste methods should iterate over the list of items and determine * if it can handle the source to destination paste operation and * update the status of the @paste context to #SWAMIGUI_PASTE_UNHANDLED * if it cannot. If handled, then the paste operation should be * carried out while checking for conflicts. If a conflict is * encountered the @paste context should be set to * #SWAMIGUI_PASTE_CONFLICT and the function should return. * swamigui_paste_save_state() can be used to save state data of each * function in the call chain to allow the operation to resume after a * decision is made. */ typedef struct _SwamiguiPaste SwamiguiPaste; typedef struct _SwamiguiPasteClass SwamiguiPasteClass; #define SWAMIGUI_TYPE_PASTE (swamigui_paste_get_type ()) #define SWAMIGUI_PASTE(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMIGUI_TYPE_PASTE, SwamiguiPaste)) #define SWAMIGUI_PASTE_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMIGUI_TYPE_PASTE, SwamiguiPasteClass)) #define SWAMIGUI_IS_PASTE(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMIGUI_TYPE_PASTE)) #define SWAMIGUI_IS_PASTE_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMIGUI_TYPE_PASTE)) /* Status of a patch item paste operation */ typedef enum { SWAMIGUI_PASTE_NORMAL, /* system normal */ SWAMIGUI_PASTE_ERROR, /* an error has occured */ SWAMIGUI_PASTE_UNHANDLED, /* unhandled paste types */ SWAMIGUI_PASTE_CONFLICT, /* a conflict occured, choice required */ SWAMIGUI_PASTE_CANCEL /* cancel paste operation */ } SwamiguiPasteStatus; typedef enum { SWAMIGUI_PASTE_NO_DECISION = 0, SWAMIGUI_PASTE_SKIP = 1 << 0, /* skip item (keep old conflict item) */ SWAMIGUI_PASTE_CHANGED = 1 << 1, /* item change (check for conflicts, etc) */ SWAMIGUI_PASTE_REPLACE = 1 << 2 /* replace conflict item */ } SwamiguiPasteDecision; /* Swami paste object */ struct _SwamiguiPaste { GObject parent_instance; /* derived from GObject */ SwamiguiPasteStatus status; /* current status of paste */ SwamiguiPasteDecision decision; /* decision value (set for conflicts) */ int decision_mask; /* a mask of allowable decisions for a conflict */ IpatchItem *dstitem; /* paste destination item */ GList *srcitems; /* source items (IpatchItem types) */ GList *curitem; /* current source item being processed */ GHashTable *item_hash; /* hash of item relations (choices) */ GList *states; /* state stack for methods (so we can resume operations) */ IpatchItem *conflict_src; /* source conflict item */ IpatchItem *conflict_dst; /* destination conflict item */ }; /* Swami paste class */ struct _SwamiguiPasteClass { GObjectClass parent_class; }; GType swamigui_paste_get_type (void); SwamiguiPaste *swamigui_paste_new (void); gboolean swamigui_paste_process (SwamiguiPaste *paste); void swamigui_paste_set_items (SwamiguiPaste *paste, IpatchItem *dstitem, GList *srcitems); void swamigui_paste_get_conflict_items (SwamiguiPaste *paste, IpatchItem **src, IpatchItem **dest); void swamigui_paste_set_conflict_items (SwamiguiPaste *paste, IpatchItem *src, IpatchItem *dest); void swamigui_paste_push_state (SwamiguiPaste *paste, gpointer state); gpointer swamigui_paste_pop_state (SwamiguiPaste *paste); #endif swami/src/swamigui/SwamiguiProp.h0000644000175000017500000000512511461334205017273 0ustar alessioalessio/* * SwamiguiProp.h - GObject property GUI control object header * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_PROP_H__ #define __SWAMIGUI_PROP_H__ #include #include typedef struct _SwamiguiProp SwamiguiProp; typedef struct _SwamiguiPropClass SwamiguiPropClass; #define SWAMIGUI_TYPE_PROP (swamigui_prop_get_type ()) #define SWAMIGUI_PROP(obj) \ (GTK_CHECK_CAST ((obj), SWAMIGUI_TYPE_PROP, SwamiguiProp)) #define SWAMIGUI_PROP_CLASS(klass) \ (GTK_CHECK_CLASS_CAST ((klass), SWAMIGUI_TYPE_PROP, SwamiguiPropClass)) #define SWAMIGUI_IS_PROP(obj) \ (GTK_CHECK_TYPE ((obj), SWAMIGUI_TYPE_PROP)) #define SWAMIGUI_IS_PROP_CLASS(klass) \ (GTK_CHECK_CLASS_TYPE ((klass), SWAMIGUI_TYPE_PROP)) /* Swami Properties Object (all fields private) */ struct _SwamiguiProp { GtkScrolledWindow parent; GtkWidget *viewport; /* viewport for child interface widget */ IpatchList *selection; /* Selection list or NULL (one item only) */ }; /* Swami Properties Object class (all fields private) */ struct _SwamiguiPropClass { GtkScrolledWindowClass parent_class; }; /** * SwamiguiPropHandler: * @widg: A previously created widget (if changing @obj) or %NULL if a new * widget should be created. * @obj: Object to create a GUI property control interface for. * * Function prototype to create a GUI property control interface. * * Returns: The toplevel widget of the interface which controls @obj. */ typedef GtkWidget * (*SwamiguiPropHandler)(GtkWidget *widg, GObject *obj); void swamigui_register_prop_glade_widg (GType objtype, const char *name); void swamigui_register_prop_handler (GType objtype, SwamiguiPropHandler handler); GType swamigui_prop_get_type (void); GtkWidget *swamigui_prop_new (void); void swamigui_prop_set_selection (SwamiguiProp *prop, IpatchList *selection); #endif swami/src/swamigui/SwamiguiItemMenu.c0000644000175000017500000006076411461334205020103 0ustar alessioalessio/* * SwamiguiTreeMenu.c - Swami Tree right-click menu object * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include "SwamiguiItemMenu.h" #include "SwamiguiRoot.h" #include "i18n.h" enum { PROP_0, PROP_SELECTION, /* the item selection list */ PROP_RIGHT_CLICK, /* the right click item */ PROP_CREATOR /* the widget creating the menu */ }; typedef struct { char *action_id; /* store the hash key, for convenience */ SwamiguiItemMenuInfo *info; SwamiguiItemMenuHandler handler; } ActionBag; typedef struct { GType type; /* type to match */ gboolean derived; /* TRUE if derived types should match also */ } TypeMatch; static void swamigui_item_menu_class_init (SwamiguiItemMenuClass *klass); static void type_match_list_free (gpointer data); static void swamigui_item_menu_set_property (GObject *obj, guint property_id, const GValue *value, GParamSpec *pspec); static void swamigui_item_menu_get_property (GObject *obj, guint property_id, GValue *value, GParamSpec *pspec); static void swamigui_item_menu_init (SwamiguiItemMenu *menu); static void swamigui_item_menu_finalize (GObject *object); static ActionBag *lookup_item_action_bag (const char *action_id); static void container_foreach_remove (GtkWidget *widg, gpointer data); static void make_action_list_GHFunc (gpointer key, gpointer value, gpointer user_data); static void swamigui_item_menu_callback_activate (GtkMenuItem *mitem, gpointer user_data); static void swamigui_item_menu_accel_activate_callback (gpointer user_data); /* keyboard accelerator group for item menu actions */ GtkAccelGroup *swamigui_item_menu_accel_group; /* hash of action ID string -> ActionBag */ G_LOCK_DEFINE_STATIC (menu_action_hash); static GHashTable *menu_action_hash = NULL; /* hash of action ID string -> GSList of TypeMatch (for including types) */ G_LOCK_DEFINE_STATIC (item_type_include_hash); static GHashTable *item_type_include_hash = NULL; /* hash of action ID string -> GSList of TypeMatch (for excluding types) */ G_LOCK_DEFINE_STATIC (item_type_exclude_hash); static GHashTable *item_type_exclude_hash = NULL; static GObjectClass *parent_class = NULL; void _swamigui_item_menu_init (void) { /* create key accelerator group */ swamigui_item_menu_accel_group = gtk_accel_group_new (); /* create menu action hash */ menu_action_hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)g_free); /* create menu item type inclusion hash */ item_type_include_hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, type_match_list_free); /* create menu item type exclusion hash */ item_type_exclude_hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, type_match_list_free); } GType swamigui_item_menu_get_type (void) { static GType obj_type = 0; if (!obj_type) { static const GTypeInfo obj_info = { sizeof (SwamiguiItemMenuClass), NULL, NULL, (GClassInitFunc) swamigui_item_menu_class_init, NULL, NULL, sizeof (SwamiguiItemMenu), 0, (GInstanceInitFunc) swamigui_item_menu_init, }; obj_type = g_type_register_static (GTK_TYPE_MENU, "SwamiguiItemMenu", &obj_info, 0); } return (obj_type); } static void swamigui_item_menu_class_init (SwamiguiItemMenuClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); parent_class = g_type_class_peek_parent (klass); obj_class->finalize = swamigui_item_menu_finalize; obj_class->get_property = swamigui_item_menu_get_property; obj_class->set_property = swamigui_item_menu_set_property; g_object_class_install_property (obj_class, PROP_SELECTION, g_param_spec_object ("selection", "selection", "selection", IPATCH_TYPE_LIST, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_RIGHT_CLICK, g_param_spec_object ("right-click", "right-click", "right-click", G_TYPE_OBJECT, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_CREATOR, g_param_spec_object ("creator", "creator", "creator", G_TYPE_OBJECT, G_PARAM_READWRITE)); } /* free a GSList of TypeMatch structures */ static void type_match_list_free (gpointer data) { GSList *p = (GSList *)data; for (; p; p = g_slist_delete_link (p, p)) g_free (p->data); } static void swamigui_item_menu_set_property (GObject *obj, guint property_id, const GValue *value, GParamSpec *pspec) { SwamiguiItemMenu *menu = SWAMIGUI_ITEM_MENU (obj); GObject *object; switch (property_id) { case PROP_SELECTION: if (menu->selection) g_object_unref (menu->selection); object = g_value_get_object (value); g_return_if_fail (!object || IPATCH_IS_LIST (object)); menu->selection = g_object_ref (object); break; case PROP_RIGHT_CLICK: if (menu->rclick) g_object_unref (menu->rclick); menu->rclick = g_value_dup_object (value); break; case PROP_CREATOR: if (menu->creator) g_object_unref (menu->creator); menu->creator = g_value_dup_object (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec); break; } } static void swamigui_item_menu_get_property (GObject *obj, guint property_id, GValue *value, GParamSpec *pspec) { SwamiguiItemMenu *menu = SWAMIGUI_ITEM_MENU (obj); switch (property_id) { case PROP_SELECTION: g_value_set_object (value, (GObject *)(menu->selection)); break; case PROP_RIGHT_CLICK: g_value_set_object (value, (GObject *)(menu->rclick)); break; case PROP_CREATOR: g_value_set_object (value, (GObject *)(menu->creator)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec); break; } } static void swamigui_item_menu_init (SwamiguiItemMenu *menu) { gtk_menu_set_accel_group (GTK_MENU (menu), swamigui_item_menu_accel_group); } static void swamigui_item_menu_finalize (GObject *object) { SwamiguiItemMenu *menu = SWAMIGUI_ITEM_MENU (object); if (menu->selection) g_object_unref (menu->selection); if (menu->rclick) g_object_unref (menu->rclick); if (menu->creator) g_object_unref (menu->creator); menu->selection = NULL; menu->rclick = NULL; menu->creator = NULL; if (parent_class->finalize) parent_class->finalize (object); } /** * swamigui_item_menu_new: * * Create a new Swami tree store. * * Returns: New Swami tree store object with a ref count of 1. */ SwamiguiItemMenu * swamigui_item_menu_new (void) { return (SWAMIGUI_ITEM_MENU (g_object_new (SWAMIGUI_TYPE_ITEM_MENU, NULL))); } /** * swamigui_item_menu_add: * @menu: GUI menu to add item to * @info: Info describing new menu item to add * @action_id: The action ID string that is adding the menu item * * Add a menu item to a GUI menu. * * Returns: The new GtkMenuItem that was added to the menu. */ GtkWidget * swamigui_item_menu_add (SwamiguiItemMenu *menu, const SwamiguiItemMenuInfo *info, const char *action_id) { GtkWidget *mitem; guint key, mods; char *accel_path; GList *list, *p; int order; int index; g_return_val_if_fail (SWAMIGUI_IS_ITEM_MENU (menu), NULL); g_return_val_if_fail (info != NULL, NULL); if (info->icon) { GtkWidget *image; mitem = gtk_image_menu_item_new_with_mnemonic (_(info->label)); image = gtk_image_new_from_stock (info->icon, GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mitem), image); } else mitem = gtk_menu_item_new_with_mnemonic (_(info->label)); gtk_widget_show (mitem); g_object_set_data (G_OBJECT (mitem), "_order", GUINT_TO_POINTER (info->order)); g_object_set_data (G_OBJECT (mitem), "_func", (gpointer)(info->func)); /* connect menu item to callback function */ if (info->func) g_signal_connect (mitem, "activate", G_CALLBACK (swamigui_item_menu_callback_activate), info->data); /* parse key accelerator and add it to menu item */ if (info->accel) { gtk_accelerator_parse (info->accel, &key, &mods); accel_path = g_strdup_printf ("/%s", action_id); gtk_accel_map_add_entry (accel_path, key, mods); gtk_menu_item_set_accel_path (GTK_MENU_ITEM (mitem), accel_path); g_free (accel_path); } list = gtk_container_get_children (GTK_CONTAINER (menu)); /* find insert position from order info parameter */ for (p = list, index = 0; p; p = p->next, index++) { order = GPOINTER_TO_INT (g_object_get_data (p->data, "_order")); if (info->order < order) break; } g_list_free (list); gtk_menu_shell_insert (GTK_MENU_SHELL (menu), mitem, index); return (mitem); } /** * swamigui_item_menu_add_registered_info: * @menu: GUI menu to add item to * @action_id: The action ID string that is adding the menu item * * Add a menu item to a GUI menu using the default info added when the * @action_id was registered. * * Returns: The new GtkMenuItem that was added to the menu. */ GtkWidget * swamigui_item_menu_add_registered_info (SwamiguiItemMenu *menu, const char *action_id) { ActionBag *found_action; g_return_val_if_fail (SWAMIGUI_IS_ITEM_MENU (menu), NULL); found_action = lookup_item_action_bag (action_id); g_return_val_if_fail (found_action != NULL, NULL); g_return_val_if_fail (found_action->info != NULL, NULL); return (swamigui_item_menu_add (menu, found_action->info, action_id)); } /* lookup a registered action by its ID */ static ActionBag * lookup_item_action_bag (const char *action_id) { ActionBag *bag; G_LOCK (menu_action_hash); bag = g_hash_table_lookup (menu_action_hash, (gpointer)action_id); G_UNLOCK (menu_action_hash); return (bag); } /** * swamigui_item_menu_generate: * @menu: GUI menu * * Generate a GUI menu by executing all registered item action handlers which * add items to the menu. Any existing items are removed before generating the * new menu. */ void swamigui_item_menu_generate (SwamiguiItemMenu *menu) { GSList *actions = NULL, *p; g_return_if_fail (SWAMIGUI_IS_ITEM_MENU (menu)); /* remove any existing items from the menu */ gtk_container_foreach (GTK_CONTAINER (menu), container_foreach_remove, menu); /* make a list so we can unlock the hash (prevent recursive locks) */ G_LOCK (menu_action_hash); g_hash_table_foreach (menu_action_hash, make_action_list_GHFunc, &actions); G_UNLOCK (menu_action_hash); for (p = actions; p; p = p->next) { ActionBag *bag = (ActionBag *)(p->data); /* if handler was supplied then execute it, otherwise create item using the item info set when action was registered (one or the other must be set). */ if (bag->handler) bag->handler (menu, bag->action_id); else swamigui_item_menu_add (menu, bag->info, bag->action_id); } g_slist_free (actions); } /* turn hash into a list */ static void make_action_list_GHFunc (gpointer key, gpointer value, gpointer user_data) { GSList **listp = (GSList **)user_data; *listp = g_slist_prepend (*listp, value); } static void container_foreach_remove (GtkWidget *widg, gpointer data) { gtk_container_remove (GTK_CONTAINER (data), widg); } /* callback when a menu item is activated */ static void swamigui_item_menu_callback_activate (GtkMenuItem *mitem, gpointer user_data) { SwamiguiItemMenuCallback callback; IpatchList *selection; callback = g_object_get_data (G_OBJECT (mitem), "_func"); g_return_if_fail (callback != NULL); /* ++ ref selection */ g_object_get (swamigui_root, "selection", &selection, NULL); if (!selection) return; (*callback)(selection, user_data); g_object_unref (selection); /* -- unref selection */ } /** * swamigui_register_item_menu_action: * @action_id: Menu item action ID (example: "paste", "new", "copy", etc), * should be a static string since it is used directly. * @info: Menu item info (optional if @handler specified). Structure is * used directly and so it should be static as well as the strings inside. * @handler: Function to call when generating a menu (may be %NULL in which * case the default handler is used). Handler function should determine * whether the registered action is appropriate for the current item * selection and right click item and add menu items as appropriate. * * Registers a menu action. */ void swamigui_register_item_menu_action (char *action_id, SwamiguiItemMenuInfo *info, SwamiguiItemMenuHandler handler) { ActionBag *bag; guint key; GdkModifierType mods; GClosure *closure; g_return_if_fail (action_id != NULL && strlen(action_id) > 0); g_return_if_fail (info != NULL || handler != NULL); bag = g_new (ActionBag, 1); bag->action_id = action_id; bag->info = info; bag->handler = handler; G_LOCK (menu_action_hash); g_hash_table_insert (menu_action_hash, (gpointer)action_id, bag); G_UNLOCK (menu_action_hash); if (info->accel) { /* parse the accelerator */ gtk_accelerator_parse (info->accel, &key, &mods); if (key != 0) /* valid accelerator? */ { /* create closure for callback and add accelerator to accel group */ closure = g_cclosure_new_swap ((GCallback)swamigui_item_menu_accel_activate_callback, info, NULL); gtk_accel_group_connect (swamigui_item_menu_accel_group, key, mods, GTK_ACCEL_VISIBLE, closure); } } } static void swamigui_item_menu_accel_activate_callback (gpointer user_data) { SwamiguiItemMenuInfo *info = (SwamiguiItemMenuInfo *)user_data; IpatchList *selection; g_return_if_fail (info->func != NULL); g_object_get (swamigui_root, "selection", &selection, NULL); info->func (selection, info->data); g_object_unref (selection); } /** * swamigui_lookup_item_menu_action: * @action_id: ID string of item menu action to lookup. * @info: Location to store pointer to registered info (or %NULL to ignore). * @handler: Location to store pointer to registered handler (or %NULL to * ignore). * * Lookup item action information registered by @action_id. * * Returns: %TRUE if action found by @action_id, %FALSE if not found. */ gboolean swamigui_lookup_item_menu_action (const char *action_id, SwamiguiItemMenuInfo **info, SwamiguiItemMenuHandler *handler) { ActionBag *bag; if (info) *info = NULL; if (handler) *handler = NULL; g_return_val_if_fail (action_id != NULL, FALSE); bag = lookup_item_action_bag (action_id); if (!bag) return (FALSE); if (info) *info = bag->info; if (handler) *handler = bag->handler; return (TRUE); } /** * swamigui_register_item_menu_include_type: * @action_id: The registered action ID string * @type: The type to add * @derived: Set to %TRUE if derived types should match also * * Adds a selection item type for inclusion for the given registered item * action. */ void swamigui_register_item_menu_include_type (const char *action_id, GType type, gboolean derived) { TypeMatch *typematch; GSList *list; g_return_if_fail (action_id != NULL); g_return_if_fail (type != 0); typematch = g_new (TypeMatch, 1); typematch->type = type; typematch->derived = derived; G_LOCK (item_type_include_hash); list = g_hash_table_lookup (item_type_include_hash, action_id); if (!list) { list = g_slist_append (list, typematch); g_hash_table_insert (item_type_include_hash, (gpointer)action_id, list); } // Assignment to keep warn_unused_result happy (append to non-empty list) else list = g_slist_append (list, typematch); G_UNLOCK (item_type_include_hash); } /** * swamigui_register_item_menu_exclude_type: * @action_id: The registered action ID string * @type: The type to add * @derived: Set to %TRUE if derived types should match also * * Adds a selection item type for exclusion for the given registered item * action. */ void swamigui_register_item_menu_exclude_type (const char *action_id, GType type, gboolean derived) { TypeMatch *typematch; GSList *list; g_return_if_fail (action_id != NULL); g_return_if_fail (type != 0); typematch = g_new (TypeMatch, 1); typematch->type = type; typematch->derived = derived; G_LOCK (item_type_exclude_hash); list = g_hash_table_lookup (item_type_exclude_hash, action_id); if (!list) { list = g_slist_append (list, typematch); g_hash_table_insert (item_type_exclude_hash, (gpointer)action_id, list); } // Assignment to keep warn_unused_result happy (append to non-empty list) else list = g_slist_append (list, typematch); G_UNLOCK (item_type_exclude_hash); } /** * swamigui_test_item_menu_type: * @action_id: Menu item action ID string * @type: Type to test * * Tests if a given item selection @type is in the include list and not in * the exclude list for @action_id. * * Returns: %TRUE if item is in include list and not in exclude list * for @action_id, %FALSE otherwise. */ gboolean swamigui_test_item_menu_type (const char *action_id, GType type) { return (swamigui_test_item_menu_include_type (action_id, type) && swamigui_test_item_menu_exclude_type (action_id, type)); } /** * swamigui_test_item_menu_include_type: * @action_id: Menu item action ID string * @type: Type to test * * Tests if a given item selection @type is in the include list for @action_id. * * Returns: %TRUE if item is in include list for @action_id, %FALSE otherwise. */ gboolean swamigui_test_item_menu_include_type (const char *action_id, GType type) { TypeMatch *match; GSList *p; g_return_val_if_fail (action_id != NULL, FALSE); g_return_val_if_fail (type != 0, FALSE); G_LOCK (item_type_include_hash); p = g_hash_table_lookup (item_type_include_hash, action_id); for (; p; p = p->next) { match = (TypeMatch *)(p->data); if ((match->derived && g_type_is_a (type, match->type)) || (!match->derived && type == match->type)) break; } G_UNLOCK (item_type_include_hash); return (p != NULL); } /** * swamigui_test_item_menu_exclude_type: * @action_id: Menu item action ID string * @type: Type to test * * Tests if a given item selection @type is not in the exclude list for * @action_id. * * Returns: %TRUE if item is not in exclude list for @action_id (should be * included), %FALSE otherwise. */ gboolean swamigui_test_item_menu_exclude_type (const char *action_id, GType type) { TypeMatch *match; GSList *p; g_return_val_if_fail (action_id != NULL, FALSE); g_return_val_if_fail (type != 0, FALSE); G_LOCK (item_type_exclude_hash); p = g_hash_table_lookup (item_type_exclude_hash, action_id); for (; p; p = p->next) { match = (TypeMatch *)(p->data); if ((match->derived && g_type_is_a (type, match->type)) || (!match->derived && type == match->type)) break; } G_UNLOCK (item_type_exclude_hash); return (p == NULL); } /** * swamigui_item_menu_get_selection_single: * @menu: GUI menu object * * Test if a menu object has a single selected item and return it if so. * * Returns: The single selected item object or %NULL if not a single selection. * Returned object does NOT have a reference added and should be referenced * if used outside of calling function. */ GObject * swamigui_item_menu_get_selection_single (SwamiguiItemMenu *menu) { g_return_val_if_fail (SWAMIGUI_IS_ITEM_MENU (menu), FALSE); if (menu->selection && menu->selection->items && !menu->selection->items->next) return (menu->selection->items->data); else return (NULL); } /** * swamigui_item_menu_get_selection: * @menu: GUI menu object * * Test if a menu object has any selected items and return the selection list * if so. * * Returns: Selected items or %NULL if no selection object. No reference is * added for caller, so caller must reference if used outside of calling * context. */ IpatchList * swamigui_item_menu_get_selection (SwamiguiItemMenu *menu) { g_return_val_if_fail (SWAMIGUI_IS_ITEM_MENU (menu), NULL); if (menu->selection) return (menu->selection); return (NULL); } /** * swamigui_item_menu_handler_single: * @menu: The menu object * @action_id: The action ID * * A #SwamiguiItemMenuHandler type that can be used when registering a menu * action. It will add a single menu item, using the info provided during * action registration, if a single item is selected and is of a type found * in the include type list and not found in exclude list. */ void swamigui_item_menu_handler_single (SwamiguiItemMenu *menu, const char *action_id) { ActionBag *bag; GObject *item; g_return_if_fail (SWAMIGUI_IS_ITEM_MENU (menu)); g_return_if_fail (action_id != NULL); /* make sure there is only 1 item selected */ item = swamigui_item_menu_get_selection_single (menu); if (!item) return; /* item type is not in include list or in exclude list? - then return */ if (!swamigui_test_item_menu_type (action_id, G_OBJECT_TYPE (item))) return; bag = lookup_item_action_bag (action_id); /* lookup the registered action */ /* add a menu item from the registered info */ swamigui_item_menu_add (menu, bag->info, action_id); } /** * swamigui_item_menu_handler_multi: * @menu: The menu object * @action_id: The action ID * * A #SwamiguiItemMenuHandler type that can be used when registering a menu * action. It will add a single menu item, using the info provided during * action registration, if a single item is selected and is of a type found * in the include type list and not in exclude list or multiple items are * selected. */ void swamigui_item_menu_handler_multi (SwamiguiItemMenu *menu, const char *action_id) { ActionBag *bag; IpatchList *list; GList *items; g_return_if_fail (SWAMIGUI_IS_ITEM_MENU (menu)); g_return_if_fail (action_id != NULL); /* make sure there is at least 1 item selected */ list = swamigui_item_menu_get_selection (menu); if (!list || !list->items) return; items = list->items; /* if only 1 item is selected.. */ if (!items->next) { GObject *item = G_OBJECT (items->data); /* item type is not in include list or in exclude list? - then return */ if (!swamigui_test_item_menu_type (action_id, G_OBJECT_TYPE (item))) return; } bag = lookup_item_action_bag (action_id); /* lookup the registered action */ /* add a menu item from the registered info */ swamigui_item_menu_add (menu, bag->info, action_id); } /** * swamigui_item_menu_handler_single_all: * @menu: The menu object * @action_id: The action ID * * A #SwamiguiItemMenuHandler type that can be used when registering a menu * action. It will add a single menu item, using the info provided during * action registration, if there is a single item selected of any type. */ void swamigui_item_menu_handler_single_all (SwamiguiItemMenu *menu, const char *action_id) { ActionBag *bag; g_return_if_fail (SWAMIGUI_IS_ITEM_MENU (menu)); g_return_if_fail (action_id != NULL); /* make sure there is only 1 item selected */ if (!swamigui_item_menu_get_selection_single (menu)) return; bag = lookup_item_action_bag (action_id); /* lookup the registered action */ /* add a menu item from the registered info */ swamigui_item_menu_add (menu, bag->info, action_id); } /** * swamigui_item_menu_handler_multi_all: * @menu: The menu object * @action_id: The action ID * * A #SwamiguiItemMenuHandler type that can be used when registering a menu * action. It will add a single menu item, using the info provided during * action registration, if there is at least one item selected of any type. */ void swamigui_item_menu_handler_multi_all (SwamiguiItemMenu *menu, const char *action_id) { ActionBag *bag; IpatchList *list; g_return_if_fail (SWAMIGUI_IS_ITEM_MENU (menu)); g_return_if_fail (action_id != NULL); /* make sure there is at least 1 item selected */ list = swamigui_item_menu_get_selection (menu); if (!list || !list->items) return; bag = lookup_item_action_bag (action_id); /* lookup the registered action */ /* add a menu item from the registered info */ swamigui_item_menu_add (menu, bag->info, action_id); } swami/src/swamigui/SwamiguiRoot.h0000644000175000017500000001075011461334205017276 0ustar alessioalessio/* * SwamiguiRoot.h - Main Swami user interface object * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_ROOT_H__ #define __SWAMIGUI_ROOT_H__ typedef struct _SwamiguiRoot SwamiguiRoot; typedef struct _SwamiguiRootClass SwamiguiRootClass; #include #include #include #include #include #include #define SWAMIGUI_TYPE_ROOT (swamigui_root_get_type ()) #define SWAMIGUI_ROOT(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMIGUI_TYPE_ROOT, SwamiguiRoot)) #define SWAMIGUI_ROOT_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMIGUI_TYPE_ROOT, SwamiguiRootClass)) #define SWAMIGUI_IS_ROOT(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMIGUI_TYPE_ROOT)) #define SWAMIGUI_IS_ROOT_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMIGUI_TYPE_ROOT)) typedef enum { SWAMIGUI_QUIT_CONFIRM_ALWAYS, /* always pop a quit confirmation */ SWAMIGUI_QUIT_CONFIRM_UNSAVED, /* only if there are unsaved files */ SWAMIGUI_QUIT_CONFIRM_NEVER /* spontaneous combust */ } SwamiguiQuitConfirm; /* Swami User Interface Object */ struct _SwamiguiRoot { SwamiRoot parent_instance; /* derived from SwamiRoot */ SwamiguiTreeStore *patch_store; /* patch tree store */ IpatchList *tree_stores; /* list of tree stores (including above) */ IpatchList *selection; /* most recent item selection (trees, etc) */ GtkWidget *main_window; /* Main toplevel window */ GtkWidget *tree; /* Tree widget */ GtkWidget *splits; /* Note/velocity splits widget */ gboolean splits_changed; /* Set to TRUE if splits-item changed and needs updating */ GtkWidget *panel_selector; /* Panel selector widget */ SwamiguiStatusbar *statusbar; /* Main statusbar */ SwamiWavetbl *wavetbl; /* Wavetable object */ gboolean solo_item_enabled; /* TRUE if solo item enabled, FALSE otherwise */ GObject *solo_item; /* Solo item child of active-item or NULL */ char *solo_item_icon; /* Stores original icon of current solo item or NULL */ SwamiControlQueue *ctrl_queue; /* control update queue */ guint update_timeout_id; /* GSource ID for GUI update timeout */ int update_interval; /* GUI update interval in milliseconds */ SwamiControlFunc *ctrl_prop; /* patch item property change ctrl listener */ SwamiControlFunc *ctrl_add; /* patch item add control listener */ SwamiControlFunc *ctrl_remove; /* patch item remove control listener */ SwamiguiQuitConfirm quit_confirm; /* quit confirm enum */ gboolean splash_enable; /* show splash on startup? */ guint splash_delay; /* splash delay in milliseconds (0 to wait for button press) */ gboolean tips_enable; /* display next tip on startup? */ int tips_position; /* Swami tips position */ guint *piano_lower_keys; /* zero terminated array of keys (or NULL) */ guint *piano_upper_keys; /* zero terminated array of keys (or NULL) */ GType default_patch_type; /* default patch type (for File->New) */ GNode *loaded_xml_config; /* Last loaded XML config (usually only on startup) or NULL */ }; struct _SwamiguiRootClass { SwamiRootClass parent_class; /* signals */ void (*quit)(SwamiguiRoot *root); }; /* global instances of SwamiguiRoot */ extern SwamiguiRoot *swamigui_root; extern SwamiRoot *swami_root; /* just for convenience */ void swamigui_init (int *argc, char **argv[]); GType swamigui_root_get_type (void); SwamiguiRoot *swamigui_root_new (void); void swamigui_root_activate (SwamiguiRoot *root); void swamigui_root_quit (SwamiguiRoot *root); SwamiguiRoot *swamigui_get_root (gpointer gobject); gboolean swamigui_root_save_prefs (SwamiguiRoot *root); gboolean swamigui_root_load_prefs (SwamiguiRoot *root); #endif swami/src/swamigui/SwamiguiSpectrumCanvas.h0000644000175000017500000000724211461334205021313 0ustar alessioalessio/* * SwamiguiSpectrumCanvas.h - Spectrum frequency canvas item * A canvas item for displaying frequency spectrum data * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_SPECTRUM_CANVAS_H__ #define __SWAMIGUI_SPECTRUM_CANVAS_H__ #include #include #include typedef struct _SwamiguiSpectrumCanvas SwamiguiSpectrumCanvas; typedef struct _SwamiguiSpectrumCanvasClass SwamiguiSpectrumCanvasClass; #define SWAMIGUI_TYPE_SPECTRUM_CANVAS (swamigui_spectrum_canvas_get_type ()) #define SWAMIGUI_SPECTRUM_CANVAS(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMIGUI_TYPE_SPECTRUM_CANVAS, \ SwamiguiSpectrumCanvas)) #define SWAMIGUI_SPECTRUM_CANVAS_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMIGUI_TYPE_SPECTRUM_CANVAS, \ SwamiguiSpectrumCanvasClass)) #define SWAMIGUI_IS_SPECTRUM_CANVAS(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMIGUI_TYPE_SPECTRUM_CANVAS)) #define SWAMIGUI_IS_SPECTRUM_CANVAS_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMIGUI_TYPE_SPECTRUM_CANVAS)) /** * SwamiguiSpectrumDestroyNotify: * @spectrum: The spectrum data pointer as passed to * swamigui_spectrum_canvas_set_data(). * @size: The number of values in the @spectrum array * * This is a function type that gets called when a spectrum canvas item * is destroyed. This function is responsible for freeing @spectrum. */ typedef void (*SwamiguiSpectrumDestroyNotify)(double *spectrum, guint size); /* Spectrum canvas item */ struct _SwamiguiSpectrumCanvas { GnomeCanvasItem parent_instance; /*< private >*/ double *spectrum; /* spectrum data */ guint spectrum_size; /* number of values in spectrum data */ SwamiguiSpectrumDestroyNotify notify; /* notify function for spectrum data */ double max_value; /* maximum value in spectrum data */ GtkAdjustment *adj; /* adjustment for view */ gboolean update_adj; /* TRUE if adj should be updated (to stop loop) */ guint start; /* start spectrum index */ double zoom; /* zoom factor indexes/pixel */ double zoom_ampl; /* amplitude zoom factor */ int x, y; /* x, y coordinates of spectrum item */ int width, height; /* width and height in pixels */ GdkGC *min_gc; /* GC for drawing minimum lines */ GdkGC *max_gc; /* GC for drawing maximum lines */ GdkGC *bar_gc; /* GC for spectrum bars (zoom < 1.0) */ guint need_bbox_update : 1; /* set if bbox needs to be updated */ }; struct _SwamiguiSpectrumCanvasClass { GnomeCanvasItemClass parent_class; }; GType swamigui_spectrum_canvas_get_type (void); void swamigui_spectrum_canvas_set_data (SwamiguiSpectrumCanvas *canvas, double *spectrum, guint size, SwamiguiSpectrumDestroyNotify notify); int swamigui_spectrum_canvas_pos_to_spectrum (SwamiguiSpectrumCanvas *canvas, int xpos); int swamigui_spectrum_canvas_spectrum_to_pos (SwamiguiSpectrumCanvas *canvas, int index); #endif swami/src/swamigui/SwamiguiKnob.h0000644000175000017500000000413511461334205017244 0ustar alessioalessio/* * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_KNOB_H__ #define __SWAMIGUI_KNOB_H__ #include G_BEGIN_DECLS #define SWAMIGUI_TYPE_KNOB (swamigui_knob_get_type ()) #define SWAMIGUI_KNOB(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMIGUI_TYPE_KNOB, SwamiguiKnob)) #define SWAMIGUI_KNOB_CLASS(obj) \ (G_TYPE_CHECK_CLASS_CAST ((obj), SWAMIGUI_TYPE_KNOB, SwamiguiKnobClass)) #define SWAMIGUI_IS_KNOB(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMIGUI_TYPE_KNOB)) typedef struct _SwamiguiKnob SwamiguiKnob; typedef struct _SwamiguiKnobClass SwamiguiKnobClass; struct _SwamiguiKnob { GtkDrawingArea parent; GtkAdjustment *adj; /* < private > */ gboolean rotation_active; /* mouse rotation is active? */ double start_pos, end_pos; /* start and end rotation in radians */ double rotation; /* current rotation in radians */ double rotation_rate; /* rotation rate in pixels/radians */ double rotation_rate_fine; /* rotation rate (fine) in pixels/rads */ double xclick, yclick; /* position of mouse click */ double click_rotation; /* rotation of knob upon click */ }; struct _SwamiguiKnobClass { GtkDrawingAreaClass parent_class; }; GType swamigui_knob_get_type (void); GtkWidget *swamigui_knob_new (void); GtkAdjustment *swamigui_knob_get_adjustment (SwamiguiKnob *knob); G_END_DECLS #endif swami/src/swamigui/swami-2.glade0000644000175000017500000070703311461353033016760 0ustar alessioalessio True True 2 2 True 8 True True True True False True 2 True gtk-missing-image 0 True Notes 1 False False 0 True True True False True 2 True gtk-missing-image 0 True Velocity 1 False False 1 False False 0 True True What gets moved on middle click drag (ranges and/or root notes) 1 True Move False False 0 True Note Ranges Root Notes Both False False 1 False False 1 True True Octave 0 True False Lower keyboard MIDI octave False 1 True True False Join octaves True 2 True False Upper keyboard MIDI octave False 3 False False 2 True True Velocity 0 True False Lower keyboard MIDI velocity False 1 True True False True Synchronize upper and lower keyboard velocity True 2 True False Upper keyboard MIDI velocity False 3 False False 3 False False 0 True True 1 True True True never never False False 0 True True never never 1 True 0 0 100 1 10 10 False False 2 0 True 0 0 100 1 10 10 False False 1 1 True 20 True 2 2 4 2 True 0 Device GTK_FILL True 0 MIDI Channels 1 2 GTK_FILL True default 1 2 True 16 32 48 64 80 96 112 128 144 160 176 192 208 224 240 256 1 2 1 2 False False 0 True 2 4 2 True Device GTK_FILL True 1 2 False False 1 True 2 4 2 True Device GTK_FILL True 1 2 False False 2 True 20 True 3 2 4 2 True 4 3 2 1 1 2 2 3 True 0 Buffer Count 2 3 GTK_FILL True 0 Device GTK_FILL True 0 Buffer Size 1 2 GTK_FILL True 8192 4096 2048 1024 512 256 128 64 1 2 1 2 True default hw:0 hw:1 1 2 0 True 3 2 4 2 True 0 Auto connect 2 3 GTK_FILL True True False 0 True 1 2 2 3 GTK_FILL True True 0 0 100 1 10 0 1 2 1 2 True 0 Input channels 1 2 GTK_FILL True True 0 0 100 1 10 0 1 2 True 0 Output channels GTK_FILL 1 True 3 2 4 2 True 4 3 2 1 1 2 2 3 True 0 Buffer Count 2 3 GTK_FILL True 0 Device GTK_FILL True 0 Buffer Size 1 2 GTK_FILL True 8192 4096 2048 1024 512 256 128 64 1 2 1 2 True /dev/dsp /dev/dsp1 1 2 2 True 3 2 4 2 True 4 3 2 1 1 2 2 3 True 0 Buffer Count 2 3 GTK_FILL True 0 Device GTK_FILL True 0 Buffer Size 1 2 GTK_FILL True 8192 4096 2048 1024 512 256 128 64 1 2 1 2 True 1 2 3 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK never automatic True True False False False 0 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 8 8 8 8 True True False False tab tab tab 1 GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True 4 2 2 4 2 True True Maximum number of simultaneous voices 0 Polyphony GTK_FILL True True 16 16 4096 1 10 0 1 2 True 0 Sample Rate 1 2 GTK_FILL True 96000 48000 44100 22050 1 2 1 2 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK General False tab True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 4 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 4 True 0 True 1 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK <b>Audio Driver</b> True label_item False False 0 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 4 True 0 True 1 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK <b>Midi Driver</b> True label_item False False 1 1 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Drivers 1 False tab GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 4 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 8 Lower True True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True Select lower key bindings True True False False 0 Upper True True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True Select upper key bindings True True RadioLower False False 1 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 1 0 True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True Reset selected octave to default key bindings True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 2 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 1 gtk-revert-to-saved False False 0 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 Reset to defaults False False 1 2 False False 0 True True automatic automatic True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 1 0 Press the key to bind or ESC to stop. False False 2 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True True True True True Add a key binding True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 2 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 1 gtk-add False False 0 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 Add False False 1 0 True True True True Change key binding True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 2 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 1 gtk-edit False False 0 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 Change False False 1 1 True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True Delete selected key bindings True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 2 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 1 gtk-delete False False 0 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 Delete False False 1 2 False False 3 GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 2 2 2 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0.0099999997764825821 Confirm quit GTK_FILL True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True Default new instrument file type 1 2 1 2 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True Prompt for quit confirmation? 1 2 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 Default file type 1 2 GTK_FILL True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0.0099999997764825821 Instruments path word-char 2 3 GTK_FILL True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 Samples path 3 4 GTK_FILL True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True Default instrument file path select-folder 1 2 2 3 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True Default audio sample path select-folder 1 2 3 4 Show tips True True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True 4 5 GTK_FILL Show splash image True True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True 1 2 4 5 GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 4 True <big><b>FluidSynth</b></big> True 90 False 0 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0.5 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 4 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 4 1 0 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 2 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Gain False False 0 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 0 True swamigui_knob_new False False 1 0 Volume True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK label_item False False 1 True False False 2 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0.5 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 4 1 0 2 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 2 4 8 2 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Damp True 3 4 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Width True 2 3 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Room True 1 2 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Level True True True swamigui_knob_new 1 2 1 2 True True swamigui_knob_new 2 3 1 2 True True swamigui_knob_new 3 4 1 2 True True swamigui_knob_new 1 2 Reverb True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK label_item False False 3 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0.5 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 4 1 0 2 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 2 5 8 2 True 12 4 5 1 2 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Type True 4 5 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Depth True 3 4 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Freq True 2 3 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Count True 1 2 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Level True True True swamigui_knob_new 1 2 True True swamigui_knob_new 1 2 1 2 True True swamigui_knob_new 2 3 1 2 True True swamigui_knob_new 3 4 1 2 Chorus True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK label_item False False 4 GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 New audio sample center-on-parent dialog False True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 2 True 0 none True 2 2 True 4 True Name center False False 0 True True 1 False False 0 0 center False False 1 2 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 4 4 4 4 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 4 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 192000 96000 48000 44100 32000 22050 11025 False False 0 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Hz False False 1 False False 0 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 8 bit int 16 bit int 24 bit int 32 bit int 32 bit float 64 bit float False False 0 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Signed Unsigned False False 1 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Little Endian Big Endian False False 2 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Mono Stereo False False 3 False False 1 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK <b>Raw Audio Parameters</b> True label_item False False 0 False False 2 1 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK False 2 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK end gtk-cancel True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True False False 0 gtk-ok True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True False False 1 False end 0 True window1 True True True True 2 True Name False False 0 True 1 False True gtk-save True True False Save current script True False True gtk-new True True False Create new script True False True gtk-execute True True False Execute current script True False True Shell mode True True False Execute a line when ENTER is pressed True True False False False 0 True True True 0 out True True automatic automatic True <b>Script Editor</b> True label_item False True True 0 out True True 2 automatic automatic in True True False char False True <b>Python Console</b> True label_item False True 1 True Loop Finder 392 416 dialog True 4 4 True True True 2 automatic automatic in True True False True True gtk-index 0 True Results 1 False tab True False automatic automatic True True True 5 2 4 2 True 0 Group size 4 5 GTK_FILL True 0 Group offset 3 4 GTK_FILL True True Minimum length of matching loops 1 0 100 1 10 0 1 True 1 2 1 2 True 0 Window size GTK_FILL True True Size of analysis window (number of samples around loop points to compare) 1 1 100 1 10 0 1 True 1 2 True 0 Min loop size 1 2 GTK_FILL True 0 Max results 2 3 GTK_FILL True True Maximum loop suggestion results 1 1 2000 1 10 0 1 True 1 2 2 3 True True Minimum loop group position difference (best result per group) 1 1 100 1 10 0 1 True 1 2 3 4 True True Minimum loop group size difference 1 0 100 1 10 0 1 True 1 2 4 5 False False 0 1 True True gtk-properties 0 True Config 1 1 False tab 0 True False False 1 True 2 gtk-revert-to-saved True True True False Revert to original loop values True False False 0 True True True False False False 1 True 0.00 secs False False 2 False False 2 True normal Swami Copyright (C) 1999-2010 Joshua "Element" Green <jgreen@users.sourceforge.net> http://swami.sourceforge.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License only. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA or point your web browser to http://www.gnu.org. Joshua "Element" Green <jgreen@users.sourceforge.net> True True False end 0 True 4 4 3 4 2 True 0 Root Note center GTK_FILL True 0 Exclusive Class center 1 2 GTK_FILL True 0 Fixed Note center 2 3 GTK_FILL True 0 Fixed Velocity center 3 4 GTK_FILL True True 0 0 127 0 10 0 1 True 1 2 GTK_FILL True True 1 1 65535 1 10 0 1 True 1 2 1 2 True True 0 0 127 1 10 0 1 True 1 2 2 3 GTK_FILL True True 0 0 127 1 10 0 1 True 1 2 3 4 GTK_FILL True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True Toggle value assignment True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK gtk-apply 1 2 3 True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True Toggle value assignment True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK gtk-apply 1 2 3 1 2 True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True Toggle value assignment True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK gtk-apply 1 2 3 2 3 True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True Toggle value assignment True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK gtk-apply 1 2 3 3 4 True True 2 True True automatic automatic True True 0 True 2 True New True True False True 0 Delete True True False True 1 False False 1 0 True True 0 True 4 0 True 2 True False True 0 0 True Source label_item False False 0 True True 0 True 4 0 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 2 0 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 1 True Destination label_item 0 False False 1 True 0 True 4 0 True True 1 0 True 4 True 1 Amount center False False 0 True True 0 -32768 32767 1 10 0 1 True 1 False False 0 True 2 True False True 0 0 False False 1 True Amount Source label_item False False 2 False False 1 True 4 True 5 5 2 2 True 0 Name center GTK_FILL True 0 Author center 1 2 GTK_FILL True 0 Copyright center 2 3 GTK_FILL True True 1 5 True True 1 5 1 2 True True 1 5 2 3 True 0 Date center 3 4 GTK_FILL True True 1 2 3 4 Current Date True True False True 2 3 3 4 True True 4 5 3 4 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 8 True 0 Product center 3 4 3 4 GTK_FILL 24 Bit Samples True True False Activating this will cause the SoundFont to be saved with 24 bit samples. True 5 4 5 GTK_FILL False False 0 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0.5 in True False 4 automatic automatic in True True word True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Comment label_item 1 True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 4 0 in True 4 4 3 4 2 True 0 center 2 3 True 0 center 2 3 1 2 True 0 center 2 3 2 3 True 0 Software center 3 4 GTK_FILL True 0 ROM version center 2 3 GTK_FILL True 0 Sound engine center 1 2 GTK_FILL True 0 SoundFont version center GTK_FILL True 0 center 2 3 3 4 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 1 2 4 label_item True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK <b>Information</b> True label_item False False 2 True Swami Tips 340 180 True True False 4 automatic automatic in True True False word 0 True 2 4 Show tips on start up True True False True True False False 0 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 2 True gtk-media-previous True True False True False False 0 gtk-media-next True True False True False False 1 gtk-close True True False True False False 2 False False end 1 False False 4 1 True 4 4 2 4 2 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 0 True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 192000 96000 48000 44100 32000 22050 11025 1 2 1 2 True 0 Name center GTK_FILL True 0 Sample rate center 1 2 GTK_FILL True 0 0 True True Name of sample 1 2 True 0 Fine tuning center 3 4 GTK_FILL True 0 0 True 4 True True Fine tuning in cents 0 -128 127 1 10 0 1 True 0 True cents center False False 1 1 2 3 4 True 0 Root note center 2 3 GTK_FILL True 0 0 True swamigui_note_selector_new 1 2 2 3 True 4 5 2 4 2 True 0 Root Note center 1 2 GTK_FILL True 0 Exclusive Class center 2 3 True 0 Fixed Note center 3 4 GTK_FILL True 0 Fixed Velocity center 4 5 GTK_FILL True 0 Name center GTK_FILL True True 1 2 True 0 0 True True True 0 0 127 0 10 0 1 True False False 0 True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True Toggle value assignment True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK gtk-apply 1 False False 1 1 2 1 2 GTK_FILL True 0 0 True True True 1 1 127 1 10 0 1 True False False 0 True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True Toggle value assignment True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK gtk-apply 1 False False 1 1 2 2 3 GTK_FILL True 0 0 True True True 0 0 127 1 10 0 1 True False False 0 True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True Toggle value assignment True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK gtk-apply 1 False False 1 1 2 3 4 GTK_FILL True 0 0 True True True 0 0 127 1 10 0 1 True False False 0 True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True Toggle value assignment True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK gtk-apply 1 False False 1 1 2 4 5 GTK_FILL True 4 3 2 4 2 True 0 0 True 4 True True 0 0 128 1 10 0 1 True 0 Percussion True True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True 1 1 2 1 2 True 0 Name center GTK_FILL True 0 Bank center 1 2 GTK_FILL True 0 Program center 2 3 GTK_FILL True 0 0 True True 1 2 GTK_FILL True 0 0 True True 0 0 127 1 10 0 1 True 1 2 2 3 swami/src/swamigui/SwamiguiItemMenu.h0000644000175000017500000001220311461334205020071 0ustar alessioalessio/* * SwamiguiItemMenu.h - Swami item action (right click) menu routines * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_ITEM_MENU_H__ #define __SWAMIGUI_ITEM_MENU_H__ #include typedef struct _SwamiguiItemMenu SwamiguiItemMenu; typedef struct _SwamiguiItemMenuClass SwamiguiItemMenuClass; typedef struct _SwamiguiItemMenuInfo SwamiguiItemMenuInfo; typedef struct _SwamiguiItemMenuEntry SwamiguiItemMenuEntry; #define SWAMIGUI_TYPE_ITEM_MENU (swamigui_item_menu_get_type ()) #define SWAMIGUI_ITEM_MENU(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMIGUI_TYPE_ITEM_MENU, \ SwamiguiItemMenu)) #define SWAMIGUI_ITEM_MENU_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMIGUI_TYPE_ITEM_MENU, \ SwamiguiItemMenuClass)) #define SWAMIGUI_IS_ITEM_MENU(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMIGUI_TYPE_ITEM_MENU)) #define SWAMIGUI_IS_ITEM_MENU_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMIGUI_TYPE_ITEM_MENU)) /** * SwamiguiItemMenuCallback: * @selection: Item selection * @data: Data defined by the menu item * * A callback function type that is used when a menu item is activated. */ typedef void (*SwamiguiItemMenuCallback)(IpatchList *selection, gpointer data); /** * SwamiguiItemMenuHandler: * @menu: GUI menu object * @action_id: Menu action ID (set when action was registered) * * A handler for a menu item type. Called when generating a menu for an * item selection and right click item. This function should determine if * its action type (example: paste, delete, copy, new, etc) is valid for the * given selection and add one or more menu items if so. */ typedef void (*SwamiguiItemMenuHandler)(SwamiguiItemMenu *menu, const char *action_id); typedef enum /*< flags >*/ { SWAMIGUI_ITEM_MENU_INACTIVE = 1 << 0, /* set if menu item should be inactive */ SWAMIGUI_ITEM_MENU_PLUGIN = 1 << 1 /* set if menu item is for a plugin */ } SwamiguiItemMenuFlags; /* menu item info */ struct _SwamiguiItemMenuInfo { guint order; /* an integer used to sort items (lower values first) */ char *label; /* menu label text */ char *accel; /* key accelerator */ char *icon; /* stock ID of icon */ guint flags; /* SwamiguiItemMenuFlags */ SwamiguiItemMenuCallback func; /* function to call when item is activated */ gpointer data; /* data to pass to callback function */ }; struct _SwamiguiItemMenu { GtkMenu parent_instance; IpatchList *selection; /* current item selection or NULL */ GObject *rclick; /* current right click item or NULL */ GObject *creator; /* object that created menu (SwamiguiTree for example) */ }; struct _SwamiguiItemMenuClass { GtkMenuClass parent_class; }; extern GtkAccelGroup *swamigui_item_menu_accel_group; GType swamigui_item_menu_get_type (); SwamiguiItemMenu *swamigui_item_menu_new (); GtkWidget *swamigui_item_menu_add (SwamiguiItemMenu *menu, const SwamiguiItemMenuInfo *info, const char *action_id); GtkWidget *swamigui_item_menu_add_registered_info (SwamiguiItemMenu *menu, const char *action_id); void swamigui_item_menu_generate (SwamiguiItemMenu *menu); void swamigui_register_item_menu_action (char *action_id, SwamiguiItemMenuInfo *info, SwamiguiItemMenuHandler handler); gboolean swamigui_lookup_item_menu_action (const char *action_id, SwamiguiItemMenuInfo **info, SwamiguiItemMenuHandler *handler); void swamigui_register_item_menu_include_type (const char *action_id, GType type, gboolean derived); void swamigui_register_item_menu_exclude_type (const char *action_id, GType type, gboolean derived); gboolean swamigui_test_item_menu_type (const char *action_id, GType type); gboolean swamigui_test_item_menu_include_type (const char *action_id, GType type); gboolean swamigui_test_item_menu_exclude_type (const char *action_id, GType type); GObject *swamigui_item_menu_get_selection_single (SwamiguiItemMenu *menu); IpatchList *swamigui_item_menu_get_selection (SwamiguiItemMenu *menu); void swamigui_item_menu_handler_single (SwamiguiItemMenu *menu, const char *action_id); void swamigui_item_menu_handler_multi (SwamiguiItemMenu *menu, const char *action_id); void swamigui_item_menu_handler_single_all (SwamiguiItemMenu *menu, const char *action_id); void swamigui_item_menu_handler_multi_all (SwamiguiItemMenu *menu, const char *action_id); #endif swami/src/swamigui/widgets/0000755000175000017500000000000011716016660016144 5ustar alessioalessioswami/src/swamigui/widgets/icon-combo.c0000644000175000017500000001501307676126120020340 0ustar alessioalessio/* * Ripped and modified for Swami from libgal-0.19.2 * * widget-pixmap-combo.c - A pixmap selector combo box * Copyright 2000, 2001, Ximian, Inc. * * Authors: * Jody Goldberg * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License, version 2, as published by the Free Software Foundation. * * 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. */ #include #include #include #include #include "combo-box.h" #include "icon-combo.h" /* from Swami src/swamigui */ #include "i18n.h" #define ICON_PREVIEW_WIDTH 15 #define ICON_PREVIEW_HEIGHT 15 enum { CHANGED, LAST_SIGNAL }; static void icon_combo_select_icon_index (IconCombo * ic, int index); static guint icon_combo_signals[LAST_SIGNAL] = { 0, }; static GObjectClass *icon_combo_parent_class; /***************************************************************************/ static void icon_combo_finalize (GObject *object) { IconCombo *ic = ICON_COMBO (object); // g_object_unref (GTK_OBJECT (ic->tool_tip)); g_free (ic->icons); (*icon_combo_parent_class->finalize) (object); } static void icon_combo_class_init (IconComboClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); obj_class->finalize = icon_combo_finalize; icon_combo_parent_class = g_type_class_peek_parent (klass); icon_combo_signals[CHANGED] = g_signal_new ("changed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IconComboClass, changed), NULL, NULL, g_cclosure_marshal_VOID__INT, GTK_TYPE_NONE, 1, G_TYPE_INT); } GType icon_combo_get_type (void) { static GType type = 0; if (!type) { GTypeInfo info = { sizeof (IconComboClass), NULL, NULL, (GClassInitFunc) icon_combo_class_init, NULL, NULL, sizeof (IconCombo), 0, (GInstanceInitFunc) NULL, }; type = g_type_register_static (COMBO_BOX_TYPE, "IconCombo", &info, 0); } return (type); } static void emit_change (GtkWidget *button, IconCombo *ic) { g_return_if_fail (ic != NULL); g_return_if_fail (0 <= ic->last_index); g_return_if_fail (ic->last_index < ic->num_elements); gtk_signal_emit (GTK_OBJECT (ic), icon_combo_signals[CHANGED], ic->elements[ic->last_index].id); } static void icon_clicked (GtkWidget *button, IconCombo *ic) { int index = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (button), "index")); icon_combo_select_icon_index (ic, index); emit_change (button, ic); combo_box_popup_hide (COMBO_BOX (ic)); } static void icon_table_setup (IconCombo *ic) { int row, col, index = 0; ic->combo_table = gtk_table_new (ic->cols, ic->rows, 0); ic->tool_tip = gtk_tooltips_new (); ic->icons = g_malloc (sizeof (GtkImage *) * ic->cols * ic->rows); for (row = 0; row < ic->rows; row++) { for (col = 0; col < ic->cols; ++col, ++index) { IconComboElement const *element = ic->elements + index; GtkWidget *button; if (element->stock_id == NULL) { /* exit both loops */ row = ic->rows; break; } ic->icons[index] = gtk_image_new_from_stock (element->stock_id, GTK_ICON_SIZE_SMALL_TOOLBAR); button = gtk_button_new (); gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE); gtk_container_add (GTK_CONTAINER (button), GTK_WIDGET (ic->icons[index])); gtk_tooltips_set_tip (ic->tool_tip, button, _(element->untranslated_tooltip), NULL); gtk_table_attach (GTK_TABLE (ic->combo_table), button, col, col + 1, row + 1, row + 2, GTK_FILL, GTK_FILL, 1, 1); g_signal_connect (button, "clicked", G_CALLBACK (icon_clicked), ic); g_object_set_data (G_OBJECT (button), "index", GINT_TO_POINTER (index)); } } ic->num_elements = index; gtk_widget_show_all (ic->combo_table); } static void icon_combo_construct (IconCombo *ic, IconComboElement const *elements, int ncols, int nrows) { g_return_if_fail (ic != NULL); g_return_if_fail (IS_ICON_COMBO (ic)); /* Our table selector */ ic->cols = ncols; ic->rows = nrows; ic->elements = elements; icon_table_setup (ic); ic->preview_button = gtk_button_new (); gtk_button_set_relief (GTK_BUTTON (ic->preview_button), GTK_RELIEF_NONE); ic->preview_icon = gtk_image_new_from_stock (elements[0].stock_id, GTK_ICON_SIZE_SMALL_TOOLBAR); gtk_container_add (GTK_CONTAINER (ic->preview_button), GTK_WIDGET (ic->preview_icon)); // gtk_widget_set_usize (GTK_WIDGET (ic->preview_icon), 24, 24); g_signal_connect (ic->preview_button, "clicked", G_CALLBACK (emit_change), ic); gtk_widget_show_all (ic->preview_button); combo_box_construct (COMBO_BOX (ic), ic->preview_button, ic->combo_table); } GtkWidget * icon_combo_new (IconComboElement const *elements, int ncols, int nrows) { IconCombo *ic; g_return_val_if_fail (elements != NULL, NULL); g_return_val_if_fail (elements != NULL, NULL); g_return_val_if_fail (ncols > 0, NULL); g_return_val_if_fail (nrows > 0, NULL); ic = g_object_new (ICON_COMBO_TYPE, NULL); icon_combo_construct (ic, elements, ncols, nrows); return (GTK_WIDGET (ic)); } /* select a icon by its index */ static void icon_combo_select_icon_index (IconCombo *ic, int index) { g_return_if_fail (ic != NULL); g_return_if_fail (IS_ICON_COMBO (ic)); g_return_if_fail (0 <= index); g_return_if_fail (index < ic->num_elements); ic->last_index = index; gtk_container_remove (GTK_CONTAINER (ic->preview_button), ic->preview_icon); ic->preview_icon = gtk_image_new_from_stock (ic->elements[index].stock_id, GTK_ICON_SIZE_SMALL_TOOLBAR); gtk_widget_show (ic->preview_icon); gtk_container_add (GTK_CONTAINER (ic->preview_button), ic->preview_icon); } /* select a icon by its unique integer ID */ void icon_combo_select_icon (IconCombo *ic, int id) { int i; g_return_if_fail (ic != NULL); g_return_if_fail (IS_ICON_COMBO (ic)); g_return_if_fail (ic->num_elements > 0); for (i = 0; i < ic->num_elements; i++) if (ic->elements[i].id == id) break; if (i >= ic->num_elements) i = 0; icon_combo_select_icon_index (ic, i); } swami/src/swamigui/widgets/Makefile.am0000644000175000017500000000025111461617723020202 0ustar alessioalessio## Process this file with automake to create Makefile.in EXTRA_DIST = \ combo-box.c \ combo-box.h \ icon-combo.c \ icon-combo.h MAINTAINERCLEANFILES = Makefile.in swami/src/swamigui/widgets/combo-box.c0000644000175000017500000005635310157753120020206 0ustar alessioalessio/* * * Ripped and slightly modified for Swami from libgal-0.19.2 * * gtk-combo-box.c - a customizable combobox * Copyright 2000, 2001, Ximian, Inc. * * Authors: * Miguel de Icaza (miguel@gnu.org) * Adrian E Feiguin (feiguin@ifir.edu.ar) * Paolo Molnaro (lupus@debian.org). * Jon K Hellan (hellan@acm.org) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License, version 2, as published by the Free Software Foundation. * * 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. */ #include #include #include #include #include #include #include #include #include #include #include #include "combo-box.h" static GtkHBoxClass *combo_box_parent_class; static int combo_toggle_pressed (GtkToggleButton * tbutton, ComboBox * combo_box); static void combo_popup_tear_off (ComboBox * combo, gboolean set_position); static void combo_set_tearoff_state (ComboBox * combo, gboolean torn_off); static void combo_popup_reparent (GtkWidget * popup, GtkWidget * new_parent, gboolean unrealize); static gboolean cb_popup_delete (GtkWidget * w, GdkEventAny * event, ComboBox * combo); static void combo_tearoff_bg_copy (ComboBox * combo); enum { POP_DOWN_WIDGET, POP_DOWN_DONE, PRE_POP_DOWN, POST_POP_HIDE, LAST_SIGNAL }; static gint combo_box_signals[LAST_SIGNAL] = { 0, }; struct _ComboBoxPrivate { GtkWidget *pop_down_widget; GtkWidget *display_widget; /* * Internal widgets used to implement the ComboBox */ GtkWidget *frame; GtkWidget *arrow_button; GtkWidget *toplevel; /* Popup's toplevel when not torn off */ GtkWidget *tearoff_window; /* Popup's toplevel when torn off */ guint torn_off; GtkWidget *tearable; /* The tearoff "button" */ GtkWidget *popup; /* Popup */ /* * Closure for invoking the callbacks above */ void *closure; }; static void combo_box_finalize (GObject *object) { ComboBox *combo_box = COMBO_BOX (object); gtk_object_destroy (GTK_OBJECT (combo_box->priv->toplevel)); g_object_unref (G_OBJECT (combo_box->priv->toplevel)); if (combo_box->priv->tearoff_window) { gtk_object_destroy (GTK_OBJECT (combo_box->priv->tearoff_window)); g_object_unref (G_OBJECT (combo_box->priv->tearoff_window)); /* ?? */ } g_free (combo_box->priv); G_OBJECT_CLASS (combo_box_parent_class)->finalize (object); } void my_marshal_POINTER__NONE (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { typedef gpointer (*GMarshalFunc_POINTER__NONE) (gpointer data1, gpointer data2); register GMarshalFunc_POINTER__NONE callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2, retval; g_return_if_fail (n_param_values == 1); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_POINTER__NONE) (marshal_data ? marshal_data : cc->callback); retval = callback (data1, data2); g_value_set_pointer (return_value, retval); } static void combo_box_class_init (ComboBoxClass *klass) { combo_box_parent_class = gtk_type_class (gtk_hbox_get_type ()); G_OBJECT_CLASS (klass)->finalize = combo_box_finalize; combo_box_signals[POP_DOWN_WIDGET] = g_signal_new ("pop_down_widget", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ComboBoxClass, pop_down_widget), NULL, NULL, my_marshal_POINTER__NONE, GTK_TYPE_POINTER, 0); combo_box_signals[POP_DOWN_DONE] = g_signal_new ("pop_down_done", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ComboBoxClass, pop_down_done), NULL, NULL, gtk_marshal_BOOL__POINTER, GTK_TYPE_BOOL, 1, GTK_TYPE_OBJECT); combo_box_signals[PRE_POP_DOWN] = g_signal_new ("pre_pop_down", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ComboBoxClass, pre_pop_down), NULL, NULL, gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); combo_box_signals[POST_POP_HIDE] = g_signal_new ("post_pop_hide", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ComboBoxClass, post_pop_hide), NULL, NULL, gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); } static void deactivate_arrow (ComboBox * combo_box) { GtkToggleButton *arrow; arrow = GTK_TOGGLE_BUTTON (combo_box->priv->arrow_button); gtk_signal_handler_block_by_func (GTK_OBJECT (arrow), GTK_SIGNAL_FUNC (combo_toggle_pressed), combo_box); gtk_toggle_button_set_active (arrow, FALSE); gtk_signal_handler_unblock_by_func (GTK_OBJECT (arrow), GTK_SIGNAL_FUNC (combo_toggle_pressed), combo_box); } /** * combo_box_popup_hide_unconditional * @combo_box: Combo box * * Hide popup, whether or not it is torn off. */ static void combo_box_popup_hide_unconditional (ComboBox * combo_box) { gboolean popup_info_destroyed = FALSE; g_return_if_fail (combo_box != NULL); g_return_if_fail (IS_COMBO_BOX (combo_box)); gtk_widget_hide (combo_box->priv->toplevel); gtk_widget_hide (combo_box->priv->popup); if (combo_box->priv->torn_off) { GTK_TEAROFF_MENU_ITEM (combo_box->priv->tearable)->torn_off = FALSE; combo_set_tearoff_state (combo_box, FALSE); } gtk_grab_remove (combo_box->priv->toplevel); gdk_pointer_ungrab (GDK_CURRENT_TIME); g_object_ref (G_OBJECT (combo_box->priv->pop_down_widget)); gtk_signal_emit (GTK_OBJECT (combo_box), combo_box_signals[POP_DOWN_DONE], combo_box->priv->pop_down_widget, &popup_info_destroyed); if (popup_info_destroyed) { gtk_container_remove (GTK_CONTAINER (combo_box->priv->frame), combo_box->priv->pop_down_widget); combo_box->priv->pop_down_widget = NULL; } g_object_unref (G_OBJECT (combo_box->priv->pop_down_widget)); deactivate_arrow (combo_box); gtk_signal_emit (GTK_OBJECT (combo_box), combo_box_signals[POST_POP_HIDE]); } /** * combo_box_popup_hide: * @combo_box: Combo box * * Hide popup, but not when it is torn off. * This is the external interface - for subclasses and apps which expect a * regular combo which doesn't do tearoffs. */ void combo_box_popup_hide (ComboBox * combo_box) { if (!combo_box->priv->torn_off) combo_box_popup_hide_unconditional (combo_box); else if (GTK_WIDGET_VISIBLE (combo_box->priv->toplevel)) { /* Both popup and tearoff window present. Get rid of just the popup shell. */ combo_popup_tear_off (combo_box, FALSE); deactivate_arrow (combo_box); } } /* * Find best location for displaying */ void combo_box_get_pos (ComboBox * combo_box, int *x, int *y) { GtkWidget *wcombo = GTK_WIDGET (combo_box); int ph, pw; gdk_window_get_origin (wcombo->window, x, y); *y += wcombo->allocation.height + wcombo->allocation.y; *x += wcombo->allocation.x; ph = combo_box->priv->popup->allocation.height; pw = combo_box->priv->popup->allocation.width; if ((*y + ph) > gdk_screen_height ()) *y = gdk_screen_height () - ph; if ((*x + pw) > gdk_screen_width ()) *x = gdk_screen_width () - pw; } static void combo_box_popup_display (ComboBox * combo_box) { int x, y; g_return_if_fail (combo_box != NULL); g_return_if_fail (IS_COMBO_BOX (combo_box)); /* * If we have no widget to display on the popdown, * create it */ if (!combo_box->priv->pop_down_widget) { GtkWidget *pw = NULL; gtk_signal_emit (GTK_OBJECT (combo_box), combo_box_signals[POP_DOWN_WIDGET], &pw); g_assert (pw != NULL); combo_box->priv->pop_down_widget = pw; gtk_container_add (GTK_CONTAINER (combo_box->priv->frame), pw); } gtk_signal_emit (GTK_OBJECT (combo_box), combo_box_signals[PRE_POP_DOWN]); if (combo_box->priv->torn_off) { /* To give the illusion that tearoff still displays the * popup, we copy the image in the popup window to the * background. Thus, it won't be blank after reparenting */ combo_tearoff_bg_copy (combo_box); /* We force an unrealize here so that we don't trigger * redrawing/ clearing code - we just want to reveal our * backing pixmap. */ combo_popup_reparent (combo_box->priv->popup, combo_box->priv->toplevel, TRUE); } combo_box_get_pos (combo_box, &x, &y); gtk_widget_set_uposition (combo_box->priv->toplevel, x, y); gtk_widget_realize (combo_box->priv->popup); gtk_widget_show (combo_box->priv->popup); gtk_widget_realize (combo_box->priv->toplevel); gtk_widget_show (combo_box->priv->toplevel); gtk_grab_add (combo_box->priv->toplevel); gdk_pointer_grab (combo_box->priv->toplevel->window, TRUE, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK, NULL, NULL, GDK_CURRENT_TIME); } static int combo_toggle_pressed (GtkToggleButton * tbutton, ComboBox * combo_box) { if (tbutton->active) combo_box_popup_display (combo_box); else combo_box_popup_hide_unconditional (combo_box); return TRUE; } static gint combo_box_button_press (GtkWidget * widget, GdkEventButton * event, ComboBox * combo_box) { GtkWidget *child; child = gtk_get_event_widget ((GdkEvent *) event); if (child != widget) { while (child) { if (child == widget) return FALSE; child = child->parent; } } combo_box_popup_hide (combo_box); return TRUE; } /** * combo_box_key_press * @widget: Widget * @event: Event * @combo_box: Combo box * * Key press handler which dismisses popup on escape. * Popup is dismissed whether or not popup is torn off. */ static gint combo_box_key_press (GtkWidget * widget, GdkEventKey * event, ComboBox * combo_box) { if (event->keyval == GDK_Escape) { combo_box_popup_hide_unconditional (combo_box); return TRUE; } else return FALSE; } static void cb_state_change (GtkWidget * widget, GtkStateType old_state, ComboBox * combo_box) { GtkStateType const new_state = GTK_WIDGET_STATE (widget); gtk_widget_set_state (combo_box->priv->display_widget, new_state); } static void combo_box_init (ComboBox * combo_box) { GtkWidget *arrow; GdkCursor *cursor; combo_box->priv = g_new0 (ComboBoxPrivate, 1); /* * Create the arrow */ combo_box->priv->arrow_button = gtk_toggle_button_new (); GTK_WIDGET_UNSET_FLAGS (combo_box->priv->arrow_button, GTK_CAN_FOCUS); arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_IN); gtk_container_add (GTK_CONTAINER (combo_box->priv->arrow_button), arrow); gtk_box_pack_end (GTK_BOX (combo_box), combo_box->priv->arrow_button, FALSE, FALSE, 0); gtk_signal_connect (GTK_OBJECT (combo_box->priv->arrow_button), "toggled", GTK_SIGNAL_FUNC (combo_toggle_pressed), combo_box); gtk_widget_show_all (combo_box->priv->arrow_button); /* * prelight the display widget when mousing over the arrow. */ gtk_signal_connect (GTK_OBJECT (combo_box->priv->arrow_button), "state-changed", GTK_SIGNAL_FUNC (cb_state_change), combo_box); /* * The pop-down container */ combo_box->priv->toplevel = gtk_window_new (GTK_WINDOW_POPUP); gtk_widget_ref (combo_box->priv->toplevel); gtk_object_sink (GTK_OBJECT (combo_box->priv->toplevel)); gtk_window_set_policy (GTK_WINDOW (combo_box->priv->toplevel), FALSE, TRUE, FALSE); combo_box->priv->popup = gtk_event_box_new (); gtk_container_add (GTK_CONTAINER (combo_box->priv->toplevel), combo_box->priv->popup); gtk_widget_show (combo_box->priv->popup); gtk_widget_realize (combo_box->priv->popup); cursor = gdk_cursor_new (GDK_TOP_LEFT_ARROW); gdk_window_set_cursor (combo_box->priv->popup->window, cursor); gdk_cursor_destroy (cursor); combo_box->priv->torn_off = FALSE; combo_box->priv->tearoff_window = NULL; combo_box->priv->frame = gtk_frame_new (NULL); gtk_container_add (GTK_CONTAINER (combo_box->priv->popup), combo_box->priv->frame); gtk_frame_set_shadow_type (GTK_FRAME (combo_box->priv->frame), GTK_SHADOW_OUT); gtk_signal_connect (GTK_OBJECT (combo_box->priv->toplevel), "button_press_event", GTK_SIGNAL_FUNC (combo_box_button_press), combo_box); gtk_signal_connect (GTK_OBJECT (combo_box->priv->toplevel), "key_press_event", GTK_SIGNAL_FUNC (combo_box_key_press), combo_box); } GType combo_box_get_type (void) { static GType type = 0; if (!type) { GTypeInfo info = { sizeof (ComboBoxClass), NULL, NULL, (GClassInitFunc) combo_box_class_init, NULL, NULL, sizeof (ComboBox), 0, (GInstanceInitFunc) combo_box_init, }; type = g_type_register_static (gtk_hbox_get_type (), "MyComboBox", &info, 0); } return type; } /** * combo_box_set_display: * @combo_box: the Combo Box to modify * @display_widget: The widget to be displayed * Sets the displayed widget for the @combo_box to be @display_widget */ void combo_box_set_display (ComboBox * combo_box, GtkWidget * display_widget) { g_return_if_fail (combo_box != NULL); g_return_if_fail (IS_COMBO_BOX (combo_box)); g_return_if_fail (display_widget != NULL); g_return_if_fail (GTK_IS_WIDGET (display_widget)); if (combo_box->priv->display_widget && combo_box->priv->display_widget != display_widget) gtk_container_remove (GTK_CONTAINER (combo_box), combo_box->priv->display_widget); combo_box->priv->display_widget = display_widget; gtk_box_pack_start (GTK_BOX (combo_box), display_widget, TRUE, TRUE, 0); } static gboolean cb_tearable_enter_leave (GtkWidget * w, GdkEventCrossing * event, gpointer data) { gboolean const flag = GPOINTER_TO_INT (data); gtk_widget_set_state (w, flag ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL); return FALSE; } /** * combo_popup_tear_off * @combo: Combo box * @set_position: Set to position of popup shell if true * * Tear off the popup * * FIXME: * Gtk popup menus are toplevel windows, not dialogs. I think this is wrong, * and make the popups dialogs. But may be there should be a way to make * them toplevel. We can do this after creating: * GTK_WINDOW (tearoff)->type = GTK_WINDOW_TOPLEVEL; */ static void combo_popup_tear_off (ComboBox * combo, gboolean set_position) { int x, y; if (!combo->priv->tearoff_window) { GtkWidget *tearoff; gchar *title; tearoff = gtk_window_new (GTK_WINDOW_POPUP); gtk_widget_ref (tearoff); gtk_object_sink (GTK_OBJECT (tearoff)); combo->priv->tearoff_window = tearoff; gtk_widget_set_app_paintable (tearoff, TRUE); gtk_signal_connect (GTK_OBJECT (tearoff), "key_press_event", GTK_SIGNAL_FUNC (combo_box_key_press), GTK_OBJECT (combo)); gtk_widget_realize (tearoff); title = gtk_object_get_data (GTK_OBJECT (combo), "combo-title"); if (title) gdk_window_set_title (tearoff->window, title); gtk_window_set_policy (GTK_WINDOW (tearoff), FALSE, TRUE, FALSE); gtk_window_set_transient_for (GTK_WINDOW (tearoff), GTK_WINDOW (gtk_widget_get_toplevel GTK_WIDGET (combo))); } if (GTK_WIDGET_VISIBLE (combo->priv->popup)) { gtk_widget_hide (combo->priv->toplevel); gtk_grab_remove (combo->priv->toplevel); gdk_pointer_ungrab (GDK_CURRENT_TIME); } combo_popup_reparent (combo->priv->popup, combo->priv->tearoff_window, FALSE); /* It may have got confused about size */ gtk_widget_queue_resize (GTK_WIDGET (combo->priv->popup)); if (set_position) { combo_box_get_pos (combo, &x, &y); gtk_widget_set_uposition (combo->priv->tearoff_window, x, y); } gtk_widget_show (GTK_WIDGET (combo->priv->popup)); gtk_widget_show (combo->priv->tearoff_window); } /** * combo_set_tearoff_state * @combo_box: Combo box * @torn_off: TRUE: Tear off. FALSE: Pop down and reattach * * Set the tearoff state of the popup * * Compare with gtk_menu_set_tearoff_state in gtk/gtkmenu.c */ static void combo_set_tearoff_state (ComboBox * combo, gboolean torn_off) { g_return_if_fail (combo != NULL); g_return_if_fail (IS_COMBO_BOX (combo)); if (combo->priv->torn_off != torn_off) { combo->priv->torn_off = torn_off; if (combo->priv->torn_off) { combo_popup_tear_off (combo, TRUE); deactivate_arrow (combo); } else { gtk_widget_hide (combo->priv->tearoff_window); combo_popup_reparent (combo->priv->popup, combo->priv->toplevel, FALSE); } } } /** * combo_tearoff_bg_copy * @combo_box: Combo box * * Copy popup window image to the tearoff window. */ static void combo_tearoff_bg_copy (ComboBox * combo) { GdkPixmap *pixmap; GdkGC *gc; GdkGCValues gc_values; GtkWidget *widget = combo->priv->popup; if (combo->priv->torn_off) { gc_values.subwindow_mode = GDK_INCLUDE_INFERIORS; gc = gdk_gc_new_with_values (widget->window, &gc_values, GDK_GC_SUBWINDOW); pixmap = gdk_pixmap_new (widget->window, widget->allocation.width, widget->allocation.height, -1); gdk_draw_pixmap (pixmap, gc, widget->window, 0, 0, 0, 0, -1, -1); gdk_gc_unref (gc); gtk_widget_set_usize (combo->priv->tearoff_window, widget->allocation.width, widget->allocation.height); gdk_window_set_back_pixmap (combo->priv->tearoff_window->window, pixmap, FALSE); gdk_pixmap_unref (pixmap); } } /** * combo_popup_reparent * @popup: Popup * @new_parent: New parent * @unrealize: Unrealize popup if TRUE. * * Reparent the popup, taking care of the refcounting * * Compare with gtk_menu_reparent in gtk/gtkmenu.c */ static void combo_popup_reparent (GtkWidget * popup, GtkWidget * new_parent, gboolean unrealize) { GtkObject *object = GTK_OBJECT (popup); gboolean was_floating = GTK_OBJECT_FLOATING (object); g_object_ref (G_OBJECT (object)); gtk_object_sink (object); if (unrealize) { g_object_ref (G_OBJECT (object)); gtk_container_remove (GTK_CONTAINER (popup->parent), popup); gtk_container_add (GTK_CONTAINER (new_parent), popup); g_object_unref (G_OBJECT (object)); } else gtk_widget_reparent (GTK_WIDGET (popup), new_parent); gtk_widget_set_usize (new_parent, -1, -1); if (was_floating) GTK_OBJECT_SET_FLAGS (object, GTK_FLOATING); else g_object_unref (G_OBJECT (object)); } /** * cb_tearable_button_release * @w: Widget * @event: Event * @combo: Combo box * * Toggle tearoff state. */ static gboolean cb_tearable_button_release (GtkWidget * w, GdkEventButton * event, ComboBox * combo) { GtkTearoffMenuItem *tearable; g_return_val_if_fail (w != NULL, FALSE); g_return_val_if_fail (GTK_IS_TEAROFF_MENU_ITEM (w), FALSE); tearable = GTK_TEAROFF_MENU_ITEM (w); tearable->torn_off = !tearable->torn_off; if (!combo->priv->torn_off) { gboolean need_connect; need_connect = (!combo->priv->tearoff_window); combo_set_tearoff_state (combo, TRUE); if (need_connect) gtk_signal_connect (GTK_OBJECT (combo->priv->tearoff_window), "delete_event", GTK_SIGNAL_FUNC (cb_popup_delete), combo); } else combo_box_popup_hide_unconditional (combo); return TRUE; } static gboolean cb_popup_delete (GtkWidget * w, GdkEventAny * event, ComboBox * combo) { combo_box_popup_hide_unconditional (combo); return TRUE; } void combo_box_construct (ComboBox * combo_box, GtkWidget * display_widget, GtkWidget * pop_down_widget) { GtkWidget *tearable; GtkWidget *vbox; g_return_if_fail (combo_box != NULL); g_return_if_fail (IS_COMBO_BOX (combo_box)); g_return_if_fail (display_widget != NULL); g_return_if_fail (GTK_IS_WIDGET (display_widget)); GTK_BOX (combo_box)->spacing = 0; GTK_BOX (combo_box)->homogeneous = FALSE; combo_box->priv->pop_down_widget = pop_down_widget; combo_box->priv->display_widget = NULL; vbox = gtk_vbox_new (FALSE, 5); tearable = gtk_tearoff_menu_item_new (); gtk_signal_connect (GTK_OBJECT (tearable), "enter-notify-event", GTK_SIGNAL_FUNC (cb_tearable_enter_leave), GINT_TO_POINTER (TRUE)); gtk_signal_connect (GTK_OBJECT (tearable), "leave-notify-event", GTK_SIGNAL_FUNC (cb_tearable_enter_leave), GINT_TO_POINTER (FALSE)); gtk_signal_connect (GTK_OBJECT (tearable), "button-release-event", GTK_SIGNAL_FUNC (cb_tearable_button_release), (gpointer) combo_box); gtk_box_pack_start (GTK_BOX (vbox), tearable, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), pop_down_widget, TRUE, TRUE, 0); combo_box->priv->tearable = tearable; /* * Finish setup */ combo_box_set_display (combo_box, display_widget); gtk_container_add (GTK_CONTAINER (combo_box->priv->frame), vbox); gtk_widget_show_all (combo_box->priv->frame); } GtkWidget * combo_box_new (GtkWidget * display_widget, GtkWidget * optional_popdown) { ComboBox *combo_box; g_return_val_if_fail (display_widget != NULL, NULL); g_return_val_if_fail (GTK_IS_WIDGET (display_widget), NULL); combo_box = gtk_type_new (combo_box_get_type ()); combo_box_construct (combo_box, display_widget, optional_popdown); return GTK_WIDGET (combo_box); } void combo_box_set_arrow_relief (ComboBox * cc, GtkReliefStyle relief) { g_return_if_fail (cc != NULL); g_return_if_fail (IS_COMBO_BOX (cc)); gtk_button_set_relief (GTK_BUTTON (cc->priv->arrow_button), relief); } /** * combo_box_set_title * @combo: Combo box * @title: Title * * Set a title to display over the tearoff window. * * FIXME: * * This should really change the title even when the popup is already torn off. * I guess the tearoff window could attach a listener to title change or * something. But I don't think we need the functionality, so I didn't bother * to investigate. */ void combo_box_set_title (ComboBox * combo, const gchar * title) { g_return_if_fail (combo != NULL); g_return_if_fail (IS_COMBO_BOX (combo)); gtk_object_set_data_full (GTK_OBJECT (combo), "combo-title", g_strdup (title), (GtkDestroyNotify) g_free); } /** * combo_box_set_arrow_sensitive * @combo: Combo box * @sensitive: Sensitivity value * * Toggle the sensitivity of the arrow button */ void combo_box_set_arrow_sensitive (ComboBox * combo, gboolean sensitive) { g_return_if_fail (combo != NULL); gtk_widget_set_sensitive (combo->priv->arrow_button, sensitive); } /** * combo_box_set_tearable: * @combo: Combo box * @tearable: whether to allow the @combo to be tearable * * controls whether the combo box's pop up widget can be torn off. */ void combo_box_set_tearable (ComboBox * combo, gboolean tearable) { g_return_if_fail (combo != NULL); g_return_if_fail (IS_COMBO_BOX (combo)); if (tearable) { gtk_widget_show (combo->priv->tearable); } else { combo_set_tearoff_state (combo, FALSE); gtk_widget_hide (combo->priv->tearable); } } swami/src/swamigui/widgets/icon-combo.h0000644000175000017500000000424007676126120020345 0ustar alessioalessio/* * Ripped and modified for Swami from libgal-0.19.2 * * widget-pixmap-combo.h - A icon selector combo box * Copyright 2000, 2001, Ximian, Inc. * * Authors: * Jody Goldberg * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License, version 2, as published by the Free Software Foundation. * * 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. */ #ifndef __ICON_COMBO_H__ #define __ICON_COMBO_H__ #include #include #include #include #include "combo-box.h" #define ICON_COMBO_TYPE (icon_combo_get_type ()) #define ICON_COMBO(obj) (GTK_CHECK_CAST((obj), ICON_COMBO_TYPE, IconCombo)) #define ICON_COMBO_CLASS(k) (GTK_CHECK_CLASS_CAST(k), ICON_COMBO_TYPE) #define IS_ICON_COMBO(obj) (GTK_CHECK_TYPE((obj), ICON_COMBO_TYPE)) typedef struct { char const *untranslated_tooltip; char *stock_id; /* icon stock ID */ int id; } IconComboElement; typedef struct { ComboBox combo_box; /* Static information */ IconComboElement const *elements; int cols, rows; int num_elements; /* State info */ int last_index; /* Interface elements */ GtkWidget *combo_table, *preview_button; GtkWidget *preview_icon; GtkTooltips *tool_tip; GtkWidget **icons; /* icon widgets */ } IconCombo; GType icon_combo_get_type (void); GtkWidget *icon_combo_new (IconComboElement const *elements, int ncols, int nrows); void icon_combo_select_icon (IconCombo *combo, int id); typedef struct { ComboBoxClass parent_class; /* Signals emited by this widget */ void (* changed) (IconCombo *icon_combo, int id); } IconComboClass; #endif /* __ICON_COMBO_H__ */ swami/src/swamigui/widgets/combo-box.h0000644000175000017500000000530010157753120020175 0ustar alessioalessio/* * Ripped and slightly modified for Swami from libgal-0.19.2 * * gtk-combo-box.h - a customizable combobox * Copyright 2000, 2001, Ximian, Inc. * * Authors: * Miguel de Icaza * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License, version 2, as published by the Free Software Foundation. * * 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. */ #ifndef _COMBO_BOX_H_ #define _COMBO_BOX_H_ #include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define COMBO_BOX_TYPE (combo_box_get_type ()) #define COMBO_BOX(obj) GTK_CHECK_CAST (obj, combo_box_get_type (), ComboBox) #define COMBO_BOX_CLASS(klass) \ GTK_CHECK_CLASS_CAST (klass, combo_box_get_type (), ComboBoxClass) #define IS_COMBO_BOX(obj) GTK_CHECK_TYPE (obj, combo_box_get_type ()) typedef struct _ComboBox ComboBox; typedef struct _ComboBoxPrivate ComboBoxPrivate; typedef struct _ComboBoxClass ComboBoxClass; struct _ComboBox { GtkHBox hbox; ComboBoxPrivate *priv; }; struct _ComboBoxClass { GtkHBoxClass parent_class; GtkWidget *(*pop_down_widget) (ComboBox *cbox); /* * invoked when the popup has been hidden, if the signal * returns TRUE, it means it should be killed from the */ gboolean *(*pop_down_done) (ComboBox *cbox, GtkWidget *); /* * Notification signals. */ void (*pre_pop_down) (ComboBox *cbox); void (*post_pop_hide) (ComboBox *cbox); }; GtkType combo_box_get_type (void); void combo_box_construct (ComboBox *combo_box, GtkWidget *display_widget, GtkWidget *optional_pop_down_widget); void combo_box_get_pos (ComboBox *combo_box, int *x, int *y); GtkWidget *combo_box_new (GtkWidget *display_widget, GtkWidget *optional_pop_down_widget); void combo_box_popup_hide (ComboBox *combo_box); void combo_box_set_display (ComboBox *combo_box, GtkWidget *display_widget); void combo_box_set_title (ComboBox *combo, const gchar *title); void combo_box_set_tearable (ComboBox *combo, gboolean tearable); void combo_box_set_arrow_sensitive (ComboBox *combo, gboolean sensitive); void combo_box_set_arrow_relief (ComboBox *cc, GtkReliefStyle relief); #ifdef __cplusplus }; #endif /* __cplusplus */ #endif /* _COMBO_BOX_H_ */ swami/src/swamigui/SwamiguiPanelSF2Gen.c0000644000175000017500000003363711461334205020363 0ustar alessioalessio/* * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include #include "SwamiguiControl.h" #include "SwamiguiPanelSF2Gen.h" #include "SwamiguiPanel.h" #include "SwamiguiRoot.h" #include "SwamiguiSpinScale.h" #include "icons.h" #include "util.h" #include "i18n.h" /* unit label used when generators are inactive */ #define BLANK_UNIT_LABEL "" /* structure used to keep track of generator widgets */ typedef struct { GtkWidget *button; /* value "set" toggle button */ GtkWidget *spinscale; /* SwamiguiSpinScale widget */ GtkWidget *unitlabel; /* unit label */ } GenWidgets; /* value used for generator property selection type, IPATCH_SF2_GEN_PROPS_INST * and IPATCH_SF2_GEN_PROPS_PRESET values are also used */ #define SEL_NONE -1 /* A separator (column or end) */ #define IS_SEPARATOR(genid) ((genid) >= SWAMIGUI_PANEL_SF2_GEN_COLUMN) /* Is value from SwamiguiPanelSF2GenOp? */ #define IS_OP(genid) ((genid) >= SWAMIGUI_PANEL_SF2_GEN_LABEL) enum { PROP_0, PROP_ITEM_SELECTION }; typedef struct _GenCtrl { SwamiguiPanelSF2Gen *genpanel; /* for GTK callback convenience */ GtkWidget *scale; /* scale widget */ GtkWidget *entry; /* entry widget */ GtkWidget *units; /* units label */ GtkWidget *defbtn; /* default toggle button */ guint16 genid; } GenCtrl; static void swamigui_panel_sf2_gen_panel_iface_init (SwamiguiPanelIface *panel_iface); static gboolean swamigui_sf2_ctrl_panel_iface_check_selection (IpatchList *selection, GType *selection_types); static void swamigui_panel_sf2_gen_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void swamigui_panel_sf2_gen_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void swamigui_panel_sf2_gen_finalize (GObject *object); static gboolean swamigui_panel_sf2_gen_real_set_selection (SwamiguiPanelSF2Gen *genpanel, IpatchList *selection); G_DEFINE_ABSTRACT_TYPE_WITH_CODE (SwamiguiPanelSF2Gen, swamigui_panel_sf2_gen, GTK_TYPE_SCROLLED_WINDOW, G_IMPLEMENT_INTERFACE (SWAMIGUI_TYPE_PANEL, swamigui_panel_sf2_gen_panel_iface_init)); static void swamigui_panel_sf2_gen_class_init (SwamiguiPanelSF2GenClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); obj_class->set_property = swamigui_panel_sf2_gen_set_property; obj_class->get_property = swamigui_panel_sf2_gen_get_property; obj_class->finalize = swamigui_panel_sf2_gen_finalize; g_object_class_override_property (obj_class, PROP_ITEM_SELECTION, "item-selection"); } static void swamigui_panel_sf2_gen_panel_iface_init (SwamiguiPanelIface *panel_iface) { panel_iface->check_selection = swamigui_sf2_ctrl_panel_iface_check_selection; } static gboolean swamigui_sf2_ctrl_panel_iface_check_selection (IpatchList *selection, GType *selection_types) { /* One item only with IpatchSF2GenItem interface */ return (!selection->items->next && g_type_is_a (G_OBJECT_TYPE (selection->items->data), IPATCH_TYPE_SF2_GEN_ITEM)); } static void swamigui_panel_sf2_gen_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { SwamiguiPanelSF2Gen *genpanel = SWAMIGUI_PANEL_SF2_GEN (object); switch (property_id) { case PROP_ITEM_SELECTION: swamigui_panel_sf2_gen_real_set_selection (genpanel, g_value_get_object (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_panel_sf2_gen_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { SwamiguiPanelSF2Gen *genpanel = SWAMIGUI_PANEL_SF2_GEN (object); switch (property_id) { case PROP_ITEM_SELECTION: g_value_set_object (value, genpanel->selection); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_panel_sf2_gen_finalize (GObject *object) { SwamiguiPanelSF2Gen *genpanel = SWAMIGUI_PANEL_SF2_GEN (object); if (genpanel->selection) g_object_unref (genpanel->selection); G_OBJECT_CLASS (swamigui_panel_sf2_gen_parent_class)->finalize (object); } static void swamigui_panel_sf2_gen_init (SwamiguiPanelSF2Gen *genpanel) { genpanel->selection = NULL; genpanel->seltype = SEL_NONE; gtk_scrolled_window_set_hadjustment (GTK_SCROLLED_WINDOW (genpanel), NULL); gtk_scrolled_window_set_vadjustment (GTK_SCROLLED_WINDOW (genpanel), NULL); gtk_container_border_width (GTK_CONTAINER (genpanel), 0); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (genpanel), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); } /** * swamigui_panel_sf2_gen_new: * * Create a new generator control panel object. * * Returns: new widget of type #SwamiguiPanelSF2Gen */ GtkWidget * swamigui_panel_sf2_gen_new (void) { return (GTK_WIDGET (gtk_type_new (swamigui_panel_sf2_gen_get_type ()))); } /** * swamigui_panel_sf2_gen_set_controls: * @genpanel: Generator control panel * @ctrlinfo: Array of control info to configure panel with (should be static) * * Configure a SoundFont generator control panel from an array of control * info. @ctrlinfo array should be terminated with a #SWAMIGUI_PANEL_SF2_GEN_END * genid item. */ void swamigui_panel_sf2_gen_set_controls (SwamiguiPanelSF2Gen *genpanel, SwamiguiPanelSF2GenCtrlInfo *ctrlinfo) { GtkWidget *hbox; GtkWidget *table; GtkWidget *widg; GtkWidget *image; GtkWidget *btn; GtkWidget *frame; GenWidgets *genwidgets; int i, ctrlndx, genid, row; SwamiguiPanelSF2GenCtrlInfo *ctrlp; g_return_if_fail (SWAMIGUI_IS_PANEL_SF2_GEN (genpanel)); g_return_if_fail (ctrlinfo != NULL); g_return_if_fail (genpanel->ctrlinfo == NULL); genpanel->ctrlinfo = ctrlinfo; genpanel->genwidget_count = 0; /* Count controls */ for (ctrlp = ctrlinfo; ctrlp->genid != SWAMIGUI_PANEL_SF2_GEN_END; ctrlp++) if (!IS_OP (ctrlp->genid)) genpanel->genwidget_count++; /* allocate array of gen widget structures */ genwidgets = g_new (GenWidgets, genpanel->genwidget_count); genpanel->genwidgets = genwidgets; hbox = gtk_hbox_new (TRUE, 4); ctrlndx = 0; next_column: frame = gtk_frame_new (NULL); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT); gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0); /* Get number of rows in this column */ for (ctrlp = ctrlinfo, i = 0; !IS_SEPARATOR (ctrlp->genid); ctrlp++, i++); /* Create table for controls */ table = gtk_table_new (i, 5, FALSE); gtk_container_add (GTK_CONTAINER (frame), table); /* loop over controls for this page */ for (ctrlp = ctrlinfo, row = 0; !IS_SEPARATOR (ctrlp->genid); ctrlp++, row++) { genid = ctrlp->genid; if (genid == SWAMIGUI_PANEL_SF2_GEN_LABEL) { widg = gtk_label_new (NULL); gtk_label_set_markup (GTK_LABEL (widg), _(ctrlp->icon)); gtk_table_attach (GTK_TABLE (table), widg, 0, 5, row, row + 1, GTK_EXPAND | GTK_FILL, 0, 0, 0); continue; } /* generator icon */ btn = gtk_toggle_button_new (); genwidgets[ctrlndx].button = btn; image = gtk_image_new_from_stock (ctrlp->icon, GTK_ICON_SIZE_MENU); gtk_button_set_image (GTK_BUTTON (btn), image); gtk_table_attach (GTK_TABLE (table), btn, 0, 1, row, row+1, 0, 0, 0, 0); /* create the control for the icon value set toggle button */ swamigui_control_new_for_widget (G_OBJECT (btn)); /* do this after control creation (since it mucks with it) */ gtk_widget_set_sensitive (btn, FALSE); /* generator label */ widg = gtk_label_new (_(ipatch_sf2_gen_info[genid].label)); gtk_misc_set_alignment (GTK_MISC (widg), 0.0, 0.5); gtk_table_attach (GTK_TABLE (table), widg, 1, 2, row, row+1, GTK_FILL, 0, 2, 0); /* create the horizontal scale and spin button combo widget */ widg = swamigui_spin_scale_new (); genwidgets[ctrlndx].spinscale = widg; swamigui_spin_scale_set_order (SWAMIGUI_SPIN_SCALE (widg), TRUE); gtk_table_attach (GTK_TABLE (table), widg, 2, 3, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0); gtk_entry_set_width_chars (GTK_ENTRY (SWAMIGUI_SPIN_SCALE (widg)->spinbtn), 8); /* create control for scale/spin combo widget */ swamigui_control_new_for_widget (G_OBJECT (widg)); /* do this after control creation (since it mucks with it) */ gtk_widget_set_sensitive (widg, FALSE); /* units label */ widg = gtk_label_new (BLANK_UNIT_LABEL); genwidgets[ctrlndx].unitlabel = widg; gtk_misc_set_alignment (GTK_MISC (widg), 0.0, 0.5); gtk_table_attach (GTK_TABLE (table), widg, 4, 5, row, row+1, GTK_FILL, 0, 2, 0); ctrlndx++; } ctrlinfo = ctrlp + 1; if (ctrlp->genid == SWAMIGUI_PANEL_SF2_GEN_COLUMN) goto next_column; gtk_widget_show_all (hbox); gtk_container_border_width (GTK_CONTAINER (hbox), 4); gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (genpanel), hbox); } /* the real selection set routine */ static gboolean swamigui_panel_sf2_gen_real_set_selection (SwamiguiPanelSF2Gen *genpanel, IpatchList *selection) { IpatchSF2GenItemIface *geniface; IpatchSF2GenArray *genarray; GenWidgets *genwidgets; int seltype = SEL_NONE; SwamiControl *widgctrl, *propctrl; IpatchUnitInfo *unitinfo, *unituser; GObject *item; char *labeltext; int i, genid, unit, ctrlndx; SwamiguiPanelSF2GenCtrlInfo *ctrlp; g_return_val_if_fail (SWAMIGUI_IS_PANEL_SF2_GEN (genpanel), FALSE); g_return_val_if_fail (!selection || IPATCH_IS_LIST (selection), FALSE); /* short circuit if selection is NULL and already is NULL in panel */ if (!genpanel->selection && (!selection || !selection->items)) return (FALSE); /* if selection with only one item and item has SF2 generator interface.. */ if (selection && selection->items && !selection->items->next && IPATCH_IS_SF2_GEN_ITEM (selection->items->data)) { /* get generator property type for item */ geniface = IPATCH_SF2_GEN_ITEM_GET_IFACE (selection->items->data); seltype = geniface->propstype & IPATCH_SF2_GEN_PROPS_MASK; } if (seltype == SEL_NONE) /* force selection to NULL if not valid */ { if (!genpanel->selection) return (FALSE); /* short circuit if already NULL */ selection = NULL; } if (selection == NULL) /* inactive selection? */ { genwidgets = (GenWidgets *)(genpanel->genwidgets); for (i = 0; i < genpanel->genwidget_count; i++, genwidgets++) { widgctrl = swamigui_control_lookup (G_OBJECT (genwidgets->button)); swami_control_disconnect_all (widgctrl); widgctrl = swamigui_control_lookup (G_OBJECT (genwidgets->spinscale)); swami_control_disconnect_all (widgctrl); gtk_widget_set_sensitive (genwidgets->button, FALSE); gtk_widget_set_sensitive (genwidgets->spinscale, FALSE); gtk_label_set_text (GTK_LABEL (genwidgets->unitlabel), BLANK_UNIT_LABEL); } } else /* selection is active */ { item = G_OBJECT (selection->items->data); /* allocate generator array and fill with all gens from item */ genarray = ipatch_sf2_gen_array_new (FALSE); /* ++ alloc */ ipatch_sf2_gen_item_copy_all (IPATCH_SF2_GEN_ITEM (item), genarray); genwidgets = (GenWidgets *)(genpanel->genwidgets); ctrlndx = 0; for (ctrlp = genpanel->ctrlinfo; ctrlp->genid != SWAMIGUI_PANEL_SF2_GEN_END; ctrlp++) { if (IS_OP (ctrlp->genid)) continue; genid = ctrlp->genid; widgctrl = swamigui_control_lookup (G_OBJECT (genwidgets->button)); swami_control_disconnect_all (widgctrl); propctrl = swami_get_control_prop (item, geniface->setspecs[genid]); swami_control_connect (propctrl, widgctrl, SWAMI_CONTROL_CONN_BIDIR | SWAMI_CONTROL_CONN_INIT); widgctrl = swamigui_control_lookup (G_OBJECT (genwidgets->spinscale)); swami_control_disconnect_all (widgctrl); swami_control_connect_item_prop (widgctrl, item, geniface->specs[genid]); gtk_widget_set_sensitive (genwidgets->button, TRUE); gtk_widget_set_sensitive (genwidgets->spinscale, TRUE); unit = ipatch_sf2_gen_info[genid].unit; /* ABS time and ABS pitch use OFS time and OFS pitch units in preset zones */ if (seltype == IPATCH_SF2_GEN_PROPS_PRESET) { if (unit == IPATCH_UNIT_TYPE_SF2_ABS_PITCH) unit = IPATCH_UNIT_TYPE_SF2_OFS_PITCH; else if (unit == IPATCH_UNIT_TYPE_SF2_ABS_TIME) unit = IPATCH_UNIT_TYPE_SF2_OFS_TIME; } unitinfo = ipatch_unit_lookup (unit); if (unitinfo) { unituser = ipatch_unit_class_lookup_map (IPATCH_UNIT_CLASS_USER, unitinfo->id); labeltext = unituser ? unituser->label : unitinfo->label; gtk_label_set_text (GTK_LABEL (genwidgets->unitlabel), labeltext); } ctrlndx++; genwidgets++; } } if (genpanel->selection) g_object_unref (genpanel->selection); if (selection) genpanel->selection = (IpatchList *)ipatch_list_duplicate (selection); else genpanel->selection = NULL; genpanel->seltype = seltype; return (TRUE); } swami/src/swamigui/util.h0000644000175000017500000000467411461334205015632 0ustar alessioalessio/* * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_UTIL_H__ #define __SWAMIGUI_UTIL_H__ #include #include #include /* size in bytes of buffers used for converting audio formats */ #define SWAMIGUI_SAMPLE_TRANSFORM_SIZE (64 * 1024) typedef void (*UtilQuickFunc) (gpointer userdata, GtkWidget *popup); /** A guint RGBA color unit type for GParamSpec "unit-type" IpatchParamProp */ #define SWAMIGUI_UNIT_RGBA_COLOR swamigui_util_unit_rgba_color_get_type() void swamigui_util_init (void); guint swamigui_util_unit_rgba_color_get_type (void); void swamigui_util_canvas_line_set (GnomeCanvasItem *item, double x1, double y1, double x2, double y2); GtkWidget *swamigui_util_quick_popup (gchar * msg, gchar * btn1, ...); GtkWidget *swamigui_util_lookup_unique_dialog (gchar *strkey, gint key2); gboolean swamigui_util_register_unique_dialog (GtkWidget *dialog, gchar *strkey, gint key2); void swamigui_util_unregister_unique_dialog (GtkWidget *dialog); gboolean swamigui_util_activate_unique_dialog (gchar *strkey, gint key2); gpointer swamigui_util_waitfor_widget_action (GtkWidget *widg); void swamigui_util_widget_action (GtkWidget *cbwidg, gpointer value); GtkWidget *swamigui_util_glade_create (const char *name); GtkWidget *swamigui_util_glade_lookup (GtkWidget *widget, const char *name); GtkWidget *swamigui_util_glade_lookup_nowarn (GtkWidget *widget, const char *name); int swamigui_util_option_menu_index (GtkWidget *opmenu); // void log_view (gchar * title); char *swamigui_util_str_crlf2lf (char *str); char *swamigui_util_str_lf2crlf (char *str); int swamigui_util_substrcmp (char *sub, char *str); #endif swami/src/swamigui/swami_python.h0000644000175000017500000000232411461334205017364 0ustar alessioalessio/* * swami_python.h - Header file for Python interpreter functions * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_SWAMI_PYTHON_H__ #define __SWAMIGUI_SWAMI_PYTHON_H__ #include typedef void (*SwamiguiPythonOutputFunc)(const char *output, gboolean is_stderr); void swamigui_python_set_output_func (SwamiguiPythonOutputFunc func); void swamigui_python_set_root (void); gboolean swamigui_python_is_initialized (void); #endif swami/src/swamigui/SwamiguiSpinScale.h0000644000175000017500000000412711461334205020235 0ustar alessioalessio/* * SwamiguiSpinScale.h - A GtkSpinButton/GtkScale combo widget * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_SPIN_SCALE_H__ #define __SWAMIGUI_SPIN_SCALE_H__ #include typedef struct _SwamiguiSpinScale SwamiguiSpinScale; typedef struct _SwamiguiSpinScaleClass SwamiguiSpinScaleClass; #define SWAMIGUI_TYPE_SPIN_SCALE (swamigui_spin_scale_get_type ()) #define SWAMIGUI_SPIN_SCALE(obj) \ (GTK_CHECK_CAST ((obj), SWAMIGUI_TYPE_SPIN_SCALE, SwamiguiSpinScale)) #define SWAMIGUI_SPIN_SCALE_CLASS(klass) \ (GTK_CHECK_CLASS_CAST ((klass), SWAMIGUI_TYPE_SPIN_SCALE, \ SwamiguiSpinScaleClass)) #define SWAMIGUI_IS_SPIN_SCALE(obj) \ (GTK_CHECK_TYPE ((obj), SWAMIGUI_TYPE_SPIN_SCALE)) #define SWAMIGUI_IS_SPIN_SCALE_CLASS(klass) \ (GTK_CHECK_CLASS_TYPE ((klass), SWAMIGUI_TYPE_SPIN_SCALE)) /* Swami SpinScale widget */ struct _SwamiguiSpinScale { GtkHBox parent; GtkWidget *spinbtn; /* spin button widget */ GtkWidget *hscale; /* horizontal scale widget */ gboolean scale_first; /* indicates order of widgets */ }; /* Swami SpinScale widget class */ struct _SwamiguiSpinScaleClass { GtkHBoxClass parent_class; }; GType swamigui_spin_scale_get_type (void); GtkWidget *swamigui_spin_scale_new (void); void swamigui_spin_scale_set_order (SwamiguiSpinScale *spin_scale, gboolean scale_first); #endif swami/src/swamigui/swami_python.c0000644000175000017500000001001311461334205017351 0ustar alessioalessio/* * python.c - Python interpreter functions * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include "swami_python.h" static void default_redir_func (const char *output, gboolean is_stderr); static SwamiguiPythonOutputFunc output_func = default_redir_func; static PyObject * redir_stdout (PyObject *self, PyObject *args) { char *s; if (!PyArg_ParseTuple(args, "s", &s)) return 0; if (output_func) output_func (s, FALSE); return Py_BuildValue(""); } static PyObject * redir_stderr (PyObject *self, PyObject *args) { char *s; if (!PyArg_ParseTuple(args, "s", &s)) return 0; if (output_func) output_func (s, TRUE); return Py_BuildValue(""); } // Define methods available to Python static PyMethodDef ioMethods[] = { {"redir_stdout", redir_stdout, METH_VARARGS, "redir_stdout"}, {"redir_stderr", redir_stderr, METH_VARARGS, "redir_stderr"}, {NULL, NULL, 0, NULL} }; static gboolean python_is_initialized = FALSE; /* * Initialize python for use with Swami. Sets up python output redirection. * Usually called once and only once by swamigui_init(). */ void _swamigui_python_init (int argc, char **argv) { PyObject* swami_main_module; char *new_argv[argc]; int i; char *init_code = "class Sout:\n" " def write(self, s):\n" " swami_redirect.redir_stdout(s)\n" "\n" "class Eout:\n" " def write(self, s):\n" " swami_redirect.redir_stderr(s)\n" "\n" "import sys\n" "import swami_redirect\n" "sys.stdout = Sout()\n" "sys.stderr = Eout()\n" "sys.stdin = None\n"; if (python_is_initialized) return; Py_Initialize (); for (i = 1; i < argc; i++) new_argv[i] = argv[i]; new_argv[0] = ""; /* set "script name" to empty string */ PySys_SetArgv (argc, new_argv); swami_main_module = Py_InitModule("swami_redirect", ioMethods); if (PyRun_SimpleString (init_code) != 0) g_critical ("Failed to redirect Python output"); if (PyRun_SimpleString ("import ipatch, swami, swamigui\n") != 0) g_critical ("Failed to 'import ipatch, swami, swamigui' modules"); python_is_initialized = TRUE; } /** * swamigui_python_set_output_func: * @func: Python output callback function or %NULL to use default (no * redirection) * * Set the Python output callback function which gets called for any * output to stdout or stderr from the Python interpreter. */ void swamigui_python_set_output_func (SwamiguiPythonOutputFunc func) { output_func = func ? func : default_redir_func; } /* a default redirection function, which doesn't redirect at all :) */ static void default_redir_func (const char *output, gboolean is_stderr) { fputs (output, is_stderr ? stderr : stdout); } /** * swamigui_python_set_root: * * Runs a bit of Python code to set the swamigui.root variable to the global * swamigui_root object. */ void swamigui_python_set_root (void) { if (PyRun_SimpleString ("swamigui.root = swamigui.swamigui_get_root()\n") != 0) g_critical ("Failed to assign swamigui.root object"); } /** * swamigui_python_is_initialized: * * Check if Python sub system is initialized and ready for action. * * Returns: TRUE if initialized, FALSE otherwise */ gboolean swamigui_python_is_initialized (void) { return python_is_initialized; } swami/src/swamigui/SwamiguiStatusbar.h0000644000175000017500000000760211461334205020325 0ustar alessioalessio/* * SwamiguiStatusbar.h - A statusbar (multiple labels/progresses) * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_STATUSBAR_H__ #define __SWAMIGUI_STATUSBAR_H__ /* max chars for "Global" group status label item */ #define SWAMIGUI_STATUSBAR_GLOBAL_MAXLEN 24 #include typedef struct _SwamiguiStatusbar SwamiguiStatusbar; typedef struct _SwamiguiStatusbarClass SwamiguiStatusbarClass; #define SWAMIGUI_TYPE_STATUSBAR (swamigui_statusbar_get_type ()) #define SWAMIGUI_STATUSBAR(obj) \ (GTK_CHECK_CAST ((obj), SWAMIGUI_TYPE_STATUSBAR, SwamiguiStatusbar)) #define SWAMIGUI_STATUSBAR_CLASS(klass) \ (GTK_CHECK_CLASS_CAST ((klass), SWAMIGUI_TYPE_STATUSBAR, \ SwamiguiStatusbarClass)) #define SWAMIGUI_IS_STATUSBAR(obj) \ (GTK_CHECK_TYPE ((obj), SWAMIGUI_TYPE_STATUSBAR)) #define SWAMIGUI_IS_STATUSBAR_CLASS(klass) \ (GTK_CHECK_CLASS_TYPE ((klass), SWAMIGUI_TYPE_STATUSBAR)) /* Statusbar widget */ struct _SwamiguiStatusbar { GtkFrame parent; /*< private >*/ GtkWidget *box; /* the hbox within the statusbar frame */ GList *items; /* active items (see StatusItem in .c) */ guint id_counter; /* unique status item ID counter */ int default_timeout; /* default timeout value in msecs */ }; /* Statusbar widget class */ struct _SwamiguiStatusbarClass { GtkFrameClass parent_class; }; /** * SwamiguiStatusbarCloseFunc: * @statusbar: The status bar widget * @widg: The message widget * * Callback function prototype which gets called when a close button on a * progress status bar item gets activated. * * Returns: Should return %TRUE to remove the item from the status bar, %FALSE * to keep it (useful if a confirmation dialog is popped for the user, etc). */ typedef gboolean (*SwamiguiStatusbarCloseFunc)(SwamiguiStatusbar *statusbar, GtkWidget *widg); typedef enum { SWAMIGUI_STATUSBAR_POS_LEFT, SWAMIGUI_STATUSBAR_POS_RIGHT } SwamiguiStatusbarPos; /* some special timeout values for statusbar messages */ typedef enum { SWAMIGUI_STATUSBAR_TIMEOUT_DEFAULT = -1, /* uses "default-timeout" property */ SWAMIGUI_STATUSBAR_TIMEOUT_FOREVER = 0 /* don't timeout */ } SwamiguiStatusbarTimeout; GType swamigui_statusbar_get_type (void); GtkWidget *swamigui_statusbar_new (void); guint swamigui_statusbar_add (SwamiguiStatusbar *statusbar, const char *group, int timeout, guint pos, GtkWidget *widg); void swamigui_statusbar_remove (SwamiguiStatusbar *statusbar, guint id, const char *group); void swamigui_statusbar_printf (SwamiguiStatusbar *statusbar, const char *format, ...) G_GNUC_PRINTF (2, 3); GtkWidget *swamigui_statusbar_msg_label_new (const char *label, guint maxlen); GtkWidget *swamigui_statusbar_msg_progress_new (const char *label, SwamiguiStatusbarCloseFunc close); void swamigui_statusbar_msg_set_timeout (SwamiguiStatusbar *statusbar, guint id, const char *group, int timeout); void swamigui_statusbar_msg_set_label (SwamiguiStatusbar *statusbar, guint id, const char *group, const char *label); void swamigui_statusbar_msg_set_progress (SwamiguiStatusbar *statusbar, guint id, const char *group, double val); #endif swami/src/swamigui/SwamiguiTreeStorePatch.h0000644000175000017500000000442111461334205021245 0ustar alessioalessio/* * SwamiguiTreeStorePatch.h - Patch tree store (for instruments). * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_TREE_STORE_PATCH_H__ #define __SWAMIGUI_TREE_STORE_PATCH_H__ typedef struct _SwamiguiTreeStorePatch SwamiguiTreeStorePatch; typedef struct _SwamiguiTreeStorePatchClass SwamiguiTreeStorePatchClass; #include #define SWAMIGUI_TYPE_TREE_STORE_PATCH (swamigui_tree_store_patch_get_type ()) #define SWAMIGUI_TREE_STORE_PATCH(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMIGUI_TYPE_TREE_STORE_PATCH, \ SwamiguiTreeStorePatch)) #define SWAMIGUI_TREE_STORE_PATCH_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMIGUI_TYPE_TREE_STORE_PATCH, \ SwamiguiTreeStorePatchClass)) #define SWAMIGUI_IS_TREE_STORE_PATCH(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMIGUI_TYPE_TREE_STORE_PATCH)) #define SWAMIGUI_IS_TREE_STORE_PATCH_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMIGUI_TYPE_TREE_STORE_PATCH)) /* Patch tree store object */ struct _SwamiguiTreeStorePatch { SwamiguiTreeStore parent_instance; /* derived from SwamiguiTreeStore */ }; /* Patch tree store class */ struct _SwamiguiTreeStorePatchClass { SwamiguiTreeStoreClass parent_class; }; GType swamigui_tree_store_patch_get_type (void); SwamiguiTreeStorePatch *swamigui_tree_store_patch_new (void); void swamigui_tree_store_patch_item_add (SwamiguiTreeStore *store, GObject *item); void swamigui_tree_store_patch_item_changed (SwamiguiTreeStore *store, GObject *item); #endif swami/src/swamigui/SwamiguiPanelSF2GenMisc.c0000644000175000017500000000657011461334205021173 0ustar alessioalessio/* * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include "SwamiguiPanelSF2GenMisc.h" #include "SwamiguiPanel.h" #include "icons.h" #include "util.h" #include "i18n.h" SwamiguiPanelSF2GenCtrlInfo sf2_gen_misc_ctrl_info[] = { { SWAMIGUI_PANEL_SF2_GEN_LABEL, N_("Pitch") }, { IPATCH_SF2_GEN_COARSE_TUNE, GTK_STOCK_CONNECT }, { IPATCH_SF2_GEN_FINE_TUNE_OVERRIDE, GTK_STOCK_CONNECT }, { IPATCH_SF2_GEN_SCALE_TUNE, GTK_STOCK_CONNECT }, { SWAMIGUI_PANEL_SF2_GEN_LABEL, N_("Effects") }, { IPATCH_SF2_GEN_FILTER_Q, GTK_STOCK_CONNECT }, { IPATCH_SF2_GEN_FILTER_CUTOFF, GTK_STOCK_CONNECT }, { IPATCH_SF2_GEN_REVERB, GTK_STOCK_CONNECT }, { IPATCH_SF2_GEN_CHORUS, GTK_STOCK_CONNECT }, { IPATCH_SF2_GEN_PAN, GTK_STOCK_CONNECT }, { SWAMIGUI_PANEL_SF2_GEN_COLUMN, NULL }, { SWAMIGUI_PANEL_SF2_GEN_LABEL, N_("Modulation LFO") }, { IPATCH_SF2_GEN_MOD_LFO_DELAY, GTK_STOCK_CONNECT }, { IPATCH_SF2_GEN_MOD_LFO_FREQ, GTK_STOCK_CONNECT }, { IPATCH_SF2_GEN_MOD_LFO_TO_PITCH, GTK_STOCK_CONNECT }, { IPATCH_SF2_GEN_MOD_LFO_TO_FILTER_CUTOFF, GTK_STOCK_CONNECT }, { IPATCH_SF2_GEN_MOD_LFO_TO_VOLUME, GTK_STOCK_CONNECT }, { SWAMIGUI_PANEL_SF2_GEN_LABEL, N_("Vibrato LFO") }, { IPATCH_SF2_GEN_VIB_LFO_DELAY, GTK_STOCK_CONNECT }, { IPATCH_SF2_GEN_VIB_LFO_FREQ, GTK_STOCK_CONNECT }, { IPATCH_SF2_GEN_VIB_LFO_TO_PITCH, GTK_STOCK_CONNECT }, { SWAMIGUI_PANEL_SF2_GEN_END, NULL } }; static void swamigui_panel_sf2_gen_misc_panel_iface_init (SwamiguiPanelIface *panel_iface); G_DEFINE_TYPE_WITH_CODE (SwamiguiPanelSF2GenMisc, swamigui_panel_sf2_gen_misc, SWAMIGUI_TYPE_PANEL_SF2_GEN, G_IMPLEMENT_INTERFACE (SWAMIGUI_TYPE_PANEL, swamigui_panel_sf2_gen_misc_panel_iface_init)); static void swamigui_panel_sf2_gen_misc_class_init (SwamiguiPanelSF2GenMiscClass *klass) { } static void swamigui_panel_sf2_gen_misc_panel_iface_init (SwamiguiPanelIface *panel_iface) { panel_iface->label = _("Misc. Controls"); panel_iface->blurb = _("Tuning, effects and oscillator controls"); panel_iface->stockid = SWAMIGUI_STOCK_EFFECT_CONTROL; } static void swamigui_panel_sf2_gen_misc_init (SwamiguiPanelSF2GenMisc *genpanel) { swamigui_panel_sf2_gen_set_controls (SWAMIGUI_PANEL_SF2_GEN (genpanel), sf2_gen_misc_ctrl_info); } /** * swamigui_panel_sf2_gen_misc_new: * * Create a new generator control panel object. * * Returns: new widget of type #SwamiguiPanelSF2GenMisc */ GtkWidget * swamigui_panel_sf2_gen_misc_new (void) { return (GTK_WIDGET (gtk_type_new (swamigui_panel_sf2_gen_misc_get_type ()))); } swami/src/swamigui/SwamiguiBar.c0000644000175000017500000003323211704446464017065 0ustar alessioalessio/** * SECTION:SwamiguiBar * @short_description: Canvas item for displaying multiple pointers or ranges. * @see_also: #SwamiguiBarPtr * * Horizontal bar canvas item for displaying multiple pointers and/or ranges. * A #SwamiguiBar is composed of one or more #SwamiguiBarPtr items. */ /* * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include "libswami/swami_priv.h" #include "SwamiguiBar.h" #include "i18n.h" enum { PROP_0, PROP_MIN_HEIGHT, /* min height of pointers (top of stack) */ PROP_MAX_HEIGHT /* max height of pointers (bottom of stack) */ }; /* structure which defines an interface pointer */ typedef struct { char *id; /* id of this item */ GnomeCanvasItem *barptr; /* pointer canvas item */ SwamiguiBar *bar; /* parent bar object */ gboolean mouse_sel; /* TRUE if mouse selection is in progress */ } PtrInfo; static void swamigui_bar_class_init (SwamiguiBarClass *klass); static void swamigui_bar_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void swamigui_bar_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void swamigui_bar_init (SwamiguiBar *bar); static void swamigui_bar_finalize (GObject *object); static gboolean swamigui_bar_cb_ptr_event (GnomeCanvasItem *item, GdkEvent *event, gpointer data); static void swamigui_bar_update_ptr_heights (SwamiguiBar *bar); static GObjectClass *parent_class = NULL; GType swamigui_bar_get_type (void) { static GType obj_type = 0; if (!obj_type) { static const GTypeInfo obj_info = { sizeof (SwamiguiBarClass), NULL, NULL, (GClassInitFunc) swamigui_bar_class_init, NULL, NULL, sizeof (SwamiguiBar), 0, (GInstanceInitFunc) swamigui_bar_init, }; obj_type = g_type_register_static (GNOME_TYPE_CANVAS_GROUP, "SwamiguiBar", &obj_info, 0); } return (obj_type); } static void swamigui_bar_class_init (SwamiguiBarClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); parent_class = g_type_class_peek_parent (klass); obj_class->set_property = swamigui_bar_set_property; obj_class->get_property = swamigui_bar_get_property; obj_class->finalize = swamigui_bar_finalize; g_object_class_install_property (obj_class, PROP_MIN_HEIGHT, g_param_spec_int ("min-height", _("Min height"), _("Minimum height of pointers"), 1, G_MAXINT, 16, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_MAX_HEIGHT, g_param_spec_int ("max-height", _("Max height"), _("Maximum height of pointers"), 1, G_MAXINT, 48, G_PARAM_READWRITE)); } static void swamigui_bar_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { SwamiguiBar *bar = SWAMIGUI_BAR (object); switch (property_id) { case PROP_MIN_HEIGHT: bar->min_height = g_value_get_int (value); swamigui_bar_update_ptr_heights (bar); break; case PROP_MAX_HEIGHT: bar->max_height = g_value_get_int (value); swamigui_bar_update_ptr_heights (bar); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_bar_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { SwamiguiBar *bar = SWAMIGUI_BAR (object); switch (property_id) { case PROP_MIN_HEIGHT: g_value_set_int (value, bar->min_height); break; case PROP_MAX_HEIGHT: g_value_set_int (value, bar->max_height); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_bar_init (SwamiguiBar *bar) { bar->min_height = 16; bar->max_height = 48; bar->ptrlist = NULL; } static void swamigui_bar_finalize (GObject *object) { SwamiguiBar *bar = SWAMIGUI_BAR (object); PtrInfo *info; GList *p; for (p = bar->ptrlist; p; p = g_list_delete_link (p, p)) { info = (PtrInfo *)(p->data); g_free (info->id); g_free (p->data); } if (G_OBJECT_CLASS (parent_class)->finalize) (* G_OBJECT_CLASS (parent_class)->finalize)(object); } /* callback for SwamiguiBarPtr events */ static gboolean swamigui_bar_cb_ptr_event (GnomeCanvasItem *item, GdkEvent *event, gpointer data) { PtrInfo *ptrinfo = (PtrInfo *)data; SwamiguiBar *bar = SWAMIGUI_BAR (ptrinfo->bar); GdkEventButton *bevent; switch (event->type) { case GDK_BUTTON_PRESS: bevent = (GdkEventButton *)event; if (bevent->button != 1) break; ptrinfo->mouse_sel = TRUE; /* make sure the item is raised to the top */ swamigui_bar_raise_pointer_to_top (bar, ptrinfo->id); gnome_canvas_item_grab (item, GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, NULL, bevent->time); return (TRUE); case GDK_BUTTON_RELEASE: if (!ptrinfo->mouse_sel) break; /* not selected? */ ptrinfo->mouse_sel = FALSE; gnome_canvas_item_ungrab (item, event->button.time); break; case GDK_MOTION_NOTIFY: if (!ptrinfo->mouse_sel) break; /* not selected? */ break; default: break; } return (FALSE); } /* update heights of all pointers based on current stacking order */ static void swamigui_bar_update_ptr_heights (SwamiguiBar *bar) { PtrInfo *info; int count, height_diff, min_height, max_height; double xform[6]; GList *p; int height; int i; count = g_list_length (bar->ptrlist); if (count == 0) return; /* just in case they are swapped */ min_height = MIN (bar->min_height, bar->max_height); max_height = MAX (bar->min_height, bar->max_height); height_diff = max_height - min_height; /* set height and y-position of pointers */ for (i = 0, p = bar->ptrlist; i < count; i++, p = p->next) { info = (PtrInfo *)(p->data); /* set the height of the pointer between min-height and max-height */ if (count != 1) height = min_height + (height_diff * i) / (count - 1); else height = max_height; g_object_set (info->barptr, "height", height, NULL); /* set the y pos of pointer so they line up on the bottom */ gnome_canvas_item_i2w_affine (info->barptr, xform); xform[5] = max_height - height; gnome_canvas_item_affine_absolute (info->barptr, xform); } } /** * swamigui_bar_create_pointer: * @bar: Bar canvas item * @id: String identifier to use for this pointer * @first_property_name: Name of first #SwamiguiBarPtr property to assign to or * %NULL to not set any pointer properties. * @...: First value to assign to @first_property_name followed by additional * name/value pairs, terminated with a %NULL name argument. * * Creates a new #SwamiguiBarPtr, sets properties and adds it to a bar canvas * item. */ void swamigui_bar_create_pointer (SwamiguiBar *bar, const char *id, const char *first_property_name, ...) { SwamiguiBarPtr *barptr; va_list args; g_return_if_fail (SWAMIGUI_IS_BAR (bar)); g_return_if_fail (id != NULL); barptr = g_object_new (SWAMIGUI_TYPE_BAR_PTR, NULL); va_start (args, first_property_name); g_object_set_valist (G_OBJECT (barptr), first_property_name, args); va_end (args); swamigui_bar_add_pointer (bar, barptr, id); } /** * swamigui_bar_add_pointer: * @bar: Bar canvas item * @barptr: Existing bar pointer to add to bar canvas item. * @id: String identifier to use for this pointer * * Add an existing bar pointer to a bar canvas item. */ void swamigui_bar_add_pointer (SwamiguiBar *bar, SwamiguiBarPtr *barptr, const char *id) { PtrInfo *info; g_return_if_fail (SWAMIGUI_IS_BAR (bar)); g_return_if_fail (SWAMIGUI_IS_BAR_PTR (barptr)); g_return_if_fail (id != NULL); info = g_slice_new (PtrInfo); info->id = g_strdup (id); info->barptr = GNOME_CANVAS_ITEM (barptr); info->bar = bar; info->mouse_sel = FALSE; bar->ptrlist = g_list_append (bar->ptrlist, info); gnome_canvas_item_reparent (GNOME_CANVAS_ITEM (barptr), GNOME_CANVAS_GROUP (bar)); gnome_canvas_item_lower_to_bottom (GNOME_CANVAS_ITEM (barptr)); g_signal_connect (G_OBJECT (barptr), "event", G_CALLBACK (swamigui_bar_cb_ptr_event), info); swamigui_bar_update_ptr_heights (bar); } /** * @bar: Bar canvas item * @id: String identifier of pointer to find * * Get a bar pointer object in a bar canvas item identified by its string ID. * * Returns: The bar pointer object with the given string @id or %NULL if not * found. */ GnomeCanvasItem * swamigui_bar_get_pointer (SwamiguiBar *bar, const char *id) { PtrInfo *info; GList *p; g_return_val_if_fail (SWAMIGUI_IS_BAR (bar), NULL); g_return_val_if_fail (id != NULL, NULL); for (p = bar->ptrlist; p; p = p->next) { info = (PtrInfo *)(p->data); if (strcmp (info->id, id) == 0) break; } return (p ? info->barptr : NULL); } /** * swamigui_bar_set_pointer_position: * @bar: Bar canvas item * @id: String identifier of pointer to set position of * @position: Position in pixels to set pointer to * * Set the position of a #SwamiguiBarPtr item in a bar canvas item. Pointer * is centered on the given @position regardless of mode (position or range). */ void swamigui_bar_set_pointer_position (SwamiguiBar *bar, const char *id, int position) { GnomeCanvasItem *barptr; double xform[6]; int width; barptr = swamigui_bar_get_pointer (bar, id); g_return_if_fail (barptr != NULL); g_object_get (barptr, "width", &width, NULL); position -= width / 2; gnome_canvas_item_i2w_affine (barptr, xform); xform[4] = position; gnome_canvas_item_affine_absolute (barptr, xform); } /** * swamigui_bar_set_pointer_range: * @bar: Bar canvas item * @id: String identifier of pointer to set position of * @start: Position in pixels of start of range * @end: Position in pixels of end of range * * Set the range of a #SwamiguiBarPtr item in a bar canvas item. Pointer is * set to the range defined by @start and @end. */ void swamigui_bar_set_pointer_range (SwamiguiBar *bar, const char *id, int start, int end) { GnomeCanvasItem *barptr; double xform[6]; int temp; barptr = swamigui_bar_get_pointer (bar, id); g_return_if_fail (barptr != NULL); if (start > end) /* swap if backwards */ { temp = start; start = end; end = temp; } g_object_set (barptr, "width", end - start + 1, NULL); gnome_canvas_item_i2w_affine (barptr, xform); xform[4] = start; gnome_canvas_item_affine_absolute (barptr, xform); } /** * swamigui_bar_get_pointer_order: * @bar: Bar canvas item * @id: String identifier of pointer to get stacking order position of * * Get the stacking order of a pointer. * * Returns: Stacking order of pointer (0 = top, -1 if pointer not found). */ int swamigui_bar_get_pointer_order (SwamiguiBar *bar, const char *id) { PtrInfo *info; GList *p; int i; g_return_val_if_fail (SWAMIGUI_IS_BAR (bar), -1); g_return_val_if_fail (id != NULL, -1); for (p = bar->ptrlist, i = 0; p; p = p->next, i++) { info = (PtrInfo *)(p->data); if (strcmp (info->id, id) == 0) break; } return (p ? i : -1); } /** * swamigui_bar_set_pointer_order: * @bar: Bar canvas item * @id: String identifier of pointer to set stacking order position of * @pos: Absolute position in stacking order (0 = top, -1 = bottom) * * Set the stacking order of a pointer to @pos. */ void swamigui_bar_set_pointer_order (SwamiguiBar *bar, const char *id, int pos) { PtrInfo *info; GList *p; int i; g_return_if_fail (SWAMIGUI_IS_BAR (bar)); g_return_if_fail (id != NULL); for (p = bar->ptrlist, i = 0; p; p = p->next, i++) { info = (PtrInfo *)(p->data); if (strcmp (info->id, id) == 0) break; } g_return_if_fail (p != NULL); /* already at the requested position? */ if (pos == i || (pos == -1 && !p->next)) return; /* re-order the element */ bar->ptrlist = g_list_delete_link (bar->ptrlist, p); bar->ptrlist = g_list_insert (bar->ptrlist, info, pos); /* set the stacking order of the canvas item */ if (pos != -1) { /* raise to top and then lower to the given position */ gnome_canvas_item_raise_to_top (info->barptr); gnome_canvas_item_lower (info->barptr, pos); } else gnome_canvas_item_lower_to_bottom (info->barptr); swamigui_bar_update_ptr_heights (bar); /* update the pointer heights */ } /** * swamigui_bar_raise_pointer_to_top: * @bar: Bar canvas item * @id: String identifier of pointer to raise to top of stacking order * * Raise a pointer to the top of the stacking order. */ void swamigui_bar_raise_pointer_to_top (SwamiguiBar *bar, const char *id) { swamigui_bar_set_pointer_order (bar, id, 0); } /** * swamigui_bar_lower_pointer_to_bottom: * @bar: Bar canvas item * @id: String identifier of pointer to lower to bottom of stacking order * * Lower a pointer to the bottom of the stacking order. */ void swamigui_bar_lower_pointer_to_bottom (SwamiguiBar *bar, const char *id) { swamigui_bar_set_pointer_order (bar, id, -1); } swami/src/swamigui/SwamiguiProp.c0000644000175000017500000002524511461334205017273 0ustar alessioalessio/* * SwamiguiProp.c - GObject property GUI control object * For creating user interfaces for controlling GObject properties. * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include "config.h" #include #include #include #include #include "SwamiguiControl.h" #include "SwamiguiRoot.h" #include "SwamiguiProp.h" #include "SwamiguiPanel.h" #include "i18n.h" #include "util.h" enum { PROP_0, PROP_ITEM_SELECTION }; /* Hash value used for prop_registry */ typedef struct { char *widg_name; /* name of Glade widget or NULL if handler set */ SwamiguiPropHandler handler; /* handler function or NULL if widg_name set */ } PropInfo; /* Local Prototypes */ static PropInfo *prop_info_new (void); static void prop_info_free (gpointer data); static void swamigui_prop_class_init (SwamiguiPropClass *klass); static void swamigui_prop_panel_iface_init (SwamiguiPanelIface *panel_iface); static gboolean swamigui_prop_panel_iface_check_selection (IpatchList *selection, GType *selection_types); static void swamigui_prop_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void swamigui_prop_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void swamigui_prop_finalize (GObject *object); static void swamigui_prop_init (SwamiguiProp *prop); static gboolean swamigui_prop_real_set_selection (SwamiguiProp *prop, IpatchList *selection); static GObjectClass *parent_class = NULL; /* Property type registry hash (GType -> PropInfo) */ static GHashTable *prop_registry = NULL; /* function for creating a PropInfo structure */ static PropInfo * prop_info_new (void) { return (g_slice_new0 (PropInfo)); } /* function for freeing a PropInfo structure */ static void prop_info_free (gpointer data) { PropInfo *info = (PropInfo *)data; g_return_if_fail (data != NULL); g_free (info->widg_name); g_slice_free (PropInfo, data); } /** * swamigui_register_prop_glade_widg: * @objtype: Type of object which the interface will control * @name: Name of a Glade widget in the Swami Glade file * * Registers a Swami Glade widget as an interface control for a given @objtype. * The Glade widget should contain child widgets of the form "PROP::" * which will cause the given widget to control the property "" of * objects of the given type. Use swamigui_prop_register_handler() instead if * additional customization is needed to create an interface. */ void swamigui_register_prop_glade_widg (GType objtype, const char *name) { PropInfo *info; g_return_if_fail (objtype != 0); g_return_if_fail (name != NULL); info = prop_info_new (); info->widg_name = g_strdup (name); g_hash_table_insert (prop_registry, (gpointer)objtype, info); } /** * swamigui_register_prop_glade_widg: * @objtype: Type of object which the interface will control * @handler: Handler function to create the interface * * Registers a handler function to create an interface control for a given * @objtype. The handler should create a widget (if its widg parameter is * %NULL), or use previously created widget, and connect its controls to the * properties of the passed in object. Use swamigui_prop_register_glade_widg() * instead if no special customization is needed beyond simply connecting * widgets to an object's properties. */ void swamigui_register_prop_handler (GType objtype, SwamiguiPropHandler handler) { PropInfo *info; g_return_if_fail (objtype != 0); g_return_if_fail (handler != NULL); info = prop_info_new (); info->handler = handler; g_hash_table_insert (prop_registry, (gpointer)objtype, info); } GType swamigui_prop_get_type (void) { static GType obj_type = 0; if (!obj_type) { static const GTypeInfo obj_info = { sizeof (SwamiguiPropClass), NULL, NULL, (GClassInitFunc) swamigui_prop_class_init, NULL, NULL, sizeof (SwamiguiProp), 0, (GInstanceInitFunc) swamigui_prop_init, }; static const GInterfaceInfo panel_info = { (GInterfaceInitFunc)swamigui_prop_panel_iface_init, NULL, NULL }; obj_type = g_type_register_static (GTK_TYPE_SCROLLED_WINDOW, "SwamiguiProp", &obj_info, 0); g_type_add_interface_static (obj_type, SWAMIGUI_TYPE_PANEL, &panel_info); prop_registry = g_hash_table_new_full (NULL, NULL, NULL, prop_info_free); } return (obj_type); } static void swamigui_prop_class_init (SwamiguiPropClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); parent_class = g_type_class_peek_parent (klass); obj_class->set_property = swamigui_prop_set_property; obj_class->get_property = swamigui_prop_get_property; obj_class->finalize = swamigui_prop_finalize; g_object_class_override_property (obj_class, PROP_ITEM_SELECTION, "item-selection"); } static void swamigui_prop_panel_iface_init (SwamiguiPanelIface *panel_iface) { panel_iface->label = _("Properties"); panel_iface->blurb = _("Edit general properties of items"); panel_iface->stockid = GTK_STOCK_PROPERTIES; panel_iface->check_selection = swamigui_prop_panel_iface_check_selection; } static gboolean swamigui_prop_panel_iface_check_selection (IpatchList *selection, GType *selection_types) { /* one item only and is a registered prop interface type */ return (!selection->items->next && g_hash_table_lookup (prop_registry, (gpointer)(*selection_types))); } static void swamigui_prop_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { SwamiguiProp *prop = SWAMIGUI_PROP (object); switch (property_id) { case PROP_ITEM_SELECTION: swamigui_prop_real_set_selection (prop, (IpatchList *)g_value_get_object (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_prop_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { SwamiguiProp *prop = SWAMIGUI_PROP (object); switch (property_id) { case PROP_ITEM_SELECTION: g_value_set_object (value, prop->selection); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_prop_finalize (GObject *object) { SwamiguiProp *prop = SWAMIGUI_PROP (object); if (prop->selection) g_object_unref (prop->selection); (*parent_class->finalize)(object); } static void swamigui_prop_init (SwamiguiProp *prop) { GtkObject *hadj, *vadj; gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (prop), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); hadj = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0); vadj = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0); g_object_set (prop, "hadjustment", hadj, "vadjustment", vadj, NULL); prop->viewport = gtk_viewport_new (GTK_ADJUSTMENT (hadj), GTK_ADJUSTMENT (vadj)); gtk_widget_show (prop->viewport); gtk_container_add (GTK_CONTAINER (prop), prop->viewport); prop->selection = NULL; } /** * swamigui_prop_new: * * Create a new Swami properties object * * Returns: Swami properties object */ GtkWidget * swamigui_prop_new (void) { return (GTK_WIDGET (g_object_new (SWAMIGUI_TYPE_PROP, NULL))); } /** * swamigui_prop_set_selection: * @prop: Properties object * @select: Item selection to control or %NULL to unset. If list contains * multiple items, then selection will be unset. * * Set the object to control properties of. */ void swamigui_prop_set_selection (SwamiguiProp *prop, IpatchList *selection) { if (swamigui_prop_real_set_selection (prop, selection)) g_object_notify (G_OBJECT (prop), "item-selection"); } static gboolean swamigui_prop_real_set_selection (SwamiguiProp *prop, IpatchList *selection) { GtkWidget *widg = NULL; GObject *item = NULL, *olditem = NULL; gboolean same_type; PropInfo *info = NULL; g_return_val_if_fail (SWAMIGUI_IS_PROP (prop), FALSE); g_return_val_if_fail (!selection || IPATCH_IS_LIST (selection), FALSE); /* selection should be a single item, otherwise set it to NULL */ if (selection && (!selection->items || selection->items->next)) selection = NULL; if (selection) { item = (GObject *)(selection->items->data); g_return_val_if_fail (G_IS_OBJECT (item), FALSE); } if (prop->selection) olditem = G_OBJECT (prop->selection->items->data); /* same item is already set? */ if (item == olditem) return (FALSE); if (item) { info = g_hash_table_lookup (prop_registry, (gpointer)G_OBJECT_TYPE (item)); if (!info) /* No interface found for this object type? */ { if (!olditem) return (FALSE); /* already unset, return */ item = NULL; selection = NULL; } } /* selected item is of the same type? */ same_type = (item && olditem && G_OBJECT_TYPE (item) == G_OBJECT_TYPE (olditem)); /* destroy the old interface (if any) if not of the same type as the new item */ if (!same_type) gtk_container_foreach (GTK_CONTAINER (prop->viewport), (GtkCallback)gtk_object_destroy, NULL); if (item) /* setting item? */ { if (!same_type) /* create new interface for different type? */ { if (info->widg_name) /* Create by widget name? */ { widg = swamigui_util_glade_create (info->widg_name); swamigui_control_glade_prop_connect (widg, item); } else widg = info->handler (NULL, item); /* Create using handler */ gtk_widget_show (widg); gtk_container_add (GTK_CONTAINER (prop->viewport), widg); } else /* same type (re-using interface) */ { widg = gtk_bin_get_child (GTK_BIN (prop->viewport)); if (widg) { /* update the interface, by widget name method or handler method */ if (info->widg_name) swamigui_control_glade_prop_connect (widg, item); else info->handler (widg, item); } } if (!widg) selection = NULL; } prop->selection = selection; if (prop->selection) g_object_ref (prop->selection); /* ++ reference selection */ return (TRUE); } swami/src/swamigui/swamigui.h0000644000175000017500000000472311461334205016475 0ustar alessioalessio/* * swamigui.h - Main public header file for Swami GUI * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMI_GUI_H__ #define __SWAMI_GUI_H__ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #endif swami/src/swamigui/SwamiguiPanelSF2Gen.h0000644000175000017500000000632111461334205020356 0ustar alessioalessio/* * SwamiguiCtrlSF2Gen.h - User interface generator control object header file * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_GEN_CTRL_H__ #define __SWAMIGUI_GEN_CTRL_H__ #include #include typedef struct _SwamiguiPanelSF2Gen SwamiguiPanelSF2Gen; typedef struct _SwamiguiPanelSF2GenClass SwamiguiPanelSF2GenClass; typedef struct _SwamiguiPanelSF2GenCtrlInfo SwamiguiPanelSF2GenCtrlInfo; #define SWAMIGUI_TYPE_PANEL_SF2_GEN (swamigui_panel_sf2_gen_get_type ()) #define SWAMIGUI_PANEL_SF2_GEN(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMIGUI_TYPE_PANEL_SF2_GEN, \ SwamiguiPanelSF2Gen)) #define SWAMIGUI_PANEL_SF2_GEN_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMIGUI_TYPE_SF2_GEN, \ SwamiguiPanelSF2GenClass)) #define SWAMIGUI_IS_PANEL_SF2_GEN(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMIGUI_TYPE_PANEL_SF2_GEN)) #define SWAMIGUI_IS_PANEL_SF2_GEN_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMIGUI_TYPE_PANEL_SF2_GEN)) struct _SwamiguiPanelSF2Gen { GtkScrolledWindow parent_instance; /* derived from GtkScrolledWindow */ IpatchList *selection; /* item selection */ int seltype; /* current selection type (see SelType in $.c) */ SwamiguiPanelSF2GenCtrlInfo *ctrlinfo; /* Array of control info */ gpointer genwidgets; /* GenWidget array (see GenWidget in $.c) */ int genwidget_count; /* Count of widgets in genwidgets array */ }; struct _SwamiguiPanelSF2GenClass { GtkScrolledWindowClass parent_class; }; /** * SwamiguiPanelSF2GenCtrlInfo: * @genid: Generator ID or value from #SwamiguiPanelSF2GenOp * @icon: Icon name or other string value (label text for example) */ struct _SwamiguiPanelSF2GenCtrlInfo { guint8 genid; char *icon; }; /** * SwamiguiPanelSF2GenOther: * @SWAMIGUI_PANEL_SF2_GEN_LABEL: A label * @SWAMIGUI_PANEL_SF2_GEN_COLUMN: Marks beginning of next column * @SWAMIGUI_PANEL_SF2_GEN_END: End of #SwamiguiPanelSF2GenCtrlInfo array * * Operator values stored in #SwamiguiPanelSF2GenCtrlInfo genid field. */ typedef enum { SWAMIGUI_PANEL_SF2_GEN_LABEL = 200, SWAMIGUI_PANEL_SF2_GEN_COLUMN, SWAMIGUI_PANEL_SF2_GEN_END /* End of list */ } SwamiguiPanelSF2GenOp; GType swamigui_panel_sf2_gen_get_type (void); GtkWidget *swamigui_panel_sf2_gen_new (void); void swamigui_panel_sf2_gen_set_controls (SwamiguiPanelSF2Gen *genpanel, SwamiguiPanelSF2GenCtrlInfo *ctrlinfo); #endif swami/src/swamigui/SwamiguiTreeStorePatch.c0000644000175000017500000005030611461334205021243 0ustar alessioalessio/* * SwamiguiTreeStorePatch.c - Patch tree store (for instruments). * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include "SwamiguiTreeStorePatch.h" #include "SwamiguiRoot.h" #include /* used by swamigui_tree_store_real_item_add to qsort child items by title */ typedef struct { GObject *tree_parent; /* tree parent object (primary sort field) */ char *title; /* text title (secondary sort field, for sorted types) */ GObject *item; } ChildSortBag; /* Local Prototypes */ static void swamigui_tree_store_patch_class_init (SwamiguiTreeStorePatchClass *klass); static IpatchItem *swamigui_tree_store_create_virtual_child (IpatchItem *container, GType virtual_child_type); static IpatchItem *swamigui_tree_store_lookup_virtual_child (IpatchItem *container, GType virtual_child_type); static void swamigui_tree_store_patch_real_item_add ( SwamiguiTreeStore *store, GObject *item, GtkTreeIter *sibling, GtkTreeIter *out_iter, GtkTreeIter *in_parent_iter, ChildSortBag *inbag); static int title_sort_compar_func (const void *a, const void *b); static gboolean get_item_sort_info (SwamiguiTreeStore *store, GObject *item, GType item_type, GObject *parent, GObject **out_tree_parent, GtkTreeIter *out_parent_iter); static gboolean find_sibling_title_sort (SwamiguiTreeStore *store, GObject *item, char *title, GtkTreeIter *parent_iter, GtkTreeIter *sibling_iter); static gboolean find_sibling_container_sort (SwamiguiTreeStore *store, GObject *item, GObject *parent, GtkTreeIter *parent_iter, GtkTreeIter *sibling_iter); GType swamigui_tree_store_patch_get_type (void) { static GType obj_type = 0; if (!obj_type) { static const GTypeInfo obj_info = { sizeof (SwamiguiTreeStorePatchClass), NULL, NULL, (GClassInitFunc) swamigui_tree_store_patch_class_init, NULL, NULL, sizeof (SwamiguiTreeStorePatch), 0, (GInstanceInitFunc) NULL, }; obj_type = g_type_register_static (SWAMIGUI_TYPE_TREE_STORE, "SwamiguiTreeStorePatch", &obj_info, 0); } return (obj_type); } static void swamigui_tree_store_patch_class_init (SwamiguiTreeStorePatchClass *klass) { SwamiguiTreeStoreClass *store_class = SWAMIGUI_TREE_STORE_CLASS (klass); store_class->item_add = swamigui_tree_store_patch_item_add; store_class->item_changed = swamigui_tree_store_patch_item_changed; } /** * swamigui_tree_store_patch_new: * * Create a new patch tree store for instruments. * * Returns: New patch tree store object with a ref count of 1. */ SwamiguiTreeStorePatch * swamigui_tree_store_patch_new (void) { return (SWAMIGUI_TREE_STORE_PATCH (g_object_new (SWAMIGUI_TYPE_TREE_STORE_PATCH, NULL))); } /* * swamigui_tree_store_create_virtual_child: * @container: Item to create virtual container child instance in * @virtual_child_type: The virtual child type * * Create a virtual container instance in a container. If @container already * has the specified @virtual_child_type it is simply returned. * * Returns: Virtual container instance */ static IpatchItem * swamigui_tree_store_create_virtual_child (IpatchItem *container, GType virtual_child_type) { IpatchItem *virt_container; gpointer data; const char *keyname; g_return_val_if_fail (IPATCH_IS_ITEM (container), NULL); g_return_val_if_fail (g_type_is_a (virtual_child_type, IPATCH_TYPE_VIRTUAL_CONTAINER), NULL); /* use the virtual type name as the GObject data key */ keyname = g_type_name (virtual_child_type); data = g_object_get_data (G_OBJECT (container), keyname); if (data) return (IPATCH_ITEM (data)); virt_container = g_object_new (virtual_child_type, NULL); /* ++ ref */ ipatch_item_set_parent (IPATCH_ITEM (virt_container),IPATCH_ITEM (container)); g_object_set_data (G_OBJECT (container), keyname, virt_container); /* !! Reference is held until @container is removed from tree */ return (virt_container); } /* * swamigui_tree_store_lookup_virtual_child: * @container: Container item to look up a virtual child instance in * @virtual_child_type: The virtual child type * * Lookup a virtual container child instance in a container. * * Returns: Virtual container instance or %NULL if no virtual child of * requested type. */ static IpatchItem * swamigui_tree_store_lookup_virtual_child (IpatchItem *container, GType virtual_child_type) { gpointer data; const char *keyname; g_return_val_if_fail (IPATCH_IS_ITEM (container), NULL); g_return_val_if_fail (g_type_is_a (virtual_child_type, IPATCH_TYPE_VIRTUAL_CONTAINER), NULL); /* use the virtual type name as the GObject data key */ keyname = g_type_name (virtual_child_type); data = g_object_get_data (G_OBJECT (container), keyname); if (data) return (IPATCH_ITEM (data)); else return (NULL); } /** * swamigui_tree_store_patch_item_add: * @store: Patch tree store * @item: Item to add * * Function used as item_add method of #SwamiguiTreeStorePatchClass. * Might be useful to other tree store types. */ void swamigui_tree_store_patch_item_add (SwamiguiTreeStore *store, GObject *item) { swamigui_tree_store_patch_real_item_add (store, item, NULL, NULL, NULL, NULL); } /* some tricks are done to speed up adding a container item (children are pre-sorted to decrease exponential list iterations). Yeah looks pretty ugly, but in theory it should provide a bit of a speedup. */ static void swamigui_tree_store_patch_real_item_add ( SwamiguiTreeStore *store, GObject *item, GtkTreeIter *sibling, GtkTreeIter *out_iter, GtkTreeIter *in_parent_iter, ChildSortBag *inbag) { GtkTreeIter *parent_iter = NULL, real_parent_iter; GtkTreeIter sibling_iter, item_iter, *pitem_iter, tmp_iter; GObject *parent, *childitem; GObject *tree_parent; IpatchList *list; ChildSortBag bag, *bagp; char *alloc_title = NULL, *title; gboolean sort = FALSE; GArray *title_sort_array = NULL; GHashTable *prev_child_hash = NULL; GList *p; int i; /* ++ ref parent */ parent = (GObject *)ipatch_item_get_parent (IPATCH_ITEM (item)); g_return_if_fail (parent != NULL); if (inbag) /* recursive call? - Use already fetched values. */ { title = inbag->title; tree_parent = inbag->tree_parent; parent_iter = in_parent_iter; } else /* not a recursive call, no pre-cached values */ { gboolean sibling_set; /* get title of item (if not supplied to function) */ g_object_get (item, "title", &title, NULL); if (swami_log_if_fail (title != NULL)) goto ret; alloc_title = title; /* get sort boolean, tree parent object and node */ sort = get_item_sort_info (store, item, 0, parent, &tree_parent, &real_parent_iter); if (tree_parent) parent_iter = &real_parent_iter; if (sort) sibling_set = find_sibling_title_sort (store, item, title, parent_iter, &sibling_iter); else sibling_set = find_sibling_container_sort (store, item, parent, parent_iter, &sibling_iter); if (sibling_set) sibling = &sibling_iter; } /* else - !inbag */ /* insert the node into the tree */ swamigui_tree_store_insert_after (store, item, title, NULL, parent_iter, sibling, &item_iter); if (out_iter) *out_iter = item_iter; /* is added item a container? */ if (IPATCH_IS_CONTAINER (item)) { const GType *types; types = ipatch_container_get_virtual_types (IPATCH_CONTAINER (item)); if (types) /* any virtual container child types? */ { IpatchItem *virt; for (; *types; types++) /* create virtual containers */ { virt = swamigui_tree_store_create_virtual_child (IPATCH_ITEM (item), *types); swamigui_tree_store_insert_before (store, G_OBJECT (virt), NULL, NULL, &item_iter, NULL, NULL); } } types = ipatch_container_get_child_types (IPATCH_CONTAINER (item)); if (!types) goto ret; /* should always be child types, but.. */ title_sort_array = g_array_new (FALSE, FALSE, sizeof (ChildSortBag)); prev_child_hash = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify)g_free); for (; *types; types++) /* loop over container child types */ { gboolean static_parent; list = ipatch_container_get_children (IPATCH_CONTAINER (item), *types); /* ++ ref list */ parent_iter = NULL; /* virtual parent type is static? */ if (!ipatch_type_get_dynamic_func (*types, "virtual-parent-type")) { sort = get_item_sort_info (store, NULL, *types, item, &tree_parent, &real_parent_iter); if (tree_parent) parent_iter = &real_parent_iter; static_parent = TRUE; } else static_parent = FALSE; sibling = NULL; /* loop over child items of the current type */ for (p = list->items; p; p = p->next) { childitem = (GObject *)(p->data); /* dynamic virtual parent type? */ if (!static_parent) { sort = get_item_sort_info (store, childitem, 0, item, &tree_parent, &real_parent_iter); if (tree_parent) parent_iter = &real_parent_iter; } /* store item's values in the bag structure, may or may not get added to the title sort array, depending on if child is title sorted */ bag.tree_parent = tree_parent; g_object_get (childitem, "title", &title, NULL); if (swami_log_if_fail (title != NULL)) { g_object_unref (list); /* -- unref list */ goto ret; } bag.title = title; bag.item = childitem; if (sort) /* item should be sorted by title? */ { g_array_append_val (title_sort_array, bag); } else /* not title sorted, just add in order */ { /* keep track of the last child for each parent */ pitem_iter = g_hash_table_lookup (prev_child_hash, tree_parent); sibling = pitem_iter; /* sibling set if previous item */ if (!pitem_iter) { pitem_iter = g_new (GtkTreeIter, 1); g_hash_table_insert (prev_child_hash, tree_parent, pitem_iter); } swamigui_tree_store_patch_real_item_add (store, G_OBJECT (p->data), sibling, &tmp_iter, parent_iter, &bag); *pitem_iter = tmp_iter; g_free (bag.title); } } /* for .. p in list */ g_object_unref (list); /* -- unref list */ if (title_sort_array->len > 0) { GObject *prev_parent = NULL; /* sort the items by parent object and title */ qsort (title_sort_array->data, title_sort_array->len, sizeof (ChildSortBag), title_sort_compar_func); /* loop over sorted items */ for (i = 0; i < title_sort_array->len; i++) { bagp = &g_array_index (title_sort_array, ChildSortBag, i); /* dynamic virtual parent type? */ if (!static_parent) { sort = get_item_sort_info (store, G_OBJECT (bagp->item), 0, item, &tree_parent, &real_parent_iter); if (tree_parent) parent_iter = &real_parent_iter; } /* previous and current item are in different containers? */ if (prev_parent != tree_parent) sibling = NULL; else sibling = &item_iter; swamigui_tree_store_patch_real_item_add (store, G_OBJECT (bagp->item), sibling, &tmp_iter, parent_iter, bagp); item_iter = tmp_iter; prev_parent = tree_parent; g_free (bagp->title); } g_array_set_size (title_sort_array, 0); /* clear array */ } /* if (title_sort_array->len > 0) */ } /* for (*types) - container child types */ } /* if (IPATCH_IS_CONTAINER (item)) */ ret: g_object_unref (parent); /* -- unref parent */ if (alloc_title) g_free (alloc_title); if (title_sort_array) g_array_free (title_sort_array, TRUE); if (prev_child_hash) g_hash_table_destroy (prev_child_hash); } static int title_sort_compar_func (const void *a, const void *b) { ChildSortBag *baga = (ChildSortBag *)a, *bagb = (ChildSortBag *)b; if (baga->tree_parent == bagb->tree_parent) return (strcmp (baga->title, bagb->title)); /* parent object is the primary sort */ if (baga->tree_parent < bagb->tree_parent) return (1); else return (-1); } /* a helper function to get sort-children property that applies to an @item (can be NULL if item_type is set instead) and can also get the tree parent object and iterator if pointers are supplied. Returns: TRUE if item should be title sorted, FALSE otherwise */ static gboolean get_item_sort_info (SwamiguiTreeStore *store, GObject *item, GType item_type, GObject *parent, GObject **out_tree_parent, GtkTreeIter *out_parent_iter) { GObject *tree_parent; gboolean sort, has_parent_iter; GType type; if (item) ipatch_type_object_get (item, "virtual-parent-type", &type, NULL); else ipatch_type_get (item_type, "virtual-parent-type", &type, NULL); if (out_tree_parent || out_parent_iter) { /* item has a virtual parent type? Get the instance of it. */ if (type != G_TYPE_NONE) tree_parent = (GObject *)swamigui_tree_store_lookup_virtual_child (IPATCH_ITEM (parent), type); else if (SWAMI_IS_CONTAINER (parent)) /* NULL parent to append to root */ tree_parent = NULL; else tree_parent = parent; /* otherwise use real parent */ if (tree_parent) { /* get the tree node for the tree parent item */ has_parent_iter = swamigui_tree_store_item_get_node (store, G_OBJECT (tree_parent), out_parent_iter); if (swami_log_if_fail (has_parent_iter)) return (FALSE); } *out_tree_parent = tree_parent; } /* use real parent type if no virtual type */ if (type == G_TYPE_NONE && item) type = G_OBJECT_TYPE (item); /* children should be sorted? */ if (type != G_TYPE_NONE) ipatch_type_get (type, "sort-children", &sort, NULL); else sort = FALSE; return (sort); } /* find the closest sibling node already in tree store to insert after, sorted * by title. * Returns: TRUE if sibling_iter is set, FALSE if item should be first. */ static gboolean find_sibling_title_sort (SwamiguiTreeStore *store, GObject *item, char *title, GtkTreeIter *parent_iter, GtkTreeIter *sibling_iter) { GtkTreeModel *model = GTK_TREE_MODEL (store); gboolean haveprev = FALSE; GtkTreeIter child; GObject *cmpitem; char *curtitle; /* parent has any children? */ if (!gtk_tree_model_iter_children (model, &child, parent_iter)) return (FALSE); do /* search for sibling to insert before */ { gtk_tree_model_get (model, &child, SWAMIGUI_TREE_STORE_LABEL_COLUMN, &curtitle, /* ++ alloc */ SWAMIGUI_TREE_STORE_OBJECT_COLUMN, &cmpitem, /* ++ ref */ -1); g_object_unref (cmpitem); /* -- unref, we only need the pointer to compare */ /* compare titles and make sure its not the same item (if called to re-sort item) */ if (strcmp (title, curtitle) <= 0 && item != cmpitem) { g_free (curtitle); break; } g_free (curtitle); *sibling_iter = child; haveprev = TRUE; } while (gtk_tree_model_iter_next (model, &child)); return (haveprev == TRUE); } /* find the closest sibling node already in tree store to insert after, * sorted as found in container child list. * Returns: TRUE if sibling_iter is set, FALSE if item should be first. */ static gboolean find_sibling_container_sort (SwamiguiTreeStore *store, GObject *item, GObject *parent, GtkTreeIter *parent_iter, GtkTreeIter *sibling_iter) { GtkTreeModel *model = GTK_TREE_MODEL (store); GtkTreeIter tmpiter; GtkTreePath *parent_path = NULL, *sibparent_path; IpatchList *list; gboolean parent_match; const GType *childtypes; GType type; GList *p; /* Find matching child type which item is a decendent of - or use item's type */ childtypes = ipatch_container_get_child_types (IPATCH_CONTAINER (parent)); type = G_OBJECT_TYPE (item); for (; *childtypes; childtypes++) { if (g_type_is_a (type, *childtypes)) { type = *childtypes; break; } } /* ++ ref list */ list = ipatch_container_get_children (IPATCH_CONTAINER (parent), type); p = g_list_find (list->items, item); /* find item in list */ if (p) { /* search for previous sibling already in tree */ for (p = p->prev; p; p = p->prev) { /* item in tree? */ if (swamigui_tree_store_item_get_node (store, p->data, sibling_iter)) { /* Make sure its the same parent (no parent if child of root) */ if (gtk_tree_model_iter_parent (model, &tmpiter, sibling_iter)) { if (!parent_path) /* get path of parent iterator in tree store */ parent_path = gtk_tree_model_get_path (model, parent_iter); sibparent_path = gtk_tree_model_get_path (model, &tmpiter); /* is item really a sibling (same parent node?) */ parent_match = gtk_tree_path_compare (parent_path, sibparent_path) == 0; gtk_tree_path_free (sibparent_path); if (parent_match) break; } else break; /* no parent in tree (child of root) */ } } } if (parent_path) gtk_tree_path_free (parent_path); g_object_unref (list); /* -- unref list */ return (p != NULL); } /** * swamigui_tree_store_patch_item_changed: * @store: Patch tree store * @item: Item that changed * * Function used as item_changed method of #SwamiguiTreeStorePatchClass. * Might be useful to other tree store types. */ void swamigui_tree_store_patch_item_changed (SwamiguiTreeStore *store, GObject *item) { GtkTreeIter item_iter, parent_iter, curparent_iter, sibling_iter; gboolean found_item_node; gboolean found_parent_node; GObject *parent = NULL, *curparent = NULL, *tree_parent; char *title, *curtitle = NULL; /* get title of item */ g_object_get (item, "title", &title, NULL); /* ++ alloc */ g_return_if_fail (title != NULL); found_item_node = swamigui_tree_store_item_get_node (store, item, &item_iter); if (swami_log_if_fail (found_item_node)) goto ret; gtk_tree_model_get (GTK_TREE_MODEL (store), &item_iter, SWAMIGUI_TREE_STORE_LABEL_COLUMN, &curtitle, /* ++ alloc */ -1); if (strcmp (title, curtitle) == 0) goto ret; /* No change in title? - Return */ swamigui_tree_store_change (store, item, title, NULL); parent = (GObject *)ipatch_item_get_parent (IPATCH_ITEM (item)); /* ++ ref */ if (swami_log_if_fail (parent != NULL)) goto ret; /* Is item under a sorted parent? */ if (get_item_sort_info (store, item, 0, parent, &tree_parent, &parent_iter)) { /* Check if parent node has changed (switched from melodic to percussion for example) */ found_parent_node = gtk_tree_model_iter_parent (GTK_TREE_MODEL (store), &curparent_iter, &item_iter); if (swami_log_if_fail (found_parent_node)) goto ret; gtk_tree_model_get (GTK_TREE_MODEL (store), &curparent_iter, SWAMIGUI_TREE_STORE_OBJECT_COLUMN, &curparent, /* ++ ref */ -1); /* If the parent is the same, we can use the tree move functions */ if (curparent == tree_parent) { if (find_sibling_title_sort (store, item, title, &parent_iter, &sibling_iter)) swamigui_tree_store_move_after (store, item, &sibling_iter); else swamigui_tree_store_move_after (store, item, NULL); } else /* Parent changed, remove and add it back (yeah, PITA!) */ { swamigui_tree_store_remove (store, item); swamigui_tree_store_patch_item_add (store, item); } } ret: g_free (title); /* -- free title */ g_free (curtitle); /* -- free curtitle */ if (parent) g_object_unref (parent); /* -- unref parent */ if (curparent) g_object_unref (curparent); /* -- unref curparent */ } swami/src/swamigui/SwamiguiPref.c0000644000175000017500000005653511461334205017255 0ustar alessioalessio/* * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include "SwamiguiPref.h" #include "SwamiguiControl.h" #include "SwamiguiRoot.h" #include "util.h" #include "i18n.h" /* columns for preference sections list store */ enum { SECTIONS_COLUMN_ICON, SECTIONS_COLUMN_NAME, SECTIONS_COLUMN_COUNT }; /* columns for piano key binding list store */ enum { KEYBIND_COLUMN_NOTE, KEYBIND_COLUMN_KEY, KEYBIND_COLUMN_COUNT }; /* Action used for piano key binding capture */ typedef enum { BIND_MODE_INACTIVE, BIND_MODE_ADD, BIND_MODE_CHANGE } BindMode; /* Stores information on a registered preferences interface */ typedef struct { char *icon; /* Stock icon of preferences interface */ char *name; /* Name of the interface */ int order; /* Sort order for this preference interface */ SwamiguiPrefHandler handler; /* Handler to create the interface */ } PrefInfo; static gint sort_pref_info_by_order_and_name (gconstpointer a, gconstpointer b); static void swamigui_pref_cb_close_clicked (GtkWidget *button, gpointer user_data); static void swamigui_pref_section_list_change (GtkTreeSelection *selection, gpointer user_data); static GtkWidget *general_prefs_handler (void); static GtkWidget *keyboard_prefs_handler (void); static void keybindings_update (GtkWidget *prefwidg, gboolean lower); static void keybindings_set_bind_mode (GtkWidget *prefwidg, BindMode mode); static void keybindings_lower_radio_toggled (GtkToggleButton *btn, gpointer user_data); static void keybindings_add_key_button_toggled (GtkToggleButton *btn, gpointer user_data); static void keybindings_change_key_button_toggled (GtkToggleButton *btn, gpointer user_data); static void keybindings_delete_key_button_clicked (GtkButton *btn, gpointer user_data); static void keybindings_reset_keys_button_clicked (GtkButton *btn, gpointer user_data); static void keybindings_reset_keys_response (GtkDialog *dialog, int response, gpointer user_data); static void keybindings_selection_foreach (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data); static gboolean keybindings_key_press_event (GtkWidget *widg, GdkEventKey *event, gpointer user_data); static void keybindings_sync (GtkWidget *prefwidg); G_DEFINE_TYPE (SwamiguiPref, swamigui_pref, GTK_TYPE_DIALOG); static GList *pref_list = NULL; /* list of registered pref interfaces (PrefInfo *) */ #define swamigui_pref_info_new() g_slice_new (PrefInfo) static const char *note_names[] = { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" }; /** * swamigui_register_pref_handler: * @name: Name of the preference interface (shown in list with icon) * @icon: Name of stock icon for interface (shown in list with name) * @order: Order of the interface in relation to others (the lower the number * the higher on the list, use #SWAMIGUI_PREF_ORDER_NAME to indicate that the * interface should be sorted by name - after other interfaces which specify * a specific value). * * Register a preferences interface which will become a part of the preferences * widget. */ void swamigui_register_pref_handler (const char *name, const char *icon, int order, SwamiguiPrefHandler handler) { PrefInfo *info; g_return_if_fail (name != NULL); g_return_if_fail (icon != NULL); g_return_if_fail (handler != NULL); info = swamigui_pref_info_new (); info->name = g_strdup (name); info->icon = g_strdup (icon); info->order = order; info->handler = handler; pref_list = g_list_insert_sorted (pref_list, info, sort_pref_info_by_order_and_name); } /* GCompareFunc for sorting list items by order value or name */ static gint sort_pref_info_by_order_and_name (gconstpointer a, gconstpointer b) { PrefInfo *ainfo = (PrefInfo *)a, *binfo = (PrefInfo *)b; if (ainfo->order != SWAMIGUI_PREF_ORDER_NAME && binfo->order != SWAMIGUI_PREF_ORDER_NAME) return (ainfo->order - binfo->order); if (ainfo->order != SWAMIGUI_PREF_ORDER_NAME && binfo->order == SWAMIGUI_PREF_ORDER_NAME) return (-1); if (ainfo->order == SWAMIGUI_PREF_ORDER_NAME && binfo->order != SWAMIGUI_PREF_ORDER_NAME) return (1); return (strcmp (ainfo->name, binfo->name)); } static void swamigui_pref_class_init (SwamiguiPrefClass *klass) { /* Add built in preference sections */ swamigui_register_pref_handler (_("General"), GTK_STOCK_PREFERENCES, 10, general_prefs_handler); /* FIXME - Install a custom keyboard icon */ swamigui_register_pref_handler (_("Keyboard Map"), GTK_STOCK_SELECT_FONT, 20, keyboard_prefs_handler); } static void swamigui_pref_init (SwamiguiPref *pref) { GtkWidget *prefwidg; GtkWidget *treeview; GtkWidget *widg; GtkWidget *btn; GtkCellRenderer *renderer; GtkTreeViewColumn *column; GtkTreeSelection *selection; GtkListStore *store; GtkTreeIter iter; PrefInfo *info; GList *p; gtk_window_set_title (GTK_WINDOW (pref), _("Preferences")); /* Create the preferences glade widget and pack it in the dialog */ prefwidg = swamigui_util_glade_create ("Preferences"); gtk_widget_show (prefwidg); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (pref)->vbox), prefwidg, TRUE, TRUE, 0); /* Add close button to button box */ btn = gtk_button_new_from_stock (GTK_STOCK_CLOSE); gtk_widget_show (btn); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (pref)->action_area), btn); g_signal_connect (btn, "clicked", G_CALLBACK (swamigui_pref_cb_close_clicked), pref); treeview = swamigui_util_glade_lookup (prefwidg, "TreeViewSections"); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); g_signal_connect (selection, "changed", G_CALLBACK (swamigui_pref_section_list_change), pref); /* create the list store for the preference sections list and assign to tree view */ store = gtk_list_store_new (SECTIONS_COLUMN_COUNT, G_TYPE_STRING, G_TYPE_STRING); gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (store)); /* add icon and name cell renderer columns to tree */ renderer = gtk_cell_renderer_pixbuf_new (); g_object_set (renderer, "stock-size", GTK_ICON_SIZE_BUTTON, NULL); column = gtk_tree_view_column_new_with_attributes ("icon", renderer, "stock-id", SECTIONS_COLUMN_ICON, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("name", renderer, "text", SECTIONS_COLUMN_NAME, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); /* each section is stored in a notebook page. Notebook tabs are invisible. */ pref->notebook = swamigui_util_glade_lookup (prefwidg, "NoteBookPanels"); /* add preferences sections to list and control interfaces to invisible notebook */ for (p = pref_list; p; p = p->next) { info = (PrefInfo *)(p->data); gtk_list_store_append (store, &iter); gtk_list_store_set (store, &iter, SECTIONS_COLUMN_ICON, info->icon, SECTIONS_COLUMN_NAME, info->name, -1); widg = info->handler (); gtk_notebook_append_page (GTK_NOTEBOOK (pref->notebook), widg, NULL); } /* Select the first item in the list */ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) gtk_tree_selection_select_iter (GTK_TREE_SELECTION (selection), &iter); } static void swamigui_pref_cb_close_clicked (GtkWidget *button, gpointer user_data) { SwamiguiPref *pref = SWAMIGUI_PREF (user_data); gtk_widget_destroy (GTK_WIDGET (pref)); /* destroy dialog */ } /* callback for when preference section list selection changes */ static void swamigui_pref_section_list_change (GtkTreeSelection *selection, gpointer user_data) { SwamiguiPref *pref = SWAMIGUI_PREF (user_data); GtkTreeModel *model; GtkTreeIter iter; GtkTreePath *path; gint *indices; if (!gtk_tree_selection_get_selected (selection, &model, &iter)) return; path = gtk_tree_model_get_path (model, &iter); /* ++ alloc path */ indices = gtk_tree_path_get_indices (path); /* set the notebook to page corresponding to selected section index */ if (indices && indices[0] != -1) gtk_notebook_set_current_page (GTK_NOTEBOOK (pref->notebook), indices[0]); gtk_tree_path_free (path); /* -- free path */ } /** * swamigui_pref_new: * * Create preferences dialog widget. * * Returns: New preferences dialog widget. */ GtkWidget * swamigui_pref_new (void) { return ((GtkWidget *)g_object_new (SWAMIGUI_TYPE_PREF, NULL)); } /* General preferences widget handler */ static GtkWidget * general_prefs_handler (void) { GtkWidget *widg; widg = swamigui_util_glade_create ("GeneralPrefs"); swamigui_control_glade_prop_connect (widg, G_OBJECT (swamigui_root)); gtk_widget_show (widg); return (widg); } /* Virtual keyboard mapping preferences handler */ static GtkWidget * keyboard_prefs_handler (void) { GtkWidget *prefwidg; GtkWidget *treeview; GtkCellRenderer *renderer; GtkTreeViewColumn *column; GtkTreeSelection *selection; GtkListStore *store; GtkWidget *widg; prefwidg = swamigui_util_glade_create ("VirtKeyboardPrefs"); treeview = swamigui_util_glade_lookup (prefwidg, "KeyTreeView"); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE); g_object_set_data (G_OBJECT (prefwidg), "selection", selection); // g_signal_connect (selection, "changed", // G_CALLBACK (keybindings_selection_changed), prefwidg); /* create the list store for the key bindings */ store = gtk_list_store_new (KEYBIND_COLUMN_COUNT, G_TYPE_STRING, G_TYPE_STRING); gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (store)); g_object_set_data (G_OBJECT (prefwidg), "store", store); /* add note and key name cell renderer columns to tree */ renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Note", renderer, "text", KEYBIND_COLUMN_NOTE, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Key binding", renderer, "text", KEYBIND_COLUMN_KEY, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); keybindings_update (prefwidg, TRUE); /* update key binding list to lower keys */ widg = swamigui_util_glade_lookup (prefwidg, "RadioLower"); g_signal_connect (widg, "toggled", G_CALLBACK (keybindings_lower_radio_toggled), prefwidg); widg = swamigui_util_glade_lookup (prefwidg, "BtnAddKey"); g_signal_connect (widg, "toggled", G_CALLBACK (keybindings_add_key_button_toggled), prefwidg); widg = swamigui_util_glade_lookup (prefwidg, "BtnChangeKey"); g_signal_connect (widg, "toggled", G_CALLBACK (keybindings_change_key_button_toggled), prefwidg); widg = swamigui_util_glade_lookup (prefwidg, "BtnDeleteKey"); g_signal_connect (widg, "clicked", G_CALLBACK (keybindings_delete_key_button_clicked), prefwidg); widg = swamigui_util_glade_lookup (prefwidg, "BtnResetKeys"); g_signal_connect (widg, "clicked", G_CALLBACK (keybindings_reset_keys_button_clicked), prefwidg); gtk_widget_show (prefwidg); return (prefwidg); } #if 0 /* callback when keybindings list selection changes */ static void keybindings_selection_changed (GtkTreeSelection *selection, gpointer user_data) { GtkWidget *prefwidg = GTK_WIDGET (user_data); GtkWidget *widg; #if 0 widg = swamigui_util_glade_lookup (prefwidg, "LabelKeyBind"); /* If key binding is active, de-activate it */ if (GTK_WIDGET_VISIBLE (widg)) { gtk_widget_hide (widg); g_signal_handlers_disconnect_by_func (prefwidg, G_CALLBACK (keybindings_key_press_event), prefwidg); } #endif /* Set change button sensitivity depending on if only one list item selected */ widg = swamigui_util_glade_lookup (prefwidg, "BtnChangeKey"); gtk_widget_set_sensitive (widg, gtk_tree_selection_count_selected_rows (selection) == 1); } #endif /* Update keybindings list to lower (lower == TRUE) or upper (lower == FALSE) */ static void keybindings_update (GtkWidget *prefwidg, gboolean lower) { char *propval; char **keys, **sptr; char notename[16]; GtkTreeIter iter; GtkListStore *store; int i; store = g_object_get_data (G_OBJECT (prefwidg), "store"); gtk_list_store_clear (store); g_object_get (swamigui_root, lower ? "piano-lower-keys" : "piano-upper-keys", &propval, NULL); /* ++ alloc string */ keys = g_strsplit (propval, ",", 0); /* ++ alloc (NULL terminated array of strings) */ g_free (propval); /* -- free string */ /* add preferences sections to list and control interfaces to invisible notebook */ for (sptr = keys, i = 0; *sptr; sptr++, i++) { gtk_list_store_append (store, &iter); sprintf (notename, "%s%d", note_names[i % 12], i / 12); gtk_list_store_set (store, &iter, KEYBIND_COLUMN_NOTE, notename, KEYBIND_COLUMN_KEY, *sptr, -1); } g_strfreev (keys); /* -- free array of strings */ } static void keybindings_set_bind_mode (GtkWidget *prefwidg, BindMode mode) { gboolean addbtn = FALSE, changebtn = FALSE; GtkWidget *widg; GtkWidget *lbl; /* Check if requested mode is already set */ if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (prefwidg), "bind-mode")) == mode) return; lbl = swamigui_util_glade_lookup (prefwidg, "LabelKeyBind"); switch (mode) { case BIND_MODE_ADD: addbtn = TRUE; /* fall through */ case BIND_MODE_CHANGE: if (mode == BIND_MODE_CHANGE) changebtn = TRUE; gtk_widget_show (lbl); g_signal_connect (prefwidg, "key-press-event", G_CALLBACK (keybindings_key_press_event), prefwidg); break; case BIND_MODE_INACTIVE: gtk_widget_hide (lbl); g_signal_handlers_disconnect_by_func (prefwidg, G_CALLBACK (keybindings_key_press_event), prefwidg); break; } widg = swamigui_util_glade_lookup (prefwidg, "BtnAddKey"); g_signal_handlers_block_by_func (widg, keybindings_add_key_button_toggled, prefwidg); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widg), addbtn); g_signal_handlers_unblock_by_func (widg, keybindings_add_key_button_toggled, prefwidg); widg = swamigui_util_glade_lookup (prefwidg, "BtnChangeKey"); g_signal_handlers_block_by_func (widg, keybindings_change_key_button_toggled, prefwidg); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widg), changebtn); g_signal_handlers_unblock_by_func (widg, keybindings_change_key_button_toggled, prefwidg); /* indicate the current key bind mode */ g_object_set_data (G_OBJECT (prefwidg), "bind-mode", GUINT_TO_POINTER (mode)); } /* callback when Lower radio button is toggled */ static void keybindings_lower_radio_toggled (GtkToggleButton *btn, gpointer user_data) { GtkWidget *prefwidg = GTK_WIDGET (user_data); keybindings_update (prefwidg, gtk_toggle_button_get_active (btn)); } static void keybindings_add_key_button_toggled (GtkToggleButton *btn, gpointer user_data) { GtkWidget *prefwidg = GTK_WIDGET (user_data); keybindings_set_bind_mode (prefwidg, gtk_toggle_button_get_active (btn) ? BIND_MODE_ADD : BIND_MODE_INACTIVE); } static void keybindings_change_key_button_toggled (GtkToggleButton *btn, gpointer user_data) { GtkWidget *prefwidg = GTK_WIDGET (user_data); keybindings_set_bind_mode (prefwidg, gtk_toggle_button_get_active (btn) ? BIND_MODE_CHANGE : BIND_MODE_INACTIVE); } static void keybindings_delete_key_button_clicked (GtkButton *btn, gpointer user_data) { GtkWidget *prefwidg = GTK_WIDGET (user_data); GtkTreeSelection *selection; GtkListStore *store; GList *sel_iters = NULL, *p; GtkTreeIter *iter; /* de-activate bind mode, if any */ keybindings_set_bind_mode (prefwidg, BIND_MODE_INACTIVE); selection = g_object_get_data (G_OBJECT (prefwidg), "selection"); store = g_object_get_data (G_OBJECT (prefwidg), "store"); gtk_tree_selection_selected_foreach (selection, keybindings_selection_foreach, &sel_iters); /* ++ alloc */ for (p = sel_iters; p; p = p->next) { iter = (GtkTreeIter *)(p->data); gtk_list_store_remove (store, iter); gtk_tree_iter_free (iter); } g_list_free (sel_iters); /* -- free */ } /* Callback for when Reset keys button is clicked */ static void keybindings_reset_keys_button_clicked (GtkButton *btn, gpointer user_data) { GtkWidget *prefwidg = GTK_WIDGET (user_data); GtkWidget *dialog; /* de-activate bind mode, if any */ keybindings_set_bind_mode (prefwidg, BIND_MODE_INACTIVE); dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, _("Reset all piano key bindings to defaults?")); g_signal_connect (GTK_DIALOG (dialog), "response", G_CALLBACK (keybindings_reset_keys_response), prefwidg); gtk_widget_show (dialog); } /* Callback for response to "Reset all keys?" dialog */ static void keybindings_reset_keys_response (GtkDialog *dialog, int response, gpointer user_data) { GtkWidget *prefwidg = GTK_WIDGET (user_data); GParamSpec *pspec; GValue value = { 0 }; GtkWidget *widg; if (response == GTK_RESPONSE_YES) /* Reset to defaults if Yes */ { pspec = g_object_class_find_property (g_type_class_peek (SWAMIGUI_TYPE_ROOT), "piano-lower-keys"); g_value_init (&value, G_TYPE_STRING); g_param_value_set_default (pspec, &value); g_object_set_property (G_OBJECT (swamigui_root), "piano-lower-keys", &value); g_value_reset (&value); pspec = g_object_class_find_property (g_type_class_peek (SWAMIGUI_TYPE_ROOT), "piano-upper-keys"); g_param_value_set_default (pspec, &value); g_object_set_property (G_OBJECT (swamigui_root), "piano-upper-keys", &value); /* Update keybindings list */ widg = swamigui_util_glade_lookup (prefwidg, "RadioLower"); keybindings_update (prefwidg, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widg))); } gtk_object_destroy (GTK_OBJECT (dialog)); } /* a tree selection foreach callback to remove selected modulators */ static void keybindings_selection_foreach (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { GList **sel_iters = (GList **)data; GtkTreeIter *copy; copy = gtk_tree_iter_copy (iter); *sel_iters = g_list_append (*sel_iters, copy); } /* callback when a key is pressed (for key binding) */ static gboolean keybindings_key_press_event (GtkWidget *eventwidg, GdkEventKey *event, gpointer user_data) { GtkWidget *prefwidg = GTK_WIDGET (user_data); GtkTreeSelection *selection; GtkWidget *treeview; GtkListStore *store; GtkTreeIter iter; GtkTreePath *path; GList *list; guint mode; char *keyname; char notename[16]; int count; if (event->keyval == GDK_Escape) /* If escape, stop key binding mode */ { keybindings_set_bind_mode (prefwidg, BIND_MODE_INACTIVE); return (TRUE); /* Stop key propagation */ } store = g_object_get_data (G_OBJECT (prefwidg), "store"); selection = g_object_get_data (G_OBJECT (prefwidg), "selection"); treeview = swamigui_util_glade_lookup (prefwidg, "KeyTreeView"); mode = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (prefwidg), "bind-mode")); switch (mode) { case BIND_MODE_ADD: /* Add new keybinding to list */ keyname = gdk_keyval_name (event->keyval); count = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL); gtk_list_store_append (store, &iter); sprintf (notename, "%s%d", note_names[count % 12], count / 12); gtk_list_store_set (store, &iter, KEYBIND_COLUMN_NOTE, notename, KEYBIND_COLUMN_KEY, keyname, -1); /* select new item and scroll to it */ gtk_tree_selection_unselect_all (selection); gtk_tree_selection_select_iter (selection, &iter); path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter); /* ++ alloc */ gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (treeview), path, NULL, FALSE, 0.0, 0.0); gtk_tree_path_free (path); /* -- free */ break; case BIND_MODE_CHANGE: keyname = gdk_keyval_name (event->keyval); list = gtk_tree_selection_get_selected_rows (selection, NULL); /* ++ alloc list */ /* if there is a selected item.. */ if (list && gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, (GtkTreePath *)(list->data))) { count = gtk_tree_path_get_indices ((GtkTreePath *)(list->data))[0]; sprintf (notename, "%s%d", note_names[count % 12], count / 12); gtk_list_store_set (store, &iter, KEYBIND_COLUMN_NOTE, notename, KEYBIND_COLUMN_KEY, keyname, -1); /* Select the next item in the list */ if (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter)) { gtk_tree_selection_unselect_all (selection); gtk_tree_selection_select_iter (selection, &iter); path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter); /* ++ alloc */ gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (treeview), path, NULL, FALSE, 0.0, 0.0); gtk_tree_path_free (path); /* -- free */ } /* No more items, de-activate change mode */ else keybindings_set_bind_mode (prefwidg, BIND_MODE_INACTIVE); } /* -- free list */ g_list_foreach (list, (GFunc)gtk_tree_path_free, NULL); g_list_free (list); break; } /* Sync updated keys to SwamiguiRoot property */ keybindings_sync (prefwidg); return (TRUE); /* Stop key propagation */ } /* Synchronize key list to SwamiguiRoot property */ static void keybindings_sync (GtkWidget *prefwidg) { GtkTreeModel *model; GtkTreeIter iter; GString *string; gboolean lowkeys; GtkWidget *radio; char *keyname; model = GTK_TREE_MODEL (g_object_get_data (G_OBJECT (prefwidg), "store")); string = g_string_new (""); /* ++ alloc */ if (gtk_tree_model_get_iter_first (model, &iter)) { do { gtk_tree_model_get (model, &iter, KEYBIND_COLUMN_KEY, &keyname, /* ++ alloc */ -1); if (string->len != 0) g_string_append_c (string, ','); g_string_append (string, keyname); g_free (keyname); /* -- free key name */ } while (gtk_tree_model_iter_next (model, &iter)); } radio = swamigui_util_glade_lookup (prefwidg, "RadioLower"); lowkeys = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radio)); g_object_set (swamigui_root, lowkeys ? "piano-lower-keys" : "piano-upper-keys", string->str, NULL); g_string_free (string, TRUE); /* -- free */ } swami/src/swamigui/SwamiguiPanelSelector.c0000644000175000017500000003330511461334205021107 0ustar alessioalessio/* * SwamiguiPanelSelector.c - Panel interface selection widget (notebook tabs) * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include "SwamiguiPanelSelector.h" #include "SwamiguiPanel.h" #include "i18n.h" enum { PROP_0, PROP_ITEM_SELECTION }; /* Stores information on a registered panel interface */ typedef struct { GType type; /* Panel type */ int order; /* Sort order for this panel type */ } PanelInfo; static void swamigui_panel_selector_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void swamigui_panel_selector_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void swamigui_panel_selector_finalize (GObject *object); static gboolean swamigui_panel_selector_button_press (GtkWidget *widget, GdkEventButton *event); static void swamigui_panel_selector_switch_page (GtkNotebook *notebook, GtkNotebookPage *page, guint page_num); static gboolean swamigui_panel_selector_real_set_selection (SwamiguiPanelSelector *selector, IpatchList *items); static gint sort_panel_info_by_order (gconstpointer a, gconstpointer b); static void swamigui_panel_selector_insert_panel (SwamiguiPanelSelector *selector, PanelInfo *info, int pos); G_DEFINE_TYPE (SwamiguiPanelSelector, swamigui_panel_selector, GTK_TYPE_NOTEBOOK); static GList *panel_list = NULL; /* list of registered panels (PanelInfo *) */ static guint panel_count = 0; /* count of items in panel_list */ /* Cached panel widgets (SwamiguiPanel *), used only in GUI context */ static GList *panel_cache = NULL; #define swamigui_panel_selector_info_new() g_slice_new (PanelInfo) /** * swamigui_get_panel_selector_types: * * Get array of GType widgets which implement the #SwamiguiPanel interface and * have been registered with swamigui_register_panel_selector_type(). * * Returns: Array of GTypes (terminated with a 0 GType) which should be freed * when finished, can be %NULL if empty list. */ GType * swamigui_get_panel_selector_types (void) { GType *types = NULL; PanelInfo *info; GList *p; guint len, i; if (!panel_list) return (NULL); len = panel_count; /* atomic integer read, value increases only */ if (len == 0) return (NULL); types = g_new (GType, len + 1); /* ++ alloc */ /* copy types */ for (i = 0, p = panel_list; i < len; i++, p = p->next) { info = (PanelInfo *)(p->data); types[i] = info->type; } types[len] = 0; return (types); /* !! caller takes over allocation */ } /** * swamigui_register_panel_selector_type: * @panel_type: Type of widget with #SwamiguiPanel interface to register * @order: Order of the interface in relation to others (determines order of * notepad tabs, lower values are placed left of higher values) * * Register a panel interface for use in the panel selector notebook widget. */ void swamigui_register_panel_selector_type (GType panel_type, int order) { PanelInfo *info; g_return_if_fail (g_type_is_a (panel_type, SWAMIGUI_TYPE_PANEL)); info = swamigui_panel_selector_info_new (); info->type = panel_type; info->order = order; panel_list = g_list_append (panel_list, info); panel_count++; } static void swamigui_panel_selector_class_init (SwamiguiPanelSelectorClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); GtkNotebookClass *notebook_class = GTK_NOTEBOOK_CLASS (klass); obj_class->set_property = swamigui_panel_selector_set_property; obj_class->get_property = swamigui_panel_selector_get_property; obj_class->finalize = swamigui_panel_selector_finalize; widget_class->button_press_event = swamigui_panel_selector_button_press; notebook_class->switch_page = swamigui_panel_selector_switch_page; g_object_class_install_property (obj_class, PROP_ITEM_SELECTION, g_param_spec_object ("item-selection", _("Item selection"), _("Item selection"), IPATCH_TYPE_LIST, G_PARAM_READWRITE)); } static void swamigui_panel_selector_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { SwamiguiPanelSelector *selector = SWAMIGUI_PANEL_SELECTOR (object); switch (property_id) { case PROP_ITEM_SELECTION: swamigui_panel_selector_real_set_selection (selector, g_value_get_object (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_panel_selector_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { SwamiguiPanelSelector *selector = SWAMIGUI_PANEL_SELECTOR (object); switch (property_id) { case PROP_ITEM_SELECTION: g_value_set_object (value, selector->selection); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_panel_selector_finalize (GObject *object) { SwamiguiPanelSelector *selector = SWAMIGUI_PANEL_SELECTOR (object); /* set to NULL selection to remove and cache all panels, free active_panels list, * and free selection */ swamigui_panel_selector_real_set_selection (selector, NULL); if (G_OBJECT_CLASS (swamigui_panel_selector_parent_class)->finalize) G_OBJECT_CLASS (swamigui_panel_selector_parent_class)->finalize (object); } static void swamigui_panel_selector_init (SwamiguiPanelSelector *selector) { } /* We focus the notebook widget so that it doesn't focus the first widget in the * child page which gets selected. Very annoying when attempts to play piano * keyboard after switching notebook tabs causes the first entry widget to get * changed. */ static gboolean swamigui_panel_selector_button_press (GtkWidget *widget, GdkEventButton *event) { gtk_widget_grab_focus (widget); if (GTK_WIDGET_CLASS (swamigui_panel_selector_parent_class)->button_press_event) return (GTK_WIDGET_CLASS (swamigui_panel_selector_parent_class)->button_press_event (widget, event)); else return (FALSE); } /* Switch page method which gets called when page is switched. * Sets the item selection of the panel for the new page. */ static void swamigui_panel_selector_switch_page (GtkNotebook *notebook, GtkNotebookPage *page, guint page_num) { SwamiguiPanelSelector *selector = SWAMIGUI_PANEL_SELECTOR (notebook); SwamiguiPanel *panel; GList *children; if (GTK_NOTEBOOK_CLASS (swamigui_panel_selector_parent_class)->switch_page) GTK_NOTEBOOK_CLASS (swamigui_panel_selector_parent_class)->switch_page (notebook, page, page_num); children = gtk_container_get_children (GTK_CONTAINER (notebook)); /* ++ alloc */ panel = (SwamiguiPanel *)g_list_nth_data (children, page_num); if (panel) g_object_set (panel, "item-selection", selector->selection, NULL); g_list_free (children); /* -- free */ } /** * swamigui_panel_selector_new: * * Create panel selector notebook widget. * * Returns: New panel selector widget. */ GtkWidget * swamigui_panel_selector_new (void) { return ((GtkWidget *)g_object_new (SWAMIGUI_TYPE_PANEL_SELECTOR, NULL)); } /** * swamigui_panel_selector_set_selection: * @editor: Panel selector widget * @items: List of selected items or %NULL to unset selection * * Set the item selection of a panel selector widget. */ void swamigui_panel_selector_set_selection (SwamiguiPanelSelector *selector, IpatchList *items) { if (swamigui_panel_selector_real_set_selection (selector, items)) g_object_notify (G_OBJECT (selector), "item-selection"); } static gboolean swamigui_panel_selector_real_set_selection (SwamiguiPanelSelector *selector, IpatchList *selection) { GList *old_panels; GtkWidget *panel; GType *item_types; PanelInfo *info; GList *children; GList *p; int i; g_return_val_if_fail (SWAMIGUI_IS_PANEL_SELECTOR (selector), FALSE); /* treat empty list as if NULL had been passed */ if (selection && !selection->items) selection = NULL; if (!selection && !selector->selection) return (FALSE); if (selector->selection) g_object_unref (selector->selection); if (selection) selector->selection = ipatch_list_duplicate (selection); else selector->selection = NULL; old_panels = selector->active_panels; selector->active_panels = NULL; /* ++ alloc list - get list of current notebook children */ children = gtk_container_get_children (GTK_CONTAINER (selector)); if (selection) { /* get unique item types in items list (for optimization purposes) */ item_types = swamigui_panel_get_types_in_selection (selection); /* ++ alloc */ /* loop over registered panel info */ for (i = 0, p = panel_list; i < panel_count; i++, p = p->next) { info = (PanelInfo *)(p->data); /* add panel types to list for those which selection is valid */ if (swamigui_panel_type_check_selection (info->type, selection, item_types)) selector->active_panels = g_list_prepend (selector->active_panels, p->data); } g_free (item_types); /* -- free */ /* sort the list of active panel types (by their order value) */ selector->active_panels = g_list_sort (selector->active_panels, sort_panel_info_by_order); /* Add new panels (if any), may get pulled from cache instead of created */ for (p = selector->active_panels, i = 0; p; p = p->next, i++) { info = (PanelInfo *)(p->data); /* panel not in old list - create a new panel or use cached one */ if (!g_list_find (old_panels, info)) swamigui_panel_selector_insert_panel (selector, info, i); } } /* Remove old unneeded panels and cache them */ for (p = old_panels, i = 0; p; p = p->next, i++) { if (!g_list_find (selector->active_panels, p->data)) { panel = g_list_nth_data (children, i); g_object_ref (panel); /* ++ ref for cache */ gtk_container_remove (GTK_CONTAINER (selector), GTK_WIDGET (panel)); g_object_set (panel, "item-selection", NULL, NULL); panel_cache = g_list_prepend (panel_cache, panel); } } /* update "item-selection" for currently selected page */ i = gtk_notebook_get_current_page (GTK_NOTEBOOK (selector)); if (i != -1) { panel = gtk_notebook_get_nth_page (GTK_NOTEBOOK (selector), i); g_object_set (panel, "item-selection", selector->selection, NULL); } g_list_free (children); /* -- free */ g_list_free (old_panels); /* -- free old panel info list */ return (TRUE); } /* GCompareFunc for sorting list items by panel 'order' values */ static gint sort_panel_info_by_order (gconstpointer a, gconstpointer b) { PanelInfo *ainfo = (PanelInfo *)a, *binfo = (PanelInfo *)b; return (ainfo->order - binfo->order); } /* create a new panel (or use existing identical panel from cache) and add to * panel selector notebook at a given position */ static void swamigui_panel_selector_insert_panel (SwamiguiPanelSelector *selector, PanelInfo *info, int pos) { GtkWidget *hbox, *widg; GtkWidget *panel = NULL; GtkWidget *cachepanel; char *label, *blurb, *stockid; PanelInfo *cacheinfo = NULL; GList *p; /* Check if there is already a panel of the requested type in the cache */ for (p = panel_cache; p; p = p->next) { cachepanel = (GtkWidget *)(p->data); cacheinfo = g_object_get_data (G_OBJECT (cachepanel), "_SwamiguiPanelInfo"); if (cacheinfo == info) { panel = cachepanel; panel_cache = g_list_delete_link (panel_cache, p); break; } } if (!panel) /* Not found in cache? - Create it and associate with info. */ { panel = GTK_WIDGET (g_object_new (info->type, NULL)); g_object_set_data (G_OBJECT (panel), "_SwamiguiPanelInfo", info); } gtk_widget_show (panel); hbox = gtk_hbox_new (FALSE, 0); swamigui_panel_type_get_info (info->type, &label, &blurb, &stockid); if (stockid) { widg = gtk_image_new_from_stock (stockid, GTK_ICON_SIZE_SMALL_TOOLBAR); gtk_box_pack_start (GTK_BOX (hbox), widg, FALSE, FALSE, 0); } if (label) { widg = gtk_label_new (label); gtk_box_pack_start (GTK_BOX (hbox), widg, FALSE, FALSE, 0); } if (blurb) gtk_widget_set_tooltip_text (GTK_WIDGET (hbox), blurb); gtk_widget_show_all (hbox); gtk_notebook_insert_page (GTK_NOTEBOOK (selector), panel, hbox, pos); /* -- unref the panel if it was taken from the cache */ if (cacheinfo == info) g_object_unref (panel); } /** * swamigui_panel_selector_get_selection: * @selector: Panel selector widget * * Get the list of selected items for a panel selector widget. * * Returns: New list containing selected items which has a ref count of one * which the caller owns or %NULL if no items selected. Remove the * reference when finished with it. */ IpatchList * swamigui_panel_selector_get_selection (SwamiguiPanelSelector *selector) { g_return_val_if_fail (SWAMIGUI_IS_PANEL_SELECTOR (selector), NULL); if (selector->selection && selector->selection->items) return (ipatch_list_duplicate (selector->selection)); else return (NULL); } swami/src/swamigui/glade_strings.c0000644000175000017500000001431110427621306017464 0ustar alessioalessio/* * Translatable strings file generated by Glade. * Add this file to your project's POTFILES.in. * DO NOT compile it as part of your application. */ gchar *s = N_("Find"); gchar *s = N_("File:"); gchar *s = N_("Type:"); gchar *s = N_("All Files"); gchar *s = N_("Preset"); gchar *s = N_("Instrument"); gchar *s = N_("Sample"); gchar *s = N_("Start from beginning"); gchar *s = N_("Preset:"); gchar *s = N_("Name:"); gchar *s = N_("Sub string"); gchar *s = N_("Starts with"); gchar *s = N_("Bank:"); gchar *s = N_("Search"); gchar *s = N_("Close"); gchar *s = N_("Cancel"); gchar *s = N_("Percussion"); gchar *s = N_("Name:"); gchar *s = N_("Bank:"); gchar *s = N_("Preset:"); gchar *s = N_("Name:"); gchar *s = N_("Name:"); gchar *s = N_("Rate:"); gchar *s = N_("Name of sample"); gchar *s = N_("MIDI note number of original pitch"); gchar *s = N_("-"); gchar *s = N_("Sample rate"); gchar *s = N_("48000"); gchar *s = N_("44100"); gchar *s = N_("22050"); gchar *s = N_("11025"); gchar *s = N_("Tuning:"); gchar *s = N_("Fine tuning in cents"); gchar *s = N_("cents"); gchar *s = N_("Note:"); gchar *s = N_("New Sample"); gchar *s = N_("Name:"); gchar *s = N_("Import loop information"); gchar *s = N_("Raw Sample Parameters"); gchar *s = N_("Rate:"); gchar *s = N_("Custom:"); gchar *s = N_("16 bit"); gchar *s = N_("8 bit"); gchar *s = N_("Mono"); gchar *s = N_("Stereo"); gchar *s = N_("44100"); gchar *s = N_("22050"); gchar *s = N_("11025"); gchar *s = N_("Custom"); gchar *s = N_("Width:"); gchar *s = N_("Channels:"); gchar *s = N_("Endian:"); gchar *s = N_("Little"); gchar *s = N_("Big"); gchar *s = N_("Sign:"); gchar *s = N_("Signed"); gchar *s = N_("Unsigned"); gchar *s = N_("OK"); gchar *s = N_("Cancel"); gchar *s = N_("Swami Tips"); gchar *s = N_("Show tips on start up"); gchar *s = N_("Previous"); gchar *s = N_("Next"); gchar *s = N_("Close"); gchar *s = N_("Preferences"); gchar *s = N_("Patches"); gchar *s = N_("Samples"); gchar *s = N_("Search Path"); gchar *s = N_("Browse"); gchar *s = N_("Browse"); gchar *s = N_("Browse"); gchar *s = N_("Colon separated list of directories to search for"); gchar *s = N_("Default Paths"); gchar *s = N_("Swami Tips"); gchar *s = N_("Splash image"); gchar *s = N_("Restore pane geometry"); gchar *s = N_("Startup Options"); gchar *s = N_("Confirm Quit"); gchar *s = N_("Always"); gchar *s = N_("Unsaved"); gchar *s = N_("Never"); gchar *s = N_("Save window geometry"); gchar *s = N_("Save Now"); gchar *s = N_("Exit Options"); gchar *s = N_("General"); gchar *s = N_("Bank"); gchar *s = N_("Preset"); gchar *s = N_("Temporary Audible"); gchar *s = N_("Text appended to stereo channel names"); gchar *s = N_("Left"); gchar *s = N_("Right"); gchar *s = N_("Max swap file waste"); gchar *s = N_("MB"); gchar *s = N_("Patches"); gchar *s = N_("Lower Octave"); gchar *s = N_("Upper Octave"); gchar *s = N_("Change"); gchar *s = N_("Change All"); gchar *s = N_("Piano"); gchar *s = N_("OK"); gchar *s = N_("Save Preferences"); gchar *s = N_("Cancel"); gchar *s = N_("Paste conflict"); gchar *s = N_("Source"); gchar *s = N_("Modify source item"); gchar *s = N_("Modify"); gchar *s = N_("Destination"); gchar *s = N_("Modify conflict item"); gchar *s = N_("Modify"); gchar *s = N_("For"); gchar *s = N_("Remember action for other items"); gchar *s = N_("This Conflict"); gchar *s = N_("This Type"); gchar *s = N_("All"); gchar *s = N_("Skip this paste item"); gchar *s = N_("Skip"); gchar *s = N_("Replace destination"); gchar *s = N_("Replace"); gchar *s = N_("Cancel entire paste operation"); gchar *s = N_("Cancel"); gchar *s = N_("Undo History"); gchar *s = N_("Backward in state history"); gchar *s = N_("Back"); gchar *s = N_("Forward in state history"); gchar *s = N_("Forward"); gchar *s = N_("Undo previous action"); gchar *s = N_("Undo"); gchar *s = N_("Redo next action"); gchar *s = N_("Redo"); gchar *s = N_("Jump to state of selected item"); gchar *s = N_("Jump"); gchar *s = N_("Close"); gchar *s = N_("Name:"); gchar *s = N_("Author:"); gchar *s = N_("Copyright:"); gchar *s = N_("Product:"); gchar *s = N_("Date:"); gchar *s = N_("Today"); gchar *s = N_("Version:"); gchar *s = N_("Sound Engine:"); gchar *s = N_("ROM:"); gchar *s = N_("Created With:"); gchar *s = N_("Edited With:"); gchar *s = N_("Comment"); gchar *s = N_("Chan"); gchar *s = N_("Preset"); gchar *s = N_("Bank"); gchar *s = N_("New"); gchar *s = N_("Delete"); gchar *s = N_("Source"); gchar *s = N_("Destination"); gchar *s = N_("Amount"); gchar *s = N_("Amount Source"); gchar *s = N_("Root Note"); gchar *s = N_("Exclusive Class"); gchar *s = N_("Fixed Note"); gchar *s = N_("Fixed Velocity"); gchar *s = N_("Set"); gchar *s = N_("Set"); gchar *s = N_("Set"); gchar *s = N_("Set"); gchar *s = N_("File"); gchar *s = N_("Edit"); gchar *s = N_("Plugins"); gchar *s = N_("Help"); gchar *s = N_("Swami Tips"); gchar *s = N_("About"); gchar *s = N_("Swami"); gchar *s = N_("Copyright (C) 1999-2006 Josh Green"); gchar *s = N_("Distributed under the GNU General Public License"); gchar *s = N_("translator-credits"); gchar *s = N_("Loop Finder"); gchar *s = N_("Sample"); gchar *s = N_("Length"); gchar *s = N_("Results"); gchar *s = N_("Min loop size"); gchar *s = N_("Size of analysis window (affects quality of results)"); gchar *s = N_("Minimum length of matching loops"); gchar *s = N_("Maximum loop suggestion results"); gchar *s = N_("Analysis window"); gchar *s = N_("Max results"); gchar *s = N_("Loop end"); gchar *s = N_("Loop start"); gchar *s = N_("Loop end search area position"); gchar *s = N_("Loop start search area position"); gchar *s = N_("Position"); gchar *s = N_("Loop start search area size"); gchar *s = N_("Loop end search area size"); gchar *s = N_("Search entire sample for loop start"); gchar *s = N_("Entire Sample"); gchar *s = N_("Search entire sample for loop end"); gchar *s = N_("Entire sample"); gchar *s = N_("Size"); gchar *s = N_("Search area"); gchar *s = N_("Revert to original loop values"); gchar *s = N_("0.00 secs"); gchar *s = N_("window1"); gchar *s = N_(" Name"); gchar *s = N_("Save current script"); gchar *s = N_("Create new script"); gchar *s = N_("Execute current script"); gchar *s = N_("Execute a line when ENTER is pressed"); gchar *s = N_("Shell mode"); gchar *s = N_("Script Editor"); gchar *s = N_("Python Console"); swami/src/swamigui/SwamiguiLoopFinder.h0000644000175000017500000000422311461334205020412 0ustar alessioalessio/* * SwamiguiLoopFinder.h - Sample loop finder widget * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_LOOP_FINDER_H__ #define __SWAMIGUI_LOOP_FINDER_H__ #include #include typedef struct _SwamiguiLoopFinder SwamiguiLoopFinder; typedef struct _SwamiguiLoopFinderClass SwamiguiLoopFinderClass; #define SWAMIGUI_TYPE_LOOP_FINDER (swamigui_loop_finder_get_type ()) #define SWAMIGUI_LOOP_FINDER(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMIGUI_TYPE_LOOP_FINDER, \ SwamiguiLoopFinder)) #define SWAMIGUI_IS_LOOP_FINDER(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMIGUI_TYPE_LOOP_FINDER)) /* Loop finder object */ struct _SwamiguiLoopFinder { GtkVBox parent_instance; /* derived from GtkVBox */ GtkListStore *store; /* list store for results */ GtkWidget *glade_widg; /* the embedded glade widget */ guint orig_loop_start; /* original loop start of current sample */ guint orig_loop_end; /* original loop end of current sample */ float prev_progress; /* progress value caching */ /*< public >*/ SwamiLoopFinder *loop_finder; /* loop finder object instance */ }; /* Loop finder widget class */ struct _SwamiguiLoopFinderClass { GtkVBoxClass parent_class; }; GType swamigui_loop_finder_get_type (void); GtkWidget *swamigui_loop_finder_new (void); void swamigui_loop_finder_clear_results (SwamiguiLoopFinder *finder); #endif swami/src/swamigui/i18n.h0000644000175000017500000000062510075302551015423 0ustar alessioalessio#ifndef __SWAMIGUI_I18N_H__ #define __SWAMIGUI_I18N_H__ #include #ifndef _ #if defined(ENABLE_NLS) # include # define _(x) gettext(x) # ifdef gettext_noop # define N_(String) gettext_noop (String) # else # define N_(String) (String) # endif #else # define N_(String) (String) # define _(x) (x) # define gettext(x) (x) #endif #endif #endif /* __SWAMIGUI_I18N_H__ */ swami/src/swamigui/SwamiguiItemMenu_actions.c0000644000175000017500000003377111461334205021621 0ustar alessioalessio/* * SwamiguiTreeMenu_items.c - Built in menu items * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include "SwamiguiItemMenu.h" #include "icons.h" #include "patch_funcs.h" #include "i18n.h" static void item_action_paste_handler (SwamiguiItemMenu *menu, const char *action_id); static void item_action_goto_link_handler (SwamiguiItemMenu *menu, const char *action_id); static void item_action_load_samples_handler (SwamiguiItemMenu *menu, const char *action_id); static void item_action_new_handler (SwamiguiItemMenu *menu, const char *action_id); static void item_cb_paste_items (IpatchList *selection, gpointer data); static void item_cb_find_item (IpatchList *selection, gpointer data); static void item_cb_find_next_item (IpatchList *selection, gpointer data); static void item_cb_goto_link_item (IpatchList *selection, gpointer data); static void item_cb_load_samples (IpatchList *selection, gpointer data); static void item_cb_new (IpatchList *selection, gpointer data); static void item_cb_solo_toggle (IpatchList *selection, gpointer data); typedef struct { char *action_id; SwamiguiItemMenuHandler handler; SwamiguiItemMenuInfo info; } MultiActionInfo; MultiActionInfo item_action_info[] = { { "copy", swamigui_item_menu_handler_multi, { 100, N_("_Copy"), "C", GTK_STOCK_COPY, 0, (SwamiguiItemMenuCallback)swamigui_copy_items, NULL } }, { "paste", item_action_paste_handler, { 200, N_("_Paste"), "V", GTK_STOCK_PASTE, 0, (SwamiguiItemMenuCallback)item_cb_paste_items, NULL } }, { "delete", swamigui_item_menu_handler_multi, { 300, N_("_Delete"), "D", GTK_STOCK_DELETE, 0, (SwamiguiItemMenuCallback)swamigui_delete_items, NULL } }, { "find", swamigui_item_menu_handler_single_all, { 400, N_("_Find"), "F", GTK_STOCK_FIND, 0, item_cb_find_item, NULL } }, { "find-next", swamigui_item_menu_handler_single_all, { 410, N_("Find _Next"), "G", GTK_STOCK_FIND, 0, item_cb_find_next_item, NULL } }, { "goto-link", item_action_goto_link_handler, { 500, N_("_Goto Link"), "L", GTK_STOCK_JUMP_TO, 0, item_cb_goto_link_item, NULL } }, { "save", swamigui_item_menu_handler_multi, { 600, N_("_Save"), "S", GTK_STOCK_SAVE, 0, (SwamiguiItemMenuCallback)swamigui_save_files, GINT_TO_POINTER (FALSE) } }, { "save-as", swamigui_item_menu_handler_multi, { 700, N_("Save _As"), NULL, GTK_STOCK_SAVE_AS, 0, (SwamiguiItemMenuCallback)swamigui_save_files, GINT_TO_POINTER(TRUE) } }, { "close", swamigui_item_menu_handler_multi, { 800, N_("Close"), "W", GTK_STOCK_CLOSE, 0, (SwamiguiItemMenuCallback)swamigui_close_files, NULL } }, { "load-samples", item_action_load_samples_handler, { 900, N_("Load Samples"), NULL, GTK_STOCK_OPEN, 0, item_cb_load_samples, NULL } }, { "export-samples", swamigui_item_menu_handler_multi, { 1000, N_("Export Samples"), NULL, GTK_STOCK_SAVE, 0, (SwamiguiItemMenuCallback)swamigui_export_samples, NULL } }, { "solo-item", swamigui_item_menu_handler_single, { 1100, N_("Solo Toggle"), "T", GTK_STOCK_MEDIA_PLAY, 0, (SwamiguiItemMenuCallback)item_cb_solo_toggle, NULL } }, /* some of these fields are dynamically generated by the handler */ { "new", item_action_new_handler, { 1100, "", NULL, GTK_STOCK_NEW, 0, item_cb_new, NULL } } }; void _swamigui_item_menu_actions_init (void) { GValue value = { 0 }; GType *types; guint count, i; /* register the item actions */ for (i = 0; i < G_N_ELEMENTS (item_action_info); i++) { swamigui_register_item_menu_action (item_action_info[i].action_id, &item_action_info[i].info, item_action_info[i].handler); } swamigui_register_item_menu_include_type ("copy", IPATCH_TYPE_ITEM, TRUE); swamigui_register_item_menu_exclude_type ("copy", IPATCH_TYPE_VIRTUAL_CONTAINER, TRUE); swamigui_register_item_menu_include_type ("paste", IPATCH_TYPE_CONTAINER, TRUE); swamigui_register_item_menu_include_type ("paste", IPATCH_TYPE_VIRTUAL_CONTAINER, TRUE); swamigui_register_item_menu_include_type ("delete", IPATCH_TYPE_ITEM, TRUE); swamigui_register_item_menu_exclude_type ("delete", IPATCH_TYPE_BASE, TRUE); swamigui_register_item_menu_exclude_type ("delete", IPATCH_TYPE_VIRTUAL_CONTAINER, TRUE); swamigui_register_item_menu_include_type ("export-samples", IPATCH_TYPE_SAMPLE, TRUE); swamigui_register_item_menu_include_type ("save", IPATCH_TYPE_ITEM, TRUE); swamigui_register_item_menu_include_type ("save-as", IPATCH_TYPE_ITEM, TRUE); swamigui_register_item_menu_include_type ("close", IPATCH_TYPE_BASE, TRUE); /* Add types for solo-item action to instrument ref and sample ref category types */ g_value_init (&value, G_TYPE_INT); g_value_set_int (&value, IPATCH_CATEGORY_INSTRUMENT_REF); types = ipatch_type_find_types_with_property ("category", &value, &count); /* ++ alloc types */ if (types) { for (i = 0; i < count; i++) swamigui_register_item_menu_include_type ("solo-item", types[i], TRUE); g_free (types); /* -- unref types */ } g_value_set_int (&value, IPATCH_CATEGORY_SAMPLE_REF); types = ipatch_type_find_types_with_property ("category", &value, &count); /* ++ alloc types */ if (types) { for (i = 0; i < count; i++) swamigui_register_item_menu_include_type ("solo-item", types[i], TRUE); g_free (types); /* -- unref types */ } #if 0 { "wavetbl-load", N_("Wavetable Load"), "L", 0, swamigui_ifaces_cb_wtbl_load_patch, NULL } #endif } static void item_action_paste_handler (SwamiguiItemMenu *menu, const char *action_id) { GObject *item; item = swamigui_item_menu_get_selection_single (menu); if (!item) return; /* if item type matches an exclude type - return */ if (!swamigui_test_item_menu_exclude_type (action_id, G_OBJECT_TYPE (item))) return; /* if item does not match an include type.. */ if (!swamigui_test_item_menu_include_type (action_id, G_OBJECT_TYPE (item))) { GType link_type; /* IpatchItem's with a link type are valid */ ipatch_type_get (G_OBJECT_TYPE (item), "link-type", &link_type, NULL); if (!IPATCH_IS_ITEM (item) || link_type == G_TYPE_NONE) return; } swamigui_item_menu_add_registered_info (menu, action_id); } static void item_action_goto_link_handler (SwamiguiItemMenu *menu, const char *action_id) { IpatchList *list; GObject *item, *origin; list = swamigui_item_menu_get_selection (menu); /* make sure exactly one item is selected */ if (!list || !list->items || list->items->next) return; /* only makes sense to goto link if a tree is the origin of selection */ origin = swami_object_get_origin (G_OBJECT (list)); if (!origin || !SWAMIGUI_IS_TREE (origin)) return; item = (GObject *)(list->items->data); /* if item type matches an exclude type - return */ if (!swamigui_test_item_menu_exclude_type (action_id, G_OBJECT_TYPE (item))) return; /* if item does not match an include type.. */ if (!swamigui_test_item_menu_include_type (action_id, G_OBJECT_TYPE (item))) { GType link_type; GObject *link; /* if object has link-type type property and link-item property is set, create menu item */ ipatch_type_get (G_OBJECT_TYPE (item), "link-type", &link_type, NULL); if (!IPATCH_IS_ITEM (item) || link_type == G_TYPE_NONE) return; g_object_get (item, "link-item", &link, NULL); if (link) g_object_unref (link); if (!link) return; } swamigui_item_menu_add_registered_info (menu, action_id); } static void item_action_load_samples_handler (SwamiguiItemMenu *menu, const char *action_id) { GObject *item; const GType *child_types, child; int category; item = swamigui_item_menu_get_selection_single (menu); if (!item) return; /* if item type matches an exclude type - return */ if (!swamigui_test_item_menu_exclude_type (action_id, G_OBJECT_TYPE (item))) return; /* if item does not match an include type.. */ if (!swamigui_test_item_menu_include_type (action_id, G_OBJECT_TYPE (item))) { /* virtual container which contains sample category items? - Add */ if (IPATCH_IS_VIRTUAL_CONTAINER (item)) { ipatch_type_get (G_OBJECT_TYPE (item), "virtual-child-type", &child, NULL); if (child == G_TYPE_NONE) return; ipatch_type_get (child, "category", &category, NULL); if (category != IPATCH_CATEGORY_SAMPLE) return; } else /* IpatchBase derived and has child item with sample category? - add */ { if (!IPATCH_IS_BASE (item)) return; child_types = ipatch_container_get_child_types (IPATCH_CONTAINER (item)); for (; *child_types; child_types++) { ipatch_type_get (*child_types, "category", &category, NULL); if (category == IPATCH_CATEGORY_SAMPLE) break; } if (!*child_types) return; } } swamigui_item_menu_add_registered_info (menu, action_id); } static void item_action_new_handler (SwamiguiItemMenu *menu, const char *action_id) { GObject *item; const GType *child_types; GType type; SwamiguiItemMenuInfo newinfo, *infop; char *type_name; int category; item = swamigui_item_menu_get_selection_single (menu); if (!item) return; /* if item type matches an exclude type - return */ if (!swamigui_test_item_menu_exclude_type (action_id, G_OBJECT_TYPE (item))) return; if (IPATCH_IS_VIRTUAL_CONTAINER (item)) { swamigui_lookup_item_menu_action (action_id, &infop, NULL); newinfo = *infop; ipatch_type_get (G_OBJECT_TYPE (item), "virtual-child-type", &type, NULL); if (type == G_TYPE_NONE) return; /* only New for Program and Instrument types */ ipatch_type_get (type, "category", &category, NULL); if (category != IPATCH_CATEGORY_PROGRAM && category != IPATCH_CATEGORY_INSTRUMENT) return; ipatch_type_get (type, "name", &type_name, NULL); newinfo.label = g_strdup_printf (_("New %s"), type_name ? type_name : g_type_name (type)); g_free (type_name); newinfo.data = GUINT_TO_POINTER (type); swamigui_item_menu_add (menu, &newinfo, action_id); g_free (newinfo.label); return; } if (!IPATCH_IS_CONTAINER (item)) return; swamigui_lookup_item_menu_action (action_id, &infop, NULL); newinfo = *infop; child_types = ipatch_container_get_child_types (IPATCH_CONTAINER (item)); for (; *child_types; child_types++) { /* skip any types in exclude list */ if (!swamigui_test_item_menu_exclude_type (action_id, *child_types)) continue; /* only New for Program and Instrument types */ ipatch_type_get (*child_types, "category", &category, NULL); if (category != IPATCH_CATEGORY_PROGRAM && category != IPATCH_CATEGORY_INSTRUMENT) continue; newinfo.order++; ipatch_type_get (*child_types, "name", &type_name, NULL); newinfo.label = g_strdup_printf (_("New %s"), type_name ? type_name : g_type_name (*child_types)); g_free (type_name); newinfo.data = GUINT_TO_POINTER (*child_types); swamigui_item_menu_add (menu, &newinfo, action_id); g_free (newinfo.label); } } /* SwamiguiItemMenu action callbacks */ static void item_cb_paste_items (IpatchList *selection, gpointer data) { if (!selection->items || selection->items->next) return; swamigui_paste_items (IPATCH_ITEM (selection->items->data), NULL); } static void item_cb_find_item (IpatchList *selection, gpointer data) { GObject *origin; /* ++ ref origin object */ origin = swami_object_get_origin (G_OBJECT (selection)); if (!origin || !SWAMIGUI_IS_TREE (origin)) return; swamigui_tree_search_set_visible (SWAMIGUI_TREE (origin), TRUE); g_object_unref (origin); /* -- unref */ } static void item_cb_find_next_item (IpatchList *selection, gpointer data) { GObject *origin; /* ++ ref origin object */ origin = swami_object_get_origin (G_OBJECT (selection)); if (!origin || !SWAMIGUI_IS_TREE (origin)) return; swamigui_tree_search_next (SWAMIGUI_TREE (origin)); g_object_unref (origin); /* -- unref */ } static void item_cb_goto_link_item (IpatchList *selection, gpointer data) { GObject *origin; if (!selection->items || selection->items->next) return; /* ++ ref origin object */ origin = swami_object_get_origin (G_OBJECT (selection)); if (!origin || !SWAMIGUI_IS_TREE (origin)) return; swamigui_goto_link_item (IPATCH_ITEM (selection->items->data), SWAMIGUI_TREE (origin)); g_object_unref (origin); /* -- unref */ } static void item_cb_load_samples (IpatchList *selection, gpointer data) { if (!selection->items || selection->items->next) return; swamigui_load_samples (IPATCH_ITEM (selection->items->data)); } static void item_cb_new (IpatchList *selection, gpointer data) { if (!selection->items || selection->items->next) return; swamigui_new_item (IPATCH_ITEM (selection->items->data), (GType)GPOINTER_TO_UINT (data)); } static void item_cb_solo_toggle (IpatchList *selection, gpointer data) { gboolean enabled; if (!selection->items || selection->items->next) return; /* Toggle solo-item-enable property of swamiguiroot */ g_object_get (swamigui_root, "solo-item-enable", &enabled, NULL); g_object_set (swamigui_root, "solo-item-enable", !enabled, NULL); } swami/src/swamigui/SwamiguiSampleCanvas.c0000644000175000017500000010767311461334205020736 0ustar alessioalessio/* * SwamiguiSampleCanvas.c - Sample data canvas widget * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include "SwamiguiSampleCanvas.h" #include "util.h" #include "i18n.h" /* Sample format used internally */ #define SAMPLE_FORMAT IPATCH_SAMPLE_16BIT | IPATCH_SAMPLE_ENDIAN_HOST | IPATCH_SAMPLE_MONO enum { PROP_0, PROP_SAMPLE, /* sample to display */ PROP_RIGHT_CHAN, /* if sample data is stereo: use right channel? */ PROP_LOOP_MODE, /* set loop mode */ PROP_LOOP_START, /* start of loop */ PROP_LOOP_END, /* end of loop */ PROP_ADJUSTMENT, /* adjustment control */ PROP_UPDATE_ADJ, /* update adjustment values? */ PROP_X, /* x position in pixels */ PROP_Y, /* y position in pixels */ PROP_WIDTH, /* width of view in pixels */ PROP_HEIGHT, /* height of view in pixels */ PROP_START, /* sample start position */ PROP_ZOOM, /* zoom value */ PROP_ZOOM_AMPL, /* amplitude zoom */ PROP_PEAK_LINE_COLOR, /* color of peak sample lines */ PROP_LINE_COLOR, /* color of connecting sample lines */ PROP_POINT_COLOR, /* color of sample points */ PROP_LOOP_START_COLOR, /* color of sample points for start of loop */ PROP_LOOP_END_COLOR /* color of sample points for end of loop */ }; #define DEFAULT_PEAK_LINE_COLOR GNOME_CANVAS_COLOR (63, 69, 255) #define DEFAULT_LINE_COLOR GNOME_CANVAS_COLOR (63, 69, 255) #define DEFAULT_POINT_COLOR GNOME_CANVAS_COLOR (170, 170, 255) #define DEFAULT_LOOP_START_COLOR GNOME_CANVAS_COLOR (0, 255, 0) #define DEFAULT_LOOP_END_COLOR GNOME_CANVAS_COLOR (255, 0, 0) static void swamigui_sample_canvas_finalize (GObject *object); static void swamigui_sample_canvas_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void swamigui_sample_canvas_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void swamigui_sample_canvas_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags); static void swamigui_sample_canvas_realize (GnomeCanvasItem *item); static void set_gc_rgb (GdkGC *gc, guint color); static void swamigui_sample_canvas_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, int height); static inline void swamigui_sample_canvas_draw_loop (SwamiguiSampleCanvas *canvas, GdkDrawable *drawable, int x, int y, int width, int height); static inline void swamigui_sample_canvas_draw_points (SwamiguiSampleCanvas *canvas, GdkDrawable *drawable, int x, int y, int width, int height); static inline void swamigui_sample_canvas_draw_segments (SwamiguiSampleCanvas *canvas, GdkDrawable *drawable, int x, int y, int width, int height); static double swamigui_sample_canvas_point (GnomeCanvasItem *item, double x, double y, int cx, int cy, GnomeCanvasItem **actual_item); static void swamigui_sample_canvas_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2); static void swamigui_sample_canvas_cb_adjustment_value_changed (GtkAdjustment *adj, gpointer user_data); static gboolean swamigui_sample_canvas_real_set_sample (SwamiguiSampleCanvas *canvas, IpatchSampleData *sample); static void swamigui_sample_canvas_update_adjustment (SwamiguiSampleCanvas *canvas); G_DEFINE_TYPE (SwamiguiSampleCanvas, swamigui_sample_canvas, GNOME_TYPE_CANVAS_ITEM) static void swamigui_sample_canvas_class_init (SwamiguiSampleCanvasClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); GnomeCanvasItemClass *item_class = GNOME_CANVAS_ITEM_CLASS (klass); obj_class->set_property = swamigui_sample_canvas_set_property; obj_class->get_property = swamigui_sample_canvas_get_property; obj_class->finalize = swamigui_sample_canvas_finalize; item_class->update = swamigui_sample_canvas_update; item_class->realize = swamigui_sample_canvas_realize; item_class->draw = swamigui_sample_canvas_draw; item_class->point = swamigui_sample_canvas_point; item_class->bounds = swamigui_sample_canvas_bounds; /* FIXME - Is there a better way to define an interface object property? */ g_object_class_install_property (obj_class, PROP_SAMPLE, g_param_spec_object ("sample", _("Sample"), _("Sample object"), IPATCH_TYPE_SAMPLE_DATA, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_RIGHT_CHAN, g_param_spec_boolean ("right-chan", _("Right Channel"), _("Use right channel of stereo samples"), FALSE, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_LOOP_MODE, g_param_spec_boolean ("loop-mode", _("Loop Mode"), _("Enable/disable loop mode"), FALSE, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_LOOP_START, g_param_spec_uint ("loop-start", _("Loop Start"), _("Start of loop in samples"), 0, G_MAXUINT, 0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_LOOP_END, g_param_spec_uint ("loop-end", _("Loop end"), _("End of loop in samples"), 0, G_MAXUINT, 0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_ADJUSTMENT, g_param_spec_object ("adjustment", _("Adjustment"), _("Adjustment control for scrolling"), GTK_TYPE_ADJUSTMENT, G_PARAM_READWRITE)); /* FIXME - better way to handle this?? Problems with recursive updates when multiple SwamiguiSampleCanvas items are on a canvas. */ g_object_class_install_property (obj_class, PROP_UPDATE_ADJ, g_param_spec_boolean ("update-adj", _("Update adjustment"), _("Update adjustment object"), FALSE, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_X, g_param_spec_int ("x", "X", _("X position in pixels"), 0, G_MAXINT, 0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_Y, g_param_spec_int ("y", "Y", _("Y position in pixels"), 0, G_MAXINT, 0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_WIDTH, g_param_spec_int ("width", _("Width"), _("Width in pixels"), 0, G_MAXINT, 1, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_HEIGHT, g_param_spec_int ("height", _("Height"), _("Height in pixels"), 0, G_MAXINT, 1, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_START, g_param_spec_uint ("start", _("View Start"), _("Start of view in samples"), 0, G_MAXUINT, 0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_ZOOM, g_param_spec_double ("zoom", _("Zoom"), _("Zoom factor in samples per pixel"), 0.0, G_MAXDOUBLE, 1.0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_ZOOM_AMPL, g_param_spec_double ("zoom-ampl", _("Zoom Amplitude"), _("Amplitude zoom factor"), 0.0, G_MAXDOUBLE, 1.0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_PEAK_LINE_COLOR, ipatch_param_set (g_param_spec_uint ("peak-line-color", _("Peak line color"), _("Color of peak sample lines"), 0, G_MAXUINT, DEFAULT_PEAK_LINE_COLOR, G_PARAM_READWRITE), "unit-type", SWAMIGUI_UNIT_RGBA_COLOR, NULL)); g_object_class_install_property (obj_class, PROP_LINE_COLOR, ipatch_param_set (g_param_spec_uint ("line-color", _("Line color"), _("Color of sample connecting lines"), 0, G_MAXUINT, DEFAULT_LINE_COLOR, G_PARAM_READWRITE), "unit-type", SWAMIGUI_UNIT_RGBA_COLOR, NULL)); g_object_class_install_property (obj_class, PROP_POINT_COLOR, ipatch_param_set (g_param_spec_uint ("point-color", _("Point color"), _("Color of sample points"), 0, G_MAXUINT, DEFAULT_POINT_COLOR, G_PARAM_READWRITE), "unit-type", SWAMIGUI_UNIT_RGBA_COLOR, NULL)); g_object_class_install_property (obj_class, PROP_LOOP_START_COLOR, ipatch_param_set (g_param_spec_uint ("loop-start-color", _("Loop start color"), _("Color of loop start sample points"), 0, G_MAXUINT, DEFAULT_LOOP_START_COLOR, G_PARAM_READWRITE), "unit-type", SWAMIGUI_UNIT_RGBA_COLOR, NULL)); g_object_class_install_property (obj_class, PROP_LOOP_END_COLOR, ipatch_param_set (g_param_spec_uint ("loop-end-color", _("Loop end color"), _("Color of loop end sample points"), 0, G_MAXUINT, DEFAULT_LOOP_END_COLOR, G_PARAM_READWRITE), "unit-type", SWAMIGUI_UNIT_RGBA_COLOR, NULL)); } static void swamigui_sample_canvas_init (SwamiguiSampleCanvas *canvas) { canvas->adj = (GtkAdjustment *)gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0); g_object_ref (canvas->adj); canvas->update_adj = FALSE; g_signal_connect (canvas->adj, "value-changed", G_CALLBACK (swamigui_sample_canvas_cb_adjustment_value_changed), canvas); canvas->sample = NULL; canvas->sample_size = 0; canvas->right_chan = FALSE; canvas->loop_mode = FALSE; canvas->loop_start = 0; canvas->loop_end = 1; canvas->start = 0; canvas->zoom = 1.0; canvas->zoom_ampl = 1.0; canvas->x = 0; canvas->y = 0; canvas->width = 0; canvas->height = 0; canvas->peak_line_color = DEFAULT_PEAK_LINE_COLOR; canvas->line_color = DEFAULT_LINE_COLOR; canvas->point_color = DEFAULT_POINT_COLOR; canvas->loop_start_color = DEFAULT_LOOP_START_COLOR; canvas->loop_end_color = DEFAULT_LOOP_END_COLOR; } static void swamigui_sample_canvas_finalize (GObject *object) { SwamiguiSampleCanvas *canvas = SWAMIGUI_SAMPLE_CANVAS (object); if (canvas->sample) { ipatch_sample_handle_close (&canvas->handle); g_object_unref (canvas->sample); } if (canvas->adj) { g_signal_handlers_disconnect_by_func (canvas->adj, G_CALLBACK (swamigui_sample_canvas_cb_adjustment_value_changed), canvas); g_object_unref (canvas->adj); } if (canvas->peak_line_gc) g_object_unref (canvas->peak_line_gc); if (canvas->line_gc) g_object_unref (canvas->line_gc); if (canvas->point_gc) g_object_unref (canvas->point_gc); if (canvas->loop_start_gc) g_object_unref (canvas->loop_start_gc); if (canvas->loop_end_gc) g_object_unref (canvas->loop_end_gc); if (G_OBJECT_CLASS (swamigui_sample_canvas_parent_class)->finalize) (*G_OBJECT_CLASS (swamigui_sample_canvas_parent_class)->finalize) (object); } static void swamigui_sample_canvas_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { GnomeCanvasItem *item = GNOME_CANVAS_ITEM (object); SwamiguiSampleCanvas *canvas = SWAMIGUI_SAMPLE_CANVAS (object); IpatchSampleData *sample; GtkAdjustment *gtkadj; gboolean b; switch (property_id) { case PROP_SAMPLE: swamigui_sample_canvas_real_set_sample (canvas, IPATCH_SAMPLE_DATA (g_value_get_object (value))); break; case PROP_RIGHT_CHAN: b = g_value_get_boolean (value); if (b != canvas->right_chan) { canvas->right_chan = b; if (canvas->sample) /* Unset and then re-assign the sample */ { sample = g_object_ref (canvas->sample); /* ++ temp ref */ swamigui_sample_canvas_real_set_sample (canvas, NULL); swamigui_sample_canvas_real_set_sample (canvas, sample); g_object_unref (canvas->sample); /* -- temp unref */ } } break; case PROP_LOOP_MODE: canvas->loop_mode = g_value_get_boolean (value); gnome_canvas_item_request_update (item); break; case PROP_LOOP_START: canvas->loop_start = g_value_get_uint (value); gnome_canvas_item_request_update (item); break; case PROP_LOOP_END: canvas->loop_end = g_value_get_uint (value); gnome_canvas_item_request_update (item); break; case PROP_ADJUSTMENT: gtkadj = g_value_get_object (value); g_return_if_fail (GTK_IS_ADJUSTMENT (gtkadj)); g_signal_handlers_disconnect_by_func (canvas->adj, G_CALLBACK (swamigui_sample_canvas_cb_adjustment_value_changed), canvas); g_object_unref (canvas->adj); canvas->adj = GTK_ADJUSTMENT (g_object_ref (gtkadj)); g_signal_connect (canvas->adj, "value-changed", G_CALLBACK (swamigui_sample_canvas_cb_adjustment_value_changed), canvas); /* only initialize adjustment if updates enabled */ if (canvas->update_adj) swamigui_sample_canvas_update_adjustment (canvas); break; case PROP_UPDATE_ADJ: canvas->update_adj = g_value_get_boolean (value); break; case PROP_X: canvas->x = g_value_get_int (value); canvas->need_bbox_update = TRUE; gnome_canvas_item_request_update (item); break; case PROP_Y: canvas->y = g_value_get_int (value); canvas->need_bbox_update = TRUE; gnome_canvas_item_request_update (item); break; case PROP_WIDTH: canvas->width = g_value_get_int (value); canvas->need_bbox_update = TRUE; gnome_canvas_item_request_update (item); /* only update adjustment if updates enabled */ if (canvas->update_adj) { canvas->adj->page_size = canvas->width * canvas->zoom; gtk_adjustment_changed (canvas->adj); } break; case PROP_HEIGHT: canvas->height = g_value_get_int (value); canvas->need_bbox_update = TRUE; gnome_canvas_item_request_update (item); break; case PROP_START: canvas->start = g_value_get_uint (value); gnome_canvas_item_request_update (item); /* only update adjustment if updates enabled */ if (canvas->update_adj) { canvas->adj->value = canvas->start; g_signal_handlers_block_by_func (canvas->adj, swamigui_sample_canvas_cb_adjustment_value_changed, canvas); gtk_adjustment_value_changed (canvas->adj); g_signal_handlers_unblock_by_func (canvas->adj, swamigui_sample_canvas_cb_adjustment_value_changed, canvas); } break; case PROP_ZOOM: canvas->zoom = g_value_get_double (value); gnome_canvas_item_request_update (item); /* only update adjustment if updates enabled */ if (canvas->update_adj) { canvas->adj->page_size = canvas->width * canvas->zoom; gtk_adjustment_changed (canvas->adj); } break; case PROP_ZOOM_AMPL: canvas->zoom_ampl = g_value_get_double (value); gnome_canvas_item_request_update (item); break; case PROP_PEAK_LINE_COLOR: canvas->peak_line_color = g_value_get_uint (value); set_gc_rgb (canvas->peak_line_gc, canvas->peak_line_color); gnome_canvas_item_request_update (item); break; case PROP_LINE_COLOR: canvas->line_color = g_value_get_uint (value); set_gc_rgb (canvas->line_gc, canvas->line_color); gnome_canvas_item_request_update (item); break; case PROP_POINT_COLOR: canvas->point_color = g_value_get_uint (value); set_gc_rgb (canvas->point_gc, canvas->point_color); gnome_canvas_item_request_update (item); break; case PROP_LOOP_START_COLOR: canvas->loop_start_color = g_value_get_uint (value); set_gc_rgb (canvas->loop_start_gc, canvas->loop_start_color); gnome_canvas_item_request_update (item); break; case PROP_LOOP_END_COLOR: canvas->loop_end_color = g_value_get_uint (value); set_gc_rgb (canvas->loop_end_gc, canvas->loop_end_color); gnome_canvas_item_request_update (item); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); return; /* return, to skip code below */ } } static void swamigui_sample_canvas_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { SwamiguiSampleCanvas *canvas = SWAMIGUI_SAMPLE_CANVAS (object); switch (property_id) { case PROP_SAMPLE: g_value_set_object (value, canvas->sample); break; case PROP_RIGHT_CHAN: g_value_set_boolean (value, canvas->right_chan); break; case PROP_LOOP_MODE: g_value_set_boolean (value, canvas->loop_mode); break; case PROP_LOOP_START: g_value_set_uint (value, canvas->loop_start); break; case PROP_LOOP_END: g_value_set_uint (value, canvas->loop_end); break; case PROP_ADJUSTMENT: g_value_set_object (value, canvas->adj); break; case PROP_UPDATE_ADJ: g_value_set_boolean (value, canvas->update_adj); break; case PROP_X: g_value_set_int (value, canvas->x); break; case PROP_Y: g_value_set_int (value, canvas->y); break; case PROP_WIDTH: g_value_set_int (value, canvas->width); break; case PROP_HEIGHT: g_value_set_int (value, canvas->height); break; case PROP_START: g_value_set_uint (value, canvas->start); break; case PROP_ZOOM: g_value_set_double (value, canvas->zoom); break; case PROP_ZOOM_AMPL: g_value_set_double (value, canvas->zoom_ampl); break; case PROP_PEAK_LINE_COLOR: g_value_set_uint (value, canvas->peak_line_color); break; case PROP_LINE_COLOR: g_value_set_uint (value, canvas->line_color); break; case PROP_POINT_COLOR: g_value_set_uint (value, canvas->point_color); break; case PROP_LOOP_START_COLOR: g_value_set_uint (value, canvas->loop_start_color); break; case PROP_LOOP_END_COLOR: g_value_set_uint (value, canvas->loop_end_color); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } /* Gnome canvas item update handler */ static void swamigui_sample_canvas_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags) { SwamiguiSampleCanvas *canvas = SWAMIGUI_SAMPLE_CANVAS (item); if (((flags & GNOME_CANVAS_UPDATE_VISIBILITY) && !(GTK_OBJECT_FLAGS (item) & GNOME_CANVAS_ITEM_VISIBLE)) || (flags & GNOME_CANVAS_UPDATE_AFFINE) || canvas->need_bbox_update) { canvas->need_bbox_update = FALSE; gnome_canvas_update_bbox (item, canvas->x, canvas->y, canvas->x + canvas->width, canvas->y + canvas->height); } else gnome_canvas_request_redraw (item->canvas, canvas->x, canvas->y, canvas->x + canvas->width, canvas->y + canvas->height); if (GNOME_CANVAS_ITEM_CLASS (swamigui_sample_canvas_parent_class)->update) GNOME_CANVAS_ITEM_CLASS (swamigui_sample_canvas_parent_class)->update (item, affine, clip_path, flags); } static void swamigui_sample_canvas_realize (GnomeCanvasItem *item) { SwamiguiSampleCanvas *canvas = SWAMIGUI_SAMPLE_CANVAS (item); GdkDrawable *drawable; if (GNOME_CANVAS_ITEM_CLASS (swamigui_sample_canvas_parent_class)->realize) GNOME_CANVAS_ITEM_CLASS (swamigui_sample_canvas_parent_class)->realize (item); if (canvas->peak_line_gc) return; /* return if GCs already created */ drawable = item->canvas->layout.bin_window; canvas->peak_line_gc = gdk_gc_new (drawable); /* ++ ref */ set_gc_rgb (canvas->peak_line_gc, canvas->peak_line_color); canvas->line_gc = gdk_gc_new (drawable); /* ++ ref */ set_gc_rgb (canvas->line_gc, canvas->line_color); canvas->point_gc = gdk_gc_new (drawable);/* ++ ref */ set_gc_rgb (canvas->point_gc, canvas->point_color); canvas->loop_start_gc = gdk_gc_new (drawable); /* ++ ref */ set_gc_rgb (canvas->loop_start_gc, canvas->loop_start_color); canvas->loop_end_gc = gdk_gc_new (drawable); /* ++ ref */ set_gc_rgb (canvas->loop_end_gc, canvas->loop_end_color); gdk_gc_set_function (canvas->loop_end_gc, GDK_XOR); } /* sets fg color of a Graphics Context to 32 bit GnomeCanvas style RGB value */ static void set_gc_rgb (GdkGC *gc, guint color) { GdkColor gdkcolor; gdkcolor.pixel = 0; gdkcolor.red = (((color >> 24) & 0xFF) * 65535) / 255; gdkcolor.green = (((color >> 16) & 0xFF) * 65535) / 255; gdkcolor.blue = (((color >> 8) & 0xFF) * 65535) / 255; gdk_gc_set_rgb_fg_color (gc, &gdkcolor); } /* GnomeCanvas draws in 512 pixel squares, allocate some extra for overlap */ #define STATIC_POINTS 544 static void swamigui_sample_canvas_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, int height) { SwamiguiSampleCanvas *canvas = SWAMIGUI_SAMPLE_CANVAS (item); GdkRectangle rect; if (!canvas->sample) return; /* set GC clipping rectangle */ rect.x = 0; rect.y = 0; rect.width = width; rect.height = height; gdk_gc_set_clip_rectangle (canvas->peak_line_gc, &rect); gdk_gc_set_clip_rectangle (canvas->line_gc, &rect); gdk_gc_set_clip_rectangle (canvas->point_gc, &rect); gdk_gc_set_clip_rectangle (canvas->loop_start_gc, &rect); gdk_gc_set_clip_rectangle (canvas->loop_end_gc, &rect); if (canvas->loop_mode) swamigui_sample_canvas_draw_loop (canvas, drawable, x, y, width, height); else if (canvas->zoom <= 1.0) swamigui_sample_canvas_draw_points (canvas, drawable, x, y, width, height); else swamigui_sample_canvas_draw_segments(canvas, drawable, x, y, width, height); } /* loop mode display "connect the dots", zoom clamped <= 1.0. Overlaps display of start and end points of a loop */ static inline void swamigui_sample_canvas_draw_loop (SwamiguiSampleCanvas *canvas, GdkDrawable *drawable, int x, int y, int width, int height) { gint16 *i16buf; int sample_ofs, sample_count, this_size; int hcenter, height_1, point_width = 0, h_point_width; int loop_index, start_index, end_index, start_ofs, end_ofs; int sample_size; double sample_mul; int xpos, ypos, i; GdkGC *gc; gboolean do_loopend_bool = TRUE; if (canvas->width < 6) return; /* hackish? */ sample_size = (int)canvas->sample_size; hcenter = canvas->width / 2 + canvas->x; /* horizontal center */ height_1 = canvas->height - 1; /* height - 1 */ sample_mul = height_1 / (double)65535.0; /* sample amplitude multiplier */ /* use larger squares for sample points? */ if (canvas->zoom < 1.0/6.0) point_width = 5; else if (canvas->zoom < 1.0/4.0) point_width = 3; h_point_width = point_width >> 1; /* calculate start and end offset, in sample points, from center to the left and right edges of the rectangular drawing area (-/+ 1 for tiling) */ start_ofs = (x - hcenter) * canvas->zoom - 1; end_ofs = (x + width - hcenter) * canvas->zoom + 1; /* do loop start point first, jump to 'do_loopend' label will occur for loop end point */ loop_index = canvas->loop_start; gc = canvas->loop_start_gc; do_loopend: /* jump label for end loop point run */ /* calculate loop point start/end sample indexes in view */ start_index = loop_index + start_ofs; end_index = loop_index + end_ofs; /* are there any sample points in view for loop start? */ if (start_index < sample_size && end_index >= 0) { start_index = CLAMP (start_index, 0, sample_size - 1); end_index = CLAMP (end_index, 0, sample_size - 1); sample_count = end_index - start_index + 1; this_size = canvas->max_frames; sample_ofs = start_index; while (sample_count > 0) { if (sample_count < this_size) this_size = sample_count; if (!(i16buf = ipatch_sample_handle_read (&canvas->handle, sample_ofs, this_size, NULL, NULL))) return; /* FIXME - Error reporting?? */ for (i = 0; i < this_size; i++, sample_ofs++) { /* calculate pixel offset from center */ xpos = (sample_ofs - loop_index) / canvas->zoom + 0.5; xpos += hcenter - x; /* adjust to drawable coordinates */ /* calculate amplitude ypos */ ypos = height_1 - (((int)i16buf[i]) + 32768) * sample_mul - y + canvas->y; if (point_width) gdk_draw_rectangle (drawable, gc, TRUE, xpos - h_point_width, ypos - h_point_width, point_width, point_width); else gdk_draw_point (drawable, gc, xpos, ypos); } sample_count -= this_size; } } if (do_loopend_bool) { loop_index = canvas->loop_end; gc = canvas->loop_end_gc; do_loopend_bool = FALSE; goto do_loopend; } } /* "connect the dots" drawing for zooms <= 1.0 */ static inline void swamigui_sample_canvas_draw_points (SwamiguiSampleCanvas *canvas, GdkDrawable *drawable, int x, int y, int width, int height) { GdkPoint static_points[STATIC_POINTS]; GdkPoint *points; int sample_start, sample_end, sample_count, point_index; int height_1; guint sample_ofs, size_left, this_size; double sample_mul; gint16 *i16buf; int i; /* calculate start sample (-1 for tiling) */ sample_start = canvas->start + x * canvas->zoom; /* calculate end sample (+1 for tiling) */ sample_end = canvas->start + ((x + width) * canvas->zoom) + 1; /* no samples in area? */ if (sample_start >= canvas->sample_size || sample_end < 0) return; sample_start = CLAMP (sample_start, 0, canvas->sample_size - 1); sample_end = CLAMP (sample_end, 0, canvas->sample_size - 1); sample_count = sample_end - sample_start + 1; height_1 = canvas->height - 1; /* height - 1 */ sample_mul = height_1 / (double)65535.0; /* sample amplitude multiplier */ /* use static point array if there is enough, otherwise fall back on malloc (shouldn't get used, but just in case) */ if (sample_count > STATIC_POINTS) points = g_new (GdkPoint, sample_count); else points = static_points; sample_ofs = sample_start; size_left = sample_count; this_size = canvas->max_frames; point_index = 0; while (size_left > 0) { if (size_left < this_size) this_size = size_left; if (!(i16buf = ipatch_sample_handle_read (&canvas->handle, sample_ofs, this_size, NULL, NULL))) { if (points != static_points) g_free (points); return; /* FIXME - Error reporting?? */ } /* loop over each sample */ for (i = 0; i < this_size; i++, sample_ofs++, point_index++) { /* calculate xpos */ points[point_index].x = (int)((sample_ofs - canvas->start) / canvas->zoom + 0.5) - x + canvas->x; /* calculate amplitude ypos */ points[point_index].y = height_1 - (((int)i16buf[i]) + 32768) * sample_mul - y + canvas->y; } size_left -= this_size; } /* draw the connected lines between points */ gdk_draw_lines (drawable, canvas->line_gc, points, sample_count); if (canvas->zoom < 1.0/4.0) /* use larger squares for points? */ { int w, half_w; if (canvas->zoom < 1.0/6.0) w = 5; else w = 3; half_w = w >> 1; for (i = 0; i < sample_count; i++) gdk_draw_rectangle (drawable, canvas->point_gc, TRUE, points[i].x - half_w, points[i].y - half_w, w, w); } /* just use pixels for dots */ else gdk_draw_points (drawable, canvas->point_gc, points, sample_count); if (points != static_points) g_free (points); } /* peak line segment drawing for zooms > 1.0 */ static inline void swamigui_sample_canvas_draw_segments (SwamiguiSampleCanvas *canvas, GdkDrawable *drawable, int x, int y, int width, int height) { GdkSegment static_segments[STATIC_POINTS]; GdkSegment *segments; int sample_start, sample_end, sample_count, sample_ofs; int segment_index, next_index; int height_1; guint size_left, this_size; double sample_mul; gint16 *i16buf; gint16 min, max; int i; /* calculate start sample */ sample_start = canvas->start + x * canvas->zoom + 0.5; /* calculate end sample */ sample_end = canvas->start + (x + width) * canvas->zoom + 0.5; /* no samples in area? */ if (sample_start >= canvas->sample_size || sample_end < 0) return; sample_start = CLAMP (sample_start, 0, canvas->sample_size - 1); sample_end = CLAMP (sample_end, 0, canvas->sample_size - 1); sample_count = sample_end - sample_start + 1; height_1 = canvas->height - 1; /* height - 1 */ sample_mul = height_1 / (double)65535.0; /* sample amplitude multiplier */ /* use static point array if there is enough, otherwise fall back on malloc (shouldn't get used, but just in case) */ if (width > STATIC_POINTS) segments = g_new (GdkSegment, width); else segments = static_segments; sample_ofs = sample_start; size_left = sample_count; this_size = canvas->max_frames; segment_index = 0; min = max = 0; next_index = canvas->start + (x + 1) * canvas->zoom + 0.5; while (size_left > 0) { if (size_left < this_size) this_size = size_left; if (!(i16buf = ipatch_sample_handle_read (&canvas->handle, sample_ofs, this_size, NULL, NULL))) { if (segments != static_segments) g_free (segments); return; /* FIXME - Error reporting?? */ } /* look for min/max sample values */ for (i = 0; i < this_size; i++, sample_ofs++) { if (sample_ofs >= next_index) { segments[segment_index].x1 = segment_index + canvas->x; segments[segment_index].x2 = segments[segment_index].x1; segments[segment_index].y1 = height_1 - (((int)max) + 32768) * sample_mul - y + canvas->y; segments[segment_index].y2 = height_1 - (((int)min) + 32768) * sample_mul - y + canvas->y; min = max = 0; segment_index++; next_index = canvas->start + (x + segment_index + 1) * canvas->zoom + 0.5; } if (i16buf[i] < min) min = i16buf[i]; if (i16buf[i] > max) max = i16buf[i]; } size_left -= this_size; } gdk_draw_segments (drawable, canvas->peak_line_gc, segments, segment_index); if (segments != static_segments) g_free (segments); } static double swamigui_sample_canvas_point (GnomeCanvasItem *item, double x, double y, int cx, int cy, GnomeCanvasItem **actual_item) { SwamiguiSampleCanvas *canvas = SWAMIGUI_SAMPLE_CANVAS (item); double points[2*4]; points[0] = canvas->x; points[1] = canvas->y; points[2] = canvas->x + canvas->width; points[3] = points[1]; points[4] = points[0]; points[5] = canvas->y + canvas->height; points[6] = points[2]; points[7] = points[5]; *actual_item = item; return (gnome_canvas_polygon_to_point (points, 4, cx, cy)); } static void swamigui_sample_canvas_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2) { SwamiguiSampleCanvas *canvas = SWAMIGUI_SAMPLE_CANVAS (item); *x1 = canvas->x; *y1 = canvas->y; *x2 = canvas->x + canvas->width; *y2 = canvas->y + canvas->height; } static void swamigui_sample_canvas_cb_adjustment_value_changed (GtkAdjustment *adj, gpointer user_data) { SwamiguiSampleCanvas *canvas = SWAMIGUI_SAMPLE_CANVAS (user_data); guint start; gboolean update_adj; update_adj = canvas->update_adj; /* store old value of update adjustment */ canvas->update_adj = FALSE; /* disable adjustment updates to stop adjustment loop */ start = adj->value; g_object_set (canvas, "start", start, NULL); canvas->update_adj = update_adj; /* restore update adjustment setting */ } /** * swamigui_sample_canvas_set_sample: * @canvas: Sample data canvas item * @sample: Sample data to assign to the canvas * * Set the sample data source of a sample canvas item. */ void swamigui_sample_canvas_set_sample (SwamiguiSampleCanvas *canvas, IpatchSampleData *sample) { if (swamigui_sample_canvas_real_set_sample (canvas, sample)) g_object_notify (G_OBJECT (canvas), "sample"); } /* the real set sample function, returns TRUE if changed, FALSE otherwise */ static gboolean swamigui_sample_canvas_real_set_sample (SwamiguiSampleCanvas *canvas, IpatchSampleData *sample) { GError *err = NULL; int channel_map; g_return_val_if_fail (SWAMIGUI_IS_SAMPLE_CANVAS (canvas), FALSE); g_return_val_if_fail (!sample || IPATCH_IS_SAMPLE_DATA (sample), FALSE); if (sample == canvas->sample) return (FALSE); /* close previous source and unref sample */ if (canvas->sample) { ipatch_sample_handle_close (&canvas->handle); g_object_unref (canvas->sample); } canvas->sample = NULL; if (sample) { g_object_get (sample, "sample-size", &canvas->sample_size, NULL); /* use right channel of stereo if right_chan is set (and stereo data) */ if (canvas->right_chan && IPATCH_SAMPLE_FORMAT_GET_CHANNELS (ipatch_sample_data_get_native_format (sample)) == IPATCH_SAMPLE_STEREO) channel_map = IPATCH_SAMPLE_MAP_CHANNEL (0, IPATCH_SAMPLE_RIGHT); else channel_map = IPATCH_SAMPLE_MAP_CHANNEL (0, IPATCH_SAMPLE_LEFT); if (!ipatch_sample_data_open_cache_sample (sample, &canvas->handle, SAMPLE_FORMAT, channel_map, &err)) { g_critical (_("Error opening cached sample data in sample canvas: %s"), ipatch_gerror_message (err)); g_error_free (err); return (FALSE); } canvas->sample = g_object_ref (sample); /* ++ ref sample for canvas */ canvas->max_frames = ipatch_sample_handle_get_max_frames (&canvas->handle); } else canvas->sample_size = 0; gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (canvas)); return (TRUE); } static void swamigui_sample_canvas_update_adjustment (SwamiguiSampleCanvas *canvas) { canvas->adj->lower = 0.0; canvas->adj->upper = canvas->sample_size; canvas->adj->value = 0.0; canvas->adj->step_increment = canvas->sample_size / 400.0; canvas->adj->page_increment = canvas->sample_size / 50.0; canvas->adj->page_size = canvas->sample_size; gtk_adjustment_changed (canvas->adj); g_signal_handlers_block_by_func (canvas->adj, swamigui_sample_canvas_cb_adjustment_value_changed, canvas); gtk_adjustment_value_changed (canvas->adj); g_signal_handlers_unblock_by_func (canvas->adj, swamigui_sample_canvas_cb_adjustment_value_changed, canvas); } /** * swamigui_sample_canvas_xpos_to_sample: * @canvas: Sample canvas item * @xpos: X pixel position * @onsample: Output: Pointer to store value indicating if given @xpos is * within sample (0 if within sample, -1 if less than 0 or no active sample, * 1 if off the end, 2 if last value after sample - useful for loop end * which is valid up to the position following the data), %NULL to ignore * * Convert an X pixel position to sample index. * * Returns: Sample index, index may be out of range of sample, use @onsample * parameter to determine that. */ int swamigui_sample_canvas_xpos_to_sample (SwamiguiSampleCanvas *canvas, int xpos, int *onsample) { int index; if (onsample) *onsample = -1; g_return_val_if_fail (SWAMIGUI_IS_SAMPLE_CANVAS (canvas), 0); index = canvas->start + canvas->zoom * xpos; if (onsample && canvas->sample) { if (index < 0) *onsample = -1; else if (index > canvas->sample_size) *onsample = 1; else if (index == canvas->sample_size) *onsample = 2; else *onsample = 0; } return (index); } /** * swamigui_sample_canvas_sample_to_xpos: * @canvas: Sample canvas item * @index: Sample index * @inview: Output: Pointer to store value indicating if given sample @index * is in view (0 if in view, -1 if too low, 1 if too high). * * Convert a sample index to x pixel position. * * Returns: X position. Note that values outside of current view may be * returned (including negative numbers), @inview can be used to determine * if value is in view or not. */ int swamigui_sample_canvas_sample_to_xpos (SwamiguiSampleCanvas *canvas, int index, int *inview) { int xpos; g_return_val_if_fail (SWAMIGUI_IS_SAMPLE_CANVAS (canvas), 0); xpos = (index - canvas->start) / canvas->zoom + 0.5; if (inview) { /* set inview output parameter as appropriate */ if (index < canvas->start) *inview = -1; else if (xpos >= canvas->width) *inview = 1; else *inview = 0; } return (xpos); } swami/src/swamigui/SwamiguiKnob.c0000644000175000017500000002266711474034033017251 0ustar alessioalessio/* * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include "SwamiguiKnob.h" #include "config.h" /* SVG image dimensions */ #define KNOB_WIDTH 48 #define KNOB_HEIGHT 48 #define KNOB_SIZE_REQ 40 /* Default knob request size (width and height) */ /* Indicator scale to knob width */ #define RADIUS_WIDTH_SCALE (1.0/3.0) /* default rotation rates in pixels/radians */ #define DEFAULT_ROTATION_RATE (140.0 / (2 * M_PI)) #define DEFAULT_ROTATION_RATE_FINE (1000.0 / (2 * M_PI)) G_DEFINE_TYPE (SwamiguiKnob, swamigui_knob, GTK_TYPE_DRAWING_AREA); static gboolean swamigui_knob_expose (GtkWidget *widget, GdkEventExpose *event); static void swamigui_knob_update (SwamiguiKnob *knob); static gboolean swamigui_knob_button_press_event (GtkWidget *widget, GdkEventButton *event); static gboolean swamigui_knob_button_release_event (GtkWidget *widget, GdkEventButton *event); static gboolean swamigui_knob_motion_notify_event (GtkWidget *widget, GdkEventMotion *event); static void swamigui_knob_adj_value_changed (GtkAdjustment *adj, gpointer user_data); RsvgHandle *knob_svg_data = NULL; static void swamigui_knob_class_init (SwamiguiKnobClass *class) { GtkWidgetClass *widget_class; widget_class = GTK_WIDGET_CLASS (class); widget_class->expose_event = swamigui_knob_expose; widget_class->button_press_event = swamigui_knob_button_press_event; widget_class->button_release_event = swamigui_knob_button_release_event; widget_class->motion_notify_event = swamigui_knob_motion_notify_event; } static void swamigui_knob_init (SwamiguiKnob *knob) { if (!knob_svg_data) { GError *err = NULL; char *filename; #ifdef MINGW32 char *appdir; gboolean free_filename = FALSE; appdir = g_win32_get_package_installation_directory_of_module (NULL); /* ++ alloc */ if (appdir) { filename = g_build_filename (appdir, "images", "knob.svg", NULL); /* ++ alloc */ free_filename = TRUE; g_free (appdir); /* -- free appdir */ } else filename = IMAGES_DIR G_DIR_SEPARATOR_S "knob.svg"; #else # ifdef SOURCE_BUILD /* use source dir for loading icons? */ filename = SOURCE_DIR "/src/swamigui/images/knob.svg"; # else filename = IMAGES_DIR G_DIR_SEPARATOR_S "knob.svg"; # endif #endif knob_svg_data = rsvg_handle_new_from_file (filename, &err); if (!knob_svg_data) { g_critical ("Failed to open SVG knob file '%s': %s", filename, err ? err->message : "No error details"); g_clear_error (&err); } #ifdef MINGW32 if (free_filename) g_free (filename); /* -- free allocated filename */ #endif } gtk_widget_set_size_request (GTK_WIDGET (knob), KNOB_SIZE_REQ, KNOB_SIZE_REQ); knob->adj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 1.0, 0.01, 0.10, 0.0)); knob->start_pos = -150.0 * M_PI / 180.0; knob->end_pos = -knob->start_pos; knob->rotation = knob->start_pos; knob->rotation_rate = DEFAULT_ROTATION_RATE; knob->rotation_rate_fine = DEFAULT_ROTATION_RATE_FINE; g_signal_connect (knob->adj, "value-changed", G_CALLBACK (swamigui_knob_adj_value_changed), knob); gtk_widget_set_events (GTK_WIDGET (knob), GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); } static gboolean swamigui_knob_expose (GtkWidget *widget, GdkEventExpose *event) { SwamiguiKnob *knob = SWAMIGUI_KNOB (widget); static guint cache_width = 0, cache_height = 0; static cairo_surface_t *knob_background = NULL; static double radius = 0.0; double halfwidth, halfheight; cairo_t *cr; if (!knob_background || cache_width != widget->allocation.width || cache_height != widget->allocation.height) { if (knob_background) cairo_surface_destroy (knob_background); cache_width = widget->allocation.width; cache_height = widget->allocation.height; radius = (double)cache_width * RADIUS_WIDTH_SCALE; knob_background = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, cache_width, cache_height); cr = cairo_create (knob_background); cairo_scale (cr, cache_width / (double)KNOB_WIDTH, cache_height / (double)KNOB_HEIGHT); rsvg_handle_render_cairo (knob_svg_data, cr); cairo_destroy (cr); } halfwidth = cache_width / 2.0; halfheight = cache_height / 2.0; cr = gdk_cairo_create (widget->window); /* ++ create a cairo_t */ /* clip to the exposed area */ cairo_rectangle (cr, event->area.x, event->area.y, event->area.width, event->area.height); cairo_clip (cr); /* draw knob background */ cairo_set_source_surface (cr, knob_background, 0.0, 0.0); cairo_paint (cr); /* set line properties */ cairo_set_line_width (cr, 2.0); cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); /* draw the line */ cairo_line_to (cr, halfwidth, halfheight); cairo_line_to (cr, halfwidth + radius * sin (knob->rotation), halfheight - radius * cos (knob->rotation)); cairo_stroke (cr); cairo_destroy (cr); /* -- free cairo_t */ return (FALSE); } /* update the knob by forcing an expose */ static void swamigui_knob_update (SwamiguiKnob *knob) { GdkRegion *region; GtkWidget *widget = GTK_WIDGET (knob); if (!widget->window) return; region = gdk_drawable_get_clip_region (widget->window); /* redraw the cairo canvas completely by exposing it */ gdk_window_invalidate_region (widget->window, region, TRUE); gdk_window_process_updates (widget->window, TRUE); gdk_region_destroy (region); } static gboolean swamigui_knob_button_press_event (GtkWidget *widget, GdkEventButton *event) { SwamiguiKnob *knob = SWAMIGUI_KNOB (widget); if (event->type != GDK_BUTTON_PRESS || event->button != 1) return (FALSE); if (gdk_pointer_grab (widget->window, FALSE, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK, NULL, NULL, GDK_CURRENT_TIME) != GDK_GRAB_SUCCESS) return (TRUE); knob->rotation_active = TRUE; knob->xclick = event->x; knob->yclick = event->y; knob->click_rotation = knob->rotation; return (TRUE); } static gboolean swamigui_knob_button_release_event (GtkWidget *widget, GdkEventButton *event) { SwamiguiKnob *knob = SWAMIGUI_KNOB (widget); if (event->type != GDK_BUTTON_RELEASE || event->button != 1) return (FALSE); knob->rotation_active = FALSE; gdk_pointer_ungrab (GDK_CURRENT_TIME); return (TRUE); } static gboolean swamigui_knob_motion_notify_event (GtkWidget *widget, GdkEventMotion *event) { SwamiguiKnob *knob = SWAMIGUI_KNOB (widget); double rotation, normval; if (!widget->window || !knob->rotation_active) return (TRUE); /* calculate rotation amount (SHIFT key causes a finer rotation) */ rotation = knob->click_rotation + (knob->yclick - event->y) / ((event->state & GDK_SHIFT_MASK) ? knob->rotation_rate_fine : knob->rotation_rate); rotation = CLAMP (rotation, knob->start_pos, knob->end_pos); if (rotation == knob->rotation) return (TRUE); knob->rotation = rotation; /* normalize rotation to a 0.0 to 1.0 position */ normval = (rotation - knob->start_pos) / (knob->end_pos - knob->start_pos); /* update the adjustment value */ knob->adj->value = normval * (knob->adj->upper - knob->adj->lower) + knob->adj->lower; /* emit value-changed signal (block our own handler) */ g_signal_handlers_block_by_func (knob->adj, swamigui_knob_adj_value_changed, knob); gtk_adjustment_value_changed (knob->adj); g_signal_handlers_unblock_by_func (knob->adj, swamigui_knob_adj_value_changed, knob); /* update knob visual */ swamigui_knob_update (knob); return (TRUE); } /* callback which gets called when the knob adjustment value changes externally */ static void swamigui_knob_adj_value_changed (GtkAdjustment *adj, gpointer user_data) { SwamiguiKnob *knob = SWAMIGUI_KNOB (user_data); gdouble normval; /* normalize the adjustment value to 0.0 through 1.0 */ normval = (adj->value - adj->lower) / (adj->upper - adj->lower); normval = CLAMP (normval, 0.0, 1.0); /* convert to a rotation amount */ knob->rotation = normval * (knob->end_pos - knob->start_pos) + knob->start_pos; swamigui_knob_update (knob); /* update knob visual */ } /** * swamigui_knob_new: * * Create a new knob widget. * * Returns: Knob widget */ GtkWidget * swamigui_knob_new (void) { return (g_object_new (SWAMIGUI_TYPE_KNOB, NULL)); } /** * swamigui_knob_get_adjustment: * @knob: Swamigui knob widget * * Get the #GtkAdjustment associated with a knob. * * Returns: The #GtkAdjustment for the knob */ GtkAdjustment * swamigui_knob_get_adjustment (SwamiguiKnob *knob) { g_return_val_if_fail (SWAMIGUI_IS_KNOB (knob), NULL); return (GTK_ADJUSTMENT (knob->adj)); } swami/src/swamigui/SwamiguiControl.h0000644000175000017500000001066511461334205020000 0ustar alessioalessio/* * SwamiguiControl.h - GUI control system * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_CONTROL_H__ #define __SWAMIGUI_CONTROL_H__ #include #include /* some defined rank values for registered handlers */ typedef enum { SWAMIGUI_CONTROL_RANK_LOWEST = 1, SWAMIGUI_CONTROL_RANK_LOW = 16, SWAMIGUI_CONTROL_RANK_NORMAL = 32, SWAMIGUI_CONTROL_RANK_HIGH = 48, SWAMIGUI_CONTROL_RANK_HIGHEST = 63 } SwamiguiControlRank; /* value to use for 0 (default) */ #define SWAMIGUI_CONTROL_RANK_DEFAULT SWAMIGUI_CONTROL_RANK_NORMAL /* rank mask */ #define SWAMIGUI_CONTROL_RANK_MASK 0x3F typedef enum { SWAMIGUI_CONTROL_CTRL = 0x40, /* controls values */ SWAMIGUI_CONTROL_VIEW = 0x80, /* displays values */ SWAMIGUI_CONTROL_NO_CREATE = 0x100 /* don't create control, cfg UI obj only */ } SwamiguiControlFlags; /* convenience for control/view controls */ #define SWAMIGUI_CONTROL_CTRLVIEW (SWAMIGUI_CONTROL_CTRL | SWAMIGUI_CONTROL_VIEW) typedef enum /*< flags >*/ { SWAMIGUI_CONTROL_OBJECT_NO_LABELS = 1 << 0, SWAMIGUI_CONTROL_OBJECT_NO_SORT = 1 << 1, SWAMIGUI_CONTROL_OBJECT_PROP_LABELS = 1 << 2 } SwamiguiControlObjectFlags; /** * SwamiguiControlHandler: * @widget: GUI widget to create a control for * @value_type: Control value type (useful to handler functions that can handle * multiple value types) * @pspec: Parameter spec defining the control parameters (value type, * valid range, etc), will be a GParamSpec of the specified @value_type or * %NULL for defaults * @flags: Flags indicating if control should display values or control * and display values. If the #SWAMIGUI_CONTROL_NO_CREATE flag is specified * then a control should not be created, but @widget should be configured to * conform to @pspec (or reset to defaults if %NULL). * * This is a function type to handle the creation of a control that is * bound to a GUI interface @widget. The control should be configured * according to @flags (if its display only then UI control changes should be * ignored or preferably disabled, control only flag will occur only with * handlers that don't display value changes). The UI @widget may be modified * to conform to @pspec (valid range, max string length, etc) and should be * done in a manner that allows @widget to be re-configured (i.e., set default * values if @pspec not supplied). * * Returns: Should return the new control which is controlling the * GUI interface @widget. */ typedef SwamiControl * (*SwamiguiControlHandler)(GObject *widget, GType value_type, GParamSpec *pspec, SwamiguiControlFlags flags); /* quark used in associating a control to a controlled object */ extern GQuark swamigui_control_quark; SwamiControl *swamigui_control_new (GType type); SwamiControl *swamigui_control_new_for_widget (GObject *widget); SwamiControl *swamigui_control_new_for_widget_full (GObject *widget, GType value_type, GParamSpec *pspec, SwamiguiControlFlags flags); SwamiControl *swamigui_control_lookup (GObject *widget); void swamigui_control_prop_connect_widget (GObject *object, const char *propname, GObject *widget); GObject *swamigui_control_create_widget (GType widg_type, GType value_type, GParamSpec *pspec, SwamiguiControlFlags flags); void swamigui_control_set_queue (SwamiControl *control); void swamigui_control_register (GType widg_type, GType value_type, SwamiguiControlHandler handler, guint flags); void swamigui_control_unregister (GType widg_type, GType value_type); void swamigui_control_glade_prop_connect (GtkWidget *widget, GObject *obj); GType swamigui_control_get_alias_value_type (GType type); #endif swami/src/swamigui/images/0000755000175000017500000000000011716016663015746 5ustar alessioalessioswami/src/swamigui/images/modulator_junct.png0000644000175000017500000001376410454447011021671 0ustar alessioalessio‰PNG  IHDRTTkÁsBIT|dˆtEXtSoftwarewww.inkscape.org›î<†IDATxœí]yxSUÚÿ½çÞ$Mšî{KkA@TDÄQqAGw\paEÑoÆAFQQ…Aq—‘E‘Qñc•­¬] kº·Iî½çýþ¸Ii Ô>yìïyò´çžsÞûž_Îò¾g 13Zƒôgz¯0ÀGÅOm”­ÖT¶0À¤â§6^IÙ§ jk(ªÚÀödMïû7‹‹žü¯»52³¦÷p¯¢ªèÜZO'¨µ54g楎ýbJÌðzþ¤õ®ÊJð€ñRƒ¢ôüIë-­Rô4¡Õ„¶Ÿuy€‰FpE5XàÅ×8Œö0€#(ªÀ|³L\—ß*EOZM¨^½*À¤EV˜™7î«!yz˜àJPT1€Wü=oÜWUQð4¡Õ„v™3`À®Ñ_|¶¸À£º†$_sL"û‡Äïð7oíý…§¹wü’ÑjB»Í¿žlIÔ{?øT÷='7À$îòˆYçËÿ¯ŸF|ʾü*€;|ù{þ4âSj•¢§ ­&´Ç?~, À,ó·Þ÷ImPš>0‰¹€ð=–Þ0së}Ÿ|”6f<@¶ÿùÖû>ùuzþÛC ¨0ÀË›î^y$(íÙ0xqÓÝ+÷ÅexÀ(ñ¡7ݽò×Ahï÷nˆðý!x¼ à…w¬ØÑLþs<ànÖ0IÖ˜¹ñŽ«Z¥èiBÄFù‹WÜÞ܈ `€™ßݲl­/ý¾ô„Ö¾€eðÝ-Ë6â BÄõ£ßGw5gSúñƒïïEaâ¶ë·ƒÞ9®íúKE« ½|Õ°€/¿nàô¼9¯'ÞÕºKÞÕ嫆|ùu—œ¾|« ½òóüöÀ´!¯¾v¡;(> À½0íÒP¿ü¤ó¬¾vá¯cPºfõˆPÚöå•ó]AéµÍ÷h&€¾¼r¾ JÓl­þòÊù¿B¯ûztsýág—Í9nxÝ×£OÔïâ³Ë朄F`ú.t@À`€17Œ]`æªK^;fĸalo“U gœ‘ˆ¡K ÐÜôšàv·ßøÃ„5òåUé¯Ð¼ÛJ5O"b6 ÙüH6€?x@L«š¨0ÀK+{½X!™§µCoÙ>)Àh˜.dú ’7‡b/˜³¢ûÌ3jê8†=ܱëI€a0Íž.'™mLjÉ{]¦{N”ø—ŠSB¨wíýᨩԜap Þé8íÔ)sšpJ ưCO÷ƒIì`ߣÌ\rÖÓßžNN¡~Ü_ôÌ9°(ë©Ý§õŧ §”ЩÕÞÑ•n‹mH´Æé 6‹×AªnU ]gC7¬nÝc©k¬µUykeOæ9ËN™2§ §„Ðé]k“bb«ÚǦÖe;âj2œqõ)¶hwœÅ¦9U‹n%a0 Mu{Ý¶ÚÆ:{e]utiƒ+öpuIl~Muú¾)Ъµýÿ/D”ÐÉ]““RxnRjYçøôʱ©•¹±‰µѱõiQNw¼Åê q+ žkMcÃUWå,®uÅU–Çt%í­,LÞýÈ–ôÌ8£ªˆ:£{YÇôÜ’i9%Ý“²+º$¥UtŒK©: $!’¦/NsÆ,̤`@ÀðZ=®’„ý‡Sö¸ Sv•¤l+*NûqÊöØ&&†/üéN4)% %¤&Áš¾réú€Û__ãôÔã÷†.IJ )5RÂ0dÃW¹ñ ¿œK{ïff™cH i˜é¤ CBêXÒÊ GRÖ5Æ–¼2R±Âl(«ì*±¶»{}[WÔm}þÞöëžØ0øÝ÷¾¹íS–ò·RJHÀYõáË'ô[ƒŸûOš.°S2AJ3Þ0ÓU[é²ú…ß•ÀÅ.}GÆAñ8V¦¾gѸ…§œÐ—úõÊéZpYTúW/Øðæ5Õuó›e "Œz¾û7fè é#3ø}f ]ùå>ËÒﲂ ÌþšKHOˆ3½éÖýµE]¿.Ú™óíþ=?ÿŸmÑ%BçomÏÌÛ¥”á Ãp ¡wY6þ²2¸aÆW#¤aÌ !Òo­›~Ó0¸tÒ’TM£]†” á5 Ã]òŒ?¡"N” 9ÌèQÝ!£cqï¬N…}º_PsÃ!ÄÞ¢rÅÿÉ+p){òË•×ÿ¹Ñîj¨VÈâ!²¸‰,na~<‚T*)U|¼5*¯À¥äT({ +”½EåÊþ#ŠÓ©rF–7¥]§Â¾‹z·ËÍï7+v¿‹Gô8â§CTKÔ51ËXõÄUo‚éë& ¾ç7“—€õ3‡•2xR“4A2¥Æ³ŽÀÏ"trÄdžu¸gFnQ¯ÌöE:¢uÛ„;ú6f¥8e IÚ›_)æ,ßÅM¤z„I¬I®A â•w6G.©DL º„ÜÌ8cìí}ÜŠÕ ˜¤ªÌŒG.Lk¸—­ãþ ƒu),ªšÅæÎ•£ Ü}ÓÌu×,9æ’vhN¿G–Û`ãËÃXÛ|©ùî÷̺öDÜü,BÛ%vMÎ>Ò-í¬’žö¸º$RuÊÍŽ‘÷îᎎRÍ&OLD†”ôåúBõ?ß²ÕR"‹‡V|¹ÏòÝÖÕ¤D S¬Ó‚‘·žçÉL³1 è”˜^Þ)-»ô¼”ÌÒó¦_P—â×eõ”þºô Ì(G‹/0gÐÔOðÙ“×îá¹0EéÀ Of°b€f'f˜yNÖ ©aWüh1¡S³k“ÒË;%g–uMÊ,ï E'VtŠFƒ¯ÊÕ.½ CÂËĨ®óÒÜ¥»­%UUfS·xľ uñû¬nÃW›MR…B¸æ’,m@¿,ŠFBÑB#(:Û•œ›’í:')¹øü`Þz°×Ìx-DÕö숙âĵÓaÎh…Òôhß?,í?¼tÏnpXâ2U‡sÊqâ[NhBV}û„ôг3*;‚ Ð! è¤Z%ÖÍ›“m›¾æKÄ8PP/^ûGž•…›¼²^^°Çr¤´‘ˆ$(¨›è”ë4ÆÜÝÅ+,:‘¯vBÑAB'GLcBRZEÇ„”ò³§vrÅëÕh÷ü@að3b~äÆçW÷€eSnó²à‘@GA…À<š:U€^îœs`3àGÚ }¾gs±-"”“TÙ.>¥:'>µ*ŠA,$AH0 ß.ÓÆ#‡žíuF+l6} C2Óê Ê¿V©ï~\ þ°¥Z1Í(ø»$ÄYxì½µ”d:Aè€Ð!ƒ˜ ‚ЛRyV\JMNjFCn°n¿´–ˆÇ…’%YΛê#ë˧nøÌó›Pô¹ÐÕq,l_v›WH G|@&äÑ/ U„>Ûµ!=&®.Ý™X›eÖNÃ$RèóbÐo¯L3ú_’l(ðF F]½NóÞ:¬.}¿Dõx øL,1©à†kRË/I”Pu@1¿$ùœ€$EÇÕ§Æ&ÖfDÇÕžªß»c/þÌýþÁ¸hƒÒo|€ $$ ˆøÙžÞn›çÿ†€7BÓËÌØf.¢E„ڵɎøºGl} „C äóŠà«EŠ*1~øYz‡\;ƒ˜| ƒˆ‘_è¡âR/!_sïÚÙÁ£îÍ4 tDB#ƒ @$|ÎHÂWŸb­O™Ý ¶&ÄHŒ‡¹D¦]÷ìçÙ°zÊ*6—hBcñª? z-OÀ\Ž ¦iYCžÍ}Ü"BmvO\T´'ÎíŽI‚`³ I ’ JO·ð˜2õ¸…ÉoÐ {yÌ@”œ¨ðã2õ¸xÁ¤&‘þ9!Éßm0$¶èÆ›£1®!®2*TÇe/)bàB;!e`ÐZ;mð{07¯Ë0¸×ØE7À¦…÷WxÂqèp$C–ªÚ½‹Íë´Ø½æÊ&I€ C¾Â "ƒ®¾"N¸*V ¦9"b+póà8Ù§·ƒáoÞäûbH‚üÝæÇfÕV«æB·‡Ó³WÍ¥¯ø.äñ×LýôVÀx@}ÓÜ<»Ó„·cà§ùc–3è“æ¡S‡L½5øI‹µnUTi5k› ŒâÚç' ¦›I>,YÚl¾‰&€‚Óg´À°¡ Ò/þ>ûÉ ¤õ—BXô(ÅbX-J}“ S¦@²O7)>ø/þÿ×O»ùo†Éži×Ü£ý)èÏÇ%EÒ_‚ƒ-"”… ’'@jP‘Æýëó*a¡&û“‘Ç#ñÅšaæácâAMö`bbðñu—¢Is%ód àÊÇ>Ifà®09«¤PûÂÇkö ¢W‚Ã-#”-I2Yý3F¦h†ßž÷q»y{½Xþ~¥ðzM‚8ˆ)¸¡‘±`I¥²o¿Çœƒ šfûói(:4 ëÕÜ<ëÛ¡\òxýSÎõ¤Åû7É¡y‰1yûk÷@÷ç\E„û›'ëK?zjnð£ªi¢QóZ ]hG ztvÈO3q]ÄËsŠÔÒrí(ælû?þôEE^úûÕëXúž³³Ïîbߪ4‹¬kŠ[×T·ÛKM–InziM<À/…ª®HéÿB¯úãÊ«™po˜"~³ùïÌ€ö,Š’Œ9ÍqA€FPF†®(´ŒÐF[»ÑZçmˆª L³`ß_0+ÌRXÁÂ¥‡•m;êéÂAHI² >V „Á3ðÝÆ:±ìƒR¬RaS.á#–ÉTW<¶Zo½½ÖS+CuT(ê¯ÒBŠÿüª)×ï€+§®‰’DáˆòB¡AÑVýO:5ÇÏYùd“s-"ÔÝh«t×Û] ¤ðY1fÁ+¼qsµxÿÓbUÓüMÝ$Ôj¸mH¢qý€8©(ÂG¦I¬ÛͼäŸÅÊÎ= ÄR¤ïË2C HLL (ðÔE»ìåOÌ=¦Éß9ûûË¢öŠÕ¦ù$ëþ  cS‚xƳ†í€žcÞìðãÇ¡bOt£sZ¸ˆj¸¬å ÕÑe UÎRÀœ]—¬0¤ó£rMWìµT¸tòÕL_M#ôìî”ÃnËÐGÝ—¥wéèG›´ÙW—zé¥yû-îF0Kõ¨\VR³CZmµ£ÄSëÜÜÜn_¾Ã* srB€G­½<³ê<0 S´ÝÕ²ê9Àt¯Ùô’š=¬KÌ£òVÛ·ˆÐ'ÅUÖ¹bŠª]1ÞFk=ˆTRe6žÿ^žeÇÞ@Ðì;8-ÙÆÈÕíÇ;rüïsôÄx ûÉd³ïŦíUÊÛïç[`¨Ì†Ê,†i\0 …k*â j*â ݇­ÇlâUÊ'£ÉQH^øñ׬€©S§ H¼p(QÌÀ¨¼WL‚zŒ]8À%Í’ ,,XþÄšæâ[<Ûä*Kȯ.N<ä*IÜ©0 K©2K6•©Ÿ¬.°ê:Fzf‚Õª`è vZ·ŽI:tC³ñÅ=ÓôA2tUG‰àñJ¼·ê€eËÎ*©2¤…¥aa–*À *ËÔ”ÅæÙ–Ø™7tÞ–Îÿ1DÕR¯Å¨ë•¾cô S¤ß¿xçZ¸`ü‚LbÌ8NñK ©„«á´˜ÐÆ­ÉûÊ‹ã÷VIÊó6FÕ³TºŠÊJ ¯-ÝbsÕxƒàÌþñÂnIƿ렱fc©EI©EIÖm<ü¶ŽZ·Nñòk„R—G¼²d«­®ŽI*“T†ÂU¥ +‹öV§|ƒ æ.¤œ „øõŒ‰ÿžx n|ö«,b7ÏYªªF`éƒH 6L:S$ÑÄ‚e{@‹ ÂÐ˧î.+LÝY–Ÿº†ž»bsÔîƒ•Š¯¿dÿ`“žì†u÷X…C²fãà3ÊiŒ¿÷\Or¼=`o²i"ñ¶¼ uч?Y¡«`C…áµyJ Sv”LÛ8n}và¸ã°ù[ S|ÌüÙÊÇ.ÇÖH¾Ž(&<üõô»*ࢇ†y5,ˆñÙÁ·&¾Ó\¼?k äñ-É»Kó“·•ä§mu'ç­ûßCêgÿÝg xD¾~3ʪò=7tñvÎIÕY³1ëv -JB³IhQ’½Q|~çLýæk:x-ªzŒmªiŒ•«÷X7î(Q`XøÈŒM¥Ó·e¯õ×Îá 7¥ã…õ )Çø§ÿg1 SŒ¯Ÿqë»ð›É b@âÕ0i2u¡Œ9N|?{£CIYÇŽýZ‚Õ®;+=öäs²Sí¾ 0Ò’íò–«»zX#s~Ó&­#–‚‡Ýpžç`›ªj¼Ä, –`¨\|(}ë‘}?ÌZ9ycBµ_Cª/2dbˆjOôØå`àìOc‰¬¯†™)nPXÒtû³€Ñ®¹²ðôÁÅãNêdßÏ&tÊvÔÍìž³,š­Ó9×+ýïé~q\ªë,(¾ gE‡:X—D†d&IŸÝ¬‰ÌL°«‚Ÿ; R@&©0*ð øPúÖ¢¼v ÷æ|4zuîAÿûX´sÌ‹‚±¹¢ÊXíÏé0²Bugæ?¯™>ä ô›¼¼cSÔÍYù®“ZBZ¹gÒöèâ¿vÉ\'¤`CW½éKCJ»²® Á`A’@1|Ë  æc¬DÀ¦Ñ©˜¦‘TÁ†ÂºÇæ.>˜±ùȾŒìÏþpä¶>xÌÛ¹ @/ÿb  Z´zJ0÷6Éàe"óÕf£ †´<-àš²!{00Ûï¸5€d,Z½zŠ~²œDd³ØÔî5‰9Y‡û¥}¸WZvéyÉÙ¥çFÇÕ§‚t@‘¾ýMÒ7§”QÓue€¡0XAeIâþ²ÂÔ¥Ò·–îOû`ä×Έ \€ S»Ãš[Ø+5·¤GJVé9ñ©•R+sck2A¾ÍW"h*Ê÷zH Àðªž*WlauqüÊÒä½å…É?•f­}ü›äÚf^ù‹DÄ7ÜÎèQ˜ZÞ+.µêìøWNl|m¦=¶!%*Úoò8Õ° bÅB74Õíi´Õ6ÖÙ]õÕÑ%5®¸¢ê²Ø¼ê‚„oú>·ùõœ_0NÙ–ðz–DGEËlg|u'{lC²ÍÞgµ{œŠÅ°X0+†æUÝÞF[]c½´®Þ¾«òpTþÛrª2%v&á´Zx£7,UuåQv‡µÿáµÝ ëþ; Õã¨NpÏk~ûË™†¶c5FÛÁ¯£íhb„Ñvx6Âh;Þa´šÐ˜°Ç¿€ kpüËÃAðîǽn•ò‡V«1tc؉’Àw©UÈ«üWd üåY~X`öÇ¿B›‹:á%.>‚ï8™K\δ]3a´]„a´]Õa´]&a´]wa´]Èa´]a´]ja´]»a´ý0@„ÑöÓFÛ«Dm?ÿa´šÐ¬é}›øò‘ú*ùòEOþ÷Œ”"0}§‹ÿ„šï y#ý™Þóqì Õ/ÿ`ÄG¹¼]ѹIEND®B`‚swami/src/swamigui/images/GIG.png0000644000175000017500000000110310454447011017046 0ustar alessioalessio‰PNG  IHDRóÿasBIT|dˆtEXtSoftwarewww.inkscape.org›î<ÕIDAT8}Ó?haÇñoÎ÷rgšÃ³Õ˜*A3ø§""")¨(êTO¡Š(Vw] .RA®›.Yœ,ªK‡º :˜ (¡bb¬ráÚ´iò:´b{¼ç3ž¿gxRJ§®jÀ `HE ¸ $€iàŠÂCˆˆ÷{ª YûÅ0 ³õ1"êcLX‘÷ÒÏÌ|8¤=óyû¼É1T%$Éè¯@ÒÉié>½Ÿ™y¿ÿÛÐè !"^¯©žÍšOY'C}ÿ‰WÿCÛíð T†ÄHßh´QmH÷m6ÿO4;ÔDDëõóýÙBD<ŸS­ÑìŒÊÑj•êåòõ„ŸQQ<ÛÑÑã‘߈h0CˆˆÇcªû˜‘ee¨+‘Û­yИjQ@Dt¹tßäªF°Û5 >çȆ¦ oD†ÑêçA @IEND®B`‚swami/src/swamigui/images/switch_neg_uni.png0000644000175000017500000000050210420662631021447 0ustar alessioalessio‰PNG  IHDRù‡yÕbKGDÿÿÿÿÿÿ X÷Ü÷IDATxÚí–± ƒ0E¿#VÌt0•½ƒ0@‚1¼C* fVø)AJä8 ¸à5çât~øî$'²’ QW!„n¾D­µÖúߺD_¦“û½(Š‚$Ó4MI2Žãø›Ø÷}ÏÝX?oëgžçš¦iŽ«ù,Ë2†aø¦d’$ÉñŸ‹žÃ%z‰†Î%z‰Pv¸¢”Rm[–eé®&–°MÖ½ËGUMÓ4u=ŽãèÏ'—5®ëò<Ï·IhŒ1ÆlkÞšîB)¥”Ú¿\øpÝcý‚ùGí ºxk}hØÖ¯¢ÿòñ³Å]Dú IEND®B`‚swami/src/swamigui/images/swami_logo.png0000644000175000017500000006176511457713741020636 0ustar alessioalessio‰PNG  IHDR  ‹Ïg-sBIT|dˆ pHYs99S<tEXtSoftwarewww.inkscape.org›î< IDATxœì½y˜$G}çý‰ˆÌ¬ª>¦gz.Í©k¤‘%„â²¹^ö5¶ñËËã•gñ±¼<>°/Æ~ñY¿~`mlðÁ¯ÍÂ⌠ 6§…Äè–FsIsÏôÌtOŸU•™ñ{ÿˆÈ«*«»ztaïýdgVž‘ßüÝñ %"üÿ¥(7ß|óÙ ì‘ËEd³ˆŒ÷,k€l™óˬˆÌs¥}'Ed¿ˆì‘}¯zÕ«N?ͯø]UÔÿª¼ýöÛGEä…"ò,´Ý~YàU»,w|ˆk§30z`în~Ík^³ð45ÅÓZþ—àwÜÑ‘çŠÈK—ŠÈ"ž€øí‹EävùŠ_n»é¦›:O}+=õåß4÷ìÙs©ˆü¨ˆ¼LDž/"-xbô€¯nY‘[€/‹È'_ÿú×?üT·ÝSUþÍð®»îZ+"¯‘7xÐ=iz’ÀWwüù˜ˆ|âo|ãÌSÚ Orù7À»ï¾;^áA÷Ji<²ÖÒívYZjÓi·i·ÛDˆ(rK•ûÕÝ{ØçÕ,ೌ_ø©Ÿú©ä©jã'«ü«à=÷ܳEDÞ ¼AD6>^ê5??ω'9uò'OžâÔ‰Sœ9s–¥¥%:N—•šK)ˆ¢ˆF#¢Ùl²vÝZÖo˜dÆõL®wëf³ùDPÚ)Äß{Ó›ÞtüIkä'¹ü«à½÷Þ»SD~YD~hž5™ŸŸçÀþƒìÛ·Ÿ£GŽqòä)æKOQ(¿~|EðµÈ÷ŒŒ4™\¿žM›7°sçvìÜN³ÙX×€Ù‘?Þýæ7¿ùÐã¬ìS^þUð¾ûîÛ%"¿""¯‘†geKKK؇ÚÇþ‡pôèqN/Ð À©>ð Féù%5ǪÀÜ´y;vî`çÎílÛ¾•0 W˲cùŸ"ò;?û³?{pÈŠ>íå_ï¿ÿþËEä7Ä)fØNi·ÛìùöÜvë·8°ÿ Öf€«‚­÷7•½ƒ@×»P;öS@ò=Ró[ÐZ±mûV®¸r7—]v)A¬†2¦"ò yç[Þò–ý*õ]S¾«øÀ´Dä"òK" C¬µ<´w·ÞrwÝy7NLº:À ¦€ý4põpøªÀìdÆ0 ¸t×Åì¾âr¶mßZy÷åÚèŠÈïŠÈýÅ_üÅ¥!+þ”—ïZ>ðÀ?,"ï‘‹†‘…¦§§ùÊ?Ûn½éésÔƒ®pè†gÃÕãÕÒß–Ã°ß „RÙîãØØ—íÞÅ3®¾ŠÑÑ‘a©â£"ò–·¾õ­ŸPé§µ|×ðÁ¼HDÞ/Μ²¢ >ujŠÏþ¹åæÛH’…öwR= S=û>€B=øÎWé¥luûz)`ï¶ôì·£¹üŠ]\{í3VYù¬ˆüüÛÞö¶GÏóež”ò]À½{÷y›ˆüšˆ´Vß±cÇùüç¾Àm·Þµ’ƒmyÐÕQÄâ×ÓI{¹ÅËŠ—g^{5kúÚ¨¦ —Dä]"òž·¿ýí逗xJËw÷îÝ»EDþBD^¼K9tè0ŸûÌ?°çÛw#Bðz(Ji¿-ÔÎWY©¬^YžV˜­•‚ /ÚÁ5×]ͺuk‡aË_‘›~õWõi·>íÜ»wïËEäã"²i¹†[XXàoÿæïøê—¿1xš*˜ti{0Ì@ùÄ™bVo‚YŽûm\hûÎS .¿b×]ÿÌaÌ8§DäuïxÇ;þi…zRËÓÀ½{÷àâìzz9ðÝü/ßä¯?ñ7ÌÎÎç@ëžR<µsý¤PJ ©ˆäÍÐKËûV[Êð«£xÙï•:êWDK³Ùàú®áâK.rwÌ’­ˆüŽˆüƯÿú¯?-,ùiàÞ½{·)"ß·œÌrøð>þ±¿`ÿ¾ƒ9д҈€V†A2_ÿ>…ˆÛVŠ|Û7[rö õpµ ¬€ 6Á¬Žýö¯÷÷¦M¸áÆëY³fÜÝw0Kþ†ˆü‡ßüÍß<¶Ê—|Üå)àÞ½{o>3ˆåZkI’”¿ÿ»ÏðŸû6­t…ò©ð©œª tÿuþì: (Ò¯ˆHŒƒJçÔ·á°ì·žZoqÝ °ùµ¤•s[¾çªÝ<ãê+«u«gÉ?ü[¿õ[·xÙ'¥<¥Ü»wï÷Ÿ‘Ñ:àYk9{æ,ø“qðÀwPhP¢@k´—í´2(4Ze ,ƒSç2bŒ…ÜØ¯ˆd ,~çÍSáêŠôý< ÈrTÏJ¶N‹aÃÆIžûüç02ÒZN.\~ä]ïz×?®òeÏ»%(¥1ÆøEc‚­arrϾñzZ#-ÿεýóžw¿ûÝ¿<äKŸWyR¸wïÞ?=|‡æ÷þÛï3==‹X‹M-q’&1qš"6uL£U‚R–0‰‚QÔ"4 BÓ 0‘cÏÚT©XY¶“B¼&ì˜+"¥¦(ƒPå¿WSê(`¶d°ü'%ðÅi‡8iÓ‰—H’.‰±6õì7@‘¢! BL`PZÓj5xÞ ŸÃx;¯‡*~ø=ïyÏZíÛ[ž4®Dùö=´Ÿ÷ýþ±°°äXqšÇI@QÛ}æ³ £ïÁÚS,Έ¸ýiŒQ4ÂÍh„(h 'RUJ€œê9 ìØŠx’k½b…^*ç®Ï¶‡}ûÁ H¯ XU@êÁØ«tˆ¤$6!I»tâEºñ"x‰Ô £ÿ•0ºc¶ õósdaî÷Ð:uo†!Æ”VDQÀ³o¼žu“këÀ—SÂßýÝß}R(á“@/ó½wøîÜsøãÇ1ˆÆZ!‰câ¤K’Ä$iÀúMKîF)*‹µÇ™>õïi„)h,¡Ñ¡WJtI)S7埯Êýí©¡ß.­]§”±Ð‡k¯zö[e·½ –ýf2_7Y¢Ý] Ó] “&¬Y÷Ç4[/ï«Kdæì›ƒDaƒF„!Zk”´Ñ\÷¬«Ù´yãrò~ï{ßû„Ë„zåSVW¼¶û{ƒÀ÷õ¯ý ôþÿN§d`)›?¬&Ö½“(ÚÖô-a¸…ÑñÿÓw‡u†­ÐÆ u@`BŒÜb‚À­³}ŒSf”Ð*p2¤×¬3yRã(ªÂ 1žªjgƒíÏæ³ßÙ9NeBù늵îùm tL÷ï_²çˆ©µ¤©£†ãkß] >€ ÜÅèøÏ`Së-‚3/:³–X¸óÛ÷røÐßµ}÷{¿ð ¿ðãO4^žPz;ßGê´]á Ÿÿ"ùÓ!þåÊØ¦û­P˜ð2FÇ~¤xƸEk]óX´Fiå”eL€1† 1&Dk§-åAhBŒq 3Ú™q´Êì‹ÊxP D•Áæ)d.?ÛdЏŽíÛòàÊÀX>¯¼/Û¯Pâ*±Ö›`´F^¹lß4š/Æúk q¤$®ˆâþ{â‘ï<:€ øÈ[Þò–ï"1ó„Ð{8>UgçË(ß'þòS®•.:>§:ÎM…;ÐÚ±Û2ø²ßÆ@m§Ñ¼ £5Z{0•ӞʹÅRÌ ³íˆ~;¯“û™w2YOqÒ´Ð<öÙ%McÒ4ÅZ[df“ìÑ íÁ •íB¼ ¸–ïh½–0¼65÷Thöí}˜#‡RHBùÔÏýÜÏÝøDáæ  ÷í~Fj<™Ì÷Ñ|¼>£¯¹j×ÑÚ¸°)cú(^ö»¼„J6.*mŒ§tžýšÀˆÚƒÑè@çhUQeì¸ìañïÚ„$mÓM–è&‹´» ´c¿tèÄ t“%â¤M’&9 ÖQÄzÖÌ2À”\ÁRyÝ”^7\g›IÊ Œ÷‚pï8urjB2*"Ÿù™Ÿù™­Ov7}TË_Êßîþ}øÀ±T(ŸVºÄî|Ç›Í|…õAÆ p‹Û¿ÆÌÝËQ;®ÀS5Sš³Þ–.“ÿ(\}Ʊ…Ô¦ÄI‡n²H'^`©;Ëb÷Kñ9;Ónéθ}ÝYÄEâ¤CjÓ„2ˆ /GQJþnQ(½f¨¾;Ká1Di v<=í’0Ôôë&ùË7¿ùÍæñâgyº=\y§ ˆj9rä(ðÞ?$‰“«õ”NN¢ñF6« F`1_™ ÷jÃA4/óe`*wba÷³V2± › Vƒ¬Ñ‚ÐʹïÁ:ÿij±6%I;tâEât‰8Y"N»X›8Ù‹ ×2“+2ŽM“Ð$ˆX0M”V(] –(齪¤áª’æÛ¿¨Òÿ‚ (=1TG‰+):™ÒSWóçak¹ïî¹îYW3R?þäû€wï8OÜ€>˜ôWêÀwæÌ~÷=ïeq±]¢z¥V©• &/j§b $ÅÊBEæ+ƒ/Ûô8©ÒUö«”vhaNQåm|âÌÐʺžSJ°© ´wrY $¶¤’ÒMÛtâ:ÉÝx‘Øj‘%¯ÂDW¢Íf§¹§'I»’vï§½ø·$éià("(Bœ ¡2Ö^PŠz)Ì/¶JAPÞf‰¸#h5,gQFùñÂs„uÙ *@’Xî¹û®»þj¢FT'þÊ›Þô¦¯ðƒ<ï ÖófÁ>ŒþãRLš$ ôþÿι™ù*ø”Bc0Z;™ËS½Ì¯«µFy X–ùêd@ŽcŒÎœ¹ê´òІ7µhåŸa¯|”¶Uém0÷¤XÛ%N馋t’lp#›>Nsâg [/A›ÍE#šÍ„­—Мø9F6þ9Ö\E;ž§ÏÓMI’ŽóÏŠ ¤Wæ[N;Î4áŒõšp•Ë‚çò@©²¼Yþ0ªì¹ÛIxðþ}%åª"jùøOÿôOo9_ý¢¿$÷}òŸâ‘ï<ê^ŃC)U˜7T¾ÀS0h˜mºh T?«²á¯Ä(/[ê’vëeºL1þ#È4àò¶_”òdE*1]¯pt’‚±ŸalãaŒ“»3*Ü» `‚­ŒnüÌØÏÑIœ§"]"±]ÄfÚñ`s 5ûÊç:]¸ÐC±àX*ݳ—ö‚°ø››[à‘‡d¤Þ$"ñ“?ù“ç%žÅ^{qøî¾ë¾ô_®˜Y²0ª *S2»]Is5&jÁW5ÍŒç`ÖÚ±âL!ÑÚkÚùq¿x9M—Ì5ùqß‚7³ØIÚF·~€æøºN: FÑÿ1Tóé&‹t“6IÒ%µIîU©WB†5É”ÂËd8ÐÚ9ÿºCeÏ)Óº2(Ë>u·}pß#tÚA6Â_{ãßxÑjÛhÕ7h¼oÜnšZ>ð'bq¡í£RtA¡¼Q7€)Ødæ3&À!Z(™bÊÊG¶À˜õ¥Z)PÚ) Å-{:*¬Vc<àTfòÍ ÞÑŸJL*1ÑÄ[QjÄ¿wµ†¤R#Do'±]›iÏe6¼Û­7Éä!f%Œ6¬XkÏ9{«7AFõËÔ® ºâw¶/I,ö}g<Ø‘÷¯Ü*Õ²*útµ þîÓÏýçß’Ñ” µÒ`*ÈB^Ó:$ BB!ȹ>ÐõjÃ&ØŒ6€úÅNWÊ 1c9 Ë{¹²’¯fêâì,!Q놊éç|JØ|©„¤6övA›»ÀVË~síWÄkØÔZL°}ÅzØôla Ã[ *¢@ÿ‡PeÃ…'Žbiii<ø¾×½îu­¡*Å*(.KÕE5¼ŸÿùÑ?w£×tÆþz}½NÛˆF£I£Ñ"\ds„9 ¼›Ì¦+6¿^#t¶?Œvy¶Y²§‰rž²A—Ö:ï„\sVÚwF-LxYþìºõjНp±|¹àVÈ\ƒ5á’ùã½YÔõlÐ4®ªI|_I2yûÔ)ƒ¨_NÅcÀ‹X…qz(úü|¿T¾oÞ| ö?ìe)U4 ÊÌ+m4°A£Ñddd”V³Ik¤åh a:7š ÐAˆMV:¼LË%w‘nÅjèL)ñõÑdE™”:!ïˆÌ4¡0á¶¾vè­Ã°`ÔfÅà(ï>«v¶¥sØû±áìÞ_ˆ?yªÜ?£´uÔ¯Œós‹œ9}vBòK7ÝtÓåÃÔk(Oˆ¸ä}ùùøëOüM…õ*­½–ë† £##4MŒ6ˆ(7ö#±¤iBœ8ög%Fì9Ğœ@}G+&ºÔ±"2Ç?ì¡EQØÌköDN Z¹}âlEçhC79Œé¡¸Öö+#Û>FàµN]¢<*ÿþ«.7|äsá%„àÍ.;·CR@›ž{ŒzÓSPR¾¼ûퟫó§Íž9³¶uåèጯ#ܹL‰Èo+Æ®H}ZÜ×Öh=|úoÿžÙÙy²/[ûÑkZiT) ´5hµZ4›MˆF³I«Õ¢52ÂHk„f³EùAF&Bë€4=à¡|e@h=Ž6›@,)Ù lßtžÚåÊHYÓS5ÌÌåà¥BTÒ?5Çù*"Äû¹Éw¾"(Q·^sKïÚ}T‚3¥’bmŠ2[ÑzíÊïÞëÍNaüÁ9³NÄŠ“$åø±“ƒ’×¾öµ¯ÝµRÝV 8_o_ZÜÇðÕ/£pci]tºÒåØo#j54[M¢¨A„npL¸Lò­†cÉÍÍF8Ø&U9ê ƒ‹±bë(‚ø8{Uš™5¢.ƒÒw€¡S• tƒÐDHrèO—²ZX$EâC:¨ZGyÄ®€°7¦Ôé>úÅJ6†ÚCè!¤{¯·zïSþAö*…ì7˜WÏ?35C{©]' ù••ê¶,}6ú××!ü³ÿ¹Ωö¹Ö«Ÿ® ÉèÈQ™V£¡ÕhD4u¶|Ùò¯~õ«FË  ¸ˆú&9=ušÛoûv5 gÐÔÆÉRaÒŒ4Qå,Y© ¬~[ M„$±$±ÅZPx-M‡$ÛVl`€°ù¬$¤’0ñ ‰Ê]^Õ¯Ö7°”M5MHdšDÁ( 3ACÄ÷Ñý0H¼l*Pbºçþ„ ¾›f0A3XKŒ; HX’ýjØo%XÀÅKŠ©dé7º¤6&}õPmÓ]ü¢÷³Gn)™œVf¹ƒ×{|öÜ<Ýn7ÃNyiz,Õ–Zú¹×ÞPÇ׿ð…/Ve¿RÐVÚ)Í&¦S:²”Úû0þ|A+¤iJ·›b VåQ*F$›qÊË þ&¼‚>Š%&M *˜›cúä­¢ÎÊkÀn`RƒHÐ Ö0­§¬Ã,}™îÔÏ“v÷­è I»Ñz3féK´‚IFÂõ4ƒ z”@7Ñ^#öYg„v²iFýRqÔ/N;¤iî&ˆvn¼¤Ä‹ŸÃèÈ)A:$÷’Ù;ª,Û/<3NÙÓ3ƒdÁ7¼êU¯ª5ù ²¾Bjæ^›™™áÖoÞžy3¶–Q¿Àd¬·I9mVûÁâYÚ åcE’Z’Ø2H–ÿÖžê˜$™%éÜMؼ~ŦšßKºð G!Ä9þÅX$‹"ñš¤" mwÞcJìZ+…(õÖ($Iˆa©}ŽøìÿM7x6\ŽjìÆ„»<è`;ûî>t÷6ªI#Ü@+˜ LyökTàÙ,¶5Ae™¬Èl€>ÚYÙ\ñHl›ØvHl—`l8wkwéf”LèqÝ(X0YðEÕÖ'ÐIФx…-Q1;3Çäú Œ1½ìx£ˆ¼øl_¿ÕU\ܬ“}Hþê—¿N’¤^ˆÖ¹ìg´!Ð!Qä¼.ýCäƒM•ËÊT L$uÀK’I,XPbÐZ$"Ñ1FuIÚ_€Ï¥=ÿ)Rybt—€JB÷Í*߀R`›çŠÆ"NŽU k4„Šc›t’yºéÄÝ;IçcÉî!*À¨ˆ Ø@ÃŒÒÈä>3J¨ú+:¼×Ø\l»€…T •„Øvè¦m’´MJHsô_±=º K #>y$èz•–)_.Æ”@¦z~—¯™éY&ׯ­“ßÀ0ôóíöE¼ˆ·ßö­Ü…“ûO•rÞF!Í(¢†^;V…±×³ÁlCšZ’ØeÂQ 2bT€X!Ð!©‰èÄ÷#vµ‚ÁU©&fä$K_ IÛªI¢b´‘Ì …%_ùNJY'jˆ´AZZ„jœD/›6iÚuvGÁ³òÐP7 Í‘ñßpb¦DnÊžŽ^Š@Ž`%q±‰iÛX"û‰¡”›N‘vn# G MÓS@ã ôS¹Ì’®”uTÊ=æÎͳnÒÈöàç•?ôC?´ösŸû\ŬÐ@ïõè›o÷¡½û˜ž>—ËUêç ËQƒ0ŠÐ&Ë;âd¿Ì%¦Pˆu.¸$¶$‰E¬ÊY£V +ÊQA9¡[Åt—¾Acte¶¾‚¥Îb;I—0™Ý;a³&¼M°Ô÷îåq^ñv3ëQ™M“Q7=‹ï[ª{ˆV1ªA #²Aî.âDò–\È€è(’ä t¬7MøºÉÝt .¦±æ¦Û ³ðm\ö0Oµ s¡_*n·te–º<¬¥È´´Ø¦Ùjô°!"¯>X®gŸRÇ~n»õöÜv–e P>4B¯t8{_`¼‘×Ë|Y´²x¾g­Ó|%±n”—*l^ùxyá9$mß\BÉrEÓqÚ%¶mâÄŰ¥ŽÎdׂmô+ÎK¡\=ˆ0ªI¤Gikiki™u´‚ Œ Ö3¬÷ûÖÒ0ki˜1gxV §Ñ÷™ 7[YñP™ˆ B" ‰uàë¤ ÄiLcíÛ뺬¦Éâg tƒÀ4½&È0êm}õÚnõ¼ºstßùs³ •‘þ+•={ö\*5ÓÜ·Ûmîºóî¼óòjg¬7 í/ŠÐ¦äi(S?¥P¢I­8Ö›f9J2P¨\K5Êg@õÚ›’i’îÞ!tx ºù½ŽmÙ%Ÿ­ ƒµ ˆÍ‰ŽB÷ŒPs¶À,Ñ"pæ`ÐÊ™04^“,Jû‘}šÐwt„!(—ù~—4Š7€ IDAT :ÍÀg}ÒɶÔ”Ì'‹èщ.ª âöh{ÊOÖMŒn UH¦ùf—ó\Y€)XpùoaaÑ÷oŸaúù¯xÅ+.@ùÑš‹¸sÏ]t»IñP­ ‘Ï9×ðö¾@»±¹x€fš/xWRbIS i9õmO(ímWN† TD¼ø…¡ })#Äé"qºH’.ۮϡ,%3RæžsšnæªËl„ˆ©³Å¥$iB’vˆÓ%ºéó¦R>Oår"às?;Ö›&âC›TA)3*˜…Ì“¨6 L’}Äí;†ê¥šã7ÑMÚ´}G: vHüø\÷~™\šÙ¶ÊÀó2àÁ×¥“ÌÓN¦™ïN1×9á–îIæº'YèN±OÓIæIÒnÊ×ĵv¾ x8™4c»qºD'g)™¥“ÌÑMÚ„ë~ ¥¢áÀ·ø%T|Q@Ó,‚PU8ËQÁå)!Ë\çŽ-Î-ÖyY¹¾9ï¸ãŽFÆ~˵Ûmì?˜ Ûª¬|Ùâ |8}îwUùù™×ÃzÓ‹X‹ÒÊŸ[}¼«”q2 qrL¨›$ó…ÈâPa¢g ×¼ŽØ¶é¦ ´ã97HÜvHÅ%êN.r¸xˆ#’¤:ÉKÉ4sÝSt'z–“,ÄS,%gé¤s$i§¤¤T]n…17‹r±¤~ |;™£ϰÏÐN0ëÞJиn¨w{Žî¹? 4-"ã|ÏNûu¢€^peÈÕ›—¿¦ú×ngã û–ç¿üå/oduε`y®ˆ´Êàì?˜›2Pi­1ñ>_—mÓä#á<•ôfwså)zÙ¯ÈENý𯓳x@‹"Т[Xbí<ݹOÒXówBIW 7’ÝÙO`­«‡Õ JÈ"íÀ±ÙŒ:é°6¡kÛ´“s,tϰŸ¥- $º¨`'ñÒmt¾NbÛXI};8­Ó˜Àû¤³÷óÚ°(,nTl;|çXJfXŒ§i'ó˜µo%©ŒeK{æý´ik‰Ì(‘iaTX2½À #s¯6;lõ×P{]»Ý¡ÑŒzØ‘ç_‡*_êוeß¾ý•›g †ñc<Â0òáUÚÑ-±ð/ž&.yšZ$­Ú™rÊWr eÔÁQZ-„‹ëtn'Ÿ‡ ‡qEiÜH2ÝÙ¿ ©¶¤:%R‚Å¢¥áòD[íä@ eÀZ!I»tãÚÉ,KÉ mÑè ïB™ 9ØUãÙØ‘WЙù0ħTD Z„Ê…`‘d¢X“Ø%:éíd†¥ä,‹‰Ÿ^ûŸ F^:Ô;$í;ö?Ñ '<øœÒ™^ÎÌ“I®³çUÍ,D‡[n·;D°SÀKñ,Ë€/­3¿Øw°ä3u@1A@DQèS¤•• O³zXLöKmnoU+'u/“?K…¦áXŠ7¨Æ³g¥à€r1ÍQã?F;™w¦;í©ÌÝdÁyR—]>MSÄúá™6%‘.±]¤“.е jòí(³¡ï:Ú…^ÿËtSo6±‹~,p–¢|ȧ³#.ÑMæYJαŸa!>ÍB|–v<‡Z%øD:tgþ›Þ`ŒÐ´ŠàƒQ§BT*Ÿ~™ /óQ¹ÊýuÛqørb€·ß~û¨ˆÜØ{òüü²ªXïõȨ`9Aù*èÜ?ÚóÕeò¦ Tæahad†xáVè”b-ºq#¬ù :V³”L³Ø=ÃR|–¥d†¥x–N:Oœ.bÅE›äspØŽ3é$‹ØÑB{ÿo™Õç«f]áR¹¥méøAît©íäJÆb<ã@×=Å|wŠ…ø m ÑëßA0òâeß­·tÎ}#Ó4JàsÔ/“É땊zYV[¢e%…ÒyÇþƒîWlo|ÉK^2 ž‹È ¥&µ®“ÿ$©ËXp|n¸¥Ò™g¤pÑe½"Ö‡‘{*àî¥K_eÿ Wµ4@iŒP,6H±X:í¯`נËó.ƒ¢·ˆ@м‚+Hæ>C<3Ú„j#£Œ`¤‰–&ʈUt“6qÒ&NÛ¤tQáEùý”ª‚<ß?ò½¤³%¶Îw«Å|7GM—ˆÓy:ét–v:K×.bG¾Ÿh̓j~‰š’vîAÿŽf8N#÷ͯG½mØœÀÐφûYñr÷n'&j„¾rl…"òBà‹ŸUG*÷ï?Ph±ž-A€ ´O^„õÔ±_±.äʦÎû‘O£JD[•_ f­ŠQŒ8›qc@º³$šøTPMM1ˆ" T3ö’èy´Ïþ9ÎaŒÌÐBIÓ¯RÓIçèÚE’´ z|Åg¨p‡›@Æ.ÒNgœÛJB"N#ïÚ9¿ž' .EOþ_Ბëµ%¦{ö7i£4‚54‚1"/¦¸~“’+m0X Ç„B,½]Íõ½û«ëŽ`6ü,J¼¼|G+h’R¹×¥QóŠƒêy°Ê¯@”v¢©¸h…ëÆŸ/ä÷P¥ÿÕÅ+> B㼪"‚$ótgþ€hí[ÀÔÝf,¸÷·2Û1“os”ðÜߣ’ShÛ@ÓðЉ!µ)î"q:Ob;èÐõQ ±ºé<Cœ.¡”Kù–Ú6±]¤kIõ8jâ?­JË-—4>H÷ô/ÑЖV°–V°†ÈŒy֛閙¿yy¹NúöÓwÎ0`ËÖe@§IZ>Där(Xðî^> pêÔ½`A)ð“ÚÔ"Æeu^·Ò¥”Ó|­[œ ^³sØ' MEƆ Ú;û33‰¯ÌÓyáÄÏ£‚­}`ë]W÷)të{1Ñ IÚÓ]ø6váNˆ¡%$µ–$éҵΧ`1 ¦~àŒ,‰tè¤sXIr0¤“š Ðz ªõ<‚!Ýju%í$>ó_hhñþé Á¸SPÕ­w]·ý´‰Iæþ >MË4ik¼Ì7FŒøF™Æ[¦|°<È Øêî‘&¢>ð9ÖiÀ"ÂÔɩ¥VºaUDÓÚÔ’ˆ› Û!M]DqÞ´Ò‹-Wª¦¼c)K¹ø¼ƒY~Mˆ–:K_¡»pjô5¨ðŠ™¯W¬d]æœ'ª¤í;HÏ}Pfh4ƒ54‚qšÁ¨÷t”ý¼nòÇz³Ërå|Ùkÿ=œÙ&Û*öKOl`YDdsOŸ>Sy¨‚Š;.78‹øÐ% µ$X uùœ1h…3µèŒz²Œ2è+U=ïïp÷W¢Áh4êC5!ÊÎÓ™ùIp5zìGÖöo(³º>ÔOÒ)’™¡;ߦeFi†›Üàö`œÐŒê†Ïm­rð¹ð ŸËFAžl`»®F¶+ŠïÎ1IUöW4áú¨Dds "ãu6Àv»í.Wž *ož`8Ö~´‚›‘6™ìç´ãŠ©fà@ß•¿4€|"é,͆¸èe”A™# ”Dh‰hÇûèž~Ò|´^Šˆ®€n9e¥wß“[R’¹OÃܧˆ´¢nÌ™1ç†Ôan™%TÁ7,°Ê¥z¬Pùì~I͵ƒ(îðŒ÷06ÙétVl.€â… M¹Jí´ÒÕküÁ~ô²OªÞ—ìZJ9JˆAdž•D€ ´4ÑvŽÎü?п•´ù2Ÿ…H£–òeÏTžp Êvñdþ3Dö4¡Òé<ãypi‘Ë …£ >jÖÅ/É·¦|Îò †½g7­"R ß‰µ–N§K–•½ü@5P‘ðgå‡z*Z‰|)ƒµ´2°z%‰âœrÈd;ü`y|rt %DÙÚ4Ña -ó˜x‘öì'é&Al.CÂë‘èz`tYmù‰ØyìÒ· };ºû‘ \°E°%§ Í(¡iø1ºGÓÍŽ¢- öèŸQjC)Á®ÿUÎGî[®ôŒ:1¯Àl'@·Û­‘Õ¨Þj+V_Áå^´12Ê—]MÚ9wü‹3³}ŒÊ­ÐYŽh€‰Ð¶1#Á(Y %Ú2O'~ŒîÒ^âôc$fÒ¸7OBXS%=‡´oG–nGw"T†P7 ƒ p#Dz”À4\&沞£ô°Øü"™ô²Zž(õÞoùsÄf~é ÇY“íÌÖKK™ü·’œFItfùÜa†erûÅ\|ý ¼Í6_~%3Gsø®=ØÄë¹[ÈÇéâF¶)¢tˆ¡‰±-Œ%6'”:v‘X–ˆ“ãÄí¿!IÿŠ$¸^ŒUë@¯Aô:”^‡ /`åa‘Ÿ; é4¤çPvÕýAü¨²m„›Ü vÝòÀkùß~ ¯Î2fAÙ¾× ²¬˜0dü‚ÍLlÙ™C0süç²'ЍT‹›‹w¥eMô)!¯€ˆ¶Šˆ˜ÒãüÏLñôR:˜É˜Ã–MïÎÁ—QžµÛvŒñÈm·’v’ê³2–éA)Q‘—9#ŒibdÄÉYªC—%º© »JT—XwHìq{O)#ñn~ºqŲu¶ýtOü—\ºåÇG˜h«[ëãÁèf>üTëRîfå_X9vÛ ¸¢(ÖnÛÎå/})aÓ…rí¸æN=ü~å³(ö“Iíœ+A$=°OÌ4àüÚš·èßU_9ÕK-Wª¨/&ˆÜT{ldÝ:.{Ñ‹yäÖÛiŸ›C‰¸úø/ñ/œg¦•nP!‘nbLB€%”. •cuLœ¸äFÝ´MWÏÑV³h™¦-ƒëÚû>jÐÐã4ƒu´Ì‘÷”Í 2>M¯›°'Ì|ºöñþÛ ðS—m×<“ Ÿ}CŸ¼´éÒ+xì®Û˜;{bÙºž_YýuVܛ԰O@¬+Ë[®œ/L“.ógN0¶¾~ª°5®}Gï¾éÇŽ”ž79PŠu”P¼¢‚õþd hÝ$D—gZ»HèØth'³h‰°6%¶ì°ÔMf £ÁFÆÂ4Ì8næ„T6QLn’ò­”›Uz×_Lp鋾ɋ/xκm®À§°ˆèÁZ "s"²®l†‰ƒÇ bqcú©¯øÙÀkÛ³æ_Ž=t/—¿`p°©6†í×_Ëø[8vç}t» ±ñr¡ŸsæÙ{³á—â&¬¥0ÚÑ«m l…›b«c0ɹ¶»LQ€Q¡¥i&hšIšÁ¡n¥fË’!y2¨ŸŽh๗ŸØ¶…‹¿÷94ÆÇœçÊÜé•Àw¾Õê¯s\©OžÓ€E½”™d{V®|Ï:ª·EÙ©ã<ò훑´?[}vÀš-›Ùõ²ïcͶ-pÖÃ3 |¶OzB°€|–,½ 7þD¸QmÊg5UC±Zê–Ï =â”70*BùôvåLU¹5©þM¿èF®ø—­¾©G0süÈ€£Oðzέ7ÃÌ"2Ûk†‰¢(W@Ü­JǕߓ)=@釥äFç!_ ×$g“°µò˜‘³‡eÿ7¾DÅ4PY/W/8pHúÀ‡ˆÌ"2WÞ AŸ Ð_YœçA"^»±Ö¢u¯Fì®)÷ž³/:põÓ‹¥ D`aú4}õ¹ä¹/fdbmøÊÛ£×sÉK×3wrš“÷dîØŒ§„Î…Un*«ýEäJŒ*UU‰"÷ò¬Zæ.Y*+åæŽb­Íäe;Øtõ.šc+>Ußs|û›ˆMBaùõjËp ®Ÿ£€À\ygVq7]–zU(§¢ÿD<â)Lu9;îya’»¢µ ™*ëÞY\dß×ÿ™Ï¼É /ª_yÝ¸Ž‹^òlæOÍpêžï0{ä,H•*/$ŠdQ$¥!£AÙ‡¶“ìin¼D™_[¦ieùžç€õW^ÌÆ«."h КÆ1û¾öOL=z0BùMXö VþVW꯫ñÏeJHŸvE!ÝNR°á’Ü'RgÕÆw¦¬ÚwnnÓ©ãštÚSTÏÉ@¨òg iÒå‘=·qöÈv\ÿlÂF£|åedÃZ.|éõ,ž:ÇÉ»eöð?™OÇáOTâ”—¼ œÕ€/kø^fÚ›µ– „c 6¢+“sV ΀,X›QE…¤€S¿ÃÔÁGYw¡bc¼ˆeð•×àÙÚ8NsÓ×n%IÚ,ÌŸfêX}t‰tê3K+SèÀ0vá8k×o`ó–ílÚº‹ñu› ÃV­O}ØrîÈqŽßû 3Gö|ý̱ É•¨_]y<`ì¿G—*ÎDd_ÀÒNO'‹}HnÿËöQ¡†ž…ª¥½ÍM¹}Îà (+ˆv¹­òÔy¦ö‚ýºHçÂv—ƒ3Ó`­ë@Iñ#ò,’ªüü©ƒpúÀc¬½ðB.¸ú kÆ*àË›Gê·+E)L+ \v"t¬rP*Ê(‰ÑÚÑš::j'"œ}ø0Çïy…³g)Ë’ý,t0[íåJଭÍ*×å÷°uàs|Õ«^uúÓŸþô´”Üq"† ë+7¯hd,×JêÆbø}J¥h«e±V;*¨S¬­V)ëg$rQmaåØ3£¬X¯|ˆËŒŸÊA|Ú\¬£~Öz@æ†fÖ‰g~”Ó³þâíl~æ4&Æý{ ¾ÇQäqÞÔ&)S=ÂÉûöÓ™ŸÇ¬ËÔnˆ oV¥›áÀ%œœ÷: ÛÎ16½oß¾ÓYf„}â2¤æ'6 FFš,-v¥ò¬X7[7ÚR J;j—*ë"R´EY(­½& @gsX±óòç²ãŠQÊ0wögŽàøûqÝä$K‹Çý>‹E;…ÃWıÖÔù4­E+‹ºˆ]eQÖÉ€~4’«“v~«ž÷#Ln¾(oüñÉ­ŒOneÝ–KÙwÛ—è..zÖë©_êŪbŸuTÕz*)^6tÇ´Ÿ‚À¹£§˜=2·hãLlßÄøŽMŒnžD« ”}¢J¼ØaþØY掟fþØíÙù èÛ°O)_Såú»¸úů&j•ÆÈ8ÏýÁŸáž¯œCûoí¹Ë®‡g¾§_ ®pJ7mÞÀÑ#Ç}4«ñžƒŒ Z'«i¯xh›ïsÙS§ùfÓp)¿N-ævÖÊSãë·síËoâà_åô¡޽ŠxV+Ο‹§zŒÎŦý¶òÀó,ÛSOg&r@kŸ›£33ÏÔý¢ƒ±-X³cã;7Ž>q©4zKÚ‰Y8>Ãüñ³Ì;ËÒô,…°X2/Jl½Ô¯z|<§æ²ÿ;Ÿq#u>E¥[.¹ŽCûo¡TA·:6\£-É=Ë~(¸Ç¯+ËÎ;¸kϽî¶b±âRbdVÁLöSÖ tʈk<…vórøñÀ(娤RLl¼˜ÜQSLØd÷ó_ÁÄòð_'í&Yœ”WLüƒè2ЍÄÙðTöU(3dŠN1 'cÎ:Éì¡SðMM4Ú"k¢šK,¤S,-Î/vŠp®åŠñB‡¶šg¶}N48—NŸnÓ™žw‰:K®Jñú™iûÁVöÜ[£ë6põË^ÍØäæe«¼frkßµTž“¿\i=$¥”Ù±ö@‘¤üf‰¥'KêöÛJ7rž 7 ‹Î'â’}«4EÄÅÕ&!Åh•Ë¢S2,ž>þ0i’¢MW¤ØÞtÑ•ŒoØÎÃßú:gŽ<âÓÂyÐy*XÐQAA|n¿Lƒvòfñò«{—‚&8?twaîü"©¸ä”óÝ“Ìt1×9Eº!F¯0]GÚM˜=6…D!iÃЉºDfœ@E¹KRúXcºªÔQÈØ¯;Ç^÷|.|æsûÚ¸®´g饜ïgþý@¤ïúljûÄ"r3Yϼæ5¯Y‘Û{Ol6›lÜ”iÃxÊá+ä=Yú]‹¸ˆbë”›úŦnºù$õ™òSÚ‹ç8úð.uWiÉ4ÔlÛZˆZkøž½’+_üÃD£kH}"q›Z¬¸{gf ë5rël4 ©K îÿz;Ù Ô±Á*K,d™aJ¥ÛdÐ=ƒ¯ž÷²ä:ê'lºä ž÷Ú7qñu/ |Ö¦Üó¦åä¿rûíä¨_í”]·?üðà P¦á+ârEWNÞ±s§NžÉS©¥6õ3)rM±~—²^ ÑšÔ:À*…Qâl|JÐöÝõEšcë™Ü|Iµó¤~½vËE\÷ʹÿNÝ}6I½Œ— |ÅD3Îè-þÚL@wÂ)-yÔMÏx‹ÌXÞO‘† Ô=Íï]€ºXW?Šºîí¥P%‹0:¹žËžÿ2ÖmÝ9t-ÅZ¸õSœ;{¤ò4úžWjÇ ¤r•ûK%©"ò•¬½üõÞ“wîÜÆž;îê«Df̵^ëä=‹ëÀ¡• J¡Tù8×ûíÅsÜñ¥qÑ•/f×µ/¯) ¡R†W?›M—^É¡{¾Í‰‡ðÐúj©ÂÚF ÚwtVŠ TwMæNéÄPÝJFY…´´˜ühùœˆ¶t]=%¬RQwŸ‘5kÙqí \pù3VåeYœ=Ã_ùœ=u2%­Â¨—ÂÕÉzƒAYf¿@Œµ¼MD–¤g¶¤­Û¶¢µäóôl^ ël{Nçu’v‚òu*Ž,ÂÅÉzåS95ª¦ pKF¥Ê,puT°—ºe¿{X¿,XÇžË0È:ylýzv\ûl6^|ÙªÝ{Gö‹û¾ùIâx©`ƒÀÕKWeš&uà[‘Û²ºä°›nº©#"·ôœL†lÛî´¤,B$ÛÎf ·Ö:6ì'w›Ébîwj-Iš¸éº¼,˜ËˆiÊÌÔa¾ù™÷qè¡Û ŽÚ³Ô¥R ›#\ô¬çóìý\xífA!¼ü±Y¯Ÿje#ÔVCË•¸÷~ËÉ›½²aQw°¬Ù²…g|ÿ+yÖ«œM—\¾*ðÅÝ%îúòG¹ûk'‰Ûˬª•/Géê@)H>kh/žDä–G}4O<Ôë¨ü²”fÌÌ–Ýßs9‡õ7Ë(aÆŠ³/ÛË‚ ÀzVˆ÷ûzºâ·m>Cü•iÚáþ[>͉G÷råsÿZã™/ºÔ±¶MØ`Ç57°ý™ÏbúðcœØ·—éC‡|à©«‡Kl+r_¶±h•רJ«_úòEòÿeÊ–Ý+;§LýÊ@-w~q]4Òdãe—sÁî+hM¬ª½åÄ#÷òà­ŸfqþlhˬžÚ Ç~“´ë¶úM0_.׫@ù¤ˆü?½]vÙ¥|ý+ÿBÛÊC2JèÕpL‹õ.·ím(HÅ`)$Ÿ¿Öy½kO„“‡örúèÃ\üŒqÉ5/Æá@àõþVJ±nÇE¬ÛqñÒS÷srÿ~ÏÎTäÀ‚í:9±P=Ê©åNr –Ö”©_ÈÙñ²f=€ÚiÅäŽlÞ½›u;væ"V[æ§OòÀ-Ïé£ûèõ)WAÖkòYu9¥sÇ`€þd¹~¾þõ¯ø£ýè-Rš5Ü ¥K.½ˆ}=ìšÏƒÎ¥ ˾lC6Q3b½·Ì'.µ<¶Ì¹ëʃ€²Ò&ÞõÏÙ¿‡ÝÏùA¶\rõ²À«û¶Zl½ú¶^} í¹9¦fúÐafŸ@’¬Îe ¸Ð]SVYpF·V.å+³õ*¸ëŽŽ°vÇ6ÖíØÎÚmÛ0a8ÔëJÒms`Ï?óèÿ‚Ø„^Yr9ê7˜òÕ­ÿ >[¾[:ôp¹ž}±B"ò1©™7x÷—óÐÞ=ì7uI!ý¶»Â{Ÿ5Ít[•™Bœfª @ŠP¬Bpî³¥¹iîùò_pøÁKÙ}ã0¾¾:CQçå;£9>Ζ+¯dË•Wb“„sÇO0{ì8óSgX<}–4.'wÌš·W Y½ ªÌb‹ã 4ÆFÙ0Éøæ ¬Ý¾‘ÉÉ¡Ÿ1ðÙÖrtÿößñE:K³5ÔªxŸa©ßò€ìrœtQ¿õÖ·€Ÿ‘÷òÅÛ¶oell„…ù6à3yjè(a¢ïå«,’gº P~âgTX›¥Û-/@I£…ÓGæÌßþ1›v^ÁÅ×½ˆµ›v®ºAEëvlgÝŽíù¾¥sçX˜:ÃÂé³´ÏÍ·Ûtçˆç—nÑIåSËß)J0Í€Æè8­‘q‘&#“ëÝ0ÉèÆõy2¡'¢Ø4áè¾»x䞯³8wf¨z=(å«Lµë¨dÕLSHp³Ë÷Ï’)"à½õVRÓ“ögö×"ò#½7¹õ–Û¹kϽd3kPÌîeº| wq,;q3¡S>U¹^J3–gÓ:¸D™Ù¹†õ[.æâë^ÌäÖKúêþx‹{Wë"¢Îpúôw8qì¦N`zîg]+ÜákÇÿM›/g˶g09y1££ëwDô ’&1Gü6Þû/´gqì^(옃´ì^¼îü´o»þú4_wâE:Ý¥>Ÿ:|øðkzë_®ëÙpŸqõUÜ{÷ýnî7ÄË|ÙÄ3ÞÁ/î˜RE: 7‹¸³ýJ‹·)¢ý1›ÛèÄ ìî·fñç‚å̱G8{ì1&6mç«ŸÏÆ ¯Êí´š’½³RŽjͽ0DD´Ò˜(DŸ}¡DžÈÒžŸåؾ»xìÛ‰Ûõa\uTª|^/;í§Žƒ¨ß`–ÝûÙ¯oÏ>ö ƒø™‘厎pù»ØûÀ¼b…I·ú"¶$ÛéžyËÊ¢~æÈög ËF”»N•ÎfNfæä_5F¸àÒ«ÙºûZÖl¬Ÿ´pu¥qÝ„ÓÙz–9êÛ+»Æ–€øøŠM¦Ýϱ}wqæèwòi`ëýƃöõ²äúýÃ)#U0v“v>Awø¦Dä uïT ÀŸú©ŸJ>ô¡}LDÞÚëJ¹öÚg²oïAƒ—wT™–­iÞèâ]cÊV+):ÅÅMUolö ©üv,¹IºE?xGü6ã“°e÷5\péUD#çù,"~öô„$éæ³©ÃÚ!®^‹ˆ»6McÒ4ÎAx¾ÜwöÔqŽï¿—ï'î.–(T/k­£xur`èªÔM)ˆcÄÉ"I’ô¯c/ëÍÚòÿ+ïÌ£%©Êÿ‹5·—o©ªW EAT±ƒP* Ûa¢ã=ˆÌÁlÄiÜ…AÁFdÎÐÌ âívlé##âH ÚLÉ: [AAmÖþ¶Ì·åû7DDn/ómUEý'##—¸ùËïÞo¹ß‘ŸìÝ»×£tœ1#"wˆÈuýíã/íÊvqäê•lÙ¼FÈóìö¯áíïúkº²ËËoeld Û^{×®A‹4§ÄZ°Úf§ˆ4¼G‰«YÕ~„Æ÷*dž(>5–§¥»ÿ­XÍÂÃŽ$Û¿t–ã¯ð:‚ÀÃó,<ÏÂu-|DÒ3Zø>Ñçªxž]ƒ°®ã§ßuÛ»ƒÑ][ÉïÚ†])w­íÕÍpÌGnh£AÒ¿ìXÖžq5} WÕîÿ«/þœžý!í`µ_‡ÕÑ-¹£Óµ¶5Bb¹çž{î>ÓÚ§OðËû$^ ©n$¨¬}çÕœpòǧüØVu’çŸü!»·=YsBKd”42á8²npDKä´&­FJãq¥éxüh¦2,\q ]E÷âe¤º§j³F¤Z`||7¹Üòù­ŒuaYÿyFx‰ï²pa‰E‹VÓß¿†¾¾¤R½èz²­!ø>¥Ñ Ãäwmcbp7Aà5ÀÕ9JÒ8®kžÐl˜Äϧª› N<õ VûÞ¶ÖMÅ3OÜÙÐõ׿§Pëûýûë:Ý«™æ Þ&"WKK¢jOO7‡¯\ÁŽí»i êz‚cOühÛÆ'S=œqÁõ ¬9—?=~/ÕÒxa£ÁQÿÅG«¶ƒfíXjÔªÍ4¼«þºS-1¸yC›_ŒDŠlÿR²ýKéî_B¶IT]!À÷]§‚m—°íŽSÁuÏœáVÕÅóNÂqŶ‹µÏ›fM3@„òÄÅÜÅü0ÅÜ ¥Ñ\ÔÅ7ÂÖè6iŸ53]œ{j—ÙšѬ—¶–·Ÿ} éÌÂö}ÜÙ¶åaF†74}ëYàsEä¶éîÕ´àî»ïþ‘ˆ|²µoãÁþOƒTYyÄœûî›gþ\‹ ÏþŒ­¯þKÓç[µÛTmï+Sž3E#ÆÇšµaëñ}%L÷Ò:¢+¸J•ª7NÉÎQ±‹æ½ Ì\" )¡ØŸ"mfɘý¤õ^ I'Ž×ðjÛ67?ÛÃ8SZ—™ìâ”3¯â°#g÷ûý¿ü »w®oúŽBy4'6Á‡ˆÜ788¸nºï›qÖ´ˆ|[Dþƒˆh„÷õõrÔ1«ÙôÚâ;ší^>íwÕNj$9åŒOrØ‘gñÂ?f<¿ƒøßX×v¡k§YÛÕÇzÍR·•Z›va¶Æ¸¯ ÚRDÀÃ)—pü Uw‚²3JÙ%HœC*1Kø”.Ê•ã±Æ×c›ls!)£SK£):D©hDx5ƒ× bãóÖ1àTÛÃ× ´ (ªÊÇ\Àñ︔Drúj«’Jõ6|K€åT:Áç‹È·gú¾#ÜŸýìg·FÑ‘)'9eíI$“ bx¶lþMݘ,\rü»[9ãÂÏ“í]ÚÒ}Ìüno6:M›§­Ô@\|qñ| Ç+c{El¯„'*‰žkf}M±${®ÁÛ+c{%¯Œë[øâˆÛtîéÚHËû:CÖi¿Es*ŠէóÞKï`íYëæŸëVxžF7UÕ*SàCDþihhhëLß9«º"òMà£"b6žÄ0 Ö¾ãm<ùøÿ ZɱkÇzVqþ¬/JQ–¯:CV¾“›×óÚóP)Ž5è´ÆäÒè3Ѥøp?|5~wܽάë?‘ÐYîNPÁò‹Ø^Ç/£g¯EÕ¦ŸUÖNTm f÷:œÂ=èž.Ç †ëújª hµ©Òc±éµ_k7Üh€´#õÏÇ0.=ìDŽçeô.<|Î×ðÔo§XØU;OÙ*µq"ffí¦›nšñM§Ÿ~úèÓO?‘³[OÖÛ×Ëðà0årPz™þÅ'ÐÕ5·MQz­äÈã/ÄLf™ÈïÀ÷ì¦Î¶ÓþtǦ:€ëƒï0vj_\Ü Ší•°¼I,¯€¯­$µào:~óL¢™ÇâTG‚á2·Z¡Z+M§(ÍZ­y\8SÚÖôãÁxÁ’#9õük9æ”’LÏÆ—ÙrÇÄç¥çïcã«÷×Àö<‡Jgo¾6ß=£ËwÞ™‘"²²Õ Ÿà·ý.rŸ„ç9î#¼ãÔO£3ûÎÚ‰ï¹ìÞö$Û6Ú͆G«Òdx~àáù6¶_¢êLRq'±½ ©Å?B3ÖÌ«ýµëp·PÍ­#¡¥I=¤Œpµs]K ©QŒ<‚±Ù2m¶dgbÝ‘¼lÕZVŸø.™ÿ5Œå7óÄúïÏ¿NãÐe²màÛ7<<\Í÷Ï@€;î¸ãùUg#/½¸¯lj°`52™%œ~Öõ¬8|ö.Œv’x­¯<ÂÐΗ£©µ­0*Lõ¶·vã×%²BýÀà ¯Œå¨º“X^5ýW¤z?»O펥:ñß*?'©gI=$nL=ƒ®šhj¸üƒRƒ°U NµŽ§3LŒDŠÃ9‡#O¸€Tfþé]žgóâs÷ñꆟ#âÑèó«Ú%*ÕöÚøàðððƒ³=Ïœøîw¿û ˆ|šžAð‡Gÿ/ùÜx“%tϜϩg|ŽTzßòÝÊÅÛ6<ÊîÍOá:V p­ á$Œv.ŽWÁöŠTÝ"–[ó]dÝÆ,l´Y‰H@eì°Ÿ"it“2¢E¨õ4†j¢¨¡Ã½q›élçœî^°ŒUÇŸÇŠ5g ë3ÌžŸA÷>Ç“ëï TÜSƒ.Þ<ßf²8Ö ¾__2—sÍÀÛo¿}%°QDR­ (—+<òðp0Á³žf¥0{X{Ú_³æ˜÷ÏyÕÌV |¡Ý/³g볌ìÜ€ï{3€WN—?Ò|Ul¯Œå±¼"¢¿®EßeþÙÈmE\Êùσ÷I=KÒȆ RëÉh¡Â(ê£4ÆÂ§sÏ$3½ºú¬XsÝ öô³ËšäOOßöÍÓ=‰aÄe¢8Úrk€¯*"ÇŒŒì˜Ë9ç Àm·Ýv£´™;°wï Oþñ™šöku,÷ô®bí©ëX±ò¬9Ÿ·x®ÅàÎÙ»õYr»_âÆS! {ܰøy ~íðC£ÃvËX^‰@;š®þ¿GQf—(ø£€‚ªÍN³‹X”rŸAõ7‘Ô»H™hUôšf„aÉhQêÃVøŒDšCŽ8™CWŸÆ‚¥«÷K~¡ëVyíåûyåå_๥&×èÚ)”Çq«|ˆÈWFFFfôûµÊ¼üÎw¾£‰È£"rn§ñàÖÍÛ›ÀkqÑâã8åëXºü”9Ÿ¿“8V™‘=¯’ß»‰üÀfªÅqêÆFŒþåG±hù1,Xr$ªºrƒÀc󯇨ðüO±¬ñŽàÅã¾r¥Ø ¾ÇDäݹ\®ýšjÓȼ¸õÖ[—‰È‹"²8jDmó}Ÿõÿúãã…ë 1”Ë–¿SN]ÇÂþ£æÕŽN""” #äö¼Nnïë!åqÜÀÁõ¬hÜWÁñ* ŸDfÑß¡ª³wQ8Õ?21:¨{—Ü‹™:{öm &(~ Ü ˜zŠ„žÆÔÓ˜z COÐÕ»ŒÅËeñ¡Ç²hùQfz¿fR‹;¶þžŸûŸ”Šƒ4;­ë1éÆqßDa´|#"rr.—œO[æ À-·Ür!𰈨­«”+¬ìI,Ëé  ›]*‡¯:›Ö~œ¾…û–f^O]Ûù¾‹ëV±íãùä†6‘ÙÂøèN “Cˆþ2½×³×*˜ú(⇫QªÚRz–þ3ŠÚ=‡vúT'¾‡*ÑÓ»œ¾…‡³xéÑôr Ùì‰. #êš#­ZËó1Ä¡+ß5'c¥~Sâ„Pϳqœ2–5I¹Dä¿är¹¯Íé‚[dŸüÖ·¾¥IXØèœvÍñô“ÏEIÏí2_Úg¶tu-aÍq³úØ÷b&:Ëêí—¨\˜Åj½"•Ê8åò(årŽR)ík”ËW#rدÖÇÐî$ú3ÉD7†Âæz6–] R]…ë¹hSUÝE:ý2ŸLfa`?™ÌBÒé>‰,†‘B×MTUÆ€õÙ‡dbl›6üo¶o} ß·™MCÝâ Í®ët‚o½ˆœŸÏçç<îk”}ছn:DD^‘Å­‰ˆ048ÌóϽL¼$êôšPi:®iIV­95ǽŸ¾EGÖÎÙ¬ñ‚>Ç©â8eªÕ *•1Êå<¥Ržr9Oµ:I©t2ŽóQ`®!™ü!½½;éî^F6»„Tª€ju’bq˜Ba‰‰Ã±¬O1÷ð]Óügºº^$•ê!“YDW×"2™E¤Ó H¥z1Í ¦™ŠâÊZ}Íaê úžËÀ®gÙúÚoÜûíò§×|á±Bi »Åâmø]GDä”|>?0Ç‹œ"û@€o|ã§IX÷#Ó®;Þ½k¯¼üz“øSNßÔÈF¸ßÝ{(‡q6+Ž8‹îÞå5ð|߉ºÛ –U Zµ^_µ:N¥’¢Z½œ 8zW'$?¡·w==Ëéí=”îî¥$“á˜Ï²  CLLìarr/GcÛW2Ÿ²ªn"•úét•Tª¯a&³Tªd²ÓLGݲiC!7ø ;¶ü‘=;ŸÂuÊm£$­ v‚¯X™À²*à+‹Èù|þ™yÜÈ)²ßøú׿þ>yPZ2¨ãslÿó6½¶­ „Óï·Æu…ž¾ÃY¾ê4–®8ÃÌ`Û¥Hë…ðU*£”ËcXV‰Jå\\÷b`~ÎeÓü½½/ÐÓs}}+èéYNWW?¦Nzrœ2¥RŽÉɽŒïfrr€‰‰SpœKçy'] ã!ÒéÇH&»ÈdN/¬uɱ6,N0¼ëyöìxÇ.W„ªÃÕ1™y¿\¤R-w‚Ï‘KòùüÃó¼°)²_øêW¿úqù©ˆ(í|„{vï §uNéŽg/JÕ—p¡é°ô[Xò7]L¶÷P™^4#iÁåò ¸î%ˆôwlïôHü‚ÞÞ—Éf—ÖàËf“Lö`Ñе°¬IŠÅ‘„Åâ'aÛ—2ÿ^ŽDâAÒéWH¥º1ô®UÄ*R߃çVÑ´0ÃFUÂÅ%N[›KúÖ¬4ŸˆÈ'òùü?ÎóbÚÊ~àÆoü‚ˆ|¯ÝxPDÎñÊ˯GS;§v»í…š/ Ââ‡^4õÑóÝhß#€T÷ûI¥ÿ#Šºj®¢H:}ÝÝ9º»—ÒÓ³œžžCÈf—Dð¥Ð´È ö=\·A8Ìää““{)†(ú©T> ÌÞÁÝ*AðgªÅ»¨–~‹¦êhšŽ®é蚦èZxLQ•Ä©”©cÀú±@ŠåñéÆ|ˆÈóùüûpCÛÊà†n¸ ør»ñ H8³nËñ¼`Ú1`íQ”È·çãù>®çàzžçFµHTÌäHe¯Â0ŽÝ§¶+Êvºº~L6«FðBw÷2ººúà3j@<‘)†°TÊQ( 299@¡0D±P._EìË<÷5*ÅcWªèš®º‰¡›èš' (ÍvŠøL–Ʀ³v‘Ûóùü ûÔørÀøò—¿|¯„³êÚzÑKÅ/½ø*Ží5͆‡Bü#‡kÃyž‹ë98®ë:ø¤º®%Ýõ TµóŒ®ÙЦ=Nw÷¯èêꥻ{Y´-!“YTs‡ÄðÕKK„¶]¤\ÎS(„–q¡0H©4A±øA?÷9 ³” À—¾ô¥ÛDäË.ЪZl|eÅb¹ÃX0Zà& ñ¹®ƒíZ¸Ž(t÷ýw’©ÙOè$"¥‰[ñ­H§ûèÊ.¡·g9Ùì’È×F'itÝDד¨QÚSà9¸®…çZ¸NÛ.bY*•ñZ—\,Q­N §>BWïWæì°n'¾·“‰±u(ÁN 3AÂHb&šjA¥¦§Ž÷<ß¡Pšèá8àš/– À¿øÅ/HXi!L»lцA°}ÛNö7W›ß!ÔÖ± DZp<…ž? ‘LWïWPçÓNrÃïF‘?“0“$aW¬ª*áµÞåŠx+…éRªbWËUûÛÚí$oØ2‘ßÿþ÷ÿQD.‰™mo@__/'|ÙlºÖe–Ê ðÕ‘ÄCÄGQç>S­Q¬êï~žý¦‘ a¦H˜©ÚXJÓôȽ¡€Ò8å³qJg§ê÷JX'[UU4MÇÐÍ)çñì~võwût-éÌ'èÞÞ+‰îWSFKqt&øÊ‘Ÿï Þ@îºë®‡%¬Â?ÒiÜa˜Ç¿†eËG?|óTÃØ½ iKçÕ×}ñü:JãŸAW'1°Û2HóéÑJ,É|­ÀµhlÝÂÏ¢Šª iZd­&0TtÎ$š:Iqü3Œ®Ãs_Ÿ×5ùÞö¦{CË¥j—˜,ŽuÊdn ¯]°?̳‘7¬ n”ë®»îù_"rLÆ[µZeçö=&KH 8®‹ãØØŽa\DßÂÿ1ësúÞ.J“w`[¡kºf¢k†ž¨íkÑX¯náÆcQ˜{X-¶BëéaµlìÀ‹|—nÔ{¾ƒçû$R“é¾]Ÿ}¢DnøBD6‘0˜fÓ0PÔ°rÙ*tš½¶/Ü_/"ÿ~Ävç*@€k¯½V¾)"7J›|B f äs£ìÞ9€e[¸Ž‹í„.˜Þ?"•zÿ´çñ½=”Š÷`UŽ®‚¦躉¡蚉¦…3Ó´8¸O7—ro¤¼i¸âŠ+RÀ×DäK•†‹!l„1ޯŶ*¥*•ŠUË;T•¸8Q«fë ßTüf« ¥eo&§jÅ ÒtñÊCŽkOYBØ:ÀçˆÈ߷̶PÐÁ75€±\~ùåG‰ÈߊÈeUjal|l¼–ðxX.¤ZªbYuàšakßÕÎd€LŠk>Þ Âæn¸î3Œ»ØÐ7èMY{£Âøz£Í—° è7‡‡‡7whÔ›FÞÆrÙe—­‘OHSn…¯“+GÁ²l,ËÆ±\\7ƒÏ¥û» ŸÍÜ ‹øøâ…þA¿ãbÏÉHÃý©ˆ|{6•Iß,ò–0–}ìc‡‰È OOv²ú:ÂùÛŶ]|ÏÇ÷ü–e¸öÕK; åãÅs˜VTš®Í^·Dä>¹mppp×>6ö —·$€±|øÃ^&"×WJ˲bóø! üÏ 3®}/@ü?ˆÞ'¹LféˆVêûõl”€úÒ]sûôy='áš~w tÞ|å- `,úЇt¹HD®”Ð}“˜+|³~-ˆ !t&K¤áD"ÈÐyÃÍ&t§üDD~Ûiù«·’üEØ(_|q¯ˆ\F¨Ï8ŒÏ>)áj“ÿ´{÷î‰7öŽXù‹°Q.ºè¢#EäR SÀÎ(Âozøªt¿‘_´.sÿ—$Ñ6Ê…^˜‘ÓóEä|9MZ²³á ÁçŠÈ3ÖØùƒˆ<½cÇû ܦ7\þÍØ*çw^FDΑ·‹ÈQÀÑ"r´ˆô`øÆEdS´mþ$"oÛ¶­|nÅA•³v’3Ï&Teò,Ki=•½~:v dc[ ¿P•E"Šþnx¡ÌFÔŽ`S ×±á‹ib}dü¹ sÌ|VQÁ3«]Ó¾Q0öæãùÇ»ûdA7Vâ7ÁÍ6mJ‰Ë‘ùÅþ®uuvž6r¹áRán7ÚÀÝQá¦þÿ¸®¾Ô+î±R™pIEND®B`‚swami/src/swamigui/images/effect_graph.png0000644000175000017500000000131210454447011021057 0ustar alessioalessio‰PNG  IHDRàw=øsBIT|dˆtEXtSoftwarewww.inkscape.org›î<\IDATH‰½•MHTQ†Ÿsïu&4gJ%ÒéG(R"„(Ü4E…- ÊZäFpI­*B7Õ" Ên‚ ©%¢ Zõ1` n 4…tF¤FÇß9sZLsõÎ8¦âôÂ…{¾ûÞï=ß}Ï÷](R@¿óÞ Ho'zÙ i­1yý0Úzï8F|@\N?ºèšÂÐ$Âõ‹c–é°}ÕPœ»ôw¡øØô†R×ïâXÐÆÉ[n|C›Vž½£-*ó ÓbèJMRþp0‹ãžÛüœÌ^›J ó¾¼ý.yͲ›žPZwÈI¡cœggɰM¯¸« ¡ù Ì„mHeð#Á¹ÎkLÍÙÙ»eǧZ0´Èu„ˆkïH15]—‘£;z¹WûuED¿€´‡Äú^!G7škéí¤Ç Wƒûh®ñR}d€ÁÀMŸ—XÆrYbÆhÆ,𽤽 ß|)ÆiÀö/êtS_åc8ÝÍSŸ; ;Ú’{ IÑðî/?mà~åCÜÛ¾%åjE?E?…ޱeG” öÁA>ï"M—xN·P–÷gúû¤yE™ &TnBŠýZé/ˆ–šäÌç”W𶺞⬑%·‘)F—èrpèÆ1fæõeªˆbgî= (ÌIì S`sk·ŒôvÚ}µÈžu­MŸÇå ö½†=•(%ˆ(ÁÀŪè) Î.:ŽS6ôUÙ9™Fÿxr$=?Ïò,åã:å–q½îèh³v2¬ó/3¾“SÿäA ñØó~y¯èIEND®B`‚swami/src/swamigui/images/switch_neg_bi.png0000644000175000017500000000054310420662631021253 0ustar alessioalessio‰PNG  IHDRù‡yÕbKGDÿÿÿÿÿÿ X÷ÜIDATxÚí”;Žƒ0E¯GT‘%$>K`%Tö²¶B¥„ÊK¢@IMq§ò |&ð˜ÉH9¡¹>²ý®€Ä‹³ó$ùŠºJ)¥ð!l­µÖÊ ‹‰Þ n$ÌÔu]“dš¦)IÆqϯçsIVUUq5ÞOüê÷ûa(˲”ËU×'º>ðr Ã0´ÖZk躮[!¸Õ0mÅÿݪf–îw÷F× žNmÛ¶ãÿáPEñ|ŽsÎ97¾Q\‹ŽcŒ1Ï×ÉXO¾¶~ÆÔ~Þï=õÒ¼E¾ï{H’$ùnͲ,€¦iš_=ó<Ï Š¢H.Wl˜¦jÍ×ÌbÁ¹zZÊÒZ›Âû‰×“4þD¿DÿZhŽOµ­ ¢${”IEND®B`‚swami/src/swamigui/images/modulator_editor.png0000644000175000017500000000311310454447011022017 0ustar alessioalessio‰PNG  IHDRàw=øsBIT|dˆtEXtSoftwarewww.inkscape.org›î<ÝIDATH‰–{l“çÆïgv‚â8÷Ĺ’„ Œ.¬]/.ëV6µ¥UJ'´uÝ&UkWµŒ"¶JÓÚ¡iÒ6:ÖŠ.L…ÐØ*“¡MÃ`¡hHÂl×¹8'8˜ÄØß÷½û£éMÛDvþ{¥£çy霟ŽRÒfŸys:-”ë äºã„™W•Z)Œæ`¡¿.ë…¯ºã´q›eˆ.žqµìÙuGiGÝÒ/¼ùàC5ãp(žè¹³sÃÙ‡ß)¶¦Ý|èÅgRoWü_&i’–$‹ðßw97pו쒓µe {xd´Ò·ä\³§xª ˜ àœÌ‰r!BJ‰Gek°Úû­óO+©»–Ž¡ )MR¨‘„xÅŸ}5oÜÙm‰ØžsÇñ-ÈÀ£’<>Zïuwï½’±zŸÓ±ÄK­ò/ßÓô‘u:q?ðwœØ‚Ì/JðÒD] Ç>µ„mG€ß¹ãD=*f`32×~ ÈçÞ:pÌgð?%pÛ€FÀ2ÏS€`"ì˜9tâ+WÊâš&VŸ.òÒàTí¥BMÓPfÑ;õåSV]ÝêŽPæÄë€ß_ŒªºÆ«EŽmÇkÒŸöÔª÷\,›]m^Ö&‡=Ö¨ª ¹&í÷\X–7˜6µÆToVÐùqî'YGk:ÖÍŸýδúåNà@ÒáÌ+®ßõJYã×ýöüš¡{‘ßúÎÐþdŸë­ìì‚Ì$ÓÕbЖåKÉí© Þ°ÍÚ¢Ê-¹¾«Ò×µ´?G7tá·“ËFò/,þ t!ø.`‹•ç®ØÔëhí8§lßwĬ¤ ‹}'N˜^?Ö©ø&†DCóY§íþóKG“" ¯­=YÖÐU=P(¤`Mo¹ÀP¤²¿öx¥.Œg<*&Ó£ÊÎç¥~÷Þ•Ë«è ˆ }A%Gßó+Év•ß¼´Ö°©e£I?7†Cy+s$Åæu—O-¾±è“´±¤o¿£÷ÃâþŒ›¦YKX½‘`hÆ¢òkBÌ3éÓ,Që,?ýa¥átš8Þ1"tâì|>G¦fÄ„°Îa‰ Õ5nJ€_ÝÛ^sѤ)zÐ9µäƒ=Ù_ûÛú+Ÿ­á±Ò3%ÁÄГ €9yÆ*C“&Ì]˜UC Å@˜t¬I15f „ŽÅ>c¾í%˜›"M 'Þ’†"¥n–;Ù£ƒšXß`—Bšùñ®q}J€fi"6”€ï·ßÛ]­› Sæø’©u—*‡7¼¿ ñ©ð}W2g¯+À¹Ä1{ˆXGÞõ)'ÏŒQœŸ,_ùÑ*ã±]rlÜÛÞ«È[‰2>ž5Æ’½€«»ÎïÎ ¥)º06lèmoø{ÁTRd@v8-¼ñêºÓ@«ø5°òÌ®Íý]%mu¥yòÙ­Õ†¸aeÛÆ,}ÄAŸÐÐeøg[. )öG’¢Ounè+Xu±Ä+…älÅÇ…h ÂØòáÝ=&©ìvÇÑÍî8㕟Xò^¸_2êw´”‹„¡MÆ@H¶?ìÒcAçì•—¹¬—ìjN?ÐWw+A³ØÇl‘ ˽{7·¯2©¬¨òNf·¸ãôý;*2oëB®1å…öedUã7²¦õÁÔNh†ÂŽ™Ã AŇ]m Ç~--j ÛŽ¯ÍƒÝ& }®Ý8ùvÿvùÀãcµ~w÷Þ-]íMW#ÖxéÁzßò=MY" äÿŵGå‰ñŠÀ“]O{J†Öôg ø”¡s#g™¶Å–µ®óVïûÒ%uÖú¬;ŽA­Y×Oì{ûÅ&„УøtÍpÃï7öTySÏoùkÑõü1;@AgÕÈÆç¿³ÝçÛ50芦ÄnÆ(é\9¸î_ís²­)ƒí [/ßý~Ó¹ozŠ¢ú¬ø<×´Ùg[§ÓBiÎ@îÛÀwœÉùM•ÕRÍÁ"_uÖµ¢-ÿ[ß­¿…Q”IEND®B`‚swami/src/swamigui/images/preset.png0000644000175000017500000000032510420662631017747 0ustar alessioalessio‰PNG  IHDROc#"bKGDÿÿÿÿÿÿ X÷ÜŠIDATxÚc``ÀcÚÛÏ›÷ÿ?½À‚.0yòÖ­""´·87×ÛûÍ,€??êYxäÈ—/›6aŠ3kÀÿÿÿÿc‹ bÅwïîî>{–Ð Œ:€ (ûA,„022222R.N²`ùWö¡[¸º––ÓѰ"rÐ :€Fp§{^ÂIEND®B`‚swami/src/swamigui/images/concave_neg_uni.png0000644000175000017500000000100310420662631021561 0ustar alessioalessio‰PNG  IHDRù‡yÕbKGDÿÿÿÿÿÿ X÷ܸIDATxÚÍ–!oêP†Ÿ3:H®Ge  ?€ÕúY~šiÔ~Ä‚«E’%3‚b—!¼Wá–Ý] isr’>çí—ï;$޽HRu1ÆxˆÛèû¾ïû÷Öý‹è±`B„u–——J¥R‘¤n·ÛÕ͉üÌwÑÓ#|~Ú¶mƒã8ŽãL§Óéí"¼¸F·Ûí`>ŸÏo'xL¬hf³Ù,ÀjµZl6›MEßÞ\×uWÚív;¢Qm¦R©@§Óé$PtO½^¯,—Ë%@³ÙlÞÜ÷|{ð<ÏóŸÏÃnT´Z­ü²½]R£—2™L&’T*•J’dY–uXÓÑÓ¶m[ŠFó¹ïD~'#ôZ—×Ý%ÿü<Fðô4›ÍfðúZ.—ËðþžËårûýAA°¡WHô߈Kô5ú‰ß÷ëóÝ÷óÙ¾ a¡Á0Ì9¡í}ÒŸÒ¯ÑÉMˆhÁ `/ C#Aq`ž¾·> ÀÐHö>̃]ü/ÿÿÿ·# <Ã0R@ü €È‚ð‚ñ¾¨­Âû'fû^x <ÇÁððÌ;/Hx€Yc˜È¯‰’lR ó@V:4_¸„ÚÒb¬IË@›:c.Üíó¢©ý"Mè¼ÒéVì4[Så‰qL @³7'nŽ–·lm˜ ´œkê"BA¨cY•HýÇë†æºúèë:ÄG ø~×¢àØ¹Æ®­ S›£å-DH "€b»K¹_Ý4b­?hrš§“š‰°…UD`C €çÀ$!c6»Å<Ô\ÐäT7Xí.å~"ˆY•ßœnÞ0ãTÉ7–ïjWÊLžOŽiÞÖh·oºå]Þyå#"gh¥Ñnßöikû¥Ìäy¾l·fÆ©’=}d€JvÚÿ䈱$#3ñGÝY­ã­m‡ w SxΜ͜‘.\#Œ€‚e}‚~âñÔÖ¶CEÙ-¦ÌDnÄX²ò®=¶ˆ½rýÕ\"Ž-Ê>:—K € .ïýŽux<¢ÝEÏùááŽ`0(æï%ËqA žcÅav÷ö˜Å “˜mfkòRAà™Øèñacéʱ;¹ë²³Ñ‹Ï\Æø´c–I|v^›“ƒ«ã–ÇÖ KÓãTºßg&­IKe³ löY˜ÈéeWÄõÍÖÔX»3*,?ã»AW.éî¯I¨®|ëË‚·LknÜ€'zÔX»w7JßÛ…¶ë;ûúàûÝš¬ ¹¼ÕUu—»ûk<^¹dõʆœn…ÈlM‰}4¦×Èg§œ5ü2¼1ïêÍêøâÜ#†Ÿ®½1åpD‹ã—ô{àÍÄ1‘È3`”ˆ|~W¦LnÚÉã¹i'»ü<8Z©–K'¦‹s¾2téj– ÄsYÉç ðûÃê÷¹6~¡÷µSD(%Â"¼Lîa¿…¿N°DØL„mDÈèîéÄþf­Éã{dçŸY¿‘wÖ?î3IEND®B`‚swami/src/swamigui/images/DLS.png0000644000175000017500000000133410454447011017070 0ustar alessioalessio‰PNG  IHDRóÿasBIT|dˆtEXtSoftwarewww.inkscape.org›î<nIDAT8u“]H“QÇóƒ™æ^e›fúj4ghyZ ""[môA ’„H(]Qäl+"ˆÀ²"ŠŠ>íC”rË‹¼(±›„"Lf¢mZ¬©½Kd~l§ uh¸ÿÍÃyÎùÿÎÃ󜣲;•nÀ ŒVà`Àb³h>8\Zà <ÎÅVÔœ¾ßl•øä|‚erÁN#°§Ù*‘$%Èù;¾–çªû®@Ùԯї·+ô½/®kÖ§¦•¤o*ˆ‹aIÿoï6á÷¸«X[U}í7c'LJQ|¾õ¾ÈŽ´™D8ÌçwmQülõ¢“óÈ/­• €¸åÝÃÛyu¥žñ¡þh€m~Ï {O´’[lõ{Ü9ÀïH±ñj +2áŠH N+ÌÏÞèdã~À³ò„¤Ë$8£D §lÈ¡£¥Á¾®z`·Í¢™ZÐè62;ó7`H—ed&0É“ó5 ÷÷Ô9\ÆU!ÂÑÌ·,Ç.„%-áÐïÛ®XWŸubòšn›EÓ’ž}òèå.´™¦~ŽVþø<$$Jk®ÀY`³>{K“éˆÀÄ8€ãÂ\/=ÏÑʹÿ{뮀0÷w?ŠÝ¾«Ú;?$Y›àÅîT ´™ˆòêSb9§Ë2 C‘IŠLÂîTD¼zÈ/­’>Kä›…Ý©tD*˜ûŽ*&†ÂŠ‘«ý^7~¯;²‡C |èX|0éA²6Smz9¯sÍ&• -Hi2i9ù”ì;:Uv§âdñëþž×€;K¹•ºL‡–â%›EóðCßÏ´j6IEND®B`‚swami/src/swamigui/images/SoundFont.png0000644000175000017500000000127010454447011020364 0ustar alessioalessio‰PNG  IHDRóÿasBIT|dˆtEXtSoftwarewww.inkscape.org›î<JIDAT8}Ó_hÕeðÏï×lCY笳©DlÉ´9”‚Š†ÑØJ­?$Šd7ý#Ø Ásqò¦áU%^LaXiÑE3éÕ0Á5'®&Š&;žUÊÙòÏëÅsn­¾ï Ïó>ïó¼oBɼw1½Há%â0 hÂ%tÙ^BºÙà›w-ªjAOkÒNHkƒùs‚U¹¶…ôŠëíéœÏ3ôŸ3#v}ÇÕ›üx‰®³°¡Kœ¦>E}%Ñ$“² y(eÓR>9ÉÉ?¡¡(pv˜}ëiªv.W9AغŒ«‡0„µ´Ò¼pÌßc¥ú/CCŒ„‘Q ·á˜ºÔÛSŒâ:F4/ü«­ ? 1þ° Ék_pdàe¬› öœfã¡:m_?\ÝŽ”ë£T'àbŒ êR x±—£¿·NœºÆÁ3|yJ"™YhÒ7Èòùð[Œ½>x6¨šÍ­»¼ÿÓÌ-ðŠï/Îu6Çæ§à`d?õD²Ã·›‹©æ'Õ¶†|;Ç_…Юógj+XS=‚ÏãHæ=Ô¨¯Üc÷:.ÿs_ ¬„dY§òÒyè6[æÈo­€ýAv,ÆNÝ¿nÅ…[Õö { í>ê'QƶXÉl*¯Åá¤_®°¤jÚÅÇÃkÔ}ªx@[4êjyº(p'phü ¿°ø¿Â{‘Âm.ä‹]-Çè×ÕBM‚¥U¼³2ü_ ÓÝ…ô#èÄsŠßu¶áÜĆ {,’9:¾7ßܳõÄ£k™0?IEND®B`‚swami/src/swamigui/images/volenv_decay.png0000644000175000017500000000106010543044062021116 0ustar alessioalessio‰PNG  IHDRàw=øsBIT|dˆtEXtSoftwarewww.inkscape.org›î<ÂIDATH‰µ–=K1Çÿé%A± 8ÔWDÁ¡‹ âê7¨‹ ~QÐ¥SgADpqpsÐIG´"¾à"èà[U¬U’\â W®mî¤ê=8ž·ßýïÉåŽc (¥ ¥„”Bˆâuù Šù‰1ÆB`³Øù"u¬1ÏŒr¡;'­±t: ª” ,&ÔAÛür(àr&“R"&¥ mð£”F `Œ!&„ˆ@¥”Xß1Ö„éæmt÷%qšÝýà½PüÚW’#èèIbwk¹‡ëªœó/ÀsΞ 5PÈõ íŸÃÙñ6Žö7 äGu l@»@áÍó8hMŒ¢)>ˆìÁn®ö~ð^;­ýÏÑÛ?…xË1NWÿSA©ÕÖõb`h5蚃í,`Œ !Âä}ŽÊ ´‰ŽÙÒÂ"`ó(Xv˜ß´žr¾Þ>È3pÝo!æºÀ‹W_¦ÀºMý9ÅGd)öç”Ü`5 ŠCœA b߀Ç;{G/!ÿ:Ü€vS¸¿¶Æ;Œþ°‹þ¸ŽÀ9^ å†~s½œ0Éd2Æûå ”‚1V²8ç¾jüŸUá·%z.IEND®B`‚swami/src/swamigui/images/sample_rom.png0000644000175000017500000000031610420662631020603 0ustar alessioalessio‰PNG  IHDROc#"bKGDÿÿÿÿÿÿ X÷܃IDATxÚc``ÀˆÊýÿŸÞ`AøÿÿïßµkéàsFfæà`&b589¹¸L™B¹8: Ú4 Tîÿÿ°( Ö¤‚}ûöìÉÉAD ±(¸<4àQ0à ´J 8,bÒŽŽŽŽŽŽ”‹Ãh˜}8³!Í-†fï FW¼†‹Â„šIEND®B`‚swami/src/swamigui/images/tree.png0000644000175000017500000000126610420662631017411 0ustar alessioalessio‰PNG  IHDRÄ´l;gAMA¯È7ŠétEXtSoftwareAdobe ImageReadyqÉe<HIDATxÚbüÿÿ?-@±XM{6Ÿ›ƒ9™‰áÏï¿ ~ýâ¿ ¿¡4ˆÿ› R÷÷÷?†ôÏÏ ÿ~}Z@, CÝÄ~þb`øùƒáÇO þÅß¾éïß¡™ Äÿ˜~= 4—á?Ä¥ŒŒŸ€»ˆ‰“…á'а_ 4ü7ÿ†â? €èFbÿCÂ(¡ÉÌÊÀÈÀÆ@,|¬ÿ¬%@ýò ÿFfÿFпÿëÅÈ‚¿@/,^ÇÄ@,üì r gϞ͚šJ0r@†€ û÷¶ÿþƒ1ˆÿëç†}G˜ˆ‰œTËP¤ €Xþgð©r¨É)ýVC!|€búÿ¼t s-²¡ ö_ 8ˆ lA gd€-ÌÁñq0  6yØ\ŒÄBLäÃÂ9Ò0ÃAÁTM#>CA–‰ €ðF.¸ E@á dM`ÌÐ_ ²ˆÑ´þÊ%!f` ,ýÿü…Ð@‹àl ýYJÿûûgjºõä;@1ҪΠ&€©;ÊQL! <IEND®B`‚swami/src/swamigui/images/modenv_delay.png0000644000175000017500000000075310543044062021116 0ustar alessioalessio‰PNG  IHDRàw=øsBIT|dˆtEXtSoftwarewww.inkscape.org›î<}IDATH‰½–±JA†ÿ¹ì®Ñ@0ÆFH§bº€…Xiga¥XXHؤ XŠ,$6)lÄ&•o`ã[X‹ø j›Í­EN£ÑÝÜœ Ëìì|ÿ°³{GÆZk03˜¾ï·‡mÍæ'cŒÉÜ]‚D.3º‡`¡îŒ¶V«¡µ‰ æŽ;Îàûf-Vr`fxÌ{cTB¤ RÂó}?U€øKk+Ü\5­ë×ÉžG8;Ü‚7kŒR*P|@uc •Ù<à¿Xc¤Ì‡/ùxV⤱ °=yPLØßYD©8Õ”ì§'³8¨–GªÂ.ŠÛ¦G{eäeµT0_š@}½I=àœÖf ƒW·zLmÁÆ$ak™"ªïSd.¬ #t9ç–Ý)ú½k¬wèË~9„R~J©¾8þw­‹Õ¶ÝÚIEND®B`‚swami/src/swamigui/images/convex_neg_bi.png0000644000175000017500000000102410420662631021247 0ustar alessioalessio‰PNG  IHDRù‡yÕbKGDÿÿÿÿÿÿ X÷ÜÉIDATxÚÍ–?Š"AÆ¥m'vêŸÄL ÚC˜‰H·'˜›‚¹W˜l`ÐÄM¼€‡Ð ˜¨4|,µíîlÏîh¹ëu5ÔW¿zõÞ«2 ñàòì‡$="®1ÆׯqÇqìøÐÙl6¨×ëu€jµZ‡C€óù|μ°~£ét:•¤Z­V“$Ïó …X^^Y)áða‡CPUM«T,• †aX–·[QxýÚfSðxš›½^ؼ9—Ëå$I~õjttdDˆ7b±hÔJ ëðøq¡P.ƒÛíñ¸ÝÐ×wòäùó00péÒÐx½6øýɨjµ ÕjµZ.ÃÍ›ôô@>ÿéS6+„\,Öj†²l·;p÷îñã‡ß´¶B:=?_*Áôô?ÿ¼33SSðô©ªjØí‡Ý—/ww‡B–ÀZ ŠÅjµ© lõâ559N'x½~{;¼}{ûv<‘Èàà©SÐ×7>>1]]¦iš I.—Ëœ9sâlÚ¤iå²ÕeB€® ¡ë`ÓõBaa Ã4­îhiikMÓ4U…ÙÙgϲYèïïïÅÀ4WWuÆÆ†‡>„; £T‚ïßs¹l~þÌç¿|!,|£È·n  133;[©@4ªëµìÞ=6öæ x½Š¢( ëû÷<’ôäI: µšiܹÓÛ»otu…B¡ œ>}ö¬$Éu‚m6Ó„ÁÁdòþ}ؾ=N&A–‹Å¥%H$΋Çad¤³3†G.^¼p4mqñ÷oˆÇS©T Âáõëív§á@×eY’„(;:ÚÛ!‘¸råêU˜šÊår9°Ûív—«>¡ Ë–òHdÛ¶-[àèÑk×®_‡µk¿~ž›muUéïÄ5ÿ³2ÆÇGG3!LsÍšuë@–­?§Ó4ËeˆDöî=vìÿ+¢ÿ „´€»äÖŒIEND®B`‚swami/src/swamigui/images/CMakeLists.txt0000644000175000017500000000374411464144605020514 0ustar alessioalessio# # Swami # Copyright (C) 1999-2010 Joshua "Element" Green # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; version 2 # of the License only. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA or point your web browser to http://www.gnu.org. # install ( FILES DLS.png GIG.png SoundFont.png concave_neg_bi.png concave_neg_uni.png concave_pos_bi.png concave_pos_uni.png effect_control.png effect_default.png effect_graph.png effect_set.png effect_view.png convex_neg_bi.png convex_neg_uni.png convex_pos_bi.png convex_pos_uni.png global_zone.png inst.png knob.svg linear_neg_bi.png linear_neg_uni.png linear_pos_bi.png linear_pos_uni.png loop_none.png loop_standard.png loop_release.png modenv.png modenv_attack.png modenv_decay.png modenv_delay.png modenv_hold.png modenv_release.png modenv_sustain.png modulator_editor.png modulator_junct.png mute.png piano.png preset.png python.png sample.png sample_rom.png sample_viewer.png splash.png splits.png swami_logo.png switch_neg_bi.png switch_neg_uni.png switch_pos_bi.png switch_pos_uni.png tree.png tuning.png velocity.png volenv.png volenv_attack.png volenv_decay.png volenv_delay.png volenv_hold.png volenv_release.png volenv_sustain.png DESTINATION ${IMAGES_DIR} ) swami/src/swamigui/images/splash.png0000644000175000017500000061634411451524061017754 0ustar alessioalessio‰PNG  IHDRwôÆämˆsBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î< IDATxœì½[Ì,×uøíKUÿçÞE[wÑeSv$KâÀ‘-; `0qòä< 0€'$~ `ÌC€yñÓ<ök0p^ŒÌÅ—Ä™Œc;‘[6ób’&EREŠÔáåð\þkwÕÞkÖZ{类ªî¿ÿîÿü‡:þݵj_ª»ú[ßþöÚk›_ÿõ_'"BŒ€@„‰ÃÀ˜)ûûï˜þ<î¤ã}s#;;Þ?ßuy¼/oê\Ž‹ó<¬îˆ1€1&ý³ÖÂ_»v mB@Œ12À3ˆ›¢°¾.~éËsãÓYý%Ýþ~¾?ú˜®Üe7V·~ôótÀq{úyzp»ÛÏÑOÙ¤1ÝÝòýÊÖZtïà½CUUðûûû˜Ïhšm›žÁÜ$Pïþý³ßÀî<èùµ—ëÜvåËõí¶ÿÃmžæ0fºÛlk¢•‘ö¶TûR»”óiFÚ:c­£õíæΑoÞ–þF^i?òyç,ªŠA}6«±·7ƒ?>>Æññ NNhšm» îúO<¿J°àÇïtó|S€Þ°o¯/gw_çiÙ§1÷ÜsÞ;ܸqK¤ÀóîË®@}ÛõnZßnx³zwÑ—ÝÝß&uÒÖ;2T ¼Öþò{fë—.ÍpéÒ%Eø¶ ˜Ï89a€g‰&Â+ n;àÞÝw`à7¾³ðyí&åÎÀÛéç¦ímR΋{î¹Özœ ƸÓö6-·©d² ©eF>ÜÝ•.{±ú¹éè`|:K{ýkZ³Yw"B]{Ìf5bŒ°Öbo¯†€#š&`±h°X´/``·ö®ï»@o,ëôù&OçݦÊlRßÙË —ÝTjÙü3ÙE?N_vªÜª:¿÷½7 ì»èǦõNÔvXë¦ýØE_ÖëÏT¹í2ùÍû²ž*·pŸEÈ2L>Çò õúCPPWÐo["‚÷mÞ{眳I”çFØäÌ­µ¿yrÕ¦ÙZw°±èš©áÌx™å‰†þ4^n¼Î©/r¨œv}¬/«ÀvªÎé2„!ç9}oëÔ t¿·éúr{Ëý™¾·ü½c“mª¾©¾¬*׿¿ÓÝÛr½Ë¶nÙ^ëƒ?Öuîo¸\®³Û—uQåÔ%ËD2?_c÷7u •)Ûj¨[g¿,cQ|«À{<úo¸/\n¼­©ú¦úN_2[/ßëïs¬"›¢dÏ=¼÷Î9Xë¸Çð\°°VÝbH¢QyfpôÇ=u£ý2Ý›¶OôéA¬?å$Çð(eªÎqv™û8\çØÑ°Õý\¯¾å:—Á4÷õt}ìöe  O×ϱrÙ¶ê»^¦S¶±zÇ€}Õè`¹¾)³Úié0°wvšh-÷eäꉾp?Æû9^çjb3¶Ó÷>õjCåV9˜u“dÆI}Ím.“‰²NUUÜ%jÆ9þga­ƒ1Q*-™{ ò¥4ôešéÑxo€×©sjT1ÚR0Og;V•rLë ýÆÊM÷t}ãå†lëõq¼S¶n[cÎb¨­uúy6‡pg°I?O×Çn¹åcªÎU zG±ô‡)–< ¦›Ô9MH§ë4Æuä“UýÔç>c*¿n3B_ñy‰¹óIkõ‚®'ÈÎì}™¹gÍÝŒ||söMd˜ ÞcuÛÆ¾øu4í1vͶÁnŒÞC·½±ú†GëÉ0ËlvŒAõ ø–ûÒµ­ïDÖgòëÉ0«úÏm®’a¶#9œ¥¾±~N昃YîÏ& zjÄqúú6¹‡üýM1ámJ4Üÿi–?fsÎᓟüÞ|ó*ŽçèjçËíåúLªgÈžeeôÝÅKÖ²#ÌÝu@<3u}]NªvßsGJÍ}¸ÃÃ72õ€+³èqð­qÂY¬ÓaÛT[S÷°Z†9=°õsécfÊYœ–YŸØ»m޵µ h§4íqfºY{ÝÏr¨În?r¹Íäiv=ÞÞT½S#€)€žbòã÷7Ôÿ tcìZAxX¢—ZV;Éq'Â6ï=¾øÅÏ¢m^ýMÄF¾ƒn[]¹%ã|¯etP‚{’e\š4ÍÀÑqoÛÑ╵g`×ùFǽá8O÷8Ëœ’Z†v=0=Ðr§œÁ¸mô×Ηjs•DÓmë´@;ìDÖ—a†œÈr_ÆÚœbɧc×Ë}*×íc·­aÛz#‡åc Çú?˜Ù6|ŒßßxÿÇùzíM9„ª²)`ð¼|ypttŒ¶ =ùƒFÁtÚ†ÑþO9ƒ~MððÇhÛ1ÆÉöÆIOùœ ýÞ”½¥|.̽;™Ú {d°6¦œ`å€÷DúPu:É0«€}Ì6ýœÞY¬¦ã¬mZÙÔQ¬²M«Àt5ë£~_†û:Ö—Mù*çS¼[jsŠan"›Œ9„õ?÷cº­)¦_Wi[íð6cúÃõMð*9e¬/cß÷Ïâþûïžð·ðgöM4M k î»ï^|ñ‹ŸÅlVáé§ŸÇÕ«ï „X”þ\¦ú1TfÚQäû+ëZ,aÕoz¨œ~§ýÏ4++ŒçæÞ—b2Íï³x€—º~îsŸÁo\Å{ïÝJŸ¿¤á›™bÏ«sض‰³8/f•£˜joU?åÕH}©†Û:`ºÚ!-/õ}ýöÎÒÏ)f]Ô~J0wÙ¶‰Ôr:‡sÛ2ÌéAxª/ëõó´}Éý7!⡇D¡5ðÞãxúÐàµ×~€wÞ¹Ž3˜nS†Ùl0åDVýÞÇúI`)¦dóz­IÑ2Î9xeì9žÝÈ+T¹sÙ+hgø]üÚ¹õÙ³ÚVMšŽ;„uœÅ(n úc÷pzG±ZN³ ?}²Ö¢ª*„Šaëz€9e[%ù,Cý\vL˶õúr: ³aÂ6æ,Îâ(V÷óô Ømo¨Îå~Lµ·Ž£˜·iG2veDÀÁÁþý¿ÿ,MêçûøÆ7þ®\¹‚7ß|KžïÓƒðxìøêEI댚†Û·e j|È–¿SÅiçì²æ^‚wörÑ¿ðì³/¡ûÀ˜¥NoʬÏn[>Ï}œÓq™ ëÝß.d˜±rc2…1W®ÜƒOúØß?Â믿““ùR›§eÐÛ“S¦îaõýð4^îg¯–gq:G±Ê6}gS`=~›Ê0§¿‡q0U‰£¼v±hðÆoÃZƒ¶m'åi`?]™iПº‡žb‰@”¿±ß’A~ÖTmaâí3kïGÀô†-³øcêÀ²æÎ=-ëVûêPÆõËhåÕ`[cì²[fÓÑÁz¶)yÃZ‹‡~_þòÏàêÕwpíÚu,-8î¶SûÀ½-ßÇØùñrëÙ€Ó8‹MÙúÐ=ô®:5o 웲õ)Ö½ LÇêÄD_ÆÊae?7±VÓ€BX:Ý+7b݈±¯ªs3¶ÎG_Š/Ëuÿ–Øœ˜;‹ðËé}ù‹ÈL~9ÏLçžÀ” Ãõ÷zátå†@Ñ#Ù/‡ûºhÏê(Æ€o̶˜vÛ‹‘‡®O>ùÞ{ïŽO@Ô×ÚUl=—ëösÛú÷· 0j+ÛNn«œÈÙ}̶= ÝÔQ¬²OÛ6Ó³-°ü™ž.¦oïǦ¶QÓèQƺ sÊðØgê Þ}0/¯cg0 ÞçaEk öööpï½÷àààGGÇè''ì~¨CÌ{g°Žm¹S2Ì:`º¿¿gžymÐ4-ºì`¸Þ¾m{rʦ6¾¿]€é”mg°©íô€¸^Ùñã"É0›é&²ÉöÙúæ2Ì*Г Ùž±/W“±ØZËàÞÏö˜Wy-xª¦SFÁE¹nGÆljߦö>¦Þ{üØ}_þòãxê©çðüó/áädÑëç0ÐN³Ëa6еŸÝvZÀ duœž7K}]L§îýìý\eÛŒ‘ŸÖ!¬²íbäp¾`š^mÍÉlnÛ>[?of3`? ¨çëòçZʬYs·ðÝ7r§GªÄj–SÆ:¸Û°]Y‚ŽTf³¬uk–;;lËömÛγ­Óõe·¶íÕ·i{Û³u“ùÅ œ½­³õó<}óh˜‹ ì«þÞ}¯zLæ”Þ=-™L•ÛŽm]ÀlÛßýîë¸ví:ŽŽŽqr2_£ìíöí€éúeÏØ·êg)»m`ߨŸ¾lUy|ðƒ?‚½½o¾ùÑýìwï`ú¶]€éöýöÈ0g;–ñ×®.4ö8g{å. °ëÆÛ´]`Î ¹Ú¶þ1L÷ýàÙ¢á ë`¥çÉÖ³mØ>eËûwŽ•Û=p¯o[¶ïLwêë÷e·¶íÕ·i{»±EœœÌñê«ßÇlVãààPžùMÛ:[?· ¦›íÅ“aÎ~”shÝcÜÇô¢é ÎóöMs½²·Ø·¦ë—=o`ߨŸ¥ì¶} ~–²|òøxŽgžù¼üòwpóæ>b gªo» ¾Ê~W†™>ÆA]%p¿ü1`§‰Ù²ÎÛìÛõ]ô墰õÛÛ—÷—í<Á´ì QÄáᎎŽAϽ/çÉÖ¹Øo'[/¸¯ò²›„*nÔ»}¼½À¾[Û²ý<}¶õû²[ÛöêÛ´½ó¶MkÖãõ­/ç ì?<2Œbìzõà>¦Ó98ÎØ7ÌõÊÞ^`ߘ®_ö¼}; ~–²] 2ÆÈ.ñM:wûÙúYÊN;®‹ÁÖWÙïÊ0ÓÇzl½<ŠésÓ[³Ô{o Ÿ³ÃÍèu00ÖÀXÀÈuüzùÀÁHuå XJ}0|~ÈÖù™-ÝMÕ¶ 8w£aî`ïÞ`PUf³Z6mº¿¡rü¼Ýwß½ø‡ÿð¿G]WöeÚ¶`GÃxoqåÊ%Ôõ šî¶_nû}Ù6°ß†¹GG–1(Ò RbÀ,²z€¸´*®·ò0Ýäð깡l‚iäÐù€ta†Ûõ¨³Jµ¨3vÛè”Áí°-Û·m³Öb6› œœÌ‹h¡ÝôcÊ~V0Íj<òÈGqï½÷àå—¿‹[·ö;÷S–ª( išg0Öõú¹MÀ´ÖàÁÀç>÷“xçkxé¥ïâäädE¹Mûq–²we˜ÓÚÖ?NÏØõèN¨&&Lô|.¸Q¢Þgù¡†XdZÏu1@+J§Óü‡J¬†rÙ5õê+ßPy¶kïœË+g#átΠÛöí€éúe‰€+W.ãóŸÿ)4Mƒçžû·Ø—õû1ÖÿuÁԃ˗/á‹_ü,}ô¸ukûû½>L;°¿ˆßû½?BÓ4[èçîÀ”³z~¿ð /¼ð2^{í ÌçsŒOŽnßÁlê«ìwe˜écÔ™z®øðéÊòbc@ ÜFÀ›Ïe€7IoI̾‡›Db”•Ü^hõ,º£ !UVÖ¥!ßy êÚ¾®?:H Ñù gª™r±¬²Sï®sÊVâ=÷\ÆãGGÇøîw_ÃááQí^$`·EãÅ_Á­[¸~ýæàš…©:c$Äx;}=[„wÞy_ýê7ðÎ;×d5õìw£aÎvŒç 0Æ ®kìíÕ8>>Á|~2ÚfW–Q€Öä3 Ü0–_§møl‘G¦ör“*}½€ØY¾y-?°Úø1#"™%(PÉô#†»)%Îf™­e0Gìô.½¢Žƒr0T8äóS¢ˆ[·ðçþßÐ4-ö÷GqmÚuû² ÛÉÉ/¼ð ¾ýí×ptt„rîd{m­Wv—`cÄõë7ñÄO#„Pìǹ¶ÎÖÏóöfÔõ¨*O|â#xôÑGðòËßÁ«¯¾ÞÛÄ$Ü;R‹LdƒŽ c…©[Þ,›“œDã ÀÔÝÐÓJKØ@K¯JöL —2K¥QE¤‰áœ€¥â£3k:tFêp¸>ôžúܦ)™¼öCEéäÒ¼AY –ëœ,ß­¦üæèèÏ>û"b$Iý»~}›Úv¦3ï““¹ì*•mÛv"S¶óÓ¶ hÛ£-÷e ¾Ê~>ÀÎiÇãÖA}•ý<€Œ±¸té>ðñýïïI@ÁðÑÓÜ ËtíÖÈ?Ëvk3è+›OéŠFdÕt¨ ç†eý+J øÜâ3[cÀo:—$æmÔYä,x‘¨Û‚=GHÛTMõ ޤîä˜rÅ©?YáˆÝ©…ÂߨóIb2QÏYúåò‰ÔÓ-7À1FÏGí·Øï,Ûy‚éEêËy²uîÇúÀn­Å¥K{¸|y7nÜ’½V×oï¢Ê0ý£i|ç;ßÃ[o½ýýƒ‚¨-Kª%s7Vs‹´®»10ik>6¤0FÇÌX`€@íÝepLlWD~…UŠê€•—ÔL @¨t®Ztù„ËbJ¬”Û‡z{ˆã)? ­äº>Èa÷…r¸Z’a´£”•}*üà `šò3,l±€xԔʔõ©¶}à^e¿½@»i}›¶wÞ¶Më;[_.º ³·7Ãç>÷{ìÓø/ÿåxýõ7:ûï]D`_Ôõˆ1âààà0Ë8z­ºZ»QPwÆYfç²Ë2YÆäØw-WH)ƃÆÈC½‡(uN@‘²|a³sLLßYH½Å5 à|Q€¤ò‹ àO«`£0]­Kµ£mG™¼¶É£ ®2Užú‚€v’GÔñ0V‘ÕΠødË7RÎJNвŒÀ ¢Ü"-|ô9…hK¹oi}ß_ŠF"ý€Ã£cüþü'Ü:8äQAá(²|O½Ec&f–G÷]Ú°}Û]f]ÛÙúrÑe˜¾½iZ¼ñÆU\½ú6Bˆˆ1\@`?P×¶¼1€÷³½Ñ5E³pÖÁ8k}ÚMÛXãºZ»1N€É"@‘c@ „#bˆ‘@A@†$íh¤äbÔeÆDžéŽ”—†ˆ‰ãÜ#Û£Í,Ÿ¥’â£$>Á->(;u tIù»Bb–{ôË5D\ª)j“¶ ×­­¦tj‚–Qý…΀²)ò'ù˜¤Ÿç¾X—Á¸/ ¥ìœ¹ i Ï?ÿ2B ñ-ùºØîB6ÒÑT'ˆÐÒÜIμ{\`ߨŸ¥ì¶} ¾Ê~û%Ÿ9¨¯²ß9ÀžÛI‹˜’4SUðµ‡÷ü×ù Î{þçœwÌØ­ƒuÆ8("ÄÚ€ ß’|è$ H"wDrê Bˆ ƒ8âIƒHF {1ð2rŠrNœALˆ©@—Ä4!Éõ*ïÌÒ³BU$‰@‡YóÜ@!È,*+9â€D'¢"±O”ó*ðCÊÎ)ËY x¡z?ô&ù^ï?w鳈{s †CMËgOçŠêuÄSTY!1wSüÅ<¨ÐÈI$&££t°Ó¨M!¶tZâo,Ê‡Ø v(5!ó2¦I>¬+á2önðR1S„—ªÓ-FF…V—*Øp¯Wö¼ý¢ŒÎØï.J:ŸÃÚ&`~²ÀÑá1æM‹WU¨ª ¾®à« ¾æ.+ïa½‡ó.Ù|Å oœµÎZX§!•¶#X™€u@á¨#¤ƒAºÍL>Ã!"4ò70›WÇÀçˆGm(FAØ?‰œ#DDQ€®!оE4 ºÎA“@°%b K¹^¸QJIE]r-¾~(T€$Ð´Ž ¤¾èuå(‚ÉÈ<IŸŒ´™ÁÛˆ#Q'“ÎgE zeL7'íKúeýIöIß/ /÷G\—Nð–ù†n?[?KÙmû.@}•ýöË0›·µÚ~çû`òáAYFiæ æ‹mœk±ð ¸s"Éxçà*•e<¬±°Þ2È{kP»þ3šÆÀXvk`‹ÖñD­5†ë·ÖsŒ½±š´Ì‚sv“3@¾?–fÀ’‹0ôвÚˆ¶¹'´!²Þ/Ž€ÿ±³c§Ð"¶|d~@F<ª(F¡eÙÂt.Ȱã eБeAÛuò˜Êâ¼Q”£Bfê8#Â¥²:H9z(Å•"R9‘\HB:ªÇÄ,¹Hˆé‰Ë;ËSMÛÏX±fAœWrì<J¶‚¼#/FÓv;_,”ñwçî+]†ž Ó¶ófë¥/»`ëUUˆ×\`É0ãýeÍ @Pˆêá ÑE´m„µA€Ù èZXÇ­ÎJ\2™¨‡–шÀÎÁ'Æ ˜IäQïĈ—IõPZ]œVµ)‹””ä¢ä „ý€¯š<`|…‡ä!\»vÖ20TŒBlélL§ê8øYϧäÀô¶²ÎB7$TMÇ=”“»zo¢ò›tFŠèÀ$ ŒÛÏØwê«ì«m!DüÅ_<É„'höÊM€ý® ³ºÕýM஌Ì* dH–ÿK”Љ@°<±h¤¼3±eð¶ºr5 MJ¡†½LŽF#U0ô´!Ž£gjšnÈÄ!Ú½å|×EUà°L Àˆ¤#‚‡q:g༅wÎY<ðàýøôÇ…w·Þ;À­ƒ}HTõ2Š(²aÚÊÁ¡p<@Ì’5¼3ž nÛÀrOË£H&ŽyÐ6ò/D„&"R(Ø>OGŠ ¶ˆ "+LZ’%I~âH!÷T‚>ƒžÊ7|^£}²CI~-I3Z®g"þë7þ [DXoS9õ‚¢§è!‘dOdàÒµ²œÍÏdÂâ<7é­I•€ºŠþä®>)§éÄ.R]é¹ëüvδÃö‹ìÛ±Åñæ›o¥×ØXd˜þ!² e²CÌJ]ädY'66€`L õ‰4D6ËRmZ‚¯ÿ/s¡€Ëed×e€æy×HTÆv°†W¡k“£Èyb€4:0:‹üÖñ}\wÇû XgðöÛ×д­€»…«¬up^ÀÞqd›$"žðÎÁy–wT byÉ¡ªˆêô½(X’Æó‡ˆH,{1ø·‰ñÇÀQCmƒÈDâ$x²8!væH¢"q„¡¥’ ›BÜcˆ°Æt€Äs †y²– :)ÕðådYŠCÔ›Tèýˆ8¢Ç.>Ø!ÁøR.’ç@"ŽºÎ€ûU 0²¦$¿%t÷ˆ¹=}&ÓŸ ì:¿°;ÐßœÏRöü¢a6õÍûrW†>ºdÌ]Ã4(DÆoceÑ0y!¥ IDATLŒ ¨VV¬š ,µúD¯¨øÁ)‹ùúhcï;ƒ4¡'£‰To«¯¥b“ dn§ ¯h/Nåèàû7``bd§b4ºG“¦êÐyoQ)Ëw6ÿuÎÛ”ÖG^¤!¶ xïÌÒg$_Œ÷X,-!‡z¦hŸ6 iCÒüu’X¥¡Vå –ÅÈs1  •‘€ ÄŸƒ0G ⊔ ʬ˅\üÒ¦×)҇،,bi}r¬q*óhAu:o#uk_´]JVõšÄôÙÉDCçÒ‚1dè¢I ¾èĶ} ¾Ê~7fú¸x2LÿðKÅÓâAd˜EEC°–„ñyõƒ"Œî£š: ñK¯¬œË×H]鞊!´:‚¬ƒð¢Ý*IÛKëø I2”>Hå©9B¢øÚW“ü ³R²ym±ì,RäPDÃ2ŽL§I_ïà+—&Œ­·°ÎÃ;_Y'õ÷=p/~éï|ÿék_hï*Eù,b9Ê«€e¸mÛ$µ! mDÿo´mDÓ´id˜¾þgB1ëòQX|ÿœ¡#ß êò*aÍïCp Ø™CIVÙ2 ›‚S$q0H Ki¢™¯IûbSÁeC*%eg•ŧчèü&øÒ³ü:=¦ú”9ŠT³_¬Õÿ1^$`ß…íâûûK†ÙüÈÌ]feQ/Ç6eòÈ:|4Ö€?øé€,µPªžº]MˆqìFŽœˆ¤àKiGá Óé<ä‡'Ž"±ý\: Ln‹l§yÂW'!M*ZD¾7 ÍTçB%”Ø?;BvE8X8cá*fýÎW¸Z]õ\ÇÁáQ^9\¹4`ùGd"˹*˱æ{Fsä0êÆÈ`!4 úMд-¨ h[>ß„¡ hC@Óêâ˜"|Bá œ†x²×ç±\TéƒÃ.×RMžBðwÓµi®<‡Fæ1Œ8‘4雜¿D#÷©ÂëŸûbÓµHå Š¿ ÔŠë$µèRïC/'M;]ƒs‘«Ÿ"ˆxµ; “4y~6@£ÔʼnB)xÔ(›½ÃäAlKý‘Ï$;ù)è‹äƒ!¦¯¬dùÒ&²NñDëÔuzþ;Ç.@}•ý® 3}Ül½<Ü‹F@ˆ"1’;ÉfrE¤ÃÉ:äÇ©ÍdÄ×E8Kµ<ûeRfYEMQk±Á6Û´ÿÅ,ßabRéÂ÷™ZGÔcf9”Nœ‰{±çHfkÉwèÄ3_Û"ˆ!À@$"Ë:~HŠÍj—ô!Åí™¶¬ûs¬?@ w¸Ëd.KB²‚ØøÊ£ªŒã÷Î:¸Põó&}?12`ó¢.èiÑ4AÚ¶•ADÛ4JñÅ#“£‹´^”NÉIèk}$ÐÂÖû€äˆÄï ‚ÂYdy/?ÒbËû9Ç]æ´¶õŽó–a¶{øÌh fJü’•.géô½Bpó%`/_ƒK—fxôÑGðüó/I¶È^>“T™ô+/æÌ6ÕT©8ÙÛ°"É#òcd0V¦§ÅbvÒbºó¨ S8€RïW™&#sH?Ü®|ƒÎßüãÖŒ„R}&ù1€LHŸ’êþDmZÉ ÓÊ„¯¬!2$4ÓÀÂø¼’7åþqì|å9OPí8w3’3(;–|<œƒär€©q¹øŠIÒ:´)¾¿E³hÑ6 3ü¶E»ü~ÑrlÛæµMÈ¡êH(äƒ<{ú\";ƒÀùáIwJžIG§üyu²íœã²D ìßAr$ d³©^’‡O?sê"¬q!T<¸‰åw)M"T„£˜Óѧu‹`ê½;Ã&?|2Œs®·•ßnÚÙôðù‰âÇ‚‚‘+gh'YDÊ=ò¿AP×:¤në ~ôGÂ>ÿ“øÖ‹/cÞòyƒÞ—Q>ûJ®Ì§8¥RLô©\Ï3Î ôû©`ª÷«¬éÊüY¤ðA䘜HÁÈS‰bô^ÊÑ\SJ[I¢Ô†FóPê+eà7@ Fýrý¨#k` ‹¿rŽòá\@üýÖÆrܾ±ºº×¡ª}tWù¬óWUUɤ°‡3œúaVYÌP§Ï0J¾Ÿ´ «iÑ,š¦IñûmÓ¢m[4s]ì$%´¤…Äú~~áÜQ­+X{zÐ…u/3z©7:tÁ`ÙG®DÖr¼˹~L(¢þ® Ð×y‰,ƒ~ŽëÈ„TNˆ&ºŸÃÒ1 ¦Uåñ•¯| _ÿú˜ÏC/ °_¦ª<~æg¾€'žxm;¾IõYÛ9Ëáû'?"f•Q%É?›~,r‰-4í‚¢¦¡1 B^{íMüÎïü;Ìçú¡ô&OË/}iáˆ):I?Ù$?tTë\Mþ¤rᮂjotP„sòÛÜFÖúµ>y‘bòþ‡¾tÃz¾ºÅbÅešDÎ6þ/Ë;Z))ʃ²Ìc詹Ç(»O¾B€Á"¶a9Çx˜á¿N~IþÇeœçœþU%€_{xgÅpÑzÆ#WU)WÐl¯Æl&Ÿ4ñ§£´M+ ß´‹Fböƒ¼¶ßʤ.qºê9÷´8eÏ6ê÷kg`'$­ŒÈÿ¥Ã(Ù9Y\øk(E™£sêD DÂ)ì¼u¤¶€7dDR²­[Ç.àçç;Gë”G\Ë1›UxüñÏáé§ÿ‹ÅõHÞ•azWƒ‡z¿ò+¿ŒgŸ}ûû;kë,ǸóÑýôÙ_Ö׳½û"ב4ÊÒÒué!+rŽ/oJ=4:è7Ï}4ó…C0ù:&]ë–nè+ØçöLqNËæLžØS9(ÏP*EE9•xüSÔOÊË.“´&k³$¿t£“ÞÉ©©C¥¹u¾.‡uÊ­ HY‰é7Hi8Ú‡RÚf+Ñ¢ú€Ž(r$O!(èKDI†NµÉ›œE!á([gyˆÏ³d£à°§ô›à|Q90 |#Žñ¯þÕ¿Æ|¾Ø°¿?e˜²­wÞ¹†ù/ÿwœœÌwÖÎYpÏ)ÁõlüUÜIÃö^Yʈ9Q/ußÔ©eºÎ‚”Õ—a(> *.£uŠ‹Šya¹ÓÌÂõ}’]¢ªêÈ®£/ï0ðG½æcËl_Ê(è'voçeÒXÓÿì>1~ä¼0ᓃÍ6ÍÌ©!žº`ËjT…óË95kü:ÙëkÏΠòœÃGB@}íË5]õ*y{BD#l¾m9N?kú-Ú¶‘ô Wû†È“¸Âò9OΔ@ŸºåcŽÚ‘ð`Š àc¤¼r›À±ù*Ñ„Ð{ LrÝ¿ªÙçQ…´)£Óu#e`\/bGÛr 9ݺ€ôܨ£²âàä­<­çìA†é1FŸì¼³“à>ì«lkû&¶uAzÕ•S:˜ €ãUÚë€uÎr©Å(€H‡Úå€Ò¨g˜ýgxN –Q9Y¤OîÊà ?=Êøó]9ë¾½!»^'Χ úêPÔ!þ´L„±ì´¾òo+Ž«1’ÊÁj8­†rj27YÁkœo£,¿®ÓwêTß—\>¾ö˜]®ówHÊè#šEƒ¦e™‡ãø´ªóÝÌ%ÈVÌ1{ }ðepŽ›tx çùϯ!Î>@uùr¡Å\ïèS´½~èCÂíX‰çÏZ>;Àc¯®0Ÿ/Ò4*!ò&ëéQMO“‚zå¿“1Y'•½£€ý<Áö|w¤)ÆŒôuçÀ¾†­ûSǾl“W¦Âjï9Ó/[\2=~IצIÚ²O¦3gÝt»XRoÐuâ *ݤ†Äˆ­Œ¾Iש>2åð]é{fì àQú «qSN®Dùå:) ƒºÚ-sÿ+èKgï’ÜãtenåP×,ñøÊÃzË»…U~Æ“½•ãþú’ÇÞtI«iئ¾J9Âô›2V?bÛ¢•UºÐM]bfùNäOÌš"GÞDùþ#ÄQxþ¾T¯¹\Nµ]‚~w· öÜK;%Øó5î|æÎhgù˜`î«@}È~:p²snvÇúi ŽmzÇÀ{¥-–çÇË•’И1åúuÆÒh: d'¢ë §Cz²·!I¾ž|Bª(õzðÉBK¡Ùk›&·—€Ø0y®+B(}O¾ÑÑ–t|”,Éi¤‘€•Ò.]À›ÂHtŽ“ø}§“·•C¥,¿®EÏçIÜzÆ»ÖYÌf` .aO0ÁžS-×lYÓo9r§]„(›¶´·hÔ•¸­hë Ò òIª @ô R-_¾Ï4JßM±i®»××·Íf5>úÑá¾ûîÅ·¿ý=ìï,}™ëÕ¹lßšM {ÇÐnÄwÌi2¬,']lj”Ú‘0ÿäÓDk,Y~á U¢)Xc¸~O$bTÉö%'P!ÑðÕ¦;¯-@™¾2ùBÒÆëëð¾+ߤÑ:“ÿéË`¹Që§w6TËkmÒôð¯xÑOβ´SÕ|ͱúõ¬‚«<|­#¾&Mâ Ëç Vð5'ÏBsó4,ñèn+[2F¤M’ºo\U¢S==&y†:LžR|¿K±þ:ОŸ2­S¾¬¶ÅB°H„¯ýÙhBãÇìë³”Fº²W7wÑ‘@Ž0Jé“Ó#-D!#A¼«ðÐC÷ãÊ=WðöÛ×pxx”6¢)cÇûƒ­_Œ¶–rËŒ1ì±c[ÀnŒÁý÷ß‹_üÅŸÇ܇›7oáðð°`ï;`ëK][¯ìzuŽ‹»ŸYäP~š)ónÑ^'šGÀ¿J'†˜¸–‚™”1¹Æ2ÉZ’b€ì©Çż€Ê4ÉùQ;$`¯ O9Ó}‘g,rX§ÄäÇ&2( »o•Ý[ÃÀÈ ]¨¦ï,³z+¹ö—äkoø^Í|Šâ©Tê©=ëûÎÂzj/â’|@:Zø¼0«iZ4s‰Ö‘EZ$ûô†á³îí "Ùm‹c$5§½æã§äÅ–Ù|Ðï]CZT•5ý˜æ Lå%þžû`¤»]O’'JXeÖöÓ–!‚¢Oïµ HWú:fó‰á#,¤$Í•£íœíO&‘Zˆey Hc$ÜÚßÇÕ·ÞÆñÉ<€bÄZ¦\Huwe˜©¶¦?›QpÏ > bÛ`ë}ÛÑÑ1žyæoàœÃññIÁ>WÕ¹l?O`ß… @ }ì‹ÊŠú“¾b[ºL?Sÿ|Y·š›'7—AŸŸƒô£LÄö´^‘‹r ]Ð×è eù øQÇ)›çµ8‚g \Ý‹ÄáGðÄ,,‰ȉÖÒ¦+² ×ãóÎ[ÎZøÚÃ8—€¾Ú«$6ߣ®+ØŠc÷yu.;23&Cˆˆ ¥˜ü¦ hçäÝi°ÅX!°nBHÚ}ìèöî!³vûÍ£``ç×d ÉšÈMÂ?mr6T¯/Wõê(¯a6¯¬ŸI `ˆÕñ|'Ÿz/¼ð nܼ™7À)¤½Ndåï==ç¤éÂÖÏ»­õŽ•qîýcWÀ0[(cGï,&ÛtRx>o¶ÐÏ‘~€"Œ²´%¶]œH1Ñ“òÎ/(U$ ZBl 3KK‹±¤-“@_Ó*ÄaÐ79-D}탩†£ïêõHLÞVÝÿ~ôƒã7€7öyÔ!‹ª »g•µÜ§«Ž"éœWÇXÀXãd`Ë1ùÆ8ç9­‚Ë;ÕÌÃWu’sªÚ¡ªkɻà ·üÌã’H\1ÚSFͶáLšMÛb1fßj¦ÍÈÀ, ¿ŒÐ)'WK6ßaìD©<…!à°¡[º=cˆ…¬ÑŸ@M¾ª©}s’Ÿ¸ux„ýÃ#î¿a'Úy”e iÛD,d²·ÜÃaA9îL¶^nKzÖ£îÅ(k© ê]`O$Ð wh ?|~÷¶Mdç,>õ©Gð³?ûßáw~ç÷±X4;èË6¶Qú%™„ãjéð§Bç§tg µäJÈt~¿|¬}“& ó+’äÂá•&M¼K¸ri†¿õ™Ç¾ðSøã?ù3ܺ~€¶iaLH¤ËRÚ$á0€H2FåèD-ƒ:Œ‘t 94“Ó,3óçL›ÞKo9sfå92§æý^¤ŸºæÉ\’OT÷ÄÕÍSú+mÛ…n™(`#Ï?…˜vÎr%ø 3O© À§e”ÀuQ(5yNëƒ2ùn}‰é—Q;)©š¤p.Vô–sÆØ"}2ã׿ÉWO$ë>¨¹¥¼9ƒ|ï¸3Ý{ϓϣmô¸O}^ë±õí3ùqÛ²ý¢È0!®^}Ï?ÿ-ù¢Îæ,–ÏoÁF™É—¶ Ó%ªçØŸT¤ëHâßg¾€£yVƒ>3´rØnò{9DSA>àøðßûÎkØ«=ÞþÁ[XŸÈ Í®¤“X¼€{–‡„¹k^ü$Ýhì=m>ÇóÆèÆZ4Τ¤j°6Çâ‹Tãk‡j¦‘:çß™Õiµ­u³ÊavI,!Ę’ª5’>¹çTÊ ü’29ä|ùdkDeë ²ú:pZeÜ‘@:³Cz>ÂÆ>Óï]+=z>jqI"]}‹$딵ì2’§äyÊGÒh³¿¸JÉÌ+ÃìíÍðàƒ÷ãí·ßíý6óLÅi5Ó ƒwÖäw ì]†éÚûû‡xúéç8î už¸ÏR–zç©÷Wsæ™F• Ô7ú1“5Õg¨S ¤Ó­%Ë7¹ù“@øöK¯âo\Åáá1gåÜÖÈœ$íXcÚÔËì˜ÍÝûŸ^ecÈ9]зŠ™R,8føVþ¹ÊrŽFãÌ*Ô5/¼byGVâÊö‰Þ{Ð%ù<$B§iÖî5ö~Á\ ÛŒA[cä%¡Z‡Åw›BÉ‡´Íb²wA·œ‚·îÉkcÉìà¥O6I:*û}Þé-‡aÒÒc¸ öb¤b}E:×&·ulßXkñðÃÉ({mà>ôiŒðÊ$b ØÏê§©“(v6"9æKÆŸ»DØ„žMÞ‡6¢ËúõÚŠ¾}BT`  ÏÆ}# ŸÂBI7aA–qôyÓ猊Ñ]‰I9ë§[k-f³UåqëÖröHc ~üÇ?‰|äƒx≧ym„>¯gôP£éÆÂÏ‹­wmËö‹"Ãlj[¿/»µm¥¾1Ð àÏ홲Ü(èk¢4IÚ¦?X=–(ï²¥Õ©./àfa±œ:WÂÆÞ€l"9ÂÆW.]ÚŒÁ¢YàÒÞe\¹ç2Þ~ç=î¾U=_#t²#È oÐËQ9ÖÁxÝËÁIVLïlÊ É»_iš…ªæ¸|WyxÇç fÙW\Éb+ž¸åQBÛ¦­9SfÈÑ4})F¸`é‰õË.Z®üšgŸ_C¤¡¨‰Ù"!¶aIÖÑöbÈ“¹ÊôuPÆÜwvÇ*À>=”Ÿ™‚»BÊ95ØoÆ¢9íE‹|àA|èC?ŠÞzë]ਯÏ|æQüÕ_=‹Ãã"ùìÇÚ+T»¶)‰K¶±:ß2Ìöl·O†ÙN}ƒ6¡Z‘ БÓh°¼@·1,¥-XŒ³ÉàO&fâ#³ÊêsØM™ê8ƒ¾NàêªK—/ãóŸ} àùç_§>þ1<ö™GñÿîÿË“¸ÆÏ±õK¯D߸|ž7F10'r^&jË<:Ö;Y\%Ì~¯B]×p²®««´ƒV-#œ©H…\êõy«Ã˜ä–m¤A¡£à aä è.”¬óï$Š‘gbÐÉÛ ml¾U-?? 'Ó{eóì1öÐ`‹`v°mšo¿ý.î½÷üÒ/ýÞxã*^xáÌç <öا°¿ˆ[·ö·ÒVy¬µB•Á;ÿ †aÐ϶å:‡l· LáI“M®t‘ýβ þn>ãIЧü"·²bB¹ê—b|€@¥j”4|uÈ=§OP=~æ>óéOÁy‡—_üžüæ3xæ©ç°X´i2¶ÔåMÁÜ5òÆX‡èZ–yœIá–Fö·U°g€çë­»l|bu‹CÑê™Ù׆9fï+XgQÏjÔ{êW9–¾)v¿Ò¶í¢•ˆÝí*¤È˜ÂØwÁY·S$qswð•zu²7êÜ€: Õÿ;º>uç ŠäjД±ö´ì¡{Û®ö*ïléX,\»vôG_ÿøYü“ò?àí·¯á+_ùþÅ¿ø ìïm­-=<0î´Ö‘aL1YÖ·Ô—ûqž`J¸rå þù?ÿŸñ¿ñ[8::,s–~¬ß—ÝÚ¶Wß¦í­°‚þ€´S<– ÜÔ×}R–ÍÐ地õ b¾¼Ï:7®ÝÄ×þó7bÀµ·¯aq2çë¬Ê; ê`SNNmlal+¦LÐt ÑqŒ&ëó úNZ1›o$-²±¼§­­”ÝçÕ´>…`J„ÎŒóã[çRžo,c”Ìu›C^]D³¡•8û‚SÀ=½=@^åš ü± Ù) Ÿ‚Nw'v5IÇrN™,'lsò4÷>ðçˤ¿£`ÛÃvÂÀOúÔÇõë7ñÕ¯þ^xáeü³ö?a±hðÈ#Çõë·póæþÙ(Ž5W¨NÉ0…­¯_vèüÉÉðÔ›±>O³Êv–²Ûö€ú*;ÅŽ®ʓHe|²NáŒLÒ’ Aö4•¶÷ðÂó/À;8©=§Hˆ)ò&I@²Š‰V›AßevÏ î-_oeßÚ謼·I»g&ßÂzf÷®G á—ióòƒ9ƒ|%+m9yšFäøºH6=‰ 𡉅^Ïqöœ-ff/,;n ú¡ÐíCÄC —¿m)çÑ>!ŠnߟØíÏtcù·övìÍÖÀ>„€}ìÃ8::Æoÿöÿ…_üÅ/coo†¯ý Þ\fã=Y»ÇĪ„1€¾xÀ¾9¨ëѶ-žzêù"|ñ"ûe;=°oh#¶O°|*'wKo ¿ÝQâh IDATªõ˳ˆB Ž»/®ëH8ÐZc_FϤÈû²MÖå­€wÖåY¢ ¢Õ[Wþe°o½MçI’f¼•|8,ã0èûò)î~–AUU¨f5Hd¿”ÅT²zVõú  ¯©ŽÀ5D²d÷”e߯بÍ2¿ùRÇ)Ôr)’giî¦`o–þŽ3ûìOô{{3üÄO<Šßû½ÿO=õ<ž|ò9üÄO| ïïý]¼òÊwñ­o}{+¿´BuìèÊ0]`¿e˜¡2 ìÛéÇú}Ù­íÂË0[·ånçÊDð)¾œ§Dós8fGnsòFóÞäúù´øªÙË"* _¯6Æ€D¾‰²*63{(°'àg&Y<¥²ñeØ¥Cãxórãx­õ¶ªxµ¬DãÔ2AËrN W³ÌãœlвW¥ÑŠ.ž M+Ûê^µzÙê‚*ê})×tefî“/Y¼„sæëTçï²ûnÌýYÁ]°×‡«û¡ Zuk½ÁÃßûÞ÷ñXqãž|ò9<÷Ü·ð‘ü(>øÁ‡ñÞ{7prrž~úoðÎ;ï øbÑ išQ\=Í!à>ì%òðt Ø—;~'É0§µåû¤ÛÅöJf£úFì¤ÿ㓜v!ï:gk1k›&iôË}iÑÝ—V@ŸŒ‰ºƒUÈà®`¯z½r¨e{Þ†°«É3ø3اU²ÞIj8‹à}'ÔÒz‡¶rô"Ï(«¯kx ½¬2ð»ÊÁZ‹zÏàA£€} ç•´*§„VY}!«”+^ûò°x„ˆ?ü“¯aq2Guï\[g»J8m· Ž¥Swj«Ëâ»RÎ8ØS„$N#É™/«i@žŸI{I¼Óœ÷o¾ùBK†ôLžà»NµBu›¼9ÛúewìÎy<ôаÖà½÷n`±Xœ²«lg)»°cxÑ‹÷X,i3”÷¥ ³M[zCÝ;â…ÿðîE|’z!éJ°­¶ý¼yIΛ¯©Œûqô!m(nS3ë,‚`]ÖáUŸ—MÇáÜm}VÀÞU>>‡\žÀÕ2)[ëÄl?ã”ǮجÜÉ(€èþ´¡GX·×ômŽÀÑÐÇPÄÈ—ò2úªrp} oCð}Y§`öm×y,}™GgT·×ÅVen}CºðJGzüÅyDT§ŸÏ<‡±¥h˜| òŠ ²{g°§'¼c*wQØúYÚS­ì—~éç1›ÍðÿãÆÕ«ï »™ÈT_.†Í{~ôƒøð‡ßúÖ·qýúÍÎnWëÖyÇÊ0g´ßít5-ÿš;Ñ9„B¾ƒ8*òõÀÞ”ÌßDP ·Tù&ÇÍ;ïqϽWpÿƒ÷ãè˜s©pŽz›äv•h²L“%‡P¹îF¢iŒndR9X/Z}]å­ gu‘*w®²ÖÀW\mPËFQ½«NÐfù&ƒlèÈ)…®Þö&duV;öù=/ *&tËzRøe_³ïNwdžÄÃ-²¡q$ºæ‚÷¥e€ß °³©p'ôÁ[ê!`϶íéE‘aú÷ÍC)^\±~_vk[·Œ1÷Üs _úÒð™Ï|·nàÖ­ÄØ®,[Ú¬l¼Pf¼Ü˜š·PßYû9UgŸØ~séR°Otœ™¡nt®Æ…’Åë{.ŸÂ(%â¦v>ò1ü¿ûsxò©gñäSÏáødÑ]<µ¤ÇgIF£o:ÿäƒïƒþ‚ÁÛ—N%›˜T¢Ùçl—šJÁYN˜†ºBDÞ„<´¼MaF«ypBÊ;_J7a™Ñ»:6rŠ„6v|ûÐûÉÞ¡üNh¦ÍÁz‹IÀ#uû£ÒÖSL¨NÙ†_Þ-•Y϶~Ù];¢ˆ›7÷ñ§úçpÎâÚµ’ñn Îg){:`ç÷»üÚkobÿï½w#9©uÛrÎâ±Ç…µ/¼ðRÒ w¦u=Ã|¾@÷{Ù¾ÙÔWØ{£:ù‰#‘'Ù %ƒ=‰3ˆË`¯E‹8z]<c°À·®ïãxÿ‹£´' Â|±u£©xñTÞ^¢Ó[ïybÖgfo+•p||[yq¬Í[Ïü¢ò ÇI\½¦;ÖPK›ö°õˆD¨%½0¯Ž )g}PàîkòÊœ;  Dzeòz.¯”-Ùý0Ø÷mÝÑ‚i-—·d bˆ@/=FU€Ïßïvð½œû?V¤ü?v ìgõm·×¶-Þ}÷=a“göÛc;>>Æ3ϼç,Žuƒ‹S8c xà~8ÇËç%ýÈÀq6 ­*Ë—/!ÆX¬¾HÀ¾¡M󢤣Ðí ÂòJ°—0MC*ö$6˜À!à;¯¼ŠïÝÀáá!ŽŽxÿac©oº >ØœÞ MÈú&çµQ@OÀ.àïð€<3úlw"Ë8ï$v^À½âDg*߸Jv±ò²é¬…òB*–o4ÑYJ‡ÐI\ÑIJ 9&wì¿2û¦X<•Ò"(³o3 —¢ ˆMàÑ@úË Û˜ˆˆ¿ÚP<É$ë™Ñ}ýò£ª ÞÕ𪶋컰èéÓ· ÏR_ÛF´íѨ}U{mðÄOà¸]m]×øìgÃË/¿ÚÙ¢ðbÊ0g´‘ö vÎË8±~iäoÞºmGí!Žå»5"kËñõÕ²y+Á¼…`޲-4zß°öî `O­Âä«â¯f³”y[;8‘qœ€;ƒ¾=^²^V,ëX™°ÞÃÃ£Š¼;•®šMQ7ÊæÛ4ï$•(ø;Véê×>hwÀ¾|ßfmDlÚ ìM‹°`p‹Á˜E+å2’…ؘÁ—Q…ÊŠ§‡„#ÇéÃDú©C´Á2›‚éúeÏØ×ëÇ*ÛYÊžØÏÞÛÚ¶Ý ˜ªÍZ‹+W.K4’žÒùœ®o¬Ü¸ú(»doúXç‚4Q¯ c»¶¯S¸&žÉ&ª­ØDVɦ<áì•/o-Œãݪ†B*5å•EP Ä}ØÄKÐwU%rއ«›‚Ý/8MBí$ïOÿœNèZ‹ÊóOŒÄ-) r¾ÎC£é„s>ú"e(¥J ’Æ?ö!»dÓT@·‹qÑrºæyƒP,<’â–¿OÒguSÞ¾ž Ó?ÖÎçže˜åócåîdæt}yÙÎSúà#ƒtUÕ¸ï¾ûdâvxo×v:p6=[ÿÇA+êìûh{TüŸeâ£{$4áü79Ò&ÇÒÓ’Vodóð2-Bt!}'aYz–j‚Ïú{š€-Á¼R°oè‡dÓ÷ î­o`ëœáÒ©vïy·ª¼›@ð šR³´ëTZ [}ŽzéNˆ“§K!“¢Ï7mþÛ¶ˆ fìa^¡/NZ×H7‹þÞAıÿd9EŒ]Œ^å7—qzdW’%íUy>½[²5,ÕwZÛía.°o¯¾MÛÛ¦Ÿç˜UU…B'çý÷߃}ìƒpÎ÷±[Ý@{fÄf”D-ن϶ÁcxÖõ!sÖì3Øç…U1…UÊÍÈoV]WM–›‘¡“¡\,É3¯ŽƒñmgµkÒäS„Í¢xaòMcèkÖê}]ÁÌ9ï«9ÖÞi¬¤Fp>kô*Ý_Á@±b6#‡SFÑåÛ þÝpF‰Yïg£l³Ô“äœÀºzææ ÂI7¯ÐÏa+‡ÆÀÌåû†¤3ø÷(ó)¾U0ëjïc#ÈõŽÉh™ ÞS Þµß•a¶QvÛÀ¾ P_Ǿ̼­µ¸ti?ü î¿ÿ~œœœà½÷n iZ<ðÀ½øü~ O|óŸç‘ÔÖz2Œ´aÐÖw<ýz»Ìx ¬éœ¨·WІ*£É2£6a‰±×•pR0”ÚŒjõ&"ï:Uf±4¡Hrfa,ƒ¿µ1I6]©Æº¦wà÷JØüB\ßÃïÕxøþûñî›°¾å‰Yaú®®ÐJ˜e;gçà5E‚Ö) ²¬5°Ö³Ã¬‘òÕ—»L…Ð#r{µlˆ Pâ(Ú ­€{‹æxx´€©Œ›ç.#(ú¼À)FPÌ׬§°l'dòÔùÜ/ [ßE{ë÷åýeÛ#_§\Œ‡˜/xëíkxä‘á+_ùY\¹ç~ú§=øþð?ü)^zéUãÊå˸uëVªs‚3èOÙ†úR2ëeЧój.•R$Ö\t˜`ìÀ2˧ôw-Ч\†ÐsfJIûHé7œÂ-#³wü(l>$OôüÞ±|“Ò8–'Òâ(•kšB‡_$`w³ 3çñùŸ| ü§†9)+e¨+¸E+š=Ë4vÁàßVlÝ$&ïUþÑùká,Á‡ N€Þ+PkTMç§´§ bmŸH£sBÛ Ì[¸ã Í¡‡©5Y›á±‘:‡”릌Râ/€sÒ¬B÷³±õòðãÐR. °ß•aÖ±mÚÞ:¶SjáIPÛbÑb±hñÊ+ßÅ믽"žýëñk¿ö«øèG>„ô«¿‚[·pppˆ?ÿó'q||‚££c©¿D´¡¾ägwŒ)/í* ]m}‡Ðá\‹)KI‚‘QÙÖÐazíõ/\o’6ÝŠžâÝI²t•¶ +äÑéø-`©ôÆFIjæ Þt#j\“B)CQSy¸“ÚãþÝÿù x‚VâámÝp ‰“ YñZ;øª…]0°ÛÊ£­<\eáê*ÅÎóD°,¶s€ƒÐö²pJÀ[óË0}ñ§ ùd@`MÞµ-BÓÀ{ØK¦¶€g…B"d6À¶ÖEã‰\Ž\Ê“ÜÓßùö޵ò¹¯ê™åOÕw1ý® ³Ž-+'Ëê¥(_är}†Ü6Í‚AûêÕwñ ¯àßü›ÿÎñnFGøä'?ƒƒ#áÝw¯'Vœú±$bDN)~Xƒ+ó&´wZžää û \6+,¹S*ëâi#ˆ~µƒÀ]:ŸáêèÈ 9’²ßÔ‰ÀélOh(3zCyi¡›’¨tà ŸC)cóä«s²kÇÏ«.Ÿ&R+x+ŒÁœžA>¿·² 6V-l}ð~VãÊåË8<:fÍ^õMX͘ À’ƒ%Í #š¼²vâÉh2$÷Ï@oAÌàC@X0°Û=^K `ˆP[’IWÛ40‹"}³µ’’ ûPÎ=ü½ñI?P¼[ìÛdò›2kc î»ï^ܼ¹Ÿ<ð:åÖïËû˶™Ô2Â8:@Û¸n_ÌRê(Þsb¶¿~öEãd>Oí½òíW±X´p΂:å†îaÌVþ( ž| OÒöðr CL?³ü’áó˘ïRŸ¦|ˆ1Œôsj’vô);býü—åíëô x¬Õsü<Òë}ìçš—í—Œ”)¬¶Ö8xÏ“¯ðü¯ o vïlí`ˆPÁ¢=YpÆK²&_H6Ïï¬9€ÈÂI²?""êoÀ¢%€¢ðø€ÌÌÂ,„± ËäU©ÔFÌ'ÜfÔSc` ‹ÏT²üm÷XsBX Þ»öU¶Ë—÷ð›¿ù¿áŸþÓÿ7nÜZ«Üú}Ù­íbÉ0Ãà¶T®sYÓåÒC@ËQÀÝgÛ žÕø±O~ O<ñ4ŽOÚæó€AÛ†áö:² åÔ{–MÏf–Gžzqð3Éåz·›Ú¨7y6ìûÒN§=XkðñuUã•W^¹ ×“NýßÇz Ÿª ½~à1åºa ·ò>C Ìð³úh Œ ]¢Œ°ù”·&ÅÃ+C_°Ì’À]@}Æ@ŸY}#²M‹×ç¯KäŽÔÕ2«w­Ääw€Þâ À27Á¦ï"‚•¹ k ‘"š°``·@D€²iÞÀEຂù­C´GóFÊúU(œ¥~¦(>àÝk¤üU&l’ (e˜e[QÓR½C¶³Ê)GG'øÇÿøIšì¦uþpÊ0fÔ‹²@áÒf¤^>Ûgå %ãoo>Ÿã·ßÃáá‰ã§ÿuÏðz‹¬{äþØ92;9Lß!,·g4Lç|—è h¾c*?ÙÒØ&ŸwÎâÓŸþxà>|÷Õ×›¼kÔ0p—$kÙtûÙ?Éÿ[èYº(5zŽº!˜d±TÞaÊ:„µÂäuAK6A>HÈ$³t[× ÈÝL^Øý¬‚«[„EÓq±m᪠10°ïà‚¬ª•Ü99׎Œ qä‘3²‹Ê9Þ)(`qˆŠð±BlZ¸“ öÀ'Õ%‡>p?ÞÛg)FY»¦‹H«Š-Òî_;‰ÚÜÇR’ï¯ÛùÑÎÌ›3ÐR{Å‘ÒýMšæ÷Í¢Å×¾ú cÐ4m²ÑÒÈ ¸;êד/Z{û¶I 7èu´¢àó†ášúÀX˨Ñ:XzŸÙ¼2yÖåubµÍMÔäÓ9¾.ÎjNHVG¸Ú!Ê"«=b Øà`Cäf‡vB6)‡1°–oÍY‡Ê8Xc጑ïØâÙ½ n†fÆú»94&àr½‡+÷^a¿uuÚ´ôìöX;Ÿûé´÷n¹¡:ÏÊÖOk[¿/»µÝ>fè‡Þ+Ò‘7z§‹wÓåÌÐGÏLÈËàÑ-Ó¶Wð.B Ê¢dÁHkãÈšâtÙ—aÖ]Ê0TÈWðs?÷8žü«¿FhLÿ¨Ñ$d{£¢K{VÐÏÎÀÈä•×$;”•jÙ¦ r‰:ƒx—Žn)?n/žk|ê ÿ¯Ü:®Ãè¨.Ÿ€> £×U°:[H6ÖYÄÖuؼõ-¢äU[°x;oz _Ã+À/Ä ,Z~ßxĦ‚«3ú@UL“ºTEXŠ0•ƒ%Ù¹ªðÙÖXX8Æ8kð@}óØÊÂT¦f}ÝY wiW9dºßýÎó˜H?¥–1‰FíÝrXi;o`ÿá–aV€z‡ñf`2–¤–\¾dµÊÈS}K²Ž”‘ÓÆ:\»~³+¤ˆS‘~ I ˆƒ¿¬tÝûÞ~û~ë·~óE›K¿Ü’–OzÏÄ [dnÔß E[^̲…ÚôÑù6 [ñÃSp-@½”o”Rú K¨÷9ô¥Ÿä{}‘ûI@_Ž”ÝÅΓ ì#ñä«1 úÄæ}à ØÆÂúâåâÍ+]k7Wy¦A˜Õ‰Á{yx?k› ¶ñˆuWGØÊƒ‚‡6GÏTV¢¬Œ4¬äÏ·0ðÆÁÏ)Dr¨ÇÜBæã€µsØÛ›á½Ïn§zÆce>÷±c˜­g‡P\Ù)3t~ûíö;Ë6¬3÷€} Ô)cP¿Úò‡»$™H‰%'ðn4E;&ƒ ÀÜRÛÆœÐ“Tô5éø¤©`ëÃwb$œœ´`§Ppë“ìøu.] ”Á´àû”“´¥æÔs¼¦úhe.~5СÃÒÐ_û8Š)ë‚üˆ«§®sºá•˱Y¶1ÖQ¤g˜Í·ÖEDÇàn¼ƒmÚ¬É/Z„ª˜h3À3¸× ðò/îU,×Ì*IÑË“²"ld€wä@ð°F¿c g˜yó“.#NùüyªÎœci@à1» u]éy±õåvÖX¡ºÊÖeC…­¯ß—ÝÚÎW†Y7=_f´Ÿéù¡šîIZÞ;Ó¹”¢W¯W–_>*Z¦ßóeð.Ȉ³è¤¢V©BË/—v¥­RR'w¸[#Éyär©.¨³äŸœ–SÆ›'Öä·CK4¶{•q:¬»üþ nƒFõC6ùÜ0Ž/î–ϯ8èMú_NI¯!1äÐï8RšŒ5–=Ž•O@ï[fñEô¶j²è©jáævÖÀ È3À× ö‹~ÖÂíµð³€ØTˆ³€ØÖpm€Dg#Œõ°†KUÜq#«V9ü‘"æÍTììD˜U\k±˜Ï¡›iƒ(‹¹ƒé蕽+Ãl§¾qÛXÄK ZÀ2ôIXb§Î –'2KÐ%b`ÿÒ—ǧ}ÿößþ>æóFˆ­2-[Ö—¼{HQä63[Ïíg¹Ce˜¥g²$µSl¾ˆ96}Û èévwÔ;OÂDÿöÞ<ʲã®óüþâ¾÷2«*k¯RI*U•–Òjí‹…Û6ÌŽOcfhM·çt7æ g†ø£û0Ðlnh< C70`h/ØÆÆ/X’µY’µ”¤*I¥¥T{UÖ’ùÞ»7bþøý~¿¸÷¾—/³2SeŸ¾u²Þ{7î÷ÞO|ï7~açÉrÑkOùAHäóR¤±øìu ±ž"]‹¶]³nôÇ5žÊ»1] Ò4Ç¡t´ÀÉÞÆ‚VÂ:VóŽ+£Éy âH›PxPEð¥O¾ Ù3÷ƒU¯ƒbÐA1èÂJýR¬š!Š©!:ƒ.ªé)tCøéÅ ‡bØEgXÁOuáª.BUÁ€wD¸%†èP!^ßÚ‚GéKœîÏb8¢”ðƒ!|¿„«¦Ööæ†87{ž»9® ô@íú]ødÞ[¦‰m™q6Œ¦çiã¼Pú³a&IƪuUÝqÉ|›)ÏtОì ×Ý(dM' òÏ=ÿ^{íu”C.,R¥)™Í«"—’,z8DœË׳çí¬2ÕcÙ^[ž„V!Ò)ÈAvK‹kî•w OyØ® W¤J+U»ýJÈÏAûj'bE.žµ.ß0‚-|lɤý—¤|HÿÇ¢"?ç÷”=ï%O#l›tJ.©yãÍ#ªxа¡àÑŽ\ÇÁyä§bXÁw¹S¯bÀa‘ {öÝý€=x?ÝE5¨Ð™®P ¹ûÞbX¢(«è¿ûPÁ£B.@ó…Ç´ë"ÞO¡ÂìàNœ?…ª?„Ÿ¢:?„Ÿ¢‡Š’pvvå°äþ䥿x=i“Ì÷ñ`]þ¶O Ù0m‘2ÿ͆¹ÐíKO¶u=S‘©K·gS%s +è±X×ôpìØIÃ)é…PFúÉÔz0Šœ@pÙAY???VéµÅBß¶¶|‚~K¾L”V+(ê@²a"C̳äɇ¦v}1 ©/D9h¦òvIßNbE­0xð›JýÞ0®i4î¸Ïúp3È·eL®ÿ—Wôñ¥Âž€ÍÓxì£ oÖn}6– òòa$|üJ€FÚÄ‚/pKXrÜ}.U¡Ji¬. q(¼D¥†ðƒŠ)þ¬Ctú=ƒªa‰Î ƒ¢ì±ú/; ²×s !„yøP!TÊ~‰rnÃ3} OGuzˆµÔÆîZTç8úú1”ƒRz‡ÌÁÎ"@ÈJ"š5Ó˜™Yƒ3g΢»ã˜<ÿGÝTäMx篮u{ y«ö^¯‡Á`°d˜:çpÍ5WbûömxàG0'ZoeÓò+[§ÅŽÈ¡nt\8­Â+h'Uli/„2q½·Ø.d*kAiÐÎ- x¥dc)Ôå»÷¦Î4]kB@ð' hóçãáEÈ+Aó i(ù¸l–5-9)äG¼Nñ¦Yk}y¤aTù ¯\éáÊ ¡ä†L:°u´k¦Jtú]Ó%ªwA\Ìwáæº(ÖpÓÜÅ0õ·^… ë7¢œ/Q <ÓGolžÞˆn ~å0¿z eÀû‹ƒ€K&„IÙç lܸ—\²k×®­Ýß“M.‚íÅöq6Ìü|W^¹ ûöío¤5§fzUy<ûì~<ÿüiî½`_Ôc²¨nÔ-š:¨‘Y,IUËÃ/*ÿŸüp­T~q]×PëÂg+M)»!cøc «4oQ­‡¨æc,±µ‡@"n© €ð˜Ì{·ù/]@Ã#n}!PO`gæ(Ô%j‡L„„¯KCâ1¾Õw×mj˜¥ÀÛzòHö ÀCrê«©ÜÍüysiÏŠÙÙªäS~¤Ê×úÊ aô‹€Ry-p,äõX¤ò5$%ÏžxðU|Ó7Ý‹O|âïc¿?,Eá°eË&œ?gΜÏWœÂ+gÃÔ„ç6oÞ„“§NqŸ+zVÑdJÝ,aᫌ¹v¶¢Â0@ÔJ Ñ–©©v¤7’4µLÔ¯Wèç•®$¯Ý_Rìöí€ô©ÎzkLûÐ…T¦µF)yÀ¾½,y«â—v;i~…¼Ž—Ddø<*‚ wÇ…¹Òà öß{•„O¨úÜ/|L„+RQиn·‹^§¹È•¯0wnG^;йÙóÎÏ£ê—ðýRZ¦qXUµ#ÈõXÑö^¨ªÅ+v–ÜŸ»Y*›ÿF¨u›BÀ¹sçQìÙ³ Ï?ÿ"ˆN×^{%6mÚ€çž;€óçç[ÎcôvÇÍ¿ð4j¤…LMOáç~þ}øÿññòˇ|Õ²¥3®ÛuY& XŸ²Jß:n¢˜É!=Q²9i¬Äð¶/QÚ^ôæó´Ì“ׂÀ¾5Ä· v‰Ì©fš/¶ìHÕîe›Ï!þ´p×N¿˜ÛIuqþÉk69ÓXVÔzôåÔ›*ع©}@Ho#ìªæS§’êÙsšWè°'ðËïhéµ ñ¸2o¨]÷”£ ߌ®IùVÏk{/.Ë4òròÊðt|„øû ‘5¡òp%wiÀ”•Ò;dÁE]J¢QC§ƒªp¨†Ãùó}øGÙ 2Ô«¡‚GmÒ0HUíš{6›Ó2ˆfê˜ÜKyÙ€zØ›óßh°ëtöìy|õ«ûðŽw|úý>.¿|î¾ûV<ôÐãxè¡ÇQ–%ªÊ7Ö[Nx;ç°aÃzÌΞ1ûª¯×–§I™ÌÏðk¿öŸpôÈñØdpãu#ø¨êIq+ÔuS®¡”sØ2¸y¾Â×EÛ„di›ìË;—ïSU{øU×X1 óëã¾(æé6baFùyë×òÄvžÛÁ>W»‘¬ê†gïäLBRÐPÈCŸ~#øtu VKTó0ۻ΅@ðH}ɇtŒhQó±NB!iJ¿䃹oÚ Oi9{O¢þ}% O-âÛR À;x®tõ2ŽjáØï ÂKe2¸v‡»ÿå±W]vŸõÕʬª²dU^zöî5ü²”y‡Lˆ›+Tkª½5K–ìÀ’;[y¨K_´D„^¯‹Ý»wâ—~é§ð·û9üñgΜ¯yW os©À_»v ~ù—ÿîß½‡I .®;ì@$‘÷‡_?ÞˆŠ=S¬æÁkz#Œ1ªát/ €›PWˆGuíè¢è‰ã¹ÕC'²ë¦m:©”U`GX[¥nއ²s·ð×\ˆ¥TüÐuÚÛyç¹TÞɪ.UaTÈZà·`%µR ÔUé'Øûxó_In‡þA€éÁq4ÚR€tT•b楈Gèk‡ùMqÙ¦//¹˜AÞfi;äc.Žåø2«xs,yÅkE™-ˆ…}¬tubÛTÒ¨u»sìß“ÞûÉ#Wß ¼½„_fŸÞ'°+Ðkê½™?+3-¹WHš*?O3¿.8m!Ð…ÃÆ°k×e¸á†½ðÞãÙgࡇÇìì¹× z¡`8wn¿ð ÿ§N†g,Ôäú“[ð5Õ:™¥%\1YÝ¥gR£S2¿Â9dCpqû!†9&¥ÏÑ% '…“,›8f$œÙ—­®ç,ð×É ¯ÇJo& ïT¤ q›&3eXIùO&Í, ƒŒÊLå*Ľ<¼Nû3ׂÜòz…â}ìç´…ªÝ¶¼ŒÖ# -}2Þ$-vqÊþɲ‰9“Î;Œ€|,ï‚ÉV jUΦé×X«¦5a‘SíÙ±o"!4÷"Íþ¹ÒÕÕ"kt”(**±a\êÞîJÊuè`ÚÞ äå·ÆÙKwì&¾ÝÜn£Ïg™§dç ªGÉØ´|½•Sóã` ¦¦ºØ²evïÞ‰éé¾øÅ/ãþá>ÜzëØ¾}+^}õu‰}on³(nºé:=zGŽ㊠;À…ĉ§v lkâÓPçÇÓ×Ò³×æè¡§e†¦‘@ž÷æ²e"¼ù­`W :~ÚÏK…A´oÔs'·à¸2ûУ*_*bÓ)ØÊÛ”'Z›?0͆uÊVU¶ªCz#¶âŒRK%pŸà)ÝóV½ŠÀðÛ—.bQq^;…º7Pgð“ó@`ÀS(ø>RÐÛïäÌoÇëʹªZçãõòªF9Ï"“­]£·”…|CŧFWÙ=<2tòBTüÆ‚‹’õ$÷HêW^ì;ÛÚ5$‚Øõž é|åZ#»EAî½\/é½/‚9ÎIÎg™¦ÜÛ ®ó›àNÐGL#l˜n·ƒÍ›7bݺµxíµ×qêÔ,Ξ=ï:î¸ãM¸ôÒíxé¥WZ·éœÃÞ½{05ÕÅѣǗ|ÍóYì¤ëYL…|¸š;‘ôã’C¿;„ÔS%©îÔ^QÛÆbÉ¢]\¦ÀÎNîˆTèºñuVA '€–y:ÊRv­ˆ¥¨‰ò7ƒ†WfvŽI«çæøGHB”tÄ&iI™mê‡ö¦åiòÖu?z_äë¯&ر-TåhkémQšf~]pÚb`:0??ßšÖï÷ñ /áÆ÷¢ÛíŒì–€š¸ðc™왲¬­“©uQEx/4 äõ ÐDêªÒC`k„6黕[EªÚà“ô×Å´ûø  ?CJ³ŠT ¬—”¦07 7°O 'Y—÷Å UÕ§X6`{'Àúòm×û/A>÷ã]Óoª©ÇÆ·qÙöé@¨…°<í—ëG,š‚©ÀoèÃÄd· u#ìé®:ØÓ~&Rî› “oãªÆ¯×ïð ¯ ÓéÀ9·l•¦Íi°§ùÍ7¿6µÎŸ±ÿ—F_.&Ñ(b D¨{xêJ$í°Ê€™q™ ž¼ò:Øâ©å*B²o¢úŽJ]Ç/3߃ òd”!Åí䲬ŽÇZ•býÊC©°FÞ24\P~M<¼¯@Ô‰ ÞÚ4ø÷Abä#äÒØ,¡âÃȲk¿—iŠ'ÑD!Û5”>–Qrù]²m² ’ïmP?VW­Ûi‘¶Lºp@œÇ¥aÁ´ ƒéè4ïNšÅÌÌÚ¤¬½¿IÓ&Uë&ÍöÕ:"¨‚¨*MŒM_-¶"3„>$µ#H» Hð•¡Ñ/•.#ÿªb¨¯S$ GµNâ] ؃±q²ÂÂFËØ¾jÀ52'‡»ÍA£ä£æ “¿öZ´U’ç×ìò;¥çªÜ9Âî=;1è÷ñÚk¯£ª*YÇ*õä™'¿]*b}jtxÁ€GÈ—ÓWìP0ª¾¦è\‚<‰‚•JZFw<¦gœ*|S{¾0Ú)Klý+ÃQÉ© Õ¼ø|3­0Ui›{Eï0“l#/pßl&„Ð\&þX}µn§E´P»d¶ƒ•ûâÓB8{ö’—ºû»°×Ô:?§ }’ˆ¨8B¨)ê1‘€m”S¬ésÅ©‹*½Èֱ˨b×eù ‹Ü¢Q¸8 ówVNÖ¯·¤´€K…€ž»mè”d»z–—æJ„úÜú…L¥Žó˜¿g|… #CuòpÅ´3" y¬áË6L¨c€^·bjŠ=xYO-^×Õ oá_!V"*äá94S>8Ü«ž‡¬áŠíT! D¨|•òkI*~à[Kàå™B:ÄçÑû»°#YM°·éÈ.}žÚÁ½X‹f\úJƒ]Óò:… Ý^=½ì”Ïo€ÝÀi2µNŒ¦ÒQ_/Q 5:²*Ûøàu2ÖJ@¿³J/ùê¢àAGE<nÍcm o-DLÒÛƒúçdö~RèyäNyÞVzÕ bl¢€nÇazŠ0ÕsèvÃ2 ß÷˜x !^ ¾†ŠùíC„’õÙ!vÈ+¯G]¸¢ƒ“§¼‡3Jdõå!6 ÄCgX èÑ1`·ð¯"ü­r§ •̪ȓ¬/y*Pg°h‹¬!r¸öÚ=8°ÿE ‡eö>ZÅ'F4> ñÜŒ†Õ¤S²^ëÓjwµ ®ûW‹ ;)ùÕVë²îJªu ¿ ™÷[+j]E´´4 â­X(æ%K$X¢aêöwü^Ô ž ¯Oéü©  Ò<£êÁ­ý‚?GÁH  OoT;ßT¨ñ}GX¿®ƒK·MaÇö.ÙÒÅÌÚS=`jÊaªG˜î9ôz„éaªGèõH@šÃ[?} æûýAÀ\ßGðë¼sç=Žž,qôøGŽ—87WÁzïDÆKÚ§L@½â“lÃúämj]ËöØlÍä žçéò.9äÕ’©ÀOš–Còæ´@€ÙÆO`û˜šêá=ïy7>øÁà¹ç^à¦ø¶ÂµUÅ«ðàòI}Û¬?_K<‡5_‰^8»ì^]½ZûY8ÆÀ½ ïQÍÅhìNZ‹Zÿ[°›%j`Oªñ­q´Z·ÖmiC"Uã¹’Nž¶KŸ±p(’â†3^9«sG)=BÙX4¶ˆðiûDVµ×Ô½ž_„:‡Zv»vlíáÒK¦péö.ÝÖÃŽm]ìØÖź5a ¬Û>Ç¥€^èuu»AµÎùù€#ÇK=Qáè‰ GN”8r|ˆã'=†e…<îÝ(wJÊ;˜È™¨Þ³ù9èsk¦¨¥FÍWÜJ¨øÍ)p¯•òh‡¼žÿ ßتI£@À£?(ñ«¿ú ‡î/‰È4€JFRñ:Ã.ž‹¤âG>=M“NÓÓSø‰ŸøŸðþ÷ÿ!^|ñ•Ô]öŠOØÖ²õõ3·Z’ “§åJ>Ÿ.°¯ª sÃÂ^nM«Ù0ªÆƒ·º‚>E¢¨}!óœôÑ RQÑ2Ÿ÷SóÃêNa]È2° ¢ΣRw2ß„Âxìé VŒšÊXaª×Á5{ÖàÆ½3¸rç4.ÝÖÅÖÍ]síëÕXvͰû²»/+jë'OW8zÒã•Ã%öààk%Ãʨu²f’­¢ª^~{[ÁZñz^혺‚W˜Ä1ðQÅûvÈ\Ûíöð=ßót»üõ_}ƒÁ ¤}±UƒàÑïüäDÑó²1l2êø`lšôÄ,ìÃë³29 çææñ³?û+˜Ÿï¯Ø/¦>-¹Ëß&¸¶h¾îm3ßZ1£l˜ fK¸~8E¢è ,K„,=UŽ’Qå ìè‘/=¨•µ[’õ §öL*œ¤ƒŠ¨Úy_E¦äÞ;œs§SàêÝëpÓÞÜ´w-®Ù=¢Ð|}c`½\Ë›7:lÚ@¸vOwÜÓCY_+qàå û_â•ׇ(«¦5ƒÚgˆ¬//P'ý^BÇ|w^º(ˆêÞÚ1|Ÿ Ïž¼GY|ò“_@¯×EUAî’cKM#l hT óZ¢”Ï5Á­Áñ©ˆ|â•Ú}xԦɡBhéÎ{¥¦Õ¶{WX ;Ÿšð^¬÷~qÙ)’6ìÔX§ ì¼­f–µÆTEÃj·( ì¼ârÜûæ;ð‘~š‘ÊIÊ@ IU[=Z*1¶¼0Ëhš~OÊ]+DÕ—G}™o•¾DÞ8•;×á¦ëÖ㦽kqÝUkÑëê[ßÅ ë ] pÕ®Üéð-ßÐEðÒk¼RáÀËC:Z²º´o€ÞÚ3U´_x~ÕôÙ³çqìøiþ . l$J€õ¾­W?½0/"€ÙBQÅ^ð6tžzèªÞ]*T±§ÊÖd¿¬ŸéáÞÛ7áÖÖãú«×bÝšvûbðJ‚½í³Û Ø»Ûáš]¼¥ƒ¹ù€_óxþ`‰'Ÿ/q~®jº qT_=}I,¼¨w 1Ø*·%ïù;Œ%÷Œ¨óÙ%¨•Ã`¥â#j‚(?.L‚Þðݲ5ñeòpIÞÆÚµkpË-7`íÚiìßÿ^}õ°©D]©éâµaêÓĘV^­Nç¡ñ6bÛ6îÝqvö,ò“^n°×”wKZZ¢©Øù~%¤<26L¼gë6 gpê¿¢–NŸ>‹/Ý÷0†ÃÃYmõÕ]­T:ý"×É7ePï Ú-l—€o{®ÐS¸d·ÓÁ7oÄÛïÞŒÛnœAQP+Üôóbðjƒ½mÞôpý•„ë¯ìâ;ßÚÁs=ÛWá¹+”•ªs  {mLà7À'~ð _!„GÅ®½KV€/EÝWpºW]}y½%´°¡âlD é9$ú&$Fe><Ìö’ˆjh呿Mð­ßú6lܸýèßáÈ‘+ ÷‹_­ÛiâîÞHfÍš)Ü~û͸ë®[ñ‘| ûöí—¾Vf)ma°S=m¬ £Öm<7ø!‰ti\zú>"ƒ7|rg-§½8JšS¨w’ÕÒ€:ÿN6ŒUðÆ‹W Ë÷k¯Z·ß³÷Þ¾3kÇG™èçÅà‹ìõOç€ëö®Ý]`®_à©ý?çñêëU„:…ðþð½¨; ä¹KÚŠ¡KN¼(üP!x¸*úñ¬Ü5²Fÿ|‹Š—þk÷ç’bäå{ðh>u;C[›FVj°!œ={÷ßÿ(¼÷Ø·o­ß¨åž¾¶ÀŒéò7Ή`Ï¡ž§åéË Ú€óççpèÐaÌÍÍ7Ò–g_ €6µÎëŒ{{4LÖÌ>*}b?.±²´ˆÞzjÊo½rYF=r'Ð&Vïªðƒ@Û‘ªzõÉ;™ª‡¼ ¤ô;¶MãíoÞŠ·ß³—lí^P½–]ÎýM÷pÇ 'gžx®ÀWŸ 89›{îì­W”T=Q‰ ±ïÁ× Oj߈J''ðר+kÇÈw¯ ¾•®jPUo».ˆÚ;xP´i\#š¦ xÙoäH0ÿ£Õ¦9sæ<î»ïxï%:&o¸Ôëu´u ¸˜iµm˜å›F*÷Å«õѾtsIÒÓŒ¹¹y<þøÓØ·o?fgÏ¢ªêã‰.n{“¥Q–bX°‹÷À™5±¿î¢k‚±XlwY\º‰Y79$²…ŒÚZJ êá_NíUç u8y€µwx_ÓÓ]¼õî­øÆ7oÅuW­•óƒê™Ù38rä(Ž=†óçÏ£ßïc~~ý~ýùƒ>æçûè÷<¯ßG¾²,Ñét055Å]@ËçT¯‡ÞTÝ^/v Ýëõ°fÍ46oÙŒmÛ¶bíÚµÿržó¦õo¿“ð¶;€WwðÄs¬ê…µ(xoDè;Qò•T¦– z*%ºF¢¯Ô'Bð!”A+2C ì¹z7j:óÄÜppä‚£ÒÚ-…@½c¶‘ †5Ó=|ç7]‚ïzÇvl˜é¬ªZ †8vô(>‚#Gøóèá£8rä(æææÌõ[܃1 1 qæÌ$K§{czz[·mÁ–­[°uëlݶ[·lÆæ-›QH<çJçÏÎK.ßΰèÉ.yºƒþ ’Ö¯FÕ[3ð R¢jÔšaeϾ;‹òªöU½3¸ ¢èÕšÉT¼v[ ã¨//ñùà†k<Ì Ï ÷‰ƒdµˆZ}›6Àg—Åì;ŸY–>õ©Ïcff]mŒ†I§¯m°-ý¹›_¨ƒ=ŸVì6-„åÜÞ¨ôñ`wDX·n †ÃóóýV°'™¿®¿m4LêmP †+ASJ»ZWOÝ;°2§N¸®Ó1ë*è‹X ÄŠSy ذ¾‡ïzÇeøÎo܆5ÓNòaåÀ577‡çžÛçž}¯zGʼn'e™¶ûÏÅoÔòíÂ'Õ’i›óó}¼úÊ!¼úÊ¡l9"ÂÆ°yëflß¾ »vï®];155µbßš©€·ßpÏÍ>]àá§ œŸ·«%B(Ò§/ù”Á¸ÙÂ)£ïˆ_¡Dt©ÌO`'c¥ž«x'}Ù[à3èƒ3«yöæÛ}x øP¼®?Ú¢©>„€ÙÙ³˜=óm²ék׆©O#l™… .—kY`šÒT¬ÔÛÖ[ùB$Ý q~ÒÒ³X IDAT¦ØºÝ¾ó;¿kÖôðÁ¿ø¨¼î)ØaÀžZbjoÁúëì¦â²¡ÖQD'µ^¯(-¢£ :l~<¼X'Û¦B}˦i¼ë—á[ߺS=·l0ªìþžyfžÝ÷^>øŠø¥öž3öV뽸ðƒA,š”{m{Ä€À©S³8uj/ì _¾ÿ!.½lvïÙ…={vcç—¯ˆºŸê÷ÞRáÎÇžuxøÉgÎs%){ì¯@×h{PÉá’T²%C%÷F±gÔz Ž €8Ä£(y$›ÆŠriE©ÑÏK>¼o vÍó ð-‘4~qÓ×¾Z·ShSìæWXŒ ³t%?==…Ë.Ûá°ÄáÃǤôʼ´§- vè÷‡øð‡?‰n¯gÀÎy”†¿³§@Þ7Œúë)&õÑRoái¿™VÛJ¶½¶4"–-›ñîwΞ=øoqäȱU²a€IÁ®iƒa‰Á°LéÔ6R’¦™þÕclºK¿ctŒ‚—¢ŠÏÔ5¬·Î ÝEµž Ÿ@^@É’‚¾¼+pÅ¥ëð}ß±ÿäîM(ÜòƦ<úècxð‡ðì³ÏaÐ×>KtªÃ<¿ésèŽúòZ3rÙ¶'Íy0¸ÉÏŸ„ªòxùåWñò˯âK¸ÝnWìº×ßp=öî½E§©êõs1ùî(à–½%nº:`ß‹<ød'N»¨Þöä žœ(võãŪW¨r!U UÅûøNàîæŽ"ä5ï4ªFÉ >¼Í]޹'©hMO€W±d‰¿Ü€ÿú±aêÓªãæ›|Q0m¦õû<øæææ¹s¢0ºê$Û›<Ó³ùìzÚ4µTô§{½Å©Þ袆bËN@ãɵ5Ù0¶™¿QåZj9Ȫu]®“)y—Y2¼Ý ë§ñCïÞ…o~˶˜7Ëvï=žyfî¿ïËxôᯠß óÑ ¯kùåUíí“ÝgVÒËT‡0Ç_~;ì‡Ã/8ˆ¼„n·‹½×^nºW\±3íåÞ”7\9Äõ{€§tðu17çD±3Ð:Ie©ªv£ÞU±C­ƒWð³OyVó!@zÅDTû¸¢Õ³èÐsPFG&kÝ•yðVð_jÝN t?Cq9Õzžpúô,>ûÙ/Âû€³gÏ®"ØëðÖÿÆ]Ͻ ìq#¨wÃø¹¿nÀCb‘1¢Ð'Pë -œIëÀ¹ï|Û¥xÏ?½ë×u QŸ¯½v÷}é~|ùþqòä)¤›Ùµ‚{Ì'±fê[¿ìb§ÆÍqnç²dr•ß{óÜ `8,ñôSÏâé§öaff×ݰ7Üp6oÙÌË\À5nºzˆ«vqßãSxòù")t {ÔOh«ù„õâ­²§áEãTÙ«5“,›K\Ñ*Q3¤H|‚x{c§åüרsÑ LØŸûÊ‚§ápˆ“'O·tÓyaŠ||úB`7·e Øc V vr²ˆ‚]U‹¶6-@¦_–¨–Àj۬ă2ݨM°N@Ç,—æsÈ#oïš=ð/ÿùìÝ3y¼ö¸´ÙÙY-t1ߦ¥ßTû=zÙñkŽ›ê^zs[9ÄÓz9À©‘Ì’éÞ1HŠÿð0<ôyè+Ø~É6\wýµ¸öº½X³fš—Ybá;ÝÞq×n¸ÒáóLãÈ nØ*“/OÅo,@Ò!¿KQì%Ÿš×ÊUðX%æõ;*à]¼æb¦à˜ìºîB`'$?`ýõûkIþzìãÅuà\—^º>Ž?Íð z¥h—á")y×Û.Me?³n ïùÞÝøö·o7ç¾t°¿øâKøøÇ>¯<ú¸‰pi·\Ú€Þ¶jKƒørW¨ŽÞf›‚Ï5hôÛÕ;Á*ûñ çåŽ9Ž£GŽá¾|W^µwÜu;¶oß¶$»L—ݱ¥Â÷ËY£š¦JW”𤊼nѰ:§@¼è½#Y4>]ýÝ%ùð”"g Ý|03SS=üÔOýK|þ àþû¿‚r8®±Ò×›Z×}µ+בÝŒòÝÛ'óú¹Ì^‰´V°·ŒÜÎóÓ²:8svþä´vV?½v©8u:øEs^tºØ½g7È8yêiT¬‹N—\r à §gç’â§n‹ZïàoÙùg»°af²~_ô³mÞóÏíÇÇ>úq|õ‰'SÞd*}ÐÛ`Ýs;g!•Þ†äåx¨Ò½œ~YXÛåšÐÏ5ª…}Ó’i}ÞÞÓû€û_Âý/b×î+pç]·cÇ¥—,ùzoºzWïà¾'¦±ïÅ@Ý(‡CTÕ ©uâˆçÉX4|¯ˆ=Ú4€;¤r•8(L”cTÅK¥hå ~å)€:¨<%U.êÝ]ìܵ ³gÎãì¹CðÄžéd`¿òŠ øWï¹7\3³$…gç=ùÕ§ð7ýöí{6žWÊ£I€ÞìQB¾|}­¶´I¦¶b =¾½¹Í\óšü]¡kš…wöV©Û ôé7ÿzùà«xùà+¸ìòKqû·bçÎËyý%¼M÷*|ó]çpÞîûê nºå<»ï9¼öê!TÕ@T<ÃÛë[©ªpr€W…L鱋a’úi”»ãJW®TÕÜ"°ç.«"à%,r$à“‚÷ÞãàÁ×á½i)›ùïÍk·rÓj" O÷Q Õ´¤È/N°Oº¯zæ3ÍØYêD`O±¼Y¨cH`oöSk”Tk)ZVÄQ-…F¿ð`äºðÞá‰'žÈÁ#Y2 õN§‹ÿáÝ{ð®wK»÷_yô1|죟À‹/¼ˆõ6(וø8%?ômÛ@Ë2í°n[nÜ4Y|{Ú¦ wäÿ›ÐeÉ4•½}°‚¢iݤ­¥mq ý§°}û6ÜvÇ-Øsåî%ûñ—n⟾ýž:ðE=:Åm'\I€”¢Ü%èǯ¡’Þ}I“>Œ±h$ðšG!—– õk¹€¿¸ ®S˪ͩ]­úÍ´Õ…÷¸´Eƒ]Òƒ(ìˆ_^Tì0`—h§>»ªyµM$’…’w®žºs ûNTæZiZûó6Ræ’mëðÓï½.«0],ؽ÷øòâo>ö ¼úÊk±nÀ‚xœJçûD®}lÇ©óñÑ1M/ýQËM2YEÞœßîÈ¿ÒïºßôØy¹\Õçe¿›…™m=z÷©¿ÇæÍ›pë·àª«ö@Ç X̵'¼éê³Ø¾yŸ}pgΉÿ.êÝCÔº©luâ•éÛ݃ kê[³ÇãÈ&/oÉ>å(‹íº‚Æ{ð:¥|úÆ1êÊi¾#“Nmê\}ÖZfÃ.ÛvE¨ñ[ú…Mõ­ç×y6¾Sío ü6Øóg{…j0ÛoZ2©ØiBþäÉÓøÜg¿€G7~wßs'ví¾‚÷´Hnû¦!ÞýM§ðùÇÖã¥×z|ìäàb¸$à„ÑVµ;8 òAZm«jI…+¸’Õ{%Ÿ—«m PÀÝ:I¿í>Y4$ú;4|ãb/Ótñ‚:ã Ø C#Ò†þê«u¨%m°ÃÜ@ìê;·ê`W{¥nä0ÇÖèºHaŽñÒáù&j†·ÑE§ÛÁ|ÿUx×·ìXôë¸~9rö§Äã=!¹‘Û/M¨çÀ®[3móòœÎÁŸ…›¶._¿†ùRíÓÒ•{Û6Ú[ ¶A¿©¶ÓúyœÈBöKÛ¼äÍ#þ¶ßgOŸÅgÿîsعërÜ{ïݘY?³h?¾× xç]§ðÔ–ux𩵨ªRT¹DÉP)°WµnòŠÎóð³ÀË&›ÆFДMÀðÀ#ðìûwº÷Ü}+ÞñÍ߀ßüÿ óóóò|ªð8‚§®àÛ”zš×étÐívPU†Ã2æÅøi5¡¾ô7 [¨š×Ç‘ úâ±h{ãÜôA}:"³.ñü ÖŠ¶0ÕþAÆ=„þz¾˜+vg Ϫž­«ØwlŸÁO¿÷ZìݳnI`‡øÄÇ?‰¿ùè'0Ho€1¿‚zS¹;r¨GCß^p>¼fm§ð›EÀÂSwû#ÔÞ•Yè×Uz;ìÛA?n™våÞyžûêˇðá×þ7ßzÞtóMpΤ“Ý'7^yÛ7ðoÀ™sݦMÌó½Æ¿›üa˜‹]}xó `$à£E<ª*àÀ ùøb 8ÒFÅÚ(¶Î'…Ãöí[píµWâèÑxá…—¹§×±Ój½~Ï-~ZôÙ£Â#/NfØ›Ú0)˜âòâØ;Ïk; NÛ–¤ÒЈR¸b²hÀ¡ö :pE×(vNû†;Õ†)–ö¯>ñ$þß?ùs¼þú‘ì|Û î´.aÔ-|yèâg¨ýnYHj>)§vˆ·«úQó&™êÛòªì´Ì¤–LªPú¨KŽRóz.y^¶ª<{ô«xaÿ‹¸çÞ»pée;x‹¸O¶nèã]o;†/=± /›$@R²g¼ÌC?Ÿ£3YIé»>È÷ ðæ=%øx#GNâØ±“¨ÊJWÊŸXКø…ì™N§ƒ={vâ]ïz'zè :t$v}Ò>­&Ø—uðÜ/°/ê#Ò`·)Øå2}ÅD¯=‚+Kë`Oý¤KŸ.Ñ#7 ‘ˆaíüÔ•ß ð)¦‹N·‹ý«ñÝß|‰œ×ä`÷ÞãÔÉSøó?ÿK<øÀC°0O•Áˆ¡œã”z]M7m›—ò€Ôb;àÄciªù´Lc±Ë,fjSñVç¿5½ÙÏLö|ÞB™F«ùI o „îÓü3Ÿþì¾rîºûvLMMÅJW`<àCèu¾éöãxfóz<ôÌ:T•_²r÷y…j‚¼W°š¼RßÈ#h2ÀW\Ê­ @ðÜ8‰¯ '¾8ÀW•Ç‘#Çqß}`ÿþ—0?ßöÕ‚úòîkL U¹©L~¥4diùzòí {Û:éqHidò3ùìÜ( H!N¥8/½ÈÀžBÇ€]•yfÉt ØMå)uqé%ëð3ï½Wïnv0èJówŸþ;|ø¯?&¯N naMéüÌ_;ÔRñÔø_o ÒB2Þ?-Ëf×"aeÆÍ[Êd÷ÒöLŠ…¾]v4ìGY2i/“Y2íRNÉvC:Þƒ/¾‚C¯›n¹ ×]¿7~èëó®ß=‹m›æñ…¯lÆ™s]ã·óq9hx¤3¿›j9ªv ß©eq5¢’55jRàƒŠØ? ‚á¹aL^FÀ›ªª ¯¼ò:Ž?)C2¶ °½šj}y§Etù»PZ^äóÓ:“§M¶îÄ`WÆ´‚=)s íâ…u¾¾CŠ®ä‰Š=Ư;ؘurÔöNTí nyÑááî\š¯ ß{Õ&üÂûnĆ™É|°ÇŽÇú½àÀó/ cÔ2I:3\ã¡Nˆ}ÔCýö”Ñí•®ú;!¨®ä‘-­J>-K5§åPîùv&‹q×õ땮㔺µ\B¶ŒUàiùñç{´.5[s>úðc8øÒËxË[ïźukƒJ [Ö÷ñ÷Åß?²ÇOu“bgOMêLS¾Äžkù™¾0ê]ögôV½pòü ò½ç‘Þ¬Q¼Îk¼á{!»Ø,…jǼ¢ÓÊìgÁPÈ4¥z”/ÿÆ«uM«eV¸¨!³žƒ]Ö V½õž†ÅK½:ÆÖ§ö»4˜í÷hsn]…Û_£îó ‹qoóØíüz…hÚcÈÖË•½‚ðô"Ç !p>xQöÞ ¬Võ­“ˆ@Ž·yòÄ)|æSŸÃw߆W\nêB¾ÿnß{ SÝ ïß áˆ:Ѓù­ç(“‚ Ò¿|¡ú¡ÖR!@[jÿ‰03Ý,Î_-µ¾ºûj{ÚQ}Ê´¯—H;ÍÍÍáçþWpîÜÜ ‚½öðRRòÙÑÆ µRÐ@J?bO)RFo$Ûu/tä$g[›¦FJ6Œ± öž¨õ¤Þ;.þõïÅ;ߺ}¢K?ýþìÏþÿ™à\ñ€º‡àáE¹#ˆŽ`z8÷(\Jž5ç:ð!À‘Io–0vMŒ´Lžè#“Þ~Ò%Ké‚ …¹eC™z²~{ºŠ$×ÈæAó7ј_mÛ[jŒ»ôhåžàe+X-øSjŒG½¼^_Ï€¯|% —e DIT»sb-þˆ0 ñÀ}áªköà¶Ûos ×ñèç »O`ªWâág¶Æ>Ä©ô¶«$ó}ˆN]?È3Ôyf• ϧ!’üÛT°êÕ‹€íBÔ2¿uÁe˜V³áiý¹+ùWî»·CÝxvö\ËîWìvÄs »~ó©U=t}ÄäÝQ+Q²ÁÀÏÀN]Vêdû…±¡ŽÝا§{øé÷^{nÝ<1ØCxýõÃøÝßù}¼|ðåvõ^«ª‚5‚Gð²±[Î9x/vŒ¨n8ÌÓjSíÌFÛ¸˜»’×Q‘QèVÕÚFNu%›@Ÿ,›¶©f©°‡ëɦt¶¡eÕ~kúBaõ‚`<èÇ[2 v¾¼A 퀪*QyþówïU½ç`g¸3Ô]ïÚ98Ç{|aÿAœVúh!Èø­i¡à:2–+@¤y¤ýÇ$;F눒HOI„Ò^ïÌú[Y\°eÞ…L«v`QÑ2mÓÂ`_jÚ’l˜¨zxj}¿P‰ïÁNr¶lÞ„“§ÎHáÀCáå㙚°ÇÚH©BÕ!6HB“B ìÖOãç~â¦Øÿ:çÂ`îÙçñþßúœ;{žÏË‹÷êù¯òžöÊse–ÏÍÀÃyµ`P+zâ¨Þ»ön+X%c1j옸£´z°ýæ›ÆJIµë{Nd ä:àÛê~LzÛ}0f©I+T­ÒN œÌ6, Ói¹Q¡m•©&ø›/%‚÷ð¾Då+¼@Þ‡Š­™`}j)p‰ tç\51<8}ê >÷÷_ĽÿälÙÒ.6Ú>/Ýro»eˆ/=yúý:àõ{;˜™=ã¥^À•ò[³_†Dà<û”ò V²ú!íÇ’¶ðÈåŸÞ°µpõióiP/ ÞãÒv½2l7¤òÚîKôO½§Gv ÀæMð‹¿ôSظq#+ò%#‘0±Ï˜|pkm‰ ­˜"‚=…Bv¤µ‹µk§ðKÿË›vxôÑÇðk¿ú›ìŠUt¥÷ðU…ª’Wõ²Dé+„°ÞO£ôÞëk¼7p¨à+öoƒç"ÜHKÏßqA訾æ neKÉŸw²¬‹ùãàPÀAç™z ýG‰ÄÛæ¹2æ¬È¹¬.@*»)ZEmóSûW_fôúFZÆåì:ºM2é”í7_–jÛ‘{²¶½|€v¥@ð! xÊW(+ª,1,‡VC”æt9àöÂ{BU•(å—æ»ÞÁ{Þ®0`0(ñ¥/<€×n½ÿFÝ«[7Ìám7¿Š^Ï\ÏÜûÝÚwµ.»æSR Nˆß5X!F¥Õ¿«Eh¾SzÞã+Y.†4|¡PÖ}®ÆÔ¾Ÿûso·a’«-ÝXoòô¥*öz5þÏú¡|;\ò³ª9yê ~ñgΞGðâ£8¥FKÒ÷zÖçKý»í½ Û‡Œ‚½7ÕÅÏþ›qM­ó/ýõ }þs_Äù£?FYú\˜ø€ªâ‡>T%Jïª Uðp´7þoX7óß§| C ÌâÌéAÿ“ð¾‚sU¨P„Š_ÛM®*”Ìõ'«Â¤ÄÅ/—¼æ·aVS$~0Dä뻀^/£°‚U[IÅ×ï"7â÷€Ùå­ñ’Ï_È’iV¨³f®Þ›Š~œZ×ïÜC¢’7VœŠr/Õ–©Jx_¢Ó»Ö¿Ók¾ \8”(‡/¢,ŸÅ¹s‚aÿ H=(òT ÄoWªò«ÊãÁÁ­·ßŒ]»w.vý¾if÷Þx÷=y9ʲW» Aì»zåj¾L¦Þµ¢5½¦0½H¤VTæ¿hŸ£ g>.zf©Ó§Öí4v€ìqóÛá¼t‹fi6Lm›-‡œ±Á–¦VCY³ç9‘xlHrê\ ±?˜8À5ÙA«­:/$F~‹¢/Š~òǮí7lXØ?öÑãCùW`E¢-CùµÖ‹„>À{ˆÖ¬ùAlÜü³pnSÌ"Hï“[±yÛoáü¹·áüìÿï WÀû ÁuäPÏ]€eúzöJ­ƒ0›å!pC%¼6n"1^å‡sUœ Õ*ÏtÙz¬öø©yÃ4CcýÎK6-™úü¶È4æåë5C}ˆEòÚ£r+¦ª@Åuزí×ÐíÝR;þ:ݽèt÷bjúÛpêÄûПÿ˜lÓƒà¹Qš„¢H…s=úæçç±÷Ú«'¾W·o<‡;¯;Œ‡ž¹T#Ó%Î=H”#/›ùò!ÀSôÏIr ° Òk õGŽC|á¡•úY'‚)Èô/¿âq^ƒï zz Î9œ??gÖYIY6úøFzîZøM–¶0¼Ç¥-M­·½9$åc؈ Ó&õô¨¯kjéqRþú—:³-R‹†ZgÝô!C~E5ý‹¼o»{ë¢<ö?ûÓâÓŸúL:f½¸Äƒ*ïî¼ظéßcíÌ{ø´´\3Ÿú}ÝÌ÷cÍš;qêÄ¿p4å3‡MF¯ IDATyh” ¢ÍBMá ë´R+ÄüÔXô/ LާŽ/°ƒ‹{zSt vÁ¶<Ô–±zÅó›4o,§÷Ĩ©íæ²ú1W í1îºöí1ÈæÕ•{®ÖSè#óL®q¸^¥Êþ*lÙöëèöns¾Q›·þNX‡ù¹¿ˆ#P*ïA^°Å盢fÛ÷ôsè÷û¸éM7L$BBعõ4úWxüÀ6ñýÃpy^C¨›*U£rgÈÀu¸ÎHàN¶‚•îInâÊþ»(HB0Då—ÙËÑšêáÇüqâÄ)|èCŸÀpXŽÍûå›&{Ëh ;‡·¹ñFB}T…ÖJ½%-^t; ¼Á•£!Ôã×㬥¾V–*Ô ukÅ †<æ¡êµ§JV±a Øà»wã{jlègÛ¼²,ñøCžD¿ßÇ­·Ýœ¢ã>¯ºô8æž}e3 æˆGiI‹®Ø4)¬ÂŽùà¸KnŤ„ ³çœGŠêc©¶÷ÿ¾´ÊÕÁ`ˆ?ýÓ¿Æüüà¢;pA]þæiÍõ06mi6Œ¦×Dó³­•j|`ä£Á@z¥bF*¿‚¨x°Ç•L´LTî¨uêØ†Aj‰j»ï}çÛ.ý{×Ä`ŸŸŸÇo¿ÿwñÔ“Ï 5"Ê#T‚çÆê¨JwÝúëe¼j×ïDÀš™ïÁÜùßNéòçˆ-ªB*v,¸6`fæŸgà–¬h…ºNE± SÓï@5ø¼>?"GéRH>:±f ÔªúìÅkBÜØ„Q½Õ¯©? eã#døCOT›Ñ“(ÄåÔ!»ÿrUW+’%l½V,i€´¦Ýê(Ø·Y2ik0çžvÆÖ Žó%hά>¬[ÿ^­Áb§^ïžX°Â|r^ æµÁ¸ã±/ßÿ0îºçvt»Ý±`×ï·ìyƒá¼~b {ë¬Þ#èùÓ‚wЦ¦M#‡jË…„ÙJ'T,Øà£BaOù‰è‰NdÏÔ'åßj}ñûá*‹l½t…ã…ÏÒ0"­™Þ–vá`§< Dâ“KÙ"|¬ò š0Ú0Ño—JJHÅ)@B´h’Zò1M³ÆKµ•ÈupÃÞÍø™÷^m!°üÖoþvv - !E®p0|#¤˜^ûpź àl½¤OýnÓœÖÎ|œ#P!aeêµ ä ©.¨@AbÓ¸…+Ð)¸™c©ÕšbÇe£RqAá o‰#y¬!“1ÌPÓêáƒRBô¤µ ¾^÷T±‘Oþ»’ž^ìŽt÷³åE)ïcX¥¿™Žµ=ôÑÕ¶‘Â&›¡”§EUÊ÷¸¾åx¹¹‹îõm΂Sѹ®ØÀ܃àÌÔ}iÁòœ?gOŸÅ£?Σ"Õîݶûš(àö«_–õý-f{w.vbï©”>9Ú̉%ê²?Ûy_|ë¦t¼PQ“BÒR¡Nfv>шï+=-}_náEtZÜã „0¦0•–ö9>­íäM¥‹›.+Žñ#‚íΗœUì¦u*YO=)øX©£eXµïÞ¹?ÿ7¢ÛÉKûQ`÷Þã÷þÏßÇóÏ€} ,àcì¸FóÈ™óx™GãÁ^º…}¯w5ȱÇî¤ðsDðÃ\ãþå %Æ® ”+P…ÆÀKÌ2j)ˆAŸµ!pðŽc·Ê0×3HL>*xÏá€U5Då9Þ»ª(«JÏŸü›Ó«j× ¡Š±ýñAª§-¸ëð®Ã¾¾|¾l=~Þ¦†¼6!$…øÍ¥(¶·= MÝÞÝñùJʽy mŸ§NÎâ±Ç¾û7Zè¾.œÇ]×¾€õëÊïžÚØ.;Òó“æ§û-Ú¢vúØÝ¶ÉK z=îȃtµO£ÒV ì ßÂÓ„-TÓûl; Ç¥-‡Z׉ò4óŠÓ¤„Ö¾cŠ/Î oó°@íó Áúê©áL'ª qHƒ›F¤´VY7_øÉ±n éýÀþþ_yô X g9±dT©«êåŠÙFéGAba.ÙÐj×èg õ¶Ž9®HuN o†”É dUY’\#îo†Ãß‚ù+ jÛ¤u‰G–.lÇ|uâ$s¢EJñ¡+ÓBÓÃsçiFœèCî ù–êPœãÆVÚ2÷Á¢y“|Ýt×évåÜ[-ŠçÐ\f\|;™}¥œÐBGOn#–:ºæ»æNz>RŽsFéóØ‘xú©}¸ñ&~{X(‚¦[T¸kï|é©kÑt§Þ{9μ“Ö¦úêMyLƒüÇ(ý½ËÍÇ~»v<æÐÖzµ=“Ÿ«ÁÉV`]”ÓÄ]þ†xƒ×ÓW ìµ´øšÕ¾ž¦ð².»¡»žÑW¾dbÔY5õÐÕ¢©õÞ»‹¶Ìû~ìZlÛÜ•cYìú¯…Ïî‹ˆŠŽÒ§£"žÒ†ÛC{ûƒ|g2u®Ó8Чß3b«88zá8ÏT±;=žø¤È™ØCUäÙà·^«px¼é7o³Ò-qÒ bÐpÀ!ªPšV·©-ï«Ü­ ÿ\"t(È…,-ù®§UïÜÌbÏ:Ô£¼÷udéye*ø-R—4}%i~êÍîÜ,uòጹ£ìÑç¿ô¼Y†?_{åuôz=\}Í•cÁ®ŸkzÜ|å+xäùÝÐ8{„nŠ  êDpZÔè$@@ˆ•«ˆ÷Œ 伬øªèkYôL0ç×6Õ—_iù %ö-cnìeƒú$éÍ´”íªwìkäâ¨wÌó³×6¤JTDŮД»óeeÇ}´'‹F<@ØÑ•XÁ;é¾÷{¿ý Üsë&9î…ÁþéOûÈǤºêŸ)„“R§MP+ Îf`¯ƒ~¼z/Pë@® Ô j±È§úýÑ÷OÅNDŸ¼]P´R´Háä>x®˜ÀÏñA`o¹@/­4+¹|¨Ø~ %ªjÀ6K­­ ÝßúXÂèbàî 8ê px×EáÓ”U©H{ñÀAt»]\±«½«êúçö 'qÕŽ¼px‹(õ Ã‘4΃‚\'æÏê›X„IÃ9ÁÁ!Â×ÓNåB¬ o•Ù ¬zr!*G×”O+¥Þ—¿YÜß(µnN>ªv{,‰R$<@£Jìk¦ö‚TTÙV¨õqQ£§N2vìltŒ;¨ƒë®Þ„þ¾]rl ƒýÄŸýÉäþ«‚=Öh…*œÜ°‰â(À „ùÎ6*LÛlû&¦óÀ@8e¼uªŸˆÇš*ÝAÎÊ‹òA†NK ä¸5,?œÎ1à_4†9<<*hÜ|ðì­W¡ä~T|¥FÀ+ôS¿æ]ï—T`qý@GàÞEá*t\ïzüpèó/•¹$쎨-Ðëøß&ç'Èë\Ó@Ç>ú†JK·d…;R¾è[lzoÉ`Îi¾xÖÜÏ?»Ýn—ìhï²Z?õûÞË^ÆÉsëpêLOïœ&X¥“èlÙH˜Vô$Á! D<Û/¡DYÍ£ô÷²Ï•¤a•{À4Š©7£(v€Ší ÚïO#TGá«×Qöa䇬Ú} ïJ„¢’kã7… p$coÑ^ÒÓ“ OX®[2MŸ-éÖ&P˜Ûá¥å^Ðç!\˜%ÞŸÕï³øYÄcÒ½·¿«àƒÇ3O=‹N·ƒÍ›7{¨Þ²{?îöF †: ñàEDIû§Ê]=zégAZ­z~~h [i¥) ÅžÔÇÅbÔr#̯ؓEF÷åTï+v`â1T ï&ð—î Y·ýt‘R™¬VœÕ:¿‰i—õx9 uÌ,W‹‰µô¦‡;tñ¾½—líMö—^<ˆßþ­ßEYV¨WžjSÿ±Ã!Tså@…ƒ û"8øÐ®ÜG©x ÿtn=ƒsQ¡Çè-Èä8â}¡y, b…X¨@òÈ{Çj˜…µ‹| :ç‡V’Vð¡Ä°êcPöQú†Õ|Tí¥÷è¬ù6L¯ýtz÷”* ÷Rb؃óŸÄpîSð”¼z_ȈF?$b‹ ƃ‡äK¦ÔõNkW47šj=¯hÍÃ,ëL¹ÊTþL*ØUýÄB[`˜½—¨8jzï‚÷O>þ n»ófÌ̬[ð˜îõqÓ®—ðø WÁ;õÚ}út>A_Û1 ô@^žC€U¹‚çðe8áu@ê¦Lžs»°Q¹jÁ½œ¯O+uîMÅž¦\­·)ù«4g‚9€zAZ;kÇ$¾;¹¶)ÜN»˜™¸Ùø©ÃäÙ–¨ŽU¾3Ý € ¼ë[wâÍ·mšìgΜÁûë·1?ß`OÞº 3`×A3+N y5 ÎÁ¶JõA4ÕªÖGAà´Nwª¡±cÔ{'’ UB¬Ë€ª 5¾(,È5Ô•¸Ïn¹RŽ‚+@> ƒ'rŽm©;p•C ŸâÏe899ÿ «y «>ªª7ýVÌlø·(:×´Þ_YtPÝé·¡;ý6TÃÃÜìï`8ÿRˆ.Ï¡ˆs±€Cà–µÆ9ƒm úfe*⼤ÓS¡²4ž_iï2µ‰äZ-]¹‡Ð0ЂªøºçžÃ4G‰¯Kÿ]W ñúÑ¡6=·dR »lL}zî.D¹{ñÛÓÛ¡…zÂ|HWÓ¾îÅëùóÔï±ï™çð¦›o vý¼æÒ—púü:œ>Û“ûăÐMè³£W|I¿“¾Ô‹ÕΕßü›+Wµâ• Í‰ÅÍîÙ$ý…L«v`d#&}e„¨®fZsþBiš¾˜4ª¥åJ"vZ['Ä‚˜ Ýú‚(ÞÄYA-i?1í$L#fòK¦wü™™5ø™ÿŸº7¶%9ë_fUsï}ï¾¥wµÔRKj­ ±  ³X`Äb0c ˆqãbb<ÇØÇÃÌ{Â3Û`†€äÁ ÏØµ$I„Ä*ÑR/j©[êî×ýöûî½çœªÌœ?¾ïË¥NÕ9çÞûºù⾪SYKVVæ/ùË/¿üÛ÷ÁêrkØÊýo'>ü¡¤Ó¾ÎÎÿt¨Ä“Ae Œ˜g™}¤‹cXkã2j„½Ñ Kclj³§² RÜû1b_Ÿf’Jþ©\DjM£«ýØ”î¼2"=ÉAÌÖ^RoE”‘K:8¿@çæ¼ -v±sëO¢Ù.},,Ëeh¶¿;·þp8#“žæñyjヺW.µêXžâ7Lãù±åø<Î÷,ì@¹@'as¾¤´)©Ð÷1 ,cÛ+—®âÓ?ÁÏZðW=ÿ!Ô5¥r1w$«oz,öÀÕ49ðÏŒ# Sg”ïGù·[Ê!I[Ìí^üQ€zìÏ^÷õMÓñ€û8 BÙȤ M¨êëH`›”Eà•ÑÉ;•ú:šfû±p%`/f¢ŠuÌ|ÏKpÛ-¤u5°?òÈ'ð¶_ýP`¼v°…£öåjÝcˆÍ­Î5<ûÓ.ø!ìð!÷¹\cíi®ÂF­‹’ÕŒÍVY²€[ä$w±ä¥“¡â¬ZéYi¬ôúÔÈYiLäKˤ$˜µ»Ð¢ó _áÔ­?Šªy5ñ êÎ&L¾j>;·þx_1ÀûÚhjÉvõQ*€  \‚b’sÈÓ±eï7ËàÉd%õ NîÌÜËÆ§Xk©á::ÀêÑÇqýúžäýx!`ZÏðòç}¢œ©š«|ö*ŠU›Ò$´ä‚@ $¢õ¤kfco™9Ž$àNÊϨ/7#Ì} hŸ©e4.¥ƒ™¸BörcÐÏ:ž½˜˜(ò°ß˜¾é£MÒŒjïâá1Úµ#÷ð˜ü`¾ò wâõŸ—ìÙWâýý}üäOü4œóqRRªIoO&”d"d¨>[ÔŠEqdÇ„4¨š[ÃäÀ>6èjìé˜oqAP¬F+;’ý8£» ¯yžþlV)I*ºNY‘Ž›>2À²™ãôüÿ[ßÓ<úÇ7iÀÖ/ÃôüÿÌ bDÖÞÂû6kl8Z¶J`6ñ{޳õ>¨—€ Pæ¹2KxPÌ d™à¯1ϳm¬ Ë`]î£wNÿîy=øç m[~æ°ëþ­§/ᎳWbýJ‹ÞTÈç>Š´ü(°ë~ªßÐò{&)¯‘»¾ÓP‰Ç– кõ\ûr÷1fàL<· /:d.»d-lšÉ'-0!‚ ¤ÛɳT“ã¡äRœ…¦™w]ϱWÀv¶|ï·%{öuÝÏŸýéŸÃ¥‹—õ I†b—QQVÉkÏõw MıÑ!}{K@®@Éâs çsvDj‘ì“/4Ç$?4Y·¹ÏÊÞ3mùÚ$é ¥¥TÙ|p ì¡CË3Õö[ÐlÅRÉÙ¼7 õÖ›Pm³,B­½v8¦–@BÉÖ±ù>È/³u¾k&)Yu ‘½Œ¹§qªôüul|äó4çq|d>_à‘‡] ìº}ñí¢ª(x›}Yÿâš ¦Wöúu\ÇbOB:²ô*¦ìñ=Ž–™ô³ÆŸ1ÊÜ9¬àñën¢ #%›ÒBñºd¹\àâ,#«äAÔ4QGlØ‘ëë¹ù£2vŽÿÎo~!ÎîÖû;ßñø“?ùr@ã´d ÙöB²POФ€ÎŒ‘4eqä…ýAV¤ý!ˆ, ?¢µ _+`Pv.¿”ÀO’®4å?5N9k̳°ý2xÊ;Ï6åÕjLvÿV*+˜ûIÃd÷ûàC-¬]f¿ª[ƒ¸~TÄ3ÜîM%d Ê}‚uá&1w¤o±`áýßë¿ß\¾tO>qa-°@mçxÑmg€žê] ôÙbÚ‘É+›É@¹L3’Ö#±÷u9û\€úúçDp?š 3vͺë6‹+'- ‚7<=ùßÎ',T†QÖ><Ø’ºsbI“­´ÔÐQ‰æÞìâë¾ò¶€ýÑG?‰_ý•·A=V*5D­9H›Î§ä° H–ª¿[+Ú»µ0V©K >ö[CŠ?ŸË+ä2!sd@YÞªÆnÈdßEÞMÏ(è³í|  :*NÀ|‡úô·ÁØó1½yÚ7 GiŒ½õ©ÿ‚{¾ô]¹HPŠ¡€~I&“ â1 ìJˆBr˜fì훿L/„p Iþ[–ˆ–¥™u¿Ë´÷?öÉOcÿÆþFõåγŸÁ©é|ЫԻŽcaRÇs™/“]uFrÑ€›½÷ ì?[a³g¬dîϾ5̺¸ à¿NˆÛÄäðgŠ6©ÒÑrC´r F',)3Ï Vÿ¸±ç»îÑxÕíÁþ~ò'~]ç,cJ†Ôg¾–د<ƒ EÆ®LÞ’i-»Éeë¹æ,{§ñºµõݱRÄʨæa”ËÒÛHÓÆ§?¨ª Yš? ¨ç ÉIZÁ(¦É#ÀEßlÝJ€>®Î>š·¤ÉMA\K%Hã>Ç“d–ãd/3‚:_ 0¶~ñ±ß+ˆ,£é4Ùþ:†>¼Í§eàxèÁGÑu¼$ݪzCxɃ¨«€> ®¦Öb`5ûË߯ø[ÉÞCyl©LÑÐÁc-´›?£9c…ö~sdÊâr¿¼ÕéÃ:]„ÙÒGÊ?jPpÉeöü˜{&Íd#ô€0Ù’±øª/½/»wg-°‡ðK¿øïðÌÓ‘b.O$=ÐÌL õöT™˜ˆZÙS‰)$¾÷Ïìü(òŒ1Mb…rNë:$¤Êœ±óØÉûjúõx€É·ä1”UX5Õ `ëÄ´çáÙ’gLuÈÞýíEWŠ!”Ì<Þ¸$3nú(Ç…© ê!‚¼µÏÑäØïåº'³ï¤ù(6¾}ðëbà9¬Š'Ìg |êÑÇ7ª7§&WqÇ™§‘ü¸÷MMv“[½é¾¾¾£²óc°÷üIáæ»1;;Û¸ãŽ[±³³Ådç˜ÏÈÀýf³îÍãÆpõpz%ñ=R\“³vþâàRœü± ¤€c,„ÈÌ£½{úCak[áôÎßý-Ïߨ€~ücâý¿÷IIYHt°Wuv«…X-clZô‚ÈÀV†W@VÕ¼­jßr?ï€=ds–·D€©_?Ž·Ó]¼MÁúLÔß5ÿX$ÙF+£1å k2Í]ÿr¹¨&_\¤5Oo^Žn6ÈWÓ/áFFó"{fˆï?¤¥—@7òšGòì•öäù&¦¾ïDïÔudž™™»”;I£YJ3ƒy‡âø¥‹W°wýÆÊz£û÷œµEÁÜ“d²wW‰¦˜‹Bª=ªîžýõ¾K‘~º³Wdï7· 5M—¿üÅø¦oúj¼ò•/AÓ4Ç~†É™Ç˜¾þœÊ0èw§ÀØÒæ~9øw•ø¶9€°ù#\u1 ¹S0>ö]ßrNíXIëxuÎáÿú…· ô­DЍjרV ò•µ¨L…ºªPWM4w¬*›1v k¹P[+1þ)ðôrÉ éîù9uý‚ø b6Ʋ •A¥•l›U †¾g¬P¦Ðãù ™øþjê—¾¯hÌõÝÅ;ŒiîKï'¬ƒ¦z422õ]-ÈDsO ¾ Ü«Ùú° Ò—d¸ ± ¨ê—û}B˜Ãw²„#%`OÚ»Z2åéê û©O~zT{Ï÷+Ûâž[íYˤõ¸¾æë+d¤Lëld퉽'íV²÷$ô_¿ÑÍ DÀdÒàìÙ]L§Ó•ÛøsÏÅRÜjP¿nÌAÿê^&“:4+YG뀩~L›>dl´@ˆ;‰ ´Ë§'*¼ôE§ñ5_v«¼Ãjæ~ÿÛ߉'Ÿx2°Òôí¿!³LÉ¢®ØÇ¸­*Dí:“©H3®ð`€wž,,±Ó¥à‡m^Räã˜ÎÞ¦zA~bD3H†ì'Ëõ¸¯%ůQÊ€¢Ú`HìÙ òÀÅ{ë;Æ»Ú[ŠôÊ oƒÌ=ÿ½ª\mÈÞ  6rʱË<bÝÈR_ºÈãJgc©1'WÒ‚ðŒX_¼=swí# xöD±@ëóï¨ÈÉqþÍ®~Óo9¯<³ÃžzòiÜy×í£À®ÛÛO? ×îÂÞá,¢31ò¦©É ® ÈG/©l 'ì]ÜçnK9mù›jB5õYÄC&‹Ëß<Ìç->úчñÄpíÚ‹öØ÷izn#OætÈ0ùqQÙÁ IDATéÑ@iwHØì¤ÛŒEÊÇ(ºû$6íÐÖ>1y.ùÔga2¢{ßwÞ+À±Ø/]ºÞˆ`žÉ B¾²’ö2¢S1¨×MƒÉd‚éd‚¦nPOÔuµuC•­2iÃÄ8s-1󜵧ü\Uõ‚DXBpñ"eó¼fBõ\Y0$dc QgOL11GiÄ(gFz¶âjœB(÷É™»½e€\ô™º6àCl}ŒÉç×ÉÑ4mž4ñÄÌýøàÞµE2‘›ä$dI²è“”GÛ×{<õÄӘϹg¹Ú‚ÆãÞ[?¾ÄÒûÌ=ö²GÙ{†yÙ\ÒÞ¥™V&_”¼ùÎwnNðÞãÚµ=<öØ“¸~}Îùcßk€¹‡e»^ŽkšçÏŸƒÝ|Þo…òÆ`8—–Íõ¼€RåÏãH¯ËäeïÑ\m‰µËD˜âxÔÛÉ૾ìN¼äží´öÿû­¿Œù|Ñ« ™ÙcÖíUYFM­eÖÞÔ šf‚ªªae`Å{fsÞóÂ!xx`c3Ð:Ç6ð°ð—«$˜~ ¨ºD§Â"2FŸ£©Œ”½#qÞ2©É!d_™¨ˆ0yP0 xùFHOïGÓ›—Û“2õ~þ {O@ža+¹cl½ŒK=£œ+âLTiXCdîD»'²”麇"˜² gÒÆ'‚œ‰½‰ä:LÃ8;ßä¸÷Ÿ~ü Üûâ{ÖÖ©íæn?ó4ž¾z+1c™ÅS%Þ!™€!xaïn€½)„ÊÞ=TR+Ù;äQzŒTöä#åq}Vz’Â'95¿ã‡ E£Ä®Çâ€eÆ~öì.¾á¾ ßø_ƒsç΂ 4YÑÐ9×qEå’¹± B±‹5N"è2yù ) !ZÊ,Ƨ٩ÖÔø_·ÙbþПáÿèOK¦0¢³'‹¶O¯«šõu[£ij4M·“ÉÓi#ÇLšuÕ ®Å¯Œ0xk“÷îÓ¨¯c°å9[¿B¤™Pt±i}߬±ì±:å¤ÊTÓÄ­ô[Yy1 Kꫦ’ci¡ò. 2wݿ٠®Á»‹ÓeT™I’ÓÒW1yêÇ÷ Ñv^õ}±’•¥ªÉá$´Ñµ÷Ølo<¨×›Ðt-³÷£o9ðþµ+×qíêu~×5uë®ÝGenG6 Ú³¢‰–>qBbÎÞK{÷Dò„F`Ïé|¿n.{Ïóææ„ À}• ƒq¢z4È–ŽÒjÜPï ÑMuV€ AjwOc—Å‹ã&°EV¨YvÉX»®´”ÍZ}ãëoíç—ºîo‹þÝ/ýJÖ¸ä…:±¡(WQr¾UÙŠÿªͤA3™¢©Øë¦F]רëÍd‚Éd‚ª©ÑÔ5êªAS7°_oãŒU ß}J³-åä ¯¡j^B$ ØËÁì8),“X"xi÷Á@”cЫp$ß+-^Íçw¹x¡w{6Bpã;ê¤+ÓƒÀ¸×ƒ|*»f且«¨±»4˜¤'b‰ÿÚÅ S³Hãñ¸™LÞ/>Ó +Q© jìY¤·0-%]ü:·öâñ‹4l @õ™Í@=}ý±ßÅuO ¸§@v’d™Þ ?@0ÔòʹzŸâ{®’gøÈb¾À… ÏàŽ;¹Œ®² ¹s÷Q\ºq;Ëwª¯‡LB ÷òÈŠDcã1±ƒýñ{Qr‰†ÁžB¥bˆ?{Ç—OØ ú]øÛ)Àg݆LVÓ°€f¦EZ‡ÊUÿØqÁ>„CøÅ‡P™†d1í äÓ`dÞÉ|ä“–ÍçeWfZ{œ0å=/ <Œ9[—PG íü1cÏê“?Ù·§eé4eG×ÕÇ…²xæÂ%œ;u½Ü;Î÷§Õ œÝ¾„+7γ5XÐ:l‚‹û«^ªÑqÙ!Ù;“$^â‘{û9Ðñ¸Oï ü”Ò•òd ΆgÔ5ÑPs3‰FãÙÖ»C×u¼.æ¨ “ß3ïÂò~wˆâÏ—ôZ¾ÆdR E†×Mz\¦­“Ú¼ë *ÇÛ×ݵØà?ÿÚÛy-Ô¾†iJ39#Ш]zÅ ^×¢¯×5j+Á [¿è}´BVÆ¢ª4u…zÒ ©”í×°¶BUñ;XkѵœH®°õ+   Á ‹—ÁÀÈÐ)vïsÍ66vY¯%jÏ$@Þ…–ûÔ0TÚÆÈ–7û@* Ù{õå¦þ;—Å»Ãßãæž*Nqº8}YJËšŒ%}½$£±QgÞ»ÂÇŽ¼îx/"¡ söV ÁÐq±4Ëêâ;l*Çäu˜Šw»&àé§.vÝÞµûH$dÉè¡7ñ°Oß¡‹‹$£Ú,íºéaO†?å»nž}`Žî«€},n“kòÚ¨ýÜwGvŽØuk&§AÄãù ]¨Wî –Bêz²I®Éÿ¾àsÏá…wO%­ãÀ~åò¼ÿwó™¨)2m3±o–cUUaR7QS¯ÄÔÑVbÒ¨iE ‡¬µÄRŽ­`ëŠÁÝVhjxßýùRîéîCÇ«Éë°£œ‚8ä‡8«­¦©“hŽJS©’Ymˆ+ Y–BL+ _¡F·÷ï¹»²lå$á(½”ÕÁ£Ý{+*ª9¦5ø U£ï:ò9¨¦zö„U׿ç_¹| m»ÞkäNs§§Ws7=PÏ|òè>!õVòq;ÊÓNù{da‰²ÿųõüY8)»>é5×ý·8ÑÜy-Q– rˆ¿ô¦¦¬<Ò`i:¬'<‚:³,Ç|m¦°[0~óË? „41NëæMaí¡ÅüÒ? {¨Í*³…ÊLaÍ–Xj"s'Ø$ÉôtöR~Jç$©È@‘?*».âà=ê­7ŸèµºùÒ ªZ$E€OÚô8çìc¸›9z÷#‚._º²–¹‡pÇé‡K .€;—edrV6*p“~¯ô­ò^?e _V—u…í¹ö2 0÷1F¾¿Éq#ºòð5”®ËŽ”{åì±ü£¾Áž?P@b÷©µ–©þ*Ñd¶°A%‘Y¼ìÞ]¼úe§$ÝãÀ¾¿¿wÿÖ{‹4Úº€Z±°µ!fé›;Nš†Am%–1ü,ß rÂO΄Bœ÷p‡sÁÙ3%7ÝPºø–½ºy @[ÌØ…ÁljtbSü6•X¥™å”½ê{霙1 –f¬iP™•™¢±SÔv µÂtŸÀüê¿A™ÞÑÞi4„ó+ÿ¦{µ™¢¶Ûhìj³% ~’±vËÍ*—¤àÇ‚JÐ 8 Ek÷¼´ 2ö@§ÑL¿äïÕ¢¿¯`íéo˜¹¯ñÕl×_“ŸsåÒ58ç×üNý vš½ÂÝ@r?kð”€ÝÖ8uzÏ{Þ8ujÆò˜‰–QæŒýw—£¿-ÄŠW@$›¡÷ôã²õa©Å½÷>wß}’YàØ={€@ýçICNµ5ÕU¤Šx(HÅr«NY«Ž¼‚Êñoù«ËZûP!û­ß|7æóEß~aÖ÷ŽRK.9kgûv‹|ëXø³î>ËM)ë¼pŽÝx—X¼J"F%X Ü@·ø³"÷‚dQM¿”MòdMÓà2S¿Øèæ`†âôûŪ‘yVÔm²oo`i"àºÃàn¶QÛmÐìý˜]üA=¾ÏI˜{ð×0»ø@³÷¡¶Û¨í»ÍÏ5ÛsÍ¥V=ò½Ԍūoum¬r ¯úÔÉŸC³ý€ŽéëÀbö> ìˤ°J–c¬’ûMO@ o§«6ü½s¼¸|é 5Û©‡;að¹eÜd2Á+^þ¼å-_¿øE¨«T4¸jI“•ÍBçëUš%Tï7 ÏvV†¸«jÄXÜêÆÀZƒW¼â>¼úÕ/™!¿n•.ï“~ª/ XŸŒ ü ѯ2ʆR\öZ¾\×ÙÝ)¾àsv×û|>Ço¾ë·%ÝéËþc¸÷¢:{%ÁªºF-¿+SEK®`°§BŽ Â,‚pŽÁÝ9ßyðÊoÂúµ»- ‘E;ûý˜ËÇa·“í7sO!x„ ë‰úø—Ø;eßLõälü öD2 Tö”7dÊÜ©F%²Lc·ÐØm4´Úl£±Û°Ý#X<ó÷àfpìwØÄrþôÀ¶¡±;hÌ&f‡÷í¶È3Xj@àuv“ ·B’)À-3¥”W¡ÐÙ3I&´Ò€&§¿óx/&aqp)Éd«Å^æRzó-²ßšöôÃŒüxìýêåkÙܘq€?=¹€Úv àM æ}à˜ÍhÛóE=•ÆÙªÚÃÌ@½H'¥7H¡”%Ÿ›°þ9‘¬–a†&3¥ãÃ׋E‡w¼ãÝIRƒÝLÉz6h»>ÙC‡ŸÅ]©P€=—¤Áè$òƒG3YÁxãënÍXàøÈý»û½888DŸ©äÅ8Ïn}­µ¨¬e“G±E¯ê&Ù³›ÄÚã‚:ŠŸiÌž º Ú·º…Õ˜¨·ûÀÝînñG@èÀ«K=½ vú‹ÁyK²ì”½ób*ÐN¤±!@ $Ì=w£Åq†Hfd(p3ŒE€¥€`¼ ¨-à+‘ÞÁݺK?ŒP¿æÔ÷ÀN^½ñ{¹ùè®ÿ°ø(jÓ ²§P[•c°×ìFÉé0ñM–…!žtü(+%!fTr3à|:¸ÐÊz­ªí7ÁTwë»@3´³÷¢2V&a%SSR"BéRÚó©VºÍß*½õÞñXŠ:§<—Ÿã\ÀÕ+×qîüIÿpDð83}»ÈD¦Ò x‚s]çÑ9ÖÚ½‡L¥vì÷$‘d*ßÁÀ‡ºÅ‡QO¿`èlší¯Ãlþ'"Ɉd@ŒËò°žYiÈÞ>…Ÿß+jäòùóê· (xžO€! 2 *™‰ˆ Ìðg躇Ñ]þGhq´õ˜É‚ìm s+ÈœFð{î"|÷4Üìßò—P™¶:%æŽSÔ†{µhíÖ4¼ô`”1H¦°ç³LsèJ ß÷úHr†×+»vðqÂR‡Î·p¾ÍÝcûôwû›Àâð= Ìah"ŽåjÞÊ@j𒇔Úȇ}9Vúr\ÿú€+—¯áì¹Ý”šㆳÓÇpqÿ…±þ…HŒÄBŽ<ˆ:v}áƒÃ9öá\‹Â{làºË@o€àSã&uÓ‚…÷®E .€|óg¬p?p<¶~¼¸r 4¨ ™/… (xC>ˆb¾½‘sd ·¿¹I¡ð)“uMïyÞ^t÷ÖJ`!àø\¿¾U¶ÊN«Ë…ËbŸ1UÅÀšU-Ì=.|Kú~ ØŠ&‡lÿ x|`ï¤^MŸ´×`Œ‡ñÉwˆ1Ýüý'w[¿¦~ \÷)ßÁRG-›'ÂÁ B ±ÿP?q‘Òr(«Îù§OßÞ À‘<çLE !Bå ° ›%† -XÌaiŽ.À¾aÿíI6 94‰\Flu–šdÇn·x U¬c*¼$r'ÐÀDn ”l}ÎÒ>pðÒpYÆ}Œáóq×9\¿¶‡Ý3§G&ö*¦õ .¦E}V¶Î€_2xïUf1`×á.zbð™aF ±xÑ Ÿ‡Îuxü±'à]—½c?_n6È/Õ–µa”¹/ûªã'ýtKj˜ìXôY”»ªEÝÔ S£ssÖ&ùȸþNàÿ¯¿e-°ÀïÿÞ¡<6Y©ŽºÖT¼\^]%ÏÖ‚¬še%‹"cJÖ@º†-cœ‡ëXo.ˆlø`   ¾Y‚j«ÖtÎÂ-þ!Ì@”|³5ÔÛ_ŵŸÕUhà¼c™†,Ë(„8¸š³›(£e_7dûyu7€©à½¡†…X7Yq¹Ä%@h`éæh©…õsxrpÔ"À#xuYL±á~bLg Vfš@ÞLØÎžÒ„%¤'˜€}˜­ëû诜Å3°{$R­]P;¿ÖÞazú{Žý­ øpóß•yU4/M½T~MãËÍÒk—Z†™ù*@ï?ëúµ8½»ÞjíìôÓ˜µ/ϬàJY†ç¸8”Rb2Æ®À®êÅ´[kðêW߇Ù|Ž'>sA&òõýï<Üýxw]÷8Ùcìã2̨kü°§ÄFÅJÄLD@O@J˜L'xѽ÷¢n&øä'ŸÂᬓ"+ H ?‚žØ¼1_ö…g×û¥‹—ððC /ÀÌ©¨(dt0UQ3—¼ê@¯K¦ecÁì!€`âà)Ë0l%Bà|ÑN0Æ#ÜÂå:{çp~ÎÏ…µ·0“/@½õÆc+˜ïÿ,MeÎ[Ê$§l\n ÷3ÖÉ0Çaæ«=õ€ÙámÛ¡ªÒšÅCõr·yèå=ÐN ÔEɆßUž ž"“4“ûAÜBÚÖáþw¼!´­“÷—ô÷ñ·ø}È?þµîcç{8îÄMab”Û®§ÃÚ•gò—À<]—N·¶vðšÏ}%Ξ;+W~³ù•ÈÒûS‘ÕEAœ‘úò38»[IúVK2c¬]ÌŠwÉ䯷Г•êÊÂâÅ­­êÿÈÒ˜kíÞ‹é#¢:çŸTm^ó•ƒ!‹15¬å¥68ÌîG½õU8‰îäÔw`~åŸÃ‡ÎWèÐ rCÂKº«*…Œ<l'ëʇœ1)¶ øD0⢕ý:˜PÐÀ†9,*š³µ upVgÑJe ÌOÁ_G&ò¨¹¥…¡&jÑDJÍZÑV  êÛèjÞ+=h|6€êYŽiýœA>´ð!`ëìß;ö7âà1ßÿen¨TgÏ\'è3-Ïù­ôÍuõa O_~¹‡Àžï¹wýÎ?³²Gmé;Íeܘõ9iïTH2Øã;i¬3i”Ò@ˆûmë’Ô0€éå;ž„ÃáîæaÅ€jïgC†ÉƒÀS9˜š³öüy€’ ¿j¸ Âl6ÃG>úvÏœÃû‘õæ@ždšè¿üuç%}›H2yúØ÷5åìÛPtÕ[×ìÜK-dtÔt‡ì:(Л˜ïØŠÄ{×96}ä9êzvÚ’¸’ ž)BÔY;f¼þ"Úù£ž|ÑÐGÚ(˜ú˜éàæ¹ 8SÁxv¦E¦ÁÃë»Å™³ü9óe>ëÆ/„·©méÔMV!I@˜¬c“Iß¡sxr𦓉@:!&p…$‚úUIú³‘Õ}L¼¯ôÄa|ÚeÌ9ø2È'0Wˆ'g™£Ëå¹ÈÚçÙßη°;o­_zìo‹ƒßÜ“0vZxµ´±L$ƒƒÔ›î²¾áæ/›1ó<®äõù=oìíãì¹Ýµõr·y 7æç3—kï=`'D-:~—»’$¼YmBôö–…“ÂúÍv`d Õñ ™¹ŠÍØ)Å•¦G”G+˜¬ª¥ŒãlÖâá‡CÝ<…Ù\ÎÕÉAFAž¸10©û¶5­ñº×œY[€}ô“¸páé¬ò+§ñuñkÉÜùÖѽµQÖŸX;ä-£³3ñ㜇ZúÀä5@Ö)•“¤¼xÀØÃØ Öyøè‡¼C  íÁý'whN}+fó?‚ -:oa\ ‹ŽäɈö®FX³6D±ßA PX\R¿5*…X˜à¥²6ðÀ$Œ¼[$Õ tpä<÷T¢ ¾÷li÷%+È®ÐÒ&2Lì Èõ=V›>BcCHÛàŵ@+2Ì›£s¼ïi‚3çDßæ7~)sá :I'` H!¯ƒÈÞd3_ÅÞ7ôñF‚·‹³Ù“I³²~žª?k^‹àm’fëë4,ÍĹêïñ!(‘ —p(Žåy¦¿³p,”?yÓ ¡×/ߨÇâ6uVfwµäçP›QŒ¼QúPØÃK¦û°X´ØßŸó‡j°½½étŠÜÏ„Ê*¯{í94µÞw¼ýþû?ˆ’)§†Åd’Š.›Ç>djT¢³[ïÃéVÖ®ÇtUžÀyçœ×E‚ô C–Dg\Ú8$Ùˆg$ª_t‚Ehkú˜2»¨v¾)ZytaÎ/Ð9–x¢“æ-ß1+q°UÔ†4L}ýüvrL@(ó†FZûY·h˜…ëŸx˜ŒRLÁbkè¬S>‡Ä3%§À€W[ÊÓD1MòÅe¿o®«ï¨x “¾|hE†™¡u3´~Æ@Z4»ß2gOô}ºù‡‘±uYœ¤R”œÒ [-Q·ñÖÄ•ç,ÏëÍø=‡Ï¿±·¿–xZœjžÈÆ­’í~n¶uÎáþೂÂéË :K2º.ªE-þc˜ÁÀdÞ"³4'>CìíÑ{¶e÷po™Î²-IQ5¿bcÃ6Ì<…¿F²a·‹ƒû‡>Ì‘B½ý5 úå,-¸E’Ü­˜è”ÂÚ IDATôyYÜC>]–gé­u¡íü{+€†v)†l&(Y®tÜʼn–(²ÀˆÏ|áhƒ#-1spýËA|ÕlÔàË÷‹ÀµgïX_¦®ÀÞº¹ ¢¾Í©o=ñ·™ßxklÔ㟺NÐ%$³òI1zûëÁ~Ð7o$ò0|þþÕš»ÆíÖŸŠu:93űÒdÁÔÄ:Ef$=_¾yþåv]¸¹ ®¡eÆY·×Püñ´wÕ×—_k• $³õœ-çº($LüHI†éœÇ‡?ôç°Õγ¢~Äí­¯|驵ç>‚7n \5Ï$p¯Ä¶=±vµ-N€n²*?®]Sà¹añžVù9Ÿô½ÍÈs0à$C–jÑ¢È;¸ùû§`ìCiÃ@hvÿæ—ÿ)|˜£sÌr;² G0Ö€¼š¥I'<Á—€Âo¬¿òF ]þhಜøÃäo$Þ€'ëí<Ë3Èú¯‰¥²VÏâaHÀ.bæ¢Bªõ;•b§Ôƒ`D¢XŽÔ_L§ŒÝ¢uüçüÞœÁöù<Á÷ààÚOÀ¾µm"¨Wq°¸›wÓÝÿú–ãöê›[¼¤{YÚ¤ëú©Ñû{çqx0ÃÖöðr—º?µ`Gð¹ÕLj¬K+Ƶ¦K9À’fa93P·â{-]ù&«Â³ìÀÌ}œÍe˜þ5½Ó¥çõ»:Y¦¦²íèlHÕÔhsž§–Ùù€¶óÈ¥Á«îÛÑrÑmD”I2Ë-9›<òýti<¶©dé;MøœøȺÆ DàÔ(DŽ䷹Ɵ§šÂÌ*(ª3Tw5˜ïý?ÃâÌÔ§ÿK¶ú€H Ž|Û‰T#ް|pe¥—õBó| *ÍdÇsÆÌÇ („h+îÅϼósKˆ¹»™ÛÃÌ]Ǭ»Žy·‡Y·'Çö°pûhý!:7ƒósi ĺfóœ«Ëlв Ì=›$%*dþbZ‘a$î Ê1o19÷ƒ'–c`võ_ËââêQSA^M;m|'ƒ1†š¶Ã }ˆÙ—×—í»qã`%°ë ùVõLI–2F'Af&Ë(γ1>¦-'êH×”aü‡­<ÿ&†#ÎP-ㆯ[ÃÖGžÇ˜•?¬€:f©¨“€:_×ÜdÝš¢§Å!¿Ï:˜úêû–'IèV÷÷÷ðÀ‡?’z ™‰•>W' ñú¦¢³ËÖ1jA“7,@Ö-¤¢°Á“°Qg¢ªÖnH¾äNdÿYc‘>sfkž5eã`ÁƒºÅ‡à…m^5öqVý¦vòZøí7¡;|±*Ž`â,Rr„ÎUh™Z°€+ã[æ…,Ã1;¢˜u‰LÄÉ?-Úî 7GëàhXbw \vÕ¡ZE :q7àÃêL@eØG"¨âgS‚£õ¦ò,C<¸Û‰ ;Ë0X¸C,„µw~Žêôw šžlÚÃ÷ÁÍ?ˆÚN“cšÒR­X寙yÉÐóïU²öœóí÷Fõhylv0_0$y;,ÓlÙ§qƒî(™{dìÙ>2¯ÌÉZ2°ª)Ò ã²‹Át÷‡gÔ5 ‚»VØ›ìÃ/•3ùØ:JFÆ…rœ²¹ñ!ùúA˜Ù餥ôAÄ®µ§Ï„WÝ7,ÉäûýÈGÑu]”dúJ¯š”­kZY¶k¯*ñʨ#÷)_sóǜ˰lÁ¬Ý» ¬Y¡ÉXSÁçËûH–È¢¿–*™ÌÓÀk<<<{¿Œ­[þ'œÔÿt}êÛáºËð‹Ð"ËgéUUžÐ`‰¹"¯ÅG| `Õ 윃V!±/÷ ¦Ñ#¥Xœ´á­ÛÇÂbáDêXÀ‡V´v ÈÀDo“[¨-ƒ€Gæ²dÒd0ŠSÑQ€º‚|~$·cÏýÞ2Œ?À¢;`Ö.½3ýJLn‚u à0»öc¼Þ¬— v‚J–+dga*W*ù•@®Û!@_eÂ8äë€!WÜaif{gµ{©½àµ G2§6íj¸YÎ@LCõðeÚr‚$¾¡†Qþ¹u ƒ3T—ƒf>Ç Ë0c–¢ò Cöþ*ß Ø·M #4B¹CÙ4)°¤™&mðßÙÝwßÑÈ;Œuõ€}ìA¨;ßdƒÎÏV2ÆÈ*K•øggÖN)m±¡QÀý“ð ð¬³{•e¤TMSý¤§ÂÆû±¡¬3=)ˆîîQ™:;²óO¢=|/ê­7}¬ ƒÁäÌ߯üÊ¿F×~ °ðòmÌŠ­i@ùcA&8aDRUØ?MôKÃ0ä»°lÕ¢ó‹(q,ü>æÝ>~­›ñ4~ß kWž5÷Ê42Y¨C°^ž!–1ZN¢©œ6—&2t)¥±â+›cN6wìB'ƒÌ wÓ×ú,ü:?Ch^ƒ­ó?˜}Ãã‡ùÞ¯‚ܧQÙ­ž$ÓÀP-äDÝ(@Þ¹¯…' _Å´—G<ìþyzÊ{Ìf‹QÝ]·¹ŠÊ,ÐzeäZg3»v)“ÖTØÚÙÂëWÑyŠÏÏ}µî³,Ãò~ã˜ÿ^KëoZØÀ+dž°á¸cÉ0!¿k™qAµÎБº¾FˆGÆÖÕLI™lV9Ó}Ô³®Ù«î;=s¼«÷àÇÌÒÊ[•dTŽ1F$™:YÈèà*)˜ÇksÖžŠ¿¼¦LZ‚˜>jZúšdÉ®”µ§ã*ý€CCà§àãઠíþÿ‹júzm}´µ³«Fsæ0¿ò¿Ã¹K,‘ ÷>‚!¶}w{¡B€H4Ñ&剔 a÷ .¨?aíîónóî†èé‡p~†P¿æôw£ž|.|wÁ]d¯ó±Øÿõ¤³C[ÅTÒ[xS‚…‚Æe+›ÌýÃØA€½t6—ASfê ·/½‹tn†`ïÁô– P}ì|ùï¯c±÷³2pZ'ÿ8qq^Hë4W±ši ì—¸Æ.žŽ\i†·‹Ùb%°ëvZ]@çîJ€.õ?Ÿ­j¨ÂwžÅwüÍ7ãßþøÏÃí·ËwH^Ô(&5¥SÁ½¼ÊsAßæ¹eì îcá8Úû:`~ßµbþ‘‹>¸ cR–J µ9akƒ,}If¨ \¹|—.]Fßd $ /“–*Ó‡H'4 3§dc¢Öžîaí¼ºƒzHÍ ÆXûÀ^¬ ¾f¼ñ¨ÔÞš<¼?ÄâÆÛ09‚kÙþ7V£2ÛhÎþ×X\þWÝU+o™¥{òðÄ µ!–Y Ÿ5o ^¬Uâ3ø}X‘áÙ\!8tb+ΪŒýΜÎ~'ªé—Æ´Ru;¨ºo}Üä•h/ÿøû °[×Dgd¬‡Aºï³““eDSçÑùWháBO†qûéO€ÝÛ;1½í_€ÌÎÆy¾*Ì®ýL˜ÁZ^ïµ¶“ÈÞ“Þ®uÈ6ÜÁíõ––z@Ïø¡ë\ç`dñŸ1€ß2pƒîŽä.×Ùä=O=u ?ó3¿ŠÙ¼ÍÞo˜<%õ Yp•×PXw3Ã2 Žˆ¬Â’Ãèo` 3rßA`§,.*36.«iEèÓƒr ©ySš¨¤º›jïD¯zé¶Ü\ÃûØÇ>ž¥(g3I’ÑÙ§UÅ&•e¿2iu&¹¦·Mƒ[1}¦Ê1Á§¢‘xR™@Y;õîS @ Œ©Xº,{Eô‡ïYZŠï(!ÿ~ÆžGsþ¿G¨î†s‰½.ÜæQo>D×Í’Ù"Ĺ÷POŽ^,„Bà†±ÌŽ] 'vâ ˆÖÏàÌiT·ÿ(¬ûX°[_†êöÿf;s¹¾ó‡"åtüõ¼®é`]H€ÝG¦'sù9:ǺÿÂÝÀ¼»y·‡¹»…`¯ïÃôöÙ[Žßyèf€Ûÿ‘­×2P\™Ivž<§²Ô0Qê×;dç •»1¢3~¯£ÜcøÚÙl`5sŸ˜§–Œ'Ð' !àúÞ¾²’D¸²±9Å›¡^órÚÏ/Ö³†0îšAã·:[Ч".^–ÖÐk Ê“²8e¤AÎ.ŠŽÿn97Áí·4+|ðá,½@ú¤©‘Qœ¸TUlGLFIç–rSz'"ŠÖ0ìj D`ãù?ò.½ç‡¼bHc'ÏU³È4c±‰ûÆÔh¯ÿBعïљӨÏý}„æ•paÁ½õûXtû˜»}ÌÝ:ˆÎÏħ K-.úƒñ²Â”4zqr›>²™å—FÂÏÓ߉€$s¬*ËT¿öö½1v~gÚºàग 7‰<:AŠåéA¸´ŽßmáöØ{+¦—aúLoû— ³;ž°#„à¯`v凣SÛ)*3ͼ\òÊKq¼)“;e"U”ïÞññóË2â—Ï-ï‘Î>¶|í|¾Zš ! ¢=T¤«¤eÒzƒ«IW7|ŸÂøE:Jðîõ‹í³Vßÿæ«@¶Ž2s(ƕݾ|¼.]Ïö‹sM¾8ÔÔPŽ ·EÎô‰€WÝwz%°ëöÁ=$·U¦ŽÈŒQWlöhm6ªÒ‹QIŸJ3±Iº ïÅ1˜÷.$ æB¯ Å™®KyX>C'rYZ°R_æq1Šö1¿öóXúß{ìû5¨Ïü]„éк[Š,ü~!U´îm§vß x¿€ ¶€b#ïâŠEÌ®;·€s-º0‡¯ïÝþŠ^V§•ìmðõ‹áÂ"zgô2ŠŸ¯`î¤ÇÀ³]ùüyÔü[w ÖæŽmêçî:æû‚v¾“[þ @ÍÚ<Þ4^þg0~/ZÆÔf*ÛIœ•ò¦œµ'ô±ó–Ë`ÿÚ´íƒæúÆ`1oŒ»îOìSùŠÎ¬3œˆàÜ3ÜXÎ+Á A`ÍÓŸ«íC ÃIÃúûdª«t!ÕÂûe¨¯‹ïëëÔ‹í1 Éxî=• ®Ñlמ·´i•C²œ¼ê¥;+ˆðÔ“OáÚµkPÈ<¨o ]5z|´6™$ÆžF>jäV2šGÊÖCHZ{œH“±ý¢—ƒám¿â©–Hâ ÊJ´% ¯Mʦ{]û´‡ï>‘õL)ÛÔ§¿­}ºë¿Šá: ^É©Ã-,&0¡†¡_â„ b5ÖC]\Ô‡…¬7Ê ýŒ;¶4ýBø½O™t?ç;xêxI5ÒïÍ2ŒCË&˜a!úz©±óß¡L’:DGÕ¹¿jç¯;O‡ÂâÆ¿G˜×xÆ^Ùi6ª a+H¦›éw°òß›êäCÚüªkÓ™«4öe\âÙªêã}ÕxÙÔ\À z@-’…°&í]eZÓ‹³Wã8 V3d…1I_ÌÃøß¬0”/Ëaµ 'rx@uUww¨Ó˜<“®K`ž®áÁ« e-,Ø ’d5£P´ÎRüHÍÙÔ’ðÊ—$½}hë½ÇÇ?þ–L % †Àë”Û¶W•E]‰s0k¢©fr V‚od™”#¶ÛÑô1HŵC®–÷úG$ ÞvŠYi¾CØ€èn¼ Uý Pu×%ÈW[oª—£½úsÀâQth¨c!Û6Lahƒä,(Ô€çÙƒÁ^„#´â¤¬¦íØßûäsãsó4¬ fëõð{¿"¢Øè[ XxÑÜÙ/¾ tb ÓùÚÀ Þ†äR  38?ƒo^…ɹÿTÝq¢¼ì×>‚öúOe¶ìS4v+[EJ\«ä‹Û¸ c‚ êA÷ çà=òG4- #,æ-ÏúÆøxÙ„ž”«“T»ò*…걸5YúrðÎÞ¡×æ ½÷øn†ÇkÂÑn²ÖŸûXÜ*·¿G}Êãú€•ZKÑS$šŠk£Ô¢fŽ ÄÐCšAšOC¾ýÖ)ΩÖJ2=ôP/¡|7#ng“£0aìÖÄ(·Ú¡2ÉÅBÄvÑÝy²Ž-„ž“ß…Š¿T]ŽKïÇ’… ÜPX †å16Eðs̯ý$&çÿ!ˆ¶—ž›‡MÀSƒ±·¡>÷Ðî¿Ýõÿ4 ÌQÑäç òh`B ;º Έ‘oŠs¸0gù©YëæéÑ@õ áÍé(Ç(7¨˜©“•üqqÓ.cì]–îg¢ÿÏѰ»ÿ&§¿7›ÉóKÿ,×{µ[쉵§ATHÙñè÷ˆ…¾Ç—áj ÷Áûf°{ôÎ[¾ß|¾ÀÖöd¥¬j°Ú`ák$YF ž2tÝWß3ëkÈ]Ø{~¢¸F02sÒ^–ÝÄpôn`瞇!ý|(~EÜॠh‰Ü¦‚¦òHzjV\þꇈçÆebtáy·MÖ{?ø‰ôêK0;WÇ`ƪM;P\õسŽh7QfŸú ÒŒ°DD#âŒÂ%[ö¡ í+‡ªHüñXÈ2¦á†…*AGÖ_ÂâÚ¿Esæ¿Ñf”Ÿÿ-_gPï|=Ló:,®ÿ„ƒ?B èÀÀn»áå¿È[‘fœxUK[Œu¾¶ß„æÌwƒìíGIÀF!„fÿŒµÝŠ•)Y{’c€å2pP<¶ /óðõ€^ž;ôìñôÝ¢Ûh¼¬¢kXÐí‘©NÃ4=7ú \i¹œŠ{ÂMóþsŽ~ó¸kÆ$¼YXo6Ùg¾š`+¥¹’v¤ ”,—V´?ø‘¶H„äÊ•"“¿ãöIzÆÈö™g.^ N,b‡\FR-?ר2­1˃4œo:aɱK_ÉCiÆærÞékæÇ²ãYZ‘…XäµÜ¯rw4Y9èÚÇÐ^û4g¿Cãgìy(áVÔg¾ÝÖ×£»þ6t‚…AÍ _£ŽÌ‚ÖÔ5º–×3{?ú»6í“;°?÷\Y'ÑÞK¦™ÒÐ|T !”@™]Ÿnú@ykDq¶#Ô;o«ã=ûÛîO?‚72Ö‹øÁuÑëa¼gçLÙû¡ðÞHÙÿj%ãç$zí …lðK[¢e&½œ§Ã€/.¸ô¥`%oºÈ¶’7û=´æ ªío(î>ôW±å1¹&€šûP»îôutûñn„ö)  TìÀ+XΫàá\Ç’ˆ[ ó9œ$ñ? ïÐÑ ê-%ÌP=fçkPí|Èœ>ѳ7 ‹ë?pðŽìüÕFµvöI2¤tYeLV±ñev?ÎÆèÃZ|Éêùn]çP7«ÇÍl¸šÝò-å.qÖªbFÎÚQn¥Þ×uƒoÿö7ãÝ¿õ{x≧à-ø"¥Ç ǽ® 0ÎnÆå™U-Êq,e²Ö·?òÈ®%-y\‚GíNEPq’ñÙŸ‚ÞyÛðzŒ¹Ýý… ÏdiD|ŸË¹  ìœC×9^›Ò¸´ð°MçùÏH¡û$þÚå~’¼ŠLÈÇ>üòqZ:ÖzqI@DðØP#(G’h‚ä¦3h÷ß Aµýµƒ)È%—!?ÆèûבمÝùk ­¿7{ÝÁæA˜?ž ß~†mÞƒ‡,§½6-+ãÁ>k:°…Œ©ž3ý<ù{ísÂÐË౸òãð¿&Ö0,Ã43öÚLaÍDä‘2IùòàQ•ÕÎÁ†Aþ¸ƒ¦)n¬!¶w_ïñ{qpР$Â>òúOÈʵ‚½àF:žÉ7ºÀ;]çðûïÿ#t]×KÕ(Òon[Ïø‡¨Ãq'ÐÞ—‰$ú"[Ï*]Áæ#è½]>÷-C¸ó¶åÁÔ>°‡D–ÑÛ¦4ªå8;ÂjÛ^˜" åòP‡x¥,¼& f‡² ‡H2ÐÅG”é›@æ{c@_žS¾‹4|†eO0ëØ{×Þs‡ïA뮡Úý^DKùuÀ9àùïþ¶ŒÌi˜­7€¦o@ øÜâ ¸Åcpݧá»k«±&Ø­7ÂØ]˜úù0õ `êç4=Ñ=O³K? š-bÌV’c̶8›È"ß@"·È*û8×@Ù±£ú*ðÎê{ƒ÷ºž€w«€=éî×áh7â@ˆ|ûh13€5ýß]§X·Šè¾ÒŠo~8‚)䘾¾nÐt,.{Œ¥ô+a¾´À1ÏÕ’$e¶²vBuê}˜¸¨[cp×ÓÁ§k6›aoï†è—ýŠs}ð0ÁÂuZ™lØ,š ¯'„šÙ¼5Ȱ`Ÿ%€×¹C>ÄJ“4"Ë” ð2;_ô½+„ÁÁ^µg ËÞ-nña,®þš3ÈìàW±ðüœ¡¸1€ïqh`šêÁK°¼®÷ RG6åïϨkØÈŸû8[_wÝòQà~”1 ð)?!e¾²Ú¢eÕWd ®V4€ c,î¾ûyxÉ=Þ ##[Ê”iò™©9Ø*{rD©+èEw÷! Ñyÿ†{êK&xö<¨S›yì¥LJ)ù }9géŠý2Ó0/Æ€¼6”Ù`´ú„®{óË?‚úÌ€ìù¥´Œwÿoè8¿ã0°÷Ÿ1Ô€üe¾{‹‹ÿÖ?Êî ¶St<ÿ1ÖT Se¾…0¨ùv@_Þù±õ÷ÞôNýg.7JË …문!µ˜Á5÷ (﹯÷ÎeÝ^IUŽ;6Xc9ñl‡µà¾N¢¹*«lå9ã2Œ4"KÇ5[2¹¨øF™y$P4 !5A„¶ëpþ,­, ,É<ƒØš™ÐK!w#ø~†WÙ_aïHRË* fìœMü/+Øwï»úc¨Ð¢¶;âR`;›:5ST=`‚ŒAå@²©&¾9 orÝÑØx~þX/cù¾Ú$9çaÖØº[\E‡S£ (‹—²ß‚+9Ö‰ð±Ð¿ÁæÜþ$aÜK]Äl ÃŒßs¾Yj¡Þ-õG² Mdz–4 Ž†Ç–6²õœQp7îÂ…K8wzw°Ìýéd)S^ö’.5*êûYºYGp`œŒ®0W5/TвLâ'¥‰c0µ4D–¶UàOÅ™ñXl )Þ›?½‰-»öNÞ0£—5xawíÿ„›|1ì©¿`º¬‡ä˜uýp°ÿËôÁòãÀì½â‹}'™<ÊD¥¤±W0¦Šf¸9°Ç k{&°\'Ó ;Vn~ì8Ìû8à=tLSß×9j°€‰æù=z¤&ÇŽA¬É~ž¬!<x•±sŸÅp ÷GPeæ ”/Lj?@9A¨ö|l*¯OL¾Ìüƒmo$Üû€Ûo·q×í3Ï,[Ê!O‹¤YY>Ï8 °ºòóèPY^ Ú[v5`ÔŸ¤fŠïŠ\r.ãŒ|ùœü×бü—œ%6½êEÒÂÈd0õ¤gy‹ TYt®`áfªp¾” IDATˆvþ ìéïÕ/w’`VÏãŽúך!–7ÿSt—6\…µ;ÑWLm„­Û­¸Øµ1•,•§``ÉJhx—ÇÖ³ðUl|sðÞ”…Õ:7n1£[‹kˆ \nN]`GÞ%IK Ô´_ïð‡ò+L>5œˆ´cÙKéaê€íhì*` „°ç$“§` Âs‘€°µµÅÂùØ‘ëdÚð•»;“† A©¹›AöÚÈSÖEMØ2”ò>°/&wl‘âKsÄ o’üJ÷e _>k9½ã@ŸŒ RÙˆ¡2ãÞ2Ø žá:±_ÛG{å߀¶þ Ìö7BÍXðÚs韷)»_>k=ÌÑ]û„ýÿ„ÚÔ¨ì)‘a¦¨Ìvt'P©©£©Äa”oöBNؼËcû¼‡‚ÍØø¦a³ç·Z^å Íà–<Êx€\z£~}G¼Grý›Îîçc ú' UeqÏ=wⓟü4K¿Ë‰*~E"£ e£ƒ1+âV{ÖP,g[(¿i?Ž[[Sü³öqîÜ.ƒLõP\S „H‹;ص…!„€«W¯õî“Ý—´ù 4A¢Hpð«gfïy­TÏ«.<àª÷?ÆvžÂ c‡€žR~RÒÙ-YYÑG–å32ýÝl£6;üG;ò{ ¼‹‹ÿ Üáï/•‘UžÇ÷÷ߥ÷ªŸµ@^„·ÿN,žú~ÐÁý¨í6&ö4&vÓj{Óê4&ö»-Ì=™<ä‹\—~cùö¨}¸Õ$â¤a(mã=ÑáQ¸tÌûõu™‰bnë®Þ! °(ó³_°†ÆÜhéH/JŸuò` á¶ÛÎák¿ö¨ëÍSßÈŸûXÜ“_ ê@ÊÉeV¾Ú2‡#gsüÐýç`›Cõ=ÓïVõ§“åÉKºUæBÀbÎë4F3HÊ”ÇzªL6ðš yöIšè´CÂ’Œp¤üž¬-eÄHî¬g蛣tG2¼~©Lè°d@ÆÂ ²•ø2©˜É ˜ f€;€»öVtô.`ç›a&¯îUlü¸Œ]¯ýl îðýðצ{i"[¯Í„uõl± ]çV—FÔjÃÃS:1 (Yá8/Ã2ÖΗ¯È¬ë)”©Y•ŽÕw ë #Òd¦Àù"÷‘åÒÌR’ø,‡Ab>ôm޼¸pá~þç߆¹`ÓŠ‡xü¹¯cë#W¥û`Èl\A2fWlƒn,{`̘K¼¿RgR&Ì¿'“õÀή:±fIÀMÇÌ…qÌ;,Çó39’¢²U²Ï&ükè¼òìÞ}{ lÊßü,I/OŒ!–‹xÉ>2°âɑث#a6Ìw îêOaQÝ Úùë€}é(XýªðÙÞcÁÏ€»ö 0íèM[γž&ÿ0¶¥ *‘a¸ç”•§ Ø¥ôbЋAÕ47ÙMÀ{èØú†å8auš×Mf"ÓJ%–Áç Ê;e@/§h]M'R:y$[¶7¿`zØûù>Ff¨Ž9 ÓÌ:.c‹Ë[̼Q ÁôðŠÎËãòcé©UÌ]÷g³YÒÏWÈ#CŽ»rc¹#MZ¡ËC ’ô ²eú–á·é! ÿå;ŒÝW·,yi9mj* /1c7¨Ùe¯©aœÍõB.Ìöqt—þ%\õrÐÖ›ê×êåqàuS‰fˆñÿÅøAø¿Z|µiPÙÓ°f"l}Z¬¢dMƒŠš8hªkF(Q?KKu`d1²—Âæ37¼nq³:xï‹ñ²!6Oh³çè½u[zùü¡ý¡ßz˜> €îÃa\2ÙÔóbÈ23½çd¶2PâëÆÀ@˜4Ã6±9{ŸÏçÏ¡òNZ˜úi8Ö—pú‘ºW©q@æÓWÇ—i^Nyy0c Her¹˜Ë‘¨-¼^©þLœñ0°hÛ_Ã2È[ÔhÑÀ„jŸƒÚO =ü8¶&_l}9`îZ òýýÏ’:´Bû8üþo ¾Æï£65¬Ý/•€;”Nâå¥eñt!!Š@t'Ÿ`=xŸŸ$,ßç(RËÐýVMdB@Œ“i(,zÀž?eáòßæô‚¡÷¼Yy·.lÞ3Xãò7ƬaëÃ,õýxoðJ£þq®ù¹M”JŠ»õ?H [“´î¢nû–2³Ù<Å¡o¹ÒK,-í,=;רùéxø -Û¸€žh4Žˆ`¨‚­TUß:ø®CPß6ųûÍBÊë@6xx2¨D¢!_Á^M‰B²x3ƒ »@ÛÍÑíÿ&ÜÞýpöÅ ò“×CíäÇ€~(ü…½?€?ü]„ýßµËàs [ífƒÐ:i‚Z,`,M`Œ•…¬•­ë`i¬É-bræü\€÷flýxà=”®£§Ñ‡ –fãú»2÷²nê³Ó1}ÛÍSÀ:þÉÜM?aí€ê¸Ds“d˜%_î–°ϘýÅIiSaªo©ûy×n.àž¤™<}éÜQ hS¿¹K)ùäyÜÏï~Þ‹å¾J?ŽÈ n¦˜ž:‹í3ç0Ý= k+ÌoìáàÚ5Ìoì¡=œ#8?x—eqÔÕe0ÄS€± WÁ˜Ž™:Õ0fƒ9L˜À`‚ X,`ì 6,ІŒû ºk¿ç¡z |ý* y5P¿˜¥9|¶½GX<„0û3`þÐ> Ï« YtkÔÜ'Ѥ±¢I\Tƒ±æq #¬QÙ:÷äJ`_ è”»ö•c£ùPë:ð>^8Y£²qs!u|¥\h± :ã:BÊòƵßH„þIa¡ZU Æ5 0ô#WÏP=èÏSºCpç„Þ“fxÅô‚¹Ïgñx¿‹V0í¡ÌÑਕ*+ÏÍuöA0mÍŽÇØ«ºÁîíwáüÝ÷bzz¶šàÿ§îÍz-Y®;¿_DN{>SÕ©ª;’©ËIj¶¹ ¶Ñh a?7ìOà¯Ó_ Ñï øE~ñƒýÐ@ëÁ’5´$R¤DŠä½¼S gÞcŽ~ˆˆÌÈܹ÷™ª®¤(œÊÜ9DÆø_+þ±b…‚²(˜¥k–——,^½bssCU8?ÙÍ£7Ô£bgŸ/¬#áÊhóR#ª …N‚œ‚Œ@(ƒœP->”…ÎQÅo©²_SV„"FEŸ@òCˆátÍ˾­]¡‹ÏÑéÏ ˜ç‡ÔÆZH °ËˆPÄÜ#³ðHD–~‰¬9cd¬„ç¦m*…¨&ÝŽBJÂ8&$ÈÈlè­UEQ¤ëU•[ê¢~ãÖ8{¾ò€wöÅóöÒ ´FÖB—æžo½WÇ(ºWúÎÍÏf ÒúჂ/ØïîíÏý.TËî{ÛÒ­{Ýouq{ƒìæþ.kÁmÑc~ ¹wøÖhî¢^òïãìþD;tÛi:ë§Ûiîb»<öU³v8qðüC&ÇO ¢¨þ¸ #âÁ€h0"J†\õ%ë«kª¬hz´ÆÛŠÓ¯kEã™ÖF[·à$!ˆQºDÊ„@”äæO„:£F£/E¦¤$§ªJªâ—TÙÏ̦&tx‚–§èà„Ï!xˆÞG‡8ÿ° ÑÕºø ]~ å+DùÊ׈êÜXG;01RŽ„™cDl¨oC»¯©óãöðtsJn$ä†GÛ“¦½n„FÑdÌìÙSfÏ_0˜óEž±º:çòóOY^¾¦*Ò­ry¬¶¾ßúæ.ï?N\¸1‡6˽o×Ü…{«É®È;šô>„†ùæê=V¨î wöÞBÜÏåïZ7à¸wQWVó`³hÚ>½~D@ݾ:µ=¡JG[ß—Ö¶àÁj廄A[P4ÿÝÞ‚00:>e|p„ŒÂ)#‰†¦§§aH}Íêì‚"Ý“n[§Ö °vÚŒÆpñ´õ=#k¡m5U©@•HQ"eI„”aAXT"7Q‹’R(UP‰ŠJ(]Q• ”º¤Ò?¡T…ÙÇT—œ2øà?Þ£üÚ!ýò‡êå¿–ÛtO LJ–V‰"0V."´š»15V/îÀ‚yàaŒí¼B`ü®ã%ûi !¢˜áÑ!ÇÄáûï›Yš7UÅøè˜(¯`qþUd»bëÿÄ݉‘Ö[o[3¿K¸ma":wk—pà°eŸGkw‚¤¡”Ì{„ÇäN¾evMp:àÞïrß½Ý`¹ ·´¡bÚM_ §ïn y^Ôo˜IÕ µÆîãzÿà²å„‰pÉþ3»ç8d2M ¢¸e¾Ùn3´ŸœDa3ó†|¹ÙÁÃ{‚ ¨]è¹ò²&Žf›³ï“B ©E„’RWTB¡‚’€’0(P²$RØ+UR©U•”ºDI³wi©rª*£Ð‚ ¥J³Uàc(!° î8ò!¡°\¹ˆ `‹Ð:î êßRµfnÞ·zmõØQ ´”‹q ê® 7KÝýLlwr!$Ñ0füô„“o‹ÙóçÄ£±™È¶Õ"¤d0™qüÁÇhUo”7ùñâG3¿kpâ~€Ï¹›2´ëÂ7MÃ<>ÜÁåïn›÷‡oŽ }™èÒ0ýiÙ—Îþxýp¿2Žs‡¶æ]Ÿ÷‘ù=ö×~hó«ÞëâvSȇF© í ÔþúÈ0fxx„ Bd3ùš|±¢*­­*Æží]ã¶t;TÕNÑL"jÁ„H¡²B+…” ME¥*BQ¡De¶ÐS%•´çº R9…È)ÅYm¬;4w¿>0H `‡r@l]*ÄÁÈ‚¼™ •µÖÔG3êÀ<°ûç ë&Àä¹VpíTÓ˜7öúŽ4ñxÈôù)'ßþ˜ÉÓ§„ƒ„Þ5RÆŒŸ ƈùÕ74?ñ͆Û&S)äþðM÷¾ðvÓ°Üw+Ðw3sì¿·¸wd®ýþ4¢ûAt_ØÏϵŸsš{W‹¿û·öðôÚtx)éÍÿÛÐäuUQæ)ªR4nûƒQ0’ÉŒÃ÷‚0fñú5›ëEÍû<¹´×¾h´Äkð–§7‚Kßú"@¡ ³ß§-šJU(iÜ%+*%•T†ž‘a•RˆR‡6 J›]°œnö&“3’`Z¯m´ó°rßÿŽ™'‘-eÀ+¡Ú^]<Ô‚ ˆgŽ>x£?dxtHèÍŸô¾&¥1}“{yüçö-L|˜Ló)ßwÞþwzÁÝ€QìÖºÛ÷wÝë‡ï»Ñ0;îõ|g_H³þ}}÷I’ÔÏïâÌû0íâ§»´K+Ü¢¹wýÞ`¯5ª*IWKÊtMÁí®ŒÖwð~D41õšõùÙrÓΨomÜ£-Þ ^´ÙÉÉlZ"L]«¡­Ý‹À–¿BK³·(Qš#ÊR5)!Ú¿Î)Eâqš;BډфHŽˆƒ I0%–kÆ#j—»¢¶G÷êI8¦Ú•‘{ñè—ûBJÂ$dxtÀÑÇï3{ï=’Ù„wÀ£¬È x0øÏ!ìv­ø¶:¿ÿù‚º ½îúÃí4L?°ïüèöû®{f'#ï3ìøÑºžf·ï˜î{]ëÓÖÀÙ'xö…Z˜N†šyßmw·Ù½ß%TeÁúú‚ë×_ë˜Ñ lk¹[rGJ¢$aòä„h8 Y¼:#›/)Ó¢™o©'XÝoj åvʲs`¤€õoTy7íjü¨(‹} ddaQ£EE%ŒÏ´¦Ò%¥J Äa÷ˆzLH«½Çv¡ÑÐÐ3Á˜H ìä©´t‹·žØãÑ-û By´œ›³ÐÜ Ø…@’x:búì ‡½ÇøÉ1Ñph\/ß!¨²$].È7+´zèB›‡é½ß´Í¹oõo¢»¥hKy}—¹x·¤³Bu7(î×Öïo÷·zhïóƦÕUMHPuâtTxÐå»Í Ýyœ4R¾mwÞ¾¶ ´ºõ\W¹÷…A“%¯a oÑØŽÑLì÷S,Í;ŠlµäæÕH)9xöÉdÖš€ë@ £dj&dãшū3–g×dË´B+Q§­Î‹ÓܱçNq­5}[†v"ÖpÑf‡'£Í;O›‚ÐÈ ”.AH´Ð(™(cn(üÕƶGÖôL`íÕÍ¢#ã¥!ÍjHlÞìѤßÑ^&6?æý ¡;GR FÇ3>xÎôÅ©©ƒ8¼³€×ª"]Üpõõ礋ëzc‹»†‡¹ ØÎËýß}À›û€]kîÔ Iï÷5Ý´ÜIw¼Wx÷#ƒ;¹ü}»Ü»3¼¶n"RÚmvÑ„( ù×ÿú¿g>ßðWó‹¦ÜwT\šUõwܱ+hâ86]uÙõ¯îkîþ‡\\ÎTS ïy¯µÞÞƒd{dp;¾+l¿e’S±™ß€úŒª(8|ñƒÙŒ ˆè#·ºï ) ‡ƧO‡C¢ñ˜ùË òÅŠbSØM(;ŠSV‹Wôjö.©õoë¯Æ¤Þ•·0{ÏÚIû¨¤@5“™vG«GÇ™#Ît³Å³‡uº$ …Oµ8Ý¥¶ è}g;AGÄÓ!“çO8øð9£ãC¢áD××Òî ªŠlµàêë/¹yõ%ù¦C§m¥äþˆÕ¢ž‹‘m»ØÍSQë­[уw¯Ã}ŠÎïwÞºËß}€fWëUŽ_oþŒ{ÞŸüäïÐZšŽ¤Iúvêͯ4k7€.°Î=®9øFIÖ¶3÷ƒˆÿ½¶ÆÓéöAmãô¿=·+ìw ±ýxSæJUl–sª¢¢ÌrŽ>ø˜Ñá1AÓ'¶F$3‚x@<™²|}ÁúâšôfƒÊ+cŽXc^“Y]kð ´Äµ!áîÑc¢éæhœ%“–ºr»5µ¸<>&Ôo ëÂÒdÒs»+–C÷Áܽí®õiÈ}ƒ !A@8ŒϘ}ðŒé‹'$“2ìY›°#h™cYÜpõågœýæ—læW¨%óÍjÕýñ¼Ý4ìv­Aôsîu3íýF¯ôcKá~s- ÷^¡ú8`ïy¯îÜNl?§íý]m[)Í›7HŒ¼a±‹«ý±,o8÷>ZœæÞù¦Ø^]«Ð5Øö§¯É‡ö²¥-š7iئkîš·Ü™+ï®þ¯*E¶Y£ß|MU¾÷‘1•K[âK¦í÷ö6ݸ| sè(ö·w­ñ±,õ/¢¶ß²›vÇ»o6YÃu7˜ë¥·}^OìÔÒŶ7qj9øVr-ðºU.N…Ù먯´t«ÓÚé=ŸÛ·yi€½™&tÉsQha‹RW”EÎââ‚l’.W<Îððˆ iv¯óÔö-­^H‚X"Ãp8 9œR¼Ø°¾X°93 _¬ T^Q&¯Jk„'„Ú¥äjSÕ£hkí»¨°»†¶Öíæ£ëßíöÔúÚ'²Q„L$ñ$!9ž0:‘ŒˆF‰±U·¼Ü;Z£ŠœÍÍ‚›¯¿âêË/X__§ëZà®» Ò·Q'}@øo ˇź7]·» Ç:uflÒá]γœ‹tƒºm}@ýNpðA0™ QJ±Z­mßMxô®P-ˊׯÏùã?þÿHÓœ¢(ê{÷ßGÕ¿·=!Õw¯†|í_vÚˆîDã˜ÙFnÞpôFów—ELÓÙŒõúiÂ÷®­kÍ\¸#MC•“{UkÍ® ¹tiï}/;ÍD*Ö>ÞãŸw»…°×kÄ…ÚÒÃË—ì^5POtªœ´RiF¶X2}þ‚É“S’ñ8-¾«±÷Q7¦ ,'„£˜øpÌ作tž‘]®Ø\®(庄¼2æX0mL%i%¶.y©ùŠjýêÒ0¾`qóB"E„I@0Œˆ$Ç#Gcâé€ ‰¢àA€ÔÚz±^³8;çú‹ÏY¼ymL[«tŸ©ãn ßþwᇅûÿ­ޏØM?‹=×ÝXê~Y×w݆ýÞig-y° pûúëÝ‚‚ÙlÂþáÈóœÿú_Æ|¾Øñí°ÓÎ=Ë2ÎÏ „µÖúÖøuð ÓÓ*ñáˆܶ>ÛTBË’Aëν-cµ®È tƒÓ|OžóúÕ›­¼øàM}Þ±‡ïjõþû€¦EáÔ4 t[C¯Ôùm-Wëæ%W¢MñyÂÓ mE_=L5ÏéªDUšÅù9ùfC:_0=}Æààp00–wñîygò ‚$&šŒ=™2Ùäó”ìjEv•R,2ª¼D]h´ãèmDJïöÇ®½W€ØÍ4„h)B‰ˆAŒ"’Ã!ñÑä`H8Œ“†ÈàaZº Jiª,'½¹æú«¯¹ùú+Ö7W”Yf5¹zfº ÛÇíkýàû{ÝïìþöCÂݾ[–Ù ì†o€Î¼xœ‚Úº[> wêO»wÝD¬ê¤¸…üqñÁÏøùÏÅb±¼•!qa'¸7CkŠÖìw¡a"šÖD`Ûr÷sÍEðÊ»ï*Åoöš¦AÝtÓ7%ï? w7àøø¨×?·´õæº[Ak>§í¢§À‚›§ñÙ¤5Ö7 ãôª0î9%ìVÔ¶>œpñµôŽîïµÑ¶æn~I›¾FÓº¡r°÷„V”eNUTd«”õå ã'O™œ>5›BÄ1È ®–.ÈwC›²È(@„fÑN22|:¥ÊJÊuN¹ÌÉn З«—”…¢ÊKdYQ¶<{ç(±Gƒ»-l=Zo•" ‚844S ãp$ÄC¢iB8 ‘Qˆ%ò´K+%Z£Š‚lµfuvÆÕ_±8;#_¯Ðª@éö£{Ü…=ùõw»wøßïÛþ¯ûÖá-À(qda¼‹ xØáåGïhKº›go.¨õx«±·íi‚Z IDAT¯ß#{Zknn–üñÿEQrs³¸3°Ãü¹÷·Ñië»îÕXîÜßn¼þ x9mµ]ižXáÍeÅ{§˜¶À“''öš›TU(‚Úm€³‚±_oåÏQ7hëüÊR35Õ @×ç&e»mcĘ[Öž*…²ÆÊÅÜ•µ¶/jbB­³ÓðÃÍ„¥²éò‹Ó<)ë¯ÝÂ#ªªPUJ™¤‹‹ó+f§§ŒŸœ³É8oAÑ.ºfç¹0öò¡¥m’ƒ!ª¨ UTTiI¶Ì(oRòeJ¶Þ × ³Œre"HãB’Gi¶$±D&!Ñ "Lb’ÑátF2ÏD“Ñ0BÆA-¤‚ÈNŒ>2 `A½,É–k6—WÌ_¾bqö†t¾ *2 êí~ÐF">ØÞüõÎkw…í]ýtß·wÇáÿêÉÇ`×ZCp¼õvƒ îîùösõoÛ7væï¾òigdYÎgŸ}R ­ïçøm¯ûýüú])Vµ?Qv×^à?k‡@^y·'i}ÂþöÁޢϛ‹ˆw6!Ç'Çöý®™¡§5™êÀÜî ìä†Y™©Œ N3nû¹ià¼IŸ¹íÇ)|m½¾fKÛÉ;4hiŸsæ’lùf× ªª Ê+ŠuÆúfÉðð’éÓ§ ˆ†ä…ôv`ê«é;´Qö"R ã9ÈR"&5Ì(SŠá‚b4¡\¬PKÁ–9ò=B|˜0G &C#†cÓÉdHœ Â)­÷IÑÉxxÐZ£ËŠ|²¹ºfþò «³36óe–¢ueGl>tû}C·®ìáîsͽ~š¥yf7dß÷]cê^ݾÛ/në˪ÖÜ=pïø´LV8¢[ù½ŸpÛ}uWx;ÚBÜõÎŽ·‹ž1÷ö½w{¶jX×X>» ôžgJ{K×oϵ›Þ°×^½¹,ö6!q3™ŒY.×ÛåPsäÞ{^#s‹Ÿ”RFCoiòF[(”H¬¶Õ  ¡“›g­JH =ã\h °ÂÈ7ªª­ye©t=°ÛÒRa㨣z“ ì3ÒíG”– ª,¨òkòÅšõÅÉô€ñ“c†'GÄ£áÀqòqî?ßw j™W“ì"ÈHj$â x¸Ë0@F¢ŽSFÒØ¡ Ñ̹¼­`ÛC•”›ŒÍÍ‚å«3oÎÉóz²´¦ùÌKîåÖ± ~}×Ìqxýkc&q.ëûv;®Ýqß÷}Ï7nv¤Ç¹÷`‚‹^›—Z‚®þ²Û@CŸºσBÕóðÐñçÞÿÐ>|~(÷n`òo¶µƒ®änÝó½Z©F‹×š³‹ý¶îJ)„Õà®´Bvvú1,|`¿)jÕ¸¦cäu…$´çºáË•F˦љX¬;2¡Ú¹&3|»e𵊠ƒ„ Œ¨ª¤*KPν‚hF Ú‚t}t«Aë"3¥h÷=m¨iýÃ8íÞo4(I•eiA:ß°<»b0›2:>füô˜x:&&»ê¶p¾/úß· Þ;‚¡¸ešS¬7¬/oX½¹`}yM¶ZRYPWžÒ`߬ºslî;®ù½?êQ¤ÙŽo@…h4ªÌ(Š¥rÐU‹¶è×òw ‘]i튡»}[¿صÖhyd7ˆièSj­ÝÆ©·ËÈ–ÐŽ¼îZ·ßÚo¿ñ9ƒÀ·»ì»ŠfwhâÓÈÚ ÒB•=qâ±M»4 ¦·*®ÑâÍDT–+æKÅt,ö6Š““c¾øü«Z›7× ÀÖ¡Úqè-J d=’±Ci-匥qg`&FH´}©( 貦e´YýÄñhxÀ`x@2ž!Tù†t½¤Ø¬Ì‚–²´+ЭÈP ·ƒ©VŽ·þêÝ®HÚ-$rE¨ 5ƒ´;*™<Ô}A9m_Qe9eZR¬RÖ7Ì_ž1<:düô„ÁÁ„hd@>ãìÒ2¡ÖÒKÊ4'›/Y]±:¿"›/(Ó e^`à5fÝ¿>*¦ê{ý€êývn†ãÃÙÉph²tÉfuÅfyM¶¹Bå]ûÿv|lÝÛþí÷vý>ðßíJ¤>Ê Æ2Ç_ˆVÇæS3ÚK›ëÃ>èëN޵Ÿûûòð~x7a¯)ä>f÷{·H²­8ûˆGηޱ?,è·@½Æ|Ïj†F[wæ 9»¬˜Œ:ÔJ‡š9®ywwÝNzš —ä´dm&±”L8[ðf!Jk©PJ …©-9£Ì¾¢Ki8ŽÞ6"!‰’1Ó“9xò>£é QyÙÓ÷ÏN“!B@‘gdë®Ï?çì«_°¼zEQV ·~Ðß ü5l=w;øß…’Ñò¸y®ÉCC¿ØòÔMù5eØ€þVšvËœùé»ôn5œþÜwkä»#»¿¶Þý޳†±¨áнþMû¼%tص¡5šÎ ìÓæÚ›ËŠoì¥fN<‹ºÚ»¨]úÒÐ@Nãn¶Ìs *§¡kûKi5}¥Ñ²h3@ËÈkE C‚0fzøœãßáàèá`„ÛG6ÑšaU2œ“Œ˜¿ù’ÅåkÒ傪(M ÚR4Ú¼BV·oŠMÍÜíƒêÑ4®ý*ûœ‹Sh3o@Y’—Šr““Ï×,Ï®ˆ’é˜áñŒÁÑŒx2$ÄÈ0D†5ýç©Õ×e«U^Qf†KÏn–¤W 6×sòå†"M©ò¥•ª-ßÉ {Ïl½àÛ¢FB†ÄÃã£g¿÷‡Ï>b4;&Œ½½Yµ¦,žŒ¦€FU9˛רJá&w[ñöýCÀ¿;BñÝØn×ܵ7™jþ÷÷{tuàüö—\yÔל pÚúNÜÛ£ßx ²]¡=„†Ù—É}Ï6D…9év @íÉSãùЯ@ç8¬áÚÎ.«[¥¾¿©Vèî\xIÑv2¸­¡#­Í‹5ÔB€´{ƙթF‹¢BHDZ;ŸæVÉ`tÈìø&Ïc2(Ï‘$“ Jˆ“Ñ`Ìüì%«ù%eš·Þ*Iο΀lç_KK½àµgÏ%@­Ô˜gë‘Qm/o… •eȼ X¦d7K–o®‰’˜df€>:˜LÈ(² …dhóöMá÷ µfh¥QE….+ª¼ Xg¤WKÒ«9éÍŠb“Qå¹ù«* ˜wµôÝ ¾›Šénï¨û® Ød:ãàé{½÷mž¾Ç`ßÍ×ä«5å&£ÌstYR)eÚÇ÷‚ßñ®ßð{žÑ;ÀPO§a2`tpÌá‹8zñ1“ÃS¢ÁÐZtõ‘$ŒÆO™ž¼ÏÕùçl6s°~âÛ`¼OÐt+­èuç‰Û€^×ó»€Ýd¡ÏRF5}Y7øQ{§\¡¶|Û%À¶áÐxo׿¶p§ª¹w·Ðcâ ÁùðØ2‡¬ÿo ¾mïî ªÄœo:Û›‹²·Qt|ô>ÿð‹_{yn¨–fu©[ê:™FQ!mZ„PíL …°Ô † ÒP:Z"¥rÚ‰Ø ³oh¢!ÚnxýzÐÖ^01ƒñ!A%câÁ˜ë×/Is”ʬ𳓫.Ë« +ˆ°Z¸¹Z9ÍÜ|Gk»ðI;Ó9kRé¨5§íö);i«)óY”+‰œ¯Øœ‡Æ›bÄ1ñt@<OCßÄ …¦P)e‘Qeª¬ÐJÑR¾ŒB§Ñ¥B%UZPŠ”¼Ø (×”›’j•“-RÊuF±ÉYhQ¢ÊUZKíè}#Þïm0kþº@ß~Æ¿'„@„!ÉhÂä䔣÷>æàô†ÓCÂ8ÙÒÖ»A ˜(†‘q™Q¯9v¡¹¶æún ÷ïM¨ôn‹·ÖµàlŸ×¶Í7RÛÆìþÛö&=R žœœ€®xýúÌëss¶’Ø ß¼¿Ü}+‘¾{K°•n4ͼ°¦ßbF@¶S97ïªfÔþ]\—Ì—šéØÏÏv#ùøã,¸»téZȸgÚø€qBÅ CŒŒµDqÒ¾R Á²óšJ)¤°LÕØ´#°Ô‹¢²{’º¬ì µ/ÂÁˆ‰|N â 7¯¿².b×説뱶 Q„¡…´ÕÞ…[à„ÄMÂîÝõ ·ï©}Ocç;\Åš‘K]»Þ=c{¯¨J*U^`æ$›Ë€0ah¼.J1èPQÈ ™^°©äù†b“R¥·ê*{C•UNš¯VsT’‰‚X,Eˆ(1Í*…*+TU¡+Ç›;WÄmÀ¦÷÷nZ¦ûüƒµv«­qÂpvÀìô}Ž_|ÄääñpBÜ}Óm0›„›¶hã浪þnïµÛ€¾_÷¹žøtÿŽjmK™)ZΠÊäöbÔ èõèÊa‰'@#…äÇ?þ„ÙlÄÿùGÿYæo_Øc)Óʈè^øFÂŽªýÀþhP×ô4ªvœõ/ßYYwÕð04ÀïMl8P×V@iïšíˆͯ¾(ù—ß ÷6’?ú'fZ‹üí÷ È ó}!©‡{6­n©Öv’°væ8€wîŠÝä©’&>i—8I4eY ŠŒ²,Ídì-UÐÐ4A4`0³\üpÂüÍ×,Îß.o(³Œª´ ÚièZ:ÉÙ½[ŽÞº°q;ªÊiãhY—Ò~6D N˜xÞê[ÝV˜™BU¥3à´~uD…9…Þê9›ò’uqÁ¦¸"Õ„?MrÏ^,QlС¤ e¹,IDŠ$&ÐfÄ$…¶îÚ Ýìºæ]ÞuÜ ø] §ýœ0&³A’Œ'ŒŽžpøìfO_0<8"Œ¯žw ¦=—f¤TU¶ív¿í—E÷íö3~Þûžìúma¢z4÷n?&þMŸ÷°A;l ¹V¦Sö¡²,ùÏÿùOѺ¢È ü,ô $Äö¥o0ôn½+¼5m½+dóº»#x€¸ž/ü{ö\;øµš¼öšk÷†d–ýúó‚²m韟œ3Y­Öuúš9òÍDjó]Y=j'VUe,[TR t…JTHi¡Ï-1ׯ•5oG (‹œÍzN¶¹a89&†'½m3kSì‚ ‘£A˜& &Gf²õêœt¹¤ÌëXcýÒpð†*²i³“©Îín3)køwp+…-ÝÕ§_Ãæhµy/¾~SŸk×è ¥JJURªœªJ)ŠŒ¢Ì(Ê‚ŠàvžqO¨²‚RçaNåTUFTAa\*våIÚ.0oûm@Þ@^øÙгW¸ö/"ˆ‡#†‡‡ÌNßcöô=ÆGOH†#DÖóCw Zkª²`³¼fyóš"[¢TŸÓ²>PßÖ} ~ÐoÇÝÕÜ{Í™£oÕøà,c´ë`Ø—mËõ±Æ½Íy‘—&Žº%«ös;Óü®C?&wV¨îNØã½Û¹Ìõþ UsŽ¢° Bt@ÞSæqßšTõf˵ÖüæóíIÕ¾FòÑÇðw?ÿe+åÚR ޝ¿!¬‹ßZ'7ºYZ¡eh,gDP7­•0C_é6Ù†( E‘±¼9çêì ¢dÊäð” HêzK¹UD@FDƒÉø€áô 7g/Yß\“­VèÜšMÔüº“§Æý€žÎ!™Caün^Äÿ²º¢®÷ÀÓ+Þ=¬Ž¥LmQ3”VÞèîaÁQU·G»P×±ÞñÎ6Ø?„w¿›h¬!¢$f0=`úô³Ó÷˜Ÿ’Œ§‘Ùð}·¿¨ž²ÐU•¤«®Ï>åêìS²tÁ¶ïø> ¿ ¬ýcûŸõˆÒå­}€èãZ©k»;™Út—ŠA»×—Þ~Ác‚è\yW࿟îñÀ½ÿ¡}–2÷KDoì­{†ªÖ4ŽºÍ}! IbNNŽ)+¸¾YPUÚ:Ïò'UÁqg®ãÞ­Ä­AÅõ¢äâZq| ö6’?þŸÿìž5O ñµÄGX¸nÑ’u ¨j×ÁZK„TuÊÑ!”±R´Ü;ÖÝ€YÍY†t}Ååë߆ Éxz²5)æzß¹ù¶$LÂñhB2=dþæ‹óפóòM•B9]YÃLëÐÌsòâ T¿ýt7 lšxW#wŽÑ¬˜³å*½2|«Ÿ»Æ;>4è­¿¦k»ïú¨ù¶öîßìÛ·sðÝ4¶ÝĸŒ'ŒŽŸpøü=&'ÏÎ æ¾ ´FUéꆫ7ŸšELׯ©Š¬Vdšòr%± êwëvÝkÛï*ÕP2;!ä"˜¾¦ïÓ«ì9ůUÆöÿV¼½DbÝ ›=/ÞV{4Êìd2¢, kµWß¹5þpßl•´wnuÓtm0Âåôô„ÿùù7\\\ó_þËŸs3_RS2¯nÝjŠõPË÷-ãfÎÍßo¾¬8ší^̤µæ£šwwZ©Ï»{tPk‘S3‰*,ó Œ]»f"U™5OÆ'¹°–4(«É;5UžÁõ´”EAùüwÏž%Cã÷¦SY»€Þ‰ c’ñA4$ÍLXœ¿bq~N¶\ óªÊ³dCËh«qk×¶]Þ)eË«ÕxTnZ‡ζVoGEø­ÓÖcÈõËÃC;^Éz“ÎæÉ}éÙuMõÞë?¶ ÆÄ!¨yõx0dxxÈôésNŸ3˜GÈ ¼—¦^çGkª"e5¿´Àþw\Ÿý–"[íð#¿ ¤w öïýqô¿«tµصF$ßj¨›V¿wåO¸öݲƒwÀ^7ðVn§Ýk­}2î!Ž#þÝ¿û·|þù×üñÿeYÝ9½þÜß¶~—Ð|Û,…7=Ä ³ËMO!×!Ý"& à5È× ®kîý×_”ü7ßoìÔûŽÓ锃Ãn®çFû®aÈ6$¡­Ön Ù]•Yƒžƒë€L{¨lT$R‹zâµ²ÂC£ çjCuõ’2ÏÙ¬–?ÿf'ï3lqªû¸øúž“2Œ“1Ãé!£ƒsçoX__‘.W¥f“`­-íÒL¤ú`ÝÔœ›'ñE´s~ÖÔnWھ愂«]¶}‹€ÚÃ燇.0kœ°i&å£\Ÿ¢x °wJ÷·= Œƒ¯0$Ο¬jçx»û,Ñ·kPwÔL½XIc©UÇé>± àÞ_ úOªwm “çÿé?ý_(UQ–êö¼Ð»BuŸ äÝÂ]gâkïyߤ]ÁùúÍôGÿ7eYqs37«pô%®¨g¾=ãM¦ÚNêWø§_4wÀîÆòáGpsýs/ÕN#uNÀL>”6n|k']"¨é§á›IÔ,oܰ*†s¯D…ClX+-ŒC`…თŲtMº^®=ýˆÑì a<¨8™ôwʼ î¶¼… ‰†Af Ÿ°ºº`u~Æêú’|¹$Ïr(]J¯$ºÇ.°; š»¼F;Gi-ŸûnÓ3}mè!¡‰½éäÞÞ£Ú€Ö¤íþÀ~ûaÌe ™žû-«Å9U™¢uÙæ}eДãîçïôþÕö³•¾ÛúܸxÐ^Ô×-Ó6ºh´|í}V{àß仾ç_«ÿº3O Zk²,¿ýÁžð8Ãà­pŸ†åwëÛßͲ”/¿üÚh´H„Œjð7@ÐtÄÆÖ]׿}*ÆÀŽ©Åªâõ…âôx¿‡È>ú€¿ýÉϬŸôF;¯¦[¼ƒqÓë|̧_¢^è#o'U±‹› È ”¶Ü¼PT¢Ù¬CRQóð•Õ_WsÊ"'K—d«Žžý“£çă AÕ½Ðû® „ŒHÆÑ`À`2crô„Õõ%«ó7,¯®É Ê,³‚Ét“ïÎ*]˹û njݼGsøçŽþp©ò5÷PÚ4ÍãƒöÎ|Òåù-YØJËþsnö6ÝdLfÍ{"H§©2yò„ññSFfs” |8¨ƒqpWæV7g\¾ú _ÿŠùÕ—d›•2ž*Û¥ÓÕÅwý]žßô~Y´ß­ªÛW–‹ð-F˜ ±m;ñ@½Í·[`ïÔ³Fãæ´öÓÓ´ÊíÖw¯)ãÇ….÷ðÁý.« èÛ×Ú“ªíŽ«Å!܃N‚:­]׿4vCÉ4Z|3TSµ6ÿé—Š§G»©­5ë#‚  ª:Et*±Ñä €×+YkkõÆj&¡eâïÒlÕaÒÞXEâ ï{UV¡Ê’<]³YÎ9|þ»=ýáäÆ;W î|È@BÂd@2™1::atyÅêòŒÍÕ%érM™fTe‰p®&U£±¸<½IA§Þ¥fšóæ“LoÁP‡y; ß]«¡fdýl°ú}ßµ>`ׂڤ1Šc¢ÑáÁŒÑñ&ÇO ¨‹‡OŠi”ÙfÁââ+.^þŠËן²š¿¡Ì7TʘƲ•~—_W^í£¿ïùî{ÛÏ·ë°‡R·û„"þ6ôº¿jØÀFƒm¾Ý}¯9o§·çþVÓëk‹÷mŸ£|Þ¸?jÖÕ„-ÜoàÓ,²ÔV4ššMãk¸v ªï^›E¡ aÍÝ̤êûûr'°ÄqÌ·çc~õŸÖ÷ŒVÞæß±æ¦!5fõ‚%¡kGbB(a€Îø3@/œ31í&VmÁh«! £ý*­JST)UYRåézI¶šsxú1“ƒS¢Á5È÷M²ö<&]AD44 ?ÏŸÍoX]]±¾¾"[,ÉÓ Uš£°Üe¡²¦“Û:Îîkæª?qÙ€ü~møñ¡|©Ï›ôkî>@ÝàMúk+,) £pÆ ˜3<<"™L‰C‚ÐìUûpL7ý£ÈRÖËKnÎ>çâë_qsñ%Ùúš¢Ì¬¶Þä¿ °»žÖÓý@¿O@´ÒÙS§¥*öú“qG3™ZÑšD­Û}|Ú¦]w5¶´®‰ú–Ÿ³NÂÿÉ„·îme}¯úÝÜ]ràí/fÂÓêèÀ“¼þª³o·€I 9:œðßû„¿þ›_¢µâ³¯J” qÛã™Ïê­†óý|_ýÃol'o¾$®„7Éê¿ ìŽšl65ìØ† x£½b¨cùbTÃ×:˜ªïŠÒ>§…±¾H1„ IDATšqv6•6f‘8>ž&¿Ø­J µ¡º14Íj~ÉìäŒÃÓ˜=g0šÙ-»—Ÿïãå*„qB<š2<8b|úœb¹`}}Íæúšt± _m¨ò‚ª¨pÃ]‰¶£0;ŠØâÜÛ öÞ[;©»,oKmòãkÚÓÜu§=êÖyØÛsûš”‚02Þ0ãñØú!ƒÙŒd4&Lcùb]<ʾÁR0yºf}sÎõÙç\¿ù-Ëë—lV7TV[÷¦ÞÊ[s¼ 8o Ú.p·…D_ýµFNZS©ý“©Zkdòm´ˆÑ*oõÿºÝôR5ÊK4~‚šøw‚·-ß­KýOÞÞ¦ºð–'Tï¶õ·æª-·x÷¼°6{ÂÕ•&œO›žZ¡•"ËRþá~…&BÆóá_ÿ}É·Þ w;pûÎw—Ÿþ¤Ïj¦›7hÒf¨—W;a(¬ÖÑä7-\¾ÝL¾µ¸Q;ÝjàÐMºb‚ªPTå‚"Ý®nXß\pðôf'2=vTMØKÕ´jgW µïÉP‡!Ñ`ˆ²¼|¶^“Τó«Ío(³”2+PE •3;ÓµR„W’þd+®€-M¿vµ÷·Ú µmWï+xÿ»3U¿m¾])22ÖHFKŒ' Hf3“±q¿ÅÈÀŽÈ»k‰6æe‘±Y\1?ÿŠ«7Ÿ1¿øšÍòŠ"_P¯¹èv~ºÀûP-|÷{· æùRå·;€ý‹6¨kãC¿ÁO9tGMCÕøtŒnRÔ-“æ~ßx±[w oØáÞàÞ?9w¿ÐÁÝ·šî^+è~!û¾e„L¼Šªy§ŽsWJAY"YWêßÿ¦"ÿÂ`wøÞ÷?á§?ùÎP¯N§MG£MÓ\w|»µ²1ל匛hµÖ76/Z vÔaWnІži—%¸Xµ¢ÒŠtuM‘nX/®X\qtú1³'ï3œ™ÅO2´‰m[Öì¬=ï¾[¹,‚!‚8"Rf§”é†|µ&].ÈK²åŠbRe¹u‘[yýDÛQðòAÞ؆*éŸÇ]ÿÛÒä<Ë™všÚ`îê^H REÆ-@8HˆFC’é„ÁtJ<ž Dƒalv£zÔ©Ÿ ×ÎË‚t5gyõŠ«×Ÿ3?ÿ‚Õüœ"[RV†‚ÙÖÖ»À»”·½yfûº/ vÇÙÿ|±‡’©Ï‰ƒïY;øªë¶»9Òm•S ÁÑ5M<¯±¥òvÁo×Åí7ß>¨»pp‰ØƒóÍMàþt[#]µC7ƒ‚8GŸŠi,güaZ³bUkE–Wüý§Š}g¿Iä³ç§θ¾ê.h²ÂÄÛpÄ ã!° KÒø4à3«¬M)í=¡©¬]¸ô];àsFþ4ådÏ÷Di„˜6®‚ËyA¶Y±Y\±¼>ãðôC&Ç/Œg„QbÒàü}ƒ°–=A( ‚€0I`:¡:,™9eš‘oRòå’t± [¬(7)UQPæ%ª(ÍB)»` mKÖÕ³ÕÜ}ºÄ×¢Þž¯;mžßiîÆÇ‘yÞ dÌîQ2 ¬†& ñxÌ`6!™LˆÇ#Âd@˜ÄÆo}àV¿­P/)²Ëë æg_pýæ –×¯I7sT™ÛQ`w΢/ï÷Ѿûžé¼û¾O@(­vZÉøçÁèhB´n\ü:3H_›$|ç;3LBþê¯~jÚ«c­-œ4í°ÖæÚv™u+d_mÁ»v¸3¸¿ÛD´1^xý;Ø{ ¦í<Ì3Ôº>÷5x­+{n‡£èÿä—ŠþîþÕªZk~ï{ßåÏþä/[iª—Ü讼¿šÓ¤gÿny½†]oìÚµÓpNƒ=í½æ¶Þ= *UÙg¨ ¥y©PEN¶Z°¾9gzòÆl´}ø„xh@^rk…ãmÚüV°4H¤ cý1¬*ªò˜2Í)²Œb³¡XÛ¿Mj|²ç¹û ]–¨ª2‡hИ] Œ_¡-Êîq¡NB[³D@€1%5‹@F2 "³ÉH8ˆ ‡C’ñ€p8$ ÂABE‘YAì¶|[{ÅšæîLbWlæW,._rsö%‹ËW¤ëª"µ·öÙÛ³uôëîZû.0¿èûßXðìvè§dœÕŒïŠ@iMºÉPeÛ@¾1´ßÕíÜv~%Ûƒ0½~ÿ݆;€û»NDÚ·®jš½Iµã¶±N“<íJ»%«Í„[͹דªZ‡žh€ÖŸ~Y±\KÆÃÝÀ®µæ“O~?û“¿°+.i¹«Zå&A]ú,(;7À-‘ ›w•›tÕ¼EËWÓD'j€7hìköö]Ršª,)ò ëù5‹‹—L_0=yñá’ÑŒ(I@<Ä7IOfÒT u32Ðv˲¤* ª¼ Ì ÊÔ‚þÆ~Ž*rªR¡ªœ¢(å•ç”Y€P*šÕÊI*;´à&±Ù6† ah@ZÆ ñ(!‰GâILGF+CCµHã¨Mزh¾õø`°JQ•9…•Í/^±¸øŠåõÙê†<_£”õm #¦ô?½ïÜ®µï´âê=к×g%³eÛ.§ÈäcTUÐåÏ›ßV¡«J>ûìK´*(«.í&ë½”kà®êvj½Za×Þ=¨»°Üße"<@¯Õ£î-,i »n4vûŒ0Ã(7±ê´vW©ÛÔŒ¶•\ÕZ¼Óø•RüôWšÿî÷w;Àt:áÅûÏyùÕk r²>¯)šEOµ†­·¹s„Ämb*„GyZ»ÓÌÍWD‡Æòù•Ñ,q£Ëé[5hE¥5:Ï©Šk²tÉòæ’ùùK&GÏ™=yÁøð)Éhf|Î<ÈU¨9ziG)24îÐÖM™¦ËU˜­ë ðç”yN‘¥äÖåB¸ Wµ*©6U–¡ÊøQé “˜(’ & ÆŒÆO˜ŒŸ01͈‡cÂ8!HÂ0&ˆÃZ#—ra¼5Õ¼lۮʂ|³b}sÉââ%7ç/YÏÏHW7”Ej"i´¡´·µåÝÚö>mö>@7;±mßìZkÂñ¿°ÝÞtKso´÷šª©Jkú©=ðVöÔ½¹×J«ÞNwë'ôüöµýo.ì÷o*] ™ö×ÞžÌõ4ÇskôÊ‚¼o÷n4v3ÉZ¡uàÑ4¾V_ñÓ_(þÕD·;vÔ'Ÿ|——_½ª½6uôxø®f.DÓ ê­ÿ¸ÉT‡¯­ „i¶„‡kv5È[KãÀ™6þ\jJã£Ch….*ª¢ OW¬ç—,.¾fzüœé“ŒN­&?4üð£ì¬·CãJÚhö !’ØÖ|³±ú(óŒ4[0ZÍX,†ó9—ˆ•@lŠG¤'>˜2 ™LN™Í^0›½`:=e4>"L‰ã!2ŒÌêP)í(Ô-ßa·ÑV™ÑJ¡ÊÜÌŸÌ/¹9ÅòâkV7ç¤ë9e‘6 åM›–âOžî¢ghý¾ Ðï¦iöSwú²Ì÷öCw”Ã?¨¼;%O7t”7ÏFÏ}Ç®ûÒÝ[)Þ3ûüÉ|³À½àþÍ{ з®j|WFIwç¢ì-jF;jFw¨ÐÛ´ŒÐŠ7—Š×—!§GÍJ¸^Þý“ïògú¬×) Eb.uh—çQ|»xáñéÎþ¦Ù ¤)+ÇÓSRÒmVþ¹7Z@Õñ™¬Z£Šœ´(ɽáýäè”Ù“ŒŸ2M “Q lokp+xZ¯›82@D È$„X£Ã’"HÉÅÊüÉ5…›‡:‰GŠd:!™MHfc’ɘx41ÔLhè*é€ÝOöÃ?»?Øö§*³Õ]¾^²Y\±¸|Ãââ«›s²õ‚ªÌvÐ/° ¬Ýóö_?åž÷¶^o=¿_ô½Öмh(™&ÊÑsOAå-…­zß¾Ýß*°Á sÁ¼û>ðóëî·*ª‹g}×ßuhëÁÎ}_f- na½2')ëeÿ  ëà½IÖZs·šrÖîÓ2Nƒÿé/þÍ¿ºES’?øñïó§ÿïŸ×]7T›¦xýчãñeã?ÓzCÃ4æ•æ?£¡;K÷¶¶ãΜEŽ› uq{+EµöRõf&¥&]ùÍüšùùkƳÆGO™=!/„aœ4”Í»TYñèœzBÓRÂR<Ò?ÀÕmçC"M|õw¼ûß@_5MÌ¬É¨Š‚"]‘.¬æ—¬¯ÏX]Ÿ³Y\“§K£©;Úa/8ߦ¥7àÛ'v~ß;»¾×Ä×ôÝ÷!+RókO?ÔZŒÿå³òöH3¢wZz›’qïlð@¾ÉCSa['6üã;|ãà¾C[ßÂtv4{¨sì§f0 ØÑØÛ“«Úÿ­*´¨øù¯ÿú›oìjX?øá÷ø«¿üë’³ ä>MÓÜkž1 íÀH4Ý(uܼ‰Ï=è€[[-¼áâý¥þn¤ƒüø€®ñKµùm}YjªrNžnØÌ¯˜_¼4<ôÁ “£'ŒNŒgÆßI[`}»´\oŸ´iµ6 =ø+hOз¼`ÛÙ#?±ë˳è©R¨ª¤È6ä›éüšÕõËë 6‹+òÍ‚"OQeqë—‡}ð5¿ú@߯™†JëµÕø²Ïè>0gëè½Öª¶’Ùì †?2}Yù–1Ç^S1xÀ®¼ºn@¾©ïn{*¬U&ÞØYÃ6N½«à+xíð ‚ûÃzE]lZX«X¶"„]¶cýž·(-[”L£Éû|U7 ! Ø/׿ú<à;ív­5Qñ£?øùç]§´ äÍE²¶¯mƒ)#¤ka¤j;o&†s7ŽÅÚ4L[n51ÛiíÕ‚B÷ °¿T«’2OI—7¬®Ï˜¿™ØM=ž0>|b}ŠOâA)ï@£oÞÔ§R•µvõ±_°âÍÆiâ÷Áâm/Xa«•B«Š²È)6Æ»çææ‚ÕÕ9ëù%ÙzNž®©ÊÜn1çÖjÜØÛ«zÛÛþ»¯¦oª7@)dXO¤’ªÊ)Ë e™¢Tlê˜ököY±¹Ó¦rø Ⱥ2î´jhÖ–Æî lèôkk;§ºErJÆ ª¦,\;ÎßuØ ìð€û]3Û€ã.jÆ\·™qÔŒëpv;:ŒÆs¢iÜN5 .ÑÖÑØN ^WüÉO~÷Ãý KkÍô}~ò×KQ”;i˜4´q &ƒ˜8ž$‡ †Dá¥ež’g+Š|MY¤èªñ¥á6žöEˆ?íŸ÷?ãÊÐ/Ú¦a(]áL/Ûko+„–µMe-46ókoŒ¦ fGŒž0š’Œ'„Ɉ(IB³”ñX޾­Ñ5Àk,ªª´¿§ýUõ¥~‹ÖUU6‚ Ø·ç=²¢­|³Ø¨Ì3ò4¥Ø¬HW7¬®/ÙÜ\.oÈÒUžš´Ôü°š]ÀÞ^Üu0¿;à›ìKÆC’áÔL8fÄɈ Éó5ëõ%›õ›õ%E±¤RUÓ;`îÇo¸öôV`×ZÎþG¶'Rïð°oû&rϹ4x­.N´ÒÝýé÷÷áƒûmÀë$[˜î–f5ÓHTCÍ: ,êáWcþ(¿3–‚Ñ:D(eÏíĪR|ýFñùKɇϛÍx»G­5I’ðý~ÂOþúg­4·µa³RH¢xÈxòœƒƒ˜|ÀdúŒ(™ «Š,[°^^°Zž±ž¿1"K­6âò ~#jkóííïÚÂ@lýö÷=íN¼vÄÎ|Óhóš\)Ê<#[-X]_2|M<œŒ¦Œf‡ ¦‡ &S¢]•'A€Òš†Þ ì»å­µ¢ªJªª¨ÿÌDbEUýàö÷„ªú¥~c…Åvü. Î{èLDO«ªRTEN™géÆLŽ.oXß\“-oÈ6KŠtM‘mPª0VB¿+°÷kÛ}¿Û Ý}® ÂÚNwd8 ΘÍ»ÑDÛ´LÐÑà+„®ø“ŸH>|¾ØÝùïÿÁøÙßþU©vjïB¢(a:{ÁÓg¿Ï“Óï3;xŸÁà LÐZQ)y6g½:çæòs®/>cqýŠ,½¡*ò¦‘îð.8·Ÿ3#Y›VvSÙ”v[iâvBÀl(¢ÐèÒ€mž­I7aÌ< F$£1ƒ‰Ùx{0uÞ‡„QlWk†«N0õ~Ã}WVS/¨ªÜû+,àü¨v¦ÔÇv4`@½,sÊ2·_ÕmEëmk›P ä TeIYäTYFž®ÉV 6sæ›å’"[S¦Ê2CÙï8w´}ôÊnJã6mû.Çý«W‚ ˆˆ’!ãéSfGsôôw88ú€áè˜02Z»)ËŠéÁûLfï‘ Ð(Ê*#MKŒ»jhÚš§µ£ÈòWï»ÁÁÿĶÆÞŒÂÛ©Û+U[î}}ÀÖ€/\è&µMð7oy×á~#ƒwîõ¤´Q‡:cföÉ^±@å:ƒo©}›÷ö„ª[äÐhðìëß¿ý:äë7‚OÛ`ÞmdƒAÂ'ßû.?ÿÛ_´òP %!2$stòž¿÷|—dp@4«D13šçÜíYßµ{º{öEšÑÌh$$$À)v™Í†2¦@¶!¶e;ªØÄWâ2å˜Å6å vÙ‰lRÄEÀ9A†àÆì‹Œ$$͢Ѩ§§§»§»ß·ßíÙîzNþ8çÜåYÞ÷yß~»GæÌ¼}ïsŸåÞ{î½ßó=ßßVYb³QîxA‹ j¶»´º}¢Þ ­nŸ Ó%ˆZxAˆxAh<D9€kmÌ”*J`Ïó„,‹-ø¦”ßr÷(õf”Ê-¨'äyl—ÀKiÙ;.–€¨<3ìÿJÕ3CVþï~С¿zͳoauý!ZíuåÛ¾ _¬«ÁÐϰÏ;ÐNîus—k¨ÎkµZDØëŸÒX,ƒ²ì0%îj¡ýš¦aµ.ÏÔA]%Ñb:øÁãâÍÖ®äÌÚᵻݽùQ¾ø…/•€FŽ‘RE]úý{é¯X)Æ æLí…Õ4=‚ ƒïøA‡V{ÍüÖEön]f4¸ILýRôL?4–:0ëÆ­rÀOõërÔ6·¡œ+c¤Ì“ØúK¤ç‰Æ79Îý0"ˆÚ­a§m+…H_¢¥¦P)i6bï1žì÷Iâ!Y:!K¿úè[m‰–¥_Mêÿ4þ$ÂRùjòQB ðD€V•¨,%OMœdbòÖYJ‘%yfÜ­{ž³¦Ü0¸—öùûb`_$·Ìn·céãûíÞýµûY?û0kÐ_;G­àù!Æýuþ³o¶{„Q—Nﺽsìî^D$»V9­ïßhí…ZlãrK\Àk¿U¤Ô!´.,cŸö–QåçæRë@ïŽËÙìÜ•*uúnoÞïU;>ÏéÁÛú7®ÌÞÂ6ªÚz5}KkªlQöÁ)|äêÉ.åmò°ý½ ê¢&ÍhUð»ŸóùƯ>ºêúÛŸy’‹/¿b‹hW²ŒÆLi£VŸ¨ÕCzáýfµgµ<|?$Œz´Úë´»gØ»õ û»WIF»dY …ª$ m]»%ë=>=Ô{>øO_)Êu7°U•–ÜgÑNO¶ï«Œ"KÌuiY¢ ³ô<°ùZ´P"''!ÍÇ$Å€IºOœfšB¾÷þ\¾ê+™ü+ŠñuÒƒ“`Ÿ“Pv Øã!µD(ŒT”çÈ ‹tž0·tg¿Xú˜´·ì³ÌsÑgfar! /"jué®ÜÃú™‡X;ó(+k÷Ñînm„\.ç#+¾ß2š¼PÝ)õcTÄÉØôÁ!Ϙ֚píëJ–^ú<ÿö¦áTSt²`^cãQ+"Kò¼ÆÎËÙ1”ì=ÑOÌ=wÛ¿p›à~¦$3ìÝ­Ù¬é´3¬º›ÓÜ(Æøj–‚|©³kϹ’há™›CÈF “pÓ~Ð&j¯Òí¡ÝÝä`ç2Ãý-’x@‘§Vw¬ƒõ¢@¥Ã4ôÃÞùÜÔeŸY0ŸûªzQ½®’( € {½ J¥ˆÔîC˜¤l …Ò)Š”TŤjL’Iò!i1†ðOô¢å:õÈ1?Ã$ý½}"oÐëzBÙÂ#“¯,ŸXݘÖ×ç½×ôù^ öÓ >oÛôòøM¦(˜Äó=ü°C··Aí^V7bmó!ºý{£žï¤Äånâª[ÜsYÎÚ1L’ñœín©µF÷àwÞj²?ª+W9åŒ[UË*i˜uÃ,õw7[`~àûÿÿ™_àÅ/’çyÙÇÎÏø Æßv;¹ 3ÝÞðª¦Íã“n»Í”8eX-ÓÔj—NVEycØ 'íJð +_ú¿«¬4£•‘£µD¿ÿœÇŸøÊ£o¾§ßþ$¯|éƒÁÇ•Í{¹5ú̹GmB„çöè†ÅwÖéõϱ¿s™ƒ½«L·HâºÈl‘×Ou°> Ä—x±pµïTëæÓõº£ó@¾1ÕÕöì ¥uA¡rr•é1I>&͇$Å4“©„vÿ›Ž×¡G4}“ý£dŽòs Ï,µŸ…– OúhááÒ7'Їú4ðóùdÀ®f¶»€:éyQ›vg•îêyV7`uãº+çhµ×ŒaTx'ȪÑÊxÊäÙ„¼HÑ¥æ&h,I×ÚÝz°úµÆfaŸc]2SÓyd*_÷&“w of.ZkÒ$åÇüÿäÖ­ë±äÞŸ#‰è'æÓ%Ë'÷;mD¨ØúÌö]ê£?µˆUë²g#V¥¾ï‘sÜ"ëîRJ™ïZ …¬txQð…‹ï}R°ÒÕ‡Þ|RJÞý•Ïòïé?”Ì@Sç1I¼Ošš$OÞ‘ÒÌt3¹N¤ÑjûA‹¨½FoåýÝ{Ùß}ÁÞëL†;¤ñUdfßµ‘d9€ŸÕÙ™úܼmÕï»›’L};Ìy÷Yí&­)tF¡3r€È'd…]W ²õA¼àÑcôãÑÍ E¶>Dÿ{dá!ññ„‡‡)Ò!Œ£;r1E>õÅ ?ûò4›¯¯J¿ì„-ZUº+çXݸ¯õÎ:AhJ1‡­7zB+²lL<Ùa2Ù!ÏÇÖ‡½:¾q<´Õ¡vá­áwž¶FNŽÉç³öFtê´ûc=*@Q(ŕ׮6ãc¿ËôöÚû·ÝNSOPCõ.4 ˆ:Kœ³¦µ5¬:À·ìÝyk žäüù3¼ÿ«ÞËÏýÜ/[€w:»eïʳ ^›Þ ¯”dŒE^RˆœO>ðÁgcssn>·¼ï¾ <ðàý¼vù*`\øÒdÀÁà*{—étÎ =“|ºêÑQÍ#=dØÆóB¢V—VwƒÞêyv¯r°{…ÁÞuâÑY:1Zpéâµ ÀôÎÎÂÏM3ô:x×Í,¨Ïy³nF¥ ìÈ35!S1™ŠÉUB¡½µï9Vÿ-ÛZ«ßÃpò«fžyáC°e'H›uöwæGz}}[gîöÛv@¤gí@>Ý•³¬¬ßÏÊúô×ÎÓj¯F¤çs˜Áôðf€=ÏÆ ‡×ÙÝùWH“!eÑj4ižf‰ùÆ!À®µ&\ÿ ¹7Ê©5æ>ÍÚ•fÚ–V¢5Ü«ˆÔ¢¶î®Nc}æ §WNÒ±5Tmš­OÁ‰ðæñèkjÞôVšñhÌöÖ6õdbóÙ»«Á™ÆH2u?øç^öxòQ³ë•quÑ*â€ì IDATTòÙ÷¼“ׯ]'Ï i6bpp…­­Ì4× ¤<>À»~’ž ôºx^‹(Z¡Ó;Cí‚ù+Œn0î‘§ã‚WNE|Õ³ªëFðR ÔbêýiàojñpÈ[éÆj¡Š¥sŠØãò¯P …J {FzçŽÙwË5éŸ#ì};ùð§È…gTåYiÂ^I@h$žQ— Žõ |©­æ°œÏû,°—®ŠRâ!a«Gwå,ýõ ¬®?@oíîAصFÏ“‚º{. òlÌ`ð:Û[/°uó9†Ã«dù¤Ô»µVŒ'ƒò;ÓËúºÝß}‡™UëʨáE¬½ÐTcí3yd¦¯Iy9h¾°3ˆ>ìÇAú;‹©Þ³Ï>ûw÷÷ ‡#Æã I’’¦y9 ¥!°¼Óë§Õ¦@N¸_4^›ãª>#Ÿ%Üh IS®\¹nX»{"Ët®vAið,_=Õl“å¶í½€'u‰æ»Öš0 @Àõ×o˜ÛÂÞðªÈç…x^ Oúeÿÿar×HâùAØ&l­Ðî¬Ñꬴ:HëKï"íLsLÛ-«_cj}ÙmÕºž³½yÃ×_‹:•lª°¬=%W)™š« i1¶ë1Jöèl~!n¯úÒaÍ ßF2úè‰y%kwµPËkf †‹ >ÔëïÎÖ—ñùÀnŽÕÑyV~é­]`ãÜcœ½ðVΜ{ k›Òé!ˆºHTwr¶®Q*33Õƒ«lo=Ç×?ÍÎΉã]”Jq3I2"›*Æá–Ím‚Ö¹ïÙµàn¥Óúº®dš¦;¤Tmé‚—* 7@íp ^;ò>u¦Ó+Çmóû·žo¯Z ¤Ï“µç¸þ,kÂÐ§Õ év[ôûVWûG1÷»$Ôûªs¿z«³÷9ïiMÓ-²ÎÞy–"¤o£~1«`& pìÝêîf›g5øœ·$Ï] xâ‘ÅSI·|ü‰¯à•/]b(²lÂhø:[7%Jå¤éˆõõGéöÎF]¤ 8‰¶é¾#e@ÔòñƒˆV{…Nÿ,½•{ì^å`ï:“á–©Ö“L(Š í®ôa’ËìÕ™Þ•a´áúHÓ`:O’ÑöSåôW›bÞ…ÊÈTBnÁ<+ÌÒÈ1í¿ÝcõÓq›]Úë›É­ïG(#ÇÈŸ5]H$¦P,•\Xë‡Å >ýú¸l~Þû€Ð¤¥GF„­íÞÝ•sô×/Ð_=O»·IÔê#½)Ob,­ZÉÖó˜x²ÃþÞenm¿ÄöÖóìî^$žì˜{Îú”*'NÆK;+ïE†@et{ÃAJ® ×¾Jö6ËÚ·ŒôéëÑ8™Ùm-Bôeþx}ìy’~¿C·Û&ËvvöÉsµÜw3÷ŠMV€s'˜û4˜‰©Õzä%5öîVEÉNªOÛ»î{îø…W½žËÞ«õÊmÑmslFr}ǰwO.v×VVû¼rñRùºP9y6!IH“}ã§Ž6)S¥oC¸OÂâ)¯•ž†¢Ö*íî:Þ:a­TœÉ¿îX‰nô«åæÕ¨o«3o¬×ot½ð= 6ϼ®»J)Tj@Ý»cì¹Jð;šÖÊŸ;vÿœ¤yÁCùEú÷ÐZà{šÿìCïáæÍ-Æ£‘-†]1÷Ù ¦:k7y¥fY;•\©kýîlw ¦<Í.KÛîcQ“ ÕŠxè¡ ¼ûÝOòı½½ÃÞÞ òæ)aš¹w—aîwºq²óû {·'©Ýæ.‚Ó”µýˆµÅ4{wV ª@“T¬º9$B ´ðÐJ‚ȉÁï|¶ÅÞ5Ÿy¸¥Öšsçîá¡GäÕW^3¡†,S ^'KGL&»ŒG7™Œ¿‚µõÇèõÏF+µÖ“¼É³-iu|¨M»»Foå<“ÑÛ ÷¯3:Ø"î’ÄCŠ,1Yµ¹±çkîÕ6wõš,Þ\œùl½’m*¨7þíª4 *”õŽ1 )¦°2*A{÷Ò^ÿ¾c÷Éí´öú÷1Hþ#¹zràu¹¯ÐTe ƒB˜{JÔç:<êÓŸ9š¥—ãŠ'‘^@uhuVèöÏÐ[;Gwõ<Þ¦I/u̽%ý¹)ŽÓŒc´õÉx‡½½Kìl‘—8Øx²c5ö¼ì&W{V+Ÿç–óž¡öæ7€Ð*#M2þÝ¿ûƆ¤2û»yÅÔë©j)\ðÜ|ÖîŒÑöZÊÚë³Òù[ÜŽ??{voø†?Æý÷Ÿã3Ÿyž½½ò¼8ú˶MûÝ–aæµy£ã´(`—åêl¶H'Ë”@_‚º+êá|Ý«V¡%Zy äÒ5yfú'¤ xòxá•€·>ìqn#_ìnýÙw¿ƒ[[·ǘ 5€J £É’xŸÉx›á`‹Í3oauíAÚMü î†v‚®|èùøa‡VgîÊ=¬nÜÏx°Í`ÿ:£ý›Œ‡;$ãy£UŽ*”eÕÕc0_¦qÿ-É8Cl5 ˦ŒqMéœ\eäELV$Ô+Ö^ÑÝü(B´NÔ'mB´èl~”ÑÖ_• Šú,Ñœ«FãK øv–§ÚFJ—m?­Ï‚º :HiÒ[H?$lu­KãYzkçé®ÜC§·AÔî›{©ÔÓÍÑŸ¼™ë•ç)I|Àpp[_bgû ìî¼Âx|ƒ$}½ÆÖA£TÎhe6Õo<Ù#MäEŠàIÏh¡ò¤W×]æx¥4†W?h ¶³J»·A»»NÔZ!ˆÚøAP†–×m…Lêð½Œ$3ÅuÊ×üïò®†±«´dèY1!- {ÏT‚£{æGñ£·¨n·Io?z†tü‹h²Æù¸c}¢e8‡„Z±ã±ø&£wŽÂóñȰݣ³²ÉÊú½¬Ÿ}„3ÞÌæù7³væ!zkçiu׬¯zP“_nG‚Á°ètÌxxí/rãõ?äÆõ?dçÖKŒF7IÓZg”Q åy(†»3–æÏ~%íóßíJO_¸t,¾`ZwwªÕÒJ€ì˜¶ï§X{®OÂÚO2ëvð¦IÓ”+WnðòË—ÙÞÞ±¬}zp1Ë0ôæÉ2_l}ºÁÞË·±w§„:önÝÓæãÒK{ÑEÓ÷ÝúÍ a˜¼E¹Kã©r¶÷Bž»ØæmV91É4ëëk<ýÌ“|æSŸ-9¬“i”J‰ã}òÚëÿ“ÿ–æÃnØ 3nzÒG£ª 'M™Íô0P]ig•žïã‘)€Ò^¡Ý[§ÓÛ Ó?C»»FØîF][ÖÐA¹méÅž™õ‚)ò”40Þ`ï2;·¾ÄÞîEƒk$ñ>y‘PNšžy¤Y2ã³ÐAöˆÖÿx#G̡˺Ÿ»*Ì}Y‚ºÓÛ+f>=ƒ:šµOm;”µŸ.YÖSÇuœö†ÖPõ}ŸV+"Ž›¨§Þ¦ÙûÔö¹ì]Zön“ŒÕ½ÁÞ Ã%ua€œŠ±£ ´ÕL+×H§µç æŽ$©Çï~®ÃÞy`Žî€ö=ïä—ÿß_e<žP‡D|ʺ(ʇi<Úæ`ÿë°¶þ0ÝþyZ­Uü g™ÙíÜP¥./%a Ãˆ¨½Bgå Y2!KLFûL†;L· wIÆûdñˆ,V™‡Gieâ4­§A“­‹òz( J¹¼1©‰B-µv³,TFký ;:ñù5›µÝf ;Bë¿C¼û÷¦€ÂzbP ud^z<üµ@•2 ö›öÁµzº$ ÏÇó¢V‡°Ý£Õ]§Ó߬d4 è~-½”îà4A]i:4%óö®°¿{‘ÝK ®Ùt•Át–­›3T*g8Þ_ صִÏ|àigc¯»>–ì½ÔÜuM–©zUŒ£îLqÖ>ÓSµõ»¥‚LÙ®´7¬†j<ôÐý<öØCüÇÿøYnÝÚ­FîyÍzÃÌçìõ°%÷YÀæ$Gk úª¼€Ú­keé=“j´&_Ô¼ È;æ®…à‹—#¾ñÐùÙÔÓË ðyïûÞůýêo¡Ôt:]…“Û¢ˆ™L ²lÂd¼Ãhp•ý½×Xßx”ÕõéõΙJN~d®‡÷÷Q­t%&!VèAÕY¥Ó?K–ŽkŒ~‡ñ`‡xt@– I“‰)䜧¨¢@)mI{=”@“›©=“7¯€½HÈŠÄ,UL^WÈhõû‰ºß|âsšnýÿ™ÞÚy*¿u¿­F$ûÿˆ’µk…Ò íäC<|¤0 /-¹ÚCK{× ÂÃó$ÒÂ?춺Dí­Þz è­NŸ ê@—AMvÓs¯ºŠZ#Æã[ ö¯°·{‘ÝW®2ï’å#SQ‰‚*mðtô¬y=ï7j¢ú|ôžÂï>VéTÀÒ4c·ÆÔFÅ¥f™½r_¥‡ŒªÍë~Ö¾£î&°/ÇäߪBz½.ïÿ»xòɯà•W^cggïppo4ÇÞ5.xÉb?•öîØ»ñ”)‹¹"¢¦¹SéíèÜü†]7nÒ2ádã –Õ“ñëŸîò-_›Ñk/Îû^êïë<ñä[ùügŸo0÷ÊN`RÝ ‘eʲø!ãÑ-†×8Ø{ˆµGX]nï,aT•9;½4¦{!=ýÚ!j¯Ñ]1@ŸÅCâÉdr`$›ñi<´Œ~Lž¦dYj²T eLäh­È­/{^d*&+RîÊ|¡2¢•ï¥ÕÿŽÛ:z›ükF»ÿOnÐ^ùÎSùÍVÿ;ÐzHrðÏ-˜kãÖiÙ»Ò>!¾ÔH­L ƒð‘[R0 #‚¨Eu [¦Àx«»J«½jØy»g$— eªS ¿@uz€âlQdd©qm\eo÷{;—88¸Âd|‹4Õ¢L šL}žÎ>h¸=ì2Ø uöÏ4Á|Ô»ãTÐR= µò†1éœîî¶9™y¬½á×®«§rq»›6Ëãµ7¤†ªÖš$Iyé¥WØÛ;`ww°OK3NËu[É6”ì]ck¨Rùi#œÎ]Ø‹ZØëiª7•~ﶪ Kw2V™™IX=>I$ÿþú|Óû÷ÌÀÁ|`¯ëï[[ÛÜx}‹ú-4]p­)´FgE‘$F£mö¯²¶÷k³²ú ÝÞ¨oómŸ–æZ±Bá ¤ôL^’¨‹ê®Ó-L±,™&#²d@<HÆû$ññdLÈÓ1i®)ò‚‚ŒB§:!Í“28É€}FÔÿ+´W>r›Ç^µ<»È`÷€ vÿAû½ø§”I²½òÐÉà_Ú-Ü5©JH3» |‚ m€£Q•ËùЦ±Ú¤œÚfV*öNÉÞÍFmÝ+åò.ýg%Ç $¥q‰vîZ6 ¬JH¤Êíû9 ÁÖNÈ'_èñž'–Òßõì3üê/ÿ:“I2u’u&¦³ñÊ(ŠÂxÕ$ŒG[ ®²²z…õ͇é¯ÞG§s†°ÕœᩪTÍJ FBØ&ꬢŠÌÎ0bòtD‰ÇÄ£]&£]&ã=&“}’É$ “ZUÉŒ¼ÈÈUŠ"¤³ùQÂöOáxMÓ:c°ýýRëÞš2Øþ~ÖÎÿ4B§²öê÷à…_Ád÷Éuf¤6€/Q@u‰Z+´lÞç‚Úê®Ñ²Õ¹ü°Cý\JßxÆ8Ñ©³CëÒ¨JeäYL<Ùg8¸ÎÁÞe£©ï¿Æx´m\só˜*ºs>Oÿ)•3훽ì@kó‘á[„Ã1wãy3]|£Ì逾4¢Ö‚”jIÂ\Tj5s¯¤]_?ÊC¦Q‹}…|ï÷~'—/_ãŸø²lÚžxœ¶¼ 3ݼgŸ}÷ßÝß?8?÷ãÝ€ÎI?IÒR[ÜDs}Úï½ö”ÇÚx.ª›fZ‚Ú¹¨Ò6.Êé¯ýŽM?PúÓ7–fûö^ÈÆªbµ—yS{žÇ™3\yíšÕßgΪ\«¶f¢ŠŒ,›ÆûÄñ.“ñ.i< Ëâ2dýšÃ?-hÞ&±‘)ì!~ØÂ:„Q¿ÝÁÚ­6^ÔB†>øí ”ÈM•%Q€÷ÝŽ½ã”ŽÑ´ñÞ?&üJ™®W‰RÛ cÂöWÚ~¼àÂöÑê3øaBØêuVh÷×鬜¡¿~Žþúyó·qžÞÚ9z+ghuW [=ü°mR@[`oÜ˧Ö¨yb¼_[ìí^bûÆ‹l]ÿ[7žgoçÆ£›¤6i‘kcý¯þžÖŠƒáNYYé(`÷»OÒÚüÆ[Wu–®¦˜¼K6G’i2x¥êÒ 8«é‹…ú¹ž³Z®mÌ, Åg>ó/¼pñØÀ^ù¹Ï{^õÔº.·Íós_Ü…ôû]ŠÂ],·cÉéÞ€óÚÜ•€]ßVƒBQ­8öSæ± . -‹æÒ}ž2 `5À¹3eMýµí6_ˆ ü£‹ý¶Z-Ö×׸zå.ÀiÎ×Î×ÝZf:©1vÆûLÆ;LF·ˆ'{äÙ¨–¨©nt;\5ÓÒµ©°M!`Ù”ÂVž¢@‰Â99J@×¼¯$èü0Bž½­cšnÉø˜üOx2Àó|<é›AHxäé"ýðƒ·œÚþ„\#h}=~¸MØ: êö Û}¢n¿¡Ÿa?°n‹Ž¥»`:óKõÛù¶åR[Vy6!Ž÷ ®³³ý ·n¾ÀÍëŸgûæóìí¾Âhxƒ4PXׯY#©¹ïË1&P)/²¥€]øëtïýKæJ w>å-3GggܳDU”Ãìi6Í€Áø9¬½1o¦¶\þ:dYnk)¯ Q]ïÙË~‡À=ŠB>ò‘ïdÿÀ†Áº¸ÓÀÎì~jà4ËÞ›ànõÏŠò?w«¨U·Ä€zÙjSdQ­—¿ÚHÙ+QJ²µßâ±û'”2Ë!7y»Ó¦×ëÚôÀ‹~v[Ý+¡È!,Ž÷‰G·¶‰Ç;¤é"OÌÔç¡qr·¹iPÇÍ$Ta¦øybd£lL’ŒHÒq|`þ’q2 ÍÆäù„\å¤ÙŸFñ—ÓMÝ›§¿A6ú!¢¨Cv‰¢aØ% ;A‹ ˆ(²ßDøoBzâž_…>Að²Mç"›±Ý]¿ªu1}ÿάçZ9†j[£§ïr°wÝí—Ùºþ[7>Ï­­/°·ó*£Ñi2D‰ÕÔKç»σÑ>Y–,ìI÷Þ ¼ÕùQ§ ÷ÇÚzMŽ1lܰøz$j“µ/p}„ò|JàÔåEšâæõ¾?™L²Lk2÷éwîKkîišñã?þ3ŒÇ‰ÍævûþÂ˵97´I™êKjÚ»¶o٥˞çcYo]ZuFVUØâ:¡JPVMñŠò5¢Z[»!Ÿzq…w½uïЛܭ_¸÷ Mãå€]kÚgήK=owÃS¦~겋ªK05Ï ô~ÑÕl£’ct…ç íešµC-Åçn‡Ë=ÇmKƒ»Öº,ú|wØ:ÌŽ–³û5[í{%è×>^ºF:Œ×¶Îª,AÝ9Ð .Щô·†UìgEÓÐ %R ž{¥Å=mî?»\Þê‡~$Nxù¥‹ÌºHºóœÎÜRÙh<]XCY“$ûŒ†7Ùß»B·w++÷Ò_»nï<íîaÔ'¬¯ü _ êÊüÎÉó”¢Hɲ Y6!I†öoP‚{’ H’!Y6f2¹Ÿ$ùn´¾ç$7Å¡Mˆ—hw>FÞC+ê[ÆÞ#°™VÆ ¤æãdHš}Œ8þ>´>=‰@©§þyþ¯PêJcÌóØ 0YLõ(ŠÔxÒ¦|¢ï‡HéÛ?cÜ_ òuiN‘§f€ï1m3؃ý+ ×n‘&äElŒ—S†ÒÃ}ñ{ãxXF .ìAïI‚•÷×ôõZêÞi@oxÇ8¶^÷go²ôÒˆZÊ2µtnpZ°T͉çƒí`í‹ñTA·Û¦(r&“ãyÞœÀ Zÿ;üÀNÞ bÎËEÚ{-§† ÔÃËõy¨É2¥ª.yþ~ò¼ ¼€R“rP,м\Wª®[öÜЃ§%s}Ü÷ò,¶Òm†WØÙ¾ÈöÙ¾ñ<Û7_d÷£Á ÒtŸ<7Ç`¼Â–ïÃ\ãdÌh2XØe`uv-:»R…•cìŸv†S5ËæÕ¬S^r^3¥cö^Ãf]ûw^SŸ¿S­ùÔNË2aèó­ßú!67W¹|ùZÍùäe™»×,¦Ø{°7_P'3P몫¨ÂеV%8;ãcÃ÷iûÐl7Ï›´²Œp%r¤ªI3Êrl!H’€_ýÔYþø»¯úz©àɧ'MnÞ¸µ€¥/–h*.g>§´ àÒ6µAž›•ÁÁ5ÚuZíMº½³tûçèôÎÒ鮄«„‘aÆØg<JfX÷,›¦ãà C”ì=MG¤é˜8~œ$ùN´>mð´—T\£Óù'´Z­Ö*Î:Îíö­ÖŠeÄEa¢~«È^7xïÿ„ñøo¢õ½§}täùŸ!Šþ5EñBcpt3ž,ëE1aر¶¶‘”jRR ´¢´q¤Éd²gƒÜn2Þ`<Ú&žì’$²l‚*RÃëìõ€=É& ÇK»ð:t.ü% ÄLW†ÔÒýQ`¿paƒë¯_§(¦rÉÔ¨¥£©(U¬Ü¼.Ùú|×GGn˜ì§ôGã4ÍøÙŸýe@+—;,%ËÜ- æ¤ûj@{ùº|¯D>m3óIËPm¾r!iø¾£Œ ƒi¤‰X5Lö³äT²Œh½¶ÆJ…©·©ìüÚ§ïáëÞy)–x„àíïxšOþÞ°·{pÀWyÔëÅ®™óy3ˆiò\£Š¬ôšð½ëìG=¢Ö î&íîYº½{èt7‰Ú«6!U„Â$úR…ÕŒcÒtbµõi:´òË4’$#²lLšFL&ßMQ¼ë×v¹&ÄM:¥Õ‚Vk•v{Í‚û:íöQd*P aа¤iT++W’øµú’‘ÖkÄñ÷e@»ýqò|‡,‹í9)maØ#ŠºAÇJ5-|?@`Ò?ë¢0}›ë´ IDAT‰Ç;Œ†ÛŒ†7‰G;L&;¤É€<›˜Ø"§ <:Ì«õådš,OŽö—vÐ9ÿ‘þ¦)¶¡2ëYUgåÍÚ¨aèñ­ßò!~ê'ÿ-[[“ÒˆZ×ÛAÑi‡ŒÇc“þ™Z3¦ºãÖP‚ý XW‰™ï,e?Ι8˜ãÏ—I Õãìg>{o¼(){ýíú{öf³¼” M¦H'ר MHΰZ²x;XpE”ržôu«àæ®Ïo}î,_ýÔ Ê)áaSW)xç³oç“¿ÿiûÃ¥Xº.}øfóè­>›e#Ëæ_' {„­UZí5ÚÝM:ÝuÂÖ*~ÐÁó}´¥A2Í&¥áÔú¸dêYÇï!M¿ èãú¯ ±k{^{·»A§³A§³N«µZ…±³˜Üæ‹j†Öüú9æ¢xÃáã„á¿¡ÕúýR{7ì}DöHÓ.ß&;ø^hf6¾!M†$ã=âñ.ãѶ)Ù׺Êq¹næ•å;`/’¹¹Ù/%í ¯uº˜5žªºgŒs‡ÔŠ8NùØÇ~Š4‰K&ª§(èõÚüàßùküðŒ[;Õ`£Íì½s»^þ[O6¶Þ9Ö~÷Èò—,s';ÍÞËMTì]XönÁ»L ¬@›ÈUÇ€M¾îEµÔ”`^ `Œ¨R¹ã°ì] 7,^påfÈï¿x–÷¼õæ¡‚[÷}Ÿ÷¼÷|ú>Ëέ½¹Oc›*g¢dõÒ>õmVN²l¾(¬dc¡r´…çE†5†]‚¨OØêÛL”!H‰ÒÚ€|‘’g±ñ<É&dYL’ÿ¹¸ñúMêòËÑ,rКþõum´<…€<§@“h“Ä×øHßGJS¥Iz!Âóp±¦öiA^»M§†£ƒÊpÉÑÀÞÚüz‚þ;+ßõ†Lf%š¨—µQ§¼d¦2@º­È—.]±.ÚÓÞ1u9¦Þ'ÐÄŸ³?uÖþÆHÛos?=¶>ý² äÕGtÉh¨o˜#Ï8@v€5®6ô÷¼ñ9œ¿{ýè¬$c† Çâͯ>©O+ÌyÓ}{‡{å%!xêé'ƒ€×._­1òe»çé÷«’Úö‰RÆ0e\ qj3êp„°%ß$?‚ôþwãFöýߦÛý8QÑj­•ÔvÛûJ Ø[Öгn„æ|Ø›à.âÏûQF£?Kž¿ÿŽž“RO“ª§(ò_#Kþ%:¿„‹]p€#]´8ÏóB–ARæ˜UYÄZì¯ÜG»9†I2b4^Þ+ \ýjµ¯-Á\•ž1‹|Û]ůú_>à›.&ïÌQrŒ®^šƒœé©?*Ào¸ßÉ“­C»¨mr7³Þ3,Å+aTò†ªéï…íå +ÿw_ ,»ÂXµÍYŸî W*ÂlûôK„AÎg—XÞòÖ7D¿x‰é@§ ªe Ì5•_¿ê!¥ëõ\°çä…+¦Q—=û5Ïé=J§ÿWˆÚßx§t kaø3t:¿CõL"®öZi@už1FŠéXO“À‰Ò€êyuÖnrárä8 t¹hâ§_%M¿ýŸ§Àó?€ç ñøg™ ~ U\4BšHa€\ Oû¦Æ®öðñÒG+i[VçÛhuþ Éä׌,ùm„”H%ñ¤g<—¤‡ïùh|<­Le.e&5ý½ÖÇgîƒÑ>I:9°ûí7Ó9÷íÖw=/½cêš{sݺ@: ×y©»c}Ý©éì ·Çú²<·¦¯q³Mþ‚÷ŽÕŽÿLH)i·#¢(`<žØøËì¿>7o¶»îwSï³w ìuï™rÕvˆŒ<£ àk- ›ot†J¢1Q Û[Û¼vù EžðìgÀg%·ÖÂm¯~/ÏC~ç¹s|ÍÓ9k݉=¾Å[?á‚Àç¹Ï¿ˆ*ª=Ö‡³émÌyœ^n–Â2õ¼È(Šœ¼ÈJöŽö ÛßJ·ÿ—ñƒ·÷ÂÜVâK´¢NeDaŸ(ì`o¯Ñj­Ójõ î1œÊÐd€´ñ J) p.º³Æâ4V4óð\å)¥jF9×q¶âºŒVÿ=Iú½hý¦»qæDíµ?@ž½Èhð¿’N~¥S<] ¬#€‡Âä´Ñ =´6ó5ãæ[ÉÇÕܵV F{¤ËæŠqv¢è~:þ‚™ Öƒ’¦»j0õ9©êé}§ ©%Ð;}½Lïkε)Ç€+ýX½7%Çœk?ÖEQÈO<Êc=ÀüÁs\¾|uNéÑyûZ|Üoh ÕÓiîBMË0bÎÇÜ…®Ë3˜*MÂJöF©ŒUTªV‚ÊRZ¥ŸúÔg1n¾eÿÈ(o*ûZ‰)&o+MC~ós÷ò¾·½ÎF¯*l0½œÞ¶±¹ÎÛŸy’Ï}öyò¬X8Oi‚½9G,£)9ÖØ  ;p/,s—Þ#¬Ÿùßðüyn³©â‘ü… QÞ ÊË+\^ ò•%^H¦%ŠÂO2Ä÷a§ÆÞ§a¯¶¹tDƒpÉŦõwST»*¨-€œ<!<ã8"-C¨¹K–’Œj‚z# Iò[Ÿ»w¿õuέÍÚ^ô õWz¼ã]Oóüç¿Àh8¶Ç;O‡oÊ4®WÐŽ¹o—Beèr[)ÇßÇúæ¿@Ê•“^ 5­'L†?‚Ê~žÀoQ¤mtSÄcŠxH´úŒƒ.QØÆ÷É"¤gÝ¥YÒFÚ殕­uªsŠ\¡ljÙ"OÉ󌼈IÓ˜4Ö‚³6ÍÈø¤ç?ˆ|’vÿû¢}×úÅóγºù£ìïÄ“—ÜSPv©-‘ÈRz\æîj€¼È w)–ÌÇ^J1Ý'èœÿ0Z‰)`Ÿ’côÖî¿…ï™RtžgCó…R"ñr:÷¾iN³u‰¥”Rh¥Ñ˜Í³0>üEždcãÇ_˜tÆE‘¢Š”,ýiâñ¯Ò[û!ÂÖWßÕ>ZYÿûdéç(Š-°›du…ÈŒ %Œî.qÚ;,øj=NÆÆ#ÆÎè–öŠYyí³ßjûrc¯|éêèRTFÔ²øµ.lÀÒ<ª]ºYèŒÎ>Gv¹#rÌéØžàK¿¬ äK¿QIIHwÁ¬7E™'¨~oTëó‚Q›¢ÆãœÁÕ‚…Ú¸!âáÕ§cB# AaÓø¥“ËNüè­ý ­Î7ŸbÏ,n¾ÿ0Ýþß`tð÷QÒ]?YFE ŒD£…;Çi9ÆÉ0)ƒÑ>E‘—}°° ÚgÿáÊûJ`¯ü<`?,— jºØF]’Ñ”u ¨éìåÍléºÁ¼ì®&Ç,Ûî†Ü\ß×Éô”À}ödMjŽ”ZÒ4ã'òäyq À>‡©7 ½>²¦¿KÊ¢Ú í݃ (Ù ´°þïT¨­±Ú{Õê€^½® °.×£.¾¾J’y¼ýÑË”ÁUKZ£(äÉ·?Î¥W.sýÚMûkbÎYÛÿj~ëZÛ@%Qô#úútZQ\c°ûwÈ’_3,Ý ð¤_-Ëyð]-T)¤meOªîÒlKOÁþ–õ” Ý,=Jò/€B”rˆùB0Øý>âñ'è¯ÿžwÚÙ%g›çÝo†h­×Ñä•qÒ\¥º7Þ&'ÃC啕KáÑ>÷ݧjIuF> ìÙïd˜š$㌨e•¥º$3m@ÕTT{J%ƒŸwÑ’c–¹Qî&°ß^»#š{«qï½çBpõêuâ89ôóI’.ñ«Ëvêby¦ð3ú».?_¥ÖÆÀªA[>d>é<ÕaÒJ®z“ÏfX|Ó¨j^ë9€oö}u»Gš?Â;»„'+Vå–‹>€‡y••>_¾Dž«Æ°Vù« à§²èEíÙÓ·×ãáÿÎpÿ"‰-ûM`÷ ›€g`_¬ô"ʰjÇyõì+aû×zA„–øxf–Uv!ªe¡yòkܺþ'è­þÞŸçNV-“r­¦CW×Q;9QT3·:°;ƹ9ÂòÀ.dDçÂwãµ™bèu`Ϧûï˜i­]Õ$˜©Ô¦gLÝ€Zazóî¦úÌ\ý}º'¿œ€½F¿óÂc|Åý¯óàÙå5p/òWìÿÉäç‘R”ù^*Æ3¬KP÷ð¤ö™ìÂiÉÕñŠÆq;÷^¼&t¹K!R ´ö,©÷ËYEé–XH !)„)Y™g¿ÁÎÍ_'j3ýÕÿÏè6޳jãÑÿQ{%J€¯³x$YÂ$–v­ã{´ö5D_o~±ÖÓì ØëþìØUØk߈@Ånc°O·ÛÑÙï¶ sºí˜à¾ÜAäyÎîî>À €ývh9Åž—û½Îæk«‚2ÿ»ñ Qµ”ÁÔ^Õ>å›,’PºÔ5¯K‰ÁÁUåi—Ðø­ÞXhÍ ¯]`gØãm\“•L3½œ·-~ô!6Î ¸|é*ñ$±l]— *¤a IüKh DtâîVŃƒe2þ)$&÷‰p¯tuœ^wSá ¦Ž…¢Ë4Í êþ=rñoh{Ø—å„O"¥¶, akðÖ}Ï•còiüólÅ¿@»óaú+é=ñQùFÃfô)ªk(t)%:g2’ÙÒ÷I}‰hÑ9ÿíøÇ›nŒÚäªÀzž3­«×2>6¢P‹°;¦^UYª€]0ªK€/¯S¦7€}é[ã?Mfº- î‹e˜Eíaë3G1û›å¦yV·]7€¿*ða5x˯…PökwœxQ45øúá”ú±iÔ4£+iFêøAsc§Ç`ü8O=|‘~ËÒ^öBÐï÷xëoâõk7¸q}Ëæ_H R ”PŒþú+ýؽžç¯0üñøã@b@[úxÖ0*-[/Ù»ðl$©cê²ì'áœE›p>è›W{™ûép^×ܪ«¼DvàÇÎäЩmàÀ€­2•¹D!‘"7L^ „RÄ㟠ÿ ­ÎŸ¥Ûÿ¾ÿÈÇÚlûû?$¶ïÌõ+g:B§#âdb¤¶»Œ sîÏ#¼Þ!^0†}7 ª³åòªõiPŸöºïzýõ`gJw_Ú€:}m]û£ìðeUCõNígàÅì¦Æv ùšÊ`§ZÈÅO5k‡:ÀÛ*N*·|>åM£5µc&À²Àn •ëã4°;¦^›I•>G¾ì€ýîìçH™½£šCói˜£¿—ƃÆ}| àË$cTR®AR5 Þ³âº[¥EX&X–¸ÖÀ¯cÝséŒJÊø·h/\½QŸÇï}ùP™fÞRA†<ôÈýìîìrýÚM&Ú ^Ú>H“ÉÇɲÙÜüq<ÿþÙžÕ“ÉÏ1|Œ"!$žgrºx.ÿ¸“\¤W2wi¥iÁÏ¢p`.Jm½ê §°Ã4àγ­Ün›/ÍÌð|áì4Uá…É o€ß°xîJI„’(e€¿ì²ô—ÙÝþÿðü·Ñíÿ5Úí?57íÃdò‹ þ1yþY¤'mÿÚ>·l½°†üé” ny¸7L‡Ö=¿ýVk­Ð0À­æiéö3jŽ{#ºùºa<ìåk×ËÓÀîÎÉ]‡if~\ý[¯·à~|ædínŽ”óä™e ðFº)5øÐ]¢.çK^…y7¬–î€ÝÕpuÉ?Ð(á´wh{3K'Ùã˜ÐÊf?[»=†ã§xâ/ÒoÍ&›·tÍÃêÚ*­v‹=nmÝ"ŽcÛs‚¢ø<7o~¾ÿRl"½ ¤Ü@ëâÉ/ÞEçÃbåÂXýM»5JWñÈFxºRÔ/Aãb9xŸêM¾~²ûJ×þݾèµF—òZé/„¹Gì ‰®ŒÃª&×(U”2˜IÒ%QÅóìþWìïþžž|Ï¿Ï;Ïdò äÙçÒö±u)Hó¥òšî.JnY`÷ZÒ>÷a„ìÏÊ0ºäuI¦øõÏ5X»‚2@iÚxZ—^êŒÝö­ž–bj}½ °9ÎÿÑvxC™ûÝž5á¢Ú´àËÔÞlšðFFÐ5¯ ÀWÖRP¹Ñ@K㪦,Öm—ŠÀ²z§Á»  sÓ#•u¥TÆ'ãÄãÓŸà‘sW¸oýÊR:«cvàƒ `}}•n·ÍþÞ»;{ÄI‚P­ÆùgMlnæzVØŒ‹^Mb1àmd9%½x%K—¶þj ŒÔú¸ìj÷dNƒø|ÙE/Ø~¼6ÿ»s¥™é×¢ê_gpÂŒæJÛÍÞKJ:€—J”Å»•”ÖÿnìáMç¿ÄJ{ÿP`w†T žçáû>ZkV×VètÛ #ö÷HâûÜÙü;æHœ´"m8áÊÀYÝÕ.•5–.ò™Þ« <—g󬙫ŸZVŽsî¹E© fÛ|PŸÏóuy¨Ò@ïAsO)mŒÅB[9J*ÃäuTÊæö‘e27¬QÖFæØ‹"3ß‘²ìÇ•b¼ÖôÎ|+"8SièS%ïTÃ#ÆwÝóežÁÔ$å%+¯§hú±×½&¿,ìu6_¿F‡ûòE!çÎm’¦·ní‘eGИno¦úwï¾\ös€7šðö=¡*‰¦ô¢Ñ”~ðv7FšñÌ+É4ÃÞkÛÝ.k7³V(©ø ön ®ŠÁÄç3—žäÜÚ6œ½ˆ/“¹w}ê.¥‘¸;Ð_]óèö:Ä“˜ýýyg‹•f.½ÐOëéUÊÝz’,ÞY˜+Ù¥ÎÎç3ò:èWÛæµå|z‹@¼¹­ùûöøíuTNª±ïH›Æ@ÙÀ8¥AH ‹— ©s7Ÿ©î;S`$WYi(õ<ÏîK4–£\ìÂëm~#~÷´ÎQEÚæiie‘çKÔ§Y»MÛÛvyªi¸;Î{=}ï4°O_‚;ìBΟ?Ç?ü\»v“_ø…_çÖ­ª¨ý¿°ô¾NÞæ;À]•e¾€ÝµE?gC üvk ð¢ðöæ«kð%À;ï~ëIZæTÆVj`O]XÉ3”ž2ßXëFÖÿŸ¼w‹µmËγ¾Ö{cι.ûr.uê’ª:Uv¹_»0ñ+(ü€ (RÞxà%ÈððñR‚x‰²Y(DD€*!Q"ŒíØIlK.lש۹í}öÙ{ÝçœcôÞ­õ1Æ\{íSÇ—’-˜Gû¬µæs\{ÿ[kû[ëšü÷daBP={ÈÓˉO½ò5>zÿ-Zeß]üûm€o眉1ÒuÇ'Çì÷{.ίØï³E–1$NÚôy Ò ‹„ô¢Ž`NœÞ륇~è/ÎóôYl/ä¿¿×óûú`j šûs IDATæn~ZÃtòäíï  /oãÁ £„ÄAÐúÂä2’óà`Ïä­Ûþ_<ÞïvèïÿýÃ?t؂ՠG?ðÜ^»{åêýÖç6êìµ{§Ç™’™›€ÍrG½ì’ŠYû7yl‹7oÔœqÌä\øãêí8/>§ß¸Ïõêò>ÔN?ø[~w]Ê&Ò^xýòü¯>á–ý8üÍ—Ý<×y=ÏÁS~HÑB–yîÑ@¯ñï¢h0ž^&™äÒ«O´D«yîêž»ƒ¾vþû,™räË>ã‹×øì«¿ÃqfGÁ@]†÷¥O”ÆimѾï999¡”ÂÍõ–›ëã0ûrqŒE?™¢£ÆQ)ì¡ßöÎoƒ>·¶_nùá'Ø7÷ìŸñù·þþZüì'gÁ;ˆƒ8€Q(U}U¨Á `¿èu—Ç~÷û·AÿùíîúFÑ,Ø)9œàíç]ï-?»ûxßÜåÖ¿>ÕCÛÖR¾Ì þbü¶'¦7}[ã"/ø]Ý«œ Ò]ýe¦Å ž3V…h ‹ýn×0_󕬶РDlÍ¥ù¼¦E1ª‚Ä9±*jÅOdš.Þ¯P Õú¿/¼u‚K&µš7_m±óä Î^åéõË|òá—yõômZ¹÷mï¯]WóÚÁzó7 _ncd½^ñò+Ùm÷\]]ss½ó‰Ø¦ó|¿õÖDxÞ{¿eÏ“Åßk÷òóõâɧwns˜¼¿0“'_ËHñ…Éᬗ÷ùEÉÒ;t§†þῲ¢Ö­ÊÝ ÐÛ¼ù¼.h˜‰~iß_‚ù!¿ns¥» ‰]"Fa·@ö6ž'ðnû-`SŸ`ÇZÞßoú藽𙎻ùïçƒÜÛß¿®ð|”qçë›ì‹<ó9Zù0¯÷ç¼§cÄ?kÓR\¬gw!´ ,aTË4y§Œ‹¹½<Ääߺ›âÆTÁ¾T­úó. Úín¤µº]²ß¿æa£–ìšN-@Õù;ƒcaëLí1Œé[‡>U4˜ËmgÛª˜¼ÐD*Å€\óÎÂ4€ò°AYµ"š)Éêdž†ŠPAm@¢}V£Q5cä'ßÁ;çŸäc÷¿ÆKÇoÃbP.˜½yö¨gPYþ¾Þ¬X­{^~®¯·Ü\mÙïæÅ#æ 4ELwx=w{÷wy^wÿäu×xú ë6/?{‘7¯ä:/DÞ€¬)˜Úë6°¿(þ°K Ýý?‹¤—8XÖÎ¥‰u¢Q }+Y ·>»U]z(q\þ­L (°7¯ÃȾú’.ªzmŠrì ôÃÎÏ{{çV~ËqÄ”;‹Wˆ‰Z2·Ç•éÖ\‚÷ygðÀáлº;òœÿ¾klUnŸÓÝÛ¾èûöºÜg»a鎓§*þŸÇ‹ù£¶@À|.:qb“m³ÇòœÍpðuXZÞ¾Éd jÛù“[žT3&Íø,®mº¯:+¯ÑÞ²ÅUæÒWségiZ;Ÿ†Év…a:+[ÍÉï§!ÙA¥€´¸ýÜ5Ͻ%rxCÔš”!Ýd<ˆf8PEjõdn±Õƒ4Qu h2^_+7µç'ßÉ[çŸåc÷¾ÊK›o rÖ·ŸÑ‹<Ê»>;>Þpt´FÕÚ@ïwöoFÞwƒ}»s·¹Õáÿ0áðïõõü¾î¦zôŽ-ž÷«.B°åöó÷roW‰t÷~€tïÇ‘xŠÖJ­£9 eÑଽbtúyâÆ™x¥)õ໓ò¥-f½è sеñîÛâì Õâ‘iÝçÈã`·;¹¸»õ¹ÇdÆ¡}׳šYæ~Ús©eœ0Àþ!DBìèÖ=»›-ZGï uØóò/ñÉü çý{yÝy˜CC!ñy(ÿÏ]ç"äó‡PDÎYW•hÆ¡Ž³]LOdámLçÙn¶yÊÁ?VŠa[{`·ö&SÈÕ@ZÜ2à.®²…R:‹F ¨±_3Ž{‚•”Þò4¹5`„Ú¬Ó{x¨ÒŒ†¢VÈDœŒcÛ—êˆ}›fh|2„ Õö§Õq‚ºƒ¯FÇ´(aJÌ:]S‹ÿLFÑP±l“o§‰¯¾ÿ¼¾×N¾ÂËÇ_CÈ‹SûðÀσ@ßwô}ÇÉéÑöÃ~dØŒCögzÛ¨¶€%ÀÞåÝ~ÂßÜ“ÿpÜüÝ ®w~Þ®½R¼Ì~ æ/ºGw‚õ‡Ü:Ò½?CwïÇ ™w|Ìu‘ü\hЛÇm^zK²:`·íXzåí÷j£ÙßÔêp®½óR«oÜb…┊ªï{6æÓöíž*,½ñÉx .\8-B˜¿ßBlöqð¬4Ø<38 ”Z)7{ "¡ÛX´1nŽuû5Ó2ËkñóÖEäÿ¡_>ôÖ(•pëz-è®ïNÏ=Ä„V#X¾ž÷§Ü›®Õ=j?âQ”‡c·¦.²|~nÝ—«!C3—õÏ4ÄÔQsvJEgÓ¼c –<ۥʼn·¸c’4r;ðfOÃÑ:ü/ßXöŸiŽ@€ÑÐÿ,/?ÃËÇ_ã•£7ˆ²óÇó-)úUG×§ƒï•\(¥’s|¥–zßJfÞûí¿•jã[ ¸küüg„#ºÓ%žü ˆFÀmÞ¶–¥Š%û¾—IÒÙs¿-a¼K£nIÓ…†ý¶F ºsðÕ¢ÃltôËaòT·~9gg åÝϪ¡Ímл èÅö—w/Ø×âßy1ó¢ñ׎_©eX¼½åÄ­ŠW¹ý=Þ_=`}TD ëz†áÅëSßIËÆØJôZ²Ñ¡ÇŠ.ü PMŤMf"Ð4{ÂBÆå¥î32©uÐ[<;&®nqÁe‰ª‚¨¥5oiÞ°Lû7Pǽkµ2ðª¶íò/”=¶‹ÃA&!ROöP‘iÙ·É­_pwæÕè(1´’sg ½´µJF4½.æÝ·ÅžE±’~LñbIåBgõ« ö…ý1ç]‰Á&$ hPºnEÍ#ˆ•»ãM¾LÙ3s«c<ºx'ׯó`ó6Vß`“Þó[û­4€˜"!º>|^«yöôó÷ÛÄŸp¤…³“±^Œo¼Ë—€ÂüsÊ} ½ðo¾-„Õë„ãï#}/ªÑ×A½tW¸Í«ž“œ ÌEgà?>êâ;¼ iê¢ýœÛò:ØO÷Û[c;“aœHûŽƒ÷œ4mï-©—æ]>¸VOFãVwVŒy>a j^´: ‡`*óÜöÏÌÁ¬óÇËM[FøÎ×íqeÔiJ+†1cÝNšl‘ío†•Êþú™ccd}¼áßþé?Ë/ü¶×wõNpW„~½&ïö¼µ­f]1OY~iz°Ó‚ ŠsÞ \Õ=Y{¸óµÖÉ;G!FJÎþ²à]p…H-.,ÃCˆ´îç:ázs”g hîe25¾/ÇϽQ4".SjÞ4u €´2üE,Å‹MüQƘLá`°~ßd6ý¼‚Vì.¸"F"1¶â––(mcÎ:H©kA\ øc2*P©ÞRÞyx1*fصž$ ´P5‚¤™®Á6!TJ‰<½þ8Ïn>É*í¸¿ú§«¯ÑÉó …´ŸßJð3í·uDüCÝï·è|ÿ ÛJz™xô§ Gâ}'­±Ø’f™€6;v¶Ö¼Ê%»WÝVPZ$HݳÇ=~¦ü>÷[Òt.JÂÞÍâí':òxc wp-6ßÝw™Þ›½õüoáÁ€ýÐVi3SL„“ÏFA× Æm)åô’;Î…ùy8-´tôàërë»^æÃõtŒfŒlÂ.]®×¬nÈ”<ŒüΗߥ¨×ÇLkG,^w'Tµ2n¯A¶Îì Ï*×u"®ã^Ü ßnæµ™ŒM"™°ºMÖæÑJ%yF½8‡‰ªçjÅ ?è’×i°ø£u¾ÙN¤NÛÉĕϷn™À5É¡À»U­bŠK ÙqÃÁ m „@UKtˆ!NyFÞ/E(Õ#±@Výia\©™ B@k˜>ÃW3§[bìÌîˆP}ù:K¤T´µ+ÐJ+Ò’`×'¦­]z5Ï_ {íxR>Ç“íçÙtgÜë¾ÆI÷u„omóÿ»mưùÂñ÷ºO0uR,#ºó`o@»­î´MãÐYxì¨%B'¯E$²>9¡ÖÂîüɤ¤¡ý²ÀÈQrAV«Žq?Brnó­yôuÂçÙa¶æzSq pXyªÍ‰µ×äÊÚgiuDJ£•prr̳gÜlËÙˆxôŒE§1R³'ï§X×Ï(Dj]òâv¬/½tŸ÷ß?wɪc¡,.è9`×ÅZq` ñî& ¨>ïÑBsTÕ˜ƒYúmFy÷üê/ý*•HÍ{¤ëŸ;füø—ÿÊùù¥žÜìLÅ0äÙƒ·*­x€‰¼˜qµ¦V]>µù²-rÇ÷'m»Ø7š7}k'“W¬{p5ü™Õ3³ám¸{ñÁ) ñ…!ˆvt/nmhB”@Ä<à qzö¢Ëaмüà`l™u“$šµm Ü"¢´dn°ßƒ7ØB§}/jjñE6dŠ–´µ"¦ùf)­]]{]œïløæ~5X¨ì÷?è<§¢©ÉMG7£n¸Ég¾ŸÝx¡åáÃÛ;Pý£ÜV"²þ<ñþOþ[ÈêÛAŽ'ºï8ÿ½Ð®%W©S25²è¹NµZŠeÜÁ²ò´'‘Ñ’©u ïnÈ»´ì9X×ÔÓhžûÌ©ŽŽVüÇùßãK_ú2—×­ ËT'KÐÓÅïxäÐêCæ×’9t¤jج;~ø‡¿ŸŸüÉãâò†÷?¡”jòÀ „Õ¯q(·@}>¿[ÇÇàæµ×^â¯þÕŸåüÃ_f,bÏu,©ÌûÓ羂¤ÎO%ûû-â÷EÔæ¨ˆ+P1¢E×6·›¥3 «Ek}Y¯{Ž×œžqÿþé 8÷éFÛ¥ÛVÆë‹Éú6Ê$Ä"‰²ßYˆßŽêD“°ðR {gªE<^©æéâá^ˆhiW’,õðr¼c³¸¥׎-ŒÐ–Òdˆ3 #í»¾ÐðÔ†V) c2ë"¨$¬üûjê›LÞÑΩz’Z¨*ó}pš±=XêlGHýÊ Á\T=l ˆˆ{©JÔ€„E)µN+ I‰v?§!íòÉ*©ºJ@¢jK$•ÁBßÜ@XO«‚ÝßTv¼Æ…¼F”ÌQú:›ô+y— ÃoPý£ÜVÖÈêuÂúÛ Gß‹ÒY‘ËbqP”*·råM¥rØn·qîѲL~.uêí½¦€p:Ç¥·já2!­H’‡‹)²v;¾øÅÿ‹§ï?5HÁú! èèÆ l÷zUY‚¢.ÿV¦íf}kY|Ýò0fÐlQu@ü My;Ö!ßŬ¨V=zŸŸù™ÿ‚«ó+Ûë$I¼µñrÿKI`ÍÓÑD¤#Ž>äê½Çs¢YÝà‰¨Y•L£kf#LÕ˜‡ƒØ`ùZ€ûÂ'hMŽ„ŠŽ7ä¼w@&úCAËžÊ`ï—“üÔâÞ†Vx£\ÀtáÍî­ÒVïºÈ0\;ù¡°Û‰yÒ5Äp܃°+i‰W{€-hrÍ Øï?¼GÉ…ëËãÐ U-™)¦b©….$öuªïÏu±^ ¼Õ€ ®Hëî¿tÌÕUa¼|F æ¡‘"ð£V¥H“9ZÄ`çX@Œ‘ö×vOB航ø6jsŠÒhE• ‰´ØònR¨XŸ1ÞÜ@ãôÕR·v6hDýÚJFB jËK$´Œ*A­­‚ŠWѺ†×ØZa,Ÿâ|x€U¼`±ï° @ï–V¾èçÿ§¶•úOúסé_C«…ôè» ¸gPžÕ( ê¡}JrZ%°„蕨ã´«Zn’GÄ£móø'~]ëÔ锞k; ”q¤è¾Í^T„±¿ñ¥·kDÉŽmy¦dZôIv8{ëÒâÄÞnÚBv˜®°ëš¹¹Þò+¿ò|éÿù Ïžž3Œ~ßÊ\4¨=ø7ü] ŸduJnÌMœfðV…ósË)H F•µO%ú¼jól›$¸s[ÍHNãa¼áæý2ÄÎó]-÷Átü ãÍ;%[@§6Û·_éùâžx.ßmÜìôPì & çn¡ „níÉݶuó§b®¹ºg)ƒ€J¤Œe‰Ý…«³'¦Ñ2ŸFpÚ¸ëyø‘óìÑ;V ¡nœ`ò@-©1XK\RŠüÄŸû^zù!óü;óìÙ99gRháOh¬ ¢JV6aj H º‘…¬uÊTÜ¢/â ¤ÆékaŸwTUbJè˜íhªDIT*ãpC iRÙ¬×$%¶W{‹ «›#‰¨µR‡kû‹NŠF´6p6p™9!˜¡¬%SŒ¢Á ¥Ì¨IuÏÞÂ8ªT¡†ÀXï³ã!!|7)<¦ãm:yBÐgD®“ùXà¶@|€Æ—!}ºO#Ý'QI …E¥ë×Ö~¡8çW 6*„Ö½ýîÞgu• uªX¬5Óõk†ññS¯˜e"µšQ€æy7½ú2‰:§ý“¦÷×G÷Ø]Ÿ9 7?Ø’’NcÔ…úD[ަ`‹Õ(HGZmÈÛ ÌUŠþùô%w e¼ž a«Ai´„Ò¨Š6͵é²Ú~›7تj$n¨u?㔈ׅ·®î¾MI_¿ç³ñ‰Ðõ|äÓŸáñW¾ùÚï͈„ =5ïì\\$13 óuC¦ì/xúõ£ƒCD¤LÒKqõ]ׯ÷7HêѼe¢hdyÞíòåƒÚø—Z¥ßEmé­$æò55ö»[9\³Ž‹Kûyµv„<î(ã`7 6ÿ¸’bO)Åû •)³Ü-µëkÆÎß|à0e³­-‚­†c“w¿ß3Hd|¯ð—ÿÃÿ’ÝÕŽ.$OºšÝ…È~{IX­ñ„:l¡Œ¤`­¦D9L@Dɪ „ ±­RdË&!ªDl=Ìâ!oA ©£äÑ—A%Q5›§-yGÉB/‰ØõŒy´BÔŽHE4#ª 7#"‰>&M¯Ö@)Î{7J3š:kÌAªÉaÁ®Aê‹’Í–s)2÷Ük…Ü<·j (k(¨!åev¼bÆÁÏ2ÉQΉzF çH}FäèÖÏÿØe¦—ÑðâKh| •—ô’·ßwZA‚sà£'¼ (÷yk]‹)2–j°’²Fõð_ £rž@Íì·m…¦‰W–\}óºƒfèŽLM2^rÐfâð+5;ONe{ù¾SŠhÒDØ÷t_‘@eD5b£i¤Ož]7@›kÉmöb÷¬^»óØœ1Xoî³ßž/Àæ6ˆËâ;3/¦þi_?’µø^Ýc_&\Û1ÊäÁk §mæØœFÿî—@³ïܳieO•BÔÑ"…êÍ„O:[¦Éº@ÚŸ™1!'”¼%ïÎA--gg¹2©•¹ÿͼ»;9÷öj]Û¡e²éˆÝ†2\úŒ6½.=MÛðV §Àn·¥Ñ@¶as'7Òmª7/lD…Ù:bß“5‘N2>{Ó ý¹‡c¢”™ÚéûD ª‘õýWÈ»-eØQ‰Óéw÷^e¼|b ž’ͳ<6kê¸g–‘Î*+ÖZ8¥ÇïÑLS°)Ôá0¶€þ>ìÏQ5¥Ö2w¸Åº¼ÀsoaI{9G$‘ÔŸú »Ë'Ó=NýÆÀ{Z9¨i443fý´-z1…<éÖ0î|PùÉ9871PRˆŒeïF:,&‡Q¡xATXô{¿]ê(YýŠã“S.Ÿ>!Š%Û’psQ“üZ¼‚ÔžÚªiÕ‹¡Ô8fóªa“zk<¤•âËH!…@—Ã`Q ¥L6[P:I «5.Ši͘­@+„Æ»'Pì^ÇžU0º«÷¸EèRd? h0êKÔUpÁ~¿W…5µŒD2[ÐC% Å@©èH'‰¨‘ ŠŠ’ëóYl2Jè¨XS8K Õ½ö ©v¿ÂEa€åÔZ¡Ø Õà¼b‹¶‚sÑÒò=™WA>bQ®X¸+>nT«'–„¡å|tDdDuoÒÁÐU À—ã|6LºìÅŠ`=F›ÔÕµ7‘àÔ†ÐǀƎ\Ñ@•êýF}g‚]S XÊŒ¨PñœGuÕ Ø%ÛçþÆ@ʾìí»µ§Ã¢˜ö ÷&%®Ð¨eOÒ@PqEÒHظh÷vØ"Æû»BB —©Eh¥W³7ÚFz›˜í¯Z<ÍûeqK‚¹G¥^<ÖèçÏ›7ÞŠÙŸ®-1ªeýÖë?ž/`ª¸ŠFíÚŠ LQÜx¶hÕ/Õ•)Z¡ïÖìÇ-³gߌA+>R ±>:f{uŽè—oþ&¥2uPÛØ(G>Îõ³ÇÀ0ƒÑ|Ûý5þm)íÓ†-s‚JQ×Í·í½¹VÃ0W¸õÝÃÞKõ½’ÕJVš¿º÷2ûë+ÈWèp½8™®xÞòÜz¾˜±zÿý3þÖßü» ƒ-d/’\BÚøy»­#ÎKFׯZ¨£É ÉÏÑ-ÚZiáðÞ>;?wÑõõsRýö}ö“ô¶ç®ÿʸçÙ³ $ì2„ÍN+P¡Žæ¹•mò&m•­ ™¤S#âÖW‚bÇ0ÐIè¬ÌÞ8j½ÏkÝQ÷Ãä¹Û€µ#mbŠ[®Z+㨭ÅhB´pzï˜{÷°=¿`·(U©yp¯À½94â—¢Mïj¡c­ÄÈD•€UšS…€‡À–b* 6ÛÇï#¹p@íÖäZ)µNîh!)u 䃩h#°”Z ²úÐ[’4Ä9z¥RÑèú{”qKߢb°s1Ã&Qóד1öš!Ø*~Õ:1²%Sƒyë6©-×`Mû§''ÜìGrÞ“ÄëìÞWAÐ\<¢V„êj!£ dÌæ}G‹Š¨•ØõäqKò ‘ |’¹šë%Rª{P$•PÓ!¡à4`£½jUb´~ôA"1ؽ£ŽF¿ÁäM¶¯§D›Ê“ï¤stŒ=U³%A]^ëã #‘”:+ ¾†€5 ·B!Ó±×jtKE­R´ññ:pùîWíJv¯ß+…cÇæþG¸~úÔ‰‰Z÷“TPv¦Þ )i\iÖ ­â´©»„¹“c]E<ÿ£(%×9÷¤…©°F•Ðõ”êí6RL÷“c´R “ÚmŸé‘ÜòOýïVw³üxj¯QjÙ»óXõ§Œy –›É0…I^é*¿ ÛÎ¥Ë$Ò¥¶Þ6í3_ †O|öSŒyüÕ7 \º‘ô—“K—CJzRNKuZ퉵r—£F‘¬¯¼ÝÈD:}…\vèî’0 PG4ï(BË7ɤÔ;¸ÁþóÅRHå¹ÈĬ¶õb‰î)Gy ÝKkä•hsÐëШFa³^3 ™:öûÝlÌC¢Œ[Ê`ËìÞTb꽞2yŽš}qhïÍâí5´^,JW•7~ó׸zÊf³æäô„Ø÷fH‚÷…Ÿ€( 1aÉ«ÌzµbØ›õ ¡éÍ™"Z+%gb4~ïSÓî·-©'”l|vˆ‰R*!v­ðäl•}Å£¢>u­gwã²»Ð!5$³é`ÜAPJ‰”Ô“«IíRtÕÃ8pÚwHŒT±5oW’ˆ©cÓ‘BÇX+%˜„-#•ìÞªEI€ÄHöÁE¹<;ã¿ÿï~Ývg=IÊhc% 0ýpÕÀуW¯Î‘PÇb$¢$/V‰º.2fKF' „jòÕˆ’µðzUú N÷$OâoËÑÌ&F†b2ÄÚ(eöç\™cÞykžeOªÑrQÌðÄ.Q¶;£©T©® Œ»kZ f£ÇŒ4¬RÉcF1úD¼—Õw¸w]‹ÝcQ+ëÍ ºÄnŸM {Ü2B,9;»§±çèá«ìÞ¶4EÔrE¤)áè¹»F_¦±_ñð•óôí7 ˜KñvÐØèžÀ£NûÍ[¼ëZ ¹\V§¬ï½ÄõÓÇh½Ac°¯-Àpn›Û¨[ótSê­òufÚ¸7?nã¥Õ#ŠýþÊv“zÈæü5y¥R‘Ø9íã˜!Âì EY¼ÖæÞ+V€5¦È«¼õÖ{¤´öŠlÃiÅL^­èÉ6½Þùø´{Úr íp Â1«W?ËŸøø'ø¡ÏmxãñŽßøÝ¯qóä+°;·Êwµ'çwÄëe;Ä÷zûÕBÔçX¸#:Z7˧pf2¹u>NHÆy^ãh³æ?ÿÏþ#þúûó¼ùÖ£ùËãIkìe¢äqRPX~Ä@¹;zU)»Kj° Ž*³®¦Û›KþÙ?ÿ-¾ú•·¸¼¸ðòKºÕEÒ& Œ¾2Ëõ¾ƒ[Y5¿oVEêJœ&çC«4+¬ Mº.±YŸ³šÒ$ï ŪOE ¼ûÔOûªU¢@L½S)¶ 8ë÷ÒŠ\bPÆZ¨9{Ìd•ʽþ˜UìP‰tëcŠO˜$‘!ÜäÁ ø¬øb½ZQF]ÅyiI¦±ÏÅ|¹‹Ë3Pj¼¼µ‘È–èLѹùò¯Þ¿Ï·ǧøµ_ûŒ#"‘蹃„¢ãžN-]ÕFVFI}GÙeÐ-Bç*&Kí—bô‚PXïl‰°«#MV6±³‹¨rnº†UôVK6v!’RB%p´é¹ØB­£åFJž&¾Ö¶>mœ ëj fïâèÒÅ:©;œC/ÙxW±$]ê?òÊ×>ú ïïÿOŸròðHàüÝ·‘ºEuœÂrG®¿1G¾ý %ïŒæëÉ'm;ˆ yËÓ·¾êN\§‚W¨M`¡N§Îî%'—”á’«'WvˆÝ B"—ŒË…FM´‡QÉc…n…ÈÎ#qÃÕfZŒE:¢ÂÉé17××nŒâL 7#PÊtM404kà˜f‹vÛ-¡»oL“–fóÔo®ÈˆK£%g®¿]ƒc¡¸¾ßßK]OwЖÏÄ¢a æÐ [¥ïožñÖ7vüW¯0ì3Ãõ5!mÐ4by›[u°vçÅ £„Ži]Ú C'p? ‘îz‰VH§H8F÷—¶“æí´ìn»±îùXntELG6xSdØß°ÛîùùŸÿŸyöìP×Vû¬¥÷CøM’¬QYŠ“üMë@Þ_ÐEoÕüéÆó¨EW—[®.wÄ: è“sßZP±&ÿ56Œbg4‰$`„)CÞ¼v&{4¶Îs¶ÐJ­LÉ´lúcBX±Ý “¥%²²¼.„6ì&¯%!“gÛÅΕ5‰Uè ±£j¡‹'ìÃŽ¡Ž¬è)qäfØ"Qè» ]è¬pˆ¤X‡ž-™]³µRοÖR½ï¼"Ö„,ufp«€ªUêJ5öq¯…”zV!‚Ž$"¥“ˆ¨0Höü•ÓMOG%K%H%E¬e¦4±{[©Å }2 9âÓÁ¸ÿR©5Rb¬Ù¾’ ðsU²¯:» âýr¼*³°¸O Ùü+ëÝÓ3ì.ˆ.ß; ›£ž<*—7­_˱S…fë¶ÙÅž]¶d›yw©ž©- ZhënVU†ýÈ?ù'¿ˆRɹ¢¬¹¹8óè®Ñ ‘ª{„‘²wçØæa *B8>&_d$ïÝ€Øuš¹·óQ…PGTU ¹öÙyŸiŸ˜ÄÕ):ÆÁ GP_cÁ]/M¬@œdÐêQ¯ZÆ[ŸË™}<›`)®Í@Èà·;rÿþ)?÷sÿ)?ûŸüW<~ü„:ûbÙ1±!Säì{+V2”g\ê[GÐÁ½cŸÚqeÔª_+h²]¶*[7:Ž îndäq°Q°¹*`52¤[³:~Èöêzó„.¶‰áæ1 É[н^ûn­Å«\X?ø}мüÚ=ž¼õ&³ûb¯EËßnn¶Öòwl@Öd‡Î_ÕÁG°‰?ƒVbmÖ?öy3¢b%ÅU]£Go2ì[¿½”9)ê7y±AÄ4Ó©ÒÓŸ¾J÷3_ØZ\íÒÈ` tÓDÝè’õòoÌxÏtý1{ý»¸¾¸på‚y­s¥m ¿Ú)ÇØÙbžÙv¸‚nCQLr™Ã80–‘ÜVÆñË Á8ñàV¢&:K1‘¢Ýã®[± =ˆõ©gu´±gPGÛG­¬b K«tDß­Y¯ÖD‚ «~MŸl%»fks:ãù³F=GVI©#…D—,$µê]Á#¬±‚’‚Ýó f”‚?£ÝnË×¾þ6c鈬b":':ÖqäTM·C¤=Ñ\NŠZO[E6“«%Owwùa„]Þ±/{“ÕM¡ò¼âP¨Ø?|ŸÆ‡5º¤ÔL)UºÕ?úCßÃÇ^}À;o?6~¹­|ä*™âU§µX¯æ‘RKpVkÐŽ3­š„`-fTó`‘A-Ô|MnwTÝ{ÌWIri…Ö½W ”B¥Pu@÷פ”ÈjâÓ“›Ì9Ú9•au¡n-2÷†ró9¶†y–DÕ’ÑqoÉDÁj¤5 ³6öw4O¸y[Nµ´®“¬£ÏÆ0m(Xß{™q8Gj¢q6cùÕúë6*Æ)œF…0Á»_†sѪÑÄ¢‘Ô%Æqç=—\±ÕT[È&P.ßBBì<'`óøÁƒ{Ü¿‹Ëkž]¸)"ÁÚô <|ùS<}ï Z¿­¥šro¾ŒJ{p¹ü\[¨toðU:¨íš<Æ3Ïýâ–ç¾(õo÷nz·¬ÓÊ)2ÝT­îí‡D<~ȧ¿ðƒœü‰o WgˆŽô§)ãÞ¾/ó‰ÌE‹èÇ¿°WFE”BÐFØ…—R(ž¬ÍÞ!¯zÕeÅÁØ=»…ý0N8­ñ"ÿW)Û ¤Z˜)b^°(ÓÊNêᅩRLõ2Ö̪ÌÕ’UmÍOKVUSøJ'z[á’+]4þiþ‹õ{‘.Òw‘>% Э7)Lªˆ’mÉ®<’bbµÚX¤¡æéw]O;_Ëuö"4€ºaL±çd}.m@…ØuÄÔ[­Üìnu`tÉWè:†\Ðdí²XÿzÞ9OÈu@)DWЇÄ*®é4Ð…H ¾ëIÁÀ?µ‰Š2”‘¢…±Z«áÖߺ`Üw0ŸQa#ëé“…ÒÆB[`¼-lT:ñ {•.FR¿1¼¸)™(¡µPÊhm0\Md:m£8bŒV¨E¡z[hõ¦ª­¡—¾õkªoñªs@·BºÍ¥¸Œpbvuϰ»€:8E\ç¦Us{Ä?ëÈÏü‘R ßøÆ7 47†V¡,Á¸È[ÊÕ{H[€»!Îb1 ñó±úµëÖ‚‹ÖeZ2ΫÍk{ê*œŠ2΂œµeô§@±6»Ö¶BÍûU#tRì<¿Ö"rY`ÓûêNèÔæDlŠîèÄ/¡%š«X‰Z3G›5ûØ«¬×+v»Á1'qò‘O3n¯Q„ víGGk>÷ù×9?»ä½÷ÏìyÁj=ŒÇÏ®4ÃM¯ïB…dc„‰Q-ÁE$­î@îzޝïÛb›^¬c^1yâ®!…:…àdêõ]bÈ#åæ_ýå_tK\À9±ýÕ%±fJè‰1YRIÛ·I8ÕHÝ$0îÎÐqDc‡é§Õˇ…Òò/"$=Ɉ˜ÚÀ’–f4Z9{ ¦“¶ÔA&ÔˆxNz!)h¶Õ©ER4Ý¢Ÿfø¼@ŠqŠd²+q¦¥-Ë­ÞH,úÊL®Kˆ Ÿø“ßû_þmº: d$ ­W{Î[º•ñâëÓ5}ýeÞþíGk Ôœ"]\CúDzDlÐÍ~)ó‰ïøOžœsõ욌í~Gí7õŠœ•a,‹É/îi ¢‚”dj#ïÝV–ŠÞs¤‘¬æmå1sÔY{fW·ô)q²:!É¥0JfŒÂžQ ÙFñ¶à´Ä˜ødíÒŠ;+Š"°ŽÉÚÊHªÊýÍ=®†köMb±^=fQRP-BÍ;J©lºŽ!äl^Ú˜ëäEH"¤èŽŒP(Ôᚘ¢wÉÆæ‰×êZs:¨¹Ñ9-l í¥LûkK·ÝZ&oÎÖúõöÐѺó¨U¬¸ç~Ôõßßð×þ›ÿqÌäaœÁ4D—dZ$¢Á“â²²Rý¼) i˜ªÈÁŒ€¹64 Ŧ˜éç§ÈÝ2©už˜¯Y=ø(ûü·óƯþ2䃃voþdsÌS·z‹–ÂŒ-oÊZ4ï÷£*A2š­šúèÕOqóÞWü´êŒw˜SruuMßE>ù©qÿÞ ¿ý»oQ+\=yDb¤H  Äøîïýú.qö춦qOÎ{W>‰Ÿ§Ý kÉ‚«íü¾¥Œ|!qeUÅZ¿H‚²{F¥xåwu‡0ÌÏÅ_ÐÒ¶mÕ„ÖŸ}þv³ä&!sͬãhU‰ÖüÆ<q-DduBÞželzñ Òqòà.ßêH®©<±i=©­e­•¦oÈßZ ¨{ ¹îA*!¬È5“}%¦ ÁUB®J$Ñ¥õèhò&ŒÕ=¦êŠã4+_ K½Ï„tÖ¦!À~=Ñ5`Ü›‰)"Ò8a5µM’¶ˆˆ:]yçw~Ë4ðbžmï¼z =ëÕëõ=ºnÍÍöšG_yŸ•DúY…5)*)®ìÙmŽèÖ'ŒçO‰ÁŠ”JÍäRˆ)ñúç>Ä@¾)\ï·ìÆ=cÈŒU(©c¯éŒƒNç‹R¤FÓ3ku }!g“˜îKf#=±VbJ ¦ïBàÕÞçÙ{\íÏèÓšRGÆ`ç¡býs­DµûgæÏ¤ ¢‚”J'–¤/uÏÍh˹ÍF­¡lÉ X£3s4"1$Kb–‘R3)¬Ðót~n5ÕV£‘Úi-ê’ëH͉ÝûhÀn[ËÄ1]×ÓgTUþüOüœò¥ßzƒ‹«EV Êñ¦ç‡~ôøìg>Îÿù~‘›Q@…:X2[Z+‹Æ ªºÄŸ‘ãÚÁšÌ*^•lƿޜA3øÒ =ÝàNÿæ×!-³Ý±ß C™.jÙceâöYÊ‹¦3²¢«9ÜJW“Õ¼¥µhÊñ}›Å,ì·—~,|jœ¹¸%6]p$¬@ ”=d´x×Ö¶Å´Õû¹·À­0G¬ ë{¯ò'¿ð§8;/_§…Âm‘îZÛÄ7YØ´ìŸVr¦F_Ó­ž8/öH+$&ºà½[‚5'J!N‰áˆ:ðG¤T6ñˆMwä}ÚÁÃFj!de-+6áˆã“—ØtǶ´^LæOíwD§\º¾£j †H®…·¿ú.×ÏnPWeÏÕpÃP÷hPÂúV½QAI©# Ö ,·}–P³¢!£ jµ*ZFs·kÍUV)Yè^+›õšŸþ‹ާOÎ8;?G4óðµc~êßýq~ó׿d¼qQb ŸÊ¸g«±ì­¸ƒÊæhÍÿ«_àͯ>b,ƒE˜Ò¹„Ìv¼¦¢äš)ÎA·6ÚªÀž]­™ÊH­#E+[¦°HA"Äêtfج"ÛÀC±\GÕ¹ÇLÕarVÌ(VzL=Q«¦Ô–t#ª®Pªz‹ÊÀêþK¶&GQÏ1§ +…í͹õ² B[.ÏgïD:¯}ŒÓ Zç µ­£ê˜cfc»;~€Æ÷ÄõZÅlPÜ‘20o« Iã(L%xt\L^hŸÍð¥‚ÓU#¢#舔ñÚ¤cu|’½ÿ}i ×ΈL=Ö[Û <¨Úõ ÈÑ+lN^%oϲ%¢µBm]öpÖNÃÔÝnÏv»ç _øn¾ó;¿2?~‚ÿúOþ(Ÿû¶Oð÷þ·Ì›o>1Î2ìòm;ÀÃ=AÒ‘I‡›E(Ô¾‚y6­k›ˆB·1žQGµéBÅV%/æW/)>xtÁñ!ÍÀØ1uîa7dÞ‚g˜B3 {[uüH+vªÂþêŒ_û•ßD54³ kr¾¡Jöк™#¿5¦¼¬×+öc“-ùÉ:Ýd‰» ›SŽŽï±ò6‚ ± )DRgC$@ KÓÕ)}¿±k,€Öë5©7a½^Sb„±˜âE!udÑ.R´(»ýÈèy€\8îÙjeWGB¢&ŠÂ~¼b¨:A¼²6ªXëÓja-¥0V‘XÕÀ(‰bo:xÂT@4 )$úÕŠ½t|ñ‹¿Î;_yDÒ gï_ðKÿè_€v£·1Ç=¹¢ÀæäûKëcduzBZmè‚Ê”KÑÂ÷´"[Å(/–…p)'½Ôè‰VðÔ¢ÔZ‰A‘Ústï®/ž€î­t^ÕX”lÕ²&˜9UZ¯ ¥zh ɬ*yé±û8V1Þ7TBÉlÏžØÈ «´¢ =ð#aÝ­ÙêŽR¼+¤«.¦VáM¢ŒxŽ®zÖÊÙݸ°¨ªesAkÖP¶gNU êšrqCŒ:½£·€ B‘& ч£G94 ñ{âÍ{çÞ û본ñü¥yU£¦{2çÒ®uuú ;ÊÍ[ hZCÙ[S½É`9m¿§òìYÔ2;»_ùò7¸º¼âÇ~ô üÔOý+œŸŸS~â'~˜¿ñ7þoý-7ÒM*©¨nˆ›òîR*­Á¢.Äfwšö³æÔA+J«“#lC;ÿ9ŠY:ÚwèÜçßSê&Ï}éúk­a¼$ã„°› Þ:v–…dÞœ/!g"â:_ê%Ù¾ÚH·A±Nq!,ª½\ÓBÙ`¼|ìÖÙŽ%±3²Í0ÿ×"+&˜6®R°(¥\9§iYpI=¹^c=›;*Ù“ ÁSÆøåP+a·Íæ¡û„AŒŠÑZÛòŠÈõ»ëóÿ—¯7ùµ-¿îû>ë×í}ι÷¾®ŠEYb™”iY¤e#Õ0–l9ŽQb ˆfF€ 2É(³ 3ÊŸdÃIgq;‰v[î‹êØH$‹d5¬×ß÷þu¬µÏ½%É~D¡XïÝ{ß9ûì½~k}×·Qm jû•UdùwÆÆi >1†‘MÚ2¦ 4…Ȇ8àƒG¼S~w ¼õö<}ÿ^ªâ©Î)ÔÔ s˜ó¬KhVq.Ò*ìëÂåt­LQ?™â0N¯šÔ×½÷F“ Z®”œqÕ¨ ½C›Uº.ž1ì Á”'jÏL,H?+ø·Ï•é½ ÇÛï}ç{4i,%“k!wÔñ°6:Žþê))&åë·Ìüê5ÿäïÿS–ª,\¡¢P «}DklcdrN—÷ï·ÓÿÖþļ{ì@êÒ¨–7zuý®5¢¨ñÙbY²=ç.Z›>´uůY]»ª${³˜_]Òãú©*^îåF;•Ô EšŠ\ºŠ½’út²ÈB)…ÈÌ«¦'üÑ;½/¶éº|<±aŒ’mQ·)uO„ÕúÙɦÙóõS{Ï‘NLÑ.‘Öò© Cò‘u zÚ!Øõ\aéçÏ^ò¿þoÿ€_ýÕ‘¿ñ7þ+v»‘ÿöoüO|ã›ïa5Z_«ù$‘/©e}§k3|WO®Õ&xÍ:X5DâÖïRU{7•³£›m¸a$Ž›{õ[î¿v¡ZªáE{aö¦{à ˆh`ÄjqêºXÝ–õPÅI/z!ít^‹vS§¥jµ4ïò¸{MJXÓŠh1tâð^è펵ÒY¿öÇ^a˜»‘K_‹v Ã8°, k¢ÓîÑ›ˆó,W/uaÛô½y¯Ð‰¾:Î:/‡“¦÷Dq-Ó\Â]¼E»~J ƒJ¥­ÓÉ(Þ#!&6iÄK¤µJÈ&m™W{Á¥ f\íˆ[lÚéºt>šÄ40õFñ˜)ËL. eQ›RšÐD']…q{ÁõqO«… >š`Ãdê­Ñ‹=x­+ƒ$j©äZ‰ÞQš&LÍe…”bw¸~‰/ßÛá%ÍyõŠiY]AsƇÈBÑ»ƒY/E}â=˜Ð ò)%#’pm¦—Jp­Wæ¼°Ôjnºïö!¨WM[-–³þ5½óI…*h3ÑÖ%tÃI<93v‚j\¥ÖŠ—N®Õ&G…îö*wÅ[VvRG-mWø•lÏC“ޏ‘Ö#85ãó"$<›” 4ñÜN·Ê :ÝÓknpµQ@ŒîÖ¦4C©Ú•«›¦òسû¸›Úv-ä^5â:𾤅1xGÎËÉHm½‚.[jWMC—ŒÍÝÁÍ*;]ÙX½éÔa>7RÑÂa×{ýTV‹ÌÑO‡ww³ÏÕ”š¦°¿ ²°ŸÓ~*åthý©¸<ŸD¡ãâïTÌÖ¹œÑ• üßûã8à½çx˜ÙlFŽÇY…n¯Aì³h«†GI¥ÜY¯ñ~Ö_êÞ#D‹bÔë¨L±ÕY´#>ÀšÁ»ÈÇŠ »OÜÉLq_ß²Üûïf#ÝzªtÚr­lë¨Ha=]¶Ô¶Ø"±ªˆá$+2œíôóÍãÁY‚Ê)¾«qYÖBºš|­F_Ê´ÑßwâuñeEû$лX)¦ë+=u«-}ÛÛ™q—·.£ÖF¶,yчDšb…¨ëÕS" ÊÄè¢òÆÅJˆMÂ]vMËLò•Ä%ˆ‰Ãr¤:•Z×Ú‰!$ª½ i•RµÍS%íFªR®Ö.8¥„RÑ užb¤äÆvØ0$R›B ê×®µw–ª¹(ôÕjGœVëuî­Q™ ’0×=HE…MѼODñTb‰>¯”Tš¬PËL‘b1‹ñlà¶/HÝCv'Ò†R:õ:Ko´’ñ!q6D–eQ„Ûè”'ܸ¶¦ÓeÇý³Ò2š›×/TÐÔ3xóÉ#6㆟½àz¿W×j¼zyŸ¦Æ³ß½º¬ÃkÎ@ë–«M¤ýdÊ%è¢r³Ûp<ܲZ‡ôfÁ¦s›`Dˆi ”‘V(eÊ8î胓vOˆ!q¼~n±pWÔ?ÑÞ•šÓïÚ×õÓa FßpìFÊr ¢Ðó °ñÆùÅ_ú*ó¿û_øíßþ6¿úýUjëüÚ¯ý=r^½c:q³#¨¹£K X(¶sFH1õ)†BˆÑpõÐ7–Rï¸0d¥Ö go¼Íí«gô{â]Íþ#<÷‰yÎälÞØbË•Ó× ë²¥Ü¡ˆÉ`âBŒ#µ¬ +‡bx›^÷;o q#~NtÊO·.vœƒ)lˆaHføcÅÞ)ýУùƒ^œnóm™¤;`}5ÑEº½/ÁÛýÓ½¯JE1WB p¦î\=e‚8 ÇPˆ¯ÞæëÍd“ƒsŽh´ÇD`pà’×lÓMãÀ6ŽDQáR Q™Dö0éâ§v@¿'8å½ëÂ4¼'ŠPòLï™Z‹1ƒ*"•". 'ÝæœAç›s}ËR•ÇoV®4ŒC®Œ¡Ò µfò¢6ÁšàdúNAUÀö¹yçÁ›eBe $DïÙ„Ãn³Ipž©ÌÊ7x§7½ôÞNÙ²xGohðZÎGF¯Ž’Þ ‡fâãa8c6êã<‰Ès™©½Þã7ƒIšu°ÏÿØ[t×9&a9\#”Sq»8ßñó?ûþÍŸû3¼xþŠË×W´Úð½Ìþ`H#Ôª›3èÊ©O}mê'CǺ9cxÙò~âKÞ™-²º€ŽA¾jUe,½ZCâ¡W..ñc_ü ¦ë[\5¥,M'§^YGOýˆë©»mtv“ÏÛ3§*U±[ §‚ÓM­ÝÁy†ó'Ô¼Xø»7.¸6AâT‹ó¬ÜqÃôÕ¸ ºåôÒió˜ó³Äðïÿe¾õíß§öÙþÎû…ËÑrVÁžXY“v÷úàä÷‚·ß?ÄꌒÖ¤$Iéû!RŠ)G Šu<-¿øK?ÍW¾ü'ùµ_ûûüÞï}‡¯ÿÖ·øÙ¯~™GÎyùò’㤞>”ŠëN03CSÛ¯p3*œ?Çsý|Ò¯Fd²6 aP!¨Ù,‡½Þ¢Óí0Dv»íÏs׿ÛÜêô#Ç™2Ì–»Ð.ªàoí Á“ç£..E»ÍïZǯ{Ÿˆ'¤²ÜÚ†ÜóÅé"*÷÷NñÆíxçÏðÙϾÅ×÷[¼xyE.÷’`DS“ ë2¬7šêI­Ó{¦ÄD]ŽôÞ1šÑ$åä.¨ÅùnRñ.¨‘ư8Y|~>òë [.訊ãÑŸ¦gåDb°YÆ}Ò"ä=^‚ŽÐAoØNÆ…‘z9¨ZPF„Hð&Ë7S)3άq“xJ‡íøR+®d‚‡t°a| Nh-⇈ëMOt³?.µ ÆR®Jp?\À£7Ùß^QoŸ“kFš^«à<ÁxQQÏè†í†šÎÓ–³ñ‚¥e®Ž7d2‡eÖŽÛãÒ¹[(;(zSúæ0$æRH¸ªÂ±à¼î?ŒÞ'^p)èáå·¤°Á¹íÇz ç‚sPŠuÖNl!«‰X_ûê—ùáOùñ œˆºv-ÍÆñ«——|¼¸¹¼ÆÕƈh&¯>ª´œ•FÚÁu¯Å«w5I¡¹ŸÖ{uU«® ƒØ³ålTJ—N 4qúsG.™ÆDpŽiÅßþm‚Dpºëµá’×<ÞZÉÒèNImõ}±NÚ [½¿Ëb·¶³ 5ëk ƒ¾ÆÖ:Z!™æ˜®_"-ÓÐÐôõ™ÔP—¦û9q'¸FŠjs;ÏëßyÞSbä7?EÎ4RÒ¥«õxkº›h¶G9Á1÷žÃf]ÿ­ß¿÷ºât Üw\,ueë¬åµÙìñ!ð•?óãüÒ/~•ÿþøÛ¼÷Þ8ñ¼z}Ëÿù÷~¯|ù'øÅ_üþå¿ü]ÞÿàãSmiK-³ÞG+ms­§½@)ä2#N½ôDV4¡Y3J¾EÆô<š à$2[-È×Fõž·Ìžý~bžËÉ[æDO\Ç‘ü¡(ÒuknM£Ò+€wînú{ôÿ3±¨»¨¹Îtdî|$Œ[ÅÕ­û½¸ØñËéçø¹Ÿÿ)ÞÿáxõòRyîb¬—® H3qP`·{D/ÝÒæÕߣµŠ[ v‹—ÓYyÀNýÔ­ðkXEZÄ¢‹°>}4[^íh¼è× ÃŽ¼¿T?p¹xãÓäéR™ç½ºAúÈà^ÔGf“û½‘MÚq¶ÝàZgpóíÆÍ9¸Hµ“;xtÅP«‰pjYðµŸ0üëûÂjýPr¦{Ç“7ß`šŽúYÞ¸ýÆ< >|$xóss&”Bh0¸ˆóŽ! D<É’xviÃn»#ئ‘!ŽT·ó Ç|`®£² œñfv8‡çİaÇÙæ éê÷Bï¤q Š¾W=Œt±æÍChLcðÝQE¸Î×Leo÷ãëD1NA§¬?øî|øÑ J™hË‚Þ ZÐ<@®\¾¸äßÿׯ¯Ée1« 6‚8vi`Àá»JÄÝêØ×Qå²€ïß»fÝ®fS®éµF¡K Yix:É'\wä¢ÝxÃ(qh×_Z6X£RÛŒ£©ªÙE¼ jÅqض#_úâçyõêÖ6¥ß².ÇWš†-ýÄ{ºßð?ûçyñb/Ë¢í¸Nû-ý–û̵†Ù‹ªiÇ펺,Ô2Qóº×[güJÎ ¿õõoPsU'ß~÷y­‚90j®ØÏ••Ì ŸEÎõÉìíDÙ<±sX§õ½:Ò0j-B0à_;~ª.:\äO}å§øü»?Æÿñwþ/¾ûÝž&†Þ2¯^½æ£ž±,3Ÿÿüçxõêšy6.zÓ œµ°÷=Ðæ$»§l_E^nÝ«ÐéU“¶0j¥kkçžØíî¨È8lbY2y1kK£ÿarm1“¨»ÃP±£»Â¾~¨+6a7‡8ÖÔsÒcÅ;6–­X‘vÕJù²Muëv&˜˜ÅL_½ºâûßÿˆýÕ-ÞèGpf‹ÐAD‹kË&C·¿%øÀj¦±c5T’Žú¹tc• øptA‹«Ý„^ÔûÅ‹'z¯E8$…ƒh§î]ì`p'ÆŽ>ÔmÙ#@iE£ïìàó¯Ñð½)&¤w¦ãA‹Zˆf8¥]WŠƒ Òˆ«•˜tÒ Akz]ð½‘|d3nˆ~ïnÃÅù–:‘۞篞³ÔÌTŽ4©,³&¼çhKQ];àÇ´Å;…­Ü{W;I?°ñcHlÂh Ø&Wë¡̦PøÅ{ƒq\%xG 猛G|é¾Äõm§å=µÌt£¤¥)M§Âh<«ïˆ…Y¶Æ4ŠqÃE²q‰mذI£† ã}`ˆIŸ½Ö˜—/B…“z«JóD¡ ©B¡{6!°ñÁ¾>@mf¹q½’œþÙR3Ãæ\w=+ Æà皪¨×½’Ãଠ– Ñ,2<ÌyBé›è¤âô`g^9]u¹³pжƽóå?ý.¿òï~ö/‡Rôð±Ç‘;u8zÀÚ¤G^¼ÿ>/q g½ït$ª’ìö}¬ðªi#º×ôÞ¨y¦wµ¥¸kƒ5[*VÔXƒ¨5ãÔ•®§Å½.µ¯MZ³æS©u©-N Å̧sb5ò„U»eõÉQë$Ó²ºûðÁ?þ…·øÎï‡?xÆxz~Å3M /^^²,.8N¥6Ä lwä¬Ù±º§0H¨¯‹_ )\ lÑÅÈ,§šuwØ­±ÐI)üûOtî‡ÃÄ4-ƽëÈÅNÜ“PèÂßñJïÿÒN6œþëŒ,:Z*Ã!+·TVéì:;áÕÛA&Õj ¶Æó—¯ùðç\^ÞÐÀÆ<§ K´¶¯‹Õµè«7÷z²ƒôn8õÀf³U?hq|wÆbÑi!9ÏÙîŒÿì?ÿë¼|vÉÕë[»!îºóä‘`v ˜Þy Ãðv¨x<)xuJ”@tºÝđѠ'Î =«@ª‰†¤ñjWo RÖðÆí½¡©õ•ãtËRgñÐHaÀ»ÀB¡KãöpÉÒg (íÔ2a 2º„orØã,A(ÅDòI÷Î£Š›‚‹ßI)¼7Êæ†àMúª½p›÷Ly4ºÓQ7¤-c ½R«Þ[Á ®ž~ÿCŽûçô’vÉmALTÍ3ß xéç5¼‹¼í#s>RMÓ>Má›1F¦¾°o™æ…*PÍ{¨Óñ1à[e º¡©‹äí®3åI ݼc ‰‡ÎÉsFÄuYiøzîlSìröùŸf¾|fg@?uÍÊ[ïtéH-ë¤jWë êé‚'‹]í½+¹‰†tðáŒÏ~ñ+¸óǔÌ—¢.ŠâTቚðh‘,8`ôžq³Å…--5ÄÆ:ï¼æ‰Š³…gR^¹Àõå ?øÞöõvpˆJÙcˆø ªÇ³u9šìŸÁ\9Û="ˆœPÊXˆN§…àÉDŸ´èûHò q^µ¤+ûEºç­ÆxFt‰ ƒg)Gæ2³Ô™¾šáˆÉ³¶œoÓœSú*]cʺuŒqä0ºÈ.nÖ`1§X7QØ*¥li•üåÆGí"é¿ZB¨šsnê#´ôÀöÁ[ÌljÆhÁôª6²Æ/ýÌB´2!Ò(~ËÒô‰"öw8jÕ"¸ ‰!íXjfn™‹ñ Ï“‹'$I,dŽe¦öÂÜLì´[¬eÆ{Å_·N¡±’‹œÙ}ñðüŒ/~ám._]RªÚ$á¿ø/ÿ~ç·¿ÅáV½Í3Å4L¢‚§®v¾Ò Á9ÝM8åÍKWÚŸ‹g´|À±Ç»fy´º·ñÛ †px…‘N°&¬c´ÎÞ¨ebn“>¿8üæ®5®/_á-j©šlÕOz7Z¯õ«fÇ« Öˆ¤ Ú2ãD̺ jàev¿ëb•°Ó ´¯|ùnb±Ã^xÖç¼à±Ðh{Ý]Sø‰B| `Æõ¥š ÄÙB¸Ùï¡÷–~ Ÿü¬Å¿÷Šëk.«F치TÏÐ !‡™—//­ƒT5©àq’°“?< m/ÈËžiÚ“K³Î}U÷{z[L´ìÀGÆGoé^Åüýµ1¾GòµËW²sžÍ£Okš™Å þqÆalq_²æPª÷ð=Ìnà/~\ú|¸‡^êiÝ{g¹Ñ¸*E£º£;59‰~ʃ#@wA­a»áý{³ïG½õy:X'àט3R*}9h—ß9çàêÞ¨ëR¤wjË„4’íCsÆ´ >àºâ×k¾gršãêåµ%y¢ q`ˆ ožåÎΨõ¯ý^~ü jg‘1mHÎ($§ÞècÚÂÈà7 ad3ìˆ>2 #)FVs¨í¸;nyI~` #)œSZ_tBòBéŠg/,òžc;@l¼ùÎlÞºàÕËkζÉ¥¶OÄJklRbwlÇs|L4ç(®A5ö¢RàÆõ5í r,Gšƒßp6ìHççlv€g?ß2‘É­(€X ùpà ápvëmÜí3°ðqÀh÷…&-­a+ŽÎš”ôî»oós?÷¾ùïãDiyáŸþÆ×yþò%Y;ò”5»6Fµ3Ʀ5­¨+ŒVK×q}Á‰ÂëúçCHˆxJÕ¥›C'‰(ž~ò1Ëh„(OBºqšj!J Ö‰Ö³š­ #Ãø€|3Y»Oiz8ôŽxƒ`Ð LT>®PÏýÌRû¥pˆ" Î9Âù[üä/|g¼¯{í*Ö3‡ÎÆ~º\îK7L~e ks©{©ÕFdž³Aåï½ÕÓžÑ.¼å…:_ºuÏàÞ²·SÍoH¿»omJ±:.ëDt¿Àß½ñÞ+ešOt[(¤!0ž0÷?âç~ÿ øÀù§ÞáöÙÇZ¨ † /¼øÞ{ £ÄJó‰iGžh€Áĺ<]¹¤½7%O¯¯Sôtr"¶‚”ítú¬Ø“áR^ÀµÎåÓáPÚ\%C™¦‰Ù©0ÀûüÈfwA¹z¦J8&Ý>{¥=N]½ÑÛ|«HsxÑ4 ¼ª0ϘF ̦x aÀ!øÍ–o½Éåûéæ¾dc`Ü xºv­¤ìý:5ò’Åœ“O ¬´­ÃÉË%Ƥ§³OÄØl·ò‘<©}ABäåáµÎ,­Ò‚'m6xI¸yð™·ˆiÄíÏéD.·\åkòt eµ§"”,‚²SZÎ$qI¤a¤nš6A>™¿ˆÃ5x‘–[j¯ ãC¥E'…Ì*~H§f!ú!+E ØXHmƒiR~ïµtz°ÝŠæÓö¨8qèìë^WºFé5m©<Ü>F|äòxÛ&®–=K/Ä9ó昹œ&¨ PªO\lÏ9^>ÅûÊ2kjV‘œæqþà>àýï}D[l‰Ú:½Vöû#ˆ§”lì!—ªÚoñÆpÆóï}'U“…P#1z¦åÈÒŽ´² !áP½±,ÊF«b])ŠÍ7CI+:L©ÙỆ…צ¶ÔB°"¥ËÚB>ª@î·¨ë 6a1jÍŒ1ðàÁöËŠðÿý&y™ô¶ƒª‹L=:½ü@1>À²}¸»ÀŠ˜Ò¦W8Wôë¥Óì@Ãà¬5a³#ß^ý‘µNª‰äãÄ7~ç»à"˜~kõT(ײJWûnPÆ›FGÓJ„ާ»¨u©Ì'º²Bþ,ÓËU}‚Ug .™`)ë6ÑšYîj»M.Jõ½4`á'z€6Ö=#ܯÿ WH¥/U®Ÿ~x ÂÂNéæÏÒ4±á,’Îk8‡-Aï¿]ŠÜãÇ{GUÒ¿=ìª/2G‚BƒŒ§;"ЛVà4¸¡(7,ËÄàš~P€øH”n¢å«Koi×#uÎB%Äý2jr‘ ]M‹oëê«>ϼþà#Boº ó/¿ó·ãt\úÀ€ IDAT‹oÂ6Ú]‰ÜÈõ7|ûN骸| I1wëtV«`gvYùx‹óq{Á4ß*ç_Y .¨9Õ&= Å-Õy®¾?1„NdÃårÍ=×Ü"n!ŽžiY]䘖èXZÁ]Tv¨MCd™Ž„ ìÒH‘F镸Ý"~àñxFf¦œ‰Ò)Ç…ý|­,§‡¥—N©Ê5w½1tpq´¾=Ój#zÍ­µ’‚£O•ŽaöÑ%æý‘Ò3­5ëD Í3„é¥ oÿ‰w8>½á|Ü);¥u¶qCxJèW ¦l „ ÄOŽñÁøƒßƒRðN§GD—Õ+y¡78¥QJ ÷€ ÷H_nuÊ]ó²kÑý^§®^èµéB¾ß¥V­Ìm3ݤÕJŠ‘¿ö+wìmÎ/ÎùGÿä÷h‹B<ÚŒuªëfgb,ÕJPÉKµª°Ýnxó'Üî'./¯Bl†{Kƈñú:$€×Ãr… òþúU'm)ï8 !I;Ò/Àêw®…\ƒÌµàºÓ·ç<¯¨ÊýrªM‚NûZ+î ¸ëò;÷-Óúè8s*}Ò óË÷q§ß]1r#}D¹¾Ÿ»šy¯Œ÷fç`äÍwŠ—ßûºúbµÓÊuOqÂüÏ|õg –9r8Nä¼òN×…ª;±]Vo÷pöˆZôâ)dU¡6z›o‰1Ýœkr€áóZÏ-¾jÞõs2ÁD° [ÔYu|¿}Ì›Ÿú<å°ÇOøñ?÷ vôã-IA®WMyñŽˆWÚ¢1D‚¼@tmØÆ1&Å÷CüjHiËHaw´´á ?ÿS¼~~IêzttUEvG"²ìÎøô»Ÿgÿò†fÐY£©|pTéˬR͆7ŸìJ«z3xÁ'Ï´L ñ§6No” jÕÚÈÊÎ@£é|vûtÁ£ó7ñÝ3-…W‡×\-/`Y(UGîN#Ž;º²ë”èÈš‡{×9ÆÆ- _¹\Üæ^–+®ç=¹ÎT‡ÞÙ $ïp½Rz§xàÉ¥³Û=&Ï !tM˜Ê5“ûÂÂÌB¥ŠN!DÕÖ½ !Ø’x>@)$—”zÚ*s4¢sHxÕo¸í7Üì¯bàSágá!Ÿyó!oEJî<ß_s]Ša;A\§ækÅÿíš#tO0ª+b¶ Æôi=4Q£©bÆÞ;AE÷à³|þ+ÿ—Ï_ê!áWÜ~]`ºSÍ”õP±ÆYÕñn=€•NÛ鈬ÅÝÄk.!F%=],îÇë¯Õ*˜^9^?c†Þ6½ô{®Ÿ€eîqH·+'OtýVn©U; ï_Ù)!¬ƒ~ZŠ=“Ma Á.„ŽR§C[ ‚Ð8ï¡Vj.§¬“œÝ$tp‡K^.õï,¯ùη~Wùá¹N¬ÚN Ï* 1¼Ý9¤iìý@A^è8œ÷–…ÑéÙšŽ“NS½¥TÇ{ÿü·l¡Ü:ŒÛ3¦ãA;ç¸ÈçðZŸñÝÌ·z§ÖÊÜ&š7<]®ª¯LòA;¦ˆ1¡dg𔾰”ƾB*š¨4ú5Åh“Îè¡ÑÚç%†”˜Kæ0q$F?R- uvÁ“ËL]f:…™Â4M”¹"1 !ѼZöâ"5FºdðÜÎGê¢]9göóÄg>ûyúÖ1ìwˆ‘eOY­- ©âëÄ.%r®Œ1ádÇ!ïA6HWoŸJ'K¥ÕÌàƒ?'—‚“È~Í&86áŒLÙâå‡ebª…^ÛL÷¶Gq¢‹U‘)rS„«eá¦Þ(.ÒÚb9¯ñje\ÅTÖµ3HÀwÛ ¹ŠsD¦åßwÎ0^psù#6Q?ÿZÐ|XÔ5:p}áýø¿³#±³Ÿö´š‰^(ÒÈ€¯Ú¸ N2ÎKhºbÞ?ãþ[Q§+¼™Ú„4< .33àÚ‘üúGªˆ–@w54§ôb¶PDí¬[kz‰£/ž}mT‰T'üÉ?û§ùþ7¿Ãt5AðLÇY ©58>n)ËAá7²˜µZ™' ?ÁX2Ϋ=•²Xý1ŸõfÀ4½¶­©Â4Ž‘<)SMÝcë'àh'N]9Å#';…HNpµ£ÐµrIïô«§üàë×@A¨pqÛ3Œ$ŽLׯÖoÖY¾1nõ\ìt,”% 'k öï;YÞY/ûÍ9MrxŽDµX¡$u«µïŒ-(¬#œ ¦o¥Lw‡€ñâåTÇ9tZ¨îm¡º–ÜìKWŠ•ÁÆ’-4IÄy¥w{a‚vC«gòZÌáîg쀳%‡ Ÿpæi±Ò/½ÊHñá´”h&Ûn²àæ[útÐDœ®(ï¼947ÙNDçVw¥BFQÃë#o~æó,ÓA!Ÿ¤¢'éÎøëf"e\K]LØÔhr]Ôn—Np‘è»t†wQ,‡©yÕØ -ê÷ã ‘Wûã¾â¬¶EÒ@À&mXsG›xOBqq$‹§oºGõº˜lâh®¨‡Œl‡C:'¦-Ã0â[‡¬¬'Ðka™´e¢æLn•\Ôb¶–#e™¨e&„ [ˆ¨Ð©¹ÎžlžÜHi3¹Lˆß|b®k·ê\";œ9Û=€eALÓ¶Nq.P›³óñ‚7/>C莇é!Ÿ{ðŽo±;Ì¡VSžy|þˆÀ…o¾þßzõûÜÔ+@{]pTåÌKP» Í ŒÕ-Ïý'î§n·˜NBZ¥–BV®»Ù7èîKwKF® Ki5«ÐI:1xš¨EAhBñÞøÉ?ÃåúRé‘M‹~>ìqeƵ¬â¸&´Ò”:çãî ZÉlñpþSÿ¶N9ÓA5ë×Ù²øô;ê²HyûË¿ÄÑEúþJElÅl!N'Â=žü A_k¿°š ²îlâXÙe²Ò×ä[}ù«G}׆OÙgƒÕY=´d­Ϊú_˹.)9†q4û3<8ûCÞ2{ÍP͹.òÊo£bE~4‰W+5A[OaM†Y¥C­Ô¨5vLœ£›¯ÂOüô_áù³Ñët¢ycx=R†h‘mÝèV.Ð ß&íÎéyщj¥mž®²ø`Ÿ‘š­BˆÞ!zÏ", É'C";1βJݽ §×°¾FžQ¾IQ<ÉŒqÔëåÕ¸+8eâàu,õÞØ:&ZqÞ›E—%CÖ!ŒÊSÇ›]rLº:Y:Íu–¶°/3…C™YRá¶M,TšØC5ŒÄÍŽæ=yJ7$BØnΉ!á»ÐóŒ´FjBÌ]eç­àªÇwÑ‚Àp!i‘ê ·a“vÚQõN÷BŒF>ø4ªQΔ6ël&êÆØJ¦×™–'Rܰ· iCi â܉ƒ\KgÊñM*û¾ç‡û²¯7´6Ó=¸Ö8Û=àû7ïsY_“e¡‰Ñçlê¨n]$»ªP£o¡ßé‚D³º é!µè“.ÂŃØ„-â‚0λS[³ØÇmÂÈöì ‘n~ðÛaGÇ‘ó-·/~À|óœÚ&*j¶æŒv*KÍ,´W²Ží¥Â¼‡e¡Ö…ÒÄ%­%­Rz#7áXæžu¢F»Y:f»¡û…®w‚4¢Ñ ugå-$D}O:EŸgðÊ~s-“KåúvažÕvñl<¦vÑàž¾Ú › ((kÆuÝõõ¦ Q¿y` ÎqéIð׫Ø9½)½ôò}þÓÿø¯RJáéÓçv¸žq…\ì]»à¡ÎÜ<ýܾ²º%¬ÿ+æ¾–S1Xi¥ ®%VÌz¸;.UtÕ ÙÁ ›oNµ 矢õÝÑ>X½eN®’ë)r¶Ší$Ö.¥Àî삳ó»múCl™õwN0Œ€:wÀtŸ ´Ã^ºmõõ\ôõœq~åÉ£˜ý*Ρ»Hh µÂüæß…®Ìo],5”j¶¬B%ñ5W¼W³ªÖ‘ÎñæJÕ­Ù2V ­ÖÂN[îõbµÞ)µ(nƒº:Ç€ç‡Ä4OÄÙÏ žjÌqÎ&ûÌm!¤ïµŸ0Âֵخmï¼z±w½Ü.¨jµi‹‚“ t6Sä90Å@íku°¥˜ ’ñÞú=8f ºNn™aù³?ÿE¾ûíñôÙ•ÅB*ªpðÀ4 ^"!Œì¶sÚ’ëÌaMË…â*¹. Î3I1ðX»ÒFq¸–Ù3s™<ð·lÊÈè6„˜¸>|Ì”o)¦yÏ”3s)¸6ã{:…yÐÌãÇ B ÅAŸžL¦T…ØRŒHk,5#R9”‰ÛºP¼#¯v]=r^̯xùñïÐd"ù‘³ÍÆÚ8ÎzÏ,ùˆôN)™Ü&]t÷ª¼–qìÂŽ‚cß¼ýÙ' û3¾GBðø©ÇÌôŷF„ñbàã½dn…€Òk£ÓŸ78OkŽÃñŠÐ*ÎU*•)ÏóD&³,Y3DÑÜÙèmr6ÇEß*ŽÈÜ }µ ¦à»?é {)tó]¯­$ZNþò‚MÃö|T£K>Pptרõ`P¥™ ‰Ã·N—~ 9tRÏeÞ[+mŒ™–iÝÒÔhL7/>Ioàá“7¸|öôŽéûCmJ‡CÔ;šZñ8r­”nÖ©MåÚ^Ô:ÓÕý)Ç÷Wq\-Þ˜:!è–³Û"Nœ£6õö.y&7ä^h­2])”ãÁ¡>ídg¤÷Úá8oþ;&ž@EcPa’Û@¯mS*#Ž.#͵uKwÁ°zÍð’z½ ªÍȵ½‹p¾=£ÔŒH#d徆i›õÁèÂÔ9«,ÞWI9çà˜k%Å-OÂuYxæ…—ó+ºW©¿(®@î*þéC¤†@÷žçuÁ-qfÚ¿$uÇyÙ±ô±Ï@g×&Ξ¼ÉÕëÂñH/œ\YÒ€˜jCüH­Ž$‘,E;×݆39ƒXxz|ÊM¹¢¬ é6Aåä- ¶÷ Û ¹Þ²\_±êjïÊâ)×;¥VÌéWÁrïÑÃ9’hË‘ï}Dé• ]®½Ñ¦…AÉEª¾ô“ïò•?÷EþÖßü;ôµ’¨bÓ¬~ŽÍe¾ø…çÃï½O-·¸KËÊê Ÿ~ìO¼ËþæÀþÅs}º¼âÖN„‘ˆ¸ÄAf®ëÞ‚Û«yÙ»’éÝ¢Ì÷V)½ÒLïàœ.ÕJ»ÜÒ Åʦæ¬k¨³sNÔ3ßyírKAêžZŽ,MÓ–ú*ÞiVþDV3J«A§ÿ£µ¤+äÛ(©}Û3ÜáG¬©n.D~ú¾Ê×~æOñ_ÿ7ÿ£šŠºn6¤R+|ýëß¶÷£ÇŠÖBm‘ÕðÏŠ¼Aœw5Ð^W­àîì3ô|EŸ.µiX¡žûßã#-Ï& ¢WbIÎùôsE ®î­B»„RÀ`¾Âu›Â0ÂyèÅ2&VK›évWmY›k0ÌýúfÏÍíã~b2“t‘Õ凌B™'i Ù‰­^ÔÚI¬).r_I¶Æo‰.] gÄÙ_¿ÄÑ ¢2úJÇùHè‚“ÈfûXý ¥áý€k†ŠÓNqºlÊ< Rðzó˜4?š£dðÚ5—VYÌ|©©`'há¾-«8é3ÙÏ-·*úTþí !‘B¹@ ‰1ŽÄH~÷8—q£<ü’Í 21„ ƒßâ‚vDCIq$¦ ãÙCÛu*‹vk¢êÀÚ+¥š0J<=ƒ=*“Æ!,—àºg“nÎÙÄ3jë*˜ viG’ÈnÜ™#£WøgÞðæ£7Xzeˆ#vo2U YMÔBŠÄ4ÐC@|4ÁPe9Þ‚©îóž¹ÌZÌ‚gjyCè™”¶ôî¬ó.d﹞®©½1 [Ÿsqñ”vïyc|ÂYJœ§ÛqÇ´ìm1ê’Kãæ‚l Qb ˆÐ³~ݪ~Tm…-»àª9À“Ä3HTÏt%çQ*>”­z.¾I' DZ #Û°!—…§O/ùÎï~ŸPÔÀkÝat2K?ÇÄíqÏåÍ-­\³,·Lµ1å‰Üu¹è]çòò%Çýž$«s©2[’ŒÛG|îK_áðò…A7*Ò€e{tD!",ãÖ# §wÚ’6™ójÃè]Ùj|füyçͪi ¼Õ'mí[5ÔݺeWŠÐ] Ä3Ížmh+ ˜%aЯQEU´+½ yÏ) VÔYòåóùð£yöìõ©¸ÒÐ [>ý¥¯qõâÔÄjT¨,•Õ†y$Äd QŒÞ™šUq$ØþA¤!Ë‘“Èê^a×.N}rÖ´¶aû„Ÿ~‡:]¡É¼E÷‘ýŽã¼cuå¤WåÄûÑ„š¶”Žë>û%ŠO´É”²(L÷¯¶¸TÌ}R¨ša|_ë¼.õÔÍøhˆ%ÀœN‹v·„µï´|RHFUg½wj›O'¨^JÅ5šÞ2ÐhyB£õõbö¿Î:¿ã§þÊ_äã~Œ”ƒ*\›… `6!ªD¡¯¸˜3ž¯z¿‹3Û„)½élø_p‘Þ„àÅD Õ ‰v:½‹Â$qT£. Ör¢OÚˆƒó˜}«“Ö²†?Ô…t:Q¬^qúÁŒqCJ#ý1 ð¢”Ëè’ Šó{idšë„â„Yô&RÀX¿ ãŽóÝ9›aG—H8ÛqX´Sè½pœöÔ²°Û Ä͆c) ÛeâÅñ9Ë2ã{£çB›6!A/ÄÞéóB&[ÀÎÔ¼@Íäy¢¬Þíf¡›§-…Òõ¾ !Ri .Ÿ{ûM~æ«?É6žÃQ Ú&ŒŒã CUÏýͰaðÒiK’AqNQ•éG]Š;›ä¬ó]]GŽ(‹xÎY…ó·='n7ÔRxxþˆèµj÷©Þø#£ßð0ì˜÷…ê"ÇåFUŸNÕ¯+ƒkíBW ‘;ÇÖÕ+¼R–Áé3=d¼xÌqššÆsEÕŒ2P´ˆ±²:ºŠÎ’eKšRèEÖ½Z¾°tz™6A-ø8âbÐ}AVïöÞ›³ÔœYcúÖ~z@å%syc_ÚñàÍ#Ï7¼ûî;üù¿ôËüÖoüCµ¬€ÓbÓÇ&AAc¯ôWͽUrýN=ÏÚ-è(Gz>èõ£M¯ ì¼ר’áÄól%gaº­.ÅÓqxéÐ §©9e¾Øþ! k QüæŒßþ~]QqGl•ætlk­’;ìγ¿z«šå̓7Ž­5«YP¥FWq]½\œÅøucD3Çr1X‡¤Ø—2{úÉÏ<çyô#ÑEõ"±å—sàÝÍB"d 5 ó!ÒD˜ëBŒQ»5ƒš DýAZfv3½OÌEwSo0Ž\/…eRñNÈM—Tƒ¤°ál ì§#»:òðì‚– ƒy™ð!’[ãj¿ÇáðâØÐ–—äùJ!¬éÕ!©Ób¤Œ’j"Fç¡éº,GºtÒÙŽôƆÏüÉ7x1—ïŒTGàŒPàÍÏìX†-r¸Y&¶Îóh{Žs·ƒp›g><üˆçûá¼#™Ènn·´–õæW„ êêéJÇUMÚ…7Pºv¾FSn­²ä™M¯xÈ¥A3á›slÂ@Â1âYê¬KË|D¢ƒÔ)òÖ§?ËOÿ™¯ðO~ówyúìâáÀg6¼óé/ð£ç‰®Ÿs]nñ”ãtÆ Ï\$⛳‡\¾þïn(ó¬C¼ß|›ÛÃ-‡›—ê0Ô=ô¬‰•ˆ·°r¼~ª]½MŸ Ç6¬¼¨ýI«—ÿç;1zÚþ%B7/«p*ºµ†‡ŸÆgøã-û›—àŠbÖM'xçƒÒe@Ò–a˜o^+¼ÔU˳.6u¡ìNM¬Nz`ºvƒÜ<ãÇ_âÇ„q`)¾¦³×N­ÛGð©wàýßšíW¬‹‰q¼à¯ýÊŸçãg—ü£ü››œYBk"ï}îûZ{ÿXÌ}5ºûºN¥–õÃKùlÔƒ…Þ‘h†ú«S\¯¬Np½©‡¸¸Õ¸_Ž÷êa‘›zyˆ(·ÝÙBסKÐ\2â †@ž¯:iN§è8ÕqÔÒ;žÊtùœÑG‚ßèòÁ›¢ ‡kžÁGÛE=hô ÁÔºpª½(œ$oÉB>¯#¸¡‡¨Ê½21F-î­6z†. ç…Lõ:lòT´ YºJoé”Üj%Ž*…9/„‘¨FY¸Æu9r»qö‡órÔ‡/À;Ÿ}ò„ó­ãw~÷‡”ý‘$ž”¢ðiCsžf"2—=Û¸%ˆgYŽ\Þ\r,Ê4¡6~Ë›»OË–GaËc÷ˆ«Í ßyñä2óÈŸÓ–gÇKnË-¥ÌÊùnECÂ’sºXöÒ€Ûœj VK»o‚ïŽà"ãøë¿úù¿ÿîoñ›ÿè~ôü’Ûã‚ë‘«ãûd—ùÖµ†PÌ­pì”&#ˆ£.œË A…HŽB±£jö¥êB*J$6Gm³‡O¸½yIÏê'S¥’‹Bb­äÓrÞu͈Ææt¢+‹Úcôf~w´¬ùÇeŸ‡ÀîQâÈó'Øß<ãœ?ñä‹”©s>ìØÅkŽíH^fjçÅ:Ìûý nOÙø^;SžO9â;¯^<µIU¡$ï­i¨H­–”ÖŠÒhCš.Ç!±ÌÕ¢×ÓÌ2h»žÒu"m­œvc§…_·Ù®ÊUÍ…Õ½±Ÿ¾+H«º+àÖT³D!þTà»ßýÀ̺‚MñæP ÌWOáê)˜™¬â#-vMt1Nkôé†ã|«‡CëtÀiHI«&xZÙ¢7ÁÇH.oÿþ˜G¾ûÞ‡,·ÿ?aïñ%Wvßy~®y."2Ò™HØ* öÜŸ=äQsÁч÷=Qy¼"ìýûQNMQ¡½ÔÏe¶Àš‚,aò ›•˜lDÒ°¬‰1й–¶¯ñѯIÇ™:æÈ1¶›²ól¤-.m^áQ}Ÿ™o%CH=FË#oD Ú`Ëœ¨V¨l Å×/!aBgqV’T¤÷=¸€ò9ÿú£Û´mÇG7o3Ö%»ù·?a™zú(C¶R}êåw›ñk2ªÒRdcÙ‘“ðf¤T¢¼CáÑ©Çx9}mÈèyC•U¸ÐÑw=f(xWJv†:´Wä:cTŒ°«]h ¸²“¡—iš®ÁÓã•§K}l ‹9u}Ììð1ýü¡­§ ç7¸ra—Vþê{?å¨p8Ð$ IDAT1ëEÍcu.áz&¢ ͬYITŒ!1´ZHs@Åž¨dñ4š“É”ùéˆ5zØÍØ"Ê¢WûDé'k¾ƒlÒ¡ºFÙ-)¹¯I†|\õkQ €£Ä¸4ð”2ßWÅJã>À¤ñWZ)hžbÜ«Ÿ]£ZŠd¼÷dyNJN` k× €×êéžóW¡b½ÄUž€’`0‰X1äå­-ýò˜ Õ 4ZA3¥FDƒQàÁƒŽ£OÑ{ øÓYÉþ+_àÁÍAé%)eÄÅ1õâX¸€èXUÊmÊ=9öÃõLsdø»ÜCµpɉW{@}rtC¬µÍóa×-Љ=.¶Âa¥8èõEW­uŽ6™Êžò3½o<9úq‚ 5¨âP&+MÒ†èzÒÀ…ŧʈa¸ëgN÷Åå›2”ÎDÖ»ÃsbÂRRÝ©M.Mg^òí×xºÎä~ŠÐVƒdd³ˆ_3«9§ÙqÔÖójHª•á,’bhjè‰x*yƒ¢JšXØÜÜcöéDzIŠb´AÉlf}ËüÅ îÙãà¶•9(Òñ4œ\4) 1ɤµ”òé‘V3”Ä<=ͬTEq-úHiõû#ãqÎææ„óç·88ØåêÕ‹¿bç®1ôr1X‘—†À.”ÊbeµŠŠA#ºZQ‡U{ÅÖ#Ä@Š+kß;žû@¹ï"vˆ«®×ÐËâesѯÑY Ul@×€ â7÷VÃ? ]ËZ‹Q0ª§ÿ¤”âðI¿dþäÖÓݳ‚®]`‹˜„ïjT&‚ …(t‚s¢ š°VJ–õ*«‡Ó¡5¤Ö¾‚µür%=øÎU}èÓ Ó…*ÿÿ)¤•Ö_Øò«1÷ôÌ¿jåÀšEë$8—¤XQf„@>E°ŠD.ò8cк§¨QL6YÞ#0ôBÁòÑŠOËÖ}˜µªì $\ô"T¢!?wn‡ÿñú&ÿÇÿþÇ4]/OZš ­VAC’P'ªlQ¶h¥±™¥Ýà04(k)‡6¤LKÀ–ËÚ”T(TJtÉйF0ø!ÿE+Xb”À%­%̤˜Ë,U1"7%«¼é@ħHÓµ ÝD¢öHo m!ذ-I™¡SŽ®¯9?aÙΨÛêU¨ulí–\¾ÌÏsýúó\¼xÀææ”¢(VŠ‘®ë˜Ïç<~ôˆ{÷îsû£Û|òñ=?:dq6Ç÷5óæ”h >:Ñ‘+ÇdR0U8ç9›/é{É!FÊbƒ„(MŸ‚ÀpZá#³âF¤#3…Ž„*&Ú0'Ë&”AcÉ)mF•ÈLE"’–”åX7öPʰ“Úùî>¡­Ïèºò<±1Í QS/[\} yFî·È]A3[ÎX,Ú¶'F…"N4ïšnNÓÒû†”¼ 3Æ›P:#K÷îbH›‘GE1D&è$ ¡®íh|5R»ç\¤éÏpá”ÆŸÒ¸3¢îrò¢ í:êeKY5Â/; +0™Ís¯ááì “â [BhÈ²ÈæöÓéçzNgÌçDA$Q€S<Ãwybê!uŒÇ%£bÂó׸zõ [[›”¥lJÌÊl8 D›Ý÷=}/6M3t-/éÚŽ¶ë麞ºi™Ï,^²€ D[ñÆ;_áƒ÷±8½FÙÐf˜K†lŸU¶9&góÒKœÞÿˆ$><$-‹Ç™¾2WŠG* í¸3Qø¡¥Ð{M4J[²ê…õýjY¬MVBÕN=†¦^of•’Sƒ2²ˆé\´‚&EÉþÉ·Pî 1Âj€•Ô0ˆEåHJB‹ÒiÊñ™E ­O«Ÿ\§Å¬"j¢m&<]Z­LÏÀWÑ­Çù3j™Õâw9t#bñ1 Ç£0àì  y4e ©—\m%út£4&z±Ó§wÒ2Êäâ2•VE´U-‘(ÄÈÀ°§JVW­íp©Á§@Ý5¼ûî-úሙç9DYY(’¸\×ýªfh^w=ƒ1v%° êYEº@â ^ÉNaH¾ŽF1E\‚j¼N‰[ŒI”eÅÈdYNŠR‡×…H¯5ïé|‡s=i[Z#U{…)È“`â‘"v©cYŸ0«Yt'ÔýŽéö˜ë/¾È—¾ô:¯¿þy®\¹Âîî“É„<Ï×uc ×Ù9Çr¹d6›ñøñnݺžÿCþé{ßçÁ'Þáz…Î36¦ŠÝ}¾ôÅÏsåÊef³ÿò/?åÝ÷n±lj9zkKŽAY‘¬Ú¬@;Oò²H¡"MÃw3H “IÉ…½ó”EÉ|Ysx<çlÞSPYFVŽ«)FçÐ!Ò:Ùe^.· ¶ãÎì„ÃùcžÜÁ5‡ìmW¼ú¹—¸~ýMÓðîÏßçã?!4Ç,-¡›b¤^v´.Ðõ"º9:iZßÐt3º° KbꨪŒ,– ýpäÎË1£ÈÈwä*—V$EëEV1¡`3›Ð„š¾Sw"EôHÄnŸzZ_“¬çâ¥=^ûÜ+œß;ÏãÇùéΧŸÓ.ž UI7$tïÑ‘b#Aa¡ÃÅ^‚è¬çàÒy¾ñk_áµW_a±\ðýïÿˆ|ÿÇ/‰©GcqÉ‹ÑÏRêÄñ˜…Ñ|õwø½ßû^yåe&“ÉpÚÔkÉò³¯£˜Á†?Wþ®f³³ÙŒ³³3žòᇷøÙÏÞçÎÝGÔí?øÞ÷!‹ïEðÔ½LCW6¨wd×®Uäìî¿>EµÀÀP¦à²D N6s¬¸±8àÕƒÚEÉ`”]$™ K69ÀLFôË#hf2sPø¾ƒ×ÝÕyVàú^î—É$b9‚wðI 1Êé#,–ë­èõ<]ÉÅåñÆnZÁEÿ8p[ë¯É” J=F%!¾(|3±ÞÁ–HýåáþTAÃjJª•ÒÂAŠlW£õ£ ø4@]ßJ´ªÁHtjE$DÖúrk¬å§¡êKËÀÔ ÃrX…@ÉŽIk1D$ÅÙÙ‚¿ýÛ&…D91ðÎSÏk¼km@2OõÌZ )ò4@L0ýL[Ê!Œ‹”ð1aŒ¸ì@“©4 KÒÎ;±cGOX8Æù„rD® lÊé¼§‹¼Ì$êy‹C¡„÷ 0¹ ʬ„,§'âéX6 ݽ«™-©ÝŒÆ‘ðÜó—xç«oò•¯~…—^z‰óçÏQU•8?£&ž\kÉóœÑhÄîî.—/_æ…nðüóÏSJþï?ûî?!ÄDêy±Éç?÷ ôGÀ7XÌ\¾|™¶ýSnÞ¼ƒN2A®4º J““úorúäé’Ý™%o½ñ:¿ñëß`oon~È_ÿ׿ãÃOÐ5gtå˜ÜÉÕûEÅH‚&ÏF®±çn¬9]œàºò¼ùöøýßû&7^x¦©ùû¿ÿ|ü'<ºwdT.8¯phúiCKòJ ÇÇš¶Ÿ¡µãÚµ^zåFk>¸ù|Ÿ¦Y²8yŒjåÖe6Ë S;"¸–¶_Š8/)67ð´õœ"«p)€¯Ñ…Âu=žó{ÛüÖoÿÿþw~›ýý <¸Ÿ?ßþÏüå_ü5O>=%jK#IõøYV²Ê¤é#Äž;vvG|å+oðþÃòꫯж-—/_f¹\òƒü”EÝI€Ò¤¨¬šlnnðå/‘o|ãë\½zuHˆüìÇjÀÿâkiõyJÂç8ç躎®ëX,ܹs—oÿ—¿âÿú³oqûÎ#b¬Ág¤Ø²ÊDWÈK1==Y<» ‘dÕ  ÑC'(<)ùaHKκ' h+R×Bê$“‰0­ô@Š‘ h‚_°wþ{a“;ïþœä¥“W¥´VýD$éT’iDGÒj 1Ýz!?èL4úú©ògåÊMÈ5:ã’¼kmNðŽ"/éºnø¡ÕŽ_ÊìxSÆv{8\³ðôD²â?0¨—Ö;þ!4ñWÃ2"*'FKµø¨gŽ•çLFSÚ©#³¢È€ bZ én“ .Ä üU–^¯1Ï2ÑQ匫’®­…½WÚž®—¸M‹")5‰¨¥ % F+•/žk·êã’£kºuÒ¤]™¤’è»­5Œ‹i%78^§á…æÉ«mê®§ë—LmN™—ƒT –¾å¬]é:§*'´] hDoÛ9ó‚Šd-ô®cáfÔý)óæ˜ÎÍ™nU|ዯò[¿ý›¼ýÖ[\¹z…Éd²N%ôÞã½_¿ÙbŒXk)Š‚<Ï×Ã?Ë2¶··yá…¼úê«üíÿû߸{÷ÞËs[–Ë—/rýúu®]»&;5çøàýøôá–3‘©.È»À¨´¨.Ñ9©Ÿ q ú½#+2^}é:ø?ü>¿öëß`ss“7®ÓÔ ÇgÍѬ“]*b¼Êw#ÛË£'žÓ.òxÙ¡Ò’®9¦L f¾åʵ}¾þõ¯ðÆ›o°³³CÛ¶Ü¿ÿ€¼,8«—,ûHY´™È[ÛaP$¢“vFts\©çÚs—øßýwüÚ¯}c,ßýîwùÓ?ùøäãGDfc‡ÆµPe¨(‘ ØE‡–Ùñ#\ëq:Pd†Ø:b¦™Í,Û3L/¾|û›¿Á›o¾Éd2áàà³ùŒwö§G3b 6¡uFCŠø4˜Y´ÄqœßßåwÞæõ×?ÏÞÞÞúdöÞ{ïóñÇwY4Op©ÃFñJŒ «híÌZªªZC1Ïžò~qÀF™òŒ¼Žªª¤Ž¢i?wîÇÇÇüÃ?ü#wî=&¤„JC&–ùaÚ†S5äK«w}ò‚sk=œè#JU$ßRí\¤Y££ÄÜb/[¥IÁ‹pGî\†ôØðàƒŸË Äa”È'QLFô~ðö‚H.bsP®C…ÄÔæä*#ê c³îˆ>5ìŸòµ¯…·ßy‹K—.a­åùçžãõ×_ã»ßû>'³C!µ%*Ë­Ç5Oæ‰,X­¨qÏO9<9byvÂ8×\¿þ"1+E>Ù÷ïDè³.ÛðO"®ó±ÔЫ¬µ"$q¤£¸Ä£œV7f%åÆ.)yÜüˆ”T)*éyHÑ¡Ê)ùöý“»²Ø%dà§§§õ®7=õÿ÷ XÃ2ÏLeP¦€§”Âf…°Âçz`uNn3BïdÕÐR"Ýö g‹O°XrCJÒ˜B“)…ÖV²ÏW¤‡QdENÝJ~…Ö 3)ûµÊb”"³9…•>ç½QÆRíì±èj|3‡éÚïz‚ïÐ)’—S¼ó(øØIÆ‹ÊHÞc•¥wžÚÕ¥(tAnŘ£j-Õ`@frŒ2Y†5†>9¼“þÉ„¹>óK\걃ßûš¤YÈ™¨ÈÖ(Ã÷=M7E,›Ÿ3™–¼õö—ø£?úÞzë-vwwÑZÓu?æÖ­[üäÇ?ågÿús>|D]7òxc@M–gŒF%Óé”íÍM¶w¶)Š‚£Ã#~ö¯?çÉãc¬ÎÅyG¤^6Ü»{Ÿ££#¼÷EÁÖÖ/¼xƒƒ‹û|z÷1Á- k)ª-FEÅJËNRô,¹ú€GË{ØÂñÜõ«¼ýö›\ºti=,&“ —.]âü¹mnßyˆoç¸vNßoRç#T–1•dÉ3Ѱœšú”ºYp~¯â¥—_d=ÜNOO¹}û6'§3b2„h)l)˜ŽùÉI¤!,ؘ¼ñÆù­÷›¼üòKL&bŒ\¼xÀ®óÃþ”ºYBðl›ŒÊÑPµgè{GH)x ;¢RÑwÄééiÂŒùüS’œ;¿ËkŸ{•óçϯIKk-çÎãÆëüÓæ÷YÌéûšÊN•–Ö¼—nͬ°2ö÷·yñÅìïï­¯¥RŠñxÌ•+—98¸@ùÞ-¼Q!)‰ìÎÑŸÌøÎ?|¾ëyùå—˜N7XUÆÐZsùòeÞ~ûm躎‡òñÇB ,e“e™€[é¾ÿÿòãŸpttJbHV!ˆrK`ŽE׃´q+=p ö|E¤]¢”' Wæ©!R©ŸVšÝó»|óß•édÌÿé_ñàA:G¥Œ RR\9–VñZT>¢Ÿ£9úT³†¤D®©µÓWZÅs Øwl! ·'øPƒÛ~0ré&jŽïÊ|Õ«öõ  ѵøúƒÄ–$´Ä°Ê—yöcدƧ_ú¥ïù ,#?«Ï Åúþ?Äâk &Ñ©ÆÚÐû’!·9!EBr(¿JNÔx¢> p«@¡ Dæ)vh£àX.069E–ï;°#L^âê%¥†| DËr]ްã!Ë8¿¿Ï“OïPŸ<"Ú€U¹„ïmSc´Å­tÜÃñ&v-6³Ô¡–š4­ÉU.0òX³¼Ây‡w=¨ˆÍdu!PØ ö÷¯ðøôº«A[‚kAE‘k¥€2šQYâb vKMÍ“îPÌ7*Ệ>,iÚSŠ,òÊk¯ñÍßýÞ|óMvww1ÆÐ4 }t›¿ûoÇwÿáùðý89žáÚ0@[Ÿ†ÎÌ$upÆhŠÌR•fI.f ÉeŒòJkúÐ|σŸrçÎ^{íµ5¬sñâ%^xá¼{‹Å©£KtwÂÌ×äU‰÷‰Æ7/Ÿ0¯áSÍÞÎ_úÒë\¿~Ñh´ÞéYkÙÞÚæÂþUöoÈT¦Àj(Êœ*gM3ŸÓ7s|¿ us66ÏóÜsϱ¹¹¹^ä=zÌÜäälNÔ9£ñ6*›b²aѱ™ð8®«»ê1ÆóÒK/ó›¿õoùÜç>·†¸¦Ó)—.]b<ñèáM7ãÁüÉd\]$…¯[|HldÆv¢>Å¥–E'¤ª|E•sá`ŸƒƒƒÏ\­5›››StQPnlCjÉU&dUò¸fŽïÎHaÁåË{ü›ßø5Þ|óõµ]Ý·ÑhÄÞÞy6&V<šW’ÚDÑwoS¦›[´Mâ]ЙD<‰ëj>­“W®^¸à®AUUìíï³µµ)ó/z4 œ'Wš÷?¾K4=®ïÈ󜃃&“ÉgððÕ}>wþea‰þÉ{"vP¥s:"UQÒ53ŽNZNOd'“@‡àÙÞÚàå—^Bq4«ûOú¯|póC@Ë¢_”äY†rš–Mϲn9¸p@wï„®7’¿>àþër‹g ”¤ £óÔË9!ÔhkÖ…ð(=¤®Ê§1%2ý´ßT%ɳIAðéÓÓ3¾õ­¿#7†G'‹¡«=¼_Óg„Ïþ½(eh\ ŠÍÑ­ øž!Šá˜D?­ÃKa± 98 $¦‚Á¨¤žz_†-ôzAµÙ€ŸÆ.¬öôBžþòÎ=·%›âÿ_µÌ’AžV[~iW!¡³œØ-„¤‰ es ³š,¯ÈR 1Ñ%Iv Qðr!>ÂÐD¤äElK”Jd1U¤#Ð¥~04hòdP z§0z© IDAT6'ÅÀ(/IÞ0ôD¼çÌwÌ›F()¢úks «ñ®E7RWÖ+ƒŠè<Í`ð0J“¡†²¬Úä¢ VˆŒL\;ìøUÏ8ãµ8ì”ïȵ¡*Æt1@;ãìÞQKKC9B– l&!\AIq¡ ÆC„©1eGóCÑ‘¼£* ^|á:o¼ñ%.\¸°† ŽŽŽøÇüGþêÛÅÍ÷>„’Íb‹Éh—øà&OŽN1ùt‰w=óÅ):¯h‰”å„îì ¡­QÑ3”¼ñÆøú×¾ÊåË—?£QJ‘ç9[[ÛlnM1YÎxkç _³_iöÊ«¸Ù’ºYÐá:bPŒÍ&Ój‹{ý{xðxÆ“W¯\YŸ4>󯳖ÍÍ)»çvÉ‹œ~áhûO޲c‘nûH˜L±³½ÍÎÎEQüÊëyn÷UU;i­I*#IŠB•8ßcÌ’dì¤èEæ‡ð»ap¯¢Yß4 m×ÑvŽ5Ë6¢T/Øóðs CUMxáÆ‹<øôg¨DÅ•9*’T)cÒ *%šÙ!›;û´}E;?0¦”ÒŒ´’ ’à•È u9%Ë ÍìPnZiœO<||CÖÂ`³ Þu¢±gˆ"u 7< $c#&:À ¼¥†ÀŠSø)ê¶0ãDxâX!)®±x%ÄÂÀ:‚´Ay>£‹—WÀ/|þôk¿ìP]¯Âa§”À5„ÐKÊðK“`˜Ø ©‡¼4tÉA‚Ñx28ÙÒý©ÙÝ™2Ùq|tB*öÐ&§>¼#‘ÂÃm:'­:Á(–D66¦,5•Ötƒ¼ 7”3[’e§,Ogøð äyAT‰Îy⪙…´ÆuRÃðUk|nr´R¸ Ñ!QVÆf4}OÌÚšÖÕŒÎ]BiKš9¬-ˆAÈ ¥½Ç‘;Ù\È•"—®V2pÑÓÆž6ErDJì6E²èÉlM'¼øÂ .^¼HYŠ)É{ÏãÇùÁ~ć7oIÀÔhÊæø“òœÔÌY‰BŽƒ‰)×%#3Â=}×Ð;É=±ÖRä©Á”MÈ—›-ϸ{ïwïÞáÕW_YC3çÏïqùêeŠŸüŒåYG4ãjf‡2.ÇèÌ@qõ‚ýóÛ¼ãqE[/èRCˆã<$‡-Þ5lL+.^¤©=™–µà=DMf ÖHÕUôÙÉCr“Ó'pZ3¾pÀ“O><¹1dÈ‹¥JÚêS$ÇÒ÷D%é‚É$l–Ó å¾+w˜dS'ü€EבiÒ`M†ó}ìE%¤4™‚ óÓûDŸÈ”¢ £3&Óm¼¾5R\ѹšHŒšF#q³@fJéG Bê®w1øu€Ñd<æàà€õŽ/„Àéé)÷ïÞe>_’Å!å2F í¬tLjMž—cEE„¦ÒyžÓÙ˜¢bTnPéš(Öñ&¡³ ­2ŽN¹yóCÞzë­õ®s{{‹7®³µ5åøì ÚJË“2 òŒ ÁÇ€Ò°·wŽn\gssó3ºéÕß‹¢`skŠ-2–ÎqÒöœs"$ò\Q‡–OGÞc¾8"¦ŽÝ-.^:`<P×5÷ïßãþý‡tÃèR~OHh§U¶ÑÎо!ÚÈÁžöµwøò—¿Äöö6J)Ú¶¥iF£ÑzW<Ø;ŽÑ¨ääì½½KâáÉcæuCnJbr䯰o²7Ú!zÇìÑC’—Âtc5;;;ìîžû¥Ý6î>Ù¿°ÏhTq˜ÎH1 cÂZOJ‡GéÄÆtÂÕkW?s=ŸîEQ°³½ÍÆx<ÔB¦-U6Æê’dr¼kð±Q` t¡§U-1•D¿$1VªŸ]C´]+ý°*#ÃUõ’´• ¿¨è½hÀÓ0”RCl@¢Oh—sÉR 5IâC ½ô©2 v­AÙ1JøvHvR4¾mÑJJ§døÇa— ÁƒÎ'$¿”ï‡á„ O,Úä¤äÔb OŽfüù_ü=çÒy‘B¢´ßµ€¢ÉEu#A¶9_ýÃßç»ù·$ÿ)ÊkRb”½§Ò:1.­ŠŒbÃJ÷/{òÊ£X•‘H;˜2‰åÉã!2á„4œ”V÷뿲Ð*Z ùg†û0õÃ7XŒÉå‚h H0þúF•eéÚ¦ÏU[· zß ß&½5Ie,›ÀÃGÇÌk‘b¤W1¬ÜŸ:pîÜ5ðÐÌ¡3é>]½”›¾áøÁMqµ&E GK‘ {mV t:Ñu=UYa1h½ïЂOkBG+iÖ!FÑÃkKåØyåúóÝÿ”‰Íˆ&Ç´=>8Ya£òÜ#½ª'³#´Ö”¶ ÓŠà#£|BÓ5-%®mÄÐU”dYÑK]ž6Ô±¦Sb\ˆQšoF£ê3Á ´Ö¢ ô®aÑ¢´¦é{&å–DRÄ„g¤*0FòP20ºDC^ްIvR–J›32šb‹¶®ùðæSh&Ïs¦Ó)Ï=wsçv¹sï !9t&ø¶.r|ßà‚cTefÞÕ´®¡¨ ®]»ÊÞù=²,[«d>úè6ÇG§h]PNÏœAaÈ ‹ïj¼_R/è‘b3Ëùâë¯ð¯Ë—/Kh—sܹs‡»wïrýúu®\¹‚1FvÔûûlLÆ Žp¡%§M£“¢äB¾ÏDåLFÔMÍã³û‡]tX“SM7¹pñÓéÆ/í¶WCy<sáÂ&c†nLƒp!bthØÞÞâÚÕ«L§Ó_©M—ë9fssJUåhŸ1-&l”;äª$ËÇ4~Á¼o¨]+‡É°)'dòÞL1eUU­wî+X¦ë$‹GÞÓÒÀ¦0ÄAãàQÜ¡+ýûJÌ!Ò?h©YD›A"Á²×L`5:Zbnʵ;|ùw¾Éûßÿ9óïaó€kÏÐÁ îuÙåàóz€Ç¾G鈊Fòi°XcDõ7@–Ú÷ÒÒ¦³uDz· lP” ÚÒ¥¸® ”r„ÐðÝ?ûc®½úw?êHqQ2‰ŒÖïIÑKÀX§!i´‘>WŸ¬”U-ù ªY5<åÅïZ”öÇÀ öyú3«Í¸” HkDñZ”¾_k¶&SˆZ„’<=`ÊjmQ0²ƒ(u–휠 'ãÁ'c•¦Æ¯{Q]r€¢|íà†“#UŒŽ„bé‘ Ê–œÌŽÈUÀêœvh‘JÊÓû”'³¥ä³$°É ¾h >J0Úv´z_¸p/¿ùeypç]×pÖáUÏâì«%AÐv¥dO+SšN[’µ’°h·°Ñ¢“4¦[[”&v†¢[õ',ê9î?äÞ½{¼òÊËdYFY–ìï_àÒÅ‹¼ûÁÇ´A“•9¦(A¢ŸCèÙÜHiww­ÅC°X,8>>f{{{= ªªbssŠÍ,Î÷´õŒ¹}BnEeTû–¦™ãcÏÎt“_z‘ÝAíã8|rÈ­oQ/j2“£zOFƸœ@çIê iˆ™šsõù}¾öµwxé¥FkãŸþéŸx÷ÝwI)qþüùµdoѨDk•°½cq'š‰6l¥œ z“¶«9ŒðmC މÓª}ì)lÎîîîgT2«¡·‚€Ê²dwG¢#ŒQ²ØÊâC‡=ù$ãÂÁ>.|F ! å3z Ílno EÌ­¡=5ã=*A£<}.¢Îyc™5”EùK;÷¾ï 1‚Ê ›ˆâDn1Ê))[—SñJF=ÜÈP„±’!Jg‚¼¥ TµÃ˯Þàxîx|óC’® Ý?üË?Ñ&\ßÈÎ~µÀ)y_ V­A›á}î i”ª¨²•{“Ôî–’F«B |Ò§À‰k¡Ùz‰àöDÊr‡zºn>ì°5¹ÕÜ}÷;¤¸„(ïm’‘çÅÊmzç)¦ûô]Kt§ÄfQzñ†iaÿUtDÑ„DZ©ˆÕ𤂔#]’ÎËN¤\–Êjb8&xY=k­Q4”Ú™Bº&UNÛ'\œW'Mp=P¨²1]ÝñðÁ§ÌfsöööÖ»ÝK—.ñÍo~“­­m~ü£s÷Î}ó%®w¸ÞãÝ’Ö%èfÃ1P’÷“™’iµC—,1x #Çõ.%iAbZ•Æ'8::ãÃ?ä­·Þdssc ÛÛ[\½r‰qA{ÒCÉ—‹$×¢bàüÎ6ׯ?ÏÖÖÖ D\è Ê3O¹zíêZÕ“Rb¹\rvvÆæææÓëY–ìloSV'Ë–y¿`cc­lŸqêØÞ¸ÄQşÝcŽÚRoHA2¿ˆ59ÖfŸ!TW ‰sŽ#ùhò ]ÛÈ0p^‚(´•D ¬Ê†Öj£$7œ©IfŠÃCÒ “:n~p›” ½"ºFêÃTààÒË|zï&@7tîá˜Á‡c3\ß=Et‹šLWC ‚u[R ´´dYÒÉwx8këuŒ‰I‰®9Ì=:Ѱ‡ˆsK’1ÆVD/I¨Ñõ¤dd§î: +³Z%‚ëN,ÈÆÛ¸¦A)‡Ž‘ñÁuúÙc|3_o´×Ī œ5ÑšÓÔ33ü³„êK»Â¥VÄé@X¬æ{Ó-†Ðò`‡xOÄ.¬Á˜’¶i‰‹9:-e¸ä›„¾lI¯dIu Õžsìm_ãÖßÃÄ«4¥ÍÑÎI…oÑ*ÑËêo6YbRôDº~Ic¥t’묓äÅ[›ƒó¤„5–ES³ì–è¼ 39¹–x¥0Dg–³fWš*ŸH¤mJD[²÷Üçypû] ?¤E†´r°)!J#Iˆ»y¥ ³{ä*Ã(1FUy‰Føï=6FêÞ±œ>xÿ&·oÄ… ûëÝîd2áµ×^cŸwÞ~›{÷ïsxxÈÙéÙ:Èiv6g1_°\64uËb±d1oh»†à—´ÍŒ¢Sl¤l^â“bækfnŽAŸœpëÖmŽŽŽ×0Æt:åêÕ+L'cžÍ ];=äÿ#ìÍz,»®<¿ßÎpǘÇÌÈ™$3IJTµJUj5ºªºËm~uð³ Æ¿ôƒ¿ Û_À~ò'he·ÝÝîjI •T*‰drÌdŽ‘1GÜñ {òÃ>÷S*À`dDÜ{î¹k­ý_ÿ!ñà«9ÝLqëÖMvv"$P×5‡‡‡öªªxùò%¿ûÝïHÓ”íííöžX[[#ÏSŽ¢¼ÂJI-fTÆò`ë!/^¼¦ªk†AôÜw™ÔÔJQ7”àß÷œY@@Á´JãNex:$Ý!U9ŠÔJïÑ:FQº¢ŒïG±€OââO Wi6¤žœÅ¢<~¶í‹ÖÚ!kH<ÒCˆ°°X4 w` €!ÈF!º¨a@ã¥!ËâTyƒ‰$s2&*ÖU´ïwû[QU1»4zÒ[ОÙô¤ÙsJ”‚ïþÑü“?ýcþûÿáÅÖ®%I˜"Ý *.} γ¼u—«“–ÎÊ."ÑÌ¿‰ÄIïAhâáD Œ€¦¨$#ˆf½8•¼¹kÿ{ŒÃTŒ¨ŠØÂ’’xXDZ‰fYªæpЬDœéaŒ™x™…$èNü¾¯ßøs¶ž!X¤¤@0®]Â8© T¾Y:hAJ•q5¹l^¼h–¥„Š«D–Nðh))æóÈ(‚ 5¨@í , ”î ´$‚4h¤ˆ§™-qÁc}”8{ÀÕqj÷ÄlIâåñFTJD<„ˆçEW±Bã|*ItŠVšà#FgELk–’ØšÑÙŒŸÿõ¿Gkͼ˜óöÛo³ººÚÚú¦iJ’$ ‡ÃvÂZŸ?y4qr|ÂãÇOø»ßüŸüöû'\Ì_3©Æd½edÖǧ8_ M¨¶†óóKž?{ÎýÑ÷ZKáµµ5¶·7H’/©æd#hCXÖ×V¹wïÞSæåå%_ý5œžžRËËËí¤™¦Sϱå +;(™ üýèGììì ”¢,Kž>}ÊÏ~ö3>ÿüs&“ yžs||Ìh4j±ì~¿Ïîî.ÃAƒ£+æ³sªúS½u‚÷x•èðÞ¹º³ÿìkB]ƒ³ô†66Ö4ËÔ”òôéS¾þúknß¾sŽ$IèõzììlÓíuÁ°Î†½·nïµ–ãñ˜Çóõ×_³»»Ëw¾óºÝns=WÛ°çÆB·Ã©(¸<û˜¥ËkÉA %sjŠÆ„K„H]xÇ,î¥Þ²NfsÒ¬Kžö™Õµ€ ÒÆ K’Ða¸¾‰HúŒO>‹ Re>#ب0v늰N>\¡š€%8ß • úrS—A¥×¾6^¤ˆ|o®¾nLÈ"$º`™ˆÈlZ!àš`bsh ǼÊsëãÙ@E!>•¯Z"¬Ç›ˆƒ‹fŸˆÔkSUüúoñ»¿û˜ª,šÅ-„:úÅuƒ‹E»AD®N^4÷Ì/´D6F™H‰ëÇNã·x[³¶¶ÆéYŸ£lšè·ØT× U©É†ë¬ï ™þîkp3¼°,’@1y%ìjª€"Ã5Ç/ÑP½‹1RÞ{„R8kçÍÅ1ªy¡‡5¿ðxnX8RÆ í_,+kÒ$Å»(¯Ž9‹”uð¬E‰þÆx”,hÒÁ6ùêãã/P>îÒNŠ órŠ‘,"¼”ÑÎ749‹´Y®–hÈTÔ‰Žoï=1ñ<¾ šè ‹9ª:É#E0D˜F IÚTH"Äc–î.Qø ¥<é¬çèÅ ÿ÷_ýkùþ¾Ïƒ‡ï²³³ÓÇ…ãc¼–×N «ßÅt|ãÆ Þº÷¼Ëý·Å¿ù×Íg3›_á*Aê‰ÊYËzH×ÃÖ®ž1MøæéS.//ÙÚÚjàŠ%nîíÑïåѤ̚èéÓϸµ·ËÍ›7ÛÅŸµ–³³3¾ùæ^¿~ÍÉÉIL‚‚–¾×ív¢¿©0UE*¦Ås;akc•‡°³…\ÖZ_óé£GœœžãƒÀ¥«˜çXWl33¤(¸u{Ÿüä#Þ~û>yžã½çää„_þò—üêW¿âôô´]^\\pzzJY–¤i‹îöÃADÅ”,-NÔè´Ò=œ|úÛOJ1­F˜PSùŠÕ|‰›{7Zêâ·O0ÏŸ?çôô”ªªÚâ¾½½Í`Ø'(OQÇP`iiÈýû÷Z¼Ý9ÇÙÙ_~ù%/_¾äèèˆù|Þ^Ï•••f9«À;–“ˆ.3á1ÁsiÇÌÍ„êËŒ’dƒ”‘/©Ü¬ÉPoLî1ÍÉQϧÈ`ÁÕà=Ý´C¾t9ÞǃÑϹ9¶2Ô“STãÈ)¼j¢óüï.-B„uêÙe[ ×k‘°Pb6o¯8¡‡&¬ZBy†5­ß2ÚÍq^-¸óߦ…H¢€¨!‰oà2„„ng‰ª.¨«"6F”$´ŠÈC°pÔõ¸ò+³hìjéECt ß‘Œã÷T²¢i²˜Z«ŠfZ_$KµÝÎ[ÎN›B¸`8ÆÔ»Å»V¨zG53:<ŽÀ¾XØe.Z‰2¸x|Yàn!v©öÛ,jªIÄÍDÕ‰ H,xšÍq)4Æ#ët»ÔðDK…'Nªé¨µ­Q*Z§Ý.®t7§Íñ"ZÒv„ff=xƒ–MÄò¬÷x¥p2¦5U\;¢¨DÉþQج‰ U!ÉtB"ãBº²EäI—TAÐé®6fk’¹¯ÉkYlDózÊeyÍÏë褃+–Šj<çÅø£WÇ|þé—ô}:Ýœn¯Ã`Ðgiy™Á°Ïp8dmm7oDçÅuVVVÈó¼¥îíí¡~ª°Ö0›Îxô»/)ëÎ’®HŒwøDbL¼ÍOOÏyõjŸ>˜’çy #,/ Ä\Ù4KY[_áþýû­±•sŽ‹‹ ¾úê+NNN˜L&œ1N£×ŽRô{=666HrÍh<£ï£OúÒ0ãþý{ìííÑétpÎq||Ì'Ÿ<âõñÆ‹¨Ê \4ssf‚­GÌFŠþà{üèG×KTc ûûûüò—¿ä«¯¾Â9×À݆çÅÇ!²£†ÃÛÛ›ä™f^6§Q3'›³J!K˜Ô1u)ˆ€L$ëë+ܼy£U¦Zk¹¼¼dŸ£££7–· ±ÝÝmzÝ£Ñt:qy}óæö$4yúô)írvQÜ3ëët;)ã²`n眛 :J ^±‘/ÅHźÂä‚«âG;7'ð7‹ûÂ%A“am׆<é L@È..ë`‚ÀØ9u]`C…Ò*ú¹[‡R¢¢Hª*çxÁRÙÙ5MT]SÿT}D|4„i'ފмXÍ£…ÍÔQ)ÚÉ{TU§¨XñD§‹ª®˜ÒËLe©><.­•³ pÑÅ0A’¢”ÄØˆ½Ó 0Á—Í•K±~ R™B’ƒJf†@#}E9ºˆÖÀi†àŒ'¸y„p›ë? „ÖTós„óx ¼iÈ0qàBÒÐ~ýû¿G…Œ/q´›lè-'vAß@)Õä„…¯£ +R.ž£©q ìçÛO*”ŽL…ˆåÇÎ$x!"ëFÈFŠŸ@¢TD!*8§“ ¢O,öÖ­c¤¶š[›«üÿåÊÿü?þo³@’˜•)S¶öÖ¸yŠÉBÀ8‡žDkdkpÁÓ[Úb<=G ‡ÒQI[{Kí¯}í-±YÕ8!ÑR dìú8I®$÷>´‹Ò”aJ-çdägPIŠ”§ïõûˆB!•¤61gVù_[&g£³YL®’•²<œõ$!ËV×W¸}÷6>àýÞãÞ½{¬¯¯·¼~ôÑGsztÎëƒs,%§ó3’¼O1:EØ„Ñh³§ÏF¬­­µ¸ûÆÆF¤ïU%NÎÞÞMöönÒívk–Ì_|ÉùùeYqyyÅÕÕƘ×ÞÜÚ$Ë4Æ[7ÆR–µÕ-Þ{ïaË^™N§¼xñ‚Ï¿øŠñdI†×BÅ×%¸gçHéÙÞÚä‡?üc>øàz‰Z »hgg‡;wî°±±ÁÖÖÛÛÛܺu‹wß}—åååâ ÜØÝ¥×írvyA]x]Kµë`T·§QcSÛíäMc½\EÑÂR¾±¼‡ìííÑôGñ]¾¼¼Ä;ï¼ÍÆÆFë[~~Η_~Ùž0ÎÏÏ™L&Xk[(ikk‹n·KrƒÞÇfLÞYbU/‘ÉYUÌë‹¥,§h ucg»°«ýýp)ã¤*%QW’h”ŽZ‰Nš"´gâL4Zó†´õ‰ðZL¢HËjÛ@Í ×ò¾µn•–õQ¤B›4µçÚO,‚jèêš)?ýéOùó?ÿsÖÖÖZžøâ¿n·K’$mA[,Uƒ’p5i*À8t"ÐHjWÅP˜ÆÏd0X&Zó^œÇc^½zÅåå%“É„££#®®®ZÏü~¿Ï^k0&B²µ¹É;ï¼ÓBJUUqxxÈ“'OÇÔÆ0¹¸¸ ªª¶¸ïîì°:XâBϱ"C¯µˆ$Е)YgÀ((^Ï©\E­*G³ˆwPÜ•ŠQ•ñÝ)ÉUá5^‰è¡Óß%)§Œg—qA(%aa†åc&sìEâÁµžI¶ib@Ü¡ˆ…W{ RÍ®E4Å=¸£ÄBoT!f¤àËXÁTBWvP@.•©Èòk%Em©%H^鯯¦$ÕôÕõV-œ,€?j‘4â¥f ö5¨4z¿/‚À…Ä©¦^ …P¢4ÂyËìä²´Cí}T³Wp ü£Á—@&iÌÓpãä‚®Þ&2½ùñ†å/ >´éÆïˆo_šŸ 4]U€úø%ç§Çˆ¼C(¦á±u…P¢ |Ý5×lÃã Ÿ“æÖÑiÚÇ *K1”V‰W)"ë!ŒAº+"SÆ€p‘ËjƒÃIÅ´¬ø÷¿þ”¢ŠYK0 £yÿö¿û_(ª™eh+Ð"FëE«Iå …–%Ö ‚‹–¯±§67¢÷$* äb)"¥+£|›BÔ`„šæmP{*¥®*ŒpÔ®ÂÍcŒUé•“Í ]!ÅÐËútdŽV’I5‰ ã+Œ­S{Øà©Íœ€ÇT†£—œÿŠã£ˆÍþ³öpçÎ6&moï¼Ã×_<áò¼@X‹s™Ä]K¢4¦,8=9åòòc yž3 ؽ±Ë`Ðg4ºbww‡´Ø¸µ–ããc>ûìsNNNprx>/899e>Ÿ·ÈÆæý~à-umšIv•Þáfò!•=úœóËM’ä$iг5¦.”¬­ xÿáÛüéŸþ#>|Ð |ºÝ.ï¾ûn»;Xì$…üïólét:lmmÅ¢«b#‰ ß_g.“8G’™—)ç¶ xÁêÊ2·ï¼‰·F#^¾|Éx<¦ªª˜žurBY–íždkk‹­­Í¶ùÞ¹{‡½½½ö$4™LxúôGGGÔUM´<.ZÒ`0ˆ6› ‡}é%ÙU1,䪼dZ_ŇëB¢9¹E½E¸Äþöuˆ×§µiœEU<ÏÛÚ0·'(²Ü’ZÅ´*0Ác¼#(Ò ¶Ž· 1;YJ‰Zø©Ð, ƒÂ DÑQ°¸E¼gh¼×¥ljO µ@÷¢ÃòÆwùé?¼ÃÅ,áo~ö/I&ç1OÛ ¤ˆ,µT阑½DSzCMtª„€RY<½ˆ&TÛû¦q4>Y2v%Ùd@‹¶f6‚¬…÷–¤©.’O¼&dÑHm ¶A*ŠrŠ”‘¡S™1B%¤É­’xB 1¤=ˆ¦xû€³5¢Áî­óH•€«ð¦ä:Ô£ؾ½˜ÔÝ¢r7A³‹ ‘Já}Ý\lM§Ó§œ]ሑAx´Î°r3W!ª]½m°<ÕpÑ›bIPòØ™t%<®)2Ñ'Ù5Ç,‡Ð!í®RÏ‘Aáx»tñnc/ããQœä'“I½·ººÚNï‹F´HœZ°d?þš‹‹+DˆžIeYqÚ4K y¼Ë¬®­¢Óèq”yI'(Tð¤2!W);ƒLm1ºà´<&Q)Fʦ€Ø¶¸·ñyJ5…=&X|¨ ¤¸¦ð)cÑAÄ`QûŠn/ÇÕ[[´HJ’ŠKeÏã”MÄŽ½ˆÍ‹"¢GÞ]¦¬.ÁЬQ…Šƒ§:*ÒuF0»ú„ó/÷é©kRã;ýµfš$Mö—89ÙG‡¨2wB#ECßD¢ã>ا d]@áÜ %ÕlÒì¢I’‚wHç@(œìÒ]‹úê[] t´Aà<‰Léd)emJ`=¡èç+$*Ź€ó5Y–RÙÆ³Æ—„@Mð/8‡”[YÀ50vóÆmж^ÐÛÿbgd‘%¸ÀÝETb.Fx!E5%¨\@7¹h~V6Øeó„Hêÿ–0JÊ€*vjáMILƒ!¹ös¬†ÑZÔ‚ EëòhLô–$q)ŒÁ …V.ž}¶7kïâ11ÉSËÛÌŽ_B0”Ö#e¦Û°}ò$ņú±{WÞa\Œ³ 2þN!ø€ Ž’€Šž¤J"CŽ33fnB¢2RÕ%Ñ)ÎCWÅLØÊ8¢ÉYG…µž$íë.½$ACYL¡B5<ùLåh)HEL€)«‚yU8O®+¬+˜–ÏŸ¾àÓOñÝ¿Û:=v»]ÖÖVÉò‰ оîŤvm˜Þ”óŠ×‡¯™N§¬®®6â&!øÎw¾ó†ïüÅÅŸ}þ‡¯OpA“ä}Bp”ÆqzvÖ÷ij³³K·“3é÷ºÜ¿Ÿ{÷Þj£ïŽŽâ"õôü ™tȺCÝÅCa ÂÕ¬-¯ð“Ÿü˜Ÿüä'oÄú-Šøïsc EQ0ŸÏ™ÍfL§ÓÖòîÝ»-2ØÝÙf©×EÔ– ]«Ù^Þ$Î_RM¯¾&ígÜØ»ÁêÚjkúVGGGœžaL¤éŽ'^¾|ÉÕÕ»»»!XZZâîÝ»lnn²¼¼ÌƒÞ€d^¿>âÉ“§L§s”Šت¨9ið÷ÐLÃÃá€ÝÝuÍG–ÌyrÑA*ïg•!} ï%W#럭rææ(ÖØ¶É-Þ3 z¤ TT|‡  Ò£D£á „Ã;ÐH:å¿úÏÿþÿë!¨†öçA«Eì^Ä¿0Øâ-¶‰€Lj4é¡ß’ª”ùl ÁÒ•iÎîŠÊ×8gI•ƹ QkNOgx"b¬uœ‚E S )Rdãc¥”¤ \Œ”ôbâRKI‘’´·N]ÌqîABÒI©Ï¾ŠÏ'ÍÑmºK7¿þé •ÑM3ï©…o®k†–ÚÕ¨ (]À„• Ý.ÊÍ1¥Å{ ~QE4ÜxDp¸ò[޾å‰.¦uô5RÓ‚ RÇI;€I,v¾1’Grª!TÊ‘:f Š(ã2%ïo0Ÿ\€ˆ®i‹&âI€H :cçÝïñúÓ¿EøŠLóðh»Iw…ºœC]ÄM4 ÂÕø "e°s‡»wxú‹_@¨ €cŠVŠD¨è\èA€±6.…§çT³3´Ð¸$!E*r„aDÊíûßãøé—dTÌ«ŠT)‚óÑȟвªëxìk0F¥£ï{XQ¢PO¼iµÅÛf*  | ˜ãæÔÞR:‰Lµ±äj_3s³˜é¨y’Pd:G§±¹jçj/ðMέV:Ò-Ņ̃±È,Ø*‹°ã´õñ¤J1Èú¤IμšlIUw0‹â>™¶“íêê*wïÞeccƒ‡¶§²,98ˆ‹ÔñxN' TŠ1%ÎÔ\\\µl’$ ƒ†Y2àüü‚ÍÍ ¾óÁìîf:òìÙ3¾~ü˜é¼"K{dI/úv·hK§“³½µÙ ½Gù½( ¦Ó)Óé”ÉdÂh4âôô”ãã“–V8N¸ÿ>ù—I¿ßGkO)»»ô;]F§g¸zŠL‡LÎ÷™ÃÌœs>;¡´¶†ëܹs»]Êzï™L&ìï0‰sÂ|V²ÿꀋ‹KŒ1m(õÝ»wyë­·ØÚÚâöíÛ-Kf2™ðìÙ3Ž)Gè,fWžÓã3ÆãI{=‡Ã!7÷nÒt˜\\ BSÐ%‘ñ4blMig¸`ÑZD¶—Šöu]_sªY`î2æ‡À’îÒ‘=tÚEu6¹aXî.‘ˆ”:ظkÃòóõ[:2á£?þ€ŸýꜬž„ø;Á¢„D$k Å0PPS¸߈ ZJ2¥He´ñÖ\…ÔëÎŒ¨ñÍ{MIá…«@x-%­¸…Çã©‚âN_ì³}û-_|†lÒç¼q2^0þt†™]6K朠Ö6ns~z— ¶$T#ª³’Õ¼C®—!4KYƒ%5JjŠb†õ5…ò˜÷*MèVí_FX'€)ã²ööûØÿê;=Y"œ‹6oÀ,qropDˆ~äHòÖÖე@glU5¿G4K^4 ò>Æd#¯˜Î9ß,Zih>€°¬áèÓŸ·‹Éˆ¹5˜ZÓªù\s, H•àê"Ò¥`zð‚ùhz½J!EL‚òžPUñï q…%ªKº´Ã÷~ü>ç5ók(/ÙÿúWà ¢“‘xGm%ùÊóѹð(©ŒÞÙæä £«Ÿ¯‘2ÞPiÒ'Ѷ.@wPIFiK†:<ÆÖÌê Å¥›6,‚hžf|ÀPPÈYÚ!ËûñohAŠÀCå4Ýl€@¡ Q$ãPRù&•i‘÷{Î9¬1­I’ ’®Hé§‘Y‘©¦\UsNŽO¹]µÖ½KKK|ç;ßÁ9Ç­[·Èóœ£ÑˆÇóêùÚ¦¬w—HÒ.³j̬ÙgU-ae ã(ä9WF0ºqvzNY– –––øðÃÑZ·|mk-GGÇ|úÉ#ÎO/ITÎJ¾ÎJo…QÒcßU”EÍéiĉ‡Ã!N‡íímÖ××™Íf¼÷Þ{m³Xz}öès..Fx‘‚NI‚« ‹¬ÒNž³õ­©"óñãÇü‹ñ¿ów¿ûçç—sC1/©æ¦vQeHDþŒ‹êãñhÒòÇb°õè™J‰ð–ºž’÷†T^à“kZi6Ö×ÙÜÜjùòo¿âàಬItÞ@ ñxÊ«WûŒÇc–––ZKçž`ÉÔuÍññ1Ïž=§žYzé©Rgç̦ó7o–elnl°µµÉóǯ˜W#®Ò3Œ²¤¾GfÓH’ðÒVØ™WÖÙh­áÿp¡Ê‚e·€^¤¡òY)`ª²}+™ìpñbÆù«/ðUEWȘ‡ì-™hˆ6æý:¥0B"‚'W>*ZI©µ$3 ,Ãɨ¯§ .’D¼'Ï™›pVN#«GÆÓ­ EH¤Àz‡u.J„„@!¨…®¬Á¡×Þ&\íS»šKGtk±XÈ¥¼æuk­è(tŽŽî3–‘Ÿ¢Â{›€ Hå—Áx‹‚Ê*çã×nøký•ˆ wEp®QÅ{¼UMÃ-õ” Ò›È.óözp o~¾^¨†8ë[KIóšø¤T’"“ [ƈ(¡3|c\'ìèü†U$÷~@ýìSD˜ \Äú|0Íæ¸ ߊ6Èø‰ôŸbì[4Rx•Ò[¹Ålá`ÿ„²ã¤]…Z<¿Ù1äxnÇÔ¬- ¾ÂÖsÊjJi& <Û»[7çÈE˜ÇÇÂ_ÿ»ŸóÕWß ‚FËŒ =’,C‡"EåæÌëUe9>:f6›±ªÚ^â IDAT¾Õ¶KËKloo’ä’b:‰Jl+©ƒÇøHKëõò& o©]äEÁÉÉ çg—à%y:@H‰q“éœ/^ru5âÆh­ã¯hª¶hѶàg§¤2gu°KW)Í”qq‚)-G‡n[_†mË+ËܼuƒOûŸ3¿¬q¦ ÷ktIQAÔ®j˜3Œmä›ñêª1DÆš’ª¸"A T‡&áë@ é&…Ê1¦É$n„6ZH:͉·6u´ n Ë*œ¯$x©PXòPÓUB+*VAH%•3÷m‹Š($ád@ú@pP£!"·p!b†qžt°£goèÑÕ}²a‡éô"BH4;ë›ëu0ÔB05%¼ÃrÕåJÌAÅýU𩩸r†ÊÕ„`IÐx‘D›Œ}fäÂnE4.šxLcÔæ¤Y† U³L… 2¢ºWGn¾ÿTÈE—&b뀔ŠàgëË…Ó[ƒ ½f¢!6†êÉß ¥%€KÓ¶±´Þ×RÙX,\çjO ¦`vò”|¸B]ûÖK&>tÑ$Ä4­øøe“HeÓ‘­bqxWc›ˆ/ë,NÚèužIÓ.ÇO¿A¦-$I¢É‚@v»ÌǼ·¤^"h(â†ÑL,ºJ¦ã}r­²n—Ri|•Œª=¥$Tð\UWnÆÆÎ2ÿä/þŒ?û³ÌÚú:‡‡¬®®ð¯þŸËþËS‚­ðu‰W\4ØJR*o©­üÚߴƸºÀÚ9Avonó£~Èûï¿ÿféÉ)O¿yÆ|ZÒÓKôò>yÒ!‘ R Ò$CË„D&T󊃃C&“)[[¡õ#_~>2Ÿ=úŒ£Ã´ÌYÒÛˆ[}"ÎXSNNÎ(æE{,--ñàÁvvvxûí· 8çxýúˆO}ÆéÙ%Bf¤ºƒ­çh<Òz´‹ÞÜ{{»|øáwß8A¼~}Äï>þ„ýÃ#Œ•äùÝf¤HID‚lbÝ„–0»¤[Š¢nð÷Yûø–——¹s÷ýå>ÇÓKR%±B t\@Z,½AĺƒA‹·O§Ó†%÷%y:$ѭ옃ƒ×\\œcŒiQ‘|ßV¶>yò ³QA?°œ¯'=Ž™L(Š‚ããfÓë¥jûx]Æç3œuÕ4æ~ùÕµ«˜Uæf¼œF·DHÒäüÜ­5g0¾dT^PÚ’4ÉÙ{k‡ñÕ”««9Bh´L±¶Cª;$IŽkl\¤lO>.)…$H¤ø ±u䀛Pᄦô‰Aã8µÂ9K7‰ð¦u阗h™~R¬‹ÃÎ[,QŸc‚'È€3ž$‘¤^@š#\F*RR¡Ð³š¶:YëB“ubò–wø€ ’ÄAžt"DõºŽªö™­"›ÍEJdŠxpó -£e‹V %<’¸ì7. (=ÑpÌ”5Ri Zw"aûÎ]ž=Á•5Á9D³'m'uÞHbZ˜ãxbºÐµ•æ‚9ãÑbYÒÐX„fë¢ù¾” Ƥ|4 k0¥…@Á;×ášpb#1 DDä"XÊñ9B ”ˆ¿A\ +B+ïB4ä~RèØ@Dx¡©}ÜÀ°3‚·˜r„¯§ä‰Bº RCJ ã1u2>Bb±ÁP ‹ )©ÐhkJ1\ßÂÔ5õl-ƒE‚FŠ” ¼`n§1ËÀ‹Æ ƒAŸÝ×¹·Î9¦Ó)GÇÇÌæ%*ÉIºr¬%ËèjÂÁÁkæó9N§-ê‹~ÊËg¯(g59$•YTA+‰в´œŸ0ZQÔ`0àÖ­=–W—xñlŸQ}Ž—‚T e=£2U=£v¥™ãET’ü÷Â: îÈt"ÚãD§ga8<±˜ÊbœG:E’ôÈ’g ¼’(@g}Ìk…k¨ÕZ5îŠÖ#$YŽwâë‚B¥ibA T*ñV`k…³)4C…ˆ[ÄMR¶·–Çœâ€&# "A¢œ#!4 _G¨”Š¢nÄ{œwM“ ÔåB,öµPllm³ø‰$Q‘¤¬D¨¡ŠÙUCV¨4ÇÕѪEâÉÓ>ÆÔ_EJ)*Â?ζÖÇm ½%`”¼üú ‚-¢|¥……xj1(#~ç¾à9 ùc‹Ä¥²ØB䡆Fúº°Î s2 ̵'EL”eatCˆÓ€V ë,½á*ó¹G¥)¾!‚¹–‡ë>´¼{Ÿ«Ã¸P6°Žoœ<}k‘ɺ‰oª(c¾B£¤À•¶±ˆ^1™TÑdÌC¡Y¾XBRàEÂÎÖmNŽ_#ˆY¨¨±qZ¿¸"i¨Z„2‘(ï Doî”hk¼ M¢ßö¬œàÌc£PP…‚ÖšÁ`Àûï¿Ït2¥25ûë¿ãøèŒÚ̾Ě9Fg[7"“ýˆAw3ÖÖ¶¸wï.ýèüÉO~»ï¾ÓJñçó9O?á׿ú LJçt’%†ù kËë|ÿ?~㯸8œ§zù~:d\Œ8?=oíJÎEqŸN§<þ‚Ã×à$þ€<ï!uFaË(^ë—WW\^^ÿžÁ`ÀÇÚ´¥óós¾øâKNŽOÑ2!MzdiŸ$( 7£0S\°l߸É÷>üðäññ1ü ûG#±.Agyt˜M:xtôw5©‚ª˜áëŠD¥Tõˆó³k‘ÑÂ]óæÍ=î޽œ'ϘN l%*Äxríúlnl´E:Ú”œS‹P9y6¤×YÂÖ3j3e:žóêÕ+F£+++01/®éÉñ)Þ Ò¼G¢;(•'5¹îQÌÇÿ]olyzÖ÷}Þí·œå.}{›éÙ5=ÌhfIŒ$„…$BHÀAÈ,eal Bʘ¥b;T0‹)@cÉb;Ác°Á!¬D‰DBíˈ‘43=[ÏŒº§×ÛÝ·ï½çžå·½[þxçt·DNÕÔÜ®îsîÙ~Ïû<ßç»0Ù;àúÎõUÊS–e9r”wœà…çN³˜%6’ù‰OñäNZɸXg˜0”¼òùkt®u(Q˜E6BWóébe3»,bËâ¾··ÇK/¿ÌdoŠ)³d$Õ/äYAa (ªE³Zƒ•_ÍR4“è”—xá…ÓLg5Ñ„`”mrdý8^iª)Óµ5îpÊÑD‡ ‚ýÉ”WξÂd2aýÉÏðñ}†½¤TÚ¼‹¦j)HKMM$‰½æ|H Cú<Ù¾*H$N¦T3^@”‚ ûa!3Yfp!Mþ&K6Î&/ýè¸zŠóS:Wã‚ãÅ—.ƒKubU­ ‚(TùE½Éúðc5&JMB*ò*Ad¥Ò F¤ØÌº©˜q@O 8vÕ…96ØÔ­û´g´6Í*i+ð^"hñ‹Ýùˆìœ}àZ„X`ýŒDï­zÄ#Å &O­¸,úr©¸±ð]Öô¿Æ[¦_‹ô„–tŒ½ ’[ãÊ<+¦‚#ÑG”1ßôi<1CGî¡Þ>M [TÐX) ,³·76õÞ¶½ò6¹Å­Šx_0„Tý©•&1jiÄkÓ„[ú=D¤_ ðš€À”›Œ6ncvõ,Rk:· Aè¥È‰QÒúŠÐÚ”;´'É•@ɈÐE'À†€p¥PýH&¥b€$ªÞˆ3Dr¡0! Œ²œ&Ž¡cïú_üâ—xèÕ2VéÖÖ¯ýcÜsÏݼéMoâüùó+—ŪJ쥢, GlÚä¶ÛŽsûí'V쑲,“KfO Ël·a³8Æí÷²6:† ‘É•™Ð“1™ÖäÙ¥3ªE»âl/ÕžX!»×w9{öó%ÖA¬ˆLý/À†ˆRºçy_ºt™étºò*_zˆ‡˜L&¼pú4gÏ] i¦‘™™,0™$¶,›<øà?ž”œ!vvvxê©§9sî<­³è|ŒÉKÖ͈Ã;)BΤӶ µ¯!$©ÒØìl2K{ñ¥—ÙÙI&cKhæ¾ûîåС .^¼‚õ]â>‹´õL•›óR'û¦Ó2#3%µX=¤®ç\ºx™«W¯ñÀÝjZš;wŽÓ/¼ÄbV¡Ä¢À‡Ž 3D\G:ˆbÙ¢âÒ¥ô¹,÷kkkÜuç FƒD}´5Fkn;rœo~Û7ñMoþ¦ô÷Ãt¸fYÆ`0`}}ý–ƒ{8rß}÷ݘėU¢ž!N>p­5_~ù,“Ý9Á:ìì¥Qè‚\ä)Ú.z¢ˆ´®Ãù¶‡tº¶I¬-Þ÷.޽U¢©Ñ!)á4t]—"Ò¶–¶m°Ý„®ÙÃÚÎ¥ƒ÷5¯ùZ¾ÿû¿Ÿ“'ïçäÉ“ÜsÏ=ÔuÍõë×yþùçùÈG>Âûßÿ.^ºB­H%F 0i® O«¡±-õL#Ôn[¬_*HáåËÉÙ6‚*…ñx‹¾·.p=ÝÛ&åjˆ°¢SW fŽ"QöïIô‰—I¨IokLð‰¸j¢—ÁM"¦¿®¶'uËi°¤(Fè1òDê"ö…~i,dƒK8¡….²¸xŠ€B¯ÀO/#p©ßrâôØŽ€ØwúY9èíªO|ٹ㉾¿Ï² )Ó1Mý‰·t½ëÕ©‰]ì3Yì¡„ÄÊ‚lp[ÍñB¡uFç"NIº6-šT£J­hcŠÐŠ¢ë £6ŒTäý./ÈtJ–w„’H!Ð&CX9¹ ´®f2¹Â—¾ð4GEkë_ýkkk(¥X[[K¦P·ßÎ#<¼ŠÖsΑŒŸR8ÇÒ’·(ŠU\ZŒI˜²¿¿ÏéÓ§ùøÇ?ɧ>ñ9¶/ì0”¬[g”o …ÂP$á—Ô¶ÂhE¦r U0¯ö¹|q›Ùt¶²í]>þÞþ>×wvim ,$(MÔ¤ “š J¬’«‚v1çÂù‹Lö'ø»níX­µlo_áéSÏpug—t9Úè˜6Èài»9FJ6××¹û®»V~çUUqæìYž|òivwвd\l02#Ž–[ŒUÁ"XfÝ¢¥˜ŒàAkL ­¨«ΜIÑ€÷Ý—Ôªyžsøð¶o­‚CD?í¦èÇcô-L¤k×Òb¶TCnÜÉk÷P–#®Çm‚šPyÁîõ=Μ9ã>rKÞêÞÞÏ=÷Ï_¢íÃLöŸÃzJ Ó^@&3šEÃ¥‹—n1w =v”Íu„Œ¸Ð‘Iʼn»nç­o{ oþæ7³±±±ò×Y…C|…ÏÎ2zïæÂ~ó-ÆÈx<æðá-Fã!¹Öh/(½âP>f¨‡™a´Æ:‹õN\YÐáû%bïÝS;id†\ô¸à“­ ÁVs:QaDDx°>`| ø ÛM‰vŽ·s¾îëæ~áxûÛ¿ó–ç:NÙÜÜdss““'Oòö·¿÷¾÷½üöoÿ;þé/ü"׿ç(Íœâ(utȲ jjÛÑňÎGXÛâ}Ýk,R(2!‰*}¢èÊhÓ¾QöØyïаiN‘j…„•ˆi—–,Æet}³VûË7ÄÞ&y¹¯²d¹ù3úk;w….‡<øu¯æùS¯Û]žHÏŒ‰‰$/uF´ d— »Di2) FôKØ(bÚZO·x¼Ô€»ñ¤bì½kBï!ãDls@$ô&eéÉg™I2éhÓ–8& '.ã³Ä Ì.:ŸØ-Ñ)«$x :'*¡¥Y€Î7Ì|èR$ö$Çú”JÕŠ€mZ)áEGC®*VT6 £ÅH’%ÖÕd²Ä(EÝuÔ10« Ó:S¡ Œqy{¿øðǨªšë;;<üÈÃ+ ×erY–_ÕE-/¯¤°µm»RH>sê>û™ÏqêÉçØÝ™Rˆ[ã_¿q¾Æh¸ŽŠ†.éÚç:2™1Ê×Y++ÊlÌþb‡«W®®–Ë‹ÞÚä ßµŽ|4D¨A"%!B´8éicbê\¸p‰K—/sò“«Žu‰3¿üò˼øÒ—©*K‘(‹™ÔäZÓµ-.$_oÙ[±:çVAO=ùgÏžÇvc ´6Ȳd;ŽÁ¡|“FDæÓ„&7Q·´uÄÉ e „¯¸¼}•'žø÷ߟRœ–ï­Ö:Éñû¨ÉØD­n,˜“2uÎöå«´Cë=­ÒòE– *cº?çùçNó†×_áðáÃdY¶êÚO=}н½tH•Ù:ÃbƒA>LÞæ^²ó:£nk¶·“8k¹'X Ͷ¶‘e†º®J0^K-ãñx¥ X~_–ŠÞ¯´køÊǯ´qØÙÙáì™WØ»¾OôBæ”J!ƒÃ¹@QhæÓƒæ=<VnžR˜$6êïããÒÃFáe È,G‘ëÞFˆŠÅÂ׸nNg§´vÆÏþüOóK¿ô‹@‚éÞóž÷ðgö!ž}î‹·Ývœïøöÿ’û±Àë^÷:ò<ç'ò'xÛÛÞÊ·ÇÅ¥Ë;ø9²iøÉôü¿ù>æuƒ÷g÷„¡"Œõ˜Ñv s{@#:šXãBMBèPÆàÛ"t©zZd’#j¬“(S຦'„xp¶¯§¡§[÷èƒJ“µw¶ÿ»%{pÙΦÛM®ñÆO]ó?ÙgÐFЃõôuEhkÈQoË‚Ð\GŸþ„è1# AÀ ³Áwàš4nЏˆ‰¯{…ìò¢¸Å/Šä*‰LŸ_ú&ì/"¥&±‚b”iˆ¤È-a(ÆkD[(B`ëƒÛuàÒh(¤`íðóé„`‰†$ú¹E*Tç“a‘¸¦E Ùói%™ˆhé¢Àd›¼úk^ùӧn†- *|¨“W»è×½J‚KÑ{6BHr¤ \>Ï>Â+gÏò ½Ž¯ÿº¯ã®»ïbkkk•ô×¹.ý@–Ù©“É„«W¯qæÌžzòiN=ý,Û®ÒU00cŽŒnçžÃ÷s||[ëG©§5ƒaAirŒÒ)|¦ŒÜA9DK^²·;áܹóœ|à$[[[„ؽ¾ËÅ‹—h«ÑÀp˜2,dèÓë#AÔ† m¸ví:§_8Í#<Ì`0XuÃÉGæÛ—®!…áî;ïbmÐLBÊ'KªXqýÚ_üÒ“¬­¯1yá…øÜgÿŠƒÝ9kf“ám¬Ž å8-¾²5|ZˆÄ>è’J8G3ÓøšÉdÎ_=ñEî¸óŽÔQóÏ>ËåËWh:›”ÛRb é,“ÉÓ錦Iç•+Ûœ?wßÂÇNpû¡;Ø0Ç1²`º8`¾Ø#7æõŒ_x‰§ž>ÅÆæ&ëëk\¾t™Ç?÷y^<ýeº62Ô S b²ÆÖÒàbbƒå¦¤vsö÷¦¼ôâK<úè#”e¹º–²,yø«ÞdïúgϾ‰'ØÜÜL=™µt]G×u«Ÿ­u¸þçeÁ_ô¥¯sŽÅ¢â¹ |ñ‰/qåâxE$R55Òb.SÌ6}GC@“l’C­ö¯EDAÂjÊuQ$w•ºÞúÄ5e@%rGSM©›]õ.u7å—~ùŸòs?÷³|âŸàð‡8a„N“¶°}uÂïüûÿÈïÿÇÿ•ßÿ½Ï;ßùN~øaþŸ?ù¯}ÝhÜ{ó‚ßùÝ÷qPO‰Z ”I’!!èZ'¨º 3æ,PF ƒ'Ø®;HßtøÎ¥"¼< I (ÂL P}C” ) %‘È%]|iÔ=ø$­biþÿs»±Pí |ŒÞ:„Ô—øî„H½¿›ºá|ƒbókø¾ùÞ÷¾ÏS]ø"±¾†p¡JpDC ™o¦iJXÐïÒV;º›³Yaie{«€e‚ªX‡Þà?mÍ´À|Åý<ËOüäßáÿèϹt%Iz ý¦‹ 8¸v¶÷ü¿EוÞQ­Ñ"ùl£3lL†I¹.1B“¡äC¤œ}æR¸oAÑ9¼kPŒ6(ŸÂI´T8G¿pMTÁÝ«3¦“gxåÌ>÷™Ç¹ÿä«8ùÀIî¸ã¶¶¶ú%¤¹§vÎÑ4-³Ù4)_9Ç—¿|–sgÏsýÚõ¬%“ŽŒnck|”­ñ Ö†·3E3`0Ô\ï&äN±±~ˆõõM®ÎQ10oæ(mÐ*gwg§?õ²<ã®»îÄ9ÏK/¾ÄŸÿ‹IÃØ¬±‘obÊà ×7ië–Z´tRà”Fe4{“O>uŠG¿öÑì4™L8uê§ž~–zÞ2Ì×9røZ®á›Î[´nQÚ eÎÎõ>ôgÉÙ3¯0¸tñ2¯¼|lÆfy„µá!´.š1ëų¶¢rÉ«'W’ªi!*TH¡ º ² BtUÅË_¾À>ðÿræÌ+()9ý⋜}å…Ȳä‹â%MÓñò—ÏòÄO{êÜãŸû+NŸþ2UÕqçmCŒ_;¤ˆldøÑ‰DEì\¾x•¿øÐGXÌçÚ:ÄÙ3¯ðéO}–ëצÙ¹‘eQ \p€À‡ £ 2]r°7ãK_|’“œ\5;gΜáÊöU¼dª@É…s—ùПþ9»×¯sìØ±~S%ÏùŒªÿ¹ªjêEMÓ68çúkîÖÎ] ‰ëÕ¼b²;¥«]òy—=V‚ëR›Q:]²Þ¼O‹R‘šž4ED\L eˆ¾ïî5¾ó8×õpEXiW‚·´¶Nâ3;ãßô üìÏþ ØVßýÝßÃþþ¡J‚,@štGK -ÖÕüÈó÷yó›ß̉'xôÑGù©ÿîòÞ_ÿ—ØÐpþÂ%l4Ø>”'Ó&5<Ã1±šc ÃþbÂŒÚGw€u*ˆGŽâ[¾å­¼ímoå±Ç£m[Ο?ϧ?ýþàþÝÝ}y Ÿ7(‘”®K8’g„0YÏî¡_pDŒÊÈŒf<R-šþ—ô ëÊhÆGiç Y¨S¬X‚Eš"8ï“ÒM€uMbþ –%Ñy‚[$ó0WB 8t¦JÖ7Ǭo¬±±¹ÁÆÆ:£Ñcz!—u4MÃl6coŸƒéŒÙÁ‚ÅlA×”2äjÈz¹ÁÆð8'Æ·qhí¥bTAž#™ÖdBp¨8‚C1·µ›±3ÙæÚä;³‹Ô;ä#Ím'Žrh9}O} IDATk#±:®^gg{á ¶†'¸íð}kGÇÔ¶c§ÞgÒNhº)³Ùu&Û´Í.ÇŒùÖoy ßøoàСC\¾|™}ô“<þø—˜Î,kƒ£9|ƒÁ:.*&õ‚ÐÍéê)³k´Ý bKY$Æë<Ñkòl“ñp‹Áh“¢\Ç#Q°n† ãýv:Î1CÅxó8‹è¸vùY2"ó¶"+“—ñ¢fT–©išçE2‹ §m+ºnNYî½çN^ußÝ $çÏ^àÒùkÈ0`ký.ïd ÇdZbÌ€¼pîÊó\Ý?Ã^}ym­SÓéœéþï4…³6Ü"×C2Q2Ê 2“Ó¸Žy3eÞ0]ìPÙ}Æ9¯ÃkùÚ¯{”_úÒ“|þsO°{mŸ% ‰R‘ÁhÀú¡µÄç£k;:ëpÖÑYKp©aèl‡_²Þnº$¥¡‘H”H4DIaÆŒ²C”²©1EIÝVäB£ÐˆÜжÑ·8¥X;|/¶®qÕZÊd¢'g"ŠÔ¸X%ðÎâ­gé4›ÜX=ûõö˜×;üoôû|ï÷~üàù®ïú[ ÐcPc„ÌR·ì*¢ŸýBÍ{þù»ùéŸþéUyœN§Ú:¢$3ÇzLP)oÕA¦é>€É3v÷ ¸ Â,öÐò£ÿGøÍßüVLµ½½=f³wß}7,2Þýî_áŸýÚ{^9R@$ƒ„ÞÚdI{ìaâž~ 4;^_c<Ê8|xÛnÛâ®»nGßà·Ó€¹Ztê¾È>IˆmÚt/Õ¥2ŠÄw÷ Q®·Ýõ@oÅzL¾¢°§‚¾Òñ/ÿ¦ÇS!íjWË|`–a²¬_xÞ|È><#½!“ÉýÄãxß/)DâÀǥǼ”IÐ?%£2Œ6Hdyoáœ0šÛmñÊùË46u2¡Ÿ)•RDë˜ï]£”Ö¤xïÈ…GJEÞ‡w§ÃD&3$h›¹” AFCnF)üOëjvwìíÍPò2&Ó£Éòl5ø$¬4ଣµçÓ!)dF™" ‘¡¢DÁz¶Æ‰ñÝÉÃ;x¦nJôFk‡yZhº(د®RÙ)¶Ÿ”Ř¡ÝÄyG½˜qö¥K¼üâ¹$ðˆ‚a6f­Ø`P®áT]ÅÌ×D.t¡Ñfˆ*ôçÉS§ža41ÎØ¾rù¡²!9GïÞâë¿öQ>ñ±gš’Ê7äYÉúø(u3Àw ÞÖ´Q2Ê7Ø\;F6XÇFš¡É±u‡ÙÚaroÁû¬¬Õô: 9><ŽcE”‘|îhÜ_'o!EF® Ê<Ñ}ôLæ»LÅUœ]pæå‹\½t!$® X/1™dÖ-ÈÚ}£u:PÊ2ì \ds°"°»¸ÊåK»‰ŒD«Y^›Qº†”&×)·Õ9Oð£2 2œá\ËÁÞ”O}òqž~ú9|ðL'3ó†\B'¡¸V°¿ãØ {ˆ`û šŸ,B „¨‰"Cdò²'-öV‚äºH2*9J¡B'FH»Ð‘C† ˆÀ¤™ %ØŒ®šrùâÈò…,>"dÉ2'Dð1bº€At¢ú ]ë-s¸èxÞúÖ·¬jÈÉ“i—ã‚iˆÂPŒŽb²‚ƒƒ}„S<1¶<ó̳Ü|[[[ãk¾æ$Ï=–NÌ1²@‹… –@2=‹Ñá]—_£ „„Š"ƒßÿ½?àû¾ïûxßûÞÇ»Þõ+<ó̳Ĺë®;ù'ÿä¿çÇüÇy÷»ßÅ›ßü7øÎï|M,¡<_§s|R¹¯¹—Kže-íÌ´–=ÃȬê8|UÌ^ú€onòđн@%?ƒèû¥'DT*˜Ùû^M}þi¢M*®@¤Çn‚Z–÷‹I<*otêRÉÒ}Ýh£’™‘Èr€ɃÁ·]—œ—ÉQBH„2:|‚ƒí³ˆ¸@ÄרD- i)³ âDb¿(R!u†óç™Ì¨Å[‹a™c†ƒªB@o7+1R§@¥!6D|ôØÖcGíåJ˜¡•G Õˆ½ECL0Iêö•Ò½@ 0cŒöxßà‚Oùå]¤ZÔésR}—¨%N–¢åŽ;Æ7~Ókyü/ŸA:ÅHŽ›u]ð ­ëh\“.‚k‚ ³œ=7¥kZp>·A¾ADA—³hg‰—KàŽ»Žq׉l¿vT¡Æy‹R’ǯêÖƒ>ÈÏýÜÏòËïþ5ð-Bhšvȉ^Çö‹Ÿ¡'»Ð4 _y{ík¾žçžGzË0Ï(´X ± þUÊÚBËoýÏÿ˪°ÿñÿ1ç~ó.ó?ñ¹zõ¿ü˿ķ}Û·ñ»¿ûÛüÝ¿ûCD¡pv†–ƒ¤¿Y†ÑÓO—N•}üßÖÖoþ¯åc¼ÿ»¡AÐ7ZÞ¥ %¬0HÝ© -fbèy¶$~*±gÂHò4_þtÂæÄMÇÃ’(ßwÔËÇMTÅ$‚²$Fz~|úýÁ%7J×9ò¼ õ ¶š%ï™ènJO«½Ï¼2½Ú!¥EE9»òé¡!’›cz •6ÐÀv Æë8/Xt5¾wÅêœÑÆU(‹  Ì†$žL)y,Χï{@¼ð„®Knq®EÐGŒ©ä ãcZ’™˜xPÊ€T”ª$#¢‹t`h•‘Øü‰ ™Ž]¹¢´"@.4…-Ù~~—u³In†m00%mQÊ0­z»Iè’ªxÒT)HÍuäZ%nqD¡1YI&"Jz¦ wÁ®ÅM‰”#U3Giµb¬T3ÚÐa£E9)){6QÕÌñÂã•Df9Ú À”t!°³;a:k‘f.PxÐYÁ |‘˜ ÁÓ63<% gѪDň֒®ZŒÝ‚ë—_Hž2|°4]ÝMEïîÐZ!¤Aå¢od”f­W,'; + H‹ ( eŽóÐGb(Í€Q9FË PX®:g"´dV¤@ˆl“ÖY¼l“@ R¡UŽJ(­Î!L HAQ °‹ )".xÚ`qÞSäƒ4 †ˆ#s¹~¡jt†2¹ C©rtT T tÞ¥ÉèlCÛUD•TŸ ò½Ít¶ »ñ>`‰xð"$ɽð"JæÉf@‹äqƒÅ @xº˜^‡·K—.­°s€ù‘ÿš_~×?K¹´Rã%¨hÙyùI„mXf9ßwß}_Uܧ³ÙªJk¦DŠ‚*-ìhì•„„€ÀáìRt¼õ[ÞÂÿðpöìYþÞßû!¼ òTÜ+¢p¼ë]¿Âßü›ßÁë_ÿz~à~€~ðOøã?þ¿ÍÒK¤Ì‰}.„D­¬Åµ’t=«fº¨yüó§èº–¢¸¡?ú*ž»ôê³^U*’÷4BÒuŽt"kúÀLßâQ¤8GˆËNý¦[Lo¸™K+z>}H[àH:}V~:$Ú®%‘¦ѹUQ_áìËi $Ë„h¢%DÊ/½9Ì{õbûÿI6-Ve¦ "Áô W§(ryè^®\¾JW/1H¢*©M^DG›2@ú‘6ôÝ‹ $—Lfb>à{Â¥·–hÒl×BùX3PQ(tå=Rf(UP(Ež)% Ò¢)Æ4á8C·9:K“‡ë!H—dúN|ñ&H¼!dMr Y¢uŽÉ4ø.Q¡…Ä…€‚‰‘¦^ ¤•XÚY¤lVްBÇ”õé—T¼#BDÛˆV’¦>MŸŠLddÑTx¡ÒòÏöMÔ ²’Î[:o±¡%ȤHUjГ 5Î'¥j‹gmcLפœÚè6¯Äl€·Ã{Þó^þÕ¿ú—«Küé§O%$"оÒ(eQrèîÛY\©¨&zèÁ¯*îÏ>ól²2–N\®'äÚ „#DÓ›yY‚·Hº›é-¿þ/Þ»zŒÿð~/ÕMQ„Hß³(Y¦èšÞûÞÁûÞ÷ŸøÕ_ýÞÿþà¼CÐõ˜«À;@øeû ©Òγk;¶¯\£,ô ²YÞôÍHÔåÏŽäJjœ ¹<±ôR'œ)úþ LpM`¹ýôIb!RçêðÔÑ ‘XZTôdQShCô>Q)ûÔ2'à"m¦."Q¥m†)))éJ õލ“HGÅŽy5C%@4Ölˆ#Й@ð3D¬ù­ßúw¬¯¯ó]ßõv^|ñ%þÛôSDaˆ"A§ HßB´\eJ´û”eÎ;ÞñŽ[ ûöö6çÏ]$Óc²c46WQùˆóžÌ,·ïˆ-o|ã7ðš×¼fõ8øÀY¥wˆUn⺉¢³ ùЇþœ®ëR(ú=÷ð¶·}3þðlj"™/¦hÛa£’]³ˆ©!^Bæ©Y—7E˜¦æXßÌXILÉ2Èú÷ijô˜!.qø„Å÷Ë[Û-V¿'uÁ‰ºXlj;kkŠá€Ÿù™åßü›?`ûò6©áW=¦ÞàeÇÒëºAj 2P¬ÇÉ5âõÓ½mè Ëà\V ÁÖ‘C<úè½\8¿ÃùfHÝTévbN¨&(°w‘ü $fÏR”ª½áøñÃDè-†!´³^*™Ç.©èArºS‡ïy€NìýâŠ#ŒHüüh“Á'Þ¯”ø%#(D¤÷ä¦{OiÁÐä#e~˜s\·½zžyth³‘ 9>>B!r‚ Ë ­I ŽºKÅLɤÞ#‘D!B¢2MnàpÂÓEÏÜwxihT…­=òdn-±Ã¸†Ì¢Ê)£u‘Ú7dJp(c½gº8@ ‰Ž)€\*E© aˆ!✥ó£ÖwøØ¥ÆPlô"9ñ0Ó‹çÉõœàJ\”dr%AQKÉ8B.àä«nãÑGîçOþOÓ4-Þº®¡‹\²¤-µ·8"Ö9r¥ƒ³IöJJ¼á™/¦8ï鈑¹CèˆÊ#B¤È3Dˆ)rÎÛd %™Q¸èQN× &õëÝV‚*D†ÖB›!—ŽBj‘Ñh“×ñA& &ÍÑuŒåónŠ÷J%;i™”ÞSÙ)séàƒ§M^¼¬ÝñjèéE,‹Ðž×¾îaæâÔéËÔõ É /ˆ]‡ˆ‹§ -28¤“ M‰ô¬£:*Šù¢â©§žâ±Çà{¿÷{øð‡?Jªæ½Ú^¤Î 1Y˜ ‘ ·“SeD_à{Aiü …j  ¡cœÝwÛbeú•ŠhrcÔøà‘Ò$‚ K–LµÒ‹–§s½¨ú¦Áv5ùÈÇÙßß!’Â’ŸBO}Œ@”D$^J¢ xßç3"Õò‰¤×Gi‰¾3Ɇ#î¸ã¾í?ÿf^¢§DyŸ”d*3él5sߢ„áÒ‹Ï‘ ·úÃÒ£´&ø^Y¦“Üð¼÷ ’¸1R“#ñ2uí.Fê&Eá¯RˆQ1@F”‘#Å:›å:¢ øÜÓK7]dÂK¥êY6!Rdóh >’$ÒÚ¦%j°xZ7g¨J,CôÖ Âö3`vf×0¦àH1¦éR¾kŒ Ѫó®"™# ër”DkHº¶"ׂq6@9ˆ2¦2à}$º”Û+"˜Ð1Ȇ^¡Õi×rõå§Ø,‡r|Lï«ù•kGâ´&z²IE}îÙk\zyjƒ­#‡Ø:t‚¥X°sé9t[ÒÏFJ“ÓX‹V¤ÀŒ®ïµ…'å9[J‘Q}D+G.LÚ;i…ó“”T”^c}G‚Îv(©0*ek­èâ‚jq‘‘«'Mš2»EºîBD„”¡©(Qö¹¹†‘’åhiµOÕÍAgtÑb]‹µ­s¼òŸ%a‘Ʀæ'jAkæ/~ƒA©~¡ ¬!Ëã<ðºWñø‹ïÇKÖâæ2ŒV ’ÉS‰ #$*¦²}²6^Á2²§ò ÈÐy"YÖöP¦òI… ‰zC/Œ$âÆ™’Áæý|Û›^Ë;Þþô';Ã;‰Ý6Â)‚œ&ø+‚P†HÖ‹ô …sàdh‘Jðó?ÿs·öëׯóoÿíï u‰Ö#”µdÒÑFÀ ,}78+1¸4ñGÏ·~ë¶zœgŸ}¶Ç¹5H“¨Ž1Y+dRÒ!ðAœ>}zUÜßô¦7¥¦O¤ILDy£¶‘h j‰®Ùÿ—‚T o›nñs‡Æ{¸iVE·GÉc‚Ä‚@$§·däUö4öäÇc¨ÝDŸÞ˜Š²‹‘O}ê¯ð¾÷¦¹™¦³|N"K¼ÞäÎN{µVz®jé ÍÒ+Xâ›9Û—/ó±~–+W¯%1†µ‘ÄÕåçØÜÜ`<Þ ë,‹J!Ä0„mGÓv8ÈóŒaÁ“_zc\2ë¡w¥WcÄ· ‘&"ÈR‚ŸáæŽÐ/O±ô<ÝŠ|ú,\ZŠ“XŒ@•tÖÒt]ÿ1Dtff¨ÓâWmÅÕïØ0%…8™¸)¥É‘Ö¥h1g"ÑÂK*§Pz„ʇ™¤ÜÖ§¨µõÍMæó–E]ÓõÃt™Œõ¸;çð¨doFìiœ&B)5z8dº¸N°ëúø”?ù4y]¢c Ï4Óv–’±¢`ê“n†ì™!´4>A‰I=hmH d>uJ&/Xt õM¢NEÙ'ÇÑB*r“£TšÔDˆìή AFC,óÅY6$’öÁ¶¨ )úÎ/††É|·4±co¾ÀûŽÝÖ‹ ‘\) aèb¢U2ê«|GèC%œŠ` Ö{”ÉðÖ!CvCz/}þ4òüë.§“š "Z‹´7 Ò‰'ùy"°»;áï|Ÿ=uŽýë¡t’?w‰,{*fð;‚µv_MfÈm÷½…k>Kgki¹…ÃViÉzËÎÖI<Óç !Ä€  ¼"C;Ï Ódó)¹äY†ñéÀÀ¤%¤!­GjÃúæÌç{æ)µW”ÑT¶£ò­> ‚‹Ìf3”R)DÙ'­Aå­›1’Šõ0`=ß·»øȳŒL*Ú¶1â ­Ó"9jt1 ik¢Ô‘üPŒ³¢j¨G–çtÞÑù€V9±q±Ñ%{%)¥¡‚Z8¤Tt¾ÃûŽ¡ÈqiÆ$ÑÒeÂt½Š‘§´"œŕ'øÈÿ}šÏ~â>d°ÜñÐÝ\>u ¹°ÔÝœÚ.ÐD†Ú069U¨¨\ƒ“‰’ É@割KZcX&~ tÎ +Ò!­sT3G›!sùf rp "+PºLßIx•3mÃßDò|Œ‘RÅ’ÞÖx›èµÎaeÀº†=•›ã)¬]%Þ5A`dN]h RÑ)… à¢F›’\&¼|ãðíìîOˆq…a5²« 6ˆ ×!‰"£`£EK•ê„Omž– íûP aÁ$¡— ö)%hi½É¿ÆÚÄÊIß7s>-XC‡¼c¨$ã0ĉ€kxâtÁ¢Ú!º€ò Æò1#FA& B&{r’XÑ/f¸nBÕíÒÙ)wÜqœ_üÅ_¼¥Æüëý?ñ¿ÿá¢0댊-‚1'Ðè ß¶ý”’–Ím›r¢!pï½÷ÜòXçÏ_HßK¡É…a E–“ EP‘H‡g@ìæÌgó[î{âÄí̦ç1õv騴Ôö!Ä  ,C=ÂMÛSñ×÷>‰‰4 "MDÀÑ5Óž-“ Y¿H øèz—Ĉд ”þÿH{Ó ÛÒ«¾ï·žçÙÃ9ïyï{‡ž¥n Zƒ…$$ ‰bZE„,l‡À@UŒ«’TÊ”c;¸B9±*©Ä Æ’- ˆÑØ€I€&HKB$$ÑR«'õt‡w<ç콟iåÃÚç½·¡âñ©ê}ûö÷^ÏZÿõV ßJ ϶JmIOÞÓ^~)ÓÙ).=IÕŽÅÞãv3ãX3ŽDžCx" ÔU¤Ä9ÆÏ:;Õê³·pÝR=›íµˆ9Î é|Špãð„ãã3~ù~“‰Êjo?ûšWñÍßôFÞôæ?OÉ…7¼á«p‹òÑÿ!.píÚ5Î6°Ùn° ø›Ì/N¯!Á£yÃ3ÿ%4ç´+#°c0”˜rR‹}ßUaS£-‘š }Ø>':h›–¢Êɸ1£¥IY5‘F¡SeÙ.r†¢:±=zÚ–Ù®B)„Ƴž6øxëÓ@ ÁDW8êzäÒêÑ+I »P’ªÊ†JÌŽDöØ×¯•©Nt®Çu…¢™M±å<žá]Ãå{ïÇ/¸ö釨õÌRfŠr¹_ÑL ÉÆzL.P³QkŽôΓJ °¦7é™ä7D×[xyÿK IDAT…>tçÆ]ÓL{œ¦5¥=¡ª±w¶=.8|I™³_bµe2a†35 ¿Ïåèª'ÖÄ~»Çåî#Öĺ2 ¬šÎ äDè]¹Ð†Ö¼gª²ðst›oÝË;®0n'âÚÌ©Õ9þÓïz=ïyǃd>Ɖ#¸@ï ×ðòË÷ðÒW<À§Ÿü<õIâz¤–Âzóü⾿Z͸2ÖH¦Ç°Ò“JToÍ3T®7kÌüÏŸr…ægg¼J™1s1<~çënPÍî|Ø-L­ÈY—í¨iƒ÷ Ó‰iuÏ­ªÄkŸ™-:1æLU¼ï(efÚ`^, øn-Rãù‡°¸>{7JFÅÄd?Ó·f6ÏîÛD¬›P'„½Û9<=~ùbüÄu>ýɇø™wü*oý–o`µ¿Çõ/=Âÿô#ßÍSO?Ë#ùÈ'xðÁO1L‘“ãSœ³1SqT5ÇÁ —_ÈúðÉ󥈸›‡€MóA£ ÙÌüÅð7=­óŒ4¹¦!“‘ÒšJDª "¨óôjÏ[E‰RI%1¥-¹Vª8²ööÜöò×óèC¿IpejÙKa!­&6c$‹šªÔ7æÈéZFø–7ÿÕ7òÑ_þ$Íö„â*Ûí–ÑW²TŠd´ÞD.‡>LM#™Œ&¥Î˧ÃIi›Ž†B-¶/¢¼ðËxòñ'¸#Î] oz´níBUå‚_Òz 974Ð3L ¯–êÔµ¹˜YSæò…Kä)C„Jͧäl0að.öh{'E'R>eJ[šêÙ§§i—¬Ú=²´>¢éÙ/ÙYœÃ«ÇkÀ‰·=A,°fåT­T©¶Ì•Äæ©3Ô9ª +Y i¢zå>ð)ÆiK#-U2›xF߯h-›q¼™i¬Â~»ÏfØ Ú0eEK!40Ä-.xjµÅªxA«’VJ1=Eßô4≥0•H©åœ]¬µâ[ow[ã5²AñÂ>¹f®>õ0;§æªÖÁ{JÌŒ)éáÏÄs¢àÉÑîç,‰T Z++i8Xî3•Ê6O$*m³àòê GÇW™¦#²³hëRô 6_3“ªe!¸† W.pÿËïãKO=Ãã‰õ°!åb>%—‘Ÿú‰Áë^÷ºó:ô‘|„·¾å[AÚfEªžT#Å{¼ R+yLxçÉ5Ί^EJ™ ëó1幡¨PŠ }Ãqû‡Ÿgš*A=Ý> -¾8:Yàz£Ðn§5EaXŸáœíî×{²«§äR43 š®ƒ 3.}•JÉ™Ú4,Z£ÚÆ’IÙŠ—sžX ©d´*¾BëVÃæ¥ ±Ð»Žê\ð8ßXFó¸J‰âY¸ß:Ö±ÌðA˜CvÌ®Ö:ÐÀå~ÉÅR9‹§†õs4RéV—8Oˆ9awJÅyk(³ƒ1 ¦¨e§kÛ/.øÊ×ÝOfÃÃ_8b¯’â ¥ üÏ?öøkí;Î+Þ{ßû>þò·ýUÒXYv Þ”¡©D¤€ÓÙzÁ ©Xö*s–³ž@„£££çUÒýý}ÛXja âš=†Ë/äÝŸúm¶Ã!£ž‘1h÷Ò-Á7§§æ\ÛŠgáZªkÙ)"TïYÞv/¯{Í«ùàû~Õ¹vý‰Ãžç yóaÞZFÓ-„ù”)ì:i;ìÐáŠâdÑ­Á'ö't«³ëÖ3*´ûoå캙%‚âªÑ‹èh«X#Ë;‘Ã'©töAÎý"RÔ_`yåe¬ŸÆÅ‘*žŒµ°@­ŽZfj)¦CòtˆEm™(­Lׯ³u×P/]á·þ%~ùW~“g¯žcDÄñÙÏ~‘'žx–‡>ù9DÕ8ÃÀþjÁÙzK® ¸€H¢hOp«ÎÑÜ!©qóqs”¡•ÝÁûÓ· äÞwä2Ñ5U» ¸pûT›£6qmŠRqø¦¥9Wï:l¿‘­SªsÄ’pÌA+¡ØÒFJ½µ+>¯Î ¢‰4MH°Å÷X'¢åp:»yÖ2Ó-‹yPËWpÕ±®kÆ T±í”3Û8Agø=(Î7T„Mš2m³ i!æÂñæ”Ö9®ì߯3£LÔ4"âHTœs,BÃéSŸg7 SF,|gŽ2‡«8ªÚ÷d‰®ijf“Æk',Ê\ ê›qKÌÑ®^„±i QÈ%Óh)¾±ç¦aS¶œš8ieá ­s u I┘ u0G+-1'.®.•”2©Nd)¶o<9™}E­…\Î([cè´mKZZUÖâ4±FÆœÈTJ^[¸*c6–˜ ž®iñsÿèĺö¶1Æ’VÓ@§Z‘RhÔBÇ'¤q¤dxw(™6W7ÃS®#:8&3æ‘X“±„œ£Á±' ÐJ˵h…):¿GlùZ‚§é—fb6·)ÇÙªdîhE(µâÖ7\{î*ïyïïòÄ“r¶~Ž’N©uäûß߯߸ÿõyûµ_û7|û·ÿ”ìèÂ>YZ¦4¢Õü³D ;cÛ´¾g)Õv^(µ§Ô‰"Žë×n<¯†^¸°o,¡š‘21ž<ή?Å2dÆ’Må\­»¿|ùÒóþß““S‚ à<§i¤2QÅhׂ²½ú$zÏch0ªøMüýf-?‡en ŒœÞ ­ó,^€kZ6‡bƒù±HX âG ~Eœ2®oØË¹ny'uxêÚú÷:R\Å€ 0J™“–:xßS²Râ±uŸFèd&!ágJ)Ã/Ø¡!Ñ‚»tu}fxrÎ?9HbǪ̀€l¬ µƒÃÜØz†³-ñê“\»zœ.rzr "¬gJ'0P!LÞ˜/s'Yj=2ßœí┊ xço\Ò‘gl­+DI3gåÕÂm—ï¢Qµ\Jç#\m9-Yդ⥚ZðâÈX4"8šÆLѢЪâ«1S‚xüÌþñÁÓº@QaÊ•âZ³ñÔ«gÐÄI=¶¤vÌ®u; ¦1ØùÜpEè0AL¬™$‡£“@«Ðù†±(Ù›C^¡ñ!NxçØ_ì1E£×ncDReÔ }ܶÁ{S·Nµ‹£V¶ãÄ:Œç‰ðUÀ¹Lš6xõ8p@š”}ßrÛÝWXõ—Ø h‚Þïs"Õ„oßö}ßȯÿÜûøÒ§hÌ´­iˆã@ŒÆÔiƒGS…Qh ¦qK!²IVÔJI¦†°¼b“ܸAÕ³\܆æ-)âŒLdwÂI9ãŽý{i\ËS:c˜ÎŒ.ª¶@ßи§™R9ø:ûÉH f"6®aBH Ù{¦¨ ŒH‰üÜ8+”béYMÓ˜æ¼" ød‡€Úož)xçð¡¡ í=Tpm`[#£$‰&¨Yk€í5T(ÎÓ»žEhØÆ­‰ µrT"MTz<{ýŠ´ŽŒÕô"bþ3(SŒ3¤TÙë{V]jål<ãøÚ)Ï=÷y†áˆi:ÉüÔOÿ$ßõ]ÿåyøÇÿøá‡øGp®Ã…êæ UGJ^Ó40MÎ58àâ•—“Š·×)µ0–L„Z¬~â‰'9:::÷È¿xñ"ŠiRŠH™WS€Z(Õ&+î7;÷axæ™g)¥%•|Î[ךL?' ÌÖ3 ~N?þ#0sÎoxƒTP2Û“ÇsKö¿.e ð¾#§D×_"µay@yöQ -^2… uû¨E„Ik”J¨=øD{åÄOâÕ–+¢‘A£uÖõdþ" ¨)·ÐB‘ÙGAÄ|a°T]C «Ë÷2<ލGj¶±N+n6³2–Ëî¢1üË2h-‘ƒÛn£ Âß A8;==‡¦¼`cÍâ"nãôêç)Ú¡yÄ5ÍæÝM :ûîc´ŽD#¸`V»bpD®™ Ú6„è½–^¡ëV]CGÞ&œ©ŒhEg!¹T4dR±–4®ÇׂxO×wó *Jð‚«)};O^žªà|`L‘±$¢T$Ú~ «uô£W‚ë™bÄwÕ_ ôq<¥©…6tÔh÷:â¸At`Ùö¬¶Dö(uœÚlع%ˆEˆùªÈ`ö"¶4«!ãJ H‹H%×I³…°h!ÕLq•#¢Bõ•±*+ŽˆÓŽsˆ… ´ðâ¯|1—ûüÞ»2Ëç"ä”Á;4)¿÷¾Opr´¶”lòH¢¡õ bhp]KéÒD-…13 :±É#*•F= éÈR©ÇO³ {MËè ý•‹<öè—p2àŠC4ãOŸ msD_=1lÇ5“&b¡À~·â`¹Âgoôb)¬Ó†aý!Áµ\h–ì·{Äš8L^2™É ¹hŒ’ìyvn ¢j *¸2Û3ø@[MÛÓ8Oãã4qV-¸§ó4Òš‰%3eÁ9O«¯i2[ñÔ¬´M‹«Ž€‰¬\è8ËÛ’ÈS¤;¸BL‚Æ‚ ‘"•fٓƉZŒ$}³ [tügßôçxÏo}˜õpÂÉúÕ l6שu ëö1Þüæ7üa¬Âd³TμWšîÓ©ñŒ—¾ô¥çùÁ$åŒÐŸ‹E­3÷³ÏçÍy·Øgιñ½•AcÅ]Õ„µPÇÄ6ÎŒ„†Ð]$M[ ™Œz>‰3L­JÓvÄ)›…*Á9ž~ú¹Ù{}¶«:Ë|IR¶×9™ÖT7‹ |E»‹hr(‡´ê‰dÄí#ŒÐ®æØ ”jªi©¡ò¢~97ž¹ÁRGÍE.Ýö†“ë,EqZÐ9š,”M Vó‰÷ÁÄ'nêvWê+“„y’(Z6¨JIi^HAï5³A¨JœƒÈɘ ‚4ÅHÙŸ™Ãc „xÊ8”Æ9JŠä9oPêD{Ý£r)¨SŠ4m‹¸À²_§ )¦ÙwÜ‘É,»KœnŽ(u‹saæ{WËÆ–r‘J&¼¦%iáxŠÜó®?ûMÚ°O¬¶§˜jâl¨¼û7?ÄÒ-H9Ï\b3aó“Ý }ìÓ™UN˜rf•½¶ABËñÙ Á%ÎH i"‹‡Ð1øLöÅ8ò(“:‚*÷LµãÀ…ëŸÿm‡÷-LEìÎâ1§××t.° Kö»ÊŠÀ{a*#c\ (%,6 –´ê‘’-üÚ·,ÃÞl¸jd #×$Wü¼¨‡‚wàñ4ÅÓûÆšµÎ±JaÌf¸×í™K£ŸiÈ.ÓÌ^ï‹Ð£©ýHJ‘  vý,XúŽ1M uË&xýbÉéæ9|­,´Á¥žä ÛɈÁ9B Ô{ÚÆœŠ“a^4‚$auçýœ]{ÉkÐ¥¦Ek2ÈnAºó—ÞnØQ§³¹x;p'PK²ñ쥃Únòm£¯µmàe/{1Ÿüäg9;>¶ß{˱”€Cg*žÉÉe¦×Uõäq@Ô>Ÿ7¤ÓS§%ôKÚæ€â…óëô¾áÞåºHê®°HW‘lnxZG’ª±ðˆšMò0%RÍ$§œßà½?÷^:5¾ùP'´³6r©&ª³?·žób)v8­ ©Ò‡Š`n—ZNï,ä¼:“øwºâxÜppqïùöoá'jfö§/‚—ÀJµi©jµßM€³­ì8ޏqKu NSMFKJhµŠ6”TÀU¦8ÍôW»R÷šýªå¶;/ñ}íWòs¿ð[´Rñ3 xšöCªŒ)rÿ‹^ÎW½ákyï¯ü5O d¶ÿ­R :¿˜ÊdSNÍû]Te›Œ¯\Dz=€¼AãHøü‘2¸:Q‚#hÀ9c±¨È9JZ¨„"ˆP¡heL‰õ4 4¢T²ËÕ5ê>ûÝ9žq˜+±(¥*YG’&³Ür-®N¨·ß¹V%0o sáŽþ2µ(©b×ëĨ<»4–jÍKΕMY‘v±dôÞ&UI,|ËàŸ*wö·siï g›S¦º%—Édù¥²è-ƒ —/\bÜlÈ“ý¾I”lo c!w½Å<.•§N®³–ê…MžèB‡f=ß ©V²NÄrÊ”NXÇj]sÿ—ßÇ?ûgÿ”oø†oàï|'?ôC?Ä·,ozÓ›æ.úý7‹¥þÅOÿ ßùßyþ4o}Ë_äÛ¾í/ŸwÊ×®]ãmo{çïXÔßßý»?Ì[Þò­ #ÐÐ4=¹œ"gÏò…?:ò—Þú–óç{ûÛßÁõëGÀb¦  ~¹âE/ùj¾øÐpÎãZ…à{RØLªF´>?¬cŽÙ{zŽÙ;æôtÍÙÙ\`Eç*ž‹·ßËv˜ÈÛ눨¹Ræ'Ü‹ù©ÕŸŸf°ó5Ÿ}jÄü_ºÎÔ ¥(ÂQO•‘ ¦2¬®âJEñhiòŒšÒF‘[Âö&Dn沲îœ!¿(ßîÍþë†ç«šõ/"4Màå/¿Ÿ/~ñ †íÜÑ‹3µs„ýËÔ’©›k¶ÐšOh[vmöAz¨g¦nmV,‚{/ÜÉë^ù"Nž>bs4Ðö+ÆÍ)7â)°×_d¬‘*‘\댺™¿O­æ¸‡ŒeËTUížIò)¤:â¼§‘ƸôNl‰V+ô ëõšÕ¾™¸iURòÒ̰“Ëæ”%Sf«HjâŸí4Ñ÷K¾é/¼ž~øãl¦É(kÕTµ¶6oîóëAÜìà¨UñEÝUµ0(×Q ´"ôËž¾ë9::2©˜1[P1†„ Fa-Êíw\╯~)øð'ˆÓhS‚*¨#x{½Ep¬BÇÒ_€\‰yËX3Q•  %k1Ç̶¥RL1;¾uÒÒ tMGEi}ƒó ×·'à*‰Ì¦&Ä·x‡é(|K) ÔeY¨Ùìì+Îïeד‡iNûªô8îî/r÷êN:YPËdŽˆ)‘½RKƹ/ɉ຦§qBÐÊ‚.´Ä™r&ºÙ¥²Dcmˆ—|¾FR-dQ[Zª2i&;¥Ì÷’Á³×­xáÞ X±àøìš…nÐqiu™eÓÚJ„”ÔÎ’r"Õ‘mß\b½}–8 a‰¯MóÈYÜr2®¤’-¦ˆU¢ÄtÌ8\¥2ðßü·‹ù‘1O ࡇâÝï~7ÿ¾GÓ4Ü~ûíÜqÇ|Ý×}Ëår®ÿÊ]wÝÅÕ«W¸|ùòóˆùñÊW¾ŠÏ|æsU\Ùßßã>þQ^ò’—ðÆ7þ>ð`Îa†»Í÷ÿ oøsüîïþ!>÷¹Ïñ5_óµl6 q =[–Ë\µæ0ÊÌ\ÔsAdaµ×rp°âŽ;.s×]—¹ï¾»o¥Bî œ•a#“X1F*'מ°B‹‚›éj£VÐUã¯[)Š3´³«·sVa±Xò·ÿö÷òÓ?ýN®Ý8EKDÅ›×r…ZŠ›]"-E‡ÖñÚoüzßoAz'ݼüôsš‘aZ†‡Ù‹ÖºC£æ7áĜ٨h<±)q&ЇoÔ°ðý—2l9Uœ_pÎùŸŒtrÕ¯x+ìÈüïŽìó+V¤&|wÁD4aVEÙÆ5·¿è Çë GWX%‹$ôÞ³­™Þ^RÂôXÂP‹‰#jž§a'çñ¾rOÍ'^A›†$Â&oíûÏBÅZ(qƒÜ8=$cÝŸ¸J)_M>/jÞ¹nÌ‹|V%»[ã$üÎï|„˜'Ц “þÏL‘Ð. ¶ÊJwé†i‹×W·4ê tÆ›û®Ã©åÂ&2Ó0 ãÄA´¡ž Í“Ž”,4!ØRÎڵ㋿ÿwÕ}´Y’BbÌ‘)'}O‰æ§?ÆÈÀ!N¼í°Ðõˆùe4(븱„wU–În2ï=ëÉ ÁB‰h†„u’Î-è$pG$X‚Q-†ÙOÅ–qÞa…ݹž©˜z³d_œBãYé÷ï¿€»º+øÐp6nÙ¤-ÎYxôЭXÖöX"“b3ó=§.à\`ˆgÄìŒú*ž®E³R(µ˜o)”bP—Š’K¢ÖH·Xк%#‘$Ù̯¤…ê¹»¿Ì~³àlsÊPGšê9ØÛ#ç ׇCjÆ¡÷¦!@-•kJ‘©nIÓU¶)2¥DŽ§Æ—/vÏ:ç¹Ðï³ç`ˆ‘©F\ð431¢LµD ™W¿úüèþèó ïk_ûZ^ûÚ×þ{‹ûÿ×ãÓŸþ4W¯^;¯µ ;) IDAT]ן³ân}ÜqÇ|æ³_@¤CU9;ùæoy ¿ÿ{æÒ¥Küú¯ÿþæßü[¼ãÿ4έ§òÖ·þE~ögßI«W¯ò­ßúWX¯GD í\€-7b§>:÷àm—”x6ï1g–;x¼ì î­"¦Ý›¶t?ÇÙ1Köwqp¶pö¿ªÌ¹GÝ0Ã&Ñ-;ÛÁºµÎ %åÁ?Åz¸÷kÞÊã}†S(Ä Ìñz³÷;1ñÉßø§fJƒ"¸`¦DfI9·æj^ ·>Tý¬‚½åcÌ‚C'zD’-·QÒÉç8Õ˨ ¥N6ÖÎ?®ÌݧVë(ÜÚ]gø^fb îI”é9{½r‚÷K¢ƒÓMæ]¿øÚÚЇ–! ¬šåK'\;zŽnÑ“Dj¥ï/rõðÐìpwÔN'B4EIªlJÆ·-qænÓ™8…:\×ÁéÙ1"JN[ â½71´/8s8”ÖC®ä™öçw˜ÚÒ½VS:……tT©ä caÉŽÍ‚±_òº¯ÿ:~ÿŸ@Ïž"H © ŸÈóa2Cxq\ò=Më¨ ª ¼ì+^Ã?û1X…+\~É+xâ±?¢Ä3’VNÖkKͺ´·Çf›é%дên9/F‘ BUG)‰Lž!‡Xø@‡:aH#U•mÙ0!,BG«O*”Šñ¸Û†åÞN7×hƒ':3×R51ŸŠÃ·-Û4°³ß£Œxo‚4/JëzZ›/Ø»KÍšál(zÌX3ãìÓ.2!z©,X¼ä•”§‡ñ\Ë¥ÅöûZç·įH9š7ÚÞ)kfÌ míÀsm×X8HÎàÁ7¶üöæáãk‹jOñvšÍ —Úž¶ ¡ßgÏw3g½°™.xb6ÓDM[S¿:GÍ;gÈ9•dVÂd5££u˜µ4>àfbì QÅ•€ËîOÝÿÐÇûßÿ~vÖ&<óÌs|ðƒä8ÿ;W¯^åãhP:»ù‰<üðc<ðƯçÿúùŸå+¾â+xûÛÿ%ßÿýßLJ?üaB<ðÀ¼îu¯Ã9Çg>óÞúÖoã _x Kjê°,TwóŸ5*&µšbæ·‘ªÐ,–ˆ»YàÏË›Á2_â¹çޏv툣£#¢Û' Ò‰²óïmÆr|Gh/á›=Æ“Çi‡#´.ñÍrNºÅáéQ*!´wÌAJ©ñv8()ÓÒÑ7Þ3k:è|Ǥ¶¤’Ùòt;ENËHVËÛwÂÅý;yæðYZqÔ5fŠf’b“¢˜«ßT ð÷ÐX—9åDuޱëf«ñ¼ú% i XD]d(Jh–´¡2i¡J&«qÒ³f&/œãƒSÁ)½_ÙgŒ/ºòåÜÓ_aÕ. Ò°e·Ä:’IL%“½#—la¡!ÔHïW8)4}K¨ž}· •¥…®”)…ÍfKÖˆïª °‰ãYç©Á:k‡#¹Ê¤‰ÌèKš:g,–¸Ø.¸Xú%©$nLG'4%pÐ]`Ñuä:1N¹˜Zy;¿Vœ}ŠJšçÍfNeRA¦ëZ^ð‚{@„çž½Æf;À̳§ŠÕC¼1dØy·[Ój5ª Úж+¦ñ]sM\­zVÜ~û%î¾ûvî»ïž[“˜v0Šõ‘â-góÜÍqö[qûðd f†äÒ!99Q´¢Þ¢f‰¿aó»‚ëµ2¥ï•í“°õ=ê Õ;F*CI9R´XžneÓq¥»€ Çé„äW³]Ö¸Ù²)4liÈîŒÚÚu<Ç”R3¨ã"")JA*QaÊ‘6XJ•Ùxx ž¤×äq 6NðõA¤V|èY4 ÇÑ‚²E¬‰J¡~n‰3æÌÍÙ®dÏñ¼Ñ<Ǿa§é¹FÆê—y\õ κrgδˆ½Ûµàzœ[P‹… ‰´³~¦íp’©:2N‰G¾ø âüâ"—ï}÷¾ä¥|êO#ÓUêfšßó®ÙMó{·¨óZq™”634󧎪ùÃÝ„§ÂóÝÌæB·{b-ÔÍøè9ìb§ÛŽã™u !¬Hyk"(Qœ_Ñ´¸Õ;Ââq}F×äÑB™9Þç3e¦÷BÉ-»×²¿S±ÔÑfÁ™ÕÐ}Õ7’ý$åÙ?¢N…}pžxZ¤v eV†„eÉê¸å`±‡Ÿ²;§&Oµu¤2Ð8o˜)8ï3Õ1ûwãɹàJ%“}AÕÓö++Ö1‚ó³­p‚ZqZ)»¹Bšæ@©Hý`Bê)Î’jž(9™úWÁu{äÍ!íò1o $b-ôm‹V;„‚xTç» ïý¼W7HAçÏÑãic2 {Û[xˆN¸íò>ozÓë¹paÅ»~þ·8=ÛX¢Bß¶4ÞS$ÌÆcR™ª¥ö¬–ûÄm$ç‰â'úí ,í ®æË­Á£‚ë(Ìô]©•*{ûè0àÔÂRRxg‡b©W„Ô¬p{—qÃsœ\ƒ’qUÈã{ìû=t*dÉŒ9[îA®ø¢´"4^¸S.óÊ;¿œýî€íæÐÜ[eÚ»‹í”ÙÆ‡Ùk;–}h3;>VúœÈUˆD6uW¡õ I²ÙBÇ5"wÙÔŠ´ £ %å·&GI•ê¨ÛbŠUoû€…ï¡ÂªmYŒ#Wx &8ZŸ"®²ß_&„–1œnŽpô´®3ÛiñdUކ3ÆqÓlí›áAo€óæ¹4Âʾ›y©s:nrÖ,8ßÍ4älMíÌò³¢¨[ÇQ¾Ê? äê¸pçË©UÙÞøŽ4Ç:ÊœJæg ÑýéÝ¥0_EòœHg΃æ9V¡VK{·q¼!„Ü`üh`ç× •´†-*e´C‡V7Ä‹K¼øÕ¼ñ?ÿùØÿóOÿáÈã ”ÜÌl™³o]rÎBæóshWÌtÍe¶÷mBÚë@©œ|è©ÚâB øíÁkøÖo€GŸ>ú›¿€ Ì?Ô_1O­3tR y7¢Íp¾ñ–â49æ"(q¹§?ò´ZÝú%CÛ.ð¾5¦‹*9eœ75l­‚çx3YW’G¦)“dDThKK.Bö¦ÔTEghLm¹”½±%2‚j"ƒ€œTòtLÛ,ÐÚPªÂ548ojS×ä4±{í-Wl6'³Û] ¦wtA‰æìY‹qì+”m&¡æ„CŒ‚Ç”âZÍÍÒiU’9'»Æ¼§o E@+òÄYÚžON<®84UyøqBç9ÙlˆÌ&‹~ÓŠ£RcÕ¦™é†KKÒt uÅââÈ#Õòóf |>„´0ž­é›u¶Sé\;¿w7cÅÓ)šÏâØÔl¡ $¼ÂmnÉ~XZ›V¬›-´Õ³×.X5 >p÷Þ–®§ˆr¸¹FÑB#<÷„e¨ö¢s¡$ÛOùÐÌêH‹ÌÈxײÎÓ n ‰l¿KµIlw–[2ʬÓÝ”‘³a¤ KéÚà5XØ·÷ßp!,¶…‹—ïãðèiš=¦4°YŸ°M¹dú¦¡o—¨*c‰ D¶i$×L­…i¶úèM«£*eÜ©0mÊÙ!WÇ6'*ƽ¯©í•‚0ñÚà½c« ÔuH=Âl£¦³¯8s…Í%Í"Ã]!î n®–-m ñ)š’E"›F‰5zê:v¡fe²ëüÕ] ¡C@ñhµe¯ŠMµz|päö–w½šéñàÊÛkŸžwaÎàLÔìKŒÏf–Ϫ@„šI‡áæÔz¦yLjŸ‡•°‹jÚö¥L¶lÜÍ0ÂŒeûóÏ,&BA]G×_aOÀmíÆAʆ³GâßýÌ㨶¸”=ÑíQÊ©áâsüM¥¨›;ô?e3oGÌ_¦@®qV®b>A(yk[㲂òqû^Þõ³¼lg#kð­´®àvTΚ8wV;O¯ÆËÅQS:xd>€T3ÎYȆ:µ Àûÿ·ºsû±,KÊû/ÖÚ—sNfVUWõef˜ 3†Ì`KF²eÄX¶,!ûùÿ1üO–åË’l,°Á3\{¦»®™y.{ïu ?D¬}NeWÏ ðÄ–º«*óœ}Y{­X_D|ñY:ÂfƒÆ5\^Nh=!ÁŠ„,¬#È5FNê’ Aˆ2PËÌ|¼CzkämM ¢wå1A²>xÌûï?ã?xÅË×w”ZÝ-ŸA ]ìÈËÞ<ŒšÌ1q§Z¡ÔDì,, !r¼M×u„q œf$tl·ÖIKÓbRÕxÞ‹?«wÝ’®·Jè7l7WÔÓÞ6™Ó‰*°œ2±³1Ë* »aGÀ¥,„( ]ofjòÒËáÄïüÎR©ÜŽ,ZÃ@©3Û¸%”*ÞÔøÓR½ð©W 4ḱˆšYÆ-‰Â¤ƒ‰Qe¥ë¯)Î`Q) µö”Ç’‰Q YY½ 7ÝÈF®v7<¿ë|ËLaˆZ{2\ó›ŸâËãS¤@ì{¢ZrL8doEx=n‘4qŸ^3•™.KÍ«ÿJ± !ÕD–HÒÅ4œÄ ]NåŽm­§®(Ûq —Ê’NÙŒlùgxùñŸ± 5)s­ä Û¡‡ l½ÇižØH"•)M\É–àäZáù«ÿ‹!LÆà^ŽmÐŽI¨#”Ê@%a–Bñfᕱ³\ZèÆ¥–D^’)_9M 6G£× X¾­PéH!£>úègyõæ–t:šDžŠX<,\Õ€Oµh@·Ý¢5Za3!F+ìÊF+ ¸”ƒ˜ ƒ¨ Z;;õîXÎëD‹÷ž0ÄÄö¢²¤sΪºÐ"€&äô®ßû%æïEDzëXç¶°É\?ú’µ?u›ÔH!V—mvÑtvP[ë5QÝRk%~ûÛßþÍÛÛ{‡£UªÎ‹Å¼%2nn,„œ9ï-.ÕÛMH çtñ3Ê™Ô ê:ßÉôa¡ä=O¿ð-Žû¶9ˆ‰yÙ9ºþ1µäó5.ÿ[û±úÑ"9"Öܹ½< ìÞû"uI„X­{ŒžŒK¯°Û]³L'bÌ>XW ˜“ –o ¬;!ÑZ¾)ÕÕ:4X! 1ZR6Ž ãZìYK¹§ŒCmÅO!vFòé‚OÞ:C™!ôh hçhs%s!<¾¹âŸþ“_à_~ç—yõæ Ï_¼¢ª€„JÑév¨&(É’L®¡cÐØºi±¼Ig19Ï ‹5ìN‹»ŸÑÜÃ`³4˜‹ÚuƒWùej¨uf™ÌÓPeÙû^,üÄ·ÿ·Ÿ¼@7;¾ù«¿Î‹O~ÀãñÞ¿ÊË»WƱpЊ’)j¡žÓ2s8’K¦ÔÂI36,ùUÓõ°ý²Ús QoJ^u¶2ú0˜ÐTŒabcÇV-i˜£Zõ®­j iÅŽÝæšë~ÃGïý=ú2‘±ë8Íö®jµÎUE+cˆ<¯ùpûu™)%yAÕÌ«é5‡eÏi90§‰)M¼Ú?gº#•‚t‘9éÈÝrÏ©ÌÌˬ…$­̺.åš8L{Ê’Œ¾œ¶™gî—§2³HáT¦2óâöc6NÃ<Ɖ 9»í ‡ ]‰ÒsóäCÝP¦#e6ïhð÷¿ Ö#ô‘%wùžãţ¢FŸ¼¾zÂaÙ3ëBªp,'æ’Ñh¹© ‘ñnSKZ¬Ÿª'—t©Þ,ȃ³¢tÒq:†ñ‰qó7÷M*/LΠZNJ5²Ùl)iñ:ÏÙI´µ›[ [Z v‡W,<éŠST5iå<·È,nG⸱d9‘Xïm.æ“3]Î’´?ú2O3Ãé •[GÿÅÞH<-whÙ)´ê¡ Ñ^ ‚БqìÙn7ìv[nnvtÖôzÒ y°+uAIŽØÍØèâ5ËrïlÒùwÕPwð]H!Qç—$l`^~ü&‚0¢Mù½ßFbBÓÈŸüÖ$„#?ñ“ßB†gäï}—\f¦¼ÐUB·ö­µC][ e¾GBAc2¹ƒÕÄÓªT麎AzÓ!ǪZkÎH?ðôýo¢/þÕŠ3 ÛȆ¾cCÏ8ì¸Þ=b¤c(Ëûùµy>јX)žlFÞ[z>zô7Ý#Ê\øøå÷™¼wAW¬“PÊJOdÛuHŒìëBßUb \ÉÜ)¹2Õ…Ó23×D„T …‚“Ç09maW1Q˜ôD_«ù×±RTÉu&I¥¥Ž×ó‰›>pZ•Âà½(|íꫵÜ#û=7U)ÃŽy¸bÉ™SY»“žiÉsÞ“ÕÄÿ¶7pbfÿêSî—ϯ™ê º-÷§]Ÿ-Ô ‘4Y³™hÃmj¹ T,jP¼Ç²˜‰Í±0lÞçÉ£/pûé_’r!×Tû-óñ5ˆy¥ÝfÇ|¸µp¢vÝNC¥å¯lmé2[Rþ¢ N. nœµ "ŠVÏi¡È|a牀ЈӼU®GJ©è›?¶îjRP©æik5’J)Æ",2 Ãc~îŸÿ ÿç¿üg„Vç’=Þ ~¸-·‚Dùßø÷úñÇŸðüùK^½zÃþþÀé8¯ÏQk$ÏEÃÚÍêy©-‰jpÓºB£'ošÞ¤×\I jôè¿ø <ûÂWøôwþµÜ{ãi¡–ÅFÇl:`ÉJYacF3 &åâÆ÷Q•š‹c©¡½P±ä"=Q*%TˆOì¥ríйWÕ% Ú¸8ñGœK»ÁÄ¡ŠoZ ¡@ þïÐCÖdúçs£M~cßB@¤ãêñÙ¿ù+¨J”…®¸º¾â8gæù„ªÃÍb•¦š‘A"”ä›5h±ÆÅE'¤dB7Pò 5quó>Óþh‰¦ê¼¶ ;Ûdî¢+fb“^+ø!%«îU‘8¢yF\} :BèÑ2›”®O^‚Xw¤UXAézó r:V²F«È%QÅŠç4¤X¯Üxõ„:–ý$¸–|k±Ò®Ø…Á_Õù^b§ŒqDuàöôœ«%ä‹r½Ùòáî#ËÛùÖ’¨ {çjM‹û`ìª(=[xÿú)RDáÕýk²$ŽË‘eY½m‚™À;:)›Nù @ aàq·¥«Æ:Yrf. 鬬ð4OÌR }`{µáæjÇt\H¹’K6}÷V=­ÅÃ]e ¯ßüJ®ŽDéy{×w_ƒŬt}0}¡Kš ,\…1Œœ˜ùëýfÍuB¥Š•ÄßMG\£Ýˆ‘B%K¦hÇHäIÍ®”ût$‹éìÃ@©‰RL®a.'–eò¼¡Å°ãæuz%SC±ü‰mãÔÎëªÂ…µ¦Fip)î7®†šµ6Ãn ϵé½{,öÜ.žAF”H”HÑÆ4ôâ?·{ª4ðõwÁsœf° @Pý–Ý“o²þ]`¢É «³·Û 77;ž>}Ä<åK_úðmän>óBÏGCņPÏZkLQB“¶Œ¾“´/­C3ú«?-? |<ñÉÇ¿‡–{‹iWÏn¯ ?ZßV• ¡§åýo|›évÏá“?F×&ÓCvy¦0±yöeæ© §¡j4‘{“{¯?"/'´ì±fmU‹Å«ñ¹iTB,1#l‰½ÉìjÍfè|û ¡óÐ@qÍ•' ?¹«§1Ú¦QÏÜÕ&h¦’9¼úS$/l}ȼ¯Ì˲˜QÄ¥¬çªÐ”+% ÀE®bñÊz$R(TT“Ä8p¸᳿Z¸Hmà ,z ã£YXÞИFË2ÛÜÐdÞQ™9k )!^!Ý@ÉG³žçÐZ¡uŠdJ3%U #ZÙšC )d-ôãhL«aäßøÿðšÿù»È÷>~IHÖ€¤¨²”DRèº }o4Öœ2e>B®rT FP©ÜÝŒL‡½;‘e1´[Œ}1ô#)eFQ6Ãí €ô›Âþ× ÏúîËÄóôŠ»41×ì}ÕÀ µXg4-Ü|ø5Ž÷w|:½@3²Ý`J‘ËrÏ¡‚­(²õr6¶‹i]•ã_™™±ô6µ¼ RcV‡Ž®ë­ZZ••çàO¹ USol†XÑHÀÂÌ%@è7tý†´NÕB¥@Ù(êU¥Íp9:ïûžynë«~iwýß 5íÙ?ÿ#à°n¾Û­»ÆܻâzuEi\¸²&ìšÞ2µJÅZ»á¼pÓ"6޼V¤«’ý<®AzãËk!hG­´ÆòüòâæRwJŸ-Sú~dYNžÐ¬<ÿî,$áͰ—Åh`!4æ7ŸÚ¦ZzÛTT@Œ!”Kb™AŠ¢Ì¨&BL”ÉŸÏ˨Ǿ·EY­™! UZÙeÛ?¡GNeâpÚó8lùp÷”R2‡eâPîÉ%<Þ<⦿â>MT…œ i^è»@ kö|(ÏïŸû¢T–2Óh½OOLy¦øÜ@ haÛðe&”UèB°Bµ•-YèÆž¾ßr¿?QºHY2u1)^ Ö»¶¯‚ZE åJâÐ3/3 Þ·v`ŸO|ò¿O@¸‰ÖpÝ:ueR©„%ˆ|éÉéÆk^ïïHó‘é>Re陲Ó'ý ×Ã÷óÄÌÂâ8}ˆh¸ágé—ùýßúOÜ}ò§Hµ^±ä91kY«¯¼ ýàL*óhk+.$°ùà«o_ÑÍw^£^,¬¨f£s ¾.ªY¬’³±º²‹ªÐ=zŸ'–ãÁKt2¦‰ÕhÄ-5H˭ˊϤzMìÂò Ó÷?q¬‚ì9’f­ÍÖš™—ɽtÜ0Ÿ.6¯Qav¤Ùèç&»î6õÂJ¶ÿת¦T ñ[ßúÖoÞßï9ÌÓ̼,¤\@¬Ê͆0´(«å²ý˜¡tnå¨Ú’¤ áFº~C)ÉÍž žªO\´Ý­#PÉyqÛv-s¥‚¯Xâ´–åâ¡<ëªÕîKúsfyE͉֤ÂÔ.«%WIWzÉÔì 2ºä1‚8í Ï¢ýOÔb.ª…~¼¢ë6tQ½˜$S±ÄlCHF£¬†ŒBô}«Úbo}¹­úL0!™«§_AºuÞSK2ªa'ˆì7ï£éÖÎQ%™¯VŽÚæŠZ†æ#šŽPŽfûž‡ZÌÈwÅ\G±ŸÙ6Ž0îi`ãŒi•·¾­ö\Í'òrÌPªÏ£B-³‹?ÍæÞ¢Pó¼òâQ8-x=‚ hJ6öŠ RuƒyUµ"Z ÑWkúœ´˜~Vk­³ñìÕ8çR•]6]Oš+YAb¤ïzVýräv¹ç¾.ÜÍo¸›^pL{’ZJŒyYxq|ÅTgB¦’˜µPªõÝÕ­ÙjRÍLXkBJ±^³1zû¸bݾªËG„`EhT^½|ÅŸÿå÷ùøû/Xæ“)j"-6†]ºÑB¹ NifÉ™>vôCÏRæ’IºPêÌi™XÊB®ÙU! uÆ .Ê ·§[&¦é„¸W``@ÈRYr²æÝÑ6Ú¢æ¡-sáõë;t™ˆ’ _üÂûü»û/øÃ?þśÄj Ácܪ…ÍîÊõpŠ ž4‘š¨š‘pÖ~R ¡ ùÜhQ„bEOêö#ž<þˆÃí§NÎ8QJ“íVï¸ä×-ôã5ÛÇOɇ;÷”̓o%ˆ öÉAª8餡nÌfŠƒÇ«ÝSr¶PÖ°»a{ý>Ëñ– 3H©›†YÁ®‹ Cd³ÙnG®®¶†ÜÉšPµE驟çlD ½šA\òÁ kïFÚâ¯ë@&eãæšlÓÀxóóþ•!äÐuJDï<ÁqiÜÛ3”sx=.ݼ‰ˆ¡©¢F©RÓ«*Ôâeõ ±–b˜tBZÓÅ4¨Cô¸qëcX,îŠéŒ°Æ§#iº÷HD¡ë/W»¶M!â4ºÞ{õâ ’UñŠ7Í– E©¡£ë®Ø¿úkßÑg£9JsAâ Ê›;sS¥C\¸ß’óùüþü:_øúÏñéŸü.uº¥† }µ^®Åš`WA5Bpm™Õ]ZÇs/:Ë/NQú페·äå T }ØHD¿KŒ©4¨Ï0CÚ-¼e@Á[¾9«š‚#ª,ÙШªwt½!W õw¨Ð+ôýH­ÂqñPQU´X—›\ w‡=K]ÌËB !R(œJt LÌš(ú #SÚs*{ŠÂ)–:z£ÝÖºP¤0§„ ±£¯•ì›ß³Ý5»0Òb à`´×lΕb’ËŠ½ï°˜„+¾ ¡ ƒÊÍyFufÛm6 ªÜO¯ µ² Vg\šy¤âôKHUé%’¥2gCÞÔÊÝ|¤8Y Õ‘¡tôý@-Щ°‰¾¦¬ÜçÂñt°¤#­zw@ËÁŠqž?ÁûíÿeÝÛÚJ mUè…×"ÌÓ _>¾þ€œ@¨çw¯=’¹˜÷Š Æ«÷8½þ+¿VF¥£{òtâÍþ¤œÃ¢muj5[aÞh 2Ï{ö/޶¸¬µ­£-Æ^ÈË%¾nÀ-º‘·°0̶ ¯ü:‘t|E>=·uØ *] ¤¿ù€åxÙª€ñ,“QV¹ãÿà7‡#Çã‘išY–DÎæjWïho#|øqC•[H~ÛÑÿÝv–ÈŠªa½Á²A;_à–,ëBZ´›<ÿ¼é$›,ÖÃl€wü¹zjUœ5wµ.¶QÆ­ŸÎ“¡ Ð#§‘ÿEªN½òÏ\Æ CóÚ…¾ñóHܰnÍ;àR<ŒãLž•ÖÙÛî›;¶€ÎNªˆt<þ‰ŸA0¢”쨣 %Y 0õÉ\.î± ¹!ù©ÿNª»zZ•/Ü¿øØIÅcšµØym–Z’sxÌ—~ñŸ³Ðý+O|6C.XÛêq.Í ˜Æ_ jš©iO”@ ®LíúÜ„@繺‡üÁQJ%4IçRœe% ÁëÔ7~{WA±&éröÑB¡‘G›O†+nÆ+‹ß¢h-ÓÌ›eÏíéŽâÔÒ¢F´œëÂ¬É rÊe6ÅÒR)ûåh>ªRr&å‰Öõj’Nœ’5ÉšIZ˜)”ï=þ"c©¼·ô1Xx°dædFª™…Ì\S™I®u#˜rç’­ˆÐj0Mú¸Û^ó䣯ñÏ~ý_1¦»7°œèú 77Ϙ'§¹R=ÜhÚÁ´ÒƒˆµÔB&“ªQçmad—¨–€Œ;4. »‡ÂÜê…àö@<õ/nìµÍe¥…XV\-wt¹YØQ\§å2íï¦KuN†_ÞOÛ Ê|BêLÜÜÆìûÀ8öl6Ûíùµ_û7úâÅKÞÜyóú5ÓR9ÜïÍÞÅÑÂdD:7ŠVEU©­· þZYÅ»Dui»©¹—µ%X=– 7YËj1-Gÿ»í8Í·÷€7òź´ÓJùÅÔùLëÊ3áAFúq$§É bY›0J°—œþ§j¹±¦T¡ë7 ,Ël±ÅË¥e O¸ˆ!Ñ䑃‰–9ÅN Ó¤‚kU¤f¬xÊŽÄd_sرÙn™ö?°d#ÝJo2ÔÚr6Î}¿±º¤µ@´MK©ÎT…íÕ5iÉäå`"S åÆë7º¤uÀJ5n¿8ÝÐPT‚0òä+?Û?û¤ßÑm®Xîžópó5Á9«l­²CºI{~Å1¸f„@ß_bÏtºMÖ•¾.H5g‚½Rµ#Ä‚åD-éµÎ5$néÇ ËéD'Ð Ä®gè·ì Âý|$ÕÅÙM•®ïÈ){(c+ˆW×zØÉE 0„ŽÝæ1¥ª·wS:®=ãx˜ÈyJ&£v¢Ä‰ˆ}舞 ¸4F¦rbγ}'Z(&ûÒPè%CÇ{¦e¢zµró›áštzCP nè©ù„he)3EÌ)Yh$8°É.¯mëË$Œ9q*†jFªyò"ÂUé¼ÚR3smûå´rÐÐæ¦‹Ó5`":€ó ‚TkÔãv£y¹ÕbufšTA¼ÊÔʃ‹{¾g ÔÕÕ[¯¨VB ì¾ú‹,‡{æçÿÏïíbÇ@×o jšmc bXQ¡¸wZ7SZ¸‡fûÚ9íoÔÇê\¬!p¦N;½ÿ]•ÕÊf츺yô芧OóþûO‰_ÿú× ¹NLÓÂ<bh»ãYÓ¥¢Ò#qc1)u£¯}»Ð‰©¬i3L@=9WÎ?÷o4¥¡ã&:/Vá©É™<ö‚ËšPh‹}K „Þ;D¹OQ•\¼šËa %˜÷uŽr›„¬×$Z‰½u77Íóâq`%†&ƒìÅ[efUos4$” ƒýy•qØR«ðèï!Ñ’Âöp šÍ Êùˆ¶ê6G–hez éxlp.lK6ÙĨ%!5#Ž.Û÷SšQ‰h^Œ­³N¸æ]T¿ßÆèÈ.9 }ÔZ8¾~n¯&òtn¼J7ƒ'’#5\¯>@gKT·Éiüf_¢”4ÛX«SD%úý¡£M£õ~QÛXk%ŽÌxä„Ò#u¡æÌzBxòø)5W¤Zcð9O–K±*\j2/C4(¥ž(u¶ÆÜÃöʬWË=ˆS%œO Ñ@Ìâá“ûÓ-¹ÜY¡ h>b¥>Æ3 ^C ÊHÐ@ÑD®™"R 1ØgjµPAÀ’ó¡V‚8R¯FûDò‰tzCI ¥N”¥^»Ýæ¦yë!Dj^Ð:›·+–Ó³¤oACÇ0]=$(gc.è…¶6¥¸»ÔÐXŠ8~_CÓŠP„®·"î!( »'Ô’ˆ¡zܽg¶Û‘ø“?ùõß<NœNGæy!¥…’/Üi*3¾¬Ô8Ð!ìœ ÊŠîÎ"dÑË<^ÕíxôÅŸåçåWøþ_¼@òÂÙ}¹‘øõÎèÔ½»á4ÕÁË„BÛe•3kG‚3B8'*Mî6ðè£/3çBȳÙÖ\µR†+ºáŠ2‡µ> )™Kž<£k A@uÁ8¯ •ÕŒ`a­…œ´f¦»¤ÓkB±ðV“dŠeñÓ? ‚‹›—lÕ¦¡Q¸ÚiÏéÞSŒÍkó´Ì SË’:áz¸˜˜ï¢fÈj¡±„ -+íÎ}Xßž¦+úA»oç_óÉ'oÐÓKš \[­ÚÞ9²RÓ$Øœ“RÝ™ > ÛÌ,î^ÖMNÓä^• ‡1 ]s¥UIef® S('yÓpió¼Ê 2Ô2‘S v#5Íàlu@k&yƒ‹Ø{[ÃÒÆ'Ñ”AÁ’£ÝEÍD¯ §’SoEÄÕ…Jk=p«éϨiõ$µð„T[MÙ7йX3ò"ÊÑs¥TºØÑÇŽ”rΫa*ªtÃc*=AËþžœö”Z¼W±ÝOtÃ^°$j­e5–ŠZ‹ÃÆ_‡6O fµ:õwÐfE FYÃj-ìa §zª‚N¤ÃžP³éœchšh¹=|ž©VÊb›· £R]0]-ky×’µˆhóÛXLº†ýš=I>ï2èBÉÓ…í»<Òa\Ï)²±5/í;ýúsX[}}xŽJœcÑÖ˜¯½¼Ñš‰1Ð÷͸[hF~õW¿£/_¾áööžýþÀédò”Ž1|'óÓd‹C«¨ûµiÆbV  "d÷>Ìoˆ‹µwCëúNC ®ýâ­ö´É‡õŒç“Ë™I±þÎ D%«çïZŒÉH‰„ÍcXN„ºo£»Ð¨—æ@5#yr}°×Øš]Q¬) ”a¼a^Žhm #Vô£ÄfMv7gzåзÓëÅ¥¹œ@o[f—_?O/ÜhmMp+Ò;òr¤éô¼kR†½\x]ë†+œÃCï:.Î'M²Â»¹«m†âß¿l[vF*Ž_$xBÚ7ÕàMÎÝøªÅÆÖï´2s+LSŠ ÎîbG®¦]²–7¬T.øY^œª©B"jgQ³šD£…¿D±ŠKèk3 ‚‡΀Œ¬Ðž{Kd”Ž›ÍŽXƒqÒ)H€a©jÐbÉ KÍ”jy!Æ@L$šLqµÜEqð!!Z‹;¼qˆ³1,òYmc*•ìõQFz¦ù–R U¬èÌ;<¬›ð©&J gÚK³ä³{ˆõv¥ÁCнÍÖy*®‚Š¯ê ³wÏzqäkONzé~ ¢aÇ?õÓhUžÿùwÑ<Ùu|L`µ6Bäí¥p^C—å67Õ½7rNmÌß÷õ"‘v¨NÖçÖ!ï ®.1jR*ç+]Ø)XMQôšû®Í-e³éÙnG®¯w<~|ͳgO̸ßÞÞqäx<1ÏÉ dìâ²ÞÅÙ¸[ŒÛ¾Zœ­—‹ý’Åri”ƒìö»oL›P/~¸:bmdm1‡h’ÁÒ’¾ë%#}?’ÒÑà gtm‰;“ÖÖ¢O+¢£‰‹kµ;mƼ¡Lõd-ihÓІ¬ï6„Fµl/RÎhû<ÈçgüŒ­õ Î]Íu#@³‰iòË5Æ‹´Šé‹Íâ,™pžÄg©mV–C±×£u‰©†TtýÎåqéa]žSü>\«ߨФx" ³4ƒ­ºV†aGI‰Ð[Y8] Ž)鈤É]dõ[ðê5î>”3º?oÊ6«ÿV‚l“uÏ£½o¤ÍŸìب-ùk¼tQg¹TcjU1$lìѺóª ‰x³bWBO­ax­º6JiS7ŠhU5@DlsÑæE¡º'mãô]ïCq Tì’k´T­Lól}õ|.ÌŒš¤CU3N¥Zñ–ÉVÁÄ<Ü}Öp gðbÄ ‰8«½Gõç–ƒ iõ—ó×û´šîKËU¤‘*hÈÿÂã¼¼ÞzKîm9P°k7„ß^Èùɪy¸%ùîîf“¾XÒÌÚ%Ud]Aíý v66ŒwÕó=CÇ8ìvV©úøñ ]×EÆq¤VëÀ3މ\ô¾ùeܵ%tÄaC9ÝN™ U[Pü­?uƒp.k?ogˆÚ*ÉxÇï/ªEµÝPCOˆ¬_åB«Že{E[œ¶/\¢O?¯íÄ„¼š!_?sñm‹nã 鎵žªç^®•·î»«×]0­¡–óVtú-"1ŽÖ‰¶½ø¼Ø*ÃÕ–ý›‹Ï=8égÆõ«°>ظþØG<ø|;š¾ýÙä(ð2kUñ«hy/í6j¨éç³í ±m¦U¤ý¡G:cÕådÏÜB,´JÄhç¨+„z0þŸíGéÍkm:Bª(=„ªôú QÎó£Ò!ªT×ò)%¡5âèšäÕm¢ä°†!¬ã7Ä®™¼Õ1ÁÃÖÑËŠe:—‡U¬kTªewל±·wê]Ä|í”ZœPTØŒ[ó.—kÓ‡*y¸ODŒ>Úäjá *„hã!ŠÉk¬ÆÖ¤É[†½ýÞŒ»t¾Ö}÷Ò¸³z<—ÿnÕõ>üï0ÞЪÚWбzŽ£XÏØÏ"+?P!yðY½8÷[Ïæ¬?ËŸse-ýy »4뜼°1º±;гTA×ú¾c»Ç®‹tÛí‘À0Œl·‰œ³³V>o@ý®Gÿ]8W½µƒ½ë!. Çz..~/Ä~cçR¡úãÑŽöyàê­óšÅç|ùáÏ.9ú¹X¼Æ–`7kË<|që=?4*\ U»@c×¼ml/Ÿë­os§‹Ý`±h½ßæIlŸ¼ã9žïáÏ"’ËŸ}Þx÷¹×Iq‹Wb¬X7Œ”4ÛÆŠ¡ñ¶•¬çkbm­ÞA"Û›G(ÂtçÆÛ Å|,›ûÜõ½À o?âÃùtùŽ/Ÿ»!S' ›kã¶$ÜeÝÂgÎwñ®ìDzŠÕslàGd ¼X ‹$øçÄ[“„®Þ–2¸Q aôP‘ÜúUÌ›0#náfÐ×^¦÷œž*b=} í™Õß—‡E”³5ò±øÌôËke½†=»åÕ,”sžË-_òCÕ+h»Â嘶K_žCWô¶ŽÏµße»y+|„à…N½ŠË¿7øð¾/Ô»×áC<ùöaß{81Ê[ ÕÍf¤{ôè†ívKΙœ­ éÌ\ù¼+ü0ãp‘¦1óÐh½ë†ßõï‹“Ȱ½b™N¶¨Þ½:ßq®u¼Ë;ø¼Ïñöí¯·i†ç\Ùö®{û¼sª%]´ŸwX›gùacüÃîáâjbYùšŸä—ç~è}ÑáÙh±þ ?÷YkãÁiÙ^œç]HÎ øácn=x$ÏÉ|¦Ùç§|Öè¯h×¶´=zš7{^h?þû:»Þ—I3ǃn:Nî®s+…vm?—¬&’5©Ù~ú¶wyþ³âùŸ cþÖ@蟷Œž¼ã9”á]?ÇÅTií[;؃_üù¹—øüwzéyüèwó.;ònC,±w ò®õ@:âæŠ2ì ŸÙ~”y¸ùŠ÷„~ëºç{!‚ø®ëèûŽîÙ³g´†ͨþ.)þ*o¿Øw…~ìã­íýs®) üþÇA¤?³œðßç£e«¤´9V?;OÎðêóÏó7ÞìþGgOì—•·§ÛßSü-ù!_–Ƭù±Ïö7ùìgï¤ã]çýìç.~÷.iýžœÿúãÞÝßÉöü°ã]ûǰ9" WïøÅç#öÏ¿þ»¯#Î~j—YÕtCüð.ŽdRögsIEND®B`‚swami/src/swamigui/images/volenv_release.png0000644000175000017500000000105110543044062021451 0ustar alessioalessio‰PNG  IHDRàw=øsBIT|dˆtEXtSoftwarewww.inkscape.org›î<»IDATH‰Õ–¿KAÇ?³;3zš+Œ‚ hŠ ImS‰¥ÿÁ)Á„tA)Rž !©RÙø„”J,A á ùuHâ]`fö&ÅáéÞzwY½ äÁÀòÞ—÷á»;óv„÷Þ8ç°Öb­ÅÓxn^­j­ò@AšöV2l£ñž¯WιTÍ„ É={ÓVS*ä±ÖXkSþ6¤”½(¥Œ1½XkÉ/,#‚ w€»sYX\CëLWZë:ਠ¹órÚð.¢TÈwÔ(¥ÅbÑŸ\9¤”(¥bKkÈ¥Éÿ’ßþ⪻5‰IEND®B`‚swami/src/swamigui/images/switch_pos_uni.png0000644000175000017500000000050510420662631021502 0ustar alessioalessio‰PNG  IHDRù‡yÕbKGDÿÿÿÿÿÿ X÷ÜúIDATxÚí–½ ƒ0F¿ L€ÄOåš2ƒ=;QQÛ•;æ`$ V¸‘C" ¼æ°çgÎÒÀŒÀ‰Ý3sˆºDDDÀÍ÷¢RJ)u¶îѹàvẮkȲ,Û‹¢(Àc¼Éy)¥”’w¦iÊÌEQô¾^‹yžçÌÌZk½Ìæübï“$IÃ0 ¿góÞÑP¸D/ÑйD/ÑÐñŠÞï}ß÷ÀÔ“}½{Çq¿ˆo– g˜:ëü'ZU]×uѶq°iʲ,¶BˆýâÖZkí4æáSôCÉ1Ööq~ÁÜQ÷×X”>4\é_¢g ùxI._ZrØ[‡IEND®B`‚swami/src/swamigui/images/sample.png0000644000175000017500000000111410454447011017723 0ustar alessioalessio‰PNG  IHDRóÿasBIT|dˆtEXtSoftwarewww.inkscape.org›î<ÞIDAT8¥“=K#Q†Ÿ;w&3Ù,3(a±l#V‰‚ °1‹"j)X¥ÓÂJ,¬ü¢ØX [¨…!6,‚ •b¡…‹ÐÉN’q2³EºÊ¸°¾Õ…÷œçž{Ï9ø„T€ øùθ¼T™žþÆÉÉmh²?PÂÌBA§\ÖþYA(àøX§Ù8Žø?@©À¶[€™™N®¯åÇ€\.ÎúzŒjUp~®‰ضÂÕ•dcã+ÛÛQîî^ÒÔö¡VìíF@"á‘LzÔëÛ”JB‹:Ýݹ\‡‡¿^77’³3 ) ¾>—tÚ¥\Ö°m…Ý]ƒ©)‡£#Ëòééy&ŸïTøB*õ•“ÙÙ߸®`m-F&ÓÀ4 Ÿ¨T67c¬®V˜Ÿ·Ûà°´ôH±h0:Zcp°ÁÅ…F:íbY>;;Q::|R©gúû]„€ù|ðZO˜›³I&=††êœžjìïôöº˜¦ÏÖV”ññÙlx¼‰|Õ @JkMN:T« š–p/iy OøþßmTy£D¢Éòò#¦é#e@6[§}‘|3 ¡ƒÔd2.–¾oï*x­‰ ‡ááÆG!>¹Î0¤þÍâüÙIEND®B`‚swami/src/swamigui/images/concave_pos_uni.png0000644000175000017500000000100610420662631021614 0ustar alessioalessio‰PNG  IHDRù‡yÕbKGDÿÿÿÿÿÿ X÷Ü»IDATxÚÍ–±®A†¿ÙXA"¥B±ABâ ÄnTôJ¯@µÆ³ˆb  JO !ÙD¥!âÜBöZd-î]öof³™sòÍ?gfŽb®„÷!"G\¥”R ´°‰–eY–õmÜ ·€ÑF£‘|( ”iš¦iJ„2 Ãð×òø¡kˆ\®ëº™L&<+´F£×n·Û”J¥R,Aûý~Îe`Û¶ôÍçóy]×õàYßít:€ív»¨×ëõ§ƒ?áè|>Ÿ‹ˆhš¦‰ˆd³ÙlxÔ], €jµZõÿ_.—Ëç³Dz8­V«P©T*p~ f³Ù  X,ŸÏú÷èd2™4›Í&Àñx<är¹Àf³Ù$“ÉäëÙßptµZ­Úív@×u Ñh4N§Ó `8árhÞ¼Qp1år¹ì¿F”RÊ?¦R©”ˆH¯×뉈ì÷ûýëG-èÐz|êô¾ù¨ÕÖëõºÝsñO§…B¡ã±a¸n:NÿÙ©;9Žã8Î¥Í u4ú¦ä9GcðÖ_;¤»­›¼­ÿý6P˜~[ýC¢c‡þIEND®B`‚swami/src/swamigui/images/linear_pos_bi.png0000644000175000017500000000056410420662631021257 0ustar alessioalessio‰PNG  IHDRù‡yÕbKGDÿÿÿÿÿÿ X÷Ü)IDATxÚÍÖ½ ƒ0àç(+@é\e d7¬À.Ù vp—0Ù„%.Eä?†81¯É2Ÿî| "Ђ—óGè¸Åì–?@·µx7Ô}(†¹^9ç¼tkñÜ÷¬ ¡ûïÁ– ÍºJ)åûÀqôÞ{ ççœã(Ç@®Ç`̳1Æ\ç—È‚cà4Ykí•§¸Ô@œÆŠ Tƒs@î}vW×êàmSJ)>X¤µ"g°;–R#sY´ÖºÞ5LñôAk?n_ú^;áUcº´T]°IEND®B`‚swami/src/swamigui/images/convex_pos_bi.png0000644000175000017500000000104510420662631021302 0ustar alessioalessio‰PNG  IHDRù‡yÕbKGDÿÿÿÿÿÿ X÷ÜÚIDATxÚÍ–OjÂ@ÆAA© Á• n<€Ëîü³1¹@w]x=‰‡P(Éï Ø…PºsÈÆ×…LµJš§Ôoæ›_Þ¼÷1 DxpÙúCDäq•RJ)°L{žçyžy`c —€ñÀ“ÉdP­V«­V«0ŸÏç‰Çˆ1¹®ëºîùJˆH.—ËéöqÇi6›M‘Ùl6»öÓ|º^¯×瀶mÛ""ÓétšÞOóÙ‰Åά^¯×ÓEØl6€z½^¿ÝÍø0=?ïv»À~¿ßôûý~vÀ ™»ú÷÷R©T±,ˉ¢(Êî§ùb+š5fžž¢(ŠÊår ŸÏç“÷%§~Vôþ|{[, CÇqxy ƒÛ}|ß÷}ÿø±W3IÚn·[‘ÃAûF£QúÝqçi¾XÐÛÕn·Û"‡ƒRJÀï•AP—GÀb±X4ñãÆ@uÅt §üõµÛív̓fÈÑ €F£Ñ8__­V+øü, …ìç_@õ#¡V«ÕŽS ÃápÇyX.—K€N§Ó1˜ôR•J¥0Ça†'Àô¯§»d®§nµt=zø&øß ÿ ”¤/-æ× q2ËIEND®B`‚swami/src/swamigui/images/effect_view.png0000644000175000017500000000030210454447011020726 0ustar alessioalessio‰PNG  IHDRàw=øsBIT|dˆtEXtSoftwarewww.inkscape.org›î<TIDATH‰í–± ! ψ=˜è§e“×/À$¡¥Kå‚Wn€X²¯ˆ€ÀHXÓ“1Ñ,—îž ¤?lÐÞÏpEeQJY”R¥”E)Âü¶lÁû!k‡¡IEND®B`‚swami/src/swamigui/images/splits.png0000644000175000017500000000045410454447011017766 0ustar alessioalessio‰PNG  IHDR!-sBIT|dˆtEXtSoftwarewww.inkscape.org›î<¾IDATH‰Ý•Qƒ0 Cí¦ÇÝŽÂŽ‹´,ûY¥BKѦIø×ÁŽèƒ€™€¤™I„Š©Iy¶ÎËá°P±Üe¨`šÃ…ÒPÈ ý¼€øÇ”º4Ü®áŇ¼Êò IûÞáIŠåÖ"Ê{ÓýڋRäHƒ¤=¢€÷ô%ý/¹R‹’ÏB͌٣bT¾ OŒ×Š˜H¤¨AÌV1aøš¢ÞåŒ20§¯’ã ÎÜ^G5ÍzІo¯£R“7™ rSÓœIEND®B`‚swami/src/swamigui/images/convex_neg_uni.png0000644000175000017500000000073610420662631021461 0ustar alessioalessio‰PNG  IHDRù‡yÕbKGDÿÿÿÿÿÿ X÷Ü“IDATxÚÍ–½®QF×™\L¥($"`:*•QÌy·Pz¡©DC#A #‘ïVçâ2W0«šù[ÙßìÉ6 ‘r¾Ü$¥Q×cŒïÖ…ÖZkí§uÿý-˜a%2Öjµš$•Ëå²$‹Å¢$5›Í¦$Çã±^†ó»ý%»Ýn0N§N§Éd2Ýn· °ßï÷oìh†a^;Çq,IƒÁ` Iù|>/IÆ#I¹\.'I‹Åbñ|GŸM¢×ëõN…=Ïóþ/üBQ‡s¢¾ïûÒ1‰ÇDÿñÞK½^¯ŒF£@Ç1@ÁãO{¡¨£ÕjµªÕj`µZ­6›Í&U¢ŽÉd29­Ûív;•¢•J¥P( ëõzJQG¿ßï‡Àr¹\Þ}ó+¦> 7õî÷e­µú$²ÙlÀ÷}`>ŸÏoïæ¼£ï[>ív»=Ö³Y©T*ë(Š¢(:®yœ‹¾#úÇÞãü>ýu\“¸ˆ>m¸èD?-t‹oݶnAÎ%IEND®B`‚swami/src/swamigui/images/linear_neg_bi.png0000644000175000017500000000063610420662631021227 0ustar alessioalessio‰PNG  IHDRù‡yÕbKGDÿÿÿÿÿÿ X÷ÜSIDATxÚÍ–±‘ƒ0E¿n\(¤ :pˆJ wJìŒ"`  :°#J ¡Œ½hƒàxÞ¬ö/ˆpr.ü@DtF]!„øÙzcß÷}ßß^ø‹h]×5EQ˜ î$LÈó<çv "ò<Ï£Y”RJ©ùuKa¿/¢ òº ‚SŠ2,Èë£(ŠN)ʰàç–ØKôcÒ4M ëºªªª Ãpóð̇iye†-ñx8Žã˜Wnê<öCÑõcåvkš¦®×¶m[àõ’RJà~w]×5ßOk­µîþò|J)e_á©Ð™VtRt-ýãÐ-ž]¦¥pè˜,Ë2 aY–¥ñ¦{TtÌøÃ±¬Â\ýf-qÀÕ›¶„eY$I’¼¿µÙožùß Çq€mÛöì1G^½ì÷6ðÏü?ÑÿšãNDçzv¼ÔµIEND®B`‚swami/src/swamigui/images/modenv_sustain.png0000644000175000017500000000113510543044062021501 0ustar alessioalessio‰PNG  IHDRàw=øsBIT|dˆtEXtSoftwarewww.inkscape.org›î<ïIDATH‰Õ–?hA‡¿¹›]MŒ’Ä3 9¸S„ÃÆ"Zi!šB°1(6VÆÆF­ ’BR*W¤mD°ö‚p)$mZEEH%¢¹€$2ovÆâþÄËíN”ät`c ZD n0s¦ÌëÇ ¬½ØL¸<6òw€êTÀâÂtêÀµ#EnÍgõÉ&Û?`[ ñ­ç¾'ˆ9{rŒÅ«ç869š^µ¶«‚í³¢| ®ÍÑÃPŸ?Ń—yûîk@ï'Êñ1DmF¸v¹Â‰ŠaýÕ'bßå­ ×î°).Mr|²ÂʳÏlmGÀÎ2íȲᒠ:ý§§`i®Ìýç-š]¸Œì¦}' Û?^‚ÛWм)© f¿dxëD…1µ{ßS=[uÿ»ÿvCR²ŠrÊ»ˆf½¶¯Çƒj4~÷—Ck1¦+Â0ü#—'ÿ î­G_ÐàIEND®B`‚swami/src/swamigui/images/piano.png0000644000175000017500000000026310420662631017554 0ustar alessioalessio‰PNG  IHDR®²‘bKGDÿÿÿÿÿÿ X÷ÜhIDATxÚí–1À íªŸòóx]žå- -C+¨Oºá R°1){-lûIƒ$ÉûyËr-¿ÍºyM ¤@ ¤Àúí(íÖQî/_çúÁXH"""ú $Iïq¥œ\¶àŽzBžëel^IEND®B`‚swami/src/swamigui/images/volenv_attack.png0000644000175000017500000000102010543044062021274 0ustar alessioalessio‰PNG  IHDRàw=øsBIT|dˆtEXtSoftwarewww.inkscape.org›î<¢IDATH‰µV=OA}{·»¨.€D &RZ¨‰ Ô6Ô„Â†ŠžÊŠŠÎhbâO1ñØX˜XÚÔ•ƒÜÞíZÈa€½“Ü$“ÜÍ›wo2™=¢”Ràº.„BÀqœáó¸aAq¢”R„èÌx¼¡¦óM¹äî™kµZ ®ë&ÔÄÎùM(ÁS³ˆ !`!B ,b”Òh c0lj”€.¢`y%+»…‹;¥Å;—󷈲ʧ C¿­sÎçS@ˆ‰ãRñÕmHùŒw}^rÞíÕ°–*Âþ¤‡@+=Án±+{»ûû.¥ž€`¹ 6 %äòåañ0`0EÓŽi:s€õÊ_ñÁv jÁ cOì!—¯Áî’‘âS)ø€Ç °2uôlªÅ½SŒ)E"Õ@ß^ÒÃD¯À8T`eÔ$ àÓ¸EßNއGòB§È'xëèïS^£ûÕÔýÀ¤WÅëˉcì>úeýºŽ’€s½‚Ð1U®zçú9a¤Ýn+ÿ—ƒR ÆØˆsÎ'b³Ä½<\ì!„€IEND®B`‚swami/src/swamigui/images/volenv_sustain.png0000644000175000017500000000113010543044062021515 0ustar alessioalessio‰PNG  IHDRàw=øsBIT|dˆtEXtSoftwarewww.inkscape.org›î<êIDATH‰Õ–?hA‡¿Ý›Ùx¢"!FApýK$…Uˆ•i hccellŒ½H*«³¹Â"ô’ÖB!p ˆXˆ6ŠˆˆMψqvfg,6»¹»ìÎ’ øƒå½7ïÛ7³óf=k­ÐZ£”B)EÇùs÷(ó•Ù=k­õ<"ùïã‰J¡/“Õ fäv¡¯V«!´Ö¥“=Qáôƒy'àãÌT©O)…¯”r&ØŽ„ýH)ñã8î/@)ŲeaÙ2ûä3ÃGŽï< A+‚}Bî=l0txg A¤€Õ&ù"dú~ƒÁCÛ‡H) ]¾rkºÁlõ5gG¯:“|ØOk«€ôØ… ìùDxêšPÝû•ñÉG,>½ iSè È &è3?ÆÀ‰3w¸xy¥g71fã³—R"â8.© ­µŠ üjÂÐð Æ'ò²qDGÿX(ê]ÁÏf_­^áüØsÞ¼šD«Õ^{I²^CÉz/0rn‰ï.Áf@ûjäKÔíèŠéxA`”£Ç^ 劻‚|“]{Ðèˆ;‰”Íðã[q†Š™cí÷LyvÀ$S|_™(ôIùv—šÝ È›]¿”Ÿƒ2Y8ïÜ,ÆðêõºÍ~9„H);F›l[±ÿJ0(©Ü ¹øIEND®B`‚swami/src/swamigui/images/python.png0000644000175000017500000000403110454447011017764 0ustar alessioalessio‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ pHYs  šœtIMEÖ$L`¦IDATHÇu•yp”åÆŸ÷»öÛ#›ì‘Í}B$ !!"¢C'ÑV©:Ulµ­´S[E;â´NéT§ƒS‡imÊQt ´€¶¡¤`KJ=@Μ¹„²›ÝÍæÛÍžßù¾ý£{ÏßÏÌï÷üõÆ ŸƘ·¯¯¯½¹¹Ùs±ÿ‚'§ªddhÄ×yûÚ€=·vÀf“ÿ³X,—Ëò/ÀçEJ§Ó8¸ÿÀ©Á£Hj PÎ@BY'p@Ò†’‚ª‹ªë¶þô¥WÀó< ‰Àn·ƒ0Æ8ôŒ%MÓ–mßñò›}œX•ß@±ö‘¸\vÍqd´ ,ƒå0ù'Ê5~{E€o¿õ6ÊKËΡ··÷ÿÌ„nn:3|êÀ¯÷¾G¥êVŠyLkãHi0ƒƒh9 Œ‡ z‚Cÿî8²SÜxï±ã;¼V_·©Tê¿ûöï}þèð›Û3zKÚJào gg°`)à¦išÅçf"†¼¨;¨—a0)++G0y"‰D¿8üÝï<ù>€§Ÿyú™¶¾ºyÉ¥‘ £·?ØßbŠéì2F>€Œ–±‚á(gH13ÙiF’š-€êf/²4‰¹ù®¿—'³¨÷›_Ûð-ÂÃc_LêŸøè©{¶Õïp—š•…ƒÏÓdÝ+\º4ÎÍÌOÑgÂQ8Eô¨ˆù¹$lá"Ć,䕊¨nó@.à@‡“¯_¦MEí#Vr===ÎÞß^ÑêÞá,±À[6”ÚëÍtŒHÇŽœãϹA¤€‰¼J@V„DD³D7r{²A ¾”LÐV>XÊ݈Œ®ødöø‹ýç™§Vz®þqº^¥9Øá2#3 ÂùbÈYxšg1lå¡ÑÙŽé¡›‰ñåµ~1ÛŸÖ¦Ž3‰¤¢¨¹´ÛY*‹†f€ÊâÁœÆxÃÏ ³ÅÛ©¾dJ9,èqC·tþò§WàZj¿È/åQÂ× †_á¾ î»Á¹ ÈŽ¸P–W‡¶¶¶Ñ ^þa|ÚP͹,•d†T: 1¦E—qÕ­Þo$¯[pëŘ½@‰ì5$§îÅÛjÈ)?Nþ~€ öMZ¾zdË [¤«W­Þ©ªêfq6­Àig¾€B(¥FÖR„Ô{Í‘ïïvØœUºV›Ê5âå‹9‡™OsàÊ`cÌ2S£Ö²»ýB­Ö„k–wþV‰+O.[ÚAÉÆ1¦¦%³à%†Ü‚a1 ~ÕŠÖª›£‘ÓsWµMþ:‡ ¦Ý\z\¶fÆãdðħŽ$µ˜µò •b±§Ùk´,»í=Jée%娭­AEEù/ÃÑ‘ÎòE—£i¨¦ e)K#Wùßì~ã-gŒÍLFօΛäU 3Wb\êŠB*Ó”,QÒÐૈ 0¬_Óýw›dÛÍäPQQžç_ݹëçß«o–à© tz@'ñ h`Üß„¦¦¦ƒ©Tò«·¬¼å¨ªª¡Pc‡Þ@ƒ 8±FÀºö¥‚ePÆ€»:î9 ;I€ðð8òäîm/¿ð\õb²›ƒTHá”D-¥6jòN‘Ê;Y–ÑÚÚ¶n.Šéé›*½~õ'E6ÓkK°¶¹ žDCyÝ\×ëàé‘ák¸㣠”6}{ËŸªoò¢¢²¥»¨OR}–Ù3ó4>¥ëVP&'WW€Ý§išëÐ…~|%KpdÈq¼(ÌÅî~\Éwd)¥? ÎD°ñ¾Gàs—a]Wýã­·•-oYUÈ-•Ù :É)Ë“à“ÎÜÖgŸýHS5ÐCÙÆ{´0y¬÷ûôâù'  -Tu÷'îDÉ[@©…\NÃéÏáŽÎnjй¡®£v‘çä—®•š[<Öéé‰ ÿ0ÅG.2KJùRº®y_|a„°aÀzeû^IÓêùl.GZZ¶ÌVV¢}ë Ëv(Š‚wõ ³£ åeµxåõ{ÛKJ]ë=RË?˜‹Â]î0FF¢öù1KgIÙJ§ÒÝ–e¡¢¢B*^/›f"ßîx§ñwwÂçKþót€¸Çþ}‡±rÅZ”ª051‡¿þy|ßý›ÛÖteHÆ–qjˆ3S&T˘çÄLܸ¾gמIðûý gÚ×Tr<ï\ÜÓsM%ð<ŽãIg±{×(3.¬niÇÙÉçÉ^¼m]YŪvó×Jy=!„¬,=«Ðè¸&/\5UR t¼÷8ü~r³âСÏ^‡ÃÒÁx·®mÃ_üø¢?£‡ÇŸ[ÖäUﺷtJr»B3ùª“Zc™ŸO‡­¸µ@΂з; ­Xµñ˜‰eüφ!"DQÇñ „€#N€×ëC~„_ì8ØU]ë.ºóKeÆÊÎÂé©YEVôìÈÔX<¾®ž ˜SÌâû«\§\>]xÑH^o>I’>3'„(¥Ðu¦iàòõ½ŽêEyŽuwÏ7´xŸ»™?3›")] †‚¹üè 9Ï(†<Ò018 š–×biC%ÚnmÀ?¼À‚áòëIEND®B`‚swami/src/swamigui/images/modenv.png0000644000175000017500000000104710543044062017735 0ustar alessioalessio‰PNG  IHDRàw=øsBIT|dˆtEXtSoftwarewww.inkscape.org›î<¹IDATH‰Õ–ÁKAÇ?óÜ3v0èÔÙƒ—N!"þ%vé `B¡—øèðDòE‡¤C† B… Ô.áA"°Kæî[d~óÞzq«·¾çÛ…öà†ßì|?óe~ «¢(Šœsˆ"‚µöÏ<9š­5«{J)òP©T¢àœËÅ@D(ˆHnÏóòh­ñ¬µ\¿ÖÃåÎKçn¨Õ"¾îýȈ<<ÆÈ`ËM³ o˜š}•@ÍBõ¸þ‹Íuì~à3ódµ%ÀóÀ ¿»&ôèÞ0ÁÑó/73$pß-ÍcÍMÞ&|^,ogØÃÔ…âÙƒ!*• ¯ßî¦ø é‹Ó·õûq›âÂL 8}^4°T¼Éèø1[?ÏIPõAÚ3%ˆ¢X)ö1<±ÃÇÏY” Ô™ m°^¼ÁÐÄ.Ÿ¾…@²M«H-ÓÉ“êÖðîa/ƒ“ßù²o“ ˆï£µWÓ…«ð~º‹©ÃzÀݧ>W:RH!ë]´wý?÷Si­ó®sc.x­5ª\.Gñ/‡çyh­ë†1æL-Ký¬4&M"CIEND®B`‚swami/src/swamigui/images/concave_pos_bi.png0000644000175000017500000000077410420662631021426 0ustar alessioalessio‰PNG  IHDRù‡yÕbKGDÿÿÿÿÿÿ X÷ܱIDATxÚÍ–=®‚P„ç¢Hl( ÆÂ†ÞÆ…\ âÜ€¥¥« îÁŠ‚-H´p .€ÆI`^aî}*àßi‰_fÎ ñåj« ’üF\!„К~°ã8Žã4Üè5`uàÕjµ*·bc’RJ)ëÜ1 Åy)Å×xôõEQY–e÷ÿõAÐ HÓ4€ét:-½éÑï÷û=Ijš¦‘d«Õj‘äét:}4ú$Ip]×Û¶mà\<°^¯×Ðét:O8ZýP(‡f³ÙŒŒ"Ã0 ’ìõz=’Bˆâìv»]’Ül6›ò÷)>q Z^+ýþñx<‹E†!0Æqç¿gÙÙ©8Öu]Ã0 `¹F#`·³,Ë*ÏÁ÷}ß÷ó¯á¨r@í–š¶mÛ¹³õ멚£SÁ­å¿Œ®þÊT“âk—‡ ¥”Ååßn·[Çã—œ¾›z:ŸÏç@Þsžçyï¼Ò-Ó-˲HR×uýÿ»öÂèMÓ4‹ó³úSO¹®¿f&“ÉäþƒîÕšª™§ËêéY½*úŽ~‡”£¿ Ÿ*Ó7GK°Ùý%IEND®B`‚swami/src/swamigui/images/convex_pos_uni.png0000644000175000017500000000077410420662631021513 0ustar alessioalessio‰PNG  IHDRù‡yÕbKGDÿÿÿÿÿÿ X÷ܱIDATxÚÍ–=nÂ@…¿ æ§¡AŠ%p$P¸‚„¸ç ãœÁ€·Ô‘@\‚Š2tȼÑ"ËŸWÙ#küí›Ý1 ñâòìƒ$½"®1Æo®ƒ ‚àÙ¸ÿ€Þ<™L&Íf³ P,‹Õjµ 0FÎ$:)ß÷}ß×jµZ-IJ§Ói»­$Éc$)ŸÏç%©R©T$i8³X¾;‚.‹Å>€Í[( ’Ôëõz—/×òyN³šÏçs€z½^ßw»Ý.@†áí¹t³ÙlFc?>N§µZ­v;à@m3l·Û-Àl6›ÝÐÊy<k0 V«Õ  Óét’<Ð9ÍÇq,I©T*µßÍ6žŒ,ߥï÷û}Ø•:Š¢ “ÉdwòGs¹\N’<Ïó’sð”£Î=úþ¾^¯×qÇív»ý0Ïwt<.—Ëeiw£Øƒý±Ž:A¿¾²ÙlVÚ5O2:uZ>óôxøøøX.—ËÝûçg©T*%_ã(úiV;æ9½~(¹¯£WøÉ:xJG¥5ÙÒÿ‚>È¥o/gG™…Mç]IEND®B`‚swami/src/swamigui/images/modenv_attack.png0000644000175000017500000000102510543044062021260 0ustar alessioalessio‰PNG  IHDRàw=øsBIT|dˆtEXtSoftwarewww.inkscape.org›î<§IDATH‰½V=KA}{·»*1‡oac#–V*&‚r»¹±09“ÈmnOcfn¾ÝaŒ1ÐZCk Ïó‚çÑæ ³3súñ$Ò°‰MþjÕ3ªz½aŒ‰4–Ïn­ÁOµŠSrÐZ#¥µv~1ª„ɤ”Hyž—(@ü§‚òú.jWw¡þ×‡ëø¢Ž.ñõ£”êȰ±uˆÜL­÷ð˜\pDÊ-¹”lï[“@~.&`mó¾_°€\ŒqÉ“™yK'cwôºÈµM‹¥StÚ¹±÷FˆÑ¦SÙäªh5£Å;– øhÊß-ZDlÓ"šÑþðÙ‡@úæ ¢Yd§íÓ”è9RòAw`n¢Ó¶c߯àíeÇžuDRÞ'?ì’×I”RÉWðsÉfü7—M7€÷9„R-¥Ô›‹ý$ÙÔFËÀvIEND®B`‚swami/src/swamigui/images/concave_neg_bi.png0000644000175000017500000000101710420662631021365 0ustar alessioalessio‰PNG  IHDRù‡yÕbKGDÿÿÿÿÿÿ X÷ÜÄIDATxÚÍ•±Šò@FÏÄAAlEHoio#láÄF›}ˆí|+ßB¬ba%ÖúvÚXl³X,(èÝfçß,ûÇ$wsšÉ„Ëpò ÷F€GÛ‘"ê*¥”Ràä}pAä/|CtµZ­¢k6Á Ëh4èšcŒ1&}}ÖïF¢µZ­p8¹'“™¢ãñx p¹\.ý~¿_HÑn·Ûp]טÏçs€Åb±(”¨e:NJ¥R  ×ëõ|ß÷öûýþ×|Ó4Åét:‰ˆ´Z­–ˆˆRJEW­µy{+—Ëe‘z½^ñ}ßY¯×ëìMhýÔwÑôcEëëõz…ççív»…§§ïÉ:Ÿwåºçóùüõþý]k­áå¥ÓétàõµZ­Vž†a†_?C¢÷Ž'{Ãáp½Çq‘Ýn·KN4Vô^’?p³Ùl¢ÂžçyñÕÖ/÷_h2ív» `Œ1ÇãñIMù¢–Éd2‰îG£Ñ¨¢Íf³ P©T*Ëår_­ÓúH<Ïó’«~Œ§{‰kvÌÄ3›ÍfÑý`0D“ÆÓãº>Ö/·D…MôŸè_ %ñÔ-0gÆ¿PVIEND®B`‚swami/src/swamigui/images/effect_control.png0000644000175000017500000000204010454447011021435 0ustar alessioalessio‰PNG  IHDRàw=øsBIT|dˆtEXtSoftwarewww.inkscape.org›î<²IDATH‰µ–Í‹EÆÕßãÌî`6™YffY dNbÀƒ.ä°.æ°ÁƒOæf.þ‘%ä  ’‹‡=xY¬Š‚AP’Sˆ‡7›³óÕÓÝõ¾f¦ÎfÓÐtUWÕûñ<ïSUFUy–7i¬¬¬$Žã˜§¶  ƒTU¢hfcccèMý÷Ï}x寬_åòW—Y\\DEDF¯ªæí›¿ßää;'¹tñÍfQáÌgì`00… <×CŒà¸NÞw12šcŒADò5Žãä_ÇuòyùøtGDF‘ªû‰|26ápz^!èåÏ.¼ºÞÙàí·xÿê¸ÆÁxý‹Ï¹ØHöë/$ÖÛŒªãr¼ÑâH¹22.ŠŠþŒHÞÏ,T«gK^ÐŽ|ÀuñÇD•Ldd¡çᎠbh-ƒ4¥7ÖL'Iè ãvÑÁ£òŸ2."T ×I5 ™"ªaDg8äá0f7âáU2k‹»i‰®ë n¯l±¶ÙÃóf0üøžÝŒß›aíI;­-ûˆGÑj¿¢qsƒãC€‰’&U0õAˆÍ»êç—øðî1Q¤‡gÎ^ Õîqñr3IN‹Í) ÷O^\¹¶Áý‡ó¼{oH°ò`ŸúìGýaá©8Ì- õÙ&­ö>J}FA€1Åæ™‚AÎaQ^Á (u(È7Q`À÷'W"Ñ8AšE' *Y$Ÿi Ÿ“¨¤8Ÿ3²ÀId›\µy‚±¼Œà÷ÏòŽÙeðgÇÞ0Ñ:¿~Ü*)õiú‡Ýôëi”vÿ•÷$zÕ›æTˆn·§¿RJ”R#æºnÁ7‰ÿ/ LLš9‹IEND®B`‚swami/src/swamigui/images/knob.svg0000644000175000017500000001753310774346067017440 0ustar alessioalessio image/svg+xml swami/src/swamigui/images/volenv.png0000644000175000017500000000103710543044062017755 0ustar alessioalessio‰PNG  IHDRàw=øsBIT|dˆtEXtSoftwarewww.inkscape.org›î<±IDATH‰Õ–AKTQÇo|÷ªX¹HAЕ W."¨DX`ŠÑÂoa_ ý…³šh'F‘ˆ‘‚H"¸²U¹PBZˆhŽãÜ7/½÷1×…>›Ñ™÷æIoÑ ‡s¸ÿî¹—ëXk-@c0Æ µ>Ï/®z½zuÀqÒˆl6K&‚TÄŒ1dŒ1©\×M „ÀÕZp³³‡–Ök‘¬-ósï{2@è`üÙknÝ}»éÃÜsÓ“ÉúŽü³NÄPŒM ŠŠù·/bRÊ¿OÁA¾B;2ôä9ÅÕ¥W;()8ÌÇ‹‡ñðñKTÑãËڛƅ|E7âà08ÉREpÊQ¡;Àj^¹<Œ¤ƒ\š%=Û;qÆóÚ- îI" 0óL6“é»vyý[ô8%”MÊ2X^‹!¾Ô×ùÜñµè;"êaæi"êœ<ïe»ö´ q_{ à$¹ÌÄW¢ˆü¾ý@ÄðÙGDsÃÓ¯Féºæë>Úï÷z}fÍ6c@2@„™‡m5fŽˆÑuVÉÏIs6=0…d5½ld)¯»‰A¢ ª¨ÈÀê¤êPÊ K¨ÈÀ*É[—ˆ³‚ ƒ’)BéA«’åà™$’m$ªÂ¶1ÙäI6&ÿ7Ã]÷ DDÃÂÌ}Þóx[Ôº}ƒ­wkÈ@€Õ©9¿ÉP°õ~Öù‘:q¬®Ü¤·¹HEþ,$©™s–Jx@ïÕ"«+·Š[É×Ï›,/Ì€à.¤ÅËà,è>‚öÓ3Wª<~ñm’œàìéSô6š4æ/î"O6c¨ÁÑëòÝ«ÔÎ?àþ³9ÁöÛ{Ô/W‹gy‹JaAïç›׫lw›| #¤RŠú´5\ü ô`Ä]Ÿ†Ý~6Û÷dŠ4yœ¨ã 2äCN† 2I¹q¸Æ£ÒÏÔCðçNÆœòu¢©L)R0f‹tAÖ"±ðû üfYÚüYZoÝ"Zß½±ÿpØMþ¸ž$÷°û—(½ ½ÐËîÜlMèt:.ûåREÑ1‹ãxÄwÿo ±F8ÃPIEND®B`‚swami/src/swamigui/images/switch_pos_bi.png0000644000175000017500000000057110420662631021304 0ustar alessioalessio‰PNG  IHDRù‡yÕbKGDÿÿÿÿÿÿ X÷Ü.IDATxÚÕ•1Žƒ0E¿WªÈâƒÊ¾A” p3¤„Ê'á (QJ$&ÅÊK²K‚ÇÚä5†æûiÐ|Dxs6öˆèu…Bà‹;Xk­µæfý-èI˜Ø8²,ˈˆ’$Iž9Ó4M‰ˆªªªó¬û§ßïÛ¶m ïûž/wã1GÇ1t]×¹§±OÔŸ/ê«fÖÞ'¾iÇ\Ǧišé}·Ëó<=ÇcŒ™ ÷¢J)¥Ôëõt:…aÞÖÏsÌÝgý&êÊùEQH)¥”€ëÖ{û…úâcDÿ(üº®k(Š¢€qÇåÀív†_”}¢—K”eYòå²-Ó\­ÙšY-¸TOkY[ksX?özâÆNôGô¿…–¸z ïã÷IEND®B`‚swami/src/swamigui/images/sample_viewer.png0000644000175000017500000000153410454447011021312 0ustar alessioalessio‰PNG  IHDRàw=øsBIT|dˆtEXtSoftwarewww.inkscape.org›î<îIDATH‰µ–=HaÇ—»K.‰B°XbÅ‚ j´iA:™¶vµ‹.g!³K§JÁÁIÁvð[¡â`j¡¢ ƒâ¤ˆÕ‚¡~åòu^s1¨å,õYîž÷ÿ{žÿûÞs'7 €aLÿ5I×áÅ‹ÛtwÑÞ~bY\’^b³’¸²bçËÉI§eñlX¬®ÚˆD”›¬­©D£òÍVW`gGƸ摰ذ(™”ØÛË-uÑÙy‹tú€ÍM…¦¦b"aG4*spK;oÓ›7…Œ¹YZ²[ 03ãddÄ äì¹? ä6:‘€åe!<7§°¿o£­í–¹g—>|pæ]³ÉÀi^++vt]àëWwñî›`°èrÀÖ–ÌúºüñÃÎÞžÍ<¢@<ðý»M3‡è:Ì̈¢Âa?j9Àû÷.Þ¾-0«~ü8NëdmM¥¤$̓‰3‹`qQ€»»ˆÇ%>Ö˜Ÿ×¸w/‰ª„BPèëó‹Ù¨¬L"Iƒƒ1êê¼LN:ÙØPihˆS\œÁá0ˆF³ƒ»wStt34TH(äA×%ººŽ1 ¨¨HÑÚ ¤…~ÓÓSÄ·ojkujkTV&˜žv’ÉHTU‰ öùÒD"2»»6¶·ÚÛyø0Û1­|þüÔÌ7-êê:¢¼<@c£ðúÙ3a@uµXà÷§ˆFe…ÿé¨*ù\wvǤ^_8DLsFTx *Ü” ·+¦9#€„b È«2$¹;ÑlÛ@×û´Ú>š®°m€cËÑê©O&“èH {{³ˆô¹¹îâûŠZ­ˆã‘_³ˆ"üš…ã±hX,É@¤Ñ¨P*w©UŸ8?ŸãìlŸ÷øä×Þ³iÀÆFä…fóN'Bã™~t7r8Ž…8N4¿|‹¦%û)€ÇGE© ƼN.§ó÷‡V^ˆãï«H<<øl•Sl櫓3Üß¿qyÕE„ÃÏ+H™ryµ$*ŠçÏ4“9詊ª(oAy0câºyiµKrQ_™Ä,ÚWÊ_1õgúK¼žª_ºÖIEND®B`‚swami/src/swamigui/images/linear_pos_uni.png0000644000175000017500000000047210420662631021456 0ustar alessioalessio‰PNG  IHDRù‡yÕbKGDÿÿÿÿÿÿ X÷ÜïIDATxÚÍÖ½ƒ0 àç\j–pÅ*>»€<PSºeö R*%üټʅŠïô\H@„›çÉ"¢;r•RJ)à±7èœsÎ¥æn@ç@9p]×5t]×íÓj¬µÖZHY–%7"¢ªªªåû@½÷~ dð÷$€cÌÈàíD„Î+fðo‰=VqèG„Î7x¬âÐ9ðÜ ×V,•©øB¨lŧ¡m«µÖòÀµ/Æ>5….¢èû¾²l†hš<Ïs‰ãdšBásæ% * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ /** * SECTION: SwamiguiPanelSF2GenEnv * @short_description: SoundFont envelope generator control panel * @see_also: * @stability: */ #ifndef __SWAMIGUI_PANEL_SF2_GEN_ENV_H__ #define __SWAMIGUI_PANEL_SF2_GEN_ENV_H__ #include #include typedef struct _SwamiguiPanelSF2GenEnv SwamiguiPanelSF2GenEnv; typedef struct _SwamiguiPanelSF2GenEnvClass SwamiguiPanelSF2GenEnvClass; #include #define SWAMIGUI_TYPE_PANEL_SF2_GEN_ENV (swamigui_panel_sf2_gen_env_get_type ()) #define SWAMIGUI_PANEL_SF2_GEN_ENV(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMIGUI_TYPE_PANEL_SF2_GEN_ENV, \ SwamiguiPanelSF2GenEnv)) #define SWAMIGUI_PANEL_SF2_GEN_ENV_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMIGUI_TYPE_PANEL_SF2_GEN_ENV, \ SwamiguiPanelSF2GenEnvClass)) #define SWAMIGUI_IS_PANEL_SF2_GEN_ENV(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMIGUI_TYPE_PANEL_SF2_GEN_ENV)) #define SWAMIGUI_IS_PANEL_SF2_GEN_ENV_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMIGUI_TYPE_PANEL_SF2_GEN_ENV)) struct _SwamiguiPanelSF2GenEnv { SwamiguiPanelSF2Gen parent_instance; }; struct _SwamiguiPanelSF2GenEnvClass { SwamiguiPanelSF2GenClass parent_class; }; GType swamigui_panel_sf2_gen_env_get_type (void); GtkWidget *swamigui_panel_sf2_gen_env_new (void); #endif swami/src/swamigui/SwamiguiPaste.c0000644000175000017500000002331611461334205017424 0ustar alessioalessio/* * SwamiguiPaste.c - Swami item paste object * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include "SwamiguiPaste.h" #include "SwamiguiRoot.h" /* for state history */ #include "i18n.h" static void swamigui_paste_class_init (SwamiguiPasteClass *klass); static void swamigui_paste_init (SwamiguiPaste *paste); static void swamigui_paste_finalize (GObject *obj); static GObjectClass *parent_class = NULL; GType swamigui_paste_get_type (void) { static GType obj_type = 0; if (!obj_type) { static const GTypeInfo obj_info = { sizeof (SwamiguiPasteClass), NULL, NULL, (GClassInitFunc) swamigui_paste_class_init, NULL, NULL, sizeof (SwamiguiPaste), 0, (GInstanceInitFunc) swamigui_paste_init }; obj_type = g_type_register_static (G_TYPE_OBJECT, "SwamiguiPaste", &obj_info, 0); } return (obj_type); } static void swamigui_paste_class_init (SwamiguiPasteClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); parent_class = g_type_class_peek_parent (klass); obj_class->finalize = swamigui_paste_finalize; } static void swamigui_paste_init (SwamiguiPaste *paste) { paste->status = SWAMIGUI_PASTE_NORMAL; paste->item_hash = g_hash_table_new_full (NULL, NULL, g_object_unref, /* key destroy func */ g_object_unref); /* value destroy func */ /* don't want paste objects to be saved for session */ swami_object_clear_flags (G_OBJECT (paste), SWAMI_OBJECT_SAVE); } static void swamigui_paste_finalize (GObject *obj) { SwamiguiPaste *paste = SWAMIGUI_PASTE (obj); if (paste->curitem) /* paste not finished? Then cancel it. */ { paste->status = SWAMIGUI_PASTE_CANCEL; swamigui_paste_process (paste); } if (paste->dstitem) g_object_unref (paste->dstitem); /* -- unref dest item */ if (paste->srcitems) /* -- unref source items */ { g_list_foreach (paste->srcitems, (GFunc)g_object_unref, NULL); g_list_free (paste->srcitems); } g_hash_table_destroy (paste->item_hash); /* clear conflict items to unref them */ swamigui_paste_set_conflict_items (paste, NULL, NULL); } /** * swamigui_paste_new: * * Create a new paste object. * * Returns: New paste object with a ref count of 1. */ SwamiguiPaste * swamigui_paste_new (void) { return (SWAMIGUI_PASTE (g_object_new (SWAMIGUI_TYPE_PASTE, NULL))); } /** * swamigui_paste_process: * @paste: Swami paste object * * Run the paste process. This function uses the IpatchPaste system to handle * paste operations. May need to be called multiple times to complete a paste * operation if decisions are required (conflict paste items, unhandled types, * or a cancel occurs). All paste status and parameters are stored in * the @paste object. This function also groups all state history actions * of the paste operation so it can be retracted if the paste is canceled. * * Returns: %TRUE if paste finished successfully, %FALSE if a decision is * required or an error occured. */ gboolean swamigui_paste_process (SwamiguiPaste *paste) { // IpatchItemIface *iface; gboolean retval = TRUE; g_return_val_if_fail (SWAMIGUI_IS_PASTE (paste), FALSE); g_return_val_if_fail (paste->dstitem != NULL, FALSE); g_return_val_if_fail (paste->srcitems != NULL, FALSE); g_return_val_if_fail (paste->status != SWAMIGUI_PASTE_ERROR, FALSE); /* skip unhandled types if requested */ if (paste->status == SWAMIGUI_PASTE_UNHANDLED && paste->decision == SWAMIGUI_PASTE_SKIP && paste->curitem) { paste->curitem = g_list_next (paste->curitem); paste->decision = SWAMIGUI_PASTE_NO_DECISION; } paste->status = SWAMIGUI_PASTE_NORMAL; /* set status to normal */ paste->decision_mask = SWAMIGUI_PASTE_SKIP | SWAMIGUI_PASTE_CHANGED | SWAMIGUI_PASTE_REPLACE; /* set decision mask to all */ // retval = ((*iface->paste)(paste->dstitem, paste)); paste->decision = SWAMIGUI_PASTE_NO_DECISION; /* clear previous decision */ return (retval); } /** * swamigui_paste_set_items: * @paste: Swami paste object * @dstitem: Destination item of paste operation * @srcitems: A list of source #IpatchItem objects * * A function to set the destination item and source item(s) of a * paste operation. This function can only be called once on a paste * object. */ void swamigui_paste_set_items (SwamiguiPaste *paste, IpatchItem *dstitem, GList *srcitems) { // IpatchItemIface *dstitem_iface; g_return_if_fail (SWAMIGUI_IS_PASTE (paste)); g_return_if_fail (IPATCH_IS_ITEM (dstitem)); g_return_if_fail (srcitems != NULL); g_return_if_fail (paste->dstitem == NULL); g_return_if_fail (paste->srcitems == NULL); /* make sure we have a paste method for the destination item */ // dstitem_iface = IPATCH_ITEM_GET_IFACE (dstitem); // g_return_if_fail (dstitem_iface->paste != NULL); g_object_ref (dstitem); /* ++ ref destination item */ paste->dstitem = dstitem; /* copy and reference source item list */ paste->srcitems = g_list_copy (srcitems); g_list_foreach (paste->srcitems, (GFunc)g_object_ref, NULL); /* ++ ref */ paste->curitem = paste->srcitems; /* set current item to first source item */ } /** * swamigui_paste_get_conflict_items: * @paste: Swami paste object * @src: Location to store a pointer to the source conflict * item (item's refcount is incremented) or %NULL * @dest: Location to store a pointer to the conflict destination * item (item's refcount is incremented) or %NULL * * Get conflict items from a @paste object (paste status should be * #SWAMIGUI_PASTE_CONFLICT or these will be %NULL). The returned * items' reference counts are incremented and the caller is * responsible for unrefing them with g_object_unref when finished using * them. */ void swamigui_paste_get_conflict_items (SwamiguiPaste *paste, IpatchItem **src, IpatchItem **dest) { g_return_if_fail (SWAMIGUI_IS_PASTE (paste)); if (src) { /* ++ ref returned src item */ if (paste->conflict_src) g_object_ref (paste->conflict_src); *src = paste->conflict_src; } if (dest) { /* ++ ref returned dest item */ if (paste->conflict_dst) g_object_ref (paste->conflict_dst); *dest = paste->conflict_dst; } } /** * swamigui_paste_set_conflict_items: * @paste: Swami paste object * @src: Source conflict item or %NULL * @dest: Destination conflict item or %NULL * * Set conflict items in a paste object. This function will cause the paste * object's status to be set to #SWAMIGUI_PASTE_CONFLICT if @src and * @dest are not %NULL, otherwise it will be set to * #SWAMIGUI_PASTE_NORMAL status and the conflict items will be cleared. */ void swamigui_paste_set_conflict_items (SwamiguiPaste *paste, IpatchItem *src, IpatchItem *dest) { g_return_if_fail (SWAMIGUI_IS_PASTE (paste)); g_return_if_fail (!src || IPATCH_IS_ITEM (src)); g_return_if_fail (!dest || IPATCH_IS_ITEM (dest)); /* unref old items if set */ if (paste->conflict_src) g_object_unref (paste->conflict_src); if (paste->conflict_dst) g_object_unref (paste->conflict_dst); if (src && dest) { paste->status = SWAMIGUI_PASTE_CONFLICT; g_object_ref (src); /* ++ ref new src conflict item */ g_object_ref (dest); /* ++ ref new dest conflict item */ } else paste->status = SWAMIGUI_PASTE_NORMAL; paste->conflict_src = src; paste->conflict_dst = dest; } /** * swamigui_paste_push_state: * @paste: Swami paste object * @state: #IpatchItem "paste" method defined state data * * This function is used by #IpatchItem interface "paste" methods to * store variable state data to be able to resume a paste operation (after * a decision is made on a conflict, etc). The @paste object stores a stack * of state data so a chain of functions can be resumed at a later time. * The methods are responsible for creating and destroying this state data * and the function chain will be resumed even on a cancel operation so this * can be accomplished properly. */ void swamigui_paste_push_state (SwamiguiPaste *paste, gpointer state) { g_return_if_fail (SWAMIGUI_IS_PASTE (paste)); g_return_if_fail (state != NULL); paste->states = g_list_prepend (paste->states, state); } /** * swamigui_paste_pop_state: * @paste: Swami paste object * * This function is used by #IpatchItem interface "paste" methods to * retrieve the next variable state data, stored by * swamigui_paste_push_state(), to be able to resume a paste * operation. The chain of functions storing state data should call * this function in the reverse order in which the states were * pushed. The state pointer is removed from the stack after this * call. * * Returns: Pointer to state data which was on the top of the stack. */ gpointer swamigui_paste_pop_state (SwamiguiPaste *paste) { gpointer state; g_return_val_if_fail (SWAMIGUI_IS_PASTE (paste), NULL); g_return_val_if_fail (paste->states != NULL, NULL); state = paste->states->data; paste->states = g_list_delete_link (paste->states, paste->states); return (state); } swami/src/swamigui/SwamiguiControlMidiKey.h0000644000175000017500000000627311461334205021254 0ustar alessioalessio/* * SwamiguiControlMidiKey.h - Header for MIDI keyboard control * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_CONTROL_MIDI_KEY_H__ #define __SWAMIGUI_CONTROL_MIDI_KEY_H__ #include #include typedef struct _SwamiguiControlMidiKey SwamiguiControlMidiKey; typedef struct _SwamiguiControlMidiKeyClass SwamiguiControlMidiKeyClass; #define SWAMIGUI_TYPE_CONTROL_MIDI_KEY (swamigui_control_midi_key_get_type ()) #define SWAMIGUI_CONTROL_MIDI_KEY(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMIGUI_TYPE_CONTROL_MIDI_KEY, \ SwamiguiControlMidiKey)) #define SWAMIGUI_CONTROL_MIDI_KEY_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMIGUI_TYPE_CONTROL_MIDI_KEY, \ SwamiguiControlMidiKeyClass)) #define SWAMIGUI_IS_CONTROL_MIDI_KEY(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMIGUI_TYPE_CONTROL_MIDI_KEY)) #define SWAMIGUI_IS_CONTROL_MIDI_KEY_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMIGUI_TYPE_CONTROL_MIDI_KEY)) /* MIDI keyboard control object */ struct _SwamiguiControlMidiKey { SwamiControlMidi parent_instance; /* derived from SwamiControlMidi */ guint snooper_id; /* key snooper handler ID */ GArray *lower_keys; /* array of lower keys (see MidiKey in .c) */ GArray *upper_keys; /* array of upper keys (see MidiKey in .c) */ gint8 lower_octave; /* lower octave (-2 - 8) */ gint8 upper_octave; /* upper octave (-2 - 8) */ gboolean join_octaves; /* if TRUE then setting lower_octave sets upper_octave + 1 */ guint8 lower_velocity; /* lower MIDI velocity */ guint8 upper_velocity; /* upper MIDI velocity */ gboolean same_velocity; /* if TRUE then setting lower_velocity sets upper_velocity */ guint8 lower_channel; /* lower MIDI channel */ guint8 upper_channel; /* upper MIDI channel */ }; /* MIDI keyboard control class */ struct _SwamiguiControlMidiKeyClass { SwamiControlMidiClass parent_class; }; GType swamigui_control_midi_key_get_type (void); SwamiguiControlMidiKey *swamigui_control_midi_key_new (void); void swamigui_control_midi_key_press (SwamiguiControlMidiKey *keyctrl, guint key); void swamigui_control_midi_key_release (SwamiguiControlMidiKey *keyctrl, guint key); void swamigui_control_midi_key_set_lower (SwamiguiControlMidiKey *keyctrl, const guint *keys, guint count); void swamigui_control_midi_key_set_upper (SwamiguiControlMidiKey *keyctrl, const guint *keys, guint count); #endif swami/src/swamigui/patch_funcs.h0000644000175000017500000000330111461334205017134 0ustar alessioalessio/* * patch_funcs.h - General instrument patch functions header * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __PATCH_FUNCS_H__ #define __PATCH_FUNCS_H__ #include #include #include #include #include "SwamiguiRoot.h" #include "SwamiguiTree.h" void swamigui_load_files (SwamiguiRoot *root); void swamigui_save_files (IpatchList *item_list, gboolean saveas); void swamigui_close_files (IpatchList *item_list); void swamigui_delete_items (IpatchList *item_list); void swamigui_wtbl_load_patch (IpatchItem *item); void swamigui_new_item (IpatchItem *parent_hint, GType type); void swamigui_goto_link_item (IpatchItem *item, SwamiguiTree *tree); void swamigui_load_samples (IpatchItem *parent_hint); void swamigui_export_samples (IpatchList *samples); void swamigui_copy_items (IpatchList *items); void swamigui_paste_items (IpatchItem *dstitem, GList *items); #endif swami/src/swamigui/SwamiguiControlAdj.c0000644000175000017500000002334411704446464020423 0ustar alessioalessio/* * SwamiguiControlAdj.c - GtkAdjustment control object * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include "SwamiguiControlAdj.h" #include "SwamiguiRoot.h" static void swamigui_control_adj_class_init (SwamiguiControlAdjClass *klass); static void swamigui_control_adj_init (SwamiguiControlAdj *ctrladj); static void swamigui_control_adj_finalize (GObject *object); static GParamSpec *control_adj_get_spec_method (SwamiControl *control); static gboolean control_adj_set_spec_method (SwamiControl *control, GParamSpec *pspec); static void control_adj_get_value_method (SwamiControl *control, GValue *value); static void control_adj_set_value_method (SwamiControl *control, SwamiControlEvent *event, const GValue *value); static void swamigui_control_adj_cb_value_changed (GtkAdjustment *adj, SwamiguiControlAdj *ctrladj); static void swamigui_adj_cb_destroy (GtkObject *object, gpointer user_data); static GObjectClass *parent_class = NULL; GType swamigui_control_adj_get_type (void) { static GType otype = 0; if (!otype) { static const GTypeInfo type_info = { sizeof (SwamiguiControlAdjClass), NULL, NULL, (GClassInitFunc) swamigui_control_adj_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SwamiguiControlAdj), 0, (GInstanceInitFunc) swamigui_control_adj_init }; otype = g_type_register_static (SWAMI_TYPE_CONTROL, "SwamiguiControlAdj", &type_info, 0); } return (otype); } static void swamigui_control_adj_class_init (SwamiguiControlAdjClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); SwamiControlClass *control_class = SWAMI_CONTROL_CLASS (klass); parent_class = g_type_class_peek_parent (klass); obj_class->finalize = swamigui_control_adj_finalize; control_class->get_spec = control_adj_get_spec_method; control_class->set_spec = control_adj_set_spec_method; control_class->get_value = control_adj_get_value_method; control_class->set_value = control_adj_set_value_method; } static void swamigui_control_adj_init (SwamiguiControlAdj *ctrladj) { SwamiControl *control = SWAMI_CONTROL (ctrladj); swami_control_set_queue (control, swamigui_root->ctrl_queue); swami_control_set_flags (control, SWAMI_CONTROL_SENDRECV | SWAMI_CONTROL_VALUE); swami_control_set_value_type (control, G_TYPE_DOUBLE); ctrladj->adj = NULL; } static void swamigui_control_adj_finalize (GObject *object) { SwamiguiControlAdj *ctrladj = SWAMIGUI_CONTROL_ADJ (object); SWAMI_LOCK_WRITE (ctrladj); if (ctrladj->adj) { g_signal_handler_disconnect (ctrladj->adj, ctrladj->value_change_id); g_signal_handlers_disconnect_by_func (ctrladj->adj, swamigui_adj_cb_destroy, ctrladj); g_object_unref (ctrladj->adj); } if (ctrladj->pspec) g_param_spec_unref (ctrladj->pspec); SWAMI_UNLOCK_WRITE (ctrladj); if (parent_class->finalize) parent_class->finalize (object); } /* control is locked by caller */ static GParamSpec * control_adj_get_spec_method (SwamiControl *control) { SwamiguiControlAdj *ctrladj = SWAMIGUI_CONTROL_ADJ (control); return (ctrladj->pspec); } /* control is locked by caller */ static gboolean control_adj_set_spec_method (SwamiControl *control, GParamSpec *pspec) { SwamiguiControlAdj *ctrladj = SWAMIGUI_CONTROL_ADJ (control); GParamSpecDouble *pspec_dbl; if (ctrladj->pspec) g_param_spec_unref (ctrladj->pspec); ctrladj->pspec = g_param_spec_ref (pspec); g_param_spec_sink (pspec); /* take ownership of the parameter spec */ if (ctrladj->adj) { pspec_dbl = G_PARAM_SPEC_DOUBLE (pspec); ctrladj->adj->lower = pspec_dbl->minimum; ctrladj->adj->upper = pspec_dbl->maximum; gtk_adjustment_changed (ctrladj->adj); } return (TRUE); } /* control is NOT locked */ static void control_adj_get_value_method (SwamiControl *control, GValue *value) { SwamiguiControlAdj *ctrladj = SWAMIGUI_CONTROL_ADJ (control); SWAMI_LOCK_READ (ctrladj); if (!ctrladj->adj) { SWAMI_UNLOCK_READ (ctrladj); return; } g_value_set_double (value, ctrladj->adj->value); SWAMI_UNLOCK_READ (ctrladj); } static void control_adj_set_value_method (SwamiControl *control, SwamiControlEvent *event, const GValue *value) { SwamiguiControlAdj *ctrladj = SWAMIGUI_CONTROL_ADJ (control); GtkAdjustment *adj; guint value_change_id; double d; /* reference the adjustment under lock, to minimize lock time and prevent possible deadlocks with gtk_adjustment_value_changed callbacks */ SWAMI_LOCK_READ (ctrladj); adj = ctrladj->adj; if (adj) g_object_ref (adj); /* ++ ref adjustment */ value_change_id = ctrladj->value_change_id; SWAMI_UNLOCK_READ (ctrladj); if (!adj) { g_object_unref (adj); /* -- unref adjustment */ return; } d = g_value_get_double (value); if (adj->value != d) /* value is different? */ { /* block handler to avoid value set/notify loop */ g_signal_handler_block (adj, value_change_id); adj->value = g_value_get_double (value); gtk_adjustment_value_changed (adj); g_signal_handler_unblock (adj, value_change_id); } g_object_unref (adj); /* -- unref adjustment */ } /** * swamigui_control_adj_new: * @adj: GtkAdjustment to use as a control or %NULL to set later * * Create a new GtkAdjustment control object. * * Returns: New GtkAdjustment control with a refcount of 1 which the caller * owns. */ SwamiguiControlAdj * swamigui_control_adj_new (GtkAdjustment *adj) { SwamiguiControlAdj *ctrladj; ctrladj = g_object_new (SWAMIGUI_TYPE_CONTROL_ADJ, NULL); if (adj) swamigui_control_adj_set (ctrladj, adj); return (ctrladj); } /** * swamigui_control_adj_set: * @ctrladj: Swami GtkAdjustment control object * @adj: GtkAdjustment to assign to @ctrladj * * Set the GtkAdjustment of a adjustment control. */ void swamigui_control_adj_set (SwamiguiControlAdj *ctrladj, GtkAdjustment *adj) { GParamSpec *pspec; g_return_if_fail (SWAMIGUI_IS_CONTROL_ADJ (ctrladj)); g_return_if_fail (GTK_IS_ADJUSTMENT (adj)); /* ++ ref new spec */ pspec = g_param_spec_double ("value", NULL, NULL, adj->lower, adj->upper, adj->value, G_PARAM_READWRITE); SWAMI_LOCK_WRITE (ctrladj); if (ctrladj->adj) { /* disconnect value change and destroy handlers */ g_signal_handler_disconnect (ctrladj->adj, ctrladj->value_change_id); g_signal_handlers_disconnect_by_func (ctrladj->adj, swamigui_adj_cb_destroy, ctrladj); g_object_unref (ctrladj->adj); /* -- unref old adjustment */ } if (ctrladj->pspec) g_param_spec_unref (ctrladj->pspec); ctrladj->adj = g_object_ref (adj); /* ++ ref new adjustment */ ctrladj->pspec = pspec; /* we take over creator's ref */ /* connect signal to adjustment change signals */ ctrladj->value_change_id = g_signal_connect (adj, "value-changed", G_CALLBACK (swamigui_control_adj_cb_value_changed), ctrladj); /* connect to the adjustment's destroy signal */ g_signal_connect (adj, "destroy", G_CALLBACK (swamigui_adj_cb_destroy), ctrladj); SWAMI_UNLOCK_WRITE (ctrladj); } /** * swamigui_control_adj_block_changes: * @ctrladj: Swami GtkAdjustment control object * * Stop GtkAdjustment change signals from sending control events. */ void swamigui_control_adj_block_changes (SwamiguiControlAdj *ctrladj) { g_return_if_fail (SWAMIGUI_IS_CONTROL_ADJ (ctrladj)); SWAMI_LOCK_READ (ctrladj); if (ctrladj->adj) g_signal_handler_block (ctrladj->adj, ctrladj->value_change_id); SWAMI_UNLOCK_READ (ctrladj); } /** * swamigui_control_adj_block_changes: * @ctrladj: Swami GtkAdjustment control object * * Unblock a previous call to swamigui_control_adj_block_changes(). */ void swamigui_control_adj_unblock_changes (SwamiguiControlAdj *ctrladj) { g_return_if_fail (SWAMIGUI_IS_CONTROL_ADJ (ctrladj)); SWAMI_LOCK_READ (ctrladj); if (ctrladj->adj) g_signal_handler_unblock (ctrladj->adj, ctrladj->value_change_id); SWAMI_UNLOCK_READ (ctrladj); } /* adjustment value changed signal callback */ static void swamigui_control_adj_cb_value_changed (GtkAdjustment *adj, SwamiguiControlAdj *ctrladj) { GValue value = { 0 }; g_value_init (&value, G_TYPE_DOUBLE); g_value_set_double (&value, adj->value); swami_control_transmit_value ((SwamiControl *)ctrladj, &value); g_value_unset (&value); } /* GtkAdjustment destroy callback - releases reference */ static void swamigui_adj_cb_destroy (GtkObject *object, gpointer user_data) { SwamiguiControlAdj *ctrladj = SWAMIGUI_CONTROL_ADJ (user_data); SWAMI_LOCK_WRITE (ctrladj); if (ctrladj->adj) { /* disconnect value change and destroy handlers */ g_signal_handler_disconnect (ctrladj->adj, ctrladj->value_change_id); g_signal_handlers_disconnect_by_func (ctrladj->adj, swamigui_adj_cb_destroy, ctrladj); g_object_unref (ctrladj->adj); /* -- unref old adjustment */ } if (ctrladj->pspec) { g_param_spec_unref (ctrladj->pspec); ctrladj->pspec = NULL; } SWAMI_UNLOCK_WRITE (ctrladj); } swami/src/swamigui/SwamiguiRoot.c0000644000175000017500000014274011704446464017311 0ustar alessioalessio/* * SwamiguiRoot.c - Swami main GUI object * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include "swamigui.h" #include "i18n.h" #include "../libswami/swami_priv.h" enum { PROP_0, PROP_MAIN_WINDOW, PROP_UPDATE_INTERVAL, PROP_QUIT_CONFIRM, PROP_SPLASH_ENABLE, PROP_SPLASH_DELAY, PROP_TIPS_ENABLE, PROP_TIPS_POSITION, PROP_PIANO_LOWER_KEYS, PROP_PIANO_UPPER_KEYS, PROP_DEFAULT_PATCH_TYPE, PROP_TREE_STORE_LIST, PROP_SELECTION_ORIGIN, PROP_SELECTION, PROP_SELECTION_SINGLE, PROP_SOLO_ITEM_ENABLE }; enum { QUIT, LAST_SIGNAL }; /* Default splash delay in milliseconds */ #define SWAMIGUI_ROOT_DEFAULT_SPLASH_DELAY 5000 #define SWAMIGUI_ROOT_DEFAULT_LOWER_KEYS "z,s,x,d,c,v,g,b,h,n,j,m,comma,l,period,semicolon,slash" #define SWAMIGUI_ROOT_DEFAULT_UPPER_KEYS "q,2,w,3,e,r,5,t,6,y,7,u,i,9,o,0,p,bracketleft,equal,bracketright" /* external private global prototypes */ void _swamigui_ifaces_init (void); /* ifaces/ifaces.c */ void _swamigui_stock_icons_init (void); /* icons.c */ void _swamigui_control_init (void); /* SwamiguiControl.c */ void _swamigui_control_widgets_init (void); /* SwamiguiControl_widgets.c */ void _swamigui_item_menu_init (void); void _swamigui_item_menu_actions_init (void); /* SwamiguiItemMenu_actions.c */ #ifdef PYTHON_SUPPORT void _swamigui_python_init (int argc, char **argv); /* in swami_python.c */ #endif /* Local Prototypes */ static void swamigui_root_class_init (SwamiguiRootClass *klass); static void swamigui_root_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void swamigui_root_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void swamigui_root_quit_method (SwamiguiRoot *root); static void swamigui_root_init (SwamiguiRoot *obj); static void swamigui_root_finalize (GObject *object); static gboolean swamigui_queue_test_func (SwamiControlQueue *queue, SwamiControl *control, SwamiControlEvent *event); static gboolean swamigui_update_gui_timeout (gpointer data); static void ctrl_prop_set_func (SwamiControl *control, SwamiControlEvent *event, const GValue *value); static void ctrl_add_set_func (SwamiControl *control, SwamiControlEvent *event, const GValue *value); static void ctrl_remove_set_func (SwamiControl *control, SwamiControlEvent *event, const GValue *value); static void swamigui_cb_quit_response (GtkDialog *dialog, int response, gpointer user_data); static void swamigui_real_quit (SwamiguiRoot *root); static void swamigui_root_create_main_window (SwamiguiRoot *root); static void swamigui_root_cb_solo_item (SwamiguiRoot *root, GParamSpec *pspec, gpointer user_data); static void swamigui_root_update_solo_item (SwamiguiRoot *root, GObject *solo_item); static void swamigui_root_connect_midi_keyboard_controls (SwamiguiRoot *root, GObject *midikey); static gint swamigui_root_cb_main_window_delete (GtkWidget *widget, GdkEvent *event, gpointer data); static guint *swamigui_root_parse_piano_keys (const char *str); static char *swamigui_root_encode_piano_keys (const guint *keyvals); static GtkWidget *sf2_prop_handler (GtkWidget *widg, GObject *obj); static void current_date_btn_clicked (GtkButton *button, gpointer user_data); static guint uiroot_signals[LAST_SIGNAL] = { 0 }; SwamiguiRoot *swamigui_root = NULL; SwamiRoot *swami_root = NULL; /* global enable bools, kind of hackish, but what is better? */ gboolean swamigui_disable_python = TRUE; gboolean swamigui_disable_plugins = FALSE; static GObjectClass *parent_class = NULL; /* used to determine if current thread is the GUI thread */ static GStaticPrivate is_gui_thread = G_STATIC_PRIVATE_INIT; /** * swamigui_init: * @argc: Number of arguments from main() * @argv: Command line arguments from main() * * Function to initialize Swami User Interface. Should be called before any * other Swamigui related functions. This function calls swami_init() as well. */ void swamigui_init (int *argc, char **argv[]) { static gboolean initialized = FALSE; if (initialized) return; initialized = TRUE; /* initialize glib thread support (if it hasn't been already!) */ if (!g_thread_supported ()) g_thread_init (NULL); gtk_set_locale (); gtk_init_check (argc, argv); /* initialize GTK */ /* set the application/program name, so things work right with recent file chooser * even when binary name is different (such as lt-swami) */ g_set_application_name ("swami"); swami_init (); /* install icon parameter property (for assigning icons to effect controls) */ ipatch_param_install_property (g_param_spec_string ("icon", "Icon", "Icon", NULL, G_PARAM_READWRITE)); /* install icon property for types (for assigning icons to object types) */ ipatch_type_install_property (g_param_spec_string ("icon", "Icon", "Icon", NULL, G_PARAM_READWRITE)); /* set type specific icons */ ipatch_type_set (IPATCH_TYPE_DLS2, "icon", SWAMIGUI_STOCK_DLS, NULL); ipatch_type_set (IPATCH_TYPE_GIG, "icon", SWAMIGUI_STOCK_GIG, NULL); ipatch_type_set (IPATCH_TYPE_SF2, "icon", SWAMIGUI_STOCK_SOUNDFONT, NULL); swamigui_util_init (); _swamigui_stock_icons_init (); _swamigui_control_init (); _swamigui_control_widgets_init (); _swamigui_item_menu_init (); /* initialize Swamigui types */ swamigui_bar_get_type (); swamigui_bar_ptr_get_type (); swamigui_bar_ptr_type_get_type (); swamigui_control_adj_get_type (); swamigui_control_flags_get_type (); swamigui_control_midi_key_get_type (); swamigui_control_object_flags_get_type (); swamigui_control_rank_get_type (); swamigui_item_menu_flags_get_type (); swamigui_item_menu_get_type (); swamigui_knob_get_type (); swamigui_menu_get_type (); swamigui_mod_edit_get_type (); swamigui_panel_get_type (); swamigui_panel_selector_get_type (); swamigui_panel_sf2_gen_get_type (); swamigui_paste_decision_get_type (); swamigui_paste_get_type (); swamigui_paste_status_get_type (); swamigui_piano_get_type (); swamigui_pref_get_type (); swamigui_prop_get_type (); swamigui_quit_confirm_get_type (); swamigui_root_get_type (); swamigui_sample_canvas_get_type (); swamigui_sample_editor_get_type (); swamigui_sample_editor_marker_flags_get_type (); swamigui_sample_editor_marker_id_get_type (); swamigui_sample_editor_status_get_type (); swamigui_spectrum_canvas_get_type (); swamigui_spin_scale_get_type (); swamigui_splits_get_type (); swamigui_splits_mode_get_type (); swamigui_splits_status_get_type (); swamigui_statusbar_get_type (); swamigui_statusbar_pos_get_type (); swamigui_tree_get_type (); swamigui_tree_store_get_type (); swamigui_tree_store_patch_get_type (); swamigui_util_unit_rgba_color_get_type (); _swamigui_item_menu_actions_init (); /* Register panel types and their order */ swamigui_register_panel_selector_type (SWAMIGUI_TYPE_PROP, 80); swamigui_register_panel_selector_type (SWAMIGUI_TYPE_SAMPLE_EDITOR, 90); swamigui_register_panel_selector_type (SWAMIGUI_TYPE_PANEL_SF2_GEN_MISC, 100); swamigui_register_panel_selector_type (SWAMIGUI_TYPE_PANEL_SF2_GEN_ENV, 105); swamigui_register_panel_selector_type (SWAMIGUI_TYPE_MOD_EDIT, 110); /* Register prop widget types */ swamigui_register_prop_handler (IPATCH_TYPE_SF2, sf2_prop_handler); swamigui_register_prop_glade_widg (IPATCH_TYPE_SF2_PRESET, "PropSF2Preset"); swamigui_register_prop_glade_widg (IPATCH_TYPE_SF2_INST, "PropSF2Inst"); swamigui_register_prop_glade_widg (IPATCH_TYPE_SF2_IZONE, "PropSF2IZone"); swamigui_register_prop_glade_widg (IPATCH_TYPE_SF2_SAMPLE, "PropSF2Sample"); #ifdef PYTHON_SUPPORT if (!swamigui_disable_python) { _swamigui_python_init (*argc, *argv); swamigui_python_view_get_type (); } #endif if (!swamigui_disable_plugins) swami_plugin_load_all (); /* load plugins */ } /* Function used by libglade to initialize libswamigui widgets */ void glade_module_register_widgets (void) { swamigui_init (0, NULL); } GType swamigui_root_get_type (void) { static GType item_type = 0; if (!item_type) { static const GTypeInfo item_info = { sizeof (SwamiguiRootClass), NULL, NULL, (GClassInitFunc) swamigui_root_class_init, NULL, NULL, sizeof (SwamiguiRoot), 0, (GInstanceInitFunc) swamigui_root_init, }; item_type = g_type_register_static (SWAMI_TYPE_ROOT, "SwamiguiRoot", &item_info, 0); } return (item_type); } static void swamigui_root_class_init (SwamiguiRootClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); parent_class = g_type_class_peek_parent (klass); obj_class->set_property = swamigui_root_set_property; obj_class->get_property = swamigui_root_get_property; obj_class->finalize = swamigui_root_finalize; klass->quit = swamigui_root_quit_method; uiroot_signals[QUIT] = g_signal_new ("quit", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (SwamiguiRootClass, quit), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); g_object_class_install_property (obj_class, PROP_MAIN_WINDOW, g_param_spec_object ("main-window", _("Main window"), _("Main window"), GTK_TYPE_WIDGET, G_PARAM_READABLE | IPATCH_PARAM_NO_SAVE)); g_object_class_install_property (obj_class, PROP_UPDATE_INTERVAL, g_param_spec_int ("update-interval", _("Update interval"), _("GUI update interval in milliseconds"), 10, 1000, 100, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_QUIT_CONFIRM, g_param_spec_enum ("quit-confirm", _("Quit confirm"), _("Quit confirmation method"), SWAMIGUI_TYPE_QUIT_CONFIRM, SWAMIGUI_QUIT_CONFIRM_UNSAVED, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_SPLASH_ENABLE, g_param_spec_boolean ("splash-enable", _("Splash image enable"), _("Show splash on startup"), TRUE, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_SPLASH_DELAY, g_param_spec_uint ("splash-delay", _("Splash delay"), _("Splash delay in milliseconds (0 to wait for button click)"), 0, G_MAXUINT, SWAMIGUI_ROOT_DEFAULT_SPLASH_DELAY, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_TIPS_ENABLE, g_param_spec_boolean ("tips-enable", _("Tips enable"), _("Show tips on startup"), TRUE, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_TIPS_POSITION, g_param_spec_int ("tips-position", "Tips position", "Tips position", 0, 255, 0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_PIANO_LOWER_KEYS, g_param_spec_string ("piano-lower-keys", "Piano lower keys", "Comma delimited list of GDK key names", SWAMIGUI_ROOT_DEFAULT_LOWER_KEYS, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_PIANO_UPPER_KEYS, g_param_spec_string ("piano-upper-keys", "Piano upper keys", "Comma delimited list of GDK key names", SWAMIGUI_ROOT_DEFAULT_UPPER_KEYS, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_DEFAULT_PATCH_TYPE, g_param_spec_gtype ("default-patch-type", "Default patch type", "Default patch type", IPATCH_TYPE_BASE, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_TREE_STORE_LIST, g_param_spec_object ("tree-store-list", "Tree store list", "List of tree stores", IPATCH_TYPE_LIST, G_PARAM_READABLE | IPATCH_PARAM_NO_SAVE)); g_object_class_install_property (obj_class, PROP_SELECTION_ORIGIN, g_param_spec_object ("selection-origin", "Selection origin", "Origin of selection", G_TYPE_OBJECT, G_PARAM_READABLE | IPATCH_PARAM_NO_SAVE)); g_object_class_install_property (obj_class, PROP_SELECTION, g_param_spec_object ("selection", "Item selection", "Last item selection", IPATCH_TYPE_LIST, G_PARAM_READWRITE | IPATCH_PARAM_NO_SAVE)); g_object_class_install_property (obj_class, PROP_SELECTION_SINGLE, g_param_spec_object ("selection-single", "Single item selection", "Last single selected item", G_TYPE_OBJECT, G_PARAM_READWRITE | IPATCH_PARAM_NO_SAVE)); g_object_class_install_property (obj_class, PROP_SOLO_ITEM_ENABLE, g_param_spec_boolean ("solo-item-enable", "Solo item enable", "Enable solo audition of active instrument", FALSE, G_PARAM_READWRITE | IPATCH_PARAM_NO_SAVE)); } static void swamigui_root_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { SwamiguiRoot *root = SWAMIGUI_ROOT (object); IpatchList *list; GObject *obj = NULL; int ival; switch (property_id) { case PROP_UPDATE_INTERVAL: ival = g_value_get_int (value); if (ival != root->update_interval) { root->update_interval = ival; /* remove old timeout and install new one */ if (root->update_timeout_id) g_source_remove (root->update_timeout_id); root->update_timeout_id = g_timeout_add (root->update_interval, (GSourceFunc)swamigui_update_gui_timeout, root); } break; case PROP_QUIT_CONFIRM: root->quit_confirm = g_value_get_enum (value); break; case PROP_SPLASH_ENABLE: root->splash_enable = g_value_get_boolean (value); break; case PROP_SPLASH_DELAY: root->splash_delay = g_value_get_uint (value); break; case PROP_TIPS_ENABLE: root->tips_enable = g_value_get_boolean (value); break; case PROP_TIPS_POSITION: root->tips_position = g_value_get_int (value); break; case PROP_PIANO_LOWER_KEYS: g_free (root->piano_lower_keys); root->piano_lower_keys = swamigui_root_parse_piano_keys (g_value_get_string (value)); break; case PROP_PIANO_UPPER_KEYS: g_free (root->piano_upper_keys); root->piano_upper_keys = swamigui_root_parse_piano_keys (g_value_get_string (value)); break; case PROP_DEFAULT_PATCH_TYPE: root->default_patch_type = g_value_get_gtype (value); break; case PROP_TREE_STORE_LIST: if (root->tree_stores) g_object_unref (root->tree_stores); root->tree_stores = IPATCH_LIST (g_value_dup_object (value)); break; case PROP_SELECTION: if (root->selection) g_object_unref (root->selection); obj = g_value_dup_object (value); if (obj) root->selection = IPATCH_LIST (obj); else root->selection = NULL; g_object_notify (G_OBJECT (root), "selection-single"); break; case PROP_SELECTION_SINGLE: if (root->selection) g_object_unref (root->selection); obj = g_value_dup_object (value); if (obj) { list = ipatch_list_new (); list->items = g_list_append (list->items, obj); root->selection = list; } else root->selection = NULL; g_object_notify (G_OBJECT (root), "selection"); break; case PROP_SOLO_ITEM_ENABLE: if (root->solo_item_enabled != g_value_get_boolean (value)) { root->solo_item_enabled = !root->solo_item_enabled; if (root->solo_item_enabled && root->selection && root->selection->items && !root->selection->items->next) obj = root->selection->items->data; swamigui_root_update_solo_item (root, obj); } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_root_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { SwamiguiRoot *root = SWAMIGUI_ROOT (object); GObject *obj = NULL; switch (property_id) { case PROP_MAIN_WINDOW: g_value_set_object (value, G_OBJECT (root->main_window)); break; case PROP_UPDATE_INTERVAL: g_value_set_int (value, root->update_interval); break; case PROP_QUIT_CONFIRM: g_value_set_enum (value, root->quit_confirm); break; case PROP_SPLASH_ENABLE: g_value_set_boolean (value, root->splash_enable); break; case PROP_SPLASH_DELAY: g_value_set_uint (value, root->splash_delay); break; case PROP_TIPS_ENABLE: g_value_set_boolean (value, root->tips_enable); break; case PROP_TIPS_POSITION: g_value_set_int (value, root->tips_position); break; case PROP_PIANO_LOWER_KEYS: g_value_set_string_take_ownership (value, swamigui_root_encode_piano_keys (root->piano_lower_keys)); break; case PROP_PIANO_UPPER_KEYS: g_value_set_string_take_ownership (value, swamigui_root_encode_piano_keys (root->piano_upper_keys)); break; case PROP_DEFAULT_PATCH_TYPE: g_value_set_gtype (value, root->default_patch_type); break; case PROP_TREE_STORE_LIST: g_value_set_object (value, root->tree_stores); break; case PROP_SELECTION_ORIGIN: if (root->selection) obj = swami_object_get_origin (G_OBJECT (root->selection)); g_value_take_object (value, obj); break; case PROP_SELECTION: g_value_set_object (value, root->selection); break; case PROP_SELECTION_SINGLE: if (root->selection && root->selection->items && !root->selection->items->next) obj = root->selection->items->data; g_value_set_object (value, obj); break; case PROP_SOLO_ITEM_ENABLE: g_value_set_boolean (value, root->solo_item_enabled); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_root_quit_method (SwamiguiRoot *root) { swamigui_root_save_prefs (root); gtk_main_quit (); } /* Additional init operations are performed in swamigui_root_activate() */ static void swamigui_root_init (SwamiguiRoot *root) { IpatchList *list; GType type; /* having global vars for the Swami instance makes things easier */ swamigui_root = root; swami_root = SWAMI_ROOT (root); #ifdef PYTHON_SUPPORT if (!swamigui_disable_python) swamigui_python_set_root (); #endif root->update_interval = 40; root->quit_confirm = SWAMIGUI_QUIT_CONFIRM_UNSAVED; root->splash_enable = TRUE; root->splash_delay = SWAMIGUI_ROOT_DEFAULT_SPLASH_DELAY; root->tips_enable = TRUE; root->default_patch_type = IPATCH_TYPE_SF2; root->piano_lower_keys = swamigui_root_parse_piano_keys (SWAMIGUI_ROOT_DEFAULT_LOWER_KEYS); root->piano_upper_keys = swamigui_root_parse_piano_keys (SWAMIGUI_ROOT_DEFAULT_UPPER_KEYS); swami_object_set (G_OBJECT (root), "name", "Swami", "flags", SWAMI_OBJECT_SAVE | SWAMI_OBJECT_USER, NULL); /* create tree store */ root->patch_store = SWAMIGUI_TREE_STORE (swamigui_tree_store_patch_new ()); /* ++ ref */ swami_object_set (G_OBJECT (root->patch_store), "name", "Patches", NULL); swami_root_add_object (SWAMI_ROOT (root), G_OBJECT (root->patch_store)); /* create GUI control queue */ root->ctrl_queue = swami_control_queue_new (); /* ++ ref control queue */ /* setup the GUI queue test function and is_gui_thread private */ g_static_private_set (&is_gui_thread, GUINT_TO_POINTER (TRUE), NULL); swami_control_queue_set_test_func (root->ctrl_queue, swamigui_queue_test_func); /* create queued patch item property changed listener */ root->ctrl_prop = swami_control_func_new (); /* ++ ref new control */ swami_control_func_assign_funcs (root->ctrl_prop, NULL /* get_func */, ctrl_prop_set_func, NULL /* destroy_func */, root); /* this control will never send (receives events only), disables event loop check */ SWAMI_CONTROL (root->ctrl_prop)->flags &= ~SWAMI_CONTROL_SENDS; /* create queued patch item add control listener */ root->ctrl_add = swami_control_func_new (); /* ++ ref new control */ swami_control_func_assign_funcs (root->ctrl_add, NULL /* get_func */, ctrl_add_set_func, NULL /* destroy_func */, root); /* this control will never send (receives events only), disables event loop check */ SWAMI_CONTROL (root->ctrl_add)->flags &= ~SWAMI_CONTROL_SENDS; /* create queued patch item remove control listener */ root->ctrl_remove = swami_control_func_new (); /* ++ ref new control */ swami_control_func_assign_funcs (root->ctrl_remove, NULL /* get_func */, ctrl_remove_set_func, NULL /* destroy_func */, root); /* this control will never send (receives events only), disables event loop check */ SWAMI_CONTROL (root->ctrl_remove)->flags &= ~SWAMI_CONTROL_SENDS; /* set the queue of the controls */ swami_control_set_queue (SWAMI_CONTROL (root->ctrl_prop), root->ctrl_queue); swami_control_set_queue (SWAMI_CONTROL (root->ctrl_add), root->ctrl_queue); swami_control_set_queue (SWAMI_CONTROL (root->ctrl_remove), root->ctrl_queue); /* connect controls to ipatch event senders */ swami_control_connect (swami_patch_prop_title_control, SWAMI_CONTROL (root->ctrl_prop), 0); swami_control_connect (swami_patch_add_control, SWAMI_CONTROL (root->ctrl_add), 0); swami_control_connect (swami_patch_remove_control, SWAMI_CONTROL (root->ctrl_remove), 0); /* add patch store to tree store list */ list = ipatch_list_new (); list->items = g_list_append (list->items, g_object_ref (root->patch_store)); root->tree_stores = list; /* create the FluidSynth wavetable object */ type = swami_type_get_default (SWAMI_TYPE_WAVETBL); /* create new wavetable object */ if (type && (root->wavetbl = g_object_new (type, NULL))) { swami_object_set (root->wavetbl, "name", "FluidSynth1", NULL); swami_root_add_object (SWAMI_ROOT (root), G_OBJECT (root->wavetbl)); } } static void swamigui_root_finalize (GObject *object) { SwamiguiRoot *root = SWAMIGUI_ROOT (object); g_object_unref (root->patch_store); g_object_unref (root->tree_stores); if (root->selection) g_object_unref (root->selection); if (root->wavetbl) g_object_unref (root->wavetbl); if (root->solo_item) g_object_unref (root->solo_item); if (root->solo_item_icon) g_free (root->solo_item_icon); g_object_unref (root->ctrl_queue); if (root->update_timeout_id) g_source_remove (root->update_timeout_id); g_object_unref (root->ctrl_prop); g_object_unref (root->ctrl_add); g_object_unref (root->ctrl_remove); if (root->loaded_xml_config) ipatch_xml_destroy (root->loaded_xml_config); if (parent_class) parent_class->finalize (object); } /* GUI queue test function (checks if queuing of events is required) */ static gboolean swamigui_queue_test_func (SwamiControlQueue *queue, SwamiControl *control, SwamiControlEvent *event) { /* are we in the GUI thread? */ gboolean bval = GPOINTER_TO_UINT (g_static_private_get (&is_gui_thread)); return (!bval); /* FALSE sends event immediately, TRUE queues */ } /* routine called at regular intervals to synchronize GUI with patch objects */ static gboolean swamigui_update_gui_timeout (gpointer data) { SwamiguiRoot *root = SWAMIGUI_ROOT (data); swami_control_queue_run (root->ctrl_queue); /* Update splits widget if its splits-item has changed */ if (root->splits_changed) { swamigui_splits_item_changed (SWAMIGUI_SPLITS (root->splits)); root->splits_changed = FALSE; } return (TRUE); } /* patch item title property change control value set function (listens for item property change events) */ static void ctrl_prop_set_func (SwamiControl *control, SwamiControlEvent *event, const GValue *value) { SwamiguiRoot *root = SWAMIGUI_ROOT (SWAMI_CONTROL_FUNC_DATA (control)); SwamiEventPropChange *prop_change; prop_change = g_value_get_boxed (&event->value); swamigui_tree_store_changed (root->patch_store, prop_change->object); } /* patch item add control value set function (listens for item add events) */ static void ctrl_add_set_func (SwamiControl *control, SwamiControlEvent *event, const GValue *value) { SwamiguiRoot *root = SWAMIGUI_ROOT (SWAMI_CONTROL_FUNC_DATA (control)); IpatchItem *item, *splits_item; item = IPATCH_ITEM (g_value_get_boxed (&event->value)); swamigui_tree_store_add (root->patch_store, G_OBJECT (item)); /* Update splits widget if its active item changed */ g_object_get (root->splits, "splits-item", &splits_item, NULL); if (splits_item == ipatch_item_peek_parent (item)) root->splits_changed = TRUE; } /* patch item remove control value set function (listens for item remove events) */ static void ctrl_remove_set_func (SwamiControl *control, SwamiControlEvent *event, const GValue *value) { SwamiguiRoot *root = SWAMIGUI_ROOT (SWAMI_CONTROL_FUNC_DATA (control)); SwamiEventItemRemove *remove; IpatchItem *splits_item; remove = g_value_get_boxed (&event->value); swamigui_tree_store_remove (root->patch_store, G_OBJECT (remove->item)); /* Update splits widget if its active item changed */ g_object_get (root->splits, "splits-item", &splits_item, NULL); if (splits_item == ipatch_item_peek_parent (remove->item)) root->splits_changed = TRUE; } /** * swamigui_root_new: * * Create a new Swami root user interface object which is a subclass of * #SwamiRoot. * * Returns: New Swami user interface object */ SwamiguiRoot * swamigui_root_new (void) { return (SWAMIGUI_ROOT (g_object_new (SWAMIGUI_TYPE_ROOT, NULL))); } /** * swamigui_root_activate: * @root: Swami GUI root object * * Activates Swami GUI by creating main window, loading plugins, and displaying * tips and splash image. Separate from object init function so that preferences * can be loaded or not. */ void swamigui_root_activate (SwamiguiRoot *root) { GError *err = NULL; g_return_if_fail (SWAMIGUI_IS_ROOT (root)); /* GUI update timeout */ root->update_timeout_id = g_timeout_add (root->update_interval, (GSourceFunc)swamigui_update_gui_timeout, root); if (root->wavetbl) { if (!swami_wavetbl_open (SWAMI_WAVETBL (root->wavetbl), &err)) { g_warning ("Failed to initialize wavetable driver '%s'", ipatch_gerror_message (err)); g_clear_error (&err); } } /* create main window and controls */ swamigui_root_create_main_window (root); /* pop up swami tip window if enabled */ if (root->tips_enable) swamigui_help_swamitips_create (root); /* display splash (with timeout) only if not disabled */ if (root->splash_enable) swamigui_splash_display (root->splash_delay); } /** * swamigui_root_quit: * @root: Swami GUI root object * * Quit Swami GUI. Pops a quit confirmation depending on preferences. */ void swamigui_root_quit (SwamiguiRoot *root) { IpatchList *list; IpatchIter iter; GObject *obj; gboolean changed = FALSE; GtkWidget *popup; int quit_confirm; char *s; list = swami_root_get_patch_items (SWAMI_ROOT (root)); /* ++ ref list */ ipatch_list_init_iter (list, &iter); obj = ipatch_iter_first (&iter); while (obj) { g_object_get (obj, "changed", &changed, NULL); if (changed) break; obj = ipatch_iter_next (&iter); } g_object_unref (list); /* -- unref list */ g_object_get (root, "quit-confirm", &quit_confirm, NULL); if (quit_confirm == SWAMIGUI_QUIT_CONFIRM_NEVER || (quit_confirm == SWAMIGUI_QUIT_CONFIRM_UNSAVED && !changed)) { swamigui_real_quit (root); return; } if (changed) s = _("Unsaved files, and you want to quit?"); else s = _("Are you sure you want to quit?"); popup = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, "%s", s); gtk_dialog_add_buttons (GTK_DIALOG (popup), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_QUIT, GTK_RESPONSE_OK, NULL); g_signal_connect (popup, "response", G_CALLBACK (swamigui_cb_quit_response), root); gtk_widget_show (popup); } static void swamigui_cb_quit_response (GtkDialog *dialog, int response, gpointer user_data) { SwamiguiRoot *root = SWAMIGUI_ROOT (user_data); gtk_widget_destroy (GTK_WIDGET (dialog)); if (response == GTK_RESPONSE_OK) swamigui_real_quit (root); } static void swamigui_real_quit (SwamiguiRoot *root) { g_signal_emit (root, uiroot_signals [QUIT], 0); } /** * swamigui_root_save_prefs: * @root: Swami GUI root object * * Save application preferences to XML config file. Only stores config if it * differs from existing stored config on disk. * * Returns: %TRUE on success, %FALSE otherwise (error message will be logged) */ gboolean swamigui_root_save_prefs (SwamiguiRoot *root) { char *config_dir, *pref_filename; GError *local_err = NULL; GNode *xmltree, *node, *pnode, *dupnode; GList *plugins, *p; SwamiPlugin *plugin; char *xmlstr; char *curxml; const char *attr_val; xmltree = ipatch_xml_new_node (NULL, "swami", NULL, /* ++ alloc XML tree */ "version", SWAMI_VERSION, NULL); /* Encode the root object */ if (!ipatch_xml_encode_object (xmltree, G_OBJECT (root), FALSE, &local_err)) { g_critical (_("Failed to save Swami preferences: %s"), ipatch_gerror_message (local_err)); g_clear_error (&local_err); ipatch_xml_destroy (xmltree); /* -- free XML tree */ return (FALSE); } /* Encode plugin preferences */ plugins = swami_plugin_get_list (); /* ++ alloc list */ for (p = plugins; p; p = p->next) { plugin = (SwamiPlugin *)(p->data); if (plugin->save_xml) { node = ipatch_xml_new_node (xmltree, "plugin", NULL, "name", G_TYPE_MODULE (plugin)->name, NULL); if (!swami_plugin_save_xml (plugin, node, &local_err)) { g_warning (_("Failed to save plugin %s preferences: %s"), G_TYPE_MODULE (plugin)->name, ipatch_gerror_message (local_err)); ipatch_xml_destroy (node); /* -- free the plugin node */ g_clear_error (&local_err); } } } g_list_free (plugins); /* -- free list */ /* Check if there is any plugin data which was loaded at startup which is no * longer present and append it to the config if so. In particular this * prevents plugin preferences from being lost if they are not loaded at * startup. */ if (root->loaded_xml_config) { for (node = root->loaded_xml_config->children; node; node = node->next) { if (!ipatch_xml_test_name (node, "plugin")) continue; attr_val = ipatch_xml_get_attribute (node, "name"); if (!attr_val) continue; for (pnode = xmltree->children; pnode; pnode = pnode->next) if (ipatch_xml_test_name (pnode, "plugin") && ipatch_xml_test_attribute (pnode, "name", attr_val)) break; if (!pnode) /* Not found in new XML config? */ { dupnode = ipatch_xml_copy (node); /* Duplicate the plugin info */ g_node_append (xmltree, dupnode); /* Append to xmltree */ } } } config_dir = g_build_filename (g_get_user_config_dir(), "swami", NULL); /* ++ alloc */ if (!g_file_test (config_dir, G_FILE_TEST_EXISTS)) { if (g_mkdir_with_parents (config_dir, 0755) == -1) { g_critical (_("Failed to create Swami config directory '%s': %s"), config_dir, g_strerror (errno)); g_free (config_dir); /* -- free */ ipatch_xml_destroy (xmltree); /* -- free XML tree */ return (FALSE); } } pref_filename = g_build_filename (config_dir, "preferences.xml", NULL); /* ++ alloc */ g_free (config_dir); /* -- free config dir */ xmlstr = ipatch_xml_to_str (xmltree, 2); /* ++ alloc xmlstr */ ipatch_xml_destroy (xmltree); /* -- free XML tree */ /* Check if config matches what is already saved - return TRUE if it matches */ if (g_file_get_contents (pref_filename, &curxml, NULL, NULL)) /* ++ alloc curxml data */ { if (strcmp (xmlstr, curxml) == 0) { g_free (curxml); /* -- free current XML data */ g_free (xmlstr); /* -- free xmlstr */ g_free (pref_filename); /* -- free pref_filename */ return (TRUE); } g_free (curxml); /* -- free current XML data */ } if (!g_file_set_contents (pref_filename, xmlstr, -1, &local_err)) { g_critical (_("Failed to save XML preferences to '%s': %s"), pref_filename, ipatch_gerror_message (local_err)); g_clear_error (&local_err); g_free (xmlstr); /* -- free xmlstr */ g_free (pref_filename); /* -- free */ return (FALSE); } g_free (xmlstr); /* -- free xmlstr */ g_free (pref_filename); /* -- free */ return (TRUE); } /** * swamigui_root_load_prefs: * @root: Swami GUI root object * * Restore application preferences from XML config files. * * Returns: %TRUE on success, %FALSE otherwise (error message will be logged) */ gboolean swamigui_root_load_prefs (SwamiguiRoot *root) { GNode *xmltree, *n; char *pref_filename; GParamSpec *pspec; GObjectClass *obj_class; SwamiPlugin *plugin; GError *err = NULL; const char *name; /* ++ alloc */ pref_filename = g_build_filename (g_get_user_config_dir(), "swami", "preferences.xml", NULL); /* No preferences stored yet? - Return success */ if (!g_file_test (pref_filename, G_FILE_TEST_EXISTS)) return (TRUE); xmltree = ipatch_xml_load_from_file (pref_filename, &err); /* ++ alloc XML tree */ if (!xmltree) { g_critical (_("Failed to load preferences from '%s': %s"), pref_filename, ipatch_gerror_message (err)); g_clear_error (&err); g_free (pref_filename); /* -- free filename */ return (FALSE); } name = ipatch_xml_get_name (xmltree); if (!name || strcmp (name, "swami") != 0) { g_critical (_("File '%s' is not a Swami preferences file"), pref_filename); ipatch_xml_destroy (xmltree); /* -- destroy XML tree */ g_free (pref_filename); /* -- free filename */ return (FALSE); } obj_class = G_OBJECT_GET_CLASS (root); for (n = xmltree->children; n; n = n->next) { name = ipatch_xml_get_name (n); if (!name) continue; if (strcmp (name, "prop") == 0) /* Root preference value */ { name = ipatch_xml_get_attribute (n, "name"); if (!name) continue; pspec = g_object_class_find_property (obj_class, name); if (!pspec || (pspec->flags & IPATCH_PARAM_NO_SAVE)) { g_warning (_("Invalid Swami property '%s' in preferences"), name); continue; } if (!ipatch_xml_decode_property (n, G_OBJECT (root), pspec, &err)) { g_critical (_("Failed to decode Swami preference property '%s': %s"), pspec->name, ipatch_gerror_message (err)); g_clear_error (&err); continue; } } else if (strcmp (name, "plugin") == 0) /* Plugin state */ { name = ipatch_xml_get_attribute (n, "name"); if (!name) continue; plugin = swami_plugin_find (name); if (plugin) { if (!swami_plugin_load_xml (plugin, n, &err)) { g_critical (_("Failed to load plugin '%s' preferences: %s"), name, ipatch_gerror_message (err)); g_clear_error (&err); } } } } g_free (pref_filename); /* -- free filename */ /* Set the loaded_xml_config variable so it reflects the last loaded XML config */ if (root->loaded_xml_config) ipatch_xml_destroy (root->loaded_xml_config); root->loaded_xml_config = xmltree; /* !! root takes over reference */ return (TRUE); } /** * swamigui_get_root: * @gobject: An object registered to a #SwamiguiRoot object * * Gets a #SwamiguiObject associated with a @gobject. A convenience function * really as swami_get_root() will return the same object but casted to * #SwamiRoot instead. * * Returns: A #SwamiguiRoot object or %NULL if @gobject not registered to one. * Returned object's refcount is not incremented. */ SwamiguiRoot * swamigui_get_root (gpointer gobject) { SwamiguiRoot *root; g_return_val_if_fail (G_IS_OBJECT (gobject), NULL); if (SWAMIGUI_IS_ROOT (gobject)) root = (SwamiguiRoot *)gobject; else root = (SwamiguiRoot *)swami_get_root (G_OBJECT (gobject)); /* if no root object is assigned to 'gobject' then just return the global */ if (!root) return (swamigui_root); return (root); } /* Create main window and controls */ static void swamigui_root_create_main_window (SwamiguiRoot *root) { SwamiPropTree *proptree; SwamiControl *ctrl, *rootsel_ctrl; SwamiControl *store_ctrl; GtkWidget *vbox; GtkWidget *tempbox; GtkWidget *vpaned, *hpaned; GtkWidget *widg; GType type; SwamiControl *midihub; SwamiguiControlMidiKey *midikey; GObject *piano; SwamiControl *pctrl, *tctrl; SwamiControlMidi *wctrl; /* get root selection property control */ rootsel_ctrl = swami_get_control_prop_by_name (G_OBJECT (root), "selection"); root->main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_default_size (GTK_WINDOW (root->main_window), 1024, 768); gtk_window_set_title (GTK_WINDOW (root->main_window), "Swami"); g_signal_connect (root->main_window, "delete_event", G_CALLBACK (swamigui_root_cb_main_window_delete), root); /* add the item menu keyboard accelerators */ gtk_window_add_accel_group (GTK_WINDOW (root->main_window), swamigui_item_menu_accel_group); vbox = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox); gtk_container_add (GTK_CONTAINER (root->main_window), vbox); hpaned = gtk_hpaned_new (); gtk_widget_show (hpaned); gtk_box_pack_start (GTK_BOX (vbox), hpaned, TRUE, TRUE, 0); tempbox = gtk_vbox_new (FALSE, 0); gtk_widget_show (tempbox); gtk_paned_pack1 (GTK_PANED (hpaned), tempbox, TRUE, TRUE); widg = swamigui_menu_new (); gtk_widget_show (widg); gtk_box_pack_start (GTK_BOX (tempbox), widg, FALSE, FALSE, 0); root->tree = swamigui_tree_new (root->tree_stores); gtk_widget_show (root->tree); gtk_box_pack_start (GTK_BOX (tempbox), root->tree, TRUE, TRUE, 0); /* connect tree selection to root selection (++ ref ctrl) */ ctrl = swami_get_control_prop_by_name (G_OBJECT (root->tree), "selection"); swami_control_connect (ctrl, rootsel_ctrl, SWAMI_CONTROL_CONN_BIDIR); g_object_unref (ctrl); /* -- unref tree control */ /* HACK - Set initial selection (so that swamigui_root "selection" is not NULL) * We need an empty selection, since it has the origin of the tree. * So no problems occur with tree menu accelerators. */ swamigui_tree_set_selection (SWAMIGUI_TREE (root->tree), NULL); vpaned = gtk_vpaned_new (); gtk_widget_show (vpaned); gtk_paned_pack2 (GTK_PANED (hpaned), vpaned, TRUE, TRUE); tempbox = gtk_vbox_new (FALSE, 0); gtk_widget_show (tempbox); gtk_paned_pack1 (GTK_PANED (vpaned), tempbox, TRUE, TRUE); /* create FluidSynth interface */ type = g_type_from_name ("FluidSynthGuiControl"); if (type) { widg = g_object_new (type, NULL); gtk_widget_show_all (widg); gtk_box_pack_start (GTK_BOX (tempbox), widg, FALSE, FALSE, 2); } /* create splits widget */ root->splits = swamigui_splits_new (); gtk_widget_show (root->splits); gtk_box_pack_start (GTK_BOX (tempbox), root->splits, TRUE, TRUE, 0); /* connect root selection to splits (++ ref ctrl) */ ctrl = swami_get_control_prop_by_name (G_OBJECT (root->splits), "item-selection"); swami_control_connect (rootsel_ctrl, ctrl, SWAMI_CONTROL_CONN_BIDIR); g_object_unref (ctrl); /* -- unref tree control */ root->panel_selector = swamigui_panel_selector_new (); gtk_widget_show (root->panel_selector); gtk_paned_pack2 (GTK_PANED (vpaned), root->panel_selector, FALSE, TRUE); /* connect root selection to panel selector (++ ref ctrl) */ ctrl = swami_get_control_prop_by_name (G_OBJECT (root->panel_selector), "item-selection"); swami_control_connect (rootsel_ctrl, ctrl, 0); g_object_unref (ctrl); /* -- unref tree control */ gtk_paned_set_position (GTK_PANED (hpaned), 300); gtk_paned_set_position (GTK_PANED (vpaned), 400); /* create statusbar and pack it */ root->statusbar = SWAMIGUI_STATUSBAR (swamigui_statusbar_new ()); gtk_widget_show (GTK_WIDGET (root->statusbar)); gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (root->statusbar), FALSE, FALSE, 2); /* connect root selection to GUI switcher widget property tree variables */ proptree = SWAMI_ROOT (root)->proptree; swami_prop_tree_add_value (proptree, G_OBJECT (root), 0, "item-selection", rootsel_ctrl); /* create SwamiguiRoot tree store property control (++ ref new object) */ store_ctrl = swami_get_control_prop_by_name (G_OBJECT (root), "tree-store-list"); /* FIXME - kill hackish property tree (alternatives?) */ swami_prop_tree_add_value (proptree, G_OBJECT (root), 0, "store-list", store_ctrl); g_object_unref (store_ctrl); /* -- unref creator's reference */ g_object_unref (rootsel_ctrl); /* -- unref root control */ /* Control section of init */ /* create MIDI hub control */ midihub = SWAMI_CONTROL /* ++ ref */ (swami_root_new_object (SWAMI_ROOT (root), "SwamiControlHub")); /* create MIDI keyboard control */ midikey = SWAMIGUI_CONTROL_MIDI_KEY /* ++ ref */ (swami_root_new_object (SWAMI_ROOT (root), "SwamiguiControlMidiKey")); /* connect keyboard control to MIDI hub */ swami_control_connect (SWAMI_CONTROL (midikey), midihub, 0); /* Connect splits widget keyboard controls to MIDI keyboard object */ swamigui_root_connect_midi_keyboard_controls (root, G_OBJECT (midikey)); g_object_unref (midikey); /* -- unref creator's ref */ g_object_get (root->splits, "piano", &piano, NULL); /* ++ ref piano */ g_object_get (piano, "midi-control", &pctrl, NULL); /* ++ ref piano MIDI ctrl */ /* connect piano to MIDI hub */ swami_control_connect (pctrl, midihub, SWAMI_CONTROL_CONN_BIDIR); g_object_unref (pctrl); /* -- unref */ g_object_unref (piano); /* -- unref */ if (root->wavetbl) { /* get wavetable MIDI control */ wctrl = swami_wavetbl_get_control (SWAMI_WAVETBL (root->wavetbl), 0); /* set initial bank/program number */ swami_control_midi_send (wctrl, SWAMI_MIDI_BANK_SELECT, 0, 127, -1); swami_control_midi_send (wctrl, SWAMI_MIDI_PROGRAM_CHANGE, 0, 127, -1); /* connect wavetable to MIDI hub */ swami_control_connect (midihub, SWAMI_CONTROL (wctrl), SWAMI_CONTROL_CONN_BIDIR | SWAMI_CONTROL_CONN_PRIORITY_HIGH); g_object_unref (wctrl); /* -- unref */ /* get control connected to root selection-single property (++ ref) */ tctrl = SWAMI_CONTROL (swami_get_control_prop_by_name (G_OBJECT (root), "selection-single")); /* get prop control to wavetbl temp item (++ ref ctrl) */ pctrl = SWAMI_CONTROL (swami_get_control_prop_by_name (G_OBJECT (root->wavetbl), "active-item")); swami_control_connect (tctrl, pctrl, 0); g_object_unref (tctrl); /* -- unref */ g_object_unref (pctrl); /* -- unref */ g_signal_connect (root, "notify::selection-single", G_CALLBACK (swamigui_root_cb_solo_item), NULL); } g_object_unref (midihub); /* -- unref creator's reference */ gtk_widget_show (root->main_window); } /* Callback for SwamiguiRoot::selection-single to update Wavetbl solo-item if enabled */ static void swamigui_root_cb_solo_item (SwamiguiRoot *root, GParamSpec *pspec, gpointer user_data) { GObject *solo_item; if (!root->solo_item_enabled) return; g_object_get (root, "selection-single", &solo_item, NULL); /* ++ ref solo item */ swamigui_root_update_solo_item (root, solo_item); if (solo_item) g_object_unref (solo_item); /* -- unref solo item */ } static void swamigui_root_update_solo_item (SwamiguiRoot *root, GObject *solo_item) { GtkTreeIter iter; int category; /* If no wavetbl driver active - return */ if (!root->wavetbl) return; /* Valid solo items are instrument or sample zones */ if (solo_item) { ipatch_type_get (G_OBJECT_TYPE (solo_item), "category", &category, NULL); if (category != IPATCH_CATEGORY_SAMPLE_REF && category != IPATCH_CATEGORY_INSTRUMENT_REF) { g_object_unref (solo_item); /* -- unref solo item */ solo_item = NULL; } } /* If previous solo item, restore its icon */ if (root->solo_item) { swamigui_tree_store_change (root->patch_store, root->solo_item, NULL, root->solo_item_icon); g_object_unref (root->solo_item); root->solo_item = NULL; root->solo_item_icon = NULL; } if (solo_item) { if (swamigui_tree_store_item_get_node (root->patch_store, solo_item, &iter)) { root->solo_item = g_object_ref (solo_item); /* !! icon column is a static string - not allocated */ gtk_tree_model_get (GTK_TREE_MODEL (root->patch_store), &iter, SWAMIGUI_TREE_STORE_ICON_COLUMN, &root->solo_item_icon, -1); gtk_tree_store_set (GTK_TREE_STORE (root->patch_store), &iter, SWAMIGUI_TREE_STORE_ICON_COLUMN, GTK_STOCK_MEDIA_PLAY, -1); } else solo_item = NULL; /* Shouldn't fail to find item in tree, but.. */ } g_object_set (root->wavetbl, "solo-item", solo_item, NULL); } static void swamigui_root_connect_midi_keyboard_controls (SwamiguiRoot *root, GObject *midikey) { GtkWidget *widget; int i; struct { char *widg_name; char *prop_name; } names[] = { { "SpinBtnLowerOctave", "lower-octave" }, { "ChkBtnJoinOctaves", "join-octaves" }, { "SpinBtnUpperOctave", "upper-octave" }, { "SpinBtnLowerVelocity", "lower-velocity" }, { "ChkBtnSameVelocity", "same-velocity" }, { "SpinBtnUpperVelocity", "upper-velocity" } }; for (i = 0; i < G_N_ELEMENTS (names); i++) { widget = swamigui_util_glade_lookup (SWAMIGUI_SPLITS (root->splits)->gladewidg, names[i].widg_name); swamigui_control_prop_connect_widget (midikey, names[i].prop_name, G_OBJECT (widget)); } } /* called when main window is closed */ static gint swamigui_root_cb_main_window_delete (GtkWidget *widget, GdkEvent *event, gpointer data) { SwamiguiRoot *root = SWAMIGUI_ROOT (data); swamigui_root_quit (root); return (TRUE); } /* converts a string of comma delimited GDK key symbols into a newly allocated zero terminated array of key values */ static guint * swamigui_root_parse_piano_keys (const char *str) { guint *keyvals; char **keynames; int count = 0, v = 0, n = 0; if (!str) return (NULL); keynames = g_strsplit (str, ",", 0); while (keynames[count]) count++; /* count key symbols */ keyvals = g_malloc ((count + 1) * sizeof (guint)); while (keynames[n]) { keyvals[v] = gdk_keyval_from_name (keynames[n]); if (keyvals[v] != GDK_VoidSymbol) v++; /* ignore invalid key names */ n++; } keyvals[v] = 0; /* zero terminated */ g_strfreev (keynames); return (keyvals); } /* converts a zero terminated array of key values into a newly allocated comma delimited GDK key symbol string */ static char * swamigui_root_encode_piano_keys (const guint *keyvals) { char **keynames; char *s; int i, count = 0; if (!keyvals) return (NULL); while (keyvals[count]) count++; /* count number of key values */ /* allocate for array of key name strings */ keynames = g_malloc ((count + 1) * sizeof (char *)); for (i = 0; i < count; i++) /* loop over each key */ { keynames[i] = gdk_keyval_name (keyvals[i]); /* get key name */ if (!keynames[i]) /* if no key name for key, fail */ { g_critical ("No GDK key name for key '%d'", keyvals[i]); g_free (keynames); return (NULL); } } keynames[count] = NULL; s = g_strjoinv (",", keynames); /* create the comma delimited key string */ g_free (keynames); return (s); } /* handler for IpatchSF2 glade property interface. * Needed in order to handle "Current Date" button. */ static GtkWidget * sf2_prop_handler (GtkWidget *widg, GObject *obj) { GtkWidget *btn, *entry; if (!widg) /* create widget? */ { widg = swamigui_util_glade_create ("PropSF2"); btn = swamigui_util_glade_lookup (widg, "BtnCurrentDate"); entry = swamigui_util_glade_lookup (widg, "PROP::date"); g_signal_connect (btn, "clicked", G_CALLBACK (current_date_btn_clicked), entry); swamigui_control_glade_prop_connect (widg, obj); } else swamigui_control_glade_prop_connect (widg, obj); /* change object */ return (widg); } /* callback when "Current Date" button is clicked */ static void current_date_btn_clicked (GtkButton *button, gpointer user_data) { struct tm *date; char datestr[64]; time_t t; t = time (NULL); date = localtime (&t); g_return_if_fail (date != NULL); /* NOTE: SoundFont standard says that conventionally the date is in the format * "April 3, 2008". This isn't international friendly though, so we instead * use the format YYYY-MM-DD which we have deemed OK, because of the use of * the word "conventionally" in the spec. */ strftime (datestr, sizeof (datestr), "%Y-%m-%d", date); gtk_entry_set_text (GTK_ENTRY (user_data), datestr); } swami/src/swamigui/SwamiguiNoteSelector.c0000644000175000017500000000607711461334205020763 0ustar alessioalessio/* * SwamiguiNoteSelector.c - MIDI note selector widget. * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "SwamiguiNoteSelector.h" #include "i18n.h" static gint swamigui_note_selector_input (GtkSpinButton *spinbutton, gdouble *newval); static gboolean swamigui_note_selector_output (GtkSpinButton *spinbutton); /* define the note selector type */ G_DEFINE_TYPE (SwamiguiNoteSelector, swamigui_note_selector, GTK_TYPE_SPIN_BUTTON); static void swamigui_note_selector_class_init (SwamiguiNoteSelectorClass *klass) { GtkSpinButtonClass *spinbtn_class = GTK_SPIN_BUTTON_CLASS (klass); spinbtn_class->input = swamigui_note_selector_input; spinbtn_class->output = swamigui_note_selector_output; } static gint swamigui_note_selector_input (GtkSpinButton *spinbutton, gdouble *newval) { const char *text; int note; text = gtk_entry_get_text (GTK_ENTRY (spinbutton)); if (!text || strchr (text, '|')) return (FALSE); note = swami_util_midi_str_to_note (text); if (note == -1) return GTK_INPUT_ERROR; *newval = note; return (TRUE); } /* override spin button display "output" signal to show note strings */ static gboolean swamigui_note_selector_output (GtkSpinButton *spinbutton) { char notestr[9] = { 0 }; GtkAdjustment *adj; int note; adj = gtk_spin_button_get_adjustment (spinbutton); note = adj->value; if (note >= 0 && note <= 127) { sprintf (notestr, "%d | ", note); swami_util_midi_note_to_str (note, notestr + strlen (notestr)); } if (strcmp (notestr, gtk_entry_get_text (GTK_ENTRY (spinbutton)))) gtk_entry_set_text (GTK_ENTRY (spinbutton), notestr); return (TRUE); } static void swamigui_note_selector_init (SwamiguiNoteSelector *notesel) { GtkAdjustment *adj; adj = (GtkAdjustment *)gtk_adjustment_new (60.0, 0.0, 127.0, 1.0, 12.0, 0.0); gtk_spin_button_configure (GTK_SPIN_BUTTON (notesel), adj, 1.0, 0); gtk_entry_set_width_chars (GTK_ENTRY (notesel), 10); } /** * swamigui_note_selector_new: * * Create a new MIDI note selector widget. * * Returns: New MIDI note selector. */ GtkWidget * swamigui_note_selector_new (void) { return (GTK_WIDGET (g_object_new (SWAMIGUI_TYPE_NOTE_SELECTOR, NULL))); } swami/src/swamigui/SwamiguiBarPtr.h0000644000175000017500000000477211461334205017554 0ustar alessioalessio/* * SwamiguiBarPtr.h - Pointer object added to SwamiguiBar canvas items * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_BAR_PTR_H__ #define __SWAMIGUI_BAR_PTR_H__ #include #include typedef struct _SwamiguiBarPtr SwamiguiBarPtr; typedef struct _SwamiguiBarPtrClass SwamiguiBarPtrClass; #define SWAMIGUI_TYPE_BAR_PTR (swamigui_bar_ptr_get_type ()) #define SWAMIGUI_BAR_PTR(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMIGUI_TYPE_BAR_PTR, SwamiguiBarPtr)) #define SWAMIGUI_BAR_PTR_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMIGUI_TYPE_BAR_PTR, SwamiguiBarPtrClass)) #define SWAMIGUI_IS_BAR_PTR(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMIGUI_TYPE_BAR_PTR)) #define SWAMIGUI_IS_BAR_PTR_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMIGUI_TYPE_BAR_PTR)) /* Pointer type */ typedef enum { SWAMIGUI_BAR_PTR_POSITION, /* pointer position indicator */ SWAMIGUI_BAR_PTR_RANGE /* range selection */ } SwamiguiBarPtrType; /* Bar pointer object */ struct _SwamiguiBarPtr { GnomeCanvasGroup parent_instance; /*< private >*/ GnomeCanvasItem *rect; /* pointer rectangle */ GnomeCanvasItem *ptr; /* triangle pointer (if SWAMIGUI_BAR_POINTER) */ GnomeCanvasItem *icon; /* icon for this pointer */ int width; /* width in pixels */ int height; /* height in pixels */ int pointer_height; /* height of pointer in pixels */ SwamiguiBarPtrType type; /* pointer interface type */ gboolean interactive; /* TRUE if user can change this pointer */ guint32 color; char *label; char *tooltip; }; struct _SwamiguiBarPtrClass { GnomeCanvasGroupClass parent_class; }; GType swamigui_bar_ptr_get_type (void); GnomeCanvasItem *swamigui_bar_ptr_new (void); #endif swami/src/swamigui/SwamiguiCanvasMod.c0000644000175000017500000004550011461334205020222 0ustar alessioalessio/* * SwamiguiCanvasMod.c - Zoom/Scroll canvas modulation object * Allows scroll/zoom of canvas as a user interface. * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include "SwamiguiCanvasMod.h" #include "marshals.h" enum { PROP_0, PROP_TIMEOUT_INTERVAL, /* timeout interval in msecs */ PROP_ABS_MIN_ZOOM, /* absolute minimum zoom value */ PROP_SNAP }; /* Equation used for zoom/scroll operations: * * val = CLAMP (mult * pow (inp, power) + ofs, min, max) * * val: Value to use as zoom multiplier or scroll offset amount (zoom multiplier * per second or scroll pixels per second) * mult: A linear multiplier factor * inp: Input source (event time interval for wheel, pixel distance from snap) * power: An exponential factor (1.0 = linear) * ofs: Offset amount * * swamigui_canvas_mod_handle_event() is called with canvas events. This * function checks for events related to zoom/scroll operations (middle * mouse click, mouse wheel, etc). A timeout is installed which sends * periodic updates for the zoom or scroll values using the "update" signal. * The "snap" signal is used for updating the X and/or Y snap lines, which * the user of SwamiguiCanvasZoom is responsible for. * * * Equation used for zoom multiplier to convert it to the timeout interval * from zoom value per second. This is done so that any changes to timeout * interval only change the number of visual updates per second, but doesn't * affect the transformation speed. * * frac_mult = pow (mult, interval) * * frac_mult: Fractional zoom multiplier to use for each timeout callback * mult: The zoom multiplier for 1 second interval (as calculated from above) * interval: The callback interval time in seconds * * * State machine of SwamiguiCanvasMod: * * snap_active: TRUE indicates that a zoom and/or scroll snap is in progress. * last_wheel_dir: When GDK_SCROLL_UP or GDK_SCROLL_DOWN then wheel zoom and/or * scroll is active * * When snap_active == TRUE the following variables are valid: * xsnap/ysnap: Original coordinates of snap (when mouse button was clicked) * cur_xsnap/cur_ysnap: Current coordinates of the mouse * cur_xchange/cur_ychange: Indicate if cur_xsnap/cur_ysnap have changed since * last timeout * * */ #define TIMEOUT_PRIORITY (G_PRIORITY_HIGH_IDLE + 40) #define DEFAULT_ZOOM_MODIFIER GDK_CONTROL_MASK #define DEFAULT_SCROLL_MODIFIER GDK_SHIFT_MASK #define DEFAULT_AXIS_MODIFIER GDK_MOD1_MASK #define DEFAULT_SNAP_BUTTON 2 /* snap mouse button */ #define DEFAULT_ACTION_ZOOM TRUE #define DEFAULT_ZOOM_DEF_AXIS SWAMIGUI_CANVAS_MOD_X #define DEFAULT_SCROLL_DEF_AXIS SWAMIGUI_CANVAS_MOD_X #define DEFAULT_ONE_WHEEL_TIME 250 /* initial wheel event 'inp' val */ #define DEFAULT_MIN_ZOOM 1.0000001 /* minimum zoom/sec */ #define DEFAULT_MAX_ZOOM 1000000000.0 /* maximum zoom/sec */ #define DEFAULT_MIN_SCROLL 1.0 /* minimim scroll/sec */ #define DEFAULT_MAX_SCROLL 100000.0 /* maximum scroll/sec */ #define DEFAULT_TIMEOUT_INTERVAL 20 /* timeout interval in msecs */ #define DEFAULT_WHEEL_TIMEOUT 250 /* wheel taper timeout in msecs */ static const SwamiguiCanvasModVars default_vars[SWAMIGUI_CANVAS_MOD_AXIS_COUNT][SWAMIGUI_CANVAS_MOD_TYPE_COUNT] = { /* { mult, power, ofs } */ { /* { X } */ { 0.5, 4.0, 1.0 }, /* MOD_SNAP_ZOOM */ { 1.0, 2.2, 5.0 }, /* MOD_WHEEL_ZOOM */ { 10.0, 1.8, 200.0 }, /* MOD_SNAP_SCROLL */ { 0.6, 1.6, 400.0 } /* MOD_WHEEL_SCROLL */ }, { /* { Y } */ { 0.5, 4.0, 1.0 }, /* MOD_SNAP_ZOOM */ { 1.0, 2.2, 5.0 }, /* MOD_WHEEL_ZOOM */ { 10.0, 1.8, 200.0 }, /* MOD_SNAP_SCROLL */ { 0.6, 1.6, 400.0 } /* MOD_WHEEL_SCROLL */ } }; enum { UPDATE_SIGNAL, SNAP_SIGNAL, SIGNAL_COUNT }; /* an undefined scroll direction for last_wheel_dir field */ #define WHEEL_INACTIVE 0xFF static guint swamigui_canvas_mod_get_actions (SwamiguiCanvasMod *mod, guint state); static gboolean swamigui_canvas_mod_timeout (gpointer data); G_DEFINE_TYPE (SwamiguiCanvasMod, swamigui_canvas_mod, G_TYPE_OBJECT); static guint signals[SIGNAL_COUNT] = { 0 }; static void swamigui_canvas_mod_class_init (SwamiguiCanvasModClass *klass) { signals[UPDATE_SIGNAL] = g_signal_new ("update", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (SwamiguiCanvasModClass, update), NULL, NULL, swamigui_marshal_VOID__DOUBLE_DOUBLE_DOUBLE_DOUBLE_DOUBLE_DOUBLE, G_TYPE_NONE, 6, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_DOUBLE); signals[SNAP_SIGNAL] = g_signal_new ("snap", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (SwamiguiCanvasModClass, snap), NULL, NULL, swamigui_marshal_VOID__UINT_DOUBLE_DOUBLE, G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_DOUBLE, G_TYPE_DOUBLE); } static void swamigui_canvas_mod_init (SwamiguiCanvasMod *mod) { mod->zoom_modifier = DEFAULT_ZOOM_MODIFIER; mod->scroll_modifier = DEFAULT_SCROLL_MODIFIER; mod->axis_modifier = DEFAULT_AXIS_MODIFIER; mod->snap_button = DEFAULT_SNAP_BUTTON; mod->def_action_zoom = DEFAULT_ACTION_ZOOM; mod->def_zoom_axis = DEFAULT_ZOOM_DEF_AXIS; mod->def_scroll_axis = DEFAULT_SCROLL_DEF_AXIS; mod->one_wheel_time = DEFAULT_ONE_WHEEL_TIME; mod->min_zoom = DEFAULT_MIN_ZOOM; mod->max_zoom = DEFAULT_MAX_ZOOM; mod->min_scroll = DEFAULT_MIN_SCROLL; mod->max_scroll = DEFAULT_MAX_SCROLL; mod->timeout_interval = DEFAULT_TIMEOUT_INTERVAL; mod->wheel_timeout = DEFAULT_WHEEL_TIMEOUT; mod->last_wheel_dir = WHEEL_INACTIVE; memcpy (mod->vars, default_vars, sizeof (SwamiguiCanvasModVars) * SWAMIGUI_CANVAS_MOD_AXIS_COUNT * SWAMIGUI_CANVAS_MOD_TYPE_COUNT); } /** * swamigui_canvas_mod_new: * * Create a new canvas zoom/scroll modulator object. This object is used for * handling canvas events and intercepting those which apply to zooming or * scrolling operations by the user. * * Returns: New canvas modulator object with a refcount of 1 which the caller * owns. */ SwamiguiCanvasMod * swamigui_canvas_mod_new (void) { return (SWAMIGUI_CANVAS_MOD (g_object_new (SWAMIGUI_TYPE_CANVAS_MOD, NULL))); } /** * swamigui_canvas_mod_set_vars: * @mod: Canvas zoom/scroll modulator * @axis: Axis of variables to assign (X or Y) * @type: Modulator type to assign to (snap zoom, snap scroll, wheel zoom or * wheel scroll) * @mult: Multiplier value to assign to equation * @power: Power value to assign to equation * @ofs: Offset value to assign to equation * * Assigns equation variables for a specific modulator and axis. */ void swamigui_canvas_mod_set_vars (SwamiguiCanvasMod *mod, SwamiguiCanvasModAxis axis, SwamiguiCanvasModType type, double mult, double power, double ofs) { g_return_if_fail (SWAMIGUI_IS_CANVAS_MOD (mod)); g_return_if_fail (axis >= 0 && axis < SWAMIGUI_CANVAS_MOD_AXIS_COUNT); g_return_if_fail (type >= 0 && type < SWAMIGUI_CANVAS_MOD_TYPE_COUNT); mod->vars[axis][type].mult = mult; mod->vars[axis][type].power = power; mod->vars[axis][type].ofs = ofs; } /** * swamigui_canvas_mod_get_vars: * @mod: Canvas zoom/scroll modulator * @axis: Axis of variables to get (X or Y) * @type: Modulator type to get vars from (snap zoom, snap scroll, wheel zoom or * wheel scroll) * @mult: Location to store multiplier value of equation or %NULL * @power: Location to store power value of equation or %NULL * @ofs: Location to store offset value of equation or %NULL * * Gets equation variables for a specific modulator and axis. */ void swamigui_canvas_mod_get_vars (SwamiguiCanvasMod *mod, SwamiguiCanvasModAxis axis, SwamiguiCanvasModType type, double *mult, double *power, double *ofs) { g_return_if_fail (SWAMIGUI_IS_CANVAS_MOD (mod)); g_return_if_fail (axis >= 0 && axis < SWAMIGUI_CANVAS_MOD_AXIS_COUNT); g_return_if_fail (type >= 0 && type < SWAMIGUI_CANVAS_MOD_TYPE_COUNT); if (mult) *mult = mod->vars[axis][type].mult; if (power) *power = mod->vars[axis][type].power; if (ofs) *ofs = mod->vars[axis][type].ofs; } /** * swamigui_canvas_mod_handle_event: * @mod: Canvas zoom/scroll modulator instance * @event: Canvas event to handle * * Processes canvas events and handles events related to zoom/scroll * actions. * * Returns: %TRUE if event was a zoom/scroll related event (was handled), * %FALSE otherwise */ gboolean swamigui_canvas_mod_handle_event (SwamiguiCanvasMod *mod, GdkEvent *event) { GdkEventMotion *motion_event; GdkEventButton *btn_event; GdkEventScroll *scroll_event; guint actions; switch (event->type) { case GDK_BUTTON_PRESS: /* button press only applies to snap */ btn_event = (GdkEventButton *)event; if (btn_event->button != mod->snap_button) return (FALSE); mod->snap_active = TRUE; mod->xsnap = btn_event->x; mod->cur_xsnap = btn_event->x; mod->cur_xchange = TRUE; mod->ysnap = btn_event->y; mod->cur_ysnap = btn_event->y; mod->cur_ychange = TRUE; /* add a timeout callback for zoom/scroll if not already added */ if (!mod->timeout_handler) { mod->timeout_handler = g_timeout_add_full (TIMEOUT_PRIORITY, mod->timeout_interval, swamigui_canvas_mod_timeout, mod, NULL); } actions = swamigui_canvas_mod_get_actions (mod, btn_event->state); g_signal_emit (mod, signals[SNAP_SIGNAL], 0, actions, (double)(mod->xsnap), (double)(mod->ysnap)); break; case GDK_MOTION_NOTIFY: /* motion applies only to snap */ if (!mod->snap_active) return (FALSE); motion_event = (GdkEventMotion *)event; if (mod->cur_xsnap != motion_event->x) { mod->cur_xsnap = motion_event->x; mod->cur_xchange = TRUE; } if (mod->cur_ysnap != motion_event->y) { mod->cur_ysnap = motion_event->y; mod->cur_ychange = TRUE; } break; case GDK_BUTTON_RELEASE: /* button release only applies to snap */ if (!mod->snap_active || ((GdkEventButton *)event)->button != mod->snap_button) return (FALSE); mod->snap_active = FALSE; /* remove timeout if wheel not active */ if (mod->last_wheel_dir == WHEEL_INACTIVE && mod->timeout_handler) { g_source_remove (mod->timeout_handler); mod->timeout_handler = 0; } g_signal_emit (mod, signals[SNAP_SIGNAL], 0, 0, mod->xsnap, mod->ysnap); break; case GDK_SCROLL: /* mouse wheel zooming */ scroll_event = (GdkEventScroll *)event; if (scroll_event->direction != GDK_SCROLL_UP && scroll_event->direction != GDK_SCROLL_DOWN) return (FALSE); /* wheel was previously scrolled in the other direction? - Stop immediately */ if (mod->last_wheel_dir != WHEEL_INACTIVE && mod->last_wheel_dir != scroll_event->direction) { /* remove timeout handler if snap is not also active */ if (!mod->snap_active && mod->timeout_handler) { g_source_remove (mod->timeout_handler); mod->timeout_handler = 0; } mod->last_wheel_dir = WHEEL_INACTIVE; return (TRUE); } /* wheel not yet scrolled? */ if (mod->last_wheel_dir == WHEEL_INACTIVE) { mod->last_wheel_dir = scroll_event->direction; mod->wheel_time = mod->one_wheel_time; mod->xwheel = scroll_event->x; mod->ywheel = scroll_event->y; if (!mod->timeout_handler) { mod->timeout_handler = g_timeout_add_full (TIMEOUT_PRIORITY, mod->timeout_interval, swamigui_canvas_mod_timeout, mod, NULL); } } /* wheel previously scrolled in the same direction */ else mod->wheel_time = scroll_event->time - mod->last_wheel_time; /* get current time for wheel timeout tapering (can't use GDK event time * since there doesn't seem to be a way to arbitrarily get current value) */ g_get_current_time (&mod->last_wheel_real_time); mod->last_wheel_time = scroll_event->time; break; default: return (FALSE); } return (TRUE); } static guint swamigui_canvas_mod_get_actions (SwamiguiCanvasMod *mod, guint state) { gboolean zoom_mod, scroll_mod, axis_mod; guint actions = 0; zoom_mod = (state & mod->zoom_modifier) != 0; scroll_mod = (state & mod->scroll_modifier) != 0; axis_mod = (state & mod->axis_modifier) != 0; /* if ZOOM and SCROLL modifier not active - use default action */ if (!zoom_mod && !scroll_mod) { if (mod->def_action_zoom) zoom_mod = TRUE; else scroll_mod = TRUE; } if (zoom_mod) actions |= 1 << (mod->def_zoom_axis ^ axis_mod); if (scroll_mod) actions |= 1 << ((mod->def_scroll_axis ^ axis_mod) + 2); return (actions); } /* equation calculation for the zoom/scroll operation */ static double calc_val (SwamiguiCanvasMod *mod, double inp, SwamiguiCanvasModAxis axis, SwamiguiCanvasModType type) { SwamiguiCanvasModVars *vars; double val; vars = &mod->vars[axis][type]; val = vars->mult * pow (inp, vars->power) + vars->ofs; return (val); } /* timeout handler which is called at regular intervals to update active * zoom and or scroll */ static gboolean swamigui_canvas_mod_timeout (gpointer data) { SwamiguiCanvasMod *mod = SWAMIGUI_CANVAS_MOD (data); GdkModifierType state; GTimeVal curtime; int lastwheel; /* last wheel event time in milliseconds */ double wheeltaper; /* taper value for wheel timeout */ double val, inp, inpy; double xpos, ypos; guint actions; /* get current keyboard modifier state and resulting actions */ gdk_display_get_pointer (gdk_display_get_default (), NULL, NULL, NULL, &state); actions = swamigui_canvas_mod_get_actions (mod, state); mod->xzoom_amt = 1.0; mod->yzoom_amt = 1.0; mod->xscroll_amt = 0.0; mod->yscroll_amt = 0.0; /* mouse wheel operation is active */ if (mod->last_wheel_dir != WHEEL_INACTIVE) { inp = mod->wheel_timeout - mod->wheel_time; inp = CLAMP (inp, 0.0, mod->wheel_timeout); /* calculate the last wheel event time in milliseconds, unfortunately I * don't think we can get the current GDK event time, so we have to use * g_get_current_time(). */ g_get_current_time (&curtime); lastwheel = (curtime.tv_sec - mod->last_wheel_real_time.tv_sec) * 1000; if (curtime.tv_usec > mod->last_wheel_real_time.tv_usec) lastwheel += (curtime.tv_usec - mod->last_wheel_real_time.tv_usec + 500) / 1000; else lastwheel -= (mod->last_wheel_real_time.tv_usec - curtime.tv_usec + 500) / 1000; /* At end of wheel activity timeout? */ if (lastwheel >= mod->wheel_timeout) { mod->last_wheel_dir = WHEEL_INACTIVE; if (mod->snap_active) return (TRUE); /* keep timeout if snap active */ mod->timeout_handler = 0; return (FALSE); } /* wheel timeout taper multiplier (1.0 to 0.0) */ wheeltaper = 1.0 - (mod->wheel_timeout - lastwheel) / (double)(mod->wheel_timeout); if (actions & SWAMIGUI_CANVAS_MOD_ZOOM_X) { val = calc_val (mod, inp, SWAMIGUI_CANVAS_MOD_X, SWAMIGUI_CANVAS_MOD_WHEEL_ZOOM); mod->xzoom_amt = 1.0 + (val - 1.0) * wheeltaper; } if (actions & SWAMIGUI_CANVAS_MOD_ZOOM_Y) { val = calc_val (mod, inp, SWAMIGUI_CANVAS_MOD_Y, SWAMIGUI_CANVAS_MOD_WHEEL_ZOOM); mod->yzoom_amt = 1.0 + (val - 1.0) * wheeltaper; } if (actions & SWAMIGUI_CANVAS_MOD_SCROLL_X) { val = calc_val (mod, inp, SWAMIGUI_CANVAS_MOD_X, SWAMIGUI_CANVAS_MOD_WHEEL_SCROLL); mod->xscroll_amt = val * wheeltaper; } if (actions & SWAMIGUI_CANVAS_MOD_SCROLL_Y) { val = calc_val (mod, inp, SWAMIGUI_CANVAS_MOD_Y, SWAMIGUI_CANVAS_MOD_WHEEL_SCROLL); mod->yscroll_amt = val * wheeltaper; } /* set "direction" of values depending on wheel direction */ if (mod->last_wheel_dir == GDK_SCROLL_DOWN) { mod->xzoom_amt = 1.0 / mod->xzoom_amt; mod->yzoom_amt = 1.0 / mod->yzoom_amt; mod->xscroll_amt = -mod->xscroll_amt; /* y scroll is already inverted */ } else mod->yscroll_amt = -mod->yscroll_amt; /* yscroll is inverted */ xpos = mod->xwheel; ypos = mod->ywheel; } else /* snap is active */ { inp = ABS (mod->cur_xsnap - mod->xsnap); inpy = ABS (mod->cur_ysnap - mod->ysnap); /* short circuit 0 case (but keep timeout) */ if (inp == 0 && inpy == 0) return (TRUE); if (actions & SWAMIGUI_CANVAS_MOD_ZOOM_X) mod->xzoom_amt = calc_val (mod, inp, SWAMIGUI_CANVAS_MOD_X, SWAMIGUI_CANVAS_MOD_SNAP_ZOOM); if (actions & SWAMIGUI_CANVAS_MOD_ZOOM_Y) mod->yzoom_amt = calc_val (mod, inpy, SWAMIGUI_CANVAS_MOD_Y, SWAMIGUI_CANVAS_MOD_SNAP_ZOOM); if (actions & SWAMIGUI_CANVAS_MOD_SCROLL_X) mod->xscroll_amt = calc_val (mod, inp, SWAMIGUI_CANVAS_MOD_X, SWAMIGUI_CANVAS_MOD_SNAP_SCROLL); if (actions & SWAMIGUI_CANVAS_MOD_SCROLL_Y) mod->yscroll_amt = calc_val (mod, inpy, SWAMIGUI_CANVAS_MOD_Y, SWAMIGUI_CANVAS_MOD_SNAP_SCROLL); /* set "direction" of values depending on snap */ if (mod->cur_xsnap < mod->xsnap) { mod->xzoom_amt = 1.0 / mod->xzoom_amt; mod->yzoom_amt = 1.0 / mod->yzoom_amt; mod->xscroll_amt = -mod->xscroll_amt; /* y scroll is already inverted */ } else mod->yscroll_amt = -mod->yscroll_amt; /* yscroll is inverted */ xpos = mod->xsnap; ypos = mod->ysnap; } if (mod->xzoom_amt != 1.0 || mod->yzoom_amt != 1.0 || mod->xscroll_amt != 0.0 || mod->yscroll_amt != 0.0) { double interval = mod->timeout_interval / 1000.0; /* factor in interval so that zoom/scroll amounts are the same rate * regardless of timeout interval */ mod->xzoom_amt = pow (mod->xzoom_amt, interval); mod->yzoom_amt = pow (mod->yzoom_amt, interval); mod->xscroll_amt *= interval; mod->yscroll_amt *= interval; /* printf ("Update: xzoom:%f yzoom:%f xscroll:%f yscroll:%f xpos:%f ypos:%f\n", mod->xzoom_amt, mod->yzoom_amt, mod->xscroll_amt, mod->yscroll_amt, xpos, ypos); */ g_signal_emit (mod, signals[UPDATE_SIGNAL], 0, mod->xzoom_amt, mod->yzoom_amt, mod->xscroll_amt, mod->yscroll_amt, xpos, ypos); } /* keep timeout if wheel is active or snap is active */ if (mod->last_wheel_dir != WHEEL_INACTIVE || mod->snap_active) return (TRUE); mod->timeout_handler = 0; return (FALSE); } swami/src/swamigui/SwamiguiPythonView.h0000644000175000017500000000451011461334205020464 0ustar alessioalessio/* * SwamiguiPythonView.h - Header for python source viewer and shell. * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_PYTHON_VIEW_H__ #define __SWAMIGUI_PYTHON_VIEW_H__ #include #include typedef struct _SwamiguiPythonView SwamiguiPythonView; typedef struct _SwamiguiPythonViewClass SwamiguiPythonViewClass; #define SWAMIGUI_TYPE_PYTHON_VIEW (swamigui_python_view_get_type ()) #define SWAMIGUI_PYTHON_VIEW(obj) \ (GTK_CHECK_CAST ((obj), SWAMIGUI_TYPE_PYTHON_VIEW, SwamiguiPythonView)) #define SWAMIGUI_PYTHON_VIEW_CLASS(klass) \ (GTK_CHECK_CLASS_CAST ((klass), SWAMIGUI_TYPE_PYTHON_VIEW, \ SwamiguiPythonViewClass)) #define SWAMIGUI_IS_PYTHON_VIEW(obj) \ (GTK_CHECK_TYPE ((obj), SWAMIGUI_TYPE_PYTHON_VIEW)) #define SWAMIGUI_IS_PYTHON_VIEW_CLASS(klass) \ (GTK_CHECK_CLASS_TYPE ((klass), SWAMIGUI_TYPE_PYTHON_VIEW)) /* Swami Python view/shell object */ struct _SwamiguiPythonView { GtkVBox parent_instance; GtkWidget *glade_widg; /* toplevel glade widget for python editor */ GtkTextBuffer *srcbuf; /* source editor buffer (GtkSourceBuffer or GtkTextBuffer depending on support libs) */ GtkWidget *srcview; /* source editor GtkSourceView */ GtkTextBuffer *conbuf; /* python output text buffer */ GtkWidget *conview; /* python console GtkTextBuffer */ GtkWidget *comboscripts; /* scripts combo box */ }; /* Swami Python view/shell class */ struct _SwamiguiPythonViewClass { GtkVBoxClass parent_class; }; GType swamigui_python_view_get_type (void); GtkWidget *swamigui_python_view_new (); #endif swami/src/swamigui/SwamiguiPanelSelector.h0000644000175000017500000000530011461334205021106 0ustar alessioalessio/* * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ /** * SECTION: SwamiguiPanelSelector * @short_description: Panel user interface notebook selection widget * @see_also: #SwamiguiPanel * @stability: Stable * * Notebook widget which provides access to valid user interface panels for a * given item selection. */ #ifndef __SWAMIGUI_PANEL_SELECTOR_H__ #define __SWAMIGUI_PANEL_SELECTOR_H__ #include typedef struct _SwamiguiPanelSelector SwamiguiPanelSelector; typedef struct _SwamiguiPanelSelectorClass SwamiguiPanelSelectorClass; #define SWAMIGUI_TYPE_PANEL_SELECTOR (swamigui_panel_selector_get_type ()) #define SWAMIGUI_PANEL_SELECTOR(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMIGUI_TYPE_PANEL_SELECTOR, \ SwamiguiPanelSelector)) #define SWAMIGUI_PANEL_SELECTOR_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMIGUI_TYPE_PANEL_SELECTOR, \ SwamiguiPanelSelectorClass)) #define SWAMIGUI_IS_PANEL_SELECTOR(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMIGUI_TYPE_PANEL_SELECTOR)) #define SWAMIGUI_IS_PANEL_SELECTOR_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMIGUI_TYPE_PANEL_SELECTOR)) /* Panel user interface selection object */ struct _SwamiguiPanelSelector { GtkNotebook parent; /* derived from GtkNotebook */ /*< private >*/ IpatchList *selection; /* Item selection */ /* Active panel for each page (SwamiguiPanelInfo *), list does not own allocation */ GList *active_panels; }; /* Panel selector object class */ struct _SwamiguiPanelSelectorClass { GtkNotebookClass parent_class; }; GType *swamigui_get_panel_selector_types (void); void swamigui_register_panel_selector_type (GType panel_type, int order); GType swamigui_panel_selector_get_type (void); GtkWidget *swamigui_panel_selector_new (void); void swamigui_panel_selector_set_selection (SwamiguiPanelSelector *selector, IpatchList *items); IpatchList *swamigui_panel_selector_get_selection (SwamiguiPanelSelector *selector); #endif swami/src/swamigui/marshals.list0000644000175000017500000000243310600216501017172 0ustar alessioalessio# see glib-genmarshal(1) for a detailed description of the file format, # possible parameter types are: # VOID indicates no return type, or no extra # parameters. if VOID is used as the parameter # list, no additional parameters may be present. # BOOLEAN for boolean types (gboolean) # CHAR for signed char types (gchar) # UCHAR for unsigned char types (guchar) # INT for signed integer types (gint) # UINT for unsigned integer types (guint) # LONG for signed long integer types (glong) # ULONG for unsigned long integer types (gulong) # ENUM for enumeration types (gint) # FLAGS for flag enumeration types (guint) # FLOAT for single-precision float types (gfloat) # DOUBLE for double-precision float types (gdouble) # STRING for string types (gchar*) # PARAM for GParamSpec or derived types (GParamSpec*) # BOXED for boxed (anonymous but reference counted) types (GBoxed*) # POINTER for anonymous pointer types (gpointer) # OBJECT for GObject or derived types (GObject*) # NONE deprecated alias for VOID # BOOL deprecated alias for BOOLEAN VOID:DOUBLE,DOUBLE,DOUBLE,DOUBLE,DOUBLE,DOUBLE VOID:UINT,DOUBLE,DOUBLE swami/src/swamigui/SwamiguiPanel.c0000644000175000017500000001327011461334205017405 0ustar alessioalessio/* * SwamiguiPanel.c - Panel control interface type * For managing control interfaces in a plug-able way. * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include "SwamiguiPanel.h" static void swamigui_panel_interface_init (SwamiguiPanelIface *panel_iface); GType swamigui_panel_get_type (void) { static GType itype = 0; if (!itype) { static const GTypeInfo info = { sizeof (SwamiguiPanelIface), NULL, /* base_init */ NULL, /* base_finalize */ (GClassInitFunc) swamigui_panel_interface_init, (GClassFinalizeFunc) NULL }; itype = g_type_register_static (G_TYPE_INTERFACE, "SwamiguiPanel", &info, 0); } return (itype); } static void swamigui_panel_interface_init (SwamiguiPanelIface *panel_iface) { g_object_interface_install_property (panel_iface, g_param_spec_object ("item-selection", "Item Selection", "Item selection list", IPATCH_TYPE_LIST, G_PARAM_READWRITE)); } /** * swamigui_panel_type_get_info: * @type: Type with a #SwamiguiPanel interface to get info on * @label: Out - User panel label (short, could be %NULL) * @blurb: Out - User panel description (longer, for tool tips, could be %NULL) * @stockid: Out - Stock ID string of icon for this panel (could be %NULL) * * Lookup info on a panel for a given @type. A %NULL value can be passed for any * of the string parameters to ignore it. Note also that a %NULL value may * be returned for any of the return parameters. The returned parameters are * internal and should not be modified or freed. */ void swamigui_panel_type_get_info (GType type, char **label, char **blurb, char **stockid) { SwamiguiPanelIface *panel_iface; GObjectClass *klass; g_return_if_fail (g_type_is_a (type, SWAMIGUI_TYPE_PANEL)); klass = g_type_class_ref (type); /* ++ ref class */ g_return_if_fail (klass != NULL); panel_iface = g_type_interface_peek (klass, SWAMIGUI_TYPE_PANEL); if (!panel_iface) g_type_class_unref (klass); /* -- unref class */ g_return_if_fail (panel_iface != NULL); if (label) *label = panel_iface->label; if (blurb) *blurb = panel_iface->blurb; if (stockid) *stockid = panel_iface->stockid; g_type_class_unref (klass); /* -- unref class */ } /** * swamigui_panel_type_check_selection: * @type: Type with a #SwamiguiPanel interface * @selection: Item selection to test support for, list should not be empty * @selection_types: 0 terminated array of unique item types in @selection or * %NULL to calculate the array * * Checks if the panel with the given @type supports the item @selection. The * @selection_types parameter is for optimization purposes, so that panel types * can quickly check if they should be active or not based on the item types * in the selection (possibly saving another iteration of the @selection), this * array will be calculated if not supplied, so its only useful if checking * many panel types for a given @selection. * * Returns: %TRUE if panel supports selection, %FALSE otherwise */ gboolean swamigui_panel_type_check_selection (GType type, IpatchList *selection, GType *selection_types) { SwamiguiPanelIface *panel_iface; GType *free_selection_types = NULL; GObjectClass *klass; gboolean retval; g_return_val_if_fail (g_type_is_a (type, SWAMIGUI_TYPE_PANEL), FALSE); g_return_val_if_fail (IPATCH_IS_LIST (selection), FALSE); g_return_val_if_fail (selection->items != NULL, FALSE); klass = g_type_class_ref (type); /* ++ ref class */ g_return_val_if_fail (klass != NULL, FALSE); panel_iface = g_type_interface_peek (klass, SWAMIGUI_TYPE_PANEL); if (!panel_iface) g_type_class_unref (klass); /* -- unref class */ g_return_val_if_fail (panel_iface != NULL, FALSE); if (!panel_iface->check_selection) { g_type_class_unref (klass); /* -- unref class */ return (TRUE); } if (!selection_types) /* ++ alloc */ free_selection_types = swamigui_panel_get_types_in_selection (selection); retval = panel_iface->check_selection (selection, selection_types); g_free (free_selection_types); /* -- free */ g_type_class_unref (klass); /* -- unref class */ return (retval); } /** * swamigui_panel_get_types_in_selection: * @selection: Item selection list * * Gets an array of unique item types in @selection. * * Returns: Newly allocated and 0 terminated array of unique types of items * in @selection. */ GType * swamigui_panel_get_types_in_selection (IpatchList *selection) { GArray *typearray; GType type; GList *p; int i; typearray = g_array_new (TRUE, FALSE, sizeof (GType)); /* ++ alloc */ if (selection) { for (p = selection->items; p; p = p->next) { type = G_OBJECT_TYPE (p->data); for (i = 0; i < typearray->len; i++) if (g_array_index (typearray, GType, i) == type) break; if (i == typearray->len) g_array_append_val (typearray, type); } } return ((GType *)g_array_free (typearray, FALSE)); /* !! caller takes over allocation */ } swami/src/swamigui/help.h0000644000175000017500000000210411461334205015567 0ustar alessioalessio/* * help.h - Header for help related user interface functions. * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __HELP_H__ #define __HELP_H__ #include #include "SwamiguiRoot.h" void swamigui_help_about (void); void swamigui_help_swamitips_create (SwamiguiRoot *root); #endif /* __HELP_H__ */ swami/src/swamigui/SwamiguiSpectrumCanvas.c0000644000175000017500000005267511461334205021320 0ustar alessioalessio/* * SwamiguiSpectrumCanvas.c - Spectrum frequency canvas item * A canvas item for displaying frequency spectrum data * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include "SwamiguiSpectrumCanvas.h" #include "util.h" #include "i18n.h" enum { PROP_0, PROP_ADJUSTMENT, /* adjustment control */ PROP_X, /* x position in pixels */ PROP_Y, /* y position in pixels */ PROP_WIDTH, /* width of view in pixels */ PROP_HEIGHT, /* height of view in pixels */ PROP_START, /* spectrum start index */ PROP_ZOOM, /* zoom value */ PROP_ZOOM_AMPL /* amplitude zoom */ }; static void swamigui_spectrum_canvas_class_init (SwamiguiSpectrumCanvasClass *klass); static void swamigui_spectrum_canvas_init (SwamiguiSpectrumCanvas *canvas); static void swamigui_spectrum_canvas_finalize (GObject *object); static void swamigui_spectrum_canvas_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void swamigui_spectrum_canvas_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void swamigui_spectrum_canvas_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags); static void swamigui_spectrum_canvas_realize (GnomeCanvasItem *item); static void swamigui_spectrum_canvas_unrealize (GnomeCanvasItem *item); static void swamigui_spectrum_canvas_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, int height); static double swamigui_spectrum_canvas_point (GnomeCanvasItem *item, double x, double y, int cx, int cy, GnomeCanvasItem **actual_item); static void swamigui_spectrum_canvas_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2); static void swamigui_spectrum_canvas_cb_adjustment_value_changed (GtkAdjustment *adj, gpointer user_data); static void swamigui_spectrum_canvas_update_adjustment (SwamiguiSpectrumCanvas *canvas); static GObjectClass *parent_class = NULL; GType swamigui_spectrum_canvas_get_type (void) { static GType obj_type = 0; if (!obj_type) { static const GTypeInfo obj_info = { sizeof (SwamiguiSpectrumCanvasClass), NULL, NULL, (GClassInitFunc) swamigui_spectrum_canvas_class_init, NULL, NULL, sizeof (SwamiguiSpectrumCanvas), 0, (GInstanceInitFunc) swamigui_spectrum_canvas_init, }; obj_type = g_type_register_static (GNOME_TYPE_CANVAS_ITEM, "SwamiguiSpectrumCanvas", &obj_info, 0); } return (obj_type); } static void swamigui_spectrum_canvas_class_init (SwamiguiSpectrumCanvasClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); GnomeCanvasItemClass *item_class = GNOME_CANVAS_ITEM_CLASS (klass); parent_class = g_type_class_peek_parent (klass); obj_class->set_property = swamigui_spectrum_canvas_set_property; obj_class->get_property = swamigui_spectrum_canvas_get_property; obj_class->finalize = swamigui_spectrum_canvas_finalize; item_class->update = swamigui_spectrum_canvas_update; item_class->realize = swamigui_spectrum_canvas_realize; item_class->unrealize = swamigui_spectrum_canvas_unrealize; item_class->draw = swamigui_spectrum_canvas_draw; item_class->point = swamigui_spectrum_canvas_point; item_class->bounds = swamigui_spectrum_canvas_bounds; g_object_class_install_property (obj_class, PROP_ADJUSTMENT, g_param_spec_object ("adjustment", _("Adjustment"), _("Adjustment control for scrolling"), GTK_TYPE_ADJUSTMENT, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_X, g_param_spec_int ("x", "X", _("X position in pixels"), 0, G_MAXINT, 0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_Y, g_param_spec_int ("y", "Y", _("Y position in pixels"), 0, G_MAXINT, 0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_WIDTH, g_param_spec_int ("width", _("Width"), _("Width in pixels"), 0, G_MAXINT, 1, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_HEIGHT, g_param_spec_int ("height", _("Height"), _("Height in pixels"), 0, G_MAXINT, 1, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_START, g_param_spec_uint ("start", _("View start"), _("Start index of spectrum in view"), 0, G_MAXUINT, 0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_ZOOM, g_param_spec_double ("zoom", _("Zoom"), _("Zoom factor in indexes per pixel"), 0.0, G_MAXDOUBLE, 1.0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_ZOOM_AMPL, g_param_spec_double ("zoom-ampl", _("Zoom Amplitude"), _("Amplitude zoom factor"), 0.0, G_MAXDOUBLE, 1.0, G_PARAM_READWRITE)); /* g_object_class_install_property (obj_class, PROP_COLOR, g_param_spec_string ("color", _("Color"), _("Spectrum color"), NULL, G_PARAM_WRITABLE)); g_object_class_install_property (obj_class, PROP_COLOR_RGBA, g_param_spec_uint ("color-rgba", _("Color RGBA"), _("Spectrum color RGBA"), 0, G_MAXUINT, 0, G_PARAM_READWRITE)); */ } static void swamigui_spectrum_canvas_init (SwamiguiSpectrumCanvas *canvas) { canvas->adj = (GtkAdjustment *)gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0); g_object_ref (canvas->adj); canvas->update_adj = TRUE; g_signal_connect (canvas->adj, "value-changed", G_CALLBACK (swamigui_spectrum_canvas_cb_adjustment_value_changed), canvas); canvas->spectrum = NULL; canvas->max_value = 0.0; canvas->start = 0; canvas->zoom = 1.0; canvas->zoom_ampl = 1.0; canvas->x = 0; canvas->y = 0; canvas->width = 0; canvas->height = 0; } static void swamigui_spectrum_canvas_finalize (GObject *object) { SwamiguiSpectrumCanvas *canvas = SWAMIGUI_SPECTRUM_CANVAS (object); if (canvas->spectrum && canvas->notify) canvas->notify (canvas->spectrum, canvas->spectrum_size); if (canvas->adj) { g_signal_handlers_disconnect_by_func (canvas->adj, G_CALLBACK (swamigui_spectrum_canvas_cb_adjustment_value_changed), canvas); g_object_unref (canvas->adj); } if (canvas->bar_gc) g_object_unref (canvas->bar_gc); if (canvas->min_gc) g_object_unref (canvas->min_gc); if (canvas->max_gc) g_object_unref (canvas->max_gc); if (G_OBJECT_CLASS (parent_class)->finalize) G_OBJECT_CLASS (parent_class)->finalize (object); } static void swamigui_spectrum_canvas_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { GnomeCanvasItem *item = GNOME_CANVAS_ITEM (object); SwamiguiSpectrumCanvas *canvas = SWAMIGUI_SPECTRUM_CANVAS (object); GtkAdjustment *gtkadj; switch (property_id) { case PROP_ADJUSTMENT: gtkadj = g_value_get_object (value); g_return_if_fail (GTK_IS_ADJUSTMENT (gtkadj)); g_signal_handlers_disconnect_by_func (canvas->adj, G_CALLBACK (swamigui_spectrum_canvas_cb_adjustment_value_changed), canvas); g_object_unref (canvas->adj); canvas->adj = GTK_ADJUSTMENT (g_object_ref (gtkadj)); g_signal_connect (canvas->adj, "value-changed", G_CALLBACK (swamigui_spectrum_canvas_cb_adjustment_value_changed), canvas); /* only initialize adjustment if updates enabled */ if (canvas->update_adj) swamigui_spectrum_canvas_update_adjustment (canvas); break; case PROP_X: canvas->x = g_value_get_int (value); canvas->need_bbox_update = TRUE; gnome_canvas_item_request_update (item); break; case PROP_Y: canvas->y = g_value_get_int (value); canvas->need_bbox_update = TRUE; gnome_canvas_item_request_update (item); break; case PROP_WIDTH: canvas->width = g_value_get_int (value); canvas->need_bbox_update = TRUE; gnome_canvas_item_request_update (item); /* only update adjustment if updates enabled */ if (canvas->update_adj) { canvas->adj->page_size = canvas->width * canvas->zoom; gtk_adjustment_changed (canvas->adj); } break; case PROP_HEIGHT: canvas->height = g_value_get_int (value); canvas->need_bbox_update = TRUE; gnome_canvas_item_request_update (item); break; case PROP_START: canvas->start = g_value_get_uint (value); gnome_canvas_item_request_update (item); /* only update adjustment if updates enabled */ if (canvas->update_adj) { canvas->adj->value = canvas->start; g_signal_handlers_block_by_func (canvas->adj, swamigui_spectrum_canvas_cb_adjustment_value_changed, canvas); gtk_adjustment_value_changed (canvas->adj); g_signal_handlers_unblock_by_func (canvas->adj, swamigui_spectrum_canvas_cb_adjustment_value_changed, canvas); } break; case PROP_ZOOM: canvas->zoom = g_value_get_double (value); gnome_canvas_item_request_update (item); /* only update adjustment if updates enabled */ if (canvas->update_adj) { canvas->adj->page_size = canvas->width * canvas->zoom; gtk_adjustment_changed (canvas->adj); } break; case PROP_ZOOM_AMPL: canvas->zoom_ampl = g_value_get_double (value); gnome_canvas_item_request_update (item); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); return; /* return, to skip code below */ } } static void swamigui_spectrum_canvas_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { SwamiguiSpectrumCanvas *canvas = SWAMIGUI_SPECTRUM_CANVAS (object); switch (property_id) { case PROP_ADJUSTMENT: g_value_set_object (value, canvas->adj); break; case PROP_X: g_value_set_int (value, canvas->x); break; case PROP_Y: g_value_set_int (value, canvas->y); break; case PROP_WIDTH: g_value_set_int (value, canvas->width); break; case PROP_HEIGHT: g_value_set_int (value, canvas->height); break; case PROP_START: g_value_set_uint (value, canvas->start); break; case PROP_ZOOM: g_value_set_double (value, canvas->zoom); break; case PROP_ZOOM_AMPL: g_value_set_double (value, canvas->zoom_ampl); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } /* Gnome canvas item update handler */ static void swamigui_spectrum_canvas_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags) { SwamiguiSpectrumCanvas *canvas = SWAMIGUI_SPECTRUM_CANVAS (item); if (((flags & GNOME_CANVAS_UPDATE_VISIBILITY) && !(GTK_OBJECT_FLAGS (item) & GNOME_CANVAS_ITEM_VISIBLE)) || (flags & GNOME_CANVAS_UPDATE_AFFINE) || canvas->need_bbox_update) { canvas->need_bbox_update = FALSE; gnome_canvas_update_bbox (item, canvas->x, canvas->y, canvas->x + canvas->width, canvas->y + canvas->height); } else gnome_canvas_request_redraw (item->canvas, canvas->x, canvas->y, canvas->x + canvas->width, canvas->y + canvas->height); if (GNOME_CANVAS_ITEM_CLASS (parent_class)->update) GNOME_CANVAS_ITEM_CLASS (parent_class)->update (item, affine, clip_path, flags); } static void swamigui_spectrum_canvas_realize (GnomeCanvasItem *item) { SwamiguiSpectrumCanvas *canvas = SWAMIGUI_SPECTRUM_CANVAS (item); GdkColor bar_color = { 0x0, 0xFFFF, 0, 0 }; GdkColor min_color = { 0x0, 0, 0, 0xFFFF }; GdkColor max_color = { 0x0, 0, 0xFFFF, 0 }; if (GNOME_CANVAS_ITEM_CLASS (parent_class)->realize) (* GNOME_CANVAS_ITEM_CLASS (parent_class)->realize)(item); canvas->bar_gc = gdk_gc_new (item->canvas->layout.bin_window); /* ++ ref */ gdk_gc_set_rgb_fg_color (canvas->bar_gc, &bar_color); canvas->min_gc = gdk_gc_new (item->canvas->layout.bin_window); /* ++ ref */ gdk_gc_set_rgb_fg_color (canvas->min_gc, &min_color); canvas->max_gc = gdk_gc_new (item->canvas->layout.bin_window); /* ++ ref */ gdk_gc_set_rgb_fg_color (canvas->max_gc, &max_color); } static void swamigui_spectrum_canvas_unrealize (GnomeCanvasItem *item) { SwamiguiSpectrumCanvas *canvas = SWAMIGUI_SPECTRUM_CANVAS (item); if (canvas->bar_gc) gdk_gc_unref (canvas->bar_gc); if (canvas->min_gc) gdk_gc_unref (canvas->min_gc); if (canvas->max_gc) gdk_gc_unref (canvas->max_gc); canvas->bar_gc = NULL; canvas->min_gc = NULL; canvas->max_gc = NULL; if (GNOME_CANVAS_ITEM_CLASS (parent_class)->unrealize) GNOME_CANVAS_ITEM_CLASS (parent_class)->unrealize (item); } /* GnomeCanvas draws in 512 pixel squares, allocate some extra for overlap */ #define STATIC_POINTS 544 static void swamigui_spectrum_canvas_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, int height) { SwamiguiSpectrumCanvas *canvas = SWAMIGUI_SPECTRUM_CANVAS (item); GdkSegment static_segments[STATIC_POINTS]; GdkSegment *segments; GdkRectangle rect; int size, start, end, index, next_index; int height_1, height_1_ofs; double ampl_mul; double min, max, val; int xpos, ypos, xofs, yofs; if (!canvas->spectrum) return; /* set GC clipping rectangle */ rect.x = 0; rect.y = 0; rect.width = width; rect.height = height; size = canvas->spectrum_size; xofs = x - canvas->x; /* x co-ordinate relative to spectrum pos */ yofs = y - canvas->y; /* y co-ordinate relative to spectrum pos */ /* calculate start index */ start = canvas->start + xofs * canvas->zoom + 0.5; /* calculate end index */ end = canvas->start + (xofs + width) * canvas->zoom + 0.5; /* no spectrum in area? */ if (start >= size || end < 0) return; start = CLAMP (start, 0, size - 1); end = CLAMP (end, 0, size - 1); height_1 = canvas->height - 1; /* height - 1 */ height_1_ofs = height_1 - yofs; /* height - 1 corrected to current ofs */ /* spectrum amplitude multiplier */ ampl_mul = height_1 * (canvas->zoom_ampl / canvas->max_value); if (canvas->zoom >= 1.0) { gdk_gc_set_clip_origin (canvas->min_gc, 0, 0); gdk_gc_set_clip_rectangle (canvas->min_gc, &rect); gdk_gc_set_clip_origin (canvas->max_gc, 0, 0); gdk_gc_set_clip_rectangle (canvas->max_gc, &rect); /* use static segment array if there is enough, otherwise fall back on malloc (shouldn't get used, but just in case) */ if (width > STATIC_POINTS) segments = g_new (GdkSegment, width); else segments = static_segments; max = -G_MAXDOUBLE; next_index = canvas->start + (xofs + 1) * canvas->zoom + 0.5; /* draw maximum lines */ for (xpos = 0, index = start; xpos < width; xpos++) { for (; index < next_index && index < size; index++) { val = canvas->spectrum[index]; if (val > max) max = val; } segments[xpos].x1 = xpos; segments[xpos].x2 = xpos; segments[xpos].y1 = height_1_ofs - max * ampl_mul; segments[xpos].y2 = height_1_ofs; if (index >= size) break; next_index = canvas->start + (xofs + xpos + 2) * canvas->zoom + 0.5; max = -G_MAXDOUBLE; } gdk_draw_segments (drawable, canvas->max_gc, segments, xpos); min = G_MAXDOUBLE; next_index = canvas->start + (xofs + 1) * canvas->zoom + 0.5; /* draw minimum lines */ for (xpos = 0, index = start; xpos < width; xpos++) { for (; index < next_index && index < size; index++) { val = canvas->spectrum[index]; if (val < min) min = val; } segments[xpos].x1 = xpos; segments[xpos].x2 = xpos; segments[xpos].y1 = height_1_ofs - min * ampl_mul; segments[xpos].y2 = height_1_ofs; if (index >= size) break; next_index = canvas->start + (xofs + xpos + 2) * canvas->zoom + 0.5; min = G_MAXDOUBLE; } gdk_draw_segments (drawable, canvas->min_gc, segments, xpos); if (segments != static_segments) g_free (segments); } else /* zoom < 1.0 (do bars) */ { gdk_gc_set_clip_origin (canvas->bar_gc, 0, 0); gdk_gc_set_clip_rectangle (canvas->bar_gc, &rect); if (start > 0) start--; /* draw previous bar for overlap */ /* first xpos co-ordinate */ xpos = (start - (int)canvas->start) / canvas->zoom - xofs + 0.5; for (index = start; index <= end; index++) { ypos = height_1_ofs - canvas->spectrum[index] * ampl_mul; val = (index - canvas->start + 1) / canvas->zoom - xofs + 0.5; gdk_draw_rectangle (drawable, canvas->bar_gc, TRUE, xpos, ypos, val - xpos + 1, height_1_ofs - ypos + 1); xpos = val; } } } static double swamigui_spectrum_canvas_point (GnomeCanvasItem *item, double x, double y, int cx, int cy, GnomeCanvasItem **actual_item) { SwamiguiSpectrumCanvas *canvas = SWAMIGUI_SPECTRUM_CANVAS (item); double points[2*4]; points[0] = canvas->x; points[1] = canvas->y; points[2] = canvas->x + canvas->width; points[3] = points[1]; points[4] = points[0]; points[5] = canvas->y + canvas->height; points[6] = points[2]; points[7] = points[5]; *actual_item = item; return (gnome_canvas_polygon_to_point (points, 4, cx, cy)); } static void swamigui_spectrum_canvas_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2) { SwamiguiSpectrumCanvas *canvas = SWAMIGUI_SPECTRUM_CANVAS (item); *x1 = canvas->x; *y1 = canvas->y; *x2 = canvas->x + canvas->width; *y2 = canvas->y + canvas->height; } static void swamigui_spectrum_canvas_cb_adjustment_value_changed (GtkAdjustment *adj, gpointer user_data) { SwamiguiSpectrumCanvas *canvas = SWAMIGUI_SPECTRUM_CANVAS (user_data); guint start; canvas->update_adj = FALSE; /* disable adjustment updates to stop adjustment loop */ start = adj->value; g_object_set (canvas, "start", start, NULL); canvas->update_adj = TRUE; /* re-enable adjustment updates */ } /** * swamigui_spectrum_canvas_set_data: * @canvas: Spectrum data canvas item * @spectrum: Spectrum data pointer * @size: Size of @spectrum data (in values, not bytes) * @notify: Function callback for freeing @spectrum data when spectrum * canvas doesn't need it anymore. * * Set the spectrum data of a spectrum canvas item. */ void swamigui_spectrum_canvas_set_data (SwamiguiSpectrumCanvas *canvas, double *spectrum, guint size, SwamiguiSpectrumDestroyNotify notify) { g_return_if_fail (SWAMIGUI_IS_SPECTRUM_CANVAS (canvas)); g_return_if_fail (!spectrum || size > 0); double max = 0.0; int i; if (spectrum == canvas->spectrum) return; /* call destroy notify if spectrum and notify is set */ if (canvas->spectrum && canvas->notify) canvas->notify (canvas->spectrum, canvas->spectrum_size); canvas->spectrum = spectrum; canvas->spectrum_size = spectrum ? size : 0; canvas->notify = notify; /* find maximum value of spectrum */ for (i = size - 1; i >= 0; i--) { if (spectrum[i] > max) max = spectrum[i]; } canvas->max_value = max; swamigui_spectrum_canvas_update_adjustment (canvas); gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (canvas)); } static void swamigui_spectrum_canvas_update_adjustment (SwamiguiSpectrumCanvas *canvas) { canvas->adj->lower = 0.0; canvas->adj->upper = canvas->spectrum_size; canvas->adj->value = 0.0; canvas->adj->step_increment = canvas->spectrum_size / 400.0; canvas->adj->page_increment = canvas->spectrum_size / 50.0; canvas->adj->page_size = canvas->spectrum_size; gtk_adjustment_changed (canvas->adj); g_signal_handlers_block_by_func (canvas->adj, swamigui_spectrum_canvas_cb_adjustment_value_changed, canvas); gtk_adjustment_value_changed (canvas->adj); g_signal_handlers_unblock_by_func (canvas->adj, swamigui_spectrum_canvas_cb_adjustment_value_changed, canvas); } /** * swamigui_spectrum_canvas_pos_to_spectrum: * @canvas: Spectrum canvas item * @xpos: X pixel position * * Convert an X pixel position to spectrum index. * * Returns: Spectrum index or -1 if out of range. */ int swamigui_spectrum_canvas_pos_to_spectrum (SwamiguiSpectrumCanvas *canvas, int xpos) { int index; g_return_val_if_fail (SWAMIGUI_IS_SPECTRUM_CANVAS (canvas), -1); index = canvas->start + canvas->zoom * xpos; if (index < 0 || index > canvas->spectrum_size) return (-1); return (index); } /** * swamigui_spectrum_canvas_spectrum_to_pos: * @canvas: Spectrum canvas item * @index: Spectrum index * * Convert a spectrum index to x pixel position. * * Returns: X position, or -1 if out of view. */ int swamigui_spectrum_canvas_spectrum_to_pos (SwamiguiSpectrumCanvas *canvas, int index) { int xpos; g_return_val_if_fail (SWAMIGUI_IS_SPECTRUM_CANVAS (canvas), -1); if (index < canvas->start) return -1; /* index before view start? */ xpos = (index - canvas->start) / canvas->zoom + 0.5; return (xpos < canvas->width) ? xpos : -1; /* return if not after view end */ } swami/src/swamigui/SwamiguiPanelSF2GenMisc.h0000644000175000017500000000423111461334205021170 0ustar alessioalessio/* * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ /** * SECTION: SwamiguiPanelSF2GenMisc * @short_description: SoundFont envelope generator control panel * @see_also: * @stability: */ #ifndef __SWAMIGUI_PANEL_SF2_GEN_MISC_H__ #define __SWAMIGUI_PANEL_SF2_GEN_MISC_H__ #include #include typedef struct _SwamiguiPanelSF2GenMisc SwamiguiPanelSF2GenMisc; typedef struct _SwamiguiPanelSF2GenMiscClass SwamiguiPanelSF2GenMiscClass; #include #define SWAMIGUI_TYPE_PANEL_SF2_GEN_MISC (swamigui_panel_sf2_gen_misc_get_type ()) #define SWAMIGUI_PANEL_SF2_GEN_MISC(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMIGUI_TYPE_PANEL_SF2_GEN_MISC, \ SwamiguiPanelSF2GenMisc)) #define SWAMIGUI_PANEL_SF2_GEN_MISC_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMIGUI_TYPE_PANEL_SF2_GEN_MISC, \ SwamiguiPanelSF2GenMiscClass)) #define SWAMIGUI_IS_PANEL_SF2_GEN_MISC(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMIGUI_TYPE_PANEL_SF2_GEN_MISC)) #define SWAMIGUI_IS_PANEL_SF2_GEN_MISC_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMIGUI_TYPE_PANEL_SF2_GEN_MISC)) struct _SwamiguiPanelSF2GenMisc { SwamiguiPanelSF2Gen parent_instance; }; struct _SwamiguiPanelSF2GenMiscClass { SwamiguiPanelSF2GenClass parent_class; }; GType swamigui_panel_sf2_gen_misc_get_type (void); GtkWidget *swamigui_panel_sf2_gen_misc_new (void); #endif swami/src/swamigui/tools/0000755000175000017500000000000011716016657015644 5ustar alessioalessioswami/src/swamigui/tools/Makefile.am0000644000175000017500000000037507626502254017703 0ustar alessioalessio## Process this file with automake to produce Makefile.in ## Conditional compilation of cdump EXTRA_DIST = cdump.c # Only compile if SPLASH is enabled if SPLASH noinst_PROGRAMS = cdump cdump_SOURCES = cdump.c endif MAINTAINERCLEANFILES = Makefile.in swami/src/swamigui/tools/cdump.c0000644000175000017500000000410007626502254017111 0ustar alessioalessio/* Swami * * This file taken from: * AbiSource Build Tools * Copyright (C) 1998 AbiSource, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ #include #include long _getFileLength(const char* pszFileName) { long iLengthOfFile; FILE* fp = fopen(pszFileName, "rb"); if (!fp) { return -1; } if (0 != fseek(fp, 0, SEEK_END)) { fclose(fp); return -1; } iLengthOfFile = ftell(fp); fclose(fp); return iLengthOfFile; } long _readEntireFile(const char* pszFileName, unsigned char* pBytes, unsigned long iLen) { FILE* fp = fopen(pszFileName, "rb"); if (!fp) { return -1; } if (iLen != fread(pBytes, 1, iLen, fp)) { fclose(fp); return -1; } fclose(fp); return iLen; } void _dumpHexCBytes(FILE* fp, const unsigned char* pBytes, long iLen) { long i; for (i=0; i * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_NOTE_SELECTOR_H__ #define __SWAMIGUI_NOTE_SELECTOR_H__ #include #include typedef struct _SwamiguiNoteSelector SwamiguiNoteSelector; typedef struct _SwamiguiNoteSelectorClass SwamiguiNoteSelectorClass; #define SWAMIGUI_TYPE_NOTE_SELECTOR (swamigui_note_selector_get_type ()) #define SWAMIGUI_NOTE_SELECTOR(obj) \ (GTK_CHECK_CAST ((obj), SWAMIGUI_TYPE_NOTE_SELECTOR, SwamiguiNoteSelector)) #define SWAMIGUI_NOTE_SELECTOR_CLASS(klass) \ (GTK_CHECK_CLASS_CAST ((klass), SWAMIGUI_TYPE_NOTE_SELECTOR, \ SwamiguiNoteSelectorClass)) #define SWAMIGUI_IS_NOTE_SELECTOR(obj) \ (GTK_CHECK_TYPE ((obj), SWAMIGUI_TYPE_NOTE_SELECTOR)) #define SWAMIGUI_IS_NOTE_SELECTOR_CLASS(klass) \ (GTK_CHECK_CLASS_TYPE ((klass), SWAMIGUI_TYPE_NOTE_SELECTOR)) /* MIDI note selector widget */ struct _SwamiguiNoteSelector { GtkSpinButton parent_instance; }; /* MIDI note selector class */ struct _SwamiguiNoteSelectorClass { GtkSpinButtonClass parent_class; }; GType swamigui_note_selector_get_type (void); GtkWidget *swamigui_note_selector_new (); #endif swami/src/swamigui/SwamiguiModEdit.h0000644000175000017500000000515711461334205017705 0ustar alessioalessio/* * SwamiguiModEdit.h - User interface modulator editor object * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_MOD_EDIT_H__ #define __SWAMIGUI_MOD_EDIT_H__ #include #include #include typedef struct _SwamiguiModEdit SwamiguiModEdit; typedef struct _SwamiguiModEditClass SwamiguiModEditClass; #define SWAMIGUI_TYPE_MOD_EDIT (swamigui_mod_edit_get_type ()) #define SWAMIGUI_MOD_EDIT(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMIGUI_TYPE_MOD_EDIT, SwamiguiModEdit)) #define SWAMIGUI_MOD_EDIT_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMIGUI_TYPE_MOD_EDIT, \ SwamiguiModEditClass)) #define SWAMIGUI_IS_MOD_EDIT(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMIGUI_TYPE_MOD_EDIT)) #define SWAMIGUI_IS_MOD_EDIT_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMIGUI_TYPE_MOD_EDIT)) struct _SwamiguiModEdit { GtkScrolledWindow parent; IpatchList *selection; /* item selection or NULL (single item only) */ IpatchSF2ModList *mods; /* modulator list being edited (copy) */ SwamiControl *modctrl; /* "modulatos" property control */ GtkWidget *tree_view; /* tree view widget for modulator list */ GtkListStore *list_store; /* GtkTreeModel list store of modulator list */ gboolean mod_selected; /* modulator selected? (mod_iter is valid) */ GtkTreeIter mod_iter; /* modulator list node being edited */ GtkWidget *glade_widg; /* glade generated editor widget */ gboolean block_callbacks; /* blocks modulator editor callbacks */ GtkTreeStore *dest_store; /* destination combo box tree store */ }; struct _SwamiguiModEditClass { GtkScrolledWindowClass parent_class; }; GType swamigui_mod_edit_get_type (void); GtkWidget *swamigui_mod_edit_new (void); void swamigui_mod_edit_set_selection (SwamiguiModEdit *modedit, IpatchList *selection); #endif swami/src/swamigui/SwamiguiSplits.c0000644000175000017500000017751411461334205017640 0ustar alessioalessio/* * SwamiguiSplits.c - Key/velocity splits widget * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include "SwamiguiSplits.h" #include "SwamiguiControl.h" #include "SwamiguiPiano.h" #include "SwamiguiRoot.h" #include "SwamiguiStatusbar.h" #include "icons.h" #include "i18n.h" #include "util.h" enum { PROP_0, PROP_ITEM_SELECTION, PROP_SPLITS_ITEM, PROP_PIANO }; /* Value used for active_drag field in SwamiguiSplits which indicates the * current drag mode */ typedef enum { ACTIVE_NONE, /* Inactive drag */ ACTIVE_LOW, /* Dragging low handle of span */ ACTIVE_HIGH, /* Dragging upper handle of span */ ACTIVE_UNDECIDED, /* Not yet decided which handle of span to drag */ ACTIVE_MOVE, /* Moving span (both handles and possibly root note too) */ ACTIVE_ROOTNOTE /* Dragging root note */ } ActiveDrag; /* min/max width of piano/splits in pixels */ #define MIN_SPLITS_WIDTH SWAMIGUI_PIANO_DEFAULT_WIDTH #define MAX_SPLITS_WIDTH 2400 #define SPAN_DEFAULT_HEIGHT 12 /* span handle height in pixels */ #define SPAN_DEFAULT_SPACING 3 /* vertical spacing between spans in pixels */ #define MOVEMENT_THRESHOLD 3 /* pixels of mouse movement till threshold */ #define SPLIT_IS_SELECTED(entry) ((entry->flags & SPLIT_SELECTED) != 0) /* default colors */ #define DEFAULT_BG_COLOR GNOME_CANVAS_COLOR (255, 255, 178) #define DEFAULT_SPAN_COLOR GNOME_CANVAS_COLOR (0, 252, 113) #define DEFAULT_SPAN_OUTLINE_COLOR GNOME_CANVAS_COLOR (0, 0, 0) #define DEFAULT_SPAN_SEL_COLOR GNOME_CANVAS_COLOR (255, 13, 53) #define DEFAULT_SPAN_SEL_OUTLINE_COLOR DEFAULT_SPAN_SEL_COLOR #define DEFAULT_LINE_COLOR DEFAULT_SPAN_OUTLINE_COLOR #define DEFAULT_LINE_SEL_COLOR DEFAULT_SPAN_SEL_OUTLINE_COLOR #define DEFAULT_ROOT_NOTE_COLOR GNOME_CANVAS_COLOR (80, 80, 255) /* some flags for each split */ enum { SPLIT_SELECTED = 1 << 0, /* span is selected? */ }; /* structure for a single split */ struct _SwamiguiSplitsEntry { SwamiguiSplits *splits; /* parent split object */ int index; /* index of this entry in splits->entry_list */ GObject *item; /* item of this split */ IpatchRange range; /* current span range (MIDI note/velocity) */ guint rootnote_val; /* current root note number (if active) */ SwamiControl *span_control; /* span range control for this split or NULL */ SwamiControl *rootnote_control; /* root note control for this split or NULL */ gboolean destroyed; /* set to TRUE when a split has been destroyed */ int refcount; /* refcount of structure (held by span_control and rootnote_control) */ GnomeCanvasItem *span; /* span canvas item (GnomeCanvasRect) */ GnomeCanvasItem *lowline; /* low range endpoint vertical line */ GnomeCanvasItem *highline; /* high range endpoint vertical line */ GnomeCanvasItem *rootnote; /* root note circle indicator (GnomeCanvasEllipse) */ int flags; /* flags */ }; static void swamigui_splits_class_init (SwamiguiSplitsClass *klass); static void splits_cb_mode_btn_clicked (GtkButton *button, gpointer user_data); static void splits_cb_move_combo_changed (GtkComboBox *combo, gpointer user_data); static void swamigui_splits_cb_canvas_size_allocate (GtkWidget *widget, GtkAllocation *allocation, gpointer user_data); static void swamigui_splits_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void swamigui_splits_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void swamigui_splits_destroy (GtkObject *object); static void swamigui_splits_init (SwamiguiSplits *splits); static gboolean swamigui_splits_cb_low_canvas_event (GnomeCanvasItem *item, GdkEvent *event, gpointer data); static GList *swamigui_splits_get_split_at_pos (SwamiguiSplits *splits, int x, int y, int *index); static void swamigui_splits_update_status_bar (SwamiguiSplits *splits, int low, int high); static void swamigui_splits_span_control_get_func (SwamiControl *control, GValue *value); static void swamigui_splits_span_control_set_func (SwamiControl *control, SwamiControlEvent *event, const GValue *value); static void swamigui_splits_span_control_destroy_func (SwamiControlFunc *control); static void swamigui_splits_root_note_control_get_func (SwamiControl *control, GValue *value); static void swamigui_splits_root_note_control_set_func (SwamiControl *control, SwamiControlEvent *event, const GValue *value); static void swamigui_splits_root_note_control_destroy_func (SwamiControlFunc *control); static void swamigui_splits_deactivate_handler (SwamiguiSplits *splits); static SwamiguiSplitsEntry *swamigui_splits_create_entry (SwamiguiSplits *splits, GObject *item); static void swamigui_splits_destroy_entry (SwamiguiSplitsEntry *entry); static GList *swamigui_splits_lookup_item (SwamiguiSplits *splits, GObject *item); static void swamigui_splits_update_item_sel (SwamiguiSplitsEntry *entry); static void swamigui_splits_update_selection (SwamiguiSplits *splits); static gboolean swamigui_splits_real_set_selection (SwamiguiSplits *splits, IpatchList *items); static void swamigui_splits_update_entries (SwamiguiSplits *splits, GList *startp, gboolean width_change, gboolean height_change); static void swamigui_splits_entry_set_span_control (SwamiguiSplitsEntry *entry, int low, int high); static void swamigui_splits_entry_set_span (SwamiguiSplitsEntry *entry, int low, int high); static void swamigui_splits_entry_set_root_note_control (SwamiguiSplitsEntry *entry, int val); static void swamigui_splits_entry_set_root_note (SwamiguiSplitsEntry *entry, int val); static gboolean swamigui_splits_default_handler (SwamiguiSplits *splits); static GdkPixbuf *swamigui_splits_create_velocity_gradient (void); static void gradient_data_free (guchar *pixels, gpointer data); /* data */ static GObjectClass *parent_class = NULL; /* we lock handlers list since they can be registered outside GUI thread */ G_LOCK_DEFINE_STATIC (handlers); static GList *split_handlers = NULL; /* list of SwamiguiSplitsHandlers */ /* start and end velocity gradient colors */ static guint8 velbar_scolor[3] = { 0, 0, 0 }; static guint8 velbar_ecolor[3] = { 0, 0, 255 }; GType swamigui_splits_get_type (void) { static GType obj_type = 0; if (!obj_type) { static const GTypeInfo obj_info = { sizeof (SwamiguiSplitsClass), NULL, NULL, (GClassInitFunc) swamigui_splits_class_init, NULL, NULL, sizeof (SwamiguiSplits), 0, (GInstanceInitFunc) swamigui_splits_init, }; obj_type = g_type_register_static (GTK_TYPE_VBOX, "SwamiguiSplits", &obj_info, 0); } return (obj_type); } static void swamigui_splits_class_init (SwamiguiSplitsClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); GtkObjectClass *gtkobj_class = GTK_OBJECT_CLASS (klass); parent_class = g_type_class_peek_parent (klass); obj_class->set_property = swamigui_splits_set_property; obj_class->get_property = swamigui_splits_get_property; gtkobj_class->destroy = swamigui_splits_destroy; g_object_class_install_property (obj_class, PROP_ITEM_SELECTION, g_param_spec_object ("item-selection", "Item selection", "Item selection", IPATCH_TYPE_LIST, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_SPLITS_ITEM, g_param_spec_object ("splits-item", "Splits item", "Splits item", IPATCH_TYPE_ITEM, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_PIANO, g_param_spec_object ("piano", "Piano", "Piano", SWAMIGUI_TYPE_PIANO, G_PARAM_READABLE)); } static void swamigui_splits_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { SwamiguiSplits *splits = SWAMIGUI_SPLITS (object); IpatchList *items; GObject *obj; switch (property_id) { case PROP_ITEM_SELECTION: items = g_value_get_object (value); swamigui_splits_real_set_selection (splits, items); break; case PROP_SPLITS_ITEM: if (splits->splits_item) g_object_unref (splits->splits_item); obj = g_value_dup_object (value); splits->splits_item = obj ? IPATCH_ITEM (obj) : NULL; break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_splits_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { SwamiguiSplits *splits = SWAMIGUI_SPLITS (object); switch (property_id) { case PROP_ITEM_SELECTION: g_value_set_object (value, splits->selection); break; case PROP_SPLITS_ITEM: g_value_set_object (value, splits->splits_item); break; case PROP_PIANO: g_value_set_object (value, splits->piano); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_splits_destroy (GtkObject *object) { SwamiguiSplits *splits = SWAMIGUI_SPLITS (object); SwamiguiSplitsEntry *entry; GList *p; /* unref objects in entries (entries are freed in control destroy callback, since control events might still occur and they depend on entry and splits widget) */ p = splits->entry_list; while (p) { entry = (SwamiguiSplitsEntry *)(p->data); entry->destroyed = TRUE; if (entry->item) g_object_unref (entry->item); if (entry->span_control) swami_control_disconnect_unref (entry->span_control); if (entry->rootnote_control) swami_control_disconnect_unref (entry->rootnote_control); p = g_list_delete_link (p, p); } splits->entry_list = NULL; splits->entry_count = 0; /* free the selection */ if (splits->selection) { g_object_unref (splits->selection); splits->selection = NULL; } /* deactivate the handler */ splits->handler = NULL; splits->handler_data = NULL; if (GTK_OBJECT_CLASS (parent_class)->destroy) (*GTK_OBJECT_CLASS (parent_class)->destroy)(object); } static void swamigui_splits_init (SwamiguiSplits *splits) { GtkWidget *gladewidg; GtkWidget *scrollwin; GtkWidget *widg; GtkAdjustment *hadj, *vadj; GtkStyle *style; GdkPixbuf *pixbuf; splits->move_flags = SWAMIGUI_SPLITS_MOVE_RANGES; splits->anchor = -1; /* no split selection anchor set */ splits->active_drag = ACTIVE_NONE; /* no active click drag */ /* set default size values */ splits->height = SPAN_DEFAULT_HEIGHT; splits->width = -1; /* Invalid width, to force update */ splits->vert_lines_width = 1; splits->span_height = SPAN_DEFAULT_HEIGHT; splits->move_threshold = MOVEMENT_THRESHOLD; splits->span_spacing = SPAN_DEFAULT_SPACING; splits->bg_color = DEFAULT_BG_COLOR; splits->span_color = DEFAULT_SPAN_COLOR; splits->span_sel_color = DEFAULT_SPAN_SEL_COLOR; splits->span_outline_color = DEFAULT_SPAN_OUTLINE_COLOR; splits->span_sel_outline_color = DEFAULT_SPAN_SEL_OUTLINE_COLOR; splits->line_color = DEFAULT_LINE_COLOR; splits->line_sel_color = DEFAULT_LINE_SEL_COLOR; splits->root_note_color = DEFAULT_ROOT_NOTE_COLOR; splits->selection = ipatch_list_new (); /* ++ ref new list */ gladewidg = swamigui_util_glade_create ("SwamiguiSplits"); gtk_box_pack_start (GTK_BOX (splits), gladewidg, TRUE, TRUE, 0); splits->gladewidg = gladewidg; splits->notes_btn = swamigui_util_glade_lookup (gladewidg, "BtnNotes"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (splits->notes_btn), TRUE); g_signal_connect (splits->notes_btn, "clicked", G_CALLBACK (splits_cb_mode_btn_clicked), splits); widg = swamigui_util_glade_lookup (gladewidg, "BtnNotesImage"); gtk_image_set_from_stock (GTK_IMAGE (widg), SWAMIGUI_STOCK_PIANO, GTK_ICON_SIZE_SMALL_TOOLBAR); splits->velocity_btn = swamigui_util_glade_lookup (gladewidg, "BtnVelocity"); g_signal_connect (splits->velocity_btn, "clicked", G_CALLBACK (splits_cb_mode_btn_clicked), splits); widg = swamigui_util_glade_lookup (gladewidg, "BtnVelocityImage"); gtk_image_set_from_stock (GTK_IMAGE (widg), SWAMIGUI_STOCK_VELOCITY, GTK_ICON_SIZE_SMALL_TOOLBAR); splits->move_combo = swamigui_util_glade_lookup (gladewidg, "ComboMove"); gtk_combo_box_set_active (GTK_COMBO_BOX (splits->move_combo), 0); g_signal_connect (splits->move_combo, "changed", G_CALLBACK (splits_cb_move_combo_changed), splits); splits->vertical_scrollbar = swamigui_util_glade_lookup (gladewidg, "SplitsVScrollBar"); vadj = gtk_range_get_adjustment (GTK_RANGE (splits->vertical_scrollbar)); widg = swamigui_util_glade_lookup (gladewidg, "SplitsHScrollBar"); hadj = gtk_range_get_adjustment (GTK_RANGE (widg)); /* Set horizontal adjustment of upper scroll window to the horizontal scrollbar's */ scrollwin = swamigui_util_glade_lookup (gladewidg, "SplitsScrollWinUpper"); gtk_scrolled_window_set_hadjustment (GTK_SCROLLED_WINDOW (scrollwin), hadj); /* setup upper canvas */ splits->top_canvas = gnome_canvas_new (); gtk_widget_show (splits->top_canvas); gtk_container_add (GTK_CONTAINER (scrollwin), splits->top_canvas); gnome_canvas_set_center_scroll_region (GNOME_CANVAS (splits->top_canvas), FALSE); gtk_widget_set_size_request (splits->top_canvas, -1, SWAMIGUI_PIANO_DEFAULT_HEIGHT); g_signal_connect (splits->top_canvas, "size-allocate", G_CALLBACK (swamigui_splits_cb_canvas_size_allocate), splits); /* create piano canvas item */ splits->piano = SWAMIGUI_PIANO (gnome_canvas_item_new (gnome_canvas_root (GNOME_CANVAS (splits->top_canvas)), SWAMIGUI_TYPE_PIANO, NULL)); /* create velocity gradient canvas item */ pixbuf = swamigui_splits_create_velocity_gradient (); splits->velgrad = gnome_canvas_item_new (gnome_canvas_root (GNOME_CANVAS (splits->top_canvas)), GNOME_TYPE_CANVAS_PIXBUF, "pixbuf", pixbuf, "x", (double)0.0, "y", (double)0.0, "height", (double)SWAMIGUI_PIANO_DEFAULT_HEIGHT, "height-set", TRUE, "width-set", TRUE, NULL); gnome_canvas_item_hide (splits->velgrad); /* assign adjustments of lower scrolled window */ scrollwin = swamigui_util_glade_lookup (gladewidg, "SplitsScrollWinLower"); gtk_scrolled_window_set_hadjustment (GTK_SCROLLED_WINDOW (scrollwin), hadj); gtk_scrolled_window_set_vadjustment (GTK_SCROLLED_WINDOW (scrollwin), vadj); /* setup lower canvas */ splits->low_canvas = gnome_canvas_new (); gtk_widget_show (splits->low_canvas); gtk_container_add (GTK_CONTAINER (scrollwin), splits->low_canvas); gnome_canvas_set_center_scroll_region (GNOME_CANVAS (splits->low_canvas), FALSE); /* set background color of canvas to white */ style = gtk_style_copy (gtk_widget_get_style (splits->low_canvas)); style->bg[GTK_STATE_NORMAL] = style->white; gtk_widget_set_style (splits->low_canvas, style); /* create lower background rectangle (to catch events) */ splits->bgrect = gnome_canvas_item_new (gnome_canvas_root (GNOME_CANVAS (splits->low_canvas)), GNOME_TYPE_CANVAS_RECT, "fill-color-rgba", splits->bg_color, "x1", (double)0.0, "x2", (double)SWAMIGUI_PIANO_DEFAULT_WIDTH, "y1", (double)0.0, "y2", (double)splits->span_height, NULL); /* create vertical line group */ splits->vline_group = GNOME_CANVAS_GROUP (gnome_canvas_item_new (gnome_canvas_root (GNOME_CANVAS (splits->low_canvas)), GNOME_TYPE_CANVAS_GROUP, NULL)); // g_signal_connect (gnome_canvas_root (GNOME_CANVAS (splits->low_canvas)), g_signal_connect (splits->low_canvas, "event", G_CALLBACK (swamigui_splits_cb_low_canvas_event), splits); } /* callback when Notes or Velocity mode toggle button is clicked */ static void splits_cb_mode_btn_clicked (GtkButton *button, gpointer user_data) { SwamiguiSplits *splits = SWAMIGUI_SPLITS (user_data); g_signal_handlers_block_by_func (splits->notes_btn, splits_cb_mode_btn_clicked, splits); g_signal_handlers_block_by_func (splits->velocity_btn, splits_cb_mode_btn_clicked, splits); if ((GtkWidget *)button == splits->notes_btn) { gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (splits->notes_btn), TRUE); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (splits->velocity_btn), FALSE); swamigui_splits_set_mode (splits, SWAMIGUI_SPLITS_NOTE); } else { gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (splits->notes_btn), FALSE); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (splits->velocity_btn), TRUE); swamigui_splits_set_mode (splits, SWAMIGUI_SPLITS_VELOCITY); } g_signal_handlers_unblock_by_func (splits->notes_btn, splits_cb_mode_btn_clicked, splits); g_signal_handlers_unblock_by_func (splits->velocity_btn, splits_cb_mode_btn_clicked, splits); } /* Callback when move flags combo box is changed */ static void splits_cb_move_combo_changed (GtkComboBox *combo, gpointer user_data) { SwamiguiSplits *splits = SWAMIGUI_SPLITS (user_data); int index; index = gtk_combo_box_get_active (combo); switch (index) { case 0: splits->move_flags = SWAMIGUI_SPLITS_MOVE_RANGES; break; case 1: splits->move_flags = SWAMIGUI_SPLITS_MOVE_PARAM1; break; case 2: splits->move_flags = SWAMIGUI_SPLITS_MOVE_RANGES | SWAMIGUI_SPLITS_MOVE_PARAM1; break; } } static void swamigui_splits_cb_canvas_size_allocate (GtkWidget *widget, GtkAllocation *allocation, gpointer user_data) { SwamiguiSplits *splits = SWAMIGUI_SPLITS (user_data); if (!splits->width_set) { if (allocation->width < SWAMIGUI_PIANO_DEFAULT_WIDTH) allocation->width = SWAMIGUI_PIANO_DEFAULT_WIDTH; swamigui_splits_set_width (splits, allocation->width); } } static gboolean swamigui_splits_cb_low_canvas_event (GnomeCanvasItem *item, GdkEvent *event, gpointer data) { SwamiguiSplits *splits = SWAMIGUI_SPLITS (data); GdkEventButton *bevent; GdkEventMotion *mevent; SwamiguiSplitsEntry *entry, *selsplit; GList *p, *selsplitp; double dlow, dhigh; int index, i, low, high, note, noteofs; gboolean updatesel = FALSE; switch (event->type) { case GDK_SCROLL: /* forward the event to the vertical scroll bar */ gtk_widget_event (splits->vertical_scrollbar, event); return (TRUE); case GDK_BUTTON_PRESS: bevent = (GdkEventButton *)event; if (!(bevent->button >= 1 && bevent->button <= 3) || bevent->y < 0.0) break; p = swamigui_splits_get_split_at_pos (splits, bevent->x, bevent->y, &index); if (!p) return (FALSE); /* no split found? */ selsplit = (SwamiguiSplitsEntry *)(p->data); selsplitp = p; /* ALT-Click sets low range, root note and upper range for left, middle and right mouse buttons respectively */ if (bevent->state & GDK_MOD1_MASK) { note = swamigui_piano_pos_to_note (splits->piano, bevent->x, 0.0, NULL, NULL); splits->active_split = selsplitp; splits->active_drag_btn = bevent->button; if (bevent->button == 1 && selsplit->span) { swamigui_splits_entry_set_span_control (selsplit, note, selsplit->range.high); splits->active_drag = ACTIVE_LOW; } else if (bevent->button == 2 && selsplit->rootnote) { swamigui_splits_entry_set_root_note_control (selsplit, note); splits->active_drag = ACTIVE_ROOTNOTE; } else if (bevent->button == 3 && selsplit->span) { swamigui_splits_entry_set_span_control (selsplit, selsplit->range.low, note); splits->active_drag = ACTIVE_HIGH; } break; } if (bevent->button != 1 && bevent->button != 2) break; /* deselect all spans if CTRL or SHIFT not pressed */ if (!(bevent->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) && !(bevent->button == 2 && SPLIT_IS_SELECTED (selsplit))) { for (p = splits->entry_list; p; p = g_list_next (p)) { entry = (SwamiguiSplitsEntry *)(p->data); if (SPLIT_IS_SELECTED (entry)) { entry->flags &= ~SPLIT_SELECTED; swamigui_splits_update_item_sel (entry); updatesel = TRUE; } } } /* SHIFT key and an anchor? - select range */ if ((bevent->state & GDK_SHIFT_MASK) && splits->anchor != -1) { int select; if (splits->anchor < index) { low = splits->anchor; high = index; } else { low = index; high = splits->anchor; } i = -1; p = splits->entry_list; while (p) { entry = (SwamiguiSplitsEntry *)(p->data); p = g_list_next (p); i++; if (i >= low && i <= high) select = TRUE; else if (!(bevent->state & GDK_CONTROL_MASK)) select = FALSE; else continue; if (SPLIT_IS_SELECTED (entry) != select) { entry->flags ^= SPLIT_SELECTED; swamigui_splits_update_item_sel (entry); updatesel = TRUE; } } } else if (bevent->state & GDK_CONTROL_MASK) /* CTRL key? */ { selsplit->flags ^= SPLIT_SELECTED; /* toggle sel state */ swamigui_splits_update_item_sel (selsplit); updatesel = TRUE; splits->anchor = index; } else /* no CTRL or SHIFT, single select */ { if (!SPLIT_IS_SELECTED (selsplit)) { selsplit->flags |= SPLIT_SELECTED; swamigui_splits_update_item_sel (selsplit); updatesel = TRUE; } splits->anchor = index; /* not yet decided if to edit handle */ if (bevent->button == 1) { splits->active_drag = ACTIVE_UNDECIDED; splits->active_xpos = bevent->x; splits->active_drag_btn = 1; splits->threshold_value = 0.0; splits->active_split = selsplitp; } } if (updatesel) swamigui_splits_update_selection (splits); if (bevent->button == 2) /* middle click? */ { note = swamigui_piano_pos_to_note (splits->piano, bevent->x, 0.0, NULL, NULL); if (note == -1) return (FALSE); splits->active_drag = ACTIVE_MOVE; splits->active_drag_btn = 2; splits->active_split = selsplitp; if (!(splits->move_flags & SWAMIGUI_SPLITS_MOVE_RANGES) || !selsplit->span) splits->move_note_ofs = note - selsplit->rootnote_val; else splits->move_note_ofs = note - selsplit->range.low; /* note offset to low note range */ /* update statusbar */ swamigui_splits_update_status_bar (splits, selsplit->range.low, selsplit->range.high); return (FALSE); } break; case GDK_BUTTON_RELEASE: if (splits->active_drag == ACTIVE_NONE) return (FALSE); /* Same button released as caused the drag? */ if (splits->active_drag_btn == event->button.button) { splits->active_drag = ACTIVE_NONE; /* clear status bar */ swamigui_statusbar_msg_set_label (swamigui_root->statusbar, 0, "Global", NULL); } break; case GDK_MOTION_NOTIFY: mevent = (GdkEventMotion *)event; if (splits->active_drag == ACTIVE_NONE) { p = swamigui_splits_get_split_at_pos (splits, mevent->x, mevent->y, NULL); if (p) { entry = (SwamiguiSplitsEntry *)(p->data); swamigui_splits_update_status_bar (splits, entry->range.low, entry->range.high); } return (FALSE); } entry = (SwamiguiSplitsEntry *)(splits->active_split->data); /* still haven't decided which handle? */ if (splits->active_drag == ACTIVE_UNDECIDED) { /* has cursor moved beyond threshold? */ splits->threshold_value += ABS (mevent->x - splits->active_xpos); if (splits->threshold_value < splits->move_threshold) return (FALSE); /* find the edge closest to the original click */ dlow = swamigui_piano_note_to_pos (splits->piano, entry->range.low, -1, FALSE, NULL); dhigh = swamigui_piano_note_to_pos (splits->piano, entry->range.high, 1, FALSE, NULL); if (ABS (splits->active_xpos - dlow) <= ABS (splits->active_xpos - dhigh)) splits->active_drag = ACTIVE_LOW; /* select lower handle1 */ else splits->active_drag = ACTIVE_HIGH; /* select upper handle2 */ } if (mevent->x < 0.0) note = 0; else if (mevent->x > splits->piano->width) note = 127; else note = swamigui_piano_pos_to_note (splits->piano, mevent->x, 0.0, NULL, NULL); if (note == -1) return (FALSE); /* Handle root note move separately */ if (splits->active_drag == ACTIVE_ROOTNOTE) { swamigui_splits_update_status_bar (splits, note, -1); swamigui_splits_entry_set_root_note_control (entry, note); break; } /* Handle move separately (could be multiple items) */ if (splits->active_drag == ACTIVE_MOVE) { note -= splits->move_note_ofs; if (note < 0) note = 0; else if (note > 127) note = 127; /* If drag has not changed the current note offset, short cut */ if (((splits->move_flags & SWAMIGUI_SPLITS_MOVE_RANGES) && entry->range.low == note) || (entry->rootnote_val == note)) break; if (!(splits->move_flags & SWAMIGUI_SPLITS_MOVE_RANGES) || !entry->span) noteofs = note - entry->rootnote_val; else noteofs = note - entry->range.low; /* note offset to low note range */ /* Check if any spans/root notes would go out of range and clamp accordingly */ for (p = splits->entry_list; p && noteofs != 0; p = p->next) { entry = (SwamiguiSplitsEntry *)(p->data); if (!SPLIT_IS_SELECTED (entry)) continue; if ((splits->move_flags & SWAMIGUI_SPLITS_MOVE_RANGES) && entry->span) { if ((int)(entry->range.low) + noteofs < 0) noteofs = -entry->range.low; if ((int)(entry->range.high) + noteofs > 127) noteofs = 127 - entry->range.high; } if (entry->rootnote && (splits->move_flags & SWAMIGUI_SPLITS_MOVE_PARAM1)) { if ((int)(entry->rootnote_val) + noteofs < 0) noteofs = -entry->rootnote_val; if ((int)(entry->rootnote_val) + noteofs > 127) noteofs = 127 - entry->rootnote_val; } } if (noteofs == 0) break; /* Move the selected spans and/or root notes */ for (p = splits->entry_list; p; p = p->next) { entry = (SwamiguiSplitsEntry *)(p->data); if (!SPLIT_IS_SELECTED (entry)) continue; if ((splits->move_flags & SWAMIGUI_SPLITS_MOVE_RANGES) && entry->span) { swamigui_splits_entry_set_span_control (entry, entry->range.low + noteofs, entry->range.high + noteofs); if (entry == splits->active_split->data) swamigui_splits_update_status_bar (splits, entry->range.low, entry->range.high); } if (entry->rootnote && (splits->move_flags & SWAMIGUI_SPLITS_MOVE_PARAM1)) swamigui_splits_entry_set_root_note_control (entry, entry->rootnote_val + noteofs); } break; } low = entry->range.low; high = entry->range.high; switch (splits->active_drag) { case ACTIVE_LOW: /* lower handle? */ /* need to switch controlled handles? */ if (note > entry->range.high) { splits->active_drag = ACTIVE_HIGH; low = entry->range.high; high = note; } else low = note; break; case ACTIVE_HIGH: /* upper handle */ /* need to switch controlled handles? */ if (note < entry->range.low) { splits->active_drag = ACTIVE_LOW; high = entry->range.low; low = note; } else high = note; break; } if (low != entry->range.low || high != entry->range.high) { swamigui_splits_update_status_bar (splits, low, high); swamigui_splits_entry_set_span_control (entry, low, high); } break; default: break; } return (FALSE); } /* find a split at a given position */ static GList * swamigui_splits_get_split_at_pos (SwamiguiSplits *splits, int x, int y, int *index) { GList *p; int d, idx; if (index) *index = 0; /* click is at least greater than upper blank area? */ if (y <= splits->span_height) return (NULL); /* subtract blank area and half of spacing */ d = y - (splits->span_height - splits->span_spacing / 2); /* calculate span index */ idx = d / (splits->span_height + splits->span_spacing); /* calculate pixel offset in span */ d -= idx * (splits->span_height + splits->span_spacing); if (index) *index = idx; if (d < splits->span_height) /* click within span height? */ { p = g_list_nth (splits->entry_list, idx); if (p && ((SwamiguiSplitsEntry *)(p->data))->span_control) return (p); else return (NULL); } else return (NULL); } /* Update status bar message. Use high = -1 for root notes or other non-range * parameters */ static void swamigui_splits_update_status_bar (SwamiguiSplits *splits, int low, int high) { char lstr[5], hstr[5]; char *msg; if (splits->mode == SWAMIGUI_SPLITS_NOTE) { swami_util_midi_note_to_str (low, lstr); if (high != -1) { swami_util_midi_note_to_str (high, hstr); msg = g_strdup_printf (_("Range: %s:%s (%d-%d)"), lstr, hstr, low, high); } else msg = g_strdup_printf (_("Note: %s (%d)"), lstr, low); } else msg = g_strdup_printf (_("Range: %d-%d"), low, high); swamigui_statusbar_msg_set_label (swamigui_root->statusbar, 0, "Global", msg); g_free (msg); } /* SwamiControlFunc callback for getting a splits current range value */ static void swamigui_splits_span_control_get_func (SwamiControl *control, GValue *value) { SwamiguiSplitsEntry *entry = SWAMI_CONTROL_FUNC_DATA (control); if (entry->destroyed) return; ipatch_value_set_range (value, &entry->range); } /* SwamiControlFunc callback for setting a splits current range value */ static void swamigui_splits_span_control_set_func (SwamiControl *control, SwamiControlEvent *event, const GValue *value) { SwamiguiSplitsEntry *entry = SWAMI_CONTROL_FUNC_DATA (control); IpatchRange *range; if (entry->destroyed) return; range = ipatch_value_get_range (value); swamigui_splits_entry_set_span (entry, range->low, range->high); } /* SwamiControlFunc destroy callback. Things are tricky here because control events might still occur after a split has been destroyed. Therefore each control holds a reference to the splits widget and frees its entry as well (if no more entry->refcounts). */ static void swamigui_splits_span_control_destroy_func (SwamiControlFunc *control) { SwamiguiSplitsEntry *entry = SWAMI_CONTROL_FUNC_DATA (control); /* -- unref the control's held reference to the splits widget */ g_object_unref (entry->splits); /* free the entry if no more controls referencing it */ if (g_atomic_int_dec_and_test (&entry->refcount)) g_free (entry); } /* SwamiControlFunc callback for getting a root note current value */ static void swamigui_splits_root_note_control_get_func (SwamiControl *control, GValue *value) { SwamiguiSplitsEntry *entry = SWAMI_CONTROL_FUNC_DATA (control); if (entry->destroyed) return; g_value_set_int (value, entry->rootnote_val); } /* SwamiControlFunc callback for setting a root note current value */ static void swamigui_splits_root_note_control_set_func (SwamiControl *control, SwamiControlEvent *event, const GValue *value) { SwamiguiSplitsEntry *entry = SWAMI_CONTROL_FUNC_DATA (control); if (entry->destroyed) return; swamigui_splits_entry_set_root_note (entry, g_value_get_int (value)); } /* SwamiControlFunc destroy callback. Things are tricky here because control events might still occur after a split has been destroyed. Therefore each control holds a reference to the splits widget and frees its entry as well (if no more entry->refcounts). */ static void swamigui_splits_root_note_control_destroy_func (SwamiControlFunc *control) { SwamiguiSplitsEntry *entry = SWAMI_CONTROL_FUNC_DATA (control); /* -- unref the control's held reference to the splits widget */ g_object_unref (entry->splits); /* free the entry if no more controls referencing it */ if (g_atomic_int_dec_and_test (&entry->refcount)) g_free (entry); } /* internal functions */ /* unset any active split handler */ static void swamigui_splits_deactivate_handler (SwamiguiSplits *splits) { swamigui_splits_remove_all (splits); splits->handler = NULL; splits->handler_data = NULL; g_object_set (splits, "splits-item", NULL, NULL); } static SwamiguiSplitsEntry * swamigui_splits_create_entry (SwamiguiSplits *splits, GObject *item) { SwamiguiSplitsEntry *entry; entry = g_new0 (SwamiguiSplitsEntry, 1); entry->splits = splits; entry->index = 0; entry->item = g_object_ref (G_OBJECT (item)); entry->range.low = 0; entry->range.high = 127; entry->destroyed = FALSE; entry->refcount = 0; entry->flags = 0; /* not selected */ return (entry); } /* calls destroy on split widgets and unrefs objects */ static void swamigui_splits_destroy_entry (SwamiguiSplitsEntry *entry) { entry->destroyed = TRUE; if (entry->span) gtk_object_destroy (GTK_OBJECT (entry->span)); if (entry->lowline) gtk_object_destroy (GTK_OBJECT (entry->lowline)); if (entry->highline) gtk_object_destroy (GTK_OBJECT (entry->highline)); if (entry->rootnote) gtk_object_destroy (GTK_OBJECT (entry->rootnote)); if (entry->item) g_object_unref (entry->item); if (entry->span_control) swami_control_disconnect_unref (entry->span_control); if (entry->rootnote_control) swami_control_disconnect_unref (entry->rootnote_control); } /* lookup a entry GList pointer by item */ static GList * swamigui_splits_lookup_item (SwamiguiSplits *splits, GObject *item) { GList *p; p = splits->entry_list; while (p) { if (((SwamiguiSplitsEntry *)(p->data))->item == item) break; p = g_list_next (p); } return (p); } /* visually update a split's selected state */ static void swamigui_splits_update_item_sel (SwamiguiSplitsEntry *entry) { gboolean sel = SPLIT_IS_SELECTED (entry); SwamiguiSplits *splits = entry->splits; guint color; g_object_set (entry->span, "fill-color-rgba", sel ? splits->span_sel_color : splits->span_color, "outline-color-rgba", sel ? splits->span_sel_outline_color : splits->span_outline_color, NULL); if (sel) { gnome_canvas_item_raise_to_top (entry->lowline); gnome_canvas_item_raise_to_top (entry->highline); color = splits->line_sel_color; } else { gnome_canvas_item_lower_to_bottom (entry->lowline); gnome_canvas_item_lower_to_bottom (entry->highline); color = splits->line_color; } g_object_set (entry->lowline, "fill-color-rgba", color, NULL); g_object_set (entry->highline, "fill-color-rgba", color, NULL); } /* updates splits->selection based on currently selected splits and issues a property change notify on "item-selection" */ static void swamigui_splits_update_selection (SwamiguiSplits *splits) { SwamiguiSplitsEntry *entry; IpatchList *listobj; GList *list = NULL, *p; for (p = splits->entry_list; p; p = g_list_next (p)) { entry = (SwamiguiSplitsEntry *)(p->data); if (SPLIT_IS_SELECTED (entry)) { list = g_list_prepend (list, entry->item); g_object_ref (entry->item); /* ++ ref item for list obj */ } } list = g_list_reverse (list); listobj = ipatch_list_new (); /* ++ ref new list object */ listobj->items = list; if (splits->selection) g_object_unref (splits->selection); splits->selection = listobj; /* !! takes over list object reference */ g_object_notify (G_OBJECT (splits), "item-selection"); } /** * swamigui_splits_new: * * Create new note/velocity splits widget. * * Returns: New splits widget. */ GtkWidget * swamigui_splits_new (void) { return (GTK_WIDGET (gtk_type_new (swamigui_splits_get_type ()))); } /** * swamigui_splits_set_mode: * @splits: Splits object * @mode: Velocity or key mode enum * * Set the mode of a splits object. */ void swamigui_splits_set_mode (SwamiguiSplits *splits, SwamiguiSplitsMode mode) { g_return_if_fail (SWAMIGUI_IS_SPLITS (splits)); if (mode == splits->mode) return; splits->mode = mode; if (splits->mode == SWAMIGUI_SPLITS_VELOCITY) /* velocity mode? */ { gnome_canvas_item_hide (GNOME_CANVAS_ITEM (splits->piano)); gnome_canvas_item_show (splits->velgrad); } else /* note mode */ { gnome_canvas_item_hide (splits->velgrad); gnome_canvas_item_show (GNOME_CANVAS_ITEM (splits->piano)); } G_LOCK (handlers); if (splits->handler) { splits->status = SWAMIGUI_SPLITS_MODE; if (!(*splits->handler)(splits)) swamigui_splits_deactivate_handler (splits); splits->status = SWAMIGUI_SPLITS_NORMAL; } G_UNLOCK (handlers); } /** * swamigui_splits_set_width: * @splits: Splits object * @width: Width in pixels * * Set the width of the splits widget in pixels. */ void swamigui_splits_set_width (SwamiguiSplits *splits, int width) { if (width == splits->width) return; splits->width = width; /* update piano width */ g_object_set (splits->piano, "width-pixels", width, NULL); /* update velocity width */ g_object_set (splits->velgrad, "width", (double)width, NULL); swamigui_splits_update_entries (splits, splits->entry_list, TRUE, FALSE); } /** * swamigui_splits_set_selection: * @splits: Splits object * @items: List of selected items (selected splits and/or the parent of * split items) or %NULL to unset selection. * * Set the items of a splits widget. The @items list can contain * an item that is a parent of items with split parameters (a * SoundFont #IpatchSF2Preset or IpatchSF2Inst for example) and/or a list * of children split item's with the same parent (for example * SoundFont #IpatchSF2PZone items), any other selection list will de-activate * the splits widget. */ void swamigui_splits_set_selection (SwamiguiSplits *splits, IpatchList *items) { if (swamigui_splits_real_set_selection (splits, items)) g_object_notify (G_OBJECT (splits), "item-selection"); } static gboolean swamigui_splits_real_set_selection (SwamiguiSplits *splits, IpatchList *items) { SwamiguiSplitsHandler hfunc; GList *p; g_return_val_if_fail (SWAMIGUI_IS_SPLITS (splits), FALSE); g_return_val_if_fail (!items || IPATCH_IS_LIST (items), FALSE); if (splits->selection) g_object_unref (splits->selection); /* -- unref old */ if (items) splits->selection = ipatch_list_duplicate (items); /* ++ ref */ else splits->selection = NULL; G_LOCK (handlers); if (splits->handler) /* active handler? */ { splits->status = SWAMIGUI_SPLITS_UPDATE; if (!items || !(*splits->handler)(splits)) swamigui_splits_deactivate_handler (splits); } if (items && !splits->handler) /* re-test in case it was de-activated */ { splits->status = SWAMIGUI_SPLITS_INIT; p = split_handlers; while (p) /* try handlers */ { hfunc = (SwamiguiSplitsHandler)(p->data); if ((*hfunc)(splits)) /* selection handled? */ { splits->handler = hfunc; break; } p = g_list_next (p); } } G_UNLOCK (handlers); if (!splits->handler) /* no handler found? - Try default. */ { if (swamigui_splits_default_handler (splits)) splits->handler = swamigui_splits_default_handler; } splits->status = SWAMIGUI_SPLITS_NORMAL; return (TRUE); } /** * swamigui_splits_get_selection: * @splits: Splits widget * * Get the list of active items in a splits widget (a parent of split items * and/or split items). * * Returns: New list containing splits with a ref count of one which the * caller owns or %NULL if no active splits. */ IpatchList * swamigui_splits_get_selection (SwamiguiSplits *splits) { g_return_val_if_fail (SWAMIGUI_IS_SPLITS (splits), NULL); if (splits->selection) return (ipatch_list_duplicate (splits->selection)); else return (NULL); } /** * swamigui_splits_select_items: * @splits: Splits widget * @items: List of objects to select (%NULL to unselect all) * * Set the list of splits currently selected. Usually only used by * #SwamiguiSplit handlers. */ void swamigui_splits_select_items (SwamiguiSplits *splits, GList *items) { SwamiguiSplitsEntry *entry; GHashTable *hash; gboolean sel; GList *p; g_return_if_fail (SWAMIGUI_IS_SPLITS (splits)); /* hash the item list for speed in the case of large split lists */ hash = g_hash_table_new (NULL, NULL); for (p = items; p; p = p->next) g_hash_table_insert (hash, p->data, GUINT_TO_POINTER (TRUE)); for (p = splits->entry_list; p; p = g_list_next (p)) { entry = (SwamiguiSplitsEntry *)(p->data); sel = GPOINTER_TO_UINT (g_hash_table_lookup (hash, entry->item)); if (sel != SPLIT_IS_SELECTED (entry)) { if (sel) entry->flags |= SPLIT_SELECTED; else entry->flags &= ~SPLIT_SELECTED; swamigui_splits_update_item_sel (entry); } } } /** * swamigui_splits_select_all: * @splits: Splits widget * * Select all splits in a splits widget. */ void swamigui_splits_select_all (SwamiguiSplits *splits) { SwamiguiSplitsEntry *entry; GList *p; g_return_if_fail (SWAMIGUI_IS_SPLITS (splits)); for (p = splits->entry_list; p; p = g_list_next (p)) { entry = (SwamiguiSplitsEntry *)(p->data); if (!SPLIT_IS_SELECTED (entry)) { entry->flags |= SPLIT_SELECTED; swamigui_splits_update_item_sel (entry); } } } /** * swamigui_splits_unselect_all: * @splits: Splits widget * * Unselect all splits in a splits widget. */ void swamigui_splits_unselect_all (SwamiguiSplits *splits) { SwamiguiSplitsEntry *entry; GList *p; g_return_if_fail (SWAMIGUI_IS_SPLITS (splits)); for (p = splits->entry_list; p; p = g_list_next (p)) { entry = (SwamiguiSplitsEntry *)(p->data); if (SPLIT_IS_SELECTED (entry)) { entry->flags &= ~SPLIT_SELECTED; swamigui_splits_update_item_sel (entry); } } } /** * swamigui_splits_item_changed: * @splits: Splits widget * * Called to indicate that the active "splits-item" has changed and the splits * should therefore be updated. */ void swamigui_splits_item_changed (SwamiguiSplits *splits) { g_return_if_fail (SWAMIGUI_IS_SPLITS (splits)); if (!splits->handler) return; splits->status = SWAMIGUI_SPLITS_CHANGED; if (!splits->handler (splits)) swamigui_splits_deactivate_handler (splits); } /** * swamigui_splits_register_handler: * @handler: Splits handler function to register * * Registers a new handler for splits widgets. Split handlers interface * patch item's of particular types with note/velocity split parameters and * note pointer controls (such as a root note parameter). * * MT: This function is multi-thread safe and can be called from outside * of the GUI thread. */ void swamigui_splits_register_handler (SwamiguiSplitsHandler handler) { g_return_if_fail (handler != NULL); G_LOCK (handlers); split_handlers = g_list_prepend (split_handlers, handler); G_UNLOCK (handlers); } /** * swamigui_splits_unregister_handler: * @handler: Handler function to unregister * * Unregisters a handler previously registered with * swamigui_splits_register_handler(). * * MT: This function is multi-thread safe and can be called from outside * of the GUI thread. */ void swamigui_splits_unregister_handler (SwamiguiSplitsHandler handler) { g_return_if_fail (handler != NULL); G_LOCK (handlers); split_handlers = g_list_remove (split_handlers, handler); G_UNLOCK (handlers); } /** * swamigui_splits_insert: * @splits: Splits widget * @item: Object for this split * @index: Index in list of existing splits in widget (-1 to append). * * Adds a new entry to a splits widget associated with a given object * @item. An entry is a place holder for a split range (key or velocity) * and/or root note controls. * * Returns: Splits entry which is internal and should only be used with * public accessor functions and should not be modified or freed. */ SwamiguiSplitsEntry * swamigui_splits_insert (SwamiguiSplits *splits, GObject *item, int index) { SwamiguiSplitsEntry *entry; GList *p; g_return_val_if_fail (SWAMIGUI_IS_SPLITS (splits), NULL); g_return_val_if_fail (IPATCH_IS_ITEM (item), NULL); entry = swamigui_splits_create_entry (splits, item); if (index < 0 || index >= splits->entry_count) /* Append? */ { index = splits->entry_count; splits->entry_list = g_list_append (splits->entry_list, entry); p = NULL; } else { p = g_list_nth (splits->entry_list, index); splits->entry_list = g_list_insert_before (splits->entry_list, p, entry); } entry->index = index; splits->entry_count++; /* increment the split count */ splits->height += splits->span_height + splits->span_spacing; /* update splits total height */ swamigui_splits_update_entries (splits, p, FALSE, TRUE); return (entry); } /* Update geometry of items in relation to entry changes or width change. * Also updates entry->index values */ static void swamigui_splits_update_entries (SwamiguiSplits *splits, GList *startp, gboolean width_change, gboolean height_change) { GnomeCanvasPoints *lpoints; double xpos1, xpos2, ypos1, ypos2, halfwidth; SwamiguiSplitsEntry *entry; int index; GList *p; /* update lower canvas background rectangle */ if (width_change && height_change) g_object_set (splits->bgrect, "x2", (double)splits->width, "y2", (double)splits->height, NULL); else if (width_change) g_object_set (splits->bgrect, "x2", (double)splits->width, NULL); else g_object_set (splits->bgrect, "y2", (double)splits->height, NULL); lpoints = gnome_canvas_points_new (2); /* line points */ if (startp && startp->prev) index = ((SwamiguiSplitsEntry *)(startp->prev->data))->index + 1; else index = 0; /* top of starting span to update */ ypos1 = splits->span_height + (index * (splits->span_height + splits->span_spacing)); /* update splits */ for (p = startp; p; p = p->next, index++) { entry = (SwamiguiSplitsEntry *)(p->data); entry->index = index; if (entry->span) { xpos1 = swamigui_piano_note_to_pos (splits->piano, entry->range.low, -1, FALSE, NULL); xpos2 = swamigui_piano_note_to_pos (splits->piano, entry->range.high, 1, FALSE, NULL); if (width_change && height_change) g_object_set (entry->span, "x1", xpos1, "x2", xpos2, "y1", ypos1, "y2", ypos1 + splits->span_height, NULL); else if (width_change) g_object_set (entry->span, "x1", xpos1, "x2", xpos2, NULL); else g_object_set (entry->span, "y1", ypos1, "y2", ypos1 + splits->span_height, NULL); lpoints->coords[1] = 0.0; lpoints->coords[3] = ypos1 + splits->span_height; /* set the low and high vertical line coordinates */ lpoints->coords[0] = lpoints->coords[2] = xpos1; g_object_set (entry->lowline, "points", lpoints, NULL); lpoints->coords[0] = lpoints->coords[2] = xpos2; g_object_set (entry->highline, "points", lpoints, NULL); } if (entry->rootnote) { xpos1 = swamigui_piano_note_to_pos (splits->piano, entry->rootnote_val, 0, FALSE, NULL); ypos2 = ypos1 + splits->span_height; /* Bottom of span */ halfwidth = splits->span_height / 2.0 - 2.0; g_object_set (entry->rootnote, "x1", xpos1 - halfwidth, "x2", xpos1 + halfwidth, "y1", ypos1 + 2.0, "y2", ypos2 - 2.0, NULL); } ypos1 += splits->span_height + splits->span_spacing; } gnome_canvas_points_free (lpoints); if (width_change) gnome_canvas_set_scroll_region (GNOME_CANVAS (splits->top_canvas), 0, 0, splits->width, SWAMIGUI_PIANO_DEFAULT_HEIGHT); gnome_canvas_set_scroll_region (GNOME_CANVAS (splits->low_canvas), 0, 0, splits->width, splits->height); } /** * swamigui_splits_remove: * @splits: Splits widget * @item: Object of split to remove * * Remove a split from a splits object by its associated object. */ void swamigui_splits_remove (SwamiguiSplits *splits, GObject *item) { SwamiguiSplitsEntry *entry; GList *lookup_item, *p; g_return_if_fail (SWAMIGUI_IS_SPLITS (splits)); g_return_if_fail (IPATCH_IS_ITEM (item)); /* lookup the entry by item */ lookup_item = swamigui_splits_lookup_item (splits, item); g_return_if_fail (lookup_item != NULL); p = lookup_item->next; /* advance to item after */ entry = (SwamiguiSplitsEntry *)(lookup_item->data); splits->entry_list = g_list_delete_link (splits->entry_list, lookup_item); swamigui_splits_destroy_entry (entry); /* destroy entry */ splits->entry_count--; /* decrement split count */ /* update splits total height */ splits->height -= splits->span_height + splits->span_spacing; swamigui_splits_update_entries (splits, p, FALSE, TRUE); } /** * swamigui_splits_remove_all: * @splits: Splits widget * * Remove all splits from a splits object. */ void swamigui_splits_remove_all (SwamiguiSplits *splits) { GList *p; g_return_if_fail (SWAMIGUI_IS_SPLITS (splits)); p = splits->entry_list; while (p) { swamigui_splits_destroy_entry ((SwamiguiSplitsEntry *)(p->data)); p = g_list_delete_link (p, p); } splits->entry_list = NULL; splits->entry_count = 0; /* update total split height (just upper blank region now) */ splits->height = splits->span_height; swamigui_splits_update_entries (splits, NULL, FALSE, TRUE); } /** * swamigui_splits_set_span_range: * @splits: Splits object * @item: Item of span to set * @low: Low value of span range * @high: High value of span range * * A convenience function to set a span control range. One could also * set this directly via the control. */ void swamigui_splits_set_span_range (SwamiguiSplits *splits, GObject *item, int low, int high) { SwamiguiSplitsEntry *entry; GList *lookup_item; g_return_if_fail (SWAMIGUI_IS_SPLITS (splits)); g_return_if_fail (IPATCH_IS_ITEM (item)); g_return_if_fail (low <= high); g_return_if_fail (low >= 0 && high <= 127); lookup_item = swamigui_splits_lookup_item (splits, item); g_return_if_fail (lookup_item != NULL); entry = (SwamiguiSplitsEntry *)(lookup_item->data); swamigui_splits_entry_set_span_control (entry, low, high); } /* sets a split span widget range and transmits the change on its control also */ static void swamigui_splits_entry_set_span_control (SwamiguiSplitsEntry *entry, int low, int high) { IpatchRange range; GValue value = { 0 }; if (low == entry->range.low && high == entry->range.high) return; swamigui_splits_entry_set_span (entry, low, high); /* transmit the change via the range control */ range.low = low; range.high = high; g_value_init (&value, IPATCH_TYPE_RANGE); ipatch_value_set_range (&value, &range); swami_control_transmit_value (entry->span_control, &value); } /* sets a split span widget range */ static void swamigui_splits_entry_set_span (SwamiguiSplitsEntry *entry, int low, int high) { double pos1, pos2, ypos; GnomeCanvasPoints *points; SwamiguiSplits *splits = entry->splits; entry->range.low = low; entry->range.high = high; pos1 = swamigui_piano_note_to_pos (entry->splits->piano, low, -1, FALSE, NULL); pos2 = swamigui_piano_note_to_pos (entry->splits->piano, high, 1, FALSE, NULL); ypos = splits->span_height + (entry->index * (splits->span_height + splits->span_spacing)); g_object_set (entry->span, "x1", pos1, "x2", pos2, NULL); /* set low and high vertical line coordinates */ points = gnome_canvas_points_new (2); points->coords[1] = 0.0; points->coords[3] = ypos; points->coords[0] = points->coords[2] = pos1; g_object_set (entry->lowline, "points", points, NULL); points->coords[0] = points->coords[2] = pos2; g_object_set (entry->highline, "points", points, NULL); gnome_canvas_points_free (points); } /** * swamigui_splits_set_root_note: * @splits: Splits widget * @item: Item of the splits entry to change the root note of * @val: MIDI root note value (0-127) * * A convenience function to set the root note value of a splits entry. */ void swamigui_splits_set_root_note (SwamiguiSplits *splits, GObject *item, int val) { SwamiguiSplitsEntry *entry; GList *lookup_item; g_return_if_fail (SWAMIGUI_IS_SPLITS (splits)); g_return_if_fail (IPATCH_IS_ITEM (item)); g_return_if_fail (val >= 0 && val <= 127); lookup_item = swamigui_splits_lookup_item (splits, item); g_return_if_fail (lookup_item != NULL); entry = (SwamiguiSplitsEntry *)(lookup_item->data); swamigui_splits_entry_set_root_note_control (entry, val); } /* sets a split root note widget range and transmits the change on its control also */ static void swamigui_splits_entry_set_root_note_control (SwamiguiSplitsEntry *entry, int val) { GValue value = { 0 }; if (val == entry->rootnote_val) return; swamigui_splits_entry_set_root_note (entry, val); /* transmit the change via the control */ g_value_init (&value, G_TYPE_INT); g_value_set_int (&value, val); swami_control_transmit_value (entry->rootnote_control, &value); } /* sets a split root note widget value */ static void swamigui_splits_entry_set_root_note (SwamiguiSplitsEntry *entry, int val) { SwamiguiSplits *splits = entry->splits; double xpos, ypos1, ypos2, halfwidth; g_return_if_fail (entry->rootnote != NULL); entry->rootnote_val = val; /* top of starting span to update */ ypos1 = splits->span_height + (entry->index * (splits->span_height + splits->span_spacing)); xpos = swamigui_piano_note_to_pos (splits->piano, val, 0, FALSE, NULL); ypos2 = ypos1 + splits->span_height; /* Bottom of span */ halfwidth = splits->span_height / 2.0 - 2.0; g_object_set (entry->rootnote, "x1", xpos - halfwidth, "x2", xpos + halfwidth, "y1", ypos1 + 2.0, "y2", ypos2 - 2.0, NULL); } /** * swamigui_splits_entry_get_split_control: * @entry: Splits entry pointer * * Get the span control for a given splits entry. The span control is * created if it hasn't already been and is used for controlling a note or * velocity range. * * Returns: The split control for the given @entry. The control has not been * referenced and is only valid while the GUI split exists. */ SwamiControl * swamigui_splits_entry_get_span_control (SwamiguiSplitsEntry *entry) { GnomeCanvasGroup *root; GnomeCanvasPoints *points; SwamiguiSplits *splits; double ypos; g_return_val_if_fail (entry != NULL, NULL); if (entry->span_control) return (entry->span_control); splits = entry->splits; root = gnome_canvas_root (GNOME_CANVAS (entry->splits->low_canvas)); g_object_ref (entry->splits); /* ++ ref the splits object for the control */ g_atomic_int_inc (&entry->refcount); /* ++ ref entry structure for span_control */ /* create control for span range (++ ref new object) */ entry->span_control = swamigui_control_new (SWAMI_TYPE_CONTROL_FUNC); swami_control_set_spec (entry->span_control, g_param_spec_boxed ("value", "value", "value", IPATCH_TYPE_RANGE, G_PARAM_READWRITE)); swami_control_func_assign_funcs (SWAMI_CONTROL_FUNC (entry->span_control), swamigui_splits_span_control_get_func, swamigui_splits_span_control_set_func, swamigui_splits_span_control_destroy_func, entry); ypos = splits->span_height + (entry->index * (splits->span_height + splits->span_spacing)); entry->span = gnome_canvas_item_new (root, GNOME_TYPE_CANVAS_RECT, "fill-color-rgba", entry->splits->span_color, "outline-color-rgba", entry->splits->span_outline_color, "x1", 0.0, "x2", (double)(entry->splits->piano->width), "y1", ypos, "y2", ypos + splits->span_height, NULL); /* set coordinates of low and high range vertical lines */ points = gnome_canvas_points_new (2); points->coords[1] = 0.0; points->coords[3] = ypos + splits->span_height; points->coords[0] = points->coords[2] = 0.0; entry->lowline = gnome_canvas_item_new (entry->splits->vline_group, GNOME_TYPE_CANVAS_LINE, "fill-color-rgba", entry->splits->line_color, "width-pixels", 1, "points", points, NULL); points->coords[0] = points->coords[2] = splits->piano->width; entry->highline = gnome_canvas_item_new (entry->splits->vline_group, GNOME_TYPE_CANVAS_LINE, "fill-color-rgba", entry->splits->line_color, "width-pixels", 1, "points", points, NULL); gnome_canvas_points_free (points); return (entry->span_control); } /** * swamigui_splits_entry_get_root_note_control: * @entry: Splits entry pointer * * Get the root note control for a given splits entry. The root note control is * created if it hasn't already been. * * Returns: The root note control for the given @entry. The control has not been * referenced and is only valid while the GUI split exists. */ SwamiControl * swamigui_splits_entry_get_root_note_control (SwamiguiSplitsEntry *entry) { GnomeCanvasGroup *root; g_return_val_if_fail (entry != NULL, NULL); if (entry->rootnote_control) return (entry->rootnote_control); g_object_ref (entry->splits); /* ++ ref the splits object for the control */ g_atomic_int_inc (&entry->refcount); /* ++ ref entry structure for rootnote_control */ root = gnome_canvas_root (GNOME_CANVAS (entry->splits->low_canvas)); entry->rootnote_control = swamigui_control_new (SWAMI_TYPE_CONTROL_FUNC); swami_control_set_spec (entry->rootnote_control, g_param_spec_int ("value", "value", "value", 0, 127, 60, G_PARAM_READWRITE)); swami_control_set_value_type (entry->rootnote_control, G_TYPE_INT); swami_control_func_assign_funcs (SWAMI_CONTROL_FUNC (entry->rootnote_control), swamigui_splits_root_note_control_get_func, swamigui_splits_root_note_control_set_func, swamigui_splits_root_note_control_destroy_func, entry); entry->rootnote = gnome_canvas_item_new (root, GNOME_TYPE_CANVAS_ELLIPSE, "fill-color-rgba", entry->splits->root_note_color, NULL); gnome_canvas_item_raise_to_top (entry->rootnote); return (entry->rootnote_control); } /* default splits handler */ static gboolean swamigui_splits_default_handler (SwamiguiSplits *splits) { SwamiguiSplitsEntry *entry; SwamiControl *span_ctrl, *prop_ctrl, *rootnote_ctrl; IpatchItem *splitsobj = NULL; IpatchList *children; IpatchIter iter; GValue value = { 0 }; IpatchRange *range; const GType *types; GObject *obj; GList *sel = NULL; int splits_type; GObjectClass *klass; if (splits->status != SWAMIGUI_SPLITS_INIT && splits->status != SWAMIGUI_SPLITS_UPDATE && splits->status != SWAMIGUI_SPLITS_MODE && splits->status != SWAMIGUI_SPLITS_CHANGED) return (TRUE); if (!splits->selection) return (FALSE); ipatch_list_init_iter (splits->selection, &iter); obj = ipatch_iter_first (&iter); if (!obj) return (FALSE); /* either a single object with its "splits-type" type property set or multiple items with the same parent which has a "splits-type" property are handled */ ipatch_type_object_get (obj, "splits-type", &splits_type, NULL); /* does not have splits-type set? */ if (splits_type == IPATCH_SPLITS_NONE) { if (!IPATCH_IS_ITEM (obj)) return (FALSE); /* not handled if !IpatchItem */ splitsobj = ipatch_item_get_parent (IPATCH_ITEM (obj)); /* ++ ref parent */ if (!splitsobj) return (FALSE); /* no parent, not handled */ /* check if parent type supports splits, unhandled if not */ ipatch_type_object_get (G_OBJECT (splitsobj), "splits-type", &splits_type, NULL); if (splits_type == IPATCH_SPLITS_NONE) { g_object_unref (splitsobj); /* -- unref parent */ return (FALSE); } sel = g_list_prepend (sel, obj); /* add to selection list */ while ((obj = ipatch_iter_next (&iter))) { /* selection unhandled if not IpatchItem or parent not the same */ if (!IPATCH_IS_ITEM (obj) || ipatch_item_peek_parent ((IpatchItem *)obj) != splitsobj) { g_list_free (sel); g_object_unref (splitsobj); /* -- unref parent */ return (FALSE); } sel = g_list_prepend (sel, obj); /* add to selection list */ } } /* item has splits-type set, selection unhandled if there is another item */ else { if (ipatch_iter_next (&iter)) return (FALSE); splitsobj = g_object_ref (obj); /* ++ ref to even things up */ } /* clear and update splits if init, mode change or update with different obj */ if (splits->status != SWAMIGUI_SPLITS_UPDATE || splits->splits_item != splitsobj) { swamigui_splits_remove_all (splits); /* set splits-item */ g_object_set (splits, "splits-item", splitsobj, NULL); types = ipatch_container_get_child_types (IPATCH_CONTAINER (splitsobj)); for (; *types; types++) /* loop over child types */ { /* Verify this child type has velocity or note range property */ if (splits->mode == SWAMIGUI_SPLITS_VELOCITY) { klass = g_type_class_peek (*types); if (!klass || !g_object_class_find_property (klass, "velocity-range")) continue; } else { klass = g_type_class_peek (*types); if (!klass || !g_object_class_find_property (klass, "note-range")) continue; } /* ++ ref new list */ children = ipatch_container_get_children (IPATCH_CONTAINER (splitsobj), *types); ipatch_list_init_iter (children, &iter); obj = ipatch_iter_first (&iter); for (; obj; obj = ipatch_iter_next (&iter)) /* loop over child items */ { g_value_init (&value, IPATCH_TYPE_RANGE); if (splits->mode == SWAMIGUI_SPLITS_VELOCITY) g_object_get_property (obj, "velocity-range", &value); else g_object_get_property (obj, "note-range", &value); range = ipatch_value_get_range (&value); /* skip objects with NULL range */ if (range->low == -1 && range->high == -1) { g_value_unset (&value); continue; } entry = swamigui_splits_add (splits, obj); /* add a new entry */ span_ctrl = swamigui_splits_entry_get_span_control (entry); /* set current value of span, we do this instead of using the SWAMI_CONTROL_CONN_INIT flag, since we already read the value */ swami_control_set_value (span_ctrl, &value); /* ++ ref new key range property control */ if (splits->mode == SWAMIGUI_SPLITS_VELOCITY) prop_ctrl = swami_get_control_prop_by_name (obj, "velocity-range"); else prop_ctrl = swami_get_control_prop_by_name (obj, "note-range"); /* connect the key range property control to the span control */ swami_control_connect (prop_ctrl, span_ctrl, SWAMI_CONTROL_CONN_BIDIR); g_object_unref (prop_ctrl); /* -- unref property control */ g_value_unset (&value); /* Add root note indicator if NOTE splits mode and has root-note property */ if (splits->mode == SWAMIGUI_SPLITS_NOTE && g_object_class_find_property (klass, "root-note")) { rootnote_ctrl = swamigui_splits_entry_get_root_note_control (entry); prop_ctrl = swami_get_control_prop_by_name (obj, "root-note"); /* ++ ref property control */ swami_control_connect (prop_ctrl, rootnote_ctrl, SWAMI_CONTROL_CONN_BIDIR | SWAMI_CONTROL_CONN_INIT); g_object_unref (prop_ctrl); /* -- unref prop control */ } } /* while (obj) */ g_object_unref (children); /* -- unref children list */ } /* for (; *types; types++) */ } g_object_unref (splitsobj); /* -- unref splits object */ swamigui_splits_select_items (splits, sel); g_list_free (sel); return (TRUE); } static GdkPixbuf * swamigui_splits_create_velocity_gradient (void) { guchar *linebuf; /* generated gradient image data */ float rval, gval, bval; float rinc, ginc, binc; gint i; /* allocate buffer space for one line of velocity bar (128 levels * RGB) */ linebuf = g_new (guchar, 128 * 3); rval = velbar_scolor[0]; gval = velbar_scolor[1]; bval = velbar_scolor[2]; rinc = (float) (velbar_ecolor[0] - rval + 1) / 128; ginc = (float) (velbar_ecolor[1] - gval + 1) / 128; binc = (float) (velbar_ecolor[2] - bval + 1) / 128; /* generate the gradient image data */ for (i = 0; i < 128 * 3;) { linebuf[i++] = rval + 0.5; linebuf[i++] = gval + 0.5; linebuf[i++] = bval + 0.5; rval += rinc; gval += ginc; bval += binc; } return (gdk_pixbuf_new_from_data (linebuf, GDK_COLORSPACE_RGB, FALSE, 8, 128, 1, 128 * 3, gradient_data_free, NULL)); } static void gradient_data_free (guchar *pixels, gpointer data) { g_free (pixels); } swami/src/swamigui/SwamiguiPanelSF2GenEnv.c0000644000175000017500000000736311461334205021031 0ustar alessioalessio/* * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include #include "SwamiguiControl.h" #include "SwamiguiPanelSF2GenEnv.h" #include "SwamiguiPanel.h" #include "SwamiguiRoot.h" #include "SwamiguiSpinScale.h" #include "icons.h" #include "util.h" #include "i18n.h" SwamiguiPanelSF2GenCtrlInfo sf2_gen_env_ctrl_info[] = { { SWAMIGUI_PANEL_SF2_GEN_LABEL, N_("Volume Envelope") }, { IPATCH_SF2_GEN_VOL_ENV_DELAY, SWAMIGUI_STOCK_VOLENV_DELAY }, { IPATCH_SF2_GEN_VOL_ENV_ATTACK, SWAMIGUI_STOCK_VOLENV_ATTACK }, { IPATCH_SF2_GEN_VOL_ENV_HOLD, SWAMIGUI_STOCK_VOLENV_HOLD }, { IPATCH_SF2_GEN_VOL_ENV_DECAY, SWAMIGUI_STOCK_VOLENV_DECAY }, { IPATCH_SF2_GEN_VOL_ENV_SUSTAIN, SWAMIGUI_STOCK_VOLENV_SUSTAIN }, { IPATCH_SF2_GEN_VOL_ENV_RELEASE, SWAMIGUI_STOCK_VOLENV_RELEASE }, { IPATCH_SF2_GEN_ATTENUATION, GTK_STOCK_CONNECT }, { IPATCH_SF2_GEN_NOTE_TO_VOL_ENV_HOLD, GTK_STOCK_CONNECT }, { IPATCH_SF2_GEN_NOTE_TO_VOL_ENV_DECAY, GTK_STOCK_CONNECT }, { SWAMIGUI_PANEL_SF2_GEN_COLUMN, NULL }, { SWAMIGUI_PANEL_SF2_GEN_LABEL, N_("Modulation Envelope") }, { IPATCH_SF2_GEN_MOD_ENV_DELAY, SWAMIGUI_STOCK_MODENV_DELAY }, { IPATCH_SF2_GEN_MOD_ENV_ATTACK, SWAMIGUI_STOCK_MODENV_ATTACK }, { IPATCH_SF2_GEN_MOD_ENV_HOLD, SWAMIGUI_STOCK_MODENV_HOLD }, { IPATCH_SF2_GEN_MOD_ENV_DECAY, SWAMIGUI_STOCK_MODENV_DECAY }, { IPATCH_SF2_GEN_MOD_ENV_SUSTAIN, SWAMIGUI_STOCK_MODENV_SUSTAIN }, { IPATCH_SF2_GEN_MOD_ENV_RELEASE, SWAMIGUI_STOCK_MODENV_RELEASE }, { IPATCH_SF2_GEN_MOD_ENV_TO_PITCH, GTK_STOCK_CONNECT }, { IPATCH_SF2_GEN_MOD_ENV_TO_FILTER_CUTOFF, GTK_STOCK_CONNECT }, { IPATCH_SF2_GEN_NOTE_TO_MOD_ENV_HOLD, GTK_STOCK_CONNECT }, { IPATCH_SF2_GEN_NOTE_TO_MOD_ENV_DECAY, GTK_STOCK_CONNECT }, { SWAMIGUI_PANEL_SF2_GEN_END, NULL } }; static void swamigui_panel_sf2_gen_env_panel_iface_init (SwamiguiPanelIface *panel_iface); G_DEFINE_TYPE_WITH_CODE (SwamiguiPanelSF2GenEnv, swamigui_panel_sf2_gen_env, SWAMIGUI_TYPE_PANEL_SF2_GEN, G_IMPLEMENT_INTERFACE (SWAMIGUI_TYPE_PANEL, swamigui_panel_sf2_gen_env_panel_iface_init)); static void swamigui_panel_sf2_gen_env_class_init (SwamiguiPanelSF2GenEnvClass *klass) { } static void swamigui_panel_sf2_gen_env_panel_iface_init (SwamiguiPanelIface *panel_iface) { panel_iface->label = _("Envelopes"); panel_iface->blurb = _("Controls for SoundFont envelope parameters"); panel_iface->stockid = SWAMIGUI_STOCK_VOLENV; } static void swamigui_panel_sf2_gen_env_init (SwamiguiPanelSF2GenEnv *genpanel) { swamigui_panel_sf2_gen_set_controls (SWAMIGUI_PANEL_SF2_GEN (genpanel), sf2_gen_env_ctrl_info); } /** * swamigui_panel_sf2_gen_env_new: * * Create a new generator control panel object. * * Returns: new widget of type #SwamiguiPanelSF2GenEnv */ GtkWidget * swamigui_panel_sf2_gen_env_new (void) { return (GTK_WIDGET (gtk_type_new (swamigui_panel_sf2_gen_env_get_type ()))); } swami/src/swamigui/SwamiguiTreeStore.h0000644000175000017500000001032011461334205020260 0ustar alessioalessio/* * SwamiguiTreeStore.h - Swami item tree store object * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_TREE_STORE_H__ #define __SWAMIGUI_TREE_STORE_H__ typedef struct _SwamiguiTreeStore SwamiguiTreeStore; typedef struct _SwamiguiTreeStoreClass SwamiguiTreeStoreClass; #include #define SWAMIGUI_TYPE_TREE_STORE (swamigui_tree_store_get_type ()) #define SWAMIGUI_TREE_STORE(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMIGUI_TYPE_TREE_STORE, \ SwamiguiTreeStore)) #define SWAMIGUI_TREE_STORE_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMIGUI_TYPE_TREE_STORE, \ SwamiguiTreeStoreClass)) #define SWAMIGUI_IS_TREE_STORE(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMIGUI_TYPE_TREE_STORE)) #define SWAMIGUI_IS_TREE_STORE_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMIGUI_TYPE_TREE_STORE)) #define SWAMIGUI_TREE_STORE_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), SWAMIGUI_TYPE_TREE_STORE, \ SwamiguiTreeStoreClass)) /* Swami GUI tree store object */ struct _SwamiguiTreeStore { GtkTreeStore parent_instance; /* derived from GtkTreeStore */ GHashTable *item_hash; /* hash of GObject -> GtkTreeIter* */ GtkTreeIter devices; /* "Devices" top level tree node */ GtkTreeIter layouts; /* "Layouts" top level tree node */ GtkTreeIter samples; /* "Samples" top level tree node */ }; /* Swami GUI tree store class */ struct _SwamiguiTreeStoreClass { GtkTreeStoreClass parent_class; void (*item_add)(SwamiguiTreeStore *store, GObject *item); void (*item_changed)(SwamiguiTreeStore *store, GObject *item); }; /* GtkTreeStore columns */ enum { SWAMIGUI_TREE_STORE_LABEL_COLUMN, /* label column */ SWAMIGUI_TREE_STORE_ICON_COLUMN, /* pointer (static string) */ SWAMIGUI_TREE_STORE_OBJECT_COLUMN, /* pointer to patch item (invisible) */ SWAMIGUI_TREE_STORE_NUM_COLUMNS }; /* some developer targeted error messages */ #define SWAMIGUI_TREE_ERRMSG_PARENT_NOT_IN_TREE "Parent not in tree store" #define SWAMIGUI_TREE_ERRMSG_ITEM_NOT_IN_TREE "Item not in tree store" GType swamigui_tree_store_get_type (void); void swamigui_tree_store_insert (SwamiguiTreeStore *store, GObject *item, const char *label, char *icon, GtkTreeIter *parent, int pos, GtkTreeIter *out_iter); void swamigui_tree_store_insert_before (SwamiguiTreeStore *store, GObject *item, const char *label, char *icon, GtkTreeIter *parent, GtkTreeIter *sibling, GtkTreeIter *out_iter); void swamigui_tree_store_insert_after (SwamiguiTreeStore *store, GObject *item, const char *label, char *icon, GtkTreeIter *parent, GtkTreeIter *sibling, GtkTreeIter *out_iter); void swamigui_tree_store_change (SwamiguiTreeStore *store, GObject *item, const char *label, char *icon); void swamigui_tree_store_remove (SwamiguiTreeStore *store, GObject *item); void swamigui_tree_store_move_before (SwamiguiTreeStore *store, GObject *item, GtkTreeIter *position); void swamigui_tree_store_move_after (SwamiguiTreeStore *store, GObject *item, GtkTreeIter *position); gboolean swamigui_tree_store_item_get_node (SwamiguiTreeStore *store, GObject *item, GtkTreeIter *iter); GObject *swamigui_tree_store_node_get_item (SwamiguiTreeStore *store, GtkTreeIter *iter); void swamigui_tree_store_add (SwamiguiTreeStore *store, GObject *item); void swamigui_tree_store_changed (SwamiguiTreeStore *store, GObject *item); #endif swami/src/swamigui/SwamiguiSampleCanvas.h0000644000175000017500000000741311461334205020732 0ustar alessioalessio/* * SwamiguiSampleCanvas.h - Sample data canvas item * A canvas item for sample data * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMIGUI_SAMPLE_CANVAS_H__ #define __SWAMIGUI_SAMPLE_CANVAS_H__ #include #include #include typedef struct _SwamiguiSampleCanvas SwamiguiSampleCanvas; typedef struct _SwamiguiSampleCanvasClass SwamiguiSampleCanvasClass; #define SWAMIGUI_TYPE_SAMPLE_CANVAS (swamigui_sample_canvas_get_type ()) #define SWAMIGUI_SAMPLE_CANVAS(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMIGUI_TYPE_SAMPLE_CANVAS, \ SwamiguiSampleCanvas)) #define SWAMIGUI_SAMPLE_CANVAS_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMIGUI_TYPE_SAMPLE_CANVAS, \ SwamiguiSampleCanvasClass)) #define SWAMIGUI_IS_SAMPLE_CANVAS(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMIGUI_TYPE_SAMPLE_CANVAS)) #define SWAMIGUI_IS_SAMPLE_CANVAS_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMIGUI_TYPE_SAMPLE_CANVAS)) /* Swami Sample Object */ struct _SwamiguiSampleCanvas { GnomeCanvasItem parent_instance; /*< private >*/ IpatchSampleData *sample; /* sample being displayed */ guint sample_size; /* cached size of sample */ IpatchSampleHandle handle; /* cached sample handle */ gboolean right_chan; /* use right channel of stereo audio? */ guint max_frames; /* max sample frames that can be converted at at time */ gboolean loop_mode; /* display loop mode? */ guint loop_start, loop_end; /* cached loop start and end in samples */ GtkAdjustment *adj; /* adjustment for view */ gboolean update_adj; /* adjustment values should be updated? */ guint need_bbox_update : 1; /* set if bbox need to be updated */ guint start; /* start sample (not used in LOOP mode) */ double zoom; /* zoom factor samples/pixel */ double zoom_ampl; /* amplitude zoom factor */ int x, y; /* x, y coordinates of sample item */ int width, height; /* width and height in pixels */ GdkGC *peak_line_gc; /* GC for drawing vertical average lines */ GdkGC *line_gc; /* GC for drawing lines */ GdkGC *point_gc; /* GC for drawing sample points */ GdkGC *loop_start_gc; /* GC for looop start sample points */ GdkGC *loop_end_gc; /* GC for loop end sample points */ guint peak_line_color; /* color of peak sample lines */ guint line_color; /* color of connecting sample lines */ guint point_color; /* color of sample points */ guint loop_start_color; /* color of sample points for start of loop */ guint loop_end_color; /* color of sample points for end of loop */ }; struct _SwamiguiSampleCanvasClass { GnomeCanvasItemClass parent_class; }; GType swamigui_sample_canvas_get_type (void); void swamigui_sample_canvas_set_sample (SwamiguiSampleCanvas *canvas, IpatchSampleData *sample); int swamigui_sample_canvas_xpos_to_sample (SwamiguiSampleCanvas *canvas, int xpos, int *onsample); int swamigui_sample_canvas_sample_to_xpos (SwamiguiSampleCanvas *canvas, int index, int *inview); #endif swami/src/swamigui/SwamiguiBarPtr.c0000644000175000017500000002306111461334205017537 0ustar alessioalessio/** * SECTION:SwamiguiBarPtr * @short_description: Canvas item used as a position or range indicator. * @see_also: #SwamiguiBar * * This canvas item is used by #SwamiguiBar to display position and range * indicators. A #SwamiguiBar is composed of one or more #SwamiguiBarPtr * items. */ /* * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include "SwamiguiBarPtr.h" #include "builtin_enums.h" #include "i18n.h" enum { PROP_0, PROP_WIDTH, /* width in pixels or rectangle and pointer */ PROP_HEIGHT, /* total height in pixels (including pointer if any) */ PROP_POINTER_HEIGHT, /* height of pointer (must be less than height) */ PROP_TYPE, PROP_INTERACTIVE, PROP_COLOR, PROP_LABEL, PROP_TOOLTIP }; static void swamigui_bar_ptr_class_init (SwamiguiBarPtrClass *klass); static void swamigui_bar_ptr_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void swamigui_bar_ptr_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void swamigui_bar_ptr_init (SwamiguiBarPtr *barptr); static void swamigui_bar_ptr_finalize (GObject *object); static void swamigui_bar_ptr_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags); static GObjectClass *parent_class = NULL; GType swamigui_bar_ptr_get_type (void) { static GType obj_type = 0; if (!obj_type) { static const GTypeInfo obj_info = { sizeof (SwamiguiBarPtrClass), NULL, NULL, (GClassInitFunc) swamigui_bar_ptr_class_init, NULL, NULL, sizeof (SwamiguiBarPtr), 0, (GInstanceInitFunc) swamigui_bar_ptr_init, }; obj_type = g_type_register_static (GNOME_TYPE_CANVAS_GROUP, "SwamiguiBarPtr", &obj_info, 0); } return (obj_type); } static void swamigui_bar_ptr_class_init (SwamiguiBarPtrClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); GnomeCanvasItemClass *item_class = GNOME_CANVAS_ITEM_CLASS (klass); parent_class = g_type_class_peek_parent (klass); obj_class->set_property = swamigui_bar_ptr_set_property; obj_class->get_property = swamigui_bar_ptr_get_property; obj_class->finalize = swamigui_bar_ptr_finalize; item_class->update = swamigui_bar_ptr_update; g_object_class_install_property (obj_class, PROP_WIDTH, g_param_spec_int ("width", _("Width"), _("Width in pixels"), 0, G_MAXINT, 0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_HEIGHT, g_param_spec_int ("height", _("Height"), _("Height in pixels"), 0, G_MAXINT, 0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_POINTER_HEIGHT, g_param_spec_int ("pointer-height", _("Pointer height"), _("Height of pointer in pixels"), 0, G_MAXINT, 0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_TYPE, g_param_spec_enum ("type", _("Type"), _("Pointer type"), SWAMIGUI_TYPE_BAR_PTR_TYPE, SWAMIGUI_BAR_PTR_POSITION, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_INTERACTIVE, g_param_spec_boolean ("interactive", _("Interactive"), _("Interactive"), TRUE, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_COLOR, g_param_spec_uint ("color", _("Color"), _("Color"), 0, G_MAXUINT, 0x00FFFFFF, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_LABEL, g_param_spec_string ("label", _("Label"), _("Label"), NULL, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_TOOLTIP, g_param_spec_string ("tooltip", _("Tooltip"), _("Tooltip"), NULL, G_PARAM_READWRITE)); } static void swamigui_bar_ptr_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { SwamiguiBarPtr *barptr = SWAMIGUI_BAR_PTR (object); GnomeCanvasItem *item = GNOME_CANVAS_ITEM (object); switch (property_id) { case PROP_WIDTH: barptr->width = g_value_get_int (value); gnome_canvas_item_request_update (item); break; case PROP_HEIGHT: barptr->height = g_value_get_int (value); gnome_canvas_item_request_update (item); break; case PROP_POINTER_HEIGHT: barptr->pointer_height = g_value_get_int (value); gnome_canvas_item_request_update (item); break; case PROP_TYPE: barptr->type = g_value_get_enum (value); gnome_canvas_item_request_update (item); break; case PROP_INTERACTIVE: barptr->interactive = g_value_get_boolean (value); break; case PROP_COLOR: barptr->color = g_value_get_uint (value); gnome_canvas_item_request_update (item); break; case PROP_LABEL: barptr->label = g_value_dup_string (value); gnome_canvas_item_request_update (item); break; case PROP_TOOLTIP: barptr->tooltip = g_value_dup_string (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_bar_ptr_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { SwamiguiBarPtr *barptr = SWAMIGUI_BAR_PTR (object); switch (property_id) { case PROP_WIDTH: g_value_set_int (value, barptr->width); break; case PROP_HEIGHT: g_value_set_int (value, barptr->height); break; case PROP_POINTER_HEIGHT: g_value_set_int (value, barptr->pointer_height); break; case PROP_TYPE: g_value_set_enum (value, barptr->type); break; case PROP_INTERACTIVE: g_value_set_boolean (value, barptr->interactive); break; case PROP_COLOR: g_value_set_uint (value, barptr->color); break; case PROP_LABEL: g_value_set_string (value, barptr->label); break; case PROP_TOOLTIP: g_value_set_string (value, barptr->tooltip); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swamigui_bar_ptr_init (SwamiguiBarPtr *barptr) { barptr->type = SWAMIGUI_BAR_PTR_POSITION; barptr->interactive = TRUE; barptr->color = 0x00FFFFFF; barptr->label = NULL; barptr->tooltip = NULL; } static void swamigui_bar_ptr_finalize (GObject *object) { SwamiguiBarPtr *barptr = SWAMIGUI_BAR_PTR (object); g_free (barptr->label); g_free (barptr->tooltip); if (G_OBJECT_CLASS (parent_class)->finalize) (* G_OBJECT_CLASS (parent_class)->finalize)(object); } /** * swamigui_bar_ptr_new: * * Create a new bar pointer object for adding to a #SwamiguiBar object. * * Returns: New bar pointer with a refcount of 1 which the caller owns. */ GnomeCanvasItem * swamigui_bar_ptr_new (void) { return (GNOME_CANVAS_ITEM (g_object_new (SWAMIGUI_TYPE_BAR_PTR, NULL))); } /* update bar pointer graphic primitives */ static void swamigui_bar_ptr_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags) { SwamiguiBarPtr *barptr = SWAMIGUI_BAR_PTR (item); GnomeCanvasPoints *points; if (barptr->type == SWAMIGUI_BAR_PTR_RANGE) /* range pointer? */ { if (!barptr->rect) barptr->rect = gnome_canvas_item_new (GNOME_CANVAS_GROUP (barptr), GNOME_TYPE_CANVAS_RECT, "x1", (gdouble)0.0, "y1", (gdouble)0.0, NULL); if (barptr->ptr) /* pointer rectangle not needed for range */ { gtk_object_destroy (GTK_OBJECT (barptr->ptr)); barptr->ptr = NULL; } g_object_set (barptr->rect, "x2", (double)(barptr->width), "y2", (double)(barptr->height), "fill-color-rgba", barptr->color, NULL); } else /* position pointer mode */ { int rheight = barptr->height - barptr->pointer_height; /* rectangle height */ if (!barptr->rect) barptr->rect = gnome_canvas_item_new (GNOME_CANVAS_GROUP (barptr), GNOME_TYPE_CANVAS_RECT, "x1", (gdouble)0.0, "y1", (gdouble)0.0, NULL); if (!barptr->ptr) barptr->rect = gnome_canvas_item_new (GNOME_CANVAS_GROUP (barptr), GNOME_TYPE_CANVAS_POLYGON, NULL); g_object_set (barptr->rect, "x2", (double)(barptr->width), "y2", (double)(rheight), "fill-color-rgba", barptr->color, NULL); points = gnome_canvas_points_new (3); /* configure as a triangle on the bottom of the rectangle */ points->coords[0] = 0; points->coords[1] = rheight; points->coords[2] = barptr->width / 2.0; points->coords[3] = barptr->height; points->coords[4] = barptr->width; points->coords[5] = rheight; g_object_set (barptr->ptr, "points", points, "fill-color-rgba", barptr->color, NULL); gnome_canvas_points_free (points); } if (GNOME_CANVAS_ITEM_CLASS (parent_class)->update) GNOME_CANVAS_ITEM_CLASS (parent_class)->update (item, affine, clip_path, flags); } swami/src/Makefile.am0000644000175000017500000000021211454115203014670 0ustar alessioalessio## Process this file with automake to produce Makefile.in SUBDIRS = libswami swamigui plugins python MAINTAINERCLEANFILES = Makefile.in swami/src/libswami/0000755000175000017500000000000011716016666014466 5ustar alessioalessioswami/src/libswami/swami_priv.h0000644000175000017500000000203211461334205017001 0ustar alessioalessio/* * swami_priv.h - Private header file * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMI_PRIV_H__ #define __SWAMI_PRIV_H__ #include #include "i18n.h" #define SWAMI_PARAM_SPEC_ID(pspec) ((pspec)->param_id) #endif /* #ifndef __SWAMI_PRIV_H__ */ swami/src/libswami/SwamiControlEvent.h0000644000175000017500000000473711461334205020262 0ustar alessioalessio/* * SwamiControlEvent.h - Swami control event structure (not an object) * A structure that defines a control event. * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMI_CONTROL_EVENT_H__ #define __SWAMI_CONTROL_EVENT_H__ #include #include #include #include typedef struct _SwamiControlEvent SwamiControlEvent; /* a boxed type for SwamiControlEvent */ #define SWAMI_TYPE_CONTROL_EVENT (swami_control_event_get_type ()) struct _SwamiControlEvent { struct timeval tick; /* tick time */ SwamiControlEvent *origin; /* origin event or %NULL if is origin */ GValue value; /* value for this event */ int active; /* active propagation count */ int refcount; /* reference count */ }; /* an accessor macro for the value field of an event */ #define SWAMI_CONTROL_EVENT_VALUE(event) (&((event)->value)) #include GType swami_control_event_get_type (void); SwamiControlEvent *swami_control_event_new (gboolean stamp); void swami_control_event_free (SwamiControlEvent *event); SwamiControlEvent * swami_control_event_duplicate (const SwamiControlEvent *event); SwamiControlEvent *swami_control_event_transform (SwamiControlEvent *event, GType valtype, SwamiValueTransform trans, gpointer data); void swami_control_event_stamp (SwamiControlEvent *event); void swami_control_event_set_origin (SwamiControlEvent *event, SwamiControlEvent *origin); SwamiControlEvent *swami_control_event_ref (SwamiControlEvent *event); void swami_control_event_unref (SwamiControlEvent *event); void swami_control_event_active_ref (SwamiControlEvent *event); void swami_control_event_active_unref (SwamiControlEvent *event); #endif swami/src/libswami/SwamiPropTree.h0000644000175000017500000000762311461334205017375 0ustar alessioalessio/* * SwamiPropTree.h - Header for property tree system * A tree of objects with inheritable active values. * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMI_PROP_TREE_H__ #define __SWAMI_PROP_TREE_H__ #include #include #include #include #include typedef struct _SwamiPropTree SwamiPropTree; typedef struct _SwamiPropTreeClass SwamiPropTreeClass; typedef struct _SwamiPropTreeNode SwamiPropTreeNode; typedef struct _SwamiPropTreeValue SwamiPropTreeValue; #define SWAMI_TYPE_PROP_TREE (swami_prop_tree_get_type ()) #define SWAMI_PROP_TREE(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMI_TYPE_PROP_TREE, SwamiPropTree)) #define SWAMI_PROP_TREE_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMI_TYPE_PROP_TREE, SwamiPropTreeClass)) #define SWAMI_IS_PROP_TREE(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMI_TYPE_PROP_TREE)) #define SWAMI_IS_PROP_TREE_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMI_TYPE_PROP_TREE)) /* Swami property tree */ struct _SwamiPropTree { SwamiLock parent_instance; /* derived from SwamiLock */ GNode *tree; /* tree of SwamiPropTreeNode structures */ GHashTable *object_hash; /* object->node hash */ }; struct _SwamiPropTreeClass { SwamiLockClass parent_class; }; /* defines a node of a property tree - an object with a list of node property values and cached object property values */ struct _SwamiPropTreeNode { GObject *object; /* pointer to the object the node manages */ GSList *values; /* list of SwamiPropTreeValue for this node */ GSList *cache; /* cached values for object (struct in SwamiPropTree.c) */ guint16 flags; guint16 reserved; }; /* defines an active value in a property tree */ struct _SwamiPropTreeValue { GType prop_type; /* instance type owning property to match (0 = wildcard) */ char *prop_name; /* name of property to match */ SwamiControl *control; /* source value control (defines the value) */ }; GType swami_prop_tree_get_type (void); SwamiPropTree *swami_prop_tree_new (void); void swami_prop_tree_set_root (SwamiPropTree *proptree, GObject *root); void swami_prop_tree_prepend (SwamiPropTree *proptree, GObject *parent, GObject *obj); #define swami_prop_tree_append(proptree, parent, obj) \ swami_prop_tree_insert_before (proptree, parent, NULL, obj) void swami_prop_tree_insert_before (SwamiPropTree *proptree, GObject *parent, GObject *sibling, GObject *obj); void swami_prop_tree_remove (SwamiPropTree *proptree, GObject *obj); void swami_prop_tree_remove_recursive (SwamiPropTree *proptree, GObject *obj); void swami_prop_tree_replace (SwamiPropTree *proptree, GObject *old, GObject *new); IpatchList *swami_prop_tree_get_children (SwamiPropTree *proptree, GObject *obj); GNode *swami_prop_tree_object_get_node (SwamiPropTree *proptree, GObject *obj); void swami_prop_tree_add_value (SwamiPropTree *proptree, GObject *obj, GType prop_type, const char *prop_name, SwamiControl *control); void swami_prop_tree_remove_value (SwamiPropTree *proptree, GObject *obj, GType prop_type, const char *prop_name); #endif swami/src/libswami/SwamiControlMidi.c0000644000175000017500000001140411461334205020043 0ustar alessioalessio/* * SwamiControlMidi.c - Swami MIDI control * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include "SwamiControlMidi.h" #include "SwamiControl.h" #include "SwamiLog.h" #include "swami_priv.h" #include "util.h" static void swami_control_midi_class_init (SwamiControlMidiClass *klass); static void swami_control_midi_init (SwamiControlMidi *ctrlmidi); GType swami_control_midi_get_type (void) { static GType otype = 0; if (!otype) { static const GTypeInfo type_info = { sizeof (SwamiControlMidiClass), NULL, NULL, (GClassInitFunc) swami_control_midi_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SwamiControlMidi), 0, (GInstanceInitFunc) swami_control_midi_init }; otype = g_type_register_static (SWAMI_TYPE_CONTROL_FUNC, "SwamiControlMidi", &type_info, 0); } return (otype); } static void swami_control_midi_class_init (SwamiControlMidiClass *klass) { SwamiControlClass *control_class = SWAMI_CONTROL_CLASS (klass); control_class->set_spec = NULL; /* clear set_spec method */ } static void swami_control_midi_init (SwamiControlMidi *ctrlmidi) { swami_control_set_flags (SWAMI_CONTROL (ctrlmidi), SWAMI_CONTROL_SENDRECV | SWAMI_CONTROL_NO_CONV | SWAMI_CONTROL_NATIVE); } /** * swami_control_midi_new: * * Create a new MIDI control. * * Returns: New MIDI control with a refcount of 1 which the caller owns. */ SwamiControlMidi * swami_control_midi_new (void) { return (SWAMI_CONTROL_MIDI (g_object_new (SWAMI_TYPE_CONTROL_MIDI, NULL))); } /** * swami_control_midi_set_callback: * @midi: MIDI control * @callback: Function to callback when a new event is received or %NULL * @data: User defined data to pass to the callback * * Set a callback function for received events on a MIDI control. */ void swami_control_midi_set_callback (SwamiControlMidi *midi, SwamiControlSetValueFunc callback, gpointer data) { g_return_if_fail (SWAMI_IS_CONTROL_MIDI (midi)); swami_control_func_assign_funcs (SWAMI_CONTROL_FUNC (midi), NULL, callback, NULL, data); } /** * swami_control_midi_send: * @midi: MIDI control * @type: MIDI event type * @channel: MIDI channel to send on * @param1: First parameter * @param2: Second parameter (only used with certain event types) * * A convenience function to send an event TO a MIDI control. One * could do the same by creating a #SwamiMidiEvent, calling * swami_midi_event_set() on it and then setting the * control with swami_control_set_value(). */ void swami_control_midi_send (SwamiControlMidi *midi, SwamiMidiEventType type, int channel, int param1, int param2) { SwamiMidiEvent *event; GValue value = { 0 }; g_return_if_fail (SWAMI_IS_CONTROL_MIDI (midi)); event = swami_midi_event_new (); swami_midi_event_set (event, type, channel, param1, param2); g_value_init (&value, SWAMI_TYPE_MIDI_EVENT); g_value_set_boxed_take_ownership (&value, event); swami_control_set_value (SWAMI_CONTROL (midi), &value); g_value_unset (&value); } /** * swami_control_midi_transmit: * @midi: MIDI control * @type: MIDI event type * @channel: MIDI channel to send on * @param1: First parameter * @param2: Second parameter (only used with certain event types) * * A convenience function to send an event FROM a MIDI control. One * could do the same by creating a #SwamiMidiEvent, calling * swami_midi_event_set() on it and then transmitting it from the * control with swami_control_transmit_value(). */ void swami_control_midi_transmit (SwamiControlMidi *midi, SwamiMidiEventType type, int channel, int param1, int param2) { SwamiMidiEvent *event; GValue value = { 0 }; g_return_if_fail (SWAMI_IS_CONTROL_MIDI (midi)); event = swami_midi_event_new (); swami_midi_event_set (event, type, channel, param1, param2); g_value_init (&value, SWAMI_TYPE_MIDI_EVENT); g_value_set_boxed_take_ownership (&value, event); swami_control_transmit_value (SWAMI_CONTROL (midi), &value); g_value_unset (&value); } swami/src/libswami/util.c0000644000175000017500000001053311461334205015576 0ustar alessioalessio/* * util.c - Miscellaneous utility functions * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include #include "util.h" #include "swami_priv.h" static void recurse_types (GType type, GArray *array); /** * swami_util_get_child_types: * @type: Type to get all children from * @n_types: Location to store count of types or %NULL to ignore * * Recursively get all child types of a @type. * * Returns: Newly allocated and 0 terminated array of types */ GType * swami_util_get_child_types (GType type, guint *n_types) { GArray *array; GType *types; array = g_array_new (TRUE, FALSE, sizeof (GType)); recurse_types (type, array); if (n_types) *n_types = array->len; types = (GType *)(array->data); g_array_free (array, FALSE); return (types); } static void recurse_types (GType type, GArray *array) { GType *child_types, *ptype; child_types = g_type_children (type, NULL); for (ptype = child_types; *ptype; ptype++) { g_array_append_val (array, *ptype); recurse_types (*ptype, array); } g_free (child_types); } /** * swami_util_new_value: * * Allocate a new GValue using a GMemChunk. * * Returns: New uninitialized (zero) GValue */ GValue * swami_util_new_value (void) { return (g_slice_new0 (GValue)); } /** * swami_util_free_value: * @value: GValue created from swami_util_new_value(). * * Free a GValue that was allocated with swami_util_new_value(). */ void swami_util_free_value (GValue *value) { g_value_unset (value); g_slice_free (GValue, value); } /** * swami_util_midi_note_to_str: * @note: MIDI note number (0-127) * @str: Buffer to store string to (at least 5 bytes in length) */ void swami_util_midi_note_to_str (int note, char *str) { static const char *notes[] = { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" }; char octavestr[3]; g_return_if_fail (note >= 0 && note <= 127); strcpy (str, notes[note % 12]); sprintf (octavestr, "%d", note / 12 - 2); /* C0 is actually note 24 */ strcat (str, octavestr); } /** * swami_util_midi_str_to_note: * @str: String to parse as a MIDI note * * Parse a string in the form "[A-Ga-g][b#]n" or "0"-"127" as a MIDI note. * Where 'n' is the octave number between -2 and 8. '#' is used to indicate * "sharp". 'b' means "flat". Examples: "C3" is middle C (note 60), * "F#-2" is note 5, "Db-2" is the same as "C#-2" (note 0). Any chars * following a valid MIDI note string are ignored. * * Returns: The MIDI note # or -1 on error (str is malformed). */ int swami_util_midi_str_to_note (const char *str) { guint8 octofs[7] = { 9, 11, 0, 2, 4, 5, 7 }; /* octave offset for A-G */ char *endptr; long int l; int note; char c; g_return_val_if_fail (str != NULL, -1); if (!*str) return (-1); /* try converting as a decimal string */ l = strtol (str, &endptr, 10); if (!*endptr && l >= 0 && l <= 127) return (l); /* get first char (should be a note character */ c = *str++; if (c >= 'A' && c <= 'G') note = octofs[c - 'A']; else if (c >= 'a' && c <= 'g') note = octofs[c - 'a']; else return (-1); c = *str++; if (c == '#') { note++; c = *str++; } else if (c == 'b') { note--; c = *str++; } else if (c == 0) return (-1); if (c == '-') { c = *str++; if (c == '1') note += 12; else if (c != '2') return (-1); } else if ((c >= '0' && c <= '8')) /* Only 1 digit? */ note += (c - '0') * 12 + 24; else return (-1); if (note >= 0 && note <= 127) return (note); else return (-1); } swami/src/libswami/SwamiLock.c0000644000175000017500000000727611461334205016524 0ustar alessioalessio/* * SwamiLock.c - Base Swami multi-thread locked object * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include "config.h" #include #include #include #include "SwamiLock.h" /* --- private function prototypes --- */ static void swami_lock_init (SwamiLock *lock); /* --- functions --- */ GType swami_lock_get_type (void) { static GType item_type = 0; if (!item_type) { static const GTypeInfo item_info = { sizeof (SwamiLockClass), NULL, NULL, (GClassInitFunc) NULL, NULL, NULL, sizeof (SwamiLock), 0, (GInstanceInitFunc) swami_lock_init, }; item_type = g_type_register_static (G_TYPE_OBJECT, "SwamiLock", &item_info, G_TYPE_FLAG_ABSTRACT); } return (item_type); } static void swami_lock_init (SwamiLock *lock) { g_static_rec_mutex_init (&lock->mutex); } /** * swami_lock_set_atomic: * @lock: SwamiLock derived object to set properties of * @first_property_name: Name of first property * @Varargs: Variable list of arguments that should start with the value to * set @first_property_name to, followed by property name/value pairs. List is * terminated with a %NULL property name. * * Sets properties on a Swami lock item atomically (i.e. item is * multi-thread locked while all properties are set). This avoids * critical parameter sync problems when multiple threads are * accessing the same item. See g_object_set() for more information on * setting properties. This function is rarely needed, only useful for cases * where multiple properties depend on each other. */ void swami_lock_set_atomic (gpointer lock, const char *first_property_name, ...) { va_list args; g_return_if_fail (SWAMI_IS_LOCK (lock)); va_start (args, first_property_name); SWAMI_LOCK_WRITE (lock); g_object_set_valist (G_OBJECT (lock), first_property_name, args); SWAMI_UNLOCK_WRITE (lock); va_end (args); } /** * swami_lock_get_atomic: * @lock: SwamiLock derived object to get properties from * @first_property_name: Name of first property * @Varargs: Variable list of arguments that should start with a * pointer to store the value from @first_property_name, followed by * property name/value pointer pairs. List is terminated with a %NULL * property name. * * Gets properties from a Swami lock item atomically (i.e. item is * multi-thread locked while all properties are retrieved). This * avoids critical parameter sync problems when multiple threads are * accessing the same item. See g_object_get() for more information on * getting properties. This function is rarely needed, only useful when * multiple properties depend on each other. */ void swami_lock_get_atomic (gpointer lock, const char *first_property_name, ...) { va_list args; g_return_if_fail (SWAMI_IS_LOCK (lock)); va_start (args, first_property_name); SWAMI_LOCK_WRITE (lock); g_object_get_valist (G_OBJECT (lock), first_property_name, args); SWAMI_UNLOCK_WRITE (lock); va_end (args); } swami/src/libswami/SwamiControlProp.h0000644000175000017500000000616511461334205020116 0ustar alessioalessio/* * SwamiControlProp.h - Header for Swami GObject property control * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMI_CONTROL_PROP_H__ #define __SWAMI_CONTROL_PROP_H__ #include #include #include typedef struct _SwamiControlProp SwamiControlProp; typedef struct _SwamiControlPropClass SwamiControlPropClass; #define SWAMI_TYPE_CONTROL_PROP (swami_control_prop_get_type ()) #define SWAMI_CONTROL_PROP(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMI_TYPE_CONTROL_PROP, \ SwamiControlProp)) #define SWAMI_CONTROL_PROP_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMI_TYPE_CONTROL_PROP, \ SwamiControlPropClass)) #define SWAMI_IS_CONTROL_PROP(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMI_TYPE_CONTROL_PROP)) #define SWAMI_IS_CONTROL_PROP_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMI_TYPE_CONTROL_PROP)) /* Property control object */ struct _SwamiControlProp { SwamiControl parent_instance; /* derived from SwamiControl */ GObject *object; /* object being controlled */ GParamSpec *spec; /* parameter spec of the property being controlled */ gulong notify_handler_id; /* ID of object "notify" signal handler */ guint item_handler_id; /* IpatchItem property callback handler ID */ gboolean send_events; /* when TRUE control uses SwamiEventPropChange events */ }; /* Property control class */ struct _SwamiControlPropClass { SwamiControlClass parent_class; }; SwamiControl *swami_get_control_prop (GObject *object, GParamSpec *pspec); SwamiControl *swami_get_control_prop_by_name (GObject *object, const char *name); void swami_control_prop_connect_objects (GObject *src, const char *propname1, GObject *dest, const char *propname2, guint flags); void swami_control_prop_connect_to_control (GObject *src, const char *propname, SwamiControl *dest, guint flags); void swami_control_prop_connect_from_control (SwamiControl *src, GObject *dest, const char *propname, guint flags); GType swami_control_prop_get_type (void); SwamiControlProp *swami_control_prop_new (GObject *object, GParamSpec *pspec); void swami_control_prop_assign (SwamiControlProp *ctrlprop, GObject *object, GParamSpec *pspec, gboolean send_events); void swami_control_prop_assign_by_name (SwamiControlProp *ctrlprop, GObject *object, const char *prop_name); #endif swami/src/libswami/SwamiMidiDevice.h0000644000175000017500000000464511461334205017640 0ustar alessioalessio/* * SwamiMidiDevice.h - Swami MIDI object header file * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMI_MIDI_DEVICE_H__ #define __SWAMI_MIDI_DEVICE_H__ #include #include #include #include #include typedef struct _SwamiMidiDevice SwamiMidiDevice; typedef struct _SwamiMidiDeviceClass SwamiMidiDeviceClass; #define SWAMI_TYPE_MIDI_DEVICE (swami_midi_device_get_type ()) #define SWAMI_MIDI_DEVICE(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMI_TYPE_MIDI_DEVICE, SwamiMidiDevice)) #define SWAMI_MIDI_DEVICE_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMI_TYPE_MIDI_DEVICE, SwamiMidiDeviceClass)) #define SWAMI_IS_MIDI_DEVICE(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMI_TYPE_MIDI_DEVICE)) #define SWAMI_IS_MIDI_DEVICE_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMI_TYPE_MIDI_DEVICE)) /* Swami MIDI device object */ struct _SwamiMidiDevice { SwamiLock parent_instance; /* derived from GObject */ /*< private >*/ gboolean active; /* driver is active? */ }; /* Swami MIDI device class */ struct _SwamiMidiDeviceClass { SwamiLockClass parent_class; /*< public >*/ /* methods */ gboolean (*open) (SwamiMidiDevice *device, GError **err); void (*close) (SwamiMidiDevice *device); SwamiControl * (*get_control) (SwamiMidiDevice *device, int index); }; GType swami_midi_device_get_type (void); gboolean swami_midi_device_open (SwamiMidiDevice *device, GError **err); void swami_midi_device_close (SwamiMidiDevice *device); SwamiControl *swami_midi_device_get_control (SwamiMidiDevice *device, int index); #endif swami/src/libswami/SwamiControlValue.h0000644000175000017500000000453611461334205020252 0ustar alessioalessio/* * SwamiControlValue.h - Header for Swami GValue control * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMI_CONTROL_VALUE_H__ #define __SWAMI_CONTROL_VALUE_H__ #include #include #include typedef struct _SwamiControlValue SwamiControlValue; typedef struct _SwamiControlValueClass SwamiControlValueClass; #define SWAMI_TYPE_CONTROL_VALUE (swami_control_value_get_type ()) #define SWAMI_CONTROL_VALUE(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMI_TYPE_CONTROL_VALUE, \ SwamiControlValue)) #define SWAMI_CONTROL_VALUE_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMI_TYPE_CONTROL_VALUE, \ SwamiControlValueClass)) #define SWAMI_IS_CONTROL_VALUE(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMI_TYPE_CONTROL_VALUE)) #define SWAMI_IS_CONTROL_VALUE_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMI_TYPE_CONTROL_VALUE)) /* Value control object */ struct _SwamiControlValue { SwamiControl parent_instance; /* derived from SwamiControl */ GValue *value; /* value being controlled */ GDestroyNotify destroy; /* function to call to destroy value or NULL */ GParamSpec *pspec; /* created param spec for controlled value */ }; /* Value control class */ struct _SwamiControlValueClass { SwamiControlClass parent_class; }; GType swami_control_value_get_type (void); SwamiControlValue *swami_control_value_new (void); void swami_control_value_assign_value (SwamiControlValue *ctrlvalue, GValue *value, GDestroyNotify destroy); void swami_control_value_alloc_value (SwamiControlValue *ctrlvalue); #endif swami/src/libswami/SwamiParam.h0000644000175000017500000000440111461334205016664 0ustar alessioalessio/* * SwamiParam.h - GParamSpec related functions * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMI_PARAM_H__ #define __SWAMI_PARAM_H__ #include #include /** * SwamiValueTransform: * @src: Source value to transform from * @dest: Destination value to store to * @user_data: User defined data (set when transform was connected for example) * * Prototype for value transform function. The transform function should * handle any value conversions required. */ typedef void (*SwamiValueTransform)(const GValue *src, GValue *dest, gpointer user_data); gboolean swami_param_get_limits (GParamSpec *pspec, gdouble *min, gdouble *max, gdouble *def, gboolean *integer); gboolean swami_param_set_limits (GParamSpec *pspec, gdouble min, gdouble max, gdouble def); gboolean swami_param_type_has_limits (GType param_type); gboolean swami_param_convert (GParamSpec *dest, GParamSpec *src); GParamSpec *swami_param_convert_new (GParamSpec *pspec, GType value_type); gboolean swami_param_type_transformable (GType src_type, GType dest_type); gboolean swami_param_type_transformable_value (GType src_valtype, GType dest_valtype); gboolean swami_param_transform (GParamSpec *dest, GParamSpec *src, SwamiValueTransform trans, gpointer user_data); GParamSpec *swami_param_transform_new (GParamSpec *dest, GType value_type, SwamiValueTransform trans, gpointer user_data); GType swami_param_type_from_value_type (GType value_type); #endif swami/src/libswami/SwamiMidiEvent.c0000644000175000017500000002375311461334205017516 0ustar alessioalessio/* * SwamiMidiEvent.c - MIDI event object * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include "SwamiMidiEvent.h" #include "swami_priv.h" GType swami_midi_event_get_type (void) { static GType item_type = 0; if (!item_type) item_type = g_boxed_type_register_static ("SwamiMidiEvent", (GBoxedCopyFunc)swami_midi_event_copy, (GBoxedFreeFunc)swami_midi_event_free); return (item_type); } /** * swami_midi_event_new: * * Create a new MIDI event structure. * * Returns: New MIDI event structure. Free it with swami_midi_event_free() * when finished. */ SwamiMidiEvent * swami_midi_event_new (void) { SwamiMidiEvent *event; event = g_slice_new0 (SwamiMidiEvent); event->type = SWAMI_MIDI_NONE; return (event); } /** * swami_midi_event_free: * @event: MIDI event structure to free * * Free a MIDI event previously allocated by swami_midi_event_new(). */ void swami_midi_event_free (SwamiMidiEvent *event) { g_slice_free (SwamiMidiEvent, event); } /** * swami_midi_event_copy: * @event: MIDI event structure to duplicate * * Duplicate a MIDI event structure. * * Returns: New duplicate MIDI event. Free it with swami_midi_event_free() * when finished. */ SwamiMidiEvent * swami_midi_event_copy (SwamiMidiEvent *event) { SwamiMidiEvent *new_event; new_event = swami_midi_event_new (); *new_event = *event; return (new_event); } /** * swami_midi_event_set: * @event: MIDI event structure * @type: Type of event to assign * @channel: MIDI channel to send to * @param1: First parameter of event @type * @param2: Second parameter of event @type (only for some types) * * A single entry point for all event types if one does not care to use * the event type specific functions. */ void swami_midi_event_set (SwamiMidiEvent *event, SwamiMidiEventType type, int channel, int param1, int param2) { SwamiMidiEventNote *note; SwamiMidiEventControl *ctrl; g_return_if_fail (event != NULL); note = &event->data.note; ctrl = &event->data.control; event->type = type; event->channel = channel; switch (type) { case SWAMI_MIDI_NOTE_ON: if (param2 == 0) event->type = SWAMI_MIDI_NOTE_OFF; /* velocity is 0? */ /* fall through */ case SWAMI_MIDI_NOTE_OFF: case SWAMI_MIDI_KEY_PRESSURE: note->note = param1; note->velocity = param2; break; case SWAMI_MIDI_PITCH_BEND: ctrl->param = param1; ctrl->value = param2; break; case SWAMI_MIDI_PROGRAM_CHANGE: ctrl->value = param1; break; case SWAMI_MIDI_CONTROL: case SWAMI_MIDI_CONTROL14: ctrl->param = param1; ctrl->value = param2; break; case SWAMI_MIDI_CHAN_PRESSURE: ctrl->value = param1; break; case SWAMI_MIDI_RPN: case SWAMI_MIDI_NRPN: ctrl->param = param1; ctrl->value = param2; break; /* these are handled by other event types, convenience only */ case SWAMI_MIDI_BEND_RANGE: event->type = SWAMI_MIDI_RPN; ctrl->param = SWAMI_MIDI_RPN_BEND_RANGE; ctrl->value = param1; break; case SWAMI_MIDI_BANK_SELECT: event->type = SWAMI_MIDI_CONTROL14; ctrl->param = SWAMI_MIDI_CC_BANK_MSB; ctrl->value = param1; break; default: g_warning ("Unknown MIDI event type"); event->type = SWAMI_MIDI_NONE; break; } } /** * swami_midi_event_note_on: * @event: MIDI event structure * @channel: MIDI channel to send note on event to * @note: MIDI note number * @velocity: MIDI note velocity * * Make a MIDI event structure a note on event. */ void swami_midi_event_note_on (SwamiMidiEvent *event, int channel, int note, int velocity) { SwamiMidiEventNote *n; g_return_if_fail (event != NULL); event->type = (velocity != 0) ? SWAMI_MIDI_NOTE_ON : SWAMI_MIDI_NOTE_OFF; event->channel = channel; n = &event->data.note; n->note = note; n->velocity = velocity; } /** * swami_midi_event_note_off: * @event: MIDI event structure * @channel: MIDI channel to send note off event to * @note: MIDI note number * @velocity: MIDI note velocity * * Make a MIDI event structure a note off event. */ void swami_midi_event_note_off (SwamiMidiEvent *event, int channel, int note, int velocity) { SwamiMidiEventNote *n; g_return_if_fail (event != NULL); event->type = SWAMI_MIDI_NOTE_OFF; event->channel = channel; n = &event->data.note; n->note = note; n->velocity = velocity; } /** * swami_midi_event_bank_select: * @event: MIDI event structure * @channel: MIDI channel to send bank select to * @bank: Bank number to change to * * Make a MIDI event structure a bank select event. A convenience function * since a bank select is just a controller event, and is sent as such. */ void swami_midi_event_bank_select (SwamiMidiEvent *event, int channel, int bank) { SwamiMidiEventControl *ctrl; g_return_if_fail (event != NULL); event->type = SWAMI_MIDI_CONTROL14; event->channel = channel; ctrl = &event->data.control; ctrl->param = SWAMI_MIDI_CC_BANK_MSB; ctrl->value = bank; } /** * swami_midi_event_program_change: * @event: MIDI event structure * @channel: MIDI channel to send program change to * @program: Program number to change to * * Set a MIDI event structure to a program change event. */ void swami_midi_event_set_program (SwamiMidiEvent *event, int channel, int program) { SwamiMidiEventControl *ctrl; g_return_if_fail (event != NULL); event->type = SWAMI_MIDI_PROGRAM_CHANGE; event->channel = channel; ctrl = &event->data.control; ctrl->value = program; } /** * swami_midi_event_bend_range: * @event: MIDI event structure * @channel: MIDI channel to send event to * @cents: Bend range in cents (100th of a semitone) * * Make a MIDI event structure a bend range event. A convenience since one * could also use the swami_midi_event_rpn() function. */ void swami_midi_event_set_bend_range (SwamiMidiEvent *event, int channel, int cents) { SwamiMidiEventControl *ctrl; g_return_if_fail (event != NULL); event->type = SWAMI_MIDI_RPN; event->channel = channel; ctrl = &event->data.control; ctrl->param = SWAMI_MIDI_RPN_BEND_RANGE; ctrl->value = cents; } /** * swami_midi_event_pitch_bend: * @event: MIDI event structure * @channel: MIDI channel to send event to * @value: MIDI pitch bend value (-8192 - 8191, 0 = center) * * Make a MIDI event structure a pitch bend event. */ void swami_midi_event_pitch_bend (SwamiMidiEvent *event, int channel, int value) { SwamiMidiEventControl *ctrl; g_return_if_fail (event != NULL); event->type = SWAMI_MIDI_PITCH_BEND; event->channel = channel; ctrl = &event->data.control; ctrl->value = value; } /** * swami_midi_event_control: * @event: MIDI event structure * @channel: MIDI channel to send event on * @ctrlnum: Control number * @value: 7 bit value to set control to * * Make a MIDI event structure a 7 bit controller event. */ void swami_midi_event_control (SwamiMidiEvent *event, int channel, int ctrlnum, int value) { SwamiMidiEventControl *ctrl; g_return_if_fail (event != NULL); event->type = SWAMI_MIDI_CONTROL; event->channel = channel; ctrl = &event->data.control; ctrl->param = ctrlnum; ctrl->value = value; } /** * swami_midi_event_control14: * @event: MIDI event structure * @channel: MIDI channel to send event on * @ctrlnum: Control number * @value: 14 bit value to set control to * * Make a MIDI event structure a 14 bit controller event. The ctrlnum should * be one of the first 32 MIDI controllers that have MSB and LSB controllers * for sending 14 bit values. Either the MSB or LSB controller number may * be used (example: either 0 or 32 can be used for setting 14 bit bank * number). Internally the MSB controller numbers are used (0-31). */ void swami_midi_event_control14 (SwamiMidiEvent *event, int channel, int ctrlnum, int value) { SwamiMidiEventControl *ctrl; g_return_if_fail (event != NULL); g_return_if_fail (ctrlnum >= 0 && ctrlnum <= 63); if (ctrlnum > 31) ctrlnum -= 32; event->type = SWAMI_MIDI_CONTROL14; event->channel = channel; ctrl = &event->data.control; ctrl->param = ctrlnum; ctrl->value = value; } /** * swami_midi_event_rpn: * @event: MIDI event structure * @channel: MIDI channel to send event to * @paramnum: RPN parameter number * @value: 14 bit value to set parameter to * * Make a MIDI event structure a RPN (registered parameter number) event. */ void swami_midi_event_rpn (SwamiMidiEvent *event, int channel, int paramnum, int value) { SwamiMidiEventControl *ctrl; g_return_if_fail (event != NULL); event->type = SWAMI_MIDI_RPN; event->channel = channel; ctrl = &event->data.control; ctrl->param = paramnum; ctrl->value = value; } /** * swami_midi_event_nrpn: * @event: MIDI event structure * @channel: MIDI channel to send event to * @paramnum: NRPN parameter number * @value: 14 bit value to set parameter to * * Make a MIDI event structure a NRPN (non-registered parameter number) event. */ void swami_midi_event_nrpn (SwamiMidiEvent *event, int channel, int paramnum, int value) { SwamiMidiEventControl *ctrl; g_return_if_fail (event != NULL); event->type = SWAMI_MIDI_NRPN; event->channel = channel; ctrl = &event->data.control; ctrl->param = paramnum; ctrl->value = value; } swami/src/libswami/libswami.h0000644000175000017500000000401711461334205016435 0ustar alessioalessio/* * libswami.h - Main libswami header file that includes all others * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __LIB_SWAMI_H__ #define __LIB_SWAMI_H__ #include #include #include #include /* libswami.c */ void swami_init (void); /* IpatchItem event controls */ extern SwamiControl *swami_patch_prop_title_control; extern SwamiControl *swami_patch_add_control; extern SwamiControl *swami_patch_remove_control; #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #endif swami/src/libswami/Makefile.am0000644000175000017500000001013511464144605016515 0ustar alessioalessio## Process this file with automake to produce Makefile.in if PLATFORM_WIN32 no_undefined = -no-undefined -export-symbols libswami_la_def = libswami.def endif if OS_WIN32 install-libtool-import-lib: $(INSTALL) .libs/libswami.dll.a $(DESTDIR)$(libdir) uninstall-libtool-import-lib: -rm $(DESTDIR)$(libdir)/libswami.dll.a else install-libtool-import-lib: uninstall-libtool-import-lib: endif lib_LTLIBRARIES = libswami.la EXTRA_DIST = version.h.in marshals.list libswami.def BUILT_SOURCES = \ builtin_enums.c \ builtin_enums.h \ marshals.c \ marshals.h # correctly clean the generated source files CLEANFILES = $(BUILT_SOURCES) swami_public_h_sources = \ SwamiContainer.h \ SwamiControl.h \ SwamiControlEvent.h \ SwamiControlFunc.h \ SwamiControlHub.h \ SwamiControlMidi.h \ SwamiControlProp.h \ SwamiControlQueue.h \ SwamiControlValue.h \ SwamiEvent_ipatch.h \ SwamiLock.h \ SwamiLog.h \ SwamiLoopFinder.h \ SwamiLoopResults.h \ SwamiMidiDevice.h \ SwamiMidiEvent.h \ SwamiObject.h \ SwamiParam.h \ SwamiPlugin.h \ SwamiPropTree.h \ SwamiRoot.h \ SwamiWavetbl.h \ util.h swami_sources = \ $(BUILT_SOURCES) \ i18n.h \ SwamiContainer.c \ SwamiControl.c \ SwamiControlEvent.c \ SwamiControlFunc.c \ SwamiControlHub.c \ SwamiControlMidi.c \ SwamiControlProp.c \ SwamiControlQueue.c \ SwamiControlValue.c \ SwamiEvent_ipatch.c \ SwamiLock.c \ SwamiLog.c \ SwamiLoopFinder.c \ SwamiLoopResults.c \ SwamiMidiDevice.c \ SwamiMidiEvent.c \ SwamiObject.c \ SwamiParam.c \ SwamiPlugin.c \ SwamiPropTree.c \ SwamiRoot.c \ SwamiWavetbl.c \ libswami.c \ libswami.h \ swami_priv.h \ util.c \ value_transform.c libswami_la_SOURCES = $(swami_public_h_sources) $(swami_sources) libswami_la_LDFLAGS = $(no_undefined) $(libswami_la_def) \ @GOBJECT_LIBS@ @LIBINSTPATCH_LIBS@ if SOURCE_BUILD PLUGINS_DIR="$(abs_top_builddir)/src/plugins/.libs" else PLUGINS_DIR="$(pkglibdir)" endif AM_CPPFLAGS = \ -DG_LOG_DOMAIN=\"libswami\" \ -DPLUGINS_DIR=\"$(PLUGINS_DIR)\" \ -DLOCALEDIR=\"$(datadir)/locale\" \ -I$(top_srcdir)/src \ -I$(top_srcdir)/src/include \ -I$(top_srcdir)/intl \ @GOBJECT_CFLAGS@ @LIBINSTPATCH_CFLAGS@ # Installed headers swamiincdir = $(includedir)/swami/libswami swamiinc_HEADERS = $(swami_public_h_sources) builtin_enums.h libswami.h marshals.c: marshals.list echo "/* Autogenerated file (add to marshals.list and 'make update-marshals') */" >marshals.c glib-genmarshal --body --prefix=swami_marshal \ marshals.list >>marshals.c marshals.h: marshals.list echo "/* Autogenerated file (add to marshals.list and 'make update-marshals') */" >marshals.h glib-genmarshal --header --prefix=swami_marshal \ marshals.list >>marshals.h builtin_enums.c: s-builtin-enums-c @true s-builtin-enums-c: $(swami_public_h_sources) Makefile ( cd $(srcdir) && glib-mkenums \ --fhead "#include \"libswami.h\"\n#include \"swami_priv.h\"" \ --fprod "\n/* enumerations from \"@filename@\" */" \ --vhead "GType\n@enum_name@_get_type (void)\n{\n static GType etype = 0;\n if (etype == 0) {\n static const G@Type@Value values[] = {" \ --vprod " { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \ --vtail " { 0, NULL, NULL }\n };\n etype = g_@type@_register_static (\"@EnumName@\", values);\n }\n return etype;\n}\n" \ $(swami_public_h_sources) ) > xgen-enumc \ && cp xgen-enumc $(srcdir)/builtin_enums.c \ && rm -f xgen-enumc builtin_enums.h: s-builtin-enums-h @true s-builtin-enums-h: $(swami_public_h_sources) Makefile ( cd $(srcdir) && glib-mkenums \ --fhead "#ifndef __SWAMI_BUILTIN_ENUMS_H__\n#define __SWAMI_BUILTIN_ENUMS_H__\n\n#include \n\nG_BEGIN_DECLS\n" \ --fprod "/* enumerations from \"@filename@\" */\n" \ --vhead "GType @enum_name@_get_type (void);\n#define SWAMI_TYPE_@ENUMSHORT@ (@enum_name@_get_type())\n" \ --ftail "G_END_DECLS\n\n#endif /* __SWAMI_BUILTIN_ENUMS_H__ */" \ $(swami_public_h_sources) ) >> xgen-enumh \ && (cmp -s xgen-enumh $(srcdir)/builtin_enums.h || cp xgen-enumh $(srcdir)/builtin_enums.h ) \ && rm -f xgen-enumh install-data-local: install-libtool-import-lib uninstall-local: uninstall-libtool-import-lib swami/src/libswami/SwamiControlHub.h0000644000175000017500000000373011461334205017707 0ustar alessioalessio/* * SwamiControlHub.h - Header for control hub object * Re-transmits any events that it receives * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMI_CONTROL_HUB_H__ #define __SWAMI_CONTROL_HUB_H__ #include #include #include typedef struct _SwamiControlHub SwamiControlHub; typedef struct _SwamiControlHubClass SwamiControlHubClass; #define SWAMI_TYPE_CONTROL_HUB (swami_control_hub_get_type ()) #define SWAMI_CONTROL_HUB(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMI_TYPE_CONTROL_HUB, \ SwamiControlHub)) #define SWAMI_CONTROL_HUB_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMI_TYPE_CONTROL_HUB, \ SwamiControlHubClass)) #define SWAMI_IS_CONTROL_HUB(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMI_TYPE_CONTROL_HUB)) #define SWAMI_IS_CONTROL_HUB_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMI_TYPE_CONTROL_HUB)) /* control hub object */ struct _SwamiControlHub { SwamiControl parent_instance; /* derived from SwamiControl */ }; /* control hub class */ struct _SwamiControlHubClass { SwamiControlClass parent_class; }; GType swami_control_hub_get_type (void); SwamiControlHub *swami_control_hub_new (void); #endif swami/src/libswami/SwamiControlQueue.h0000644000175000017500000000612711461334205020260 0ustar alessioalessio/* * SwamiControlQueue.h - Swami control event queue * For queuing SwamiControl events * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMI_CONTROL_QUEUE_H__ #define __SWAMI_CONTROL_QUEUE_H__ typedef struct _SwamiControlQueue SwamiControlQueue; typedef struct _SwamiControlQueueClass SwamiControlQueueClass; #include #include #include #include #include #define SWAMI_TYPE_CONTROL_QUEUE (swami_control_queue_get_type ()) #define SWAMI_CONTROL_QUEUE(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMI_TYPE_CONTROL_QUEUE, \ SwamiControlQueue)) #define SWAMI_CONTROL_QUEUE_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMI_TYPE_CONTROL_QUEUE, \ SwamiControlQueueClass)) #define SWAMI_IS_CONTROL_QUEUE(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMI_TYPE_CONTROL_QUEUE)) #define SWAMI_IS_CONTROL_QUEUE_CLASS(obj) \ (G_TYPE_CHECK_CLASS_TYPE ((obj), SWAMI_TYPE_CONTROL_QUEUE)) /** * SwamiControlQueueTestFunc: * @queue: The queue object * @control: The control * @event: The control event * * A callback function type used to test if an event should be added to a queue. * An example of its usage would be a GUI queue which could test to see if the * event is being sent within the GUI thread or not. * * Returns: Function should return %TRUE if event should be queued, %FALSE to * send event immediately. */ typedef gboolean (* SwamiControlQueueTestFunc)(SwamiControlQueue *queue, SwamiControl *control, SwamiControlEvent *event); /* control event queue */ struct _SwamiControlQueue { SwamiLock parent_instance; /* derived from SwamiLock */ SwamiControlQueueTestFunc test_func; GList *list; /* list of queued events (struct in SwamiControlQueue.c) */ GList *tail; /* tail of the list */ }; /* control value change queue class */ struct _SwamiControlQueueClass { SwamiLockClass parent_class; }; GType swami_control_queue_get_type (void); SwamiControlQueue *swami_control_queue_new (void); void swami_control_queue_add_event (SwamiControlQueue *queue, SwamiControl *control, SwamiControlEvent *event); void swami_control_queue_run (SwamiControlQueue *queue); void swami_control_queue_set_test_func (SwamiControlQueue *queue, SwamiControlQueueTestFunc test_func); #endif swami/src/libswami/SwamiLoopFinder.h0000644000175000017500000000614511461334205017674 0ustar alessioalessio/* * SwamiLoopFinder.h - Sample loop finder object * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMI_LOOP_FINDER_H__ #define __SWAMI_LOOP_FINDER_H__ #include #include #include typedef struct _SwamiLoopFinder SwamiLoopFinder; typedef struct _SwamiLoopFinderClass SwamiLoopFinderClass; #define SWAMI_TYPE_LOOP_FINDER (swami_loop_finder_get_type ()) #define SWAMI_LOOP_FINDER(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMI_TYPE_LOOP_FINDER, \ SwamiLoopFinder)) #define SWAMI_IS_LOOP_FINDER(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMI_TYPE_LOOP_FINDER)) /* Loop finder object */ struct _SwamiLoopFinder { SwamiLock parent_instance; IpatchSample *sample; /* sample assigned to loop finder */ IpatchSampleHandle *sample_handle; /* Open handle to cached sample data (allocated) */ guint sample_size; /* size of sample */ float *sample_data; /* converted sample data */ gboolean active; /* TRUE if find is currently active */ gboolean cancel; /* set to TRUE to cancel current find */ float progress; /* if active is TRUE, progress 0.0 - 1.0 */ int max_results; /* max SwamiLoopMatch result entries */ int analysis_window; /* width in samples of analysis window */ int min_loop_size; /* minimum loop size */ int window1_start; /* sample start position of window1 search */ int window1_end; /* sample end position of window1 search */ int window2_start; /* sample start position of window1 search */ int window2_end; /* sample end position of window1 search */ int group_pos_diff; /* min pos diff of loops for separate groups */ int group_size_diff; /* min size diff of loops for separate groups */ guint exectime; /* execution time in milliseconds */ SwamiLoopResults *results; /* results object */ }; /* Loop finder class */ struct _SwamiLoopFinderClass { SwamiLockClass parent_class; }; GType swami_loop_finder_get_type (void); SwamiLoopFinder *swami_loop_finder_new (void); void swami_loop_finder_full_search (SwamiLoopFinder *finder); gboolean swami_loop_finder_verify_params (SwamiLoopFinder *finder, gboolean nudge, GError **err); gboolean swami_loop_finder_find (SwamiLoopFinder *finder, GError **err); SwamiLoopResults *swami_loop_finder_get_results (SwamiLoopFinder *finder); #endif swami/src/libswami/CMakeLists.txt0000644000175000017500000001453311466101732017223 0ustar alessioalessio# # Swami # Copyright (C) 1999-2010 Joshua "Element" Green # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; version 2 # of the License only. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA or point your web browser to http://www.gnu.org. # include_directories ( ${CMAKE_SOURCE_DIR}/src ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${GOBJECT_INCLUDEDIR} ${GOBJECT_INCLUDE_DIRS} ${LIBINSTPATCH_INCLUDEDIR} ${LIBINSTPATCH_INCLUDE_DIRS} ) # ************ library ************ set ( libswami_public_HEADERS SwamiContainer.h SwamiControl.h SwamiControlEvent.h SwamiControlFunc.h SwamiControlHub.h SwamiControlMidi.h SwamiControlProp.h SwamiControlQueue.h SwamiControlValue.h SwamiEvent_ipatch.h SwamiLock.h SwamiLog.h SwamiLoopFinder.h SwamiLoopResults.h SwamiMidiDevice.h SwamiMidiEvent.h SwamiObject.h SwamiParam.h SwamiPlugin.h SwamiPropTree.h SwamiRoot.h SwamiWavetbl.h util.h ${CMAKE_CURRENT_BINARY_DIR}/version.h ) set ( libswami_SOURCES SwamiContainer.c SwamiControl.c SwamiControlEvent.c SwamiControlFunc.c SwamiControlHub.c SwamiControlMidi.c SwamiControlProp.c SwamiControlQueue.c SwamiControlValue.c SwamiEvent_ipatch.c SwamiLock.c SwamiLog.c SwamiLoopFinder.c SwamiLoopResults.c SwamiMidiDevice.c SwamiMidiEvent.c SwamiObject.c SwamiParam.c SwamiPlugin.c SwamiPropTree.c SwamiRoot.c SwamiWavetbl.c libswami.c util.c value_transform.c ) set ( public_main_HEADER libswami.h ) link_directories ( ${GOBJECT_LIBDIR} ${GOBJECT_LIBRARY_DIRS} ${LIBINSTPATCH_LIBDIR} ${LIBINSTPATCH_LIBRARY_DIRS} ) add_definitions ( -DLOCALEDIR="${DATA_INSTALL_DIR}/locale" -DG_LOG_DOMAIN=\"libswami\" ) add_library ( libswami ${CMAKE_CURRENT_BINARY_DIR}/builtin_enums.c ${CMAKE_CURRENT_BINARY_DIR}/marshals.c ${libswami_SOURCES} ) # Version file configure_file ( ${CMAKE_CURRENT_SOURCE_DIR}/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/version.h ) install ( FILES ${libswami_public_HEADERS} ${public_main_HEADER} DESTINATION include/swami/libswami ) find_program (GLIB2_MKENUMS glib-mkenums) find_program (SED sed) add_custom_command ( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/builtin_enums.h COMMAND ${GLIB2_MKENUMS} ARGS --fhead \"\#ifndef __SWAMI_BUILTIN_ENUMS_H__\\n\" --fhead \"\#define __SWAMI_BUILTIN_ENUMS_H__\\n\\n\" --fhead \"\#include \\n\\n\" --fhead \"G_BEGIN_DECLS\\n\" --fprod \"/* enumerations from \\"@filename@\\" */\\n\" --vhead \"GType @enum_name@_get_type \(void\)\;\\n\" --vhead \"\#define SWAMI_TYPE_@ENUMSHORT@ \(@enum_name@_get_type\(\)\)\\n\" --ftail \"G_END_DECLS\\n\\n\" --ftail \"\#endif /* __SWAMI_BUILTIN_ENUMS_H__ */\" ${libswami_public_HEADERS} > ${CMAKE_CURRENT_BINARY_DIR}/builtin_enums.h WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ${libswami_public_HEADERS} ) add_custom_command ( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/builtin_enums.c COMMAND ${GLIB2_MKENUMS} ARGS --fhead \"\#include \\"libswami.h\\"\\n\" --fhead \"\#include \\"swami_priv.h\\"\\n\" --fprod \"/* enumerations from \\"@filename@\\" */\" --vhead \"static const G@Type@Value _@enum_name@_values[] = {\" --vprod \" { @VALUENAME@, \\"@VALUENAME@\\", \\"@valuenick@\\" },\" --vtail \" { 0, NULL, NULL }\\n}\;\\n\\n\" --vtail \"GType\\n@enum_name@_get_type \(void\)\\n{\\n\" --vtail \" static GType type = 0\;\\n\\n\" --vtail \" if \(G_UNLIKELY \(type == 0\)\)\\n\" --vtail \" type = g_\@type\@_register_static \(\\"@EnumName@\\", _@enum_name@_values\)\;\\n\\n\" --vtail \" return type\;\\n}\\n\\n\" ${libswami_public_HEADERS} > ${CMAKE_CURRENT_BINARY_DIR}/builtin_enums.c WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ${libswami_public_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/builtin_enums.h ) find_program (GLIB2_GENMARSHAL glib-genmarshal) add_custom_command ( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/marshals.c COMMAND ${GLIB2_GENMARSHAL} ARGS --body --prefix=swami_marshal ${CMAKE_CURRENT_SOURCE_DIR}/marshals.list >${CMAKE_CURRENT_BINARY_DIR}/marshals.c WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/marshals.list ${CMAKE_CURRENT_BINARY_DIR}/marshals.h ) add_custom_command ( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/marshals.h COMMAND ${GLIB2_GENMARSHAL} ARGS --header --prefix=swami_marshal ${CMAKE_CURRENT_SOURCE_DIR}/marshals.list >${CMAKE_CURRENT_BINARY_DIR}/marshals.h WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/marshals.list ) target_link_libraries ( libswami ${GOBJECT_LIBRARIES} ${LIBINSTPATCH_LIBRARIES} ) if ( MACOSX_FRAMEWORK ) set_property ( SOURCE ${libswami_public_HEADERS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/libswami ) set_target_properties ( libswami PROPERTIES OUTPUT_NAME "libswami" FRAMEWORK TRUE PUBLIC_HEADER "${public_main_HEADER}" FRAMEWORK_VERSION "${LIB_VERSION_CURRENT}" INSTALL_NAME_DIR ${FRAMEWORK_INSTALL_DIR} VERSION ${LIB_VERSION_INFO} SOVERSION ${LIB_VERSION_CURRENT} ) else ( MACOSX_FRAMEWORK ) set_target_properties ( libswami PROPERTIES PREFIX "lib" OUTPUT_NAME "swami" VERSION ${LIB_VERSION_INFO} SOVERSION ${LIB_VERSION_CURRENT} ) endif ( MACOSX_FRAMEWORK ) install ( TARGETS libswami RUNTIME DESTINATION ${BIN_INSTALL_DIR} LIBRARY DESTINATION ${LIB_INSTALL_DIR}${LIB_SUFFIX} ARCHIVE DESTINATION ${LIB_INSTALL_DIR}${LIB_SUFFIX} FRAMEWORK DESTINATION ${FRAMEWORK_INSTALL_DIR} BUNDLE DESTINATION ${BUNDLE_INSTALL_DIR} ) swami/src/libswami/SwamiRoot.c0000644000175000017500000004151411461353033016550 0ustar alessioalessio/* * SwamiRoot.c - Root Swami application object * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include "config.h" #include #include #include #include #include #include #include "SwamiRoot.h" #include "SwamiLog.h" #include "SwamiObject.h" #include "i18n.h" /* Maximum swap file waste in megabytes (not yet used) */ #define DEFAULT_SWAP_MAX_WASTE 64 /* Maximum sample size to import in megabytes * (To prevent "O crap, I didn't mean to load that one!") */ #define DEFAULT_SAMPLE_MAX_SIZE 32 /* Swami root object properties */ enum { PROP_0, PROP_PATCH_SEARCH_PATH, PROP_PATCH_PATH, PROP_SAMPLE_PATH, PROP_SAMPLE_FORMAT, PROP_SWAP_MAX_WASTE, PROP_SAMPLE_MAX_SIZE, PROP_PATCH_ROOT }; /* Swami root object signals */ enum { SWAMI_PROP_NOTIFY, OBJECT_ADD, /* add object */ LAST_SIGNAL }; /* --- private function prototypes --- */ static void swami_root_class_init (SwamiRootClass *klass); static void swami_root_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void swami_root_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void swami_root_init (SwamiRoot *root); guint root_signals[LAST_SIGNAL] = { 0 }; GType swami_root_get_type (void) { static GType item_type = 0; if (!item_type) { static const GTypeInfo item_info = { sizeof (SwamiRootClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) swami_root_class_init, NULL, NULL, sizeof (SwamiRoot), 0, (GInstanceInitFunc) swami_root_init, }; item_type = g_type_register_static (SWAMI_TYPE_LOCK, "SwamiRoot", &item_info, 0); } return (item_type); } static void swami_root_class_init (SwamiRootClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); root_signals[SWAMI_PROP_NOTIFY] = g_signal_new ("swami-prop-notify", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED | G_SIGNAL_NO_HOOKS, 0, NULL, NULL, g_cclosure_marshal_VOID__PARAM, G_TYPE_NONE, 1, G_TYPE_PARAM); root_signals[OBJECT_ADD] = g_signal_new ("object-add", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (SwamiRootClass, object_add), NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT); obj_class->set_property = swami_root_set_property; obj_class->get_property = swami_root_get_property; g_object_class_install_property (obj_class, PROP_PATCH_SEARCH_PATH, g_param_spec_string ("patch-search-path", N_("Patch search path"), N_("Patch search path"), NULL, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_PATCH_PATH, g_param_spec_string ("patch-path", N_("Patch path"), N_("Default patch path"), NULL, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_SAMPLE_PATH, g_param_spec_string ("sample-path", N_("Sample path"), N_("Default sample path"), NULL, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_SAMPLE_FORMAT, g_param_spec_string ("sample-format", N_("Sample format"), N_("Default sample format"), NULL, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_SWAP_MAX_WASTE, g_param_spec_int ("swap-max-waste", N_("Swap max waste"), N_("Max waste of sample swap in megabytes"), 1, G_MAXINT, DEFAULT_SWAP_MAX_WASTE, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_SAMPLE_MAX_SIZE, g_param_spec_int ("sample-max-size", N_("Sample max size"), N_("Max sample size in megabytes"), 1, G_MAXINT, DEFAULT_SAMPLE_MAX_SIZE, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_PATCH_ROOT, g_param_spec_object ("patch-root", N_("Patch root"), N_("Root container of instrument patch tree"), SWAMI_TYPE_CONTAINER, G_PARAM_READABLE | IPATCH_PARAM_NO_SAVE)); } static void swami_root_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { SwamiRoot *root = SWAMI_ROOT (object); switch (property_id) { case PROP_PATCH_SEARCH_PATH: if (root->patch_search_path) g_free (root->patch_search_path); root->patch_search_path = g_value_dup_string (value); break; case PROP_PATCH_PATH: if (root->patch_path) g_free (root->patch_path); root->patch_path = g_value_dup_string (value); break; case PROP_SAMPLE_PATH: if (root->sample_path) g_free (root->sample_path); root->sample_path = g_value_dup_string (value); break; case PROP_SAMPLE_FORMAT: if (root->sample_format) g_free (root->sample_format); root->sample_format = g_value_dup_string (value); break; case PROP_SWAP_MAX_WASTE: root->swap_max_waste = g_value_get_int (value); break; case PROP_SAMPLE_MAX_SIZE: root->sample_max_size = g_value_get_int (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swami_root_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { SwamiRoot *root = SWAMI_ROOT (object); switch (property_id) { case PROP_PATCH_SEARCH_PATH: g_value_set_string (value, root->patch_search_path); break; case PROP_PATCH_PATH: g_value_set_string (value, root->patch_path); break; case PROP_SAMPLE_PATH: g_value_set_string (value, root->sample_path); break; case PROP_SAMPLE_FORMAT: g_value_set_string (value, root->sample_format); break; case PROP_SWAP_MAX_WASTE: g_value_set_int (value, root->swap_max_waste); break; case PROP_SAMPLE_MAX_SIZE: g_value_set_int (value, root->sample_max_size); break; case PROP_PATCH_ROOT: g_value_set_object (value, root->patch_root); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swami_root_init (SwamiRoot *root) { root->swap_max_waste = DEFAULT_SWAP_MAX_WASTE; root->sample_max_size = DEFAULT_SAMPLE_MAX_SIZE; root->patch_root = swami_container_new (); root->patch_root->root = root; /* set the IpatchItem hooks active flag to make all children items execute hook callback functions (once added to root) */ ipatch_item_set_flags (IPATCH_ITEM (root->patch_root), IPATCH_ITEM_HOOKS_ACTIVE); root->proptree = swami_prop_tree_new (); /* ++ ref property tree */ swami_prop_tree_set_root (root->proptree, G_OBJECT (root)); } /** * swami_root_new: * * Create a new Swami root object which is a toplevel container for * patches, objects, configuration data and state history. * * Returns: New Swami root object */ SwamiRoot * swami_root_new (void) { return SWAMI_ROOT (g_object_new (SWAMI_TYPE_ROOT, NULL)); } /** * swami_get_root: * @object: An object registered to a #SwamiRoot, an #IpatchItem contained * in a #SwamiRoot or the root itself * * Gets the #SwamiRoot object associated with a @object. * * Returns: The #SwamiRoot object or %NULL if @object not registered to a * root. Returned root object is not referenced, we assume it won't be * destroyed. */ SwamiRoot * swami_get_root (gpointer object) { SwamiContainer *container; SwamiRoot *root = NULL; SwamiObjectPropBag *propbag; g_return_val_if_fail (G_IS_OBJECT (object), NULL); if (SWAMI_IS_ROOT (object)) root = (SwamiRoot *)object; else if (IPATCH_IS_ITEM (object)) { container = (SwamiContainer *)ipatch_item_peek_ancestor_by_type (object, SWAMI_TYPE_CONTAINER); root = container->root; } else { propbag = g_object_get_qdata (G_OBJECT (object), swami_object_propbag_quark); if (propbag) root = propbag->root; } return (root); } /** * swami_root_get_objects: * @root: Swami root object * * Get an iterator filled with toplevel objects that are the first children * of a #SwamiRoot object property tree. * * Returns: New object list with a reference count of 1 which the caller owns, * remember to unref it when finished. */ IpatchList * swami_root_get_objects (SwamiRoot *root) { GNode *node; IpatchList *list; g_return_val_if_fail (SWAMI_IS_ROOT (root), NULL); list = ipatch_list_new (); /* ++ ref new list */ SWAMI_LOCK_READ (root->proptree); node = root->proptree->tree->children; while (node) { g_object_ref (node->data); list->items = g_list_prepend (list->items, node->data); node = node->next; } SWAMI_UNLOCK_READ (root->proptree); return (list); } /** * swami_root_add_object: * @root: Swami root object * @object: Object to add * * Add an object to a Swami root property tree. A reference is held on * the object for the @root object. */ void swami_root_add_object (SwamiRoot *root, GObject *object) { g_return_if_fail (SWAMI_IS_ROOT (root)); g_return_if_fail (G_IS_OBJECT (object)); swami_object_set (object, "root", root, NULL); swami_prop_tree_prepend (root->proptree, G_OBJECT (root), object); g_signal_emit (root, root_signals[OBJECT_ADD], 0, object); } /** * swami_root_new_object: * @root: Swami root object * @type_name: Name of GObject derived GType of object to create and add to a * @root object. * * Like swami_root_add_object() but creates a new object rather than using * an existing one. * * Returns: The new GObject created or NULL on error. The caller owns a * reference on the new object and should unref it when done. The @root * also owns a reference, until swami_root_remove_object() is called on it. */ GObject * swami_root_new_object (SwamiRoot *root, const char *type_name) { GObject *obj; GType type; g_return_val_if_fail (SWAMI_IS_ROOT (root), NULL); g_return_val_if_fail (g_type_from_name (type_name) != 0, NULL); type = g_type_from_name (type_name); g_return_val_if_fail (g_type_is_a (type, G_TYPE_OBJECT), NULL); if (!(obj = g_object_new (type, NULL))) return (NULL); /* ++ ref new item */ swami_root_add_object (root, obj); return (obj); /* !! caller takes over creator's ref */ } /** * swami_root_prepend_object: * @root: Swami root object * @parent: New parent of @object * @object: Object to prepend * * Prepends an object to an object property tree in a @root object as * a child of @parent. Like swami_root_add_object() but allows parent * to specified (rather than using the @root as the parent). */ void swami_root_prepend_object (SwamiRoot *root, GObject *parent, GObject *object) { g_return_if_fail (SWAMI_IS_ROOT (root)); g_return_if_fail (G_IS_OBJECT (parent)); g_return_if_fail (G_IS_OBJECT (object)); swami_object_set (object, "root", root, NULL); swami_prop_tree_prepend (root->proptree, parent, object); g_signal_emit (root, root_signals[OBJECT_ADD], 0, object); } /** * swami_root_insert_object_before: * @root: Swami root object * @parent: New parent of @object * @sibling: Sibling to insert object before or %NULL to append * @object: Object to insert * * Inserts an object into an object property tree in a @root object as * a child of @parent and before @sibling. */ void swami_root_insert_object_before (SwamiRoot *root, GObject *parent, GObject *sibling, GObject *object) { g_return_if_fail (SWAMI_IS_ROOT (root)); g_return_if_fail (G_IS_OBJECT (parent)); g_return_if_fail (!sibling || G_IS_OBJECT (sibling)); g_return_if_fail (G_IS_OBJECT (object)); swami_object_set (object, "root", root, NULL); swami_prop_tree_insert_before (root->proptree, parent, sibling, object); g_signal_emit (root, root_signals[OBJECT_ADD], 0, object); } /** * swami_root_patch_load: * @root: Swami root object to load into * @filename: Name and path of file to load * @item: Location to store pointer to object that has been loaded into Swami * root object (or %NULL). Remember to unref the object when done with it * (not necessary of course if %NULL was passed). * @err: Location to store error info or %NULL * * Load an instrument patch file and append to Swami object tree. The caller * owns a reference to the returned patch object and should unref it when * done with the object. * * Returns: %TRUE on success, %FALSE otherwise */ gboolean swami_root_patch_load (SwamiRoot *root, const char *filename, IpatchItem **item, GError **err) { IpatchFileHandle *handle; GObject *obj; g_return_val_if_fail (SWAMI_IS_ROOT (root), FALSE); g_return_val_if_fail (filename != NULL, FALSE); g_return_val_if_fail (!err || !*err, FALSE); handle = ipatch_file_identify_open (filename, err); /* ++ open file handle */ if (!handle) return (FALSE); if (!(obj = ipatch_convert_object_to_type (G_OBJECT (handle->file), IPATCH_TYPE_BASE, err))) { ipatch_file_close (handle); /* -- close file handle */ return (FALSE); } ipatch_file_close (handle); /* -- close file handle */ ipatch_container_append (IPATCH_CONTAINER (root->patch_root), IPATCH_ITEM (obj)); /* !! if @item field was passed, then caller takes over ref */ if (item) *item = IPATCH_ITEM (obj); else g_object_unref (obj); return (TRUE); } /** * swami_root_patch_save: * @item: Patch item to save. * @filename: New file name to save to or NULL to use current one. * @err: Location to store error info or NULL * * Save a patch item to a file. * * Returns: %TRUE on success, %FALSE otherwise */ gboolean swami_root_patch_save (IpatchItem *item, const char *filename, GError **err) { IpatchConverterInfo *info; IpatchFile *file; char *dir, *tmpfname, *prop_filename = NULL; int tmpfd; g_return_val_if_fail (IPATCH_IS_ITEM (item), FALSE); g_return_val_if_fail (filename != NULL, FALSE); g_return_val_if_fail (!err || !*err, FALSE); /* if no filename specified use current one */ if (!filename) { g_object_get (item, "file-name", &prop_filename, NULL); filename = prop_filename; if (!filename) { g_set_error (err, SWAMI_ERROR, SWAMI_ERROR_INVALID, _("File name not supplied and none currently assigned")); return (FALSE); } } /* get the destination directory and create a temporary file template */ dir = g_path_get_dirname (filename); tmpfname = g_strconcat (dir, G_DIR_SEPARATOR_S, "swami_tmpXXXXXX", NULL); g_free (dir); /* open temporary file in same directory as destination */ if ((tmpfd = g_mkstemp (tmpfname)) == -1) { g_set_error (err, SWAMI_ERROR, SWAMI_ERROR_IO, _("Unable to open temp file '%s' for writing: %s"), tmpfname, g_strerror (errno)); g_free (tmpfname); g_free (prop_filename); return (FALSE); } info = ipatch_lookup_converter_info (0, G_OBJECT_TYPE (item), IPATCH_TYPE_FILE); if (!info) { g_set_error (err, SWAMI_ERROR, SWAMI_ERROR_UNSUPPORTED, _("Saving object of type '%s' to file '%s' not supported"), g_type_name (G_OBJECT_TYPE (item)), filename); close (tmpfd); unlink (tmpfname); g_free (tmpfname); g_free (prop_filename); return (FALSE); } file = IPATCH_FILE (g_object_new (info->dest_type, NULL)); /* ++ ref new file */ ipatch_file_assign_fd (file, tmpfd, TRUE); /* Assign file descriptor and set close on finalize */ /* attempt to save patch file */ if (!ipatch_convert_objects (G_OBJECT (item), G_OBJECT (file), err)) { g_object_unref (file); /* -- unref creators reference */ unlink (tmpfname); g_free (tmpfname); g_free (prop_filename); return (FALSE); } g_object_unref (file); /* -- unref creators reference */ #ifdef MINGW32 /* win32 rename won't overwrite files, so just blindly unlink destination */ unlink (filename); #endif if (rename (tmpfname, filename) == -1) { g_set_error (err, SWAMI_ERROR, SWAMI_ERROR_IO, _("Failed to rename temp file: %s"), g_strerror (errno)); unlink (tmpfname); g_free (tmpfname); g_free (prop_filename); return (FALSE); } g_free (tmpfname); if (prop_filename) g_free (prop_filename); /* same file name? */ else g_object_set (item, "file-name", filename, NULL); /* new file name */ return (TRUE); } swami/src/libswami/SwamiControlEvent.c0000644000175000017500000001516411461334205020251 0ustar alessioalessio/* * SwamiControlEvent.c - Swami event structure * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #ifdef WIN32 #include #include #endif #include "SwamiControlEvent.h" #include "swami_priv.h" GType swami_control_event_get_type (void) { static GType type = 0; if (!type) type = g_boxed_type_register_static ("SwamiControlEvent", (GBoxedCopyFunc)swami_control_event_duplicate, (GBoxedFreeFunc)swami_control_event_unref); return (type); } /** * swami_control_event_new: * @stamp: %TRUE to time stamp the new event (can be done later with * swami_control_event_stamp(). * * Create a new control event structure. * * Returns: New control event with a refcount of 1 which the caller owns. * Keep in mind that a SwamiControlEvent is not a GObject, so it does its * own refcounting with swami_control_event_ref() and * swami_control_event_unref(). */ SwamiControlEvent * swami_control_event_new (gboolean stamp) { SwamiControlEvent *event; event = g_slice_new0 (SwamiControlEvent); event->refcount = 1; if (stamp) { #ifndef WIN32 gettimeofday (&event->tick, NULL); #else static DWORD tick_start ; tick_start = GetTickCount(); event->tick.tv_sec = tick_start / 1000; event->tick.tv_usec = ( tick_start % 1000 ) * 1000; #endif } return (event); } /** * swami_control_event_free: * @event: Swami control event structure to free * * Frees a Swami control event structure. Normally this function should * not be used, swami_control_event_unref() should be used instead to allow * for multiple users of a SwamiControlEvent. Calling this function bypasses * reference counting, so make sure you know what you are doing if you use * this. */ void swami_control_event_free (SwamiControlEvent *event) { g_return_if_fail (event != NULL); if (event->origin) swami_control_event_unref (event->origin); g_value_unset (&event->value); g_slice_free (SwamiControlEvent, event); } /** * swami_control_event_duplicate: * @event: Swami control event structure * * Duplicate a control event. The refcount and active count are not duplicated, * but the tick, origin and value are. * * Returns: New duplicate control event */ SwamiControlEvent * swami_control_event_duplicate (const SwamiControlEvent *event) { SwamiControlEvent *dup; g_return_val_if_fail (event != NULL, NULL); dup = g_slice_new0 (SwamiControlEvent); dup->refcount = 1; dup->tick = event->tick; if (event->origin) dup->origin = swami_control_event_ref (event->origin); g_value_copy (&event->value, &dup->value); return (dup); } /** * swami_control_event_transform: * @event: Swami control event structure * @valtype: The type for the new value (or 0 to use the @event value type) * @trans: Value transform function * @data: User data passed to transform function * * Like swami_control_event_duplicate() but transforms the event's value * using the @trans function to the type indicated by @valtype. * * Returns: New transformed control event (caller owns creator's reference) */ SwamiControlEvent * swami_control_event_transform (SwamiControlEvent *event, GType valtype, SwamiValueTransform trans, gpointer data) { SwamiControlEvent *dup; g_return_val_if_fail (event != NULL, NULL); g_return_val_if_fail (trans != NULL, NULL); dup = g_slice_new0 (SwamiControlEvent); dup->refcount = 1; dup->tick = event->tick; dup->origin = event->origin ? event->origin : event; swami_control_event_ref (dup->origin); g_value_init (&dup->value, valtype ? valtype : G_VALUE_TYPE (&event->value)); trans (&event->value, &dup->value, data); return (dup); } /** * swami_control_event_stamp: * @event: Event to stamp * * Stamps an event with the current tick count. */ void swami_control_event_stamp (SwamiControlEvent *event) { g_return_if_fail (event != NULL); #ifndef WIN32 gettimeofday (&event->tick, NULL); #else { static DWORD tick_start ; tick_start = GetTickCount(); event->tick.tv_sec = tick_start / 1000; event->tick.tv_usec = ( tick_start % 1000 ) * 1000; } #endif } /** * swami_control_event_set_origin: * @event: Event structure * @origin: Origin event or %NULL if @event is its own origin * * Set the origin of an event. Should only be set once since its * not multi-thread locked. */ void swami_control_event_set_origin (SwamiControlEvent *event, SwamiControlEvent *origin) { g_return_if_fail (event != NULL); g_return_if_fail (event->origin == NULL); if (origin) swami_control_event_ref (origin); event->origin = origin; } /** * swami_control_event_ref: * @event: Event structure * * Increment the reference count of an event. * * Returns: The same referenced @event as a convenience. */ SwamiControlEvent * swami_control_event_ref (SwamiControlEvent *event) { g_return_val_if_fail (event != NULL, NULL); event->refcount++; return (event); } /** * swami_control_event_unref: * @event: Event structure * * Decrement the reference count of an event. If the reference count * reaches 0 the event will be freed. */ void swami_control_event_unref (SwamiControlEvent *event) { g_return_if_fail (event != NULL); g_return_if_fail (event->refcount > 0); if (--event->refcount == 0) swami_control_event_free (event); } /** * swami_control_event_active_ref: * @event: Event structure * * Increment the active propagation reference count. */ void swami_control_event_active_ref (SwamiControlEvent *event) { g_return_if_fail (event != NULL); event->active++; } /** * swami_control_event_active_unref: * @event: Event object * * Decrement the active propagation reference count. */ void swami_control_event_active_unref (SwamiControlEvent *event) { g_return_if_fail (event != NULL); g_return_if_fail (event->active > 0); event->active--; } swami/src/libswami/SwamiEvent_ipatch.c0000644000175000017500000001172411461334205020236 0ustar alessioalessio/* * SwamiEvent_ipatch.c - libInstPatch SwamiControl event types * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include "SwamiEvent_ipatch.h" #include "swami_priv.h" GType swami_event_item_add_get_type (void) { static GType item_type = 0; if (!item_type) { item_type = g_boxed_type_register_static ("SwamiEventItemAdd", (GBoxedCopyFunc) swami_event_item_add_copy, (GBoxedFreeFunc) swami_event_item_add_free); } return (item_type); } GType swami_event_item_remove_get_type (void) { static GType item_type = 0; if (!item_type) { item_type = g_boxed_type_register_static ("SwamiEventItemRemove", (GBoxedCopyFunc) swami_event_item_remove_copy, (GBoxedFreeFunc) swami_event_item_remove_free); } return (item_type); } GType swami_event_prop_change_get_type (void) { static GType item_type = 0; if (!item_type) { item_type = g_boxed_type_register_static ("SwamiEventPropChange", (GBoxedCopyFunc) swami_event_prop_change_copy, (GBoxedFreeFunc) swami_event_prop_change_free); } return (item_type); } /** * swami_event_item_add_copy: * @item_add: Patch item add event to copy * * Copies a patch item add event (an IpatchItem pointer really). * * Returns: New duplicated patch item add event. */ SwamiEventItemAdd * swami_event_item_add_copy (SwamiEventItemAdd *item_add) { return (g_object_ref (item_add)); } /** * swami_event_item_add_free: * @item_add: Patch item add event to free * * Free a patch item add event (an IpatchItem pointer really). */ void swami_event_item_add_free (SwamiEventItemAdd *item_add) { g_object_unref (item_add); } /** * swami_event_item_remove_new: * * Allocate a new patch item remove event structure. * * Returns: Newly allocated patch item remove event structure. */ SwamiEventItemRemove * swami_event_item_remove_new (void) { return (g_slice_new0 (SwamiEventItemRemove)); } /** * swami_event_item_remove_copy: * @item_remove: Patch item remove event to copy * * Copies a patch item remove event structure. * * Returns: New duplicated patch item remove event structure. */ SwamiEventItemRemove * swami_event_item_remove_copy (SwamiEventItemRemove *item_remove) { SwamiEventItemRemove *new_event; new_event = g_slice_new (SwamiEventItemRemove); new_event->item = g_object_ref (item_remove->item); new_event->parent = g_object_ref (item_remove->parent); return (new_event); } /** * swami_event_item_remove_free: * @item_remove: Patch item remove event to free * * Free a patch item remove event structure. */ void swami_event_item_remove_free (SwamiEventItemRemove *item_remove) { g_object_unref (item_remove->item); g_object_unref (item_remove->parent); g_slice_free (SwamiEventItemRemove, item_remove); } /** * swami_event_prop_change_new: * * Allocate a new patch property change event structure. * * Returns: Newly allocated patch property change event structure. */ SwamiEventPropChange * swami_event_prop_change_new (void) { return (g_slice_new0 (SwamiEventPropChange)); } /** * swami_event_prop_change_copy: * @prop_change: Patch property change event to copy * * Copies a patch property change event structure. * * Returns: New duplicated patch property change event structure. */ SwamiEventPropChange * swami_event_prop_change_copy (SwamiEventPropChange *prop_change) { SwamiEventPropChange *new_event; new_event = g_slice_new (SwamiEventPropChange); new_event->object = g_object_ref (prop_change->object); new_event->pspec = g_param_spec_ref (prop_change->pspec); if (G_IS_VALUE (&prop_change->value)) g_value_copy (&prop_change->value, &new_event->value); else memset (&prop_change->value, 0, sizeof (GValue)); return (new_event); } /** * swami_event_prop_change_free: * @prop_change: Patch property change event to free * * Free a patch property change event structure. */ void swami_event_prop_change_free (SwamiEventPropChange *prop_change) { g_object_unref (prop_change->object); g_param_spec_unref (prop_change->pspec); if (G_IS_VALUE (&prop_change->value)) g_value_unset (&prop_change->value); g_slice_free (SwamiEventPropChange, prop_change); } swami/src/libswami/SwamiWavetbl.c0000644000175000017500000003060011461334205017223 0ustar alessioalessio/* * SwamiWavetbl.c - Swami Wavetable object (base class for drivers) * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include "SwamiWavetbl.h" #include "SwamiLog.h" #include "i18n.h" /* --- signals and properties --- */ enum { ACTIVE, LAST_SIGNAL }; enum { PROP_0, PROP_VBANK, PROP_ACTIVE, PROP_ACTIVE_BANK, PROP_ACTIVE_PROGRAM }; /* --- private function prototypes --- */ static void swami_wavetbl_class_init (SwamiWavetblClass *klass); static void swami_wavetbl_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void swami_wavetbl_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void swami_wavetbl_init (SwamiWavetbl *wavetbl); static void swami_wavetbl_finalize (GObject *object); /* --- private data --- */ SwamiWavetblClass *wavetbl_class = NULL; static guint wavetbl_signals[LAST_SIGNAL] = { 0 }; static GObjectClass *parent_class = NULL; /* --- functions --- */ GType swami_wavetbl_get_type (void) { static GType item_type = 0; if (!item_type) { static const GTypeInfo item_info = { sizeof (SwamiWavetblClass), NULL, NULL, (GClassInitFunc) swami_wavetbl_class_init, NULL, NULL, sizeof (SwamiWavetbl), 0, (GInstanceInitFunc) swami_wavetbl_init, }; item_type = g_type_register_static (SWAMI_TYPE_LOCK, "SwamiWavetbl", &item_info, G_TYPE_FLAG_ABSTRACT); } return (item_type); } static void swami_wavetbl_class_init (SwamiWavetblClass *klass) { GObjectClass *objclass = G_OBJECT_CLASS (klass); parent_class = g_type_class_peek_parent (klass); objclass->set_property = swami_wavetbl_set_property; objclass->get_property = swami_wavetbl_get_property; objclass->finalize = swami_wavetbl_finalize; wavetbl_signals[ACTIVE] = g_signal_new ("active", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); g_object_class_install_property (objclass, PROP_VBANK, g_param_spec_object ("vbank", _("Virtual bank"), _("Virtual bank"), IPATCH_TYPE_VBANK, G_PARAM_READABLE)); g_object_class_install_property (objclass, PROP_ACTIVE, g_param_spec_boolean ("active", _("Active"), _("State of driver"), FALSE, G_PARAM_READABLE)); g_object_class_install_property (objclass, PROP_ACTIVE_BANK, g_param_spec_int ("active-bank", _("Active bank"), _("Active (focused) MIDI bank number"), 0, 128, 127, G_PARAM_READWRITE)); g_object_class_install_property (objclass, PROP_ACTIVE_PROGRAM, g_param_spec_int ("active-program", _("Active program"), _("Active (focused) MIDI program number"), 0, 127, 127, G_PARAM_READWRITE)); } static void swami_wavetbl_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { SwamiWavetbl *wavetbl = SWAMI_WAVETBL (object); switch (property_id) { case PROP_ACTIVE_BANK: wavetbl->active_bank = g_value_get_int (value); break; case PROP_ACTIVE_PROGRAM: wavetbl->active_program = g_value_get_int (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swami_wavetbl_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { SwamiWavetbl *wavetbl; g_return_if_fail (SWAMI_IS_WAVETBL (object)); wavetbl = SWAMI_WAVETBL (object); switch (property_id) { case PROP_VBANK: g_value_set_object (value, G_OBJECT (wavetbl->vbank)); break; case PROP_ACTIVE: g_value_set_boolean (value, wavetbl->active); break; case PROP_ACTIVE_BANK: g_value_set_int (value, wavetbl->active_bank); break; case PROP_ACTIVE_PROGRAM: g_value_set_int (value, wavetbl->active_program); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swami_wavetbl_init (SwamiWavetbl *wavetbl) { wavetbl->vbank = ipatch_vbank_new (); wavetbl->active = FALSE; wavetbl->active_bank = 127; wavetbl->active_program = 127; } static void swami_wavetbl_finalize (GObject *object) { SwamiWavetbl *wavetbl = SWAMI_WAVETBL (object); swami_wavetbl_close (wavetbl); g_object_unref (wavetbl->vbank); if (parent_class->finalize) parent_class->finalize (object); } /** * swami_wavetbl_get_virtual_bank: * @wavetbl: Swami Wavetable object * * Retrieve the #IpatchVBank object from a Wavetable instance. This * bank is the main synthesis object for the Wavetable instance, which is used * for mapping instruments to MIDI bank:program locales. * * Returns: The virtual bank of the Wavetable instance with a reference count * added for the caller. */ IpatchVBank * swami_wavetbl_get_virtual_bank (SwamiWavetbl *wavetbl) { return (g_object_ref (wavetbl->vbank)); } /** * swami_wavetbl_set_active_item_locale: * @wavetbl: Swami wave table object * @bank: MIDI bank number of active item * @program: MIDI program number of active item * * Sets the MIDI bank and program numbers (MIDI locale) of the * active item. The active item is the currently focused item in the user * interface, which doesn't necessarily have its own locale bank and program. * * MT-NOTE: This function ensures bank and program number are set atomically, * which is not assured if using the standard * g_object_set() routine. */ void swami_wavetbl_set_active_item_locale (SwamiWavetbl *wavetbl, int bank, int program) { g_return_if_fail (SWAMI_IS_WAVETBL (wavetbl)); g_return_if_fail (bank >= 0 && bank <= 128); g_return_if_fail (program >= 0 && program <= 127); SWAMI_LOCK_WRITE (wavetbl); wavetbl->active_bank = bank; wavetbl->active_program = program; SWAMI_UNLOCK_WRITE (wavetbl); } /** * swami_wavetbl_get_active_item_locale: * @wavetbl: Swami wave table object * @bank: Location to store MIDI bank number of active item or %NULL * @program: Location to store MIDI program number of active item or %NULL * * Gets the MIDI bank and program numbers (MIDI locale) of the active * item. See swami_wavetbl_set_active_item_locale() for more info. */ void swami_wavetbl_get_active_item_locale (SwamiWavetbl *wavetbl, int *bank, int *program) { g_return_if_fail (SWAMI_IS_WAVETBL (wavetbl)); SWAMI_LOCK_READ (wavetbl); if (bank) *bank = wavetbl->active_bank; if (program) *program = wavetbl->active_program; SWAMI_UNLOCK_READ (wavetbl); } /** * swami_wavetbl_open: * @wavetbl: Swami Wavetable object * @err: Location to store error information or %NULL. * * Open Wavetbl driver. * * Returns: %TRUE on success, %FALSE otherwise */ gboolean swami_wavetbl_open (SwamiWavetbl *wavetbl, GError **err) { SwamiWavetblClass *wavetbl_class; gboolean retval = TRUE; g_return_val_if_fail (SWAMI_IS_WAVETBL (wavetbl), FALSE); wavetbl_class = SWAMI_WAVETBL_GET_CLASS (wavetbl); g_return_val_if_fail (wavetbl_class->open != NULL, FALSE); if (wavetbl->active) return (TRUE); retval = wavetbl_class->open (wavetbl, err); if (retval) g_signal_emit (G_OBJECT (wavetbl), wavetbl_signals[ACTIVE], 0, TRUE); return (retval); } /** * swami_wavetbl_close: * @wavetbl: Swami Wavetable object * * Close driver, has no effect if already closed. Emits the "active" signal. */ void swami_wavetbl_close (SwamiWavetbl *wavetbl) { SwamiWavetblClass *oclass; g_return_if_fail (SWAMI_IS_WAVETBL (wavetbl)); oclass = SWAMI_WAVETBL_GET_CLASS (wavetbl); g_return_if_fail (oclass->close != NULL); if (!wavetbl->active) return; (*oclass->close)(wavetbl); g_signal_emit (G_OBJECT (wavetbl), wavetbl_signals[ACTIVE], 0, FALSE); } /** * swami_wavetbl_get_control: * @wavetbl: Swami Wavetable object * @index: Control index * * Get a MIDI control from a wavetable object. Calls the wavetable's * "get_control" method. A control @index is used to support multiple * controls (for example if the wavetable device supports more than 16 * MIDI channels). * * Returns: New MIDI control object linked to @wavetbl or %NULL if no * control with the given @index. The returned control's reference count * has been incremented and is owned by the caller, remember to unref it * when finished. */ SwamiControlMidi * swami_wavetbl_get_control (SwamiWavetbl *wavetbl, int index) { SwamiWavetblClass *wavetbl_class; SwamiControlMidi *control = NULL; g_return_val_if_fail (SWAMI_IS_WAVETBL (wavetbl), NULL); wavetbl_class = SWAMI_WAVETBL_GET_CLASS (wavetbl); if (wavetbl_class->get_control) { control = (*wavetbl_class->get_control)(wavetbl, index); if (control) g_object_ref (control); /* ++ ref control for caller */ } return (control); } /** * swami_wavetbl_load_patch: * @wavetbl: Swami Wavetable object * @patch: Patch object to load * @err: Location to store error information or %NULL. * * Load a patch into a wavetable object. * * Returns: %TRUE on success, %FALSE otherwise */ gboolean swami_wavetbl_load_patch (SwamiWavetbl *wavetbl, IpatchItem *patch, GError **err) { SwamiWavetblClass *wavetbl_class; g_return_val_if_fail (SWAMI_IS_WAVETBL (wavetbl), FALSE); g_return_val_if_fail (IPATCH_IS_ITEM (patch), FALSE); wavetbl_class = SWAMI_WAVETBL_GET_CLASS (wavetbl); g_return_val_if_fail (wavetbl_class->load_patch != NULL, FALSE); return ((*wavetbl_class->load_patch)(wavetbl, patch, err)); } /** * swami_wavetbl_load_active_item: * @wavetbl: Swami Wavetable object * @item: Patch item to load as active item. * @err: Location to store error information or %NULL. * * Load an item as the active program item. * * Returns: %TRUE on success, %FALSE otherwise */ gboolean swami_wavetbl_load_active_item (SwamiWavetbl *wavetbl, IpatchItem *item, GError **err) { SwamiWavetblClass *wavetbl_class; gboolean retval; g_return_val_if_fail (SWAMI_IS_WAVETBL (wavetbl), FALSE); g_return_val_if_fail (IPATCH_IS_ITEM (item), FALSE); wavetbl_class = SWAMI_WAVETBL_GET_CLASS (wavetbl); g_return_val_if_fail (wavetbl_class->load_active_item != NULL, FALSE); retval = (*wavetbl_class->load_active_item)(wavetbl, item, err); return (retval); } /** * swami_wavetbl_check_update_item: * @wavetbl: Swami Wavetable object * @item: Patch item to check if an update is needed * @prop: #GParamSpec of property that has changed * * Checks if a given @item needs to be updated if the property @prop has * changed. * * Returns: %TRUE if @item should be updated, %FALSE otherwise (@prop is not * a synthesis property or @item is not currently loaded in @wavetbl). */ gboolean swami_wavetbl_check_update_item (SwamiWavetbl *wavetbl, IpatchItem *item, GParamSpec *prop) { SwamiWavetblClass *oclass; gboolean retval; g_return_val_if_fail (SWAMI_IS_WAVETBL (wavetbl), FALSE); g_return_val_if_fail (IPATCH_IS_ITEM (item), FALSE); g_return_val_if_fail (G_IS_PARAM_SPEC (prop), FALSE); oclass = SWAMI_WAVETBL_GET_CLASS (wavetbl); if (!oclass->update_item) return (FALSE); retval = (*oclass->check_update_item)(wavetbl, item, prop); return (retval); } /** * swami_wavetbl_update_item: * @wavetbl: Swami Wavetable object * @item: Patch item to force update on * * Refresh a given @item object's synthesis cache. This should be called after * a change affecting synthesis output occurs to @item, which can be tested * with swami_wavetbl_check_update_item(). */ void swami_wavetbl_update_item (SwamiWavetbl *wavetbl, IpatchItem *item) { SwamiWavetblClass *oclass; g_return_if_fail (SWAMI_IS_WAVETBL (wavetbl)); g_return_if_fail (IPATCH_IS_ITEM (item)); oclass = SWAMI_WAVETBL_GET_CLASS (wavetbl); if (!oclass->update_item) return; (*oclass->update_item)(wavetbl, item); } swami/src/libswami/SwamiControlProp.c0000644000175000017500000006441011461334205020106 0ustar alessioalessio/* * SwamiControlProp.c - GObject property control object * Special support for IpatchItem properties (don't use "notify") * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include #include #include "SwamiControlProp.h" #include "libswami.h" #include "swami_priv.h" /* hash key used for cache of SwamiControlProp by Object:GParamSpec */ typedef struct { GObject *object; /* object, no ref is held, weak notify instead */ GParamSpec *pspec; /* property param spec of the control */ } ControlPropKey; /* defined in libswami.c */ extern void _swami_set_patch_prop_origin_event (SwamiControlEvent *origin); static void control_prop_weak_notify (gpointer data, GObject *was_object); static guint control_prop_hash_func (gconstpointer key); static gboolean control_prop_equal_func (gconstpointer a, gconstpointer b); static void control_prop_key_free_func (gpointer data); static void swami_control_prop_class_init (SwamiControlPropClass *klass); static void swami_control_prop_finalize (GObject *object); static GParamSpec *control_prop_get_spec_method (SwamiControl *control); static void control_prop_get_value_method (SwamiControl *control, GValue *value); static void control_prop_set_value_method (SwamiControl *control, SwamiControlEvent *event, const GValue *value); static void swami_control_prop_item_cb_notify (IpatchItemPropNotify *notify); static void swami_control_prop_item_cb_notify_event (IpatchItemPropNotify *notify); static void swami_control_prop_cb_notify (GObject *object, GParamSpec *pspec, SwamiControlProp *ctrlprop); static void swami_control_prop_cb_notify_event (GObject *object, GParamSpec *pspec, SwamiControlProp *ctrlprop); static void control_prop_object_weak_notify (gpointer user_data, GObject *object); static GObjectClass *parent_class = NULL; /* hash of GObject:GParamSpec -> SwamiControlProp objects. Only 1 control needed for an object property. */ G_LOCK_DEFINE_STATIC (control_prop_hash); static GHashTable *control_prop_hash = NULL; /* reverse hash for quick lookup by control (on control removal) * SwamiControlProp -> ControlPropKey (uses key from control_prop_hash) */ static GHashTable *control_prop_reverse_hash = NULL; /* thread private variable for preventing IpatchItem property loops, stores current origin SwamiControlEvent for property changes during IpatchItem property set, NULL when not in use */ static GStaticPrivate prop_notify_origin = G_STATIC_PRIVATE_INIT; /** * swami_get_control_prop: * @object: Object to get property control from (%NULL for wildcard, * #IpatchItem only) * @pspec: Property parameter spec of @object to get control for (%NULL for * wildcard, #IpatchItem only) * * Gets the #SwamiControlProp object associated with an object's GObject * property by @pspec. If a control for the given @object and @pspec * does not yet exist, then it is created and returned. Passing * %NULL for @object and/or @pspec create's a wildcard control which receives * property change events for a specific property of all items (@object is * %NULL), any property of a specifc item (@pspec is %NULL) or all item property * changes (both are %NULL). Note that wildcard property controls only work * for #IpatchItem derived objects currently. * * Returns: The control associated with the @object and property @pspec. * Caller owns a reference to the returned object and should unref it when * finished. */ SwamiControl * swami_get_control_prop (GObject *object, GParamSpec *pspec) { ControlPropKey key, *newkey; SwamiControlProp *control, *beatus; key.object = object; key.pspec = pspec; G_LOCK (control_prop_hash); control = (SwamiControlProp *)g_hash_table_lookup (control_prop_hash, &key); if (control) g_object_ref (control); G_UNLOCK (control_prop_hash); if (!control) { /* ++ ref control (caller takes over reference) */ control = swami_control_prop_new (object, pspec); g_return_val_if_fail (control != NULL, NULL); newkey = g_slice_new (ControlPropKey); newkey->object = object; newkey->pspec = pspec; G_LOCK (control_prop_hash); /* double check that another thread didn't create the same control between * these two locks (beat us to it) */ beatus = (SwamiControlProp *)g_hash_table_lookup (control_prop_hash, &key); if (!beatus) { g_hash_table_insert (control_prop_hash, newkey, control); g_hash_table_insert (control_prop_reverse_hash, control, newkey); } else g_object_ref (beatus); G_UNLOCK (control_prop_hash); if (beatus) /* if another thread created control, cleanup properly */ { g_slice_free (ControlPropKey, newkey); g_object_unref (control); /* -- unref */ control = beatus; } else /* passively watch the control, to remove it from hash when destroyed */ g_object_weak_ref (G_OBJECT (control), control_prop_weak_notify, NULL); } return ((SwamiControl *)control); } /* weak notify to remove control from hash when it gets destroyed */ static void control_prop_weak_notify (gpointer data, GObject *was_object) { ControlPropKey *key; G_LOCK (control_prop_hash); /* lookup key in reverse hash */ key = g_hash_table_lookup (control_prop_reverse_hash, was_object); if (key) /* still in hash? (this func may be called multiple times) */ { g_hash_table_remove (control_prop_reverse_hash, was_object); g_hash_table_remove (control_prop_hash, key); } G_UNLOCK (control_prop_hash); } /** * swami_get_control_prop_by_name: * @object: Object to get property control from * @name: A property of @object to get the control for (or %NULL for wildcard, * #IpatchItem derived objects only) * * Like swami_get_control_prop() but takes a property name * instead. It is also therefore not possible to specify a wildcard @object * (%NULL). * * Returns: The control associated with the @object and property @name. * Caller owns a reference to the returned object and should unref it when * finished. */ SwamiControl * swami_get_control_prop_by_name (GObject *object, const char *name) { GParamSpec *pspec; GObjectClass *klass; g_return_val_if_fail (G_IS_OBJECT (object), NULL); if (name) { klass = G_OBJECT_GET_CLASS (object); g_return_val_if_fail (klass != NULL, NULL); pspec = g_object_class_find_property (klass, name); g_return_val_if_fail (pspec != NULL, NULL); } else pspec = NULL; return (swami_get_control_prop (object, pspec)); } /** * swami_control_prop_connect_objects: * @src: Source object * @propname1: Property of source object (and @dest if @propname2 is %NULL). * @dest: Destination object * @propname2: Property of destination object (%NULL to use @propname1). * @flags: Same flags as for swami_control_connect(). * * Connect the properties of two objects together using #SwamiControlProp * controls. */ void swami_control_prop_connect_objects (GObject *src, const char *propname1, GObject *dest, const char *propname2, guint flags) { SwamiControl *sctrl, *dctrl; g_return_if_fail (G_IS_OBJECT (src)); g_return_if_fail (propname1 != NULL); g_return_if_fail (G_IS_OBJECT (dest)); sctrl = swami_get_control_prop_by_name (src, propname1); /* ++ ref */ g_return_if_fail (sctrl != NULL); /* ++ ref */ dctrl = swami_get_control_prop_by_name (dest, propname2 ? propname2 : propname1); if (swami_log_if_fail (dctrl != NULL)) { g_object_unref (sctrl); /* -- unref */ return; } swami_control_connect (sctrl, dctrl, flags); g_object_unref (sctrl); /* -- unref */ g_object_unref (dctrl); /* -- unref */ } /** * swami_control_prop_connect_to_control: * @src: Object with property to connect as source * @propname: Property of @object to use as source control * @dest: Destination control to connect the object property to * @flags: Same flags as for swami_control_connect(). * * A convenience function to connect an object property as the source control * to another #SwamiControl. */ void swami_control_prop_connect_to_control (GObject *src, const char *propname, SwamiControl *dest, guint flags) { SwamiControl *sctrl; g_return_if_fail (G_IS_OBJECT (src)); g_return_if_fail (propname != NULL); g_return_if_fail (SWAMI_IS_CONTROL (dest)); sctrl = swami_get_control_prop_by_name (src, propname); /* ++ ref */ g_return_if_fail (sctrl != NULL); swami_control_connect (sctrl, dest, flags); g_object_unref (sctrl); /* -- unref */ } /** * swami_control_prop_connect_from_control: * @src: Source control to connect to an object property * @dest: Object with property to connect to * @propname: Property of @object to use as destination control * @flags: Same flags as for swami_control_connect(). * * A convenience function to connect a #SwamiControl to an object property as * the destination control. */ void swami_control_prop_connect_from_control (SwamiControl *src, GObject *dest, const char *propname, guint flags) { SwamiControl *dctrl; g_return_if_fail (SWAMI_IS_CONTROL (src)); g_return_if_fail (G_IS_OBJECT (dest)); g_return_if_fail (propname != NULL); dctrl = swami_get_control_prop_by_name (dest, propname); /* ++ ref */ g_return_if_fail (dctrl != NULL); swami_control_connect (src, dctrl, flags); g_object_unref (dctrl); /* -- unref */ } static guint control_prop_hash_func (gconstpointer key) { ControlPropKey *pkey = (ControlPropKey *)key; return (GPOINTER_TO_UINT (pkey->object) + GPOINTER_TO_UINT (pkey->pspec)); } static gboolean control_prop_equal_func (gconstpointer a, gconstpointer b) { ControlPropKey *akey = (ControlPropKey *)a; ControlPropKey *bkey = (ControlPropKey *)b; return (akey->object == bkey->object && akey->pspec == bkey->pspec); } static void control_prop_key_free_func (gpointer data) { g_slice_free (ControlPropKey, data); } GType swami_control_prop_get_type (void) { static GType otype = 0; if (!otype) { static const GTypeInfo type_info = { sizeof (SwamiControlPropClass), NULL, NULL, (GClassInitFunc) swami_control_prop_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SwamiControlProp), 0, (GInstanceInitFunc) NULL }; control_prop_hash = g_hash_table_new_full (control_prop_hash_func, control_prop_equal_func, control_prop_key_free_func, NULL); control_prop_reverse_hash = g_hash_table_new (NULL, NULL); otype = g_type_register_static (SWAMI_TYPE_CONTROL, "SwamiControlProp", &type_info, 0); } return (otype); } static void swami_control_prop_class_init (SwamiControlPropClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); SwamiControlClass *control_class = SWAMI_CONTROL_CLASS (klass); parent_class = g_type_class_peek_parent (klass); obj_class->finalize = swami_control_prop_finalize; control_class->get_spec = control_prop_get_spec_method; control_class->set_spec = NULL; control_class->get_value = control_prop_get_value_method; control_class->set_value = control_prop_set_value_method; } static void swami_control_prop_finalize (GObject *object) { SwamiControlProp *ctrlprop = SWAMI_CONTROL_PROP (object); SWAMI_LOCK_WRITE (ctrlprop); if (ctrlprop->object) { if (ctrlprop->item_handler_id) ipatch_item_prop_disconnect (ctrlprop->item_handler_id); else if (g_signal_handler_is_connected (ctrlprop->object, ctrlprop->notify_handler_id)) g_signal_handler_disconnect (ctrlprop->object, ctrlprop->notify_handler_id); g_object_weak_unref (ctrlprop->object, control_prop_object_weak_notify, ctrlprop); ctrlprop->object = NULL; } if (ctrlprop->spec) g_param_spec_unref (ctrlprop->spec); SWAMI_UNLOCK_WRITE (ctrlprop); if (parent_class->finalize) parent_class->finalize (object); } /* control is locked by caller */ static GParamSpec * control_prop_get_spec_method (SwamiControl *control) { SwamiControlProp *ctrlprop = SWAMI_CONTROL_PROP (control); return (ctrlprop->spec); } /* NOT locked by caller */ static void control_prop_get_value_method (SwamiControl *control, GValue *value) { SwamiControlProp *ctrlprop = SWAMI_CONTROL_PROP (control); GObject *object; GParamSpec *spec; SWAMI_LOCK_READ (ctrlprop); if (!ctrlprop->object || !ctrlprop->spec) { SWAMI_UNLOCK_READ (ctrlprop); return; } spec = ctrlprop->spec; /* no need to ref, since owner object ref'd */ object = g_object_ref (ctrlprop->object); /* ++ ref object */ SWAMI_UNLOCK_READ (ctrlprop); /* OPTME - Faster, but doesn't work for overridden properties (wrong param_id) */ /* klass->get_property (object, SWAMI_PARAM_SPEC_ID (spec), value, spec); */ g_object_get_property (object, spec->name, value); g_object_unref (object); /* -- unref object */ } /* NOT locked by caller */ static void control_prop_set_value_method (SwamiControl *control, SwamiControlEvent *event, const GValue *value) { SwamiControlProp *ctrlprop = SWAMI_CONTROL_PROP (control); guint notify_handler_id, item_handler_id; GParamSpec *spec; GObject *object; SWAMI_LOCK_READ (ctrlprop); if (!ctrlprop->object || !ctrlprop->spec) { SWAMI_UNLOCK_READ (ctrlprop); return; } object = g_object_ref (ctrlprop->object); /* ++ ref object */ spec = ctrlprop->spec; /* no need to ref since we ref'd owner obj */ item_handler_id = ctrlprop->item_handler_id; notify_handler_id = ctrlprop->notify_handler_id; SWAMI_UNLOCK_READ (ctrlprop); if (item_handler_id) /* IpatchItem object? */ { /* set current thread IpatchItem origin event to prevent event loops */ g_static_private_set (&prop_notify_origin, event->origin ? event->origin : event, NULL); /* OPTME - Faster but can't use for overridden properties (wrong param_id) */ // klass->set_property (object, SWAMI_PARAM_SPEC_ID (spec), value, spec); g_object_set_property (object, spec->name, value); /* IpatchItem set property no longer active for this thread */ g_static_private_set (&prop_notify_origin, NULL, NULL); } else /* non IpatchItem object */ { /* block handler to avoid property set/notify loop (object "notify") */ g_signal_handler_block (object, notify_handler_id); /* OPTME - Faster but can't use for overridden properties (wrong param_id) */ // klass->set_property (object, SWAMI_PARAM_SPEC_ID (spec), value, spec); g_object_set_property (object, spec->name, value); g_signal_handler_unblock (object, notify_handler_id); } g_object_unref (object); /* -- unref the object */ /* propagate to outputs - FIXME: Should all controls do this? */ swami_control_transmit_event_loop (control, event); } /** * swami_control_prop_new: * @object: Object with property to control or %NULL for wildcard * @pspec: Parameter spec of property to control or %NULL for wildcard * * Create a new GObject property control. Note that swami_get_control_prop() * is likely more desireable to use, since it will return an existing control * if one already exists for the given @object and @pspec. * * If one of @object or @pspec is %NULL then it acts as a wildcard and the * control will send only (transmit changes for matching properties). If both * are %NULL however, the control has no active property to control (use * swami_get_control_prop() if a #IpatchItem entirely wildcard callback is * desired). If @object and/or @pspec is wildcard then the control will use * #SwamiEventPropChange events instead of just the property value. * * Returns: New GObject property control with a refcount of 1 which the caller * owns. */ SwamiControlProp * swami_control_prop_new (GObject *object, GParamSpec *pspec) { SwamiControlProp *ctrlprop; ctrlprop = g_object_new (SWAMI_TYPE_CONTROL_PROP, NULL); swami_control_prop_assign (ctrlprop, object, pspec, (!object || !pspec) && (object || pspec)); return (ctrlprop); } /** * swami_control_prop_assign: * @ctrlprop: Swami property control object * @object: Object containing the property to control (%NULL = wildcard) * @pspec: Parameter spec of the property of @object to control (%NULL = wildcard) * @send_events: Set to %TRUE to send/receive #SwamiEventPropChange events * for the @ctrlprop, %FALSE will use just the property value. * * Assign the object property to control for a #SwamiControlProp object. * If a property is already set for the control the new object property must * honor existing input/output connections by being writable/readable * respectively and have the same value type. * * If one of @object or @pspec is %NULL then it acts as a wildcard and the * control will send only (transmit changes for matching properties). If both * are %NULL however, the control has no active property to control. */ void swami_control_prop_assign (SwamiControlProp *ctrlprop, GObject *object, GParamSpec *pspec, gboolean send_events) { SwamiControl *control; GType value_type; g_return_if_fail (SWAMI_IS_CONTROL_PROP (ctrlprop)); g_return_if_fail (!object || pspec || IPATCH_IS_ITEM (object)); control = SWAMI_CONTROL (ctrlprop); if (pspec && !send_events) { value_type = G_PARAM_SPEC_VALUE_TYPE (pspec); /* use derived type if GBoxed or GObject parameter */ if (value_type == G_TYPE_BOXED || value_type == G_TYPE_OBJECT) value_type = pspec->value_type; } else value_type = SWAMI_TYPE_EVENT_PROP_CHANGE; /* set control value type */ swami_control_set_value_type (control, value_type); g_return_if_fail (control->value_type == value_type); SWAMI_LOCK_WRITE (ctrlprop); /* spec must be supplied and be writable if control has input connections */ if (control->inputs && !(pspec && (pspec->flags & G_PARAM_WRITABLE))) { g_critical ("%s: Invalid writable property control object change", G_STRLOC); SWAMI_UNLOCK_WRITE (ctrlprop); return; } /* spec can be wildcard or be readable if control has output connections */ if (control->outputs && (pspec && !(pspec->flags & G_PARAM_READABLE))) { g_critical ("%s: Invalid readable property control object change", G_STRLOC); SWAMI_UNLOCK_WRITE (ctrlprop); return; } if (ctrlprop->object) { if (ctrlprop->item_handler_id) ipatch_item_prop_disconnect (ctrlprop->item_handler_id); else if (g_signal_handler_is_connected (ctrlprop->object, ctrlprop->notify_handler_id)) g_signal_handler_disconnect (ctrlprop->object, ctrlprop->notify_handler_id); ctrlprop->item_handler_id = 0; ctrlprop->notify_handler_id = 0; g_object_weak_unref (ctrlprop->object, control_prop_object_weak_notify, ctrlprop); } if (ctrlprop->spec) g_param_spec_unref (ctrlprop->spec); ctrlprop->object = object; ctrlprop->spec = pspec; ctrlprop->send_events = send_events; if (object) g_object_weak_ref (object, control_prop_object_weak_notify, ctrlprop); if (pspec) g_param_spec_ref (pspec); /* set readable/writable control flags to reflect new object property */ if (pspec && (pspec->flags & G_PARAM_WRITABLE)) control->flags |= SWAMI_CONTROL_RECVS; else control->flags &= ~SWAMI_CONTROL_RECVS; if (!pspec || (pspec->flags & G_PARAM_READABLE)) control->flags |= SWAMI_CONTROL_SENDS; else control->flags &= ~SWAMI_CONTROL_SENDS; /* IpatchItems are handled differently, wildcard is #IpatchItem only */ if (!object || !pspec || IPATCH_IS_ITEM (object)) { /* add a IpatchItem change callback for the given property */ ctrlprop->item_handler_id = ipatch_item_prop_connect ((IpatchItem *)object, pspec, send_events ? swami_control_prop_item_cb_notify_event : swami_control_prop_item_cb_notify, NULL, /* disconnect func */ ctrlprop); } else /* regular object (not IpatchItem) */ { /* connect signal to property change notify */ char *s = g_strconcat ("notify::", pspec->name, NULL); ctrlprop->notify_handler_id = g_signal_connect (object, s, G_CALLBACK (send_events ? swami_control_prop_cb_notify_event : swami_control_prop_cb_notify), ctrlprop); g_free (s); } SWAMI_UNLOCK_WRITE (ctrlprop); } /** * swami_control_prop_assign_by_name: * @ctrlprop: Swami property control object * @object: Object containing the property to control (or %NULL to un-assign) * @prop_name: Name of property to assign to property control (or %NULL for * wildcard, #IpatchItem types only, or to un-assign if @object is also %NULL) * * Like swami_control_prop_assign() but accepts a name of a property instead * of the param spec. Note also that @object may not be wildcard, contrary * to the other function. */ void swami_control_prop_assign_by_name (SwamiControlProp *ctrlprop, GObject *object, const char *prop_name) { GParamSpec *pspec = NULL; g_return_if_fail (SWAMI_IS_CONTROL_PROP (ctrlprop)); g_return_if_fail (prop_name == NULL || object != NULL); if (prop_name) { pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), prop_name); if (!pspec) { g_warning ("%s: object class `%s' has no property named `%s'", G_STRLOC, G_OBJECT_TYPE_NAME (object), prop_name); return; } } swami_control_prop_assign (ctrlprop, object, pspec, object && !prop_name); } /* IpatchItem property change notify callback */ static void swami_control_prop_item_cb_notify (IpatchItemPropNotify *notify) { SwamiControl *ctrlprop = (SwamiControl *)(notify->user_data); SwamiControlEvent *ctrlevent, *origin; /* copy changed value to a new event */ ctrlevent = swami_control_event_new (TRUE); /* ++ ref new event */ g_value_init (&ctrlevent->value, G_VALUE_TYPE (notify->new_value)); g_value_copy (notify->new_value, &ctrlevent->value); /* IpatchItem property loop prevention, get current IpatchItem property origin event for this thread (if any) */ if ((origin = g_static_private_get (&prop_notify_origin))) swami_control_event_set_origin (ctrlevent, origin); /* transmit the new event to the controls destinations */ swami_control_transmit_event (ctrlprop, ctrlevent); swami_control_event_unref (ctrlevent); /* -- unref creator's ref */ } /* used instead of swami_control_prop_item_cb_notify() to send the value as * a SwamiEventPropChange event. */ static void swami_control_prop_item_cb_notify_event (IpatchItemPropNotify *notify) { SwamiControl *ctrlprop = (SwamiControl *)(notify->user_data); SwamiControlEvent *ctrlevent, *origin; SwamiEventPropChange *propevent; propevent = swami_event_prop_change_new (); /* create prop change event */ /* load values of property change structure */ propevent->object = g_object_ref (notify->item); propevent->pspec = g_param_spec_ref (notify->pspec); g_value_init (&propevent->value, G_VALUE_TYPE (notify->new_value)); g_value_copy (notify->new_value, &propevent->value); /* create the control event */ ctrlevent = swami_control_event_new (TRUE); /* ++ ref new event */ g_value_init (&ctrlevent->value, SWAMI_TYPE_EVENT_PROP_CHANGE); g_value_take_boxed (&ctrlevent->value, propevent); /* IpatchItem property loop prevention, get current IpatchItem property origin event for this thread (if any) */ if ((origin = g_static_private_get (&prop_notify_origin))) swami_control_event_set_origin (ctrlevent, origin); /* transmit the new event to the controls destinations */ swami_control_transmit_event (ctrlprop, ctrlevent); swami_control_event_unref (ctrlevent); /* -- unref creator's ref */ } /* property change notify signal callback */ static void swami_control_prop_cb_notify (GObject *object, GParamSpec *pspec, SwamiControlProp *ctrlprop) { GValue value = { 0 }; g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec)); /* OPTME - Faster, but doesn't work with overriden properties */ /* klass->get_property (object, SWAMI_PARAM_SPEC_ID (spec), &value, ctrlprop->spec); */ g_object_get_property (object, pspec->name, &value); swami_control_transmit_value ((SwamiControl *)ctrlprop, &value); g_value_unset (&value); } /* property change notify signal callback (sends event instead of prop value) */ static void swami_control_prop_cb_notify_event (GObject *object, GParamSpec *pspec, SwamiControlProp *ctrlprop) { SwamiEventPropChange *event; GValue value = { 0 }; /* create property change event structure and load fields */ event = swami_event_prop_change_new (); event->object = g_object_ref (object); event->pspec = g_param_spec_ref (pspec); g_value_init (&event->value, G_PARAM_SPEC_VALUE_TYPE (pspec)); g_object_get_property (object, pspec->name, &event->value); /* init value and assign prop change event */ g_value_init (&value, SWAMI_TYPE_EVENT_PROP_CHANGE); g_value_take_boxed (&value, event); swami_control_transmit_value ((SwamiControl *)ctrlprop, &value); g_value_unset (&value); } /* catches object finalization passively */ static void control_prop_object_weak_notify (gpointer user_data, GObject *object) { SwamiControlProp *ctrlprop = SWAMI_CONTROL_PROP (user_data); ControlPropKey key; SWAMI_LOCK_WRITE (ctrlprop); key.object = object; key.pspec = ctrlprop->spec; if (ctrlprop->item_handler_id) ipatch_item_prop_disconnect (ctrlprop->item_handler_id); ctrlprop->item_handler_id = 0; ctrlprop->notify_handler_id = 0; ctrlprop->object = NULL; if (ctrlprop->spec) g_param_spec_unref (ctrlprop->spec); ctrlprop->spec = NULL; SWAMI_UNLOCK_WRITE (ctrlprop); /* remove control prop hash entry if any */ G_LOCK (control_prop_hash); g_hash_table_remove (control_prop_reverse_hash, ctrlprop); g_hash_table_remove (control_prop_hash, &key); G_UNLOCK (control_prop_hash); } swami/src/libswami/SwamiLog.h0000644000175000017500000000562311461334205016354 0ustar alessioalessio/* * SwamiLog.h - Message logging and debugging functions * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMI_LOG_H__ #define __SWAMI_LOG_H__ #include /* Swami domain for g_set_error */ #define SWAMI_ERROR swami_error_quark() typedef enum { SWAMI_ERROR_FAIL, /* general failure */ SWAMI_ERROR_INVALID, /* invalid parameter/setting/etc */ SWAMI_ERROR_CANCELED, /* an operation was canceled (SwamiLoopFinder) */ SWAMI_ERROR_UNSUPPORTED, /* an unsupported feature or unhandled operation */ SWAMI_ERROR_IO /* I/O related error */ } SwamiError; GQuark swami_error_quark (void); #ifdef __GNUC__ #define swami_log_if_fail(expr) (!(expr) && \ _swami_ret_g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, \ "file %s: line %d (%s): assertion `%s' failed.", \ __FILE__, __LINE__, __PRETTY_FUNCTION__, \ #expr)) #else /* !GNUC */ #define swami_log_if_fail(expr) (!(expr) && \ _swami_ret_g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, \ "file %s: line %d: assertion `%s' failed.", \ __FILE__, __LINE__, \ #expr)) #endif int _swami_ret_g_log (const gchar *log_domain, GLogLevelFlags log_level, const gchar *format, ...); extern void _swami_pretty_log_handler (GLogLevelFlags flags, char *file, char *function, int line, char *format, ...); #ifdef SWAMI_DEBUG_ENABLED #define SWAMI_DEBUG(format, args...) \ _swami_pretty_log_handler (G_LOG_LEVEL_DEBUG, \ __FILE__, __PRETTY_FUNCTION__, __LINE__, \ format, ## args); #else #define SWAMI_DEBUG(format, args...) #endif #define SWAMI_INFO(format, args...) \ _swami_pretty_log_handler (G_LOG_LEVEL_INFO, \ __FILE__, __PRETTY_FUNCTION__, __LINE__, \ format, ## args); #define SWAMI_PARAM_ERROR(param) \ _swami_pretty_log_handler (G_LOG_LEVEL_CRITICAL, \ __FILE__, __PRETTY_FUNCTION__, __LINE__, \ "Invalid function parameter value for '%s'.", \ param); #define SWAMI_CRITICAL(format, args...) \ _swami_pretty_log_handler (G_LOG_LEVEL_CRITICAL, \ __FILE__, __PRETTY_FUNCTION__, __LINE__, \ format, ## args); #endif /* __SWAMI_LOG_H__ */ swami/src/libswami/libswami.c0000644000175000017500000001465411461334205016440 0ustar alessioalessio/* * libswami.c - libswami library functions and sub systems * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include "config.h" #include #include #include #include #include "libswami.h" #include "builtin_enums.h" #include "i18n.h" /* inactive control event expiration interval in milliseconds */ #define SWAMI_CONTROL_EVENT_EXPIRE_INTERVAL 10000 /* --- private function prototypes --- */ static gboolean swami_control_event_expire_timeout (gpointer data); static void container_add_notify (IpatchContainer *container, IpatchItem *item, gpointer user_data); static void container_remove_notify (IpatchContainer *container, IpatchItem *item, gpointer user_data); /* local libswami prototypes (in separate source files) */ void _swami_object_init (void); /* SwamiObject.c */ void _swami_plugin_initialize (void); /* SwamiPlugin.c */ void _swami_value_transform_init (void); /* value_transform.c */ /* Ipatch property and container add/remove event controls */ SwamiControl *swami_patch_prop_title_control; SwamiControl *swami_patch_add_control; SwamiControl *swami_patch_remove_control; /** * swami_init: * * Initialize libSwami (should be called before any other libSwami functions) */ void swami_init (void) { static gboolean initialized = FALSE; if (initialized) return; initialized = TRUE; ipatch_init (); /* initialize libInstPatch */ /* bind the gettext domain */ #if defined(ENABLE_NLS) bindtextdomain ("libswami", LOCALEDIR); #endif g_type_class_ref (SWAMI_TYPE_ROOT); /* initialize child properties and type rank systems */ _swami_object_init (); /* Register additional value transform functions */ _swami_value_transform_init (); /* initialize libswami types */ g_type_class_ref (SWAMI_TYPE_CONTROL); g_type_class_ref (SWAMI_TYPE_CONTROL_FUNC); g_type_class_ref (SWAMI_TYPE_CONTROL_HUB); g_type_class_ref (SWAMI_TYPE_CONTROL_MIDI); g_type_class_ref (SWAMI_TYPE_CONTROL_PROP); g_type_class_ref (SWAMI_TYPE_CONTROL_QUEUE); g_type_class_ref (SWAMI_TYPE_CONTROL_VALUE); g_type_class_ref (SWAMI_TYPE_LOCK); g_type_class_ref (SWAMI_TYPE_MIDI_DEVICE); swami_midi_event_get_type (); g_type_class_ref (SWAMI_TYPE_PLUGIN); g_type_class_ref (SWAMI_TYPE_PROP_TREE); g_type_class_ref (SWAMI_TYPE_WAVETBL); _swami_plugin_initialize (); /* initialize plugin system */ /* create IpatchItem title property control */ swami_patch_prop_title_control /* ++ ref forever */ = SWAMI_CONTROL (swami_control_prop_new (NULL, ipatch_item_pspec_title)); /* create ipatch container event controls */ swami_patch_add_control = swami_control_new (); /* ++ ref forever */ swami_patch_remove_control = swami_control_new (); /* ++ ref forever */ /* connect libInstPatch item notifies */ ipatch_container_add_connect (NULL, container_add_notify, NULL, NULL); ipatch_container_remove_connect (NULL, NULL, container_remove_notify, NULL, NULL); /* install periodic control event expiration process */ g_timeout_add (SWAMI_CONTROL_EVENT_EXPIRE_INTERVAL, swami_control_event_expire_timeout, NULL); } static gboolean swami_control_event_expire_timeout (gpointer data) { swami_control_do_event_expiration (); return (TRUE); } #if 0 /** * */ SwamiControlEvent * swami_item_prop_assign_change_event (IpatchItemPropNotify *info) { SwamiControlEvent *event, *origin; SwamiEventPropChange *prop_change; /* if event has already been created, return it */ if (info->event_ptrs[0]) return (info->event_ptrs[0]); event = swami_control_event_new (TRUE); /* ++ ref new control event */ g_value_init (&event->value, SWAMI_TYPE_EVENT_PROP_CHANGE); prop_change = swami_event_prop_change_new (); prop_change->object = g_object_ref (info->item); /* ++ ref object */ prop_change->pspec = g_param_spec_ref (info->pspec); /* ++ ref parameter spec */ g_value_init (&prop_change->value, G_VALUE_TYPE (info->new_value)); g_value_copy (info->new_value, &prop_change->value); g_value_set_boxed_take_ownership (&event->value, prop_change); /* IpatchItem property loop prevention, get current IpatchItem property origin event for this thread (if any) */ if ((origin = g_static_private_get (&prop_notify_origin))) swami_control_event_set_origin (event, origin); /* assign the pointer and destroy function to the event notify structure */ IPATCH_ITEM_PROP_NOTIFY_SET_EVENT (info, 0, event, (GDestroyNotify)swami_control_event_unref); return (event); } #endif /* IpatchContainer "add" notify callback */ static void container_add_notify (IpatchContainer *container, IpatchItem *item, gpointer user_data) { SwamiControlEvent *event; event = swami_control_event_new (TRUE); /* ++ ref new control event */ g_value_init (&event->value, SWAMI_TYPE_EVENT_ITEM_ADD); /* boxed copy handles reference counting */ g_value_set_boxed (&event->value, item); swami_control_transmit_event (swami_patch_add_control, event); swami_control_event_unref (event); /* -- unref creator's reference */ } /* IpatchContainer "remove" notify */ static void container_remove_notify (IpatchContainer *container, IpatchItem *item, gpointer user_data) { SwamiControlEvent *event; SwamiEventItemRemove *item_remove; event = swami_control_event_new (TRUE); /* ++ ref new control event */ g_value_init (&event->value, SWAMI_TYPE_EVENT_ITEM_REMOVE); item_remove = swami_event_item_remove_new (); item_remove->item = g_object_ref (item); item_remove->parent = ipatch_item_get_parent (item); g_value_set_boxed_take_ownership (&event->value, item_remove); swami_control_transmit_event (swami_patch_remove_control, event); swami_control_event_unref (event); /* -- unref creator's reference */ } swami/src/libswami/SwamiMidiEvent.h0000644000175000017500000001077511461334205017523 0ustar alessioalessio/* * SwamiMidiEvent.h - Header for MIDI event object * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMI_MIDI_EVENT_H__ #define __SWAMI_MIDI_EVENT_H__ #include #include typedef struct _SwamiMidiEvent SwamiMidiEvent; typedef struct _SwamiMidiEventNote SwamiMidiEventNote; typedef struct _SwamiMidiEventControl SwamiMidiEventControl; #define SWAMI_TYPE_MIDI_EVENT (swami_midi_event_get_type ()) /* MIDI event type (in comments Control = SwamiMidiEventControl and Note = SwamiMidiEventNote) */ typedef enum { SWAMI_MIDI_NONE, /* NULL event */ SWAMI_MIDI_NOTE, /* a note interval (Note) */ SWAMI_MIDI_NOTE_ON, /* note on event (Note) */ SWAMI_MIDI_NOTE_OFF, /* note off event (Note) */ SWAMI_MIDI_KEY_PRESSURE, /* key pressure (Note) */ SWAMI_MIDI_PITCH_BEND, /* pitch bend event -8192 - 8191 (Control) */ SWAMI_MIDI_PROGRAM_CHANGE, /* program change (Control) */ SWAMI_MIDI_CONTROL, /* 7 bit controller (Control) */ SWAMI_MIDI_CONTROL14, /* 14 bit controller (Control) */ SWAMI_MIDI_CHAN_PRESSURE, /* channel pressure (Control) */ SWAMI_MIDI_RPN, /* registered param (Control) */ SWAMI_MIDI_NRPN, /* non registered param (Control) */ /* these are used as a convenience for swami_midi_event_set() but they should not appear in the event type field, they are handled by other events above */ SWAMI_MIDI_BEND_RANGE, SWAMI_MIDI_BANK_SELECT } SwamiMidiEventType; /* structure defining parameters of a note event */ struct _SwamiMidiEventNote { guint8 note; guint8 velocity; /* _NOTE_ON, _NOTE_OFF, _KEY_PRESSURE, or _NOTE events */ guint8 off_velocity; /* _NOTE event only */ guint8 unused; guint duration; /* for SWAMI_MIDI_NOTE event only */ }; /* some standard General MIDI custom controllers */ #define SWAMI_MIDI_CC_BANK_MSB 0 #define SWAMI_MIDI_CC_MODULATION 1 #define SWAMI_MIDI_CC_VOLUME 7 #define SWAMI_MIDI_CC_PAN 10 #define SWAMI_MIDI_CC_EXPRESSION 11 #define SWAMI_MIDI_CC_BANK_LSB 32 #define SWAMI_MIDI_CC_SUSTAIN 64 #define SWAMI_MIDI_CC_REVERB 91 #define SWAMI_MIDI_CC_CHORUS 93 /* standard registered parameter numbers */ #define SWAMI_MIDI_RPN_BEND_RANGE 0 #define SWAMI_MIDI_RPN_MASTER_TUNE 1 struct _SwamiMidiEventControl { guint param; /* control number */ int value; /* control value */ }; struct _SwamiMidiEvent { SwamiMidiEventType type; int channel; /* most events send on a specific MIDI channel */ union { SwamiMidiEventNote note; SwamiMidiEventControl control; } data; }; GType swami_midi_event_get_type (void); SwamiMidiEvent *swami_midi_event_new (void); void swami_midi_event_free (SwamiMidiEvent *event); SwamiMidiEvent *swami_midi_event_copy (SwamiMidiEvent *event); void swami_midi_event_set (SwamiMidiEvent *event, SwamiMidiEventType type, int channel, int param1, int param2); void swami_midi_event_note_on (SwamiMidiEvent *event, int channel, int note, int velocity); void swami_midi_event_note_off (SwamiMidiEvent *event, int channel, int note, int velocity); void swami_midi_event_bank_select (SwamiMidiEvent *event, int channel, int bank); void swami_midi_event_program_change (SwamiMidiEvent *event, int channel, int program); void swami_midi_event_bend_range (SwamiMidiEvent *event, int channel, int cents); void swami_midi_event_pitch_bend (SwamiMidiEvent *event, int channel, int value); void swami_midi_event_control (SwamiMidiEvent *event, int channel, int ctrlnum, int value); void swami_midi_event_control14 (SwamiMidiEvent *event, int channel, int ctrlnum, int value); void swami_midi_event_rpn (SwamiMidiEvent *event, int channel, int paramnum, int value); void swami_midi_event_nrpn (SwamiMidiEvent *event, int channel, int paramnum, int value); #endif swami/src/libswami/SwamiControlQueue.c0000644000175000017500000001126611461334205020253 0ustar alessioalessio/* * SwamiControlQueue.c - Swami control event queue * For queuing SwamiControl events * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include "SwamiControlQueue.h" #include "swami_priv.h" /* queue item bag */ typedef struct { SwamiControl *control; SwamiControlEvent *event; } QueueItem; GType swami_control_queue_get_type (void) { static GType obj_type = 0; if (!obj_type) { static const GTypeInfo obj_info = { sizeof (SwamiControlQueueClass), NULL, NULL, (GClassInitFunc) NULL, NULL, NULL, sizeof (SwamiControlQueue), 0, (GInstanceInitFunc) NULL }; obj_type = g_type_register_static (SWAMI_TYPE_LOCK, "SwamiControlQueue", &obj_info, 0); } return (obj_type); } /** * swami_control_queue_new: * * Create a new control queue object. These are used to queue control events * which can then be run at a later time (within a GUI thread for example). * * Returns: New control queue with a ref count of 1 that the caller owns. */ SwamiControlQueue * swami_control_queue_new (void) { return (SWAMI_CONTROL_QUEUE (g_object_new (SWAMI_TYPE_CONTROL_QUEUE, NULL))); } /** * swami_control_queue_add_event: * @queue: Swami control queue object * @control: Control to queue an event for * @event: Control event to queue * * Adds a control event to a queue. Does not run queue test function this is * the responsibility of the caller (for added performance). */ void swami_control_queue_add_event (SwamiControlQueue *queue, SwamiControl *control, SwamiControlEvent *event) { QueueItem *item; g_return_if_fail (SWAMI_IS_CONTROL_QUEUE (queue)); g_return_if_fail (SWAMI_IS_CONTROL (control)); g_return_if_fail (event != NULL); item = g_slice_new (QueueItem); item->control = g_object_ref (control); /* ++ ref control */ item->event = swami_control_event_ref (event); /* ++ ref event */ /* ++ increment active reference, gets removed in swami_control_queue_run */ swami_control_event_active_ref (event); SWAMI_LOCK_WRITE (queue); queue->list = g_list_prepend (queue->list, item); if (!queue->tail) queue->tail = queue->list; SWAMI_UNLOCK_WRITE (queue); } /** * swami_control_queue_run: * @queue: Swami control queue object * * Process a control event queue by sending queued events to controls. */ void swami_control_queue_run (SwamiControlQueue *queue) { GList *list, *p, *temp; QueueItem *item; g_return_if_fail (SWAMI_IS_CONTROL_QUEUE (queue)); SWAMI_LOCK_WRITE (queue); list = queue->tail; /* take over the list */ queue->list = NULL; queue->tail = NULL; SWAMI_UNLOCK_WRITE (queue); /* process queue in reverse (since we prepended) */ p = list; while (p) { item = (QueueItem *)(p->data); swami_control_set_event_no_queue_loop (item->control, item->event); g_object_unref (item->control); /* -- unref control */ swami_control_event_active_unref (item->event); /* -- unref active ref */ swami_control_event_unref (item->event); /* -- unref event */ g_slice_free (QueueItem, item); temp = p; p = p->prev; temp = g_list_delete_link (temp, temp); /* assign to prevent gcc warning */ } } /** * swami_control_queue_set_test_func: * @queue: Control queue object * @test_func: Test function callback (function should return %TRUE to queue * an event or %FALSE to send immediately), can be %NULL in which case all * events are queued (the default). * * Set the queue test function which is called for each event added (and should * therefore be fast) to determine if the event should be queued or sent * immediately. Note that swami_control_queue_add_event() doesn't run the * test function, that is up to the caller (for increased performance). */ void swami_control_queue_set_test_func (SwamiControlQueue *queue, SwamiControlQueueTestFunc test_func) { g_return_if_fail (SWAMI_IS_CONTROL_QUEUE (queue)); queue->test_func = test_func; } swami/src/libswami/SwamiLoopFinder.c0000644000175000017500000007370411474034033017674 0ustar alessioalessio/* * SwamiLoopFinder.c - Sample loop finder object * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ /* * Thanks to Luis Garrido for the original loop finder algorithm code and his * interest in creating this feature for Swami. */ #include #include #include "SwamiLoopFinder.h" #include "SwamiLog.h" #include "i18n.h" #define DEFAULT_MAX_RESULTS 200 #define MAX_MAX_RESULTS 4000 #define DEFAULT_ANALYSIS_WINDOW 17 #define DEFAULT_MIN_LOOP_SIZE 10 #define DEFAULT_GROUP_POS_DIFF 20 #define DEFAULT_GROUP_SIZE_DIFF 5 /* Sample format used by loop finder */ #define SAMPLE_FORMAT IPATCH_SAMPLE_FLOAT | IPATCH_SAMPLE_MONO | IPATCH_SAMPLE_ENDIAN_HOST enum { PROP_0, PROP_RESULTS, /* SwamiLoopResults object */ PROP_ACTIVE, /* TRUE if find is in progress */ PROP_CANCEL, /* set to TRUE to cancel in progress find */ PROP_PROGRESS, /* current progress of find (0.0 - 1.0) */ PROP_SAMPLE, /* sample data assigned to loop finder */ PROP_MAX_RESULTS, /* max results to return */ PROP_ANALYSIS_WINDOW, /* size in samples of analysis window */ PROP_MIN_LOOP_SIZE, /* minimum loop size */ PROP_WINDOW1_START, /* window1 start position in samples */ PROP_WINDOW1_END, /* window1 end position in samples */ PROP_WINDOW2_START, /* window2 start position in samples */ PROP_WINDOW2_END, /* window2 end position in samples */ PROP_GROUP_POS_DIFF, /* min pos diff of loops for separate groups */ PROP_GROUP_SIZE_DIFF, /* min size diff of loops for separate groups */ PROP_EXEC_TIME /* execution time in milliseconds of find */ }; static void swami_loop_finder_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void swami_loop_finder_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void swami_loop_finder_init (SwamiLoopFinder *editor); static void swami_loop_finder_finalize (GObject *object); static void swami_loop_finder_real_set_sample (SwamiLoopFinder *finder, IpatchSample *sample); static void find_loop (SwamiLoopFinder *finder, SwamiLoopMatch *matches); G_DEFINE_TYPE (SwamiLoopFinder, swami_loop_finder, SWAMI_TYPE_LOCK); static void swami_loop_finder_class_init (SwamiLoopFinderClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); obj_class->set_property = swami_loop_finder_set_property; obj_class->get_property = swami_loop_finder_get_property; obj_class->finalize = swami_loop_finder_finalize; g_object_class_install_property (obj_class, PROP_RESULTS, g_param_spec_object ("results", _("Results"), _("Loop results object"), SWAMI_TYPE_LOOP_RESULTS, G_PARAM_READABLE)); g_object_class_install_property (obj_class, PROP_ACTIVE, g_param_spec_boolean ("active", _("Active"), _("Active"), FALSE, G_PARAM_READABLE)); g_object_class_install_property (obj_class, PROP_CANCEL, g_param_spec_boolean ("cancel", _("Cancel"), _("Cancel"), FALSE, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_PROGRESS, g_param_spec_float ("progress", _("Progress"), _("Progress"), 0.0, 1.0, 0.0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_SAMPLE, g_param_spec_object ("sample", _("Sample"), _("Sample data object"), IPATCH_TYPE_SAMPLE, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_MAX_RESULTS, g_param_spec_int ("max-results", _("Max results"), _("Max results"), 1, MAX_MAX_RESULTS, DEFAULT_MAX_RESULTS, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_ANALYSIS_WINDOW, g_param_spec_int ("analysis-window", _("Analysis window"), _("Size of analysis window"), 1, G_MAXINT, DEFAULT_ANALYSIS_WINDOW, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_MIN_LOOP_SIZE, g_param_spec_int ("min-loop-size", _("Min loop size"), _("Minimum size of matching loops"), 1, G_MAXINT, DEFAULT_MIN_LOOP_SIZE, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_WINDOW1_START, g_param_spec_int ("window1-start", _("First window start position"), _("First window start position"), 0, G_MAXINT, 0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_WINDOW1_END, g_param_spec_int ("window1-end", _("First window end position"), _("First window end position"), 0, G_MAXINT, 0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_WINDOW2_START, g_param_spec_int ("window2-start", _("Second window start position"), _("Second window start position"), 0, G_MAXINT, 0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_WINDOW2_END, g_param_spec_int ("window2-end", _("Second window end position"), _("Second window end position"), 0, G_MAXINT, 0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_GROUP_POS_DIFF, g_param_spec_int ("group-pos-diff", _("Group pos diff"), _("Min difference of loop position of separate groups"), 0, G_MAXINT, DEFAULT_GROUP_POS_DIFF, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_GROUP_SIZE_DIFF, g_param_spec_int ("group-size-diff", _("Group size diff"), _("Min difference of loop size of separate groups"), 0, G_MAXINT, 0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_EXEC_TIME, g_param_spec_uint ("exec-time", _("Exec time"), _("Execution time in milliseconds"), 0, G_MAXUINT, 0, G_PARAM_READABLE)); } static void swami_loop_finder_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { SwamiLoopFinder *finder = SWAMI_LOOP_FINDER (object); GObject *obj; switch (property_id) { case PROP_CANCEL: if (g_value_get_boolean (value)) finder->cancel = TRUE; break; case PROP_PROGRESS: finder->progress = g_value_get_float (value); break; case PROP_SAMPLE: obj = g_value_get_object (value); swami_loop_finder_real_set_sample (finder, obj ? IPATCH_SAMPLE (obj) : NULL); break; case PROP_MAX_RESULTS: finder->max_results = g_value_get_int (value); break; case PROP_ANALYSIS_WINDOW: finder->analysis_window = g_value_get_int (value); break; case PROP_MIN_LOOP_SIZE: finder->min_loop_size = g_value_get_int (value); break; case PROP_WINDOW1_START: finder->window1_start = g_value_get_int (value); break; case PROP_WINDOW1_END: finder->window1_end = g_value_get_int (value); break; case PROP_WINDOW2_START: finder->window2_start = g_value_get_int (value); break; case PROP_WINDOW2_END: finder->window2_end = g_value_get_int (value); break; case PROP_GROUP_POS_DIFF: finder->group_pos_diff = g_value_get_int (value); break; case PROP_GROUP_SIZE_DIFF: finder->group_size_diff = g_value_get_int (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swami_loop_finder_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { SwamiLoopFinder *finder = SWAMI_LOOP_FINDER (object); switch (property_id) { case PROP_RESULTS: SWAMI_LOCK_READ (finder); g_value_set_object (value, finder->results); SWAMI_UNLOCK_READ (finder); break; case PROP_ACTIVE: g_value_set_boolean (value, finder->active); break; case PROP_CANCEL: g_value_set_boolean (value, finder->cancel); break; case PROP_PROGRESS: g_value_set_float (value, finder->progress); break; case PROP_SAMPLE: g_value_set_object (value, finder->sample); break; case PROP_MAX_RESULTS: g_value_set_int (value, finder->max_results); break; case PROP_ANALYSIS_WINDOW: g_value_set_int (value, finder->analysis_window); break; case PROP_MIN_LOOP_SIZE: g_value_set_int (value, finder->min_loop_size); break; case PROP_WINDOW1_START: g_value_set_int (value, finder->window1_start); break; case PROP_WINDOW1_END: g_value_set_int (value, finder->window1_end); break; case PROP_WINDOW2_START: g_value_set_int (value, finder->window2_start); break; case PROP_WINDOW2_END: g_value_set_int (value, finder->window2_end); break; case PROP_EXEC_TIME: g_value_set_uint (value, finder->exectime); break; case PROP_GROUP_POS_DIFF: g_value_set_int (value, finder->group_pos_diff); break; case PROP_GROUP_SIZE_DIFF: g_value_set_int (value, finder->group_size_diff); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swami_loop_finder_init (SwamiLoopFinder *finder) { finder->max_results = DEFAULT_MAX_RESULTS; finder->analysis_window = DEFAULT_ANALYSIS_WINDOW; finder->min_loop_size = DEFAULT_MIN_LOOP_SIZE; finder->group_pos_diff = DEFAULT_GROUP_POS_DIFF; finder->group_size_diff = DEFAULT_GROUP_SIZE_DIFF; } static void swami_loop_finder_finalize (GObject *object) { SwamiLoopFinder *finder = SWAMI_LOOP_FINDER (object); if (finder->sample) g_object_unref (finder->sample); if (finder->sample_handle) /* Close and free old cached sample handle if any */ { ipatch_sample_handle_close (finder->sample_handle); g_slice_free (IpatchSampleHandle, finder->sample_handle); } if (finder->results) g_object_unref (finder->results); if (G_OBJECT_CLASS (swami_loop_finder_parent_class)->finalize) G_OBJECT_CLASS (swami_loop_finder_parent_class)->finalize (object); } /** * swami_loop_finder_new: * * Create a new sample loop finder object. * * Returns: New object of type #SwamiLoopFinder */ SwamiLoopFinder * swami_loop_finder_new (void) { return (SWAMI_LOOP_FINDER (g_object_new (SWAMI_TYPE_LOOP_FINDER, NULL))); } static void swami_loop_finder_real_set_sample (SwamiLoopFinder *finder, IpatchSample *sample) { IpatchSampleData *sampledata; IpatchSampleHandle *old_handle; gpointer old_sample; guint new_sample_size = 0; if (sample == finder->sample) return; if (sample) { g_object_get (sample, "sample-data", &sampledata, NULL); /* ++ ref sample data */ if (sampledata) { g_object_get (sample, "sample-size", &new_sample_size, NULL); g_object_ref (sample); /* ++ ref for loop finder */ g_object_unref (sampledata); /* -- unref sample data */ } else sample = NULL; /* no sample-data property? - No dice */ } SWAMI_LOCK_WRITE (finder); old_sample = finder->sample; old_handle = finder->sample_handle; finder->sample = sample; finder->sample_handle = NULL; finder->sample_size = new_sample_size; finder->sample_data = NULL; SWAMI_UNLOCK_WRITE (finder); if (sample) swami_loop_finder_full_search (finder); if (old_sample) g_object_unref (old_sample); /* -- unref old sample (if any) */ if (old_handle) /* Close and free old cached sample handle if any */ { ipatch_sample_handle_close (old_handle); g_slice_free (IpatchSampleHandle, old_handle); } } /** * swami_loop_finder_full_search: * @finder: Loop finder object * * Configures a loop finder to do a full loop search of the assigned sample. * Note that a sample must have already been assigned and the "analysis-window" * and "min-loop-size" parameters should be valid for it. This means: * (finder->analysis_window <= finder->sample_size) && * (finder->sample_size - finder->analysis_window) >= finder->min_loop_size. */ void swami_loop_finder_full_search (SwamiLoopFinder *finder) { int max_loop_size; g_return_if_fail (SWAMI_IS_LOOP_FINDER (finder)); g_return_if_fail (finder->sample != NULL); max_loop_size = finder->sample_size - finder->analysis_window; /* silently fail if analysis window or loop size is out of wack */ if (finder->analysis_window > finder->sample_size || max_loop_size < finder->min_loop_size) return; finder->window1_start = finder->analysis_window / 2; finder->window1_end = finder->window1_start + finder->sample_size - finder->analysis_window; finder->window2_start = finder->window1_start; finder->window2_end = finder->window1_end; g_object_notify (G_OBJECT (finder), "window1-start"); g_object_notify (G_OBJECT (finder), "window1-end"); g_object_notify (G_OBJECT (finder), "window2-start"); g_object_notify (G_OBJECT (finder), "window2-end"); } /** * swami_loop_finder_verify_params: * @finder: Loop finder object * @nudge: %TRUE to nudge start and end loop search windows into compliance * @err: Location to store error message or %NULL to ignore * * Verify a loop finder's parameters. If the @nudge parameter is %TRUE then * corrections will be made to start and end loop search windows if necessary * (changed to fit within sample and analysis window and swapped if * windows are backwards). * * Note that the other parameters will not be corrected and will still cause * errors if wacked. Nudged values are only changed if %TRUE is returned. * * Returns: %TRUE on success, %FALSE if there is a problem with the loop * finder parameters (error may be stored in @err). */ gboolean swami_loop_finder_verify_params (SwamiLoopFinder *finder, gboolean nudge, GError **err) { int halfwin, ohalfwin; int win1start, win1end; /* stores window1 start/end */ int win2start, win2end; /* stores window2 start/end */ int tmp; g_return_val_if_fail (SWAMI_IS_LOOP_FINDER (finder), FALSE); g_return_val_if_fail (!err || !*err, FALSE); /* Swap start/ends as needed */ win1start = MIN (finder->window1_start, finder->window1_end); win1end = MAX (finder->window1_start, finder->window1_end); win2start = MIN (finder->window2_start, finder->window2_end); win2end = MAX (finder->window2_start, finder->window2_end); /* Swap ranges if needed, so that window1 is start of loop */ if (win1start > win2start) { tmp = win1start; win1start = win2start; win2start = tmp; tmp = win1end; win1end = win2end; win2end = tmp; } /* calculate first and second half of analysis window */ halfwin = finder->analysis_window / 2; ohalfwin = finder->analysis_window - halfwin; /* other half */ /* analysis window is sane? */ if (finder->analysis_window > finder->sample_size) { g_set_error (err, SWAMI_ERROR, SWAMI_ERROR_INVALID, _("Analysis window is too large for sample")); return (FALSE); } /* nudge loop search windows if needed */ if (nudge) { if (win1start < halfwin) win1start = halfwin; if (win1end > (finder->sample_size - ohalfwin)) win1end = finder->sample_size - ohalfwin; if (win2start < halfwin) win2start = halfwin; if (win2end > (finder->sample_size - ohalfwin)) win2end = finder->sample_size - ohalfwin; } else { /* window1 is valid? */ if (win1start < halfwin || win1end > (finder->sample_size - ohalfwin)) { g_set_error (err, SWAMI_ERROR, SWAMI_ERROR_INVALID, _("Loop start search window is invalid")); return (FALSE); } /* loop end search window is valid? */ if (win2start < halfwin || win2end > (finder->sample_size - ohalfwin)) { g_set_error (err, SWAMI_ERROR, SWAMI_ERROR_INVALID, _("Loop end search window is invalid")); return (FALSE); } } /* make sure min_loop_size isn't impossible to satisfy */ if (win2end - win1start + 1 < finder->min_loop_size) { g_set_error (err, SWAMI_ERROR, SWAMI_ERROR_INVALID, _("Impossible to satisfy minimum loop size")); return (FALSE); } if (nudge) /* modify parameters if they have been nudged */ { if (win1start != finder->window1_start) g_object_set (finder, "window1-start", win1start, NULL); if (win1end != finder->window1_end) g_object_set (finder, "window1-end", win1end, NULL); if (win2start != finder->window2_start) g_object_set (finder, "window2-start", win2start, NULL); if (win2end != finder->window2_end) g_object_set (finder, "window2-end", win2end, NULL); } return (TRUE); } /** * swami_loop_finder_find: * @finder: Loop finder object * @err: Location to store error info or %NULL to ignore * * Execute the loop find operation. This function blocks until operation is * finished or the "cancel" property is assigned %TRUE. The "progress" * parameter is updated periodically with the current progress value (between * 0.0 and 1.0). * * Note: Not thread safe. Properties should be assigned, this function * called and the results retrieved with swami_loop_finder_get_results() in * a serialized fashion. As long as this is ensured, creating a separate * thread to call this function will be OK. The results can only be accessed * up until the next call to this function. * * Returns: TRUE on success, FALSE if the find parameter values are invalid * or operation was cancelled (in which case @err may be set). */ gboolean swami_loop_finder_find (SwamiLoopFinder *finder, GError **err) { IpatchSampleData *sampledata; IpatchSampleStore *store; SwamiLoopResults *results; SwamiLoopMatch *matches; GTimeVal start, end; int i; /* make sure parameter are sane */ if (!swami_loop_finder_verify_params (finder, FALSE, err)) return (FALSE); /* change active state */ finder->active = TRUE; g_object_notify (G_OBJECT (finder), "active"); /* sample data converted to float yet? */ if (!finder->sample_data) { g_object_get (finder->sample, "sample-data", &sampledata, NULL); /* ++ ref sample data */ g_return_val_if_fail (sampledata != NULL, FALSE); /* ++ ref sample store in floating point format */ store = ipatch_sample_data_get_cache_sample (sampledata, SAMPLE_FORMAT, IPATCH_SAMPLE_UNITY_CHANNEL_MAP, err); if (!store) { g_object_unref (sampledata); /* -- unref sample data */ return (FALSE); } g_object_unref (sampledata); /* -- unref sample data */ /* FIXME - What to do about stereo? */ /* Allocate a sample handle and open the store */ finder->sample_handle = g_slice_new (IpatchSampleHandle); if (!ipatch_sample_handle_open (IPATCH_SAMPLE (store), finder->sample_handle, 'r', 0, IPATCH_SAMPLE_UNITY_CHANNEL_MAP, err)) { g_object_unref (store); /* -- unref store */ return (FALSE); } finder->sample_data = ((IpatchSampleStoreCache *)store)->location; g_object_unref (store); /* -- unref store */ } matches = g_new (SwamiLoopMatch, finder->max_results); g_get_current_time (&start); /* run the loop finder processing algorithm */ find_loop (finder, matches); g_get_current_time (&end); finder->exectime = (end.tv_sec - start.tv_sec) * 1000; finder->exectime += (end.tv_usec - start.tv_usec + 500) / 1000; /* quit_it: */ if (finder->cancel) /* find was canceled? */ { g_free (matches); SWAMI_LOCK_WRITE (finder); if (finder->results) { g_object_unref (finder->results); finder->results = NULL; } SWAMI_UNLOCK_WRITE (finder); finder->cancel = FALSE; g_object_notify (G_OBJECT (finder), "cancel"); finder->active = FALSE; g_object_notify (G_OBJECT (finder), "active"); g_set_error (err, SWAMI_ERROR, SWAMI_ERROR_CANCELED, _("Find operation canceled")); return (FALSE); } /* search for first uninitialized result, to calculate result count */ for (i = 0; i < finder->max_results; i++) if (matches[i].start == 0 && matches[i].end == 0) break; if (i > 0) { results = swami_loop_results_new (); /* ++ ref (taken by finder) */ results->count = i; results->values = matches; } else results = NULL; SWAMI_LOCK_WRITE (finder); if (finder->results) g_object_unref (finder->results); finder->results = results; SWAMI_UNLOCK_WRITE (finder); g_object_notify (G_OBJECT (finder), "results"); finder->active = FALSE; g_object_notify (G_OBJECT (finder), "active"); return (TRUE); } /** * swami_loop_finder_get_results: * @finder: Loop finder object * * Get the loop results object from a loop finder. * * Returns: Loop results object or %NULL if none (if swami_loop_finder_find() * has not yet been called or was canceled). The caller owns a reference * to the returned object and should unref it when completed. */ SwamiLoopResults * swami_loop_finder_get_results (SwamiLoopFinder *finder) { SwamiLoopResults *results; g_return_val_if_fail (SWAMI_IS_LOOP_FINDER (finder), NULL); SWAMI_LOCK_READ (finder); results = finder->results ? g_object_ref (finder->results) : NULL; SWAMI_UNLOCK_READ (finder); return (results); } /* the loop finder algorithm, parameters should be varified before calling. */ static void find_loop (SwamiLoopFinder *finder, SwamiLoopMatch *matches) { float *sample_data = finder->sample_data; /* Pointer to sample data */ int max_results = finder->max_results; /* Maximum results to return */ int analysis_window = finder->analysis_window; /* Analysis window size */ int min_loop_size = finder->min_loop_size; /* Minimum loop size */ int win1start, win1end, win1size, win2start, win2end, win2size; /* Search window parameters */ int group_pos_diff = finder->group_pos_diff; /* Minimum result group position diff */ int group_size_diff = finder->group_size_diff; /* Minimum result group size diff */ int half_window = analysis_window / 2; /* First half of analysis window */ guint64 progress_step, progress_count; /* Progress update vars */ SwamiLoopMatch *match, *cmpmatch; float *anwin_factors; GList *match_list = NULL; GList *match_list_last = NULL; int match_list_size = 0; float match_list_worst = 1.0; int win1, win2; int startpos, endpos; int pos_diff, size_diff, loop_diff; float quality, diff; GList *p, *link, *insert, *tmp; int fract, pow2; int i; /* Swap start/ends as needed */ win1start = MIN (finder->window1_start, finder->window1_end); win1end = MAX (finder->window1_start, finder->window1_end); win2start = MIN (finder->window2_start, finder->window2_end); win2end = MAX (finder->window2_start, finder->window2_end); /* Swap ranges if needed, so that window1 is loop start search */ if (win1start > win2start) { int tmp; tmp = win1start; win1start = win2start; win2start = tmp; tmp = win1end; win1end = win2end; win2end = tmp; } win1size = win1end - win1start + 1; win2size = win2end - win2start + 1; /* Control of progress update */ progress_step = ((float)win1size * (float)win2size) / 1000.0; /* Max. 1000 progress callbacks */ progress_count = progress_step; finder->progress = 0.0; g_object_notify ((GObject *)finder, "progress"); /* Create analysis window factors array. All values in array add up to * 0.5 which when multiplied times maximum sample value difference of * 2.0 (1 - -1), gives a maximum quality value (worse quality) of 1.0. * Each neighboring factor towards the center point is twice the value of * it's outer neighbor. */ anwin_factors = g_new (float, analysis_window); /* Calculate fraction divisor */ for (i = 0, fract = 0, pow2 = 1; i <= half_window; i++, pow2 *= 2) { fract += pow2; if (i < half_window) fract += pow2; } /* Even windows are asymetrical, subtract 1 */ if (!(analysis_window & 1)) fract--; /* Calculate values for 1st half of window and center of window */ for (i = 0, pow2 = 1; i <= half_window; i++, pow2 *= 2) anwin_factors[i] = pow2 * 0.5 / fract; /* Copy values for 2nd half of window */ for (i = 0; half_window + i + 1 < analysis_window; i++) anwin_factors[half_window + i + 1] = anwin_factors[half_window - i - 1]; for (win1 = 0; win1 < win1size; win1++) { startpos = win1start + win1; for (win2 = 0; win2 < win2size; win2++) { endpos = win2start + win2; if (finder->cancel) /* if cancel flag has been set, return */ { for (p = match_list; p; p = g_list_delete_link (p, p)) g_slice_free (SwamiLoopMatch, p->data); g_free (anwin_factors); return; } /* progress management */ progress_count--; if (progress_count == 0) { progress_count = progress_step; finder->progress = ((float)win1 * win2size + win2) / ((float)win1size * win2size); g_object_notify ((GObject *)finder, "progress"); } if (startpos >= endpos || endpos - startpos + 1 < min_loop_size) continue; for (i = 0, quality = 0.0; i < analysis_window; i++) { diff = sample_data[startpos + i - half_window] - sample_data[endpos + i - half_window]; if (diff < 0) diff = -diff; quality += diff * anwin_factors[i]; } /* Skip if worse than the worst and result list already full */ if (quality >= match_list_worst && match_list_size == max_results) continue; loop_diff = endpos - startpos; insert = NULL; link = NULL; /* Look through existing matches for insert position, check if new * match is a part of an existing group and discard new match if worse * than existing group match or remove old group matches if worse quality */ for (p = match_list; p; ) { cmpmatch = (SwamiLoopMatch *)(p->data); /* Calculate position and size differences of new match and cmpmatch */ pos_diff = startpos - cmpmatch->start; size_diff = loop_diff - (cmpmatch->end - cmpmatch->start); if (pos_diff < 0) pos_diff = -pos_diff; if (size_diff < 0) size_diff = -size_diff; /* Same match group? */ if (pos_diff < group_pos_diff && size_diff < group_size_diff) { /* New match is worse? - Discard new */ if (quality >= cmpmatch->quality) break; /* New match is better - Discard old */ if (p == match_list_last) { match_list_last = p->prev; if (match_list_last) { match = (SwamiLoopMatch *)(match_list_last->data); match_list_worst = match->quality; } } if (!link) { /* Re-use list nodes */ link = p; p = p->next; match_list = g_list_remove_link (match_list, link); } else { tmp = p; p = p->next; g_slice_free (SwamiLoopMatch, tmp->data); match_list = g_list_delete_link (match_list, tmp); } match_list_size--; continue; } if (!insert && quality < cmpmatch->quality) insert = p; p = p->next; } /* Discard new match? */ if (p) continue; /* max results reached? */ if (match_list_size == max_results) { if (insert == match_list_last) insert = NULL; if (!link) { /* Re-use list nodes */ link = match_list_last; match_list_last = match_list_last->prev; match_list = g_list_remove_link (match_list, link); } else { tmp = match_list_last; match_list_last = match_list_last->prev; g_slice_free (SwamiLoopMatch, tmp->data); match_list = g_list_delete_link (match_list, tmp); } match = (SwamiLoopMatch *)(match_list_last->data); match_list_worst = match->quality; match_list_size--; } if (!link) { match = g_slice_new (SwamiLoopMatch); link = g_list_append (NULL, match); } else match = link->data; match_list_size++; match->start = startpos; match->end = endpos; match->quality = quality; if (insert) { link->prev = insert->prev; link->next = insert; if (insert->prev) insert->prev->next = link; else match_list = link; insert->prev = link; } else /* Append */ { if (match_list_last) { match_list_last->next = link; link->prev = match_list_last; } else match_list = link; match_list_last = link; match = (SwamiLoopMatch *)(match_list_last->data); match_list_worst = match->quality; } } } for (p = match_list, i = 0; p; p = g_list_delete_link (p, p), i++) { match = (SwamiLoopMatch *)(p->data); #if 0 // Debugging output of results printf ("Quality: %0.4f start: %d end: %d\n", match->quality, match->start, match->end); for (i2 = 0; i2 < analysis_window; i2++) { float f; diff = sample_data[match->start - half_window + i2] - sample_data[match->end - half_window + i2]; if (diff < 0.0) diff = -diff; f = (float)diff * anwin_factors[i2]; printf (" %d diff:%0.8f * factor:%0.8f = %0.8f\n", i2, diff, anwin_factors[i2], f); } #endif matches[i].start = match->start; matches[i].end = match->end; matches[i].quality = match->quality; g_slice_free (SwamiLoopMatch, match); } for (; i < max_results; i++) { matches[i].start = 0; matches[i].end = 0; matches[i].quality = 1.0; } finder->progress = 1.0; g_object_notify ((GObject *)finder, "progress"); g_free (anwin_factors); } swami/src/libswami/libswami.def0000644000175000017500000001457310313226600016746 0ustar alessioalessioLIBRARY libswami-0.dll EXPORTS _swami_object_init _swami_param_init _swami_plugin_initialize _swami_pretty_log_handler _swami_ret_g_log _swami_set_patch_prop_origin_event _swami_state_types_init _swami_util_init group_parent_class DATA item_parent_class DATA patch_add_parent_class DATA patch_change_parent_class DATA patch_remove_parent_class DATA root_signals DATA state_parent_class DATA swami_add_patch_prop_callback swami_clear_item_prop_change_cache swami_control_conn_flags_get_type swami_control_conn_priority_get_type swami_control_connect swami_control_debug DATA swami_control_disconnect swami_control_disconnect_all swami_control_disconnect_unref swami_control_do_event_expiration swami_control_event_active_ref swami_control_event_active_unref swami_control_event_duplicate swami_control_event_free swami_control_event_get_type swami_control_event_new swami_control_event_ref swami_control_event_set_origin swami_control_event_stamp swami_control_event_unref swami_control_flags_get_type swami_control_func_assign_funcs swami_control_func_get_type swami_control_func_new swami_control_get_connections swami_control_get_flags swami_control_get_type swami_control_get_value swami_control_get_value_native swami_control_hub_get_type swami_control_hub_new swami_control_midi_get_type swami_control_midi_new swami_control_midi_send swami_control_midi_set_callback swami_control_midi_transmit swami_control_new swami_control_new_event swami_control_prop_assign_property swami_control_prop_get_type swami_control_prop_new swami_control_queue_add_event swami_control_queue_get_type swami_control_queue_new swami_control_queue_run swami_control_queue_set_test_func swami_control_ref_queue swami_control_ref_spec swami_control_set_event swami_control_set_event_no_queue swami_control_set_event_no_queue_loop swami_control_set_flags swami_control_set_queue swami_control_set_spec swami_control_set_value swami_control_set_value_no_queue swami_control_set_value_type swami_control_slave_spec swami_control_transmit_event swami_control_transmit_event_loop swami_control_transmit_value swami_control_value_alloc_value swami_control_value_assign_value swami_control_value_get_type swami_control_value_new swami_error_get_type swami_error_quark swami_event_item_add_copy swami_event_item_add_free swami_event_item_add_get_type swami_event_item_remove_copy swami_event_item_remove_free swami_event_item_remove_get_type swami_event_item_remove_new swami_event_prop_change_copy swami_event_prop_change_free swami_event_prop_change_get_type swami_event_prop_change_new swami_find_object_property swami_get_root swami_init swami_list_object_properties swami_lock_get_atomic swami_lock_get_type swami_lock_set_atomic swami_marshal_VOID__OBJECT_UINT swami_midi_device_close swami_midi_device_get_type swami_midi_device_new swami_midi_device_open swami_midi_device_ref_control swami_midi_event_bank_select swami_midi_event_control swami_midi_event_control14 swami_midi_event_copy swami_midi_event_free swami_midi_event_get_type swami_midi_event_new swami_midi_event_note_off swami_midi_event_note_on swami_midi_event_nrpn swami_midi_event_pitch_bend swami_midi_event_rpn swami_midi_event_set swami_midi_event_set_bend_range swami_midi_event_set_program swami_midi_event_type_get_type swami_object_clear_flags swami_object_find_by_type swami_object_flags_get_type swami_object_get swami_object_get_flags swami_object_get_property swami_object_get_valist swami_object_propbag_quark DATA swami_object_ref_by_name swami_object_ref_by_type swami_object_remove swami_object_remove_recursive swami_object_replace swami_object_set swami_object_set_default swami_object_set_flags swami_object_set_property swami_object_set_valist swami_param_convert swami_param_convert_new swami_param_get_digits swami_param_get_limits swami_param_set_digits swami_param_set_limits swami_param_type_from_value_type swami_patch_add_control DATA swami_patch_load_ref swami_patch_prop_control DATA swami_patch_remove_control DATA swami_patch_save swami_plugin_add_path swami_plugin_find swami_plugin_get_list swami_plugin_get_type swami_plugin_is_loaded swami_plugin_load swami_plugin_load_absolute swami_plugin_load_all swami_plugin_load_plugin swami_prop_tree_add_value swami_prop_tree_get_children swami_prop_tree_get_type swami_prop_tree_insert_before swami_prop_tree_new swami_prop_tree_node_flags_get_type swami_prop_tree_object_get_node swami_prop_tree_prepend swami_prop_tree_remove swami_prop_tree_remove_recursive swami_prop_tree_remove_value swami_prop_tree_replace swami_prop_tree_set_root swami_prop_tree_xml_save_state swami_rank_get_type swami_remove_patch_prop_callback swami_remove_patch_prop_callback_matched swami_root_add_object swami_root_get_objects swami_root_get_type swami_root_insert_object_before swami_root_new swami_root_new_object swami_root_prepend_object swami_state_begin_group swami_state_end_group swami_state_get_type swami_state_get_undo_depends swami_state_group_flags_get_type swami_state_group_get_type swami_state_item_conflict swami_state_item_depend swami_state_item_describe swami_state_item_flags_get_type swami_state_item_get_type swami_state_item_restore swami_state_item_type_get_type swami_state_new swami_state_patch_add_get_type swami_state_patch_change_get_type swami_state_patch_remove_get_type swami_state_record swami_state_record_item swami_state_ref_active_group swami_state_retract swami_state_set_active_group swami_state_undo swami_type_get_children swami_type_get_default swami_type_get_rank swami_type_set_rank swami_util_free_value swami_util_get_child_types swami_util_new_value swami_wavetbl_close swami_wavetbl_get_temp_item_locale swami_wavetbl_get_type swami_wavetbl_load_patch swami_wavetbl_load_temp_item swami_wavetbl_open swami_wavetbl_ref_control swami_wavetbl_set_gen_realtime swami_wavetbl_set_temp_item_locale swami_xml_is_doc swami_xml_new_doc swami_xml_object_get_type swami_xml_object_get_xml swami_xml_object_set_xml swami_xml_read_file swami_xml_restore_ctx_add_fixup swami_xml_restore_ctx_fixup swami_xml_restore_ctx_get_type swami_xml_restore_ctx_new swami_xml_restore_object swami_xml_restore_object_state swami_xml_restore_object_state_by_type swami_xml_restore_properties_by_type swami_xml_save_ctx_get_object_id swami_xml_save_ctx_get_type swami_xml_save_ctx_new swami_xml_save_object swami_xml_save_object_node swami_xml_save_object_state swami_xml_save_object_state_by_type swami_xml_save_properties_by_type swami_xml_state_get_type swami_xml_write_file wavetbl_class DATA swami/src/libswami/SwamiLoopResults.h0000644000175000017500000000372311461334205020125 0ustar alessioalessio/* * SwamiLoopResults.h - Sample loop finder results object * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMI_LOOP_RESULTS_H__ #define __SWAMI_LOOP_RESULTS_H__ #include #include typedef struct _SwamiLoopResults SwamiLoopResults; typedef struct _SwamiLoopResultsClass SwamiLoopResultsClass; #define SWAMI_TYPE_LOOP_RESULTS (swami_loop_results_get_type ()) #define SWAMI_LOOP_RESULTS(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMI_TYPE_LOOP_RESULTS, \ SwamiLoopResults)) #define SWAMI_IS_LOOP_RESULTS(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMI_TYPE_LOOP_RESULTS)) /* loop match structure */ typedef struct { guint start; guint end; float quality; } SwamiLoopMatch; /* Loop results object */ struct _SwamiLoopResults { GObject parent_instance; /*< public >*/ SwamiLoopMatch *values; /* loop match result values */ int count; /* number of entries in values */ }; /* Loop finder class */ struct _SwamiLoopResultsClass { GObjectClass parent_class; }; GType swami_loop_results_get_type (void); SwamiLoopResults *swami_loop_results_new (void); SwamiLoopMatch *swami_loop_results_get_values (SwamiLoopResults *results, guint *count); #endif swami/src/libswami/SwamiControl.c0000644000175000017500000016417111464144605017260 0ustar alessioalessio/* * SwamiControl.c - Swami control base object * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include "SwamiControl.h" #include "SwamiControlEvent.h" #include "SwamiControlQueue.h" #include "SwamiControlFunc.h" #include "SwamiControlProp.h" #include "SwamiLog.h" #include "SwamiParam.h" #include "swami_priv.h" #include "util.h" #include "marshals.h" #include "config.h" /* work around for bug in G_BREAKPOINT where SIGTRAP symbol is used on * some architectures without including signal.h header. */ #if DEBUG #include #endif /* max number of destination connections per control (for mem optimizations) */ #define MAX_DEST_CONNECTIONS 64 enum { CONNECT_SIGNAL, DISCONNECT_SIGNAL, SPEC_CHANGED_SIGNAL, SIGNAL_COUNT }; /* a structure defining an endpoint of a connection */ typedef struct _SwamiControlConn { guint flags; /* SwamiControlConnPriority | SwamiControlConnFlags */ SwamiControl *control; /* connection control */ /* for src -> dest connections only */ SwamiValueTransform trans; /* transform func */ GDestroyNotify destroy; /* function to call when connection is destroyed */ gpointer data; /* user data to pass to transform function */ } SwamiControlConn; #define swami_control_conn_new() g_slice_new0 (SwamiControlConn) #define swami_control_conn_free(conn) g_slice_free (SwamiControlConn, conn) /* bag used for transmitting values to destination controls */ typedef struct { SwamiControl *control; SwamiValueTransform trans; gpointer data; } CtrlUpdateBag; static void swami_control_class_init (SwamiControlClass *klass); static void swami_control_init (SwamiControl *control); static void swami_control_finalize (GObject *object); static void swami_control_connect_real (SwamiControl *src, SwamiControl *dest, SwamiValueTransform trans, gpointer data, GDestroyNotify destroy, guint flags); static gint GCompare_func_conn_priority (gconstpointer a, gconstpointer b); static void item_prop_value_transform (const GValue *src, GValue *dest, gpointer data); static void swami_control_real_disconnect (SwamiControl *c1, SwamiControl *c2, guint flags); static inline void swami_control_set_event_real (SwamiControl *control, SwamiControlEvent *event); static inline gboolean swami_control_loop_check (SwamiControl *control, SwamiControlEvent *event); /* a master list of all controls, used for doing periodic inactive event expiration cleanup */ G_LOCK_DEFINE_STATIC (control_list); static GList *control_list = NULL; static GObjectClass *parent_class = NULL; static guint control_signals[SIGNAL_COUNT] = { 0 }; /* debug flag for enabling display of control operations */ #if DEBUG gboolean swami_control_debug = FALSE; SwamiControl *swami_control_break = NULL; #define SWAMI_CONTROL_TEST_BREAK(a, b) \ if (swami_control_break && (a == swami_control_break || b == swami_control_break)) \ G_BREAKPOINT () /* generate a descriptive control description string, must be freed when finished */ static char * pretty_control (SwamiControl *ctrl) { char *s; if (!ctrl) return (g_strdup ("")); if (SWAMI_IS_CONTROL_FUNC (ctrl)) { SwamiControlFunc *fn = SWAMI_CONTROL_FUNC (ctrl); s = g_strdup_printf ("<%s>%p (get=%p, set=%p)", G_OBJECT_TYPE_NAME (fn), fn, fn->get_func, fn->set_func); } else if (SWAMI_IS_CONTROL_PROP (ctrl)) { SwamiControlProp *pc = SWAMI_CONTROL_PROP (ctrl); s = g_strdup_printf ("<%s>%p (object=<%s>%p, property='%s')", G_OBJECT_TYPE_NAME (pc), pc, pc->object ? G_OBJECT_TYPE_NAME (pc->object) : "", pc->object, pc->spec ? pc->spec->name : ""); } else s = g_strdup_printf ("<%s>%p", G_OBJECT_TYPE_NAME (ctrl), ctrl); return (s); } #endif GType swami_control_get_type (void) { static GType obj_type = 0; if (!obj_type) { static const GTypeInfo obj_info = { sizeof (SwamiControlClass), NULL, NULL, (GClassInitFunc) swami_control_class_init, NULL, NULL, sizeof (SwamiControl), 0, (GInstanceInitFunc) swami_control_init }; obj_type = g_type_register_static (SWAMI_TYPE_LOCK, "SwamiControl", &obj_info, 0); } return (obj_type); } static void swami_control_class_init (SwamiControlClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); parent_class = g_type_class_peek_parent (klass); obj_class->finalize = swami_control_finalize; klass->connect = NULL; klass->disconnect = NULL; control_signals[CONNECT_SIGNAL] = g_signal_new ("connect", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (SwamiControlClass, connect), NULL, NULL, swami_marshal_VOID__OBJECT_UINT, G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_UINT); control_signals[DISCONNECT_SIGNAL] = g_signal_new ("disconnect", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (SwamiControlClass, disconnect), NULL, NULL, swami_marshal_VOID__OBJECT_UINT, G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_UINT); control_signals[SPEC_CHANGED_SIGNAL] = g_signal_new ("spec-changed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__PARAM, G_TYPE_NONE, 1, G_TYPE_PARAM); } /* creating an instance of SwamiControl creates a send only event control */ static void swami_control_init (SwamiControl *control) { control->flags = SWAMI_CONTROL_SENDS; /* prepend control to master list */ G_LOCK (control_list); control_list = g_list_prepend (control_list, control); G_UNLOCK (control_list); } static void swami_control_finalize (GObject *object) { SwamiControl *control = SWAMI_CONTROL (object); swami_control_disconnect_all (control); G_LOCK (control_list); control_list = g_list_remove (control_list, object); G_UNLOCK (control_list); } /** * swami_control_new: * * Create a new #SwamiControl instance. #SwamiControl is the base class for * other control types as well. Creating an instance of a #SwamiControl * will create a send only event control. * * Returns: New #SwamiControl object, the caller owns a reference. */ SwamiControl * swami_control_new (void) { return (SWAMI_CONTROL (g_object_new (SWAMI_TYPE_CONTROL, NULL))); } /** * swami_control_connect: * @src: Source control to connect (readable) * @dest: Destination control to connect (writable) * @flags: Flags for this connection (#SwamiControlConnFlags) * * Connect two controls (i.e., when the @src control's value changes * the @dest control is set to this value). Useful flags include the * #SWAMI_CONTROL_CONN_INIT flag which will cause @dest to be set to * the current value of @src and #SWAMI_CONTROL_CONN_BIDIR which will * cause a bi-directional connection to be made (as if 2 calls where * made to this function with the @src and @dest swapped the second * time). The connection priority can also be set via the flags field * by or-ing in #SwamiControlConnPriority values (assumes default * priority if not specified). The priority determines the order in * which connections are processed. The #SWAMI_CONTROL_CONN_SPEC flag will * cause the parameter spec of the @dest control to be set to that of @src. */ void swami_control_connect (SwamiControl *src, SwamiControl *dest, guint flags) { swami_control_connect_transform (src, dest, flags, NULL, NULL, NULL, NULL, NULL, NULL); } /** * swami_control_connect_transform: * @src: Source control to connect (readable) * @dest: Destination control to connect (writable) * @flags: Flags for this connection (#SwamiControlConnFlags). * @trans1: Value transform function from @src to @dest (or %NULL for no transform) * @trans2: Value transform function from @dest to @src * (#SWAMI_CONTROL_CONN_BIDIR only, %NULL for no transform). * @data1: User data to pass to @trans1 function. * @data2: User data to pass to @trans2 function. * (#SWAMI_CONTROL_CONN_BIDIR only, %NULL for no transform). * @destroy1: Optional callback to free @data1 when @trans1 is disconnected. * @destroy2: Optional callback to free @data2 when @trans2 is disconnected. * * Like swami_control_connect() but transform functions can be specified * during connect, rather than having to call swami_control_set_transform() * later. */ void swami_control_connect_transform (SwamiControl *src, SwamiControl *dest, guint flags, SwamiValueTransform trans1, SwamiValueTransform trans2, gpointer data1, gpointer data2, GDestroyNotify destroy1, GDestroyNotify destroy2) { guint flags2; g_return_if_fail (SWAMI_IS_CONTROL (src)); g_return_if_fail (SWAMI_IS_CONTROL (dest)); if (flags & SWAMI_CONTROL_CONN_BIDIR) { swami_control_connect_real (src, dest, trans1, data1, destroy1, flags); flags2 = flags & ~(SWAMI_CONTROL_CONN_INIT | SWAMI_CONTROL_CONN_SPEC); swami_control_connect_real (dest, src, trans2, data2, destroy2, flags2); } else swami_control_connect_real (src, dest, trans1, data1, destroy1, flags); #if DEBUG if (swami_control_debug) { char *s1, *s2; s1 = pretty_control (src); s2 = pretty_control (dest); g_message ("Connect: %s %s %s", s1, (flags & SWAMI_CONTROL_CONN_BIDIR) ? "<-->" : "-->", s2); g_free (s1); g_free (s2); SWAMI_CONTROL_TEST_BREAK (src, dest); } #endif } static void swami_control_connect_real (SwamiControl *src, SwamiControl *dest, SwamiValueTransform trans, gpointer data, GDestroyNotify destroy, guint flags) { SwamiControlConn *sconn, *dconn; GValue value = { 0 }, transval = { 0 }; /* allocate and init connections */ sconn = swami_control_conn_new (); sconn->flags = (flags & SWAMI_CONTROL_CONN_PRIORITY_MASK) | SWAMI_CONTROL_CONN_OUTPUT; sconn->control = dest; sconn->trans = trans; sconn->data = data; sconn->destroy = destroy; dconn = swami_control_conn_new (); dconn->flags = (flags & SWAMI_CONTROL_CONN_PRIORITY_MASK) | SWAMI_CONTROL_CONN_INPUT; dconn->control = src; /* add output connection to source control */ SWAMI_LOCK_WRITE (src); if (swami_log_if_fail (src->flags & SWAMI_CONTROL_SENDS)) { SWAMI_UNLOCK_WRITE (src); goto err_src; } if (g_slist_length (src->outputs) >= MAX_DEST_CONNECTIONS) { SWAMI_UNLOCK_WRITE (src); g_critical ("Maximum number of control connections reached!"); goto err_src; } /* add connection to list */ src->outputs = g_slist_insert_sorted (src->outputs, sconn, GCompare_func_conn_priority); g_object_ref (dest); /* ++ ref dest for source connection */ SWAMI_UNLOCK_WRITE (src); /* add input connection to destination control */ SWAMI_LOCK_WRITE (dest); if (swami_log_if_fail (dest->flags & SWAMI_CONTROL_RECVS)) { SWAMI_UNLOCK_WRITE (dest); goto err_dest; } dest->inputs = g_slist_prepend (dest->inputs, dconn); g_object_ref (src); /* ++ ref src for destination connection */ SWAMI_UNLOCK_WRITE (dest); /* check if connect parameter spec flag is set for src, and slave the parameter spec if so */ if (flags & SWAMI_CONTROL_CONN_SPEC) swami_control_sync_spec (dest, src, trans, data); /* initialize destination control from current source value? */ if (flags & SWAMI_CONTROL_CONN_INIT) { swami_control_get_value_native (src, &value); if (trans) /* transform function provided? */ { g_value_init (&transval, dest->value_type ? dest->value_type : G_VALUE_TYPE (&value)); trans (&value, &transval, data); swami_control_set_value (dest, &transval); g_value_unset (&transval); } else swami_control_set_value (dest, &value); g_value_unset (&value); } /* emit connect signals */ g_signal_emit (src, control_signals[CONNECT_SIGNAL], 0, dest, flags | SWAMI_CONTROL_CONN_OUTPUT); g_signal_emit (dest, control_signals[CONNECT_SIGNAL], 0, src, flags | SWAMI_CONTROL_CONN_INPUT); return; err_dest: /* error occured after src already connected, undo */ SWAMI_LOCK_WRITE (src); { GSList **list, *p, *prev = NULL; list = &src->outputs; p = *list; while (p) { if (p->data == sconn) { if (!prev) *list = p->next; else prev->next = p->next; g_slist_free_1 (p); g_object_unref (dest); /* -- unref dest from source connection */ break; } prev = p; p = g_slist_next (p); } } SWAMI_UNLOCK_WRITE (src); /* fall through */ err_src: /* OK to free connections unlocked since they aren't used anymore */ swami_control_conn_free (sconn); swami_control_conn_free (dconn); } /* a priority comparison function for lists of #SwamiControlConn objects */ static gint GCompare_func_conn_priority (gconstpointer a, gconstpointer b) { SwamiControlConn *aconn = (SwamiControlConn *)a; SwamiControlConn *bconn = (SwamiControlConn *)b; return ((aconn->flags & SWAMI_CONTROL_CONN_PRIORITY_MASK) - (bconn->flags & SWAMI_CONTROL_CONN_PRIORITY_MASK)); } /** * swami_control_connect_item_prop: * @dest: Destination control * @object: Object of source parameter to convert to user units * @pspec: Parameter spec of property of @object to connect to * * An ultra-convenience function to connect an existing control to a synthesis * property of an object (#IpatchItem property for example). The connection is * bi-directional and transform functions are used to convert between the two * unit types as needed. */ void swami_control_connect_item_prop (SwamiControl *dest, GObject *object, GParamSpec *pspec) { SwamiControl *src; gpointer data1, data2; guint src_unit, dest_unit; IpatchUnitInfo *info; GParamSpec *destspec; g_return_if_fail (SWAMI_IS_CONTROL (dest)); g_return_if_fail (G_IS_OBJECT (object)); g_return_if_fail (G_IS_PARAM_SPEC (pspec)); /* get/create control for source item synthesis parameter */ src = swami_get_control_prop (object, pspec); /* ++ ref */ g_return_if_fail (src != NULL); /* get the synthesis unit type for this parameter */ ipatch_param_get (pspec, "unit-type", &src_unit, NULL); if (swami_log_if_fail (src_unit != 0)) /* error if no unit type */ { g_object_unref (src); /* -- unref */ return; } /* get the user unit type to convert to */ info = ipatch_unit_class_lookup_map (IPATCH_UNIT_CLASS_USER, src_unit); if (info) /* use the user unit type if found and not the same as src type */ { dest_unit = info->id; if (src_unit == dest_unit) dest_unit = 0; } else dest_unit = 0; if (dest_unit) { /* pass unit types to item_prop_value_transform */ data1 = GUINT_TO_POINTER (src_unit | (dest_unit << 16)); data2 = GUINT_TO_POINTER (dest_unit | (src_unit << 16)); /* transform the parameter spec if necessary */ destspec = swami_control_transform_spec (dest, src, /* !! floating ref */ item_prop_value_transform, data1); g_return_if_fail (destspec != NULL); ipatch_param_set (destspec, "unit-type", dest_unit, NULL); swami_control_set_spec (dest, destspec); swami_control_connect_transform (src, dest, SWAMI_CONTROL_CONN_BIDIR_INIT, item_prop_value_transform, item_prop_value_transform, data1, data2, NULL, NULL); } else swami_control_connect_transform (src, dest, SWAMI_CONTROL_CONN_BIDIR_SPEC_INIT, NULL, NULL, NULL, NULL, NULL, NULL); } /* value transform function for swami_control_connect_item_prop() */ static void item_prop_value_transform (const GValue *src, GValue *dest, gpointer data) { guint src_unit, dest_unit; src_unit = GPOINTER_TO_UINT (data); dest_unit = src_unit >> 16; src_unit &= 0xFFFF; /* do the unit conversion */ ipatch_unit_convert (src_unit, dest_unit, src, dest); } /** * swami_control_disconnect: * @src: Source control of an existing connection * @dest: Destination control of an existing connection * * Disconnects a connection specified by its @src and @dest controls. */ void swami_control_disconnect (SwamiControl *src, SwamiControl *dest) { guint flags = 0; GSList *p; g_return_if_fail (SWAMI_IS_CONTROL (src)); g_return_if_fail (SWAMI_IS_CONTROL (dest)); /* check and see if connection exists */ SWAMI_LOCK_READ (dest); p = dest->inputs; /* use single dest input list to simplify things */ while (p) /* look for matching connection */ { SwamiControlConn *conn = (SwamiControlConn *)(p->data); if (src == conn->control) { flags = conn->flags; /* get flags under lock */ break; } p = g_slist_next (p); } SWAMI_UNLOCK_READ (dest); /* adjust flags for src control connection */ flags &= ~SWAMI_CONTROL_CONN_INPUT; flags |= SWAMI_CONTROL_CONN_OUTPUT; if (p) /* connection found? - emit disconnect signal */ { g_signal_emit (src, control_signals[DISCONNECT_SIGNAL], 0, dest, flags); swami_control_real_disconnect (src, dest, flags); } } /** * swami_control_disconnect_all: * @control: Swami control object * * Disconnect all connections from a control. */ void swami_control_disconnect_all (SwamiControl *control) { SwamiControl *src, *dest = NULL; SwamiControlConn *conn; guint flags = 0; g_return_if_fail (SWAMI_IS_CONTROL (control)); do { /* look for a connection to disconnect */ SWAMI_LOCK_READ (control); if (control->inputs) /* any more input connections? */ { conn = (SwamiControlConn *)(control->inputs->data); src = g_object_ref (conn->control); /* ++ ref connection source */ dest = control; flags = conn->flags; } else if (control->outputs) /* any more direct output connections? */ { conn = (SwamiControlConn *)(control->outputs->data); dest = g_object_ref (conn->control); /* ++ ref connection dest */ src = control; flags = conn->flags; } else src = NULL; /* no more connections */ SWAMI_UNLOCK_READ (control); if (src) { /* adjust flags for src control connection */ flags &= ~SWAMI_CONTROL_CONN_INPUT; flags |= SWAMI_CONTROL_CONN_OUTPUT; g_signal_emit (src, control_signals[DISCONNECT_SIGNAL], 0, dest, flags); swami_control_real_disconnect (src, dest, flags); /* -- unref connection control */ if (control != src) g_object_unref (src); else g_object_unref (dest); } } while (src); } /** * swami_control_disconnect_unref: * @control: Swami control object * * A convenience function to disconnect all connections of a control and * unref it. This is often useful for GDestroyNotify callbacks where a * control's creator wishes to destroy the control. The control is only * destroyed if it is not referenced by anything else. */ void swami_control_disconnect_unref (SwamiControl *control) { g_return_if_fail (SWAMI_IS_CONTROL (control)); swami_control_disconnect_all (control); g_object_unref (control); } /* real disconnect routine, the default class method */ static void swami_control_real_disconnect (SwamiControl *c1, SwamiControl *c2, guint flags) { GSList **list, *p, *prev = NULL; GDestroyNotify destroy = NULL; gpointer data = NULL; SwamiControlConn *conn; SWAMI_LOCK_WRITE (c1); if (flags & SWAMI_CONTROL_CONN_OUTPUT) /* output conn (source control)? */ list = &c1->outputs; /* use output connection list */ else list = &c1->inputs; /* destination control - use input conn list */ p = *list; while (p) /* search for connection in list */ { conn = (SwamiControlConn *)(p->data); if (c2 == conn->control) /* connection found? destroy it */ { if (prev) prev->next = p->next; else *list = p->next; g_slist_free_1 (p); g_object_unref (conn->control); /* -- unref control from conn */ /* store destroy notify if output conn */ if (flags & SWAMI_CONTROL_CONN_OUTPUT) { destroy = conn->destroy; data = conn->data; } swami_control_conn_free (conn); /* free the connection */ break; } prev = p; p = g_slist_next (p); } SWAMI_UNLOCK_WRITE (c1); /* call the destroy notify for the transform user data if any */ if (destroy && data) destroy (data); /* chain disconnect signal to destination control (if source control) */ if (flags & SWAMI_CONTROL_CONN_OUTPUT) { #if DEBUG if (swami_control_debug) { char *s1, *s2; s1 = pretty_control (c1); s2 = pretty_control (c2); g_message ("Disconnect: %s =X= %s", s1, s2); g_free (s1); g_free (s2); } SWAMI_CONTROL_TEST_BREAK (c1, c2); #endif /* adjust flags for input connection (destination control) */ flags &= ~SWAMI_CONTROL_CONN_OUTPUT; flags |= SWAMI_CONTROL_CONN_INPUT; g_signal_emit (c2, control_signals[DISCONNECT_SIGNAL], 0, c1, flags); swami_control_real_disconnect (c2, c1, flags); } } /** * swami_control_get_connections: * @control: Control to get connections of * @dir: Direction of connections to get, #SWAMI_CONTROL_CONN_INPUT for incoming * connections, #SWAMI_CONTROL_CONN_OUTPUT for outgoing (values can be OR'd * to return all connections). * * Get a list of connections to a control. * * Returns: List of #SwamiControl objects connected to @control or %NULL if * none. Caller owns reference to returned list and should unref when done. */ IpatchList * swami_control_get_connections (SwamiControl *control, SwamiControlConnFlags dir) { SwamiControlConn *conn; IpatchList *listobj; GList *list = NULL; GSList *p; g_return_val_if_fail (SWAMI_IS_CONTROL (control), NULL); SWAMI_LOCK_READ (control); if (dir & SWAMI_CONTROL_CONN_INPUT) { for (p = control->inputs; p; p = g_slist_next (p)) { conn = (SwamiControlConn *)(p->data); list = g_list_prepend (list, g_object_ref (conn->control)); } } if (dir & SWAMI_CONTROL_CONN_OUTPUT) { for (p = control->outputs; p; p = g_slist_next (p)) { conn = (SwamiControlConn *)(p->data); list = g_list_prepend (list, g_object_ref (conn->control)); } } SWAMI_UNLOCK_READ (control); if (list) { listobj = ipatch_list_new (); /* ++ ref new list object */ listobj->items = g_list_reverse (list); /* reverse to priority order */ return (listobj); /* !! caller takes over reference */ } else return (NULL); } /** * swami_control_set_transform: * @src: Source control of the connection * @dest: Destination control of the connection * @trans: Transform function to assign to the connection (or %NULL for none) * @data: User data to pass to @trans function (or %NULL). * @destroy: Optional callback to free @data when @trans is disconnected. * * Assigns a value transform function to an existing control connection. The * connection is specified by @src and @dest controls. The transform function * will receive values from the @src control and should transform them * appropriately for the @dest. */ void swami_control_set_transform (SwamiControl *src, SwamiControl *dest, SwamiValueTransform trans, gpointer data, GDestroyNotify destroy) { gboolean conn_found = FALSE; GDestroyNotify oldnotify = NULL; gpointer olddata = NULL; GSList *p; g_return_if_fail (SWAMI_IS_CONTROL (src)); g_return_if_fail (SWAMI_IS_CONTROL (dest)); SWAMI_LOCK_READ (src); /* look for matching connection */ for (p = src->outputs; p; p = p->next) { SwamiControlConn *conn = (SwamiControlConn *)(p->data); if (dest == conn->control) { oldnotify = conn->destroy; olddata = conn->data; conn->trans = trans; conn->data = data; conn->destroy = destroy; conn_found = TRUE; break; } } SWAMI_UNLOCK_READ (src); /* if there already was a transform with destroy function, call it on the user data */ if (oldnotify && olddata) oldnotify (olddata); g_return_if_fail (conn_found); } /** * swami_control_get_transform: * @src: Source control of the connection * @dest: Destination control of the connection * @trans: Pointer to store transform function of the connection * * Gets the current value transform function to an existing control connection. * The connection is specified by @src and @dest controls. The value stored to * @trans may be %NULL if no transform function is assigned. */ void swami_control_get_transform (SwamiControl *src, SwamiControl *dest, SwamiValueTransform *trans) { gboolean conn_found = FALSE; GSList *p; g_return_if_fail (SWAMI_IS_CONTROL (src)); g_return_if_fail (SWAMI_IS_CONTROL (dest)); g_return_if_fail (trans != NULL); SWAMI_LOCK_READ (src); /* look for matching connection */ for (p = src->outputs; p; p = p->next) { SwamiControlConn *conn = (SwamiControlConn *)(p->data); if (dest == conn->control) { *trans = conn->trans; conn_found = TRUE; break; } } SWAMI_UNLOCK_READ (src); g_return_if_fail (conn_found); } /** * swami_control_set_flags: * @control: Control object * @flags: Value to assign to control flags (#SwamiControlFlags) * * Set flags of a control object. Flags can only be set for controls * that don't have any connections yet. */ void swami_control_set_flags (SwamiControl *control, int flags) { g_return_if_fail (SWAMI_IS_CONTROL (control)); SWAMI_LOCK_WRITE (control); if (swami_log_if_fail (!(control->inputs || control->outputs))) { SWAMI_UNLOCK_WRITE (control); return; } flags &= SWAMI_CONTROL_FLAGS_USER_MASK; control->flags &= ~SWAMI_CONTROL_FLAGS_USER_MASK; control->flags |= flags; SWAMI_UNLOCK_WRITE (control); } /** * swami_control_get_flags: * @control: Control object * * Get the flags from a control object. * * Returns: Flags value (#SwamiControlFlags) for @control */ int swami_control_get_flags (SwamiControl *control) { int flags; g_return_val_if_fail (SWAMI_IS_CONTROL (control), 0); SWAMI_LOCK_READ (control); flags = control->flags; SWAMI_UNLOCK_READ (control); return (flags); } /** * swami_control_set_queue: * @control: Control object * @queue: Queue to use for control or %NULL to disable queuing * * Set the queue used by a control object. When a control has a queue all * receive/set events are sent to the queue. This queue can then be processed * at a later time (a GUI thread for example). */ void swami_control_set_queue (SwamiControl *control, SwamiControlQueue *queue) { g_return_if_fail (SWAMI_IS_CONTROL (control)); g_return_if_fail (!queue || SWAMI_IS_CONTROL_QUEUE (queue)); SWAMI_LOCK_WRITE (control); if (queue) g_object_ref (queue); /* ++ ref new queue */ if (control->queue) g_object_unref (control->queue); /* -- unref old queue */ control->queue = queue; SWAMI_UNLOCK_WRITE (control); } /** * swami_control_get_queue: * @control: Control object * * Get the queue used by a control object. * * Returns: The queue assigned to a control or %NULL if it does not have one. * The caller owns a reference to the returned queue object. */ SwamiControlQueue * swami_control_get_queue (SwamiControl *control) { SwamiControlQueue *queue = NULL; g_return_val_if_fail (SWAMI_IS_CONTROL (control), NULL); SWAMI_LOCK_READ (control); if (control->queue) queue = g_object_ref (control->queue); /* ++ ref queue */ SWAMI_UNLOCK_WRITE (control); return (queue); /* !! caller takes over reference */ } /** * swami_control_get_spec: * @control: Control object * * Get a control object's parameter specification. * * Returns: The parameter spec or %NULL on error or if the given * control is type independent. The returned spec is used internally * and should not be modified or freed, however the caller does own a * reference to it and should unref it with g_param_spec_unref when * finished. */ GParamSpec * swami_control_get_spec (SwamiControl *control) { SwamiControlClass *klass; GParamSpec *pspec = NULL; g_return_val_if_fail (SWAMI_IS_CONTROL (control), NULL); klass = SWAMI_CONTROL_GET_CLASS (control); g_return_val_if_fail (klass->get_spec != NULL, NULL); SWAMI_LOCK_READ (control); if (klass->get_spec) pspec = (*klass->get_spec)(control); if (pspec) g_param_spec_ref (pspec); SWAMI_UNLOCK_READ (control); return (pspec); } /** * swami_control_set_spec: * @control: Control object * @pspec: The parameter specification to assign (used directly) * * Set a control object's parameter specification. This function uses * the @pspec directly (its refcount is incremented and ownership is * taken). The parameter spec is not permitted to be of a different * type than the previous parameter spec. * * Returns: %TRUE if parameter specification successfully set, %FALSE * otherwise (in which case the @pspec is unreferenced). */ gboolean swami_control_set_spec (SwamiControl *control, GParamSpec *pspec) { SwamiControlClass *klass; GParamSpec *newspec; GType value_type; gboolean retval; g_return_val_if_fail (SWAMI_IS_CONTROL (control), FALSE); g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE); klass = SWAMI_CONTROL_GET_CLASS (control); g_return_val_if_fail (klass->get_spec != NULL, FALSE); g_return_val_if_fail (klass->set_spec != NULL, FALSE); value_type = G_PARAM_SPEC_VALUE_TYPE (pspec); /* use derived type if GBoxed or GObject type */ if (value_type == G_TYPE_BOXED || value_type == G_TYPE_OBJECT) value_type = pspec->value_type; /* if control's value type doesn't match the param spec value type and "no conversion" flag isn't set, then convert parameter spec */ if (control->value_type && control->value_type != value_type && !(control->flags & SWAMI_CONTROL_SPEC_NO_CONV)) { newspec = swami_param_convert_new (pspec, control->value_type); /* take control of the old pspec and then destroy it */ g_param_spec_ref (pspec); g_param_spec_sink (pspec); g_param_spec_unref (pspec); if (!newspec) return (FALSE); pspec = newspec; } SWAMI_LOCK_WRITE (control); retval = (*klass->set_spec)(control, pspec); SWAMI_UNLOCK_WRITE (control); if (retval) g_signal_emit (control, control_signals[SPEC_CHANGED_SIGNAL], 0, pspec); return (retval); } /** * swami_control_set_value_type: * @control: Control to set value type of * @type: Value type to assign to control * * Usually only called by #SwamiControl derived types from within * their instance init function. Sets the parameter spec value type * for @control and should be called once for specific type value * based controls before being used and cannot be changed * afterwards. If the type is not set then the control is a wild card * control (can handle any value). For GBoxed and GObject based values * use the specific GType for @type. */ void swami_control_set_value_type (SwamiControl *control, GType type) { g_return_if_fail (SWAMI_IS_CONTROL (control)); g_return_if_fail (type != 0); SWAMI_LOCK_WRITE (control); /* make sure type is not already set */ if (control->value_type) { if (swami_log_if_fail (control->value_type == type)) { SWAMI_UNLOCK_WRITE (control); return; } } else control->value_type = type; SWAMI_UNLOCK_WRITE (control); } /** * swami_control_sync_spec: * @control: Control to set parameter spec control of * @source: The source control to get the parameter spec from * @trans: Optional value transform function * @data: User data to pass to transform function * * Synchronizes a @control object's parameter spec to the @source control. * The @source control must already have an assigned parameter spec and the * @control should have an assigned value type. The optional @trans parameter * can be used to specify a transform function, which is executed on the * min, max and default components of the parameter spec when creating the new * param spec. * * Returns: %TRUE on success, %FALSE otherwise (param spec conversion error) */ gboolean swami_control_sync_spec (SwamiControl *control, SwamiControl *source, SwamiValueTransform trans, gpointer data) { GParamSpec *pspec; int retval; g_return_val_if_fail (SWAMI_IS_CONTROL (control), FALSE); g_return_val_if_fail (SWAMI_IS_CONTROL (source), FALSE); if (trans) /* !! floating reference */ pspec = swami_control_transform_spec (control, source, trans, data); else pspec = swami_control_get_spec (source); /* ++ ref spec */ if (!pspec) { g_debug ("pspec == NULL"); return (FALSE); } /* set the param spec for the control */ retval = swami_control_set_spec (control, pspec); /* only unref if swami_control_get_spec() was used, was floating otherwise */ if (!trans) g_param_spec_unref (pspec); /* -- unref */ return (retval); } /** * swami_control_transform_spec: * @control: Destination control for the transformed parameter spec * @source: Source control with the parameter spec to transform * @trans: Transform function * @data: User defined data to pass to transform function * * Transforms a parameter spec from a @source control in preperation for * assignment to @control (but doesn't actually assign it). * * Returns: Transformed parameter spec or %NULL on error, the reference count * is 1 and floating, which means it should be taken over by calling * g_param_spec_ref() followed by g_param_spec_sink(). */ GParamSpec * swami_control_transform_spec (SwamiControl *control, SwamiControl *source, SwamiValueTransform trans, gpointer data) { GParamSpec *srcspec, *transform_spec; GType type; g_return_val_if_fail (SWAMI_IS_CONTROL (control), NULL); g_return_val_if_fail (SWAMI_IS_CONTROL (source), NULL); g_return_val_if_fail (trans != NULL, NULL); /* get the master control parameter spec */ srcspec = swami_control_get_spec (source); /* ++ ref spec */ g_return_val_if_fail (srcspec != NULL, NULL); type = control->value_type ? control->value_type : G_PARAM_SPEC_VALUE_TYPE (srcspec); /* !! floating ref, transform the parameter spec */ transform_spec = swami_param_transform_new (srcspec, type, trans, data); g_param_spec_unref (srcspec); /* -- unref */ g_return_val_if_fail (transform_spec != NULL, NULL); return (transform_spec); /* !! caller takes over floating reference */ } /** * swami_control_get_value: * @control: Control object of type #SWAMI_CONTROL_VALUE * @value: Caller supplied initialized GValue structure to store the value in. * * Get the current value of a value control object. The @control must * have the #SWAMI_CONTROL_SENDS flag set and be a value type control * with an assigned parameter spec. The @value parameter should be * initialized to the type of the control or a transformable type. */ void swami_control_get_value (SwamiControl *control, GValue *value) { SwamiControlClass *klass; GValue *get_value, tmp_value = { 0 }; g_return_if_fail (SWAMI_IS_CONTROL (control)); g_return_if_fail (G_IS_VALUE (value)); klass = SWAMI_CONTROL_GET_CLASS (control); /* some sanity checking */ g_return_if_fail (klass->get_value != NULL); g_return_if_fail (control->flags & SWAMI_CONTROL_SENDS); g_return_if_fail (control->value_type != 0); if (G_VALUE_HOLDS (value, control->value_type)) { /* same type, just reset value and use it */ g_value_reset (value); get_value = value; } else if (!g_value_type_transformable (control->value_type, G_VALUE_TYPE (value))) { g_critical ("%s: Failed to transform value type '%s' to type '%s'", G_STRLOC, g_type_name (control->value_type), g_type_name (G_VALUE_TYPE (value))); return; } else /* @value is not the same type, but is transformable */ { g_value_init (&tmp_value, control->value_type); get_value = &tmp_value; } /* get_value method responsible for locking, if needed */ (*klass->get_value)(control, get_value); if (get_value == &tmp_value) /* transform the value if needed */ { g_value_transform (get_value, value); g_value_unset (&tmp_value); } } /** * swami_control_get_value_native: * @control: Control object of type #SWAMI_CONTROL_VALUE * @value: Caller supplied uninitalized GValue structure to store the value in. * * Like swami_control_get_value() but forces @value to be the native type of * the control, rather than transforming the value to the initialized @value * type. Therefore @value should be un-initialized, contrary to * swami_control_get_value(). */ void swami_control_get_value_native (SwamiControl *control, GValue *value) { SwamiControlClass *klass; g_return_if_fail (SWAMI_IS_CONTROL (control)); g_return_if_fail (value != NULL); klass = SWAMI_CONTROL_GET_CLASS (control); /* some sanity checking */ g_return_if_fail (klass->get_value != NULL); g_return_if_fail (control->flags & SWAMI_CONTROL_SENDS); g_return_if_fail (control->value_type != 0); g_value_init (value, control->value_type); /* get_value method responsible for locking, if needed */ (*klass->get_value)(control, value); } /** * swami_control_set_value: * @control: Control object * @value: Value to set control to * * Sets/sends a value to a control object. If the control has a queue * assigned to it then the value is queued. The @value parameter * should be of a type transformable to the type used by @control (see * g_value_transformable). The @control must have the * #SWAMI_CONTROL_RECVS flag set. */ void swami_control_set_value (SwamiControl *control, const GValue *value) { SwamiControlEvent *event; SwamiControlQueue *queue; SwamiControlQueueTestFunc test_func; g_return_if_fail (SWAMI_IS_CONTROL (control)); g_return_if_fail (G_IS_VALUE (value)); event = swami_control_new_event (control, NULL, value); /* ++ ref new */ swami_control_event_active_ref (event); /* ++ active ref the event */ swami_control_event_ref (event); /* ++ ref event for control active list */ /* prepend the event to the active list */ SWAMI_LOCK_WRITE (control); control->active = g_list_prepend (control->active, event); SWAMI_UNLOCK_WRITE (control); queue = swami_control_get_queue (control); /* ++ ref queue */ if (queue) /* if queue, then add event to the queue */ { /* run queue test function (if any) */ test_func = queue->test_func; /* should be atomic */ if (!test_func || test_func (queue, control, event)) { swami_control_queue_add_event (queue, control, event); g_object_unref (queue); /* -- unref queue */ swami_control_event_active_unref (event); /* -- active unref event */ swami_control_event_unref (event); /* -- unref creator's ref */ return; } /* queue has a test function and it returned FALSE (no queue) */ g_object_unref (queue); /* -- unref queue */ } swami_control_set_event_real (control, event); swami_control_event_active_unref (event); /* -- active unref the event */ swami_control_event_unref (event); /* -- unref creator's ref */ } /** * swami_control_set_value_no_queue: * @control: Control object * @value: Value to set control to * * Sets/sends a value to a control object bypassing the control's * queue if it has one assigned to it. The @value parameter should be * of a type transformable to the type used by @control (see * g_value_transformable). The @control must have the * #SWAMI_CONTROL_RECVS flag set. Normally the swami_control_set_value() * function should be used instead to send a value to a control, use this * only if you know what you are doing since some controls are sensitive to * when they are processed (within a GUI thread for instance). */ void swami_control_set_value_no_queue (SwamiControl *control, const GValue *value) { SwamiControlEvent *event; g_return_if_fail (SWAMI_IS_CONTROL (control)); g_return_if_fail (G_IS_VALUE (value)); event = swami_control_new_event (control, NULL, value); /* ++ ref new */ swami_control_event_active_ref (event); /* ++ active ref the event */ swami_control_event_ref (event); /* ++ ref event for control active list */ /* prepend the event to the active list */ SWAMI_LOCK_WRITE (control); control->active = g_list_prepend (control->active, event); SWAMI_UNLOCK_WRITE (control); swami_control_set_event_real (control, event); swami_control_event_active_unref (event); /* -- active unref the event */ swami_control_event_unref (event); /* -- unref creator's ref */ } /** * swami_control_set_event: * @control: Control object * @event: Event to set control to * * Sets the value of a control object (value controls) or sends an * event (stream controls). This is like swami_control_set_value() but * uses an existing event, rather than creating a new one. The * @control must have the #SWAMI_CONTROL_RECVS flag set. If the * control has a queue then the event will be added to the queue. */ void swami_control_set_event (SwamiControl *control, SwamiControlEvent *event) { SwamiControlEvent *origin; SwamiControlQueue *queue; SwamiControlQueueTestFunc test_func; g_return_if_fail (SWAMI_IS_CONTROL (control)); g_return_if_fail (event != NULL); origin = event->origin ? event->origin : event; swami_control_event_active_ref (event); /* ++ active ref the event */ SWAMI_LOCK_WRITE (control); /* check for event looping (only if control can send) */ if (!swami_control_loop_check (control, event)) { SWAMI_UNLOCK_WRITE (control); swami_control_event_active_unref (event); /* -- decrement active ref */ return; } /* prepend the event origin to the active list */ control->active = g_list_prepend (control->active, origin); SWAMI_UNLOCK_WRITE (control); swami_control_event_ref (origin); /* ++ ref event for control active list */ queue = swami_control_get_queue (control); /* ++ ref queue */ if (queue) /* if queue, then add event to the queue */ { /* run queue test function (if any) */ test_func = queue->test_func; /* should be atomic */ if (!test_func || test_func (queue, control, event)) { swami_control_queue_add_event (queue, control, event); g_object_unref (queue); /* -- unref queue */ swami_control_event_active_unref (event); /* -- active unref */ return; } /* queue has a test function and it returned FALSE (no queue) */ g_object_unref (queue); /* -- unref queue */ } swami_control_set_event_real (control, event); swami_control_event_active_unref (event); /* -- decrement active ref */ } /** * swami_control_set_event_no_queue: * @control: Control object * @event: Event to set control to * * Like swami_control_set_event() but bypasses any queue that a * control might have. The @control must have the #SWAMI_CONTROL_RECVS * flag set. */ void swami_control_set_event_no_queue (SwamiControl *control, SwamiControlEvent *event) { SwamiControlEvent *origin; g_return_if_fail (SWAMI_IS_CONTROL (control)); g_return_if_fail (event != NULL); g_return_if_fail (event->active > 0); origin = event->origin ? event->origin : event; swami_control_event_active_ref (event); /* ++ active ref the event */ SWAMI_LOCK_WRITE (control); /* check for event looping (only if control can send) */ if (!swami_control_loop_check (control, event)) { SWAMI_UNLOCK_WRITE (control); swami_control_event_active_unref (event); /* -- decrement active ref */ return; } /* prepend the event origin to the active list */ control->active = g_list_prepend (control->active, origin); SWAMI_UNLOCK_WRITE (control); swami_control_event_ref (origin); /* ++ ref event for control active list */ swami_control_set_event_real (control, event); swami_control_event_active_unref (event); /* -- decrement active ref */ } /** * swami_control_set_event_no_queue_loop: * @control: Control object * @event: Event to set control to * * Like swami_control_set_event_no_queue() but doesn't do an event * loop check. This function is usually only used by * #SwamiControlQueue objects. The @control must have the * #SWAMI_CONTROL_RECVS flag set. */ void swami_control_set_event_no_queue_loop (SwamiControl *control, SwamiControlEvent *event) { g_return_if_fail (SWAMI_IS_CONTROL (control)); g_return_if_fail (event != NULL); g_return_if_fail (event->active > 0); swami_control_event_active_ref (event); /* ++ active ref the event */ swami_control_set_event_real (control, event); swami_control_event_active_unref (event); /* -- decrement active ref */ } /* the real set event routine */ static inline void swami_control_set_event_real (SwamiControl *control, SwamiControlEvent *event) { SwamiControlClass *klass; GValue temp = { 0 }, *value; klass = SWAMI_CONTROL_GET_CLASS (control); /* some sanity checking */ g_return_if_fail (klass->set_value != NULL); g_return_if_fail (control->flags & SWAMI_CONTROL_RECVS); /* parameter conversion or specific type required? */ if (klass->get_spec && control->value_type != 0 && (!(control->flags & SWAMI_CONTROL_NO_CONV) || (control->flags & SWAMI_CONTROL_NATIVE))) { value = &event->value; if (control->flags & SWAMI_CONTROL_NATIVE) /* native type only? */ { if (!G_VALUE_HOLDS (value, control->value_type)) { g_critical ("%s: Control requires value type '%s' got '%s'", G_STRLOC, g_type_name (control->value_type), g_type_name (G_VALUE_TYPE (value))); return; } } /* transform the value if needed */ else if (!G_VALUE_HOLDS (value, control->value_type)) { g_value_init (&temp, control->value_type); if (!g_value_transform (value, &temp)) { g_value_unset (&temp); /* FIXME - probably should just set a flag or inc a counter */ g_critical ("%s: Failed to transform value type '%s' to" " type '%s'", G_STRLOC, g_type_name (G_VALUE_TYPE (value)), g_type_name (control->value_type)); return; } value = &temp; } } else value = &event->value; /* No conversion necessary */ #if DEBUG if (swami_control_debug) { char *valstr = g_strdup_value_contents (value); char *s1 = pretty_control (control); g_message ("Set: %s EV:%p ORIGIN:%p VAL:<%s>='%s'", s1, event, event->origin, G_VALUE_TYPE_NAME (value), valstr); g_free (s1); g_free (valstr); SWAMI_CONTROL_TEST_BREAK (control, NULL); } #endif /* set_value method is responsible for locking, if needed */ (*klass->set_value)(control, event, value); if (value == &temp) g_value_unset (&temp); } /* Check if an event is already visited a control. Also purges old active events. Control must be locked by caller. Returns: TRUE if not looped, FALSE otherwise */ static inline gboolean swami_control_loop_check (SwamiControl *control, SwamiControlEvent *event) { SwamiControlEvent *ev, *origin; GList *p, *temp; /* if control only sends or only receives, don't do loop check. * FIXME - Is that right? */ if ((control->flags & SWAMI_CONTROL_SENDRECV) != SWAMI_CONTROL_SENDRECV) return (TRUE); origin = event->origin ? event->origin : event; /* look through active events to stop loops and to cleanup old entries */ p = control->active; while (p) { ev = (SwamiControlEvent *)(p->data); if (ev == origin) /* event loop catch */ { #if DEBUG if (swami_control_debug) { char *s1 = pretty_control (control); g_message ("Loop killer: %s EV:%p ORIGIN:%p", s1, event, origin); g_free (s1); } SWAMI_CONTROL_TEST_BREAK (control, NULL); #endif return (FALSE); /* return immediately, looped */ } if (!ev->active) /* event still active? */ { /* no, remove from list */ temp = p; p = g_list_next (p); control->active = g_list_delete_link (control->active, temp); swami_control_event_unref (ev); /* -- unref inactive event */ } else p = g_list_next (p); } return (TRUE); } /** * swami_control_transmit_value: * @control: Control object * @value: Value to transmit or %NULL (readable value controls only, sends * value changed event). * * Sends a value to all output connections of @control. Usually only * used by #SwamiControl object implementations. The @value is used if * not %NULL or the control's value is used (readable value controls * only). This is a convenience function that creates a * #SwamiControlEvent based on the new transmit value, use * swami_control_transmit_event() to send an existing event. */ void swami_control_transmit_value (SwamiControl *control, const GValue *value) { CtrlUpdateBag update_ctrls[MAX_DEST_CONNECTIONS + 1]; CtrlUpdateBag *bag; SwamiControlEvent *event, *transevent; SwamiControlConn *conn; GSList *p; int uc = 0; g_return_if_fail (SWAMI_IS_CONTROL (control)); event = swami_control_new_event (control, NULL, value); /* ++ ref new */ swami_control_event_active_ref (event); /* ++ active ref event */ swami_control_event_ref (event); /* ++ ref event for control active list */ SWAMI_LOCK_WRITE (control); /* prepend the event origin to the active list */ control->active = g_list_prepend (control->active, event); /* copy destination controls to an array under lock, which is then used outside of lock to avoid recursive dead locks */ /* loop over destination connections */ for (p = control->outputs; p; p = p->next) { conn = (SwamiControlConn *)(p->data); /* ++ ref dest control and add to array, copy transform func also */ update_ctrls[uc].control = g_object_ref (conn->control); update_ctrls[uc].trans = conn->trans; update_ctrls[uc++].data = conn->data; } update_ctrls[uc].control = NULL; SWAMI_UNLOCK_WRITE (control); #if DEBUG if (swami_control_debug) { char *s1 = pretty_control (control); g_message ("Transmit to %d dests: %s EV:%p", uc, s1, event); g_free (s1); } SWAMI_CONTROL_TEST_BREAK (control, NULL); #endif bag = update_ctrls; while (bag->control) /* send event to destination controls */ { if (bag->trans) { /* transform event using transform function */ transevent = swami_control_event_transform /* ++ ref */ (event, bag->control->value_type, bag->trans, bag->data); swami_control_set_event (bag->control, transevent); swami_control_event_unref (transevent); /* -- unref */ } else swami_control_set_event (bag->control, event); g_object_unref (bag->control); /* -- unref control from update array */ bag++; } swami_control_event_active_unref (event); /* -- active unref */ swami_control_event_unref (event); /* -- unref creator's reference */ } /** * swami_control_transmit_event: * @control: Control object * @event: Event to send to output connections of @control * * This function sends an event to all destination connected * controls. Usually only used by #SwamiControl object * implementations. */ void swami_control_transmit_event (SwamiControl *control, SwamiControlEvent *event) { CtrlUpdateBag update_ctrls[MAX_DEST_CONNECTIONS + 1]; SwamiControlEvent *transevent; CtrlUpdateBag *bag; g_return_if_fail (SWAMI_IS_CONTROL (control)); g_return_if_fail (event != NULL); swami_control_event_active_ref (event); /* ++ inc active ref count */ { /* recursive function, save on stack space */ SwamiControlConn *conn; SwamiControlEvent *origin; GSList *p; int uc = 0; origin = event->origin ? event->origin : event; swami_control_event_ref (origin); /* ++ ref event for active list */ SWAMI_LOCK_WRITE (control); /* check for event looping (only if control can send) */ if (!swami_control_loop_check (control, event)) { SWAMI_UNLOCK_WRITE (control); swami_control_event_active_unref (event); /* -- decrement active ref */ return; } control->active = g_list_prepend (control->active, origin); /* copy destination controls to an array under lock, which is then used outside of lock to avoid recursive dead locks */ /* loop over destination connections */ for (p = control->outputs; p; p = p->next) { conn = (SwamiControlConn *)(p->data); /* ++ ref dest control and add to array, copy transform func also */ update_ctrls[uc].control = g_object_ref (conn->control); update_ctrls[uc].trans = conn->trans; update_ctrls[uc++].data = conn->data; } update_ctrls[uc].control = NULL; SWAMI_UNLOCK_WRITE (control); } /* stack space saver */ #if DEBUG if (swami_control_debug) { char *s1 = pretty_control (control); g_message ("Transmit: %s EV:%p ORIGIN:%p", s1, event, event->origin); g_free (s1); } SWAMI_CONTROL_TEST_BREAK (control, NULL); #endif bag = update_ctrls; while (bag->control) /* send event to destination controls */ { if (bag->trans) { /* transform event using transform function */ transevent = swami_control_event_transform /* ++ ref */ (event, bag->control->value_type, bag->trans, bag->data); swami_control_set_event (bag->control, transevent); swami_control_event_unref (transevent); /* -- unref */ } else swami_control_set_event (bag->control, event); g_object_unref (bag->control); /* -- unref control from update array */ bag++; } swami_control_event_active_unref (event); /* -- decrement active ref */ } /** * swami_control_transmit_event_loop: * @control: Control object * @event: Event to send to output connections of @control * * Like swami_control_transmit_event() but doesn't do an event loop check. * This is useful for control implementations that receive an event and * want to re-transmit it (swami_control_transmit_event() would stop it, * since the event is already in the active list for the control). */ void swami_control_transmit_event_loop (SwamiControl *control, SwamiControlEvent *event) { CtrlUpdateBag update_ctrls[MAX_DEST_CONNECTIONS + 1]; SwamiControlEvent *transevent; CtrlUpdateBag *bag; g_return_if_fail (SWAMI_IS_CONTROL (control)); g_return_if_fail (event != NULL); swami_control_event_active_ref (event); /* ++ inc active ref count */ { /* recursive function, save on stack space */ SwamiControlConn *conn; SwamiControlEvent *origin; GSList *p; int uc = 0; origin = event->origin ? event->origin : event; SWAMI_LOCK_WRITE (control); /* check for event in active list (only if control can send) */ if (swami_control_loop_check (control, event)) { /* not already in list, prepend the event origin to the active list */ control->active = g_list_prepend (control->active, origin); swami_control_event_ref (origin); /* ++ ref event for active list */ } /* copy destination controls to an array under lock, which is then used outside of lock to avoid recursive dead locks */ /* loop over destination connections */ for (p = control->outputs; p; p = p->next) { conn = (SwamiControlConn *)(p->data); /* ++ ref dest control and add to array, copy transform func also */ update_ctrls[uc].control = g_object_ref (conn->control); update_ctrls[uc].trans = conn->trans; update_ctrls[uc++].data = conn->data; } update_ctrls[uc].control = NULL; SWAMI_UNLOCK_WRITE (control); } /* stack space saver */ #if DEBUG if (swami_control_debug) { char *s1 = pretty_control (control); g_message ("Transmit: %s EV:%p ORIGIN:%p", s1, event, event->origin); g_free (s1); } SWAMI_CONTROL_TEST_BREAK (control, NULL); #endif bag = update_ctrls; while (bag->control) /* send event to destination controls */ { if (bag->trans) { /* transform event using transform function */ transevent = swami_control_event_transform /* ++ ref */ (event, bag->control->value_type, bag->trans, bag->data); swami_control_set_event (bag->control, transevent); swami_control_event_unref (transevent); /* -- unref */ } else swami_control_set_event (bag->control, event); g_object_unref (bag->control); /* -- unref control from update array */ bag++; } swami_control_event_active_unref (event); /* -- decrement active ref */ } /** * swami_control_do_event_expiration: * * Processes all controls in search of inactive expired events. This should * be called periodically to expire events in controls that don't receive any * events for a long period after previous activity. Note that currently this * is handled automatically if swami_init() is called. */ void swami_control_do_event_expiration (void) { GList *cp, *ep, *temp; SwamiControlEvent *ev; SwamiControl *control; G_LOCK (control_list); for (cp = control_list; cp; cp = cp->next) /* loop over controls */ { control = (SwamiControl *)(cp->data); SWAMI_LOCK_WRITE (control); ep = control->active; while (ep) /* loop over active event list */ { ev = (SwamiControlEvent *)(ep->data); if (!ev->active) /* event still active? */ { /* no, remove from list */ temp = ep; ep = g_list_next (ep); control->active = g_list_delete_link (control->active, temp); swami_control_event_unref (ev); /* -- unref inactive event */ } else ep = g_list_next (ep); } SWAMI_UNLOCK_WRITE (control); } G_UNLOCK (control_list); } /** * swami_control_new_event: * @control: Control object * @origin: Origin event or %NULL if new event is origin * @value: Value to use as event value or %NULL to use @control as the * value (a value change event) * * Create an event for @control. If @value is non %NULL then * it is used as the value of the event otherwise the @control is used as * the value of the event (a value changed event). * * Returns: New event with a refcount of 1 which the caller owns. Remember * that a #SwamiControlEvent is not a GObject and has its own reference * counting routines swami_control_event_ref() and * swami_control_event_unref(). */ SwamiControlEvent * swami_control_new_event (SwamiControl *control, SwamiControlEvent *origin, const GValue *value) { SwamiControlEvent *event; g_return_val_if_fail (SWAMI_IS_CONTROL (control), NULL); event = swami_control_event_new (TRUE); /* ++ ref new event */ if (origin) swami_control_event_set_origin (event, origin); if (value) /* if value supplied, use it */ { g_value_init (&event->value, G_VALUE_TYPE (value)); g_value_copy (value, &event->value); } else /* create a value change event */ { g_value_init (&event->value, G_TYPE_OBJECT); g_value_set_object (&event->value, control); } return (event); /* !! caller owns reference */ } swami/src/libswami/util.h0000644000175000017500000000225111461334205015601 0ustar alessioalessio/* * util.h - Swami utility stuff * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMI_UTIL_H__ #define __SWAMI_UTIL_H__ GType *swami_util_get_child_types (GType type, guint *n_types); GValue *swami_util_new_value (void); void swami_util_free_value (GValue *value); void swami_util_midi_note_to_str (int note, char *str); int swami_util_midi_str_to_note (const char *str); #endif /* __SWAMI_UTIL_H__ */ swami/src/libswami/SwamiControlValue.c0000644000175000017500000001615711704446464020262 0ustar alessioalessio/* * SwamiControlValue.c - Swami GValue control object * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include "SwamiControlValue.h" #include "SwamiControl.h" #include "SwamiLog.h" #include "swami_priv.h" #include "util.h" static void swami_control_value_class_init (SwamiControlValueClass *klass); static void swami_control_value_init (SwamiControlValue *ctrlvalue); static void swami_control_value_finalize (GObject *object); static GParamSpec *control_value_get_spec_method (SwamiControl *control); static gboolean control_value_set_spec_method (SwamiControl *control, GParamSpec *pspec); static void control_value_get_value_method (SwamiControl *control, GValue *value); static void control_value_set_value_method (SwamiControl *control, SwamiControlEvent *event, const GValue *value); static GObjectClass *parent_class = NULL; GType swami_control_value_get_type (void) { static GType otype = 0; if (!otype) { static const GTypeInfo type_info = { sizeof (SwamiControlValueClass), NULL, NULL, (GClassInitFunc) swami_control_value_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SwamiControlValue), 0, (GInstanceInitFunc) swami_control_value_init }; otype = g_type_register_static (SWAMI_TYPE_CONTROL, "SwamiControlValue", &type_info, 0); } return (otype); } static void swami_control_value_class_init (SwamiControlValueClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); SwamiControlClass *control_class = SWAMI_CONTROL_CLASS (klass); parent_class = g_type_class_peek_parent (klass); obj_class->finalize = swami_control_value_finalize; control_class->get_spec = control_value_get_spec_method; control_class->set_spec = control_value_set_spec_method; control_class->get_value = control_value_get_value_method; control_class->set_value = control_value_set_value_method; } static void swami_control_value_init (SwamiControlValue *ctrlvalue) { swami_control_set_flags (SWAMI_CONTROL (ctrlvalue), SWAMI_CONTROL_SENDRECV); } static void swami_control_value_finalize (GObject *object) { SwamiControlValue *ctrlvalue = SWAMI_CONTROL_VALUE (object); if (ctrlvalue->destroy && ctrlvalue->value) (*ctrlvalue->destroy)(ctrlvalue->value); if (ctrlvalue->pspec) g_param_spec_unref (ctrlvalue->pspec); parent_class->finalize (object); } /* control is locked by caller */ static GParamSpec * control_value_get_spec_method (SwamiControl *control) { SwamiControlValue *ctrlvalue = SWAMI_CONTROL_VALUE (control); return (ctrlvalue->pspec); } /* control is locked by caller */ static gboolean control_value_set_spec_method (SwamiControl *control, GParamSpec *pspec) { SwamiControlValue *ctrlvalue = SWAMI_CONTROL_VALUE (control); if (ctrlvalue->pspec) g_param_spec_unref (ctrlvalue->pspec); ctrlvalue->pspec = g_param_spec_ref (pspec); g_param_spec_sink (pspec); return (TRUE); } static void control_value_get_value_method (SwamiControl *control, GValue *value) { SwamiControlValue *ctrlvalue = SWAMI_CONTROL_VALUE (control); g_value_copy (ctrlvalue->value, value); } static void control_value_set_value_method (SwamiControl *control, SwamiControlEvent *event, const GValue *value) { SwamiControlValue *ctrlvalue = SWAMI_CONTROL_VALUE (control); g_value_copy (value, ctrlvalue->value); } /** * swami_control_value_new: * * Create a new GValue control. * * Returns: New GValue control with a refcount of 1 which the caller owns. */ SwamiControlValue * swami_control_value_new (void) { return (SWAMI_CONTROL_VALUE (g_object_new (SWAMI_TYPE_CONTROL_VALUE, NULL))); } /** * swami_control_value_assign_value: * @ctrlvalue: Swami GValue control object * @value: Value to be controlled * @destroy: A function to destroy @value or %NULL * * Assigns a GValue to be controlled by a Swami GValue control object. * If @destroy is set it will be called on the @value when it is no longer * being used. The @ctrlvalue should already have a parameter specification. * If the @value type is the same as the GParamSpec value type it will be * used as is otherwise it will be initialized to the parameter spec type. */ void swami_control_value_assign_value (SwamiControlValue *ctrlvalue, GValue *value, GDestroyNotify destroy) { GValue *destroy_value = NULL; GDestroyNotify destroy_func; g_return_if_fail (SWAMI_IS_CONTROL_VALUE (ctrlvalue)); g_return_if_fail (value != NULL); SWAMI_LOCK_WRITE (ctrlvalue); if (swami_log_if_fail (ctrlvalue->pspec != NULL)) { SWAMI_UNLOCK_WRITE (ctrlvalue); return; } if (ctrlvalue->destroy && ctrlvalue->value) { destroy_value = ctrlvalue->value; destroy_func = ctrlvalue->destroy; } ctrlvalue->value = value; ctrlvalue->destroy = destroy; /* ensure existing value is set to the type specified by spec */ if (G_VALUE_TYPE (ctrlvalue->value) != G_PARAM_SPEC_VALUE_TYPE (ctrlvalue->pspec)) { g_value_unset (ctrlvalue->value); g_value_init (ctrlvalue->value, G_PARAM_SPEC_VALUE_TYPE (ctrlvalue->pspec)); } SWAMI_UNLOCK_WRITE (ctrlvalue); /* destroy value outside of lock (if any) */ if (destroy_value) (*destroy_func)(destroy_value); } /** * swami_control_value_alloc_value: * @ctrlvalue: Swami GValue control object * * Allocate a GValue and assign it to the @ctrlvalue object. See * swami_control_value_assign_value() to assign an existing GValue to * a Swami GValue control object. The @ctrlvalue should already have an * assigned parameter spec. */ void swami_control_value_alloc_value (SwamiControlValue *ctrlvalue) { GValue *destroy_value = NULL; GDestroyNotify destroy_func; GValue *value; g_return_if_fail (SWAMI_IS_CONTROL_VALUE (ctrlvalue)); SWAMI_LOCK_WRITE (ctrlvalue); if (swami_log_if_fail (ctrlvalue->pspec != NULL)) { SWAMI_UNLOCK_WRITE (ctrlvalue); return; } if (ctrlvalue->destroy && ctrlvalue->value) { destroy_value = ctrlvalue->value; destroy_func = ctrlvalue->destroy; } value = swami_util_new_value (); g_value_init (value, G_PARAM_SPEC_VALUE_TYPE (ctrlvalue->pspec)); ctrlvalue->value = value; ctrlvalue->destroy = (GDestroyNotify)swami_util_free_value; SWAMI_UNLOCK_WRITE (ctrlvalue); /* destroy value outside of lock (if any) */ if (destroy_value) (*destroy_func)(destroy_value); } swami/src/libswami/SwamiLock.h0000644000175000017500000000437611461334205016527 0ustar alessioalessio/* * SwamiLock.h - Header for Swami multi-threaded locked base object class * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMI_LOCK_H__ #define __SWAMI_LOCK_H__ #include #include typedef struct _SwamiLock SwamiLock; typedef struct _SwamiLockClass SwamiLockClass; #define SWAMI_TYPE_LOCK (swami_lock_get_type ()) #define SWAMI_LOCK(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMI_TYPE_LOCK, SwamiLock)) #define SWAMI_LOCK_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMI_TYPE_LOCK, SwamiLockClass)) #define SWAMI_IS_LOCK(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMI_TYPE_LOCK)) #define SWAMI_IS_LOCK_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMI_TYPE_LOCK)) struct _SwamiLock { GObject parent_instance; GStaticRecMutex mutex; }; struct _SwamiLockClass { GObjectClass parent_class; }; /* Multi-thread locking macros. For now there is no distinction between write and read locking since GStaticRWLock is not recursive. */ #define SWAMI_LOCK_WRITE(lock) \ g_static_rec_mutex_lock (&((SwamiLock *)(lock))->mutex) #define SWAMI_UNLOCK_WRITE(lock) \ g_static_rec_mutex_unlock (&((SwamiLock *)(lock))->mutex) #define SWAMI_LOCK_READ(lock) SWAMI_LOCK_WRITE(lock) #define SWAMI_UNLOCK_READ(lock) SWAMI_UNLOCK_WRITE(lock) GType swami_lock_get_type (void); void swami_lock_set_atomic (gpointer lock, const char *first_property_name, ...); void swami_lock_get_atomic (gpointer lock, const char *first_property_name, ...); #endif swami/src/libswami/SwamiContainer.h0000644000175000017500000000373011461334205017552 0ustar alessioalessio/* * SwamiContainer.h - Root container for instrument patches * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMI_CONTAINER_H__ #define __SWAMI_CONTAINER_H__ #include #include #include typedef struct _SwamiContainer SwamiContainer; typedef struct _SwamiContainerClass SwamiContainerClass; #include #define SWAMI_TYPE_CONTAINER (swami_container_get_type ()) #define SWAMI_CONTAINER(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMI_TYPE_CONTAINER, SwamiContainer)) #define SWAMI_CONTAINER_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMI_TYPE_CONTAINER, SwamiContainerClass)) #define SWAMI_IS_CONTAINER(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMI_TYPE_CONTAINER)) #define SWAMI_IS_CONTAINER_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMI_TYPE_CONTAINER)) struct _SwamiContainer { IpatchContainer parent; /*< private >*/ GSList *patch_list; /* list of instrument patches */ SwamiRoot *root; /* root object owning this container */ }; struct _SwamiContainerClass { IpatchContainerClass parent_class; }; GType swami_container_get_type (void); SwamiContainer *swami_container_new (void); #endif swami/src/libswami/SwamiControlFunc.h0000644000175000017500000000617511461334205020072 0ustar alessioalessio/* * SwamiControlFunc.h - Header for Swami control function object * A convenient control type that uses user defined callback routines. * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMI_CONTROL_FUNC_H__ #define __SWAMI_CONTROL_FUNC_H__ #include #include #include typedef struct _SwamiControlFunc SwamiControlFunc; typedef struct _SwamiControlFuncClass SwamiControlFuncClass; #define SWAMI_TYPE_CONTROL_FUNC (swami_control_func_get_type ()) #define SWAMI_CONTROL_FUNC(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMI_TYPE_CONTROL_FUNC, \ SwamiControlFunc)) #define SWAMI_CONTROL_FUNC_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMI_TYPE_CONTROL_FUNC, \ SwamiControlFuncClass)) #define SWAMI_IS_CONTROL_FUNC(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMI_TYPE_CONTROL_FUNC)) #define SWAMI_IS_CONTROL_FUNC_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMI_TYPE_CONTROL_FUNC)) /** * SwamiControlFuncDestroy: * @control: Function control object * * A function to call when the function control is destroyed or when the * function callbacks are changed. This function should handle all cleanup * for the callback functions. This function is called with @control * multi-thread write locked. */ typedef void (*SwamiControlFuncDestroy)(SwamiControlFunc *control); /* function control object */ struct _SwamiControlFunc { SwamiControl parent_instance; /* derived from SwamiControl */ SwamiControlGetValueFunc get_func; /* callback function to get value */ SwamiControlSetValueFunc set_func; /* callback function to set value */ SwamiControlFuncDestroy destroy_func; /* destroy function */ gpointer user_data; /* user data for callback functions */ GParamSpec *pspec; /* optional parameter specification for this control */ }; /* function control class */ struct _SwamiControlFuncClass { SwamiControlClass parent_class; }; /* macro to get user data field from a SwamiControlFunc */ #define SWAMI_CONTROL_FUNC_DATA(ctrl) (SWAMI_CONTROL_FUNC (ctrl)->user_data) GType swami_control_func_get_type (void); SwamiControlFunc *swami_control_func_new (void); void swami_control_func_assign_funcs (SwamiControlFunc *ctrlfunc, SwamiControlGetValueFunc get_func, SwamiControlSetValueFunc set_func, SwamiControlFuncDestroy destroy_func, gpointer user_data); #endif swami/src/libswami/SwamiPlugin.c0000644000175000017500000004015711474034033017065 0ustar alessioalessio/* * SwamiPlugin.c - Swami plugin system * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * Inspired by gstplugin from GStreamer (although re-coded) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include #include #include "config.h" #include /* ipatch_gerror_message() */ #include "SwamiPlugin.h" #include "SwamiLog.h" #include "version.h" #include "i18n.h" enum { PROP_0, PROP_MODULE, PROP_LOADED, PROP_NAME, PROP_FILENAME, PROP_VERSION, PROP_AUTHOR, PROP_COPYRIGHT, PROP_DESCR, PROP_LICENSE }; static GList *swami_plugins = NULL; /* global list of plugins */ static int plugin_seqno = 0; /* plugin counter (for stats) */ static GList *plugin_paths = NULL; /* plugin search paths */ static GObjectClass *parent_class = NULL; static void swami_plugin_class_init (SwamiPluginClass *klass); static void swami_plugin_finalize (GObject *object); static void swami_plugin_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void swami_plugin_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static gboolean swami_plugin_type_module_load (GTypeModule *type_module); static void swami_plugin_type_module_unload (GTypeModule *type_module); static gboolean swami_plugin_load_recurse (char *file, char *name); /* initialize plugin system */ void _swami_plugin_initialize (void) { #ifdef MINGW32 char *appdir, *path; appdir = g_win32_get_package_installation_directory_of_module (NULL); /* ++ alloc */ if (appdir) { path = g_build_filename (appdir, "plugins", NULL); /* !! never freed */ g_free (appdir); /* -- free appdir */ } else path = PLUGINS_DIR; plugin_paths = g_list_append (plugin_paths, path); #else plugin_paths = g_list_append (plugin_paths, PLUGINS_DIR); #endif } GType swami_plugin_get_type (void) { static GType obj_type = 0; if (!obj_type) { static GTypeInfo obj_info = { sizeof (SwamiPluginClass), NULL, NULL, (GClassInitFunc) swami_plugin_class_init, NULL, NULL, sizeof (SwamiPlugin), 0, (GInstanceInitFunc) NULL, }; obj_type = g_type_register_static (G_TYPE_TYPE_MODULE, "SwamiPlugin", &obj_info, 0); } return (obj_type); } static void swami_plugin_class_init (SwamiPluginClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (klass); parent_class = g_type_class_peek_parent (klass); obj_class->finalize = swami_plugin_finalize; obj_class->set_property = swami_plugin_set_property; obj_class->get_property = swami_plugin_get_property; module_class->load = swami_plugin_type_module_load; module_class->unload = swami_plugin_type_module_unload; g_object_class_install_property (obj_class, PROP_MODULE, g_param_spec_pointer ("module", "Module", "GModule of plugin", G_PARAM_READABLE)); g_object_class_install_property (obj_class, PROP_LOADED, g_param_spec_boolean ("loaded", "Loaded", "Loaded state of plugin", FALSE, G_PARAM_READABLE)); g_object_class_install_property (obj_class, PROP_NAME, g_param_spec_string ("name", "Name", "Name of plugin", NULL, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_FILENAME, g_param_spec_string ("file-name", "File Name", "Name of plugin file", NULL, G_PARAM_READABLE)); g_object_class_install_property (obj_class, PROP_VERSION, g_param_spec_string ("version", "Version", "Plugin specific version", NULL, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_AUTHOR, g_param_spec_string ("author", "Author", "Author of the plugin", NULL, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_COPYRIGHT, g_param_spec_string ("copyright", "Copyright", "Copyright string", NULL, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_DESCR, g_param_spec_string ("descr", "Description", "Description of plugin", NULL, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_LICENSE, g_param_spec_string ("license", "License", "Plugin license type", NULL, G_PARAM_READWRITE)); } static void swami_plugin_finalize (GObject *object) { SwamiPlugin *plugin = SWAMI_PLUGIN (object); g_free (plugin->filename); g_free (plugin->version); g_free (plugin->author); g_free (plugin->copyright); g_free (plugin->descr); g_free (plugin->license); G_OBJECT_CLASS (parent_class)->finalize (object); } static void swami_plugin_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { SwamiPlugin *plugin = SWAMI_PLUGIN (object); switch (property_id) { case PROP_NAME: g_type_module_set_name (G_TYPE_MODULE (plugin), g_value_get_string (value)); break; case PROP_VERSION: g_free (plugin->version); plugin->version = g_value_dup_string (value); break; case PROP_AUTHOR: g_free (plugin->author); plugin->author = g_value_dup_string (value); break; case PROP_COPYRIGHT: g_free (plugin->copyright); plugin->copyright = g_value_dup_string (value); break; case PROP_DESCR: g_free (plugin->descr); plugin->descr = g_value_dup_string (value); break; case PROP_LICENSE: g_free (plugin->license); plugin->license = g_value_dup_string (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void swami_plugin_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { SwamiPlugin *plugin = SWAMI_PLUGIN (object); switch (property_id) { case PROP_MODULE: g_value_set_pointer (value, plugin->module); break; case PROP_LOADED: g_value_set_boolean (value, plugin->module != NULL); break; case PROP_NAME: g_value_set_string (value, G_TYPE_MODULE (plugin)->name); break; case PROP_FILENAME: g_value_set_string (value, plugin->filename); break; case PROP_VERSION: g_value_set_string (value, plugin->version); break; case PROP_AUTHOR: g_value_set_string (value, plugin->author); break; case PROP_COPYRIGHT: g_value_set_string (value, plugin->copyright); break; case PROP_DESCR: g_value_set_string (value, plugin->descr); break; case PROP_LICENSE: g_value_set_string (value, plugin->license); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static gboolean swami_plugin_type_module_load (GTypeModule *type_module) { SwamiPlugin *plugin = SWAMI_PLUGIN (type_module); SwamiPluginInfo *info; GError *err = NULL; g_return_val_if_fail (SWAMI_IS_PLUGIN (plugin), FALSE); g_return_val_if_fail (plugin->filename != NULL, FALSE); g_return_val_if_fail (plugin->module == NULL, FALSE); plugin->module = g_module_open (plugin->filename, G_MODULE_BIND_LAZY); if (!plugin->module) { g_critical (_("Failed to load plugin \"%s\": %s"), plugin->filename, g_module_error ()); return (FALSE); } if (!g_module_symbol (plugin->module, "swami_plugin_info", (gpointer *)&info)) { g_critical (_("Symbol \"swami_plugin_info\" not found in plugin \"%s\""), plugin->filename); goto fail; } if (strncmp (info->magic, SWAMI_PLUGIN_MAGIC, 4) != 0) { g_critical (_("Invalid Swami plugin magic number")); goto fail; } if (strcmp (info->swami_version, SWAMI_VERSION) != 0) { g_critical (_("Plugin compiled for Swami version %s but loading on %s"), info->swami_version, SWAMI_VERSION); goto fail; } if (info->init && !(*info->init)(plugin, &err)) { g_critical (_("Plugin init function failed: %s"), ipatch_gerror_message (err)); g_clear_error (&err); goto fail; } plugin->init = info->init; plugin->exit = info->exit; return (TRUE); fail: g_module_close (plugin->module); plugin->module = NULL; return (FALSE); } static void swami_plugin_type_module_unload (GTypeModule *type_module) { SwamiPlugin *plugin = SWAMI_PLUGIN (type_module); g_return_if_fail (plugin->module != NULL); if (plugin->exit) /* call the plugin's exit function (if any) */ (*plugin->exit)(plugin); plugin->init = NULL; plugin->exit = NULL; g_module_close (plugin->module); plugin->module = NULL; } /** * swami_plugin_add_path: * @path: The directory to add to the search path * * Add a directory to the path searched for plugins. */ void swami_plugin_add_path (const char *path) { plugin_paths = g_list_append (plugin_paths, g_strdup (path)); } /** * swami_plugin_load_all: * * Load all plugins in the plugin search path. */ void swami_plugin_load_all (void) { GList *path; path = plugin_paths; if (path == NULL) g_warning ("Plugin search path is empty"); while (path) { g_message (_("Loading plugins from %s"), (char *)path->data); swami_plugin_load_recurse (path->data, NULL); path = g_list_next (path); } g_message (_("Loaded %d plugins"), plugin_seqno); } static gboolean swami_plugin_load_recurse (char *file, char *name) { DIR *dir; struct dirent *dirent; gboolean loaded = FALSE; char *dirname, *temp; dir = opendir (file); if (dir) /* is "file" a directory or file? */ { while ((dirent = readdir (dir))) /* its a directory, open it */ { /* don't want to recurse in place or backwards */ if (strcmp (dirent->d_name, ".") && strcmp (dirent->d_name, "..")) { dirname = g_strjoin (G_DIR_SEPARATOR_S, file, dirent->d_name, NULL); loaded = swami_plugin_load_recurse (dirname, name); g_free (dirname); if (loaded && name) /* done searching for a specific plugin? */ { closedir (dir); return TRUE; } } } closedir (dir); } else { /* search for shared library extension */ temp = g_strrstr (file, "." G_MODULE_SUFFIX); /* make sure file ends with shared library extension */ if (temp && strcmp (temp, "." G_MODULE_SUFFIX) == 0) { /* if we aren't searching for a specific plugin or this file name matches the search, load the plugin */ if (!name || ((temp = strstr (file, name)) && strcmp (temp, name) == 0)) loaded = swami_plugin_load_absolute (file); } } return (loaded); } /** * swami_plugin_load: * @filename: File name of plugin to load * * Load the named plugin. Name should be the plugin file name * ("libplugin.so" on Linux for example). * * Returns: Whether the plugin was loaded or not */ gboolean swami_plugin_load (const char *filename) { GList *path; char *pluginname; SwamiPlugin *plugin; g_return_val_if_fail (filename != NULL, FALSE); plugin = swami_plugin_find (filename); if (plugin && plugin->module) return (TRUE); path = plugin_paths; while (path) { pluginname = g_module_build_path (path->data, filename); if (swami_plugin_load_absolute (pluginname)) { g_free (pluginname); return (TRUE); } g_free (pluginname); path = g_list_next (path); } return (FALSE); } /** * swami_plugin_load_absolute: * @filename: Name of plugin to load * * Load the named plugin. Name should be the full path and file name of the * plugin to load. * * Returns: whether the plugin was loaded or not */ gboolean swami_plugin_load_absolute (const char *filename) { SwamiPlugin *plugin = NULL; GList *plugins = swami_plugins; g_return_val_if_fail (filename != NULL, FALSE); while (plugins) /* see if plugin already exists */ { SwamiPlugin *testplugin = (SwamiPlugin *)plugins->data; if (testplugin->filename && strcmp (testplugin->filename, filename) == 0) { plugin = testplugin; break; } plugins = g_list_next (plugins); } if (!plugin) { plugin = g_object_new (SWAMI_TYPE_PLUGIN, NULL); plugin->filename = g_strdup (filename); swami_plugins = g_list_prepend (swami_plugins, plugin); plugin_seqno++; } return (g_type_module_use (G_TYPE_MODULE (plugin))); } /** * swami_plugin_load_plugin: * @plugin: The plugin to load * * Load the given plugin. * * Returns: %TRUE on success (loaded or already loaded), %FALSE otherwise */ gboolean swami_plugin_load_plugin (SwamiPlugin *plugin) { g_return_val_if_fail (SWAMI_IS_PLUGIN (plugin), FALSE); if (plugin->module) return (TRUE); return (g_type_module_use (G_TYPE_MODULE (plugin))); } /** * swami_plugin_is_loaded: * @plugin: Plugin to query * * Queries if the plugin is loaded into memory * * Returns: %TRUE is loaded, %FALSE otherwise */ gboolean swami_plugin_is_loaded (SwamiPlugin *plugin) { g_return_val_if_fail (plugin != NULL, FALSE); return (plugin->module != NULL); } /** * swami_plugin_find: * @name: Name of plugin to find * * Search the list of registered plugins for one with the given plugin name * (not file name). * * Returns: Pointer to the #SwamiPlugin if found, %NULL otherwise */ SwamiPlugin * swami_plugin_find (const char *name) { GList *plugins = swami_plugins; g_return_val_if_fail (name != NULL, NULL); while (plugins) { SwamiPlugin *plugin = (SwamiPlugin *)plugins->data; if (G_TYPE_MODULE (plugin)->name && strcmp (G_TYPE_MODULE (plugin)->name, name) == 0) return (plugin); plugins = g_list_next (plugins); } return (NULL); } /** * swami_plugin_get_list: * * get the currently loaded plugins * * Returns: a GList of SwamiPlugin elements which should be freed with * g_list_free when finished with. */ GList * swami_plugin_get_list (void) { return (g_list_copy (swami_plugins)); } /** * swami_plugin_save_xml: * @plugin: Swami plugin * @xmlnode: XML node to save plugin state to * @err: Location to store error info or %NULL to ignore * * Save a plugin's preferences state to XML. Not all plugins implement this * method. Check if the xml_save field is set for @plugin before calling, just * returns %TRUE if not implemented. * * Returns: %TRUE on success, %FALSE otherwise (in which case @err may be set) */ gboolean swami_plugin_save_xml (SwamiPlugin *plugin, GNode *xmlnode, GError **err) { g_return_val_if_fail (SWAMI_IS_PLUGIN (plugin), FALSE); g_return_val_if_fail (xmlnode != NULL, FALSE); g_return_val_if_fail (!err || !*err, FALSE); if (!plugin->save_xml) return (TRUE); return (plugin->save_xml (plugin, xmlnode, err)); } /** * swami_plugin_load_xml: * @plugin: Swami plugin * @xmlnode: XML node to load plugin state from * @err: Location to store error info or %NULL to ignore * * Load a plugin's preferences state from XML. Not all plugins implement this * method. Check if the xml_load field is set for @plugin before calling, just * returns %TRUE if not implemented. * * Returns: %TRUE on success, %FALSE otherwise (in which case @err may be set) */ gboolean swami_plugin_load_xml (SwamiPlugin *plugin, GNode *xmlnode, GError **err) { g_return_val_if_fail (SWAMI_IS_PLUGIN (plugin), FALSE); g_return_val_if_fail (xmlnode != NULL, FALSE); g_return_val_if_fail (!err || !*err, FALSE); if (!plugin->load_xml) return (TRUE); return (plugin->load_xml (plugin, xmlnode, err)); } swami/src/libswami/SwamiPlugin.h0000644000175000017500000001277411461334205017076 0ustar alessioalessio/* * SwamiPlugin.h - Header file for Swami plugin system * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * Inspired by gstplugin from GStreamer (although re-coded) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMI_PLUGIN_H__ #define __SWAMI_PLUGIN_H__ #include #include #include #include typedef struct _SwamiPlugin SwamiPlugin; typedef struct _SwamiPluginClass SwamiPluginClass; typedef struct _SwamiPluginInfo SwamiPluginInfo; #define SWAMI_TYPE_PLUGIN (swami_plugin_get_type ()) #define SWAMI_PLUGIN(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMI_TYPE_PLUGIN, SwamiPlugin)) #define SWAMI_PLUGIN_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMI_TYPE_PLUGIN, SwamiPluginClass)) #define SWAMI_IS_PLUGIN(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMI_TYPE_PLUGIN)) #define SWAMI_IS_PLUGIN_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMI_TYPE_PLUGIN)) /** * SwamiPluginInitFunc: * @plugin: Plugin object being loaded * @err: Location to store error information * * A function type called after a plugin has been loaded. * * Returns: Should return %TRUE on success, %FALSE otherwise (@err should be * set on failure). */ typedef gboolean (*SwamiPluginInitFunc)(SwamiPlugin *plugin, GError **err); /** * SwamiPluginExitFunc: * @plugin: Plugin object being unloaded * * A function type called before a plugin is unloaded. */ typedef void (*SwamiPluginExitFunc)(SwamiPlugin *plugin); /** * SwamiPluginSaveXmlFunc: * @plugin: Plugin object to save preference state of * @xmlnode: #IpatchXmlNode tree to save preferences to * @err: Location to store error info to * * An optional function type which is called to save a plugin's preference state to * an XML tree. The passed in @xmlnode is an XML node created for this plugin. * * Returns: Should return %TRUE on success, %FALSE otherwise (in which case @err * should be set). */ typedef gboolean (*SwamiPluginSaveXmlFunc)(SwamiPlugin *plugin, GNode *xmlnode, GError **err); /** * SwamiPluginLoadXmlFunc: * @plugin: Plugin object to load preference state to * @xmlnode: #IpatchXmlNode tree to load preferences from * @err: Location to store error info to * * An optional function type which is called to load a plugin's preference state from * an XML tree. The passed in @xmlnode is an XML node for this plugin. * * Returns: Should return %TRUE on success, %FALSE otherwise (in which case @err * should be set). */ typedef gboolean (*SwamiPluginLoadXmlFunc)(SwamiPlugin *plugin, GNode *xmlnode, GError **err); /* Swami plugin object (each loaded plugin gets one of these) */ struct _SwamiPlugin { GTypeModule parent_instance; /* derived from GTypeModule */ /*< private >*/ GModule *module; /* module of the plugin or NULL if not loaded */ SwamiPluginInitFunc init; /* function stored from SwamiPluginInfo */ SwamiPluginExitFunc exit; /* function stored from SwamiPluginInfo */ SwamiPluginSaveXmlFunc save_xml; /* Optional XML save function assigned in init */ SwamiPluginLoadXmlFunc load_xml; /* Optional XML load function assigned in init */ char *filename; /* filename it came from */ char *version; /* plugin specific version string */ char *author; /* author of this plugin */ char *copyright; /* copyright string */ char *descr; /* description of plugin */ char *license; /* license this plugin is distributed under */ }; /* Swami plugin class */ struct _SwamiPluginClass { GTypeModuleClass parent_class; }; /* magic string to check sanity of plugins */ //#define SWAMI_PLUGIN_MAGIC GUINT_FROM_BE(0x53574D49) #define SWAMI_PLUGIN_MAGIC "SWMI" struct _SwamiPluginInfo { char magic[4]; /* magic string to ensure sanity */ char *swami_version; /* version of Swami plugin compiled for */ SwamiPluginInitFunc init; /* called to initialize plugin */ SwamiPluginExitFunc exit; /* called before plugin is unloaded */ }; /* a convenience macro to define plugin info */ #define SWAMI_PLUGIN_INFO(init, exit) \ SwamiPluginInfo swami_plugin_info = \ { \ SWAMI_PLUGIN_MAGIC, \ SWAMI_VERSION, \ init, \ exit \ }; GType swami_plugin_get_type (void); void swami_plugin_add_path (const char *path); void swami_plugin_load_all (void); gboolean swami_plugin_load (const char *filename); gboolean swami_plugin_load_absolute (const char *filename); gboolean swami_plugin_load_plugin (SwamiPlugin *plugin); gboolean swami_plugin_is_loaded (SwamiPlugin *plugin); SwamiPlugin *swami_plugin_find (const char *name); GList *swami_plugin_get_list (void); gboolean swami_plugin_save_xml (SwamiPlugin *plugin, GNode *xmlnode, GError **err); gboolean swami_plugin_load_xml (SwamiPlugin *plugin, GNode *xmlnode, GError **err); #endif /* __SWAMI_PLUGIN_H__ */ swami/src/libswami/i18n.h0000644000175000017500000000061010075302551015377 0ustar alessioalessio#ifndef __LIBSWAMI_I18N_H__ #define __LIBSWAMI_I18N_H__ #include #ifndef _ #if defined(ENABLE_NLS) # include # define _(x) dgettext("libswami", x) # ifdef gettext_noop # define N_(String) gettext_noop (String) # else # define N_(String) (String) # endif #else # define N_(String) (String) # define _(x) (x) # define gettext(x) (x) #endif #endif #endif swami/src/libswami/SwamiControl.h0000644000175000017500000002531611461334205017254 0ustar alessioalessio/* * SwamiControl.h - Swami control base object * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMI_CONTROL_H__ #define __SWAMI_CONTROL_H__ typedef struct _SwamiControl SwamiControl; typedef struct _SwamiControlClass SwamiControlClass; #include #include #include #include #include #include #include #include #define SWAMI_TYPE_CONTROL (swami_control_get_type ()) #define SWAMI_CONTROL(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMI_TYPE_CONTROL, SwamiControl)) #define SWAMI_CONTROL_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMI_TYPE_CONTROL, \ SwamiControlClass)) #define SWAMI_IS_CONTROL(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMI_TYPE_CONTROL)) #define SWAMI_IS_CONTROL_CLASS(obj) \ (G_TYPE_CHECK_CLASS_TYPE ((obj), SWAMI_TYPE_CONTROL)) #define SWAMI_CONTROL_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS (obj, SWAMI_TYPE_CONTROL, SwamiControlClass)) /* Swami control object */ struct _SwamiControl { SwamiLock parent_instance; /* derived from SwamiLock */ guint flags; /* flags field (SwamiControlFlags) */ GList *active; /* active event propagations */ SwamiControlQueue *queue; /* event queue or NULL if no queuing */ SwamiControl *master; /* control to slave parameter spec to or NULL */ GType value_type; /* control value type (or 0 for wildcard) */ /* lists of SwamiControlConn structures (defined in SwamiControl.c) */ GSList *inputs; /* list of input connections (readable) */ GSList *outputs; /* list of output connections (writable) */ }; /** * SwamiControlGetSpecFunc: * @control: Control to get parameter spec for * * A #SwamiControlClass optional method type to get the parameter spec * from a control. If this method is not used or it returns %NULL then * the control is assumed to accept control events of any type. * * Note: The control is locked while calling this method. Also, this * method should return the parameter spec quickly, to speed up the event * emission process. * * Returns: Should return the parameter specification for the control or * %NULL for type independent controls. Reference count should not be modified, * this is handled by the caller. */ typedef GParamSpec *(*SwamiControlGetSpecFunc)(SwamiControl *control); /** * SwamiControlSetSpecFunc: * @control: Control to get parameter spec for * @pspec: Parameter specification to assign * * A #SwamiControlClass optional method type to set the parameter spec * for a control. The method should call g_param_spec_ref() followed by * g_param_spec_sink () to take over the reference. * If a control has a specific value type and the * #SWAMI_CONTROL_SPEC_NO_CONV is not set then the parameter spec is * converted to the parameter spec type used for the given value type and the * min/max/default values of the parameter spec will be processed with the * set_trans value transform function if assigned, * otherwise the parameter spec is passed as is without conversion. * * Note: The control is locked while calling this method. * * Returns: Should return %TRUE if parameter spec change was allowed, * %FALSE otherwise. */ typedef gboolean (*SwamiControlSetSpecFunc)(SwamiControl *control, GParamSpec *pspec); /** * SwamiControlGetValueFunc: * @control: Control to get value from * @value: Caller supplied value to store control value in * * A #SwamiControlClass optional method type to get the value from a * value control that is readable (#SWAMI_CONTROL_SENDS flag must be * set). The @value has been initialized to the native type of the * control's parameter spec. If this method is used then * #SwamiControlGetSpecFunc must also be set. * * Note: The control is not locked when calling this method. */ typedef void (*SwamiControlGetValueFunc)(SwamiControl *control, GValue *value); /** * SwamiControlSetValueFunc: * @control: Control that is receiving an event * @event: Control event being received * @value: Value which is being received (possibly converted from original * event value depending on the control's settings) * * A #SwamiControlClass optional method type to receive control * values. If the #SWAMI_CONTROL_NO_CONV flag is not set for this * control and the #SwamiControlGetSpecFunc returns a parameter spec * then @value will be the result of the original event value * converted to the control's native type. * * This method gets called for events received via a control's inputs * or when swami_control_set_event() or swami_control_set_value() is called. * * Note: The control is not locked during this method call. */ typedef void (*SwamiControlSetValueFunc)(SwamiControl *control, SwamiControlEvent *event, const GValue *value); struct _SwamiControlClass { SwamiLockClass parent_class; /* signals */ void (*connect)(SwamiControl *c1, SwamiControl *c2, guint flags); void (*disconnect)(SwamiControl *c1, SwamiControl *c2, guint flags); /* methods */ SwamiControlGetSpecFunc get_spec; SwamiControlSetSpecFunc set_spec; SwamiControlGetValueFunc get_value; SwamiControlSetValueFunc set_value; }; typedef enum { SWAMI_CONTROL_SENDS = 1 << 0, /* control is readable/sends */ SWAMI_CONTROL_RECVS = 1 << 1, /* control is writable/receives */ SWAMI_CONTROL_NO_CONV = 1 << 2, /* don't convert incoming values */ SWAMI_CONTROL_NATIVE = 1 << 3, /* values of native value type only */ SWAMI_CONTROL_VALUE = 1 << 4, /* value control - queue optimization */ SWAMI_CONTROL_SPEC_NO_CONV = 1 << 5 /* don't convert parameter spec type */ } SwamiControlFlags; /* mask for user controlled flag bits */ #define SWAMI_CONTROL_FLAGS_USER_MASK 0x7F /* a convenience value for send/receive controls */ #define SWAMI_CONTROL_SENDRECV (SWAMI_CONTROL_SENDS | SWAMI_CONTROL_RECVS) /* 7 bits used, 5 reserved */ #define SWAMI_CONTROL_UNUSED_FLAG_SHIFT 12 /* connection priority ranking (first 2 bits of flags field) */ typedef enum { SWAMI_CONTROL_CONN_PRIORITY_DEFAULT = 0, SWAMI_CONTROL_CONN_PRIORITY_LOW = 1, SWAMI_CONTROL_CONN_PRIORITY_MEDIUM = 2, SWAMI_CONTROL_CONN_PRIORITY_HIGH = 3 } SwamiControlConnPriority; #define SWAMI_CONTROL_CONN_PRIORITY_MASK (0x2) #define SWAMI_CONTROL_CONN_DEFAULT_PRIORITY_VALUE \ (SWAMI_CONTROL_CONN_PRIORITY_MEDIUM) typedef enum /*< flags >*/ { SWAMI_CONTROL_CONN_INPUT = 1 << 2, /* set for inputs (used internally) */ SWAMI_CONTROL_CONN_OUTPUT = 1 << 3, /* set for outputs (used internally) */ SWAMI_CONTROL_CONN_INIT = 1 << 4, /* update value on connect */ SWAMI_CONTROL_CONN_BIDIR = 1 << 5, /* make a bi-directional connection */ SWAMI_CONTROL_CONN_SPEC = 1 << 6 /* synchronize the parameter spec on connect */ } SwamiControlConnFlags; /* convenience combo flags */ /* #SWAMI_CONTROL_CONN_BIDIR and #SWAMI_CONTROL_CONN_INIT */ #define SWAMI_CONTROL_CONN_BIDIR_INIT \ (SWAMI_CONTROL_CONN_BIDIR | SWAMI_CONTROL_CONN_INIT) /* #SWAMI_CONTROL_CONN_BIDIR, #SWAMI_CONTROL_CONN_SPEC and * #SWAMI_CONTROL_CONN_INIT */ #define SWAMI_CONTROL_CONN_BIDIR_SPEC_INIT \ (SWAMI_CONTROL_CONN_BIDIR | SWAMI_CONTROL_CONN_SPEC | SWAMI_CONTROL_CONN_INIT) GType swami_control_get_type (void); SwamiControl *swami_control_new (void); void swami_control_connect (SwamiControl *src, SwamiControl *dest, guint flags); void swami_control_connect_transform (SwamiControl *src, SwamiControl *dest, guint flags, SwamiValueTransform trans1, SwamiValueTransform trans2, gpointer data1, gpointer data2, GDestroyNotify destroy1, GDestroyNotify destroy2); void swami_control_connect_item_prop (SwamiControl *dest, GObject *object, GParamSpec *pspec); void swami_control_disconnect (SwamiControl *src, SwamiControl *dest); void swami_control_disconnect_all (SwamiControl *control); void swami_control_disconnect_unref (SwamiControl *control); IpatchList *swami_control_get_connections (SwamiControl *control, SwamiControlConnFlags dir); void swami_control_set_transform (SwamiControl *src, SwamiControl *dest, SwamiValueTransform trans, gpointer data, GDestroyNotify destroy); void swami_control_get_transform (SwamiControl *src, SwamiControl *dest, SwamiValueTransform *trans); void swami_control_set_flags (SwamiControl *control, int flags); int swami_control_get_flags (SwamiControl *control); void swami_control_set_queue (SwamiControl *control, SwamiControlQueue *queue); SwamiControlQueue *swami_control_get_queue (SwamiControl *control); GParamSpec *swami_control_get_spec (SwamiControl *control); gboolean swami_control_set_spec (SwamiControl *control, GParamSpec *pspec); gboolean swami_control_sync_spec (SwamiControl *control, SwamiControl *source, SwamiValueTransform trans, gpointer data); GParamSpec * swami_control_transform_spec (SwamiControl *control, SwamiControl *source, SwamiValueTransform trans, gpointer data); void swami_control_set_value_type (SwamiControl *control, GType type); void swami_control_get_value (SwamiControl *control, GValue *value); void swami_control_get_value_native (SwamiControl *control, GValue *value); void swami_control_set_value (SwamiControl *control, const GValue *value); void swami_control_set_value_no_queue (SwamiControl *control, const GValue *value); void swami_control_set_event (SwamiControl *control, SwamiControlEvent *event); void swami_control_set_event_no_queue (SwamiControl *control, SwamiControlEvent *event); void swami_control_set_event_no_queue_loop (SwamiControl *control, SwamiControlEvent *event); void swami_control_transmit_value (SwamiControl *control, const GValue *value); void swami_control_transmit_event (SwamiControl *control, SwamiControlEvent *event); void swami_control_transmit_event_loop (SwamiControl *control, SwamiControlEvent *event); void swami_control_do_event_expiration (void); SwamiControlEvent *swami_control_new_event (SwamiControl *control, SwamiControlEvent *origin, const GValue *value); #endif swami/src/libswami/SwamiObject.c0000644000175000017500000007672611461334205017050 0ustar alessioalessio/* * SwamiObject.c - Child object properties and type rank system * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include #include #include "SwamiObject.h" #include "SwamiRoot.h" #include "builtin_enums.h" #include "i18n.h" #include "swami_priv.h" #define PARAM_SPEC_PARAM_ID(pspec) ((pspec)->param_id) #define PARAM_SPEC_SET_PARAM_ID(pspec, id) ((pspec)->param_id = (id)) /* Swami child object properties */ enum { OBJ_PROP_0, OBJ_PROP_NAME, OBJ_PROP_RANK, OBJ_PROP_FLAGS, OBJ_PROP_ROOT }; /* --- private function prototypes --- */ static gint swami_gcompare_typerank_by_rank (gconstpointer a, gconstpointer b); static gint swami_gcompare_typerank_by_type (gconstpointer a, gconstpointer b); static void swami_type_recurse_make_list (GType type, GList **list); static gboolean node_traverse_match_name (GNode *node, gpointer data); static gboolean node_traverse_match_type (GNode *node, gpointer data); static gint swami_gcompare_object_rank (gconstpointer a, gconstpointer b); static void swami_install_object_property (guint property_id, GParamSpec *pspec); static void object_property_notify_dispatcher (GObject *object, guint n_pspecs, GParamSpec **pspecs); static inline SwamiObjectPropBag *object_new_propbag (GObject *object); static void free_propbag (gpointer data); static void object_get_property (GObject *object, GParamSpec *pspec, GValue *value); static void object_set_property (GObject *object, GParamSpec *pspec, const GValue *value, GObjectNotifyQueue *nqueue); GQuark swami_object_propbag_quark; /* object qdata quark for property bag */ /* global lock for all Swami object property bags (only used for name property currently) */ G_LOCK_DEFINE_STATIC (SwamiObjectPropBag); static GParamSpecPool *object_property_pool; /* Swami property pool */ static GObjectNotifyContext *object_property_notify_context; /* structure used to rank GTypes */ typedef struct { GType type; int rank; } TypeRank; G_LOCK_DEFINE_STATIC (typerank); /* a lock for typerank system */ static GHashTable *typerank_hash = NULL; /* signal id of SwamiRoot PROP_NOTIFY signal (looked up by name) */ static guint root_prop_notify_signal_id; /* initialization for swami object properties and type rank system */ void _swami_object_init (void) { static GObjectNotifyContext opn_context = { 0, NULL, NULL }; root_prop_notify_signal_id = g_signal_lookup ("swami-prop-notify", SWAMI_TYPE_ROOT); typerank_hash = g_hash_table_new (NULL, NULL); object_property_pool = g_param_spec_pool_new (FALSE); opn_context.quark_notify_queue = g_quark_from_static_string ("Swami-object-property-notify-queue"); opn_context.dispatcher = object_property_notify_dispatcher; object_property_notify_context = &opn_context; /* get a quark for property bag object qdata quark */ swami_object_propbag_quark = g_quark_from_static_string ("_SwamiPropBag"); /* install Swami object properties */ swami_install_object_property (OBJ_PROP_NAME, g_param_spec_string ("name", _("Name"), _("Name"), NULL, G_PARAM_READWRITE)); swami_install_object_property (OBJ_PROP_RANK, g_param_spec_int ("rank", _("Rank"), _("Rank"), 1, 100, SWAMI_RANK_NORMAL, G_PARAM_READWRITE)); swami_install_object_property (OBJ_PROP_FLAGS, g_param_spec_flags ("flags", _("Flags"), _("Flags"), SWAMI_TYPE_OBJECT_FLAGS, 0, G_PARAM_READWRITE)); swami_install_object_property (OBJ_PROP_ROOT, g_param_spec_object ("root", _("Root"), _("Root object"), SWAMI_TYPE_ROOT, G_PARAM_READWRITE)); } /** * swami_type_set_rank: * @type: Type to set rank value of * @group_type: An ancestor type of @type * @rank: Rank value (see #SwamiRank enum). * * Sets the ranking of instance GTypes derived from an ancestor @group_type. * This is useful to set a default instance type or to define order to types. * An example of use would be to set a higher rank on a plugin wavetable type * to cause it to be used when creating a default wavetable instance. */ void swami_type_set_rank (GType type, GType group_type, int rank) { GSList *grplist, *p; TypeRank *typerank; g_return_if_fail (g_type_is_a (type, group_type)); rank = CLAMP (rank, 1, 100); G_LOCK (typerank); grplist = g_hash_table_lookup (typerank_hash, GINT_TO_POINTER (group_type)); if (grplist) { p = grplist; while (p) /* remove existing TypeRank for @type (if any) */ { if (((TypeRank *)(p->data))->type == type) { g_slice_free (TypeRank, p->data); grplist = g_slist_delete_link (grplist, p); break; } p = g_slist_next (p); } } if (rank != SWAMI_RANK_NORMAL) { typerank = g_slice_new (TypeRank); typerank->type = type; typerank->rank = rank; grplist = g_slist_insert_sorted (grplist, typerank, swami_gcompare_typerank_by_rank); } g_hash_table_insert (typerank_hash, GINT_TO_POINTER (group_type), grplist); G_UNLOCK (typerank); } static gint swami_gcompare_typerank_by_rank (gconstpointer a, gconstpointer b) { TypeRank *atyperank = (TypeRank *)a, *btyperank = (TypeRank *)b; return (atyperank->rank - btyperank->rank); } static gint swami_gcompare_typerank_by_type (gconstpointer a, gconstpointer b) { TypeRank *atyperank = (TypeRank *)a, *btyperank = (TypeRank *)b; return (atyperank->type - btyperank->type); } /** * swami_type_get_rank: * @type: Instance type to get rank of * @group_type: Ancestor group type * * Gets the instance rank of the given @type derived from a @group_type. * See swami_type_set_rank() for more info. * * Returns: Rank value (#SWAMI_RANK_NORMAL if not explicitly set). */ int swami_type_get_rank (GType type, GType group_type) { GSList *grplist, *p; TypeRank find; int rank = SWAMI_RANK_NORMAL; g_return_val_if_fail (g_type_is_a (type, group_type), 0); find.type = type; G_LOCK (typerank); grplist = g_hash_table_lookup (typerank_hash, GINT_TO_POINTER (group_type)); p = g_slist_find_custom (grplist, &find, swami_gcompare_typerank_by_type); if (p) rank = ((TypeRank *)(p->data))->rank; G_UNLOCK (typerank); return (rank); } /** * swami_type_get_children: * @group_type: Group type to get derived types from * * Gets an array of types that are derived from @group_type, sorted by rank. * For types that have not had their rank explicitly set #SWAMI_RANK_NORMAL * will be assumed. * * Returns: Newly allocated and zero terminated array of GTypes sorted by rank * or %NULL if no types found. Should be freed when finished. */ GType * swami_type_get_children (GType group_type) { GList *typelist = NULL, *sortlist = NULL, *normal = NULL, *tp; GSList *grplist, *p; TypeRank *typerank; GType *retarray, *ap; g_return_val_if_fail (group_type != 0, NULL); /* create list of type tree under (and including) group_type */ swami_type_recurse_make_list (group_type, &typelist); if (!typelist) return (NULL); G_LOCK (typerank); /* sort typelist */ grplist = g_hash_table_lookup (typerank_hash, GINT_TO_POINTER (group_type)); p = grplist; while (p) { typerank = (TypeRank *)(p->data); tp = g_list_find (typelist, GINT_TO_POINTER (typerank->type)); if (tp) { typelist = g_list_remove_link (typelist, tp); sortlist = g_list_concat (tp, sortlist); /* finds the node to insert SWAMI_RANK_NORMAL types at */ if (typerank->rank > SWAMI_RANK_NORMAL) normal = tp; } p = g_slist_next (p); } G_UNLOCK (typerank); /* add remaining SWAMI_RANK_NORMAL types (not in hash) */ if (typelist) { if (normal) /* found node to insert SWAMI_RANK_NORMAL types before? */ { GList *last = g_list_last (typelist); /* link SWAMI_RANK_NORMAL types into sortlist */ if (normal->prev) normal->prev->next = typelist; typelist->prev = normal->prev; normal->prev = last; last->next = normal; } /* all ranks in hash below or equal to SWAMI_RANK_NORMAL, append */ else sortlist = g_list_concat (sortlist, typelist); } tp = sortlist = g_list_reverse (sortlist); ap = retarray = g_malloc ((g_list_length (sortlist) + 1) * sizeof (GType)); while (tp) { *ap = GPOINTER_TO_INT (tp->data); /* store GType into array element */ ap++; tp = g_list_delete_link (tp, tp); /* delete and iterate */ } *ap = 0; return (retarray); } /* recursive function to find non-abstract types derived from initial type */ static void swami_type_recurse_make_list (GType type, GList **list) { GType *children, *t; if (!G_TYPE_IS_ABSTRACT (type)) /* only add non-abstract types */ *list = g_list_prepend (*list, GINT_TO_POINTER (type)); children = g_type_children (type, NULL); t = children; while (*t) { swami_type_recurse_make_list (*t, list); t++; } g_free (children); } /** * swami_type_get_default: * @group_type: Group type to get default (highest ranked) instance type from * * Gets the default (highest ranked) type derived from a group_type. * Like swami_type_get_children() but returns first type instead of an array. * * Returns: GType of default type or 0 if no types derived from @group_type. */ GType swami_type_get_default (GType group_type) { GType *types, rettype = 0; types = swami_type_get_children (group_type); if (types) { rettype = *types; g_free (types); } return (rettype); } /** * swami_object_set_default: * @object: Object to set as default * @type: A type that @object is derived from (or its type) * * Set an @object as default amongst its peers of the same @type. Uses * the Swami rank system (see "rank" Swami property) to elect a default * object. All other object's registered to the same #SwamiRoot and of * the same @type (or derived thereof) are set to #SWAMI_RANK_NORMAL and the * @object's rank is set higher. */ void swami_object_set_default (GObject *object, GType type) { IpatchList *list; IpatchIter iter; GObject *pobj; g_return_if_fail (G_IS_OBJECT (object)); g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (object, type)); list = swami_object_find_by_type (object, g_type_name (type));/* ++ ref */ g_return_if_fail (list != NULL); ipatch_list_init_iter (list, &iter); pobj = ipatch_iter_first (&iter); while (pobj) { swami_object_set (pobj, "rank", (pobj == object) ? SWAMI_RANK_DEFAULT : SWAMI_RANK_NORMAL); pobj = ipatch_iter_next (&iter); } g_object_unref (list); /* -- unref list */ } /* a bag for swami_object_get_by_name() */ typedef struct { const char *name; GObject *match; } ObjectFindNameBag; /** * swami_object_get_by_name: * @object: Swami root object (#SwamiRoot) or an object added to one * @name: Name to look for * * Finds an object by its Swami name property, searches recursively * through object tree. The @object can be either a #SwamiRoot or, as * an added convenience, an object registered to one. * * Returns: Object that matched @name or %NULL if not found. Remember to * unref it when finished. */ GObject * swami_object_get_by_name (GObject *object, const char *name) { ObjectFindNameBag findbag; SwamiObjectPropBag *propbag; SwamiRoot *root; g_return_val_if_fail (G_IS_OBJECT (object), NULL); g_return_val_if_fail (name != NULL, NULL); if (!SWAMI_IS_ROOT (object)) { propbag = g_object_get_qdata (object, swami_object_propbag_quark); g_return_val_if_fail (propbag != NULL, NULL); g_return_val_if_fail (SWAMI_IS_ROOT (propbag->root), NULL); root = propbag->root; } else root = SWAMI_ROOT (object); findbag.name = name; findbag.match = NULL; SWAMI_LOCK_READ (root->proptree); g_node_traverse (root->proptree->tree, G_PRE_ORDER, G_TRAVERSE_ALL, -1, node_traverse_match_name, &findbag); SWAMI_UNLOCK_READ (root->proptree); return (findbag.match); } static gboolean node_traverse_match_name (GNode *node, gpointer data) { ObjectFindNameBag *findbag = (ObjectFindNameBag *)data; SwamiPropTreeNode *propnode; SwamiObjectPropBag *propbag; propnode = (SwamiPropTreeNode *)(node->data); propbag = g_object_get_qdata (G_OBJECT (propnode->object), swami_object_propbag_quark); if (propbag && propbag->name && strcmp (findbag->name, propbag->name) == 0) { findbag->match = propnode->object; g_object_ref (findbag->match); return (TRUE); /* stop this madness */ } return (FALSE); /* continue until found */ } /* a bag for swami_object_find_by_type() */ typedef struct { GType type; IpatchList *list; } ObjectFindTypeBag; /** * swami_object_find_by_type: * @object: Swami root object (#SwamiRoot) or an object added to one * @type_name: Name of GObject derived GType of objects to search for, objects * derived from this type will also match. * * Lookup all objects by @type_name or derived from @type_name * recursively. The @object can be either a #SwamiRoot or, as an * added convenience, an object registered to one. The returned * iterator list is sorted by Swami rank (see "rank" Swami property). * * Returns: New list of objects of @type_name and/or derived * from it or NULL if no matches to that type. The returned list has a * reference count of 1 which the caller owns, remember to unref it when * finished. */ IpatchList * swami_object_find_by_type (GObject *object, const char *type_name) { ObjectFindTypeBag findbag; SwamiObjectPropBag *propbag; SwamiRoot *root; GType type; g_return_val_if_fail (G_IS_OBJECT (object), NULL); type = g_type_from_name (type_name); g_return_val_if_fail (type != 0, NULL); g_return_val_if_fail (g_type_is_a (type, G_TYPE_OBJECT), NULL); if (!SWAMI_IS_ROOT (object)) { propbag = g_object_get_qdata (object, swami_object_propbag_quark); g_return_val_if_fail (propbag != NULL, NULL); g_return_val_if_fail (SWAMI_IS_ROOT (propbag->root), NULL); root = propbag->root; } else root = SWAMI_ROOT (object); findbag.type = type; findbag.list = ipatch_list_new (); /* ++ ref new list */ SWAMI_LOCK_READ (root->proptree); g_node_traverse (root->proptree->tree, G_PRE_ORDER, G_TRAVERSE_ALL, -1, node_traverse_match_type, &findbag); SWAMI_UNLOCK_READ (root->proptree); if (!findbag.list->items) /* free list if no matching items */ { g_object_unref (findbag.list); /* -- unref list */ findbag.list = NULL; } /* sort object list by Swami rank */ else findbag.list->items = g_list_sort (findbag.list->items, swami_gcompare_object_rank); return (findbag.list); } static gboolean node_traverse_match_type (GNode *node, gpointer data) { ObjectFindTypeBag *bag = (ObjectFindTypeBag *)data; SwamiPropTreeNode *propnode; propnode = (SwamiPropTreeNode *)(node->data); if (g_type_is_a (G_TYPE_FROM_INSTANCE (propnode->object), bag->type)) { g_object_ref (propnode->object); /* ++ ref for list */ bag->list->items = g_list_prepend (bag->list->items, propnode->object); } return (FALSE); /* don't stop for nothin */ } static gint swami_gcompare_object_rank (gconstpointer a, gconstpointer b) { int arank, brank; swami_object_get (G_OBJECT (a), "rank", &arank, NULL); swami_object_get (G_OBJECT (b), "rank", &brank, NULL); return (arank - brank); } /** * swami_object_get_by_type: * @object: Swami root object (#SwamiRoot) or an object added to one * @type_name: Name of GObject derived GType to search for * * Lookup the highest ranking (see "rank" Swami property) object of * the given @type_name or derived from it. The returned object's * reference count is incremented and the caller is responsible for * removing it with g_object_unref when finished with it. * * Returns: The highest ranking object of the given type or NULL if none. * Remember to unreference it when done. */ GObject * swami_object_get_by_type (GObject *object, const char *type_name) { IpatchList *list; GObject *match = NULL; list = swami_object_find_by_type (object, type_name); /* ++ ref list */ if (list) { match = (GObject *)(list->items->data); g_object_ref (match); g_object_unref (list); /* -- unref list */ } return (match); } /** * swami_object_get_valist: * @object: An object * @first_property_name: Name of first Swami property to get * @var_args: Pointer to store first property value in followed by * property name pointer pairs, terminated with a NULL property name. * * Get Swami properties from an object. */ void swami_object_get_valist (GObject *object, const char *first_property_name, va_list var_args) { const char *name; g_return_if_fail (G_IS_OBJECT (object)); name = first_property_name; while (name) { GValue value = { 0, }; GParamSpec *pspec; char *error; pspec = g_param_spec_pool_lookup (object_property_pool, name, SWAMI_TYPE_ROOT, FALSE); if (!pspec) { g_warning ("%s: no Swami property named `%s'", G_STRLOC, name); break; } if (!(pspec->flags & G_PARAM_READABLE)) { g_warning ("%s: Swami property `%s' is not readable", G_STRLOC, pspec->name); break; } g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec)); object_get_property (object, pspec, &value); G_VALUE_LCOPY (&value, var_args, 0, &error); if (error) { g_warning ("%s: %s", G_STRLOC, error); g_free (error); g_value_unset (&value); break; } g_value_unset (&value); name = va_arg (var_args, char *); } } /** * swami_object_get_property: * @object: An object * @property_name: Name of Swami property to get * @value: An initialized value to store the property value in. The value's * type must be a type that the property can be transformed to. * * Get a Swami property from an object. */ void swami_object_get_property (GObject *object, const char *property_name, GValue *value) { GParamSpec *pspec; g_return_if_fail (G_IS_OBJECT (object)); g_return_if_fail (property_name != NULL); g_return_if_fail (G_IS_VALUE (value)); pspec = g_param_spec_pool_lookup (object_property_pool, property_name, SWAMI_TYPE_ROOT, FALSE); if (!pspec) g_warning ("%s: no Swami property named `%s'", G_STRLOC, property_name); else if (!(pspec->flags & G_PARAM_READABLE)) g_warning ("%s: Swami property `%s' is not readable", G_STRLOC, pspec->name); else { GValue *prop_value, tmp_value = { 0, }; /* auto-conversion of the callers value type */ if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec)) { g_value_reset (value); prop_value = value; } else if (!g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value))) { g_warning ("can't retrieve Swami property `%s' of type `%s' as" " value of type `%s'", pspec->name, g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)), G_VALUE_TYPE_NAME (value)); return; } else { g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec)); prop_value = &tmp_value; } object_get_property (object, pspec, prop_value); if (prop_value != value) { g_value_transform (prop_value, value); g_value_unset (&tmp_value); } } } /** * swami_object_get: * @object: A GObject * @first_prop_name: Name of first Swami property to get * @...: First value should be a pointer to store the first property value into * followed by property name and pointer pairs, terminated by a %NULL * property name. * * Get multiple Swami properties from an @object. */ void swami_object_get (gpointer object, const char *first_prop_name, ...) { va_list var_args; g_return_if_fail (G_IS_OBJECT (object)); va_start (var_args, first_prop_name); swami_object_get_valist (object, first_prop_name, var_args); va_end (var_args); } /** * swami_object_set_valist: * @object: An object * @first_property_name: Name of first Swami property to set * @var_args: Pointer to get first property value from followed by * property name pointer pairs, terminated with a NULL property name. * * Set Swami properties of an object. */ void swami_object_set_valist (GObject *object, const char *first_property_name, va_list var_args) { GObjectNotifyQueue *nqueue; const char *name; g_return_if_fail (G_IS_OBJECT (object)); nqueue = g_object_notify_queue_freeze (object, object_property_notify_context); name = first_property_name; while (name) { GValue value = { 0, }; gchar *error = NULL; GParamSpec *pspec = g_param_spec_pool_lookup (object_property_pool, name, SWAMI_TYPE_ROOT, FALSE); if (!pspec) { g_warning ("%s: no Swami property named `%s'", G_STRLOC, name); break; } if (!(pspec->flags & G_PARAM_WRITABLE)) { g_warning ("%s: Swami property `%s' is not writable", G_STRLOC, pspec->name); break; } g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec)); G_VALUE_COLLECT (&value, var_args, 0, &error); if (error) { g_warning ("%s: %s", G_STRLOC, error); g_free (error); /* we purposely leak the value here, it might not be * in a sane state if an error condition occured */ break; } object_set_property (object, pspec, &value, nqueue); g_value_unset (&value); name = va_arg (var_args, char *); } g_object_notify_queue_thaw (object, nqueue); } /** * swami_object_set_property: * @object: An object * @property_name: Name of Swami property to set * @value: Value to set the property to. The value's type must be the same * as the property's type. * * Set a Swami property of an object. */ void swami_object_set_property (GObject *object, const char *property_name, const GValue *value) { GObjectNotifyQueue *nqueue; GParamSpec *pspec; g_return_if_fail (G_IS_OBJECT (object)); g_return_if_fail (property_name != NULL); g_return_if_fail (G_IS_VALUE (value)); nqueue = g_object_notify_queue_freeze (object, object_property_notify_context); pspec = g_param_spec_pool_lookup (object_property_pool, property_name, SWAMI_TYPE_ROOT, FALSE); if (!pspec) g_warning ("%s: no Swami property named `%s'", G_STRLOC, property_name); else if (!(pspec->flags & G_PARAM_WRITABLE)) g_warning ("%s: Swami property `%s' is not writable", G_STRLOC, pspec->name); else object_set_property (object, pspec, value, nqueue); g_object_notify_queue_thaw (object, nqueue); } /** * swami_object_set: * @object: A GObject * @first_prop_name: Name of first Swami property to set * @...: First parameter should be the value to set the first property * value to followed by property name and pointer pairs, terminated * by a %NULL property name. * * Set multiple Swami properties on an @object. */ void swami_object_set (gpointer object, const char *first_prop_name, ...) { va_list var_args; g_return_if_fail (G_IS_OBJECT (object)); va_start (var_args, first_prop_name); swami_object_set_valist (object, first_prop_name, var_args); va_end (var_args); } /* install a Swami property */ static void swami_install_object_property (guint property_id, GParamSpec *pspec) { g_return_if_fail (property_id > 0); g_return_if_fail (PARAM_SPEC_PARAM_ID (pspec) == 0); /* paranoid */ if (g_param_spec_pool_lookup (object_property_pool, pspec->name, SWAMI_TYPE_ROOT, FALSE)) { g_warning (G_STRLOC ": already a Swami property named `%s'", pspec->name); return; } g_param_spec_ref (pspec); g_param_spec_sink (pspec); PARAM_SPEC_SET_PARAM_ID (pspec, property_id); g_param_spec_pool_insert (object_property_pool, pspec, SWAMI_TYPE_ROOT); } /** * swami_find_object_property: * @property_name: Name of Swami property to find * * Find a Swami property. * * Returns: Parameter spec with @property_name or %NULL if not found. * Returned parameter spec is internal and should not be modified or freed. */ GParamSpec * swami_find_object_property (const char *property_name) { g_return_val_if_fail (property_name != NULL, NULL); return (g_param_spec_pool_lookup (object_property_pool, property_name, SWAMI_TYPE_ROOT, FALSE)); } /** * swami_list_object_properties: * @n_properties: Location to store number of param specs or %NULL * * Get the list of Swami properties. * * Returns: A %NULL terminated array of GParamSpecs. Free the array when * finished with it, but don't mess with the contents. */ GParamSpec ** swami_list_object_properties (guint *n_properties) { GParamSpec **pspecs; guint n; pspecs = g_param_spec_pool_list (object_property_pool, SWAMI_TYPE_ROOT, &n); if (n_properties) *n_properties = n; return (pspecs); } /** * swami_object_get_flags: * @object: Object to get Swami flags from * * Get Swami flags from an object (see #SwamiObjectFlags). * * Returns: The flags value. */ guint swami_object_get_flags (GObject *object) { SwamiObjectPropBag *propbag; g_return_val_if_fail (G_IS_OBJECT (object), 0); propbag = g_object_get_qdata (object, swami_object_propbag_quark); if (!propbag) return (0); return (propbag->flags); } /** * swami_object_set_flags: * @object: Object to set Swami flags on * @flags: Flags to set * * Sets Swami @flags in an @object. Flag bits are only set, not cleared. */ void swami_object_set_flags (GObject *object, guint flags) { SwamiObjectPropBag *propbag; g_return_if_fail (G_IS_OBJECT (object)); G_LOCK (SwamiObjectPropBag); propbag = g_object_get_qdata (object, swami_object_propbag_quark); if (!propbag) propbag = object_new_propbag (object); propbag->flags |= flags; G_UNLOCK (SwamiObjectPropBag); } /** * swami_object_clear_flags: * @object: Object to clear Swami flags on * @flags: Flags to clear * * Clears Swami @flags in an @object. Flag bits are only cleared, not set. */ void swami_object_clear_flags (GObject *object, guint flags) { SwamiObjectPropBag *propbag; g_return_if_fail (G_IS_OBJECT (object)); propbag = g_object_get_qdata (object, swami_object_propbag_quark); if (!propbag) return; propbag->flags &= ~flags; } /* dispatches swami property changes */ static void object_property_notify_dispatcher (GObject *object, guint n_pspecs, GParamSpec **pspecs) { SwamiObjectPropBag *propbag; guint i; propbag = g_object_get_qdata (object, swami_object_propbag_quark); if (!propbag || !propbag->root) return; /* rootless objects */ for (i = 0; i < n_pspecs; i++) g_signal_emit (propbag->root, root_prop_notify_signal_id, g_quark_from_string (pspecs[i]->name), pspecs[i]); } static inline SwamiObjectPropBag * object_new_propbag (GObject *object) { SwamiObjectPropBag *propbag; propbag = g_slice_new0 (SwamiObjectPropBag); g_object_set_qdata_full (object, swami_object_propbag_quark, propbag, free_propbag); return (propbag); } static void free_propbag (gpointer data) { g_slice_free (SwamiObjectPropBag, data); } /* Swami child object get property routine */ static void object_get_property (GObject *object, GParamSpec *pspec, GValue *value) { guint property_id = PARAM_SPEC_PARAM_ID (pspec); SwamiObjectPropBag *propbag; propbag = g_object_get_qdata (object, swami_object_propbag_quark); switch (property_id) { case OBJ_PROP_NAME: G_LOCK (SwamiObjectPropBag); if (propbag) g_value_set_string (value, propbag->name); else g_value_set_string (value, NULL); G_UNLOCK (SwamiObjectPropBag); break; case OBJ_PROP_RANK: if (propbag) g_value_set_int (value, propbag->rank); else g_value_set_int (value, SWAMI_RANK_NORMAL); break; case OBJ_PROP_FLAGS: if (propbag) g_value_set_flags (value, propbag->flags); else g_value_set_flags (value, 0); break; case OBJ_PROP_ROOT: if (propbag) g_value_set_object (value, propbag->root); else g_value_set_object (value, NULL); break; default: break; } } static void object_set_property (GObject *object, GParamSpec *pspec, const GValue *value, GObjectNotifyQueue *nqueue) { GValue tmp_value = { 0, }; /* provide a copy to work from, convert (if necessary) and validate */ g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec)); if (!g_value_transform (value, &tmp_value)) g_warning ("unable to set Swami property `%s' of type `%s' from" " value of type `%s'", pspec->name, g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)), G_VALUE_TYPE_NAME (value)); else if (g_param_value_validate (pspec, &tmp_value) && !(pspec->flags & G_PARAM_LAX_VALIDATION)) { char *contents = g_strdup_value_contents (value); g_warning ("value \"%s\" of type `%s' is invalid for Swami" " property `%s' of type `%s'", contents, G_VALUE_TYPE_NAME (value), pspec->name, g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec))); g_free (contents); } else { guint property_id = PARAM_SPEC_PARAM_ID (pspec); SwamiObjectPropBag *propbag; G_LOCK (SwamiObjectPropBag); propbag = g_object_get_qdata (object, swami_object_propbag_quark); if (!propbag) propbag = object_new_propbag (object); switch (property_id) { case OBJ_PROP_NAME: g_free (propbag->name); propbag->name = g_value_dup_string (value); break; case OBJ_PROP_RANK: propbag->rank = g_value_get_int (value); break; case OBJ_PROP_FLAGS: propbag->flags = g_value_get_flags (value); break; case OBJ_PROP_ROOT: propbag->root = g_value_get_object (value); break; default: break; } G_UNLOCK (SwamiObjectPropBag); g_object_notify_queue_add (G_OBJECT (object), nqueue, pspec); } g_value_unset (&tmp_value); } /** * swami_object_set_origin: * @obj: Object to assign origin object value * @origin: Value to assign as the origin * * This is used for associating an origin object to another object. Currently * this is only used for #GtkList item selections. The current active item * selection is assigned to the swamigui_root object. In order to determine * what GUI widget is the source, this function can be used to associate the * widget object with the #GtkList selection (for example the #SwamiguiTree or * #SwamiguiSplits widgets). In this way, only the selection needs to be * assigned to the root object and the source widget can be determined. */ void swami_object_set_origin (GObject *obj, GObject *origin) { g_return_if_fail (G_IS_OBJECT (obj)); g_return_if_fail (G_IS_OBJECT (origin)); g_object_set_data (obj, "_SwamiOrigin", origin); } /** * swami_object_get_origin: * @obj: Object to get the origin object of * * See swamigui_object_set_origin() for more details. * * Returns: The origin object of @obj or NULL if no origin object assigned. * The caller owns a reference to the returned object and should unref it * when finished. */ GObject * swami_object_get_origin (GObject *obj) { GObject *origin; g_return_val_if_fail (G_IS_OBJECT (obj), NULL); origin = g_object_get_data (obj, "_SwamiOrigin"); if (origin) g_object_ref (origin); return (origin); } swami/src/libswami/SwamiEvent_ipatch.h0000644000175000017500000000535311461334205020244 0ustar alessioalessio/* * SwamiEvent_ipatch.h - libInstPatch SwamiControl event types * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMI_CONTROL_IPATCH_H__ #define __SWAMI_CONTROL_IPATCH_H__ #include /* libInstPatch event box types */ #define SWAMI_TYPE_EVENT_ITEM_ADD (swami_event_item_add_get_type ()) #define SWAMI_VALUE_HOLDS_EVENT_ITEM_ADD(value) \ (G_TYPE_CHECK_VALUE_TYPE ((value), SWAMI_TYPE_EVENT_ITEM_ADD)) #define SWAMI_TYPE_EVENT_ITEM_REMOVE (swami_event_item_remove_get_type ()) #define SWAMI_VALUE_HOLDS_EVENT_ITEM_REMOVE(value) \ (G_TYPE_CHECK_VALUE_TYPE ((value), SWAMI_TYPE_EVENT_ITEM_REMOVE)) #define SWAMI_TYPE_EVENT_PROP_CHANGE (swami_event_prop_change_get_type ()) #define SWAMI_VALUE_HOLDS_EVENT_PROP_CHANGE(value) \ (G_TYPE_CHECK_VALUE_TYPE ((value), SWAMI_TYPE_EVENT_PROP_CHANGE)) /* item add just uses IpatchItem pointer */ typedef IpatchItem SwamiEventItemAdd; typedef struct _SwamiEventItemRemove { IpatchItem *item; /* item removed or to be removed */ IpatchItem *parent; /* parent of item */ } SwamiEventItemRemove; typedef struct _SwamiEventPropChange { GObject *object; /* object whose property changed */ GParamSpec *pspec; /* property parameter spec */ GValue value; /* new value */ } SwamiEventPropChange; GType swami_event_item_add_get_type (void); GType swami_event_item_remove_get_type (void); GType swami_event_prop_change_get_type (void); SwamiEventItemAdd *swami_event_item_add_copy (SwamiEventItemAdd *item_add); void swami_event_item_add_free (SwamiEventItemAdd *item_add); SwamiEventItemRemove *swami_event_item_remove_new (void); SwamiEventItemRemove * swami_event_item_remove_copy (SwamiEventItemRemove *item_remove); void swami_event_item_remove_free (SwamiEventItemRemove *item_remove); SwamiEventPropChange *swami_event_prop_change_new (void); SwamiEventPropChange * swami_event_prop_change_copy (SwamiEventPropChange *prop_change); void swami_event_prop_change_free (SwamiEventPropChange *prop_change); #endif swami/src/libswami/value_transform.c0000644000175000017500000000410011461334205020021 0ustar alessioalessio/* * value_transform.c - Value transform functions * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include static void value_transform_string_int (const GValue *src_value, GValue *dest_value); static void value_transform_string_double (const GValue *src_value, GValue *dest_value); void _swami_value_transform_init (void) { g_value_register_transform_func (G_TYPE_STRING, G_TYPE_INT, value_transform_string_int); g_value_register_transform_func (G_TYPE_STRING, G_TYPE_DOUBLE, value_transform_string_double); } /* string to int transform function */ static void value_transform_string_int (const GValue *src_value, GValue *dest_value) { const char *str; char *endptr; long int lval = 0; str = g_value_get_string (src_value); if (str) { lval = strtol (str, &endptr, 10); if (*endptr != '\0' || endptr == str) lval = 0; } g_value_set_int (dest_value, lval); } /* string to double transform function */ static void value_transform_string_double (const GValue *src_value, GValue *dest_value) { const char *str; char *endptr; double dval = 0.0; str = g_value_get_string (src_value); if (str) { dval = strtod (str, &endptr); if (*endptr != '\0' || endptr == str) dval = 0; } g_value_set_double (dest_value, dval); } swami/src/libswami/SwamiControlMidi.h0000644000175000017500000000465711461334205020064 0ustar alessioalessio/* * SwamiControlMidi.h - Header for Swami MIDI control * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMI_CONTROL_MIDI_H__ #define __SWAMI_CONTROL_MIDI_H__ #include #include #include #include #include typedef struct _SwamiControlMidi SwamiControlMidi; typedef struct _SwamiControlMidiClass SwamiControlMidiClass; #define SWAMI_TYPE_CONTROL_MIDI (swami_control_midi_get_type ()) #define SWAMI_CONTROL_MIDI(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMI_TYPE_CONTROL_MIDI, \ SwamiControlMidi)) #define SWAMI_CONTROL_MIDI_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMI_TYPE_CONTROL_MIDI, \ SwamiControlMidiClass)) #define SWAMI_IS_CONTROL_MIDI(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMI_TYPE_CONTROL_MIDI)) #define SWAMI_IS_CONTROL_MIDI_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMI_TYPE_CONTROL_MIDI)) /* MIDI control object */ struct _SwamiControlMidi { SwamiControlFunc parent_instance; /* derived from SwamiControlFunc */ }; /* MIDI control class */ struct _SwamiControlMidiClass { SwamiControlFuncClass parent_class; }; GType swami_control_midi_get_type (void); SwamiControlMidi *swami_control_midi_new (void); void swami_control_midi_set_callback (SwamiControlMidi *midi, SwamiControlSetValueFunc callback, gpointer data); void swami_control_midi_send (SwamiControlMidi *midi, SwamiMidiEventType type, int channel, int param1, int param2); void swami_control_midi_transmit (SwamiControlMidi *midi, SwamiMidiEventType type, int channel, int param1, int param2); #endif swami/src/libswami/SwamiLog.c0000644000175000017500000000347611461334205016353 0ustar alessioalessio/* * SwamiLog.c - Message logging and debugging functions * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. * * To contact the author of this program: * Email: Josh Green * Swami homepage: http://swami.sourceforge.net */ #include #include #include GQuark swami_error_quark (void) { static GQuark q = 0; if (q == 0) q = g_quark_from_static_string ("libswami-error-quark"); return (q); } int _swami_ret_g_log (const gchar *log_domain, GLogLevelFlags log_level, const gchar *format, ...) { va_list args; va_start (args, format); g_logv (log_domain, log_level, format, args); va_end (args); return (TRUE); } void _swami_pretty_log_handler (GLogLevelFlags level, char *file, char *function, int line, char *format, ...) { va_list args; char *s, *s2; va_start (args, format); s = g_strdup_vprintf (format, args); va_end (args); s2 = g_strdup_printf ("file %s: line %d (%s): %s", file, line, function, s); g_free (s); g_log (NULL, level, "%s", s2); g_free (s2); } swami/src/libswami/SwamiMidiDevice.c0000644000175000017500000001053111461334205017622 0ustar alessioalessio/* * SwamiMidiDevice.c - MIDI device base class * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include "config.h" #include #include #include "SwamiMidiDevice.h" #include "SwamiLog.h" /* --- signals and properties --- */ enum { LAST_SIGNAL }; enum { PROP_0, }; /* --- private function prototypes --- */ static void swami_midi_device_class_init (SwamiMidiDeviceClass *klass); static void swami_midi_device_init (SwamiMidiDevice *device); /* --- private data --- */ // static guint midi_signals[LAST_SIGNAL] = { 0 }; /* --- functions --- */ GType swami_midi_device_get_type (void) { static GType item_type = 0; if (!item_type) { static const GTypeInfo item_info = { sizeof (SwamiMidiDeviceClass), NULL, NULL, (GClassInitFunc) swami_midi_device_class_init, NULL, NULL, sizeof (SwamiMidiDevice), 0, (GInstanceInitFunc) swami_midi_device_init, }; item_type = g_type_register_static (SWAMI_TYPE_LOCK, "SwamiMidiDevice", &item_info, G_TYPE_FLAG_ABSTRACT); } return (item_type); } static void swami_midi_device_class_init (SwamiMidiDeviceClass *klass) { } static void swami_midi_device_init (SwamiMidiDevice *midi) { midi->active = FALSE; } SwamiMidiDevice * swami_midi_device_new (void) { return SWAMI_MIDI_DEVICE (g_object_new (SWAMI_TYPE_MIDI_DEVICE, NULL)); } /** * swami_midi_device_open: * @device: Swami MIDI device * @err: Location to store error information or %NULL * * Open a MIDI device. * * Returns: %TRUE on success, %FALSE otherwise */ gboolean swami_midi_device_open (SwamiMidiDevice *device, GError **err) { SwamiMidiDeviceClass *oclass; int retval = TRUE; g_return_val_if_fail (SWAMI_IS_MIDI_DEVICE (device), FALSE); g_return_val_if_fail (!err || !*err, FALSE); oclass = SWAMI_MIDI_DEVICE_CLASS (G_OBJECT_GET_CLASS (device)); SWAMI_LOCK_WRITE (device); if (!device->active) { if (oclass->open) retval = (*oclass->open) (device, err); if (retval) device->active = TRUE; } SWAMI_UNLOCK_WRITE (device); return (retval); } /** * swami_midi_device_close: * @device: MIDI device object * * Close an active MIDI device. */ void swami_midi_device_close (SwamiMidiDevice *device) { SwamiMidiDeviceClass *oclass; g_return_if_fail (SWAMI_IS_MIDI_DEVICE (device)); oclass = SWAMI_MIDI_DEVICE_CLASS (G_OBJECT_GET_CLASS (device)); SWAMI_LOCK_WRITE (device); if (device->active) { if (oclass->close) (*oclass->close) (device); device->active = FALSE; } SWAMI_UNLOCK_WRITE (device); } /** * swami_midi_device_get_control: * @device: MIDI device object * @index: Index of control * * Get a MIDI control object from a MIDI device. A MIDI device may have * multiple MIDI control interface channels (if supporting more than 16 * MIDI channels for example), so index can be used to iterate over them. * The MIDI device does NOT need to be active when calling this function. * * Returns: The MIDI control for the given @index, or %NULL if no control * with that index. The reference count of the returned control has been * incremented and is owned by the caller, remember to unref it when finished. */ SwamiControl * swami_midi_device_get_control (SwamiMidiDevice *device, int index) { SwamiMidiDeviceClass *oclass; SwamiControl *control = NULL; g_return_val_if_fail (SWAMI_IS_MIDI_DEVICE (device), NULL); oclass = SWAMI_MIDI_DEVICE_CLASS (G_OBJECT_GET_CLASS (device)); if (oclass->get_control) { control = (*oclass->get_control)(device, index); if (control) g_object_ref (control); /* ++ ref for caller */ } return (control); } swami/src/libswami/SwamiObject.h0000644000175000017500000000665111461334205017043 0ustar alessioalessio/* * SwamiObject.h - Child object properties and type rank systems * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMI_OBJECT_H__ #define __SWAMI_OBJECT_H__ #include #include #include #include typedef struct _SwamiObjectPropBag SwamiObjectPropBag; /* structure used for Swami object properties */ struct _SwamiObjectPropBag { SwamiRoot *root; /* parent swami root object */ char *name; /* Swami object property name */ guint8 rank; /* Swami object rank property */ guint8 flags; /* Swami object flags property */ guint16 reserved; }; /* some pre-defined ranks (valid range is 1-100) */ typedef enum { SWAMI_RANK_INVALID = 0, SWAMI_RANK_LOWEST = 10, SWAMI_RANK_LOW = 25, SWAMI_RANK_NORMAL = 50, /* NORMAL default value */ SWAMI_RANK_DEFAULT = 60, /* value to elect default objects */ SWAMI_RANK_HIGH = 75, SWAMI_RANK_HIGHEST = 90 } SwamiRank; typedef enum /*< flags >*/ { SWAMI_OBJECT_SAVE = 1 << 0, /* flags if object state should be saved */ SWAMI_OBJECT_USER = 1 << 1 /* user visable object (in tree view, etc) */ } SwamiObjectFlags; extern GQuark swami_object_propbag_quark; void swami_type_set_rank (GType type, GType group_type, int rank); int swami_type_get_rank (GType type, GType group_type); GType *swami_type_get_children (GType group_type); GType swami_type_get_default (GType group_type); void swami_object_set_default (GObject *object, GType type); GObject *swami_object_get_by_name (GObject *object, const char *name); IpatchList *swami_object_find_by_type (GObject *object, const char *type_name); GObject *swami_object_get_by_type (GObject *object, const char *type_name); void swami_object_get_valist (GObject *object, const char *first_property_name, va_list var_args); void swami_object_get_property (GObject *object, const char *property_name, GValue *value); void swami_object_get (gpointer object, const char *first_prop_name, ...); void swami_object_set_valist (GObject *object, const char *first_property_name, va_list var_args); void swami_object_set_property (GObject *object, const char *property_name, const GValue *value); void swami_object_set (gpointer object, const char *first_prop_name, ...); GParamSpec *swami_find_object_property (const char *property_name); GParamSpec **swami_list_object_properties (guint *n_properties); guint swami_object_get_flags (GObject *object); void swami_object_set_flags (GObject *object, guint flags); void swami_object_clear_flags (GObject *object, guint flags); void swami_object_set_origin (GObject *obj, GObject *origin); GObject *swami_object_get_origin (GObject *obj); #endif swami/src/libswami/version.h.in0000644000175000017500000000252707600251444016727 0ustar alessioalessio/* * version.h - Swami version information * * Swami * Copyright (C) 1999-2002 Josh Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. * * To contact the author of this program: * Email: Josh Green * Swami homepage: http://swami.sourceforge.net */ #ifndef __SWAMI_VERSION_H__ #define __SWAMI_VERSION_H__ #define SWAMI_VERSION @SWAMI_VERSION@ #define SWAMI_VERSION_MAJOR @SWAMI_VERSION_MAJOR@ #define SWAMI_VERSION_MINOR @SWAMI_VERSION_MINOR@ #define SWAMI_VERSION_MICRO @SWAMI_VERSION_MICRO@ void swami_version (guint *major, guint *minor, guint *micro); #endif /* __SWAMI_VERSION_H__ */ swami/src/libswami/marshals.list0000644000175000017500000000234507711255141017172 0ustar alessioalessio# see glib-genmarshal(1) for a detailed description of the file format, # possible parameter types are: # VOID indicates no return type, or no extra # parameters. if VOID is used as the parameter # list, no additional parameters may be present. # BOOLEAN for boolean types (gboolean) # CHAR for signed char types (gchar) # UCHAR for unsigned char types (guchar) # INT for signed integer types (gint) # UINT for unsigned integer types (guint) # LONG for signed long integer types (glong) # ULONG for unsigned long integer types (gulong) # ENUM for enumeration types (gint) # FLAGS for flag enumeration types (guint) # FLOAT for single-precision float types (gfloat) # DOUBLE for double-precision float types (gdouble) # STRING for string types (gchar*) # PARAM for GParamSpec or derived types (GParamSpec*) # BOXED for boxed (anonymous but reference counted) types (GBoxed*) # POINTER for anonymous pointer types (gpointer) # OBJECT for GObject or derived types (GObject*) # NONE deprecated alias for VOID # BOOL deprecated alias for BOOLEAN VOID:OBJECT,UINT swami/src/libswami/SwamiContainer.c0000644000175000017500000000550011461334205017542 0ustar alessioalessio/* * SwamiContainer.c - Root container for instrument patches * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include "SwamiContainer.h" static void swami_container_class_init (SwamiContainerClass *klass); static const GType *swami_container_child_types (void); static gboolean swami_container_init_iter (IpatchContainer *container, IpatchIter *iter, GType type); static GType container_child_types[2] = { 0 }; GType swami_container_get_type (void) { static GType item_type = 0; if (!item_type) { static const GTypeInfo item_info = { sizeof (SwamiContainerClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) swami_container_class_init, NULL, NULL, sizeof (SwamiContainer), 0, (GInstanceInitFunc) NULL, }; item_type = g_type_register_static (IPATCH_TYPE_CONTAINER, "SwamiContainer", &item_info, 0); } return (item_type); } static void swami_container_class_init (SwamiContainerClass *klass) { IpatchContainerClass *container_class = IPATCH_CONTAINER_CLASS (klass); container_class->child_types = swami_container_child_types; container_class->init_iter = swami_container_init_iter; container_child_types[0] = IPATCH_TYPE_BASE; } static const GType * swami_container_child_types (void) { return (container_child_types); } /* container is locked by caller */ static gboolean swami_container_init_iter (IpatchContainer *container, IpatchIter *iter, GType type) { SwamiContainer *scontainer = SWAMI_CONTAINER (container); if (type != IPATCH_TYPE_BASE) { g_critical ("Invalid child type '%s' for parent of type '%s'", g_type_name (type), g_type_name (G_OBJECT_TYPE (container))); return (FALSE); } ipatch_iter_GSList_init (iter, &scontainer->patch_list); return (TRUE); } /** * swami_container_new: * * Create a new Swami container object which is a toplevel container for * instrument patches. * * Returns: New Swami container object */ SwamiContainer * swami_container_new (void) { return SWAMI_CONTAINER (g_object_new (SWAMI_TYPE_CONTAINER, NULL)); } swami/src/libswami/SwamiLoopResults.c0000644000175000017500000000542711461334205020123 0ustar alessioalessio/* * SwamiLoopResults.c - Sample loop finder results object * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * Thanks to Luis Garrido for the loop finder algorithm code and his * interest in creating this feature for Swami. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include "SwamiLoopResults.h" static void swami_loop_results_init (SwamiLoopResults *results); static void swami_loop_results_finalize (GObject *object); G_DEFINE_TYPE (SwamiLoopResults, swami_loop_results, G_TYPE_OBJECT); static void swami_loop_results_class_init (SwamiLoopResultsClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); obj_class->finalize = swami_loop_results_finalize; } static void swami_loop_results_init (SwamiLoopResults *results) { } static void swami_loop_results_finalize (GObject *object) { SwamiLoopResults *results = SWAMI_LOOP_RESULTS (object); g_free (results->values); if (G_OBJECT_CLASS (swami_loop_results_parent_class)->finalize) G_OBJECT_CLASS (swami_loop_results_parent_class)->finalize (object); } /** * swami_loop_results_new: * * Create a new sample loop finder results object. Used for storing results * of a #SwamiLoopFinder find operation. * * Returns: New object of type #SwamiLoopResults */ SwamiLoopResults * swami_loop_results_new (void) { return (SWAMI_LOOP_RESULTS (g_object_new (SWAMI_TYPE_LOOP_RESULTS, NULL))); } /** * swami_loop_results_get_values: * @results: Loop finder results object * @length: Output: location to store length of returned values array * * Get the loop match values array from a loop results object. * * Returns: Array of loop results or %NULL if none. The array is internal, * should not be modified or freed and should be used only up to the point * where @results is destroyed (no more references held). */ SwamiLoopMatch * swami_loop_results_get_values (SwamiLoopResults *results, guint *count) { g_return_val_if_fail (SWAMI_IS_LOOP_RESULTS (results), NULL); g_return_val_if_fail (count != NULL, NULL); *count = results->count; return (results->values); } swami/src/libswami/SwamiControlHub.c0000644000175000017500000000541611461334205017705 0ustar alessioalessio/* * SwamiControlHub.c - Control hub object * Re-transmits any events it receives * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include "SwamiControlHub.h" #include "SwamiControl.h" #include "SwamiLog.h" #include "swami_priv.h" #include "util.h" static void swami_control_hub_class_init (SwamiControlHubClass *klass); static void control_hub_set_value_method (SwamiControl *control, SwamiControlEvent *event, const GValue *value); static void swami_control_hub_init (SwamiControlHub *ctrlhub); GType swami_control_hub_get_type (void) { static GType otype = 0; if (!otype) { static const GTypeInfo type_info = { sizeof (SwamiControlHubClass), NULL, NULL, (GClassInitFunc) swami_control_hub_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SwamiControlHub), 0, (GInstanceInitFunc) swami_control_hub_init }; otype = g_type_register_static (SWAMI_TYPE_CONTROL, "SwamiControlHub", &type_info, 0); } return (otype); } static void swami_control_hub_class_init (SwamiControlHubClass *klass) { SwamiControlClass *control_class = SWAMI_CONTROL_CLASS (klass); control_class->set_value = control_hub_set_value_method; } static void control_hub_set_value_method (SwamiControl *control, SwamiControlEvent *event, const GValue *value) { /* re-transmit the event (without loop check) */ swami_control_transmit_event_loop (control, event); } static void swami_control_hub_init (SwamiControlHub *ctrlhub) { /* hubs send and receive */ swami_control_set_flags (SWAMI_CONTROL (ctrlhub), SWAMI_CONTROL_SENDRECV); } /** * swami_control_hub_new: * * Create a new control hub. Control hubes re-transmit any events they * receive and are useful for connecting many controls together. * * Returns: New control hub with a refcount of 1 which the caller owns. */ SwamiControlHub * swami_control_hub_new (void) { return (SWAMI_CONTROL_HUB (g_object_new (SWAMI_TYPE_CONTROL_HUB, NULL))); } swami/src/libswami/SwamiParam.c0000644000175000017500000003641711461334205016673 0ustar alessioalessio/* * SwamiParam.c - GParamSpec related functions * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include #include "SwamiParam.h" /** * swami_param_get_limits: * @pspec: GParamSpec to get limits of * @min: Output: Minimum value of parameter specification * @max: Output: Maximum value of parameter specification * @def: Output: Default value of parameter specification * @integer: Output: %TRUE if integer parameter spec, %FALSE if floating point * * Get limits of a numeric parameter specification. * * Returns: %TRUE if @pspec is numeric, %FALSE otherwise (in which case * output variables are undefined) */ gboolean swami_param_get_limits (GParamSpec *pspec, gdouble *min, gdouble *max, gdouble *def, gboolean *integer) { GType type; gdouble rmin, rmax, rdef; gboolean isint; g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE); type = G_PARAM_SPEC_TYPE (pspec); if (type == G_TYPE_PARAM_BOOLEAN) { GParamSpecBoolean *sp = (GParamSpecBoolean *)pspec; rmin = 0.0; rmax = 1.0; rdef = sp->default_value; isint = TRUE; } else if (type == G_TYPE_PARAM_CHAR) { GParamSpecChar *sp = (GParamSpecChar *)pspec; rmin = sp->minimum; rmax = sp->maximum; rdef = sp->default_value; isint = TRUE; } else if (type == G_TYPE_PARAM_UCHAR) { GParamSpecUChar *sp = (GParamSpecUChar *)pspec; rmin = sp->minimum; rmax = sp->maximum; rdef = sp->default_value; isint = TRUE; } else if (type == G_TYPE_PARAM_INT) { GParamSpecInt *sp = (GParamSpecInt *)pspec; rmin = sp->minimum; rmax = sp->maximum; rdef = sp->default_value; isint = TRUE; } else if (type == G_TYPE_PARAM_UINT) { GParamSpecUInt *sp = (GParamSpecUInt *)pspec; rmin = sp->minimum; rmax = sp->maximum; rdef = sp->default_value; isint = TRUE; } else if (type == G_TYPE_PARAM_LONG) { GParamSpecLong *sp = (GParamSpecLong *)pspec; rmin = sp->minimum; rmax = sp->maximum; rdef = sp->default_value; isint = TRUE; } else if (type == G_TYPE_PARAM_ULONG) { GParamSpecULong *sp = (GParamSpecULong *)pspec; rmin = sp->minimum; rmax = sp->maximum; rdef = sp->default_value; isint = TRUE; } else if (type == G_TYPE_PARAM_INT64) { GParamSpecInt64 *sp = (GParamSpecInt64 *)pspec; rmin = sp->minimum; rmax = sp->maximum; rdef = sp->default_value; isint = TRUE; } else if (type == G_TYPE_PARAM_UINT64) { GParamSpecUInt64 *sp = (GParamSpecUInt64 *)pspec; rmin = sp->minimum; rmax = sp->maximum; rdef = sp->default_value; isint = TRUE; } else if (type == G_TYPE_PARAM_FLOAT) { GParamSpecFloat *sp = (GParamSpecFloat *)pspec; rmin = sp->minimum; rmax = sp->maximum; rdef = sp->default_value; isint = FALSE; } else if (type == G_TYPE_PARAM_DOUBLE) { GParamSpecDouble *sp = (GParamSpecDouble *)pspec; rmin = sp->minimum; rmax = sp->maximum; rdef = sp->default_value; isint = FALSE; } else return (FALSE); if (min) *min = rmin; if (max) *max = rmax; if (def) *def = rdef; if (integer) *integer = isint; return (TRUE); } /** * swami_param_set_limits: * @pspec: GParamSpec to set limits of * @min: Minimum value of parameter specification * @max: Maximum value of parameter specification * @def: Default value of parameter specification * * Set limits of a numeric parameter specification. * * Returns: %TRUE if @pspec is numeric, %FALSE otherwise (in which case * @pspec is unchanged) */ gboolean swami_param_set_limits (GParamSpec *pspec, gdouble min, gdouble max, gdouble def) { GType type; g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE); type = G_PARAM_SPEC_TYPE (pspec); if (type == G_TYPE_PARAM_BOOLEAN) { GParamSpecBoolean *sp = (GParamSpecBoolean *)pspec; sp->default_value = (def != 0.0); } else if (type == G_TYPE_PARAM_CHAR) { GParamSpecChar *sp = (GParamSpecChar *)pspec; sp->minimum = min; sp->maximum = max; sp->default_value = def; } else if (type == G_TYPE_PARAM_UCHAR) { GParamSpecUChar *sp = (GParamSpecUChar *)pspec; sp->minimum = min; sp->maximum = max; sp->default_value = def; } else if (type == G_TYPE_PARAM_INT) { GParamSpecInt *sp = (GParamSpecInt *)pspec; sp->minimum = min; sp->maximum = max; sp->default_value = def; } else if (type == G_TYPE_PARAM_UINT) { GParamSpecUInt *sp = (GParamSpecUInt *)pspec; sp->minimum = min; sp->maximum = max; sp->default_value = def; } else if (type == G_TYPE_PARAM_LONG) { GParamSpecLong *sp = (GParamSpecLong *)pspec; sp->minimum = min; sp->maximum = max; sp->default_value = def; } else if (type == G_TYPE_PARAM_ULONG) { GParamSpecULong *sp = (GParamSpecULong *)pspec; sp->minimum = min; sp->maximum = max; sp->default_value = def; } else if (type == G_TYPE_PARAM_INT64) { GParamSpecInt64 *sp = (GParamSpecInt64 *)pspec; sp->minimum = min; sp->maximum = max; sp->default_value = def; } else if (type == G_TYPE_PARAM_UINT64) { GParamSpecUInt64 *sp = (GParamSpecUInt64 *)pspec; sp->minimum = min; sp->maximum = max; sp->default_value = def; } else if (type == G_TYPE_PARAM_FLOAT) { GParamSpecFloat *sp = (GParamSpecFloat *)pspec; sp->minimum = min; sp->maximum = max; sp->default_value = def; } else if (type == G_TYPE_PARAM_DOUBLE) { GParamSpecDouble *sp = (GParamSpecDouble *)pspec; sp->minimum = min; sp->maximum = max; sp->default_value = def; } else return (FALSE); return (TRUE); } /** * swami_param_type_has_limits: * @param_type: #GParamSpec type * * Check if a given #GParamSpec type can be used with swami_param_get_limits() * and swami_param_set_limits(). * * Returns: %TRUE if can get/set limits, %FALSE otherwise */ gboolean swami_param_type_has_limits (GType param_type) { return (param_type == G_TYPE_PARAM_BOOLEAN || param_type == G_TYPE_PARAM_CHAR || param_type == G_TYPE_PARAM_UCHAR || param_type == G_TYPE_PARAM_INT || param_type == G_TYPE_PARAM_UINT || param_type == G_TYPE_PARAM_LONG || param_type == G_TYPE_PARAM_ULONG || param_type == G_TYPE_PARAM_INT64 || param_type == G_TYPE_PARAM_UINT64 || param_type == G_TYPE_PARAM_FLOAT || param_type == G_TYPE_PARAM_DOUBLE); } /** * swami_param_convert: * @src: Source param specification to get limits from * @dest: Destination param specification to set limits of * * Convert parameter limits between two numeric parameter specifications, also * copies the "unit-type" and "float-digit" parameter properties. Sets * "float-digits" to 0 on the @dest parameter spec if the source is an integer * type. * * Returns: %TRUE if both parameter specs are numeric, %FALSE otherwise * (in which case @dest will be unchanged). */ gboolean swami_param_convert (GParamSpec *src, GParamSpec *dest) { gdouble min, max, def; GValue value = { 0 }; gboolean isint; g_return_val_if_fail (G_IS_PARAM_SPEC (dest), FALSE); g_return_val_if_fail (G_IS_PARAM_SPEC (src), FALSE); if (!swami_param_get_limits (src, &min, &max, &def, &isint)) return (FALSE); if (!swami_param_set_limits (dest, min, max, def)) return (FALSE); g_value_init (&value, G_TYPE_UINT); if (ipatch_param_get_property (src, "unit-type", &value)) ipatch_param_set_property (dest, "unit-type", &value); if (isint) g_value_set_uint (&value, 0); if (isint || ipatch_param_get_property (src, "float-digits", &value)) ipatch_param_set_property (dest, "float-digits", &value); return (TRUE); } /** * swami_param_convert_new: * @pspec: Source parameter spec to convert * @value_type: Value type of new parameter spec * * Create a new parameter spec using values of @value_type and convert * @pspec to the new parameter spec. * * Returns: New parameter spec that uses @value_type or %NULL on error * (unable to convert @pspec to @value_type) */ GParamSpec * swami_param_convert_new (GParamSpec *pspec, GType value_type) { GParamSpec *newspec; GType newspec_type; g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL); newspec_type = swami_param_type_from_value_type (value_type); g_return_val_if_fail (newspec_type != 0, NULL); newspec = g_param_spec_internal (newspec_type, pspec->name, pspec->_nick, pspec->_blurb, pspec->flags); if (!swami_param_convert (pspec, newspec)) { g_param_spec_ref (newspec); g_param_spec_sink (newspec); g_param_spec_unref (newspec); return (NULL); } return (newspec); } /** * swami_param_type_transformable: * @src_type: Source #GParamSpec type. * @dest_type: Destination #GParamSpec type. * * Check if a source #GParamSpec type is transformable to a destination type. * * Returns: %TRUE on success, %FALSE otherwise */ gboolean swami_param_type_transformable (GType src_type, GType dest_type) { return (swami_param_type_has_limits (src_type) && swami_param_type_has_limits (dest_type)); } /** * swami_param_type_transformable_value: * @src_type: Source #GValue type. * @dest_type: Destination #GValue type. * * Check if a source #GParamSpec type is transformable to a destination type * by corresponding #GValue types. * * Returns: %TRUE on success, %FALSE otherwise */ gboolean swami_param_type_transformable_value (GType src_valtype, GType dest_valtype) { GType src_type, dest_type; src_type = swami_param_type_from_value_type (src_valtype); dest_type = swami_param_type_from_value_type (dest_valtype); return (swami_param_type_has_limits (src_type) && swami_param_type_has_limits (dest_type)); } /** * swami_param_transform: * @src: Source param specification to get limits from * @dest: Destination param specification to set limits of * @trans: Transform function * @user_data: User defined data passed to transform function * * Convert parameter limits between two numeric parameter specifications using * a custom transform function. The @trans parameter specifies the transform * function which is called for the min, max and default values of the @src * parameter spec, which are then assigned to @dest. The source and destination * GValue parameters to the transform function are of #G_TYPE_DOUBLE. * * Returns: %TRUE if both parameter specs are numeric, %FALSE otherwise * (in which case @dest will be unchanged). */ gboolean swami_param_transform (GParamSpec *src, GParamSpec *dest, SwamiValueTransform trans, gpointer user_data) { gdouble min, max, def; gdouble tmin, tmax, tdef; GValue srcval = { 0 }, destval = { 0 }; g_return_val_if_fail (G_IS_PARAM_SPEC (src), FALSE); g_return_val_if_fail (G_IS_PARAM_SPEC (dest), FALSE); g_return_val_if_fail (trans != NULL, FALSE); if (!swami_param_get_limits (src, &min, &max, &def, NULL)) return (FALSE); g_value_init (&srcval, G_TYPE_DOUBLE); g_value_init (&destval, G_TYPE_DOUBLE); g_value_set_double (&srcval, min); trans (&srcval, &destval, user_data); tmin = g_value_get_double (&destval); g_value_reset (&srcval); g_value_reset (&destval); g_value_set_double (&srcval, max); trans (&srcval, &destval, user_data); tmax = g_value_get_double (&destval); g_value_reset (&srcval); g_value_reset (&destval); g_value_set_double (&srcval, def); trans (&srcval, &destval, user_data); tdef = g_value_get_double (&destval); g_value_unset (&srcval); g_value_unset (&destval); if (!swami_param_set_limits (dest, tmin, tmax, tdef)) return (FALSE); return (TRUE); } /** * swami_param_transform_new: * @pspec: Source parameter spec to convert * @value_type: Value type of new parameter spec * @trans: Transform function * @user_data: User defined data passed to transform function * * Create a new parameter spec using values of @value_type and transform * @pspec to the new parameter spec using a custom transform function. * See swami_param_transform() for more details. * * Returns: New parameter spec that uses @value_type or %NULL on error * (error message is then printed) */ GParamSpec * swami_param_transform_new (GParamSpec *pspec, GType value_type, SwamiValueTransform trans, gpointer user_data) { GParamSpec *newspec; GType newspec_type; g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL); g_return_val_if_fail (trans != NULL, NULL); newspec_type = swami_param_type_from_value_type (value_type); g_return_val_if_fail (newspec_type != 0, NULL); newspec = g_param_spec_internal (newspec_type, pspec->name, pspec->_nick, pspec->_blurb, pspec->flags); if (!swami_param_transform (pspec, newspec, trans, user_data)) { g_critical ("%s: Failed to transform param spec of type '%s' to '%s'", G_STRLOC, G_PARAM_SPEC_TYPE_NAME (pspec), G_PARAM_SPEC_TYPE_NAME (newspec)); g_param_spec_ref (newspec); g_param_spec_sink (newspec); g_param_spec_unref (newspec); return (FALSE); } return (newspec); } /** * swami_param_type_from_value_type: * @value_type: A value type to get the parameter spec type that contains it. * * Get a parameter spec type for a given value type. * * Returns: Parameter spec type or 0 if no param spec type for @value_type. */ GType swami_param_type_from_value_type (GType value_type) { value_type = G_TYPE_FUNDAMENTAL (value_type); switch (value_type) { case G_TYPE_BOOLEAN: return G_TYPE_PARAM_BOOLEAN; case G_TYPE_CHAR: return G_TYPE_PARAM_CHAR; case G_TYPE_UCHAR: return G_TYPE_PARAM_UCHAR; case G_TYPE_INT: return G_TYPE_PARAM_INT; case G_TYPE_UINT: return G_TYPE_PARAM_UINT; case G_TYPE_LONG: return G_TYPE_PARAM_LONG; case G_TYPE_ULONG: return G_TYPE_PARAM_ULONG; case G_TYPE_INT64: return G_TYPE_PARAM_INT64; case G_TYPE_UINT64: return G_TYPE_PARAM_UINT64; case G_TYPE_ENUM: return G_TYPE_PARAM_ENUM; case G_TYPE_FLAGS: return G_TYPE_PARAM_FLAGS; case G_TYPE_FLOAT: return G_TYPE_PARAM_FLOAT; case G_TYPE_DOUBLE: return G_TYPE_PARAM_DOUBLE; case G_TYPE_STRING: return G_TYPE_PARAM_STRING; case G_TYPE_POINTER: return G_TYPE_PARAM_POINTER; case G_TYPE_BOXED: return G_TYPE_PARAM_BOXED; case G_TYPE_OBJECT: return G_TYPE_PARAM_OBJECT; default: return 0; } } swami/src/libswami/SwamiPropTree.c0000644000175000017500000006535211704446464017406 0ustar alessioalessio/* * SwamiPropTree.c - Swami property tree object * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include "SwamiPropTree.h" #include "SwamiControlProp.h" #include "SwamiLog.h" #include "swami_priv.h" /* a cached active property value */ typedef struct { GParamSpec *pspec; /* parameter spec for this cached property */ SwamiControl *prop_ctrl; /* object property control for this cache */ SwamiPropTreeValue *value; /* tree value connected to prop_ctrl */ SwamiPropTreeNode *value_node; /* node containing @value */ } CacheValue; /* unlocked chunk alloc/free macros (requires external locking) */ #define swami_prop_tree_new_node_L() \ g_slice_new (SwamiPropTreeNode) #define swami_prop_tree_free_node_L(node) \ g_slice_free (SwamiPropTreeNode, node) #define swami_prop_tree_new_value_L() \ g_slice_new (SwamiPropTreeValue) #define swami_prop_tree_free_value_L(value) \ g_slice_free (SwamiPropTreeValue, value) #define TREE_CACHE_PREALLOC 64 #define swami_prop_tree_new_cache_L() \ g_slice_new (CacheValue) #define swami_prop_tree_free_cache_L(cache) \ g_slice_free (CacheValue, cache) static void swami_prop_tree_class_init (SwamiPropTreeClass *klass); static void swami_prop_tree_init (SwamiPropTree *proptree); static void swami_prop_tree_finalize (GObject *object); static void swami_prop_tree_object_weak_notify (gpointer user_data, GObject *object); static inline void swami_prop_tree_node_reset_L (SwamiPropTree *proptree, SwamiPropTreeNode *treenode); static inline void swami_prop_tree_node_clear_cache_L (SwamiPropTreeNode *treenode); static void recursive_remove_nodes (GNode *node, SwamiPropTree *proptree); static void resolve_object_props_L (SwamiPropTree *proptree, GNode *object_node, GList *speclist); static GList *object_spec_list (GObject *object); static void refresh_value_nodes_L (GNode *node, SwamiPropTreeValue *treeval); static void refresh_value_nodes_list_L (GNode *node, GSList *treevals); static inline void refresh_cache_value_L (GNode *node, CacheValue *cache); static GObjectClass *parent_class = NULL; GType swami_prop_tree_get_type (void) { static GType otype = 0; if (!otype) { static const GTypeInfo type_info = { sizeof (SwamiPropTreeClass), NULL, NULL, (GClassInitFunc) swami_prop_tree_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SwamiPropTree), 0, (GInstanceInitFunc) swami_prop_tree_init }; otype = g_type_register_static (SWAMI_TYPE_LOCK, "SwamiPropTree", &type_info, 0); } return (otype); } static void swami_prop_tree_class_init (SwamiPropTreeClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); parent_class = g_type_class_peek_parent (klass); obj_class->finalize = swami_prop_tree_finalize; } static void swami_prop_tree_init (SwamiPropTree *proptree) { proptree->tree = NULL; proptree->object_hash = g_hash_table_new (NULL, NULL); } static void swami_prop_tree_finalize (GObject *object) { SwamiPropTree *proptree = SWAMI_PROP_TREE (object); SWAMI_LOCK_WRITE (proptree); recursive_remove_nodes (proptree->tree, proptree); /* recursive remove */ SWAMI_UNLOCK_WRITE (proptree); g_hash_table_destroy (proptree->object_hash); parent_class->finalize (object); } /** * swami_prop_tree_new: * * Create a new property tree object. * * Returns: New property tree object with a refcount of 1. */ SwamiPropTree * swami_prop_tree_new (void) { return (SWAMI_PROP_TREE (g_object_new (SWAMI_TYPE_PROP_TREE, NULL))); } /** * swami_prop_tree_set_root: * @proptree: Property tree object * @root: Object to make the root object of the tree * * Set the root object of a property tree. Should only be set once. */ void swami_prop_tree_set_root (SwamiPropTree *proptree, GObject *root) { SwamiPropTreeNode *node; g_return_if_fail (SWAMI_IS_PROP_TREE (proptree)); g_return_if_fail (G_IS_OBJECT (root)); SWAMI_LOCK_WRITE (proptree); if (swami_log_if_fail (proptree->tree == NULL)) { SWAMI_UNLOCK_WRITE (proptree); return; } node = swami_prop_tree_new_node_L (); node->object = root; node->values = NULL; node->cache = NULL; proptree->tree = g_node_new (node); /* add to object => GNode hash */ g_hash_table_insert (proptree->object_hash, root, proptree->tree); /* weak ref to passively catch objects demise */ g_object_weak_ref (root, swami_prop_tree_object_weak_notify, proptree); SWAMI_UNLOCK_WRITE (proptree); } /** * swami_prop_tree_prepend: * @proptree: Property tree object * @parent: Object in @proptree to parent to * @obj: Object to prepend to @proptree * * Prepends an object to a property tree. */ void swami_prop_tree_prepend (SwamiPropTree *proptree, GObject *parent, GObject *obj) { SwamiPropTreeNode *treenode; GNode *parent_node, *newnode; GList *speclist; g_return_if_fail (SWAMI_IS_PROP_TREE (proptree)); g_return_if_fail (G_IS_OBJECT (parent)); g_return_if_fail (G_IS_OBJECT (obj)); speclist = object_spec_list (obj); SWAMI_LOCK_WRITE (proptree); parent_node = g_hash_table_lookup (proptree->object_hash, parent); if (swami_log_if_fail (parent_node != NULL)) { SWAMI_UNLOCK_WRITE (proptree); return; } treenode = swami_prop_tree_new_node_L (); treenode->object = obj; treenode->values = NULL; treenode->cache = NULL; newnode = g_node_prepend_data (parent_node, treenode); g_hash_table_insert (proptree->object_hash, obj, newnode); /* weak ref to passively catch objects demise */ g_object_weak_ref (obj, swami_prop_tree_object_weak_notify, proptree); /* resolve properties if any (speclist is freed) */ if (speclist) resolve_object_props_L (proptree, newnode, speclist); SWAMI_UNLOCK_WRITE (proptree); } /** * swami_prop_tree_insert_before: * @proptree: Property tree object * @parent: Object in @proptree to parent to * @sibling: Object in @proptree to insert before or %NULL to append * @obj: Object to prepend to @proptree * * Inserts an object to a property tree before @sibling and parented to * @parent. */ void swami_prop_tree_insert_before (SwamiPropTree *proptree, GObject *parent, GObject *sibling, GObject *obj) { SwamiPropTreeNode *treenode; GNode *parent_node, *sibling_node = NULL, *newnode; GList *speclist; g_return_if_fail (SWAMI_IS_PROP_TREE (proptree)); g_return_if_fail (G_IS_OBJECT (parent)); g_return_if_fail (!sibling || G_IS_OBJECT (sibling)); g_return_if_fail (G_IS_OBJECT (obj)); speclist = object_spec_list (obj); SWAMI_LOCK_WRITE (proptree); parent_node = g_hash_table_lookup (proptree->object_hash, parent); if (swami_log_if_fail (parent_node != NULL)) { SWAMI_UNLOCK_WRITE (proptree); return; } if (sibling) { sibling_node = g_hash_table_lookup (proptree->object_hash, sibling); if (swami_log_if_fail (sibling_node != NULL)) { SWAMI_UNLOCK_WRITE (proptree); return; } } treenode = swami_prop_tree_new_node_L (); treenode->object = obj; treenode->values = NULL; treenode->cache = NULL; newnode = g_node_insert_data_before (parent_node, sibling_node, treenode); g_hash_table_insert (proptree->object_hash, obj, newnode); /* weak ref to passively catch objects demise */ g_object_weak_ref (obj, swami_prop_tree_object_weak_notify, proptree); /* resolve properties if any (speclist is freed) */ if (speclist) resolve_object_props_L (proptree, newnode, speclist); SWAMI_UNLOCK_WRITE (proptree); } /** * swami_prop_tree_remove: * @proptree: Property tree object * @obj: Object in @proptree to remove * * Removes an @obj, and all values bound to it, from a property tree. * All child nodes are moved up to the next parent node. */ void swami_prop_tree_remove (SwamiPropTree *proptree, GObject *obj) { SwamiPropTreeNode *treenode; GNode *obj_node, *newparent, *n, *temp; g_return_if_fail (SWAMI_IS_PROP_TREE (proptree)); g_return_if_fail (G_IS_OBJECT (obj)); SWAMI_LOCK_WRITE (proptree); obj_node = g_hash_table_lookup (proptree->object_hash, obj); if (swami_log_if_fail (obj_node != NULL)) { SWAMI_UNLOCK_WRITE (proptree); return; } newparent = obj_node->parent; if (swami_log_if_fail (newparent != NULL)) { SWAMI_UNLOCK_WRITE (proptree); return; } treenode = (SwamiPropTreeNode *)(obj_node->data); g_node_unlink (obj_node); /* unlink the GNode */ n = g_node_last_child (obj_node); while (n) /* move children of removed node to parent of it and refresh */ { temp = n; n = n->prev; g_node_prepend (newparent, temp); /* recursive refresh */ if (treenode->values) refresh_value_nodes_list_L (n, treenode->values); } obj_node->children = NULL; g_node_destroy (obj_node); /* destroy the GNode */ /* reset and free the tree node */ swami_prop_tree_node_reset_L (proptree, treenode); swami_prop_tree_free_node_L (treenode); SWAMI_UNLOCK_WRITE (proptree); } /** * swami_prop_tree_remove_recursive: * @proptree: Property tree object * @obj: Object in @proptree to recursively remove * * Recursively removes an @object, and all values bound to it, from a property * tree. */ void swami_prop_tree_remove_recursive (SwamiPropTree *proptree, GObject *obj) { GNode *obj_node; g_return_if_fail (SWAMI_IS_PROP_TREE (proptree)); g_return_if_fail (G_IS_OBJECT (obj)); SWAMI_LOCK_WRITE (proptree); obj_node = g_hash_table_lookup (proptree->object_hash, obj); if (swami_log_if_fail (obj_node != NULL)) { SWAMI_UNLOCK_WRITE (proptree); return; } recursive_remove_nodes (obj_node, proptree); /* recursive remove */ SWAMI_UNLOCK_WRITE (proptree); } /* called when an object in the tree is destroyed */ static void swami_prop_tree_object_weak_notify (gpointer user_data, GObject *object) { SwamiPropTree *proptree = SWAMI_PROP_TREE (user_data); SWAMI_LOCK_WRITE (proptree); g_hash_table_remove (proptree->object_hash, object); SWAMI_UNLOCK_WRITE (proptree); } /* reset a SwamiPropTreeNode (remove all of its innards) */ static inline void swami_prop_tree_node_reset_L (SwamiPropTree *proptree, SwamiPropTreeNode *treenode) { GSList *p; if (treenode->object) /* clear object->treenode hash entry */ { g_object_weak_unref (treenode->object, /* -- remove the weak ref */ swami_prop_tree_object_weak_notify, proptree); g_hash_table_remove (proptree->object_hash, treenode->object); } p = treenode->values; while (p) /* destroy values */ { swami_prop_tree_free_value_L (p->data); p = g_slist_delete_link (p, p); } swami_prop_tree_node_clear_cache_L (treenode); } /* clear cache of a property tree node */ static inline void swami_prop_tree_node_clear_cache_L (SwamiPropTreeNode *treenode) { CacheValue *cache; GSList *p; p = treenode->cache; while (p) /* destroy cache */ { cache = (CacheValue *)(p->data); if (cache->prop_ctrl) /* destroy property control */ { swami_control_disconnect_all ((SwamiControl *)(cache->prop_ctrl)); g_object_unref (cache->prop_ctrl); /* -- unref from cache */ } swami_prop_tree_free_cache_L (p->data); /* free cache value */ p = g_slist_delete_link (p, p); } treenode->cache = NULL; } /* recursively remove SwamiPropTreeNodes */ static void recursive_remove_nodes (GNode *node, SwamiPropTree *proptree) { GNode *n; n = node->children; while (n) { recursive_remove_nodes (n, proptree); n = n->next; } { SwamiPropTreeNode *treenode = (SwamiPropTreeNode *)(node->data); swami_prop_tree_node_reset_L (proptree, treenode); swami_prop_tree_free_node_L (treenode); /* free node */ g_node_destroy (node); } } /** * swami_prop_tree_replace: * @proptree: Property tree object * @old: Old object in @proptree to replace * @new: New object to replace @old object with * * Replaces an @old object with a @new object in a property tree. */ void swami_prop_tree_replace (SwamiPropTree *proptree, GObject *old, GObject *new) { SwamiPropTreeNode *treenode; GNode *obj_node; GList *speclist; g_return_if_fail (SWAMI_IS_PROP_TREE (proptree)); g_return_if_fail (G_IS_OBJECT (old)); g_return_if_fail (G_IS_OBJECT (new)); speclist = object_spec_list (new); /* get GParamSpec list for new object */ SWAMI_LOCK_WRITE (proptree); obj_node = g_hash_table_lookup (proptree->object_hash, old); if (swami_log_if_fail (obj_node != NULL)) { SWAMI_UNLOCK_WRITE (proptree); g_list_free (speclist); return; } treenode = (SwamiPropTreeNode *)(obj_node->data); /* clear old cache and remove old object hash entry */ swami_prop_tree_node_clear_cache_L (treenode); g_hash_table_remove (proptree->object_hash, old); g_hash_table_insert (proptree->object_hash, new, obj_node); /* weak ref to passively catch objects demise */ g_object_weak_ref (new, swami_prop_tree_object_weak_notify, proptree); /* re-resolve properties if any (speclist is freed) */ if (speclist) resolve_object_props_L (proptree, obj_node, speclist); SWAMI_UNLOCK_WRITE (proptree); } /** * swami_prop_tree_get_children: * @proptree: Property tree object * @obj: Object in @proptree to get children of * * Gets the list of GObject children of @obj in a property tree. * * Returns: A new object list populated with the children of @obj in @proptree. * The new list has a reference count of 1 which the caller owns, remember to * unref it when finished. */ IpatchList * swami_prop_tree_get_children (SwamiPropTree *proptree, GObject *obj) { IpatchList *list; SwamiPropTreeNode *treenode; GNode *obj_node, *n; g_return_val_if_fail (SWAMI_IS_PROP_TREE (proptree), NULL); g_return_val_if_fail (G_IS_OBJECT (obj), NULL); list = ipatch_list_new (); /* ++ ref new list */ SWAMI_LOCK_READ (proptree); obj_node = g_hash_table_lookup (proptree->object_hash, obj); if (swami_log_if_fail (obj_node != NULL)) { SWAMI_UNLOCK_READ (proptree); g_object_unref (list); /* -- unref list */ return (NULL); } n = obj_node->children; while (n) { treenode = (SwamiPropTreeNode *)(n->data); g_object_ref (treenode->object); /* ++ ref for list */ list->items = g_list_prepend (list->items, treenode->object); n = n->next; } SWAMI_UNLOCK_READ (proptree); list->items = g_list_reverse (list->items); return (list); } /** * swami_prop_tree_get_node: * @proptree: Property tree object * @obj: Object in @proptree to get GNode of * * Gets the GNode of an object in a property tree. This should only be done * for objects which are sure to remain in the property tree for the duration * of GNode use. * * Returns: GNode of @obj in property tree. GNode can only be used for as * long as the object is in the tree. */ GNode * swami_prop_tree_object_get_node (SwamiPropTree *proptree, GObject *obj) { GNode *node; g_return_val_if_fail (SWAMI_IS_PROP_TREE (proptree), NULL); g_return_val_if_fail (G_IS_OBJECT (obj), NULL); SWAMI_LOCK_READ (proptree); node = g_hash_table_lookup (proptree->object_hash, obj); SWAMI_UNLOCK_READ (proptree); return (node); } /** * swami_prop_tree_add_value: * @proptree: Property tree object * @obj: Object in @proptree * @prop_type: GObject derived type the value should match (0 = wildcard) * @prop_name: Property name to match * @control: Active value control * * Adds a value to an object in a property tree. If a value already exists * with the same @prop_type and @prop_name its @control value is replaced. */ void swami_prop_tree_add_value (SwamiPropTree *proptree, GObject *obj, GType prop_type, const char *prop_name, SwamiControl *control) { SwamiPropTreeValue *treeval; SwamiPropTreeNode *treenode; GNode *obj_node; GSList *p; g_return_if_fail (SWAMI_IS_PROP_TREE (proptree)); g_return_if_fail (G_IS_OBJECT (obj)); g_return_if_fail (!prop_type || g_type_is_a (prop_type, G_TYPE_OBJECT)); g_return_if_fail (prop_name != NULL && *prop_name != '\0'); g_return_if_fail (SWAMI_IS_CONTROL (control)); SWAMI_LOCK_WRITE (proptree); obj_node = g_hash_table_lookup (proptree->object_hash, obj); if (swami_log_if_fail (obj_node != NULL)) { SWAMI_UNLOCK_WRITE (proptree); return; } treenode = (SwamiPropTreeNode *)(obj_node->data); g_object_ref (control); /* ++ ref control for tree value */ p = treenode->values; while (p) /* look for existing duplicate tree value */ { treeval = (SwamiPropTreeValue *)(p->data); if (treeval->prop_type == prop_type && strcmp (treeval->prop_name, prop_name) == 0) { g_object_unref (control); /* -- unref old control */ break; } p = g_slist_next (p); } /* if a matching value doesn't already exist, allocate a new one */ if (!p) { treeval = swami_prop_tree_new_value_L (); treeval->prop_type = prop_type; treeval->prop_name = g_strdup (prop_name); treenode->values = g_slist_prepend (treenode->values, treeval); } treeval->control = control; refresh_value_nodes_L (obj_node, treeval); /* refresh nodes */ SWAMI_UNLOCK_WRITE (proptree); } /** * swami_prop_tree_remove_value: * @proptree: Property tree object * @obj: Object in @proptree * @prop_type: GObject derived type field of existing value * @prop_name: Property name field of existing value * * Removes a value from an object in a property tree. The @prop_type and * @prop_name parameters are used to find the value to remove. */ void swami_prop_tree_remove_value (SwamiPropTree *proptree, GObject *obj, GType prop_type, const char *prop_name) { SwamiPropTreeValue *treeval; SwamiPropTreeNode *treenode; GNode *obj_node; GSList *p, *prev = NULL; g_return_if_fail (SWAMI_IS_PROP_TREE (proptree)); g_return_if_fail (G_IS_OBJECT (obj)); g_return_if_fail (!prop_type || g_type_is_a (prop_type, G_TYPE_OBJECT)); g_return_if_fail (prop_name != NULL && *prop_name != '\0'); obj_node = g_hash_table_lookup (proptree->object_hash, obj); if (swami_log_if_fail (obj_node != NULL)) { SWAMI_UNLOCK_WRITE (proptree); return; } treenode = (SwamiPropTreeNode *)(obj_node->data); p = treenode->values; while (p) /* loop over values */ { treeval = (SwamiPropTreeValue *)(p->data); if (treeval->prop_type == prop_type /* tree value matches? */ && strcmp (treeval->prop_name, prop_name) == 0) break; prev = p; p = g_slist_next (p); } if (p) /* if a match was found */ { /* quick remove the value from the list */ if (prev) prev->next = p->next; else treenode->values = p->next; refresh_value_nodes_L (obj_node, treeval); /* refresh nodes */ /* free the tree value */ g_free (treeval->prop_name); g_object_unref (treeval->control); /* -- unref control */ swami_prop_tree_free_value_L (treeval); } SWAMI_UNLOCK_WRITE (proptree); } /* one time property resolve and cache function */ static void resolve_object_props_L (SwamiPropTree *proptree, GNode *object_node, GList *speclist) { SwamiPropTreeNode *treenode, *obj_treenode; SwamiPropTreeValue *treeval; SwamiControl *prop_ctrl; CacheValue *cache; GParamSpec *pspec; GType obj_type; GNode *n; GList *sp, *temp; GSList *p; int flags; obj_treenode = (SwamiPropTreeNode *)(object_node->data); obj_type = G_TYPE_FROM_INSTANCE (obj_treenode->object); n = object_node; do { /* loop over tree ancestry */ treenode = (SwamiPropTreeNode *)(n->data); p = treenode->values; while (p) /* loop over variables in each node */ { treeval = (SwamiPropTreeValue *)(p->data); /* object type matches? */ if (!treeval->prop_type || (treeval->prop_type == obj_type)) { sp = speclist; while (sp) /* loop over remaining object param specs */ { pspec = (GParamSpec *)(sp->data); if (strcmp (pspec->name, treeval->prop_name) == 0) { /* property name matches */ /* create a new object property control */ prop_ctrl = swami_get_control_prop_by_name (obj_treenode->object, pspec->name); flags = SWAMI_CONTROL_CONN_INIT; if (swami_control_get_flags (prop_ctrl) & SWAMI_CONTROL_SENDS) flags |= SWAMI_CONTROL_CONN_BIDIR; /* connect the tree value control to the property control and initialize the property to the tree value */ swami_control_connect (treeval->control, (SwamiControl *)prop_ctrl, flags); /* create cache value and add it to object tree node */ cache = swami_prop_tree_new_cache_L (); cache->pspec = pspec; cache->prop_ctrl = prop_ctrl; cache->value = treeval; cache->value_node = treenode; obj_treenode->cache = g_slist_prepend (obj_treenode->cache, cache); temp = sp; sp = g_list_next (sp); /* delete param spec from find spec list */ speclist = g_list_delete_link (speclist, temp); if (!speclist) goto done; /* no more properties? */ } else sp = g_list_next (sp); } } p = g_slist_next (p); } } while ((n = n->parent)); done: while (speclist) /* loop over remaining parameter specs */ { pspec = (GParamSpec *)(speclist->data); /* create an "unset" cache value */ cache = swami_prop_tree_new_cache_L (); cache->pspec = pspec; cache->prop_ctrl = NULL; cache->value = NULL; cache->value_node = NULL; obj_treenode->cache = g_slist_prepend (obj_treenode->cache, cache); /* free each node of the spec list */ speclist = g_list_delete_link (speclist, speclist); } } /* create a GList of parameter specs for a given object */ static GList * object_spec_list (GObject *object) { GParamSpec **pspecs, **spp; GList *speclist = NULL; pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), NULL); spp = pspecs; while (*spp) /* create a param spec list */ { speclist = g_list_prepend (speclist, *spp); spp++; } g_free (pspecs); /* no longer need array */ return (speclist); } /* recursively refresh cache values affected by a tree value */ static void refresh_value_nodes_L (GNode *node, SwamiPropTreeValue *treeval) { GNode *n; n = node->children; while (n) { refresh_value_nodes_L (n, treeval); n = n->next; } { SwamiPropTreeNode *treenode = (SwamiPropTreeNode *)(node->data); GType obj_type = G_TYPE_FROM_INSTANCE (treenode->object); char *prop_name = treeval->prop_name; CacheValue *cache; GSList *p; /* object type matches type criteria of treeval? */ if (treeval->prop_type && treeval->prop_type != obj_type) return; p = treenode->cache; while (p) /* loop over the node's cache */ { cache = (CacheValue *)(p->data); if (strcmp (prop_name, cache->pspec->name) == 0) break; p = g_slist_next (p); } if (p) refresh_cache_value_L (node, cache); } } /* recursively refresh cache values affected by a list of tree values */ static void refresh_value_nodes_list_L (GNode *node, GSList *treevals) { GNode *n; n = node->children; while (n) { refresh_value_nodes_list_L (n, treevals); n = n->next; } { SwamiPropTreeNode *treenode = (SwamiPropTreeNode *)(node->data); GType obj_type = G_TYPE_FROM_INSTANCE (treenode->object); SwamiPropTreeValue *treeval; CacheValue *cache; GSList *p, *p2; p = treevals; while (p) /* loop over list of tree values to match for refresh */ { treeval = (SwamiPropTreeValue *)(p->data); /* treeval matches type criteria of treeval? */ if (!treeval->prop_type || treeval->prop_type == obj_type) { p2 = treenode->cache; while (p2) /* loop over the node's cache */ { cache = (CacheValue *)(p2->data); /* prop name matches? - refresh cache val */ if (strcmp (treeval->prop_name, cache->pspec->name) == 0) refresh_cache_value_L (node, cache); p2 = g_slist_next (p2); } } p = g_slist_next (p); } } } /* refreshes a single cache value in a tree node */ static inline void refresh_cache_value_L (GNode *node, CacheValue *cache) { SwamiPropTreeNode *treenode, *obj_treenode; SwamiPropTreeValue *treeval; const char *prop_name; GType obj_type; GSList *p; int flags; obj_treenode = (SwamiPropTreeNode *)(node->data); obj_type = G_TYPE_FROM_INSTANCE (obj_treenode->object); prop_name = cache->pspec->name; do { /* loop over tree ancestry */ treenode = (SwamiPropTreeNode *)(node->data); p = treenode->values; while (p) /* loop over variables in each node */ { treeval = (SwamiPropTreeValue *)(p->data); /* property type and name matches? */ if ((!treeval->prop_type || (treeval->prop_type == obj_type)) && strcmp (prop_name, treeval->prop_name) == 0) { /* property name matches */ if (cache->value == treeval) return; /* cache is correct? */ if (!cache->prop_ctrl) /* no existing property control? */ cache->prop_ctrl = /* ++ ref new property control */ swami_get_control_prop_by_name (obj_treenode->object, prop_name); else /* disconnect current property control */ swami_control_disconnect_all ((SwamiControl *)(cache->prop_ctrl)); /* update the cached tree value */ cache->value = treeval; cache->value_node = treenode; flags = SWAMI_CONTROL_CONN_INIT; if (swami_control_get_flags (cache->prop_ctrl) & SWAMI_CONTROL_SENDS) flags |= SWAMI_CONTROL_CONN_BIDIR; /* connect tree value control to property control and initialize to current value (connect bi-direction if prop_ctrl sends) */ swami_control_connect (treeval->control, (SwamiControl *)(cache->prop_ctrl), flags); return; } p = g_slist_next (p); } } while ((node = node->parent)); /* no tree value found to satisfy cache property criteria */ if (cache->prop_ctrl) /* destroy unused property control? */ { swami_control_disconnect_all ((SwamiControl *)(cache->prop_ctrl)); g_object_unref (cache->prop_ctrl); /* -- unref prop ctrl from cache */ cache->prop_ctrl = NULL; } /* set cached value to "unset" state */ cache->value = NULL; cache->value_node = NULL; } swami/src/libswami/SwamiWavetbl.h0000644000175000017500000000726411461334205017242 0ustar alessioalessio/* * SwamiWavetbl.h - Swami wave table object * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMI_WAVETBL_H__ #define __SWAMI_WAVETBL_H__ #include #include #include #include #include #include typedef struct _SwamiWavetbl SwamiWavetbl; typedef struct _SwamiWavetblClass SwamiWavetblClass; #define SWAMI_TYPE_WAVETBL (swami_wavetbl_get_type ()) #define SWAMI_WAVETBL(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMI_TYPE_WAVETBL, SwamiWavetbl)) #define SWAMI_WAVETBL_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMI_TYPE_WAVETBL, SwamiWavetblClass)) #define SWAMI_IS_WAVETBL(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMI_TYPE_WAVETBL)) #define SWAMI_IS_WAVETBL_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMI_TYPE_WAVETBL)) #define SWAMI_WAVETBL_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), SWAMI_TYPE_WAVETBL, SwamiWavetblClass)) /* Swami Wavetbl object */ struct _SwamiWavetbl { SwamiLock parent_instance; IpatchVBank *vbank; /* Virtual bank of available instruments */ /*< private >*/ gboolean active; /* driver is active? */ guint16 active_bank; /* active (focused) audible MIDI bank number */ guint16 active_program; /* active (focused) audible MIDI program number */ }; struct _SwamiWavetblClass { SwamiLockClass parent_class; /*< public >*/ gboolean (*open)(SwamiWavetbl *wavetbl, GError **err); void (*close)(SwamiWavetbl *wavetbl); SwamiControlMidi * (*get_control) (SwamiWavetbl *wavetbl, int index); gboolean (*load_patch)(SwamiWavetbl *wavetbl, IpatchItem *patch, GError **err); gboolean (*load_active_item)(SwamiWavetbl *wavetbl, IpatchItem *item, GError **err); gboolean (*check_update_item)(SwamiWavetbl *wavetbl, IpatchItem *item, GParamSpec *prop); void (*update_item)(SwamiWavetbl *wavetbl, IpatchItem *item); void (*realtime_effect)(SwamiWavetbl *wavetbl, IpatchItem *item, GParamSpec *prop, GValue *value); }; GType swami_wavetbl_get_type (void); IpatchVBank *swami_wavetbl_get_virtual_bank (SwamiWavetbl *wavetbl); void swami_wavetbl_set_active_item_locale (SwamiWavetbl *wavetbl, int bank, int program); void swami_wavetbl_get_active_item_locale (SwamiWavetbl *wavetbl, int *bank, int *program); gboolean swami_wavetbl_open (SwamiWavetbl *wavetbl, GError **err); void swami_wavetbl_close (SwamiWavetbl *wavetbl); SwamiControlMidi *swami_wavetbl_get_control (SwamiWavetbl *wavetbl, int index); gboolean swami_wavetbl_load_patch (SwamiWavetbl *wavetbl, IpatchItem *patch, GError **err); gboolean swami_wavetbl_load_active_item (SwamiWavetbl *wavetbl, IpatchItem *item, GError **err); gboolean swami_wavetbl_check_update_item (SwamiWavetbl *wavetbl, IpatchItem *item, GParamSpec *prop); void swami_wavetbl_update_item (SwamiWavetbl *wavetbl, IpatchItem *item); #endif swami/src/libswami/SwamiControlFunc.c0000644000175000017500000001477711461334205020074 0ustar alessioalessio/* * SwamiControlFunc.c - Swami function control object * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include "SwamiControlFunc.h" #include "SwamiControl.h" #include "SwamiLog.h" #include "swami_priv.h" #include "util.h" static void swami_control_func_class_init (SwamiControlFuncClass *klass); static void swami_control_func_finalize (GObject *object); static GParamSpec *control_func_get_spec_method (SwamiControl *control); static gboolean control_func_set_spec_method (SwamiControl *control, GParamSpec *spec); static void control_func_get_value_method (SwamiControl *control, GValue *value); static void control_func_set_value_method (SwamiControl *control, SwamiControlEvent *event, const GValue *value); static GObjectClass *parent_class = NULL; GType swami_control_func_get_type (void) { static GType otype = 0; if (!otype) { static const GTypeInfo type_info = { sizeof (SwamiControlFuncClass), NULL, NULL, (GClassInitFunc) swami_control_func_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SwamiControlFunc), 0, (GInstanceInitFunc) NULL }; otype = g_type_register_static (SWAMI_TYPE_CONTROL, "SwamiControlFunc", &type_info, 0); } return (otype); } static void swami_control_func_class_init (SwamiControlFuncClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); SwamiControlClass *control_class = SWAMI_CONTROL_CLASS (klass); parent_class = g_type_class_peek_parent (klass); obj_class->finalize = swami_control_func_finalize; control_class->get_spec = control_func_get_spec_method; control_class->set_spec = control_func_set_spec_method; control_class->get_value = control_func_get_value_method; control_class->set_value = control_func_set_value_method; } static void swami_control_func_finalize (GObject *object) { SwamiControlFunc *ctrlfunc = SWAMI_CONTROL_FUNC (object); SWAMI_LOCK_WRITE (ctrlfunc); if (ctrlfunc->pspec) g_param_spec_unref (ctrlfunc->pspec); if (ctrlfunc->destroy_func) (*ctrlfunc->destroy_func)(ctrlfunc); ctrlfunc->get_func = NULL; ctrlfunc->set_func = NULL; ctrlfunc->destroy_func = NULL; SWAMI_UNLOCK_WRITE (ctrlfunc); parent_class->finalize (object); } /* control is locked by caller */ static GParamSpec * control_func_get_spec_method (SwamiControl *control) { SwamiControlFunc *ctrlfunc = SWAMI_CONTROL_FUNC (control); return (ctrlfunc->pspec); } /* control is locked by caller */ static gboolean control_func_set_spec_method (SwamiControl *control, GParamSpec *spec) { SwamiControlFunc *ctrlfunc = SWAMI_CONTROL_FUNC (control); if (ctrlfunc->pspec) g_param_spec_unref (ctrlfunc->pspec); ctrlfunc->pspec = g_param_spec_ref (spec); g_param_spec_sink (spec); /* take ownership of the parameter spec */ return (TRUE); } /* locking is up to user (not locked) */ static void control_func_get_value_method (SwamiControl *control, GValue *value) { SwamiControlGetValueFunc func = SWAMI_CONTROL_FUNC (control)->get_func; if (func) (*func)(control, value); } /* locking is up to user (not locked) */ static void control_func_set_value_method (SwamiControl *control, SwamiControlEvent *event, const GValue *value) { SwamiControlSetValueFunc func = SWAMI_CONTROL_FUNC (control)->set_func; (*func)(control, event, value); } /** * swami_control_func_new: * * Create a new function callback control. Function controls are useful for * easily creating custom controls using callback functions. * * Returns: New function control with a refcount of 1 which the caller owns. */ SwamiControlFunc * swami_control_func_new (void) { return (SWAMI_CONTROL_FUNC (g_object_new (SWAMI_TYPE_CONTROL_FUNC, NULL))); } /** * swami_control_func_assign_funcs: * @ctrlfunc: Swami function control object * @get_func: Function to call to get control value or %NULL if not a readable * value control (may still send events) * @set_func: Function to call to set control value or %NULL if not a writable * value control * @destroy_func: Function to call when control is destroyed or function * callbacks are changed or %NULL if no cleanup is needed. * @user_data: User defined pointer (set in @ctrlfunc instance). * * Assigns callback functions to a Swami function control object. * These callback functions should handle the getting and setting of the * control's value. The value passed to these callback functions is initialized * to the type of the control's parameter spec and this type should not be * changed. The @destroy_func callback is called when the control is destroyed * or when the callback functions are changed and should do any needed cleanup. * The control is not locked for any of these callbacks and so must be done * in the callback if there are any thread sensitive operations. */ void swami_control_func_assign_funcs (SwamiControlFunc *ctrlfunc, SwamiControlGetValueFunc get_func, SwamiControlSetValueFunc set_func, SwamiControlFuncDestroy destroy_func, gpointer user_data) { SwamiControl *control; g_return_if_fail (SWAMI_IS_CONTROL_FUNC (ctrlfunc)); control = SWAMI_CONTROL (ctrlfunc); SWAMI_LOCK_WRITE (ctrlfunc); /* ensure input/output connections are still valid if changing functions */ if (control->inputs && !set_func) { g_critical ("%s: Invalid writable function control function change", G_STRLOC); SWAMI_UNLOCK_WRITE (ctrlfunc); return; } if (ctrlfunc->destroy_func) (*ctrlfunc->destroy_func)(ctrlfunc); control->flags = SWAMI_CONTROL_SENDS | (set_func ? SWAMI_CONTROL_RECVS : 0); ctrlfunc->get_func = get_func; ctrlfunc->set_func = set_func; ctrlfunc->destroy_func = destroy_func; ctrlfunc->user_data = user_data; SWAMI_UNLOCK_WRITE (ctrlfunc); } swami/src/libswami/SwamiRoot.h0000644000175000017500000000627411461334205016561 0ustar alessioalessio/* * SwamiRoot.h - Root Swami application object * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __SWAMI_ROOT_H__ #define __SWAMI_ROOT_H__ #include #include #include typedef struct _SwamiRoot SwamiRoot; typedef struct _SwamiRootClass SwamiRootClass; #include #include #include #define SWAMI_TYPE_ROOT (swami_root_get_type ()) #define SWAMI_ROOT(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWAMI_TYPE_ROOT, SwamiRoot)) #define SWAMI_ROOT_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), SWAMI_TYPE_ROOT, SwamiRootClass)) #define SWAMI_IS_ROOT(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWAMI_TYPE_ROOT)) #define SWAMI_IS_ROOT_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), SWAMI_TYPE_ROOT)) struct _SwamiRoot { SwamiLock parent_instance; SwamiContainer *patch_root; /* instrument patch tree */ /*< private >*/ SwamiPropTree *proptree; /* object property tree */ char *patch_search_path; char *patch_path; /* default path to patch files */ char *sample_path; /* default path to sample files */ char *sample_format; /* default sample format string */ int swap_max_waste; /* maximum sample swap waste in MB */ int sample_max_size; /* max sample size in MB (until big samples handled) */ }; struct _SwamiRootClass { SwamiLockClass parent_class; /* object add signal */ void (*object_add)(GObject *object); }; GType swami_root_get_type (void); SwamiRoot *swami_root_new (void); #define swami_root_get_patch_items(swami) \ ipatch_container_get_children (IPATCH_CONTAINER (swami->patch_root), \ IPATCH_TYPE_ITEM) SwamiRoot *swami_get_root (gpointer object); IpatchList *swami_root_get_objects (SwamiRoot *root); void swami_root_add_object (SwamiRoot *root, GObject *object); GObject *swami_root_new_object (SwamiRoot *root, const char *type_name); void swami_root_prepend_object (SwamiRoot *root, GObject *parent, GObject *object); #define swami_root_append_object(root, parent, object) \ swami_root_insert_object_before (root, parent, NULL, object) void swami_root_insert_object_before (SwamiRoot *root, GObject *parent, GObject *sibling, GObject *object); gboolean swami_root_patch_load (SwamiRoot *root, const char *filename, IpatchItem **item, GError **err); gboolean swami_root_patch_save (IpatchItem *item, const char *filename, GError **err); #endif swami/src/CMakeLists.txt0000644000175000017500000000163011464144605015412 0ustar alessioalessio# # Swami # Copyright (C) 1999-2010 Joshua "Element" Green # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; version 2 # of the License only. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA or point your web browser to http://www.gnu.org. # # Process subdirectories add_subdirectory ( libswami ) add_subdirectory ( swamigui ) add_subdirectory ( plugins ) swami/src/swamish/0000755000175000017500000000000011716016666014332 5ustar alessioalessioswami/src/swamish/swamish.c0000644000175000017500000001651611461334205016147 0ustar alessioalessio/* * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include #include #include typedef struct _SwamishCmd SwamishCmd; typedef void (*SwamishCmdCallback)(SwamishCmd *command, char **args, int count); struct _SwamishCmd { char *command; /* text of command */ SwamishCmdCallback callback; /* command callback function */ char *syntax; /* syntax description of command */ char *descr; /* description of command */ char *help; /* detailed help on command */ }; static void swamish_cmd_ls (SwamishCmd *command, char **args, int count); static void swamish_cmd_pwd (SwamishCmd *command, char **args, int count); static void swamish_cmd_quit (SwamishCmd *command, char **args, int count); static SwamishCmd swamish_commands[] = { { "cd", NULL, N_("cd PATH"), N_("Change current object"), N_("Change the current object\n" "The `PATH' parameter is the directory or object to change to.") }, { "close", NULL, N_("close PATH [PATH2]..."), N_("Close instrument files"), N_("Close one or more files.\n" "`PATH' is a path to an instrument file.") }, { "cp", NULL, N_("cp SRC [SRC2]... DEST"), N_("Copy objects"), N_("Copy one or more objects to a destination.\n" "`SRC' and `DEST' are paths to objects or directories.") }, { "get", NULL, N_("get PATH [PATH2]... [NAME]..."), N_("Get object properties"), N_("Get an instrument object's property values.\n" "`PATH' is the path to an instrument object.\n" "Property names can be specified, all are listed if not given.") }, { "help", NULL, N_("help"), N_("Get help"), N_("When you don't know what to do, get some help.") }, { "ls", swamish_cmd_ls, N_("ls [PATH]..."), N_("List directory or object contents"), N_("List directory or instrument object children.\n" "The optional parameters can be objects and/or directories.\n" "If no parameters are given, the current directory is displayed.") }, { "new", NULL, N_("new [TYPE]"), N_("Create a new instrument object"), N_("Create a new instrument object within the current path.\n" "`TYPE' is the type of object to create.\n" "Available types are displayed if not specified.") }, { "pwd", swamish_cmd_pwd, N_("pwd"), N_("Print current object path"), N_("Displays the current directory or object path.") }, { "quit", swamish_cmd_quit, N_("quit"), N_("Quit"), N_("Exit the Swami Shell") }, { "rm", NULL, N_("rm PATH [PATH2]..."), N_("Remove files or objects"), N_("Remove one or more objects or files.\n" "`PATH' is a path to a directory or object.") }, { "save", NULL, N_("save PATH [PATH2]..."), N_("Save instrument files"), N_("Save one or more instrument files.\n" "`PATH' is a path to an instrument file.") }, { "saveas", NULL, N_("saveas PATH NEWPATH"), N_("Save instrument file as another file"), N_("Save an instrument file to a different name.\n" "`PATH' is a path to an instrument file.\n" "`NEWPATH' is a new file path to save to.") }, { "set", NULL, N_("set PATH [PATH2]... NAME=VALUE..."), N_("Set object properties"), N_("Set properties of an instrument object.\n" "`PATH' is the path to an instrument object.\n" "One or more property `NAME=VALUE' pairs may be given.") }, }; gboolean exit_swamish = FALSE; // Set to TRUE to exit char *current_dir = NULL; // Current directory of current path char *current_obj = NULL; // Current obj of path or NULL (appended to dir) rl_compentry_func_t *complete_command () { } char * get_cmd (void) { char *line; line = readline("swami> "); if (line && *line) /* add line to history if it has any text */ add_history(line); return (line); } int main(void) { char *line; SwamishCmd *cmdinfo; int i; current_dir = g_get_current_dir (); do { line = get_cmd(); for (i = 0; i < G_N_ELEMENTS (swamish_commands); i++) { cmdinfo = &swamish_commands[i]; // Command matches? if (strcmp (cmdinfo->command, line) == 0) break; } free (line); // Was there a match and has a callback? if (i < G_N_ELEMENTS (swamish_commands)) { if (cmdinfo->callback) cmdinfo->callback (cmdinfo, NULL, 0); } else printf ("Unknown command\n"); } while (!exit_swamish); printf("See ya!\n"); return 0; } /* get a file listing for a directory (excluding '.' and '..' entries), returns NULL terminated array of strings which should be freed with g_strfreev() */ char ** get_path_contents (char *path, GError **err) { GDir *dh; const char *fname; GPtrArray *file_array; char **retptr; g_return_val_if_fail (path != NULL, NULL); g_return_val_if_fail (!err || !*err, NULL); dh = g_dir_open (path, 0, err); if (!dh) return (NULL); file_array = g_ptr_array_new (); while ((fname = g_dir_read_name (dh))) g_ptr_array_add (file_array, g_strdup (fname)); g_ptr_array_sort (file_array, (GCompareFunc)strcmp); /* sort the array */ g_ptr_array_add (file_array, NULL); /* NULL terminate */ g_dir_close (dh); retptr = (char **)(file_array->pdata); g_ptr_array_free (file_array, FALSE); return (retptr); } #if 0 static gboolean parse_path (const char *path, char **ret_dir, char **ret_obj) { char *fullpath = NULL; g_return_val_if_fail (path != NULL && *path, FALSE); if (!g_path_is_absolute (path)) { fullpath = g_build_filename (current_dir, path, NULL); path = fullpath; } if (fullpath) g_free (fullpath); return (TRUE); } static void swamish_cmd_cd (SwamishCmd *command, char **args, int count) { } #endif static void swamish_cmd_ls (SwamishCmd *command, char **args, int count) { char **files, **s; GError *err = NULL; if (!current_obj) // Is current path a directory? { files = get_path_contents (current_dir, &err); if (!files) { g_critical ("Error while getting directory listing: %s\n", ipatch_gerror_message (err)); g_clear_error (&err); return; } } else return; s = files; while (*s) { printf ("%s\n", *s); s++; } g_strfreev (files); } static void swamish_cmd_pwd (SwamishCmd *command, char **args, int count) { char *path; path = g_build_filename (current_dir, current_obj, NULL); printf ("%s\n", path); g_free (path); } static void swamish_cmd_quit (SwamishCmd *command, char **args, int count) { exit_swamish = TRUE; } swami/src/python/0000755000175000017500000000000011716016656014177 5ustar alessioalessioswami/src/python/swamiguimodule.c0000644000175000017500000000314611474034033017370 0ustar alessioalessio/* * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define NO_IMPORT_PYGOBJECT #include #include #include "swamigui_missing.h" void pyswamigui_register_missing_classes (PyObject *d); void pyswamigui_register_classes (PyObject *d); void pyswamigui_add_constants(PyObject *module, const gchar *strip_prefix); extern PyMethodDef pyswamigui_functions[]; DL_EXPORT(void) initswamigui(void) { PyObject *m, *d; init_pygobject (); swamigui_init (NULL, NULL); /* initialize swamigui */ m = Py_InitModule ("swamigui", pyswamigui_functions); d = PyModule_GetDict (m); pyswamigui_register_missing_classes (d); pyswamigui_register_classes (d); pyswamigui_add_constants(m, "SWAMIGUI_"); if (PyErr_Occurred ()) { PyErr_Print (); Py_FatalError ("can't initialise module swamigui"); } } swami/src/python/swamigui_missing.c0000644000175000017500000001206711474034033017715 0ustar alessioalessio/* * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #define NO_IMPORT_PYGOBJECT #include "pygobject.h" #include static PyTypeObject *_PyGtkObject_Type; #define PyGtkObject_Type (*_PyGtkObject_Type) PyTypeObject PyGnomeCanvasItem_Type; PyTypeObject PyGnomeCanvasGroup_Type; static int pygobject_no_constructor(PyObject *self, PyObject *args, PyObject *kwargs) { gchar buf[512]; g_snprintf(buf, sizeof(buf), "%s is an abstract widget", self->ob_type->tp_name); PyErr_SetString(PyExc_NotImplementedError, buf); return -1; } PyTypeObject PyGnomeCanvasItem_Type = { PyObject_HEAD_INIT(NULL) 0, /* ob_size */ "SwamiGui.GnomeCanvasItem", /* tp_name */ sizeof(PyGObject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor)0, /* tp_dealloc */ (printfunc)0, /* tp_print */ (getattrfunc)0, /* tp_getattr */ (setattrfunc)0, /* tp_setattr */ (cmpfunc)0, /* tp_compare */ (reprfunc)0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ (hashfunc)0, /* tp_hash */ (ternaryfunc)0, /* tp_call */ (reprfunc)0, /* tp_str */ (getattrofunc)0, /* tp_getattro */ (setattrofunc)0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ NULL, /* Documentation string */ (traverseproc)0, /* tp_traverse */ (inquiry)0, /* tp_clear */ (richcmpfunc)0, /* tp_richcompare */ offsetof(PyGObject, weakreflist), /* tp_weaklistoffset */ (getiterfunc)0, /* tp_iter */ (iternextfunc)0, /* tp_iternext */ NULL, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ NULL, /* tp_base */ NULL, /* tp_dict */ (descrgetfunc)0, /* tp_descr_get */ (descrsetfunc)0, /* tp_descr_set */ offsetof(PyGObject, inst_dict), /* tp_dictoffset */ (initproc)pygobject_no_constructor, /* tp_init */ }; PyTypeObject PyGnomeCanvasGroup_Type = { PyObject_HEAD_INIT(NULL) 0, /* ob_size */ "SwamiGui.GnomeCanvasGroup", /* tp_name */ sizeof(PyGObject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor)0, /* tp_dealloc */ (printfunc)0, /* tp_print */ (getattrfunc)0, /* tp_getattr */ (setattrfunc)0, /* tp_setattr */ (cmpfunc)0, /* tp_compare */ (reprfunc)0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ (hashfunc)0, /* tp_hash */ (ternaryfunc)0, /* tp_call */ (reprfunc)0, /* tp_str */ (getattrofunc)0, /* tp_getattro */ (setattrofunc)0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ NULL, /* Documentation string */ (traverseproc)0, /* tp_traverse */ (inquiry)0, /* tp_clear */ (richcmpfunc)0, /* tp_richcompare */ offsetof(PyGObject, weakreflist), /* tp_weaklistoffset */ (getiterfunc)0, /* tp_iter */ (iternextfunc)0, /* tp_iternext */ NULL, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ NULL, /* tp_base */ NULL, /* tp_dict */ (descrgetfunc)0, /* tp_descr_get */ (descrsetfunc)0, /* tp_descr_set */ offsetof(PyGObject, inst_dict), /* tp_dictoffset */ (initproc)pygobject_no_constructor, /* tp_init */ }; /* intialise stuff extension classes */ void pyswamigui_register_missing_classes (PyObject *d) { PyObject *module; if ((module = PyImport_ImportModule("gtk")) != NULL) { PyObject *moddict = PyModule_GetDict(module); _PyGtkObject_Type = (PyTypeObject *)PyDict_GetItemString(moddict, "GtkObject"); if (_PyGtkObject_Type == NULL) { PyErr_SetString(PyExc_ImportError, "cannot import name GtkObject from gtk"); return; } } else { PyErr_SetString(PyExc_ImportError, "could not import gtk"); return; } pygobject_register_class(d, "GnomeCanvasItem", GNOME_TYPE_CANVAS_ITEM, &PyGnomeCanvasItem_Type, Py_BuildValue("(O)", &PyGtkObject_Type)); pygobject_register_class(d, "GnomeCanvasGroup", GNOME_TYPE_CANVAS_GROUP, &PyGnomeCanvasGroup_Type, Py_BuildValue("(O)", &PyGnomeCanvasItem_Type)); } swami/src/python/Makefile.am0000644000175000017500000000541611461404311016223 0ustar alessioalessio# Path to PyGtk defs utilities H2DEF=$(PYGTK_CODEGEN_DIR)/h2def.py MERGEDEFS=$(PYGTK_CODEGEN_DIR)/mergedefs.py AUTOMAKE_OPTIONS=1.5 INCLUDES = $(PYTHON_CFLAGS) $(PYGTK_CFLAGS) -I$(top_srcdir)/src \ $(GOBJECT_CFLAGS) $(LIBINSTPATCH_CFLAGS) $(GTK_CFLAGS) if PYTHON_SUPPORT swamimodule_cond = swamimodule.la swamiguimodule.la DEFPATH := $(shell pkg-config --variable=defsdir pygtk-2.0) defsdir = $(DEFPATH) defs_DATA = swami.defs swamigui.defs endif EXTRA_DIST = swami.override swami.defs swamimodule.c \ swamigui.override swamigui.defs swamiguimodule.c pyexec_LTLIBRARIES = $(swamimodule_cond) swamimodule_la_LDFLAGS = -module -avoid-version -export-symbols-regex \ initswami swamimodule_la_LIBADD = ../libswami/libswami.la @PYGTK_LIBS@ \ @GOBJECT_LIBS@ @LIBINSTPATCH_LIBS@ swamimodule_la_SOURCES = swamimodule.c swami_missing.c swami_missing.h nodist_swamimodule_la_SOURCES = swami.c swami.c: swami.defs swami.override swamiguimodule_la_LDFLAGS = -module -avoid-version -export-symbols-regex \ initswamigui swamiguimodule_la_LIBADD = \ ../swamigui/libswamigui.la ../libswami/libswami.la \ @PYGTK_LIBS@ @GOBJECT_LIBS@ @LIBINSTPATCH_LIBS@ \ @GUI_LIBS@ @GTK_SOURCE_VIEW_LIBS@ @LIBGLADE_LIBS@ swamiguimodule_la_CFLAGS = @GUI_CFLAGS@ @GTK_SOURCE_VIEW_CFLAGS@ swamiguimodule_la_SOURCES = swamiguimodule.c swamigui_missing.c \ swamigui_missing.h nodist_swamiguimodule_la_SOURCES = swamigui.c swamigui.c: swamigui.defs swamigui.override CLEANFILES = swami.c swamigui.c swami.c: (cd $(srcdir)\ && pygtk-codegen-2.0 \ --register $(DEFPATH)/ipatch.defs \ --register $(DEFPATH)/ipatch-types.defs \ --override swami.override \ --prefix pyswami swami.defs) > gen-swami.c \ && cp gen-swami.c swami.c \ && rm -f gen-swami.c swamigui.c: (cd $(srcdir)\ && pygtk-codegen-2.0 \ --register $(DEFPATH)/ipatch.defs \ --register $(DEFPATH)/ipatch-types.defs \ --register $(DEFPATH)/gtk-base.defs \ --register $(DEFPATH)/gtk-base-types.defs \ --register $(DEFPATH)/gdk-base.defs \ --register $(DEFPATH)/gdk-base-types.defs \ --override swamigui.override \ --prefix pyswamigui swamigui.defs) > gen-swamigui.c \ && cp gen-swamigui.c swamigui.c \ && rm -f gen-swamigui.c swami.defs: (cd $(srcdir)\ && $(PYTHON) ${H2DEF} `cat ../libswami/libswami.h | grep "^#include [<]libswami" | sed 's/#include //;s/^/\.\.\/libswami\//'`) > swami.defs swamigui.defs: (cd $(srcdir)\ && $(PYTHON) ${H2DEF} `cat ../swamigui/swamigui.h | grep "^#include [<]swamigui" | sed 's/#include //;s/^/\.\.\/swamigui\//'`) > swamigui.defs # Not merging old defs currently just re-generating # (cd $(srcdir) && cp -f swami.defs swami.defs.bak \ # && $(PYTHON) ${MERGEDEFS} swami.defs.gen swami.defs.bak) \ # >swami.defs swami/src/python/swamigui.override0000644000175000017500000000472210774346067017577 0ustar alessioalessio/* -*- Mode: C -*- * * swamigui.override - Function override for SwamiGUI python binding * * Swami * Copyright (C) 1999-2002 Josh Green * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser 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 */ %% headers #include #include "pygobject.h" #include #include #include #include "swamigui_missing.h" %% modulename SwamiGui %% import gobject.GObject as PyGObject_Type import ipatch.Container as PyIpatchContainer_Type import ipatch.Item as PyIpatchItem_Type import ipatch.List as PyIpatchList_Type import ipatch.Sample as PyIpatchSample_Type import swami.Control as PySwamiControl_Type import swami.ControlMidi as PySwamiControlMidi_Type import swami.Root as PySwamiRoot_Type import gtk.Adjustment as PyGtkAdjustment_Type import gtk.Container as PyGtkContainer_Type import gtk.Dialog as PyGtkDialog_Type import gtk.Window as PyGtkWindow_Type import gtk.Widget as PyGtkWidget_Type import gtk.VBox as PyGtkVBox_Type import gtk.EventBox as PyGtkEventBox_Type import gtk.VPaned as PyGtkVPaned_Type import gtk.ScrolledWindow as PyGtkScrolledWindow_Type import gtk.HBox as PyGtkHBox_Type import gtk.HPaned as PyGtkHPaned_Type import gtk.MenuBar as PyGtkMenuBar_Type import gtk.Menu as PyGtkMenu_Type import gtk.SpinButton as PyGtkSpinButton_Type import gtk.Toolbar as PyGtkToolbar_Type import gtk.TreeStore as PyGtkTreeStore_Type import gtk.Notebook as PyGtkNotebook_Type import gtk.Frame as PyGtkFrame_Type import gtk.DrawingArea as PyGtkDrawingArea_Type %% ignore-glob *_get_type %% override swamigui_get_root kwargs static PyObject * _wrap_swamigui_get_root (PyObject *self, PyObject *args, PyObject *kwargs) { /* pygobject_new handles NULL checking */ return pygobject_new((GObject *)swamigui_root); } swami/src/python/swamigui.defs0000644000175000017500000015727111457412471016701 0ustar alessioalessio;; -*- scheme -*- ; object definitions ... (define-object Bar (in-module "Swamigui") (parent "GnomeCanvasGroup") (c-name "SwamiguiBar") (gtype-id "SWAMIGUI_TYPE_BAR") ) (define-object BarPtr (in-module "Swamigui") (parent "GnomeCanvasGroup") (c-name "SwamiguiBarPtr") (gtype-id "SWAMIGUI_TYPE_BAR_PTR") ) (define-object CanvasMod (in-module "Swamigui") (parent "GObject") (c-name "SwamiguiCanvasMod") (gtype-id "SWAMIGUI_TYPE_CANVAS_MOD") ) (define-object ControlAdj (in-module "Swamigui") (parent "SwamiControl") (c-name "SwamiguiControlAdj") (gtype-id "SWAMIGUI_TYPE_CONTROL_ADJ") ) (define-object ControlMidiKey (in-module "Swamigui") (parent "SwamiControlMidi") (c-name "SwamiguiControlMidiKey") (gtype-id "SWAMIGUI_TYPE_CONTROL_MIDI_KEY") ) (define-object ItemMenu (in-module "Swamigui") (parent "GtkMenu") (c-name "SwamiguiItemMenu") (gtype-id "SWAMIGUI_TYPE_ITEM_MENU") ) (define-object Knob (in-module "Swamigui") (parent "GtkDrawingArea") (c-name "SwamiguiKnob") (gtype-id "SWAMIGUI_TYPE_KNOB") ) (define-object LoopFinder (in-module "Swamigui") (parent "GtkVBox") (c-name "SwamiguiLoopFinder") (gtype-id "SWAMIGUI_TYPE_LOOP_FINDER") ) (define-object Menu (in-module "Swamigui") (parent "GtkVBox") (c-name "SwamiguiMenu") (gtype-id "SWAMIGUI_TYPE_MENU") ) (define-object ModEdit (in-module "Swamigui") (parent "GtkScrolledWindow") (c-name "SwamiguiModEdit") (gtype-id "SWAMIGUI_TYPE_MOD_EDIT") ) (define-object MultiSave (in-module "Swamigui") (parent "GtkDialog") (c-name "SwamiguiMultiSave") (gtype-id "SWAMIGUI_TYPE_MULTI_SAVE") ) (define-object NoteSelector (in-module "Swamigui") (parent "GtkSpinButton") (c-name "SwamiguiNoteSelector") (gtype-id "SWAMIGUI_TYPE_NOTE_SELECTOR") ) (define-object Panel (in-module "Swamigui") (c-name "SwamiguiPanel") (gtype-id "SWAMIGUI_TYPE_PANEL") ) (define-object PanelSF2Gen (in-module "Swamigui") (parent "GtkScrolledWindow") (c-name "SwamiguiPanelSF2Gen") (gtype-id "SWAMIGUI_TYPE_PANEL_SF2_GEN") ) (define-object PanelSelector (in-module "Swamigui") (parent "GtkNotebook") (c-name "SwamiguiPanelSelector") (gtype-id "SWAMIGUI_TYPE_PANEL_SELECTOR") ) (define-object Paste (in-module "Swamigui") (parent "GObject") (c-name "SwamiguiPaste") (gtype-id "SWAMIGUI_TYPE_PASTE") ) (define-object Piano (in-module "Swamigui") (parent "GnomeCanvasGroup") (c-name "SwamiguiPiano") (gtype-id "SWAMIGUI_TYPE_PIANO") ) (define-object Pref (in-module "Swamigui") (parent "GtkDialog") (c-name "SwamiguiPref") (gtype-id "SWAMIGUI_TYPE_PREF") ) (define-object Prop (in-module "Swamigui") (parent "GtkScrolledWindow") (c-name "SwamiguiProp") (gtype-id "SWAMIGUI_TYPE_PROP") ) (define-object PythonView (in-module "Swamigui") (parent "GtkVBox") (c-name "SwamiguiPythonView") (gtype-id "SWAMIGUI_TYPE_PYTHON_VIEW") ) (define-object Root (in-module "Swamigui") (parent "SwamiRoot") (c-name "SwamiguiRoot") (gtype-id "SWAMIGUI_TYPE_ROOT") ) (define-object SampleCanvas (in-module "Swamigui") (parent "GnomeCanvasItem") (c-name "SwamiguiSampleCanvas") (gtype-id "SWAMIGUI_TYPE_SAMPLE_CANVAS") ) (define-object SampleEditor (in-module "Swamigui") (parent "GtkHBox") (c-name "SwamiguiSampleEditor") (gtype-id "SWAMIGUI_TYPE_SAMPLE_EDITOR") ) (define-object SpectrumCanvas (in-module "Swamigui") (parent "GnomeCanvasItem") (c-name "SwamiguiSpectrumCanvas") (gtype-id "SWAMIGUI_TYPE_SPECTRUM_CANVAS") ) (define-object SpinScale (in-module "Swamigui") (parent "GtkHBox") (c-name "SwamiguiSpinScale") (gtype-id "SWAMIGUI_TYPE_SPIN_SCALE") ) (define-object Splits (in-module "Swamigui") (parent "GtkVBox") (c-name "SwamiguiSplits") (gtype-id "SWAMIGUI_TYPE_SPLITS") ) (define-object Statusbar (in-module "Swamigui") (parent "GtkFrame") (c-name "SwamiguiStatusbar") (gtype-id "SWAMIGUI_TYPE_STATUSBAR") ) (define-object Tree (in-module "Swamigui") (parent "GtkVBox") (c-name "SwamiguiTree") (gtype-id "SWAMIGUI_TYPE_TREE") ) (define-object TreeStore (in-module "Swamigui") (parent "GtkTreeStore") (c-name "SwamiguiTreeStore") (gtype-id "SWAMIGUI_TYPE_TREE_STORE") ) (define-object TreeStorePatch (in-module "Swamigui") (parent "SwamiguiTreeStore") (c-name "SwamiguiTreeStorePatch") (gtype-id "SWAMIGUI_TYPE_TREE_STORE_PATCH") ) ;; Enumerations and flags ... (define-enum BarPtrType (in-module "Swamigui") (c-name "SwamiguiBarPtrType") (gtype-id "SWAMIGUI_TYPE_BAR_PTR_TYPE") (values '("position" "SWAMIGUI_BAR_PTR_POSITION") '("range" "SWAMIGUI_BAR_PTR_RANGE") ) ) (define-enum CanvasModType (in-module "Swamigui") (c-name "SwamiguiCanvasModType") (gtype-id "SWAMIGUI_TYPE_CANVAS_MOD_TYPE") (values '("snap-zoom" "SWAMIGUI_CANVAS_MOD_SNAP_ZOOM") '("wheel-zoom" "SWAMIGUI_CANVAS_MOD_WHEEL_ZOOM") '("snap-scroll" "SWAMIGUI_CANVAS_MOD_SNAP_SCROLL") '("wheel-scroll" "SWAMIGUI_CANVAS_MOD_WHEEL_SCROLL") ) ) (define-enum CanvasModAxis (in-module "Swamigui") (c-name "SwamiguiCanvasModAxis") (gtype-id "SWAMIGUI_TYPE_CANVAS_MOD_AXIS") (values '("x" "SWAMIGUI_CANVAS_MOD_X") '("y" "SWAMIGUI_CANVAS_MOD_Y") ) ) (define-flags CanvasModFlags (in-module "Swamigui") (c-name "SwamiguiCanvasModFlags") (gtype-id "SWAMIGUI_TYPE_CANVAS_MOD_FLAGS") (values '("enabled" "SWAMIGUI_CANVAS_MOD_ENABLED") ) ) (define-flags CanvasModActions (in-module "Swamigui") (c-name "SwamiguiCanvasModActions") (gtype-id "SWAMIGUI_TYPE_CANVAS_MOD_ACTIONS") (values '("zoom-x" "SWAMIGUI_CANVAS_MOD_ZOOM_X") '("zoom-y" "SWAMIGUI_CANVAS_MOD_ZOOM_Y") '("scroll-x" "SWAMIGUI_CANVAS_MOD_SCROLL_X") '("scroll-y" "SWAMIGUI_CANVAS_MOD_SCROLL_Y") ) ) (define-enum ControlRank (in-module "Swamigui") (c-name "SwamiguiControlRank") (gtype-id "SWAMIGUI_TYPE_CONTROL_RANK") (values '("lowest" "SWAMIGUI_CONTROL_RANK_LOWEST") '("low" "SWAMIGUI_CONTROL_RANK_LOW") '("normal" "SWAMIGUI_CONTROL_RANK_NORMAL") '("high" "SWAMIGUI_CONTROL_RANK_HIGH") '("highest" "SWAMIGUI_CONTROL_RANK_HIGHEST") ) ) (define-enum ControlFlags (in-module "Swamigui") (c-name "SwamiguiControlFlags") (gtype-id "SWAMIGUI_TYPE_CONTROL_FLAGS") (values '("ctrl" "SWAMIGUI_CONTROL_CTRL") '("view" "SWAMIGUI_CONTROL_VIEW") '("no-create" "SWAMIGUI_CONTROL_NO_CREATE") ) ) (define-flags ControlObjectFlags (in-module "Swamigui") (c-name "SwamiguiControlObjectFlags") (gtype-id "SWAMIGUI_TYPE_CONTROL_OBJECT_FLAGS") (values '("no-labels" "SWAMIGUI_CONTROL_OBJECT_NO_LABELS") '("no-sort" "SWAMIGUI_CONTROL_OBJECT_NO_SORT") '("prop-labels" "SWAMIGUI_CONTROL_OBJECT_PROP_LABELS") ) ) (define-flags ItemMenuFlags (in-module "Swamigui") (c-name "SwamiguiItemMenuFlags") (gtype-id "SWAMIGUI_TYPE_ITEM_MENU_FLAGS") (values '("inactive" "SWAMIGUI_ITEM_MENU_INACTIVE") '("plugin" "SWAMIGUI_ITEM_MENU_PLUGIN") ) ) (define-enum PasteStatus (in-module "Swamigui") (c-name "SwamiguiPasteStatus") (gtype-id "SWAMIGUI_TYPE_PASTE_STATUS") (values '("normal" "SWAMIGUI_PASTE_NORMAL") '("error" "SWAMIGUI_PASTE_ERROR") '("unhandled" "SWAMIGUI_PASTE_UNHANDLED") '("conflict" "SWAMIGUI_PASTE_CONFLICT") '("cancel" "SWAMIGUI_PASTE_CANCEL") ) ) (define-flags PasteDecision (in-module "Swamigui") (c-name "SwamiguiPasteDecision") (gtype-id "SWAMIGUI_TYPE_PASTE_DECISION") (values '("no-decision" "SWAMIGUI_PASTE_NO_DECISION") '("skip" "SWAMIGUI_PASTE_SKIP") '("changed" "SWAMIGUI_PASTE_CHANGED") '("replace" "SWAMIGUI_PASTE_REPLACE") ) ) (define-enum QuitConfirm (in-module "Swamigui") (c-name "SwamiguiQuitConfirm") (gtype-id "SWAMIGUI_TYPE_QUIT_CONFIRM") (values '("always" "SWAMIGUI_QUIT_CONFIRM_ALWAYS") '("unsaved" "SWAMIGUI_QUIT_CONFIRM_UNSAVED") '("never" "SWAMIGUI_QUIT_CONFIRM_NEVER") ) ) (define-enum SampleEditorStatus (in-module "Swamigui") (c-name "SwamiguiSampleEditorStatus") (gtype-id "SWAMIGUI_TYPE_SAMPLE_EDITOR_STATUS") (values '("normal" "SWAMIGUI_SAMPLE_EDITOR_NORMAL") '("init" "SWAMIGUI_SAMPLE_EDITOR_INIT") '("update" "SWAMIGUI_SAMPLE_EDITOR_UPDATE") ) ) (define-flags SampleEditorMarkerFlags (in-module "Swamigui") (c-name "SwamiguiSampleEditorMarkerFlags") (gtype-id "SWAMIGUI_TYPE_SAMPLE_EDITOR_MARKER_FLAGS") (values '("single" "SWAMIGUI_SAMPLE_EDITOR_MARKER_SINGLE") '("view" "SWAMIGUI_SAMPLE_EDITOR_MARKER_VIEW") '("size" "SWAMIGUI_SAMPLE_EDITOR_MARKER_SIZE") ) ) (define-enum SampleEditorMarkerId (in-module "Swamigui") (c-name "SwamiguiSampleEditorMarkerId") (gtype-id "SWAMIGUI_TYPE_SAMPLE_EDITOR_MARKER_ID") (values '("selection" "SWAMIGUI_SAMPLE_EDITOR_MARKER_ID_SELECTION") '("loop-find-start" "SWAMIGUI_SAMPLE_EDITOR_MARKER_ID_LOOP_FIND_START") '("loop-find-end" "SWAMIGUI_SAMPLE_EDITOR_MARKER_ID_LOOP_FIND_END") ) ) (define-enum SplitsMode (in-module "Swamigui") (c-name "SwamiguiSplitsMode") (gtype-id "SWAMIGUI_TYPE_SPLITS_MODE") (values '("note" "SWAMIGUI_SPLITS_NOTE") '("velocity" "SWAMIGUI_SPLITS_VELOCITY") ) ) (define-enum SplitsStatus (in-module "Swamigui") (c-name "SwamiguiSplitsStatus") (gtype-id "SWAMIGUI_TYPE_SPLITS_STATUS") (values '("normal" "SWAMIGUI_SPLITS_NORMAL") '("init" "SWAMIGUI_SPLITS_INIT") '("mode" "SWAMIGUI_SPLITS_MODE") '("update" "SWAMIGUI_SPLITS_UPDATE") ) ) (define-flags SplitsMoveFlags (in-module "Swamigui") (c-name "SwamiguiSplitsMoveFlags") (gtype-id "SWAMIGUI_TYPE_SPLITS_MOVE_FLAGS") (values '("ranges" "SWAMIGUI_SPLITS_MOVE_RANGES") '("param1" "SWAMIGUI_SPLITS_MOVE_PARAM1") ) ) (define-enum StatusbarPos (in-module "Swamigui") (c-name "SwamiguiStatusbarPos") (gtype-id "SWAMIGUI_TYPE_STATUSBAR_POS") (values '("left" "SWAMIGUI_STATUSBAR_POS_LEFT") '("right" "SWAMIGUI_STATUSBAR_POS_RIGHT") ) ) (define-enum StatusbarTimeout (in-module "Swamigui") (c-name "SwamiguiStatusbarTimeout") (gtype-id "SWAMIGUI_TYPE_STATUSBAR_TIMEOUT") (values '("default" "SWAMIGUI_STATUSBAR_TIMEOUT_DEFAULT") '("forever" "SWAMIGUI_STATUSBAR_TIMEOUT_FOREVER") ) ) ;; From SwamiguiBar.h (define-function swamigui_bar_get_type (c-name "swamigui_bar_get_type") (return-type "GType") ) (define-method create_pointer (of-object "SwamiguiBar") (c-name "swamigui_bar_create_pointer") (return-type "none") (parameters '("const-char*" "id") '("const-char*" "first_property_name") ) (varargs #t) ) (define-method add_pointer (of-object "SwamiguiBar") (c-name "swamigui_bar_add_pointer") (return-type "none") (parameters '("SwamiguiBarPtr*" "barptr") '("const-char*" "id") ) ) (define-method get_pointer (of-object "SwamiguiBar") (c-name "swamigui_bar_get_pointer") (return-type "GnomeCanvasItem*") (parameters '("const-char*" "id") ) ) (define-method set_pointer_position (of-object "SwamiguiBar") (c-name "swamigui_bar_set_pointer_position") (return-type "none") (parameters '("const-char*" "id") '("int" "position") ) ) (define-method set_pointer_range (of-object "SwamiguiBar") (c-name "swamigui_bar_set_pointer_range") (return-type "none") (parameters '("const-char*" "id") '("int" "start") '("int" "end") ) ) (define-method get_pointer_order (of-object "SwamiguiBar") (c-name "swamigui_bar_get_pointer_order") (return-type "int") (parameters '("const-char*" "id") ) ) (define-method set_pointer_order (of-object "SwamiguiBar") (c-name "swamigui_bar_set_pointer_order") (return-type "none") (parameters '("const-char*" "id") '("int" "pos") ) ) (define-method raise_pointer_to_top (of-object "SwamiguiBar") (c-name "swamigui_bar_raise_pointer_to_top") (return-type "none") (parameters '("const-char*" "id") ) ) (define-method lower_pointer_to_bottom (of-object "SwamiguiBar") (c-name "swamigui_bar_lower_pointer_to_bottom") (return-type "none") (parameters '("const-char*" "id") ) ) ;; From SwamiguiBarPtr.h (define-function swamigui_bar_ptr_get_type (c-name "swamigui_bar_ptr_get_type") (return-type "GType") ) (define-function swamigui_bar_ptr_new (c-name "swamigui_bar_ptr_new") (is-constructor-of "SwamiguiBarPtr") (return-type "GnomeCanvasItem*") ) ;; From SwamiguiCanvasMod.h (define-function swamigui_canvas_mod_get_type (c-name "swamigui_canvas_mod_get_type") (return-type "GType") ) (define-function swamigui_canvas_mod_new (c-name "swamigui_canvas_mod_new") (is-constructor-of "SwamiguiCanvasMod") (return-type "SwamiguiCanvasMod*") ) (define-method set_vars (of-object "SwamiguiCanvasMod") (c-name "swamigui_canvas_mod_set_vars") (return-type "none") (parameters '("SwamiguiCanvasModAxis" "axis") '("SwamiguiCanvasModType" "type") '("double" "mult") '("double" "power") '("double" "ofs") ) ) (define-method get_vars (of-object "SwamiguiCanvasMod") (c-name "swamigui_canvas_mod_get_vars") (return-type "none") (parameters '("SwamiguiCanvasModAxis" "axis") '("SwamiguiCanvasModType" "type") '("double*" "mult") '("double*" "power") '("double*" "ofs") ) ) (define-method handle_event (of-object "SwamiguiCanvasMod") (c-name "swamigui_canvas_mod_handle_event") (return-type "gboolean") (parameters '("GdkEvent*" "event") ) ) ;; From SwamiguiControl.h (define-function swamigui_control_new (c-name "swamigui_control_new") (is-constructor-of "SwamiguiControl") (return-type "SwamiControl*") (parameters '("GType" "type") ) ) (define-function swamigui_control_new_for_widget (c-name "swamigui_control_new_for_widget") (return-type "SwamiControl*") (parameters '("GObject*" "widget") ) ) (define-function swamigui_control_new_for_widget_full (c-name "swamigui_control_new_for_widget_full") (return-type "SwamiControl*") (parameters '("GObject*" "widget") '("GType" "value_type") '("GParamSpec*" "pspec") '("SwamiguiControlFlags" "flags") ) ) (define-function swamigui_control_lookup (c-name "swamigui_control_lookup") (return-type "SwamiControl*") (parameters '("GObject*" "widget") ) ) (define-function swamigui_control_prop_connect_widget (c-name "swamigui_control_prop_connect_widget") (return-type "none") (parameters '("GObject*" "object") '("const-char*" "propname") '("GObject*" "widget") ) ) (define-function swamigui_control_create_widget (c-name "swamigui_control_create_widget") (return-type "GObject*") (parameters '("GType" "widg_type") '("GType" "value_type") '("GParamSpec*" "pspec") '("SwamiguiControlFlags" "flags") ) ) (define-function swamigui_control_set_queue (c-name "swamigui_control_set_queue") (return-type "none") (parameters '("SwamiControl*" "control") ) ) (define-function swamigui_control_register (c-name "swamigui_control_register") (return-type "none") (parameters '("GType" "widg_type") '("GType" "value_type") '("SwamiguiControlHandler" "handler") '("guint" "flags") ) ) (define-function swamigui_control_unregister (c-name "swamigui_control_unregister") (return-type "none") (parameters '("GType" "widg_type") '("GType" "value_type") ) ) (define-function swamigui_control_glade_prop_connect (c-name "swamigui_control_glade_prop_connect") (return-type "none") (parameters '("GtkWidget*" "widget") '("GObject*" "obj") ) ) (define-function swamigui_control_get_alias_value_type (c-name "swamigui_control_get_alias_value_type") (return-type "GType") (parameters '("GType" "type") ) ) ;; From SwamiguiControlAdj.h (define-function swamigui_control_adj_get_type (c-name "swamigui_control_adj_get_type") (return-type "GType") ) (define-function swamigui_control_adj_new (c-name "swamigui_control_adj_new") (is-constructor-of "SwamiguiControlAdj") (return-type "SwamiguiControlAdj*") (parameters '("GtkAdjustment*" "adj") ) ) (define-method set (of-object "SwamiguiControlAdj") (c-name "swamigui_control_adj_set") (return-type "none") (parameters '("GtkAdjustment*" "adj") ) ) (define-method block_changes (of-object "SwamiguiControlAdj") (c-name "swamigui_control_adj_block_changes") (return-type "none") ) (define-method unblock_changes (of-object "SwamiguiControlAdj") (c-name "swamigui_control_adj_unblock_changes") (return-type "none") ) ;; From SwamiguiControlMidiKey.h (define-function swamigui_control_midi_key_get_type (c-name "swamigui_control_midi_key_get_type") (return-type "GType") ) (define-function swamigui_control_midi_key_new (c-name "swamigui_control_midi_key_new") (is-constructor-of "SwamiguiControlMidiKey") (return-type "SwamiguiControlMidiKey*") ) (define-method press (of-object "SwamiguiControlMidiKey") (c-name "swamigui_control_midi_key_press") (return-type "none") (parameters '("guint" "key") ) ) (define-method release (of-object "SwamiguiControlMidiKey") (c-name "swamigui_control_midi_key_release") (return-type "none") (parameters '("guint" "key") ) ) (define-method set_lower (of-object "SwamiguiControlMidiKey") (c-name "swamigui_control_midi_key_set_lower") (return-type "none") (parameters '("const-guint*" "keys") '("guint" "count") ) ) (define-method set_upper (of-object "SwamiguiControlMidiKey") (c-name "swamigui_control_midi_key_set_upper") (return-type "none") (parameters '("const-guint*" "keys") '("guint" "count") ) ) ;; From SwamiguiDnd.h ;; From SwamiguiItemMenu.h (define-function swamigui_item_menu_get_type (c-name "swamigui_item_menu_get_type") (return-type "GType") (parameters ) ) (define-function swamigui_item_menu_new (c-name "swamigui_item_menu_new") (is-constructor-of "SwamiguiItemMenu") (return-type "SwamiguiItemMenu*") (parameters ) ) (define-method add (of-object "SwamiguiItemMenu") (c-name "swamigui_item_menu_add") (return-type "GtkWidget*") (parameters '("const-SwamiguiItemMenuInfo*" "info") '("const-char*" "action_id") ) ) (define-method add_registered_info (of-object "SwamiguiItemMenu") (c-name "swamigui_item_menu_add_registered_info") (return-type "GtkWidget*") (parameters '("const-char*" "action_id") ) ) (define-method generate (of-object "SwamiguiItemMenu") (c-name "swamigui_item_menu_generate") (return-type "none") ) (define-function swamigui_register_item_menu_action (c-name "swamigui_register_item_menu_action") (return-type "none") (parameters '("char*" "action_id") '("SwamiguiItemMenuInfo*" "info") '("SwamiguiItemMenuHandler" "handler") ) ) (define-function swamigui_lookup_item_menu_action (c-name "swamigui_lookup_item_menu_action") (return-type "gboolean") (parameters '("const-char*" "action_id") '("SwamiguiItemMenuInfo**" "info") '("SwamiguiItemMenuHandler*" "handler") ) ) (define-function swamigui_register_item_menu_include_type (c-name "swamigui_register_item_menu_include_type") (return-type "none") (parameters '("const-char*" "action_id") '("GType" "type") '("gboolean" "derived") ) ) (define-function swamigui_register_item_menu_exclude_type (c-name "swamigui_register_item_menu_exclude_type") (return-type "none") (parameters '("const-char*" "action_id") '("GType" "type") '("gboolean" "derived") ) ) (define-function swamigui_test_item_menu_type (c-name "swamigui_test_item_menu_type") (return-type "gboolean") (parameters '("const-char*" "action_id") '("GType" "type") ) ) (define-function swamigui_test_item_menu_include_type (c-name "swamigui_test_item_menu_include_type") (return-type "gboolean") (parameters '("const-char*" "action_id") '("GType" "type") ) ) (define-function swamigui_test_item_menu_exclude_type (c-name "swamigui_test_item_menu_exclude_type") (return-type "gboolean") (parameters '("const-char*" "action_id") '("GType" "type") ) ) (define-method get_selection_single (of-object "SwamiguiItemMenu") (c-name "swamigui_item_menu_get_selection_single") (return-type "GObject*") ) (define-method get_selection (of-object "SwamiguiItemMenu") (c-name "swamigui_item_menu_get_selection") (return-type "IpatchList*") ) (define-method handler_single (of-object "SwamiguiItemMenu") (c-name "swamigui_item_menu_handler_single") (return-type "none") (parameters '("const-char*" "action_id") ) ) (define-method handler_multi (of-object "SwamiguiItemMenu") (c-name "swamigui_item_menu_handler_multi") (return-type "none") (parameters '("const-char*" "action_id") ) ) (define-method handler_single_all (of-object "SwamiguiItemMenu") (c-name "swamigui_item_menu_handler_single_all") (return-type "none") (parameters '("const-char*" "action_id") ) ) (define-method handler_multi_all (of-object "SwamiguiItemMenu") (c-name "swamigui_item_menu_handler_multi_all") (return-type "none") (parameters '("const-char*" "action_id") ) ) ;; From SwamiguiKnob.h (define-function swamigui_knob_get_type (c-name "swamigui_knob_get_type") (return-type "GType") ) (define-function swamigui_knob_new (c-name "swamigui_knob_new") (is-constructor-of "SwamiguiKnob") (return-type "GtkWidget*") ) (define-method get_adjustment (of-object "SwamiguiKnob") (c-name "swamigui_knob_get_adjustment") (return-type "GtkAdjustment*") ) ;; From SwamiguiLoopFinder.h (define-function swamigui_loop_finder_get_type (c-name "swamigui_loop_finder_get_type") (return-type "GType") ) (define-function swamigui_loop_finder_new (c-name "swamigui_loop_finder_new") (is-constructor-of "SwamiguiLoopFinder") (return-type "GtkWidget*") ) ;; From SwamiguiMenu.h (define-function swamigui_menu_get_type (c-name "swamigui_menu_get_type") (return-type "GType") ) (define-function swamigui_menu_new (c-name "swamigui_menu_new") (is-constructor-of "SwamiguiMenu") (return-type "GtkWidget*") ) ;; From SwamiguiModEdit.h (define-function swamigui_mod_edit_get_type (c-name "swamigui_mod_edit_get_type") (return-type "GType") ) (define-function swamigui_mod_edit_new (c-name "swamigui_mod_edit_new") (is-constructor-of "SwamiguiModEdit") (return-type "GtkWidget*") ) (define-method set_selection (of-object "SwamiguiModEdit") (c-name "swamigui_mod_edit_set_selection") (return-type "none") (parameters '("IpatchList*" "selection") ) ) ;; From SwamiguiMultiSave.h (define-function swamigui_multi_save_get_type (c-name "swamigui_multi_save_get_type") (return-type "GType") ) (define-function swamigui_multi_save_new (c-name "swamigui_multi_save_new") (is-constructor-of "SwamiguiMultiSave") (return-type "GtkWidget*") (parameters '("char*" "title") '("char*" "message") '("guint" "flags") ) ) (define-method set_selection (of-object "SwamiguiMultiSave") (c-name "swamigui_multi_save_set_selection") (return-type "none") (parameters '("IpatchList*" "selection") ) ) ;; From SwamiguiNoteSelector.h (define-function swamigui_note_selector_get_type (c-name "swamigui_note_selector_get_type") (return-type "GType") ) (define-function swamigui_note_selector_new (c-name "swamigui_note_selector_new") (is-constructor-of "SwamiguiNoteSelector") (return-type "GtkWidget*") (parameters ) ) ;; From SwamiguiPanel.h (define-function swamigui_panel_get_type (c-name "swamigui_panel_get_type") (return-type "GType") ) (define-function swamigui_panel_type_get_info (c-name "swamigui_panel_type_get_info") (return-type "none") (parameters '("GType" "type") '("char**" "label") '("char**" "blurb") '("char**" "stockid") ) ) (define-function swamigui_panel_type_check_selection (c-name "swamigui_panel_type_check_selection") (return-type "gboolean") (parameters '("GType" "type") '("IpatchList*" "selection") '("GType*" "selection_types") ) ) (define-function swamigui_panel_get_types_in_selection (c-name "swamigui_panel_get_types_in_selection") (return-type "GType*") (parameters '("IpatchList*" "selection") ) ) ;; From SwamiguiPanelSelector.h (define-function swamigui_get_panel_selector_types (c-name "swamigui_get_panel_selector_types") (return-type "GType*") ) (define-function swamigui_register_panel_selector_type (c-name "swamigui_register_panel_selector_type") (return-type "none") (parameters '("GType" "panel_type") '("int" "order") ) ) (define-function swamigui_panel_selector_get_type (c-name "swamigui_panel_selector_get_type") (return-type "GType") ) (define-function swamigui_panel_selector_new (c-name "swamigui_panel_selector_new") (is-constructor-of "SwamiguiPanelSelector") (return-type "GtkWidget*") ) (define-method set_selection (of-object "SwamiguiPanelSelector") (c-name "swamigui_panel_selector_set_selection") (return-type "none") (parameters '("IpatchList*" "items") ) ) (define-method get_selection (of-object "SwamiguiPanelSelector") (c-name "swamigui_panel_selector_get_selection") (return-type "IpatchList*") ) ;; From SwamiguiPanelSF2Gen.h (define-function swamigui_panel_sf2_gen_get_type (c-name "swamigui_panel_sf2_gen_get_type") (return-type "GType") ) (define-function swamigui_panel_sf2_gen_new (c-name "swamigui_panel_sf2_gen_new") (is-constructor-of "SwamiguiPanelSf2Gen") (return-type "GtkWidget*") ) ;; From SwamiguiPaste.h (define-function swamigui_paste_get_type (c-name "swamigui_paste_get_type") (return-type "GType") ) (define-function swamigui_paste_new (c-name "swamigui_paste_new") (is-constructor-of "SwamiguiPaste") (return-type "SwamiguiPaste*") ) (define-method process (of-object "SwamiguiPaste") (c-name "swamigui_paste_process") (return-type "gboolean") ) (define-method set_items (of-object "SwamiguiPaste") (c-name "swamigui_paste_set_items") (return-type "none") (parameters '("IpatchItem*" "dstitem") '("GList*" "srcitems") ) ) (define-method get_conflict_items (of-object "SwamiguiPaste") (c-name "swamigui_paste_get_conflict_items") (return-type "none") (parameters '("IpatchItem**" "src") '("IpatchItem**" "dest") ) ) (define-method set_conflict_items (of-object "SwamiguiPaste") (c-name "swamigui_paste_set_conflict_items") (return-type "none") (parameters '("IpatchItem*" "src") '("IpatchItem*" "dest") ) ) (define-method push_state (of-object "SwamiguiPaste") (c-name "swamigui_paste_push_state") (return-type "none") (parameters '("gpointer" "state") ) ) (define-method pop_state (of-object "SwamiguiPaste") (c-name "swamigui_paste_pop_state") (return-type "gpointer") ) ;; From SwamiguiPiano.h (define-function swamigui_piano_get_type (c-name "swamigui_piano_get_type") (return-type "GType") ) (define-method note_on (of-object "SwamiguiPiano") (c-name "swamigui_piano_note_on") (return-type "none") (parameters '("int" "note") '("int" "velocity") ) ) (define-method note_off (of-object "SwamiguiPiano") (c-name "swamigui_piano_note_off") (return-type "none") (parameters '("int" "note") '("int" "velocity") ) ) (define-method pos_to_note (of-object "SwamiguiPiano") (c-name "swamigui_piano_pos_to_note") (return-type "int") (parameters '("double" "x") '("double" "y") '("int*" "velocity") '("gboolean*" "isblack") ) ) (define-method note_to_pos (of-object "SwamiguiPiano") (c-name "swamigui_piano_note_to_pos") (return-type "double") (parameters '("int" "note") '("int" "edge") '("gboolean" "realnote") '("gboolean*" "isblack") ) ) ;; From SwamiguiPref.h (define-function swamigui_register_pref_handler (c-name "swamigui_register_pref_handler") (return-type "none") (parameters '("const-char*" "name") '("const-char*" "icon") '("int" "order") '("SwamiguiPrefHandler" "handler") ) ) (define-function swamigui_pref_get_type (c-name "swamigui_pref_get_type") (return-type "GType") ) (define-function swamigui_pref_new (c-name "swamigui_pref_new") (is-constructor-of "SwamiguiPref") (return-type "GtkWidget*") ) ;; From SwamiguiProp.h (define-function swamigui_register_prop_glade_widg (c-name "swamigui_register_prop_glade_widg") (return-type "none") (parameters '("GType" "objtype") '("const-char*" "name") ) ) (define-function swamigui_register_prop_handler (c-name "swamigui_register_prop_handler") (return-type "none") (parameters '("GType" "objtype") '("SwamiguiPropHandler" "handler") ) ) (define-function swamigui_prop_get_type (c-name "swamigui_prop_get_type") (return-type "GType") ) (define-function swamigui_prop_new (c-name "swamigui_prop_new") (is-constructor-of "SwamiguiProp") (return-type "GtkWidget*") ) (define-method set_selection (of-object "SwamiguiProp") (c-name "swamigui_prop_set_selection") (return-type "none") (parameters '("IpatchList*" "selection") ) ) ;; From SwamiguiPythonView.h (define-function swamigui_python_view_get_type (c-name "swamigui_python_view_get_type") (return-type "GType") ) (define-function swamigui_python_view_new (c-name "swamigui_python_view_new") (is-constructor-of "SwamiguiPythonView") (return-type "GtkWidget*") (parameters ) ) ;; From SwamiguiRoot.h (define-function swamigui_init (c-name "swamigui_init") (return-type "none") (parameters '("int*" "argc") '("char**[]" "argv") ) ) (define-function swamigui_root_get_type (c-name "swamigui_root_get_type") (return-type "GType") ) (define-function swamigui_root_new (c-name "swamigui_root_new") (is-constructor-of "SwamiguiRoot") (return-type "SwamiguiRoot*") ) (define-method activate (of-object "SwamiguiRoot") (c-name "swamigui_root_activate") (return-type "none") ) (define-method quit (of-object "SwamiguiRoot") (c-name "swamigui_root_quit") (return-type "none") ) (define-function swamigui_get_root (c-name "swamigui_get_root") (return-type "SwamiguiRoot*") (parameters '("gpointer" "gobject") ) ) (define-method save_prefs (of-object "SwamiguiRoot") (c-name "swamigui_root_save_prefs") (return-type "gboolean") ) (define-method load_prefs (of-object "SwamiguiRoot") (c-name "swamigui_root_load_prefs") (return-type "gboolean") ) ;; From SwamiguiSampleCanvas.h (define-function swamigui_sample_canvas_get_type (c-name "swamigui_sample_canvas_get_type") (return-type "GType") ) (define-method set_sample (of-object "SwamiguiSampleCanvas") (c-name "swamigui_sample_canvas_set_sample") (return-type "none") (parameters '("IpatchSampleData*" "sample") ) ) (define-method xpos_to_sample (of-object "SwamiguiSampleCanvas") (c-name "swamigui_sample_canvas_xpos_to_sample") (return-type "int") (parameters '("int" "xpos") '("int*" "onsample") ) ) (define-method sample_to_xpos (of-object "SwamiguiSampleCanvas") (c-name "swamigui_sample_canvas_sample_to_xpos") (return-type "int") (parameters '("int" "index") '("int*" "inview") ) ) ;; From SwamiguiSampleEditor.h (define-function swamigui_sample_editor_get_type (c-name "swamigui_sample_editor_get_type") (return-type "GType") ) (define-function swamigui_sample_editor_new (c-name "swamigui_sample_editor_new") (is-constructor-of "SwamiguiSampleEditor") (return-type "GtkWidget*") ) (define-method zoom_ofs (of-object "SwamiguiSampleEditor") (c-name "swamigui_sample_editor_zoom_ofs") (return-type "none") (parameters '("double" "zoom_amt") '("double" "zoom_xpos") ) ) (define-method scroll_ofs (of-object "SwamiguiSampleEditor") (c-name "swamigui_sample_editor_scroll_ofs") (return-type "none") (parameters '("int" "sample_ofs") ) ) (define-method loop_zoom (of-object "SwamiguiSampleEditor") (c-name "swamigui_sample_editor_loop_zoom") (return-type "none") (parameters '("double" "zoom_amt") ) ) (define-method set_selection (of-object "SwamiguiSampleEditor") (c-name "swamigui_sample_editor_set_selection") (return-type "none") (parameters '("IpatchList*" "items") ) ) (define-method get_selection (of-object "SwamiguiSampleEditor") (c-name "swamigui_sample_editor_get_selection") (return-type "IpatchList*") ) (define-function swamigui_sample_editor_register_handler (c-name "swamigui_sample_editor_register_handler") (return-type "none") (parameters '("SwamiguiSampleEditorHandler" "handler") '("SwamiguiPanelCheckFunc" "check_func") ) ) (define-function swamigui_sample_editor_unregister_handler (c-name "swamigui_sample_editor_unregister_handler") (return-type "none") (parameters '("SwamiguiSampleEditorHandler" "handler") ) ) (define-method reset (of-object "SwamiguiSampleEditor") (c-name "swamigui_sample_editor_reset") (return-type "none") ) (define-method get_loop_controls (of-object "SwamiguiSampleEditor") (c-name "swamigui_sample_editor_get_loop_controls") (return-type "none") (parameters '("SwamiControl**" "loop_start") '("SwamiControl**" "loop_end") ) ) (define-method add_track (of-object "SwamiguiSampleEditor") (c-name "swamigui_sample_editor_add_track") (return-type "int") (parameters '("IpatchSampleData*" "sample") '("gboolean" "right_chan") ) ) (define-method get_track_info (of-object "SwamiguiSampleEditor") (c-name "swamigui_sample_editor_get_track_info") (return-type "gboolean") (parameters '("guint" "track") '("IpatchSampleData**" "sample") '("SwamiguiSampleCanvas**" "sample_view") '("SwamiguiSampleCanvas**" "loop_view") ) ) (define-method remove_track (of-object "SwamiguiSampleEditor") (c-name "swamigui_sample_editor_remove_track") (return-type "none") (parameters '("guint" "track") ) ) (define-method remove_all_tracks (of-object "SwamiguiSampleEditor") (c-name "swamigui_sample_editor_remove_all_tracks") (return-type "none") ) (define-method add_marker (of-object "SwamiguiSampleEditor") (c-name "swamigui_sample_editor_add_marker") (return-type "guint") (parameters '("guint" "flags") '("SwamiControl**" "start") '("SwamiControl**" "end") ) ) (define-method get_marker_info (of-object "SwamiguiSampleEditor") (c-name "swamigui_sample_editor_get_marker_info") (return-type "gboolean") (parameters '("guint" "marker") '("guint*" "flags") '("GnomeCanvasItem**" "start_line") '("GnomeCanvasItem**" "end_line") '("SwamiControl**" "start_ctrl") '("SwamiControl**" "end_ctrl") ) ) (define-method set_marker (of-object "SwamiguiSampleEditor") (c-name "swamigui_sample_editor_set_marker") (return-type "none") (parameters '("guint" "marker") '("guint" "start") '("guint" "end") ) ) (define-method remove_marker (of-object "SwamiguiSampleEditor") (c-name "swamigui_sample_editor_remove_marker") (return-type "none") (parameters '("guint" "marker") ) ) (define-method remove_all_markers (of-object "SwamiguiSampleEditor") (c-name "swamigui_sample_editor_remove_all_markers") (return-type "none") ) (define-method show_marker (of-object "SwamiguiSampleEditor") (c-name "swamigui_sample_editor_show_marker") (return-type "none") (parameters '("guint" "marker") '("gboolean" "show_marker") ) ) (define-method set_loop_types (of-object "SwamiguiSampleEditor") (c-name "swamigui_sample_editor_set_loop_types") (return-type "none") (parameters '("int*" "types") '("gboolean" "loop_play_btn") ) ) (define-method set_active_loop_type (of-object "SwamiguiSampleEditor") (c-name "swamigui_sample_editor_set_active_loop_type") (return-type "none") (parameters '("int" "type") ) ) ;; From SwamiguiSpectrumCanvas.h (define-function swamigui_spectrum_canvas_get_type (c-name "swamigui_spectrum_canvas_get_type") (return-type "GType") ) (define-method set_data (of-object "SwamiguiSpectrumCanvas") (c-name "swamigui_spectrum_canvas_set_data") (return-type "none") (parameters '("double*" "spectrum") '("guint" "size") '("SwamiguiSpectrumDestroyNotify" "notify") ) ) (define-method pos_to_spectrum (of-object "SwamiguiSpectrumCanvas") (c-name "swamigui_spectrum_canvas_pos_to_spectrum") (return-type "int") (parameters '("int" "xpos") ) ) (define-method spectrum_to_pos (of-object "SwamiguiSpectrumCanvas") (c-name "swamigui_spectrum_canvas_spectrum_to_pos") (return-type "int") (parameters '("int" "index") ) ) ;; From SwamiguiSpinScale.h (define-function swamigui_spin_scale_get_type (c-name "swamigui_spin_scale_get_type") (return-type "GType") ) (define-function swamigui_spin_scale_new (c-name "swamigui_spin_scale_new") (is-constructor-of "SwamiguiSpinScale") (return-type "GtkWidget*") ) (define-method set_order (of-object "SwamiguiSpinScale") (c-name "swamigui_spin_scale_set_order") (return-type "none") (parameters '("gboolean" "scale_first") ) ) ;; From SwamiguiSplits.h (define-function swamigui_splits_get_type (c-name "swamigui_splits_get_type") (return-type "GType") ) (define-function swamigui_splits_new (c-name "swamigui_splits_new") (is-constructor-of "SwamiguiSplits") (return-type "GtkWidget*") ) (define-method set_mode (of-object "SwamiguiSplits") (c-name "swamigui_splits_set_mode") (return-type "none") (parameters '("SwamiguiSplitsMode" "mode") ) ) (define-method set_width (of-object "SwamiguiSplits") (c-name "swamigui_splits_set_width") (return-type "none") (parameters '("int" "width") ) ) (define-method set_selection (of-object "SwamiguiSplits") (c-name "swamigui_splits_set_selection") (return-type "none") (parameters '("IpatchList*" "items") ) ) (define-method get_selection (of-object "SwamiguiSplits") (c-name "swamigui_splits_get_selection") (return-type "IpatchList*") ) (define-method select_items (of-object "SwamiguiSplits") (c-name "swamigui_splits_select_items") (return-type "none") (parameters '("GList*" "items") ) ) (define-method select_all (of-object "SwamiguiSplits") (c-name "swamigui_splits_select_all") (return-type "none") ) (define-method unselect_all (of-object "SwamiguiSplits") (c-name "swamigui_splits_unselect_all") (return-type "none") ) (define-function swamigui_splits_register_handler (c-name "swamigui_splits_register_handler") (return-type "none") (parameters '("SwamiguiSplitsHandler" "handler") ) ) (define-function swamigui_splits_unregister_handler (c-name "swamigui_splits_unregister_handler") (return-type "none") (parameters '("SwamiguiSplitsHandler" "handler") ) ) (define-method insert (of-object "SwamiguiSplits") (c-name "swamigui_splits_insert") (return-type "SwamiguiSplitsEntry*") (parameters '("GObject*" "item") '("int" "index") ) ) (define-method lookup_entry (of-object "SwamiguiSplits") (c-name "swamigui_splits_lookup_entry") (return-type "SwamiguiSplitsEntry*") (parameters '("GObject*" "item") ) ) (define-method remove (of-object "SwamiguiSplits") (c-name "swamigui_splits_remove") (return-type "none") (parameters '("GObject*" "item") ) ) (define-method remove_all (of-object "SwamiguiSplits") (c-name "swamigui_splits_remove_all") (return-type "none") ) (define-method set_span_range (of-object "SwamiguiSplits") (c-name "swamigui_splits_set_span_range") (return-type "none") (parameters '("GObject*" "item") '("int" "low") '("int" "high") ) ) (define-method set_root_note (of-object "SwamiguiSplits") (c-name "swamigui_splits_set_root_note") (return-type "none") (parameters '("GObject*" "item") '("int" "val") ) ) (define-method get_span_control (of-object "SwamiguiSplitsEntry") (c-name "swamigui_splits_entry_get_span_control") (return-type "SwamiControl*") ) (define-method get_root_note_control (of-object "SwamiguiSplitsEntry") (c-name "swamigui_splits_entry_get_root_note_control") (return-type "SwamiControl*") ) (define-method get_index (of-object "SwamiguiSplitsEntry") (c-name "swamigui_splits_entry_get_index") (return-type "int") ) ;; From SwamiguiStatusbar.h (define-function swamigui_statusbar_get_type (c-name "swamigui_statusbar_get_type") (return-type "GType") ) (define-function swamigui_statusbar_new (c-name "swamigui_statusbar_new") (is-constructor-of "SwamiguiStatusbar") (return-type "GtkWidget*") ) (define-method add (of-object "SwamiguiStatusbar") (c-name "swamigui_statusbar_add") (return-type "guint") (parameters '("const-char*" "group") '("int" "timeout") '("guint" "pos") '("GtkWidget*" "widg") ) ) (define-method remove (of-object "SwamiguiStatusbar") (c-name "swamigui_statusbar_remove") (return-type "none") (parameters '("guint" "id") '("const-char*" "group") ) ) (define-method printf (of-object "SwamiguiStatusbar") (c-name "swamigui_statusbar_printf") (return-type "none") (parameters '("const-char*" "format") ) (varargs #t) ) (define-function swamigui_statusbar_msg_label_new (c-name "swamigui_statusbar_msg_label_new") (is-constructor-of "SwamiguiStatusbarMsgLabel") (return-type "GtkWidget*") (parameters '("const-char*" "label") '("guint" "maxlen") ) ) (define-function swamigui_statusbar_msg_progress_new (c-name "swamigui_statusbar_msg_progress_new") (is-constructor-of "SwamiguiStatusbarMsgProgress") (return-type "GtkWidget*") (parameters '("const-char*" "label") '("SwamiguiStatusbarCloseFunc" "close") ) ) (define-method msg_set_timeout (of-object "SwamiguiStatusbar") (c-name "swamigui_statusbar_msg_set_timeout") (return-type "none") (parameters '("guint" "id") '("const-char*" "group") '("int" "timeout") ) ) (define-method msg_set_label (of-object "SwamiguiStatusbar") (c-name "swamigui_statusbar_msg_set_label") (return-type "none") (parameters '("guint" "id") '("const-char*" "group") '("const-char*" "label") ) ) (define-method msg_set_progress (of-object "SwamiguiStatusbar") (c-name "swamigui_statusbar_msg_set_progress") (return-type "none") (parameters '("guint" "id") '("const-char*" "group") '("double" "val") ) ) ;; From SwamiguiTree.h (define-function swamigui_tree_get_type (c-name "swamigui_tree_get_type") (return-type "GType") ) (define-function swamigui_tree_new (c-name "swamigui_tree_new") (is-constructor-of "SwamiguiTree") (return-type "GtkWidget*") (parameters '("IpatchList*" "stores") ) ) (define-method set_store_list (of-object "SwamiguiTree") (c-name "swamigui_tree_set_store_list") (return-type "none") (parameters '("IpatchList*" "list") ) ) (define-method get_store_list (of-object "SwamiguiTree") (c-name "swamigui_tree_get_store_list") (return-type "IpatchList*") ) (define-method set_selected_store (of-object "SwamiguiTree") (c-name "swamigui_tree_set_selected_store") (return-type "none") (parameters '("SwamiguiTreeStore*" "store") ) ) (define-method get_selected_store (of-object "SwamiguiTree") (c-name "swamigui_tree_get_selected_store") (return-type "SwamiguiTreeStore*") ) (define-method get_selection_single (of-object "SwamiguiTree") (c-name "swamigui_tree_get_selection_single") (return-type "GObject*") ) (define-method get_selection (of-object "SwamiguiTree") (c-name "swamigui_tree_get_selection") (return-type "IpatchList*") ) (define-method clear_selection (of-object "SwamiguiTree") (c-name "swamigui_tree_clear_selection") (return-type "none") ) (define-method set_selection (of-object "SwamiguiTree") (c-name "swamigui_tree_set_selection") (return-type "none") (parameters '("IpatchList*" "list") ) ) (define-method spotlight_item (of-object "SwamiguiTree") (c-name "swamigui_tree_spotlight_item") (return-type "none") (parameters '("GObject*" "item") ) ) (define-method search_set_start (of-object "SwamiguiTree") (c-name "swamigui_tree_search_set_start") (return-type "none") (parameters '("GObject*" "start") ) ) (define-method search_set_text (of-object "SwamiguiTree") (c-name "swamigui_tree_search_set_text") (return-type "none") (parameters '("const-char*" "text") ) ) (define-method search_set_visible (of-object "SwamiguiTree") (c-name "swamigui_tree_search_set_visible") (return-type "none") (parameters '("gboolean" "visible") ) ) (define-method search_next (of-object "SwamiguiTree") (c-name "swamigui_tree_search_next") (return-type "none") ) (define-method search_prev (of-object "SwamiguiTree") (c-name "swamigui_tree_search_prev") (return-type "none") ) ;; From SwamiguiTreeStore.h (define-function swamigui_tree_store_get_type (c-name "swamigui_tree_store_get_type") (return-type "GType") ) (define-method insert (of-object "SwamiguiTreeStore") (c-name "swamigui_tree_store_insert") (return-type "none") (parameters '("GObject*" "item") '("const-char*" "label") '("char*" "icon") '("GtkTreeIter*" "parent") '("int" "pos") '("GtkTreeIter*" "out_iter") ) ) (define-method insert_before (of-object "SwamiguiTreeStore") (c-name "swamigui_tree_store_insert_before") (return-type "none") (parameters '("GObject*" "item") '("const-char*" "label") '("char*" "icon") '("GtkTreeIter*" "parent") '("GtkTreeIter*" "sibling") '("GtkTreeIter*" "out_iter") ) ) (define-method insert_after (of-object "SwamiguiTreeStore") (c-name "swamigui_tree_store_insert_after") (return-type "none") (parameters '("GObject*" "item") '("const-char*" "label") '("char*" "icon") '("GtkTreeIter*" "parent") '("GtkTreeIter*" "sibling") '("GtkTreeIter*" "out_iter") ) ) (define-method change (of-object "SwamiguiTreeStore") (c-name "swamigui_tree_store_change") (return-type "none") (parameters '("GObject*" "item") '("const-char*" "label") '("char*" "icon") ) ) (define-method remove (of-object "SwamiguiTreeStore") (c-name "swamigui_tree_store_remove") (return-type "none") (parameters '("GObject*" "item") ) ) (define-method move_before (of-object "SwamiguiTreeStore") (c-name "swamigui_tree_store_move_before") (return-type "none") (parameters '("GObject*" "item") '("GtkTreeIter*" "position") ) ) (define-method move_after (of-object "SwamiguiTreeStore") (c-name "swamigui_tree_store_move_after") (return-type "none") (parameters '("GObject*" "item") '("GtkTreeIter*" "position") ) ) (define-method item_get_node (of-object "SwamiguiTreeStore") (c-name "swamigui_tree_store_item_get_node") (return-type "gboolean") (parameters '("GObject*" "item") '("GtkTreeIter*" "iter") ) ) (define-method node_get_item (of-object "SwamiguiTreeStore") (c-name "swamigui_tree_store_node_get_item") (return-type "GObject*") (parameters '("GtkTreeIter*" "iter") ) ) (define-method add (of-object "SwamiguiTreeStore") (c-name "swamigui_tree_store_add") (return-type "none") (parameters '("GObject*" "item") ) ) (define-method changed (of-object "SwamiguiTreeStore") (c-name "swamigui_tree_store_changed") (return-type "none") (parameters '("GObject*" "item") ) ) ;; From SwamiguiTreeStorePatch.h (define-function swamigui_tree_store_patch_get_type (c-name "swamigui_tree_store_patch_get_type") (return-type "GType") ) (define-function swamigui_tree_store_patch_new (c-name "swamigui_tree_store_patch_new") (is-constructor-of "SwamiguiTreeStorePatch") (return-type "SwamiguiTreeStorePatch*") ) (define-method patch_item_add (of-object "SwamiguiTreeStore") (c-name "swamigui_tree_store_patch_item_add") (return-type "none") (parameters '("GObject*" "item") ) ) (define-method patch_item_changed (of-object "SwamiguiTreeStore") (c-name "swamigui_tree_store_patch_item_changed") (return-type "none") (parameters '("GObject*" "item") ) ) ;; From builtin_enums.h (define-function swamigui_bar_ptr_type_get_type (c-name "swamigui_bar_ptr_type_get_type") (return-type "GType") ) (define-function swamigui_canvas_mod_type_get_type (c-name "swamigui_canvas_mod_type_get_type") (return-type "GType") ) (define-function swamigui_canvas_mod_axis_get_type (c-name "swamigui_canvas_mod_axis_get_type") (return-type "GType") ) (define-function swamigui_canvas_mod_flags_get_type (c-name "swamigui_canvas_mod_flags_get_type") (return-type "GType") ) (define-function swamigui_canvas_mod_actions_get_type (c-name "swamigui_canvas_mod_actions_get_type") (return-type "GType") ) (define-function swamigui_control_rank_get_type (c-name "swamigui_control_rank_get_type") (return-type "GType") ) (define-function swamigui_control_flags_get_type (c-name "swamigui_control_flags_get_type") (return-type "GType") ) (define-function swamigui_control_object_flags_get_type (c-name "swamigui_control_object_flags_get_type") (return-type "GType") ) (define-function swamigui_item_menu_flags_get_type (c-name "swamigui_item_menu_flags_get_type") (return-type "GType") ) (define-function swamigui_paste_status_get_type (c-name "swamigui_paste_status_get_type") (return-type "GType") ) (define-function swamigui_paste_decision_get_type (c-name "swamigui_paste_decision_get_type") (return-type "GType") ) (define-function swamigui_quit_confirm_get_type (c-name "swamigui_quit_confirm_get_type") (return-type "GType") ) (define-function swamigui_sample_editor_status_get_type (c-name "swamigui_sample_editor_status_get_type") (return-type "GType") ) (define-function swamigui_sample_editor_marker_flags_get_type (c-name "swamigui_sample_editor_marker_flags_get_type") (return-type "GType") ) (define-function swamigui_sample_editor_marker_id_get_type (c-name "swamigui_sample_editor_marker_id_get_type") (return-type "GType") ) (define-function swamigui_splits_mode_get_type (c-name "swamigui_splits_mode_get_type") (return-type "GType") ) (define-function swamigui_splits_status_get_type (c-name "swamigui_splits_status_get_type") (return-type "GType") ) (define-function swamigui_splits_move_flags_get_type (c-name "swamigui_splits_move_flags_get_type") (return-type "GType") ) (define-function swamigui_statusbar_pos_get_type (c-name "swamigui_statusbar_pos_get_type") (return-type "GType") ) (define-function swamigui_statusbar_timeout_get_type (c-name "swamigui_statusbar_timeout_get_type") (return-type "GType") ) ;; From help.h (define-function swamigui_help_about (c-name "swamigui_help_about") (return-type "none") ) (define-function swamigui_help_swamitips_create (c-name "swamigui_help_swamitips_create") (return-type "none") (parameters '("SwamiguiRoot*" "root") ) ) ;; From icons.h (define-function swamigui_icon_get_category_icon (c-name "swamigui_icon_get_category_icon") (return-type "char*") (parameters '("int" "category") ) ) ;; From patch_funcs.h (define-function swamigui_load_files (c-name "swamigui_load_files") (return-type "none") (parameters '("SwamiguiRoot*" "root") ) ) (define-function swamigui_save_files (c-name "swamigui_save_files") (return-type "none") (parameters '("IpatchList*" "item_list") '("gboolean" "saveas") ) ) (define-function swamigui_close_files (c-name "swamigui_close_files") (return-type "none") (parameters '("IpatchList*" "item_list") ) ) (define-function swamigui_delete_items (c-name "swamigui_delete_items") (return-type "none") (parameters '("IpatchList*" "item_list") ) ) (define-function swamigui_wtbl_load_patch (c-name "swamigui_wtbl_load_patch") (return-type "none") (parameters '("IpatchItem*" "item") ) ) (define-function swamigui_new_item (c-name "swamigui_new_item") (return-type "none") (parameters '("IpatchItem*" "parent_hint") '("GType" "type") ) ) (define-function swamigui_goto_link_item (c-name "swamigui_goto_link_item") (return-type "none") (parameters '("IpatchItem*" "item") '("SwamiguiTree*" "tree") ) ) (define-function swamigui_load_samples (c-name "swamigui_load_samples") (return-type "none") (parameters '("IpatchItem*" "parent_hint") ) ) (define-function swamigui_export_samples (c-name "swamigui_export_samples") (return-type "none") (parameters '("IpatchList*" "samples") ) ) (define-function swamigui_copy_items (c-name "swamigui_copy_items") (return-type "none") (parameters '("IpatchList*" "items") ) ) (define-function swamigui_paste_items (c-name "swamigui_paste_items") (return-type "none") (parameters '("IpatchItem*" "dstitem") '("GList*" "items") ) ) ;; From splash.h (define-function swamigui_splash_display (c-name "swamigui_splash_display") (return-type "none") (parameters '("guint" "timeout") ) ) (define-function swamigui_splash_kill (c-name "swamigui_splash_kill") (return-type "gboolean") ) ;; From swami_python.h (define-function swamigui_python_set_output_func (c-name "swamigui_python_set_output_func") (return-type "none") (parameters '("SwamiguiPythonOutputFunc" "func") ) ) (define-function swamigui_python_set_root (c-name "swamigui_python_set_root") (return-type "none") ) (define-function swamigui_python_is_initialized (c-name "swamigui_python_is_initialized") (return-type "gboolean") ) ;; From util.h (define-function swamigui_util_init (c-name "swamigui_util_init") (return-type "none") ) (define-function swamigui_util_unit_rgba_color_get_type (c-name "swamigui_util_unit_rgba_color_get_type") (return-type "guint") ) (define-function swamigui_util_canvas_line_set (c-name "swamigui_util_canvas_line_set") (return-type "none") (parameters '("GnomeCanvasItem*" "item") '("double" "x1") '("double" "y1") '("double" "x2") '("double" "y2") ) ) (define-function swamigui_util_quick_popup (c-name "swamigui_util_quick_popup") (return-type "GtkWidget*") (parameters '("gchar*" "msg") '("gchar*" "btn1") ) (varargs #t) ) (define-function swamigui_util_lookup_unique_dialog (c-name "swamigui_util_lookup_unique_dialog") (return-type "GtkWidget*") (parameters '("gchar*" "strkey") '("gint" "key2") ) ) (define-function swamigui_util_register_unique_dialog (c-name "swamigui_util_register_unique_dialog") (return-type "gboolean") (parameters '("GtkWidget*" "dialog") '("gchar*" "strkey") '("gint" "key2") ) ) (define-function swamigui_util_unregister_unique_dialog (c-name "swamigui_util_unregister_unique_dialog") (return-type "none") (parameters '("GtkWidget*" "dialog") ) ) (define-function swamigui_util_activate_unique_dialog (c-name "swamigui_util_activate_unique_dialog") (return-type "gboolean") (parameters '("gchar*" "strkey") '("gint" "key2") ) ) (define-function swamigui_util_waitfor_widget_action (c-name "swamigui_util_waitfor_widget_action") (return-type "gpointer") (parameters '("GtkWidget*" "widg") ) ) (define-function swamigui_util_widget_action (c-name "swamigui_util_widget_action") (return-type "none") (parameters '("GtkWidget*" "cbwidg") '("gpointer" "value") ) ) (define-function swamigui_util_glade_create (c-name "swamigui_util_glade_create") (return-type "GtkWidget*") (parameters '("const-char*" "name") ) ) (define-function swamigui_util_glade_lookup (c-name "swamigui_util_glade_lookup") (return-type "GtkWidget*") (parameters '("GtkWidget*" "widget") '("const-char*" "name") ) ) (define-function swamigui_util_glade_lookup_nowarn (c-name "swamigui_util_glade_lookup_nowarn") (return-type "GtkWidget*") (parameters '("GtkWidget*" "widget") '("const-char*" "name") ) ) (define-function swamigui_util_option_menu_index (c-name "swamigui_util_option_menu_index") (return-type "int") (parameters '("GtkWidget*" "opmenu") ) ) (define-function swamigui_util_str_crlf2lf (c-name "swamigui_util_str_crlf2lf") (return-type "char*") (parameters '("char*" "str") ) ) (define-function swamigui_util_str_lf2crlf (c-name "swamigui_util_str_lf2crlf") (return-type "char*") (parameters '("char*" "str") ) ) (define-function swamigui_util_substrcmp (c-name "swamigui_util_substrcmp") (return-type "int") (parameters '("char*" "sub") '("char*" "str") ) ) swami/src/python/swamigui_missing.h0000644000175000017500000000207411474034033017717 0ustar alessioalessio/* * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* * swamigui_missing.h: Provides missing type definitions for * swamiguimodule that should probably be handled by other library bindings. */ #include #define NO_IMPORT_PYGOBJECT #include "pygobject.h" extern PyTypeObject PyGnomeCanvasItem_Type; extern PyTypeObject PyGnomeCanvasGroup_Type; swami/src/python/swami.override0000644000175000017500000000233610427621306017054 0ustar alessioalessio/* -*- Mode: C -*- * * swami.override - Function override for libswami python binding * * Swami * Copyright (C) 1999-2002 Josh Green * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser 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 */ %% headers #include #include "pygobject.h" #include #include #include "swami_missing.h" %% modulename Swami %% import gobject.GObject as PyGObject_Type import ipatch.Container as PyIpatchContainer_Type import ipatch.Item as PyIpatchItem_Type %% ignore-glob *_get_type swami/src/python/swami_missing.h0000644000175000017500000000200511474034033017204 0ustar alessioalessio/* * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* * swami_missing.h: Provides missing type definitions for swamimodule * that should probably be handled by other library bindings. */ #include #define NO_IMPORT_PYGOBJECT #include "pygobject.h" extern PyTypeObject PyGTypeModule_Type; swami/src/python/swamimodule.c0000644000175000017500000000313311474034033016657 0ustar alessioalessio/* * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define NO_IMPORT_PYGOBJECT #include #include #include #include "swami_missing.h" void pyswami_register_missing_classes (PyObject *d); void pyswami_register_classes (PyObject *d); void pyswami_add_constants(PyObject *module, const gchar *strip_prefix); extern PyMethodDef pyswami_functions[]; DL_EXPORT(void) initswami(void) { PyObject *m, *d; init_pygobject (); swami_init (); /* initialize libswami */ m = Py_InitModule ("swami", pyswami_functions); d = PyModule_GetDict (m); pyswami_register_missing_classes (d); pyswami_register_classes (d); pyswami_add_constants(m, "SWAMI_"); if (PyErr_Occurred ()) { PyErr_Print (); Py_FatalError ("can't initialise module swami"); } } swami/src/python/swami_missing.c0000644000175000017500000000656611474034033017217 0ustar alessioalessio/* * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #define NO_IMPORT_PYGOBJECT #include static PyTypeObject *_PyGObject_Type; #define PyGObject_Type (*_PyGObject_Type) PyTypeObject PyGTypeModule_Type; static int pygobject_no_constructor(PyObject *self, PyObject *args, PyObject *kwargs) { gchar buf[512]; g_snprintf(buf, sizeof(buf), "%s is an abstract widget", self->ob_type->tp_name); PyErr_SetString(PyExc_NotImplementedError, buf); return -1; } PyTypeObject PyGTypeModule_Type = { PyObject_HEAD_INIT(NULL) 0, /* ob_size */ "Swami.GTypeModule", /* tp_name */ sizeof(PyGObject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor)0, /* tp_dealloc */ (printfunc)0, /* tp_print */ (getattrfunc)0, /* tp_getattr */ (setattrfunc)0, /* tp_setattr */ (cmpfunc)0, /* tp_compare */ (reprfunc)0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ (hashfunc)0, /* tp_hash */ (ternaryfunc)0, /* tp_call */ (reprfunc)0, /* tp_str */ (getattrofunc)0, /* tp_getattro */ (setattrofunc)0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ NULL, /* Documentation string */ (traverseproc)0, /* tp_traverse */ (inquiry)0, /* tp_clear */ (richcmpfunc)0, /* tp_richcompare */ offsetof(PyGObject, weakreflist), /* tp_weaklistoffset */ (getiterfunc)0, /* tp_iter */ (iternextfunc)0, /* tp_iternext */ NULL, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ NULL, /* tp_base */ NULL, /* tp_dict */ (descrgetfunc)0, /* tp_descr_get */ (descrsetfunc)0, /* tp_descr_set */ offsetof(PyGObject, inst_dict), /* tp_dictoffset */ (initproc)pygobject_no_constructor, /* tp_init */ }; /* intialise stuff extension classes */ void pyswami_register_missing_classes (PyObject *d) { PyObject *module; if ((module = PyImport_ImportModule("gobject")) != NULL) { PyObject *moddict = PyModule_GetDict(module); _PyGObject_Type = (PyTypeObject *)PyDict_GetItemString(moddict, "GObject"); if (_PyGObject_Type == NULL) { PyErr_SetString(PyExc_ImportError, "cannot import name GObject from gobject"); return; } } else { PyErr_SetString(PyExc_ImportError, "could not import gobject"); return; } pygobject_register_class(d, "GTypeModule", G_TYPE_TYPE_MODULE, &PyGTypeModule_Type, Py_BuildValue("(O)", &PyGObject_Type)); } swami/src/python/swami.defs0000644000175000017500000011511311456655605016170 0ustar alessioalessio;; -*- scheme -*- ; object definitions ... (define-object Lock (in-module "Swami") (parent "GObject") (c-name "SwamiLock") (gtype-id "SWAMI_TYPE_LOCK") ) (define-object ControlQueue (in-module "Swami") (parent "SwamiLock") (c-name "SwamiControlQueue") (gtype-id "SWAMI_TYPE_CONTROL_QUEUE") ) (define-object Control (in-module "Swami") (parent "SwamiLock") (c-name "SwamiControl") (gtype-id "SWAMI_TYPE_CONTROL") ) (define-object ControlValue (in-module "Swami") (parent "SwamiControl") (c-name "SwamiControlValue") (gtype-id "SWAMI_TYPE_CONTROL_VALUE") ) (define-object ControlProp (in-module "Swami") (parent "SwamiControl") (c-name "SwamiControlProp") (gtype-id "SWAMI_TYPE_CONTROL_PROP") ) (define-object ControlHub (in-module "Swami") (parent "SwamiControl") (c-name "SwamiControlHub") (gtype-id "SWAMI_TYPE_CONTROL_HUB") ) (define-object ControlFunc (in-module "Swami") (parent "SwamiControl") (c-name "SwamiControlFunc") (gtype-id "SWAMI_TYPE_CONTROL_FUNC") ) (define-object ControlMidi (in-module "Swami") (parent "SwamiControlFunc") (c-name "SwamiControlMidi") (gtype-id "SWAMI_TYPE_CONTROL_MIDI") ) (define-object MidiDevice (in-module "Swami") (parent "SwamiLock") (c-name "SwamiMidiDevice") (gtype-id "SWAMI_TYPE_MIDI_DEVICE") ) (define-object Plugin (in-module "Swami") (parent "GTypeModule") (c-name "SwamiPlugin") (gtype-id "SWAMI_TYPE_PLUGIN") ) (define-object PropTree (in-module "Swami") (parent "SwamiLock") (c-name "SwamiPropTree") (gtype-id "SWAMI_TYPE_PROP_TREE") ) (define-object Root (in-module "Swami") (parent "SwamiLock") (c-name "SwamiRoot") (gtype-id "SWAMI_TYPE_ROOT") ) (define-object Wavetbl (in-module "Swami") (parent "SwamiLock") (c-name "SwamiWavetbl") (gtype-id "SWAMI_TYPE_WAVETBL") ) ;; Enumerations and flags ... (define-flags ControlFlags (in-module "Swami") (c-name "SwamiControlFlags") (gtype-id "SWAMI_TYPE_CONTROL_FLAGS") (values '("sends" "SWAMI_CONTROL_SENDS") '("recvs" "SWAMI_CONTROL_RECVS") '("no-conv" "SWAMI_CONTROL_NO_CONV") '("native" "SWAMI_CONTROL_NATIVE") '("value" "SWAMI_CONTROL_VALUE") '("spec-no-conv" "SWAMI_CONTROL_SPEC_NO_CONV") ) ) (define-enum ControlConnPriority (in-module "Swami") (c-name "SwamiControlConnPriority") (gtype-id "SWAMI_TYPE_CONTROL_CONN_PRIORITY") (values '("default" "SWAMI_CONTROL_CONN_PRIORITY_DEFAULT") '("low" "SWAMI_CONTROL_CONN_PRIORITY_LOW") '("medium" "SWAMI_CONTROL_CONN_PRIORITY_MEDIUM") '("high" "SWAMI_CONTROL_CONN_PRIORITY_HIGH") ) ) (define-flags ControlConnFlags (in-module "Swami") (c-name "SwamiControlConnFlags") (gtype-id "SWAMI_TYPE_CONTROL_CONN_FLAGS") (values '("input" "SWAMI_CONTROL_CONN_INPUT") '("output" "SWAMI_CONTROL_CONN_OUTPUT") '("init" "SWAMI_CONTROL_CONN_INIT") '("bidir" "SWAMI_CONTROL_CONN_BIDIR") '("spec" "SWAMI_CONTROL_CONN_SPEC") ) ) (define-enum Error (in-module "Swami") (c-name "SwamiError") (gtype-id "SWAMI_TYPE_ERROR") (values '("fail" "SWAMI_ERROR_FAIL") '("invalid" "SWAMI_ERROR_INVALID") '("canceled" "SWAMI_ERROR_CANCELED") '("unsupported" "SWAMI_ERROR_UNSUPPORTED") '("io" "SWAMI_ERROR_IO") ) ) (define-enum MidiEventType (in-module "Swami") (c-name "SwamiMidiEventType") (gtype-id "SWAMI_TYPE_MIDI_EVENT_TYPE") (values '("none" "SWAMI_MIDI_NONE") '("note" "SWAMI_MIDI_NOTE") '("note-on" "SWAMI_MIDI_NOTE_ON") '("note-off" "SWAMI_MIDI_NOTE_OFF") '("key-pressure" "SWAMI_MIDI_KEY_PRESSURE") '("pitch-bend" "SWAMI_MIDI_PITCH_BEND") '("program-change" "SWAMI_MIDI_PROGRAM_CHANGE") '("control" "SWAMI_MIDI_CONTROL") '("control14" "SWAMI_MIDI_CONTROL14") '("chan-pressure" "SWAMI_MIDI_CHAN_PRESSURE") '("rpn" "SWAMI_MIDI_RPN") '("nrpn" "SWAMI_MIDI_NRPN") '("bend-range" "SWAMI_MIDI_BEND_RANGE") '("bank-select" "SWAMI_MIDI_BANK_SELECT") ) ) (define-enum Rank (in-module "Swami") (c-name "SwamiRank") (gtype-id "SWAMI_TYPE_RANK") (values '("invalid" "SWAMI_RANK_INVALID") '("lowest" "SWAMI_RANK_LOWEST") '("low" "SWAMI_RANK_LOW") '("normal" "SWAMI_RANK_NORMAL") '("default" "SWAMI_RANK_DEFAULT") '("high" "SWAMI_RANK_HIGH") '("highest" "SWAMI_RANK_HIGHEST") ) ) (define-flags ObjectFlags (in-module "Swami") (c-name "SwamiObjectFlags") (gtype-id "SWAMI_TYPE_OBJECT_FLAGS") (values '("save" "SWAMI_OBJECT_SAVE") '("user" "SWAMI_OBJECT_USER") ) ) ;; From SwamiControl.h (define-function swami_control_get_type (c-name "swami_control_get_type") (return-type "GType") ) (define-function swami_control_new (c-name "swami_control_new") (is-constructor-of "SwamiControl") (return-type "SwamiControl*") ) (define-method connect (of-object "SwamiControl") (c-name "swami_control_connect") (return-type "none") (parameters '("SwamiControl*" "dest") '("guint" "flags") ) ) (define-method connect_transform (of-object "SwamiControl") (c-name "swami_control_connect_transform") (return-type "none") (parameters '("SwamiControl*" "dest") '("guint" "flags") '("SwamiValueTransform" "trans1") '("SwamiValueTransform" "trans2") '("gpointer" "data1") '("gpointer" "data2") '("GDestroyNotify" "destroy1") '("GDestroyNotify" "destroy2") ) ) (define-method connect_item_prop (of-object "SwamiControl") (c-name "swami_control_connect_item_prop") (return-type "none") (parameters '("GObject*" "object") '("GParamSpec*" "pspec") ) ) (define-method disconnect (of-object "SwamiControl") (c-name "swami_control_disconnect") (return-type "none") (parameters '("SwamiControl*" "dest") ) ) (define-method disconnect_all (of-object "SwamiControl") (c-name "swami_control_disconnect_all") (return-type "none") ) (define-method disconnect_unref (of-object "SwamiControl") (c-name "swami_control_disconnect_unref") (return-type "none") ) (define-method get_connections (of-object "SwamiControl") (c-name "swami_control_get_connections") (return-type "IpatchList*") (parameters '("SwamiControlConnFlags" "dir") ) ) (define-method set_transform (of-object "SwamiControl") (c-name "swami_control_set_transform") (return-type "none") (parameters '("SwamiControl*" "dest") '("SwamiValueTransform" "trans") '("gpointer" "data") '("GDestroyNotify" "destroy") ) ) (define-method get_transform (of-object "SwamiControl") (c-name "swami_control_get_transform") (return-type "none") (parameters '("SwamiControl*" "dest") '("SwamiValueTransform*" "trans") ) ) (define-method set_flags (of-object "SwamiControl") (c-name "swami_control_set_flags") (return-type "none") (parameters '("int" "flags") ) ) (define-method get_flags (of-object "SwamiControl") (c-name "swami_control_get_flags") (return-type "int") ) (define-method set_queue (of-object "SwamiControl") (c-name "swami_control_set_queue") (return-type "none") (parameters '("SwamiControlQueue*" "queue") ) ) (define-method get_queue (of-object "SwamiControl") (c-name "swami_control_get_queue") (return-type "SwamiControlQueue*") ) (define-method get_spec (of-object "SwamiControl") (c-name "swami_control_get_spec") (return-type "GParamSpec*") ) (define-method set_spec (of-object "SwamiControl") (c-name "swami_control_set_spec") (return-type "gboolean") (parameters '("GParamSpec*" "pspec") ) ) (define-method sync_spec (of-object "SwamiControl") (c-name "swami_control_sync_spec") (return-type "gboolean") (parameters '("SwamiControl*" "source") '("SwamiValueTransform" "trans") '("gpointer" "data") ) ) (define-method transform_spec (of-object "SwamiControl") (c-name "swami_control_transform_spec") (return-type "GParamSpec*") (parameters '("SwamiControl*" "source") '("SwamiValueTransform" "trans") '("gpointer" "data") ) ) (define-method set_value_type (of-object "SwamiControl") (c-name "swami_control_set_value_type") (return-type "none") (parameters '("GType" "type") ) ) (define-method get_value (of-object "SwamiControl") (c-name "swami_control_get_value") (return-type "none") (parameters '("GValue*" "value") ) ) (define-method get_value_native (of-object "SwamiControl") (c-name "swami_control_get_value_native") (return-type "none") (parameters '("GValue*" "value") ) ) (define-method set_value (of-object "SwamiControl") (c-name "swami_control_set_value") (return-type "none") (parameters '("const-GValue*" "value") ) ) (define-method set_value_no_queue (of-object "SwamiControl") (c-name "swami_control_set_value_no_queue") (return-type "none") (parameters '("const-GValue*" "value") ) ) (define-method set_event (of-object "SwamiControl") (c-name "swami_control_set_event") (return-type "none") (parameters '("SwamiControlEvent*" "event") ) ) (define-method set_event_no_queue (of-object "SwamiControl") (c-name "swami_control_set_event_no_queue") (return-type "none") (parameters '("SwamiControlEvent*" "event") ) ) (define-method set_event_no_queue_loop (of-object "SwamiControl") (c-name "swami_control_set_event_no_queue_loop") (return-type "none") (parameters '("SwamiControlEvent*" "event") ) ) (define-method transmit_value (of-object "SwamiControl") (c-name "swami_control_transmit_value") (return-type "none") (parameters '("const-GValue*" "value") ) ) (define-method transmit_event (of-object "SwamiControl") (c-name "swami_control_transmit_event") (return-type "none") (parameters '("SwamiControlEvent*" "event") ) ) (define-method transmit_event_loop (of-object "SwamiControl") (c-name "swami_control_transmit_event_loop") (return-type "none") (parameters '("SwamiControlEvent*" "event") ) ) (define-function swami_control_do_event_expiration (c-name "swami_control_do_event_expiration") (return-type "none") ) (define-method new_event (of-object "SwamiControl") (c-name "swami_control_new_event") (return-type "SwamiControlEvent*") (parameters '("SwamiControlEvent*" "origin") '("const-GValue*" "value") ) ) ;; From SwamiEvent_ipatch.h (define-function swami_event_item_add_get_type (c-name "swami_event_item_add_get_type") (return-type "GType") ) (define-function swami_event_item_remove_get_type (c-name "swami_event_item_remove_get_type") (return-type "GType") ) (define-function swami_event_prop_change_get_type (c-name "swami_event_prop_change_get_type") (return-type "GType") ) (define-method copy (of-object "SwamiEventItemAdd") (c-name "swami_event_item_add_copy") (return-type "SwamiEventItemAdd*") ) (define-method free (of-object "SwamiEventItemAdd") (c-name "swami_event_item_add_free") (return-type "none") ) (define-function swami_event_item_remove_new (c-name "swami_event_item_remove_new") (is-constructor-of "SwamiEventItemRemove") (return-type "SwamiEventItemRemove*") ) (define-method copy (of-object "SwamiEventItemRemove") (c-name "swami_event_item_remove_copy") (return-type "SwamiEventItemRemove*") ) (define-method free (of-object "SwamiEventItemRemove") (c-name "swami_event_item_remove_free") (return-type "none") ) (define-function swami_event_prop_change_new (c-name "swami_event_prop_change_new") (is-constructor-of "SwamiEventPropChange") (return-type "SwamiEventPropChange*") ) (define-method copy (of-object "SwamiEventPropChange") (c-name "swami_event_prop_change_copy") (return-type "SwamiEventPropChange*") ) (define-method free (of-object "SwamiEventPropChange") (c-name "swami_event_prop_change_free") (return-type "none") ) ;; From SwamiControlEvent.h (define-function swami_control_event_get_type (c-name "swami_control_event_get_type") (return-type "GType") ) (define-function swami_control_event_new (c-name "swami_control_event_new") (is-constructor-of "SwamiControlEvent") (return-type "SwamiControlEvent*") (parameters '("gboolean" "stamp") ) ) (define-method free (of-object "SwamiControlEvent") (c-name "swami_control_event_free") (return-type "none") ) (define-method duplicate (of-object "SwamiControlEvent") (c-name "swami_control_event_duplicate") (return-type "SwamiControlEvent*") ) (define-method transform (of-object "SwamiControlEvent") (c-name "swami_control_event_transform") (return-type "SwamiControlEvent*") (parameters '("GType" "valtype") '("SwamiValueTransform" "trans") '("gpointer" "data") ) ) (define-method stamp (of-object "SwamiControlEvent") (c-name "swami_control_event_stamp") (return-type "none") ) (define-method set_origin (of-object "SwamiControlEvent") (c-name "swami_control_event_set_origin") (return-type "none") (parameters '("SwamiControlEvent*" "origin") ) ) (define-method ref (of-object "SwamiControlEvent") (c-name "swami_control_event_ref") (return-type "SwamiControlEvent*") ) (define-method unref (of-object "SwamiControlEvent") (c-name "swami_control_event_unref") (return-type "none") ) (define-method active_ref (of-object "SwamiControlEvent") (c-name "swami_control_event_active_ref") (return-type "none") ) (define-method active_unref (of-object "SwamiControlEvent") (c-name "swami_control_event_active_unref") (return-type "none") ) ;; From SwamiControlFunc.h (define-function swami_control_func_get_type (c-name "swami_control_func_get_type") (return-type "GType") ) (define-function swami_control_func_new (c-name "swami_control_func_new") (is-constructor-of "SwamiControlFunc") (return-type "SwamiControlFunc*") ) (define-method assign_funcs (of-object "SwamiControlFunc") (c-name "swami_control_func_assign_funcs") (return-type "none") (parameters '("SwamiControlGetValueFunc" "get_func") '("SwamiControlSetValueFunc" "set_func") '("SwamiControlFuncDestroy" "destroy_func") '("gpointer" "user_data") ) ) ;; From SwamiControlHub.h (define-function swami_control_hub_get_type (c-name "swami_control_hub_get_type") (return-type "GType") ) (define-function swami_control_hub_new (c-name "swami_control_hub_new") (is-constructor-of "SwamiControlHub") (return-type "SwamiControlHub*") ) ;; From SwamiControlMidi.h (define-function swami_control_midi_get_type (c-name "swami_control_midi_get_type") (return-type "GType") ) (define-function swami_control_midi_new (c-name "swami_control_midi_new") (is-constructor-of "SwamiControlMidi") (return-type "SwamiControlMidi*") ) (define-method set_callback (of-object "SwamiControlMidi") (c-name "swami_control_midi_set_callback") (return-type "none") (parameters '("SwamiControlSetValueFunc" "callback") '("gpointer" "data") ) ) (define-method send (of-object "SwamiControlMidi") (c-name "swami_control_midi_send") (return-type "none") (parameters '("SwamiMidiEventType" "type") '("int" "channel") '("int" "param1") '("int" "param2") ) ) (define-method transmit (of-object "SwamiControlMidi") (c-name "swami_control_midi_transmit") (return-type "none") (parameters '("SwamiMidiEventType" "type") '("int" "channel") '("int" "param1") '("int" "param2") ) ) ;; From SwamiControlProp.h (define-function swami_get_control_prop (c-name "swami_get_control_prop") (return-type "SwamiControl*") (parameters '("GObject*" "object") '("GParamSpec*" "pspec") ) ) (define-function swami_get_control_prop_by_name (c-name "swami_get_control_prop_by_name") (return-type "SwamiControl*") (parameters '("GObject*" "object") '("const-char*" "name") ) ) (define-function swami_control_prop_connect_objects (c-name "swami_control_prop_connect_objects") (return-type "none") (parameters '("GObject*" "src") '("const-char*" "propname1") '("GObject*" "dest") '("const-char*" "propname2") '("guint" "flags") ) ) (define-function swami_control_prop_connect_to_control (c-name "swami_control_prop_connect_to_control") (return-type "none") (parameters '("GObject*" "src") '("const-char*" "propname") '("SwamiControl*" "dest") '("guint" "flags") ) ) (define-method prop_connect_from_control (of-object "SwamiControl") (c-name "swami_control_prop_connect_from_control") (return-type "none") (parameters '("GObject*" "dest") '("const-char*" "propname") '("guint" "flags") ) ) (define-function swami_control_prop_get_type (c-name "swami_control_prop_get_type") (return-type "GType") ) (define-function swami_control_prop_new (c-name "swami_control_prop_new") (is-constructor-of "SwamiControlProp") (return-type "SwamiControlProp*") (parameters '("GObject*" "object") '("GParamSpec*" "pspec") ) ) (define-method assign (of-object "SwamiControlProp") (c-name "swami_control_prop_assign") (return-type "none") (parameters '("GObject*" "object") '("GParamSpec*" "pspec") '("gboolean" "send_events") ) ) (define-method assign_by_name (of-object "SwamiControlProp") (c-name "swami_control_prop_assign_by_name") (return-type "none") (parameters '("GObject*" "object") '("const-char*" "prop_name") ) ) ;; From SwamiControlQueue.h (define-function swami_control_queue_get_type (c-name "swami_control_queue_get_type") (return-type "GType") ) (define-function swami_control_queue_new (c-name "swami_control_queue_new") (is-constructor-of "SwamiControlQueue") (return-type "SwamiControlQueue*") ) (define-method add_event (of-object "SwamiControlQueue") (c-name "swami_control_queue_add_event") (return-type "none") (parameters '("SwamiControl*" "control") '("SwamiControlEvent*" "event") ) ) (define-method run (of-object "SwamiControlQueue") (c-name "swami_control_queue_run") (return-type "none") ) (define-method set_test_func (of-object "SwamiControlQueue") (c-name "swami_control_queue_set_test_func") (return-type "none") (parameters '("SwamiControlQueueTestFunc" "test_func") ) ) ;; From SwamiControlValue.h (define-function swami_control_value_get_type (c-name "swami_control_value_get_type") (return-type "GType") ) (define-function swami_control_value_new (c-name "swami_control_value_new") (is-constructor-of "SwamiControlValue") (return-type "SwamiControlValue*") ) (define-method assign_value (of-object "SwamiControlValue") (c-name "swami_control_value_assign_value") (return-type "none") (parameters '("GValue*" "value") '("GDestroyNotify" "destroy") ) ) (define-method alloc_value (of-object "SwamiControlValue") (c-name "swami_control_value_alloc_value") (return-type "none") ) ;; From SwamiEvent_ipatch.h (define-function swami_event_item_add_get_type (c-name "swami_event_item_add_get_type") (return-type "GType") ) (define-function swami_event_item_remove_get_type (c-name "swami_event_item_remove_get_type") (return-type "GType") ) (define-function swami_event_prop_change_get_type (c-name "swami_event_prop_change_get_type") (return-type "GType") ) (define-method copy (of-object "SwamiEventItemAdd") (c-name "swami_event_item_add_copy") (return-type "SwamiEventItemAdd*") ) (define-method free (of-object "SwamiEventItemAdd") (c-name "swami_event_item_add_free") (return-type "none") ) (define-function swami_event_item_remove_new (c-name "swami_event_item_remove_new") (is-constructor-of "SwamiEventItemRemove") (return-type "SwamiEventItemRemove*") ) (define-method copy (of-object "SwamiEventItemRemove") (c-name "swami_event_item_remove_copy") (return-type "SwamiEventItemRemove*") ) (define-method free (of-object "SwamiEventItemRemove") (c-name "swami_event_item_remove_free") (return-type "none") ) (define-function swami_event_prop_change_new (c-name "swami_event_prop_change_new") (is-constructor-of "SwamiEventPropChange") (return-type "SwamiEventPropChange*") ) (define-method copy (of-object "SwamiEventPropChange") (c-name "swami_event_prop_change_copy") (return-type "SwamiEventPropChange*") ) (define-method free (of-object "SwamiEventPropChange") (c-name "swami_event_prop_change_free") (return-type "none") ) ;; From SwamiLock.h (define-function swami_lock_get_type (c-name "swami_lock_get_type") (return-type "GType") ) (define-function swami_lock_set_atomic (c-name "swami_lock_set_atomic") (return-type "none") (parameters '("gpointer" "lock") '("const-char*" "first_property_name") ) (varargs #t) ) (define-function swami_lock_get_atomic (c-name "swami_lock_get_atomic") (return-type "none") (parameters '("gpointer" "lock") '("const-char*" "first_property_name") ) (varargs #t) ) ;; From SwamiLog.h (define-function swami_error_quark (c-name "swami_error_quark") (return-type "GQuark") ) ;; From SwamiMidiDevice.h (define-function swami_midi_device_get_type (c-name "swami_midi_device_get_type") (return-type "GType") ) (define-method open (of-object "SwamiMidiDevice") (c-name "swami_midi_device_open") (return-type "gboolean") (parameters '("GError**" "err") ) ) (define-method close (of-object "SwamiMidiDevice") (c-name "swami_midi_device_close") (return-type "none") ) (define-method get_control (of-object "SwamiMidiDevice") (c-name "swami_midi_device_get_control") (return-type "SwamiControl*") (parameters '("int" "index") ) ) ;; From SwamiMidiEvent.h (define-function swami_midi_event_get_type (c-name "swami_midi_event_get_type") (return-type "GType") ) (define-function swami_midi_event_new (c-name "swami_midi_event_new") (is-constructor-of "SwamiMidiEvent") (return-type "SwamiMidiEvent*") ) (define-method free (of-object "SwamiMidiEvent") (c-name "swami_midi_event_free") (return-type "none") ) (define-method copy (of-object "SwamiMidiEvent") (c-name "swami_midi_event_copy") (return-type "SwamiMidiEvent*") ) (define-method set (of-object "SwamiMidiEvent") (c-name "swami_midi_event_set") (return-type "none") (parameters '("SwamiMidiEventType" "type") '("int" "channel") '("int" "param1") '("int" "param2") ) ) (define-method note_on (of-object "SwamiMidiEvent") (c-name "swami_midi_event_note_on") (return-type "none") (parameters '("int" "channel") '("int" "note") '("int" "velocity") ) ) (define-method note_off (of-object "SwamiMidiEvent") (c-name "swami_midi_event_note_off") (return-type "none") (parameters '("int" "channel") '("int" "note") '("int" "velocity") ) ) (define-method bank_select (of-object "SwamiMidiEvent") (c-name "swami_midi_event_bank_select") (return-type "none") (parameters '("int" "channel") '("int" "bank") ) ) (define-method program_change (of-object "SwamiMidiEvent") (c-name "swami_midi_event_program_change") (return-type "none") (parameters '("int" "channel") '("int" "program") ) ) (define-method bend_range (of-object "SwamiMidiEvent") (c-name "swami_midi_event_bend_range") (return-type "none") (parameters '("int" "channel") '("int" "cents") ) ) (define-method pitch_bend (of-object "SwamiMidiEvent") (c-name "swami_midi_event_pitch_bend") (return-type "none") (parameters '("int" "channel") '("int" "value") ) ) (define-method control (of-object "SwamiMidiEvent") (c-name "swami_midi_event_control") (return-type "none") (parameters '("int" "channel") '("int" "ctrlnum") '("int" "value") ) ) (define-method control14 (of-object "SwamiMidiEvent") (c-name "swami_midi_event_control14") (return-type "none") (parameters '("int" "channel") '("int" "ctrlnum") '("int" "value") ) ) (define-method rpn (of-object "SwamiMidiEvent") (c-name "swami_midi_event_rpn") (return-type "none") (parameters '("int" "channel") '("int" "paramnum") '("int" "value") ) ) (define-method nrpn (of-object "SwamiMidiEvent") (c-name "swami_midi_event_nrpn") (return-type "none") (parameters '("int" "channel") '("int" "paramnum") '("int" "value") ) ) ;; From SwamiObject.h (define-function swami_type_set_rank (c-name "swami_type_set_rank") (return-type "none") (parameters '("GType" "type") '("GType" "group_type") '("int" "rank") ) ) (define-function swami_type_get_rank (c-name "swami_type_get_rank") (return-type "int") (parameters '("GType" "type") '("GType" "group_type") ) ) (define-function swami_type_get_children (c-name "swami_type_get_children") (return-type "GType*") (parameters '("GType" "group_type") ) ) (define-function swami_type_get_default (c-name "swami_type_get_default") (return-type "GType") (parameters '("GType" "group_type") ) ) (define-function swami_object_set_default (c-name "swami_object_set_default") (return-type "none") (parameters '("GObject*" "object") '("GType" "type") ) ) (define-function swami_object_get_by_name (c-name "swami_object_get_by_name") (return-type "GObject*") (parameters '("GObject*" "object") '("const-char*" "name") ) ) (define-function swami_object_find_by_type (c-name "swami_object_find_by_type") (return-type "IpatchList*") (parameters '("GObject*" "object") '("const-char*" "type_name") ) ) (define-function swami_object_get_by_type (c-name "swami_object_get_by_type") (return-type "GObject*") (parameters '("GObject*" "object") '("const-char*" "type_name") ) ) (define-function swami_object_get_valist (c-name "swami_object_get_valist") (return-type "none") (parameters '("GObject*" "object") '("const-char*" "first_property_name") '("va_list" "var_args") ) ) (define-function swami_object_get_property (c-name "swami_object_get_property") (return-type "none") (parameters '("GObject*" "object") '("const-char*" "property_name") '("GValue*" "value") ) ) (define-function swami_object_get (c-name "swami_object_get") (return-type "none") (parameters '("gpointer" "object") '("const-char*" "first_prop_name") ) (varargs #t) ) (define-function swami_object_set_valist (c-name "swami_object_set_valist") (return-type "none") (parameters '("GObject*" "object") '("const-char*" "first_property_name") '("va_list" "var_args") ) ) (define-function swami_object_set_property (c-name "swami_object_set_property") (return-type "none") (parameters '("GObject*" "object") '("const-char*" "property_name") '("const-GValue*" "value") ) ) (define-function swami_object_set (c-name "swami_object_set") (return-type "none") (parameters '("gpointer" "object") '("const-char*" "first_prop_name") ) (varargs #t) ) (define-function swami_find_object_property (c-name "swami_find_object_property") (return-type "GParamSpec*") (parameters '("const-char*" "property_name") ) ) (define-function swami_list_object_properties (c-name "swami_list_object_properties") (return-type "GParamSpec**") (parameters '("guint*" "n_properties") ) ) (define-function swami_object_get_flags (c-name "swami_object_get_flags") (return-type "guint") (parameters '("GObject*" "object") ) ) (define-function swami_object_set_flags (c-name "swami_object_set_flags") (return-type "none") (parameters '("GObject*" "object") '("guint" "flags") ) ) (define-function swami_object_clear_flags (c-name "swami_object_clear_flags") (return-type "none") (parameters '("GObject*" "object") '("guint" "flags") ) ) (define-function swami_object_set_origin (c-name "swami_object_set_origin") (return-type "none") (parameters '("GObject*" "obj") '("GObject*" "origin") ) ) (define-function swami_object_get_origin (c-name "swami_object_get_origin") (return-type "GObject*") (parameters '("GObject*" "obj") ) ) ;; From SwamiParam.h (define-function swami_param_get_limits (c-name "swami_param_get_limits") (return-type "gboolean") (parameters '("GParamSpec*" "pspec") '("gdouble*" "min") '("gdouble*" "max") '("gdouble*" "def") '("gboolean*" "integer") ) ) (define-function swami_param_set_limits (c-name "swami_param_set_limits") (return-type "gboolean") (parameters '("GParamSpec*" "pspec") '("gdouble" "min") '("gdouble" "max") '("gdouble" "def") ) ) (define-function swami_param_type_has_limits (c-name "swami_param_type_has_limits") (return-type "gboolean") (parameters '("GType" "param_type") ) ) (define-function swami_param_convert (c-name "swami_param_convert") (return-type "gboolean") (parameters '("GParamSpec*" "dest") '("GParamSpec*" "src") ) ) (define-function swami_param_convert_new (c-name "swami_param_convert_new") (is-constructor-of "SwamiParamConvert") (return-type "GParamSpec*") (parameters '("GParamSpec*" "pspec") '("GType" "value_type") ) ) (define-function swami_param_type_transformable (c-name "swami_param_type_transformable") (return-type "gboolean") (parameters '("GType" "src_type") '("GType" "dest_type") ) ) (define-function swami_param_type_transformable_value (c-name "swami_param_type_transformable_value") (return-type "gboolean") (parameters '("GType" "src_valtype") '("GType" "dest_valtype") ) ) (define-function swami_param_transform (c-name "swami_param_transform") (return-type "gboolean") (parameters '("GParamSpec*" "dest") '("GParamSpec*" "src") '("SwamiValueTransform" "trans") '("gpointer" "user_data") ) ) (define-function swami_param_transform_new (c-name "swami_param_transform_new") (is-constructor-of "SwamiParamTransform") (return-type "GParamSpec*") (parameters '("GParamSpec*" "dest") '("GType" "value_type") '("SwamiValueTransform" "trans") '("gpointer" "user_data") ) ) (define-function swami_param_type_from_value_type (c-name "swami_param_type_from_value_type") (return-type "GType") (parameters '("GType" "value_type") ) ) ;; From SwamiPlugin.h (define-function swami_plugin_get_type (c-name "swami_plugin_get_type") (return-type "GType") ) (define-function swami_plugin_add_path (c-name "swami_plugin_add_path") (return-type "none") (parameters '("const-char*" "path") ) ) (define-function swami_plugin_load_all (c-name "swami_plugin_load_all") (return-type "none") ) (define-function swami_plugin_load (c-name "swami_plugin_load") (return-type "gboolean") (parameters '("const-char*" "filename") ) ) (define-function swami_plugin_load_absolute (c-name "swami_plugin_load_absolute") (return-type "gboolean") (parameters '("const-char*" "filename") ) ) (define-method load_plugin (of-object "SwamiPlugin") (c-name "swami_plugin_load_plugin") (return-type "gboolean") ) (define-method is_loaded (of-object "SwamiPlugin") (c-name "swami_plugin_is_loaded") (return-type "gboolean") ) (define-function swami_plugin_find (c-name "swami_plugin_find") (return-type "SwamiPlugin*") (parameters '("const-char*" "name") ) ) (define-function swami_plugin_get_list (c-name "swami_plugin_get_list") (return-type "GList*") ) (define-method save_xml (of-object "SwamiPlugin") (c-name "swami_plugin_save_xml") (return-type "gboolean") (parameters '("GNode*" "xmlnode") '("GError**" "err") ) ) (define-method load_xml (of-object "SwamiPlugin") (c-name "swami_plugin_load_xml") (return-type "gboolean") (parameters '("GNode*" "xmlnode") '("GError**" "err") ) ) ;; From SwamiPropTree.h (define-function swami_prop_tree_get_type (c-name "swami_prop_tree_get_type") (return-type "GType") ) (define-function swami_prop_tree_new (c-name "swami_prop_tree_new") (is-constructor-of "SwamiPropTree") (return-type "SwamiPropTree*") ) (define-method set_root (of-object "SwamiPropTree") (c-name "swami_prop_tree_set_root") (return-type "none") (parameters '("GObject*" "root") ) ) (define-method prepend (of-object "SwamiPropTree") (c-name "swami_prop_tree_prepend") (return-type "none") (parameters '("GObject*" "parent") '("GObject*" "obj") ) ) (define-method insert_before (of-object "SwamiPropTree") (c-name "swami_prop_tree_insert_before") (return-type "none") (parameters '("GObject*" "parent") '("GObject*" "sibling") '("GObject*" "obj") ) ) (define-method remove (of-object "SwamiPropTree") (c-name "swami_prop_tree_remove") (return-type "none") (parameters '("GObject*" "obj") ) ) (define-method remove_recursive (of-object "SwamiPropTree") (c-name "swami_prop_tree_remove_recursive") (return-type "none") (parameters '("GObject*" "obj") ) ) (define-method replace (of-object "SwamiPropTree") (c-name "swami_prop_tree_replace") (return-type "none") (parameters '("GObject*" "old") '("GObject*" "new") ) ) (define-method get_children (of-object "SwamiPropTree") (c-name "swami_prop_tree_get_children") (return-type "IpatchList*") (parameters '("GObject*" "obj") ) ) (define-method object_get_node (of-object "SwamiPropTree") (c-name "swami_prop_tree_object_get_node") (return-type "GNode*") (parameters '("GObject*" "obj") ) ) (define-method add_value (of-object "SwamiPropTree") (c-name "swami_prop_tree_add_value") (return-type "none") (parameters '("GObject*" "obj") '("GType" "prop_type") '("const-char*" "prop_name") '("SwamiControl*" "control") ) ) (define-method remove_value (of-object "SwamiPropTree") (c-name "swami_prop_tree_remove_value") (return-type "none") (parameters '("GObject*" "obj") '("GType" "prop_type") '("const-char*" "prop_name") ) ) ;; From SwamiRoot.h (define-function swami_root_get_type (c-name "swami_root_get_type") (return-type "GType") ) (define-function swami_root_new (c-name "swami_root_new") (is-constructor-of "SwamiRoot") (return-type "SwamiRoot*") ) (define-function swami_get_root (c-name "swami_get_root") (return-type "SwamiRoot*") (parameters '("gpointer" "object") ) ) (define-method get_objects (of-object "SwamiRoot") (c-name "swami_root_get_objects") (return-type "IpatchList*") ) (define-method add_object (of-object "SwamiRoot") (c-name "swami_root_add_object") (return-type "none") (parameters '("GObject*" "object") ) ) (define-method new_object (of-object "SwamiRoot") (c-name "swami_root_new_object") (return-type "GObject*") (parameters '("const-char*" "type_name") ) ) (define-method prepend_object (of-object "SwamiRoot") (c-name "swami_root_prepend_object") (return-type "none") (parameters '("GObject*" "parent") '("GObject*" "object") ) ) (define-method insert_object_before (of-object "SwamiRoot") (c-name "swami_root_insert_object_before") (return-type "none") (parameters '("GObject*" "parent") '("GObject*" "sibling") '("GObject*" "object") ) ) (define-method patch_load (of-object "SwamiRoot") (c-name "swami_root_patch_load") (return-type "gboolean") (parameters '("const-char*" "filename") '("IpatchItem**" "item") '("GError**" "err") ) ) (define-function swami_root_patch_save (c-name "swami_root_patch_save") (return-type "gboolean") (parameters '("IpatchItem*" "item") '("const-char*" "filename") '("GError**" "err") ) ) ;; From SwamiWavetbl.h (define-function swami_wavetbl_get_type (c-name "swami_wavetbl_get_type") (return-type "GType") ) (define-method get_virtual_bank (of-object "SwamiWavetbl") (c-name "swami_wavetbl_get_virtual_bank") (return-type "IpatchVBank*") ) (define-method set_active_item_locale (of-object "SwamiWavetbl") (c-name "swami_wavetbl_set_active_item_locale") (return-type "none") (parameters '("int" "bank") '("int" "program") ) ) (define-method get_active_item_locale (of-object "SwamiWavetbl") (c-name "swami_wavetbl_get_active_item_locale") (return-type "none") (parameters '("int*" "bank") '("int*" "program") ) ) (define-method open (of-object "SwamiWavetbl") (c-name "swami_wavetbl_open") (return-type "gboolean") (parameters '("GError**" "err") ) ) (define-method close (of-object "SwamiWavetbl") (c-name "swami_wavetbl_close") (return-type "none") ) (define-method get_control (of-object "SwamiWavetbl") (c-name "swami_wavetbl_get_control") (return-type "SwamiControlMidi*") (parameters '("int" "index") ) ) (define-method load_patch (of-object "SwamiWavetbl") (c-name "swami_wavetbl_load_patch") (return-type "gboolean") (parameters '("IpatchItem*" "patch") '("GError**" "err") ) ) (define-method load_active_item (of-object "SwamiWavetbl") (c-name "swami_wavetbl_load_active_item") (return-type "gboolean") (parameters '("IpatchItem*" "item") '("GError**" "err") ) ) (define-method check_update_item (of-object "SwamiWavetbl") (c-name "swami_wavetbl_check_update_item") (return-type "gboolean") (parameters '("IpatchItem*" "item") '("GParamSpec*" "prop") ) ) (define-method update_item (of-object "SwamiWavetbl") (c-name "swami_wavetbl_update_item") (return-type "none") (parameters '("IpatchItem*" "item") ) ) ;; From builtin_enums.h (define-function swami_control_flags_get_type (c-name "swami_control_flags_get_type") (return-type "GType") ) (define-function swami_control_conn_priority_get_type (c-name "swami_control_conn_priority_get_type") (return-type "GType") ) (define-function swami_control_conn_flags_get_type (c-name "swami_control_conn_flags_get_type") (return-type "GType") ) (define-function swami_error_get_type (c-name "swami_error_get_type") (return-type "GType") ) (define-function swami_midi_event_type_get_type (c-name "swami_midi_event_type_get_type") (return-type "GType") ) (define-function swami_rank_get_type (c-name "swami_rank_get_type") (return-type "GType") ) (define-function swami_object_flags_get_type (c-name "swami_object_flags_get_type") (return-type "GType") ) ;; From util.h (define-function swami_util_get_child_types (c-name "swami_util_get_child_types") (return-type "GType*") (parameters '("GType" "type") '("guint*" "n_types") ) ) (define-function swami_util_new_value (c-name "swami_util_new_value") (return-type "GValue*") ) (define-function swami_util_free_value (c-name "swami_util_free_value") (return-type "none") (parameters '("GValue*" "value") ) ) (define-function swami_util_midi_note_to_str (c-name "swami_util_midi_note_to_str") (return-type "none") (parameters '("int" "note") '("char*" "str") ) ) (define-function swami_util_midi_str_to_note (c-name "swami_util_midi_str_to_note") (return-type "int") (parameters '("const-char*" "str") ) ) ;; From version.h (define-function swami_version (c-name "swami_version") (return-type "none") (parameters '("guint*" "major") '("guint*" "minor") '("guint*" "micro") ) ) swami/src/libinstpatch/0000755000175000017500000000000011716016656015342 5ustar alessioalessioswami/src/libinstpatch/README0000644000175000017500000000031310071360410016176 0ustar alessioalessiolibInstPatch is now a stand alone library and can be found from the Swami web site: http://swami.sourceforge.net Email me if you have any questions: Josh Green 2003-08-29 swami/src/plugins/0000755000175000017500000000000011716016656014337 5ustar alessioalessioswami/src/plugins/fluidsynth_i18n.c0000644000175000017500000000240007676126120017525 0ustar alessioalessio/* * Translatable strings file generated by Glade. * Add this file to your project's POTFILES.in. * DO NOT compile it as part of your application. */ gchar *s = N_("Preferences"); gchar *s = N_("Restart drivers for changes to take effect"); gchar *s = N_("Type"); gchar *s = N_("Device"); gchar *s = N_("Buffer Size"); gchar *s = N_("Buffer Count"); gchar *s = N_("AUTO"); gchar *s = N_("*"); gchar *s = N_("Default"); gchar *s = N_("Audio Driver"); gchar *s = N_("Type"); gchar *s = N_("Device"); gchar *s = N_("NONE"); gchar *s = N_("*"); gchar *s = N_("Default"); gchar *s = N_("MIDI Driver"); gchar *s = N_("FluidSynth Control"); gchar *s = N_("Master Gain"); gchar *s = N_("Default"); gchar *s = N_("Disabled"); gchar *s = N_("Default *"); gchar *s = N_("Custom"); gchar *s = N_("Room Size"); gchar *s = N_("Damp"); gchar *s = N_("Width"); gchar *s = N_("Level"); gchar *s = N_("Reverb"); gchar *s = N_("Disabled"); gchar *s = N_("Default *"); gchar *s = N_("Custom"); gchar *s = N_("N"); gchar *s = N_("Level"); gchar *s = N_("Frequency"); gchar *s = N_("Depth"); gchar *s = N_("Waveform"); gchar *s = N_("Sine"); gchar *s = N_("Triangle"); gchar *s = N_("Chorus"); gchar *s = N_("* marks options that require a driver restart to take effect"); gchar *s = N_("Close"); swami/src/plugins/fftune_gui.c0000644000175000017500000010243511704446464016644 0ustar alessioalessio/* * fftune_gui.h - FFTune GUI object (Fast Fourier sample tuning GUI) * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include #include #include #include #include #include #include #include #include /* log_if_fail() */ #include "fftune_gui.h" /* the range of time for the mouse wheel scroll zoom speed function, times are in milliseconds and represent the time between events */ #define WHEEL_ZOOM_MIN_TIME 10 /* fastest event time interval */ #define WHEEL_ZOOM_MAX_TIME 500 /* slowest event time interval */ /* zoom in speed range defined for the time interval above */ #define WHEEL_ZOOM_MIN_SPEED 0.98 /* slowest zoom in speed */ #define WHEEL_ZOOM_MAX_SPEED 0.7 /* fastest zoom in speed */ #define WHEEL_ZOOM_RANGE (WHEEL_ZOOM_MIN_SPEED - WHEEL_ZOOM_MAX_SPEED) /* min zoom value (indexes/pixel) */ #define SPECTRUM_CANVAS_MIN_ZOOM 0.02 #define SNAP_TIMEOUT_PRIORITY (G_PRIORITY_HIGH_IDLE + 40) #define SNAP_TIMEOUT_PIXEL_RANGE 60 /* range in pixels of timeout varience */ #define SNAP_TIMEOUT_MIN 40 /* minimum timeout in milliseconds */ #define SNAP_TIMEOUT_MAX 120 /* maximum timeout in milliseconds */ #define SNAP_SCROLL_MIN 1 /* minimum scroll amount in pixels */ #define SNAP_SCROLL_MULT 6.0 /* scroll multiplier in pixels */ /* range of zoom speeds over SNAP_TIMEOUT_PIXEL_RANGE */ #define SNAP_ZOOM_MIN 0.99 /* minimum (slowest) zoom in amount (< 1.0) */ #define SNAP_ZOOM_MAX 0.26 /* max (fastest) zoom in amount (< 1.0) */ enum { PROP_0, PROP_ITEM_SELECTION }; /* columns for fftunegui->freq_store */ enum { COL_POWER, /* power ratio column */ COL_FREQ, /* frequency column */ COL_NOTE, /* MIDI note column */ COL_CENTS, /* fractional tuning (cents) */ COL_COUNT /* count of columns */ }; typedef struct { int limit; char *label; } LimitInfo; /* Default index in limits[] array below */ #define DEFAULT_LIMIT_INDEX 2 /* Items in limits GtkComboBox */ const LimitInfo limits[] = { { 0, N_("Unlimited") }, { 128 * 1024, N_("128K") }, { 64 * 1024, N_("64K") }, { 32 * 1024, N_("32K") }, { 16 * 1024, N_("16K") } }; static gboolean plugin_fftune_gui_init (SwamiPlugin *plugin, GError **err); static void fftune_gui_panel_iface_init (SwamiguiPanelIface *panel_iface); static gboolean fftune_gui_panel_iface_check_selection (IpatchList *selection, GType *selection_types); static void fftune_gui_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void fftune_gui_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void fftune_gui_finalize (GObject *object); static void fftunegui_cb_revert_clicked (GtkButton *button, gpointer user_data); static void fftunegui_cb_freq_list_sel_changed (GtkTreeSelection *selection, gpointer user_data); static void fftune_gui_cb_spectrum_change (FFTuneSpectra *spectra, guint size, double *spectrum, gpointer user_data); static void fftune_gui_cb_tunings_change (FFTuneSpectra *spectra, guint count, gpointer user_data); static void fftune_gui_cb_mode_menu_changed (GtkComboBox *combo, gpointer user_data); static void fftune_gui_cb_limit_changed (GtkComboBox *combo, gpointer user_data); static void fftune_gui_cb_window_toggled (GtkToggleButton *button, gpointer user_data); static void fftune_gui_cb_canvas_size_allocate (GtkWidget *widget, GtkAllocation *allocation, gpointer user_data); static void fftune_gui_cb_scroll (GtkAdjustment *adj, gpointer user_data); static gboolean fftune_gui_cb_spectrum_canvas_event (GnomeCanvas *canvas, GdkEvent *event, gpointer data); static gboolean fftune_gui_snap_timeout (gpointer data); static void fftune_gui_cb_ampl_zoom_value_changed (GtkAdjustment *adj, gpointer user_data); static void fftune_gui_zoom_ofs (FFTuneGui *fftunegui, double zoom_amt, int zoom_xpos); static void fftune_gui_scroll_ofs (FFTuneGui *fftunegui, int index_ofs); /* set plugin information */ SWAMI_PLUGIN_INFO (plugin_fftune_gui_init, NULL); /* define FFTuneGui type */ G_DEFINE_TYPE_WITH_CODE (FFTuneGui, fftune_gui, GTK_TYPE_VBOX, G_IMPLEMENT_INTERFACE (SWAMIGUI_TYPE_PANEL, fftune_gui_panel_iface_init)); static gboolean plugin_fftune_gui_init (SwamiPlugin *plugin, GError **err) { /* bind the gettext domain */ #if defined(ENABLE_NLS) bindtextdomain ("SwamiPlugin-fftune_gui", LOCALEDIR); #endif g_object_set (plugin, "name", "FFTuneGui", "version", "1.0", "author", "Josh Green", "copyright", "Copyright (C) 2005", "descr", N_("GUI for Fast Fourier Transform sample tuner"), "license", "GPL", NULL); /* register types and register it as a panel interface */ swamigui_register_panel_selector_type (fftune_gui_get_type (), 200); return (TRUE); } static void fftune_gui_class_init (FFTuneGuiClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); obj_class->set_property = fftune_gui_set_property; obj_class->get_property = fftune_gui_get_property; obj_class->finalize = fftune_gui_finalize; g_object_class_override_property (obj_class, PROP_ITEM_SELECTION, "item-selection"); } static void fftune_gui_panel_iface_init (SwamiguiPanelIface *panel_iface) { panel_iface->label = _("FFTune"); panel_iface->blurb = _("Semi-automated tuning plugin"); panel_iface->stockid = SWAMIGUI_STOCK_TUNING; panel_iface->check_selection = fftune_gui_panel_iface_check_selection; } static gboolean fftune_gui_panel_iface_check_selection (IpatchList *selection, GType *selection_types) { /* a single item with sample interface is valid */ return (!selection->items->next && g_type_is_a (*selection_types, IPATCH_TYPE_SAMPLE)); } static void fftune_gui_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { FFTuneGui *fftunegui = FFTUNE_GUI (object); SwamiControl *samctrl; IpatchSample *sample = NULL; IpatchSampleData *sampledata = NULL; IpatchList *list; int root_note, fine_tune; switch (property_id) { case PROP_ITEM_SELECTION: list = g_value_get_object (value); /* only set sample if a single IpatchSample item or NULL list */ if (list && list->items && !list->items->next && IPATCH_IS_SAMPLE (list->items->data)) { sample = IPATCH_SAMPLE (list->items->data); g_object_get (sample, "sample-data", &sampledata, NULL); } /* disconnect GUI controls (if connected) */ swami_control_disconnect_all (fftunegui->root_note_ctrl); swami_control_disconnect_all (fftunegui->fine_tune_ctrl); /* connect controls to sample properties */ if (sampledata) { g_object_get (sample, "root-note", &root_note, "fine-tune", &fine_tune, NULL); fftunegui->orig_root_note = root_note; fftunegui->orig_fine_tune = fine_tune; samctrl = swami_get_control_prop_by_name (G_OBJECT (sample), "root-note"); swami_control_connect (samctrl, fftunegui->root_note_ctrl, SWAMI_CONTROL_CONN_BIDIR | SWAMI_CONTROL_CONN_INIT); samctrl = swami_get_control_prop_by_name (G_OBJECT (sample), "fine-tune"); swami_control_connect (samctrl, fftunegui->fine_tune_ctrl, SWAMI_CONTROL_CONN_BIDIR | SWAMI_CONTROL_CONN_INIT); } /* recalculate full zoom */ fftunegui->recalc_zoom = TRUE; /* de-activate spectra object before setting sample */ g_object_set (fftunegui->spectra, "active", FALSE, NULL); /* reset amplitude zoom */ gtk_range_set_value (GTK_RANGE (fftunegui->vscale), 1.0); g_object_set (fftunegui->spectra, "sample", sample, NULL); /* re-activate spectra if sample is set */ if (sample) g_object_set (fftunegui->spectra, "active", TRUE, NULL); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void fftune_gui_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { FFTuneGui *fftunegui = FFTUNE_GUI (object); IpatchSampleData *sample = NULL; IpatchList *list; switch (property_id) { case PROP_ITEM_SELECTION: list = ipatch_list_new (); g_object_get (fftunegui->spectra, "sample", &sample, NULL); if (sample) list->items = g_list_append (list->items, sample); g_value_set_object (value, list); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void fftune_gui_finalize (GObject *object) { FFTuneGui *fftunegui = FFTUNE_GUI (object); g_object_unref (fftunegui->spectra); swami_control_disconnect_unref (fftunegui->root_note_ctrl); swami_control_disconnect_unref (fftunegui->fine_tune_ctrl); if (G_OBJECT_CLASS (fftune_gui_parent_class)->finalize) G_OBJECT_CLASS (fftune_gui_parent_class)->finalize (object); } static void fftune_gui_init (FFTuneGui *fftunegui) { GtkCellRenderer *renderer; GtkTreeViewColumn *column; GtkWidget *scrollwin; GtkWidget *box, *vbox, *hbox; GtkWidget *lbl; GtkWidget *frame; GtkStyle *style; GtkAdjustment *adj; GtkWidget *widg; int i; fftunegui->snap_active = FALSE; fftunegui->snap_timeout_handler = 0; fftunegui->scroll_active = FALSE; fftunegui->zoom_active = FALSE; fftunegui->snap_line_color = 0xFF0000FF; /* create spectrum tuning object */ fftunegui->spectra = g_object_new (g_type_from_name ("FFTuneSpectra"), NULL); /* Set default FFT limit */ g_object_set (fftunegui->spectra, "limit", limits[DEFAULT_LIMIT_INDEX].limit, NULL); /* connect to spectrum change signal */ g_signal_connect (fftunegui->spectra, "spectrum-change", G_CALLBACK (fftune_gui_cb_spectrum_change), fftunegui); /* connect to tunings change signal */ g_signal_connect (fftunegui->spectra, "tunings-change", G_CALLBACK (fftune_gui_cb_tunings_change), fftunegui); /* horizontal box to pack sample data selector, etc */ box = gtk_hbox_new (FALSE, 4); gtk_widget_show (box); lbl = gtk_label_new (_("Data")); gtk_widget_show (lbl); gtk_box_pack_start (GTK_BOX (box), lbl, FALSE, FALSE, 0); fftunegui->mode_menu = gtk_combo_box_new_text (); gtk_widget_show (fftunegui->mode_menu); gtk_box_pack_start (GTK_BOX (box), fftunegui->mode_menu, FALSE, FALSE, 0); gtk_combo_box_append_text (GTK_COMBO_BOX (fftunegui->mode_menu), _("All")); gtk_combo_box_append_text (GTK_COMBO_BOX (fftunegui->mode_menu), _("Loop")); gtk_combo_box_set_active (GTK_COMBO_BOX (fftunegui->mode_menu), 0); g_signal_connect (fftunegui->mode_menu, "changed", (GCallback)fftune_gui_cb_mode_menu_changed, fftunegui); lbl = gtk_label_new (_("Limit")); gtk_widget_show (lbl); gtk_box_pack_start (GTK_BOX (box), lbl, FALSE, FALSE, 0); widg = gtk_combo_box_new_text (); gtk_widget_show (widg); gtk_box_pack_start (GTK_BOX (box), widg, FALSE, FALSE, 0); for (i = 0; i < G_N_ELEMENTS (limits); i++) gtk_combo_box_append_text (GTK_COMBO_BOX (widg), _(limits[i].label)); gtk_combo_box_set_active (GTK_COMBO_BOX (widg), DEFAULT_LIMIT_INDEX); g_signal_connect (widg, "changed", (GCallback)fftune_gui_cb_limit_changed, fftunegui); widg = gtk_toggle_button_new_with_label (_("Window")); gtk_widget_show (widg); gtk_box_pack_start (GTK_BOX (box), widg, FALSE, FALSE, 0); g_signal_connect (widg, "toggled", (GCallback)fftune_gui_cb_window_toggled, fftunegui); lbl = gtk_label_new (_("Root note")); gtk_widget_show (lbl); gtk_box_pack_start (GTK_BOX (box), lbl, FALSE, FALSE, 0); fftunegui->root_notesel = swamigui_note_selector_new (); gtk_widget_show (fftunegui->root_notesel); gtk_box_pack_start (GTK_BOX (box), fftunegui->root_notesel, FALSE, FALSE, 0); /* create root note control and add to GUI queue */ adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (fftunegui->root_notesel)); fftunegui->root_note_ctrl = SWAMI_CONTROL (swamigui_control_adj_new (adj)); lbl = gtk_label_new (_("Fine tune")); gtk_widget_show (lbl); gtk_box_pack_start (GTK_BOX (box), lbl, FALSE, FALSE, 0); adj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, -99.0, 99.0, 1.0, 5.0, 0.0)); fftunegui->fine_tune = gtk_spin_button_new (adj, 1.0, 0); gtk_widget_show (fftunegui->fine_tune); gtk_box_pack_start (GTK_BOX (box), fftunegui->fine_tune, FALSE, FALSE, 0); /* create fine tune control */ fftunegui->fine_tune_ctrl = SWAMI_CONTROL (swamigui_control_adj_new (adj)); widg = gtk_vseparator_new (); gtk_widget_show (widg); gtk_box_pack_start (GTK_BOX (box), widg, FALSE, FALSE, 0); fftunegui->revert_button = gtk_button_new_with_mnemonic (_("_Revert")); gtk_widget_set_tooltip_text (fftunegui->revert_button, _("Revert to original tuning values")); gtk_widget_show (fftunegui->revert_button); gtk_box_pack_start (GTK_BOX (box), fftunegui->revert_button, FALSE, FALSE, 0); g_signal_connect (fftunegui->revert_button, "clicked", G_CALLBACK (fftunegui_cb_revert_clicked), fftunegui); /* vbox to set vertical spacing of upper outtie frame */ vbox = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox); gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, FALSE, 2); /* upper outtie frame, with spectrum data selector, etc */ frame = gtk_frame_new (NULL); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT); gtk_container_set_border_width (GTK_CONTAINER (frame), 0); gtk_widget_show (frame); gtk_box_pack_start (GTK_BOX (fftunegui), frame, FALSE, FALSE, 0); gtk_container_add (GTK_CONTAINER (frame), vbox); /* lower inset frame for spectrum canvas */ frame = gtk_frame_new (NULL); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); gtk_container_set_border_width (GTK_CONTAINER (frame), 0); gtk_widget_show (frame); gtk_box_pack_start (GTK_BOX (fftunegui), frame, TRUE, TRUE, 0); /* attach a horizontal scrollbar to the spectrum view */ fftunegui->hscrollbar = gtk_hscrollbar_new (NULL); gtk_widget_show (fftunegui->hscrollbar); gtk_box_pack_start (GTK_BOX (fftunegui), fftunegui->hscrollbar, FALSE, FALSE, 0); g_signal_connect_after (gtk_range_get_adjustment (GTK_RANGE (fftunegui->hscrollbar)), "value-changed", G_CALLBACK (fftune_gui_cb_scroll), fftunegui); /* hbox for frequency list and desired root note selector */ hbox = gtk_hbox_new (FALSE, 0); gtk_widget_show (hbox); gtk_container_add (GTK_CONTAINER (frame), hbox); /* create frequency suggestion store */ fftunegui->freq_store = gtk_list_store_new (COL_COUNT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); /* scroll window for frequency suggestion list */ scrollwin = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwin), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_widget_show (scrollwin); gtk_box_pack_start (GTK_BOX (hbox), scrollwin, FALSE, FALSE, 0); /* create frequency suggestion list */ fftunegui->freq_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (fftunegui->freq_store)); /* Disable search, since it breaks piano key playback */ g_object_set (fftunegui->freq_list, "enable-search", FALSE, NULL); gtk_widget_show (fftunegui->freq_list); gtk_container_add (GTK_CONTAINER (scrollwin), GTK_WIDGET (fftunegui->freq_list)); g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (fftunegui->freq_list)), "changed", G_CALLBACK (fftunegui_cb_freq_list_sel_changed), fftunegui); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes (_("Power"), renderer, "text", COL_POWER, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (fftunegui->freq_list), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes (_("Frequency"), renderer, "text", COL_FREQ, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (fftunegui->freq_list), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes (_("Note"), renderer, "text", COL_NOTE, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (fftunegui->freq_list), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes (_("Cents"), renderer, "text", COL_CENTS, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (fftunegui->freq_list), column); /* create canvas */ fftunegui->canvas = GNOME_CANVAS (gnome_canvas_new ()); gnome_canvas_set_center_scroll_region (GNOME_CANVAS (fftunegui->canvas), FALSE); gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (fftunegui->canvas), TRUE, TRUE, 0); g_signal_connect (fftunegui->canvas, "event", G_CALLBACK (fftune_gui_cb_spectrum_canvas_event), fftunegui); g_signal_connect (fftunegui->canvas, "size-allocate", G_CALLBACK (fftune_gui_cb_canvas_size_allocate), fftunegui); /* change background color of canvas to black */ style = gtk_style_copy (gtk_widget_get_style (GTK_WIDGET (fftunegui->canvas))); style->bg[GTK_STATE_NORMAL] = style->black; gtk_widget_set_style (GTK_WIDGET (fftunegui->canvas), style); gtk_widget_show (GTK_WIDGET (fftunegui->canvas)); /* create spectrum canvas item */ fftunegui->spectrum = gnome_canvas_item_new (gnome_canvas_root (fftunegui->canvas), SWAMIGUI_TYPE_SPECTRUM_CANVAS, "adjustment", gtk_range_get_adjustment (GTK_RANGE (fftunegui->hscrollbar)), NULL); /* create snap line */ fftunegui->snap_line = gnome_canvas_item_new (gnome_canvas_root (fftunegui->canvas), GNOME_TYPE_CANVAS_LINE, "fill-color-rgba", fftunegui->snap_line_color, "width-pixels", 2, NULL); gnome_canvas_item_hide (fftunegui->snap_line); /* vertical scale for setting amplitude zoom */ fftunegui->vscale = gtk_vscale_new_with_range (1.0, 100.0, 0.5); gtk_scale_set_draw_value (GTK_SCALE (fftunegui->vscale), FALSE); gtk_range_set_inverted (GTK_RANGE (fftunegui->vscale), TRUE); adj = gtk_range_get_adjustment (GTK_RANGE (fftunegui->vscale)); g_signal_connect (adj, "value-changed", G_CALLBACK (fftune_gui_cb_ampl_zoom_value_changed), fftunegui); gtk_widget_show (fftunegui->vscale); gtk_box_pack_start (GTK_BOX (hbox), fftunegui->vscale, FALSE, FALSE, 0); } static void fftunegui_cb_revert_clicked (GtkButton *button, gpointer user_data) { FFTuneGui *fftunegui = FFTUNE_GUI (user_data); IpatchSample *sample; g_object_get (fftunegui->spectra, "sample", &sample, NULL); /* ++ ref */ if (!sample) return; g_object_set (sample, "root-note", fftunegui->orig_root_note, "fine-tune", fftunegui->orig_fine_tune, NULL); g_object_unref (sample); /* -- unref */ } static void fftunegui_cb_freq_list_sel_changed (GtkTreeSelection *selection, gpointer user_data) { FFTuneGui *fftunegui = FFTUNE_GUI (user_data); IpatchSample *sample; GtkTreeIter iter; char *notestr, *centstr; int note, finetune; if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) return; g_object_get (fftunegui->spectra, "sample", &sample, NULL); /* ++ ref */ if (!sample) return; gtk_tree_model_get (GTK_TREE_MODEL (fftunegui->freq_store), &iter, COL_NOTE, ¬estr, /* ++ alloc */ COL_CENTS, ¢str, /* ++ alloc */ -1); note = strtol (notestr, NULL, 10); finetune = -roundf (strtof (centstr, NULL)); /* Invert cents to get finetune adjustment */ g_object_set (sample, "root-note", note, "fine-tune", finetune, NULL); g_object_unref (sample); /* -- unref */ } static void fftune_gui_cb_spectrum_change (FFTuneSpectra *spectra, guint size, double *spectrum, gpointer user_data) { FFTuneGui *fftunegui = FFTUNE_GUI (user_data); int width, height; double zoom; swamigui_spectrum_canvas_set_data (SWAMIGUI_SPECTRUM_CANVAS (fftunegui->spectrum), spectrum, size, NULL); if (fftunegui->recalc_zoom) { g_object_get (fftunegui->spectrum, "width", &width, "height", &height, NULL); if (width == 0.0) zoom = 0.0; else zoom = size / (double)width; g_object_set (fftunegui->spectrum, "zoom", zoom, NULL); fftunegui->recalc_zoom = FALSE; } } static void fftune_gui_cb_tunings_change (FFTuneSpectra *spectra, guint count, gpointer user_data) { FFTuneGui *fftunegui = FFTUNE_GUI (user_data); GtkTreeIter iter; double power, max_power = 0.0, freq, cents; char powerstr[6], freqstr[32], notestr[11], centsstr[16]; int i, note; gtk_list_store_clear (fftunegui->freq_store); for (i = 0; i < count; i++) { /* select the current tuning index */ g_object_set (spectra, "tune-select", i, NULL); /* get frequency and power of the current tuning suggestion */ g_object_get (spectra, "tune-freq", &freq, "tune-power", &power, NULL); if (i == 0) max_power = power; /* first tuning is max power */ cents = ipatch_unit_hertz_to_cents (freq); note = cents / 100.0 + 0.5; cents -= note * 100; sprintf (powerstr, "%0.2f", power / max_power); sprintf (freqstr, "%0.2f", freq); sprintf (centsstr, "%0.2f", cents); if (note < 0) strcpy (notestr, "<0"); else if (note > 127) strcpy (notestr, ">127"); else { sprintf (notestr, "%d | ", note); swami_util_midi_note_to_str (note, notestr + strlen (notestr)); } gtk_list_store_append (fftunegui->freq_store, &iter); gtk_list_store_set (fftunegui->freq_store, &iter, COL_POWER, powerstr, COL_FREQ, freqstr, COL_NOTE, notestr, COL_CENTS, centsstr, -1); } } /* callback when sample mode combo box changes */ static void fftune_gui_cb_mode_menu_changed (GtkComboBox *combo, gpointer user_data) { FFTuneGui *fftunegui = FFTUNE_GUI (user_data); int active; active = gtk_combo_box_get_active (combo); if (active != -1) g_object_set (fftunegui->spectra, "sample-mode", active, NULL); } static void fftune_gui_cb_limit_changed (GtkComboBox *combo, gpointer user_data) { FFTuneGui *fftunegui = FFTUNE_GUI (user_data); int active; active = gtk_combo_box_get_active (combo); if (active != -1) g_object_set (fftunegui->spectra, "limit", limits[active].limit, NULL); } static void fftune_gui_cb_window_toggled (GtkToggleButton *button, gpointer user_data) { FFTuneGui *fftunegui = FFTUNE_GUI (user_data); g_object_set (fftunegui->spectra, "enable-window", gtk_toggle_button_get_active (button), NULL); } static void fftune_gui_cb_canvas_size_allocate (GtkWidget *widget, GtkAllocation *allocation, gpointer user_data) { FFTuneGui *fftunegui = FFTUNE_GUI (user_data); GnomeCanvas *canvas = GNOME_CANVAS (widget); int width, height; width = GTK_WIDGET (canvas)->allocation.width; height = GTK_WIDGET (canvas)->allocation.height; /* update size of spectrum canvas item */ g_object_set (fftunegui->spectrum, "width", width, "height", height, NULL); } /* horizontal scroll bar value changed callback */ static void fftune_gui_cb_scroll (GtkAdjustment *adj, gpointer user_data) { // FFTuneGui *fftunegui = FFTUNE_GUI (user_data); // marker_control_update_all (fftunegui); /* update all markers */ } static gboolean fftune_gui_cb_spectrum_canvas_event (GnomeCanvas *canvas, GdkEvent *event, gpointer data) { FFTuneGui *fftunegui = FFTUNE_GUI (data); GnomeCanvasPoints *points; // MarkerInfo *marker_info; GdkEventScroll *scroll_event; GdkEventButton *btn_event; GdkEventMotion *motion_event; double scale, zoom; int height; int ofs, val; guint32 timed = G_MAXUINT; switch (event->type) { case GDK_MOTION_NOTIFY: motion_event = (GdkEventMotion *)event; #if 0 if (fftunegui->sel_marker != -1) { marker_info = g_list_nth_data (fftunegui->markers, fftunegui->sel_marker); if (!marker_info) break; val = swamigui_spectrum_canvas_pos_to_sample (SWAMIGUI_SPECTRUM_CANVAS (track_info->sample_view), motion_event->x); g_value_init (&value, G_TYPE_UINT); g_value_set_uint (&value, val); swami_control_transmit_value (marker_info->ctrl, &value); g_value_unset (&value); /* update the marker */ marker_info->sample_pos = val; marker_control_update (marker_info); break; } else /* no active marker selection, see if mouse cursor over marker */ { /* see if mouse is over a marker */ marker_info = fftune_gui_xpos_is_marker (fftunegui, motion_event->x); /* see if cursor should be changed */ if ((marker_info != NULL) != fftunegui->marker_cursor) { if (marker_info) cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW); /* ++ ref */ else cursor = gdk_cursor_new (GDK_LEFT_PTR); gdk_window_set_cursor (GTK_WIDGET (fftunegui->canvas)->window, cursor); gdk_cursor_unref (cursor); fftunegui->marker_cursor = marker_info != NULL; } } #endif if (!fftunegui->snap_active) break; ofs = motion_event->x - fftunegui->snap_pos; val = ABS (ofs); if (val > SNAP_TIMEOUT_PIXEL_RANGE) val = SNAP_TIMEOUT_PIXEL_RANGE; if (ofs != 0) fftunegui->snap_interval = (SNAP_TIMEOUT_PIXEL_RANGE - val) * (SNAP_TIMEOUT_MAX - SNAP_TIMEOUT_MIN) / (SNAP_TIMEOUT_PIXEL_RANGE - 1) + SNAP_TIMEOUT_MIN; else fftunegui->snap_interval = 0; /* add a timeout callback for zoom/scroll if not already added */ if (!fftunegui->snap_timeout_handler && fftunegui->snap_interval > 0) { fftunegui->snap_timeout_handler = g_timeout_add_full (SNAP_TIMEOUT_PRIORITY, fftunegui->snap_interval, fftune_gui_snap_timeout, fftunegui, NULL); } if (motion_event->state & GDK_SHIFT_MASK) { fftunegui->scroll_active = TRUE; g_object_get (fftunegui->spectrum, "zoom", &zoom, NULL); if (ofs >= 0) val = SNAP_SCROLL_MIN; else val = -SNAP_SCROLL_MIN; fftunegui->scroll_amt = zoom * (ofs * SNAP_SCROLL_MULT + val); } else fftunegui->scroll_active = FALSE; if (motion_event->state & GDK_CONTROL_MASK) { fftunegui->zoom_active = TRUE; if (ofs != 0) { fftunegui->zoom_amt = val * (SNAP_ZOOM_MAX - SNAP_ZOOM_MIN) / (SNAP_TIMEOUT_PIXEL_RANGE - 1) + SNAP_ZOOM_MIN; if (ofs < 0) fftunegui->zoom_amt = 1.0 / fftunegui->zoom_amt; } else fftunegui->zoom_amt = 1.0; } else fftunegui->zoom_active = FALSE; break; case GDK_BUTTON_PRESS: btn_event = (GdkEventButton *)event; /* make sure its button 1 */ if (btn_event->button != 1) break; #if 0 /* is it a marker click? */ marker_info = fftune_gui_xpos_is_marker (fftunegui, btn_event->x); if (marker_info) { fftunegui->sel_marker = g_list_index (fftunegui->markers, marker_info); break; } #endif if (!(btn_event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK))) break; fftunegui->snap_active = TRUE; fftunegui->snap_pos = btn_event->x; height = GTK_WIDGET (fftunegui->canvas)->allocation.height; points = gnome_canvas_points_new (2); points->coords[0] = fftunegui->snap_pos; points->coords[1] = 0; points->coords[2] = fftunegui->snap_pos; points->coords[3] = height - 1; g_object_set (fftunegui->snap_line, "points", points, NULL); gnome_canvas_item_show (fftunegui->snap_line); gnome_canvas_points_free (points); break; case GDK_BUTTON_RELEASE: if (!fftunegui->snap_active) break; // if (!fftunegui->snap_active && fftunegui->sel_marker == -1) break; btn_event = (GdkEventButton *)event; if (btn_event->button != 1) break; // fftunegui->sel_marker = -1; fftunegui->snap_active = FALSE; if (fftunegui->snap_timeout_handler != 0) { g_source_remove (fftunegui->snap_timeout_handler); fftunegui->snap_timeout_handler = 0; } fftunegui->scroll_active = FALSE; fftunegui->zoom_active = FALSE; gnome_canvas_item_hide (fftunegui->snap_line); break; case GDK_SCROLL: /* mouse wheel zooming */ scroll_event = (GdkEventScroll *)event; if (scroll_event->direction != GDK_SCROLL_UP && scroll_event->direction != GDK_SCROLL_DOWN) break; if (scroll_event->direction == fftunegui->last_wheel_dir) timed = scroll_event->time - fftunegui->last_wheel_time; timed = CLAMP (timed, WHEEL_ZOOM_MIN_TIME, WHEEL_ZOOM_MAX_TIME); timed -= WHEEL_ZOOM_MIN_TIME; scale = WHEEL_ZOOM_MAX_SPEED + (double)timed / WHEEL_ZOOM_MAX_TIME * WHEEL_ZOOM_RANGE; if (scroll_event->direction == GDK_SCROLL_DOWN) scale = 1 / scale; fftune_gui_zoom_ofs (fftunegui, scale, scroll_event->x); fftunegui->last_wheel_dir = scroll_event->direction; fftunegui->last_wheel_time = scroll_event->time; break; default: break; } return (FALSE); } static gboolean fftune_gui_snap_timeout (gpointer data) { FFTuneGui *fftunegui = FFTUNE_GUI (data); if (fftunegui->scroll_active && fftunegui->scroll_amt != 0) fftune_gui_scroll_ofs (fftunegui, fftunegui->scroll_amt); if (fftunegui->zoom_active && fftunegui->zoom_amt != 1.0) fftune_gui_zoom_ofs (fftunegui, fftunegui->zoom_amt, fftunegui->snap_pos); /* add timeout for next interval */ if (fftunegui->snap_interval > 0) { fftunegui->snap_timeout_handler = g_timeout_add_full (SNAP_TIMEOUT_PRIORITY, fftunegui->snap_interval, fftune_gui_snap_timeout, fftunegui, NULL); } else fftunegui->snap_timeout_handler = 0; return (FALSE); /* remove this timeout */ } static void fftune_gui_cb_ampl_zoom_value_changed (GtkAdjustment *adj, gpointer user_data) { FFTuneGui *fftunegui = FFTUNE_GUI (user_data); /* set vertical zoom */ g_object_set (fftunegui->spectrum, "zoom-ampl", adj->value, NULL); } #if 0 /* check if a given xpos is on a marker */ static MarkerInfo * fftune_gui_xpos_is_marker (FFTuneGui *fftunegui, int xpos) { MarkerInfo *marker_info, *match = NULL; SwamiguiSampleCanvas *sample_view; int x, ofs = -1; GList *p; if (!fftunegui->markers || !fftunegui->tracks) return (NULL); sample_view = SWAMIGUI_SPECTRUM_CANVAS (((TrackInfo *)(fftunegui->tracks->data))->sample_view); for (p = fftunegui->markers; p; p = g_list_next (p)) { marker_info = (MarkerInfo *)(p->data); x = swamigui_spectrum_canvas_sample_to_pos (sample_view, marker_info->sample_pos); if (x != -1) { x = ABS (xpos - x); if (x <= MARKER_CLICK_DISTANCE && (ofs == -1 || x < ofs)) { match = marker_info; ofs = x; } } } return (match); } #endif /* Zoom the spectrum canvas the specified offset amount and modify the * start index position to keep the given X coordinate stationary. */ static void fftune_gui_zoom_ofs (FFTuneGui *fftunegui, double zoom_amt, int zoom_xpos) { double zoom; guint start; guint spectrum_size; int width, index_ofs; g_return_if_fail (FFTUNE_IS_GUI (fftunegui)); /* get current values from spectrum canvas view */ g_object_get (fftunegui->spectrum, "zoom", &zoom, "start", &start, "width", &width, NULL); index_ofs = zoom_xpos * zoom; /* index to zoom xpos */ zoom *= zoom_amt; spectrum_size = SWAMIGUI_SPECTRUM_CANVAS (fftunegui->spectrum)->spectrum_size; /* do some bounds checking on the zoom value */ if (zoom < SPECTRUM_CANVAS_MIN_ZOOM) zoom = SPECTRUM_CANVAS_MIN_ZOOM; else if (width * zoom > spectrum_size) { /* view exceeds spectrum data */ start = 0; zoom = spectrum_size / (double)width; } else { index_ofs -= zoom_xpos * zoom; /* subtract new zoom offset */ if (index_ofs < 0 && -index_ofs > start) start = 0; else start += index_ofs; /* make sure spectrum doesn't end in the middle of the display */ if (start + width * zoom > spectrum_size) start = spectrum_size - width * zoom; } g_object_set (fftunegui->spectrum, "zoom", zoom, "start", start, NULL); } /* Scroll the spectrum canvas by a given offset. */ static void fftune_gui_scroll_ofs (FFTuneGui *fftunegui, int index_ofs) { double zoom; guint start_index; int newstart, width; guint spectrum_size; int last_index; g_return_if_fail (FFTUNE_IS_GUI (fftunegui)); if (index_ofs == 0) return; g_object_get (fftunegui->spectrum, "start", &start_index, "zoom", &zoom, "width", &width, NULL); spectrum_size = SWAMIGUI_SPECTRUM_CANVAS (fftunegui->spectrum)->spectrum_size; last_index = spectrum_size - zoom * width; if (last_index < 0) return; /* spectrum too small for current zoom? */ newstart = (int)start_index + index_ofs; newstart = CLAMP (newstart, 0, last_index); g_object_set (fftunegui->spectrum, "start", newstart, NULL); } swami/src/plugins/fluidsynth_gui_i18n.h0000644000175000017500000000067610774346067020422 0ustar alessioalessio#ifndef __SWAMIPLUGIN_FLUIDSYNTH_GUI_I18N_H__ #define __SWAMIPLUGIN_FLUIDSYNTH_GUI_I18N_H__ #include #ifndef _ #if defined(ENABLE_NLS) # include # define _(x) dgettext("SwamiPlugin-fluidsynth-gui", x) # ifdef gettext_noop # define N_(String) gettext_noop (String) # else # define N_(String) (String) # endif #else # define N_(String) (String) # define _(x) (x) # define gettext(x) (x) #endif #endif #endif swami/src/plugins/fftune.c0000644000175000017500000006127511704446464016006 0ustar alessioalessio/* * fftune.c - Fast Fourier Transform sample tuning plugin * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. * */ #include #include #include #include #include #include /* part of the FFTW package */ #include #include #include #include "fftune_i18n.h" #include "fftune.h" #define DEFAULT_THRESHOLD 0.1 #define DEFAULT_SEPARATION 20.0 #define DEFAULT_MIN_FREQ 20.0 #define DEFAULT_MAX_FREQ 14000.0 #define DEFAULT_MAX_TUNINGS 10 #define MAX_ALLOWED_TUNINGS 1024 /* absolute max tunings allowed */ /* Sample format used internally */ #define SAMPLE_FORMAT IPATCH_SAMPLE_FLOAT | IPATCH_SAMPLE_MONO | IPATCH_SAMPLE_ENDIAN_HOST enum { PROP_0, PROP_ACTIVE, /* when TRUE: spectrum and tuning suggestions are calculated any changes in parameters cause recalc of tuning suggestions */ PROP_SAMPLE, /* sample object to calculate spectrum on */ PROP_SAMPLE_MODE, /* sample calculation mode enum */ PROP_SAMPLE_START, /* start position in sample */ PROP_SAMPLE_END, /* end position in sample */ PROP_LIMIT, /* maximum samples to process or 0 for unlimited */ PROP_THRESHOLD, /* power threshold for tuning suggestions */ PROP_SEPARATION, /* min freq between consecutive tuning suggestions */ PROP_MIN_FREQ, /* minimum frequency for tuning suggestions */ PROP_MAX_FREQ, /* maximum frequency for tuning suggestions */ PROP_MAX_TUNINGS, /* max number of tuning suggestions */ /* properties for selecting and retrieving tuning suggestions */ PROP_TUNE_SELECT, /* for selecting tuning suggestions */ PROP_TUNE_COUNT, /* count of available tuning suggestions */ PROP_TUNE_INDEX, /* index in spectrum data for this tuning suggestion */ PROP_TUNE_POWER, /* power of current tuning (0.0 if no more suggestions) */ PROP_TUNE_FREQ, /* frequency of current tuning */ PROP_ENABLE_WINDOW, /* Enable Hann window of sample data */ PROP_ELLAPSED_TIME /* Ellapsed time of last execution in seconds */ }; enum { SPECTRUM_CHANGE, /* spectrum data change signal */ TUNINGS_CHANGE, /* tuning suggestions changed signal */ SIGNAL_COUNT }; #define ERRMSG_MALLOC_1 "Failed to allocate %d bytes in FFTune plugin" static gboolean plugin_fftune_init (SwamiPlugin *plugin, GError **err); static GType sample_mode_register_type (SwamiPlugin *plugin); static void fftune_spectra_finalize (GObject *object); static void fftune_spectra_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void fftune_spectra_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static gboolean fftune_spectra_calc_spectrum (FFTuneSpectra *spectra); static double *fftune_spectra_run_fftw (void *data, int *dsize); static gboolean fftune_spectra_calc_tunings (FFTuneSpectra *spectra); static gint tuneval_compare_func (gconstpointer a, gconstpointer b); /* set plugin information */ SWAMI_PLUGIN_INFO (plugin_fftune_init, NULL); /* define FFTuneSpectra type */ G_DEFINE_TYPE (FFTuneSpectra, fftune_spectra, G_TYPE_OBJECT); static GType sample_mode_enum_type; static guint obj_signals[SIGNAL_COUNT]; static gboolean plugin_fftune_init (SwamiPlugin *plugin, GError **err) { /* bind the gettext domain */ #if defined(ENABLE_NLS) bindtextdomain ("SwamiPlugin-fftune", LOCALEDIR); #endif g_object_set (plugin, "name", "FFTune", "version", "1.0", "author", "Josh Green", "copyright", "Copyright (C) 2004", "descr", N_("Fast Fourier Transform sample tuner"), "license", "GPL", NULL); /* register types */ sample_mode_enum_type = sample_mode_register_type (plugin); fftune_spectra_get_type (); return (TRUE); } static GType sample_mode_register_type (SwamiPlugin *plugin) { static const GEnumValue values[] = { { FFTUNE_MODE_SELECTION, "FFTUNE_MODE_SELECTION", "Selection" }, { FFTUNE_MODE_LOOP, "FFTUNE_MODE_LOOP", "Loop" }, { 0, NULL, NULL } }; static GTypeInfo enum_info = { 0, NULL, NULL, NULL, NULL, NULL, 0, 0, NULL }; /* initialize the type info structure for the enum type */ g_enum_complete_type_info (G_TYPE_ENUM, &enum_info, values); return (g_type_module_register_type (G_TYPE_MODULE (plugin), G_TYPE_ENUM, "FFTuneSampleMode", &enum_info, 0)); } static void fftune_spectra_class_init (FFTuneSpectraClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); obj_class->set_property = fftune_spectra_set_property; obj_class->get_property = fftune_spectra_get_property; obj_class->finalize = fftune_spectra_finalize; /* This signal gets emitted when spectrum data changes. The pointer argument is the new spectrum data (array of doubles), after this signal is emitted the old spectrum data should no longer be accessed. The unsigned int is the array size. */ obj_signals[SPECTRUM_CHANGE] = g_signal_new ("spectrum-change", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__UINT_POINTER, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_POINTER); /* signal emitted when tuning suggestions change, first parameter is the count of tuning suggestions (equivalent to "tune-count") */ obj_signals[TUNINGS_CHANGE] = g_signal_new ("tunings-change", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT); g_object_class_install_property (obj_class, PROP_ACTIVE, g_param_spec_boolean ("active", _("Active"), _("Active"), FALSE, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_SAMPLE, g_param_spec_object ("sample", _("Sample"), _("Sample"), IPATCH_TYPE_SAMPLE, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_SAMPLE_MODE, g_param_spec_enum ("sample-mode", _("Sample mode"), _("Sample spectrum mode"), sample_mode_enum_type, FFTUNE_MODE_SELECTION, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_SAMPLE_START, g_param_spec_uint ("sample-start", _("Sample start"), _("Sample start"), 0, G_MAXINT, 0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_SAMPLE_END, g_param_spec_uint ("sample-end", _("Sample end"), _("Sample end"), 0, G_MAXUINT, 0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_LIMIT, g_param_spec_uint ("limit", _("Limit"), _("Limit"), 0, G_MAXUINT, 0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_THRESHOLD, g_param_spec_float ("threshold", _("Threshold"), _("Min ratio to max power of tuning suggestions"), 0.0, 1.0, DEFAULT_THRESHOLD, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_SEPARATION, g_param_spec_float ("separation", _("Separation"), _("Min frequency separation between tunings"), 0.0, 24000.0, DEFAULT_SEPARATION, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_MIN_FREQ, g_param_spec_float ("min-freq", _("Min frequency"), _("Min frequency of tuning suggestions"), 0.0, 24000.0, DEFAULT_MIN_FREQ, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_MAX_FREQ, g_param_spec_float ("max-freq", _("Max frequency"), _("Max frequency of tuning suggestions"), 0.0, 24000.0, DEFAULT_MAX_FREQ, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_MAX_TUNINGS, g_param_spec_int ("max-tunings", _("Max tunings"), _("Max tuning suggestions"), 0, MAX_ALLOWED_TUNINGS, DEFAULT_MAX_TUNINGS, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_TUNE_SELECT, g_param_spec_int ("tune-select", _("Tune select"), _("Select tuning suggestion by index"), 0, MAX_ALLOWED_TUNINGS, 0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_TUNE_COUNT, g_param_spec_int ("tune-count", _("Tune count"), _("Count of tuning suggestions"), 0, MAX_ALLOWED_TUNINGS, 0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_TUNE_INDEX, g_param_spec_int ("tune-index", _("Tune index"), _("Spectrum index of current tuning"), 0, G_MAXINT, 0, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_TUNE_POWER, g_param_spec_double ("tune-power", _("Tune power"), _("Power of current tuning"), 0.0, G_MAXDOUBLE, 0.0, G_PARAM_READABLE)); g_object_class_install_property (obj_class, PROP_TUNE_FREQ, g_param_spec_double ("tune-freq", _("Tune frequency"), _("Frequency of current tuning"), 0.0, G_MAXDOUBLE, 0.0, G_PARAM_READABLE)); g_object_class_install_property (obj_class, PROP_ENABLE_WINDOW, g_param_spec_boolean ("enable-window", _("Enable window"), _("Enable window"), FALSE, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, PROP_ELLAPSED_TIME, g_param_spec_float ("ellapsed-time", _("Ellapsed time"), _("Ellapsed time of last execution in seconds"), 0.0, G_MAXFLOAT, 0.0, G_PARAM_READABLE)); } static void fftune_spectra_init (FFTuneSpectra *spectra) { spectra->sample_mode = FFTUNE_MODE_SELECTION; spectra->threshold = DEFAULT_THRESHOLD; spectra->separation = DEFAULT_SEPARATION; spectra->min_freq = DEFAULT_MIN_FREQ; spectra->max_freq = DEFAULT_MAX_FREQ; spectra->max_tunings = DEFAULT_MAX_TUNINGS; } static void fftune_spectra_finalize (GObject *object) { FFTuneSpectra *spectra = FFTUNE_SPECTRA (object); if (spectra->spectrum) fftw_free (spectra->spectrum); if (spectra->sample) g_object_unref (spectra->sample); if (spectra->tunevals) g_free (spectra->tunevals); } static void fftune_spectra_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { FFTuneSpectra *spectra = FFTUNE_SPECTRA (object); gboolean spectrum_update = FALSE; gboolean tunings_update = FALSE; switch (property_id) { case PROP_ACTIVE: if (!spectra->active && g_value_get_boolean (value)) /* activating? */ spectrum_update = TRUE; spectra->active = g_value_get_boolean (value); break; case PROP_SAMPLE: if (g_value_get_object (value) == spectra->sample) break; if (spectra->sample) g_object_unref (spectra->sample); spectra->sample = g_value_get_object (value); if (spectra->sample) g_object_ref (spectra->sample); spectrum_update = TRUE; break; case PROP_SAMPLE_MODE: if (g_value_get_enum (value) == spectra->sample_mode) break; spectra->sample_mode = g_value_get_enum (value); spectrum_update = TRUE; break; case PROP_SAMPLE_START: if (g_value_get_uint (value) == spectra->sample_start) break; spectra->sample_start = g_value_get_uint (value); spectrum_update = TRUE; break; case PROP_SAMPLE_END: if (g_value_get_uint (value) == spectra->sample_end) break; spectra->sample_end = g_value_get_uint (value); spectrum_update = TRUE; break; case PROP_LIMIT: if (g_value_get_uint (value) == spectra->limit) break; spectra->limit = g_value_get_uint (value); spectrum_update = TRUE; break; case PROP_THRESHOLD: if (g_value_get_float (value) == spectra->threshold) break; spectra->threshold = g_value_get_float (value); tunings_update = TRUE; break; case PROP_SEPARATION: if (g_value_get_float (value) == spectra->separation) break; spectra->separation = g_value_get_float (value); tunings_update = TRUE; break; case PROP_MIN_FREQ: if (g_value_get_float (value) == spectra->min_freq) break; spectra->min_freq = g_value_get_float (value); tunings_update = TRUE; break; case PROP_MAX_FREQ: if (g_value_get_float (value) == spectra->max_freq) break; spectra->max_freq = g_value_get_float (value); tunings_update = TRUE; break; case PROP_MAX_TUNINGS: if (g_value_get_int (value) == spectra->max_tunings) break; spectra->max_tunings = g_value_get_int (value); tunings_update = TRUE; break; case PROP_TUNE_SELECT: spectra->tune_select = g_value_get_int (value); break; case PROP_ENABLE_WINDOW: if (g_value_get_boolean (value) == spectra->enable_window) break; spectra->enable_window = g_value_get_boolean (value); spectrum_update = TRUE; break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } if (spectra->active && spectra->sample) { if (spectrum_update) /* spectrum need update? */ { if (fftune_spectra_calc_spectrum (spectra)) fftune_spectra_calc_tunings (spectra); } else if (tunings_update) /* tuning values need update? */ fftune_spectra_calc_tunings (spectra); } } static void fftune_spectra_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { FFTuneSpectra *spectra = FFTUNE_SPECTRA (object); int index; switch (property_id) { case PROP_ACTIVE: g_value_set_boolean (value, spectra->active); break; case PROP_SAMPLE: g_value_set_object (value, spectra->sample); break; case PROP_SAMPLE_MODE: g_value_set_enum (value, spectra->sample_mode); break; case PROP_SAMPLE_START: g_value_set_uint (value, spectra->sample_start); break; case PROP_SAMPLE_END: g_value_set_uint (value, spectra->sample_end); break; case PROP_LIMIT: g_value_set_uint (value, spectra->limit); break; case PROP_THRESHOLD: g_value_set_float (value, spectra->threshold); break; case PROP_SEPARATION: g_value_set_float (value, spectra->separation); break; case PROP_MIN_FREQ: g_value_set_float (value, spectra->min_freq); break; case PROP_MAX_FREQ: g_value_set_float (value, spectra->max_freq); break; case PROP_MAX_TUNINGS: g_value_set_int (value, spectra->max_tunings); break; case PROP_TUNE_SELECT: g_value_set_int (value, spectra->tune_select); break; case PROP_TUNE_COUNT: g_value_set_int (value, spectra->n_tunevals); break; case PROP_TUNE_INDEX: if (spectra->tunevals && spectra->tune_select < spectra->n_tunevals) g_value_set_int (value, spectra->tunevals[spectra->tune_select]); else g_value_set_int (value, 0); break; case PROP_TUNE_POWER: if (spectra->tunevals && spectra->tune_select < spectra->n_tunevals && spectra->spectrum) { index = spectra->tunevals[spectra->tune_select]; g_value_set_double (value, spectra->spectrum[index]); } else g_value_set_double (value, 0.0); break; case PROP_TUNE_FREQ: if (spectra->tunevals && spectra->tune_select < spectra->n_tunevals && spectra->spectrum) { index = spectra->tunevals[spectra->tune_select]; g_value_set_double (value, spectra->freqres * index); } else g_value_set_double (value, 0.0); break; case PROP_ENABLE_WINDOW: g_value_set_boolean (value, spectra->enable_window); break; case PROP_ELLAPSED_TIME: g_value_set_float (value, spectra->ellapsed_time); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static gboolean fftune_spectra_calc_spectrum (FFTuneSpectra *spectra) { guint start, sample_size, loop_start, loop_end; IpatchSampleHandle handle; GError *err = NULL; void *data; /* Stores sample data (floats) */ double *result; /* FFT power spectrum result */ int dsize, result_size; int count, i; GTimeVal start_time, end_time; float ellapsed; g_return_val_if_fail (spectra->sample != NULL, FALSE); g_object_get (spectra->sample, "sample-size", &sample_size, "loop-start", &loop_start, "loop-end", &loop_end, NULL); if (spectra->sample_mode == FFTUNE_MODE_LOOP) /* loop mode? */ { start = loop_start; count = loop_end - loop_start; /* number of samples in loop */ dsize = count * 2 + 1; /* 2 iterations + 1 (first sample appended) */ } else /* selection mode */ { if (spectra->sample_start == 0 && spectra->sample_end == 0) { start = 0; count = sample_size; } else { if (spectra->sample_start <= spectra->sample_end) { start = spectra->sample_start; count = spectra->sample_end - spectra->sample_start + 1; } else /* swap start/end if backwards */ { start = spectra->sample_end; count = spectra->sample_start - spectra->sample_end + 1; } } if (spectra->limit && count > spectra->limit) count = spectra->limit; dsize = count; } /* Allocate sample/result buffer, sample data is stored as floats and result * is stored as doubles (dsize / 2 + 1 in length). */ data = g_try_malloc (sizeof (double) * (dsize / 2 + 1)); /* allocate transform array */ if (!data) { g_critical (_(ERRMSG_MALLOC_1), sizeof (double) * (dsize / 2 + 1)); return (FALSE); } if (!ipatch_sample_handle_open (spectra->sample, &handle, 'r', SAMPLE_FORMAT, IPATCH_SAMPLE_UNITY_CHANNEL_MAP, &err)) { g_critical ("Failed to open sample in FFTune plugin: %s", ipatch_gerror_message (err)); g_error_free (err); g_free (data); return (FALSE); } /* load the sample data */ if (!ipatch_sample_handle_read (&handle, start, count, data, &err)) { g_critical ("Failed to read sample data in FFTune plugin: %s", ipatch_gerror_message (err)); g_error_free (err); ipatch_sample_handle_close (&handle); g_free (data); return (FALSE); } ipatch_sample_handle_close (&handle); if (spectra->sample_mode == FFTUNE_MODE_LOOP) /* do 2 iterations for loops */ { for (i=0; i < count; i++) ((float *)data)[i + count] = ((float *)data)[i]; /* append first sample to end to complete the 2 cycles */ ((float *)data)[dsize - 1] = ((float *)data)[0]; } result_size = dsize; g_get_current_time (&start_time); if (spectra->enable_window) { for (i = 0; i < dsize; i++) ((float *)data)[i] *= 0.5 * (1.0 - cos (2.0 * G_PI * ((float)i / (dsize - 1)))); } /* Calculate FFT power spectrum of sample data. Result is returned in the same array. */ result = fftune_spectra_run_fftw (data, &result_size); g_get_current_time (&end_time); ellapsed = (end_time.tv_sec - start_time.tv_sec) + (end_time.tv_usec - start_time.tv_usec) / 1000000.0; spectra->ellapsed_time = ellapsed; if (!result) { g_free (data); return (FALSE); } /* emit spectrum-change signal */ g_signal_emit (spectra, obj_signals[SPECTRUM_CHANGE], 0, result_size, result); g_free (spectra->spectrum); spectra->spectrum = result; spectra->spectrum_size = result_size; return (TRUE); } static double * fftune_spectra_run_fftw (void *data, int *dsize) { fftwf_plan fftplan; float *outdata; int size = *dsize; int outsize; int i, x; outsize = size / 2 + 1; outdata = fftwf_malloc (sizeof (float) * size); /* allocate output transform array */ if (!outdata) { g_critical (_(ERRMSG_MALLOC_1), sizeof (float) * size); return (NULL); } /* create FFTW plan (real to half complex, in place transform) */ fftplan = fftwf_plan_r2r_1d (size, data, outdata, FFTW_R2HC, FFTW_ESTIMATE); fftwf_execute (fftplan); /* do the FFT calculation */ fftwf_destroy_plan (fftplan); /* compute power spectrum (its stored over the output array) */ ((double *)data)[0] = outdata[0] * outdata[0]; /* DC component */ x = (size+1) / 2; for (i=1; i < x; ++i) /* (i < size/2 rounded up) */ ((double *)data)[i] = outdata[i] * outdata[i] + outdata[size - i] * outdata[size - i]; if (size % 2 == 0) /* count is even? */ ((double *)data)[size / 2] = outdata[size / 2] * outdata[size / 2]; /* Nyquist freq. */ fftwf_free (outdata); *dsize = outsize; /* Resize data array to size of FFT power data */ data = realloc (data, sizeof (double) * outsize); return (data); } /* typebag for temporary sorted GList of tunings. Wouldn't need it if * g_list_insert_sorted had a user data parameter -:( */ typedef struct { double *spectrum; int index; } TuneBag; static gboolean fftune_spectra_calc_tunings (FFTuneSpectra *spectra) { GList *sugvals = NULL, *p; /* list of spectrum indexes */ double *spectrum; TuneBag *bag; int sugcount = 0; int tolndx, tolcount; double max, val, full_max, threshold; int i, start, stop, maxndx; int sample_rate; g_return_val_if_fail (spectra->sample != NULL, FALSE); g_return_val_if_fail (spectra->spectrum != NULL, FALSE); spectrum = spectra->spectrum; threshold = spectra->threshold; g_object_get (spectra->sample, "sample-rate", &sample_rate, NULL); /* frequency resolution (frequency difference between array indexes) */ spectra->freqres = (double)sample_rate / ((spectra->spectrum_size - 1) * 2); /* separation amount in array index units for selecting unique tunings */ tolndx = spectra->separation / spectra->freqres + 0.5; /* don't care about anything below min_freq */ start = (int)(spectra->min_freq / spectra->freqres) + 1; start = CLAMP (start, 0, spectra->spectrum_size - 1); /* don't care about anything above max_freq */ stop = spectra->max_freq / spectra->freqres; stop = CLAMP (stop, 0, spectra->spectrum_size - 1); /* get maximum power in frequency range (full_max) */ for (i = start, full_max = 0.0; i <= stop; i++) { val = spectrum[i]; if (val > full_max) full_max = val; } if (full_max == 0.0) full_max = 1.0; /* div/0 protection */ /* printf ("spectrum_size = %d, freqres = %0.2f, tolndx = %d, start = %d, stop = %d\n", spectra->spectrum_size, spectra->freqres, tolndx, start, stop); */ tolcount = tolndx; /* separation counter */ max = 0.0; /* current maximum power */ maxndx = -1; /* spectrum index of current maximum */ for (i = start; i <= stop; i++) { val = spectra->spectrum[i]; /* power of frequency exceeds full_max threshold ratio? */ if (val / full_max >= threshold) { if (val > max) /* find frequency with most power */ { /* new maximum */ max = val; maxndx = i; } tolcount = tolndx; /* reset separation counter */ } /* Do we have a frequency suggestion and no threshold, last index or separation counter expired? */ if (maxndx >= 0 && (threshold == 0.0 || tolcount-- <= 0 || i == stop - 1)) { /* if max tunevals exceeded, remove the least powerful one i.e. the little guy gets sacked. */ if (sugcount == spectra->max_tunings) { bag = sugvals->data; /* steal the TuneBag */ sugvals = g_list_delete_link (sugvals, sugvals); } else { bag = g_new (TuneBag, 1); bag->spectrum = spectra->spectrum; sugcount++; } bag->index = maxndx; /* add to tuning suggestion list using sort function (reverse sort) */ sugvals = g_list_insert_sorted (sugvals, bag, (GCompareFunc)tuneval_compare_func); /* reset variables */ tolcount = tolndx; max = 0.0; maxndx = -1; } } spectra->n_tunevals = sugcount; if (sugcount > 0) { spectra->tunevals = g_realloc (spectra->tunevals, sizeof (int) * sugcount); /* list is reverse sorted, so copy to descending array indexes */ for (i = sugcount - 1, p = sugvals; i >= 0; i--) { bag = (TuneBag *)(p->data); spectra->tunevals[i] = bag->index; g_free (bag); p = g_list_delete_link (p, p); } } else { g_free (spectra->tunevals); spectra->tunevals = NULL; } spectra->tune_select = 0; /* emit tunings-change signal */ g_signal_emit (spectra, obj_signals[TUNINGS_CHANGE], 0, sugcount); return (TRUE); } /* reverse sorted, so that tuneval with smallest value is always first for quick removal */ static gint tuneval_compare_func (gconstpointer a, gconstpointer b) { TuneBag *abag = (TuneBag *)a, *bbag = (TuneBag *)b; double f; f = abag->spectrum[abag->index] - bbag->spectrum[bbag->index]; if (f < 0.0) return -1; if (f > 0.0) return 1; return 0; } swami/src/plugins/Makefile.am0000644000175000017500000000330511464321230016357 0ustar alessioalessio## Process this file with automake to produce Makefile.in if PLATFORM_WIN32 no_undefined = -no-undefined -export-symbols fluidsynth_la_def = fluidsynth.def endif EXTRA_DIST = \ fftune.c \ fftune.h \ fftune_gui.c \ fftune_gui.h \ fftune_i18n.h \ fluidsynth.c \ fluidsynth.glade \ fluidsynth_i18n.c \ fluidsynth_i18n.h \ fluidsynth_gui.c \ fluidsynth_gui_i18n.h if FLUIDSYNTH_SUPPORT fluidsynth_lib = fluidsynth_plugin.la fluidsynth_gui_lib = fluidsynth_gui.la endif if FFTW_SUPPORT fftune_lib = fftune.la fftune_gui_lib = fftune_gui.la endif pkglib_LTLIBRARIES = $(fluidsynth_lib) $(fluidsynth_gui_lib) \ $(fftune_lib) $(fftune_gui_lib) fluidsynth_plugin_la_SOURCES = fluidsynth.c fluidsynth_i18n.h fluidsynth_plugin_la_CFLAGS = @FLUIDSYNTH_CFLAGS@ @LIBINSTPATCH_CFLAGS@ @GUI_CFLAGS@ fluidsynth_plugin_la_LDFLAGS = $(no_undefined) $(fluidsynth_la_def) \ -module -avoid-version @FLUIDSYNTH_LIBS@ @GUI_LIBS@ \ ../libswami/libswami.la fluidsynth_gui_la_SOURCES = fluidsynth_gui.c fluidsynth_gui_i18n.h fluidsynth_gui_la_CFLAGS = @GUI_CFLAGS@ @LIBINSTPATCH_CFLAGS@ fluidsynth_gui_la_LDFLAGS = -module -avoid-version @GUI_LIBS@ @LIBINSTPATCH_LIBS@ fftune_la_SOURCES = fftune.c fftune.h fftune_i18n.h fftune_la_CFLAGS = @FFTW_CFLAGS@ @LIBINSTPATCH_CFLAGS@ fftune_la_LDFLAGS = -module -avoid-version fftune_la_LIBADD = @FFTW_LIBS@ @LIBINSTPATCH_LIBS@ fftune_gui_la_SOURCES = fftune_gui.c fftune_gui.h fftune_i18n.h fftune_gui_la_CFLAGS = @GUI_CFLAGS@ @LIBINSTPATCH_CFLAGS@ fftune_gui_la_LDFLAGS = -module -avoid-version @GUI_LIBS@ @LIBINSTPATCH_LIBS@ INCLUDES = -I$(top_srcdir)/src/libinstpatch -I$(top_srcdir)/src \ -I$(top_srcdir)/intl -DLOCALEDIR=\"$(datadir)/locale\" MAINTAINERCLEANFILES = Makefile.in swami/src/plugins/fftune_i18n.h0000644000175000017500000000064610157753120016634 0ustar alessioalessio#ifndef __SWAMIPLUGIN_FFTUNE_I18N_H__ #define __SWAMIPLUGIN_FFTUNE_I18N_H__ #include #ifndef _ #if defined(ENABLE_NLS) # include # define _(x) dgettext("SwamiPlugin-FFTune", x) # ifdef gettext_noop # define N_(String) gettext_noop (String) # else # define N_(String) (String) # endif #else # define N_(String) (String) # define _(x) (x) # define gettext(x) (x) #endif #endif #endif swami/src/plugins/CMakeLists.txt0000644000175000017500000000606311466101732017074 0ustar alessioalessio# # Swami # Copyright (C) 1999-2010 Joshua "Element" Green # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; version 2 # of the License only. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA or point your web browser to http://www.gnu.org. # include_directories ( ${CMAKE_SOURCE_DIR}/src ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${GOBJECT_INCLUDEDIR} ${GOBJECT_INCLUDE_DIRS} ${GUI_INCLUDEDIR} ${GUI_INCLUDE_DIRS} ${LIBINSTPATCH_INCLUDEDIR} ${LIBINSTPATCH_INCLUDE_DIRS} ${FLUIDSYNTH_INCLUDEDIR} ${FLUIDSYNTH_INCLUDE_DIRS} ${FFTW_INCLUDEDIR} ${FFTW_INCLUDE_DIRS} ) if ( FLUIDSYNTH_SUPPORT ) link_directories ( ${GOBJECT_LIBDIR} ${GOBJECT_LIBRARY_DIRS} ${LIBINSTPATCH_LIBDIR} ${LIBINSTPATCH_LIBRARY_DIRS} ${FLUIDSYNTH_LIBDIR} ${FLUIDSYNTH_LIBRARY_DIRS} ) add_library ( fluidsynth_plugin MODULE fluidsynth.c ) target_link_libraries ( fluidsynth_plugin libswami libswamigui ${GOBJECT_LIBRARIES} ${LIBINSTPATCH_LIBRARIES} ${FLUIDSYNTH_LIBRARIES} ) link_directories ( ${GUI_LIBDIR} ${GUI_LIBRARY_DIRS} ${LIBINSTPATCH_LIBDIR} ${LIBINSTPATCH_LIBRARY_DIRS} ${FLUIDSYNTH_LIBDIR} ${FLUIDSYNTH_LIBRARY_DIRS} ) add_library ( fluidsynth_gui MODULE fluidsynth_gui.c ) target_link_libraries ( fluidsynth_gui libswami libswamigui ${GUI_LIBRARIES} ${LIBINSTPATCH_LIBRARIES} ${FLUIDSYNTH_LIBRARIES} ) set_target_properties ( fluidsynth_plugin PROPERTIES PREFIX "" ) set_target_properties ( fluidsynth_gui PROPERTIES PREFIX "" ) install ( TARGETS fluidsynth_plugin fluidsynth_gui RUNTIME DESTINATION ${PLUGINS_DIR} LIBRARY DESTINATION ${PLUGINS_DIR} ) endif ( FLUIDSYNTH_SUPPORT ) if ( FFTW_SUPPORT ) link_directories ( ${GOBJECT_LIBDIR} ${GOBJECT_LIBRARY_DIRS} ${LIBINSTPATCH_LIBDIR} ${LIBINSTPATCH_LIBRARY_DIRS} ${FFTW_LIBDIR} ${FFTW_DIRS} ) add_library ( fftune MODULE fftune.c ) target_link_libraries ( fftune libswami ${GOBJECT_LIBRARIES} ${LIBINSTPATCH_LIBRARIES} ${FFTW_LIBRARIES} ) link_directories ( ${GUI_LIBDIR} ${GUI_LIBRARY_DIRS} ${LIBINSTPATCH_LIBDIR} ${LIBINSTPATCH_LIBRARY_DIRS} ) add_library ( fftune_gui MODULE fftune_gui.c ) target_link_libraries ( fftune_gui libswami libswamigui ${GUI_LIBRARIES} ${LIBINSTPATCH_LIBRARIES} ) set_target_properties ( fftune PROPERTIES PREFIX "" ) set_target_properties ( fftune_gui PROPERTIES PREFIX "" ) install ( TARGETS fftune fftune_gui RUNTIME DESTINATION ${PLUGINS_DIR} LIBRARY DESTINATION ${PLUGINS_DIR} ) endif ( FFTW_SUPPORT ) swami/src/plugins/fftune_gui.h0000644000175000017500000000711211464321230016627 0ustar alessioalessio/* * fftune_gui.h - FFTune GUI object (Fast Fourier sample tuning GUI) * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __FFTUNE_GUI_H__ #define __FFTUNE_GUI_H__ #include #include #include typedef struct _FFTuneGui FFTuneGui; typedef struct _FFTuneGuiClass FFTuneGuiClass; /* Defined in fftune.h */ typedef struct _FFTuneSpectra FFTuneSpectra; #define FFTUNE_TYPE_GUI (fftune_gui_get_type ()) #define FFTUNE_GUI(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), FFTUNE_TYPE_GUI, FFTuneGui)) #define FFTUNE_GUI_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), FFTUNE_TYPE_GUI, FFTuneGuiClass)) #define FFTUNE_IS_GUI(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FFTUNE_TYPE_GUI)) #define FFTUNE_IS_GUI_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), FFTUNE_TYPE_GUI)) /* Sample view object */ struct _FFTuneGui { GtkVBox parent; /* derived from GtkVBox */ FFTuneSpectra *spectra; /* FFTuneSpectra object (fftune.[ch]) */ gboolean snap_active; /* set to TRUE when a snap zoom/scroll is active */ int snap_pos; /* xpos of zoom/scroll snap line */ guint snap_timeout_handler; /* snap timeout callback handler ID */ guint snap_interval; /* interval in milliseconds for timeout handler */ gboolean scroll_active; /* TRUE if SHIFT scrolling is active */ gboolean zoom_active; /* TRUE if CTRL zooming is active */ int scroll_amt; /* scroll amount for each timeout in samples */ double zoom_amt; /* zoom multiplier for each timeout */ /* for mouse wheel scrolling */ GdkScrollDirection last_wheel_dir; /* last wheel direction */ guint32 last_wheel_time; /* last time stamp of mouse wheel */ GnomeCanvas *canvas; /* canvas */ GnomeCanvasItem *spectrum; /* SwamiguiSpectrumCanvas item */ GnomeCanvasItem *snap_line; /* zoom/scroll snap line */ gboolean recalc_zoom; /* TRUE to recalc full zoom (after sample change) */ GtkWidget *mode_menu; /* data selection menu */ GtkWidget *hscrollbar; /* horizontal scrollbar widget */ GtkListStore *freq_store; /* store for freq tuning list */ GtkWidget *freq_list; /* GtkTreeView list of freq tuning suggestions */ GtkWidget *vscale; /* Vertical scale widget */ GtkWidget *root_notesel; /* root note selector widget */ GtkWidget *fine_tune; /* fine tune spin button */ GtkWidget *revert_button; /* Revert button */ SwamiControl *root_note_ctrl; /* root note Swami control */ SwamiControl *fine_tune_ctrl; /* fine tune Swami control */ guint8 orig_root_note; /* Original root note value */ guint8 orig_fine_tune; /* Original fine tune value */ guint snap_line_color; /* zoom/scroll snap line color */ }; /* Sample view object class */ struct _FFTuneGuiClass { GtkVBoxClass parent_class; }; GType fftune_gui_get_type (void); GtkWidget *fftune_gui_new (void); #endif swami/src/plugins/fluidsynth.c0000644000175000017500000020444611461334205016674 0ustar alessioalessio/* * fluidsynth.c - Swami plugin for FluidSynth * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include "config.h" #include #include #include #include #include #include #include #include "fluidsynth_i18n.h" /* max voices per instrument (voices exceeding this will not sound) */ #define MAX_INST_VOICES 128 /* maximum # of voices under real time control (voices exceeding this number just wont be controllable in real time, no fatal problems though) */ #define MAX_REALTIME_VOICES 64 /* maximum realtime effect parameter updates for a single property change */ #define MAX_REALTIME_UPDATES 128 /* default number of synth channels (FIXME - dynamic?) */ #define DEFAULT_CHANNEL_COUNT 16 /* max length of reverb/chorus preset names (including '\0') */ #define PRESET_NAME_LEN 21 typedef struct _WavetblFluidSynth WavetblFluidSynth; typedef struct _WavetblFluidSynthClass WavetblFluidSynthClass; #define WAVETBL_TYPE_FLUIDSYNTH (wavetbl_type) #define WAVETBL_FLUIDSYNTH(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), WAVETBL_TYPE_FLUIDSYNTH, \ WavetblFluidSynth)) #define WAVETBL_FLUIDSYNTH_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), WAVETBL_TYPE_FLUIDSYNTH, \ WavetblFluidSynthClass)) #define WAVETBL_IS_FLUIDSYNTH(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), WAVETBL_TYPE_FLUIDSYNTH)) #define WAVETBL_IS_FLUIDSYNTH_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), WAVETBL_TYPE_FLUIDSYNTH)) typedef struct _realtime_noteon_t realtime_noteon_t; #define INTERPOLATION_TYPE (interp_mode_type) /* structure for storing reverb parameters */ typedef struct { char name[PRESET_NAME_LEN]; /* for presets */ double room_size; double damp; double width; double level; } ReverbParams; /* structure for storing chorus parameters */ typedef struct { char name[PRESET_NAME_LEN]; /* for presets */ int count; double level; double freq; double depth; int waveform; } ChorusParams; #define CHORUS_WAVEFORM_TYPE (chorus_waveform_type) /* FluidSynth SwamiWavetbl object */ struct _WavetblFluidSynth { SwamiWavetbl object; /* derived from SwamiWavetbl */ fluid_synth_t *synth; /* the FluidSynth handle */ fluid_settings_t *settings; /* to free on close */ fluid_audio_driver_t *audio; /* FluidSynth audio driver */ fluid_midi_driver_t *midi; /* FluidSynth MIDI driver */ fluid_midi_router_t *midi_router; /* FluidSynth MIDI router */ SwamiControlMidi *midi_ctrl; /* MIDI control */ guint prop_callback_handler_id; /* property change handler ID */ GSList *mods; /* session modulators */ int channel_count; /* number of MIDI channels */ guint8 *banks; /* bank numbers for each channel */ guint8 *programs; /* program numbers for each channel */ int interp; /* interpolation type */ gboolean reverb_update; /* TRUE if reverb needs update */ ReverbParams reverb_params; /* current reverb parameters */ gboolean chorus_update; /* TRUE if chorus needs update */ ChorusParams chorus_params; /* current chorus parameters */ /* active item is the focus, allow realtime control of most recent note of active item. */ IpatchItem *active_item; /* active audible instrument */ IpatchItem *solo_item; /* child of active item to solo or NULL */ IpatchSF2VoiceCache *rt_cache; /* voice cache of active_item */ int rt_sel_values[IPATCH_SF2_VOICE_CACHE_MAX_SEL_VALUES]; /* sel criteria of note */ fluid_voice_t *rt_voices[MAX_REALTIME_VOICES]; /* FluidSynth voices */ int rt_count; /* count for rt_index_array and rt_voices */ }; /* FluidSynth wavetbl class */ struct _WavetblFluidSynthClass { SwamiWavetblClass parent_class; /* derived from SwamiWavetblClass */ }; enum { WTBL_PROP_0, WTBL_PROP_INTERP, WTBL_PROP_REVERB_PRESET, WTBL_PROP_REVERB_ROOM_SIZE, WTBL_PROP_REVERB_DAMP, WTBL_PROP_REVERB_WIDTH, WTBL_PROP_REVERB_LEVEL, WTBL_PROP_CHORUS_PRESET, WTBL_PROP_CHORUS_COUNT, WTBL_PROP_CHORUS_LEVEL, WTBL_PROP_CHORUS_FREQ, WTBL_PROP_CHORUS_DEPTH, WTBL_PROP_CHORUS_WAVEFORM, WTBL_PROP_ACTIVE_ITEM, WTBL_PROP_SOLO_ITEM, WTBL_PROP_MODULATORS }; /* number to use for first dynamic (FluidSynth settings) property */ #define FIRST_DYNAMIC_PROP 256 /* FluidSynth MIDI event types (MIDI control codes) */ enum { WAVETBL_FLUID_NOTE_OFF = 0x80, WAVETBL_FLUID_NOTE_ON = 0x90, WAVETBL_FLUID_CONTROL_CHANGE = 0xb0, WAVETBL_FLUID_PROGRAM_CHANGE = 0xc0, WAVETBL_FLUID_PITCH_BEND = 0xe0 }; #define _SYNTH_OK 0 /* FLUID_OK not defined in header */ /* additional data for sfloader patch base objects */ typedef struct { WavetblFluidSynth *wavetbl; /* wavetable object */ IpatchBase *base_item; /* IpatchBase object */ } sfloader_sfont_data_t; typedef struct { WavetblFluidSynth *wavetbl; /* wavetable object */ IpatchItem *item; /* instrument item */ } sfloader_preset_data_t; /* FluidSynth property flags (for exceptions such as string booleans) */ typedef enum { PROP_STRING_BOOL = 1 << 0 } PropFlags; static gboolean plugin_fluidsynth_init (SwamiPlugin *plugin, GError **err); static gboolean plugin_fluidsynth_save_xml (SwamiPlugin *plugin, GNode *xmlnode, GError **err); static gboolean plugin_fluidsynth_load_xml (SwamiPlugin *plugin, GNode *xmlnode, GError **err); static GType wavetbl_register_type (SwamiPlugin *plugin); static GType interp_mode_register_type (SwamiPlugin *plugin); static GType chorus_waveform_register_type (SwamiPlugin *plugin); static void wavetbl_fluidsynth_class_init (WavetblFluidSynthClass *klass); static void settings_foreach_count (void *data, char *name, int type); static void settings_foreach_option_count (void *data, char *name, char *option); static void settings_foreach_func (void *data, char *name, int type); static void settings_foreach_option_func (void *data, char *name, char *option); static int cmpstringp (const void *p1, const void *p2); static void wavetbl_fluidsynth_init (WavetblFluidSynth *wavetbl); static void wavetbl_fluidsynth_finalize (GObject *object); static void wavetbl_fluidsynth_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void wavetbl_fluidsynth_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static void wavetbl_fluidsynth_dispatch_properties_changed (GObject *object, guint n_pspecs, GParamSpec **pspecs); static void wavetbl_fluidsynth_midi_ctrl_callback (SwamiControl *control, SwamiControlEvent *event, const GValue *value); static gboolean wavetbl_fluidsynth_open (SwamiWavetbl *swami_wavetbl, GError **err); static void wavetbl_fluidsynth_prop_callback (IpatchItemPropNotify *notify); static int wavetbl_fluidsynth_handle_midi_event (void* data, fluid_midi_event_t* event); static void wavetbl_fluidsynth_close (SwamiWavetbl *swami_wavetbl); static SwamiControlMidi * wavetbl_fluidsynth_get_control (SwamiWavetbl *swami_wavetbl, int index); static gboolean wavetbl_fluidsynth_load_patch (SwamiWavetbl *swami_wavetbl, IpatchItem *patch, GError **err); static gboolean wavetbl_fluidsynth_load_active_item (SwamiWavetbl *swami_wavetbl, IpatchItem *item, GError **err); static gboolean wavetbl_fluidsynth_check_update_item (SwamiWavetbl *wavetbl, IpatchItem *item, GParamSpec *prop); static void wavetbl_fluidsynth_update_item (SwamiWavetbl *wavetbl, IpatchItem *item); static void wavetbl_fluidsynth_update_reverb (WavetblFluidSynth *wavetbl); static int find_reverb_preset (const char *name); static void wavetbl_fluidsynth_update_chorus (WavetblFluidSynth *wavetbl); static int find_chorus_preset (const char *name); static int sfloader_free (fluid_sfloader_t *loader); static fluid_sfont_t *sfloader_load_sfont (fluid_sfloader_t *loader, const char *filename); static int sfloader_sfont_free (fluid_sfont_t *sfont); static char *sfloader_sfont_get_name (fluid_sfont_t *sfont); static fluid_preset_t *sfloader_sfont_get_preset (fluid_sfont_t *sfont, unsigned int bank, unsigned int prenum); static void sfloader_sfont_iteration_start (fluid_sfont_t *sfont); static int sfloader_sfont_iteration_next (fluid_sfont_t *sfont, fluid_preset_t *preset); static int sfloader_preset_free (fluid_preset_t *preset); static int sfloader_active_preset_free (fluid_preset_t *preset); static char *sfloader_preset_get_name (fluid_preset_t *preset); static char *sfloader_active_preset_get_name (fluid_preset_t *preset); static int sfloader_preset_get_banknum (fluid_preset_t *preset); static int sfloader_active_preset_get_banknum (fluid_preset_t *preset); static int sfloader_preset_get_num (fluid_preset_t *preset); static int sfloader_active_preset_get_num (fluid_preset_t *preset); static int sfloader_preset_noteon (fluid_preset_t *preset, fluid_synth_t *synth, int chan, int key, int vel); static int sfloader_active_preset_noteon (fluid_preset_t *preset, fluid_synth_t *synth, int chan, int key, int vel); static void cache_instrument (WavetblFluidSynth *wavetbl, IpatchItem *item); static int cache_instrument_noteon (WavetblFluidSynth *wavetbl, IpatchItem *item, fluid_synth_t *synth, int chan, int key, int vel); static void active_item_realtime_update (WavetblFluidSynth *wavetbl, IpatchItem *item, GParamSpec *pspec, const GValue *value); /* FluidSynth settings boolean exceptions (yes/no string values) */ static const char *settings_str_bool[] = { "audio.jack.multi", "synth.chorus.active", "synth.dump", "synth.ladspa.active", "synth.reverb.active", "synth.verbose", NULL }; /* types are defined as global vars */ static GType wavetbl_type = 0; static GType interp_mode_type = 0; static GType chorus_waveform_type = 0; static GObjectClass *wavetbl_parent_class = NULL; /* last dynamic property ID (incremented for each dynamically installed prop) */ static int last_property_id = FIRST_DYNAMIC_PROP; /* stores all dynamic FluidSynth setting names for mapping between property ID and FluidSynth setting */ static char **dynamic_prop_names; /* stores PropFlags for property exceptions (string booleans, etc) */ static guint8 *dynamic_prop_flags; /* Quark key used for assigning FluidSynth options string arrays to GParamSpecs */ GQuark wavetbl_fluidsynth_options_quark; /* keeps a hash of patch objects to SF2VoiceCache objects */ G_LOCK_DEFINE_STATIC (voice_cache_hash); static GHashTable *voice_cache_hash = NULL; /* Reverb and Chorus preset tables (index 0 contains default values) */ G_LOCK_DEFINE_STATIC (preset_tables); /* lock for reverb and chorus tables */ static ReverbParams *reverb_presets = NULL; static ChorusParams *chorus_presets = NULL; static int reverb_presets_count; /* count of reverb presets */ static int chorus_presets_count; /* count of chorus presets */ /* count of built in reverb and chorus presets */ #define REVERB_PRESETS_BUILTIN 1 #define CHORUS_PRESETS_BUILTIN 1 /* set plugin information */ SWAMI_PLUGIN_INFO (plugin_fluidsynth_init, NULL); /* --- functions --- */ /* plugin init function (one time initialize of SwamiPlugin) */ static gboolean plugin_fluidsynth_init (SwamiPlugin *plugin, GError **err) { /* bind the gettext domain */ #if defined(ENABLE_NLS) bindtextdomain ("SwamiPlugin-fluidsynth", LOCALEDIR); #endif plugin->save_xml = plugin_fluidsynth_save_xml; plugin->load_xml = plugin_fluidsynth_load_xml; g_object_set (plugin, "name", "FluidSynth", "version", "1.01", "author", "Josh Green", "copyright", "Copyright (C) 2002-2008", "descr", N_("FluidSynth software wavetable synth plugin"), "license", "GPL", NULL); /* initialize voice cache hash */ voice_cache_hash = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify)g_object_unref); /* initialize types */ wavetbl_type = wavetbl_register_type (plugin); interp_mode_type = interp_mode_register_type (plugin); chorus_waveform_type = chorus_waveform_register_type (plugin); /* initialize built-in reverb and chorus presets * !! Make sure that name field ends in NULLs (strncpy does this). * !! If not, then a potential multi-thread string crash could occur. */ reverb_presets = g_new (ReverbParams, REVERB_PRESETS_BUILTIN); strncpy (reverb_presets[0].name, N_("Default"), PRESET_NAME_LEN); reverb_presets[0].room_size = FLUID_REVERB_DEFAULT_ROOMSIZE; reverb_presets[0].damp = FLUID_REVERB_DEFAULT_DAMP; reverb_presets[0].width = FLUID_REVERB_DEFAULT_WIDTH; reverb_presets[0].level = FLUID_REVERB_DEFAULT_LEVEL; chorus_presets = g_new (ChorusParams, CHORUS_PRESETS_BUILTIN); strncpy (chorus_presets[0].name, N_("Default"), PRESET_NAME_LEN); chorus_presets[0].count = FLUID_CHORUS_DEFAULT_N; chorus_presets[0].level = FLUID_CHORUS_DEFAULT_LEVEL; chorus_presets[0].freq = FLUID_CHORUS_DEFAULT_SPEED; chorus_presets[0].depth = FLUID_CHORUS_DEFAULT_DEPTH; chorus_presets[0].waveform = FLUID_CHORUS_DEFAULT_TYPE; return (TRUE); } static gboolean plugin_fluidsynth_save_xml (SwamiPlugin *plugin, GNode *xmlnode, GError **err) { WavetblFluidSynth *wavetbl; if (!swamigui_root || !swamigui_root->wavetbl || !WAVETBL_IS_FLUIDSYNTH (swamigui_root->wavetbl)) { g_set_error (err, SWAMI_ERROR, SWAMI_ERROR_FAIL, "Failure saving FluidSynth preferences: No FluidSynth object"); return (FALSE); } wavetbl = WAVETBL_FLUIDSYNTH (swamigui_root->wavetbl); return (ipatch_xml_encode_object (xmlnode, G_OBJECT (wavetbl), FALSE, err)); } static gboolean plugin_fluidsynth_load_xml (SwamiPlugin *plugin, GNode *xmlnode, GError **err) { WavetblFluidSynth *wavetbl; if (!swamigui_root || !swamigui_root->wavetbl || !WAVETBL_IS_FLUIDSYNTH (swamigui_root->wavetbl)) { g_set_error (err, SWAMI_ERROR, SWAMI_ERROR_FAIL, "Failure loading FluidSynth preferences: No FluidSynth object"); return (FALSE); } wavetbl = WAVETBL_FLUIDSYNTH (swamigui_root->wavetbl); return (ipatch_xml_decode_object (xmlnode, G_OBJECT (wavetbl), err)); } static GType wavetbl_register_type (SwamiPlugin *plugin) { static const GTypeInfo obj_info = { sizeof (WavetblFluidSynthClass), NULL, NULL, (GClassInitFunc) wavetbl_fluidsynth_class_init, NULL, NULL, sizeof (WavetblFluidSynth), 0, (GInstanceInitFunc) wavetbl_fluidsynth_init, }; return (g_type_module_register_type (G_TYPE_MODULE (plugin), SWAMI_TYPE_WAVETBL, "WavetblFluidSynth", &obj_info, 0)); } static GType interp_mode_register_type (SwamiPlugin *plugin) { static const GEnumValue values[] = { { FLUID_INTERP_NONE, "WAVETBL_FLUIDSYNTH_INTERP_NONE", "None" }, { FLUID_INTERP_LINEAR, "WAVETBL_FLUIDSYNTH_INTERP_LINEAR", "Linear" }, { FLUID_INTERP_4THORDER, "WAVETBL_FLUIDSYNTH_INTERP_4THORDER", "4th Order" }, { FLUID_INTERP_7THORDER, "WAVETBL_FLUIDSYNTH_INTERP_7THORDER", "7th Order" }, { 0, NULL, NULL } }; static GTypeInfo enum_info = { 0, NULL, NULL, NULL, NULL, NULL, 0, 0, NULL }; /* initialize the type info structure for the enum type */ g_enum_complete_type_info (G_TYPE_ENUM, &enum_info, values); return (g_type_module_register_type (G_TYPE_MODULE (plugin), G_TYPE_ENUM, "WavetblFluidSynthInterpType", &enum_info, 0)); } static GType chorus_waveform_register_type (SwamiPlugin *plugin) { static const GEnumValue values[] = { { FLUID_CHORUS_MOD_SINE, "WAVETBL_FLUID_CHORUS_MOD_SINE", "Sine" }, { FLUID_CHORUS_MOD_TRIANGLE, "WAVETBL_FLUID_CHORUS_MOD_TRIANGLE", "Triangle" }, { 0, NULL, NULL } }; static GTypeInfo enum_info = { 0, NULL, NULL, NULL, NULL, NULL, 0, 0, NULL }; /* initialize the type info structure for the enum type */ g_enum_complete_type_info (G_TYPE_ENUM, &enum_info, values); return (g_type_module_register_type (G_TYPE_MODULE (plugin), G_TYPE_ENUM, "WavetblFluidSynthChorusWaveform", &enum_info, 0)); } /* used for passing multiple values to FluidSynth foreach function */ typedef struct { fluid_settings_t *settings; GObjectClass *klass; int count; } ForeachBag; static void wavetbl_fluidsynth_class_init (WavetblFluidSynthClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); SwamiWavetblClass *wavetbl_class; ForeachBag bag; wavetbl_parent_class = g_type_class_peek_parent (klass); obj_class->finalize = wavetbl_fluidsynth_finalize; obj_class->set_property = wavetbl_fluidsynth_set_property; obj_class->get_property = wavetbl_fluidsynth_get_property; obj_class->dispatch_properties_changed = wavetbl_fluidsynth_dispatch_properties_changed; wavetbl_class = SWAMI_WAVETBL_CLASS (klass); wavetbl_class->open = wavetbl_fluidsynth_open; wavetbl_class->close = wavetbl_fluidsynth_close; wavetbl_class->get_control = wavetbl_fluidsynth_get_control; wavetbl_class->load_patch = wavetbl_fluidsynth_load_patch; wavetbl_class->load_active_item = wavetbl_fluidsynth_load_active_item; wavetbl_class->check_update_item = wavetbl_fluidsynth_check_update_item; wavetbl_class->update_item = wavetbl_fluidsynth_update_item; wavetbl_fluidsynth_options_quark = g_quark_from_static_string ("FluidSynth-options"); /* used for dynamically installing settings (required for settings queries) */ bag.settings = new_fluid_settings (); bag.klass = obj_class; bag.count = 0; /* count the number of FluidSynth properties + options properties */ fluid_settings_foreach (bag.settings, &bag, settings_foreach_count); /* have to keep a mapping of property IDs to FluidSynth setting names, since GObject properties get mangled ('.' turns to '-') */ dynamic_prop_names = g_malloc (bag.count * sizeof (char *)); /* allocate array for property exception flags */ dynamic_prop_flags = g_malloc0 (bag.count * sizeof (guint8)); /* add all FluidSynth settings as class properties */ fluid_settings_foreach (bag.settings, &bag, settings_foreach_func); delete_fluid_settings (bag.settings); /* not needed anymore */ g_object_class_install_property (obj_class, WTBL_PROP_INTERP, g_param_spec_enum ("interp", _("Interpolation"), _("Interpolation type"), INTERPOLATION_TYPE, FLUID_INTERP_DEFAULT, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, WTBL_PROP_REVERB_PRESET, g_param_spec_string ("reverb-preset", _("Reverb preset"), _("Reverb preset"), NULL, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, WTBL_PROP_REVERB_ROOM_SIZE, g_param_spec_double ("reverb-room-size", _("Reverb room size"), _("Reverb room size"), 0.0, 1.2, FLUID_REVERB_DEFAULT_ROOMSIZE, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, WTBL_PROP_REVERB_DAMP, g_param_spec_double ("reverb-damp", _("Reverb damp"), _("Reverb damp"), 0.0, 1.0, FLUID_REVERB_DEFAULT_DAMP, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, WTBL_PROP_REVERB_WIDTH, g_param_spec_double ("reverb-width", _("Reverb width"), _("Reverb width"), 0.0, 100.0, FLUID_REVERB_DEFAULT_WIDTH, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, WTBL_PROP_REVERB_LEVEL, g_param_spec_double ("reverb-level", _("Reverb level"), _("Reverb level"), 0.0, 1.0, FLUID_REVERB_DEFAULT_LEVEL, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, WTBL_PROP_CHORUS_PRESET, g_param_spec_string ("chorus-preset", _("Chorus preset"), _("Chorus preset"), NULL, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, WTBL_PROP_CHORUS_COUNT, g_param_spec_int ("chorus-count", _("Chorus count"), _("Number of chorus delay lines"), 1, 99, FLUID_CHORUS_DEFAULT_N, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, WTBL_PROP_CHORUS_LEVEL, g_param_spec_double ("chorus-level", _("Chorus level"), _("Output level of each chorus line"), 0.0, 10.0, FLUID_CHORUS_DEFAULT_LEVEL, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, WTBL_PROP_CHORUS_FREQ, g_param_spec_double ("chorus-freq", _("Chorus freq"), _("Chorus modulation frequency (Hz)"), 0.3, 5.0, FLUID_CHORUS_DEFAULT_SPEED, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, WTBL_PROP_CHORUS_DEPTH, g_param_spec_double ("chorus-depth", _("Chorus depth"), _("Chorus depth"), 0.0, 20.0, FLUID_CHORUS_DEFAULT_DEPTH, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, WTBL_PROP_CHORUS_WAVEFORM, g_param_spec_enum ("chorus-waveform", _("Chorus waveform"), _("Chorus waveform type"), CHORUS_WAVEFORM_TYPE, FLUID_CHORUS_DEFAULT_TYPE, G_PARAM_READWRITE)); g_object_class_install_property (obj_class, WTBL_PROP_ACTIVE_ITEM, g_param_spec_object ("active-item", _("Active item"), _("Active focused audible item"), IPATCH_TYPE_ITEM, G_PARAM_READWRITE | IPATCH_PARAM_NO_SAVE)); g_object_class_install_property (obj_class, WTBL_PROP_SOLO_ITEM, g_param_spec_object ("solo-item", _("Solo item"), _("Child of active item to solo"), IPATCH_TYPE_ITEM, G_PARAM_READWRITE | IPATCH_PARAM_NO_SAVE)); g_object_class_install_property (obj_class, WTBL_PROP_MODULATORS, g_param_spec_boxed ("modulators", _("Modulators"), _("Modulators"), IPATCH_TYPE_SF2_MOD_LIST, G_PARAM_READWRITE | IPATCH_PARAM_NO_SAVE)); } /* for counting the number of FluidSynth settings properties */ static void settings_foreach_count (void *data, char *name, int type) { ForeachBag *bag = (ForeachBag *)data; int optcount = 0; bag->count = bag->count + 1; /* if there are string options, add one for an "-options" property */ if (type == FLUID_STR_TYPE) { fluid_settings_foreach_option (bag->settings, name, &optcount, settings_foreach_option_count); if (optcount > 0) bag->count = bag->count + 1; } } /* function to count FluidSynth string options for a parameter */ static void settings_foreach_option_count (void *data, char *name, char *option) { int *optcount = data; *optcount = *optcount + 1; } /* add each FluidSynth setting as a GObject property */ static void settings_foreach_func (void *data, char *name, int type) { ForeachBag *bag = (ForeachBag *)data; GStrv options = NULL, optionp; GParamSpec *spec; double dmin, dmax, ddef; int imin, imax, idef; gboolean bdef; char *defstr; const char **sp; int optcount = 0; char *optname; /* check if this property is on the string boolean list */ for (sp = settings_str_bool; *sp; sp++) if (type == FLUID_STR_TYPE && strcmp (name, *sp) == 0) break; if (*sp) /* string boolean value? */ { bdef = fluid_settings_str_equal (bag->settings, name, "yes"); spec = g_param_spec_boolean (name, name, name, bdef, G_PARAM_READWRITE); /* set PROP_STRING_BOOL property flag */ dynamic_prop_flags[last_property_id - FIRST_DYNAMIC_PROP] |= PROP_STRING_BOOL; } else { switch (type) { case FLUID_NUM_TYPE: fluid_settings_getnum_range (bag->settings, name, &dmin, &dmax); ddef = fluid_settings_getnum_default (bag->settings, name); spec = g_param_spec_double (name, name, name, dmin, dmax, ddef, G_PARAM_READWRITE); break; case FLUID_INT_TYPE: fluid_settings_getint_range (bag->settings, name, &imin, &imax); idef = fluid_settings_getint_default (bag->settings, name); if (imin == 0 && imax == 1) /* boolean parameter? */ spec = g_param_spec_boolean (name, name, name, idef != 0, G_PARAM_READWRITE); else spec = g_param_spec_int (name, name, name, imin, imax, idef, G_PARAM_READWRITE); break; case FLUID_STR_TYPE: defstr = fluid_settings_getstr_default (bag->settings, name); spec = g_param_spec_string (name, name, name, defstr, G_PARAM_READWRITE); /* count options for this string parameter (if any) */ fluid_settings_foreach_option (bag->settings, name, &optcount, settings_foreach_option_count); /* if there are any options, create a string array and assign them */ if (optcount > 0) { options = g_new (char *, optcount + 1); /* ++ alloc string array */ optionp = options; fluid_settings_foreach_option (bag->settings, name, &optionp, settings_foreach_option_func); options[optcount] = NULL; /* Sort the options alphabetically */ qsort (options, optcount, sizeof (options[0]), cmpstringp); } break; case FLUID_SET_TYPE: g_warning ("Enum not handled for property '%s'", name); return; default: return; } } /* install the property */ g_object_class_install_property (bag->klass, last_property_id, spec); /* store the name to the property name array */ dynamic_prop_names[last_property_id - FIRST_DYNAMIC_PROP] = g_strdup (name); last_property_id++; /* advance the last dynamic property ID */ /* install an options parameter if there are any string options */ if (options) { optname = g_strconcat (name, "-options", NULL); /* ++ alloc */ spec = g_param_spec_boxed (optname, optname, optname, G_TYPE_STRV, G_PARAM_READABLE); /* !! GParamSpec takes over allocation of options array */ g_param_spec_set_qdata (spec, wavetbl_fluidsynth_options_quark, options); g_object_class_install_property (bag->klass, last_property_id, spec); /* !! takes over allocation */ dynamic_prop_names[last_property_id - FIRST_DYNAMIC_PROP] = optname; last_property_id++; /* advance the last dynamic property ID */ } } /* function to iterate over FluidSynth string options for string parameters * and fill a string array */ static void settings_foreach_option_func (void *data, char *name, char *option) { GStrv *poptions = data; **poptions = g_strdup (option); *poptions = *poptions + 1; } /* qsort function to sort array of option strings */ static int cmpstringp (const void *p1, const void *p2) { return strcmp (*(char * const *)p1, *(char * const *)p2); } static void wavetbl_fluidsynth_init (WavetblFluidSynth *wavetbl) { wavetbl->synth = NULL; wavetbl->settings = new_fluid_settings (); wavetbl->midi_ctrl = swami_control_midi_new (); /* ++ ref */ swami_control_midi_set_callback (wavetbl->midi_ctrl, wavetbl_fluidsynth_midi_ctrl_callback, wavetbl); wavetbl->channel_count = DEFAULT_CHANNEL_COUNT; wavetbl->banks = g_new0 (guint8, wavetbl->channel_count); wavetbl->programs = g_new0 (guint8, wavetbl->channel_count); wavetbl->reverb_params = reverb_presets[0]; wavetbl->chorus_params = chorus_presets[0]; wavetbl->active_item = NULL; wavetbl->rt_cache = NULL; wavetbl->rt_count = 0; } static void wavetbl_fluidsynth_finalize (GObject *object) { WavetblFluidSynth *wavetbl = WAVETBL_FLUIDSYNTH (object); g_free (wavetbl->banks); g_free (wavetbl->programs); if (wavetbl->midi_ctrl) g_object_unref (wavetbl->midi_ctrl); /* -- unref */ if (wavetbl->settings) delete_fluid_settings (wavetbl->settings); G_OBJECT_CLASS (wavetbl_parent_class)->finalize (object); } static void wavetbl_fluidsynth_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { WavetblFluidSynth *wavetbl = WAVETBL_FLUIDSYNTH (object); GSList *oldmods, *newmods; IpatchItem *item, *active_item; char *name; const char *s; int retval; int index; /* is it one of the dynamically installed properties? */ if (property_id >= FIRST_DYNAMIC_PROP && property_id < last_property_id) { name = dynamic_prop_names[property_id - FIRST_DYNAMIC_PROP]; switch (G_PARAM_SPEC_VALUE_TYPE (pspec)) { case G_TYPE_INT: retval = fluid_settings_setint (wavetbl->settings, name, g_value_get_int (value)); break; case G_TYPE_DOUBLE: retval = fluid_settings_setnum (wavetbl->settings, name, g_value_get_double (value)); break; case G_TYPE_STRING: retval = fluid_settings_setstr (wavetbl->settings, name, (char *)g_value_get_string (value)); break; case G_TYPE_BOOLEAN: /* check if its a string boolean property */ if (dynamic_prop_flags[property_id - FIRST_DYNAMIC_PROP] & PROP_STRING_BOOL) retval = fluid_settings_setstr (wavetbl->settings, name, g_value_get_boolean (value) ? "yes" : "no"); else retval = fluid_settings_setint (wavetbl->settings, name, g_value_get_boolean (value)); break; default: g_critical ("Unexpected FluidSynth dynamic property type"); return; } if (!retval) g_critical ("Failed to set FluidSynth property '%s'", name); return; } switch (property_id) { case WTBL_PROP_INTERP: wavetbl->interp = g_value_get_enum (value); SWAMI_LOCK_WRITE (wavetbl); if (wavetbl->synth) fluid_synth_set_interp_method (wavetbl->synth, -1, wavetbl->interp); SWAMI_UNLOCK_WRITE (wavetbl); break; case WTBL_PROP_REVERB_PRESET: s = g_value_get_string (value); index = 0; if (s && s[0] != '\0') /* valid preset name? */ { G_LOCK (preset_tables); index = find_reverb_preset (s); if (index != 0) wavetbl->reverb_params = reverb_presets[index]; G_UNLOCK (preset_tables); } if (index == 0) wavetbl->reverb_params = reverb_presets[0]; wavetbl->reverb_update = TRUE; break; case WTBL_PROP_REVERB_ROOM_SIZE: wavetbl->reverb_params.name[0] = '\0'; /* clear preset name (if any) */ wavetbl->reverb_params.room_size = g_value_get_double (value); wavetbl->reverb_update = TRUE; break; case WTBL_PROP_REVERB_DAMP: wavetbl->reverb_params.name[0] = '\0'; /* clear preset name (if any) */ wavetbl->reverb_params.damp = g_value_get_double (value); wavetbl->reverb_update = TRUE; break; case WTBL_PROP_REVERB_WIDTH: wavetbl->reverb_params.name[0] = '\0'; /* clear preset name (if any) */ wavetbl->reverb_params.width = g_value_get_double (value); wavetbl->reverb_update = TRUE; break; case WTBL_PROP_REVERB_LEVEL: wavetbl->reverb_params.name[0] = '\0'; /* clear preset name (if any) */ wavetbl->reverb_params.level = g_value_get_double (value); wavetbl->reverb_update = TRUE; break; case WTBL_PROP_CHORUS_PRESET: s = g_value_get_string (value); index = 0; if (s && s[0] != '\0') /* valid preset name? */ { G_LOCK (preset_tables); index = find_chorus_preset (s); if (index != 0) wavetbl->chorus_params = chorus_presets[index]; G_UNLOCK (preset_tables); } if (index == 0) wavetbl->chorus_params = chorus_presets[0]; wavetbl->chorus_update = TRUE; break; case WTBL_PROP_CHORUS_COUNT: wavetbl->chorus_params.name[0] = '\0'; /* clear preset name (if any) */ wavetbl->chorus_params.count = g_value_get_int (value); wavetbl->chorus_update = TRUE; break; case WTBL_PROP_CHORUS_LEVEL: wavetbl->chorus_params.name[0] = '\0'; /* clear preset name (if any) */ wavetbl->chorus_params.level = g_value_get_double (value); wavetbl->chorus_update = TRUE; break; case WTBL_PROP_CHORUS_FREQ: wavetbl->chorus_params.name[0] = '\0'; /* clear preset name (if any) */ wavetbl->chorus_params.freq = g_value_get_double (value); wavetbl->chorus_update = TRUE; break; case WTBL_PROP_CHORUS_DEPTH: wavetbl->chorus_params.name[0] = '\0'; /* clear preset name (if any) */ wavetbl->chorus_params.depth = g_value_get_double (value); wavetbl->chorus_update = TRUE; break; case WTBL_PROP_CHORUS_WAVEFORM: wavetbl->chorus_params.name[0] = '\0'; /* clear preset name (if any) */ wavetbl->chorus_params.waveform = g_value_get_enum (value); wavetbl->chorus_update = TRUE; break; case WTBL_PROP_ACTIVE_ITEM: item = g_value_get_object (value); SWAMI_LOCK_WRITE (wavetbl); wavetbl_fluidsynth_load_active_item ((SwamiWavetbl *)wavetbl, item, NULL); SWAMI_UNLOCK_WRITE (wavetbl); break; case WTBL_PROP_SOLO_ITEM: item = g_value_get_object (value); SWAMI_LOCK_WRITE (wavetbl); if (wavetbl->solo_item) g_object_unref (wavetbl->solo_item); wavetbl->solo_item = g_value_dup_object (value); active_item = g_object_ref (wavetbl->active_item); /* ++ ref active item */ SWAMI_UNLOCK_WRITE (wavetbl); wavetbl_fluidsynth_update_item ((SwamiWavetbl *)wavetbl, active_item); g_object_unref (active_item); /* -- unref active item */ break; case WTBL_PROP_MODULATORS: newmods = g_value_dup_boxed (value); SWAMI_LOCK_WRITE (wavetbl); oldmods = wavetbl->mods; wavetbl->mods = newmods; SWAMI_UNLOCK_WRITE (wavetbl); if (oldmods) ipatch_sf2_mod_list_free (oldmods, TRUE); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void wavetbl_fluidsynth_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { WavetblFluidSynth *wavetbl = WAVETBL_FLUIDSYNTH (object); GSList *mods; char *s; char *name; double d; int retval; int i; GStrv strv; /* is it one of the dynamically installed properties? */ if (property_id >= FIRST_DYNAMIC_PROP && property_id < last_property_id) { name = dynamic_prop_names[property_id - FIRST_DYNAMIC_PROP]; switch (G_PARAM_SPEC_VALUE_TYPE (pspec)) { case G_TYPE_INT: retval = fluid_settings_getint (wavetbl->settings, name, &i); if (retval) g_value_set_int (value, i); break; case G_TYPE_DOUBLE: retval = fluid_settings_getnum (wavetbl->settings, name, &d); if (retval) g_value_set_double (value, d); break; case G_TYPE_STRING: retval = fluid_settings_getstr (wavetbl->settings, name, &s); if (retval) g_value_set_string (value, s); break; case G_TYPE_BOOLEAN: /* check if its a string boolean property */ if (dynamic_prop_flags[property_id - FIRST_DYNAMIC_PROP] & PROP_STRING_BOOL) { i = fluid_settings_str_equal (wavetbl->settings, name, "yes"); g_value_set_boolean (value, i); retval = TRUE; } else { retval = fluid_settings_getint (wavetbl->settings, name, &i); if (retval) g_value_set_boolean (value, i); } break; default: /* For FluidSynth string -options parameters */ if (G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_STRV) { strv = g_param_spec_get_qdata (pspec, wavetbl_fluidsynth_options_quark); g_value_set_boxed (value, strv); } else { g_critical ("Unexpected FluidSynth dynamic property type"); return; } } if (!retval) g_critical ("Failed to get FluidSynth property '%s'", name); return; } switch (property_id) { case WTBL_PROP_INTERP: g_value_set_enum (value, wavetbl->interp); break; case WTBL_PROP_REVERB_PRESET: /* don't need to lock since buffer is static and will always contain a * NULL terminator (a partially updated string could occur though). */ g_value_set_string (value, wavetbl->reverb_params.name); break; case WTBL_PROP_REVERB_ROOM_SIZE: g_value_set_double (value, wavetbl->reverb_params.room_size); break; case WTBL_PROP_REVERB_DAMP: g_value_set_double (value, wavetbl->reverb_params.damp); break; case WTBL_PROP_REVERB_WIDTH: g_value_set_double (value, wavetbl->reverb_params.width); break; case WTBL_PROP_REVERB_LEVEL: g_value_set_double (value, wavetbl->reverb_params.level); break; case WTBL_PROP_CHORUS_PRESET: /* don't need to lock since buffer is static and will always contain a * NULL terminator (a partially updated string could occur though). */ g_value_set_string (value, wavetbl->chorus_params.name); break; case WTBL_PROP_CHORUS_COUNT: g_value_set_int (value, wavetbl->chorus_params.count); break; case WTBL_PROP_CHORUS_LEVEL: g_value_set_double (value, wavetbl->chorus_params.level); break; case WTBL_PROP_CHORUS_FREQ: g_value_set_double (value, wavetbl->chorus_params.freq); break; case WTBL_PROP_CHORUS_DEPTH: g_value_set_double (value, wavetbl->chorus_params.depth); break; case WTBL_PROP_CHORUS_WAVEFORM: g_value_set_enum (value, wavetbl->chorus_params.waveform); break; case WTBL_PROP_ACTIVE_ITEM: SWAMI_LOCK_READ (wavetbl); g_value_set_object (value, wavetbl->active_item); SWAMI_UNLOCK_READ (wavetbl); break; case WTBL_PROP_SOLO_ITEM: SWAMI_LOCK_READ (wavetbl); g_value_set_object (value, wavetbl->solo_item); SWAMI_UNLOCK_READ (wavetbl); break; case WTBL_PROP_MODULATORS: SWAMI_LOCK_READ (wavetbl); mods = ipatch_sf2_mod_list_duplicate (wavetbl->mods); SWAMI_UNLOCK_READ (wavetbl); g_value_set_boxed_take_ownership (value, mods); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } /* used to group reverb and/or chorus property updates, when changing multiple * properties, to prevent excess calculation */ static void wavetbl_fluidsynth_dispatch_properties_changed (GObject *object, guint n_pspecs, GParamSpec **pspecs) { WavetblFluidSynth *wavetbl = WAVETBL_FLUIDSYNTH (object); if (wavetbl->reverb_update || wavetbl->chorus_update) { SWAMI_LOCK_WRITE (wavetbl); if (wavetbl->reverb_update) wavetbl_fluidsynth_update_reverb (wavetbl); if (wavetbl->chorus_update) wavetbl_fluidsynth_update_chorus (wavetbl); SWAMI_UNLOCK_WRITE (wavetbl); } G_OBJECT_CLASS (wavetbl_parent_class)->dispatch_properties_changed (object, n_pspecs, pspecs); } /* MIDI control callback */ static void wavetbl_fluidsynth_midi_ctrl_callback (SwamiControl *control, SwamiControlEvent *event, const GValue *value) { WavetblFluidSynth *wavetbl = WAVETBL_FLUIDSYNTH (((SwamiControlFunc *)control)->user_data); fluid_synth_t *synth; GValueArray *valarray = NULL; SwamiMidiEvent *midi; int i, count = 1; /* default for single values */ if (!wavetbl->synth) return; synth = wavetbl->synth; /* if its multiple values, fetch the value array */ if (G_VALUE_TYPE (value) == G_TYPE_VALUE_ARRAY) { valarray = g_value_get_boxed (value); count = valarray->n_values; } i = 0; while (i < count) { if (valarray) value = g_value_array_get_nth (valarray, i); if (G_VALUE_TYPE (value) == SWAMI_TYPE_MIDI_EVENT && (midi = g_value_get_boxed (value))) { switch (midi->type) { case SWAMI_MIDI_NOTE_ON: fluid_synth_noteon (synth, midi->channel, midi->data.note.note, midi->data.note.velocity); break; case SWAMI_MIDI_NOTE_OFF: fluid_synth_noteoff (synth, midi->channel, midi->data.note.note); break; case SWAMI_MIDI_PITCH_BEND: /* FluidSynth uses 0-16383 */ fluid_synth_pitch_bend (synth, midi->channel, midi->data.control.value + 8192); break; case SWAMI_MIDI_CONTROL: fluid_synth_cc (synth, midi->channel, midi->data.control.param, midi->data.control.value); break; case SWAMI_MIDI_CONTROL14: if (midi->data.control.param == SWAMI_MIDI_CC_BANK_MSB) { /* update channel bank # */ if (midi->channel < wavetbl->channel_count) wavetbl->banks[midi->channel] = midi->data.control.value; fluid_synth_bank_select (synth, midi->channel, midi->data.control.value); } else fluid_synth_cc (synth, midi->channel, midi->data.control.param, midi->data.control.value); break; case SWAMI_MIDI_PROGRAM_CHANGE: /* update channel program # */ if (midi->channel < wavetbl->channel_count) wavetbl->programs[midi->channel] = midi->data.control.value; fluid_synth_program_change (synth, midi->channel, midi->data.control.value); break; default: break; } } i++; } } /** init function for FluidSynth Swami wavetable driver */ static gboolean wavetbl_fluidsynth_open (SwamiWavetbl *swami_wavetbl, GError **err) { WavetblFluidSynth *wavetbl = WAVETBL_FLUIDSYNTH (swami_wavetbl); fluid_sfloader_t *loader; int i; SWAMI_LOCK_WRITE (wavetbl); if (swami_wavetbl->active) { SWAMI_UNLOCK_WRITE (wavetbl); return (TRUE); } /* create new FluidSynth */ wavetbl->synth = new_fluid_synth (wavetbl->settings); if (!wavetbl->synth) { g_set_error (err, SWAMI_ERROR, SWAMI_ERROR_FAIL, _("Failed to create FluidSynth context")); SWAMI_UNLOCK_WRITE (wavetbl); return (FALSE); } /* hook our sfloader */ loader = g_malloc0 (sizeof (fluid_sfloader_t)); loader->data = wavetbl; loader->free = sfloader_free; loader->load = sfloader_load_sfont; fluid_synth_add_sfloader (wavetbl->synth, loader); wavetbl->audio = new_fluid_audio_driver (wavetbl->settings, wavetbl->synth); /* Load dummy SoundFont to make active items work - sfloader_load_sfont */ fluid_synth_sfload (wavetbl->synth, "!", FALSE); /* create MIDI router to send MIDI to FluidSynth */ wavetbl->midi_router = new_fluid_midi_router (wavetbl->settings, wavetbl_fluidsynth_handle_midi_event, (void *)wavetbl); if (wavetbl->midi_router) { fluid_synth_set_midi_router (wavetbl->synth, wavetbl->midi_router); wavetbl->midi = new_fluid_midi_driver (wavetbl->settings, fluid_midi_router_handle_midi_event, (void *)(wavetbl->midi_router)); if (!wavetbl->midi) g_warning (_("Failed to create FluidSynth MIDI input driver")); } else g_warning (_("Failed to create MIDI input router")); /* update reverb */ wavetbl->reverb_update = TRUE; wavetbl_fluidsynth_update_reverb (wavetbl); /* update chorus */ wavetbl->chorus_update = TRUE; wavetbl_fluidsynth_update_chorus (wavetbl); /* load active item if set */ if (wavetbl->active_item) wavetbl_fluidsynth_load_active_item (swami_wavetbl, wavetbl->active_item, NULL); /* restore bank and program channel selections */ for (i = 0; i < wavetbl->channel_count; i++) { fluid_synth_bank_select (wavetbl->synth, i, wavetbl->banks[i]); fluid_synth_program_change (wavetbl->synth, i, wavetbl->programs[i]); } /* monitor all property changes */ wavetbl->prop_callback_handler_id = ipatch_item_prop_connect (NULL, NULL, wavetbl_fluidsynth_prop_callback, NULL, wavetbl); swami_wavetbl->active = TRUE; SWAMI_UNLOCK_WRITE (wavetbl); return (TRUE); } /* called for every property change */ static void wavetbl_fluidsynth_prop_callback (IpatchItemPropNotify *notify) { WavetblFluidSynth *wavetbl = (WavetblFluidSynth *)(notify->user_data); /* quick check to see if property has SYNTH flag set */ if (!(notify->pspec->flags & IPATCH_PARAM_SYNTH)) return; /* check if changed item is a dependent of active audible (for realtime fx) */ SWAMI_LOCK_READ (wavetbl); if (notify->item == wavetbl->active_item && notify->pspec->flags & IPATCH_PARAM_SYNTH_REALTIME) active_item_realtime_update (wavetbl, notify->item, notify->pspec, notify->new_value); SWAMI_UNLOCK_READ (wavetbl); /* see if property change affects any loaded instruments */ if (wavetbl_fluidsynth_check_update_item ((SwamiWavetbl *)wavetbl, notify->item, notify->pspec)) wavetbl_fluidsynth_update_item ((SwamiWavetbl *)wavetbl, notify->item); } /* Called for each event received from the FluidSynth MIDI router */ static int wavetbl_fluidsynth_handle_midi_event (void* data, fluid_midi_event_t* event) { WavetblFluidSynth *wavetbl = WAVETBL_FLUIDSYNTH (data); int type = fluid_midi_event_get_type (event); int chan = fluid_midi_event_get_channel (event); int retval; retval = fluid_synth_handle_midi_event (wavetbl->synth, event); switch (type) { case WAVETBL_FLUID_NOTE_ON: swami_control_midi_transmit (wavetbl->midi_ctrl, SWAMI_MIDI_NOTE_ON, chan, fluid_midi_event_get_key (event), fluid_midi_event_get_velocity (event)); break; case WAVETBL_FLUID_NOTE_OFF: swami_control_midi_transmit (wavetbl->midi_ctrl, SWAMI_MIDI_NOTE_OFF, chan, fluid_midi_event_get_key (event), fluid_midi_event_get_velocity (event)); break; case WAVETBL_FLUID_CONTROL_CHANGE: /* update current wavetable bank? */ if (fluid_midi_event_get_control (event) == SWAMI_MIDI_CC_BANK_MSB && chan < wavetbl->channel_count) wavetbl->banks[chan] = fluid_midi_event_get_value (event); swami_control_midi_transmit (wavetbl->midi_ctrl, SWAMI_MIDI_CONTROL, chan, fluid_midi_event_get_control (event), fluid_midi_event_get_value (event)); break; case WAVETBL_FLUID_PROGRAM_CHANGE: if (chan < wavetbl->channel_count) wavetbl->programs[chan] = fluid_midi_event_get_program (event); swami_control_midi_transmit (wavetbl->midi_ctrl, SWAMI_MIDI_PROGRAM_CHANGE, chan, fluid_midi_event_get_program (event), 0); break; case WAVETBL_FLUID_PITCH_BEND: /* FluidSynth uses 0-16383 */ swami_control_midi_transmit (wavetbl->midi_ctrl, SWAMI_MIDI_PITCH_BEND, chan, fluid_midi_event_get_pitch (event) - 8192, 0); break; } return retval; } /* close function for FluidSynth driver */ static void wavetbl_fluidsynth_close (SwamiWavetbl *swami_wavetbl) { WavetblFluidSynth *wavetbl = WAVETBL_FLUIDSYNTH (swami_wavetbl); SWAMI_LOCK_WRITE (wavetbl); if (!swami_wavetbl->active) { SWAMI_UNLOCK_WRITE (wavetbl); return; } /* remove our property change callback */ ipatch_item_prop_disconnect (wavetbl->prop_callback_handler_id); if (wavetbl->midi) delete_fluid_midi_driver (wavetbl->midi); if (wavetbl->midi_router) delete_fluid_midi_router (wavetbl->midi_router); if (wavetbl->audio) delete_fluid_audio_driver (wavetbl->audio); if (wavetbl->synth) delete_fluid_synth (wavetbl->synth); if (wavetbl->rt_cache) g_object_unref (wavetbl->rt_cache); wavetbl->midi = NULL; wavetbl->midi_router = NULL; wavetbl->audio = NULL; wavetbl->synth = NULL; wavetbl->rt_cache = NULL; wavetbl->rt_count = 0; swami_wavetbl->active = FALSE; SWAMI_UNLOCK_WRITE (wavetbl); } /* get MIDI control method */ static SwamiControlMidi * wavetbl_fluidsynth_get_control (SwamiWavetbl *swami_wavetbl, int index) { WavetblFluidSynth *wavetbl = WAVETBL_FLUIDSYNTH (swami_wavetbl); if (index == 0) return (wavetbl->midi_ctrl); return (NULL); } /* patch load function for FluidSynth driver */ static gboolean wavetbl_fluidsynth_load_patch (SwamiWavetbl *swami_wavetbl, IpatchItem *patch, GError **err) { WavetblFluidSynth *wavetbl = WAVETBL_FLUIDSYNTH (swami_wavetbl); char s[16]; /* enough space to store printf "&%p" */ if (!IPATCH_IS_BASE (patch)) { g_set_error (err, SWAMI_ERROR, SWAMI_ERROR_UNSUPPORTED, _("Unsupported item type '%s' for FluidSynth patch load"), G_OBJECT_TYPE_NAME (patch)); return (FALSE); } SWAMI_LOCK_WRITE (wavetbl); /* make sure synth has been initialized */ if (swami_log_if_fail (swami_wavetbl->active)) { SWAMI_UNLOCK_WRITE (wavetbl); return (FALSE); } /* load patch by pointer (our FluidSynth sfloader plugin will use it) */ g_strdup_printf (s, "&%p", (void *)patch); fluid_synth_sfload (wavetbl->synth, s, FALSE); SWAMI_UNLOCK_WRITE (wavetbl); return (TRUE); } /* active item load function for FluidSynth driver */ static gboolean wavetbl_fluidsynth_load_active_item (SwamiWavetbl *swami_wavetbl, IpatchItem *item, GError **err) { WavetblFluidSynth *wavetbl = WAVETBL_FLUIDSYNTH (swami_wavetbl); /* only set as active item if its convertable to a SF2 voice cache */ if (item && ipatch_find_converter (G_OBJECT_TYPE (item), IPATCH_TYPE_SF2_VOICE_CACHE)) { SWAMI_LOCK_WRITE (wavetbl); if (wavetbl->active_item) /* remove reference to any current active item */ g_object_unref (wavetbl->active_item); wavetbl->active_item = g_object_ref (item); /* ++ add reference to item */ if (wavetbl->rt_cache) { g_object_unref (wavetbl->rt_cache); wavetbl->rt_cache = NULL; } wavetbl->rt_count = 0; cache_instrument (wavetbl, item); /* cache the instrument voices */ SWAMI_UNLOCK_WRITE (wavetbl); } return (TRUE); } /* SwamiWavetbl method to check if an item needs to update its synthesis cache */ static gboolean wavetbl_fluidsynth_check_update_item (SwamiWavetbl *wavetbl, IpatchItem *item, GParamSpec *prop) { IpatchSF2VoiceCache *cache; /* if parameter doesn't have the SYNTH flag set, then no update needed */ if (!(prop->flags & IPATCH_PARAM_SYNTH)) return (FALSE); /* check if item is cached */ G_LOCK (voice_cache_hash); cache = g_hash_table_lookup (voice_cache_hash, item); G_UNLOCK (voice_cache_hash); return (cache != NULL); } /* SwamiWavetbl method to update an item's synthesis cache */ static void wavetbl_fluidsynth_update_item (SwamiWavetbl *wavetbl, IpatchItem *item) { SWAMI_LOCK_WRITE (wavetbl); cache_instrument (WAVETBL_FLUIDSYNTH (wavetbl), item); SWAMI_UNLOCK_WRITE (wavetbl); } static void wavetbl_fluidsynth_update_reverb (WavetblFluidSynth *wavetbl) { g_return_if_fail (WAVETBL_IS_FLUIDSYNTH (wavetbl)); if (!wavetbl->synth || !wavetbl->reverb_update) return; wavetbl->reverb_update = FALSE; fluid_synth_set_reverb (wavetbl->synth, wavetbl->reverb_params.room_size, wavetbl->reverb_params.damp, wavetbl->reverb_params.width, wavetbl->reverb_params.level); } /* Lock preset_tables before calling this function */ static int find_reverb_preset (const char *name) { int i; for (i = 0; i < reverb_presets_count; i++) { if (strcmp (reverb_presets[i].name, name) == 0) return (i); } return (0); } static void wavetbl_fluidsynth_update_chorus (WavetblFluidSynth *wavetbl) { g_return_if_fail (WAVETBL_IS_FLUIDSYNTH (wavetbl)); if (!wavetbl->synth || !wavetbl->chorus_update) return; wavetbl->chorus_update = FALSE; fluid_synth_set_chorus (wavetbl->synth, wavetbl->chorus_params.count, wavetbl->chorus_params.level, wavetbl->chorus_params.freq, wavetbl->chorus_params.depth, wavetbl->chorus_params.waveform); } /* Lock preset_tables before calling this function */ static int find_chorus_preset (const char *name) { int i; for (i = 0; i < chorus_presets_count; i++) { if (strcmp (chorus_presets[i].name, name) == 0) return (i); } return (0); } /* FluidSynth sfloader functions */ /** FluidSynth sfloader "free" function */ static int sfloader_free (fluid_sfloader_t *loader) { g_free (loader); return (_SYNTH_OK); } /** FluidSynth sfloader "load" function */ static fluid_sfont_t * sfloader_load_sfont (fluid_sfloader_t *loader, const char *filename) { fluid_sfont_t *sfont; sfloader_sfont_data_t *sfont_data; IpatchItem *item = NULL; /* file name should be a string in the printf form "&%p" where the pointer is a pointer to a IpatchBase object, or "!" for dummy SoundFont to get active preset item to work when no SoundFont banks loaded */ if (filename[0] == '&') { sscanf (filename, "&%p", (void **)(&item)); if (!item) return (NULL); g_object_ref (item); /* ++ Add a reference to the patch object */ } else if (filename[0] != '!') return (NULL); /* didn't begin with '&' or '!' */ sfont_data = g_malloc0 (sizeof (sfloader_sfont_data_t)); sfont_data->wavetbl = (WavetblFluidSynth *)(loader->data); sfont_data->base_item = IPATCH_BASE (item); sfont = g_malloc0 (sizeof (fluid_sfont_t)); sfont->data = sfont_data; sfont->free = sfloader_sfont_free; sfont->get_name = sfloader_sfont_get_name; sfont->get_preset = sfloader_sfont_get_preset; sfont->iteration_start = sfloader_sfont_iteration_start; sfont->iteration_next = sfloader_sfont_iteration_next; return (sfont); } /* sfloader callback to clean up an fluid_sfont_t structure */ static int sfloader_sfont_free (fluid_sfont_t *sfont) { sfloader_sfont_data_t *sfont_data; sfont_data = (sfloader_sfont_data_t *)(sfont->data); if (sfont_data->base_item) /* -- remove reference */ g_object_unref (IPATCH_ITEM (sfont_data->base_item)); g_free (sfont_data); g_free (sfont); return (_SYNTH_OK); } /* sfloader callback to get a patch file name */ static char * sfloader_sfont_get_name (fluid_sfont_t *sfont) { sfloader_sfont_data_t *sfont_data; static char buf[256]; /* using static buffer so info string can be freed */ char *s; sfont_data = (sfloader_sfont_data_t *)(sfont->data); if (sfont_data->base_item) { g_object_get (sfont_data->base_item, "file-name", &s, NULL); g_strlcpy (buf, s, sizeof (buf)); g_free (s); } else buf[0] = '\0'; return (buf); } /* sfloader callback to get a preset (instrument) by bank and preset number */ static fluid_preset_t * sfloader_sfont_get_preset (fluid_sfont_t *sfont, unsigned int bank, unsigned int prenum) { sfloader_sfont_data_t *sfont_data; sfloader_preset_data_t *preset_data; fluid_preset_t* preset; int b, p; sfont_data = (sfloader_sfont_data_t *)(sfont->data); /* active item bank:preset requested? */ swami_wavetbl_get_active_item_locale (SWAMI_WAVETBL (sfont_data->wavetbl), &b, &p); if (bank == b && prenum == p) { g_object_ref (G_OBJECT (sfont_data->wavetbl)); /* ++ inc wavetbl ref */ preset = g_malloc0 (sizeof (fluid_preset_t)); preset->sfont = sfont; preset->data = sfont_data->wavetbl; preset->free = sfloader_active_preset_free; preset->get_name = sfloader_active_preset_get_name; preset->get_banknum = sfloader_active_preset_get_banknum; preset->get_num = sfloader_active_preset_get_num; preset->noteon = sfloader_active_preset_noteon; } else /* regular preset request */ { IpatchItem *item; if (!sfont_data->base_item) /* for active preset SoundFont HACK */ return (NULL); /* ++ ref found MIDI instrument object */ item = ipatch_base_find_item_by_midi_locale (sfont_data->base_item, bank, prenum); if (!item) return (NULL); preset_data = g_malloc0 (sizeof (sfloader_preset_data_t)); g_object_ref (G_OBJECT (sfont_data->wavetbl)); /* ++ inc wavetbl ref */ preset_data->wavetbl = sfont_data->wavetbl; preset_data->item = item; /* !! item already referenced by find */ preset = g_malloc0 (sizeof (fluid_preset_t)); preset->sfont = sfont; preset->data = preset_data; preset->free = sfloader_preset_free; preset->get_name = sfloader_preset_get_name; preset->get_banknum = sfloader_preset_get_banknum; preset->get_num = sfloader_preset_get_num; preset->noteon = sfloader_preset_noteon; } return (preset); } /* sfloader callback to start a SoundFont preset iteration */ static void sfloader_sfont_iteration_start (fluid_sfont_t *sfont) { } /* sfloader callback to get next preset in a SoundFont iteration */ static int sfloader_sfont_iteration_next (fluid_sfont_t *sfont, fluid_preset_t *preset) { return (0); } /* sfloader callback to clean up an fluid_preset_t structure */ static int sfloader_preset_free (fluid_preset_t *preset) { sfloader_preset_data_t *preset_data; preset_data = preset->data; /* -- remove item reference */ g_object_unref (IPATCH_ITEM (preset_data->item)); /* remove wavetable object reference */ g_object_unref (G_OBJECT (preset_data->wavetbl)); g_free (preset_data); g_free (preset); return (_SYNTH_OK); } /* sfloader callback to clean up a active item preset structure */ static int sfloader_active_preset_free (fluid_preset_t *preset) { g_object_unref (G_OBJECT (preset->data)); /* -- remove wavetbl obj ref */ g_free (preset); return (_SYNTH_OK); } /* sfloader callback to get the name of a preset */ static char * sfloader_preset_get_name (fluid_preset_t *preset) { sfloader_preset_data_t *preset_data = preset->data; static char buf[256]; /* return string is static */ char *name; g_object_get (preset_data->item, "name", &name, NULL); g_strlcpy (buf, name, sizeof (buf)); g_free (name); return (buf); } /* sfloader callback to get name of active preset */ static char * sfloader_active_preset_get_name (fluid_preset_t *preset) { return (_("")); } /* sfloader callback to get the bank number of a preset */ static int sfloader_preset_get_banknum (fluid_preset_t *preset) { sfloader_preset_data_t *preset_data = preset->data; int bank; g_object_get (preset_data->item, "bank", &bank, NULL); return (bank); } /* sfloader callback to get the bank number of active preset */ static int sfloader_active_preset_get_banknum (fluid_preset_t *preset) { sfloader_preset_data_t *preset_data = preset->data; int bank; g_object_get (preset_data->wavetbl, "active-bank", &bank, NULL); return (bank); } /* sfloader callback to get the preset number of a preset */ static int sfloader_preset_get_num (fluid_preset_t *preset) { sfloader_preset_data_t *preset_data = preset->data; int program; g_object_get (preset_data->item, "program", &program, NULL); return (program); } /* sfloader callback to get the preset number of active preset */ static int sfloader_active_preset_get_num (fluid_preset_t *preset) { sfloader_preset_data_t *preset_data = preset->data; int psetnum; g_object_get (preset_data->wavetbl, "active-program", &psetnum, NULL); return (psetnum); } /* sfloader callback for a noteon event */ static int sfloader_preset_noteon (fluid_preset_t *preset, fluid_synth_t *synth, int chan, int key, int vel) { sfloader_preset_data_t *preset_data = preset->data; WavetblFluidSynth *wavetbl = preset->data; /* No item matches the bank:program? */ if (!preset_data->item) return (_SYNTH_OK); SWAMI_LOCK_WRITE (wavetbl); cache_instrument_noteon (wavetbl, preset_data->item, synth, chan, key, vel); SWAMI_UNLOCK_WRITE (wavetbl); return (_SYNTH_OK); } /* handles noteon event for active item */ static int sfloader_active_preset_noteon (fluid_preset_t *preset, fluid_synth_t *synth, int chan, int key, int vel) { WavetblFluidSynth *wavetbl = preset->data; SWAMI_LOCK_WRITE (wavetbl); if (!wavetbl->active_item) { SWAMI_UNLOCK_WRITE (wavetbl); return (_SYNTH_OK); /* no active item? Do nothing.. */ } cache_instrument_noteon (wavetbl, wavetbl->active_item, synth, chan, key, vel); SWAMI_UNLOCK_WRITE (wavetbl); return (_SYNTH_OK); } /* caches an instrument item into SoundFont voices for faster processing at * note-on time in cache_instrument_noteon(). * MT-NOTE: Caller is responsible for wavetbl object locking. */ static void cache_instrument (WavetblFluidSynth *wavetbl, IpatchItem *item) { IpatchSF2Voice *voice; IpatchSF2VoiceCache *cache; IpatchList *list; IpatchItem *solo_item = NULL; int i, count; /* no SF2 voice cache converter? */ if (!ipatch_find_converter (G_OBJECT_TYPE (item), IPATCH_TYPE_SF2_VOICE_CACHE)) return; SWAMI_LOCK_READ (wavetbl); if (wavetbl->solo_item) solo_item = g_object_ref (wavetbl->solo_item); /* ++ ref solo item */ SWAMI_UNLOCK_READ (wavetbl); /* Convert item to SF2 voice cache and assign solo-item (if any) * ++ ref list */ list = ipatch_convert_object_to_type_multi_set (G_OBJECT (item), IPATCH_TYPE_SF2_VOICE_CACHE, NULL, "solo-item", solo_item, NULL); if (!list) return; /* ++ ref first object from the list (voice cache) */ cache = IPATCH_SF2_VOICE_CACHE (g_object_ref (list->items->data)); g_object_unref (list); /* -- unref list */ /* copy session modulators to voice cache */ cache->default_mods = ipatch_sf2_mod_list_duplicate (wavetbl->mods); /* Use voice->user_data to close open cached stores */ cache->voice_user_data_destroy = (GDestroyNotify)ipatch_sample_store_cache_close; /* loop over voices and load sample data into RAM */ count = cache->voices->len; for (i = 0; i < count; i++) { voice = &g_array_index (cache->voices, IpatchSF2Voice, i); ipatch_sf2_voice_cache_sample_data (voice, NULL); /* Keep sample store cached by doing a dummy open */ ipatch_sample_store_cache_open ((IpatchSampleStoreCache *)voice->sample_store); voice->user_data = voice->sample_store; } /* !! hash takes over voice cache reference */ G_LOCK (voice_cache_hash); g_hash_table_insert (voice_cache_hash, item, cache); G_UNLOCK (voice_cache_hash); } /* noteon event function for cached instruments. * MT-NOTE: Caller is responsible for wavetbl object locking. */ static int cache_instrument_noteon (WavetblFluidSynth *wavetbl, IpatchItem *item, fluid_synth_t *synth, int chan, int key, int vel) { guint16 index_array[MAX_INST_VOICES]; /* voice index array */ int sel_values[IPATCH_SF2_VOICE_CACHE_MAX_SEL_VALUES]; fluid_voice_t *fluid_voices[MAX_REALTIME_VOICES]; IpatchSF2VoiceCache *cache; IpatchSF2VoiceSelInfo *sel_info; IpatchSF2GenArray *gen_array; fluid_voice_t *flvoice; fluid_sample_t *wusample; fluid_mod_t wumod; IpatchSF2Mod *mod; IpatchSF2Voice *voice; int i, voice_count, voice_num; GSList *p; G_LOCK (voice_cache_hash); cache = g_hash_table_lookup (voice_cache_hash, item); if (cache) g_object_ref (cache); /* ++ ref cache object */ G_UNLOCK (voice_cache_hash); if (!cache) return (_SYNTH_OK); /* instrument not yet cached? */ for (i = 0; i < cache->sel_count; i++) { sel_info = &cache->sel_info[i]; switch (sel_info->type) { case IPATCH_SF2_VOICE_SEL_NOTE: sel_values[i] = key; break; case IPATCH_SF2_VOICE_SEL_VELOCITY: sel_values[i] = vel; break; default: sel_values[i] = 127; /* FIXME */ break; } } voice_count = ipatch_sf2_voice_cache_select (cache, sel_values, index_array, MAX_INST_VOICES); /* loop over matching voice indexes */ for (voice_num = 0; voice_num < voice_count; voice_num++) { voice = IPATCH_SF2_VOICE_CACHE_GET_VOICE (cache, index_array[voice_num]); if (!voice->sample_store) continue; /* For ROM and other non-readable samples */ /* FIXME - pool of wusamples? */ wusample = g_malloc0 (sizeof (fluid_sample_t)); wusample->name[0] = '\0'; wusample->start = 0; wusample->end = voice->sample_size - 1; wusample->loopstart = voice->loop_start; wusample->loopend = voice->loop_end; wusample->samplerate = voice->rate; wusample->origpitch = voice->root_note; wusample->pitchadj = voice->fine_tune; wusample->sampletype = 0; wusample->valid = 1; wusample->data = ipatch_sample_store_cache_get_location ((IpatchSampleStoreCache *)(voice->sample_store)); /* allocate the FluidSynth voice */ flvoice = fluid_synth_alloc_voice (synth, wusample, chan, key, vel); if (!flvoice) { g_free (wusample); g_object_unref (cache); /* -- unref cache */ return (TRUE); } /* set only those generator parameters that are set */ gen_array = &voice->gen_array; for (i = 0; i < IPATCH_SF2_GEN_COUNT; i++) if (IPATCH_SF2_GEN_ARRAY_TEST_FLAG (gen_array, i)) fluid_voice_gen_set (flvoice, i, (float)(gen_array->values[i].sword)); p = voice->mod_list; while (p) { // wumod = fluid_mod_new (); mod = (IpatchSF2Mod *)(p->data); wumod.dest = mod->dest; wumod.src1 = mod->src & IPATCH_SF2_MOD_MASK_CONTROL; wumod.flags1 = ((mod->src & (IPATCH_SF2_MOD_MASK_DIRECTION | IPATCH_SF2_MOD_MASK_POLARITY | IPATCH_SF2_MOD_MASK_TYPE)) >> IPATCH_SF2_MOD_SHIFT_DIRECTION) | ((mod->src & IPATCH_SF2_MOD_MASK_CC) ? FLUID_MOD_CC : 0); wumod.src2 = mod->amtsrc & IPATCH_SF2_MOD_MASK_CONTROL; wumod.flags2 = ((mod->amtsrc & (IPATCH_SF2_MOD_MASK_DIRECTION | IPATCH_SF2_MOD_MASK_POLARITY | IPATCH_SF2_MOD_MASK_TYPE)) >> IPATCH_SF2_MOD_SHIFT_DIRECTION) | ((mod->amtsrc & IPATCH_SF2_MOD_MASK_CC) ? FLUID_MOD_CC : 0); wumod.amount = mod->amount; fluid_voice_add_mod (flvoice, &wumod, FLUID_VOICE_OVERWRITE); p = p->next; } fluid_synth_start_voice (synth, flvoice); /* let 'er rip */ /* voice pointers are only used for realtime note on, but not much CPU */ if (voice_num < MAX_REALTIME_VOICES) fluid_voices[voice_num] = flvoice; /* !! store reference taken over by wusample structure */ } g_object_unref (cache); /* -- unref cache */ /* check if item is the active audible, and update realtime vars if so */ if (item == wavetbl->active_item) { if (wavetbl->rt_cache) g_object_unref (wavetbl->rt_cache); wavetbl->rt_cache = g_object_ref (cache); /* store selection criteria and FluidSynth voices for note event */ memcpy (wavetbl->rt_sel_values, sel_values, cache->sel_count * sizeof (sel_values[0])); memcpy (wavetbl->rt_voices, fluid_voices, MIN (voice_count, MAX_REALTIME_VOICES) * sizeof (fluid_voices[0])); wavetbl->rt_count = voice_count; } return (_SYNTH_OK); } /* perform a realtime update on the active audible. * MT-NOTE: Wavetbl instance must be locked by caller. */ static void active_item_realtime_update (WavetblFluidSynth *wavetbl, IpatchItem *item, GParamSpec *pspec, const GValue *value) { IpatchSF2VoiceUpdate updates[MAX_REALTIME_UPDATES], *upd; int count, i, rt_count; rt_count = wavetbl->rt_count; if (!wavetbl->rt_cache || rt_count == 0) return; count = ipatch_sf2_voice_cache_update (wavetbl->rt_cache, wavetbl->rt_sel_values, (GObject *)(wavetbl->active_item), (GObject *)item, pspec, value, updates, MAX_REALTIME_UPDATES); /* loop over updates and apply to FluidSynth voices */ for (i = 0; i < count; i++) { upd = &updates[i]; if (upd->voice < rt_count) fluid_voice_gen_set (wavetbl->rt_voices[upd->voice], upd->genid, upd->ival); } /* update parameters (do separately so things are "more" atomic) */ for (i = 0; i < count; i++) { upd = &updates[i]; if (upd->voice < rt_count) fluid_voice_update_param (wavetbl->rt_voices[upd->voice], upd->genid); } } swami/src/plugins/fluidsynth_gui.c0000644000175000017500000002530711461334205017535 0ustar alessioalessio/* * fluidsynth_gui.c - GUI widgets for FluidSynth Swami plugin. * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #include "config.h" #include #include #include #include #include "fluidsynth_gui_i18n.h" typedef struct { GtkVBox parent_instance; GtkWidget *ctrl_widg; } FluidSynthGuiControl; typedef struct { GtkVBoxClass parent_class; } FluidSynthGuiControlClass; static int plugin_fluidsynth_gui_init (SwamiPlugin *plugin, GError **err); static GtkWidget *fluid_synth_pref_handler (void); static void fluid_synth_gui_audio_driver_changed (GtkComboBox *combo, gpointer user_data); static void fluid_synth_gui_midi_driver_changed (GtkComboBox *combo, gpointer user_data); static GType fluid_synth_gui_control_register_type (SwamiPlugin *plugin); static void fluid_synth_gui_control_class_init (FluidSynthGuiControlClass *klass); static void fluid_synth_gui_control_init (FluidSynthGuiControl *fsctrl); SWAMI_PLUGIN_INFO (plugin_fluidsynth_gui_init, NULL); /* List of audio and MIDI drivers that have Glade widgets */ const char *audio_driver_widgets[] = { "alsa", "jack", "oss", "dsound", NULL }; const char *midi_driver_widgets[] = { "alsa_seq", "alsa_raw", "oss", NULL }; /* --- functions --- */ /* plugin init function (one time initialize of SwamiPlugin) */ static gboolean plugin_fluidsynth_gui_init (SwamiPlugin *plugin, GError **err) { /* bind the gettext domain */ #if defined(ENABLE_NLS) bindtextdomain ("SwamiPlugin-fluidsynth-gui", LOCALEDIR); #endif g_object_set (plugin, "name", "FluidSynthGui", "version", "1.01", "author", "Josh Green", "copyright", "Copyright (C) 2007-2008", "descr", N_("FluidSynth software wavetable synth GUI plugin"), "license", "GPL", NULL); /* initialize types */ fluid_synth_gui_control_register_type (plugin); // fluid_synth_gui_map_register_type (plugin); // fluid_synth_gui_channels_register_type (plugin); swamigui_register_pref_handler ("FluidSynth", GTK_STOCK_MEDIA_PLAY, SWAMIGUI_PREF_ORDER_NAME, fluid_synth_pref_handler); return (TRUE); } /* preferences handler */ static GtkWidget * fluid_synth_pref_handler (void) { GtkWidget *fluid_widg; GtkWidget *widg; GtkListStore *store; GtkCellRenderer *cell; char **options, **optionp; fluid_widg = swamigui_util_glade_create ("FluidSynthPrefs"); if (swamigui_root->wavetbl) { /* Initialize audio driver list */ widg = swamigui_util_glade_lookup (fluid_widg, "ComboAudioDriver"); store = gtk_list_store_new (1, G_TYPE_STRING); gtk_combo_box_set_model (GTK_COMBO_BOX (widg), GTK_TREE_MODEL (store)); g_object_unref (store); cell = gtk_cell_renderer_text_new (); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widg), cell, TRUE); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (widg), cell, "text", 0, NULL); g_object_get (swamigui_root->wavetbl, "audio-driver-options", &options, NULL); /* ++ alloc */ for (optionp = options; *optionp; optionp++) gtk_combo_box_append_text (GTK_COMBO_BOX (widg), *optionp); g_boxed_free (G_TYPE_STRV, options); /* -- free */ /* Connect to changed signal of audio driver combo box */ g_signal_connect (widg, "changed", G_CALLBACK (fluid_synth_gui_audio_driver_changed), fluid_widg); /* Connect the audio combo box to the "audio.driver" property */ swamigui_control_prop_connect_widget (G_OBJECT (swamigui_root->wavetbl), "audio.driver", G_OBJECT (widg)); /* Initialize MIDI driver list */ widg = swamigui_util_glade_lookup (fluid_widg, "ComboMidiDriver"); store = gtk_list_store_new (1, G_TYPE_STRING); gtk_combo_box_set_model (GTK_COMBO_BOX (widg), GTK_TREE_MODEL (store)); g_object_unref (store); cell = gtk_cell_renderer_text_new (); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widg), cell, TRUE); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (widg), cell, "text", 0, NULL); g_object_get (swamigui_root->wavetbl, "midi-driver-options", &options, NULL); /* ++ alloc */ for (optionp = options; *optionp; optionp++) gtk_combo_box_append_text (GTK_COMBO_BOX (widg), *optionp); g_boxed_free (G_TYPE_STRV, options); /* -- free */ /* Connect to changed signal of MIDI driver combo box */ g_signal_connect (widg, "changed", G_CALLBACK (fluid_synth_gui_midi_driver_changed), fluid_widg); /* Connect the MIDI combo box to the "midi.driver" property */ swamigui_control_prop_connect_widget (G_OBJECT (swamigui_root->wavetbl), "midi.driver", G_OBJECT (widg)); /* Connect widgets to FluidSynth properties */ swamigui_control_glade_prop_connect (fluid_widg, G_OBJECT (swamigui_root->wavetbl)); } gtk_widget_show (fluid_widg); return (fluid_widg); } /* Callback when audio driver combo box changes */ static void fluid_synth_gui_audio_driver_changed (GtkComboBox *combo, gpointer user_data) { GtkWidget *fluid_widg = GTK_WIDGET (user_data); GtkWidget *driverwidg; GtkWidget *vbox; char *driver, *widgname; const char **sptr; driver = gtk_combo_box_get_active_text (combo); /* ++ alloc */ vbox = swamigui_util_glade_lookup (fluid_widg, "VBoxAudioDriver"); /* Remove existing child, if any */ gtk_container_foreach (GTK_CONTAINER (vbox), (GtkCallback)gtk_object_destroy, NULL); /* See if the driver has a widget */ for (sptr = audio_driver_widgets; *sptr; sptr++) if (strcmp (driver, *sptr) == 0) break; if (*sptr) { widgname = g_strconcat ("FluidSynth-Audio:", driver, NULL); /* ++ alloc */ driverwidg = swamigui_util_glade_create (widgname); g_free (widgname); /* -- free */ if (driverwidg) { swamigui_control_glade_prop_connect (driverwidg, G_OBJECT (swamigui_root->wavetbl)); gtk_box_pack_start (GTK_BOX (vbox), driverwidg, FALSE, FALSE, 0); } } } /* Callback when MIDI driver combo box changes */ static void fluid_synth_gui_midi_driver_changed (GtkComboBox *combo, gpointer user_data) { GtkWidget *fluid_widg = GTK_WIDGET (user_data); GtkWidget *driverwidg; GtkWidget *vbox; char *driver, *widgname; const char **sptr; driver = gtk_combo_box_get_active_text (combo); /* ++ alloc */ vbox = swamigui_util_glade_lookup (fluid_widg, "VBoxMidiDriver"); /* Remove existing child, if any */ gtk_container_foreach (GTK_CONTAINER (vbox), (GtkCallback)gtk_object_destroy, NULL); /* See if the driver has a widget */ for (sptr = midi_driver_widgets; *sptr; sptr++) if (strcmp (driver, *sptr) == 0) break; if (*sptr) { widgname = g_strconcat ("FluidSynth-MIDI:", driver, NULL); /* ++ alloc */ driverwidg = swamigui_util_glade_create (widgname); g_free (widgname); /* -- free */ if (driverwidg) { swamigui_control_glade_prop_connect (driverwidg, G_OBJECT (swamigui_root->wavetbl)); gtk_box_pack_start (GTK_BOX (vbox), driverwidg, FALSE, FALSE, 0); } } } static GType fluid_synth_gui_control_register_type (SwamiPlugin *plugin) { static const GTypeInfo obj_info = { sizeof (FluidSynthGuiControlClass), NULL, NULL, (GClassInitFunc)fluid_synth_gui_control_class_init, NULL, NULL, sizeof (FluidSynthGuiControl), 0, (GInstanceInitFunc) fluid_synth_gui_control_init, }; return (g_type_module_register_type (G_TYPE_MODULE (plugin), GTK_TYPE_VBOX, "FluidSynthGuiControl", &obj_info, 0)); } static void fluid_synth_gui_control_class_init (FluidSynthGuiControlClass *klass) { } static void fluid_synth_gui_control_init (FluidSynthGuiControl *fsctrl) { SwamiWavetbl *wavetbl; char namebuf[32]; const char *knobnames[] = { "Gain", "ReverbLevel", "ReverbRoom", "ReverbWidth", "ReverbDamp", "ChorusLevel", "ChorusCount", "ChorusFreq", "ChorusDepth" }; const char *propnames[] = { "synth-gain", "reverb-level", "reverb-room-size", "reverb-width", "reverb-damp", "chorus-level", "chorus-count", "chorus-freq", "chorus-depth" }; SwamiControl *propctrl, *widgctrl; GtkAdjustment *adj; GtkWidget *widg; GType type; int i; fsctrl->ctrl_widg = swamigui_util_glade_create ("FluidSynth"); gtk_widget_show (fsctrl->ctrl_widg); gtk_box_pack_start (GTK_BOX (fsctrl), fsctrl->ctrl_widg, FALSE, FALSE, 0); wavetbl = (SwamiWavetbl *)swami_object_get_by_type (G_OBJECT (swamigui_root), "WavetblFluidSynth"); if (!wavetbl) return; for (i = 0; i < G_N_ELEMENTS (knobnames); i++) { strcpy (namebuf, "Knob"); strcat (namebuf, knobnames[i]); widg = swamigui_util_glade_lookup (fsctrl->ctrl_widg, namebuf); adj = swamigui_knob_get_adjustment (SWAMIGUI_KNOB (widg)); propctrl = swami_get_control_prop_by_name (G_OBJECT (wavetbl), propnames[i]); widgctrl = SWAMI_CONTROL (swamigui_control_adj_new (adj)); swami_control_connect (propctrl, widgctrl, SWAMI_CONTROL_CONN_BIDIR | SWAMI_CONTROL_CONN_INIT | SWAMI_CONTROL_CONN_SPEC); } propctrl = swami_get_control_prop_by_name (G_OBJECT (wavetbl), "synth.reverb.active"); widg = swamigui_util_glade_lookup (fsctrl->ctrl_widg, "BtnReverb"); widgctrl = swamigui_control_new_for_widget (G_OBJECT (widg)); swami_control_connect (propctrl, widgctrl, SWAMI_CONTROL_CONN_BIDIR | SWAMI_CONTROL_CONN_INIT | SWAMI_CONTROL_CONN_SPEC); propctrl = swami_get_control_prop_by_name (G_OBJECT (wavetbl), "synth.chorus.active"); widg = swamigui_util_glade_lookup (fsctrl->ctrl_widg, "BtnChorus"); widgctrl = swamigui_control_new_for_widget (G_OBJECT (widg)); swami_control_connect (propctrl, widgctrl, SWAMI_CONTROL_CONN_BIDIR | SWAMI_CONTROL_CONN_INIT | SWAMI_CONTROL_CONN_SPEC); widg = swamigui_util_glade_lookup (fsctrl->ctrl_widg, "ComboChorusType"); propctrl = swami_get_control_prop_by_name (G_OBJECT (wavetbl), "chorus-waveform"); type = g_type_from_name ("WavetblFluidSynthChorusWaveform"); widgctrl = swamigui_control_new_for_widget_full (G_OBJECT (widg), type, NULL, 0); swami_control_connect (propctrl, widgctrl, SWAMI_CONTROL_CONN_BIDIR | SWAMI_CONTROL_CONN_INIT | SWAMI_CONTROL_CONN_SPEC); } swami/src/plugins/fluidsynth.def0000644000175000017500000000006610313226600017172 0ustar alessioalessioLIBRARY fluidsynth.dll EXPORTS swami_plugin_info DATA swami/src/plugins/fluidsynth_i18n.h0000644000175000017500000000066210075302551017531 0ustar alessioalessio#ifndef __SWAMIPLUGIN_FLUIDSYNTH_I18N_H__ #define __SWAMIPLUGIN_FLUIDSYNTH_I18N_H__ #include #ifndef _ #if defined(ENABLE_NLS) # include # define _(x) dgettext("SwamiPlugin-fluidsynth", x) # ifdef gettext_noop # define N_(String) gettext_noop (String) # else # define N_(String) (String) # endif #else # define N_(String) (String) # define _(x) (x) # define gettext(x) (x) #endif #endif #endif swami/src/plugins/fluidsynth.gladep0000644000175000017500000000131607676126120017705 0ustar alessioalessio FluidSynth Plugin fluidsynth-plugin . . FALSE FALSE FALSE FALSE FALSE TRUE FluidSynth_i18n.c swami/src/plugins/fftune.h0000644000175000017500000000623711704446464016010 0ustar alessioalessio/* * fftune.h - Header file for FFTW sample tuning plugin * * Swami * Copyright (C) 1999-2010 Joshua "Element" Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. */ #ifndef __PLUGIN_FFTUNE_H__ #define __PLUGIN_FFTUNE_H__ #include #include #define FFTUNE_TYPE_SPECTRA (fftune_spectra_get_type ()) #define FFTUNE_SPECTRA(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), FFTUNE_TYPE_SPECTRA, FFTuneSpectra)) #define FFTUNE_SPECTRA_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), FFTUNE_TYPE_SPECTRA, FFTuneSpectraClass)) #define FFTUNE_IS_SPECTRA(obj) \ (G_TYPE_CHECK_INSTANCE ((obj), FFTUNE_TYPE_SPECTRA)) #define FFTUNE_IS_SPECTRA_CLASS(klass) \ (G_TYPE_CHECK_CLASS ((klass), FFTUNE_TYPE_SPECTRA)) /* size in bytes for sample copy buffer */ #define FFTUNE_SAMPLE_COPY_BUFFER_SIZE (32 * 1024) /* FFT power spectrum object */ typedef struct { GObject parent; gboolean active; /* if TRUE, then change of params will update spectrum */ IpatchSample *sample; /* sample to calculate spectrum on */ int sample_mode; /* FFTUNE_MODE_* */ guint sample_start; /* start of selection (FFTUNE_MODE_SELECTION) */ guint sample_end; /* end of selection (start/end=0 will use entire sample) */ guint limit; /* maximum number of samples to process or 0 for unlimited */ double *spectrum; /* spectrum power data */ int spectrum_size; /* size of spectrum array */ double freqres; /* freq difference between consecutive spectrum indexes */ double max_index; /* index in spectrum of maximum power */ int *tunevals; /* array of spectrum indexes for tuning suggestions */ int n_tunevals; /* size of tunevals */ int tune_select; /* selected index in tunevals */ float threshold; /* power threshold for potential tuning suggestions */ float separation; /* min freq spread between suggestions */ float min_freq; /* min freq for tuning suggestions */ float max_freq; /* max freq for tuning suggestions */ int max_tunings; /* maximum tuning suggestions to find */ int enable_window; /* Enable Hann windowing of sample data */ float ellapsed_time; /* Ellapsed time of last execution in seconds */ } FFTuneSpectra; typedef struct { GObjectClass parent_class; } FFTuneSpectraClass; /* sample calculation mode enum */ enum { FFTUNE_MODE_SELECTION,/* sample start/end selection (entire sample if 0/0) */ FFTUNE_MODE_LOOP /* sample loop */ }; GType fftune_spectra_get_type (void); FFTuneSpectra *fftune_spectra_new (void); #endif swami/src/plugins/fluidsynth.glade0000644000175000017500000021361507711255141017530 0ustar alessioalessio True Preferences GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False True False 4 True False 6 True 0 0.5 GTK_SHADOW_ETCHED_IN 2 True False 2 2 True 3 2 False 2 2 True Type False False GTK_JUSTIFY_CENTER False False 0 0.5 0 0 0 1 0 1 fill True Device False False GTK_JUSTIFY_CENTER False False 0 0.5 0 0 0 1 1 2 fill True Buffer Size False False GTK_JUSTIFY_CENTER False False 0 0.5 0 0 0 1 2 3 fill True False 2 True True 1 0 False GTK_UPDATE_ALWAYS False False 64 16 4096 1 16 10 0 True True True Buffer Count False False GTK_JUSTIFY_CENTER False False 0.5 0.5 0 0 0 False False True True 1 0 True GTK_UPDATE_ALWAYS False False 3 2 16 1 4 10 0 True True 1 2 2 3 fill fill True 0 0.5 0 1 True True 0 True True AUTO True 1 2 0 1 fill True False 2 True True True True 0 True * False 0 True True True True Default True GTK_RELIEF_NORMAL False False True 0 False False 1 2 1 2 fill 0 True True True Audio Driver False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 label_item 0 False False True 0 0.5 GTK_SHADOW_ETCHED_IN 2 True False 2 2 True 2 2 False 2 2 True Type False False GTK_JUSTIFY_CENTER False False 0 0.5 0 0 0 1 0 1 fill True Device False False GTK_JUSTIFY_CENTER False False 0 0.5 0 0 0 1 1 2 fill True 0 0.5 0 1 True True 0 True True NONE True 1 2 0 1 True False 2 True True True True 0 True * False 0 True True True True Default True GTK_RELIEF_NORMAL False False True 0 False False 1 2 1 2 0 True True True MIDI Driver False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 label_item 0 False False True False 4 True True GTK_RELIEF_NORMAL True 0.5 0.5 0 0 True False 2 True gtk-refresh 4 0.5 0.5 0 0 0 False False True Restart True False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 0 False False 0 False False True For changes to take effect False False GTK_JUSTIFY_CENTER False False 0 0.5 0 0 0 False False 0 False False True FluidSynth Control GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False True False 4 True False 4 True True True True GTK_POS_TOP False False 4 True False 2 True False 0 True Master Gain False False GTK_JUSTIFY_CENTER False False 0.5 0.5 0 0 0 False False True True False GTK_POS_TOP 3 GTK_UPDATE_CONTINUOUS False 0 0 5 0.01 0 0 0 True True True True Default True GTK_RELIEF_NORMAL False False True 0 False False 0 False False True 0 0.5 GTK_SHADOW_ETCHED_IN 2 True 5 2 False 2 4 True Level False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 0 1 4 5 fill True Width False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 0 1 3 4 fill True Damp False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 0 1 2 3 fill True Room Size False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 0 1 1 2 fill True True False GTK_POS_RIGHT 3 GTK_UPDATE_CONTINUOUS False 0 0 1.2 0.001 0 0 1 2 1 2 fill True True False GTK_POS_RIGHT 3 GTK_UPDATE_CONTINUOUS False 0 0 1 0.001 0 0 1 2 2 3 fill True True False GTK_POS_RIGHT 3 GTK_UPDATE_CONTINUOUS False 0 0 100 0.1 0 0 1 2 3 4 fill True True False GTK_POS_RIGHT 3 GTK_UPDATE_CONTINUOUS False -30 -30 30 0.01 0.1 0 1 2 4 5 fill True False 2 True False True False True False True True True True 0 True * False True GTK_SELECTION_BROWSE 0 True True True True GTK_RELIEF_NORMAL True 0.5 0.5 0 0 True False 2 True gtk-save 4 0.5 0.5 0 0 0 False False True Save True False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 0 False False 0 False False 1 2 0 1 fill True Preset False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 0 1 0 1 fill True Reverb False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 label_item 0 False False True 0 0.5 GTK_SHADOW_ETCHED_IN 2 True 6 2 False 2 4 True Waveform False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 0 1 5 6 fill True Depth False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 0 1 4 5 fill True Frequency False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 0 1 3 4 fill True Level False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 0 1 2 3 fill True Count False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 0 1 1 2 fill True False 2 True False True False True False True True True True 0 True * False True GTK_SELECTION_BROWSE 0 True True True True GTK_RELIEF_NORMAL True 0.5 0.5 0 0 True False 2 True gtk-save 4 0.5 0.5 0 0 0 False False True Save True False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 0 False False 0 False False 1 2 0 1 fill True Preset False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 0 1 0 1 fill True 0 0.5 0 1 True True 0 True True Sine True True Triangle True 1 2 5 6 fill expand True True False GTK_POS_TOP 3 GTK_UPDATE_CONTINUOUS False 0 0 10 0.01 1 0 1 2 4 5 True True False GTK_POS_TOP 3 GTK_UPDATE_CONTINUOUS False 0.29 0.29 5 0.01 1 0 1 2 3 4 True True False GTK_POS_TOP 3 GTK_UPDATE_CONTINUOUS False 0 0 10 0.01 1 0 1 2 2 3 True True False GTK_POS_TOP 0 GTK_UPDATE_CONTINUOUS False 1 1 99 1 2 0 1 2 1 2 True Chorus False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 label_item 0 False False False True True Synthesis False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 tab 4 True True GTK_POLICY_AUTOMATIC GTK_POLICY_AUTOMATIC GTK_SHADOW_IN GTK_CORNER_TOP_LEFT True True True False False True False True True MIDI Channels False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 tab 4 True 3 2 False 2 2 True Polyphony False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 0 1 1 2 fill True Sample Rate False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 0 1 2 3 fill True Interpolation False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 0 1 0 1 fill True False 2 True True 0 True None True True Linear True True 4th Order True True 7th Order True 0 False False True True Default True GTK_RELIEF_NORMAL False False True 0 False False 1 2 0 1 fill True 0 0.5 0 1 True True 1 0 True GTK_UPDATE_ALWAYS False False 64 1 512 1 10 10 1 2 1 2 True 0 0.5 0 1 True True 1 0 True GTK_UPDATE_ALWAYS False False 44100 8000 192000 1 10 10 1 2 2 3 False False True Performance False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 tab 0 True True True 1 0.5 0 1 True True GTK_RELIEF_NORMAL True 0.5 0.5 0 0 True False 2 True gtk-close 4 0.5 0.5 0 0 0 False False True Close True False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 0 False False 0 False False swami/AUTHORS0000644000175000017500000000111010543044062013115 0ustar alessioalessioJosh Green Luis Garrido for the auto loop finder algorithm Ebrahim Mayat for Mac OS X testing, support and build HOWTO documentation Keishi Suenaga for Win32 patches and build HOWTO documentation Much thanks go to the following people who donated money $$ to the Swami project: Thomas Spellman - The first donor ;) Floyd Goldstein - Donated a very generous sum and also an Edirol R-09 recorder to the project, many many thanks! Additional donations and support: Apple Computer, Inc. for loaning me a G5 development machine for Mac OS X testing. swami/gtk-doc.make0000644000175000017500000001262711344522607014261 0ustar alessioalessio# -*- mode: makefile -*- #################################### # Everything below here is generic # #################################### if GTK_DOC_USE_LIBTOOL GTKDOC_CC = $(LIBTOOL) --mode=compile $(CC) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) GTKDOC_LD = $(LIBTOOL) --mode=link $(CC) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) GTKDOC_RUN = $(LIBTOOL) --mode=execute else GTKDOC_CC = $(CC) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) GTKDOC_LD = $(CC) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) GTKDOC_RUN = sh -c endif # We set GPATH here; this gives us semantics for GNU make # which are more like other make's VPATH, when it comes to # whether a source that is a target of one rule is then # searched for in VPATH/GPATH. # GPATH = $(srcdir) TARGET_DIR=$(HTML_DIR)/$(DOC_MODULE) EXTRA_DIST = \ $(content_files) \ $(HTML_IMAGES) \ $(DOC_MAIN_SGML_FILE) \ $(DOC_MODULE)-sections.txt \ $(DOC_MODULE)-overrides.txt DOC_STAMPS=scan-build.stamp sgml-build.stamp html-build.stamp \ $(srcdir)/sgml.stamp $(srcdir)/html.stamp SCANOBJ_FILES = \ $(DOC_MODULE).args \ $(DOC_MODULE).hierarchy \ $(DOC_MODULE).interfaces \ $(DOC_MODULE).prerequisites \ $(DOC_MODULE).signals REPORT_FILES = \ $(DOC_MODULE)-undocumented.txt \ $(DOC_MODULE)-undeclared.txt \ $(DOC_MODULE)-unused.txt CLEANFILES = $(SCANOBJ_FILES) $(REPORT_FILES) $(DOC_STAMPS) if ENABLE_GTK_DOC all-local: html-build.stamp else all-local: endif docs: html-build.stamp $(REPORT_FILES): sgml-build.stamp #### scan #### scan-build.stamp: $(HFILE_GLOB) $(CFILE_GLOB) @echo 'gtk-doc: Scanning header files' @-chmod -R u+w $(srcdir) cd $(srcdir) && \ gtkdoc-scan --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) --ignore-headers="$(IGNORE_HFILES)" $(SCAN_OPTIONS) $(EXTRA_HFILES) if grep -l '^..*$$' $(srcdir)/$(DOC_MODULE).types > /dev/null 2>&1 ; then \ CC="$(GTKDOC_CC)" LD="$(GTKDOC_LD)" RUN="$(GTKDOC_RUN)" CFLAGS="$(GTKDOC_CFLAGS) $(CFLAGS)" LDFLAGS="$(GTKDOC_LIBS) $(LDFLAGS)" gtkdoc-scangobj $(SCANGOBJ_OPTIONS) --module=$(DOC_MODULE) --output-dir=$(srcdir) ; \ else \ cd $(srcdir) ; \ for i in $(SCANOBJ_FILES) ; do \ test -f $$i || touch $$i ; \ done \ fi touch scan-build.stamp $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_MODULE)-overrides.txt: scan-build.stamp @true #### xml #### sgml-build.stamp: $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_MODULE)-overrides.txt $(expand_content_files) @echo 'gtk-doc: Building XML' @-chmod -R u+w $(srcdir) cd $(srcdir) && \ gtkdoc-mkdb --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) --output-format=xml --expand-content-files="$(expand_content_files)" --main-sgml-file=$(DOC_MAIN_SGML_FILE) $(MKDB_OPTIONS) touch sgml-build.stamp sgml.stamp: sgml-build.stamp @true #### html #### html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) @echo 'gtk-doc: Building HTML' @-chmod -R u+w $(srcdir) rm -rf $(srcdir)/html mkdir $(srcdir)/html mkhtml_options=""; \ gtkdoc-mkhtml 2>&1 --help | grep >/dev/null "\-\-path"; \ if test "$(?)" = "0"; then \ mkhtml_options=--path="$(srcdir)"; \ fi cd $(srcdir)/html && gtkdoc-mkhtml $(mkhtml_options) $(MKHTML_OPTIONS) $(DOC_MODULE) ../$(DOC_MAIN_SGML_FILE) test "x$(HTML_IMAGES)" = "x" || ( cd $(srcdir) && cp $(HTML_IMAGES) html ) @echo 'gtk-doc: Fixing cross-references' cd $(srcdir) && gtkdoc-fixxref --module-dir=html --html-dir=$(HTML_DIR) $(FIXXREF_OPTIONS) touch html-build.stamp ############## clean-local: rm -f *~ *.bak rm -rf .libs distclean-local: cd $(srcdir) && \ rm -rf xml $(REPORT_FILES) \ $(DOC_MODULE)-decl-list.txt $(DOC_MODULE)-decl.txt maintainer-clean-local: clean cd $(srcdir) && rm -rf html install-data-local: installfiles=`echo $(srcdir)/html/*`; \ if test "$$installfiles" = '$(srcdir)/html/*'; \ then echo '-- Nothing to install' ; \ else \ if test -n "$(DOC_MODULE_VERSION)"; then \ installdir="$(DESTDIR)$(TARGET_DIR)-$(DOC_MODULE_VERSION)"; \ else \ installdir="$(DESTDIR)$(TARGET_DIR)"; \ fi; \ $(mkinstalldirs) $${installdir} ; \ for i in $$installfiles; do \ echo '-- Installing '$$i ; \ $(INSTALL_DATA) $$i $${installdir}; \ done; \ if test -n "$(DOC_MODULE_VERSION)"; then \ mv -f $${installdir}/$(DOC_MODULE).devhelp2 \ $${installdir}/$(DOC_MODULE)-$(DOC_MODULE_VERSION).devhelp2; \ mv -f $${installdir}/$(DOC_MODULE).devhelp \ $${installdir}/$(DOC_MODULE)-$(DOC_MODULE_VERSION).devhelp; \ fi; \ ! which gtkdoc-rebase >/dev/null 2>&1 || \ gtkdoc-rebase --relative --dest-dir=$(DESTDIR) --html-dir=$${installdir} ; \ fi uninstall-local: if test -n "$(DOC_MODULE_VERSION)"; then \ installdir="$(DESTDIR)$(TARGET_DIR)-$(DOC_MODULE_VERSION)"; \ else \ installdir="$(DESTDIR)$(TARGET_DIR)"; \ fi; \ rm -rf $${installdir} # # Require gtk-doc when making dist # if ENABLE_GTK_DOC dist-check-gtkdoc: else dist-check-gtkdoc: @echo "*** gtk-doc must be installed and enabled in order to make dist" @false endif dist-hook: dist-check-gtkdoc dist-hook-local mkdir $(distdir)/html cp $(srcdir)/html/* $(distdir)/html -cp $(srcdir)/$(DOC_MODULE).types $(distdir)/ -cp $(srcdir)/$(DOC_MODULE)-sections.txt $(distdir)/ cd $(distdir) && rm -f $(DISTCLEANFILES) ! which gtkdoc-rebase >/dev/null 2>&1 || \ gtkdoc-rebase --online --relative --html-dir=$(distdir)/html .PHONY : dist-hook-local docs swami/HACKERS0000644000175000017500000000436610565141214013071 0ustar alessioalessioDocumentation for fellow hackers and those wishing to contribute code to the Swami project. Contributions without following these guidlines are ok, but it likely means more work for me, since I'll probably modify things so that it is correctly assimulated. Code style --------------- Code indentation style is pretty much the GNU style of the 'indent' command with a couple exceptions: Braces are not indented (i.e., they are on the same column as the statement they follow). Note that currently most of the project does in fact have 2 space brace indenting, but I'd like to change that. Also, pointer arguments in functions don't have a space between the * and the argument name (anyone know how to turn that off with indent?) Example: int function (GObject *obj, int arg) { int i; if (1 == 1) { for (i = 0; i < 0; i++) { printf ("This coding style is yummy!\n"); } } } The following indent command will get things almost right. If anyone knows how to turn off the spaces between the * in function pointer arguments and the argument name, do let me know. For some reason that just annoys the hell out of me ;) The other thing that is annoying is breaking lines on _("") macro i18n calls, but I doubt indent can be forced to not to do that. If I could fix those two issues I'd probably run indent on all the code, since the current bracing indentation style is not to my liking. indent -bli0 -sc -ncs myfile.c Commenting code --------------- Please comment all new public functions with GTK doc style comment blocks. Refcounting/memory allocation is also good to comment. Please do so like this: sf2 = ipatch_sf2_new (); /* ++ ref */ file = ipatch_file_new (); /* ++ ref */ ptr = g_new (MyStruct, 1); /* ++ alloc */ ... g_free (ptr); /* -- free */ g_object_unref (file); /* -- unref */ return (sf2); /* !! caller takes over reference */ So in other words, use "++" to indicate an allocate or object reference, "--" to indicate free or object unref and "!!" to indicate something special with allocation or reference counting (such as returning allocated or referenced object to caller). In this way it should be easy to scan a function quickly and notice if there are any ref/allocation issues (an unref forgotten, etc). swami/missing0000755000175000017500000002123107573110375013464 0ustar alessioalessio#! /bin/sh # Common stub for a few missing GNU programs while installing. # Copyright 1996, 1997, 1999, 2000 Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program 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 General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi case "$1" in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case "$1" in -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch]" ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing 0.3 - GNU automake" ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; aclocal) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case "$f" in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.h fi ;; esac fi if [ ! -f y.tab.h ]; then echo >y.tab.h fi if [ ! -f y.tab.c ]; then echo 'main() { return 0; }' >y.tab.c fi ;; lex|flex) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if [ ! -f lex.yy.c ]; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` fi if [ -f "$file" ]; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit 1 fi ;; makeinfo) if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then # We have makeinfo, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` fi touch $file ;; tar) shift if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 fi # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar ${1+"$@"} && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar ${1+"$@"} && exit 0 fi firstarg="$1" if shift; then case "$firstarg" in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" ${1+"$@"} && exit 0 ;; esac case "$firstarg" in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" ${1+"$@"} && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and you do not seem to have it handy on your system. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequirements for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 swami/INSTALL0000644000175000017500000000443207477605651013133 0ustar alessioalessio+-------------------------------------------------------+ + Swami - Installation + + Copyright (C) 1999-2002 Josh Green + + Email: jgreen@users.sourceforge.net + + Swami homepage: http://swami.sourceforge.net + +-------------------------------------------------------+ If compiling from CVS ----------------- You need to run "./autogen.sh" in the toplevel directory. You'll need autoconf, automake, libtool and perhaps other libraries and there development packages in order for this to work. Configure build system ----------------- Change to toplevel Swami source directory and execute: ./configure Some useful options to the configure script ("./configure --help" to list more options) you probably won't need to specify any of these: --with-audiofile-prefix=PFX Prefix where AUDIOFILE is installed (optional) --disable-splash Don't compile Swami splash intro image TIPS in using the configure script ----------------- Support for external libraries is for the most part auto detected. So you probably won't need to supply any switches to the configure script. If the configure script does something unexpected or fails it is often useful to look at the config.log file. If you install or remove a library used by Swami and you want to re-run configure, you may want to delete config.cache first. Required libraries ----------------- Swami requires a sound file library to load sample files (WAV, AU etc). Currently only audiofile is supported (libsndfile support soon). audiofile homepage: http://www.68k.org/~michael/audiofile/ libsndfile homepage: http://www.zip.com.au/~erikd/libsndfile/ GTK 1.2+ is required. It depends on a number of other libraries as well. Chances are you already have it. GTK homepage: http://www.gtk.org Optional libraries ----------------- The libpng library is used for the splash intro image. If you don't have it you won't get the splash image. You can also force the splash image to not be compiled (save about 60k in the Swami binary, but lose some of the Swami atmosphere) with the --disable-splash switch. Compile and install ----------------- To compile the package execute: make To install the binary file "swami" issue a: make install Please contact me (Josh Green ) if you have problems or suggestions with the build process. swami/ltmain.sh0000644000175000017500000073341511464144605013720 0ustar alessioalessio# Generated from ltmain.m4sh. # ltmain.sh (GNU libtool) 2.2.6b # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 2008 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, # or obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Usage: $progname [OPTION]... [MODE-ARG]... # # Provide generalized library-building support services. # # --config show all configuration variables # --debug enable verbose shell tracing # -n, --dry-run display commands without modifying any files # --features display basic configuration information and exit # --mode=MODE use operation mode MODE # --preserve-dup-deps don't remove duplicate dependency libraries # --quiet, --silent don't print informational messages # --tag=TAG use configuration variables from tag TAG # -v, --verbose print informational messages (default) # --version print version information # -h, --help print short or long help message # # MODE must be one of the following: # # clean remove files from the build directory # compile compile a source file into a libtool object # execute automatically set library path, then run a program # finish complete the installation of libtool libraries # install install libraries or executables # link create a library or an executable # uninstall remove libraries from an installed directory # # MODE-ARGS vary depending on the MODE. # Try `$progname --help --mode=MODE' for a more detailed description of MODE. # # When reporting a bug, please describe a test case to reproduce it and # include the following information: # # host-triplet: $host # shell: $SHELL # compiler: $LTCC # compiler flags: $LTCFLAGS # linker: $LD (gnu? $with_gnu_ld) # $progname: (GNU libtool) 2.2.6b Debian-2.2.6b-2ubuntu1 # automake: $automake_version # autoconf: $autoconf_version # # Report bugs to . PROGRAM=ltmain.sh PACKAGE=libtool VERSION="2.2.6b Debian-2.2.6b-2ubuntu1" TIMESTAMP="" package_revision=1.3017 # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # NLS nuisances: We save the old values to restore during execute mode. # Only set LANG and LC_ALL to C if already set. # These must not be set unconditionally because not all systems understand # e.g. LANG=C (notably SCO). lt_user_locale= lt_safe_locale= for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${$lt_var+set}\" = set; then save_$lt_var=\$$lt_var $lt_var=C export $lt_var lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" fi" done $lt_unset CDPATH : ${CP="cp -f"} : ${ECHO="echo"} : ${EGREP="/bin/grep -E"} : ${FGREP="/bin/grep -F"} : ${GREP="/bin/grep"} : ${LN_S="ln -s"} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SED="/bin/sed"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} : ${Xsed="$SED -e 1s/^X//"} # Global variables: EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. exit_status=$EXIT_SUCCESS # Make sure IFS has a sensible default lt_nl=' ' IFS=" $lt_nl" dirname="s,/[^/]*$,," basename="s,^.*/,," # func_dirname_and_basename file append nondir_replacement # perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` } # Generated shell functions inserted here. # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath="$0" # The name of this program: # In the unlikely event $progname began with a '-', it would play havoc with # func_echo (imagine progname=-n), so we prepend ./ in that case: func_dirname_and_basename "$progpath" progname=$func_basename_result case $progname in -*) progname=./$progname ;; esac # Make sure we have an absolute path for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=$func_dirname_result progdir=`cd "$progdir" && pwd` progpath="$progdir/$progname" ;; *) save_IFS="$IFS" IFS=: for progdir in $PATH; do IFS="$save_IFS" test -x "$progdir/$progname" && break done IFS="$save_IFS" test -n "$progdir" || progdir=`pwd` progpath="$progdir/$progname" ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed="${SED}"' -e 1s/^X//' sed_quote_subst='s/\([`"$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Re-`\' parameter expansions in output of double_quote_subst that were # `\'-ed in input to the same. If an odd number of `\' preceded a '$' # in input to double_quote_subst, that '$' was protected from expansion. # Since each input `\' is now two `\'s, look for any number of runs of # four `\'s followed by two `\'s and then a '$'. `\' that '$'. bs='\\' bs2='\\\\' bs4='\\\\\\\\' dollar='\$' sed_double_backslash="\ s/$bs4/&\\ /g s/^$bs2$dollar/$bs&/ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g s/\n//g" # Standard options: opt_dry_run=false opt_help=false opt_quiet=false opt_verbose=false opt_warning=: # func_echo arg... # Echo program name prefixed message, along with the current mode # name if it has been set yet. func_echo () { $ECHO "$progname${mode+: }$mode: $*" } # func_verbose arg... # Echo program name prefixed message in verbose mode only. func_verbose () { $opt_verbose && func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_error arg... # Echo program name prefixed message to standard error. func_error () { $ECHO "$progname${mode+: }$mode: "${1+"$@"} 1>&2 } # func_warning arg... # Echo program name prefixed warning message to standard error. func_warning () { $opt_warning && $ECHO "$progname${mode+: }$mode: warning: "${1+"$@"} 1>&2 # bash bug again: : } # func_fatal_error arg... # Echo program name prefixed message to standard error, and exit. func_fatal_error () { func_error ${1+"$@"} exit $EXIT_FAILURE } # func_fatal_help arg... # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { func_error ${1+"$@"} func_fatal_error "$help" } help="Try \`$progname --help' for more information." ## default # func_grep expression filename # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $GREP "$1" "$2" >/dev/null 2>&1 } # func_mkdir_p directory-path # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { my_directory_path="$1" my_dir_list= if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then # Protect directory names starting with `-' case $my_directory_path in -*) my_directory_path="./$my_directory_path" ;; esac # While some portion of DIR does not yet exist... while test ! -d "$my_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. my_dir_list="$my_directory_path:$my_dir_list" # If the last portion added has no slash in it, the list is done case $my_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop my_directory_path=`$ECHO "X$my_directory_path" | $Xsed -e "$dirname"` done my_dir_list=`$ECHO "X$my_dir_list" | $Xsed -e 's,:*$,,'` save_mkdir_p_IFS="$IFS"; IFS=':' for my_dir in $my_dir_list; do IFS="$save_mkdir_p_IFS" # mkdir can fail with a `File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$my_dir" 2>/dev/null || : done IFS="$save_mkdir_p_IFS" # Bail out if we (or some other process) failed to create a directory. test -d "$my_directory_path" || \ func_fatal_error "Failed to create \`$1'" fi } # func_mktempdir [string] # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, STRING is the basename for that directory. func_mktempdir () { my_template="${TMPDIR-/tmp}/${1-$progname}" if test "$opt_dry_run" = ":"; then # Return a directory name, but don't create it in dry-run mode my_tmpdir="${my_template}-$$" else # If mktemp works, use that first and foremost my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` if test ! -d "$my_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race my_tmpdir="${my_template}-${RANDOM-0}$$" save_mktempdir_umask=`umask` umask 0077 $MKDIR "$my_tmpdir" umask $save_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$my_tmpdir" || \ func_fatal_error "cannot create temporary directory \`$my_tmpdir'" fi $ECHO "X$my_tmpdir" | $Xsed } # func_quote_for_eval arg # Aesthetically quote ARG to be evaled later. # This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT # is double-quoted, suitable for a subsequent eval, whereas # FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters # which are still active within double quotes backslashified. func_quote_for_eval () { case $1 in *[\\\`\"\$]*) func_quote_for_eval_unquoted_result=`$ECHO "X$1" | $Xsed -e "$sed_quote_subst"` ;; *) func_quote_for_eval_unquoted_result="$1" ;; esac case $func_quote_for_eval_unquoted_result in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and and variable # expansion for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" ;; *) func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" esac } # func_quote_for_expand arg # Aesthetically quote ARG to be evaled later; same as above, # but do not quote variable references. func_quote_for_expand () { case $1 in *[\\\`\"]*) my_arg=`$ECHO "X$1" | $Xsed \ -e "$double_quote_subst" -e "$sed_double_backslash"` ;; *) my_arg="$1" ;; esac case $my_arg in # Double-quote args containing shell metacharacters to delay # word splitting and command substitution for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") my_arg="\"$my_arg\"" ;; esac func_quote_for_expand_result="$my_arg" } # func_show_eval cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$my_cmd" my_status=$? if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_show_eval_locale cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$lt_user_locale $my_cmd" my_status=$? eval "$lt_safe_locale" if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_version # Echo version message to standard output and exit. func_version () { $SED -n '/^# '$PROGRAM' (GNU /,/# warranty; / { s/^# // s/^# *$// s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ p }' < "$progpath" exit $? } # func_usage # Echo short help message to standard output and exit. func_usage () { $SED -n '/^# Usage:/,/# -h/ { s/^# // s/^# *$// s/\$progname/'$progname'/ p }' < "$progpath" $ECHO $ECHO "run \`$progname --help | more' for full usage" exit $? } # func_help # Echo long help message to standard output and exit. func_help () { $SED -n '/^# Usage:/,/# Report bugs to/ { s/^# // s/^# *$// s*\$progname*'$progname'* s*\$host*'"$host"'* s*\$SHELL*'"$SHELL"'* s*\$LTCC*'"$LTCC"'* s*\$LTCFLAGS*'"$LTCFLAGS"'* s*\$LD*'"$LD"'* s/\$with_gnu_ld/'"$with_gnu_ld"'/ s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/ s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/ p }' < "$progpath" exit $? } # func_missing_arg argname # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { func_error "missing argument for $1" exit_cmd=exit } exit_cmd=: # Check that we have a working $ECHO. if test "X$1" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test "X$1" = X--fallback-echo; then # Avoid inline document here, it may be left over : elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t'; then # Yippee, $ECHO works! : else # Restart under the correct shell, and then maybe $ECHO will work. exec $SHELL "$progpath" --no-reexec ${1+"$@"} fi if test "X$1" = X--fallback-echo; then # used as fallback echo shift cat </dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # Parse options once, thoroughly. This comes as soon as possible in # the script to make things like `libtool --version' happen quickly. { # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; esac # Parse non-mode specific arguments: while test "$#" -gt 0; do opt="$1" shift case $opt in --config) func_config ;; --debug) preserve_args="$preserve_args $opt" func_echo "enabling shell trace mode" opt_debug='set -x' $opt_debug ;; -dlopen) test "$#" -eq 0 && func_missing_arg "$opt" && break execute_dlfiles="$execute_dlfiles $1" shift ;; --dry-run | -n) opt_dry_run=: ;; --features) func_features ;; --finish) mode="finish" ;; --mode) test "$#" -eq 0 && func_missing_arg "$opt" && break case $1 in # Valid mode arguments: clean) ;; compile) ;; execute) ;; finish) ;; install) ;; link) ;; relink) ;; uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $opt" exit_cmd=exit break ;; esac mode="$1" shift ;; --preserve-dup-deps) opt_duplicate_deps=: ;; --quiet|--silent) preserve_args="$preserve_args $opt" opt_silent=: ;; --verbose| -v) preserve_args="$preserve_args $opt" opt_silent=false ;; --tag) test "$#" -eq 0 && func_missing_arg "$opt" && break preserve_args="$preserve_args $opt $1" func_enable_tag "$1" # tagname is set here shift ;; # Separate optargs to long options: -dlopen=*|--mode=*|--tag=*) func_opt_split "$opt" set dummy "$func_opt_split_opt" "$func_opt_split_arg" ${1+"$@"} shift ;; -\?|-h) func_usage ;; --help) opt_help=: ;; --version) func_version ;; -*) func_fatal_help "unrecognized option \`$opt'" ;; *) nonopt="$opt" break ;; esac done case $host in *cygwin* | *mingw* | *pw32* | *cegcc*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_duplicate_deps ;; esac # Having warned about all mis-specified options, bail out if # anything was wrong. $exit_cmd $EXIT_FAILURE } # func_check_version_match # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } ## ----------- ## ## Main. ## ## ----------- ## $opt_help || { # Sanity checks first: func_check_version_match if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then func_fatal_configuration "not configured to build any kind of library" fi test -z "$mode" && func_fatal_error "error: you must specify a MODE." # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$execute_dlfiles" && test "$mode" != execute; then func_error "unrecognized option \`-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help="$help" help="Try \`$progname --help --mode=$mode' for more information." } # func_lalib_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null \ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_unsafe_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if `file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case "$lalib_p_line" in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test "$lalib_p" = yes } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { func_lalib_p "$1" } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_ltwrapper_scriptname_result="" if func_ltwrapper_executable_p "$1"; then func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" fi } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $opt_debug save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$save_ifs eval cmd=\"$cmd\" func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # `FILE.' does not work on cygwin managed mounts. func_source () { $opt_debug case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $opt_debug if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_quote_for_eval "$arg" CC_quoted="$CC_quoted $func_quote_for_eval_result" done case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_quote_for_eval "$arg" CC_quoted="$CC_quoted $func_quote_for_eval_result" done case "$@ " in " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with \`--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=${1} if test "$build_libtool_libs" = yes; then write_lobj=\'${2}\' else write_lobj=none fi if test "$build_old_libs" = yes; then write_oldobj=\'${3}\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T <?"'"'"' &()|`$[]' \ && func_warning "libobj name \`$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname="$func_basename_result" xdir="$func_dirname_result" lobj=${xdir}$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test "$build_old_libs" = yes; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test "$compiler_c_o" = no; then output_obj=`$ECHO "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} lockfile="$output_obj.lock" else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test "$need_locks" = yes; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test "$need_locks" = warn; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi removelist="$removelist $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist removelist="$removelist $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 if test -n "$fix_srcfile_path"; then eval srcfile=\"$fix_srcfile_path\" fi func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. if test "$build_libtool_libs" = yes; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test "$pic_mode" != no; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir command="$command -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test "$suppress_opt" = yes; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test "$build_old_libs" = yes; then if test "$pic_mode" != yes; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test "$compiler_c_o" = yes; then command="$command -o $obj" fi # Suppress compiler output if we already did a PIC compilation. command="$command$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test "$need_locks" != no; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test "$mode" = compile && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to building PIC objects only -prefer-non-pic try to building non-PIC objects only -shared do not build a \`.o' file suitable for static linking -static only build a \`.o' file suitable for static linking COMPILE-COMMAND is a command to be used in creating a \`standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix \`.c' with the library object suffix, \`.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to \`-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the \`--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the \`install' or \`cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE Use a list of object files found in FILE to specify objects -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface All other options (arguments beginning with \`-') are ignored. Every other argument is treated as a filename. Files ending in \`.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only library objects (\`.lo' files) may be specified, and \`-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created using \`ar' and \`ranlib', or on Windows using \`lib'. If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode \`$mode'" ;; esac $ECHO $ECHO "Try \`$progname --help' for more information about other modes." exit $? } # Now that we've collected a possible --mode arg, show help if necessary $opt_help && func_mode_help # func_mode_execute arg... func_mode_execute () { $opt_debug # The first argument is the command name. cmd="$nonopt" test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $execute_dlfiles; do test -f "$file" \ || func_fatal_help "\`$file' is not a file" dir= case $file in *.la) # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "\`$file' was not linked with \`-export-dynamic'" continue fi func_dirname "$file" "" "." dir="$func_dirname_result" if test -f "$dir/$objdir/$dlname"; then dir="$dir/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir="$func_dirname_result" ;; *) func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir="$absdir" # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic="$magic" # Check if any of the arguments is a wrapper script. args= for file do case $file in -*) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file="$progdir/$program" elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file="$progdir/$program" fi ;; esac # Quote arguments (to preserve shell metacharacters). func_quote_for_eval "$file" args="$args $func_quote_for_eval_result" done if test "X$opt_dry_run" = Xfalse; then if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd="\$cmd$args" else # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" $ECHO "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS fi } test "$mode" = execute && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $opt_debug libdirs="$nonopt" admincmds= if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for dir do libdirs="$libdirs $dir" done for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || admincmds="$admincmds $cmds" fi done fi # Exit here if they wanted silent mode. $opt_silent && exit $EXIT_SUCCESS $ECHO "X----------------------------------------------------------------------" | $Xsed $ECHO "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done $ECHO $ECHO "If you ever happen to want to link against installed libraries" $ECHO "in a given directory, LIBDIR, you must either use libtool, and" $ECHO "specify the full pathname of the library, or use the \`-LLIBDIR'" $ECHO "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then $ECHO " - add LIBDIR to the \`$shlibpath_var' environment variable" $ECHO " during execution" fi if test -n "$runpath_var"; then $ECHO " - add LIBDIR to the \`$runpath_var' environment variable" $ECHO " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the \`$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then $ECHO " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" fi $ECHO $ECHO "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) $ECHO "more information, such as the ld(1), crle(1) and ld.so(8) manual" $ECHO "pages." ;; *) $ECHO "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac $ECHO "X----------------------------------------------------------------------" | $Xsed exit $EXIT_SUCCESS } test "$mode" = finish && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $opt_debug # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || # Allow the use of GNU shtool's install command. $ECHO "X$nonopt" | $GREP shtool >/dev/null; then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_for_eval "$arg" install_prog="$install_prog$func_quote_for_eval_result" # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=no stripme= for arg do if test -n "$dest"; then files="$files $dest" dest=$arg continue fi case $arg in -d) isdir=yes ;; -f) case " $install_prog " in *[\\\ /]cp\ *) ;; *) prev=$arg ;; esac ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_for_eval "$arg" install_prog="$install_prog $func_quote_for_eval_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the \`$prev' option requires an argument" if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=yes if test "$isdir" = yes; then destdir="$dest" destname= else func_dirname_and_basename "$dest" "" "." destdir="$func_dirname_result" destname="$func_basename_result" # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "\`$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "\`$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. staticlibs="$staticlibs $file" ;; *.la) # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) current_libdirs="$current_libdirs $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) future_libdirs="$future_libdirs $libdir" ;; esac fi func_dirname "$file" "/" "" dir="$func_dirname_result" dir="$dir$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "X$destdir" | $Xsed -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%%"` fi func_warning "relinking \`$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname="$1" shift srcname="$realname" test -n "$relink_command" && srcname="$realname"T # Install the shared library and build the symlinks. func_show_eval "$install_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme="$stripme" case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme="" ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try `ln -sf' first, because the `ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib="$destdir/$realname" func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name="$func_basename_result" instname="$dir/$name"i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest="$destfile" destfile= ;; *) func_fatal_help "cannot copy a libtool object to \`$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test "$build_old_libs" = yes; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext="" case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=".exe" fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script \`$wrapper'" finalize=yes for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile="$libdir/"`$ECHO "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test if test -n "$libdir" && test ! -f "$libfile"; then func_warning "\`$lib' has not been installed in \`$libdir'" finalize=no fi done relink_command= func_source "$wrapper" outputname= if test "$fast_install" = no && test -n "$relink_command"; then $opt_dry_run || { if test "$finalize" = yes; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file="$func_basename_result" outputname="$tmpdir/$file" # Replace the output file specification. relink_command=`$ECHO "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` $opt_silent || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else func_error "error: relink \`$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file="$outputname" else func_warning "cannot relink \`$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name="$func_basename_result" # Set up the ranlib parameters. oldlib="$destdir/$name" func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run \`$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test "$mode" = install && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $opt_debug my_outputname="$1" my_originator="$2" my_pic_p="${3-no}" my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms="${my_outputname}S.c" else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist="$output_objdir/${my_outputname}.nm" func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif /* External symbol declarations for the compiler. */\ " if test "$dlself" = yes; then func_verbose "generating symbol list for \`$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` for progfile in $progfiles; do func_verbose "extracting global C symbols from \`$progfile'" $opt_dry_run || eval "$NM $progfile | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols="$output_objdir/$outputname.exp" $opt_dry_run || { $RM $export_symbols eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from \`$dlprefile'" func_basename "$dlprefile" name="$func_basename_result" $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'" } done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else $ECHO '/* NONE */' >> "$output_objdir/$my_dlsyms" fi $ECHO >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; " case $host in *cygwin* | *mingw* | *cegcc* ) $ECHO >> "$output_objdir/$my_dlsyms" "\ /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */" lt_dlsym_const= ;; *osf5*) echo >> "$output_objdir/$my_dlsyms" "\ /* This system does not cope well with relocations in const data */" lt_dlsym_const= ;; *) lt_dlsym_const=const ;; esac $ECHO >> "$output_objdir/$my_dlsyms" "\ extern $lt_dlsym_const lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[]; $lt_dlsym_const lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = {\ { \"$my_originator\", (void *) 0 }," case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac $ECHO >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) if test "X$my_pic_p" != Xno; then pic_flag_for_symtable=" $pic_flag" fi ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) symtab_cflags="$symtab_cflags $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' # Transform the symbol file into the correct name. symfileobj="$output_objdir/${my_outputname}S.$objext" case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for \`$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` fi } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. func_win32_libid () { $opt_debug win32_libid_type="unknown" win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then win32_nmres=`eval $NM -f posix -A $1 | $SED -n -e ' 1,100{ / I /{ s,.*,import, p q } }'` case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_extract_an_archive dir oldlib func_extract_an_archive () { $opt_debug f_ex_an_ar_dir="$1"; shift f_ex_an_ar_oldlib="$1" func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" 'exit $?' if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $opt_debug my_gentop="$1"; shift my_oldlibs=${1+"$@"} my_oldobjs="" my_xlib="" my_xabs="" my_xdir="" for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib="$func_basename_result" my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir="$my_gentop/$my_xlib_u" func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` darwin_base_archive=`basename "$darwin_archive"` darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches ; do func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" func_extract_an_archive "`pwd`" "${darwin_base_archive}" cd "$darwin_curdir" $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` done func_extract_archives_result="$my_oldobjs" } # func_emit_wrapper_part1 [arg=no] # # Emit the first part of a libtool wrapper script on stdout. # For more information, see the description associated with # func_emit_wrapper(), below. func_emit_wrapper_part1 () { func_emit_wrapper_part1_arg1=no if test -n "$1" ; then func_emit_wrapper_part1_arg1=$1 fi $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed='${SED} -e 1s/^X//' sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then ECHO=\"$qecho\" file=\"\$0\" # Make sure echo works. if test \"X\$1\" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test \"X\`{ \$ECHO '\t'; } 2>/dev/null\`\" = 'X\t'; then # Yippee, \$ECHO works! : else # Restart under the correct shell, and then maybe \$ECHO will work. exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} fi fi\ " $ECHO "\ # Find the directory that this script lives in. thisdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"X\$file\" | \$Xsed -e 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` done " } # end: func_emit_wrapper_part1 # func_emit_wrapper_part2 [arg=no] # # Emit the second part of a libtool wrapper script on stdout. # For more information, see the description associated with # func_emit_wrapper(), below. func_emit_wrapper_part2 () { func_emit_wrapper_part2_arg1=no if test -n "$1" ; then func_emit_wrapper_part2_arg1=$1 fi $ECHO "\ # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_part2_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"X\$thisdir\" | \$Xsed -e 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test "$fast_install" = yes; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else $ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # Export our shlibpath_var if we have one. if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` export $shlibpath_var " fi # fixup the dll searchpath if we need to. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 fi else # The program doesn't exist. \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 $ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # end: func_emit_wrapper_part2 # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory in which it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=no if test -n "$1" ; then func_emit_wrapper_arg1=$1 fi # split this up so that func_emit_cwrapperexe_src # can call each part independently. func_emit_wrapper_part1 "${func_emit_wrapper_arg1}" func_emit_wrapper_part2 "${func_emit_wrapper_arg1}" } # func_to_host_path arg # # Convert paths to host format when used with build tools. # Intended for use with "native" mingw (where libtool itself # is running under the msys shell), or in the following cross- # build environments: # $build $host # mingw (msys) mingw [e.g. native] # cygwin mingw # *nix + wine mingw # where wine is equipped with the `winepath' executable. # In the native mingw case, the (msys) shell automatically # converts paths for any non-msys applications it launches, # but that facility isn't available from inside the cwrapper. # Similar accommodations are necessary for $host mingw and # $build cygwin. Calling this function does no harm for other # $host/$build combinations not listed above. # # ARG is the path (on $build) that should be converted to # the proper representation for $host. The result is stored # in $func_to_host_path_result. func_to_host_path () { func_to_host_path_result="$1" if test -n "$1" ; then case $host in *mingw* ) lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' case $build in *mingw* ) # actually, msys # awkward: cmd appends spaces to result lt_sed_strip_trailing_spaces="s/[ ]*\$//" func_to_host_path_tmp1=`( cmd //c echo "$1" |\ $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""` func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ $SED -e "$lt_sed_naive_backslashify"` ;; *cygwin* ) func_to_host_path_tmp1=`cygpath -w "$1"` func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ $SED -e "$lt_sed_naive_backslashify"` ;; * ) # Unfortunately, winepath does not exit with a non-zero # error code, so we are forced to check the contents of # stdout. On the other hand, if the command is not # found, the shell will set an exit code of 127 and print # *an error message* to stdout. So we must check for both # error code of zero AND non-empty stdout, which explains # the odd construction: func_to_host_path_tmp1=`winepath -w "$1" 2>/dev/null` if test "$?" -eq 0 && test -n "${func_to_host_path_tmp1}"; then func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ $SED -e "$lt_sed_naive_backslashify"` else # Allow warning below. func_to_host_path_result="" fi ;; esac if test -z "$func_to_host_path_result" ; then func_error "Could not determine host path corresponding to" func_error " '$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_path_result="$1" fi ;; esac fi } # end: func_to_host_path # func_to_host_pathlist arg # # Convert pathlists to host format when used with build tools. # See func_to_host_path(), above. This function supports the # following $build/$host combinations (but does no harm for # combinations not listed here): # $build $host # mingw (msys) mingw [e.g. native] # cygwin mingw # *nix + wine mingw # # Path separators are also converted from $build format to # $host format. If ARG begins or ends with a path separator # character, it is preserved (but converted to $host format) # on output. # # ARG is a pathlist (on $build) that should be converted to # the proper representation on $host. The result is stored # in $func_to_host_pathlist_result. func_to_host_pathlist () { func_to_host_pathlist_result="$1" if test -n "$1" ; then case $host in *mingw* ) lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_to_host_pathlist_tmp2="$1" # Once set for this call, this variable should not be # reassigned. It is used in tha fallback case. func_to_host_pathlist_tmp1=`echo "$func_to_host_pathlist_tmp2" |\ $SED -e 's|^:*||' -e 's|:*$||'` case $build in *mingw* ) # Actually, msys. # Awkward: cmd appends spaces to result. lt_sed_strip_trailing_spaces="s/[ ]*\$//" func_to_host_pathlist_tmp2=`( cmd //c echo "$func_to_host_pathlist_tmp1" |\ $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""` func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\ $SED -e "$lt_sed_naive_backslashify"` ;; *cygwin* ) func_to_host_pathlist_tmp2=`cygpath -w -p "$func_to_host_pathlist_tmp1"` func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\ $SED -e "$lt_sed_naive_backslashify"` ;; * ) # unfortunately, winepath doesn't convert pathlists func_to_host_pathlist_result="" func_to_host_pathlist_oldIFS=$IFS IFS=: for func_to_host_pathlist_f in $func_to_host_pathlist_tmp1 ; do IFS=$func_to_host_pathlist_oldIFS if test -n "$func_to_host_pathlist_f" ; then func_to_host_path "$func_to_host_pathlist_f" if test -n "$func_to_host_path_result" ; then if test -z "$func_to_host_pathlist_result" ; then func_to_host_pathlist_result="$func_to_host_path_result" else func_to_host_pathlist_result="$func_to_host_pathlist_result;$func_to_host_path_result" fi fi fi IFS=: done IFS=$func_to_host_pathlist_oldIFS ;; esac if test -z "$func_to_host_pathlist_result" ; then func_error "Could not determine the host path(s) corresponding to" func_error " '$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This may break if $1 contains DOS-style drive # specifications. The fix is not to complicate the expression # below, but for the user to provide a working wine installation # with winepath so that path translation in the cross-to-mingw # case works properly. lt_replace_pathsep_nix_to_dos="s|:|;|g" func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp1" |\ $SED -e "$lt_replace_pathsep_nix_to_dos"` fi # Now, add the leading and trailing path separators back case "$1" in :* ) func_to_host_pathlist_result=";$func_to_host_pathlist_result" ;; esac case "$1" in *: ) func_to_host_pathlist_result="$func_to_host_pathlist_result;" ;; esac ;; esac fi } # end: func_to_host_pathlist # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #ifdef _MSC_VER # include # include # include # define setmode _setmode #else # include # include # ifdef __CYGWIN__ # include # define HAVE_SETENV # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif # endif #endif #include #include #include #include #include #include #include #include #if defined(PATH_MAX) # define LT_PATHMAX PATH_MAX #elif defined(MAXPATHLEN) # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif #ifdef _MSC_VER # define S_IXUSR _S_IEXEC # define stat _stat # ifndef _INTPTR_T_DEFINED # define intptr_t int # endif #endif #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ defined (__OS2__) # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifdef __CYGWIN__ # define FOPEN_WB "wb" #endif #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free ((void *) stale); stale = 0; } \ } while (0) #undef LTWRAPPER_DEBUGPRINTF #if defined DEBUGWRAPPER # define LTWRAPPER_DEBUGPRINTF(args) ltwrapper_debugprintf args static void ltwrapper_debugprintf (const char *fmt, ...) { va_list args; va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } #else # define LTWRAPPER_DEBUGPRINTF(args) #endif const char *program_name = NULL; void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_fatal (const char *message, ...); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_opt_process_env_set (const char *arg); void lt_opt_process_env_prepend (const char *arg); void lt_opt_process_env_append (const char *arg); int lt_split_name_value (const char *arg, char** name, char** value); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); static const char *script_text_part1 = EOF func_emit_wrapper_part1 yes | $SED -e 's/\([\\"]\)/\\\1/g' \ -e 's/^/ "/' -e 's/$/\\n"/' echo ";" cat <"))); for (i = 0; i < newargc; i++) { LTWRAPPER_DEBUGPRINTF (("(main) newargz[%d] : %s\n", i, (newargz[i] ? newargz[i] : ""))); } EOF case $host_os in mingw*) cat <<"EOF" /* execv doesn't actually work on mingw as expected on unix */ rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz); if (rval == -1) { /* failed to start process */ LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target \"%s\": errno = %d\n", lt_argv_zero, errno)); return 127; } return rval; EOF ;; *) cat <<"EOF" execv (lt_argv_zero, newargz); return rval; /* =127, but avoids unused variable warning */ EOF ;; esac cat <<"EOF" } void * xmalloc (size_t num) { void *p = (void *) malloc (num); if (!p) lt_fatal ("Memory exhausted"); return p; } char * xstrdup (const char *string) { return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL; } const char * base_name (const char *name) { const char *base; #if defined (HAVE_DOS_BASED_FILE_SYSTEM) /* Skip over the disk name in MSDOS pathnames. */ if (isalpha ((unsigned char) name[0]) && name[1] == ':') name += 2; #endif for (base = name; *name; name++) if (IS_DIR_SEPARATOR (*name)) base = name + 1; return base; } int check_executable (const char *path) { struct stat st; LTWRAPPER_DEBUGPRINTF (("(check_executable) : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!")); if ((!path) || (!*path)) return 0; if ((stat (path, &st) >= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; LTWRAPPER_DEBUGPRINTF (("(make_executable) : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!")); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; int tmp_len; char *concat_name; LTWRAPPER_DEBUGPRINTF (("(find_executable) : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!")); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined (HAVE_DOS_BASED_FILE_SYSTEM) if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined (HAVE_DOS_BASED_FILE_SYSTEM) } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = q - p; p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal ("getcwd failed"); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal ("getcwd failed"); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { LTWRAPPER_DEBUGPRINTF (("checking path component for symlinks: %s\n", tmp_pathspec)); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { char *errstr = strerror (errno); lt_fatal ("Error accessing file %s (%s)", tmp_pathspec, errstr); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal ("Could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (strcmp (str, pat) == 0) *str = '\0'; } return str; } static void lt_error_core (int exit_status, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s: %s: ", program_name, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, "FATAL", message, ap); va_end (ap); } void lt_setenv (const char *name, const char *value) { LTWRAPPER_DEBUGPRINTF (("(lt_setenv) setting '%s' to '%s'\n", (name ? name : ""), (value ? value : ""))); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else int len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { int orig_value_len = strlen (orig_value); int add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } int lt_split_name_value (const char *arg, char** name, char** value) { const char *p; int len; if (!arg || !*arg) return 1; p = strchr (arg, (int)'='); if (!p) return 1; *value = xstrdup (++p); len = strlen (arg) - strlen (*value); *name = XMALLOC (char, len); strncpy (*name, arg, len-1); (*name)[len - 1] = '\0'; return 0; } void lt_opt_process_env_set (const char *arg) { char *name = NULL; char *value = NULL; if (lt_split_name_value (arg, &name, &value) != 0) { XFREE (name); XFREE (value); lt_fatal ("bad argument for %s: '%s'", env_set_opt, arg); } lt_setenv (name, value); XFREE (name); XFREE (value); } void lt_opt_process_env_prepend (const char *arg) { char *name = NULL; char *value = NULL; char *new_value = NULL; if (lt_split_name_value (arg, &name, &value) != 0) { XFREE (name); XFREE (value); lt_fatal ("bad argument for %s: '%s'", env_prepend_opt, arg); } new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); XFREE (name); XFREE (value); } void lt_opt_process_env_append (const char *arg) { char *name = NULL; char *value = NULL; char *new_value = NULL; if (lt_split_name_value (arg, &name, &value) != 0) { XFREE (name); XFREE (value); lt_fatal ("bad argument for %s: '%s'", env_append_opt, arg); } new_value = lt_extend_str (getenv (name), value, 1); lt_setenv (name, new_value); XFREE (new_value); XFREE (name); XFREE (value); } void lt_update_exe_path (const char *name, const char *value) { LTWRAPPER_DEBUGPRINTF (("(lt_update_exe_path) modifying '%s' by prepending '%s'\n", (name ? name : ""), (value ? value : ""))); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ int len = strlen (new_value); while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[len-1] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { LTWRAPPER_DEBUGPRINTF (("(lt_update_lib_path) modifying '%s' by prepending '%s'\n", (name ? name : ""), (value ? value : ""))); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF } # end: func_emit_cwrapperexe_src # func_mode_link arg... func_mode_link () { $opt_debug case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # which system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll which has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=no prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module="${wl}-single_module" func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg="$1" shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result func_append libtool_args " $func_quote_for_eval_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in dlfiles|dlprefiles) if test "$preload" = no; then # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=yes fi case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test "$dlself" = no; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test "$prev" = dlprefiles; then dlself=yes elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test "$prev" = dlfiles; then dlfiles="$dlfiles $arg" else dlprefiles="$dlprefiles $arg" fi prev= continue ;; esac ;; expsyms) export_symbols="$arg" test -f "$arg" \ || func_fatal_error "symbol file \`$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex="$arg" prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) deplibs="$deplibs $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir="$arg" prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # moreargs="$moreargs $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then dlfiles="$dlfiles $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. dlprefiles="$dlprefiles $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file \`$arg' does not exist" fi arg=$save_arg prev= continue ;; precious_regex) precious_files_regex="$arg" prev= continue ;; release) release="-$arg" prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test "$prev" = rpath; then case "$rpath " in *" $arg "*) ;; *) rpath="$rpath $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) xrpath="$xrpath $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds="$arg" prev= continue ;; weak) weak_libs="$weak_libs $arg" prev= continue ;; xcclinker) linker_flags="$linker_flags $qarg" compiler_flags="$compiler_flags $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) compiler_flags="$compiler_flags $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) linker_flags="$linker_flags $qarg" compiler_flags="$compiler_flags $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg="$arg" case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "\`-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test "X$arg" = "X-export-symbols"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname '-L' '' "$arg" dir=$func_stripname_result if test -z "$dir"; then if test "$#" -gt 0; then func_fatal_error "require no space between \`-L' and \`$1'" else func_fatal_error "need path for \`-L' option" fi fi # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of \`$dir'" dir="$absdir" ;; esac case "$deplibs " in *" -L$dir "*) ;; *) deplibs="$deplibs -L$dir" lib_search_path="$lib_search_path $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "X$dir" | $Xsed -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) dllsearchpath="$dllsearchpath:$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) dllsearchpath="$dllsearchpath:$testbindir";; esac ;; esac continue ;; -l*) if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test "X$arg" = "X-lc" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. test "X$arg" = "X-lc" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework deplibs="$deplibs System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test "X$arg" = "X-lc" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test "X$arg" = "X-lc" && continue ;; esac elif test "X$arg" = "X-lc_r"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi deplibs="$deplibs $arg" continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot) compiler_flags="$compiler_flags $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) compiler_flags="$compiler_flags $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) new_inherited_linker_flags="$new_inherited_linker_flags $arg" ;; esac continue ;; -multi_module) single_module="${wl}-multi_module" continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "\`-no-install' is ignored for $host" func_warning "assuming \`-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) xrpath="$xrpath $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" arg="$arg $wl$func_quote_for_eval_result" compiler_flags="$compiler_flags $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" arg="$arg $wl$func_quote_for_eval_result" compiler_flags="$compiler_flags $wl$func_quote_for_eval_result" linker_flags="$linker_flags $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; # -64, -mips[0-9] enable 64-bit mode on the SGI compiler # -r[0-9][0-9]* specifies the processor on the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler # +DA*, +DD* enable 64-bit mode on the HP compiler # -q* pass through compiler args for the IBM compiler # -m*, -t[45]*, -txscale* pass through architecture-specific # compiler args for GCC # -F/path gives path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC # @file GCC response files -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" func_append compile_command " $arg" func_append finalize_command " $arg" compiler_flags="$compiler_flags $arg" continue ;; # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; *.$objext) # A standard object. objs="$objs $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then dlfiles="$dlfiles $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. dlprefiles="$dlprefiles $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. deplibs="$deplibs $arg" old_deplibs="$old_deplibs $arg" continue ;; *.la) # A libtool-controlled library. if test "$prev" = dlfiles; then # This library was specified with -dlopen. dlfiles="$dlfiles $arg" prev= elif test "$prev" = dlprefiles; then # The library was specified with -dlpreopen. dlprefiles="$dlprefiles $arg" prev= else deplibs="$deplibs $arg" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the \`$prevarg' option requires an argument" if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname="$func_basename_result" libobjs_save="$libobjs" if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" func_dirname "$output" "/" "" output_objdir="$func_dirname_result$objdir" # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_duplicate_deps ; then case "$libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi libs="$libs $deplib" done if test "$linkmode" = lib; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; esac pre_post_deps="$pre_post_deps $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=no newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test "$linkmode,$pass" = "lib,link"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs="$tmp_deplibs" fi if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan"; then libs="$deplibs" deplibs= fi if test "$linkmode" = prog; then case $pass in dlopen) libs="$dlfiles" ;; dlpreopen) libs="$dlprefiles" ;; link) libs="$deplibs %DEPLIBS%" test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" ;; esac fi if test "$linkmode,$pass" = "lib,dlpreopen"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= case $lib in *.la) func_source "$lib" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do deplib_base=`$ECHO "X$deplib" | $Xsed -e "$basename"` case " $weak_libs " in *" $deplib_base "*) ;; *) deplibs="$deplibs $deplib" ;; esac done done libs="$dlprefiles" fi if test "$pass" = dlopen; then # Collect dlpreopened libraries save_deplibs="$deplibs" deplibs= fi for deplib in $libs; do lib= found=no case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else compiler_flags="$compiler_flags $deplib" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;; esac fi fi continue ;; -l*) if test "$linkmode" != lib && test "$linkmode" != prog; then func_warning "\`-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test "$linkmode" = lib; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib="$searchdir/lib${name}${search_ext}" if test -f "$lib"; then if test "$search_ext" = ".la"; then found=yes else found=no fi break 2 fi done done if test "$found" != yes; then # deplib doesn't seem to be a libtool library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue else # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll="$l" done if test "X$ll" = "X$old_library" ; then # only static version available found=no func_dirname "$lib" "" "." ladir="$func_dirname_result" lib=$ladir/$old_library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi fi ;; # -l *.ltframework) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test "$pass" = conv && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" newlib_search_path="$newlib_search_path $func_stripname_result" ;; prog) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi if test "$pass" = scan; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" newlib_search_path="$newlib_search_path $func_stripname_result" ;; *) func_warning "\`-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test "$pass" = link; then func_stripname '-R' '' "$deplib" dir=$func_stripname_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) xrpath="$xrpath $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) lib="$deplib" ;; *.$libext) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=no case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"X$deplib\"" 2>/dev/null | $Xsed -e 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=yes fi ;; pass_all) valid_a_lib=yes ;; esac if test "$valid_a_lib" != yes; then $ECHO $ECHO "*** Warning: Trying to link with static lib archive $deplib." $ECHO "*** I have the capability to make that library automatically link in when" $ECHO "*** you link to this library. But I can only do this if you have a" $ECHO "*** shared version of the library, which you do not appear to have" $ECHO "*** because the file extensions .$libext of this argument makes me believe" $ECHO "*** that it is just a static archive that I should not use here." else $ECHO $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" fi ;; esac continue ;; prog) if test "$pass" != link; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test "$pass" = conv; then deplibs="$deplib $deplibs" elif test "$linkmode" = prog; then if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlopen support or we're linking statically, # we need to preload. newdlprefiles="$newdlprefiles $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else newdlfiles="$newdlfiles $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=yes continue ;; esac # case $deplib if test "$found" = yes || test -f "$lib"; then : else func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" fi # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "\`$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir="$func_dirname_result" dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "X$inherited_linker_flags" | $Xsed -e 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) new_inherited_linker_flags="$new_inherited_linker_flags $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO "X $dependency_libs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan" || { test "$linkmode" != prog && test "$linkmode" != lib; }; then test -n "$dlopen" && dlfiles="$dlfiles $dlopen" test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" fi if test "$pass" = conv; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # It is a libtool convenience library, so add in its objects. convenience="$convenience $ladir/$objdir/$old_library" old_convenience="$old_convenience $ladir/$objdir/$old_library" tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_duplicate_deps ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done elif test "$linkmode" != prog && test "$linkmode" != lib; then func_fatal_error "\`$lib' is not a convenience library" fi continue fi # $pass = conv # Get the name of the library we link against. linklib= for l in $old_library $library_names; do linklib="$l" done if test -z "$linklib"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # This library was specified with -dlopen. if test "$pass" = dlopen; then if test -z "$libdir"; then func_fatal_error "cannot -dlopen a convenience library: \`$lib'" fi if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. dlprefiles="$dlprefiles $lib $dependency_libs" else newdlfiles="$newdlfiles $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of \`$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir="$ladir" fi ;; esac func_basename "$lib" laname="$func_basename_result" # Find the relevant object directory and library name. if test "X$installed" = Xyes; then if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library \`$lib' was moved." dir="$ladir" absdir="$abs_ladir" libdir="$abs_ladir" else dir="$libdir" absdir="$libdir" fi test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir="$ladir" absdir="$abs_ladir" # Remove this search path later notinst_path="$notinst_path $abs_ladir" else dir="$ladir/$objdir" absdir="$abs_ladir/$objdir" # Remove this search path later notinst_path="$notinst_path $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test "$pass" = dlpreopen; then if test -z "$libdir" && test "$linkmode" = prog; then func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" fi # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then newdlprefiles="$newdlprefiles $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ dlpreconveniencelibs="$dlpreconveniencelibs $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then newdlprefiles="$newdlprefiles $dir/$dlname" else newdlprefiles="$newdlprefiles $dir/$linklib" fi fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test "$linkmode" = lib; then deplibs="$dir/$old_library $deplibs" elif test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test "$linkmode" = prog && test "$pass" != link; then newlib_search_path="$newlib_search_path $ladir" deplibs="$lib $deplibs" linkalldeplibs=no if test "$link_all_deplibs" != no || test -z "$library_names" || test "$build_libtool_libs" = no; then linkalldeplibs=yes fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" newlib_search_path="$newlib_search_path $func_stripname_result" ;; esac # Need to link against all dependency_libs? if test "$linkalldeplibs" = yes; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_duplicate_deps ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done # for deplib continue fi # $linkmode = prog... if test "$linkmode,$pass" = "prog,link"; then if test -n "$library_names" && { { test "$prefer_static_libs" = no || test "$prefer_static_libs,$installed" = "built,yes"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then # Make sure the rpath contains only unique directories. case "$temp_rpath:" in *"$absdir:"*) ;; *) temp_rpath="$temp_rpath$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) compile_rpath="$compile_rpath $absdir" esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" esac ;; esac fi # $linkmode,$pass = prog,link... if test "$alldeplibs" = yes && { test "$deplibs_check_method" = pass_all || { test "$build_libtool_libs" = yes && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test "$use_static_libs" = built && test "$installed" = yes; then use_static_libs=no fi if test -n "$library_names" && { test "$use_static_libs" = no || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc*) # No point in relinking DLLs because paths are not encoded notinst_deplibs="$notinst_deplibs $lib" need_relink=no ;; *) if test "$installed" = no; then notinst_deplibs="$notinst_deplibs $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule="" for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule="$dlpremoduletest" break fi done if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then $ECHO if test "$linkmode" = prog; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test "$linkmode" = lib && test "$hardcode_into_libs" = yes; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) compile_rpath="$compile_rpath $absdir" esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname="$1" shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname="$dlname" elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc*) func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; esac eval soname=\"$soname_spec\" else soname="$realname" fi # Make a new name for the extract_expsyms_cmds to use soroot="$soname" func_basename "$soroot" soname="$func_basename_result" func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from \`$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for \`$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test "$linkmode" = prog || test "$mode" != relink; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test "$hardcode_direct" = no; then add="$dir/$linklib" case $host in *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; *-*-sysv4*uw2*) add_dir="-L$dir" ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir="-L$dir" ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we can not # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null ; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library" ; then $ECHO $ECHO "*** And there doesn't seem to be a static archive available" $ECHO "*** The link will probably fail, sorry" else add="$dir/$old_library" fi elif test -n "$old_library"; then add="$dir/$old_library" fi fi esac elif test "$hardcode_minus_L" = no; then case $host in *-*-sunos*) add_shlibpath="$dir" ;; esac add_dir="-L$dir" add="-l$name" elif test "$hardcode_shlibpath_var" = no; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; relink) if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$dir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$dir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) add_dir="$add_dir -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; *) lib_linked=no ;; esac if test "$lib_linked" != yes; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; esac fi if test "$linkmode" = prog; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test "$hardcode_direct" != yes && test "$hardcode_minus_L" != yes && test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; esac fi fi fi if test "$linkmode" = prog || test "$mode" = relink; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$libdir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$libdir" add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; esac add="-l$name" elif test "$hardcode_automatic" = yes; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib" ; then add="$inst_prefix_dir$libdir/$linklib" else add="$libdir/$linklib" fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir="-L$libdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) add_dir="$add_dir -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" fi if test "$linkmode" = prog; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test "$linkmode" = prog; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test "$hardcode_direct" != unsupported; then test -n "$old_library" && linklib="$old_library" compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test "$build_libtool_libs" = yes; then # Not a shared library if test "$deplibs_check_method" != pass_all; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. $ECHO $ECHO "*** Warning: This system can not link to static lib archive $lib." $ECHO "*** I have the capability to make that library automatically link in when" $ECHO "*** you link to this library. But I can only do this if you have a" $ECHO "*** shared version of the library, which you do not appear to have." if test "$module" = yes; then $ECHO "*** But as you try to build a module library, libtool will still create " $ECHO "*** a static module, that should work as long as the dlopening application" $ECHO "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then $ECHO $ECHO "*** However, this would only work if libtool was able to extract symbol" $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could" $ECHO "*** not find such a program. So, this module is probably useless." $ECHO "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test "$linkmode" = lib; then if test -n "$dependency_libs" && { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes || test "$link_static" = yes; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) xrpath="$xrpath $temp_xrpath";; esac;; *) temp_deplibs="$temp_deplibs $libdir";; esac done dependency_libs="$temp_deplibs" fi newlib_search_path="$newlib_search_path $absdir" # Link against this library test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" if $opt_duplicate_deps ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done if test "$link_all_deplibs" != no; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in -L*) path="$deplib" ;; *.la) func_dirname "$deplib" "" "." dir="$func_dirname_result" # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of \`$dir'" absdir="$dir" fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names" ; then for tmp in $deplibrary_names ; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl" ; then depdepl="$absdir/$objdir/$depdepl" darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi compiler_flags="$compiler_flags ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" linker_flags="$linker_flags -dylib_file ${darwin_install_name}:${depdepl}" path= fi fi ;; *) path="-L$absdir/$objdir" ;; esac else eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "\`$deplib' seems to be moved" path="-L$absdir" fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test "$pass" = link; then if test "$linkmode" = "prog"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs="$newdependency_libs" if test "$pass" = dlpreopen; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test "$pass" != dlopen; then if test "$pass" != conv; then # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) lib_search_path="$lib_search_path $dir" ;; esac done newlib_search_path= fi if test "$linkmode,$pass" != "prog,link"; then vars="deplibs" else vars="compile_deplibs finalize_deplibs" fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) tmp_libs="$tmp_libs $deplib" ;; esac ;; *) tmp_libs="$tmp_libs $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs ; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i="" ;; esac if test -n "$i" ; then tmp_libs="$tmp_libs $i" fi done dependency_libs=$tmp_libs done # for pass if test "$linkmode" = prog; then dlfiles="$newdlfiles" fi if test "$linkmode" = prog || test "$linkmode" = lib; then dlprefiles="$newdlprefiles" fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "\`-R' is ignored for archives" test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "\`-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "\`-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs="$output" objs="$objs$old_deplibs" ;; lib) # Make sure we only generate libraries of the form `libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test "$module" = no && \ func_fatal_help "libtool library \`$output' must begin with \`lib'" if test "$need_lib_prefix" != no; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test "$deplibs_check_method" != pass_all; then func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" else $ECHO $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" libobjs="$libobjs $objs" fi fi test "$dlself" != no && \ func_warning "\`-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test "$#" -gt 1 && \ func_warning "ignoring multiple \`-rpath's for a libtool library" install_libdir="$1" oldlibs= if test -z "$rpath"; then if test "$build_libtool_libs" = yes; then # Building a libtool convenience library. # Some compilers have problems with a `.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "\`-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs="$IFS"; IFS=':' set dummy $vinfo 0 0 0 shift IFS="$save_ifs" test -n "$7" && \ func_fatal_help "too many parameters to \`-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major="$1" number_minor="$2" number_revision="$3" # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # which has an extra 1 added just for fun # case $version_type in darwin|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_revision" ;; freebsd-aout|freebsd-elf|sunos) current="$number_major" revision="$number_minor" age="0" ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_minor" lt_irix_increment=no ;; *) func_fatal_configuration "$modename: unknown library version type \`$version_type'" ;; esac ;; no) current="$1" revision="$2" age="$3" ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT \`$current' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION \`$revision' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE \`$age' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE \`$age' is greater than the current interface number \`$current'" func_fatal_error "\`$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; freebsd-aout) major=".$current" versuffix=".$current.$revision"; ;; freebsd-elf) major=".$current" versuffix=".$current" ;; irix | nonstopux) if test "X$lt_irix_increment" = "Xno"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring="$verstring_prefix$major.$revision" # Add in all the interfaces that we are compatible with. loop=$revision while test "$loop" -ne 0; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring_prefix$major.$iface:$verstring" done # Before this point, $major must not contain `.'. major=.$major versuffix="$major.$revision" ;; linux) func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=".$current.$age.$revision" verstring="$current.$age.$revision" # Add in all the interfaces that we are compatible with. loop=$age while test "$loop" -ne 0; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring:${iface}.0" done # Make executables depend on our current version. verstring="$verstring:${current}.0" ;; qnx) major=".$current" versuffix=".$current" ;; sunos) major=".$current" versuffix=".$current.$revision" ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 filesystems. func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; *) func_fatal_configuration "unknown library version type \`$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring="0.0" ;; esac if test "$need_version" = no; then versuffix= else versuffix=".0.0" fi fi # Remove version info from name if versioning should be avoided if test "$avoid_version" = yes && test "$need_version" = no; then major= versuffix= verstring="" fi # Check to see if the archive will have undefined symbols. if test "$allow_undefined" = yes; then if test "$allow_undefined_flag" = unsupported; then func_warning "undefined symbols not allowed in $host shared libraries" build_libtool_libs=no build_old_libs=yes fi else # Don't allow undefined symbols. allow_undefined_flag="$no_undefined_flag" fi fi func_generate_dlsyms "$libname" "$libname" "yes" libobjs="$libobjs $symfileobj" test "X$libobjs" = "X " && libobjs= if test "$mode" != relink; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) if test "X$precious_files_regex" != "X"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi removelist="$removelist $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then oldlibs="$oldlibs $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "X$lib_search_path " | $Xsed -e "s% $path % %g"` # deplibs=`$ECHO "X$deplibs " | $Xsed -e "s% -L$path % %g"` # dependency_libs=`$ECHO "X$dependency_libs " | $Xsed -e "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do temp_xrpath="$temp_xrpath -R$libdir" case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" ;; esac done if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles="$dlfiles" dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) dlfiles="$dlfiles $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles="$dlprefiles" dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) dlprefiles="$dlprefiles $lib" ;; esac done if test "$build_libtool_libs" = yes; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework deplibs="$deplibs System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test "$build_libtool_need_lc" = "yes"; then deplibs="$deplibs -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release="" versuffix="" major="" newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c </dev/null` for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib="$potent_lib" while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; *) potlib=`$ECHO "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then newdeplibs="$newdeplibs $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes $ECHO $ECHO "*** Warning: linker path does not have real file for library $a_deplib." $ECHO "*** I have the capability to make that library automatically link in when" $ECHO "*** you link to this library. But I can only do this if you have a" $ECHO "*** shared version of the library, which you do not appear to have" $ECHO "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. newdeplibs="$newdeplibs $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $a_deplib "*) newdeplibs="$newdeplibs $a_deplib" a_deplib="" ;; esac fi if test -n "$a_deplib" ; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib="$potent_lib" # see symlink-check above in file_magic test if eval "\$ECHO \"X$potent_lib\"" 2>/dev/null | $Xsed -e 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then newdeplibs="$newdeplibs $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes $ECHO $ECHO "*** Warning: linker path does not have real file for library $a_deplib." $ECHO "*** I have the capability to make that library automatically link in when" $ECHO "*** you link to this library. But I can only do this if you have a" $ECHO "*** shared version of the library, which you do not appear to have" $ECHO "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. newdeplibs="$newdeplibs $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs="" tmp_deplibs=`$ECHO "X $deplibs" | $Xsed \ -e 's/ -lc$//' -e 's/ -[LR][^ ]*//g'` if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then for i in $predeps $postdeps ; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO "X $tmp_deplibs" | $Xsed -e "s,$i,,"` done fi if $ECHO "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' | $GREP . >/dev/null; then $ECHO if test "X$deplibs_check_method" = "Xnone"; then $ECHO "*** Warning: inter-library dependencies are not supported in this platform." else $ECHO "*** Warning: inter-library dependencies are not known to be supported." fi $ECHO "*** All declared inter-library dependencies are being dropped." droppeddeps=yes fi ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's/ -lc / System.ltframework /'` ;; esac if test "$droppeddeps" = yes; then if test "$module" = yes; then $ECHO $ECHO "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" $ECHO "*** a static module, that should work as long as the dlopening" $ECHO "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then $ECHO $ECHO "*** However, this would only work if libtool was able to extract symbol" $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could" $ECHO "*** not find such a program. So, this module is probably useless." $ECHO "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else $ECHO "*** The inter-library dependencies that have been dropped here will be" $ECHO "*** automatically added whenever a program is linked with this library" $ECHO "*** or is declared to -dlopen it." if test "$allow_undefined" = no; then $ECHO $ECHO "*** Since this library must not contain undefined symbols," $ECHO "*** because either the platform does not support them or" $ECHO "*** it was explicitly requested with -no-undefined," $ECHO "*** libtool will only create a static version of it." if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO "X $deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) new_libs="$new_libs -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$new_libs $deplib" ;; esac ;; *) new_libs="$new_libs $deplib" ;; esac done deplibs="$new_libs" # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test "$build_libtool_libs" = yes; then if test "$hardcode_into_libs" = yes; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath="$finalize_rpath" test "$mode" != relink && rpath="$compile_rpath$rpath" for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" dep_rpath="$dep_rpath $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) perm_rpath="$perm_rpath $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" if test -n "$hardcode_libdir_flag_spec_ld"; then eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" else eval dep_rpath=\"$hardcode_libdir_flag_spec\" fi fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do rpath="$rpath$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath="$finalize_shlibpath" test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname="$1" shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname="$realname" fi if test -z "$dlname"; then dlname=$soname fi lib="$output_objdir/$realname" linknames= for link do linknames="$linknames $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols="$output_objdir/$libname.uexp" delfiles="$delfiles $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile if test "x`$SED 1q $export_symbols`" != xEXPORTS; then # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols="$export_symbols" export_symbols= always_export_symbols=yes fi fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" func_len " $cmd" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then func_show_eval "$cmd" 'exit $?' skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS="$save_ifs" if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"' fi if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter delfiles="$delfiles $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) tmp_deplibs="$tmp_deplibs $test_deplib" ;; esac done deplibs="$tmp_deplibs" if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test "$compiler_needs_object" = yes && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_extract_archives $gentop $convenience libobjs="$libobjs $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" linker_flags="$linker_flags $flag" fi # Make a backup of the uninstalled library when relinking if test "$mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test "X$skipped_export" != "X:" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output output_la=`$ECHO "X$output" | $Xsed -e "$basename"` # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then output=${output_objdir}/${output_la}.lnkscript func_verbose "creating GNU ld script: $output" $ECHO 'INPUT (' > $output for obj in $save_libobjs do $ECHO "$obj" >> $output done $ECHO ')' >> $output delfiles="$delfiles $output" elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then output=${output_objdir}/${output_la}.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test "$compiler_needs_object" = yes; then firstobj="$1 " shift fi for obj do $ECHO "$obj" >> $output done delfiles="$delfiles $output" output=$firstobj\"$file_list_spec$output\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-${k}.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test "X$objlist" = X || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test "$k" -eq 1 ; then # The first file doesn't have a previous command to add. eval concat_cmds=\"$reload_cmds $objlist $last_robj\" else # All subsequent reloadable object files will link in # the last one created. eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-${k}.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-${k}.$objext objlist=$obj func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" if test -n "$last_robj"; then eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" fi delfiles="$delfiles $output" else output= fi if ${skipped_export-false}; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi fi test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs="$IFS"; IFS='~' for cmd in $concat_cmds; do IFS="$save_ifs" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi if ${skipped_export-false}; then if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter delfiles="$delfiles $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi fi libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_extract_archives $gentop $dlprefiles libobjs="$libobjs $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" # Restore the uninstalled library and exit if test "$mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test "$module" = yes || test "$export_dynamic" = yes; then # On all known operating systems, these are identical. dlname="$soname" fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "\`-R' is ignored for objects" test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for objects" test -n "$release" && \ func_warning "\`-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object \`$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj="$output" ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # reload_cmds runs $LD directly, so let us get rid of # -Wl from whole_archive_flag_spec and hope we can get by with # turning comma into space.. wl= if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" reload_conv_objs=$reload_objs\ `$ECHO "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'` else gentop="$output_objdir/${obj}x" generated="$generated $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # Create the old-style object. reload_objs="$objs$old_deplibs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test output="$obj" func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi if test "$build_libtool_libs" != yes; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS fi if test -n "$pic_flag" || test "$pic_mode" != default; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output="$libobj" func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for programs" test -n "$release" && \ func_warning "\`-release' is ignored for programs" test "$preload" = yes \ && test "$dlopen_support" = unknown \ && test "$dlopen_self" = unknown \ && test "$dlopen_self_static" = unknown && \ func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test "$tagname" = CXX ; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) compile_command="$compile_command ${wl}-bind_at_load" finalize_command="$finalize_command ${wl}-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) new_libs="$new_libs -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$new_libs $deplib" ;; esac ;; *) new_libs="$new_libs $deplib" ;; esac done compile_deplibs="$new_libs" compile_command="$compile_command $compile_deplibs" finalize_command="$finalize_command $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" rpath="$rpath $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) perm_rpath="$perm_rpath $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) dllsearchpath="$dllsearchpath:$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) dllsearchpath="$dllsearchpath:$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath="$rpath" rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" rpath="$rpath $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath="$rpath" if test -n "$libobjs" && test "$build_old_libs" = yes; then # Transform all the library objects into standard objects. compile_command=`$ECHO "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` finalize_command=`$ECHO "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" "no" # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=yes case $host in *cygwin* | *mingw* ) if test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; *cegcc) # Disable wrappers for cegcc, we are cross compiling anyway. wrappers_required=no ;; *) if test "$need_relink" = no || test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; esac if test "$wrappers_required" = no; then # Replace the output file specification. compile_command=`$ECHO "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` link_command="$compile_command$compile_rpath" # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' # Delete the generated files. if test -f "$output_objdir/${outputname}S.${objext}"; then func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' fi exit $exit_status fi if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do rpath="$rpath$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do rpath="$rpath$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test "$no_install" = yes; then # We don't need to create a wrapper script. link_command="$compile_var$compile_command$compile_rpath" # Replace the output file specification. link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' exit $EXIT_SUCCESS fi if test "$hardcode_action" = relink; then # Fast installation is not supported link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" func_warning "this platform does not like uninstalled shared libraries" func_warning "\`$output' will be relinked during installation" else if test "$fast_install" != no; then link_command="$finalize_var$compile_command$finalize_rpath" if test "$fast_install" = yes; then relink_command=`$ECHO "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` else # fast_install is set to needless relink_command= fi else link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" fi fi # Replace the output file specification. link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"` fi # Quote $ECHO for shipping. if test "X$ECHO" = "X$SHELL $progpath --fallback-echo"; then case $progpath in [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; esac qecho=`$ECHO "X$qecho" | $Xsed -e "$sed_quote_subst"` else qecho=`$ECHO "X$ECHO" | $Xsed -e "$sed_quote_subst"` fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource="$output_path/$objdir/lt-$output_name.c" cwrapper="$output_path/$output_name.exe" $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host" ; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do if test "$build_libtool_libs" = convenience; then oldobjs="$libobjs_save $symfileobj" addlibs="$convenience" build_libtool_libs=no else if test "$build_libtool_libs" = module; then oldobjs="$libobjs_save" build_libtool_libs=no else oldobjs="$old_deplibs $non_pic_objects" if test "$preload" = yes && test -f "$symfileobj"; then oldobjs="$oldobjs $symfileobj" fi fi addlibs="$old_convenience" fi if test -n "$addlibs"; then gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_extract_archives $gentop $addlibs oldobjs="$oldobjs $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_extract_archives $gentop $dlprefiles oldobjs="$oldobjs $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else $ECHO "copying selected object files to avoid basename conflicts..." gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase="$func_basename_result" case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" oldobjs="$oldobjs $gentop/$newobj" ;; *) oldobjs="$oldobjs $obj" ;; esac done fi eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj" ; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test "X$oldobjs" = "X" ; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test "$build_old_libs" = yes && old_library="$libname.$libext" func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"` if test "$hardcode_automatic" = yes ; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test "$installed" = yes; then if test -z "$install_libdir"; then break fi output="$output_objdir/$outputname"i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" newdependency_libs="$newdependency_libs $libdir/$name" ;; *) newdependency_libs="$newdependency_libs $deplib" ;; esac done dependency_libs="$newdependency_libs" newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" newdlfiles="$newdlfiles $libdir/$name" ;; *) newdlfiles="$newdlfiles $lib" ;; esac done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" newdlprefiles="$newdlprefiles $libdir/$name" ;; esac done dlprefiles="$newdlprefiles" else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac newdlfiles="$newdlfiles $abs" done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac newdlprefiles="$newdlprefiles $abs" done dlprefiles="$newdlprefiles" fi $RM $output # place dlname in correct position for cygwin tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that can not go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test "$installed" = no && test "$need_relink" = yes; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } { test "$mode" = link || test "$mode" = relink; } && func_mode_link ${1+"$@"} # func_mode_uninstall arg... func_mode_uninstall () { $opt_debug RM="$nonopt" files= rmforce= exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" for arg do case $arg in -f) RM="$RM $arg"; rmforce=yes ;; -*) RM="$RM $arg" ;; *) files="$files $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= origobjdir="$objdir" for file in $files; do func_dirname "$file" "" "." dir="$func_dirname_result" if test "X$dir" = X.; then objdir="$origobjdir" else objdir="$dir/$origobjdir" fi func_basename "$file" name="$func_basename_result" test "$mode" = uninstall && objdir="$dir" # Remember objdir for removal later, being careful to avoid duplicates if test "$mode" = clean; then case " $rmdirs " in *" $objdir "*) ;; *) rmdirs="$rmdirs $objdir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif test "$rmforce" = yes; then continue fi rmfiles="$file" case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do rmfiles="$rmfiles $objdir/$n" done test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" case "$mode" in clean) case " $library_names " in # " " in the beginning catches empty $dlname *" $dlname "*) ;; *) rmfiles="$rmfiles $objdir/$dlname" ;; esac test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test "$pic_object" != none; then rmfiles="$rmfiles $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test "$non_pic_object" != none; then rmfiles="$rmfiles $dir/$non_pic_object" fi fi ;; *) if test "$mode" = clean ; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe rmfiles="$rmfiles $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result rmfiles="$rmfiles $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" if test "$fast_install" = yes && test -n "$relink_command"; then rmfiles="$rmfiles $objdir/lt-$name" fi if test "X$noexename" != "X$name" ; then rmfiles="$rmfiles $objdir/lt-${noexename}.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done objdir="$origobjdir" # Try to remove the ${objdir}s in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } { test "$mode" = uninstall || test "$mode" = clean; } && func_mode_uninstall ${1+"$@"} test -z "$mode" && { help="$generic_help" func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode \`$mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # in which we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: # vi:sw=2 swami/config.sub0000755000175000017500000010224011344522607014044 0ustar alessioalessio#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 # Free Software Foundation, Inc. timestamp='2009-04-17' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray) os= basic_machine=$1 ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nios | nios2 \ | ns16k | ns32k \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ | v850 | v850e \ | we32k \ | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \ | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; mvs) basic_machine=i370-ibm os=-mvs ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff ;; tic55x | c55x*) basic_machine=tic55x-unknown os=-coff ;; tic6x | c6x*) basic_machine=tic6x-unknown os=-coff ;; tile*) basic_machine=tile-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -kopensolaris* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: swami/Makefile.am0000644000175000017500000000323111461404311014104 0ustar alessioalessio## Process this file with automake to produce Makefile.in SUBDIRS = m4 src po docs package ACLOCAL_AMFLAGS = -I m4 EXTRA_DIST = \ autogen.sh \ ABOUT-NLS \ CVS-HOWTO \ intltool-extract.in \ intltool-merge.in \ intltool-update.in \ swami.desktop \ swami.png \ swami.svg \ swami.xml desktopdir = $(datadir)/applications desktop_DATA = swami.desktop mimexmldir = $(datadir)/mime/packages mimexml_DATA = swami.xml appicondir = $(datadir)/icons/hicolor/48x48/apps appicon_DATA = swami.png appsvgdir = $(datadir)/icons/hicolor/scalable/apps appsvg_DATA = swami.svg DISTCLEANFILES = \ intltool-extract.in \ intltool-merge.in \ intltool-update.in rpms: dist cd package && ./rpmpkg.sh ../${PACKAGE}-${VERSION}.tar.gz DISTCHECK_CONFIGURE_FLAGS=--enable-gtk-doc gtk_update_icon_cache = gtk-update-icon-cache -f -t $(datadir)/icons/hicolor update-icon-cache: @-if test -z "$(DESTDIR)"; then \ echo "Updating Gtk icon cache."; \ $(gtk_update_icon_cache); \ else \ echo "*** Icon cache not updated. After (un)install, run this:"; \ echo "*** $(gtk_update_icon_cache)"; \ fi UPDATE_MIME = \ if [ -f $(DESTDIR)$(datadir)/mime/packages/freedesktop.org.xml ] ; then \ if which update-mime-database>/dev/null 2>&1; then \ update-mime-database $(DESTDIR)$(datadir)/mime; \ fi \ fi UPDATE_DESKTOP = \ if [ -f $(DESTDIR)$(datadir)/applications/defaults.list ] ; then \ if which update-desktop-database>/dev/null 2>&1 ; then \ update-desktop-database; \ fi \ fi install-data-hook: update-icon-cache $(UPDATE_MIME) $(UPDATE_DESKTOP) uninstall-hook: update-icon-cache $(UPDATE_MIME) $(UPDATE_DESKTOP) swami/package/0000755000175000017500000000000011716016670013456 5ustar alessioalessioswami/package/Makefile.am0000644000175000017500000000016607445534355015526 0ustar alessioalessio## Process this file with automake to produce Makefile.in EXTRA_DIST = rpmpkg.sh MAINTAINERCLEANFILES = Makefile.in swami/package/rpmpkg.sh0000755000175000017500000000236107445534355015330 0ustar alessioalessio#!/bin/sh # Package a Swami tarball into RPM packages # Careful with this script!! It needs to be run as root to build RPMs. # In particular an "rm -rf $TMPDIR" is done RPMROOT=/usr/src/RPM PKGDIR=. TMPDIR=${PKGDIR}/packtmp if test ! -e "./$0" ; then echo "Run this script from within the package directory" exit 1 fi if test -z "$1" -o ! -e "$1" ; then echo "Usage: $0 swami-x.xx.x.tar.gz" exit 1 fi if test $LOGNAME != "root" ; then echo "Should be run as root to build RPMs" exit 1 fi SWAMIDIR=`basename $1 .tar.gz` # Unset LINGUAS so all languages will be built unset LINGUAS rm -rf ${TMPDIR} && \ mkdir ${TMPDIR} && \ tar -C ${TMPDIR} -xzf $1 && \ cat ${TMPDIR}/${SWAMIDIR}/swami.spec \ | sed 's|^\./configure.*$|& --disable-alsa-support --with-audiofile'\ ' --disable-awe-caching|' \ >${TMPDIR}/swami-binary-rpm.spec && \ mv ${TMPDIR}/${SWAMIDIR}/swami.spec ${TMPDIR}/swami-binary-rpm.spec \ ${RPMROOT}/SPECS/ && \ cp $1 ${RPMROOT}/SOURCES/ && \ rpm -bs ${RPMROOT}/SPECS/swami.spec && \ rpm -bb ${RPMROOT}/SPECS/swami-binary-rpm.spec && \ find ${RPMROOT}/RPMS/ -name "swami*.rpm" -exec mv {} ${PKGDIR} ';' && \ find ${RPMROOT}/SRPMS/ -name "swami*.rpm" -exec mv {} ${PKGDIR} ';' && \ rm -rf ${TMPDIR} exit 0 swami/intltool-update.in0000644000175000017500000000000011344522607015524 0ustar alessioalessioswami/py-compile0000755000175000017500000000474507573110375014104 0ustar alessioalessio#!/bin/sh # py-compile - Compile a Python program # Copyright 2000, 2001 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program 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 General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # called as "py-compile [--basedir DIR] PY_FILES ... if [ -z "$PYTHON" ]; then PYTHON=python fi basedir= case "$1" in --basedir) basedir=$2 shift 2 ;; --help) echo "Usage: py-compile [--basedir DIR] PY_FILES ..." echo "Byte compile some python scripts. This should be performed" echo "after they have been moved to the final installation location" exit 0 ;; --version) echo "py-compile version 0.0" exit 0 ;; esac if [ $# = 0 ]; then echo "No files given to $0" 1>&2 exit 1 fi # if basedir was given, then it should be prepended to filenames before # byte compilation. if [ -z "$basedir" ]; then trans="path = file" else trans="path = os.path.join('$basedir', file)" fi $PYTHON -c " import sys, os, string, py_compile files = '''$*''' print 'Byte-compiling python modules...' for file in string.split(files): $trans if not os.path.exists(path) or not (len(path) >= 3 and path[-3:] == '.py'): continue print file, sys.stdout.flush() py_compile.compile(path) print" || exit $? # this will fail for python < 1.5, but that doesn't matter ... $PYTHON -O -c " import sys, os, string, py_compile files = '''$*''' print 'Byte-compiling python modules (optimised versions) ...' for file in string.split(files): $trans if not os.path.exists(path) or not (len(path) >= 3 and path[-3:] == '.py'): continue print file, sys.stdout.flush() py_compile.compile(path) print" 2>/dev/null || : swami/po/0000755000175000017500000000000011716016670012501 5ustar alessioalessioswami/po/remove-potcdate.sin0000644000175000017500000000066010071366012016303 0ustar alessioalessio# Sed script that remove the POT-Creation-Date line in the header entry # from a POT file. # # The distinction between the first and the following occurrences of the # pattern is achieved by looking at the hold space. /^"POT-Creation-Date: .*"$/{ x # Test if the hold space is empty. s/P/P/ ta # Yes it was empty. First occurrence. Remove the line. g d bb :a # The hold space was nonempty. Following occurrences. Do nothing. x :b } swami/po/POTFILES.in0000644000175000017500000000127611072476353014267 0ustar alessioalessio# List of source files containing translatable strings. # Each source file that has gettext translatable strings should be listed here src/libswami/SwamiObject.c src/libswami/SwamiPlugin.c src/libswami/SwamiRoot.c src/libswami/SwamiWavetbl.c src/swamigui/glade_strings.c src/swamigui/help.c src/swamigui/main.c src/swamigui/patch_funcs.c src/swamigui/SwamiguiItemMenu.c src/swamigui/SwamiguiMenu.c src/swamigui/SwamiguiModEdit.c src/swamigui/SwamiguiMultiList.c src/swamigui/SwamiguiPaste.c src/swamigui/SwamiguiPiano.c src/swamigui/SwamiguiProp.c src/swamigui/SwamiguiRoot.c src/swamigui/SwamiguiSampleCanvas.c src/swamigui/SwamiguiSampleEditor.c src/swamigui/util.c src/swamigui/widgets/icon-combo.c swami/po/insert-header.sin0000644000175000017500000000124010071366012015732 0ustar alessioalessio# Sed script that inserts the file called HEADER before the header entry. # # At each occurrence of a line starting with "msgid ", we execute the following # commands. At the first occurrence, insert the file. At the following # occurrences, do nothing. The distinction between the first and the following # occurrences is achieved by looking at the hold space. /^msgid /{ x # Test if the hold space is empty. s/m/m/ ta # Yes it was empty. First occurrence. Read the file. r HEADER # Output the file's contents by reading the next line. But don't lose the # current line while doing this. g N bb :a # The hold space was nonempty. Following occurrences. Do nothing. x :b } swami/po/Rules-quot0000644000175000017500000000323110071366012014472 0ustar alessioalessio# Special Makefile rules for English message catalogs with quotation marks. DISTFILES.common.extra1 = quot.sed boldquot.sed en@quot.header en@boldquot.header insert-header.sin Rules-quot .SUFFIXES: .insert-header .po-update-en en@quot.po-update: en@quot.po-update-en en@boldquot.po-update: en@boldquot.po-update-en .insert-header.po-update-en: @lang=`echo $@ | sed -e 's/\.po-update-en$$//'`; \ if test "$(PACKAGE)" = "gettext"; then PATH=`pwd`/../src:$$PATH; GETTEXTLIBDIR=`cd $(top_srcdir)/src && pwd`; export GETTEXTLIBDIR; fi; \ tmpdir=`pwd`; \ echo "$$lang:"; \ ll=`echo $$lang | sed -e 's/@.*//'`; \ LC_ALL=C; export LC_ALL; \ cd $(srcdir); \ if $(MSGINIT) -i $(DOMAIN).pot --no-translator -l $$ll -o - 2>/dev/null | sed -f $$tmpdir/$$lang.insert-header | $(MSGCONV) -t UTF-8 | $(MSGFILTER) sed -f `echo $$lang | sed -e 's/.*@//'`.sed 2>/dev/null > $$tmpdir/$$lang.new.po; then \ if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ rm -f $$tmpdir/$$lang.new.po; \ else \ if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ :; \ else \ echo "creation of $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ exit 1; \ fi; \ fi; \ else \ echo "creation of $$lang.po failed!" 1>&2; \ rm -f $$tmpdir/$$lang.new.po; \ fi en@quot.insert-header: insert-header.sin sed -e '/^#/d' -e 's/HEADER/en@quot.header/g' $(srcdir)/insert-header.sin > en@quot.insert-header en@boldquot.insert-header: insert-header.sin sed -e '/^#/d' -e 's/HEADER/en@boldquot.header/g' $(srcdir)/insert-header.sin > en@boldquot.insert-header mostlyclean: mostlyclean-quot mostlyclean-quot: rm -f *.insert-header swami/po/ChangeLog0000644000175000017500000000104210333101113014225 0ustar alessioalessio2005-10-15 gettextize * Makefile.in.in: Upgrade to gettext-0.12.1. 2003-06-24 gettextize * Makefile.in.in: Upgrade to gettext-0.11.5. * boldquot.sed: New file, from gettext-0.11.5. * en@boldquot.header: New file, from gettext-0.11.5. * en@quot.header: New file, from gettext-0.11.5. * insert-header.sin: New file, from gettext-0.11.5. * quot.sed: New file, from gettext-0.11.5. * remove-potcdate.sin: New file, from gettext-0.11.5. * Rules-quot: New file, from gettext-0.11.5. swami/po/Makefile.in.in0000644000175000017500000001537711344522607015167 0ustar alessioalessio# Makefile for program source directory in GNU NLS utilities package. # Copyright (C) 1995, 1996, 1997 by Ulrich Drepper # Copyright (C) 2004-2008 Rodney Dawes # # This file may be copied and used freely without restrictions. It may # be used in projects which are not available under a GNU Public License, # but which still want to provide support for the GNU gettext functionality. # # - Modified by Owen Taylor to use GETTEXT_PACKAGE # instead of PACKAGE and to look for po2tbl in ./ not in intl/ # # - Modified by jacob berkman to install # Makefile.in.in and po2tbl.sed.in for use with glib-gettextize # # - Modified by Rodney Dawes for use with intltool # # We have the following line for use by intltoolize: # INTLTOOL_MAKEFILE GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ PACKAGE = @PACKAGE@ VERSION = @VERSION@ SHELL = @SHELL@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ top_builddir = @top_builddir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ datadir = @datadir@ datarootdir = @datarootdir@ libdir = @libdir@ DATADIRNAME = @DATADIRNAME@ itlocaledir = $(prefix)/$(DATADIRNAME)/locale subdir = po install_sh = @install_sh@ # Automake >= 1.8 provides @mkdir_p@. # Until it can be supposed, use the safe fallback: mkdir_p = $(install_sh) -d INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ GMSGFMT = @GMSGFMT@ MSGFMT = @MSGFMT@ XGETTEXT = @XGETTEXT@ INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ MSGMERGE = INTLTOOL_EXTRACT=$(INTLTOOL_EXTRACT) srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --dist GENPOT = INTLTOOL_EXTRACT=$(INTLTOOL_EXTRACT) srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --pot ALL_LINGUAS = @ALL_LINGUAS@ PO_LINGUAS=$(shell if test -r $(srcdir)/LINGUAS; then grep -v "^\#" $(srcdir)/LINGUAS; else echo "$(ALL_LINGUAS)"; fi) USER_LINGUAS=$(shell if test -n "$(LINGUAS)"; then LLINGUAS="$(LINGUAS)"; ALINGUAS="$(ALL_LINGUAS)"; for lang in $$LLINGUAS; do if test -n "`grep \^$$lang$$ $(srcdir)/LINGUAS 2>/dev/null`" -o -n "`echo $$ALINGUAS|tr ' ' '\n'|grep \^$$lang$$`"; then printf "$$lang "; fi; done; fi) USE_LINGUAS=$(shell if test -n "$(USER_LINGUAS)" -o -n "$(LINGUAS)"; then LLINGUAS="$(USER_LINGUAS)"; else if test -n "$(PO_LINGUAS)"; then LLINGUAS="$(PO_LINGUAS)"; else LLINGUAS="$(ALL_LINGUAS)"; fi; fi; for lang in $$LLINGUAS; do printf "$$lang "; done) POFILES=$(shell LINGUAS="$(PO_LINGUAS)"; for lang in $$LINGUAS; do printf "$$lang.po "; done) DISTFILES = Makefile.in.in POTFILES.in $(POFILES) EXTRA_DISTFILES = ChangeLog POTFILES.skip Makevars LINGUAS POTFILES = \ # This comment gets stripped out CATALOGS=$(shell LINGUAS="$(USE_LINGUAS)"; for lang in $$LINGUAS; do printf "$$lang.gmo "; done) .SUFFIXES: .SUFFIXES: .po .pox .gmo .mo .msg .cat .po.pox: $(MAKE) $(GETTEXT_PACKAGE).pot $(MSGMERGE) $< $(GETTEXT_PACKAGE).pot -o $*.pox .po.mo: $(MSGFMT) -o $@ $< .po.gmo: file=`echo $* | sed 's,.*/,,'`.gmo \ && rm -f $$file && $(GMSGFMT) -o $$file $< .po.cat: sed -f ../intl/po2msg.sed < $< > $*.msg \ && rm -f $@ && gencat $@ $*.msg all: all-@USE_NLS@ all-yes: $(CATALOGS) all-no: $(GETTEXT_PACKAGE).pot: $(POTFILES) $(GENPOT) install: install-data install-data: install-data-@USE_NLS@ install-data-no: all install-data-yes: all linguas="$(USE_LINGUAS)"; \ for lang in $$linguas; do \ dir=$(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES; \ $(mkdir_p) $$dir; \ if test -r $$lang.gmo; then \ $(INSTALL_DATA) $$lang.gmo $$dir/$(GETTEXT_PACKAGE).mo; \ echo "installing $$lang.gmo as $$dir/$(GETTEXT_PACKAGE).mo"; \ else \ $(INSTALL_DATA) $(srcdir)/$$lang.gmo $$dir/$(GETTEXT_PACKAGE).mo; \ echo "installing $(srcdir)/$$lang.gmo as" \ "$$dir/$(GETTEXT_PACKAGE).mo"; \ fi; \ if test -r $$lang.gmo.m; then \ $(INSTALL_DATA) $$lang.gmo.m $$dir/$(GETTEXT_PACKAGE).mo.m; \ echo "installing $$lang.gmo.m as $$dir/$(GETTEXT_PACKAGE).mo.m"; \ else \ if test -r $(srcdir)/$$lang.gmo.m ; then \ $(INSTALL_DATA) $(srcdir)/$$lang.gmo.m \ $$dir/$(GETTEXT_PACKAGE).mo.m; \ echo "installing $(srcdir)/$$lang.gmo.m as" \ "$$dir/$(GETTEXT_PACKAGE).mo.m"; \ else \ true; \ fi; \ fi; \ done # Empty stubs to satisfy archaic automake needs dvi info ctags tags CTAGS TAGS ID: # Define this as empty until I found a useful application. install-exec installcheck: uninstall: linguas="$(USE_LINGUAS)"; \ for lang in $$linguas; do \ rm -f $(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE).mo; \ rm -f $(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE).mo.m; \ done check: all $(GETTEXT_PACKAGE).pot rm -f missing notexist srcdir=$(srcdir) $(INTLTOOL_UPDATE) -m if [ -r missing -o -r notexist ]; then \ exit 1; \ fi mostlyclean: rm -f *.pox $(GETTEXT_PACKAGE).pot *.old.po cat-id-tbl.tmp rm -f .intltool-merge-cache clean: mostlyclean distclean: clean rm -f Makefile Makefile.in POTFILES stamp-it rm -f *.mo *.msg *.cat *.cat.m *.gmo maintainer-clean: distclean @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." rm -f Makefile.in.in distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) dist distdir: $(DISTFILES) dists="$(DISTFILES)"; \ extra_dists="$(EXTRA_DISTFILES)"; \ for file in $$extra_dists; do \ test -f $(srcdir)/$$file && dists="$$dists $(srcdir)/$$file"; \ done; \ for file in $$dists; do \ test -f $$file || file="$(srcdir)/$$file"; \ ln $$file $(distdir) 2> /dev/null \ || cp -p $$file $(distdir); \ done update-po: Makefile $(MAKE) $(GETTEXT_PACKAGE).pot tmpdir=`pwd`; \ linguas="$(USE_LINGUAS)"; \ for lang in $$linguas; do \ echo "$$lang:"; \ result="`$(MSGMERGE) -o $$tmpdir/$$lang.new.po $$lang`"; \ if $$result; then \ if cmp $(srcdir)/$$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ rm -f $$tmpdir/$$lang.new.po; \ else \ if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ :; \ else \ echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ rm -f $$tmpdir/$$lang.new.po; \ exit 1; \ fi; \ fi; \ else \ echo "msgmerge for $$lang.gmo failed!"; \ rm -f $$tmpdir/$$lang.new.po; \ fi; \ done Makefile POTFILES: stamp-it @if test ! -f $@; then \ rm -f stamp-it; \ $(MAKE) stamp-it; \ fi stamp-it: Makefile.in.in $(top_builddir)/config.status POTFILES.in cd $(top_builddir) \ && CONFIG_FILES=$(subdir)/Makefile.in CONFIG_HEADERS= CONFIG_LINKS= \ $(SHELL) ./config.status # Tell versions [3.59,3.63) of GNU make not to export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: swami/po/boldquot.sed0000644000175000017500000000033110071366012015013 0ustar alessioalessios/"\([^"]*\)"/“\1â€/g s/`\([^`']*\)'/‘\1’/g s/ '\([^`']*\)' / ‘\1’ /g s/ '\([^`']*\)'$/ ‘\1’/g s/^'\([^`']*\)' /‘\1’ /g s/“â€/""/g s/“/“/g s/â€/â€/g s/‘/‘/g s/’/’/g swami/po/en@quot.header0000644000175000017500000000226310071366012015260 0ustar alessioalessio# All this catalog "translates" are quotation characters. # The msgids must be ASCII and therefore cannot contain real quotation # characters, only substitutes like grave accent (0x60), apostrophe (0x27) # and double quote (0x22). These substitutes look strange; see # http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html # # This catalog translates grave accent (0x60) and apostrophe (0x27) to # left single quotation mark (U+2018) and right single quotation mark (U+2019). # It also translates pairs of apostrophe (0x27) to # left single quotation mark (U+2018) and right single quotation mark (U+2019) # and pairs of quotation mark (0x22) to # left double quotation mark (U+201C) and right double quotation mark (U+201D). # # When output to an UTF-8 terminal, the quotation characters appear perfectly. # When output to an ISO-8859-1 terminal, the single quotation marks are # transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to # grave/acute accent (by libiconv), and the double quotation marks are # transliterated to 0x22. # When output to an ASCII terminal, the single quotation marks are # transliterated to apostrophes, and the double quotation marks are # transliterated to 0x22. # swami/po/Makevars0000644000175000017500000000350310072577776014213 0ustar alessioalessio# Makefile variables for PO directory in any package using GNU gettext. # Usually the message domain is the same as the package name. DOMAIN = $(PACKAGE) # These two variables depend on the location of this directory. subdir = po top_builddir = .. # These options get passed to xgettext. XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ # This is the copyright holder that gets inserted into the header of the # $(DOMAIN).pot file. Set this to the copyright holder of the surrounding # package. (Note that the msgstr strings, extracted from the package's # sources, belong to the copyright holder of the package.) Translators are # expected to transfer the copyright for their translations to this person # or entity, or to disclaim their copyright. The empty string stands for # the public domain; in this case the translators are expected to disclaim # their copyright. COPYRIGHT_HOLDER = Josh Green # This is the email address or URL to which the translators shall report # bugs in the untranslated strings: # - Strings which are not entire sentences, see the maintainer guidelines # in the GNU gettext documentation, section 'Preparing Strings'. # - Strings which use unclear terms or require additional context to be # understood. # - Strings which make invalid assumptions about notation of date, time or # money. # - Pluralisation problems. # - Incorrect English spelling. # - Incorrect formatting. # It can be your email address, or a mailing list address where translators # can write to without being subscribed, or the URL of a web page through # which the translators can contact you. MSGID_BUGS_ADDRESS = Josh Green # This is the list of locale categories, beyond LC_MESSAGES, for which the # message catalogs shall be used. It is usually empty. EXTRA_LOCALE_CATEGORIES = swami/po/en@boldquot.header0000644000175000017500000000247110071366012016122 0ustar alessioalessio# All this catalog "translates" are quotation characters. # The msgids must be ASCII and therefore cannot contain real quotation # characters, only substitutes like grave accent (0x60), apostrophe (0x27) # and double quote (0x22). These substitutes look strange; see # http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html # # This catalog translates grave accent (0x60) and apostrophe (0x27) to # left single quotation mark (U+2018) and right single quotation mark (U+2019). # It also translates pairs of apostrophe (0x27) to # left single quotation mark (U+2018) and right single quotation mark (U+2019) # and pairs of quotation mark (0x22) to # left double quotation mark (U+201C) and right double quotation mark (U+201D). # # When output to an UTF-8 terminal, the quotation characters appear perfectly. # When output to an ISO-8859-1 terminal, the single quotation marks are # transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to # grave/acute accent (by libiconv), and the double quotation marks are # transliterated to 0x22. # When output to an ASCII terminal, the single quotation marks are # transliterated to apostrophes, and the double quotation marks are # transliterated to 0x22. # # This catalog furthermore displays the text between the quotation marks in # bold face, assuming the VT100/XTerm escape sequences. # swami/po/quot.sed0000644000175000017500000000023110071366012014151 0ustar alessioalessios/"\([^"]*\)"/“\1â€/g s/`\([^`']*\)'/‘\1’/g s/ '\([^`']*\)' / ‘\1’ /g s/ '\([^`']*\)'$/ ‘\1’/g s/^'\([^`']*\)' /‘\1’ /g s/“â€/""/g swami/NEWS0000644000175000017500000000153107477605651012576 0ustar alessioalessio+-------------------------------------------------------+ + Smurf Sound Font Editor - News + + Copyright (C) 1999-2002 Josh Green + + Email: jgreen@users.sourceforge.net + + Smurf homepage: http://smurf.sourceforge.net + +-------------------------------------------------------+ Jun 5th 2002 - Swami v0.9.0pre1 released (yee ha!) --- Smurf Sound Font Editor (RIP) --- Sep 6th 2001 - Smurf v0.52.5 released May 5th 2001 - Smurf v0.52.1 released May 2nd 2001 - Smurf v0.52 released Jan 31st 2001 - Smurf v0.50.1 released Jan 1st 2001 - Smurf v0.50.0 released Sep 12th 2000 - Smurf v0.49.8 released Jul 5th 2000 - Smurf v0.49.5 released Mar 25th 2000 - Smurf v0.49.1 released Mar 20th 2000 - Smurf v0.49 released Dec 6th 1999 - Smurf v0.46 released Nov 8th 1999 - Smurf v0.45 released Sep 12th 1999 - Smurf v0.40 released, first public release! swami/ABOUT-NLS0000644000175000017500000011311310333101113013267 0ustar alessioalessioNotes on the Free Translation Project ************************************* Free software is going international! The Free Translation Project is a way to get maintainers of free software, translators, and users all together, so that will gradually become able to speak many languages. A few packages already provide translations for their messages. If you found this `ABOUT-NLS' file inside a distribution, you may assume that the distributed package does use GNU `gettext' internally, itself available at your nearest GNU archive site. But you do _not_ need to install GNU `gettext' prior to configuring, installing or using this package with messages translated. Installers will find here some useful hints. These notes also explain how users should proceed for getting the programs to use the available translations. They tell how people wanting to contribute and work at translations should contact the appropriate team. When reporting bugs in the `intl/' directory or bugs which may be related to internationalization, you should tell about the version of `gettext' which is used. The information can be found in the `intl/VERSION' file, in internationalized packages. Quick configuration advice ========================== If you want to exploit the full power of internationalization, you should configure it using ./configure --with-included-gettext to force usage of internationalizing routines provided within this package, despite the existence of internationalizing capabilities in the operating system where this package is being installed. So far, only the `gettext' implementation in the GNU C library version 2 provides as many features (such as locale alias, message inheritance, automatic charset conversion or plural form handling) as the implementation here. It is also not possible to offer this additional functionality on top of a `catgets' implementation. Future versions of GNU `gettext' will very likely convey even more functionality. So it might be a good idea to change to GNU `gettext' as soon as possible. So you need _not_ provide this option if you are using GNU libc 2 or you have installed a recent copy of the GNU gettext package with the included `libintl'. INSTALL Matters =============== Some packages are "localizable" when properly installed; the programs they contain can be made to speak your own native language. Most such packages use GNU `gettext'. Other packages have their own ways to internationalization, predating GNU `gettext'. By default, this package will be installed to allow translation of messages. It will automatically detect whether the system already provides the GNU `gettext' functions. If not, the GNU `gettext' own library will be used. This library is wholly contained within this package, usually in the `intl/' subdirectory, so prior installation of the GNU `gettext' package is _not_ required. Installers may use special options at configuration time for changing the default behaviour. The commands: ./configure --with-included-gettext ./configure --disable-nls will respectively bypass any pre-existing `gettext' to use the internationalizing routines provided within this package, or else, _totally_ disable translation of messages. When you already have GNU `gettext' installed on your system and run configure without an option for your new package, `configure' will probably detect the previously built and installed `libintl.a' file and will decide to use this. This might be not what is desirable. You should use the more recent version of the GNU `gettext' library. I.e. if the file `intl/VERSION' shows that the library which comes with this package is more recent, you should use ./configure --with-included-gettext to prevent auto-detection. The configuration process will not test for the `catgets' function and therefore it will not be used. The reason is that even an emulation of `gettext' on top of `catgets' could not provide all the extensions of the GNU `gettext' library. Internationalized packages have usually many `po/LL.po' files, where LL gives an ISO 639 two-letter code identifying the language. Unless translations have been forbidden at `configure' time by using the `--disable-nls' switch, all available translations are installed together with the package. However, the environment variable `LINGUAS' may be set, prior to configuration, to limit the installed set. `LINGUAS' should then contain a space separated list of two-letter codes, stating which languages are allowed. Using This Package ================== As a user, if your language has been installed for this package, you only have to set the `LANG' environment variable to the appropriate `LL_CC' combination. Here `LL' is an ISO 639 two-letter language code, and `CC' is an ISO 3166 two-letter country code. For example, let's suppose that you speak German and live in Germany. At the shell prompt, merely execute `setenv LANG de_DE' (in `csh'), `export LANG; LANG=de_DE' (in `sh') or `export LANG=de_DE' (in `bash'). This can be done from your `.login' or `.profile' file, once and for all. You might think that the country code specification is redundant. But in fact, some languages have dialects in different countries. For example, `de_AT' is used for Austria, and `pt_BR' for Brazil. The country code serves to distinguish the dialects. The locale naming convention of `LL_CC', with `LL' denoting the language and `CC' denoting the country, is the one use on systems based on GNU libc. On other systems, some variations of this scheme are used, such as `LL' or `LL_CC.ENCODING'. You can get the list of locales supported by your system for your country by running the command `locale -a | grep '^LL''. Not all programs have translations for all languages. By default, an English message is shown in place of a nonexistent translation. If you understand other languages, you can set up a priority list of languages. This is done through a different environment variable, called `LANGUAGE'. GNU `gettext' gives preference to `LANGUAGE' over `LANG' for the purpose of message handling, but you still need to have `LANG' set to the primary language; this is required by other parts of the system libraries. For example, some Swedish users who would rather read translations in German than English for when Swedish is not available, set `LANGUAGE' to `sv:de' while leaving `LANG' to `sv_SE'. In the `LANGUAGE' environment variable, but not in the `LANG' environment variable, `LL_CC' combinations can be abbreviated as `LL' to denote the language's main dialect. For example, `de' is equivalent to `de_DE' (German as spoken in Germany), and `pt' to `pt_PT' (Portuguese as spoken in Portugal) in this context. Translating Teams ================= For the Free Translation Project to be a success, we need interested people who like their own language and write it well, and who are also able to synergize with other translators speaking the same language. Each translation team has its own mailing list. The up-to-date list of teams can be found at the Free Translation Project's homepage, `http://www.iro.umontreal.ca/contrib/po/HTML/', in the "National teams" area. If you'd like to volunteer to _work_ at translating messages, you should become a member of the translating team for your own language. The subscribing address is _not_ the same as the list itself, it has `-request' appended. For example, speakers of Swedish can send a message to `sv-request@li.org', having this message body: subscribe Keep in mind that team members are expected to participate _actively_ in translations, or at solving translational difficulties, rather than merely lurking around. If your team does not exist yet and you want to start one, or if you are unsure about what to do or how to get started, please write to `translation@iro.umontreal.ca' to reach the coordinator for all translator teams. The English team is special. It works at improving and uniformizing the terminology in use. Proven linguistic skill are praised more than programming skill, here. Available Packages ================== Languages are not equally supported in all packages. The following matrix shows the current state of internationalization, as of May 2003. The matrix shows, in regard of each package, for which languages PO files have been submitted to translation coordination, with a translation percentage of at least 50%. Ready PO files am az be bg ca cs da de el en en_GB eo es +-------------------------------------------+ a2ps | [] [] [] [] | aegis | () | anubis | | ap-utils | | bash | [] [] [] | batchelor | | bfd | [] [] | binutils | [] [] | bison | [] [] [] | bluez-pin | [] [] | clisp | | clisp | [] [] [] | coreutils | [] [] [] [] | cpio | [] [] [] | darkstat | () [] | diffutils | [] [] [] [] [] [] [] | e2fsprogs | [] [] | enscript | [] [] [] [] | error | [] [] [] [] [] | fetchmail | [] () [] [] [] [] | fileutils | [] [] [] | findutils | [] [] [] [] [] [] | flex | [] [] [] [] | gas | [] | gawk | [] [] [] [] | gcal | [] | gcc | [] [] | gettext | [] [] [] [] [] | gettext-runtime | [] [] [] [] [] | gettext-tools | [] [] | gimp-print | [] [] [] [] [] | gliv | | glunarclock | [] [] [] | gnucash | () [] | gnucash-glossary | [] () [] | gnupg | [] () [] [] [] [] | gpe-calendar | [] | gpe-conf | [] | gpe-contacts | [] | gpe-edit | | gpe-login | [] | gpe-ownerinfo | [] | gpe-sketchbook | [] | gpe-timesheet | | gpe-today | [] | gpe-todo | [] | gphoto2 | [] [] [] [] | gprof | [] [] | gpsdrive | () () () | grep | [] [] [] [] [] | gretl | [] | hello | [] [] [] [] [] [] | id-utils | [] [] | indent | [] [] [] [] | jpilot | [] [] [] [] | jwhois | [] | kbd | [] [] [] [] [] | ld | [] [] | libc | [] [] [] [] [] [] | libgpewidget | [] | libiconv | [] [] [] [] [] | lifelines | [] () | lilypond | [] | lingoteach | | lingoteach_lessons | () () | lynx | [] [] [] [] | m4 | [] [] [] [] | mailutils | [] [] | make | [] [] [] | man-db | [] () [] [] () | mysecretdiary | [] [] [] | nano | [] () [] [] [] | nano_1_0 | [] () [] [] [] | opcodes | [] [] | parted | [] [] [] [] [] | ptx | [] [] [] [] [] | python | | radius | | recode | [] [] [] [] [] [] | screem | | sed | [] [] [] [] [] | sh-utils | [] [] [] | sharutils | [] [] [] [] [] [] | sketch | [] () [] | soundtracker | [] [] [] | sp | [] | tar | [] [] [] [] | texinfo | [] [] [] [] | textutils | [] [] [] [] | tin | () () | util-linux | [] [] [] [] [] | vorbis-tools | [] [] [] | wastesedge | () | wdiff | [] [] [] [] | wget | [] [] [] [] [] [] [] | xchat | [] [] [] | xpad | | +-------------------------------------------+ am az be bg ca cs da de el en en_GB eo es 0 1 4 2 31 17 54 60 14 1 4 12 56 et fa fi fr ga gl he hr hu id it ja ko +----------------------------------------+ a2ps | [] [] [] () () | aegis | | anubis | [] | ap-utils | [] | bash | [] [] | batchelor | [] | bfd | [] [] | binutils | [] [] | bison | [] [] [] [] | bluez-pin | [] [] [] [] | clisp | | clisp | [] | coreutils | [] [] [] [] | cpio | [] [] [] [] | darkstat | () [] [] [] | diffutils | [] [] [] [] [] [] [] | e2fsprogs | | enscript | [] [] | error | [] [] [] [] | fetchmail | [] | fileutils | [] [] [] [] [] | findutils | [] [] [] [] [] [] [] [] [] [] [] | flex | [] [] | gas | [] | gawk | [] [] | gcal | [] | gcc | [] | gettext | [] [] [] | gettext-runtime | [] [] [] [] | gettext-tools | [] | gimp-print | [] [] | gliv | () | glunarclock | [] [] [] [] | gnucash | [] | gnucash-glossary | [] | gnupg | [] [] [] [] [] [] [] | gpe-calendar | [] | gpe-conf | | gpe-contacts | [] | gpe-edit | [] [] | gpe-login | [] | gpe-ownerinfo | [] [] [] | gpe-sketchbook | [] | gpe-timesheet | [] [] [] | gpe-today | [] [] | gpe-todo | [] [] | gphoto2 | [] [] [] | gprof | [] [] | gpsdrive | () [] () () | grep | [] [] [] [] [] [] [] [] [] [] [] | gretl | [] | hello | [] [] [] [] [] [] [] [] [] [] [] [] [] | id-utils | [] [] [] | indent | [] [] [] [] [] [] [] [] | jpilot | [] () | jwhois | [] [] [] [] | kbd | [] | ld | [] | libc | [] [] [] [] [] [] | libgpewidget | [] [] [] | libiconv | [] [] [] [] [] [] [] [] | lifelines | () | lilypond | [] | lingoteach | [] [] | lingoteach_lessons | | lynx | [] [] [] [] | m4 | [] [] [] [] | mailutils | | make | [] [] [] [] [] [] | man-db | [] () () | mysecretdiary | [] [] | nano | [] [] [] [] | nano_1_0 | [] [] [] [] | opcodes | [] [] | parted | [] [] [] | ptx | [] [] [] [] [] [] [] | python | | radius | | recode | [] [] [] [] [] [] | screem | | sed | [] [] [] [] [] [] [] [] | sh-utils | [] [] [] [] [] [] | sharutils | [] [] [] [] [] | sketch | [] | soundtracker | [] [] [] | sp | [] () | tar | [] [] [] [] [] [] [] [] [] | texinfo | [] [] [] [] | textutils | [] [] [] [] [] | tin | [] () | util-linux | [] [] [] [] () [] | vorbis-tools | [] | wastesedge | () | wdiff | [] [] [] [] [] | wget | [] [] [] [] [] [] [] [] | xchat | [] [] [] | xpad | | +----------------------------------------+ et fa fi fr ga gl he hr hu id it ja ko 20 1 15 73 14 24 8 10 30 31 19 31 9 lg lt lv ms nb nl nn no pl pt pt_BR ro +----------------------------------------+ a2ps | [] [] () () () [] [] | aegis | () | anubis | [] [] | ap-utils | () | bash | [] | batchelor | | bfd | | binutils | | bison | [] [] [] [] | bluez-pin | [] | clisp | | clisp | [] | coreutils | [] | cpio | [] [] [] | darkstat | [] [] [] [] | diffutils | [] [] [] | e2fsprogs | | enscript | [] [] | error | [] [] | fetchmail | () () | fileutils | [] | findutils | [] [] [] [] | flex | [] | gas | | gawk | [] | gcal | | gcc | | gettext | [] | gettext-runtime | [] | gettext-tools | | gimp-print | [] | gliv | [] | glunarclock | [] | gnucash | | gnucash-glossary | [] [] | gnupg | | gpe-calendar | [] [] | gpe-conf | [] [] | gpe-contacts | [] | gpe-edit | [] [] | gpe-login | [] [] | gpe-ownerinfo | [] [] | gpe-sketchbook | [] [] | gpe-timesheet | [] [] | gpe-today | [] [] | gpe-todo | [] [] | gphoto2 | | gprof | [] | gpsdrive | () () () | grep | [] [] [] [] | gretl | | hello | [] [] [] [] [] [] [] [] [] | id-utils | [] [] [] | indent | [] [] [] | jpilot | () () | jwhois | [] [] [] | kbd | | ld | | libc | [] [] [] [] | libgpewidget | [] [] | libiconv | [] [] | lifelines | | lilypond | [] | lingoteach | | lingoteach_lessons | | lynx | [] [] | m4 | [] [] [] [] | mailutils | | make | [] [] | man-db | [] | mysecretdiary | [] | nano | [] [] [] [] | nano_1_0 | [] [] [] [] | opcodes | [] [] [] | parted | [] [] [] | ptx | [] [] [] [] [] [] [] | python | | radius | | recode | [] [] [] | screem | | sed | [] [] | sh-utils | [] | sharutils | [] | sketch | [] | soundtracker | | sp | | tar | [] [] [] [] [] [] | texinfo | [] | textutils | [] | tin | | util-linux | [] [] | vorbis-tools | [] [] | wastesedge | | wdiff | [] [] [] [] | wget | [] [] [] | xchat | [] [] | xpad | [] | +----------------------------------------+ lg lt lv ms nb nl nn no pl pt pt_BR ro 0 0 2 11 7 26 3 4 18 15 34 34 ru sk sl sr sv ta tr uk vi wa zh_CN zh_TW +-------------------------------------------+ a2ps | [] [] [] [] [] | 16 aegis | () | 0 anubis | [] [] | 5 ap-utils | () | 1 bash | [] | 7 batchelor | | 1 bfd | [] [] [] | 7 binutils | [] [] [] | 7 bison | [] [] | 13 bluez-pin | | 7 clisp | | 0 clisp | | 5 coreutils | [] [] [] [] [] | 14 cpio | [] [] [] | 13 darkstat | [] () () | 9 diffutils | [] [] [] [] | 21 e2fsprogs | [] | 3 enscript | [] [] [] | 11 error | [] [] [] | 14 fetchmail | [] | 7 fileutils | [] [] [] [] [] [] | 15 findutils | [] [] [] [] [] [] | 27 flex | [] [] [] | 10 gas | [] | 3 gawk | [] [] | 9 gcal | [] [] | 4 gcc | [] | 4 gettext | [] [] [] [] [] [] | 15 gettext-runtime | [] [] [] [] [] [] | 16 gettext-tools | [] [] | 5 gimp-print | [] [] | 10 gliv | | 1 glunarclock | [] [] [] | 11 gnucash | [] [] | 4 gnucash-glossary | [] [] [] | 8 gnupg | [] [] [] [] | 16 gpe-calendar | [] | 5 gpe-conf | | 3 gpe-contacts | [] | 4 gpe-edit | [] | 5 gpe-login | [] | 5 gpe-ownerinfo | [] | 7 gpe-sketchbook | [] | 5 gpe-timesheet | [] | 6 gpe-today | [] | 6 gpe-todo | [] | 6 gphoto2 | [] [] | 9 gprof | [] [] | 7 gpsdrive | [] [] | 3 grep | [] [] [] [] | 24 gretl | | 2 hello | [] [] [] [] [] | 33 id-utils | [] [] [] | 11 indent | [] [] [] [] | 19 jpilot | [] [] [] [] [] | 10 jwhois | () () [] [] | 10 kbd | [] [] | 8 ld | [] [] | 5 libc | [] [] [] [] | 20 libgpewidget | | 6 libiconv | [] [] [] [] [] [] | 21 lifelines | [] | 2 lilypond | [] | 4 lingoteach | | 2 lingoteach_lessons | () | 0 lynx | [] [] [] [] | 14 m4 | [] [] [] | 15 mailutils | | 2 make | [] [] [] [] | 15 man-db | [] | 6 mysecretdiary | [] [] | 8 nano | [] [] [] | 15 nano_1_0 | [] [] [] | 15 opcodes | [] [] | 9 parted | [] [] | 13 ptx | [] [] [] | 22 python | | 0 radius | | 0 recode | [] [] [] [] | 19 screem | [] | 1 sed | [] [] [] [] [] | 20 sh-utils | [] [] [] | 13 sharutils | [] [] [] [] | 16 sketch | [] | 5 soundtracker | [] | 7 sp | [] | 3 tar | [] [] [] [] [] | 24 texinfo | [] [] [] [] | 13 textutils | [] [] [] [] [] | 15 tin | | 1 util-linux | [] [] | 14 vorbis-tools | [] | 7 wastesedge | | 0 wdiff | [] [] [] [] | 17 wget | [] [] [] [] [] [] [] | 25 xchat | [] [] [] | 11 xpad | | 1 +-------------------------------------------+ 50 teams ru sk sl sr sv ta tr uk vi wa zh_CN zh_TW 97 domains 32 19 16 0 56 0 48 10 1 1 12 23 913 Some counters in the preceding matrix are higher than the number of visible blocks let us expect. This is because a few extra PO files are used for implementing regional variants of languages, or language dialects. For a PO file in the matrix above to be effective, the package to which it applies should also have been internationalized and distributed as such by its maintainer. There might be an observable lag between the mere existence a PO file and its wide availability in a distribution. If May 2003 seems to be old, you may fetch a more recent copy of this `ABOUT-NLS' file on most GNU archive sites. The most up-to-date matrix with full percentage details can be found at `http://www.iro.umontreal.ca/contrib/po/HTML/matrix.html'. Using `gettext' in new packages =============================== If you are writing a freely available program and want to internationalize it you are welcome to use GNU `gettext' in your package. Of course you have to respect the GNU Library General Public License which covers the use of the GNU `gettext' library. This means in particular that even non-free programs can use `libintl' as a shared library, whereas only free software can use `libintl' as a static library or use modified versions of `libintl'. Once the sources are changed appropriately and the setup can handle the use of `gettext' the only thing missing are the translations. The Free Translation Project is also available for packages which are not developed inside the GNU project. Therefore the information given above applies also for every other Free Software Project. Contact `translation@iro.umontreal.ca' to make the `.pot' files available to the translation teams. swami/swami.svg0000644000175000017500000003772111461404311013724 0ustar alessioalessio image/svg+xml swami/CMakeLists.txt0000644000175000017500000002065111704446464014634 0ustar alessioalessio# # Swami # Copyright (C) 1999-2010 Joshua "Element" Green # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; version 2 # of the License only. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA or point your web browser to http://www.gnu.org. # project ( Swami C ) cmake_minimum_required ( VERSION 2.6.3 ) set ( CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake ) # Swami package name set ( PACKAGE "swami" ) # Swami package version set ( SWAMI_VERSION_MAJOR 2 ) set ( SWAMI_VERSION_MINOR 0 ) set ( SWAMI_VERSION_MICRO 0 ) set ( VERSION "${SWAMI_VERSION_MAJOR}.${SWAMI_VERSION_MINOR}.${SWAMI_VERSION_MICRO}" ) set ( SWAMI_VERSION "\"${VERSION}\"" ) # libswami/libswamigui - Library versions # *** NOTICE *** # Update library version upon each release (follow these steps in order) # if any source code changes: REVISION++ # if any interfaces added/removed/changed: REVISION=0 # if any interfaces removed/changed (compatibility broken): CURRENT++ # if any interfaces have been added: AGE++ # if any interfaces have been removed/changed (compatibility broken): AGE=0 # This is not exactly the same algorithm as the libtool one, but the results are the same. set ( LIB_VERSION_CURRENT 0 ) set ( LIB_VERSION_AGE 0 ) set ( LIB_VERSION_REVISION 0 ) set ( LIB_VERSION_INFO "${LIB_VERSION_CURRENT}.${LIB_VERSION_AGE}.${LIB_VERSION_REVISION}" ) # Options disabled by default option ( enable-debug "enable debugging (default=no)" off ) option ( enable-source-build "enable source build - load resources from source dir (default=no)" off ) # Options enabled by default option ( BUILD_SHARED_LIBS "Build a shared object or DLL (default=yes)" on ) option ( enable-fluidsynth "enable FluidSynth plugin - needed for sound (if it is available)" on ) option ( enable-fftw "enable fftw support for the FFTune plugin (if it is available)" on ) # Initialize the library directory name suffix. if ( CMAKE_SIZEOF_VOID_P EQUAL 8 ) set ( _init_lib_suffix "64" ) else ( CMAKE_SIZEOF_VOID_P EQUAL 8 ) set ( _init_lib_suffix "" ) endif ( CMAKE_SIZEOF_VOID_P EQUAL 8 ) set ( LIB_SUFFIX ${_init_lib_suffix} CACHE STRING "library directory name suffix (32/64/nothing)" ) mark_as_advanced ( LIB_SUFFIX ) # Default install directory names include ( DefaultDirs ) # Basic C library checks include ( CheckSTDC ) include ( CheckIncludeFile ) check_include_file ( string.h HAVE_STRING_H ) check_include_file ( stdlib.h HAVE_STDLIB_H ) check_include_file ( stdio.h HAVE_STDIO_H ) check_include_file ( math.h HAVE_MATH_H ) check_include_file ( errno.h HAVE_ERRNO_H ) check_include_file ( stdarg.h HAVE_STDARG_H ) check_include_file ( unistd.h HAVE_UNISTD_H ) unset ( SWAMI_LIBS CACHE ) # Options for the GNU C compiler only if ( CMAKE_COMPILER_IS_GNUCC ) if ( NOT APPLE ) set ( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed" ) set ( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined" ) endif ( NOT APPLE ) set ( GNUCC_WARNING_FLAGS "-Wall") set ( CMAKE_C_FLAGS_DEBUG "-g -DDEBUG ${GNUCC_WARNING_FLAGS}" ) set ( CMAKE_C_FLAGS_RELEASE "-O2 -DNDEBUG ${GNUCC_WARNING_FLAGS}" ) set ( CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g -DNDEBUG ${GNUCC_WARNING_FLAGS}" ) endif ( CMAKE_COMPILER_IS_GNUCC ) if ( enable-debug ) set ( CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the build type, options: Debug Release RelWithDebInfo" FORCE ) else ( enable-debug ) set ( CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the build type, options: Debug Release RelWithDebInfo" FORCE ) endif ( enable-debug ) unset ( MINGW32 CACHE ) if ( WIN32 ) # MinGW compiler (a Windows GCC port) if ( MINGW ) set ( MINGW32 1 ) add_definitions ( -mms-bitfields ) endif ( MINGW ) else ( WIN32 ) set ( SWAMI_LIBS "m" ) endif ( WIN32 ) unset ( DEBUG CACHE ) if ( CMAKE_BUILD_TYPE MATCHES "Debug" ) set ( DEBUG 1 ) endif ( CMAKE_BUILD_TYPE MATCHES "Debug" ) unset ( SOURCE_BUILD CACHE ) unset ( SOURCE_DIR CACHE ) if ( enable-source-build ) set ( SOURCE_BUILD 1 ) set ( SOURCE_DIR ${CMAKE_SOURCE_DIR} ) set ( PLUGINS_DIR ${CMAKE_BINARY_DIR}/src/plugins ) endif ( enable-source-build ) # Mandatory tool: pkg-config find_package ( PkgConfig REQUIRED ) # Mandatory library libinstpatch pkg_check_modules ( LIBINSTPATCH REQUIRED libinstpatch-1.0>=1.0 ) # Mandatory libraries: GTK+, librsvg and libgnomecanvas pkg_check_modules ( GUI REQUIRED gtk+-2.0>=2.12 librsvg-2.0>=2.8 libgnomecanvas-2.0>=2.0 ) # Mandatory libraries: gobject, glib, gmodule and gthread pkg_check_modules ( GOBJECT REQUIRED gobject-2.0>=2.12 glib-2.0>=2.12 gmodule-2.0>=2.12 gthread-2.0>=2.12 ) # Mandatory library libglade pkg_check_modules ( LIBGLADE REQUIRED libglade-2.0 ) include ( UnsetPkgConfig ) # Optional library FluidSynth unset ( FLUIDSYNTH_SUPPORT CACHE ) if ( enable-fluidsynth ) pkg_check_modules ( FLUIDSYNTH fluidsynth>=1.0 ) set ( FLUIDSYNTH_SUPPORT ${FLUIDSYNTH_FOUND} ) else ( enable-fluidsynth ) unset_pkg_config ( FLUIDSYNTH ) endif ( enable-fluidsynth ) # Optional library fftw3 unset ( FFTW_SUPPORT CACHE ) if ( enable-fftw ) pkg_check_modules ( FFTW fftw3f>=3.0 ) set ( FFTW_SUPPORT ${FFTW_FOUND} ) else ( enable-fftw ) unset_pkg_config ( FFTW ) endif ( enable-fftw ) # General configuration file configure_file ( ${CMAKE_SOURCE_DIR}/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h ) add_definitions ( -DHAVE_CONFIG_H ) # Process subdirectories add_subdirectory ( src ) # Extra targets for Unix build environments if ( UNIX ) # uninstall custom target configure_file ( "${CMAKE_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY) add_custom_target ( uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") # Install XDG mime type, application icon and .desktop file install ( FILES swami.desktop DESTINATION ${DATA_INSTALL_DIR}/applications ) install ( FILES swami.xml DESTINATION ${DATA_INSTALL_DIR}/mime/packages ) install ( FILES swami.png DESTINATION ${DATA_INSTALL_DIR}/icons/hicolor/48x48/apps ) install ( FILES swami.svg DESTINATION ${DATA_INSTALL_DIR}/icons/hicolor/scalable/apps ) endif ( UNIX ) message( "\n**************************************************************\n" ) if ( FLUIDSYNTH_SUPPORT ) message ( "FluidSynth: yes" ) else ( FLUIDSYNTH_SUPPORT ) message ( "FluidSynth: no (there will be no sound!)" ) endif ( FLUIDSYNTH_SUPPORT ) if ( FFTW_SUPPORT ) message ( "FFTW: yes" ) else ( FFTW_SUPPORT ) message ( "FFTW: no (there will be no FFTune plugin!)" ) endif ( FFTW_SUPPORT ) if ( DEBUG ) message ( "Debug: yes" ) else ( DEBUG ) message ( "Debug: no" ) endif ( DEBUG ) if ( SOURCE_BUILD ) message ( "Source build: yes (resources loaded from source dir)" ) else ( SOURCE_BUILD ) message ( "Source build: no" ) endif ( SOURCE_BUILD ) message ( "**************************************************************\n\n" ) # CPack support set ( CPACK_PACKAGE_DESCRIPTION_SUMMARY "Swami instrument editor" ) set ( CPACK_PACKAGE_VENDOR "swami.sourceforge.net" ) set ( CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README" ) set ( CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING" ) set ( CPACK_PACKAGE_VERSION_MAJOR ${SWAMI_VERSION_MAJOR} ) set ( CPACK_PACKAGE_VERSION_MINOR ${SWAMI_VERSION_MINOR} ) set ( CPACK_PACKAGE_VERSION_PATCH ${SWAMI_VERSION_MICRO} ) # source packages set ( CPACK_SOURCE_GENERATOR TGZ;TBZ2;ZIP ) set ( CPACK_SOURCE_IGNORE_FILES "/.svn/;~$;.cproject;.project;/.settings/;${CPACK_SOURCE_IGNORE_FILES}" ) set ( CPACK_SOURCE_PACKAGE_FILE_NAME "${PACKAGE}-${VERSION}" ) set ( CPACK_SOURCE_STRIP_FILES OFF ) # binary packages include ( InstallRequiredSystemLibraries ) set ( CPACK_GENERATOR STGZ;TGZ;TBZ2;ZIP ) set ( CPACK_PACKAGE_NAME ${PACKAGE} ) set ( CPACK_STRIP_FILES ON ) include ( CPack ) swami/config.guess0000755000175000017500000013226411344522607014412 0ustar alessioalessio#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 # Free Software Foundation, Inc. timestamp='2009-04-27' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner . # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit build system type. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep __ELF__ >/dev/null then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm:riscos:*:*|arm:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[456]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep __LP64__ >/dev/null then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) case ${UNAME_MACHINE} in pc98) echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:[3456]*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; EM64T | authenticamd | genuineintel) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-gnu else echo ${UNAME_MACHINE}-unknown-linux-gnueabi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) echo cris-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo crisv32-axis-linux-gnu exit ;; frv:Linux:*:*) echo frv-unknown-linux-gnu exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; mips:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips #undef mipsel #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mipsel #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips #else CPU= #endif #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^CPU/{ s: ::g p }'`" test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips64 #undef mips64el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mips64el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips64 #else CPU= #endif #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^CPU/{ s: ::g p }'`" test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) echo or32-unknown-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; padre:Linux:*:*) echo sparc-unknown-linux-gnu exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent # problems with other programs or directories called `ld' in the path. # Set LC_ALL=C to ensure ld outputs messages in English. ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ | sed -ne '/supported targets:/!d s/[ ][ ]*/ /g s/.*supported targets: *// s/ .*// p'` case "$ld_supported_targets" in elf32-i386) TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" ;; a.out-i386-linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" exit ;; "") # Either a pre-BFD a.out linker (linux-gnuoldld) or # one that does not give us useful --help. echo "${UNAME_MACHINE}-pc-linux-gnuoldld" exit ;; esac # Determine whether the default compiler is a.out or elf eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 LIBC=gnu # else LIBC=gnulibc1 # endif # else LIBC=gnulibc1 # endif #else #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) LIBC=gnu #else LIBC=gnuaout #endif #endif #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^LIBC/{ s: ::g p }'`" test x"${LIBC}" != x && { echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit } test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: swami/autogen.sh0000755000175000017500000000601311464144605014064 0ustar alessioalessio#!/bin/sh AUTOMAKE_REQ=1.7 AUTOCONF_REQ=2.54 LIBTOOL_REQ=2.2.10 PKG_CONFIG_REQ=0.1 lessthan () { ver1="$1" ver2="$2" major1=$( echo $ver1 | sed "s/^\([0-9]*\)\..*/\1/"); minor1=$( echo $ver1 | sed "s/^[^\.]*\.\([0-9]*\).*/\1/" ); major2=$( echo $ver2 | sed "s/^\([0-9]*\)\..*/\1/"); minor2=$( echo $ver2 | sed "s/^[^\.]*\.\([0-9]*\).*/\1/" ); test "$major1" -lt "$major2" || test "$minor1" -lt "$minor2"; } morethan () { ver1="$1" ver2="$2" major1=$( echo $ver1 | sed "s/^\([0-9]*\)\..*/\1/"); minor1=$( echo $ver1 | sed "s/^[^\.]*\.\([0-9]*\).*/\1/" ); major2=$( echo $ver2 | sed "s/^\([0-9]*\)\..*/\1/"); minor2=$( echo $ver2 | sed "s/^[^\.]*\.\([0-9]*\).*/\1/" ); test "$major2" -lt "$major1" || test "$minor2" -lt "$minor1"; } echo -n "automake version: " amver=$( automake --version | head -1 | sed "s/.* //" ); echo -n "$amver" lessthan $amver $AUTOMAKE_REQ if test $? = 0; then echo " (not ok)" echo " #################################################################### ######################### WARNING ################################ #################################################################### You need automake >= ${AUTOMAKE_REQ}! " sleep 1; else echo " (ok)" fi echo -n "autoconf version: " acver=$( autoconf --version | head -1 | sed "s/.* //" ); echo -n "$acver" lessthan $acver $AUTOCONF_REQ if test $? = 0; then echo " (not ok)" echo " #################################################################### ######################### WARNING ################################ #################################################################### You need autoconf >= ${AUTOCONF_REQ}! " sleep 1; else echo " (ok)" fi if [ ! -f `which libtool` ] ; then echo "No libtool installed" exit 1 fi echo -n "libtool version: " ltver=$( libtool --version | cut -d ' ' -f 4 | head -1 ); echo -n "$ltver" echo " (ok)" echo -n "pkg-config: " pkg_config="$( which pkg-config )" if test -z "$pkg_config"; then echo "(not found)" echo " #################################################################### ######################### WARNING ################################ #################################################################### You need pkg-config! " else echo "$pkg_config" echo -n "pkg-config version: " pcver=$( pkg-config --version ) echo -n "$pcver" lessthan $pcver $PKG_CONFIG_REQ if test $? = 0; then echo " (not ok)" echo " #################################################################### ######################### WARNING ################################ #################################################################### You need pkg-config >= ${PKG_CONFIG_REQ}! " else echo " (ok)" sleep 1; fi fi echo -n "generating build system.." libtoolize -f -c \ && echo -n "." && aclocal -I m4 \ && echo -n "." && autoheader \ && echo -n "." && automake -a --include-deps \ && echo -n "." && autoconf && echo "done" \ && echo " You may now run ./configure " swami/install-sh0000755000175000017500000003246411344522607014077 0ustar alessioalessio#!/bin/sh # install - install a program, script, or datafile scriptversion=2006-12-25.00 # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. nl=' ' IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else doit_exec=$doit fi # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_glob='?' initialize_posix_glob=' test "$posix_glob" != "?" || { if (set -f) 2>/dev/null; then posix_glob= else posix_glob=: fi } ' posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false no_target_directory= usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) dst_arg=$2 shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call `install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then trap '(exit $?); exit' 1 2 13 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names starting with `-'. case $src in -*) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # Protect names starting with `-'. case $dst in -*) dst=./$dst;; esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else # Prefer dirname, but fall back on a substitute if dirname fails. dstdir=` (dirname "$dst") 2>/dev/null || expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$dst" : 'X\(//\)[^/]' \| \ X"$dst" : 'X\(//\)$' \| \ X"$dst" : 'X\(/\)' \| . 2>/dev/null || echo X"$dst" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q' ` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writeable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; -*) prefix='./';; *) prefix='';; esac eval "$initialize_posix_glob" oIFS=$IFS IFS=/ $posix_glob set -f set fnord $dstdir shift $posix_glob set +f IFS=$oIFS prefixes= for d do test -z "$d" && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && eval "$initialize_posix_glob" && $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && $posix_glob set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: swami/COPYING0000644000175000017500000003552511470120020013106 0ustar alessioalessioNOTE: This software is restricted to version 2 of the GPL only. GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS swami/swami.desktop0000644000175000017500000000103111500477133014565 0ustar alessioalessio[Desktop Entry] Encoding=UTF-8 Name=Swami Instrument Editor Name[ru]=Редактор ÑÑмплов Swami GenericName=Instrument Editor GenericName[ru]=Редактор ÑÑмплов Comment=Create, play and organize MIDI instruments and sounds Comment[ru]=Создание, воÑпроизведение и Ð¾Ñ€Ð³Ð°Ð½Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð·Ð²ÑƒÐºÐ¾Ð²Ñ‹Ñ… ÑÑмплов Exec=swami %F Icon=swami StartupNotify=true Terminal=false Type=Application Categories=GTK;Application;AudioVideo;Audio;Midi;Music; MimeType=audio/dls;audio/x-soundfont; swami/acinclude.m40000644000175000017500000000235711464144605014263 0ustar alessioalessiodnl - Macros for configure script dnl Summary print function dnl dnl FEATURE_SUMMARY(FEATURE-NAME, FEATURE-TEST, FAILURE-NOTE) AC_DEFUN([FEATURE_SUMMARY], [ if test [$2]; then _SUMMARY_ENABLED="$_SUMMARY_ENABLED$1\n" else _SUMMARY_DISABLED="$_SUMMARY_DISABLED$1\n" ifelse([$3], , :, _SUMMARY_DISABLED="$_SUMMARY_DISABLED\t** Note: $3\n") fi ]) AC_DEFUN([AC_DEBUGGING], [ AC_ARG_ENABLE(debug, [ --disable-debug disable debugging compiler options], enable_debug=$enableval, enable_debug="yes") if test "$enable_debug" = "yes" ; then AC_MSG_RESULT([enable debugging compiler flags ...]) CFLAGS="-g ${CFLAGS}" AC_DEFINE_UNQUOTED(DEBUG, 1, [Enable debugging]) AC_SUBST(DEBUG) else AC_MSG_RESULT([disable debugging compiler flags ...]) CFLAGS="-O2 ${CFLAGS}" fi ]) AC_DEFUN([AC_PROFILING], [ AC_ARG_ENABLE(profile, [ --enable-profile enable profiling compiler options], enable_profile=$enableval, enable_profile="no") if test "${enable_profile}" = "yes" ; then AC_MSG_RESULT([enable profile compiler flags ...]) if test "$GCC" = "yes" ; then CFLAGS="-pg ${CFLAGS}" else AC_MSG_RESULT(we do not have gcc, hope we have a nice profiler...) CFLAGS="-p ${CFLAGS}" fi fi ]) swami/CVS-HOWTO0000644000175000017500000000035207573110375013342 0ustar alessioalessioIf you got Swami from CVS, then run ./autogen.sh. You need autoconf and automake installed in order for this to work. Once this is done, you can compile like you normally would (see INSTALL for details): ./configure make make install swami/config.h.cmake0000644000175000017500000000455711464144605014573 0ustar alessioalessio#ifndef CONFIG_H #define CONFIG_H /* Define to 1 if you have the header file. */ #cmakedefine HAVE_ERRNO_H @HAVE_ERRNO_H@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_FCNTL_H @HAVE_FCNTL_H@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_MATH_H @HAVE_MATH_H@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STDARG_H @HAVE_STDARG_H@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STDIO_H @HAVE_STDIO_H@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STDLIB_H @HAVE_STDLIB_H@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STRING_H @HAVE_STRING_H@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_STAT_H @HAVE_SYS_STAT_H@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_UNISTD_H @HAVE_UNISTD_H@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_WINDOWS_H @HAVE_WINDOWS_H@ /* Define if using the MinGW32 environment */ #cmakedefine MINGW32 @MINGW32@ /* Define to 1 if your C compiler doesn't accept -c and -o together. */ #cmakedefine NO_MINUS_C_MINUS_O @NO_MINUS_C_MINUS_O@ /* Name of package */ #cmakedefine PACKAGE "@PACKAGE@" /* Define to the address where bug reports for this package should be sent. */ #cmakedefine PACKAGE_BUGREPORT @PACKAGE_BUGREPORT@ /* Define to the full name of this package. */ #cmakedefine PACKAGE_NAME @PACKAGE_NAME@ /* Define to the full name and version of this package. */ #cmakedefine PACKAGE_STRING @PACKAGE_STRING@ /* Define to the one symbol short name of this package. */ #cmakedefine PACKAGE_TARNAME @PACKAGE_TARNAME@ /* Define to the version of this package. */ #cmakedefine PACKAGE_VERSION @PACKAGE_VERSION@ /* Define to 1 if you have the ANSI C header files. */ #cmakedefine STDC_HEADERS @STDC_HEADERS@ /* Version number of package */ #cmakedefine VERSION @SWAMI_VERSION@ /* Source build? (resources loaded from source/build dirs) */ #cmakedefine SOURCE_BUILD @SOURCE_BUILD@ /* Source code directory */ #cmakedefine SOURCE_DIR "@SOURCE_DIR@" /* Plugins install directory */ #cmakedefine PLUGINS_DIR "@PLUGINS_DIR@" /* Images install directory */ #cmakedefine IMAGES_DIR "@IMAGES_DIR@" /* UI XML file install directory */ #cmakedefine UIXML_DIR "@UIXML_DIR@" #endif /* CONFIG_H */ swami/swami.png0000644000175000017500000001070711461404311013704 0ustar alessioalessio‰PNG  IHDR00Wù‡sBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<DIDATh­šy”UÇ?w©ª·õšNg±“4I#„D@6 &²(¨#4I@G< ŒÈœGô(Ã9œEAGŒ¢"Hº›€âÑ€BT–°…5 !é4YºûuºßRõªî½óÇ{ I§; Ž¿sê¼wnÕ­ß÷{ïïþ¶÷„sޱ"ª­ ?“!›J‘ Cœ”„…¥Þ^"ç°ûLúˆȶ6‚\ŽŒµ¤öÐ[q3vŽç%¢½/¦q`à†Ó£hÝç•jØïYÿòX{;CB9ǾÌÿàE{;~6KCÿ·…áS_´Ö³ÜÚzݽííä…ÀŽÕ»@)k{Ûâxý÷ƒ`NÜ a¸î„úz>E„@ û®Æx ’¬”’@ʸ5Š^úžïwLBP©l™_*½°NˆùåñôŽK@)üáá{Oñ¼¹Tj~mxýÌRiÕ±ZŸ·(ND Z{,²£Y³P½öCF8G*Ÿï9ÞóÚ&¥Ró@úa¸zQ&3ÓxzÇ# ´F+UïCŒÖ­€Bë“o÷}|¨®ì8àeGžµ¤¢ˆT*…†¸Ž"¥µ&‚xR)¼0,ÎÔz2ž7p(ÕÔIÏC§w<8‡"m„Ð „‡”œsõZ£;:B ö"²½ß9êÓiZòù§V*›—25óÏfÏY Ì›Ga<Õ…¢Ò,D¶¦/ž×\çDœ8çüйp€Bˆk R¢‹ÅªiŒ•J‘"ß¶cǵß"8Uëœ3”J]†Ï­hlüæMÖ’P5ƒ·LAD[²¡í\ܨT= p®‚s R¶ìW³—ŒÄU*˜Tê¨7¬ k« F ´A6»÷v ˜>Ï9êûû¿ûy¥šNÍdN “9‰Læ$Òéã”sá%##?*Q„rŽ’ÉBŒZiŒs!ZO¨T0ï„@¢ÔìA°ƒÖ†€¨mi2K²Zã±·=ŠL ÔY;üaÏ›…ï·3úéû‡ày3Doú'­É”J¨±8²Y´”¤­f ‘ÖF8—‚ c RaÔL &¶–"È­Ö‡”„PmÖöO¶–ö!’)%Z×,e!ÒH™ª]ÕïÎÅS’eÌ>‡Q Aàœ©‚R¦‡s%„[¬¥ï€@©D¢5E!ü—ŒÙ Ä‘A©Fxø¾3Üôé{™Ó+¨­ÆìÆÚÝ3Œ1»1fc†Âßè±çíÉÛÛQA@ºX|x¾”õ”ÀbLð7C©X4tË"­Éµ¶âut ÕÖFÐÑAC]ÓÃð/§†ásWù~‡Vª kCâxΕŸÉf<“$6lßþÄxõ¼•”yóçÓdLù°oß•JÍ}—ï8*•ÍT*›·44\ø%­§½†ô;G”É*žš;4tóýZOÎ9Ü7iÒ÷®²–)qR’SŠÖBaÍéQôÌׂ #ëym€$Ž·P.?SL§O»Øó<š$ôoÞÑÀ9œ$»vQ¨«Ko ‚ù7FÑ+ß–2'xQ*uDÎ÷gÕVtó©¾Ïç¨7ĕC†‡ûçäR©#”ÖSA’l' _±ApØ¥Ó žrŽÝ6L˜üíŸ@„‚(ÌdÎ]“$7ÞE¯,B¡Ôd|¿!R3¢èé¢èÙÇ|îš\îýÛ({’PŠúTŠi»wßyN¿q‰Ö“¦k=¥kùR)³(UWË,Ö±v¸Fdcv“$;I’])îkl\ö3)›6Œ0°e E8ðÊ4în&ƒ·l}£Wµ–IZ›éƒƒ?9¿RÙ¶Lëúf¥ZÐzZ·2øªAi'q¼$ÙN’ ç*oH™Z[W·ü—RNÙâZ3¼~=!¼fü£lÚ€óy¾zé¥$€ž7È)EƒµL*:²Ryã}`ŽRªn~ÌIkÝŠµe*•×°6ù³”Áã™Ì kkÞn CB0Ç¥$¬ùzÓÝMð`rsÑÿGx\)–.^Ì6@Ì›‡V ¯R!¥5™$¡Qkf Ýñ5­[NöývŒ)†ëhlüÌEƨ´f§s PY¿C­ØïéasÜÌ‚s–,áWû÷_7 ` '+Ep"p²1¬[¹’ÿ¨«cÅÙgS jo§èû”Á3&_’2]+ #ŒÁ¹pH©ì®ÁAúú¨PÍmœs¸;菉»›«€¯ðvvð+çøÍðí/•`Ù2¶æóœ*7׆Z„à–B +WriWÚ9’Í›‰óyB) «$U^–j™à\•iÓˆ#q{×]´vuñŸ¾Ïà«5¹t)/,¦wDà¶Ûðš›ù”s|mO"ÎAㆆØyûí?ÊîÚU—%P,®åsŸ»òµ3tk&Cƒ[ÃÃÎñ­óÏg5dÉ>g`åJæJÉuÎñ|qý'?IqÏû—\B ¬¸í6~ÖÜÌbçøð!` ¤dŠ”®FÊÕœ#ä¡bïJøM` pKg'›àÝw3CJ®*BðïìÚ/!ø:ðq!øx*Å'zzøì’%<8ö¹‘»»¯¹ÙÑÁIaÈÅ"s …‘CC}p•L¹Ì_£ˆM¾ÏcžÇƒ‹óòD G¡ôôp‰RÜÔÕÆž~p Ë©¨vçXÓÓâˆ/_x!Ããiºúj¬¬=ê(ž1†YýýýG¥Ó3ê5Ž{î‘_ C^ظ‘Açª%åD²j³aÕs2*#ưzì³ûx¡ÎNî‚ðö 9ÇÅ¾ÏÆîn®]µŠi)6a-ð«Í0¨¶Gœ[ë®M(ÝÝÙÝÍ cX?ü”âÈeËØéz¡{îá½ÖrÃ8/Øî‚?óèµ×òf6Ë¡»v}ó·éôûZ|¿8ÞN¹ü̶ÖÖ«:óy^9ñD Ë–q”1,‚EÀÞ¶ñQ1BÐ%%_:ï<Þܾƒv£ÝÝ)_pŽ ØÛwW5C·ogèûß¿~–RÇ(Ï›B÷’Jõ>ýéK7¶¶’I§™*å>€GeÐ9VÁ­l9\`åJæ;Ga<•ÎNž>ÓÝÍW…àRçXÌ¥úÃÖB’Ð\.›Iáy„ðECäœÖ¼Gg½à ç¸]~qþù”÷øškóæq¶l_¼˜'EW—»øÕfm7ðåƒeßÝÍdç8ÕV*,æðU«ºô† éôÑH™#Ž·ÒÔ”gÉ’ÓÒ™ %¥xJ‚GÂÇÇÆš‰¤«‹÷×Ršcœc©èîv7:Ç{QköÇÛF”šzWc㲕ào-é_´sæ™|L).>0Ž~ ¬H¾¾|9ýoYÃxn´»›P-ës’ÊexñÅ×¢5kˆvî,Öy^›ÐzJ5ÖZ,y¢è ¤ôžÐzÖ‹Qôôr­Ûüj(ƒµ1Æ ǽ8·}ø¸ãNzþŒ3NË462ÏóðåøÊCÖråÒ¥<=öÆþâ€èêâ4)¹Ø9α?Šà‘GÖpï½]¤RGãû³©¶Ã}œ‹H’DÑÚÚ¦lY¸pùãÎ1°iÓú¶¿üeÕ‡„˜šòý™HÙ\ë¨T6†ë8÷ÜÅœ|òûI¥`T{@~.·í/ñ;¨@ÖÝÍäJ…O‡!ß}÷­Ï>»•tú½h=!4ÆŒ$Û>N8áxN9åƒär %T*°cÇ¿ûÝ=¼þú›x^{í€ûÓO>ÇÑGÏdéÒÏ’É€”<"%·e³ôœuѰ½“¾~÷»i ÃËo-Ìù©ÔáHÙ€s!IÒÏ¡‡Îæ´Ó>Ê”)õ¤Óàû D5ÀE”Jðꫯ²fÍ} FHÙˆs!•ÊF,8ó¯ ž÷SçxàŠ+xý ýääÉd|ÿ9…Âí7K™;B©ÜH.wÈßN<ñÜ-sçÎô›› ²Yr¾O“Ö4 A‹sXc¨T,¢ü䓜´nÝïß]* EÖ´´Üô½|ž»vQ>P/ôï&P#áÍžM&“¡^²Ö"… 2†RQ²–hófbÆøõÑÿOŒºßt𴵤|‘$”ã˜â† ”aâß&’ÿÈóZ–z ½IEND®B`‚swami/docs/0000755000175000017500000000000011716016666013020 5ustar alessioalessioswami/docs/Makefile.am0000644000175000017500000000002407676126120015045 0ustar alessioalessioSUBDIRS = reference swami/docs/reference/0000755000175000017500000000000011716016666014756 5ustar alessioalessioswami/docs/reference/swamigui/0000755000175000017500000000000011716016666016603 5ustar alessioalessioswami/docs/reference/swamigui/Makefile.am0000644000175000017500000000551011461404311020621 0ustar alessioalessio## Process this file with automake to produce Makefile.in # We require automake 1.6 at least. AUTOMAKE_OPTIONS = 1.6 # This is a blank Makefile.am for using gtk-doc. # Copy this to your project's API docs directory and modify the variables to # suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples # of using the various options. # The name of the module, e.g. 'glib'. DOC_MODULE=swamigui # The top-level SGML file. You can change this if you want to. DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml # The directory containing the source code. Relative to $(srcdir). # gtk-doc will search all .c & .h files beneath here for inline comments # documenting the functions and macros. DOC_SOURCE_DIR=$(top_srcdir)/src/swamigui # Extra options to pass to gtkdoc-scangobj. Not normally needed. SCANGOBJ_OPTIONS=--type-init-func="swamigui_init (0, NULL)" # Extra options to supply to gtkdoc-scan. # e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" SCAN_OPTIONS= # Extra options to supply to gtkdoc-mkdb. # e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml MKDB_OPTIONS=--sgml-mode --output-format=xml # Extra options to supply to gtkdoc-mktmpl # e.g. MKTMPL_OPTIONS=--only-section-tmpl MKTMPL_OPTIONS= # Extra options to supply to gtkdoc-fixref. Not normally needed. # e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html FIXXREF_OPTIONS= # Used for dependencies. The docs will be rebuilt if any of these change. HFILE_GLOB=$(top_srcdir)/src/swamigui/*.h CFILE_GLOB=$(top_srcdir)/src/swamigui/*.c # Header files to ignore when scanning. IGNORE_HFILES=builtin_enums.h \ i18n.h \ swamigui.h \ swamigui_priv.h # Images to copy into HTML directory. # e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png HTML_IMAGES= # Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). # e.g. content_files=running.sgml building.sgml changes-2.0.sgml content_files= # SGML files where gtk-doc abbrevations (#GtkWidget) are expanded # These files must be listed here *and* in content_files # e.g. expand_content_files=running.sgml expand_content_files= # CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. # Only needed if you are using gtkdoc-scangobj to dynamically query widget # signals and properties. # e.g. INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) # e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) INCLUDES = -I$(top_srcdir)/src/swamigui -I$(top_srcdir)/src \ @GUI_CFLAGS@ @LIBINSTPATCH_CFLAGS@ GTKDOC_LIBS = $(top_srcdir)/src/swamigui/libswamigui.la \ $(top_srcdir)/src/libswami/libswami.la @GUI_LIBS@ @LIBGLADE_LIBS@ \ @LIBINSTPATCH_LIBS@ @PYTHON_LIBS@ @GTK_SOURCE_VIEW_LIBS@ # This includes the standard gtk-doc make rules, copied by gtkdocize. include $(top_srcdir)/gtk-doc.make # Other files to distribute # e.g. EXTRA_DIST += version.xml.in EXTRA_DIST += swami/docs/reference/swamigui/swamigui-docs.sgml0000644000175000017500000000635011461404311022227 0ustar alessioalessio ]> swamigui Reference Manual For swamigui 2.0.0 The latest version of this documentation can be found on-line at http://swami.sourceforge.net/api/swamigui/. General Controls Canvas items and related GUI Widgets Misc Object Hierarchy API Index swami/docs/reference/swamigui/swamigui.types0000644000175000017500000000162711461715433021517 0ustar alessioalessioswamigui_bar_get_type swamigui_panel_selector_get_type swamigui_panel_sf2_gen_misc_get_type swamigui_tree_store_patch_get_type swamigui_prop_get_type swamigui_panel_sf2_gen_env_get_type swamigui_pref_get_type swamigui_control_midi_key_get_type swamigui_piano_get_type swamigui_statusbar_get_type swamigui_control_adj_get_type swamigui_knob_get_type swamigui_loop_finder_get_type swamigui_mod_edit_get_type swamigui_sample_canvas_get_type swamigui_panel_get_type swamigui_spin_scale_get_type swamigui_spectrum_canvas_get_type swamigui_canvas_mod_get_type swamigui_note_selector_get_type swamigui_menu_get_type swamigui_item_menu_get_type swamigui_bar_ptr_get_type swamigui_tree_get_type swamigui_tree_store_get_type swamigui_paste_get_type swamigui_sample_editor_get_type swamigui_multi_save_get_type swamigui_splits_get_type swamigui_panel_sf2_gen_get_type swamigui_root_get_type icon_combo_get_type combo_box_get_type swami/docs/reference/swamigui/swamigui-sections.txt0000644000175000017500000004610511461404311023005 0ustar alessioalessio
SwamiguiBar SwamiguiBar SwamiguiBar swamigui_bar_create_pointer swamigui_bar_add_pointer swamigui_bar_get_pointer swamigui_bar_set_pointer_position swamigui_bar_set_pointer_range swamigui_bar_get_pointer_order swamigui_bar_set_pointer_order swamigui_bar_raise_pointer_to_top swamigui_bar_lower_pointer_to_bottom SWAMIGUI_BAR SWAMIGUI_IS_BAR SWAMIGUI_TYPE_BAR swamigui_bar_get_type SWAMIGUI_BAR_CLASS SWAMIGUI_IS_BAR_CLASS
SwamiguiPanelSelector SwamiguiPanelSelector SwamiguiPanelSelector swamigui_get_panel_selector_types swamigui_register_panel_selector_type swamigui_panel_selector_new swamigui_panel_selector_set_selection swamigui_panel_selector_get_selection SWAMIGUI_PANEL_SELECTOR SWAMIGUI_IS_PANEL_SELECTOR SWAMIGUI_TYPE_PANEL_SELECTOR swamigui_panel_selector_get_type SWAMIGUI_PANEL_SELECTOR_CLASS SWAMIGUI_IS_PANEL_SELECTOR_CLASS
SwamiguiPanelSF2GenMisc SwamiguiPanelSF2GenMisc SwamiguiPanelSF2GenMisc swamigui_panel_sf2_gen_misc_new SWAMIGUI_PANEL_SF2_GEN_MISC SWAMIGUI_IS_PANEL_SF2_GEN_MISC SWAMIGUI_TYPE_PANEL_SF2_GEN_MISC swamigui_panel_sf2_gen_misc_get_type SWAMIGUI_PANEL_SF2_GEN_MISC_CLASS SWAMIGUI_IS_PANEL_SF2_GEN_MISC_CLASS
SwamiguiTreeStorePatch SwamiguiTreeStorePatch SwamiguiTreeStorePatch swamigui_tree_store_patch_new swamigui_tree_store_patch_item_add swamigui_tree_store_patch_item_changed SWAMIGUI_TREE_STORE_PATCH SWAMIGUI_IS_TREE_STORE_PATCH SWAMIGUI_TYPE_TREE_STORE_PATCH swamigui_tree_store_patch_get_type SWAMIGUI_TREE_STORE_PATCH_CLASS SWAMIGUI_IS_TREE_STORE_PATCH_CLASS
SwamiguiProp SwamiguiProp SwamiguiProp SwamiguiPropHandler swamigui_register_prop_glade_widg swamigui_register_prop_handler swamigui_prop_new swamigui_prop_set_selection SWAMIGUI_PROP SWAMIGUI_IS_PROP SWAMIGUI_TYPE_PROP swamigui_prop_get_type SWAMIGUI_PROP_CLASS SWAMIGUI_IS_PROP_CLASS
SwamiguiPanelSF2GenEnv SwamiguiPanelSF2GenEnv SwamiguiPanelSF2GenEnv swamigui_panel_sf2_gen_env_new SWAMIGUI_PANEL_SF2_GEN_ENV SWAMIGUI_IS_PANEL_SF2_GEN_ENV SWAMIGUI_TYPE_PANEL_SF2_GEN_ENV swamigui_panel_sf2_gen_env_get_type SWAMIGUI_PANEL_SF2_GEN_ENV_CLASS SWAMIGUI_IS_PANEL_SF2_GEN_ENV_CLASS
SwamiguiPref SwamiguiPref SwamiguiPref SwamiguiPrefHandler SWAMIGUI_PREF_ORDER_NAME swamigui_register_pref_handler swamigui_pref_new SWAMIGUI_PREF SWAMIGUI_IS_PREF SWAMIGUI_TYPE_PREF swamigui_pref_get_type SWAMIGUI_PREF_CLASS SWAMIGUI_IS_PREF_CLASS
SwamiguiControlMidiKey SwamiguiControlMidiKey SwamiguiControlMidiKey swamigui_control_midi_key_new swamigui_control_midi_key_press swamigui_control_midi_key_release swamigui_control_midi_key_set_lower swamigui_control_midi_key_set_upper SWAMIGUI_CONTROL_MIDI_KEY SWAMIGUI_IS_CONTROL_MIDI_KEY SWAMIGUI_TYPE_CONTROL_MIDI_KEY swamigui_control_midi_key_get_type SWAMIGUI_CONTROL_MIDI_KEY_CLASS SWAMIGUI_IS_CONTROL_MIDI_KEY_CLASS
SwamiguiPiano SWAMIGUI_PIANO_DEFAULT_WIDTH SWAMIGUI_PIANO_DEFAULT_HEIGHT SWAMIGUI_PIANO_DEFAULT_LOWER_OCTAVE SWAMIGUI_PIANO_DEFAULT_UPPER_OCTAVE SwamiguiPiano SwamiguiPiano swamigui_piano_note_on swamigui_piano_note_off swamigui_piano_pos_to_note swamigui_piano_note_to_pos SWAMIGUI_PIANO SWAMIGUI_IS_PIANO SWAMIGUI_TYPE_PIANO swamigui_piano_get_type SWAMIGUI_PIANO_CLASS SWAMIGUI_IS_PIANO_CLASS
SwamiguiStatusbar SWAMIGUI_STATUSBAR_GLOBAL_MAXLEN SwamiguiStatusbar SwamiguiStatusbar SwamiguiStatusbarCloseFunc SwamiguiStatusbarPos SwamiguiStatusbarTimeout swamigui_statusbar_new swamigui_statusbar_add swamigui_statusbar_remove swamigui_statusbar_printf swamigui_statusbar_msg_label_new swamigui_statusbar_msg_progress_new swamigui_statusbar_msg_set_timeout swamigui_statusbar_msg_set_label swamigui_statusbar_msg_set_progress SWAMIGUI_STATUSBAR SWAMIGUI_IS_STATUSBAR SWAMIGUI_TYPE_STATUSBAR swamigui_statusbar_get_type SWAMIGUI_STATUSBAR_CLASS SWAMIGUI_IS_STATUSBAR_CLASS
SwamiguiControlAdj SwamiguiControlAdj SwamiguiControlAdj swamigui_control_adj_new swamigui_control_adj_set swamigui_control_adj_block_changes swamigui_control_adj_unblock_changes SWAMIGUI_CONTROL_ADJ SWAMIGUI_IS_CONTROL_ADJ SWAMIGUI_TYPE_CONTROL_ADJ swamigui_control_adj_get_type SWAMIGUI_CONTROL_ADJ_CLASS SWAMIGUI_IS_CONTROL_ADJ_CLASS
SwamiguiKnob SwamiguiKnob SwamiguiKnob swamigui_knob_new swamigui_knob_get_adjustment SWAMIGUI_KNOB SWAMIGUI_IS_KNOB SWAMIGUI_TYPE_KNOB swamigui_knob_get_type SWAMIGUI_KNOB_CLASS
SwamiguiLoopFinder SwamiguiLoopFinder SwamiguiLoopFinder swamigui_loop_finder_new swamigui_loop_finder_clear_results SWAMIGUI_LOOP_FINDER SWAMIGUI_IS_LOOP_FINDER SWAMIGUI_TYPE_LOOP_FINDER swamigui_loop_finder_get_type
SwamiguiModEdit SwamiguiModEdit SwamiguiModEdit swamigui_mod_edit_new swamigui_mod_edit_set_selection SWAMIGUI_MOD_EDIT SWAMIGUI_IS_MOD_EDIT SWAMIGUI_TYPE_MOD_EDIT swamigui_mod_edit_get_type SWAMIGUI_MOD_EDIT_CLASS SWAMIGUI_IS_MOD_EDIT_CLASS
SwamiguiPythonView SwamiguiPythonView SwamiguiPythonView swamigui_python_view_new SWAMIGUI_PYTHON_VIEW SWAMIGUI_IS_PYTHON_VIEW SWAMIGUI_TYPE_PYTHON_VIEW swamigui_python_view_get_type SWAMIGUI_PYTHON_VIEW_CLASS SWAMIGUI_IS_PYTHON_VIEW_CLASS
SwamiguiSampleCanvas SwamiguiSampleCanvas SwamiguiSampleCanvas swamigui_sample_canvas_set_sample swamigui_sample_canvas_xpos_to_sample swamigui_sample_canvas_sample_to_xpos SWAMIGUI_SAMPLE_CANVAS SWAMIGUI_IS_SAMPLE_CANVAS SWAMIGUI_TYPE_SAMPLE_CANVAS swamigui_sample_canvas_get_type SWAMIGUI_SAMPLE_CANVAS_CLASS SWAMIGUI_IS_SAMPLE_CANVAS_CLASS
SwamiguiPanel SwamiguiPanel SwamiguiPanelIface SwamiguiPanelCheckFunc swamigui_panel_type_get_info swamigui_panel_type_check_selection swamigui_panel_get_types_in_selection SWAMIGUI_PANEL SWAMIGUI_IS_PANEL SWAMIGUI_TYPE_PANEL swamigui_panel_get_type SWAMIGUI_PANEL_CLASS SWAMIGUI_PANEL_GET_IFACE
SwamiguiSpinScale SwamiguiSpinScale SwamiguiSpinScale swamigui_spin_scale_new swamigui_spin_scale_set_order SWAMIGUI_SPIN_SCALE SWAMIGUI_IS_SPIN_SCALE SWAMIGUI_TYPE_SPIN_SCALE swamigui_spin_scale_get_type SWAMIGUI_SPIN_SCALE_CLASS SWAMIGUI_IS_SPIN_SCALE_CLASS
SwamiguiSpectrumCanvas SwamiguiSpectrumDestroyNotify SwamiguiSpectrumCanvas SwamiguiSpectrumCanvas swamigui_spectrum_canvas_set_data swamigui_spectrum_canvas_pos_to_spectrum swamigui_spectrum_canvas_spectrum_to_pos SWAMIGUI_SPECTRUM_CANVAS SWAMIGUI_IS_SPECTRUM_CANVAS SWAMIGUI_TYPE_SPECTRUM_CANVAS swamigui_spectrum_canvas_get_type SWAMIGUI_SPECTRUM_CANVAS_CLASS SWAMIGUI_IS_SPECTRUM_CANVAS_CLASS
SwamiguiCanvasMod SwamiguiCanvasModType SWAMIGUI_CANVAS_MOD_TYPE_COUNT SwamiguiCanvasModAxis SWAMIGUI_CANVAS_MOD_AXIS_COUNT SwamiguiCanvasModFlags SwamiguiCanvasModActions SwamiguiCanvasMod SwamiguiCanvasMod swamigui_canvas_mod_new swamigui_canvas_mod_set_vars swamigui_canvas_mod_get_vars swamigui_canvas_mod_handle_event SWAMIGUI_CANVAS_MOD SWAMIGUI_IS_CANVAS_MOD SWAMIGUI_TYPE_CANVAS_MOD swamigui_canvas_mod_get_type SWAMIGUI_CANVAS_MOD_CLASS SWAMIGUI_IS_CANVAS_MOD_CLASS
SwamiguiNoteSelector SwamiguiNoteSelector SwamiguiNoteSelector swamigui_note_selector_new SWAMIGUI_NOTE_SELECTOR SWAMIGUI_IS_NOTE_SELECTOR SWAMIGUI_TYPE_NOTE_SELECTOR swamigui_note_selector_get_type SWAMIGUI_NOTE_SELECTOR_CLASS SWAMIGUI_IS_NOTE_SELECTOR_CLASS
SwamiguiMenu SwamiguiMenu SwamiguiMenu swamigui_menu_new SWAMIGUI_MENU SWAMIGUI_IS_MENU SWAMIGUI_TYPE_MENU swamigui_menu_get_type SWAMIGUI_MENU_CLASS SWAMIGUI_IS_MENU_CLASS
SwamiguiItemMenu SwamiguiItemMenuInfo SwamiguiItemMenuEntry SwamiguiItemMenuCallback SwamiguiItemMenuHandler SwamiguiItemMenuFlags SwamiguiItemMenu SwamiguiItemMenu swamigui_item_menu_accel_group swamigui_item_menu_new swamigui_item_menu_add swamigui_item_menu_add_registered_info swamigui_item_menu_generate swamigui_register_item_menu_action swamigui_lookup_item_menu_action swamigui_register_item_menu_include_type swamigui_register_item_menu_exclude_type swamigui_test_item_menu_type swamigui_test_item_menu_include_type swamigui_test_item_menu_exclude_type swamigui_item_menu_get_selection_single swamigui_item_menu_get_selection swamigui_item_menu_handler_single swamigui_item_menu_handler_multi swamigui_item_menu_handler_single_all swamigui_item_menu_handler_multi_all SWAMIGUI_ITEM_MENU SWAMIGUI_IS_ITEM_MENU SWAMIGUI_TYPE_ITEM_MENU swamigui_item_menu_get_type SWAMIGUI_ITEM_MENU_CLASS SWAMIGUI_IS_ITEM_MENU_CLASS
SwamiguiBarPtr SwamiguiBarPtrType SwamiguiBarPtr SwamiguiBarPtr swamigui_bar_ptr_new SWAMIGUI_BAR_PTR SWAMIGUI_IS_BAR_PTR SWAMIGUI_TYPE_BAR_PTR swamigui_bar_ptr_get_type SWAMIGUI_BAR_PTR_CLASS SWAMIGUI_IS_BAR_PTR_CLASS
SwamiguiTree SwamiguiTree SwamiguiTree swamigui_tree_new swamigui_tree_set_store_list swamigui_tree_get_store_list swamigui_tree_set_selected_store swamigui_tree_get_selected_store swamigui_tree_get_selection_single swamigui_tree_get_selection swamigui_tree_clear_selection swamigui_tree_set_selection swamigui_tree_spotlight_item swamigui_tree_search_set_start swamigui_tree_search_set_text swamigui_tree_search_set_visible swamigui_tree_search_next swamigui_tree_search_prev SWAMIGUI_TREE SWAMIGUI_IS_TREE SWAMIGUI_TYPE_TREE swamigui_tree_get_type SWAMIGUI_TREE_CLASS SWAMIGUI_IS_TREE_CLASS
SwamiguiTreeStore SwamiguiTreeStore SwamiguiTreeStore SWAMIGUI_TREE_ERRMSG_PARENT_NOT_IN_TREE SWAMIGUI_TREE_ERRMSG_ITEM_NOT_IN_TREE swamigui_tree_store_insert swamigui_tree_store_insert_before swamigui_tree_store_insert_after swamigui_tree_store_change swamigui_tree_store_remove swamigui_tree_store_move_before swamigui_tree_store_move_after swamigui_tree_store_item_get_node swamigui_tree_store_node_get_item swamigui_tree_store_add swamigui_tree_store_changed SWAMIGUI_TREE_STORE SWAMIGUI_IS_TREE_STORE SWAMIGUI_TYPE_TREE_STORE swamigui_tree_store_get_type SWAMIGUI_TREE_STORE_CLASS SWAMIGUI_IS_TREE_STORE_CLASS SWAMIGUI_TREE_STORE_GET_CLASS
SwamiguiPaste SwamiguiPasteStatus SwamiguiPasteDecision SwamiguiPaste SwamiguiPaste swamigui_paste_new swamigui_paste_process swamigui_paste_set_items swamigui_paste_get_conflict_items swamigui_paste_set_conflict_items swamigui_paste_push_state swamigui_paste_pop_state SWAMIGUI_PASTE SWAMIGUI_IS_PASTE SWAMIGUI_TYPE_PASTE swamigui_paste_get_type SWAMIGUI_PASTE_CLASS SWAMIGUI_IS_PASTE_CLASS
SwamiguiSampleEditor SwamiguiSampleEditorStatus SwamiguiSampleEditorHandler SwamiguiSampleEditor SwamiguiSampleEditor SwamiguiSampleEditorMarkerFlags SwamiguiSampleEditorMarkerId swamigui_sample_editor_new swamigui_sample_editor_zoom_ofs swamigui_sample_editor_scroll_ofs swamigui_sample_editor_loop_zoom swamigui_sample_editor_set_selection swamigui_sample_editor_get_selection swamigui_sample_editor_register_handler swamigui_sample_editor_unregister_handler swamigui_sample_editor_reset swamigui_sample_editor_get_loop_controls swamigui_sample_editor_add_track swamigui_sample_editor_get_track_info swamigui_sample_editor_remove_track swamigui_sample_editor_remove_all_tracks swamigui_sample_editor_add_marker swamigui_sample_editor_get_marker_info swamigui_sample_editor_set_marker swamigui_sample_editor_remove_marker swamigui_sample_editor_remove_all_markers swamigui_sample_editor_show_marker swamigui_sample_editor_set_loop_types swamigui_sample_editor_set_active_loop_type SWAMIGUI_SAMPLE_EDITOR SWAMIGUI_IS_SAMPLE_EDITOR SWAMIGUI_TYPE_SAMPLE_EDITOR swamigui_sample_editor_get_type SWAMIGUI_SAMPLE_EDITOR_CLASS SWAMIGUI_IS_SAMPLE_EDITOR_CLASS
SwamiguiMultiSave SwamiguiMultiSave SwamiguiMultiSave SwamiguiMultiSaveFlags swamigui_multi_save_new swamigui_multi_save_set_selection SWAMIGUI_MULTI_SAVE SWAMIGUI_IS_MULTI_SAVE SWAMIGUI_TYPE_MULTI_SAVE swamigui_multi_save_get_type SWAMIGUI_MULTI_SAVE_CLASS SWAMIGUI_IS_MULTI_SAVE_CLASS
SwamiguiSplits SwamiguiSplitsEntry SWAMIGUI_SPLITS_WHITE_KEY_COUNT SwamiguiSplitsMode SwamiguiSplitsStatus SwamiguiSplitsMoveFlags SwamiguiSplitsHandler SwamiguiSplits SwamiguiSplits swamigui_splits_new swamigui_splits_set_mode swamigui_splits_set_width swamigui_splits_set_selection swamigui_splits_get_selection swamigui_splits_select_items swamigui_splits_select_all swamigui_splits_unselect_all swamigui_splits_item_changed swamigui_splits_register_handler swamigui_splits_unregister_handler swamigui_splits_add swamigui_splits_insert swamigui_splits_lookup_entry swamigui_splits_remove swamigui_splits_remove_all swamigui_splits_set_span_range swamigui_splits_set_root_note swamigui_splits_entry_get_span_control swamigui_splits_entry_get_root_note_control swamigui_splits_entry_get_index SWAMIGUI_SPLITS SWAMIGUI_IS_SPLITS SWAMIGUI_TYPE_SPLITS swamigui_splits_get_type SWAMIGUI_SPLITS_CLASS SWAMIGUI_IS_SPLITS_CLASS
SwamiguiPanelSF2Gen SwamiguiPanelSF2GenCtrlInfo SwamiguiPanelSF2Gen SwamiguiPanelSF2Gen SwamiguiPanelSF2GenOp swamigui_panel_sf2_gen_new swamigui_panel_sf2_gen_set_controls SWAMIGUI_PANEL_SF2_GEN SWAMIGUI_IS_PANEL_SF2_GEN SWAMIGUI_TYPE_PANEL_SF2_GEN swamigui_panel_sf2_gen_get_type SWAMIGUI_PANEL_SF2_GEN_CLASS SWAMIGUI_IS_PANEL_SF2_GEN_CLASS
SwamiguiRoot SwamiguiQuitConfirm SwamiguiRoot SwamiguiRoot swamigui_root swami_root swamigui_init swamigui_root_new swamigui_root_activate swamigui_root_quit swamigui_get_root swamigui_root_save_prefs swamigui_root_load_prefs SWAMIGUI_ROOT SWAMIGUI_IS_ROOT SWAMIGUI_TYPE_ROOT swamigui_root_get_type SWAMIGUI_ROOT_CLASS SWAMIGUI_IS_ROOT_CLASS
help swamigui_help_about swamigui_help_swamitips_create
util SWAMIGUI_SAMPLE_TRANSFORM_SIZE UtilQuickFunc SWAMIGUI_UNIT_RGBA_COLOR swamigui_util_init swamigui_util_unit_rgba_color_get_type swamigui_util_canvas_line_set swamigui_util_quick_popup swamigui_util_lookup_unique_dialog swamigui_util_register_unique_dialog swamigui_util_unregister_unique_dialog swamigui_util_activate_unique_dialog swamigui_util_waitfor_widget_action swamigui_util_widget_action swamigui_util_glade_create swamigui_util_glade_lookup swamigui_util_glade_lookup_nowarn swamigui_util_option_menu_index swamigui_util_str_crlf2lf swamigui_util_str_lf2crlf swamigui_util_substrcmp
swami_python SwamiguiPythonOutputFunc swamigui_python_set_output_func swamigui_python_set_root swamigui_python_is_initialized
SwamiguiDnd SWAMIGUI_DND_OBJECT_NAME SWAMIGUI_DND_URI_NAME
icons SWAMIGUI_STOCK_CONCAVE_NEG_BI SWAMIGUI_STOCK_CONCAVE_NEG_UNI SWAMIGUI_STOCK_CONCAVE_POS_BI SWAMIGUI_STOCK_CONCAVE_POS_UNI SWAMIGUI_STOCK_CONVEX_NEG_BI SWAMIGUI_STOCK_CONVEX_NEG_UNI SWAMIGUI_STOCK_CONVEX_POS_BI SWAMIGUI_STOCK_CONVEX_POS_UNI SWAMIGUI_STOCK_DLS SWAMIGUI_STOCK_EFFECT_CONTROL SWAMIGUI_STOCK_EFFECT_DEFAULT SWAMIGUI_STOCK_EFFECT_GRAPH SWAMIGUI_STOCK_EFFECT_SET SWAMIGUI_STOCK_EFFECT_VIEW SWAMIGUI_STOCK_GIG SWAMIGUI_STOCK_GLOBAL_ZONE SWAMIGUI_STOCK_INST SWAMIGUI_STOCK_LINEAR_NEG_BI SWAMIGUI_STOCK_LINEAR_NEG_UNI SWAMIGUI_STOCK_LINEAR_POS_BI SWAMIGUI_STOCK_LINEAR_POS_UNI SWAMIGUI_STOCK_LOOP_NONE SWAMIGUI_STOCK_LOOP_STANDARD SWAMIGUI_STOCK_LOOP_RELEASE SWAMIGUI_STOCK_MODENV SWAMIGUI_STOCK_MODENV_ATTACK SWAMIGUI_STOCK_MODENV_DECAY SWAMIGUI_STOCK_MODENV_DELAY SWAMIGUI_STOCK_MODENV_HOLD SWAMIGUI_STOCK_MODENV_RELEASE SWAMIGUI_STOCK_MODENV_SUSTAIN SWAMIGUI_STOCK_MODULATOR_EDITOR SWAMIGUI_STOCK_MODULATOR_JUNCT SWAMIGUI_STOCK_MUTE SWAMIGUI_STOCK_PIANO SWAMIGUI_STOCK_PRESET SWAMIGUI_STOCK_PYTHON SWAMIGUI_STOCK_SAMPLE SWAMIGUI_STOCK_SAMPLE_ROM SWAMIGUI_STOCK_SAMPLE_VIEWER SWAMIGUI_STOCK_SOUNDFONT SWAMIGUI_STOCK_SPLITS SWAMIGUI_STOCK_SWITCH_NEG_BI SWAMIGUI_STOCK_SWITCH_NEG_UNI SWAMIGUI_STOCK_SWITCH_POS_BI SWAMIGUI_STOCK_SWITCH_POS_UNI SWAMIGUI_STOCK_TREE SWAMIGUI_STOCK_TUNING SWAMIGUI_STOCK_VELOCITY SWAMIGUI_STOCK_VOLENV SWAMIGUI_STOCK_VOLENV_ATTACK SWAMIGUI_STOCK_VOLENV_DECAY SWAMIGUI_STOCK_VOLENV_DELAY SWAMIGUI_STOCK_VOLENV_HOLD SWAMIGUI_STOCK_VOLENV_RELEASE SWAMIGUI_STOCK_VOLENV_SUSTAIN SWAMIGUI_ICON_SIZE_CUSTOM_LARGE1 swamigui_icon_size_custom_large1 swamigui_icon_get_category_icon
splash swamigui_splash_display swamigui_splash_kill
patch_funcs swamigui_load_files swamigui_save_files swamigui_close_files swamigui_delete_items swamigui_wtbl_load_patch swamigui_new_item swamigui_goto_link_item swamigui_load_samples swamigui_export_samples swamigui_copy_items swamigui_paste_items
marshals swamigui_marshal_VOID__DOUBLE_DOUBLE_DOUBLE_DOUBLE_DOUBLE_DOUBLE swamigui_marshal_VOID__UINT_DOUBLE_DOUBLE
SwamiguiControl SwamiguiControlRank SWAMIGUI_CONTROL_RANK_DEFAULT SWAMIGUI_CONTROL_RANK_MASK SwamiguiControlFlags SWAMIGUI_CONTROL_CTRLVIEW SwamiguiControlObjectFlags SwamiguiControlHandler swamigui_control_quark swamigui_control_new swamigui_control_new_for_widget swamigui_control_new_for_widget_full swamigui_control_lookup swamigui_control_prop_connect_widget swamigui_control_create_widget swamigui_control_set_queue swamigui_control_register swamigui_control_unregister swamigui_control_glade_prop_connect swamigui_control_get_alias_value_type
icon-combo ICON_COMBO_TYPE ICON_COMBO ICON_COMBO_CLASS IS_ICON_COMBO icon_combo_get_type icon_combo_new icon_combo_select_icon changed
combo-box COMBO_BOX_TYPE COMBO_BOX COMBO_BOX_CLASS IS_COMBO_BOX ComboBoxPrivate ComboBox ComboBox combo_box_get_type combo_box_construct combo_box_get_pos combo_box_new combo_box_popup_hide combo_box_set_display combo_box_set_title combo_box_set_tearable combo_box_set_arrow_sensitive combo_box_set_arrow_relief
swami/docs/reference/Makefile.am0000644000175000017500000000003410071360410016765 0ustar alessioalessioSUBDIRS = libswami swamigui swami/docs/reference/libswami/0000755000175000017500000000000011716016666016565 5ustar alessioalessioswami/docs/reference/libswami/libswami-sections.txt0000644000175000017500000002513711461404311022753 0ustar alessioalessio
SwamiControlMidi SwamiControlMidi SwamiControlMidi swami_control_midi_new swami_control_midi_set_callback swami_control_midi_send swami_control_midi_transmit SWAMI_CONTROL_MIDI SWAMI_IS_CONTROL_MIDI SWAMI_TYPE_CONTROL_MIDI swami_control_midi_get_type SWAMI_CONTROL_MIDI_CLASS SWAMI_IS_CONTROL_MIDI_CLASS
SwamiPlugin SwamiPluginInfo SwamiPluginInitFunc SwamiPluginExitFunc SwamiPluginSaveXmlFunc SwamiPluginLoadXmlFunc SwamiPlugin SwamiPlugin SWAMI_PLUGIN_MAGIC SWAMI_PLUGIN_INFO swami_plugin_add_path swami_plugin_load_all swami_plugin_load swami_plugin_load_absolute swami_plugin_load_plugin swami_plugin_is_loaded swami_plugin_find swami_plugin_get_list swami_plugin_save_xml swami_plugin_load_xml SWAMI_PLUGIN SWAMI_IS_PLUGIN SWAMI_TYPE_PLUGIN swami_plugin_get_type SWAMI_PLUGIN_CLASS SWAMI_IS_PLUGIN_CLASS
SwamiControlQueue SwamiControlQueueTestFunc SwamiControlQueue SwamiControlQueue swami_control_queue_new swami_control_queue_add_event swami_control_queue_run swami_control_queue_set_test_func SWAMI_CONTROL_QUEUE SWAMI_IS_CONTROL_QUEUE SWAMI_TYPE_CONTROL_QUEUE swami_control_queue_get_type SWAMI_CONTROL_QUEUE_CLASS SWAMI_IS_CONTROL_QUEUE_CLASS
SwamiControlFunc SwamiControlFuncDestroy SwamiControlFunc SwamiControlFunc SWAMI_CONTROL_FUNC_DATA swami_control_func_new swami_control_func_assign_funcs SWAMI_CONTROL_FUNC SWAMI_IS_CONTROL_FUNC SWAMI_TYPE_CONTROL_FUNC swami_control_func_get_type SWAMI_CONTROL_FUNC_CLASS SWAMI_IS_CONTROL_FUNC_CLASS
SwamiMidiDevice SwamiMidiDevice SwamiMidiDevice swami_midi_device_open swami_midi_device_close swami_midi_device_get_control SWAMI_MIDI_DEVICE SWAMI_IS_MIDI_DEVICE SWAMI_TYPE_MIDI_DEVICE swami_midi_device_get_type SWAMI_MIDI_DEVICE_CLASS SWAMI_IS_MIDI_DEVICE_CLASS
SwamiControl SwamiControlGetSpecFunc SwamiControlSetSpecFunc SwamiControlGetValueFunc SwamiControlSetValueFunc SwamiControl SwamiControl SwamiControlFlags SWAMI_CONTROL_FLAGS_USER_MASK SWAMI_CONTROL_SENDRECV SWAMI_CONTROL_UNUSED_FLAG_SHIFT SwamiControlConnPriority SWAMI_CONTROL_CONN_PRIORITY_MASK SWAMI_CONTROL_CONN_DEFAULT_PRIORITY_VALUE SwamiControlConnFlags SWAMI_CONTROL_CONN_BIDIR_INIT SWAMI_CONTROL_CONN_BIDIR_SPEC_INIT swami_control_new swami_control_connect swami_control_connect_transform swami_control_connect_item_prop swami_control_disconnect swami_control_disconnect_all swami_control_disconnect_unref swami_control_get_connections swami_control_set_transform swami_control_get_transform swami_control_set_flags swami_control_get_flags swami_control_set_queue swami_control_get_queue swami_control_get_spec swami_control_set_spec swami_control_sync_spec swami_control_transform_spec swami_control_set_value_type swami_control_get_value swami_control_get_value_native swami_control_set_value swami_control_set_value_no_queue swami_control_set_event swami_control_set_event_no_queue swami_control_set_event_no_queue_loop swami_control_transmit_value swami_control_transmit_event swami_control_transmit_event_loop swami_control_do_event_expiration swami_control_new_event SWAMI_CONTROL SWAMI_IS_CONTROL SWAMI_TYPE_CONTROL swami_control_get_type SWAMI_CONTROL_CLASS SWAMI_IS_CONTROL_CLASS SWAMI_CONTROL_GET_CLASS
SwamiControlHub SwamiControlHub SwamiControlHub swami_control_hub_new SWAMI_CONTROL_HUB SWAMI_IS_CONTROL_HUB SWAMI_TYPE_CONTROL_HUB swami_control_hub_get_type SWAMI_CONTROL_HUB_CLASS SWAMI_IS_CONTROL_HUB_CLASS
SwamiLock SwamiLock SwamiLock SWAMI_LOCK_WRITE SWAMI_UNLOCK_WRITE SWAMI_LOCK_READ SWAMI_UNLOCK_READ swami_lock_set_atomic swami_lock_get_atomic SWAMI_LOCK SWAMI_IS_LOCK SWAMI_TYPE_LOCK swami_lock_get_type SWAMI_LOCK_CLASS SWAMI_IS_LOCK_CLASS
SwamiRoot SwamiRoot SwamiRoot swami_root_new swami_root_get_patch_items swami_get_root swami_root_get_objects swami_root_add_object swami_root_new_object swami_root_prepend_object swami_root_append_object swami_root_insert_object_before swami_root_patch_load swami_root_patch_save SWAMI_ROOT SWAMI_IS_ROOT SWAMI_TYPE_ROOT swami_root_get_type SWAMI_ROOT_CLASS SWAMI_IS_ROOT_CLASS
SwamiWavetbl SwamiWavetbl SwamiWavetbl swami_wavetbl_get_virtual_bank swami_wavetbl_set_active_item_locale swami_wavetbl_get_active_item_locale swami_wavetbl_open swami_wavetbl_close swami_wavetbl_get_control swami_wavetbl_load_patch swami_wavetbl_load_active_item swami_wavetbl_check_update_item swami_wavetbl_update_item SWAMI_WAVETBL SWAMI_IS_WAVETBL SWAMI_TYPE_WAVETBL swami_wavetbl_get_type SWAMI_WAVETBL_CLASS SWAMI_IS_WAVETBL_CLASS SWAMI_WAVETBL_GET_CLASS
SwamiContainer SwamiContainer SwamiContainer swami_container_new SWAMI_CONTAINER SWAMI_IS_CONTAINER SWAMI_TYPE_CONTAINER swami_container_get_type SWAMI_CONTAINER_CLASS SWAMI_IS_CONTAINER_CLASS
SwamiPropTree SwamiPropTreeNode SwamiPropTreeValue SwamiPropTree SwamiPropTree swami_prop_tree_new swami_prop_tree_set_root swami_prop_tree_prepend swami_prop_tree_append swami_prop_tree_insert_before swami_prop_tree_remove swami_prop_tree_remove_recursive swami_prop_tree_replace swami_prop_tree_get_children swami_prop_tree_object_get_node swami_prop_tree_add_value swami_prop_tree_remove_value SWAMI_PROP_TREE SWAMI_IS_PROP_TREE SWAMI_TYPE_PROP_TREE swami_prop_tree_get_type SWAMI_PROP_TREE_CLASS SWAMI_IS_PROP_TREE_CLASS
SwamiControlValue SwamiControlValue SwamiControlValue swami_control_value_new swami_control_value_assign_value swami_control_value_alloc_value SWAMI_CONTROL_VALUE SWAMI_IS_CONTROL_VALUE SWAMI_TYPE_CONTROL_VALUE swami_control_value_get_type SWAMI_CONTROL_VALUE_CLASS SWAMI_IS_CONTROL_VALUE_CLASS
SwamiLoopResults SwamiLoopResults SwamiLoopResults swami_loop_results_new swami_loop_results_get_values SWAMI_LOOP_RESULTS SWAMI_IS_LOOP_RESULTS SWAMI_TYPE_LOOP_RESULTS swami_loop_results_get_type
SwamiControlProp SwamiControlProp SwamiControlProp swami_get_control_prop swami_get_control_prop_by_name swami_control_prop_connect_objects swami_control_prop_connect_to_control swami_control_prop_connect_from_control swami_control_prop_new swami_control_prop_assign swami_control_prop_assign_by_name SWAMI_CONTROL_PROP SWAMI_IS_CONTROL_PROP SWAMI_TYPE_CONTROL_PROP swami_control_prop_get_type SWAMI_CONTROL_PROP_CLASS SWAMI_IS_CONTROL_PROP_CLASS
SwamiLoopFinder SwamiLoopFinder SwamiLoopFinder swami_loop_finder_new swami_loop_finder_full_search swami_loop_finder_verify_params swami_loop_finder_find swami_loop_finder_get_results SWAMI_LOOP_FINDER SWAMI_IS_LOOP_FINDER SWAMI_TYPE_LOOP_FINDER swami_loop_finder_get_type
SwamiEvent_ipatch SWAMI_TYPE_EVENT_ITEM_ADD SWAMI_VALUE_HOLDS_EVENT_ITEM_ADD SWAMI_TYPE_EVENT_ITEM_REMOVE SWAMI_VALUE_HOLDS_EVENT_ITEM_REMOVE SWAMI_TYPE_EVENT_PROP_CHANGE SWAMI_VALUE_HOLDS_EVENT_PROP_CHANGE SwamiEventItemAdd swami_event_item_add_get_type swami_event_item_remove_get_type swami_event_prop_change_get_type swami_event_item_add_copy swami_event_item_add_free swami_event_item_remove_new swami_event_item_remove_copy swami_event_item_remove_free swami_event_prop_change_new swami_event_prop_change_copy swami_event_prop_change_free
libswami swami_init swami_patch_prop_title_control swami_patch_add_control swami_patch_remove_control
version SWAMI_VERSION SWAMI_VERSION_MAJOR SWAMI_VERSION_MINOR SWAMI_VERSION_MICRO swami_version
util swami_util_get_child_types swami_util_new_value swami_util_free_value swami_util_midi_note_to_str swami_util_midi_str_to_note
SwamiLog SWAMI_ERROR SwamiError swami_error_quark swami_log_if_fail SWAMI_DEBUG SWAMI_INFO SWAMI_PARAM_ERROR SWAMI_CRITICAL
SwamiMidiEvent SwamiMidiEvent SwamiMidiEventNote SwamiMidiEventControl SWAMI_TYPE_MIDI_EVENT SwamiMidiEventType SWAMI_MIDI_CC_BANK_MSB SWAMI_MIDI_CC_MODULATION SWAMI_MIDI_CC_VOLUME SWAMI_MIDI_CC_PAN SWAMI_MIDI_CC_EXPRESSION SWAMI_MIDI_CC_BANK_LSB SWAMI_MIDI_CC_SUSTAIN SWAMI_MIDI_CC_REVERB SWAMI_MIDI_CC_CHORUS SWAMI_MIDI_RPN_BEND_RANGE SWAMI_MIDI_RPN_MASTER_TUNE swami_midi_event_get_type swami_midi_event_new swami_midi_event_free swami_midi_event_copy swami_midi_event_set swami_midi_event_note_on swami_midi_event_note_off swami_midi_event_bank_select swami_midi_event_program_change swami_midi_event_bend_range swami_midi_event_pitch_bend swami_midi_event_control swami_midi_event_control14 swami_midi_event_rpn swami_midi_event_nrpn
SwamiObject SwamiObjectPropBag SwamiRank SwamiObjectFlags swami_object_propbag_quark swami_type_set_rank swami_type_get_rank swami_type_get_children swami_type_get_default swami_object_set_default swami_object_get_by_name swami_object_find_by_type swami_object_get_by_type swami_object_get_valist swami_object_get_property swami_object_get swami_object_set_valist swami_object_set_property swami_object_set swami_find_object_property swami_list_object_properties swami_object_get_flags swami_object_set_flags swami_object_clear_flags swami_object_set_origin swami_object_get_origin
SwamiControlEvent SwamiControlEvent SWAMI_TYPE_CONTROL_EVENT SWAMI_CONTROL_EVENT_VALUE swami_control_event_get_type swami_control_event_new swami_control_event_free swami_control_event_duplicate swami_control_event_transform swami_control_event_stamp swami_control_event_set_origin swami_control_event_ref swami_control_event_unref swami_control_event_active_ref swami_control_event_active_unref
SwamiParam SwamiValueTransform swami_param_get_limits swami_param_set_limits swami_param_type_has_limits swami_param_convert swami_param_convert_new swami_param_type_transformable swami_param_type_transformable_value swami_param_transform swami_param_transform_new swami_param_type_from_value_type
swami/docs/reference/libswami/Makefile.am0000644000175000017500000000572511461404311020613 0ustar alessioalessio## Process this file with automake to produce Makefile.in # We require automake 1.6 at least. AUTOMAKE_OPTIONS = 1.6 # This is a blank Makefile.am for using gtk-doc. # Copy this to your project's API docs directory and modify the variables to # suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples # of using the various options. # The name of the module, e.g. 'glib'. DOC_MODULE=libswami # The top-level SGML file. You can change this if you want to. DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml # The directory containing the source code. Relative to $(srcdir). # gtk-doc will search all .c & .h files beneath here for inline comments # documenting the functions and macros. DOC_SOURCE_DIR=$(top_srcdir)/src/libswami # Extra options to pass to gtkdoc-scangobj. Not normally needed. SCANGOBJ_OPTIONS= # Extra options to supply to gtkdoc-scan. # e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" SCAN_OPTIONS= # Extra options to supply to gtkdoc-mkdb. # e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml MKDB_OPTIONS=--sgml-mode --output-format=xml # Extra options to supply to gtkdoc-mktmpl # e.g. MKTMPL_OPTIONS=--only-section-tmpl MKTMPL_OPTIONS= # Extra options to supply to gtkdoc-fixref. Not normally needed. # e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html FIXXREF_OPTIONS= # Used for dependencies. The docs will be rebuilt if any of these change. HFILE_GLOB=$(top_srcdir)/src/libswami/*.h CFILE_GLOB=$(top_srcdir)/src/libswami/*.c # Header files to ignore when scanning. IGNORE_HFILES=swami_priv.h marshals.h \ builtin_enums.h i18n.h SwamiState_types.h # Images to copy into HTML directory. # e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png HTML_IMAGES= # Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). # e.g. content_files=running.sgml building.sgml changes-2.0.sgml content_files= # SGML files where gtk-doc abbrevations (#GtkWidget) are expanded # These files must be listed here *and* in content_files # e.g. expand_content_files=running.sgml expand_content_files= # CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. # Only needed if you are using gtkdoc-scangobj to dynamically query widget # signals and properties. # e.g. INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) # e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) INCLUDES = -I$(top_srcdir)/src @GOBJECT_CFLAGS@ @LIBINSTPATCH_CFLAGS@ GTKDOC_LIBS = @GOBJECT_LIBS@ @LIBINSTPATCH_LIBS@ -lm \ $(top_srcdir)/src/libswami/libswami.la # This includes the standard gtk-doc make rules, copied by gtkdocize. include $(top_srcdir)/gtk-doc.make # Other files to distribute # e.g. EXTRA_DIST += version.xml.in EXTRA_DIST += # Files not to distribute # for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types # for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt #DISTCLEANFILES += # Comment this out if you want your docs-status tested during 'make check' #TESTS = $(GTKDOC_CHECK) swami/docs/reference/libswami/libswami.types0000644000175000017500000000106011461404311021440 0ustar alessioalessioswami_control_midi_get_type swami_event_item_add_get_type swami_event_item_remove_get_type swami_event_prop_change_get_type swami_plugin_get_type swami_control_queue_get_type swami_control_func_get_type swami_midi_device_get_type swami_control_get_type swami_control_hub_get_type swami_lock_get_type swami_root_get_type swami_wavetbl_get_type swami_container_get_type swami_prop_tree_get_type swami_midi_event_get_type swami_control_value_get_type swami_loop_results_get_type swami_control_prop_get_type swami_loop_finder_get_type swami_control_event_get_type swami/docs/reference/libswami/libswami-docs.sgml0000644000175000017500000000443511461404311022175 0ustar alessioalessio ]> libswami Reference Manual For libswami 2.0.0. The latest version of this documentation can be found on-line at http://swami.sourceforge.net/api/libswami/. General Type independent control/event network Misc Object Hierarchy API Index swami/docs/manual/0000755000175000017500000000000011716016666014275 5ustar alessioalessioswami/docs/manual/Swami-Manual.sgml0000644000175000017500000000151107676126120017447 0ustar alessioalessio
Swami Manual Josh Green
jgreen@users.sourceforge.net
0.1 2001-02-01 jmg Initial document created This is the Swami manual. It contains information on using Swami and some brief info on patch files and MIDI as well as links to other information resources.
swami/TODO.tasks0000644000175000017500000002264310600216501013670 0ustar alessioalessio CRAM read/write Preferences FluidSynth panel Multi-level paste (Sample -> Preset) External sample editing Sample cut/crop Sample dicer Highlight ranges on mouse over and status bar Use real unit value for effect controls Default lower view to SwamiPanel interfaces SoundFont sample start/end ranges GigaSampler dimension editor Patch item interface selection buttons Box select note/velocity ranges, move as group and set as group Highlight piano buttons on mouse over Integrate sample tuner into sample editor Add fundamental tuning waveform playback Implement loops as canvas ranges Loop finder built into sample viewer Invalid value detection (duplicate names, invalid loops, etc) Interface editor property toggle Error output dialog Re-implement save dialog Append file extensions on save (if not specified) Ignore key presses with piano with certain widgets Don't play piano when typing in text entries or views. Add "Load Samples" menu item to Samples branch in tree Keyboard octave selector and root note selector above piano Smarter keyboard piano key mapping Re-enable save dirty flag check on exit Some right click menu items wrong Copy, Close and Delete are on menu when they shouldn't be sometimes. Multi-item options should check all items in selection. Search position/deactivation when tree is clicked Prevent files from being opened multiple times Handle stereo samples correctly with SoundFont files SF2IZone loop override negative values broken Piano crashes when out of view and note is played Changing preset bank/program not resorting New Zone doesn't work Remove New Zone option or allow empty zones that need samples assigned to them. swami/ChangeLog0000644000175000017500000022005011075036701013627 0ustar alessioalessio2008-10-13 Josh Green * src/python/swami.defs: Fixed libswami Python binding. * src/swamigui/SwamiguiSplits.c: Fixed crash bug with span Middle click move operation (thanks to Ebrahim Mayat for reporting this). Fixed Middle click move status bar updates. 2008-10-11 Josh Green * README.OSX: Update from Ebrahim Mayat. * src/swamigui/swami-2.glade: Re-saved swami-2.glade using glade 3.4.5. 2008-10-05 Josh Green * src/swamigui/SwamiguiSplits.c: Added support for moving multiple selected spans and root notes (depending on move mode). 2008-09-26 Josh Green * src/swamigui/SwamiguiSplits.c: Added ALT click drag functionality for setting low span handle, root note or upper span handle depending on mouse button pressed. Improved drag logic. 2008-09-25 Josh Green * po/POTFILES.in: Patch from Henry Kroll to remove a couple of files which were recently deleted. * src/libswami/SwamiObject.c: Removed some unused functions. * src/swamigui/SwamiguiSplits.c: Now using GTK for widget construction, added root note indicators, now using anti-aliased canvases, combined several instances of width/height item resize code into a single function called swamigui_splits_update_entries(), now using buttons for Note/Velocity mode selection instead of a notebook, placed a "Shift Mode" drop down widget for future selection of what items get shifted with the middle mouse button (spans, root notes or both), SwamiguiSplitsEntry replaced SplitBag and is now part of the public API (although private), span and root note controls now only created when the appropriate API function is called to get its control, likely some other improvements. * src/swamigui/swami-2.glade: Added SwamiguiSplits widget. 2008-08-18 Josh Green * Removed SwamiguiHPaned.[ch], SwamiguiVPaned.[ch], SwamiguiLayout.[ch], SwamiguiSelector.[ch], SwamiguiSwitcher.[ch], SwamiguiTreeStorePref.[ch] as they weren't providing necessary functionality. * configure.ac: Required glib and gobject version now set to 2.12. * src/glade/Makefile.am: Removed libgladeswamigui (just uses libswamigui now). * src/glade/swamigui.xml: Set library to "swamigui-2.0" other minor changes. * src/libswami/SwamiControl.c: (swami_control_sync_spec): Now returns boolean value to indicate if conversion was successful. * src/libswami/SwamiParam.c: (swami_param_type_has_limits): New function. (swami_param_convert_new): No longer prints conversion errors. (swami_param_type_transformable): New function. (swami_param_type_transformable_value): New function. * src/libswami/swami_priv.h: Removed macros related to older glib support. * src/libswami/value_transform.c: New file which contains additional GValue conversion functions (string to int and string to double currently). * src/plugins/fluidsynth.c: Removed "reverb-enable" and "chorus-enable" properties, since they are now dynamically created as FluidSynth settings properties. Enumeration strings are introspected and a "-options" property is installed. String enumeration types "yes/no" are created as standard boolean properties. * src/plugins/fluidsynth_gui.c: Added FluidSynth preferences. Updated "reverb-enable" and "chorus-enable" to new property names "synth-reverb-active" and "synth-chorus-active". * src/swamigui/SwamiguiControl.c: (swamigui_control_new_for_widget_full): Flags and enum types are reduced to G_TYPE_FLAGS and G_TYPE_ENUM during widget handler comparison. Improved widget handler comparison to find best match. (swamigui_control_glade_prop_connect): Allow for ":blah" postfix to auto glade property names to work around duplicate glade names. * src/swamigui/SwamiguiControl_widgets.c: Added GtkComboBoxEntry handler, GtkFileChooserButton handler and GtkComboBox handlers (string, enum and gtype). (adjustment_control_handler): "digits" now assigned and "spec-changed" watched under the property conditions. (entry_control_handler): Control parameter spec conversion now performed. * src/swamigui/SwamiguiMenu.c: Added Python script editor to Tools menu. Some i18n updates. Added FluidSynth restart item until it is managed by the FluidSynth plugin. * src/swamigui/SwamiguiModEdit.c: Removed "item" property, now using only "item-selection" parameter and supports generic IpatchSF2ModItem interface. * src/swamigui/SwamiguiMultiList.c: Renamed swamigui_multi_list_set_items() to swamigui_multi_list_set_selection(). * src/swamigui/SwamiguiPanelSelector.c: Renamed swamigui_panel_selector_set_items() and swamigui_panel_selector_get_items() to swamigui_panel_selector_set_selection() and swamigui_panel_selector_get_selection(). * src/swamigui/SwamiguiPref.[ch]: New preferences registration and widget. * src/swamigui/SwamiguiRoot.c: Added default piano key mapping strings, Now using a prop handler function for IpatchSF2 types to provide custom creation date functionality (push button for current date). Added glade_module_register_widgets() function, so libswamigui can be used as a glade module. Removed "layout" parameter. Added main_window field to SwamiguiRoot. Updated swamigui_root_init() code to create wavetable device, create main window, display splash image if enabled and swami tips. (swamigui_root_create_main_window): Code in swamigui_create_default_session() moved here. Removed pref_store field from SwamiguiRoot object and added main_window, tree, splits, panel_selector and wavetbl. * src/swamigui/SwamiguiSampleEditor.c: Renamed swamigui_sample_editor_set_items() to swamigui_sample_editor_set_selection() and swamigui_sample_editor_get_items() to swamigui_sample_editor_get_selection(). * src/swamigui/SwamiguiSplits.c: Renamed swamigui_splits_set_items() to swamigui_splits_set_selection(), swamigui_splits_get_items() to swamigui_splits_get_selection() and swamigui_splits_set_selection() to swamigui_splits_select_items(). * src/swamigui/util.c: Added swamigui_util_glade_lookup_nowarn() to not warn if a Glade widget can't be found. * src/swamigui/swami-2.glade: Lots of GUI changes. New preferences interfaces, more interfaces using PROP:: style widget/property auto connection. 2008-03-31 Josh Green * autogen.sh: Added gtkdocize. * configure.ac: Now requiring librsvg-2.0 >= 2.8 and GTK_DOC_CHECK(1.9). * Makefile.am: Added glade sub directory (Swami widgets in glade!). * plugins/Makefile.am: Now building fluidsynth_gui.c. * plugins/fftune_gui.c: Now implements SwamiguiPanel interface. * plugins/fluidsynth.c: Removed left over disabled fixed modulators, reverb and chorus names are now character arrays, reverb and chorus now reverb_params and chorus_params, added reverb_presets and chorus_presets arrays and default presets for both, added reverb-enable and reverb-preset properties (removed reverb-mode), added chorus-enable and chorus-preset (removed chorus-mode), lots of other changes to reverb/chorus parameters and presets. * plugins/fluidsynth_gui.c: New FluidSynth GUI with knobs. * src/swamigui/SwamiguiControl.c: Removed swamigui_control_object_create_widgets(), swamigui_control_object_connect_widgets(), swamigui_control_object_disconnect_widgets() and related functions. Added swamigui_control_glade_prop_connect() which basically replaces above functions, but allows custom glade interfaces whose widgets are automatically connected to object properties. * src/swamigui/SwamiguiKnob.[ch]: New SVG based cairo knob widget. * src/swamigui/SwamiguiMenu.c: Added place holder for preferences. * src/swamigui/SwamiguiModEdit.c: Now implements SwamiguiPanel interface, updated to GtkComboBox widgets. * src/swamigui/SwamiguiPanel.c: Renamed swamigui_panel_get_info() to swamigui_panel_type_get_info(), renamed swamigui_panel_test() to swamigui_panel_type_check_selection(), added swamigui_panel_get_types_in_selection() helper function. * src/swamigui/SwamiguiPanel.h: Added SwamiguiPanelCheckFunc method function definition. * src/swamigui/SwamiguiPanelSelector.[ch]: New panel selector notebook widget. Yeeeeee haaa! * src/swamigui/SwamiguiProp.[ch]: More useful now as it has a registry for Glade widgets or handler functions to create interfaces for specific object types. * src/swamigui/SwamiguiRoot.c: New FluidSynth interface loaded, some layout changes of main window. * src/swamigui/SwamiguiSampleEditor.[ch]: Implements SwamiguiPanel interface now. swamigui_sample_editor_register_handler() now takes a SwamiguiPanelCheckFunc() for determining when an item selection is valid for a given sample editor handler. * src/swamigui/SwamiguiSplits.[ch]: Updated to support any item type with a "note-range" or "velocity-range" property. * src/swamigui/swami-2.glade: Lots of GUI changes. * src/swamigui/images/knob.svg: New Knob SVG image. * src/glade: New directory for Swami glade catalog widgets (use Swami widgets directly in Glade). * src/glade/glade-swamigui.c: Init function of libswamigui. * src/glade/swamigui.xml: Glade catalog description file (only SwamiguiKnob is defined for the moment). 2007-12-02 Josh Green * configure.ac: Removed detection for libxml (will use glib XML functions), removed --enable-build-dir option and added --enable-developer as a replacement which will also include other developer functionality. * swami.anjuta: New Anjuta project file. * swami.prj: Removed old Anjuta project file. * src/libswami/SwamiXml.[ch]: Removed, will be replaced by libinstpatch XML object pickling. Also removed all XML interfaces from other objects. * src/libswami/SwamiXmlObject.[ch]: Removed and probably not needed. * src/libswami/SwamiLog.h: Added SWAMI_ERROR_IO. * src/libswami/SwamiRoot.c (swami_root_patch_load): Added err parameter. (swami_root_patch_save): Added err parameter. * src/python/Makefile.am: Added separate targets for swami.c and swamigui.c and include appropriate PyGtk .def dependencies. * src/python/swamigui.override: Added additional import dependencies. * src/swamigui/SwamiguiMultiSave.[ch]: Added new multi-file save dialog. * src/swamigui/help.c (swamigui_help_about): Ticket #38 - Can now close the about dialog. * src/swamigui/patch_funcs.c: Using new multi file save dialog for saving patch files, added _() i18n macro to some strings. 2007-05-10 Josh Green * Default value for GType properties is now G_TYPE_NONE. * src/libswami/swami_priv.h: Added GTYPE_PARAM_SUPPORT for checking existence of GType GParamSpec support (glib 2.10.0). * src/swamigui/SwamiguiRoot.c: Fixed issue with storage of GType in "default-patch-type" property of SwamiguiRoot, which would affect 64 bit platforms. Now using GType GParamSpec if available (Glib 2.10.0) with fallback to gulong (instead of guint). * src/swamigui/SwamiguiTree.c: Added conditional for use of GTK 2.10.0 only function gdk_atom_intern_static_string(). 2007-04-20 Josh Green * configure.ac: Added --disable-python configure option. * swami-2.png: Updated with new blurry feature of Inkscape, to give some software edge effects. * src/swamigui/SwamiguiDnd.h: Changed SWAMIGUI_DND_WIDGET_INFO and SWAMIGUI_DND_WIDGET_NAME to SWAMIGUI_DND_OBJECT_INFO and SWAMIGUI_DND_OBJECT_NAME respectively, since they will be used for passing arbitrary GObject's within Swami. * src/swamigui/SwamiguiSampleEditor.c: Added buttons for sample cut, crop and new from selection. Added selection support using marker 0. Initial function stubs are there for sample operation buttons, but don't do anything yet. Added swamigui_sample_editor_set_marker() function. * src/swamigui/SwamiguiStatusbar.c: Added "default-timeout" property which is used for messages which use the SWAMIGUI_STATUSBAR_TIMEOUT_DEFAULT value. Added swamigui_statusbar_printf() for added convenience in sending executed operation status messages to status bar. * src/swamigui/SwamiguiTree.c: Added support for paste operations using drag and drop and high level tree DnD API. Unfortunately this doesn't currently support multiple item drag and drop, so only 1 item at a time can be pasted using this method (plan to hack in code to implement custom multi-item drag and drop, or wait for GTK support). 2007-03-21 Josh Green * src/swamigui/SwamiguiSampleEditor.c: Moved zoom/scroll canvas functionality to a new separate object SwamiguiCanvasMod. Loop cross section viewer is now also zoomable. Added swamigui_sample_editor_loop_zoom() function to set zoom of loop view. * src/swamigui/SwamiguiTree.c: When item selection is assigned to tree it now expands all parents of selected items and makes the first item in view. * src/swamigui/patch_funcs.c: swamigui_new_item() now sets new item as current selection. swamigui_cb_load_samples_response() now sets current item selection to added samples. * src/swamigui/SwamiguiItemMenu_actions.c: "copy" action now excluded for virtual container types. "load-samples" not available for virtual containers containing samples. "new" available only for instrument and program categories now. * src/swamigui/SwamiguiRoot.c: Tree "selection" now connected bi-directionally to swamigui_root "selection". * src/swamigui/marshals.list: New file, marshals for GUI. * src/swamigui/SwamiguiCanvasMod.[ch]: New canvas zoom/scroll modulator object, so canvas zoom/scroll can be managed in a centralized fashion. New features include: mouse wheel scrolling, acceleration curve equations for wheel and snap zoom/scrolling, smooth wheel operation (scrolling continues for a short time after last wheel event). * src/libswami/SwamiPropTree.c: Properties in prop tree now connected bi-directionally when supported. 2007-02-18 Josh Green * src/swamigui/icons.c: Fixed setting of window default icon name. * src/swamigui/SwamiguiRoot.c: Making sure that we are calling all GUI get_type functions, adding of selector options is handled better for optional components, added global enable variables for Python and plugins so command line arguments can disable them. * src/swamigui/SwamiguiItemMenu.c: Moved one time init stuff to an internal init function instead of the class initializer. * src/swamigui/swami_python.c: Added swamigui_python_is_initialized() to check if Python binding is active. * src/swamigui/main.c: Added -y switch to disable Python binding, plugin disable switch -p should now be working. 2007-02-15 Josh Green * Modified many version sensitive file names to include 2.0 version indicator so future major revisions can be parallel installable (including swami-0.9.xx). * src/plugins/fluidsynth.c: Added initial real time effect control support (currently only works with IpatchSF2Sample items), locking of wavetable object was moved to FluidSynth driver instead of SwamiWavetbl for finer control. * src/swamigui/SwamiguiSampleEditor.c: New range based markers in a bar above sample view, sample loop finder now integrated with sample viewer, started sample selection support (not yet finished). * src/swamigui/SwamiguiLoopFinder.[ch]: Now only the GUI portion of the finder. The smarts have been moved to libswami. * src/swamigui/icons.c: Added loop none/standard/release icons, removed swami icon (moved to top source folder). * src/swamigui/util.c: Added swamigui_util_unit_rgba_color_get_type() to create a new unit type for guint properties to indicate they are RGBA color values (SWAMIGUI_UNIT_RGBA_COLOR). * src/swamigui/SwamiguiSampleCanvas.c: Properties for color values of sample canvas. Modified swamigui_sample_canvas_xpos_to_sample() and swamigui_sample_canvas_sample_to_xpos() to still return a value but also return info on whether the calculated value is valid. * src/swamigui/SwamiguiPiano.c: Added properties for colors. * src/swamigui/SwamiguiControl.c: Simplified parameters of swamigui_control_new_for_widget() and created swamigui_control_new_for_widget_full() with the previous set. Added new swamigui_control_prop_connect_widget() function. * src/swamigui/swami_python.c: Now calling PySys_SetArgv() in _swamigui_python_init() function. * src/libswami/SwamiWavetbl.c: Locking of SwamiWavetbl object removed from most class functions. Its up to the derived class to do its own locking (more flexible). * src/libswami/SwamiControlProp.c: Added new swami_control_prop_connect_to_control() and swami_control_prop_connect_from_control() for added convenience. * src/libswami/SwamiLoopFinder.[ch]: Separated from GUI and moved to its own stand alone object. 2007-01-09 Josh Green * src/swamigui/SwamiguiSampleEditor.c: Speeded up zoom/scroll quite a bit, should be controllable via properties/prefs, fixed problem where zoom value of sample view was quite screwed up on initial display, removed "goto loop end point" buttons (will replace with a canvas loop scrolly thingy). * src/swamigui/SwamiguiTree.c: Added way cool search feature, not yet finished though. * src/swamigui/SwamiguiMenu.c: Setting recent chooser limit to unlimited since the list gets truncated before being filtered (bug in GTK?). * src/swamigui/SwamiguiStatusbar.[ch]: A new statusbar! * src/swamigui/SwamiguiProp.c: Now displays "Item not selected" if property interface is being used but no item is active, fixed an issue with the GtkAdjustment related SwamiControl in SwamiguiControl_widgets.c which broke ranges of scale widgets. * src/swamigui/SwamiguiPiano.c: Re-worked drawing routines and such so that each key has an equal amount of active space (so that the spans don't look so funky), now sends statusbar info to indicate what note is being played or the mouse is over (including velocity). * src/swamigui/SwamiguiSpans.c: Spans are now equal distant for each note, sending statusbar messages to show current span range (on mouse over and when setting/moving). * src/swamigui/SwamiguiItemMenu_actions.c: Added Find and Find Next item menu options and hot keys. * src/swamigui/SwamiguiRoot.c: A little hack to get root "selection" property to always be set to a IpatchList selection (even if its empty) so that the "origin" object is availabe (SwamiguiTree for example), statusbar getting visiously packed. * src/swamigui/SwamiguiRoot.h: Added "statusbar" to SwamiguiRoot instance. * src/swamigui/SwamiguiControl_widgets.c: GtkAdjustment GParamSpec wasn't being handled correctly, breaking SwamiguiProp scale widgets. * src/libswami/util.c: Changed swami_util_midi_note_to_str() to use octave -2 for the first C (as Rosegarden does). Forgot to update swami_util_midi_str_to_note though, added to TODO list. 2006-12-28 Josh Green * src/swamigui/SwamiguiMenu.c: Patch icons are now being used for New.. menu items. * src/swamigui/SwamiguiTreeStorePatch.c: Implemented a work around for SwamiContainer, since it can contain children of different item types. * src/swamigui/SwamiguiPiano.c: Fixed bug which caused mouse grab to not be released when playing the piano with the mouse off the right hand side. * src/swamigui/SwamiguiSplits.c: Velocity mode of the splits widget appears to be working, fixed bug which caused default handler to not initialize correctly in some cases. 2006-12-22 Josh Green * Lots of envelope icons added in src/swamigui/images. * src/swamigui/SwamiguiPanelSF2Gen.[ch]: New - SoundFont generator control interface (oooo puuurrrtty! ;) * src/swamigui/SwamiguiGenGraph.[ch]: Killed, it will be replaced with a generic envelope graph editor. * src/swamigui/SwamiguiGenView.[ch]: Murdered, will replace with a generic property view. * src/swamigui/SwamiguiGenCtrl.[ch]: Replaced by SwamiguiPanelSF2Gen.[ch]. * src/libswami/SwamiStateItem.[ch]: Moving to libInstPatch. * src/libswami/SwamiStateGroup.[ch]: Moving to libInstPatch. * src/libswami/SwamiState_types.[ch]: Moving to libInstPatch. * src/libswami/SwamiState.[ch]: Moving to libInstPatch. * src/libswami/SwamiControlProp.c: New and improved! Updates for new IpatchItem notify system. * src/swamigui/SwamiguiPanel.c: Actually does something now! * src/swamigui/icons.[ch]: New envelope icons! * src/swamigui/SwamiguiTreeStorePatch.c: Various bug fixes that were causing items to not be inserted correctly for container sorted items. * src/swamigui/SwamiguiSplits.c: Beginning of tabbed interface for note and velocity range switching (not done). * src/swamigui/SwamiguiRoot.c: Updated for changes to property/container notify system (moved to libinstpatch). * src/swamigui/SwamiguiSpinScale.c: Some improvements. * src/libswami/SwamiControl.c: Lots of new goodies to make things more complicated and fun including new value transform functions for converting values for a specific connection, swami_control_connect_item_prop() for ultra convenient property connections (with unit conversion!), lots of other crazy crap, I sure hope SwamiControl doesn't become more of a nightmare than it is! Still, it does kick some ass. * Tons of other cool improvements and changes which I don't feel like writing about.. 2006-08-31 Josh Green * src/swamigui/SwamiguiTree.c: Added external file drag and drop support TO the instrument tree. * src/swamigui/SwamiguiMenu.c: Changes to recent manager list in menu (not sure what exactly, but seems to be working well ;). * src/swamigui/icons.h: Reminded by Ebrahim Mayat that OS X does not like variables declared in headers without extern (causes duplicate symbols error during link). * src/swamigui/SwamiguiDnd.h: Added new SWAMIGUI_DND_URI_INFO type for use in external file drag and drop. 2006-07-10 Josh Green * src/plugins/fluidsynth.c: Reverb and Chorus parameters now update synth. * src/swamigui/SwamiguiSampleEditor.c: Removed vertical scaling range control and related non-functioning code. * src/swamigui/SwamiguiTree.c: Right click menu can now be popped via keyboard (popup_menu GtkWidget method hooked), private function swamigui_tree_real_set_store() added to assign active tree store, right click on item not part of list causes right clicked item to become selected, swamigui_tree_get_selection_single() no longer adds a reference to the returned item (the single threaded GUI policy), removed rclick_item field and corresponding functions, tree now assigns itself as the origin (swami_object_set_origin) on its selection property. * src/swamigui/SwamiguiMenu.c: Recent file chooser sub menu added, removed global Edit menu, removed global "Save" menu item, added "New " menu item and the New menu item creates the default or last patch type created, added "Save All" menu item, removed other inactive code. * src/swamigui/icons.c: Icons got severely WORKED over! New icons for DLS, Gig, SoundFont, FFTune GUI and Modulator junction, also a new Swami desktop icon which is now assigned to the main window (gtk_window_set_default_icon). Most other icons replaced by newer sexier versions. Starting to look fucking awesome now! Swami, if you weren't a computer program I'd.. ;) * src/swamigui/SwamiguiTreeStore.c: Renamed swamigui_tree_store_node_peek_item() to swamigui_tree_store_node_get_item() since the default GUI policy is to not reference returned objects. * src/swamigui/patch_funcs.c: Opened files are now added to recent files manager (Gtk+ 2.10.0+ support only currently). * src/swamigui/SwamiguiItemMenu_actions.c: Added key bindings to menu actions, for right click item menu actions which require the active tree the origin is fetched with swami_object_get_origin() and other updates to conform to new SwamiguiItemMenu changes. * src/swamigui/SwamiguiRoot.c: Added "selection-origin" property, icons in SwamiguiSelector re-arranged, "icon" IpatchTypeProp set for supported patch types, item menu accelerators assigned to main window. * src/swamigui/SwamiguiItemMenu.c: Keyboard accelerator code updated, right click item and menu no longer passed to action handlers to make item menu more generic (to be used by splits view for example), and also since the actions can be initiated by key presses. * src/swamigui/main.c: Swami can now except URI style file names (added for support for recent files subsystem). * src/libswami/SwamiRoot.c (swami_root_patch_load): Item is now returned via a pointer instead of the return value, to make it optional and remove the necessity of unreferencing it by the caller. * src/libswami/SwamiObject.c: Added swami_object_set_origin()/get to be able to assign an "origin" object to objects such as IpatchList item selections. 2006-05-08 Josh Green * Functions with 'ref' in the name renamed. * src/plugins/fluidsynth.c: Added "modulators" property for assigning session modulators to FluidSynth instance which get applied to voice caches. If an invalid temporary item is selected, the previous sounding item remains. * Improved Python binding generation (pulls in ipatch.defs). * src/swamigui/SwamiguiGenGraph.c: Fixes/improvements to envelope graph, including MVC updates. * src/swamigui/SwamiguiTree.c: Right click on a non-selected item now clears selection before selecting new item. * src/swamigui/SwamiguiPythonView.c: Added loading of scripts from "scripts" directory in Swami config directory (currently hard coded path: FIXME!). * src/swamigui/patch_funcs.c (swamigui_new_item): Items can now also be created using a IpatchVirtualContainer parent hint and will also use any "virtual-child-conform-func" type property to make new item conform to virtual container. * src/swamigui/SwamiguiMenu_actions.c: "New item" menu action updated to handle virtual containers also. * src/swamigui/SwamiguiModEdit.c: Updated to handle editing of any object which contains a "modulators" property and do so in a MVC fashion. * src/swamigui/main.c: Added "-r" option to run Python scripts on startup. * src/libswami/SwamiControlProp.c: Added swami_control_prop_connect_objects for connecting two object properties together. * src/libswami/SwamiRoot.c: Added "patch-root" property. Renamed swami_patch_load_ref to swami_root_patch_load and swami_patch_save to swami_root_patch_save. 2006-04-15 Josh Green * gtk-doc updates. * Removed builtin_enums.[ch] and marshals.[ch] which are now being auto generated always. 2006-04-12 Josh Green * src/python/swami.defs: No longer auto generated. * src/python/swamigui.defs: No longer auto generated. * src/swamigui/SwamiguiBar.[ch]: New canvas item bar for pointers and ranges (not yet functional). * src/swamigui/SwamiguiBarPtr.[ch]: New canvas item which defines a pointer or range to be added to a SwamiguiBar canvas item (not yet functional). * src/libswami/SwamiWavetbl.[ch]: Added check_update_item, update_item, and realtime_effect methods and related C functions. * src/libswami/libswami.c: Changed patch property change callback system: properties are now specified by GParamSpec instead of property name, wild card callbacks can be added for item and or property. * src/libswami/libswami.h: Changed SwamiPatchPropCallback to include SwamiEventPropChange parameter to save one from having to retrieve it. * src/plugins/fluidsynth.c: Added patch property change monitoring and check_update_item and update_item methods for refreshing voice cache of active instruments. * src/swamigui/SwamiguiPythonView.[ch]: Widget is now generated with glade, scripts can now be execute in full, toggle for line by line execution. * src/swamigui/swami_python.[ch] (swamigui_python_set_root): Function called by SwamiguiRoot to assign to the "swamigui.root" variable so it is availabe to Python scripts. 2006-03-15 Josh Green * Updated gtk-doc build files and now disabled by default. * src/swamigui/SwamiguiControl.c (swamigui_control_object_create_widgets): Added hack for read only label controls to make them left justified. * src/swamigui/SwamiguiLoopFinder.c: Added a revert button to revert loop settings to the original values. * src/swamigui/SwamiguiRoot.c: Root "selection" property now connected to "item-selection" property of SwamiguiSwitcher objects. * src/swamigui/SwamiguiSampleEditor.c: Start and end loop spin buttons now functional. * src/swamigui/patch_funcs.c (swamigui_new_item): Fixed creation of new IpatchBase types. 2006-03-11 Luis Garrido * Autolooper: much more optimization and even better handling of local maxima. 2006-03-10 Josh Green * src/swamigui/SwamiguiLoopFinder.c: Some minor bug fixes and optimizations. 2006-03-10 Luis Garrido * Autolooper: some optimization and better handling of local maxima. 2006-03-09 Josh Green * src/libswami/SwamiContainer.[ch]: Created new object type for IpatchItem container root. * src/libswami/SwamiRoot.c: No longer derived from IpatchItem. Patch tree root is now a separate object. * src/libswami/SwamiControl.c: More detailed control debug messages. * src/libswami/SwamiControlProp.c: Now re-transmitting all set value events to connected outputs. * src/swamigui/SwamiguiControlMidiKey.c: Using key snooper functionality of GTK main loop, instead of a widget. * src/swamigui/SwamiguiLoopFinder.c: Algorithm run in a separate thread making the GUI much more responsive, many other GUI improvements including min loop size parameter. * src/swamigui/SwamiguiRoot.c: Added "selection-single" property and sending notify events for "selection" and visa-versa, swamigui_root "selection" and "selection-single" are now being used to connect other interfaces via controls. * src/swamigui/SwamiguiSampleEditor.c: Better loop finder button. 2006-03-08 Luis Garrido * Added first version of functional autolooper code. 2006-03-07 Josh Green * src/swamigui/SwamiguiLoopFinder.[ch]: New loop finder dialog widget. Awaiting loop finder algorithm code from Luis Garrido. * src/swamigui/SwamiguiSampleEditor.c: Removed recently added loop finder widgets and added Find button for loop finder dialog. * src/swamigui/help.c: Now using GtkAboutDialog for about. * src/swamigui/util.c: Removed call to gtk_window_set_wmclass as its not recommended anymore. 2006-03-04 Josh Green * src/plugins/fluidsynth.c: Added FluidSynth MIDI router callback to pass events to FluidSynth (from MIDI driver) to Swami control network, now tracking channel bank and preset numbers and restoring when Synth is restarted, temporary item is not cleared when closed and is restored when restarted, bug fixes to close and finalize. * src/swamigui/SwamiguiItemMenu_actions.c: Added a "Restart Driver" option for SwamiWavetbl devices. 2006-03-03 Josh Green * src/swamigui/SwamiguiSampleEditor.c: Started adding loop finder GUI components and loop start/end goto and spin buttons. * src/swamigui/SwamiguiMenu.c: Forgot to add edit menu action again. 2006-03-03 Josh Green * src/swamigui/SwamiguiPanel.c: New interface "panel" registry, not yet being used. * src/swamigui/SwamiguiTreeStorePatch.c: Split off instrument tree store specific code to a sub class. * src/swamigui/SwamiguiTreeStorePref.c: New preferences tree store. * src/libswami/SwamiControlProp.c: Added swami_ref_prop_control_from_name and swami_ref_prop_control_from_pspec to allow for SwamiControlProp sharing for a given object property. * src/libswami/SwamiPropTree.c: Converted GMemChunk stuff to new GSlice with backwards compatible defines. * src/libswami/SwamiRoot.h: Changed add_object signal to object_add. * src/libswami/swami_priv.h: Added GSlice backward compatible defines and removed PREALLOC defines since they are likely useless with new GSlice memory allocator. * src/libswami/util.c: Converted GMemChunk related code to GSlice. * src/plugins/fluidsynth.c: All FluidSynth properties now dynamically created, removed static properties now being handled dynamically. * src/swamigui/SwamiguiControl.c (swamigui_control_object_create_widgets): Checking for IPATCH_PARAM_HIDE flag in property GParamSpecs to not show certain properties in user interfaces. * src/swamigui/SwamiguiMenu.c: Now using swamigui_root "selection" property for edit menu actions. * src/swamigui/SwamiguiRoot.c: Changed tree-store property to tree-store-list which is now a list of tree stores. Removed tree-focus property and added a "selection" property. Now creating the preferences tree store. * src/swamigui/SwamiguiTree.c: Changed to a notebook to allow for multiple tree interfaces (instrument and preferences currently). * src/swamigui/SwamiguiTreeStore.c: All instrument tree specific code moved to SwamiguiTreeStorePatch.c, now an abstract base class. 2006-01-20 Josh Green * src/swamigui/SwamiguiSampleEditor.c: Fixes to object finalization. * src/swamigui/patch_funcs.c: Removed old rotten mass of smelly yucky stuff that was the paste system and put a nice new shiney one in its place. Ohh, did I mention it kicks ass? Probably still many bugs to fix.. "But we don't care, we still want the money Lebowski!" 2005-11-25 Josh Green * src/libswami/SwamiRoot.c: Modified swami_patch_load_ref and swami_patch_save to use new IpatchConverter convenience functions. * src/plugins/fluidsynth.c: Modified for new IpatchConverter system. 2005-11-05 Josh Green * src/swamigui/SwamiguiNoteSelector.[ch]: New MIDI note selector widget. * src/plugins/fftune_gui.[ch]: GUI frontend for FFTune plugin. * intl: removed. * src/libswami/SwamiControl.c: Don't allow more connections than can be handled to a control at swami_control_connect() time. * src/libswami/SwamiControlProp.c: Removed direct calling of get_property and set_property functions, since it probably isn't supported. * src/libswami/SwamiEvent_ipatch.c: Fixed some finalize bugs with prop change event, and allow empty value now. * src/libswami/SwamiParam.c: Removed extra parameters, now superseded by IpatchParamProp. * src/libswami/SwamiRoot.c: Added a "sample-format" parameter to set the default sample export format. * src/libswami/util.c: Added swami_util_midi_note_to_str() and swami_util_midi_str_to_note() for converting between MIDI note numbers and ASCII strings. * src/plugins/fftune.[ch]: Now kicks ass, and actually works to some extent :) Interface is accomplished completely through properties and signals. * src/plugins/fftune_gui.[ch]: Yes, there is now a GUI for FFTune! * src/swamigui/SwamiguiControl.c: new swamigui_control_object_disconnect_widgets() function, now doing some crude aliasing to make more property types be controllable by GUI widgets. * src/swamigui/SwamiguiProp.c: Updates to the properties control widget, works "mo' betta now". * src/swamigui/SwamiguiRoot.c: Added a "main-window" property and property changes are now handled to some extent. * src/swamigui/SwamiguiSpectrumCanvas.[ch]: Lots of bug fixes, i.e., actually works now! * src/swamigui/SwamiguiTreeStore.c: Property changes handled somewhat, no auto-re-sorting though, yet. * src/swamigui/patch_funcs.c: Removed swamigui_item_properties() because it was lame and no longer needed. Added sample export function. 2005-10-15 gettextize * Makefile.am (SUBDIRS): Remove intl. 2005-09-18 Josh Green Applied Win32 build patch from Keishi Suenaga. Fixed a build error with python binding. 2005-08-17 Josh Green src/swamigui/SwamiguiControl_widgets.c: Fixed some bugs where IPATCH_ITEM_WLOCK/UNLOCK was being used instead of SWAMI_LOCK_WRITE/UNLOCK. src/swamigui/SwamiguiRoot.c: Added "icon" and "open-icon" type properties. src/swamigui/SwamiguiTree.c: Fixes to right click menu handling which was causing item reference leaks. src/swamigui/ifaces/SwamiguiItem_DLS2.c: Modified to handle new DLS "percussion" property. configure.ac: Removed src/swamish/Makefile from AC_OUTPUT, thanks to Pieter Penninckx for reporting this. 2005-06-24 Josh Green src/libswami/SwamiControl.c: Controls now added to a global list for periodic expired event cleanup, swami_control_do_event_expiration added for this purpose. src/libswami/SwamiControlProp.c: Fixes to finalization and referencing. src/libswami/SwamiPropTree.c: Fixes to finalization and referencing. src/libswami/SwamiRoot.c: Fixes to finalization. src/libswami/libswami.c: Timeout added for expiring inactive control events. src/plugins/fluidsynth.c: Converted to IpatchSF2VoiceCache system. src/swamigui/SwamiguiControl_widgets.c: Fixes to finalization and referencing. src/swamigui/SwamiguiLayout.c: Fixes to finalization and referencing. src/swamigui/SwamiguiMenu.c: Now using gtk_ui_manager for menus. src/swamigui/SwamiguiRoot.c: Fixes to finalization and referencing. src/swamigui/SwamiguiSplits.c: "item-selection" property now readable. src/swamigui/SwamiguiTree.c: Disabled new interactive search feature, fixes to finalization. src/swamigui/SwamiguiTreeStore.c: Fixes to finalization. src/swamigui/main.c: Updated command line text output. src/swamigui/ifaces/SwamiguiSplits_DLS2.c: Some bug fixes and added custom tests for Gig files. src/swamigui/ifaces/SwamiguiSplits_SF2.c: Some bug fixes. 2005-05-06 Josh Green Removed dependency on popt. Updated copyright year and license to indicate only Version 2 of the GPL can be used (to avoid any possible future corruptions of the GPL). Added an "object-add" signal to SwamiRoot which is emitted when an object is added. Splash is now conditionally built. Renamed swami_control_new_for_object to swami_control_new_for_widget and swami_control_create_object to swami_control_create_widget. Added swamigui_control_object_create_widgets and swamigui_control_object_connect_widgets for creating and connecting, respectively, GUI controls to a GObject's properties. Improved reference handling and item locking for SwamiguiControlAdj and SwamiguiControl_widgets. SwamiguiMenu now has a "New .." menu item which allows for selection of what type of object to create. SwamiguiProp will now automatically create a property editor if no SwamiguiItem prop method exists and now allows GObject items. Added a "default-patch-type" property for setting the default File->New patch type. SwamiguiTree now responds to "selection" set property. Sample importing now works and in a generic way. Started Copy/Paste clipboard style item paste (not done yet). Continuing work on swamish (not wroking yet). SwamiguiSplits syncing to tree item selection, but not the other way yet. Added a center horizontal line to SwamiguiSampleEditor. Probably other stuff too :) 2004-12-14 Josh Green Some documentation updates, other stuffs.. * src/plugins/fftune.[ch]: Updated for fftw3 and new IpatchSample interface. * src/plugins/FFTuneGui.[ch]: Starting to implement the FFTune GUI yeeeha! * src/swamigui/SwamiguiSpectrumCanvas.[ch]: New fequency spectrum canvas, completely untested :) * src/swamigui/SwamiguiControl.[ch]: GUI object can now be configured without creating the SwamiControl and GParamSpecs are used for configuring GUI objects. * src/swamigui/SwamiguiControl_widgets.c: Updated for changes in SwamiControl.c. * src/swamigui/SwamiguiSplits.c: Now sizes to an absolute minimum or the width of the view whatever is largest. 2004-11-19 Josh Green * src/plugins/fluidsynth.c: Samples are now converted to 16 bit mono and native host endian if necessary. 2004-11-08 Josh Green * configure.ac: PyGtk codegen dir now fetched with pkg-config. * src/python/Makefile.am: PyGtk codegen dir now fetched with pkg-config. 2004-11-07 Josh Green * src/swamigui/Makefile.am: Added swami.glade to EXTRA_DIST. * src/swamigui/SwamiguiSampleCanvas.c: Updated for new sample format channel routing. * src/swamigui/ifaces/SwamiguiSampleEditor_DLS2.c: Loop points are now working for DLS and GigaSampler and stereo support added. * src/swamigui/ifaces/SwamiguiSplits_DLS2.c: Key split controls added for DLS2 regions. 2004-11-03 Josh Green * configure.ac: Micro versions (*.*.M) removed from PKG_CONFIG tests, thanks to Ebrahim Mayat for pointing out that this breaks the fftw test on Mac OS X. * src/swamigui/SwamiguiRoot.c: ALSA sequencer plugin is now tested for before being created. * src/swamigui/Makefile.am: Swamigui is now built as an installed shared library, swami.glade and header files are now installed. * src/libswami/Makefile.am: Header files now get installed. * ac_python_devel.m4: Uses -lSystem on Darwin instead of -lutil, thanks to Ebrahim Mayat for reporting this. 2004-10-28 Josh Green Massive rename of SwamiUi to swamigui to comply with mixed case naming conventions used by PyGtk, etc. * src/libswami/SwamiControl.c: Added a new function swami_control_get_connections(), added event debugging code, queue test_func virtual functions are now called to determine if an event should be queued or not. * src/libswami/SwamiControlProp.c: Fixed a signal disconnect bug. * src/libswami/SwamiControlQueue.c: Added swami_control_queue_set_test_func() for setting a queue test function. * src/libswami/SwamiWavetbl.c: Renamed swami_wavetbl_init_driver to swami_wavetbl_open, renamed swami_wavetbl_close_driver to swami_wavetbl_close including method names. * src/swamigui/patch_funcs.c: Updated file open dialog to use new GTK 2.4 file dialog. * src/swamigui/SwamiguiSampleEditor.c: Many improvements including loop viewer is now working, sample view markers functional, multiple tracks can now be added, many bug fixes. * src/swamigui/SwamiguiSplits.c: Re-wrote splits canvas widget to use rectangles for the span areas and include vertical lines for the end points. * src/swamigui/SwamiguiSpan.[ch]: Removed, no longer needed. * src/swamigui/ifaces/SwamiguiSampleEditor_SF2.c: Updated for latest changes to sample editor. * src/swamigui/ifaces/SwamiguiSplits_SF2.c: Updated for latest changes to splits widget. * src/plugins/alsaseq.c: New ALSA sequencer MIDI source/sink. 2004-09-17 Josh Green Release: 1.0.0beta-20040917 Massive rename of SwamiUi -> Swamigui. Cleaned up Python checks in configure.ac (hopefully). API documentation updates. Python binding now functional for libswami and swamigui! Renaming of some widgets to fit case naming conventions. * src/swamigui/SwamiguiSampleCanvas.c: CTRL-key zooming and SHIFT-key scrolling in sample view. * src/swamigui/SwamiguiPythonView.[ch]: New Python editor/shell widget, in other words, yeeeeeeha! 2004-09-04 Josh Green * src/libswami/SwamiRoot.c (swami_patch_save): Updated to use new patch object conversion system, so any patch format that has an object to file converter should save now. * src/swamigui/SwamiUiSampleCanvas.c: Re-wrote draw routines to use new IpatchSampleTransform object system and other improvements (code not as ugly and perhaps faster and less buggy?). * src/swamigui/SwamiUiSampleEditor.c: Sample zoom is now clamped to sane values. 2004-07-14 Josh Green Removed unused plugins and src/include files (each src directory now has its own i18n.h). SwamiMidiEvent now structure boxed type rather than an object. Updated patch object load routine to use new converter system. Updated i18n support in all src/ directories so each one now has its own gettext domain. More fixes to SwamiUiSplits in regards to destroying and finalization. 2004-07-06 Josh Green Fixes to po and intl gettext stuff and other build problems. Some changes to python binding, although its probably not working yet. gtk-doc documentation now pretty nice - doc updates throughout code. * src/libswami/SwamiControl.c: Some changes to handling of GValue GBoxed and GObject based GParamSpecs. * src/libswami/SwamiControlProp.c: Changes to handling of GValue GBoxed and GObject based GParamSpecs. * src/libswami/SwamiObject.c: Moved some more functions from SwamiRoot.c. * src/libswami/SwamiParam.c (swami_param_type_from_value_type): Now handles GBoxed and GValue derived value types. * src/libswami/SwamiRoot.c: Moved some functions to SwamiObject.c. * src/swamigui/SwamiUiControl.c: Renamed swamiui_control_create to swamiui_control_new_for_type and added a swamiui_control_new function for ultra convenience. * src/swamigui/SwamiUiPiano.c: Moved code in "destroy" handler to "finalize" handler, since it was causing a crash (destroy called multiple times). * src/swamigui/SwamiUiRoot.c: Added more items to the switcher object including tree and splits editor. Also added some new icons for these. A "store" value is now set at the root of the property tree to assign itself to new tree objects (a HACK?) * src/swamigui/SwamiUiSplits.c: SwamiControls are now being created for splits and SF2 interface is now using them. * src/swamigui/SwamiUiTree.c: Added a "store" property for tree store which automatically gets set for new tree objects by SwamiUiRoot property tree. 2004-07-02 Josh Green Release: 1.0.0beta-20040703 Lots of changes, I'll do my best to include them here. Lots of changes to SwamiControl and friends; SwamiRoot split out into SwamiRoot, SwamiObject and SwamiParam; new controls including PC MIDI keyboard, event hub, and GTK control widgets; new undo/redo state types based on control events; FluidSynth plugin is working again; a vertical and horizontal pane splitting widget; properties widget updates to patch interfaces. Lots of cool things are starting to work and come together. 2003-08-06 Josh Green GigaSampler loading and synthesis support. FluidSynth plugin now working again. Modified IpatchSF2Voices interface to abstract samples away from IpatchSF2Sample. Created SwamiControlMidi for MIDI controls and added interfaces to FluidSynth plugin and SwamiUiPiano. Fixed some bugs in IpatchRiffParser related to odd chunk sizes. SwamiRoot object lookup functions now search recursively through tree. 2003-07-28 Josh Green Removed old SoundFont loader and implemented new IpatchRiffParser based one. Many updates to IpatchRiffParser. Added IpatchFileBuf functionality for parsing data in an endian safe fashion. Added SwamiEvent as a base object for events in the SwamiControl network. SwamiEventValue for value update propagations. SwamiMidiEvent for MIDI events. SwamiMidiDevice to take the place of removed SwamiMidi. SwamiUiControlAdj to connect GtkAdjustment into the SwamiControl network. SwamiUiSample is a new GnomeCanvas item sample display. SwamiUiSampleEditor takes the place of the removed SwamiUiSampleViewer. SwamiUiSpan is a GnomeCanvas item span widget which replaces widgets/keyspan.[ch]. SwamiUiSplits replaces the SwamiUiSpanWin widget. ifaces/SwamiUiDLS2Dummy.[ch] for DLS dummy tree items. ifaces/SwamiUiSampleEditor* for interfaces to new sample editor. ifaces/SwamiUiSplits* for interfaces for new splits widget. Lots of other junk. 2003-06-24 gettextize * Makefile.am (SUBDIRS): Add m4. (ACLOCAL_AMFLAGS): New variable. * configure.ac (AC_OUTPUT): Add m4/Makefile. 2003-06-24 Josh Green Can't remember, its been way too long since last commit. Lots of stuff though, re-writing GUI widgets and making them more pluggable, etc. Whos checking the ChangeLog anyways :) 2003-03-05 Josh Green *: DLS objects are now almost complete, DLS loader is compiling, memchunks in libinstpatch now being properly locked, a GValue control interface and a few objects were added to libswami as well as the beginning of a property tree system and GValue stack based virtual machine, "Preset number" changed to "program number" to coincide with terminology with other patch formats. 2003-02-24 Josh Green * : DLS loader is taking shape, changes and additions to RIFF parser, IpatchDLS2 object in the works, SwamiXmlObject created to store raw XML state data, GUI moved from src/gui/ to src/swamigui/ to help global GUI header install, now using libglade although not fully migrated yet, ipatch_sf2_find_free_preset annexed in favor of a ipatch_base_find_unused_midi_locale method, SoundFont item make unique and add unique functionality moved to IpatchContainer, added a remove method to IpatchItem to handle removes of item and all dependencies (IpatchSF2Sample and IpatchSF2Inst methods implemented), fixed some bugs in IpatchSF2 duplicate method, added "rate" property to IpatchSampleData, removed SwamiConfig system entirely (config vars are now handled by object properties), added type and instance ranking to SwamiRoot, added a "create_midi" method to SwamiWavetbl to allow a wavetable object to create MIDI objects to control itself, many additions and changes to XML state system, GUI layout is now attempting to save/restore itself (not working yet), probably many other things. 2003-01-24 Josh Green * : Extreme rapeage! New RIFF parser object in libInstPatch, started DLS2 objects and loader, a SwamiUiItem interface created to ease adaption of new patch formats (handles labels and pixmaps, adding, removing and updating GUI tree store, action menus, paste routines, property create, verify and commit), all SoundFont SwamiUiItem interface methods put in SwamiUiItem_SF2.c with paste routines in SwamiUiPaste_SF2.c, tree store abstracted from GUI tree, SwamiItem renamed to SwamiLock to reflect its real purpose, FluidSynth plugin updated for recent CVS changes, a new paste object created to handle paste operations, many things still broken :) 2002-12-18 Josh Green * : libInstPatch API doc updates, split IpatchSampleStore types out to individual files, split IpatchSF2File to its own file, all for documentation purposes. Changed many functions related to modulator lists. Added a SF2 voices interface to convert patch items to SF2 voices for synthesis (and created these interfaces for standard SF2 items). FluidSynth plugin is now working again and making noises :) Moved IpatchSampleStore flags into IpatchItem flags field. 2002-12-12 Josh Green * : Lots of API renaming including changing SoundFont based objects with SF in the name to SF2 (to be able to distinguish from other versions of SoundFont should they be added), IPatch->Ipatch, and SwamiUI->SwamiUi. Also SwamiObject was renamed to SwamiRoot and SwamiUIObject to SwamiUiRoot. Python support being worked on (its now functioning but not complete). SwamiUiGenView and SwamiUiGenCtrl are now smarter in how they update themselves to improve performance. Also these objects now listen to generator change events. Piano to keyboard key mapping preferences converted to GtkTreeView. Fixed SwamiUiGenGraph object. SwamiXml.[ch] interface added for new XML based state save/restore system. Ported some changes from GTK1.2 branch including changes to Piano and Keyspan widget. Removed improper use of depricated gtk_widget_set_usize (now using gtk_entry_set_width_chars where appropriate). 2002-12-03 Josh Green * : Devel branch checked in. TONS of changes including GUI is now GTK2 based, libInstPatch has been completely re-written using GObject, Swami undo/redo state history and queues, gtk-docs being built and many other things. Lots of bugs, so lets get this show on the road! 2002-07-17 Josh Green * : FLAC plugin compressor is working (not enabled or tested yet) and configure option added, separated iiwusynth GUI stuff to wavetbl_iiwusynth_gui.c, GenGraph object is now functioning and usable, added 'patch-load' signal to SwamiUIObject so loading of files can be hooked, added a macro and routine to run a separate GUI init function in plugins and fixed some stuff with libinstpatch lowlevel chunk routines and reporting of file position. 2002-07-08 Josh Green * : Gettext support re-enabled, converting to gtk-doc for API docs, plugin system is now working, a new gtk-canvas based SwamiUIGenGraph object for graphing generator controls, libInstPatch now using glib, new functionality for SoundFont lowlevel chunk routines, a FLAC based plugin is in the works, some fixes to passing of modulators to iiwusynth, blah blah blah blah.. Too long since last update. 2002-06-08 Josh Green * : Many new routines dealing with modulator lists in libInstPatch and also added modulator layering to sfont_item_foreach_voice. Modulator editor now works and modulators are loaded into iiwusynth (not tested). Chorus parameter controls added to iiwusynth control dialog and enabling/disabling chorus/reverb doesn't require restart of drivers any more. Fixed keyspan widget grabbing for SwamiUISpanWin. 2002-06-06 Josh Green * : Updated documentation and added 2002 to copyright string. Moved libsoundfont into src/libinstpatch and renamed soundfont.h header to instpatch.h. Also split view menu radio buttons out into individual callbacks again due to a problem with Glade. 2002-06-04 Josh Green * Makefile.am: Disabled gettext support (temporary) * README: Updated for Swami (was the Smurf README). * configure.in: Removed gettext support (temporary) * src/gui/Makefile.am: Removed gettext support (temporary) * src/gui/SwamiUIModEdit.c: Its actually somewhat working now. Will display available modulators and load controls. Doesn't edit anything yet though. A pixmap combo box was added for selecting source control transform functions. Two option menus are used for selecting destination generator, one being the group the generator is part of and the other is filled with the generators for the selected group, which can then be selected. * src/gui/SwamiUIObject.c: Moved lack of plugin support hackery to SwamiUIObject instead of SwamiObject. "Plugins" are now being statically linked into swami binary. * src/gui/pixmap.c: Pixmaps added for modulator transform functions. * src/gui/pixmap.h: Pixmaps added for modulator transform functions. * src/gui/pixmaps/Makefile.am: More pixmaps. * src/gui/widgets/Makefile.am: combo-box.[ch] and pixmap-combo.[ch] widgets added and modified from libgal. * src/gui/widgets/combo-box.c: New widget taken and modified from libgal. A popup combo box widget. * src/gui/widgets/pixmap-combo.c: A widget that uses combo-box to display a table of pixmaps for selection. Currently used in modulator editor. * src/include/Makefile.am: Added missing entries for some header files. * src/libswami/Makefile.am: Removed linking of "plugins" into libswami which was causing some breakage for some users. Now being linked into swami binary. * src/libswami/SwamiObject.c: Removed "plugin" loading hackery. * src/libswami/SwamiPlugin.c: Plugin code ripped and modified from gstreamer, not yet being used. * src/libswami/SwamiPlugin.h: Plugin code ripped and modified from gstreamer, not yet being used. 2002-05-31 Josh Green * acinclude.m4: Removed comments that contained "AM_PATH_ALSA" as aclocal assumed that we were using it (how appalling!) * src/gui/SwamiUIGenCtrl.c: (cb_ctrl_value_change): Updated for changed function prototype for real time generator control. * src/gui/menutbar.c: (swamiui_menu_cb_lowpane_select), (swamiui_tbar_new), (tbar_cb_lower_view_button_toggled), (tbar_cb_piano_mode_button_toggled), (swamiui_tbar_set_lowpane_togbtn), (swamiui_tbar_set_piano_mode_togbtn): Fixed menu view radio buttons and now have an icon for the not as yet working modulator editor. * src/gui/pixmap.c: Added a new pixmap. * src/libswami/SwamiWavetbl.c: (swami_wavetbl_set_gen_realtime): Changed realtime generator control function prototype to use an SFItem as the layer rather than an index. * src/libswami/SwamiWavetbl.h: Changed prototype for swami_wavetbl_set_gen_realtime. * src/plugins/wavetbl_iiwusynth.c: (wavetbl_iiwusynth_register), (wavetbl_iiwusynth_init), (sfloader_preset_noteon), (sfloader_temp_preset_noteon), (sfloader_preset_foreach_voice), (wavetbl_iiwusynth_set_gen_realtime), (swamiui_wavetbl_iiwusynth_create_controls): Removed old inadequate real time generator control and implemented a routine to re-layer an audible and update changed voices. Only works for most recent note in temporary audible. 2002-05-28 Josh Green * src/gui/SwamiUIObject.c: Quit confirmation works now. Add selected files in multi file selection dialog works for patch file loading. Selecting zones in tree selects them in spanwin as well (not the other way around yet though). * src/gui/SwamiUISpanWin.c: Virtual piano key table is now loaded and saved from preferences. Fixed stuck notes problem. * src/gui/menutbar.c: (swamiui_menu_cb_save): Enabled Save and Save As options on main menu. * src/gui/pref.c: Re-enabled virtual piano key table configuration. * src/gui/widgets/piano.c: Fixed piano widget so it won't emit note on/off events for keys that are already in that state. * src/gui/SwamiUIProp.c: Added instrument zone properties for setting Root key override, exclusive class, fixed note, and fixed velocity generators. 2002-05-27 Josh Green * autogen.sh: Added '--add-missing --copy' switches to automake to fix problems with missing files and automake 1.5. * configure.in: Changed version to "0.9pre1". * src/gui/Makefile.am: Removed SwamiUISelector.[ch], added pref.[ch], SwamiUIModEdit.[ch] and item_paste.[ch]. * src/gui/SwamiUIGenCtrl.c: Patch item is now set explicitly with swamiui_genctrl_set_item and removed use of SwamiUISelector. Added generator default toggle buttons to unset generators and re-structured code a bit. * src/gui/SwamiUIGenView.c: Patch item is now set explicitly with swamiui_genview_set_item and removed use of SwamiUISelector. * src/gui/SwamiUIMidiCtrl.c: New routine swamiui_midictrl_midi_update_all which sends values of all controls to MIDI driver. Now using 0-15 for channel value sent to MIDI driver. * src/gui/SwamiUIObject.c: Changed many SwamiConfig variable key names and removed a few. Using a new object registration system to associate child objects to main SwamiUIObject. Added new modulator editor to GUI, not operation yet though. Open files routine now uses multi file selection widget to open multiple files. Multi file close dialog now functions properly. Sample load dialog now uses multi file selection widget and samples are named properly. * src/gui/SwamiUIObject.h: Removed child widget pointers from SwamiUIObject, use child registration system instead. * src/gui/SwamiUIProp.c: (sync_widget_to_property): Fixed some problems with handling of NULL strings for some property values. Fixed some bugs relating to setting properties on items not in Swami tree. Comment field of SFData items now converts newlines. * src/gui/SwamiUISampleView.c: Renamed swamiui_sampleview_set_sfitem to swamiui_sampleview_set_item as well as the sfitem field of the SwamiUISampleView object to item. * src/gui/SwamiUISelector.c: Removed from CVS, bad idea. * src/gui/SwamiUISelector.h: Removed from CVS, bad idea. * src/gui/SwamiUISpanWin.c: More renaming of 'sfitem' to 'item' and setting item to an invalid type now the same as setting to NULL. Added 'select-zone' and 'unselect-zone' signals for keyspan list selection. Rootkey ptrstrip now works (have to select keyspan though). * src/gui/SwamiUITree.c: Fixed a bug in preset add routine related to faulty iteration over GtkCTree nodes causing failure. Renamed swamiui_tree_get_selection_complete to swamiui_tree_get_selection_rclick. Now using a hash table for item->ctree_node lookups in preparation for multiple trees and to free up the user_data field of items. Added test for single selected item on 'tree-row-unselect' signal, might remove though as it causes unselect/select widget weirdness. * src/gui/SwamiUITreeMenu.c: Right click 'R' and Multi item 'M' menu items now use different, and proper, tree selection fetch routines. Added paste routines and removed un-implemented right click menu items. * src/gui/main.c: Swami will now accept sound font file names on the command line, which it will load. * src/gui/menutbar.c: Menu radio button under 'View' now work and are synchronized with the toolbar buttons. Green light toggle button now being used again, it stops and starts iiwusynth. * src/gui/pref.c: Added to CVS. Most preferences work now. * src/gui/pref.h: Added to CVS. * src/gui/util.c: New routine swamiui_util_option_menu_index. Modified swamiui_util_lookup_widget to work with regular glade widgets. Renamed some of the unused string utility functions. * src/include/gobject2gtk.h: Fixed G_OBJECT to work correctly. Added GTK based g_object_get and g_object_get_valist handlers. * src/libswami/SwamiAudiofile.c: Fixed a bug with initial parameter settings and changed a config variable. * src/libswami/SwamiConfig.c: Fixed a file handle leak. * src/libswami/SwamiMidi.c: Fixed bug where class was accessed before it was created. * src/libswami/SwamiObject.c: Added a flag to SFItem for toplevel patch objects which indicates whether they are active and part of the Swami tree and should emit signals. This allows property set routines to be used for items which aren't in Swami's tree without causing problems. Some SwamiConfig variables added. Child registration functions renamed. The swami_item_new routine now accepts a variable argument list of properties to set on the new item. "software" property of SoundFonts is now intialized for new items and set for saved ones. * src/libswami/SwamiWavetbl.c: An 'active' property added which allows the querying of the active state of a wavetable driver. Fixed bug where class was accessed before it was created. Added 'set_gen_realtime' function type for wavetable drivers. * src/libswami/gobject2gtk.c: Many changes to fix G_OBJECT macro. Added g2g_object_get_valist and g2g_object_get handlers. * src/plugins/wavetbl_iiwusynth.c: SwamiConfig variables added. Driver preferences now working. MIDI driver now closes when Wavetable driver does. SWAMI_MIDI_BEND_RANGE now handled. Update for change in iiwusynth.h, rename of iiwu_voice_start to iiwu_synth_start_voice. iiwusynth control dialog hacked and works for setting reverb, chorus and master gain settings. Some trace code for real time generators which is currently non-operative. * src/gui/SwamiUIModEdit.c: Added to build, modulator edit widget. * src/gui/SwamiUIModEdit.h: Added to build. * src/gui/item_paste.c: Added to build, item paste routines. * src/gui/item_paste.h: Added to build. * src/gui/widgets/multi_filesel.c: Added to build, multi file selection widget. * src/gui/widgets/multi_filesel.h: Added to build. 2002-04-30 Josh Green * src/gui/Makefile.am: Build flags for audiofile * src/gui/SwamiUIMidiCtrl.c: (swamiui_midictrl_init), (send_midi_event), (set_piano_octave): Fixed initial MIDI spin button control bug and piano octave setting now works. * src/gui/SwamiUIMultiList.c: (swamiui_multilist_init), (swamiui_multilist_new), (swamiui_multilist_set_selection), (destroynotify_unref_items), (swamiui_multilist_new_listbtn), (cb_listbtn_clicked): Adding more helpful stuff to the multi item list object, including routines to help with referencing a list of items and a routine to create list buttons. * src/gui/SwamiUIObject.c: (swamiui_object_init), (swamiui_open_files), (swamiui_cb_open_files_okay), (swamiui_close_files), (swamiui_save_files), (cb_save_files_ok), (cb_save_files_browse), (cb_save_files_browse_ok), (swamiui_delete_items), (swamiui_wtbl_load_patch), (swamiui_item_properties), (swamiui_new_item), (swamiui_goto_zone_refitem), (swamiui_load_sample), (swamiui_cb_load_sample_okay), (swamiui_cb_paste_items): Some routine renaming away from sound font centric to more generic "patch" names. Changes to SwamiUITreeMenuCallback routines so that they are no longer callback specific. Save file multi item dialog implemented. Sample loading dialog implemented. * src/gui/SwamiUISpanWin.c: (swamiui_spanwin_set_mode), (swamiui_spanwin_set_sfitem), (swamiui_spanwin_update), (swamiui_spanwin_piano_set_octave): Added a routine to set the piano octave. Spans now update correctly on mode SpanWin mode change. * src/gui/SwamiUITreeMenu.c: (swamiui_treemenu_class_init), (swamiui_treemenu_activate), (treemenu_cb_selection_done), (swamiui_cb_wtbl_load_patch), (swamiui_cb_new_item), (swamiui_cb_goto_zone_refitem), (swamiui_cb_load_sample): Created a SwamiUITreeMenuCallback type to handle all menu callbacks. Updated callback handlers to use the new more specific non-callback functions and wrote wrappers where necessary. * src/libswami/Makefile.am: Added SwamiAudiofile.[ch] to the build. * src/libswami/SwamiAudiofile.c: (swami_audiofile_class_init), (swami_audiofile_driver_register_info), (swami_audiofile_select_driver), (find_driver_id_GCompareFunc), (swami_audiofile_get_driver_info), (swami_audiofile_init_driver), (swami_audiofile_load_sampledata), (swami_audiofile_init_sample), (swami_audiofile_open), (audiofile_okay), (swami_audiofile_close), (swami_audiofile_read): Audiofile loading is now working, a lot done (tired, must go to sleep). * src/libswami/SwamiObject.c: (swami_object_init), (swami_patch_load), (swami_patch_save), (swami_get_patch_list), (swami_item_insert), (swami_item_insert_before), (swami_item_new), (item_get_property): More renaming away from sound font centric routines to generic "patch" names. New routine `swami_patch_save' to save patch files. 2002-04-12 Josh Green * Makefile.am: Removed libltdl from automake SUBDIRS. * acinclude.m4: Removed unused macros left over from Smurf and added two new ones `AM_PATH_LIBSOUNDFONT' and `AM_PATH_IIWUSYNTH'. * autogen.sh: Removed build generation stuff for libswami as it is now one unified autoconf/automake build. * configure.in: Massive build changes, now a unified build system for libswami and gui. Should be cleaner with more checks for required libraries. * libltdl/*: Removed libltdl library, decided to use GModule. * src/gui/Makefile.am: Build changes, fixed splash_png.c generation, hopefully. * src/gui/SwamiUIObject.c: SwamiUITreeMenu activate callbacks now pass SwamiUITree object as the first parameter, so updated callbacks. (swamiui_cb_new_item): New SwamiUITreeMenu callback function to create a new item. (swamiui_cb_goto_zone_refitem): New SwamiUITreeMenu callback function to goto a zone's referenced item. * src/gui/SwamiUITree.c (swamiui_tree_init, tree_cb_item_prop_change): SFItem property change updates now update SwamiUITree. (swamiui_tree_freeze): Bug (bad cut and paste) that thawed instead of froze. (swamiui_tree_add_sfont, swamiui_tree_add_preset) (swamiui_tree_add_inst, swamiui_tree_add_sample): Now using `swami_item_get_formatted_name' to generate node labels for items. (swamiui_tree_item_set_pixmap): New function to set a pixmap in the first column of a SwamiUITree by sound font item. Was previously private and called `set_node_label'. * src/gui/SwamiUITreeMenu.c: Added an entry for SFITEM_SAMPLE_DATA to rmu_menus which caused the wrong menu options to be displayed for certain item types. Added callbacks for `New ' and `Goto ' menu entries. (swamiui_treemenu_activate): Now passing SwamiUITree object as the first parameter to menu item callbacks. * src/gui/help.c (swamiui_help_about): Commented out unused COMPILE_OPTIONS variable which will most likely be handled differently when the plugin system works. * src/gui/swami.glade: Added a couple of buttons to the Sample properties widget to allow selection of SampleData from a file or another sample, although neither is working yet. * src/gui/widgets/Makefile.am: Added GTK_CFLAGS to INCLUDES. * src/libswami/Makefile.am: Updated to be a part of the unified build system, as libswami is no longer built with a separate autoconf. * src/libswami/SwamiAudiofile.c: Minor changes, still not working yet. (swami_audiofile_load_into_sampledata): New function to create an SFSampleData object and load a sample into it. * src/libswami/SwamiObject.c: (swami_object_class_init): Added ITEM_PROP_CHANGE signal which is emitted when an SFItem's property is changed. (swami_item_new, new_item_unique_name): New function to create a unique SFItem and add it to the SwamiObject sound font tree. (swami_item_get_formatted_name): Updated to return formatted names suitable for SwamiUITree nodes. (swami_item_set_valist, swami_item_set_property, item_set_property): Updated to emit ITEM_PROP_CHANGE signal. * src/libswami/acinclude.m4: Removed, libswami now built from top. * src/libswami/configure.in: Removed, libswami now built from top. * src/libswami/marshals.c: Added to build. For custom signal marshallers. * src/libswami/marshals.h: Added to build. * src/plugins/Makefile.am: Statically compiling plugins for now until the plugin system works. 2002-04-07 Josh Green * src/gui/Makefile.am: Added SwamiUIProp.[ch] to the build. * src/gui/SwamiUIObject.c: Added multi sound font item properties dialog. * src/gui/SwamiUIProp.c: Properties object now working. * src/gui/SwamiUISampleView.c: Update for swami_item_get/set function renames. * src/gui/SwamiUISpanWin.c: Update for swami_item_get/set function renames. * src/gui/SwamiUITreeMenu.c: Enabled menu item for item `Properties'. * src/include/gobject2gtk.h: GValue strings are now dynamically allocated and freed on g_value_unset. * src/libswami/SwamiConfig.c: Fixed a bug where string config variables were set to static string values as defaults. Only occured when no config files present (caused segfault when opening a sound font file). * src/libswami/SwamiObject.c: Shortened swami_item_get/set_property functions to swami_item_get/set, i.e. removed "property". * src/libswami/SwamiObject.h: Rename of swami item get/set property functions. * src/libswami/gobject2gtk.c: Added g2g_value_unset to handle free of string values. * src/plugins/wavetbl_iiwusynth.c: Synchronized with iiwusynth header file which renamed all sfloader "delete" functions to "free". 2002-04-01 Josh Green * src/gui/Makefile.am: Added SwamiUISampleView.[ch] to the build. * src/gui/SwamiUISampleView.c: Added to CVS. * src/gui/SwamiUISampleView.h: Added to CVS. * src/gui/SwamiUIObject.c: Added sample view to interface. Created a swami_object variable to simplify things, don't need to cast swamiui_object anymore. * src/gui/SwamiUIProp.c: Messing with properties object, not functional yet. * src/gui/SwamiUISpanWin.c: Spans window implimented as a GtkList with a hack to allow KeySpan widget to grab mouse, still has some problems. * src/gui/SwamiUITree.h: Changed *_LAST enums to *_COUNT. * src/gui/util.h: Added RGB2GDK macro. * src/gui/widgets/keyspan.c: Synchronized with changes from Smurf, which adds some friendliness to the span widget. * src/gui/widgets/ptrstrip.c: Changed GtkPSPtr to PtrStripPointer. * src/gui/widgets/samview.c: Changed GtkSVMark to SamViewMark. * src/libswami/SwamiObject.c: Added more properties to SFSample items. * src/plugins/wavetbl_iiwusynth.c: Updated to use new libsoundfont sample storage management. swami/swami.xml0000644000175000017500000000126410565356664013743 0ustar alessioalessio Downloadable Sounds SoundFont swami/README0000644000175000017500000004425411473652713012760 0ustar alessioalessio+-------------------------------------------------------+ + Swami - README + + Copyright (C) 1999-2010 Joshua "Element" Green + + Email: jgreen@users.sourceforge.net + + Swami homepage: http://swami.sourceforge.net + +-------------------------------------------------------+ ******************************************************************* * NOTE: This will be replaced by a real manual in the near future * * Also NOTE that it is outdated. * ******************************************************************* ===================================== 1. What is Swami? 2. What happened to the Smurf SoundFont Editor? 3. License 4. Changes from Smurf 5. Requirements 6. Supported sound cards 7. Features 8. Future plans 9. Troubleshooting drivers (or why does Swami crash on startup?) 10. Using Virtual Keyboard interface 11. Creating Preset/Instrument zones 12. Using the sample viewer 13. Undo system 14. Virtual Banks 15. SoundFont information, links and other resources 16. Thanks 17. Trademark Acknowledgement 18. Contact ===================================== 1. What is Swami? ------------------------------------- Swami (Sampled Waveforms And Musical Instruments) is a SoundFont editor. SoundFont files are a collection of audio samples and other data that describe instruments for the purpose of composing music. SoundFont files do not describe the music itself, but rather the sounds of the instruments. These instruments can be composed of any digitally recordable or generated sound. This format provides a portable and flexible sound synthesis environment that can be supported in hardware or software. 2. What happend to the Smurf SoundFont Editor? ------------------------------------- Nothing actually. Since I was already doing an entire re-code of Smurf I decided it would be good to change the name to give the program a fresh start and because I'm planning to make it more than just a SoundFont editor. Also the word 'Smurf' is copyrighted so I thought a change wise in this day and age of law suits. Swami does not yet completely replace Smurf in functionality, but it will. 3. License ------------------------------------- This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License only. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. NOTE: Python binding in src/python is also licensed under the GPL version 2 only. 4. Changes from Smurf ------------------------------------- Most of the changes have occured in the programming architecture. Much of this work has been done in preparation for really cool features (TM) :) The SoundFont editing code is now completely abstracted from the GUI in separate shared libraries making things like: scripting support, multiple client concurrent access to SoundFont objects and SwamiJam (networked semi-realtime composition with friends) more feasible. Most importantly things are much cleaner now so I don't go insane in attempts to add functionality. New features: - FluidSynth soft synth support (actually its required) which allows any OS supported sound card to be used and gives us modulators (real time effects) and routeable digital audio output for adding additional effects and for easy recording. - More operations work for multiple items. Including loading/saving/closing of multiple SoundFont files, loading multiple samples, and setting/viewing properties on multiple items. - Modulator editor for editing real time control parameters - Default toggle buttons for generator (effect) controls Things missing (as of this README): - Undo support - virtual SoundFont bank support - OSS AWE/SB Live! wavetable backend 5. Requirements ------------------------------------- Look at the INSTALL file for instructions on compiling and installing Swami and for more details on software requirements. Version numbers listed are what I developed Swami on, older or newer versions of the listed software may or may not work, but give it a try! And do let me know if you encounter any problems. Swami has the following requirements: - Linux, Windows and Mac OS X. Probably anywhere else GTK+ will run. - GTK+ v2.0 - FluidSynth v1.0 (software wavetable synthesizer) - libsndfile GTK homepage: http://www.gtk.org FluidSynth homepage: http://www.fluidsynth.org libsndfile homepage: http://www.mega-nerd.com/libsndfile ALSA homepage: http://www.alsa-project.org OSS homepage: http://www.4front-tech.com 6. Supported sound cards ------------------------------------- Any FluidSynth supported sound card (i.e. works under ALSA or OSS in Linux), since Swami uses FluidSynth which does all synthesis in software. A wavetable backend is planned for using hardware based SoundFont synthesizers like the SB AWE/Live! for those who don't want to use their precious CPU cycles :) 7. Features ------------------------------------- Current features include: - Loading of multiple SoundFont 2.x files *.SF2 - Saving of multiple SoundFont files - Copy Samples/Instruments/Presets between and within SoundFont objects - Load and export multiple audio sample files (WAV, AU, etc) - View/set multiple Preset, Instrument and Sample parameters - A GTK piano widget to play notes with computer keyboard/mouse - Wavetable loading of entire SoundFont - Piano MIDI controls (Pitch bender amount, volume etc.) Features provided by FluidSynth: - Flexible driver system that supports OSS, ALSA, LADSPA, Jack, Midishare, etc - Real time effects via modulators and C API 8. Future plans ------------------------------------- The following are in the works or planned: - Undo support (just haven't written a front end for it really) - Copy/Paste generator parameters - Graphical manipulation of generator parameters Was part of Smurf, not yet added: - Loading, saving and editing of virtual bank (*.bnk) files - Multiple undo/redo tree system, allowing for multiple redo "branches" - Sample cut support - Sample waveform generation - International language support (currently disabled until there are some updated translations, contact me if interested) 9. Troubleshooting drivers (or why does Swami crash on startup?) ------------------------------------- [Some of these switches haven't been enabled yet!] Some new command line switches were added to help with trouble shooting problems with Swami. Crashes experienced on startup of Swami are often caused by audio drivers. Type "swami --help" to get a list of usable switches. Since Swami, by default, tries to open the drivers on start up, a way to disable this behavior was added. "swami -d" will cause Swami to start, but drivers will not automatically be opened. Once started you can change your driver preferences (set certain ones to NONE) to try to determine which driver is crashing. Then issue a Control->"Restart Drivers" to cause the drivers to be re-opened. Swami v0.9.0pre1 Copyright 1999-2002 Josh Green Distributed under the GNU General Public License Usage: swami [options] Options: -h, --help Display this information -d Disable drivers (try if Swami crashes on start up) -c Ignore preferences and use factory defaults 10. Using Virtual Keyboard interface ------------------------------------- [Most of this is true, although some things haven't been implemented yet] The wavetable and piano interface have been changed in Smurf v0.52. Some of the new features include: * MIDI channel control (on toolbar, titled "Chan") Sets what MIDI channel the piano plays on. All other MIDI controls (bank, preset and MIDI controls on pop up menu) are remembered for each channel. * MIDI bank and preset controls (also on toolbar) Sets the current bank and preset for the selected MIDI channel. These are often changed automatically by the user interface when selecting items in the SoundFont tree, they can be changed manually as well. * Entire SoundFont loading Allows you to load an entire SoundFont. This is particularly useful to make a SoundFont available for sequencing with other programs. * Controls for changing how interface works with wavetable Piano follows selection When enabled: virtual keyboard will "follow" the SoundFont tree selection. This will cause the selected item to be the one heard on the piano. If selected item is a Preset in a loaded SoundFont, then the piano will select the Bank:Preset of that item. Otherwise it is set to the Temporary Audible Bank:Preset (configurable from preferences, defaults to 127:127). By disabling this feature you can have more control over what is being played by the virtual keyboard. Auto load temp audible When enabled: selected items in the SoundFont tree that aren't Presets in a loaded SoundFont, are automatically loaded into the wavetable device. They are mapped to a temporary Bank:Preset which is configurable from Preferences. Disabling this allows for faster editing, if one does not care to hear items. - Temporary audible - The temporary audible enables you to listen to components of a SoundFont that aren't directly mapped to a MIDI Bank:Preset. This is done by designating a Bank:Preset for temporary use. It defaults to 127:127 but can be changed in Preferences. When a non-Preset or a Preset that isn't in a loaded SoundFont is loaded (either from the "Auto load temp audible" option or manually from the "Wavetable Load" item on the right click menus), it is mapped to this temporary bank and preset number. I hope that this new interface is more flexable and at the same time not too confusing. Let me know if you have any better ideas :) 11. Creating Preset/Instrument zones ------------------------------------- To add zones to an Instrument hold down the CTRL key and select the samples you want to be added (SHIFT works too for selecting a range of items). Then "Right Click" the Instrument you want to add the samples to. Select "Paste" from the pop up menu. A zone will be created for each Sample (or Instrument zone) you selected. This same procedure can be applied to Presets using Instruments as zones. To create a "Global Zone", "Right Click" on the Preset or Instrument you want to create the zone under. Select "Global Zone" from the pop up menu. Global Zones are used to set "Default" generator (and modulator) parameters that the other zones don't already have set. 12. Using the sample viewer ------------------------------------- The sample viewer is used to change loop points for samples and instrument zones. Some things have changed in the sample viewer and probably will be changing again. The sample zoom/unzoom is now performed with the SHIFT key held down. Regular left mouse clicks are now used for sample selections for audio editing functions (currently only "cut"). Tips to using the sample viewer: Zooming IN/OUT Hold down SHIFT on the computer keyboard and click and hold the LEFT mouse button in the sample window, a white line will appear to mark your click, move the mouse to the left or the right to zoom into the sample. The distance you move the mouse from the original point of your click determines the speed in which the view zooms. If you then move the mouse to the other side of the line the view will unzoom. The RIGHT mouse button does the same thing, except the first direction you move the mouse unzooms the view. Selecting audio data Left click and drag to mark an area. An existing selection can be changed by holding down CTRL and Left or Right clicking to change the left or right ends of the selection respectively. 13. Undo system ------------------------------------- [Not enabled yet!] Swami has a rather flexible undo system. Many actions aren't currently undo-able, but will be implimented soon. Currently all actions relating to new SoundFont items, pasted SoundFont items, and deleted items are undo-able. The undo system is based on a tree rather than queue or list. This means that multiple changes can be easily tested. A traditional undo system is oriented as a list. Here is an example to help understand the Swami undo tree system compared with the traditional one. 1. You change some parameters related to the Modulation Envelope of an instrument 2. You don't quite like the changes, so you undo them 3. You try some other values for the same Modulation Envelope Lets say now you want to try the parameters in Step 1 again to compare to the settings in Step 3. In a traditional undo system you would not be able to do this because Step 3 would cause the "redo" information from Step 2 to be lost. Using a tree, multiple branches of "state" information can be stored. So rather than Step 3 "over writing" the redo info from Step 2, it would simply create another "branch" in the tree. Note: This was just an example of usage, but Swami doesn't support undo-ing of parameter changes yet. When just using the Undo/Redo menu items the undo system acts as a traditional list oriented undo system. The "Undo History" item on the Edit menu will bring up a dialog that lists previous actions. The dialog buttons available are Undo, Redo, Jump, Back, Forward, < (left arrow), > (right arrow). The current location in the state history is indicated by 2 greater than symbols ">>" in the left most column. Undo and Redo act just like the menu items, undo-ing (moving up the undo history) and redo-ing (moving down the undo history) the next/previous action from the current location. The "Jump" button will jump to the desired position in the undo history, causing actions to be undone/redone as necessary to realize the desired state. The Back and Forward buttons act like the traditional web browser function. Currently the last 10 positions in the undo history are remembered. This makes testing different settings easier. This isn't really useful yet as the currently undo-able actions aren't really ones you would wan't to test different settings with. But in the future when generator parameters are tracked in the undo history, this will be useful. The < (left arrow) and > (right arrow) are the second and third column headers of the history list. These columns are used to indicate other branches in the tree. Items that have other "sibling" branches will have a number in brackets (example: [ 1]) listed in the < (left arrow) and/or > (right arrow) column(s). The left arrow switches to older branches the right arrow to newer ones. Numbers in these columns indicate how many alternate older or newer branches (left arrow or right arrow respectively) are available. To switch to an alternate branch, select an item that has a number in one of the arrow columns. Click the corresponding arrow button at the top of the list. The selected item and all items below will be changed to reflect the new branch. 14. Virtual Banks ------------------------------------- [Not implemented yet in Swami!] Virtual banks allow you to make a SoundFont bank from many other SoundFont files. Swami currently supports loading and saving of the AWE .bnk format. This is a simple text file format listing each Preset and where it can be found SoundFont file:Bank:Preset and its destination Bank:Preset. ** NOTE ** Make sure you set the "Virtual SoundFont bank search paths" field in Preferences. It should be a colon seperated list of where to find your SoundFont files. Example: "/home/josh/sbks/*:/tmp/sbks". Adding a '/*' to the end of a path will cause that directory to be recursively scanned (all sub directories under it). ** Current limitations (will be fixed in future) ** SoundFont files will not automatically be loaded with a virtual bank, so you'll have to load them by hand. Default SoundFont bank can't be cleared Can't edit virtual bank mappings - Adding a Preset to a virtual bank - Simply select and paste Preset items into the Mapping section of the virtual bank. - Setting default SoundFont - The default SoundFont sets the default Preset instruments. The Preset mappings override the default Presets. To change the default SoundFont simply paste a SoundFont item to the branch of the virtual bank. 15. SoundFont information, links and other resources ------------------------------------- I wrote an "Intro to SoundFonts" and its available on the Swami homepage http://swami.sourceforge.net. Its a general overview of what a SoundFont is. More information on the SoundFont standard can be obtained from www.soundfont.com. There is a PDF of the SoundFont technical specification at www.soundfont.com/documents/sfspec24.pdf. If you find that it has moved then look under the Resources section off of the soundfont.com home page (although it looks like you have to get a login to go there). Thanks to Frank Johnson at EMU for clarifying this. 16. Thanks ------------------------------------- Thanks to the following projects for making Swami possible: - FluidSynth (its what makes the instruments sound :) - gstreamer for gobject2gtk code and helpful examples of using GObject - Glade GTK interface builder - Gimp for graphics editing - Blender for render of campfire in desert Splash image - xmms code which I borrowed the multi selection file dialog modifications from - Piano to computer keyboard mapping inspired from soundtracker 17. Trademark Acknowledgement ------------------------------------- SoundFont is a registered trademark of E-mu Systems, Inc. Sound Blaster Live! and Sound Blaster AWE 32/64 are registered trademarks of Creative Labs Inc. All other trademarks are property of their respective holders. 18. Contact ------------------------------------- Contact me (Joshua "Element" Green) particularly if you are interested in helping develop Swami. Programming, web page design, and documentation are all things that are lacking, so if you have an interest, do contact me. Also contact me if you find any bugs, have trouble compiling on a platform you think should be supported, want to tell me how much you like Swami, or have suggestions or ideas. Email: jgreen@users.sourceforge.net Swami homepage: http://swami.sourceforge.net ===================================== swami/mkinstalldirs0000755000175000017500000000370410072577776014712 0ustar alessioalessio#! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain errstatus=0 dirmode="" usage="\ Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." # process command line arguments while test $# -gt 0 ; do case $1 in -h | --help | --h*) # -h for help echo "$usage" 1>&2 exit 0 ;; -m) # -m PERM arg shift test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } dirmode=$1 shift ;; --) # stop option processing shift break ;; -*) # unknown option echo "$usage" 1>&2 exit 1 ;; *) # first non-opt arg break ;; esac done for file do if test -d "$file"; then shift else break fi done case $# in 0) exit 0 ;; esac case $dirmode in '') if mkdir -p -- . 2>/dev/null; then echo "mkdir -p -- $*" exec mkdir -p -- "$@" fi ;; *) if mkdir -m "$dirmode" -p -- . 2>/dev/null; then echo "mkdir -m $dirmode -p -- $*" exec mkdir -m "$dirmode" -p -- "$@" fi ;; esac for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case $pathcomp in -*) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr else if test ! -z "$dirmode"; then echo "chmod $dirmode $pathcomp" lasterr="" chmod "$dirmode" "$pathcomp" || lasterr=$? if test ! -z "$lasterr"; then errstatus=$lasterr fi fi fi fi pathcomp="$pathcomp/" done done exit $errstatus # Local Variables: # mode: shell-script # sh-indentation: 2 # End: # mkinstalldirs ends here swami/compile0000755000175000017500000000532607573110375013452 0ustar alessioalessio#! /bin/sh # Wrapper for compilers which do not understand `-c -o'. # Copyright 1999, 2000 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Usage: # compile PROGRAM [ARGS]... # `-o FOO.o' is removed from the args passed to the actual compile. prog=$1 shift ofile= cfile= args= while test $# -gt 0; do case "$1" in -o) # configure might choose to run compile as `compile cc -o foo foo.c'. # So we do something ugly here. ofile=$2 shift case "$ofile" in *.o | *.obj) ;; *) args="$args -o $ofile" ofile= ;; esac ;; *.c) cfile=$1 args="$args $1" ;; *) args="$args $1" ;; esac shift done if test -z "$ofile" || test -z "$cfile"; then # If no `-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # `.c' file was seen then we are probably linking. That is also # ok. exec "$prog" $args fi # Name of file we expect compiler to create. cofile=`echo $cfile | sed -e 's|^.*/||' -e 's/\.c$/.o/'` # Create the lock directory. # Note: use `[/.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo $cofile | sed -e 's|[/.-]|_|g'`.d while true; do if mkdir $lockdir > /dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir $lockdir; exit 1" 1 2 15 # Run the compile. "$prog" $args status=$? if test -f "$cofile"; then mv "$cofile" "$ofile" fi rmdir $lockdir exit $status swami/m4/0000755000175000017500000000000011716016655012406 5ustar alessioalessioswami/m4/lib-ld.m40000644000175000017500000000676110333101113013777 0ustar alessioalessio# lib-ld.m4 serial 2 (gettext-0.12) dnl Copyright (C) 1996-2003 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl Subroutines of libtool.m4, dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision dnl with libtool.m4. dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no. AC_DEFUN([AC_LIB_PROG_LD_GNU], [AC_CACHE_CHECK([if the linker ($LD) is GNU ld], acl_cv_prog_gnu_ld, [# I'd rather use --version here, but apparently some GNU ld's only accept -v. if $LD -v 2>&1 &5; then acl_cv_prog_gnu_ld=yes else acl_cv_prog_gnu_ld=no fi]) with_gnu_ld=$acl_cv_prog_gnu_ld ]) dnl From libtool-1.4. Sets the variable LD. AC_DEFUN([AC_LIB_PROG_LD], [AC_ARG_WITH(gnu-ld, [ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl # Prepare PATH_SEPARATOR. # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by GCC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]* | [A-Za-z]:[\\/]*)] [re_direlt='/[^/][^/]*/\.\./'] # Canonicalize the path of ld ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(acl_cv_path_LD, [if test -z "$LD"; then IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then acl_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some GNU ld's only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. if "$acl_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then test "$with_gnu_ld" != no && break else test "$with_gnu_ld" != yes && break fi fi done IFS="$ac_save_ifs" else acl_cv_path_LD="$LD" # Let the user override the test with a path. fi]) LD="$acl_cv_path_LD" if test -n "$LD"; then AC_MSG_RESULT($LD) else AC_MSG_RESULT(no) fi test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) AC_LIB_PROG_LD_GNU ]) swami/m4/lt~obsolete.m40000644000175000017500000001311311464144605015216 0ustar alessioalessio# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 4 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_RC], [AC_DEFUN([AC_LIBTOOL_RC])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) swami/m4/isc-posix.m40000644000175000017500000000213307711261100014550 0ustar alessioalessio# isc-posix.m4 serial 2 (gettext-0.11.2) dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. # This file is not needed with autoconf-2.53 and newer. Remove it in 2005. # This test replaces the one in autoconf. # Currently this macro should have the same name as the autoconf macro # because gettext's gettext.m4 (distributed in the automake package) # still uses it. Otherwise, the use in gettext.m4 makes autoheader # give these diagnostics: # configure.in:556: AC_TRY_COMPILE was called before AC_ISC_POSIX # configure.in:556: AC_TRY_RUN was called before AC_ISC_POSIX undefine([AC_ISC_POSIX]) AC_DEFUN([AC_ISC_POSIX], [ dnl This test replaces the obsolescent AC_ISC_POSIX kludge. AC_CHECK_LIB(cposix, strerror, [LIBS="$LIBS -lcposix"]) ] ) swami/m4/longlong.m40000644000175000017500000000164310072577776014505 0ustar alessioalessio# longlong.m4 serial 4 dnl Copyright (C) 1999-2003 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Paul Eggert. # Define HAVE_LONG_LONG if 'long long' works. AC_DEFUN([jm_AC_TYPE_LONG_LONG], [ AC_CACHE_CHECK([for long long], ac_cv_type_long_long, [AC_TRY_LINK([long long ll = 1LL; int i = 63;], [long long llmax = (long long) -1; return ll << i | ll >> i | llmax / ll | llmax % ll;], ac_cv_type_long_long=yes, ac_cv_type_long_long=no)]) if test $ac_cv_type_long_long = yes; then AC_DEFINE(HAVE_LONG_LONG, 1, [Define if you have the 'long long' type.]) fi ]) swami/m4/inttypes.m40000644000175000017500000000171707711261100014520 0ustar alessioalessio# inttypes.m4 serial 1 (gettext-0.11.4) dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Paul Eggert. # Define HAVE_INTTYPES_H if exists and doesn't clash with # . AC_DEFUN([gt_HEADER_INTTYPES_H], [ AC_CACHE_CHECK([for inttypes.h], gt_cv_header_inttypes_h, [ AC_TRY_COMPILE( [#include #include ], [], gt_cv_header_inttypes_h=yes, gt_cv_header_inttypes_h=no) ]) if test $gt_cv_header_inttypes_h = yes; then AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H, 1, [Define if exists and doesn't clash with .]) fi ]) swami/m4/Makefile.am0000644000175000017500000000055410420404332014426 0ustar alessioalessioEXTRA_DIST = intmax.m4 longdouble.m4 longlong.m4 nls.m4 po.m4 printf-posix.m4 \ signed.m4 size_max.m4 wchar_t.m4 wint_t.m4 xsize.m4 codeset.m4 gettext.m4 \ glibc21.m4 iconv.m4 intdiv0.m4 inttypes.m4 inttypes_h.m4 inttypes-pri.m4 \ isc-posix.m4 lcmessage.m4 lib-ld.m4 lib-link.m4 lib-prefix.m4 progtest.m4 \ stdint_h.m4 uintmax_t.m4 ulonglong.m4 python.m4 swami/m4/lcmessage.m40000644000175000017500000000261607711261100014603 0ustar alessioalessio# lcmessage.m4 serial 3 (gettext-0.11.3) dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl dnl This file can can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU dnl gettext package package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: dnl Ulrich Drepper , 1995. # Check whether LC_MESSAGES is available in . AC_DEFUN([AM_LC_MESSAGES], [ AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, [AC_TRY_LINK([#include ], [return LC_MESSAGES], am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) if test $am_cv_val_LC_MESSAGES = yes; then AC_DEFINE(HAVE_LC_MESSAGES, 1, [Define if your file defines LC_MESSAGES.]) fi ]) swami/m4/nls.m40000644000175000017500000000350510072577776013461 0ustar alessioalessio# nls.m4 serial 1 (gettext-0.12) dnl Copyright (C) 1995-2003 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl dnl This file can can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU dnl gettext package package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: dnl Ulrich Drepper , 1995-2000. dnl Bruno Haible , 2000-2003. AC_DEFUN([AM_NLS], [ AC_MSG_CHECKING([whether NLS is requested]) dnl Default is enabled NLS AC_ARG_ENABLE(nls, [ --disable-nls do not use Native Language Support], USE_NLS=$enableval, USE_NLS=yes) AC_MSG_RESULT($USE_NLS) AC_SUBST(USE_NLS) ]) AC_DEFUN([AM_MKINSTALLDIRS], [ dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly dnl find the mkinstalldirs script in another subdir but $(top_srcdir). dnl Try to locate it. MKINSTALLDIRS= if test -n "$ac_aux_dir"; then case "$ac_aux_dir" in /*) MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" ;; *) MKINSTALLDIRS="\$(top_builddir)/$ac_aux_dir/mkinstalldirs" ;; esac fi if test -z "$MKINSTALLDIRS"; then MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" fi AC_SUBST(MKINSTALLDIRS) ]) swami/m4/python.m40000644000175000017500000000404510420404332014154 0ustar alessioalessiodnl Available from the GNU Autoconf Macro Archive at: dnl http://www.gnu.org/software/ac-archive/htmldoc/ac_python_devel.html dnl AC_DEFUN([AC_PYTHON_DEVEL],[ AC_REQUIRE([AM_PATH_PYTHON]) # Check for Python include path AC_MSG_CHECKING([for Python include path]) python_path=`echo $PYTHON | sed "s,/bin.*$,,"` for i in "$python_path/include/python$PYTHON_VERSION/" "$python_path/include/python/" "$python_path/" ; do python_path=`find $i -type f -name Python.h -print | sed "1q"` if test -n "$python_path" ; then break fi done python_path=`echo $python_path | sed "s,/Python.h$,,"` AC_MSG_RESULT([$python_path]) if test -z "$python_path" ; then AC_MSG_ERROR([cannot find Python include path]) fi AC_SUBST([PYTHON_CFLAGS],[-I$python_path]) # Check for Python library path AC_MSG_CHECKING([for Python library path]) python_path=`echo $PYTHON | sed "s,/bin.*$,,"` for i in "$python_path/lib/python$PYTHON_VERSION/config/" "$python_path/lib/python$PYTHON_VERSION/" "$python_path/lib/python/config/" "$python_path/lib/python/" "$python_path/" ; do python_path=`find $i -type f -name libpython$PYTHON_VERSION.* -print | sed "1q"` if test -n "$python_path" ; then break fi done python_path=`echo $python_path | sed "s,/libpython.*$,,"` AC_MSG_RESULT([$python_path]) if test -z "$python_path" ; then AC_MSG_ERROR([cannot find Python library path]) fi python_libs="-L$python_path -lpython$PYTHON_VERSION" # What a pain case $host_os in darwin*) python_libs="${python_libs} -lSystem" ;; *) python_libs="${python_libs} -lutil" ;; esac AC_SUBST([PYTHON_LIBS],[$python_libs]) # python_site=`echo $python_path | sed "s/config/site-packages/"` AC_SUBST([PYTHON_SITE_PKG],[$python_site]) # # libraries which must be linked in when embedding # AC_MSG_CHECKING(python extra libraries) PYTHON_EXTRA_LIBS=`$PYTHON -c "import distutils.sysconfig; \ conf = distutils.sysconfig.get_config_var; \ print conf('LOCALMODLIBS')+' '+conf('LIBS')" AC_MSG_RESULT($PYTHON_EXTRA_LIBS)` AC_SUBST(PYTHON_EXTRA_LIBS) ]) swami/m4/inttypes_h.m40000644000175000017500000000210310072577776015044 0ustar alessioalessio# inttypes_h.m4 serial 5 (gettext-0.12) dnl Copyright (C) 1997-2003 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Paul Eggert. # Define HAVE_INTTYPES_H_WITH_UINTMAX if exists, # doesn't clash with , and declares uintmax_t. AC_DEFUN([jm_AC_HEADER_INTTYPES_H], [ AC_CACHE_CHECK([for inttypes.h], jm_ac_cv_header_inttypes_h, [AC_TRY_COMPILE( [#include #include ], [uintmax_t i = (uintmax_t) -1;], jm_ac_cv_header_inttypes_h=yes, jm_ac_cv_header_inttypes_h=no)]) if test $jm_ac_cv_header_inttypes_h = yes; then AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H_WITH_UINTMAX, 1, [Define if exists, doesn't clash with , and declares uintmax_t. ]) fi ]) swami/m4/intdiv0.m40000644000175000017500000000356507711261100014221 0ustar alessioalessio# intdiv0.m4 serial 1 (gettext-0.11.3) dnl Copyright (C) 2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Bruno Haible. AC_DEFUN([gt_INTDIV0], [ AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_CACHE_CHECK([whether integer division by zero raises SIGFPE], gt_cv_int_divbyzero_sigfpe, [ AC_TRY_RUN([ #include #include static void #ifdef __cplusplus sigfpe_handler (int sig) #else sigfpe_handler (sig) int sig; #endif { /* Exit with code 0 if SIGFPE, with code 1 if any other signal. */ exit (sig != SIGFPE); } int x = 1; int y = 0; int z; int nan; int main () { signal (SIGFPE, sigfpe_handler); /* IRIX and AIX (when "xlc -qcheck" is used) yield signal SIGTRAP. */ #if (defined (__sgi) || defined (_AIX)) && defined (SIGTRAP) signal (SIGTRAP, sigfpe_handler); #endif /* Linux/SPARC yields signal SIGILL. */ #if defined (__sparc__) && defined (__linux__) signal (SIGILL, sigfpe_handler); #endif z = x / y; nan = y / y; exit (1); } ], gt_cv_int_divbyzero_sigfpe=yes, gt_cv_int_divbyzero_sigfpe=no, [ # Guess based on the CPU. case "$host_cpu" in alpha* | i[34567]86 | m68k | s390*) gt_cv_int_divbyzero_sigfpe="guessing yes";; *) gt_cv_int_divbyzero_sigfpe="guessing no";; esac ]) ]) case "$gt_cv_int_divbyzero_sigfpe" in *yes) value=1;; *) value=0;; esac AC_DEFINE_UNQUOTED(INTDIV0_RAISES_SIGFPE, $value, [Define if integer division by zero raises signal SIGFPE.]) ]) swami/m4/signed.m40000644000175000017500000000140110072577776014127 0ustar alessioalessio# signed.m4 serial 1 (gettext-0.10.40) dnl Copyright (C) 2001-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Bruno Haible. AC_DEFUN([bh_C_SIGNED], [ AC_CACHE_CHECK([for signed], bh_cv_c_signed, [AC_TRY_COMPILE(, [signed char x;], bh_cv_c_signed=yes, bh_cv_c_signed=no)]) if test $bh_cv_c_signed = no; then AC_DEFINE(signed, , [Define to empty if the C compiler doesn't support this keyword.]) fi ]) swami/m4/longdouble.m40000644000175000017500000000230010072577776015007 0ustar alessioalessio# longdouble.m4 serial 1 (gettext-0.12) dnl Copyright (C) 2002-2003 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Bruno Haible. dnl Test whether the compiler supports the 'long double' type. dnl Prerequisite: AC_PROG_CC AC_DEFUN([gt_TYPE_LONGDOUBLE], [ AC_CACHE_CHECK([for long double], gt_cv_c_long_double, [if test "$GCC" = yes; then gt_cv_c_long_double=yes else AC_TRY_COMPILE([ /* The Stardent Vistra knows sizeof(long double), but does not support it. */ long double foo = 0.0; /* On Ultrix 4.3 cc, long double is 4 and double is 8. */ int array [2*(sizeof(long double) >= sizeof(double)) - 1]; ], , gt_cv_c_long_double=yes, gt_cv_c_long_double=no) fi]) if test $gt_cv_c_long_double = yes; then AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if you have the 'long double' type.]) fi ]) swami/m4/codeset.m40000644000175000017500000000157607711261100014272 0ustar alessioalessio# codeset.m4 serial AM1 (gettext-0.10.40) dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Bruno Haible. AC_DEFUN([AM_LANGINFO_CODESET], [ AC_CACHE_CHECK([for nl_langinfo and CODESET], am_cv_langinfo_codeset, [AC_TRY_LINK([#include ], [char* cs = nl_langinfo(CODESET);], am_cv_langinfo_codeset=yes, am_cv_langinfo_codeset=no) ]) if test $am_cv_langinfo_codeset = yes; then AC_DEFINE(HAVE_LANGINFO_CODESET, 1, [Define if you have and nl_langinfo(CODESET).]) fi ]) swami/m4/size_max.m40000644000175000017500000000407210072577776014504 0ustar alessioalessio# size_max.m4 serial 2 dnl Copyright (C) 2003 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Bruno Haible. AC_DEFUN([gl_SIZE_MAX], [ AC_CHECK_HEADERS(stdint.h) dnl First test whether the system already has SIZE_MAX. AC_MSG_CHECKING([for SIZE_MAX]) result= AC_EGREP_CPP([Found it], [ #include #if HAVE_STDINT_H #include #endif #ifdef SIZE_MAX Found it #endif ], result=yes) if test -z "$result"; then dnl Define it ourselves. Here we assume that the type 'size_t' is not wider dnl than the type 'unsigned long'. dnl The _AC_COMPUTE_INT macro works up to LONG_MAX, since it uses 'expr', dnl which is guaranteed to work from LONG_MIN to LONG_MAX. _AC_COMPUTE_INT([~(size_t)0 / 10], res_hi, [#include ], result=?) _AC_COMPUTE_INT([~(size_t)0 % 10], res_lo, [#include ], result=?) _AC_COMPUTE_INT([sizeof (size_t) <= sizeof (unsigned int)], fits_in_uint, [#include ], result=?) if test "$fits_in_uint" = 1; then dnl Even though SIZE_MAX fits in an unsigned int, it must be of type dnl 'unsigned long' if the type 'size_t' is the same as 'unsigned long'. AC_TRY_COMPILE([#include extern size_t foo; extern unsigned long foo; ], [], fits_in_uint=0) fi if test -z "$result"; then if test "$fits_in_uint" = 1; then result="$res_hi$res_lo"U else result="$res_hi$res_lo"UL fi else dnl Shouldn't happen, but who knows... result='~(size_t)0' fi fi AC_MSG_RESULT([$result]) if test "$result" != yes; then AC_DEFINE_UNQUOTED([SIZE_MAX], [$result], [Define as the maximum value of type 'size_t', if the system doesn't define it.]) fi ]) swami/m4/ltversion.m40000644000175000017500000000127711464144605014701 0ustar alessioalessio# ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # Generated from ltversion.in. # serial 3017 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.2.6b]) m4_define([LT_PACKAGE_REVISION], [1.3017]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.2.6b' macro_revision='1.3017' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) swami/m4/progtest.m40000644000175000017500000000563410072577776014541 0ustar alessioalessio# progtest.m4 serial 3 (gettext-0.12) dnl Copyright (C) 1996-2003 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl dnl This file can can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU dnl gettext package package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: dnl Ulrich Drepper , 1996. # Search path for a program which passes the given test. dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) AC_DEFUN([AM_PATH_PROG_WITH_TEST], [ # Prepare PATH_SEPARATOR. # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Find out how to test for executable files. Don't use a zero-byte file, # as systems may use methods other than mode bits to determine executability. cat >conf$$.file <<_ASEOF #! /bin/sh exit 0 _ASEOF chmod +x conf$$.file if test -x conf$$.file >/dev/null 2>&1; then ac_executable_p="test -x" else ac_executable_p="test -f" fi rm -f conf$$.file # Extract the first word of "$2", so it can be a program name with args. set dummy $2; ac_word=[$]2 AC_MSG_CHECKING([for $ac_word]) AC_CACHE_VAL(ac_cv_path_$1, [case "[$]$1" in [[\\/]]* | ?:[[\\/]]*) ac_cv_path_$1="[$]$1" # Let the user override the test with a path. ;; *) ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in ifelse([$5], , $PATH, [$5]); do IFS="$ac_save_IFS" test -z "$ac_dir" && ac_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then if [$3]; then ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext" break 2 fi fi done done IFS="$ac_save_IFS" dnl If no 4th arg is given, leave the cache variable unset, dnl so AC_PATH_PROGS will keep looking. ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" ])dnl ;; esac])dnl $1="$ac_cv_path_$1" if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then AC_MSG_RESULT([$]$1) else AC_MSG_RESULT(no) fi AC_SUBST($1)dnl ]) swami/m4/glibc21.m40000644000175000017500000000172707711261100014065 0ustar alessioalessio# glibc21.m4 serial 2 (fileutils-4.1.3, gettext-0.10.40) dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. # Test for the GNU C Library, version 2.1 or newer. # From Bruno Haible. AC_DEFUN([jm_GLIBC21], [ AC_CACHE_CHECK(whether we are using the GNU C Library 2.1 or newer, ac_cv_gnu_library_2_1, [AC_EGREP_CPP([Lucky GNU user], [ #include #ifdef __GNU_LIBRARY__ #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2) Lucky GNU user #endif #endif ], ac_cv_gnu_library_2_1=yes, ac_cv_gnu_library_2_1=no) ] ) AC_SUBST(GLIBC21) GLIBC21="$ac_cv_gnu_library_2_1" ] ) swami/m4/stdint_h.m40000644000175000017500000000205310072577776014476 0ustar alessioalessio# stdint_h.m4 serial 3 (gettext-0.12) dnl Copyright (C) 1997-2003 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Paul Eggert. # Define HAVE_STDINT_H_WITH_UINTMAX if exists, # doesn't clash with , and declares uintmax_t. AC_DEFUN([jm_AC_HEADER_STDINT_H], [ AC_CACHE_CHECK([for stdint.h], jm_ac_cv_header_stdint_h, [AC_TRY_COMPILE( [#include #include ], [uintmax_t i = (uintmax_t) -1;], jm_ac_cv_header_stdint_h=yes, jm_ac_cv_header_stdint_h=no)]) if test $jm_ac_cv_header_stdint_h = yes; then AC_DEFINE_UNQUOTED(HAVE_STDINT_H_WITH_UINTMAX, 1, [Define if exists, doesn't clash with , and declares uintmax_t. ]) fi ]) swami/m4/ltoptions.m40000644000175000017500000002724211464144605014707 0ustar alessioalessio# Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option `$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl `shared' nor `disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [0], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [0], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [0], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the `shared' and # `disable-shared' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the `static' and # `disable-static' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the `fast-install' # and `disable-fast-install' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the `pic-only' and `no-pic' # LT_INIT options. # MODE is either `yes' or `no'. If omitted, it defaults to `both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [pic_mode="$withval"], [pic_mode=default]) test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) swami/m4/ltsugar.m40000644000175000017500000001042411464144605014327 0ustar alessioalessio# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59 which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) swami/m4/iconv.m40000644000175000017500000000665307711261100013763 0ustar alessioalessio# iconv.m4 serial AM4 (gettext-0.11.3) dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Bruno Haible. AC_DEFUN([AM_ICONV_LINKFLAGS_BODY], [ dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) AC_REQUIRE([AC_LIB_RPATH]) dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV dnl accordingly. AC_LIB_LINKFLAGS_BODY([iconv]) ]) AC_DEFUN([AM_ICONV_LINK], [ dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and dnl those with the standalone portable GNU libiconv installed). dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV dnl accordingly. AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) dnl Add $INCICONV to CPPFLAGS before performing the following checks, dnl because if the user has installed libiconv and not disabled its use dnl via --without-libiconv-prefix, he wants to use it. The first dnl AC_TRY_LINK will then fail, the second AC_TRY_LINK will succeed. am_save_CPPFLAGS="$CPPFLAGS" AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV]) AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [ am_cv_func_iconv="no, consider installing GNU libiconv" am_cv_lib_iconv=no AC_TRY_LINK([#include #include ], [iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd);], am_cv_func_iconv=yes) if test "$am_cv_func_iconv" != yes; then am_save_LIBS="$LIBS" LIBS="$LIBS $LIBICONV" AC_TRY_LINK([#include #include ], [iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd);], am_cv_lib_iconv=yes am_cv_func_iconv=yes) LIBS="$am_save_LIBS" fi ]) if test "$am_cv_func_iconv" = yes; then AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.]) fi if test "$am_cv_lib_iconv" = yes; then AC_MSG_CHECKING([how to link with libiconv]) AC_MSG_RESULT([$LIBICONV]) else dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV dnl either. CPPFLAGS="$am_save_CPPFLAGS" LIBICONV= LTLIBICONV= fi AC_SUBST(LIBICONV) AC_SUBST(LTLIBICONV) ]) AC_DEFUN([AM_ICONV], [ AM_ICONV_LINK if test "$am_cv_func_iconv" = yes; then AC_MSG_CHECKING([for iconv declaration]) AC_CACHE_VAL(am_cv_proto_iconv, [ AC_TRY_COMPILE([ #include #include extern #ifdef __cplusplus "C" #endif #if defined(__STDC__) || defined(__cplusplus) size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); #else size_t iconv(); #endif ], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const") am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` AC_MSG_RESULT([$]{ac_t:- }[$]am_cv_proto_iconv) AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1, [Define as const if the declaration of iconv() needs const.]) fi ]) swami/m4/lib-link.m40000644000175000017500000005534310072577776014375 0ustar alessioalessio# lib-link.m4 serial 4 (gettext-0.12) dnl Copyright (C) 2001-2003 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Bruno Haible. dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and dnl the libraries corresponding to explicit and implicit dependencies. dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and dnl augments the CPPFLAGS variable. AC_DEFUN([AC_LIB_LINKFLAGS], [ AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) AC_REQUIRE([AC_LIB_RPATH]) define([Name],[translit([$1],[./-], [___])]) define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [ AC_LIB_LINKFLAGS_BODY([$1], [$2]) ac_cv_lib[]Name[]_libs="$LIB[]NAME" ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME" ac_cv_lib[]Name[]_cppflags="$INC[]NAME" ]) LIB[]NAME="$ac_cv_lib[]Name[]_libs" LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs" INC[]NAME="$ac_cv_lib[]Name[]_cppflags" AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) AC_SUBST([LIB]NAME) AC_SUBST([LTLIB]NAME) dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the dnl results of this search when this library appears as a dependency. HAVE_LIB[]NAME=yes undefine([Name]) undefine([NAME]) ]) dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode) dnl searches for libname and the libraries corresponding to explicit and dnl implicit dependencies, together with the specified include files and dnl the ability to compile and link the specified testcode. If found, it dnl sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} and dnl LTLIB${NAME} variables and augments the CPPFLAGS variable, and dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty. AC_DEFUN([AC_LIB_HAVE_LINKFLAGS], [ AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) AC_REQUIRE([AC_LIB_RPATH]) define([Name],[translit([$1],[./-], [___])]) define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME dnl accordingly. AC_LIB_LINKFLAGS_BODY([$1], [$2]) dnl Add $INC[]NAME to CPPFLAGS before performing the following checks, dnl because if the user has installed lib[]Name and not disabled its use dnl via --without-lib[]Name-prefix, he wants to use it. ac_save_CPPFLAGS="$CPPFLAGS" AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [ ac_save_LIBS="$LIBS" LIBS="$LIBS $LIB[]NAME" AC_TRY_LINK([$3], [$4], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name=no]) LIBS="$ac_save_LIBS" ]) if test "$ac_cv_lib[]Name" = yes; then HAVE_LIB[]NAME=yes AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the $1 library.]) AC_MSG_CHECKING([how to link with lib[]$1]) AC_MSG_RESULT([$LIB[]NAME]) else HAVE_LIB[]NAME=no dnl If $LIB[]NAME didn't lead to a usable library, we don't need dnl $INC[]NAME either. CPPFLAGS="$ac_save_CPPFLAGS" LIB[]NAME= LTLIB[]NAME= fi AC_SUBST([HAVE_LIB]NAME) AC_SUBST([LIB]NAME) AC_SUBST([LTLIB]NAME) undefine([Name]) undefine([NAME]) ]) dnl Determine the platform dependent parameters needed to use rpath: dnl libext, shlibext, hardcode_libdir_flag_spec, hardcode_libdir_separator, dnl hardcode_direct, hardcode_minus_L. AC_DEFUN([AC_LIB_RPATH], [ AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir AC_CACHE_CHECK([for shared library run path origin], acl_cv_rpath, [ CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh . ./conftest.sh rm -f ./conftest.sh acl_cv_rpath=done ]) wl="$acl_cv_wl" libext="$acl_cv_libext" shlibext="$acl_cv_shlibext" hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" hardcode_direct="$acl_cv_hardcode_direct" hardcode_minus_L="$acl_cv_hardcode_minus_L" dnl Determine whether the user wants rpath handling at all. AC_ARG_ENABLE(rpath, [ --disable-rpath do not hardcode runtime library paths], :, enable_rpath=yes) ]) dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and dnl the libraries corresponding to explicit and implicit dependencies. dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. AC_DEFUN([AC_LIB_LINKFLAGS_BODY], [ define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) dnl By default, look in $includedir and $libdir. use_additional=yes AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) AC_LIB_ARG_WITH([lib$1-prefix], [ --with-lib$1-prefix[=DIR] search for lib$1 in DIR/include and DIR/lib --without-lib$1-prefix don't search for lib$1 in includedir and libdir], [ if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) else additional_includedir="$withval/include" additional_libdir="$withval/lib" fi fi ]) dnl Search the library and its dependencies in $additional_libdir and dnl $LDFLAGS. Using breadth-first-seach. LIB[]NAME= LTLIB[]NAME= INC[]NAME= rpathdirs= ltrpathdirs= names_already_handled= names_next_round='$1 $2' while test -n "$names_next_round"; do names_this_round="$names_next_round" names_next_round= for name in $names_this_round; do already_handled= for n in $names_already_handled; do if test "$n" = "$name"; then already_handled=yes break fi done if test -z "$already_handled"; then names_already_handled="$names_already_handled $name" dnl See if it was already located by an earlier AC_LIB_LINKFLAGS dnl or AC_LIB_HAVE_LINKFLAGS call. uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` eval value=\"\$HAVE_LIB$uppername\" if test -n "$value"; then if test "$value" = yes; then eval value=\"\$LIB$uppername\" test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" eval value=\"\$LTLIB$uppername\" test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" else dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined dnl that this library doesn't exist. So just drop it. : fi else dnl Search the library lib$name in $additional_libdir and $LDFLAGS dnl and the already constructed $LIBNAME/$LTLIBNAME. found_dir= found_la= found_so= found_a= if test $use_additional = yes; then if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then found_dir="$additional_libdir" found_so="$additional_libdir/lib$name.$shlibext" if test -f "$additional_libdir/lib$name.la"; then found_la="$additional_libdir/lib$name.la" fi else if test -f "$additional_libdir/lib$name.$libext"; then found_dir="$additional_libdir" found_a="$additional_libdir/lib$name.$libext" if test -f "$additional_libdir/lib$name.la"; then found_la="$additional_libdir/lib$name.la" fi fi fi fi if test "X$found_dir" = "X"; then for x in $LDFLAGS $LTLIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) case "$x" in -L*) dir=`echo "X$x" | sed -e 's/^X-L//'` if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then found_dir="$dir" found_so="$dir/lib$name.$shlibext" if test -f "$dir/lib$name.la"; then found_la="$dir/lib$name.la" fi else if test -f "$dir/lib$name.$libext"; then found_dir="$dir" found_a="$dir/lib$name.$libext" if test -f "$dir/lib$name.la"; then found_la="$dir/lib$name.la" fi fi fi ;; esac if test "X$found_dir" != "X"; then break fi done fi if test "X$found_dir" != "X"; then dnl Found the library. LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" if test "X$found_so" != "X"; then dnl Linking with a shared library. We attempt to hardcode its dnl directory into the executable's runpath, unless it's the dnl standard /usr/lib. if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then dnl No hardcoding is needed. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" else dnl Use an explicit option to hardcode DIR into the resulting dnl binary. dnl Potentially add DIR to ltrpathdirs. dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. haveit= for x in $ltrpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $found_dir" fi dnl The hardcoding into $LIBNAME is system dependent. if test "$hardcode_direct" = yes; then dnl Using DIR/libNAME.so during linking hardcodes DIR into the dnl resulting binary. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" else if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then dnl Use an explicit option to hardcode DIR into the resulting dnl binary. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" dnl Potentially add DIR to rpathdirs. dnl The rpathdirs will be appended to $LIBNAME at the end. haveit= for x in $rpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $found_dir" fi else dnl Rely on "-L$found_dir". dnl But don't add it if it's already contained in the LDFLAGS dnl or the already constructed $LIBNAME haveit= for x in $LDFLAGS $LIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" fi if test "$hardcode_minus_L" != no; then dnl FIXME: Not sure whether we should use dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" dnl here. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" else dnl We cannot use $hardcode_runpath_var and LD_RUN_PATH dnl here, because this doesn't fit in flags passed to the dnl compiler. So give up. No hardcoding. This affects only dnl very old systems. dnl FIXME: Not sure whether we should use dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" dnl here. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" fi fi fi fi else if test "X$found_a" != "X"; then dnl Linking with a static library. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" else dnl We shouldn't come here, but anyway it's good to have a dnl fallback. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" fi fi dnl Assume the include files are nearby. additional_includedir= case "$found_dir" in */lib | */lib/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` additional_includedir="$basedir/include" ;; esac if test "X$additional_includedir" != "X"; then dnl Potentially add $additional_includedir to $INCNAME. dnl But don't add it dnl 1. if it's the standard /usr/include, dnl 2. if it's /usr/local/include and we are using GCC on Linux, dnl 3. if it's already present in $CPPFLAGS or the already dnl constructed $INCNAME, dnl 4. if it doesn't exist as a directory. if test "X$additional_includedir" != "X/usr/include"; then haveit= if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux*) haveit=yes;; esac fi fi if test -z "$haveit"; then for x in $CPPFLAGS $INC[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_includedir"; then dnl Really add $additional_includedir to $INCNAME. INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" fi fi fi fi fi dnl Look for dependencies. if test -n "$found_la"; then dnl Read the .la file. It defines the variables dnl dlname, library_names, old_library, dependency_libs, current, dnl age, revision, installed, dlopen, dlpreopen, libdir. save_libdir="$libdir" case "$found_la" in */* | *\\*) . "$found_la" ;; *) . "./$found_la" ;; esac libdir="$save_libdir" dnl We use only dependency_libs. for dep in $dependency_libs; do case "$dep" in -L*) additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. dnl But don't add it dnl 1. if it's the standard /usr/lib, dnl 2. if it's /usr/local/lib and we are using GCC on Linux, dnl 3. if it's already present in $LDFLAGS or the already dnl constructed $LIBNAME, dnl 4. if it doesn't exist as a directory. if test "X$additional_libdir" != "X/usr/lib"; then haveit= if test "X$additional_libdir" = "X/usr/local/lib"; then if test -n "$GCC"; then case $host_os in linux*) haveit=yes;; esac fi fi if test -z "$haveit"; then haveit= for x in $LDFLAGS $LIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then dnl Really add $additional_libdir to $LIBNAME. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" fi fi haveit= for x in $LDFLAGS $LTLIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then dnl Really add $additional_libdir to $LTLIBNAME. LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" fi fi fi fi ;; -R*) dir=`echo "X$dep" | sed -e 's/^X-R//'` if test "$enable_rpath" != no; then dnl Potentially add DIR to rpathdirs. dnl The rpathdirs will be appended to $LIBNAME at the end. haveit= for x in $rpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $dir" fi dnl Potentially add DIR to ltrpathdirs. dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. haveit= for x in $ltrpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $dir" fi fi ;; -l*) dnl Handle this in the next round. names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` ;; *.la) dnl Handle this in the next round. Throw away the .la's dnl directory; it is already contained in a preceding -L dnl option. names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` ;; *) dnl Most likely an immediate library name. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" ;; esac done fi else dnl Didn't find the library; assume it is in the system directories dnl known to the linker and runtime loader. (All the system dnl directories known to the linker should also be known to the dnl runtime loader, otherwise the system is severely misconfigured.) LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" fi fi fi done done if test "X$rpathdirs" != "X"; then if test -n "$hardcode_libdir_separator"; then dnl Weird platform: only the last -rpath option counts, the user must dnl pass all path elements in one option. We can arrange that for a dnl single library, but not when more than one $LIBNAMEs are used. alldirs= for found_dir in $rpathdirs; do alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" done dnl Note: hardcode_libdir_flag_spec uses $libdir and $wl. acl_save_libdir="$libdir" libdir="$alldirs" eval flag=\"$hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" else dnl The -rpath options are cumulative. for found_dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$found_dir" eval flag=\"$hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" done fi fi if test "X$ltrpathdirs" != "X"; then dnl When using libtool, the option that works for both libraries and dnl executables is -R. The -R options are cumulative. for found_dir in $ltrpathdirs; do LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" done fi ]) dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, dnl unless already present in VAR. dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes dnl contains two or three consecutive elements that belong together. AC_DEFUN([AC_LIB_APPENDTOVAR], [ for element in [$2]; do haveit= for x in $[$1]; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X$element"; then haveit=yes break fi done if test -z "$haveit"; then [$1]="${[$1]}${[$1]:+ }$element" fi done ]) swami/m4/po.m40000644000175000017500000002152010333101113013240 0ustar alessioalessio# po.m4 serial 1 (gettext-0.12) dnl Copyright (C) 1995-2003 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl dnl This file can can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU dnl gettext package package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: dnl Ulrich Drepper , 1995-2000. dnl Bruno Haible , 2000-2003. dnl Checks for all prerequisites of the po subdirectory. AC_DEFUN([AM_PO_SUBDIRS], [ AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl AC_REQUIRE([AM_MKINSTALLDIRS])dnl AC_REQUIRE([AM_NLS])dnl dnl Perform the following tests also if --disable-nls has been given, dnl because they are needed for "make dist" to work. dnl Search for GNU msgfmt in the PATH. dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions. dnl The second test excludes FreeBSD msgfmt. AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, [$ac_dir/$ac_word --statistics /dev/null >/dev/null 2>&1 && (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], :) AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) dnl Search for GNU xgettext 0.12 or newer in the PATH. dnl The first test excludes Solaris xgettext and early GNU xgettext versions. dnl The second test excludes FreeBSD xgettext. AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >/dev/null 2>&1 && (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], :) dnl Remove leftover from FreeBSD xgettext call. rm -f messages.po dnl Search for GNU msgmerge 0.11 or newer in the PATH. AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge, [$ac_dir/$ac_word --update -q /dev/null /dev/null >/dev/null 2>&1], :) dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. dnl Test whether we really found GNU msgfmt. if test "$GMSGFMT" != ":"; then dnl If it is no GNU msgfmt we define it as : so that the dnl Makefiles still can work. if $GMSGFMT --statistics /dev/null >/dev/null 2>&1 && (if $GMSGFMT --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then : ; else GMSGFMT=`echo "$GMSGFMT" | sed -e 's,^.*/,,'` AC_MSG_RESULT( [found $GMSGFMT program is not GNU msgfmt; ignore it]) GMSGFMT=":" fi fi dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. dnl Test whether we really found GNU xgettext. if test "$XGETTEXT" != ":"; then dnl If it is no GNU xgettext we define it as : so that the dnl Makefiles still can work. if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >/dev/null 2>&1 && (if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then : ; else AC_MSG_RESULT( [found xgettext program is not GNU xgettext; ignore it]) XGETTEXT=":" fi dnl Remove leftover from FreeBSD xgettext call. rm -f messages.po fi AC_OUTPUT_COMMANDS([ for ac_file in $CONFIG_FILES; do # Support "outfile[:infile[:infile...]]" case "$ac_file" in *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; esac # PO directories have a Makefile.in generated from Makefile.in.in. case "$ac_file" in */Makefile.in) # Adjust a relative srcdir. ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` # In autoconf-2.13 it is called $ac_given_srcdir. # In autoconf-2.50 it is called $srcdir. test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" case "$ac_given_srcdir" in .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; /*) top_srcdir="$ac_given_srcdir" ;; *) top_srcdir="$ac_dots$ac_given_srcdir" ;; esac if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then rm -f "$ac_dir/POTFILES" test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" POMAKEFILEDEPS="POTFILES.in" # ALL_LINGUAS, POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES depend # on $ac_dir but don't depend on user-specified configuration # parameters. if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then # The LINGUAS file contains the set of available languages. if test -n "$OBSOLETE_ALL_LINGUAS"; then test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" fi ALL_LINGUAS_=`sed -e "/^#/d" "$ac_given_srcdir/$ac_dir/LINGUAS"` # Hide the ALL_LINGUAS assigment from automake. eval 'ALL_LINGUAS''=$ALL_LINGUAS_' POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" else # The set of available languages was given in configure.in. eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS' fi case "$ac_given_srcdir" in .) srcdirpre= ;; *) srcdirpre='$(srcdir)/' ;; esac POFILES= GMOFILES= UPDATEPOFILES= DUMMYPOFILES= for lang in $ALL_LINGUAS; do POFILES="$POFILES $srcdirpre$lang.po" GMOFILES="$GMOFILES $srcdirpre$lang.gmo" UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" DUMMYPOFILES="$DUMMYPOFILES $lang.nop" done # CATALOGS depends on both $ac_dir and the user's LINGUAS # environment variable. INST_LINGUAS= if test -n "$ALL_LINGUAS"; then for presentlang in $ALL_LINGUAS; do useit=no if test "%UNSET%" != "$LINGUAS"; then desiredlanguages="$LINGUAS" else desiredlanguages="$ALL_LINGUAS" fi for desiredlang in $desiredlanguages; do # Use the presentlang catalog if desiredlang is # a. equal to presentlang, or # b. a variant of presentlang (because in this case, # presentlang can be used as a fallback for messages # which are not translated in the desiredlang catalog). case "$desiredlang" in "$presentlang"*) useit=yes;; esac done if test $useit = yes; then INST_LINGUAS="$INST_LINGUAS $presentlang" fi done fi CATALOGS= if test -n "$INST_LINGUAS"; then for lang in $INST_LINGUAS; do CATALOGS="$CATALOGS $lang.gmo" done fi test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do if test -f "$f"; then case "$f" in *.orig | *.bak | *~) ;; *) cat "$f" >> "$ac_dir/Makefile" ;; esac fi done fi ;; esac done], [# Capture the value of obsolete ALL_LINGUAS because we need it to compute # POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES, CATALOGS. But hide it # from automake. eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"' # Capture the value of LINGUAS because we need it to compute CATALOGS. LINGUAS="${LINGUAS-%UNSET%}" ]) ]) swami/m4/wint_t.m40000644000175000017500000000153110072577776014166 0ustar alessioalessio# wint_t.m4 serial 1 (gettext-0.12) dnl Copyright (C) 2003 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Bruno Haible. dnl Test whether has the 'wint_t' type. dnl Prerequisite: AC_PROG_CC AC_DEFUN([gt_TYPE_WINT_T], [ AC_CACHE_CHECK([for wint_t], gt_cv_c_wint_t, [AC_TRY_COMPILE([#include wint_t foo = (wchar_t)'\0';], , gt_cv_c_wint_t=yes, gt_cv_c_wint_t=no)]) if test $gt_cv_c_wint_t = yes; then AC_DEFINE(HAVE_WINT_T, 1, [Define if you have the 'wint_t' type.]) fi ]) swami/m4/printf-posix.m40000644000175000017500000000310610072577776015324 0ustar alessioalessio# printf-posix.m4 serial 2 (gettext-0.13.1) dnl Copyright (C) 2003 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Bruno Haible. dnl Test whether the printf() function supports POSIX/XSI format strings with dnl positions. AC_DEFUN([gt_PRINTF_POSIX], [ AC_REQUIRE([AC_PROG_CC]) AC_CACHE_CHECK([whether printf() supports POSIX/XSI format strings], gt_cv_func_printf_posix, [ AC_TRY_RUN([ #include #include /* The string "%2$d %1$d", with dollar characters protected from the shell's dollar expansion (possibly an autoconf bug). */ static char format[] = { '%', '2', '$', 'd', ' ', '%', '1', '$', 'd', '\0' }; static char buf[100]; int main () { sprintf (buf, format, 33, 55); return (strcmp (buf, "55 33") != 0); }], gt_cv_func_printf_posix=yes, gt_cv_func_printf_posix=no, [ AC_EGREP_CPP(notposix, [ #if defined __NetBSD__ || defined _MSC_VER || defined __MINGW32__ || defined __CYGWIN__ notposix #endif ], gt_cv_func_printf_posix="guessing no", gt_cv_func_printf_posix="guessing yes") ]) ]) case $gt_cv_func_printf_posix in *yes) AC_DEFINE(HAVE_POSIX_PRINTF, 1, [Define if your printf() function supports format strings with positions.]) ;; esac ]) swami/m4/gtk-doc.m40000644000175000017500000000245410774346067014213 0ustar alessioalessiodnl -*- mode: autoconf -*- # serial 1 dnl Usage: dnl GTK_DOC_CHECK([minimum-gtk-doc-version]) AC_DEFUN([GTK_DOC_CHECK], [ AC_BEFORE([AC_PROG_LIBTOOL],[$0])dnl setup libtool first AC_BEFORE([AM_PROG_LIBTOOL],[$0])dnl setup libtool first dnl for overriding the documentation installation directory AC_ARG_WITH([html-dir], AS_HELP_STRING([--with-html-dir=PATH], [path to installed docs]),, [with_html_dir='${datadir}/gtk-doc/html']) HTML_DIR="$with_html_dir" AC_SUBST([HTML_DIR]) dnl enable/disable documentation building AC_ARG_ENABLE([gtk-doc], AS_HELP_STRING([--enable-gtk-doc], [use gtk-doc to build documentation [[default=no]]]),, [enable_gtk_doc=no]) if test x$enable_gtk_doc = xyes; then ifelse([$1],[], [PKG_CHECK_EXISTS([gtk-doc],, AC_MSG_ERROR([gtk-doc not installed and --enable-gtk-doc requested]))], [PKG_CHECK_EXISTS([gtk-doc >= $1],, AC_MSG_ERROR([You need to have gtk-doc >= $1 installed to build gtk-doc]))]) fi AC_MSG_CHECKING([whether to build gtk-doc documentation]) AC_MSG_RESULT($enable_gtk_doc) AC_PATH_PROGS(GTKDOC_CHECK,gtkdoc-check,) AM_CONDITIONAL([ENABLE_GTK_DOC], [test x$enable_gtk_doc = xyes]) AM_CONDITIONAL([GTK_DOC_USE_LIBTOOL], [test -n "$LIBTOOL"]) ]) swami/m4/gettext.m40000644000175000017500000004052110333101113014310 0ustar alessioalessio# gettext.m4 serial 20 (gettext-0.12) dnl Copyright (C) 1995-2003 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl dnl This file can can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU dnl gettext package package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: dnl Ulrich Drepper , 1995-2000. dnl Bruno Haible , 2000-2003. dnl Macro to add for using GNU gettext. dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]). dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The dnl default (if it is not specified or empty) is 'no-libtool'. dnl INTLSYMBOL should be 'external' for packages with no intl directory, dnl and 'no-libtool' or 'use-libtool' for packages with an intl directory. dnl If INTLSYMBOL is 'use-libtool', then a libtool library dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static, dnl depending on --{enable,disable}-{shared,static} and on the presence of dnl AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library dnl $(top_builddir)/intl/libintl.a will be created. dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext dnl implementations (in libc or libintl) without the ngettext() function dnl will be ignored. If NEEDSYMBOL is specified and is dnl 'need-formatstring-macros', then GNU gettext implementations that don't dnl support the ISO C 99 formatstring macros will be ignored. dnl INTLDIR is used to find the intl libraries. If empty, dnl the value `$(top_builddir)/intl/' is used. dnl dnl The result of the configuration is one of three cases: dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled dnl and used. dnl Catalog format: GNU --> install in $(datadir) dnl Catalog extension: .mo after installation, .gmo in source tree dnl 2) GNU gettext has been found in the system's C library. dnl Catalog format: GNU --> install in $(datadir) dnl Catalog extension: .mo after installation, .gmo in source tree dnl 3) No internationalization, always use English msgid. dnl Catalog format: none dnl Catalog extension: none dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur. dnl The use of .gmo is historical (it was needed to avoid overwriting the dnl GNU format catalogs when building on a platform with an X/Open gettext), dnl but we keep it in order not to force irrelevant filename changes on the dnl maintainers. dnl AC_DEFUN([AM_GNU_GETTEXT], [ dnl Argument checking. ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], , [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT ])])])])]) ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], , [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT ])])])]) define(gt_included_intl, ifelse([$1], [external], [no], [yes])) define(gt_libtool_suffix_prefix, ifelse([$1], [use-libtool], [l], [])) AC_REQUIRE([AM_PO_SUBDIRS])dnl ifelse(gt_included_intl, yes, [ AC_REQUIRE([AM_INTL_SUBDIR])dnl ]) dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) AC_REQUIRE([AC_LIB_RPATH]) dnl Sometimes libintl requires libiconv, so first search for libiconv. dnl Ideally we would do this search only after the dnl if test "$USE_NLS" = "yes"; then dnl if test "$gt_cv_func_gnugettext_libc" != "yes"; then dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT dnl the configure script would need to contain the same shell code dnl again, outside any 'if'. There are two solutions: dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'. dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE. dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not dnl documented, we avoid it. ifelse(gt_included_intl, yes, , [ AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) ]) dnl Set USE_NLS. AM_NLS ifelse(gt_included_intl, yes, [ BUILD_INCLUDED_LIBINTL=no USE_INCLUDED_LIBINTL=no ]) LIBINTL= LTLIBINTL= POSUB= dnl If we use NLS figure out what method if test "$USE_NLS" = "yes"; then gt_use_preinstalled_gnugettext=no ifelse(gt_included_intl, yes, [ AC_MSG_CHECKING([whether included gettext is requested]) AC_ARG_WITH(included-gettext, [ --with-included-gettext use the GNU gettext library included here], nls_cv_force_use_gnu_gettext=$withval, nls_cv_force_use_gnu_gettext=no) AC_MSG_RESULT($nls_cv_force_use_gnu_gettext) nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" if test "$nls_cv_force_use_gnu_gettext" != "yes"; then ]) dnl User does not insist on using GNU NLS library. Figure out what dnl to use. If GNU gettext is available we use this. Else we have dnl to fall back to GNU NLS library. dnl Add a version number to the cache macros. define([gt_api_version], ifelse([$2], [need-formatstring-macros], 3, ifelse([$2], [need-ngettext], 2, 1))) define([gt_cv_func_gnugettext_libc], [gt_cv_func_gnugettext]gt_api_version[_libc]) define([gt_cv_func_gnugettext_libintl], [gt_cv_func_gnugettext]gt_api_version[_libintl]) AC_CACHE_CHECK([for GNU gettext in libc], gt_cv_func_gnugettext_libc, [AC_TRY_LINK([#include ]ifelse([$2], [need-formatstring-macros], [#ifndef __GNU_GETTEXT_SUPPORTED_REVISION #define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) #endif changequote(,)dnl typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; changequote([,])dnl ], [])[extern int _nl_msg_cat_cntr; extern int *_nl_domain_bindings;], [bindtextdomain ("", ""); return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_domain_bindings], gt_cv_func_gnugettext_libc=yes, gt_cv_func_gnugettext_libc=no)]) if test "$gt_cv_func_gnugettext_libc" != "yes"; then dnl Sometimes libintl requires libiconv, so first search for libiconv. ifelse(gt_included_intl, yes, , [ AM_ICONV_LINK ]) dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv]) dnl because that would add "-liconv" to LIBINTL and LTLIBINTL dnl even if libiconv doesn't exist. AC_LIB_LINKFLAGS_BODY([intl]) AC_CACHE_CHECK([for GNU gettext in libintl], gt_cv_func_gnugettext_libintl, [gt_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $INCINTL" gt_save_LIBS="$LIBS" LIBS="$LIBS $LIBINTL" dnl Now see whether libintl exists and does not depend on libiconv. AC_TRY_LINK([#include ]ifelse([$2], [need-formatstring-macros], [#ifndef __GNU_GETTEXT_SUPPORTED_REVISION #define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) #endif changequote(,)dnl typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; changequote([,])dnl ], [])[extern int _nl_msg_cat_cntr; extern #ifdef __cplusplus "C" #endif const char *_nl_expand_alias ();], [bindtextdomain ("", ""); return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias (0)], gt_cv_func_gnugettext_libintl=yes, gt_cv_func_gnugettext_libintl=no) dnl Now see whether libintl exists and depends on libiconv. if test "$gt_cv_func_gnugettext_libintl" != yes && test -n "$LIBICONV"; then LIBS="$LIBS $LIBICONV" AC_TRY_LINK([#include ]ifelse([$2], [need-formatstring-macros], [#ifndef __GNU_GETTEXT_SUPPORTED_REVISION #define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) #endif changequote(,)dnl typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; changequote([,])dnl ], [])[extern int _nl_msg_cat_cntr; extern #ifdef __cplusplus "C" #endif const char *_nl_expand_alias ();], [bindtextdomain ("", ""); return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias (0)], [LIBINTL="$LIBINTL $LIBICONV" LTLIBINTL="$LTLIBINTL $LTLIBICONV" gt_cv_func_gnugettext_libintl=yes ]) fi CPPFLAGS="$gt_save_CPPFLAGS" LIBS="$gt_save_LIBS"]) fi dnl If an already present or preinstalled GNU gettext() is found, dnl use it. But if this macro is used in GNU gettext, and GNU dnl gettext is already preinstalled in libintl, we update this dnl libintl. (Cf. the install rule in intl/Makefile.in.) if test "$gt_cv_func_gnugettext_libc" = "yes" \ || { test "$gt_cv_func_gnugettext_libintl" = "yes" \ && test "$PACKAGE" != gettext-runtime \ && test "$PACKAGE" != gettext-tools; }; then gt_use_preinstalled_gnugettext=yes else dnl Reset the values set by searching for libintl. LIBINTL= LTLIBINTL= INCINTL= fi ifelse(gt_included_intl, yes, [ if test "$gt_use_preinstalled_gnugettext" != "yes"; then dnl GNU gettext is not found in the C library. dnl Fall back on included GNU gettext library. nls_cv_use_gnu_gettext=yes fi fi if test "$nls_cv_use_gnu_gettext" = "yes"; then dnl Mark actions used to generate GNU NLS library. BUILD_INCLUDED_LIBINTL=yes USE_INCLUDED_LIBINTL=yes LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV" LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV" LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'` fi if test "$gt_use_preinstalled_gnugettext" = "yes" \ || test "$nls_cv_use_gnu_gettext" = "yes"; then dnl Mark actions to use GNU gettext tools. CATOBJEXT=.gmo fi ]) if test "$gt_use_preinstalled_gnugettext" = "yes" \ || test "$nls_cv_use_gnu_gettext" = "yes"; then AC_DEFINE(ENABLE_NLS, 1, [Define to 1 if translation of program messages to the user's native language is requested.]) else USE_NLS=no fi fi AC_MSG_CHECKING([whether to use NLS]) AC_MSG_RESULT([$USE_NLS]) if test "$USE_NLS" = "yes"; then AC_MSG_CHECKING([where the gettext function comes from]) if test "$gt_use_preinstalled_gnugettext" = "yes"; then if test "$gt_cv_func_gnugettext_libintl" = "yes"; then gt_source="external libintl" else gt_source="libc" fi else gt_source="included intl directory" fi AC_MSG_RESULT([$gt_source]) fi if test "$USE_NLS" = "yes"; then if test "$gt_use_preinstalled_gnugettext" = "yes"; then if test "$gt_cv_func_gnugettext_libintl" = "yes"; then AC_MSG_CHECKING([how to link with libintl]) AC_MSG_RESULT([$LIBINTL]) AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL]) fi dnl For backward compatibility. Some packages may be using this. AC_DEFINE(HAVE_GETTEXT, 1, [Define if the GNU gettext() function is already present or preinstalled.]) AC_DEFINE(HAVE_DCGETTEXT, 1, [Define if the GNU dcgettext() function is already present or preinstalled.]) fi dnl We need to process the po/ directory. POSUB=po fi ifelse(gt_included_intl, yes, [ dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL dnl to 'yes' because some of the testsuite requires it. if test "$PACKAGE" = gettext-runtime || test "$PACKAGE" = gettext-tools; then BUILD_INCLUDED_LIBINTL=yes fi dnl Make all variables we use known to autoconf. AC_SUBST(BUILD_INCLUDED_LIBINTL) AC_SUBST(USE_INCLUDED_LIBINTL) AC_SUBST(CATOBJEXT) dnl For backward compatibility. Some configure.ins may be using this. nls_cv_header_intl= nls_cv_header_libgt= dnl For backward compatibility. Some Makefiles may be using this. DATADIRNAME=share AC_SUBST(DATADIRNAME) dnl For backward compatibility. Some Makefiles may be using this. INSTOBJEXT=.mo AC_SUBST(INSTOBJEXT) dnl For backward compatibility. Some Makefiles may be using this. GENCAT=gencat AC_SUBST(GENCAT) dnl For backward compatibility. Some Makefiles may be using this. if test "$USE_INCLUDED_LIBINTL" = yes; then INTLOBJS="\$(GETTOBJS)" fi AC_SUBST(INTLOBJS) dnl Enable libtool support if the surrounding package wishes it. INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix AC_SUBST(INTL_LIBTOOL_SUFFIX_PREFIX) ]) dnl For backward compatibility. Some Makefiles may be using this. INTLLIBS="$LIBINTL" AC_SUBST(INTLLIBS) dnl Make all documented variables known to autoconf. AC_SUBST(LIBINTL) AC_SUBST(LTLIBINTL) AC_SUBST(POSUB) ]) dnl Checks for all prerequisites of the intl subdirectory, dnl except for INTL_LIBTOOL_SUFFIX_PREFIX (and possibly LIBTOOL), INTLOBJS, dnl USE_INCLUDED_LIBINTL, BUILD_INCLUDED_LIBINTL. AC_DEFUN([AM_INTL_SUBDIR], [ AC_REQUIRE([AC_PROG_INSTALL])dnl AC_REQUIRE([AM_MKINSTALLDIRS])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_RANLIB])dnl AC_REQUIRE([AC_ISC_POSIX])dnl AC_REQUIRE([AC_HEADER_STDC])dnl AC_REQUIRE([AC_C_CONST])dnl AC_REQUIRE([AC_C_INLINE])dnl AC_REQUIRE([AC_TYPE_OFF_T])dnl AC_REQUIRE([AC_TYPE_SIZE_T])dnl AC_REQUIRE([AC_FUNC_ALLOCA])dnl AC_REQUIRE([AC_FUNC_MMAP])dnl AC_REQUIRE([jm_GLIBC21])dnl AC_REQUIRE([gt_INTDIV0])dnl AC_REQUIRE([jm_AC_TYPE_UINTMAX_T])dnl AC_REQUIRE([gt_HEADER_INTTYPES_H])dnl AC_REQUIRE([gt_INTTYPES_PRI])dnl AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h stddef.h \ stdlib.h string.h unistd.h sys/param.h]) AC_CHECK_FUNCS([feof_unlocked fgets_unlocked getc_unlocked getcwd getegid \ geteuid getgid getuid mempcpy munmap putenv setenv setlocale stpcpy \ strcasecmp strdup strtoul tsearch __argz_count __argz_stringify __argz_next \ __fsetlocking]) AM_ICONV AM_LANGINFO_CODESET if test $ac_cv_header_locale_h = yes; then AM_LC_MESSAGES fi dnl intl/plural.c is generated from intl/plural.y. It requires bison, dnl because plural.y uses bison specific features. It requires at least dnl bison-1.26 because earlier versions generate a plural.c that doesn't dnl compile. dnl bison is only needed for the maintainer (who touches plural.y). But in dnl order to avoid separate Makefiles or --enable-maintainer-mode, we put dnl the rule in general Makefile. Now, some people carelessly touch the dnl files or have a broken "make" program, hence the plural.c rule will dnl sometimes fire. To avoid an error, defines BISON to ":" if it is not dnl present or too old. AC_CHECK_PROGS([INTLBISON], [bison]) if test -z "$INTLBISON"; then ac_verc_fail=yes else dnl Found it, now check the version. AC_MSG_CHECKING([version of bison]) changequote(<<,>>)dnl ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'` case $ac_prog_version in '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; 1.2[6-9]* | 1.[3-9][0-9]* | [2-9].*) changequote([,])dnl ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; esac AC_MSG_RESULT([$ac_prog_version]) fi if test $ac_verc_fail = yes; then INTLBISON=: fi ]) dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version]) AC_DEFUN([AM_GNU_GETTEXT_VERSION], []) swami/m4/wchar_t.m40000644000175000017500000000155310072577776014315 0ustar alessioalessio# wchar_t.m4 serial 1 (gettext-0.12) dnl Copyright (C) 2002-2003 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Bruno Haible. dnl Test whether has the 'wchar_t' type. dnl Prerequisite: AC_PROG_CC AC_DEFUN([gt_TYPE_WCHAR_T], [ AC_CACHE_CHECK([for wchar_t], gt_cv_c_wchar_t, [AC_TRY_COMPILE([#include wchar_t foo = (wchar_t)'\0';], , gt_cv_c_wchar_t=yes, gt_cv_c_wchar_t=no)]) if test $gt_cv_c_wchar_t = yes; then AC_DEFINE(HAVE_WCHAR_T, 1, [Define if you have the 'wchar_t' type.]) fi ]) swami/m4/uintmax_t.m40000644000175000017500000000235010072577776014672 0ustar alessioalessio# uintmax_t.m4 serial 7 (gettext-0.12) dnl Copyright (C) 1997-2003 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Paul Eggert. AC_PREREQ(2.13) # Define uintmax_t to 'unsigned long' or 'unsigned long long' # if it is not already defined in or . AC_DEFUN([jm_AC_TYPE_UINTMAX_T], [ AC_REQUIRE([jm_AC_HEADER_INTTYPES_H]) AC_REQUIRE([jm_AC_HEADER_STDINT_H]) if test $jm_ac_cv_header_inttypes_h = no && test $jm_ac_cv_header_stdint_h = no; then AC_REQUIRE([jm_AC_TYPE_UNSIGNED_LONG_LONG]) test $ac_cv_type_unsigned_long_long = yes \ && ac_type='unsigned long long' \ || ac_type='unsigned long' AC_DEFINE_UNQUOTED(uintmax_t, $ac_type, [Define to unsigned long or unsigned long long if and don't define.]) else AC_DEFINE(HAVE_UINTMAX_T, 1, [Define if you have the 'uintmax_t' type in or .]) fi ]) swami/m4/intmax.m40000644000175000017500000000217210072577776014164 0ustar alessioalessio# intmax.m4 serial 1 (gettext-0.12) dnl Copyright (C) 2002-2003 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Bruno Haible. dnl Test whether the system has the 'intmax_t' type, but don't attempt to dnl find a replacement if it is lacking. AC_DEFUN([gt_TYPE_INTMAX_T], [ AC_REQUIRE([jm_AC_HEADER_INTTYPES_H]) AC_REQUIRE([jm_AC_HEADER_STDINT_H]) AC_CACHE_CHECK(for intmax_t, gt_cv_c_intmax_t, [AC_TRY_COMPILE([ #include #include #if HAVE_STDINT_H_WITH_UINTMAX #include #endif #if HAVE_INTTYPES_H_WITH_UINTMAX #include #endif ], [intmax_t x = -1;], gt_cv_c_intmax_t=yes, gt_cv_c_intmax_t=no)]) if test $gt_cv_c_intmax_t = yes; then AC_DEFINE(HAVE_INTMAX_T, 1, [Define if you have the 'intmax_t' type in or .]) fi ]) swami/m4/xsize.m40000644000175000017500000000103110072577776014017 0ustar alessioalessio# xsize.m4 serial 2 dnl Copyright (C) 2003 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. AC_DEFUN([gl_XSIZE], [ dnl Prerequisites of lib/xsize.h. AC_REQUIRE([gl_SIZE_MAX]) AC_CHECK_HEADERS(stdint.h) ]) swami/m4/ChangeLog0000644000175000017500000000412510333101113014134 0ustar alessioalessio2005-10-15 gettextize * gettext.m4: Upgrade to gettext-0.12.1. * lib-ld.m4: Upgrade to gettext-0.12.1. * lib-prefix.m4: Upgrade to gettext-0.12.1. * po.m4: Upgrade to gettext-0.12.1. * ulonglong.m4: Upgrade to gettext-0.12.1. 2004-07-02 gettextize * gettext.m4: Upgrade to gettext-0.13.1. * intmax.m4: New file, from gettext-0.13.1. * inttypes_h.m4: Upgrade to gettext-0.13.1. * lib-ld.m4: Upgrade to gettext-0.13.1. * lib-link.m4: Upgrade to gettext-0.13.1. * lib-prefix.m4: Upgrade to gettext-0.13.1. * longdouble.m4: New file, from gettext-0.13.1. * longlong.m4: New file, from gettext-0.13.1. * nls.m4: New file, from gettext-0.13.1. * po.m4: New file, from gettext-0.13.1. * printf-posix.m4: New file, from gettext-0.13.1. * progtest.m4: Upgrade to gettext-0.13.1. * signed.m4: New file, from gettext-0.13.1. * size_max.m4: New file, from gettext-0.13.1. * stdint_h.m4: Upgrade to gettext-0.13.1. * uintmax_t.m4: Upgrade to gettext-0.13.1. * ulonglong.m4: Upgrade to gettext-0.13.1. * wchar_t.m4: New file, from gettext-0.13.1. * wint_t.m4: New file, from gettext-0.13.1. * xsize.m4: New file, from gettext-0.13.1. * Makefile.am (EXTRA_DIST): Add the new files. 2003-06-24 gettextize * codeset.m4: New file, from gettext-0.11.5. * gettext.m4: New file, from gettext-0.11.5. * glibc21.m4: New file, from gettext-0.11.5. * iconv.m4: New file, from gettext-0.11.5. * intdiv0.m4: New file, from gettext-0.11.5. * inttypes.m4: New file, from gettext-0.11.5. * inttypes_h.m4: New file, from gettext-0.11.5. * inttypes-pri.m4: New file, from gettext-0.11.5. * isc-posix.m4: New file, from gettext-0.11.5. * lcmessage.m4: New file, from gettext-0.11.5. * lib-ld.m4: New file, from gettext-0.11.5. * lib-link.m4: New file, from gettext-0.11.5. * lib-prefix.m4: New file, from gettext-0.11.5. * progtest.m4: New file, from gettext-0.11.5. * stdint_h.m4: New file, from gettext-0.11.5. * uintmax_t.m4: New file, from gettext-0.11.5. * ulonglong.m4: New file, from gettext-0.11.5. * Makefile.am: New file. swami/m4/inttypes-pri.m40000644000175000017500000000222707711261100015305 0ustar alessioalessio# inttypes-pri.m4 serial 1 (gettext-0.11.4) dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Bruno Haible. # Define PRI_MACROS_BROKEN if exists and defines the PRI* # macros to non-string values. This is the case on AIX 4.3.3. AC_DEFUN([gt_INTTYPES_PRI], [ AC_REQUIRE([gt_HEADER_INTTYPES_H]) if test $gt_cv_header_inttypes_h = yes; then AC_CACHE_CHECK([whether the inttypes.h PRIxNN macros are broken], gt_cv_inttypes_pri_broken, [ AC_TRY_COMPILE([#include #ifdef PRId32 char *p = PRId32; #endif ], [], gt_cv_inttypes_pri_broken=no, gt_cv_inttypes_pri_broken=yes) ]) fi if test "$gt_cv_inttypes_pri_broken" = yes; then AC_DEFINE_UNQUOTED(PRI_MACROS_BROKEN, 1, [Define if exists and defines unusable PRI* macros.]) fi ]) swami/m4/libtool.m40000644000175000017500000077464711464144605014342 0ustar alessioalessio# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ]) # serial 56 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_CC_BASENAME(CC) # ------------------- # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. m4_defun([_LT_CC_BASENAME], [for cc_temp in $1""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl _LT_PROG_ECHO_BACKSLASH case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from `configure', and `config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # `config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain="$ac_aux_dir/ltmain.sh" ])# _LT_PROG_LTMAIN ## ------------------------------------- ## ## Accumulate code for creating libtool. ## ## ------------------------------------- ## # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the `libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) ## ------------------------ ## ## FIXME: Eliminate VARNAME ## ## ------------------------ ## # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to `config.status' so that its # declaration there will have the same value as in `configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "X$][$1" | $Xsed -e "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "X$" | $Xsed -e "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags="_LT_TAGS"dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the `libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into `config.status', and then the shell code to quote escape them in # for loops in `config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Fix-up fallback echo if it was mangled by the above quoting rules. case \$lt_ECHO in *'\\\[$]0 --fallback-echo"')dnl " lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\[$]0 --fallback-echo"\[$]/\[$]0 --fallback-echo"/'\` ;; esac _LT_OUTPUT_LIBTOOL_INIT ]) # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) cat >"$CONFIG_LT" <<_LTEOF #! $SHELL # Generated by $as_me. # Run this file to recreate a libtool stub with the current configuration. lt_cl_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ \`$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2008 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test $[#] != 0 do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try \`$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try \`$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. if test "$no_create" != yes; then lt_cl_success=: test "$silent" = yes && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) fi ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # _LT_COPYING _LT_LIBTOOL_TAGS # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) _LT_PROG_XSI_SHELLFNS sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS="$save_LDFLAGS" ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[[012]]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES # -------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(whole_archive_flag_spec, $1)='' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=echo _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" m4_if([$1], [CXX], [ if test "$lt_cv_apple_cc_single_mod" != "yes"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX # ----------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl AC_LINK_IFELSE(AC_LANG_PROGRAM,[ lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/ p } }' aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [ifdef([AC_DIVERSION_NOTICE], [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], [AC_DIVERT_PUSH(NOTICE)]) $1 AC_DIVERT_POP ])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Add some code to the start of the generated configure script which # will find an echo command which doesn't interpret backslashes. m4_defun([_LT_PROG_ECHO_BACKSLASH], [_LT_SHELL_INIT([ # Check that we are running under the correct shell. SHELL=${CONFIG_SHELL-/bin/sh} case X$lt_ECHO in X*--fallback-echo) # Remove one level of quotation (which was required for Make). ECHO=`echo "$lt_ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` ;; esac ECHO=${lt_ECHO-echo} if test "X[$]1" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test "X[$]1" = X--fallback-echo; then # Avoid inline document here, it may be left over : elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then # Yippee, $ECHO works! : else # Restart under the correct shell. exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} fi if test "X[$]1" = X--fallback-echo; then # used as fallback echo shift cat <<_LT_EOF [$]* _LT_EOF exit 0 fi # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test -z "$lt_ECHO"; then if test "X${echo_test_string+set}" != Xset; then # find a string as large as possible, as long as the shell can cope with it for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... if { echo_test_string=`eval $cmd`; } 2>/dev/null && { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null then break fi done fi if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then : else # The Solaris, AIX, and Digital Unix default echo programs unquote # backslashes. This makes it impossible to quote backslashes using # echo "$something" | sed 's/\\/\\\\/g' # # So, first we look for a working echo in the user's PATH. lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for dir in $PATH /usr/ucb; do IFS="$lt_save_ifs" if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then ECHO="$dir/echo" break fi done IFS="$lt_save_ifs" if test "X$ECHO" = Xecho; then # We didn't find a better echo, so look for alternatives. if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # This shell has a builtin print -r that does the trick. ECHO='print -r' elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && test "X$CONFIG_SHELL" != X/bin/ksh; then # If we have ksh, try running configure again with it. ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} export ORIGINAL_CONFIG_SHELL CONFIG_SHELL=/bin/ksh export CONFIG_SHELL exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} else # Try using printf. ECHO='printf %s\n' if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # Cool, printf works : elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL export CONFIG_SHELL SHELL="$CONFIG_SHELL" export SHELL ECHO="$CONFIG_SHELL [$]0 --fallback-echo" elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then ECHO="$CONFIG_SHELL [$]0 --fallback-echo" else # maybe with a smaller string... prev=: for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null then break fi prev="$cmd" done if test "$prev" != 'sed 50q "[$]0"'; then echo_test_string=`eval $prev` export echo_test_string exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} else # Oops. We lost completely, so just stick with echo. ECHO=echo fi fi fi fi fi fi # Copy echo and quote the copy suitably for passing to libtool from # the Makefile, instead of quoting the original, which is used later. lt_ECHO=$ECHO if test "X$lt_ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then lt_ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" fi AC_SUBST(lt_ECHO) ]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that does not interpret backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '[#]line __oline__ "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; sparc*-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) LD="${LD-ld} -m elf64_sparc" ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" ])# _LT_ENABLE_LOCK # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [AC_CHECK_TOOL(AR, ar, false) test -z "$AR" && AR=ar test -z "$AR_FLAGS" && AR_FLAGS=cru _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1]) AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" fi _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test x"[$]$2" = xyes; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" ]) if test x"[$]$2" = xyes; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ = "XX$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n $lt_cv_sys_max_cmd_len ; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "$cross_compiling" = yes; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line __oline__ "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif void fnord() { int i=42;} int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen="shl_load"], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen="dlopen"], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) ]) ]) ]) ]) ]) ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links="nottested" if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test "$hard_links" = no; then AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", [Define to the sub-directory in which libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then # We can hardcode non-existent directories. if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` else lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[[4-9]]*) version_type=linux need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$host_os in yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH printed by # mingw gcc, but we are running on Cygwin. Gcc prints its search # path with ; separators, and with drive letters. We can handle the # drive letters (cygwin fileutils understands them), so leave them, # especially as we might pass files found there to a mingw objdump, # which wouldn't understand a cygwinified path. Ahh. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; esac ;; *) library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' ;; esac dynamic_linker='Win32 ld.exe' # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd1*) dynamic_linker=no ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[123]]*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555. postinstall_cmds='chmod 555 $lib' ;; interix[[3-9]]*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be Linux ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[[89]] | openbsd2.[[89]].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([], [sys_lib_dlsearch_path_spec], [2], [Run-time system search path for libraries]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program which can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$1; then lt_cv_path_MAGIC_CMD="$ac_dir/$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac]) MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program which can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test "$withval" = no || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; gnu*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be Linux ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method == "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi]) if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. AC_CHECK_TOOLS(DUMPBIN, ["dumpbin -symbols" "link -dump -symbols"], :) AC_SUBST([DUMPBIN]) if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:__oline__: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:__oline__: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:__oline__: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM="-lm") ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test "$GCC" = yes; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ const struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_save_LIBS="$LIBS" lt_save_CFLAGS="$CFLAGS" LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS="$lt_save_LIBS" CFLAGS="$lt_save_CFLAGS" else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= AC_MSG_CHECKING([for $compiler option to produce PIC]) m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64 which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC*) # IBM XL 8.0 on PPC _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test "$GCC" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; pgcc* | pgf77* | pgf90* | pgf95*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl*) # IBM XL C 8.0/Fortran 10.1 on PPC _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Sun\ F*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_MSG_RESULT([$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ;; cygwin* | mingw* | cegcc*) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' ;; linux* | k*bsd*-gnu) _LT_TAGVAR(link_all_deplibs, $1)=no ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; linux* | k*bsd*-gnu) _LT_TAGVAR(link_all_deplibs, $1)=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes if test "$with_gnu_ld" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.9.1, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to modify your PATH *** so that a non-GNU linker is found, and then restart. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag= tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; xl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi _LT_TAGVAR(link_all_deplibs, $1)=no else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; freebsd1*) _LT_TAGVAR(ld_shlibs, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; hpux10*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" AC_LINK_IFELSE(int foo(void) {}, _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' ) LDFLAGS="$save_LDFLAGS" else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' else case $host_os in openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ;; esac fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_MSG_CHECKING([whether -lc should be explicitly linked in]) $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then _LT_TAGVAR(archive_cmds_need_lc, $1)=no else _LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* AC_MSG_RESULT([$_LT_TAGVAR(archive_cmds_need_lc, $1)]) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1], [[If ld is used when linking, flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting ${shlibpath_var} if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [fix_srcfile_path], [1], [Fix the shell variable $srcfile for the compiler]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC="$CC" AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report which library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC="$lt_save_CC" ])# _LT_LANG_C_CONFIG # _LT_PROG_CXX # ------------ # Since AC_PROG_CXX is broken, in that it returns g++ if there is no c++ # compiler, we have our own version here. m4_defun([_LT_PROG_CXX], [ pushdef([AC_MSG_ERROR], [_lt_caught_CXX_error=yes]) AC_PROG_CXX if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi popdef([AC_MSG_ERROR]) ])# _LT_PROG_CXX dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([_LT_PROG_CXX], []) # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [AC_REQUIRE([_LT_PROG_CXX])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_caught_CXX_error" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test "$GXX" = yes; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='${wl}' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GXX" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared # libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd[[12]]*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; gnu*) ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; *) if test "$GXX" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]]* | *pgcpp\ [[1-5]]*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; *) # Version 6 will use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; xl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='echo' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd2*) # C++ shared libraries are fairly broken _LT_TAGVAR(ld_shlibs, $1)=no ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' fi output_verbose_link_cmd=echo else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='echo' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(GCC, $1)="$GXX" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test "$_lt_caught_CXX_error" != yes AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ]) dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case $p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" || test $p = "-R"; then prev=$p continue else prev= fi if test "$pre_test_object_deps_done" = no; then case $p in -L* | -R*) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)="${prev}${p}" else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" fi fi ;; *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test "$pre_test_object_deps_done" = no; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)="$p" else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)="$p" else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; solaris*) case $cc_basename in CC*) # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_PROG_F77 # ------------ # Since AC_PROG_F77 is broken, in that it returns the empty string # if there is no fortran compiler, we have our own version here. m4_defun([_LT_PROG_F77], [ pushdef([AC_MSG_ERROR], [_lt_disable_F77=yes]) AC_PROG_F77 if test -z "$F77" || test "X$F77" = "Xno"; then _lt_disable_F77=yes fi popdef([AC_MSG_ERROR]) ])# _LT_PROG_F77 dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([_LT_PROG_F77], []) # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_REQUIRE([_LT_PROG_F77])dnl AC_LANG_PUSH(Fortran 77) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_F77" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC CC=${F77-"f77"} compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$G77" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC="$lt_save_CC" fi # test "$_lt_disable_F77" != yes AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_PROG_FC # ----------- # Since AC_PROG_FC is broken, in that it returns the empty string # if there is no fortran compiler, we have our own version here. m4_defun([_LT_PROG_FC], [ pushdef([AC_MSG_ERROR], [_lt_disable_FC=yes]) AC_PROG_FC if test -z "$FC" || test "X$FC" = "Xno"; then _lt_disable_FC=yes fi popdef([AC_MSG_ERROR]) ])# _LT_PROG_FC dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([_LT_PROG_FC], []) # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_REQUIRE([_LT_PROG_FC])dnl AC_LANG_PUSH(Fortran) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_FC" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC CC=${FC-"f95"} compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC="$lt_save_CC" fi # test "$_lt_disable_FC" != yes AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC="$lt_save_CC" ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code="$lt_simple_compile_test_code" # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC GCC= CC=${RC-"windres"} compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC="$lt_save_CC" ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f $lt_ac_sed && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test $lt_ac_count -gt 10 && break lt_ac_count=`expr $lt_ac_count + 1` if test $lt_ac_count -gt $lt_ac_max; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [AC_MSG_CHECKING([whether the shell understands some XSI constructs]) # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes AC_MSG_RESULT([$xsi_shell]) _LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) AC_MSG_CHECKING([whether the shell understands "+="]) lt_shell_append=no ( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes AC_MSG_RESULT([$lt_shell_append]) _LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PROG_XSI_SHELLFNS # --------------------- # Bourne and XSI compatible variants of some useful shell functions. m4_defun([_LT_PROG_XSI_SHELLFNS], [case $xsi_shell in yes) cat << \_LT_EOF >> "$cfgfile" # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac } # func_basename file func_basename () { func_basename_result="${1##*/}" } # func_dirname_and_basename file append nondir_replacement # perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac func_basename_result="${1##*/}" } # func_stripname prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). func_stripname () { # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary parameter first. func_stripname_result=${3} func_stripname_result=${func_stripname_result#"${1}"} func_stripname_result=${func_stripname_result%"${2}"} } # func_opt_split func_opt_split () { func_opt_split_opt=${1%%=*} func_opt_split_arg=${1#*=} } # func_lo2o object func_lo2o () { case ${1} in *.lo) func_lo2o_result=${1%.lo}.${objext} ;; *) func_lo2o_result=${1} ;; esac } # func_xform libobj-or-source func_xform () { func_xform_result=${1%.*}.lo } # func_arith arithmetic-term... func_arith () { func_arith_result=$(( $[*] )) } # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=${#1} } _LT_EOF ;; *) # Bourne compatible functions. cat << \_LT_EOF >> "$cfgfile" # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi } # func_basename file func_basename () { func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` } dnl func_dirname_and_basename dnl A portable version of this function is already defined in general.m4sh dnl so there is no need for it here. # func_stripname prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # func_strip_suffix prefix name func_stripname () { case ${2} in .*) func_stripname_result=`$ECHO "X${3}" \ | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "X${3}" \ | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; esac } # sed scripts: my_sed_long_opt='1s/^\(-[[^=]]*\)=.*/\1/;q' my_sed_long_arg='1s/^-[[^=]]*=//' # func_opt_split func_opt_split () { func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` } # func_lo2o object func_lo2o () { func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` } # func_xform libobj-or-source func_xform () { func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[[^.]]*$/.lo/'` } # func_arith arithmetic-term... func_arith () { func_arith_result=`expr "$[@]"` } # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=`expr "$[1]" : ".*" 2>/dev/null || echo $max_cmd_len` } _LT_EOF esac case $lt_shell_append in yes) cat << \_LT_EOF >> "$cfgfile" # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "$[1]+=\$[2]" } _LT_EOF ;; *) cat << \_LT_EOF >> "$cfgfile" # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "$[1]=\$$[1]\$[2]" } _LT_EOF ;; esac ]) swami/m4/ulonglong.m40000644000175000017500000000200010333101113014616 0ustar alessioalessio# ulonglong.m4 serial 2 (fileutils-4.0.32, gettext-0.10.40) dnl Copyright (C) 1999-2002 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Paul Eggert. AC_DEFUN([jm_AC_TYPE_UNSIGNED_LONG_LONG], [ AC_CACHE_CHECK([for unsigned long long], ac_cv_type_unsigned_long_long, [AC_TRY_LINK([unsigned long long ull = 1; int i = 63;], [unsigned long long ullmax = (unsigned long long) -1; return ull << i | ull >> i | ullmax / ull | ullmax % ull;], ac_cv_type_unsigned_long_long=yes, ac_cv_type_unsigned_long_long=no)]) if test $ac_cv_type_unsigned_long_long = yes; then AC_DEFINE(HAVE_UNSIGNED_LONG_LONG, 1, [Define if you have the unsigned long long type.]) fi ]) swami/m4/lib-prefix.m40000644000175000017500000001250510333101113014666 0ustar alessioalessio# lib-prefix.m4 serial 2 (gettext-0.12) dnl Copyright (C) 2001-2003 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General dnl Public License, this file may be distributed as part of a program dnl that contains a configuration script generated by Autoconf, under dnl the same distribution terms as the rest of that program. dnl From Bruno Haible. dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't dnl require excessive bracketing. ifdef([AC_HELP_STRING], [AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])], [AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])]) dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed dnl to access previously installed libraries. The basic assumption is that dnl a user will want packages to use other packages he previously installed dnl with the same --prefix option. dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate dnl libraries, but is otherwise very convenient. AC_DEFUN([AC_LIB_PREFIX], [ AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) dnl By default, look in $includedir and $libdir. use_additional=yes AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) AC_LIB_ARG_WITH([lib-prefix], [ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib --without-lib-prefix don't search for libraries in includedir and libdir], [ if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) else additional_includedir="$withval/include" additional_libdir="$withval/lib" fi fi ]) if test $use_additional = yes; then dnl Potentially add $additional_includedir to $CPPFLAGS. dnl But don't add it dnl 1. if it's the standard /usr/include, dnl 2. if it's already present in $CPPFLAGS, dnl 3. if it's /usr/local/include and we are using GCC on Linux, dnl 4. if it doesn't exist as a directory. if test "X$additional_includedir" != "X/usr/include"; then haveit= for x in $CPPFLAGS; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux*) haveit=yes;; esac fi fi if test -z "$haveit"; then if test -d "$additional_includedir"; then dnl Really add $additional_includedir to $CPPFLAGS. CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" fi fi fi fi dnl Potentially add $additional_libdir to $LDFLAGS. dnl But don't add it dnl 1. if it's the standard /usr/lib, dnl 2. if it's already present in $LDFLAGS, dnl 3. if it's /usr/local/lib and we are using GCC on Linux, dnl 4. if it doesn't exist as a directory. if test "X$additional_libdir" != "X/usr/lib"; then haveit= for x in $LDFLAGS; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test "X$additional_libdir" = "X/usr/local/lib"; then if test -n "$GCC"; then case $host_os in linux*) haveit=yes;; esac fi fi if test -z "$haveit"; then if test -d "$additional_libdir"; then dnl Really add $additional_libdir to $LDFLAGS. LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" fi fi fi fi fi ]) dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, dnl acl_final_exec_prefix, containing the values to which $prefix and dnl $exec_prefix will expand at the end of the configure script. AC_DEFUN([AC_LIB_PREPARE_PREFIX], [ dnl Unfortunately, prefix and exec_prefix get only finally determined dnl at the end of configure. if test "X$prefix" = "XNONE"; then acl_final_prefix="$ac_default_prefix" else acl_final_prefix="$prefix" fi if test "X$exec_prefix" = "XNONE"; then acl_final_exec_prefix='${prefix}' else acl_final_exec_prefix="$exec_prefix" fi acl_save_prefix="$prefix" prefix="$acl_final_prefix" eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" prefix="$acl_save_prefix" ]) dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the dnl variables prefix and exec_prefix bound to the values they will have dnl at the end of the configure script. AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], [ acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" $1 exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" ]) swami/intltool-extract.in0000644000175000017500000000000011344522607015714 0ustar alessioalessioswami/cmake/0000755000175000017500000000000011716016655013146 5ustar alessioalessioswami/cmake/CheckDIRSymbolExists.cmake0000644000175000017500000000666711464144605020126 0ustar alessioalessio# - Check if the DIR symbol exists like in AC_HEADER_DIRENT. # CHECK_DIRSYMBOL_EXISTS(FILES VARIABLE) # # FILES - include files to check # VARIABLE - variable to return result # # This module is a small but important variation on CheckSymbolExists.cmake. # The symbol always searched for is DIR, and the test programme follows # the AC_HEADER_DIRENT test programme rather than the CheckSymbolExists.cmake # test programme which always fails since DIR tends to be typedef'd # rather than #define'd. # # The following variables may be set before calling this macro to # modify the way the check is run: # # CMAKE_REQUIRED_FLAGS = string of compile command line flags # CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar) # CMAKE_REQUIRED_INCLUDES = list of include directories # CMAKE_REQUIRED_LIBRARIES = list of libraries to link MACRO(CHECK_DIRSYMBOL_EXISTS FILES VARIABLE) IF(NOT DEFINED ${VARIABLE}) SET(CMAKE_CONFIGURABLE_FILE_CONTENT "/* */\n") SET(MACRO_CHECK_DIRSYMBOL_EXISTS_FLAGS ${CMAKE_REQUIRED_FLAGS}) IF(CMAKE_REQUIRED_LIBRARIES) SET(CHECK_DIRSYMBOL_EXISTS_LIBS "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") ELSE(CMAKE_REQUIRED_LIBRARIES) SET(CHECK_DIRSYMBOL_EXISTS_LIBS) ENDIF(CMAKE_REQUIRED_LIBRARIES) IF(CMAKE_REQUIRED_INCLUDES) SET(CMAKE_DIRSYMBOL_EXISTS_INCLUDES "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}") ELSE(CMAKE_REQUIRED_INCLUDES) SET(CMAKE_DIRSYMBOL_EXISTS_INCLUDES) ENDIF(CMAKE_REQUIRED_INCLUDES) FOREACH(FILE ${FILES}) SET(CMAKE_CONFIGURABLE_FILE_CONTENT "${CMAKE_CONFIGURABLE_FILE_CONTENT}#include <${FILE}>\n") ENDFOREACH(FILE) SET(CMAKE_CONFIGURABLE_FILE_CONTENT "${CMAKE_CONFIGURABLE_FILE_CONTENT}\nint main()\n{if ((DIR *) 0) return 0;}\n") CONFIGURE_FILE("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in" "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/CheckDIRSymbolExists.c" @ONLY) MESSAGE(STATUS "Looking for DIR in ${FILES}") TRY_COMPILE(${VARIABLE} ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/CheckDIRSymbolExists.c COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_DIRSYMBOL_EXISTS_FLAGS} "${CHECK_DIRSYMBOL_EXISTS_LIBS}" "${CMAKE_DIRSYMBOL_EXISTS_INCLUDES}" OUTPUT_VARIABLE OUTPUT) IF(${VARIABLE}) MESSAGE(STATUS "Looking for DIR in ${FILES} - found") SET(${VARIABLE} 1 CACHE INTERNAL "Have symbol DIR") FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log "Determining if the DIR symbol is defined as in AC_HEADER_DIRENT " "passed with the following output:\n" "${OUTPUT}\nFile ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/CheckDIRSymbolExists.c:\n" "${CMAKE_CONFIGURABLE_FILE_CONTENT}\n") ELSE(${VARIABLE}) MESSAGE(STATUS "Looking for DIR in ${FILES} - not found.") SET(${VARIABLE} "" CACHE INTERNAL "Have symbol DIR") FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log "Determining if the DIR symbol is defined as in AC_HEADER_DIRENT " "failed with the following output:\n" "${OUTPUT}\nFile ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/CheckDIRSymbolExists.c:\n" "${CMAKE_CONFIGURABLE_FILE_CONTENT}\n") ENDIF(${VARIABLE}) ENDIF(NOT DEFINED ${VARIABLE}) ENDMACRO(CHECK_DIRSYMBOL_EXISTS) swami/cmake/CheckPrototypeExists.cmake0000644000175000017500000000237411464144605020316 0ustar alessioalessio# - Check if the prototype for a function exists. # CHECK_PROTOTYPE_EXISTS (FUNCTION HEADER VARIABLE) # # FUNCTION - the name of the function you are looking for # HEADER - the header(s) where the prototype should be declared # VARIABLE - variable to store the result # # The following variables may be set before calling this macro to # modify the way the check is run: # # CMAKE_REQUIRED_FLAGS = string of compile command line flags # CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar) # CMAKE_REQUIRED_INCLUDES = list of include directories # Copyright (c) 2006, Alexander Neundorf, # # Redistribution and use is allowed according to the terms of the BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. INCLUDE(CheckCSourceCompiles) MACRO (CHECK_PROTOTYPE_EXISTS _SYMBOL _HEADER _RESULT) SET(_INCLUDE_FILES) FOREACH (it ${_HEADER}) SET(_INCLUDE_FILES "${_INCLUDE_FILES}#include <${it}>\n") ENDFOREACH (it) SET(_CHECK_PROTO_EXISTS_SOURCE_CODE " ${_INCLUDE_FILES} int main() { #ifndef ${_SYMBOL} int i = sizeof(&${_SYMBOL}); #endif return 0; } ") CHECK_C_SOURCE_COMPILES("${_CHECK_PROTO_EXISTS_SOURCE_CODE}" ${_RESULT}) ENDMACRO (CHECK_PROTOTYPE_EXISTS _SYMBOL _HEADER _RESULT) swami/cmake/DefaultDirs.cmake0000644000175000017500000000501011464144605016347 0ustar alessioalessio# Several directory names used by libInstPatch to install files # the variable names are similar to the KDE4 build system # BUNDLE_INSTALL_DIR - Mac only: the directory for application bundles set (BUNDLE_INSTALL_DIR "/Applications" CACHE STRING "The install dir for application bundles") mark_as_advanced (BUNDLE_INSTALL_DIR) # FRAMEWORK_INSTALL_DIR - Mac only: the directory for framework bundles set (FRAMEWORK_INSTALL_DIR "/Library/Frameworks" CACHE STRING "The install dir for framework bundles") mark_as_advanced (FRAMEWORK_INSTALL_DIR) # BIN_INSTALL_DIR - the directory where executables will be installed set (BIN_INSTALL_DIR "bin" CACHE STRING "The install dir for executables") mark_as_advanced (BIN_INSTALL_DIR) # SBIN_INSTALL_DIR - the directory where system executables will be installed set (SBIN_INSTALL_DIR "sbin" CACHE STRING "The install dir for system executables") mark_as_advanced (SBIN_INSTALL_DIR) # LIB_INSTALL_DIR - the directory where libraries will be installed set (LIB_INSTALL_DIR "lib" CACHE STRING "The install dir for libraries") mark_as_advanced (LIB_INSTALL_DIR) # INCLUDE_INSTALL_DIR - the install dir for header files set (INCLUDE_INSTALL_DIR "include" CACHE STRING "The install dir for headers") mark_as_advanced (INCLUDE_INSTALL_DIR) # DATA_INSTALL_DIR - the base install directory for data files set (DATA_INSTALL_DIR "share" CACHE STRING "The base install dir for data files") mark_as_advanced (DATA_INSTALL_DIR) # DOC_INSTALL_DIR - the install dir for documentation set (DOC_INSTALL_DIR "share/doc" CACHE STRING "The install dir for documentation") mark_as_advanced (DOC_INSTALL_DIR) # PLUGINS_DIR - the directory where application plugins will be installed if ( UNIX ) set (PLUGINS_DIR "${CMAKE_INSTALL_PREFIX}/lib/swami" CACHE STRING "The install dir for plugins") else ( UNIX ) set (PLUGINS_DIR "plugins" CACHE STRING "The install dir for plugins") endif ( UNIX ) mark_as_advanced (PLUGINS_DIR) # IMAGES_DIR - the directory where images are installed if ( UNIX ) set (IMAGES_DIR "${CMAKE_INSTALL_PREFIX}/share/swami/images" CACHE STRING "The install dir for images") else ( UNIX ) set (IMAGES_DIR "images" CACHE STRING "The install dir for images") endif ( UNIX ) mark_as_advanced (IMAGES_DIR) # UIXML_DIR - the directory where UI XML is installed if ( UNIX ) set (UIXML_DIR "${CMAKE_INSTALL_PREFIX}/share/swami" CACHE STRING "The install dir for UI XML files") else ( UNIX ) set (UIXML_DIR "." CACHE STRING "The install dir for UI XML files") endif ( UNIX ) mark_as_advanced (UIXML_DIR) swami/cmake/Makefile.am0000644000175000017500000000061211464144605015176 0ustar alessioalessio## Process this file with automake to produce Makefile.in EXTRA_DIST = CheckDIRSymbolExists.cmake \ CheckPrototypeExists.cmake \ CheckSTDC.cmake \ cmake_uninstall.cmake.in \ DefaultDirs.cmake \ FindMidiShare.cmake \ FindOSS.cmake \ FindPthreads.cmake \ FindReadline.cmake \ report.cmake \ TestInline.cmake \ TestVLA.cmake \ UnsetPkgConfig.cmake swami/cmake/CheckSTDC.cmake0000644000175000017500000000231511464144605015641 0ustar alessioalessiomessage(STATUS "Checking whether system has ANSI C header files") include(CheckPrototypeExists) include(CheckIncludeFiles) check_include_files("dlfcn.h;stdint.h;stddef.h;inttypes.h;stdlib.h;strings.h;string.h;float.h" StandardHeadersExist) if(StandardHeadersExist) check_prototype_exists(memchr string.h memchrExists) if(memchrExists) check_prototype_exists(free stdlib.h freeExists) if(freeExists) message(STATUS "ANSI C header files - found") set(STDC_HEADERS 1 CACHE INTERNAL "System has ANSI C header files") set(HAVE_STRINGS_H 1) set(HAVE_STRING_H 1) set(HAVE_FLOAT_H 1) set(HAVE_STDLIB_H 1) set(HAVE_STDDEF_H 1) set(HAVE_STDINT_H 1) set(HAVE_INTTYPES_H 1) set(HAVE_DLFCN_H 1) endif(freeExists) endif(memchrExists) endif(StandardHeadersExist) if(NOT STDC_HEADERS) message(STATUS "ANSI C header files - not found") set(STDC_HEADERS 0 CACHE INTERNAL "System has ANSI C header files") endif(NOT STDC_HEADERS) check_include_files(unistd.h HAVE_UNISTD_H) include(CheckDIRSymbolExists) check_dirsymbol_exists("sys/stat.h;sys/types.h;dirent.h" HAVE_DIRENT_H) if (HAVE_DIRENT_H) set(HAVE_SYS_STAT_H 1) set(HAVE_SYS_TYPES_H 1) endif (HAVE_DIRENT_H) swami/cmake/cmake_uninstall.cmake.in0000644000175000017500000000155511464144605017731 0ustar alessioalessioIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) STRING(REGEX REPLACE "\n" ";" files "${files}") FOREACH(file ${files}) MESSAGE(STATUS "Uninstalling \"${file}\"") IF(EXISTS "${file}") EXEC_PROGRAM( "@CMAKE_COMMAND@" ARGS "-E remove \"${file}\"" OUTPUT_VARIABLE rm_out RETURN_VALUE rm_retval ) IF("${rm_retval}" STREQUAL 0) ELSE("${rm_retval}" STREQUAL 0) MESSAGE(FATAL_ERROR "Problem when removing \"${file}\"") ENDIF("${rm_retval}" STREQUAL 0) ELSE(EXISTS "${file}") MESSAGE(STATUS "File \"${file}\" does not exist.") ENDIF(EXISTS "${file}") ENDFOREACH(file) swami/cmake/UnsetPkgConfig.cmake0000644000175000017500000000104111464144605017027 0ustar alessioalessiomacro ( unset_pkg_config _prefix ) unset ( ${_prefix}_VERSION CACHE ) unset ( ${_prefix}_PREFIX CACHE ) unset ( ${_prefix}_CFLAGS CACHE ) unset ( ${_prefix}_CFLAGS_OTHER CACHE ) unset ( ${_prefix}_LDFLAGS CACHE ) unset ( ${_prefix}_LDFLAGS_OTHER CACHE ) unset ( ${_prefix}_LIBRARIES CACHE ) unset ( ${_prefix}_INCLUDEDIR CACHE ) unset ( ${_prefix}_INCLUDE_DIRS CACHE ) unset ( ${_prefix}_LIBDIR CACHE ) unset ( ${_prefix}_LIBRARY_DIRS CACHE ) unset ( __pkg_config_checked_${_prefix} CACHE ) endmacro ( unset_pkg_config ) swami/swami.anjuta0000644000175000017500000000303411454115203014376 0ustar alessioalessio swami/intltool-merge.in0000644000175000017500000000000011344522607015341 0ustar alessioalessioswami/configure.ac0000644000175000017500000001554611464144605014364 0ustar alessioalessiodnl -------------------------------------------------- dnl configure.in for Swami dnl -------------------------------------------------- AC_INIT(src/swamigui/main.c) SWAMI_VERSION_MAJOR=2 SWAMI_VERSION_MINOR=0 SWAMI_VERSION_MICRO=0 SWAMI_VERSION=$SWAMI_VERSION_MAJOR.$SWAMI_VERSION_MINOR.$SWAMI_VERSION_MICRO AC_SUBST(SWAMI_VERSION_MAJOR) AC_SUBST(SWAMI_VERSION_MINOR) AC_SUBST(SWAMI_VERSION_MICRO) AC_SUBST(SWAMI_VERSION) dnl - Check build environment AC_CANONICAL_SYSTEM AM_INIT_AUTOMAKE(swami, $SWAMI_VERSION) AM_CONFIG_HEADER(config.h) SWAMI_VERSION="\"$VERSION\"" CFLAGS="$CFLAGS -Wall" dnl - Program checks AC_PROG_CC dnl International language support ALL_LINGUAS="" AM_GNU_GETTEXT([external]) AC_PROG_INTLTOOL AC_PROG_INSTALL AC_HEADER_STDC AC_LIBTOOL_WIN32_DLL AM_PROG_LIBTOOL dnl - Check for mingw Win32 gcc environment AC_MINGW32 if test "${MINGW32}" == "yes" ; then AC_DEFINE(MINGW32, 1, [Define if using the mingw environment]) fi AC_MSG_CHECKING([for native Win32]) case "$host" in *-*-mingw*) native_win32=yes ;; *) native_win32=no ;; esac AC_MSG_RESULT([$native_win32]) AM_CONDITIONAL(OS_WIN32, test "$native_win32" = yes) AC_MSG_CHECKING([for Win32 platform in general]) case "$host" in *-*-mingw*|*-*-cygwin*) platform_win32=yes ;; *) platform_win32=no ;; esac AC_MSG_RESULT($platform_win32) AM_CONDITIONAL(PLATFORM_WIN32, test "$platform_win32" = yes) # Ensure MSVC-compatible struct packing convention is used when # compiling for Win32 with gcc. GTK+ uses this convention, so we must, too. # What flag to depends on gcc version: gcc3 uses "-mms-bitfields", while # gcc2 uses "-fnative-struct". if test x"$native_win32" = xyes; then if test x"$GCC" = xyes; then msnative_struct='' AC_MSG_CHECKING([how to get MSVC-compatible struct packing]) if test -z "$ac_cv_prog_CC"; then our_gcc="$CC" else our_gcc="$ac_cv_prog_CC" fi case `$our_gcc --version | sed -e 's,\..*,.,' -e q` in 2.) if $our_gcc -v --help 2>/dev/null | grep fnative-struct >/dev/null; then msnative_struct='-fnative-struct' fi ;; *) if $our_gcc -v --help 2>/dev/null | grep ms-bitfields >/dev/null; then msnative_struct='-mms-bitfields' fi ;; esac if test x"$msnative_struct" = x ; then AC_MSG_RESULT([no way]) AC_MSG_WARN([produced libraries will be incompatible with prebuilt GTK+ DLLs]) else CFLAGS="$CFLAGS $msnative_struct" AC_MSG_RESULT([${msnative_struct}]) fi fi fi dnl - Check for debugging and profiling flags AC_DEBUGGING AC_PROFILING PKG_CHECK_MODULES(LIBINSTPATCH, libinstpatch-1.0 >= 1.0) AC_SUBST(LIBINSTPATCH_CFLAGS) AC_SUBST(LIBINSTPATCH_LIBS) PKG_CHECK_MODULES(GUI, gtk+-2.0 >= 2.12 librsvg-2.0 >= 2.8 libgnomecanvas-2.0 >= 2.0) AC_SUBST(GUI_CFLAGS) AC_SUBST(GUI_LIBS) PKG_CHECK_MODULES(GOBJECT, gobject-2.0 >= 2.12 glib-2.0 >= 2.12 gmodule-2.0 >= 2.12 gthread-2.0 >= 2.12) AC_SUBST(GOBJECT_CFLAGS) AC_SUBST(GOBJECT_LIBS) PKG_CHECK_MODULES(LIBGLADE, libglade-2.0) AC_SUBST(LIBGLADE_CFLAGS) AC_SUBST(LIBGLADE_LIBS) dnl - Check for FluidSynth PKG_CHECK_MODULES(FLUIDSYNTH, fluidsynth >= 1.0, FLUIDSYNTH_SUPPORT=1, FLUIDSYNTH_SUPPORT=0) AC_SUBST(FLUIDSYNTH_CFLAGS) AC_SUBST(FLUIDSYNTH_LIBS) AM_CONDITIONAL(FLUIDSYNTH_SUPPORT, test "$FLUIDSYNTH_SUPPORT" = "1") dnl Check for FFTW PKG_CHECK_MODULES(FFTW, fftw3 >= 3.0, FFTW_SUPPORT=1, FFTW_SUPPORT=0) AC_SUBST(FFTW_CFLAGS) AC_SUBST(FFTW_LIBS) AM_CONDITIONAL(FFTW_SUPPORT, test "$FFTW_SUPPORT" = "1") PKG_CHECK_MODULES(PYGTK, pygtk-2.0, PYGTK_SUPPORT=1, PYGTK_SUPPORT=0) AC_SUBST(PYGTK_CFLAGS) AC_SUBST(PYGTK_LIBS) AC_ARG_ENABLE(python, AS_HELP_STRING([--disable-python], [disable python binding]), enable_python=$enableval, enable_python="yes") if test "x${enable_python}" = "xyes" -a "$PYGTK_SUPPORT" = "1" ; then AC_DEFINE(PYTHON_SUPPORT, 1, [Define to build Python binding]) # Get the codegen directory PYGTK_CODEGEN_DIR=`pkg-config pygtk-2.0 --variable=codegendir` if test "x$PYGTK_CODEGEN_DIR" = "x" ; then PYGTK_CODEGEN_DIR=/usr/share/pygtk/2.0/codegen fi AC_SUBST(PYGTK_CODEGEN_DIR) dnl Check for python 2.2 (defines PYTHON_CFLAGS, PYTHON_LIBS, PYTHON_SITE_PKG, PYTHON_EXTRA_LIBS) AC_PYTHON_DEVEL else enable_python="no" fi AM_CONDITIONAL(PYTHON_SUPPORT, test "x$enable_python" = "xyes") dnl - Check for GtkSourceView PKG_CHECK_MODULES(GTK_SOURCE_VIEW, gtksourceview-1.0 >= 1.0, GTK_SOURCE_VIEW_SUPPORT=1, GTK_SOURCE_VIEW_SUPPORT=0) AC_SUBST(GTK_SOURCE_VIEW_CFLAGS) AC_SUBST(GTK_SOURCE_VIEW_LIBS) AC_ARG_ENABLE(gtk-source-view, AS_HELP_STRING([--disable-gtk-source-view], [disable GtkSourceView support]), enable_gtk_source_view=$enableval, enable_gtk_source_view="yes") if test "${enable_gtk_source_view}" = "yes" \ -a "$GTK_SOURCE_VIEW_SUPPORT" = "1" \ -a "${enable_python}" = "yes" ; then AC_DEFINE(GTK_SOURCE_VIEW_SUPPORT, 1, [Define to enable GtkSourceView support]) else enable_gtk_source_view="no" fi dnl *** Plugin stuff *** AC_ARG_ENABLE(source-build, [--enable-source-build] [Enable source build (use source path for externals], [case "${enableval}" in yes) SOURCE_BUILD=yes ;; no) SOURCE_BUILD=no ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-source-build) ;; esac], [SOURCE_BUILD=no]) dnl Default value if test "x$SOURCE_BUILD" = "xyes"; then AC_DEFINE(SOURCE_BUILD, 1, [Define to enable use of source path for externals]) fi AM_CONDITIONAL(SOURCE_BUILD, test "x$SOURCE_BUILD" = "xyes") dnl Check for Gtk-doc GTK_DOC_CHECK(1.9) dnl Add m4 macro include directory AC_CONFIG_MACRO_DIR(m4) AC_OUTPUT([ Makefile docs/Makefile docs/reference/Makefile docs/reference/libswami/Makefile docs/reference/swamigui/Makefile m4/Makefile src/Makefile src/libswami/Makefile src/libswami/version.h src/swamigui/Makefile src/swamigui/images/Makefile src/swamigui/widgets/Makefile src/plugins/Makefile src/python/Makefile po/Makefile.in package/Makefile]) _SUMMARY_ENABLED= _SUMMARY_DISABLED= FEATURE_SUMMARY([ FluidSynth - Soft synth wavetable plugin], ["${FLUIDSYNTH_SUPPORT}" = "1"]) FEATURE_SUMMARY([ FFTW support - Auto sample tuning plugin (not available yet)], ["${FFTW_SUPPORT}" = "1"]) FEATURE_SUMMARY([ Python support], ["${enable_python}" = "yes"]) FEATURE_SUMMARY([ GtkSourceView support (extended Python script editing features)],["${enable_gtk_source_view}" = "yes"]) FEATURE_SUMMARY([ Generate gtk-doc API docs], ["x${enable_gtk_doc}" == "xyes"]) FEATURE_SUMMARY([ Debugging (compiler flags)], ["${disable_debug}" != "yes"]) FEATURE_SUMMARY([ Source build (load external files from source code path)], ["${SOURCE_BUILD}" == "yes"]) echo echo "**************************************************************" echo "Enabled features:" echo -e -n "$_SUMMARY_ENABLED" echo echo "Disabled features:" echo -e -n "$_SUMMARY_DISABLED" echo echo "**************************************************************" echo swami/depcomp0000755000175000017500000002752507573110375013456 0ustar alessioalessio#! /bin/sh # depcomp - compile a program generating dependencies as side-effects # Copyright 1999, 2000 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program 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 General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # `libtool' can also be set to `yes' or `no'. depfile=${depfile-`echo "$object" | sed 's,\([^/]*\)$,.deps/\1,;s/\.\([^.]*\)$/.P\1/'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the `deleted header file' problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. tr ' ' ' ' < "$tmpdepfile" | ## Some versions of gcc put a space before the `:'. On the theory ## that the space means something, we add a space to the output as ## well. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like `#:fec' to the end of the # dependency line. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr ' ' ' ' >> $depfile echo >> $depfile # The second pass generates a dummy entry for each header file. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> $depfile else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. This file always lives in the current directory. # Also, the AIX compiler puts `$object:' at the start of each line; # $object doesn't have directory information. stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'` tmpdepfile="$stripped.u" outname="$stripped.o" if test "$libtool" = yes; then "$@" -Wc,-M else "$@" -M fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi if test -f "$tmpdepfile"; then # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; tru64) # The Tru64 AIX compiler uses -MD to generate dependencies as a side # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in `foo.d' instead, so we check for that too. # Subdirectories are respected. tmpdepfile1="$object.d" tmpdepfile2=`echo "$object" | sed -e 's/.o$/.d/'` if test "$libtool" = yes; then "$@" -Wc,-MD else "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi if test -f "$tmpdepfile1"; then tmpdepfile="$tmpdepfile1" else tmpdepfile="$tmpdepfile2" fi if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a space and a tab in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout, regardless of -o, # because we must use -o when running libtool. test -z "$dashmflag" && dashmflag=-M ( IFS=" " case " $* " in *" --mode=compile "*) # this is libtool, let us make it quiet for arg do # cycle over the arguments case "$arg" in "--mode=compile") # insert --quiet before "--mode=compile" set fnord "$@" --quiet shift # fnord ;; esac set fnord "$@" "$arg" shift # fnord shift # "$arg" done ;; esac "$@" $dashmflag | sed 's:^[^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" ) & proc=$! "$@" stat=$? wait "$proc" if test "$stat" != 0; then exit $stat; fi rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' ' ' < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) # X makedepend ( shift cleared=no for arg in "$@"; do case $cleared in no) set ""; shift cleared=yes esac case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift;; -*) ;; *) set fnord "$@" "$arg"; shift;; esac done obj_suffix="`echo $object | sed 's/^.*\././'`" touch "$tmpdepfile" ${MAKEDEPEND-makedepend} 2>/dev/null -o"$obj_suffix" -f"$tmpdepfile" "$@" ) & proc=$! "$@" stat=$? wait "$proc" if test "$stat" != 0; then exit $stat; fi rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tail +3 "$tmpdepfile" | tr ' ' ' ' | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout, regardless of -o, # because we must use -o when running libtool. ( IFS=" " case " $* " in *" --mode=compile "*) for arg do # cycle over the arguments case $arg in "--mode=compile") # insert --quiet before "--mode=compile" set fnord "$@" --quiet shift # fnord ;; esac set fnord "$@" "$arg" shift # fnord shift # "$arg" done ;; esac "$@" -E | sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | sed '$ s: \\$::' > "$tmpdepfile" ) & proc=$! "$@" stat=$? wait "$proc" if test "$stat" != 0; then exit $stat; fi rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout, regardless of -o, # because we must use -o when running libtool. ( IFS=" " case " $* " in *" --mode=compile "*) for arg do # cycle over the arguments case $arg in "--mode=compile") # insert --quiet before "--mode=compile" set fnord "$@" --quiet shift # fnord ;; esac set fnord "$@" "$arg" shift # fnord shift # "$arg" done ;; esac "$@" -E | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" ) & proc=$! "$@" stat=$? wait "$proc" if test "$stat" != 0; then exit $stat; fi rm -f "$depfile" echo "$object : \\" > "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" echo " " >> "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0