mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-18 07:47:17 +00:00
873 lines
22 KiB
Text
873 lines
22 KiB
Text
|
#!/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",
|