Index: gtk/gtkenums.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkenums.h,v
retrieving revision 1.52
diff -u -b -B -p -r1.52 gtkenums.h
--- gtk/gtkenums.h	10 Oct 2002 23:42:55 -0000	1.52
+++ gtk/gtkenums.h	27 Jan 2003 00:17:25 -0000
@@ -202,8 +202,18 @@ typedef enum {
   GTK_MOVEMENT_PARAGRAPHS,        /* move up/down paragraphs (newline-ended lines) */
   GTK_MOVEMENT_PARAGRAPH_ENDS,    /* move to either end of a paragraph */
   GTK_MOVEMENT_PAGES,	          /* move by pages */
-  GTK_MOVEMENT_BUFFER_ENDS        /* move to ends of the buffer */
+  GTK_MOVEMENT_BUFFER_ENDS,       /* move to ends of the buffer */
+  GTK_MOVEMENT_HORIZONTAL_PAGES   /* move horizontally by pages */
 } GtkMovementStep;
+
+typedef enum {
+  GTK_SCROLL_STEPS,
+  GTK_SCROLL_PAGES,
+  GTK_SCROLL_ENDS,
+  GTK_SCROLL_HORIZONTAL_STEPS,
+  GTK_SCROLL_HORIZONTAL_PAGES,
+  GTK_SCROLL_HORIZONTAL_ENDS
+} GtkScrollStep;
 
 /* Orientation for toolbars, etc. */
 typedef enum
Index: gtk/gtktextview.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktextview.h,v
retrieving revision 1.40
diff -u -b -B -p -r1.40 gtktextview.h
--- gtk/gtktextview.h	6 Jan 2003 23:07:06 -0000	1.40
+++ gtk/gtktextview.h	27 Jan 2003 00:17:25 -0000
@@ -181,6 +181,10 @@ struct _GtkTextViewClass
                               gint         count,
                               gboolean     extend_selection);
   
+  void (* move_viewport)     (GtkTextView    *text_view,
+                              GtkScrollStep step,
+                              gint            count);
+
   /* move the "anchor" (what Emacs calls the mark) to the cursor position */
   void (* set_anchor)  (GtkTextView    *text_view);
 
Index: gtk/gtktextview.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktextview.c,v
retrieving revision 1.221
diff -u -b -B -p -r1.221 gtktextview.c
--- gtk/gtktextview.c	21 Jan 2003 22:31:29 -0000	1.221
+++ gtk/gtktextview.c	27 Jan 2003 00:17:27 -0000
@@ -108,6 +108,7 @@ enum
   SET_SCROLL_ADJUSTMENTS,
   POPULATE_POPUP,
   MOVE_CURSOR,
+  MOVE_VIEWPORT,
   PAGE_HORIZONTALLY,
   SET_ANCHOR,
   INSERT_AT_CURSOR,
@@ -233,6 +234,9 @@ static void gtk_text_view_move_cursor   
 static void gtk_text_view_page_horizontally (GtkTextView          *text_view,
                                              gint                  count,
                                              gboolean              extend_selection);
