| Server IP : 182.53.201.61 / Your IP : 216.73.217.175 Web Server : Apache/2.2.15 (Fedora) System : Linux km10.dyndns.org 2.6.31.5-127.fc12.i686.PAE #1 SMP Sat Nov 7 21:25:57 EST 2009 i686 User : apache ( 48) PHP Version : 5.3.3 Disable Function : NONE MySQL : ON | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /usr/bin/ |
Upload File : |
#!/usr/bin/perl -w
# -*- cperl -*-
#
# 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_arg_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;
unshift @INC, '/usr/share/gtk-doc/data';
require "gtkdoc-common.pl";
# Options
# name of documentation module
my $MODULE;
my $OUTPUT_DIR;
my $PRINT_VERSION;
%optctl = (module => \$MODULE,
types => \$TYPES_FILE,
nogtkinit => \$NO_GTK_INIT,
'output-dir' => \$OUTPUT_DIR,
'version' => \$PRINT_VERSION);
GetOptions(\%optctl, "module=s", "types:s", "output-dir:s", "nogtkinit", "version");
if ($PRINT_VERSION) {
print "1.11\n";
exit 0;
}
$OUTPUT_DIR = $OUTPUT_DIR ? $OUTPUT_DIR : ".";
$TYPES_FILE = $TYPES_FILE ? $TYPES_FILE : "$OUTPUT_DIR/$MODULE.types";
open (TYPES, $TYPES_FILE) || die "Cannot open $TYPES_FILE: $!\n";
open (OUTPUT, ">$MODULE-scan.c") || die "Cannot open $MODULE-scan.c: $!\n";
my $old_signals_filename = "$OUTPUT_DIR/$MODULE.signals";
my $new_signals_filename = "$OUTPUT_DIR/$MODULE.signals.new";
my $old_hierarchy_filename = "$OUTPUT_DIR/$MODULE.hierarchy";
my $new_hierarchy_filename = "$OUTPUT_DIR/$MODULE.hierarchy.new";
my $old_args_filename = "$OUTPUT_DIR/$MODULE.args";
my $new_args_filename = "$OUTPUT_DIR/$MODULE.args.new";
# 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 <stdlib.h>
#include <stdio.h>
#include <errno.h>
$includes
GtkType object_types[$ntypes];
GtkType *
get_object_types (void)
{
gint i = 0;
EOT
for (@types) {
print OUTPUT " object_types[i++] = $_ ();\n";
}
print OUTPUT <<EOT;
object_types[i] = 0;
return object_types;
}
/*
* This uses GTK type functions to output signal prototypes and the widget
* hierarchy.
*/
/* The output files */
gchar *signals_filename = "$new_signals_filename";
gchar *hierarchy_filename = "$new_hierarchy_filename";
gchar *args_filename = "$new_args_filename";
static void output_signals (void);
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 (void);
static void output_hierarchy (FILE *fp,
GtkType type,
guint level);
static void output_args (void);
static void output_widget_args (FILE *fp, GtkType object_type);
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;
get_object_types ();
output_signals ();
output_widget_hierarchy ();
output_args ();
return 0;
}
static void
output_signals (void)
{
FILE *fp;
gint i;
fp = fopen (signals_filename, "w");
if (fp == NULL)
{
g_warning ("Couldn't open output file: %s : %s", signals_filename, strerror(errno));
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];
guint 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);
}
/* Returns the type name to use for a signal argument or return value, given
the GtkType from the signal info. It also sets is_pointer to TRUE if the
argument needs a '*' since it is a pointer. */
static gchar *
get_type_name (GtkType type, gboolean * is_pointer)
{
gchar *type_name;
*is_pointer = FALSE;
type_name = gtk_type_name (type);
switch (type) {
case GTK_TYPE_NONE:
case GTK_TYPE_CHAR:
case GTK_TYPE_UCHAR:
case GTK_TYPE_BOOL:
case GTK_TYPE_INT:
case GTK_TYPE_UINT:
case GTK_TYPE_LONG:
case GTK_TYPE_ULONG:
case GTK_TYPE_FLOAT:
case GTK_TYPE_DOUBLE:
case GTK_TYPE_POINTER:
/* These all have normal C type names so they are OK. */
return type_name;
case GTK_TYPE_STRING:
/* A GtkString is really a gchar*. */
*is_pointer = TRUE;
return "gchar";
case GTK_TYPE_ENUM:
case GTK_TYPE_FLAGS:
/* We use a gint for both of these. Hopefully a subtype with a decent
name will be registered and used instead, as GTK+ does itself. */
return "gint";
case GTK_TYPE_BOXED:
/* A boxed value is just an opaque pointer, I think. */
return "gpointer";
case GTK_TYPE_SIGNAL:
case GTK_TYPE_ARGS:
case GTK_TYPE_FOREIGN:
case GTK_TYPE_CALLBACK:
case GTK_TYPE_C_CALLBACK:
/* FIXME: These are wrong. I think they expand into more than 1 argument.
See the GtkArg struct in gtktypeutils.h and gtkargcollector.c.
Fortunately I doubt anything uses these as signal args. */
return "gpointer";
default:
break;
}
/* For all GtkObject subclasses we can use the class name with a "*",
e.g. 'GtkWidget *'. */
if (gtk_type_is_a (type, GTK_TYPE_OBJECT))
*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",
"visibility_notify_event", "GdkEventVisibility",
"window_state_event", "GdkEventWindowState",
"scroll_event", "GdkEventScroll",
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 (void)
{
FILE *fp;
fp = fopen (hierarchy_filename, "w");
if (fp == NULL)
{
g_warning ("Couldn't open output file: %s : %s", hierarchy_filename, strerror(errno));
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,
guint level)
{
GList *list;
guint i;
if (!type)
return;
for (i = 0; i < level; i++)
fprintf (fp, " ");
fprintf (fp, "%s\\n", gtk_type_name (type));
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 (void)
{
FILE *fp;
gint i;
fp = fopen (args_filename, "w");
if (fp == NULL)
{
g_warning ("Couldn't open output file: %s : %s", args_filename, strerror(errno));
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;
guint 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</ARG>\\n\\n",
args[arg].name, gtk_type_name (args[arg].type), flags);
}
g_free (args);
g_free (arg_flags);
}
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} : "";
my $o_file;
if ($CC =~ /libtool/) {
$o_file = "$MODULE-scan.lo"
} else {
$o_file = "$MODULE-scan.o"
}
print "gtk-doc: Compiling scanner\n";
$command = "$CC $CFLAGS -c -o $o_file $MODULE-scan.c";
system($command) == 0 or die "Compilation of scanner failed: $!\n";
print "gtk-doc: Linking scanner\n";
$command = "$LD -o $MODULE-scan $o_file $LDFLAGS";
system($command) == 0 or die "Linking of scanner failed: $!\n";
print "gtk-doc: Running scanner $MODULE-scan\n";
system("sh -c ./$MODULE-scan") == 0 or die "Scan failed: $!\n";
unlink "./$MODULE-scan.c", "./$MODULE-scan.o", "./$MODULE-scan.lo", "./$MODULE-scan";
&UpdateFileIfChanged ($old_signals_filename, $new_signals_filename, 0);
&UpdateFileIfChanged ($old_hierarchy_filename, $new_hierarchy_filename, 0);
&UpdateFileIfChanged ($old_args_filename, $new_args_filename, 0);