Index: gtksourceview/gtksourceview.c
===================================================================
RCS file: /cvs/gnome/gtksourceview/gtksourceview/gtksourceview.c,v
retrieving revision 1.26
diff -u -p -r1.26 gtksourceview.c
--- gtksourceview/gtksourceview.c	19 Jul 2003 16:34:52 -0000	1.26
+++ gtksourceview/gtksourceview.c	6 Feb 2004 14:17:55 -0000
@@ -95,6 +95,15 @@ struct _GtkSourceViewPrivate
 
 	GtkSourceBuffer *source_buffer;
 	gint		 old_lines;
+
+	/* Call tips */
+	gboolean	 calltip_active;
+	GtkWidget	*calltip_window;
+	GtkWidget	*calltip_label;
+	gchar		*calltip_description;
+	guint		 calltip_start_hl;
+	guint		 calltip_end_hl;
+	GdkRectangle	 calltip_iter_location;
 };
 
 /* Implement DnD for application/x-color drops */
@@ -1881,4 +1890,265 @@ gtk_source_view_style_set (GtkWidget *wi
 	}
 }
 
+/* Call tips */
+
+static gint
+calltip_paint_window (GtkSourceView *view)
+{
+	gtk_paint_flat_box (view->priv->calltip_window->style,
+			    view->priv->calltip_window->window, GTK_STATE_NORMAL,
+			    GTK_SHADOW_OUT, NULL,
+			    GTK_WIDGET (view->priv->calltip_window), "tooltip",
+			    0, 0, -1, -1);
+
+	return FALSE;
+}
+
+static void
+calltip_event_handler (GtkWidget *widget,
+                       GdkEvent  *event)
+{
+	/* FIXME: cancel the tooltip when the view scroll horizontally
+	 * and when the widget is resized or the window is moved or minimized - 
+	 * Paolo (Feb 6, 2004)
+	 */
+	if (!gtk_source_view_has_active_call_tip (GTK_SOURCE_VIEW (widget)))
+		return;
+	
+	switch (event->type)
+	{
+		case GDK_FOCUS_CHANGE:
+			if (!event->focus_change.in)
+			{
+				gtk_source_view_cancel_call_tip (GTK_SOURCE_VIEW (widget));
+			}
+			break;
+			
+		case GDK_BUTTON_PRESS:
+		case GDK_BUTTON_RELEASE:
+		case GDK_SCROLL:
+		case GDK_NO_EXPOSE:
+			gtk_source_view_cancel_call_tip (GTK_SOURCE_VIEW (widget));
+			break;
+					
+		default:
+			break;
+	}
+}
+
+static void
+call_tip_force_window (GtkSourceView *view)
+{
+	g_return_if_fail (view->priv->calltip_window == NULL);
+
+	view->priv->calltip_window = gtk_window_new (GTK_WINDOW_POPUP);
+
+	gtk_widget_set_app_paintable (view->priv->calltip_window, TRUE);
+	gtk_window_set_resizable (GTK_WINDOW (view->priv->calltip_window), FALSE);
+	gtk_widget_set_name (view->priv->calltip_window, "gtksourceview-calltip");
+
+	gtk_container_set_border_width (GTK_CONTAINER (view->priv->calltip_window), 4);
+
+	g_signal_connect_swapped (view->priv->calltip_window,
+				  "expose_event",
+				  G_CALLBACK (calltip_paint_window),
+				  view);
+
+	view->priv->calltip_label = gtk_label_new (NULL);
+	gtk_label_set_line_wrap (GTK_LABEL (view->priv->calltip_label), TRUE);
+	gtk_misc_set_alignment (GTK_MISC (view->priv->calltip_label), 0.5, 0.5);
+	gtk_widget_show (view->priv->calltip_label);
+
+	gtk_container_add (GTK_CONTAINER (view->priv->calltip_window),
+			   view->priv->calltip_label);
+
+	g_signal_connect_after (view, 
+				"event-after",
+				G_CALLBACK (calltip_event_handler),
+				NULL);
+}
+
+static void
+draw_calltip (GtkSourceView *view)
+{
+	GtkRequisition requisition;
+	GtkWidget *widget;
+	gint x, y, w, h, w_x, w_y, scr_w, scr_h;
+	GdkScreen *screen;
+
+	if (view->priv->calltip_window == NULL)
+		call_tip_force_window (view);
+
+	gtk_widget_ensure_style (view->priv->calltip_window);
+	
+	widget = GTK_WIDGET (view);
+
+	screen = gtk_widget_get_screen (widget);
+	scr_w = gdk_screen_get_width (screen);
+	scr_h = gdk_screen_get_height (screen);
+
+	gtk_label_set_text (GTK_LABEL (view->priv->calltip_label),
+			    view->priv->calltip_description);
+
+	if (view->priv->calltip_start_hl < view->priv->calltip_end_hl)
+	{
+		PangoAttribute *attr;
+		PangoAttrList  *attrs;
+
+		attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
+		attr->start_index = view->priv->calltip_start_hl;
+		attr->end_index = view->priv->calltip_end_hl;
+
+		attrs = pango_attr_list_new ();
+
+		pango_attr_list_insert (attrs, attr);
+		
+		gtk_label_set_attributes (GTK_LABEL (view->priv->calltip_label),
+					  attrs);
+
+		pango_attr_list_unref (attrs);
+	}
+
+	gtk_widget_size_request (view->priv->calltip_window, &requisition);
+	w = requisition.width;
+	h = requisition.height;
+
+	gtk_text_view_buffer_to_window_coords (GTK_TEXT_VIEW (view),
+					       GTK_TEXT_WINDOW_WIDGET,
+					       view->priv->calltip_iter_location.x,
+					       view->priv->calltip_iter_location.y,
+					       &x,
+					       &y);
+	
+	gdk_window_get_origin (widget->window, &w_x, &w_y);
+	g_return_if_fail (!GTK_WIDGET_NO_WINDOW (widget));
+	
+	x += w_x + 4;
+	y += w_y;
+	
+	if ((x + w) > scr_w)
+		x -= (x + w) - scr_w;
+
+	if (x < 4)
+		x = 4;
+
+	if ((y - h - 4) > 0)
+		y = y - h - 4;
+	else
+		y = y + view->priv->calltip_iter_location.height +  4;
+
+	gtk_window_move (GTK_WINDOW (view->priv->calltip_window), x, y);
+	gtk_widget_show (view->priv->calltip_window);
+}
+
+/**
+ * gtk_source_view_show_call_tip:
+ * @view: a #GtkSourceView 
+ * @iter: a #GtkTextIter represeting the position in the document at which to align the call tip.
+ * The call tip text is aligned to start one line above this character.
+ * @desc: the call tip text, it can contain multiple lines separated by '\n' (Line Feed, ASCII code 10) 
+ * characters.
+ * @stath_hl: the zero-based index into the call tip text of the first character to highlight
+ * @end_hl: the index of the first character after the highlight (must be greater 
+ * than #hlStart)
+ *
+ * Displays a call tip containing the text @desc at position @iter. If a call tip is already active, 
+ * this has no effect.
+ **/
+void
+gtk_source_view_show_call_tip (GtkSourceView *view,
+			       GtkTextIter   *iter,
+			       const gchar   *desc,
+			       guint          start_hl,
+			       guint          end_hl)
+{
+	g_return_if_fail (GTK_IS_SOURCE_VIEW (view));
+	g_return_if_fail (gtk_text_iter_get_buffer (iter) == 
+			  	gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
+	g_return_if_fail (desc != NULL);
+	g_return_if_fail (start_hl <= end_hl);
+
+	if (view->priv->calltip_active)
+		return;
+
+	g_free (view->priv->calltip_description);
+	view->priv->calltip_description = g_strdup (desc);
+	
+	view->priv->calltip_start_hl = start_hl;
+	view->priv->calltip_end_hl = end_hl;
+
+	gtk_text_view_get_iter_location (GTK_TEXT_VIEW (view),
+					 iter,
+					 &view->priv->calltip_iter_location);
+	
+	draw_calltip (view);
+
+	view->priv->calltip_active = TRUE;
+}
+
+/**
+ * gtk_source_view_highlight_call_tip_region:
+ * @view: a #GtkSourceView
+ * @start_hl: the zero-based index into the string of the first character to highlight
+ * @end_hl: the index of the first character after the highlight (must be greater 
+ * than #hlStart)
+ *
+ * Sets the region of the call tips text to display in a highlighted style.
+ */
+void		 
+gtk_source_view_highlight_call_tip_region (GtkSourceView *view,
+					   guint          start_hl,
+					   guint          end_hl)
+{
+	g_return_if_fail (GTK_IS_SOURCE_VIEW (view));
+	g_return_if_fail (start_hl <= end_hl);
+	
+	if (!view->priv->calltip_active)
+		return;
+
+	view->priv->calltip_start_hl = start_hl;
+	view->priv->calltip_end_hl = end_hl;
+
+	gtk_widget_hide (view->priv->calltip_window);
+
+	draw_calltip (view);
+}
+
+/**
+ * gtk_source_view_cancel_call_tip:
+ * @view: a #GtkSourceView
+ *
+ * Cancels displayed call tip if any.
+ **/
+void
+gtk_source_view_cancel_call_tip (GtkSourceView *view)
+{
+	g_return_if_fail (GTK_IS_SOURCE_VIEW (view));
+
+	if (!view->priv->calltip_active)
+		return;
+
+	g_return_if_fail (view->priv->calltip_window != NULL);
+	gtk_widget_hide (view->priv->calltip_window);
+
+	view->priv->calltip_active = FALSE;
+}
+	
+/**
+ * gtk_source_view_has_active_call_tip:
+ * @view: a #GtkSourceView
+ *
+ * Rturns %TRUE if a call tip is active and %FALSE if it is not active.
+ *
+ * Return value: %TRUE if if a call tip is active and %FALSE otherwise.
+ **/
+
+gboolean 
+gtk_source_view_has_active_call_tip (GtkSourceView *view)
+{
+	g_return_val_if_fail (GTK_IS_SOURCE_VIEW (view), FALSE);
+
+	return view->priv->calltip_active ? TRUE : FALSE;
+}
+
 
Index: gtksourceview/gtksourceview.h
===================================================================
RCS file: /cvs/gnome/gtksourceview/gtksourceview/gtksourceview.h,v
retrieving revision 1.9
diff -u -p -r1.9 gtksourceview.h
--- gtksourceview/gtksourceview.h	4 May 2003 22:43:57 -0000	1.9
+++ gtksourceview/gtksourceview.h	6 Feb 2004 14:17:55 -0000
@@ -112,5 +112,22 @@ void		 gtk_source_view_set_smart_home_en
 							 gboolean         enable);
 gboolean	 gtk_source_view_get_smart_home_end	(GtkSourceView   *view);
 