+static void gtk_text_view_move_viewport     (GtkTextView           *text_view,
+                                             GtkScrollStep          step,
+                                             gint                   count);
 static void gtk_text_view_set_anchor       (GtkTextView           *text_view);
 static void gtk_text_view_scroll_pages     (GtkTextView           *text_view,
                                             gint                   count,
@@ -520,6 +524,7 @@ gtk_text_view_class_init (GtkTextViewCla
 
   klass->move_cursor = gtk_text_view_move_cursor;
   klass->page_horizontally = gtk_text_view_page_horizontally;
+  klass->move_viewport = gtk_text_view_move_viewport;
   klass->set_anchor = gtk_text_view_set_anchor;
   klass->insert_at_cursor = gtk_text_view_insert_at_cursor;
   klass->delete_from_cursor = gtk_text_view_delete_from_cursor;
@@ -664,6 +669,17 @@ gtk_text_view_class_init (GtkTextViewCla
 		  G_TYPE_INT,
 		  G_TYPE_BOOLEAN);
   
+  signals[MOVE_CURSOR] =
+    g_signal_new ("move_viewport",
+		  G_OBJECT_CLASS_TYPE (gobject_class),
+		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+		  G_STRUCT_OFFSET (GtkTextViewClass, move_cursor),
+		  NULL, NULL,
+		  _gtk_marshal_VOID__ENUM_INT,
+		  G_TYPE_NONE, 2,
+		  GTK_TYPE_SCROLL_STEP,
+		  G_TYPE_INT);
+
   signals[SET_ANCHOR] =
     g_signal_new ("set_anchor",
 		  G_OBJECT_CLASS_TYPE (gobject_class),
@@ -853,6 +869,18 @@ gtk_text_view_class_init (GtkTextViewCla
   add_move_binding (binding_set, GDK_KP_Page_Down, 0,
                     GTK_MOVEMENT_PAGES, 1);
 
+  add_move_binding (binding_set, GDK_Page_Up, GDK_CONTROL_MASK,
+                    GTK_MOVEMENT_HORIZONTAL_PAGES, -1);
+
+  add_move_binding (binding_set, GDK_KP_Page_Up, GDK_CONTROL_MASK,
+                    GTK_MOVEMENT_HORIZONTAL_PAGES, -1);
+  
+  add_move_binding (binding_set, GDK_Page_Down, GDK_CONTROL_MASK,
+                    GTK_MOVEMENT_HORIZONTAL_PAGES, 1);
+
+  add_move_binding (binding_set, GDK_KP_Page_Down, GDK_CONTROL_MASK,
+                    GTK_MOVEMENT_HORIZONTAL_PAGES, 1);
+
   /* Select all
    */
   gtk_binding_entry_add_signal (binding_set, GDK_a, GDK_CONTROL_MASK,
@@ -885,48 +913,6 @@ gtk_text_view_class_init (GtkTextViewCla
 				G_TYPE_INT, 0,
 				G_TYPE_BOOLEAN, FALSE);
 
-  
-
-  gtk_binding_entry_add_signal (binding_set, GDK_Page_Up, GDK_CONTROL_MASK,
-				"page_horizontally", 2,
-				G_TYPE_INT, -1,
-				G_TYPE_BOOLEAN, FALSE);
-
-  gtk_binding_entry_add_signal (binding_set, GDK_Page_Up, GDK_CONTROL_MASK | GDK_SHIFT_MASK,
-				"page_horizontally", 2,
-				G_TYPE_INT, -1,
-				G_TYPE_BOOLEAN, TRUE);
-
-  gtk_binding_entry_add_signal (binding_set, GDK_KP_Page_Up, GDK_CONTROL_MASK,
-				"page_horizontally", 2,
-				G_TYPE_INT, -1,
-				G_TYPE_BOOLEAN, FALSE);
-
-  gtk_binding_entry_add_signal (binding_set, GDK_KP_Page_Up, GDK_CONTROL_MASK | GDK_SHIFT_MASK,
-				"page_horizontally", 2,
-				G_TYPE_INT, -1,
-				G_TYPE_BOOLEAN, TRUE);
-
-  gtk_binding_entry_add_signal (binding_set, GDK_Page_Down, GDK_CONTROL_MASK,
-				"page_horizontally", 2,
-				G_TYPE_INT, 1,
-				G_TYPE_BOOLEAN, FALSE);
-
-  gtk_binding_entry_add_signal (binding_set, GDK_Page_Down, GDK_CONTROL_MASK | GDK_SHIFT_MASK,
-				"page_horizontally", 2,
-				G_TYPE_INT, 1,
-				G_TYPE_BOOLEAN, TRUE);
-
-  gtk_binding_entry_add_signal (binding_set, GDK_KP_Page_Down, GDK_CONTROL_MASK,
-				"page_horizontally", 2,
-				G_TYPE_INT, 1,
-				G_TYPE_BOOLEAN, FALSE);
-
-  gtk_binding_entry_add_signal (binding_set, GDK_KP_Page_Down, GDK_CONTROL_MASK | GDK_SHIFT_MASK,
-				"page_horizontally", 2,
-				G_TYPE_INT, 1,
-				G_TYPE_BOOLEAN, TRUE);
-  
   /* Deleting text */
   gtk_binding_entry_add_signal (binding_set, GDK_Delete, 0,
 				"delete_from_cursor", 2,
@@ -4475,11 +4461,6 @@ move_cursor (GtkTextView       *text_vie
                                   new_location);
 }
 
-/* FIXME when we are unfrozen and can change GtkMovementStep,
- * fix this
- */
-#define PAGE_HORIZONTALLY_HACK_VALUE 57
-
 static void
 gtk_text_view_move_cursor_internal (GtkTextView     *text_view,
                                     GtkMovementStep  step,
@@ -4491,6 +4472,39 @@ gtk_text_view_move_cursor_internal (GtkT
 
   gint cursor_x_pos = 0;
 
+  if (!text_view->cursor_visible) 
+    {
+      GtkScrollStep scroll_step;
+
+      switch (step) 
+	{
+	case GTK_MOVEMENT_LOGICAL_POSITIONS:
+        case GTK_MOVEMENT_VISUAL_POSITIONS:
+        case GTK_MOVEMENT_WORDS:
+	  scroll_step = GTK_SCROLL_HORIZONTAL_STEPS;
+	  break;
+        case GTK_MOVEMENT_DISPLAY_LINES:
+        case GTK_MOVEMENT_DISPLAY_LINE_ENDS:
+        case GTK_MOVEMENT_PARAGRAPHS:
+        case GTK_MOVEMENT_PARAGRAPH_ENDS:
+	  scroll_step = GTK_SCROLL_STEPS;
+	  break;
+	case GTK_MOVEMENT_PAGES:
+	  scroll_step = GTK_SCROLL_PAGES;
+	  break;
+	case GTK_MOVEMENT_HORIZONTAL_PAGES:
+	  scroll_step = GTK_SCROLL_HORIZONTAL_PAGES;
+	  break;
+	case GTK_MOVEMENT_BUFFER_ENDS:
+	  scroll_step = GTK_SCROLL_ENDS;
+	  break;
+	}
+      
+      gtk_text_view_move_viewport (text_view, scroll_step, count);
+
+      return;
+    }
+
   gtk_text_view_reset_im_context (text_view);
 
   if (step == GTK_MOVEMENT_PAGES)
@@ -4499,7 +4513,7 @@ gtk_text_view_move_cursor_internal (GtkT
       gtk_text_view_pend_cursor_blink (text_view);
       return;
     }
-  else if (step == PAGE_HORIZONTALLY_HACK_VALUE)
+  else if (step == GTK_MOVEMENT_HORIZONTAL_PAGES)
     {
       gtk_text_view_scroll_hpages (text_view, count, extend_selection);
       gtk_text_view_pend_cursor_blink (text_view);
@@ -4628,8 +4642,49 @@ gtk_text_view_page_horizontally (GtkText
                                  gint             count,
                                  gboolean         extend_selection)
 {
-  gtk_text_view_move_cursor_internal (text_view, PAGE_HORIZONTALLY_HACK_VALUE,
+  gtk_text_view_move_cursor_internal (text_view, GTK_MOVEMENT_HORIZONTAL_PAGES,
                                       count, extend_selection);
+}
+
+static void
+gtk_text_view_move_viewport (GtkTextView     *text_view,
+                             GtkScrollStep    step,
+                             gint             count)
+{
+  GtkAdjustment *adjustment;
+  gdouble increment;
+  
+  switch (step) 
+    {
+    case GTK_SCROLL_STEPS:
+    case GTK_SCROLL_PAGES:
+    case GTK_SCROLL_ENDS:
+      adjustment = get_vadjustment (text_view);
+      break;
+    case GTK_SCROLL_HORIZONTAL_STEPS:
+    case GTK_SCROLL_HORIZONTAL_PAGES:
+    case GTK_SCROLL_HORIZONTAL_ENDS:
+      adjustment = get_hadjustment (text_view);
+      break;
+    }
+
+  switch (step) 
+    {
+    case GTK_SCROLL_STEPS:
+    case GTK_SCROLL_HORIZONTAL_STEPS:
+      increment = adjustment->step_increment;
+      break;
+    case GTK_SCROLL_PAGES:
+    case GTK_SCROLL_HORIZONTAL_PAGES:
+      increment = adjustment->page_increment;
+      break;
+    case GTK_SCROLL_ENDS:
+    case GTK_SCROLL_HORIZONTAL_ENDS:
+      increment = adjustment->upper - adjustment->lower;
+      break;
+    }
+
+  set_adjustment_clamped (adjustment, adjustment->value + count * increment);
 }
 
 static void
