--- gtk+-2.6.4/gtk/gtktextview.c	2005-03-01 08:28:56.000000000 +0200
+++ gtk+-2.6.4/gtk/gtktextview.c	2005-04-06 16:19:38.152738264 +0300
@@ -99,6 +99,11 @@
 
 #define SPACE_FOR_CURSOR 1
 
+typedef struct _GtkTextViewPrivate GtkTextViewPrivate;
+
+#define GTK_TEXT_VIEW_GET_PRIVATE(obj) ( G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
+                                      GTK_TYPE_TEXT_VIEW, GtkTextViewPrivate) )
+
 struct _GtkTextPendingScroll
 {
   GtkTextMark   *mark;
@@ -145,6 +150,8 @@
   PROP_BUFFER,
   PROP_OVERWRITE,
   PROP_ACCEPTS_TAB,
+  PROP_AUTOCAP,
+  PROP_INPUT_MODE,
   LAST_PROP
 };
 
@@ -343,6 +350,13 @@
 
 static void gtk_text_view_update_im_spot_location (GtkTextView *text_view);
 
+static void     gtk_text_view_set_autocap          (GtkTextView *text_view,
+                                                    gboolean    autocap);
+static gboolean gtk_text_view_get_autocap          (GtkTextView *text_view);
+static void     gtk_text_view_set_input_mode       (GtkTextView *text_view,
+                                                    gint         mode);
+static gint     gtk_text_view_get_input_mode       (GtkTextView *text_view);
+
 /* Container methods */
 static void gtk_text_view_add    (GtkContainer *container,
                                   GtkWidget    *child);
@@ -412,6 +426,10 @@
 static gint           text_window_get_width       (GtkTextWindow     *win);
 static gint           text_window_get_height      (GtkTextWindow     *win);
 
+struct _GtkTextViewPrivate
+{
+  guint release_selection : 1;
+};
 
 static const GtkTargetEntry target_table[] = {
   { "GTK_TEXT_BUFFER_CONTENTS", GTK_TARGET_SAME_APP, 0 },
@@ -481,6 +499,7 @@
 
   parent_class = g_type_class_peek_parent (klass);
 
+  g_type_class_add_private( klass, sizeof(GtkTextViewPrivate) );
   /* Default handlers and virtual methods
    */
   gobject_class->set_property = gtk_text_view_set_property;
@@ -667,6 +686,24 @@
 							 TRUE,
 							 G_PARAM_READWRITE));
 
+  g_object_class_install_property (gobject_class,
+                                   PROP_AUTOCAP,
+                                   g_param_spec_boolean ("autocap",
+                                                         P_("auto capitalization"),
+                                                         P_("Enable autocap support"),
+                                                         TRUE,
+                                                         G_PARAM_READABLE | G_PARAM_WRITABLE)); 
+  
+  g_object_class_install_property (gobject_class,
+                                   PROP_INPUT_MODE,
+                                   g_param_spec_int ("input_mode",
+                                                     P_("input mode"),
+                                                     P_("Define widget's input mode"),
+                                                     0,
+                                                     9, /* keep me updated */
+                                                     0,
+                                                     G_PARAM_READABLE | G_PARAM_WRITABLE)); 
+
   /*
    * Style properties
    */
@@ -676,6 +713,14 @@
 							       P_("Color with which to draw error-indication underlines"),
 							       GDK_TYPE_COLOR,
 							       G_PARAM_READABLE));
+
+  gtk_widget_class_install_style_property (widget_class,
+                                          g_param_spec_boolean ("autocap",
+                                                                _("auto capitalization"),
+                                                                _("Enable autocap support"),
+                                                            TRUE,
+                                                            G_PARAM_READABLE));
+  
   
   /*
    * Signals
@@ -1040,8 +1085,9 @@
 gtk_text_view_init (GtkTextView *text_view)
 {
   GtkWidget *widget;
-
+  GtkTextViewPrivate *priv = NULL;
   widget = GTK_WIDGET (text_view);
+  priv = GTK_TEXT_VIEW_GET_PRIVATE(text_view);
 
   GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS);
 
@@ -1057,6 +1103,8 @@
   text_view->tabs = NULL;
   text_view->editable = TRUE;
 
+  priv->release_selection = TRUE;
+
   gtk_drag_dest_set (widget,
 		     0,
                      target_table, G_N_ELEMENTS (target_table),
@@ -1070,6 +1118,10 @@
    * to it; so we create it here and destroy it in finalize ().
    */
   text_view->im_context = gtk_im_multicontext_new ();
+  /* Set default stuff. */
+  gtk_text_view_set_autocap (text_view, TRUE);
+  gtk_text_view_set_input_mode (text_view, 0); /* alpha-numeric-special */
+  g_object_set (G_OBJECT (text_view->im_context), "use-show-hide", TRUE, NULL);
 
   g_signal_connect (text_view->im_context, "commit",
                     G_CALLBACK (gtk_text_view_commit_handler), text_view);
