mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 08:46:40 +00:00
9bae9d4b91
Original commit message from CVS: More Docs updates. Added plugin documentation. I fear we need a gstdoc implementation that loads plugins and does introspection on them. I think we should automatically create the docs for the pads and mime types the plugins provide. Does anyone have enough perl knowledge to add these features? I allready changed the C code to output the pad definitions but my perl knowledge is too limited, for now, to implement the rest of the needed functionality...
872 lines
22 KiB
Perl
Executable file
872 lines
22 KiB
Perl
Executable file
#!/usr/bin/perl -w
|
|
#
|
|
# gtk-doc - GTK DocBook documentation generator.
|
|
# Copyright (C) 1998 Damon Chaplin
|
|
#
|
|
# 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.
|
|
#
|
|
|
|
#
|
|
# This gets information about object heirarchies and signals
|
|
# by compiling a small C program. CFLAGS and LDFLAGS must be
|
|
# set appropriately before running this script.
|
|
#
|
|
# NOTE: the lookup_signal_srg_names() function contains the argument names of
|
|
# standard GTK signal handlers. This may need to be updated for new
|
|
# GTK signals or Gnome widget signals.
|
|
|
|
use Getopt::Long;
|
|
|
|
# Options
|
|
|
|
# name of documentation module
|
|
my $MODULE;
|
|
my $OUTPUT_DIR;
|
|
|
|
%optctl = (module => \$MODULE,
|
|
types => \$TYPES_FILE,
|
|
nogtkinit => \$NO_GTK_INIT);
|
|
|
|
GetOptions(\%optctl, "module=s", "types:s", "nogtkinit");
|
|
|
|
$TYPES_FILE = $TYPES_FILE ? $TYPES_FILE : "$MODULE.types";
|
|
|
|
open TYPES, $TYPES_FILE || die "Cannot open $TYPES_FILE: $!\n";
|
|
open OUTPUT, ">$MODULE-scan.c" || die "Cannot open $MODULE-scan.c: $!\n";
|
|
|
|
# write a C program to scan the types
|
|
|
|
$includes = "";
|
|
@types = ();
|
|
|
|
for (<TYPES>) {
|
|
if (/^#include/) {
|
|
$includes .= $_;
|
|
} elsif (/^%/) {
|
|
next;
|
|
} elsif (/^\s*$/) {
|
|
next;
|
|
} else {
|
|
chomp;
|
|
push @types, $_;
|
|
}
|
|
}
|
|
|
|
$ntypes = @types + 1;
|
|
|
|
print OUTPUT <<EOT;
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
|
|
$includes
|
|
GtkType object_types[$ntypes];
|
|
GstElement *elements[$ntypes];
|
|
|
|
gint _typenr = 0;
|
|
|
|
gboolean
|
|
get_plugins ()
|
|
{
|
|
gint i = 0;
|
|
EOT
|
|
|
|
for (@types) {
|
|
print OUTPUT " gst_plugin_load(\"$_\");\n";
|
|
print OUTPUT " elements[i] = gst_elementfactory_make(\"$_\", \"dummy\");\n";
|
|
print OUTPUT " object_types[i] = GTK_OBJECT_TYPE(GTK_OBJECT(elements[i]));\n";
|
|
print OUTPUT " i++; \n";
|
|
}
|
|
print OUTPUT " object_types[i] = 0;\n";
|
|
|
|
print OUTPUT <<EOT;
|
|
return TRUE;
|
|
}
|
|
|
|
/*
|
|
* This uses GTK type functions to output signal prototypes and the widget
|
|
* hierarchy.
|
|
*/
|
|
|
|
/* The output files */
|
|
gchar *signals_filename = "$MODULE.signals";
|
|
gchar *hierarchy_filename = "$MODULE.hierarchy";
|
|
gchar *args_filename = "$MODULE.args";
|
|
gchar *pads_filename = "$MODULE.pads";
|
|
|
|
|
|
static void output_signals ();
|
|
static void output_widget_signals (FILE *fp,
|
|
GtkType object_type);
|
|
static void output_widget_signal (FILE *fp,
|
|
GtkType object_type,
|
|
gchar *object_class_name,
|
|
guint signal_id);
|
|
static gchar * get_type_name (GtkType type,
|
|
gboolean * is_pointer);
|
|
static gchar * get_gdk_event (const gchar * signal_name);
|
|
static gchar ** lookup_signal_arg_names (gchar * type,
|
|
const gchar * signal_name);
|
|
|
|
static void output_widget_hierarchy ();
|
|
static void output_hierarchy (FILE *fp,
|
|
GtkType type,
|
|
gint level);
|
|
|
|
static void output_args ();
|
|
static void output_widget_args (FILE *fp, GtkType object_type);
|
|
|
|
static void output_pads ();
|
|
static void output_widget_pads (FILE *fp, GstElement *element);
|
|
|
|
int
|
|
main (int argc, char *argv[])
|
|
{
|
|
EOT
|
|
|
|
if ($NO_GTK_INIT) {
|
|
print OUTPUT <<EOT;
|
|
gtk_type_init ();
|
|
EOT
|
|
} else {
|
|
print OUTPUT <<EOT;
|
|
gtk_init (&argc, &argv);
|
|
EOT
|
|
}
|
|
|
|
print OUTPUT <<EOT;
|
|
gst_init (&argc, &argv);
|
|
get_plugins();
|
|
|
|
output_widget_hierarchy ();
|
|
output_signals ();
|
|
output_args ();
|
|
output_pads ();
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
static void
|
|
output_signals ()
|
|
{
|
|
FILE *fp;
|
|
gint i;
|
|
|
|
fp = fopen (signals_filename, "w");
|
|
if (fp == NULL)
|
|
{
|
|
g_warning ("Couldn't open output file: %s", signals_filename);
|
|
return;
|
|
}
|
|
|
|
for (i = 0; object_types[i]; i++)
|
|
output_widget_signals (fp, object_types[i]);
|
|
|
|
fclose (fp);
|
|
}
|
|
|
|
|
|
/* This outputs all the signals of one widget. */
|
|
static void
|
|
output_widget_signals (FILE *fp, GtkType object_type)
|
|
{
|
|
GtkObjectClass *class;
|
|
gchar *object_class_name;
|
|
guint sig;
|
|
|
|
class = gtk_type_class (object_type);
|
|
if (!class || class->nsignals == 0)
|
|
return;
|
|
|
|
object_class_name = gtk_type_name (object_type);
|
|
|
|
for (sig = 0; sig < class->nsignals; sig++)
|
|
{
|
|
if (!class->signals[sig])
|
|
{
|
|
/*g_print ("Signal slot [%u] is empty\n", sig);*/
|
|
continue;
|
|
}
|
|
|
|
output_widget_signal (fp, object_type, object_class_name,
|
|
class->signals[sig]);
|
|
}
|
|
}
|
|
|
|
|
|
/* This outputs one signal. */
|
|
static void
|
|
output_widget_signal (FILE *fp,
|
|
GtkType object_type,
|
|
gchar *object_name,
|
|
guint signal_id)
|
|
{
|
|
GtkSignalQuery *query_info;
|
|
gchar *ret_type, *pos, *type_name, *arg_name, *object_arg, *object_arg_start;
|
|
gboolean is_pointer;
|
|
gchar ret_type_buffer[1024], buffer[1024];
|
|
gint i, param;
|
|
gchar **arg_names;
|
|
gint param_num, widget_num, event_num, callback_num;
|
|
gint *arg_num;
|
|
gchar signal_name[128];
|
|
|
|
|
|
/* g_print ("Object: %s Type: %i Signal: %u\n", object_name, object_type,
|
|
signal_id);*/
|
|
|
|
param_num = 1;
|
|
widget_num = event_num = callback_num = 0;
|
|
|
|
query_info = gtk_signal_query (signal_id);
|
|
if (query_info == NULL)
|
|
{
|
|
g_warning ("Couldn't query signal");
|
|
return;
|
|
}
|
|
|
|
/* Output the return type and function name. */
|
|
ret_type = get_type_name (query_info->return_val, &is_pointer);
|
|
sprintf (ret_type_buffer, "%s%s", ret_type, is_pointer ? "*" : "");
|
|
|
|
/* Output the signal object type and the argument name. We assume the
|
|
type is a pointer - I think that is OK. We remove "Gtk" or "Gnome" and
|
|
convert to lower case for the argument name. */
|
|
pos = buffer;
|
|
sprintf (pos, "%s ", object_name);
|
|
pos += strlen (pos);
|
|
|
|
if (!strncmp (object_name, "Gtk", 3))
|
|
object_arg = object_name + 3;
|
|
else if (!strncmp (object_name, "Gnome", 5))
|
|
object_arg = object_name + 5;
|
|
else
|
|
object_arg = object_name;
|
|
|
|
object_arg_start = pos;
|
|
sprintf (pos, "*%s\n", object_arg);
|
|
pos += strlen (pos);
|
|
g_strdown (object_arg_start);
|
|
if (!strcmp (object_arg_start, "widget"))
|
|
widget_num++;
|
|
|
|
/* Convert signal name to use underscores rather than dashes '-'. */
|
|
strcpy (signal_name, query_info->signal_name);
|
|
for (i = 0; signal_name[i]; i++)
|
|
{
|
|
if (signal_name[i] == '-')
|
|
signal_name[i] = '_';
|
|
}
|
|
|
|
/* Output the signal parameters. */
|
|
arg_names = lookup_signal_arg_names (object_name, signal_name);
|
|
|
|
for (param = 0; param < query_info->nparams; param++)
|
|
{
|
|
if (arg_names)
|
|
{
|
|
sprintf (pos, "%s\n", arg_names[param]);
|
|
pos += strlen (pos);
|
|
}
|
|
else
|
|
{
|
|
type_name = get_type_name (query_info->params[param], &is_pointer);
|
|
|
|
/* Most arguments to the callback are called "arg1", "arg2", etc.
|
|
GdkWidgets are called "widget", "widget2", ...
|
|
GdkEvents are called "event", "event2", ...
|
|
GtkCallbacks are called "callback", "callback2", ... */
|
|
if (!strcmp (type_name, "GtkWidget"))
|
|
{
|
|
arg_name = "widget";
|
|
arg_num = &widget_num;
|
|
}
|
|
else if (!strcmp (type_name, "GdkEvent"))
|
|
{
|
|
type_name = get_gdk_event (signal_name);
|
|
arg_name = "event";
|
|
arg_num = &event_num;
|
|
is_pointer = TRUE;
|
|
}
|
|
else if (!strcmp (type_name, "GtkCallback")
|
|
|| !strcmp (type_name, "GtkCCallback"))
|
|
{
|
|
arg_name = "callback";
|
|
arg_num = &callback_num;
|
|
}
|
|
else
|
|
{
|
|
arg_name = "arg";
|
|
arg_num = ¶m_num;
|
|
}
|
|
sprintf (pos, "%s ", type_name);
|
|
pos += strlen (pos);
|
|
|
|
if (!arg_num || *arg_num == 0)
|
|
sprintf (pos, "%s%s\n", is_pointer ? "*" : " ", arg_name);
|
|
else
|
|
sprintf (pos, "%s%s%i\n", is_pointer ? "*" : " ", arg_name,
|
|
*arg_num);
|
|
pos += strlen (pos);
|
|
|
|
if (arg_num)
|
|
*arg_num += 1;
|
|
}
|
|
}
|
|
|
|
fprintf (fp,
|
|
"<SIGNAL>\n<NAME>%s::%s</NAME>\n<RETURNS>%s</RETURNS>\n%s</SIGNAL>\n\n",
|
|
object_name, query_info->signal_name, ret_type_buffer, buffer);
|
|
g_free (query_info);
|
|
}
|
|
|
|
|
|
static gchar *
|
|
get_type_name (GtkType type, gboolean * is_pointer)
|
|
{
|
|
static gchar *GbTypeNames[] =
|
|
{
|
|
"char", "gchar",
|
|
"bool", "gboolean",
|
|
"int", "gint",
|
|
"uint", "guint",
|
|
"long", "glong",
|
|
"ulong", "gulong",
|
|
"float", "gfloat",
|
|
"double", "gdouble",
|
|
"string", "gchar",
|
|
"enum", "gint",
|
|
"flags", "gint",
|
|
"boxed", "gpointer",
|
|
"foreign", "gpointer",
|
|
"callback", "GtkCallback", /* ?? */
|
|
"args", "gpointer",
|
|
|
|
"pointer", "gpointer",
|
|
"signal", "gpointer",
|
|
"c_callback", "GtkCallback", /* ?? */
|
|
|
|
NULL
|
|
};
|
|
|
|
GtkType parent_type;
|
|
gchar *type_name, *parent_type_name;
|
|
gint i;
|
|
|
|
*is_pointer = FALSE;
|
|
type_name = gtk_type_name (type);
|
|
for (i = 0; GbTypeNames[i]; i += 2)
|
|
{
|
|
if (!strcmp (type_name, GbTypeNames[i]))
|
|
{
|
|
if (!strcmp (type_name, "string"))
|
|
*is_pointer = TRUE;
|
|
return GbTypeNames[i + 1];
|
|
}
|
|
}
|
|
|
|
for (;;)
|
|
{
|
|
parent_type = gtk_type_parent (type);
|
|
if (parent_type == 0)
|
|
break;
|
|
type = parent_type;
|
|
}
|
|
parent_type_name = gtk_type_name (type);
|
|
/*g_print ("Parent type name: %s\n", parent_type_name);*/
|
|
if (!strcmp (parent_type_name, "GtkObject")
|
|
|| !strcmp (parent_type_name, "boxed")
|
|
|| !strcmp (parent_type_name, "GtkBoxed"))
|
|
*is_pointer = TRUE;
|
|
|
|
return type_name;
|
|
}
|
|
|
|
|
|
static gchar *
|
|
get_gdk_event (const gchar * signal_name)
|
|
{
|
|
static gchar *GbGDKEvents[] =
|
|
{
|
|
"button_press_event", "GdkEventButton",
|
|
"button_release_event", "GdkEventButton",
|
|
"motion_notify_event", "GdkEventMotion",
|
|
"delete_event", "GdkEvent",
|
|
"destroy_event", "GdkEvent",
|
|
"expose_event", "GdkEventExpose",
|
|
"key_press_event", "GdkEventKey",
|
|
"key_release_event", "GdkEventKey",
|
|
"enter_notify_event", "GdkEventCrossing",
|
|
"leave_notify_event", "GdkEventCrossing",
|
|
"configure_event", "GdkEventConfigure",
|
|
"focus_in_event", "GdkEventFocus",
|
|
"focus_out_event", "GdkEventFocus",
|
|
"map_event", "GdkEvent",
|
|
"unmap_event", "GdkEvent",
|
|
"property_notify_event", "GdkEventProperty",
|
|
"selection_clear_event", "GdkEventSelection",
|
|
"selection_request_event", "GdkEventSelection",
|
|
"selection_notify_event", "GdkEventSelection",
|
|
"proximity_in_event", "GdkEventProximity",
|
|
"proximity_out_event", "GdkEventProximity",
|
|
"drag_begin_event", "GdkEventDragBegin",
|
|
"drag_request_event", "GdkEventDragRequest",
|
|
"drag_end_event", "GdkEventDragRequest",
|
|
"drop_enter_event", "GdkEventDropEnter",
|
|
"drop_leave_event", "GdkEventDropLeave",
|
|
"drop_data_available_event", "GdkEventDropDataAvailable",
|
|
"other_event", "GdkEventOther",
|
|
"client_event", "GdkEventClient",
|
|
"no_expose_event", "GdkEventNoExpose",
|
|
NULL
|
|
};
|
|
|
|
gint i;
|
|
|
|
for (i = 0; GbGDKEvents[i]; i += 2)
|
|
{
|
|
if (!strcmp (signal_name, GbGDKEvents[i]))
|
|
return GbGDKEvents[i + 1];
|
|
}
|
|
return "GdkEvent";
|
|
}
|
|
|
|
|
|
/* This returns argument names to use for some known GTK signals.
|
|
It is passed a widget name, e.g. 'GtkCList' and a signal name, e.g.
|
|
'select_row' and it returns a pointer to an array of argument types and
|
|
names. */
|
|
static gchar **
|
|
lookup_signal_arg_names (gchar * type, const gchar * signal_name)
|
|
{
|
|
/* Each arg array starts with the object type name and the signal name,
|
|
and then signal arguments follow. */
|
|
static gchar *GbArgTable[][16] =
|
|
{
|
|
{"GtkCList", "select_row",
|
|
"gint row",
|
|
"gint column",
|
|
"GdkEventButton *event"},
|
|
{"GtkCList", "unselect_row",
|
|
"gint row",
|
|
"gint column",
|
|
"GdkEventButton *event"},
|
|
{"GtkCList", "click_column",
|
|
"gint column"},
|
|
|
|
{"GtkCList", "resize_column",
|
|
"gint column",
|
|
"gint width"},
|
|
|
|
{"GtkCList", "extend_selection",
|
|
"GtkScrollType scroll_type",
|
|
"gfloat position",
|
|
"gboolean auto_start_selection"},
|
|
{"GtkCList", "scroll_vertical",
|
|
"GtkScrollType scroll_type",
|
|
"gfloat position"},
|
|
{"GtkCList", "scroll_horizontal",
|
|
"GtkScrollType scroll_type",
|
|
"gfloat position"},
|
|
{"GtkContainer", "focus",
|
|
"GtkDirectionType direction"},
|
|
{"GtkCTree", "tree_select_row",
|
|
"GList *node",
|
|
"gint column"},
|
|
{"GtkCTree", "tree_unselect_row",
|
|
"GList *node",
|
|
"gint column"},
|
|
|
|
{"GtkCTree", "tree_expand",
|
|
"GList *node"},
|
|
{"GtkCTree", "tree_collapse",
|
|
"GList *node"},
|
|
{"GtkCTree", "tree_move",
|
|
"GList *node",
|
|
"GList *new_parent",
|
|
"GList *new_sibling"},
|
|
{"GtkCTree", "change_focus_row_expansion",
|
|
"GtkCTreeExpansionType expansion"},
|
|
|
|
{"GtkEditable", "insert_text",
|
|
"gchar *new_text",
|
|
"gint new_text_length",
|
|
"gint *position"},
|
|
{"GtkEditable", "delete_text",
|
|
"gint start_pos",
|
|
"gint end_pos"},
|
|
{"GtkEditable", "set_editable",
|
|
"gboolean is_editable"},
|
|
{"GtkEditable", "move_cursor",
|
|
"gint x",
|
|
"gint y"},
|
|
{"GtkEditable", "move_word",
|
|
"gint num_words"},
|
|
{"GtkEditable", "move_page",
|
|
"gint x",
|
|
"gint y"},
|
|
{"GtkEditable", "move_to_row",
|
|
"gint row"},
|
|
{"GtkEditable", "move_to_column",
|
|
"gint column"},
|
|
|
|
{"GtkEditable", "kill_char",
|
|
"gint direction"},
|
|
{"GtkEditable", "kill_word",
|
|
"gint direction"},
|
|
{"GtkEditable", "kill_line",
|
|
"gint direction"},
|
|
|
|
|
|
{"GtkInputDialog", "enable_device",
|
|
"gint deviceid"},
|
|
{"GtkInputDialog", "disable_device",
|
|
"gint deviceid"},
|
|
|
|
{"GtkListItem", "extend_selection",
|
|
"GtkScrollType scroll_type",
|
|
"gfloat position",
|
|
"gboolean auto_start_selection"},
|
|
{"GtkListItem", "scroll_vertical",
|
|
"GtkScrollType scroll_type",
|
|
"gfloat position"},
|
|
{"GtkListItem", "scroll_horizontal",
|
|
"GtkScrollType scroll_type",
|
|
"gfloat position"},
|
|
|
|
{"GtkMenuShell", "move_current",
|
|
"GtkMenuDirectionType direction"},
|
|
{"GtkMenuShell", "activate_current",
|
|
"gboolean force_hide"},
|
|
|
|
|
|
{"GtkNotebook", "switch_page",
|
|
"GtkNotebookPage *page",
|
|
"gint page_num"},
|
|
{"GtkStatusbar", "text_pushed",
|
|
"guint context_id",
|
|
"gchar *text"},
|
|
{"GtkStatusbar", "text_popped",
|
|
"guint context_id",
|
|
"gchar *text"},
|
|
{"GtkTipsQuery", "widget_entered",
|
|
"GtkWidget *widget",
|
|
"gchar *tip_text",
|
|
"gchar *tip_private"},
|
|
{"GtkTipsQuery", "widget_selected",
|
|
"GtkWidget *widget",
|
|
"gchar *tip_text",
|
|
"gchar *tip_private",
|
|
"GdkEventButton *event"},
|
|
{"GtkToolbar", "orientation_changed",
|
|
"GtkOrientation orientation"},
|
|
{"GtkToolbar", "style_changed",
|
|
"GtkToolbarStyle style"},
|
|
{"GtkWidget", "draw",
|
|
"GdkRectangle *area"},
|
|
{"GtkWidget", "size_request",
|
|
"GtkRequisition *requisition"},
|
|
{"GtkWidget", "size_allocate",
|
|
"GtkAllocation *allocation"},
|
|
{"GtkWidget", "state_changed",
|
|
"GtkStateType state"},
|
|
{"GtkWidget", "style_set",
|
|
"GtkStyle *previous_style"},
|
|
|
|
{"GtkWidget", "install_accelerator",
|
|
"gchar *signal_name",
|
|
"gchar key",
|
|
"gint modifiers"},
|
|
|
|
{"GtkWidget", "add_accelerator",
|
|
"guint accel_signal_id",
|
|
"GtkAccelGroup *accel_group",
|
|
"guint accel_key",
|
|
"GdkModifierType accel_mods",
|
|
"GtkAccelFlags accel_flags"},
|
|
|
|
{"GtkWidget", "parent_set",
|
|
"GtkObject *old_parent"},
|
|
|
|
{"GtkWidget", "remove_accelerator",
|
|
"GtkAccelGroup *accel_group",
|
|
"guint accel_key",
|
|
"GdkModifierType accel_mods"},
|
|
{"GtkWidget", "debug_msg",
|
|
"gchar *message"},
|
|
{"GtkWindow", "move_resize",
|
|
"gint *x",
|
|
"gint *y",
|
|
"gint width",
|
|
"gint height"},
|
|
{"GtkWindow", "set_focus",
|
|
"GtkWidget *widget"},
|
|
|
|
{"GtkWidget", "selection_get",
|
|
"GtkSelectionData *data",
|
|
"guint info",
|
|
"guint time"},
|
|
{"GtkWidget", "selection_received",
|
|
"GtkSelectionData *data",
|
|
"guint time"},
|
|
|
|
{"GtkWidget", "drag_begin",
|
|
"GdkDragContext *drag_context"},
|
|
{"GtkWidget", "drag_end",
|
|
"GdkDragContext *drag_context"},
|
|
{"GtkWidget", "drag_data_delete",
|
|
"GdkDragContext *drag_context"},
|
|
{"GtkWidget", "drag_leave",
|
|
"GdkDragContext *drag_context",
|
|
"guint time"},
|
|
{"GtkWidget", "drag_motion",
|
|
"GdkDragContext *drag_context",
|
|
"gint x",
|
|
"gint y",
|
|
"guint time"},
|
|
{"GtkWidget", "drag_drop",
|
|
"GdkDragContext *drag_context",
|
|
"gint x",
|
|
"gint y",
|
|
"guint time"},
|
|
{"GtkWidget", "drag_data_get",
|
|
"GdkDragContext *drag_context",
|
|
"GtkSelectionData *data",
|
|
"guint info",
|
|
"guint time"},
|
|
{"GtkWidget", "drag_data_received",
|
|
"GdkDragContext *drag_context",
|
|
"gint x",
|
|
"gint y",
|
|
"GtkSelectionData *data",
|
|
"guint info",
|
|
"guint time"},
|
|
|
|
{NULL}
|
|
};
|
|
|
|
gint i;
|
|
|
|
for (i = 0; GbArgTable[i][0]; i++)
|
|
{
|
|
if (!strcmp (type, GbArgTable[i][0])
|
|
&& !strcmp (signal_name, GbArgTable[i][1]))
|
|
return &GbArgTable[i][2];
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/* This outputs the hierarchy of all widgets which have been initialized,
|
|
i.e. by calling their XXX_get_type() initialization function. */
|
|
static void
|
|
output_widget_hierarchy ()
|
|
{
|
|
FILE *fp;
|
|
|
|
fp = fopen (hierarchy_filename, "w");
|
|
if (fp == NULL)
|
|
{
|
|
g_warning ("Couldn't open output file: %s", hierarchy_filename);
|
|
return;
|
|
}
|
|
output_hierarchy (fp, GTK_TYPE_OBJECT, 0);
|
|
fclose (fp);
|
|
}
|
|
|
|
|
|
/* This is called recursively to output the hierarchy of a widget. */
|
|
static void
|
|
output_hierarchy (FILE *fp,
|
|
GtkType type,
|
|
gint level)
|
|
{
|
|
GList *list;
|
|
guint i;
|
|
|
|
if (!type)
|
|
return;
|
|
|
|
for (i = 0; i < level; i++)
|
|
fprintf (fp, " ");
|
|
fprintf (fp, gtk_type_name (type));
|
|
fprintf (fp, "\n");
|
|
|
|
list = gtk_type_children_types (type);
|
|
|
|
while (list)
|
|
{
|
|
GtkType child = (GtkType) list->data;
|
|
output_hierarchy (fp, child, level + 1);
|
|
list = list->next;
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
output_args ()
|
|
{
|
|
FILE *fp;
|
|
gint i;
|
|
|
|
fp = fopen (args_filename, "w");
|
|
if (fp == NULL)
|
|
{
|
|
g_warning ("Couldn't open output file: %s", args_filename);
|
|
return;
|
|
}
|
|
|
|
for (i = 0; object_types[i]; i++)
|
|
output_widget_args (fp, object_types[i]);
|
|
|
|
fclose (fp);
|
|
}
|
|
|
|
|
|
static void
|
|
output_widget_args (FILE *fp, GtkType object_type)
|
|
{
|
|
GtkObjectClass *class;
|
|
gchar *object_class_name;
|
|
GtkArg *args;
|
|
guint32 *arg_flags;
|
|
guint n_args;
|
|
gint arg;
|
|
gchar flags[16], *pos;
|
|
|
|
class = gtk_type_class (object_type);
|
|
if (!class)
|
|
return;
|
|
|
|
object_class_name = gtk_type_name (object_type);
|
|
|
|
args = gtk_object_query_args (class->type, &arg_flags, &n_args);
|
|
|
|
for (arg = 0; arg < n_args; arg++)
|
|
{
|
|
pos = flags;
|
|
/* We use one-character flags for simplicity. */
|
|
if (arg_flags[arg] & GTK_ARG_READABLE)
|
|
*pos++ = 'r';
|
|
if (arg_flags[arg] & GTK_ARG_WRITABLE)
|
|
*pos++ = 'w';
|
|
if (arg_flags[arg] & GTK_ARG_CONSTRUCT)
|
|
*pos++ = 'x';
|
|
if (arg_flags[arg] & GTK_ARG_CONSTRUCT_ONLY)
|
|
*pos++ = 'X';
|
|
if (arg_flags[arg] & GTK_ARG_CHILD_ARG)
|
|
*pos++ = 'c';
|
|
*pos = '\0';
|
|
|
|
fprintf (fp, "<ARG>\n<NAME>%s</NAME>\n<TYPE>%s</TYPE>\n<FLAGS>%s</FLAGS>\n",
|
|
args[arg].name, gtk_type_name (args[arg].type), flags);
|
|
|
|
if (GTK_FUNDAMENTAL_TYPE(args[arg].type) == GTK_TYPE_ENUM) {
|
|
GtkEnumValue *values;
|
|
gint i=0;
|
|
|
|
values = gtk_type_enum_get_values(args[arg].type);
|
|
|
|
while (values[i].value_name) {
|
|
fprintf (fp, "<ENUM>\n<VALUE>%d</VALUE>\n<NICK>%s</NICK>\n</ENUM>\n",
|
|
values[i].value, values[i].value_nick);
|
|
i++;
|
|
}
|
|
}
|
|
|
|
fprintf(fp, "</ARG>\n\n");
|
|
}
|
|
|
|
g_free (args);
|
|
g_free (arg_flags);
|
|
}
|
|
|
|
|
|
static void
|
|
output_pads ()
|
|
{
|
|
FILE *fp;
|
|
gint i;
|
|
|
|
fp = fopen (pads_filename, "w");
|
|
if (fp == NULL)
|
|
{
|
|
g_warning ("Couldn't open output file: %s", pads_filename);
|
|
return;
|
|
}
|
|
|
|
for (i = 0; elements[i]; i++)
|
|
output_widget_pads (fp, elements[i]);
|
|
|
|
fclose (fp);
|
|
}
|
|
|
|
static void
|
|
output_widget_pads (FILE *fp, GstElement *element)
|
|
{
|
|
GtkObjectClass *class;
|
|
GstElementFactory *factory;
|
|
GList *pads;
|
|
|
|
class = GTK_OBJECT(element)->klass;
|
|
if (!class || !GST_IS_ELEMENT_CLASS(class))
|
|
return;
|
|
|
|
pads = gst_element_get_pad_list(element);
|
|
|
|
factory = GST_ELEMENT_CLASS(class)->elementfactory;
|
|
|
|
if (!factory)
|
|
return;
|
|
|
|
while (pads) {
|
|
GstPad *pad = (GstPad *)pads->data;
|
|
GstType *type;
|
|
|
|
type = gst_type_find_by_id(pad->type);
|
|
|
|
fprintf (fp, "<PAD>\n<NAME>%s::%s</NAME>\n",
|
|
gtk_type_name(factory->type), pad->name);
|
|
|
|
if (type) {
|
|
fprintf(fp, "<MIME>%s</MIME>\n", type->mime);
|
|
if (type->exts)
|
|
fprintf(fp, "<EXTS>%s</EXTS>\n", type->exts);
|
|
}
|
|
|
|
fprintf(fp, "</PAD>\n\n");
|
|
|
|
pads = g_list_next(pads);
|
|
}
|
|
}
|
|
|
|
EOT
|
|
|
|
close OUTPUT;
|
|
|
|
# Compile and run our file
|
|
|
|
$CC = $ENV{CC} ? $ENV{CC} : "gcc";
|
|
$LD = $ENV{LD} ? $ENV{LD} : $CC;
|
|
$CFLAGS = $ENV{CFLAGS} ? $ENV{CFLAGS} : "";
|
|
$LDFLAGS = $ENV{LDFLAGS} ? $ENV{LDFLAGS} : "";
|
|
|
|
$command = "$CC $CFLAGS -c -o $MODULE-scan.o $MODULE-scan.c && $LD -o $MODULE-scan $MODULE-scan.o $LDFLAGS";
|
|
|
|
system($command) == 0 or die "Compilation of scanner failed\n";
|
|
|
|
system("./$MODULE-scan") == 0 or die "Scan failed\n";
|
|
|
|
unlink "./$MODULE-scan.c", "./$MODULE-scan",
|