mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 16:26:39 +00:00
279 lines
9.9 KiB
C
279 lines
9.9 KiB
C
|
/* Gnome-Streamer
|
||
|
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
||
|
*
|
||
|
* This library is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU Library General Public
|
||
|
* License as published by the Free Software Foundation; either
|
||
|
* version 2 of the License, or (at your option) any later version.
|
||
|
*
|
||
|
* This library is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
* Library General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU Library General Public
|
||
|
* License along with this library; if not, write to the
|
||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||
|
* Boston, MA 02111-1307, USA.
|
||
|
*/
|
||
|
|
||
|
|
||
|
#include <gst/gst.h>
|
||
|
#include <gnome.h>
|
||
|
|
||
|
struct element_select_classlist {
|
||
|
gchar *name;
|
||
|
GSList *subclasses;
|
||
|
GSList *factories;
|
||
|
};
|
||
|
|
||
|
struct element_select_details {
|
||
|
GstElementFactory *factory;
|
||
|
GtkWidget *longname, *description, *version, *author, *copyright;
|
||
|
};
|
||
|
|
||
|
static gint compare_name(gconstpointer a,gconstpointer b) {
|
||
|
return (strcmp(((GstElementFactory *)a)->name,
|
||
|
((GstElementFactory *)b)->name));
|
||
|
}
|
||
|
|
||
|
gint str_compare(gconstpointer a,gconstpointer b) {
|
||
|
return (strcmp((gchar *)a,(gchar *)b));
|
||
|
}
|
||
|
|
||
|
/* this function creates a GtkCTreeNode with the contents of the classtree */
|
||
|
static void make_ctree(GtkCTree *tree,GtkCTreeNode *parent,
|
||
|
struct element_select_classlist *class) {
|
||
|
GSList *traverse;
|
||
|
GtkCTreeNode *classnode, *node = NULL;
|
||
|
gchar *data[2];
|
||
|
|
||
|
data[0] = g_strdup(class->name);
|
||
|
data[1] = NULL;
|
||
|
classnode = gtk_ctree_insert_node(tree,parent,NULL,data,0,
|
||
|
NULL,NULL,NULL,NULL,FALSE,TRUE);
|
||
|
gtk_ctree_node_set_selectable(tree,classnode,FALSE);
|
||
|
|
||
|
traverse = class->subclasses;
|
||
|
while (traverse) {
|
||
|
make_ctree(tree,classnode,
|
||
|
(struct element_select_classlist *)(traverse->data));
|
||
|
traverse = g_slist_next(traverse);
|
||
|
}
|
||
|
|
||
|
traverse = class->factories;
|
||
|
while (traverse) {
|
||
|
GstElementFactory *factory = (GstElementFactory *)(traverse->data);
|
||
|
data[0] = g_strdup(factory->name);
|
||
|
data[1] = g_strdup(factory->details->description);
|
||
|
node = gtk_ctree_insert_node(tree,classnode,NULL,data,0,
|
||
|
NULL,NULL,NULL,NULL,TRUE,FALSE);
|
||
|
gtk_ctree_node_set_row_data_full(tree,node,factory,NULL);
|
||
|
traverse = g_slist_next(traverse);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void ctree_select(GtkWidget *widget,gint row,gint column,
|
||
|
GdkEventButton *bevent,gpointer data) {
|
||
|
GtkCTree *tree = GTK_CTREE(widget);
|
||
|
GtkCTreeNode *node;
|
||
|
GstElementFactory *factory;
|
||
|
struct element_select_details *details;
|
||
|
node = gtk_ctree_node_nth(tree,row);
|
||
|
factory = (GstElementFactory *)gtk_ctree_node_get_row_data(tree,node);
|
||
|
if (!factory)
|
||
|
return;
|
||
|
details = (struct element_select_details *)data;
|
||
|
details->factory = factory;
|
||
|
|
||
|
gtk_entry_set_text(GTK_ENTRY(details->longname),
|
||
|
factory->details->longname);
|
||
|
gtk_entry_set_text(GTK_ENTRY(details->description),
|
||
|
factory->details->description);
|
||
|
gtk_entry_set_text(GTK_ENTRY(details->version),
|
||
|
factory->details->version);
|
||
|
gtk_entry_set_text(GTK_ENTRY(details->author),
|
||
|
factory->details->author);
|
||
|
gtk_entry_set_text(GTK_ENTRY(details->copyright),
|
||
|
factory->details->copyright);
|
||
|
|
||
|
if (bevent && bevent->type == GDK_2BUTTON_PRESS)
|
||
|
gtk_main_quit();
|
||
|
}
|
||
|
|
||
|
|
||
|
GstElementFactory *element_select_dialog() {
|
||
|
GtkWidget *dialog;
|
||
|
gchar *titles[2];
|
||
|
GtkWidget *ctree;
|
||
|
GtkWidget *scroller;
|
||
|
GtkTable *table;
|
||
|
GtkWidget *detailslabel;
|
||
|
GtkWidget *detailshsep;
|
||
|
GtkWidget *longname, *description, *version, *author, *copyright;
|
||
|
|
||
|
GList *elements;
|
||
|
GstElementFactory *element;
|
||
|
gchar **classes, **class;
|
||
|
GSList *classlist;
|
||
|
GSList *classtree, *treewalk;
|
||
|
GSList **curlist;
|
||
|
struct element_select_classlist *branch;
|
||
|
struct element_select_details details;
|
||
|
|
||
|
/* first create the dialog and associated stuff */
|
||
|
dialog = gnome_dialog_new("Select Element",
|
||
|
GNOME_STOCK_BUTTON_OK,
|
||
|
GNOME_STOCK_BUTTON_CANCEL,
|
||
|
NULL);
|
||
|
gnome_dialog_set_close(GNOME_DIALOG(dialog),TRUE);
|
||
|
gnome_dialog_close_hides(GNOME_DIALOG(dialog),TRUE);
|
||
|
gnome_dialog_set_default(GNOME_DIALOG(dialog),GNOME_OK);
|
||
|
|
||
|
titles[0] = "Element ";
|
||
|
titles[1] = "Description";
|
||
|
ctree = gtk_ctree_new_with_titles(2,0,titles);
|
||
|
gtk_widget_set_usize(ctree,400,350);
|
||
|
|
||
|
scroller = gtk_scrolled_window_new(NULL,NULL);
|
||
|
gtk_container_add(GTK_CONTAINER(scroller),ctree);
|
||
|
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroller),
|
||
|
GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
|
||
|
gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog)->vbox),scroller,
|
||
|
TRUE,TRUE,0);
|
||
|
|
||
|
/* create the details table and put a title on it */
|
||
|
table = GTK_TABLE(gtk_table_new(2,7,FALSE));
|
||
|
detailslabel = gtk_label_new("Element Details:");
|
||
|
gtk_misc_set_alignment(GTK_MISC(detailslabel),0.0,0.5);
|
||
|
gtk_table_attach(table,detailslabel,0,2,0,1,GTK_FILL|GTK_EXPAND,0,0,0);
|
||
|
|
||
|
/* then a separator to keep the title separate */
|
||
|
detailshsep = gtk_hseparator_new();
|
||
|
gtk_table_attach(table,detailshsep,0,2,1,2,GTK_FILL|GTK_EXPAND,0,0,0);
|
||
|
|
||
|
/* the long name of the element */
|
||
|
longname = gtk_label_new("Name:");
|
||
|
gtk_misc_set_alignment(GTK_MISC(longname),1.0,0.5);
|
||
|
gtk_table_attach(table,longname,0,1,2,3,GTK_FILL,0,5,0);
|
||
|
details.longname = gtk_entry_new();
|
||
|
gtk_entry_set_editable(GTK_ENTRY(details.longname),FALSE);
|
||
|
gtk_table_attach(table,details.longname,1,2,2,3,GTK_FILL|GTK_EXPAND,0,0,0);
|
||
|
|
||
|
/* the description */
|
||
|
description = gtk_label_new("Description:");
|
||
|
gtk_misc_set_alignment(GTK_MISC(description),1.0,0.5);
|
||
|
gtk_table_attach(table,description,0,1,3,4,GTK_FILL,0,5,0);
|
||
|
details.description = gtk_entry_new();
|
||
|
gtk_entry_set_editable(GTK_ENTRY(details.description),FALSE);
|
||
|
gtk_table_attach(table,details.description,1,2,3,4,GTK_FILL|GTK_EXPAND,0,0,0);
|
||
|
|
||
|
/* the version */
|
||
|
version = gtk_label_new("Version:");
|
||
|
gtk_misc_set_alignment(GTK_MISC(version),1.0,0.5);
|
||
|
gtk_table_attach(table,version,0,1,4,5,GTK_FILL,0,5,0);
|
||
|
details.version = gtk_entry_new();
|
||
|
gtk_entry_set_editable(GTK_ENTRY(details.version),FALSE);
|
||
|
gtk_table_attach(table,details.version,1,2,4,5,GTK_FILL|GTK_EXPAND,0,0,0);
|
||
|
|
||
|
/* the author */
|
||
|
author = gtk_label_new("Author:");
|
||
|
gtk_misc_set_alignment(GTK_MISC(author),1.0,0.5);
|
||
|
gtk_table_attach(table,author,0,1,6,7,GTK_FILL,0,5,0);
|
||
|
details.author = gtk_entry_new();
|
||
|
gtk_entry_set_editable(GTK_ENTRY(details.author),FALSE);
|
||
|
gtk_table_attach(table,details.author,1,2,6,7,GTK_FILL|GTK_EXPAND,0,0,0);
|
||
|
|
||
|
/* the copyright */
|
||
|
copyright = gtk_label_new("Copyright:");
|
||
|
gtk_misc_set_alignment(GTK_MISC(copyright),1.0,0.5);
|
||
|
gtk_table_attach(table,copyright,0,1,7,8,GTK_FILL,0,5,0);
|
||
|
details.copyright = gtk_entry_new();
|
||
|
gtk_entry_set_editable(GTK_ENTRY(details.copyright),FALSE);
|
||
|
gtk_table_attach(table,details.copyright,1,2,7,8,GTK_FILL|GTK_EXPAND,0,0,0);
|
||
|
|
||
|
gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog)->vbox),GTK_WIDGET(table),
|
||
|
TRUE,TRUE,0);
|
||
|
|
||
|
|
||
|
/* first create a sorted (by class) tree of all the factories */
|
||
|
classtree = NULL;
|
||
|
elements = gst_elementfactory_get_list();
|
||
|
while (elements) {
|
||
|
element = (GstElementFactory *)(elements->data);
|
||
|
/* split up the factory's class */
|
||
|
classes = g_strsplit(element->details->class,"/",0);
|
||
|
class = classes;
|
||
|
curlist = &classtree;
|
||
|
/* walk down the class tree to find where to place this element */
|
||
|
/* the goal is for treewalk to point to the right class branch */
|
||
|
/* when we exit this thing, branch is pointing where we want */
|
||
|
while (*class) {
|
||
|
treewalk = *curlist;
|
||
|
/* walk the current level of class to see if we have the class */
|
||
|
while (treewalk) {
|
||
|
branch = (struct element_select_classlist *)(treewalk->data);
|
||
|
/* see if this class matches what we're looking for */
|
||
|
if (!strcmp(branch->name,*class)) {
|
||
|
/* if so, we progress down the list into this one's list */
|
||
|
curlist = &branch->subclasses;
|
||
|
break;
|
||
|
}
|
||
|
treewalk = g_slist_next(treewalk);
|
||
|
}
|
||
|
/* if treewalk == NULL, it wasn't in the list. add one */
|
||
|
if (treewalk == NULL) {
|
||
|
/* curlist is pointer to list */
|
||
|
branch = g_new0(struct element_select_classlist,1);
|
||
|
branch->name = g_strdup(*class);
|
||
|
*curlist = g_slist_insert_sorted(*curlist,branch,str_compare);
|
||
|
curlist = &branch->subclasses;
|
||
|
}
|
||
|
class++;
|
||
|
}
|
||
|
/* theoretically branch points where we want now */
|
||
|
branch->factories = g_slist_insert_sorted(branch->factories,element,
|
||
|
compare_name);
|
||
|
elements = g_list_next(elements);
|
||
|
}
|
||
|
|
||
|
/* now fill in the ... */
|
||
|
gtk_clist_freeze(GTK_CLIST(ctree));
|
||
|
treewalk = classtree;
|
||
|
while (treewalk) {
|
||
|
make_ctree(GTK_CTREE(ctree),NULL,
|
||
|
(struct element_select_classlist *)(treewalk->data));
|
||
|
treewalk = g_slist_next(treewalk);
|
||
|
}
|
||
|
gtk_clist_thaw(GTK_CLIST(ctree));
|
||
|
|
||
|
gtk_signal_connect(GTK_OBJECT(ctree),"select_row",
|
||
|
GTK_SIGNAL_FUNC(ctree_select),&details);
|
||
|
|
||
|
gtk_widget_show_all(GTK_WIDGET(dialog));
|
||
|
|
||
|
details.factory = NULL;
|
||
|
if (gnome_dialog_run_and_close(GNOME_DIALOG(dialog)) == GNOME_CANCEL)
|
||
|
return NULL;
|
||
|
else
|
||
|
return details.factory;
|
||
|
};
|
||
|
|
||
|
|
||
|
/* this is available so we can do a quick test of this thing */
|
||
|
#ifdef ELEMENTSELECT_MAIN
|
||
|
int main(int argc,char *argv[]) {
|
||
|
GstElementFactory *chosen;
|
||
|
|
||
|
gst_init(&argc,&argv);
|
||
|
gst_plugin_load_all();
|
||
|
gnome_init("elementselect_test","0.0.0",argc,argv);
|
||
|
chosen = element_select_dialog();
|
||
|
if (chosen)
|
||
|
g_print("selected '%s'\n",chosen->name);
|
||
|
else
|
||
|
g_print("didn't choose any\n");
|
||
|
exit(0);
|
||
|
}
|
||
|
#endif /* ELEMENTSELECT_MAIN */
|