@@ -2664,6 +2716,14 @@
       gtk_text_view_set_accepts_tab (text_view, g_value_get_boolean (value));
       break;
       
+    case PROP_AUTOCAP:
+      gtk_text_view_set_autocap (text_view, g_value_get_boolean (value));
+      break;
+
+    case PROP_INPUT_MODE:
+      gtk_text_view_set_input_mode (text_view, g_value_get_int (value));
+      break;
+      
     default:
       g_assert_not_reached ();
       break;
@@ -2738,6 +2798,14 @@
       g_value_set_boolean (value, text_view->accepts_tab);
       break;
       
+    case PROP_AUTOCAP:
+      g_value_set_boolean (value, gtk_text_view_get_autocap (text_view));
+      break;
+      
+    case PROP_INPUT_MODE:
+      g_value_set_int (value, gtk_text_view_get_input_mode (text_view));
+      break;
+      
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -3916,7 +3984,7 @@
   GtkTextView *text_view = GTK_TEXT_VIEW (widget);
   GtkTextMark *insert;
   GtkTextIter iter;
-
+  
   if (text_view->layout == NULL || get_buffer (text_view) == NULL)
     return FALSE;
       
@@ -4039,6 +4107,9 @@
   if (event->window != text_view->text_window->bin_window)
     return FALSE;
 
+  if (text_view->editable)
+    gtk_im_context_show (text_view->im_context);
+  
   if (event->button == 1)
     {
       if (text_view->drag_start_x >= 0)
@@ -4083,7 +4154,15 @@
 static gint
 gtk_text_view_focus_in_event (GtkWidget *widget, GdkEventFocus *event)
 {
+  /*gboolean have_selection;
+  GtkTextIter sel_start, sel_end;*/
+	
   GtkTextView *text_view = GTK_TEXT_VIEW (widget);
+  
+  /*have_selection = gtk_text_buffer_get_selection_bounds(text_view->buffer, &sel_start, &sel_end);
+  
+  if(!have_selection)
+    gtk_text_view_move_cursor(text_view, GTK_MOVEMENT_BUFFER_ENDS, 1, FALSE);*//*FIXME some other way to place the cursor in the end*/
 
   gtk_widget_queue_draw (widget);
 
@@ -4100,8 +4179,10 @@
 		    G_CALLBACK (keymap_direction_changed), text_view);
   gtk_text_view_check_keymap_direction (text_view);
   
+  /* Keyboard hack */
   text_view->need_im_reset = TRUE;
   gtk_im_context_focus_in (GTK_TEXT_VIEW (widget)->im_context);
+  gtk_text_view_reset_im_context (text_view);
 
   return FALSE;
 }
@@ -4110,6 +4191,14 @@
 gtk_text_view_focus_out_event (GtkWidget *widget, GdkEventFocus *event)
 {
   GtkTextView *text_view = GTK_TEXT_VIEW (widget);
+  GtkTextViewPrivate *priv = GTK_TEXT_VIEW_GET_PRIVATE(text_view);
+  /*{
+    GtkTextIter start;
+    GtkTextIter end;
+    
+    gtk_text_buffer_get_bounds(text_view->buffer, &start, &end);
+    gtk_text_buffer_select_range(text_view->buffer, &start, &start);
+  }*//*FIXME need a hack here to take away the focus*/
 
   gtk_widget_queue_draw (widget);
 
@@ -4125,8 +4214,11 @@
 					keymap_direction_changed,
 					text_view);
 
-  text_view->need_im_reset = TRUE;
-  gtk_im_context_focus_out (GTK_TEXT_VIEW (widget)->im_context);
+  /* This is commented out to disable unselect feature.
+     When the decition of this has been made, we can either remove this patch
+     or to leave it.
+  if( priv->release_selection )
+    gtk_text_view_unselect( text_view );*/
 
   return FALSE;
 }
@@ -5082,7 +5174,8 @@
   GtkTextIter end;
   gboolean leave_one = FALSE;
 