+/* Call tips */
+void		 gtk_source_view_show_call_tip		(GtkSourceView   *view,
+							 GtkTextIter     *iter,
+							 const gchar     *desc,
+							 guint            start_hl,
+							 guint            end_hl);
+
+void		 gtk_source_view_highlight_call_tip_region
+							(GtkSourceView   *view,
+							 guint            start_hl,
+							 guint            end_hl);
+
+void		 gtk_source_view_cancel_call_tip	(GtkSourceView   *view);
+
+gboolean	 gtk_source_view_has_active_call_tip	(GtkSourceView   *view);
+
+
 G_END_DECLS
 #endif				/* end of SOURCE_VIEW_H__ */
Index: tests/test-widget.c
===================================================================
RCS file: /cvs/gnome/gtksourceview/tests/test-widget.c,v
retrieving revision 1.9
diff -u -p -r1.9 test-widget.c
--- tests/test-widget.c	16 Dec 2003 04:57:23 -0000	1.9
+++ tests/test-widget.c	6 Feb 2004 14:17:56 -0000
@@ -592,6 +592,19 @@ update_cursor_position (GtkTextBuffer *b
 		
 		gtk_text_iter_forward_char (&start);
 	}
+
+	if (col == 10)
+		gtk_source_view_show_call_tip (view, &iter, "Prova (pippo, opi)", 7, 13);
+	else
+	{
+		if (col == 15)
+			gtk_source_view_highlight_call_tip_region (view, 14, 17);
+		else
+		{
+			if (col == 20)				
+				gtk_source_view_cancel_call_tip (view);
+		}		
+	}
 	
 	msg = g_strdup_printf ("char: %d, line: %d, column: %d", chars, row, col);
 	gtk_label_set_text (pos_label, msg);
@@ -854,6 +867,7 @@ create_view_window (GtkSourceBuffer *buf
 	gtk_source_view_set_marker_pixbuf (GTK_SOURCE_VIEW (view), MARKER_TYPE_2, pixbuf);
 	g_object_unref (pixbuf);
 	
+
 	gtk_widget_show_all (vbox);
 
 	return window;