-  gtk_text_view_reset_im_context (text_view);
+  /*gtk_text_view_reset_im_context (text_view);*/ /*backspace should not clear
+                                                    the word completion*/
 
   if (type == GTK_DELETE_CHARS)
     {
@@ -5200,7 +5293,8 @@
 {
   GtkTextIter insert;
 
-  gtk_text_view_reset_im_context (text_view);
+  /*gtk_text_view_reset_im_context (text_view);*/ /*backspace should not clear
+                                                    the word completion*/
 
   /* Backspace deletes the selection, if one exists */
   if (gtk_text_buffer_delete_selection (get_buffer (text_view), TRUE,
@@ -5928,11 +6022,11 @@
 static void
 gtk_text_view_reset_im_context (GtkTextView *text_view)
 {
-  if (text_view->need_im_reset)
+/*  if (text_view->need_im_reset)
     {
-      text_view->need_im_reset = FALSE;
+      text_view->need_im_reset = FALSE;*/
       gtk_im_context_reset (text_view->im_context);
-    }
+/*    }*/
 }
 
 /*
@@ -6665,18 +6759,23 @@
 {
   GtkTextIter start;
   GtkTextIter end;
-  gint pos;
+  gint pos, endpos;
   gchar *text;
 
-  gtk_text_buffer_get_iter_at_mark (text_view->buffer, &start,  
+  gtk_text_buffer_get_iter_at_line (text_view->buffer, &start, 0);
+  gtk_text_buffer_get_iter_at_mark (text_view->buffer, &end,  
 				    gtk_text_buffer_get_insert (text_view->buffer));
-  end = start;
 
-  pos = gtk_text_iter_get_line_index (&start);
-  gtk_text_iter_set_line_offset (&start, 0);
+  pos = gtk_text_iter_get_line_index (&end);
+
   gtk_text_iter_forward_to_line_end (&end);
+  endpos = gtk_text_iter_get_line_index (&end);
 
   text = gtk_text_iter_get_slice (&start, &end);
+  if (text)
+    pos = strlen (text) - (endpos - pos); /* want bytes, not characters */
+  else
+    pos = 0;
   gtk_im_context_set_surrounding (context, text, -1, pos);
   g_free (text);
 
@@ -6726,8 +6825,8 @@
       need_reset = TRUE;
     }
 
-  if (need_reset)
-    gtk_text_view_reset_im_context (text_view);
+  /*if (need_reset)
+    gtk_text_view_reset_im_context (text_view);*//*FIXME need a hack here*/
 }
 
 static void
@@ -6957,6 +7056,13 @@
 }                             
 
 static void
+block_selection_change( GtkMenuShell *menushell, gpointer user_data )
+{
+  GtkTextViewPrivate *priv = GTK_TEXT_VIEW_GET_PRIVATE(user_data);
+  priv->release_selection = TRUE;
+}
+
+static void
 unichar_chosen_func (const char *text,
                      gpointer    data)
 {
@@ -7064,7 +7170,12 @@
 		     signals[POPULATE_POPUP],
 		     0,
 		     text_view->popup_menu);
-      
+    {
+      GtkTextViewPrivate *priv = GTK_TEXT_VIEW_GET_PRIVATE(text_view);
+      g_signal_connect( GTK_WIDGET(text_view->popup_menu), "selection-done",
+                        G_CALLBACK(block_selection_change), text_view );
+      priv->release_selection = FALSE;
+    }
       if (info->button)
 	gtk_menu_popup (GTK_MENU (text_view->popup_menu), NULL, NULL,
 			NULL, NULL,
@@ -8301,3 +8412,81 @@
 
   return gtk_text_layout_move_iter_visually (text_view->layout, iter, count);
 }
+
+/*
+ * gtk_text_view_set_autocap:
+ * @entry: a #GtkTextView
+ * @autocap: autocap
+ *
+ * Sets autocapitalization of the widget.
+ */
+static void
+gtk_text_view_set_autocap (GtkTextView *text_view,
+                           gboolean     autocap)
+{
+  g_return_if_fail (GTK_IS_TEXT_VIEW (text_view));
+
+  if (gtk_text_view_get_autocap (text_view) != autocap)
+  {
+    g_object_set (G_OBJECT (text_view->im_context), "autocap", autocap, NULL);
+    g_object_notify (G_OBJECT (text_view), "autocap");
+  }
+}
+
+/*
+ * gtk_text_view_get_autocap:
+ * @entry: a #GtkTextView
+ *
+ * Gets autocapitalization state of the widget.
+ *
+ * Return value: a state
+ */
+static gboolean
+gtk_text_view_get_autocap (GtkTextView *text_view)
+{
+  gboolean autocap;
+  g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), FALSE);
+
+  g_object_get (G_OBJECT (text_view->im_context), "autocap", &autocap, NULL);
+
+  return autocap;
+}
+
+/*
+ * gtk_text_view_set_input_mode:
+ * @text_view: a #GtkTextView
+ * @mode: input mode
+ *
+ * Sets autocapitalization of the widget.
+ */
+static void
+gtk_text_view_set_input_mode (GtkTextView *text_view,
+                              gint         mode)
+{
+  g_return_if_fail (GTK_IS_TEXT_VIEW (text_view));
+
+  if (gtk_text_view_get_input_mode (text_view) != mode)
+  {
+    g_object_set (G_OBJECT (text_view->im_context), "input_mode", mode, NULL);
+    g_object_notify (G_OBJECT (text_view), "input_mode");
+  }
+}
+
+/*
+ * gtk_text_view_get_input_mode:
+ * @text_view: a #GtkTextView
+ *
+ * Gets input mode of the widget.
+ *
+ * Return value: input mode
+ */
+static gint
+gtk_text_view_get_input_mode (GtkTextView *text_view)
+{
+  gint mode;
+  g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), FALSE);
+
+  g_object_get (G_OBJECT (text_view->im_context), "input_mode", &mode, NULL);
+
+  return mode;
+}